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 * rev [-l] [file ...]
244887Schin *
254887Schin * reverse the characters or lines of one or more files
264887Schin *
274887Schin * David Korn
284887Schin * AT&T Laboratories
294887Schin * dgk@research.att.com
304887Schin *
314887Schin */
324887Schin
334887Schin static const char usage[] =
348462SApril.Chin@Sun.COM "[-?\n@(#)$Id: rev (AT&T Research) 2007-11-29 $\n]"
354887Schin USAGE_LICENSE
364887Schin "[+NAME?rev - reverse the characters or lines of one or more files]"
374887Schin "[+DESCRIPTION?\brev\b copies one or more files to standard output "
384887Schin "reversing the order of characters on every line of the file "
394887Schin "or reversing the order of lines of the file if \b-l\b is specified.]"
404887Schin "[+?If no \afile\a is given, or if the \afile\a is \b-\b, \brev\b "
414887Schin "copies from standard input starting at the current offset.]"
424887Schin "[l:line?Reverse the lines of the file.]"
434887Schin
444887Schin "\n"
454887Schin "\n[file ...]\n"
464887Schin "\n"
474887Schin "[+EXIT STATUS?]{"
484887Schin "[+0?All files copied successfully.]"
494887Schin "[+>0?One or more files did not copy.]"
504887Schin "}"
514887Schin "[+SEE ALSO?\bcat\b(1), \btail\b(1)]"
524887Schin ;
534887Schin
544887Schin #include <cmd.h>
554887Schin #include <rev.h>
564887Schin
574887Schin /*
584887Schin * reverse the characters within a line
594887Schin */
rev_char(Sfio_t * in,Sfio_t * out)604887Schin static int rev_char(Sfio_t *in, Sfio_t *out)
614887Schin {
624887Schin register int c;
634887Schin register char *ep, *bp, *cp;
648462SApril.Chin@Sun.COM register wchar_t *wp, *xp;
658462SApril.Chin@Sun.COM register size_t n;
668462SApril.Chin@Sun.COM register size_t w;
678462SApril.Chin@Sun.COM if (mbwide())
684887Schin {
698462SApril.Chin@Sun.COM wp = 0;
708462SApril.Chin@Sun.COM w = 0;
718462SApril.Chin@Sun.COM while(cp = bp = sfgetr(in,'\n',0))
724887Schin {
738462SApril.Chin@Sun.COM ep = bp + (n=sfvalue(in)) - 1;
748462SApril.Chin@Sun.COM if (n > w)
758462SApril.Chin@Sun.COM {
768462SApril.Chin@Sun.COM w = roundof(n + 1, 1024);
778462SApril.Chin@Sun.COM if (!(wp = newof(wp, wchar_t, w, 0)))
788462SApril.Chin@Sun.COM {
798462SApril.Chin@Sun.COM error(ERROR_SYSTEM|2, "out of space");
808462SApril.Chin@Sun.COM return 0;
818462SApril.Chin@Sun.COM }
828462SApril.Chin@Sun.COM }
838462SApril.Chin@Sun.COM xp = wp;
848462SApril.Chin@Sun.COM while (cp < ep)
858462SApril.Chin@Sun.COM *xp++ = mbchar(cp);
868462SApril.Chin@Sun.COM cp = bp;
878462SApril.Chin@Sun.COM while (xp > wp)
888462SApril.Chin@Sun.COM cp += mbconv(cp, *--xp);
898462SApril.Chin@Sun.COM *cp++ = '\n';
908462SApril.Chin@Sun.COM if (sfwrite(out, bp, cp - bp) < 0)
918462SApril.Chin@Sun.COM return -1;
924887Schin }
938462SApril.Chin@Sun.COM if (wp)
948462SApril.Chin@Sun.COM free(wp);
954887Schin }
968462SApril.Chin@Sun.COM else
978462SApril.Chin@Sun.COM while(cp = bp = sfgetr(in,'\n',0))
988462SApril.Chin@Sun.COM {
998462SApril.Chin@Sun.COM ep = bp + (n=sfvalue(in)) -1;
1008462SApril.Chin@Sun.COM while(ep > bp)
1018462SApril.Chin@Sun.COM {
1028462SApril.Chin@Sun.COM c = *--ep;
1038462SApril.Chin@Sun.COM *ep = *bp;
1048462SApril.Chin@Sun.COM *bp++ = c;
1058462SApril.Chin@Sun.COM }
1068462SApril.Chin@Sun.COM if(sfwrite(out,cp,n)<0)
1078462SApril.Chin@Sun.COM return(-1);
1088462SApril.Chin@Sun.COM }
1094887Schin return(0);
1104887Schin }
1114887Schin
1124887Schin int
b_rev(int argc,register char ** argv,void * context)1134887Schin b_rev(int argc, register char** argv, void* context)
1144887Schin {
1154887Schin register Sfio_t *fp;
1164887Schin register char *cp;
1174887Schin register int n, line=0;
1184887Schin NOT_USED(argc);
1194887Schin
1204887Schin cmdinit(argc, argv, context, ERROR_CATALOG, 0);
1214887Schin while (n = optget(argv, usage)) switch (n)
1224887Schin {
1234887Schin case 'l':
1244887Schin line=1;
1254887Schin break;
1264887Schin case ':':
1274887Schin error(2, "%s", opt_info.arg);
1284887Schin break;
1294887Schin case '?':
1304887Schin error(ERROR_usage(2), "%s", opt_info.arg);
1314887Schin break;
1324887Schin }
1334887Schin argv += opt_info.index;
1344887Schin if(error_info.errors)
1354887Schin error(ERROR_usage(2),"%s",optusage((char*)0));
1364887Schin n=0;
1374887Schin if(cp = *argv)
1384887Schin argv++;
1394887Schin do
1404887Schin {
1414887Schin if(!cp || streq(cp,"-"))
1424887Schin fp = sfstdin;
1434887Schin else if(!(fp = sfopen((Sfio_t*)0,cp,"r")))
1444887Schin {
1454887Schin error(ERROR_system(0),"%s: cannot open",cp);
1464887Schin n=1;
1474887Schin continue;
1484887Schin }
1494887Schin if(line)
1504887Schin line = rev_line(fp,sfstdout,sftell(fp));
1514887Schin else
1524887Schin line = rev_char(fp,sfstdout);
1534887Schin if(fp!=sfstdin)
1544887Schin sfclose(fp);
1554887Schin if(line < 0)
1564887Schin error(ERROR_system(1),"write failed");
1574887Schin }
1584887Schin while(cp= *argv++);
1594887Schin return(n);
1604887Schin }
161