wcalc  2.5
About: Wcalc is a natural-expression command-line calculator.
  Fossies Dox: wcalc-2.5.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

variables.c
Go to the documentation of this file.
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4 
5 /* System Headers */
6 #include <ctype.h>
7 #if HAVE_STRING_H || !defined(HAVE_CONFIG_H)
8 # include <string.h>
9 #endif
10 
11 /* Internal Headers */
12 #include "number.h"
13 #include "calculator.h" /* for report_error */
14 #include "list.h"
15 #include "variables.h"
16 #include "output.h"
17 
18 #define THE_VALUE 0
19 #define THE_STRUCTURE 2
20 #define THE_EXPRESSION 4
21 #define HASH_LENGTH = 101
22 
23 List them = NULL;
24 
25 /* Hidden, internal functions */
26 static void *getvar_core(const char *key,
27  const int all_or_nothing);
28 
29 void initvar(void)
30 { /*{{{ */
31 } /*}}} */
32 
33 /* This function deletes all the variables and frees all the memory. */
34 void cleanupvar(void)
35 { /*{{{ */
36  variable_t *freeme;
37 
38  while ((freeme = (variable_t *)getHeadOfList(them)) != NULL) {
39  free(freeme->key);
40  if (freeme->exp == 1) {
41  free(freeme->expression);
42  } else {
43  num_free(freeme->value);
44  }
45  if (freeme->description) {
46  free(freeme->description);
47  }
48  free(freeme);
49  }
50 } /*}}} */
51 
52 /* Returns the number of variables */
53 size_t numvars()
54 { /*{{{ */
55  return listLen(them);
56 } /*}}} */
57 
58 /* prints out all the variables */
59 void printvariables(void)
60 { /*{{{*/
61  ListIterator li = NULL;
62  variable_t *cursor = NULL;
63  unsigned digits = 1;
64 
65  if (!them || (listLen(them) == 0)) {
66  return;
67  }
68 
69  {
70  unsigned len = listLen(them);
71  while (len > 9) {
72  digits++;
73  len /= 10;
74  }
75  }
76 
77  li = getListIterator(them);
78  cursor = (variable_t *)nextListElement(li);
79  if (cursor != NULL) {
80  unsigned count = 1;
81  display_var(cursor, count++, digits);
82  while ((cursor = (variable_t *)nextListElement(li)) != NULL) {
83  display_var(cursor, count++, digits);
84  }
85  }
86  freeListIterator(li);
87 } /*}}}*/
88 
89 /* returns a list of variables (only the base array is malloc'd, the rest must
90  * NOT be freed */
91 char **listvarnames(void)
92 { /*{{{*/
93  size_t i;
94  char **ret = calloc(listLen(them) + 1, sizeof(char *));
95  ListIterator li = NULL;
96  variable_t *cursor = NULL;
97 
98  if (!them || (listLen(them) == 0)) {
99  return ret;
100  }
101 
102  li = getListIterator(them);
103  i = 0;
104  while ((cursor = (variable_t *)nextListElement(li)) != NULL) {
105  ret[i++] = cursor->key;
106  }
107  freeListIterator(li);
108  return ret;
109 /*}}}*/ }
110 
111 void delnvar(const size_t i)
112 { /*{{{ */
113  variable_t *freeme;
114 
115  freeme = (variable_t *)getListElement(them, i);
116  if (freeme) {
117  free(freeme->key);
118  if (freeme->exp == 1) {
119  free(freeme->expression);
120  } else {
121  num_free(freeme->value);
122  }
123  free(freeme);
124  }
125 } /*}}} */
126 
127 variable_t *getrealnvar(const size_t i)
128 { /*{{{ */
129  return (variable_t *)peekListElement(them, i);
130 } /*}}} */
131 
132 answer_t getvar(const char *key)
133 { /*{{{ */
134  answer_t ans;
135  Number *t = getvar_core(key, THE_VALUE);
136 
137  if (t) {
138  num_init_set(ans.val, *t);
139  ans.err = 0;
140  ans.exp = NULL;
141  } else {
142  /* it's an error.
143  * if you access ans.val, you deserve what you get */
144  ans.exp = NULL;
145  ans.err = 1;
146  }
147  return ans;
148 } /*}}} */
149 
150 void getvarval(Number out,
151  const char *key)
152 { /*{{{ */
153  Number *t = getvar_core(key, THE_VALUE);
154 
155  if (t) {
156  num_set(out, *t);
157  }
158 } /*}}} */
159 
160 answer_t getvar_full(const char *key)
161 { /*{{{ */
162  answer_t ans;
163  variable_t *var;
164 
165  var = getvar_core(key, THE_STRUCTURE);
166  if (var && !var->exp) {
167  num_init_set(ans.val, var->value);
168  ans.err = 0;
169  ans.exp = NULL;
170  ans.desc = var->description;
171  } else if (var && var->exp) {
172  ans.exp = var->expression;
173  ans.desc = var->description;
174  ans.err = 0;
175  } else {
176  ans.exp = NULL;
177  ans.err = 1;
178  }
179  return ans;
180 } /*}}} */
181 
182 /* This function returns 1 if a variable by that key has already been created
183  * and returns 0 if a variable by that key has not been created yet */
184 int varexists(const char *key)
185 { /*{{{ */
186  variable_t *cursor = NULL;
187  ListIterator li = NULL;
188 
189  if (!them || !strlen(key) || (listLen(them) == 0)) {
190  return 0;
191  }
192 
193  li = getListIterator(them);
194  while ((cursor = (variable_t *)nextListElement(li)) != NULL) {
195  if (!strncmp(cursor->key, key, strlen(cursor->key) + 1)) {
196  break;
197  } else {
198  cursor = NULL;
199  }
200  }
201  freeListIterator(li);
202  return cursor ? 1 : 0;
203 } /*}}} */
204 
205 static void *getvar_core(const char *key,
206  const int all_or_nothing)
207 { /*{{{ */
208  variable_t *cursor = NULL;
209  ListIterator li = NULL;
210 
211  if (!them || (key == NULL) || (*key == 0) || (listLen(them) == 0)) {
212  return NULL;
213  }
214 
215  li = getListIterator(them);
216  while ((cursor = (variable_t *)nextListElement(li)) != NULL) {
217  if (!strncmp(cursor->key, key, strlen(cursor->key) + 1)) {
218  break;
219  } else {
220  cursor = NULL;
221  }
222  }
223  freeListIterator(li);
224  if (cursor) {
225  switch (all_or_nothing) {
226  case THE_VALUE:
227  if (cursor->exp) {
228  return NULL;
229  } else {
230  return &(cursor->value);
231  }
232  case THE_STRUCTURE:
233  return cursor;
234 
235  case THE_EXPRESSION:
236  return cursor->expression;
237  }
238  }
239  return NULL;
240 } /*}}} */
241 
242 /* this adds the key-expression pair to the list.
243  * if the key already exists, change the value to this */
244 int putexp(const char *key,
245  const char *value,
246  const char *desc)
247 { /*{{{ */
248  variable_t *cursor = NULL;
249 
250  if (*key == 0) {
251  return -1;
252  }
253 
254  cursor = getvar_core(key, THE_STRUCTURE);
255  if (!cursor) {
256  // variable named "key" doesn't exist yet, so allocate memory
257  cursor = calloc(sizeof(variable_t), 1);
258  addToList(&them, cursor);
259  }
260  // by this point, we have a variable (cursor) in the list (them)
261  if (cursor->key) {
262  if (cursor->expression) {
263  free(cursor->expression);
264  } else {
265  num_free(cursor->value);
266  }
267  if (cursor->description) {
268  free(cursor->description);
269  }
270  } else {
271  cursor->key = (char *)strdup(key);
272  }
273  // by this point, the cursor has been prepared to accept the exp/desc
274  cursor->expression = (char *)strdup(value);
275  if (desc != NULL) {
276  cursor->description = (char *)strdup(desc);
277  } else {
278  cursor->description = NULL;
279  }
280  cursor->exp = 1;
281  return 0;
282 } /*}}} */
283 
284 /* this adds the key-value pair to the list.
285  * if the key already exists, change the value to this */
286 int putval(const char *key,
287  const Number value,
288  const char *desc)
289 { /*{{{ */
290  variable_t *cursor = NULL;
291 
292  if ((key == NULL) || (*key == 0)) {
293  return -1;
294  }
295 
296  cursor = getvar_core(key, THE_STRUCTURE);
297  if (!cursor) {
298  // variable named "key" doesn't exist yet, so allocate memory
299  cursor = calloc(1, sizeof(variable_t));
300  addToList(&them, cursor);
301  }
302  // by this point, we have a variable (cursor) in the list (them)
303  // but key may not exist, and value may not be properly initialized
304  if (!cursor->key) {
305  cursor->key = (char *)strdup(key);
306  num_init(cursor->value);
307  } else if (cursor->expression) {
308  free(cursor->expression);
309  cursor->expression = NULL;
310  num_init(cursor->value);
311  }
312  if (cursor->description) {
313  free(cursor->description);
314  }
315  cursor->exp = 0;
316  // by this point, the variable has a key, and an initialized value,
317  // and is ready to receive the correct value/desc
318  if (desc != NULL) {
319  cursor->description = (char *)strdup(desc);
320  } else {
321  cursor->description = NULL;
322  }
323  num_set(cursor->value, value);
324  return 0;
325 } /*}}} */
326 
327 /* vim:set expandtab: */
answer::desc
char * desc
Definition: variables.h:32
peekListElement
void * peekListElement(List, size_t)
Definition: list.c:284
_list_iterator
Definition: list.c:27
display_var
void display_var(variable_t *v, unsigned count, unsigned digits)
Definition: main.c:1563
THE_STRUCTURE
#define THE_STRUCTURE
Definition: variables.c:19
num_init_set
void num_init_set(Number n1, const Number n2)
Definition: number.c:74
calculator.h
cleanupvar
void cleanupvar(void)
Definition: variables.c:34
getvarval
void getvarval(Number out, const char *key)
Definition: variables.c:150
putexp
int putexp(const char *key, const char *value, const char *desc)
Definition: variables.c:244
free
void free(void *)
delnvar
void delnvar(const size_t i)
Definition: variables.c:111
getrealnvar
variable_t * getrealnvar(const size_t i)
Definition: variables.c:127
variables.h
getHeadOfList
void * getHeadOfList(List)
Definition: list.c:264
listLen
size_t listLen(List)
Definition: list.c:352
variable::exp
unsigned int exp
Definition: variables.h:25
initvar
void initvar(void)
Definition: variables.c:29
_list
Definition: list.c:19
addToList
void addToList(List *, void *)
Definition: list.c:204
variable::description
char * description
Definition: variables.h:23
answer
Definition: variables.h:29
num_init
void num_init(Number n)
Definition: number.c:69
getvar
answer_t getvar(const char *key)
Definition: variables.c:132
Number
#define Number
Definition: number.h:23
num_set
void num_set(Number n1, const Number n2)
Definition: number.c:105
getvar_core
static void * getvar_core(const char *key, const int all_or_nothing)
Definition: variables.c:205
answer::err
unsigned int err
Definition: variables.h:33
answer::exp
char * exp
Definition: variables.h:31
putval
int putval(const char *key, const Number value, const char *desc)
Definition: variables.c:286
numvars
size_t numvars()
Definition: variables.c:53
listvarnames
char ** listvarnames(void)
Definition: variables.c:91
num_free
void num_free(Number n)
Definition: number.c:738
THE_EXPRESSION
#define THE_EXPRESSION
Definition: variables.c:20
printvariables
void printvariables(void)
Definition: variables.c:59
getListIterator
ListIterator getListIterator(List)
Definition: list.c:362
THE_VALUE
#define THE_VALUE
Definition: variables.c:18
nextListElement
void * nextListElement(ListIterator)
Definition: list.c:385
variable::expression
char * expression
Definition: variables.h:22
varexists
int varexists(const char *key)
Definition: variables.c:184
variable::value
mpfr_t value
Definition: variables.h:24
freeListIterator
void freeListIterator(ListIterator)
Definition: list.c:406
getvar_full
answer_t getvar_full(const char *key)
Definition: variables.c:160
variable
Definition: variables.h:20
answer::val
mpfr_t val
Definition: variables.h:30
them
List them
Definition: variables.c:23
list.h
number.h
getListElement
void * getListElement(List, size_t)
Definition: list.c:305
output.h
variable::key
char * key
Definition: variables.h:21