aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/embryo/src/lib/embryo_str.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/embryo/src/lib/embryo_str.c')
-rw-r--r--libraries/embryo/src/lib/embryo_str.c485
1 files changed, 485 insertions, 0 deletions
diff --git a/libraries/embryo/src/lib/embryo_str.c b/libraries/embryo/src/lib/embryo_str.c
new file mode 100644
index 0000000..46a3284
--- /dev/null
+++ b/libraries/embryo/src/lib/embryo_str.c
@@ -0,0 +1,485 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <stdlib.h>
6#include <stdio.h>
7#include <string.h>
8#include <fnmatch.h>
9
10#ifdef HAVE_ALLOCA_H
11# include <alloca.h>
12#elif defined __GNUC__
13# define alloca __builtin_alloca
14#elif defined _AIX
15# define alloca __alloca
16#elif defined _MSC_VER
17# include <malloc.h>
18# define alloca _alloca
19#else
20# include <stddef.h>
21# ifdef __cplusplus
22extern "C"
23# endif
24void *alloca (size_t);
25#endif
26
27#include "Embryo.h"
28#include "embryo_private.h"
29
30#define STRGET(ep, str, par) { \
31 Embryo_Cell *___cptr; \
32 str = NULL; \
33 if ((___cptr = embryo_data_address_get(ep, par))) { \
34 int ___l; \
35 ___l = embryo_data_string_length_get(ep, ___cptr); \
36 (str) = alloca(___l + 1); \
37 if (str) embryo_data_string_get(ep, ___cptr, str); \
38 } }
39#define STRSET(ep, par, str) { \
40 Embryo_Cell *___cptr; \
41 if ((___cptr = embryo_data_address_get(ep, par))) { \
42 embryo_data_string_set(ep, str, ___cptr); \
43 } }
44
45/* exported string api */
46
47static Embryo_Cell
48_embryo_str_atoi(Embryo_Program *ep, Embryo_Cell *params)
49{
50 char *s1;
51
52 /* params[1] = str */
53 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
54 STRGET(ep, s1, params[1]);
55 if (!s1) return 0;
56 return (Embryo_Cell)atoi(s1);
57}
58
59static Embryo_Cell
60_embryo_str_fnmatch(Embryo_Program *ep, Embryo_Cell *params)
61{
62 char *s1, *s2;
63
64 /* params[1] = glob */
65 /* params[2] = str */
66 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
67 STRGET(ep, s1, params[1]);
68 STRGET(ep, s2, params[2]);
69 if ((!s1) || (!s2)) return -1;
70 return (Embryo_Cell)fnmatch(s1, s2, 0);
71}
72
73static Embryo_Cell
74_embryo_str_strcmp(Embryo_Program *ep, Embryo_Cell *params)
75{
76 char *s1, *s2;
77
78 /* params[1] = str1 */
79 /* params[2] = str2 */
80 if (params[0] != (2 * sizeof(Embryo_Cell))) return -1;
81 STRGET(ep, s1, params[1]);
82 STRGET(ep, s2, params[2]);
83 if ((!s1) || (!s2)) return -1;
84 return (Embryo_Cell)strcmp(s1, s2);
85}
86
87static Embryo_Cell
88_embryo_str_strncmp(Embryo_Program *ep, Embryo_Cell *params)
89{
90 char *s1, *s2;
91
92 /* params[1] = str1 */
93 /* params[2] = str2 */
94 /* params[3] = n */
95 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
96 if (params[3] < 0) params[3] = 0;
97 STRGET(ep, s1, params[1]);
98 STRGET(ep, s2, params[2]);
99 if ((!s1) || (!s2)) return -1;
100 return (Embryo_Cell)strncmp(s1, s2, (size_t)params[3]);
101}
102
103static Embryo_Cell
104_embryo_str_strcpy(Embryo_Program *ep, Embryo_Cell *params)
105{
106 char *s1;
107
108 /* params[1] = dst */
109 /* params[2] = str */
110 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
111 STRGET(ep, s1, params[2]);
112 if (!s1) return 0;
113 STRSET(ep, params[1], s1);
114 return 0;
115}
116
117static Embryo_Cell
118_embryo_str_strncpy(Embryo_Program *ep, Embryo_Cell *params)
119{
120 char *s1;
121 int l;
122
123 /* params[1] = dst */
124 /* params[2] = str */
125 /* params[3] = n */
126 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
127 if (params[3] < 0) params[3] = 0;
128 STRGET(ep, s1, params[2]);
129 if (!s1) return 0;
130 l = strlen(s1);
131 if (l > params[3]) s1[params[3]] = 0;
132 STRSET(ep, params[1], s1);
133 return 0;
134}
135
136static Embryo_Cell
137_embryo_str_strlen(Embryo_Program *ep, Embryo_Cell *params)
138{
139 char *s1;
140
141 /* params[1] = str */
142 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
143 STRGET(ep, s1, params[1]);
144 if (!s1) return 0;
145 return (Embryo_Cell)strlen(s1);
146}
147
148static Embryo_Cell
149_embryo_str_strcat(Embryo_Program *ep, Embryo_Cell *params)
150{
151 char *s1, *s2, *s3;
152
153 /* params[1] = dsr */
154 /* params[2] = str */
155 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
156 STRGET(ep, s1, params[1]);
157 STRGET(ep, s2, params[2]);
158 if ((!s1) || (!s2)) return 0;
159 s3 = alloca(strlen(s1) + strlen(s2) + 1);
160 if (!s3) return 0;
161 strcpy(s3, s1);
162 strcat(s3, s2);
163 STRSET(ep, params[1], s3);
164 return 0;
165}
166
167static Embryo_Cell
168_embryo_str_strncat(Embryo_Program *ep, Embryo_Cell *params)
169{
170 char *s1, *s2, *s3;
171 int l1, l2;
172
173 /* params[1] = dst */
174 /* params[2] = str */
175 /* params[3] = n */
176 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
177 if (params[3] < 0) params[3] = 0;
178 STRGET(ep, s1, params[1]);
179 STRGET(ep, s2, params[2]);
180 if ((!s1) || (!s2)) return 0;
181 l1 = strlen(s1);
182 l2 = strlen(s2);
183 s3 = alloca(l1 + l2 + 1);
184 if (!s3) return 0;
185 strcpy(s3, s1);
186 strncat(s3, s2, params[3]);
187 if (l2 >= params[3]) s3[l1 + params[3]] = 0;
188 STRSET(ep, params[1], s3);
189 return 0;
190}
191
192static Embryo_Cell
193_embryo_str_strprep(Embryo_Program *ep, Embryo_Cell *params)
194{
195 char *s1, *s2, *s3;
196
197 /* params[1] = dst */
198 /* params[2] = str */
199 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
200 STRGET(ep, s1, params[1]);
201 STRGET(ep, s2, params[2]);
202 if ((!s1) || (!s2)) return 0;
203 s3 = alloca(strlen(s1) + strlen(s2) + 1);
204 if (!s3) return 0;
205 strcpy(s3, s2);
206 strcat(s3, s1);
207 STRSET(ep, params[1], s3);
208 return 0;
209}
210
211static Embryo_Cell
212_embryo_str_strnprep(Embryo_Program *ep, Embryo_Cell *params)
213{
214 char *s1, *s2, *s3;
215 int l1, l2;
216
217 /* params[1] = dst */
218 /* params[2] = str */
219 /* params[3] = n */
220 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
221 if (params[3] < 0) params[3] = 0;
222 STRGET(ep, s1, params[1]);
223 STRGET(ep, s2, params[2]);
224 if ((!s1) || (!s2)) return 0;
225 l1 = strlen(s1);
226 l2 = strlen(s2);
227 s3 = alloca(l1 + l2 + 1);
228 if (!s3) return 0;
229 strncpy(s3, s2, params[3]);
230 if (params[3] <= l2) s3[params[3]] = 0;
231 strcat(s3, s1);
232 STRSET(ep, params[1], s3);
233 return 0;
234}
235
236static Embryo_Cell
237_embryo_str_strcut(Embryo_Program *ep, Embryo_Cell *params)
238{
239 char *s1, *s2;
240 int l1;
241
242 /* params[1] = dst */
243 /* params[2] = str */
244 /* params[3] = n */
245 /* params[4] = n2 */
246 if (params[0] != (4 * sizeof(Embryo_Cell))) return 0;
247 if (params[3] < 0) params[3] = 0;
248 if (params[4] < params[3]) params[4] = params[3];
249 STRGET(ep, s1, params[2]);
250 if (!s1) return 0;
251 l1 = strlen(s1);
252 if (params[3] >= l1) params[3] = l1;
253 if (params[4] >= l1) params[4] = l1;
254 if (params[4] == params[3])
255 {
256 STRSET(ep, params[1], "");
257 return 0;
258 }
259 s2 = alloca(params[4] - params[3] + 1);
260 strncpy(s2, s1 + params[3], params[4] - params[3]);
261 s2[params[4] - params[3]] = 0;
262 STRSET(ep, params[1], s2);
263 return 0;
264}
265
266static Embryo_Cell
267_embryo_str_snprintf(Embryo_Program *ep, Embryo_Cell *params)
268{
269 char *s1, *s2;
270 int i, o;
271 int inesc = 0;
272 int insub = 0;
273 int p, pnum;
274
275 /* params[1] = buf */
276 /* params[2] = bufsize */
277 /* params[3] = format_string */
278 /* params[4] = first arg ... */
279 if (params[0] < (Embryo_Cell)(3 * sizeof(Embryo_Cell))) return 0;
280 if (params[2] <= 0) return 0;
281 STRGET(ep, s1, params[3]);
282 if (!s1) return -1;
283 s2 = alloca(params[2] + 1);
284 if (!s2) return -1;
285 s2[0] = 0;
286 pnum = (params[0] / sizeof(Embryo_Cell)) - 3;
287 for (p = 0, o = 0, i = 0; (s1[i]) && (o < (params[2] - 1)) && (p < (pnum + 1)); i++)
288 {
289 if ((!inesc) && (!insub))
290 {
291 if (s1[i] == '\\') inesc = 1;
292 else if (s1[i] == '%') insub = 1;
293 if ((!inesc) && (!insub))
294 {
295 s2[o] = s1[i];
296 o++;
297 }
298 }
299 else
300 {
301 Embryo_Cell *cptr;
302
303 if (inesc)
304 {
305 switch (s1[i])
306 {
307 case 't':
308 s2[o] = '\t';
309 o++;
310 break;
311 case 'n':
312 s2[o] = '\n';
313 o++;
314 break;
315 default:
316 s2[o] = s1[i];
317 o++;
318 break;
319 }
320 inesc = 0;
321 }
322 if ((insub) && (s1[i] == '%')) pnum++;
323 if ((insub) && (p < pnum))
324 {
325 switch (s1[i])
326 {
327 case '%':
328 s2[o] = '%';
329 o++;
330 break;
331 case 'c':
332 cptr = embryo_data_address_get(ep, params[4 + p]);
333 if (cptr) s2[o] = (char)(*cptr);
334 p++;
335 o++;
336 break;
337 case 'i':
338 case 'd':
339 case 'x':
340 case 'X':
341 {
342 char fmt[10] = "";
343 char tmp[256] = "";
344 int l;
345
346 if (s1[i] == 'i') strcpy(fmt, "%i");
347 else if (s1[i] == 'd') strcpy(fmt, "%d");
348 else if (s1[i] == 'x') strcpy(fmt, "%x");
349 else if (s1[i] == 'X') strcpy(fmt, "%08x");
350 cptr = embryo_data_address_get(ep, params[4 + p]);
351 if (cptr) snprintf(tmp, sizeof(tmp), fmt, (int)(*cptr));
352 l = strlen(tmp);
353 if ((o + l) > (params[2] - 1))
354 {
355 l = params[2] - 1 - o;
356 if (l < 0) l = 0;
357 tmp[l] = 0;
358 }
359 strcpy(s2 + o, tmp);
360 o += l;
361 p++;
362 }
363 break;
364 case 'f':
365 {
366 char tmp[256] = "";
367 int l;
368
369 cptr = embryo_data_address_get(ep, params[4 + p]);
370 if (cptr) snprintf(tmp, sizeof(tmp), "%f", (double)EMBRYO_CELL_TO_FLOAT(*cptr));
371 l = strlen(tmp);
372 if ((o + l) > (params[2] - 1))
373 {
374 l = params[2] - 1 - o;
375 if (l < 0) l = 0;
376 tmp[l] = 0;
377 }
378 strcpy(s2 + o, tmp);
379 o += l;
380 p++;
381 }
382 break;
383 case 's':
384 {
385 char *tmp;
386 int l;
387
388 STRGET(ep, tmp, params[4 + p]);
389 l = strlen(tmp);
390 if ((o + l) > (params[2] - 1))
391 {
392 l = params[2] - 1 - o;
393 if (l < 0) l = 0;
394 tmp[l] = 0;
395 }
396 strcpy(s2 + o, tmp);
397 o += l;
398 p++;
399 }
400 break;
401 default:
402 break;
403 }
404 insub = 0;
405 }
406 else if (insub)
407 insub = 0;
408 }
409 }
410 s2[o] = 0;
411
412 STRSET(ep, params[1], s2);
413 return o;
414}
415
416static Embryo_Cell
417_embryo_str_strstr(Embryo_Program *ep, Embryo_Cell *params)
418{
419 char *s1, *s2, *p;
420
421 /* params[1] = str */
422 /* params[2] = ndl */
423 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
424 STRGET(ep, s1, params[1]);
425 STRGET(ep, s2, params[2]);
426 if ((!s1) || (!s2)) return -1;
427 p = strstr(s1, s2);
428 if (!p) return -1;
429 return (Embryo_Cell)(p - s1);
430}
431
432static Embryo_Cell
433_embryo_str_strchr(Embryo_Program *ep, Embryo_Cell *params)
434{
435 char *s1, *s2, *p;
436
437 /* params[1] = str */
438 /* params[2] = ch */
439 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
440 STRGET(ep, s1, params[1]);
441 STRGET(ep, s2, params[2]);
442 if ((!s1) || (!s2)) return -1;
443 p = strchr(s1, s2[0]);
444 if (!p) return -1;
445 return (Embryo_Cell)(p - s1);
446}
447
448static Embryo_Cell
449_embryo_str_strrchr(Embryo_Program *ep, Embryo_Cell *params)
450{
451 char *s1, *s2, *p;
452
453 /* params[1] = str */
454 /* params[2] = ch */
455 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
456 STRGET(ep, s1, params[1]);
457 STRGET(ep, s2, params[2]);
458 if ((!s1) || (!s2)) return -1;
459 p = strrchr(s1, s2[0]);
460 if (!p) return -1;
461 return (Embryo_Cell)(p - s1);
462}
463
464/* functions used by the rest of embryo */
465
466void
467_embryo_str_init(Embryo_Program *ep)
468{
469 embryo_program_native_call_add(ep, "atoi", _embryo_str_atoi);
470 embryo_program_native_call_add(ep, "fnmatch", _embryo_str_fnmatch);
471 embryo_program_native_call_add(ep, "strcmp", _embryo_str_strcmp);
472 embryo_program_native_call_add(ep, "strncmp", _embryo_str_strncmp);
473 embryo_program_native_call_add(ep, "strcpy", _embryo_str_strcpy);
474 embryo_program_native_call_add(ep, "strncpy", _embryo_str_strncpy);
475 embryo_program_native_call_add(ep, "strlen", _embryo_str_strlen);
476 embryo_program_native_call_add(ep, "strcat", _embryo_str_strcat);
477 embryo_program_native_call_add(ep, "strncat", _embryo_str_strncat);
478 embryo_program_native_call_add(ep, "strprep", _embryo_str_strprep);
479 embryo_program_native_call_add(ep, "strnprep", _embryo_str_strnprep);
480 embryo_program_native_call_add(ep, "strcut", _embryo_str_strcut);
481 embryo_program_native_call_add(ep, "snprintf", _embryo_str_snprintf);
482 embryo_program_native_call_add(ep, "strstr", _embryo_str_strstr);
483 embryo_program_native_call_add(ep, "strchr", _embryo_str_strchr);
484 embryo_program_native_call_add(ep, "strrchr", _embryo_str_strrchr);
485}