main.c revision 1.31
1/* $NetBSD: main.c,v 1.31 2015/02/28 21:56:53 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.31 2015/02/28 21:56:53 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 91FILE *infile; /* Current input file */ 92FILE *outfile; /* Current output file */ 93 94int aflag; 95static int eflag; 96int nflag; 97int rflags = 0; 98 99int ispan; /* Whether inplace editing spans across files */ 100const char *inplace; /* Inplace edit file extension. */ 101 102static void add_compunit(enum e_cut, char *); 103static void add_file(char *); 104static void usage(void) __dead; 105 106int 107main(int argc, char *argv[]) 108{ 109 int rval; /* Exit status */ 110 int c, fflag; 111 char *temp_arg; 112 113 setprogname(argv[0]); 114 (void) setlocale(LC_ALL, ""); 115 116 fflag = 0; 117 inplace = NULL; 118 119 while ((c = getopt(argc, argv, "EI::ae:f:i::lnru")) != -1) 120 switch (c) { 121 case 'r': /* Gnu sed compat */ 122 case 'E': 123 rflags = REG_EXTENDED; 124 break; 125 case 'I': 126 inplace = optarg ? optarg : __UNCONST(""); 127 ispan = 1; /* span across input files */ 128 break; 129 case 'a': 130 aflag = 1; 131 break; 132 case 'e': 133 eflag = 1; 134 temp_arg = xmalloc(strlen(optarg) + 2); 135 strcpy(temp_arg, optarg); 136 strcat(temp_arg, "\n"); 137 add_compunit(CU_STRING, temp_arg); 138 break; 139 case 'f': 140 fflag = 1; 141 add_compunit(CU_FILE, optarg); 142 break; 143 case 'i': 144 inplace = optarg ? optarg : __UNCONST(""); 145 ispan = 0; /* don't span across input files */ 146 break; 147 case 'l': 148#ifdef _IOLBF 149 c = setvbuf(stdout, NULL, _IOLBF, 0); 150#else 151 c = setlinebuf(stdout); 152#endif 153 if (c) 154 warn("setting line buffered output failed"); 155 break; 156 case 'n': 157 nflag = 1; 158 break; 159 case 'u': 160#ifdef _IONBF 161 c = setvbuf(stdout, NULL, _IONBF, 0); 162#else 163 c = -1; 164 errno = EOPNOTSUPP; 165#endif 166 if (c) 167 warn("setting unbuffered output failed"); 168 break; 169 default: 170 case '?': 171 usage(); 172 } 173 argc -= optind; 174 argv += optind; 175 176 /* First usage case; script is the first arg */ 177 if (!eflag && !fflag && *argv) { 178 add_compunit(CU_STRING, *argv); 179 argv++; 180 } 181 182 compile(); 183 184 /* Continue with first and start second usage */ 185 if (*argv) 186 for (; *argv; argv++) 187 add_file(*argv); 188 else 189 add_file(NULL); 190 rval = process(); 191 cfclose(prog, NULL); 192 if (fclose(stdout)) 193 err(1, "stdout"); 194 exit(rval); 195} 196 197static void 198usage(void) 199{ 200 (void)fprintf(stderr, 201 "Usage: %s [-aElnru] command [file ...]\n" 202 "\t%s [-aElnru] [-e command] [-f command_file] [-I[extension]]\n" 203 "\t [-i[extension]] [file ...]\n", getprogname(), getprogname()); 204 exit(1); 205} 206 207/* 208 * Add a compilation unit to the linked list 209 */ 210static void 211add_compunit(enum e_cut type, char *s) 212{ 213 struct s_compunit *cu; 214 215 cu = xmalloc(sizeof(struct s_compunit)); 216 cu->type = type; 217 cu->s = s; 218 cu->next = NULL; 219 *cu_nextp = cu; 220 cu_nextp = &cu->next; 221} 222 223/* 224 * Add a file to the linked list 225 */ 226static void 227add_file(char *s) 228{ 229 struct s_flist *fp; 230 231 fp = xmalloc(sizeof(struct s_flist)); 232 fp->next = NULL; 233 *fl_nextp = fp; 234 fp->fname = s; 235 fl_nextp = &fp->next; 236} 237