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
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]
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 */
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 */
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 */
73 sourcedir(char *dirlist
)
75 struct stat statstruct
;
78 /* don't change environment variable text */
79 dirlist
= stralloc(dirlist
);
81 /* parse the directory list */
82 dir
= strtok(dirlist
, DIRSEPS
);
85 * make sure it is a directory (must exist in current
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
) {
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 */
106 includedir(char *dirlist
)
108 struct stat statstruct
;
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
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
) {
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 */
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
;
151 /* if there are source file arguments */
153 /* put them in a list that can be expanded */
154 for (i
= 0; i
< fileargc
; ++i
) {
156 if (infilelist(file
) == NO
) {
157 if (vpaccess(file
, READ
) == 0) {
160 (void) fprintf(stderr
,
161 "cscope: cannot find file %s\n",
169 /* see if a file name file exists */
170 if (namefile
== NULL
&& vpaccess(NAMEFILE
, READ
) == 0) {
173 /* if there is a file of source file names */
174 if (namefile
!= NULL
) {
175 if ((names
= vpfopen(namefile
, "r")) == NULL
) {
176 cannotopen(namefile
);
179 /* get the names in the file */
180 while (fscanf(names
, "%s", path
) == 1) {
181 if (*path
== '-') { /* if an option */
184 case 'q': /* quick search */
188 /* truncate symbols to 8 characters */
191 case 'I': /* #include file directory */
192 case 'p': /* file path components to */
194 s
= path
+ 2; /* for "-Ipath" */
195 if (*s
== '\0') { /* if "-I path" */
201 case 'I': /* #include file directory */
202 if (firstbuild
== YES
) {
210 /* file path components */
212 if (*s
< '0' || *s
> '9') {
213 (void) fprintf(stderr
,
221 dispcomponents
= atoi(s
);
226 (void) fprintf(stderr
,
227 "cscope: only -I, -p, and -T "
228 "options can be in file %s\n",
231 } else if (vpaccess(path
, READ
) == 0) {
234 (void) fprintf(stderr
,
235 "cscope: cannot find file %s\n",
240 (void) fclose(names
);
244 /* make a list of all the source files in the directories */
245 for (i
= 0; i
< nsrcdirs
; ++i
) {
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
)) {
264 /* get the source file names in this directory */
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 */
290 /* see if this is a source file */
293 issrcfile(char *file
)
295 struct stat statstruct
;
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 */
309 if (s
[1] == '\0') { /* 1 character suffix */
321 } else if (s
[2] == '\0') { /* 2 character suffix */
322 if (*s
== 'b' && s
[1] == 'p' || /* breakpoint listing */
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
)) {
342 /* add an include file to the source file list */
345 incfile(char *file
, int type
)
347 char path
[PATHLEN
+ 1];
350 /* see if the file is already in the source file list */
351 if (infilelist(file
) == YES
) {
354 /* look in current directory if it was #include "file" */
355 if (type
== '"' && vpaccess(file
, READ
) == 0) {
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
) {
366 /* make sure it exists and is readable */
367 if (vpaccess(compath(path
), READ
) == 0) {
375 /* see if the file is already in the list */
378 infilelist(char *file
)
382 for (p
= srcfiletable
[hash(compath(file
)) % HASHMOD
];
383 p
!= NULL
; p
= p
->next
) {
384 if (strequal(file
, p
->file
)) {
391 /* add a source file to the list */
394 addsrcfile(char *path
)
399 /* make sure there is room for the file */
400 if (nsrcfiles
== msrcfiles
) {
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
];
410 srcfiles
[nsrcfiles
++] = p
->file
;
413 /* free the memory allocated for the source file list */
418 struct listitem
*p
, *nextp
;
421 while (nsrcfiles
> 0) {
422 free(srcfiles
[--nsrcfiles
]);
424 for (i
= 0; i
< HASHMOD
; ++i
) {
425 for (p
= srcfiletable
[i
]; p
!= NULL
; p
= nextp
) {
429 srcfiletable
[i
] = NULL
;