/****************************************************************************** * TinTin++ * * Copyright (C) 2005 (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 * *******************************************************************************/ /****************************************************************************** * file: list.c - pseudo array support * * * * (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t * * * * coded by Igor van den Hoven 2004 * ******************************************************************************/ #include "tintin.h" DO_COMMAND(do_list) { char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE]; struct listroot *root; struct listnode *node; int cnt; root = ses->list[LIST_VARIABLE]; arg = sub_arg_in_braces(ses, arg, arg1, GET_NST, SUB_VAR|SUB_FUN); arg = sub_arg_in_braces(ses, arg, arg2, GET_ONE, SUB_VAR|SUB_FUN); if (*arg1 == 0 || *arg2 == 0) { show_message(ses, LIST_VARIABLE, "#SYNTAX: #LIST {variable} {ADD|CLE|CRE|DEL|FIN|GET|INS|SET|SIZ|SOR} {argument}"); } else { for (cnt = 0 ; *array_table[cnt].name ; cnt++) { if (is_abbrev(arg2, array_table[cnt].name)) { break; } } if (*array_table[cnt].name == 0) { return do_list(ses, ""); } else { if ((node = search_nest_node(root, arg1)) == NULL) { node = set_nest_node(root, arg1, ""); } array_table[cnt].array(ses, node, arg); } } return ses; } DO_ARRAY(array_add) { char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE], *str; int index; if (!list->root) { list->root = init_list(ses, LIST_VARIABLE, LIST_SIZE); } index = list->root->used + 1; while (*arg) { arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN); str = arg1; while (*str) { str = get_arg_in_braces(str, arg2, GET_ALL); insert_node_list(list->root, ntos(index++), arg2, ""); if (*str == COMMAND_SEPARATOR) { str++; } } } return ses; } DO_ARRAY(array_clear) { if (list->root) { free_list(list->root); list->root = NULL; } set_nest_node(ses->list[LIST_VARIABLE], list->left, ""); return ses; } DO_ARRAY(array_create) { char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE], buf[BUFFER_SIZE], *str; int index = 1; substitute(ses, arg, buf, SUB_VAR|SUB_FUN); arg = buf; if (list->root) { free_list(list->root); } list->root = init_list(ses, LIST_VARIABLE, LIST_SIZE); while (*arg) { arg = get_arg_in_braces(arg, arg1, GET_ONE); str = arg1; while (*str) { str = get_arg_in_braces(str, arg2, GET_ALL); insert_node_list(list->root, ntos(index++), arg2, ""); if (*str == COMMAND_SEPARATOR) { str++; } } if (*arg == COMMAND_SEPARATOR) { arg++; } } return ses; } DO_ARRAY(array_delete) { char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE]; int index, cnt, loop; if (list->root) { arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN); arg = get_arg_in_braces(arg, arg2, GET_ALL); loop = *arg2 ? (int) get_number(ses, arg2) : 1; while (loop--) { index = search_nest_index(list->root, arg1); if (atoi(arg1) == 0 || index == -1) { tintin_printf2(ses, "#LIST DEL: Invalid index: %s", arg1); return ses; } for (cnt = index + 1 ; cnt < list->root->used ; cnt++) { list->root->list[cnt]->left = refstring(list->root->list[cnt]->left, "%d", cnt); } delete_index_list(list->root, index); } } else { show_message(ses, LIST_VARIABLE, "#LIST DEL: {%s} is not a list.", list->left); } return ses; } DO_ARRAY(array_find) { char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE]; int index; arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN); arg = sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_VAR|SUB_FUN); if (*arg2 == 0) { show_message(ses, LIST_VARIABLE, "#SYNTAX: #LIST {variable} FIND {string} {variable}"); return ses; } if (list->root) { for (index = 0 ; index < list->root->used ; index++) { if (match(ses, list->root->list[index]->right, arg1)) { break; } } if (index < list->root->used) { set_nest_node(ses->list[LIST_VARIABLE], arg2, "%d", index + 1); } else { set_nest_node(ses->list[LIST_VARIABLE], arg2, "0"); } return ses; } else { set_nest_node(ses->list[LIST_VARIABLE], arg2, "0"); } return ses; } DO_ARRAY(array_get) { char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE]; arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN); arg = sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_VAR|SUB_FUN); if (*arg2 == 0) { show_message(ses, LIST_VARIABLE, "#SYNTAX: #LIST {variable} GET {index} {variable}"); return ses; } if (list->root) { int index = search_nest_index(list->root, arg1); if (atoi(arg1) == 0 || index == -1) { set_nest_node(ses->list[LIST_VARIABLE], arg2, "0"); } else { set_nest_node(ses->list[LIST_VARIABLE], arg2, "%s", list->root->list[index]->right); } return ses; } else { set_nest_node(ses->list[LIST_VARIABLE], arg2, "0"); } return ses; } DO_ARRAY(array_insert) { char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE]; int cnt, index; arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN); arg = sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_VAR|SUB_FUN); if (!list->root) { list->root = init_list(ses, LIST_VARIABLE, LIST_SIZE); } index = search_nest_index(list->root, arg1); if (atoi(arg1) == 0) { tintin_printf2(ses, "#LIST INS: Invalid index: %s", arg1); return ses; } if (index == -1 || atoi(arg1) < 0) { index++; } for (cnt = index ; cnt < list->root->used ; cnt++) { list->root->list[cnt]->left = refstring(list->root->list[cnt]->left, "%d", cnt + 2); } sprintf(arg1, "%d", index + 1); insert_node_list(list->root, arg1, arg2, ""); return ses; } DO_ARRAY(array_size) { char arg1[BUFFER_SIZE]; arg = sub_arg_in_braces(ses, arg, arg1, GET_ALL, SUB_VAR|SUB_FUN); if (*arg1 == 0) { show_message(ses, LIST_VARIABLE, "#SYNTAX: #LIST {variable} SIZE {variable}"); return ses; } if (list->root) { set_nest_node(ses->list[LIST_VARIABLE], arg1, "%d", list->root->used); return ses; } set_nest_node(ses->list[LIST_VARIABLE], arg1, "0"); return ses; } DO_ARRAY(array_set) { char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE]; arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN); arg = sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_VAR|SUB_FUN); if (list->root) { int index = search_nest_index(list->root, arg1); if (atoi(arg1) == 0 || index == -1) { tintin_printf2(ses, "#LIST SET: Invalid index: %s", arg1); return ses; } RESTRING(list->root->list[index]->right, arg2); return ses; } show_message(ses, LIST_VARIABLE, "#LIST SET: {%s} is not a list.", list->left); return ses; } DO_ARRAY(array_sort) { char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE]; int cnt; arg = sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_VAR|SUB_FUN); if (!list->root) { list->root = init_list(ses, LIST_VARIABLE, LIST_SIZE); } for (cnt = 0 ; cnt < list->root->used ; cnt++) { if (strcmp(arg2, list->root->list[cnt]->right) <= 0) { break; } } sprintf(arg1, "%d", cnt + 1); if (cnt == list->root->used) { sprintf(arg1, "{%d} {%s}", -1, arg2); } else { sprintf(arg1, "{%d} {%s}", cnt + 1, arg2); } array_insert(ses, list, arg1); return ses; }