17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 237c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 27*4bc0a2efScasper * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28*4bc0a2efScasper * Use is subject to license terms. 297c478bd9Sstevel@tonic-gate */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate /* 347c478bd9Sstevel@tonic-gate * cscope - interactive C symbol cross-reference 357c478bd9Sstevel@tonic-gate * 367c478bd9Sstevel@tonic-gate * directory searching functions 377c478bd9Sstevel@tonic-gate */ 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate #include <sys/types.h> /* needed by stat.h */ 407c478bd9Sstevel@tonic-gate #include <sys/stat.h> /* stat */ 417c478bd9Sstevel@tonic-gate #include "global.h" 427c478bd9Sstevel@tonic-gate #include "dirent.h" 437c478bd9Sstevel@tonic-gate #include "vp.h" /* vpdirs and vpndirs */ 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate #define DIRSEPS " ,:" /* directory list separators */ 467c478bd9Sstevel@tonic-gate #define DIRINC 10 /* directory list size increment */ 477c478bd9Sstevel@tonic-gate #define HASHMOD 2003 /* must be a prime number */ 487c478bd9Sstevel@tonic-gate #define SRCINC HASHMOD /* source file list size increment */ 497c478bd9Sstevel@tonic-gate /* largest known database had 22049 files */ 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate char **incdirs; /* #include directories */ 527c478bd9Sstevel@tonic-gate char **srcdirs; /* source directories */ 537c478bd9Sstevel@tonic-gate char **srcfiles; /* source files */ 547c478bd9Sstevel@tonic-gate int nincdirs; /* number of #include directories */ 557c478bd9Sstevel@tonic-gate int mincdirs = DIRINC; /* maximum number of #include directories */ 567c478bd9Sstevel@tonic-gate int nsrcdirs; /* number of source directories */ 577c478bd9Sstevel@tonic-gate int msrcdirs = DIRINC; /* maximum number of source directories */ 587c478bd9Sstevel@tonic-gate int nsrcfiles; /* number of source files */ 597c478bd9Sstevel@tonic-gate int msrcfiles = SRCINC; /* maximum number of source files */ 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate static struct listitem { /* source file table entry */ 627c478bd9Sstevel@tonic-gate char *file; 637c478bd9Sstevel@tonic-gate struct listitem *next; 647c478bd9Sstevel@tonic-gate } *srcfiletable[HASHMOD]; 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate static void getsrcfiles(char *vpdir, char *dir); 687c478bd9Sstevel@tonic-gate static BOOL issrcfile(char *file); 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate /* add a source directory to the list for each view path source directory */ 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate void 737c478bd9Sstevel@tonic-gate sourcedir(char *dirlist) 747c478bd9Sstevel@tonic-gate { 757c478bd9Sstevel@tonic-gate struct stat statstruct; 767c478bd9Sstevel@tonic-gate char *dir; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate /* don't change environment variable text */ 797c478bd9Sstevel@tonic-gate dirlist = stralloc(dirlist); 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate /* parse the directory list */ 827c478bd9Sstevel@tonic-gate dir = strtok(dirlist, DIRSEPS); 837c478bd9Sstevel@tonic-gate while (dir != NULL) { 847c478bd9Sstevel@tonic-gate /* 857c478bd9Sstevel@tonic-gate * make sure it is a directory (must exist in current 867c478bd9Sstevel@tonic-gate * view path node) 877c478bd9Sstevel@tonic-gate */ 887c478bd9Sstevel@tonic-gate if (stat(compath(dir), &statstruct) == 0 && 89*4bc0a2efScasper S_ISDIR(statstruct.st_mode)) { 907c478bd9Sstevel@tonic-gate if (srcdirs == NULL) { 917c478bd9Sstevel@tonic-gate srcdirs = mymalloc(msrcdirs * sizeof (char *)); 927c478bd9Sstevel@tonic-gate } else if (nsrcdirs == msrcdirs) { 937c478bd9Sstevel@tonic-gate msrcdirs += DIRINC; 947c478bd9Sstevel@tonic-gate srcdirs = myrealloc(srcdirs, 957c478bd9Sstevel@tonic-gate msrcdirs * sizeof (char *)); 967c478bd9Sstevel@tonic-gate } 977c478bd9Sstevel@tonic-gate srcdirs[nsrcdirs++] = stralloc(dir); 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate dir = strtok((char *)NULL, DIRSEPS); 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate } 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate /* add a #include directory to the list for each view path source directory */ 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate void 1067c478bd9Sstevel@tonic-gate includedir(char *dirlist) 1077c478bd9Sstevel@tonic-gate { 1087c478bd9Sstevel@tonic-gate struct stat statstruct; 1097c478bd9Sstevel@tonic-gate char *dir; 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate /* don't change environment variable text */ 1127c478bd9Sstevel@tonic-gate dirlist = stralloc(dirlist); 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate /* parse the directory list */ 1157c478bd9Sstevel@tonic-gate dir = strtok(dirlist, DIRSEPS); 1167c478bd9Sstevel@tonic-gate while (dir != NULL) { 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate /* 1197c478bd9Sstevel@tonic-gate * make sure it is a directory (must exist in current 1207c478bd9Sstevel@tonic-gate * view path node) 1217c478bd9Sstevel@tonic-gate */ 1227c478bd9Sstevel@tonic-gate if (stat(compath(dir), &statstruct) == 0 && 123*4bc0a2efScasper S_ISDIR(statstruct.st_mode)) { 1247c478bd9Sstevel@tonic-gate if (incdirs == NULL) { 1257c478bd9Sstevel@tonic-gate incdirs = mymalloc(mincdirs * sizeof (char *)); 1267c478bd9Sstevel@tonic-gate } else if (nincdirs == mincdirs) { 1277c478bd9Sstevel@tonic-gate mincdirs += DIRINC; 1287c478bd9Sstevel@tonic-gate incdirs = myrealloc(incdirs, 1297c478bd9Sstevel@tonic-gate mincdirs * sizeof (char *)); 1307c478bd9Sstevel@tonic-gate } 1317c478bd9Sstevel@tonic-gate incdirs[nincdirs++] = stralloc(dir); 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate dir = strtok((char *)NULL, DIRSEPS); 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate /* make the source file list */ 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate void 1407c478bd9Sstevel@tonic-gate makefilelist(void) 1417c478bd9Sstevel@tonic-gate { 1427c478bd9Sstevel@tonic-gate static BOOL firstbuild = YES; /* first time through */ 1437c478bd9Sstevel@tonic-gate FILE *names; /* name file pointer */ 1447c478bd9Sstevel@tonic-gate char dir[PATHLEN + 1]; 1457c478bd9Sstevel@tonic-gate char path[PATHLEN + 1]; 1467c478bd9Sstevel@tonic-gate struct stat statstruct; 1477c478bd9Sstevel@tonic-gate char *file; 1487c478bd9Sstevel@tonic-gate char *s; 1497c478bd9Sstevel@tonic-gate int i, j; 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate /* if there are source file arguments */ 1527c478bd9Sstevel@tonic-gate if (fileargc > 0) { 1537c478bd9Sstevel@tonic-gate /* put them in a list that can be expanded */ 1547c478bd9Sstevel@tonic-gate for (i = 0; i < fileargc; ++i) { 1557c478bd9Sstevel@tonic-gate file = fileargv[i]; 1567c478bd9Sstevel@tonic-gate if (infilelist(file) == NO) { 1577c478bd9Sstevel@tonic-gate if (vpaccess(file, READ) == 0) { 1587c478bd9Sstevel@tonic-gate addsrcfile(file); 1597c478bd9Sstevel@tonic-gate } else { 1607c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1617c478bd9Sstevel@tonic-gate "cscope: cannot find file %s\n", 1627c478bd9Sstevel@tonic-gate file); 1637c478bd9Sstevel@tonic-gate errorsfound = YES; 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate return; 1687c478bd9Sstevel@tonic-gate } 1697c478bd9Sstevel@tonic-gate /* see if a file name file exists */ 1707c478bd9Sstevel@tonic-gate if (namefile == NULL && vpaccess(NAMEFILE, READ) == 0) { 1717c478bd9Sstevel@tonic-gate namefile = NAMEFILE; 1727c478bd9Sstevel@tonic-gate } 1737c478bd9Sstevel@tonic-gate /* if there is a file of source file names */ 1747c478bd9Sstevel@tonic-gate if (namefile != NULL) { 1757c478bd9Sstevel@tonic-gate if ((names = vpfopen(namefile, "r")) == NULL) { 1767c478bd9Sstevel@tonic-gate cannotopen(namefile); 1777c478bd9Sstevel@tonic-gate myexit(1); 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate /* get the names in the file */ 1807c478bd9Sstevel@tonic-gate while (fscanf(names, "%s", path) == 1) { 1817c478bd9Sstevel@tonic-gate if (*path == '-') { /* if an option */ 1827c478bd9Sstevel@tonic-gate i = path[1]; 1837c478bd9Sstevel@tonic-gate switch (i) { 1847c478bd9Sstevel@tonic-gate case 'q': /* quick search */ 1857c478bd9Sstevel@tonic-gate invertedindex = YES; 1867c478bd9Sstevel@tonic-gate break; 1877c478bd9Sstevel@tonic-gate case 'T': 1887c478bd9Sstevel@tonic-gate /* truncate symbols to 8 characters */ 1897c478bd9Sstevel@tonic-gate truncatesyms = YES; 1907c478bd9Sstevel@tonic-gate break; 1917c478bd9Sstevel@tonic-gate case 'I': /* #include file directory */ 1927c478bd9Sstevel@tonic-gate case 'p': /* file path components to */ 1937c478bd9Sstevel@tonic-gate /* display */ 1947c478bd9Sstevel@tonic-gate s = path + 2; /* for "-Ipath" */ 1957c478bd9Sstevel@tonic-gate if (*s == '\0') { /* if "-I path" */ 1967c478bd9Sstevel@tonic-gate (void) fscanf(names, 1977c478bd9Sstevel@tonic-gate "%s", path); 1987c478bd9Sstevel@tonic-gate s = path; 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate switch (i) { 2017c478bd9Sstevel@tonic-gate case 'I': /* #include file directory */ 2027c478bd9Sstevel@tonic-gate if (firstbuild == YES) { 2037c478bd9Sstevel@tonic-gate /* expand $ and ~ */ 2047c478bd9Sstevel@tonic-gate shellpath(dir, 2057c478bd9Sstevel@tonic-gate sizeof (dir), s); 2067c478bd9Sstevel@tonic-gate includedir(dir); 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate break; 2097c478bd9Sstevel@tonic-gate case 'p': 2107c478bd9Sstevel@tonic-gate /* file path components */ 2117c478bd9Sstevel@tonic-gate /* to display */ 2127c478bd9Sstevel@tonic-gate if (*s < '0' || *s > '9') { 2137c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2147c478bd9Sstevel@tonic-gate "cscope: -p option " 2157c478bd9Sstevel@tonic-gate "in file %s: " 2167c478bd9Sstevel@tonic-gate "missing or " 2177c478bd9Sstevel@tonic-gate "invalid numeric " 2187c478bd9Sstevel@tonic-gate "value\n", 2197c478bd9Sstevel@tonic-gate namefile); 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate dispcomponents = atoi(s); 2227c478bd9Sstevel@tonic-gate break; 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate break; 2257c478bd9Sstevel@tonic-gate default: 2267c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2277c478bd9Sstevel@tonic-gate "cscope: only -I, -p, and -T " 2287c478bd9Sstevel@tonic-gate "options can be in file %s\n", 2297c478bd9Sstevel@tonic-gate namefile); 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate } else if (vpaccess(path, READ) == 0) { 2327c478bd9Sstevel@tonic-gate addsrcfile(path); 2337c478bd9Sstevel@tonic-gate } else { 2347c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2357c478bd9Sstevel@tonic-gate "cscope: cannot find file %s\n", 2367c478bd9Sstevel@tonic-gate path); 2377c478bd9Sstevel@tonic-gate errorsfound = YES; 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate } 2407c478bd9Sstevel@tonic-gate (void) fclose(names); 2417c478bd9Sstevel@tonic-gate firstbuild = NO; 2427c478bd9Sstevel@tonic-gate return; 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate /* make a list of all the source files in the directories */ 2457c478bd9Sstevel@tonic-gate for (i = 0; i < nsrcdirs; ++i) { 2467c478bd9Sstevel@tonic-gate s = srcdirs[i]; 2477c478bd9Sstevel@tonic-gate getsrcfiles(s, s); 2487c478bd9Sstevel@tonic-gate if (*s != '/') { /* if it isn't a full path name */ 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate /* compute its path from any higher view path nodes */ 2517c478bd9Sstevel@tonic-gate for (j = 1; j < vpndirs; ++j) { 2527c478bd9Sstevel@tonic-gate (void) sprintf(dir, "%s/%s", vpdirs[j], s); 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate /* make sure it is a directory */ 2557c478bd9Sstevel@tonic-gate if (stat(compath(dir), &statstruct) == 0 && 256*4bc0a2efScasper S_ISDIR(statstruct.st_mode)) { 2577c478bd9Sstevel@tonic-gate getsrcfiles(dir, s); 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate } 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate /* get the source file names in this directory */ 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate static void 2677c478bd9Sstevel@tonic-gate getsrcfiles(char *vpdir, char *dir) 2687c478bd9Sstevel@tonic-gate { 2697c478bd9Sstevel@tonic-gate DIR *dirfile; /* directory file descriptor */ 2707c478bd9Sstevel@tonic-gate struct dirent *entry; /* directory entry pointer */ 2717c478bd9Sstevel@tonic-gate char path[PATHLEN + 1]; 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate /* attempt to open the directory */ 2747c478bd9Sstevel@tonic-gate if ((dirfile = opendir(vpdir)) != NULL) { 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate /* read each entry in the directory */ 2777c478bd9Sstevel@tonic-gate while ((entry = readdir(dirfile)) != NULL) { 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate /* if it is a source file not already found */ 2807c478bd9Sstevel@tonic-gate (void) sprintf(path, "%s/%s", dir, entry->d_name); 2817c478bd9Sstevel@tonic-gate if (entry->d_ino != 0 && 2827c478bd9Sstevel@tonic-gate issrcfile(path) && infilelist(path) == NO) { 2837c478bd9Sstevel@tonic-gate addsrcfile(path); /* add it to the list */ 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate } 2867c478bd9Sstevel@tonic-gate closedir(dirfile); 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate /* see if this is a source file */ 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate static BOOL 2937c478bd9Sstevel@tonic-gate issrcfile(char *file) 2947c478bd9Sstevel@tonic-gate { 2957c478bd9Sstevel@tonic-gate struct stat statstruct; 2967c478bd9Sstevel@tonic-gate char *s; 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate /* if there is a file suffix */ 2997c478bd9Sstevel@tonic-gate if ((s = strrchr(file, '.')) != NULL && *++s != '\0') { 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate /* if an SCCS or versioned file */ 3027c478bd9Sstevel@tonic-gate if (file[1] == '.' && file + 2 != s) { /* 1 character prefix */ 3037c478bd9Sstevel@tonic-gate switch (*file) { 3047c478bd9Sstevel@tonic-gate case 's': 3057c478bd9Sstevel@tonic-gate case 'S': 3067c478bd9Sstevel@tonic-gate return (NO); 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate if (s[1] == '\0') { /* 1 character suffix */ 3107c478bd9Sstevel@tonic-gate switch (*s) { 3117c478bd9Sstevel@tonic-gate case 'c': 3127c478bd9Sstevel@tonic-gate case 'h': 3137c478bd9Sstevel@tonic-gate case 'l': 3147c478bd9Sstevel@tonic-gate case 'y': 3157c478bd9Sstevel@tonic-gate case 'C': 3167c478bd9Sstevel@tonic-gate case 'G': 3177c478bd9Sstevel@tonic-gate case 'H': 3187c478bd9Sstevel@tonic-gate case 'L': 3197c478bd9Sstevel@tonic-gate return (YES); 3207c478bd9Sstevel@tonic-gate } 3217c478bd9Sstevel@tonic-gate } else if (s[2] == '\0') { /* 2 character suffix */ 3227c478bd9Sstevel@tonic-gate if (*s == 'b' && s[1] == 'p' || /* breakpoint listing */ 3237c478bd9Sstevel@tonic-gate *s == 'q' && 3247c478bd9Sstevel@tonic-gate (s[1] == 'c' || s[1] == 'h') || /* Ingres */ 3257c478bd9Sstevel@tonic-gate *s == 'p' && s[1] == 'r' || /* SDL */ 3267c478bd9Sstevel@tonic-gate *s == 's' && s[1] == 'd') { /* SDL */ 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate /* 3297c478bd9Sstevel@tonic-gate * some directories have 2 character 3307c478bd9Sstevel@tonic-gate * suffixes so make sure it is a file 3317c478bd9Sstevel@tonic-gate */ 3327c478bd9Sstevel@tonic-gate if (vpstat(file, &statstruct) == 0 && 333*4bc0a2efScasper S_ISREG(statstruct.st_mode)) { 3347c478bd9Sstevel@tonic-gate return (YES); 3357c478bd9Sstevel@tonic-gate } 3367c478bd9Sstevel@tonic-gate } 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate return (NO); 3407c478bd9Sstevel@tonic-gate } 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate /* add an include file to the source file list */ 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate void 3457c478bd9Sstevel@tonic-gate incfile(char *file, int type) 3467c478bd9Sstevel@tonic-gate { 3477c478bd9Sstevel@tonic-gate char path[PATHLEN + 1]; 3487c478bd9Sstevel@tonic-gate int i; 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate /* see if the file is already in the source file list */ 3517c478bd9Sstevel@tonic-gate if (infilelist(file) == YES) { 3527c478bd9Sstevel@tonic-gate return; 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate /* look in current directory if it was #include "file" */ 3557c478bd9Sstevel@tonic-gate if (type == '"' && vpaccess(file, READ) == 0) { 3567c478bd9Sstevel@tonic-gate addsrcfile(file); 3577c478bd9Sstevel@tonic-gate } else { 3587c478bd9Sstevel@tonic-gate /* search for the file in the #include directory list */ 3597c478bd9Sstevel@tonic-gate for (i = 0; i < nincdirs; ++i) { 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate /* don't include the file from two directories */ 3627c478bd9Sstevel@tonic-gate (void) sprintf(path, "%s/%s", incdirs[i], file); 3637c478bd9Sstevel@tonic-gate if (infilelist(path) == YES) { 3647c478bd9Sstevel@tonic-gate break; 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate /* make sure it exists and is readable */ 3677c478bd9Sstevel@tonic-gate if (vpaccess(compath(path), READ) == 0) { 3687c478bd9Sstevel@tonic-gate addsrcfile(path); 3697c478bd9Sstevel@tonic-gate break; 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate /* see if the file is already in the list */ 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate BOOL 3787c478bd9Sstevel@tonic-gate infilelist(char *file) 3797c478bd9Sstevel@tonic-gate { 3807c478bd9Sstevel@tonic-gate struct listitem *p; 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate for (p = srcfiletable[hash(compath(file)) % HASHMOD]; 3837c478bd9Sstevel@tonic-gate p != NULL; p = p->next) { 3847c478bd9Sstevel@tonic-gate if (strequal(file, p->file)) { 3857c478bd9Sstevel@tonic-gate return (YES); 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate return (NO); 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate /* add a source file to the list */ 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate void 3947c478bd9Sstevel@tonic-gate addsrcfile(char *path) 3957c478bd9Sstevel@tonic-gate { 3967c478bd9Sstevel@tonic-gate struct listitem *p; 3977c478bd9Sstevel@tonic-gate int i; 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate /* make sure there is room for the file */ 4007c478bd9Sstevel@tonic-gate if (nsrcfiles == msrcfiles) { 4017c478bd9Sstevel@tonic-gate msrcfiles += SRCINC; 4027c478bd9Sstevel@tonic-gate srcfiles = myrealloc(srcfiles, msrcfiles * sizeof (char *)); 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate /* add the file to the list */ 4057c478bd9Sstevel@tonic-gate p = (struct listitem *)mymalloc(sizeof (struct listitem)); 4067c478bd9Sstevel@tonic-gate p->file = stralloc(compath(path)); 4077c478bd9Sstevel@tonic-gate i = hash(p->file) % HASHMOD; 4087c478bd9Sstevel@tonic-gate p->next = srcfiletable[i]; 4097c478bd9Sstevel@tonic-gate srcfiletable[i] = p; 4107c478bd9Sstevel@tonic-gate srcfiles[nsrcfiles++] = p->file; 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate /* free the memory allocated for the source file list */ 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate void 4167c478bd9Sstevel@tonic-gate freefilelist(void) 4177c478bd9Sstevel@tonic-gate { 4187c478bd9Sstevel@tonic-gate struct listitem *p, *nextp; 4197c478bd9Sstevel@tonic-gate int i; 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate while (nsrcfiles > 0) { 4227c478bd9Sstevel@tonic-gate free(srcfiles[--nsrcfiles]); 4237c478bd9Sstevel@tonic-gate } 4247c478bd9Sstevel@tonic-gate for (i = 0; i < HASHMOD; ++i) { 4257c478bd9Sstevel@tonic-gate for (p = srcfiletable[i]; p != NULL; p = nextp) { 4267c478bd9Sstevel@tonic-gate nextp = p->next; 4277c478bd9Sstevel@tonic-gate free(p); 4287c478bd9Sstevel@tonic-gate } 4297c478bd9Sstevel@tonic-gate srcfiletable[i] = NULL; 4307c478bd9Sstevel@tonic-gate } 4317c478bd9Sstevel@tonic-gate } 432