From e952523a06b81e8915751bdcb01ca87aad06ce1c Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Tue, 14 Feb 2023 00:05:41 +0100 Subject: [PATCH] add worspace type --- calc.c | 2 +- program.c | 180 +++++++++++++++++----------------------------------- program.h | 15 +---- tabular.c | 3 + workspace.c | 100 +++++++++++++++++++++++++++++ workspace.h | 31 +++++++++ 6 files changed, 196 insertions(+), 135 deletions(-) create mode 100644 workspace.c create mode 100644 workspace.h diff --git a/calc.c b/calc.c index 920099b..d444ab1 100644 --- a/calc.c +++ b/calc.c @@ -1,6 +1,6 @@ /* depend: */ /* cflags: */ -/* linker: alloc.o argument.o debug.o element.o format.o parser.o program.o stack.o storage.o tabular.o -lm -lreadline */ +/* linker: alloc.o argument.o debug.o element.o format.o parser.o program.o stack.o storage.o tabular.o workspace.o -lm -lreadline */ #include #include diff --git a/program.c b/program.c index 18a9719..e8cd2d1 100644 --- a/program.c +++ b/program.c @@ -9,125 +9,108 @@ #include "stack.h" #include "storage.h" #include "tabular.h" +#include "workspace.h" #include "program.h" /* global variables */ -workspace_t *programs = NULL; +workspace_t **programs = NULL; int nb_programs = 0; +/* lookfor program id */ + +int lookfor_program (int id) +{ + int i; + for (i = 0; (programs) && (i < nb_programs); i++) { + if (programs[i]->id == id) { + return i; + } + } + return -1; +} + /* program function */ void prog (int id, element_t *root) { - int i, n = -1; + int n = -1; if (programs == NULL) { /* initial memory allocation */ - programs = (workspace_t *) callocordie (1, sizeof (workspace_t)); - nb_programs = 1; + programs = (workspace_t **) callocordie (1, sizeof (workspace_t *)); n = 0; + nb_programs = 1; + programs[n] = alloc_ws (); } else { /* look for existing program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } - } + n = lookfor_program (id); if (n == -1) { /* new program */ n = nb_programs++; - workspace_t *tmp = (workspace_t *) callocordie (nb_programs, sizeof (workspace_t)); - memcpy (tmp, programs, (nb_programs - 1) * sizeof (workspace_t)); + workspace_t **tmp = (workspace_t **) callocordie (nb_programs, sizeof (workspace_t *)); + memcpy (tmp, programs, (nb_programs - 1) * sizeof (workspace_t *)); free (programs); programs = tmp; + programs[n] = alloc_ws (); + } else { /* clean old program */ - if ((programs + n)->storage) { - free_tab ((programs + n)->storage); - } - if ((programs + n)->stack) { - free_tab ((programs + n)->stack); - } - if ((programs + n)->root) { - delelement ((programs + n)->root); - } - if ((programs + n)->string) { - free ((programs + n)->string); - (programs + n)->string = NULL; - } + clean_ws(programs[n]); } } /* set program */ - (programs + n)->id = id; - (programs + n)->answer = 0; - (programs + n)->storage = NULL; - (programs + n)->stack = NULL; - (programs + n)->root = dupelement (root); + programs[n]->id = id; + programs[n]->root = dupelement (root); } double call (int id, int nbargs, element_t **args) { - workspace_t tmp = {0}; - int i, n = -1; double ret = 0; - if (programs) { - - /* look for program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } - } - } + /* look for program */ + int n = lookfor_program (id); if (n == -1) { VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); return 0; } - /* store context */ - tmp.answer = answer; - tmp.argument = argument; - tmp.stack = stack; - tmp.storage = storage; - - /* change context */ - answer = 0; + /* backup context */ + workspace_t *tmp = backup_ws (alloc_ws ()); + restore_ws (programs[n]); + + /* set arguments */ + free_tab (argument); argument = NULL; if (nbargs > 0) { def (nbargs, args); } - stack = (programs + n)->stack; - storage = (programs + n)->storage; /* evaluate program */ - element_t *elements = dupelement ((programs + n)->root); + answer = 0; + element_t *elements = dupelement (programs[n]->root); ret = evaluate_element (elements, 0); delelement (elements); - /* cleaning context */ - (programs + n)->answer = answer; + /* clean arguments */ if (argument) { free_tab (argument); } - (programs + n)->stack = stack; - (programs + n)->storage = storage; + argument = NULL; + if (nbargs > 0) { + def (nbargs, args); + } /* restore context */ - answer = tmp.answer; - argument = tmp.argument; - storage = tmp.storage; - stack = tmp.stack; + backup_ws (programs[n]); + restore_ws (tmp); return ret; } @@ -137,107 +120,62 @@ void list () int i; fprintf (stdout, "programs:"); for (i = 0; i < nb_programs; i++) { - fprintf (stdout, " %d", (programs + i)->id); + fprintf (stdout, " %d", programs[i]->id); } fprintf (stdout, "\n"); } void edit (int id) { - int i, n = -1; - - if (programs) { - - /* look for program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } - } - } + int n = lookfor_program (id); if (n == -1) { VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); return; } /* set string program */ - fprintf (stdout, "edit: %s\n", (programs + n)->string); + fprintf (stdout, "edit: %s\n", programs[n]->string); } void savestring (int id, char *string) { - int i, n = -1; - - if (programs) { - - /* look for program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } - } - } + int n = lookfor_program (id); /* unnecesary code */ //if (n == -1) { // VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); // return; //} - //if ((programs + n)->string) { - // free ((programs + n)->string); + //if (programs[n]->string) { + // free (programs[n]->string); //} if (string) { - (programs + n)->string = strdup (string); + programs[n]->string = strdup (string); } } void del (int id) { - int i, j, n = -1; - - if (programs) { - - /* look for program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } - } - } + int n = lookfor_program (id); if (n == -1) { VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); return; } /* clean program */ - if ((programs + n)->storage) { - free_tab ((programs + n)->storage); - } - if ((programs + n)->stack) { - free_tab ((programs + n)->stack); - } - if ((programs + n)->root) { - delelement ((programs + n)->root); - } - if ((programs + n)->string) { - free ((programs + n)->string); - } + free_ws (programs[n]); /* remove entry */ - workspace_t *tmp = (workspace_t *) callocordie (nb_programs - 1, sizeof (workspace_t)); - for (i = 0, j = 0; i < nb_programs; i++) { - if (i != n) { - memcpy (tmp + j, programs + i, sizeof (workspace_t)); - j++; - } + workspace_t **tmp = (workspace_t **) callocordie (--nb_programs, sizeof (workspace_t *)); + if (n != 0) { + memcpy (tmp, programs, (n - 1) * sizeof (workspace_t)); + } + if (n != nb_programs) { + memcpy (tmp + n - 1, programs + n, (nb_programs - n) * sizeof (workspace_t)); } free (programs); programs = tmp; - nb_programs--; } /* vim: set ts=4 sw=4 et: */ diff --git a/program.h b/program.h index d830b7f..f3f5369 100644 --- a/program.h +++ b/program.h @@ -3,22 +3,11 @@ #include "element.h" #include "tabular.h" +#include "workspace.h" /* global variables */ -/* workspace type */ - -typedef struct _workspace_t { - double answer; - tab_t *argument; - int id; - element_t *root; - tab_t *stack; - tab_t *storage; - char *string; -} workspace_t; - -extern workspace_t *programs; +extern workspace_t **programs; extern int nb_programs; /* program function */ diff --git a/tabular.c b/tabular.c index 0252a8e..60709aa 100644 --- a/tabular.c +++ b/tabular.c @@ -43,6 +43,9 @@ tab_t *resize_tab (tab_t *tab, int nb) tab_t *copy_tab (tab_t *tab) { + if (tab == NULL) { + return NULL; + } tab_t *new = alloc_tab (tab->size); memcpy (new->data, tab->data, tab->size * sizeof (double)); return new; diff --git a/workspace.c b/workspace.c new file mode 100644 index 0000000..26bbe8a --- /dev/null +++ b/workspace.c @@ -0,0 +1,100 @@ +#include +#include + +#include "argument.h" +#include "debug.h" +#include "element.h" +#include "parser.h" +#include "stack.h" +#include "storage.h" +#include "tabular.h" + +#include "workspace.h" + +/* allocate workspace*/ + +workspace_t *alloc_ws () +{ + return (workspace_t *) callocordie (1, sizeof (workspace_t)); +} + +/* backup workspace*/ + +workspace_t *backup_ws (workspace_t *ws) +{ + ws->answer = answer; + ws->argument = copy_tab (argument); + ws->stack = copy_tab (stack); + ws->storage = copy_tab (storage); + return ws; +} + +/* clean workspace */ + +workspace_t *clean_ws (workspace_t *ws) +{ + ws->answer = 0; + + if (ws->argument) { + free_tab (ws->argument); + ws->argument = NULL; + } + + ws->id = 0; + + if (ws->root) { + delelement (ws->root); + ws->root = NULL; + } + + if (ws->stack) { + free_tab (ws->stack); + ws->stack = NULL; + } + + if (ws->string) { + free (ws->string); + ws->string = NULL; + } + + if (ws->storage) { + free_tab (ws->storage); + ws->storage = NULL; + } + + return ws; +} + +/* free workspace */ + +void free_ws (workspace_t *ws) +{ + if (ws) { + clean_ws (ws); + free (ws); + } +} + +/* restore workspace*/ + +void restore_ws (workspace_t *ws) +{ + answer = ws->answer; + + if (argument) { + free_tab (argument); + } + argument = copy_tab (ws->argument); + + if (stack) { + free_tab (stack); + } + stack = copy_tab (ws->stack); + + if (storage) { + free_tab (storage); + } + storage = copy_tab (ws->storage); +} + +/* vim: set ts=4 sw=4 et: */ diff --git a/workspace.h b/workspace.h new file mode 100644 index 0000000..7bca4e0 --- /dev/null +++ b/workspace.h @@ -0,0 +1,31 @@ +#ifndef __WORKSPACE_H__ +#define __WORKSPACE_H__ + +#include "element.h" +#include "tabular.h" + +/* global variables */ + +/* workspace type */ + +typedef struct _workspace_t { + double answer; + tab_t *argument; + int id; + element_t *root; + tab_t *stack; + tab_t *storage; + char *string; +} workspace_t; + +/* workspace functions */ + +workspace_t *alloc_ws (); +workspace_t *backup_ws (workspace_t *ws); +workspace_t *clean_ws (workspace_t *ws); +void free_ws (workspace_t *ws); +void restore_ws (workspace_t *ws); + +#endif /* __WORKSPACE_H__ */ + +/* vim: set ts=4 sw=4 et: */ -- 2.30.2