|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <ctype.h> ! 3: #include <sys/types.h> ! 4: #include <sys/stat.h> ! 5: #include "streams.h" ! 6: #include "bib.h" ! 7: ! 8: #define maxrefs 500 ! 9: #define LONGSTR 1280 ! 10: ! 11: ! 12: char *strncat(), *strncpy(), *strcat(), *strcpy(), *strrchr(); ! 13: ! 14: #define ireturn(s,name) \ ! 15: { \ ! 16: fprintf(stderr,s,name); \ ! 17: nodatabase = 1; \ ! 18: return(NULL); \ ! 19: } ! 20: ! 21: struct reftype{ ! 22: char reffile[maxstr]; ! 23: long int start, length; ! 24: }; ! 25: ! 26: char *malloc(); ! 27: char *stripkeys(); ! 28: int fetchref(); ! 29: ! 30: /* locate(keys, name): ! 31: Returns a string containing all references pointed to by name ! 32: that contain all keys in keys. Common is name of common word file. ! 33: Pointer returned comes from malloc. Use free to return storage. ! 34: NB A zero length string returned if nothing is found. ! 35: A NULL pointer indicates an error accessing the file "name". ! 36: */ ! 37: char *locate(keys,name) ! 38: char *keys, *name; ! 39: { ! 40: static int max_klen = MAXKLEN; /* max key length */ ! 41: static char *common = COMFILE; /* pointer to common file */ ! 42: static char comstr[maxstr]; /* holds name of common file */ ! 43: ! 44: static char oldname[maxstr] = ""; /* oldname is name of stream index */ ! 45: static FILE *index = NULL; ! 46: static long int i_size; /* size of index */ ! 47: static char oldtext[maxstr]; /* oldtext is the path to stream */ ! 48: static FILE *text = NULL; /* text. if it is a relative */ ! 49: FILE *head; ! 50: ! 51: static int pathlen; /* path, it is relative to index */ ! 52: int len; ! 53: char key[maxstr]; /* refs[i] is a line of index for */ ! 54: char line[maxstr]; ! 55: struct reftype refs[maxrefs]; /* all keys up to key */ ! 56: ! 57: int refcnt, copied, comp; /* refcnt = # of refs */ ! 58: struct reftype ref; ! 59: char str[LONGSTR]; ! 60: char istr[LONGSTR]; ! 61: char tstr[maxstr], *tp; ! 62: int more; ! 63: int outofdate; ! 64: ! 65: long int ans; ! 66: int i,j; ! 67: unsigned total; ! 68: char *allrefs, *next; /* all refs (separated by null line)*/ ! 69: char *p; ! 70: ! 71: static int nodatabase = 0; /* cannot open or invert INDEX */ ! 72: ! 73: struct stat ibuf, tbuf; /* for comparing mtimes of index and text */ ! 74: /* open index */ ! 75: if(strcmp(oldname,name)!=0) { ! 76: nodatabase = 0; ! 77: if (index) fclose(index); ! 78: if (text) fclose(text); ! 79: strcpy(oldname,name); ! 80: strcpy(oldtext,""); ! 81: /* determine pathlen */ ! 82: p= strrchr(oldname, '/'); ! 83: if (p!=NULL) pathlen= p-oldname+1; ! 84: else pathlen= 0; ! 85: ! 86: *istr = NULL; ! 87: if(stat(oldname,&ibuf) == -1) { /* create index */ ! 88: strncpy(istr,oldname,strlen(oldname)-2); ! 89: /* assume that bib database is named istr */ ! 90: if(makeindex(istr,istr,max_klen,common)) ! 91: ireturn("locate: cannot invert %s\n",istr); ! 92: } ! 93: else { /* see if index is up to date */ ! 94: *str = NULL; ! 95: strcpy(str,oldname); ! 96: str[strlen(oldname)-1] = NULL; ! 97: strcat(str,"h"); ! 98: if((head = fopen(str,"r")) == NULL) ! 99: ireturn("locate: cannot open %s\n",str); ! 100: if(fscanf(head,"%s %d\n",comstr,&max_klen) != 2) { ! 101: ireturn("locate: %s is in the wrong format; rerun pinvert\n",str); ! 102: } ! 103: else { ! 104: common = comstr; ! 105: } ! 106: *str = NULL; ! 107: outofdate = 0; ! 108: while(fgets(line,maxstr,head)) { ! 109: line[strlen(line)-1] = NULL; ! 110: if(*line != '/') { ! 111: strncat(str, oldname, pathlen); ! 112: } ! 113: strcat(str,line); ! 114: strcat(str," "); ! 115: if(!outofdate) { ! 116: if(*line != '/') { ! 117: *tstr = NULL; ! 118: strncat(tstr, oldname, pathlen); ! 119: strcat(tstr,line); ! 120: tp = tstr; ! 121: } ! 122: else tp = line; ! 123: if(stat(tp,&tbuf) == -1) ! 124: ireturn("locate: cannot stat %s\n",tp); ! 125: if(tbuf.st_mtime > ibuf.st_mtime) ! 126: outofdate++; ! 127: } ! 128: } ! 129: fclose(head); ! 130: if(outofdate) { ! 131: if(*istr == NULL) ! 132: strncpy(istr,oldname,strlen(oldname)-2); ! 133: if(makeindex(str,istr,max_klen,common)) ! 134: ireturn("locate: cannot invert %s\n",str); ! 135: } ! 136: } ! 137: if ((index= fopen(oldname,"r"))==NULL) ! 138: ireturn("locate: cannot open %s\n", oldname); ! 139: fseek(index,0L,2); /* seeks last newline */ ! 140: i_size= ftell(index); ! 141: } ! 142: else if/* database known to be unaccessible */ ! 143: (nodatabase) return(NULL); ! 144: ! 145: /* load references to first key */ ! 146: keys= stripkeys(keys,key, max_klen, common); ! 147: if (*key==NULL) { ! 148: allrefs = malloc(1); ! 149: if (allrefs==NULL) { ! 150: fprintf(stderr, ! 151: "locate: insufficient space for references\n"); ! 152: exit(1); ! 153: } ! 154: *allrefs= NULL; ! 155: return(allrefs); ! 156: } ! 157: len= strlen(key); ! 158: strcat(key," "); ! 159: alpha_seek(index, key, i_size, 0); ! 160: key[len]= NULL; /* strip blank off */ ! 161: ! 162: refcnt= 0; ! 163: fscanf(index,"%s ", str); ! 164: if (strcmp(str,key) == 0) { ! 165: str[0]= NULL; ! 166: while (refcnt < maxrefs && fetchref(index, str, &ref) ) { ! 167: refs[refcnt]= ref; ! 168: refcnt++; ! 169: } ! 170: } ! 171: ! 172: if (refcnt==maxrefs) ! 173: fprintf(stderr, ! 174: "locate: first key (%s) matched too many refs\n", key); ! 175: ! 176: /* intersect the reference sets for remaining keys with first set */ ! 177: while (*keys!=NULL) { ! 178: keys= stripkeys(keys, key, max_klen, common); ! 179: if (*key==NULL) continue; ! 180: ! 181: len= strlen(key); ! 182: strcat(key," "); ! 183: alpha_seek(index, key, i_size, 0); ! 184: key[len]= NULL; ! 185: ! 186: fscanf(index,"%s ", str); ! 187: if (strcmp(str,key) != 0) refcnt= 0; /* no matching refs */ ! 188: ! 189: copied= 0; ! 190: comp= 0; ! 191: more= fetchref(index, str, &ref); ! 192: while (comp < refcnt && more) { /* ans= ref-refs[comp] */ ! 193: ans= strcmp(ref.reffile, refs[comp].reffile); ! 194: if (ans==0) ans= ref.start-refs[comp].start; ! 195: if (ans==0) ans= ref.length-refs[comp].length; ! 196: if (ans<0) more= fetchref(index, str, &ref); ! 197: if (ans==0) { ! 198: refs[copied]= refs[comp]; ! 199: comp++; ! 200: copied++; ! 201: more= fetchref(index, str, &ref); ! 202: } ! 203: if (ans>0) comp++; ! 204: } ! 205: ! 206: refcnt= copied; ! 207: } ! 208: ! 209: total= 0; ! 210: for (i=0; i<refcnt; i++) total += refs[i].length+1; ! 211: ! 212: allrefs= malloc(total+1); ! 213: if (allrefs==NULL) { ! 214: fprintf(stderr, "locate: insufficient space for references\n"); ! 215: exit(1); ! 216: } ! 217: ! 218: /* copy refs into allrefs */ ! 219: next= allrefs; ! 220: for (i=0; i<refcnt; i++) { /* open text */ ! 221: if (strcmp(oldtext,refs[i].reffile) != 0) { ! 222: strcpy(oldtext,refs[i].reffile); ! 223: if (oldtext[0]=='/') { /* absolute path */ ! 224: strcpy(str,oldtext); ! 225: } else { /* relative name */ ! 226: strncpy(str, oldname, pathlen); ! 227: str[pathlen]= NULL; ! 228: strcat(str, oldtext); ! 229: } ! 230: if (text) fclose(text); ! 231: text= fopen(str, "r"); ! 232: if (text==NULL) { ! 233: fprintf(stderr, "locate: cannot open %s\n", str); ! 234: strcpy(oldtext, ""); ! 235: return(NULL); ! 236: } ! 237: } ! 238: fseek(text, refs[i].start, 0); ! 239: for (j=0; j<refs[i].length; j++) *next++ = getc(text); ! 240: *next++ = '\n'; ! 241: } ! 242: *next = NULL; ! 243: return(allrefs); ! 244: } ! 245: ! 246: ! 247: ! 248: /* stripkeys(line,key,max_klen, common): ! 249: assigns to key the first key in line ! 250: and returns a pointer to the position following the key ! 251: */ ! 252: char *stripkeys(line,key,max_klen,common) ! 253: char *line, *key; ! 254: int max_klen; ! 255: char *common; ! 256: { ! 257: char *p; ! 258: ! 259: do { ! 260: while (*line && !isalnum(*line)) line++; ! 261: ! 262: p= key; ! 263: while (isalnum(*line)) ! 264: *p++ = *line++; ! 265: *p= NULL; ! 266: if(*key == NULL) ! 267: break; ! 268: makekey(key, max_klen, common); ! 269: } while (*key == NULL); ! 270: return(line); ! 271: } ! 272: ! 273: /* read a reference pair from stream into *ref. if file not given, ! 274: use oldfile. return 1 if pair found, 0 ow. ! 275: */ ! 276: int fetchref(stream, oldfile, ref) ! 277: FILE *stream; ! 278: char *oldfile; ! 279: struct reftype *ref; ! 280: { ! 281: char cntl; ! 282: ! 283: fscanf(stream, "%c", &cntl); ! 284: if (cntl=='\n') { ! 285: return (0); ! 286: } ! 287: if (cntl==':') fscanf(stream, "%s", oldfile); ! 288: strcpy(ref->reffile, oldfile); ! 289: fscanf(stream, "%ld/%ld", &ref->start, &ref->length); ! 290: return(1); ! 291: } ! 292: ! 293: ! 294: ! 295: char pinvert[] = "pinvert -l%d -c%s -p%s %s"; ! 296: ! 297: makeindex(names,index,k,com) ! 298: char *names,*com,*index; ! 299: int k; ! 300: { ! 301: char pcmd[LONGSTR]; ! 302: ! 303: sprintf(pcmd,pinvert,k,com,index,names); ! 304: return(system(pcmd)); ! 305: } ! 306: ! 307: ! 308:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.