1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
\def\title{Finding dependencies in a {\tt WEB} file}
@*Introduction.
Often we want to know what files another {\tt WEB} file depends on, for
use in ``{\tt make depend}.''
This program reads a {\tt WEB} file, looking for |"@i"| at the
beginning of a line, and writes
the names of all of the include files on standard output.
It searches the paths set by the |WEBPATH| environment variable.
Usage is:
$${\tt depend [-a<at-sign>] [-I<directory>] [files...]}$$
If no at sign is specified, we use |'@@'|.
If no files are specified, we read from standard input.
In no case do we write the name of the file given on the command line.
@ The main program just processes the arguments.
|switchar(c)| tells whether |c| introduces an option.
@d switchar(c) = ((c)=='-')
@u
#include <stdio.h>
#include <ctype.h>
@i pathopen.h
static char at_sign = '@@';
main(argc,argv)
int argc; char **argv;
{
FILE *fp;
@<Read options and set |argc|, |argv| to remaining args@>@;
pathaddpath(getenv("WEBPATH"),':');
if (argc==0)
depend(stdin);
else while (argc-->0)
if ((fp=pathopen(*argv++))!=NULL)
depend(fp);
else {
fprintf(stderr,"Can't find %s on search path\n",*--argv);
exit(1);
}
}
@ @<Read options...@>=
while (--argc>0)
if (switchar(**++argv))
switch(*++(*argv)) {
case 'a':
++*argv;
@<Set |at_sign| according to |**argv|@>@;
break;
case 'I':
pathaddname(++(*argv));
break;
default:
fprintf(stderr,"Unknown option -%c\n", **argv);
break;
}
else break;
@ Since {\tt \#} is hard to write in {\tt Makefile}, we
let {\tt s} stand for {\tt \#}.
@<Set |at_sign| according to |**argv|@>=
at_sign = **argv;
if (at_sign=='s') at_sign='#';
@ All the real work is done by the recursive function |depend|, which
searches for {\tt @@i} and prints its findings on |stdout|.
@u
depend (fp)
FILE *fp;
{
int c;
char filename[128], *fn;
FILE *fp2;
c='\n'; /* begin like at the end of a line */
do {
if (c=='\n') {
end_line:
if ((c=getc(fp))==EOF) break;
if (c==at_sign) {
if ((c=getc(fp))==EOF) break;
if (c=='i' || c=='I') { /* live one */
@<Get name, print, and call |depend|@>@;
} else if (c=='\n') goto end_line;
} else if (c=='\n') goto end_line;
}
} while ((c=getc(fp))!=EOF);
fclose(fp);
}
@ @<Get name, print, and call |depend|@>=
while ((c=getc(fp))!=EOF)
if (!isspace(c)) break;
if (c==EOF) break;
fn=filename;
do {
if (isspace(c)) break;
else {
*fn++=c;
putchar(c);
}
} while ((c=getc(fp))!=EOF);
*fn='\0';
putchar('\n');
if ((fp2=pathopen(filename))!=NULL)
depend(fp2);
else {
fprintf(stderr,"Can't find %s on search path\n",filename);
exit(1);
}
if (c==EOF) break;
if (c=='\n') goto end_line;
/* N.B. to reiterate |isspace(c)|, so |c!=at_sign| */
@ Here's what |pathopen| and friends call in case of overflow.
@u
overflow(s)
char *s;
{
fprintf(stderr,"Sorry, capacity exceeded: %s\n",s);
exit(1);
}
@*Index.
|