main.c revision 0eb10989
10eb10989Smrg/* $Xorg: main.c,v 1.5 2001/02/09 02:03:16 xorgcvs Exp $ */
20eb10989Smrg/* $XdotOrg: $ */
30eb10989Smrg/*
40eb10989Smrg
50eb10989SmrgCopyright (c) 1993, 1994, 1998 The Open Group
60eb10989Smrg
70eb10989SmrgPermission to use, copy, modify, distribute, and sell this software and its
80eb10989Smrgdocumentation for any purpose is hereby granted without fee, provided that
90eb10989Smrgthe above copyright notice appear in all copies and that both that
100eb10989Smrgcopyright notice and this permission notice appear in supporting
110eb10989Smrgdocumentation.
120eb10989Smrg
130eb10989SmrgThe above copyright notice and this permission notice shall be included in
140eb10989Smrgall copies or substantial portions of the Software.
150eb10989Smrg
160eb10989SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
170eb10989SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
180eb10989SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
190eb10989SmrgTHE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
200eb10989SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
210eb10989SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
220eb10989Smrg
230eb10989SmrgExcept as contained in this notice, the name of The Open Group shall not be
240eb10989Smrgused in advertising or otherwise to promote the sale, use or other dealings
250eb10989Smrgin this Software without prior written authorization from The Open Group.
260eb10989Smrg
270eb10989Smrg*/
280eb10989Smrg/* $XFree86: xc/config/makedepend/main.c,v 3.31tsi Exp $ */
290eb10989Smrg
300eb10989Smrg#include "def.h"
310eb10989Smrg#ifdef hpux
320eb10989Smrg#define sigvec sigvector
330eb10989Smrg#endif /* hpux */
340eb10989Smrg
350eb10989Smrg#ifdef X_POSIX_C_SOURCE
360eb10989Smrg#define _POSIX_C_SOURCE X_POSIX_C_SOURCE
370eb10989Smrg#include <signal.h>
380eb10989Smrg#undef _POSIX_C_SOURCE
390eb10989Smrg#else
400eb10989Smrg#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
410eb10989Smrg#include <signal.h>
420eb10989Smrg#else
430eb10989Smrg#define _POSIX_SOURCE
440eb10989Smrg#include <signal.h>
450eb10989Smrg#undef _POSIX_SOURCE
460eb10989Smrg#endif
470eb10989Smrg#endif
480eb10989Smrg
490eb10989Smrg#include <stdarg.h>
500eb10989Smrg
510eb10989Smrg#ifdef DEBUG
520eb10989Smrgint	_debugmask;
530eb10989Smrg#endif
540eb10989Smrg
550eb10989Smrg/* #define DEBUG_DUMP */
560eb10989Smrg#ifdef DEBUG_DUMP
570eb10989Smrg#define DBG_PRINT(file, fmt, args)   fprintf(file, fmt, args)
580eb10989Smrg#else
590eb10989Smrg#define DBG_PRINT(file, fmt, args)   /* empty */
600eb10989Smrg#endif
610eb10989Smrg
620eb10989Smrg#define DASH_INC_PRE    "#include \""
630eb10989Smrg#define DASH_INC_POST   "\""
640eb10989Smrg
650eb10989Smrgchar *ProgramName;
660eb10989Smrg
670eb10989Smrgchar	*directives[] = {
680eb10989Smrg	"if",
690eb10989Smrg	"ifdef",
700eb10989Smrg	"ifndef",
710eb10989Smrg	"else",
720eb10989Smrg	"endif",
730eb10989Smrg	"define",
740eb10989Smrg	"undef",
750eb10989Smrg	"include",
760eb10989Smrg	"line",
770eb10989Smrg	"pragma",
780eb10989Smrg	"error",
790eb10989Smrg	"ident",
800eb10989Smrg	"sccs",
810eb10989Smrg	"elif",
820eb10989Smrg	"eject",
830eb10989Smrg	"warning",
840eb10989Smrg	"include_next",
850eb10989Smrg	NULL
860eb10989Smrg};
870eb10989Smrg
880eb10989Smrg#define MAKEDEPEND
890eb10989Smrg#include "imakemdep.h"	/* from config sources */
900eb10989Smrg#undef MAKEDEPEND
910eb10989Smrg
920eb10989Smrgstruct	inclist inclist[ MAXFILES ],
930eb10989Smrg		*inclistp = inclist,
940eb10989Smrg		*inclistnext = inclist,
950eb10989Smrg		maininclist;
960eb10989Smrg
970eb10989Smrgstatic char	*filelist[ MAXFILES ];
980eb10989Smrgchar		*includedirs[ MAXDIRS + 1 ],
990eb10989Smrg		**includedirsnext = includedirs;
1000eb10989Smrgchar		*notdotdot[ MAXDIRS ];
1010eb10989Smrgstatic int	cmdinc_count = 0;
1020eb10989Smrgstatic char	*cmdinc_list[ 2 * MAXINCFILES ];
1030eb10989Smrgchar		*objprefix = "";
1040eb10989Smrgchar		*objsuffix = OBJSUFFIX;
1050eb10989Smrgstatic char	*startat = "# DO NOT DELETE";
1060eb10989Smrgint		width = 78;
1070eb10989Smrgstatic boolean	append = FALSE;
1080eb10989Smrgboolean		printed = FALSE;
1090eb10989Smrgboolean		verbose = FALSE;
1100eb10989Smrgboolean		show_where_not = FALSE;
1110eb10989Smrg/* Warn on multiple includes of same file */
1120eb10989Smrgboolean 	warn_multiple = FALSE;
1130eb10989Smrg
1140eb10989Smrgstatic void setfile_cmdinc(struct filepointer *filep, long count, char **list);
1150eb10989Smrgstatic void redirect(char *line, char *makefile);
1160eb10989Smrg
1170eb10989Smrgstatic
1180eb10989Smrg#ifdef RETSIGTYPE
1190eb10989SmrgRETSIGTYPE
1200eb10989Smrg#else
1210eb10989Smrg# ifdef SIGNALRETURNSINT
1220eb10989Smrgint
1230eb10989Smrg# else
1240eb10989Smrgvoid
1250eb10989Smrg# endif
1260eb10989Smrg#endif
1270eb10989Smrgcatch (int sig)
1280eb10989Smrg{
1290eb10989Smrg	fflush (stdout);
1300eb10989Smrg	fatalerr ("got signal %d\n", sig);
1310eb10989Smrg}
1320eb10989Smrg
1330eb10989Smrg#if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(__UNIXOS2__) || defined(Lynx_22) || defined(__CYGWIN__)
1340eb10989Smrg#define USGISH
1350eb10989Smrg#endif
1360eb10989Smrg
1370eb10989Smrg#ifndef USGISH
1380eb10989Smrg#ifdef X_NOT_POSIX
1390eb10989Smrg#define sigaction sigvec
1400eb10989Smrg#define sa_handler sv_handler
1410eb10989Smrg#define sa_mask sv_mask
1420eb10989Smrg#define sa_flags sv_flags
1430eb10989Smrg#endif
1440eb10989Smrgstruct sigaction sig_act;
1450eb10989Smrg#endif /* USGISH */
1460eb10989Smrg
1470eb10989Smrg#ifndef USING_AUTOCONF
1480eb10989Smrg# if !defined(USGISH) && !defined(_SEQUENT_) && !defined(MINIX)
1490eb10989Smrg#  define HAVE_FCHMOD	1
1500eb10989Smrg# endif
1510eb10989Smrg#endif
1520eb10989Smrg
1530eb10989Smrgint
1540eb10989Smrgmain(int argc, char *argv[])
1550eb10989Smrg{
1560eb10989Smrg	char	**fp = filelist;
1570eb10989Smrg	char	**incp = includedirs;
1580eb10989Smrg	char	*p;
1590eb10989Smrg	struct inclist	*ip;
1600eb10989Smrg	char	*makefile = NULL;
1610eb10989Smrg	struct filepointer	*filecontent;
1620eb10989Smrg	struct symtab *psymp = predefs;
1630eb10989Smrg	char *endmarker = NULL;
1640eb10989Smrg	char *defincdir = NULL;
1650eb10989Smrg	char **undeflist = NULL;
1660eb10989Smrg	int numundefs = 0, i;
1670eb10989Smrg
1680eb10989Smrg	ProgramName = argv[0];
1690eb10989Smrg
1700eb10989Smrg	while (psymp->s_name)
1710eb10989Smrg	{
1720eb10989Smrg	    define2(psymp->s_name, psymp->s_value, &maininclist);
1730eb10989Smrg	    psymp++;
1740eb10989Smrg	}
1750eb10989Smrg	if (argc == 2 && argv[1][0] == '@') {
1760eb10989Smrg	    struct stat ast;
1770eb10989Smrg	    int afd;
1780eb10989Smrg	    char *args;
1790eb10989Smrg	    char **nargv;
1800eb10989Smrg	    int nargc;
1810eb10989Smrg	    char quotechar = '\0';
1820eb10989Smrg
1830eb10989Smrg	    nargc = 1;
1840eb10989Smrg	    if ((afd = open(argv[1]+1, O_RDONLY)) < 0)
1850eb10989Smrg		fatalerr("cannot open \"%s\"\n", argv[1]+1);
1860eb10989Smrg	    fstat(afd, &ast);
1870eb10989Smrg	    args = (char *)malloc(ast.st_size + 1);
1880eb10989Smrg	    if ((ast.st_size = read(afd, args, ast.st_size)) < 0)
1890eb10989Smrg		fatalerr("failed to read %s\n", argv[1]+1);
1900eb10989Smrg	    args[ast.st_size] = '\0';
1910eb10989Smrg	    close(afd);
1920eb10989Smrg	    for (p = args; *p; p++) {
1930eb10989Smrg		if (quotechar) {
1940eb10989Smrg		    if (quotechar == '\\' ||
1950eb10989Smrg			(*p == quotechar && p[-1] != '\\'))
1960eb10989Smrg			quotechar = '\0';
1970eb10989Smrg		    continue;
1980eb10989Smrg		}
1990eb10989Smrg		switch (*p) {
2000eb10989Smrg		case '\\':
2010eb10989Smrg		case '"':
2020eb10989Smrg		case '\'':
2030eb10989Smrg		    quotechar = *p;
2040eb10989Smrg		    break;
2050eb10989Smrg		case ' ':
2060eb10989Smrg		case '\n':
2070eb10989Smrg		    *p = '\0';
2080eb10989Smrg		    if (p > args && p[-1])
2090eb10989Smrg			nargc++;
2100eb10989Smrg		    break;
2110eb10989Smrg		}
2120eb10989Smrg	    }
2130eb10989Smrg	    if (p[-1])
2140eb10989Smrg		nargc++;
2150eb10989Smrg	    nargv = (char **)malloc(nargc * sizeof(char *));
2160eb10989Smrg	    nargv[0] = argv[0];
2170eb10989Smrg	    argc = 1;
2180eb10989Smrg	    for (p = args; argc < nargc; p += strlen(p) + 1)
2190eb10989Smrg		if (*p) nargv[argc++] = p;
2200eb10989Smrg	    argv = nargv;
2210eb10989Smrg	}
2220eb10989Smrg	for(argc--, argv++; argc; argc--, argv++) {
2230eb10989Smrg	    	/* if looking for endmarker then check before parsing */
2240eb10989Smrg		if (endmarker && strcmp (endmarker, *argv) == 0) {
2250eb10989Smrg		    endmarker = NULL;
2260eb10989Smrg		    continue;
2270eb10989Smrg		}
2280eb10989Smrg		if (**argv != '-') {
2290eb10989Smrg			/* treat +thing as an option for C++ */
2300eb10989Smrg			if (endmarker && **argv == '+')
2310eb10989Smrg				continue;
2320eb10989Smrg			*fp++ = argv[0];
2330eb10989Smrg			continue;
2340eb10989Smrg		}
2350eb10989Smrg		switch(argv[0][1]) {
2360eb10989Smrg		case '-':
2370eb10989Smrg			endmarker = &argv[0][2];
2380eb10989Smrg			if (endmarker[0] == '\0') endmarker = "--";
2390eb10989Smrg			break;
2400eb10989Smrg		case 'D':
2410eb10989Smrg			if (argv[0][2] == '\0') {
2420eb10989Smrg				argv++;
2430eb10989Smrg				argc--;
2440eb10989Smrg			}
2450eb10989Smrg			for (p=argv[0] + 2; *p ; p++)
2460eb10989Smrg				if (*p == '=') {
2470eb10989Smrg					*p = ' ';
2480eb10989Smrg					break;
2490eb10989Smrg				}
2500eb10989Smrg			define(argv[0] + 2, &maininclist);
2510eb10989Smrg			break;
2520eb10989Smrg		case 'I':
2530eb10989Smrg			if (incp >= includedirs + MAXDIRS)
2540eb10989Smrg			    fatalerr("Too many -I flags.\n");
2550eb10989Smrg			*incp++ = argv[0]+2;
2560eb10989Smrg			if (**(incp-1) == '\0') {
2570eb10989Smrg				*(incp-1) = *(++argv);
2580eb10989Smrg				argc--;
2590eb10989Smrg			}
2600eb10989Smrg			break;
2610eb10989Smrg		case 'U':
2620eb10989Smrg			/* Undef's override all -D's so save them up */
2630eb10989Smrg			numundefs++;
2640eb10989Smrg			if (numundefs == 1)
2650eb10989Smrg			    undeflist = malloc(sizeof(char *));
2660eb10989Smrg			else
2670eb10989Smrg			    undeflist = realloc(undeflist,
2680eb10989Smrg						numundefs * sizeof(char *));
2690eb10989Smrg			if (argv[0][2] == '\0') {
2700eb10989Smrg				argv++;
2710eb10989Smrg				argc--;
2720eb10989Smrg			}
2730eb10989Smrg			undeflist[numundefs - 1] = argv[0] + 2;
2740eb10989Smrg			break;
2750eb10989Smrg		case 'Y':
2760eb10989Smrg			defincdir = argv[0]+2;
2770eb10989Smrg			break;
2780eb10989Smrg		/* do not use if endmarker processing */
2790eb10989Smrg		case 'a':
2800eb10989Smrg			if (endmarker) break;
2810eb10989Smrg			append = TRUE;
2820eb10989Smrg			break;
2830eb10989Smrg		case 'w':
2840eb10989Smrg			if (endmarker) break;
2850eb10989Smrg			if (argv[0][2] == '\0') {
2860eb10989Smrg				argv++;
2870eb10989Smrg				argc--;
2880eb10989Smrg				width = atoi(argv[0]);
2890eb10989Smrg			} else
2900eb10989Smrg				width = atoi(argv[0]+2);
2910eb10989Smrg			break;
2920eb10989Smrg		case 'o':
2930eb10989Smrg			if (endmarker) break;
2940eb10989Smrg			if (argv[0][2] == '\0') {
2950eb10989Smrg				argv++;
2960eb10989Smrg				argc--;
2970eb10989Smrg				objsuffix = argv[0];
2980eb10989Smrg			} else
2990eb10989Smrg				objsuffix = argv[0]+2;
3000eb10989Smrg			break;
3010eb10989Smrg		case 'p':
3020eb10989Smrg			if (endmarker) break;
3030eb10989Smrg			if (argv[0][2] == '\0') {
3040eb10989Smrg				argv++;
3050eb10989Smrg				argc--;
3060eb10989Smrg				objprefix = argv[0];
3070eb10989Smrg			} else
3080eb10989Smrg				objprefix = argv[0]+2;
3090eb10989Smrg			break;
3100eb10989Smrg		case 'v':
3110eb10989Smrg			if (endmarker) break;
3120eb10989Smrg			verbose = TRUE;
3130eb10989Smrg#ifdef DEBUG
3140eb10989Smrg			if (argv[0][2])
3150eb10989Smrg				_debugmask = atoi(argv[0]+2);
3160eb10989Smrg#endif
3170eb10989Smrg			break;
3180eb10989Smrg		case 's':
3190eb10989Smrg			if (endmarker) break;
3200eb10989Smrg			startat = argv[0]+2;
3210eb10989Smrg			if (*startat == '\0') {
3220eb10989Smrg				startat = *(++argv);
3230eb10989Smrg				argc--;
3240eb10989Smrg			}
3250eb10989Smrg			if (*startat != '#')
3260eb10989Smrg				fatalerr("-s flag's value should start %s\n",
3270eb10989Smrg					"with '#'.");
3280eb10989Smrg			break;
3290eb10989Smrg		case 'f':
3300eb10989Smrg			if (endmarker) break;
3310eb10989Smrg			makefile = argv[0]+2;
3320eb10989Smrg			if (*makefile == '\0') {
3330eb10989Smrg				makefile = *(++argv);
3340eb10989Smrg				argc--;
3350eb10989Smrg			}
3360eb10989Smrg			break;
3370eb10989Smrg
3380eb10989Smrg		case 'm':
3390eb10989Smrg			warn_multiple = TRUE;
3400eb10989Smrg			break;
3410eb10989Smrg
3420eb10989Smrg		/* Ignore -O, -g so we can just pass ${CFLAGS} to
3430eb10989Smrg		   makedepend
3440eb10989Smrg		 */
3450eb10989Smrg		case 'O':
3460eb10989Smrg		case 'g':
3470eb10989Smrg			break;
3480eb10989Smrg		case 'i':
3490eb10989Smrg			if (strcmp(&argv[0][1],"include") == 0) {
3500eb10989Smrg				char *buf;
3510eb10989Smrg				if (argc<2)
3520eb10989Smrg					fatalerr("option -include is a "
3530eb10989Smrg						 "missing its parameter\n");
3540eb10989Smrg				if (cmdinc_count >= MAXINCFILES)
3550eb10989Smrg					fatalerr("Too many -include flags.\n");
3560eb10989Smrg				argc--;
3570eb10989Smrg				argv++;
3580eb10989Smrg				buf = malloc(strlen(DASH_INC_PRE) +
3590eb10989Smrg					     strlen(argv[0]) +
3600eb10989Smrg					     strlen(DASH_INC_POST) + 1);
3610eb10989Smrg                		if(!buf)
3620eb10989Smrg					fatalerr("out of memory at "
3630eb10989Smrg						 "-include string\n");
3640eb10989Smrg				cmdinc_list[2 * cmdinc_count + 0] = argv[0];
3650eb10989Smrg				cmdinc_list[2 * cmdinc_count + 1] = buf;
3660eb10989Smrg				cmdinc_count++;
3670eb10989Smrg				break;
3680eb10989Smrg			}
3690eb10989Smrg			/* intentional fall through */
3700eb10989Smrg		default:
3710eb10989Smrg			if (endmarker) break;
3720eb10989Smrg	/*		fatalerr("unknown opt = %s\n", argv[0]); */
3730eb10989Smrg			warning("ignoring option %s\n", argv[0]);
3740eb10989Smrg		}
3750eb10989Smrg	}
3760eb10989Smrg	/* Now do the undefs from the command line */
3770eb10989Smrg	for (i = 0; i < numundefs; i++)
3780eb10989Smrg	    undefine(undeflist[i], &maininclist);
3790eb10989Smrg	if (numundefs > 0)
3800eb10989Smrg	    free(undeflist);
3810eb10989Smrg
3820eb10989Smrg	if (!defincdir) {
3830eb10989Smrg#ifdef PREINCDIR
3840eb10989Smrg	    if (incp >= includedirs + MAXDIRS)
3850eb10989Smrg		fatalerr("Too many -I flags.\n");
3860eb10989Smrg	    *incp++ = PREINCDIR;
3870eb10989Smrg#endif
3880eb10989Smrg#ifdef __UNIXOS2__
3890eb10989Smrg	    {
3900eb10989Smrg		char *emxinc = getenv("C_INCLUDE_PATH");
3910eb10989Smrg		/* can have more than one component */
3920eb10989Smrg		if (emxinc) {
3930eb10989Smrg		    char *beg, *end;
3940eb10989Smrg		    beg= (char*)strdup(emxinc);
3950eb10989Smrg		    for (;;) {
3960eb10989Smrg			end = (char*)strchr(beg,';');
3970eb10989Smrg			if (end) *end = 0;
3980eb10989Smrg		    	if (incp >= includedirs + MAXDIRS)
3990eb10989Smrg				fatalerr("Too many include dirs\n");
4000eb10989Smrg			*incp++ = beg;
4010eb10989Smrg			if (!end) break;
4020eb10989Smrg			beg = end+1;
4030eb10989Smrg		    }
4040eb10989Smrg		}
4050eb10989Smrg	    }
4060eb10989Smrg#else /* !__UNIXOS2__, does not use INCLUDEDIR at all */
4070eb10989Smrg	    if (incp >= includedirs + MAXDIRS)
4080eb10989Smrg		fatalerr("Too many -I flags.\n");
4090eb10989Smrg	    *incp++ = INCLUDEDIR;
4100eb10989Smrg#endif
4110eb10989Smrg
4120eb10989Smrg#ifdef EXTRAINCDIR
4130eb10989Smrg	    if (incp >= includedirs + MAXDIRS)
4140eb10989Smrg		fatalerr("Too many -I flags.\n");
4150eb10989Smrg	    *incp++ = EXTRAINCDIR;
4160eb10989Smrg#endif
4170eb10989Smrg
4180eb10989Smrg#ifdef POSTINCDIR
4190eb10989Smrg	    if (incp >= includedirs + MAXDIRS)
4200eb10989Smrg		fatalerr("Too many -I flags.\n");
4210eb10989Smrg	    *incp++ = POSTINCDIR;
4220eb10989Smrg#endif
4230eb10989Smrg	} else if (*defincdir) {
4240eb10989Smrg	    if (incp >= includedirs + MAXDIRS)
4250eb10989Smrg		fatalerr("Too many -I flags.\n");
4260eb10989Smrg	    *incp++ = defincdir;
4270eb10989Smrg	}
4280eb10989Smrg
4290eb10989Smrg	redirect(startat, makefile);
4300eb10989Smrg
4310eb10989Smrg	/*
4320eb10989Smrg	 * catch signals.
4330eb10989Smrg	 */
4340eb10989Smrg#ifdef USGISH
4350eb10989Smrg/*  should really reset SIGINT to SIG_IGN if it was.  */
4360eb10989Smrg#ifdef SIGHUP
4370eb10989Smrg	signal (SIGHUP, catch);
4380eb10989Smrg#endif
4390eb10989Smrg	signal (SIGINT, catch);
4400eb10989Smrg#ifdef SIGQUIT
4410eb10989Smrg	signal (SIGQUIT, catch);
4420eb10989Smrg#endif
4430eb10989Smrg	signal (SIGILL, catch);
4440eb10989Smrg#ifdef SIGBUS
4450eb10989Smrg	signal (SIGBUS, catch);
4460eb10989Smrg#endif
4470eb10989Smrg	signal (SIGSEGV, catch);
4480eb10989Smrg#ifdef SIGSYS
4490eb10989Smrg	signal (SIGSYS, catch);
4500eb10989Smrg#endif
4510eb10989Smrg#else
4520eb10989Smrg	sig_act.sa_handler = catch;
4530eb10989Smrg#if defined(_POSIX_SOURCE) || !defined(X_NOT_POSIX)
4540eb10989Smrg	sigemptyset(&sig_act.sa_mask);
4550eb10989Smrg	sigaddset(&sig_act.sa_mask, SIGINT);
4560eb10989Smrg	sigaddset(&sig_act.sa_mask, SIGQUIT);
4570eb10989Smrg#ifdef SIGBUS
4580eb10989Smrg	sigaddset(&sig_act.sa_mask, SIGBUS);
4590eb10989Smrg#endif
4600eb10989Smrg	sigaddset(&sig_act.sa_mask, SIGILL);
4610eb10989Smrg	sigaddset(&sig_act.sa_mask, SIGSEGV);
4620eb10989Smrg	sigaddset(&sig_act.sa_mask, SIGHUP);
4630eb10989Smrg	sigaddset(&sig_act.sa_mask, SIGPIPE);
4640eb10989Smrg#ifdef SIGSYS
4650eb10989Smrg	sigaddset(&sig_act.sa_mask, SIGSYS);
4660eb10989Smrg#endif
4670eb10989Smrg#else
4680eb10989Smrg	sig_act.sa_mask = ((1<<(SIGINT -1))
4690eb10989Smrg			   |(1<<(SIGQUIT-1))
4700eb10989Smrg#ifdef SIGBUS
4710eb10989Smrg			   |(1<<(SIGBUS-1))
4720eb10989Smrg#endif
4730eb10989Smrg			   |(1<<(SIGILL-1))
4740eb10989Smrg			   |(1<<(SIGSEGV-1))
4750eb10989Smrg			   |(1<<(SIGHUP-1))
4760eb10989Smrg			   |(1<<(SIGPIPE-1))
4770eb10989Smrg#ifdef SIGSYS
4780eb10989Smrg			   |(1<<(SIGSYS-1))
4790eb10989Smrg#endif
4800eb10989Smrg			   );
4810eb10989Smrg#endif /* _POSIX_SOURCE */
4820eb10989Smrg	sig_act.sa_flags = 0;
4830eb10989Smrg	sigaction(SIGHUP, &sig_act, (struct sigaction *)0);
4840eb10989Smrg	sigaction(SIGINT, &sig_act, (struct sigaction *)0);
4850eb10989Smrg	sigaction(SIGQUIT, &sig_act, (struct sigaction *)0);
4860eb10989Smrg	sigaction(SIGILL, &sig_act, (struct sigaction *)0);
4870eb10989Smrg#ifdef SIGBUS
4880eb10989Smrg	sigaction(SIGBUS, &sig_act, (struct sigaction *)0);
4890eb10989Smrg#endif
4900eb10989Smrg	sigaction(SIGSEGV, &sig_act, (struct sigaction *)0);
4910eb10989Smrg#ifdef SIGSYS
4920eb10989Smrg	sigaction(SIGSYS, &sig_act, (struct sigaction *)0);
4930eb10989Smrg#endif
4940eb10989Smrg#endif /* USGISH */
4950eb10989Smrg
4960eb10989Smrg	/*
4970eb10989Smrg	 * now peruse through the list of files.
4980eb10989Smrg	 */
4990eb10989Smrg	for(fp=filelist; *fp; fp++) {
5000eb10989Smrg		DBG_PRINT(stderr,"file: %s\n",*fp);
5010eb10989Smrg		filecontent = getfile(*fp);
5020eb10989Smrg		setfile_cmdinc(filecontent, cmdinc_count, cmdinc_list);
5030eb10989Smrg		ip = newinclude(*fp, (char *)NULL);
5040eb10989Smrg
5050eb10989Smrg		find_includes(filecontent, ip, ip, 0, FALSE);
5060eb10989Smrg		freefile(filecontent);
5070eb10989Smrg		recursive_pr_include(ip, ip->i_file, base_name(*fp));
5080eb10989Smrg		inc_clean();
5090eb10989Smrg	}
5100eb10989Smrg	if (printed)
5110eb10989Smrg		printf("\n");
5120eb10989Smrg	return 0;
5130eb10989Smrg}
5140eb10989Smrg
5150eb10989Smrg#ifdef __UNIXOS2__
5160eb10989Smrg/*
5170eb10989Smrg * eliminate \r chars from file
5180eb10989Smrg */
5190eb10989Smrgstatic int
5200eb10989Smrgelim_cr(char *buf, int sz)
5210eb10989Smrg{
5220eb10989Smrg	int i,wp;
5230eb10989Smrg	for (i= wp = 0; i<sz; i++) {
5240eb10989Smrg		if (buf[i] != '\r')
5250eb10989Smrg			buf[wp++] = buf[i];
5260eb10989Smrg	}
5270eb10989Smrg	return wp;
5280eb10989Smrg}
5290eb10989Smrg#endif
5300eb10989Smrg
5310eb10989Smrgstruct filepointer *
5320eb10989Smrggetfile(char *file)
5330eb10989Smrg{
5340eb10989Smrg	int	fd;
5350eb10989Smrg	struct filepointer	*content;
5360eb10989Smrg	struct stat	st;
5370eb10989Smrg
5380eb10989Smrg	content = (struct filepointer *)malloc(sizeof(struct filepointer));
5390eb10989Smrg	content->f_name = file;
5400eb10989Smrg	if ((fd = open(file, O_RDONLY)) < 0) {
5410eb10989Smrg		warning("cannot open \"%s\"\n", file);
5420eb10989Smrg		content->f_p = content->f_base = content->f_end = (char *)malloc(1);
5430eb10989Smrg		*content->f_p = '\0';
5440eb10989Smrg		return(content);
5450eb10989Smrg	}
5460eb10989Smrg	fstat(fd, &st);
5470eb10989Smrg	content->f_base = (char *)malloc(st.st_size+1);
5480eb10989Smrg	if (content->f_base == NULL)
5490eb10989Smrg		fatalerr("cannot allocate mem\n");
5500eb10989Smrg	if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0)
5510eb10989Smrg		fatalerr("failed to read %s\n", file);
5520eb10989Smrg#ifdef __UNIXOS2__
5530eb10989Smrg	st.st_size = elim_cr(content->f_base,st.st_size);
5540eb10989Smrg#endif
5550eb10989Smrg	close(fd);
5560eb10989Smrg	content->f_len = st.st_size+1;
5570eb10989Smrg	content->f_p = content->f_base;
5580eb10989Smrg	content->f_end = content->f_base + st.st_size;
5590eb10989Smrg	*content->f_end = '\0';
5600eb10989Smrg	content->f_line = 0;
5610eb10989Smrg	content->cmdinc_count = 0;
5620eb10989Smrg	content->cmdinc_list = NULL;
5630eb10989Smrg	content->cmdinc_line = 0;
5640eb10989Smrg	return(content);
5650eb10989Smrg}
5660eb10989Smrg
5670eb10989Smrgvoid
5680eb10989Smrgsetfile_cmdinc(struct filepointer* filep, long count, char** list)
5690eb10989Smrg{
5700eb10989Smrg	filep->cmdinc_count = count;
5710eb10989Smrg	filep->cmdinc_list = list;
5720eb10989Smrg	filep->cmdinc_line = 0;
5730eb10989Smrg}
5740eb10989Smrg
5750eb10989Smrgvoid
5760eb10989Smrgfreefile(struct filepointer *fp)
5770eb10989Smrg{
5780eb10989Smrg	free(fp->f_base);
5790eb10989Smrg	free(fp);
5800eb10989Smrg}
5810eb10989Smrg
5820eb10989Smrgchar *copy(char *str)
5830eb10989Smrg{
5840eb10989Smrg	char	*p = (char *)malloc(strlen(str) + 1);
5850eb10989Smrg
5860eb10989Smrg	strcpy(p, str);
5870eb10989Smrg	return(p);
5880eb10989Smrg}
5890eb10989Smrg
5900eb10989Smrgint
5910eb10989Smrgmatch(char *str, char **list)
5920eb10989Smrg{
5930eb10989Smrg	int	i;
5940eb10989Smrg
5950eb10989Smrg	for (i=0; *list; i++, list++)
5960eb10989Smrg		if (strcmp(str, *list) == 0)
5970eb10989Smrg			return(i);
5980eb10989Smrg	return(-1);
5990eb10989Smrg}
6000eb10989Smrg
6010eb10989Smrg/*
6020eb10989Smrg * Get the next line.  We only return lines beginning with '#' since that
6030eb10989Smrg * is all this program is ever interested in.
6040eb10989Smrg */
6050eb10989Smrgchar *getnextline(struct filepointer *filep)
6060eb10989Smrg{
6070eb10989Smrg	char	*p,	/* walking pointer */
6080eb10989Smrg		*eof,	/* end of file pointer */
6090eb10989Smrg		*bol;	/* beginning of line pointer */
6100eb10989Smrg	int	lineno;	/* line number */
6110eb10989Smrg	boolean whitespace = FALSE;
6120eb10989Smrg
6130eb10989Smrg	/*
6140eb10989Smrg	 * Fake the "-include" line files in form of #include to the
6150eb10989Smrg	 * start of each file.
6160eb10989Smrg	 */
6170eb10989Smrg	if (filep->cmdinc_line < filep->cmdinc_count) {
6180eb10989Smrg		char *inc = filep->cmdinc_list[2 * filep->cmdinc_line + 0];
6190eb10989Smrg		char *buf = filep->cmdinc_list[2 * filep->cmdinc_line + 1];
6200eb10989Smrg		filep->cmdinc_line++;
6210eb10989Smrg		sprintf(buf,"%s%s%s",DASH_INC_PRE,inc,DASH_INC_POST);
6220eb10989Smrg		DBG_PRINT(stderr,"%s\n",buf);
6230eb10989Smrg		return(buf);
6240eb10989Smrg	}
6250eb10989Smrg
6260eb10989Smrg	p = filep->f_p;
6270eb10989Smrg	eof = filep->f_end;
6280eb10989Smrg	if (p >= eof)
6290eb10989Smrg		return((char *)NULL);
6300eb10989Smrg	lineno = filep->f_line;
6310eb10989Smrg
6320eb10989Smrg	for (bol = p--; ++p < eof; ) {
6330eb10989Smrg		if ((bol == p) && ((*p == ' ') || (*p == '\t')))
6340eb10989Smrg		{
6350eb10989Smrg			/* Consume leading white-spaces for this line */
6360eb10989Smrg			while (((p+1) < eof) && ((*p == ' ') || (*p == '\t')))
6370eb10989Smrg			{
6380eb10989Smrg				p++;
6390eb10989Smrg				bol++;
6400eb10989Smrg			}
6410eb10989Smrg			whitespace = TRUE;
6420eb10989Smrg		}
6430eb10989Smrg
6440eb10989Smrg		if (*p == '/' && (p+1) < eof && *(p+1) == '*') {
6450eb10989Smrg			/* Consume C comments */
6460eb10989Smrg			*(p++) = ' ';
6470eb10989Smrg			*(p++) = ' ';
6480eb10989Smrg			while (p < eof && *p) {
6490eb10989Smrg				if (*p == '*' && (p+1) < eof && *(p+1) == '/') {
6500eb10989Smrg					*(p++) = ' ';
6510eb10989Smrg					*(p++) = ' ';
6520eb10989Smrg					break;
6530eb10989Smrg				}
6540eb10989Smrg				if (*p == '\n')
6550eb10989Smrg					lineno++;
6560eb10989Smrg				*(p++) = ' ';
6570eb10989Smrg			}
6580eb10989Smrg			--p;
6590eb10989Smrg		}
6600eb10989Smrg		else if (*p == '/' && (p+1) < eof && *(p+1) == '/') {
6610eb10989Smrg			/* Consume C++ comments */
6620eb10989Smrg			*(p++) = ' ';
6630eb10989Smrg			*(p++) = ' ';
6640eb10989Smrg			while (p < eof && *p) {
6650eb10989Smrg				if (*p == '\\' && (p+1) < eof &&
6660eb10989Smrg				    *(p+1) == '\n') {
6670eb10989Smrg					*(p++) = ' ';
6680eb10989Smrg					lineno++;
6690eb10989Smrg				}
6700eb10989Smrg				else if (*p == '?' && (p+3) < eof &&
6710eb10989Smrg					 *(p+1) == '?' &&
6720eb10989Smrg					 *(p+2) == '/' &&
6730eb10989Smrg					 *(p+3) == '\n') {
6740eb10989Smrg					*(p++) = ' ';
6750eb10989Smrg					*(p++) = ' ';
6760eb10989Smrg					*(p++) = ' ';
6770eb10989Smrg					lineno++;
6780eb10989Smrg				}
6790eb10989Smrg				else if (*p == '\n')
6800eb10989Smrg					break;	/* to process end of line */
6810eb10989Smrg				*(p++) = ' ';
6820eb10989Smrg			}
6830eb10989Smrg			--p;
6840eb10989Smrg		}
6850eb10989Smrg		else if (*p == '\\' && (p+1) < eof && *(p+1) == '\n') {
6860eb10989Smrg			/* Consume backslash line terminations */
6870eb10989Smrg			*(p++) = ' ';
6880eb10989Smrg			*p = ' ';
6890eb10989Smrg			lineno++;
6900eb10989Smrg		}
6910eb10989Smrg		else if (*p == '?' && (p+3) < eof &&
6920eb10989Smrg			 *(p+1) == '?' && *(p+2) == '/' && *(p+3) == '\n') {
6930eb10989Smrg			/* Consume trigraph'ed backslash line terminations */
6940eb10989Smrg			*(p++) = ' ';
6950eb10989Smrg			*(p++) = ' ';
6960eb10989Smrg			*(p++) = ' ';
6970eb10989Smrg			*p = ' ';
6980eb10989Smrg			lineno++;
6990eb10989Smrg		}
7000eb10989Smrg		else if (*p == '\n') {
7010eb10989Smrg			lineno++;
7020eb10989Smrg			if (*bol == '#') {
7030eb10989Smrg				char *cp;
7040eb10989Smrg
7050eb10989Smrg				*(p++) = '\0';
7060eb10989Smrg				/* punt lines with just # (yacc generated) */
7070eb10989Smrg				for (cp = bol+1;
7080eb10989Smrg				     *cp && (*cp == ' ' || *cp == '\t'); cp++);
7090eb10989Smrg				if (*cp) goto done;
7100eb10989Smrg				--p;
7110eb10989Smrg			}
7120eb10989Smrg			bol = p+1;
7130eb10989Smrg			whitespace = FALSE;
7140eb10989Smrg		}
7150eb10989Smrg	}
7160eb10989Smrg	if (*bol != '#')
7170eb10989Smrg		bol = NULL;
7180eb10989Smrgdone:
7190eb10989Smrg	filep->f_p = p;
7200eb10989Smrg	filep->f_line = lineno;
7210eb10989Smrg#ifdef DEBUG_DUMP
7220eb10989Smrg	if (bol)
7230eb10989Smrg		DBG_PRINT(stderr,"%s\n",bol);
7240eb10989Smrg#endif
7250eb10989Smrg	return(bol);
7260eb10989Smrg}
7270eb10989Smrg
7280eb10989Smrg/*
7290eb10989Smrg * Strip the file name down to what we want to see in the Makefile.
7300eb10989Smrg * It will have objprefix and objsuffix around it.
7310eb10989Smrg */
7320eb10989Smrgchar *base_name(char *file)
7330eb10989Smrg{
7340eb10989Smrg	char	*p;
7350eb10989Smrg
7360eb10989Smrg	file = copy(file);
7370eb10989Smrg	for(p=file+strlen(file); p>file && *p != '.'; p--) ;
7380eb10989Smrg
7390eb10989Smrg	if (*p == '.')
7400eb10989Smrg		*p = '\0';
7410eb10989Smrg	return(file);
7420eb10989Smrg}
7430eb10989Smrg
7440eb10989Smrg#ifdef USING_AUTOCONF
7450eb10989Smrg# ifndef HAVE_RENAME
7460eb10989Smrg#  define NEED_RENAME
7470eb10989Smrg# endif
7480eb10989Smrg#else /* Imake configured, check known OS'es without rename() */
7490eb10989Smrg# if defined(USG) && !defined(CRAY) && !defined(SVR4) && !defined(__UNIXOS2__) && !defined(clipper) && !defined(__clipper__)
7500eb10989Smrg#  define NEED_RENAME
7510eb10989Smrg# endif
7520eb10989Smrg#endif
7530eb10989Smrg
7540eb10989Smrg#ifdef NEED_RENAME
7550eb10989Smrgint rename (char *from, char *to)
7560eb10989Smrg{
7570eb10989Smrg    (void) unlink (to);
7580eb10989Smrg    if (link (from, to) == 0) {
7590eb10989Smrg	unlink (from);
7600eb10989Smrg	return 0;
7610eb10989Smrg    } else {
7620eb10989Smrg	return -1;
7630eb10989Smrg    }
7640eb10989Smrg}
7650eb10989Smrg#endif /* NEED_RENAME */
7660eb10989Smrg
7670eb10989Smrgvoid
7680eb10989Smrgredirect(char *line, char *makefile)
7690eb10989Smrg{
7700eb10989Smrg	struct stat	st;
7710eb10989Smrg	FILE	*fdin, *fdout;
7720eb10989Smrg	char	backup[ BUFSIZ ],
7730eb10989Smrg		buf[ BUFSIZ ];
7740eb10989Smrg	boolean	found = FALSE;
7750eb10989Smrg	int	len;
7760eb10989Smrg
7770eb10989Smrg	/*
7780eb10989Smrg	 * if makefile is "-" then let it pour onto stdout.
7790eb10989Smrg	 */
7800eb10989Smrg	if (makefile && *makefile == '-' && *(makefile+1) == '\0') {
7810eb10989Smrg		puts(line);
7820eb10989Smrg		return;
7830eb10989Smrg	}
7840eb10989Smrg
7850eb10989Smrg	/*
7860eb10989Smrg	 * use a default makefile is not specified.
7870eb10989Smrg	 */
7880eb10989Smrg	if (!makefile) {
7890eb10989Smrg		if (stat("Makefile", &st) == 0)
7900eb10989Smrg			makefile = "Makefile";
7910eb10989Smrg		else if (stat("makefile", &st) == 0)
7920eb10989Smrg			makefile = "makefile";
7930eb10989Smrg		else
7940eb10989Smrg			fatalerr("[mM]akefile is not present\n");
7950eb10989Smrg	}
7960eb10989Smrg	else
7970eb10989Smrg	    stat(makefile, &st);
7980eb10989Smrg	if ((fdin = fopen(makefile, "r")) == NULL)
7990eb10989Smrg		fatalerr("cannot open \"%s\"\n", makefile);
8000eb10989Smrg	sprintf(backup, "%s.bak", makefile);
8010eb10989Smrg	unlink(backup);
8020eb10989Smrg#if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__)
8030eb10989Smrg	fclose(fdin);
8040eb10989Smrg#endif
8050eb10989Smrg	if (rename(makefile, backup) < 0)
8060eb10989Smrg		fatalerr("cannot rename %s to %s\n", makefile, backup);
8070eb10989Smrg#if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__)
8080eb10989Smrg	if ((fdin = fopen(backup, "r")) == NULL)
8090eb10989Smrg		fatalerr("cannot open \"%s\"\n", backup);
8100eb10989Smrg#endif
8110eb10989Smrg	if ((fdout = freopen(makefile, "w", stdout)) == NULL)
8120eb10989Smrg		fatalerr("cannot open \"%s\"\n", backup);
8130eb10989Smrg	len = strlen(line);
8140eb10989Smrg	while (!found && fgets(buf, BUFSIZ, fdin)) {
8150eb10989Smrg		if (*buf == '#' && strncmp(line, buf, len) == 0)
8160eb10989Smrg			found = TRUE;
8170eb10989Smrg		fputs(buf, fdout);
8180eb10989Smrg	}
8190eb10989Smrg	if (!found) {
8200eb10989Smrg		if (verbose)
8210eb10989Smrg		warning("Adding new delimiting line \"%s\" and dependencies...\n",
8220eb10989Smrg			line);
8230eb10989Smrg		puts(line); /* same as fputs(fdout); but with newline */
8240eb10989Smrg	} else if (append) {
8250eb10989Smrg	    while (fgets(buf, BUFSIZ, fdin)) {
8260eb10989Smrg		fputs(buf, fdout);
8270eb10989Smrg	    }
8280eb10989Smrg	}
8290eb10989Smrg	fflush(fdout);
8300eb10989Smrg#ifndef HAVE_FCHMOD
8310eb10989Smrg	chmod(makefile, st.st_mode);
8320eb10989Smrg#else
8330eb10989Smrg        fchmod(fileno(fdout), st.st_mode);
8340eb10989Smrg#endif /* HAVE_FCHMOD */
8350eb10989Smrg}
8360eb10989Smrg
8370eb10989Smrgvoid
8380eb10989Smrgfatalerr(char *msg, ...)
8390eb10989Smrg{
8400eb10989Smrg	va_list args;
8410eb10989Smrg	fprintf(stderr, "%s: error:  ", ProgramName);
8420eb10989Smrg	va_start(args, msg);
8430eb10989Smrg	vfprintf(stderr, msg, args);
8440eb10989Smrg	va_end(args);
8450eb10989Smrg	exit (1);
8460eb10989Smrg}
8470eb10989Smrg
8480eb10989Smrgvoid
8490eb10989Smrgwarning(char *msg, ...)
8500eb10989Smrg{
8510eb10989Smrg	va_list args;
8520eb10989Smrg	fprintf(stderr, "%s: warning:  ", ProgramName);
8530eb10989Smrg	va_start(args, msg);
8540eb10989Smrg	vfprintf(stderr, msg, args);
8550eb10989Smrg	va_end(args);
8560eb10989Smrg}
8570eb10989Smrg
8580eb10989Smrgvoid
8590eb10989Smrgwarning1(char *msg, ...)
8600eb10989Smrg{
8610eb10989Smrg	va_list args;
8620eb10989Smrg	va_start(args, msg);
8630eb10989Smrg	vfprintf(stderr, msg, args);
8640eb10989Smrg	va_end(args);
8650eb10989Smrg}
866