/* Hey EMACS -*- linux-c -*- */
/* $Id: dirlist.c 733 2004-05-28 21:11:48Z roms $ */
/* libticalcs - Ti Calculator library, a part of the TiLP project
* Copyright (C) 1999-2004 Romain Lievin
*
* 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.
*/
/*
Utility functions for directory list (tree)
They support both format (old and new format introduced in v4.4.3)
*/
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "gettext.h"
#include "calc_def.h"
#include "headers.h"
#include "tnode.h"
#include "printl.h"
static tboolean free_varentry(TNode * node, tpointer data)
{
if (node)
free(node->data);
return FALSE;
}
TIEXPORT void TICALL ticalc_dirlist_destroy(TNode ** tree)
{
if (*tree != NULL) {
t_node_traverse(*tree, T_IN_ORDER, T_TRAVERSE_ALL, -1,
free_varentry, NULL);
t_node_destroy(*tree);
*tree = NULL;
}
}
static void dirlist_display_vars(TNode * tree)
{
int i, j, k;
TNode *vars = tree;
printl2(0, "+------------------+----------+----+----+----------+----------+\n");
printl2(0, _("| B. name | T. name |Attr|Type| Size | Parent |\n"));
printl2(0, "+------------------+----------+----+----+----------+----------+\n");
for (i = 0; i < (int)t_node_n_children(vars); i++) // parse folders
{
TNode *parent = t_node_nth_child(vars, i);
TiVarEntry *fe = (TiVarEntry *) (parent->data);
if (fe != NULL) {
printl2(0, "| ");
for (k = 0; k < 8; k++)
printl2(0, "%02X", (uint8_t) (fe->name)[k]);
printl2(0, " | ");
printl2(0, "%8s", fe->trans);
printl2(0, " | ");
printl2(0, "%2i", fe->attr);
printl2(0, " | ");
printl2(0, "%02X", fe->type);
printl2(0, " | ");
printl2(0, "%08X", fe->size);
printl2(0, " | ");
printl2(0, "%8s", fe->folder);
printl2(0, " |\n");
}
for (j = 0; j < (int)t_node_n_children(parent); j++) //parse variables
{
TNode *child = t_node_nth_child(parent, j);
TiVarEntry *ve = (TiVarEntry *) (child->data);
printl2(0, "| ");
for (k = 0; k < 8; k++) {
printl2(0, "%02X", (uint8_t) (ve->name)[k]);
}
printl2(0, " | ");
printl2(0, "%8s", ve->trans);
printl2(0, " | ");
printl2(0, "%2i", ve->attr);
printl2(0, " | ");
printl2(0, "%02X", ve->type);
printl2(0, " | ");
printl2(0, "%08X", ve->size);
printl2(0, " | ");
printl2(0, "%8s", ve->folder);
printl2(0, " |\n");
}
}
if (!i)
printl2(0, _(" No variables\n"));
printl2(0, _
("+------------------+----------+----+----+----------+----------+\n"));
}
static void dirlist_display_apps(TNode * tree)
{
int i, k;
TNode *apps = tree;
printl2(0, "+------------------+----------+----+----+----------+\n");
printl2(0, _("| B. name | T. name |Attr|Type| Size |\n"));
printl2(0, "+------------------+----------+----+----+----------+\n");
for (i = 0; i < (int)t_node_n_children(apps); i++) {
TNode *child = t_node_nth_child(apps, i);
TiVarEntry *ve = (TiVarEntry *) (child->data);
printl2(0, "| ");
for (k = 0; k < 8; k++) {
printl2(0, "%02X", (uint8_t) (ve->name)[k]);
}
printl2(0, " | ");
printl2(0, "%8s", ve->trans);
printl2(0, " | ");
printl2(0, "%2i", ve->attr);
printl2(0, " | ");
printl2(0, "%02X", ve->type);
printl2(0, " | ");
printl2(0, "%08X", ve->size);
printl2(0, " |\n");
}
if (!i)
printl2(0, _(" No applications\n"));
printl2(0, "+------------------+----------+----+----+----------+\n");
printl2(0, "\n");
}
static void dirlist_display1(TNode * tree)
{
TNode *vars, *apps;
if (tree == NULL)
return;
// List variables
vars = t_node_nth_child(tree, 0);
if (vars == NULL)
return;
dirlist_display_vars(vars);
// List applications
apps = t_node_nth_child(tree, 1);
if (apps == NULL)
return;
dirlist_display_apps(apps);
}
TIEXPORT void TICALL ticalc_dirlist_display(TNode * tree)
{
if (tree == NULL)
return;
// Determine tree format
if (tree->data == NULL) {
printl2(0, "dirlist form #1: vars & apps\n");
dirlist_display1(tree);
} else {
char *node_name = (char *) tree->data;
if (!strcmp(node_name, VAR_NODE_NAME)) {
printl2(0, "dirlist form #2: vars\n");
dirlist_display_vars(tree);
} else if (!strcmp(node_name, APP_NODE_NAME)) {
printl2(0, "dirlist form #2: apps\n");
dirlist_display_apps(tree);
} else {
printl2(2, "invalid tree !\n");
printl2(2, "Program halted before crashing...\n");
exit(-1);
}
}
}
TIEXPORT TiVarEntry *TICALL ticalc_check_if_var_exists(TNode * tree,
char *full_name)
{
int i, j;
TNode *vars;
char fldname[18];
char varname[18];
strcpy(fldname, tifiles_get_fldname(full_name));
strcpy(varname, tifiles_get_varname(full_name));
if (tree == NULL)
return NULL;
if (tree->data == NULL) { // old format
vars = t_node_nth_child(tree, 0);
if (vars == NULL)
return NULL;
} else { // new format
vars = tree;
if (strcmp(vars->data, VAR_NODE_NAME))
return 0;
}
for (i = 0; i < (int)t_node_n_children(vars); i++) // parse folders
{
TNode *parent = t_node_nth_child(vars, i);
TiVarEntry *fe = (TiVarEntry *) (parent->data);
if ((fe != NULL) && strcmp(fe->name, fldname))
continue;
for (j = 0; j < (int)t_node_n_children(parent); j++) //parse variables
{
TNode *child = t_node_nth_child(parent, j);
TiVarEntry *ve = (TiVarEntry *) (child->data);
if (!strcmp(ve->name, varname))
return ve;
}
}
return NULL;
}
TIEXPORT TiVarEntry *TICALL ticalc_check_if_app_exists(TNode * tree,
char *appname)
{
int i;
TNode *apps;
if (tree == NULL)
return NULL;
if (tree->data == NULL) { // old format
apps = t_node_nth_child(tree, 1);
if (apps == NULL)
return NULL;
} else { // new format
apps = tree;
if (strcmp(apps->data, APP_NODE_NAME))
return 0;
}
for (i = 0; i < (int)t_node_n_children(apps); i++) {
TNode *child = t_node_nth_child(apps, i);
TiVarEntry *ve = (TiVarEntry *) (child->data);
if (!strcmp(ve->name, appname))
return ve;
}
return NULL;
}
TIEXPORT int TICALL ticalc_dirlist_numvars(TNode * tree)
{
int i, j;
TNode *vars;
int nvars = 0;
if (tree == NULL)
return 0;
// List variables
if (tree->data == NULL) { // old format
vars = t_node_nth_child(tree, 0);
if (vars == NULL)
return 0;
} else { // new format
vars = tree;
if (strcmp(vars->data, VAR_NODE_NAME))
return 0;
}
for (i = 0; i < (int)t_node_n_children(vars); i++) // parse folders
{
TNode *parent = t_node_nth_child(vars, i);
for (j = 0; j < (int)t_node_n_children(parent); j++) //parse variables
{
nvars++;
}
}
return nvars;
}
TIEXPORT int TICALL ticalc_dirlist_memused(TNode * tree)
{
int i, j;
TNode *vars;
uint32_t mem = 0;
if (tree == NULL)
return 0;
// List variables
vars = t_node_nth_child(tree, 0);
if (vars == NULL)
return 0;
for (i = 0; i < (int)t_node_n_children(vars); i++) // parse folders
{
TNode *parent = t_node_nth_child(vars, i);
for (j = 0; j < (int)t_node_n_children(parent); j++) //parse variables
{
TNode *child = t_node_nth_child(parent, j);
TiVarEntry *ve = (TiVarEntry *) (child->data);
mem += ve->size;
}
}
return mem;
}
/*
The returned array is a NULL terminated array of string.
It is pre-initialized with ACT_OVER(write).
*/
TIEXPORT char **TICALL ticalc_action_create_array(int num_entries)
{
char **ptr;
int i;
ptr = (char **) calloc(num_entries + 1, sizeof(char *));
if (ptr == NULL)
return NULL;
for (i = 0; i < num_entries; i++) {
ptr[i] = (char *) calloc(18, sizeof(char));
ptr[i][0] = ACT_OVER;
}
return ptr;
}
TIEXPORT void TICALL ticalc_action_destroy_array(char **array)
{
int i;
if (array == NULL)
return;
for (i = 0; array[i] != NULL; i++)
free(array[i]);
free(array);
}
/*
Implement new tree format by using old functions (maintains compatibility)
Simply break the tree into 2 sub-trees but take care of memory.
*/
TicalcFncts *tcf;
int tixx_directorylist2(TNode ** vars, TNode ** apps, uint32_t * memory)
{
TNode *tree;
TNode *var_node, *app_node;
int err;
// Get old directory list
err = tcf->directorylist(&tree, memory);
if (err) {
*vars = *apps = NULL;
return err;
}
// Get Vars tree
var_node = t_node_nth_child(tree, 0);
var_node->data = strdup(VAR_NODE_NAME); // so that it can be freed !
// Get Apps tree
app_node = t_node_nth_child(tree, 1);
app_node->data = strdup(APP_NODE_NAME);
// Split trees
t_node_unlink(var_node);
t_node_unlink(app_node);
t_node_destroy(tree);
// Returns new trees
*vars = var_node;
*apps = app_node;
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1