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