missing end of line
[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"
a24bd519
LM
12
13#include "program.h"
14
15/* global variables */
16
a24bd519
LM
17workspace_t *programs = NULL;
18int nb_programs = 0;
19
20/* program function */
21
22void prog (int id, element_t *root)
23{
24 int i, n = -1;
25
26 if (programs == NULL) {
27
28 /* initial memory allocation */
29 programs = (workspace_t *) callocordie (1, sizeof (workspace_t));
30 nb_programs = 1;
31 n = 0;
32
33 } else {
34
35 /* look for existing program */
36 for (i = 0; i < nb_programs; i++) {
37 if ((programs + i)->id == id) {
38 n = i;
39 break;
40 }
41 }
42 if (n == -1) {
43
44 /* new program */
45 n = nb_programs++;
46 workspace_t *tmp = (workspace_t *) callocordie (nb_programs, sizeof (workspace_t));
47 memcpy (tmp, programs, (nb_programs - 1) * sizeof (workspace_t));
48 free (programs);
49 programs = tmp;
50 } else {
51
52 /* clean old program */
53 if ((programs + n)->storage) {
893638e2 54 free_tab ((programs + n)->storage);
a24bd519
LM
55 }
56 if ((programs + n)->stack) {
3559b26c 57 free_tab ((programs + n)->stack);
a24bd519
LM
58 }
59 if ((programs + n)->root) {
60 delelement ((programs + n)->root);
61 }
62 if ((programs + n)->string) {
63 free ((programs + n)->string);
64 (programs + n)->string = NULL;
65 }
66 }
67 }
68
69 /* set program */
70 (programs + n)->id = id;
71 (programs + n)->answer = 0;
72 (programs + n)->storage = NULL;
a24bd519 73 (programs + n)->stack = NULL;
a24bd519
LM
74 (programs + n)->root = dupelement (root);
75}
76
a24bd519
LM
77double call (int id, int nbargs, element_t **args)
78{
79 workspace_t tmp = {0};
c91672f9 80 int i, n = -1;
a24bd519
LM
81 double ret = 0;
82
83 if (programs) {
84
85 /* look for program */
86 for (i = 0; i < nb_programs; i++) {
87 if ((programs + i)->id == id) {
88 n = i;
89 break;
90 }
91 }
92 }
93 if (n == -1) {
94 VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id));
95 return 0;
96 }
97
98 /* store context */
99 tmp.answer = answer;
100 tmp.argument = argument;
a24bd519 101 tmp.stack = stack;
c91672f9 102 tmp.storage = storage;
a24bd519
LM
103
104 /* change context */
105 answer = 0;
a24bd519 106 argument = NULL;
a24bd519 107 if (nbargs > 0) {
c91672f9 108 def (nbargs, args);
a24bd519 109 }
c91672f9
LM
110 stack = (programs + n)->stack;
111 storage = (programs + n)->storage;
a24bd519
LM
112
113 /* evaluate program */
114 element_t *elements = dupelement ((programs + n)->root);
115 ret = evaluate_element (elements, 0);
116 delelement (elements);
c91672f9
LM
117
118 /* cleaning context */
a24bd519 119 (programs + n)->answer = answer;
a24bd519 120 if (argument) {
c91672f9 121 free_tab (argument);
a24bd519
LM
122 }
123 (programs + n)->stack = stack;
c91672f9 124 (programs + n)->storage = storage;
a24bd519
LM
125
126 /* restore context */
127 answer = tmp.answer;
a24bd519 128 argument = tmp.argument;
c91672f9 129 storage = tmp.storage;
a24bd519 130 stack = tmp.stack;
a24bd519
LM
131
132 return ret;
133}
134
135void list ()
136{
137 int i;
138 fprintf (stdout, "programs:");
139 for (i = 0; i < nb_programs; i++) {
140 fprintf (stdout, " %d", (programs + i)->id);
141 }
142 fprintf (stdout, "\n");
143}
144
145void edit (int id)
146{
147 int i, n = -1;
148
149 if (programs) {
150
151 /* look for program */
152 for (i = 0; i < nb_programs; i++) {
153 if ((programs + i)->id == id) {
154 n = i;
155 break;
156 }
157 }
158 }
159 if (n == -1) {
160 VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id));
161 return;
162 }
163
164 /* set string program */
165 fprintf (stdout, "edit: %s\n", (programs + n)->string);
166}
167
168void savestring (int id, char *string)
169{
170 int i, n = -1;
171
172 if (programs) {
173
174 /* look for program */
175 for (i = 0; i < nb_programs; i++) {
176 if ((programs + i)->id == id) {
177 n = i;
178 break;
179 }
180 }
181 }
182
183 /* unnecesary code */
184 //if (n == -1) {
185 // VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id));
186 // return;
187 //}
188 //if ((programs + n)->string) {
189 // free ((programs + n)->string);
190 //}
191
192 if (string) {
193 (programs + n)->string = strdup (string);
194 }
195}
196
197void del (int id)
198{
199 int i, j, n = -1;
200
201 if (programs) {
202
203 /* look for program */
204 for (i = 0; i < nb_programs; i++) {
205 if ((programs + i)->id == id) {
206 n = i;
207 break;
208 }
209 }
210 }
211 if (n == -1) {
212 VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id));
213 return;
214 }
215
216 /* clean program */
217 if ((programs + n)->storage) {
893638e2 218 free_tab ((programs + n)->storage);
a24bd519
LM
219 }
220 if ((programs + n)->stack) {
3559b26c 221 free_tab ((programs + n)->stack);
a24bd519
LM
222 }
223 if ((programs + n)->root) {
224 delelement ((programs + n)->root);
225 }
226 if ((programs + n)->string) {
227 free ((programs + n)->string);
228 }
229
230 /* remove entry */
231 workspace_t *tmp = (workspace_t *) callocordie (nb_programs - 1, sizeof (workspace_t));
232 for (i = 0, j = 0; i < nb_programs; i++) {
233 if (i != n) {
234 memcpy (tmp + j, programs + i, sizeof (workspace_t));
235 j++;
236 }
237 }
238 free (programs);
239 programs = tmp;
240 nb_programs--;
241}
242
243/* vim: set ts=4 sw=4 et: */