|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)locate.c 2.6 3/5/87"; ! 3: #endif not lint ! 4: # ! 5: ! 6: # include "stdio.h" ! 7: # include "streams.h" ! 8: # include "ctype.h" ! 9: # define maxrefs 1000 ! 10: ! 11: struct reftype{ ! 12: char reffile[maxstr]; ! 13: long int start, length; ! 14: }; ! 15: ! 16: char *calloc(); ! 17: char *rindex(); ! 18: char *stripkeys(); ! 19: int fetchref(); ! 20: ! 21: /* locate(keys, name, max_klen, common): ! 22: Returns a string containing all references pointed to by name ! 23: that contain all keys in keys. Common is name of common word file. ! 24: Pointer returned comes from calloc. Use free to return storage. ! 25: NB A zero length string returned if nothing is found. ! 26: A NULL pointer indicates an error accessing the file "name". ! 27: */ ! 28: int fflag; /* set if want the reference string to have the file name*/ ! 29: char *locate(keys,name,max_klen,common) ! 30: char *keys, *name, *common; ! 31: int max_klen; /* max key length */ ! 32: { static char oldname[maxstr] = ""; /* oldname is name of stream index */ ! 33: static FILE *index = NULL; ! 34: static long int i_size; /* size of index */ ! 35: static char oldtext[maxstr]; /* oldtext is the path to stream */ ! 36: static FILE *text = NULL; /* text. if it is a relative */ ! 37: static int pathlen; /* path, it is relative to index */ ! 38: /* directory. */ ! 39: /* oldname[0..pathlen-1] is index */ ! 40: /* directory */ ! 41: int len; ! 42: char key[maxstr]; /* refs[i] is a line of index for */ ! 43: struct reftype refs[maxrefs]; /* all keys up to key */ ! 44: ! 45: int refcnt, copied, comp; /* refcnt = # of refs */ ! 46: /* copied = # of refs copied */ ! 47: /* comp = # of refs compared */ ! 48: struct reftype ref; ! 49: char str[maxstr]; ! 50: int more; ! 51: ! 52: long int ans; ! 53: int i,j; ! 54: unsigned total; ! 55: char *allrefs, *next; /* all refs (separated by null line)*/ ! 56: char *p; ! 57: ! 58: /* open index */ ! 59: if (strcmp(oldname,name)!=0) ! 60: { if (index) fclose(index); ! 61: if (text) fclose(text); ! 62: strcpy(oldname,name); ! 63: strcpy(oldtext,""); ! 64: /* determine pathlen */ ! 65: p= rindex(oldname, '/'); ! 66: if (p!=NULL) pathlen= p-oldname+1; ! 67: else pathlen= 0; ! 68: ! 69: index= fopen(oldname,"r"); ! 70: if (index==NULL) ! 71: { fprintf(stderr, "locate: cannot open %s\n", oldname); ! 72: strcpy(oldname, ""); ! 73: return(NULL); ! 74: } ! 75: else ! 76: { fseek(index,0L,2); /* seeks last newline */ ! 77: i_size= ftell(index); ! 78: } ! 79: ! 80: } ! 81: ! 82: /* load references to first key */ ! 83: keys= stripkeys(keys,key, max_klen, common); ! 84: if (*key==NULL) ! 85: { fprintf(stderr,"locate: no keys for citation\n"); ! 86: allrefs = (char *) calloc(1, sizeof (char)); ! 87: if (allrefs==NULL) ! 88: { fprintf(stderr, ! 89: "locate: insufficient space for references\n"); ! 90: exit(1); ! 91: } ! 92: *allrefs= NULL; ! 93: return(allrefs); ! 94: } ! 95: len= strlen(key); ! 96: strcat(key," "); ! 97: alpha_seek(index, key, i_size, 0); ! 98: key[len]= NULL; /* strip blank off */ ! 99: ! 100: refcnt= 0; ! 101: fscanf(index,"%s ", str); ! 102: if (strcmp(str,key) == 0) ! 103: { str[0]= NULL; ! 104: while (refcnt < maxrefs && fetchref(index, str, &ref) ) ! 105: { refs[refcnt]= ref; ! 106: refcnt++; ! 107: } ! 108: } ! 109: ! 110: if (refcnt==maxrefs) ! 111: fprintf(stderr, ! 112: "locate: first key (%s) matched too many refs\n", key); ! 113: ! 114: /* intersect the reference sets for remaining keys with first set */ ! 115: while (*keys!=NULL) ! 116: { keys= stripkeys(keys, key, max_klen, common); ! 117: if (*key==NULL) continue; ! 118: ! 119: len= strlen(key); ! 120: strcat(key," "); ! 121: alpha_seek(index, key, i_size, 0); ! 122: key[len]= NULL; ! 123: ! 124: fscanf(index,"%s ", str); ! 125: if (strcmp(str,key) != 0) refcnt= 0; /* no matching refs */ ! 126: ! 127: copied= 0; comp= 0; more= fetchref(index, str, &ref); ! 128: while (comp < refcnt && more) ! 129: { /* ans= ref-refs[comp] */ ! 130: ans= strcmp(ref.reffile, refs[comp].reffile); ! 131: if (ans==0) ans= ref.start-refs[comp].start; ! 132: if (ans==0) ans= ref.length-refs[comp].length; ! 133: if (ans<0) more= fetchref(index, str, &ref); ! 134: if (ans==0) { refs[copied]= refs[comp]; comp++; copied++; ! 135: more= fetchref(index, str, &ref);} ! 136: if (ans>0) comp++; ! 137: } ! 138: ! 139: refcnt= copied; ! 140: } ! 141: ! 142: total= 0; ! 143: for (i=0; i<refcnt; i++) { ! 144: total += refs[i].length+1; ! 145: if (fflag){ ! 146: total += strlen(refs[i].reffile) + 1; ! 147: } ! 148: } ! 149: ! 150: allrefs= (char *) calloc(total+1, sizeof (char)); ! 151: if (allrefs==NULL) ! 152: { fprintf(stderr, "locate: insufficient space for references\n"); ! 153: exit(1); ! 154: } ! 155: ! 156: /* copy refs into allrefs */ ! 157: next= allrefs; ! 158: for (i=0; i<refcnt; i++) ! 159: { /* open text */ ! 160: if (strcmp(oldtext,refs[i].reffile) != 0) ! 161: { strcpy(oldtext,refs[i].reffile); ! 162: if (oldtext[0]=='/') ! 163: { /* absolute path */ ! 164: strcpy(str,oldtext); ! 165: } else ! 166: { /* relative name */ ! 167: strncpy(str, oldname, pathlen); str[pathlen]= NULL; ! 168: strcat(str, oldtext); ! 169: } ! 170: if (text) fclose(text); ! 171: text= fopen(str, "r"); ! 172: if (text==NULL) ! 173: { fprintf(stderr, "locate: cannot open %s\n", str); ! 174: strcpy(oldtext, ""); ! 175: return(NULL); ! 176: } ! 177: } ! 178: fseek(text, refs[i].start, 0); ! 179: if (fflag){ ! 180: strcat(next, refs[i].reffile); ! 181: next += strlen(next); ! 182: *next++ = '\n'; ! 183: *next = 0; ! 184: } ! 185: for (j=0; j<refs[i].length; j++) *next++ = getc(text); ! 186: *next++ = '\n'; ! 187: } ! 188: *next = NULL; ! 189: return(allrefs); ! 190: } ! 191: ! 192: ! 193: ! 194: /* stripkeys(line,key,max_klen, common): ! 195: assigns to key the first key in line ! 196: and returns a pointer to the position following the key ! 197: */ ! 198: char *stripkeys(line,key,max_klen,common) ! 199: char *line, *key; ! 200: int max_klen; ! 201: char *common; ! 202: { char *p; ! 203: ! 204: do ! 205: { while (isspace(*line)) line++; ! 206: ! 207: p= key; ! 208: while (*line!=NULL && !isspace(*line)) ! 209: { *p++ = *line++; ! 210: } ! 211: *p= NULL; ! 212: ! 213: makekey(key, max_klen, common); ! 214: } while (*key==NULL && *line!=NULL); ! 215: return(line); ! 216: } ! 217: ! 218: /* read a reference pair from stream into *ref. if file not given, ! 219: use oldfile. return 1 if pair found, 0 ow. ! 220: */ ! 221: int fetchref(stream, oldfile, ref) ! 222: FILE *stream; ! 223: char *oldfile; ! 224: struct reftype *ref; ! 225: { char cntl; ! 226: ! 227: fscanf(stream, "%c", &cntl); ! 228: if (cntl=='\n') {return (0);} ! 229: if (cntl==':') fscanf(stream, "%s", oldfile); ! 230: strcpy(ref->reffile, oldfile); ! 231: fscanf(stream, "%D/%D", &ref->start, &ref->length); ! 232: return(1); ! 233: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.