5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2002 - 2008 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program 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.
20 #include "silcruntime.h"
22 /* Concatenates the `src' into `dest'. If `src_len' is more than the
23 size of the `dest' (minus NULL at the end) the `src' will be
26 char *silc_strncat(char *dest, SilcUInt32 dest_size,
27 const char *src, SilcUInt32 src_len)
31 dest[dest_size - 1] = '\0';
33 len = dest_size - 1 - strlen(dest);
36 strncat(dest, src, len);
38 strncat(dest, src, src_len);
44 /* Compares two strings. Strings may include wildcards '*' and '?'.
45 Returns TRUE if strings match. */
47 int silc_string_compare(char *string1, char *string2)
52 char *tmpstr1, *tmpstr2;
54 if (!string1 || !string2)
57 slen1 = strlen(string1);
58 slen2 = strlen(string2);
60 /* See if they are same already */
61 if (!strncmp(string1, string2, slen2) && slen2 == slen1)
65 if (!strchr(string1, '*'))
68 /* Take copies of the original strings as we will change them */
69 tmpstr1 = silc_calloc(slen1 + 1, sizeof(char));
70 memcpy(tmpstr1, string1, slen1);
71 tmpstr2 = silc_calloc(slen2 + 1, sizeof(char));
72 memcpy(tmpstr2, string2, slen2);
74 for (i = 0; i < slen1; i++) {
76 /* * wildcard. Only one * wildcard is possible. */
77 if (tmpstr1[i] == '*')
78 if (!strncmp(tmpstr1, tmpstr2, i)) {
79 memset(tmpstr2, 0, slen2);
80 strncpy(tmpstr2, tmpstr1, i);
85 if (tmpstr1[i] == '?') {
86 if (!strncmp(tmpstr1, tmpstr2, i)) {
88 if (tmpstr1[i + 1] != '?' &&
89 tmpstr1[i + 1] != tmpstr2[i + 1])
98 /* if using *, remove it */
99 if (strchr(tmpstr1, '*'))
100 *strchr(tmpstr1, '*') = 0;
102 if (!strcmp(tmpstr1, tmpstr2)) {
103 memset(tmpstr1, 0, slen1);
104 memset(tmpstr2, 0, slen2);
110 memset(tmpstr1, 0, slen1);
111 memset(tmpstr2, 0, slen2);
117 /* Splits a string containing separator `ch' and returns an array of the
120 char **silc_string_split(const char *string, char ch, int *ret_count)
122 char **splitted = NULL, sep[2], *item, *cp;
125 if (!string || !ret_count) {
126 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
130 splitted = silc_calloc(1, sizeof(*splitted));
134 if (!strchr(string, ch)) {
135 splitted[0] = silc_memdup(string, strlen(string));
144 len = strcspn(cp, sep);
148 item = silc_memdup(cp, len);
160 splitted[i++] = item;
163 splitted = silc_realloc(splitted, (i + 1) * sizeof(*splitted));
173 /* Inspects the `string' for wildcards and returns regex string that can
174 be used by the GNU regex library. A comma (`,') in the `string' means
175 that the string is list. */
177 char *silc_string_regexify(const char *string)
183 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
187 len = strlen(string);
189 for (i = 0; i < len; i++) {
190 if (string[i] == '*' || string[i] == '?')
191 count++; /* Will add '.' */
192 if (string[i] == ',')
193 count += 2; /* Will add '|' and '^' */
196 regex = silc_calloc(len + count + 1, sizeof(*regex));
201 regex[count++] = '(';
202 regex[count++] = '^';
204 for (i = 0; i < len; i++) {
205 if (string[i] == '*' || string[i] == '?') {
208 } else if (string[i] == ',') {
211 regex[count++] = '|';
212 regex[count++] = '^';
216 regex[count++] = string[i];
219 regex[count++] = ')';
225 /* Combines two regex strings into one regex string so that they can be
226 used as one by the GNU regex library. The `string2' is combine into
229 char *silc_string_regex_combine(const char *string1, const char *string2)
234 if (!string1 || !string2) {
235 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
239 len1 = strlen(string1);
240 len2 = strlen(string2);
242 tmp = silc_calloc(2 + len1 + len2, sizeof(*tmp));
243 strncat(tmp, string1, len1 - 2);
244 strncat(tmp, "|", 1);
245 strncat(tmp, string2 + 1, len2 - 1);
250 /* Do regex match to the two strings `string1' and `string2'. If the
251 `string2' matches the `string1' this returns TRUE. */
253 int silc_string_match(const char *string1, const char *string2)
258 if (!string1 || !string2) {
259 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
263 s1 = silc_string_regexify(string1);
264 ret = silc_string_regex_match(s1, string2);