--- /dev/null
+#include <malloc.h>
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "debug.h"
+#include "alloc.h"
+
+#include "tabular.h"
+
+/* management function */
+
+/* allocate a tab of N elements */
+
+tab_t *alloc_tab (int nb)
+{
+ tab_t *tab = (tab_t *) callocordie (1, sizeof (tab_t));
+ if (nb > 0) {
+ tab->data = (double *) callocordie (nb, sizeof (double));
+ tab->size = nb;
+ }
+ return (tab);
+}
+
+/* resize a tab to size N */
+
+tab_t *resize_tab (tab_t *tab, int nb)
+{
+ double *tmp = NULL;
+ tab = (tab) ? tab : (tab_t *) callocordie (1, sizeof (tab_t));
+ nb = (nb > 0) ? nb : 0;
+ if (nb > 0) {
+ tmp = (double *) callocordie (nb, sizeof (double));
+ memcpy (tmp, tab->data, ((tab->size < nb) ? tab->size : nb) * sizeof (double));
+ }
+ free (tab->data);
+ tab->data = tmp;
+ tab->size = nb;
+ return tab;
+}
+
+/* copy a tab */
+
+tab_t *copy_tab (tab_t *tab)
+{
+ tab_t *new = alloc_tab (tab->size);
+ memcpy (new->data, tab->data, tab->size * sizeof (double));
+ return new;
+}
+
+/* free a tab */
+
+void free_tab (tab_t *tab)
+{
+ if (tab) {
+ if (tab->data) {
+ free (tab->data);
+ }
+ free (tab);
+ }
+}
+
+/* get table size */
+
+int size_tab (tab_t *tab)
+{
+ int ret = 0;
+ if (tab) {
+ ret = tab->size;
+ }
+ return ret;
+}
+
+/* set an element into a tab at position id [1..N] */
+
+double set_tab (tab_t *tab, int id, double val)
+{
+ double ret = NAN;
+ if ((!tab) || (id < 1) || (id > tab->size)) {
+ VERBOSE (WARNING, fprintf (stdout, "error out of bounds (%d/%d)\n", id, (tab) ? tab->size : 0));
+ } else {
+ ret = tab->data[id - 1] = val;
+ }
+ return ret;
+}
+
+/* get an element from a tab at position id [1..N] */
+
+double get_tab (tab_t *tab, int id)
+{
+ double ret = NAN;
+ if ((!tab) || (id < 1) || (id > tab->size)) {
+ VERBOSE (WARNING, fprintf (stdout, "error out of bounds (%d/%d)\n", id, (tab) ? tab->size : 0));
+ } else {
+ ret = tab->data[id - 1];
+ }
+ return ret;
+}
+
+/* push an element into a tab at position id [1.. N](-1 means end) resulting to a tab of N+1 elements */
+
+double push_tab (tab_t *tab, int id, double val)
+{
+ double ret = NAN;
+ if ((!tab) || (((id < 1) || (id > tab->size + 1)) && (id != -1))) {
+ VERBOSE (WARNING, fprintf (stdout, "error out of bounds (%d/%d)\n", id, (tab) ? tab->size : 0));
+ } else {
+
+ /* special case for inserting an element at the end */
+ id = (id == -1) ? tab->size + 1 : id;
+
+ /* create larger tab */
+ double *tmp = (double *) callocordie (tab->size + 1, sizeof (double));
+ memcpy (tmp, tab->data, (id - 1) * sizeof (double));
+ ret = tmp[id - 1] = val;
+ memcpy (tmp + id , tab->data + id - 1, (tab->size - id + 1) * sizeof (double));
+
+ /* update structure */
+ free (tab->data);
+ tab->data = tmp;
+ tab->size++;
+ }
+ return ret;
+}
+
+/* pop an element from a tab at position id [1.. N](-1 means last) resulting to a tab of N-1 elements */
+
+double pop_tab (tab_t *tab, int id)
+{
+ double ret = NAN;
+ if ((!tab) || (((id < 1) || (id > tab->size)) && (id != -1))) {
+ VERBOSE (WARNING, fprintf (stdout, "error out of bounds (%d/%d)\n", id, (tab) ? tab->size : 0));
+ } else {
+ ret = tab->data[id - 1];
+
+ /* special case for inserting an element at the end */
+ id = (id == -1) ? tab->size : id;
+
+ /* create larger tab */
+ double *tmp = (double *) callocordie (tab->size - 1, sizeof (double));
+ memcpy (tmp, tab->data, (id - 1) * sizeof (double));
+ memcpy (tmp + id - 1, tab->data + id, (tab->size - id) * sizeof (double));
+
+ /* update structure */
+ free (tab->data);
+ tab->data = tmp;
+ tab->size--;
+ }
+ return ret;
+}
+
+/* sort tab */
+
+void order_tab (tab_t *tab)
+{
+ int i, j;
+ if ((!tab) || (tab->size < 3)) {
+ VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", tab->size));
+ return;
+ }
+
+ /* buble sort */
+ for (i = 0; i < tab->size - 1; i++) {
+ int done = 0;
+ for (j = 0; j < tab->size - 1; j++) {
+ double tab_j = tab->data[j];
+ double tab_jp1 = tab->data[j + 1];
+ if (tab_j > tab_jp1) {
+ tab->data[j] = tab_jp1;
+ tab->data[j + 1] = tab_j;
+ done = 1;
+ }
+ }
+ if (done == 0) {
+ break;
+ }
+ }
+}
+
+/* vim: set ts=4 sw=4 et: */