#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#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
Platon Group <platon@platon.sk> http://platon.sk/
|