1 /*
2 Copyright (C) 2002 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 #include "defs.h"
20 #include "xmlgeneric.h"
21
22 static char* deficon = NULL;
23 static char* nuke_placer;
24
25 static waypoint* wpt_tmp;
26
27 static gbfile* ofd;
28
29 static
30 arglist_t geo_args[] = {
31 {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX },
32 {"nuke_placer", &nuke_placer, "Omit Placer name", NULL, ARGTYPE_BOOL, ARG_NOMINMAX },
33 ARG_TERMINATOR
34 };
35
36 #define MYNAME "geo"
37 #define MY_CBUF 4096
38
39 #if ! HAVE_LIBEXPAT
40 static void
geo_rd_init(const char * fname)41 geo_rd_init(const char* fname)
42 {
43 fatal(MYNAME ": This build excluded GEO support because expat was not installed.\n");
44 }
45
46 void
geo_read(void)47 geo_read(void)
48 {
49 }
50 #else
51
52 static xg_callback wpt_s, wpt_e;
53 static xg_callback wpt_link_s, wpt_link;
54 static xg_callback wpt_name, wpt_name_s, wpt_type, wpt_coord;
55 static xg_callback wpt_diff, wpt_terr, wpt_container;
56
57 static
58 xg_tag_mapping loc_map[] = {
59 { wpt_s, cb_start, "/loc/waypoint" },
60 { wpt_e, cb_end, "/loc/waypoint" },
61 { wpt_name_s, cb_start, "/loc/waypoint/name" },
62 { wpt_name, cb_cdata, "/loc/waypoint/name" },
63 { wpt_type, cb_cdata, "/loc/waypoint/type" },
64 { wpt_link_s, cb_start, "/loc/waypoint/link" },
65 { wpt_link, cb_cdata, "/loc/waypoint/link" },
66 { wpt_coord, cb_start, "/loc/waypoint/coord" },
67 { wpt_diff, cb_cdata, "/loc/waypoint/difficulty" },
68 { wpt_terr, cb_cdata, "/loc/waypoint/terrain" },
69 { wpt_container,cb_cdata, "/loc/waypoint/container" },
70 { NULL, (xg_cb_type)0, NULL }
71 };
72
wpt_s(const char * args,const char ** unused)73 void wpt_s(const char* args, const char** unused)
74 {
75 wpt_tmp = waypt_new();
76 /*
77 * 'geo' doesn't really have an 'unknown' and doesn't have any
78 * concept of alt. Unfortunately, we have many reference files
79 * that have leaked the 'unknown_alt' value into them, so we paper
80 * over that here.
81 */
82 wpt_tmp->altitude = 0;
83 }
84
wpt_e(const char * args,const char ** unused)85 void wpt_e(const char* args, const char** unused)
86 {
87 waypt_add(wpt_tmp);
88 }
89
wpt_name_s(const char * args,const char ** attrv)90 void wpt_name_s(const char* args, const char** attrv)
91 {
92 const char** avp = &attrv[0];
93 while (*avp) {
94 if (0 == strcmp(avp[0], "id")) {
95 wpt_tmp->shortname = xstrdup(avp[1]);
96 }
97 avp+=2;
98 }
99 }
100
wpt_name(const char * args,const char ** unused)101 void wpt_name(const char* args, const char** unused)
102 {
103 char* s;
104 if (!args) {
105 return;
106 }
107
108 wpt_tmp->description = xstrappend(wpt_tmp->description,args);
109 s = xstrrstr(wpt_tmp->description, " by ");
110 if (s) {
111 waypt_alloc_gc_data(wpt_tmp)->placer = xstrdup(s + 4);
112
113 if (nuke_placer) {
114 *s = '\0';
115 }
116 }
117 }
118
wpt_link_s(const char * args,const char ** attrv)119 void wpt_link_s(const char* args, const char** attrv)
120 {
121 const char** avp = &attrv[0];
122 while (*avp) {
123 if (0 == strcmp(avp[0], "text")) {
124 wpt_tmp->url_link_text = xstrdup(avp[1]);
125 }
126 avp+=2;
127 }
128 }
wpt_link(const char * args,const char ** attrv)129 void wpt_link(const char* args, const char** attrv)
130 {
131 wpt_tmp->url = xstrdup(args);
132 }
133
wpt_type(const char * args,const char ** unused)134 void wpt_type(const char* args, const char** unused)
135 {
136 wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1;
137 wpt_tmp->icon_descr = xstrdup(args);
138 }
139
wpt_coord(const char * args,const char ** attrv)140 void wpt_coord(const char* args, const char** attrv)
141 {
142 const char** avp = &attrv[0];
143
144 while (*avp) {
145 if (strcmp(avp[0], "lat") == 0) {
146 sscanf(avp[1], "%lf",
147 &wpt_tmp->latitude);
148 } else if (strcmp(avp[0], "lon") == 0) {
149 sscanf(avp[1], "%lf",
150 &wpt_tmp->longitude);
151 }
152 avp+=2;
153 }
154 }
155
wpt_container(const char * args,const char ** unused)156 void wpt_container(const char* args, const char** unused)
157 {
158 int v;
159
160 if (!args) {
161 return;
162 }
163 switch (atoi(args)) {
164 case 1:
165 v = gc_unknown;
166 break;
167 case 2:
168 v = gc_micro;
169 break;
170 case 3:
171 v = gc_regular;
172 break;
173 case 4:
174 v = gc_large;
175 break;
176 case 5:
177 v = gc_virtual;;
178 break;
179 case 6:
180 v = gc_other;
181 break;
182 case 8:
183 v = gc_small;
184 break;
185 default:
186 v = gc_unknown;
187 break;
188 }
189 waypt_alloc_gc_data(wpt_tmp)->container = v;
190 }
191
wpt_diff(const char * args,const char ** unused)192 void wpt_diff(const char* args, const char** unused)
193 {
194 if (!args) {
195 return;
196 }
197 waypt_alloc_gc_data(wpt_tmp)->diff = atof(args) * 10;
198 }
199
wpt_terr(const char * args,const char ** unused)200 void wpt_terr(const char* args, const char** unused)
201 {
202 if (!args) {
203 return;
204 }
205 waypt_alloc_gc_data(wpt_tmp)->terr = atof(args) * 10;
206 }
207
208 static void
geo_rd_init(const char * fname)209 geo_rd_init(const char* fname)
210 {
211 xml_init(fname, loc_map, NULL);
212 }
213
214 static void
geo_read(void)215 geo_read(void)
216 {
217 xml_read();
218 }
219 #endif
220
221 static void
geo_rd_deinit(void)222 geo_rd_deinit(void)
223 {
224 xml_deinit();
225 }
226
227 static void
geo_wr_init(const char * fname)228 geo_wr_init(const char* fname)
229 {
230 ofd = gbfopen(fname, "w", MYNAME);
231 }
232
233 static void
geo_wr_deinit(void)234 geo_wr_deinit(void)
235 {
236 gbfclose(ofd);
237 }
238
239 static void
geo_waypt_pr(const waypoint * waypointp)240 geo_waypt_pr(const waypoint* waypointp)
241 {
242 char* tmp;
243
244 gbfprintf(ofd, "<waypoint>\n");
245 gbfprintf(ofd, "<name id=\"%s\">", waypointp->shortname);
246 gbfprintf(ofd, "<![CDATA[%s]]>", waypointp->description);
247 gbfprintf(ofd, "</name>\n");
248
249 gbfprintf(ofd, "<coord lat=\"%lf\" lon=\"%lf\"/>",
250 waypointp->latitude,
251 waypointp->longitude);
252 gbfprintf(ofd, "\n");
253
254 if (waypointp->icon_descr) {
255 gbfprintf(ofd, "<type>%s</type>\n", deficon ? deficon : waypointp->icon_descr);
256 }
257 if (waypointp->url) {
258 tmp = xml_entitize(waypointp->url);
259 gbfprintf(ofd, "<link text =\"Cache Details\">%s</link>\n",
260 tmp);
261 xfree(tmp);
262 }
263 if (waypointp->gc_data && waypointp->gc_data->diff) {
264 int v;
265
266 gbfprintf(ofd, "<difficulty>%.1lf</difficulty>\n",
267 waypointp->gc_data->diff / 10.0);
268 gbfprintf(ofd, "<terrain>%.1lf</terrain>\n",
269 waypointp->gc_data->terr / 10.0);
270 switch (waypointp->gc_data->container) {
271 case gc_unknown:
272 v = 1;
273 break;
274 case gc_micro:
275 v = 2;
276 break;
277 case gc_regular:
278 v = 3;
279 break;
280 case gc_large:
281 v = 4;
282 break;
283 case gc_virtual:
284 v = 5;
285 break;
286 case gc_other:
287 v = 6;
288 break;
289 case gc_small:
290 v = 8;
291 break;
292 default:
293 v = 1;
294 break;
295 }
296 gbfprintf(ofd, "<container>%d</container>\n", v);
297 }
298 gbfprintf(ofd, "</waypoint>\n");
299 }
300
301 static void
geo_write(void)302 geo_write(void)
303 {
304 gbfprintf(ofd, "<?xml version=\"1.0\"?><loc version=\"1.0\" src=\"EasyGPS\">\n");
305 waypt_disp_all(geo_waypt_pr);
306 gbfprintf(ofd, "</loc>\n");
307 }
308
309 ff_vecs_t geo_vecs = {
310 ff_type_file,
311 { (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none, ff_cap_none },
312 geo_rd_init,
313 geo_wr_init,
314 geo_rd_deinit,
315 geo_wr_deinit,
316 geo_read,
317 geo_write,
318 NULL,
319 geo_args,
320 CET_CHARSET_UTF8, 0 /* CET-REVIEW */
321 };
322