112913Sgarrison #ifndef lint 2*23486Sgarrison static char sccsid[] = "@(#)locate.c 2.4 06/10/85"; 313111Srrh #endif not lint 415062Sgarrison # 512913Sgarrison 612913Sgarrison # include "stdio.h" 712913Sgarrison # include "streams.h" 812913Sgarrison # include "ctype.h" 912913Sgarrison # define maxrefs 200 1012913Sgarrison 1112913Sgarrison struct reftype{ 1215062Sgarrison char reffile[maxstr]; 1312913Sgarrison long int start, length; 1412913Sgarrison }; 1512913Sgarrison 16*23486Sgarrison char *calloc(); 1712913Sgarrison char *rindex(); 1812913Sgarrison char *stripkeys(); 1912913Sgarrison int fetchref(); 2012913Sgarrison 2112913Sgarrison /* locate(keys, name, max_klen, common): 2212913Sgarrison Returns a string containing all references pointed to by name 2312913Sgarrison that contain all keys in keys. Common is name of common word file. 24*23486Sgarrison Pointer returned comes from calloc. Use free to return storage. 2512913Sgarrison NB A zero length string returned if nothing is found. 2612913Sgarrison A NULL pointer indicates an error accessing the file "name". 2712913Sgarrison */ 2815889Srrh int fflag; /* set if want the reference string to have the file name*/ 2912913Sgarrison char *locate(keys,name,max_klen,common) 3012913Sgarrison char *keys, *name, *common; 3112913Sgarrison int max_klen; /* max key length */ 3212913Sgarrison { static char oldname[maxstr] = ""; /* oldname is name of stream index */ 3312913Sgarrison static FILE *index = NULL; 3412913Sgarrison static long int i_size; /* size of index */ 3512913Sgarrison static char oldtext[maxstr]; /* oldtext is the path to stream */ 3612913Sgarrison static FILE *text = NULL; /* text. if it is a relative */ 3712913Sgarrison static int pathlen; /* path, it is relative to index */ 3812913Sgarrison /* directory. */ 3912913Sgarrison /* oldname[0..pathlen-1] is index */ 4012913Sgarrison /* directory */ 4112913Sgarrison int len; 4212913Sgarrison char key[maxstr]; /* refs[i] is a line of index for */ 4312913Sgarrison struct reftype refs[maxrefs]; /* all keys up to key */ 4412913Sgarrison 4512913Sgarrison int refcnt, copied, comp; /* refcnt = # of refs */ 4612913Sgarrison /* copied = # of refs copied */ 4712913Sgarrison /* comp = # of refs compared */ 4812913Sgarrison struct reftype ref; 4912913Sgarrison char str[maxstr]; 5012913Sgarrison int more; 5112913Sgarrison 5212913Sgarrison long int ans; 5312913Sgarrison int i,j; 5412913Sgarrison unsigned total; 5512913Sgarrison char *allrefs, *next; /* all refs (separated by null line)*/ 5612913Sgarrison char *p; 5712913Sgarrison 5812913Sgarrison /* open index */ 5912913Sgarrison if (strcmp(oldname,name)!=0) 6012913Sgarrison { if (index) fclose(index); 6112913Sgarrison if (text) fclose(text); 6212913Sgarrison strcpy(oldname,name); 6312913Sgarrison strcpy(oldtext,""); 6412913Sgarrison /* determine pathlen */ 6512913Sgarrison p= rindex(oldname, '/'); 6612913Sgarrison if (p!=NULL) pathlen= p-oldname+1; 6712913Sgarrison else pathlen= 0; 6812913Sgarrison 6912913Sgarrison index= fopen(oldname,"r"); 7012913Sgarrison if (index==NULL) 7112913Sgarrison { fprintf(stderr, "locate: cannot open %s\n", oldname); 7212913Sgarrison strcpy(oldname, ""); 7312913Sgarrison return(NULL); 7412913Sgarrison } 7512913Sgarrison else 7612913Sgarrison { fseek(index,0L,2); /* seeks last newline */ 7712913Sgarrison i_size= ftell(index); 7812913Sgarrison } 7912913Sgarrison 8012913Sgarrison } 8112913Sgarrison 8212913Sgarrison /* load references to first key */ 8312913Sgarrison keys= stripkeys(keys,key, max_klen, common); 8412913Sgarrison if (*key==NULL) 8512913Sgarrison { fprintf(stderr,"locate: no keys for citation\n"); 86*23486Sgarrison allrefs = (char *) calloc(1, sizeof (char)); 8712913Sgarrison if (allrefs==NULL) 8812913Sgarrison { fprintf(stderr, 8912913Sgarrison "locate: insufficient space for references\n"); 9012913Sgarrison exit(1); 9112913Sgarrison } 9212913Sgarrison *allrefs= NULL; 9312913Sgarrison return(allrefs); 9412913Sgarrison } 9512913Sgarrison len= strlen(key); 9612913Sgarrison strcat(key," "); 9712913Sgarrison alpha_seek(index, key, i_size, 0); 9812913Sgarrison key[len]= NULL; /* strip blank off */ 9912913Sgarrison 10012913Sgarrison refcnt= 0; 10112913Sgarrison fscanf(index,"%s ", str); 10212913Sgarrison if (strcmp(str,key) == 0) 10312913Sgarrison { str[0]= NULL; 10412913Sgarrison while (refcnt < maxrefs && fetchref(index, str, &ref) ) 10512913Sgarrison { refs[refcnt]= ref; 10612913Sgarrison refcnt++; 10712913Sgarrison } 10812913Sgarrison } 10912913Sgarrison 11012913Sgarrison if (refcnt==maxrefs) 11112913Sgarrison fprintf(stderr, 11212913Sgarrison "locate: first key (%s) matched too many refs\n", key); 11312913Sgarrison 11412913Sgarrison /* intersect the reference sets for remaining keys with first set */ 11512913Sgarrison while (*keys!=NULL) 11612913Sgarrison { keys= stripkeys(keys, key, max_klen, common); 11712913Sgarrison if (*key==NULL) continue; 11812913Sgarrison 11912913Sgarrison len= strlen(key); 12012913Sgarrison strcat(key," "); 12112913Sgarrison alpha_seek(index, key, i_size, 0); 12212913Sgarrison key[len]= NULL; 12312913Sgarrison 12412913Sgarrison fscanf(index,"%s ", str); 12512913Sgarrison if (strcmp(str,key) != 0) refcnt= 0; /* no matching refs */ 12612913Sgarrison 12712913Sgarrison copied= 0; comp= 0; more= fetchref(index, str, &ref); 12812913Sgarrison while (comp < refcnt && more) 12912913Sgarrison { /* ans= ref-refs[comp] */ 13012913Sgarrison ans= strcmp(ref.reffile, refs[comp].reffile); 13112913Sgarrison if (ans==0) ans= ref.start-refs[comp].start; 13212913Sgarrison if (ans==0) ans= ref.length-refs[comp].length; 13312913Sgarrison if (ans<0) more= fetchref(index, str, &ref); 13412913Sgarrison if (ans==0) { refs[copied]= refs[comp]; comp++; copied++; 13512913Sgarrison more= fetchref(index, str, &ref);} 13612913Sgarrison if (ans>0) comp++; 13712913Sgarrison } 13812913Sgarrison 13912913Sgarrison refcnt= copied; 14012913Sgarrison } 14112913Sgarrison 14215062Sgarrison total= 0; 14315062Sgarrison for (i=0; i<refcnt; i++) total += refs[i].length+1; 14415889Srrh if (fflag){ 14515889Srrh total += strlen(refs[i].reffile) + 1; 14615889Srrh } 14715062Sgarrison 148*23486Sgarrison allrefs= (char *) calloc(total+1, sizeof (char)); 14915062Sgarrison if (allrefs==NULL) 15015062Sgarrison { fprintf(stderr, "locate: insufficient space for references\n"); 15115062Sgarrison exit(1); 15215062Sgarrison } 15315062Sgarrison 15415062Sgarrison /* copy refs into allrefs */ 15515062Sgarrison next= allrefs; 15612913Sgarrison for (i=0; i<refcnt; i++) 15712913Sgarrison { /* open text */ 15812913Sgarrison if (strcmp(oldtext,refs[i].reffile) != 0) 15912913Sgarrison { strcpy(oldtext,refs[i].reffile); 16012913Sgarrison if (oldtext[0]=='/') 16112913Sgarrison { /* absolute path */ 16212913Sgarrison strcpy(str,oldtext); 16312913Sgarrison } else 16412913Sgarrison { /* relative name */ 16512913Sgarrison strncpy(str, oldname, pathlen); str[pathlen]= NULL; 16612913Sgarrison strcat(str, oldtext); 16712913Sgarrison } 16812913Sgarrison if (text) fclose(text); 16912913Sgarrison text= fopen(str, "r"); 17012913Sgarrison if (text==NULL) 17112913Sgarrison { fprintf(stderr, "locate: cannot open %s\n", str); 17212913Sgarrison strcpy(oldtext, ""); 17312913Sgarrison return(NULL); 17412913Sgarrison } 17512913Sgarrison } 17612913Sgarrison fseek(text, refs[i].start, 0); 17715889Srrh if (fflag){ 17815889Srrh strcat(next, refs[i].reffile); 17915889Srrh next += strlen(next); 18015889Srrh *next++ = '\n'; 18115889Srrh *next = 0; 18215889Srrh } 18312913Sgarrison for (j=0; j<refs[i].length; j++) *next++ = getc(text); 18412913Sgarrison *next++ = '\n'; 18512913Sgarrison } 18612913Sgarrison *next = NULL; 18712913Sgarrison return(allrefs); 18812913Sgarrison } 18912913Sgarrison 19012913Sgarrison 19112913Sgarrison 19212913Sgarrison /* stripkeys(line,key,max_klen, common): 19312913Sgarrison assigns to key the first key in line 19412913Sgarrison and returns a pointer to the position following the key 19512913Sgarrison */ 19612913Sgarrison char *stripkeys(line,key,max_klen,common) 19712913Sgarrison char *line, *key; 19812913Sgarrison int max_klen; 19912913Sgarrison char *common; 20012913Sgarrison { char *p; 20112913Sgarrison 20212913Sgarrison do 20312913Sgarrison { while (isspace(*line)) line++; 20412913Sgarrison 20512913Sgarrison p= key; 20612913Sgarrison while (*line!=NULL && !isspace(*line)) 20712913Sgarrison { *p++ = *line++; 20812913Sgarrison } 20912913Sgarrison *p= NULL; 21012913Sgarrison 21112913Sgarrison makekey(key, max_klen, common); 21212913Sgarrison } while (*key==NULL && *line!=NULL); 21312913Sgarrison return(line); 21412913Sgarrison } 21512913Sgarrison 21612913Sgarrison /* read a reference pair from stream into *ref. if file not given, 21712913Sgarrison use oldfile. return 1 if pair found, 0 ow. 21812913Sgarrison */ 21912913Sgarrison int fetchref(stream, oldfile, ref) 22012913Sgarrison FILE *stream; 22112913Sgarrison char *oldfile; 22212913Sgarrison struct reftype *ref; 22312913Sgarrison { char cntl; 22412913Sgarrison 22512913Sgarrison fscanf(stream, "%c", &cntl); 22612913Sgarrison if (cntl=='\n') {return (0);} 22712913Sgarrison if (cntl==':') fscanf(stream, "%s", oldfile); 22812913Sgarrison strcpy(ref->reffile, oldfile); 22915062Sgarrison fscanf(stream, "%D/%D", &ref->start, &ref->length); 23012913Sgarrison return(1); 23112913Sgarrison } 232