ftp.nice.ch/pub/next/unix/developer/docgen.0.3.2.s.tar.gz#/docgen-0.3.2/files.c

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.