# HG changeset patch # User Miles Bader # Date 1003672096 0 # Node ID 89269b100451a8fbdd230ff835f1bd03d4a339a8 # Parent 9fb304fb3f211f0f80f72bb129bad6b30903d08a (struct rcsoc_state): New type. (read_c_string_or_comment): Use a variable of type `rcsoc_state' to hold most of our state. (put_char): Add STATE parameter, and remove all other parameters except CH. Use STATE to get access to all needed state. (scan_keyword_or_put_char): New function. diff -r 9fb304fb3f21 -r 89269b100451 lib-src/make-docfile.c --- a/lib-src/make-docfile.c Sun Oct 21 13:28:46 2001 +0000 +++ b/lib-src/make-docfile.c Sun Oct 21 13:48:16 2001 +0000 @@ -198,42 +198,122 @@ char buf[128]; -/* Add CH to either outfile, if PRINTFLAG is positive, or to the buffer - whose end is pointed to by BUFP, if PRINTFLAG is negative. - If the counters pointed to by PENDING_NEWLINES and PENDING_SPACES are - non-zero, that many newlines and spaces are output before CH, and - the counters are zeroed. */ +/* Some state during the execution of `read_c_string_or_comment'. */ +struct rcsoc_state +{ + /* A count of spaces and newlines that have been read, but not output. */ + unsigned pending_spaces, pending_newlines; + + /* Where we're reading from. */ + FILE *in_file; + + /* If non-zero, a buffer into which to copy characters. */ + char *buf_ptr; + /* If non-zero, a file into which to copy characters. */ + FILE *out_file; + + /* A keyword we look for at the beginning of lines. If found, it is + not copied, and SAW_KEYWORD is set to true. */ + char *keyword; + /* The current point we've reached in an occurance of KEYWORD in + the input stream. */ + char *cur_keyword_ptr; + /* Set to true if we saw an occurance of KEYWORD. */ + int saw_keyword; +}; + +/* Output CH to the file or buffer in STATE. Any pending newlines or + spaces are output first. */ static INLINE void -put_char (ch, printflag, bufp, pending_newlines, pending_spaces) - int ch, printflag; - char **bufp; - unsigned *pending_newlines, *pending_spaces; +put_char (ch, state) + int ch; + struct rcsoc_state *state; { int out_ch; do { - if (*pending_newlines > 0) + if (state->pending_newlines > 0) { - (*pending_newlines)--; + state->pending_newlines--; out_ch = '\n'; } - else if (*pending_spaces > 0) + else if (state->pending_spaces > 0) { - (*pending_spaces)--; + state->pending_spaces--; out_ch = ' '; } else out_ch = ch; - if (printflag > 0) - putc (out_ch, outfile); - else if (printflag < 0) - *(*bufp)++ = out_ch; + if (state->out_file) + putc (out_ch, state->out_file); + if (state->buf_ptr) + *state->buf_ptr++ = out_ch; } while (out_ch != ch); } +/* If in the middle of scanning a keyword, continue scanning with + character CH, otherwise output CH to the file or buffer in STATE. + Any pending newlines or spaces are output first, as well as any + previously scanned characters that were thought to be part of a + keyword, but were in fact not. */ + +static void +scan_keyword_or_put_char (ch, state) + int ch; + struct rcsoc_state *state; +{ + if (state->keyword + && *state->cur_keyword_ptr == ch + && (state->cur_keyword_ptr > state->keyword + || state->pending_newlines > 0)) + /* We might be looking at STATE->keyword at some point. + Keep looking until we know for sure. */ + { + if (*++state->cur_keyword_ptr == '\0') + /* Saw the whole keyword. Set SAW_KEYWORD flag to true. */ + { + state->saw_keyword = 1; + + /* Reset the scanning pointer. */ + state->cur_keyword_ptr = state->keyword; + + /* Canonicalize whitespace preceding a usage string. */ + state->pending_newlines = 2; + state->pending_spaces = 0; + + /* Skip any whitespace between the keyword and the + usage string. */ + do + ch = getc (state->in_file); + while (ch == ' ' || ch == '\n'); + + /* Put back the non-whitespace character. */ + ungetc (ch, state->in_file); + } + } + else + { + if (state->keyword && state->cur_keyword_ptr > state->keyword) + /* We scanned the beginning of a potential usage + keyword, but it was a false alarm. Output the + part we scanned. */ + { + char *p; + + for (p = state->keyword; p < state->cur_keyword_ptr; p++) + put_char (*p, state); + + state->cur_keyword_ptr = state->keyword; + } + + put_char (ch, state); + } +} + + /* Skip a C string or C-style comment from INFILE, and return the character that follows. COMMENT non-zero means skip a comment. If PRINTFLAG is positive, output string contents to outfile. If it is @@ -250,26 +330,21 @@ int *saw_usage; { register int c; - unsigned pending_spaces = 0, pending_newlines = 0; - char *p = buf; - /* When this keyword occurs at the beginning of a line, we remove it, - and set *SAW_USAGE to true. */ - static char usage_keyword[] = "usage:"; - /* The current point we've reached in an occurance of USAGE_KEYWORD in - the input stream. */ - char *cur_usage_ptr = usage_keyword; + struct rcsoc_state state; + state.in_file = infile; + state.buf_ptr = (printflag < 0 ? buf : 0); + state.out_file = (printflag > 0 ? outfile : 0); + state.pending_spaces = 0; + state.pending_newlines = 0; + state.keyword = (saw_usage ? "usage:" : 0); + state.cur_keyword_ptr = state.keyword; + state.saw_keyword = 0; + + c = getc (infile); if (comment) - { - while ((c = getc (infile)) != EOF - && (c == '\n' || c == '\r' || c == '\t' || c == ' ')) - ; - } - else - c = getc (infile); - - if (saw_usage) - *saw_usage = 0; + while (c == '\n' || c == '\r' || c == '\t' || c == ' ') + c = getc (infile); while (c != EOF) { @@ -290,59 +365,14 @@ } if (c == ' ') - pending_spaces++; + state.pending_spaces++; else if (c == '\n') { - pending_newlines++; - pending_spaces = 0; + state.pending_newlines++; + state.pending_spaces = 0; } else - { - if (saw_usage - && *cur_usage_ptr == c - && (cur_usage_ptr > usage_keyword || pending_newlines > 0)) - /* We might be looking at USAGE_KEYWORD at some point. - Keep looking until we know for sure. */ - { - if (*++cur_usage_ptr == '\0') - /* Saw the whole keyword. Set *SAW_USAGE to true. */ - { - *saw_usage = 1; - - /* Reset the scanning pointer. */ - cur_usage_ptr = usage_keyword; - - /* Canonicalize whitespace preceding a usage string. */ - pending_newlines = 2; - pending_spaces = 0; - - /* Skip any whitespace between the keyword and the - usage string. */ - do - c = getc (infile); - while (c == ' ' || c == '\n'); - - continue; /* This just skips the getc at end-of-loop. */ - } - } - else - { - if (cur_usage_ptr > usage_keyword) - /* We scanned the beginning of a potential usage - keyword, but it was a false alarm. Output the - part we scanned. */ - { - char *p; - for (p = usage_keyword; p < cur_usage_ptr; p++) - put_char (*p, printflag, &p, - &pending_newlines, &pending_spaces); - cur_usage_ptr = usage_keyword; - } - - put_char (c, printflag, &p, - &pending_newlines, &pending_spaces); - } - } + scan_keyword_or_put_char (c, &state); c = getc (infile); } @@ -358,7 +388,7 @@ break; } - put_char ('*', printflag, &p, &pending_newlines, &pending_spaces); + scan_keyword_or_put_char ('*', &state); } else { @@ -371,7 +401,10 @@ } if (printflag < 0) - *p = 0; + *state.buf_ptr = 0; + + if (saw_usage) + *saw_usage = state.saw_keyword; return c; }