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* 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 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 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