112913Sgarrison #ifndef lint 2*15062Sgarrison static char sccsid[] = "@(#)locate.c 2.2 09/23/83"; 313111Srrh #endif not lint 4*15062Sgarrison # 512913Sgarrison 612913Sgarrison # include "stdio.h" 712913Sgarrison # include "streams.h" 812913Sgarrison # include "ctype.h" 912913Sgarrison # define maxrefs 200 1012913Sgarrison 1112913Sgarrison struct reftype{ 12*15062Sgarrison char reffile[maxstr]; 1312913Sgarrison long int start, length; 1412913Sgarrison }; 1512913Sgarrison 1612913Sgarrison char *malloc(); 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. 2412913Sgarrison Pointer returned comes from malloc. 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 */ 2812913Sgarrison char *locate(keys,name,max_klen,common) 2912913Sgarrison char *keys, *name, *common; 3012913Sgarrison int max_klen; /* max key length */ 3112913Sgarrison { static char oldname[maxstr] = ""; /* oldname is name of stream index */ 3212913Sgarrison static FILE *index = NULL; 3312913Sgarrison static long int i_size; /* size of index */ 3412913Sgarrison static char oldtext[maxstr]; /* oldtext is the path to stream */ 3512913Sgarrison static FILE *text = NULL; /* text. if it is a relative */ 3612913Sgarrison static int pathlen; /* path, it is relative to index */ 3712913Sgarrison /* directory. */ 3812913Sgarrison /* oldname[0..pathlen-1] is index */ 3912913Sgarrison /* directory */ 4012913Sgarrison int len; 4112913Sgarrison char key[maxstr]; /* refs[i] is a line of index for */ 4212913Sgarrison struct reftype refs[maxrefs]; /* all keys up to key */ 4312913Sgarrison 4412913Sgarrison int refcnt, copied, comp; /* refcnt = # of refs */ 4512913Sgarrison /* copied = # of refs copied */ 4612913Sgarrison /* comp = # of refs compared */ 4712913Sgarrison struct reftype ref; 4812913Sgarrison char str[maxstr]; 4912913Sgarrison int more; 5012913Sgarrison 5112913Sgarrison long int ans; 5212913Sgarrison int i,j; 5312913Sgarrison unsigned total; 5412913Sgarrison char *allrefs, *next; /* all refs (separated by null line)*/ 5512913Sgarrison char *p; 5612913Sgarrison 5712913Sgarrison /* open index */ 5812913Sgarrison if (strcmp(oldname,name)!=0) 5912913Sgarrison { if (index) fclose(index); 6012913Sgarrison if (text) fclose(text); 6112913Sgarrison strcpy(oldname,name); 6212913Sgarrison strcpy(oldtext,""); 6312913Sgarrison /* determine pathlen */ 6412913Sgarrison p= rindex(oldname, '/'); 6512913Sgarrison if (p!=NULL) pathlen= p-oldname+1; 6612913Sgarrison else pathlen= 0; 6712913Sgarrison 6812913Sgarrison index= fopen(oldname,"r"); 6912913Sgarrison if (index==NULL) 7012913Sgarrison { fprintf(stderr, "locate: cannot open %s\n", oldname); 7112913Sgarrison strcpy(oldname, ""); 7212913Sgarrison return(NULL); 7312913Sgarrison } 7412913Sgarrison else 7512913Sgarrison { fseek(index,0L,2); /* seeks last newline */ 7612913Sgarrison i_size= ftell(index); 7712913Sgarrison } 7812913Sgarrison 7912913Sgarrison } 8012913Sgarrison 8112913Sgarrison /* load references to first key */ 8212913Sgarrison keys= stripkeys(keys,key, max_klen, common); 8312913Sgarrison if (*key==NULL) 8412913Sgarrison { fprintf(stderr,"locate: no keys for citation\n"); 8512913Sgarrison allrefs = malloc(1); 8612913Sgarrison if (allrefs==NULL) 8712913Sgarrison { fprintf(stderr, 8812913Sgarrison "locate: insufficient space for references\n"); 8912913Sgarrison exit(1); 9012913Sgarrison } 9112913Sgarrison *allrefs= NULL; 9212913Sgarrison return(allrefs); 9312913Sgarrison } 9412913Sgarrison len= strlen(key); 9512913Sgarrison strcat(key," "); 9612913Sgarrison alpha_seek(index, key, i_size, 0); 9712913Sgarrison key[len]= NULL; /* strip blank off */ 9812913Sgarrison 9912913Sgarrison refcnt= 0; 10012913Sgarrison fscanf(index,"%s ", str); 10112913Sgarrison if (strcmp(str,key) == 0) 10212913Sgarrison { str[0]= NULL; 10312913Sgarrison while (refcnt < maxrefs && fetchref(index, str, &ref) ) 10412913Sgarrison { refs[refcnt]= ref; 10512913Sgarrison refcnt++; 10612913Sgarrison } 10712913Sgarrison } 10812913Sgarrison 10912913Sgarrison if (refcnt==maxrefs) 11012913Sgarrison fprintf(stderr, 11112913Sgarrison "locate: first key (%s) matched too many refs\n", key); 11212913Sgarrison 11312913Sgarrison /* intersect the reference sets for remaining keys with first set */ 11412913Sgarrison while (*keys!=NULL) 11512913Sgarrison { keys= stripkeys(keys, key, max_klen, common); 11612913Sgarrison if (*key==NULL) continue; 11712913Sgarrison 11812913Sgarrison len= strlen(key); 11912913Sgarrison strcat(key," "); 12012913Sgarrison alpha_seek(index, key, i_size, 0); 12112913Sgarrison key[len]= NULL; 12212913Sgarrison 12312913Sgarrison fscanf(index,"%s ", str); 12412913Sgarrison if (strcmp(str,key) != 0) refcnt= 0; /* no matching refs */ 12512913Sgarrison 12612913Sgarrison copied= 0; comp= 0; more= fetchref(index, str, &ref); 12712913Sgarrison while (comp < refcnt && more) 12812913Sgarrison { /* ans= ref-refs[comp] */ 12912913Sgarrison ans= strcmp(ref.reffile, refs[comp].reffile); 13012913Sgarrison if (ans==0) ans= ref.start-refs[comp].start; 13112913Sgarrison if (ans==0) ans= ref.length-refs[comp].length; 13212913Sgarrison if (ans<0) more= fetchref(index, str, &ref); 13312913Sgarrison if (ans==0) { refs[copied]= refs[comp]; comp++; copied++; 13412913Sgarrison more= fetchref(index, str, &ref);} 13512913Sgarrison if (ans>0) comp++; 13612913Sgarrison } 13712913Sgarrison 13812913Sgarrison refcnt= copied; 13912913Sgarrison } 14012913Sgarrison 141*15062Sgarrison total= 0; 142*15062Sgarrison for (i=0; i<refcnt; i++) total += refs[i].length+1; 143*15062Sgarrison 144*15062Sgarrison allrefs= malloc(total+1); 145*15062Sgarrison if (allrefs==NULL) 146*15062Sgarrison { fprintf(stderr, "locate: insufficient space for references\n"); 147*15062Sgarrison exit(1); 148*15062Sgarrison } 149*15062Sgarrison 150*15062Sgarrison /* copy refs into allrefs */ 151*15062Sgarrison next= allrefs; 15212913Sgarrison for (i=0; i<refcnt; i++) 15312913Sgarrison { /* open text */ 15412913Sgarrison if (strcmp(oldtext,refs[i].reffile) != 0) 15512913Sgarrison { strcpy(oldtext,refs[i].reffile); 15612913Sgarrison if (oldtext[0]=='/') 15712913Sgarrison { /* absolute path */ 15812913Sgarrison strcpy(str,oldtext); 15912913Sgarrison } else 16012913Sgarrison { /* relative name */ 16112913Sgarrison strncpy(str, oldname, pathlen); str[pathlen]= NULL; 16212913Sgarrison strcat(str, oldtext); 16312913Sgarrison } 16412913Sgarrison if (text) fclose(text); 16512913Sgarrison text= fopen(str, "r"); 16612913Sgarrison if (text==NULL) 16712913Sgarrison { fprintf(stderr, "locate: cannot open %s\n", str); 16812913Sgarrison strcpy(oldtext, ""); 16912913Sgarrison return(NULL); 17012913Sgarrison } 17112913Sgarrison } 17212913Sgarrison fseek(text, refs[i].start, 0); 17312913Sgarrison for (j=0; j<refs[i].length; j++) *next++ = getc(text); 17412913Sgarrison *next++ = '\n'; 17512913Sgarrison } 17612913Sgarrison *next = NULL; 17712913Sgarrison return(allrefs); 17812913Sgarrison } 17912913Sgarrison 18012913Sgarrison 18112913Sgarrison 18212913Sgarrison /* stripkeys(line,key,max_klen, common): 18312913Sgarrison assigns to key the first key in line 18412913Sgarrison and returns a pointer to the position following the key 18512913Sgarrison */ 18612913Sgarrison char *stripkeys(line,key,max_klen,common) 18712913Sgarrison char *line, *key; 18812913Sgarrison int max_klen; 18912913Sgarrison char *common; 19012913Sgarrison { char *p; 19112913Sgarrison 19212913Sgarrison do 19312913Sgarrison { while (isspace(*line)) line++; 19412913Sgarrison 19512913Sgarrison p= key; 19612913Sgarrison while (*line!=NULL && !isspace(*line)) 19712913Sgarrison { *p++ = *line++; 19812913Sgarrison } 19912913Sgarrison *p= NULL; 20012913Sgarrison 20112913Sgarrison makekey(key, max_klen, common); 20212913Sgarrison } while (*key==NULL && *line!=NULL); 20312913Sgarrison return(line); 20412913Sgarrison } 20512913Sgarrison 20612913Sgarrison /* read a reference pair from stream into *ref. if file not given, 20712913Sgarrison use oldfile. return 1 if pair found, 0 ow. 20812913Sgarrison */ 20912913Sgarrison int fetchref(stream, oldfile, ref) 21012913Sgarrison FILE *stream; 21112913Sgarrison char *oldfile; 21212913Sgarrison struct reftype *ref; 21312913Sgarrison { char cntl; 21412913Sgarrison 21512913Sgarrison fscanf(stream, "%c", &cntl); 21612913Sgarrison if (cntl=='\n') {return (0);} 21712913Sgarrison if (cntl==':') fscanf(stream, "%s", oldfile); 21812913Sgarrison strcpy(ref->reffile, oldfile); 219*15062Sgarrison fscanf(stream, "%D/%D", &ref->start, &ref->length); 22012913Sgarrison return(1); 22112913Sgarrison } 222