[comp.sources.misc] v09i015: FPLAN 5/6

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (11/27/89)

Posting-number: Volume 9, Issue 15
Submitted-by: tynor@prism.gatech.edu (Steve Tynor)
Archive-name: fplan/part05

#This is part 5/6 of FPLAN
#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#	Packed Mon Nov 20 19:28:40 EST 1989 by gaffa!tynor
#	from directory /files/home/users/tynor/src/fplan
#
#	Run the following text with /bin/sh to create:
#	  main.c
#	  misc.c
#	  db.c
#	  strings.c
#
echo "x - extracting main.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > main.c &&
X/*
X * $Id: main.c,v 2.12 89/11/11 19:13:48 tynor Exp $
X *----------------------------------------------------------------------------
X *	FPLAN - Flight Planner
X *	Steve Tynor
X *	tynor@prism.gatech.edu
X *
X *	This program is in the public domain. Permission to copy,
X * distribute, modify this program is hearby given as long as this header
X * remains. If you redistribute this program after modifying it, please
X * document your changes so that I do not take the blame (or credit) for
X * those changes.  If you fix bugs or add features, please send me a
X * patch so that I can keep the 'official' version up-to-date.
X *
X *	Bug reports are welcome and I'll make an attempt to fix those
X * that are reported.
X *
X *	USE AT YOUR OWN RISK! I assume no responsibility for any
X * errors in this program, its database or documentation. I will make an
X * effort to fix bugs, but if you crash and burn because, for example,
X * fuel estimates in this program were inaccurate, it's your own fault
X * for trusting somebody else's code! Remember, as PIC, it's _your_
X * responsibility to do complete preflight planning. Use this program as
X * a flight planning aid, but verify its results before using them.
X *----------------------------------------------------------------------------
X */
X
Xstatic char rcsid[] = "$Id: main.c,v 2.12 89/11/11 19:13:48 tynor Exp $";
X
X#include <stdio.h>
X#include "wp_info.h"
X#include "version.h"
X
X#define EXIT_GOOD 0
X#define EXIT_BAD  1
X
Xextern FILE *yyin;
Xextern BOOLEAN open_dbs ();
Xextern BOOLEAN close_dbs ();
Xextern BOOLEAN compute_plan ();
Xextern void print_plan ();
Xextern void set_output_units ();
Xextern void set_format ();
Xextern void set_brief ();
Xextern char yytext[];
Xextern BOOLEAN lookup_desig ();
Xextern void put_db_summary ();
Xextern void print_reverse ();
X
X/*
X * if any of the GFX_* options are defined, define GFX
X */
X#ifdef GFX_SUNVIEW
X#define GFX
X#endif
X#ifdef GFX_X
X#undef GFX
X#define GFX
X#endif
X#ifdef GFX_POSTSCRIPT
X#undef GFX
X#define GFX
X#endif
X
X/*----------------------------------------------------------------------------*/
Xstatic void do_lookup (desig)
X     char *desig;
X{
X   DATABASE_INFO *db1 = (DATABASE_INFO*)0;
X   DATABASE_INFO *db2 = (DATABASE_INFO*)0;
X
X   if (lookup_desig (WP_VIA, desig, &db1))
X      put_db (stdout, db1);
X
X   if (lookup_desig (WP_FROM, desig, &db2))
X      if (!db1 || (db1->mode != db2->mode))
X	 put_db (stdout, db2);
X}
X
X/*----------------------------------------------------------------------------*/
Xstatic void init (brief)
X     BOOLEAN brief;
X{
X   /* 
X    * NOTE: we count on all variables being set to 0 (thus all optional values
X    * are 'off' by default).
X    */
X   num_waypoints = 0;
X   num_cached = 0;
X   set_brief (brief);
X}
X
X/*----------------------------------------------------------------------------*/
Xstatic BOOLEAN parse_script ()
X{
X   return (BOOLEAN) (! yyparse ());
X}
X
X/*----------------------------------------------------------------------------*/
Xusage (progname)
X     char *progname;
X{
X   fprintf (stderr, "FPLAN %s\n", VERSION);
X   /*
X    * LOOKUP mode:
X    */
X   fprintf (stderr, "usage: %s -l designator ...\n", progname);
X   fprintf (stderr, "\t-l - lookup the designator(s) in the databases\n");
X
X   /*
X    * REVERSE mode:
X    */
X   fprintf (stderr, "    or\n");
X   fprintf (stderr, "       %s -r [-|planfile]\n", progname);
X   fprintf (stderr, "\t-r - compute the return trip, prints the reversed plan to stdout.\n");
X   fprintf (stderr, "\t-  - read 'planfile' from the standard input.\n");
X
X#ifdef GFX
X   /*
X    * GRAPHICS mode:
X    */
X   fprintf (stderr, "    or\n");
X   fprintf (stderr, "       %s -g [-|planfile]\n", progname);
X
X#ifdef GFX_SUNVIEW
X   fprintf (stderr, "\t-g - preview the route graphically in a Sunview window\n");
X#endif /* GFX_SUNVIEW */
X#ifdef GFX_X
X   fprintf (stderr, "\t-g - preview the route graphically in an X window\n");
X#endif /* GFX_X*/
X#ifdef GFX_POSTSCRIPT
X   fprintf (stderr, "\t-g - create a PostScript program to draw the route\n");
X#endif /* GFX_POSTSCRIPT*/
X   fprintf (stderr, "\t-  - read 'planfile' from the standard input.\n");
X#endif /* GFX */
X
X   /*
X    * NORMAL mode:
X    */
X   fprintf (stderr, "    or\n");
X   fprintf (stderr, "       %s [-n|w][-b][-t][-s][-e][-|planfile]\n", 
X	    progname);
X   fprintf (stderr, "\t-n - selects the narrow (no VOR fixes) format form [default]\n");
X   fprintf (stderr, "\t-w - selects the wide (VOR fixes) format form \n");
X   fprintf (stderr, "\t-s - selects Statute miles for output format [default = Nautical]\n");
X   fprintf (stderr, "\t-t - disable automatically tracking navaids in NAV1 [default = enabled]\n");
X   fprintf (stderr, "\t-b - set BRIEF mode - ignore 'incremental' waypoints\n");
X   fprintf (stderr, "\t-e - use Epson (PC) box characters on output form\n");
X   fprintf (stderr, "\t-d - append a summary of all database objects used\n");
X   fprintf (stderr, "\t-  - read 'planfile' from the standard input.\n");
X   fprintf (stderr, "    the planfile format is described in FPLAN(1)\n");
X   exit (EXIT_BAD);
X}
X
X/*----------------------------------------------------------------------------*/
Xint main (argc, argv)
X     int argc;
X     char *argv[];
X{
X   enum {WIDE, NARROW} format = NARROW;
X   int i;
X   BOOLEAN auto_nav1        = TRUE;
X   BOOLEAN brief            = FALSE;
X   BOOLEAN epson_box_chars  = FALSE;
X   BOOLEAN reverse          = FALSE;
X   BOOLEAN database_summary = FALSE;
X#ifdef GFX_SUNVIEW
X   BOOLEAN draw_sunview     = FALSE;
X#endif
X#ifdef GFX_X
X   BOOLEAN draw_x           = FALSE;
X#endif
X#ifdef GFX_POSTSCRIPT
X   BOOLEAN draw_postscript  = FALSE;
X#endif
X
X   if (argc < 2)
X      usage (argv[0]);
X
X   if (! open_dbs ())
X      exit (EXIT_BAD);
X
X   if ((argv[1][0] == '-') && (argv[1][1] == 'l')) {
X      for (i = 2; i < argc; i++)
X	 do_lookup (argv[i]);
X      exit (EXIT_GOOD);
X   }
X
X   yyin = NULL;
X   set_output_units (1);
X   for (i = 1; i < argc; i++) {
X      if (argv[i][0] == '-') {
X	 switch (argv[i][1]) {
X	 case 'g':
X	    /* 
X	     *leave these separate for now, we'll probably want to link in all
X	     * three on some systems...
X	     */
X#ifdef GFX_SUNVIEW
X	    draw_sunview = TRUE;
X#endif
X#ifdef GFX_X
X	    draw_x = TRUE;
X#endif
X#ifdef GFX_POSTSCRIPT
X	    draw_postscript = TRUE;
X#endif
X	    break;
X	 case 'r':
X	    reverse = TRUE;
X	    break;
X	 case 'e':
X	    epson_box_chars = TRUE;
X	    break;
X	 case 'd':
X	    database_summary = TRUE;
X	    break;
X	 case 's':
X	    set_output_units (0);
X	    break;
X	 case 'n':
X	    format = NARROW;
X	    break;
X	 case 'w':
X	    format = WIDE;
X	    break;
X	 case 'b':
X	    brief = TRUE;
X	    break;
X	 case 't':
X	    auto_nav1 = FALSE;
X	    break;
X	 case '\0':
X	    if (yyin) {
X	       fprintf (stderr, 
X			"ERROR: cannot read from stdin and planfile: \"%s\".\n",
X			argv[i]);
X	       usage (argv[0]);
X	    } else {
X	       yyin = stdin;
X	    }
X	    break;
X	 default:
X	    fprintf (stderr, "ERROR: unknown option: \"%s\".\n", argv[i]);
X	    usage (argv[0]);
X	    break;
X	 }
X      } else {
X	 if (yyin) {
X	    fprintf (stderr, "ERROR: only one planfile allowed: \"%s\".\n",
X		     argv[i]);
X	    usage (argv[0]);
X	 } else {
X	    yyin = fopen (argv[i], "r");
X            if (! yyin) {
X	       fprintf (stderr, "ERROR: could not open script file: %s.\n", 
X			argv[i]);
X	       usage (argv[0]);
X	    }
X	 }
X      }
X   }
X
X   if (! yyin) {
X      fprintf (stderr, "ERROR: no planfile\n");
X      usage (argv[0]);
X   }
X   init (brief);
X
X   if (! parse_script ())
X      exit (EXIT_BAD);
X
X   if (! compute_plan (auto_nav1) )
X      exit (EXIT_BAD);
X
X   if (reverse) {
X      print_reverse ();
X#ifdef GFX_SUNVIEW
X   } else if (draw_sunview) {
X      sv_draw (brief);
X#endif
X#ifdef GFX_X
X   } else if (draw_x) {
X      x_draw (brief);
X#endif
X#ifdef GFX_POSTSCRIPT
X   } else if (draw_postscript) {
X      ps_draw (brief);
X#endif
X   } else {
X      if (format == NARROW)
X	 max_nav = -1;
X      else if (auto_nav1)
X	 max_nav = MAX (0, max_nav);
X      set_format (max_nav, epson_box_chars);
X      
X      print_plan ();
X
X      if (database_summary)
X	 put_db_summary (stdout);
X   }
X
X   if (! close_dbs ())
X      exit (EXIT_BAD);
X}
X
X
X/*----------------------------------------------------------------------------*/
Xint yyerror(s)
Xchar* s;
X{
X   extern int yylineno;
X
X   fprintf (stderr, "ERROR: line %d: %s\n", yylineno, s);
X   exit (EXIT_BAD);
X}
X
X/*----------------------------------------------------------------------------*/
Xint yywrap ()
X{
X   return (1);
X}
X
X/*----------------------------------------------------------------------------*/
Xint yyreject ()
X{
X   printf ("ERROR: parser rejecting %s\n", yytext);
X   return (1);
X}
X
SHAR_EOF
chmod 0444 main.c || echo "restore of main.c fails"
echo "x - extracting misc.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > misc.c &&
X/*
X * $Id: misc.c,v 2.3 89/11/05 11:23:46 tynor Exp $
X *----------------------------------------------------------------------------
X *	FPLAN - Flight Planner
X *	Steve Tynor
X *	tynor@prism.gatech.edu
X *
X *	This program is in the public domain. Permission to copy,
X * distribute, modify this program is hearby given as long as this header
X * remains. If you redistribute this program after modifying it, please
X * document your changes so that I do not take the blame (or credit) for
X * those changes.  If you fix bugs or add features, please send me a
X * patch so that I can keep the 'official' version up-to-date.
X *
X *	Bug reports are welcome and I'll make an attempt to fix those
X * that are reported.
X *
X *	USE AT YOUR OWN RISK! I assume no responsibility for any
X * errors in this program, its database or documentation. I will make an
X * effort to fix bugs, but if you crash and burn because, for example,
X * fuel estimates in this program were inaccurate, it's your own fault
X * for trusting somebody else's code! Remember, as PIC, it's _your_
X * responsibility to do complete preflight planning. Use this program as
X * a flight planning aid, but verify its results before using them.
X *----------------------------------------------------------------------------
X */
X
Xstatic char rcsid[] = "$Id: misc.c,v 2.3 89/11/05 11:23:46 tynor Exp $";
X
X#include <math.h>
X
X/*----------------------------------------------------------------------------*/
Xdouble degrees_mins_2_decimal (hm)
X     double hm;
X{
X   /*
X    * input looks like: 40.45 (40 deg, 45 min), output is 40.75 (40.75 deg)
X    */
X   double i = (double) floor (hm);
X   
X   return (i + (hm - i) / 0.6);
X}
X
X/*----------------------------------------------------------------------------*/
Xdouble decimal_2_degrees_mins (dec)
X     double dec;
X{
X   /*
X    * input looks like: 40.75 (40.75 deg), output is 40 and 45 (40 deg, 45 min)
X    */
X   double tmp = (double) floor (dec);
X
X   return (tmp + 0.6 * (dec - tmp));
X}
X
SHAR_EOF
chmod 0444 misc.c || echo "restore of misc.c fails"
echo "x - extracting db.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > db.c &&
X/*
X * $Id: db.c,v 2.9 89/11/11 19:09:34 tynor Exp $
X *----------------------------------------------------------------------------
X *	FPLAN - Flight Planner
X *	Steve Tynor
X *	tynor@prism.gatech.edu
X *
X *	This program is in the public domain. Permission to copy,
X * distribute, modify this program is hearby given as long as this header
X * remains. If you redistribute this program after modifying it, please
X * document your changes so that I do not take the blame (or credit) for
X * those changes.  If you fix bugs or add features, please send me a
X * patch so that I can keep the 'official' version up-to-date.
X *
X *	Bug reports are welcome and I'll make an attempt to fix those
X * that are reported.
X *
X *	USE AT YOUR OWN RISK! I assume no responsibility for any
X * errors in this program, its database or documentation. I will make an
X * effort to fix bugs, but if you crash and burn because, for example,
X * fuel estimates in this program were inaccurate, it's your own fault
X * for trusting somebody else's code! Remember, as PIC, it's _your_
X * responsibility to do complete preflight planning. Use this program as
X * a flight planning aid, but verify its results before using them.
X *----------------------------------------------------------------------------
X */
X
X#include "mystring.h"
X#include <stdio.h>
X#include <ctype.h>
X#include "wp_info.h"
X
Xextern char *malloc();
Xextern char *getenv();
Xextern int qsort();
X
Xstatic char rcsid[] = "$Id: db.c,v 2.9 89/11/11 19:09:34 tynor Exp $";
X
X/*
X * the database file pointers:
X */
X
Xtypedef struct {
X   FILE  *fp;
X   long  rec_size;
X   long  num_recs;
X} DB_FILE;
X
X
XDB_FILE pub_airports, pvt_airports, pub_vors, pvt_vors;
X
X/*
X * environment variables for where the databases are:
X */
X#define HOME 		"HOME"
X#define NAV_PUBLIC	"NAV"
X#define NAV_PRIVATE	"NAV_PRIVATE"
X
X#ifndef DEFAULT_PVT_DIRECTORY
X#ifdef MSDOS
X#define DEFAULT_PVT_DIRECTORY	"\\flight"
X#else
X#define DEFAULT_PVT_DIRECTORY	"~/preflight"
X#endif
X#endif
X
X#ifndef DEFAULT_PUB_DIRECTORY
X#ifdef MSDOS
X#define DEFAULT_PUB_DIRECTORY	"\\lib\\flight"
X#else
X#define DEFAULT_PUB_DIRECTORY	"/usr/local/lib/preflight"
X#endif
X#endif
X
X#ifdef MSDOS
X#define AIRPORTS_NAME "\\airports.nav"
X#define VORS_NAME     "\\vors.nav"
X#else
X#define AIRPORTS_NAME "/airports.nav"
X#define VORS_NAME     "/vors.nav"
X#endif
X
X#define FSEEK_FROM_BEGINNING 0
X#define FSEEK_FROM_CURRENT   1
X#define FSEEK_FROM_END       2
X
X/*----------------------------------------------------------------------------*/
Xstatic long get_rec_size (buffer)
Xchar *buffer;
X{
X   long i;
X
X   for (i = 0;; i++) {
X      if (buffer[i] == '\n') {
X	 return (i + 1L);
X      }
X   }
X}
X
X/*----------------------------------------------------------------------------*/
Xstatic long get_num_recs (rec_size, fp, filename)
X     long  rec_size;
X     FILE **fp;
X     char *filename;
X{
X   long file_size;
X
X   if (fseek (*fp, 0L, FSEEK_FROM_END)) {
X      fprintf (stderr, "ERROR: could not seek in db file: %s\n", filename);
X      *fp = NULL;
X      return (0L);
X   }
X   file_size = ftell (*fp);
X
X#ifndef MSDOS
X   /*
X    * can't figure out why MSC doesn't do this properly - maybe it's an 
X    * inconsistency in the way fseek works? For now, just assume that 
X    * database is in the proper format.
X    */
X   if ((file_size % rec_size) != 0L) {
X      fprintf (stderr, 
X	       "ERROR: file size (%ld/%ld) inconsistency in db file: %s\n", 
X	       file_size, rec_size, filename);
X      *fp = NULL;
X      return (0L);
X   }
X#endif
X   return (file_size / rec_size);
X}
X
X/*----------------------------------------------------------------------------*/
XBOOLEAN open_dbs ()
X{
X   char *pub_dir, *pvt_dir;
X   BOOLEAN ok;
X
X#define BUFSIZE 200
X   char filename[BUFSIZE];
X   char buffer[BUFSIZE];
X
X#ifdef MSDOS
X#define OPEN_MODE "rb"
X#else
X#define OPEN_MODE "r"
X#endif
X
X   if (! (pub_dir = getenv (NAV_PUBLIC)))
X      pub_dir = DEFAULT_PUB_DIRECTORY;
X
X   if (! (pvt_dir = getenv (NAV_PRIVATE)))
X      pvt_dir = DEFAULT_PVT_DIRECTORY;
X
X#ifndef MSDOS
X   if (pvt_dir[0] == '~') {
X      strcpy (filename, getenv (HOME));
X      strcat (filename, &pvt_dir[1]);
X      pvt_dir = strdup (filename);
X   }
X#endif
X
X   strcpy (filename, pub_dir);
X   strcat (filename, AIRPORTS_NAME);
X   if (pub_airports.fp = fopen (filename, OPEN_MODE)) {
X      fgets (buffer, BUFSIZE, pub_airports.fp);
X      pub_airports.rec_size = get_rec_size (buffer);
X      pub_airports.num_recs = get_num_recs (pub_airports.rec_size,
X					    &pub_airports.fp, filename);
X   }
X
X   strcpy (filename, pvt_dir);
X   strcat (filename, AIRPORTS_NAME);
X   if (pvt_airports.fp = fopen (filename, OPEN_MODE)) {
X      fgets (buffer, BUFSIZE, pvt_airports.fp);
X      pvt_airports.rec_size = get_rec_size (buffer);
X      pvt_airports.num_recs = get_num_recs (pvt_airports.rec_size,
X					    &pvt_airports.fp, filename);
X   }
X
X   strcpy (filename, pub_dir);
X   strcat (filename, VORS_NAME);
X   if (pub_vors.fp = fopen (filename, OPEN_MODE)) {
X      fgets (buffer, BUFSIZE, pub_vors.fp);
X      pub_vors.rec_size = get_rec_size (buffer);
X      pub_vors.num_recs = get_num_recs (pub_vors.rec_size,
X					&pub_vors.fp, filename);
X   }
X
X   strcpy (filename, pvt_dir);
X   strcat (filename, VORS_NAME);
X   if (pvt_vors.fp = fopen (filename, OPEN_MODE)) {
X      fgets (buffer, BUFSIZE, pvt_vors.fp);
X      pvt_vors.rec_size = get_rec_size (buffer);
X      pvt_vors.num_recs = get_num_recs (pvt_vors.rec_size,
X					&pvt_vors.fp, filename);
X   }
X   ok = TRUE;
X
X   if (!pub_airports.fp && !pvt_airports.fp) {
X      ok = FALSE;
X      fprintf (stderr, "ERROR: neither public or private airports db found\n");
X   }
X   if (!pub_vors.fp && !pvt_vors.fp) {
X      ok = FALSE;
X      fprintf (stderr, "ERROR: neither public or private vors db found\n");
X   }
X   return (ok);
X}
X
X/*----------------------------------------------------------------------------*/
XBOOLEAN close_dbs ()
X{
X   if (pub_airports.fp)
X      fclose (pub_airports.fp);
X   if (pvt_airports.fp)
X      fclose (pvt_airports.fp);
X   if (pub_vors.fp)
X      fclose (pub_vors.fp);
X   if (pvt_vors.fp)
X      fclose (pvt_vors.fp);
X
X   return (TRUE);
X}
X
X
X/*----------------------------------------------------------------------------*/
Xstatic BOOLEAN lookup_desig_internal (db, desig, buffer_size, buffer)
X     DB_FILE db;
X     char *desig;
X     int  buffer_size;
X     char *buffer;
X{
X   long low, high, mid;
X   int  cmp;
X   if (! db.fp) 
X      return FALSE;
X
X#ifdef NO_BINARY_SEARCH
X   rewind (db.fp);   
X   while (fgets (buffer, buffer_size, db.fp)) {
X      if (!strcmp (desig, strtok (buffer, ":\n")))
X	 return TRUE;
X   }
X   return FALSE;
X#else
X   low = 0L;
X   high = db.num_recs;
X   while (low <= high) {
X      mid = (low + high) / 2L;
X      fseek (db.fp, mid * db.rec_size, FSEEK_FROM_BEGINNING);
X      fgets (buffer, buffer_size, db.fp);
X      cmp =strcmp (desig, strtok (buffer, ":\n"));
X      if (!cmp)
X	 return TRUE;
X      else if (cmp > 0)
X	 low = mid + 1;
X      else
X	 high = mid - 1;
X   }
X   return FALSE;
X#endif
X}
X
X/*----------------------------------------------------------------------------*/
Xstatic void decode_common (db)
X     DATABASE_INFO *db;
X{
X   extern double atof ();
X   extern double degrees_mins_2_decimal ();
X   double d1, d2;
X
X   db->altitude.value =  atof (strtok ((char*)0, ":\n"));
X   db->altitude.valid = TRUE;
X
X   d1 = atof (strtok ((char*)0, ":\n"));
X   d2 = atof (strtok ((char*)0, ":\n"));
X   db->mag_variation = d1 + d2 / 60.0;
X
X   d1 = atof (strtok ((char*)0, ":\n"));
X   d2 = atof (strtok ((char*)0, ":\n"));
X   db->latitude = d1 + d2 / 60.0;
X
X   d1 = atof (strtok ((char*)0, ":\n"));
X   d2 = atof (strtok ((char*)0, ":\n"));
X   db->longitude = d1 + d2 / 60.0;
X}
X
X/*----------------------------------------------------------------------------*/
Xstatic void decode_vor (db)
X     DATABASE_INFO *db;
X{
X   char *tok;
X
X   db->name = strdup (strtok ((char*)0, ":\n"));
X
X   tok = strdup (strtok ((char*)0, ":\n"));   
X   if (tok[0] != '\0') {
X      db->freq.valid = TRUE;
X      db->freq.value = atof (tok);
X   } else
X      db->freq.valid = FALSE;
X
X   decode_common (db);
X
X   tok = strtok ((char*)0, ":\n");
X   if (!strcmp ("NDB", tok))
X      db->mode = WP_NDB;
X   else if (!strcmp ("VOR", tok))
X      db->mode = WP_VOR;
X   else if (!strcmp ("DME", tok))
X      db->mode = WP_DME;
X   else if (!strcmp ("TAC", tok))
X      db->mode = WP_TAC;
X   else if (!strcmp ("ILS", tok))
X      db->mode = WP_ILS;
X   else if (!strcmp ("INT", tok))
X      db->mode = WP_NAMED_INTERSECTION;
X   else if (!strcmp ("WPT", tok))
X      db->mode = WP_WPT;
X   else if (!strcmp ("LOM", tok))
X      db->mode = WP_LOM;
X   else if (!strcmp ("LMM", tok))
X      db->mode = WP_LMM;
X   else 
X      db->mode = WP_UNK;
X
X   tok = strtok ((char*)0, ":\n");   
X   if (tok)
X      db->comment = strdup (tok);
X   else
X      db->comment = NULL;
X}
X
X/*----------------------------------------------------------------------------*/
Xstatic void decode_airport (db)
X     DATABASE_INFO *db;
X{
X   char *tok;
X
X   db->mode = WP_AIRPORT;
X   db->city = strdup (strtok ((char*)0, ":\n"));   
X   db->name = strdup (strtok ((char*)0, ":\n"));   
X
X   decode_common (db);
X
X   tok = strdup (strtok ((char*)0, ":\n"));   
X
X   if (tok[0] != '\0') {
X      db->freq.valid = TRUE;
X      db->freq.value = atof (tok);
X   } else
X      db->freq.valid = FALSE;
X
X   tok = strtok ((char*)0, ":\n");   
X   if (tok)
X      db->comment = strdup (tok);
X   else
X      db->comment = NULL;
X}
X
X/*----------------------------------------------------------------------------*/
Xstatic void str_upcase (str)
X     char *str;
X{
X   int i;
X
X   for (i = 0; str[i] != '\0'; i++)
X      if (islower (str[i]))
X	  str[i] = toupper (str[i]);
X}
X
X/*----------------------------------------------------------------------------*/
Xstatic BOOLEAN in_cache (mode, desig)
X     WAYPOINT_MODE mode;
X     char *desig;
X{
X   int i;
X
X   for (i = 0; i < num_cached; i++) {
X      if ((!strcmp (desig, cache[i]->desig)) && 
X	  (mode == cache[i]->mode)) {
X	 return TRUE;
X      }
X   }
X   return FALSE;
X}
X
X/*----------------------------------------------------------------------------*/
XBOOLEAN lookup_desig (kind, desig, db)
X     WAYPOINT_KIND kind;
X     char          *desig;
X     DATABASE_INFO **db;
X{
X#undef BUFSIZE
X#define BUFSIZE 200
X   char buffer [BUFSIZE];
X   DB_FILE fps[4];
X   int i;
X   BOOLEAN found;
X   extern yyerror();
X   enum {VOR, AIRPORT} db_kind;
X
X   str_upcase (desig);
X
X   if (kind == WP_VIA) {
X      /* 
X       * prefer the VOR databases
X       */
X      fps[0] = pvt_vors;
X      fps[1] = pub_vors;
X      fps[2] = pvt_airports;
X      fps[3] = pub_airports;
X   } else {
X      /* 
X       * prefer the AIRPORT databases 
X       */
X      fps[0] = pvt_airports;
X      fps[1] = pub_airports;
X      fps[2] = pvt_vors;
X      fps[3] = pub_vors;
X   }
X
X   for (i = 0; i < 4; i++) {
X      if (found = lookup_desig_internal (fps[i], desig, BUFSIZE, buffer)) {
X#if 0
X	 printf ("%s found w/db %d[%ld] (%s)\n",desig,i,fps[i].fp,
X		 ((fps[i].fp == pub_airports.fp) ||
X		  (fps[i].fp == pvt_airports.fp)) ? "APT" : "VOR");
X#endif
X	 if ((fps[i].fp == pub_airports.fp) || (fps[i].fp == pvt_airports.fp))
X	    db_kind = AIRPORT;
X	 else
X	    db_kind = VOR;
X	 break;
X      }
X   }
X   if (! found) {
X      fprintf (stderr, "ERROR: could not find %s in any database\n", desig);
X      return FALSE;
X   }
X
X   /*
X    * now, convert it into a db record...
X    */
X
X   *db = (DATABASE_INFO*) malloc (sizeof (DATABASE_INFO));
X   if (! *db)
X      yyerror ("unable to allocate space for database element");
X
X   (*db)->desig = desig;	/* no need to strdup - the parser already did */
X
X   if (db_kind == VOR)
X      decode_vor (*db);
X   else
X      decode_airport (*db);
X
X   /*
X    * append to the cache: (NOTE: it might already be there if we didn't grab
X    * it out of the cach because of incompatible modes - e.g. the cached wp is
X    * an airport, but this is a via node - we forced a recheck in case there was
X    * a navaid with the same desig)
X    */
X   if (num_cached < CACHE_SIZE)
X      if (! in_cache ((*db)->mode, desig)) {
X	 cache[num_cached++] = *db;
X      }
X   return TRUE;
X}
X
X/*----------------------------------------------------------------------------*/
Xstatic int dbcmp (db1, db2)
X     DATABASE_INFO **db1, **db2;
X{
X   return (strcmp ((*db1)->desig, (*db2)->desig));
X}
X
X/*----------------------------------------------------------------------------*/
Xvoid put_db_summary (out_fp)
X     FILE *out_fp;
X{
X   int i;
X
X   /*
X    * first, sort the cache 
X    */
X   qsort ((char*) &cache[0], num_cached, sizeof(DATABASE_INFO*), dbcmp);
X
X   /*
X    * now, print it out.
X    */
X   fprintf (out_fp, "\f\n");
X   for (i = 0; i < num_cached; i++)
X      put_db (out_fp, cache[i]);
X}
X
X
X/*----------------------------------------------------------------------------*/
Xvoid min_max_lat_long (min_lat, max_lat, min_long, max_long)
X     double *min_lat, *max_lat, *min_long, *max_long;
X{
X   int i;
X
X   *min_lat  =  190.0;
X   *max_lat  = -190.0;
X   *min_long =  190.0;
X   *max_long = -190.0;
X
X   for (i = 0; i < num_cached; i++) {
X      *min_lat = MIN (cache[i]->latitude, *min_lat);
X      *max_lat = MAX (cache[i]->latitude, *max_lat);
X      *min_long = MIN (cache[i]->longitude, *min_long);
X      *max_long = MAX (cache[i]->longitude, *max_long);
X   }
X}
SHAR_EOF
chmod 0444 db.c || echo "restore of db.c fails"
echo "x - extracting strings.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > strings.c &&
X/*
X * $Id: strings.c,v 1.7 89/11/11 19:13:40 tynor Exp $
X *----------------------------------------------------------------------------
X *	FPLAN - Flight Planner
X *	Steve Tynor
X *	tynor@prism.gatech.edu
X *
X *	This program is in the public domain. Permission to copy,
X * distribute, modify this program is hearby given as long as this header
X * remains. If you redistribute this program after modifying it, please
X * document your changes so that I do not take the blame (or credit) for
X * those changes.  If you fix bugs or add features, please send me a
X * patch so that I can keep the 'official' version up-to-date.
X *
X *	Bug reports are welcome and I'll make an attempt to fix those
X * that are reported.
X *
X *	USE AT YOUR OWN RISK! I assume no responsibility for any
X * errors in this program, its database or documentation. I will make an
X * effort to fix bugs, but if you crash and burn because, for example,
X * fuel estimates in this program were inaccurate, it's your own fault
X * for trusting somebody else's code! Remember, as PIC, it's _your_
X * responsibility to do complete preflight planning. Use this program as
X * a flight planning aid, but verify its results before using them.
X *----------------------------------------------------------------------------
X */
X
Xstatic char rcsid[] = "$Id: strings.c,v 1.7 89/11/11 19:13:40 tynor Exp $";
X
X#include "mystring.h"
X#include "wp_info.h"
X#include "math.h"
X
Xextern char* malloc();
X
X/*
X * define a couple of functions that are in SunOS string(3), but apparently
X * aren't 'standard' - so much for the wonder of the portability of the 
X * standard C library...
X *
X * The only thing we count on is strlen().
X */
X
X/*---------------------------------------------------------------------------*/
Xchar* index (s, c)
X     char *s, c;
X{
X   char *p;
X   for (p = s; *p; p++)
X      if (*p == c)
X	 return p;
X   if (!c)
X      return p;
X   else
X      return (char*) 0;
X}
X
X/*---------------------------------------------------------------------------*/
Xchar* strdup (s)
X     char *s;
X{
X   int len = strlen (s);
X   char *new = (char*) malloc (len + 1);
X
X   if (new)
X      strcpy (new, s);
X   return (new);
X}
X
Xstatic char *buffer;
Xstatic int  start;
Xstatic int  buf_len;
X
X/*---------------------------------------------------------------------------*/
Xchar *strtok (str, separators)
X     char *str;
X     char *separators;
X{
X   int i, k;
X   int len = strlen (separators);
X   char *ptr;
X
X   if (str) {
X      buf_len = strlen (str);
X      buffer = str;
X      start = 0;
X   }
X   if (start > buf_len) {
X      return (char*) 0;
X   }
X   for (i = 0; i <= len; i++) {
X      /*
X       * notice we cheat and use the '\0' terminator in the separators string 
X       * to always recognize '\0' as a separator.
X       */
X      if (ptr = index (&buffer[start], separators[i])) {
X	 *ptr = '\0';
X	 k = start;
X	 start = (int) (ptr - buffer + 1);
X	 return (&buffer[k]);
X      }
X   }
X   return (char*) 0;
X}
X
SHAR_EOF
chmod 0444 strings.c || echo "restore of strings.c fails"
exit 0