=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/cut/cut.c,v retrieving revision 1.22 retrieving revision 1.23 diff -c -r1.22 -r1.23 *** src/usr.bin/cut/cut.c 2015/11/03 04:57:20 1.22 --- src/usr.bin/cut/cut.c 2015/12/02 00:56:46 1.23 *************** *** 1,4 **** ! /* $OpenBSD: cut.c,v 1.22 2015/11/03 04:57:20 mmcc Exp $ */ /* $NetBSD: cut.c,v 1.9 1995/09/02 05:59:23 jtc Exp $ */ /* --- 1,4 ---- ! /* $OpenBSD: cut.c,v 1.23 2015/12/02 00:56:46 schwarze Exp $ */ /* $NetBSD: cut.c,v 1.9 1995/09/02 05:59:23 jtc Exp $ */ /* *************** *** 33,38 **** --- 33,39 ---- * SUCH DAMAGE. */ + #include #include #include #include *************** *** 43,54 **** #include #include int cflag; - char dchar; int dflag; int fflag; int sflag; void c_cut(FILE *, char *); void f_cut(FILE *, char *); void get_list(char *); --- 44,60 ---- #include #include + char dchar[5]; + int dlen; + + int bflag; int cflag; int dflag; int fflag; + int nflag; int sflag; + void b_cut(FILE *, char *); void c_cut(FILE *, char *); void f_cut(FILE *, char *); void get_list(char *); *************** *** 61,97 **** void (*fcn)(FILE *, char *); int ch, rval; ! setlocale (LC_ALL, ""); if (pledge("stdio rpath", NULL) == -1) err(1, "pledge"); ! dchar = '\t'; /* default delimiter is \t */ - /* Since we don't support multi-byte characters, the -c and -b - options are equivalent, and the -n option is meaningless. */ while ((ch = getopt(argc, argv, "b:c:d:f:sn")) != -1) switch(ch) { case 'b': case 'c': - fcn = c_cut; get_list(optarg); cflag = 1; break; case 'd': ! dchar = *optarg; dflag = 1; break; case 'f': get_list(optarg); - fcn = f_cut; fflag = 1; break; case 's': sflag = 1; break; - case 'n': - break; case '?': default: usage(); --- 67,109 ---- void (*fcn)(FILE *, char *); int ch, rval; ! setlocale(LC_CTYPE, ""); if (pledge("stdio rpath", NULL) == -1) err(1, "pledge"); ! dchar[0] = '\t'; /* default delimiter */ ! dchar[1] = '\0'; ! dlen = 1; while ((ch = getopt(argc, argv, "b:c:d:f:sn")) != -1) switch(ch) { case 'b': + get_list(optarg); + bflag = 1; + break; case 'c': get_list(optarg); cflag = 1; break; case 'd': ! if ((dlen = mblen(optarg, MB_CUR_MAX)) == -1) ! usage(); ! assert(dlen < sizeof(dchar)); ! (void)memcpy(dchar, optarg, dlen); ! dchar[dlen] = '\0'; dflag = 1; break; case 'f': get_list(optarg); fflag = 1; break; + case 'n': + nflag = 1; + break; case 's': sflag = 1; break; case '?': default: usage(); *************** *** 99,110 **** argc -= optind; argv += optind; ! if (fflag) { ! if (cflag) ! usage(); ! } else if (!cflag || dflag || sflag) usage(); rval = 0; if (*argv) for (; *argv; ++argv) { --- 111,131 ---- argc -= optind; argv += optind; ! if (bflag + cflag + fflag != 1 || ! (nflag && !bflag) || ! ((dflag || sflag) && !fflag)) usage(); + if (MB_CUR_MAX == 1) { + nflag = 0; + if (cflag) { + bflag = 1; + cflag = 0; + } + } + + fcn = fflag ? f_cut : (cflag || nflag) ? c_cut : b_cut; + rval = 0; if (*argv) for (; *argv; ++argv) { *************** *** 192,198 **** /* ARGSUSED */ void ! c_cut(FILE *fp, char *fname) { int ch, col; char *pos; --- 213,219 ---- /* ARGSUSED */ void ! b_cut(FILE *fp, char *fname) { int ch, col; char *pos; *************** *** 220,284 **** } void ! f_cut(FILE *fp, char *fname) { ! int ch, field, isdelim; ! char *pos, *p, sep; ! int output; ! size_t len; ! char *lbuf, *tbuf; ! for (sep = dchar, tbuf = NULL; (lbuf = fgetln(fp, &len));) { ! output = 0; ! if (lbuf[len - 1] != '\n') { ! /* no newline at the end of the last line so add one */ ! if ((tbuf = malloc(len + 1)) == NULL) ! err(1, NULL); ! memcpy(tbuf, lbuf, len); ! tbuf[len] = '\n'; ! lbuf = tbuf; } ! for (isdelim = 0, p = lbuf;; ++p) { ! ch = *p; ! /* this should work if newline is delimiter */ ! if (ch == sep) ! isdelim = 1; ! if (ch == '\n') { ! if (!isdelim && !sflag) ! (void)fwrite(lbuf, len, 1, stdout); ! break; ! } ! } ! if (!isdelim) continue; pos = positions + 1; ! for (field = maxval, p = lbuf; field; --field, ++pos) { ! if (*pos) { ! if (output++) ! (void)putchar(sep); ! while ((ch = *p++) != '\n' && ch != sep) ! (void)putchar(ch); } else ! while ((ch = *p++) != '\n' && ch != sep) ! ; ! if (ch == '\n') break; } ! if (ch != '\n') { ! if (autostop) { ! if (output) ! (void)putchar(sep); ! for (; (ch = *p) != '\n'; ++p) ! (void)putchar(ch); ! } else ! for (; (ch = *p) != '\n'; ++p) ! ; ! } ! (void)putchar('\n'); } - if (tbuf) - free(tbuf); } void --- 241,322 ---- } void ! c_cut(FILE *fp, char *fname) { ! static char *line = NULL; ! static size_t linesz = 0; ! ssize_t linelen; ! char *cp, *pos, *maxpos; ! int len; ! while ((linelen = getline(&line, &linesz, fp)) != -1) { ! if (line[linelen - 1] == '\n') ! line[linelen - 1] = '\0'; ! ! cp = line; ! pos = positions + 1; ! maxpos = pos + maxval; ! while(pos < maxpos && *cp != '\0') { ! len = mblen(cp, MB_CUR_MAX); ! if (len == -1) ! len = 1; ! pos += nflag ? len : 1; ! if (pos[-1] == '\0') ! cp += len; ! else ! while (len--) ! putchar(*cp++); } ! if (autostop) ! puts(cp); ! else ! putchar('\n'); ! } ! } ! ! void ! f_cut(FILE *fp, char *fname) ! { ! static char *line = NULL; ! static size_t linesz = 0; ! ssize_t linelen; ! char *sp, *ep, *pos, *maxpos; ! int output; ! ! while ((linelen = getline(&line, &linesz, fp)) != -1) { ! if (line[linelen - 1] == '\n') ! line[linelen - 1] = '\0'; ! ! if ((ep = strstr(line, dchar)) == NULL) { ! if (!sflag) ! puts(line); continue; + } pos = positions + 1; ! maxpos = pos + maxval; ! output = 0; ! sp = line; ! for (;;) { ! if (*pos++) { ! if (output) ! fputs(dchar, stdout); ! while (sp < ep) ! putchar(*sp++); ! output = 1; } else ! sp = ep; ! if (*sp == '\0' || pos == maxpos) break; + sp += dlen; + if ((ep = strstr(sp, dchar)) == NULL) + ep = strchr(sp, '\0'); } ! if (autostop) ! puts(sp); ! else ! putchar('\n'); } } void