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