17 # define alloca __builtin_alloca
19 # define alloca __alloca
20 # elif defined _MSC_VER
22 # define alloca _alloca
23 # elif !defined HAVE_ALLOCA
27 void *alloca (size_t);
37 #include "embryo_private.h"
39 #define STRGET(ep, str, par) { \
40 Embryo_Cell *___cptr; \
42 if ((___cptr = embryo_data_address_get(ep, par))) { \
44 ___l = embryo_data_string_length_get(ep, ___cptr); \
45 (str) = alloca(___l + 1); \
46 if (str) embryo_data_string_get(ep, ___cptr, str); \
48 #define STRSET(ep, par, str) { \
49 Embryo_Cell *___cptr; \
50 if ((___cptr = embryo_data_address_get(ep, par))) { \
51 embryo_data_string_set(ep, str, ___cptr); \
54 /* exported string api */
57 _embryo_str_atoi(Embryo_Program *ep, Embryo_Cell *params)
62 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
63 STRGET(ep, s1, params[1]);
65 return (Embryo_Cell)atoi(s1);
69 _embryo_str_fnmatch(Embryo_Program *ep, Embryo_Cell *params)
73 /* params[1] = glob */
75 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
76 STRGET(ep, s1, params[1]);
77 STRGET(ep, s2, params[2]);
78 if ((!s1) || (!s2)) return -1;
79 return (Embryo_Cell)fnmatch(s1, s2, 0);
83 _embryo_str_strcmp(Embryo_Program *ep, Embryo_Cell *params)
87 /* params[1] = str1 */
88 /* params[2] = str2 */
89 if (params[0] != (2 * sizeof(Embryo_Cell))) return -1;
90 STRGET(ep, s1, params[1]);
91 STRGET(ep, s2, params[2]);
92 if ((!s1) || (!s2)) return -1;
93 return (Embryo_Cell)strcmp(s1, s2);
97 _embryo_str_strncmp(Embryo_Program *ep, Embryo_Cell *params)
101 /* params[1] = str1 */
102 /* params[2] = str2 */
104 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
105 if (params[3] < 0) params[3] = 0;
106 STRGET(ep, s1, params[1]);
107 STRGET(ep, s2, params[2]);
108 if ((!s1) || (!s2)) return -1;
109 return (Embryo_Cell)strncmp(s1, s2, (size_t)params[3]);
113 _embryo_str_strcpy(Embryo_Program *ep, Embryo_Cell *params)
117 /* params[1] = dst */
118 /* params[2] = str */
119 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
120 STRGET(ep, s1, params[2]);
122 STRSET(ep, params[1], s1);
127 _embryo_str_strncpy(Embryo_Program *ep, Embryo_Cell *params)
132 /* params[1] = dst */
133 /* params[2] = str */
135 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
136 if (params[3] < 0) params[3] = 0;
137 STRGET(ep, s1, params[2]);
140 if (l > params[3]) s1[params[3]] = 0;
141 STRSET(ep, params[1], s1);
146 _embryo_str_strlen(Embryo_Program *ep, Embryo_Cell *params)
150 /* params[1] = str */
151 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
152 STRGET(ep, s1, params[1]);
154 return (Embryo_Cell)strlen(s1);
158 _embryo_str_strcat(Embryo_Program *ep, Embryo_Cell *params)
162 /* params[1] = dsr */
163 /* params[2] = str */
164 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
165 STRGET(ep, s1, params[1]);
166 STRGET(ep, s2, params[2]);
167 if ((!s1) || (!s2)) return 0;
168 s3 = alloca(strlen(s1) + strlen(s2) + 1);
172 STRSET(ep, params[1], s3);
177 _embryo_str_strncat(Embryo_Program *ep, Embryo_Cell *params)
182 /* params[1] = dst */
183 /* params[2] = str */
185 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
186 if (params[3] < 0) params[3] = 0;
187 STRGET(ep, s1, params[1]);
188 STRGET(ep, s2, params[2]);
189 if ((!s1) || (!s2)) return 0;
192 s3 = alloca(l1 + l2 + 1);
195 strncat(s3, s2, params[3]);
196 if (l2 >= params[3]) s3[l1 + params[3]] = 0;
197 STRSET(ep, params[1], s3);
202 _embryo_str_strprep(Embryo_Program *ep, Embryo_Cell *params)
206 /* params[1] = dst */
207 /* params[2] = str */
208 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
209 STRGET(ep, s1, params[1]);
210 STRGET(ep, s2, params[2]);
211 if ((!s1) || (!s2)) return 0;
212 s3 = alloca(strlen(s1) + strlen(s2) + 1);
216 STRSET(ep, params[1], s3);
221 _embryo_str_strnprep(Embryo_Program *ep, Embryo_Cell *params)
226 /* params[1] = dst */
227 /* params[2] = str */
229 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
230 if (params[3] < 0) params[3] = 0;
231 STRGET(ep, s1, params[1]);
232 STRGET(ep, s2, params[2]);
233 if ((!s1) || (!s2)) return 0;
236 s3 = alloca(l1 + l2 + 1);
238 strncpy(s3, s2, params[3]);
239 if (params[3] <= l2) s3[params[3]] = 0;
241 STRSET(ep, params[1], s3);
246 _embryo_str_strcut(Embryo_Program *ep, Embryo_Cell *params)
251 /* params[1] = dst */
252 /* params[2] = str */
255 if (params[0] != (4 * sizeof(Embryo_Cell))) return 0;
256 if (params[3] < 0) params[3] = 0;
257 if (params[4] < params[3]) params[4] = params[3];
258 STRGET(ep, s1, params[2]);
261 if (params[3] >= l1) params[3] = l1;
262 if (params[4] >= l1) params[4] = l1;
263 if (params[4] == params[3])
265 STRSET(ep, params[1], "");
268 s2 = alloca(params[4] - params[3] + 1);
269 strncpy(s2, s1 + params[3], params[4] - params[3]);
270 s2[params[4] - params[3]] = 0;
271 STRSET(ep, params[1], s2);
276 _embryo_str_snprintf(Embryo_Program *ep, Embryo_Cell *params)
284 /* params[1] = buf */
285 /* params[2] = bufsize */
286 /* params[3] = format_string */
287 /* params[4] = first arg ... */
288 if (params[0] < (Embryo_Cell)(3 * sizeof(Embryo_Cell))) return 0;
289 if (params[2] <= 0) return 0;
290 STRGET(ep, s1, params[3]);
292 s2 = alloca(params[2] + 1);
295 pnum = (params[0] / sizeof(Embryo_Cell)) - 3;
296 for (p = 0, o = 0, i = 0; (s1[i]) && (o < (params[2] - 1)) && (p < (pnum + 1)); i++)
298 if ((!inesc) && (!insub))
300 if (s1[i] == '\\') inesc = 1;
301 else if (s1[i] == '%') insub = 1;
302 if ((!inesc) && (!insub))
331 if ((insub) && (s1[i] == '%')) pnum++;
332 if ((insub) && (p < pnum))
341 cptr = embryo_data_address_get(ep, params[4 + p]);
342 if (cptr) s2[o] = (char)(*cptr);
355 if (s1[i] == 'i') strcpy(fmt, "%i");
356 else if (s1[i] == 'd') strcpy(fmt, "%d");
357 else if (s1[i] == 'x') strcpy(fmt, "%x");
358 else if (s1[i] == 'X') strcpy(fmt, "%08x");
359 cptr = embryo_data_address_get(ep, params[4 + p]);
360 if (cptr) snprintf(tmp, sizeof(tmp), fmt, (int)(*cptr));
362 if ((o + l) > (params[2] - 1))
364 l = params[2] - 1 - o;
378 cptr = embryo_data_address_get(ep, params[4 + p]);
379 if (cptr) snprintf(tmp, sizeof(tmp), "%f", (double)EMBRYO_CELL_TO_FLOAT(*cptr));
381 if ((o + l) > (params[2] - 1))
383 l = params[2] - 1 - o;
397 STRGET(ep, tmp, params[4 + p]);
399 if ((o + l) > (params[2] - 1))
401 l = params[2] - 1 - o;
421 STRSET(ep, params[1], s2);
426 _embryo_str_strstr(Embryo_Program *ep, Embryo_Cell *params)
430 /* params[1] = str */
431 /* params[2] = ndl */
432 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
433 STRGET(ep, s1, params[1]);
434 STRGET(ep, s2, params[2]);
435 if ((!s1) || (!s2)) return -1;
438 return (Embryo_Cell)(p - s1);
442 _embryo_str_strchr(Embryo_Program *ep, Embryo_Cell *params)
446 /* params[1] = str */
448 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
449 STRGET(ep, s1, params[1]);
450 STRGET(ep, s2, params[2]);
451 if ((!s1) || (!s2)) return -1;
452 p = strchr(s1, s2[0]);
454 return (Embryo_Cell)(p - s1);
458 _embryo_str_strrchr(Embryo_Program *ep, Embryo_Cell *params)
462 /* params[1] = str */
464 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
465 STRGET(ep, s1, params[1]);
466 STRGET(ep, s2, params[2]);
467 if ((!s1) || (!s2)) return -1;
468 p = strrchr(s1, s2[0]);
470 return (Embryo_Cell)(p - s1);
473 /* functions used by the rest of embryo */
476 _embryo_str_init(Embryo_Program *ep)
478 embryo_program_native_call_add(ep, "atoi", _embryo_str_atoi);
479 embryo_program_native_call_add(ep, "fnmatch", _embryo_str_fnmatch);
480 embryo_program_native_call_add(ep, "strcmp", _embryo_str_strcmp);
481 embryo_program_native_call_add(ep, "strncmp", _embryo_str_strncmp);
482 embryo_program_native_call_add(ep, "strcpy", _embryo_str_strcpy);
483 embryo_program_native_call_add(ep, "strncpy", _embryo_str_strncpy);
484 embryo_program_native_call_add(ep, "strlen", _embryo_str_strlen);
485 embryo_program_native_call_add(ep, "strcat", _embryo_str_strcat);
486 embryo_program_native_call_add(ep, "strncat", _embryo_str_strncat);
487 embryo_program_native_call_add(ep, "strprep", _embryo_str_strprep);
488 embryo_program_native_call_add(ep, "strnprep", _embryo_str_strnprep);
489 embryo_program_native_call_add(ep, "strcut", _embryo_str_strcut);
490 embryo_program_native_call_add(ep, "snprintf", _embryo_str_snprintf);
491 embryo_program_native_call_add(ep, "strstr", _embryo_str_strstr);
492 embryo_program_native_call_add(ep, "strchr", _embryo_str_strchr);
493 embryo_program_native_call_add(ep, "strrchr", _embryo_str_strrchr);