8990 /opt/onbld/gk is useless
[unleashed.git] / usr / src / tools / cscope-fast / dir.c
blob8d12ba56c0a9bb245def7bcf2d11716ed3169aff
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
22 /* Copyright (c) 1988 AT&T */
23 /* All Rights Reserved */
27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
31 #pragma ident "%Z%%M% %I% %E% SMI"
34 * cscope - interactive C symbol cross-reference
36 * directory searching functions
39 #include <sys/types.h> /* needed by stat.h */
40 #include <sys/stat.h> /* stat */
41 #include "global.h"
42 #include "dirent.h"
43 #include "vp.h" /* vpdirs and vpndirs */
45 #define DIRSEPS " ,:" /* directory list separators */
46 #define DIRINC 10 /* directory list size increment */
47 #define HASHMOD 2003 /* must be a prime number */
48 #define SRCINC HASHMOD /* source file list size increment */
49 /* largest known database had 22049 files */
51 char **incdirs; /* #include directories */
52 char **srcdirs; /* source directories */
53 char **srcfiles; /* source files */
54 int nincdirs; /* number of #include directories */
55 int mincdirs = DIRINC; /* maximum number of #include directories */
56 int nsrcdirs; /* number of source directories */
57 int msrcdirs = DIRINC; /* maximum number of source directories */
58 int nsrcfiles; /* number of source files */
59 int msrcfiles = SRCINC; /* maximum number of source files */
61 static struct listitem { /* source file table entry */
62 char *file;
63 struct listitem *next;
64 } *srcfiletable[HASHMOD];
67 static void getsrcfiles(char *vpdir, char *dir);
68 static BOOL issrcfile(char *file);
70 /* add a source directory to the list for each view path source directory */
72 void
73 sourcedir(char *dirlist)
75 struct stat statstruct;
76 char *dir;
78 /* don't change environment variable text */
79 dirlist = stralloc(dirlist);
81 /* parse the directory list */
82 dir = strtok(dirlist, DIRSEPS);
83 while (dir != NULL) {
85 * make sure it is a directory (must exist in current
86 * view path node)
88 if (stat(compath(dir), &statstruct) == 0 &&
89 S_ISDIR(statstruct.st_mode)) {
90 if (srcdirs == NULL) {
91 srcdirs = mymalloc(msrcdirs * sizeof (char *));
92 } else if (nsrcdirs == msrcdirs) {
93 msrcdirs += DIRINC;
94 srcdirs = myrealloc(srcdirs,
95 msrcdirs * sizeof (char *));
97 srcdirs[nsrcdirs++] = stralloc(dir);
99 dir = strtok((char *)NULL, DIRSEPS);
103 /* add a #include directory to the list for each view path source directory */
105 void
106 includedir(char *dirlist)
108 struct stat statstruct;
109 char *dir;
111 /* don't change environment variable text */
112 dirlist = stralloc(dirlist);
114 /* parse the directory list */
115 dir = strtok(dirlist, DIRSEPS);
116 while (dir != NULL) {
119 * make sure it is a directory (must exist in current
120 * view path node)
122 if (stat(compath(dir), &statstruct) == 0 &&
123 S_ISDIR(statstruct.st_mode)) {
124 if (incdirs == NULL) {
125 incdirs = mymalloc(mincdirs * sizeof (char *));
126 } else if (nincdirs == mincdirs) {
127 mincdirs += DIRINC;
128 incdirs = myrealloc(incdirs,
129 mincdirs * sizeof (char *));
131 incdirs[nincdirs++] = stralloc(dir);
133 dir = strtok((char *)NULL, DIRSEPS);
137 /* make the source file list */
139 void
140 makefilelist(void)
142 static BOOL firstbuild = YES; /* first time through */
143 FILE *names; /* name file pointer */
144 char dir[PATHLEN + 1];
145 char path[PATHLEN + 1];
146 struct stat statstruct;
147 char *file;
148 char *s;
149 int i, j;
151 /* if there are source file arguments */
152 if (fileargc > 0) {
153 /* put them in a list that can be expanded */
154 for (i = 0; i < fileargc; ++i) {
155 file = fileargv[i];
156 if (infilelist(file) == NO) {
157 if (vpaccess(file, READ) == 0) {
158 addsrcfile(file);
159 } else {
160 (void) fprintf(stderr,
161 "cscope: cannot find file %s\n",
162 file);
163 errorsfound = YES;
167 return;
169 /* see if a file name file exists */
170 if (namefile == NULL && vpaccess(NAMEFILE, READ) == 0) {
171 namefile = NAMEFILE;
173 /* if there is a file of source file names */
174 if (namefile != NULL) {
175 if ((names = vpfopen(namefile, "r")) == NULL) {
176 cannotopen(namefile);
177 myexit(1);
179 /* get the names in the file */
180 while (fscanf(names, "%s", path) == 1) {
181 if (*path == '-') { /* if an option */
182 i = path[1];
183 switch (i) {
184 case 'q': /* quick search */
185 invertedindex = YES;
186 break;
187 case 'T':
188 /* truncate symbols to 8 characters */
189 truncatesyms = YES;
190 break;
191 case 'I': /* #include file directory */
192 case 'p': /* file path components to */
193 /* display */
194 s = path + 2; /* for "-Ipath" */
195 if (*s == '\0') { /* if "-I path" */
196 (void) fscanf(names,
197 "%s", path);
198 s = path;
200 switch (i) {
201 case 'I': /* #include file directory */
202 if (firstbuild == YES) {
203 /* expand $ and ~ */
204 shellpath(dir,
205 sizeof (dir), s);
206 includedir(dir);
208 break;
209 case 'p':
210 /* file path components */
211 /* to display */
212 if (*s < '0' || *s > '9') {
213 (void) fprintf(stderr,
214 "cscope: -p option "
215 "in file %s: "
216 "missing or "
217 "invalid numeric "
218 "value\n",
219 namefile);
221 dispcomponents = atoi(s);
222 break;
224 break;
225 default:
226 (void) fprintf(stderr,
227 "cscope: only -I, -p, and -T "
228 "options can be in file %s\n",
229 namefile);
231 } else if (vpaccess(path, READ) == 0) {
232 addsrcfile(path);
233 } else {
234 (void) fprintf(stderr,
235 "cscope: cannot find file %s\n",
236 path);
237 errorsfound = YES;
240 (void) fclose(names);
241 firstbuild = NO;
242 return;
244 /* make a list of all the source files in the directories */
245 for (i = 0; i < nsrcdirs; ++i) {
246 s = srcdirs[i];
247 getsrcfiles(s, s);
248 if (*s != '/') { /* if it isn't a full path name */
250 /* compute its path from any higher view path nodes */
251 for (j = 1; j < vpndirs; ++j) {
252 (void) sprintf(dir, "%s/%s", vpdirs[j], s);
254 /* make sure it is a directory */
255 if (stat(compath(dir), &statstruct) == 0 &&
256 S_ISDIR(statstruct.st_mode)) {
257 getsrcfiles(dir, s);
264 /* get the source file names in this directory */
266 static void
267 getsrcfiles(char *vpdir, char *dir)
269 DIR *dirfile; /* directory file descriptor */
270 struct dirent *entry; /* directory entry pointer */
271 char path[PATHLEN + 1];
273 /* attempt to open the directory */
274 if ((dirfile = opendir(vpdir)) != NULL) {
276 /* read each entry in the directory */
277 while ((entry = readdir(dirfile)) != NULL) {
279 /* if it is a source file not already found */
280 (void) sprintf(path, "%s/%s", dir, entry->d_name);
281 if (entry->d_ino != 0 &&
282 issrcfile(path) && infilelist(path) == NO) {
283 addsrcfile(path); /* add it to the list */
286 closedir(dirfile);
290 /* see if this is a source file */
292 static BOOL
293 issrcfile(char *file)
295 struct stat statstruct;
296 char *s;
298 /* if there is a file suffix */
299 if ((s = strrchr(file, '.')) != NULL && *++s != '\0') {
301 /* if an SCCS or versioned file */
302 if (file[1] == '.' && file + 2 != s) { /* 1 character prefix */
303 switch (*file) {
304 case 's':
305 case 'S':
306 return (NO);
309 if (s[1] == '\0') { /* 1 character suffix */
310 switch (*s) {
311 case 'c':
312 case 'h':
313 case 'l':
314 case 'y':
315 case 'C':
316 case 'G':
317 case 'H':
318 case 'L':
319 return (YES);
321 } else if (s[2] == '\0') { /* 2 character suffix */
322 if (*s == 'b' && s[1] == 'p' || /* breakpoint listing */
323 *s == 'q' &&
324 (s[1] == 'c' || s[1] == 'h') || /* Ingres */
325 *s == 'p' && s[1] == 'r' || /* SDL */
326 *s == 's' && s[1] == 'd') { /* SDL */
329 * some directories have 2 character
330 * suffixes so make sure it is a file
332 if (vpstat(file, &statstruct) == 0 &&
333 S_ISREG(statstruct.st_mode)) {
334 return (YES);
339 return (NO);
342 /* add an include file to the source file list */
344 void
345 incfile(char *file, int type)
347 char path[PATHLEN + 1];
348 int i;
350 /* see if the file is already in the source file list */
351 if (infilelist(file) == YES) {
352 return;
354 /* look in current directory if it was #include "file" */
355 if (type == '"' && vpaccess(file, READ) == 0) {
356 addsrcfile(file);
357 } else {
358 /* search for the file in the #include directory list */
359 for (i = 0; i < nincdirs; ++i) {
361 /* don't include the file from two directories */
362 (void) sprintf(path, "%s/%s", incdirs[i], file);
363 if (infilelist(path) == YES) {
364 break;
366 /* make sure it exists and is readable */
367 if (vpaccess(compath(path), READ) == 0) {
368 addsrcfile(path);
369 break;
375 /* see if the file is already in the list */
377 BOOL
378 infilelist(char *file)
380 struct listitem *p;
382 for (p = srcfiletable[hash(compath(file)) % HASHMOD];
383 p != NULL; p = p->next) {
384 if (strequal(file, p->file)) {
385 return (YES);
388 return (NO);
391 /* add a source file to the list */
393 void
394 addsrcfile(char *path)
396 struct listitem *p;
397 int i;
399 /* make sure there is room for the file */
400 if (nsrcfiles == msrcfiles) {
401 msrcfiles += SRCINC;
402 srcfiles = myrealloc(srcfiles, msrcfiles * sizeof (char *));
404 /* add the file to the list */
405 p = (struct listitem *)mymalloc(sizeof (struct listitem));
406 p->file = stralloc(compath(path));
407 i = hash(p->file) % HASHMOD;
408 p->next = srcfiletable[i];
409 srcfiletable[i] = p;
410 srcfiles[nsrcfiles++] = p->file;
413 /* free the memory allocated for the source file list */
415 void
416 freefilelist(void)
418 struct listitem *p, *nextp;
419 int i;
421 while (nsrcfiles > 0) {
422 free(srcfiles[--nsrcfiles]);
424 for (i = 0; i < HASHMOD; ++i) {
425 for (p = srcfiletable[i]; p != NULL; p = nextp) {
426 nextp = p->next;
427 free(p);
429 srcfiletable[i] = NULL;