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/expand | |
| download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz | |
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/expand')
| -rw-r--r-- | usr/src/cmd/expand/Makefile | 60 | ||||
| -rw-r--r-- | usr/src/cmd/expand/expand.c | 282 | ||||
| -rw-r--r-- | usr/src/cmd/expand/unexpand.c | 277 |
3 files changed, 619 insertions, 0 deletions
diff --git a/usr/src/cmd/expand/Makefile b/usr/src/cmd/expand/Makefile new file mode 100644 index 0000000000..3799b14d2b --- /dev/null +++ b/usr/src/cmd/expand/Makefile @@ -0,0 +1,60 @@ +# +# 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. +# +# ident "%Z%%M% %I% %E% SMI" +# +# cmd/expand/Makefile +# + +PROG= expand unexpand +SRCS= $(PROG:=.c) + +include ../Makefile.cmd + +# workaround two meanings for expand.po +POFILES= expand_cmd.po unexpand.po +POFILE= expand.po + +CLEANFILES += expand_cmd.c + +.KEEP_STATE: + +all: $(PROG) + +install: all $(ROOTPROG) + +clean: + +lint: + $(LINT.c) expand.c $(LDLIBS) + $(LINT.c) unexpand.c $(LDLIBS) + +$(POFILE): $(POFILES) + $(RM) $@; cat $(POFILES) > $@ + +expand_cmd.c: + $(RM) $@; cp expand.c $@ + +include ../Makefile.targ diff --git a/usr/src/cmd/expand/expand.c b/usr/src/cmd/expand/expand.c new file mode 100644 index 0000000000..49f3e08255 --- /dev/null +++ b/usr/src/cmd/expand/expand.c @@ -0,0 +1,282 @@ +/* + * 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 1989 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 <libintl.h> +#include <locale.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <limits.h> +#include <wchar.h> + +/* + * expand - expand tabs to equivalent spaces + */ +static int nstops = 0; +static int tabstops[100]; +static int isClocale; + +static void getstops(const char *); +static void usage(void); + +int +main(argc, argv) +int argc; +char *argv[]; +{ + static char ibuf[BUFSIZ]; + register int c, column; + register int n; + register int i, j; + char *locale; + int flag, tflag = 0; + int len; + int p_col; + wchar_t wc; + char *p1, *p2; + + (void) setlocale(LC_ALL, ""); + locale = setlocale(LC_CTYPE, NULL); + isClocale = (strcmp(locale, "C") == 0); +#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ +#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ +#endif + (void) textdomain(TEXT_DOMAIN); + + /* + * First, look for and extract any "-<number>" args then pass + * them to getstops(). + */ + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "--") == 0) + break; + + if (*argv[i] != '-') + continue; + if (!isdigit(*(argv[i]+1))) + continue; + + getstops(argv[i]+1); + tflag++; + + /* Pull this arg from list */ + for (j = i; j < (argc-1); j++) + argv[j] = argv[j+1]; + argc--; + } + + while ((flag = getopt(argc, argv, "t:")) != EOF) { + switch (flag) { + case 't': + if (tflag) + usage(); + + getstops(optarg); + break; + + default: + usage(); + break; + } + } + + argc -= optind; + argv = &argv[optind]; + + do { + if (argc > 0) { + if (freopen(argv[0], "r", stdin) == NULL) { + perror(argv[0]); + exit(1); + /* NOTREACHED */ + } + argc--; + argv++; + } + + column = 0; + p1 = p2 = ibuf; + for (;;) { + if (p1 >= p2) { + p1 = ibuf; + if ((len = fread(p1, 1, BUFSIZ, stdin)) <= 0) + break; + p2 = p1 + len; + } + + c = *p1++; + switch (c) { + case '\t': + if (nstops == 0) { + do { + (void) putchar(' '); + column++; + } while (column & 07); + continue; + } + if (nstops == 1) { + do { + (void) putchar(' '); + column++; + } while ( + ((column - 1) % tabstops[0]) != + (tabstops[0] - 1)); + continue; + } + for (n = 0; n < nstops; n++) + if (tabstops[n] > column) + break; + if (n == nstops) { + (void) putchar(' '); + column++; + continue; + } + while (column < tabstops[n]) { + (void) putchar(' '); + column++; + } + continue; + + case '\b': + if (column) + column--; + (void) putchar('\b'); + continue; + + default: + if (isClocale) { + (void) putchar(c); + column++; + continue; + } + + if (isascii(c)) { + (void) putchar(c); + column++; + continue; + } + + p1--; + if ((len = (p2 - p1)) < + (unsigned int)MB_CUR_MAX) { + for (n = 0; n < len; n++) + ibuf[n] = *p1++; + p1 = ibuf; + p2 = p1 + n; + if ((len = fread(p2, 1, BUFSIZ - n, + stdin)) > 0) + p2 += len; + } + if ((len = (p2 - p1)) > + (unsigned int)MB_CUR_MAX) + len = (unsigned int)MB_CUR_MAX; + + if ((len = mbtowc(&wc, p1, len)) <= 0) { + (void) putchar(c); + column++; + p1++; + continue; + } + + if ((p_col = wcwidth(wc)) < 0) + p_col = len; + p1 += len; + (void) putwchar(wc); + column += p_col; + continue; + + case '\n': + (void) putchar(c); + column = 0; + continue; + } + } + } while (argc > 0); + + return (0); + /* NOTREACHED */ +} + +static void +getstops(const char *cp) +{ + register int i; + + for (;;) { + i = 0; + while (*cp >= '0' && *cp <= '9') + i = i * 10 + *cp++ - '0'; + + if (i <= 0 || i > INT_MAX) { + (void) fprintf(stderr, gettext( + "expand: invalid tablist\n")); + usage(); + } + + if (nstops > 0 && i <= tabstops[nstops-1]) { + (void) fprintf(stderr, gettext( + "expand: tablist must be increasing\n")); + usage(); + } + + tabstops[nstops++] = i; + if (*cp == 0) + break; + + if (*cp != ',' && *cp != ' ') { + (void) fprintf(stderr, gettext( + "expand: invalid tablist\n")); + usage(); + } + cp++; + } +} + +static void +usage(void) +{ + (void) fprintf(stderr, gettext( + "usage: expand [-t tablist] [file ...]\n" + " expand [-tabstop] [-tab1,tab2,...,tabn] [file ...]\n")); + exit(2); + /* NOTREACHED */ +} diff --git a/usr/src/cmd/expand/unexpand.c b/usr/src/cmd/expand/unexpand.c new file mode 100644 index 0000000000..82de1608d9 --- /dev/null +++ b/usr/src/cmd/expand/unexpand.c @@ -0,0 +1,277 @@ +/* + * 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 1989 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" + +/* + * unexpand - put tabs into a file replacing blanks + */ +#include <stdio.h> +#include <limits.h> +#include <stdlib.h> +#include <locale.h> +#include <libintl.h> +#include <wchar.h> + +#define INPUT_SIZ LINE_MAX /* POSIX.2 */ +#define MAX_TABS 100 /* maximum number of tabstops */ + +static int nstops = 0; /* total number of tabstops */ +static int tabstops[MAX_TABS]; /* the tabstops themselves */ + +static void tabify(wchar_t *, int); +static void getstops(const char *); +static void usage(void); + +int +main(argc, argv) +int argc; +char *argv[]; +{ + int flag; /* option flag read by getopt() */ + int all = 0; /* -a flag */ + int status = 0; + wchar_t input_buf[INPUT_SIZ+1]; + + (void) setlocale(LC_ALL, ""); +#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ +#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ +#endif + (void) textdomain(TEXT_DOMAIN); + + while ((flag = getopt(argc, argv, "at:")) != EOF) { + switch (flag) { + case 'a': + all++; + break; + + case 't': /* POSIX.2 */ + all++; /* -t turns on -a */ + getstops(optarg); + break; + + default: + usage(); + break; + } + } + + argc -= optind; + argv = &argv[optind]; + + do { + if (argc > 0) { + if (freopen(argv[0], "r", stdin) == NULL) { + (void) fprintf(stderr, "unexpand: "); + perror(argv[0]); + status++; + } + argc--, argv++; + } + + while (fgetws(input_buf, INPUT_SIZ, stdin) != NULL) { + input_buf[INPUT_SIZ] = 0; + tabify(input_buf, all); + } + } while (argc > 0); + + return (status); + /* NOTREACHED */ +} + +void +tabify(wchar_t *ibuf, int all) +{ + wchar_t *cp; /* current position in ibuf */ + int ocol = 0; /* current output column */ + int cstop = 0; /* current tabstop */ + int spaces = 0; /* spaces to convert to tab */ + int p_col; + + cp = ibuf; + + for (;;) { + switch (*cp) { + case ' ': + cp++; + + spaces++; + ocol++; + + if (nstops == 0) { /* default tab = 8 */ + if ((ocol & 7) != 0) + break; + } else if (nstops == 1) { /* tab width */ + if ((ocol % tabstops[0]) != 0) + break; + } else { /* explicit tabstops */ + while (cstop < nstops && + ocol > tabstops[cstop]) + cstop++; + + if (cstop >= nstops) { + (void) putchar(' '); + spaces = 0; + break; + } + + if (ocol != tabstops[cstop]) + break; + cstop++; + } + + /* + * if we get to this point, we must be at a + * tab stop. if spaces, then write out a tab. + */ + if (spaces > 0) { + (void) putchar(((spaces > 1) ? '\t' : ' ')); + spaces = 0; + } + + break; + + case '\b': /* POSIX.2 */ + while (spaces-- > 0) + (void) putchar(' '); + spaces = 0; + + cp++; + (void) putchar('\b'); + + if (--ocol < 0) + ocol = 0; + + /* just in case */ + cstop = 0; + break; + + case '\t': + cp++; + (void) putchar('\t'); + + /* adjust ocol to current tabstop */ + if (nstops == 0) { + ocol = (ocol + 8) & ~07; + } else if (nstops == 1) { + ocol += ocol % tabstops[0]; + } else { + if (cstop < nstops && + ocol < tabstops[cstop]) + ocol = tabstops[cstop++]; + else + ocol++; + } + + spaces = 0; + break; + + default: + while (spaces-- > 0) + (void) putchar(' '); + spaces = 0; + + if (*cp == 0 || *cp == '\n' || all == 0) { + /* + * either end of input line or -a not set + */ + while (*cp != 0) + (void) putwchar(*cp++); + return; + } + + (void) putwchar(*cp++); + if ((p_col = wcwidth(*cp)) < 0) + p_col = 0; + ocol += p_col; + break; + } + } +} + +static void +getstops(const char *cp) +{ + register int i; + + for (;;) { + i = 0; + while (*cp >= '0' && *cp <= '9') + i = i * 10 + *cp++ - '0'; + + if (i <= 0 || i > INT_MAX) { + (void) fprintf(stderr, gettext( + "unexpand: invalid tablist item\n")); + usage(); + } + + if (nstops > 0 && i <= tabstops[nstops-1]) { + (void) fprintf(stderr, gettext( + "unexpand: tablist must be increasing\n")); + usage(); + } + + if (nstops == MAX_TABS) { + (void) fprintf(stderr, gettext( + "unexpand: number of tabstops limited to %d\n"), + MAX_TABS); + usage(); + } + + tabstops[nstops++] = i; + if (*cp == 0) + break; + if (*cp != ',' && *cp != ' ') { + (void) fprintf(stderr, gettext( + "unexpand: invalid tablist separator\n")); + usage(); + } + + cp++; + } +} + +static void +usage(void) +{ + (void) fprintf(stderr, gettext( + "usage: unexpand [-a ] [-t tablist] [file ...]\n")); + exit(2); + /* NOTREACHED */ +} |
