Annotation of researchv10no/cmd/prefer/pref/locate.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.