1 /*
2     Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007  Robert Lipe, robertlipe@usa.net
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
17 
18  */
19 #ifndef gpsbabel_defs_h_included
20 #define gpsbabel_defs_h_included
21 #include <time.h>
22 #include <stdlib.h>
23 #include <math.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdarg.h>
27 #include <stddef.h>
28 #if HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31 #include "queue.h"
32 #include "gbtypes.h"
33 #if HAVE_LIBZ
34 #include <zlib.h>
35 #elif !ZLIB_INHIBITED
36 #include "zlib/zlib.h"
37 #endif
38 #include "gbfile.h"
39 #include "cet.h"
40 #include "cet_util.h"
41 #include "inifile.h"
42 #include "session.h"
43 
44 // Turn on Unicode in expat?
45 #ifdef _UNICODE
46 #  define XML_UNICODE
47 #endif
48 
49 /*
50  * Amazingly, this constant is not specified in the standard...
51  */
52 #ifndef M_PI
53 #  define M_PI 3.14159265358979323846
54 #endif
55 
56 #ifndef FALSE
57 #  define FALSE 0
58 #endif
59 
60 #ifndef TRUE
61 #  define TRUE !FALSE
62 #endif
63 
64 #define FEET_TO_METERS(feetsies) ((feetsies) * 0.3048)
65 #define METERS_TO_FEET(meetsies) ((meetsies) * 3.2808399)
66 
67 #define NMILES_TO_METERS(a) ((a) * 1852.0)	/* nautical miles */
68 #define METERS_TO_NMILES(a) ((a) / 1852.0)
69 
70 #define MILES_TO_METERS(a) ((a) * 1609.344)
71 #define METERS_TO_MILES(a) ((a) / 1609.344)
72 #define FATHOMS_TO_METERS(a) ((a) * 1.8288)
73 
74 #define CELSIUS_TO_FAHRENHEIT(a) (((a) * 1.8) + 32)
75 #define FAHRENHEIT_TO_CELSIUS(a) (((a) - 32) / 1.8)
76 
77 #define SECONDS_PER_HOUR (60L*60)
78 #define SECONDS_PER_DAY (24L*60*60)
79 
80 /* meters/second to kilometers/hour */
81 #define MPS_TO_KPH(a) ((double)(a)*SECONDS_PER_HOUR/1000)
82 
83 /* meters/second to miles/hour */
84 #define MPS_TO_MPH(a) (METERS_TO_MILES(a) * SECONDS_PER_HOUR)
85 
86 /* meters/second to knots */
87 #define MPS_TO_KNOTS(a) (MPS_TO_KPH((a)/1.852))
88 
89 /* kilometers/hour to meters/second */
90 #define KPH_TO_MPS(a) ((double)(a)*1000/SECONDS_PER_HOUR)
91 
92 /* miles/hour to meters/second */
93 #define MPH_TO_MPS(a) (MILES_TO_METERS(a) / SECONDS_PER_HOUR)
94 
95 /* knots to meters/second */
96 #define KNOTS_TO_MPS(a) (KPH_TO_MPS((a)*1.852))
97 
98 /*
99  * Snprintf is in SUS (so it's in most UNIX-like substance) and it's in
100  * C99 (albeit with slightly different semantics) but it isn't in C89.
101  * This tweaks allows us to use snprintf on the holdout.
102  */
103 #if __WIN32__
104 #  define snprintf _snprintf
105 #  define vsnprintf _vsnprintf
106 #  ifndef fileno
107 #    define fileno _fileno
108 #  endif
109 #  define strdup _strdup
110 #endif
111 
112 /* Turn off numeric conversion warning */
113 #if __WIN32__
114 #  if _MSC_VER
115 #    pragma warning(disable:4244)
116 #  endif
117 #if !defined _CRT_SECURE_NO_DEPRECATE
118 #  define _CRT_SECURE_NO_DEPRECATE 1
119 #endif
120 #endif
121 
122 /* Pathname separator character */
123 #if __WIN32__
124 #  define GB_PATHSEP '\\'
125 #else
126 #  define GB_PATHSEP '/'
127 #endif
128 
129 /*
130  *  Toss in some GNU C-specific voodoo for checking.
131  */
132 #if __GNUC__
133 #  define PRINTFLIKE(x,y) __attribute__ ((__format__ (__printf__, (x), (y))))
134 #  define NORETURN void __attribute__ ((__noreturn__))
135 #else
136 #  define PRINTFLIKE(x,y)
137 #  define NORETURN void
138 #endif
139 
140 #ifndef HAVE_VA_COPY
141 #  ifdef __va_copy
142 #    define va_copy(DEST,SRC) __va_copy((DEST),(SRC))
143 #  else
144 #    ifdef HAVE_VA_LIST_AS_ARRAY
145 #      define va_copy(DEST,SRC) (*(DEST) = *(SRC))
146 #    else
147 #      define va_copy(DEST,SRC) ((DEST) = (SRC))
148 #    endif
149 #  endif
150 #endif
151 
152 /*
153  * Common definitions.   There should be no protocol or file-specific
154  * data in this file.
155  */
156 #define BASE_STRUCT(memberp, struct_type, member_name) \
157    ((struct_type *)((char *)(memberp) - offsetof(struct_type, member_name)))
158 
159 typedef enum {
160   fix_unknown=-1,
161   fix_none=0,
162   fix_2d=1,
163   fix_3d,
164   fix_dgps,
165   fix_pps
166 } fix_type;
167 
168 typedef enum {
169   status_unknown=0,
170   status_true,
171   status_false
172 } status_type;
173 
174 /*
175  * Define globally on which kind of data gpsbabel is working.
176  * Important for "file types" that are essentially a communication
177  * protocol for a receiver, like the Magellan serial data.
178  */
179 typedef enum {
180   unknown_gpsdata = 0,
181   trkdata = 1 ,
182   wptdata,
183   rtedata,
184   posndata
185 } gpsdata_type;
186 
187 #define NOTHINGMASK		0
188 #define WPTDATAMASK		1
189 #define TRKDATAMASK		2
190 #define	RTEDATAMASK		4
191 #define	POSNDATAMASK		8
192 
193 /* mask objective testing */
194 #define	doing_nothing (global_opts.masked_objective == NOTHINGMASK)
195 #define	doing_wpts ((global_opts.masked_objective & WPTDATAMASK) == WPTDATAMASK)
196 #define	doing_trks ((global_opts.masked_objective & TRKDATAMASK) == TRKDATAMASK)
197 #define	doing_rtes ((global_opts.masked_objective & RTEDATAMASK) == RTEDATAMASK)
198 #define	doing_posn ((global_opts.masked_objective & POSNDATAMASK) == POSNDATAMASK)
199 
200 typedef struct {
201   int synthesize_shortnames;
202   int debug_level;
203   gpsdata_type objective;
204   unsigned int	masked_objective;
205   int verbose_status;	/* set by GUI wrappers for status */
206   int smart_icons;
207   int smart_names;
208   cet_cs_vec_t* charset;
209   char* charset_name;
210   inifile_t* inifile;
211 } global_options;
212 
213 extern global_options global_opts;
214 extern const char gpsbabel_version[];
215 extern time_t gpsbabel_now;	/* gpsbabel startup-time; initialized in main.c with time() */
216 extern time_t gpsbabel_time;	/* gpsbabel startup-time; initialized in main.c with current_time(), ! ZERO within testo ! */
217 extern int geocaches_present;
218 
219 #define MILLI_TO_MICRO(t) (t * 1000)  /* Milliseconds to Microseconds */
220 #define MICRO_TO_MILLI(t) (t / 1000)  /* Microseconds to Milliseconds*/
221 #define CENTI_TO_MICRO(t) (t * 10000) /* Centiseconds to Microseconds */
222 #define MICRO_TO_CENTI(t) (t / 10000) /* Centiseconds to Microseconds */
223 
224 /* Short or Long XML Times */
225 #define XML_SHORT_TIME 1
226 #define XML_LONG_TIME 2
227 
228 /*
229  * Extended data if waypoint happens to represent a geocache.  This is
230  * totally voluntary data...
231  */
232 
233 typedef enum {
234   gt_unknown = 0 ,
235   gt_traditional,
236   gt_multi,
237   gt_virtual,
238   gt_letterbox,
239   gt_event,
240   gt_suprise,
241   gt_webcam,
242   gt_earth,
243   gt_locationless,
244   gt_benchmark, /* Extension to Groundspeak for GSAK */
245   gt_cito,
246   gt_ape,
247   gt_mega,
248   gt_wherigo
249 } geocache_type;
250 
251 typedef enum {
252   gc_unknown = 0,
253   gc_micro,
254   gc_other,
255   gc_regular,
256   gc_large,
257   gc_virtual,
258   gc_small
259 } geocache_container;
260 
261 typedef struct {
262   int is_html;
263   char* utfstring;
264 } utf_string;
265 
266 typedef struct {
267   int id; /* The decimal cache number */
268   geocache_type type:5;
269   geocache_container container:4;
270   unsigned int diff:6; /* (multiplied by ten internally) */
271   unsigned int terr:6; /* (likewise) */
272   status_type is_archived:2;
273   status_type is_available:2;
274   status_type is_memberonly:2;
275   status_type has_customcoords:2;
276   time_t exported;
277   time_t last_found;
278   char* placer; /* Placer name */
279   int placer_id; /* Placer id */
280   char* hint; /* all these UTF8, XML entities removed, May be not HTML. */
281   utf_string desc_short;
282   utf_string desc_long;
283   int favorite_points;
284   char* personal_note;
285 } geocache_data ;
286 
287 typedef struct xml_tag {
288   char* tagname;
289   char* cdata;
290   int cdatalen;
291   char* parentcdata;
292   int parentcdatalen;
293   char** attributes;
294   struct xml_tag* parent;
295   struct xml_tag* sibling;
296   struct xml_tag* child;
297 } xml_tag ;
298 
299 typedef void (*fs_destroy)(void*);
300 typedef void (*fs_copy)(void**, void*);
301 typedef void (*fs_convert)(void*);
302 
303 typedef struct format_specific_data {
304   long type;
305   struct format_specific_data* next;
306 
307   fs_destroy destroy;
308   fs_copy copy;
309   fs_convert convert;
310 } format_specific_data;
311 
312 typedef struct {
313   int bbggrr;   // 32 bit color: Blue/Green/Red.  < 0 == unknown.
314   unsigned char opacity;  // 0 == transparent.  255 == opaque.
315 } gb_color;
316 
317 
318 format_specific_data* fs_chain_copy(format_specific_data* source);
319 void fs_chain_destroy(format_specific_data* chain);
320 format_specific_data* fs_chain_find(format_specific_data* chain, long type);
321 void fs_chain_add(format_specific_data** chain, format_specific_data* data);
322 
323 typedef struct fs_xml {
324   format_specific_data fs;
325   xml_tag* tag;
326 } fs_xml;
327 
328 fs_xml* fs_xml_alloc(long type);
329 
330 #define FS_GPX 0x67707800L
331 #define FS_AN1W 0x616e3177L
332 #define FS_AN1L 0x616e316cL
333 #define FS_AN1V 0x616e3176L
334 #define FS_OZI 0x6f7a6900L
335 #define FS_GMSD 0x474d5344L	/* GMSD = Garmin specific data */
336 #define FS_LOWRANCEUSR4 0x615f234cL
337 
338 /*
339  * Structures and functions for multiple URLs per waypoint.
340  */
341 typedef struct url_link {
342   struct url_link* url_next;
343   char* url;
344   char* url_link_text;
345 } url_link;
346 
347 /*
348  * Misc bitfields inside struct waypoint;
349  */
350 typedef struct {
351   unsigned int icon_descr_is_dynamic:1;
352   unsigned int shortname_is_synthetic:1;
353   unsigned int cet_converted:1;		/* strings are converted to UTF8; interesting only for input */
354   unsigned int fmt_use:1;			/* lightweight "extra data" */
355   /* "flagged fields" */
356   unsigned int temperature:1;		/* temperature field is set */
357   unsigned int proximity:1;		/* proximity field is set */
358   unsigned int course:1;			/* course field is set */
359   unsigned int speed:1;			/* speed field is set */
360   unsigned int depth:1;			/* depth field is set */
361   /* !ToDo!
362   unsigned int altitude:1;		/+ altitude field is set +/
363   ... and others
364   */
365   unsigned int is_split:1;		/* the waypoint represents a split */
366   unsigned int new_trkseg:1;		/* True if first in new trkseg. */
367 
368 
369 } wp_flags;
370 
371 // These are dicey as they're collected on read. Subsequent filters may change
372 // things, though it's u nlikely to matter in practical terms.  Don't use these
373 // if a false positive would be deleterious.
374 typedef struct {
375   unsigned int trait_geocaches:1;
376   unsigned int trait_heartrate:1;
377   unsigned int trait_cadence:1;
378   unsigned int trait_power:1;
379   unsigned int trait_depth:1;
380   unsigned int trait_temperature:1;
381 } global_trait;
382 const global_trait* get_traits();
383 
384 #define WAYPT_SET(wpt,member,val) { wpt->member = (val); wpt->wpt_flags.member = 1; }
385 #define WAYPT_GET(wpt,member,def) ((wpt->wpt_flags.member) ? (wpt->member) : (def))
386 #define WAYPT_UNSET(wpt,member) wpt->wpt_flags.member = 0
387 #define WAYPT_HAS(wpt,member) (wpt->wpt_flags.member)
388 /*
389  * This is a waypoint, as stored in the GPSR.   It tries to not
390  * cater to any specific model or protocol.  Anything that needs to
391  * be truncated, edited, or otherwise trimmed should be done on the
392  * way to the target.
393  */
394 
395 typedef struct {
396   queue Q;			/* Master waypoint q.  Not for use
397 					   by modules. */
398 
399   double latitude;		/* Degrees */
400   double longitude; 		/* Degrees */
401   double altitude; 		/* Meters. */
402 
403   /*
404    * The "thickness" of a waypoint; adds an element of 3D.  Can be
405    * used to construct rudimentary polygons for, say, airspace
406    * definitions.   The units are meters.
407    */
408   double depth;
409 
410   /*
411    * An alarm trigger value that can be considered to be a circle
412    * surrounding a waypoint (or cylinder if depth is also defined).
413    * The units are meters.
414    */
415   double proximity;
416 
417   /* shortname is a waypoint name as stored in receiver.  It should
418    * strive to be, well, short, and unique.   Enforcing length and
419    * character restrictions is the job of the output.   A typical
420    * minimum length for shortname is 6 characters for NMEA units,
421    * 8 for Magellan and 10 for Vista.   These are only guidelines.
422    */
423   char* shortname;
424   /*
425    * description is typically a human readable description of the
426    * waypoint.   It may be used as a comment field in some receivers.
427    * These are probably under 40 bytes, but that's only a guideline.
428    */
429   char* description;
430   /*
431    * notes are relatively long - over 100 characters - prose associated
432    * with the above.   Unlike shortname and description, these are never
433    * used to compute anything else and are strictly "passed through".
434    * Few formats support this.
435    */
436   char* notes;
437 
438   /* This is a bit icky.   Multiple waypoint support is an
439    * afterthought and I don't want to change our data structures.
440    * So we have the first in the waypoint itself and subsequent
441    * ones in a linked list.
442    * We also use an implicit anonymous union here, so these three
443    * members must match struct url_link...
444    */
445   struct url_link* url_next;
446   char* url;
447   char* url_link_text;
448 
449   wp_flags wpt_flags;
450   const char* icon_descr;
451   time_t creation_time;	/* standardized in UTC/GMT */
452   int microseconds;	/* Optional millionths of a second. */
453 
454   /*
455    * route priority is for use by the simplify filter.  If we have
456    * some reason to believe that the route point is more important,
457    * we can give it a higher (numerically; 0 is the lowest) priority.
458    * This causes it to be removed last.
459    * This is currently used by the saroute input filter to give named
460    * waypoints (representing turns) a higher priority.
461    * This is also used by the google input filter because they were
462    * nice enough to use exactly the same priority scheme.
463    */
464   int route_priority;
465 
466   /* Optional dilution of precision:  positional, horizontal, veritcal.
467    * 1 <= dop <= 50
468    */
469   float hdop;
470   float vdop;
471   float pdop;
472   float course;	/* Optional: degrees true */
473   float speed;   	/* Optional: meters per second. */
474   fix_type fix;	/* Optional: 3d, 2d, etc. */
475   int  sat;	/* Optional: number of sats used for fix */
476 
477   unsigned char heartrate; /* Beats/min. likely to get moved to fs. */
478   unsigned char cadence;	 /* revolutions per minute */
479   float power; /* watts, as measured by cyclists */
480   float temperature; /* Degrees celsius */
481   float odometer_distance; /* Meters? */
482   const geocache_data* gc_data;
483   format_specific_data* fs;
484   session_t* session;	/* pointer to a session struct */
485   void* extra_data;	/* Extra data added by, say, a filter. */
486 } waypoint;
487 
488 typedef struct {
489   queue Q;		/* Link onto parent list. */
490   queue waypoint_list;	/* List of child waypoints */
491   char* rte_name;
492   char* rte_desc;
493   char* rte_url;
494   int rte_num;
495   int rte_waypt_ct;		/* # waypoints in waypoint list */
496   format_specific_data* fs;
497   unsigned short cet_converted;	/* strings are converted to UTF8; interesting only for input */
498   gb_color line_color;         /* Optional line color for rendering */
499   int line_width;         /* in pixels (sigh).  < 0 is unknown. */
500   session_t* session;	/* pointer to a session struct */
501 } route_head;
502 
503 /*
504  *  Structure of recomputed track/roue data.
505  */
506 typedef struct {
507   double	distance_meters;
508   double	max_alt;	/*  unknown_alt => invalid */
509   double	min_alt;	/* -unknown_alt => invalid */
510   double	max_spd;	/* Meters/sec */
511   double	min_spd;	/* Meters/sec */
512   double	avg_hrt;	/* Avg Heartrate */
513   double	avg_cad;	/* Avg Cadence */
514   time_t	start;		/* Min time */
515   time_t	end;		/* Max time */
516   int	min_hrt;        /* Min Heartrate */
517   int	max_hrt;        /* Max Heartrate */
518   int	max_cad;        /* Max Cadence */
519 } computed_trkdata;
520 
521 /*
522  *  Bounding box information.
523  */
524 typedef struct {
525   double max_lat;
526   double max_lon;
527   double max_alt;	/*  unknown_alt => invalid */
528   double min_lat;
529   double min_lon;
530   double min_alt;	/* -unknown_alt => invalid */
531 } bounds;
532 
533 typedef struct {
534   volatile int request_terminate;
535 } posn_status;
536 
537 extern posn_status tracking_status;
538 
539 typedef void (*ff_init)(char const*);
540 typedef void (*ff_deinit)(void);
541 typedef void (*ff_read)(void);
542 typedef void (*ff_write)(void);
543 typedef void (*ff_exit)(void);
544 typedef void (*ff_writeposn)(waypoint*);
545 typedef waypoint* (*ff_readposn)(posn_status*);
546 
547 #ifndef DEBUG_MEM
548 char* get_option(const char* iarglist, const char* argname);
549 #else
550 #define DEBUG_PARAMS const char *file, const int line
551 char* GET_OPTION(const char* iarglist, const char* argname, DEBUG_PARAMS);
552 #define get_option(iarglist, argname) GET_OPTION(iarglist, argname, __FILE__, __LINE__)
553 #endif
554 
555 typedef void (*filter_init)(char const*);
556 typedef void (*filter_process)(void);
557 typedef void (*filter_deinit)(void);
558 typedef void (*filter_exit)(void);
559 
560 typedef void (*waypt_cb)(const waypoint*);
561 typedef void (*route_hdr)(const route_head*);
562 typedef void (*route_trl)(const route_head*);
563 void waypt_add(waypoint*);
564 waypoint* waypt_dupe(const waypoint*);
565 waypoint* waypt_new(void);
566 void waypt_del(waypoint*);
567 void waypt_free(waypoint*);
568 void waypt_disp_all(waypt_cb);
569 void waypt_disp_session(const session_t* se, waypt_cb cb);
570 void waypt_init_bounds(bounds* bounds);
571 int waypt_bounds_valid(bounds* bounds);
572 void waypt_add_to_bounds(bounds* bounds, const waypoint* waypointp);
573 void waypt_compute_bounds(bounds*);
574 double gcgeodist(const double lat1, const double lon1,
575                  const double lat2, const double lon2);
576 void waypt_flush(queue*);
577 void waypt_flush_all(void);
578 unsigned int waypt_count(void);
579 void set_waypt_count(unsigned int nc);
580 void waypt_add_url(waypoint* wpt, char* link, char* url_link_text);
581 void free_gpx_extras(xml_tag* tag);
582 void xcsv_setup_internal_style(const char* style_buf);
583 void xcsv_read_internal_style(const char* style_buf);
584 waypoint* find_waypt_by_name(const char* name);
585 void waypt_backup(signed int* count, queue** head_bak);
586 void waypt_restore(signed int count, queue* head_bak);
587 
588 geocache_data* waypt_alloc_gc_data(waypoint* wpt);
589 int waypt_empty_gc_data(const waypoint* wpt);
590 geocache_type gs_mktype(const char* t);
591 geocache_container gs_mkcont(const char* t);
592 
593 route_head* route_head_alloc(void);
594 void route_add(waypoint*);
595 void route_add_wpt(route_head* rte, waypoint* wpt);
596 void route_del_wpt(route_head* rte, waypoint* wpt);
597 void track_add_wpt(route_head* rte, waypoint* wpt);
598 void track_del_wpt(route_head* rte, waypoint* wpt);
599 void route_add_head(route_head* rte);
600 void route_del_head(route_head* rte);
601 void route_reverse(const route_head* rte_hd);
602 waypoint* route_find_waypt_by_name(route_head* rh, const char* name);
603 void track_add_head(route_head* rte);
604 void track_del_head(route_head* rte);
605 void track_insert_head(route_head* rte, route_head* predecessor);
606 void route_disp(const route_head* rte, waypt_cb);
607 void route_disp_all(route_hdr, route_trl, waypt_cb);
608 void track_disp_all(route_hdr, route_trl, waypt_cb);
609 void route_disp_session(const session_t* se, route_hdr rh, route_trl rt, waypt_cb wc);
610 void track_disp_session(const session_t* se, route_hdr rh, route_trl rt, waypt_cb wc);
611 void route_flush(queue*);
612 void route_flush_all(void);
613 void route_flush_all_routes(void);
614 void route_flush_all_tracks(void);
615 route_head* route_find_route_by_name(const char* name);
616 route_head* route_find_track_by_name(const char* name);
617 unsigned int route_waypt_count(void);
618 unsigned int route_count(void);
619 unsigned int track_waypt_count(void);
620 unsigned int track_count(void);
621 void route_copy(int* dst_count, int* dst_wpt_count, queue** dst, queue* src);
622 void route_backup(signed int* count, queue** head_bak);
623 void route_restore(queue* head_bak);
624 void route_append(queue* src);
625 void track_backup(signed int* count, queue** head_bak);
626 void track_restore(queue* head_bak);
627 void track_append(queue* src);
628 void route_flush(queue* head);
629 void track_recompute(const route_head* trk, computed_trkdata**);
630 
631 /*
632  * All shortname functions take a shortname handle as the first arg.
633  * This is an opaque pointer.  Callers must not fondle the contents of it.
634  */
635 // This is a crutch until the new C++ shorthandle goes in.
636 #define PRIME 37
637 typedef struct {
638   unsigned int target_len;
639   char* badchars;
640   char* goodchars;
641   char* defname;
642   queue namelist[PRIME];
643 
644   /* Various internal flags at end to allow alignment flexibility. */
645   unsigned int mustupper:1;
646   unsigned int whitespaceok:1;
647   unsigned int repeating_whitespaceok:1;
648   unsigned int must_uniq:1;
649   unsigned int is_utf8:1;
650 } mkshort_handle_imp;
651 typedef mkshort_handle_imp* short_handle;
652 
653 #ifndef DEBUG_MEM
654 char* mkshort(short_handle,  const char*);
655 short_handle mkshort_new_handle(void);
656 #else
657 char* MKSHORT(short_handle,  const char*, DEBUG_PARAMS);
658 short_handle MKSHORT_NEW_HANDLE(DEBUG_PARAMS);
659 #define mkshort( a, b) MKSHORT(a,b,__FILE__, __LINE__)
660 #define mkshort_new_handle() MKSHORT_NEW_HANDLE(__FILE__,__LINE__)
661 #endif
662 char* mkshort_from_wpt(short_handle h, const waypoint* wpt);
663 void mkshort_del_handle(short_handle* h);
664 void setshort_length(short_handle, int n);
665 void setshort_badchars(short_handle,  const char*);
666 void setshort_goodchars(short_handle,  const char*);
667 void setshort_mustupper(short_handle,  int n);
668 void setshort_mustuniq(short_handle,  int n);
669 void setshort_whitespace_ok(short_handle,  int n);
670 void setshort_repeating_whitespace_ok(short_handle,  int n);
671 void setshort_defname(short_handle, const char* s);
672 void setshort_is_utf8(short_handle h, const int is_utf8);
673 
674 /*
675  *  Vmem flags values.
676  */
677 #define VMFL_NOZERO (1 << 0)
678 typedef struct vmem {
679   char* mem;		/* visible memory object */
680   size_t size; 		/* allocated size of object */
681 } vmem_t;
682 vmem_t 	vmem_alloc(size_t, int flags);
683 void 	vmem_free(vmem_t*);
684 void 	vmem_realloc(vmem_t*, size_t);
685 
686 
687 #define ARGTYPE_UNKNOWN    0x00000000
688 #define ARGTYPE_INT        0x00000001
689 #define ARGTYPE_FLOAT      0x00000002
690 #define ARGTYPE_STRING     0x00000003
691 #define ARGTYPE_BOOL       0x00000004
692 #define ARGTYPE_FILE       0x00000005
693 #define ARGTYPE_OUTFILE    0x00000006
694 
695 /* REQUIRED means that the option is required to be set.
696  * See also BEGIN/END_REQ */
697 #define ARGTYPE_REQUIRED   0x40000000
698 
699 /* HIDDEN means that the option does not appear in help texts.  Useful
700  * for debugging or testing options */
701 #define ARGTYPE_HIDDEN     0x20000000
702 
703 /* BEGIN/END_EXCL mark the beginning and end of an exclusive range of
704  * options. No more than one of the options in the range may be selected
705  * or set. If exactly one must be set, use with BEGIN/END_REQ
706  * Both of these flags set is just like neither set, so avoid doing that. */
707 #define ARGTYPE_BEGIN_EXCL 0x10000000
708 #define ARGTYPE_END_EXCL   0x08000000
709 
710 /* BEGIN/END_REQ mark the beginning and end of a required range of
711  * options.  One or more of the options in the range MUST be selected or set.
712  * If exactly one must be set, use with BEGIN/END_EXCL
713  * Both of these flags set is synonymous with REQUIRED, so use that instead
714  * for "groups" of exactly one option. */
715 #define ARGTYPE_BEGIN_REQ  0x04000000
716 #define ARGTYPE_END_REQ    0x02000000
717 
718 #define ARGTYPE_TYPEMASK 0x00000fff
719 #define ARGTYPE_FLAGMASK 0xfffff000
720 
721 #define ARG_NOMINMAX NULL, NULL
722 #define ARG_TERMINATOR {0, 0, 0, 0, 0, ARG_NOMINMAX}
723 
724 typedef struct arglist {
725   const char* argstring;
726   char** argval;
727   const char* helpstring;
728   const char* defaultvalue;
729   const gbuint32 argtype;
730   const char* minvalue;		/* minimum value for numeric options */
731   const char* maxvalue;		/* maximum value for numeric options */
732   char* argvalptr;	/* !!! internal helper. Not used in definitions !!! */
733 } arglist_t;
734 
735 typedef enum {
736   ff_type_file = 1,	/* normal format: useful to a GUI. */
737   ff_type_internal,	/* fmt not useful with default options */
738   ff_type_serial		/* format describes a serial protocol (GUI can display port names) */
739 } ff_type;
740 
741 typedef enum {
742   ff_cap_rw_wpt,
743   ff_cap_rw_trk,
744   ff_cap_rw_rte
745 } ff_cap_array;
746 
747 typedef enum {
748   ff_cap_none,
749   ff_cap_read = 1,
750   ff_cap_write = 2
751 } ff_cap;
752 
753 #define FF_CAP_RW_ALL \
754 	{ (ff_cap) (ff_cap_read | ff_cap_write), (ff_cap) (ff_cap_read | ff_cap_write), (ff_cap) (ff_cap_read | ff_cap_write) }
755 
756 #define FF_CAP_RW_WPT \
757 	{ (ff_cap) (ff_cap_read | ff_cap_write), ff_cap_none, ff_cap_none}
758 
759 /*
760  * Format capabilities for realtime positioning.
761  */
762 typedef struct position_ops {
763   ff_init rd_init;
764   ff_readposn rd_position;
765   ff_deinit rd_deinit;
766 
767   ff_init wr_init;
768   ff_writeposn wr_position;
769   ff_deinit wr_deinit;
770 } position_ops_t;
771 
772 /*
773  *  Describe the file format to the caller.
774  */
775 typedef struct ff_vecs {
776   ff_type type;
777   ff_cap cap[3];
778   ff_init rd_init;
779   ff_init wr_init;
780   ff_deinit rd_deinit;
781   ff_deinit wr_deinit;
782   ff_read read;
783   ff_write write;
784   ff_exit exit;
785   arglist_t* args;
786   const char* encode;
787   int fixed_encode;
788   position_ops_t position_ops;
789   const char* name;		/* dyn. initialized by find_vec */
790 } ff_vecs_t;
791 
792 typedef struct style_vecs {
793   const char* name;
794   const char* style_buf;
795 } style_vecs_t;
796 extern style_vecs_t style_list[];
797 
798 void waypt_init(void);
799 void route_init(void);
800 void waypt_disp(const waypoint*);
801 void waypt_status_disp(int total_ct, int myct);
802 double waypt_time(const waypoint* wpt);
803 double waypt_speed(const waypoint* A, const waypoint* B);
804 double waypt_speed_ex(const waypoint* A, const waypoint* B);
805 double waypt_course(const waypoint* A, const waypoint* B);
806 double waypt_distance(const waypoint* A, const waypoint* B);
807 double waypt_distance_ex(const waypoint* A, const waypoint* B);
808 
809 NORETURN fatal(const char*, ...) PRINTFLIKE(1, 2);
810 void is_fatal(const int condition, const char*, ...) PRINTFLIKE(2, 3);
811 void warning(const char*, ...) PRINTFLIKE(1, 2);
812 void debug_print(int level, const char* fmt, ...) PRINTFLIKE(2,3);
813 
814 ff_vecs_t* find_vec(char* const, char**);
815 void assign_option(const char* vecname, arglist_t* ap, const char* val);
816 void disp_vec_options(const char* vecname, arglist_t* ap);
817 void disp_vecs(void);
818 void disp_vec(const char* vecname);
819 void init_vecs(void);
820 void exit_vecs(void);
821 void disp_formats(int version);
822 const char* name_option(long type);
823 void printposn(const double c, int is_lat);
824 
825 #ifndef DEBUG_MEM
826 void* xcalloc(size_t nmemb, size_t size);
827 void* xmalloc(size_t size);
828 void* xrealloc(void* p, size_t s);
829 void xfree(void* mem);
830 char* xstrdup(const char* s);
831 char* xstrndup(const char* s, size_t n);
832 char* xstrndupt(const char* s, size_t n);
833 char* xstrappend(char* src, const char* addon);
834 #define xxcalloc(nmemb, size, file, line) xcalloc(nmemb, size)
835 #define xxmalloc(size, file, line) xmalloc(size)
836 #define xxrealloc(p, s, file, line) xrealloc(p,s)
837 #define xxfree(mem, file, line) xfree(mem)
838 #define xxstrdup(s, file, line) xstrdup(s)
839 #define xxstrappend(src, addon, file, line) xstrappend(src, addon)
840 #else /* DEBUG_MEM */
841 void* XCALLOC(size_t nmemb, size_t size, DEBUG_PARAMS);
842 void* XMALLOC(size_t size, DEBUG_PARAMS);
843 void* XREALLOC(void* p, size_t s, DEBUG_PARAMS);
844 void XFREE(void* mem, DEBUG_PARAMS);
845 char* XSTRDUP(const char* s, DEBUG_PARAMS);
846 char* XSTRNDUP(const char* src, size_t size, DEBUG_PARAMS);
847 char* XSTRNDUPT(const char* src, size_t size, DEBUG_PARAMS);
848 char* XSTRAPPEND(char* src, const char* addon, DEBUG_PARAMS);
849 void debug_mem_open();
850 void debug_mem_output(char* format, ...);
851 void debug_mem_close();
852 #define xcalloc(nmemb, size) XCALLOC(nmemb, size, __FILE__, __LINE__)
853 #define xmalloc(size) XMALLOC(size, __FILE__, __LINE__)
854 #define xrealloc(p, s) XREALLOC(p,s,__FILE__,__LINE__)
855 #define xfree(mem) XFREE(mem, __FILE__, __LINE__)
856 #define xstrdup(s) XSTRDUP(s, __FILE__, __LINE__)
857 #define xstrndup(s, z) XSTRNDUP(s, z, __FILE__, __LINE__)
858 #define xstrndupt(s, z) XSTRNDUPT(s, z, __FILE__, __LINE__)
859 #define xstrappend(src,addon) XSTRAPPEND(src, addon, __FILE__, __LINE__)
860 #define xxcalloc XCALLOC
861 #define xxmalloc XMALLOC
862 #define xxrealloc XREALLOC
863 #define xxfree XFREE
864 #define xxstrdup XSTRDUP
865 #define xxstrndupt XSTRNDUPT
866 #define xxstrappend XSTRAPPEND
867 #endif /* DEBUG_MEM */
868 
869 FILE* xfopen(const char* fname, const char* type, const char* errtxt);
870 void xfprintf(const char* errtxt, FILE* stream, const char* format, ...);
871 void xfputs(const char* errtxt, const char* s, FILE* stream);
872 
873 int case_ignore_strcmp(const char* s1, const char* s2);
874 int case_ignore_strncmp(const char* s1, const char* s2, int n);
875 int str_match(const char* str, const char* match);
876 int case_ignore_str_match(const char* str, const char* match);
877 char* strenquote(const char* str, const char quot_char);
878 
879 char* strsub(const char* s, const char* search, const char* replace);
880 char* gstrsub(const char* s, const char* search, const char* replace);
881 char* xstrrstr(const char* s1, const char* s2);
882 void rtrim(char* s);
883 char* lrtrim(char* s);
884 int xasprintf(char** strp, const char* fmt, ...) PRINTFLIKE(2, 3);
885 int xvasprintf(char** strp, const char* fmt, va_list ap);
886 char* strupper(char* src);
887 char* strlower(char* src);
888 signed int get_tz_offset(void);
889 time_t mklocaltime(struct tm* t);
890 time_t mkgmtime(struct tm* t);
891 time_t current_time(void);
892 void dotnet_time_to_time_t(double dotnet, time_t* t, int* ms);
893 signed int month_lookup(const char* m);
894 const char* get_cache_icon(const waypoint* waypointp);
895 const char* gs_get_cachetype(geocache_type t);
896 const char* gs_get_container(geocache_container t);
897 char* xml_entitize(const char* str);
898 char* html_entitize(const char* str);
899 char* strip_html(const utf_string*);
900 char* strip_nastyhtml(const char* in);
901 char* convert_human_date_format(const char* human_datef);	/* "MM,YYYY,DD" -> "%m,%Y,%d" */
902 char* convert_human_time_format(const char* human_timef);	/* "HH+mm+ss"   -> "%H+%M+%S" */
903 char* pretty_deg_format(double lat, double lon, char fmt, const char* sep, int html);    /* decimal ->  dd.dddd or dd mm.mmm or dd mm ss */
904 
905 char* get_filename(const char* fname);				/* extract the filename portion */
906 
907 /*
908  * Character encoding transformations.
909  */
910 
911 #define CET_NOT_CONVERTABLE_DEFAULT '$'
912 #define CET_CHARSET_ASCII	"US-ASCII"
913 #define CET_CHARSET_UTF8	"UTF-8"
914 #define CET_CHARSET_HEBREW  "CP1255"
915 #define CET_CHARSET_MS_ANSI	"MS-ANSI"
916 #define CET_CHARSET_LATIN1	"ISO-8859-1"
917 
918 #define str_utf8_to_cp1252(str) cet_str_utf8_to_cp1252((str))
919 #define str_cp1252_to_utf8(str) cet_str_cp1252_to_utf8((str))
920 
921 #define str_utf8_to_iso8859_1(str) cet_str_utf8_to_iso8859_1((str))
922 #define str_iso8859_1_to_utf8(str) cet_str_iso8859_1_to_utf8((str))
923 
924 /* this lives in gpx.c */
925 time_t xml_parse_time(const char* cdatastr, int* microsecs);
926 
927 xml_tag* xml_findfirst(xml_tag* root, const char* tagname);
928 xml_tag* xml_findnext(xml_tag* root, xml_tag* cur, const char* tagname);
929 char* xml_attribute(xml_tag* tag, const char* attrname);
930 
931 char* rot13(const char* str);
932 
933 /*
934  * PalmOS records like fixed-point numbers, which should be rounded
935  * to deal with possible floating-point representation errors.
936  */
937 
938 signed int si_round(double d);
939 
940 /*
941  * Data types for Palm/OS files.
942  */
943 typedef struct {
944   unsigned char data[4];
945 } pdb_32;
946 
947 typedef struct {
948   unsigned char data[2];
949 } pdb_16;
950 
951 typedef struct {
952   unsigned char data[8];
953 } pdb_double;
954 
955 typedef struct {
956   unsigned char data[4];
957 } pdb_float;
958 
959 /*
960  * Protypes for Endianness helpers.
961  */
962 
963 signed int be_read16(const void* p);
964 unsigned int be_readu16(const void* p);
965 signed int be_read32(const void* p);
966 signed int le_read16(const void* p);
967 unsigned int le_readu16(const void* p);
968 signed int le_read32(const void* p);
969 unsigned int le_readu32(const void* p);
970 void le_read64(void* dest, const void* src);
971 void be_write16(void* pp, const unsigned i);
972 void be_write32(void* pp, const unsigned i);
973 void le_write16(void* pp, const unsigned i);
974 void le_write32(void* pp, const unsigned i);
975 
976 double endian_read_double(const void* ptr, int read_le);
977 float  endian_read_float(const void* ptr, int read_le);
978 void   endian_write_double(void* ptr, double d, int write_le);
979 void   endian_write_float(void* ptr, float f, int write_le);
980 
981 float  be_read_float(void* p);
982 double be_read_double(void* p);
983 void   be_write_float(void* pp, float d);
984 void   be_write_double(void* pp, double d);
985 
986 float  le_read_float(const void* p);
987 double le_read_double(const void* p);
988 void   le_write_float(void* ptr, float f);
989 void   le_write_double(void* p, double d);
990 
991 #define pdb_write_float be_write_float
992 #define pdb_read_float be_read_float
993 #define pdb_write_double be_write_double
994 #define pdb_read_double be_read_double
995 
996 /*
997  * Prototypes for generic conversion routines (util.c).
998  */
999 
1000 double ddmm2degrees(double ddmm_val);
1001 double degrees2ddmm(double deg_val);
1002 
1003 typedef enum {
1004   grid_unknown = -1,
1005   grid_lat_lon_ddd = 0,
1006   grid_lat_lon_dmm = 1,
1007   grid_lat_lon_dms = 2,
1008   grid_bng = 3,
1009   grid_utm = 4,
1010   grid_swiss = 5
1011 } grid_type;
1012 
1013 #define GRID_INDEX_MIN	grid_lat_lon_ddd
1014 #define GRID_INDEX_MAX	grid_swiss
1015 
1016 #define DATUM_OSGB36	86
1017 #define DATUM_WGS84	118
1018 
1019 /* bit manipulation functions (util.c) */
1020 
1021 char gb_getbit(const void* buf, const gbuint32 nr);
1022 void gb_setbit(void* buf, const gbuint32 nr);
1023 
1024 void* gb_int2ptr(const int i);
1025 int gb_ptr2int(const void* p);
1026 
1027 /*
1028  *  From parse.c
1029  */
1030 int parse_coordinates(const char* str, int datum, const grid_type grid,
1031                       double* latitude, double* longitude, const char* module);
1032 int parse_distance(const char* str, double* val, double scale, const char* module);
1033 int parse_speed(const char* str, double* val, const double scale, const char* module);
1034 time_t parse_date(const char* str, const char* format, const char* module);
1035 
1036 /*
1037  *  From util_crc.c
1038  */
1039 unsigned long get_crc32(const void* data, int datalen);
1040 unsigned long get_crc32_s(const void* data);
1041 
1042 /*
1043  *  From units.c
1044  */
1045 typedef enum {
1046   units_unknown = 0,
1047   units_statute = 1,
1048   units_metric = 2,
1049   units_nautical =3,
1050   units_aviation =4
1051 } fmt_units;
1052 
1053 int    fmt_setunits(fmt_units);
1054 double fmt_distance(const double, char** tag);
1055 double fmt_altitude(const double, char** tag);
1056 double fmt_speed(const double, char** tag);
1057 
1058 /*
1059  * From gbsleep.c
1060  */
1061 void gb_sleep(unsigned long microseconds);
1062 
1063 /*
1064  * From nmea.c
1065  */
1066 int nmea_cksum(const char* const buf);
1067 
1068 /*
1069  * Color helpers.
1070  */
1071 int color_to_bbggrr(const char* cname);
1072 
1073 /*
1074  * A constant for unknown altitude.   It's tempting to just use zero
1075  * but that's not very nice for the folks near sea level.
1076  */
1077 #define unknown_alt 	-99999999.0
1078 #define unknown_color	-1
1079 
1080 #endif /* gpsbabel_defs_h_included */
1081