da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1992-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char usage[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[-?\n@(#)$Id: fmt (AT&T Research) 2007-01-02 $\n]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinUSAGE_LICENSE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+NAME?fmt - simple text formatter]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+DESCRIPTION?\bfmt\b reads the input files and left justifies space "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "separated words into lines \awidth\a characters or less in length and "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "writes the lines to the standard output. The standard input is read if "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\b-\b or no files are specified. Blank lines and interword spacing are "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "preserved in the output. Indentation is preserved, and lines with "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "identical indentation are joined and justified.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?\bfmt\b is meant to format mail messages prior to sending, but may "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "also be useful for other simple tasks. For example, in \bvi\b(1) the "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "command \b:!}fmt\b will justify the lines in the current paragraph.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[c:crown-margin?Preserve the indentation of the first two lines within "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "a paragraph, and align the left margin of each subsequent line with "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "that of the second line.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[o:optget?Format concatenated \boptget\b(3) usage strings.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[s:split-only?Split lines only; do not join short lines to form longer "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "ones.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[u:uniform-spacing?One space between words, two after sentences.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[w:width?Set the output line width to \acolumns\a.]#[columns:=72]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\n\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[ file ... ]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\n\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+SEE ALSO?\bmailx\b(1), \bnroff\b(1), \btroff\b(1), \bvi\b(1), "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\boptget\b(3)]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <cmd.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ctype.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct Fmt_s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* outp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* outbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* endbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t* in;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t* out;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int indent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int nextdent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int nwords;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int prefix;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int quote;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int retain;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int section;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Fmt_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INDENT 4
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TABSZ 8
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define isoption(fp,c) ((fp)->flags&(1L<<((c)-'a')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define setoption(fp,c) ((fp)->flags|=(1L<<((c)-'a')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define clroption(fp,c) ((fp)->flags&=~(1L<<((c)-'a')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinoutline(Fmt_t* fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* cp = fp->outbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!fp->outp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (fp->outp[-1] == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->outp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fp->outp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*cp++ == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n >= TABSZ)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n /= TABSZ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = &fp->outbuf[TABSZ*n];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (n--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *--cp = '\t';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = fp->outbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->nwords = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!isoption(fp, 'o'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(fp->out, cp, '\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = fp->indent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*cp != '[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*cp == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n += INDENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (n--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(fp->out, ' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->quote)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((d = (fp->outp - cp)) <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((c = fp->outp[-1]) == 'n' && d > 1 && fp->outp[-2] == '\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '}';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(fp->out, "\"%s%s\"\n", cp, c == ']' || c == '{' || c == '}' ? "" : " ");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(fp->out, cp, '\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->nextdent)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->indent += fp->nextdent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->endbuf -= fp->nextdent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->nextdent = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->outp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsplit(Fmt_t* fp, char* buf, int splice)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* qp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int q = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int prefix;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (ep = buf; *ep == ' '; ep++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prefix = ep - buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * preserve blank lines
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*ep == 0 || *buf == '.') && !isoption(fp, 'o'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prefix = strlen(buf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outline(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(fp->outbuf, buf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->outp = fp->outbuf+prefix;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outline(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->prefix < prefix && !isoption(fp, 'c'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outline(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!fp->outp || prefix < fp->prefix)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->prefix = prefix;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*ep == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp != ep && isoption(fp, 'u'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = ep-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c = *ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * skip over \space
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '\\' && *ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (ep-cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n && isoption(fp, 'o'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (qp = cp; qp < ep; qp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*qp == '\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin qp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*qp == '"')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = !q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*(ep-1) == '"')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->nwords > 0 && &fp->outp[n] >= fp->endbuf && !fp->retain && !q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outline(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skip:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->nwords == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->prefix)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(fp->outbuf, ' ', fp->prefix);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->outp = &fp->outbuf[fp->prefix];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*cp == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (ep-cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(fp->outp, cp, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->outp += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->nwords++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isoption(fp, 's') || *buf == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outline(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (fp->outp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * two spaces at ends of sentences
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!isoption(fp, 'o') && strchr(".:!?", fp->outp[-1]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fp->outp++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!splice && !fp->retain && (!fp->quote || (fp->outp - fp->outbuf) < 2 || fp->outp[-2] != '\\' || fp->outp[-1] != 'n' && fp->outp[-1] != 't' && fp->outp[-1] != ' '))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *fp->outp++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindofmt(Fmt_t* fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int splice;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* lp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buf[8192];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (cp || (cp = sfgetr(fp->in, '\n', 0)) && !(splice = 0) && (lp = cp + sfvalue(fp->in) - 1) || (cp = sfgetr(fp->in, '\n', SF_LASTR)) && (splice = 1) && (lp = cp + sfvalue(fp->in)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isoption(fp, 'o'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!isoption(fp, 'i'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(fp, 'i');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (cp < lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*cp == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b += 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*cp == '\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b += INDENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->indent = roundof(b, INDENT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (cp < lp && (*cp == ' ' || *cp == '\t'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!isoption(fp, 'q') && cp < lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(fp, 'q');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*cp == '"')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = lp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (--ep > cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*ep == '"')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->quote = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*ep != ' ' && *ep != '\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin again:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (b = 1;; b = 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp >= lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isoption(fp, 'o'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (cp < lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*cp == '\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((lp - cp) < 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*cp == 'n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((lp - cp) > 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*cp == ']' || *cp == '@' && *(cp + 1) == '(')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = 'n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*cp == '\\' && *(cp + 1) == 'n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*cp == 't' || *cp == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (x && dp != buf && *(dp - 1) != ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*cp == ' ' || *cp == '\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (x && c != '\n' && dp != buf && *(dp - 1) != ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto flush;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == ' ' && (dp == buf || *(dp - 1) == ' '))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '"')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b || cp >= lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->quote)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->section = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '\a')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 'a';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '\b')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 'b';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '\f')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 'f';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '\v')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 'v';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == ']' && (cp >= lp || *cp != ':' && *cp != '#' && *cp != '!'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp < lp && *cp == ']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->section = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->retain = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flush:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin split(fp, buf, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outline(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto again;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (fp->section)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->retain = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto flush;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->section = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '{')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (tp = cp; tp < lp; tp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*tp == '[' || *tp == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*tp == ' ' || *tp == '\t' || *tp == '"')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*tp == '\\' && (lp - tp) > 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*++tp == 'n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*tp == 't' || *tp == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->endbuf > (fp->outbuf + fp->indent + 2*INDENT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->nextdent = 2*INDENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto flush;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->section = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '}')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->indent && (b || *(cp - 2) != 'f'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->indent -= 2*INDENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->endbuf += 2*INDENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto flush;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->section = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == ' ' || c == '\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->section = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '?' && (cp >= lp || *cp != '?'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->retain)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (cp < lp && *cp != ' ' && *cp != '\t' && *cp != ']' && dp < &buf[sizeof(buf)-3])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = *cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp < lp && (*cp == ' ' || *cp == '\t'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = *cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin split(fp, buf, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->retain = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp->outp >= fp->endbuf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outline(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == ' ' || c == '\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (c = ' '; *cp == ' ' || *cp == '\t'; cp++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '\b')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (dp > buf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * expand tabs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = isoption(fp, 'o') ? 1 : TABSZ - (dp - buf) % TABSZ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (dp >= &buf[sizeof(buf) - c - 3])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c-- > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!isprint(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (dp >= &buf[sizeof(buf) - 3])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp = dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (--tp > buf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isspace(*tp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp -= dp - tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c != ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ep = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin split(fp, buf, splice);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinb_fmt(int argc, char** argv, void *context)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Fmt_t fmt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char outbuf[8 * 1024];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmt.flags = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmt.out = sfstdout;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmt.outbuf = outbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmt.outp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmt.endbuf = &outbuf[72];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmt.indent = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmt.nextdent = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmt.nwords = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmt.prefix = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmt.quote = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmt.retain = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmt.section = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cmdinit(argc, argv, context, ERROR_CATALOG, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (n = optget(argv, usage))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'c':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'o':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'u':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(&fmt, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'w':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (opt_info.num < TABSZ || opt_info.num>= sizeof(outbuf))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "width out of range");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmt.endbuf = &outbuf[opt_info.num];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_usage(2), "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv += opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (error_info.errors)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_usage(2), "%s", optusage(NiL));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isoption(&fmt, 'o'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(&fmt, 'c');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isoption(&fmt, 's'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin clroption(&fmt, 'u');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp = *argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!cp || streq(cp, "-"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmt.in = sfstdin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(fmt.in = sfopen(NiL, cp, "r")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(0), "%s: cannot open", cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.errors = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dofmt(&fmt);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fmt.in != sfstdin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(fmt.in);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (cp = *argv++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outline(&fmt);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfsync(sfstdout))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(0), "write error");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return error_info.errors != 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}