Fixed found Valgrind issues.
[rpn.git] / src / variables.c
blob90d9552ba61971645c8323093fde47275ce2553f
1 /*******************************************************************************
2 * Reverse Polish Notation calculator. *
3 * Copyright (c) 2007-2008, Samuel Fredrickson <kinghajj@gmail.com> *
4 * All rights reserved. *
5 * *
6 * Redistribution and use in source and binary forms, with or without *
7 * modification, are permitted provided that the following conditions are met: *
8 * * Redistributions of source code must retain the above copyright *
9 * notice, this list of conditions and the following disclaimer. *
10 * * Redistributions in binary form must reproduce the above copyright *
11 * notice, this list of conditions and the following disclaimer in the *
12 * documentation and/or other materials provided with the distribution. *
13 * *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS *
15 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED *
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
17 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY *
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR *
20 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *
21 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY *
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
24 * DAMAGE. *
25 ******************************************************************************/
27 /*******************************************************************************
28 * variables.c - implements the variables table. *
29 ******************************************************************************/
31 #include "rpn.h"
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
36 //! Creates a new, empty variables table.
37 /**
38 * @return The new, empty variables table.
40 RPNVariables *RPN_newVariables()
42 RPNVariables *variables = new(RPNVariables);
43 if(!variables)
44 RPN_error("could not allocate memory for a variables table.");
45 // uthash.h requires that an empty table hash be set to NULL.
46 variables->table = NULL;
47 RPN_dprintf("allocated variable table %p", variables);
48 return variables;
51 //! Creates a new variable.
52 /**
53 * @param name The string representation of the variable.
54 * @param value The value of the variable.
55 * @return The new variable.
57 RPNVariable *RPN_newVariable(char *name, RPNValue value)
59 RPNVariable *var = new(RPNVariable);
60 if(!var)
61 RPN_error("could not allocate memory for a variable.");
62 var->name = name;
63 var->value = value;
64 RPN_dprintf("allocated variable %p", var);
65 return var;
68 //! Adds a variable to a variable table.
69 /**
70 * @param variables The variable table.
71 * @param name The string representation of the variable.
72 * @param value The value of the variable.
73 * @return true if succeeds.
75 bool RPN_addVariable(RPNVariables *variables, char *name, RPNValue value)
77 RPNVariable *var;
79 if(!variables)
80 RPN_error("tried to push variable to a NULL stack.");
81 var = RPN_newVariable(name, value);
82 // name of hash header, name of hash table, name of key, length of key,
83 // structure to add
84 HASH_ADD_KEYPTR( hh, variables->table, name, strlen(name), var );
85 RPN_dprintf("added variable %p to table %p", var, variables);
86 return true;
89 //! Finds a variable by its string representation.
90 /**
91 * @param variables The variable table.
92 * @param name The string representation of the variable.
93 * @return The variable if found, else NULL.
95 RPNVariable *RPN_findVariable(RPNVariables *variables, char *name)
97 RPNVariable *var = NULL;
98 if(!variables)
99 RPN_error("tried to find variable in NULL stack.");
100 if(!name)
101 RPN_error("tried to find a variable with a NULL name.");
102 HASH_FIND_STR( variables->table, name, var);
103 return var;
106 //! Gets the value of a variable by its string representation.
108 * @param variables The variable table.
109 * @param name The string representation of the variable.
110 * @return The value if found, else 0.
112 RPNValue RPN_getVariableValue(RPNVariables *variables, char *name)
114 RPNVariable *var = RPN_findVariable(variables, name);
115 RPNValue value = 0;
117 if(!variables)
118 RPN_error("tried to find variable in a NULL variable table.");
119 if(var)
120 value = var->value;
122 return value;
125 //! Frees a variable and its string representation.
127 * @param variable The variable to free.
129 void RPN_freeVariable(RPNVariable *variable)
131 if(!variable || !variable->name)
132 RPN_error("attempted to free a NULL variable.");
133 RPN_free(variable->name);
134 RPN_free(variable);
135 RPN_dprintf("freed variable %p", variable);
138 //! Removes a variable from a variable table, then frees it.
140 * @param variables The variable table.
141 * @param variable The variable to remove.
143 void RPN_removeVariable(RPNVariables *variables, RPNVariable *variable)
145 if(!variables)
146 RPN_error("attempted to remove a variable from a NULL variable table.");
147 if(!variable)
148 RPN_error("attempted to remove a NULL variable.");
149 HASH_DEL( variables->table, variable );
150 RPN_freeVariable(variable);
151 RPN_dprintf("removed variable %p from table %p", variable, variables);
154 //! Frees a variable table and all its variables.
156 * @param variables The variable table to free.
158 void RPN_freeVariables(RPNVariables *variables)
160 RPNVariable *variable, *next;
162 // go through every command and remove/free it.
163 for(variable = variables->table; variable != NULL; variable = next) {
164 next = variable->hh.next;
165 RPN_removeVariable(variables, variable);
168 RPN_free(variables);
169 RPN_dprintf("freed variable table %p", variables);
172 //! Prints the variables of a variable table.
174 * @param variables The variable table to print.
176 void RPN_printVariables(RPNVariables *variables)
178 RPNVariable *var;
180 RPN_printf("[ ");
181 for(var = variables->table; var != NULL; var = var->hh.next)
182 RPN_printf("%s = " RPN_VALUE_SHORT_FORMAT ", ", var->name, var->value);
183 RPN_printf("]\n");
186 //! Prints the variables of a variable table in more detail.
188 * @param variables The variable table to print.
190 void RPN_printVariablesDetailed(RPNVariables *variables)
192 RPNVariable *var;
194 RPN_printf("[ ");
195 for(var = variables->table; var != NULL; var = var->hh.next)
196 RPN_printf("%s = " RPN_VALUE_LONG_FORMAT ", ", var->name, var->value);
197 RPN_printf("]\n");
200 //! Returns a default variable table.
202 * @return The default variable table.
204 RPNVariables *RPN_defaultVariables()
206 RPNVariables *variables = RPN_newVariables();
208 // Computer sizes.
209 RPN_addVariable(variables, strdup("KB"), 1000);
210 RPN_addVariable(variables, strdup("MB"), 1000 * 1000);
211 RPN_addVariable(variables, strdup("GB"), 1000 * 1000 * 1000);
212 RPN_addVariable(variables, strdup("KiB"), 1024);
213 RPN_addVariable(variables, strdup("MiB"), 1024 * 1024);
214 RPN_addVariable(variables, strdup("GiB"), 1024 * 1024 * 1024);
215 RPN_addVariable(variables, strdup("Kib"), 1024 / 8);
216 RPN_addVariable(variables, strdup("Mib"), 1024 * 1024 / 8);
217 RPN_addVariable(variables, strdup("Gib"), 1024 * 1024 * 1024 / 8);
219 // Mathematical numbers.
220 RPN_addVariable(variables, strdup("PI"), 3.1415926535897932385);
221 RPN_addVariable(variables, strdup("E"), 2.72828182845904523536);
223 // Time sizes.
224 RPN_addVariable(variables, strdup("HOURS"), 60 * 60);
225 RPN_addVariable(variables, strdup("MINUTES"), 60);
227 return variables;