Annotation of src/usr.bin/fold/fold.c, Revision 1.1
1.1 ! deraadt 1: /* $NetBSD: fold.c,v 1.6 1995/09/01 01:42:44 jtc Exp $ */
! 2:
! 3: /*-
! 4: * Copyright (c) 1990, 1993
! 5: * The Regents of the University of California. All rights reserved.
! 6: *
! 7: * This code is derived from software contributed to Berkeley by
! 8: * Kevin Ruddy.
! 9: *
! 10: * Redistribution and use in source and binary forms, with or without
! 11: * modification, are permitted provided that the following conditions
! 12: * are met:
! 13: * 1. Redistributions of source code must retain the above copyright
! 14: * notice, this list of conditions and the following disclaimer.
! 15: * 2. Redistributions in binary form must reproduce the above copyright
! 16: * notice, this list of conditions and the following disclaimer in the
! 17: * documentation and/or other materials provided with the distribution.
! 18: * 3. All advertising materials mentioning features or use of this software
! 19: * must display the following acknowledgement:
! 20: * This product includes software developed by the University of
! 21: * California, Berkeley and its contributors.
! 22: * 4. Neither the name of the University nor the names of its contributors
! 23: * may be used to endorse or promote products derived from this software
! 24: * without specific prior written permission.
! 25: *
! 26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 36: * SUCH DAMAGE.
! 37: */
! 38:
! 39: #ifndef lint
! 40: static char copyright[] =
! 41: "@(#) Copyright (c) 1990, 1993\n\
! 42: The Regents of the University of California. All rights reserved.\n";
! 43: #endif /* not lint */
! 44:
! 45: #ifndef lint
! 46: #if 0
! 47: static char sccsid[] = "@(#)fold.c 8.1 (Berkeley) 6/6/93";
! 48: #endif
! 49: static char rcsid[] = "$NetBSD: fold.c,v 1.6 1995/09/01 01:42:44 jtc Exp $";
! 50: #endif /* not lint */
! 51:
! 52: #include <stdio.h>
! 53: #include <stdlib.h>
! 54: #include <string.h>
! 55: #include <unistd.h>
! 56: #include <err.h>
! 57:
! 58: #define DEFLINEWIDTH 80
! 59:
! 60: static void fold ();
! 61: static int new_column_position ();
! 62: int count_bytes = 0;
! 63: int split_words = 0;
! 64:
! 65: int
! 66: main(argc, argv)
! 67: int argc;
! 68: char **argv;
! 69: {
! 70: register int ch;
! 71: int width;
! 72: char *p;
! 73:
! 74: width = -1;
! 75: while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1)
! 76: switch (ch) {
! 77: case 'b':
! 78: count_bytes = 1;
! 79: break;
! 80: case 's':
! 81: split_words = 1;
! 82: break;
! 83: case 'w':
! 84: if ((width = atoi(optarg)) <= 0) {
! 85: (void)fprintf(stderr,
! 86: "fold: illegal width value.\n");
! 87: exit(1);
! 88: }
! 89: break;
! 90: case '0': case '1': case '2': case '3': case '4':
! 91: case '5': case '6': case '7': case '8': case '9':
! 92: if (width == -1) {
! 93: p = argv[optind - 1];
! 94: if (p[0] == '-' && p[1] == ch && !p[2])
! 95: width = atoi(++p);
! 96: else
! 97: width = atoi(argv[optind] + 1);
! 98: }
! 99: break;
! 100: default:
! 101: (void)fprintf(stderr,
! 102: "usage: fold [-bs] [-w width] [file ...]\n");
! 103: exit(1);
! 104: }
! 105: argv += optind;
! 106: argc -= optind;
! 107:
! 108: if (width == -1)
! 109: width = DEFLINEWIDTH;
! 110:
! 111: if (!*argv)
! 112: fold(width);
! 113: else for (; *argv; ++argv)
! 114: if (!freopen(*argv, "r", stdin)) {
! 115: err (1, "%s", *argv);
! 116: /* NOTREACHED */
! 117: } else
! 118: fold(width);
! 119: exit(0);
! 120: }
! 121:
! 122: /*
! 123: * Fold the contents of standard input to fit within WIDTH columns
! 124: * (or bytes) and write to standard output.
! 125: *
! 126: * If split_words is set, split the line at the last space character
! 127: * on the line. This flag necessitates storing the line in a buffer
! 128: * until the current column > width, or a newline or EOF is read.
! 129: *
! 130: * The buffer can grow larger than WIDTH due to backspaces and carriage
! 131: * returns embedded in the input stream.
! 132: */
! 133: static void
! 134: fold(width)
! 135: register int width;
! 136: {
! 137: static char *buf = NULL;
! 138: static int buf_max = 0;
! 139: register int ch, col;
! 140: register int indx;
! 141:
! 142: col = indx = 0;
! 143: while ((ch = getchar()) != EOF) {
! 144: if (ch == '\n') {
! 145: if (indx != 0)
! 146: fwrite (buf, 1, indx, stdout);
! 147: putchar('\n');
! 148: col = indx = 0;
! 149: continue;
! 150: }
! 151:
! 152: col = new_column_position (col, ch);
! 153: if (col > width) {
! 154: int i, last_space;
! 155:
! 156: if (split_words) {
! 157: for (i = 0, last_space = -1; i < indx; i++)
! 158: if(buf[i] == ' ') last_space = i;
! 159: }
! 160:
! 161: if (split_words && last_space != -1) {
! 162: last_space++;
! 163:
! 164: fwrite (buf, 1, last_space, stdout);
! 165: memmove (buf, buf+last_space, indx-last_space);
! 166:
! 167: indx -= last_space;
! 168: col = 0;
! 169: for (i = 0; i < indx; i++) {
! 170: col = new_column_position (col, ch);
! 171: }
! 172: } else {
! 173: fwrite (buf, 1, indx, stdout);
! 174: col = indx = 0;
! 175: }
! 176: putchar('\n');
! 177:
! 178: /* calculate the column position for the next line. */
! 179: col = new_column_position (col, ch);
! 180: }
! 181:
! 182: if (indx + 1 > buf_max) {
! 183: /* Allocate buffer in LINE_MAX increments */
! 184: buf_max += 2048;
! 185: if((buf = realloc (buf, buf_max)) == NULL) {
! 186: err (1, NULL);
! 187: /* NOTREACHED */
! 188: }
! 189: }
! 190: buf[indx++] = ch;
! 191: }
! 192:
! 193: if (indx != 0)
! 194: fwrite (buf, 1, indx, stdout);
! 195: }
! 196:
! 197: /*
! 198: * calculate the column position
! 199: */
! 200: static int
! 201: new_column_position (col, ch)
! 202: int col;
! 203: int ch;
! 204: {
! 205: if (!count_bytes) {
! 206: switch (ch) {
! 207: case '\b':
! 208: if (col > 0)
! 209: --col;
! 210: break;
! 211: case '\r':
! 212: col = 0;
! 213: break;
! 214: case '\t':
! 215: col = (col + 8) & ~7;
! 216: break;
! 217: default:
! 218: ++col;
! 219: break;
! 220: }
! 221: } else {
! 222: ++col;
! 223: }
! 224:
! 225: return col;
! 226: }