Branch data Line data Source code
1 : : /*
2 : : * libdpkg - Debian packaging suite library routines
3 : : * string.c - string handling routines
4 : : *
5 : : * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 : : * Copyright © 2008-2015 Guillem Jover <guillem@debian.org>
7 : : *
8 : : * This is free software; you can redistribute it and/or modify
9 : : * it under the terms of the GNU General Public License as published by
10 : : * the Free Software Foundation; either version 2 of the License, or
11 : : * (at your option) any later version.
12 : : *
13 : : * This is distributed in the hope that it will be useful,
14 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : : * GNU General Public License for more details.
17 : : *
18 : : * You should have received a copy of the GNU General Public License
19 : : * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 : : */
21 : :
22 : : #include <config.h>
23 : : #include <compat.h>
24 : :
25 : : #include <string.h>
26 : :
27 : : #include <dpkg/c-ctype.h>
28 : : #include <dpkg/string.h>
29 : : #include <dpkg/dpkg.h>
30 : :
31 : : char *
32 : 38 : str_concat(char *dst, ...)
33 : : {
34 : : va_list args;
35 : : const char *src;
36 : :
37 : 38 : va_start(args, dst);
38 [ + + ]: 145 : while ((src = va_arg(args, const char *))) {
39 : : size_t len;
40 : :
41 : 107 : len = strlen(src);
42 : 107 : memcpy(dst, src, len);
43 : 107 : dst += len;
44 : : }
45 : 38 : va_end(args);
46 : 38 : *dst = '\0';
47 : :
48 : 38 : return dst;
49 : : }
50 : :
51 : : /**
52 : : * Match the end of a string.
53 : : *
54 : : * @param str The string.
55 : : * @param end The end to match in str.
56 : : *
57 : : * @return Whether the string was matched at the end.
58 : : */
59 : : bool
60 : 6 : str_match_end(const char *str, const char *end)
61 : : {
62 : 6 : size_t str_len = strlen(str);
63 : 6 : size_t end_len = strlen(end);
64 : 6 : const char *str_end = str + str_len - end_len;
65 : :
66 [ + + + + ]: 6 : if (str_len >= end_len && strcmp(str_end, end) == 0)
67 : 3 : return true;
68 : : else
69 : 3 : return false;
70 : : }
71 : :
72 : : /**
73 : : * Print formatted output to an allocated string.
74 : : *
75 : : * @param fmt The format string.
76 : : * @param ... The format arguments.
77 : : *
78 : : * @return The new allocated formatted output string (never NULL).
79 : : */
80 : : char *
81 : 1718 : str_fmt(const char *fmt, ...)
82 : : {
83 : : va_list args;
84 : : char *str;
85 : :
86 : 1718 : va_start(args, fmt);
87 : 1718 : m_vasprintf(&str, fmt, args);
88 : 1718 : va_end(args);
89 : :
90 : 1718 : return str;
91 : : }
92 : :
93 : : /**
94 : : * Escape format characters from a string.
95 : : *
96 : : * @param dst The destination string.
97 : : * @param src The source string.
98 : : * @param n The size of the destination buffer.
99 : : *
100 : : * @return The end of the destination string.
101 : : */
102 : : char *
103 : 8 : str_escape_fmt(char *dst, const char *src, size_t n)
104 : : {
105 : 8 : char *d = dst;
106 : 8 : const char *s = src;
107 : :
108 [ + + ]: 8 : if (n == 0)
109 : 1 : return d;
110 : :
111 [ + + ]: 24 : while (*s) {
112 [ + + ]: 20 : if (*s == '%') {
113 [ + + ]: 15 : if (n-- <= 2)
114 : 2 : break;
115 : 13 : *d++ = '%';
116 : : }
117 [ + + ]: 18 : if (n-- <= 1)
118 : 1 : break;
119 : 17 : *d++ = *s++;
120 : : }
121 : :
122 : 7 : *d = '\0';
123 : :
124 : 7 : return d;
125 : : }
126 : :
127 : : /**
128 : : * Quote shell metacharacters in a string.
129 : : *
130 : : * This function allows passing strings to commands without splitting the
131 : : * arguments, like in system(3)
132 : : *
133 : : * @param src The source string to escape.
134 : : *
135 : : * @return The new allocated string (never NULL).
136 : : */
137 : : char *
138 : 3 : str_quote_meta(const char *src)
139 : : {
140 : : char *new_dst, *dst;
141 : :
142 : 3 : new_dst = dst = m_malloc(strlen(src) * 2);
143 : :
144 [ + + ]: 30 : while (*src) {
145 [ + + + + ]: 27 : if (!c_isdigit(*src) && !c_isalpha(*src))
146 : 3 : *dst++ = '\\';
147 : :
148 : 27 : *dst++ = *src++;
149 : : }
150 : :
151 : 3 : *dst = '\0';
152 : :
153 : 3 : return new_dst;
154 : : }
155 : :
156 : : /**
157 : : * Check and strip possible surrounding quotes in string.
158 : : *
159 : : * @param str The string to act on.
160 : : *
161 : : * @return A pointer to str or NULL if the quotes were unbalanced.
162 : : */
163 : : char *
164 : 9 : str_strip_quotes(char *str)
165 : : {
166 [ + + + + ]: 9 : if (str[0] == '"' || str[0] == '\'') {
167 : 6 : size_t str_len = strlen(str);
168 : :
169 [ + + ]: 6 : if (str[0] != str[str_len - 1])
170 : 4 : return NULL;
171 : :
172 : : /* Remove surrounding quotes. */
173 : 2 : str[str_len - 1] = '\0';
174 : 2 : str++;
175 : : }
176 : :
177 : 5 : return str;
178 : : }
179 : :
180 : : /**
181 : : * Trim possible ending spaces in string.
182 : : *
183 : : * @param str The string to act on.
184 : : * @param str_end The end of the string to act on.
185 : : *
186 : : * @return A pointer to the end of the trimmed string.
187 : : */
188 : : char *
189 : 158 : str_rtrim_spaces(const char *str, char *str_end)
190 : : {
191 [ + + + + ]: 176 : while (str_end > str && c_isspace(str_end[-1]))
192 : 18 : str_end--;
193 [ + - ]: 158 : if (str_end >= str)
194 : 158 : *str_end = '\0';
195 : 158 : return str_end;
196 : : }
|