1 /* $Xorg: main.c,v 1.3 2000/08/17 19:41:51 cpqbld Exp $ */
4 Copyright (c) 1993, 1994, 1998 The Open Group
8 The above copyright notice and this permission notice shall be included in
9 all copies or substantial portions of the Software.
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14 THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
15 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 Except as contained in this notice, the name of The Open Group shall not be
19 used in advertising or otherwise to promote the sale, use or other dealings
20 in this Software without prior written authorization from The Open Group.
23 /* $XFree86: xc/config/makedepend/main.c,v 3.22 2001/07/25 15:04:40 dawes Exp $ */
27 #define sigvec sigvector
30 #ifdef X_POSIX_C_SOURCE
31 #define _POSIX_C_SOURCE X_POSIX_C_SOURCE
33 #undef _POSIX_C_SOURCE
35 #if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
56 char *directives
[] = {
78 #include "imakemdep.h" /* from config sources */
81 struct inclist inclist
[ MAXFILES
],
83 *inclistnext
= inclist
,
86 char *filelist
[ MAXFILES
];
87 char *includedirs
[ MAXDIRS
+ 1 ],
88 **includedirsnext
= includedirs
;
89 char *notdotdot
[ MAXDIRS
];
91 char *objsuffix
= OBJSUFFIX
;
92 char *startat
= "# DO NOT DELETE";
94 boolean append
= FALSE
;
95 boolean printed
= FALSE
;
96 boolean verbose
= FALSE
;
97 boolean show_where_not
= FALSE
;
98 boolean warn_multiple
= FALSE
; /* Warn on multiple includes of same file */
100 static void redirect(char *line
, char *makefile
);
103 #ifdef SIGNALRETURNSINT
111 fatalerr ("got signal %d\n", sig
);
114 #if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(__EMX__) || defined(Lynx_22) || defined(__CYGWIN__)
120 #define sigaction sigvec
121 #define sa_handler sv_handler
122 #define sa_mask sv_mask
123 #define sa_flags sv_flags
125 struct sigaction sig_act
;
129 main(int argc
, char *argv
[])
131 char **fp
= filelist
;
132 char **incp
= includedirs
;
135 char *makefile
= NULL
;
136 struct filepointer
*filecontent
;
137 struct symtab
*psymp
= predefs
;
138 char *endmarker
= NULL
;
139 char *defincdir
= NULL
;
140 char **undeflist
= NULL
;
141 int numundefs
= 0, i
;
143 ProgramName
= argv
[0];
145 while (psymp
->s_name
)
147 define2(psymp
->s_name
, psymp
->s_value
, &maininclist
);
150 if (argc
== 2 && argv
[1][0] == '@') {
156 char quotechar
= '\0';
159 if ((afd
= open(argv
[1]+1, O_RDONLY
)) < 0)
160 fatalerr("cannot open \"%s\"\n", argv
[1]+1);
162 args
= (char *)malloc(ast
.st_size
+ 1);
163 if ((ast
.st_size
= read(afd
, args
, ast
.st_size
)) < 0)
164 fatalerr("failed to read %s\n", argv
[1]+1);
165 args
[ast
.st_size
] = '\0';
167 for (p
= args
; *p
; p
++) {
169 if (quotechar
== '\\' ||
170 (*p
== quotechar
&& p
[-1] != '\\'))
183 if (p
> args
&& p
[-1])
190 nargv
= (char **)malloc(nargc
* sizeof(char *));
193 for (p
= args
; argc
< nargc
; p
+= strlen(p
) + 1)
194 if (*p
) nargv
[argc
++] = p
;
197 for(argc
--, argv
++; argc
; argc
--, argv
++) {
198 /* if looking for endmarker then check before parsing */
199 if (endmarker
&& strcmp (endmarker
, *argv
) == 0) {
204 /* treat +thing as an option for C++ */
205 if (endmarker
&& **argv
== '+')
212 endmarker
= &argv
[0][2];
213 if (endmarker
[0] == '\0') endmarker
= "--";
216 if (argv
[0][2] == '\0') {
220 for (p
=argv
[0] + 2; *p
; p
++)
225 define(argv
[0] + 2, &maininclist
);
228 if (incp
>= includedirs
+ MAXDIRS
)
229 fatalerr("Too many -I flags.\n");
231 if (**(incp
-1) == '\0') {
232 *(incp
-1) = *(++argv
);
237 /* Undef's override all -D's so save them up */
240 undeflist
= malloc(sizeof(char *));
242 undeflist
= realloc(undeflist
,
243 numundefs
* sizeof(char *));
244 if (argv
[0][2] == '\0') {
248 undeflist
[numundefs
- 1] = argv
[0] + 2;
251 defincdir
= argv
[0]+2;
253 /* do not use if endmarker processing */
255 if (endmarker
) break;
259 if (endmarker
) break;
260 if (argv
[0][2] == '\0') {
263 width
= atoi(argv
[0]);
265 width
= atoi(argv
[0]+2);
268 if (endmarker
) break;
269 if (argv
[0][2] == '\0') {
274 objsuffix
= argv
[0]+2;
277 if (endmarker
) break;
278 if (argv
[0][2] == '\0') {
283 objprefix
= argv
[0]+2;
286 if (endmarker
) break;
290 _debugmask
= atoi(argv
[0]+2);
294 if (endmarker
) break;
296 if (*startat
== '\0') {
301 fatalerr("-s flag's value should start %s\n",
305 if (endmarker
) break;
306 makefile
= argv
[0]+2;
307 if (*makefile
== '\0') {
308 makefile
= *(++argv
);
314 warn_multiple
= TRUE
;
317 /* Ignore -O, -g so we can just pass ${CFLAGS} to
324 if (endmarker
) break;
325 /* fatalerr("unknown opt = %s\n", argv[0]); */
326 warning("ignoring option %s\n", argv
[0]);
329 /* Now do the undefs from the command line */
330 for (i
= 0; i
< numundefs
; i
++)
331 undefine(undeflist
[i
], &maininclist
);
337 if (incp
>= includedirs
+ MAXDIRS
)
338 fatalerr("Too many -I flags.\n");
343 char *emxinc
= getenv("C_INCLUDE_PATH");
344 /* can have more than one component */
347 beg
= (char*)strdup(emxinc
);
349 end
= (char*)strchr(beg
,';');
351 if (incp
>= includedirs
+ MAXDIRS
)
352 fatalerr("Too many include dirs\n");
359 #else /* !__EMX__, does not use INCLUDEDIR at all */
360 if (incp
>= includedirs
+ MAXDIRS
)
361 fatalerr("Too many -I flags.\n");
362 *incp
++ = INCLUDEDIR
;
366 if (incp
>= includedirs
+ MAXDIRS
)
367 fatalerr("Too many -I flags.\n");
368 *incp
++ = EXTRAINCDIR
;
372 if (incp
>= includedirs
+ MAXDIRS
)
373 fatalerr("Too many -I flags.\n");
374 *incp
++ = POSTINCDIR
;
376 } else if (*defincdir
) {
377 if (incp
>= includedirs
+ MAXDIRS
)
378 fatalerr("Too many -I flags.\n");
382 redirect(startat
, makefile
);
388 /* should really reset SIGINT to SIG_IGN if it was. */
390 signal (SIGHUP
, catch);
392 signal (SIGINT
, catch);
394 signal (SIGQUIT
, catch);
396 signal (SIGILL
, catch);
398 signal (SIGBUS
, catch);
400 signal (SIGSEGV
, catch);
402 signal (SIGSYS
, catch);
405 sig_act
.sa_handler
= catch;
406 #if defined(_POSIX_SOURCE) || !defined(X_NOT_POSIX)
407 sigemptyset(&sig_act
.sa_mask
);
408 sigaddset(&sig_act
.sa_mask
, SIGINT
);
409 sigaddset(&sig_act
.sa_mask
, SIGQUIT
);
411 sigaddset(&sig_act
.sa_mask
, SIGBUS
);
413 sigaddset(&sig_act
.sa_mask
, SIGILL
);
414 sigaddset(&sig_act
.sa_mask
, SIGSEGV
);
415 sigaddset(&sig_act
.sa_mask
, SIGHUP
);
416 sigaddset(&sig_act
.sa_mask
, SIGPIPE
);
418 sigaddset(&sig_act
.sa_mask
, SIGSYS
);
421 sig_act
.sa_mask
= ((1<<(SIGINT
-1))
434 #endif /* _POSIX_SOURCE */
435 sig_act
.sa_flags
= 0;
436 sigaction(SIGHUP
, &sig_act
, (struct sigaction
*)0);
437 sigaction(SIGINT
, &sig_act
, (struct sigaction
*)0);
438 sigaction(SIGQUIT
, &sig_act
, (struct sigaction
*)0);
439 sigaction(SIGILL
, &sig_act
, (struct sigaction
*)0);
441 sigaction(SIGBUS
, &sig_act
, (struct sigaction
*)0);
443 sigaction(SIGSEGV
, &sig_act
, (struct sigaction
*)0);
445 sigaction(SIGSYS
, &sig_act
, (struct sigaction
*)0);
450 * now peruse through the list of files.
452 for(fp
=filelist
; *fp
; fp
++) {
453 filecontent
= getfile(*fp
);
454 ip
= newinclude(*fp
, (char *)NULL
);
456 find_includes(filecontent
, ip
, ip
, 0, FALSE
);
457 freefile(filecontent
);
458 recursive_pr_include(ip
, ip
->i_file
, base_name(*fp
));
468 * eliminate \r chars from file
471 elim_cr(char *buf
, int sz
)
474 for (i
= wp
= 0; i
<sz
; i
++) {
486 struct filepointer
*content
;
489 content
= (struct filepointer
*)malloc(sizeof(struct filepointer
));
490 if ((fd
= open(file
, O_RDONLY
)) < 0) {
491 warning("cannot open \"%s\"\n", file
);
492 content
->f_p
= content
->f_base
= content
->f_end
= (char *)malloc(1);
493 *content
->f_p
= '\0';
497 content
->f_base
= (char *)malloc(st
.st_size
+1);
498 if (content
->f_base
== NULL
)
499 fatalerr("cannot allocate mem\n");
500 if ((st
.st_size
= read(fd
, content
->f_base
, st
.st_size
)) < 0)
501 fatalerr("failed to read %s\n", file
);
503 st
.st_size
= elim_cr(content
->f_base
,st
.st_size
);
506 content
->f_len
= st
.st_size
+1;
507 content
->f_p
= content
->f_base
;
508 content
->f_end
= content
->f_base
+ st
.st_size
;
509 *content
->f_end
= '\0';
515 freefile(struct filepointer
*fp
)
521 char *copy(char *str
)
523 char *p
= (char *)malloc(strlen(str
) + 1);
530 match(char *str
, char **list
)
534 for (i
=0; *list
; i
++, list
++)
535 if (strcmp(str
, *list
) == 0)
541 * Get the next line. We only return lines beginning with '#' since that
542 * is all this program is ever interested in.
544 char *getnextline(struct filepointer
*filep
)
546 char *p
, /* walking pointer */
547 *eof
, /* end of file pointer */
548 *bol
; /* beginning of line pointer */
549 int lineno
; /* line number */
554 return((char *)NULL
);
555 lineno
= filep
->f_line
;
557 for(bol
= p
--; ++p
< eof
; ) {
558 if (*p
== '/' && *(p
+1) == '*') { /* consume comments */
559 *p
++ = ' ', *p
++ = ' ';
561 if (*p
== '*' && *(p
+1) == '/') {
562 *p
++ = ' ', *p
= ' ';
571 else if (*p
== '/' && *(p
+1) == '/') { /* consume comments */
572 *p
++ = ' ', *p
++ = ' ';
573 while (*p
&& *p
!= '\n')
578 else if (*p
== '\\') {
579 if (*(p
+1) == '\n') {
585 else if (*p
== '\n') {
591 /* punt lines with just # (yacc generated) */
593 *cp
&& (*cp
== ' ' || *cp
== '\t'); cp
++);
604 filep
->f_line
= lineno
;
609 * Strip the file name down to what we want to see in the Makefile.
610 * It will have objprefix and objsuffix around it.
612 char *base_name(char *file
)
617 for(p
=file
+strlen(file
); p
>file
&& *p
!= '.'; p
--) ;
624 #if defined(USG) && !defined(CRAY) && !defined(SVR4) && !defined(__EMX__) && !defined(clipper) && !defined(__clipper__)
625 int rename (char *from
, char *to
)
628 if (link (from
, to
) == 0) {
638 redirect(char *line
, char *makefile
)
642 char backup
[ BUFSIZ
],
644 boolean found
= FALSE
;
648 * if makefile is "-" then let it pour onto stdout.
650 if (makefile
&& *makefile
== '-' && *(makefile
+1) == '\0') {
656 * use a default makefile is not specified.
659 if (stat("Makefile", &st
) == 0)
660 makefile
= "Makefile";
661 else if (stat("makefile", &st
) == 0)
662 makefile
= "makefile";
664 fatalerr("[mM]akefile is not present\n");
668 if ((fdin
= fopen(makefile
, "r")) == NULL
)
669 fatalerr("cannot open \"%s\"\n", makefile
);
670 sprintf(backup
, "%s.bak", makefile
);
672 #if defined(WIN32) || defined(__EMX__) || defined(__CYGWIN__)
675 if (rename(makefile
, backup
) < 0)
676 fatalerr("cannot rename %s to %s\n", makefile
, backup
);
677 #if defined(WIN32) || defined(__EMX__) || defined(__CYGWIN__)
678 if ((fdin
= fopen(backup
, "r")) == NULL
)
679 fatalerr("cannot open \"%s\"\n", backup
);
681 if ((fdout
= freopen(makefile
, "w", stdout
)) == NULL
)
682 fatalerr("cannot open \"%s\"\n", backup
);
684 while (!found
&& fgets(buf
, BUFSIZ
, fdin
)) {
685 if (*buf
== '#' && strncmp(line
, buf
, len
) == 0)
691 warning("Adding new delimiting line \"%s\" and dependencies...\n",
693 puts(line
); /* same as fputs(fdout); but with newline */
695 while (fgets(buf
, BUFSIZ
, fdin
)) {
700 #if defined(USGISH) || defined(_SEQUENT_) || defined(USE_CHMOD)
701 chmod(makefile
, st
.st_mode
);
703 fchmod(fileno(fdout
), st
.st_mode
);
708 fatalerr(char *msg
, ...)
711 fprintf(stderr
, "%s: error: ", ProgramName
);
713 vfprintf(stderr
, msg
, args
);
719 warning(char *msg
, ...)
722 fprintf(stderr
, "%s: warning: ", ProgramName
);
724 vfprintf(stderr
, msg
, args
);
729 warning1(char *msg
, ...)
733 vfprintf(stderr
, msg
, args
);