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: }

Defined functions

fetchref defined in line 221; used 5 times
locate defined in line 29; used 4 times
stripkeys defined in line 198; used 3 times

Defined variables

fflag defined in line 28; used 2 times
sccsid defined in line 2; never used

Defined struct's

reftype defined in line 11; used 6 times

Defined macros

maxrefs defined in line 9; used 3 times
Last modified: 1985-06-12
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1290
Valid CSS Valid XHTML 1.0 Strict