home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume9 / fplan / part05 < prev    next >
Text File  |  1989-11-26  |  29KB  |  1,044 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v09i015: FPLAN 5/6
  3. from: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  4. Reply-To: tynor@prism.gatech.edu (Steve Tynor)
  5.  
  6. Posting-number: Volume 9, Issue 15
  7. Submitted-by: tynor@prism.gatech.edu (Steve Tynor)
  8. Archive-name: fplan/part05
  9.  
  10. #This is part 5/6 of FPLAN
  11. #!/bin/sh
  12. # shar:    Shell Archiver  (v1.22)
  13. #    Packed Mon Nov 20 19:28:40 EST 1989 by gaffa!tynor
  14. #    from directory /files/home/users/tynor/src/fplan
  15. #
  16. #    Run the following text with /bin/sh to create:
  17. #      main.c
  18. #      misc.c
  19. #      db.c
  20. #      strings.c
  21. #
  22. echo "x - extracting main.c (Text)"
  23. sed 's/^X//' << 'SHAR_EOF' > main.c &&
  24. X/*
  25. X * $Id: main.c,v 2.12 89/11/11 19:13:48 tynor Exp $
  26. X *----------------------------------------------------------------------------
  27. X *    FPLAN - Flight Planner
  28. X *    Steve Tynor
  29. X *    tynor@prism.gatech.edu
  30. X *
  31. X *    This program is in the public domain. Permission to copy,
  32. X * distribute, modify this program is hearby given as long as this header
  33. X * remains. If you redistribute this program after modifying it, please
  34. X * document your changes so that I do not take the blame (or credit) for
  35. X * those changes.  If you fix bugs or add features, please send me a
  36. X * patch so that I can keep the 'official' version up-to-date.
  37. X *
  38. X *    Bug reports are welcome and I'll make an attempt to fix those
  39. X * that are reported.
  40. X *
  41. X *    USE AT YOUR OWN RISK! I assume no responsibility for any
  42. X * errors in this program, its database or documentation. I will make an
  43. X * effort to fix bugs, but if you crash and burn because, for example,
  44. X * fuel estimates in this program were inaccurate, it's your own fault
  45. X * for trusting somebody else's code! Remember, as PIC, it's _your_
  46. X * responsibility to do complete preflight planning. Use this program as
  47. X * a flight planning aid, but verify its results before using them.
  48. X *----------------------------------------------------------------------------
  49. X */
  50. X
  51. Xstatic char rcsid[] = "$Id: main.c,v 2.12 89/11/11 19:13:48 tynor Exp $";
  52. X
  53. X#include <stdio.h>
  54. X#include "wp_info.h"
  55. X#include "version.h"
  56. X
  57. X#define EXIT_GOOD 0
  58. X#define EXIT_BAD  1
  59. X
  60. Xextern FILE *yyin;
  61. Xextern BOOLEAN open_dbs ();
  62. Xextern BOOLEAN close_dbs ();
  63. Xextern BOOLEAN compute_plan ();
  64. Xextern void print_plan ();
  65. Xextern void set_output_units ();
  66. Xextern void set_format ();
  67. Xextern void set_brief ();
  68. Xextern char yytext[];
  69. Xextern BOOLEAN lookup_desig ();
  70. Xextern void put_db_summary ();
  71. Xextern void print_reverse ();
  72. X
  73. X/*
  74. X * if any of the GFX_* options are defined, define GFX
  75. X */
  76. X#ifdef GFX_SUNVIEW
  77. X#define GFX
  78. X#endif
  79. X#ifdef GFX_X
  80. X#undef GFX
  81. X#define GFX
  82. X#endif
  83. X#ifdef GFX_POSTSCRIPT
  84. X#undef GFX
  85. X#define GFX
  86. X#endif
  87. X
  88. X/*----------------------------------------------------------------------------*/
  89. Xstatic void do_lookup (desig)
  90. X     char *desig;
  91. X{
  92. X   DATABASE_INFO *db1 = (DATABASE_INFO*)0;
  93. X   DATABASE_INFO *db2 = (DATABASE_INFO*)0;
  94. X
  95. X   if (lookup_desig (WP_VIA, desig, &db1))
  96. X      put_db (stdout, db1);
  97. X
  98. X   if (lookup_desig (WP_FROM, desig, &db2))
  99. X      if (!db1 || (db1->mode != db2->mode))
  100. X     put_db (stdout, db2);
  101. X}
  102. X
  103. X/*----------------------------------------------------------------------------*/
  104. Xstatic void init (brief)
  105. X     BOOLEAN brief;
  106. X{
  107. X   /* 
  108. X    * NOTE: we count on all variables being set to 0 (thus all optional values
  109. X    * are 'off' by default).
  110. X    */
  111. X   num_waypoints = 0;
  112. X   num_cached = 0;
  113. X   set_brief (brief);
  114. X}
  115. X
  116. X/*----------------------------------------------------------------------------*/
  117. Xstatic BOOLEAN parse_script ()
  118. X{
  119. X   return (BOOLEAN) (! yyparse ());
  120. X}
  121. X
  122. X/*----------------------------------------------------------------------------*/
  123. Xusage (progname)
  124. X     char *progname;
  125. X{
  126. X   fprintf (stderr, "FPLAN %s\n", VERSION);
  127. X   /*
  128. X    * LOOKUP mode:
  129. X    */
  130. X   fprintf (stderr, "usage: %s -l designator ...\n", progname);
  131. X   fprintf (stderr, "\t-l - lookup the designator(s) in the databases\n");
  132. X
  133. X   /*
  134. X    * REVERSE mode:
  135. X    */
  136. X   fprintf (stderr, "    or\n");
  137. X   fprintf (stderr, "       %s -r [-|planfile]\n", progname);
  138. X   fprintf (stderr, "\t-r - compute the return trip, prints the reversed plan to stdout.\n");
  139. X   fprintf (stderr, "\t-  - read 'planfile' from the standard input.\n");
  140. X
  141. X#ifdef GFX
  142. X   /*
  143. X    * GRAPHICS mode:
  144. X    */
  145. X   fprintf (stderr, "    or\n");
  146. X   fprintf (stderr, "       %s -g [-|planfile]\n", progname);
  147. X
  148. X#ifdef GFX_SUNVIEW
  149. X   fprintf (stderr, "\t-g - preview the route graphically in a Sunview window\n");
  150. X#endif /* GFX_SUNVIEW */
  151. X#ifdef GFX_X
  152. X   fprintf (stderr, "\t-g - preview the route graphically in an X window\n");
  153. X#endif /* GFX_X*/
  154. X#ifdef GFX_POSTSCRIPT
  155. X   fprintf (stderr, "\t-g - create a PostScript program to draw the route\n");
  156. X#endif /* GFX_POSTSCRIPT*/
  157. X   fprintf (stderr, "\t-  - read 'planfile' from the standard input.\n");
  158. X#endif /* GFX */
  159. X
  160. X   /*
  161. X    * NORMAL mode:
  162. X    */
  163. X   fprintf (stderr, "    or\n");
  164. X   fprintf (stderr, "       %s [-n|w][-b][-t][-s][-e][-|planfile]\n", 
  165. X        progname);
  166. X   fprintf (stderr, "\t-n - selects the narrow (no VOR fixes) format form [default]\n");
  167. X   fprintf (stderr, "\t-w - selects the wide (VOR fixes) format form \n");
  168. X   fprintf (stderr, "\t-s - selects Statute miles for output format [default = Nautical]\n");
  169. X   fprintf (stderr, "\t-t - disable automatically tracking navaids in NAV1 [default = enabled]\n");
  170. X   fprintf (stderr, "\t-b - set BRIEF mode - ignore 'incremental' waypoints\n");
  171. X   fprintf (stderr, "\t-e - use Epson (PC) box characters on output form\n");
  172. X   fprintf (stderr, "\t-d - append a summary of all database objects used\n");
  173. X   fprintf (stderr, "\t-  - read 'planfile' from the standard input.\n");
  174. X   fprintf (stderr, "    the planfile format is described in FPLAN(1)\n");
  175. X   exit (EXIT_BAD);
  176. X}
  177. X
  178. X/*----------------------------------------------------------------------------*/
  179. Xint main (argc, argv)
  180. X     int argc;
  181. X     char *argv[];
  182. X{
  183. X   enum {WIDE, NARROW} format = NARROW;
  184. X   int i;
  185. X   BOOLEAN auto_nav1        = TRUE;
  186. X   BOOLEAN brief            = FALSE;
  187. X   BOOLEAN epson_box_chars  = FALSE;
  188. X   BOOLEAN reverse          = FALSE;
  189. X   BOOLEAN database_summary = FALSE;
  190. X#ifdef GFX_SUNVIEW
  191. X   BOOLEAN draw_sunview     = FALSE;
  192. X#endif
  193. X#ifdef GFX_X
  194. X   BOOLEAN draw_x           = FALSE;
  195. X#endif
  196. X#ifdef GFX_POSTSCRIPT
  197. X   BOOLEAN draw_postscript  = FALSE;
  198. X#endif
  199. X
  200. X   if (argc < 2)
  201. X      usage (argv[0]);
  202. X
  203. X   if (! open_dbs ())
  204. X      exit (EXIT_BAD);
  205. X
  206. X   if ((argv[1][0] == '-') && (argv[1][1] == 'l')) {
  207. X      for (i = 2; i < argc; i++)
  208. X     do_lookup (argv[i]);
  209. X      exit (EXIT_GOOD);
  210. X   }
  211. X
  212. X   yyin = NULL;
  213. X   set_output_units (1);
  214. X   for (i = 1; i < argc; i++) {
  215. X      if (argv[i][0] == '-') {
  216. X     switch (argv[i][1]) {
  217. X     case 'g':
  218. X        /* 
  219. X         *leave these separate for now, we'll probably want to link in all
  220. X         * three on some systems...
  221. X         */
  222. X#ifdef GFX_SUNVIEW
  223. X        draw_sunview = TRUE;
  224. X#endif
  225. X#ifdef GFX_X
  226. X        draw_x = TRUE;
  227. X#endif
  228. X#ifdef GFX_POSTSCRIPT
  229. X        draw_postscript = TRUE;
  230. X#endif
  231. X        break;
  232. X     case 'r':
  233. X        reverse = TRUE;
  234. X        break;
  235. X     case 'e':
  236. X        epson_box_chars = TRUE;
  237. X        break;
  238. X     case 'd':
  239. X        database_summary = TRUE;
  240. X        break;
  241. X     case 's':
  242. X        set_output_units (0);
  243. X        break;
  244. X     case 'n':
  245. X        format = NARROW;
  246. X        break;
  247. X     case 'w':
  248. X        format = WIDE;
  249. X        break;
  250. X     case 'b':
  251. X        brief = TRUE;
  252. X        break;
  253. X     case 't':
  254. X        auto_nav1 = FALSE;
  255. X        break;
  256. X     case '\0':
  257. X        if (yyin) {
  258. X           fprintf (stderr, 
  259. X            "ERROR: cannot read from stdin and planfile: \"%s\".\n",
  260. X            argv[i]);
  261. X           usage (argv[0]);
  262. X        } else {
  263. X           yyin = stdin;
  264. X        }
  265. X        break;
  266. X     default:
  267. X        fprintf (stderr, "ERROR: unknown option: \"%s\".\n", argv[i]);
  268. X        usage (argv[0]);
  269. X        break;
  270. X     }
  271. X      } else {
  272. X     if (yyin) {
  273. X        fprintf (stderr, "ERROR: only one planfile allowed: \"%s\".\n",
  274. X             argv[i]);
  275. X        usage (argv[0]);
  276. X     } else {
  277. X        yyin = fopen (argv[i], "r");
  278. X            if (! yyin) {
  279. X           fprintf (stderr, "ERROR: could not open script file: %s.\n", 
  280. X            argv[i]);
  281. X           usage (argv[0]);
  282. X        }
  283. X     }
  284. X      }
  285. X   }
  286. X
  287. X   if (! yyin) {
  288. X      fprintf (stderr, "ERROR: no planfile\n");
  289. X      usage (argv[0]);
  290. X   }
  291. X   init (brief);
  292. X
  293. X   if (! parse_script ())
  294. X      exit (EXIT_BAD);
  295. X
  296. X   if (! compute_plan (auto_nav1) )
  297. X      exit (EXIT_BAD);
  298. X
  299. X   if (reverse) {
  300. X      print_reverse ();
  301. X#ifdef GFX_SUNVIEW
  302. X   } else if (draw_sunview) {
  303. X      sv_draw (brief);
  304. X#endif
  305. X#ifdef GFX_X
  306. X   } else if (draw_x) {
  307. X      x_draw (brief);
  308. X#endif
  309. X#ifdef GFX_POSTSCRIPT
  310. X   } else if (draw_postscript) {
  311. X      ps_draw (brief);
  312. X#endif
  313. X   } else {
  314. X      if (format == NARROW)
  315. X     max_nav = -1;
  316. X      else if (auto_nav1)
  317. X     max_nav = MAX (0, max_nav);
  318. X      set_format (max_nav, epson_box_chars);
  319. X      
  320. X      print_plan ();
  321. X
  322. X      if (database_summary)
  323. X     put_db_summary (stdout);
  324. X   }
  325. X
  326. X   if (! close_dbs ())
  327. X      exit (EXIT_BAD);
  328. X}
  329. X
  330. X
  331. X/*----------------------------------------------------------------------------*/
  332. Xint yyerror(s)
  333. Xchar* s;
  334. X{
  335. X   extern int yylineno;
  336. X
  337. X   fprintf (stderr, "ERROR: line %d: %s\n", yylineno, s);
  338. X   exit (EXIT_BAD);
  339. X}
  340. X
  341. X/*----------------------------------------------------------------------------*/
  342. Xint yywrap ()
  343. X{
  344. X   return (1);
  345. X}
  346. X
  347. X/*----------------------------------------------------------------------------*/
  348. Xint yyreject ()
  349. X{
  350. X   printf ("ERROR: parser rejecting %s\n", yytext);
  351. X   return (1);
  352. X}
  353. X
  354. SHAR_EOF
  355. chmod 0444 main.c || echo "restore of main.c fails"
  356. echo "x - extracting misc.c (Text)"
  357. sed 's/^X//' << 'SHAR_EOF' > misc.c &&
  358. X/*
  359. X * $Id: misc.c,v 2.3 89/11/05 11:23:46 tynor Exp $
  360. X *----------------------------------------------------------------------------
  361. X *    FPLAN - Flight Planner
  362. X *    Steve Tynor
  363. X *    tynor@prism.gatech.edu
  364. X *
  365. X *    This program is in the public domain. Permission to copy,
  366. X * distribute, modify this program is hearby given as long as this header
  367. X * remains. If you redistribute this program after modifying it, please
  368. X * document your changes so that I do not take the blame (or credit) for
  369. X * those changes.  If you fix bugs or add features, please send me a
  370. X * patch so that I can keep the 'official' version up-to-date.
  371. X *
  372. X *    Bug reports are welcome and I'll make an attempt to fix those
  373. X * that are reported.
  374. X *
  375. X *    USE AT YOUR OWN RISK! I assume no responsibility for any
  376. X * errors in this program, its database or documentation. I will make an
  377. X * effort to fix bugs, but if you crash and burn because, for example,
  378. X * fuel estimates in this program were inaccurate, it's your own fault
  379. X * for trusting somebody else's code! Remember, as PIC, it's _your_
  380. X * responsibility to do complete preflight planning. Use this program as
  381. X * a flight planning aid, but verify its results before using them.
  382. X *----------------------------------------------------------------------------
  383. X */
  384. X
  385. Xstatic char rcsid[] = "$Id: misc.c,v 2.3 89/11/05 11:23:46 tynor Exp $";
  386. X
  387. X#include <math.h>
  388. X
  389. X/*----------------------------------------------------------------------------*/
  390. Xdouble degrees_mins_2_decimal (hm)
  391. X     double hm;
  392. X{
  393. X   /*
  394. X    * input looks like: 40.45 (40 deg, 45 min), output is 40.75 (40.75 deg)
  395. X    */
  396. X   double i = (double) floor (hm);
  397. X   
  398. X   return (i + (hm - i) / 0.6);
  399. X}
  400. X
  401. X/*----------------------------------------------------------------------------*/
  402. Xdouble decimal_2_degrees_mins (dec)
  403. X     double dec;
  404. X{
  405. X   /*
  406. X    * input looks like: 40.75 (40.75 deg), output is 40 and 45 (40 deg, 45 min)
  407. X    */
  408. X   double tmp = (double) floor (dec);
  409. X
  410. X   return (tmp + 0.6 * (dec - tmp));
  411. X}
  412. X
  413. SHAR_EOF
  414. chmod 0444 misc.c || echo "restore of misc.c fails"
  415. echo "x - extracting db.c (Text)"
  416. sed 's/^X//' << 'SHAR_EOF' > db.c &&
  417. X/*
  418. X * $Id: db.c,v 2.9 89/11/11 19:09:34 tynor Exp $
  419. X *----------------------------------------------------------------------------
  420. X *    FPLAN - Flight Planner
  421. X *    Steve Tynor
  422. X *    tynor@prism.gatech.edu
  423. X *
  424. X *    This program is in the public domain. Permission to copy,
  425. X * distribute, modify this program is hearby given as long as this header
  426. X * remains. If you redistribute this program after modifying it, please
  427. X * document your changes so that I do not take the blame (or credit) for
  428. X * those changes.  If you fix bugs or add features, please send me a
  429. X * patch so that I can keep the 'official' version up-to-date.
  430. X *
  431. X *    Bug reports are welcome and I'll make an attempt to fix those
  432. X * that are reported.
  433. X *
  434. X *    USE AT YOUR OWN RISK! I assume no responsibility for any
  435. X * errors in this program, its database or documentation. I will make an
  436. X * effort to fix bugs, but if you crash and burn because, for example,
  437. X * fuel estimates in this program were inaccurate, it's your own fault
  438. X * for trusting somebody else's code! Remember, as PIC, it's _your_
  439. X * responsibility to do complete preflight planning. Use this program as
  440. X * a flight planning aid, but verify its results before using them.
  441. X *----------------------------------------------------------------------------
  442. X */
  443. X
  444. X#include "mystring.h"
  445. X#include <stdio.h>
  446. X#include <ctype.h>
  447. X#include "wp_info.h"
  448. X
  449. Xextern char *malloc();
  450. Xextern char *getenv();
  451. Xextern int qsort();
  452. X
  453. Xstatic char rcsid[] = "$Id: db.c,v 2.9 89/11/11 19:09:34 tynor Exp $";
  454. X
  455. X/*
  456. X * the database file pointers:
  457. X */
  458. X
  459. Xtypedef struct {
  460. X   FILE  *fp;
  461. X   long  rec_size;
  462. X   long  num_recs;
  463. X} DB_FILE;
  464. X
  465. X
  466. XDB_FILE pub_airports, pvt_airports, pub_vors, pvt_vors;
  467. X
  468. X/*
  469. X * environment variables for where the databases are:
  470. X */
  471. X#define HOME         "HOME"
  472. X#define NAV_PUBLIC    "NAV"
  473. X#define NAV_PRIVATE    "NAV_PRIVATE"
  474. X
  475. X#ifndef DEFAULT_PVT_DIRECTORY
  476. X#ifdef MSDOS
  477. X#define DEFAULT_PVT_DIRECTORY    "\\flight"
  478. X#else
  479. X#define DEFAULT_PVT_DIRECTORY    "~/preflight"
  480. X#endif
  481. X#endif
  482. X
  483. X#ifndef DEFAULT_PUB_DIRECTORY
  484. X#ifdef MSDOS
  485. X#define DEFAULT_PUB_DIRECTORY    "\\lib\\flight"
  486. X#else
  487. X#define DEFAULT_PUB_DIRECTORY    "/usr/local/lib/preflight"
  488. X#endif
  489. X#endif
  490. X
  491. X#ifdef MSDOS
  492. X#define AIRPORTS_NAME "\\airports.nav"
  493. X#define VORS_NAME     "\\vors.nav"
  494. X#else
  495. X#define AIRPORTS_NAME "/airports.nav"
  496. X#define VORS_NAME     "/vors.nav"
  497. X#endif
  498. X
  499. X#define FSEEK_FROM_BEGINNING 0
  500. X#define FSEEK_FROM_CURRENT   1
  501. X#define FSEEK_FROM_END       2
  502. X
  503. X/*----------------------------------------------------------------------------*/
  504. Xstatic long get_rec_size (buffer)
  505. Xchar *buffer;
  506. X{
  507. X   long i;
  508. X
  509. X   for (i = 0;; i++) {
  510. X      if (buffer[i] == '\n') {
  511. X     return (i + 1L);
  512. X      }
  513. X   }
  514. X}
  515. X
  516. X/*----------------------------------------------------------------------------*/
  517. Xstatic long get_num_recs (rec_size, fp, filename)
  518. X     long  rec_size;
  519. X     FILE **fp;
  520. X     char *filename;
  521. X{
  522. X   long file_size;
  523. X
  524. X   if (fseek (*fp, 0L, FSEEK_FROM_END)) {
  525. X      fprintf (stderr, "ERROR: could not seek in db file: %s\n", filename);
  526. X      *fp = NULL;
  527. X      return (0L);
  528. X   }
  529. X   file_size = ftell (*fp);
  530. X
  531. X#ifndef MSDOS
  532. X   /*
  533. X    * can't figure out why MSC doesn't do this properly - maybe it's an 
  534. X    * inconsistency in the way fseek works? For now, just assume that 
  535. X    * database is in the proper format.
  536. X    */
  537. X   if ((file_size % rec_size) != 0L) {
  538. X      fprintf (stderr, 
  539. X           "ERROR: file size (%ld/%ld) inconsistency in db file: %s\n", 
  540. X           file_size, rec_size, filename);
  541. X      *fp = NULL;
  542. X      return (0L);
  543. X   }
  544. X#endif
  545. X   return (file_size / rec_size);
  546. X}
  547. X
  548. X/*----------------------------------------------------------------------------*/
  549. XBOOLEAN open_dbs ()
  550. X{
  551. X   char *pub_dir, *pvt_dir;
  552. X   BOOLEAN ok;
  553. X
  554. X#define BUFSIZE 200
  555. X   char filename[BUFSIZE];
  556. X   char buffer[BUFSIZE];
  557. X
  558. X#ifdef MSDOS
  559. X#define OPEN_MODE "rb"
  560. X#else
  561. X#define OPEN_MODE "r"
  562. X#endif
  563. X
  564. X   if (! (pub_dir = getenv (NAV_PUBLIC)))
  565. X      pub_dir = DEFAULT_PUB_DIRECTORY;
  566. X
  567. X   if (! (pvt_dir = getenv (NAV_PRIVATE)))
  568. X      pvt_dir = DEFAULT_PVT_DIRECTORY;
  569. X
  570. X#ifndef MSDOS
  571. X   if (pvt_dir[0] == '~') {
  572. X      strcpy (filename, getenv (HOME));
  573. X      strcat (filename, &pvt_dir[1]);
  574. X      pvt_dir = strdup (filename);
  575. X   }
  576. X#endif
  577. X
  578. X   strcpy (filename, pub_dir);
  579. X   strcat (filename, AIRPORTS_NAME);
  580. X   if (pub_airports.fp = fopen (filename, OPEN_MODE)) {
  581. X      fgets (buffer, BUFSIZE, pub_airports.fp);
  582. X      pub_airports.rec_size = get_rec_size (buffer);
  583. X      pub_airports.num_recs = get_num_recs (pub_airports.rec_size,
  584. X                        &pub_airports.fp, filename);
  585. X   }
  586. X
  587. X   strcpy (filename, pvt_dir);
  588. X   strcat (filename, AIRPORTS_NAME);
  589. X   if (pvt_airports.fp = fopen (filename, OPEN_MODE)) {
  590. X      fgets (buffer, BUFSIZE, pvt_airports.fp);
  591. X      pvt_airports.rec_size = get_rec_size (buffer);
  592. X      pvt_airports.num_recs = get_num_recs (pvt_airports.rec_size,
  593. X                        &pvt_airports.fp, filename);
  594. X   }
  595. X
  596. X   strcpy (filename, pub_dir);
  597. X   strcat (filename, VORS_NAME);
  598. X   if (pub_vors.fp = fopen (filename, OPEN_MODE)) {
  599. X      fgets (buffer, BUFSIZE, pub_vors.fp);
  600. X      pub_vors.rec_size = get_rec_size (buffer);
  601. X      pub_vors.num_recs = get_num_recs (pub_vors.rec_size,
  602. X                    &pub_vors.fp, filename);
  603. X   }
  604. X
  605. X   strcpy (filename, pvt_dir);
  606. X   strcat (filename, VORS_NAME);
  607. X   if (pvt_vors.fp = fopen (filename, OPEN_MODE)) {
  608. X      fgets (buffer, BUFSIZE, pvt_vors.fp);
  609. X      pvt_vors.rec_size = get_rec_size (buffer);
  610. X      pvt_vors.num_recs = get_num_recs (pvt_vors.rec_size,
  611. X                    &pvt_vors.fp, filename);
  612. X   }
  613. X   ok = TRUE;
  614. X
  615. X   if (!pub_airports.fp && !pvt_airports.fp) {
  616. X      ok = FALSE;
  617. X      fprintf (stderr, "ERROR: neither public or private airports db found\n");
  618. X   }
  619. X   if (!pub_vors.fp && !pvt_vors.fp) {
  620. X      ok = FALSE;
  621. X      fprintf (stderr, "ERROR: neither public or private vors db found\n");
  622. X   }
  623. X   return (ok);
  624. X}
  625. X
  626. X/*----------------------------------------------------------------------------*/
  627. XBOOLEAN close_dbs ()
  628. X{
  629. X   if (pub_airports.fp)
  630. X      fclose (pub_airports.fp);
  631. X   if (pvt_airports.fp)
  632. X      fclose (pvt_airports.fp);
  633. X   if (pub_vors.fp)
  634. X      fclose (pub_vors.fp);
  635. X   if (pvt_vors.fp)
  636. X      fclose (pvt_vors.fp);
  637. X
  638. X   return (TRUE);
  639. X}
  640. X
  641. X
  642. X/*----------------------------------------------------------------------------*/
  643. Xstatic BOOLEAN lookup_desig_internal (db, desig, buffer_size, buffer)
  644. X     DB_FILE db;
  645. X     char *desig;
  646. X     int  buffer_size;
  647. X     char *buffer;
  648. X{
  649. X   long low, high, mid;
  650. X   int  cmp;
  651. X   if (! db.fp) 
  652. X      return FALSE;
  653. X
  654. X#ifdef NO_BINARY_SEARCH
  655. X   rewind (db.fp);   
  656. X   while (fgets (buffer, buffer_size, db.fp)) {
  657. X      if (!strcmp (desig, strtok (buffer, ":\n")))
  658. X     return TRUE;
  659. X   }
  660. X   return FALSE;
  661. X#else
  662. X   low = 0L;
  663. X   high = db.num_recs;
  664. X   while (low <= high) {
  665. X      mid = (low + high) / 2L;
  666. X      fseek (db.fp, mid * db.rec_size, FSEEK_FROM_BEGINNING);
  667. X      fgets (buffer, buffer_size, db.fp);
  668. X      cmp =strcmp (desig, strtok (buffer, ":\n"));
  669. X      if (!cmp)
  670. X     return TRUE;
  671. X      else if (cmp > 0)
  672. X     low = mid + 1;
  673. X      else
  674. X     high = mid - 1;
  675. X   }
  676. X   return FALSE;
  677. X#endif
  678. X}
  679. X
  680. X/*----------------------------------------------------------------------------*/
  681. Xstatic void decode_common (db)
  682. X     DATABASE_INFO *db;
  683. X{
  684. X   extern double atof ();
  685. X   extern double degrees_mins_2_decimal ();
  686. X   double d1, d2;
  687. X
  688. X   db->altitude.value =  atof (strtok ((char*)0, ":\n"));
  689. X   db->altitude.valid = TRUE;
  690. X
  691. X   d1 = atof (strtok ((char*)0, ":\n"));
  692. X   d2 = atof (strtok ((char*)0, ":\n"));
  693. X   db->mag_variation = d1 + d2 / 60.0;
  694. X
  695. X   d1 = atof (strtok ((char*)0, ":\n"));
  696. X   d2 = atof (strtok ((char*)0, ":\n"));
  697. X   db->latitude = d1 + d2 / 60.0;
  698. X
  699. X   d1 = atof (strtok ((char*)0, ":\n"));
  700. X   d2 = atof (strtok ((char*)0, ":\n"));
  701. X   db->longitude = d1 + d2 / 60.0;
  702. X}
  703. X
  704. X/*----------------------------------------------------------------------------*/
  705. Xstatic void decode_vor (db)
  706. X     DATABASE_INFO *db;
  707. X{
  708. X   char *tok;
  709. X
  710. X   db->name = strdup (strtok ((char*)0, ":\n"));
  711. X
  712. X   tok = strdup (strtok ((char*)0, ":\n"));   
  713. X   if (tok[0] != '\0') {
  714. X      db->freq.valid = TRUE;
  715. X      db->freq.value = atof (tok);
  716. X   } else
  717. X      db->freq.valid = FALSE;
  718. X
  719. X   decode_common (db);
  720. X
  721. X   tok = strtok ((char*)0, ":\n");
  722. X   if (!strcmp ("NDB", tok))
  723. X      db->mode = WP_NDB;
  724. X   else if (!strcmp ("VOR", tok))
  725. X      db->mode = WP_VOR;
  726. X   else if (!strcmp ("DME", tok))
  727. X      db->mode = WP_DME;
  728. X   else if (!strcmp ("TAC", tok))
  729. X      db->mode = WP_TAC;
  730. X   else if (!strcmp ("ILS", tok))
  731. X      db->mode = WP_ILS;
  732. X   else if (!strcmp ("INT", tok))
  733. X      db->mode = WP_NAMED_INTERSECTION;
  734. X   else if (!strcmp ("WPT", tok))
  735. X      db->mode = WP_WPT;
  736. X   else if (!strcmp ("LOM", tok))
  737. X      db->mode = WP_LOM;
  738. X   else if (!strcmp ("LMM", tok))
  739. X      db->mode = WP_LMM;
  740. X   else 
  741. X      db->mode = WP_UNK;
  742. X
  743. X   tok = strtok ((char*)0, ":\n");   
  744. X   if (tok)
  745. X      db->comment = strdup (tok);
  746. X   else
  747. X      db->comment = NULL;
  748. X}
  749. X
  750. X/*----------------------------------------------------------------------------*/
  751. Xstatic void decode_airport (db)
  752. X     DATABASE_INFO *db;
  753. X{
  754. X   char *tok;
  755. X
  756. X   db->mode = WP_AIRPORT;
  757. X   db->city = strdup (strtok ((char*)0, ":\n"));   
  758. X   db->name = strdup (strtok ((char*)0, ":\n"));   
  759. X
  760. X   decode_common (db);
  761. X
  762. X   tok = strdup (strtok ((char*)0, ":\n"));   
  763. X
  764. X   if (tok[0] != '\0') {
  765. X      db->freq.valid = TRUE;
  766. X      db->freq.value = atof (tok);
  767. X   } else
  768. X      db->freq.valid = FALSE;
  769. X
  770. X   tok = strtok ((char*)0, ":\n");   
  771. X   if (tok)
  772. X      db->comment = strdup (tok);
  773. X   else
  774. X      db->comment = NULL;
  775. X}
  776. X
  777. X/*----------------------------------------------------------------------------*/
  778. Xstatic void str_upcase (str)
  779. X     char *str;
  780. X{
  781. X   int i;
  782. X
  783. X   for (i = 0; str[i] != '\0'; i++)
  784. X      if (islower (str[i]))
  785. X      str[i] = toupper (str[i]);
  786. X}
  787. X
  788. X/*----------------------------------------------------------------------------*/
  789. Xstatic BOOLEAN in_cache (mode, desig)
  790. X     WAYPOINT_MODE mode;
  791. X     char *desig;
  792. X{
  793. X   int i;
  794. X
  795. X   for (i = 0; i < num_cached; i++) {
  796. X      if ((!strcmp (desig, cache[i]->desig)) && 
  797. X      (mode == cache[i]->mode)) {
  798. X     return TRUE;
  799. X      }
  800. X   }
  801. X   return FALSE;
  802. X}
  803. X
  804. X/*----------------------------------------------------------------------------*/
  805. XBOOLEAN lookup_desig (kind, desig, db)
  806. X     WAYPOINT_KIND kind;
  807. X     char          *desig;
  808. X     DATABASE_INFO **db;
  809. X{
  810. X#undef BUFSIZE
  811. X#define BUFSIZE 200
  812. X   char buffer [BUFSIZE];
  813. X   DB_FILE fps[4];
  814. X   int i;
  815. X   BOOLEAN found;
  816. X   extern yyerror();
  817. X   enum {VOR, AIRPORT} db_kind;
  818. X
  819. X   str_upcase (desig);
  820. X
  821. X   if (kind == WP_VIA) {
  822. X      /* 
  823. X       * prefer the VOR databases
  824. X       */
  825. X      fps[0] = pvt_vors;
  826. X      fps[1] = pub_vors;
  827. X      fps[2] = pvt_airports;
  828. X      fps[3] = pub_airports;
  829. X   } else {
  830. X      /* 
  831. X       * prefer the AIRPORT databases 
  832. X       */
  833. X      fps[0] = pvt_airports;
  834. X      fps[1] = pub_airports;
  835. X      fps[2] = pvt_vors;
  836. X      fps[3] = pub_vors;
  837. X   }
  838. X
  839. X   for (i = 0; i < 4; i++) {
  840. X      if (found = lookup_desig_internal (fps[i], desig, BUFSIZE, buffer)) {
  841. X#if 0
  842. X     printf ("%s found w/db %d[%ld] (%s)\n",desig,i,fps[i].fp,
  843. X         ((fps[i].fp == pub_airports.fp) ||
  844. X          (fps[i].fp == pvt_airports.fp)) ? "APT" : "VOR");
  845. X#endif
  846. X     if ((fps[i].fp == pub_airports.fp) || (fps[i].fp == pvt_airports.fp))
  847. X        db_kind = AIRPORT;
  848. X     else
  849. X        db_kind = VOR;
  850. X     break;
  851. X      }
  852. X   }
  853. X   if (! found) {
  854. X      fprintf (stderr, "ERROR: could not find %s in any database\n", desig);
  855. X      return FALSE;
  856. X   }
  857. X
  858. X   /*
  859. X    * now, convert it into a db record...
  860. X    */
  861. X
  862. X   *db = (DATABASE_INFO*) malloc (sizeof (DATABASE_INFO));
  863. X   if (! *db)
  864. X      yyerror ("unable to allocate space for database element");
  865. X
  866. X   (*db)->desig = desig;    /* no need to strdup - the parser already did */
  867. X
  868. X   if (db_kind == VOR)
  869. X      decode_vor (*db);
  870. X   else
  871. X      decode_airport (*db);
  872. X
  873. X   /*
  874. X    * append to the cache: (NOTE: it might already be there if we didn't grab
  875. X    * it out of the cach because of incompatible modes - e.g. the cached wp is
  876. X    * an airport, but this is a via node - we forced a recheck in case there was
  877. X    * a navaid with the same desig)
  878. X    */
  879. X   if (num_cached < CACHE_SIZE)
  880. X      if (! in_cache ((*db)->mode, desig)) {
  881. X     cache[num_cached++] = *db;
  882. X      }
  883. X   return TRUE;
  884. X}
  885. X
  886. X/*----------------------------------------------------------------------------*/
  887. Xstatic int dbcmp (db1, db2)
  888. X     DATABASE_INFO **db1, **db2;
  889. X{
  890. X   return (strcmp ((*db1)->desig, (*db2)->desig));
  891. X}
  892. X
  893. X/*----------------------------------------------------------------------------*/
  894. Xvoid put_db_summary (out_fp)
  895. X     FILE *out_fp;
  896. X{
  897. X   int i;
  898. X
  899. X   /*
  900. X    * first, sort the cache 
  901. X    */
  902. X   qsort ((char*) &cache[0], num_cached, sizeof(DATABASE_INFO*), dbcmp);
  903. X
  904. X   /*
  905. X    * now, print it out.
  906. X    */
  907. X   fprintf (out_fp, "\f\n");
  908. X   for (i = 0; i < num_cached; i++)
  909. X      put_db (out_fp, cache[i]);
  910. X}
  911. X
  912. X
  913. X/*----------------------------------------------------------------------------*/
  914. Xvoid min_max_lat_long (min_lat, max_lat, min_long, max_long)
  915. X     double *min_lat, *max_lat, *min_long, *max_long;
  916. X{
  917. X   int i;
  918. X
  919. X   *min_lat  =  190.0;
  920. X   *max_lat  = -190.0;
  921. X   *min_long =  190.0;
  922. X   *max_long = -190.0;
  923. X
  924. X   for (i = 0; i < num_cached; i++) {
  925. X      *min_lat = MIN (cache[i]->latitude, *min_lat);
  926. X      *max_lat = MAX (cache[i]->latitude, *max_lat);
  927. X      *min_long = MIN (cache[i]->longitude, *min_long);
  928. X      *max_long = MAX (cache[i]->longitude, *max_long);
  929. X   }
  930. X}
  931. SHAR_EOF
  932. chmod 0444 db.c || echo "restore of db.c fails"
  933. echo "x - extracting strings.c (Text)"
  934. sed 's/^X//' << 'SHAR_EOF' > strings.c &&
  935. X/*
  936. X * $Id: strings.c,v 1.7 89/11/11 19:13:40 tynor Exp $
  937. X *----------------------------------------------------------------------------
  938. X *    FPLAN - Flight Planner
  939. X *    Steve Tynor
  940. X *    tynor@prism.gatech.edu
  941. X *
  942. X *    This program is in the public domain. Permission to copy,
  943. X * distribute, modify this program is hearby given as long as this header
  944. X * remains. If you redistribute this program after modifying it, please
  945. X * document your changes so that I do not take the blame (or credit) for
  946. X * those changes.  If you fix bugs or add features, please send me a
  947. X * patch so that I can keep the 'official' version up-to-date.
  948. X *
  949. X *    Bug reports are welcome and I'll make an attempt to fix those
  950. X * that are reported.
  951. X *
  952. X *    USE AT YOUR OWN RISK! I assume no responsibility for any
  953. X * errors in this program, its database or documentation. I will make an
  954. X * effort to fix bugs, but if you crash and burn because, for example,
  955. X * fuel estimates in this program were inaccurate, it's your own fault
  956. X * for trusting somebody else's code! Remember, as PIC, it's _your_
  957. X * responsibility to do complete preflight planning. Use this program as
  958. X * a flight planning aid, but verify its results before using them.
  959. X *----------------------------------------------------------------------------
  960. X */
  961. X
  962. Xstatic char rcsid[] = "$Id: strings.c,v 1.7 89/11/11 19:13:40 tynor Exp $";
  963. X
  964. X#include "mystring.h"
  965. X#include "wp_info.h"
  966. X#include "math.h"
  967. X
  968. Xextern char* malloc();
  969. X
  970. X/*
  971. X * define a couple of functions that are in SunOS string(3), but apparently
  972. X * aren't 'standard' - so much for the wonder of the portability of the 
  973. X * standard C library...
  974. X *
  975. X * The only thing we count on is strlen().
  976. X */
  977. X
  978. X/*---------------------------------------------------------------------------*/
  979. Xchar* index (s, c)
  980. X     char *s, c;
  981. X{
  982. X   char *p;
  983. X   for (p = s; *p; p++)
  984. X      if (*p == c)
  985. X     return p;
  986. X   if (!c)
  987. X      return p;
  988. X   else
  989. X      return (char*) 0;
  990. X}
  991. X
  992. X/*---------------------------------------------------------------------------*/
  993. Xchar* strdup (s)
  994. X     char *s;
  995. X{
  996. X   int len = strlen (s);
  997. X   char *new = (char*) malloc (len + 1);
  998. X
  999. X   if (new)
  1000. X      strcpy (new, s);
  1001. X   return (new);
  1002. X}
  1003. X
  1004. Xstatic char *buffer;
  1005. Xstatic int  start;
  1006. Xstatic int  buf_len;
  1007. X
  1008. X/*---------------------------------------------------------------------------*/
  1009. Xchar *strtok (str, separators)
  1010. X     char *str;
  1011. X     char *separators;
  1012. X{
  1013. X   int i, k;
  1014. X   int len = strlen (separators);
  1015. X   char *ptr;
  1016. X
  1017. X   if (str) {
  1018. X      buf_len = strlen (str);
  1019. X      buffer = str;
  1020. X      start = 0;
  1021. X   }
  1022. X   if (start > buf_len) {
  1023. X      return (char*) 0;
  1024. X   }
  1025. X   for (i = 0; i <= len; i++) {
  1026. X      /*
  1027. X       * notice we cheat and use the '\0' terminator in the separators string 
  1028. X       * to always recognize '\0' as a separator.
  1029. X       */
  1030. X      if (ptr = index (&buffer[start], separators[i])) {
  1031. X     *ptr = '\0';
  1032. X     k = start;
  1033. X     start = (int) (ptr - buffer + 1);
  1034. X     return (&buffer[k]);
  1035. X      }
  1036. X   }
  1037. X   return (char*) 0;
  1038. X}
  1039. X
  1040. SHAR_EOF
  1041. chmod 0444 strings.c || echo "restore of strings.c fails"
  1042. exit 0
  1043.  
  1044.