home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 445.lha / RoadRoute_v1.6 / RoadScan.c < prev    next >
C/C++ Source or Header  |  1990-12-06  |  29KB  |  848 lines

  1. /* after years of fiddling..
  2.   'v1.1  August 90
  3. 'Jim Butterfield  */
  4.  
  5.    /* compile with lc -Lcd -v <filename> */
  6. #include <proto/exec.h>
  7. #include <proto/dos.h>
  8. #include <stdio.h>
  9. #define BUFFERLINE 50
  10. #define INFOSIZE sizeof(struct FileInfoBlock)
  11. #define TRAILLEN 60
  12.  
  13. /* File Support structures */
  14. struct CityData {
  15.                 char *CityName;              /* full name  w/state */
  16.                 char *StateName;             /* state/province only */
  17.                 struct CityData *CityLink;   /* init letter chain */
  18.                 struct CityData *StateLink;  /* init letter chain */
  19.                 struct RouteData *RoadList;  /* roads to/from city */
  20.                 struct CityData *WorkList;   /* temp job queue */
  21.                 struct CityData *NextCity[2];  /* result links */
  22.       /* Mindist[0] doubles as CityDupe flag during file input */
  23.                 unsigned short MinDist[2];   /* closest so far */
  24.                 unsigned char StateDupe;     /* one name per state */
  25.                 unsigned char Colum;         /* goes with RoadList */
  26.                 };
  27. struct RouteData {
  28.                  struct CityData *CityNum[2];  /* cities each end */
  29.                  unsigned short Dist[2];       /* distance, time */
  30.                  char *Hiway;                  /* name of Highway */
  31.                  struct RouteData *RLink[2];   /* link for each city */
  32.                  unsigned char Colm[2];        /* goes with RLink */
  33.                  };
  34. struct RouteData *Route0, *Route9;
  35. struct CityData *City0, *City9;
  36. struct CityData *CharLink[0x20];
  37. struct CityData *ChStLink[0x20];
  38. struct CityData *CityLink[0x100];     /* The only 1.1 change! */
  39. struct CityData *CountLink[5];
  40. static char InBuff[BUFFERLINE];
  41. static struct CityData *Trail[TRAILLEN][2];
  42. unsigned short TrailPoint[2];
  43. void TimeShow(unsigned short,char *);
  44. int CityMatch(struct CityData *,char *);
  45. unsigned short ParseCities(char *,long);
  46. unsigned short ParseRoutes(char *,long);
  47. struct CityData * AskCity();
  48. unsigned short Navigate(struct CityData *,struct CityData *);
  49. void main()
  50.   {
  51.   long fh, lok;
  52.   unsigned short NextCol, NewCol;
  53.   unsigned short AllocCount, errnum;
  54.   struct FileInfoBlock *fibb;
  55.   long CitySize, RouteSize;
  56.   char *CityBlox, *RouteBlox, *DataScan, *Active;
  57.   char *CityScan, *CityPoint, *RoutePoint;
  58.   struct CityData *From, *Dest;
  59.   struct RouteData *NextRoute, *NewRoute, *ScanRoute;
  60.   unsigned short Cities, Roads;
  61.   unsigned short CityPSize, RoutePSize;
  62.   unsigned char Ct0;             /* general character work value */
  63.   unsigned short Count, Links;
  64.   static char ActCity[]="Cities";
  65.   static char ActRoad[]="Roads";
  66.   for (Ct0=0; Ct0 < 0x20; Ct0++) CharLink[Ct0]= 0;
  67.   for (Ct0=0; Ct0 < 0x20; Ct0++) ChStLink[Ct0]= 0;
  68.   for (Ct0=0; Ct0 < 5; Ct0++) CountLink[Ct0]= 0;
  69.   AllocCount=0;
  70.   errnum=2;                   /* no memory */
  71.   if ( (long) (fibb = (struct FileInfoBlock *) AllocMem(INFOSIZE,0L))
  72.                                                                 != 0L)
  73.     {
  74.     AllocCount=1;
  75.     errnum=3;                   /* file problems */
  76.     fprintf(stderr,"RoadScan V1.1  ..   Jim Butterfield\n");
  77.     fprintf(stderr,"   Release version:  1990 08 13\n");
  78.     Cities=0;
  79.     Active=ActCity;
  80.     if ( (lok = Lock("Cities",ACCESS_READ)) != 0L)
  81.       {
  82.       if ( (fh=Examine(lok,fibb)) !=0L)
  83.         {
  84.         CitySize=fibb->fib_Size;
  85.         if ( (long) (CityBlox = AllocMem(CitySize,0L)) != 0L)
  86.       {
  87.           AllocCount=2;
  88.           if ( (fh = Open("Cities",MODE_OLDFILE)) != 0L)
  89.             {
  90.             errnum=0;
  91.             Read(fh,CityBlox,CitySize);
  92.             Close(fh);
  93.         }                      /* City file opened   */
  94.           }                        /* data alloc OK */
  95.     }                          /* examine OK    */
  96.         UnLock(lok);
  97.       }                            /* lock OK          */
  98.     }                              /* examine alloc OK */
  99.   if (errnum == 0)
  100.     {
  101.     for (DataScan=CityBlox;DataScan < CityBlox+CitySize;DataScan++)
  102.       if (*DataScan == 0x0A) Cities++;
  103.     CityPSize=Cities*sizeof(struct CityData);
  104.     if ( (long) (CityPoint = AllocMem(CityPSize,0L)) != 0L)
  105.       AllocCount=3;
  106.     else
  107.       errnum=2;
  108.     }
  109.   if (errnum ==0 )
  110.     {
  111.     errnum=3;                   /* file problems */
  112.     Active=ActRoad;
  113.     Roads=0;
  114.     if ( (lok = Lock("Roads",ACCESS_READ)) != 0L)
  115.       {
  116.       if ( (fh=Examine(lok,fibb/* after years of fiddling..
  117.   'v1.1  August 90
  118. 'Jim Butterfield  */
  119.  
  120.    /* compile with lc -Lcd -v <filename> */
  121. #include <proto/exec.h>
  122. #include <proto/dos.h>
  123. #include <stdio.h>
  124. #define BUFFERLINE 50
  125. #define INFOSIZE sizeof(struct FileInfoBlock)
  126. #define TRAILLEN 60
  127.  
  128. /* File Support structures */
  129. struct CityData {
  130.                 char *CityName;              /* full name  w/state */
  131.                 char *StateName;             /* state/province only */
  132.                 struct CityData *CityLink;   /* init letter chain */
  133.                 struct CityData *StateLink;  /* init letter chain */
  134.                 struct RouteData *RoadList;  /* roads to/from city */
  135.                 struct CityData *WorkList;   /* temp job queue */
  136.                 struct CityData *NextCity[2];  /* result links */
  137.       /* Mindist[0] doubles as CityDupe flag during file input */
  138.                 unsigned short MinDist[2];   /* closest so far */
  139.                 unsigned char StateDupe;     /* one name per state */
  140.                 unsigned char Colum;         /* goes with RoadList */
  141.                 };
  142. struct RouteData {
  143.                  struct CityData *CityNum[2];  /* cities each end */
  144.                  unsigned short Dist[2];       /* distance, time */
  145.                  char *Hiway;                  /* name of Highway */
  146.                  struct RouteData *RLink[2];   /* link for each city */
  147.                  unsigned char Colm[2];        /* goes with RLink */
  148.                  };
  149. struct RouteData *Route0, *Route9;
  150. struct CityData *City0, *City9;
  151. struct CityData *CharLink[0x20];
  152. struct CityData *ChStLink[0x20];
  153. struct CityData *CityLink[0x100];     /* The only 1.1 change! */
  154. struct CityData *CountLink[5];
  155. static char InBuff[BUFFERLINE];
  156. static struct CityData *Trail[TRAILLEN][2];
  157. unsigned short TrailPoint[2];
  158. void TimeShow(unsigned short,char *);
  159. int CityMatch(struct CityData *,char *);
  160. unsigned short ParseCities(char *,long);
  161. unsigned short ParseRoutes(char *,long);
  162. struct CityData * AskCity();
  163. unsigned short Navigate(struct CityData *,struct CityData *);
  164. void main()
  165.   {
  166.   long fh, lok;
  167.   unsigned short NextCol, NewCol;
  168.   unsigned short AllocCount, errnum;
  169.   struct FileInfoBlock *fibb;
  170.   long CitySize, RouteSize;
  171.   char *CityBlox, *RouteBlox, *DataScan, *Active;
  172.   char *CityScan, *CityPoint, *RoutePoint;
  173.   struct CityData *From, *Dest;
  174.   struct RouteData *NextRoute, *NewRoute, *ScanRoute;
  175.   unsigned short Cities, Roads;
  176.   unsigned short CityPSize, RoutePSize;
  177.   unsigned char Ct0;             /* general character work value */
  178.   unsigned short Count, Links;
  179.   static char ActCity[]="Cities";
  180.   static char ActRoad[]="Roads";
  181.   for (Ct0=0; Ct0 < 0x20; Ct0++) CharLink[Ct0]= 0;
  182.   for (Ct0=0; Ct0 < 0x20; Ct0++) ChStLink[Ct0]= 0;
  183.   for (Ct0=0; Ct0 < 5; Ct0++) CountLink[Ct0]= 0;
  184.   AllocCount=0;
  185.   errnum=2;                   /* no memory */
  186.   if ( (long) (fibb = (struct FileInfoBlock *) AllocMem(INFOSIZE,0L))
  187.                                                                 != 0L)
  188.     {
  189.     AllocCount=1;
  190.     errnum=3;                   /* file problems */
  191.     fprintf(stderr,"RoadScan V1.1  ..   Jim Butterfield\n");
  192.     fprintf(stderr,"   Release version:  1990 08 13\n");
  193.     Cities=0;
  194.     Active=ActCity;
  195.     if ( (lok = Lock("Cities",ACCESS_READ)) != 0L)
  196.       {
  197.       if ( (fh=Examine(lok,fibb)) !=0L)
  198.         {
  199.         CitySize=fibb->fib_Size;
  200.         if ( (long) (CityBlox = AllocMem(CitySize,0L)) != 0L)
  201.       {
  202.           AllocCount=2;
  203.           if ( (fh = Open("Cities",MODE_OLDFILE)) != 0L)
  204.             {
  205.             errnum=0;
  206.             Read(fh,CityBlox,CitySize);
  207.             Close(fh);
  208.         }                      /* City file opened   */
  209.           }                        /* data alloc OK */
  210.     }                          /* examine OK    */
  211.         UnLock(lok);
  212.       }                            /* lock OK          */
  213.     }                              /* examine alloc OK */
  214.   if (errnum == 0)
  215.     {
  216.     for (DataScan=CityBlox;DataScan < CityBlox+CitySize;DataScan++)
  217.       if (*DataScan == 0x0A) Cities++;
  218.     CityPSize=Cities*sizeof(struct CityData);
  219.     if ( (long) (CityPoint = AllocMem(CityPSize,0L)) != 0L)
  220.       AllocCount=3;
  221.     else
  222.       errnum=2;
  223.     }
  224.   if (errnum ==0 )
  225.     {
  226.     errnum=3;                   /* file problems */
  227.     Active=ActRoad;
  228.     Roads=0;
  229.     if ( (lok = Lock("Roads",ACCESS_READ)) != 0L)
  230.       {
  231.       if ( (fh=Examine(lok,fibb)) !=0L)
  232.         {
  233.         RouteSize=fibb->fib_Size;
  234.         if ( (long) (RouteBlox = AllocMem(RouteSize,0L)) != 0L)
  235.           {
  236.           AllocCount=4;
  237.           if ( (fh = Open("Roads",MODE_OLDFILE)) != 0L)
  238.             {
  239.             errnum=0;
  240.             Read(fh,RouteBlox,RouteSize);
  241.             Close(fh);
  242.             }                      /* file opened   */
  243.           }                        /* data alloc OK */
  244.         }                          /* examine OK    */
  245.       UnLock(/* after years of fiddling..
  246.   'v1.1  August 90
  247. 'Jim Butterfield  */
  248.  
  249.    /* compile with lc -Lcd -v <filename> */
  250. #include <proto/exec.h>
  251. #include <proto/dos.h>
  252. #include <stdio.h>
  253. #define BUFFERLINE 50
  254. #define INFOSIZE sizeof(struct FileInfoBlock)
  255. #define TRAILLEN 60
  256.  
  257. /* File Support structures */
  258. struct CityData {
  259.                 char *CityName;              /* full name  w/state */
  260.                 char *StateName;             /* state/province only */
  261.                 struct CityData *CityLink;   /* init letter chain */
  262.                 struct CityData *StateLink;  /* init letter chain */
  263.                 struct RouteData *RoadList;  /* roads to/from city */
  264.                 struct CityData *WorkList;   /* temp job queue */
  265.                 struct CityData *NextCity[2];  /* result links */
  266.       /* Mindist[0] doubles as CityDupe flag during file input */
  267.                 unsigned short MinDist[2];   /* closest so far */
  268.                 unsigned char StateDupe;     /* one name per state */
  269.                 unsigned char Colum;         /* goes with RoadList */
  270.                 };
  271. struct RouteData {
  272.                  struct CityData *CityNum[2];  /* cities each end */
  273.                  unsigned short Dist[2];       /* distance, time */
  274.                  char *Hiway;                  /* name of Highway */
  275.                  struct RouteData *RLink[2];   /* link for each city */
  276.                  unsigned char Colm[2];        /* goes with RLink */
  277.                  };
  278. struct RouteData *Route0, *Route9;
  279. struct CityData *City0, *City9;
  280. struct CityData *CharLink[0x20];
  281. struct CityData *ChStLink[0x20];
  282. struct CityData *CityLink[0x100];     /* The only 1.1 change! */
  283. struct CityData *CountLink[5];
  284. static char InBuff[BUFFERLINE];
  285. static struct CityData *Trail[TRAILLEN][2];
  286. unsigned short TrailPoint[2];
  287. void TimeShow(unsigned short,char *);
  288. int CityMatch(struct CityData *,char *);
  289. unsigned short ParseCities(char *,long);
  290. unsigned short ParseRoutes(char *,long);
  291. struct CityData * AskCity();
  292. unsigned short Navigate(struct CityData *,struct CityData *);
  293. void main()
  294.   {
  295.   long fh, lok;
  296.   unsigned short NextCol, NewCol;
  297.   unsigned short AllocCount, errnum;
  298.   struct FileInfoBlock *fibb;
  299.   long CitySize, RouteSize;
  300.   char *CityBlox, *RouteBlox, *DataScan, *Active;
  301.   char *CityScan, *CityPoint, *RoutePoint;
  302.   struct CityData *From, *Dest;
  303.   struct RouteData *NextRoute, *NewRoute, *ScanRoute;
  304.   unsigned short Cities, Roads;
  305.   unsigned short CityPSize, RoutePSize;
  306.   unsigned char Ct0;             /* general character work value */
  307.   unsigned short Count, Links;
  308.   static char ActCity[]="Cities";
  309.   static char ActRoad[]="Roads";
  310.   for (Ct0=0; Ct0 < 0x20; Ct0++) CharLink[Ct0]= 0;
  311.   for (Ct0=0; Ct0 < 0x20; Ct0++) ChStLink[Ct0]= 0;
  312.   for (Ct0=0; Ct0 < 5; Ct0++) CountLink[Ct0]= 0;
  313.   AllocCount=0;
  314.   errnum=2;                   /* no memory */
  315.   if ( (long) (fibb = (struct FileInfoBlock *) AllocMem(INFOSIZE,0L))
  316.                                                                 != 0L)
  317.     {
  318.     AllocCount=1;
  319.     errnum=3;                   /* file problems */
  320.     fprintf(stderr,"RoadScan V1.1  ..   Jim Butterfield\n");
  321.     fprintf(stderr,"   Release version:  1990 08 13\n");
  322.     Cities=0;
  323.     Active=ActCity;
  324.     if ( (lok = Lock("Cities",ACCESS_READ)) != 0L)
  325.       {
  326.       if ( (fh=Examine(lok,fibb)) !=0L)
  327.         {
  328.         CitySize=fibb->fib_Size;
  329.         if ( (long) (CityBlox = AllocMem(CitySize,0L)) != 0L)
  330.       {
  331.           AllocCount=2;
  332.           if ( (fh = Open("Cities",MODE_OLDFILE)) != 0L)
  333.             {
  334.             errnum=0;
  335.             Read(fh,CityBlox,CitySize);
  336.             Close(fh);
  337.         }                      /* City file opened   */
  338.           }                        /* data alloc OK */
  339.     }                          /* examine OK    */
  340.         UnLock(lok);
  341.       }                            /* lock OK          */
  342.     }                              /* examine alloc OK */
  343.   if (errnum == 0)
  344.     {
  345.     for (DataScan=CityBlox;DataScan < CityBlox+CitySize;DataScan++)
  346.       if (*DataScan == 0x0A) Cities++;
  347.     CityPSize=Cities*sizeof(struct CityData);
  348.     if ( (long) (CityPoint = AllocMem(CityPSize,0L)) != 0L)
  349.       AllocCount=3;
  350.     else
  351.       errnum=2;
  352.     }
  353.   if (errnum ==0 )
  354.     {
  355.     errnum=3;                   /* file problems */
  356.     Active=ActRoad;
  357.     Roads=0;
  358.     if ( (lok = Lock("Roads",ACCESS_READ)) != 0L)
  359.       {
  360.       if ( (fh=Examine(lok,fibb)) !=0L)
  361.         {
  362.         RouteSize=fibb->fib_Size;
  363.         if ( (long) (RouteBlox = AllocMem(RouteSize,0L)) != 0L)
  364.           {
  365.           AllocCount=4;
  366.           if ( (fh = Open("Roads",MODE_OLDFILE)) != 0L)
  367.             {
  368.             errnum=0;
  369.             Read(fh,RouteBlox,RouteSize);
  370.             Close(fh);
  371.             }                      /* file opened   */
  372.           }                        /* data alloc OK */
  373.         }                          /* examine OK    */
  374.       UnLock(lok);
  375.       }                            /* lock OK          */
  376.     }
  377.   if (errnum == 0)
  378.     {
  379.     for (DataScan=RouteBlox;DataScan < RouteBlox+RouteSize;DataScan++)
  380.       if (*DataScan == 0x0A) Roads++;
  381.     RoutePSize=Roads*sizeof(struct RouteData);
  382.     if ( (long) (RoutePoint = AllocMem(RoutePSize,0L)) != 0L)
  383.       AllocCount=5;
  384.     else
  385.       errnum=2;
  386.     }
  387.   if (errnum == 0)
  388.     {
  389.     Active=ActCity;
  390.     fprintf(stderr,">> %d Cities\n",Cities);
  391.     City0 = (struct CityData *) CityPoint;
  392.     errnum=ParseCities(CityBlox,CitySize);
  393.     }
  394.   if (errnum == 0)
  395.     {
  396.     Active=ActRoad;
  397.     fprintf(stderr,">> %d Roads\n",Roads);
  398.     Route0 = (struct RouteData *) RoutePoint;
  399.     errnum=ParseRoutes(RouteBlox,RouteSize);
  400.     }
  401.   switch (errnum)
  402.     {
  403.     case 0:                /* no errors, do main job */
  404.       printf("Scanning Cities...\n\n");
  405.       From=City0;
  406.       while (From<City9)
  407.        {
  408.        CityScan=From->CityName;
  409.        while (*(++CityScan) != ',');
  410.        *CityScan=0;
  411.        Count=0;
  412.        NextRoute=From->RoadList;
  413.        NextCol=From->Colum;
  414.        while (NextRoute != 0)
  415.      {
  416.          Dest=NextRoute->CityNum[1-NextCol];
  417.          for (Links=0; Links<Count; Links++)
  418.            if (CityLink[Links]==Dest && From>Dest )
  419.              printf("DUPE: %s,%s TO %s\n",
  420.            Dest->CityName,Dest->StateName,From->CityName);
  421.          CityLink[Count]=Dest;
  422.      Count++;
  423.      NewRoute=NextRoute->RLink[NextCol];
  424.      NewCol=NextRoute->Colm[NextCol];
  425.      NextRoute=NewRoute;
  426.      NextCol=NewCol;
  427.      }
  428.        if ( Count<5 )
  429.      {
  430.      From->WorkList=CountLink[Count];
  431.      CountLink[Count]=From;
  432.      }
  433.        From++;
  434.        }
  435.       From = CountLink[0];
  436.       if ( From !=0 )
  437.        {
  438.        printf("Following Cities have NO Roads !?!...\n");
  439.        printf(">>> connect or eliminate them!\n");
  440.        while (From != 0)
  441.        {
  442.        printf(" %s\n",From->CityName);
  443.        From = From->WorkList;
  444.        }
  445.        }
  446.       for (Count=1; Count<=3; Count++)
  447.         {
  448.         From = CountLink[Count];
  449.         if ( From!=0 )
  450.          {
  451.          printf("Following Cities have %d Roads...\n",Count);
  452.          printf(">>> you could save space if they were not needed!\n");
  453.          while (From != 0)
  454.            {
  455.            printf(" %s,%s ",From->CityName,From->StateName);
  456.            Ct0='[';
  457.            NextRoute=From->RoadList;
  458.            NextCol=From->Colum;
  459.            while (NextRoute != 0)
  460.              {
  461.              Dest=NextRoute->CityNum[1-NextCol];
  462.          printf("%c%s",Ct0,Dest->CityName);
  463.              NewRoute=NextRoute->RLink[NextCol];
  464.              NewCol=NextRoute->Colm[NextCol];
  465.              NextRoute=NewRoute;
  466.              NextCol=NewCol;
  467.          Ct0='-';
  468.          } /* wend, connecting-city list loop */
  469.  
  470.        printf("]\n");
  471.        From = From->WorkList;
  472.        }  /* wend, next city for this count-list */
  473.          }  /* endif count-list not empty */
  474.         }   /* next count-list  */
  475.       Ct0=0;
  476.       for (ScanRoute=Route0; ScanRoute<Route9; ScanRoute++)
  477.         {
  478.         TrailPoint[0]=0;
  479.         TrailPoint[1]=0;
  480.         From=ScanRoute->CityNum[0];
  481.         Dest=ScanRoute->CityNum[1];
  482.     if ( Navigate(From,Dest)>1 )
  483.           {
  484.               if (Ct0==0)
  485.                  printf("... Following DIRECT routes are not shortest!\n");
  486.               Ct0=1;
  487.           printf("%s,%s->%s \n",
  488.              From->CityName,From->StateName,Dest->CityName);
  489.               }
  490.         }           /* next Road to analyze */
  491.       break;
  492.     case 1:         /* trouble in file data */
  493.       fprintf(stderr,"----> Correct data in file %s and try again.\n",Active);
  494.       break;
  495.     case 2:         /* AllocMem refused */
  496.         fprintf(stderr,"----> Not enough memory to run RoadRoute.\n");
  497.     break;
  498.     case 3:         /* real trouble with file */
  499.         fprintf(stderr,"----> Can't proceed due to unreadable file %s.\n",Active);
  500.         break;
  501.     default:
  502.       fprintf(stderr,"System error: %d\n",errnum);
  503.     }  /* error switch area */
  504.   switch (AllocCount)
  505.     {
  506.     case 5:  FreeMem(RoutePoint,RoutePSize);
  507.     case 4:  FreeMem( (char *) RouteBlox,RouteSize);
  508.     case 3:  FreeMem(CityPoint,CityPSize);
  509.     case 2:  FreeMem( (char *) CityBlox,CitySize);
  510.     case 1:  FreeMem( (char *) fibb,INFOSIZE);
  511.     }  /* memory cleanup */
  512.   if (errnum != 0)
  513.     {
  514.     fprintf(stderr,"Press any key to quit\n");
  515.     gets(InBuff);
  516.     }    
  517.   }
  518.  
  519.  
  520. void TimeShow(Time, Buffer)
  521.   unsigned short Time;
  522.   char *Buffer;
  523.   {
  524.   unsigned short MinFlag, radix, digit, SuppressLimit, FillChar, Hours[2];
  525.   Hours[0]=Time/60;
  526.   Hours[1]=Time%60;
  527.   SuppressLimit=1;
  528.   FillChar=':';
  529.   radix=10000;
  530.   while (radix>Hours[0] && radix>SuppressLimit)
  531.     {
  532.     radix/=10;
  533.     *Buffer++ =' ';
  534.     }
  535.   for (MinFlag=0;MinFlag<2;MinFlag++)
  536.     {
  537.     while (radix>0)
  538.       {
  539.       digit=Hours[MinFlag]/radix;
  540.       Hours[MinFlag]%=radix;
  541.       *Buffer++ =digit+'0';
  542.       radix/=10;
  543.       }  /* more digits */
  544.     *Buffer++ =FillChar;
  545.     FillChar=0;
  546.     SuppressLimit=10;
  547.     radix=10;
  548.     }  /* next MinFlag */
  549.   }
  550.  
  551. int CityMatch(TabPoint,CityText)
  552.   struct CityData *TabPoint;
  553.   char *CityText;
  554.   {
  555.   /* Name must match exactly; state is optional */
  556.   int Match, StateMatch;
  557.   char TablChar, TextChar;
  558.   char *TableName;
  559.   TableName=TabPoint->CityName;
  560.   TablChar=*TableName++; if (TablChar > 'Z') TablChar-=0x20;
  561.   TextChar=*CityText++; if (TextChar > 'Z') TextChar-=0x20;
  562.   Match=1;
  563.   StateMatch=0;
  564.   while (Match == 1 && TextChar != ',')
  565.     {
  566.     if (TablChar != TextChar)
  567.       {
  568.       if (TablChar ==',' && TextChar =='/') StateMatch=1;
  569.       else Match=0;
  570.       }
  571.     TablChar=*TableName++; if (TablChar > 'Z') TablChar-=0x20;
  572.     TextChar=*CityText++; if (TextChar > 'Z') TextChar-=0x20;
  573.     }
  574.   if (Match==1)
  575.     {
  576.     if (TablChar != 0 && TablChar !=',') Match=0;
  577.     if (TabPoint->MinDist[0]==1 && StateMatch ==0) Match=0;
  578.     }
  579.   return (Match);
  580.   }
  581.  
  582. unsigned short ParseCities(CitiesBlock,CBlockSize)
  583.   char *CitiesBlock;
  584.   long CBlockSize;
  585.   {
  586.   struct CityData *CityStruct, *CityScan;
  587.   char *LineBegin, *EndLine, *NewName, *OldName;
  588.   unsigned short CityError;
  589.   unsigned char CityIndex,NewChar,OldChar;
  590.   unsigned char FoundFlag, StateFlag;
  591.   CityError=0;
  592.   CityStruct = City0;
  593.   LineBegin = CitiesBlock;
  594.   FoundFlag=0;
  595.   for (EndLine=CitiesBlock;EndLine < CitiesBlock+CBlockSize;EndLine++)
  596.   if (*EndLine == ',' || *EndLine == 0x0A)
  597.     {
  598.     if (*EndLine == ',')
  599.       {
  600.       FoundFlag=1;
  601.       CityStruct->CityName=LineBegin;
  602.       /* MinDist[0] used as temporary dupe CityName flag */
  603.       CityStruct->MinDist[0]=0;          /* No City Duplicate Name */
  604.       CityIndex = *LineBegin & 0x1F;        /* strip first char */
  605.       CityScan = CharLink[CityIndex];
  606.       while (CityScan != 0)
  607.         {
  608.         NewName=LineBegin;
  609.         OldName=CityScan->CityName;
  610.         NewChar=*NewName++; if (NewChar > 0x60) NewChar -= 0x20;
  611.         OldChar=*OldName++; if (OldChar > 0x60) OldChar -= 0x20;
  612.         while (NewChar == OldChar && NewChar != ',')
  613.           {
  614.           NewChar=*NewName++; if (NewChar > 0x60) NewChar -= 0x20;
  615.           OldChar=*OldName++; if (OldChar > 0x60) OldChar -= 0x20;
  616.           }
  617.         if (NewChar == OldChar)     /* Dupe City Name */
  618.           {
  619.           CityStruct->MinDist[0]=1;
  620.           CityScan->MinDist[0]=1;
  621.           }
  622.         CityScan = CityScan->CityLink;
  623.         }   /* chain search for input city name */
  624.        CityStruct->CityLink = CharLink[CityIndex];
  625.       CityStruct->RoadList = 0;
  626.       CharLink[CityIndex]=CityStruct;
  627.       LineBegin=EndLine+1;
  628.       }    /* end of comma..City parsing */
  629.     else     /* NewLine */
  630.       {
  631.       *EndLine=0;
  632.       if (FoundFlag ==0)
  633.         {
  634.         fprintf(stderr,"*FILE Cities: NO COMMA:\n%s\n",LineBegin);
  635.         CityError=1;
  636.         }
  637.       FoundFlag=0;
  638.       CityStruct->StateName=LineBegin;
  639.       CityStruct->StateDupe=1;
  640.       CityIndex = *LineBegin & 0x1F;        /* strip first char */
  641.       CityScan = ChStLink[CityIndex];
  642.       StateFlag = 0;
  643.       while (CityScan != 0 && StateFlag == 0)
  644.         {
  645.         NewName=LineBegin;
  646.         OldName=CityScan->StateName;
  647.         NewChar=*NewName++; if (NewChar > 0x60) NewChar -= 0x20;
  648.         OldChar=*OldName++; if (OldChar > 0x60) OldChar -= 0x20;
  649.         while (NewChar == OldChar && NewChar !=0 && OldChar !=0)
  650.           {
  651.           NewChar=*NewName++; if (NewChar > 0x60) NewChar -= 0x20;
  652.           OldChar=*OldName++; if (OldChar > 0x60) OldChar -= 0x20;
  653.           }
  654.         if (NewChar == OldChar)
  655.           {
  656.           CityScan->StateDupe=0;
  657.           StateFlag=1;
  658.           }
  659.         CityScan = CityScan->StateLink;
  660.         }   /* more states in chain */
  661.       CityStruct->StateLink = ChStLink[CityIndex];
  662.       ChStLink[CityIndex]=CityStruct;
  663.       CityStruct++;
  664.       LineBegin=EndLine+1;
  665.       }    /* end of NewLine parsing */
  666.     }
  667.   City9=CityStruct;
  668.   return(CityError);
  669.   }
  670.  
  671. unsigned short ParseRoutes(DataBlock,BlockSize)
  672.   char *DataBlock;
  673.   long BlockSize;
  674.   {
  675.   struct RouteData *RouteStruct;
  676.   struct CityData *CityScan, *FoundCity;
  677.   unsigned short ErrorFlag, CityColm, CityFlag, CityValue, Multiplier;
  678.   unsigned char CtNameKey, Digit;
  679.   char *LineStart,*LineEnd,*FieldStart,*FieldEnd,*NumPtr;
  680.   ErrorFlag=0;
  681.   RouteStruct = Route0;
  682.   LineStart = DataBlock;
  683.   for (LineEnd=DataBlock;LineEnd < DataBlock+BlockSize;LineEnd++)
  684.   if (*LineEnd == 0x0A)
  685.     {
  686.     *LineEnd=0;
  687.     FieldStart=LineStart;
  688.     for (CityColm=0 ; ErrorFlag==0 && CityColm < 2 ; CityColm++)
  689.       {
  690.       for (FieldEnd=FieldStart ;
  691.              *FieldEnd !=',' && FieldEnd < LineEnd ; FieldEnd++);
  692.       if (*FieldEnd !=',')
  693.         {
  694.         fprintf(stderr,"*FILE Roads:  MISSING FIELDS:\n%s\n",LineStart);
  695.         ErrorFlag=1;
  696.         }   /* no comma! */
  697.       /* ***** search city name chain */
  698.       CtNameKey = *FieldStart & 0x1F;        /* strip first char */
  699.       CityScan = CharLink[CtNameKey];
  700.       CityValue =0;
  701.       while (CityScan != 0 && CityValue ==0)
  702.         {
  703.         if (CityMatch(CityScan,FieldStart)==1)
  704.           {
  705.           CityValue=1;
  706.           FoundCity=CityScan;
  707.           }
  708.         CityScan = CityScan->CityLink;
  709.         }   /* chain search for input city name */      
  710.       if (CityValue ==0)
  711.         {
  712.         fprintf(stderr,"*FILE Roads:  CITY NOT FOUND:\n%s\n",LineStart);
  713.         ErrorFlag=1;
  714.         }
  715.       RouteStruct->CityNum[CityColm]=FoundCity;
  716.       RouteStruct->RLink[CityColm]=FoundCity->RoadList;
  717.       RouteStruct->Colm[CityColm]=FoundCity->Colum;
  718.       FoundCity->RoadList=RouteStruct;
  719.       FoundCity->Colum=CityColm;
  720.       FieldStart=FieldEnd+1;
  721.       }   /* two-city loop */
  722.     /* Now grab mileage, time, and Hiway */
  723.     for (CityColm=0 ; ErrorFlag==0 && CityColm < 2 ; CityColm++)
  724.       {
  725.       for (FieldEnd=FieldStart ;
  726.                 *FieldEnd !=',' && FieldEnd < LineEnd ; FieldEnd++);
  727.       if (*FieldEnd !=',')
  728.         {
  729.         fprintf(stderr,"FILE Roads:  MISSING FIELDS:\n%s????\n",LineStart);
  730.         ErrorFlag=1;
  731.         }   /* no comma! */
  732.       CityValue=0 ; CityFlag=0;
  733.       Multiplier=10;
  734.       for (NumPtr=FieldStart ; CityFlag==0 && NumPtr < FieldEnd ;
  735.                                                           NumPtr++)
  736.         {
  737.         Digit=*NumPtr;
  738.         if (Digit >='0' && Digit<='9')
  739.           {
  740.           CityValue=CityValue * Multiplier + Digit - '0';
  741.           Multiplier=10;
  742.           }
  743.         else if (Digit ==':') Multiplier = 6;
  744.         }  /* Scan for colon */
  745.       RouteStruct->Dist[CityColm]=CityValue;
  746.       FieldStart=FieldEnd+1;
  747.       }    /* Two value paramemters */
  748.     RouteStruct->Hiway=FieldStart;
  749.     RouteStruct++;
  750.     LineStart=LineEnd+1;
  751.     }    /* end of routefile scan */
  752.   Route9 = RouteStruct;
  753.   return(ErrorFlag);
  754.   }   /* if no error, table build */
  755.  
  756. #define MENUSIZE 30
  757.  
  758. unsigned short Navigate(struct CityData *Start,struct CityData *Finish)
  759.   {
  760.   unsigned short Column, Travel;
  761.   unsigned short NextCol, NewCol;
  762.   struct CityData *CityScan;
  763.   struct CityData *BLink, *SearchCity;
  764.   struct CityData *ELink, *FLink, *OtherCity;
  765.   struct RouteData *NextRoute, *NewRoute;
  766.   static unsigned short MiniVal;
  767.   static unsigned short ThisDist[2], LCount[2];
  768.         for (CityScan=City0; CityScan<City9; CityScan++)
  769.           {
  770.           CityScan->WorkList = 0;
  771.           for (Column=0; Column<2; Column++)
  772.             {
  773.             CityScan->MinDist[Column]=9999;
  774.             CityScan->NextCity[Column]=0;
  775.             }
  776.           }
  777.         ELink=Finish;
  778.         MiniVal=0;
  779.         for (Column=0; Column<2; Column++)
  780.           {
  781.           Finish->MinDist[Column]=0;
  782.           ThisDist[Column]=9999;
  783.           }
  784.         SearchCity=Finish;       
  785.         while (SearchCity != 0)
  786.           {
  787.           for (Column=0; Column<2; Column++)
  788.             {
  789.             if (SearchCity->MinDist[Column] < Start->MinDist[Column])
  790.               {
  791.     /*   if (Column==0)
  792.      *   printf("Scanning map at range: %d\n",SearchCity->MinDist[0]); */
  793.               MiniVal=SearchCity->MinDist[Column];
  794.               NextRoute=SearchCity->RoadList;
  795.               NextCol=SearchCity->Colum;
  796.               while (NextRoute != 0)
  797.                 {
  798.                 OtherCity=NextRoute->CityNum[1-NextCol];
  799.                 Travel=MiniVal+NextRoute->Dist[Column];
  800.                 if (OtherCity->MinDist[Column] > Travel)
  801.                   /* found a new shortest path */
  802.                   {
  803.                   OtherCity->MinDist[Column]=Travel;
  804.                   OtherCity->NextCity[Column]=SearchCity;
  805.                   if (OtherCity->WorkList == 0 && ELink!=OtherCity)
  806.                     {
  807.                     BLink=SearchCity;
  808.                     FLink=SearchCity->WorkList;
  809.                     while (FLink!=0 && Travel>FLink->MinDist[Column])
  810.                       {
  811.                       BLink=FLink;
  812.                       FLink=BLink->WorkList;
  813.                       }
  814.                     BLink->WorkList=OtherCity;
  815.                     OtherCity->WorkList=FLink;
  816.                     if (FLink==0) ELink=OtherCity;
  817.                     }  /* build new Worklist */
  818.                   }    /* shorter total distance */
  819.                 if (Travel < ThisDist[Column]) ThisDist[Column]=Travel; 
  820.                 NewRoute=NextRoute->RLink[NextCol];
  821.                 NewCol=NextRoute->Colm[NextCol];
  822.                 NextRoute=NewRoute;
  823.                 NextCol=NewCol;
  824.                 }   /* Try another route from SearchCity */
  825.               }     /* if Search City within target range */
  826.             }       /* Next Column (Mileage/Time) */
  827.           BLink=SearchCity->WorkList;
  828.           SearchCity->WorkList=0;
  829.           SearchCity=BLink;
  830.           }  /* if SearchCity not zero, go back */
  831.         for (Column=0; Column<2; Column++)
  832.           {
  833.           LCount[Column]=0;
  834.           SearchCity=Start;
  835.           FLink=SearchCity->NextCity[Column];
  836.           while (FLink != 0)
  837.             {
  838.             LCount[Column]+=1;
  839.             Trail[TrailPoint[Column]++][Column]=FLink;
  840.             SearchCity=FLink;
  841.             FLink=SearchCity->NextCity[Column];
  842.             }  /* wend for next FLink */
  843.           }    /* next Column */
  844.   MiniVal=LCount[0];
  845.   if (MiniVal<LCount[1]) MiniVal=LCount[1];
  846.   return(MiniVal);
  847.   }
  848.