4bc4c5668b5e9bb8da3f877ce5fac72f9561c996
[egate.git] / fml / fmlmem.c
1 /*
2  * FML interpreter. Europagate, 1995
3  *
4  * $Log: fmlmem.c,v $
5  * Revision 1.1  1995/02/06 13:48:09  adam
6  * Initial revision
7  *
8  */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <assert.h>
13
14 #include "fmlp.h"
15
16 #define FML_ATOM_CHUNK 1024
17 #define FML_NODE_CHUNK 1024
18
19 struct fml_node *fml_node_alloc (Fml fml)
20 {
21     struct fml_node *n;
22
23     if (! fml->node_free_list)
24     {
25         int i;
26
27         n = fml->node_free_list = malloc (sizeof(*n) * FML_NODE_CHUNK);
28         if (!n)
29         {
30             (*fml->err_handle)(FML_ERR_NOMEM);
31             exit (1);
32         }
33         for (i = FML_ATOM_CHUNK-1; --i >= 0; n++)
34             n->p[1] = n+1;
35         n->p[1] = NULL;
36     }
37     n = fml->node_free_list;
38     fml->node_free_list = n->p[1];
39     n->p[0] = n->p[1] = NULL;
40     n->is_atom = 0;
41     return n;
42 }
43
44 static struct fml_atom *atom_malloc (Fml fml)
45 {
46     struct fml_atom *fa;
47
48     if (! fml->atom_free_list)
49     {
50         int i;
51
52         fa = fml->atom_free_list = malloc (sizeof(*fa) * FML_ATOM_CHUNK);
53         if (!fa)
54         {
55             (*fml->err_handle)(FML_ERR_NOMEM);
56             exit (1);
57         }
58         for (i = FML_ATOM_CHUNK-1; --i >= 0; fa++)
59             fa->next = fa+1;
60         fa->next = NULL;
61     }
62     fa = fml->atom_free_list;
63     fml->atom_free_list = fa->next;
64     return fa;
65 }
66
67 static void atom_delete (Fml fml, struct fml_atom *a)
68 {
69     a->next = fml->atom_free_list;
70     fml->atom_free_list = a;
71 }
72
73 static struct fml_atom *atom_copy (Fml fml, struct fml_atom *a)
74 {
75     struct fml_atom *a0, *a1;
76
77     a0 = a1 = atom_malloc (fml);
78     while (a)
79     {
80         memcpy (&a1->buf, &a->buf, FML_ATOM_CHUNK);
81         if (!a->next)
82             break;
83         a = a->next;
84         a1 = a1->next = atom_malloc (fml);
85     }
86     a1->next = NULL;
87     return a0;
88 }
89
90 struct fml_atom *fml_atom_alloc (Fml fml, char *str)
91 {
92     int soff = 0;
93     struct fml_atom *a, *a0;
94
95     a0 = a = atom_malloc (fml);
96     strncpy (a->buf, str, FML_ATOM_BUF);
97     while (strlen (str+soff) >= FML_ATOM_BUF)
98     {
99         struct fml_atom *an;
100
101         an = atom_malloc (fml);
102         a->next = an;
103         soff += FML_ATOM_BUF;
104         strncpy (an->buf, str+soff, FML_ATOM_BUF);
105         a = an;
106     }
107     a->next = NULL;
108     return a0;
109 }
110
111 struct fml_node *fml_mk_list (Fml fml, struct fml_node *fn)
112 {
113     if (fn->is_atom)
114     {
115         struct fml_node *fn2;
116
117         fn2 = fml_node_alloc (fml);
118         fn2->is_atom = 1;
119         fn2->p[0] = fn->p[0];
120         return fn2;
121     }
122     else
123         return fn->p[0];
124 }
125
126 int fml_atom_str (struct fml_atom *a, char *str)
127 {
128     int len = 0;
129
130     assert (a);
131     while (a->next)
132     {
133         if (str)
134             memcpy (str+len, a->buf, FML_ATOM_BUF);
135         len += FML_ATOM_BUF;
136         a = a->next;
137     }
138     if (str)
139         strcpy (str+len, a->buf);
140     len += strlen(str+len);
141     return len;
142 }
143
144 void fml_atom_strx (struct fml_atom *a, char *str, int max)
145 {
146     int len = 0;
147
148     assert (a);
149     while (a->next && len < max - 2*FML_ATOM_BUF)
150     {
151         memcpy (str+len, a->buf, FML_ATOM_BUF);
152         len += FML_ATOM_BUF;
153         a = a->next;
154     }
155     strncpy (str+len, a->buf, FML_ATOM_BUF-1);
156     str[len+FML_ATOM_BUF-1] = '\0';
157 }
158
159 int fml_atom_val (struct fml_atom *a)
160 {
161     assert (a);
162     return atoi (a->buf);
163 }
164
165 void fml_node_delete (Fml fml, struct fml_node *fn)
166 {
167     struct fml_node *f1;
168     while (fn)
169     {
170         if (fn->is_atom)
171             atom_delete (fml, fn->p[0]);
172         else
173             fml_node_delete (fml, fn->p[0]);
174         f1 = fn->p[1];
175         
176         fn->p[1] = fml->node_free_list;
177         fml->node_free_list = fn;
178
179         fn = f1;
180     }
181 }
182
183 struct fml_node *fml_node_copy (Fml fml, struct fml_node *fn)
184 {
185     struct fml_node *fn0, *fn1;
186
187     if (!fn)
188         return NULL;
189     fn1 = fn0 = fml_node_alloc (fml);
190     while (1)
191     {
192         if (fn->is_atom)
193         {
194             fn1->is_atom = 1;
195             fn1->p[0] = atom_copy (fml, fn->p[0]);
196         }
197         else 
198             fn1->p[0] = fml_node_copy (fml, fn->p[0]);
199         if (!fn->p[1])
200             break;
201         fn = fn->p[1];
202         fn1 = fn1->p[1] = fml_node_alloc (fml);
203     }
204     return fn0;
205 }