fmt.c (ccb8bea4f004ee996833c323bdefce0f86943296) | fmt.c (deba2451768df7509013747bcbbf1ad926f2d9d5) |
---|---|
1/* $OpenBSD: fmt.c,v 1.16 2000/06/25 15:35:42 pjanzen Exp $ */ 2 3/* Sensible version of fmt 4 * 5 * Syntax: fmt [ options ] [ goal [ max ] ] [ filename ... ] 6 * 7 * Since the documentation for the original fmt is so poor, here 8 * is an accurate description of what this one does. It's usually --- 16 unchanged lines hidden (view full) --- 25 * If the `-p' option is given then the first line of a 26 * paragraph is permitted to have indentation different 27 * from that of the other lines. 28 * If the `-m' option is given then a line that looks 29 * like a mail message header, if it is not immediately 30 * preceded by a non-blank non-message-header line, is 31 * taken to start a new paragraph, which also contains 32 * any subsequent lines with non-empty leading whitespace. | 1/* $OpenBSD: fmt.c,v 1.16 2000/06/25 15:35:42 pjanzen Exp $ */ 2 3/* Sensible version of fmt 4 * 5 * Syntax: fmt [ options ] [ goal [ max ] ] [ filename ... ] 6 * 7 * Since the documentation for the original fmt is so poor, here 8 * is an accurate description of what this one does. It's usually --- 16 unchanged lines hidden (view full) --- 25 * If the `-p' option is given then the first line of a 26 * paragraph is permitted to have indentation different 27 * from that of the other lines. 28 * If the `-m' option is given then a line that looks 29 * like a mail message header, if it is not immediately 30 * preceded by a non-blank non-message-header line, is 31 * taken to start a new paragraph, which also contains 32 * any subsequent lines with non-empty leading whitespace. |
33 * Unless the `-n' option is given, lines beginning with 34 * a . (dot) are not formatted. |
|
33 * 3. The "everything else" is split into words; a word 34 * includes its trailing whitespace, and a word at the 35 * end of a line is deemed to be followed by a single 36 * space, or two spaces if it ends with a sentence-end 37 * character. (See the `-d' option for how to change that.) 38 * If the `-s' option has been given, then a word's trailing 39 * whitespace is replaced by what it would have had if it 40 * had occurred at end of line. --- 176 unchanged lines hidden (view full) --- 217static size_t goal_length=0; /* Target length for output lines */ 218static size_t max_length=0; /* Maximum length for output lines */ 219static int coalesce_spaces_P=0; /* Coalesce multiple whitespace -> ' ' ? */ 220static int allow_indented_paragraphs=0; /* Can first line have diff. ind.? */ 221static int tab_width=8; /* Number of spaces per tab stop */ 222static size_t output_tab_width=8; /* Ditto, when squashing leading spaces */ 223static const char *sentence_enders=".?!"; /* Double-space after these */ 224static int grok_mail_headers=0; /* treat embedded mail headers magically? */ | 35 * 3. The "everything else" is split into words; a word 36 * includes its trailing whitespace, and a word at the 37 * end of a line is deemed to be followed by a single 38 * space, or two spaces if it ends with a sentence-end 39 * character. (See the `-d' option for how to change that.) 40 * If the `-s' option has been given, then a word's trailing 41 * whitespace is replaced by what it would have had if it 42 * had occurred at end of line. --- 176 unchanged lines hidden (view full) --- 219static size_t goal_length=0; /* Target length for output lines */ 220static size_t max_length=0; /* Maximum length for output lines */ 221static int coalesce_spaces_P=0; /* Coalesce multiple whitespace -> ' ' ? */ 222static int allow_indented_paragraphs=0; /* Can first line have diff. ind.? */ 223static int tab_width=8; /* Number of spaces per tab stop */ 224static size_t output_tab_width=8; /* Ditto, when squashing leading spaces */ 225static const char *sentence_enders=".?!"; /* Double-space after these */ 226static int grok_mail_headers=0; /* treat embedded mail headers magically? */ |
227static int format_troff=0; /* Format troff? */ |
|
225 226static int n_errors=0; /* Number of failed files. Return on exit. */ 227static char *output_buffer=0; /* Output line will be built here */ 228static size_t x; /* Horizontal position in output line */ 229static size_t x0; /* Ditto, ignoring leading whitespace */ 230static size_t pending_spaces; /* Spaces to add before next word */ 231static int output_in_paragraph=0; /* Any of current para written out yet? */ 232 --- 19 unchanged lines hidden (view full) --- 252main(int argc, char *argv[]) { 253 int ch; /* used for |getopt| processing */ 254 255 256 (void) setlocale(LC_CTYPE, ""); 257 258 /* 1. Grok parameters. */ 259 | 228 229static int n_errors=0; /* Number of failed files. Return on exit. */ 230static char *output_buffer=0; /* Output line will be built here */ 231static size_t x; /* Horizontal position in output line */ 232static size_t x0; /* Ditto, ignoring leading whitespace */ 233static size_t pending_spaces; /* Spaces to add before next word */ 234static int output_in_paragraph=0; /* Any of current para written out yet? */ 235 --- 19 unchanged lines hidden (view full) --- 255main(int argc, char *argv[]) { 256 int ch; /* used for |getopt| processing */ 257 258 259 (void) setlocale(LC_CTYPE, ""); 260 261 /* 1. Grok parameters. */ 262 |
260 while ((ch = getopt(argc, argv, "0123456789cd:hl:mpst:w:")) != -1) | 263 while ((ch = getopt(argc, argv, "0123456789cd:hl:mnpst:w:")) != -1) |
261 switch(ch) { 262 case 'c': 263 centerP = 1; | 264 switch(ch) { 265 case 'c': 266 centerP = 1; |
267 format_troff = 1; |
|
264 continue; 265 case 'd': 266 sentence_enders = optarg; 267 continue; 268 case 'l': 269 output_tab_width 270 = get_nonnegative(optarg, "output tab width must be non-negative", 1); 271 continue; 272 case 'm': 273 grok_mail_headers = 1; 274 continue; | 268 continue; 269 case 'd': 270 sentence_enders = optarg; 271 continue; 272 case 'l': 273 output_tab_width 274 = get_nonnegative(optarg, "output tab width must be non-negative", 1); 275 continue; 276 case 'm': 277 grok_mail_headers = 1; 278 continue; |
279 case 'n': 280 format_troff = 1; 281 continue; |
|
275 case 'p': 276 allow_indented_paragraphs = 1; 277 continue; 278 case 's': 279 coalesce_spaces_P = 1; 280 continue; 281 case 't': 282 tab_width = get_positive(optarg, "tab width must be positive", 1); --- 19 unchanged lines hidden (view full) --- 302 case 'h': default: 303 fprintf(stderr, 304"Usage: fmt [-cmps] [-d chars] [-l num] [-t num]\n" 305" [-w width | -width | goal [maximum]] [file ...]\n" 306"Options: -c center each line instead of formatting\n" 307" -d <chars> double-space after <chars> at line end\n" 308" -l <n> turn each <n> spaces at start of line into a tab\n" 309" -m try to make sure mail header lines stay separate\n" | 282 case 'p': 283 allow_indented_paragraphs = 1; 284 continue; 285 case 's': 286 coalesce_spaces_P = 1; 287 continue; 288 case 't': 289 tab_width = get_positive(optarg, "tab width must be positive", 1); --- 19 unchanged lines hidden (view full) --- 309 case 'h': default: 310 fprintf(stderr, 311"Usage: fmt [-cmps] [-d chars] [-l num] [-t num]\n" 312" [-w width | -width | goal [maximum]] [file ...]\n" 313"Options: -c center each line instead of formatting\n" 314" -d <chars> double-space after <chars> at line end\n" 315" -l <n> turn each <n> spaces at start of line into a tab\n" 316" -m try to make sure mail header lines stay separate\n" |
317" -n format lines beginning with a dot\n" |
|
310" -p allow indented paragraphs\n" 311" -s coalesce whitespace inside lines\n" 312" -t <n> have tabs every <n> columns\n" 313" -w <n> set maximum width to <n>\n" 314" goal set target width to goal\n"); 315 exit(ch=='h' ? 0 : EX_USAGE); 316 } 317 argc -= optind; argv += optind; --- 72 unchanged lines hidden (view full) --- 390 if (grok_mail_headers && prev_header_type!=hdr_NonHeader) { 391 if (np==0 && might_be_header(line)) 392 header_type = hdr_Header; 393 else if (np>0 && prev_header_type>hdr_NonHeader) 394 header_type = hdr_Continuation; 395 } 396 /* We need a new paragraph if and only if: 397 * this line is blank, | 318" -p allow indented paragraphs\n" 319" -s coalesce whitespace inside lines\n" 320" -t <n> have tabs every <n> columns\n" 321" -w <n> set maximum width to <n>\n" 322" goal set target width to goal\n"); 323 exit(ch=='h' ? 0 : EX_USAGE); 324 } 325 argc -= optind; argv += optind; --- 72 unchanged lines hidden (view full) --- 398 if (grok_mail_headers && prev_header_type!=hdr_NonHeader) { 399 if (np==0 && might_be_header(line)) 400 header_type = hdr_Header; 401 else if (np>0 && prev_header_type>hdr_NonHeader) 402 header_type = hdr_Continuation; 403 } 404 /* We need a new paragraph if and only if: 405 * this line is blank, |
406 * OR it's a troff request (and we don't format troff), |
|
398 * OR it's a mail header, 399 * OR it's not a mail header AND the last line was one, 400 * OR the indentation has changed 401 * AND the line isn't a mail header continuation line 402 * AND this isn't the second line of an indented paragraph. 403 */ 404 if ( length==0 | 407 * OR it's a mail header, 408 * OR it's not a mail header AND the last line was one, 409 * OR the indentation has changed 410 * AND the line isn't a mail header continuation line 411 * AND this isn't the second line of an indented paragraph. 412 */ 413 if ( length==0 |
414 || (line[0]=='.' && !format_troff) |
|
405 || header_type==hdr_Header 406 || (header_type==hdr_NonHeader && prev_header_type>hdr_NonHeader) 407 || (np!=last_indent 408 && header_type != hdr_Continuation 409 && (!allow_indented_paragraphs || para_line_number != 1)) ) { 410 new_paragraph(output_in_paragraph ? last_indent : first_indent, np); 411 para_line_number = 0; 412 first_indent = np; 413 last_indent = np; 414 if (header_type==hdr_Header) last_indent=2; /* for cont. lines */ | 415 || header_type==hdr_Header 416 || (header_type==hdr_NonHeader && prev_header_type>hdr_NonHeader) 417 || (np!=last_indent 418 && header_type != hdr_Continuation 419 && (!allow_indented_paragraphs || para_line_number != 1)) ) { 420 new_paragraph(output_in_paragraph ? last_indent : first_indent, np); 421 para_line_number = 0; 422 first_indent = np; 423 last_indent = np; 424 if (header_type==hdr_Header) last_indent=2; /* for cont. lines */ |
415 if (length==0) { 416 putchar('\n'); | 425 if (length==0 || (line[0]=='.' && !format_troff)) { 426 if (length==0) 427 putchar('\n'); 428 else 429 printf("%.*s\n", (int)length, line); |
417 prev_header_type=hdr_ParagraphStart; 418 continue; 419 } 420 } 421 else { 422 /* If this is an indented paragraph other than a mail header 423 * continuation, set |last_indent|. 424 */ --- 164 unchanged lines hidden (view full) --- 589 */ 590static char * 591get_line(FILE *stream, size_t *lengthp) { 592 static char *buf=NULL; 593 static size_t length=0; 594 size_t len=0; 595 int ch; 596 size_t spaces_pending=0; | 430 prev_header_type=hdr_ParagraphStart; 431 continue; 432 } 433 } 434 else { 435 /* If this is an indented paragraph other than a mail header 436 * continuation, set |last_indent|. 437 */ --- 164 unchanged lines hidden (view full) --- 602 */ 603static char * 604get_line(FILE *stream, size_t *lengthp) { 605 static char *buf=NULL; 606 static size_t length=0; 607 size_t len=0; 608 int ch; 609 size_t spaces_pending=0; |
610 int troff=0; |
|
597 598 if (buf==NULL) { length=100; buf=XMALLOC(length); } 599 while ((ch=getc(stream)) != '\n' && ch != EOF) { | 611 612 if (buf==NULL) { length=100; buf=XMALLOC(length); } 613 while ((ch=getc(stream)) != '\n' && ch != EOF) { |
614 if (len+spaces_pending==0 && ch=='.' && !format_troff) troff=1; |
|
600 if (ch==' ') ++spaces_pending; | 615 if (ch==' ') ++spaces_pending; |
601 else if (isprint(ch)) { | 616 else if (troff || isprint(ch)) { |
602 while (len+spaces_pending >= length) { 603 length*=2; buf=xrealloc(buf, length); 604 } 605 while (spaces_pending > 0) { --spaces_pending; buf[len++]=' '; } 606 buf[len++] = ch; 607 } 608 else if (ch=='\t') 609 spaces_pending += tab_width - (len+spaces_pending)%tab_width; --- 14 unchanged lines hidden --- | 617 while (len+spaces_pending >= length) { 618 length*=2; buf=xrealloc(buf, length); 619 } 620 while (spaces_pending > 0) { --spaces_pending; buf[len++]=' '; } 621 buf[len++] = ch; 622 } 623 else if (ch=='\t') 624 spaces_pending += tab_width - (len+spaces_pending)%tab_width; --- 14 unchanged lines hidden --- |