1
/* $Xorg: main.c,v 1.5 2001/02/09 02:03:16 xorgcvs Exp $ */
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
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.
27
/* $XFree86: xc/config/makedepend/main.c,v 3.32 2003/03/26 20:43:48 tsi Exp $ */
31
#define sigvec sigvector
34
#ifdef X_POSIX_C_SOURCE
35
#define _POSIX_C_SOURCE X_POSIX_C_SOURCE
37
#undef _POSIX_C_SOURCE
39
#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
58
/* #define DEBUG_DUMP */
60
#define DBG_PRINT(file, fmt, args) fprintf(file, fmt, args)
62
#define DBG_PRINT(file, fmt, args) /* empty */
65
#define DASH_INC_PRE "#include \""
66
#define DASH_INC_POST "\""
70
char *directives[] = {
92
#include "imakemdep.h" /* from config sources */
95
struct inclist inclist[ MAXFILES ],
97
*inclistnext = inclist,
100
static char *filelist[ MAXFILES ];
101
char *includedirs[ MAXDIRS + 1 ],
102
**includedirsnext = includedirs;
103
char *notdotdot[ MAXDIRS ];
104
static int cmdinc_count = 0;
105
static char *cmdinc_list[ 2 * MAXINCFILES ];
106
char *objprefix = "";
107
char *objsuffix = OBJSUFFIX;
108
static char *startat = "# DO NOT DELETE";
110
static boolean append = FALSE;
111
boolean printed = FALSE;
112
boolean verbose = FALSE;
113
boolean show_where_not = FALSE;
114
/* Warn on multiple includes of same file */
115
boolean warn_multiple = FALSE;
117
static void setfile_cmdinc(struct filepointer *filep, long count, char **list);
118
static void redirect(char *line, char *makefile);
121
#ifdef SIGNALRETURNSINT
129
fatalerr ("got signal %d\n", sig);
132
#if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(__UNIXOS2__) || defined(Lynx_22) || defined(__CYGWIN__)
138
#define sigaction sigvec
139
#define sa_handler sv_handler
140
#define sa_mask sv_mask
141
#define sa_flags sv_flags
143
struct sigaction sig_act;
147
main(int argc, char *argv[])
149
char **fp = filelist;
150
char **incp = includedirs;
153
char *makefile = NULL;
154
struct filepointer *filecontent;
155
struct symtab *psymp = predefs;
156
char *endmarker = NULL;
157
char *defincdir = NULL;
158
char **undeflist = NULL;
159
int numundefs = 0, i;
160
register char offset;
162
ProgramName = argv[0];
164
while (psymp->s_name)
166
define2(psymp->s_name, psymp->s_value, &maininclist);
169
if (argc == 2 && argv[1][0] == '@') {
175
char quotechar = '\0';
178
if ((afd = open(argv[1]+1, O_RDONLY)) < 0)
179
fatalerr("cannot open \"%s\"\n", argv[1]+1);
181
args = (char *)malloc(ast.st_size + 1);
182
if ((ast.st_size = read(afd, args, ast.st_size)) < 0)
183
fatalerr("failed to read %s\n", argv[1]+1);
184
args[ast.st_size] = '\0';
186
for (p = args; *p; p++) {
188
if (quotechar == '\\' ||
189
(*p == quotechar && p[-1] != '\\'))
202
if (p > args && p[-1])
209
nargv = (char **)malloc(nargc * sizeof(char *));
212
for (p = args; argc < nargc; p += strlen(p) + 1)
213
if (*p) nargv[argc++] = p;
216
for(argc--, argv++; argc; argc--, argv++) {
217
/* if looking for endmarker then check before parsing */
218
if (endmarker && strcmp (endmarker, *argv) == 0) {
223
/* treat +thing as an option for C++ */
224
if (endmarker && **argv == '+')
231
endmarker = &argv[0][2];
232
if (endmarker[0] == '\0') endmarker = "--";
236
if (argv[0][2] == '\0') {
241
/* offset +1 here since first def letter
244
for (p = argv[0] + offset + 1; *p; p++)
249
define(argv[0] + offset, &maininclist);
252
if (incp >= includedirs + MAXDIRS)
253
fatalerr("Too many -I flags.\n");
255
if (**(incp-1) == '\0') {
256
*(incp-1) = *(++argv);
261
/* Undef's override all -D's so save them up */
264
undeflist = malloc(sizeof(char *));
266
undeflist = realloc(undeflist,
267
numundefs * sizeof(char *));
269
if (argv[0][2] == '\0') {
274
undeflist[numundefs - 1] = argv[0] + offset;
277
defincdir = argv[0]+2;
279
/* do not use if endmarker processing */
281
if (endmarker) break;
285
if (endmarker) break;
286
if (argv[0][2] == '\0') {
289
width = atoi(argv[0]);
291
width = atoi(argv[0]+2);
294
if (endmarker) break;
295
if (argv[0][2] == '\0') {
300
objsuffix = argv[0]+2;
303
if (endmarker) break;
304
if (argv[0][2] == '\0') {
309
objprefix = argv[0]+2;
312
if (endmarker) break;
316
_debugmask = atoi(argv[0]+2);
320
if (endmarker) break;
322
if (*startat == '\0') {
327
fatalerr("-s flag's value should start %s\n",
331
if (endmarker) break;
332
makefile = argv[0]+2;
333
if (*makefile == '\0') {
334
makefile = *(++argv);
340
warn_multiple = TRUE;
343
/* Ignore -O, -g so we can just pass ${CFLAGS} to
350
if (strcmp(&argv[0][1],"include") == 0) {
353
fatalerr("option -include is a "
354
"missing its parameter\n");
355
if (cmdinc_count >= MAXINCFILES)
356
fatalerr("Too many -include flags.\n");
359
buf = malloc(strlen(DASH_INC_PRE) +
361
strlen(DASH_INC_POST) + 1);
363
fatalerr("out of memory at "
364
"-include string\n");
365
cmdinc_list[2 * cmdinc_count + 0] = argv[0];
366
cmdinc_list[2 * cmdinc_count + 1] = buf;
370
/* intentional fall through */
372
if (endmarker) break;
373
/* fatalerr("unknown opt = %s\n", argv[0]); */
374
warning("ignoring option %s\n", argv[0]);
377
/* Now do the undefs from the command line */
378
for (i = 0; i < numundefs; i++)
379
undefine(undeflist[i], &maininclist);
385
if (incp >= includedirs + MAXDIRS)
386
fatalerr("Too many -I flags.\n");
391
char *emxinc = getenv("C_INCLUDE_PATH");
392
/* can have more than one component */
395
beg= (char*)strdup(emxinc);
397
end = (char*)strchr(beg,';');
399
if (incp >= includedirs + MAXDIRS)
400
fatalerr("Too many include dirs\n");
407
#else /* !__UNIXOS2__, does not use INCLUDEDIR at all */
408
if (incp >= includedirs + MAXDIRS)
409
fatalerr("Too many -I flags.\n");
410
*incp++ = INCLUDEDIR;
414
if (incp >= includedirs + MAXDIRS)
415
fatalerr("Too many -I flags.\n");
416
*incp++ = EXTRAINCDIR;
420
if (incp >= includedirs + MAXDIRS)
421
fatalerr("Too many -I flags.\n");
422
*incp++ = POSTINCDIR;
424
} else if (*defincdir) {
425
if (incp >= includedirs + MAXDIRS)
426
fatalerr("Too many -I flags.\n");
430
redirect(startat, makefile);
436
/* should really reset SIGINT to SIG_IGN if it was. */
438
signal (SIGHUP, catch);
440
signal (SIGINT, catch);
442
signal (SIGQUIT, catch);
444
signal (SIGILL, catch);
446
signal (SIGBUS, catch);
448
signal (SIGSEGV, catch);
450
signal (SIGSYS, catch);
453
sig_act.sa_handler = catch;
454
#if defined(_POSIX_SOURCE) || !defined(X_NOT_POSIX)
455
sigemptyset(&sig_act.sa_mask);
456
sigaddset(&sig_act.sa_mask, SIGINT);
457
sigaddset(&sig_act.sa_mask, SIGQUIT);
459
sigaddset(&sig_act.sa_mask, SIGBUS);
461
sigaddset(&sig_act.sa_mask, SIGILL);
462
sigaddset(&sig_act.sa_mask, SIGSEGV);
463
sigaddset(&sig_act.sa_mask, SIGHUP);
464
sigaddset(&sig_act.sa_mask, SIGPIPE);
466
sigaddset(&sig_act.sa_mask, SIGSYS);
469
sig_act.sa_mask = ((1<<(SIGINT -1))
482
#endif /* _POSIX_SOURCE */
483
sig_act.sa_flags = 0;
484
sigaction(SIGHUP, &sig_act, (struct sigaction *)0);
485
sigaction(SIGINT, &sig_act, (struct sigaction *)0);
486
sigaction(SIGQUIT, &sig_act, (struct sigaction *)0);
487
sigaction(SIGILL, &sig_act, (struct sigaction *)0);
489
sigaction(SIGBUS, &sig_act, (struct sigaction *)0);
491
sigaction(SIGSEGV, &sig_act, (struct sigaction *)0);
493
sigaction(SIGSYS, &sig_act, (struct sigaction *)0);
498
* now peruse through the list of files.
500
for(fp=filelist; *fp; fp++) {
501
DBG_PRINT(stderr,"file: %s\n",*fp);
502
filecontent = getfile(*fp);
503
setfile_cmdinc(filecontent, cmdinc_count, cmdinc_list);
504
ip = newinclude(*fp, (char *)NULL);
506
find_includes(filecontent, ip, ip, 0, FALSE);
507
freefile(filecontent);
508
recursive_pr_include(ip, ip->i_file, base_name(*fp));
518
* eliminate \r chars from file
521
elim_cr(char *buf, int sz)
524
for (i= wp = 0; i<sz; i++) {
536
struct filepointer *content;
539
content = (struct filepointer *)malloc(sizeof(struct filepointer));
540
content->f_name = file;
541
if ((fd = open(file, O_RDONLY)) < 0) {
542
warning("cannot open \"%s\"\n", file);
543
content->f_p = content->f_base = content->f_end = (char *)malloc(1);
544
*content->f_p = '\0';
548
content->f_base = (char *)malloc(st.st_size+1);
549
if (content->f_base == NULL)
550
fatalerr("cannot allocate mem\n");
551
if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0)
552
fatalerr("failed to read %s\n", file);
554
st.st_size = elim_cr(content->f_base,st.st_size);
557
content->f_len = st.st_size+1;
558
content->f_p = content->f_base;
559
content->f_end = content->f_base + st.st_size;
560
*content->f_end = '\0';
562
content->cmdinc_count = 0;
563
content->cmdinc_list = NULL;
564
content->cmdinc_line = 0;
569
setfile_cmdinc(struct filepointer* filep, long count, char** list)
571
filep->cmdinc_count = count;
572
filep->cmdinc_list = list;
573
filep->cmdinc_line = 0;
577
freefile(struct filepointer *fp)
583
char *copy(char *str)
585
char *p = (char *)malloc(strlen(str) + 1);
592
match(char *str, char **list)
596
for (i=0; *list; i++, list++)
597
if (strcmp(str, *list) == 0)
603
* Get the next line. We only return lines beginning with '#' since that
604
* is all this program is ever interested in.
606
char *getnextline(struct filepointer *filep)
608
char *p, /* walking pointer */
609
*eof, /* end of file pointer */
610
*bol; /* beginning of line pointer */
611
int lineno; /* line number */
612
boolean whitespace = FALSE;
615
* Fake the "-include" line files in form of #include to the
616
* start of each file.
618
if (filep->cmdinc_line < filep->cmdinc_count) {
619
char *inc = filep->cmdinc_list[2 * filep->cmdinc_line + 0];
620
char *buf = filep->cmdinc_list[2 * filep->cmdinc_line + 1];
621
filep->cmdinc_line++;
622
sprintf(buf,"%s%s%s",DASH_INC_PRE,inc,DASH_INC_POST);
623
DBG_PRINT(stderr,"%s\n",buf);
630
return((char *)NULL);
631
lineno = filep->f_line;
633
for (bol = p--; ++p < eof; ) {
634
if ((bol == p) && ((*p == ' ') || (*p == '\t')))
636
/* Consume leading white-spaces for this line */
637
while (((p+1) < eof) && ((*p == ' ') || (*p == '\t')))
645
if (*p == '/' && (p+1) < eof && *(p+1) == '*') {
646
/* Consume C comments */
649
while (p < eof && *p) {
650
if (*p == '*' && (p+1) < eof && *(p+1) == '/') {
661
else if (*p == '/' && (p+1) < eof && *(p+1) == '/') {
662
/* Consume C++ comments */
665
while (p < eof && *p) {
666
if (*p == '\\' && (p+1) < eof &&
671
else if (*p == '?' && (p+3) < eof &&
681
break; /* to process end of line */
686
else if (*p == '\\' && (p+1) < eof && *(p+1) == '\n') {
687
/* Consume backslash line terminations */
692
else if (*p == '?' && (p+3) < eof &&
693
*(p+1) == '?' && *(p+2) == '/' && *(p+3) == '\n') {
694
/* Consume trigraph'ed backslash line terminations */
701
else if (*p == '\n') {
707
/* punt lines with just # (yacc generated) */
709
*cp && (*cp == ' ' || *cp == '\t'); cp++);
720
if (bol && whitespace) {
721
warning("%s: non-portable whitespace encountered at line %d\n",
722
filep->f_name, lineno);
725
filep->f_line = lineno;
728
DBG_PRINT(stderr,"%s\n",bol);
734
* Strip the file name down to what we want to see in the Makefile.
735
* It will have objprefix and objsuffix around it.
737
char *base_name(char *file)
742
for(p=file+strlen(file); p>file && *p != '.'; p--) ;
749
#if defined(USG) && !defined(CRAY) && !defined(SVR4) && !defined(__UNIXOS2__) && !defined(clipper) && !defined(__clipper__)
750
int rename (char *from, char *to)
753
if (link (from, to) == 0) {
763
redirect(char *line, char *makefile)
767
char backup[ BUFSIZ ],
769
boolean found = FALSE;
773
* if makefile is "-" then let it pour onto stdout.
775
if (makefile && *makefile == '-' && *(makefile+1) == '\0') {
781
* use a default makefile is not specified.
784
if (stat("Makefile", &st) == 0)
785
makefile = "Makefile";
786
else if (stat("makefile", &st) == 0)
787
makefile = "makefile";
789
fatalerr("[mM]akefile is not present\n");
793
if ((fdin = fopen(makefile, "r")) == NULL)
794
fatalerr("cannot open \"%s\"\n", makefile);
795
sprintf(backup, "%s.bak", makefile);
797
#if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__)
800
if (rename(makefile, backup) < 0)
801
fatalerr("cannot rename %s to %s\n", makefile, backup);
802
#if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__)
803
if ((fdin = fopen(backup, "r")) == NULL)
804
fatalerr("cannot open \"%s\"\n", backup);
806
if ((fdout = freopen(makefile, "w", stdout)) == NULL)
807
fatalerr("cannot open \"%s\"\n", backup);
809
while (!found && fgets(buf, BUFSIZ, fdin)) {
810
if (*buf == '#' && strncmp(line, buf, len) == 0)
816
warning("Adding new delimiting line \"%s\" and dependencies...\n",
818
puts(line); /* same as fputs(fdout); but with newline */
820
while (fgets(buf, BUFSIZ, fdin)) {
825
#if defined(USGISH) || defined(_SEQUENT_) || defined(USE_CHMOD)
826
chmod(makefile, st.st_mode);
828
fchmod(fileno(fdout), st.st_mode);
833
fatalerr(char *msg, ...)
836
fprintf(stderr, "%s: error: ", ProgramName);
838
vfprintf(stderr, msg, args);
844
warning(char *msg, ...)
847
fprintf(stderr, "%s: warning: ", ProgramName);
849
vfprintf(stderr, msg, args);
854
warning1(char *msg, ...)
858
vfprintf(stderr, msg, args);