112913Sgarrison #ifndef lint 2*23493Sgarrison static char sccsid[] = "@(#)locate.c 2.5 06/11/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 1623486Sgarrison 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. 2423486Sgarrison 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"); 8623486Sgarrison 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; 143*23493Sgarrison for (i=0; i<refcnt; i++) { 144*23493Sgarrison total += refs[i].length+1; 145*23493Sgarrison if (fflag){ 146*23493Sgarrison total += strlen(refs[i].reffile) + 1; 147*23493Sgarrison } 14815889Srrh } 14915062Sgarrison 15023486Sgarrison allrefs= (char *) calloc(total+1, sizeof (char)); 15115062Sgarrison if (allrefs==NULL) 15215062Sgarrison { fprintf(stderr, "locate: insufficient space for references\n"); 15315062Sgarrison exit(1); 15415062Sgarrison } 15515062Sgarrison 15615062Sgarrison /* copy refs into allrefs */ 15715062Sgarrison next= allrefs; 15812913Sgarrison for (i=0; i<refcnt; i++) 15912913Sgarrison { /* open text */ 16012913Sgarrison if (strcmp(oldtext,refs[i].reffile) != 0) 16112913Sgarrison { strcpy(oldtext,refs[i].reffile); 16212913Sgarrison if (oldtext[0]=='/') 16312913Sgarrison { /* absolute path */ 16412913Sgarrison strcpy(str,oldtext); 16512913Sgarrison } else 16612913Sgarrison { /* relative name */ 16712913Sgarrison strncpy(str, oldname, pathlen); str[pathlen]= NULL; 16812913Sgarrison strcat(str, oldtext); 16912913Sgarrison } 17012913Sgarrison if (text) fclose(text); 17112913Sgarrison text= fopen(str, "r"); 17212913Sgarrison if (text==NULL) 17312913Sgarrison { fprintf(stderr, "locate: cannot open %s\n", str); 17412913Sgarrison strcpy(oldtext, ""); 17512913Sgarrison return(NULL); 17612913Sgarrison } 17712913Sgarrison } 17812913Sgarrison fseek(text, refs[i].start, 0); 17915889Srrh if (fflag){ 18015889Srrh strcat(next, refs[i].reffile); 18115889Srrh next += strlen(next); 18215889Srrh *next++ = '\n'; 18315889Srrh *next = 0; 18415889Srrh } 18512913Sgarrison for (j=0; j<refs[i].length; j++) *next++ = getc(text); 18612913Sgarrison *next++ = '\n'; 18712913Sgarrison } 18812913Sgarrison *next = NULL; 18912913Sgarrison return(allrefs); 19012913Sgarrison } 19112913Sgarrison 19212913Sgarrison 19312913Sgarrison 19412913Sgarrison /* stripkeys(line,key,max_klen, common): 19512913Sgarrison assigns to key the first key in line 19612913Sgarrison and returns a pointer to the position following the key 19712913Sgarrison */ 19812913Sgarrison char *stripkeys(line,key,max_klen,common) 19912913Sgarrison char *line, *key; 20012913Sgarrison int max_klen; 20112913Sgarrison char *common; 20212913Sgarrison { char *p; 20312913Sgarrison 20412913Sgarrison do 20512913Sgarrison { while (isspace(*line)) line++; 20612913Sgarrison 20712913Sgarrison p= key; 20812913Sgarrison while (*line!=NULL && !isspace(*line)) 20912913Sgarrison { *p++ = *line++; 21012913Sgarrison } 21112913Sgarrison *p= NULL; 21212913Sgarrison 21312913Sgarrison makekey(key, max_klen, common); 21412913Sgarrison } while (*key==NULL && *line!=NULL); 21512913Sgarrison return(line); 21612913Sgarrison } 21712913Sgarrison 21812913Sgarrison /* read a reference pair from stream into *ref. if file not given, 21912913Sgarrison use oldfile. return 1 if pair found, 0 ow. 22012913Sgarrison */ 22112913Sgarrison int fetchref(stream, oldfile, ref) 22212913Sgarrison FILE *stream; 22312913Sgarrison char *oldfile; 22412913Sgarrison struct reftype *ref; 22512913Sgarrison { char cntl; 22612913Sgarrison 22712913Sgarrison fscanf(stream, "%c", &cntl); 22812913Sgarrison if (cntl=='\n') {return (0);} 22912913Sgarrison if (cntl==':') fscanf(stream, "%s", oldfile); 23012913Sgarrison strcpy(ref->reffile, oldfile); 23115062Sgarrison fscanf(stream, "%D/%D", &ref->start, &ref->length); 23212913Sgarrison return(1); 23312913Sgarrison } 234