24 #define GB_PATH_MAX 1024
31 const char *key =
GB_KEY(gbd);
35 while (*key) *bp++ = *key++;
42 #define BUFFERSIZE 1024
45 static char *orgbuffer =
NULp;
81 if (i == *(
int*)val) equal =
true;
117 if (after) index = (
int)after->
index+1;
else index = 0;
122 for (; index < end; index++) {
123 if (header[index].
flags.key_quark != 0) {
137 if (!skip_over--)
return gb;
143 for (; index < end; index++) {
144 if (key_quark == header[index].
flags.key_quark) {
167 if (!skip_over--)
return gb;
189 if (after) index = (
int)after->
index+1;
else index = 0;
215 (!strchr(val,
'*')) &&
219 if (ifs->
key != sub_key_quark)
continue;
221 res =
gb_index_find(father, ifs, sub_key_quark, val, case_sens, index);
227 for (; index < end; index++) {
372 if (index >= father->
d.
nheader || index <0) {
398 for (
int i=0; i<256; i++) {
399 table[i] = islower(i) || isupper(i) || isdigit(i) || i==
'_' || i==
'@';
427 if (create != oldType) {
428 GB_export_errorf(
"Inconsistent type for field '%s' (existing=%i, expected=%i)", key, oldType, create);
455 if (!key)
return NULp;
468 if (!separator) gb_result =
find_or_create(gbc, key, create, internflag);
470 int len = separator-key;
471 char firstKey[len+1];
472 memcpy(firstKey, key, len);
475 char invalid_char = 0;
477 switch (separator[0]) {
482 if (separator[1] ==
'/') {
490 GB_export_errorf(
"terminal entry '%s' cannot be used as container", firstKey);
496 if (separator[1] !=
'.') invalid_char = separator[0];
500 switch (separator[2]) {
501 case 0: gb_result = gb_parent;
break;
502 case '/': gb_result =
gb_search(gb_parent, separator+3, create, internflag);
break;
517 invalid_char = separator[0];
539 if (type != expected_type) {
540 GB_export_errorf(
"Field '%s' has wrong type (found=%i, expected=%i)", fieldname, type, expected_type);
619 for (index = firstindex; index<end; index++) {
622 if (! (userbit & header[index].
flags.flags))
continue;
623 if ((key_quark>=0) && (header[index].
flags.key_quark != key_quark))
continue;
630 if (!skip_over--)
return gb;
644 for (
int index = 0; index<end; index++) {
645 if (!(userbit & header[index].
flags.flags))
continue;
688 GB_ERROR create_many_items(
GBDATA *gb_parent,
const char **item_key_list,
int item_count) {
690 for (
int i = 0; i<item_count && !
error; i++) {
691 const char *item_key = item_key_list[k++];
692 if (!item_key) { item_key = item_key_list[0]; k = 1; }
709 gb_main =
GB_open(
"nosuch.arb",
"c");
721 const char *single_key[] = {
"entry",
NULp };
722 const char *mixed_keys[] = {
"item",
"other",
NULp };
724 if (!error) error = create_many_items(gb_cont1, single_key, 100);
725 if (!error) error = create_many_items(gb_cont2, mixed_keys, 20);
750 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(db.gb_main,
"zic-zac",
GB_FIND),
"Invalid char '-' in key 'zic-zac'");
753 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(db.gb_main,
"->entry",
GB_FIND),
"Invalid char '-' in key '->entry'");
754 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(db.gb_main,
"entry->bla",
GB_FIND),
"Invalid char '-' in key 'entry->bla'");
755 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(db.gb_main,
"container1/entry->nowhere",
GB_FIND),
"Invalid char '-' in key 'entry->nowhere'");
756 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(db.gb_main,
"container1/nosuchentry->nowhere",
GB_STRING),
"Invalid char '-' in key 'nosuchentry->nowhere");
757 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(db.gb_main,
"entry->",
GB_FIND),
"Invalid char '-' in key 'entry->'");
768 TEST_EXPECT_NORESULT__NOERROREXPORTED(
GB_search(gb_any_child,
"../../..",
GB_FIND));
769 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(gb_any_child,
"../../../impossible",
GB_STRING),
"cannot use '..' at root node");
773 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(gb_any_child,
"/container1/entry/name/",
GB_FIND),
"terminal entry 'name' cannot be used as container");
777 TEST_EXPECT_NORESULT__NOERROREXPORTED(
GB_search(gb_any_child,
"/..",
GB_FIND));
791 TEST_EXPECT_NORESULT__NOERROREXPORTED(
GB_entry(db.gb_cont2,
"entry"));
830 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_searchOrCreate_float (db.gb_cont_misc,
"int", 0.815),
"has wrong type");
831 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_searchOrCreate_float (db.gb_cont_misc,
"str", 0.815),
"has wrong type");
832 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_searchOrCreate_int (db.gb_cont_misc,
"float", 4711),
"has wrong type");
833 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_searchOrCreate_int (db.gb_cont_misc,
"str", 4711),
"has wrong type");
834 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_searchOrCreate_string(db.gb_cont_misc,
"float",
"bla"),
"has wrong type");
835 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_searchOrCreate_string(db.gb_cont_misc,
"int",
"bla"),
"has wrong type");
837 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_searchOrCreate_string(db.gb_cont_misc,
"*",
"bla"),
"Invalid char '*' in key '*'");
838 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_searchOrCreate_string(db.gb_cont_misc,
"int*",
"bla"),
"Invalid char '*' in key 'int*'");
839 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_searchOrCreate_string(db.gb_cont_misc,
"sth_else*",
"bla"),
"Invalid char '*' in key 'sth_else*'");
842 TEST_EXPECT_NORESULT__NOERROREXPORTED(
GB_search(db.gb_cont_misc,
"subcont/entry",
GB_FIND));
843 TEST_EXPECT_RESULT__NOERROREXPORTED(gb_entry =
GB_search(db.gb_cont_misc,
"subcont/entry",
GB_INT));
901 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(db.gb_cont_misc,
"str",
GB_INT),
"Inconsistent type for field");
902 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(db.gb_cont_misc,
"subcont",
GB_STRING),
"Inconsistent type for field");
908 TEST_EXPECT_RESULT__NOERROREXPORTED(gb_cont2_slash =
GB_search(db.gb_cont_misc,
"subcont2/",
GB_FIND));
912 GBDATA *gb_rootcont_slash;
913 TEST_EXPECT_RESULT__NOERROREXPORTED(gb_rootcont =
GB_search(db.gb_main,
"/container1",
GB_FIND));
914 TEST_EXPECT_RESULT__NOERROREXPORTED(gb_rootcont_slash =
GB_search(db.gb_main,
"/container1/",
GB_FIND));
920 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(db.gb_cont_misc,
"sub/inva*lid",
GB_INT),
"Invalid char '*' in key 'inva*lid'");
921 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(db.gb_cont_misc,
"sub/1 3",
GB_INT),
"Invalid char ' ' in key '1 3'");
922 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(db.gb_cont_misc,
"sub//sub",
GB_INT),
"Invalid '//' in key 'sub//sub'");
923 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(db.gb_cont_misc,
"subcont2//",
GB_FIND),
"Invalid '//' in key 'subcont2//'");
924 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(db.gb_cont_misc,
"sub/..sub",
GB_INT),
"Expected '/' after '..' in key '..sub'");
925 TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(
GB_search(db.gb_cont_misc,
"subcont/entry/",
GB_FIND),
"terminal entry 'entry' cannot be used as container");
934 TEST_EXPECT_NORESULT__NOERROREXPORTED(
GB_first_marked(db.gb_cont2,
"entry"));
GBDATA * GB_entry(GBDATA *father, const char *key)
GBDATA * GB_child(GBDATA *father)
GBDATA * GB_open(const char *path, const char *opent)
static const char * GB_get_GBDATA_path(GBDATA *gbd)
GBDATA * GB_find(GBDATA *gbd, const char *key, GB_SEARCH_TYPE gbs)
#define TEST_EXPECT_SIMILAR(expr, want, epsilon)
long GB_read_int(GBDATA *gbd)
__ATTR__USERESULT GB_ERROR send_update_to_server(GBDATA *gbd) __ATTR__USERESULT
GB_ERROR GB_write_string(GBDATA *gbd, const char *s)
GBCONTAINER * expect_container() const
GBDATA * find_or_create(GBCONTAINER *gb_parent, const char *key, GB_TYPES create, bool internflag)
gb_user * users[GB_MAX_USERS]
unsigned int folded_container
GBDATA * gb_index_find(GBCONTAINER *gbf, gb_index_files *ifs, GBQUARK quark, const char *val, GB_CASE case_sens, int after_index)
static void build_GBDATA_path(GBDATA *gbd, char **buffer)
static GBDATA * find_sub_sub_by_quark(GBCONTAINER *const father, const char *key, GBQUARK sub_key_quark, GB_TYPES type, const char *val, GB_CASE case_sens, GBDATA *after)
GBCONTAINER * gb_create_container(GBCONTAINER *father, const char *key)
void GB_internal_errorf(const char *templat,...)
const char * GBS_global_string(const char *templat,...)
GBDATA * GB_nextEntry(GBDATA *entry)
static GBDATA * gb_search_marked(GBCONTAINER *gbc, GBQUARK key_quark, int firstindex, size_t skip_over)
CONSTEXPR_INLINE gb_header_list * GB_DATA_LIST_HEADER(gb_data_list &dl)
GBDATA * GB_find_sub_by_quark(GBDATA *father, GBQUARK key_quark, GBDATA *after, size_t skip_over)
gb_index_files * GB_INDEX_FILES_NEXT(gb_index_files *ixf)
GB_MAIN_TYPE * GBCONTAINER_MAIN(GBCONTAINER *gbc)
GBDATA * GB_searchOrCreate_float(GBDATA *gb_container, const char *fieldpath, float default_value)
char buffer[MESSAGE_BUFFERSIZE]
GBDATA * GB_get_father(GBDATA *gbd)
GBENTRY * gb_create(GBCONTAINER *father, const char *key, GB_TYPES type)
GB_ERROR GB_check_hkey(const char *key) __ATTR__USERESULT
GBDATA * GBCMC_find(GBDATA *gbd, const char *key, GB_TYPES type, const char *str, GB_CASE case_sens, GB_SEARCH_TYPE gbs)
GB_ERROR GB_export_error(const char *error)
GB_ERROR GB_await_error()
AliDataPtr after(AliDataPtr data, size_t pos)
GB_ERROR gb_unfold(GBCONTAINER *gbc, long deep, int index_pos)
GBDATA * GB_create_container(GBDATA *father, const char *key)
GBDATA * GB_searchOrCreate_string(GBDATA *gb_container, const char *fieldpath, const char *default_value)
TYPE * ARB_alloc(size_t nelem)
GB_CSTR GB_read_key_pntr(GBDATA *gbd)
GBDATA * GB_create(GBDATA *father, const char *key, GB_TYPES type)
static GBDATA * GB_find_subcontent_by_quark(GBDATA *father, GBQUARK key_quark, GB_TYPES type, const char *val, GB_CASE case_sens, GBDATA *after, size_t skip_over)
GBDATA * GB_brother(GBDATA *entry, const char *key)
long GB_number_of_subentries(GBDATA *gbd)
GBDATA * GB_search(GBDATA *gbd, const char *fieldpath, GB_TYPES create)
GBDATA * GB_find_string(GBDATA *gbd, const char *key, const char *str, GB_CASE case_sens, GB_SEARCH_TYPE gbs)
static bool gb_find_value_equal(GBDATA *gb, GB_TYPES type, const char *val, GB_CASE case_sens)
bool is_container() const
#define TEST_REJECT_NULL(n)
static void error(const char *msg)
static keychar_table keychars
GBDATA * gb_find_by_nr(GBCONTAINER *father, int index)
GBDATA * GB_followingEntry(GBDATA *entry, size_t skip_over)
unsigned int update_in_server
float GB_read_float(GBDATA *gbd)
GBCONTAINER * as_container() const
GB_write_int const char GB_write_autoconv_string WRITE_SKELETON(write_pointer, GBDATA *,"%p", GB_write_pointer) char *AW_awa if)(!gb_var) return strdup("")
GBQUARK GB_get_quark(GBDATA *gbd)
GBDATA * GB_following_marked(GBDATA *gbd, const char *keystring, size_t skip_over)
CONSTEXPR_INLINE GBCONTAINER * GB_FATHER(GBDATA *gbd)
gb_index_files * GBCONTAINER_IFS(GBCONTAINER *gbc)
GB_ERROR GB_write_float(GBDATA *gbd, float f)
const int GB_MAX_LOCAL_SEARCH
GB_ERROR GB_write_int(GBDATA *gbd, long i)
const char * GB_first_non_key_char(const char *str)
#define __ATTR__REDUCED_OPTIMIZE
void GB_test_transaction(GB_MAIN_TYPE *Main)
const char * first_non_key_character(const char *str) const
GB_ERROR GB_export_errorf(const char *templat,...)
void GB_internal_error(const char *message)
#define TEST_EXPECT_NULL(n)
void GB_write_flag(GBDATA *gbd, long flag)
#define assert_or_exit(cond)
GBQUARK GB_find_existing_quark(GBDATA *gbd, const char *key)
static GBDATA * gb_expect_type(GBDATA *gbd, GB_TYPES expected_type, const char *fieldname)
static GBDATA * gb_find_internal(GBDATA *gbd, const char *key, GB_TYPES type, const char *val, GB_CASE case_sens, GB_SEARCH_TYPE gbs)
GBDATA * GB_nextChild(GBDATA *child)
#define TEST_EXPECT_NO_ERROR(call)
NOT4PERL GBDATA * GB_find_int(GBDATA *gbd, const char *key, long val, GB_SEARCH_TYPE gbs)
GBDATA * GB_first_marked(GBDATA *gbd, const char *keystring)
GBDATA * GB_next_marked(GBDATA *gbd, const char *keystring)
long GB_number_of_marked_subentries(GBDATA *gbd)
#define TEST_EXPECT_ERROR_CONTAINS(call, part)
static GBDATA * find_sub_by_quark(GBCONTAINER *father, GBQUARK key_quark, GB_TYPES type, const char *val, GB_CASE case_sens, GBDATA *after, size_t skip_over)
GBDATA * gb_search(GBCONTAINER *gbc, const char *key, GB_TYPES create, int internflag)
const char * GBT_get_name(GBDATA *gb_item)
GBDATA * GB_searchOrCreate_int(GBDATA *gb_container, const char *fieldpath, long default_value)
GB_transaction ta(gb_var)
GB_CSTR GB_read_char_pntr(GBDATA *gbd)
bool GBS_string_matches(const char *str, const char *expr, GB_CASE case_sens)
const char * GB_KEY(GBDATA *gbd)
size_t GB_countEntries(GBDATA *father, const char *key)
GBCONTAINER * gb_get_root(GBENTRY *gbe)
#define TEST_EXPECT_EQUAL(expr, want)
GBCONTAINER * get_father()
void GB_close(GBDATA *gbd)