Esempio n. 1
0
static void 
osm_node(const char *args, const char **attrv)
{
	const char **avp = &attrv[0];

	wpt = waypt_new();

        while (*avp) {
		if (strcmp(avp[0], "id") == 0) {
			xasprintf(&wpt->description, "osm-id %s", avp[1]);
			if (! avltree_insert(waypoints, avp[1], (void *)wpt))
				warning(MYNAME ": Duplicate osm-id %s!\n", avp[1]);
			else
				wpt->wpt_flags.fmt_use = 1;
		}
		else if (strcmp(avp[0], "user") == 0) ;
		else if (strcmp(avp[0], "lat") == 0)
			wpt->latitude = atof(avp[1]);
		else if (strcmp(avp[0], "lon") == 0)
			wpt->longitude = atof(avp[1]);
		else if (strcmp(avp[0], "timestamp") == 0)
			wpt->creation_time = xml_parse_time(avp[1], &wpt->microseconds);

		avp += 2;
	}
}
Esempio n. 2
0
static void
xol_shape(const char *args, const char **attrv)
{
	const char **avp = &attrv[0];

        while (*avp) {
		if (strcmp(avp[0], "type") == 0) {
			if (strcmp(avp[1], "waypoint") == 0) {
				wpt = waypt_new();
			}
			else if (strcmp(avp[1], "polyline") == 0) {
				trk = route_head_alloc();
				track_add_head(trk);
			}
		}
		else if (strcmp(avp[0], "name") == 0) {
			if (wpt) wpt->shortname = xstrdup(avp[1]);
			else if (trk) trk->rte_name = xstrdup(avp[1]);
		}
		else if (strcmp(avp[0], "comment") == 0) {
			if (wpt) wpt->notes = xstrdup(avp[1]);
		}
		else if (strcmp(avp[0], "alt") == 0) {
			if (wpt) wpt->altitude = atof(avp[1]);
		}
		else if (strcmp(avp[0], "timestamp") == 0) {
			if (wpt) wpt->creation_time = xml_parse_time(avp[1], &wpt->microseconds);
		}
		else if (strcmp(avp[0], "icon") == 0) {
			if (wpt) {
				wpt->icon_descr = xstrdup(avp[1]);
				wpt->wpt_flags.icon_descr_is_dynamic = 1;
			}
		}

		avp+=2;
	}
}
Esempio n. 3
0
/**
 * Parse a directory tree from the given XML source into the given index data structure.
 * @param reader the XML source
 * @param parent Directory where the new subdirectory should be created, or NULL to populate the
 *               root dentry.
 * @param idx LTFS index data
 * @param vol LTFS volume to which the index belongs. May be NULL.
 * @return 0 on success or a negative value on error
 */
int _xml_parse_dirtree(xmlTextReaderPtr reader, struct dentry *parent,
	struct ltfs_index *idx, struct ltfs_volume *vol, struct name_list *dirname)
{
	int ret;
	unsigned long long value_int;
	struct dentry *dir;
	declare_parser_vars("directory");
	declare_tracking_arrays(9, 1);

	if (! parent && idx->root) {
		dir = idx->root;
		dir->vol = vol;
	} else {
		dir = fs_allocate_dentry(parent, NULL, NULL, true, false, false, idx);
		if (! dir) {
			ltfsmsg(LTFS_ERR, "10001E", __FUNCTION__);
			return -LTFS_NO_MEMORY;
		}
		if (! parent) {
			idx->root = dir;
			dir->vol = vol;
			++dir->link_count;
		}
	}

	while (true) {
		get_next_tag();

		if (!strcmp(name, "name")) {
			check_required_tag(0);

			if (parent) {
				get_tag_text();
				if (xml_parse_filename(&dir->name, value) < 0)
					return -1;
				dirname->name = dir->name;
				dirname->d = dir;
				check_tag_end("name");
			} else {
				/* this is the root directory, so set the volume name */
				check_empty();
				if (empty > 0) {
					value = NULL;
				} else {
					if (xml_scan_text(reader, &value) < 0)
						return -1;
				}

				if (value && strlen(value) > 0) {
					if (xml_parse_filename(&idx->volume_name, value) < 0)
						return -1;
					/* if the value is the empty string, then xml_scan_text consumed the "name"
					 * element end */
					check_tag_end("name");
				} else
					idx->volume_name = NULL;
			}

		} else if (!strcmp(name, "readonly")) {
			check_required_tag(1);
			get_tag_text();
			if (xml_parse_bool(&dir->readonly, value) < 0)
				return -1;
			check_tag_end("readonly");

		} else if (!strcmp(name, "modifytime")) {
			check_required_tag(2);
			get_tag_text();
			ret = xml_parse_time(true, value, &dir->modify_time);
			if (ret < 0)
				return -1;
			else if (ret == LTFS_TIME_OUT_OF_RANGE)
				ltfsmsg(LTFS_WARN, "17220W", "updatetime", dir->name, dir->uid, value);

			check_tag_end("modifytime");

		} else if (!strcmp(name, "creationtime")) {
			check_required_tag(3);
			get_tag_text();
			ret = xml_parse_time(true, value, &dir->creation_time);
			if (ret < 0)
				return -1;
			else if (ret == LTFS_TIME_OUT_OF_RANGE)
				ltfsmsg(LTFS_WARN, "17220W", "creationtime", dir->name, dir->uid, value);

			check_tag_end("creationtime");

		} else if (!strcmp(name, "accesstime")) {
			check_required_tag(4);
			get_tag_text();
			ret = xml_parse_time(true, value, &dir->access_time);
			if (ret < 0)
				return -1;
			else if (ret == LTFS_TIME_OUT_OF_RANGE)
				ltfsmsg(LTFS_WARN, "17220W", "accesstime", dir->name, dir->uid, value);

			check_tag_end("accesstime");

		} else if (!strcmp(name, "changetime")) {
			check_required_tag(5);
			get_tag_text();
			ret = xml_parse_time(true, value, &dir->change_time);
			if (ret < 0)
				return -1;
			else if (ret == LTFS_TIME_OUT_OF_RANGE)
				ltfsmsg(LTFS_WARN, "17220W", "changetime", dir->name, dir->uid, value);

			check_tag_end("changetime");

		} else if (! strcmp(name, "contents")) {
			check_required_tag(6);
			check_empty();
			if (empty == 0 && (ret = _xml_parse_dir_contents(reader, dir, idx)) < 0) {
				if (ret == -LTFS_NO_MEMORY)
					return ret;
				else
					return -1;
			}

		} else if (!strcmp(name, "extendedattributes")) {
			check_optional_tag(0);
			check_empty();
			if (empty == 0 && _xml_parse_xattrs(reader, dir) < 0)
					return -1;

		} else if (idx->version >= IDX_VERSION_UID && ! strcmp(name, UID_TAGNAME)) {
			check_required_tag(7);
			get_tag_text();
			if (xml_parse_ull(&value_int, value) < 0)
				return -1;
			dir->uid = value_int;
			if (dir->uid > idx->uid_number)
				idx->uid_number = dir->uid;
			if (parent) {
				dirname->uid  = dir->uid;
			}
			check_tag_end(UID_TAGNAME);
		} else if (! strcmp(name, UID_TAGNAME)) {
			ignore_unrecognized_tag();

		} else if (idx->version >= IDX_VERSION_BACKUPTIME && ! strcmp(name, BACKUPTIME_TAGNAME)) {
			check_required_tag(8);
			get_tag_text();
			ret = xml_parse_time(true, value, &dir->backup_time);
			if (ret < 0)
				return -1;
			else if (ret == LTFS_TIME_OUT_OF_RANGE)
				ltfsmsg(LTFS_WARN, "17220W", "backuptime", dir->name, dir->uid, value);

			check_tag_end(BACKUPTIME_TAGNAME);
		} else if (! strcmp(name, BACKUPTIME_TAGNAME)) {
			ignore_unrecognized_tag();

		} else
			preserve_unrecognized_tag(dir);
	}

	/* For old index versions, allocate a UID */
	if (idx->version < IDX_VERSION_UID) {
		check_required_tag(7);
		if (parent) {
			dir->uid = fs_allocate_uid(idx);
			if (dir->uid > idx->uid_number)
				idx->uid_number = dir->uid;
			dirname->uid  = dir->uid;
		}
		/* root directory already got assigned UID 1 by fs_allocate_dentry */
	}

	/* For old index versions, set backup time equal to creation time */
	if (idx->version < IDX_VERSION_BACKUPTIME) {
		check_required_tag(8);
		dir->backup_time = dir->creation_time;
	}

	check_required_tags();

	/* Validate UID: root directory must have uid==1, other dentries must have nonzero UID */
	/* TODO: would be nice to verify that there are no UID conflicts */
	if (parent && dir->uid == 1) {
		ltfsmsg(LTFS_ERR, "17101E");
		return -1;
	} else if (! parent && dir->uid != 1) {
		ltfsmsg(LTFS_ERR, "17100E");
		return -1;
	} else if (dir->uid == 0) {
		ltfsmsg(LTFS_ERR, "17106E");
		return -1;
	}

	return 0;
}
Esempio n. 4
0
/**
 * Parse an index file from the given source and populate the priv->root virtual dentry tree.
 * with the nodes found during the scanning.
 * @param reader Source of XML data
 * @param idx LTFS index
 * @param vol LTFS volume to which the index belongs. May be NULL.
 * @return 0 on success or a negative value on error.
 */
int _xml_parse_schema(xmlTextReaderPtr reader, struct ltfs_index *idx, struct ltfs_volume *vol)
{
	int ret;
	unsigned long long value_int;
	declare_parser_vars("ltfsindex");
	declare_tracking_arrays(8, 3);

	/* start the parser: find top-level "index" tag, check version and encoding */
	ret = _xml_parser_init(reader, parent_tag, &idx->version,
						   LTFS_INDEX_VERSION_MIN, LTFS_INDEX_VERSION_MAX);
	if (ret < 0)
		return ret;

	if (idx->version < LTFS_INDEX_VERSION)
		ltfsmsg(LTFS_WARN, "17095W",
				LTFS_INDEX_VERSION_STR,
				LTFS_FORMAT_MAJOR(idx->version),
				LTFS_FORMAT_MINOR(idx->version),
				LTFS_FORMAT_REVISION(idx->version));
	else if (idx->version / 100 > LTFS_INDEX_VERSION / 100)
		ltfsmsg(LTFS_WARN, "17096W",
				LTFS_INDEX_VERSION_STR,
				LTFS_FORMAT_MAJOR(idx->version),
				LTFS_FORMAT_MINOR(idx->version),
				LTFS_FORMAT_REVISION(idx->version));
	else if (idx->version > LTFS_INDEX_VERSION)
		ltfsmsg(LTFS_WARN, "17234W",
				LTFS_INDEX_VERSION_STR,
				LTFS_FORMAT_MAJOR(idx->version),
				LTFS_FORMAT_MINOR(idx->version),
				LTFS_FORMAT_REVISION(idx->version));

	if (idx->commit_message) {
		free(idx->commit_message);
		idx->commit_message = NULL;
	}

	/* parse index file contents */
	while (true) {
		get_next_tag();

		if (! strcmp(name, "creator")) {
			check_required_tag(0);
			get_tag_text();
			if (idx->creator)
				free(idx->creator);
			idx->creator = strdup(value);
			if (! idx->creator) {
				ltfsmsg(LTFS_ERR, "10001E", name);
				return -1;
			}
			check_tag_end("creator");

		} else if (! strcmp(name, "volumeuuid")) {
			check_required_tag(1);
			get_tag_text();
			if (xml_parse_uuid(idx->vol_uuid, value) < 0)
				return -1;
			check_tag_end("volumeuuid");

		} else if (! strcmp(name, "generationnumber")) {
			check_required_tag(2);
			get_tag_text();
			if (xml_parse_ull(&value_int, value) < 0) {
				ltfsmsg(LTFS_ERR, "17023E", value);
				return -1;
			}
			idx->generation = value_int;
			check_tag_end("generationnumber");

		} else if (! strcmp(name, "updatetime")) {
			check_required_tag(3);
			get_tag_text();
			ret = xml_parse_time(true, value, &idx->mod_time);
			if (ret < 0)
				return -1;
			else if (ret == LTFS_TIME_OUT_OF_RANGE)
				ltfsmsg(LTFS_WARN, "17219W", "updatetime", value);

			check_tag_end("updatetime");

		} else if (! strcmp(name, "location")) {
			check_required_tag(4);
			assert_not_empty();
			if (_xml_scan_tapepos(reader, "location", &idx->selfptr) < 0)
				return -1;

		} else if (! strcmp(name, "allowpolicyupdate")) {
			check_required_tag(5);
			get_tag_text();
			if (xml_parse_bool(&idx->criteria_allow_update, value) < 0)
				return -1;
			check_tag_end("allowpolicyupdate");

		} else if (! strcmp(name, "directory")) {
			check_required_tag(6);
			assert_not_empty();
			if ((ret = _xml_parse_dirtree(reader, NULL, idx, vol, NULL)) < 0) {
				if (ret == -LTFS_NO_MEMORY)
					return -LTFS_NO_MEMORY;
				else
					return -1;
			}

		} else if (! strcmp(name, "previousgenerationlocation")) {
			check_optional_tag(0);
			assert_not_empty();
			if (_xml_scan_tapepos(reader, "previousgenerationlocation", &idx->backptr) < 0)
				return -1;

		} else if (! strcmp(name, "dataplacementpolicy")) {
			check_optional_tag(1);
			assert_not_empty();
			if (_xml_parse_policy(reader, idx) < 0)
				return -1;

		} else if (! strcmp(name, "comment")) {
			check_optional_tag(2);
			get_tag_text();
			if (strlen(value) > INDEX_MAX_COMMENT_LEN) {
				ltfsmsg(LTFS_ERR, "17094E");
				return -1;
			}
			idx->commit_message = strdup(value);
			if (! idx->commit_message) {
				ltfsmsg(LTFS_ERR, "10001E", "_xml_parse_schema: index comment");
				return -1;
			}
			check_tag_end("comment");

		} else if (idx->version >= IDX_VERSION_UID && ! strcmp(name, NEXTUID_TAGNAME)) {
			check_required_tag(7);
			get_tag_text();
			if (xml_parse_ull(&value_int, value) < 0)
				return -1;
			if (value_int > idx->uid_number)
				idx->uid_number = value_int;
			check_tag_end(NEXTUID_TAGNAME);
		} else if (! strcmp(name, NEXTUID_TAGNAME)) {
			ignore_unrecognized_tag();

		} else
			preserve_unrecognized_tag(idx);
	}

	/* For older index versions, assume we handle UIDs correctly.
	 * The idx->uid_number field is automatically initialized to 1, so it will be set correctly
	 * once all files and directories are parsed. */
	if (idx->version < IDX_VERSION_UID)
		check_required_tag(7);

	check_required_tags();

	if ( idx->symerr_count != 0 ) {
		return -LTFS_SYMLINK_CONFLICT;
	}


	return 0;
}
Esempio n. 5
0
/**
 * Parse an XML label, populating the given label data structure.
 */
int _xml_parse_label(xmlTextReaderPtr reader, struct ltfs_label *label)
{
	int ret;
	unsigned long long value_int;
	declare_parser_vars("ltfslabel");
	declare_tracking_arrays(7, 0);

	/* start the parser: find top-level "label" tag, check version and encoding */
	if (_xml_parser_init(reader, parent_tag, &label->version,
		LTFS_LABEL_VERSION_MIN, LTFS_LABEL_VERSION_MAX) < 0)
		return -1;

	/* parse label contents */
	while (true) {
		get_next_tag();

		if (! strcmp(name, "creator")) {
			check_required_tag(0);
			get_tag_text();
			if (label->creator) {
				free(label->creator); 
				label->creator = NULL;
			}
			label->creator = strdup(value);
			if (! label->creator) {
				ltfsmsg(LTFS_ERR, "10001E", name);
				return -1;
			}
			check_tag_end("creator");

		} else if (! strcmp(name, "formattime")) {
			check_required_tag(1);
			get_tag_text();
			ret = xml_parse_time(true, value, &label->format_time);
			if (ret < 0)
				return -1;
			else if (ret == LTFS_TIME_OUT_OF_RANGE)
				ltfsmsg(LTFS_WARN, "17218W", "formattime", value);
			check_tag_end("formattime");

		} else if (! strcmp(name, "volumeuuid")) {
			check_required_tag(2);
			get_tag_text();
			if (xml_parse_uuid(label->vol_uuid, value) < 0)
				return -1;
			check_tag_end("volumeuuid");

		} else if (! strcmp(name, "location")) {
			check_required_tag(3);
			assert_not_empty();
			if (_xml_parse_label_location(reader, label) < 0)
				return -1;

		} else if (! strcmp(name, "partitions")) {
			check_required_tag(4);
			assert_not_empty();
			if (_xml_parse_partition_map(reader, label) < 0)
				return -1;

		} else if (! strcmp(name, "blocksize")) {
			check_required_tag(5);
			get_tag_text();
			if (xml_parse_ull(&value_int, value) < 0 || value_int == 0) {
				ltfsmsg(LTFS_ERR, "17022E", value);
				return -1;
			}
			label->blocksize = value_int;
			check_tag_end("blocksize");

		} else if (! strcmp(name, "compression")) {
			check_required_tag(6);
			get_tag_text();
			if (xml_parse_bool(&label->enable_compression, value) < 0)
				return -1;
			check_tag_end("compression");

		} else
			ignore_unrecognized_tag();
	}

	check_required_tags();
	return 0;
}
Esempio n. 6
0
void
gtc_trk_utc(const char *args, const char **unused)
{
	wpt_tmp->creation_time = xml_parse_time(args, NULL);
}
Esempio n. 7
0
static void
text_disp(const waypoint *wpt)
{
	int latint, lonint;
	char tbuf[1024];
	time_t tm = wpt->creation_time;
	gbint32 utmz;
	double utme, utmn;
	char utmzc;
	char *tmpout1, *tmpout2;
	char *altout;
	fs_xml *fs_gpx;

	waypoint_count++;
	
	if (split_output) {
		char *thisfname;
		xasprintf(&thisfname, "%s%d", output_name, waypoint_count);
		file_out = gbfopen(thisfname, "w", MYNAME);
	}
	
	lonint = abs((int) wpt->longitude);
	latint = abs((int) wpt->latitude);

	GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, 
		&utme, &utmn, &utmz, &utmzc);

	if (tm == 0) 
		tm = time(NULL);
	strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm));

	tmpout1 = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 0);
	if (wpt->altitude != unknown_alt) {
		xasprintf(&altout, " alt:%d", (int) ( (altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude) );
	}
	else {
		altout = "";
	}
	xasprintf (&tmpout2, "%s (%d%c %6.0f %7.0f)%s", tmpout1, utmz, utmzc, utme, utmn, altout );
	gbfprintf(file_out, "%-16s  %59s\n",
		(global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname,
		tmpout2);
	xfree(tmpout2);
	xfree(tmpout1);	
	if (altout[0]) 
		xfree(altout);
	

	if (strcmp(wpt->description, wpt->shortname)) {
		gbfprintf(file_out, "%s", wpt->description);
		if (wpt->gc_data->placer) 
			gbfprintf(file_out, " by %s", wpt->gc_data->placer);
		}
		if (wpt->gc_data->terr) {
			gbfprintf(file_out, " - %s / %s - (%d%s / %d%s)\n", 
				gs_get_cachetype(wpt->gc_data->type), gs_get_container(wpt->gc_data->container), 
				(int)(wpt->gc_data->diff / 10), (wpt->gc_data->diff%10)?".5":"", 
				(int)(wpt->gc_data->terr / 10), (wpt->gc_data->terr%10)?".5":""  ); 
	        if (wpt->gc_data->desc_short.utfstring) {
	                char *stripped_html = strip_html(&wpt->gc_data->desc_short);
			gbfprintf (file_out, "\n%s\n", stripped_html);
                	xfree(stripped_html);
       		}
	        if (wpt->gc_data->desc_long.utfstring) {
	                char *stripped_html = strip_html(&wpt->gc_data->desc_long);
			gbfprintf (file_out, "\n%s\n", stripped_html);
                	xfree(stripped_html);
       		}
		if (wpt->gc_data->hint) {
			char *hint = NULL;
			if ( txt_encrypt ) 
				hint = rot13( wpt->gc_data->hint );
			else
				hint = xstrdup( wpt->gc_data->hint );
			gbfprintf (file_out, "\nHint: %s\n", hint);
			xfree( hint );
		}
	}
	else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) {
		gbfprintf (file_out, "\n%s\n", wpt->notes);
	}

	fs_gpx = NULL;
	if ( includelogs ) {
		fs_gpx = (fs_xml *)fs_chain_find( wpt->fs, FS_GPX);
	}
	
	if ( fs_gpx && fs_gpx->tag ) {
		xml_tag *root = fs_gpx->tag;
		xml_tag *curlog = NULL;
		xml_tag *logpart = NULL;
		curlog = xml_findfirst( root, "groundspeak:log" );
		while ( curlog ) {
			time_t logtime = 0;
			struct tm *logtm = NULL;
			gbfprintf( file_out, "\n" );
			
			logpart = xml_findfirst( curlog, "groundspeak:type" );
			if ( logpart ) {
				gbfprintf( file_out, "%s by ", logpart->cdata );
			}
			
			logpart = xml_findfirst( curlog, "groundspeak:finder" );
			if ( logpart ) {
				gbfprintf( file_out, "%s on ", logpart->cdata );
			}
			
			logpart = xml_findfirst( curlog, "groundspeak:date" );
			if ( logpart ) {
				logtime = xml_parse_time( logpart->cdata, NULL);
				logtm = localtime( &logtime );
				if ( logtm ) {
					gbfprintf( file_out, 
						"%4.4d-%2.2d-%2.2d\n",
						logtm->tm_year+1900,
						logtm->tm_mon+1,
						logtm->tm_mday );
				}
			}
			
			logpart = xml_findfirst( curlog, "groundspeak:log_wpt" );
			if ( logpart ) {
				char *coordstr = NULL;
				float lat = 0;
				float lon = 0;
				coordstr = xml_attribute( logpart, "lat" );
				if ( coordstr ) {
					lat = atof( coordstr );
				}
			        coordstr = xml_attribute( logpart, "lon" );
				if ( coordstr ) {
					lon = atof( coordstr );
				}
				coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 0);
				gbfprintf( file_out, "%s\n", coordstr);
				xfree(coordstr);
			}
			
			logpart = xml_findfirst( curlog, "groundspeak:text" );
			if ( logpart ) {
				char *encstr = NULL;
				char *s = NULL;
				int encoded = 0;
				encstr = xml_attribute( logpart, "encoded" );
				encoded = (encstr[0] != 'F');
				
				if ( txt_encrypt && encoded ) {
					s = rot13( logpart->cdata );
				}
				else {
					s = xstrdup( logpart->cdata );
				}
					
				gbfprintf( file_out, "%s", s ); 
				xfree( s );
			}

			gbfprintf( file_out, "\n" );
			curlog = xml_findnext( root, curlog, "groundspeak:log" );
		}
	}
	if (! suppresssep) 
		gbfprintf(file_out, "\n-----------------------------------------------------------------------------\n");
	else
		gbfprintf(file_out, "\n");

	if (split_output) {
		gbfclose(file_out);
		file_out = NULL;
	}
}
Esempio n. 8
0
static void
unicsv_parse_one_line(char *ibuf)
{
	char *s;
	waypoint *wpt = NULL;
	int column;
	int  utm_zone = -9999;
	double utm_easting = 0;
	double utm_northing = 0;
	char utm_zc = 'N';
	char bng_zone[3] = "";
	double bng_easting = 0;
	double bng_northing = 0;
	double swiss_easting = unicsv_unknown;
	double swiss_northing = unicsv_unknown;
	int checked = 0;
	time_t date = -1, time = -1;
	int msec = -1;
	char is_localtime = 0;
	garmin_fs_t *gmsd;
	double d;
	struct tm ymd;
	int src_datum = unicsv_datum_idx;
	int ns = 1;
	int ew = 1;
#ifdef UNICSV_GC_READY
	geocache_data *gc_data = NULL;
#endif
	wpt = waypt_new();
	wpt->latitude = unicsv_unknown;
	wpt->longitude = unicsv_unknown;
	memset(&ymd, 0, sizeof(ymd));

	column = -1;
	while ((s = csv_lineparse(ibuf, unicsv_fieldsep, "\"", 0))) {

		if (column > unicsv_fields_tab_ct) break;	/* ignore extra fields on line */

		ibuf = NULL;

		column++;
		checked++;

		s = lrtrim(s);
		if (! *s) continue;	/* skip empty columns */
		switch(unicsv_fields_tab[column]) {

		case fld_time:
		case fld_date:
		case fld_datetime:
			/* switch column type if it looks like an iso time string */
			if (strchr(s, 'T'))
				unicsv_fields_tab[column] = fld_iso_time;
			break;
		default: ;
		}


		switch(unicsv_fields_tab[column]) {

		case fld_latitude:
			human_to_dec( s, &wpt->latitude, &wpt->longitude, 1 );
			wpt->latitude = wpt->latitude * ns;
			break;

		case fld_longitude:
			human_to_dec( s, &wpt->latitude, &wpt->longitude, 2 );
			wpt->longitude = wpt->longitude * ew;
			break;

		case fld_shortname:
			wpt->shortname = xstrdup(s);
			break;

		case fld_description:
			wpt->description = xstrdup(s);
			break;

		case fld_notes:
			wpt->notes = xstrdup(s);
			break;

		case fld_url:
			wpt->url = xstrdup(s);
			break;

		case fld_altitude:
			if (parse_distance(s, &d, unicsv_altscale, MYNAME)) {
				if (fabs(d) < fabs(unknown_alt))
					wpt->altitude = d;
			}
			break;

		case fld_utm_zone:
			utm_zone = atoi(s);
			break;

		case fld_utm_easting:
			utm_easting = atof(s);
			break;

		case fld_utm_northing:
			utm_northing = atof(s);
			break;

		case fld_utm_zone_char:
			utm_zc = toupper(s[0]);
			break;

		case fld_utm:
			parse_coordinates(s, unicsv_datum_idx, grid_utm,
				&wpt->latitude, &wpt->longitude, MYNAME);
			/* coordinates from parse_coordinates are in WGS84
			   don't convert a second time */
			src_datum = DATUM_WGS84;
			break;

		case fld_bng:
			parse_coordinates(s, DATUM_OSGB36, grid_bng,
				&wpt->latitude, &wpt->longitude, MYNAME);
			/* coordinates from parse_coordinates are in WGS84
			   don't convert a second time */
			src_datum = DATUM_WGS84;
			break;

		case fld_bng_zone:
			strncpy(bng_zone, s, sizeof(bng_zone));
			strupper(bng_zone);
			break;

		case fld_bng_northing:
			bng_northing = atof(s);
			break;

		case fld_bng_easting:
			bng_easting = atof(s);
			break;

		case fld_swiss:
			parse_coordinates(s, DATUM_WGS84, grid_swiss,
				&wpt->latitude, &wpt->longitude, MYNAME);
			/* coordinates from parse_coordinates are in WGS84
			   don't convert a second time */
			src_datum = DATUM_WGS84;
			break;

		case fld_swiss_easting:
			swiss_easting = atof(s);
			break;

		case fld_swiss_northing:
			swiss_northing = atof(s);
			break;

		case fld_hdop:
			wpt->hdop = atof(s);
			if (unicsv_detect) unicsv_data_type = trkdata;
			break;

		case fld_pdop:
			wpt->pdop = atof(s);
			if (unicsv_detect) unicsv_data_type = trkdata;
			break;

		case fld_vdop:
			wpt->vdop = atof(s);
			if (unicsv_detect) unicsv_data_type = trkdata;
			break;

		case fld_sat:
			wpt->sat = atoi(s);
			if (unicsv_detect) unicsv_data_type = trkdata;
			break;

		case fld_fix:
			if (unicsv_detect) unicsv_data_type = trkdata;
			if (case_ignore_strcmp(s, "none") == 0)
				wpt->fix = fix_none;
			else if (case_ignore_strcmp(s, "2d") == 0)
				wpt->fix = fix_2d;
			else if (case_ignore_strcmp(s, "3d") == 0)
				wpt->fix = fix_3d;
			else if (case_ignore_strcmp(s, "dgps") == 0)
				wpt->fix = fix_dgps;
			else if (case_ignore_strcmp(s, "pps") == 0)
				wpt->fix = fix_pps;
			else wpt->fix = fix_unknown;
			break;

		case fld_utc_date:
			if ((is_localtime < 2) && (date < 0)) {
				date = unicsv_parse_date(s, NULL);
				is_localtime = 0;
			}
			break;

		case fld_utc_time:
			if ((is_localtime < 2) && (time < 0)) {
				time = unicsv_parse_time(s, &msec, &date);
				is_localtime = 0;
			}
			break;

		case fld_speed:
			if (parse_speed(s, &d, 1.0, MYNAME)) {
				WAYPT_SET(wpt, speed, d);
				if (unicsv_detect)
					unicsv_data_type = trkdata;
			}
			break;

		case fld_course:
			WAYPT_SET(wpt, course, atof(s));
			if (unicsv_detect) unicsv_data_type = trkdata;
			break;

		case fld_temperature:
			d = atof(s);
			if (fabs(d) < 999999) WAYPT_SET(wpt, temperature, d);
			break;

		case fld_temperature_f:
			d = atof(s);
			if (fabs(d) < 999999) WAYPT_SET(wpt, temperature, FAHRENHEIT_TO_CELSIUS(d));
			break;

		case fld_heartrate:
			wpt->heartrate = atoi(s);
			if (unicsv_detect) unicsv_data_type = trkdata;
			break;

		case fld_cadence:
			wpt->cadence = atoi(s);
			if (unicsv_detect) unicsv_data_type = trkdata;
			break;

		case fld_proximity:
			if (parse_distance(s, &d, unicsv_proximityscale, MYNAME))
				WAYPT_SET(wpt, proximity, d);
			break;

		case fld_depth:
			if (parse_distance(s, &d, unicsv_depthscale, MYNAME))
				WAYPT_SET(wpt, depth, d);
			break;

		case fld_symbol:
			wpt->icon_descr = xstrdup(s);
			wpt->wpt_flags.icon_descr_is_dynamic = 1;
			break;

		case fld_iso_time:
			is_localtime = 2;	/* fix result */
			wpt->creation_time = xml_parse_time(s, &wpt->microseconds);
			break;

		case fld_time:
			if ((is_localtime < 2) && (time < 0)) {
				time = unicsv_parse_time(s, &msec, &date);
				is_localtime = 1;
			}
			break;

		case fld_date:
			if ((is_localtime < 2) && (date < 0)) {
				date = unicsv_parse_date(s, NULL);
				is_localtime = 1;
			}
			break;

		case fld_year:
			ymd.tm_year = atoi(s);
			break;

		case fld_month:
			ymd.tm_mon = atoi(s);
			break;

		case fld_day:
			ymd.tm_mday = atoi(s);
			break;

		case fld_hour:
			ymd.tm_hour = atoi(s);
			break;

		case fld_min:
			ymd.tm_min = atoi(s);
			break;

		case fld_sec:
			ymd.tm_sec = atoi(s);
			break;

		case fld_datetime:
			if ((is_localtime < 2) && (date < 0) && (time < 0)) {
				time = unicsv_parse_time(s, &msec, &date);
				is_localtime = 1;
			}
			break;

		case fld_ns:
			ns = tolower(s[0]) == 'n' ? 1 : -1;
			wpt->latitude *= ns;
			break;

		case fld_ew:
			ew = tolower(s[0]) == 'e' ? 1 : -1;
			wpt->longitude *= ew;
			break;

		case fld_garmin_city:
		case fld_garmin_postal_code:
		case fld_garmin_state:
		case fld_garmin_country:
		case fld_garmin_addr:
		case fld_garmin_phone_nr:
		case fld_garmin_phone_nr2:
		case fld_garmin_fax_nr:
		case fld_garmin_email:
		case fld_garmin_facility:
			gmsd = GMSD_FIND(wpt);
			if (! gmsd) {
				gmsd = garmin_fs_alloc(-1);
				fs_chain_add(&wpt->fs, (format_specific_data *) gmsd);
			}
			switch(unicsv_fields_tab[column]) {
			case fld_garmin_city: GMSD_SETSTR(city, s); break;
			case fld_garmin_postal_code: GMSD_SETSTR(postal_code, s); break;
			case fld_garmin_state: GMSD_SETSTR(state, s); break;
			case fld_garmin_country: GMSD_SETSTR(country, s); break;
			case fld_garmin_addr: GMSD_SETSTR(addr, s); break;
			case fld_garmin_phone_nr: GMSD_SETSTR(phone_nr, s); break;
			case fld_garmin_phone_nr2: GMSD_SETSTR(phone_nr2, s); break;
			case fld_garmin_fax_nr: GMSD_SETSTR(fax_nr, s); break;
			case fld_garmin_email: GMSD_SETSTR(email, s); break;
			case fld_garmin_facility: GMSD_SETSTR(facility, s); break;
			default: break;
			}
			break;
#ifdef UNICSV_GC_READY
		case fld_gc_id:
		case fld_gc_type:
		case fld_gc_container:
		case fld_gc_terr:
		case fld_gc_diff:
		case fld_gc_is_archived:
		case fld_gc_is_available:
		case fld_gc_exported:
		case fld_gc_last_found:
		case fld_gc_placer:
		case fld_gc_placer_id:
		case fld_gc_hint:

			gc_data = waypt_alloc_gc_data(wpt);

			switch(unicsv_fields_tab[column]) {

			case fld_gc_id:
				gc_data->id = atoi(s);
				if (gc_data->id == 0) gc_data->id = unicsv_parse_gc_id(s);
				break;
			case fld_gc_type: gc_data->type = gs_mktype(s); break;
			case fld_gc_container: gc_data->container = gs_mkcont(s); break;
			case fld_gc_terr: gc_data->terr = atof(s) * 10; break;
			case fld_gc_diff: gc_data->diff = atof(s) * 10; break;
			case fld_gc_is_archived: gc_data->is_archived = unicsv_parse_status(s); break;
			case fld_gc_is_available: gc_data->is_available = unicsv_parse_status(s); break;
			case fld_gc_exported: {
				time_t time, date; int msec;
				time = unicsv_parse_time(s, &msec, &date);
				if (date || time) gc_data->exported = unicsv_adjust_time(time, &date);
				}
				break;
			case fld_gc_last_found: {
				time_t time, date;
				int msec;
				time = unicsv_parse_time(s, &msec, &date);
				if (date || time) gc_data->last_found = unicsv_adjust_time(time, &date);
				}
				break;
			case fld_gc_placer: gc_data->placer = xstrdup(s); break;
			case fld_gc_placer_id: gc_data->placer_id = atoi(s); break;
			case fld_gc_hint: gc_data->hint = xstrdup(s); break;

			default: break;
			}
			break;
#endif
		case fld_terminator: /* dummy */
			checked--;
			break;
		}
	}

	if (checked == 0) {
		waypt_free(wpt);
		return;
	}

	if (is_localtime < 2) {	/* not fixed */
		if ((time >= 0) && (date >= 0)) {
			time_t t = date + time;

			if (is_localtime) {
				struct tm tm;
				tm = *gmtime(&t);
				if (opt_utc)
					wpt->creation_time = mkgmtime(&tm);
				else
					wpt->creation_time = mklocaltime(&tm);
			}
			else
				wpt->creation_time = t;
		}
		else if (time >= 0)
			wpt->creation_time = time;
		else if (date >= 0)
			wpt->creation_time = date;
		else if (ymd.tm_year || ymd.tm_mon || ymd.tm_mday) {
			if (ymd.tm_year < 100) {
				if (ymd.tm_year <= 70) ymd.tm_year += 2000;
				else ymd.tm_year += 1900;
			}
			ymd.tm_year -= 1900;

			if (ymd.tm_mon == 0) ymd.tm_mon = 1;
			if (ymd.tm_mday == 0) ymd.tm_mday = 1;

			ymd.tm_mon--;
			if (opt_utc)
				wpt->creation_time = mkgmtime(&ymd);
			else
				wpt->creation_time = mklocaltime(&ymd);
		}
		else if (ymd.tm_hour || ymd.tm_min || ymd.tm_sec) {
			if (opt_utc)
				wpt->creation_time = mkgmtime(&ymd);
			else
				wpt->creation_time = mklocaltime(&ymd);
		}

		if (msec >= 0)
			wpt->microseconds = msec;

		if (opt_utc)
			wpt->creation_time += atoi(opt_utc) * SECONDS_PER_HOUR;
	}

	/* utm/bng/swiss can be optional */

	if ((wpt->latitude == unicsv_unknown) && (wpt->longitude == unicsv_unknown)) {
		if (utm_zone != -9999) {
			GPS_Math_UTM_EN_To_Known_Datum(&wpt->latitude, &wpt->longitude,
				utm_easting, utm_northing, utm_zone, utm_zc, unicsv_datum_idx);
		}
		else if (bng_zone[0]) {
			if (! GPS_Math_UKOSMap_To_WGS84_M(
				bng_zone, bng_easting, bng_northing,
				&wpt->latitude, &wpt->longitude))
			fatal(MYNAME ": Unable to convert BNG coordinates (%s %.f %.f)!\n",
				bng_zone, bng_easting, bng_northing);
			src_datum = DATUM_WGS84;	/* don't convert afterwards */
		}
		else if ((swiss_easting != unicsv_unknown) && (swiss_northing != unicsv_unknown)) {
			GPS_Math_Swiss_EN_To_WGS84(swiss_easting, swiss_northing,
				&wpt->latitude, &wpt->longitude);
			src_datum = DATUM_WGS84;	/* don't convert afterwards */
		}
	}

	if ((src_datum != DATUM_WGS84) &&
	    (wpt->latitude != unicsv_unknown) && (wpt->longitude != unicsv_unknown)) {
		double alt;
		GPS_Math_Known_Datum_To_WGS84_M(wpt->latitude, wpt->longitude, (double) 0.0,
			&wpt->latitude, &wpt->longitude, &alt, src_datum);
	}

	switch(unicsv_data_type) {
	case rtedata:
		if (! unicsv_route) {
			unicsv_route = route_head_alloc();
			route_add_head(unicsv_route);
		}
		route_add_wpt(unicsv_route, wpt);
		break;
	case trkdata:
		if (! unicsv_track) {
			unicsv_track = route_head_alloc();
			track_add_head(unicsv_track);
		}
		track_add_wpt(unicsv_track, wpt);
		break;
	default:
		waypt_add(wpt);
	}
}
Esempio n. 9
0
void wpt_time(const char *args, const char **unused)
{
	wpt_tmp->creation_time = xml_parse_time(args, &wpt_tmp->microseconds);
}