* Copyright (c) 1980 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1980 Regents of the University of California.\n\
static char sccsid
[] = "@(#)fmt.c 5.8 (Berkeley) %G%";
* fmt -- format the concatenation of input files or standard input
* onto standard output. Designed for use with Mail ~|
* Syntax : fmt [ goal [ max ] ] [ name ... ]
* Authors: Kurt Shoens (UCB) 12/7/78;
* Liz Allen (UMCP) 2/24/83 [Addition of goal length concept].
/* LIZ@UOM 6/18/85 -- Don't need LENGTH any more.
* #define LENGTH 72 Max line length in output
#define NOSTR ((char *) 0) /* Null string pointer for lint */
/* LIZ@UOM 6/18/85 --New variables goal_length and max_length */
int goal_length
; /* Target or goal line length in output */
int max_length
; /* Max line length in output */
int pfx
; /* Current leading blank count */
int lineno
; /* Current input line */
int mark
; /* Last place we saw a head line */
char *malloc(); /* 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
int number
; /* LIZ@UOM 6/18/85 */
goal_length
= GOAL_LENGTH
;
* LIZ@UOM 6/18/85 -- Check for goal and max length arguments
if (argc
> 1 && (1 == (sscanf(argv
[1], "%d", &number
)))) {
if (argc
> 1 && (1 == (sscanf(argv
[1], "%d", &number
)))) {
if (max_length
<= goal_length
) {
fprintf(stderr
, "Max length must be greater than %s\n",
if ((fi
= fopen(*++argv
, "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
int wordl
; /* LIZ@UOM 6/18/85 */
wordl
= 0; /* LIZ@UOM 6/18/85 */
* Collect a 'word,' allowing it to contain escaped white
while (*cp
&& *cp
!= ' ') {
if (*cp
== '\\' && isspace(cp
[1]))
wordl
++;/* LIZ@UOM 6/18/85 */
* Guarantee a space at end of line. Two spaces after end of
if (index(".:!", cp
[-1]))
* LIZ@UOM 6/18/85 pack(word);
* 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.
* LIZ@UOM 6/18/85 -- If the new word will fit in at less than the
* goal length, take it. If not, then check to see if the line
* will be over the max length; if so put the word on the next
* line. If not, check to see if the line will be closer to the
* goal length with or without the word and take it or put it on
* the next line accordingly.
* LIZ@UOM 6/18/85 -- pass in the length of the word as well
* LIZ@UOM 6/18/85 -- change condition to check goal_length; s is the
* length of the line before the word is added; t is now the length
* of the line after the word is added
if ((t
<= goal_length
) ||
((t
<= max_length
) && (t
- goal_length
<= goal_length
- s
))) {
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
= malloc(strlen(str
) + 1);
fprintf(stderr
, "fmt: Ran out of memory\n");