Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
/* $XConsortium: main.c /main/82 1995/11/07 19:47:02 gildea $ */
2
/*
3
Copyright (c) 1993, 1994  X Consortium
4
 
5
Permission is hereby granted, free of charge, to any person obtaining a copy
6
of this software and associated documentation files (the "Software"), to deal
7
in the Software without restriction, including without limitation the rights
8
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
copies of the Software, and to permit persons to whom the Software is
10
furnished to do so, subject to the following conditions:
11
 
12
The above copyright notice and this permission notice shall be included in
13
all copies or substantial portions of the Software.
14
 
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
X CONSORTIUM 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.
21
 
22
Except as contained in this notice, the name of the X Consortium 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 X Consortium.
25
 
26
      22/08/99 APY   MSDOS builds (using gcc),
27
                        import INCLUDE
28
                        convert '\' to '/' for gmake happy output.
29
                     -M switch
30
      25/08/99 APY   Allow multiple -Y definitions
31
      11/02/04 APY   -b, basename option
32
      16/02/04       --help, v2.1
33
      28/04/04       -W[1|2], quote whitespace,
34
                     - MAX_PATH cleanup (formal buffers sized by BUFSIZ)
35
                     - v2.20
36
      03/11/04       - Multiple -p definitions.
37
                     - MAXDIRS=256    
38
      04/11/04       - Correctly handle an empty INCLUDE vararg.
39
                     - More advanced cmdfile processor (see argv).
40
                     - v2.21
41
 
42
 $Source: /cvsroot/device/DEVL/UTILS/MKDEPEND/main.c,v $
43
 $Revision: 1.6 $ $Date: 2004/11/04 07:11:36 $ $State: Exp $
44
 $Author: ayoung $ $Locker:  $
45
 
46
*/
47
 
48
#define VMAJOR          2
49
#define VMINOR          25
50
 
51
#include "def.h"
52
#ifdef hpux
53
#define sigvec sigvector
54
#endif /* hpux */
55
 
56
#ifdef X_POSIX_C_SOURCE
57
#define _POSIX_C_SOURCE X_POSIX_C_SOURCE
58
#include <signal.h>
59
#undef _POSIX_C_SOURCE
60
#else
61
#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
62
#include <signal.h>
63
#else
64
#define _POSIX_SOURCE
65
#include <signal.h>
66
#undef _POSIX_SOURCE
67
#endif
68
#endif
69
 
70
#ifdef NeedVarargsPrototypes
71
#include <stdarg.h>
72
#endif
73
 
74
#ifdef DEBUG
75
int     _debugmask;
76
#endif
77
 
78
static const char *ProgramName, *ProgramPath;
79
 
80
const char *directives[] = {
81
        "if",                   /* 0  */
82
        "ifdef",                /* 1  */
83
        "ifndef",               /* 2  */
84
        "else",                 /* 3  */
85
        "endif",                /* 4  */
86
        "define",               /* 5  */
87
        "undef",                /* 6  */
88
        "include",              /* 7  */
89
        "line",                 /* 8  */
90
        "pragma",               /* 9  */
91
        "error",                /* 10 */
92
        "ident",                /* 11 */
93
        "sccs",                 /* 12 */
94
        "elif",                 /* 13 */
95
        "eject",                /* 14 */
96
        "warning",              /* 15 */
97
        NULL
98
};
99
 
100
#define MAKEDEPEND
101
#include "imakedep.h"           /* from config sources */
102
#undef  MAKEDEPEND
103
#ifdef  MSDOS
104
#include <libdos.h>
105
#endif
106
 
107
struct  inclist inclist[ MAXFILES ] = {0};
108
struct  inclist *inclistp = inclist;
109
struct  inclist maininclist;
110
 
111
char    *filelist[ MAXFILES ] = {0};
112
char    *includedirs[ MAXDIRS+1 ] = {0};
113
char    *defincdirs[ MAXDIRS+1 ] = {0};
114
char    **systemdirs = NULL;
115
char    *notdotdot[ MAXDIRS ] = {0};
116
char    *objprefixs[ MAXPREFIXS ] = {0};
117
char    *objsuffix = OBJSUFFIX;
118
char    *startat = "# DO NOT DELETE -- make depend depends on it.";
119
int     width = 78;
120
int     mflags = 0;
121
boolean append = FALSE;
122
boolean printed = FALSE;
123
boolean verbose = FALSE;
124
boolean opt_basename = FALSE;
125
int embeddedwhite = BS_UNKNOWN;
126
boolean show_where_not = FALSE;
127
boolean warn_multiple = FALSE;  /* Warn on multiple includes of same file */
128
 
129
static void usage(void);
130
 
131
static
132
#ifdef SIGNALRETURNSINT
133
int
134
#else
135
void
136
#endif
137
catch (int sig)
138
{
139
        fflush (stdout);
140
        fatalerr ("got signal %d\n", sig);
141
}
142
 
143
#if defined(USG) || (defined(i386) && defined(SYSV)) ||\
144
                defined(WIN32) || defined(MSDOS)
145
#define USGISH
146
#endif
147
 
148
#ifndef USGISH
149
#ifndef _POSIX_SOURCE
150
#define sigaction sigvec
151
#define sa_handler sv_handler
152
#define sa_mask sv_mask
153
#define sa_flags sv_flags
154
#endif
155
struct sigaction sig_act;
156
#endif /* USGISH */
157
 
158
#if defined(WIN32)
159
extern int
160
parse_cmdbuffer(const char *, const char *, char ***, int *);
161
#endif
162
 
163
main(argc, argv)
164
        int     argc;
165
        char    **argv;
166
{
167
        register char   **fp = filelist;
168
        register char   **incp = includedirs;
169
        register char   **defp = defincdirs;
170
        register char   **prefixp = objprefixs;
171
 
172
        register char   *p;
173
        register struct inclist *ip;
174
        char            *makefile = NULL;
175
        struct  filepointer *filecontent;
176
        struct  symtab  *psymp = predefs;
177
        char            *endmarker = NULL;
178
 
179
        ProgramName = strdup(argv[0]);
180
#if defined(WIN32) || defined(DOS)
181
        if ((p = strrchr(ProgramName, '/')) != NULL ||
182
                    (p = strrchr(ProgramName, '\\')) != NULL) {
183
                ProgramPath = ProgramName;
184
                *p++ = '\0';
185
                ProgramName = p;
186
        } else {
187
                ProgramPath = NULL;
188
                ProgramName = p;
189
        }     
190
        if ((p = strrchr(ProgramName, '.')) != NULL && !stricmp(p, ".exe"))
191
                *p = '\0';
192
#endif
193
 
194
        while (psymp->s_name)
195
        {
196
                define2(psymp->s_name, psymp->s_value, &maininclist);
197
                psymp++;
198
        }
199
 
200
#ifdef DEBUG
201
        if ((p = getenv("MKDEPENDDEBUG")) != NULL && *p) {
202
                _debugmask = strtol(p, NULL, 0);
203
        }
204
#endif
205
 
206
        if (argc == 2 && argv[1][0] == '@') {
207
                struct stat ast;
208
                int afd;
209
                char *args;
210
                char quotechar = '\0';
211
                char **nargv;
212
                int nargc;
213
 
214
                debug(1, ("importing: %s\n", argv[1]+1));
215
 
216
                if ((afd = open(argv[1]+1, O_RDONLY)) < 0)
217
                        fatalerr("cannot open \"%s\"\n", argv[1]+1);
218
                fstat(afd, &ast);
219
                args = (char *)malloc(ast.st_size + 1);
220
                if ((ast.st_size = read(afd, args, ast.st_size)) < 0)
221
                        fatalerr("failed to read %s\n", argv[1]+1);
222
                args[ast.st_size] = '\0';
223
                close(afd);
224
 
225
#if defined(WIN32)
226
                if (parse_cmdbuffer( argv[0], args, &nargv, &argc ) == -1)
227
                        fatalerr( "failed to parse %s\n", argv[1]+1 );
228
 
229
                for (nargc = 1; nargv[nargc]; nargc++) {
230
                        debug(1, ("arg%d: %s\n", nargc, nargv[nargc]));
231
                }
232
 
233
                argv = nargv;
234
#else
235
                for (nargc = 1, p = args; *p; p++) {
236
                        if (quotechar) {
237
                        if (quotechar == '\\' ||
238
                                (*p == quotechar && p[-1] != '\\'))
239
                                quotechar = '\0';
240
                        continue;
241
                        }
242
                        switch (*p) {
243
                        case '\\':
244
                        case '"':
245
                        case '\'':
246
                        quotechar = *p;
247
                        break;
248
                        case ' ':
249
                        case '\n':
250
                        *p = '\0';
251
                        if (p > args && p[-1])
252
                                nargc++;
253
                        break;
254
                        }
255
                }
256
                if (p[-1])
257
                        nargc++;
258
                nargv = (char **)malloc(nargc * sizeof(char *));
259
                nargv[0] = argv[0];
260
                argc = 1;
261
                for (p = args; argc < nargc; p += strlen(p) + 1)
262
                        if (*p) nargv[argc++] = p;
263
                argv = nargv;
264
#endif
265
        }
266
 
267
        for(argc--, argv++; argc; argc--, argv++) {
268
                /* if looking for endmarker then check before parsing */
269
                if (endmarker && strcmp (endmarker, *argv) == 0) {
270
                    endmarker = NULL;
271
                    continue;
272
                }
273
                if (**argv != '-') {
274
                        /* treat +thing as an option for C++ */
275
                        if (endmarker && **argv == '+')
276
                                continue;
277
                        *fp++ = argv[0];
278
                        continue;
279
                }
280
                switch(argv[0][1]) {
281
                case '-':
282
                        if (strcmp("help", argv[0]+2) == 0)
283
                                usage();
284
                        endmarker = &argv[0][2];
285
                        if (endmarker[0] == '\0') endmarker = "--";
286
                        break;
287
                case 'D':
288
                        if (argv[0][2] == '\0') {
289
                                argv++;
290
                                argc--;
291
                        }
292
                        for (p=argv[0] + 2; *p ; p++)
293
                                if (*p == '=') {
294
                                        *p = ' ';
295
                                        break;
296
                                }
297
                        define(argv[0] + 2, &maininclist);
298
                        debug(1, ("-D%s\n", argv[0] + 2));
299
                        break;
300
                case 'I':
301
                        if (incp >= includedirs + MAXDIRS)
302
                                fatalerr("Too many -I flags.\n");
303
                        *incp++ = argv[0]+2;
304
                        if (**(incp-1) == '\0') {
305
                                *(incp-1) = *(++argv);
306
                                argc--;
307
                        }
308
                        debug(1, ("-I%s\n", *(incp-1)));
309
                        break;
310
                case 'Y':
311
                        if (defp >= defincdirs + MAXDIRS)
312
                                fatalerr("Too many -Y flags.\n");
313
                        *defp++ = argv[0]+2;
314
                        if (**(defp-1) == '\0') {
315
                                *(defp-1) = *(++argv);
316
                                argc--;
317
                        }
318
                        debug(1, ("-Y%s\n", *(defp-1)));
319
                        break;
320
                case 'M':
321
                        for (p=argv[0]+2; *p; p++)
322
                                switch (*p) {
323
                                case 'M':
324
                                        mflags |= MFLAG_NOSYSTEM;
325
                                        break;
326
                                case 'G':
327
                                        mflags |= MFLAG_GENERATED;
328
                                        break;
329
                                default:
330
                                        warning("ignoring option -M%c\n", *p);
331
                                        break;
332
                                }
333
                        break;
334
 
335
                /* do not use if endmarker processing */
336
                case 'a':
337
                        if (endmarker) break;
338
                        append = TRUE;
339
                        break;
340
                case 'w':
341
                        if (endmarker) break;
342
                        if (argv[0][2] == '\0') {
343
                                argv++;
344
                                argc--;
345
                                width = atoi(argv[0]);
346
                        } else
347
                                width = atoi(argv[0]+2);
348
                        break;
349
                case 'o':                       /* objsuffix */
350
                        if (endmarker) break;
351
                        if (argv[0][2] == '\0') {
352
                                argv++;
353
                                argc--;
354
                                objsuffix = argv[0];
355
                        } else
356
                                objsuffix = argv[0]+2;
357
                        break;
358
                case 'p':                       /* objprefix(s) */                    
359
                        if (endmarker) break;
360
                        if (prefixp >= objprefixs + MAXPREFIXS)
361
                                fatalerr("Too many -p flags.\n");
362
                        *prefixp++ = argv[0]+2;
363
                        if (**(prefixp-1) == '\0') {
364
                                *(prefixp-1) = *(++argv);
365
                                argc--;
366
                        }
367
                        debug(1, ("-p%s\n", *(prefixp-1)));
368
                        break;
369
                case 'b':                       /* basename */
370
                        if (endmarker) break;
371
                        opt_basename = TRUE;
372
                        break;
373
                case 'W':                       /* whitespace handling */
374
                        if (endmarker) break;
375
                        embeddedwhite = BS_ESCAPE;
376
                        for (p=argv[0]+2; *p; p++)
377
                                switch (*p) {
378
                                case '0':       /* method 0: nothing */
379
                                case '-':
380
                                        embeddedwhite = BS_IGNORE;
381
                                        break;
382
                                case '1':       /* method 1: escape */  
383
                                case 'e':
384
                                case '+':
385
                                        embeddedwhite = BS_ESCAPE;
386
                                        break;
387
                                case '2':       /* method 2: quote path */
388
                                case 'q':
389
                                        embeddedwhite = BS_QUOTE;
390
                                        break;
391
                                case '3':       /* method 3: junk */
392
                                case 'j':
393
                                        embeddedwhite = BS_JUNK;
394
                                        break;
395
                                case '4':       /* method 3: URL */
396
                                case 'u':
397
                                        embeddedwhite = BS_URL;
398
                                        break;
399
                                default:
400
                                        warning("ignoring option -W%c\n", *p);
401
                                        break;
402
                                }
403
                        break;
404
                case 'v':
405
                        if (endmarker) break;
406
                        verbose = TRUE;
407
#ifdef DEBUG
408
                        if (argv[0][2])
409
                                _debugmask = atoi(argv[0]+2);
410
#ifdef MSDOS
411
                        __systeml_debug = 1;
412
#endif
413
#endif
414
                        break;
415
                case 's':
416
                        if (endmarker) break;
417
                        startat = argv[0]+2;
418
                        if (*startat == '\0') {
419
                                startat = *(++argv);
420
                                argc--;
421
                        }
422
                        if (*startat != '#')
423
                                fatalerr("-s flag's value should start %s\n",
424
                                        "with '#'.");
425
                        break;
426
                case 'f':
427
                        if (endmarker) break;
428
                        makefile = argv[0]+2;
429
                        if (*makefile == '\0') {
430
                                makefile = *(++argv);
431
                                argc--;
432
                        }
433
                        break;
434
 
435
                case 'm':
436
                        warn_multiple = TRUE;
437
                        break;
438
 
439
                /* Ignore -O, -g so we can just pass ${CFLAGS} to
440
                 *      makedepend
441
                 */
442
                case 'O':
443
                case 'g':
444
                        break;
445
                default:
446
                        if (endmarker) break;
447
                        warning("ignoring option %s\n", argv[0]);
448
                }
449
        }
450
 
451
        systemdirs = incp;      /* mark beginning of system directories */
452
        if (!defincdirs[0]) {
453
#ifdef PREINCDIR
454
                if (incp >= includedirs + MAXDIRS)
455
                        fatalerr("Too many -I flags.\n");
456
                *incp++ = PREINCDIR;
457
#endif
458
#ifdef INCLUDEDIR
459
                if (incp >= includedirs + MAXDIRS)
460
                        fatalerr("Too many -I flags.\n");
461
                *incp++ = INCLUDEDIR;
462
#endif
463
#ifdef POSTINCDIR
464
                if (incp >= includedirs + MAXDIRS)
465
                        fatalerr("Too many -I flags.\n");
466
                *incp++ = POSTINCDIR;
467
#endif
468
#if defined(WIN32) || defined(MSDOS)
469
                {
470
                        char *p, *p2;
471
 
472
                        if ((p = getenv("INCLUDE")) != NULL && *p &&
473
                                (p = p2 = strdup(p)) != (char *)NULL) 
474
                        {
475
                        /* split path */
476
                                do {
477
                                        *incp = p;
478
                                        if ((p = strchr(p, ';')) != NULL)
479
                                                *p++ = '\0';
480
                                        debug(1, ("imported -I%s\n", *incp));
481
                                        incp++;
482
                                } while (p && *p);
483
                        }
484
                }
485
#endif  /*WIN32, MSDOS*/
486
        } else {
487
                register char   **pp;
488
 
489
                for (pp = defincdirs; *pp; pp++) {
490
                        if (incp >= includedirs + MAXDIRS)
491
                            fatalerr("Too many -I and -Y flags.\n");
492
                        *incp++ = *pp;
493
                }
494
        }
495
#if defined(WIN32) || defined(MSDOS)
496
        {
497
                register char   **pp, *p;
498
 
499
                for (pp = includedirs; *pp; pp++) {
500
                        p = *pp;
501
                        do {
502
                                if ((p = strchr(p, '\\')) != NULL)
503
                                        *p = '/';
504
                        } while (p && *p);
505
                }
506
        }
507
#endif  /*WIN32, MSDOS*/
508
 
509
        /* terminate each directory with '/', allowing 
510
         *      simple -MM detection.
511
         */
512
        if (mflags & MFLAG_NOSYSTEM) {
513
                register char   **pp, *p;
514
                register int    len;
515
 
516
                for (pp = systemdirs; *pp; pp++) {
517
                        len = strlen(*pp);
518
                        if ( len == 0 )
519
                            break;
520
                        if ( (*pp)[ len-1 ] != '/' ) {
521
                                p = malloc(len+2);
522
                                (void) strcpy(p, (const char *)*pp);
523
                                p[ len ] = '/', p[ len+1 ] = '\0';
524
                                debug(1, ("conv -Y%s\n", p));
525
                                *pp = p;
526
                        }
527
                }
528
        }
529
 
530
        redirect(startat, makefile);
531
 
532
        /*
533
         * catch signals.
534
         */
535
#ifdef USGISH
536
/*  should really reset SIGINT to SIG_IGN if it was.  */
537
#ifdef SIGHUP
538
        signal (SIGHUP,  catch);
539
#endif
540
        signal (SIGINT,  catch);
541
#ifdef SIGQUIT
542
        signal (SIGQUIT, catch);
543
#endif
544
        signal (SIGILL,  catch);
545
#ifdef SIGBUS
546
        signal (SIGBUS,  catch);
547
#endif
548
        signal (SIGSEGV, catch);
549
#ifdef SIGSYS
550
        signal (SIGSYS,  catch);
551
#endif
552
#else
553
        sig_act.sa_handler = catch;
554
#ifdef _POSIX_SOURCE
555
        sigemptyset(&sig_act.sa_mask);
556
        sigaddset(&sig_act.sa_mask, SIGINT);
557
        sigaddset(&sig_act.sa_mask, SIGQUIT);
558
#ifdef SIGBUS
559
        sigaddset(&sig_act.sa_mask, SIGBUS);
560
#endif
561
        sigaddset(&sig_act.sa_mask, SIGILL);
562
        sigaddset(&sig_act.sa_mask, SIGSEGV);
563
        sigaddset(&sig_act.sa_mask, SIGHUP);
564
        sigaddset(&sig_act.sa_mask, SIGPIPE);
565
#ifdef SIGSYS
566
        sigaddset(&sig_act.sa_mask, SIGSYS);
567
#endif
568
#else
569
        sig_act.sa_mask = ((1<<(SIGINT -1))
570
                           |(1<<(SIGQUIT-1))
571
#ifdef SIGBUS
572
                           |(1<<(SIGBUS-1))
573
#endif
574
                           |(1<<(SIGILL-1))
575
                           |(1<<(SIGSEGV-1))
576
                           |(1<<(SIGHUP-1))
577
                           |(1<<(SIGPIPE-1))
578
#ifdef SIGSYS
579
                           |(1<<(SIGSYS-1))
580
#endif
581
                           );
582
#endif /* _POSIX_SOURCE */
583
        sig_act.sa_flags = 0;
584
        sigaction(SIGHUP, &sig_act, (struct sigaction *)0);
585
        sigaction(SIGINT, &sig_act, (struct sigaction *)0);
586
        sigaction(SIGQUIT, &sig_act, (struct sigaction *)0);
587
        sigaction(SIGILL, &sig_act, (struct sigaction *)0);
588
#ifdef SIGBUS
589
        sigaction(SIGBUS, &sig_act, (struct sigaction *)0);
590
#endif
591
        sigaction(SIGSEGV, &sig_act, (struct sigaction *)0);
592
#ifdef SIGSYS
593
        sigaction(SIGSYS, &sig_act, (struct sigaction *)0);
594
#endif
595
#endif /* USGISH */
596
 
597
        /*
598
         * now peruse through the list of files.
599
         */
600
        for(fp=filelist; *fp; fp++) {
601
                filecontent = getfile(*fp);
602
                ip = newinclude(*fp, (char *)NULL);
603
 
604
                find_includes(filecontent, ip, ip, 0, FALSE);
605
                freefile(filecontent);
606
                recursive_pr_include(ip, ip->i_file, base_name(*fp));
607
                inc_clean();
608
                inc_dump();
609
        }
610
        if (printed)
611
                printf("\n");
612
        exit(0);
613
}
614
 
615
 
616
static void 
617
usage(void)
618
{
619
        fprintf( stderr,
620
"Makedepend - %d.%02d\n" \
621
"Create dependencies in makefiles\n" \
622
"\n" \
623
"Usage: %s [-D name[=def]] [-I includedir] [-Y includedir]\n" \
624
"         [-a] [-f makefile] [-b] [-W[1|2]] [-o objsuffix] [-p objprefix]\n" \
625
"         [-s string] [-w width] [-v] [-m] [-- otheroptions --]\n" \
626
"         sourcefile [sourcefile ...]\n\n",
627
        VMAJOR, VMINOR, ProgramName );
628
 
629
        fprintf( stderr,
630
"Options:\n" \
631
" -f makefile              Alternate output file name\n" \
632
" -a                       Append dependencies to the end of the file.\n" \
633
" -DIname=def or -DIname   Define a symbol.\n" \
634
" -I includedir            Include directory.\n" \
635
" -Y includedir            System include directory.\n" \
636
" -b                       Strip any directory from object file name.\n" \
637
" -W[0|1|2|3|4]            Specify method of handling embedded whitespace.\n" \
638
"    0                     - Disable warnings.\n"\
639
"    1                     - Escape (eg /Embedded\\ Space/x.h).\n"\
640
"    2                     - Quote the entire path (eg \"/Embedded Space/x.h\").\n"\
641
"    3                     - Junk.\n"\
642
"    4                     - URL style (eg /Embedded%%20Space/x.h).\n"\
643
" -o objsuffix             Object file suffix.\n" \
644
" -p objprefix             Object file prefix.\n" \
645
" -s string                Starting string delimiter.\n" \
646
" -w width                 Line width.\n" \
647
" -v                       Verbose operation.\n" \
648
" -m                       Warn about multiple inclusion.\n" \
649
" -M                       GCC style dependency generation.\n" \
650
"    -M                    - Output dependencies.\n"\
651
"    -MG                   - Treat missing header files as generated\n" \
652
"    -MM                   - Output mentions only the user header\n" \
653
"\n");
654
        exit(1);
655
}
656
 
657
 
658
struct filepointer *getfile(file)
659
        char    *file;
660
{
661
        register int    fd;
662
        struct filepointer      *content;
663
        struct stat     st;
664
 
665
        content = (struct filepointer *)malloc(sizeof(struct filepointer));
666
        debug(1,( "Opening File: %s\n", file ));
667
 
668
        if ((fd = open(file, O_RDONLY)) < 0) {
669
                warning("cannot open \"%s\"\n", file);
670
                content->f_p = content->f_base = content->f_end = (char *)malloc(1);
671
                *content->f_p = '\0';
672
                return(content);
673
        }
674
        fstat(fd, &st);
675
        content->f_base = (char *)malloc(st.st_size+1);
676
        if (content->f_base == NULL)
677
                fatalerr("cannot allocate mem\n");
678
        if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0)
679
                fatalerr("failed to read %s\n", file);
680
        close(fd);
681
        content->f_len = st.st_size+1;
682
        content->f_p = content->f_base;
683
        content->f_end = content->f_base + st.st_size;
684
        *content->f_end = '\0';
685
        content->f_line = 0;
686
        content->f_name = copy(file);
687
        return(content);
688
}
689
 
690
freefile(fp)
691
        struct filepointer      *fp;
692
{
693
        debug(1,( "EndProcessing File: %s\n", fp->f_name ));
694
        free(fp->f_base);
695
        free(fp);
696
   return (0);
697
}
698
 
699
char *copy(str)
700
        register char   *str;
701
{
702
        register char   *p = (char *)malloc(strlen(str) + 1);
703
 
704
        strcpy(p, str);
705
        return(p);
706
}
707
 
708
match(str, list)
709
        register char *str;
710
        register const char **list;
711
{
712
        register int    i;
713
 
714
        for (i=0; *list; i++, list++)
715
                if (strcmp(str, *list) == 0)
716
                        return(i);
717
        return(-1);
718
}
719
 
720
/*
721
 * Get the next line.  We only return lines beginning with '#' since that
722
 * is all this program is ever interested in.
723
 */
724
char *getline(filep)
725
        register struct filepointer     *filep;
726
{
727
        register char   *p,             /* walking pointer */
728
                        *eof,           /* end of file pointer */
729
                        *bol;           /* beginning of line pointer */
730
        register        lineno;         /* line number */
731
 
732
        p = filep->f_p;
733
        eof = filep->f_end;
734
        if (p >= eof)
735
                return((char *)NULL);
736
        lineno = filep->f_line;
737
 
738
        for(bol = p--; ++p < eof; ) {
739
 
740
                if (*p == '/' && *(p+1) == '*') {       /* consume comments */
741
                        *p++ = ' ', *p++ = ' ';
742
                        while (*p) {
743
                                if (*p == '*' && *(p+1) == '/') {
744
                                        *p++ = ' ', *p = ' ';
745
                                        break;
746
                                }
747
                                else if (*p == '\n')
748
                                        lineno++;
749
                                *p++ = ' ';
750
                        }
751
                        continue;
752
                }
753
#if defined(MSDOS) || defined(WIN32)
754
                else if (*p == '/' && *(p+1) == '/') {  /* consume comments */
755
                        *p++ = ' ', *p++ = ' ';
756
                        while (*p && *p != '\n')
757
                                *p++ = ' ';
758
                        --p;
759
                        continue;
760
                }
761
#endif
762
                else if (*p == '\\') {
763
                        if (*(p+1) == '\n') {
764
                                *p = ' ';
765
                                *(p+1) = ' ';
766
                                lineno++;
767
                        }
768
                }
769
                else if (*p == '\n') {
770
                        char *cp = bol;
771
                        lineno++;
772
 
773
                        /*
774
                        **  Allow white space before a directive. Its not ansi, but
775
                        **  it is used by people
776
                        */
777
                        if ( *cp == ' ' || *cp == '\t' )
778
                        {
779
                            while ( *cp == ' ' || *cp == '\t' )
780
                            {
781
                                *cp++;
782
                            }
783
                            bol = cp;
784
                        }
785
 
786
                        if (*bol == '#') {
787
                                register char *cp;
788
 
789
                                *p++ = '\0';
790
                                /* punt lines with just # (yacc generated) */
791
                                for (cp = bol+1;
792
                                     *cp && (*cp == ' ' || *cp == '\t'); cp++);
793
                                if (*cp)
794
                                    goto done;
795
                        }
796
                        bol = p+1;
797
                }
798
        }
799
 
800
        if (*bol != '#')
801
                bol = NULL;
802
done:
803
 
804
        filep->f_p = p;
805
        filep->f_line = lineno;
806
        return(bol);
807
}
808
 
809
/*
810
 * Strip the file name down to what we want to see in the Makefile.
811
 * It will have objprefix and objsuffix around it.
812
 */
813
char *base_name(file)
814
        register char   *file;
815
{
816
        register char   *p;
817
 
818
        file = copy(file);
819
        for(p=file+strlen(file); p>file && *p != '.'; p--) ;
820
 
821
        if (*p == '.')
822
                *p = '\0';
823
        return(file);
824
}
825
 
826
#if defined(USG) && !defined(CRAY) && !defined(SVR4)
827
int
828
rename (from, to)
829
        char *from, *to;
830
{
831
        (void) unlink (to);
832
        if (link (from, to) == 0) {
833
                unlink (from);
834
                return 0;
835
        } else {
836
                return -1;
837
        }
838
}
839
#endif /* USGISH */
840
 
841
 
842
void
843
redirect(line, makefile)
844
        char    *line,
845
                *makefile;
846
{
847
        struct stat     st;
848
        FILE    *fdin, *fdout;
849
        char    backup[ MAX_PATH+1 ],
850
                buf[ MAX_PATH+1 ];
851
        boolean found = FALSE;
852
        int     len;
853
 
854
        /*
855
         * if makefile is "-" then let it pour onto stdout.
856
         */
857
        if (makefile && *makefile == '-' && *(makefile+1) == '\0') {
858
                puts(line);
859
                return;
860
        }
861
 
862
        /*
863
         * use a default makefile is not specified.
864
         */
865
        if (!makefile) {
866
                if (stat("Makefile", &st) == 0)
867
                        makefile = "Makefile";
868
                else if (stat("makefile", &st) == 0)
869
                        makefile = "makefile";
870
                else
871
                        fatalerr("[mM]akefile is not present\n");
872
        }
873
        else
874
            stat(makefile, &st);
875
        if ((fdin = fopen(makefile, "r")) == NULL)
876
                fatalerr("cannot open \"%s\"\n", makefile);
877
        sprintf(backup, "%s.bak", makefile);
878
        unlink(backup);
879
#if defined(WIN32) || defined(MSDOS)
880
        fclose(fdin);
881
#endif
882
        if (rename(makefile, backup) < 0)
883
                fatalerr("cannot rename %s to %s\n", makefile, backup);
884
#if defined(WIN32) || defined(MSDOS)
885
        if ((fdin = fopen(backup, "r")) == NULL)
886
                fatalerr("cannot open \"%s\"\n", backup);
887
#endif
888
        if ((fdout = freopen(makefile, "w", stdout)) == NULL)
889
                fatalerr("cannot open \"%s\"\n", backup);
890
        len = strlen(line);
891
        while (!found && fgets(buf, MAX_PATH, fdin)) {
892
                if (*buf == '#' && strncmp(line, buf, len) == 0)
893
                        found = TRUE;
894
                fputs(buf, fdout);
895
        }
896
        if (!found) {
897
                if (verbose)
898
                        warning("Adding new delimiting line \"%s\" and dependencies...\n", line);
899
                puts(line); /* same as fputs(fdout); but with newline */
900
        } else if (append) {
901
            while (fgets(buf, MAX_PATH, fdin)) {
902
                fputs(buf, fdout);
903
            }
904
        }
905
        fflush(fdout);
906
#if defined(USGISH) || defined(_SEQUENT_)
907
        chmod(makefile, st.st_mode);
908
#else
909
        fchmod(fileno(fdout), st.st_mode);
910
#endif /* USGISH */
911
}
912
 
913
 
914
void
915
#ifdef NeedVarargsPrototypes
916
fatalerr(char *msg, ...)
917
#else
918
/*VARARGS*/
919
fatalerr(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
920
    char *msg;
921
#endif
922
{
923
#ifdef NeedVarargsPrototypes
924
        va_list args;
925
#endif
926
        fprintf(stderr, "%s: error:  ", ProgramName);
927
#ifdef NeedVarargsPrototypes
928
        va_start(args, msg);
929
        vfprintf(stderr, msg, args);
930
        va_end(args);
931
#else
932
        fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
933
#endif
934
        exit (1);
935
}
936
 
937
 
938
void
939
#if NeedVarargsPrototypes
940
warning(char *msg, ...)
941
#else
942
/*VARARGS0*/
943
warning(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
944
    char *msg;
945
#endif
946
{
947
#if NeedVarargsPrototypes
948
        va_list args;
949
#endif
950
        fprintf(stderr, "%s: warning:  ", ProgramName);
951
#if NeedVarargsPrototypes
952
        va_start(args, msg);
953
        vfprintf(stderr, msg, args);
954
        va_end(args);
955
#else
956
        fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
957
#endif
958
}
959
 
960
 
961
void
962
#if NeedVarargsPrototypes
963
warning1(char *msg, ...)
964
#else
965
/*VARARGS0*/
966
warning1(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
967
    char *msg;
968
#endif
969
{
970
#if NeedVarargsPrototypes
971
        va_list args;
972
        va_start(args, msg);
973
        vfprintf(stderr, msg, args);
974
        va_end(args);
975
#else
976
        fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
977
#endif
978
}
979
 
980
 
981
void
982
#if NeedVarargsPrototypes
983
info(char *msg, ...)
984
#else
985
/*VARARGS0*/
986
info(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
987
        char *msg;
988
#endif
989
{
990
#if NeedVarargsPrototypes
991
        va_list args;
992
#endif
993
        fprintf(stderr, "%s: info: ", ProgramName);
994
#if NeedVarargsPrototypes
995
        va_start(args, msg);
996
        vfprintf(stderr, msg, args);
997
        va_end(args);
998
#else
999
        fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
1000
#endif
1001
}
1002
 
1003