add del feature
[calc.git] / parser.c
index 03ef985f49b892aca4b906e8ee15d85f8ad31c8e..4f50a0e8b7703571cb52b6a0bddb32aabc16b290 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -50,6 +50,9 @@ int codecmp (char *ref, char *str)
 
 void *callocordie (size_t count, size_t size)
 {
+    if (count * size == 0) {
+        return NULL;
+    }
     void *new = calloc (count, size);
     if (new == NULL) {
         VERBOSE (ERROR, fprintf (stderr, "can't allocate memory\n"));
@@ -797,41 +800,41 @@ double call (int id, int nbops, element_t **ops)
                 break;
             }
         }
-        if (n == -1) {
-            VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id));
-            return 0;
-        }
+    }
+    if (n == -1) {
+        VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id));
+        return 0;
+    }
 
-        /* store context */
-        tmp.answer = answer;
-        tmp.storage = storage;
-        tmp.storage_size = storage_size;
-
-        /* change context */
-        answer = 0;
-        storage = (programs + n)->storage;
-        storage_size = (programs + n)->storage_size;
-        if (nbops > storage_size) {
-            double *tmp = (double *) callocordie (nbops, sizeof (double));
-            memcpy (tmp, storage, storage_size * sizeof (double));
-            free (storage);
-            storage = tmp;
-            storage_size = nbops;
-        }
-        for (i = 0; i < nbops; i++) {
-            double val = evaluate_element (ops[i], 0);
-            store (i + 1, val);
-        }
+    /* store context */
+    tmp.answer = answer;
+    tmp.storage = storage;
+    tmp.storage_size = storage_size;
+
+    /* change context */
+    answer = 0;
+    storage = (programs + n)->storage;
+    storage_size = (programs + n)->storage_size;
+    if (nbops > storage_size) {
+        double *tmp = (double *) callocordie (nbops, sizeof (double));
+        memcpy (tmp, storage, storage_size * sizeof (double));
+        free (storage);
+        storage = tmp;
+        storage_size = nbops;
+    }
+    for (i = 0; i < nbops; i++) {
+        double val = evaluate_element (ops[i], 0);
+        store (i + 1, val);
+    }
 
-        /* evaluate program */
-        element_t *elements = dupelement ((programs + n)->root);
-        ret = evaluate_element (elements, 0);
+    /* evaluate program */
+    element_t *elements = dupelement ((programs + n)->root);
+    ret = evaluate_element (elements, 0);
 
-        /* restore context */
-        answer = tmp.answer;
-        storage = tmp.storage;
-        storage_size = tmp.storage_size;
-    }
+    /* restore context */
+    answer = tmp.answer;
+    storage = tmp.storage;
+    storage_size = tmp.storage_size;
 
     return ret;
 }
@@ -839,20 +842,55 @@ double call (int id, int nbops, element_t **ops)
 void list ()
 {
     int i;
-    if (programs != NULL) {
-        fprintf (stdout, "programs:");
-        for (i = 0; i < nb_programs; i++) {
-            fprintf (stdout, " %d", (programs + i)->id);
-        }
-        fprintf (stdout, "\n");
+    fprintf (stdout, "programs:");
+    for (i = 0; i < nb_programs; i++) {
+        fprintf (stdout, " %d", (programs + i)->id);
     }
+    fprintf (stdout, "\n");
 }
 
 void edit (int id)
 { }
 
 void del (int id)
-{ }
+{
+    int i, j, n = -1;
+
+    if (programs) {
+
+        /* look for program */
+        for (i = 0; i < nb_programs; i++) {
+            if ((programs + i)->id == id) {
+                n = i;
+                break;
+            }
+        }
+    }
+    if (n == -1) {
+        VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id));
+        return;
+    }
+
+    /* clean program */
+    if ((programs + n)->storage) {
+        free ((programs + n)->storage);
+    }
+    if ((programs + n)->root) {
+        delelement ((programs + n)->root);
+    }
+
+    /* remove entry */
+    workspace_t *tmp = (workspace_t *) callocordie (nb_programs - 1, sizeof (workspace_t));
+    for (i = 0, j = 0; i < nb_programs; i++) {
+        if (i != n) {
+            memcpy (tmp + j, programs + i, sizeof (workspace_t));
+            j++;
+        }
+    }
+    free (programs);
+    programs = tmp;
+    nb_programs--;
+}
 
 /* help message */