1 /*
2  * implement arrays for dc
3  *
4  * Copyright (C) 1994, 1997, 1998, 2000, 2006, 2008
5  * Free Software Foundation, Inc.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 /* This module is the only one that knows what arrays look like. */
23 
24 #include "config.h"
25 
26 #include <stdio.h>	/* "dc-proto.h" wants this */
27 #ifdef HAVE_STDLIB_H
28 /* get size_t definition from "almost ANSI" compiling environments. */
29 #include <stdlib.h>
30 #endif
31 #include "dc.h"
32 #include "dc-proto.h"
33 #include "dc-regdef.h"
34 
35 /* what's most useful: quick access or sparse arrays? */
36 /* I'll go with sparse arrays for now */
37 struct dc_array {
38 	int Index;
39 	dc_data value;
40 	struct dc_array *next;
41 };
42 
43 
44 /* initialize the arrays */
45 void
DC_DECLVOID()46 dc_array_init DC_DECLVOID()
47 {
48 }
49 
50 /* store value into array_id[Index] */
51 void
dc_array_set(array_id,Index,value)52 dc_array_set DC_DECLARG((array_id, Index, value))
53 	int array_id DC_DECLSEP
54 	int Index DC_DECLSEP
55 	dc_data value DC_DECLEND
56 {
57 	struct dc_array *cur;
58 	struct dc_array *prev = NULL;
59 
60 	cur = dc_get_stacked_array(array_id);
61 	while (cur != NULL  &&  cur->Index < Index){
62 		prev = cur;
63 		cur = cur->next;
64 	}
65 	if (cur != NULL  &&  cur->Index == Index){
66 		if (cur->value.dc_type == DC_NUMBER)
67 			dc_free_num(&cur->value.v.number);
68 		else if (cur->value.dc_type == DC_STRING)
69 			dc_free_str(&cur->value.v.string);
70 		else
71 			dc_garbage(" in array", array_id);
72 		cur->value = value;
73 	}else{
74 		struct dc_array *newentry = dc_malloc(sizeof *newentry);
75 		newentry->Index = Index;
76 		newentry->value = value;
77 		newentry->next = cur;
78 		if (prev != NULL)
79 			prev->next = newentry;
80 		else
81 			dc_set_stacked_array(array_id, newentry);
82 	}
83 }
84 
85 /* retrieve a dup of a value from array_id[Index] */
86 /* A zero value is returned if the specified value is unintialized. */
87 dc_data
dc_array_get(array_id,Index)88 dc_array_get DC_DECLARG((array_id, Index))
89 	int array_id DC_DECLSEP
90 	int Index DC_DECLEND
91 {
92 	struct dc_array *cur = dc_get_stacked_array(array_id);
93 
94 	while (cur != NULL  &&  cur->Index < Index)
95 		cur = cur->next;
96 	if (cur !=NULL  &&  cur->Index == Index)
97 		return dc_dup(cur->value);
98 	return dc_int2data(0);
99 }
100 
101 /* free an array chain */
102 void
103 dc_array_free DC_DECLARG((a_head))
104 	struct dc_array *a_head DC_DECLEND
105 {
106 	struct dc_array *cur;
107 	struct dc_array *next;
108 
109 	for (cur=a_head; cur!=NULL; cur=next) {
110 		next = cur->next;
111 		if (cur->value.dc_type == DC_NUMBER)
112 			dc_free_num(&cur->value.v.number);
113 		else if (cur->value.dc_type == DC_STRING)
114 			dc_free_str(&cur->value.v.string);
115 		else
116 			dc_garbage("in stack", -1);
117 		free(cur);
118 	}
119 }
120 
121 
122 /*
123  * Local Variables:
124  * mode: C
125  * tab-width: 4
126  * End:
127  * vi: set ts=4 :
128  */
129