Annotation of researchv10no/cmd/prefer/pref/locate.c, revision 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.