\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] [-I] [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 #include @i pathopen.h static char at_sign = '@@'; main(argc,argv) int argc; char **argv; { FILE *fp; @@; 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); } } @ @= while (--argc>0) if (switchar(**++argv)) switch(*++(*argv)) { case 'a': ++*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 \#}. @= 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 */ @@; } else if (c=='\n') goto end_line; } else if (c=='\n') goto end_line; } } while ((c=getc(fp))!=EOF); fclose(fp); } @ @= 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.