michael@0: /* $Xorg: main.c,v 1.5 2001/02/09 02:03:16 xorgcvs Exp $ */ michael@0: /* michael@0: michael@0: Copyright (c) 1993, 1994, 1998 The Open Group michael@0: michael@0: Permission to use, copy, modify, distribute, and sell this software and its michael@0: documentation for any purpose is hereby granted without fee, provided that michael@0: the above copyright notice appear in all copies and that both that michael@0: copyright notice and this permission notice appear in supporting michael@0: documentation. michael@0: michael@0: The above copyright notice and this permission notice shall be included in michael@0: all copies or substantial portions of the Software. michael@0: michael@0: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR michael@0: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, michael@0: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE michael@0: THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN michael@0: AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN michael@0: CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. michael@0: michael@0: Except as contained in this notice, the name of The Open Group shall not be michael@0: used in advertising or otherwise to promote the sale, use or other dealings michael@0: in this Software without prior written authorization from The Open Group. michael@0: michael@0: */ michael@0: /* $XFree86: xc/config/makedepend/main.c,v 3.32 2003/03/26 20:43:48 tsi Exp $ */ michael@0: michael@0: #include "def.h" michael@0: #ifdef hpux michael@0: #define sigvec sigvector michael@0: #endif /* hpux */ michael@0: michael@0: #ifdef X_POSIX_C_SOURCE michael@0: #define _POSIX_C_SOURCE X_POSIX_C_SOURCE michael@0: #include michael@0: #undef _POSIX_C_SOURCE michael@0: #else michael@0: #if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE) michael@0: #include michael@0: #else michael@0: #define _POSIX_SOURCE michael@0: #include michael@0: #undef _POSIX_SOURCE michael@0: #endif michael@0: #endif michael@0: michael@0: #include michael@0: #ifdef _WIN32 michael@0: #include michael@0: #endif michael@0: michael@0: #ifdef MINIX michael@0: #define USE_CHMOD 1 michael@0: #endif michael@0: michael@0: #ifdef DEBUG michael@0: int _debugmask; michael@0: #endif michael@0: michael@0: /* #define DEBUG_DUMP */ michael@0: #ifdef DEBUG_DUMP michael@0: #define DBG_PRINT(file, fmt, args) fprintf(file, fmt, args) michael@0: #else michael@0: #define DBG_PRINT(file, fmt, args) /* empty */ michael@0: #endif michael@0: michael@0: #define DASH_INC_PRE "#include \"" michael@0: #define DASH_INC_POST "\"" michael@0: michael@0: char *ProgramName; michael@0: michael@0: char *directives[] = { michael@0: "if", michael@0: "ifdef", michael@0: "ifndef", michael@0: "else", michael@0: "endif", michael@0: "define", michael@0: "undef", michael@0: "include", michael@0: "line", michael@0: "pragma", michael@0: "error", michael@0: "ident", michael@0: "sccs", michael@0: "elif", michael@0: "eject", michael@0: "warning", michael@0: "include_next", michael@0: NULL michael@0: }; michael@0: michael@0: #define MAKEDEPEND michael@0: #include "imakemdep.h" /* from config sources */ michael@0: #undef MAKEDEPEND michael@0: michael@0: struct inclist inclist[ MAXFILES ], michael@0: *inclistp = inclist, michael@0: *inclistnext = inclist, michael@0: maininclist; michael@0: michael@0: static char *filelist[ MAXFILES ]; michael@0: char *includedirs[ MAXDIRS + 1 ], michael@0: **includedirsnext = includedirs; michael@0: char *notdotdot[ MAXDIRS ]; michael@0: static int cmdinc_count = 0; michael@0: static char *cmdinc_list[ 2 * MAXINCFILES ]; michael@0: char *objprefix = ""; michael@0: char *objsuffix = OBJSUFFIX; michael@0: static char *startat = "# DO NOT DELETE"; michael@0: int width = 78; michael@0: static boolean append = FALSE; michael@0: boolean printed = FALSE; michael@0: boolean verbose = FALSE; michael@0: boolean show_where_not = FALSE; michael@0: /* Warn on multiple includes of same file */ michael@0: boolean warn_multiple = FALSE; michael@0: michael@0: static void setfile_cmdinc(struct filepointer *filep, long count, char **list); michael@0: static void redirect(char *line, char *makefile); michael@0: michael@0: static michael@0: #ifdef SIGNALRETURNSINT michael@0: int michael@0: #else michael@0: void michael@0: #endif michael@0: catch (int sig) michael@0: { michael@0: fflush (stdout); michael@0: fatalerr ("got signal %d\n", sig); michael@0: } michael@0: michael@0: #if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(__UNIXOS2__) || defined(Lynx_22) || defined(__CYGWIN__) michael@0: #define USGISH michael@0: #endif michael@0: michael@0: #ifndef USGISH michael@0: #ifdef X_NOT_POSIX michael@0: #define sigaction sigvec michael@0: #define sa_handler sv_handler michael@0: #define sa_mask sv_mask michael@0: #define sa_flags sv_flags michael@0: #endif michael@0: struct sigaction sig_act; michael@0: #endif /* USGISH */ michael@0: michael@0: int michael@0: main(int argc, char *argv[]) michael@0: { michael@0: char **fp = filelist; michael@0: char **incp = includedirs; michael@0: char *p; michael@0: struct inclist *ip; michael@0: char *makefile = NULL; michael@0: struct filepointer *filecontent; michael@0: struct symtab *psymp = predefs; michael@0: char *endmarker = NULL; michael@0: char *defincdir = NULL; michael@0: char **undeflist = NULL; michael@0: int numundefs = 0, i; michael@0: register char offset; michael@0: michael@0: ProgramName = argv[0]; michael@0: michael@0: while (psymp->s_name) michael@0: { michael@0: define2(psymp->s_name, psymp->s_value, &maininclist); michael@0: psymp++; michael@0: } michael@0: if (argc == 2 && argv[1][0] == '@') { michael@0: struct stat ast; michael@0: int afd; michael@0: char *args; michael@0: char **nargv; michael@0: int nargc; michael@0: char quotechar = '\0'; michael@0: michael@0: nargc = 1; michael@0: if ((afd = open(argv[1]+1, O_RDONLY)) < 0) michael@0: fatalerr("cannot open \"%s\"\n", argv[1]+1); michael@0: fstat(afd, &ast); michael@0: args = (char *)malloc(ast.st_size + 1); michael@0: if ((ast.st_size = read(afd, args, ast.st_size)) < 0) michael@0: fatalerr("failed to read %s\n", argv[1]+1); michael@0: args[ast.st_size] = '\0'; michael@0: close(afd); michael@0: for (p = args; *p; p++) { michael@0: if (quotechar) { michael@0: if (quotechar == '\\' || michael@0: (*p == quotechar && p[-1] != '\\')) michael@0: quotechar = '\0'; michael@0: continue; michael@0: } michael@0: switch (*p) { michael@0: case '\\': michael@0: case '"': michael@0: case '\'': michael@0: quotechar = *p; michael@0: break; michael@0: case ' ': michael@0: case '\n': michael@0: *p = '\0'; michael@0: if (p > args && p[-1]) michael@0: nargc++; michael@0: break; michael@0: } michael@0: } michael@0: if (p[-1]) michael@0: nargc++; michael@0: nargv = (char **)malloc(nargc * sizeof(char *)); michael@0: nargv[0] = argv[0]; michael@0: argc = 1; michael@0: for (p = args; argc < nargc; p += strlen(p) + 1) michael@0: if (*p) nargv[argc++] = p; michael@0: argv = nargv; michael@0: } michael@0: for(argc--, argv++; argc; argc--, argv++) { michael@0: /* if looking for endmarker then check before parsing */ michael@0: if (endmarker && strcmp (endmarker, *argv) == 0) { michael@0: endmarker = NULL; michael@0: continue; michael@0: } michael@0: if (**argv != '-') { michael@0: /* treat +thing as an option for C++ */ michael@0: if (endmarker && **argv == '+') michael@0: continue; michael@0: *fp++ = argv[0]; michael@0: continue; michael@0: } michael@0: switch(argv[0][1]) { michael@0: case '-': michael@0: endmarker = &argv[0][2]; michael@0: if (endmarker[0] == '\0') endmarker = "--"; michael@0: break; michael@0: case 'D': michael@0: offset = 2; michael@0: if (argv[0][2] == '\0') { michael@0: argv++; michael@0: argc--; michael@0: offset = 0; michael@0: } michael@0: /* offset +1 here since first def letter michael@0: * cannot be `=` michael@0: */ michael@0: for (p = argv[0] + offset + 1; *p; p++) michael@0: if (*p == '=') { michael@0: *p = ' '; michael@0: break; michael@0: } michael@0: define(argv[0] + offset, &maininclist); michael@0: break; michael@0: case 'I': michael@0: if (incp >= includedirs + MAXDIRS) michael@0: fatalerr("Too many -I flags.\n"); michael@0: *incp++ = argv[0]+2; michael@0: if (**(incp-1) == '\0') { michael@0: *(incp-1) = *(++argv); michael@0: argc--; michael@0: } michael@0: break; michael@0: case 'U': michael@0: /* Undef's override all -D's so save them up */ michael@0: numundefs++; michael@0: if (numundefs == 1) michael@0: undeflist = malloc(sizeof(char *)); michael@0: else michael@0: undeflist = realloc(undeflist, michael@0: numundefs * sizeof(char *)); michael@0: offset = 2; michael@0: if (argv[0][2] == '\0') { michael@0: argv++; michael@0: argc--; michael@0: offset = 0; michael@0: } michael@0: undeflist[numundefs - 1] = argv[0] + offset; michael@0: break; michael@0: case 'Y': michael@0: defincdir = argv[0]+2; michael@0: break; michael@0: /* do not use if endmarker processing */ michael@0: case 'a': michael@0: if (endmarker) break; michael@0: append = TRUE; michael@0: break; michael@0: case 'w': michael@0: if (endmarker) break; michael@0: if (argv[0][2] == '\0') { michael@0: argv++; michael@0: argc--; michael@0: width = atoi(argv[0]); michael@0: } else michael@0: width = atoi(argv[0]+2); michael@0: break; michael@0: case 'o': michael@0: if (endmarker) break; michael@0: if (argv[0][2] == '\0') { michael@0: argv++; michael@0: argc--; michael@0: objsuffix = argv[0]; michael@0: } else michael@0: objsuffix = argv[0]+2; michael@0: break; michael@0: case 'p': michael@0: if (endmarker) break; michael@0: if (argv[0][2] == '\0') { michael@0: argv++; michael@0: argc--; michael@0: objprefix = argv[0]; michael@0: } else michael@0: objprefix = argv[0]+2; michael@0: break; michael@0: case 'v': michael@0: if (endmarker) break; michael@0: verbose = TRUE; michael@0: #ifdef DEBUG michael@0: if (argv[0][2]) michael@0: _debugmask = atoi(argv[0]+2); michael@0: #endif michael@0: break; michael@0: case 's': michael@0: if (endmarker) break; michael@0: startat = argv[0]+2; michael@0: if (*startat == '\0') { michael@0: startat = *(++argv); michael@0: argc--; michael@0: } michael@0: if (*startat != '#') michael@0: fatalerr("-s flag's value should start %s\n", michael@0: "with '#'."); michael@0: break; michael@0: case 'f': michael@0: if (endmarker) break; michael@0: makefile = argv[0]+2; michael@0: if (*makefile == '\0') { michael@0: makefile = *(++argv); michael@0: argc--; michael@0: } michael@0: break; michael@0: michael@0: case 'm': michael@0: warn_multiple = TRUE; michael@0: break; michael@0: michael@0: /* Ignore -O, -g so we can just pass ${CFLAGS} to michael@0: makedepend michael@0: */ michael@0: case 'O': michael@0: case 'g': michael@0: break; michael@0: case 'i': michael@0: if (strcmp(&argv[0][1],"include") == 0) { michael@0: char *buf; michael@0: if (argc<2) michael@0: fatalerr("option -include is a " michael@0: "missing its parameter\n"); michael@0: if (cmdinc_count >= MAXINCFILES) michael@0: fatalerr("Too many -include flags.\n"); michael@0: argc--; michael@0: argv++; michael@0: buf = malloc(strlen(DASH_INC_PRE) + michael@0: strlen(argv[0]) + michael@0: strlen(DASH_INC_POST) + 1); michael@0: if(!buf) michael@0: fatalerr("out of memory at " michael@0: "-include string\n"); michael@0: cmdinc_list[2 * cmdinc_count + 0] = argv[0]; michael@0: cmdinc_list[2 * cmdinc_count + 1] = buf; michael@0: cmdinc_count++; michael@0: break; michael@0: } michael@0: /* intentional fall through */ michael@0: default: michael@0: if (endmarker) break; michael@0: /* fatalerr("unknown opt = %s\n", argv[0]); */ michael@0: warning("ignoring option %s\n", argv[0]); michael@0: } michael@0: } michael@0: /* Now do the undefs from the command line */ michael@0: for (i = 0; i < numundefs; i++) michael@0: undefine(undeflist[i], &maininclist); michael@0: if (numundefs > 0) michael@0: free(undeflist); michael@0: michael@0: if (!defincdir) { michael@0: #ifdef PREINCDIR michael@0: if (incp >= includedirs + MAXDIRS) michael@0: fatalerr("Too many -I flags.\n"); michael@0: *incp++ = PREINCDIR; michael@0: #endif michael@0: #if defined(__UNIXOS2__) || defined(_MSC_VER) michael@0: { michael@0: #if defined(_MSC_VER) michael@0: char *includepath = getenv("INCLUDE"); michael@0: #else michael@0: char *includepath = getenv("C_INCLUDE_PATH"); michael@0: #endif michael@0: /* can have more than one component */ michael@0: if (includepath) { michael@0: char *beg, *end; michael@0: beg= (char*)strdup(includepath); michael@0: for (;;) { michael@0: end = (char*)strchr(beg,';'); michael@0: if (end) *end = 0; michael@0: if (incp >= includedirs + MAXDIRS) michael@0: fatalerr("Too many include dirs\n"); michael@0: *incp++ = beg; michael@0: if (!end) break; michael@0: beg = end+1; michael@0: } michael@0: } michael@0: } michael@0: #else /* !__UNIXOS2__ && !_MSC_VER, does not use INCLUDEDIR at all */ michael@0: if (incp >= includedirs + MAXDIRS) michael@0: fatalerr("Too many -I flags.\n"); michael@0: *incp++ = INCLUDEDIR; michael@0: #endif michael@0: michael@0: #ifdef EXTRAINCDIR michael@0: if (incp >= includedirs + MAXDIRS) michael@0: fatalerr("Too many -I flags.\n"); michael@0: *incp++ = EXTRAINCDIR; michael@0: #endif michael@0: michael@0: #ifdef POSTINCDIR michael@0: if (incp >= includedirs + MAXDIRS) michael@0: fatalerr("Too many -I flags.\n"); michael@0: *incp++ = POSTINCDIR; michael@0: #endif michael@0: } else if (*defincdir) { michael@0: if (incp >= includedirs + MAXDIRS) michael@0: fatalerr("Too many -I flags.\n"); michael@0: *incp++ = defincdir; michael@0: } michael@0: michael@0: redirect(startat, makefile); michael@0: michael@0: /* michael@0: * catch signals. michael@0: */ michael@0: #ifdef USGISH michael@0: /* should really reset SIGINT to SIG_IGN if it was. */ michael@0: #ifdef SIGHUP michael@0: signal (SIGHUP, catch); michael@0: #endif michael@0: signal (SIGINT, catch); michael@0: #ifdef SIGQUIT michael@0: signal (SIGQUIT, catch); michael@0: #endif michael@0: signal (SIGILL, catch); michael@0: #ifdef SIGBUS michael@0: signal (SIGBUS, catch); michael@0: #endif michael@0: signal (SIGSEGV, catch); michael@0: #ifdef SIGSYS michael@0: signal (SIGSYS, catch); michael@0: #endif michael@0: #else michael@0: sig_act.sa_handler = catch; michael@0: #if defined(_POSIX_SOURCE) || !defined(X_NOT_POSIX) michael@0: sigemptyset(&sig_act.sa_mask); michael@0: sigaddset(&sig_act.sa_mask, SIGINT); michael@0: sigaddset(&sig_act.sa_mask, SIGQUIT); michael@0: #ifdef SIGBUS michael@0: sigaddset(&sig_act.sa_mask, SIGBUS); michael@0: #endif michael@0: sigaddset(&sig_act.sa_mask, SIGILL); michael@0: sigaddset(&sig_act.sa_mask, SIGSEGV); michael@0: sigaddset(&sig_act.sa_mask, SIGHUP); michael@0: sigaddset(&sig_act.sa_mask, SIGPIPE); michael@0: #ifdef SIGSYS michael@0: sigaddset(&sig_act.sa_mask, SIGSYS); michael@0: #endif michael@0: #else michael@0: sig_act.sa_mask = ((1<<(SIGINT -1)) michael@0: |(1<<(SIGQUIT-1)) michael@0: #ifdef SIGBUS michael@0: |(1<<(SIGBUS-1)) michael@0: #endif michael@0: |(1<<(SIGILL-1)) michael@0: |(1<<(SIGSEGV-1)) michael@0: |(1<<(SIGHUP-1)) michael@0: |(1<<(SIGPIPE-1)) michael@0: #ifdef SIGSYS michael@0: |(1<<(SIGSYS-1)) michael@0: #endif michael@0: ); michael@0: #endif /* _POSIX_SOURCE */ michael@0: sig_act.sa_flags = 0; michael@0: sigaction(SIGHUP, &sig_act, (struct sigaction *)0); michael@0: sigaction(SIGINT, &sig_act, (struct sigaction *)0); michael@0: sigaction(SIGQUIT, &sig_act, (struct sigaction *)0); michael@0: sigaction(SIGILL, &sig_act, (struct sigaction *)0); michael@0: #ifdef SIGBUS michael@0: sigaction(SIGBUS, &sig_act, (struct sigaction *)0); michael@0: #endif michael@0: sigaction(SIGSEGV, &sig_act, (struct sigaction *)0); michael@0: #ifdef SIGSYS michael@0: sigaction(SIGSYS, &sig_act, (struct sigaction *)0); michael@0: #endif michael@0: #endif /* USGISH */ michael@0: michael@0: /* michael@0: * now peruse through the list of files. michael@0: */ michael@0: for(fp=filelist; *fp; fp++) { michael@0: DBG_PRINT(stderr,"file: %s\n",*fp); michael@0: filecontent = getfile(*fp); michael@0: setfile_cmdinc(filecontent, cmdinc_count, cmdinc_list); michael@0: ip = newinclude(*fp, (char *)NULL); michael@0: michael@0: find_includes(filecontent, ip, ip, 0, FALSE); michael@0: freefile(filecontent); michael@0: recursive_pr_include(ip, ip->i_file, base_name(*fp)); michael@0: inc_clean(); michael@0: } michael@0: if (printed) michael@0: printf("\n"); michael@0: return 0; michael@0: } michael@0: michael@0: #ifdef __UNIXOS2__ michael@0: /* michael@0: * eliminate \r chars from file michael@0: */ michael@0: static int michael@0: elim_cr(char *buf, int sz) michael@0: { michael@0: int i,wp; michael@0: for (i= wp = 0; if_name = file; michael@0: if ((fd = open(file, O_RDONLY)) < 0) { michael@0: warning("cannot open \"%s\"\n", file); michael@0: content->f_p = content->f_base = content->f_end = (char *)malloc(1); michael@0: *content->f_p = '\0'; michael@0: return(content); michael@0: } michael@0: fstat(fd, &st); michael@0: content->f_base = (char *)malloc(st.st_size+1); michael@0: if (content->f_base == NULL) michael@0: fatalerr("cannot allocate mem\n"); michael@0: if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0) michael@0: fatalerr("failed to read %s\n", file); michael@0: #ifdef __UNIXOS2__ michael@0: st.st_size = elim_cr(content->f_base,st.st_size); michael@0: #endif michael@0: close(fd); michael@0: content->f_len = st.st_size+1; michael@0: content->f_p = content->f_base; michael@0: content->f_end = content->f_base + st.st_size; michael@0: *content->f_end = '\0'; michael@0: content->f_line = 0; michael@0: content->cmdinc_count = 0; michael@0: content->cmdinc_list = NULL; michael@0: content->cmdinc_line = 0; michael@0: return(content); michael@0: } michael@0: michael@0: void michael@0: setfile_cmdinc(struct filepointer* filep, long count, char** list) michael@0: { michael@0: filep->cmdinc_count = count; michael@0: filep->cmdinc_list = list; michael@0: filep->cmdinc_line = 0; michael@0: } michael@0: michael@0: void michael@0: freefile(struct filepointer *fp) michael@0: { michael@0: free(fp->f_base); michael@0: free(fp); michael@0: } michael@0: michael@0: char *copy(char *str) michael@0: { michael@0: char *p = (char *)malloc(strlen(str) + 1); michael@0: michael@0: strcpy(p, str); michael@0: return(p); michael@0: } michael@0: michael@0: int michael@0: match(char *str, char **list) michael@0: { michael@0: int i; michael@0: michael@0: for (i=0; *list; i++, list++) michael@0: if (strcmp(str, *list) == 0) michael@0: return(i); michael@0: return(-1); michael@0: } michael@0: michael@0: /* michael@0: * Get the next line. We only return lines beginning with '#' since that michael@0: * is all this program is ever interested in. michael@0: */ michael@0: char *getnextline(struct filepointer *filep) michael@0: { michael@0: char *p, /* walking pointer */ michael@0: *eof, /* end of file pointer */ michael@0: *bol; /* beginning of line pointer */ michael@0: int lineno; /* line number */ michael@0: boolean whitespace = FALSE; michael@0: michael@0: /* michael@0: * Fake the "-include" line files in form of #include to the michael@0: * start of each file. michael@0: */ michael@0: if (filep->cmdinc_line < filep->cmdinc_count) { michael@0: char *inc = filep->cmdinc_list[2 * filep->cmdinc_line + 0]; michael@0: char *buf = filep->cmdinc_list[2 * filep->cmdinc_line + 1]; michael@0: filep->cmdinc_line++; michael@0: sprintf(buf,"%s%s%s",DASH_INC_PRE,inc,DASH_INC_POST); michael@0: DBG_PRINT(stderr,"%s\n",buf); michael@0: return(buf); michael@0: } michael@0: michael@0: p = filep->f_p; michael@0: eof = filep->f_end; michael@0: if (p >= eof) michael@0: return((char *)NULL); michael@0: lineno = filep->f_line; michael@0: michael@0: for (bol = p--; ++p < eof; ) { michael@0: if ((bol == p) && ((*p == ' ') || (*p == '\t'))) michael@0: { michael@0: /* Consume leading white-spaces for this line */ michael@0: while (((p+1) < eof) && ((*p == ' ') || (*p == '\t'))) michael@0: { michael@0: p++; michael@0: bol++; michael@0: } michael@0: whitespace = TRUE; michael@0: } michael@0: michael@0: if (*p == '/' && (p+1) < eof && *(p+1) == '*') { michael@0: /* Consume C comments */ michael@0: *(p++) = ' '; michael@0: *(p++) = ' '; michael@0: while (p < eof && *p) { michael@0: if (*p == '*' && (p+1) < eof && *(p+1) == '/') { michael@0: *(p++) = ' '; michael@0: *(p++) = ' '; michael@0: break; michael@0: } michael@0: if (*p == '\n') michael@0: lineno++; michael@0: *(p++) = ' '; michael@0: } michael@0: --p; michael@0: } michael@0: else if (*p == '/' && (p+1) < eof && *(p+1) == '/') { michael@0: /* Consume C++ comments */ michael@0: *(p++) = ' '; michael@0: *(p++) = ' '; michael@0: while (p < eof && *p) { michael@0: if (*p == '\\' && (p+1) < eof && michael@0: *(p+1) == '\n') { michael@0: *(p++) = ' '; michael@0: lineno++; michael@0: } michael@0: else if (*p == '?' && (p+3) < eof && michael@0: *(p+1) == '?' && michael@0: *(p+2) == '/' && michael@0: *(p+3) == '\n') { michael@0: *(p++) = ' '; michael@0: *(p++) = ' '; michael@0: *(p++) = ' '; michael@0: lineno++; michael@0: } michael@0: else if (*p == '\n') michael@0: break; /* to process end of line */ michael@0: *(p++) = ' '; michael@0: } michael@0: --p; michael@0: } michael@0: else if (*p == '\\' && (p+1) < eof && *(p+1) == '\n') { michael@0: /* Consume backslash line terminations */ michael@0: *(p++) = ' '; michael@0: *p = ' '; michael@0: lineno++; michael@0: } michael@0: else if (*p == '?' && (p+3) < eof && michael@0: *(p+1) == '?' && *(p+2) == '/' && *(p+3) == '\n') { michael@0: /* Consume trigraph'ed backslash line terminations */ michael@0: *(p++) = ' '; michael@0: *(p++) = ' '; michael@0: *(p++) = ' '; michael@0: *p = ' '; michael@0: lineno++; michael@0: } michael@0: else if (*p == '\n') { michael@0: lineno++; michael@0: if (*bol == '#') { michael@0: char *cp; michael@0: michael@0: *(p++) = '\0'; michael@0: /* punt lines with just # (yacc generated) */ michael@0: for (cp = bol+1; michael@0: *cp && (*cp == ' ' || *cp == '\t'); cp++); michael@0: if (*cp) goto done; michael@0: --p; michael@0: } michael@0: bol = p+1; michael@0: whitespace = FALSE; michael@0: } michael@0: } michael@0: if (*bol != '#') michael@0: bol = NULL; michael@0: done: michael@0: #if !defined(__UNIXOS2__) && !defined(_MSC_VER) && !defined(_WIN32) michael@0: /* Don't print warnings for system header files */ michael@0: if (bol && whitespace && !strstr(filep->f_name, INCLUDEDIR)) { michael@0: warning("%s: non-portable whitespace encountered at line %d\n", michael@0: filep->f_name, lineno); michael@0: } michael@0: #endif michael@0: filep->f_p = p; michael@0: filep->f_line = lineno; michael@0: #ifdef DEBUG_DUMP michael@0: if (bol) michael@0: DBG_PRINT(stderr,"%s\n",bol); michael@0: #endif michael@0: return(bol); michael@0: } michael@0: michael@0: /* michael@0: * Strip the file name down to what we want to see in the Makefile. michael@0: * It will have objprefix and objsuffix around it. michael@0: */ michael@0: char *base_name(char *file) michael@0: { michael@0: char *p; michael@0: michael@0: file = copy(file); michael@0: for(p=file+strlen(file); p>file && *p != '.'; p--) ; michael@0: michael@0: if (*p == '.') michael@0: *p = '\0'; michael@0: return(file); michael@0: } michael@0: michael@0: #if defined(USG) && !defined(CRAY) && !defined(SVR4) && !defined(__UNIXOS2__) && !defined(clipper) && !defined(__clipper__) michael@0: int rename (char *from, char *to) michael@0: { michael@0: (void) unlink (to); michael@0: if (link (from, to) == 0) { michael@0: unlink (from); michael@0: return 0; michael@0: } else { michael@0: return -1; michael@0: } michael@0: } michael@0: #endif /* USGISH */ michael@0: michael@0: void michael@0: redirect(char *line, char *makefile) michael@0: { michael@0: struct stat st; michael@0: FILE *fdin, *fdout; michael@0: char backup[ BUFSIZ ], michael@0: buf[ BUFSIZ ]; michael@0: boolean found = FALSE; michael@0: int len; michael@0: michael@0: /* michael@0: * if makefile is "-" then let it pour onto stdout. michael@0: */ michael@0: if (makefile && *makefile == '-' && *(makefile+1) == '\0') { michael@0: puts(line); michael@0: return; michael@0: } michael@0: michael@0: /* michael@0: * use a default makefile is not specified. michael@0: */ michael@0: if (!makefile) { michael@0: if (stat("Makefile", &st) == 0) michael@0: makefile = "Makefile"; michael@0: else if (stat("makefile", &st) == 0) michael@0: makefile = "makefile"; michael@0: else michael@0: fatalerr("[mM]akefile is not present\n"); michael@0: } michael@0: else michael@0: stat(makefile, &st); michael@0: if ((fdin = fopen(makefile, "r")) == NULL) michael@0: fatalerr("cannot open \"%s\"\n", makefile); michael@0: sprintf(backup, "%s.bak", makefile); michael@0: unlink(backup); michael@0: #if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__) michael@0: fclose(fdin); michael@0: #endif michael@0: if (rename(makefile, backup) < 0) michael@0: fatalerr("cannot rename %s to %s\n", makefile, backup); michael@0: #if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__) michael@0: if ((fdin = fopen(backup, "r")) == NULL) michael@0: fatalerr("cannot open \"%s\"\n", backup); michael@0: #endif michael@0: if ((fdout = freopen(makefile, "w", stdout)) == NULL) michael@0: fatalerr("cannot open \"%s\"\n", backup); michael@0: len = strlen(line); michael@0: while (!found && fgets(buf, BUFSIZ, fdin)) { michael@0: if (*buf == '#' && strncmp(line, buf, len) == 0) michael@0: found = TRUE; michael@0: fputs(buf, fdout); michael@0: } michael@0: if (!found) { michael@0: if (verbose) michael@0: warning("Adding new delimiting line \"%s\" and dependencies...\n", michael@0: line); michael@0: puts(line); /* same as fputs(fdout); but with newline */ michael@0: } else if (append) { michael@0: while (fgets(buf, BUFSIZ, fdin)) { michael@0: fputs(buf, fdout); michael@0: } michael@0: } michael@0: fflush(fdout); michael@0: #if defined(USGISH) || defined(_SEQUENT_) || defined(USE_CHMOD) michael@0: chmod(makefile, st.st_mode); michael@0: #else michael@0: fchmod(fileno(fdout), st.st_mode); michael@0: #endif /* USGISH */ michael@0: } michael@0: michael@0: void michael@0: fatalerr(char *msg, ...) michael@0: { michael@0: va_list args; michael@0: fprintf(stderr, "%s: error: ", ProgramName); michael@0: va_start(args, msg); michael@0: vfprintf(stderr, msg, args); michael@0: va_end(args); michael@0: exit (1); michael@0: } michael@0: michael@0: void michael@0: warning(char *msg, ...) michael@0: { michael@0: va_list args; michael@0: fprintf(stderr, "%s: warning: ", ProgramName); michael@0: va_start(args, msg); michael@0: vfprintf(stderr, msg, args); michael@0: va_end(args); michael@0: } michael@0: michael@0: void michael@0: warning1(char *msg, ...) michael@0: { michael@0: va_list args; michael@0: va_start(args, msg); michael@0: vfprintf(stderr, msg, args); michael@0: va_end(args); michael@0: }