diff options
author | chin <none@none> | 2007-08-17 12:01:52 -0700 |
---|---|---|
committer | chin <none@none> | 2007-08-17 12:01:52 -0700 |
commit | da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968 (patch) | |
tree | 5280d3b78e289fe9551371ab6e7f15ef9944ea14 /usr/src/lib/libcmd/common/paste.c | |
parent | 073dbf9103ef2a2b05d8a16e2d26db04e0374b0e (diff) | |
download | illumos-joyent-da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968.tar.gz |
6437624 RFE: Add ksh93 (as /usr/bin/ksh93) and libshell.so to OS/Net
6505835 AST tools and library (libpp) required for creating l10n messages for ksh93
PSARC/2006/550 Korn Shell 93 Integration
PSARC/2006/587 /etc/ksh.kshrc for ksh93
PSARC/2007/035 ksh93 Amendments
Contributed by Roland Mainz <roland.mainz@nrubsig.org>
--HG--
rename : usr/src/lib/libcmd/common/mapfile-vers => deleted_files/usr/src/lib/libcmd/common/mapfile-vers
rename : usr/src/lib/libcmd/common/placeholder.c => deleted_files/usr/src/lib/libcmd/common/placeholder.c
Diffstat (limited to 'usr/src/lib/libcmd/common/paste.c')
-rw-r--r-- | usr/src/lib/libcmd/common/paste.c | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/usr/src/lib/libcmd/common/paste.c b/usr/src/lib/libcmd/common/paste.c new file mode 100644 index 0000000000..5aaeb369ac --- /dev/null +++ b/usr/src/lib/libcmd/common/paste.c @@ -0,0 +1,247 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1992-2007 AT&T Knowledge Ventures * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Knowledge Ventures * +* * +* A copy of the License is available at * +* http://www.opensource.org/licenses/cpl1.0.txt * +* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* David Korn <dgk@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * David Korn + * AT&T Bell Laboratories + * + * paste [-s] [-d delim] [file] ... + * + * paste lines from files together + */ + +static const char usage[] = +"[-?\n@(#)$Id: paste (AT&T Research) 1999-06-22 $\n]" +USAGE_LICENSE +"[+NAME?paste - merge lines of files]" +"[+DESCRIPTION?\bpaste\b concatenates the corresponding lines of a " + "given input file and writes the resulting lines to standard " + "output. By default \bpaste\b replaces the newline character of " + "every line other than the last input file with the TAB character.]" +"[+?Unless the \b-s\b option is specified, if an end-of-file is encountered " + "on one or more input files, but not all input files, \bpaste\b " + "behaves as if empty lines were read from the file(s) on which " + "end-of-file was detected.]" +"[+?Unless the \b-s\b option is specified, \bpaste\b is limited by " + "the underlying operating system on how many \afile\a operands " + "can be specified.]" +"[+?If no \afile\a operands are given or if the \afile\a is \b-\b, \bpaste\b " + "reads from standard input. The start of the file is defined as the " + "current offset.]" + +"[s:serial?Paste the lines of one file at a time rather than one line " + "from each file. In this case if the \b-d\b option is " + "specified the delimiter will be reset to the first in the " + "list at the beginning of each file.]" +"[d:delimiters]:[list?\alist\a specifies a list of delimiters. These " + "delimiters are used circularly instead of TAB to replace " + "the newline character of the input lines. Unless the \b-s\b " + "option is specified, the delimiter will be reset to the first " + "element of \alist\a each time a line is processed from each file. " + "The delimiter characters corresponding to \alist\a will be found " + "by treating \alist\a as an ANSI-C string, except that the \b\\0\b " + "sequence will insert the empty string instead of the null character.]" +"\n" +"\n[file ...]\n" +"\n" +"[+EXIT STATUS?]{" + "[+0?All files processed successfully.]" + "[+>0?An error occurred.]" +"}" +"[+SEE ALSO?\bcut\b(1), \bcat\b(1), \bjoin\b(1)]" +; + + +#include <cmd.h> + +/* + * paste the lines of the <nstreams> defined in <streams> and put results + * to <out> + */ + +static int paste(int nstream,Sfio_t* streams[],Sfio_t *out, register const char *delim,int dlen) +{ + register const char *cp; + register int d, n, more=1; + register Sfio_t *fp; + do + { + d = (dlen>0?0:-1); + for(n=more-1,more=0; n < nstream;) + { + if(fp=streams[n]) + { + if(cp = sfgetr(fp,'\n',0)) + { + if(n==0) + more = 1; + else if(!more) /* first stream with output */ + { + if(dlen==1) + sfnputc(out, *delim, n); + else if(dlen>0) + { + for(d=n; d>dlen; d-=dlen) + sfwrite(out,delim,dlen); + if(d) + sfwrite(out,delim,d); + } + more = n+1; + } + if(sfwrite(out,cp,sfvalue(fp)-((n+1)<nstream)) < 0) + return(-1); + } + else + streams[n] = 0; + } + if(++n<nstream && more && d>=0) + { + register int c; + if(d >= dlen) + d = 0; + if(c=delim[d++]) + sfputc(out,c); + } + else if(n==nstream && !streams[n-1] && more) + sfputc(out,'\n'); + } + } + while(more); + return(0); +} + +/* + * Handles paste -s, for file <in> to file <out> using delimiters <delim> + */ +static int spaste(Sfio_t *in,register Sfio_t* out,register const char *delim,int dlen) +{ + register const char *cp; + register int d=0; + if(cp = sfgetr(in,'\n',0)) + { + if(sfwrite(out,cp,sfvalue(in)-1) < 0) + return(-1); + } + while(cp=sfgetr(in, '\n',0)) + { + if(dlen) + { + register int c; + if(d >= dlen) + d = 0; + if(c=delim[d++]) + sfputc(out,c); + } + if(sfwrite(out,cp,sfvalue(in)-1) < 0) + return(-1); + } + sfputc(out,'\n'); + return(0); +} + +int +b_paste(int argc,register char *argv[], void* context) +{ + register int n, sflag=0; + register Sfio_t *fp, **streams; + register char *cp, *delim; + int dlen; + char defdelim[2]; + + cmdinit(argc, argv, context, ERROR_CATALOG, 0); + delim = 0; + while (n = optget(argv, usage)) switch (n) + { + case 'd': + delim = opt_info.arg; + break; + case 's': + sflag++; + break; + case ':': + error(2, "%s", opt_info.arg); + break; + case '?': + error(ERROR_usage(2), "%s", opt_info.arg); + break; + } + argv += opt_info.index; + if(error_info.errors) + error(ERROR_usage(2),"%s", optusage(NiL)); + if(delim) + dlen = stresc(delim); + else + { + *(delim = defdelim) = '\t'; + dlen = 1; + } + if(cp = *argv) + { + n = argc - opt_info.index; + argv++; + } + else + n = 1; + if(!sflag) + { + if (!(streams = (Sfio_t**)stakalloc(n*sizeof(Sfio_t*)))) + error(ERROR_exit(1), "out of space"); + n = 0; + } + do + { + if(!cp || streq(cp,"-")) + fp = sfstdin; + else if(!(fp = sfopen(NiL,cp,"r"))) + { + error(ERROR_system(0),"%s: cannot open",cp); + error_info.errors = 1; + } + if(fp && sflag) + { + if(spaste(fp,sfstdout,delim,dlen) < 0) + { + error(ERROR_system(0),"write failed"); + error_info.errors = 1; + } + if(fp!=sfstdin) + sfclose(fp); + } + else + streams[n++] = fp; + } + while(cp= *argv++); + if(!sflag) + { + if(error_info.errors==0 && paste(n,streams,sfstdout,delim,dlen) < 0) + { + error(ERROR_system(0),"write failed"); + error_info.errors = 1; + } + while(--n>=0) + { + if((fp=streams[n]) && fp!=sfstdin) + sfclose(fp); + } + } + return(error_info.errors); +} + |