From 12d7f9b45303fb458cb21a3e0e430af96c781d8b Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 24 Mar 2025 22:58:14 +0100 Subject: First commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- libgeome_get_from_file.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 libgeome_get_from_file.c (limited to 'libgeome_get_from_file.c') diff --git a/libgeome_get_from_file.c b/libgeome_get_from_file.c new file mode 100644 index 0000000..bbed448 --- /dev/null +++ b/libgeome_get_from_file.c @@ -0,0 +1,95 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +static int +parse(char *s, struct location *location) +{ + errno = 0; + + location->latitude = strtod(s, &s); + if (errno) + return -1; + + while (isspace(*s)) + s++; + if (*s == ',' || *s == ':') + s++; + while (isspace(*s)) + s++; + + location->longitude = strtod(s, &s); + if (errno) + return -1; + + while (isspace(*s) && *s != '\n') + s++; + + return (*s && *s != '\n') ? -1 : 0; +} + + +int +libgeome_get_from_file(struct libgeome_context *ctx, struct libgeome_data *out, const char *path) +{ + struct location location; + FILE *f; + char *line = NULL; + size_t size = 0; + int r; + + if (!path) + path = GEOFILE; + + f = fopen(path, "r"); + if (!f) { + if (errno == ENOENT) + ctx->print_debug(ctx, "fopen %s r: %s\n", path, strerror(errno)); + else + ctx->print_error(ctx, "fopen %s r: %s\n", path, strerror(errno)); + return 1; + } + +again: + if (getline(&line, &size, f) < 0) { + if (feof(f)) { + ctx->print_debug(ctx, "%s is empty\n", path, strerror(errno)); + } else { + if (errno == EINTR) { + clearerr(f); + goto again; + } + ctx->print_error(ctx, "getline %s: %s\n", path, strerror(errno)); + } + fclose(f); + free(line); + return 1; + } + + fclose(f); + + r = parse(line, &location); + free(line); + if (!r) { + if (!isfinite(location.latitude) || !isfinite(location.longitude)) + r = -1; + else if (location.latitude < -90 || location.latitude > 90) + r = -1; + else if (location.longitude < -180 || location.longitude > 180) + r = -1; + } + if (r) { + ctx->print_debug(ctx, "the first line of %s was not a coordinate pair\n", path, strerror(errno)); + return 1; + } + + out->requested_data &= LIBGEOME_DATUM_LATITUDE | LIBGEOME_DATUM_LONGITUDE; + if (out->requested_data) { + if (out->requested_data & LIBGEOME_DATUM_LATITUDE) + out->latitude = location.latitude; + if (out->requested_data & LIBGEOME_DATUM_LONGITUDE) + out->longitude = location.longitude; + } + + return 0; +} -- cgit v1.2.3-70-g09d2