altos/scheme: More compiler warning cleanups
[fw/altos] / src / scheme / ao_scheme_string.c
1 /*
2  * Copyright © 2016 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 #include "ao_scheme.h"
19
20 static void string_mark(void *addr)
21 {
22         (void) addr;
23 }
24
25 static int string_size(void *addr)
26 {
27         if (!addr)
28                 return 0;
29         return strlen(addr) + 1;
30 }
31
32 static void string_move(void *addr)
33 {
34         (void) addr;
35 }
36
37 const struct ao_scheme_type ao_scheme_string_type = {
38         .mark = string_mark,
39         .size = string_size,
40         .move = string_move,
41         .name = "string",
42 };
43
44 char *
45 ao_scheme_string_copy(char *a)
46 {
47         int     alen = strlen(a);
48         char    *r;
49
50         ao_scheme_string_stash(0, a);
51         r = ao_scheme_alloc(alen + 1);
52         a = ao_scheme_string_fetch(0);
53         if (!r)
54                 return NULL;
55         strcpy(r, a);
56         return r;
57 }
58
59 char *
60 ao_scheme_string_cat(char *a, char *b)
61 {
62         int     alen = strlen(a);
63         int     blen = strlen(b);
64         char    *r;
65
66         ao_scheme_string_stash(0, a);
67         ao_scheme_string_stash(1, b);
68         r = ao_scheme_alloc(alen + blen + 1);
69         a = ao_scheme_string_fetch(0);
70         b = ao_scheme_string_fetch(1);
71         if (!r)
72                 return NULL;
73         strcpy(r, a);
74         strcpy(r+alen, b);
75         return r;
76 }
77
78 ao_poly
79 ao_scheme_string_pack(struct ao_scheme_cons *cons)
80 {
81         char    *r;
82         char    *s;
83         int     len;
84
85         len = ao_scheme_cons_length(cons);
86         ao_scheme_cons_stash(0, cons);
87         r = ao_scheme_alloc(len + 1);
88         cons = ao_scheme_cons_fetch(0);
89         s = r;
90
91         while (cons) {
92                 if (!ao_scheme_integer_typep(ao_scheme_poly_type(cons->car)))
93                         return ao_scheme_error(AO_SCHEME_INVALID, "non-int passed to pack");
94                 *s++ = ao_scheme_poly_integer(cons->car);
95                 cons = ao_scheme_poly_cons(cons->cdr);
96         }
97         *s++ = 0;
98         return ao_scheme_string_poly(r);
99 }
100
101 ao_poly
102 ao_scheme_string_unpack(char *a)
103 {
104         struct ao_scheme_cons   *cons = NULL, *tail = NULL;
105         int                     c;
106         int                     i;
107
108         for (i = 0; (c = a[i]); i++) {
109                 struct ao_scheme_cons   *n;
110                 ao_scheme_cons_stash(0, cons);
111                 ao_scheme_cons_stash(1, tail);
112                 ao_scheme_string_stash(0, a);
113                 n = ao_scheme_cons_cons(ao_scheme_int_poly(c), AO_SCHEME_NIL);
114                 a = ao_scheme_string_fetch(0);
115                 cons = ao_scheme_cons_fetch(0);
116                 tail = ao_scheme_cons_fetch(1);
117
118                 if (!n) {
119                         cons = NULL;
120                         break;
121                 }
122                 if (tail)
123                         tail->cdr = ao_scheme_cons_poly(n);
124                 else
125                         cons = n;
126                 tail = n;
127         }
128         return ao_scheme_cons_poly(cons);
129 }
130
131 void
132 ao_scheme_string_write(ao_poly p)
133 {
134         char    *s = ao_scheme_poly_string(p);
135         char    c;
136
137         putchar('"');
138         while ((c = *s++)) {
139                 switch (c) {
140                 case '\n':
141                         printf ("\\n");
142                         break;
143                 case '\r':
144                         printf ("\\r");
145                         break;
146                 case '\t':
147                         printf ("\\t");
148                         break;
149                 default:
150                         if (c < ' ')
151                                 printf("\\%03o", c);
152                         else
153                                 putchar(c);
154                         break;
155                 }
156         }
157         putchar('"');
158 }
159
160 void
161 ao_scheme_string_display(ao_poly p)
162 {
163         char    *s = ao_scheme_poly_string(p);
164         char    c;
165
166         while ((c = *s++))
167                 putchar(c);
168 }