docs/cut
diff code/cut.c__netbsd.1993-03-21 @ 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__netbsd.1993-03-21 Tue May 12 06:46:59 2015 +0200 1.3 @@ -0,0 +1,270 @@ 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, with or without 1.12 + * modification, are permitted provided that the following conditions 1.13 + * are met: 1.14 + * 1. Redistributions of source code must retain the above copyright 1.15 + * notice, this list of conditions and the following disclaimer. 1.16 + * 2. Redistributions in binary form must reproduce the above copyright 1.17 + * notice, this list of conditions and the following disclaimer in the 1.18 + * documentation and/or other materials provided with the distribution. 1.19 + * 3. All advertising materials mentioning features or use of this software 1.20 + * must display the following acknowledgement: 1.21 + * This product includes software developed by the University of 1.22 + * California, Berkeley and its contributors. 1.23 + * 4. Neither the name of the University nor the names of its contributors 1.24 + * may be used to endorse or promote products derived from this software 1.25 + * without specific prior written permission. 1.26 + * 1.27 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1.28 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.29 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.30 + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 1.31 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1.32 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1.33 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1.34 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 1.35 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 1.36 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1.37 + * SUCH DAMAGE. 1.38 + */ 1.39 + 1.40 +#ifndef lint 1.41 +char copyright[] = 1.42 +"@(#) Copyright (c) 1989 The Regents of the University of California.\n\ 1.43 + All rights reserved.\n"; 1.44 +#endif /* not lint */ 1.45 + 1.46 +#ifndef lint 1.47 +static char sccsid[] = "@(#)cut.c 5.4 (Berkeley) 10/30/90"; 1.48 +#endif /* not lint */ 1.49 + 1.50 +#include <limits.h> 1.51 +#include <stdio.h> 1.52 +#include <ctype.h> 1.53 + 1.54 +int cflag; 1.55 +char dchar; 1.56 +int dflag; 1.57 +int fflag; 1.58 +int sflag; 1.59 + 1.60 +main(argc, argv) 1.61 + int argc; 1.62 + char **argv; 1.63 +{ 1.64 + extern char *optarg; 1.65 + extern int errno, optind; 1.66 + FILE *fp; 1.67 + int ch, (*fcn)(), c_cut(), f_cut(); 1.68 + char *strerror(); 1.69 + 1.70 + dchar = '\t'; /* default delimiter is \t */ 1.71 + 1.72 + while ((ch = getopt(argc, argv, "c:d:f:s")) != EOF) 1.73 + switch(ch) { 1.74 + case 'c': 1.75 + fcn = c_cut; 1.76 + get_list(optarg); 1.77 + cflag = 1; 1.78 + break; 1.79 + case 'd': 1.80 + dchar = *optarg; 1.81 + dflag = 1; 1.82 + break; 1.83 + case 'f': 1.84 + get_list(optarg); 1.85 + fcn = f_cut; 1.86 + fflag = 1; 1.87 + break; 1.88 + case 's': 1.89 + sflag = 1; 1.90 + break; 1.91 + case '?': 1.92 + default: 1.93 + usage(); 1.94 + } 1.95 + argc -= optind; 1.96 + argv += optind; 1.97 + 1.98 + if (fflag) { 1.99 + if (cflag) 1.100 + usage(); 1.101 + } else if (!cflag || dflag || sflag) 1.102 + usage(); 1.103 + 1.104 + if (*argv) 1.105 + for (; *argv; ++argv) { 1.106 + if (!(fp = fopen(*argv, "r"))) { 1.107 + (void)fprintf(stderr, 1.108 + "cut: %s: %s\n", *argv, strerror(errno)); 1.109 + exit(1); 1.110 + } 1.111 + fcn(fp, *argv); 1.112 + } 1.113 + else 1.114 + fcn(stdin, "stdin"); 1.115 + exit(0); 1.116 +} 1.117 + 1.118 +int autostart, autostop, maxval; 1.119 + 1.120 +char positions[_POSIX2_LINE_MAX + 1]; 1.121 + 1.122 +get_list(list) 1.123 + char *list; 1.124 +{ 1.125 + register char *pos; 1.126 + register int setautostart, start, stop; 1.127 + char *p, *strtok(); 1.128 + 1.129 + /* 1.130 + * set a byte in the positions array to indicate if a field or 1.131 + * column is to be selected; use +1, it's 1-based, not 0-based. 1.132 + * This parser is less restrictive than the Draft 9 POSIX spec. 1.133 + * POSIX doesn't allow lists that aren't in increasing order or 1.134 + * overlapping lists. We also handle "-3-5" although there's no 1.135 + * real reason too. 1.136 + */ 1.137 + for (; p = strtok(list, ", \t"); list = NULL) { 1.138 + setautostart = start = stop = 0; 1.139 + if (*p == '-') { 1.140 + ++p; 1.141 + setautostart = 1; 1.142 + } 1.143 + if (isdigit(*p)) { 1.144 + start = stop = strtol(p, &p, 10); 1.145 + if (setautostart && start > autostart) 1.146 + autostart = start; 1.147 + } 1.148 + if (*p == '-') { 1.149 + if (isdigit(p[1])) 1.150 + stop = strtol(p + 1, &p, 10); 1.151 + if (*p == '-') { 1.152 + ++p; 1.153 + if (!autostop || autostop > stop) 1.154 + autostop = stop; 1.155 + } 1.156 + } 1.157 + if (*p) 1.158 + badlist("illegal list value"); 1.159 + if (!stop || !start) 1.160 + badlist("values may not include zero"); 1.161 + if (stop > _POSIX2_LINE_MAX) { 1.162 + /* positions used rather than allocate a new buffer */ 1.163 + (void)sprintf(positions, "%d too large (max %d)", 1.164 + stop, _POSIX2_LINE_MAX); 1.165 + badlist(positions); 1.166 + } 1.167 + if (maxval < stop) 1.168 + maxval = stop; 1.169 + for (pos = positions + start; start++ <= stop; *pos++ = 1); 1.170 + } 1.171 + 1.172 + /* overlapping ranges */ 1.173 + if (autostop && maxval > autostop) 1.174 + maxval = autostop; 1.175 + 1.176 + /* set autostart */ 1.177 + if (autostart) 1.178 + memset(positions + 1, '1', autostart); 1.179 +} 1.180 + 1.181 +/* ARGSUSED */ 1.182 +c_cut(fp, fname) 1.183 + FILE *fp; 1.184 + char *fname; 1.185 +{ 1.186 + register int ch, col; 1.187 + register char *pos; 1.188 + 1.189 + for (;;) { 1.190 + pos = positions + 1; 1.191 + for (col = maxval; col; --col) { 1.192 + if ((ch = getc(fp)) == EOF) 1.193 + return; 1.194 + if (ch == '\n') 1.195 + break; 1.196 + if (*pos++) 1.197 + putchar(ch); 1.198 + } 1.199 + if (ch != '\n') 1.200 + if (autostop) 1.201 + while ((ch = getc(fp)) != EOF && ch != '\n') 1.202 + putchar(ch); 1.203 + else 1.204 + while ((ch = getc(fp)) != EOF && ch != '\n'); 1.205 + putchar('\n'); 1.206 + } 1.207 +} 1.208 + 1.209 +f_cut(fp, fname) 1.210 + FILE *fp; 1.211 + char *fname; 1.212 +{ 1.213 + register int ch, field, isdelim; 1.214 + register char *pos, *p, sep; 1.215 + int output; 1.216 + char lbuf[_POSIX2_LINE_MAX + 1]; 1.217 + 1.218 + for (sep = dchar, output = 0; fgets(lbuf, sizeof(lbuf), fp);) { 1.219 + for (isdelim = 0, p = lbuf;; ++p) { 1.220 + if (!(ch = *p)) { 1.221 + (void)fprintf(stderr, 1.222 + "cut: %s: line too long.\n", fname); 1.223 + exit(1); 1.224 + } 1.225 + /* this should work if newline is delimiter */ 1.226 + if (ch == sep) 1.227 + isdelim = 1; 1.228 + if (ch == '\n') { 1.229 + if (!isdelim && !sflag) 1.230 + (void)printf("%s", lbuf); 1.231 + break; 1.232 + } 1.233 + } 1.234 + if (!isdelim) 1.235 + continue; 1.236 + 1.237 + pos = positions + 1; 1.238 + for (field = maxval, p = lbuf; field; --field, ++pos) { 1.239 + if (*pos) { 1.240 + if (output++) 1.241 + putchar(sep); 1.242 + while ((ch = *p++) != '\n' && ch != sep) 1.243 + putchar(ch); 1.244 + } else 1.245 + while ((ch = *p++) != '\n' && ch != sep); 1.246 + if (ch == '\n') 1.247 + break; 1.248 + } 1.249 + if (ch != '\n') 1.250 + if (autostop) { 1.251 + if (output) 1.252 + putchar(sep); 1.253 + for (; (ch = *p) != '\n'; ++p) 1.254 + putchar(ch); 1.255 + } else 1.256 + for (; (ch = *p) != '\n'; ++p); 1.257 + putchar('\n'); 1.258 + } 1.259 +} 1.260 + 1.261 +badlist(msg) 1.262 + char *msg; 1.263 +{ 1.264 + (void)fprintf(stderr, "cut: [-cf] list: %s.\n", msg); 1.265 + exit(1); 1.266 +} 1.267 + 1.268 +usage() 1.269 +{ 1.270 + (void)fprintf(stderr, 1.271 +"usage:\tcut -c list [file1 ...]\n\tcut -f list [-s] [-d delim] [file ...]\n"); 1.272 + exit(1); 1.273 +}