xref: /inferno-os/utils/srclist/srclist.c (revision ecc9caba0e344ed50c05ee8156b2734f4d76e463)
1 #include <lib9.h>
2 #include <bio.h>
3 #include <mach.h>
4 
5 int	conly;
6 int	exists;
7 
8 enum {
9 	Maxroot = 10,
10 };
11 
12 int	nroot;
13 char	*root[Maxroot];
14 int	rootlen[Maxroot];
15 
16 void	usage(void);
17 void	error(char *);
18 void	addroot(char *);
19 void	addroots(char *);
20 void	chomp(char *);
21 
22 extern char	*mygetwd(char*, int);
23 
24 void
25 main(int argc, char **argv)
26 {
27 	char buf[1024], *cwd;
28 
29 	cwd = mygetwd(buf, sizeof(buf));
30 	ARGBEGIN {
31 	case 'c':
32 		conly = 1;
33 		break;
34 	case 'e':
35 		exists = 1;
36 		break;
37 	case 'r':
38 		addroots(EARGF(usage()));
39 		break;
40 	default:
41 		usage();
42 	} ARGEND
43 
44 	if(argc != 1)
45 		usage();
46 
47 	if(cwd != nil)
48 		chdir(cwd);
49 	setbinmode();
50 	chomp(argv[0]);
51 
52 	exits(0);
53 }
54 
55 void
56 addroot(char *x)
57 {
58 	if(nroot >= Maxroot){
59 		fprint(2, "srclist: too many root directories\n");
60 		exits("usage");
61 	}
62 	root[nroot] = x;
63 	rootlen[nroot] = strlen(x);
64 	nroot++;
65 }
66 
67 void
68 addrootnt(char *r)
69 {
70 	addroot(r);
71 	if(r[1] != ':')
72 		return;	/* phew! */
73 	if(*r >= 'a' && *r <= 'z' || *r >= 'A' && *r <= 'Z')
74 		addroot(r+2);
75 }
76 
77 void
78 addroots(char *r)
79 {
80 	char buf[1024], *r2;
81 
82 	addrootnt(r);
83 	if(chdir(r) < 0)
84 		return;
85 	r2 = mygetwd(buf, sizeof(buf));
86 	if(r2 && strcmp(r2, r) != 0)
87 		addrootnt(r2);
88 }
89 
90 void
91 chomp(char *file)
92 {
93 	int fd, i, j, len;
94 	Fhdr fhdr;
95 	Dir *td;
96 	char fname[1024];
97 
98 	fd = open(file, OREAD);
99 	if(fd < 0)
100 		error("open");
101 
102 	if(crackhdr(fd, &fhdr) == 0)
103 		error("crackhdr");
104 
105 	if(syminit(fd, &fhdr) < 0)
106 		error("syminit");
107 
108 	for(i = 0; i < 1000; i++)
109 		if(filesym(i, fname, sizeof(fname)-1)){
110 			cleanname(fname);
111 			if(conly){
112 				len = strlen(fname);
113 				if(len < 2 || strcmp(fname+len-2, ".c") != 0)
114 					continue;
115 			}
116 			if(exists){
117 				if((td = dirstat(fname)) == nil)
118 					continue;
119 				free(td);
120 			}
121 			if(nroot){
122 				for(j = 0; j < nroot; j++)
123 					if(strncmp(fname, root[j], rootlen[j]) == 0)
124 						break;
125 				if(j == nroot)
126 					continue;
127 			}
128 			print("%s\n", fname);
129 		}
130 }
131 
132 void
133 usage(void)
134 {
135 	fprint(2, "usage: srclist [-ce] [-r root] <objfile>\n");
136 	exits("usage");
137 }
138 
139 void
140 error(char *s)
141 {
142 	fprint(2, "srclist: %s: %r\n", s);
143 	exits(s);
144 }
145