dpkg (1.18.25) stretch; urgency=medium
[dpkg] / lib / dpkg / string.c
CommitLineData
1479465f
GJ
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 */
39bool
40str_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 */
60char *
61str_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 */
82char *
83str_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 */
117char *
118str_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 */
143char *
144str_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}