/** * @brief Close given number of levels of key * * @pre there is some needed special handling at begin at end, * the caller needs to do that * * For the basename of cur nothing needs to be done * (it was either a value or an array entry) * * Then for every level do: * * * (C1) * #/_ * (lookahead says it is a map in the array) * -> close the anonymous map and then the array * * (C2) * _/# * _/___empty_map * (lookahead says it is not a map) * -> don't do anything * * (C3) * # * -> close the array * * (C4) * _ * -> close the map * * * @param g to yield json information * @param cur the key which name is used for closing * @param levels the number of levels to close */ static void elektraGenCloseIterate(yajl_gen g, const Key *cur, int levels) { keyNameReverseIterator curIt = elektraKeyNameGetReverseIterator(cur); // jump last element elektraKeyNameReverseNext(&curIt); for (int i=0; i<levels; ++i) { elektraKeyNameReverseNext(&curIt); lookahead_t lookahead = elektraLookahead(curIt.current, curIt.size); if (curIt.current[0] == '#') { if (lookahead == LOOKAHEAD_MAP) { #ifdef ELEKTRA_YAJL_VERBOSE printf ("GEN (C1) anon map close\n"); #endif yajl_gen_map_close(g); } #ifdef ELEKTRA_YAJL_VERBOSE printf ("GEN (C3) array close\n"); #endif yajl_gen_array_close(g); } else { if (lookahead == LOOKAHEAD_MAP) { #ifdef ELEKTRA_YAJL_VERBOSE printf ("GEN (C4) map close\n"); #endif yajl_gen_map_close(g); } else { #ifdef ELEKTRA_YAJL_VERBOSE printf ("(C2) lookahead not a map: nothing to do\n"); #endif } } } }
/** * @brief fixes elektraGenCloseIterate for the special handling of * arrays at very last position. * * @param g generate array there * @param key the key to look at */ static void elektraGenCloseLast (yajl_gen g, const Key * key) { keyNameReverseIterator last = elektraKeyNameGetReverseIterator (key); elektraKeyNameReverseNext (&last); #ifdef ELEKTRA_YAJL_VERBOSE printf ("last startup entry: \"%.*s\"\n", (int)last.size, last.current); #endif if (last.current[0] == '#' && strcmp (last.current, "###empty_array")) { #ifdef ELEKTRA_YAJL_VERBOSE printf ("GEN array close last\n"); #endif yajl_gen_array_close (g); } }
void test_reverseLevel (void) { Key * k = keyNew ("user/abc/defghi/jkl", KEY_END); int level = 0; char buffer[20]; printf ("Test reverse level\n"); keyNameReverseIterator it = elektraKeyNameGetReverseIterator (k); while (elektraKeyNameReverseNext (&it)) { level++; strncpy (buffer, it.current, it.size); buffer[it.size] = 0; // printf("Level %d name: \"%s\"\n",level,buffer); switch (level) { case 4: succeed_if (strcmp (buffer, "user") == 0, "keyNameGetOneLevel not correct"); break; case 3: succeed_if (strcmp (buffer, "abc") == 0, "keyNameGetOneLevel not correct"); break; case 2: succeed_if (strcmp (buffer, "defghi") == 0, "keyNameGetOneLevel not correct"); break; case 1: succeed_if (strcmp (buffer, "jkl") == 0, "keyNameGetOneLevel not correct"); break; default: succeed_if (0, "should not reach case statement"); } } keySetName (k, "user////\\/abc/\\/def\\/ghi////jkl\\/\\/"); level = 0; it = elektraKeyNameGetReverseIterator (k); while (elektraKeyNameReverseNext (&it)) { level++; strncpy (buffer, it.current, it.size); buffer[it.size] = 0; // printf("Level %d name: \"%s\"\n",level,buffer); switch (level) { case 4: succeed_if (strcmp (buffer, "user") == 0, "keyNameGetOneLevel not correct"); break; case 3: succeed_if (strcmp (buffer, "\\/abc") == 0, "keyNameGetOneLevel not correct"); break; case 2: succeed_if (strcmp (buffer, "\\/def\\/ghi") == 0, "keyNameGetOneLevel not correct"); break; case 1: succeed_if (strcmp (buffer, "jkl\\/\\/") == 0, "keyNameGetOneLevel not correct"); break; default: succeed_if (0, "should not reach case statement"); } } keyDel (k); }