Annotation of 43BSD/contrib/bib/src/locate.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)locate.c   2.5     6/11/85";
                      3: #endif not lint
                      4: #
                      5: 
                      6: # include   "stdio.h"
                      7: # include   "streams.h"
                      8: # include   "ctype.h"
                      9: # define    maxrefs      200
                     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: }

unix.superglobalmegacorp.com

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