3 /* usage: fmt [-width] [files]...
5 * Fmt rearrages text in order to make each line have roughly the
6 * same width. Indentation and word spacing is preserved.
8 * The default width is 72 characters, but you can override that via -width.
9 * If no files are given on the command line, then it reads stdin.
21 int width
= 72; /* the desired line width */
22 int isblank
; /* is the current output line blank? */
23 int indent
; /* width of the indentation */
24 char ind
[512]; /* indentation text */
25 char word
[1024]; /* word buffer */
27 /* This function displays a usage message and quits */
30 fprintf(stderr
, "usage: fmt [-width] [files]...\n");
36 /* This function outputs a single word. It takes care of spacing and the
37 * newlines within a paragraph.
41 int i
; /* index into word[], or whatever */
42 int ww
; /* width of the word */
43 int sw
; /* width of spacing after word */
44 static int psw
; /* space width of previous word */
45 static int tab
; /* the width of text already written */
48 /* separate the word and its spacing */
49 for (ww
= 0; word
[ww
] && word
[ww
] != ' '; ww
++)
52 sw
= strlen(word
) - ww
;
55 /* if no spacing (that is, the word was at the end of the line) then
56 * assume 1 space unless the last char of the word was punctuation
61 if (word
[ww
- 1] == '.' || word
[ww
- 1] == '?' || word
[ww
- 1] == '!')
65 /* if this is the first word on the line... */
68 /* output the indentation first */
72 else /* text has already been written to this output line */
74 /* will the word fit on this line? */
75 if (psw
+ ww
+ tab
<= width
)
77 /* yes - so write the previous word's spacing */
78 for (i
= 0; i
< psw
; i
++)
86 /* no, so write a newline and the indentation */
93 /* write the word itself */
97 /* remember this word's spacing */
100 /* this output line isn't blank anymore. */
106 /* This function reformats text. */
108 FILE *in
; /* the name of the input stream */
110 int ch
; /* character from input stream */
111 int prevch
; /* the previous character in the loop */
112 int i
; /* index into ind[] or word[] */
113 int inword
; /* boolean: are we between indent & newline? */
116 /* for each character in the stream... */
117 for (indent
= -1, isblank
= TRUE
, inword
= FALSE
, i
= 0, prevch
= '\n';
118 (ch
= getc(in
)) != EOF
;
121 /* is this the end of a line? */
124 /* if end of last word in the input line */
127 /* if it really is a word */
135 else /* blank line in input */
137 /* finish the previous paragraph */
144 /* output a blank line */
148 /* continue with next input line... */
155 /* if we're expecting indentation now... */
158 /* if this is part of the indentation... */
159 if (ch
== ' ' || ch
== '\t')
164 else /* end of indentation */
166 /* mark the end of the indentation string */
169 /* calculate the width of the indentation */
170 for (i
= indent
= 0; ind
[i
]; i
++)
173 indent
= (indent
| 7) + 1;
178 /* reset the word index */
181 /* reprocess that last character */
185 /* continue in the for-loop */
189 /* if we get here, we're either in a word or in the space
194 /* is this the start of a new word? */
195 if (ch
!= ' ' && prevch
== ' ')
197 /* yes! output the previous word */
201 /* reset `i' to the start of the word[] buffer */
207 /* if necessary, write a final newline */
223 FILE *in
; /* an input stream */
224 int error
; /* if non-zero, then an error occurred */
228 /* handle the -width flag, if given */
229 if (argc
> 1 && argv
[1][0] == '-')
231 width
= atoi(argv
[1] + 1);
240 /* if no filenames given, then process stdin */
245 else /* one or more filenames given */
247 for (error
= 0, i
= 1; i
< argc
; i
++)
249 in
= fopen(argv
[i
], "r");
263 /* exit, possibly indicating an error */