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