--- rcs.c 2005-10-06 15:41:28.000000000 -0400 +++ rcs.c.new 2006-08-29 09:08:56.000000000 -0400 @@ -17,6 +17,7 @@ #include "cvs.h" #include "edit.h" #include "hardlink.h" +#include /* These need to be source after cvs.h or HAVE_MMAP won't be set... */ #ifdef HAVE_MMAP @@ -6854,9 +6855,9 @@ { if (vec->lines_alloced == 0) vec->lines_alloced = 10; - while (vec->nlines + nnew >= vec->lines_alloced) - vec->lines_alloced *= 2; - vec->vector = xnrealloc (vec->vector, + while (vec->nlines + nnew >= vec->lines_alloced) + vec->lines_alloced *= 2; + vec->vector = xnrealloc (vec->vector, vec->lines_alloced, sizeof (*vec->vector)); } @@ -6871,27 +6872,28 @@ i = pos; nextline_text = text; nextline_newline = 0; - for (p = text; p < textend; ++p) - if (*p == '\n') - { - nextline_newline = 1; - if (p + 1 == textend) - /* If there are no characters beyond the last newline, we - don't consider it another line. */ - break; - nextline_len = p - nextline_text; - q = xmalloc (sizeof (struct line) + nextline_len); - q->vers = vers; - q->text = (char *)q + sizeof (struct line); - q->len = nextline_len; - q->has_newline = nextline_newline; - q->refcount = 1; - memcpy (q->text, nextline_text, nextline_len); - vec->vector[i++] = q; - - nextline_text = (char *)p + 1; - nextline_newline = 0; - } + for (p = text; p < textend; ++p) { + if (*p == '\n') + { + nextline_newline = 1; + if (p + 1 == textend) + /* If there are no characters beyond the last newline, we + don't consider it another line. */ + break; + nextline_len = p - nextline_text; + q = xmalloc (sizeof (struct line) + nextline_len); + q->vers = vers; + q->text = (char *)q + sizeof (struct line); + q->len = nextline_len; + q->has_newline = nextline_newline; + q->refcount = 1; + memcpy (q->text, nextline_text, nextline_len); + vec->vector[i++] = q; + + nextline_text = (char *)p + 1; + nextline_newline = 0; + } + } nextline_len = p - nextline_text; q = xmalloc (sizeof (struct line) + nextline_len); q->vers = vers; @@ -7034,105 +7036,103 @@ struct deltafrag *dfhead; struct deltafrag *dftail; struct deltafrag *df; - int err; - int numlines, lastmodline, offset; + int err, numfrags, numlines, lastmodline, offset, tracecount, i; struct linevector *orig_lines = lines; dfhead = NULL; + numfrags = 0; numlines = lines->nlines; // start with init # of lines - for (p = diffbuf; p != NULL && p < diffbuf + difflen; ) + for (p = diffbuf; p != NULL && p < diffbuf + difflen; numfrags++) { - op = *p++; - if (op != 'a' && op != 'd') - /* Can't just skip over the deltafrag, because the value - of op determines the syntax. */ - error (1, 0, "unrecognized operation '\\x%x' in %s", - op, name); - df = xmalloc (sizeof (struct deltafrag)); - df->next = NULL; - if (dfhead == NULL) { + op = *p++; + if (op != 'a' && op != 'd') + /* Can't just skip over the deltafrag, because the value + of op determines the syntax. */ + error (1, 0, "unrecognized operation '\\x%x' in %s", + op, name); + df = xmalloc (sizeof (struct deltafrag)); + df->next = NULL; + if (dfhead == NULL) { dfhead = df; - } - else { - dftail->next = df; - } - dftail = df; - - df->pos = strtoul (p, (char **) &q, 10); - - if (p == q) - error (1, 0, "number expected in %s", name); - p = q; - if (*p++ != ' ') - error (1, 0, "space expected in %s", name); - df->nlines = strtoul (p, (char **) &q, 10); - if (p == q) - error (1, 0, "number expected in %s", name); - p = q; - if (*p++ != '\012') - error (1, 0, "linefeed expected in %s", name); - - if (op == 'a') - { - unsigned int i; - - df->type = FRAG_ADD; - i = df->nlines; - /* The text we want is the number of lines specified, or - until the end of the value, whichever comes first (it - will be the former except in the case where we are - adding a line which does not end in newline). */ - for (q = p; i != 0; ++q) - if (*q == '\n') - --i; - else if (q == diffbuf + difflen) - { - if (i != 1) - error (1, 0, "premature end of change in %s", name); - else - break; - } - - /* Stash away a pointer to the text we are adding. */ - df->new_lines = p; - df->len = q - p; - - p = q; - numlines+=df->nlines; - } - else - { - /* Correct for the fact that line numbers in RCS files - start with 1. */ - --df->pos; + } + else { + dftail->next = df; + } + dftail = df; - assert (op == 'd'); - df->type = FRAG_DELETE; - numlines-=df->nlines; - } + df->pos = strtoul (p, (char **) &q, 10); + + if (p == q) + error (1, 0, "number expected in %s", name); + p = q; + if (*p++ != ' ') + error (1, 0, "space expected in %s", name); + df->nlines = strtoul (p, (char **) &q, 10); + if (p == q) + error (1, 0, "number expected in %s", name); + p = q; + if (*p++ != '\012') + error (1, 0, "linefeed expected in %s", name); + + if (op == 'a') + { + unsigned int i; + + df->type = FRAG_ADD; + i = df->nlines; + /* The text we want is the number of lines specified, or + until the end of the value, whichever comes first (it + will be the former except in the case where we are + adding a line which does not end in newline). */ + for (q = p; i != 0; ++q) + if (*q == '\n') + --i; + else if (q == diffbuf + difflen) + { + if (i != 1) + error (1, 0, "premature end of change in %s", name); + else + break; + } + + /* Stash away a pointer to the text we are adding. */ + df->new_lines = p; + df->len = q - p; + + p = q; + numlines+= df->nlines; + } + else + { + /* Correct for the fact that line numbers in RCS files + start with 1. */ + --df->pos; + + assert (op == 'd'); + df->type = FRAG_DELETE; + numlines-=df->nlines; + } } - // new temp data structure to hold new org before - // copy back into original structure. lines = xmalloc (sizeof (struct linevector)); lines->nlines = lines->lines_alloced = numlines; lines->vector = xnrealloc(NULL, numlines, sizeof(*lines->vector)); + err = 0; // we changed the list order to first to last -- so the // list never gets larger than the size numlines lastmodline = 0; offset = 0; // offset created when adding/removing lines // between new and original structure + tracecount = 0; - err = 0; - for (df = dfhead; df != NULL;) - { - unsigned int ln; + for (df = dfhead; df != NULL;) { // here we need to get to the line where the next insert will - // begin which is pos> we will fill up to df->pos with + // begin which is pos> + // we will fill from df->pos to df->pos + df->nlines-1 with // original items unsigned int deltaend = df->pos-offset; @@ -7141,13 +7141,13 @@ lines->vector[lastmodline] = orig_lines->vector[lastmodline+offset]; } - /* Once an error is encountered, just free the rest of the list and - * return. - */ - if (!err) - switch (df->type) - { - case FRAG_ADD: + /* Once an error is encountered, just free the rest of the list and + * return. + */ + if (!err) { + switch (df->type) + { + case FRAG_ADD: { const char *textend, *p; @@ -7198,46 +7198,32 @@ } - break; - case FRAG_DELETE: - offset+=df->nlines; // we are removing this many lines from the source - if (df->pos > orig_lines->nlines - || df->pos + df->nlines > orig_lines->nlines) - return 0; - if (delvers != NULL) - for (ln = df->pos; ln < df->pos + df->nlines; ++ln) { - if (--orig_lines->vector[ln]->refcount == 0) - free (orig_lines->vector[ln]); - else - orig_lines->vector[ln]->vers = delvers; - } - break; - } - - df = df->next; - free (dfhead); - dfhead = df; + break; + case FRAG_DELETE: + offset+=df->nlines; // we are removing this many lines from + // the source -- so increment the offset so we skip them + break; + } + } + + df = df->next; + free (dfhead); + dfhead = df; } - // add the rest of the remaining lines to the data vector for(;lastmodlinevector[lastmodline] = orig_lines->vector[lastmodline+offset]; } - // we didn't make the lines structure fully -- so we can't - // use the linevector_copy without issues -- so we do it inline - // make the original vector larger if necessary if (numlines > orig_lines->nlines) { - orig_lines->vector = xnrealloc (orig_lines->vector, - numlines, + orig_lines = xnrealloc (orig_lines->vector, + orig_lines->lines_alloced, sizeof (*orig_lines->vector)); - orig_lines->lines_alloced = numlines; } memcpy (orig_lines->vector, lines->vector, xtimes (lines->nlines, sizeof (*orig_lines->vector))); orig_lines->nlines = lines->nlines; - free(lines->vector); free(lines); // we don't need it any longer @@ -7429,34 +7415,34 @@ && STREQ (key, "log") && STREQ (branchversion, version)) { - if (*log != NULL) - { - error (0, 0, "Duplicate `log' keyword in RCS file (`%s').", - rcs->print_path); - free (*log); - } - *log = rcsbuf_valcopy (rcsbuf, value, 0, loglen); + if (*log != NULL) + { + error (0, 0, "Duplicate `log' keyword in RCS file (`%s').", + rcs->print_path); + free (*log); + } + *log = rcsbuf_valcopy (rcsbuf, value, 0, loglen); } if (STREQ (key, "text")) { - rcsbuf_valpolish (rcsbuf, value, 0, &vallen); - if (ishead) - { - if (! linevector_add (&curlines, value, vallen, NULL, 0)) - error (1, 0, "invalid rcs file %s", rcs->print_path); - - ishead = 0; - } - else if (isnext) - { - if (! apply_rcs_changes (&curlines, value, vallen, - rcs->path, - onbranch ? vers : NULL, - onbranch ? NULL : prev_vers)) - error (1, 0, "invalid change text in %s", rcs->print_path); - } - break; + rcsbuf_valpolish (rcsbuf, value, 0, &vallen); + if (ishead) + { + if (! linevector_add (&curlines, value, vallen, NULL, 0)) + error (1, 0, "invalid rcs file %s", rcs->print_path); + + ishead = 0; + } + else if (isnext) + { + if (! apply_rcs_changes (&curlines, value, vallen, + rcs->path, + onbranch ? vers : NULL, + onbranch ? NULL : prev_vers)) + error (1, 0, "invalid change text in %s", rcs->print_path); + } + break; } }