This is files.c in view mode; [Download] [Up]
/* docgen Objective C Document Generator Copyright (C) 1995 Bill Bereza. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Email: berezaw@river.it.gvsu.edu S-mail: Bill Bereza 9526 Judson Rd. Ravenna, MI 49451-9427 */ /* docgen Objective C Document Generator * Copyright (c) 1994 Bill Bereza * * $Log: files.c,v $ * Revision 1.7 96/01/07 01:29:26 berezaw * added hashtable caching of return values for findfile * a %700 increase in performance! * * Revision 1.6 95/07/26 21:46:18 berezaw * *** empty log message *** * * Revision 1.5 95/07/21 21:40:12 berezaw * *** empty log message *** * * Revision 1.4 95/07/20 00:30:19 berezaw * changed struct direct to struct dirent through the entire file * * Revision 1.3 95/03/02 03:44:43 berezaw * using GNU regex library * rewrote recmp() as docgen_recmp() * added GPL stuff to each file * increase rev. to 0.1.9 * * Revision 1.2 94/11/28 12:08:32 berezaw * *** empty log message *** * * * $Header: /Users/berezaw/src/docgen/test/RCS/files.c,v 1.7 96/01/07 01:29:26 berezaw Exp $ */ #include "docgen.h" #include <assert.h> #define H_SIZE 1024 char null_string[]="..."; char **file_hash; char **file_val; static void init_hash() { int loop; file_hash=calloc(H_SIZE, sizeof(char *)); file_val =calloc(H_SIZE, sizeof(char *)); if(V_USELESS) fprintf(stderr, "init_hash\n"); for(loop=0;loop<H_SIZE;loop++) { file_val[loop]=file_hash[loop]=NULL; } } static int shash(char *st) { int hash, loop, len; len=strlen(st); hash=st[0]; for(loop=0;loop<len;loop++) { hash=(hash * 32 + st[loop]) % H_SIZE; } return hash; } static int find_val(char *key) { int coll=0, pos; pos=shash(key); while(file_hash[pos] && strcmp(key, file_hash[pos]) && coll<H_SIZE) { assert(pos<H_SIZE); coll++; pos=pos+2*coll-1; if(pos>=H_SIZE) pos-=H_SIZE; } if(file_hash[pos]) { if(V_USELESS) fprintf(stderr, "find_val:found val %s for key %s at pos %d\n", file_val[pos], key, pos); } else { if(V_USELESS) fprintf(stderr, "find_val:could not find val for key %s at pos %d\n", key, pos); } return pos; } static void add_key_val(char *key, char *val) { char *valcp=NULL; char *keycp=NULL; int pos; keycp=malloc(strlen(key)+1); if(!keycp) return; strcpy(keycp, key); pos=find_val(key); if(val) { valcp=malloc(strlen(val)+1); if(!valcp) { free(keycp); return; } strcpy(valcp, val); } if(!file_hash[pos]) { file_hash[pos]=keycp; file_val[pos]=(valcp ? valcp : null_string) ; if(V_USELESS) fprintf(stderr, "findfile: adding key %s, val %s, pos %d\n", key, val, pos); } else { free(keycp); free(valcp); } } char *_findfile(char *, char *); char *findfile(char *name, char *dir) { static int first=1; char *ret; int pos; char *full; char *t; if(first) { init_hash(); first=0; } full=dirfile(dir, name); pos=find_val(full); if(file_hash[pos]) { if(V_USELESS) fprintf(stderr, "findfile: returning %s from hashtable\n", file_val[pos]); free(full); ret = (!strcmp(file_val[pos], null_string)) ? NULL : file_val[pos]; if(!ret) return NULL; t=malloc(strlen(ret)+1); if(!t) return NULL; strcpy(t,ret); return t; } else { ret=_findfile(name, dir); add_key_val(full, ret); free(full); return ret; } } /* Just in case I switch over to requiring Objective-C char *findfile(char *name, char *dir) { static HashTable fileTable=nil; char *value; char *key; char nulls[]="..."; char *valcp; if(!fileTable) { fileTable=[[HashTable alloc] initKeyDesc:"*" valueDesc:"*"]; } key=dirfile(dir, name); value=(char *)[fileTable valueForKey:key]; if(!value) { value=_findfile(name, dir); if(value) { valcp=malloc(strlen(value)+1); strcpy(valcp, value); } else { valcp=nulls; } [fileTable insertKey:key value:valcp]; } if(!strcmp(value, nulls)) { return NULL; } else { return value; } } */ char *_findfile(char *name, char *dir) { struct dirent *dp; DIR *dfd; static char errmess[1024]; char *newf=NULL; char *fulldir; struct stat stbuf; #ifndef NODEBUG if(V_USELESS) fprintf(stderr, "findfile(%s, %s)\n", dir, name); #endif if((dfd=opendir(dir)) == NULL) { sprintf(errmess, "findfile: Are you sure about this dir?\n%.1000s",dir); if(V_BADERR) perror(errmess); return NULL; } while (((dp=readdir(dfd)) != NULL) && (newf==NULL)) { if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) continue; /* skip self and parent */ fulldir=dirfile(dir, dp->d_name); if(stat(fulldir, &stbuf) == -1) { #ifndef NODEBUG if(V_ERR) fprintf(stderr,"findfile: error getting stats of \n%s\n", fulldir); #endif free(fulldir); continue; } else if((stbuf.st_mode & S_IFMT) == S_IFDIR) { newf=_findfile(name, fulldir); free(fulldir); } else if(!strcmp(dp->d_name, name)) newf=fulldir; else free(fulldir); } closedir(dfd); #ifndef NODEBUG if(V_USELESS) fprintf(stderr, "findfile: returning\n%s\n",newf); #endif return newf; } /* blatantly copied from K&R */ void dirwalk(char *dir, void (*fcn)(char *, char *, char *, char *), char *odir, char *hdir) { struct dirent *dp; DIR *dfd; char errmess[1024]; #ifndef NODEBUG if(V_USELESS) fprintf(stderr, "dirwalk(%s, func, %s, %s)\n", dir, odir, hdir); #endif if((dfd=opendir(dir)) == NULL) { sprintf(errmess, "dirwalk: Are you sure about this dir?\n%.1000s",dir); if(V_BADERR) perror(errmess); return; } while ((dp=readdir(dfd)) != NULL) { if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) continue; /* skip self and parent */ (*fcn)(dp->d_name, dir, odir, hdir); } closedir(dfd); #ifndef NODEBUG if(V_USELESS) fprintf(stderr, "dirwalk: returning\n"); #endif } void procfile(char *name, char *idir, char *odir, char *hdir) { struct stat stbuf; char *dir; char errmess[1024]; dir=dirfile(idir, name); #ifndef NODEBUG if(V_USELESS) printf("procfile( %s, %s, %s, %s)\n", name, idir, odir, hdir); #endif if(stat(dir, &stbuf) == -1) { sprintf(errmess,"procfile: can't access this file\n%.800s/%.200s",idir, name); if(V_BADERR) perror(errmess); return; } if((stbuf.st_mode & S_IFMT) == S_IFDIR) dirwalk(dir, procfile, odir, hdir); else if(strstr(&name[strlen(name)-3], ".m") != NULL) procm(name, idir, odir, hdir); free(dir); #ifndef NODEBUG if(V_USELESS) fprintf(stderr, "procfile: returning\n"); #endif } char *dirfile(char *idir, char *name) { DSTRING *ddir; char *dir; #ifndef NODEBUG if(V_USELESS) fprintf(stderr, "dirfile(%s, %s)\n", idir, name); #endif ddir=dstrarr(idir); dstrarrcat(ddir, "/"); dstrarrcat(ddir, name); dir=arrdstr(ddir); freedstr(ddir); #ifndef NODEBUG if(V_USELESS) fprintf(stderr, "dirfile: returning with %s\n", dir); #endif return dir; } void procm(char *mname, char *idir, char *odir, char *hdir) { DSTRING *dhname; char *hname, *fqmname, *fqhname, *rtfname, *fqrtfname; int parseret; #ifndef NODEBUG if(V_USELESS) fprintf(stderr,"procm(%s, %s, %s, %s)\n",mname, idir, odir, hdir); #endif /* remove '.m' from file name and add '.h' */ dhname=dstrarr(mname); free(arrdstrrmfromtail(dhname, 2)); /* This function allocates memory * so it must be free'd */ dstrarrcat(dhname, ".h"); hname=arrdstr(dhname); /* plain name of '.h' file */ /* mname is the plain name of the '.m' file */ /* remove '.h' from file name and add '.rtf' */ free(arrdstrrmfromtail(dhname, 2)); daddchar(dhname,'.'); dstrarrcat(dhname, [[myForm class] fileExtension]); rtfname=arrdstr(dhname); /* plain name of '.rtf' file */ fqmname= dirfile(idir, mname); /* FQN of '.m' file */ fqhname= dirfile(idir, hname); /* FQN of '.h' file */ fqrtfname= dirfile(odir, rtfname); /* FQN of '.rtf' file */ parseret=parseobjc(fqmname, fqhname, fqrtfname, hdir); #ifndef NODEBUG if(parseret<0) if(V_STAT) fprintf(stderr, "Couldn't parse with the following args\nidir = [%s]\nfqmname = [%s]\nfqhanem = [%s]\nodir = [%s]\nhdir = [%s]\n", idir, fqmname, fqhname, odir, hdir); #endif /* free all the things we've created */ freedstr(dhname); free(hname); free(fqmname); free(fqhname); free(rtfname); free(fqrtfname); #ifndef NODEBUG if(V_USELESS) fprintf(stderr, "procm: returning\n"); #endif }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.