Coverage Report

Created: 2026-06-30 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dcmtk/oficonv/libsrc/citrus_bcs.c
Line
Count
Source
1
/*-
2
 * Copyright (c)2003 Citrus Project,
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
 * SUCH DAMAGE.
25
 */
26
27
#include "dcmtk/config/osconfig.h"
28
#include "dcmtk/oficonv/iconv.h"
29
#include "citrus_bcs.h"
30
31
#include <stdlib.h>
32
#include <stdio.h>
33
#include <string.h>
34
35
char *oficonv_path = NULL;
36
37
0
void OFiconv_setpath(const char *runtime_path) {
38
0
    if (oficonv_path) {
39
0
        free(oficonv_path);
40
0
        oficonv_path = NULL;
41
0
    }
42
0
    if (runtime_path) {
43
0
        oficonv_path = strdup(runtime_path);
44
0
    }
45
0
}
46
47
/*
48
 * case insensitive comparison between two C strings.
49
 */
50
int
51
_citrus_bcs_strcasecmp(const char * str1,
52
    const char * str2)
53
0
{
54
0
    int c1, c2;
55
56
0
    c1 = c2 = 1;
57
58
0
    while (c1 && c2 && c1 == c2) {
59
0
        c1 = _citrus_bcs_toupper(*str1++);
60
0
        c2 = _citrus_bcs_toupper(*str2++);
61
0
    }
62
63
0
    return ((c1 == c2) ? 0 : ((c1 > c2) ? 1 : -1));
64
0
}
65
66
/*
67
 * case insensitive comparison between two C strings with limitation of length.
68
 */
69
int
70
_citrus_bcs_strncasecmp(const char * str1,
71
    const char * str2, size_t sz)
72
0
{
73
0
    int c1, c2;
74
75
0
    c1 = c2 = 1;
76
77
0
    while (c1 && c2 && c1 == c2 && sz != 0) {
78
0
        c1 = _citrus_bcs_toupper(*str1++);
79
0
        c2 = _citrus_bcs_toupper(*str2++);
80
0
        sz--;
81
0
    }
82
83
0
    return ((c1 == c2) ? 0 : ((c1 > c2) ? 1 : -1));
84
0
}
85
86
/*
87
 * skip white space characters.
88
 */
89
const char *
90
_citrus_bcs_skip_ws(const char * p)
91
0
{
92
93
0
    while (*p && _citrus_bcs_isspace(*p))
94
0
        p++;
95
96
0
    return (p);
97
0
}
98
99
/*
100
 * skip non white space characters.
101
 */
102
const char *
103
_citrus_bcs_skip_nonws(const char * p)
104
0
{
105
106
0
    while (*p && !_citrus_bcs_isspace(*p))
107
0
        p++;
108
109
0
    return (p);
110
0
}
111
112
/*
113
 * skip white space characters with limitation of length.
114
 */
115
const char *
116
_citrus_bcs_skip_ws_len(const char * p, size_t * len)
117
0
{
118
119
0
    while (*len > 0 && *p && _citrus_bcs_isspace(*p)) {
120
0
        p++;
121
0
        (*len)--;
122
0
    }
123
124
0
    return (p);
125
0
}
126
127
/*
128
 * skip non white space characters with limitation of length.
129
 */
130
const char *
131
_citrus_bcs_skip_nonws_len(const char * p, size_t * len)
132
0
{
133
134
0
    while (*len > 0 && *p && !_citrus_bcs_isspace(*p)) {
135
0
        p++;
136
0
        (*len)--;
137
0
    }
138
139
0
    return (p);
140
0
}
141
142
/*
143
 * truncate trailing white space characters.
144
 */
145
void
146
_citrus_bcs_trunc_rws_len(const char * p, size_t * len)
147
0
{
148
149
0
    while (*len > 0 && _citrus_bcs_isspace(p[*len - 1]))
150
0
        (*len)--;
151
0
}
152
153
/*
154
 * destructive transliterate to lowercase.
155
 */
156
void
157
_citrus_bcs_convert_to_lower(char *s)
158
0
{
159
160
0
    while (*s) {
161
0
        *s = _citrus_bcs_tolower(*s);
162
0
        s++;
163
0
    }
164
0
}
165
166
/*
167
 * destructive transliterate to uppercase.
168
 */
169
void
170
_citrus_bcs_convert_to_upper(char *s)
171
0
{
172
173
0
    while (*s) {
174
0
        *s = _citrus_bcs_toupper(*s);
175
0
        s++;
176
0
    }
177
0
}
178
179
/*
180
 * compute path to data file
181
 */
182
void get_data_path(char *path_out, size_t path_size, const char *dirname, const char *filename)
183
0
{
184
0
    const char *env;
185
0
    const char *separator1;
186
0
    const char *separator2;
187
0
    size_t len;
188
0
    char sep[3];
189
#ifdef HAVE_WINDOWS_H
190
    char buf[OFICONV_PATH_MAX+1];
191
    memset(buf, 0, sizeof(buf));
192
#endif
193
194
    // create a string containing the path separator
195
0
    snprintf(sep, sizeof(sep), "%c", PATH_SEPARATOR);
196
197
    // retrieve the DCMICONVPATH environment variable
198
0
    env = getenv(OFICONV_PATH_VARIABLE);
199
200
    // if the environment variable is not set, use the runtime oficonv path instead:
201
0
    if ( env == NULL && oficonv_path != NULL ) env = oficonv_path;
202
203
    // if the environment variable is not set, use DEFAULT_SUPPORT_DATA_DIR instead
204
0
    if (env == NULL) env = DEFAULT_SUPPORT_DATA_DIR;
205
206
#ifdef HAVE_WINDOWS_H
207
    (void) ExpandEnvironmentStringsA(env, buf, sizeof(buf));
208
    env = buf;
209
#endif
210
211
0
    len = strlen(env);
212
0
    if (len == 0) separator1 = ""; // empty path, don't add path separator
213
0
    else
214
0
    {
215
0
        if ((env[len-1] == PATH_SEPARATOR)||(env[len-1] == '/'))
216
0
            separator1 = ""; // path already ends with path separator
217
0
            else separator1 = sep; // add path separator
218
0
    }
219
220
    // use non-empty separator 2 only if filename is present and non-empty
221
0
    if (filename && (strlen(filename) > 0))
222
0
        separator2 = sep;
223
0
        else separator2 = "";
224
225
    // replace NULL filename with empty filename
226
0
    if (filename == NULL) filename = "";
227
228
    // finally print full path
229
0
    snprintf(path_out, path_size, "%s%s%s%s%s", env, separator1, dirname, separator2, filename);
230
0
}