int main() { int i,y,test_size=1000,size_ret; char test_str[32768]; char buf[16]; char *test_str_array[test_size]; const char **ret; for (i=0;i<test_size;i++) { snprintf(buf,16,"arg%d",i); test_str_array[i] = strdup(buf); } for (i=0;i<test_size;i++) { test_str[0]='\0'; for (y=0;y<i;y++) { snprintf(buf,16,"arg%d ",y); strncat(test_str,buf,16); } ret = splitstr(test_str,NULL,&size_ret); assert(size_ret == i); for (y=0;y<i;y++) assert( strcmp(ret[y],test_str_array[y])==0 ); splitstr_free(ret); } return 0; }
/* * Retrieve a Symbol's Contents * * "key" is not modified. * If the key cannot be found, NULL is returned */ void *sym_get(SYM sym, char *key) { char *nkey; const char **keys; /* key split into a 2d string array */ char **kk; SYM csym; /* search: current symbol table */ struct sym *nsym = NULL; /* search: found symbol entry */ if (sym == NULL) return (NULL); nkey = strdup(key); keys = splitstr(nkey, ",", NULL); if (keys == NULL) return (NULL); for (kk = (char **)keys, csym = sym; *kk != NULL && (nsym = find_key1(csym->sym, *kk)) != NULL; csym = nsym->data) { if (*++kk == NULL) break; if (nsym->data == NULL) { /* fatal error */ free(nkey); splitstr_free(keys); return (NULL); } if (((SYM) (nsym->data))->magic != SYM_MAGIC) { free(nkey); splitstr_free(keys); return (NULL); } } if (*kk == NULL) { /* found a complete match */ splitstr_free(keys); free(nkey); return (nsym->data); } else { splitstr_free(keys); free(nkey); return (NULL); } }
/* * Add (key, data) to an existing symbol table * * If the key does not exist, a new key is added to the end of the list. * If the key exists and the PUT_REPLACE flag is not supplied, return EEXIST. * If a symbol table entry in a multi-part key is not a symbol table (i.e. * element two of a three or more element key), return ENOTDIR. * * "data" is not duplicated and must not point to a static area that could * go away before the element is deleted (such as a local string in a * function) * * "key" is duplicated as needed, and is not modified. * * Code: * chop up key on commas * * search until a key element isn't found in the key tree, the key list is * exhausted, or a key's data element is not a sub-tree * * if the key list is exhausted, return a "duplicate entry" error * * if the last found key's data element is not a sub-tree, return * something like "ENOTDIR". * * add new keys for sub-trees until key list is exhausted; * last node gets 'data'. * */ int sym_put(SYM sym, char *key, void *data, int flags) { const char **keys; /* key split into a 2d string array */ char **kk; char *nkey; /* copy of 'key' -- before split */ SYM csym, ncsym; /* search: current symbol table */ struct sym *nsym = NULL; /* search: found symbol entry */ if (sym == NULL) return (EINVAL); nkey = strdup(key); keys = splitstr(key, ",", NULL); if (keys == NULL) { free(nkey); return (EINVAL); } for (kk = (char **)keys, csym = sym; *kk != NULL && (nsym = find_key1(csym->sym, *kk)) != NULL; csym = nsym->data) { if (*++kk == NULL) break; if (nsym->data == NULL) { /* fatal error */ free(nkey); splitstr_free(keys); return (ENOTDIR); } if (((SYM) (nsym->data))->magic != SYM_MAGIC) { free(nkey); splitstr_free(keys); return (ENOTDIR); } } if (*kk == NULL) { /* found a complete match */ free(nkey); splitstr_free(keys); if (flags == PUT_REPLACE) { nsym->data = data; return (0); } else { return (EEXIST); } } /* csym is a ptr to a list */ for (; *kk != NULL; kk++) { if (*(kk + 1) != NULL) { add_key(csym, *kk, (void *)(ncsym = newsym())); csym = ncsym; } else { add_key(csym, *kk, data); /* last key */ } } free(nkey); splitstr_free(keys); return (0); }