Home | History | Annotate | Line # | Download | only in sed
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
     53 static 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  */
     81 struct s_compunit *script;
     82 static struct s_compunit **cu_nextp = &script;
     83 
     84 /*
     85  * Linked list pointer to files and pointer to current
     86  * next pointer.
     87  */
     88 struct s_flist *files;
     89 static struct s_flist **fl_nextp = &files;
     90 
     91 int aflag;
     92 static int eflag;
     93 int nflag;
     94 int rflags = 0;
     95 
     96 int ispan;			/* Whether inplace editing spans across files */
     97 const char *inplace;		/* Inplace edit file extension. */
     98 
     99 static void add_compunit(enum e_cut, char *);
    100 static void add_file(char *);
    101 static void usage(void) __dead;
    102 
    103 int
    104 main(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 
    194 static void
    195 usage(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  */
    207 static void
    208 add_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  */
    223 static void
    224 add_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