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