14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1992-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * *
204887Schin ***********************************************************************/
214887Schin #pragma prototyped
224887Schin /*
234887Schin * David Korn
244887Schin * Glenn Fowler
254887Schin * AT&T Bell Laboratories
264887Schin *
274887Schin * cat
284887Schin */
294887Schin
304887Schin #include <cmd.h>
314887Schin #include <fcntl.h>
324887Schin
334887Schin static const char usage[] =
3410898Sroland.mainz@nrubsig.org "[-?\n@(#)$Id: cat (AT&T Research) 2009-03-31 $\n]"
354887Schin USAGE_LICENSE
364887Schin "[+NAME?cat - concatenate files]"
374887Schin "[+DESCRIPTION?\bcat\b copies each \afile\a in sequence to the standard"
384887Schin " output. If no \afile\a is given, or if the \afile\a is \b-\b,"
394887Schin " \bcat\b copies from standard input starting at the current location.]"
404887Schin
414887Schin "[b:number-nonblank?Number lines as with \b-n\b but omit line numbers from"
424887Schin " blank lines.]"
434887Schin "[d:dos-input?Input files are opened in \atext\amode which removes carriage"
444887Schin " returns in front of new-lines on some systems.]"
454887Schin "[e?Equivalent to \b-vE\b.]"
464887Schin "[n:number?Causes a line number to be inserted at the beginning of each line.]"
474887Schin "[s?Equivalent to \b-S\b for \aatt\a universe and \b-B\b otherwise.]"
484887Schin "[t?Equivalent to \b-vT\b.]"
494887Schin "[u:unbuffer?The output is not delayed by buffering.]"
504887Schin "[v:show-nonprinting?Causes non-printing characters (whith the exception of"
514887Schin " tabs, new-lines, and form-feeds) to be output as printable charater"
524887Schin " sequences. ASCII control characters are printed as \b^\b\an\a,"
534887Schin " where \an\a is the corresponding ASCII character in the range"
544887Schin " octal 100-137. The DEL character (octal 0177) is copied"
554887Schin " as \b^?\b. Other non-printable characters are copied as \bM-\b\ax\a"
564887Schin " where \ax\a is the ASCII character specified by the low-order seven"
574887Schin " bits. Multibyte characters in the current locale are treated as"
584887Schin " printable characters.]"
594887Schin "[A:show-all?Equivalent to \b-vET\b.]"
604887Schin "[B:squeeze-blank?Multiple adjacent new-line characters are replace by one"
614887Schin " new-line.]"
624887Schin "[D:dos-output?Output files are opened in \atext\amode which inserts carriage"
634887Schin " returns in front of new-lines on some systems.]"
644887Schin "[E:show-ends?Causes a \b$\b to be inserted before each new-line.]"
6510898Sroland.mainz@nrubsig.org "[R:regress?Regression test defaults: \b-v\b buffer size 4.]"
664887Schin "[S:silent?\bcat\b is silent about non-existent files.]"
674887Schin "[T:show-blank?Causes tabs to be copied as \b^I\b and formfeeds as \b^L\b.]"
684887Schin
694887Schin "\n"
704887Schin "\n[file ...]\n"
714887Schin "\n"
724887Schin
734887Schin "[+SEE ALSO?\bcp\b(1), \bgetconf\b(1), \bpr\b(1)]"
744887Schin ;
754887Schin
764887Schin #define RUBOUT 0177
774887Schin
784887Schin /* control flags */
794887Schin #define B_FLAG (1<<0)
804887Schin #define E_FLAG (1<<1)
814887Schin #define F_FLAG (1<<2)
824887Schin #define N_FLAG (1<<3)
834887Schin #define S_FLAG (1<<4)
844887Schin #define T_FLAG (1<<5)
854887Schin #define U_FLAG (1<<6)
864887Schin #define V_FLAG (1<<7)
874887Schin #define D_FLAG (1<<8)
884887Schin #define d_FLAG (1<<9)
894887Schin
904887Schin /* character types */
9110898Sroland.mainz@nrubsig.org #define T_ERROR 1
9210898Sroland.mainz@nrubsig.org #define T_EOF 2
9310898Sroland.mainz@nrubsig.org #define T_ENDBUF 3
9410898Sroland.mainz@nrubsig.org #define T_NEWLINE 4
9510898Sroland.mainz@nrubsig.org #define T_CONTROL 5
9610898Sroland.mainz@nrubsig.org #define T_EIGHTBIT 6
9710898Sroland.mainz@nrubsig.org #define T_CNTL8BIT 7
984887Schin
994887Schin #define printof(c) ((c)^0100)
1004887Schin
10110898Sroland.mainz@nrubsig.org typedef void* (*Reserve_f)(Sfio_t*, ssize_t, int);
10210898Sroland.mainz@nrubsig.org
10310898Sroland.mainz@nrubsig.org #ifndef sfvalue
10410898Sroland.mainz@nrubsig.org #define sfvalue(f) ((f)->_val)
10510898Sroland.mainz@nrubsig.org #endif
10610898Sroland.mainz@nrubsig.org
10710898Sroland.mainz@nrubsig.org static void*
regress(Sfio_t * sp,ssize_t n,int f)10810898Sroland.mainz@nrubsig.org regress(Sfio_t* sp, ssize_t n, int f)
10910898Sroland.mainz@nrubsig.org {
11010898Sroland.mainz@nrubsig.org void* r;
11110898Sroland.mainz@nrubsig.org
11210898Sroland.mainz@nrubsig.org if (!(r = sfreserve(sp, 4, f)))
11310898Sroland.mainz@nrubsig.org r = sfreserve(sp, n, f);
11410898Sroland.mainz@nrubsig.org else if (sfvalue(sp) > 4)
11510898Sroland.mainz@nrubsig.org sfvalue(sp) = 4;
11610898Sroland.mainz@nrubsig.org return r;
11710898Sroland.mainz@nrubsig.org }
11810898Sroland.mainz@nrubsig.org
1194887Schin /*
1204887Schin * called for any special output processing
1214887Schin */
1224887Schin
1234887Schin static int
vcat(register char * states,Sfio_t * ip,Sfio_t * op,Reserve_f reserve,int flags)12410898Sroland.mainz@nrubsig.org vcat(register char* states, Sfio_t* ip, Sfio_t* op, Reserve_f reserve, int flags)
1254887Schin {
1264887Schin register unsigned char* cp;
12710898Sroland.mainz@nrubsig.org register unsigned char* pp;
12810898Sroland.mainz@nrubsig.org unsigned char* cur;
12910898Sroland.mainz@nrubsig.org unsigned char* end;
13010898Sroland.mainz@nrubsig.org unsigned char* buf;
13110898Sroland.mainz@nrubsig.org unsigned char* nxt;
1324887Schin register int n;
13310898Sroland.mainz@nrubsig.org register int line;
13410898Sroland.mainz@nrubsig.org register int raw;
13510898Sroland.mainz@nrubsig.org int last;
13610898Sroland.mainz@nrubsig.org int c;
13710898Sroland.mainz@nrubsig.org int m;
13810898Sroland.mainz@nrubsig.org int any;
13910898Sroland.mainz@nrubsig.org int header;
1404887Schin
1414887Schin unsigned char meta[4];
14210898Sroland.mainz@nrubsig.org unsigned char tmp[32];
1434887Schin
1444887Schin meta[0] = 'M';
1454887Schin meta[1] = '-';
14610898Sroland.mainz@nrubsig.org last = -1;
14710898Sroland.mainz@nrubsig.org *(cp = buf = end = tmp) = 0;
14810898Sroland.mainz@nrubsig.org any = 0;
14910898Sroland.mainz@nrubsig.org header = flags & (B_FLAG|N_FLAG);
15010898Sroland.mainz@nrubsig.org line = 1;
15110898Sroland.mainz@nrubsig.org states[0] = T_ENDBUF;
15210898Sroland.mainz@nrubsig.org raw = !mbwide();
1534887Schin for (;;)
1544887Schin {
15510898Sroland.mainz@nrubsig.org cur = cp;
15610898Sroland.mainz@nrubsig.org if (raw)
15710898Sroland.mainz@nrubsig.org while (!(n = states[*cp++]));
15810898Sroland.mainz@nrubsig.org else
15910898Sroland.mainz@nrubsig.org for (;;)
16010898Sroland.mainz@nrubsig.org {
16110898Sroland.mainz@nrubsig.org while (!(n = states[*cp++]));
16210898Sroland.mainz@nrubsig.org if (n < T_CONTROL)
16310898Sroland.mainz@nrubsig.org break;
16410898Sroland.mainz@nrubsig.org if ((m = mbsize(pp = cp - 1)) > 1)
16510898Sroland.mainz@nrubsig.org cp += m - 1;
16610898Sroland.mainz@nrubsig.org else
16710898Sroland.mainz@nrubsig.org {
16810898Sroland.mainz@nrubsig.org if (m <= 0)
16910898Sroland.mainz@nrubsig.org {
17010898Sroland.mainz@nrubsig.org if (cur == pp)
17110898Sroland.mainz@nrubsig.org {
17210898Sroland.mainz@nrubsig.org if (last > 0)
17310898Sroland.mainz@nrubsig.org {
17410898Sroland.mainz@nrubsig.org *end = last;
17510898Sroland.mainz@nrubsig.org last = -1;
17610898Sroland.mainz@nrubsig.org c = end - pp + 1;
17710898Sroland.mainz@nrubsig.org if ((m = mbsize(pp)) == c)
17810898Sroland.mainz@nrubsig.org {
17910898Sroland.mainz@nrubsig.org any = 1;
18010898Sroland.mainz@nrubsig.org if (header)
18110898Sroland.mainz@nrubsig.org {
18210898Sroland.mainz@nrubsig.org header = 0;
18310898Sroland.mainz@nrubsig.org sfprintf(op, "%6d\t", line);
18410898Sroland.mainz@nrubsig.org }
18510898Sroland.mainz@nrubsig.org sfwrite(op, cur, m);
18610898Sroland.mainz@nrubsig.org *(cp = cur = end) = 0;
18710898Sroland.mainz@nrubsig.org }
18810898Sroland.mainz@nrubsig.org else
18910898Sroland.mainz@nrubsig.org {
19010898Sroland.mainz@nrubsig.org memcpy(tmp, pp, c);
19110898Sroland.mainz@nrubsig.org if (!(nxt = (unsigned char*)(*reserve)(ip, SF_UNBOUND, 0)))
19210898Sroland.mainz@nrubsig.org {
19310898Sroland.mainz@nrubsig.org states[0] = sfvalue(ip) ? T_ERROR : T_EOF;
19410898Sroland.mainz@nrubsig.org *(cp = end = tmp + sizeof(tmp) - 1) = 0;
19510898Sroland.mainz@nrubsig.org last = -1;
19610898Sroland.mainz@nrubsig.org }
19710898Sroland.mainz@nrubsig.org else if ((n = sfvalue(ip)) <= 0)
19810898Sroland.mainz@nrubsig.org {
19910898Sroland.mainz@nrubsig.org states[0] = n ? T_ERROR : T_EOF;
20010898Sroland.mainz@nrubsig.org *(cp = end = tmp + sizeof(tmp) - 1) = 0;
20110898Sroland.mainz@nrubsig.org last = -1;
20210898Sroland.mainz@nrubsig.org }
20310898Sroland.mainz@nrubsig.org else
20410898Sroland.mainz@nrubsig.org {
20510898Sroland.mainz@nrubsig.org cp = buf = nxt;
20610898Sroland.mainz@nrubsig.org end = buf + n - 1;
20710898Sroland.mainz@nrubsig.org last = *end;
20810898Sroland.mainz@nrubsig.org *end = 0;
20910898Sroland.mainz@nrubsig.org }
21010898Sroland.mainz@nrubsig.org mb:
21110898Sroland.mainz@nrubsig.org if ((n = end - cp + 1) >= (sizeof(tmp) - c))
21210898Sroland.mainz@nrubsig.org n = sizeof(tmp) - c - 1;
21310898Sroland.mainz@nrubsig.org memcpy(tmp + c, cp, n);
21410898Sroland.mainz@nrubsig.org if ((m = mbsize(tmp)) >= c)
21510898Sroland.mainz@nrubsig.org {
21610898Sroland.mainz@nrubsig.org any = 1;
21710898Sroland.mainz@nrubsig.org if (header)
21810898Sroland.mainz@nrubsig.org {
21910898Sroland.mainz@nrubsig.org header = 0;
22010898Sroland.mainz@nrubsig.org sfprintf(op, "%6d\t", line);
22110898Sroland.mainz@nrubsig.org }
22210898Sroland.mainz@nrubsig.org sfwrite(op, tmp, m);
22310898Sroland.mainz@nrubsig.org cur = cp += m - c;
22410898Sroland.mainz@nrubsig.org }
22510898Sroland.mainz@nrubsig.org }
22610898Sroland.mainz@nrubsig.org continue;
22710898Sroland.mainz@nrubsig.org }
22810898Sroland.mainz@nrubsig.org }
22910898Sroland.mainz@nrubsig.org else
23010898Sroland.mainz@nrubsig.org {
23110898Sroland.mainz@nrubsig.org cp = pp + 1;
23210898Sroland.mainz@nrubsig.org n = 0;
23310898Sroland.mainz@nrubsig.org }
23410898Sroland.mainz@nrubsig.org }
23510898Sroland.mainz@nrubsig.org break;
23610898Sroland.mainz@nrubsig.org }
23710898Sroland.mainz@nrubsig.org }
23810898Sroland.mainz@nrubsig.org c = *--cp;
23910898Sroland.mainz@nrubsig.org if ((m = cp - cur) || n >= T_CONTROL)
2404887Schin {
24110898Sroland.mainz@nrubsig.org flush:
24210898Sroland.mainz@nrubsig.org any = 1;
24310898Sroland.mainz@nrubsig.org if (header)
24410898Sroland.mainz@nrubsig.org {
24510898Sroland.mainz@nrubsig.org header = 0;
24610898Sroland.mainz@nrubsig.org sfprintf(op, "%6d\t", line);
24710898Sroland.mainz@nrubsig.org }
24810898Sroland.mainz@nrubsig.org if (m)
24910898Sroland.mainz@nrubsig.org sfwrite(op, cur, m);
2504887Schin }
25110898Sroland.mainz@nrubsig.org special:
25210898Sroland.mainz@nrubsig.org switch (n)
2534887Schin {
25410898Sroland.mainz@nrubsig.org case T_ERROR:
25510898Sroland.mainz@nrubsig.org if (cp != end)
25610898Sroland.mainz@nrubsig.org {
25710898Sroland.mainz@nrubsig.org n = T_CONTROL;
25810898Sroland.mainz@nrubsig.org goto flush;
25910898Sroland.mainz@nrubsig.org }
26010898Sroland.mainz@nrubsig.org return -1;
26110898Sroland.mainz@nrubsig.org case T_EOF:
26210898Sroland.mainz@nrubsig.org if (cp != end)
26310898Sroland.mainz@nrubsig.org {
26410898Sroland.mainz@nrubsig.org n = T_CONTROL;
26510898Sroland.mainz@nrubsig.org goto flush;
26610898Sroland.mainz@nrubsig.org }
26710898Sroland.mainz@nrubsig.org return 0;
26810898Sroland.mainz@nrubsig.org case T_ENDBUF:
26910898Sroland.mainz@nrubsig.org if (cp != end)
27010898Sroland.mainz@nrubsig.org {
27110898Sroland.mainz@nrubsig.org n = T_CONTROL;
27210898Sroland.mainz@nrubsig.org goto flush;
27310898Sroland.mainz@nrubsig.org }
27410898Sroland.mainz@nrubsig.org c = last;
27510898Sroland.mainz@nrubsig.org if (!(nxt = (unsigned char*)(*reserve)(ip, SF_UNBOUND, 0)))
27610898Sroland.mainz@nrubsig.org {
27710898Sroland.mainz@nrubsig.org *(cp = end = tmp) = 0;
27810898Sroland.mainz@nrubsig.org states[0] = sfvalue(ip) ? T_ERROR : T_EOF;
27910898Sroland.mainz@nrubsig.org last = -1;
28010898Sroland.mainz@nrubsig.org }
28110898Sroland.mainz@nrubsig.org else if ((m = sfvalue(ip)) <= 0)
28210898Sroland.mainz@nrubsig.org {
28310898Sroland.mainz@nrubsig.org *(cp = end = tmp) = 0;
28410898Sroland.mainz@nrubsig.org states[0] = m ? T_ERROR : T_EOF;
28510898Sroland.mainz@nrubsig.org last = -1;
28610898Sroland.mainz@nrubsig.org }
2874887Schin else
2884887Schin {
28910898Sroland.mainz@nrubsig.org buf = nxt;
29010898Sroland.mainz@nrubsig.org end = buf + m - 1;
29110898Sroland.mainz@nrubsig.org last = *end;
29210898Sroland.mainz@nrubsig.org *end = 0;
29310898Sroland.mainz@nrubsig.org cp = buf;
29410898Sroland.mainz@nrubsig.org }
29510898Sroland.mainz@nrubsig.org if (c >= 0)
29610898Sroland.mainz@nrubsig.org {
29710898Sroland.mainz@nrubsig.org if (!(n = states[c]))
29810898Sroland.mainz@nrubsig.org {
29910898Sroland.mainz@nrubsig.org *(cur = tmp) = c;
30010898Sroland.mainz@nrubsig.org m = 1;
30110898Sroland.mainz@nrubsig.org goto flush;
30210898Sroland.mainz@nrubsig.org }
30310898Sroland.mainz@nrubsig.org if (raw || n < T_CONTROL)
3044887Schin {
30510898Sroland.mainz@nrubsig.org cp--;
30610898Sroland.mainz@nrubsig.org goto special;
30710898Sroland.mainz@nrubsig.org }
30810898Sroland.mainz@nrubsig.org tmp[0] = c;
30910898Sroland.mainz@nrubsig.org c = 1;
31010898Sroland.mainz@nrubsig.org goto mb;
31110898Sroland.mainz@nrubsig.org }
31210898Sroland.mainz@nrubsig.org break;
31310898Sroland.mainz@nrubsig.org case T_CONTROL:
31410898Sroland.mainz@nrubsig.org do
31510898Sroland.mainz@nrubsig.org {
31610898Sroland.mainz@nrubsig.org sfputc(op, '^');
31710898Sroland.mainz@nrubsig.org sfputc(op, printof(c));
31810898Sroland.mainz@nrubsig.org } while (states[c = *++cp] == T_CONTROL);
31910898Sroland.mainz@nrubsig.org break;
32010898Sroland.mainz@nrubsig.org case T_CNTL8BIT:
32110898Sroland.mainz@nrubsig.org meta[2] = '^';
32210898Sroland.mainz@nrubsig.org do
32310898Sroland.mainz@nrubsig.org {
32410898Sroland.mainz@nrubsig.org n = c & ~0200;
32510898Sroland.mainz@nrubsig.org meta[3] = printof(n);
32610898Sroland.mainz@nrubsig.org sfwrite(op, (char*)meta, 4);
32710898Sroland.mainz@nrubsig.org } while (states[c = *++cp] == T_CNTL8BIT && raw);
32810898Sroland.mainz@nrubsig.org break;
32910898Sroland.mainz@nrubsig.org case T_EIGHTBIT:
33010898Sroland.mainz@nrubsig.org do
33110898Sroland.mainz@nrubsig.org {
33210898Sroland.mainz@nrubsig.org meta[2] = c & ~0200;
33310898Sroland.mainz@nrubsig.org sfwrite(op, (char*)meta, 3);
33410898Sroland.mainz@nrubsig.org } while (states[c = *++cp] == T_EIGHTBIT && raw);
33510898Sroland.mainz@nrubsig.org break;
33610898Sroland.mainz@nrubsig.org case T_NEWLINE:
33710898Sroland.mainz@nrubsig.org if (header && !(flags & B_FLAG))
33810898Sroland.mainz@nrubsig.org sfprintf(op, "%6d\t", line);
33910898Sroland.mainz@nrubsig.org if (flags & E_FLAG)
34010898Sroland.mainz@nrubsig.org sfputc(op, '$');
34110898Sroland.mainz@nrubsig.org sfputc(op, '\n');
34210898Sroland.mainz@nrubsig.org if (!header || !(flags & B_FLAG))
34310898Sroland.mainz@nrubsig.org line++;
34410898Sroland.mainz@nrubsig.org header = !(flags & S_FLAG);
34510898Sroland.mainz@nrubsig.org for (;;)
34610898Sroland.mainz@nrubsig.org {
34710898Sroland.mainz@nrubsig.org if ((n = states[*++cp]) == T_ENDBUF)
34810898Sroland.mainz@nrubsig.org {
34910898Sroland.mainz@nrubsig.org if (cp != end || last != '\n')
35010898Sroland.mainz@nrubsig.org break;
35110898Sroland.mainz@nrubsig.org if (!(nxt = (unsigned char*)(*reserve)(ip, SF_UNBOUND, 0)))
3524887Schin {
35310898Sroland.mainz@nrubsig.org states[0] = sfvalue(ip) ? T_ERROR : T_EOF;
35410898Sroland.mainz@nrubsig.org cp = end = tmp;
35510898Sroland.mainz@nrubsig.org *cp-- = 0;
35610898Sroland.mainz@nrubsig.org last = -1;
35710898Sroland.mainz@nrubsig.org }
35810898Sroland.mainz@nrubsig.org else if ((n = sfvalue(ip)) <= 0)
35910898Sroland.mainz@nrubsig.org {
36010898Sroland.mainz@nrubsig.org states[0] = n ? T_ERROR : T_EOF;
36110898Sroland.mainz@nrubsig.org cp = end = tmp;
36210898Sroland.mainz@nrubsig.org *cp-- = 0;
36310898Sroland.mainz@nrubsig.org last = -1;
3644887Schin }
3654887Schin else
3664887Schin {
36710898Sroland.mainz@nrubsig.org buf = nxt;
36810898Sroland.mainz@nrubsig.org end = buf + n - 1;
36910898Sroland.mainz@nrubsig.org last = *end;
37010898Sroland.mainz@nrubsig.org *end = 0;
37110898Sroland.mainz@nrubsig.org cp = buf - 1;
3724887Schin }
3734887Schin }
37410898Sroland.mainz@nrubsig.org else if (n != T_NEWLINE)
3754887Schin break;
37610898Sroland.mainz@nrubsig.org if (!(flags & S_FLAG) || any || header)
37710898Sroland.mainz@nrubsig.org {
37810898Sroland.mainz@nrubsig.org any = 0;
37910898Sroland.mainz@nrubsig.org header = 0;
38010898Sroland.mainz@nrubsig.org if ((flags & (B_FLAG|N_FLAG)) == N_FLAG)
38110898Sroland.mainz@nrubsig.org sfprintf(op, "%6d\t", line);
38210898Sroland.mainz@nrubsig.org if (flags & E_FLAG)
38310898Sroland.mainz@nrubsig.org sfputc(op, '$');
38410898Sroland.mainz@nrubsig.org sfputc(op, '\n');
38510898Sroland.mainz@nrubsig.org }
38610898Sroland.mainz@nrubsig.org if (!(flags & B_FLAG))
38710898Sroland.mainz@nrubsig.org line++;
3884887Schin }
38910898Sroland.mainz@nrubsig.org header = flags & (B_FLAG|N_FLAG);
39010898Sroland.mainz@nrubsig.org break;
3914887Schin }
3924887Schin }
3934887Schin }
3944887Schin
3954887Schin int
b_cat(int argc,char ** argv,void * context)3964887Schin b_cat(int argc, char** argv, void* context)
3974887Schin {
3984887Schin register int n;
3994887Schin register int flags = 0;
4004887Schin register char* cp;
4014887Schin register Sfio_t* fp;
4024887Schin char* mode;
40310898Sroland.mainz@nrubsig.org Reserve_f reserve = sfreserve;
4044887Schin int att;
40510898Sroland.mainz@nrubsig.org int dovcat = 0;
4064887Schin char states[UCHAR_MAX+1];
4074887Schin
4084887Schin cmdinit(argc, argv, context, ERROR_CATALOG, 0);
4094887Schin att = !strcmp(astconf("UNIVERSE", NiL, NiL), "att");
4104887Schin mode = "r";
4114887Schin for (;;)
4124887Schin {
41310898Sroland.mainz@nrubsig.org n = 0;
4144887Schin switch (optget(argv, usage))
4154887Schin {
4164887Schin case 'A':
41710898Sroland.mainz@nrubsig.org n = T_FLAG|E_FLAG|V_FLAG;
41810898Sroland.mainz@nrubsig.org break;
4194887Schin case 'B':
42010898Sroland.mainz@nrubsig.org n = S_FLAG;
42110898Sroland.mainz@nrubsig.org break;
4224887Schin case 'b':
42310898Sroland.mainz@nrubsig.org n = B_FLAG;
42410898Sroland.mainz@nrubsig.org break;
42510898Sroland.mainz@nrubsig.org case 'd':
42610898Sroland.mainz@nrubsig.org mode = opt_info.num ? "rt" : "r";
4274887Schin continue;
42810898Sroland.mainz@nrubsig.org case 'D':
42910898Sroland.mainz@nrubsig.org n = d_FLAG;
43010898Sroland.mainz@nrubsig.org break;
4314887Schin case 'E':
43210898Sroland.mainz@nrubsig.org n = E_FLAG;
43310898Sroland.mainz@nrubsig.org break;
4344887Schin case 'e':
43510898Sroland.mainz@nrubsig.org n = E_FLAG|V_FLAG;
43610898Sroland.mainz@nrubsig.org break;
4374887Schin case 'n':
43810898Sroland.mainz@nrubsig.org n = N_FLAG;
43910898Sroland.mainz@nrubsig.org break;
44010898Sroland.mainz@nrubsig.org case 'R':
44110898Sroland.mainz@nrubsig.org reserve = opt_info.num ? regress : sfreserve;
4424887Schin continue;
4434887Schin case 's':
44410898Sroland.mainz@nrubsig.org n = att ? F_FLAG : S_FLAG;
44510898Sroland.mainz@nrubsig.org break;
4464887Schin case 'S':
44710898Sroland.mainz@nrubsig.org n = F_FLAG;
44810898Sroland.mainz@nrubsig.org break;
4494887Schin case 'T':
45010898Sroland.mainz@nrubsig.org n = T_FLAG;
45110898Sroland.mainz@nrubsig.org break;
4524887Schin case 't':
45310898Sroland.mainz@nrubsig.org n = T_FLAG|V_FLAG;
45410898Sroland.mainz@nrubsig.org break;
4554887Schin case 'u':
45610898Sroland.mainz@nrubsig.org n = U_FLAG;
45710898Sroland.mainz@nrubsig.org break;
4584887Schin case 'v':
45910898Sroland.mainz@nrubsig.org n = V_FLAG;
46010898Sroland.mainz@nrubsig.org break;
4614887Schin case ':':
4624887Schin error(2, "%s", opt_info.arg);
4634887Schin break;
4644887Schin case '?':
4654887Schin error(ERROR_usage(2), "%s", opt_info.arg);
4664887Schin break;
4674887Schin }
46810898Sroland.mainz@nrubsig.org if (!n)
46910898Sroland.mainz@nrubsig.org break;
47010898Sroland.mainz@nrubsig.org if (opt_info.num)
47110898Sroland.mainz@nrubsig.org flags |= n;
47210898Sroland.mainz@nrubsig.org else
47310898Sroland.mainz@nrubsig.org flags &= ~n;
4744887Schin }
4754887Schin argv += opt_info.index;
4764887Schin if (error_info.errors)
4774887Schin error(ERROR_usage(2), "%s", optusage(NiL));
4784887Schin memset(states, 0, sizeof(states));
4794887Schin if (flags&V_FLAG)
4804887Schin {
4814887Schin memset(states, T_CONTROL, ' ');
4824887Schin states[RUBOUT] = T_CONTROL;
4834887Schin memset(states+0200, T_EIGHTBIT, 0200);
4844887Schin memset(states+0200, T_CNTL8BIT, ' ');
4854887Schin states[RUBOUT|0200] = T_CNTL8BIT;
4864887Schin states['\n'] = 0;
4874887Schin }
4884887Schin if (flags&T_FLAG)
4894887Schin states['\t'] = T_CONTROL;
4904887Schin states[0] = T_ENDBUF;
4914887Schin if (att)
4924887Schin {
4934887Schin if (flags&V_FLAG)
4944887Schin {
4954887Schin states['\n'|0200] = T_EIGHTBIT;
4964887Schin if (!(flags&T_FLAG))
4974887Schin {
4984887Schin states['\t'] = states['\f'] = 0;
4994887Schin states['\t'|0200] = states['\f'|0200] = T_EIGHTBIT;
5004887Schin }
5014887Schin }
5024887Schin }
5034887Schin else if (flags)
5044887Schin {
5054887Schin if (!(flags&T_FLAG))
5064887Schin states['\t'] = 0;
5074887Schin }
5088462SApril.Chin@Sun.COM if (flags&(V_FLAG|T_FLAG|N_FLAG|E_FLAG|B_FLAG|S_FLAG))
5094887Schin {
5104887Schin states['\n'] = T_NEWLINE;
5114887Schin dovcat = 1;
5124887Schin }
5134887Schin if (flags&d_FLAG)
5144887Schin sfopen(sfstdout, NiL, "wt");
5154887Schin if (cp = *argv)
5164887Schin argv++;
5174887Schin do
5184887Schin {
51910898Sroland.mainz@nrubsig.org if (!cp || streq(cp, "-"))
5204887Schin {
5214887Schin fp = sfstdin;
5224887Schin if (flags&D_FLAG)
5234887Schin sfopen(fp, NiL, mode);
5244887Schin }
5254887Schin else if (!(fp = sfopen(NiL, cp, mode)))
5264887Schin {
5274887Schin if (!(flags&F_FLAG))
5284887Schin error(ERROR_system(0), "%s: cannot open", cp);
5294887Schin error_info.errors = 1;
5304887Schin continue;
5314887Schin }
5324887Schin if (flags&U_FLAG)
5334887Schin sfsetbuf(fp, (void*)fp, -1);
5344887Schin if (dovcat)
53510898Sroland.mainz@nrubsig.org n = vcat(states, fp, sfstdout, reserve, flags);
5364887Schin else if (sfmove(fp, sfstdout, SF_UNBOUND, -1) >= 0 && sfeof(fp))
5374887Schin n = 0;
5384887Schin else
5394887Schin n = -1;
5404887Schin if (fp != sfstdin)
5414887Schin sfclose(fp);
5424887Schin if (n < 0 && errno != EPIPE)
5434887Schin {
5444887Schin if (cp)
5454887Schin error(ERROR_system(0), "%s: read error", cp);
5464887Schin else
5474887Schin error(ERROR_system(0), "read error");
5484887Schin }
5494887Schin if (sferror(sfstdout))
5504887Schin break;
5514887Schin } while (cp = *argv++);
5524887Schin if (sfsync(sfstdout))
5534887Schin error(ERROR_system(0), "write error");
5544887Schin if (flags&d_FLAG)
5554887Schin sfopen(sfstdout, NiL, "w");
5564887Schin return error_info.errors;
5574887Schin }
558