14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*10898Sroland.mainz@nrubsig.org * Copyright (c) 1992-2009 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[] = 34*10898Sroland.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.]" 65*10898Sroland.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 */ 91*10898Sroland.mainz@nrubsig.org #define T_ERROR 1 92*10898Sroland.mainz@nrubsig.org #define T_EOF 2 93*10898Sroland.mainz@nrubsig.org #define T_ENDBUF 3 94*10898Sroland.mainz@nrubsig.org #define T_NEWLINE 4 95*10898Sroland.mainz@nrubsig.org #define T_CONTROL 5 96*10898Sroland.mainz@nrubsig.org #define T_EIGHTBIT 6 97*10898Sroland.mainz@nrubsig.org #define T_CNTL8BIT 7 984887Schin 994887Schin #define printof(c) ((c)^0100) 1004887Schin 101*10898Sroland.mainz@nrubsig.org typedef void* (*Reserve_f)(Sfio_t*, ssize_t, int); 102*10898Sroland.mainz@nrubsig.org 103*10898Sroland.mainz@nrubsig.org #ifndef sfvalue 104*10898Sroland.mainz@nrubsig.org #define sfvalue(f) ((f)->_val) 105*10898Sroland.mainz@nrubsig.org #endif 106*10898Sroland.mainz@nrubsig.org 107*10898Sroland.mainz@nrubsig.org static void* 108*10898Sroland.mainz@nrubsig.org regress(Sfio_t* sp, ssize_t n, int f) 109*10898Sroland.mainz@nrubsig.org { 110*10898Sroland.mainz@nrubsig.org void* r; 111*10898Sroland.mainz@nrubsig.org 112*10898Sroland.mainz@nrubsig.org if (!(r = sfreserve(sp, 4, f))) 113*10898Sroland.mainz@nrubsig.org r = sfreserve(sp, n, f); 114*10898Sroland.mainz@nrubsig.org else if (sfvalue(sp) > 4) 115*10898Sroland.mainz@nrubsig.org sfvalue(sp) = 4; 116*10898Sroland.mainz@nrubsig.org return r; 117*10898Sroland.mainz@nrubsig.org } 118*10898Sroland.mainz@nrubsig.org 1194887Schin /* 1204887Schin * called for any special output processing 1214887Schin */ 1224887Schin 1234887Schin static int 124*10898Sroland.mainz@nrubsig.org vcat(register char* states, Sfio_t* ip, Sfio_t* op, Reserve_f reserve, int flags) 1254887Schin { 1264887Schin register unsigned char* cp; 127*10898Sroland.mainz@nrubsig.org register unsigned char* pp; 128*10898Sroland.mainz@nrubsig.org unsigned char* cur; 129*10898Sroland.mainz@nrubsig.org unsigned char* end; 130*10898Sroland.mainz@nrubsig.org unsigned char* buf; 131*10898Sroland.mainz@nrubsig.org unsigned char* nxt; 1324887Schin register int n; 133*10898Sroland.mainz@nrubsig.org register int line; 134*10898Sroland.mainz@nrubsig.org register int raw; 135*10898Sroland.mainz@nrubsig.org int last; 136*10898Sroland.mainz@nrubsig.org int c; 137*10898Sroland.mainz@nrubsig.org int m; 138*10898Sroland.mainz@nrubsig.org int any; 139*10898Sroland.mainz@nrubsig.org int header; 1404887Schin 1414887Schin unsigned char meta[4]; 142*10898Sroland.mainz@nrubsig.org unsigned char tmp[32]; 1434887Schin 1444887Schin meta[0] = 'M'; 1454887Schin meta[1] = '-'; 146*10898Sroland.mainz@nrubsig.org last = -1; 147*10898Sroland.mainz@nrubsig.org *(cp = buf = end = tmp) = 0; 148*10898Sroland.mainz@nrubsig.org any = 0; 149*10898Sroland.mainz@nrubsig.org header = flags & (B_FLAG|N_FLAG); 150*10898Sroland.mainz@nrubsig.org line = 1; 151*10898Sroland.mainz@nrubsig.org states[0] = T_ENDBUF; 152*10898Sroland.mainz@nrubsig.org raw = !mbwide(); 1534887Schin for (;;) 1544887Schin { 155*10898Sroland.mainz@nrubsig.org cur = cp; 156*10898Sroland.mainz@nrubsig.org if (raw) 157*10898Sroland.mainz@nrubsig.org while (!(n = states[*cp++])); 158*10898Sroland.mainz@nrubsig.org else 159*10898Sroland.mainz@nrubsig.org for (;;) 160*10898Sroland.mainz@nrubsig.org { 161*10898Sroland.mainz@nrubsig.org while (!(n = states[*cp++])); 162*10898Sroland.mainz@nrubsig.org if (n < T_CONTROL) 163*10898Sroland.mainz@nrubsig.org break; 164*10898Sroland.mainz@nrubsig.org if ((m = mbsize(pp = cp - 1)) > 1) 165*10898Sroland.mainz@nrubsig.org cp += m - 1; 166*10898Sroland.mainz@nrubsig.org else 167*10898Sroland.mainz@nrubsig.org { 168*10898Sroland.mainz@nrubsig.org if (m <= 0) 169*10898Sroland.mainz@nrubsig.org { 170*10898Sroland.mainz@nrubsig.org if (cur == pp) 171*10898Sroland.mainz@nrubsig.org { 172*10898Sroland.mainz@nrubsig.org if (last > 0) 173*10898Sroland.mainz@nrubsig.org { 174*10898Sroland.mainz@nrubsig.org *end = last; 175*10898Sroland.mainz@nrubsig.org last = -1; 176*10898Sroland.mainz@nrubsig.org c = end - pp + 1; 177*10898Sroland.mainz@nrubsig.org if ((m = mbsize(pp)) == c) 178*10898Sroland.mainz@nrubsig.org { 179*10898Sroland.mainz@nrubsig.org any = 1; 180*10898Sroland.mainz@nrubsig.org if (header) 181*10898Sroland.mainz@nrubsig.org { 182*10898Sroland.mainz@nrubsig.org header = 0; 183*10898Sroland.mainz@nrubsig.org sfprintf(op, "%6d\t", line); 184*10898Sroland.mainz@nrubsig.org } 185*10898Sroland.mainz@nrubsig.org sfwrite(op, cur, m); 186*10898Sroland.mainz@nrubsig.org *(cp = cur = end) = 0; 187*10898Sroland.mainz@nrubsig.org } 188*10898Sroland.mainz@nrubsig.org else 189*10898Sroland.mainz@nrubsig.org { 190*10898Sroland.mainz@nrubsig.org memcpy(tmp, pp, c); 191*10898Sroland.mainz@nrubsig.org if (!(nxt = (unsigned char*)(*reserve)(ip, SF_UNBOUND, 0))) 192*10898Sroland.mainz@nrubsig.org { 193*10898Sroland.mainz@nrubsig.org states[0] = sfvalue(ip) ? T_ERROR : T_EOF; 194*10898Sroland.mainz@nrubsig.org *(cp = end = tmp + sizeof(tmp) - 1) = 0; 195*10898Sroland.mainz@nrubsig.org last = -1; 196*10898Sroland.mainz@nrubsig.org } 197*10898Sroland.mainz@nrubsig.org else if ((n = sfvalue(ip)) <= 0) 198*10898Sroland.mainz@nrubsig.org { 199*10898Sroland.mainz@nrubsig.org states[0] = n ? T_ERROR : T_EOF; 200*10898Sroland.mainz@nrubsig.org *(cp = end = tmp + sizeof(tmp) - 1) = 0; 201*10898Sroland.mainz@nrubsig.org last = -1; 202*10898Sroland.mainz@nrubsig.org } 203*10898Sroland.mainz@nrubsig.org else 204*10898Sroland.mainz@nrubsig.org { 205*10898Sroland.mainz@nrubsig.org cp = buf = nxt; 206*10898Sroland.mainz@nrubsig.org end = buf + n - 1; 207*10898Sroland.mainz@nrubsig.org last = *end; 208*10898Sroland.mainz@nrubsig.org *end = 0; 209*10898Sroland.mainz@nrubsig.org } 210*10898Sroland.mainz@nrubsig.org mb: 211*10898Sroland.mainz@nrubsig.org if ((n = end - cp + 1) >= (sizeof(tmp) - c)) 212*10898Sroland.mainz@nrubsig.org n = sizeof(tmp) - c - 1; 213*10898Sroland.mainz@nrubsig.org memcpy(tmp + c, cp, n); 214*10898Sroland.mainz@nrubsig.org if ((m = mbsize(tmp)) >= c) 215*10898Sroland.mainz@nrubsig.org { 216*10898Sroland.mainz@nrubsig.org any = 1; 217*10898Sroland.mainz@nrubsig.org if (header) 218*10898Sroland.mainz@nrubsig.org { 219*10898Sroland.mainz@nrubsig.org header = 0; 220*10898Sroland.mainz@nrubsig.org sfprintf(op, "%6d\t", line); 221*10898Sroland.mainz@nrubsig.org } 222*10898Sroland.mainz@nrubsig.org sfwrite(op, tmp, m); 223*10898Sroland.mainz@nrubsig.org cur = cp += m - c; 224*10898Sroland.mainz@nrubsig.org } 225*10898Sroland.mainz@nrubsig.org } 226*10898Sroland.mainz@nrubsig.org continue; 227*10898Sroland.mainz@nrubsig.org } 228*10898Sroland.mainz@nrubsig.org } 229*10898Sroland.mainz@nrubsig.org else 230*10898Sroland.mainz@nrubsig.org { 231*10898Sroland.mainz@nrubsig.org cp = pp + 1; 232*10898Sroland.mainz@nrubsig.org n = 0; 233*10898Sroland.mainz@nrubsig.org } 234*10898Sroland.mainz@nrubsig.org } 235*10898Sroland.mainz@nrubsig.org break; 236*10898Sroland.mainz@nrubsig.org } 237*10898Sroland.mainz@nrubsig.org } 238*10898Sroland.mainz@nrubsig.org c = *--cp; 239*10898Sroland.mainz@nrubsig.org if ((m = cp - cur) || n >= T_CONTROL) 2404887Schin { 241*10898Sroland.mainz@nrubsig.org flush: 242*10898Sroland.mainz@nrubsig.org any = 1; 243*10898Sroland.mainz@nrubsig.org if (header) 244*10898Sroland.mainz@nrubsig.org { 245*10898Sroland.mainz@nrubsig.org header = 0; 246*10898Sroland.mainz@nrubsig.org sfprintf(op, "%6d\t", line); 247*10898Sroland.mainz@nrubsig.org } 248*10898Sroland.mainz@nrubsig.org if (m) 249*10898Sroland.mainz@nrubsig.org sfwrite(op, cur, m); 2504887Schin } 251*10898Sroland.mainz@nrubsig.org special: 252*10898Sroland.mainz@nrubsig.org switch (n) 2534887Schin { 254*10898Sroland.mainz@nrubsig.org case T_ERROR: 255*10898Sroland.mainz@nrubsig.org if (cp != end) 256*10898Sroland.mainz@nrubsig.org { 257*10898Sroland.mainz@nrubsig.org n = T_CONTROL; 258*10898Sroland.mainz@nrubsig.org goto flush; 259*10898Sroland.mainz@nrubsig.org } 260*10898Sroland.mainz@nrubsig.org return -1; 261*10898Sroland.mainz@nrubsig.org case T_EOF: 262*10898Sroland.mainz@nrubsig.org if (cp != end) 263*10898Sroland.mainz@nrubsig.org { 264*10898Sroland.mainz@nrubsig.org n = T_CONTROL; 265*10898Sroland.mainz@nrubsig.org goto flush; 266*10898Sroland.mainz@nrubsig.org } 267*10898Sroland.mainz@nrubsig.org return 0; 268*10898Sroland.mainz@nrubsig.org case T_ENDBUF: 269*10898Sroland.mainz@nrubsig.org if (cp != end) 270*10898Sroland.mainz@nrubsig.org { 271*10898Sroland.mainz@nrubsig.org n = T_CONTROL; 272*10898Sroland.mainz@nrubsig.org goto flush; 273*10898Sroland.mainz@nrubsig.org } 274*10898Sroland.mainz@nrubsig.org c = last; 275*10898Sroland.mainz@nrubsig.org if (!(nxt = (unsigned char*)(*reserve)(ip, SF_UNBOUND, 0))) 276*10898Sroland.mainz@nrubsig.org { 277*10898Sroland.mainz@nrubsig.org *(cp = end = tmp) = 0; 278*10898Sroland.mainz@nrubsig.org states[0] = sfvalue(ip) ? T_ERROR : T_EOF; 279*10898Sroland.mainz@nrubsig.org last = -1; 280*10898Sroland.mainz@nrubsig.org } 281*10898Sroland.mainz@nrubsig.org else if ((m = sfvalue(ip)) <= 0) 282*10898Sroland.mainz@nrubsig.org { 283*10898Sroland.mainz@nrubsig.org *(cp = end = tmp) = 0; 284*10898Sroland.mainz@nrubsig.org states[0] = m ? T_ERROR : T_EOF; 285*10898Sroland.mainz@nrubsig.org last = -1; 286*10898Sroland.mainz@nrubsig.org } 2874887Schin else 2884887Schin { 289*10898Sroland.mainz@nrubsig.org buf = nxt; 290*10898Sroland.mainz@nrubsig.org end = buf + m - 1; 291*10898Sroland.mainz@nrubsig.org last = *end; 292*10898Sroland.mainz@nrubsig.org *end = 0; 293*10898Sroland.mainz@nrubsig.org cp = buf; 294*10898Sroland.mainz@nrubsig.org } 295*10898Sroland.mainz@nrubsig.org if (c >= 0) 296*10898Sroland.mainz@nrubsig.org { 297*10898Sroland.mainz@nrubsig.org if (!(n = states[c])) 298*10898Sroland.mainz@nrubsig.org { 299*10898Sroland.mainz@nrubsig.org *(cur = tmp) = c; 300*10898Sroland.mainz@nrubsig.org m = 1; 301*10898Sroland.mainz@nrubsig.org goto flush; 302*10898Sroland.mainz@nrubsig.org } 303*10898Sroland.mainz@nrubsig.org if (raw || n < T_CONTROL) 3044887Schin { 305*10898Sroland.mainz@nrubsig.org cp--; 306*10898Sroland.mainz@nrubsig.org goto special; 307*10898Sroland.mainz@nrubsig.org } 308*10898Sroland.mainz@nrubsig.org tmp[0] = c; 309*10898Sroland.mainz@nrubsig.org c = 1; 310*10898Sroland.mainz@nrubsig.org goto mb; 311*10898Sroland.mainz@nrubsig.org } 312*10898Sroland.mainz@nrubsig.org break; 313*10898Sroland.mainz@nrubsig.org case T_CONTROL: 314*10898Sroland.mainz@nrubsig.org do 315*10898Sroland.mainz@nrubsig.org { 316*10898Sroland.mainz@nrubsig.org sfputc(op, '^'); 317*10898Sroland.mainz@nrubsig.org sfputc(op, printof(c)); 318*10898Sroland.mainz@nrubsig.org } while (states[c = *++cp] == T_CONTROL); 319*10898Sroland.mainz@nrubsig.org break; 320*10898Sroland.mainz@nrubsig.org case T_CNTL8BIT: 321*10898Sroland.mainz@nrubsig.org meta[2] = '^'; 322*10898Sroland.mainz@nrubsig.org do 323*10898Sroland.mainz@nrubsig.org { 324*10898Sroland.mainz@nrubsig.org n = c & ~0200; 325*10898Sroland.mainz@nrubsig.org meta[3] = printof(n); 326*10898Sroland.mainz@nrubsig.org sfwrite(op, (char*)meta, 4); 327*10898Sroland.mainz@nrubsig.org } while (states[c = *++cp] == T_CNTL8BIT && raw); 328*10898Sroland.mainz@nrubsig.org break; 329*10898Sroland.mainz@nrubsig.org case T_EIGHTBIT: 330*10898Sroland.mainz@nrubsig.org do 331*10898Sroland.mainz@nrubsig.org { 332*10898Sroland.mainz@nrubsig.org meta[2] = c & ~0200; 333*10898Sroland.mainz@nrubsig.org sfwrite(op, (char*)meta, 3); 334*10898Sroland.mainz@nrubsig.org } while (states[c = *++cp] == T_EIGHTBIT && raw); 335*10898Sroland.mainz@nrubsig.org break; 336*10898Sroland.mainz@nrubsig.org case T_NEWLINE: 337*10898Sroland.mainz@nrubsig.org if (header && !(flags & B_FLAG)) 338*10898Sroland.mainz@nrubsig.org sfprintf(op, "%6d\t", line); 339*10898Sroland.mainz@nrubsig.org if (flags & E_FLAG) 340*10898Sroland.mainz@nrubsig.org sfputc(op, '$'); 341*10898Sroland.mainz@nrubsig.org sfputc(op, '\n'); 342*10898Sroland.mainz@nrubsig.org if (!header || !(flags & B_FLAG)) 343*10898Sroland.mainz@nrubsig.org line++; 344*10898Sroland.mainz@nrubsig.org header = !(flags & S_FLAG); 345*10898Sroland.mainz@nrubsig.org for (;;) 346*10898Sroland.mainz@nrubsig.org { 347*10898Sroland.mainz@nrubsig.org if ((n = states[*++cp]) == T_ENDBUF) 348*10898Sroland.mainz@nrubsig.org { 349*10898Sroland.mainz@nrubsig.org if (cp != end || last != '\n') 350*10898Sroland.mainz@nrubsig.org break; 351*10898Sroland.mainz@nrubsig.org if (!(nxt = (unsigned char*)(*reserve)(ip, SF_UNBOUND, 0))) 3524887Schin { 353*10898Sroland.mainz@nrubsig.org states[0] = sfvalue(ip) ? T_ERROR : T_EOF; 354*10898Sroland.mainz@nrubsig.org cp = end = tmp; 355*10898Sroland.mainz@nrubsig.org *cp-- = 0; 356*10898Sroland.mainz@nrubsig.org last = -1; 357*10898Sroland.mainz@nrubsig.org } 358*10898Sroland.mainz@nrubsig.org else if ((n = sfvalue(ip)) <= 0) 359*10898Sroland.mainz@nrubsig.org { 360*10898Sroland.mainz@nrubsig.org states[0] = n ? T_ERROR : T_EOF; 361*10898Sroland.mainz@nrubsig.org cp = end = tmp; 362*10898Sroland.mainz@nrubsig.org *cp-- = 0; 363*10898Sroland.mainz@nrubsig.org last = -1; 3644887Schin } 3654887Schin else 3664887Schin { 367*10898Sroland.mainz@nrubsig.org buf = nxt; 368*10898Sroland.mainz@nrubsig.org end = buf + n - 1; 369*10898Sroland.mainz@nrubsig.org last = *end; 370*10898Sroland.mainz@nrubsig.org *end = 0; 371*10898Sroland.mainz@nrubsig.org cp = buf - 1; 3724887Schin } 3734887Schin } 374*10898Sroland.mainz@nrubsig.org else if (n != T_NEWLINE) 3754887Schin break; 376*10898Sroland.mainz@nrubsig.org if (!(flags & S_FLAG) || any || header) 377*10898Sroland.mainz@nrubsig.org { 378*10898Sroland.mainz@nrubsig.org any = 0; 379*10898Sroland.mainz@nrubsig.org header = 0; 380*10898Sroland.mainz@nrubsig.org if ((flags & (B_FLAG|N_FLAG)) == N_FLAG) 381*10898Sroland.mainz@nrubsig.org sfprintf(op, "%6d\t", line); 382*10898Sroland.mainz@nrubsig.org if (flags & E_FLAG) 383*10898Sroland.mainz@nrubsig.org sfputc(op, '$'); 384*10898Sroland.mainz@nrubsig.org sfputc(op, '\n'); 385*10898Sroland.mainz@nrubsig.org } 386*10898Sroland.mainz@nrubsig.org if (!(flags & B_FLAG)) 387*10898Sroland.mainz@nrubsig.org line++; 3884887Schin } 389*10898Sroland.mainz@nrubsig.org header = flags & (B_FLAG|N_FLAG); 390*10898Sroland.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; 403*10898Sroland.mainz@nrubsig.org Reserve_f reserve = sfreserve; 4044887Schin int att; 405*10898Sroland.mainz@nrubsig.org int dovcat = 0; 4064887Schin char states[UCHAR_MAX+1]; 4074887Schin 4084887Schin cmdinit(argc, argv, context, ERROR_CATALOG, 0); 409*10898Sroland.mainz@nrubsig.org setlocale(LC_ALL, ""); 4104887Schin att = !strcmp(astconf("UNIVERSE", NiL, NiL), "att"); 4114887Schin mode = "r"; 4124887Schin for (;;) 4134887Schin { 414*10898Sroland.mainz@nrubsig.org n = 0; 4154887Schin switch (optget(argv, usage)) 4164887Schin { 4174887Schin case 'A': 418*10898Sroland.mainz@nrubsig.org n = T_FLAG|E_FLAG|V_FLAG; 419*10898Sroland.mainz@nrubsig.org break; 4204887Schin case 'B': 421*10898Sroland.mainz@nrubsig.org n = S_FLAG; 422*10898Sroland.mainz@nrubsig.org break; 4234887Schin case 'b': 424*10898Sroland.mainz@nrubsig.org n = B_FLAG; 425*10898Sroland.mainz@nrubsig.org break; 426*10898Sroland.mainz@nrubsig.org case 'd': 427*10898Sroland.mainz@nrubsig.org mode = opt_info.num ? "rt" : "r"; 4284887Schin continue; 429*10898Sroland.mainz@nrubsig.org case 'D': 430*10898Sroland.mainz@nrubsig.org n = d_FLAG; 431*10898Sroland.mainz@nrubsig.org break; 4324887Schin case 'E': 433*10898Sroland.mainz@nrubsig.org n = E_FLAG; 434*10898Sroland.mainz@nrubsig.org break; 4354887Schin case 'e': 436*10898Sroland.mainz@nrubsig.org n = E_FLAG|V_FLAG; 437*10898Sroland.mainz@nrubsig.org break; 4384887Schin case 'n': 439*10898Sroland.mainz@nrubsig.org n = N_FLAG; 440*10898Sroland.mainz@nrubsig.org break; 441*10898Sroland.mainz@nrubsig.org case 'R': 442*10898Sroland.mainz@nrubsig.org reserve = opt_info.num ? regress : sfreserve; 4434887Schin continue; 4444887Schin case 's': 445*10898Sroland.mainz@nrubsig.org n = att ? F_FLAG : S_FLAG; 446*10898Sroland.mainz@nrubsig.org break; 4474887Schin case 'S': 448*10898Sroland.mainz@nrubsig.org n = F_FLAG; 449*10898Sroland.mainz@nrubsig.org break; 4504887Schin case 'T': 451*10898Sroland.mainz@nrubsig.org n = T_FLAG; 452*10898Sroland.mainz@nrubsig.org break; 4534887Schin case 't': 454*10898Sroland.mainz@nrubsig.org n = T_FLAG|V_FLAG; 455*10898Sroland.mainz@nrubsig.org break; 4564887Schin case 'u': 457*10898Sroland.mainz@nrubsig.org n = U_FLAG; 458*10898Sroland.mainz@nrubsig.org break; 4594887Schin case 'v': 460*10898Sroland.mainz@nrubsig.org n = V_FLAG; 461*10898Sroland.mainz@nrubsig.org break; 4624887Schin case ':': 4634887Schin error(2, "%s", opt_info.arg); 4644887Schin break; 4654887Schin case '?': 4664887Schin error(ERROR_usage(2), "%s", opt_info.arg); 4674887Schin break; 4684887Schin } 469*10898Sroland.mainz@nrubsig.org if (!n) 470*10898Sroland.mainz@nrubsig.org break; 471*10898Sroland.mainz@nrubsig.org if (opt_info.num) 472*10898Sroland.mainz@nrubsig.org flags |= n; 473*10898Sroland.mainz@nrubsig.org else 474*10898Sroland.mainz@nrubsig.org flags &= ~n; 4754887Schin } 4764887Schin argv += opt_info.index; 4774887Schin if (error_info.errors) 4784887Schin error(ERROR_usage(2), "%s", optusage(NiL)); 4794887Schin memset(states, 0, sizeof(states)); 4804887Schin if (flags&V_FLAG) 4814887Schin { 4824887Schin memset(states, T_CONTROL, ' '); 4834887Schin states[RUBOUT] = T_CONTROL; 4844887Schin memset(states+0200, T_EIGHTBIT, 0200); 4854887Schin memset(states+0200, T_CNTL8BIT, ' '); 4864887Schin states[RUBOUT|0200] = T_CNTL8BIT; 4874887Schin states['\n'] = 0; 4884887Schin } 4894887Schin if (flags&T_FLAG) 4904887Schin states['\t'] = T_CONTROL; 4914887Schin states[0] = T_ENDBUF; 4924887Schin if (att) 4934887Schin { 4944887Schin if (flags&V_FLAG) 4954887Schin { 4964887Schin states['\n'|0200] = T_EIGHTBIT; 4974887Schin if (!(flags&T_FLAG)) 4984887Schin { 4994887Schin states['\t'] = states['\f'] = 0; 5004887Schin states['\t'|0200] = states['\f'|0200] = T_EIGHTBIT; 5014887Schin } 5024887Schin } 5034887Schin } 5044887Schin else if (flags) 5054887Schin { 5064887Schin if (!(flags&T_FLAG)) 5074887Schin states['\t'] = 0; 5084887Schin } 5098462SApril.Chin@Sun.COM if (flags&(V_FLAG|T_FLAG|N_FLAG|E_FLAG|B_FLAG|S_FLAG)) 5104887Schin { 5114887Schin states['\n'] = T_NEWLINE; 5124887Schin dovcat = 1; 5134887Schin } 5144887Schin if (flags&d_FLAG) 5154887Schin sfopen(sfstdout, NiL, "wt"); 5164887Schin if (cp = *argv) 5174887Schin argv++; 5184887Schin do 5194887Schin { 520*10898Sroland.mainz@nrubsig.org if (!cp || streq(cp, "-")) 5214887Schin { 5224887Schin fp = sfstdin; 5234887Schin if (flags&D_FLAG) 5244887Schin sfopen(fp, NiL, mode); 5254887Schin } 5264887Schin else if (!(fp = sfopen(NiL, cp, mode))) 5274887Schin { 5284887Schin if (!(flags&F_FLAG)) 5294887Schin error(ERROR_system(0), "%s: cannot open", cp); 5304887Schin error_info.errors = 1; 5314887Schin continue; 5324887Schin } 5334887Schin if (flags&U_FLAG) 5344887Schin sfsetbuf(fp, (void*)fp, -1); 5354887Schin if (dovcat) 536*10898Sroland.mainz@nrubsig.org n = vcat(states, fp, sfstdout, reserve, flags); 5374887Schin else if (sfmove(fp, sfstdout, SF_UNBOUND, -1) >= 0 && sfeof(fp)) 5384887Schin n = 0; 5394887Schin else 5404887Schin n = -1; 5414887Schin if (fp != sfstdin) 5424887Schin sfclose(fp); 5434887Schin if (n < 0 && errno != EPIPE) 5444887Schin { 5454887Schin if (cp) 5464887Schin error(ERROR_system(0), "%s: read error", cp); 5474887Schin else 5484887Schin error(ERROR_system(0), "read error"); 5494887Schin } 5504887Schin if (sferror(sfstdout)) 5514887Schin break; 5524887Schin } while (cp = *argv++); 5534887Schin if (sfsync(sfstdout)) 5544887Schin error(ERROR_system(0), "write error"); 5554887Schin if (flags&d_FLAG) 5564887Schin sfopen(sfstdout, NiL, "w"); 5574887Schin return error_info.errors; 5584887Schin } 559