add coverage tests
[calc.git] / program.c
CommitLineData
a24bd519 1#include <malloc.h>
7059478f 2#include <stdio.h>
a24bd519
LM
3#include <string.h>
4
5#include "alloc.h"
c91672f9 6#include "argument.h"
a24bd519
LM
7#include "debug.h"
8#include "parser.h"
9#include "stack.h"
10#include "storage.h"
3559b26c 11#include "tabular.h"
e952523a 12#include "workspace.h"
a24bd519
LM
13
14#include "program.h"
15
16/* global variables */
17
e952523a 18workspace_t **programs = NULL;
a24bd519
LM
19int nb_programs = 0;
20
e952523a
LM
21/* lookfor program id */
22
23int lookfor_program (int id)
24{
25 int i;
26 for (i = 0; (programs) && (i < nb_programs); i++) {
27 if (programs[i]->id == id) {
28 return i;
29 }
30 }
31 return -1;
32}
33
a24bd519
LM
34/* program function */
35
36void prog (int id, element_t *root)
37{
e952523a 38 int n = -1;
a24bd519
LM
39
40 if (programs == NULL) {
41
42 /* initial memory allocation */
e952523a 43 programs = (workspace_t **) callocordie (1, sizeof (workspace_t *));
a24bd519 44 n = 0;
e952523a
LM
45 nb_programs = 1;
46 programs[n] = alloc_ws ();
a24bd519
LM
47
48 } else {
49
50 /* look for existing program */
e952523a 51 n = lookfor_program (id);
a24bd519
LM
52 if (n == -1) {
53
54 /* new program */
55 n = nb_programs++;
e952523a
LM
56 workspace_t **tmp = (workspace_t **) callocordie (nb_programs, sizeof (workspace_t *));
57 memcpy (tmp, programs, (nb_programs - 1) * sizeof (workspace_t *));
a24bd519
LM
58 free (programs);
59 programs = tmp;
e952523a
LM
60 programs[n] = alloc_ws ();
61
a24bd519
LM
62 } else {
63
64 /* clean old program */
e952523a 65 clean_ws(programs[n]);
a24bd519
LM
66 }
67 }
68
69 /* set program */
e952523a
LM
70 programs[n]->id = id;
71 programs[n]->root = dupelement (root);
a24bd519
LM
72}
73
a24bd519
LM
74double call (int id, int nbargs, element_t **args)
75{
a24bd519
LM
76 double ret = 0;
77
e952523a
LM
78 /* look for program */
79 int n = lookfor_program (id);
a24bd519
LM
80 if (n == -1) {
81 VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id));
82 return 0;
83 }
84
e952523a
LM
85 /* backup context */
86 workspace_t *tmp = backup_ws (alloc_ws ());
87 restore_ws (programs[n]);
88
89 /* set arguments */
90 free_tab (argument);
a24bd519 91 argument = NULL;
a24bd519 92 if (nbargs > 0) {
c91672f9 93 def (nbargs, args);
a24bd519
LM
94 }
95
96 /* evaluate program */
e952523a
LM
97 answer = 0;
98 element_t *elements = dupelement (programs[n]->root);
a24bd519
LM
99 ret = evaluate_element (elements, 0);
100 delelement (elements);
c91672f9 101
e952523a 102 /* clean arguments */
a24bd519 103 if (argument) {
c91672f9 104 free_tab (argument);
a24bd519 105 }
e952523a
LM
106 argument = NULL;
107 if (nbargs > 0) {
108 def (nbargs, args);
109 }
a24bd519
LM
110
111 /* restore context */
e952523a
LM
112 backup_ws (programs[n]);
113 restore_ws (tmp);
a24bd519
LM
114
115 return ret;
116}
117
118void list ()
119{
120 int i;
121 fprintf (stdout, "programs:");
122 for (i = 0; i < nb_programs; i++) {
e952523a 123 fprintf (stdout, " %d", programs[i]->id);
a24bd519
LM
124 }
125 fprintf (stdout, "\n");
126}
127
128void edit (int id)
129{
e952523a 130 int n = lookfor_program (id);
a24bd519
LM
131 if (n == -1) {
132 VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id));
133 return;
134 }
135
136 /* set string program */
e952523a 137 fprintf (stdout, "edit: %s\n", programs[n]->string);
a24bd519
LM
138}
139
140void savestring (int id, char *string)
141{
e952523a 142 int n = lookfor_program (id);
a24bd519
LM
143
144 /* unnecesary code */
145 //if (n == -1) {
146 // VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id));
147 // return;
148 //}
e952523a
LM
149 //if (programs[n]->string) {
150 // free (programs[n]->string);
a24bd519
LM
151 //}
152
153 if (string) {
e952523a 154 programs[n]->string = strdup (string);
a24bd519
LM
155 }
156}
157
158void del (int id)
159{
e952523a 160 int n = lookfor_program (id);
a24bd519
LM
161 if (n == -1) {
162 VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id));
163 return;
164 }
165
166 /* clean program */
e952523a 167 free_ws (programs[n]);
a24bd519
LM
168
169 /* remove entry */
5d50462b
LM
170 workspace_t **tmp = (workspace_t **) callocordie (nb_programs - 1, sizeof (workspace_t *));
171 memcpy (tmp, programs, n * sizeof (workspace_t *));
172 memcpy (tmp + n, programs + n + 1, (nb_programs - n - 1) * sizeof (workspace_t *));
173 nb_programs--;
a24bd519
LM
174 free (programs);
175 programs = tmp;
a24bd519
LM
176}
177
178/* vim: set ts=4 sw=4 et: */