home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume9 / fplan / part04 < prev    next >
Text File  |  1989-11-26  |  23KB  |  804 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v09i014: FPLAN 4/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 14
  7. Submitted-by: tynor@prism.gatech.edu (Steve Tynor)
  8. Archive-name: fplan/part04
  9.  
  10. #This is part 4/6 of FPLAN
  11. #!/bin/sh
  12. # shar:    Shell Archiver  (v1.22)
  13. #    Packed Mon Nov 20 19:28:39 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. #      output.c
  18. #
  19. echo "x - extracting output.c (Text)"
  20. sed 's/^X//' << 'SHAR_EOF' > output.c &&
  21. X/*
  22. X * $Id: output.c,v 2.10 89/11/11 19:09:29 tynor Exp $
  23. X *----------------------------------------------------------------------------
  24. X *    FPLAN - Flight Planner
  25. X *    Steve Tynor
  26. X *    tynor@prism.gatech.edu
  27. X *
  28. X *    This program is in the public domain. Permission to copy,
  29. X * distribute, modify this program is hearby given as long as this header
  30. X * remains. If you redistribute this program after modifying it, please
  31. X * document your changes so that I do not take the blame (or credit) for
  32. X * those changes.  If you fix bugs or add features, please send me a
  33. X * patch so that I can keep the 'official' version up-to-date.
  34. X *
  35. X *    Bug reports are welcome and I'll make an attempt to fix those
  36. X * that are reported.
  37. X *
  38. X *    USE AT YOUR OWN RISK! I assume no responsibility for any
  39. X * errors in this program, its database or documentation. I will make an
  40. X * effort to fix bugs, but if you crash and burn because, for example,
  41. X * fuel estimates in this program were inaccurate, it's your own fault
  42. X * for trusting somebody else's code! Remember, as PIC, it's _your_
  43. X * responsibility to do complete preflight planning. Use this program as
  44. X * a flight planning aid, but verify its results before using them.
  45. X *----------------------------------------------------------------------------
  46. X */
  47. X
  48. Xstatic char rcsid[] = "$Id: output.c,v 2.10 89/11/11 19:09:29 tynor Exp $";
  49. X
  50. X#include <math.h>
  51. X#include <stdio.h>
  52. X#include "mystring.h"
  53. X#include "wp_info.h"
  54. X
  55. Xextern double decimal_2_degrees_mins();
  56. X
  57. Xtypedef enum {
  58. X   END_OF_FORMAT,    /* we count on ((int)END_OF_FORMAT == 0) */
  59. X   CITY, NAME, COMMENT, ELEV, FREQ, TYPE, DESIG, 
  60. X   TC, MC, MH, WIND, DIST_LEG, DIST, DIST_REMAIN,
  61. X   ETA_LEG, ETA, ATA, FUEL_AMT, FUEL_RATE, FUEL_LEG, ALT,
  62. X   TAS, EGS, AGS, VOR_DESIG, VOR_FREQ, VOR_RADIAL, LAT_LONG, VOR_DME,
  63. X   IGNORE, EMPTY, FORWARD_ARROW, BACKWARD_ARROW, 
  64. X   SEPARATOR, BAR, CROSS, EOL, END_OF_VOR,
  65. X   } FORMAT_KIND;
  66. X
  67. Xchar *headers[] = 
  68. X{
  69. X   "", "CITY", "CHECKPOINT", "COMMENT", "ELEV", "FREQ", "TYPE", "DESIG", 
  70. X   "TC", "MC", "MH", "WIND", "DIST", "DIS", "REM",
  71. X   "ETE", "ETE", "ATE", "FUEL", "RATE", "FUEL", "ALT",
  72. X   "TAS", "EGS", "AGS", "VOR", "FREQ", "RAD", "LAT/LONG", "DME", "", "",
  73. X};
  74. X
  75. Xtypedef enum {R, L} JUSTIFICATION;
  76. X
  77. Xtypedef enum {U,S} UNSHIFTED_OR_SHIFTED;
  78. X
  79. Xtypedef struct {
  80. X   FORMAT_KIND         kind;
  81. X   int             field_width;
  82. X   JUSTIFICATION     justification;
  83. X   int             arg;    /* which_vor or num_decimal_points */
  84. X   UNSHIFTED_OR_SHIFTED    shifted;
  85. X} FORMAT_SPEC_CELL;
  86. X
  87. X/*
  88. X * default format (for narrow output (e.g. to terminals) the VORs are not 
  89. X * output)
  90. X *
  91. X *                                                            VOR1    VOR2
  92. X *+=========//==============+===+=====+                            +=======+
  93. X *|NAME     //    TYPE DESIG|   | FUEL|                            |    VOR|
  94. X *|CITY     //      ALT FREQ|DIS|  ETE|======+===+====+====+=======|   FREQ|
  95. X *|COMMENT  //      LAT/LONG|REM|  ATE|    MC|TAS|DIST| ALT|    VOR|RAD DME|
  96. X *+=========//==============+===+=====>  WIND|EGS| ETE|RATE|   FREQ<-------+
  97. X *|         //              |   |     |    MH|AGS| ATE|FUEL|RAD DME|       |
  98. X *|         //              |   |     |======+===+====+====+=======|       |
  99. X *|         //              |   |     |      |   |    |    |       |       |
  100. X *+---------//--------------+---+----->      |   |    |    |       <-------+
  101. X *|         //              |   |     |      |   |    |    |       |       |
  102. X *|         //              |   |     |------+---+----+----+-------|       |
  103. X */
  104. X
  105. X#define MAX_NUM_FIELDS 170
  106. X
  107. XFORMAT_SPEC_CELL default_format_wide [] = 
  108. X{
  109. X   /* line 0 */
  110. X   /* WAYPOINT INFO */
  111. X   {CROSS},{SEPARATOR,44,L},{CROSS},
  112. X   {SEPARATOR,3}, {CROSS}, {SEPARATOR,5},{FORWARD_ARROW},
  113. X
  114. X   /* LEG INFO */
  115. X   {WIND,6,R,0,S},{BAR,1,R,0,S},{EGS,3,R,0,S},{BAR,1,R,0,S},
  116. X   {ETA_LEG,4,R,0,S},{BAR,1,R,0,S},{FUEL_RATE,5,R,1,S},{BAR,1,R,0,S},
  117. X   {END_OF_VOR,1,R,0,U},{VOR_FREQ,8,R,0,S},{BACKWARD_ARROW,1,R,0,U},
  118. X   /* WAYPOINT INFO */
  119. X   {END_OF_VOR,1,R,1,U},{SEPARATOR,8,R,1,U},{CROSS},
  120. X   {END_OF_VOR,1,R,2,U},{SEPARATOR,8,R,2,U},{CROSS},
  121. X   {END_OF_VOR,1,R,3,U},{SEPARATOR,8,R,3,U},{CROSS},
  122. X   {END_OF_VOR,1,R,4,U},{SEPARATOR,8,R,4,U},{CROSS},
  123. X   {END_OF_VOR,1,R,5,U},{SEPARATOR,8,R,5,U},{CROSS},
  124. X   {END_OF_VOR,1,R,6,U},{SEPARATOR,8,R,6,U},{CROSS},
  125. X   {END_OF_VOR,1,R,7,U},{SEPARATOR,8,R,7,U},{CROSS},
  126. X   {EOL}, 
  127. X
  128. X   /* line 1 */
  129. X   /* WAYPOINT INFO */
  130. X   {BAR},{NAME,32,L},{ELEV,5},{EMPTY,1},{DESIG,6},{BAR},
  131. X   {EMPTY,3}, {BAR}, {FUEL_AMT,5,R,1},{BAR},
  132. X   /* LEG INFO */
  133. X   {MH,6,R,0,S},{BAR,1,R,0,S},{AGS,3,R,0,S},{BAR,1,R,0,S},
  134. X   {ATA,4,R,0,S},{BAR,1,R,0,S},{FUEL_LEG,5,R,1,S},{BAR,1,R,0,S},
  135. X   {VOR_RADIAL,4,L,0,S},
  136. X   {VOR_DME,4,R,0,S},{BAR,1,R,0,U},
  137. X   /* WAYPOINT INFO */
  138. X   {VOR_DESIG,8,R,1,U},{BAR},
  139. X   {VOR_DESIG,8,R,2,U},{BAR},
  140. X   {VOR_DESIG,8,R,3,U},{BAR},
  141. X   {VOR_DESIG,8,R,4,U},{BAR},
  142. X   {VOR_DESIG,8,R,5,U},{BAR},
  143. X   {VOR_DESIG,8,R,6,U},{BAR},
  144. X   {VOR_DESIG,8,R,7,U},{BAR},
  145. X   {EOL}, 
  146. X
  147. X   /* line 2 */
  148. X   /* WAYPOINT INFO */
  149. X   {BAR},{CITY,29,L},{TYPE,8},{EMPTY,1},{FREQ,6},{BAR},
  150. X   {DIST,3}, {BAR},{ETA,5},{BAR},
  151. X   /* LEG INFO */
  152. X   {SEPARATOR,6,R,0,U},{CROSS,1,R,0,U},{SEPARATOR,3,R,0,U},{CROSS,1,R,0,U},
  153. X   {SEPARATOR,4,R,0,U},{CROSS,1,R,0,U},{SEPARATOR,5,R,0,U},{CROSS,1,R,0,U},
  154. X   {END_OF_VOR,1,R,0,U},{SEPARATOR,8,R,0,U},{BAR,1,R,0,U},
  155. X   /* WAYPOINT INFO */
  156. X   {VOR_FREQ,8,R,1,U},{BAR},
  157. X   {VOR_FREQ,8,R,2,U},{BAR},
  158. X   {VOR_FREQ,8,R,3,U},{BAR},
  159. X   {VOR_FREQ,8,R,4,U},{BAR},
  160. X   {VOR_FREQ,8,R,5,U},{BAR},
  161. X   {VOR_FREQ,8,R,6,U},{BAR},
  162. X   {VOR_FREQ,8,R,7,U},{BAR},
  163. X   {EOL}, 
  164. X
  165. X   /* line 3 */
  166. X   /* WAYPOINT INFO */
  167. X   {BAR},{COMMENT,26,L},{LAT_LONG,18},{BAR},
  168. X   {DIST_REMAIN,3}, {BAR},{ATA,5},{BAR},
  169. X   /* LEG INFO */
  170. X   {MC,6,R,0,S},{BAR,1,R,0,S},{TAS,3,R,0,S},{BAR,1,R,0,S},
  171. X   {DIST_LEG,4,R,0,S},{BAR,1,R,0,S},{ALT,5,R,0,S},{BAR,1,R,0,S},
  172. X   {VOR_DESIG,8,R,0,S},{BAR,1,R,0,U},
  173. X   /* WAYPOINT INFO */
  174. X   {VOR_RADIAL,4,L,1,U}, {VOR_DME,4,R,1,U},{BAR},
  175. X   {VOR_RADIAL,4,L,2,U}, {VOR_DME,4,R,2,U},{BAR},
  176. X   {VOR_RADIAL,4,L,3,U}, {VOR_DME,4,R,3,U},{BAR},
  177. X   {VOR_RADIAL,4,L,4,U}, {VOR_DME,4,R,4,U},{BAR},
  178. X   {VOR_RADIAL,4,L,5,U}, {VOR_DME,4,R,5,U},{BAR},
  179. X   {VOR_RADIAL,4,L,6,U}, {VOR_DME,4,R,6,U},{BAR},
  180. X   {VOR_RADIAL,4,L,7,U}, {VOR_DME,4,R,7,U},{BAR},
  181. X   {EOL}, 
  182. X   {END_OF_FORMAT}
  183. X};
  184. X
  185. X#ifdef OLD_FORMAT
  186. X/*
  187. X * Default wide column format:
  188. X *
  189. X+-------------//--------------+------+---+----+-----+-----+-----+-----+
  190. X|NAME         //    TYPE DESIG|    MC|TAS| LEG|  LEG|  ALT|  VOR|  VOR|
  191. X|CITY         //      ALT FREQ|  WIND|EGS|DIST|  ETA| RATE| FREQ| FREQ|
  192. X|COMMENT      //      LAT/LONG|    MH|AGS| REM|  ATA| FUEL|  RAD|  RAD|
  193. X+-------------//--------------+------+---+----+-----+-----+-----+-----+
  194. X *
  195. X * narrow column format is the same - without the last 2 fields
  196. X */
  197. X
  198. XFORMAT_SPEC_CELL default_format_wide [MAX_NUM_FIELDS] = 
  199. X{
  200. X   {BAR},{NAME,33,L},{TYPE,11},{EMPTY,1},{DESIG,6},{BAR},
  201. X   {MC,6},{BAR},{TAS,3},{BAR},
  202. X   {DIST_LEG,4},{BAR},{ETA_LEG,5},{BAR},{ALT,5},{BAR},
  203. X   {VOR_DESIG,6,R,0},{BAR},{VOR_DESIG,6,R,1},{BAR},
  204. X   {EOL}, 
  205. X
  206. X   {BAR},{CITY,33,L},{ELEV,11},{EMPTY,1},{FREQ,6,R,1},{BAR},
  207. X   {WIND,6},{BAR},{EGS,3},{BAR},
  208. X   {DIST,4},{BAR},{ETA,5},{BAR},{FUEL_RATE,5,R,1},{BAR},
  209. X   {VOR_FREQ,6,R,0},{BAR},{VOR_FREQ,6,R,1},{BAR},
  210. X   {EOL},
  211. X
  212. X   {BAR},{COMMENT,33,L},{LAT_LONG,18},
  213. X   {BAR},{MH,6},{BAR},{AGS,3},{BAR},
  214. X   {DIST_REMAIN,4},{BAR},{ATA,5},{BAR},{FUEL_AMT,5,R,1},{BAR},
  215. X   {VOR_RADIAL,6,R,0},{BAR},{VOR_RADIAL,6,R,1},{BAR},
  216. X   {EOL},
  217. X
  218. X   {END_OF_FORMAT}
  219. X};
  220. X#endif
  221. X
  222. XFORMAT_SPEC_CELL output_format [MAX_NUM_FIELDS];
  223. X
  224. Xint line_num;
  225. X
  226. Xenum {NAUTICAL, STATUTE} output_units = NAUTICAL;
  227. X/*
  228. X * the only things affected by the output_format are:
  229. X * speeds (TAS, GS) and distance (DIST, DIST_LEG, DIST_REMAIN)
  230. X * All are internally stored as knots and km.
  231. X */
  232. X#define NM_OR_MI(a) ((output_units == NAUTICAL) ? (a) : (a) * MI_PER_NM)
  233. X
  234. X#define EPSON_CROSS        197
  235. X#define EPSON_VERTICAL_BAR    179
  236. X#define EPSON_HORIZONTAL_BAR    196
  237. X#define EPSON_FORWARD_ARROW    180
  238. X#define EPSON_BACKWARD_ARROW    195
  239. Xstatic BOOLEAN use_epson_box_chars = FALSE;
  240. X
  241. X/*----------------------------------------------------------------------------*/
  242. Xvoid set_output_units (nautical)
  243. X     int nautical;
  244. X{
  245. X   if (nautical)
  246. X      output_units = NAUTICAL;
  247. X   else
  248. X      output_units = STATUTE;
  249. X}
  250. X
  251. X/*----------------------------------------------------------------------------*/
  252. Xvoid set_format (max_nav, epson)
  253. X     int max_nav;
  254. X     BOOLEAN epson;
  255. X{
  256. X   int i;
  257. X   FORMAT_SPEC_CELL *spec = default_format_wide;
  258. X
  259. X   use_epson_box_chars = epson;
  260. X   for (i = 0; i < MAX_NUM_FIELDS; i++) {
  261. X      if (((spec[i].kind == END_OF_VOR) ||
  262. X       (spec[i].kind == VOR_DESIG) ||
  263. X       (spec[i].kind == VOR_FREQ) ||
  264. X       (spec[i].kind == VOR_DME) ||
  265. X       (spec[i].kind == VOR_RADIAL))
  266. X      && 
  267. X      (max_nav < spec[i].arg)) {
  268. X     for (; (spec[i].kind != EOL) && (i < MAX_NUM_FIELDS); i++) {
  269. X        output_format[i].kind = IGNORE;
  270. X     }
  271. X     i--;
  272. X      } else {
  273. X     output_format[i] = spec[i];
  274. X      }
  275. X   }
  276. X#if 0
  277. X   output_format[i] = spec[i];
  278. X#endif
  279. X}
  280. X
  281. X/*----------------------------------------------------------------------------*/
  282. Xstatic void put_time (out_fp, field_width, hours)
  283. X     FILE   *out_fp;
  284. X     int    field_width;
  285. X     double hours;
  286. X{
  287. X   char   buffer[30];
  288. X   int    h       = (int) hours;
  289. X   double minutes = hours * 60.0;
  290. X
  291. X   if (h > 0) {
  292. X      sprintf (buffer, "%d:%02.0f", h, minutes - h * 60.0);
  293. X      fprintf (out_fp, "%*s", field_width, buffer);
  294. X   } else {
  295. X      fprintf (out_fp, "%*.0f", field_width, minutes);
  296. X   }
  297. X}
  298. X/*----------------------------------------------------------------------------*/
  299. Xstatic void put_string (out_fp, fw, str)
  300. XFILE *out_fp;
  301. Xint fw;
  302. Xchar *str;
  303. X{
  304. X   /*
  305. X    * force a string to fit in the specified field width. if we have to 
  306. X    * truncate, then indicate the truncation with a '>' in the last position
  307. X    */
  308. X
  309. X   char buffer[100];
  310. X
  311. X   strncpy (buffer, str, ABS (fw));
  312. X   if (strlen (str) > ABS(fw))
  313. X      buffer[ABS (fw)-1] = '>';
  314. X   buffer[ABS (fw)] = '\0';
  315. X#ifdef MSDOS
  316. X   /* 
  317. X    * both the Microsoft and Zortech compilers generate incorrect output for
  318. X    * negative field widths.
  319. X    */
  320. X   {
  321. X      int i;
  322. X      int xtra = ABS(fw) - strlen (buffer);
  323. X      
  324. X      if (fw > 0)
  325. X     for (i = 0; i < xtra; i++)
  326. X        fprintf (out_fp, " ");
  327. X      fprintf (out_fp, "%s", buffer);
  328. X      if (fw < 0)
  329. X     for (i = 0; i < xtra; i++)
  330. X        fprintf (out_fp, " ");
  331. X   }
  332. X#else
  333. X   fprintf (out_fp, "%*s", fw, buffer);
  334. X#endif
  335. X}
  336. X
  337. X/*----------------------------------------------------------------------------*/
  338. Xstatic void put_lat_long (out_fp, fw, latitude, longitude)
  339. X     FILE   *out_fp;
  340. X     int    fw;
  341. X     double latitude, longitude;
  342. X{
  343. X   char buffer [100];
  344. X   sprintf (buffer, "[%c%3.3lf,%c%3.3lf]", 
  345. X        (latitude > 0.0) ? 'N' : 'S',
  346. X        fabs ((double) decimal_2_degrees_mins (latitude)),
  347. X        (longitude > 0.0) ? 'W' : 'E',
  348. X        fabs ((double) decimal_2_degrees_mins (longitude)));
  349. X   fprintf (out_fp, "%*s", fw, buffer);
  350. X}
  351. X/*----------------------------------------------------------------------------*/
  352. Xstatic void put_db_mode (out_fp, fw, mode)
  353. X     FILE        *out_fp;
  354. X     int           fw;
  355. X     WAYPOINT_MODE mode;
  356. X{
  357. X   char *str_val;
  358. X
  359. X   switch (mode) {
  360. X   case WP_AIRPORT:
  361. X      str_val = "Airport";
  362. X      break;
  363. X   case WP_VOR:
  364. X      str_val = "VOR";
  365. X      break;
  366. X   case WP_NAMED_INTERSECTION:
  367. X   case WP_INTERSECTION:
  368. X      str_val = "Intersection";
  369. X      break;
  370. X   case WP_INCREMENTAL:
  371. X      str_val = "Incremental";
  372. X      break;
  373. X   case WP_LAT_LONG:
  374. X      str_val = "Lat/Long";
  375. X      break;
  376. X   case WP_NDB:
  377. X      str_val = "NDB";
  378. X      break;
  379. X   case WP_DME:
  380. X      str_val = "VOR/DME";
  381. X      break;
  382. X   case WP_TAC:
  383. X      str_val = "TACAN";
  384. X      break;
  385. X   case WP_ILS:
  386. X      str_val = "ILS";
  387. X      break;
  388. X   case WP_WPT:
  389. X      str_val = "Waypoint";
  390. X      break;
  391. X   case WP_LOM:
  392. X      str_val = "Outer Mkr";
  393. X      break;
  394. X   case WP_LMM:
  395. X      str_val = "Middle Mkr";
  396. X      break;
  397. X   default:
  398. X      break;
  399. X   }
  400. X   put_string (out_fp, fw, str_val);
  401. X}
  402. X/*----------------------------------------------------------------------------*/
  403. Xstatic void put_header_cell (out_fp, cell, force)
  404. X     FILE *out_fp;
  405. X     FORMAT_SPEC_CELL cell;
  406. X     BOOLEAN force;
  407. X{
  408. X   int fw = ((cell.justification == R) ? cell.field_width :
  409. X         -1 * cell.field_width);
  410. X
  411. X
  412. X   if ((cell.kind == IGNORE) || (cell.kind == END_OF_VOR))
  413. X      return;
  414. X
  415. X   if (cell.kind == EOL) {
  416. X      line_num++;
  417. X      fprintf (out_fp, "\n");
  418. X      return;
  419. X   }
  420. X
  421. X   if ((!force) &&(cell.shifted == S) && ((line_num == 0) || (line_num == 1))) {
  422. X      put_string (out_fp, cell.field_width, "");
  423. X      return;
  424. X   }
  425. X
  426. X   switch (cell.kind) {
  427. X   case BAR:
  428. X      fprintf (out_fp, "%c", use_epson_box_chars ? EPSON_VERTICAL_BAR : '|');
  429. X      break;
  430. X   case FORWARD_ARROW:
  431. X      fprintf (out_fp, "%c", use_epson_box_chars ? EPSON_FORWARD_ARROW : '+');
  432. X      break;
  433. X   case BACKWARD_ARROW:
  434. X      fprintf (out_fp, "%c", use_epson_box_chars ? EPSON_BACKWARD_ARROW : '+');
  435. X      break;
  436. X   case CROSS:
  437. X      fprintf (out_fp, "%c", use_epson_box_chars ? EPSON_CROSS : '+');
  438. X      break;
  439. X   case SEPARATOR:
  440. X      { 
  441. X     int i;
  442. X     for (i = 0; i < cell.field_width; i++)
  443. X        fprintf (out_fp, "%c", 
  444. X             use_epson_box_chars ? EPSON_HORIZONTAL_BAR : '-');
  445. X      }
  446. X      break;
  447. X   default:
  448. X      put_string (out_fp, fw, headers[(int) cell.kind]);
  449. X   }
  450. X}
  451. X
  452. X
  453. X/*----------------------------------------------------------------------------*/
  454. Xstatic void put_info_cell (out_fp, cell, prev_wp, curr_wp)
  455. X     FILE             *out_fp;
  456. X     FORMAT_SPEC_CELL cell;
  457. X     WAYPOINT_INFO    *prev_wp, *curr_wp;
  458. X{ 
  459. X   WAYPOINT_INFO *wp;
  460. X
  461. X   int fw = ((cell.justification == R) ? cell.field_width :
  462. X         -1 * cell.field_width);
  463. X   char   *str_val;
  464. X   double d_val;
  465. X   char buffer[80];
  466. X   BOOLEAN valid;
  467. X   
  468. X   if ((cell.kind == IGNORE) || (cell.kind == END_OF_VOR))
  469. X      return;
  470. X   if ((cell.shifted == S) &&
  471. X    ((line_num == 0) || (line_num == 1))) {
  472. X      if (! prev_wp) {
  473. X     put_header_cell (out_fp, cell, TRUE);
  474. X     return;
  475. X      } else
  476. X     wp = prev_wp;
  477. X   } else
  478. X      wp = curr_wp;
  479. X
  480. X   if ((cell.shifted == S) && (wp->wp_kind == WP_TO)) {
  481. X      put_string (out_fp, cell.field_width, "");
  482. X      return;
  483. X   }
  484. X
  485. X   switch (cell.kind) {
  486. X   case EOL:
  487. X      line_num++;
  488. X      fprintf (out_fp, "\n");
  489. X      break;
  490. X   case BAR:
  491. X      fprintf (out_fp, "%c", use_epson_box_chars ? EPSON_VERTICAL_BAR : '|');
  492. X      break;
  493. X   case CROSS:
  494. X      fprintf (out_fp, "%c", use_epson_box_chars ? EPSON_CROSS : '+');
  495. X      break;
  496. X   case FORWARD_ARROW:
  497. X      fprintf (out_fp, "%c", use_epson_box_chars ? EPSON_FORWARD_ARROW : '>');
  498. X      break;
  499. X   case BACKWARD_ARROW:
  500. X      fprintf (out_fp, "%c", use_epson_box_chars ? EPSON_BACKWARD_ARROW : '<');
  501. X      break;
  502. X   case SEPARATOR:
  503. X      { 
  504. X     int i;
  505. X     for (i = 0; i < cell.field_width; i++)
  506. X        fprintf (out_fp, "%c", 
  507. X             use_epson_box_chars ? EPSON_HORIZONTAL_BAR : '-');
  508. X      }
  509. X      break;
  510. X      /*
  511. X       * strings
  512. X       */
  513. X   case NAME:
  514. X   case CITY:
  515. X   case COMMENT:
  516. X   case DESIG:
  517. X   case VOR_DESIG:
  518. X      switch (cell.kind) {
  519. X      case CITY:
  520. X     valid = TRUE;
  521. X     str_val = wp->db->city;
  522. X     break;
  523. X      case NAME:
  524. X     valid = TRUE;
  525. X     str_val = wp->db->name;
  526. X     break;
  527. X      case COMMENT:
  528. X     valid = TRUE;
  529. X     str_val = wp->db->comment;
  530. X     break;
  531. X      case DESIG:
  532. X     valid = TRUE;
  533. X     str_val = wp->db->desig;
  534. X     break;
  535. X      case VOR_DESIG:
  536. X     valid   = wp->vor_fix [cell.arg].valid;
  537. X     if (valid)
  538. X        str_val = wp->vor_fix [cell.arg].db->desig;
  539. X     break;
  540. X      default:
  541. X     valid   = FALSE;
  542. X     str_val = NULL;
  543. X     break;
  544. X      }
  545. X      if (! str_val)
  546. X     valid = FALSE;
  547. X      if (valid) {
  548. X     put_string (out_fp, fw, str_val);
  549. X      } else
  550. X     fprintf (out_fp, "%*s", fw, "");
  551. X      break;
  552. X      /*
  553. X       * headings
  554. X       */
  555. X   case MH:
  556. X   case MC:
  557. X   case TC:
  558. X      switch (cell.kind) {
  559. X      case MH:
  560. X     valid = wp->mh.valid;
  561. X     d_val = wp->mh.value;
  562. X     break;
  563. X      case MC:
  564. X     valid = wp->mc.valid;
  565. X     d_val = wp->mc.value;
  566. X     break;
  567. X      case TC:
  568. X     valid = wp->tc.valid;
  569. X     d_val = wp->tc.value;
  570. X     break;
  571. X      default:
  572. X     break;
  573. X      }
  574. X      if (valid) {
  575. X     sprintf (buffer, "%03.*f", cell.arg, d_val);
  576. X     fprintf (out_fp, "%*s", fw, buffer);
  577. X      } else {
  578. X     fprintf (out_fp, "%*s", fw, "");
  579. X      }
  580. X      break;
  581. X      /*
  582. X       * numbers
  583. X       */
  584. X   case FREQ:
  585. X   case VOR_FREQ:
  586. X      switch (cell.kind) {
  587. X      case VOR_FREQ:
  588. X     valid = wp->vor_fix [cell.arg].valid;
  589. X     if (valid) 
  590. X        d_val = wp->vor_fix [cell.arg].db->freq.value;
  591. X     break;
  592. X      case FREQ:
  593. X     valid = wp->db->freq.valid;
  594. X     d_val = wp->db->freq.value;
  595. X     break;
  596. X      default:
  597. X     valid = FALSE;
  598. X     break;
  599. X      }
  600. X      if (valid) {
  601. X     fprintf (out_fp, "%*.2f", fw, d_val);
  602. X      } else
  603. X     fprintf (out_fp, "%*s", fw, "");
  604. X      break;
  605. X   case ELEV:
  606. X   case TAS:
  607. X   case EGS:
  608. X   case FUEL_AMT:
  609. X   case FUEL_LEG:
  610. X   case FUEL_RATE:
  611. X   case DIST_LEG:
  612. X   case DIST:
  613. X   case DIST_REMAIN:
  614. X      switch (cell.kind) {
  615. X      case ELEV:
  616. X     valid = wp->db->altitude.valid;
  617. X     d_val = wp->db->altitude.value;
  618. X     break;
  619. X      case TAS:
  620. X     valid = wp->tas.valid;
  621. X     d_val = NM_OR_MI (wp->tas.value); 
  622. X     break;
  623. X      case EGS:
  624. X     valid = wp->egs.valid;
  625. X     d_val = NM_OR_MI (wp->egs.value);
  626. X     break;
  627. X      case FUEL_AMT:
  628. X     valid = wp->fuel_amt.valid;
  629. X     d_val = wp->fuel_amt.value;
  630. X     break;
  631. X      case FUEL_LEG:
  632. X     valid = wp->fuel_leg.valid;
  633. X     d_val = wp->fuel_leg.value;
  634. X     break;
  635. X      case FUEL_RATE:
  636. X     valid = wp->fuel_rate.valid;
  637. X     d_val = wp->fuel_rate.value;
  638. X     break;
  639. X      case DIST_LEG:
  640. X     valid = wp->dist_leg.valid;
  641. X     d_val = NM_OR_MI (wp->dist_leg.value);
  642. X     break;
  643. X      case DIST:
  644. X     valid = wp->dist.valid;
  645. X     d_val = NM_OR_MI (wp->dist.value);
  646. X     break;
  647. X      case DIST_REMAIN:
  648. X     valid = wp->dist_remain.valid;
  649. X     d_val = NM_OR_MI (wp->dist_remain.value);
  650. X     break;
  651. X      default:
  652. X     valid = FALSE;
  653. X     d_val = 0.0;
  654. X     break;
  655. X      }
  656. X      if (valid) {
  657. X     fprintf (out_fp, "%*.*f", fw, cell.arg, d_val);
  658. X      } else
  659. X     fprintf (out_fp, "%*s", fw, "");
  660. X      break;
  661. X      /*
  662. X       * times:
  663. X       */
  664. X   case ETA:
  665. X   case ETA_LEG:
  666. X      valid = (cell.kind == ETA) ? wp->eta.valid : wp->eta_leg.valid;
  667. X      d_val = (cell.kind == ETA) ? wp->eta.value : wp->eta_leg.value;
  668. X      if (valid)
  669. X     put_time (out_fp, fw, d_val);
  670. X      else
  671. X     fprintf (out_fp, "%*s", fw, "");
  672. X      break;
  673. X   case VOR_DME:
  674. X      if (wp->vor_fix[cell.arg].valid)
  675. X     fprintf (out_fp, "%*.0lf", fw, wp->vor_fix[cell.arg].distance);
  676. X      else
  677. X     fprintf (out_fp, "%*s", fw, "");
  678. X      break;
  679. X   case VOR_RADIAL:
  680. X      if (wp->vor_fix[cell.arg].valid) {
  681. X     sprintf (buffer, "%03.0f%c", wp->vor_fix[cell.arg].heading, 
  682. X          (wp->vor_fix[cell.arg].from_to == FROM ? 'F' : 'T') );
  683. X     fprintf (out_fp, "%*s", fw, buffer);
  684. X      } else {
  685. X     fprintf (out_fp, "%*s", fw, "");
  686. X      }
  687. X      break;
  688. X   case LAT_LONG:
  689. X      put_lat_long (out_fp, fw, wp->db->latitude, wp->db->longitude);
  690. X      break;
  691. X   case ALT:
  692. X      if (! wp->altitude.valid) {
  693. X     fprintf (out_fp, "%*s", fw, "");
  694. X#if 0
  695. X      } else if (wp->altitude.value < 1000.0) {
  696. X     sprintf (buffer, "FL%g", wp->altitude.value);
  697. X     fprintf (out_fp, "%*s", fw, buffer);
  698. X#endif
  699. X      } else {
  700. X     fprintf (out_fp, "%*.0f", fw, wp->altitude.value);
  701. X      }
  702. X      break;
  703. X   case WIND:
  704. X      if (wp->wind_direction.valid && wp->wind_speed.valid) {
  705. X     sprintf (buffer, "%03.0f@%02.0f", wp->wind_direction.value, 
  706. X          wp->wind_speed.value);
  707. X     fprintf (out_fp, "%*s", fw, buffer);
  708. X      } else {
  709. X     fprintf (out_fp, "%*s", fw, "");
  710. X      }
  711. X      break;
  712. X   case TYPE:
  713. X      put_db_mode (out_fp, fw, wp->db->mode);
  714. X      break;
  715. X   case EMPTY:
  716. X   case ATA:
  717. X   case AGS:
  718. X   default:
  719. X      fprintf (out_fp, "%*s", fw, "");
  720. X      break;
  721. X   }    
  722. X}
  723. X
  724. X/*----------------------------------------------------------------------------*/
  725. Xstatic void put_info_cells (out_fp, cells, prev_wp, wp)
  726. X     FILE             *out_fp;
  727. X     FORMAT_SPEC_CELL cells[];
  728. X     WAYPOINT_INFO    *prev_wp, *wp;
  729. X{
  730. X   int i;
  731. X
  732. X   line_num = 0;
  733. X   for (i = 0; (cells[i].kind != END_OF_FORMAT); i++) 
  734. X      put_info_cell (out_fp, cells[i], prev_wp, wp);
  735. X}
  736. X
  737. X/*----------------------------------------------------------------------------*/
  738. Xstatic void put_header_cells (out_fp, cells, first_line_only)
  739. X     FILE             *out_fp;
  740. X     FORMAT_SPEC_CELL cells[];
  741. X     BOOLEAN first_line_only;
  742. X{
  743. X   int i;
  744. X
  745. X   line_num = 0;
  746. X   for (i = 0; (cells[i].kind != END_OF_FORMAT); i++) {
  747. X      if (first_line_only && line_num)
  748. X     return;
  749. X      else
  750. X     put_header_cell (out_fp, cells[i], FALSE);
  751. X   }
  752. X}
  753. X
  754. X/*----------------------------------------------------------------------------*/
  755. Xvoid print_plan ()
  756. X{
  757. X   int i;
  758. X
  759. X   for (i = 0; i < num_waypoints; i++) {
  760. X      if (waypoints[i].wp_kind == WP_FROM) {
  761. X     if (i)
  762. X        fprintf (stdout, "\f");
  763. X     printf ("\nSpeeds in %s; Distances in %s miles\n",
  764. X         (output_units == NAUTICAL) ? "knots" : "mph (wind in knots)",
  765. X         (output_units == NAUTICAL) ? "nautical" : "statute");
  766. X     put_header_cells (stdout, output_format, FALSE);
  767. X      }
  768. X      put_info_cells (stdout, output_format,
  769. X              (waypoints[i].wp_kind == WP_FROM) ? 0 : &waypoints[i-1],
  770. X              &waypoints[i]);
  771. X      if (waypoints[i].wp_kind == WP_TO)
  772. X     put_header_cells (stdout, output_format, TRUE);
  773. X   }
  774. X}
  775. X
  776. X
  777. X/*----------------------------------------------------------------------------*/
  778. Xput_db (out_fp, db)
  779. X     FILE          *out_fp;
  780. X     DATABASE_INFO *db;
  781. X{
  782. X   fprintf (out_fp, "______________________________________________________________________________\n");
  783. X   fprintf (out_fp, "%s\t", db->desig);
  784. X   put_db_mode (out_fp, -12, db->mode);
  785. X   if (db->name)
  786. X      fprintf (out_fp, "\nNAME   : %s\n", db->name);
  787. X   if (db->city)
  788. X      fprintf (out_fp, "CITY   : %s\n", db->city);
  789. X   if (db->comment)
  790. X      fprintf (out_fp, "COMMENT: %s\n", db->comment);
  791. X   fprintf (out_fp, "LAT/LONG: ");
  792. X   put_lat_long (out_fp, 1, db->latitude, db->longitude);
  793. X   fprintf (out_fp, " MAG VARIATION: %g ", db->mag_variation);
  794. X   if (db->freq.valid)
  795. X      fprintf (out_fp, "FREQ: %7.2f ", db->freq.value);
  796. X   if (db->altitude.valid)
  797. X      fprintf (out_fp, "ALTITUDE: %g", db->altitude.value);
  798. X   fprintf (out_fp, "\n");
  799. X}
  800. SHAR_EOF
  801. chmod 0444 output.c || echo "restore of output.c fails"
  802. exit 0
  803.  
  804.