1 /* $XTermId: xstrings.c,v 1.37 2010/04/04 22:34:17 tom Exp $ */
3 /************************************************************
5 Copyright 2000-2009,2010 by Thomas E. Dickey
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice shall be included
18 in all copies or substantial portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
24 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 Except as contained in this notice, the name(s) of the above copyright
29 holders shall not be used in advertising or otherwise to promote the
30 sale, use or other dealings in this Software without prior written
33 ********************************************************/
37 #include <sys/types.h>
45 x_basename(char *name)
49 cp = strrchr(name, '/');
52 cp = strrchr(name, '\\');
54 return (cp ? cp + 1 : name);
58 * Decode a hexadecimal string, returning the decoded string.
59 * On return, 'next' points to the first character not part of the input.
60 * The caller must free the result.
63 x_decode_hex(const char *source, const char **next)
69 for (pass = 0; pass < 2; ++pass) {
70 for (j = k = 0; isxdigit(CharOf(source[j])); ++j) {
71 if ((pass != 0) && (j & 1) != 0) {
72 result[k++] = (char) ((x_hex2int(source[j - 1]) << 4)
73 | x_hex2int(source[j]));
83 break; /* not enough memory */
86 break; /* must have an even number of digits */
93 * Encode a string into hexadecimal, returning the encoded string.
94 * The caller must free the result.
97 x_encode_hex(const char *source)
99 size_t need = (strlen(source) * 2) + 1;
100 char *result = malloc(need);
104 for (j = k = 0; source[j] != '\0'; ++j) {
105 sprintf(result + k, "%02X", CharOf(source[j]));
113 x_getenv(const char *name)
115 return x_strdup(x_nonempty(getenv(name)));
119 * Decode a single hex "nibble", returning the nibble as 0-15, or -1 on error.
123 if (c >= '0' && c <= '9')
125 if (c >= 'a' && c <= 'f')
127 if (c >= 'A' && c <= 'F')
133 * Check if the given string is nonnull/nonempty. If so, return a pointer
134 * to the beginning of its content, otherwise return null.
143 s = x_skip_blanks(s);
152 x_skip_blanks(String s)
154 while (isspace(CharOf(*s)))
160 x_skip_nonblanks(String s)
162 while (*s != '\0' && !isspace(CharOf(*s)))
168 x_strcasecmp(const char *s1, const char *s2)
170 size_t len = strlen(s1);
172 if (len != strlen(s2))
175 return x_strncasecmp(s1, s2, (unsigned) len);
179 x_strncasecmp(const char *s1, const char *s2, unsigned n)
182 char c1 = x_toupper(*s1);
183 char c2 = x_toupper(*s2);
195 * Allocates a copy of a string
198 x_strdup(const char *s)
203 char *t = CastMallocN(char, strlen(s));
213 * Returns a pointer to the first occurrence of s2 in s1,
214 * or NULL if there are none.
217 x_strindex(char *s1, const char *s2)
220 size_t s2len = strlen(s2);
222 while ((s3 = strchr(s1, *s2)) != NULL) {
223 if (strncmp(s3, s2, s2len) == 0)
231 * Trims leading/trailing spaces from a copy of the string.
234 x_strtrim(const char *source)
240 if (source != 0 && *source != '\0') {
241 char *t = x_strdup(source);
244 while (isspace(CharOf(*s)))
246 while ((*d++ = *s++) != '\0') {
251 while (s != t && isspace(CharOf(s[-1]))) {
257 result = x_strdup("");
263 * Avoid using system locale for upper/lowercase conversion, since there are
264 * a few locales where toupper(tolower(c)) != c.
269 static char table[256];
270 char result = table[CharOf(ch)];
272 if (result == '\0') {
274 const char *s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
276 for (n = 0; n < sizeof(table); ++n) {
279 for (n = 0; s[n] != '\0'; ++n) {
280 table[CharOf(s[n])] = s[n % 26];
282 result = table[CharOf(ch)];