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