diff options
| author | Miles Bader | 2001-10-21 13:48:16 +0000 |
|---|---|---|
| committer | Miles Bader | 2001-10-21 13:48:16 +0000 |
| commit | 52d8c529768a1e337a065cd6ea79451b13c41afd (patch) | |
| tree | c58dacd9454a724b6b5395880b4d08a117ddb8bb /lib-src | |
| parent | 888ebd132e5d888159bcf2667844d54782cbd11e (diff) | |
| download | emacs-52d8c529768a1e337a065cd6ea79451b13c41afd.tar.gz emacs-52d8c529768a1e337a065cd6ea79451b13c41afd.zip | |
(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.
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/make-docfile.c | 207 |
1 files changed, 120 insertions, 87 deletions
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index ed786b0951e..4ddfe736325 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c | |||
| @@ -198,42 +198,122 @@ scan_file (filename) | |||
| 198 | 198 | ||
| 199 | char buf[128]; | 199 | char buf[128]; |
| 200 | 200 | ||
| 201 | /* Add CH to either outfile, if PRINTFLAG is positive, or to the buffer | 201 | /* Some state during the execution of `read_c_string_or_comment'. */ |
| 202 | whose end is pointed to by BUFP, if PRINTFLAG is negative. | 202 | struct rcsoc_state |
| 203 | If the counters pointed to by PENDING_NEWLINES and PENDING_SPACES are | 203 | { |
| 204 | non-zero, that many newlines and spaces are output before CH, and | 204 | /* A count of spaces and newlines that have been read, but not output. */ |
| 205 | the counters are zeroed. */ | 205 | unsigned pending_spaces, pending_newlines; |
| 206 | |||
| 207 | /* Where we're reading from. */ | ||
| 208 | FILE *in_file; | ||
| 209 | |||
| 210 | /* If non-zero, a buffer into which to copy characters. */ | ||
| 211 | char *buf_ptr; | ||
| 212 | /* If non-zero, a file into which to copy characters. */ | ||
| 213 | FILE *out_file; | ||
| 214 | |||
| 215 | /* A keyword we look for at the beginning of lines. If found, it is | ||
| 216 | not copied, and SAW_KEYWORD is set to true. */ | ||
| 217 | char *keyword; | ||
| 218 | /* The current point we've reached in an occurance of KEYWORD in | ||
| 219 | the input stream. */ | ||
| 220 | char *cur_keyword_ptr; | ||
| 221 | /* Set to true if we saw an occurance of KEYWORD. */ | ||
| 222 | int saw_keyword; | ||
| 223 | }; | ||
| 224 | |||
| 225 | /* Output CH to the file or buffer in STATE. Any pending newlines or | ||
| 226 | spaces are output first. */ | ||
| 206 | 227 | ||
| 207 | static INLINE void | 228 | static INLINE void |
| 208 | put_char (ch, printflag, bufp, pending_newlines, pending_spaces) | 229 | put_char (ch, state) |
| 209 | int ch, printflag; | 230 | int ch; |
| 210 | char **bufp; | 231 | struct rcsoc_state *state; |
| 211 | unsigned *pending_newlines, *pending_spaces; | ||
| 212 | { | 232 | { |
| 213 | int out_ch; | 233 | int out_ch; |
| 214 | do | 234 | do |
| 215 | { | 235 | { |
| 216 | if (*pending_newlines > 0) | 236 | if (state->pending_newlines > 0) |
| 217 | { | 237 | { |
| 218 | (*pending_newlines)--; | 238 | state->pending_newlines--; |
| 219 | out_ch = '\n'; | 239 | out_ch = '\n'; |
| 220 | } | 240 | } |
| 221 | else if (*pending_spaces > 0) | 241 | else if (state->pending_spaces > 0) |
| 222 | { | 242 | { |
| 223 | (*pending_spaces)--; | 243 | state->pending_spaces--; |
| 224 | out_ch = ' '; | 244 | out_ch = ' '; |
| 225 | } | 245 | } |
| 226 | else | 246 | else |
| 227 | out_ch = ch; | 247 | out_ch = ch; |
| 228 | 248 | ||
| 229 | if (printflag > 0) | 249 | if (state->out_file) |
| 230 | putc (out_ch, outfile); | 250 | putc (out_ch, state->out_file); |
| 231 | else if (printflag < 0) | 251 | if (state->buf_ptr) |
| 232 | *(*bufp)++ = out_ch; | 252 | *state->buf_ptr++ = out_ch; |
| 233 | } | 253 | } |
| 234 | while (out_ch != ch); | 254 | while (out_ch != ch); |
| 235 | } | 255 | } |
| 236 | 256 | ||
| 257 | /* If in the middle of scanning a keyword, continue scanning with | ||
| 258 | character CH, otherwise output CH to the file or buffer in STATE. | ||
| 259 | Any pending newlines or spaces are output first, as well as any | ||
| 260 | previously scanned characters that were thought to be part of a | ||
| 261 | keyword, but were in fact not. */ | ||
| 262 | |||
| 263 | static void | ||
| 264 | scan_keyword_or_put_char (ch, state) | ||
| 265 | int ch; | ||
| 266 | struct rcsoc_state *state; | ||
| 267 | { | ||
| 268 | if (state->keyword | ||
| 269 | && *state->cur_keyword_ptr == ch | ||
| 270 | && (state->cur_keyword_ptr > state->keyword | ||
| 271 | || state->pending_newlines > 0)) | ||
| 272 | /* We might be looking at STATE->keyword at some point. | ||
| 273 | Keep looking until we know for sure. */ | ||
| 274 | { | ||
| 275 | if (*++state->cur_keyword_ptr == '\0') | ||
| 276 | /* Saw the whole keyword. Set SAW_KEYWORD flag to true. */ | ||
| 277 | { | ||
| 278 | state->saw_keyword = 1; | ||
| 279 | |||
| 280 | /* Reset the scanning pointer. */ | ||
| 281 | state->cur_keyword_ptr = state->keyword; | ||
| 282 | |||
| 283 | /* Canonicalize whitespace preceding a usage string. */ | ||
| 284 | state->pending_newlines = 2; | ||
| 285 | state->pending_spaces = 0; | ||
| 286 | |||
| 287 | /* Skip any whitespace between the keyword and the | ||
| 288 | usage string. */ | ||
| 289 | do | ||
| 290 | ch = getc (state->in_file); | ||
| 291 | while (ch == ' ' || ch == '\n'); | ||
| 292 | |||
| 293 | /* Put back the non-whitespace character. */ | ||
| 294 | ungetc (ch, state->in_file); | ||
| 295 | } | ||
| 296 | } | ||
| 297 | else | ||
| 298 | { | ||
| 299 | if (state->keyword && state->cur_keyword_ptr > state->keyword) | ||
| 300 | /* We scanned the beginning of a potential usage | ||
| 301 | keyword, but it was a false alarm. Output the | ||
| 302 | part we scanned. */ | ||
| 303 | { | ||
| 304 | char *p; | ||
| 305 | |||
| 306 | for (p = state->keyword; p < state->cur_keyword_ptr; p++) | ||
| 307 | put_char (*p, state); | ||
| 308 | |||
| 309 | state->cur_keyword_ptr = state->keyword; | ||
| 310 | } | ||
| 311 | |||
| 312 | put_char (ch, state); | ||
| 313 | } | ||
| 314 | } | ||
| 315 | |||
| 316 | |||
| 237 | /* Skip a C string or C-style comment from INFILE, and return the | 317 | /* Skip a C string or C-style comment from INFILE, and return the |
| 238 | character that follows. COMMENT non-zero means skip a comment. If | 318 | character that follows. COMMENT non-zero means skip a comment. If |
| 239 | PRINTFLAG is positive, output string contents to outfile. If it is | 319 | PRINTFLAG is positive, output string contents to outfile. If it is |
| @@ -250,26 +330,21 @@ read_c_string_or_comment (infile, printflag, comment, saw_usage) | |||
| 250 | int *saw_usage; | 330 | int *saw_usage; |
| 251 | { | 331 | { |
| 252 | register int c; | 332 | register int c; |
| 253 | unsigned pending_spaces = 0, pending_newlines = 0; | 333 | struct rcsoc_state state; |
| 254 | char *p = buf; | 334 | |
| 255 | /* When this keyword occurs at the beginning of a line, we remove it, | 335 | state.in_file = infile; |
| 256 | and set *SAW_USAGE to true. */ | 336 | state.buf_ptr = (printflag < 0 ? buf : 0); |
| 257 | static char usage_keyword[] = "usage:"; | 337 | state.out_file = (printflag > 0 ? outfile : 0); |
| 258 | /* The current point we've reached in an occurance of USAGE_KEYWORD in | 338 | state.pending_spaces = 0; |
| 259 | the input stream. */ | 339 | state.pending_newlines = 0; |
| 260 | char *cur_usage_ptr = usage_keyword; | 340 | state.keyword = (saw_usage ? "usage:" : 0); |
| 261 | 341 | state.cur_keyword_ptr = state.keyword; | |
| 342 | state.saw_keyword = 0; | ||
| 343 | |||
| 344 | c = getc (infile); | ||
| 262 | if (comment) | 345 | if (comment) |
| 263 | { | 346 | while (c == '\n' || c == '\r' || c == '\t' || c == ' ') |
| 264 | while ((c = getc (infile)) != EOF | 347 | c = getc (infile); |
| 265 | && (c == '\n' || c == '\r' || c == '\t' || c == ' ')) | ||
| 266 | ; | ||
| 267 | } | ||
| 268 | else | ||
| 269 | c = getc (infile); | ||
| 270 | |||
| 271 | if (saw_usage) | ||
| 272 | *saw_usage = 0; | ||
| 273 | 348 | ||
| 274 | while (c != EOF) | 349 | while (c != EOF) |
| 275 | { | 350 | { |
| @@ -290,59 +365,14 @@ read_c_string_or_comment (infile, printflag, comment, saw_usage) | |||
| 290 | } | 365 | } |
| 291 | 366 | ||
| 292 | if (c == ' ') | 367 | if (c == ' ') |
| 293 | pending_spaces++; | 368 | state.pending_spaces++; |
| 294 | else if (c == '\n') | 369 | else if (c == '\n') |
| 295 | { | 370 | { |
| 296 | pending_newlines++; | 371 | state.pending_newlines++; |
| 297 | pending_spaces = 0; | 372 | state.pending_spaces = 0; |
| 298 | } | 373 | } |
| 299 | else | 374 | else |
| 300 | { | 375 | scan_keyword_or_put_char (c, &state); |
| 301 | if (saw_usage | ||
| 302 | && *cur_usage_ptr == c | ||
| 303 | && (cur_usage_ptr > usage_keyword || pending_newlines > 0)) | ||
| 304 | /* We might be looking at USAGE_KEYWORD at some point. | ||
| 305 | Keep looking until we know for sure. */ | ||
| 306 | { | ||
| 307 | if (*++cur_usage_ptr == '\0') | ||
| 308 | /* Saw the whole keyword. Set *SAW_USAGE to true. */ | ||
| 309 | { | ||
| 310 | *saw_usage = 1; | ||
| 311 | |||
| 312 | /* Reset the scanning pointer. */ | ||
| 313 | cur_usage_ptr = usage_keyword; | ||
| 314 | |||
| 315 | /* Canonicalize whitespace preceding a usage string. */ | ||
| 316 | pending_newlines = 2; | ||
| 317 | pending_spaces = 0; | ||
| 318 | |||
| 319 | /* Skip any whitespace between the keyword and the | ||
| 320 | usage string. */ | ||
| 321 | do | ||
| 322 | c = getc (infile); | ||
| 323 | while (c == ' ' || c == '\n'); | ||
| 324 | |||
| 325 | continue; /* This just skips the getc at end-of-loop. */ | ||
| 326 | } | ||
| 327 | } | ||
| 328 | else | ||
| 329 | { | ||
| 330 | if (cur_usage_ptr > usage_keyword) | ||
| 331 | /* We scanned the beginning of a potential usage | ||
| 332 | keyword, but it was a false alarm. Output the | ||
| 333 | part we scanned. */ | ||
| 334 | { | ||
| 335 | char *p; | ||
| 336 | for (p = usage_keyword; p < cur_usage_ptr; p++) | ||
| 337 | put_char (*p, printflag, &p, | ||
| 338 | &pending_newlines, &pending_spaces); | ||
| 339 | cur_usage_ptr = usage_keyword; | ||
| 340 | } | ||
| 341 | |||
| 342 | put_char (c, printflag, &p, | ||
| 343 | &pending_newlines, &pending_spaces); | ||
| 344 | } | ||
| 345 | } | ||
| 346 | 376 | ||
| 347 | c = getc (infile); | 377 | c = getc (infile); |
| 348 | } | 378 | } |
| @@ -358,7 +388,7 @@ read_c_string_or_comment (infile, printflag, comment, saw_usage) | |||
| 358 | break; | 388 | break; |
| 359 | } | 389 | } |
| 360 | 390 | ||
| 361 | put_char ('*', printflag, &p, &pending_newlines, &pending_spaces); | 391 | scan_keyword_or_put_char ('*', &state); |
| 362 | } | 392 | } |
| 363 | else | 393 | else |
| 364 | { | 394 | { |
| @@ -371,7 +401,10 @@ read_c_string_or_comment (infile, printflag, comment, saw_usage) | |||
| 371 | } | 401 | } |
| 372 | 402 | ||
| 373 | if (printflag < 0) | 403 | if (printflag < 0) |
| 374 | *p = 0; | 404 | *state.buf_ptr = 0; |
| 405 | |||
| 406 | if (saw_usage) | ||
| 407 | *saw_usage = state.saw_keyword; | ||
| 375 | 408 | ||
| 376 | return c; | 409 | return c; |
| 377 | } | 410 | } |