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 { | |||
36 | 36 | ||
37 | char * | 37 | static int |
38 | get_num(char *p, unsigned *pn) | 38 | get_num(const char *p, int i, unsigned *pn) |
39 | { | 39 | { |
40 | unsigned n = 0; | 40 | unsigned n = 0; |
41 | for (; *p && mu_isdigit(*p); p++) | 41 | |
42 | n = n * 10 + *p - '0'; | 42 | for (; p[i] && mu_isdigit(p[i]); i++) |
43 | n = n * 10 + p[i] - '0'; | ||
43 | *pn = n; | 44 | *pn = n; |
44 | return p; | 45 | return i; |
45 | } | 46 | } |
@@ -52,4 +53,4 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
52 | int i = 0; | 53 | int i = 0; |
53 | char *p = format; | 54 | int cur = 0; |
54 | char *start; | 55 | int start; |
55 | char buf[SPRINTF_BUF_SIZE]; | 56 | char buf[SPRINTF_BUF_SIZE]; |
@@ -63,3 +64,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
63 | MF_VA_START(); | 64 | MF_VA_START(); |
64 | while (*p) { | 65 | while (format[cur]) { |
65 | unsigned n; | 66 | unsigned n; |
@@ -73,4 +74,4 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
73 | /* Expect `%', and copy all the rest verbatim */ | 74 | /* Expect `%', and copy all the rest verbatim */ |
74 | if (*p == '%') { | 75 | if (format[cur] == '%') { |
75 | start = p; | 76 | start = cur; |
76 | state = fmts_pos; | 77 | state = fmts_pos; |
@@ -80,4 +81,4 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
80 | } else | 81 | } else |
81 | MF_OBSTACK_1GROW(*p); | 82 | MF_OBSTACK_1GROW(format[cur]); |
82 | p++; | 83 | cur++; |
83 | break; | 84 | break; |
@@ -86,5 +87,5 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
86 | /* Expect '%' or an argument position -- %_% or %_2$ */ | 87 | /* Expect '%' or an argument position -- %_% or %_2$ */ |
87 | if (*p == '%') { | 88 | if (format[cur] == '%') { |
88 | MF_OBSTACK_1GROW('%'); | 89 | MF_OBSTACK_1GROW('%'); |
89 | p++; | 90 | cur++; |
90 | state = fmts_copy; | 91 | state = fmts_copy; |
@@ -92,8 +93,8 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
92 | } | 93 | } |
93 | if (mu_isdigit(*p)) { | 94 | if (mu_isdigit(format[cur])) { |
94 | char *q = get_num(p, &n); | 95 | int pos = get_num(format, cur, &n); |
95 | if (*q == '$') { | 96 | if (format[pos] == '$') { |
96 | argnum = n - 1; | 97 | argnum = n - 1; |
97 | flags |= FMT_ALTPOS; | 98 | flags |= FMT_ALTPOS; |
98 | p = q + 1; | 99 | cur = pos + 1; |
99 | } | 100 | } |
@@ -105,6 +106,6 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
105 | /* Expect flags -- %2$_# */ | 106 | /* Expect flags -- %2$_# */ |
106 | switch (*p) { | 107 | switch (format[cur]) { |
107 | case '#': | 108 | case '#': |
108 | flags |= FMT_ALTERNATE; | 109 | flags |= FMT_ALTERNATE; |
109 | p++; | 110 | cur++; |
110 | break; | 111 | break; |
@@ -113,3 +114,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
113 | flags |= FMT_PADZERO; | 114 | flags |= FMT_PADZERO; |
114 | p++; | 115 | cur++; |
115 | break; | 116 | break; |
@@ -118,3 +119,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
118 | flags |= FMT_ADJUST_LEFT; | 119 | flags |= FMT_ADJUST_LEFT; |
119 | p++; | 120 | cur++; |
120 | break; | 121 | break; |
@@ -123,3 +124,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
123 | flags |= FMT_SPACEPFX; | 124 | flags |= FMT_SPACEPFX; |
124 | p++; | 125 | cur++; |
125 | break; | 126 | break; |
@@ -128,3 +129,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
128 | flags |= FMT_SIGNPFX; | 129 | flags |= FMT_SIGNPFX; |
129 | p++; | 130 | cur++; |
130 | break; | 131 | break; |
@@ -138,7 +139,7 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
138 | /* Expect width -- %2$#_8 or %2$#_* */ | 139 | /* Expect width -- %2$#_8 or %2$#_* */ |
139 | if (mu_isdigit(*p)) { | 140 | if (mu_isdigit(format[cur])) { |
140 | p = get_num(p, &width); | 141 | cur = get_num(format, cur, &width); |
141 | state = fmts_prec; | 142 | state = fmts_prec; |
142 | } else if (*p == '*') { | 143 | } else if (format[cur] == '*') { |
143 | p++; | 144 | cur++; |
144 | state = fmts_width_arg; | 145 | state = fmts_width_arg; |
@@ -151,7 +152,7 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
151 | state = fmts_prec; | 152 | state = fmts_prec; |
152 | if (mu_isdigit(*p)) { | 153 | if (mu_isdigit(format[cur])) { |
153 | char *q = get_num(p, &n); | 154 | int pos = get_num(format, cur, &n); |
154 | if (*q == '$') { | 155 | if (format[pos] == '$') { |
155 | MF_VA_ARG(n-1, NUMBER, num); | 156 | MF_VA_ARG(n-1, NUMBER, num); |
156 | p = q + 1; | 157 | cur = pos + 1; |
157 | if (num < 0) { | 158 | if (num < 0) { |
@@ -178,8 +179,8 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
178 | state = fmts_conv; | 179 | state = fmts_conv; |
179 | if (*p == '.') { | 180 | if (format[cur] == '.') { |
180 | p++; | 181 | cur++; |
181 | if (mu_isdigit(*p)) { | 182 | if (mu_isdigit(format[cur])) { |
182 | p = get_num(p, &prec); | 183 | cur = get_num(format, cur, &prec); |
183 | } else if (*p == '*') { | 184 | } else if (format[cur] == '*') { |
184 | p++; | 185 | cur++; |
185 | state = fmts_prec_arg; | 186 | state = fmts_prec_arg; |
@@ -193,5 +194,5 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
193 | state = fmts_conv; | 194 | state = fmts_conv; |
194 | if (mu_isdigit(*p)) { | 195 | if (mu_isdigit(format[cur])) { |
195 | char *q = get_num(p, &n); | 196 | int pos = get_num(format, cur, &n); |
196 | if (*q == '$') { | 197 | if (format[pos] == '$') { |
197 | MF_VA_ARG(n-1, NUMBER, num); | 198 | MF_VA_ARG(n-1, NUMBER, num); |
@@ -199,3 +200,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
199 | prec = (unsigned) num; | 200 | prec = (unsigned) num; |
200 | p = q + 1; | 201 | cur = pos + 1; |
201 | break; | 202 | break; |
@@ -212,3 +213,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
212 | argnum = i++; | 213 | argnum = i++; |
213 | switch (*p) { | 214 | switch (format[cur]) { |
214 | case 's': | 215 | case 's': |
@@ -333,3 +334,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
333 | flags &= ~FMT_PADZERO; | 334 | flags &= ~FMT_PADZERO; |
334 | fmtbuf[1] = *p; | 335 | fmtbuf[1] = format[cur]; |
335 | snprintf(buf+2, sizeof(buf)-2, fmtbuf, num); | 336 | snprintf(buf+2, sizeof(buf)-2, fmtbuf, num); |
@@ -344,3 +345,3 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
344 | if (flags & FMT_ALTERNATE) { | 345 | if (flags & FMT_ALTERNATE) { |
345 | *--str = *p; | 346 | *--str = format[cur]; |
346 | *--str = '0'; | 347 | *--str = '0'; |
@@ -408,6 +409,7 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) | |||
408 | default: | 409 | default: |
409 | MF_OBSTACK_GROW(start, p - start + 1); | 410 | MF_OBSTACK_GROW(&format[start], |
411 | cur - start + 1); | ||
410 | } | 412 | } |
411 | 413 | ||
412 | p++; | 414 | cur++; |
413 | state = fmts_copy; | 415 | state = fmts_copy; |
@@ -386,3 +386,3 @@ env_get_locus(eval_environ_t env, struct mu_locus_range *locus) | |||
386 | locus->beg.mu_file = (char*)(env->dataseg + env->locus.file); | 386 | locus->beg.mu_file = (char*)(env->dataseg + env->locus.file); |
387 | env_register_auto(env, (void*) locus->beg.mu_file); | 387 | env_register_auto(env, (void*) &locus->beg.mu_file); |
388 | locus->beg.mu_line = env->locus.line; | 388 | locus->beg.mu_line = env->locus.line; |
@@ -495,2 +495,4 @@ env_register_auto(eval_environ_t env, void *ptr) | |||
495 | { | 495 | { |
496 | char *addr = *(char**)ptr; | ||
497 | |||
496 | if (env->numautos == MAX_AUTO_PTR) | 498 | if (env->numautos == MAX_AUTO_PTR) |
@@ -498,2 +500,6 @@ env_register_auto(eval_environ_t env, void *ptr) | |||
498 | __FILE__, __LINE__); | 500 | __FILE__, __LINE__); |
501 | /* Check if address is within the dataseg */ | ||
502 | if (!(addr >= (char*) env->dataseg | ||
503 | && (addr < (char*) (env->dataseg + datasize + env->stack_size)))) | ||
504 | ptr = NULL; | ||
499 | env->auto_ptr[env->numautos++] = ptr; | 505 | env->auto_ptr[env->numautos++] = ptr; |
@@ -502,3 +508,3 @@ env_register_auto(eval_environ_t env, void *ptr) | |||
502 | /* Pop the last registered auto variable */ | 508 | /* Pop the last registered auto variable */ |
503 | void | 509 | static void |
504 | env_pop_auto(eval_environ_t env) | 510 | env_pop_auto(eval_environ_t env) |
@@ -508,3 +514,3 @@ env_pop_auto(eval_environ_t env) | |||
508 | 514 | ||
509 | void | 515 | static void |
510 | env_unregister_autos(eval_environ_t env) | 516 | env_unregister_autos(eval_environ_t env) |
@@ -514,3 +520,3 @@ env_unregister_autos(eval_environ_t env) | |||
514 | 520 | ||
515 | void | 521 | static void |
516 | env_fixup_autos(eval_environ_t env, ptrdiff_t offset) | 522 | env_fixup_autos(eval_environ_t env, ptrdiff_t offset) |
@@ -520,3 +526,4 @@ env_fixup_autos(eval_environ_t env, ptrdiff_t offset) | |||
520 | STKVAL *pptr = env->auto_ptr[i]; |