summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-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 11effd5..0a927dd 100644
--- a/src/builtin/sprintf.bi
+++ b/src/builtin/sprintf.bi
@@ -34,14 +34,15 @@ typedef enum {
34 fmts_conv /* Expect conversion specifier */ 34 fmts_conv /* Expect conversion specifier */
35} printf_format_state; 35} printf_format_state;
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}
46 47
47#define __MF_MAX(a,b) ((a)>(b) ? (a) : (b)) 48#define __MF_MAX(a,b) ((a)>(b) ? (a) : (b))
@@ -50,8 +51,8 @@ get_num(char *p, unsigned *pn)
50MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) 51MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
51{ 52{
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];
56 printf_format_state state = fmts_copy; 57 printf_format_state state = fmts_copy;
57 int flags = 0; 58 int flags = 0;
@@ -61,7 +62,7 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
61 62
62 MF_OBSTACK_BEGIN(); 63 MF_OBSTACK_BEGIN();
63 MF_VA_START(); 64 MF_VA_START();
64 while (*p) { 65 while (format[cur]) {
65 unsigned n; 66 unsigned n;
66 char *str; 67 char *str;
67 long num; 68 long num;
@@ -71,31 +72,31 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
71 switch (state) { 72 switch (state) {
72 case fmts_copy: 73 case fmts_copy:
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;
77 flags = 0; 78 flags = 0;
78 width = 0; 79 width = 0;
79 prec = 0; 80 prec = 0;
80 } else 81 } else
81 MF_OBSTACK_1GROW(*p); 82 MF_OBSTACK_1GROW(format[cur]);
82 p++; 83 cur++;
83 break; 84 break;
84 85
85 case fmts_pos: 86 case fmts_pos:
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;
91 break; 92 break;
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 }
100 } 101 }
101 state = fmts_flags; 102 state = fmts_flags;
@@ -103,30 +104,30 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
103 104
104 case fmts_flags: 105 case fmts_flags:
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;
111 112
112 case '0': 113 case '0':
113 flags |= FMT_PADZERO; 114 flags |= FMT_PADZERO;
114 p++; 115 cur++;
115 break; 116 break;
116 117
117 case '-': 118 case '-':
118 flags |= FMT_ADJUST_LEFT; 119 flags |= FMT_ADJUST_LEFT;
119 p++; 120 cur++;
120 break; 121 break;
121 122
122 case ' ': 123 case ' ':
123 flags |= FMT_SPACEPFX; 124 flags |= FMT_SPACEPFX;
124 p++; 125 cur++;
125 break; 126 break;
126 127
127 case '+': 128 case '+':
128 flags |= FMT_SIGNPFX; 129 flags |= FMT_SIGNPFX;
129 p++; 130 cur++;
130 break; 131 break;
131 132
132 default: 133 default:
@@ -136,11 +137,11 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
136 137
137 case fmts_width: 138 case fmts_width:
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;
145 } else 146 } else
146 state = fmts_prec; 147 state = fmts_prec;
@@ -149,11 +150,11 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
149 case fmts_width_arg: 150 case fmts_width_arg:
150 /* Expect width argument position -- %2$#*_1$ */ 151 /* Expect width argument position -- %2$#*_1$ */
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) {
158 flags |= FMT_SPACEPFX; 159 flags |= FMT_SPACEPFX;
159 num = - num; 160 num = - num;
@@ -176,12 +177,12 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
176 case fmts_prec: 177 case fmts_prec:
177 /* Expect precision -- %2$#*1$_. */ 178 /* Expect precision -- %2$#*1$_. */
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;
186 } 187 }
187 } 188 }
@@ -191,13 +192,13 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
191 /* Expect precision argument position -- 192 /* Expect precision argument position --
192 %2$#*1$.*_3$ */ 193 %2$#*1$.*_3$ */
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);
198 if (num > 0) 199 if (num > 0)
199 prec = (unsigned) num; 200 prec = (unsigned) num;
200 p = q + 1; 201 cur = pos + 1;
201 break; 202 break;
202 } 203 }
203 } 204 }
@@ -210,7 +211,7 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
210 case fmts_conv: /* Expect conversion specifier */ 211 case fmts_conv: /* Expect conversion specifier */
211 if (!(flags & FMT_ALTPOS)) 212 if (!(flags & FMT_ALTPOS))
212 argnum = i++; 213 argnum = i++;
213 switch (*p) { 214 switch (format[cur]) {
214 case 's': 215 case 's':
215 MF_VA_ARG(argnum, STRING, str); 216 MF_VA_ARG(argnum, STRING, str);
216 n = strlen(str); 217 n = strlen(str);
@@ -331,7 +332,7 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
331 /* A - overrides a 0 if both are given.*/ 332 /* A - overrides a 0 if both are given.*/
332 if (prec || (flags & FMT_ADJUST_LEFT)) 333 if (prec || (flags & FMT_ADJUST_LEFT))
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);
336 str = buf + 2; 337 str = buf + 2;
337 n = strlen(str); 338 n = strlen(str);
@@ -342,7 +343,7 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
342 } 343 }
343 344
344 if (flags & FMT_ALTERNATE) { 345 if (flags & FMT_ALTERNATE) {
345 *--str = *p; 346 *--str = format[cur];
346 *--str = '0'; 347 *--str = '0';
347 n += 2; 348 n += 2;
348 } 349 }
@@ -406,10 +407,11 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
406 break; 407 break;
407 408
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;
414 } 416 }
415 } 417 }
diff --git a/src/prog.c b/src/prog.c
index 83401ef..75b5228 100644
--- a/src/prog.c
+++ b/src/prog.c
@@ -384,7 +384,7 @@ env_get_locus(eval_environ_t env, struct mu_locus_range *locus)
384{ 384{
385 mu_locus_range_init(locus); 385 mu_locus_range_init(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;
389#if 0 389#if 0
390 locus->beg.mu_col = env->locus.point; 390 locus->beg.mu_col = env->locus.point;
@@ -493,32 +493,39 @@ env_function_cleanup_add(eval_environ_t env, void *data,
493static void 493static void
494env_register_auto(eval_environ_t env, void *ptr) 494env_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)
497 runtime_error(env, "INTERNAL ERROR at %s:%d, please report", 499 runtime_error(env, "INTERNAL ERROR at %s:%d, please report",
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;
500} 506}
501 507
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)
505{ 511{
506 env->numautos--; 512 env->numautos--;
507} 513}
508 514
509void 515static void
510env_unregister_autos(eval_environ_t env) 516env_unregister_autos(eval_environ_t env)
511{ 517{
512 env->numautos = 0; 518 env->numautos = 0;
513} 519}
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)
517{ 523{
518 int i; 524 int i;
519 for (i = 0; i < env->numautos; i++) { 525 for (i = 0; i < env->numautos; i++) {
520 STKVAL *pptr = env->auto_ptr[i]; 526 STKVAL *pptr = env->auto_ptr[i];
521 mf_c_val(*pptr,str) += offset; /*FIXME*/ 527 if (pptr)
528 mf_c_val(*pptr,str) += offset; /*FIXME*/
522 } 529 }
523} 530}
524 531
@@ -799,7 +806,7 @@ heap_obstack_grow(eval_environ_t env, void * MFL_DATASEG ptr, size_t size)
799 size_t words = B2STACK(size); 806 size_t words = B2STACK(size);
800 char *ret; 807 char *ret;
801 808
802 env_register_auto(env, ptr); 809 env_register_auto(env, (void*) &ptr);
803 if (env->tos - env->toh < words + B2STACK(env->temp_size)) 810 if (env->tos - env->toh < words + B2STACK(env->temp_size))
804 expand_dataseg(env, words, 811 expand_dataseg(env, words,
805 _("memory chunk too big to fit into heap")); 812 _("memory chunk too big to fit into heap"));
@@ -829,7 +836,7 @@ pushs(eval_environ_t env, const char * MFL_DATASEG s)
829{ 836{
830 size_t off; 837 size_t off;
831 838
832 env_register_auto(env, (void*) s); 839 env_register_auto(env, (void*) &s);
833 off = heap_reserve(env, strlen(s) + 1); 840 off = heap_reserve(env, strlen(s) + 1);
834 strcpy((char*) env_data_ref(env, off), s); 841 strcpy((char*) env_data_ref(env, off), s);
835 env_pop_auto(env); 842 env_pop_auto(env);

Return to:

Send suggestions and report system problems to the System administrator.