aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/builtin/sprintf.bi96
-rw-r--r--src/prog.c21
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
37char * 37static int
38get_num(char *p, unsigned *pn) 38get_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;
diff --git a/src/prog.c b/src/prog.c
index 83401ef3..75b52284 100644
--- a/src/prog.c
+++ b/src/prog.c
@@ -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 */
503void 509static void
504env_pop_auto(eval_environ_t env) 510env_pop_auto(eval_environ_t env)
@@ -508,3 +514,3 @@ env_pop_auto(eval_environ_t env)
508 514
509void 515static void
510env_unregister_autos(eval_environ_t env) 516env_unregister_autos(eval_environ_t env)
@@ -514,3 +520,3 @@ env_unregister_autos(eval_environ_t env)
514 520
515void 521static void
516env_fixup_autos(eval_environ_t env, ptrdiff_t offset) 522env_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];