2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
16 #elif defined __GNUC__
17 # define alloca __builtin_alloca
19 # define alloca __alloca
20 #elif defined _MSC_VER
22 # define alloca _alloca
28 void *alloca (size_t);
32 #include "embryo_private.h"
34 #define STRGET(ep, str, par) { \
35 Embryo_Cell *___cptr; \
37 if ((___cptr = embryo_data_address_get(ep, par))) { \
39 ___l = embryo_data_string_length_get(ep, ___cptr); \
40 (str) = alloca(___l + 1); \
41 if (str) embryo_data_string_get(ep, ___cptr, str); \
43 #define STRSET(ep, par, str) { \
44 Embryo_Cell *___cptr; \
45 if ((___cptr = embryo_data_address_get(ep, par))) { \
46 embryo_data_string_set(ep, str, ___cptr); \
49 /* exported string api */
52 _embryo_str_atoi(Embryo_Program *ep, Embryo_Cell *params)
57 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
58 STRGET(ep, s1, params[1]);
60 return (Embryo_Cell)atoi(s1);
64 _embryo_str_fnmatch(Embryo_Program *ep, Embryo_Cell *params)
68 /* params[1] = glob */
70 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
71 STRGET(ep, s1, params[1]);
72 STRGET(ep, s2, params[2]);
73 if ((!s1) || (!s2)) return -1;
74 return (Embryo_Cell)fnmatch(s1, s2, 0);
78 _embryo_str_strcmp(Embryo_Program *ep, Embryo_Cell *params)
82 /* params[1] = str1 */
83 /* params[2] = str2 */
84 if (params[0] != (2 * sizeof(Embryo_Cell))) return -1;
85 STRGET(ep, s1, params[1]);
86 STRGET(ep, s2, params[2]);
87 if ((!s1) || (!s2)) return -1;
88 return (Embryo_Cell)strcmp(s1, s2);
92 _embryo_str_strncmp(Embryo_Program *ep, Embryo_Cell *params)
96 /* params[1] = str1 */
97 /* params[2] = str2 */
99 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
100 if (params[3] < 0) params[3] = 0;
101 STRGET(ep, s1, params[1]);
102 STRGET(ep, s2, params[2]);
103 if ((!s1) || (!s2)) return -1;
104 return (Embryo_Cell)strncmp(s1, s2, (size_t)params[3]);
108 _embryo_str_strcpy(Embryo_Program *ep, Embryo_Cell *params)
112 /* params[1] = dst */
113 /* params[2] = str */
114 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
115 STRGET(ep, s1, params[2]);
117 STRSET(ep, params[1], s1);
122 _embryo_str_strncpy(Embryo_Program *ep, Embryo_Cell *params)
127 /* params[1] = dst */
128 /* params[2] = str */
130 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
131 if (params[3] < 0) params[3] = 0;
132 STRGET(ep, s1, params[2]);
135 if (l > params[3]) s1[params[3]] = 0;
136 STRSET(ep, params[1], s1);
141 _embryo_str_strlen(Embryo_Program *ep, Embryo_Cell *params)
145 /* params[1] = str */
146 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
147 STRGET(ep, s1, params[1]);
149 return (Embryo_Cell)strlen(s1);
153 _embryo_str_strcat(Embryo_Program *ep, Embryo_Cell *params)
157 /* params[1] = dsr */
158 /* params[2] = str */
159 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
160 STRGET(ep, s1, params[1]);
161 STRGET(ep, s2, params[2]);
162 if ((!s1) || (!s2)) return 0;
163 s3 = alloca(strlen(s1) + strlen(s2) + 1);
167 STRSET(ep, params[1], s3);
172 _embryo_str_strncat(Embryo_Program *ep, Embryo_Cell *params)
177 /* params[1] = dst */
178 /* params[2] = str */
180 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
181 if (params[3] < 0) params[3] = 0;
182 STRGET(ep, s1, params[1]);
183 STRGET(ep, s2, params[2]);
184 if ((!s1) || (!s2)) return 0;
187 s3 = alloca(l1 + l2 + 1);
190 strncat(s3, s2, params[3]);
191 if (l2 >= params[3]) s3[l1 + params[3]] = 0;
192 STRSET(ep, params[1], s3);
197 _embryo_str_strprep(Embryo_Program *ep, Embryo_Cell *params)
201 /* params[1] = dst */
202 /* params[2] = str */
203 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
204 STRGET(ep, s1, params[1]);
205 STRGET(ep, s2, params[2]);
206 if ((!s1) || (!s2)) return 0;
207 s3 = alloca(strlen(s1) + strlen(s2) + 1);
211 STRSET(ep, params[1], s3);
216 _embryo_str_strnprep(Embryo_Program *ep, Embryo_Cell *params)
221 /* params[1] = dst */
222 /* params[2] = str */
224 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
225 if (params[3] < 0) params[3] = 0;
226 STRGET(ep, s1, params[1]);
227 STRGET(ep, s2, params[2]);
228 if ((!s1) || (!s2)) return 0;
231 s3 = alloca(l1 + l2 + 1);
233 strncpy(s3, s2, params[3]);
234 if (params[3] <= l2) s3[params[3]] = 0;
236 STRSET(ep, params[1], s3);
241 _embryo_str_strcut(Embryo_Program *ep, Embryo_Cell *params)
246 /* params[1] = dst */
247 /* params[2] = str */
250 if (params[0] != (4 * sizeof(Embryo_Cell))) return 0;
251 if (params[3] < 0) params[3] = 0;
252 if (params[4] < params[3]) params[4] = params[3];
253 STRGET(ep, s1, params[2]);
256 if (params[3] >= l1) params[3] = l1;
257 if (params[4] >= l1) params[4] = l1;
258 if (params[4] == params[3])
260 STRSET(ep, params[1], "");
263 s2 = alloca(params[4] - params[3] + 1);
264 strncpy(s2, s1 + params[3], params[4] - params[3]);
265 s2[params[4] - params[3]] = 0;
266 STRSET(ep, params[1], s2);
271 _embryo_str_snprintf(Embryo_Program *ep, Embryo_Cell *params)
279 /* params[1] = buf */
280 /* params[2] = bufsize */
281 /* params[3] = format_string */
282 /* params[4] = first arg ... */
283 if (params[0] < (3 * sizeof(Embryo_Cell))) return 0;
284 if (params[2] <= 0) return 0;
285 STRGET(ep, s1, params[3]);
287 s2 = alloca(params[2] + 1);
290 pnum = (params[0] / sizeof(Embryo_Cell)) - 3;
291 for (p = 0, o = 0, i = 0; (s1[i]) && (o < (params[2] - 1)) && (p < (pnum + 1)); i++)
293 if ((!inesc) && (!insub))
295 if (s1[i] == '\\') inesc = 1;
296 else if (s1[i] == '%') insub = 1;
297 if ((!inesc) && (!insub))
326 if ((insub) && (s1[i] == '%')) pnum++;
327 if ((insub) && (p < pnum))
336 cptr = embryo_data_address_get(ep, params[4 + p]);
337 if (cptr) s2[o] = (char)(*cptr);
350 if (s1[i] == 'i') strcpy(fmt, "%i");
351 else if (s1[i] == 'd') strcpy(fmt, "%d");
352 else if (s1[i] == 'x') strcpy(fmt, "%x");
353 else if (s1[i] == 'X') strcpy(fmt, "%08x");
354 cptr = embryo_data_address_get(ep, params[4 + p]);
355 if (cptr) snprintf(tmp, sizeof(tmp), fmt, (int)(*cptr));
357 if ((o + l) > (params[2] - 1))
359 l = params[2] - 1 - o;
373 cptr = embryo_data_address_get(ep, params[4 + p]);
374 if (cptr) snprintf(tmp, sizeof(tmp), "%f", (double)EMBRYO_CELL_TO_FLOAT(*cptr));
376 if ((o + l) > (params[2] - 1))
378 l = params[2] - 1 - o;
392 STRGET(ep, tmp, params[4 + p]);
394 if ((o + l) > (params[2] - 1))
396 l = params[2] - 1 - o;
416 STRSET(ep, params[1], s2);
421 _embryo_str_strstr(Embryo_Program *ep, Embryo_Cell *params)
425 /* params[1] = str */
426 /* params[2] = ndl */
427 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
428 STRGET(ep, s1, params[1]);
429 STRGET(ep, s2, params[2]);
430 if ((!s1) || (!s2)) return -1;
432 if (p == NULL) return -1;
433 return (Embryo_Cell)(p - s1);
437 _embryo_str_strchr(Embryo_Program *ep, Embryo_Cell *params)
441 /* params[1] = str */
443 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
444 STRGET(ep, s1, params[1]);
445 STRGET(ep, s2, params[2]);
446 p = strchr(s1, s2[0]);
447 if (p == NULL) return -1;
448 return (Embryo_Cell)(p - s1);
452 _embryo_str_strrchr(Embryo_Program *ep, Embryo_Cell *params)
456 /* params[1] = str */
458 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
459 STRGET(ep, s1, params[1]);
460 STRGET(ep, s2, params[2]);
461 p = strrchr(s1, s2[0]);
462 if (p == NULL) return -1;
463 return (Embryo_Cell)(p - s1);
466 /* functions used by the rest of embryo */
469 _embryo_str_init(Embryo_Program *ep)
471 embryo_program_native_call_add(ep, "atoi", _embryo_str_atoi);
472 embryo_program_native_call_add(ep, "fnmatch", _embryo_str_fnmatch);
473 embryo_program_native_call_add(ep, "strcmp", _embryo_str_strcmp);
474 embryo_program_native_call_add(ep, "strncmp", _embryo_str_strncmp);
475 embryo_program_native_call_add(ep, "strcpy", _embryo_str_strcpy);
476 embryo_program_native_call_add(ep, "strncpy", _embryo_str_strncpy);
477 embryo_program_native_call_add(ep, "strlen", _embryo_str_strlen);
478 embryo_program_native_call_add(ep, "strcat", _embryo_str_strcat);
479 embryo_program_native_call_add(ep, "strncat", _embryo_str_strncat);
480 embryo_program_native_call_add(ep, "strprep", _embryo_str_strprep);
481 embryo_program_native_call_add(ep, "strnprep", _embryo_str_strnprep);
482 embryo_program_native_call_add(ep, "strcut", _embryo_str_strcut);
483 embryo_program_native_call_add(ep, "snprintf", _embryo_str_snprintf);
484 embryo_program_native_call_add(ep, "strstr", _embryo_str_strstr);
485 embryo_program_native_call_add(ep, "strchr", _embryo_str_strchr);
486 embryo_program_native_call_add(ep, "strrchr", _embryo_str_strrchr);