Coverage Report

Created: 2025-06-13 06:29

/src/proj/src/rtodms.cpp
Line
Count
Source (jump to first uncovered line)
1
/* Convert radian argument to DMS ascii format */
2
3
#include <math.h>
4
#include <stddef.h>
5
#include <stdio.h>
6
#include <string.h>
7
8
#include "proj.h"
9
#include "proj_internal.h"
10
11
/*
12
** RES is fractional second figures
13
** RES60 = 60 * RES
14
** CONV = 180 * 3600 * RES / PI (radians to RES seconds)
15
*/
16
static double RES = 1000., RES60 = 60000., CONV = 206264806.24709635516;
17
static char format[50] = "%dd%d'%.3f\"%c";
18
static int dolong = 0;
19
0
void set_rtodms(int fract, int con_w) {
20
0
    int i;
21
22
0
    if (fract >= 0 && fract < 9) {
23
0
        RES = 1.;
24
        /* following not very elegant, but used infrequently */
25
0
        for (i = 0; i < fract; ++i)
26
0
            RES *= 10.;
27
0
        RES60 = RES * 60.;
28
0
        CONV = 180. * 3600. * RES / M_PI;
29
0
        if (!con_w)
30
0
            (void)snprintf(format, sizeof(format), "%%dd%%d'%%.%df\"%%c",
31
0
                           fract);
32
0
        else
33
0
            (void)snprintf(format, sizeof(format), "%%dd%%02d'%%0%d.%df\"%%c",
34
0
                           fract + 2 + (fract ? 1 : 0), fract);
35
0
        dolong = con_w;
36
0
    }
37
0
}
38
0
char *rtodms(char *s, size_t sizeof_s, double r, int pos, int neg) {
39
0
    int deg, min, sign;
40
0
    char *ss = s;
41
0
    double sec;
42
0
    size_t sizeof_ss = sizeof_s;
43
44
0
    if (r < 0) {
45
0
        r = -r;
46
0
        if (!pos) {
47
0
            if (sizeof_s == 1) {
48
0
                *s = 0;
49
0
                return s;
50
0
            }
51
0
            sizeof_ss--;
52
0
            *ss++ = '-';
53
0
            sign = 0;
54
0
        } else
55
0
            sign = neg;
56
0
    } else
57
0
        sign = pos;
58
0
    r = floor(r * CONV + .5);
59
0
    sec = fmod(r / RES, 60.);
60
0
    r = floor(r / RES60);
61
0
    min = (int)fmod(r, 60.);
62
0
    r = floor(r / 60.);
63
0
    deg = (int)r;
64
65
0
    if (dolong)
66
0
        (void)snprintf(ss, sizeof_ss, format, deg, min, sec, sign);
67
0
    else if (sec != 0.0) {
68
0
        char *p, *q;
69
        /* double prime + pos/neg suffix (if included) + NUL */
70
0
        size_t suffix_len = sign ? 3 : 2;
71
72
0
        (void)snprintf(ss, sizeof_ss, format, deg, min, sec, sign);
73
        /* Replace potential decimal comma by decimal point for non C locale */
74
0
        for (p = ss; *p != '\0'; ++p) {
75
0
            if (*p == ',') {
76
0
                *p = '.';
77
0
                break;
78
0
            }
79
0
        }
80
0
        if (suffix_len > strlen(ss))
81
0
            return s;
82
0
        for (q = p = ss + strlen(ss) - suffix_len; *p == '0'; --p)
83
0
            ;
84
0
        if (*p != '.')
85
0
            ++p;
86
0
        if (++q != p)
87
0
            (void)memmove(p, q, suffix_len);
88
0
    } else if (min)
89
0
        (void)snprintf(ss, sizeof_ss, "%dd%d'%c", deg, min, sign);
90
0
    else
91
0
        (void)snprintf(ss, sizeof_ss, "%dd%c", deg, sign);
92
0
    return s;
93
0
}