docs/cut
diff code/cut.c__4.3bsd-reno.1990-06-25 @ 14:21ad1c1548c4
Code ausgewaehlter Implementierungen eingefuegt
Das Datum entspricht dem Dateiaenderungsdatum.
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Tue, 12 May 2015 06:46:59 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/code/cut.c__4.3bsd-reno.1990-06-25 Tue May 12 06:46:59 2015 +0200 1.3 @@ -0,0 +1,256 @@ 1.4 +/* 1.5 + * Copyright (c) 1989 The Regents of the University of California. 1.6 + * All rights reserved. 1.7 + * 1.8 + * This code is derived from software contributed to Berkeley by 1.9 + * Adam S. Moskowitz of Menlo Consulting and Marciano Pitargue. 1.10 + * 1.11 + * Redistribution and use in source and binary forms are permitted provided 1.12 + * that: (1) source distributions retain this entire copyright notice and 1.13 + * comment, and (2) distributions including binaries display the following 1.14 + * acknowledgement: ``This product includes software developed by the 1.15 + * University of California, Berkeley and its contributors'' in the 1.16 + * documentation or other materials provided with the distribution and in 1.17 + * all advertising materials mentioning features or use of this software. 1.18 + * Neither the name of the University nor the names of its contributors may 1.19 + * be used to endorse or promote products derived from this software without 1.20 + * specific prior written permission. 1.21 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1.22 + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1.23 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1.24 + */ 1.25 + 1.26 +#ifndef lint 1.27 +char copyright[] = 1.28 +"@(#) Copyright (c) 1989 The Regents of the University of California.\n\ 1.29 + All rights reserved.\n"; 1.30 +#endif /* not lint */ 1.31 + 1.32 +#ifndef lint 1.33 +static char sccsid[] = "@(#)cut.c 5.3 (Berkeley) 6/24/90"; 1.34 +#endif /* not lint */ 1.35 + 1.36 +#include <limits.h> 1.37 +#include <stdio.h> 1.38 +#include <ctype.h> 1.39 + 1.40 +int cflag; 1.41 +char dchar; 1.42 +int dflag; 1.43 +int fflag; 1.44 +int sflag; 1.45 + 1.46 +main(argc, argv) 1.47 + int argc; 1.48 + char **argv; 1.49 +{ 1.50 + extern char *optarg; 1.51 + extern int errno, optind; 1.52 + FILE *fp; 1.53 + int ch, (*fcn)(), c_cut(), f_cut(); 1.54 + char *strerror(); 1.55 + 1.56 + dchar = '\t'; /* default delimiter is \t */ 1.57 + 1.58 + while ((ch = getopt(argc, argv, "c:d:f:s")) != EOF) 1.59 + switch(ch) { 1.60 + case 'c': 1.61 + fcn = c_cut; 1.62 + get_list(optarg); 1.63 + cflag = 1; 1.64 + break; 1.65 + case 'd': 1.66 + dchar = *optarg; 1.67 + dflag = 1; 1.68 + break; 1.69 + case 'f': 1.70 + get_list(optarg); 1.71 + fcn = f_cut; 1.72 + fflag = 1; 1.73 + break; 1.74 + case 's': 1.75 + sflag = 1; 1.76 + break; 1.77 + case '?': 1.78 + default: 1.79 + usage(); 1.80 + } 1.81 + argc -= optind; 1.82 + argv += optind; 1.83 + 1.84 + if (fflag) { 1.85 + if (cflag) 1.86 + usage(); 1.87 + } else if (!cflag || dflag || sflag) 1.88 + usage(); 1.89 + 1.90 + if (*argv) 1.91 + for (; *argv; ++argv) { 1.92 + if (!(fp = fopen(*argv, "r"))) { 1.93 + (void)fprintf(stderr, 1.94 + "cut: %s: %s\n", *argv, strerror(errno)); 1.95 + exit(1); 1.96 + } 1.97 + fcn(fp, *argv); 1.98 + } 1.99 + else 1.100 + fcn(stdin, "stdin"); 1.101 + exit(0); 1.102 +} 1.103 + 1.104 +int autostart, autostop, maxval; 1.105 + 1.106 +char positions[_BSD_LINE_MAX + 1]; 1.107 + 1.108 +get_list(list) 1.109 + char *list; 1.110 +{ 1.111 + register char *pos; 1.112 + register int setautostart, start, stop; 1.113 + char *p, *strtok(); 1.114 + 1.115 + /* 1.116 + * set a byte in the positions array to indicate if a field or 1.117 + * column is to be selected; use +1, it's 1-based, not 0-based. 1.118 + * This parser is less restrictive than the Draft 9 POSIX spec. 1.119 + * POSIX doesn't allow lists that aren't in increasing order or 1.120 + * overlapping lists. We also handle "-3-5" although there's no 1.121 + * real reason too. 1.122 + */ 1.123 + for (; p = strtok(list, ", \t"); list = NULL) { 1.124 + setautostart = start = stop = 0; 1.125 + if (*p == '-') { 1.126 + ++p; 1.127 + setautostart = 1; 1.128 + } 1.129 + if (isdigit(*p)) { 1.130 + start = stop = strtol(p, &p, 10); 1.131 + if (setautostart && start > autostart) 1.132 + autostart = start; 1.133 + } 1.134 + if (*p == '-') { 1.135 + if (isdigit(p[1])) 1.136 + stop = strtol(p + 1, &p, 10); 1.137 + if (*p == '-') { 1.138 + ++p; 1.139 + if (!autostop || autostop > stop) 1.140 + autostop = stop; 1.141 + } 1.142 + } 1.143 + if (*p) 1.144 + badlist("illegal list value"); 1.145 + if (!stop || !start) 1.146 + badlist("values may not include zero"); 1.147 + if (stop > _BSD_LINE_MAX) { 1.148 + /* positions used rather than allocate a new buffer */ 1.149 + (void)sprintf(positions, "%d too large (max %d)", 1.150 + stop, _BSD_LINE_MAX); 1.151 + badlist(positions); 1.152 + } 1.153 + if (maxval < stop) 1.154 + maxval = stop; 1.155 + for (pos = positions + start; start++ <= stop; *pos++ = 1); 1.156 + } 1.157 + 1.158 + /* overlapping ranges */ 1.159 + if (autostop && maxval > autostop) 1.160 + maxval = autostop; 1.161 + 1.162 + /* set autostart */ 1.163 + if (autostart) 1.164 + memset(positions + 1, '1', autostart); 1.165 +} 1.166 + 1.167 +/* ARGSUSED */ 1.168 +c_cut(fp, fname) 1.169 + FILE *fp; 1.170 + char *fname; 1.171 +{ 1.172 + register int ch, col; 1.173 + register char *pos; 1.174 + 1.175 + for (;;) { 1.176 + pos = positions + 1; 1.177 + for (col = maxval; col; --col) { 1.178 + if ((ch = getc(fp)) == EOF) 1.179 + return; 1.180 + if (ch == '\n') 1.181 + break; 1.182 + if (*pos++) 1.183 + putchar(ch); 1.184 + } 1.185 + if (ch != '\n') 1.186 + if (autostop) 1.187 + while ((ch = getc(fp)) != EOF && ch != '\n') 1.188 + putchar(ch); 1.189 + else 1.190 + while ((ch = getc(fp)) != EOF && ch != '\n'); 1.191 + putchar('\n'); 1.192 + } 1.193 +} 1.194 + 1.195 +f_cut(fp, fname) 1.196 + FILE *fp; 1.197 + char *fname; 1.198 +{ 1.199 + register int ch, field, isdelim; 1.200 + register char *pos, *p, sep; 1.201 + int output; 1.202 + char lbuf[_BSD_LINE_MAX + 1]; 1.203 + 1.204 + for (sep = dchar, output = 0; fgets(lbuf, sizeof(lbuf), fp);) { 1.205 + for (isdelim = 0, p = lbuf;; ++p) { 1.206 + if (!(ch = *p)) { 1.207 + (void)fprintf(stderr, 1.208 + "cut: %s: line too long.\n", fname); 1.209 + exit(1); 1.210 + } 1.211 + /* this should work if newline is delimiter */ 1.212 + if (ch == sep) 1.213 + isdelim = 1; 1.214 + if (ch == '\n') { 1.215 + if (!isdelim && !sflag) 1.216 + (void)printf("%s", lbuf); 1.217 + break; 1.218 + } 1.219 + } 1.220 + if (!isdelim) 1.221 + continue; 1.222 + 1.223 + pos = positions + 1; 1.224 + for (field = maxval, p = lbuf; field; --field, ++pos) { 1.225 + if (*pos) { 1.226 + if (output++) 1.227 + putchar(sep); 1.228 + while ((ch = *p++) != '\n' && ch != sep) 1.229 + putchar(ch); 1.230 + } else 1.231 + while ((ch = *p++) != '\n' && ch != sep); 1.232 + if (ch == '\n') 1.233 + break; 1.234 + } 1.235 + if (ch != '\n') 1.236 + if (autostop) { 1.237 + if (output) 1.238 + putchar(sep); 1.239 + for (; (ch = *p) != '\n'; ++p) 1.240 + putchar(ch); 1.241 + } else 1.242 + for (; (ch = *p) != '\n'; ++p); 1.243 + putchar('\n'); 1.244 + } 1.245 +} 1.246 + 1.247 +badlist(msg) 1.248 + char *msg; 1.249 +{ 1.250 + (void)fprintf(stderr, "cut: [-cf] list: %s.\n", msg); 1.251 + exit(1); 1.252 +} 1.253 + 1.254 +usage() 1.255 +{ 1.256 + (void)fprintf(stderr, 1.257 +"usage:\tcut -c list [file1 ...]\n\tcut -f list [-s] [-d delim] [file ...]\n"); 1.258 + exit(1); 1.259 +}