security/nss/coreconf/mkdepend/main.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* $Xorg: main.c,v 1.5 2001/02/09 02:03:16 xorgcvs Exp $ */
     2 /*
     4 Copyright (c) 1993, 1994, 1998 The Open Group
     6 Permission to use, copy, modify, distribute, and sell this software and its
     7 documentation for any purpose is hereby granted without fee, provided that
     8 the above copyright notice appear in all copies and that both that
     9 copyright notice and this permission notice appear in supporting
    10 documentation.
    12 The above copyright notice and this permission notice shall be included in
    13 all copies or substantial portions of the Software.
    15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    18 THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
    19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    22 Except as contained in this notice, the name of The Open Group shall not be
    23 used in advertising or otherwise to promote the sale, use or other dealings
    24 in this Software without prior written authorization from The Open Group.
    26 */
    27 /* $XFree86: xc/config/makedepend/main.c,v 3.32 2003/03/26 20:43:48 tsi Exp $ */
    29 #include "def.h"
    30 #ifdef hpux
    31 #define sigvec sigvector
    32 #endif /* hpux */
    34 #ifdef X_POSIX_C_SOURCE
    35 #define _POSIX_C_SOURCE X_POSIX_C_SOURCE
    36 #include <signal.h>
    37 #undef _POSIX_C_SOURCE
    38 #else
    39 #if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
    40 #include <signal.h>
    41 #else
    42 #define _POSIX_SOURCE
    43 #include <signal.h>
    44 #undef _POSIX_SOURCE
    45 #endif
    46 #endif
    48 #include <stdarg.h>
    49 #ifdef _WIN32
    50 #include <io.h>
    51 #endif
    53 #ifdef MINIX
    54 #define USE_CHMOD	1
    55 #endif
    57 #ifdef DEBUG
    58 int	_debugmask;
    59 #endif
    61 /* #define DEBUG_DUMP */
    62 #ifdef DEBUG_DUMP
    63 #define DBG_PRINT(file, fmt, args)   fprintf(file, fmt, args)
    64 #else
    65 #define DBG_PRINT(file, fmt, args)   /* empty */
    66 #endif
    68 #define DASH_INC_PRE    "#include \""
    69 #define DASH_INC_POST   "\""
    71 char *ProgramName;
    73 char	*directives[] = {
    74 	"if",
    75 	"ifdef",
    76 	"ifndef",
    77 	"else",
    78 	"endif",
    79 	"define",
    80 	"undef",
    81 	"include",
    82 	"line",
    83 	"pragma",
    84 	"error",
    85 	"ident",
    86 	"sccs",
    87 	"elif",
    88 	"eject",
    89 	"warning",
    90 	"include_next",
    91 	NULL
    92 };
    94 #define MAKEDEPEND
    95 #include "imakemdep.h"	/* from config sources */
    96 #undef MAKEDEPEND
    98 struct	inclist inclist[ MAXFILES ],
    99 		*inclistp = inclist,
   100 		*inclistnext = inclist,
   101 		maininclist;
   103 static char	*filelist[ MAXFILES ];
   104 char		*includedirs[ MAXDIRS + 1 ],
   105 		**includedirsnext = includedirs;
   106 char		*notdotdot[ MAXDIRS ];
   107 static int	cmdinc_count = 0;
   108 static char	*cmdinc_list[ 2 * MAXINCFILES ];
   109 char		*objprefix = "";
   110 char		*objsuffix = OBJSUFFIX;
   111 static char	*startat = "# DO NOT DELETE";
   112 int		width = 78;
   113 static boolean	append = FALSE;
   114 boolean		printed = FALSE;
   115 boolean		verbose = FALSE;
   116 boolean		show_where_not = FALSE;
   117 /* Warn on multiple includes of same file */
   118 boolean 	warn_multiple = FALSE;
   120 static void setfile_cmdinc(struct filepointer *filep, long count, char **list);
   121 static void redirect(char *line, char *makefile);
   123 static
   124 #ifdef SIGNALRETURNSINT
   125 int
   126 #else
   127 void
   128 #endif
   129 catch (int sig)
   130 {
   131 	fflush (stdout);
   132 	fatalerr ("got signal %d\n", sig);
   133 }
   135 #if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(__UNIXOS2__) || defined(Lynx_22) || defined(__CYGWIN__)
   136 #define USGISH
   137 #endif
   139 #ifndef USGISH
   140 #ifdef X_NOT_POSIX
   141 #define sigaction sigvec
   142 #define sa_handler sv_handler
   143 #define sa_mask sv_mask
   144 #define sa_flags sv_flags
   145 #endif
   146 struct sigaction sig_act;
   147 #endif /* USGISH */
   149 int
   150 main(int argc, char *argv[])
   151 {
   152 	char	**fp = filelist;
   153 	char	**incp = includedirs;
   154 	char	*p;
   155 	struct inclist	*ip;
   156 	char	*makefile = NULL;
   157 	struct filepointer	*filecontent;
   158 	struct symtab *psymp = predefs;
   159 	char *endmarker = NULL;
   160 	char *defincdir = NULL;
   161 	char **undeflist = NULL;
   162 	int numundefs = 0, i;
   163 	register char offset;
   165 	ProgramName = argv[0];
   167 	while (psymp->s_name)
   168 	{
   169 	    define2(psymp->s_name, psymp->s_value, &maininclist);
   170 	    psymp++;
   171 	}
   172 	if (argc == 2 && argv[1][0] == '@') {
   173 	    struct stat ast;
   174 	    int afd;
   175 	    char *args;
   176 	    char **nargv;
   177 	    int nargc;
   178 	    char quotechar = '\0';
   180 	    nargc = 1;
   181 	    if ((afd = open(argv[1]+1, O_RDONLY)) < 0)
   182 		fatalerr("cannot open \"%s\"\n", argv[1]+1);
   183 	    fstat(afd, &ast);
   184 	    args = (char *)malloc(ast.st_size + 1);
   185 	    if ((ast.st_size = read(afd, args, ast.st_size)) < 0)
   186 		fatalerr("failed to read %s\n", argv[1]+1);
   187 	    args[ast.st_size] = '\0';
   188 	    close(afd);
   189 	    for (p = args; *p; p++) {
   190 		if (quotechar) {
   191 		    if (quotechar == '\\' ||
   192 			(*p == quotechar && p[-1] != '\\'))
   193 			quotechar = '\0';
   194 		    continue;
   195 		}
   196 		switch (*p) {
   197 		case '\\':
   198 		case '"':
   199 		case '\'':
   200 		    quotechar = *p;
   201 		    break;
   202 		case ' ':
   203 		case '\n':
   204 		    *p = '\0';
   205 		    if (p > args && p[-1])
   206 			nargc++;
   207 		    break;
   208 		}
   209 	    }
   210 	    if (p[-1])
   211 		nargc++;
   212 	    nargv = (char **)malloc(nargc * sizeof(char *));
   213 	    nargv[0] = argv[0];
   214 	    argc = 1;
   215 	    for (p = args; argc < nargc; p += strlen(p) + 1)
   216 		if (*p) nargv[argc++] = p;
   217 	    argv = nargv;
   218 	}
   219 	for(argc--, argv++; argc; argc--, argv++) {
   220 	    	/* if looking for endmarker then check before parsing */
   221 		if (endmarker && strcmp (endmarker, *argv) == 0) {
   222 		    endmarker = NULL;
   223 		    continue;
   224 		}
   225 		if (**argv != '-') {
   226 			/* treat +thing as an option for C++ */
   227 			if (endmarker && **argv == '+')
   228 				continue;
   229 			*fp++ = argv[0];
   230 			continue;
   231 		}
   232 		switch(argv[0][1]) {
   233 		case '-':
   234 			endmarker = &argv[0][2];
   235 			if (endmarker[0] == '\0') endmarker = "--";
   236 			break;
   237 		case 'D':
   238 			offset = 2;
   239 			if (argv[0][2] == '\0') {
   240 				argv++;
   241 				argc--;
   242 				offset = 0;
   243 			}
   244 			/* offset +1 here since first def letter
   245 			 * cannot be `=`
   246 			 */
   247 			for (p = argv[0] + offset + 1; *p; p++)
   248 				if (*p == '=') {
   249 					*p = ' ';
   250 					break;
   251 				}
   252 			define(argv[0] + offset, &maininclist);
   253 			break;
   254 		case 'I':
   255 			if (incp >= includedirs + MAXDIRS)
   256 			    fatalerr("Too many -I flags.\n");
   257 			*incp++ = argv[0]+2;
   258 			if (**(incp-1) == '\0') {
   259 				*(incp-1) = *(++argv);
   260 				argc--;
   261 			}
   262 			break;
   263 		case 'U':
   264 			/* Undef's override all -D's so save them up */
   265 			numundefs++;
   266 			if (numundefs == 1)
   267 			    undeflist = malloc(sizeof(char *));
   268 			else
   269 			    undeflist = realloc(undeflist,
   270 						numundefs * sizeof(char *));
   271 			offset = 2;
   272 			if (argv[0][2] == '\0') {
   273 				argv++;
   274 				argc--;
   275 				offset = 0;
   276 			}
   277 			undeflist[numundefs - 1] = argv[0] + offset;
   278 			break;
   279 		case 'Y':
   280 			defincdir = argv[0]+2;
   281 			break;
   282 		/* do not use if endmarker processing */
   283 		case 'a':
   284 			if (endmarker) break;
   285 			append = TRUE;
   286 			break;
   287 		case 'w':
   288 			if (endmarker) break;
   289 			if (argv[0][2] == '\0') {
   290 				argv++;
   291 				argc--;
   292 				width = atoi(argv[0]);
   293 			} else
   294 				width = atoi(argv[0]+2);
   295 			break;
   296 		case 'o':
   297 			if (endmarker) break;
   298 			if (argv[0][2] == '\0') {
   299 				argv++;
   300 				argc--;
   301 				objsuffix = argv[0];
   302 			} else
   303 				objsuffix = argv[0]+2;
   304 			break;
   305 		case 'p':
   306 			if (endmarker) break;
   307 			if (argv[0][2] == '\0') {
   308 				argv++;
   309 				argc--;
   310 				objprefix = argv[0];
   311 			} else
   312 				objprefix = argv[0]+2;
   313 			break;
   314 		case 'v':
   315 			if (endmarker) break;
   316 			verbose = TRUE;
   317 #ifdef DEBUG
   318 			if (argv[0][2])
   319 				_debugmask = atoi(argv[0]+2);
   320 #endif
   321 			break;
   322 		case 's':
   323 			if (endmarker) break;
   324 			startat = argv[0]+2;
   325 			if (*startat == '\0') {
   326 				startat = *(++argv);
   327 				argc--;
   328 			}
   329 			if (*startat != '#')
   330 				fatalerr("-s flag's value should start %s\n",
   331 					"with '#'.");
   332 			break;
   333 		case 'f':
   334 			if (endmarker) break;
   335 			makefile = argv[0]+2;
   336 			if (*makefile == '\0') {
   337 				makefile = *(++argv);
   338 				argc--;
   339 			}
   340 			break;
   342 		case 'm':
   343 			warn_multiple = TRUE;
   344 			break;
   346 		/* Ignore -O, -g so we can just pass ${CFLAGS} to
   347 		   makedepend
   348 		 */
   349 		case 'O':
   350 		case 'g':
   351 			break;
   352 		case 'i':
   353 			if (strcmp(&argv[0][1],"include") == 0) {
   354 				char *buf;
   355 				if (argc<2)
   356 					fatalerr("option -include is a "
   357 						 "missing its parameter\n");
   358 				if (cmdinc_count >= MAXINCFILES)
   359 					fatalerr("Too many -include flags.\n");
   360 				argc--;
   361 				argv++;
   362 				buf = malloc(strlen(DASH_INC_PRE) +
   363 					     strlen(argv[0]) +
   364 					     strlen(DASH_INC_POST) + 1);
   365                 		if(!buf)
   366 					fatalerr("out of memory at "
   367 						 "-include string\n");
   368 				cmdinc_list[2 * cmdinc_count + 0] = argv[0];
   369 				cmdinc_list[2 * cmdinc_count + 1] = buf;
   370 				cmdinc_count++;
   371 				break;
   372 			}
   373 			/* intentional fall through */
   374 		default:
   375 			if (endmarker) break;
   376 	/*		fatalerr("unknown opt = %s\n", argv[0]); */
   377 			warning("ignoring option %s\n", argv[0]);
   378 		}
   379 	}
   380 	/* Now do the undefs from the command line */
   381 	for (i = 0; i < numundefs; i++)
   382 	    undefine(undeflist[i], &maininclist);
   383 	if (numundefs > 0)
   384 	    free(undeflist);
   386 	if (!defincdir) {
   387 #ifdef PREINCDIR
   388 	    if (incp >= includedirs + MAXDIRS)
   389 		fatalerr("Too many -I flags.\n");
   390 	    *incp++ = PREINCDIR;
   391 #endif
   392 #if defined(__UNIXOS2__) || defined(_MSC_VER)
   393 	    {
   394 #if defined(_MSC_VER)
   395 		char *includepath = getenv("INCLUDE");
   396 #else
   397 		char *includepath = getenv("C_INCLUDE_PATH");
   398 #endif
   399 		/* can have more than one component */
   400 		if (includepath) {
   401 		    char *beg, *end;
   402 		    beg= (char*)strdup(includepath);
   403 		    for (;;) {
   404 			end = (char*)strchr(beg,';');
   405 			if (end) *end = 0;
   406 		    	if (incp >= includedirs + MAXDIRS)
   407 				fatalerr("Too many include dirs\n");
   408 			*incp++ = beg;
   409 			if (!end) break;
   410 			beg = end+1;
   411 		    }
   412 		}
   413 	    }
   414 #else /* !__UNIXOS2__ && !_MSC_VER, does not use INCLUDEDIR at all */
   415 	    if (incp >= includedirs + MAXDIRS)
   416 		fatalerr("Too many -I flags.\n");
   417 	    *incp++ = INCLUDEDIR;
   418 #endif
   420 #ifdef EXTRAINCDIR
   421 	    if (incp >= includedirs + MAXDIRS)
   422 		fatalerr("Too many -I flags.\n");
   423 	    *incp++ = EXTRAINCDIR;
   424 #endif
   426 #ifdef POSTINCDIR
   427 	    if (incp >= includedirs + MAXDIRS)
   428 		fatalerr("Too many -I flags.\n");
   429 	    *incp++ = POSTINCDIR;
   430 #endif
   431 	} else if (*defincdir) {
   432 	    if (incp >= includedirs + MAXDIRS)
   433 		fatalerr("Too many -I flags.\n");
   434 	    *incp++ = defincdir;
   435 	}
   437 	redirect(startat, makefile);
   439 	/*
   440 	 * catch signals.
   441 	 */
   442 #ifdef USGISH
   443 /*  should really reset SIGINT to SIG_IGN if it was.  */
   444 #ifdef SIGHUP
   445 	signal (SIGHUP, catch);
   446 #endif
   447 	signal (SIGINT, catch);
   448 #ifdef SIGQUIT
   449 	signal (SIGQUIT, catch);
   450 #endif
   451 	signal (SIGILL, catch);
   452 #ifdef SIGBUS
   453 	signal (SIGBUS, catch);
   454 #endif
   455 	signal (SIGSEGV, catch);
   456 #ifdef SIGSYS
   457 	signal (SIGSYS, catch);
   458 #endif
   459 #else
   460 	sig_act.sa_handler = catch;
   461 #if defined(_POSIX_SOURCE) || !defined(X_NOT_POSIX)
   462 	sigemptyset(&sig_act.sa_mask);
   463 	sigaddset(&sig_act.sa_mask, SIGINT);
   464 	sigaddset(&sig_act.sa_mask, SIGQUIT);
   465 #ifdef SIGBUS
   466 	sigaddset(&sig_act.sa_mask, SIGBUS);
   467 #endif
   468 	sigaddset(&sig_act.sa_mask, SIGILL);
   469 	sigaddset(&sig_act.sa_mask, SIGSEGV);
   470 	sigaddset(&sig_act.sa_mask, SIGHUP);
   471 	sigaddset(&sig_act.sa_mask, SIGPIPE);
   472 #ifdef SIGSYS
   473 	sigaddset(&sig_act.sa_mask, SIGSYS);
   474 #endif
   475 #else
   476 	sig_act.sa_mask = ((1<<(SIGINT -1))
   477 			   |(1<<(SIGQUIT-1))
   478 #ifdef SIGBUS
   479 			   |(1<<(SIGBUS-1))
   480 #endif
   481 			   |(1<<(SIGILL-1))
   482 			   |(1<<(SIGSEGV-1))
   483 			   |(1<<(SIGHUP-1))
   484 			   |(1<<(SIGPIPE-1))
   485 #ifdef SIGSYS
   486 			   |(1<<(SIGSYS-1))
   487 #endif
   488 			   );
   489 #endif /* _POSIX_SOURCE */
   490 	sig_act.sa_flags = 0;
   491 	sigaction(SIGHUP, &sig_act, (struct sigaction *)0);
   492 	sigaction(SIGINT, &sig_act, (struct sigaction *)0);
   493 	sigaction(SIGQUIT, &sig_act, (struct sigaction *)0);
   494 	sigaction(SIGILL, &sig_act, (struct sigaction *)0);
   495 #ifdef SIGBUS
   496 	sigaction(SIGBUS, &sig_act, (struct sigaction *)0);
   497 #endif
   498 	sigaction(SIGSEGV, &sig_act, (struct sigaction *)0);
   499 #ifdef SIGSYS
   500 	sigaction(SIGSYS, &sig_act, (struct sigaction *)0);
   501 #endif
   502 #endif /* USGISH */
   504 	/*
   505 	 * now peruse through the list of files.
   506 	 */
   507 	for(fp=filelist; *fp; fp++) {
   508 		DBG_PRINT(stderr,"file: %s\n",*fp);
   509 		filecontent = getfile(*fp);
   510 		setfile_cmdinc(filecontent, cmdinc_count, cmdinc_list);
   511 		ip = newinclude(*fp, (char *)NULL);
   513 		find_includes(filecontent, ip, ip, 0, FALSE);
   514 		freefile(filecontent);
   515 		recursive_pr_include(ip, ip->i_file, base_name(*fp));
   516 		inc_clean();
   517 	}
   518 	if (printed)
   519 		printf("\n");
   520 	return 0;
   521 }
   523 #ifdef __UNIXOS2__
   524 /*
   525  * eliminate \r chars from file
   526  */
   527 static int 
   528 elim_cr(char *buf, int sz)
   529 {
   530 	int i,wp;
   531 	for (i= wp = 0; i<sz; i++) {
   532 		if (buf[i] != '\r')
   533 			buf[wp++] = buf[i];
   534 	}
   535 	return wp;
   536 }
   537 #endif
   539 struct filepointer *
   540 getfile(char *file)
   541 {
   542 	int	fd;
   543 	struct filepointer	*content;
   544 	struct stat	st;
   546 	content = (struct filepointer *)malloc(sizeof(struct filepointer));
   547 	content->f_name = file;
   548 	if ((fd = open(file, O_RDONLY)) < 0) {
   549 		warning("cannot open \"%s\"\n", file);
   550 		content->f_p = content->f_base = content->f_end = (char *)malloc(1);
   551 		*content->f_p = '\0';
   552 		return(content);
   553 	}
   554 	fstat(fd, &st);
   555 	content->f_base = (char *)malloc(st.st_size+1);
   556 	if (content->f_base == NULL)
   557 		fatalerr("cannot allocate mem\n");
   558 	if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0)
   559 		fatalerr("failed to read %s\n", file);
   560 #ifdef __UNIXOS2__
   561 	st.st_size = elim_cr(content->f_base,st.st_size);
   562 #endif
   563 	close(fd);
   564 	content->f_len = st.st_size+1;
   565 	content->f_p = content->f_base;
   566 	content->f_end = content->f_base + st.st_size;
   567 	*content->f_end = '\0';
   568 	content->f_line = 0;
   569 	content->cmdinc_count = 0;
   570 	content->cmdinc_list = NULL;
   571 	content->cmdinc_line = 0;
   572 	return(content);
   573 }
   575 void
   576 setfile_cmdinc(struct filepointer* filep, long count, char** list)
   577 {
   578 	filep->cmdinc_count = count;
   579 	filep->cmdinc_list = list;
   580 	filep->cmdinc_line = 0;
   581 }
   583 void
   584 freefile(struct filepointer *fp)
   585 {
   586 	free(fp->f_base);
   587 	free(fp);
   588 }
   590 char *copy(char *str)
   591 {
   592 	char	*p = (char *)malloc(strlen(str) + 1);
   594 	strcpy(p, str);
   595 	return(p);
   596 }
   598 int
   599 match(char *str, char **list)
   600 {
   601 	int	i;
   603 	for (i=0; *list; i++, list++)
   604 		if (strcmp(str, *list) == 0)
   605 			return(i);
   606 	return(-1);
   607 }
   609 /*
   610  * Get the next line.  We only return lines beginning with '#' since that
   611  * is all this program is ever interested in.
   612  */
   613 char *getnextline(struct filepointer *filep)
   614 {
   615 	char	*p,	/* walking pointer */
   616 		*eof,	/* end of file pointer */
   617 		*bol;	/* beginning of line pointer */
   618 	int	lineno;	/* line number */
   619 	boolean whitespace = FALSE;
   621 	/*
   622 	 * Fake the "-include" line files in form of #include to the
   623 	 * start of each file.
   624 	 */
   625 	if (filep->cmdinc_line < filep->cmdinc_count) {
   626 		char *inc = filep->cmdinc_list[2 * filep->cmdinc_line + 0];
   627 		char *buf = filep->cmdinc_list[2 * filep->cmdinc_line + 1];
   628 		filep->cmdinc_line++;
   629 		sprintf(buf,"%s%s%s",DASH_INC_PRE,inc,DASH_INC_POST);
   630 		DBG_PRINT(stderr,"%s\n",buf);
   631 		return(buf);
   632 	}
   634 	p = filep->f_p;
   635 	eof = filep->f_end;
   636 	if (p >= eof)
   637 		return((char *)NULL);
   638 	lineno = filep->f_line;
   640 	for (bol = p--; ++p < eof; ) {
   641 		if ((bol == p) && ((*p == ' ') || (*p == '\t')))
   642 		{
   643 			/* Consume leading white-spaces for this line */
   644 			while (((p+1) < eof) && ((*p == ' ') || (*p == '\t')))
   645 			{
   646 				p++;
   647 				bol++;
   648 			}
   649 			whitespace = TRUE;
   650 		}
   652 		if (*p == '/' && (p+1) < eof && *(p+1) == '*') {
   653 			/* Consume C comments */
   654 			*(p++) = ' ';
   655 			*(p++) = ' ';
   656 			while (p < eof && *p) {
   657 				if (*p == '*' && (p+1) < eof && *(p+1) == '/') {
   658 					*(p++) = ' ';
   659 					*(p++) = ' ';
   660 					break;
   661 				}
   662 				if (*p == '\n')
   663 					lineno++;
   664 				*(p++) = ' ';
   665 			}
   666 			--p;
   667 		}
   668 		else if (*p == '/' && (p+1) < eof && *(p+1) == '/') {
   669 			/* Consume C++ comments */
   670 			*(p++) = ' ';
   671 			*(p++) = ' ';
   672 			while (p < eof && *p) {
   673 				if (*p == '\\' && (p+1) < eof &&
   674 				    *(p+1) == '\n') {
   675 					*(p++) = ' ';
   676 					lineno++;
   677 				}
   678 				else if (*p == '?' && (p+3) < eof &&
   679 					 *(p+1) == '?' && 
   680 					 *(p+2) == '/' &&
   681 					 *(p+3) == '\n') {
   682 					*(p++) = ' ';
   683 					*(p++) = ' ';
   684 					*(p++) = ' ';
   685 					lineno++;
   686 				}
   687 				else if (*p == '\n')
   688 					break;	/* to process end of line */
   689 				*(p++) = ' ';
   690 			}
   691 			--p;
   692 		}
   693 		else if (*p == '\\' && (p+1) < eof && *(p+1) == '\n') {
   694 			/* Consume backslash line terminations */
   695 			*(p++) = ' ';
   696 			*p = ' ';
   697 			lineno++;
   698 		}
   699 		else if (*p == '?' && (p+3) < eof &&
   700 			 *(p+1) == '?' && *(p+2) == '/' && *(p+3) == '\n') {
   701 			/* Consume trigraph'ed backslash line terminations */
   702 			*(p++) = ' ';
   703 			*(p++) = ' ';
   704 			*(p++) = ' ';
   705 			*p = ' ';
   706 			lineno++;
   707 		}
   708 		else if (*p == '\n') {
   709 			lineno++;
   710 			if (*bol == '#') {
   711 				char *cp;
   713 				*(p++) = '\0';
   714 				/* punt lines with just # (yacc generated) */
   715 				for (cp = bol+1; 
   716 				     *cp && (*cp == ' ' || *cp == '\t'); cp++);
   717 				if (*cp) goto done;
   718 				--p;
   719 			}
   720 			bol = p+1;
   721 			whitespace = FALSE;
   722 		}
   723 	}
   724 	if (*bol != '#')
   725 		bol = NULL;
   726 done:
   727 #if !defined(__UNIXOS2__) && !defined(_MSC_VER) && !defined(_WIN32)
   728 	/* Don't print warnings for system header files */
   729 	if (bol && whitespace && !strstr(filep->f_name, INCLUDEDIR)) {
   730 		warning("%s:  non-portable whitespace encountered at line %d\n",
   731 			filep->f_name, lineno);
   732 	}
   733 #endif
   734 	filep->f_p = p;
   735 	filep->f_line = lineno;
   736 #ifdef DEBUG_DUMP
   737 	if (bol)
   738 		DBG_PRINT(stderr,"%s\n",bol);
   739 #endif
   740 	return(bol);
   741 }
   743 /*
   744  * Strip the file name down to what we want to see in the Makefile.
   745  * It will have objprefix and objsuffix around it.
   746  */
   747 char *base_name(char *file)
   748 {
   749 	char	*p;
   751 	file = copy(file);
   752 	for(p=file+strlen(file); p>file && *p != '.'; p--) ;
   754 	if (*p == '.')
   755 		*p = '\0';
   756 	return(file);
   757 }
   759 #if defined(USG) && !defined(CRAY) && !defined(SVR4) && !defined(__UNIXOS2__) && !defined(clipper) && !defined(__clipper__)
   760 int rename (char *from, char *to)
   761 {
   762     (void) unlink (to);
   763     if (link (from, to) == 0) {
   764 	unlink (from);
   765 	return 0;
   766     } else {
   767 	return -1;
   768     }
   769 }
   770 #endif /* USGISH */
   772 void
   773 redirect(char *line, char *makefile)
   774 {
   775 	struct stat	st;
   776 	FILE	*fdin, *fdout;
   777 	char	backup[ BUFSIZ ],
   778 		buf[ BUFSIZ ];
   779 	boolean	found = FALSE;
   780 	int	len;
   782 	/*
   783 	 * if makefile is "-" then let it pour onto stdout.
   784 	 */
   785 	if (makefile && *makefile == '-' && *(makefile+1) == '\0') {
   786 		puts(line);
   787 		return;
   788 	}
   790 	/*
   791 	 * use a default makefile is not specified.
   792 	 */
   793 	if (!makefile) {
   794 		if (stat("Makefile", &st) == 0)
   795 			makefile = "Makefile";
   796 		else if (stat("makefile", &st) == 0)
   797 			makefile = "makefile";
   798 		else
   799 			fatalerr("[mM]akefile is not present\n");
   800 	}
   801 	else
   802 	    stat(makefile, &st);
   803 	if ((fdin = fopen(makefile, "r")) == NULL)
   804 		fatalerr("cannot open \"%s\"\n", makefile);
   805 	sprintf(backup, "%s.bak", makefile);
   806 	unlink(backup);
   807 #if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__)
   808 	fclose(fdin);
   809 #endif
   810 	if (rename(makefile, backup) < 0)
   811 		fatalerr("cannot rename %s to %s\n", makefile, backup);
   812 #if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__)
   813 	if ((fdin = fopen(backup, "r")) == NULL)
   814 		fatalerr("cannot open \"%s\"\n", backup);
   815 #endif
   816 	if ((fdout = freopen(makefile, "w", stdout)) == NULL)
   817 		fatalerr("cannot open \"%s\"\n", backup);
   818 	len = strlen(line);
   819 	while (!found && fgets(buf, BUFSIZ, fdin)) {
   820 		if (*buf == '#' && strncmp(line, buf, len) == 0)
   821 			found = TRUE;
   822 		fputs(buf, fdout);
   823 	}
   824 	if (!found) {
   825 		if (verbose)
   826 		warning("Adding new delimiting line \"%s\" and dependencies...\n",
   827 			line);
   828 		puts(line); /* same as fputs(fdout); but with newline */
   829 	} else if (append) {
   830 	    while (fgets(buf, BUFSIZ, fdin)) {
   831 		fputs(buf, fdout);
   832 	    }
   833 	}
   834 	fflush(fdout);
   835 #if defined(USGISH) || defined(_SEQUENT_) || defined(USE_CHMOD)
   836 	chmod(makefile, st.st_mode);
   837 #else
   838         fchmod(fileno(fdout), st.st_mode);
   839 #endif /* USGISH */
   840 }
   842 void
   843 fatalerr(char *msg, ...)
   844 {
   845 	va_list args;
   846 	fprintf(stderr, "%s: error:  ", ProgramName);
   847 	va_start(args, msg);
   848 	vfprintf(stderr, msg, args);
   849 	va_end(args);
   850 	exit (1);
   851 }
   853 void
   854 warning(char *msg, ...)
   855 {
   856 	va_list args;
   857 	fprintf(stderr, "%s: warning:  ", ProgramName);
   858 	va_start(args, msg);
   859 	vfprintf(stderr, msg, args);
   860 	va_end(args);
   861 }
   863 void
   864 warning1(char *msg, ...)
   865 {
   866 	va_list args;
   867 	va_start(args, msg);
   868 	vfprintf(stderr, msg, args);
   869 	va_end(args);
   870 }

mercurial