* fmt -- format the concatenation of input files or standard input
* onto standard output. Designed for use with Mail ~|
* Syntax: fmt [ -width ] [ name ... ]
* Author: Kurt Shoens (UCB) 12/7/78
static char *SccsId
= "@(#)fmt.c 2.1 %G%";
#define NOSTR ((char *) 0) /* Null string pointer for lint */
int pfx
; /* Current leading blank count */
int lineno
; /* Current input line */
int mark
; /* Last place we saw a head line */
int width
= 72; /* Width that we will not exceed */
char *calloc(); /* for lint . . . */
char *headnames
[] = {"To", "Subject", "Cc", 0};
* Drive the whole formatter by managing input files. Also,
* cause initialization of the output stuff and flush it out
if (width
<= 0 || width
>= BUFSIZ
-2) {
fprintf(stderr
, "fmt: bad width: %d\n", width
);
if ((fi
= fopen(cp
, "r")) == NULL
) {
* Read up characters from the passed input file, forming lines,
* doing ^H processing, expanding tabs, stripping trailing blanks,
* and sending each line down for analysis.
char linebuf
[BUFSIZ
], canonb
[BUFSIZ
];
* Collect a line, doing ^H processing.
while (c
!= '\n' && c
!= EOF
&& cp
-linebuf
< BUFSIZ
-1) {
if ((c
< ' ' || c
>= 0177) && c
!= '\t') {
* Toss anything remaining on the input line.
while (c
!= '\n' && c
!= EOF
)
* Expand tabs on the way to canonb.
if (cp2
-canonb
< BUFSIZ
-1)
if (cp2
-canonb
< BUFSIZ
-1)
} while ((col
& 07) != 0);
* Swipe trailing blanks from the line.
for (cp2
--; cp2
>= canonb
&& *cp2
== ' '; cp2
--)
* Take a line devoid of tabs and other garbage and determine its
* blank prefix. If the indent changes, call for a linebreak.
* If the input line is blank, echo the blank line on the output.
* Finally, if the line minus the prefix is a mail header, try to keep
* it on a line by itself.
for (cp
= line
; *cp
== ' '; cp
++)
* The following horrible expression attempts to avoid linebreaks
* when the indent changes due to a paragraph.
if (np
!= pfx
&& (np
> pfx
|| abs(pfx
-np
) > 8))
if (lineno
- mark
< 3 && lineno
- mark
> 0)
for (hp
= &headnames
[0]; *hp
!= (char *) 0; hp
++)
if (!h
&& (h
= (*cp
== '.')))
* Split up the passed line into output "words" which are
* maximal strings of non-blanks with the blank separation
* attached at the end. Pass these words along to the output
* Collect a 'word,' allowing it to contain escaped
while (*cp
&& *cp
!= ' ') {
if (*cp
== '\\' && isspace(cp
[1]))
* Guarantee a space at end of line.
* Two spaces after end of sentence punctuation.
* Build up line images from the words passed in. Prefix
* each line with correct number of blanks. The buffer "outbuf"
* contains the current partial line image, including prefixed blanks.
* "outp" points to the next available space therein. When outp is NOSTR,
* there ain't nothing in there yet. At the bottom of this whole mess,
* leading tabs are reinserted.
char outbuf
[BUFSIZ
]; /* Sandbagged output line image */
char *outp
; /* Pointer in above */
* Initialize the output section.
* Pack a word onto the output line. If this is the beginning of
* the line, push on the appropriately-sized string of blanks first.
* If the word won't fit on the current line, flush and begin a new
* line. If the word is too long to fit all by itself on a line,
* just give it its own and hope for the best.
for (cp
= word
; *cp
; *outp
++ = *cp
++)
for (cp
= word
; *cp
; *outp
++ = *cp
++)
* If there is anything on the current output line, send it on
* its way. Set outp to NOSTR to indicate the absence of the current
* Take the passed line buffer, insert leading tabs where possible, and
* output on standard output (finally).
* Toss trailing blanks in the output line.
cp
= line
+ strlen(line
) - 1;
while (cp
>= line
&& *cp
== ' ')
* Count the leading blank space and tabulate.
for (cp
= line
; *cp
== ' '; cp
++)
* Initialize the output line with the appropriate number of
for (b
= 0, cp
= outbuf
; b
< pfx
; b
++)
* Save a string in dynamic space.
* This little goodie is needed for
* a headline detector in head.c
top
= calloc(strlen(str
) + 1, 1);
fprintf(stderr
, "fmt: Ran out of memory\n");