fix bracket evaluation
[calc.git] / tabular.c
CommitLineData
3559b26c
LM
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
15tab_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
27tab_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 }
1546a0b5
LM
36 if (tab->data){
37 free (tab->data);
38 }
3559b26c
LM
39 tab->data = tmp;
40 tab->size = nb;
41 return tab;
42}
43
44/* copy a tab */
45
46tab_t *copy_tab (tab_t *tab)
47{
e952523a
LM
48 if (tab == NULL) {
49 return NULL;
50 }
3559b26c
LM
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
58void 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
70int 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
81double 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
94double 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
107double 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
133double 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 {
3559b26c
LM
139
140 /* special case for inserting an element at the end */
141 id = (id == -1) ? tab->size : id;
142
1546a0b5
LM
143 /* read data */
144 ret = tab->data[id - 1];
145
3559b26c
LM
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
161void order_tab (tab_t *tab)
162{
163 int i, j;
dd32032c
LM
164 if ((!tab) || (tab->size < 2)) {
165 VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", (tab) ? tab->size : 0));
3559b26c
LM
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: */