*** empty log message ***
This commit is contained in:
		| @ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * $Id: awk_i.h,v 1.77 2006-11-12 15:09:14 bacon Exp $ |  * $Id: awk_i.h,v 1.78 2006-11-13 15:08:53 bacon Exp $ | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #ifndef _ASE_AWK_AWKI_H_ | #ifndef _ASE_AWK_AWKI_H_ | ||||||
| @ -270,20 +270,10 @@ struct ase_awk_run_t | |||||||
|  |  | ||||||
| 	struct | 	struct | ||||||
| 	{ | 	{ | ||||||
| 		struct | 		ase_awk_str_t fmt; | ||||||
| 		{ | 		ase_awk_str_t out; | ||||||
| 			ase_size_t len; | 		ase_char_t tmp[4096]; | ||||||
| 			ase_char_t buf[1024]; | 	} sprintf; | ||||||
| 		} out; |  | ||||||
|  |  | ||||||
| 		struct |  | ||||||
| 		{ |  | ||||||
| 			ase_size_t len; |  | ||||||
| 			ase_char_t buf[256]; |  | ||||||
| 		} fmt; |  | ||||||
|  |  | ||||||
| 		ase_char_t buf[4096]; |  | ||||||
| 	} format; |  | ||||||
|  |  | ||||||
| 	int errnum; | 	int errnum; | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * $Id: map.c,v 1.30 2006-10-30 14:31:37 bacon Exp $ |  * $Id: map.c,v 1.31 2006-11-13 15:08:53 bacon Exp $ | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <ase/awk/awk_i.h> | #include <ase/awk/awk_i.h> | ||||||
| @ -76,8 +76,7 @@ void ase_awk_map_clear (ase_awk_map_t* map) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ASE_AWK_ASSERTX (map->awk, map->size == 0,  | 	ASE_AWK_ASSERTX (map->awk, map->size == 0,  | ||||||
| 		"the map should not contain any pairs of a key and a value" | 		"the map should not contain any pairs of a key and a value after it has been cleared"); | ||||||
| 		"after it has been cleared"); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| ase_awk_pair_t* ase_awk_map_get ( | ase_awk_pair_t* ase_awk_map_get ( | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * $Id: misc.c,v 1.37 2006-11-13 09:02:23 bacon Exp $ |  * $Id: misc.c,v 1.38 2006-11-13 15:08:53 bacon Exp $ | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <ase/awk/awk_i.h> | #include <ase/awk/awk_i.h> | ||||||
| @ -1061,13 +1061,6 @@ exit_loop: | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| int ase_awk_sprintf (ase_awk_t* awk, |  | ||||||
| 	ase_char_t* buf, ase_size_t len, const ase_char_t* fmt, ...) |  | ||||||
| { |  | ||||||
| 	/* TODO: */ |  | ||||||
| 	return -1; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int ase_awk_assertfail (ase_awk_t* awk,  | int ase_awk_assertfail (ase_awk_t* awk,  | ||||||
| 	const ase_char_t* expr, const ase_char_t* desc,  | 	const ase_char_t* expr, const ase_char_t* desc,  | ||||||
| 	const ase_char_t* file, int line) | 	const ase_char_t* file, int line) | ||||||
| @ -1088,3 +1081,4 @@ int ase_awk_assertfail (ase_awk_t* awk, | |||||||
| 	awk->syscas.abort (); | 	awk->syscas.abort (); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * $Id: misc.h,v 1.9 2006-10-31 10:13:14 bacon Exp $ |  * $Id: misc.h,v 1.10 2006-11-13 15:08:54 bacon Exp $ | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #ifndef _ASE_AWK_MISC_H_ | #ifndef _ASE_AWK_MISC_H_ | ||||||
| @ -38,9 +38,6 @@ ase_char_t* ase_awk_strxntokbyrex ( | |||||||
| 	ase_awk_run_t* run, const ase_char_t* s, ase_size_t len, | 	ase_awk_run_t* run, const ase_char_t* s, ase_size_t len, | ||||||
| 	void* rex, ase_char_t** tok, ase_size_t* tok_len, int* errnum); | 	void* rex, ase_char_t** tok, ase_size_t* tok_len, int* errnum); | ||||||
|  |  | ||||||
| int ase_awk_sprintf (ase_awk_t* awk, |  | ||||||
| 	ase_char_t* buf, ase_size_t len, const ase_char_t* fmt, ...); |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * $Id: parse.c,v 1.201 2006-11-13 09:02:23 bacon Exp $ |  * $Id: parse.c,v 1.202 2006-11-13 15:08:17 bacon Exp $ | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <ase/awk/awk_i.h> | #include <ase/awk/awk_i.h> | ||||||
| @ -3317,8 +3317,7 @@ static ase_awk_nde_t* __parse_print (ase_awk_t* awk, int type) | |||||||
|  |  | ||||||
| 	ASE_AWK_ASSERTX (awk,  | 	ASE_AWK_ASSERTX (awk,  | ||||||
| 		type == ASE_AWK_NDE_PRINT || type == ASE_AWK_NDE_PRINTF,  | 		type == ASE_AWK_NDE_PRINT || type == ASE_AWK_NDE_PRINTF,  | ||||||
| 		"the node type should be either ASE_AWK_NDE_PRINT or " | 		"the node type should be either ASE_AWK_NDE_PRINT or ASE_AWK_NDE_PRINTF"); | ||||||
| 		"ASE_AWK_NDE_PRINTF"); |  | ||||||
|  |  | ||||||
| 	if (type == ASE_AWK_NDE_PRINTF && args == ASE_NULL) | 	if (type == ASE_AWK_NDE_PRINTF && args == ASE_NULL) | ||||||
| 	{ | 	{ | ||||||
|  | |||||||
							
								
								
									
										840
									
								
								ase/awk/run.c
									
									
									
									
									
								
							
							
						
						
									
										840
									
								
								ase/awk/run.c
									
									
									
									
									
								
							| @ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * $Id: run.c,v 1.257 2006-11-13 09:02:23 bacon Exp $ |  * $Id: run.c,v 1.258 2006-11-13 15:07:24 bacon Exp $ | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <ase/awk/awk_i.h> | #include <ase/awk/awk_i.h> | ||||||
| @ -661,9 +661,26 @@ static int __init_run (ase_awk_run_t* run, ase_awk_runios_t* runios, int* errnum | |||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (ase_awk_str_open (&run->sprintf.out, 256, run->awk) == ASE_NULL) | ||||||
|  | 	{ | ||||||
|  | 		ase_awk_str_close (&run->inrec.line); | ||||||
|  | 		*errnum = ASE_AWK_ENOMEM; | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (ase_awk_str_open (&run->sprintf.fmt, 256, run->awk) == ASE_NULL) | ||||||
|  | 	{ | ||||||
|  | 		ase_awk_str_close (&run->sprintf.out); | ||||||
|  | 		ase_awk_str_close (&run->inrec.line); | ||||||
|  | 		*errnum = ASE_AWK_ENOMEM; | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (ase_awk_map_open (&run->named,  | 	if (ase_awk_map_open (&run->named,  | ||||||
| 		run, DEF_BUF_CAPA, __free_namedval, run->awk) == ASE_NULL)  | 		run, DEF_BUF_CAPA, __free_namedval, run->awk) == ASE_NULL)  | ||||||
| 	{ | 	{ | ||||||
|  | 		ase_awk_str_close (&run->sprintf.fmt); | ||||||
|  | 		ase_awk_str_close (&run->sprintf.out); | ||||||
| 		ase_awk_str_close (&run->inrec.line); | 		ase_awk_str_close (&run->inrec.line); | ||||||
| 		*errnum = ASE_AWK_ENOMEM;  | 		*errnum = ASE_AWK_ENOMEM;  | ||||||
| 		return -1; | 		return -1; | ||||||
| @ -676,6 +693,8 @@ static int __init_run (ase_awk_run_t* run, ase_awk_runios_t* runios, int* errnum | |||||||
| 		if (run->pattern_range_state == ASE_NULL) | 		if (run->pattern_range_state == ASE_NULL) | ||||||
| 		{ | 		{ | ||||||
| 			ase_awk_map_close (&run->named); | 			ase_awk_map_close (&run->named); | ||||||
|  | 			ase_awk_str_close (&run->sprintf.fmt); | ||||||
|  | 			ase_awk_str_close (&run->sprintf.out); | ||||||
| 			ase_awk_str_close (&run->inrec.line); | 			ase_awk_str_close (&run->inrec.line); | ||||||
| 			*errnum = ASE_AWK_ENOMEM;  | 			*errnum = ASE_AWK_ENOMEM;  | ||||||
| 				return -1; | 				return -1; | ||||||
| @ -702,6 +721,7 @@ static int __init_run (ase_awk_run_t* run, ase_awk_runios_t* runios, int* errnum | |||||||
|  |  | ||||||
| static void __deinit_run (ase_awk_run_t* run) | static void __deinit_run (ase_awk_run_t* run) | ||||||
| { | { | ||||||
|  |  | ||||||
| 	if (run->pattern_range_state != ASE_NULL) | 	if (run->pattern_range_state != ASE_NULL) | ||||||
| 		ASE_AWK_FREE (run->awk, run->pattern_range_state); | 		ASE_AWK_FREE (run->awk, run->pattern_range_state); | ||||||
|  |  | ||||||
| @ -761,6 +781,9 @@ static void __deinit_run (ase_awk_run_t* run) | |||||||
| 		run->global.subsep.len = 0; | 		run->global.subsep.len = 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	ase_awk_str_close (&run->sprintf.fmt); | ||||||
|  | 	ase_awk_str_close (&run->sprintf.out); | ||||||
|  |  | ||||||
| 	/* destroy input record. ase_awk_clrrec should be called | 	/* destroy input record. ase_awk_clrrec should be called | ||||||
| 	 * before the run stack has been destroyed because it may try | 	 * before the run stack has been destroyed because it may try | ||||||
| 	 * to change the value to ASE_AWK_GLOBAL_NF. */ | 	 * to change the value to ASE_AWK_GLOBAL_NF. */ | ||||||
| @ -1963,9 +1986,7 @@ static int __run_delete (ase_awk_run_t* run, ase_awk_nde_delete_t* nde) | |||||||
| 		ASE_AWK_ASSERTX (run->awk,  | 		ASE_AWK_ASSERTX (run->awk,  | ||||||
| 			(var->type == ASE_AWK_NDE_NAMED && var->idx == ASE_NULL) || | 			(var->type == ASE_AWK_NDE_NAMED && var->idx == ASE_NULL) || | ||||||
| 			(var->type == ASE_AWK_NDE_NAMEDIDX && var->idx != ASE_NULL), | 			(var->type == ASE_AWK_NDE_NAMEDIDX && var->idx != ASE_NULL), | ||||||
| 			"if a named variable has an index part and " | 			"if a named variable has an index part and a named indexed variable doesn't have an index part, the program is definitely wrong"); | ||||||
| 			"a named indexed variable doesn't have an index " |  | ||||||
| 			"part, the program is definitely wrong"); |  | ||||||
|  |  | ||||||
| 		pair = ase_awk_map_get ( | 		pair = ase_awk_map_get ( | ||||||
| 			&run->named, var->id.name, var->id.name_len); | 			&run->named, var->id.name, var->id.name_len); | ||||||
| @ -2142,9 +2163,7 @@ static int __run_delete (ase_awk_run_t* run, ase_awk_nde_delete_t* nde) | |||||||
| 	{ | 	{ | ||||||
| 		ASE_AWK_ASSERTX (run->awk,  | 		ASE_AWK_ASSERTX (run->awk,  | ||||||
| 			!"should never happen - wrong variable type for delete", | 			!"should never happen - wrong variable type for delete", | ||||||
| 			"the delete statement cannot be called with other " | 			"the delete statement cannot be called with other nodes than the variables such as a named variable, a named indexed variable, etc"); | ||||||
| 			"nodes than the variables such as a named variable, " |  | ||||||
| 			"a named indexed variable, etc"); |  | ||||||
| 		run->errnum = ASE_AWK_EINTERNAL; | 		run->errnum = ASE_AWK_EINTERNAL; | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| @ -2296,23 +2315,12 @@ skip_write: | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int xxx__run_printf (ase_awk_run_t* run, ase_awk_nde_print_t* nde) |  | ||||||
| { |  | ||||||
| ASE_AWK_ASSERTX (run->awk, !"should never happen - not implemented", |  | ||||||
| 	"the runtime function for the printf statement has not been " |  | ||||||
| 	"implemented yet. please do not use printf until it is fully " |  | ||||||
| 	"implemented"); |  | ||||||
|  |  | ||||||
| 	run->errnum = ASE_AWK_EINTERNAL; |  | ||||||
| 	return -1; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int __run_printf (ase_awk_run_t* run, ase_awk_nde_print_t* nde) | static int __run_printf (ase_awk_run_t* run, ase_awk_nde_print_t* nde) | ||||||
| { | { | ||||||
| 	ase_char_t* out = ASE_NULL; | 	ase_char_t* out = ASE_NULL; | ||||||
| 	const ase_char_t* dst; | 	const ase_char_t* dst; | ||||||
| 	ase_awk_val_t* v, * fmt; | 	ase_awk_val_t* v; | ||||||
| 	ase_awk_nde_t* head, * np; | 	ase_awk_nde_t* head; | ||||||
| 	int n; | 	int n; | ||||||
|  |  | ||||||
| 	ASE_AWK_ASSERT (run->awk,  | 	ASE_AWK_ASSERT (run->awk,  | ||||||
| @ -2370,8 +2378,7 @@ static int __run_printf (ase_awk_run_t* run, ase_awk_nde_print_t* nde) | |||||||
| 	dst = (out == ASE_NULL)? ASE_T(""): out; | 	dst = (out == ASE_NULL)? ASE_T(""): out; | ||||||
|  |  | ||||||
| 	ASE_AWK_ASSERTX (run->awk, nde->args != ASE_NULL,  | 	ASE_AWK_ASSERTX (run->awk, nde->args != ASE_NULL,  | ||||||
| 		"a valid printf statement should have at least one argument. " | 		"a valid printf statement should have at least one argument. the parser must ensure this."); | ||||||
| 		"the parser must ensure this."); |  | ||||||
|  |  | ||||||
| 	if (nde->args->type == ASE_AWK_NDE_GRP) | 	if (nde->args->type == ASE_AWK_NDE_GRP) | ||||||
| 	{ | 	{ | ||||||
| @ -2382,8 +2389,7 @@ static int __run_printf (ase_awk_run_t* run, ase_awk_nde_print_t* nde) | |||||||
| 	else head = nde->args; | 	else head = nde->args; | ||||||
|  |  | ||||||
| 	ASE_AWK_ASSERTX (run->awk, head != ASE_NULL, | 	ASE_AWK_ASSERTX (run->awk, head != ASE_NULL, | ||||||
| 		"a valid printf statement should have at least one argument. " | 		"a valid printf statement should have at least one argument. the parser must ensure this."); | ||||||
| 		"the parser must ensure this."); |  | ||||||
|  |  | ||||||
| 	v = __eval_expression (run, head); | 	v = __eval_expression (run, head); | ||||||
| 	if (v == ASE_NULL)  | 	if (v == ASE_NULL)  | ||||||
| @ -2431,392 +2437,17 @@ static int __formatted_output ( | |||||||
| 	ase_awk_run_t* run, int out_type, const ase_char_t* dst,  | 	ase_awk_run_t* run, int out_type, const ase_char_t* dst,  | ||||||
| 	const ase_char_t* fmt, ase_size_t fmt_len, ase_awk_nde_t* args) | 	const ase_char_t* fmt, ase_size_t fmt_len, ase_awk_nde_t* args) | ||||||
| { | { | ||||||
| 	ase_size_t i, j; | 	ase_char_t* ptr; | ||||||
|  | 	ase_size_t len; | ||||||
|  | 	int n; | ||||||
|  |  | ||||||
| #define FLUSH() \ | 	ptr = ase_awk_sprintf (run, fmt, fmt_len, args, &len); | ||||||
| 	do { \ | 	if (ptr == ASE_NULL) return -1; | ||||||
| 		int n = ase_awk_writeextio_str ( \ |  | ||||||
| 			run, out_type, dst, \ |  | ||||||
| 			run->format.out.buf, run->format.out.len); \ |  | ||||||
| 		if (n < 0 && run->errnum != ASE_AWK_EIOHANDLER) return -1; \ |  | ||||||
| 		run->format.out.len = 0; \ |  | ||||||
| 	} while (0) |  | ||||||
|  |  | ||||||
| #define OUTPUT_CHAR(c) \ | 	n = ase_awk_writeextio_str (run, out_type, dst, ptr, len); | ||||||
| 	do { \ | 	if (n < 0 && run->errnum != ASE_AWK_EIOHANDLER) return -1; | ||||||
| 		run->format.out.buf[run->format.out.len++] = (c); \ |  | ||||||
| 		if (run->format.out.len >= \ |  | ||||||
| 		    ase_countof(run->format.out.buf)) FLUSH (); \ |  | ||||||
| 	} while (0) |  | ||||||
|  |  | ||||||
| #define ADD_TO_FMTBUF(c) \ | 	return 0; | ||||||
| 	do { \ |  | ||||||
| 		if (run->format.fmt.len < ase_countof(run->format.fmt.buf)-1) \ |  | ||||||
| 		{ \ |  | ||||||
| 			run->format.fmt.buf[run->format.fmt.len++] = (c); \ |  | ||||||
| 			run->format.fmt.buf[run->format.fmt.len] = ASE_T('\0'); \ |  | ||||||
| 		} \ |  | ||||||
| 		else \ |  | ||||||
| 		{ \ |  | ||||||
| 			run->errnum = ASE_AWK_EFMTSEQ; \ |  | ||||||
| 			return -1; \ |  | ||||||
| 		} \ |  | ||||||
| 	} while (0) |  | ||||||
|  |  | ||||||
| 	run->format.out.len = 0; |  | ||||||
| 	run->format.fmt.len = 0; |  | ||||||
|  |  | ||||||
| 	for (i = 0; i < fmt_len; i++) |  | ||||||
| 	{ |  | ||||||
| 		if (run->format.fmt.len == 0) |  | ||||||
| 		{ |  | ||||||
| 			if (fmt[i] == ASE_T('%'))  |  | ||||||
| 			{ |  | ||||||
| 				run->format.fmt.buf[run->format.fmt.len++] = fmt[i]; |  | ||||||
| 			} |  | ||||||
| 			else OUTPUT_CHAR (fmt[i]); |  | ||||||
| 			continue; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		while (i < fmt_len && |  | ||||||
| 		       (fmt[i] == ASE_T(' ') || fmt[i] == ASE_T('#') || |  | ||||||
| 		        fmt[i] == ASE_T('0') || fmt[i] == ASE_T('+') || |  | ||||||
| 		        fmt[i] == ASE_T('-'))) |  | ||||||
| 		{ |  | ||||||
| 			ADD_TO_FMTBUF (fmt[i]); i++; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (i < fmt_len && fmt[i] == ASE_T('*')) |  | ||||||
| 		{ |  | ||||||
| 			ase_awk_val_t* v; |  | ||||||
| 			ase_long_t l; |  | ||||||
| 			ase_real_t r; |  | ||||||
| 			ase_char_t* p; |  | ||||||
| 			int n; |  | ||||||
|  |  | ||||||
| 			if (args == ASE_NULL) |  | ||||||
| 			{ |  | ||||||
| 				run->errnum = ASE_AWK_EPRINTFARG; |  | ||||||
| 				return -1; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			v = __eval_expression (run, args); |  | ||||||
| 			if (v == ASE_NULL) return -1; |  | ||||||
|  |  | ||||||
| 			ase_awk_refupval (v); |  | ||||||
| 			n = ase_awk_valtonum (run, v, &l, &r); |  | ||||||
| 			ase_awk_refdownval (run, v); |  | ||||||
|  |  | ||||||
| 			if (n == -1) return -1;  |  | ||||||
| 			if (n == 1) l = (ase_long_t)r; |  | ||||||
|  |  | ||||||
| 			run->awk->syscas.sprintf ( |  | ||||||
| 				run->format.buf,  |  | ||||||
| 				ase_countof(run->format.buf), |  | ||||||
| 				ASE_T("%lld"), (long long)l); |  | ||||||
|  |  | ||||||
| 			p = run->format.buf; |  | ||||||
| 			while (*p != ASE_T('\0')) |  | ||||||
| 			{ |  | ||||||
| 				ADD_TO_FMTBUF (*p); |  | ||||||
| 				p++; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			args = args->next; |  | ||||||
| 			i++; |  | ||||||
| 		} |  | ||||||
| 		else |  | ||||||
| 		{ |  | ||||||
| 			while (i < fmt_len && ASE_AWK_ISDIGIT(run->awk, fmt[i])) |  | ||||||
| 			{ |  | ||||||
| 				ADD_TO_FMTBUF (fmt[i]); i++; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (i < fmt_len && fmt[i] == ASE_T('.')) |  | ||||||
| 		{ |  | ||||||
| 			ADD_TO_FMTBUF (fmt[i]); i++; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (i < fmt_len && fmt[i] == ASE_T('*')) |  | ||||||
| 		{ |  | ||||||
| 			ase_awk_val_t* v; |  | ||||||
| 			ase_long_t l; |  | ||||||
| 			ase_real_t r; |  | ||||||
| 			ase_char_t* p; |  | ||||||
| 			int n; |  | ||||||
|  |  | ||||||
| 			if (args == ASE_NULL) |  | ||||||
| 			{ |  | ||||||
| 				run->errnum = ASE_AWK_EPRINTFARG; |  | ||||||
| 				return -1; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			v = __eval_expression (run, args); |  | ||||||
| 			if (v == ASE_NULL) return -1; |  | ||||||
|  |  | ||||||
| 			ase_awk_refupval (v); |  | ||||||
| 			n = ase_awk_valtonum (run, v, &l, &r); |  | ||||||
| 			ase_awk_refdownval (run, v); |  | ||||||
|  |  | ||||||
| 			if (n == -1) return -1;  |  | ||||||
| 			if (n == 1) l = (ase_long_t)r; |  | ||||||
|  |  | ||||||
| 			run->awk->syscas.sprintf ( |  | ||||||
| 				run->format.buf,  |  | ||||||
| 				ase_countof(run->format.buf), |  | ||||||
| 				ASE_T("%lld"), (long long)l); |  | ||||||
|  |  | ||||||
| 			p = run->format.buf; |  | ||||||
| 			while (*p != ASE_T('\0')) |  | ||||||
| 			{ |  | ||||||
| 				ADD_TO_FMTBUF (*p); |  | ||||||
| 				p++; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			args = args->next; |  | ||||||
| 			i++; |  | ||||||
| 		} |  | ||||||
| 		else |  | ||||||
| 		{ |  | ||||||
| 			while (i < fmt_len && ASE_AWK_ISDIGIT(run->awk, fmt[i])) |  | ||||||
| 			{ |  | ||||||
| 				ADD_TO_FMTBUF (fmt[i]); i++; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (i >= fmt_len) break; |  | ||||||
|  |  | ||||||
| 		if (fmt[i] == ASE_T('d') || fmt[i] == ASE_T('i') ||  |  | ||||||
| 		    fmt[i] == ASE_T('x') || fmt[i] == ASE_T('X') || |  | ||||||
| 		    fmt[i] == ASE_T('o')) |  | ||||||
| 		{ |  | ||||||
| 			ase_awk_val_t* v; |  | ||||||
| 			ase_long_t l; |  | ||||||
| 			ase_real_t r; |  | ||||||
| 			ase_char_t* p; |  | ||||||
| 			int n; |  | ||||||
|  |  | ||||||
| 			if (args == ASE_NULL) |  | ||||||
| 			{ |  | ||||||
| 				run->errnum = ASE_AWK_EPRINTFARG; |  | ||||||
| 				return -1; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			ADD_TO_FMTBUF (ASE_T('l')); |  | ||||||
| 			ADD_TO_FMTBUF (ASE_T('l')); |  | ||||||
| 			ADD_TO_FMTBUF (fmt[i]); |  | ||||||
|  |  | ||||||
| 			v = __eval_expression (run, args); |  | ||||||
| 			if (v == ASE_NULL) return -1; |  | ||||||
|  |  | ||||||
| 			ase_awk_refupval (v); |  | ||||||
| 			n = ase_awk_valtonum (run, v, &l, &r); |  | ||||||
| 			ase_awk_refdownval (run, v); |  | ||||||
|  |  | ||||||
| 			if (n == -1) return -1;  |  | ||||||
| 			if (n == 1) l = (ase_long_t)r; |  | ||||||
|  |  | ||||||
| 			/* TODO: check the return value of syscas.sprintf and handle an error */ |  | ||||||
| 			run->awk->syscas.sprintf ( |  | ||||||
| 				run->format.buf,  |  | ||||||
| 				ase_countof(run->format.buf), |  | ||||||
| 				run->format.fmt.buf, (long long)l); |  | ||||||
|  |  | ||||||
| 			p = run->format.buf; |  | ||||||
| 			while (*p != ASE_T('\0')) |  | ||||||
| 			{ |  | ||||||
| 				OUTPUT_CHAR (*p); |  | ||||||
| 				p++; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		else if (fmt[i] == ASE_T('e') || fmt[i] == ASE_T('E') || |  | ||||||
| 		         fmt[i] == ASE_T('g') || fmt[i] == ASE_T('G') || |  | ||||||
| 		         fmt[i] == ASE_T('f')) |  | ||||||
| 		{ |  | ||||||
| 			ase_awk_val_t* v; |  | ||||||
| 			ase_long_t l; |  | ||||||
| 			ase_real_t r; |  | ||||||
| 			ase_char_t* p; |  | ||||||
| 			int n; |  | ||||||
|  |  | ||||||
| 			if (args == ASE_NULL) |  | ||||||
| 			{ |  | ||||||
| 				run->errnum = ASE_AWK_EPRINTFARG; |  | ||||||
| 				return -1; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			ADD_TO_FMTBUF (ASE_T('L')); |  | ||||||
| 			ADD_TO_FMTBUF (fmt[i]); |  | ||||||
|  |  | ||||||
| 			v = __eval_expression (run, args); |  | ||||||
| 			if (v == ASE_NULL) return -1; |  | ||||||
|  |  | ||||||
| 			ase_awk_refupval (v); |  | ||||||
| 			n = ase_awk_valtonum (run, v, &l, &r); |  | ||||||
| 			ase_awk_refdownval (run, v); |  | ||||||
|  |  | ||||||
| 			if (n == -1) return -1;  |  | ||||||
| 			if (n == 0) r = (ase_real_t)l; |  | ||||||
|  |  | ||||||
| 			/* TODO: check the return value of syscas.sprintf and handle an error */ |  | ||||||
| 			run->awk->syscas.sprintf ( |  | ||||||
| 				run->format.buf,  |  | ||||||
| 				ase_countof(run->format.buf), |  | ||||||
| 				run->format.fmt.buf, (long double)r); |  | ||||||
|  |  | ||||||
| 			p = run->format.buf; |  | ||||||
| 			while (*p != ASE_T('\0')) |  | ||||||
| 			{ |  | ||||||
| 				OUTPUT_CHAR (*p); |  | ||||||
| 				p++; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		else if (fmt[i] == ASE_T('c'))  |  | ||||||
| 		{ |  | ||||||
| 			ase_awk_val_t* v; |  | ||||||
| 			ase_char_t* p; |  | ||||||
|  |  | ||||||
| 			if (args == ASE_NULL) |  | ||||||
| 			{ |  | ||||||
| 				run->errnum = ASE_AWK_EPRINTFARG; |  | ||||||
| 				return -1; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			ADD_TO_FMTBUF (fmt[i]); |  | ||||||
|  |  | ||||||
| 			v = __eval_expression (run, args); |  | ||||||
| 			if (v == ASE_NULL) return -1; |  | ||||||
|  |  | ||||||
| 			ase_awk_refupval (v); |  | ||||||
| 			if (v->type == ASE_AWK_VAL_NIL) |  | ||||||
| 			{ |  | ||||||
| 				run->format.buf[0] = ASE_T('\0'); |  | ||||||
| 			} |  | ||||||
| 			else if (v->type == ASE_AWK_VAL_INT) |  | ||||||
| 			{ |  | ||||||
| 				run->awk->syscas.sprintf ( |  | ||||||
| 					run->format.buf,  |  | ||||||
| 					ase_countof(run->format.buf), |  | ||||||
| 					run->format.fmt.buf,  |  | ||||||
| 					(int)((ase_awk_val_int_t*)v)->val); |  | ||||||
| 			} |  | ||||||
| 			else if (v->type == ASE_AWK_VAL_REAL) |  | ||||||
| 			{ |  | ||||||
| 				run->awk->syscas.sprintf ( |  | ||||||
| 					run->format.buf,  |  | ||||||
| 					ase_countof(run->format.buf), |  | ||||||
| 					run->format.fmt.buf,  |  | ||||||
| 					(int)((ase_awk_val_real_t*)v)->val); |  | ||||||
| 			} |  | ||||||
| 			else if (v->type == ASE_AWK_VAL_STR) |  | ||||||
| 			{ |  | ||||||
| 				ase_awk_val_str_t* str = (ase_awk_val_str_t*)v; |  | ||||||
|  |  | ||||||
| 				if (str->len > 0) |  | ||||||
| 				{ |  | ||||||
| 					run->awk->syscas.sprintf ( |  | ||||||
| 						run->format.buf,  |  | ||||||
| 						ase_countof(run->format.buf), |  | ||||||
| 						run->format.fmt.buf, str->buf[0]); |  | ||||||
| 				} |  | ||||||
| 				else run->format.buf[0] = ASE_T('\0'); |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				ase_awk_refdownval (run, v); |  | ||||||
| 				run->errnum = ASE_AWK_EVALTYPE; |  | ||||||
| 				return -1; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			ase_awk_refdownval (run, v); |  | ||||||
|  |  | ||||||
| 			p = run->format.buf; |  | ||||||
| 			while (*p != ASE_T('\0')) |  | ||||||
| 			{ |  | ||||||
| 				OUTPUT_CHAR (*p); |  | ||||||
| 				p++; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		else if (fmt[i] == ASE_T('s'))  |  | ||||||
| 		{ |  | ||||||
| 			ase_awk_val_t* v; |  | ||||||
| 			ase_char_t* p; |  | ||||||
|  |  | ||||||
| 			if (args == ASE_NULL) |  | ||||||
| 			{ |  | ||||||
| 				run->errnum = ASE_AWK_EPRINTFARG; |  | ||||||
| 				return -1; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			ADD_TO_FMTBUF (fmt[i]); |  | ||||||
|  |  | ||||||
| 			v = __eval_expression (run, args); |  | ||||||
| 			if (v == ASE_NULL) return -1; |  | ||||||
|  |  | ||||||
| 			ase_awk_refupval (v); |  | ||||||
| 			if (v->type == ASE_AWK_VAL_NIL) |  | ||||||
| 			{ |  | ||||||
| 				run->format.buf[0] = ASE_T('\0'); |  | ||||||
| 			} |  | ||||||
| 			else if (v->type == ASE_AWK_VAL_STR) |  | ||||||
| 			{ |  | ||||||
| 				/* TODO: handle a string contailing null characters */ |  | ||||||
| 				/* TODO: handle error conditions of sprintf */ |  | ||||||
|  |  | ||||||
| 				run->awk->syscas.sprintf ( |  | ||||||
| 					run->format.buf,  |  | ||||||
| 					ase_countof(run->format.buf), |  | ||||||
| 					run->format.fmt.buf,  |  | ||||||
| 					((ase_awk_val_str_t*)v)->buf); |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				ase_char_t* str; |  | ||||||
| 				ase_size_t len; |  | ||||||
|  |  | ||||||
| 				str = ase_awk_valtostr (run, v, ASE_AWK_VALTOSTR_CLEAR, ASE_NULL, &len); |  | ||||||
| 				if (str == ASE_NULL) |  | ||||||
| 				{ |  | ||||||
| 					ase_awk_refdownval (run, v); |  | ||||||
| 					return -1; |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				run->awk->syscas.sprintf ( |  | ||||||
| 					run->format.buf,  |  | ||||||
| 					ase_countof(run->format.buf), |  | ||||||
| 					run->format.fmt.buf, str); |  | ||||||
|  |  | ||||||
| 				ASE_AWK_FREE (run->awk, str); |  | ||||||
| 			} |  | ||||||
| 			 |  | ||||||
| 			ase_awk_refdownval (run, v); |  | ||||||
|  |  | ||||||
| 			p = run->format.buf; |  | ||||||
| 			while (*p != ASE_T('\0')) |  | ||||||
| 			{ |  | ||||||
| 				OUTPUT_CHAR (*p); |  | ||||||
| 				p++; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		else /*if (fmt[i] == ASE_T('%'))*/ |  | ||||||
| 		{ |  | ||||||
| 			for (j = 0; j < run->format.fmt.len; j++) |  | ||||||
| 				OUTPUT_CHAR (run->format.fmt.buf[j]); |  | ||||||
| 			OUTPUT_CHAR (fmt[i]); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		args = args->next; |  | ||||||
| 		run->format.fmt.len = 0; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (run->format.fmt.len > 0) |  | ||||||
| 	{ |  | ||||||
| 		/* flush uncompleted formatting sequence */ |  | ||||||
| 		for (j = 0; j < run->format.fmt.len; j++) |  | ||||||
| 			OUTPUT_CHAR (run->format.fmt.buf[j]); |  | ||||||
| 	} |  | ||||||
| 	FLUSH (); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static ase_awk_val_t* __eval_expression (ase_awk_run_t* run, ase_awk_nde_t* nde) | static ase_awk_val_t* __eval_expression (ase_awk_run_t* run, ase_awk_nde_t* nde) | ||||||
| @ -2842,9 +2473,7 @@ static ase_awk_val_t* __eval_expression (ase_awk_run_t* run, ase_awk_nde_t* nde) | |||||||
| 		{ | 		{ | ||||||
| 			ASE_AWK_ASSERTX (run->awk,  | 			ASE_AWK_ASSERTX (run->awk,  | ||||||
| 				run->inrec.d0->type == ASE_AWK_VAL_STR, | 				run->inrec.d0->type == ASE_AWK_VAL_STR, | ||||||
| 				"the internal value representing $0 should " | 				"the internal value representing $0 should always be of the string type once it has been set/updated. it is nil initially."); | ||||||
| 				"always be of the string type once it has been " |  | ||||||
| 				"set/updated. it is nil initially."); |  | ||||||
|  |  | ||||||
| 			n = ase_awk_matchrex ( | 			n = ase_awk_matchrex ( | ||||||
| 				((ase_awk_run_t*)run)->awk,  | 				((ase_awk_run_t*)run)->awk,  | ||||||
| @ -4090,8 +3719,7 @@ static ase_awk_val_t* __eval_binop_exp ( | |||||||
| 	ase_awk_val_t* res; | 	ase_awk_val_t* res; | ||||||
|  |  | ||||||
| 	ASE_AWK_ASSERTX (run->awk, run->awk->syscas.pow != ASE_NULL, | 	ASE_AWK_ASSERTX (run->awk, run->awk->syscas.pow != ASE_NULL, | ||||||
| 		"the pow function should be provided when the awk object " | 		"the pow function should be provided when the awk object is created to make the exponentiation work properly."); | ||||||
| 		"is created to make the exponentiation work properly."); |  | ||||||
|  |  | ||||||
| 	n1 = ase_awk_valtonum (run, left, &l1, &r1); | 	n1 = ase_awk_valtonum (run, left, &l1, &r1); | ||||||
| 	n2 = ase_awk_valtonum (run, right, &l2, &r2); | 	n2 = ase_awk_valtonum (run, right, &l2, &r2); | ||||||
| @ -5873,3 +5501,391 @@ static ase_char_t* __idxnde_to_str ( | |||||||
|  |  | ||||||
| 	return str; | 	return 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_size_t i, j; | ||||||
|  |  | ||||||
|  | #define OUT_CHAR(c) \ | ||||||
|  | 	do { \ | ||||||
|  | 		if (ase_awk_str_ccat (&run->sprintf.out, (c)) == -1) \ | ||||||
|  | 		{ \ | ||||||
|  | 			run->errnum = ASE_AWK_ENOMEM; \ | ||||||
|  | 			return ASE_NULL; \ | ||||||
|  | 		} \ | ||||||
|  | 	} while (0) | ||||||
|  |  | ||||||
|  | #define FMT_CHAR(c) \ | ||||||
|  | 	do { \ | ||||||
|  | 		if (ase_awk_str_ccat (&run->sprintf.fmt, (c)) == -1) \ | ||||||
|  | 		{ \ | ||||||
|  | 			run->errnum = ASE_AWK_ENOMEM; \ | ||||||
|  | 			return ASE_NULL; \ | ||||||
|  | 		} \ | ||||||
|  | 	} while (0) | ||||||
|  |  | ||||||
|  | 	ase_awk_str_clear (&run->sprintf.out); | ||||||
|  | 	ase_awk_str_clear (&run->sprintf.fmt); | ||||||
|  |  | ||||||
|  | 	for (i = 0; i < fmt_len; i++) | ||||||
|  | 	{ | ||||||
|  | 		if (ASE_AWK_STR_LEN(&run->sprintf.fmt) == 0) | ||||||
|  | 		{ | ||||||
|  | 			if (fmt[i] == ASE_T('%')) FMT_CHAR (fmt[i]); | ||||||
|  | 			else OUT_CHAR (fmt[i]); | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		while (i < fmt_len && | ||||||
|  | 		       (fmt[i] == ASE_T(' ') || fmt[i] == ASE_T('#') || | ||||||
|  | 		        fmt[i] == ASE_T('0') || fmt[i] == ASE_T('+') || | ||||||
|  | 		        fmt[i] == ASE_T('-'))) | ||||||
|  | 		{ | ||||||
|  | 			FMT_CHAR (fmt[i]); i++; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (i < fmt_len && fmt[i] == ASE_T('*')) | ||||||
|  | 		{ | ||||||
|  | 			ase_awk_val_t* v; | ||||||
|  | 			ase_long_t l; | ||||||
|  | 			ase_real_t r; | ||||||
|  | 			ase_char_t* p; | ||||||
|  | 			int n; | ||||||
|  |  | ||||||
|  | 			if (args == ASE_NULL) | ||||||
|  | 			{ | ||||||
|  | 				run->errnum = ASE_AWK_EPRINTFARG; | ||||||
|  | 				return ASE_NULL; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			v = __eval_expression (run, args); | ||||||
|  | 			if (v == ASE_NULL) return ASE_NULL; | ||||||
|  |  | ||||||
|  | 			ase_awk_refupval (v); | ||||||
|  | 			n = ase_awk_valtonum (run, v, &l, &r); | ||||||
|  | 			ase_awk_refdownval (run, v); | ||||||
|  |  | ||||||
|  | 			if (n == -1) return ASE_NULL;  | ||||||
|  | 			if (n == 1) l = (ase_long_t)r; | ||||||
|  |  | ||||||
|  | 			run->awk->syscas.sprintf ( | ||||||
|  | 				run->sprintf.tmp,  | ||||||
|  | 				ase_countof(run->sprintf.tmp), | ||||||
|  | 			#ifdef _WIN32 | ||||||
|  | 				ASE_T("%I64d"), (__int64)l); | ||||||
|  | 			#else | ||||||
|  | 				ASE_T("%lld"), (long long)l); | ||||||
|  | 			#endif | ||||||
|  |  | ||||||
|  | 			p = run->sprintf.tmp; | ||||||
|  | 			while (*p != ASE_T('\0')) | ||||||
|  | 			{ | ||||||
|  | 				FMT_CHAR (*p); | ||||||
|  | 				p++; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			args = args->next; | ||||||
|  | 			i++; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			while (i < fmt_len && ASE_AWK_ISDIGIT(run->awk, fmt[i])) | ||||||
|  | 			{ | ||||||
|  | 				FMT_CHAR (fmt[i]); i++; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (i < fmt_len && fmt[i] == ASE_T('.')) | ||||||
|  | 		{ | ||||||
|  | 			FMT_CHAR (fmt[i]); i++; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (i < fmt_len && fmt[i] == ASE_T('*')) | ||||||
|  | 		{ | ||||||
|  | 			ase_awk_val_t* v; | ||||||
|  | 			ase_long_t l; | ||||||
|  | 			ase_real_t r; | ||||||
|  | 			ase_char_t* p; | ||||||
|  | 			int n; | ||||||
|  |  | ||||||
|  | 			if (args == ASE_NULL) | ||||||
|  | 			{ | ||||||
|  | 				run->errnum = ASE_AWK_EPRINTFARG; | ||||||
|  | 				return ASE_NULL; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			v = __eval_expression (run, args); | ||||||
|  | 			if (v == ASE_NULL) return ASE_NULL; | ||||||
|  |  | ||||||
|  | 			ase_awk_refupval (v); | ||||||
|  | 			n = ase_awk_valtonum (run, v, &l, &r); | ||||||
|  | 			ase_awk_refdownval (run, v); | ||||||
|  |  | ||||||
|  | 			if (n == -1) return ASE_NULL;  | ||||||
|  | 			if (n == 1) l = (ase_long_t)r; | ||||||
|  |  | ||||||
|  | 			run->awk->syscas.sprintf ( | ||||||
|  | 				run->sprintf.tmp,  | ||||||
|  | 				ase_countof(run->sprintf.tmp), | ||||||
|  | 			#ifdef _WIN32 | ||||||
|  | 				ASE_T("%I64d"), (__int64)l); | ||||||
|  | 			#else | ||||||
|  | 				ASE_T("%lld"), (long long)l); | ||||||
|  | 			#endif | ||||||
|  |  | ||||||
|  | 			p = run->sprintf.tmp; | ||||||
|  | 			while (*p != ASE_T('\0')) | ||||||
|  | 			{ | ||||||
|  | 				FMT_CHAR (*p); | ||||||
|  | 				p++; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			args = args->next; | ||||||
|  | 			i++; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			while (i < fmt_len && ASE_AWK_ISDIGIT(run->awk, fmt[i])) | ||||||
|  | 			{ | ||||||
|  | 				FMT_CHAR (fmt[i]); i++; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (i >= fmt_len) break; | ||||||
|  |  | ||||||
|  | 		if (fmt[i] == ASE_T('d') || fmt[i] == ASE_T('i') ||  | ||||||
|  | 		    fmt[i] == ASE_T('x') || fmt[i] == ASE_T('X') || | ||||||
|  | 		    fmt[i] == ASE_T('o')) | ||||||
|  | 		{ | ||||||
|  | 			ase_awk_val_t* v; | ||||||
|  | 			ase_long_t l; | ||||||
|  | 			ase_real_t r; | ||||||
|  | 			ase_char_t* p; | ||||||
|  | 			int n; | ||||||
|  |  | ||||||
|  | 			if (args == ASE_NULL) | ||||||
|  | 			{ | ||||||
|  | 				run->errnum = ASE_AWK_EPRINTFARG; | ||||||
|  | 				return ASE_NULL; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			FMT_CHAR (ASE_T('l')); | ||||||
|  | 			FMT_CHAR (ASE_T('l')); | ||||||
|  | 			FMT_CHAR (fmt[i]); | ||||||
|  |  | ||||||
|  | 			v = __eval_expression (run, args); | ||||||
|  | 			if (v == ASE_NULL) return ASE_NULL; | ||||||
|  |  | ||||||
|  | 			ase_awk_refupval (v); | ||||||
|  | 			n = ase_awk_valtonum (run, v, &l, &r); | ||||||
|  | 			ase_awk_refdownval (run, v); | ||||||
|  |  | ||||||
|  | 			if (n == -1) return ASE_NULL;  | ||||||
|  | 			if (n == 1) l = (ase_long_t)r; | ||||||
|  |  | ||||||
|  | 			/* TODO: check the return value of syscas.sprintf and handle an error */ | ||||||
|  | 			run->awk->syscas.sprintf ( | ||||||
|  | 				run->sprintf.tmp,  | ||||||
|  | 				ase_countof(run->sprintf.tmp), | ||||||
|  | 			#ifdef _WIN32 | ||||||
|  | 				run->sprintf.fmt.buf, (__int64)l); | ||||||
|  | 			#else | ||||||
|  | 				run->sprintf.fmt.buf, (long long)l); | ||||||
|  | 			#endif | ||||||
|  |  | ||||||
|  | 			p = run->sprintf.tmp; | ||||||
|  | 			while (*p != ASE_T('\0')) | ||||||
|  | 			{ | ||||||
|  | 				OUT_CHAR (*p); | ||||||
|  | 				p++; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else if (fmt[i] == ASE_T('e') || fmt[i] == ASE_T('E') || | ||||||
|  | 		         fmt[i] == ASE_T('g') || fmt[i] == ASE_T('G') || | ||||||
|  | 		         fmt[i] == ASE_T('f')) | ||||||
|  | 		{ | ||||||
|  | 			ase_awk_val_t* v; | ||||||
|  | 			ase_long_t l; | ||||||
|  | 			ase_real_t r; | ||||||
|  | 			ase_char_t* p; | ||||||
|  | 			int n; | ||||||
|  |  | ||||||
|  | 			if (args == ASE_NULL) | ||||||
|  | 			{ | ||||||
|  | 				run->errnum = ASE_AWK_EPRINTFARG; | ||||||
|  | 				return ASE_NULL; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			FMT_CHAR (ASE_T('L')); | ||||||
|  | 			FMT_CHAR (fmt[i]); | ||||||
|  |  | ||||||
|  | 			v = __eval_expression (run, args); | ||||||
|  | 			if (v == ASE_NULL) return ASE_NULL; | ||||||
|  |  | ||||||
|  | 			ase_awk_refupval (v); | ||||||
|  | 			n = ase_awk_valtonum (run, v, &l, &r); | ||||||
|  | 			ase_awk_refdownval (run, v); | ||||||
|  |  | ||||||
|  | 			if (n == -1) return ASE_NULL; | ||||||
|  | 			if (n == 0) r = (ase_real_t)l; | ||||||
|  |  | ||||||
|  | 			/* TODO: check the return value of syscas.sprintf and handle an error */ | ||||||
|  | 			run->awk->syscas.sprintf ( | ||||||
|  | 				run->sprintf.tmp,  | ||||||
|  | 				ase_countof(run->sprintf.tmp), | ||||||
|  | 				run->sprintf.fmt.buf, (long double)r); | ||||||
|  |  | ||||||
|  | 			p = run->sprintf.tmp; | ||||||
|  | 			while (*p != ASE_T('\0')) | ||||||
|  | 			{ | ||||||
|  | 				OUT_CHAR (*p); | ||||||
|  | 				p++; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else if (fmt[i] == ASE_T('c'))  | ||||||
|  | 		{ | ||||||
|  | 			ase_awk_val_t* v; | ||||||
|  | 			ase_char_t* p; | ||||||
|  |  | ||||||
|  | 			if (args == ASE_NULL) | ||||||
|  | 			{ | ||||||
|  | 				run->errnum = ASE_AWK_EPRINTFARG; | ||||||
|  | 				return ASE_NULL; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			FMT_CHAR (fmt[i]); | ||||||
|  |  | ||||||
|  | 			v = __eval_expression (run, args); | ||||||
|  | 			if (v == ASE_NULL) return ASE_NULL; | ||||||
|  |  | ||||||
|  | 			ase_awk_refupval (v); | ||||||
|  | 			if (v->type == ASE_AWK_VAL_NIL) | ||||||
|  | 			{ | ||||||
|  | 				run->sprintf.tmp[0] = ASE_T('\0'); | ||||||
|  | 			} | ||||||
|  | 			else if (v->type == ASE_AWK_VAL_INT) | ||||||
|  | 			{ | ||||||
|  | 				run->awk->syscas.sprintf ( | ||||||
|  | 					run->sprintf.tmp,  | ||||||
|  | 					ase_countof(run->sprintf.tmp), | ||||||
|  | 					run->sprintf.fmt.buf,  | ||||||
|  | 					(int)((ase_awk_val_int_t*)v)->val); | ||||||
|  | 			} | ||||||
|  | 			else if (v->type == ASE_AWK_VAL_REAL) | ||||||
|  | 			{ | ||||||
|  | 				run->awk->syscas.sprintf ( | ||||||
|  | 					run->sprintf.tmp,  | ||||||
|  | 					ase_countof(run->sprintf.tmp), | ||||||
|  | 					run->sprintf.fmt.buf,  | ||||||
|  | 					(int)((ase_awk_val_real_t*)v)->val); | ||||||
|  | 			} | ||||||
|  | 			else if (v->type == ASE_AWK_VAL_STR) | ||||||
|  | 			{ | ||||||
|  | 				ase_awk_val_str_t* str = (ase_awk_val_str_t*)v; | ||||||
|  |  | ||||||
|  | 				if (str->len > 0) | ||||||
|  | 				{ | ||||||
|  | 					run->awk->syscas.sprintf ( | ||||||
|  | 						run->sprintf.tmp,  | ||||||
|  | 						ase_countof(run->sprintf.tmp), | ||||||
|  | 						run->sprintf.fmt.buf, str->buf[0]); | ||||||
|  | 				} | ||||||
|  | 				else run->sprintf.tmp[0] = ASE_T('\0'); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				ase_awk_refdownval (run, v); | ||||||
|  | 				run->errnum = ASE_AWK_EVALTYPE; | ||||||
|  | 				return ASE_NULL; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			ase_awk_refdownval (run, v); | ||||||
|  |  | ||||||
|  | 			p = run->sprintf.tmp; | ||||||
|  | 			while (*p != ASE_T('\0')) | ||||||
|  | 			{ | ||||||
|  | 				OUT_CHAR (*p); | ||||||
|  | 				p++; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else if (fmt[i] == ASE_T('s'))  | ||||||
|  | 		{ | ||||||
|  | 			ase_awk_val_t* v; | ||||||
|  | 			ase_char_t* p; | ||||||
|  |  | ||||||
|  | 			if (args == ASE_NULL) | ||||||
|  | 			{ | ||||||
|  | 				run->errnum = ASE_AWK_EPRINTFARG; | ||||||
|  | 				return ASE_NULL; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			FMT_CHAR (fmt[i]); | ||||||
|  |  | ||||||
|  | 			v = __eval_expression (run, args); | ||||||
|  | 			if (v == ASE_NULL) return ASE_NULL; | ||||||
|  |  | ||||||
|  | 			ase_awk_refupval (v); | ||||||
|  | 			if (v->type == ASE_AWK_VAL_NIL) | ||||||
|  | 			{ | ||||||
|  | 				run->sprintf.tmp[0] = ASE_T('\0'); | ||||||
|  | 			} | ||||||
|  | 			else if (v->type == ASE_AWK_VAL_STR) | ||||||
|  | 			{ | ||||||
|  | 				/* TODO: handle a string contailing null characters */ | ||||||
|  | 				/* TODO: handle error conditions of sprintf */ | ||||||
|  |  | ||||||
|  | 				run->awk->syscas.sprintf ( | ||||||
|  | 					run->sprintf.tmp,  | ||||||
|  | 					ase_countof(run->sprintf.tmp), | ||||||
|  | 					run->sprintf.fmt.buf,  | ||||||
|  | 					((ase_awk_val_str_t*)v)->buf); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				ase_size_t l; | ||||||
|  |  | ||||||
|  | 				p = ase_awk_valtostr (run, v,  | ||||||
|  | 					ASE_AWK_VALTOSTR_CLEAR, ASE_NULL, &l); | ||||||
|  | 				if (p == ASE_NULL) | ||||||
|  | 				{ | ||||||
|  | 					ase_awk_refdownval (run, v); | ||||||
|  | 					return ASE_NULL; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				run->awk->syscas.sprintf ( | ||||||
|  | 					run->sprintf.tmp,  | ||||||
|  | 					ase_countof(run->sprintf.tmp), | ||||||
|  | 					run->sprintf.fmt.buf, p); | ||||||
|  |  | ||||||
|  | 				ASE_AWK_FREE (run->awk, p); | ||||||
|  | 			} | ||||||
|  | 			 | ||||||
|  | 			ase_awk_refdownval (run, v); | ||||||
|  |  | ||||||
|  | 			p = run->sprintf.tmp; | ||||||
|  | 			while (*p != ASE_T('\0')) | ||||||
|  | 			{ | ||||||
|  | 				OUT_CHAR (*p); | ||||||
|  | 				p++; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else /*if (fmt[i] == ASE_T('%'))*/ | ||||||
|  | 		{ | ||||||
|  | 			for (j = 0; j < ASE_AWK_STR_LEN(&run->sprintf.fmt); j++) | ||||||
|  | 				OUT_CHAR (ASE_AWK_STR_CHAR(&run->sprintf.fmt,j)); | ||||||
|  | 			OUT_CHAR (fmt[i]); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		args = args->next; | ||||||
|  | 		ase_awk_str_clear (&run->sprintf.fmt); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* flush uncompleted formatting sequence */ | ||||||
|  | 	for (j = 0; j < ASE_AWK_STR_LEN(&run->sprintf.fmt); j++) | ||||||
|  | 		OUT_CHAR (ASE_AWK_STR_CHAR(&run->sprintf.fmt,j)); | ||||||
|  |  | ||||||
|  | 	*len = ASE_AWK_STR_LEN(&run->sprintf.out); | ||||||
|  | 	return ASE_AWK_STR_BUF(&run->sprintf.out);  | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * $Id: run.h,v 1.21 2006-10-24 04:10:12 bacon Exp $ |  * $Id: run.h,v 1.22 2006-11-13 15:08:54 bacon Exp $ | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #ifndef _ASE_AWK_RUN_H_ | #ifndef _ASE_AWK_RUN_H_ | ||||||
| @ -100,4 +100,16 @@ enum | |||||||
| 	ASE_AWK_GLOBAL_SUBSEP | 	ASE_AWK_GLOBAL_SUBSEP | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | 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); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * $Id: val.c,v 1.80 2006-10-30 14:31:37 bacon Exp $ |  * $Id: val.c,v 1.81 2006-11-13 15:08:54 bacon Exp $ | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <ase/awk/awk_i.h> | #include <ase/awk/awk_i.h> | ||||||
| @ -300,8 +300,7 @@ xp_printf (ASE_T("\n"));*/ | |||||||
| 	{ | 	{ | ||||||
| 		ASE_AWK_ASSERTX (run->awk,  | 		ASE_AWK_ASSERTX (run->awk,  | ||||||
| 			!"should never happen - invalid value type", | 			!"should never happen - invalid value type", | ||||||
| 			"the type of a value should be one of ASE_AWK_VAL_XXX's" | 			"the type of a value should be one of ASE_AWK_VAL_XXX's defined in val.h"); | ||||||
| 			"defined in val.h"); |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -328,8 +327,7 @@ xp_printf (ASE_T("\n")); | |||||||
| */ | */ | ||||||
|  |  | ||||||
| 	ASE_AWK_ASSERTX (run->awk, val->ref > 0,  | 	ASE_AWK_ASSERTX (run->awk, val->ref > 0,  | ||||||
| 		"the reference count of a value should be greater than zero" | 		"the reference count of a value should be greater than zero for it to be decremented. check the source code for any bugs"); | ||||||
| 		"for it to be decremented. check the source code for any bugs"); |  | ||||||
|  |  | ||||||
| 	val->ref--; | 	val->ref--; | ||||||
| 	if (val->ref <= 0)  | 	if (val->ref <= 0)  | ||||||
| @ -348,8 +346,7 @@ void ase_awk_refdownval_nofree (ase_awk_run_t* run, ase_awk_val_t* val) | |||||||
| 	if (ase_awk_isbuiltinval(val)) return; | 	if (ase_awk_isbuiltinval(val)) return; | ||||||
|  |  | ||||||
| 	ASE_AWK_ASSERTX (run->awk, val->ref > 0, | 	ASE_AWK_ASSERTX (run->awk, val->ref > 0, | ||||||
| 		"the reference count of a value should be greater than zero" | 		"the reference count of a value should be greater than zero for it to be decremented. check the source code for any bugs"); | ||||||
| 		"for it to be decremented. check the source code for any bugs"); |  | ||||||
| 	val->ref--; | 	val->ref--; | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -377,8 +374,7 @@ ase_bool_t ase_awk_valtobool (ase_awk_run_t* run, ase_awk_val_t* val) | |||||||
|  |  | ||||||
| 	ASE_AWK_ASSERTX (run->awk,  | 	ASE_AWK_ASSERTX (run->awk,  | ||||||
| 		!"should never happen - invalid value type", | 		!"should never happen - invalid value type", | ||||||
| 		"the type of a value should be one of ASE_AWK_VAL_XXX's" | 		"the type of a value should be one of ASE_AWK_VAL_XXX's defined in val.h"); | ||||||
| 		"defined in val.h"); |  | ||||||
| 	return ase_false; | 	return ase_false; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user