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