Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / lib / libcmd / cat.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: cat.c /main/3 1995/11/01 19:03:07 rswiston $ */
24 /***************************************************************
25 *                                                              *
26 *                      AT&T - PROPRIETARY                      *
27 *                                                              *
28 *         THIS IS PROPRIETARY SOURCE CODE LICENSED BY          *
29 *                          AT&T CORP.                          *
30 *                                                              *
31 *                Copyright (c) 1995 AT&T Corp.                 *
32 *                     All Rights Reserved                      *
33 *                                                              *
34 *           This software is licensed by AT&T Corp.            *
35 *       under the terms and conditions of the license in       *
36 *       http://www.research.att.com/orgs/ssr/book/reuse        *
37 *                                                              *
38 *               This software was created by the               *
39 *           Software Engineering Research Department           *
40 *                    AT&T Bell Laboratories                    *
41 *                                                              *
42 *               For further information contact                *
43 *                     gsf@research.att.com                     *
44 *                                                              *
45 ***************************************************************/
46
47 /* : : generated by proto : : */
48
49 #if !defined(__PROTO__)
50 #if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)
51 #if defined(__cplusplus)
52 #define __MANGLE__      "C"
53 #else
54 #define __MANGLE__
55 #endif
56 #define __STDARG__
57 #define __PROTO__(x)    x
58 #define __OTORP__(x)
59 #define __PARAM__(n,o)  n
60 #if !defined(__STDC__) && !defined(__cplusplus)
61 #if !defined(c_plusplus)
62 #define const
63 #endif
64 #define signed
65 #define void            int
66 #define volatile
67 #define __V_            char
68 #else
69 #define __V_            void
70 #endif
71 #else
72 #define __PROTO__(x)    ()
73 #define __OTORP__(x)    x
74 #define __PARAM__(n,o)  o
75 #define __MANGLE__
76 #define __V_            char
77 #define const
78 #define signed
79 #define void            int
80 #define volatile
81 #endif
82 #if defined(__cplusplus) || defined(c_plusplus)
83 #define __VARARG__      ...
84 #else
85 #define __VARARG__
86 #endif
87 #if defined(__STDARG__)
88 #define __VA_START__(p,a)       va_start(p,a)
89 #else
90 #define __VA_START__(p,a)       va_start(p)
91 #endif
92 #endif
93 static const char id[] = "\n@(#)cat (AT&T Bell Laboratories) 05/09/95\0\n";
94
95 #include <cmdlib.h>
96
97 #define RUBOUT  0177
98
99 /* control flags */
100 #define B_FLAG          (1<<0)
101 #define E_FLAG          (1<<1)
102 #define F_FLAG          (1<<2)
103 #define N_FLAG          (1<<3)
104 #define S_FLAG          (1<<4)
105 #define T_FLAG          (1<<5)
106 #define U_FLAG          (1<<6)
107 #define V_FLAG          (1<<7)
108
109 /* character types */
110 #define T_ENDBUF        1
111 #define T_CONTROL       2
112 #define T_NEWLINE       3
113 #define T_EIGHTBIT      4
114 #define T_CNTL8BIT      5
115
116 #define printof(c)      ((c)^0100)
117
118 static char     states[UCHAR_MAX+1];
119
120 /*
121  * called for any special output processing
122  */
123
124 static int
125 vcat __PARAM__((Sfio_t *fdin, Sfio_t *fdout, int flags), (fdin, fdout, flags)) __OTORP__(Sfio_t *fdin; Sfio_t *fdout; int flags;){
126         register unsigned char* cp;
127         register unsigned char* cpold;
128         register int            n;
129         register int            line = 1;
130         register unsigned char* endbuff;
131         unsigned char*          inbuff;
132         int                     printdefer = (flags&(B_FLAG|N_FLAG));
133         int                     lastchar;
134
135         static unsigned char    meta[4] = "M-";
136
137         for (;;)
138         {
139                 /* read in a buffer full */
140                 if (!(inbuff = (unsigned char*)sfreserve(fdin, SF_UNBOUND, 0)))
141                         return(sfslen() ? -1 : 0);
142                 if ((n = sfslen()) <= 0)
143                         return(n);
144                 cp = inbuff;
145                 lastchar = *(endbuff = cp + --n);
146                 *endbuff = 0;
147                 if (printdefer)
148                 {
149                         if (states[*cp]!=T_NEWLINE || !(flags&B_FLAG))
150                                 sfprintf(fdout,"%6d\t",line);
151                         printdefer = 0;
152                 }
153                 while (endbuff)
154                 {
155                         cpold = cp;
156                         /* skip over ASCII characters */
157                         while ((n = states[*cp++]) == 0);
158                         if (n==T_ENDBUF)
159                         {
160                                 if (cp>endbuff)
161                                 {
162                                         if (!(n = states[lastchar]))
163                                         {
164                                                 *endbuff = lastchar;
165                                                 cp++;
166                                         }
167                                         else
168                                         {
169                                                 if (--cp > cpold)
170                                                         sfwrite(fdout,(char*)cpold,cp-cpold);
171                                                 if (endbuff==inbuff)
172                                                         *++endbuff = 0;
173                                                 cp = cpold = endbuff;
174                                                 cp[-1] = lastchar;
175                                                 if (n==T_ENDBUF)
176                                                         n = T_CONTROL;
177                                                 
178                                         }
179                                         endbuff = 0;
180                                 }
181                                 else n = T_CONTROL;
182                         }
183                         if (--cp>cpold)
184                                 sfwrite(fdout,(char*)cpold,cp-cpold);
185                         switch(n)
186                         {
187                                 case T_CNTL8BIT:
188                                         meta[2] = '^';
189                                         do
190                                         {
191                                                 n = (*cp++)&~0200;
192                                                 meta[3] = printof(n);
193                                                 sfwrite(fdout,(char*)meta,4);
194                                         }
195                                         while ((n=states[*cp])==T_CNTL8BIT);
196                                         break;
197                                 case T_EIGHTBIT:
198                                         do
199                                         {
200                                                 meta[2] = (*cp++)&~0200;
201                                                 sfwrite(fdout,(char*)meta,3);
202                                         }
203                                         while ((n=states[*cp])==T_EIGHTBIT);
204                                         break;
205                                 case T_CONTROL:
206                                         do
207                                         {
208                                                 n = *cp++;
209                                                 sfputc(fdout,'^');
210                                                 sfputc(fdout,printof(n));
211                                         }
212                                         while ((n=states[*cp])==T_CONTROL);
213                                         break;
214                                 case T_NEWLINE:
215                                         if (flags&S_FLAG)
216                                         {
217                                                 while (states[*++cp]==T_NEWLINE)
218                                                         line++;
219                                                 cp--;
220                                         }
221                                         do
222                                         {
223                                                 cp++;
224                                                 if (flags&E_FLAG)
225                                                         sfputc(fdout,'$');
226                                                 sfputc(fdout,'\n');
227                                                 if (!(flags&(N_FLAG|B_FLAG)))
228                                                         continue;
229                                                 line++;
230                                                 if (cp < endbuff)
231                                                         sfprintf(fdout,"%6d\t",line);
232                                                 else printdefer = 1;
233                                         }
234                                         while (states[*cp]==T_NEWLINE);
235                                         break;
236                         }
237                 }
238         }
239 }
240
241 int
242 b_cat __PARAM__((int argc, char** argv), (argc, argv)) __OTORP__(int argc; char** argv;){
243         register int            n;
244         register int            flags = 0;
245         register char*          cp;
246         register Sfio_t*        fp;
247         int                     att;
248
249         NoP(id[0]);
250         NoP(argc);
251         cmdinit(argv);
252         att = !strcmp(astconf("UNIVERSE", NiL, NiL), "att");
253         while (n = optget(argv, "benstuv [file...] ")) switch (n)
254         {
255         case 'b':
256                 flags |= B_FLAG;
257                 break;
258         case 'e':
259                 flags |= E_FLAG;
260                 break;
261         case 'n':
262                 flags |= N_FLAG;
263                 break;
264         case 's':
265                 flags |= att ? F_FLAG : S_FLAG;
266                 break;
267         case 't':
268                 flags |= T_FLAG;
269                 break;
270         case 'u':
271                 flags |= U_FLAG;
272                 break;
273         case 'v':
274                 flags |= V_FLAG;
275                 break;
276         case ':':
277                 error(2, opt_info.arg);
278                 break;
279         case '?':
280                 error(ERROR_usage(2), opt_info.arg);
281                 break;
282         }
283         argv += opt_info.index;
284         if (error_info.errors)
285                 error(ERROR_usage(2), optusage(NiL));
286         if (flags&V_FLAG)
287         {
288                 memset(states, T_CONTROL, ' ');
289                 states[RUBOUT] = T_CONTROL;
290                 memset(states+0200, T_EIGHTBIT, 0200);
291                 memset(states+0200, T_CNTL8BIT,  ' ');
292                 states[RUBOUT|0200] = T_CNTL8BIT;
293                 states['\n'] = 0;
294         }
295         states[0] = T_ENDBUF;
296         if (att)
297         {
298                 if (flags&V_FLAG)
299                 {
300                         states['\n'|0200] = T_EIGHTBIT;
301                         if (!(flags&T_FLAG))
302                         {
303                                 states['\t'] = states['\f'] = 0;
304                                 states['\t'|0200] = states['\f'|0200] = T_EIGHTBIT;
305                         }
306                 }
307         }
308         else if (flags)
309         {
310                 flags |= V_FLAG;
311                 if (!(flags&T_FLAG))
312                         states['\t'] = 0;
313         }
314         if (flags&B_FLAG)
315         {
316                 flags &= ~(N_FLAG|E_FLAG);
317                 flags |= (V_FLAG|S_FLAG);
318         }
319         if (flags&N_FLAG)
320         {
321                 flags &= ~(B_FLAG|S_FLAG|E_FLAG);
322                 flags |= V_FLAG;
323         }
324         if (flags&V_FLAG)
325                 states['\n'] = T_NEWLINE;
326         if (cp = *argv)
327                 argv++;
328         do
329         {
330                 if (!cp || streq(cp,"-"))
331                         fp = sfstdin;
332                 else if (!(fp = sfopen(NiL, cp, "r")))
333                 {
334                         if (!(flags&F_FLAG))
335                                 error(ERROR_system(0), "%s: cannot open", cp);
336                         error_info.errors = 1;
337                         continue;
338                 }
339                 if (flags&U_FLAG)
340                         sfsetbuf(fp, (__V_*)fp, -1);
341                 if (flags&V_FLAG) n = vcat(fp, sfstdout, flags);
342                 else if ((n = sfmove(fp, sfstdout, SF_UNBOUND, -1)) >= 0 && (!sfeof(fp) || sferror(sfstdout)))
343                         n = -1;
344                 if (fp != sfstdin)
345                         sfclose(fp);
346                 if (n < 0)
347                 {
348                         if (cp) error(ERROR_system(0), "%s: cannot copy", cp);
349                         else error(ERROR_system(0), "cannot copy");
350                         if (sferror(sfstdout)) break;
351                 }
352         } while (cp = *argv++);
353         return(error_info.errors);
354 }