diff options
| author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
|---|---|---|
| committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
| commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
| tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/fold | |
| download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz | |
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/fold')
| -rw-r--r-- | usr/src/cmd/fold/Makefile | 45 | ||||
| -rw-r--r-- | usr/src/cmd/fold/fold.c | 394 |
2 files changed, 439 insertions, 0 deletions
diff --git a/usr/src/cmd/fold/Makefile b/usr/src/cmd/fold/Makefile new file mode 100644 index 0000000000..519c39a0e2 --- /dev/null +++ b/usr/src/cmd/fold/Makefile @@ -0,0 +1,45 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +#ident "%Z%%M% %I% %E% SMI" +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +PROG= fold + +include ../Makefile.cmd + +CFLAGS += $(CCVERBOSE) + +.KEEP_STATE: + +all: $(PROG) + +install: all $(ROOTPROG) + +clean: + +lint: lint_PROG + +include ../Makefile.targ diff --git a/usr/src/cmd/fold/fold.c b/usr/src/cmd/fold/fold.c new file mode 100644 index 0000000000..83a15a00e5 --- /dev/null +++ b/usr/src/cmd/fold/fold.c @@ -0,0 +1,394 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + +/* + * University Copyright- Copyright (c) 1982, 1986, 1988 + * The Regents of the University of California + * All Rights Reserved + * + * University Acknowledgment- Portions of this document are derived from + * software developed by the University of California, Berkeley, and its + * contributors. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <locale.h> +#include <wchar.h> +#include <euc.h> +#include <stdlib.h> /* XCU4 */ +#include <limits.h> +#include <libintl.h> +#include <langinfo.h> +#include <utime.h> +#include <widec.h> +#include <wctype.h> +#include <errno.h> + + +/* + * fold - fold long lines for finite output devices + */ + +static int fold = 80; +static int bflg = 0; +static int sflg = 0; +static int wflg = 0; +static int lastc = 0; +static int col = 0; +static int ncol = 0; +static int spcol = 0; +static wchar_t line[LINE_MAX]; +static wchar_t *lastout = line; +static wchar_t *curc = line; +static wchar_t *lastsp = NULL; +#define MAXARG _POSIX_ARG_MAX + +/* + * Fix lint errors + */ +void exit(); +static void Usage(); +static void putch(); +static void newline_init(); +static int chr_width(); +extern int errno; +static int get_foldw(); + + +int +main(int argc, char *argv[]) +{ + int c, narg; + int ch; + char *cmdline[MAXARG]; + int new_argc; + int w; + extern int optind; + extern char *optarg; + + (void) setlocale(LC_ALL, ""); +#if !defined(TEXT_DOMAIN) +#define TEXT_DOMAIN "SYS_TEST" +#endif + (void) textdomain(TEXT_DOMAIN); + + /* + * Parse -width separately and build + * the new command line without -width. + * Next, use getopt() to parse this + * new command line. + */ + + for (narg = new_argc = 0; narg < argc; narg ++) { + if (argv[narg][0] == '-' && + isdigit(argv[narg][1])) { + + if (get_foldw((char *)&argv[narg][1], &w) < 0) + exit(1); + + fold = w; /* Update with new width */ + } else { + /* Build the new command line */ + cmdline[new_argc++] = argv[narg]; + + /* + * Check to make sure the option with + * required arg should have arg. + * This would check errors introduced in + * mixing non-getopt() options and that of + * getopt()'s due to stripping non-getopt + * options. + */ + if ((argv[narg][0] == '-') && (argv[narg][1] == 'w')) { + if (((narg+1) < argc) && + (argv[narg+1][0] == '-')) { + (void) fprintf(stderr, "fold"); + (void) fprintf(stderr, gettext( + ": option requires an argument -- w\n")); + Usage(); + exit(1); + } + } + } + } + + while ((ch = getopt(new_argc, cmdline, "w:bs")) != EOF) { + switch (ch) { + case 'b': + bflg++; + break; + case 's': + sflg++; + break; + case 'w': + wflg++; + /* No required arg ? */ + if ((optarg == (char *)NULL) || + ((optarg != (char *)NULL) && + (*optarg == '-'))) { + (void) fprintf(stderr, "fold"); + (void) fprintf(stderr, gettext( + ": option requires an argument -- w\n")); + Usage(); + exit(1); + } + /* Bad number ? */ + if (get_foldw(optarg, &w) < 0) + exit(1); + + fold = w; + break; + default: + /* + * Errors should be filtered in previous + * pass. + */ + Usage(); + exit(1); + } /* switch */ + } /* while */ + + do { + if (new_argc > optind) { + if (freopen(cmdline[optind], "r", stdin) == NULL) { + perror(cmdline[optind]); + Usage(); + exit(1); + } + optind++; + } + + for (;;) { + c = getwc(stdin); + if (c == EOF) + break; + (void) putch(c); + lastc = c; + } + if (col != 0) newline_init(); + } while (new_argc > optind); + + return (0); +} + +static void +putch(int c) +{ + wchar_t tline[LINE_MAX]; + + switch (c) { + case '\n': + ncol = 0; + break; + case '\t': + if (bflg) + ncol = col + chr_width(c); + else + ncol = (col + 8) &~ 7; + break; + case '\b': + if (bflg) + ncol = col + chr_width(c); + else + ncol = col ? col - 1 : 0; + break; + case '\r': + if (bflg) + ncol = col + chr_width(c); + else + ncol = 0; + break; + + default: + if (bflg) + ncol = col + chr_width(c); + else + ncol = col + wcwidth(c); + + } + + /* + * Special processing when -b is not specified + * for backspace, and carriage return. + * No newline is inseted before or after the + * special character: backspace, or cr. + * See man page for the handling of backspace + * and CR when there is no -b. + */ + if ((ncol > fold) && (bflg || + (!bflg && (lastc != '\b') && (c != '\b') && + (lastc != '\n') && (c != '\n')))) { + /* + * Need to check the last position for blank + */ + if (sflg && lastsp) { + /* + * Save the output buffer + * as NULL has to be insert into the last + * sp position. + */ + (void) wscpy(tline, line); + *lastsp = (wchar_t)NULL; + (void) fputws(lastout, stdout); + (void) putwchar('\n'); + /* + * Restore the output buffer to stuff + * NULL into the last sp position + * for the new line. + */ + (void) wscpy(line, tline); + lastout = lastsp; + lastsp = NULL; /* Reset the last sp */ + ncol -= spcol; /* Reset column positions */ + col -= spcol; + } else { + (void) newline_init(); + (void) putwchar('\n'); + lastout = curc; + } + } + /* Output buffer is full ? */ + if ((curc + 1) >= (line + LINE_MAX)) { + /* Reach buffer limit */ + if (col > 0) { + *curc = (wchar_t)NULL; + (void) fputws(lastout, stdout); + lastsp = NULL; + } + curc = lastout = line; + + } + + /* Store in output buffer */ + *curc++ = (wchar_t)c; + + switch (c) { + case '\n': + (void) newline_init(); + curc = lastout = line; + break; + case '\t': + if (bflg) + col = col + chr_width(c); + else + col = (col + 8) &~ 7; + if (sflg && iswspace(c)) { + lastsp = curc; + spcol = ncol; + } + + break; + case '\b': + if (bflg) + col = ncol; + else { + if (col) + col--; + } + break; + case '\r': + col = 0; + break; + default: + if (sflg && iswspace(c)) { + lastsp = curc; + spcol = ncol; + } + + if (bflg) + col += chr_width(c); + else + col += wcwidth(c); + + break; + } +} +static +void +Usage() +{ + (void) fprintf(stderr, gettext( + "Usage: fold [-bs] [-w width | -width ] [file...]\n")); +} + +static +void +newline_init() +{ + *curc = (wchar_t)NULL; + (void) fputws(lastout, stdout); + ncol = col = spcol = 0; + lastsp = NULL; +} + +static int +chr_width(c) +register int c; +{ + char chr[MB_LEN_MAX+1]; + register int n; + + n = wctomb(chr, (wchar_t)c); + + return (n > 0 ? n : 0); +} + +static int +get_foldw(toptarg, width) +char *toptarg; +int *width; +{ + char *p; + + if (!toptarg) + goto badno; + + *width = 0; + errno = 0; + *width = strtoul(toptarg, &p, 10); + if (*width == -1) + goto badno; + + if (*p) + goto badno; + + if (!*width) + goto badno; + + return (0); + +badno: + /* fold error message */ + (void) fprintf(stderr, gettext( + "Bad number for fold\n")); + Usage(); + return (-1); +} |
