diff --git a/ase/awk/func.c b/ase/awk/func.c index ba61cc64..673f8340 100644 --- a/ase/awk/func.c +++ b/ase/awk/func.c @@ -1,5 +1,5 @@ /* - * $Id: func.c,v 1.73 2006-11-13 09:37:00 bacon Exp $ + * $Id: func.c,v 1.74 2006-11-14 14:54:17 bacon Exp $ */ #include @@ -1243,8 +1243,41 @@ static int __bfn_match (ase_awk_run_t* run) } static int __bfn_sprintf (ase_awk_run_t* run) -{ - return -1; +{ + ase_size_t nargs; + ase_awk_val_t* a0; + ase_char_t* str0, * ptr; + ase_size_t len0, len; + + nargs = ase_awk_getnargs (run); + ASE_AWK_ASSERT (run->awk, nargs > 0); + + a0 = ase_awk_getarg (run, 0); + if (a0->type == ASE_AWK_VAL_STR) + { + str0 = ((ase_awk_val_str_t*)a0)->buf; + len0 = ((ase_awk_val_str_t*)a0)->len; + } + else + { + str0 = ase_awk_valtostr ( + run, a0, ASE_AWK_VALTOSTR_CLEAR, ASE_NULL, &len0); + if (str0 == ASE_NULL) return -1; + } + + ptr = ase_awk_sprintf (run, str0, len0, nargs, ASE_NULL, &len); + if (a0->type != ASE_AWK_VAL_STR) ASE_AWK_FREE (run->awk, str0); + if (ptr == ASE_NULL) return -1; + + a0 = ase_awk_makestrval (run, ptr, len); + if (a0 == ASE_NULL) + { + ase_awk_setrunerrnum (run, ASE_AWK_ENOMEM); + return -1; + } + + ase_awk_setretval (run, a0); + return 0; } #if 0 diff --git a/ase/awk/run.c b/ase/awk/run.c index e46765ab..2ad28ec8 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.258 2006-11-13 15:07:24 bacon Exp $ + * $Id: run.c,v 1.259 2006-11-14 14:54:17 bacon Exp $ */ #include @@ -2441,7 +2441,7 @@ static int __formatted_output ( ase_size_t len; int n; - ptr = ase_awk_sprintf (run, fmt, fmt_len, args, &len); + ptr = ase_awk_sprintf (run, fmt, fmt_len, 0, args, &len); if (ptr == ASE_NULL) return -1; n = ase_awk_writeextio_str (run, out_type, dst, ptr, len); @@ -3537,7 +3537,7 @@ static ase_awk_val_t* __eval_binop_lshift ( if (n3 == 0) { if (l2 == 0) PANIC (run, ASE_AWK_EDIVBYZERO); - res = ase_awk_makeintval (run, (ase_long_t)l1 << (ase_long_t)l2); + res = ase_awk_makeintval (run, (ase_long_t)l1<<(ase_long_t)l2); } else PANIC (run, ASE_AWK_EOPERAND); @@ -3562,7 +3562,7 @@ static ase_awk_val_t* __eval_binop_rshift ( if (n3 == 0) { if (l2 == 0) PANIC (run, ASE_AWK_EDIVBYZERO); - res = ase_awk_makeintval (run, (ase_long_t)l1 >> (ase_long_t)l2); + res = ase_awk_makeintval (run, (ase_long_t)l1>>(ase_long_t)l2); } else PANIC (run, ASE_AWK_EOPERAND); @@ -5503,10 +5503,11 @@ static ase_char_t* __idxnde_to_str ( } ase_char_t* ase_awk_sprintf ( - ase_awk_run_t* run, const ase_char_t* fmt, - ase_size_t fmt_len, ase_awk_nde_t* args, ase_size_t* len) + ase_awk_run_t* run, const ase_char_t* fmt, ase_size_t fmt_len, + ase_size_t nargs_on_stack, ase_awk_nde_t* args, ase_size_t* len) { ase_size_t i, j; + ase_size_t stack_arg_idx = 1; #define OUT_CHAR(c) \ do { \ @@ -5554,13 +5555,15 @@ ase_char_t* ase_awk_sprintf ( ase_char_t* p; int n; - if (args == ASE_NULL) + if (args == ASE_NULL && stack_arg_idx >= nargs_on_stack) { run->errnum = ASE_AWK_EPRINTFARG; return ASE_NULL; } - v = __eval_expression (run, args); + v = (args == ASE_NULL)? + ase_awk_getarg (run, stack_arg_idx): + __eval_expression (run, args); if (v == ASE_NULL) return ASE_NULL; ase_awk_refupval (v); @@ -5586,7 +5589,8 @@ ase_char_t* ase_awk_sprintf ( p++; } - args = args->next; + if (args == ASE_NULL) stack_arg_idx++; + else args = args->next; i++; } else @@ -5610,13 +5614,15 @@ ase_char_t* ase_awk_sprintf ( ase_char_t* p; int n; - if (args == ASE_NULL) + if (args == ASE_NULL && stack_arg_idx >= nargs_on_stack) { run->errnum = ASE_AWK_EPRINTFARG; return ASE_NULL; } - v = __eval_expression (run, args); + v = (args == ASE_NULL)? + ase_awk_getarg (run, stack_arg_idx): + __eval_expression (run, args); if (v == ASE_NULL) return ASE_NULL; ase_awk_refupval (v); @@ -5642,7 +5648,8 @@ ase_char_t* ase_awk_sprintf ( p++; } - args = args->next; + if (args == ASE_NULL) stack_arg_idx++; + else args = args->next; i++; } else @@ -5665,7 +5672,7 @@ ase_char_t* ase_awk_sprintf ( ase_char_t* p; int n; - if (args == ASE_NULL) + if (args == ASE_NULL && stack_arg_idx >= nargs_on_stack) { run->errnum = ASE_AWK_EPRINTFARG; return ASE_NULL; @@ -5675,7 +5682,9 @@ ase_char_t* ase_awk_sprintf ( FMT_CHAR (ASE_T('l')); FMT_CHAR (fmt[i]); - v = __eval_expression (run, args); + v = (args == ASE_NULL)? + ase_awk_getarg (run, stack_arg_idx): + __eval_expression (run, args); if (v == ASE_NULL) return ASE_NULL; ase_awk_refupval (v); @@ -5712,7 +5721,7 @@ ase_char_t* ase_awk_sprintf ( ase_char_t* p; int n; - if (args == ASE_NULL) + if (args == ASE_NULL && stack_arg_idx >= nargs_on_stack) { run->errnum = ASE_AWK_EPRINTFARG; return ASE_NULL; @@ -5721,7 +5730,9 @@ ase_char_t* ase_awk_sprintf ( FMT_CHAR (ASE_T('L')); FMT_CHAR (fmt[i]); - v = __eval_expression (run, args); + v = (args == ASE_NULL)? + ase_awk_getarg (run, stack_arg_idx): + __eval_expression (run, args); if (v == ASE_NULL) return ASE_NULL; ase_awk_refupval (v); @@ -5749,7 +5760,7 @@ ase_char_t* ase_awk_sprintf ( ase_awk_val_t* v; ase_char_t* p; - if (args == ASE_NULL) + if (args == ASE_NULL && stack_arg_idx >= nargs_on_stack) { run->errnum = ASE_AWK_EPRINTFARG; return ASE_NULL; @@ -5757,7 +5768,9 @@ ase_char_t* ase_awk_sprintf ( FMT_CHAR (fmt[i]); - v = __eval_expression (run, args); + v = (args == ASE_NULL)? + ase_awk_getarg (run, stack_arg_idx): + __eval_expression (run, args); if (v == ASE_NULL) return ASE_NULL; ase_awk_refupval (v); @@ -5815,7 +5828,7 @@ ase_char_t* ase_awk_sprintf ( ase_awk_val_t* v; ase_char_t* p; - if (args == ASE_NULL) + if (args == ASE_NULL && stack_arg_idx >= nargs_on_stack) { run->errnum = ASE_AWK_EPRINTFARG; return ASE_NULL; @@ -5823,7 +5836,9 @@ ase_char_t* ase_awk_sprintf ( FMT_CHAR (fmt[i]); - v = __eval_expression (run, args); + v = (args == ASE_NULL)? + ase_awk_getarg (run, stack_arg_idx): + __eval_expression (run, args); if (v == ASE_NULL) return ASE_NULL; ase_awk_refupval (v); @@ -5878,7 +5893,8 @@ ase_char_t* ase_awk_sprintf ( OUT_CHAR (fmt[i]); } - args = args->next; + if (args == ASE_NULL) stack_arg_idx++; + else args = args->next; ase_awk_str_clear (&run->sprintf.fmt); } diff --git a/ase/awk/run.h b/ase/awk/run.h index 4b481e38..40ec3919 100644 --- a/ase/awk/run.h +++ b/ase/awk/run.h @@ -1,5 +1,5 @@ /* - * $Id: run.h,v 1.22 2006-11-13 15:08:54 bacon Exp $ + * $Id: run.h,v 1.23 2006-11-14 14:54:18 bacon Exp $ */ #ifndef _ASE_AWK_RUN_H_ @@ -105,8 +105,8 @@ extern "C" { #endif ase_char_t* ase_awk_sprintf ( - ase_awk_run_t* run, const ase_char_t* fmt, - ase_size_t fmt_len, ase_awk_nde_t* args, ase_size_t* len); + ase_awk_run_t* run, const ase_char_t* fmt, ase_size_t fmt_len, + ase_size_t nargs_on_stack, ase_awk_nde_t* args, ase_size_t* len); #ifdef __cplusplus } diff --git a/ase/awk/val.c b/ase/awk/val.c index cda80d36..a506fd62 100644 --- a/ase/awk/val.c +++ b/ase/awk/val.c @@ -1,5 +1,5 @@ /* - * $Id: val.c,v 1.81 2006-11-13 15:08:54 bacon Exp $ + * $Id: val.c,v 1.82 2006-11-14 14:54:18 bacon Exp $ */ #include @@ -578,6 +578,7 @@ static ase_char_t* __val_real_to_str ( /* TODO: need to use awk's own version of sprintf so that it would have * problems with handling long double or double... */ /* TODO: does it need to check if a null character is included in convfmt??? */ +/* TODO: check if convfmt contains more that one format specifier */ run->awk->syscas.sprintf (tbuf, ase_countof(tbuf), tmp, (double)v->val); if (buf == ASE_NULL) { diff --git a/ase/test/awk/arg.awk b/ase/test/awk/arg.awk index 1f823d09..01bdf5f0 100644 --- a/ase/test/awk/arg.awk +++ b/ase/test/awk/arg.awk @@ -29,4 +29,6 @@ BEGIN { if (ARGC >= 0) printf ("ARGC [%++#10.10f] is positive\n", 10124.1123); printf ("[%d], [%f], [%s]\n", 10124.1123, 10124.1123, 10124.1123); printf ("[%-10c] [% 0*.*d]\n", 65, 45, 48, -1); + + print sprintf ("abc%d %*.*d %c %s %c", 10, 20, 30, 40, "good", "good", 75.34); }