home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume34 / unpackmaps / part02 / getpath.c < prev    next >
C/C++ Source or Header  |  1992-11-29  |  2KB  |  110 lines

  1. /* taken from: *sccsid="@(#)getpath.c    2.5 (smail) 9/15/87";
  2.    Permission pending
  3.  */
  4.  
  5. #ifndef lint
  6. static char SCCSid[] = "@(#)getpath.c 1.1 92/06/10 01:16:17";
  7. #endif
  8.  
  9. #include "unpack.h"
  10.  
  11. #define DEBUG    if (debug) (void) printf
  12. char *gpathdata;
  13. #define    lower(x)    (isupper(x)? x-'A'+'a' : x)
  14.  
  15. /*
  16. **
  17. ** getpath(): look up key in ascii sorted path database.
  18. **
  19. */
  20.  
  21. /*    Every time reset to zero, path file is reopened */
  22. long pathlength = 0;
  23.  
  24. getpath( key, path, cost)
  25. char *key;        /* what we are looking for */
  26. char *path;        /* where the path results go */
  27. int *cost;        /* where the cost results go */
  28. {
  29.     long pos, middle, hi, lo;
  30.     register char *s;
  31.     int c;
  32.     int flag;
  33.     static FILE *file = (FILE *) NULL;
  34.  
  35.     DEBUG("getpath: looking for '%s'\n", key);
  36.  
  37.     if(pathlength == 0) {    /* open file on first use */
  38.         if (file)
  39.             (void) fclose(file);
  40.         if((file = fopen(gpathdata, "r")) == NULL) {
  41.             (void) printf("Can't access %s.\n", gpathdata);
  42.             pathlength = -1;
  43.         } else {
  44.             (void) fseek(file, 0L, 2);    /* find length */
  45.             pathlength = ftell(file);
  46.         }
  47.     }
  48.     if( pathlength == -1 )
  49.         return( 1 );
  50.  
  51.     lo = 0;
  52.     hi = pathlength;
  53.     (void) strcpy( path, key );
  54.     (void) strcat( path, "\t" );
  55. /*
  56. ** "Binary search routines are never written right the first time around."
  57. ** - Robert G. Sheldon.
  58. */
  59.     for( ;; ) {
  60.         pos = middle = ( hi+lo+1 )/2;
  61.         (void) fseek(file, pos, 0);    /* find midpoint */
  62.         if(pos != 0)
  63.             while(((c = getc(file)) != EOF) && (c != '\n'))
  64.                 continue;    /* go to beginning of next line */
  65.         if(c == EOF) {
  66.             return(1);
  67.         }
  68.         for( flag = 0, s = path; flag == 0; s++ ) { /* match??? */
  69.             if( *s == '\0' ) {
  70.                 goto solved;
  71.             }
  72.             if((c = getc(file)) == EOF) {
  73.                 return(1);
  74.             }
  75.             flag = lower(c) - lower(*s);
  76.         } 
  77.         if(lo >= middle) {        /* failure? */
  78.             return(1);
  79.         }
  80.         if((c != EOF) && (flag < 0)) {    /* close window */
  81.             lo = middle;
  82.         } else {
  83.             hi = middle - 1;
  84.         }
  85.     }
  86. /* 
  87. ** Now just copy the result.
  88. */
  89. solved:
  90.     while(((c  = getc(file)) != EOF) && (c != '\t') && (c != '\n')) {
  91.         *path++ = c;
  92.     }
  93.     *path = '\0';
  94. /*
  95. ** See if the next field on the line is numeric.
  96. ** If so, use it as the cost for the route.
  97. */
  98.     if(c == '\t') {
  99.         int tcost = -1;
  100.         while(((c = getc(file)) != EOF) && isdigit(c)) {
  101.             if(tcost < 0) tcost = 0;
  102.             tcost *= 10;
  103.             tcost += c - '0';
  104.         }
  105.         if(tcost >= 0) *cost = tcost;
  106.     }
  107.     return (0);
  108. }
  109.  
  110.