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);
41 #include "embryo_private.h"
43 #define STRGET(ep, str, par) { \
44 Embryo_Cell *___cptr; \
46 if ((___cptr = embryo_data_address_get(ep, par))) { \
48 ___l = embryo_data_string_length_get(ep, ___cptr); \
49 (str) = alloca(___l + 1); \
50 if (str) embryo_data_string_get(ep, ___cptr, str); \
52 #define STRSET(ep, par, str) { \
53 Embryo_Cell *___cptr; \
54 if ((___cptr = embryo_data_address_get(ep, par))) { \
55 embryo_data_string_set(ep, str, ___cptr); \
58 /* exported string api */
61 _embryo_str_atoi(Embryo_Program *ep, Embryo_Cell *params)
66 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
67 STRGET(ep, s1, params[1]);
69 return (Embryo_Cell)atoi(s1);
73 _embryo_str_fnmatch(Embryo_Program *ep, Embryo_Cell *params)
77 /* params[1] = glob */
79 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
80 STRGET(ep, s1, params[1]);
81 STRGET(ep, s2, params[2]);
82 if ((!s1) || (!s2)) return -1;
83 return (Embryo_Cell)fnmatch(s1, s2, 0);
87 _embryo_str_strcmp(Embryo_Program *ep, Embryo_Cell *params)
91 /* params[1] = str1 */
92 /* params[2] = str2 */
93 if (params[0] != (2 * sizeof(Embryo_Cell))) return -1;
94 STRGET(ep, s1, params[1]);
95 STRGET(ep, s2, params[2]);
96 if ((!s1) || (!s2)) return -1;
97 return (Embryo_Cell)strcmp(s1, s2);
101 _embryo_str_strncmp(Embryo_Program *ep, Embryo_Cell *params)
105 /* params[1] = str1 */
106 /* params[2] = str2 */
108 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
109 if (params[3] < 0) params[3] = 0;
110 STRGET(ep, s1, params[1]);
111 STRGET(ep, s2, params[2]);
112 if ((!s1) || (!s2)) return -1;
113 return (Embryo_Cell)strncmp(s1, s2, (size_t)params[3]);
117 _embryo_str_strcpy(Embryo_Program *ep, Embryo_Cell *params)
121 /* params[1] = dst */
122 /* params[2] = str */
123 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
124 STRGET(ep, s1, params[2]);
126 STRSET(ep, params[1], s1);
131 _embryo_str_strncpy(Embryo_Program *ep, Embryo_Cell *params)
136 /* params[1] = dst */
137 /* params[2] = str */
139 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
140 if (params[3] < 0) params[3] = 0;
141 STRGET(ep, s1, params[2]);
144 if (l > params[3]) s1[params[3]] = 0;
145 STRSET(ep, params[1], s1);
150 _embryo_str_strlen(Embryo_Program *ep, Embryo_Cell *params)
154 /* params[1] = str */
155 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
156 STRGET(ep, s1, params[1]);
158 return (Embryo_Cell)strlen(s1);
162 _embryo_str_strcat(Embryo_Program *ep, Embryo_Cell *params)
166 /* params[1] = dsr */
167 /* params[2] = str */
168 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
169 STRGET(ep, s1, params[1]);
170 STRGET(ep, s2, params[2]);
171 if ((!s1) || (!s2)) return 0;
172 s3 = alloca(strlen(s1) + strlen(s2) + 1);
176 STRSET(ep, params[1], s3);
181 _embryo_str_strncat(Embryo_Program *ep, Embryo_Cell *params)
186 /* params[1] = dst */
187 /* params[2] = str */
189 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
190 if (params[3] < 0) params[3] = 0;
191 STRGET(ep, s1, params[1]);
192 STRGET(ep, s2, params[2]);
193 if ((!s1) || (!s2)) return 0;
196 s3 = alloca(l1 + l2 + 1);
199 strncat(s3, s2, params[3]);
200 if (l2 >= params[3]) s3[l1 + params[3]] = 0;
201 STRSET(ep, params[1], s3);
206 _embryo_str_strprep(Embryo_Program *ep, Embryo_Cell *params)
210 /* params[1] = dst */
211 /* params[2] = str */
212 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
213 STRGET(ep, s1, params[1]);
214 STRGET(ep, s2, params[2]);
215 if ((!s1) || (!s2)) return 0;
216 s3 = alloca(strlen(s1) + strlen(s2) + 1);
220 STRSET(ep, params[1], s3);
225 _embryo_str_strnprep(Embryo_Program *ep, Embryo_Cell *params)
230 /* params[1] = dst */
231 /* params[2] = str */
233 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
234 if (params[3] < 0) params[3] = 0;
235 STRGET(ep, s1, params[1]);
236 STRGET(ep, s2, params[2]);
237 if ((!s1) || (!s2)) return 0;
240 s3 = alloca(l1 + l2 + 1);
242 strncpy(s3, s2, params[3]);
243 if (params[3] <= l2) s3[params[3]] = 0;
245 STRSET(ep, params[1], s3);
250 _embryo_str_strcut(Embryo_Program *ep, Embryo_Cell *params)
255 /* params[1] = dst */
256 /* params[2] = str */
259 if (params[0] != (4 * sizeof(Embryo_Cell))) return 0;
260 if (params[3] < 0) params[3] = 0;
261 if (params[4] < params[3]) params[4] = params[3];
262 STRGET(ep, s1, params[2]);
265 if (params[3] >= l1) params[3] = l1;
266 if (params[4] >= l1) params[4] = l1;
267 if (params[4] == params[3])
269 STRSET(ep, params[1], "");
272 s2 = alloca(params[4] - params[3] + 1);
273 strncpy(s2, s1 + params[3], params[4] - params[3]);
274 s2[params[4] - params[3]] = 0;
275 STRSET(ep, params[1], s2);
280 _embryo_str_snprintf(Embryo_Program *ep, Embryo_Cell *params)
288 /* params[1] = buf */
289 /* params[2] = bufsize */
290 /* params[3] = format_string */
291 /* params[4] = first arg ... */
292 if (params[0] < (Embryo_Cell)(3 * sizeof(Embryo_Cell))) return 0;
293 if (params[2] <= 0) return 0;
294 STRGET(ep, s1, params[3]);
296 s2 = alloca(params[2] + 1);
299 pnum = (params[0] / sizeof(Embryo_Cell)) - 3;
300 for (p = 0, o = 0, i = 0; (s1[i]) && (o < (params[2] - 1)) && (p < (pnum + 1)); i++)
302 if ((!inesc) && (!insub))
304 if (s1[i] == '\\') inesc = 1;
305 else if (s1[i] == '%') insub = 1;
306 if ((!inesc) && (!insub))
335 if ((insub) && (s1[i] == '%')) pnum++;
336 if ((insub) && (p < pnum))
345 cptr = embryo_data_address_get(ep, params[4 + p]);
346 if (cptr) s2[o] = (char)(*cptr);
359 if (s1[i] == 'i') strcpy(fmt, "%i");
360 else if (s1[i] == 'd') strcpy(fmt, "%d");
361 else if (s1[i] == 'x') strcpy(fmt, "%x");
362 else if (s1[i] == 'X') strcpy(fmt, "%08x");
363 cptr = embryo_data_address_get(ep, params[4 + p]);
364 if (cptr) snprintf(tmp, sizeof(tmp), fmt, (int)(*cptr));
366 if ((o + l) > (params[2] - 1))
368 l = params[2] - 1 - o;
382 cptr = embryo_data_address_get(ep, params[4 + p]);
383 if (cptr) snprintf(tmp, sizeof(tmp), "%f", (double)EMBRYO_CELL_TO_FLOAT(*cptr));
385 if ((o + l) > (params[2] - 1))
387 l = params[2] - 1 - o;
401 STRGET(ep, tmp, params[4 + p]);
405 if ((o + l) > (params[2] - 1))
407 l = params[2] - 1 - o;
428 STRSET(ep, params[1], s2);
433 _embryo_str_strstr(Embryo_Program *ep, Embryo_Cell *params)
437 /* params[1] = str */
438 /* params[2] = ndl */
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;
445 return (Embryo_Cell)(p - s1);
449 _embryo_str_strchr(Embryo_Program *ep, Embryo_Cell *params)
453 /* params[1] = str */
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 = strchr(s1, s2[0]);
461 return (Embryo_Cell)(p - s1);
465 _embryo_str_strrchr(Embryo_Program *ep, Embryo_Cell *params)
469 /* params[1] = str */
471 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
472 STRGET(ep, s1, params[1]);
473 STRGET(ep, s2, params[2]);
474 if ((!s1) || (!s2)) return -1;
475 p = strrchr(s1, s2[0]);
477 return (Embryo_Cell)(p - s1);
480 /* functions used by the rest of embryo */
483 _embryo_str_init(Embryo_Program *ep)
485 embryo_program_native_call_add(ep, "atoi", _embryo_str_atoi);
486 embryo_program_native_call_add(ep, "fnmatch", _embryo_str_fnmatch);
487 embryo_program_native_call_add(ep, "strcmp", _embryo_str_strcmp);
488 embryo_program_native_call_add(ep, "strncmp", _embryo_str_strncmp);
489 embryo_program_native_call_add(ep, "strcpy", _embryo_str_strcpy);
490 embryo_program_native_call_add(ep, "strncpy", _embryo_str_strncpy);
491 embryo_program_native_call_add(ep, "strlen", _embryo_str_strlen);
492 embryo_program_native_call_add(ep, "strcat", _embryo_str_strcat);
493 embryo_program_native_call_add(ep, "strncat", _embryo_str_strncat);
494 embryo_program_native_call_add(ep, "strprep", _embryo_str_strprep);
495 embryo_program_native_call_add(ep, "strnprep", _embryo_str_strnprep);
496 embryo_program_native_call_add(ep, "strcut", _embryo_str_strcut);
497 embryo_program_native_call_add(ep, "snprintf", _embryo_str_snprintf);
498 embryo_program_native_call_add(ep, "strstr", _embryo_str_strstr);
499 embryo_program_native_call_add(ep, "strchr", _embryo_str_strchr);
500 embryo_program_native_call_add(ep, "strrchr", _embryo_str_strrchr);