2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
5 #include "embryo_private.h"
8 #define STRGET(ep, str, par) { \
9 Embryo_Cell *___cptr; \
11 if ((___cptr = embryo_data_address_get(ep, par))) { \
13 ___l = embryo_data_string_length_get(ep, ___cptr); \
14 (str) = alloca(___l + 1); \
15 if (str) embryo_data_string_get(ep, ___cptr, str); \
17 #define STRSET(ep, par, str) { \
18 Embryo_Cell *___cptr; \
19 if ((___cptr = embryo_data_address_get(ep, par))) { \
20 embryo_data_string_set(ep, str, ___cptr); \
23 /* exported string api */
26 _embryo_str_atoi(Embryo_Program *ep, Embryo_Cell *params)
31 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
32 STRGET(ep, s1, params[1]);
34 return (Embryo_Cell)atoi(s1);
38 _embryo_str_fnmatch(Embryo_Program *ep, Embryo_Cell *params)
42 /* params[1] = glob */
44 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
45 STRGET(ep, s1, params[1]);
46 STRGET(ep, s2, params[2]);
47 if ((!s1) || (!s2)) return -1;
48 return (Embryo_Cell)fnmatch(s1, s2, 0);
52 _embryo_str_strcmp(Embryo_Program *ep, Embryo_Cell *params)
56 /* params[1] = str1 */
57 /* params[2] = str2 */
58 if (params[0] != (2 * sizeof(Embryo_Cell))) return -1;
59 STRGET(ep, s1, params[1]);
60 STRGET(ep, s2, params[2]);
61 if ((!s1) || (!s2)) return -1;
62 return (Embryo_Cell)strcmp(s1, s2);
66 _embryo_str_strncmp(Embryo_Program *ep, Embryo_Cell *params)
70 /* params[1] = str1 */
71 /* params[2] = str2 */
73 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
74 if (params[3] < 0) params[3] = 0;
75 STRGET(ep, s1, params[1]);
76 STRGET(ep, s2, params[2]);
77 if ((!s1) || (!s2)) return -1;
78 return (Embryo_Cell)strncmp(s1, s2, (size_t)params[3]);
82 _embryo_str_strcpy(Embryo_Program *ep, Embryo_Cell *params)
88 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
89 STRGET(ep, s1, params[2]);
91 STRSET(ep, params[1], s1);
96 _embryo_str_strncpy(Embryo_Program *ep, Embryo_Cell *params)
101 /* params[1] = dst */
102 /* params[2] = str */
104 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
105 if (params[3] < 0) params[3] = 0;
106 STRGET(ep, s1, params[2]);
109 if (l > params[3]) s1[params[3]] = 0;
110 STRSET(ep, params[1], s1);
115 _embryo_str_strlen(Embryo_Program *ep, Embryo_Cell *params)
119 /* params[1] = str */
120 if (params[0] != (1 * sizeof(Embryo_Cell))) return 0;
121 STRGET(ep, s1, params[1]);
123 return (Embryo_Cell)strlen(s1);
127 _embryo_str_strcat(Embryo_Program *ep, Embryo_Cell *params)
131 /* params[1] = dsr */
132 /* params[2] = str */
133 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
134 STRGET(ep, s1, params[1]);
135 STRGET(ep, s2, params[2]);
136 if ((!s1) || (!s2)) return 0;
137 s3 = alloca(strlen(s1) + strlen(s2) + 1);
141 STRSET(ep, params[1], s3);
146 _embryo_str_strncat(Embryo_Program *ep, Embryo_Cell *params)
151 /* params[1] = dst */
152 /* params[2] = str */
154 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
155 if (params[3] < 0) params[3] = 0;
156 STRGET(ep, s1, params[1]);
157 STRGET(ep, s2, params[2]);
158 if ((!s1) || (!s2)) return 0;
161 s3 = alloca(l1 + l2 + 1);
164 strncat(s3, s2, params[3]);
165 if (l2 >= params[3]) s3[l1 + params[3]] = 0;
166 STRSET(ep, params[1], s3);
171 _embryo_str_strprep(Embryo_Program *ep, Embryo_Cell *params)
175 /* params[1] = dst */
176 /* params[2] = str */
177 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
178 STRGET(ep, s1, params[1]);
179 STRGET(ep, s2, params[2]);
180 if ((!s1) || (!s2)) return 0;
181 s3 = alloca(strlen(s1) + strlen(s2) + 1);
185 STRSET(ep, params[1], s3);
190 _embryo_str_strnprep(Embryo_Program *ep, Embryo_Cell *params)
195 /* params[1] = dst */
196 /* params[2] = str */
198 if (params[0] != (3 * sizeof(Embryo_Cell))) return 0;
199 if (params[3] < 0) params[3] = 0;
200 STRGET(ep, s1, params[1]);
201 STRGET(ep, s2, params[2]);
202 if ((!s1) || (!s2)) return 0;
205 s3 = alloca(l1 + l2 + 1);
207 strncpy(s3, s2, params[3]);
208 if (params[3] <= l2) s3[params[3]] = 0;
210 STRSET(ep, params[1], s3);
215 _embryo_str_strcut(Embryo_Program *ep, Embryo_Cell *params)
220 /* params[1] = dst */
221 /* params[2] = str */
224 if (params[0] != (4 * sizeof(Embryo_Cell))) return 0;
225 if (params[3] < 0) params[3] = 0;
226 if (params[4] < params[3]) params[4] = params[3];
227 STRGET(ep, s1, params[2]);
230 if (params[3] >= l1) params[3] = l1;
231 if (params[4] >= l1) params[4] = l1;
232 if (params[4] == params[3])
234 STRSET(ep, params[1], "");
237 s2 = alloca(params[4] - params[3] + 1);
238 strncpy(s2, s1 + params[3], params[4] - params[3]);
239 s2[params[4] - params[3]] = 0;
240 STRSET(ep, params[1], s2);
245 _embryo_str_snprintf(Embryo_Program *ep, Embryo_Cell *params)
253 /* params[1] = buf */
254 /* params[2] = bufsize */
255 /* params[3] = format_string */
256 /* params[4] = first arg ... */
257 if (params[0] < (3 * sizeof(Embryo_Cell))) return 0;
258 if (params[2] <= 0) return 0;
259 STRGET(ep, s1, params[3]);
261 s2 = alloca(params[2] + 1);
264 pnum = (params[0] / sizeof(Embryo_Cell)) - 3;
265 for (p = 0, o = 0, i = 0; (s1[i]) && (o < (params[2] - 1)) && (p < (pnum + 1)); i++)
267 if ((!inesc) && (!insub))
269 if (s1[i] == '\\') inesc = 1;
270 else if (s1[i] == '%') insub = 1;
271 if ((!inesc) && (!insub))
300 if ((insub) && (s1[i] == '%')) pnum++;
301 if ((insub) && (p < pnum))
310 cptr = embryo_data_address_get(ep, params[4 + p]);
311 if (cptr) s2[o] = (char)(*cptr);
324 if (s1[i] == 'i') strcpy(fmt, "%i");
325 else if (s1[i] == 'd') strcpy(fmt, "%d");
326 else if (s1[i] == 'x') strcpy(fmt, "%x");
327 else if (s1[i] == 'X') strcpy(fmt, "%08x");
328 cptr = embryo_data_address_get(ep, params[4 + p]);
329 if (cptr) snprintf(tmp, sizeof(tmp), fmt, (int)(*cptr));
331 if ((o + l) > (params[2] - 1))
333 l = params[2] - 1 - o;
347 cptr = embryo_data_address_get(ep, params[4 + p]);
348 if (cptr) snprintf(tmp, sizeof(tmp), "%f", (double)EMBRYO_CELL_TO_FLOAT(*cptr));
350 if ((o + l) > (params[2] - 1))
352 l = params[2] - 1 - o;
366 STRGET(ep, tmp, params[4 + p]);
368 if ((o + l) > (params[2] - 1))
370 l = params[2] - 1 - o;
390 STRSET(ep, params[1], s2);
395 _embryo_str_strstr(Embryo_Program *ep, Embryo_Cell *params)
399 /* params[1] = str */
400 /* params[2] = ndl */
401 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
402 STRGET(ep, s1, params[1]);
403 STRGET(ep, s2, params[2]);
404 if ((!s1) || (!s2)) return -1;
406 if (p == NULL) return -1;
407 return (Embryo_Cell)(p - s1);
411 _embryo_str_strchr(Embryo_Program *ep, Embryo_Cell *params)
415 /* params[1] = str */
417 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
418 STRGET(ep, s1, params[1]);
419 STRGET(ep, s2, params[2]);
420 p = strchr(s1, s2[0]);
421 if (p == NULL) return -1;
422 return (Embryo_Cell)(p - s1);
426 _embryo_str_strrchr(Embryo_Program *ep, Embryo_Cell *params)
430 /* params[1] = str */
432 if (params[0] != (2 * sizeof(Embryo_Cell))) return 0;
433 STRGET(ep, s1, params[1]);
434 STRGET(ep, s2, params[2]);
435 p = strrchr(s1, s2[0]);
436 if (p == NULL) return -1;
437 return (Embryo_Cell)(p - s1);
440 /* functions used by the rest of embryo */
443 _embryo_str_init(Embryo_Program *ep)
445 embryo_program_native_call_add(ep, "atoi", _embryo_str_atoi);
446 embryo_program_native_call_add(ep, "fnmatch", _embryo_str_fnmatch);
447 embryo_program_native_call_add(ep, "strcmp", _embryo_str_strcmp);
448 embryo_program_native_call_add(ep, "strncmp", _embryo_str_strncmp);
449 embryo_program_native_call_add(ep, "strcpy", _embryo_str_strcpy);
450 embryo_program_native_call_add(ep, "strncpy", _embryo_str_strncpy);
451 embryo_program_native_call_add(ep, "strlen", _embryo_str_strlen);
452 embryo_program_native_call_add(ep, "strcat", _embryo_str_strcat);
453 embryo_program_native_call_add(ep, "strncat", _embryo_str_strncat);
454 embryo_program_native_call_add(ep, "strprep", _embryo_str_strprep);
455 embryo_program_native_call_add(ep, "strnprep", _embryo_str_strnprep);
456 embryo_program_native_call_add(ep, "strcut", _embryo_str_strcut);
457 embryo_program_native_call_add(ep, "snprintf", _embryo_str_snprintf);
458 embryo_program_native_call_add(ep, "strstr", _embryo_str_strstr);
459 embryo_program_native_call_add(ep, "strchr", _embryo_str_strchr);
460 embryo_program_native_call_add(ep, "strrchr", _embryo_str_strrchr);