docs/cut
diff code/cut.c__freebsd.1994-05-27 @ 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__freebsd.1994-05-27 Tue May 12 06:46:59 2015 +0200 1.3 @@ -0,0 +1,296 @@ 1.4 +/* 1.5 + * Copyright (c) 1989, 1993 1.6 + * The Regents of the University of California. 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 +static char copyright[] = 1.42 +"@(#) Copyright (c) 1989, 1993\n\ 1.43 + The Regents of the University of California. All rights reserved.\n"; 1.44 +#endif /* not lint */ 1.45 + 1.46 +#ifndef lint 1.47 +static char sccsid[] = "@(#)cut.c 8.1 (Berkeley) 6/6/93"; 1.48 +#endif /* not lint */ 1.49 + 1.50 +#include <ctype.h> 1.51 +#include <errno.h> 1.52 +#include <limits.h> 1.53 +#include <stdio.h> 1.54 +#include <stdlib.h> 1.55 +#include <string.h> 1.56 + 1.57 +int cflag; 1.58 +char dchar; 1.59 +int dflag; 1.60 +int fflag; 1.61 +int sflag; 1.62 + 1.63 +void c_cut __P((FILE *, char *)); 1.64 +void err __P((const char *, ...)); 1.65 +void f_cut __P((FILE *, char *)); 1.66 +void get_list __P((char *)); 1.67 +void usage __P((void)); 1.68 + 1.69 +int 1.70 +main(argc, argv) 1.71 + int argc; 1.72 + char *argv[]; 1.73 +{ 1.74 + FILE *fp; 1.75 + void (*fcn) __P((FILE *, char *)); 1.76 + int ch; 1.77 + 1.78 + dchar = '\t'; /* default delimiter is \t */ 1.79 + 1.80 + while ((ch = getopt(argc, argv, "c:d:f:s")) != EOF) 1.81 + switch(ch) { 1.82 + case 'c': 1.83 + fcn = c_cut; 1.84 + get_list(optarg); 1.85 + cflag = 1; 1.86 + break; 1.87 + case 'd': 1.88 + dchar = *optarg; 1.89 + dflag = 1; 1.90 + break; 1.91 + case 'f': 1.92 + get_list(optarg); 1.93 + fcn = f_cut; 1.94 + fflag = 1; 1.95 + break; 1.96 + case 's': 1.97 + sflag = 1; 1.98 + break; 1.99 + case '?': 1.100 + default: 1.101 + usage(); 1.102 + } 1.103 + argc -= optind; 1.104 + argv += optind; 1.105 + 1.106 + if (fflag) { 1.107 + if (cflag) 1.108 + usage(); 1.109 + } else if (!cflag || dflag || sflag) 1.110 + usage(); 1.111 + 1.112 + if (*argv) 1.113 + for (; *argv; ++argv) { 1.114 + if (!(fp = fopen(*argv, "r"))) 1.115 + err("%s: %s\n", *argv, strerror(errno)); 1.116 + fcn(fp, *argv); 1.117 + (void)fclose(fp); 1.118 + } 1.119 + else 1.120 + fcn(stdin, "stdin"); 1.121 + exit(0); 1.122 +} 1.123 + 1.124 +int autostart, autostop, maxval; 1.125 + 1.126 +char positions[_POSIX2_LINE_MAX + 1]; 1.127 + 1.128 +void 1.129 +get_list(list) 1.130 + char *list; 1.131 +{ 1.132 + register int setautostart, start, stop; 1.133 + register char *pos; 1.134 + char *p; 1.135 + 1.136 + /* 1.137 + * set a byte in the positions array to indicate if a field or 1.138 + * column is to be selected; use +1, it's 1-based, not 0-based. 1.139 + * This parser is less restrictive than the Draft 9 POSIX spec. 1.140 + * POSIX doesn't allow lists that aren't in increasing order or 1.141 + * overlapping lists. We also handle "-3-5" although there's no 1.142 + * real reason too. 1.143 + */ 1.144 + for (; p = strtok(list, ", \t"); list = NULL) { 1.145 + setautostart = start = stop = 0; 1.146 + if (*p == '-') { 1.147 + ++p; 1.148 + setautostart = 1; 1.149 + } 1.150 + if (isdigit(*p)) { 1.151 + start = stop = strtol(p, &p, 10); 1.152 + if (setautostart && start > autostart) 1.153 + autostart = start; 1.154 + } 1.155 + if (*p == '-') { 1.156 + if (isdigit(p[1])) 1.157 + stop = strtol(p + 1, &p, 10); 1.158 + if (*p == '-') { 1.159 + ++p; 1.160 + if (!autostop || autostop > stop) 1.161 + autostop = stop; 1.162 + } 1.163 + } 1.164 + if (*p) 1.165 + err("[-cf] list: illegal list value\n"); 1.166 + if (!stop || !start) 1.167 + err("[-cf] list: values may not include zero\n"); 1.168 + if (stop > _POSIX2_LINE_MAX) 1.169 + err("[-cf] list: %d too large (max %d)\n", 1.170 + stop, _POSIX2_LINE_MAX); 1.171 + if (maxval < stop) 1.172 + maxval = stop; 1.173 + for (pos = positions + start; start++ <= stop; *pos++ = 1); 1.174 + } 1.175 + 1.176 + /* overlapping ranges */ 1.177 + if (autostop && maxval > autostop) 1.178 + maxval = autostop; 1.179 + 1.180 + /* set autostart */ 1.181 + if (autostart) 1.182 + memset(positions + 1, '1', autostart); 1.183 +} 1.184 + 1.185 +/* ARGSUSED */ 1.186 +void 1.187 +c_cut(fp, fname) 1.188 + FILE *fp; 1.189 + char *fname; 1.190 +{ 1.191 + register int ch, col; 1.192 + register char *pos; 1.193 + 1.194 + for (;;) { 1.195 + pos = positions + 1; 1.196 + for (col = maxval; col; --col) { 1.197 + if ((ch = getc(fp)) == EOF) 1.198 + return; 1.199 + if (ch == '\n') 1.200 + break; 1.201 + if (*pos++) 1.202 + (void)putchar(ch); 1.203 + } 1.204 + if (ch != '\n') 1.205 + if (autostop) 1.206 + while ((ch = getc(fp)) != EOF && ch != '\n') 1.207 + (void)putchar(ch); 1.208 + else 1.209 + while ((ch = getc(fp)) != EOF && ch != '\n'); 1.210 + (void)putchar('\n'); 1.211 + } 1.212 +} 1.213 + 1.214 +void 1.215 +f_cut(fp, fname) 1.216 + FILE *fp; 1.217 + char *fname; 1.218 +{ 1.219 + register int ch, field, isdelim; 1.220 + register char *pos, *p, sep; 1.221 + int output; 1.222 + char lbuf[_POSIX2_LINE_MAX + 1]; 1.223 + 1.224 + for (sep = dchar, output = 0; fgets(lbuf, sizeof(lbuf), fp);) { 1.225 + for (isdelim = 0, p = lbuf;; ++p) { 1.226 + if (!(ch = *p)) 1.227 + err("%s: line too long.\n", fname); 1.228 + /* this should work if newline is delimiter */ 1.229 + if (ch == sep) 1.230 + isdelim = 1; 1.231 + if (ch == '\n') { 1.232 + if (!isdelim && !sflag) 1.233 + (void)printf("%s", lbuf); 1.234 + break; 1.235 + } 1.236 + } 1.237 + if (!isdelim) 1.238 + continue; 1.239 + 1.240 + pos = positions + 1; 1.241 + for (field = maxval, p = lbuf; field; --field, ++pos) { 1.242 + if (*pos) { 1.243 + if (output++) 1.244 + (void)putchar(sep); 1.245 + while ((ch = *p++) != '\n' && ch != sep) 1.246 + (void)putchar(ch); 1.247 + } else 1.248 + while ((ch = *p++) != '\n' && ch != sep); 1.249 + if (ch == '\n') 1.250 + break; 1.251 + } 1.252 + if (ch != '\n') 1.253 + if (autostop) { 1.254 + if (output) 1.255 + (void)putchar(sep); 1.256 + for (; (ch = *p) != '\n'; ++p) 1.257 + (void)putchar(ch); 1.258 + } else 1.259 + for (; (ch = *p) != '\n'; ++p); 1.260 + (void)putchar('\n'); 1.261 + } 1.262 +} 1.263 + 1.264 +void 1.265 +usage() 1.266 +{ 1.267 + (void)fprintf(stderr, 1.268 +"usage:\tcut -c list [file1 ...]\n\tcut -f list [-s] [-d delim] [file ...]\n"); 1.269 + exit(1); 1.270 +} 1.271 + 1.272 +#if __STDC__ 1.273 +#include <stdarg.h> 1.274 +#else 1.275 +#include <varargs.h> 1.276 +#endif 1.277 + 1.278 +void 1.279 +#if __STDC__ 1.280 +err(const char *fmt, ...) 1.281 +#else 1.282 +err(fmt, va_alist) 1.283 + char *fmt; 1.284 + va_dcl 1.285 +#endif 1.286 +{ 1.287 + va_list ap; 1.288 +#if __STDC__ 1.289 + va_start(ap, fmt); 1.290 +#else 1.291 + va_start(ap); 1.292 +#endif 1.293 + (void)fprintf(stderr, "cut: "); 1.294 + (void)vfprintf(stderr, fmt, ap); 1.295 + va_end(ap); 1.296 + (void)fprintf(stderr, "\n"); 1.297 + exit(1); 1.298 + /* NOTREACHED */ 1.299 +}