Coverage Report

Created: 2025-07-14 06:48

/src/libyang/compat/compat.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file compat.c
3
 * @author Michal Vasko <mvasko@cesnet.cz>
4
 * @brief compatibility functions
5
 *
6
 * Copyright (c) 2020 CESNET, z.s.p.o.
7
 *
8
 * This source code is licensed under BSD 3-Clause License (the "License").
9
 * You may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     https://opensource.org/licenses/BSD-3-Clause
13
 */
14
#include "compat.h"
15
16
#define _POSIX_C_SOURCE 200809L /* fdopen, _POSIX_PATH_MAX, strdup */
17
#define _ISOC99_SOURCE /* vsnprintf */
18
19
#include <errno.h>
20
#include <limits.h>
21
#include <stdarg.h>
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
#include <unistd.h>
26
27
#ifndef HAVE_VDPRINTF
28
int
29
vdprintf(int fd, const char *format, va_list ap)
30
{
31
    FILE *stream;
32
    int count = 0;
33
34
    stream = fdopen(dup(fd), "a+");
35
    if (stream) {
36
        count = vfprintf(stream, format, ap);
37
        fclose(stream);
38
    }
39
    return count;
40
}
41
42
#endif
43
44
#ifndef HAVE_ASPRINTF
45
int
46
asprintf(char **strp, const char *fmt, ...)
47
{
48
    int ret;
49
    va_list ap;
50
51
    va_start(ap, fmt);
52
    ret = vasprintf(strp, fmt, ap);
53
    va_end(ap);
54
    return ret;
55
}
56
57
#endif
58
59
#ifndef HAVE_VASPRINTF
60
int
61
vasprintf(char **strp, const char *fmt, va_list ap)
62
{
63
    va_list ap2;
64
65
    va_copy(ap2, ap);
66
    int l = vsnprintf(0, 0, fmt, ap2);
67
68
    va_end(ap2);
69
70
    if ((l < 0) || !(*strp = malloc(l + 1U))) {
71
        return -1;
72
    }
73
74
    return vsnprintf(*strp, l + 1U, fmt, ap);
75
}
76
77
#endif
78
79
#ifndef HAVE_STRNDUP
80
char *
81
strndup(const char *s, size_t n)
82
{
83
    char *buf;
84
    size_t len = 0;
85
86
    /* strnlen */
87
    for ( ; (len < n) && (s[len] != '\0'); ++len) {}
88
89
    if (!(buf = malloc(len + 1U))) {
90
        return NULL;
91
    }
92
93
    memcpy(buf, s, len);
94
    buf[len] = '\0';
95
    return buf;
96
}
97
98
#endif
99
100
#ifndef HAVE_STRNSTR
101
char *
102
strnstr(const char *s, const char *find, size_t slen)
103
0
{
104
0
    char c, sc;
105
0
    size_t len;
106
107
0
    if ((c = *find++) != '\0') {
108
0
        len = strlen(find);
109
0
        do {
110
0
            do {
111
0
                if ((slen-- < 1) || ((sc = *s++) == '\0')) {
112
0
                    return NULL;
113
0
                }
114
0
            } while (sc != c);
115
0
            if (len > slen) {
116
0
                return NULL;
117
0
            }
118
0
        } while (strncmp(s, find, len));
119
0
        s--;
120
0
    }
121
0
    return (char *)s;
122
0
}
123
124
#endif
125
126
#ifndef HAVE_GETLINE
127
ssize_t
128
getline(char **lineptr, size_t *n, FILE *stream)
129
{
130
    static char line[256];
131
    char *ptr;
132
    ssize_t len;
133
134
    if (!lineptr || !n) {
135
        errno = EINVAL;
136
        return -1;
137
    }
138
139
    if (ferror(stream) || feof(stream)) {
140
        return -1;
141
    }
142
143
    if (!fgets(line, 256, stream)) {
144
        return -1;
145
    }
146
147
    ptr = strchr(line, '\n');
148
    if (ptr) {
149
        *ptr = '\0';
150
    }
151
152
    len = strlen(line);
153
154
    if (len + 1 < 256) {
155
        ptr = realloc(*lineptr, 256);
156
        if (!ptr) {
157
            return -1;
158
        }
159
        *lineptr = ptr;
160
        *n = 256;
161
    }
162
163
    strcpy(*lineptr, line);
164
    return len;
165
}
166
167
#endif
168
169
#ifndef HAVE_GET_CURRENT_DIR_NAME
170
char *
171
get_current_dir_name(void)
172
{
173
    char tmp[_POSIX_PATH_MAX];
174
    char *retval = NULL;
175
176
    if (getcwd(tmp, sizeof(tmp))) {
177
        retval = strdup(tmp);
178
        if (!retval) {
179
            errno = ENOMEM;
180
        }
181
    }
182
183
    return retval;
184
}
185
186
#endif