Coverage Report

Created: 2025-07-07 10:01

/work/workdir/UnpackedTarball/libexttextcat/src/common.c
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* 
3
 * common.c -- miscellanious helper functions.
4
 *
5
 * Copyright (c) 2003, WiseGuys Internet B.V.
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * - Redistributions of source code must retain the above copyright
13
 * notice, this list of conditions and the following disclaimer.
14
 *
15
 * - Redistributions in binary form must reproduce the above copyright
16
 * notice, this list of conditions and the following disclaimer in the
17
 * documentation and/or other materials provided with the
18
 * distribution.
19
 *
20
 * - Neither the name of the WiseGuys Internet B.V. nor the names of
21
 * its contributors may be used to endorse or promote products derived
22
 * from this software without specific prior written permission.
23
 *
24
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
 */
36
#ifdef HAVE_CONFIG_H
37
#include "config.h"
38
#endif
39
#include <stdio.h>
40
#include <string.h>
41
#include <stdarg.h>
42
#include <ctype.h>
43
#include "common_impl.h"
44
45
extern char *wg_getline(char *line, int size, FILE * fp)
46
0
{
47
0
    char *p;
48
49
0
    if (fgets(line, size, fp) == NULL)
50
0
    {
51
0
        return NULL;
52
0
    }
53
54
        /** kill term null **/
55
0
    if ((p = strpbrk(line, "\n\r")))
56
0
    {
57
0
        *p = '\0';
58
0
    }
59
60
0
    return line;
61
0
}
62
63
64
65
/* 
66
 * wg_split: split a line into segments, using whitespace-sequences as separators.
67
 *
68
 * ARGUMENTS:
69
 * - result:
70
 *
71
 *  After the split, this array contains pointers to the start of each
72
 *  detected segment. Must be preallocated and at least as large as
73
 *  maxsegments. The pointers point into the dest buffer.
74
 *
75
 * - dest:
76
 *
77
 *  String into which result points as an index. Must be preallocated, and
78
 *  at least as big as src. You can use src as dest, but in that case src
79
 *  is overwritten!
80
 *
81
 * - src:
82
 *
83
 *  The string to split. Sequences of whitespace are treated as separators, unless
84
 *  escaped. There are two ways to escape: by using single quotes (anything
85
 *  between single quotes is treated as one segment), or by using a backslash
86
 *  to escape the next character. The backslash escape works inside quotation
87
 *  as well.
88
 *
89
 *  Example:
90
 *
91
 *  "It\'s   very\ easy   'to  use WiseGuys\' wg_split()' function" is split into:
92
 *
93
 *  "It's"
94
 *  "very easy"
95
 *  "to  use WiseGuys' wg_split()"
96
 *  "function"
97
 *
98
 * - maxsegments:
99
 *
100
 *  The maximum number of segments. If the splitter runs out of segments,
101
 *  the remainder of the string is stored in the last segment.
102
 *
103
 * RETURN VALUE:
104
 * The number of segments found.
105
 */
106
unsigned int wg_split(char **result, char *dest, char *src, int maxsegments)
107
0
{
108
0
    char *p = src;
109
0
    char *w = dest;
110
0
    int cnt = 0;
111
0
    int state = 0;
112
113
0
    if (maxsegments == 0)
114
0
    {
115
0
        return 0;
116
0
    }
117
118
0
    maxsegments--;
119
120
0
    while (cnt < maxsegments && *p)
121
0
    {
122
123
0
        switch (state)
124
0
        {
125
0
        case 0:
126
            /*** Skip spaces ***/
127
0
            while (isspace((unsigned char)*p))
128
0
            {
129
0
                p++;
130
0
            }
131
132
            /*** Start segment ***/
133
0
            result[cnt] = w;
134
0
            cnt++;
135
0
            state = 1;
136
137
            /*** fall through **/
138
139
0
        case 1:
140
            /*** Unquoted segment ***/
141
0
            while (*p)
142
0
            {
143
0
                if (isspace((unsigned char)*p))
144
0
                {
145
0
                    *w++ = '\0';
146
0
                    p++;
147
0
                    state = 0;
148
0
                    break;
149
0
                }
150
0
                else if (*p == '\'')
151
0
                {
152
                    /*** Start quotation ***/
153
0
                    p++;
154
0
                    state = 2;
155
0
                    break;
156
0
                }
157
0
                else if (*p == '\\' && p[1])
158
0
                {
159
                    /*** Escape ***/
160
0
                    p++;
161
0
                    *w++ = *p++;
162
0
                }
163
0
                else
164
0
                {
165
0
                    *w++ = *p++;
166
0
                }
167
0
            }
168
0
            break;
169
170
0
        case 2:
171
            /*** Inside quotes ***/
172
0
            while (*p)
173
0
            {
174
0
                if (*p == '\'')
175
0
                {
176
0
                    p++;
177
0
                    break;
178
0
                }
179
0
                else if (*p == '\\' && p[1])
180
0
                {
181
                    /*** Escape ***/
182
0
                    p++;
183
0
                    *w++ = *p++;
184
0
                }
185
0
                else
186
0
                {
187
0
                    *w++ = *p++;
188
0
                }
189
0
            }
190
0
            state = 1;
191
0
            break;
192
193
0
        }
194
0
    }
195
196
0
    if (!*p)
197
0
    {
198
0
        *w = '\0';
199
0
        return cnt;
200
0
    }
201
202
    /*** We ran out of segments; copy the remainder of the string into last segment ***/
203
0
    result[cnt++] = w;
204
0
    while (*p)
205
0
    {
206
0
        *w++ = *p++;
207
0
    }
208
0
    *w = '\0';
209
0
    return cnt;
210
0
}
211
212
/**
213
 * wg_strgmov -- a guarded strcpy() variation
214
 *
215
 * copies src to dest (including terminating zero), and returns
216
 * pointer to position of terminating zero in dest. The function is
217
 * guaranteed not to write past destlimit. If the copy couldn't be
218
 * finished, the function returns NULL after restoring the first
219
 * character in dest for your convenience (since this is usually a zero).
220
 */
221
char *wg_strgmov(char *dest, const char *src, const char *destlimit)
222
0
{
223
0
    char tmp, *w;
224
225
0
    if (!dest || dest >= destlimit)
226
0
    {
227
0
        return NULL;
228
0
    }
229
230
0
    tmp = *dest;
231
0
    w = dest;
232
233
0
    while (*src)
234
0
    {
235
236
0
        *w++ = *src++;
237
238
0
        if (w == destlimit)
239
0
        {
240
            /*** restore old situation ***/
241
0
            *dest = tmp;
242
0
            return NULL;
243
0
        }
244
0
    }
245
246
0
    *w = '\0';
247
0
    return w;
248
249
0
}
250
251
/* 
252
 * wg_trim() -- remove whitespace surrounding a string.
253
 *
254
 * Example: "   bla   bla   bla   " becomes "bla   bla   bla" after trimming.
255
 *
256
 * ARGUMENTS
257
 * - dest : After the trim, this will point to the trimmed string.
258
 *          Must be preallocated and at least as big as src. You can
259
 *          use src as dest.
260
 * - src : Points to the string to be trimmed.
261
 *
262
 * RETURNS:
263
 * dest
264
 */
265
char *wg_trim(char *dest, const char *src)
266
0
{
267
0
    char *lastnonspace = &dest[-1];
268
0
    const char *p = src;
269
0
    char *w = dest;
270
271
0
    while (isspace((unsigned char)*p))
272
0
    {
273
0
        p++;
274
0
    }
275
0
    while (*p)
276
0
    {
277
0
        if (!isspace((unsigned char)*p))
278
0
        {
279
0
            lastnonspace = w;
280
0
        }
281
0
        *w++ = *p++;
282
0
    }
283
0
    lastnonspace[1] = '\0';
284
285
0
    return dest;
286
0
}
287
288
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */