main.c revision 1.32
1/* $NetBSD: main.c,v 1.32 2015/03/01 00:38:01 asau Exp $ */ 2 3/*- 4 * Copyright (c) 2013 Johann 'Myrkraverk' Oskarsson. 5 * Copyright (c) 1992 Diomidis Spinellis. 6 * Copyright (c) 1992, 1993 7 * The Regents of the University of California. All rights reserved. 8 * 9 * This code is derived from software contributed to Berkeley by 10 * Diomidis Spinellis of Imperial College, University of London. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#if HAVE_NBTOOL_CONFIG_H 38#include "nbtool_config.h" 39#endif 40 41#include <sys/cdefs.h> 42__RCSID("$NetBSD: main.c,v 1.32 2015/03/01 00:38:01 asau Exp $"); 43#ifdef __FBSDID 44__FBSDID("$FreeBSD: head/usr.bin/sed/main.c 252231 2013-06-26 04:14:19Z pfg $"); 45#endif 46 47#ifndef lint 48__COPYRIGHT("@(#) Copyright (c) 1992, 1993\ 49 The Regents of the University of California. All rights reserved."); 50#endif 51 52#if 0 53static const char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/3/94"; 54#endif 55 56#include <sys/types.h> 57#include <sys/mman.h> 58#include <sys/param.h> 59#include <sys/stat.h> 60 61#include <err.h> 62#include <errno.h> 63#include <fcntl.h> 64#include <limits.h> 65#include <locale.h> 66#include <regex.h> 67#include <stddef.h> 68#define _WITH_GETLINE 69#include <stdio.h> 70#include <stdlib.h> 71#include <string.h> 72#include <unistd.h> 73 74#include "defs.h" 75#include "extern.h" 76 77/* 78 * Linked list pointer to compilation units and pointer to current 79 * next pointer. 80 */ 81struct s_compunit *script; 82static struct s_compunit **cu_nextp = &script; 83 84/* 85 * Linked list pointer to files and pointer to current 86 * next pointer. 87 */ 88struct s_flist *files; 89static struct s_flist **fl_nextp = &files; 90 91int aflag; 92static int eflag; 93int nflag; 94int rflags = 0; 95 96int ispan; /* Whether inplace editing spans across files */ 97const char *inplace; /* Inplace edit file extension. */ 98 99static void add_compunit(enum e_cut, char *); 100static void add_file(char *); 101static void usage(void) __dead; 102 103int 104main(int argc, char *argv[]) 105{ 106 int rval; /* Exit status */ 107 int c, fflag; 108 char *temp_arg; 109 110 setprogname(argv[0]); 111 (void) setlocale(LC_ALL, ""); 112 113 fflag = 0; 114 inplace = NULL; 115 116 while ((c = getopt(argc, argv, "EI::ae:f:i::lnru")) != -1) 117 switch (c) { 118 case 'r': /* Gnu sed compat */ 119 case 'E': 120 rflags = REG_EXTENDED; 121 break; 122 case 'I': 123 inplace = optarg ? optarg : __UNCONST(""); 124 ispan = 1; /* span across input files */ 125 break; 126 case 'a': 127 aflag = 1; 128 break; 129 case 'e': 130 eflag = 1; 131 temp_arg = xmalloc(strlen(optarg) + 2); 132 strcpy(temp_arg, optarg); 133 strcat(temp_arg, "\n"); 134 add_compunit(CU_STRING, temp_arg); 135 break; 136 case 'f': 137 fflag = 1; 138 add_compunit(CU_FILE, optarg); 139 break; 140 case 'i': 141 inplace = optarg ? optarg : __UNCONST(""); 142 ispan = 0; /* don't span across input files */ 143 break; 144 case 'l': 145#ifdef _IOLBF 146 c = setvbuf(stdout, NULL, _IOLBF, 0); 147#else 148 c = setlinebuf(stdout); 149#endif 150 if (c) 151 warn("setting line buffered output failed"); 152 break; 153 case 'n': 154 nflag = 1; 155 break; 156 case 'u': 157#ifdef _IONBF 158 c = setvbuf(stdout, NULL, _IONBF, 0); 159#else 160 c = -1; 161 errno = EOPNOTSUPP; 162#endif 163 if (c) 164 warn("setting unbuffered output failed"); 165 break; 166 default: 167 case '?': 168 usage(); 169 } 170 argc -= optind; 171 argv += optind; 172 173 /* First usage case; script is the first arg */ 174 if (!eflag && !fflag && *argv) { 175 add_compunit(CU_STRING, *argv); 176 argv++; 177 } 178 179 compile(); 180 181 /* Continue with first and start second usage */ 182 if (*argv) 183 for (; *argv; argv++) 184 add_file(*argv); 185 else 186 add_file(NULL); 187 rval = process(); 188 cfclose(prog, NULL); 189 if (fclose(stdout)) 190 err(1, "stdout"); 191 exit(rval); 192} 193 194static void 195usage(void) 196{ 197 (void)fprintf(stderr, 198 "Usage: %s [-aElnru] command [file ...]\n" 199 "\t%s [-aElnru] [-e command] [-f command_file] [-I[extension]]\n" 200 "\t [-i[extension]] [file ...]\n", getprogname(), getprogname()); 201 exit(1); 202} 203 204/* 205 * Add a compilation unit to the linked list 206 */ 207static void 208add_compunit(enum e_cut type, char *s) 209{ 210 struct s_compunit *cu; 211 212 cu = xmalloc(sizeof(struct s_compunit)); 213 cu->type = type; 214 cu->s = s; 215 cu->next = NULL; 216 *cu_nextp = cu; 217 cu_nextp = &cu->next; 218} 219 220/* 221 * Add a file to the linked list 222 */ 223static void 224add_file(char *s) 225{ 226 struct s_flist *fp; 227 228 fp = xmalloc(sizeof(struct s_flist)); 229 fp->next = NULL; 230 *fl_nextp = fp; 231 fp->fname = s; 232 fl_nextp = &fp->next; 233} 234