diff options
-rw-r--r-- | usr.bin/cvs/rcs.c | 369 |
1 files changed, 198 insertions, 171 deletions
diff --git a/usr.bin/cvs/rcs.c b/usr.bin/cvs/rcs.c index acb0a5110d9..51eb79f66a0 100644 --- a/usr.bin/cvs/rcs.c +++ b/usr.bin/cvs/rcs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rcs.c,v 1.230 2007/11/11 10:14:33 tobias Exp $ */ +/* $OpenBSD: rcs.c,v 1.231 2007/11/11 14:02:35 tobias Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -3083,13 +3083,14 @@ static void rcs_kwexp_line(char *rcsfile, struct rcs_delta *rdp, struct cvs_line *line, int mode) { + BUF *tmpbuf; int kwtype; u_int j, found; const u_char *c, *start, *fin, *end; char *kwstr; char expbuf[256], buf[256]; char *fmt; - size_t len, kwlen; + size_t clen, kwlen, len, tlen; kwtype = 0; kwstr = NULL; @@ -3112,199 +3113,225 @@ rcs_kwexp_line(char *rcsfile, struct rcs_delta *rdp, struct cvs_line *line, * $Keyword: value$ */ for (; c < fin; c++) { - if (*c == '$') { - BUF *tmpbuf; - size_t clen, tlen; + if (*c != '$') + continue; - /* remember start of this possible keyword */ - start = c; + /* remember start of this possible keyword */ + start = c; - /* first following character has to be alphanumeric */ - c++; - if (!isalpha(*c)) { - c = start; - continue; - } + /* first following character has to be alphanumeric */ + c++; + if (!isalpha(*c)) { + c = start; + continue; + } - /* Number of characters between c and fin, inclusive. */ - clen = fin - c + 1; + /* Number of characters between c and fin, inclusive. */ + clen = fin - c + 1; - /* look for any matching keywords */ - found = 0; - for (j = 0; j < RCS_NKWORDS; j++) { - kwlen = strlen(rcs_expkw[j].kw_str); - /* - * kwlen must be less than clen since clen - * includes either a terminating `$' or a `:'. - */ - if (kwlen < clen && - memcmp(c, rcs_expkw[j].kw_str, kwlen) == 0 && - (c[kwlen] == '$' || c[kwlen] == ':')) { - found = 1; - kwstr = rcs_expkw[j].kw_str; - kwtype = rcs_expkw[j].kw_type; - c += kwlen; - break; - } + /* look for any matching keywords */ + found = 0; + for (j = 0; j < RCS_NKWORDS; j++) { + kwlen = strlen(rcs_expkw[j].kw_str); + /* + * kwlen must be less than clen since clen + * includes either a terminating `$' or a `:'. + */ + if (kwlen < clen && + memcmp(c, rcs_expkw[j].kw_str, kwlen) == 0 && + (c[kwlen] == '$' || c[kwlen] == ':')) { + found = 1; + kwstr = rcs_expkw[j].kw_str; + kwtype = rcs_expkw[j].kw_type; + c += kwlen; + break; } + } - if (found == 0 && cvs_tagname != NULL) { - kwlen = strlen(cvs_tagname); - if (kwlen < clen && - memcmp(c, cvs_tagname, kwlen) == 0 && - (c[kwlen] == '$' || c[kwlen] == ':')) { - found = 1; - kwstr = cvs_tagname; - kwtype = RCS_KW_ID; - c += kwlen; - } + if (found == 0 && cvs_tagname != NULL) { + kwlen = strlen(cvs_tagname); + if (kwlen < clen && + memcmp(c, cvs_tagname, kwlen) == 0 && + (c[kwlen] == '$' || c[kwlen] == ':')) { + found = 1; + kwstr = cvs_tagname; + kwtype = RCS_KW_ID; + c += kwlen; + } + } + + /* unknown keyword, continue looking */ + if (found == 0) { + c = start; + continue; + } + + /* + * if the next character was ':' we need to look for + * an '$' before the end of the line to be sure it is + * in fact a keyword. + */ + if (*c == ':') { + for (; c <= fin; ++c) { + if (*c == '$' || *c == '\n') + break; } - /* unknown keyword, continue looking */ - if (found == 0) { + if (*c != '$') { c = start; continue; } + } + end = c + 1; + + /* start constructing the expansion */ + expbuf[0] = '\0'; + + if (mode & RCS_KWEXP_NAME) { + if (strlcat(expbuf, "$", sizeof(expbuf)) >= + sizeof(expbuf) || strlcat(expbuf, kwstr, + sizeof(expbuf)) >= sizeof(expbuf)) + fatal("rcs_kwexp_line: truncated"); + if ((mode & RCS_KWEXP_VAL) && + strlcat(expbuf, ": ", sizeof(expbuf)) >= + sizeof(expbuf)) + fatal("rcs_kwexp_line: truncated"); + } - /* - * if the next character was ':' we need to look for - * an '$' before the end of the line to be sure it is - * in fact a keyword. - */ - if (*c == ':') { - for (; c <= fin; ++c) { - if (*c == '$' || *c == '\n') - break; - } - - if (*c != '$') { - c = start; - continue; - } + /* + * order matters because of RCS_KW_ID and + * RCS_KW_HEADER here + */ + if (mode & RCS_KWEXP_VAL) { + if (kwtype & RCS_KW_RCSFILE) { + if (!(kwtype & RCS_KW_FULLPATH)) + (void)strlcat(expbuf, basename(rcsfile), + sizeof(expbuf)); + else + (void)strlcat(expbuf, rcsfile, + sizeof(expbuf)); + if (strlcat(expbuf, " ", sizeof(expbuf)) >= + sizeof(expbuf)) + fatal("rcs_kwexp_line: truncated"); } - end = c + 1; - /* start constructing the expansion */ - expbuf[0] = '\0'; - - if (mode & RCS_KWEXP_NAME) { - if (strlcat(expbuf, "$", sizeof(expbuf)) >= sizeof(expbuf) || - strlcat(expbuf, kwstr, sizeof(expbuf)) >= sizeof(expbuf)) - fatal("rcs_kwexp_line: truncated"); - if ((mode & RCS_KWEXP_VAL) && - strlcat(expbuf, ": ", sizeof(expbuf)) >= sizeof(expbuf)) + if (kwtype & RCS_KW_REVISION) { + rcsnum_tostr(rdp->rd_num, buf, sizeof(buf)); + if (strlcat(buf, " ", sizeof(buf)) >= + sizeof(buf) || strlcat(expbuf, buf, + sizeof(expbuf)) >= sizeof(buf)) fatal("rcs_kwexp_line: truncated"); } - /* - * order matters because of RCS_KW_ID and - * RCS_KW_HEADER here - */ - if (mode & RCS_KWEXP_VAL) { - if (kwtype & RCS_KW_RCSFILE) { - if (!(kwtype & RCS_KW_FULLPATH)) - (void)strlcat(expbuf, basename(rcsfile), sizeof(expbuf)); - else - (void)strlcat(expbuf, rcsfile, sizeof(expbuf)); - if (strlcat(expbuf, " ", sizeof(expbuf)) >= sizeof(expbuf)) - fatal("rcs_kwexp_line: truncated"); - } - - if (kwtype & RCS_KW_REVISION) { - rcsnum_tostr(rdp->rd_num, buf, sizeof(buf)); - if (strlcat(buf, " ", sizeof(buf)) >= sizeof(buf) || - strlcat(expbuf, buf, sizeof(expbuf)) >= sizeof(buf)) - fatal("rcs_kwexp_line: truncated"); - } - - if (kwtype & RCS_KW_DATE) { - fmt = "%Y/%m/%d %H:%M:%S "; - - if (strftime(buf, sizeof(buf), fmt, &rdp->rd_date) == 0) - fatal("rcs_kwexp_line: strftime failure"); - if (strlcat(expbuf, buf, sizeof(expbuf)) >= sizeof(expbuf)) - fatal("rcs_kwexp_line: string truncated"); - } - - if (kwtype & RCS_KW_MDOCDATE) { - /* - * Do not prepend ' ' for a single - * digit, %e would do so and there is - * no better format for strftime(). - */ - if (rdp->rd_date.tm_mday < 10) - fmt = "%B%e %Y "; - else - fmt = "%B %e %Y "; - - if (strftime(buf, sizeof(buf), fmt, &rdp->rd_date) == 0) - fatal("rcs_kwexp_line: strftime failure"); - if (strlcat(expbuf, buf, sizeof(expbuf)) >= sizeof(expbuf)) - fatal("rcs_kwexp_line: string truncated"); - } - - if (kwtype & RCS_KW_AUTHOR) { - if (strlcat(expbuf, rdp->rd_author, sizeof(expbuf)) >= sizeof(expbuf) || - strlcat(expbuf, " ", sizeof(expbuf)) >= sizeof(expbuf)) - fatal("rcs_kwexp_line: string truncated"); - } - - if (kwtype & RCS_KW_STATE) { - if (strlcat(expbuf, rdp->rd_state, sizeof(expbuf)) >= sizeof(expbuf) || - strlcat(expbuf, " ", sizeof(expbuf)) >= sizeof(expbuf)) - fatal("rcs_kwexp_line: string truncated"); - } - - /* order does not matter anymore below */ - if (kwtype & RCS_KW_LOG) - if (strlcat(expbuf, " ", sizeof(expbuf)) >= sizeof(expbuf)) - fatal("rcs_kwexp_line: string truncated"); + if (kwtype & RCS_KW_DATE) { + fmt = "%Y/%m/%d %H:%M:%S "; + + if (strftime(buf, sizeof(buf), fmt, + &rdp->rd_date) == 0) + fatal("rcs_kwexp_line: strftime " + "failure"); + if (strlcat(expbuf, buf, sizeof(expbuf)) >= + sizeof(expbuf)) + fatal("rcs_kwexp_line: string " + "truncated"); + } - if (kwtype & RCS_KW_SOURCE) { - if (strlcat(expbuf, rcsfile, sizeof(expbuf)) >= sizeof(expbuf) || - strlcat(expbuf, " ", sizeof(expbuf)) >= sizeof(expbuf)) - fatal("rcs_kwexp_line: string truncated"); - } + if (kwtype & RCS_KW_MDOCDATE) { + /* + * Do not prepend ' ' for a single + * digit, %e would do so and there is + * no better format for strftime(). + */ + if (rdp->rd_date.tm_mday < 10) + fmt = "%B%e %Y "; + else + fmt = "%B %e %Y "; + + if (strftime(buf, sizeof(buf), fmt, + &rdp->rd_date) == 0) + fatal("rcs_kwexp_line: strftime " + "failure"); + if (strlcat(expbuf, buf, sizeof(expbuf)) >= + sizeof(expbuf)) + fatal("rcs_kwexp_line: string " + "truncated"); + } - if (kwtype & RCS_KW_NAME) - if (strlcat(expbuf, " ", sizeof(expbuf)) >= sizeof(expbuf)) - fatal("rcs_kwexp_line: string truncated"); + if (kwtype & RCS_KW_AUTHOR) { + if (strlcat(expbuf, rdp->rd_author, + sizeof(expbuf)) >= sizeof(expbuf) || + strlcat(expbuf, " ", sizeof(expbuf)) >= + sizeof(expbuf)) + fatal("rcs_kwexp_line: string " + "truncated"); + } - if (kwtype & RCS_KW_LOCKER) - if (strlcat(expbuf, " ", sizeof(expbuf)) >= sizeof(expbuf)) - fatal("rcs_kwexp_line: string truncated"); + if (kwtype & RCS_KW_STATE) { + if (strlcat(expbuf, rdp->rd_state, + sizeof(expbuf)) >= sizeof(expbuf) || + strlcat(expbuf, " ", sizeof(expbuf)) >= + sizeof(expbuf)) + fatal("rcs_kwexp_line: string " + "truncated"); } - /* end the expansion */ - if (mode & RCS_KWEXP_NAME) - if (strlcat(expbuf, "$", + /* order does not matter anymore below */ + if (kwtype & RCS_KW_LOG) + if (strlcat(expbuf, " ", sizeof(expbuf)) >= + sizeof(expbuf)) + fatal("rcs_kwexp_line: string " + "truncated"); + + if (kwtype & RCS_KW_SOURCE) { + if (strlcat(expbuf, rcsfile, sizeof(expbuf)) >= + sizeof(expbuf) || strlcat(expbuf, " ", sizeof(expbuf)) >= sizeof(expbuf)) - fatal("rcs_kwexp_line: truncated"); + fatal("rcs_kwexp_line: string " + "truncated"); + } - /* Concatenate everything together. */ - tmpbuf = cvs_buf_alloc(len + strlen(expbuf), BUF_AUTOEXT); - /* Append everything before keyword. */ - cvs_buf_append(tmpbuf, line->l_line, - start - line->l_line); - /* Append keyword. */ - cvs_buf_append(tmpbuf, expbuf, strlen(expbuf)); - /* Point c to end of keyword. */ - tlen = cvs_buf_len(tmpbuf) - 1; - /* Append everything after keyword. */ - cvs_buf_append(tmpbuf, end, - line->l_line + line->l_len - end); - c = cvs_buf_get(tmpbuf) + tlen; - /* Point fin to end of data. */ - fin = cvs_buf_get(tmpbuf) + cvs_buf_len(tmpbuf) - 1; - /* Recalculate new length. */ - len = cvs_buf_len(tmpbuf); - - /* tmpbuf is now ready, convert to string */ - if (line->l_needsfree) - xfree(line->l_line); - line->l_len = len; - line->l_line = cvs_buf_release(tmpbuf); - line->l_needsfree = 1; + if (kwtype & RCS_KW_NAME) + if (strlcat(expbuf, " ", sizeof(expbuf)) >= + sizeof(expbuf)) + fatal("rcs_kwexp_line: string " + "truncated"); + + if (kwtype & RCS_KW_LOCKER) + if (strlcat(expbuf, " ", sizeof(expbuf)) >= + sizeof(expbuf)) + fatal("rcs_kwexp_line: string " + "truncated"); } + + /* end the expansion */ + if (mode & RCS_KWEXP_NAME) + if (strlcat(expbuf, "$", + sizeof(expbuf)) >= sizeof(expbuf)) + fatal("rcs_kwexp_line: truncated"); + + /* Concatenate everything together. */ + tmpbuf = cvs_buf_alloc(len + strlen(expbuf), BUF_AUTOEXT); + /* Append everything before keyword. */ + cvs_buf_append(tmpbuf, line->l_line, + start - line->l_line); + /* Append keyword. */ + cvs_buf_append(tmpbuf, expbuf, strlen(expbuf)); + /* Point c to end of keyword. */ + tlen = cvs_buf_len(tmpbuf) - 1; + /* Append everything after keyword. */ + cvs_buf_append(tmpbuf, end, + line->l_line + line->l_len - end); + c = cvs_buf_get(tmpbuf) + tlen; + /* Point fin to end of data. */ + fin = cvs_buf_get(tmpbuf) + cvs_buf_len(tmpbuf) - 1; + /* Recalculate new length. */ + len = cvs_buf_len(tmpbuf); + + /* tmpbuf is now ready, convert to string */ + if (line->l_needsfree) + xfree(line->l_line); + line->l_len = len; + line->l_line = cvs_buf_release(tmpbuf); + line->l_needsfree = 1; } } |