altos/telegps-v2.0: git ignore make results
[fw/altos] / src / lisp / ao_lisp_string.c
index 0064064cfe07cfc22730b7ac1f369b5240a23633..cd7b27a97f1f67f7136f03f650cbf2aacaba0511 100644 (file)
@@ -34,21 +34,21 @@ static void string_move(void *addr)
        (void) addr;
 }
 
-char *
-ao_lisp_string_new(int len) {
-       char    *a = ao_lisp_alloc(len + 1);
-       if (!a)
-               return NULL;
-       a[len] = '\0';
-       return a;
-}
+const struct ao_lisp_type ao_lisp_string_type = {
+       .mark = string_mark,
+       .size = string_size,
+       .move = string_move,
+       .name = "string",
+};
 
 char *
 ao_lisp_string_copy(char *a)
 {
        int     alen = strlen(a);
 
+       ao_lisp_string_stash(0, a);
        char    *r = ao_lisp_alloc(alen + 1);
+       a = ao_lisp_string_fetch(0);
        if (!r)
                return NULL;
        strcpy(r, a);
@@ -60,7 +60,12 @@ ao_lisp_string_cat(char *a, char *b)
 {
        int     alen = strlen(a);
        int     blen = strlen(b);
+
+       ao_lisp_string_stash(0, a);
+       ao_lisp_string_stash(1, b);
        char    *r = ao_lisp_alloc(alen + blen + 1);
+       a = ao_lisp_string_fetch(0);
+       b = ao_lisp_string_fetch(1);
        if (!r)
                return NULL;
        strcpy(r, a);
@@ -68,11 +73,53 @@ ao_lisp_string_cat(char *a, char *b)
        return r;
 }
 
-const struct ao_lisp_type ao_lisp_string_type = {
-       .mark = string_mark,
-       .size = string_size,
-       .move = string_move,
-};
+ao_poly
+ao_lisp_string_pack(struct ao_lisp_cons *cons)
+{
+       int     len = ao_lisp_cons_length(cons);
+       ao_lisp_cons_stash(0, cons);
+       char    *r = ao_lisp_alloc(len + 1);
+       cons = ao_lisp_cons_fetch(0);
+       char    *s = r;
+
+       while (cons) {
+               if (ao_lisp_poly_type(cons->car) != AO_LISP_INT)
+                       return ao_lisp_error(AO_LISP_INVALID, "non-int passed to pack");
+               *s++ = ao_lisp_poly_int(cons->car);
+               cons = ao_lisp_poly_cons(cons->cdr);
+       }
+       *s++ = 0;
+       return ao_lisp_string_poly(r);
+}
+
+ao_poly
+ao_lisp_string_unpack(char *a)
+{
+       struct ao_lisp_cons     *cons = NULL, *tail = NULL;
+       int                     c;
+       int                     i;
+
+       for (i = 0; (c = a[i]); i++) {
+               ao_lisp_cons_stash(0, cons);
+               ao_lisp_cons_stash(1, tail);
+               ao_lisp_string_stash(0, a);
+               struct ao_lisp_cons     *n = ao_lisp_cons_cons(ao_lisp_int_poly(c), NULL);
+               a = ao_lisp_string_fetch(0);
+               cons = ao_lisp_cons_fetch(0);
+               tail = ao_lisp_cons_fetch(1);
+
+               if (!n) {
+                       cons = NULL;
+                       break;
+               }
+               if (tail)
+                       tail->cdr = ao_lisp_cons_poly(n);
+               else
+                       cons = n;
+               tail = n;
+       }
+       return ao_lisp_cons_poly(cons);
+}
 
 void
 ao_lisp_string_print(ao_poly p)