summaryrefslogtreecommitdiff
path: root/web/spiderweb/tools/depend.web
blob: 42049d494766f6486b02e2c2d35b52b49fd3308b (plain)
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.