summaryrefslogtreecommitdiff
path: root/usr/src/cmd/fold
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/fold
downloadillumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/fold')
-rw-r--r--usr/src/cmd/fold/Makefile45
-rw-r--r--usr/src/cmd/fold/fold.c394
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);
+}