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 ---