#include #include #include #include #include "strdyn.h" /* function from libplaton/str/strplus.c */ int strcnt_sepstr(const char *str, const char *substr) { register char *s; register int count, substr_size; substr_size = strlen(substr); for (count = 0; ; count++) { if ((s = strstr(str, substr)) == NULL) break; else str += (s - str) + substr_size; } return count; } void strdyn_free(char **ar) { register int i; for (i = 0; ar[i] != NULL; i++) free(ar[i]); free(ar); } int strdyn_get_size(char **ar) { register int i; for (i = 0; ar[i] != NULL; i++) ; return i; } char **strdyn_create(void) { register char **ar; if ((ar = (char **) malloc(1 * sizeof(char *))) == NULL) return NULL; ar[0] = NULL; return ar; } char **strdyn_create_va(char *s1, ...) { register char **ar; if ((ar = strdyn_create()) == NULL) return NULL; if (s1 != NULL) { register char *s; va_list ap; if ((ar = strdyn_add(ar, s1)) == NULL) return NULL; va_start(ap, s1); while ((s = va_arg(ap, char *)) != NULL) if ((ar = strdyn_add(ar, s)) == NULL) return NULL; va_end(ap); } return ar; } char **strdyn_add(char **ar, const char *s) { register int count; if (ar == NULL) if ((ar = strdyn_create()) == NULL) return NULL; count = strdyn_get_size(ar); if ((ar = (char **) realloc(ar, (count + 2) * sizeof(char *))) == NULL) return NULL; ar[count] = strdup(s); ar[count + 1] = NULL; return ar; } char **strdyn_add_va(char **ar, ...) { register char *s; va_list ap; if (ar == NULL) if ((ar = strdyn_create()) == NULL) return NULL; va_start(ap, ar); while ((s = va_arg(ap, char *)) != NULL) if ((ar = strdyn_add(ar, s)) == NULL) return NULL; va_end(ap); return ar; } char **strdyn_add_ar(char **ar, char * const *s_ar) { register int k; for (k = 0; s_ar[k] != NULL; k++) { if ((ar = strdyn_add(ar, s_ar[k])) == NULL) return NULL; } return ar; } char **strdyn_duplicate(char **ar) { register int i; register char **new_ar; if ((new_ar = (char**) malloc((strdyn_get_size(ar) + 1) * sizeof(char*))) == NULL) return NULL; for (i = 0; ar[i] != NULL; i++) new_ar[i] = strdup(ar[i]); new_ar[i] = NULL; return new_ar; } char **strdyn_remove_empty(char **ar) { register int i, j; for (i = 0; ar[i] != NULL; ) { if (strlen(ar[i]) == 0) { free(ar[i]); for (j = i; ar[j] != NULL; j++) ar[j] = ar[j + 1]; } else i++; } if ((ar = (char**) realloc(ar, (i + 1) * sizeof(char*))) == NULL) return NULL; return ar; } char **strdyn_explode_chr(char *str, char sep) { char sep_str[2]; sep_str[0] = sep; sep_str[1] = '\0'; return strdyn_explode_str(str, sep_str); } char **strdyn_explode2_chr(char *str, char sep) { return strdyn_remove_empty(strdyn_explode_chr(str, sep)); } char **strdyn_explode_str(char *str, char *sep) { register char **ar; register char *s; register int ar_size, s_size, sep_size, i; if (str == NULL || sep == NULL) return NULL; ar_size = strcnt_sepstr(str, sep); if ((ar = (char**) malloc((ar_size + 2) * sizeof(char*))) == NULL) return NULL; sep_size = strlen(sep); for (s = str, i = 0; i < ar_size; i++, s += s_size + sep_size) { s_size = strstr(s, sep) - s; if ((ar[i] = (char*) malloc((s_size + 1) * sizeof(char))) == NULL) return NULL; strncpy(ar[i], s, s_size); ar[i][s_size] = '\0'; } if ((ar[ar_size] = strdup(s)) == NULL) return NULL; ar[ar_size + 1] = NULL; return ar; } char **strdyn_explode2_str(char *str, char *sep) { return strdyn_remove_empty(strdyn_explode_str(str, sep)); } char *strdyn_implode_chr(char **ar, char sep) { char sep_str[2]; sep_str[0] = sep; sep_str[1] = '\0'; return strdyn_implode_str(ar, sep_str); } char *strdyn_implode2_chr(char **ar, char sep) { register char **new_ar; register char *s; new_ar = strdyn_remove_empty(strdyn_duplicate(ar)); s = strdyn_implode_chr(new_ar, sep); strdyn_free(new_ar); return s; } char *strdyn_implode_str(char **ar, char *sep) { register int i, str_size, sep_size; register char *str, *s; sep_size = strlen(sep); for (i = 0, str_size = 0; ar[i] != NULL; ) str_size += strlen(ar[i++]) + sep_size; if ((str = (char*) malloc(str_size * sizeof(char))) == NULL) return NULL; for (i = 0, s = str; ar[i] != NULL; i++) { strcpy(s, ar[i]); s += strlen(ar[i]); if (ar[i + 1] != NULL) strcpy(s, sep); s += sep_size; } return str; } char *strdyn_implode2_str(char **ar, char *str) { register char **new_ar; register char *s; new_ar = strdyn_remove_empty(strdyn_duplicate(ar)); s = strdyn_implode_str(new_ar, str); strdyn_free(new_ar); return s; } char **strdyn_conjunct(char **ar1, char **ar2) { register int i; register char **ar; if ((ar = strdyn_create()) == NULL) return NULL; for (i = 0; ar2[i] != NULL; i++) { if (! strdyn_compare(ar1, ar2[i])) { if ((ar = strdyn_add(ar, ar2[i])) == NULL) return NULL; } } return ar; } char **strdyn_consolide(char **ar1, char **ar2) { register int i; register char **ar; if ((ar = strdyn_create()) == NULL) return NULL; for (i = 0; ar1[i] != NULL; i++) { if (strdyn_compare(ar, ar1[i])) { if ((ar = strdyn_add(ar, ar1[i])) == NULL) return NULL; } } for (i = 0; ar2[i] != NULL; i++) { if (strdyn_compare(ar, ar2[i])) { if ((ar = strdyn_add(ar, ar2[i])) == NULL) return NULL; } } return ar; } int strdyn_search(char **ar, char *s) { register int i; for (i = 0; ar[i] != NULL; i++) if (! strcmp(ar[i], s)) return i; return -1; } int strdyn_compare(char **ar, char *s) { return strdyn_search(ar, s) < 0 ? -1 : 0; } int strdyn_compare_all(char **ar, char *s) { register int i; for (i = 0; ar[i] != NULL; i++) if (strcmp(ar[i], s)) return -1; return 0; } #if defined(SELF) || defined(SELFTEST) || defined(SELF_STRDYN) #define TESTSTR1 "___AAA_BBBB__C_DaDaD____" #define TESTSEP1 '_' #define TESTSEP2 "__" int main(void) { register int i; char **ar1, **ar2, **ar_join, **ar_intersect; char *s; ar2 = strdyn_create_va("A", "B", "C", "D", NULL); i = 0; while (ar2[i] != NULL) { printf("ar2[%d] = \"%s\"\n", i, ar2[i]); i++; } printf("strdyn_explode2_chr(\"%s\", '%c') = ar1\n", TESTSTR1, TESTSEP1); ar1 = strdyn_explode2_chr(TESTSTR1, TESTSEP1); puts("strdyn_free(ar1)"); strdyn_free(ar1); printf("strdyn_explode_str(\"%s\", \"%s\") = ar1\n", TESTSTR1, TESTSEP2); ar1 = strdyn_explode_str(TESTSTR1, TESTSEP2); for (i = 0; ar1[i] != NULL; i++) printf("ar1[%d] = \"%s\"\n", i, ar1[i]); s = strdyn_implode2_chr(ar1, TESTSEP1); printf("strdyn_implode2_chr(ar1, '%c') = \"%s\"\n", TESTSEP1, s); puts("free(s)"); free(s); s = strdyn_implode2_str(ar1, TESTSEP2); printf("strdyn_implode2_str(ar1, \"%s\") = \"%s\"\n", TESTSEP2, s); puts("free(s)"); free(s); ar_join = strdyn_join(ar1, ar2); ar_intersect = strdyn_intersect(ar1, ar2); i = 0; while (ar_join[i] != NULL) { printf("ar_join[%d] = \"%s\"\n", i, ar_join[i]); i++; } i = 0; while (ar_intersect[i] != NULL) { printf("ar_intersect[%d] = \"%s\"\n", i, ar_intersect[i]); i++; } puts("strdyn_free(ar1)"); strdyn_free(ar1); puts("strdyn_free(ar2)"); strdyn_free(ar2); puts("strdyn_free(ar_join)"); strdyn_free(ar_join); puts("strdyn_free(ar_intersect)"); strdyn_free(ar_intersect); return 0; } #endif