diff options
author | sepotvin <sepotvin@FreeBSD.org> | 2009-05-08 02:18:46 +0000 |
---|---|---|
committer | sepotvin <sepotvin@FreeBSD.org> | 2009-05-08 02:18:46 +0000 |
commit | e89e15c13db72fc3d3b1bd5745c30120445e9409 (patch) | |
tree | 866bcb97cc0bd25d3053cc96c7f8a37922b0ea14 /gnu | |
parent | a51a65fed4c9f5062b1713275072bf2d9f2b63e5 (diff) | |
download | FreeBSD-src-e89e15c13db72fc3d3b1bd5745c30120445e9409.zip FreeBSD-src-e89e15c13db72fc3d3b1bd5745c30120445e9409.tar.gz |
Change the internal buffer used to store input lines from a static buffer
to a dynamically allocated one in order to support input lines of
arbitrary length.
Approved by: kan (mentor)
MFC after: 1 month
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/usr.bin/patch/common.h | 5 | ||||
-rw-r--r-- | gnu/usr.bin/patch/inp.c | 4 | ||||
-rw-r--r-- | gnu/usr.bin/patch/patch.c | 5 | ||||
-rw-r--r-- | gnu/usr.bin/patch/pch.c | 97 | ||||
-rw-r--r-- | gnu/usr.bin/patch/pch.h | 2 | ||||
-rw-r--r-- | gnu/usr.bin/patch/util.c | 14 |
6 files changed, 74 insertions, 53 deletions
diff --git a/gnu/usr.bin/patch/common.h b/gnu/usr.bin/patch/common.h index ed97132..7063be6 100644 --- a/gnu/usr.bin/patch/common.h +++ b/gnu/usr.bin/patch/common.h @@ -63,7 +63,7 @@ #define MAXHUNKSIZE 200000 /* is this enough lines? */ #define INITHUNKMAX 125 /* initial dynamic allocation size */ -#define MAXLINELEN 4096 +#define INITLINELEN 4096 #define BUFFERSIZE 4096 #define SCCSPREFIX "s." @@ -105,7 +105,8 @@ EXT int optind_last; /* for restarting plan_b */ EXT struct stat filestat; /* file statistics area */ EXT int filemode INIT(0644); -EXT char buf[MAXLINELEN]; /* general purpose buffer */ +EXT char *buf; /* general purpose buffer */ +EXT size_t buf_size; /* size of the general purpose buffer */ EXT FILE *ofp INIT(Nullfp); /* output file pointer */ EXT FILE *rejfp INIT(Nullfp); /* reject file pointer */ diff --git a/gnu/usr.bin/patch/inp.c b/gnu/usr.bin/patch/inp.c index d77ef65..17f8adb 100644 --- a/gnu/usr.bin/patch/inp.c +++ b/gnu/usr.bin/patch/inp.c @@ -79,7 +79,7 @@ plan_a(char *filename) int ifd, statfailed; Reg1 char *s; Reg2 LINENUM iline; - char lbuf[MAXLINELEN]; + char lbuf[INITLINELEN]; int output_elsewhere = strcmp(filename, outname); extern int check_patch; @@ -284,7 +284,7 @@ plan_b(char *filename) pfatal2("can't open file %s", filename); if ((tifd = creat(TMPINNAME, 0666)) < 0) pfatal2("can't open file %s", TMPINNAME); - while (fgets(buf, sizeof buf, ifp) != Nullch) { + while (fgets(buf, buf_size, ifp) != Nullch) { if (revision != Nullch && !found_revision && rev_in_string(buf)) found_revision = TRUE; if ((i = strlen(buf)) > maxlen) diff --git a/gnu/usr.bin/patch/patch.c b/gnu/usr.bin/patch/patch.c index 8e06c33..fbf7e70 100644 --- a/gnu/usr.bin/patch/patch.c +++ b/gnu/usr.bin/patch/patch.c @@ -155,6 +155,11 @@ char **argv; for (i = 0; i<MAXFILEC; i++) filearg[i] = Nullch; + buf_size = INITLINELEN; + buf = malloc((MEM)(buf_size)); + if (buf == Nullch) + fatal1("out of memory\n"); + myuid = getuid(); index_first = getenv ("PATCH_INDEX_FIRST") != 0; diff --git a/gnu/usr.bin/patch/pch.c b/gnu/usr.bin/patch/pch.c index 7dee1a6..1638241 100644 --- a/gnu/usr.bin/patch/pch.c +++ b/gnu/usr.bin/patch/pch.c @@ -87,7 +87,7 @@ open_patch_file(char *filename) pfp = fopen(TMPPATNAME, "w"); if (pfp == Nullfp) pfatal2("can't create %s", TMPPATNAME); - while (fgets(buf, sizeof buf, stdin) != Nullch) + while (fgets(buf, buf_size, stdin) != Nullch) fputs(buf, pfp); Fclose(pfp); filename = TMPPATNAME; @@ -248,7 +248,7 @@ intuit_diff_type(void) this_line = ftell(pfp); indent = 0; p_input_line++; - if (fgets(buf, sizeof buf, pfp) == Nullch) { + if (pgets(FALSE) == 0) { if (first_command_line >= 0L) { /* nothing but deletes!? */ p_start = first_command_line; @@ -427,15 +427,15 @@ next_intuit_at(long file_pos, long file_line) void skip_to(long file_pos, long file_line) { - char *ret; + size_t len; assert(p_base <= file_pos); if (verbose && p_base < file_pos) { Fseek(pfp, p_base, 0); say1("The text leading up to this was:\n--------------------------\n"); while (ftell(pfp) < file_pos) { - ret = fgets(buf, sizeof buf, pfp); - assert(ret != Nullch); + len = pgets(FALSE); + assert(len != 0); say2("|%s", buf); } say1("--------------------------\n"); @@ -486,7 +486,7 @@ bool another_hunk(void) { Reg1 char *s; - Reg8 char *ret; + size_t len; Reg2 int context = 0; while (p_end >= 0) { @@ -517,9 +517,9 @@ another_hunk(void) Reg7 LINENUM ptrn_copiable = 0; /* # of copiable lines in ptrn */ - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch || strnNE(buf, "********", 8)) { + if (len == 0 || strnNE(buf, "********", 8)) { next_intuit_at(line_beginning,p_input_line); return FALSE; } @@ -527,9 +527,9 @@ another_hunk(void) p_hunk_beg = p_input_line + 1; while (p_end < p_max) { line_beginning = ftell(pfp); - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch) { + if (len == 0) { if (p_max - p_end < 4) Strcpy(buf, " \n"); /* assume blank lines got chopped */ else { @@ -839,9 +839,9 @@ another_hunk(void) Reg5 LINENUM filldst; /* index of new lines */ char ch; - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch || strnNE(buf, "@@ -", 4)) { + if (len == 0 || strnNE(buf, "@@ -", 4)) { next_intuit_at(line_beginning,p_input_line); return FALSE; } @@ -895,9 +895,9 @@ another_hunk(void) p_hunk_beg = p_input_line + 1; while (fillsrc <= p_ptrn_lines || filldst <= p_end) { line_beginning = ftell(pfp); - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch) { + if (len == 0) { if (p_max - filldst < 3) Strcpy(buf, " \n"); /* assume blank lines got chopped */ else { @@ -994,9 +994,9 @@ another_hunk(void) long line_beginning = ftell(pfp); p_context = 0; - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch || !isdigit((unsigned char)*buf)) { + if (len == 0 || !isdigit((unsigned char)*buf)) { next_intuit_at(line_beginning,p_input_line); return FALSE; } @@ -1035,9 +1035,9 @@ another_hunk(void) } p_Char[0] = '*'; for (i=1; i<=p_ptrn_lines; i++) { - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch) + if (len == 0) fatal2("unexpected end of file in patch at line %ld\n", p_input_line); if (*buf != '<') @@ -1057,9 +1057,9 @@ another_hunk(void) } if (hunk_type == 'c') { - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch) + if (len == 0) fatal2("unexpected end of file in patch at line %ld\n", p_input_line); if (*buf != '-') @@ -1073,9 +1073,9 @@ another_hunk(void) } p_Char[i] = '='; for (i++; i<=p_end; i++) { - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch) + if (len == 0) fatal2("unexpected end of file in patch at line %ld\n", p_input_line); if (*buf != '>') @@ -1118,28 +1118,43 @@ another_hunk(void) } /* - * Input a line from the patch file, worrying about indentation. + * Input a line from the patch file. + * Worry about indentation if do_indent is true. + * The line is read directly into the buf global variable which + * is resized if necessary in order to hold the complete line. + * Returns the number of characters read including the terminating + * '\n', if any. */ -char * -pgets(char *bf, int sz, FILE *fp) +size_t +pgets(bool do_indent) { - char *ret = fgets(bf, sz, fp); - Reg1 char *s; - Reg2 int indent = 0; + char *line; + size_t len; + int indent = 0, skipped = 0; - if (p_indent && ret != Nullch) { - for (s=buf; - indent < p_indent && (*s == ' ' || *s == '\t' || *s == 'X'); - s++) { - if (*s == '\t') - indent += 8 - (indent % 7); - else - indent++; + line = fgetln(pfp, &len); + if (line != Nullch) { + if (len + 1 > buf_size) { + while (len + 1 > buf_size) + buf_size *= 2; + free(buf); + buf = malloc(buf_size); + if (buf == Nullch) + fatal1("out of memory\n"); + } + if (do_indent == TRUE && p_indent) { + for (; + indent < p_indent && (*line == ' ' || *line == '\t' || *line == 'X'); + line++, skipped++) { + if (*line == '\t') + indent += 8 - (indent %7); + else + indent++; + } } - if (buf != s) - Strcpy(buf, s); + Strlcpy(buf, line, len + 1 - skipped); } - return ret; + return len; } /* @@ -1360,7 +1375,7 @@ do_ed_script(void) } for (;;) { beginning_of_this_line = ftell(pfp); - if (pgets(buf, sizeof buf, pfp) == Nullch) { + if (pgets(TRUE) == 0) { next_intuit_at(beginning_of_this_line, p_input_line); break; } @@ -1373,7 +1388,7 @@ do_ed_script(void) if (!skip_rest_of_patch) fputs(buf, pipefp); if (*t != 'd') { - while (pgets(buf, sizeof buf, pfp) != Nullch) { + while (pgets(TRUE) != 0) { p_input_line++; if (!skip_rest_of_patch) fputs(buf, pipefp); diff --git a/gnu/usr.bin/patch/pch.h b/gnu/usr.bin/patch/pch.h index d815fe8..0393dea 100644 --- a/gnu/usr.bin/patch/pch.h +++ b/gnu/usr.bin/patch/pch.h @@ -32,5 +32,5 @@ LINENUM pch_context(void); LINENUM pch_hunk_beg(void); char pch_char(LINENUM _line); char *pfetch(LINENUM _line); -char *pgets(char *_bf, int _sz, FILE *_fp); +size_t pgets(bool _do_indent); void do_ed_script(void); diff --git a/gnu/usr.bin/patch/util.c b/gnu/usr.bin/patch/util.c index b6e6652..5a76a03 100644 --- a/gnu/usr.bin/patch/util.c +++ b/gnu/usr.bin/patch/util.c @@ -46,7 +46,7 @@ move_file(char *from, char *to) fromfd = open(from, 0); if (fromfd < 0) pfatal2("internal error, can't reopen %s", from); - while ((i = read(fromfd, buf, sizeof buf)) > 0) + while ((i = read(fromfd, buf, buf_size)) > 0) if (write(1, buf, i) != 1) pfatal1("write failed"); Close(fromfd); @@ -126,7 +126,7 @@ move_file(char *from, char *to) fromfd = open(from, 0); if (fromfd < 0) pfatal2("internal error, can't reopen %s", from); - while ((i = read(fromfd, buf, sizeof buf)) > 0) + while ((i = read(fromfd, buf, buf_size)) > 0) if (write(tofd, buf, i) != i) pfatal1("write failed"); Close(fromfd); @@ -152,7 +152,7 @@ copy_file(char *from, char *to) fromfd = open(from, 0); if (fromfd < 0) pfatal2("internal error, can't reopen %s", from); - while ((i = read(fromfd, buf, sizeof buf)) > 0) + while ((i = read(fromfd, buf, buf_size)) > 0) if (write(tofd, buf, i) != i) pfatal2("write to %s failed", to); Close(fromfd); @@ -256,20 +256,20 @@ long arg1,arg2,arg3; Fflush(stderr); write(2, buf, strlen(buf)); if (tty2) { /* might be redirected to a file */ - r = read(2, buf, sizeof buf); + r = read(2, buf, buf_size); } else if (isatty(1)) { /* this may be new file output */ Fflush(stdout); write(1, buf, strlen(buf)); - r = read(1, buf, sizeof buf); + r = read(1, buf, buf_size); } else if ((ttyfd = open(_PATH_TTY, 2)) >= 0 && isatty(ttyfd)) { /* might be deleted or unwriteable */ write(ttyfd, buf, strlen(buf)); - r = read(ttyfd, buf, sizeof buf); + r = read(ttyfd, buf, buf_size); Close(ttyfd); } else if (isatty(0)) { /* this is probably patch input */ Fflush(stdin); write(0, buf, strlen(buf)); - r = read(0, buf, sizeof buf); + r = read(0, buf, buf_size); } else { /* no terminal at all--default it */ buf[0] = '\n'; buf[1] = 0; |