+
+/* Splits a string containing separator `ch' and returns an array of the
+ splitted strings. */
+
+char **silc_string_split(const char *string, char ch, int *ret_count)
+{
+ char **splitted = NULL, sep[2], *item, *cp;
+ int i = 0, len;
+
+ if (!string || !ret_count) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return NULL;
+ }
+
+ splitted = silc_calloc(1, sizeof(*splitted));
+ if (!splitted)
+ return NULL;
+
+ if (!strchr(string, ch)) {
+ splitted[0] = silc_memdup(string, strlen(string));
+ *ret_count = 1;
+ return splitted;
+ }
+
+ sep[0] = ch;
+ sep[1] = '\0';
+ cp = (char *)string;
+ while (cp) {
+ len = strcspn(cp, sep);
+ if (!len)
+ break;
+
+ item = silc_memdup(cp, len);
+ if (!item) {
+ silc_free(splitted);
+ return NULL;
+ }
+
+ cp += len;
+ if (strlen(cp) == 0)
+ cp = NULL;
+ else
+ cp++;
+
+ splitted[i++] = item;
+
+ if (cp) {
+ splitted = silc_realloc(splitted, (i + 1) * sizeof(*splitted));
+ if (!splitted)
+ return NULL;
+ }
+ }
+ *ret_count = i;
+
+ return splitted;
+}
+
+/* Inspects the `string' for wildcards and returns regex string that can
+ be used by the GNU regex library. A comma (`,') in the `string' means
+ that the string is list. */
+
+char *silc_string_regexify(const char *string)
+{
+ int i, len, count;
+ char *regex;
+
+ if (!string) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return NULL;
+ }
+
+ len = strlen(string);
+ count = 4;
+ for (i = 0; i < len; i++) {
+ if (string[i] == '*' || string[i] == '?')
+ count++; /* Will add '.' */
+ if (string[i] == ',')
+ count += 2; /* Will add '|' and '^' */
+ }
+
+ regex = silc_calloc(len + count + 1, sizeof(*regex));
+ if (!regex)
+ return NULL;
+
+ count = 0;
+ regex[count++] = '(';
+ regex[count++] = '^';
+
+ for (i = 0; i < len; i++) {
+ if (string[i] == '*' || string[i] == '?') {
+ regex[count] = '.';
+ count++;
+ } else if (string[i] == ',') {
+ if (i + 2 == len)
+ continue;
+ regex[count++] = '|';
+ regex[count++] = '^';
+ continue;
+ }
+
+ regex[count++] = string[i];
+ }
+
+ regex[count++] = ')';
+ regex[count] = '$';
+
+ return regex;
+}
+
+/* Combines two regex strings into one regex string so that they can be
+ used as one by the GNU regex library. The `string2' is combine into
+ the `string1'. */
+
+char *silc_string_regex_combine(const char *string1, const char *string2)
+{
+ char *tmp;
+ int len1, len2;
+
+ if (!string1 || !string2) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return NULL;
+ }
+
+ len1 = strlen(string1);
+ len2 = strlen(string2);
+
+ tmp = silc_calloc(2 + len1 + len2, sizeof(*tmp));
+ strncat(tmp, string1, len1 - 2);
+ strncat(tmp, "|", 1);
+ strncat(tmp, string2 + 1, len2 - 1);
+
+ return tmp;
+}
+
+/* Do regex match to the two strings `string1' and `string2'. If the
+ `string2' matches the `string1' this returns TRUE. */
+
+int silc_string_match(const char *string1, const char *string2)
+{
+ char *s1;
+ int ret = FALSE;
+
+ if (!string1 || !string2) {
+ silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+ return ret;
+ }
+
+ s1 = silc_string_regexify(string1);
+ ret = silc_string_regex_match(s1, string2);
+ silc_free(s1);
+
+ return ret;
+}