2 * gpsdclient.c -- support functions for GPSD clients
4 * This file is Copyright (c) 2010 by the GPSD project
5 * BSD terms apply: see the file COPYING in the distribution root for details.
11 #endif /* S_SPLINT_S */
19 #include "gpsd_config.h"
21 #include "gpsdclient.h"
27 /* convert double degrees to a static string and return a pointer to it
30 * deg_dd : return DD.dddddd
31 * deg_ddmm : return DD MM.mmmm'
32 * deg_ddmmss : return DD MM' SS.sss"
35 /*@observer@*/ char *deg_to_str(enum deg_str_type type, double f)
38 int dsec, sec, deg, min;
40 double fdsec, fsec, fdeg, fmin;
42 if (f < 0 || f > 360) {
43 (void)strlcpy(str, "nan", 40);
47 fmin = modf(f, &fdeg);
49 frac_deg = (long)(fmin * 1000000);
53 (void)snprintf(str, sizeof(str), "%3d.%06ld", deg, frac_deg);
56 fsec = modf(fmin * 60, &fmin);
58 sec = (int)(fsec * 10000.0);
60 if (deg_ddmm == type) {
62 (void)snprintf(str, sizeof(str), "%3d %02d.%04d'", deg, min, sec);
65 /* else DD MM SS.sss */
66 fdsec = modf(fsec * 60, &fsec);
68 dsec = (int)(fdsec * 1000.0);
69 (void)snprintf(str, sizeof(str), "%3d %02d' %02d.%03d\"", deg, min, sec,
76 * check the environment to determine proper GPS units
78 * clients should only call this if no user preference is specified on
79 * the command line or via X resources.
81 * return imperial - Use miles/feet
82 * nautical - Use knots/feet
83 * metric - Use km/meters
84 * unspecified - use compiled default
86 * In order check these environment vars:
88 * imperial = miles/feet
89 * nautical = knots/feet
100 * [other] = km/meters
102 * if none found then return compiled in default
104 enum unit gpsd_units(void)
108 #ifdef HAVE_SETLOCALE
109 (void)setlocale(LC_NUMERIC, "C");
111 if ((envu = getenv("GPSD_UNITS")) != NULL && *envu != '\0') {
112 if (0 == strcasecmp(envu, "imperial")) {
115 if (0 == strcasecmp(envu, "nautical")) {
118 if (0 == strcasecmp(envu, "metric")) {
121 /* unrecognized, ignore it */
123 if (((envu = getenv("LC_MEASUREMENT")) != NULL && *envu != '\0')
124 || ((envu = getenv("LANG")) != NULL && *envu != '\0')) {
125 if (strncasecmp(envu, "en_US", 5) == 0
126 || strcasecmp(envu, "C") == 0 || strcasecmp(envu, "POSIX") == 0) {
129 /* Other, must be metric */
132 /* TODO: allow a compile time default here */
136 /*@ -observertrans -statictrans -mustfreeonly -branchstate -kepttrans @*/
137 void gpsd_source_spec(const char *arg, struct fixsource_t *source)
138 /* standard parsing of a GPS data source spec */
140 source->server = "localhost";
141 source->port = DEFAULT_GPSD_PORT;
142 source->device = NULL;
144 /*@-usedef@ Sigh, splint is buggy */
146 char *colon1, *skipto, *rbrk;
147 source->spec = strdup(arg);
148 assert(source->spec != NULL);
150 skipto = source->spec;
151 if (*skipto == '[' && (rbrk = strchr(skipto, ']')) != NULL) {
154 colon1 = strchr(skipto, ':');
156 if (colon1 != NULL) {
159 if (colon1 != source->spec) {
160 source->server = source->spec;
162 source->port = colon1 + 1;
163 colon2 = strchr(source->port, ':');
164 if (colon2 != NULL) {
166 source->device = colon2 + 1;
168 } else if (strchr(source->spec, '/') != NULL) {
169 source->device = source->spec;
171 source->server = source->spec;
176 if (*source->server == '[') {
177 char *rbrk = strchr(source->server, ']');
186 /*@ +observertrans -statictrans +mustfreeonly +branchstate +kepttrans @*/
188 /* gpsclient.c ends here */