fix bracket evaluation
[calc.git] / tabular.c
1 #include <malloc.h>
2 #include <math.h>
3 #include <stdio.h>
4 #include <string.h>
5
6 #include "debug.h"
7 #include "alloc.h"
8
9 #include "tabular.h"
10
11 /* management function */
12
13 /* allocate a tab of N elements */
14
15 tab_t *alloc_tab (int nb)
16 {
17 tab_t *tab = (tab_t *) callocordie (1, sizeof (tab_t));
18 if (nb > 0) {
19 tab->data = (double *) callocordie (nb, sizeof (double));
20 tab->size = nb;
21 }
22 return (tab);
23 }
24
25 /* resize a tab to size N */
26
27 tab_t *resize_tab (tab_t *tab, int nb)
28 {
29 double *tmp = NULL;
30 tab = (tab) ? tab : (tab_t *) callocordie (1, sizeof (tab_t));
31 nb = (nb > 0) ? nb : 0;
32 if (nb > 0) {
33 tmp = (double *) callocordie (nb, sizeof (double));
34 memcpy (tmp, tab->data, ((tab->size < nb) ? tab->size : nb) * sizeof (double));
35 }
36 if (tab->data){
37 free (tab->data);
38 }
39 tab->data = tmp;
40 tab->size = nb;
41 return tab;
42 }
43
44 /* copy a tab */
45
46 tab_t *copy_tab (tab_t *tab)
47 {
48 if (tab == NULL) {
49 return NULL;
50 }
51 tab_t *new = alloc_tab (tab->size);
52 memcpy (new->data, tab->data, tab->size * sizeof (double));
53 return new;
54 }
55
56 /* free a tab */
57
58 void free_tab (tab_t *tab)
59 {
60 if (tab) {
61 if (tab->data) {
62 free (tab->data);
63 }
64 free (tab);
65 }
66 }
67
68 /* get table size */
69
70 int size_tab (tab_t *tab)
71 {
72 int ret = 0;
73 if (tab) {
74 ret = tab->size;
75 }
76 return ret;
77 }
78
79 /* set an element into a tab at position id [1..N] */
80
81 double set_tab (tab_t *tab, int id, double val)
82 {
83 double ret = NAN;
84 if ((!tab) || (id < 1) || (id > tab->size)) {
85 VERBOSE (WARNING, fprintf (stdout, "error out of bounds (%d/%d)\n", id, (tab) ? tab->size : 0));
86 } else {
87 ret = tab->data[id - 1] = val;
88 }
89 return ret;
90 }
91
92 /* get an element from a tab at position id [1..N] */
93
94 double get_tab (tab_t *tab, int id)
95 {
96 double ret = NAN;
97 if ((!tab) || (id < 1) || (id > tab->size)) {
98 VERBOSE (WARNING, fprintf (stdout, "error out of bounds (%d/%d)\n", id, (tab) ? tab->size : 0));
99 } else {
100 ret = tab->data[id - 1];
101 }
102 return ret;
103 }
104
105 /* push an element into a tab at position id [1.. N](-1 means end) resulting to a tab of N+1 elements */
106
107 double push_tab (tab_t *tab, int id, double val)
108 {
109 double ret = NAN;
110 if ((!tab) || (((id < 1) || (id > tab->size + 1)) && (id != -1))) {
111 VERBOSE (WARNING, fprintf (stdout, "error out of bounds (%d/%d)\n", id, (tab) ? tab->size : 0));
112 } else {
113
114 /* special case for inserting an element at the end */
115 id = (id == -1) ? tab->size + 1 : id;
116
117 /* create larger tab */
118 double *tmp = (double *) callocordie (tab->size + 1, sizeof (double));
119 memcpy (tmp, tab->data, (id - 1) * sizeof (double));
120 ret = tmp[id - 1] = val;
121 memcpy (tmp + id , tab->data + id - 1, (tab->size - id + 1) * sizeof (double));
122
123 /* update structure */
124 free (tab->data);
125 tab->data = tmp;
126 tab->size++;
127 }
128 return ret;
129 }
130
131 /* pop an element from a tab at position id [1.. N](-1 means last) resulting to a tab of N-1 elements */
132
133 double pop_tab (tab_t *tab, int id)
134 {
135 double ret = NAN;
136 if ((!tab) || (((id < 1) || (id > tab->size)) && (id != -1))) {
137 VERBOSE (WARNING, fprintf (stdout, "error out of bounds (%d/%d)\n", id, (tab) ? tab->size : 0));
138 } else {
139
140 /* special case for inserting an element at the end */
141 id = (id == -1) ? tab->size : id;
142
143 /* read data */
144 ret = tab->data[id - 1];
145
146 /* create larger tab */
147 double *tmp = (double *) callocordie (tab->size - 1, sizeof (double));
148 memcpy (tmp, tab->data, (id - 1) * sizeof (double));
149 memcpy (tmp + id - 1, tab->data + id, (tab->size - id) * sizeof (double));
150
151 /* update structure */
152 free (tab->data);
153 tab->data = tmp;
154 tab->size--;
155 }
156 return ret;
157 }
158
159 /* sort tab */
160
161 void order_tab (tab_t *tab)
162 {
163 int i, j;
164 if ((!tab) || (tab->size < 2)) {
165 VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", (tab) ? tab->size : 0));
166 return;
167 }
168
169 /* buble sort */
170 for (i = 0; i < tab->size - 1; i++) {
171 int done = 0;
172 for (j = 0; j < tab->size - 1; j++) {
173 double tab_j = tab->data[j];
174 double tab_jp1 = tab->data[j + 1];
175 if (tab_j > tab_jp1) {
176 tab->data[j] = tab_jp1;
177 tab->data[j + 1] = tab_j;
178 done = 1;
179 }
180 }
181 if (done == 0) {
182 break;
183 }
184 }
185 }
186
187 /* vim: set ts=4 sw=4 et: */