summaryrefslogtreecommitdiff
path: root/usr.bin/rcs
diff options
context:
space:
mode:
authorRay Lai <ray@cvs.openbsd.org>2006-07-21 00:47:36 +0000
committerRay Lai <ray@cvs.openbsd.org>2006-07-21 00:47:36 +0000
commit53ae3275f8d4018706772981cbad38b9a19181e7 (patch)
tree45886ad7484ea6735de03eb1f693dc34898a12af /usr.bin/rcs
parent99f0e7df0ca7a5589c64c383099e788306ba6dcf (diff)
Revert; keywords did not expand.
Diffstat (limited to 'usr.bin/rcs')
-rw-r--r--usr.bin/rcs/rcs.c119
1 files changed, 55 insertions, 64 deletions
diff --git a/usr.bin/rcs/rcs.c b/usr.bin/rcs/rcs.c
index f5412e6b447..5567b21eb27 100644
--- a/usr.bin/rcs/rcs.c
+++ b/usr.bin/rcs/rcs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcs.c,v 1.24 2006/07/21 00:21:52 ray Exp $ */
+/* $OpenBSD: rcs.c,v 1.25 2006/07/21 00:47:35 ray Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -2567,14 +2567,15 @@ rcs_strprint(const u_char *str, size_t slen, FILE *stream)
static BUF *
rcs_expand_keywords(char *rcsfile, struct rcs_delta *rdp, BUF *bp, int mode)
{
- BUF *newbuf;
+ ptrdiff_t c_offset, sizdiff, start_offset;
+ size_t i;
int kwtype;
u_int j, found;
- u_char *c, *kwstr, *start, *end, *fin;
+ u_char *c, *data, *kwstr, *start, *end, *tbuf, *fin;
char expbuf[256], buf[256];
struct tm tb;
char *fmt;
- size_t len;
+ size_t len, tbuflen;
kwtype = 0;
kwstr = NULL;
@@ -2590,29 +2591,13 @@ rcs_expand_keywords(char *rcsfile, struct rcs_delta *rdp, BUF *bp, int mode)
c = rcs_buf_get(bp);
found = 0;
- /* Final character in buffer. */
- fin = c + len - 1;
-
- /* If no keywords exist, return original BUF. */
- while (c < fin && !found) {
+ for (i = 0; i < len; i++) {
if (*c == '$') {
- size_t clen;
-
- /* Skip initial `$'. */
c++;
- /* Number of characters between c and fin, inclusive. */
- clen = fin - c + 1;
+ i++;
for (j = 0; j < RCS_NKWORDS; j++) {
- size_t kwlen;
-
- 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] == ':')) {
+ if (!strncmp(c, rcs_expkw[j].kw_str,
+ strlen(rcs_expkw[j].kw_str))) {
found = 1;
kwstr = rcs_expkw[j].kw_str;
kwtype = rcs_expkw[j].kw_type;
@@ -2625,8 +2610,11 @@ rcs_expand_keywords(char *rcsfile, struct rcs_delta *rdp, BUF *bp, int mode)
if (found == 0)
return (bp);
- /* If no keywords are found, return original buffer. */
- newbuf = bp;
+ rcs_buf_putc(bp, '\0');
+ data = rcs_buf_release(bp);
+ c = data;
+ fin = c + len;
+ len++;
/*
* Keyword formats:
@@ -2635,11 +2623,9 @@ rcs_expand_keywords(char *rcsfile, struct rcs_delta *rdp, BUF *bp, int mode)
*/
for (; c < fin; c++) {
if (*c == '$') {
- BUF *tmpbuf;
- size_t clen;
-
/* remember start of this possible keyword */
start = c;
+ start_offset = start - data;
/* first following character has to be alphanumeric */
c++;
@@ -2648,26 +2634,14 @@ rcs_expand_keywords(char *rcsfile, struct rcs_delta *rdp, BUF *bp, int mode)
continue;
}
- /* 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++) {
- size_t kwlen;
-
- 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] == ':')) {
+ if (!strncmp(c, rcs_expkw[j].kw_str,
+ strlen(rcs_expkw[j].kw_str))) {
found = 1;
kwstr = rcs_expkw[j].kw_str;
kwtype = rcs_expkw[j].kw_type;
- c += kwlen;
break;
}
}
@@ -2678,13 +2652,20 @@ rcs_expand_keywords(char *rcsfile, struct rcs_delta *rdp, BUF *bp, int mode)
continue;
}
+ /* next character has to be ':' or '$' */
+ c += strlen(kwstr);
+ if (*c != ':' && *c != '$') {
+ 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) {
+ while (*c++) {
if (*c == '$' || *c == '\n')
break;
}
@@ -2694,6 +2675,7 @@ rcs_expand_keywords(char *rcsfile, struct rcs_delta *rdp, BUF *bp, int mode)
continue;
}
}
+ c_offset = c - data;
end = c + 1;
/* start constructing the expansion */
@@ -2773,29 +2755,38 @@ rcs_expand_keywords(char *rcsfile, struct rcs_delta *rdp, BUF *bp, int mode)
if (strlcat(expbuf, "$", sizeof(expbuf)) >= sizeof(expbuf))
errx(1, "rcs_expand_keywords: string truncated");
- /* Concatenate everything together. */
- tmpbuf = rcs_buf_alloc(len + strlen(expbuf), BUF_AUTOEXT);
- /* Append everything before keyword. */
- rcs_buf_append(tmpbuf, rcs_buf_get(newbuf),
- start - (unsigned char *)rcs_buf_get(newbuf));
- /* Append keyword. */
- rcs_buf_append(tmpbuf, expbuf, strlen(expbuf));
- /* Point c to end of keyword. */
- c = rcs_buf_get(tmpbuf) + rcs_buf_len(tmpbuf) - 1;
- /* Append everything after keyword. */
- rcs_buf_append(tmpbuf, end,
- ((unsigned char *)rcs_buf_get(newbuf) + rcs_buf_len(newbuf)) - end);
- /* Point fin to end of data. */
- fin = rcs_buf_get(tmpbuf) + rcs_buf_len(tmpbuf) - 1;
-
- /* tmpbuf is now ready, free old newbuf if allocated here. */
- if (newbuf != bp)
- rcs_buf_free(newbuf);
- newbuf = tmpbuf;
+ sizdiff = strlen(expbuf) - (end - start);
+ tbuflen = fin - end;
+ tbuf = xmalloc(tbuflen);
+ memcpy(tbuf, end, tbuflen);
+ /* only realloc if we have to */
+ if (sizdiff > 0) {
+ char *newdata;
+
+ len += sizdiff;
+ newdata = xrealloc(data, 1, len);
+ data = newdata;
+ /*
+ * ensure string pointers are not invalidated
+ * after realloc()
+ */
+ start = data + start_offset;
+ fin = data + len;
+ c = data + c_offset;
+ }
+ memcpy(start, expbuf, strlen(expbuf) + 1);
+ start += strlen(expbuf);
+ memcpy(start, tbuf, tbuflen);
+ xfree(tbuf);
+ c = start + strlen(expbuf);
}
}
- return (newbuf);
+ bp = rcs_buf_alloc(len - 1, BUF_AUTOEXT);
+ rcs_buf_set(bp, data, len - 1, 0);
+ xfree(data);
+
+ return (bp);
}
/*