|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T p ┃
Length: 4780 (0x12ac) Types: TextFile Names: »paste.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/cut/paste.c«
/* * A version of paste. This is compatable with AT&T paste command SVR2. * * John Weald * */ #include <stdio.h> #define MAXLINE 1024 /* Max. allowed line length */ #define MAXFILES 12 /* Max. number of input files */ extern void exit(); main(argc, argv) int argc; char *argv[]; { extern int optind; extern char *optarg; int c; /* For getopt() */ char conchars[MAXFILES]; /* The concatination characters */ int nconchars = 1; /* The number of conchars[] */ int serial = 0; /* True if old type paste "-s" */ conchars[0] = '\t'; while ((c = getopt(argc, argv, "sd:")) != EOF) { switch(c) { case 's': /* Concatinate the same file serially */ serial++; break; case 'd': /* Use other than a single tab */ nconchars = setconcat(conchars, optarg); break; default: /* Does not return */ prusage(); } } if (serial) spaste(&argv[optind], conchars, nconchars); else paste(&argv[optind], conchars, nconchars); exit(0); /* NOTREACHED */ } /* * paste() * * Do the actual paste. */ paste(files, con, ncons) char *files[]; /* Null terminated list of input files */ char con[]; /* The concatination characters */ char ncons; /* The number of above */ { char ibuf[MAXLINE+1]; /* The input buffer */ char obuf[MAXLINE]; /* The output buffer */ register char *iptr = ibuf; register char *optr = obuf; FILE *fps[MAXFILES]; /* One for each open file */ int f; /* Number of files opened */ int allfiles; /* Ditto */ int inc; /* True if concat. char. == '\0'*/ int ocount; /* Output buffer char. count */ char c; /* The current concat. char */ int i; /* * Open all the input files, any filename of '-' means * the standard input. No file name means standard input. */ for (f = 0; files[f] != (char *)NULL; f++) { if (*files[f] == '-') fps[f] = stdin; else if ((fps[f] = fopen(files[f], "r")) == (FILE *)NULL) { fprintf(stderr, "Failed to open file %s\n", files[f]); exit(1); } if (f >= MAXFILES) { fprintf(stderr, "Too many files. Maximum allowed is %d\n", MAXFILES); exit(1); } } if (files[0] == (char *)NULL) { fps[0] = stdin; f++; } /* * Read all lines until no more lines in any file. */ allfiles = f; while (f) { optr = obuf; ocount = 0; /* * Join lines from all files. * * The concatination character may be '\0' which * means no character. The variable inc is an indication * of the concatination character being '\0', we need to * if there is a concatination character to move up the * output buffer. * * The concatination characters are used in a round robin * list. */ for (inc = 0, i = 0; i < allfiles; i++) { iptr = ibuf; optr += inc; /* To save repeated evaluation */ c = con[i % ncons]; inc = c == '\0' ? 0 : 1; if (fps[i] == (FILE *)NULL) { /* No more lines in this file. */ *optr = c; continue; } if (fgets(ibuf, sizeof(ibuf), fps[i]) == (char *)NULL) { /* Reached EOF - finished with the file */ (void)fclose(fps[i]); fps[i] = (FILE *)NULL; *optr = c; f--; continue; } /* * Replace the newline with the concatination character. * There is no need to look for end-of-string since * we know that * a) if ibuf is full to the max, then we will * overflow obuf before we hit the end of ibuf. * b) if ibuf is not full, then it must contain a * a newline character, but may or may not * fit into obuf. */ for (; *iptr != '\n'; ocount++) { /* Need space for trailing null */ if (ocount >= sizeof(obuf) - 1) { fprintf(stderr, "Output line too long, maximum length is %d.\n", MAXLINE); exit(1); } *optr++ = *iptr++; } *optr = c; } if (f) { *optr = '\0'; puts(obuf); } } } /* * setconcat() * * Parse the concatination characters and place them in the array c. * Return the number of concatination characters. * * Specials are: * \n - Newline * \t - Tab (default) * \ - Backslash * \0 - No concatination character */ static int setconcat(c, in) char *c; char *in; { int i; /* The number seen so far */ for (i = 0; *in != '\0'; in++, c++, i++) { if (i > MAXFILES) { fprintf(stderr, "Too many concatination characters, maximum allowed is %d\n", MAXFILES); exit(1); } if (*in != '\\') { *c = *in; continue; } in++; switch (*in) { case 'n': *c = '\n'; break; case 't': *c = '\t'; break; case '0': *c = '\0'; break; default: /* Includes '\\' */ *c = *in; break; } } return(i); } static prusage() { fprintf(stderr, "USAGE: paste [-s] [-d<list>] files\n"); exit(1); }