diff options
-rw-r--r-- | src/builtin/sprintf.bi | 96 | ||||
-rw-r--r-- | src/prog.c | 21 |
2 files changed, 63 insertions, 54 deletions
diff --git a/src/builtin/sprintf.bi b/src/builtin/sprintf.bi index 11effd58..0a927dd2 100644 --- a/src/builtin/sprintf.bi +++ b/src/builtin/sprintf.bi @@ -36,10 +36,11 @@ typedef enum { -char * -get_num(char *p, unsigned *pn) +static int +get_num(const char *p, int i, unsigned *pn) { unsigned n = 0; - for (; *p && mu_isdigit(*p); p++) - n = n * 10 + *p - '0'; + + for (; p[i] && mu_isdigit(p[i]); i++) + n = n * 10 + p[i] - '0'; *pn = n; - return p; + return i; } @@ -52,4 +53,4 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) int i = 0; - char *p = format; - char *start; + int cur = 0; + int start; char buf[SPRINTF_BUF_SIZE]; @@ -63,3 +64,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) MF_VA_START(); - while (*p) { + while (format[cur]) { unsigned n; @@ -73,4 +74,4 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) /* Expect `%', and copy all the rest verbatim */ - if (*p == '%') { - start = p; + if (format[cur] == '%') { + start = cur; state = fmts_pos; @@ -80,4 +81,4 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) } else - MF_OBSTACK_1GROW(*p); - p++; + MF_OBSTACK_1GROW(format[cur]); + cur++; break; @@ -86,5 +87,5 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) /* Expect '%' or an argument position -- %_% or %_2$ */ - if (*p == '%') { + if (format[cur] == '%') { MF_OBSTACK_1GROW('%'); - p++; + cur++; state = fmts_copy; @@ -92,8 +93,8 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) } - if (mu_isdigit(*p)) { - char *q = get_num(p, &n); - if (*q == '$') { + if (mu_isdigit(format[cur])) { + int pos = get_num(format, cur, &n); + if (format[pos] == '$') { argnum = n - 1; flags |= FMT_ALTPOS; - p = q + 1; + cur = pos + 1; } @@ -105,6 +106,6 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) /* Expect flags -- %2$_# */ - switch (*p) { + switch (format[cur]) { case '#': flags |= FMT_ALTERNATE; - p++; + cur++; break; @@ -113,3 +114,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) flags |= FMT_PADZERO; - p++; + cur++; break; @@ -118,3 +119,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) flags |= FMT_ADJUST_LEFT; - p++; + cur++; break; @@ -123,3 +124,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) flags |= FMT_SPACEPFX; - p++; + cur++; break; @@ -128,3 +129,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) flags |= FMT_SIGNPFX; - p++; + cur++; break; @@ -138,7 +139,7 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) /* Expect width -- %2$#_8 or %2$#_* */ - if (mu_isdigit(*p)) { - p = get_num(p, &width); + if (mu_isdigit(format[cur])) { + cur = get_num(format, cur, &width); state = fmts_prec; - } else if (*p == '*') { - p++; + } else if (format[cur] == '*') { + cur++; state = fmts_width_arg; @@ -151,7 +152,7 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) state = fmts_prec; - if (mu_isdigit(*p)) { - char *q = get_num(p, &n); - if (*q == '$') { + if (mu_isdigit(format[cur])) { + int pos = get_num(format, cur, &n); + if (format[pos] == '$') { MF_VA_ARG(n-1, NUMBER, num); - p = q + 1; + cur = pos + 1; if (num < 0) { @@ -178,8 +179,8 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) state = fmts_conv; - if (*p == '.') { - p++; - if (mu_isdigit(*p)) { - p = get_num(p, &prec); - } else if (*p == '*') { - p++; + if (format[cur] == '.') { + cur++; + if (mu_isdigit(format[cur])) { + cur = get_num(format, cur, &prec); + } else if (format[cur] == '*') { + cur++; state = fmts_prec_arg; @@ -193,5 +194,5 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) state = fmts_conv; - if (mu_isdigit(*p)) { - char *q = get_num(p, &n); - if (*q == '$') { + if (mu_isdigit(format[cur])) { + int pos = get_num(format, cur, &n); + if (format[pos] == '$') { MF_VA_ARG(n-1, NUMBER, num); @@ -199,3 +200,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) prec = (unsigned) num; - p = q + 1; + cur = pos + 1; break; @@ -212,3 +213,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) argnum = i++; - switch (*p) { + switch (format[cur]) { case 's': @@ -333,3 +334,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) flags &= ~FMT_PADZERO; - fmtbuf[1] = *p; + fmtbuf[1] = format[cur]; snprintf(buf+2, sizeof(buf)-2, fmtbuf, num); @@ -344,3 +345,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) if (flags & FMT_ALTERNATE) { - *--str = *p; + *--str = format[cur]; *--str = '0'; @@ -408,6 +409,7 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) default: - MF_OBSTACK_GROW(start, p - start + 1); + MF_OBSTACK_GROW(&format[start], + cur - start + 1); } - p++; + cur++; state = fmts_copy; @@ -386,3 +386,3 @@ env_get_locus(eval_environ_t env, struct mu_locus_range *locus) locus->beg.mu_file = (char*)(env->dataseg + env->locus.file); - env_register_auto(env, (void*) locus->beg.mu_file); + env_register_auto(env, (void*) &locus->beg.mu_file); locus->beg.mu_line = env->locus.line; @@ -495,2 +495,4 @@ env_register_auto(eval_environ_t env, void *ptr) { + char *addr = *(char**)ptr; + if (env->numautos == MAX_AUTO_PTR) @@ -498,2 +500,6 @@ env_register_auto(eval_environ_t env, void *ptr) __FILE__, __LINE__); + /* Check if address is within the dataseg */ + if (!(addr >= (char*) env->dataseg + && (addr < (char*) (env->dataseg + datasize + env->stack_size)))) + ptr = NULL; env->auto_ptr[env->numautos++] = ptr; @@ -502,3 +508,3 @@ env_register_auto(eval_environ_t env, void *ptr) /* Pop the last registered auto variable */ -void +static void env_pop_auto(eval_environ_t env) @@ -508,3 +514,3 @@ env_pop_auto(eval_environ_t env) -void +static void env_unregister_autos(eval_environ_t env) @@ -514,3 +520,3 @@ env_unregister_autos(eval_environ_t env) -void +static void env_fixup_autos(eval_environ_t env, ptrdiff_t offset) @@ -520,3 +526,4 @@ env_fixup_autos(eval_environ_t env, ptrdiff_t offset) STKVAL *pptr = env->auto_ptr[i]; - mf_c_val(*pptr,str) += offset; /*FIXME*/ + if (pptr) + mf_c_val(*pptr,str) += offset; /*FIXME*/ } @@ -801,3 +808,3 @@ heap_obstack_grow(eval_environ_t env, void * MFL_DATASEG ptr, size_t size) - env_register_auto(env, ptr); + env_register_auto(env, (void*) &ptr); if (env->tos - env->toh < words + B2STACK(env->temp_size)) @@ -831,3 +838,3 @@ pushs(eval_environ_t env, const char * MFL_DATASEG s) - env_register_auto(env, (void*) s); + env_register_auto(env, (void*) &s); off = heap_reserve(env, strlen(s) + 1); |