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