/****************************************************************************** * TinTin++ * * Copyright (C) 2004 (See CREDITS file) * * * * This program is protected under the GNU GPL (See COPYING) * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *******************************************************************************/ /****************************************************************************** * (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t * * * * coded by Igor van den Hoven 2009 * ******************************************************************************/ #include "tintin.h" struct listroot *search_nest_root(struct listroot *root, char *arg) { struct listnode *node; node = search_node_list(root, arg); if (node == NULL || node->root == NULL) { return NULL; } return node->root; } struct listnode *search_base_node(struct listroot *root, char *variable) { char name[BUFFER_SIZE]; get_arg_to_brackets(variable, name); return search_node_list(root, get_alnum(root->ses, name)); } struct listnode *search_nest_node(struct listroot *root, char *variable) { char name[BUFFER_SIZE], *arg; arg = get_arg_to_brackets(variable, name); while (root && *arg) { root = search_nest_root(root, get_alnum(root->ses, name)); if (root) { arg = get_arg_in_brackets(arg, name); } } if (root) { return search_node_list(root, get_alnum(root->ses, name)); } return NULL; } int search_nest_index(struct listroot *root, char *variable) { char name[BUFFER_SIZE], *arg; arg = get_arg_to_brackets(variable, name); while (root && *arg) { root = search_nest_root(root, get_alnum(root->ses, name)); if (root) { arg = get_arg_in_brackets(arg, name); } } if (root) { return search_index_list(root, get_alnum(root->ses, name), NULL); } return -1; } struct listroot *update_nest_root(struct listroot *root, char *arg) { struct listnode *node; node = search_node_list(root, arg); if (node == NULL) { node = update_node_list(root, arg, "", ""); } if (node->root == NULL) { node->root = init_list(root->ses, root->type, LIST_SIZE); } return node->root; } void update_nest_node(struct listroot *root, char *arg) { char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE]; while (*arg) { arg = get_arg_in_braces(arg, arg1, FALSE); arg = get_arg_in_braces(arg, arg2, FALSE); if (*arg2 == DEFAULT_OPEN) { update_nest_node(update_nest_root(root, get_alnum(root->ses, arg1)), arg2); } else if (*arg1) { update_node_list(root, get_alnum(root->ses, arg1), arg2, ""); } if (*arg == COMMAND_SEPARATOR) { arg++; } } } int delete_nest_node(struct listroot *root, char *variable) { char name[BUFFER_SIZE], *arg; int index; arg = get_arg_to_brackets(variable, name); while (root && *arg) { root = search_nest_root(root, get_alnum(root->ses, name)); if (root) { arg = get_arg_in_brackets(arg, name); } } if (root) { index = search_index_list(root, get_alnum(root->ses, name), NULL); if (index != -1) { delete_index_list(root, index); return TRUE; } } return FALSE; } // Return the number of indices of a node. int get_nest_size(struct listroot *root, char *variable, char *result) { char name[BUFFER_SIZE], *arg; int index, count; arg = get_arg_to_brackets(variable, name); *result = 0; if (!strcmp(arg, "[]")) { if (*name == 0) { for (index = 0 ; index < root->used ; index++) { cat_sprintf(result, "{%s}", root->list[index]->left); } return root->used + 1; } if (search_nest_root(root, get_alnum(root->ses, name)) == NULL) { if (search_node_list(root, name)) { return 1; } } } while (root && *name) { // Handle regex queries if (search_nest_root(root, get_alnum(root->ses, name)) == NULL) { if (search_node_list(root, name) == NULL) { for (index = count = 0 ; index < root->used ; index++) { if (match(NULL, root->list[index]->left, name)) { // cat_sprintf(result, "{%s}", root->list[index]->right); show_nest_node(root->list[index], result, 0); count++; } } if (count) { return count + 1; } else { return tintin_regexp_check(name); // so using a regex returns "" instead of "0" } } } root = search_nest_root(root, get_alnum(root->ses, name)); if (root) { if (!strcmp(arg, "[]")) { for (index = 0 ; index < root->used ; index++) { cat_sprintf(result, "{%s}", root->list[index]->left); } return root->used + 1; } arg = get_arg_in_brackets(arg, name); } } return 0; } struct listnode *get_nest_node(struct listroot *root, char *variable, char *result, int def) { struct listnode *node; int size; size = get_nest_size(root, variable, result); if (size) { return NULL; } node = search_nest_node(root, variable); if (node) { show_nest_node(node, result, TRUE); return node; } node = search_base_node(root, variable); if (node || def) { strcpy(result, ""); } else { sprintf(result, "$%s", variable); } return NULL; } int get_nest_index(struct listroot *root, char *variable, char *result, int def) { struct listnode *node; int index, size; size = get_nest_size(root, variable, result); if (size) { sprintf(result, "%d", size - 1); return -1; } index = search_nest_index(root, variable); if (index >= 0) { sprintf(result, "%d", index + 1); return index; } node = search_base_node(root, variable); if (node || def) { strcpy(result, "0"); } else { sprintf(result, "&%s", variable); } return -1; } struct listnode *set_nest_node(struct listroot *root, char *arg1, char *format, ...) { struct listnode *node; char arg2[BUFFER_SIZE], name[BUFFER_SIZE], *arg; va_list args; va_start(args, format); vsprintf(arg2, format, args); va_end(args); arg = get_arg_to_brackets(arg1, name); while (*arg) { root = update_nest_root(root, get_alnum(root->ses, name)); if (root) { arg = get_arg_in_brackets(arg, name); } } node = search_node_list(root, get_alnum(root->ses, name)); if (node && node->root) { free_list(node->root); node->root = NULL; } if (*space_out(arg2) == DEFAULT_OPEN) { update_nest_node(update_nest_root(root, get_alnum(root->ses, name)), arg2); return search_node_list(root, get_alnum(root->ses, name)); } else { return update_node_list(root, get_alnum(root->ses, name), arg2, ""); } } struct listnode *add_nest_node(struct listroot *root, char *arg1, char *format, ...) { struct listnode *node; char arg2[BUFFER_SIZE], name[BUFFER_SIZE], *arg; va_list args; va_start(args, format); vsprintf(arg2, format, args); va_end(args); arg = get_arg_to_brackets(arg1, name); while (*arg) { root = update_nest_root(root, get_alnum(root->ses, name)); if (root) { arg = get_arg_in_brackets(arg, name); } } node = search_node_list(root, get_alnum(root->ses, name)); /* Adding here, so don't clear the variable. if (node && node->root) { free_list(node->root); node->root = NULL; } */ if (*space_out(arg2) == DEFAULT_OPEN) { update_nest_node(update_nest_root(root, get_alnum(root->ses, name)), arg2); return search_node_list(root, get_alnum(root->ses, name)); } else { return update_node_list(root, get_alnum(root->ses, name), arg2, ""); } } void show_nest_node(struct listnode *node, char *result, int initialize) { if (initialize) { *result = 0; } if (node->root == NULL) { if (initialize) { strcat(result, node->right); } else { cat_sprintf(result, "{%s}", node->right); } } else { struct listroot *root = node->root; int i; if (!initialize) { strcat(result, "{"); } for (i = 0 ; i < root->used ; i++) { cat_sprintf(result, "{%s}", root->list[i]->left); show_nest_node(root->list[i], result, FALSE); } if (!initialize) { strcat(result, "}"); } } } void copy_nest_node(struct listroot *dst_root, struct listnode *dst, struct listnode *src) { int index; if (src->root == NULL) { return; } dst_root = dst->root = init_list(dst_root->ses, dst_root->type, src->root->size); for (index = 0 ; index < src->root->used ; index++) { dst = insert_node_list(dst_root, src->root->list[index]->left, src->root->list[index]->right, src->root->list[index]->pr); if (src->root->list[index]->root) { copy_nest_node(dst_root, dst, src->root->list[index]); } } }