dpkg (1.18.25) stretch; urgency=medium
[dpkg] / lib / dpkg / string.c
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 /**
32 * Match the end of a string.
33 *
34 * @param str The string.
35 * @param end The end to match in str.
36 *
37 * @return Whether the string was matched at the end.
38 */
39 bool
40 str_match_end(const char *str, const char *end)
41 {
42 size_t str_len = strlen(str);
43 size_t end_len = strlen(end);
44 const char *str_end = str + str_len - end_len;
45
46 if (str_len >= end_len && strcmp(str_end, end) == 0)
47 return true;
48 else
49 return false;
50 }
51
52 /**
53 * Print formatted output to an allocated string.
54 *
55 * @param fmt The format string.
56 * @param ... The format arguments.
57 *
58 * @return The new allocated formatted output string (never NULL).
59 */
60 char *
61 str_fmt(const char *fmt, ...)
62 {
63 va_list args;
64 char *str;
65
66 va_start(args, fmt);
67 m_vasprintf(&str, fmt, args);
68 va_end(args);
69
70 return str;
71 }
72
73 /**
74 * Escape format characters from a string.
75 *
76 * @param dst The destination string.
77 * @param src The source string.
78 * @param n The size of the destination buffer.
79 *
80 * @return The end of the destination string.
81 */
82 char *
83 str_escape_fmt(char *dst, const char *src, size_t n)
84 {
85 char *d = dst;
86 const char *s = src;
87
88 if (n == 0)
89 return d;
90
91 while (*s) {
92 if (*s == '%') {
93 if (n-- <= 2)
94 break;
95 *d++ = '%';
96 }
97 if (n-- <= 1)
98 break;
99 *d++ = *s++;
100 }
101
102 *d = '\0';
103
104 return d;
105 }
106
107 /**
108 * Quote shell metacharacters in a string.
109 *
110 * This function allows passing strings to commands without splitting the
111 * arguments, like in system(3)
112 *
113 * @param src The source string to escape.
114 *
115 * @return The new allocated string (never NULL).
116 */
117 char *
118 str_quote_meta(const char *src)
119 {
120 char *new_dst, *dst;
121
122 new_dst = dst = m_malloc(strlen(src) * 2);
123
124 while (*src) {
125 if (!c_isdigit(*src) && !c_isalpha(*src))
126 *dst++ = '\\';
127
128 *dst++ = *src++;
129 }
130
131 *dst = '\0';
132
133 return new_dst;
134 }
135
136 /**
137 * Check and strip possible surrounding quotes in string.
138 *
139 * @param str The string to act on.
140 *
141 * @return A pointer to str or NULL if the quotes were unbalanced.
142 */
143 char *
144 str_strip_quotes(char *str)
145 {
146 if (str[0] == '"' || str[0] == '\'') {
147 size_t str_len = strlen(str);
148
149 if (str[0] != str[str_len - 1])
150 return NULL;
151
152 /* Remove surrounding quotes. */
153 str[str_len - 1] = '\0';
154 str++;
155 }
156
157 return str;
158 }