first version upgrade
[devspec.git] / devspec.en_US / project / recutils / src / rec-sex-ast.c
blob0a8bb71823ad89791833f9b6f37e7cb77cfd1877
1 /* -*- mode: C -*-
3 * File: rec-sex-ast.c
4 * Date: Tue Jan 12 17:29:03 2010
6 * GNU recutils - SEX Abstract Syntax Trees
8 */
10 /* Copyright (C) 2010-2019 Jose E. Marchesi */
12 /* This program is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include <config.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdio.h>
32 #include <rec-sex-ast.h>
35 * Data types
38 #define REC_SEX_AST_MAX_CHILDREN 3
40 struct rec_sex_ast_node_s
42 enum rec_sex_ast_node_type_e type;
43 union {
44 int integer;
45 double real;
46 char *string;
47 char *name[2];
48 } val;
50 int index;
51 bool fixed;
52 char *fixed_val;
53 rec_sex_ast_node_t children[REC_SEX_AST_MAX_CHILDREN];
54 size_t num_children;
57 struct rec_sex_ast_s
59 rec_sex_ast_node_t top;
63 * Public functions
66 rec_sex_ast_t
67 rec_sex_ast_new ()
69 rec_sex_ast_t new;
71 new = malloc (sizeof (struct rec_sex_ast_s));
72 if (new)
74 new->top = NULL;
77 return new;
80 void
81 rec_sex_ast_destroy (rec_sex_ast_t ast)
83 if (ast->top)
85 rec_sex_ast_node_destroy (ast->top);
88 free (ast);
91 rec_sex_ast_node_t
92 rec_sex_ast_node_new (void)
94 rec_sex_ast_node_t new;
96 new = malloc (sizeof(struct rec_sex_ast_node_s));
97 if (new)
99 new->type = REC_SEX_NOVAL;
100 new->num_children = 0;
101 new->index = -1;
102 new->fixed = false;
103 new->fixed_val = NULL;
106 return new;
109 void
110 rec_sex_ast_node_destroy (rec_sex_ast_node_t node)
112 size_t i;
114 /* Destroy children. */
115 for (i = 0; i < node->num_children; i++)
117 rec_sex_ast_node_destroy (node->children[i]);
120 /* Destroy values. */
121 if (node->type == REC_SEX_STR)
123 free (node->val.string);
125 else if (node->type == REC_SEX_NAME)
127 free (node->val.name[0]);
128 free (node->val.name[1]);
131 free (node->fixed_val);
132 free (node);
135 enum rec_sex_ast_node_type_e
136 rec_sex_ast_node_type (rec_sex_ast_node_t node)
138 return node->type;
141 void
142 rec_sex_ast_node_set_type (rec_sex_ast_node_t node,
143 enum rec_sex_ast_node_type_e type)
145 node->type = type;
149 rec_sex_ast_node_int (rec_sex_ast_node_t node)
151 return node->val.integer;
154 void
155 rec_sex_ast_node_set_int (rec_sex_ast_node_t node,
156 int num)
158 node->type = REC_SEX_INT;
159 node->val.integer = num;
162 double
163 rec_sex_ast_node_real (rec_sex_ast_node_t node)
165 return node->val.real;
168 void
169 rec_sex_ast_node_set_real (rec_sex_ast_node_t node,
170 double num)
172 node->type = REC_SEX_REAL;
173 node->val.real = num;
176 char *
177 rec_sex_ast_node_str (rec_sex_ast_node_t node)
179 return node->val.string;
182 void
183 rec_sex_ast_node_set_str (rec_sex_ast_node_t node,
184 char *str)
186 if (node->type == REC_SEX_STR)
188 free (node->val.string);
191 node->type = REC_SEX_STR;
192 node->val.string = strdup (str);
195 const char *
196 rec_sex_ast_node_name (rec_sex_ast_node_t node)
198 return node->val.name[0];
201 const char *
202 rec_sex_ast_node_subname (rec_sex_ast_node_t node)
204 return node->val.name[1];
207 void
208 rec_sex_ast_node_set_name (rec_sex_ast_node_t node,
209 const char *name,
210 const char *subname)
212 if (node->type == REC_SEX_NAME)
214 free (node->val.name[0]);
215 free (node->val.name[1]);
218 node->type = REC_SEX_NAME;
219 node->val.name[0] = strdup (name);
220 node->val.name[1] = NULL;
221 if (subname)
223 node->val.name[1] = strdup (subname);
227 void
228 rec_sex_ast_node_link (rec_sex_ast_node_t parent,
229 rec_sex_ast_node_t child)
231 if (parent->num_children < REC_SEX_AST_MAX_CHILDREN)
233 parent->children[parent->num_children++] = child;
237 rec_sex_ast_node_t
238 rec_sex_ast_top (rec_sex_ast_t ast)
240 return ast->top;
243 void
244 rec_sex_ast_set_top (rec_sex_ast_t ast,
245 rec_sex_ast_node_t node)
247 ast->top = node;
250 void
251 rec_sex_ast_print_node (rec_sex_ast_node_t node)
253 int i;
255 for (i = 0; i < node->num_children; i++)
257 rec_sex_ast_print_node (node->children[i]);
260 printf ("------- node\n");
261 printf ("type: %d\n", node->type);
262 if (node->type == REC_SEX_INT)
264 printf("value: %d\n", node->val.integer);
266 if (node->type == REC_SEX_NAME)
268 printf("value: %s\n", node->val.name[0]);
270 if (node->type == REC_SEX_STR)
272 printf("value: %s\n", node->val.string);
275 printf("\n");
279 rec_sex_ast_node_num_children (rec_sex_ast_node_t node)
281 return node->num_children;
284 rec_sex_ast_node_t
285 rec_sex_ast_node_child (rec_sex_ast_node_t node,
286 int n)
288 rec_sex_ast_node_t res;
290 res = NULL;
291 if (n < node->num_children)
293 res = node->children[n];
296 return res;
299 void
300 rec_sex_ast_node_reset (rec_sex_ast_node_t node)
302 int i;
304 for (i = 0; i < node->num_children; i++)
306 rec_sex_ast_node_reset (node->children[i]);
309 node->index = 0;
312 void
313 rec_sex_ast_node_fix (rec_sex_ast_node_t node,
314 char *val)
316 free (node->fixed_val);
317 node->fixed = true;
318 node->fixed_val = strdup (val);
321 void
322 rec_sex_ast_node_unfix (rec_sex_ast_node_t node)
324 int i;
326 for (i = 0; i < node->num_children; i++)
328 rec_sex_ast_node_unfix (node->children[i]);
331 node->fixed = false;
334 bool
335 rec_sex_ast_node_fixed (rec_sex_ast_node_t node)
337 return node->fixed;
340 char *
341 rec_sex_ast_node_fixed_val (rec_sex_ast_node_t node)
343 return node->fixed_val;
347 rec_sex_ast_node_index (rec_sex_ast_node_t node)
349 return node->index;
352 void
353 rec_sex_ast_node_set_index (rec_sex_ast_node_t node,
354 int index)
356 node->index = index;
359 void
360 rec_sex_ast_print (rec_sex_ast_t ast)
362 rec_sex_ast_print_node (ast->top);
365 bool
366 rec_sex_ast_name_p_1 (rec_sex_ast_node_t node,
367 const char *name,
368 size_t idx)
370 size_t i = 0;
372 if (node)
374 if ((node->type == REC_SEX_NAME)
375 && ((node->index == -1) || (node->index < idx))
376 && (strcmp (name, node->val.name[0]) == 0))
378 return true;
381 for (i = 0; i < node->num_children; i++)
383 if (rec_sex_ast_name_p_1 (node->children[i], name, idx))
385 return true;
390 return false;
393 bool
394 rec_sex_ast_name_p (rec_sex_ast_t ast,
395 const char *name,
396 size_t idx)
398 /* Traverse the AST looking for any name node NAME[I] where I <
399 idx. */
401 return rec_sex_ast_name_p_1 (ast->top,
402 name,
403 idx);
406 static bool
407 rec_sex_ast_hash_name_p_1 (rec_sex_ast_node_t node,
408 const char *name)
410 if (node)
412 size_t i = 0;
414 if ((node->type == REC_SEX_OP_SHA)
415 && (node->num_children == 1)
416 && (node->children[0]->type == REC_SEX_NAME)
417 && (strcmp (name, node->children[0]->val.name[0]) == 0))
418 return true;
420 for (i = 0; i < node->num_children; i++)
421 if (rec_sex_ast_hash_name_p_1 (node->children[i], name))
422 return true;
425 return false;
428 bool
429 rec_sex_ast_hash_name_p (rec_sex_ast_t ast,
430 const char *name)
432 /* Traverse the AST looking for any name node NAME whose father is a
433 REC_SEX_OP_SHA. */
434 return rec_sex_ast_hash_name_p_1 (ast->top, name);
437 /* End of rec-sex-ast.c */