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