1 /*******************************************************************************
2 * Reverse Polish Notation calculator. *
3 * Copyright (c) 2007-2008, Samuel Fredrickson <kinghajj@gmail.com> *
4 * All rights reserved. *
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. *
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 *
25 ******************************************************************************/
27 /*******************************************************************************
28 * variables.c - implements the variables table. *
29 ******************************************************************************/
36 //! Creates a new, empty variables table.
38 * @return The new, empty variables table.
40 RPNVariables
*RPN_newVariables()
42 RPNVariables
*variables
= new(RPNVariables
);
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
);
51 //! Creates a new variable.
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
);
61 RPN_error("could not allocate memory for a variable.");
64 RPN_dprintf("allocated variable %p", var
);
68 //! Adds a variable to a variable table.
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
)
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,
84 HASH_ADD_KEYPTR( hh
, variables
->table
, name
, strlen(name
), var
);
85 RPN_dprintf("added variable %p to table %p", var
, variables
);
89 //! Finds a variable by its string representation.
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
;
99 RPN_error("tried to find variable in NULL stack.");
101 RPN_error("tried to find a variable with a NULL name.");
102 HASH_FIND_STR( variables
->table
, name
, 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
);
118 RPN_error("tried to find variable in a NULL variable table.");
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
);
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
)
146 RPN_error("attempted to remove a variable from a NULL variable table.");
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
);
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
)
181 for(var
= variables
->table
; var
!= NULL
; var
= var
->hh
.next
)
182 RPN_printf("%s = " RPN_VALUE_SHORT_FORMAT
", ", var
->name
, var
->value
);
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
)
195 for(var
= variables
->table
; var
!= NULL
; var
= var
->hh
.next
)
196 RPN_printf("%s = " RPN_VALUE_LONG_FORMAT
", ", var
->name
, var
->value
);
200 //! Returns a default variable table.
202 * @return The default variable table.
204 RPNVariables
*RPN_defaultVariables()
206 RPNVariables
*variables
= RPN_newVariables();
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);
224 RPN_addVariable(variables
, strdup("HOURS"), 60 * 60);
225 RPN_addVariable(variables
, strdup("MINUTES"), 60);