expand.c revision 1.9
1/* $NetBSD: expand.c,v 1.9 2003/08/07 11:13:39 agc Exp $ */ 2 3/* 4 * Copyright (c) 1980, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> 33#ifndef lint 34__COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\ 35 The Regents of the University of California. All rights reserved.\n"); 36#endif /* not lint */ 37 38#ifndef lint 39#if 0 40static char sccsid[] = "@(#)expand.c 8.1 (Berkeley) 6/9/93"; 41#endif 42__RCSID("$NetBSD: expand.c,v 1.9 2003/08/07 11:13:39 agc Exp $"); 43#endif /* not lint */ 44 45#include <stdio.h> 46#include <stdlib.h> 47#include <ctype.h> 48#include <unistd.h> 49 50/* 51 * expand - expand tabs to equivalent spaces 52 */ 53int nstops; 54int tabstops[100]; 55 56static void getstops __P((char *)); 57 int main __P((int, char **)); 58static void usage __P((void)); 59 60int 61main(argc, argv) 62 int argc; 63 char *argv[]; 64{ 65 int c, column; 66 int n; 67 68 /* handle obsolete syntax */ 69 while (argc > 1 && 70 argv[1][0] == '-' && isdigit((unsigned char)argv[1][1])) { 71 getstops(&argv[1][1]); 72 argc--; argv++; 73 } 74 75 while ((c = getopt (argc, argv, "t:")) != -1) { 76 switch (c) { 77 case 't': 78 getstops(optarg); 79 break; 80 case '?': 81 default: 82 usage(); 83 /* NOTREACHED */ 84 } 85 } 86 argc -= optind; 87 argv += optind; 88 89 do { 90 if (argc > 0) { 91 if (freopen(argv[0], "r", stdin) == NULL) { 92 perror(argv[0]); 93 exit(EXIT_FAILURE); 94 } 95 argc--, argv++; 96 } 97 column = 0; 98 while ((c = getchar()) != EOF) { 99 switch (c) { 100 case '\t': 101 if (nstops == 0) { 102 do { 103 putchar(' '); 104 column++; 105 } while (column & 07); 106 continue; 107 } 108 if (nstops == 1) { 109 do { 110 putchar(' '); 111 column++; 112 } while (((column - 1) % tabstops[0]) != (tabstops[0] - 1)); 113 continue; 114 } 115 for (n = 0; n < nstops; n++) 116 if (tabstops[n] > column) 117 break; 118 if (n == nstops) { 119 putchar(' '); 120 column++; 121 continue; 122 } 123 while (column < tabstops[n]) { 124 putchar(' '); 125 column++; 126 } 127 continue; 128 129 case '\b': 130 if (column) 131 column--; 132 putchar('\b'); 133 continue; 134 135 default: 136 putchar(c); 137 column++; 138 continue; 139 140 case '\n': 141 putchar(c); 142 column = 0; 143 continue; 144 } 145 } 146 } while (argc > 0); 147 exit(EXIT_SUCCESS); 148 /* NOTREACHED */ 149} 150 151static void 152getstops(cp) 153 char *cp; 154{ 155 int i; 156 157 nstops = 0; 158 for (;;) { 159 i = 0; 160 while (*cp >= '0' && *cp <= '9') 161 i = i * 10 + *cp++ - '0'; 162 if (i <= 0 || i > 256) { 163bad: 164 fprintf(stderr, "Bad tab stop spec\n"); 165 exit(EXIT_FAILURE); 166 } 167 if (nstops > 0 && i <= tabstops[nstops-1]) 168 goto bad; 169 tabstops[nstops++] = i; 170 if (*cp == 0) 171 break; 172 if (*cp != ',' && *cp != ' ') 173 goto bad; 174 cp++; 175 } 176} 177 178static void 179usage() 180{ 181 182 (void)fprintf(stderr, "usage: expand [-t tablist] [file ...]\n"); 183 exit(EXIT_FAILURE); 184} 185