/* Copyright (C) 2002 Robert Lipe, robertlipe@usa.net 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 */ #include "defs.h" #include "xmlgeneric.h" static char* deficon = NULL; static char* nuke_placer; static waypoint* wpt_tmp; static gbfile* ofd; static arglist_t geo_args[] = { {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, {"nuke_placer", &nuke_placer, "Omit Placer name", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, ARG_TERMINATOR }; #define MYNAME "geo" #define MY_CBUF 4096 #if ! HAVE_LIBEXPAT static void geo_rd_init(const char* fname) { fatal(MYNAME ": This build excluded GEO support because expat was not installed.\n"); } void geo_read(void) { } #else static xg_callback wpt_s, wpt_e; static xg_callback wpt_link_s, wpt_link; static xg_callback wpt_name, wpt_name_s, wpt_type, wpt_coord; static xg_callback wpt_diff, wpt_terr, wpt_container; static xg_tag_mapping loc_map[] = { { wpt_s, cb_start, "/loc/waypoint" }, { wpt_e, cb_end, "/loc/waypoint" }, { wpt_name_s, cb_start, "/loc/waypoint/name" }, { wpt_name, cb_cdata, "/loc/waypoint/name" }, { wpt_type, cb_cdata, "/loc/waypoint/type" }, { wpt_link_s, cb_start, "/loc/waypoint/link" }, { wpt_link, cb_cdata, "/loc/waypoint/link" }, { wpt_coord, cb_start, "/loc/waypoint/coord" }, { wpt_diff, cb_cdata, "/loc/waypoint/difficulty" }, { wpt_terr, cb_cdata, "/loc/waypoint/terrain" }, { wpt_container,cb_cdata, "/loc/waypoint/container" }, { NULL, (xg_cb_type)0, NULL } }; void wpt_s(const char* args, const char** unused) { wpt_tmp = waypt_new(); /* * 'geo' doesn't really have an 'unknown' and doesn't have any * concept of alt. Unfortunately, we have many reference files * that have leaked the 'unknown_alt' value into them, so we paper * over that here. */ wpt_tmp->altitude = 0; } void wpt_e(const char* args, const char** unused) { waypt_add(wpt_tmp); } void wpt_name_s(const char* args, const char** attrv) { const char** avp = &attrv[0]; while (*avp) { if (0 == strcmp(avp[0], "id")) { wpt_tmp->shortname = xstrdup(avp[1]); } avp+=2; } } void wpt_name(const char* args, const char** unused) { char* s; if (!args) { return; } wpt_tmp->description = xstrappend(wpt_tmp->description,args); s = xstrrstr(wpt_tmp->description, " by "); if (s) { waypt_alloc_gc_data(wpt_tmp)->placer = xstrdup(s + 4); if (nuke_placer) { *s = '\0'; } } } void wpt_link_s(const char* args, const char** attrv) { const char** avp = &attrv[0]; while (*avp) { if (0 == strcmp(avp[0], "text")) { wpt_tmp->url_link_text = xstrdup(avp[1]); } avp+=2; } } void wpt_link(const char* args, const char** attrv) { wpt_tmp->url = xstrdup(args); } void wpt_type(const char* args, const char** unused) { wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; wpt_tmp->icon_descr = xstrdup(args); } void wpt_coord(const char* args, const char** attrv) { const char** avp = &attrv[0]; while (*avp) { if (strcmp(avp[0], "lat") == 0) { sscanf(avp[1], "%lf", &wpt_tmp->latitude); } else if (strcmp(avp[0], "lon") == 0) { sscanf(avp[1], "%lf", &wpt_tmp->longitude); } avp+=2; } } void wpt_container(const char* args, const char** unused) { int v; if (!args) { return; } switch (atoi(args)) { case 1: v = gc_unknown; break; case 2: v = gc_micro; break; case 3: v = gc_regular; break; case 4: v = gc_large; break; case 5: v = gc_virtual;; break; case 6: v = gc_other; break; case 8: v = gc_small; break; default: v = gc_unknown; break; } waypt_alloc_gc_data(wpt_tmp)->container = v; } void wpt_diff(const char* args, const char** unused) { if (!args) { return; } waypt_alloc_gc_data(wpt_tmp)->diff = atof(args) * 10; } void wpt_terr(const char* args, const char** unused) { if (!args) { return; } waypt_alloc_gc_data(wpt_tmp)->terr = atof(args) * 10; } static void geo_rd_init(const char* fname) { xml_init(fname, loc_map, NULL); } static void geo_read(void) { xml_read(); } #endif static void geo_rd_deinit(void) { xml_deinit(); } static void geo_wr_init(const char* fname) { ofd = gbfopen(fname, "w", MYNAME); } static void geo_wr_deinit(void) { gbfclose(ofd); } static void geo_waypt_pr(const waypoint* waypointp) { char* tmp; gbfprintf(ofd, "\n"); gbfprintf(ofd, "", waypointp->shortname); gbfprintf(ofd, "", waypointp->description); gbfprintf(ofd, "\n"); gbfprintf(ofd, "", waypointp->latitude, waypointp->longitude); gbfprintf(ofd, "\n"); if (waypointp->icon_descr) { gbfprintf(ofd, "%s\n", deficon ? deficon : waypointp->icon_descr); } if (waypointp->url) { tmp = xml_entitize(waypointp->url); gbfprintf(ofd, "%s\n", tmp); xfree(tmp); } if (waypointp->gc_data && waypointp->gc_data->diff) { int v; gbfprintf(ofd, "%.1lf\n", waypointp->gc_data->diff / 10.0); gbfprintf(ofd, "%.1lf\n", waypointp->gc_data->terr / 10.0); switch (waypointp->gc_data->container) { case gc_unknown: v = 1; break; case gc_micro: v = 2; break; case gc_regular: v = 3; break; case gc_large: v = 4; break; case gc_virtual: v = 5; break; case gc_other: v = 6; break; case gc_small: v = 8; break; default: v = 1; break; } gbfprintf(ofd, "%d\n", v); } gbfprintf(ofd, "\n"); } static void geo_write(void) { gbfprintf(ofd, "\n"); waypt_disp_all(geo_waypt_pr); gbfprintf(ofd, "\n"); } ff_vecs_t geo_vecs = { ff_type_file, { (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none, ff_cap_none }, geo_rd_init, geo_wr_init, geo_rd_deinit, geo_wr_deinit, geo_read, geo_write, NULL, geo_args, CET_CHARSET_UTF8, 0 /* CET-REVIEW */ };