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 : 30 : str_concat(char *dst, ...) 33 : : { 34 : : va_list args; 35 : : const char *src; 36 : : size_t len; 37 : : 38 : 30 : va_start(args, dst); 39 [ + + ]: 113 : while ((src = va_arg(args, const char *))) { 40 : 83 : len = strlen(src); 41 : 83 : memcpy(dst, src, len); 42 : 83 : dst += len; 43 : : } 44 : 30 : va_end(args); 45 : 30 : *dst = '\0'; 46 : : 47 : 30 : return dst; 48 : : } 49 : : 50 : : /** 51 : : * Match the end of a string. 52 : : * 53 : : * @param str The string. 54 : : * @param end The end to match in str. 55 : : * 56 : : * @return Whether the string was matched at the end. 57 : : */ 58 : : bool 59 : 6 : str_match_end(const char *str, const char *end) 60 : : { 61 : 6 : size_t str_len = strlen(str); 62 : 6 : size_t end_len = strlen(end); 63 : 6 : const char *str_end = str + str_len - end_len; 64 : : 65 [ + + + + ]: 6 : if (str_len >= end_len && strcmp(str_end, end) == 0) 66 : 3 : return true; 67 : : else 68 : 3 : return false; 69 : : } 70 : : 71 : : /** 72 : : * Print formatted output to an allocated string. 73 : : * 74 : : * @param fmt The format string. 75 : : * @param ... The format arguments. 76 : : * 77 : : * @return The new allocated formatted output string (never NULL). 78 : : */ 79 : : char * 80 : 1579 : str_fmt(const char *fmt, ...) 81 : : { 82 : : va_list args; 83 : : char *str; 84 : : 85 : 1579 : va_start(args, fmt); 86 : 1579 : m_vasprintf(&str, fmt, args); 87 : 1579 : va_end(args); 88 : : 89 : 1579 : return str; 90 : : } 91 : : 92 : : /** 93 : : * Escape format characters from a string. 94 : : * 95 : : * @param dst The destination string. 96 : : * @param src The source string. 97 : : * @param n The size of the destination buffer. 98 : : * 99 : : * @return The end of the destination string. 100 : : */ 101 : : char * 102 : 8 : str_escape_fmt(char *dst, const char *src, size_t n) 103 : : { 104 : 8 : char *d = dst; 105 : 8 : const char *s = src; 106 : : 107 [ + + ]: 8 : if (n == 0) 108 : 1 : return d; 109 : : 110 [ + + ]: 24 : while (*s) { 111 [ + + ]: 20 : if (*s == '%') { 112 [ + + ]: 15 : if (n-- <= 2) 113 : 2 : break; 114 : 13 : *d++ = '%'; 115 : : } 116 [ + + ]: 18 : if (n-- <= 1) 117 : 1 : break; 118 : 17 : *d++ = *s++; 119 : : } 120 : : 121 : 7 : *d = '\0'; 122 : : 123 : 7 : return d; 124 : : } 125 : : 126 : : /** 127 : : * Quote shell metacharacters in a string. 128 : : * 129 : : * This function allows passing strings to commands without splitting the 130 : : * arguments, like in system(3) 131 : : * 132 : : * @param src The source string to escape. 133 : : * 134 : : * @return The new allocated string (never NULL). 135 : : */ 136 : : char * 137 : 3 : str_quote_meta(const char *src) 138 : : { 139 : : char *new_dst, *dst; 140 : : 141 : 3 : new_dst = dst = m_malloc(strlen(src) * 2); 142 : : 143 [ + + ]: 30 : while (*src) { 144 [ + + + + ]: 27 : if (!c_isdigit(*src) && !c_isalpha(*src)) 145 : 3 : *dst++ = '\\'; 146 : : 147 : 27 : *dst++ = *src++; 148 : : } 149 : : 150 : 3 : *dst = '\0'; 151 : : 152 : 3 : return new_dst; 153 : : } 154 : : 155 : : /** 156 : : * Check and strip possible surrounding quotes in string. 157 : : * 158 : : * @param str The string to act on. 159 : : * 160 : : * @return A pointer to str or NULL if the quotes were unbalanced. 161 : : */ 162 : : char * 163 : 9 : str_strip_quotes(char *str) 164 : : { 165 [ + + + + ]: 9 : if (str[0] == '"' || str[0] == '\'') { 166 : 6 : size_t str_len = strlen(str); 167 : : 168 [ + + ]: 6 : if (str[0] != str[str_len - 1]) 169 : 4 : return NULL; 170 : : 171 : : /* Remove surrounding quotes. */ 172 : 2 : str[str_len - 1] = '\0'; 173 : 2 : str++; 174 : : } 175 : : 176 : 5 : return str; 177 : : } 178 : : 179 : : /** 180 : : * Trim possible ending spaces in string. 181 : : * 182 : : * @param str The string to act on. 183 : : * @param str_end The end of the string to act on. 184 : : * 185 : : * @return A pointer to the end of the trimmed string. 186 : : */ 187 : : char * 188 : 158 : str_rtrim_spaces(const char *str, char *str_end) 189 : : { 190 [ + + + + ]: 176 : while (str_end > str && c_isspace(str_end[-1])) 191 : 18 : str_end--; 192 [ + - ]: 158 : if (str_end >= str) 193 : 158 : *str_end = '\0'; 194 : 158 : return str_end; 195 : : }