112913Sgarrison #ifndef lint 2*13111Srrh static char sccsid[] = "@(#)locate.c 1.2 06/14/83"; 3*13111Srrh #endif not lint 412913Sgarrison 512913Sgarrison # include "stdio.h" 612913Sgarrison # include "streams.h" 712913Sgarrison # include "ctype.h" 812913Sgarrison # define maxrefs 200 912913Sgarrison 1012913Sgarrison struct reftype{ 1112913Sgarrison char reffile[64]; /* rrh: still may be too short */ 1212913Sgarrison long int start, length; 1312913Sgarrison }; 1412913Sgarrison 1512913Sgarrison char *malloc(); 1612913Sgarrison char *rindex(); 1712913Sgarrison char *stripkeys(); 1812913Sgarrison int fetchref(); 1912913Sgarrison int fileflag; 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 char workbuf[10240]; /* work buffer */ 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"); 8612913Sgarrison allrefs = malloc(1); 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 14212913Sgarrison /* copy refs into the work buffer */ 14312913Sgarrison next= workbuf; 14412913Sgarrison for (i=0; i<refcnt; i++) 14512913Sgarrison { /* open text */ 14612913Sgarrison if (strcmp(oldtext,refs[i].reffile) != 0) 14712913Sgarrison { strcpy(oldtext,refs[i].reffile); 14812913Sgarrison if (oldtext[0]=='/') 14912913Sgarrison { /* absolute path */ 15012913Sgarrison strcpy(str,oldtext); 15112913Sgarrison } else 15212913Sgarrison { /* relative name */ 15312913Sgarrison strncpy(str, oldname, pathlen); str[pathlen]= NULL; 15412913Sgarrison strcat(str, oldtext); 15512913Sgarrison } 15612913Sgarrison if (text) fclose(text); 15712913Sgarrison text= fopen(str, "r"); 15812913Sgarrison if (text==NULL) 15912913Sgarrison { fprintf(stderr, "locate: cannot open %s\n", str); 16012913Sgarrison strcpy(oldtext, ""); 16112913Sgarrison return(NULL); 16212913Sgarrison } 16312913Sgarrison } 16412913Sgarrison fseek(text, refs[i].start, 0); 16512913Sgarrison { 16612913Sgarrison register char *from; 16712913Sgarrison if (fileflag){ 16812913Sgarrison from = oldtext; 16912913Sgarrison while(*next++ = *from++) /*VOID*/ ; 17012913Sgarrison next[-1] = '\n'; 17112913Sgarrison } 17212913Sgarrison } 17312913Sgarrison for (j=0; j<refs[i].length; j++) *next++ = getc(text); 17412913Sgarrison *next++ = '\n'; 17512913Sgarrison } 17612913Sgarrison *next = NULL; 17712913Sgarrison allrefs = malloc(strlen(workbuf) + 1); 17812913Sgarrison if (allrefs == NULL) { 17912913Sgarrison fprintf(stderr, "No space left for allrefs\n"); 18012913Sgarrison exit(1); 18112913Sgarrison } 18212913Sgarrison strcpy(allrefs, workbuf); 18312913Sgarrison return(allrefs); 18412913Sgarrison } 18512913Sgarrison 18612913Sgarrison 18712913Sgarrison 18812913Sgarrison /* stripkeys(line,key,max_klen, common): 18912913Sgarrison assigns to key the first key in line 19012913Sgarrison and returns a pointer to the position following the key 19112913Sgarrison */ 19212913Sgarrison char *stripkeys(line,key,max_klen,common) 19312913Sgarrison char *line, *key; 19412913Sgarrison int max_klen; 19512913Sgarrison char *common; 19612913Sgarrison { char *p; 19712913Sgarrison 19812913Sgarrison do 19912913Sgarrison { while (isspace(*line)) line++; 20012913Sgarrison 20112913Sgarrison p= key; 20212913Sgarrison while (*line!=NULL && !isspace(*line)) 20312913Sgarrison { *p++ = *line++; 20412913Sgarrison } 20512913Sgarrison *p= NULL; 20612913Sgarrison 20712913Sgarrison makekey(key, max_klen, common); 20812913Sgarrison } while (*key==NULL && *line!=NULL); 20912913Sgarrison return(line); 21012913Sgarrison } 21112913Sgarrison 21212913Sgarrison /* read a reference pair from stream into *ref. if file not given, 21312913Sgarrison use oldfile. return 1 if pair found, 0 ow. 21412913Sgarrison */ 21512913Sgarrison int fetchref(stream, oldfile, ref) 21612913Sgarrison FILE *stream; 21712913Sgarrison char *oldfile; 21812913Sgarrison struct reftype *ref; 21912913Sgarrison { char cntl; 22012913Sgarrison 22112913Sgarrison fscanf(stream, "%c", &cntl); 22212913Sgarrison if (cntl=='\n') {return (0);} 22312913Sgarrison if (cntl==':') fscanf(stream, "%s", oldfile); 22412913Sgarrison strcpy(ref->reffile, oldfile); 225*13111Srrh fscanf(stream, "%ld/%ld", &ref->start, &ref->length); 22612913Sgarrison return(1); 22712913Sgarrison } 228