qse/ase/awk/val.c

821 lines
19 KiB
C
Raw Normal View History

2006-03-04 15:54:37 +00:00
/*
2006-12-16 16:14:40 +00:00
* $Id: val.c,v 1.100 2006-12-16 16:14:40 bacon Exp $
2006-03-04 15:54:37 +00:00
*/
2006-10-24 04:10:12 +00:00
#include <ase/awk/awk_i.h>
2006-03-04 15:54:37 +00:00
2006-10-24 04:10:12 +00:00
static ase_char_t* __str_to_str (
ase_awk_run_t* run, const ase_char_t* str, ase_size_t str_len,
int opt, ase_awk_str_t* buf, ase_size_t* len);
static ase_char_t* __val_int_to_str (
ase_awk_run_t* run, ase_awk_val_int_t* v,
int opt, ase_awk_str_t* buf, ase_size_t* len);
static ase_char_t* __val_real_to_str (
ase_awk_run_t* run, ase_awk_val_real_t* v,
int opt, ase_awk_str_t* buf, ase_size_t* len);
2006-09-27 14:14:47 +00:00
2006-10-24 04:10:12 +00:00
static ase_awk_val_nil_t __awk_nil = { ASE_AWK_VAL_NIL, 0 };
static ase_awk_val_str_t __awk_zls = { ASE_AWK_VAL_STR, 0, ASE_T(""), 0 };
2006-11-23 14:27:52 +00:00
/* TODO: consider different line ending schemes */
static ase_awk_val_str_t __awk_nl = { ASE_AWK_VAL_STR, 0, ASE_T("\n"), 1 };
ase_awk_val_t* ase_awk_val_nil = (ase_awk_val_t*)&__awk_nil;
2006-10-24 04:10:12 +00:00
ase_awk_val_t* ase_awk_val_zls = (ase_awk_val_t*)&__awk_zls;
2006-11-23 14:27:52 +00:00
ase_awk_val_t* ase_awk_val_nl = (ase_awk_val_t*)&__awk_nl;
2006-07-10 04:51:38 +00:00
2006-10-24 04:10:12 +00:00
static ase_awk_val_int_t __awk_int[] =
2006-03-22 16:05:50 +00:00
{
2006-11-22 06:05:45 +00:00
{ ASE_AWK_VAL_INT, 0, -1, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 0, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 1, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 2, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 3, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 4, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 5, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 6, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 7, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 8, ASE_NULL },
2006-12-16 16:14:40 +00:00
{ ASE_AWK_VAL_INT, 0, 9, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 10, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 11, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 12, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 13, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 14, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 15, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 16, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 17, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 18, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 19, ASE_NULL },
{ ASE_AWK_VAL_INT, 0, 20, ASE_NULL }
2006-03-22 16:05:50 +00:00
};
2006-12-16 14:48:31 +00:00
ase_awk_val_t* ase_awk_val_negone = (ase_awk_val_t*)&__awk_int[0];
2006-10-24 04:10:12 +00:00
ase_awk_val_t* ase_awk_val_zero = (ase_awk_val_t*)&__awk_int[1];
ase_awk_val_t* ase_awk_val_one = (ase_awk_val_t*)&__awk_int[2];
2006-07-12 07:25:15 +00:00
2006-10-24 04:10:12 +00:00
ase_awk_val_t* ase_awk_makeintval (ase_awk_run_t* run, ase_long_t v)
2006-03-04 15:54:37 +00:00
{
2006-10-24 04:10:12 +00:00
ase_awk_val_int_t* val;
2006-03-04 15:54:37 +00:00
2006-03-22 16:05:50 +00:00
if (v >= __awk_int[0].val &&
2006-11-29 02:39:10 +00:00
v <= __awk_int[ASE_COUNTOF(__awk_int)-1].val)
2006-03-22 16:05:50 +00:00
{
2006-10-24 04:10:12 +00:00
return (ase_awk_val_t*)&__awk_int[v-__awk_int[0].val];
2006-03-22 16:05:50 +00:00
}
2006-04-21 17:24:31 +00:00
if (run->icache_count > 0)
2006-03-27 11:43:17 +00:00
{
2006-04-21 17:24:31 +00:00
val = run->icache[--run->icache_count];
2006-03-27 11:43:17 +00:00
}
else
{
2006-10-24 04:10:12 +00:00
val = (ase_awk_val_int_t*) ASE_AWK_MALLOC (
2006-11-29 02:39:10 +00:00
run->awk, ASE_SIZEOF(ase_awk_val_int_t));
2006-10-24 04:10:12 +00:00
if (val == ASE_NULL) return ASE_NULL;
2006-03-27 11:43:17 +00:00
}
2006-03-04 15:54:37 +00:00
2006-10-24 04:10:12 +00:00
val->type = ASE_AWK_VAL_INT;
2006-03-26 16:36:30 +00:00
val->ref = 0;
2006-03-04 15:54:37 +00:00
val->val = v;
2006-10-24 04:10:12 +00:00
val->nde = ASE_NULL;
2006-03-05 17:07:33 +00:00
2006-10-24 04:10:12 +00:00
/*xp_printf (ASE_T("makeintval => %p\n"), val);*/
return (ase_awk_val_t*)val;
2006-03-05 17:07:33 +00:00
}
2006-10-24 04:10:12 +00:00
ase_awk_val_t* ase_awk_makerealval (ase_awk_run_t* run, ase_real_t v)
2006-03-05 17:07:33 +00:00
{
2006-10-24 04:10:12 +00:00
ase_awk_val_real_t* val;
2006-03-05 17:07:33 +00:00
2006-04-21 17:24:31 +00:00
if (run->rcache_count > 0)
2006-03-28 16:33:09 +00:00
{
2006-04-21 17:24:31 +00:00
val = run->rcache[--run->rcache_count];
2006-03-28 16:33:09 +00:00
}
else
{
2006-10-24 04:10:12 +00:00
val = (ase_awk_val_real_t*) ASE_AWK_MALLOC (
2006-11-29 02:39:10 +00:00
run->awk, ASE_SIZEOF(ase_awk_val_real_t));
2006-10-24 04:10:12 +00:00
if (val == ASE_NULL) return ASE_NULL;
2006-03-28 16:33:09 +00:00
}
2006-03-05 17:07:33 +00:00
2006-10-24 04:10:12 +00:00
val->type = ASE_AWK_VAL_REAL;
2006-03-26 16:36:30 +00:00
val->ref = 0;
2006-03-05 17:07:33 +00:00
val->val = v;
2006-10-24 04:10:12 +00:00
val->nde = ASE_NULL;
2006-03-05 17:07:33 +00:00
2006-10-24 04:10:12 +00:00
/*xp_printf (ASE_T("makerealval => %p\n"), val);*/
return (ase_awk_val_t*)val;
2006-03-05 17:07:33 +00:00
}
2006-10-24 04:10:12 +00:00
ase_awk_val_t* ase_awk_makestrval0 (ase_awk_run_t* run, const ase_char_t* str)
2006-06-26 15:09:28 +00:00
{
2006-10-24 04:10:12 +00:00
return ase_awk_makestrval (run, str, ase_awk_strlen(str));
2006-06-26 15:09:28 +00:00
}
2006-10-24 04:10:12 +00:00
ase_awk_val_t* ase_awk_makestrval (
ase_awk_run_t* run, const ase_char_t* str, ase_size_t len)
2006-03-05 17:07:33 +00:00
{
2006-10-24 04:10:12 +00:00
ase_awk_val_str_t* val;
2006-03-05 17:07:33 +00:00
2006-10-24 04:10:12 +00:00
val = (ase_awk_val_str_t*) ASE_AWK_MALLOC (
2006-11-29 02:39:10 +00:00
run->awk, ASE_SIZEOF(ase_awk_val_str_t));
2006-10-24 04:10:12 +00:00
if (val == ASE_NULL) return ASE_NULL;
2006-03-05 17:07:33 +00:00
2006-10-24 04:10:12 +00:00
val->type = ASE_AWK_VAL_STR;
2006-03-26 16:36:30 +00:00
val->ref = 0;
2006-03-05 17:07:33 +00:00
val->len = len;
2006-10-24 04:10:12 +00:00
val->buf = ase_awk_strxdup (run->awk, str, len);
if (val->buf == ASE_NULL)
2006-04-17 16:12:02 +00:00
{
2006-10-24 04:10:12 +00:00
ASE_AWK_FREE (run->awk, val);
return ASE_NULL;
2006-03-05 17:07:33 +00:00
}
2006-10-24 04:10:12 +00:00
/*xp_printf (ASE_T("makestrval => %p\n"), val);*/
return (ase_awk_val_t*)val;
2006-03-04 15:54:37 +00:00
}
2006-03-05 17:07:33 +00:00
2006-11-16 15:16:25 +00:00
ase_awk_val_t* ase_awk_makestrval_nodup (
ase_awk_run_t* run, ase_char_t* str, ase_size_t len)
{
ase_awk_val_str_t* val;
val = (ase_awk_val_str_t*) ASE_AWK_MALLOC (
2006-11-29 02:39:10 +00:00
run->awk, ASE_SIZEOF(ase_awk_val_str_t));
2006-11-16 15:16:25 +00:00
if (val == ASE_NULL) return ASE_NULL;
val->type = ASE_AWK_VAL_STR;
val->ref = 0;
val->len = len;
val->buf = str;
return (ase_awk_val_t*)val;
}
2006-10-24 04:10:12 +00:00
ase_awk_val_t* ase_awk_makestrval2 (
ase_awk_run_t* run,
const ase_char_t* str1, ase_size_t len1,
const ase_char_t* str2, ase_size_t len2)
2006-04-06 16:25:37 +00:00
{
2006-10-24 04:10:12 +00:00
ase_awk_val_str_t* val;
2006-04-06 16:25:37 +00:00
2006-10-24 04:10:12 +00:00
val = (ase_awk_val_str_t*) ASE_AWK_MALLOC (
2006-11-29 02:39:10 +00:00
run->awk, ASE_SIZEOF(ase_awk_val_str_t));
2006-10-24 04:10:12 +00:00
if (val == ASE_NULL) return ASE_NULL;
2006-04-06 16:25:37 +00:00
2006-10-24 04:10:12 +00:00
val->type = ASE_AWK_VAL_STR;
2006-04-06 16:25:37 +00:00
val->ref = 0;
val->len = len1 + len2;
2006-10-24 04:10:12 +00:00
val->buf = ase_awk_strxdup2 (run->awk, str1, len1, str2, len2);
if (val->buf == ASE_NULL)
2006-04-17 16:12:02 +00:00
{
2006-10-24 04:10:12 +00:00
ASE_AWK_FREE (run->awk, val);
return ASE_NULL;
2006-04-17 16:12:02 +00:00
}
2006-10-24 04:10:12 +00:00
/*xp_printf (ASE_T("makestrval2 => %p\n"), val);*/
return (ase_awk_val_t*)val;
2006-04-17 16:12:02 +00:00
}
2006-10-24 04:10:12 +00:00
ase_awk_val_t* ase_awk_makerexval (
ase_awk_run_t* run, const ase_char_t* buf, ase_size_t len, void* code)
2006-04-24 11:26:00 +00:00
{
2006-10-24 04:10:12 +00:00
ase_awk_val_rex_t* val;
2006-04-24 11:26:00 +00:00
2006-10-24 04:10:12 +00:00
val = (ase_awk_val_rex_t*) ASE_AWK_MALLOC (
2006-11-29 02:39:10 +00:00
run->awk, ASE_SIZEOF(ase_awk_val_rex_t));
2006-10-24 04:10:12 +00:00
if (val == ASE_NULL) return ASE_NULL;
2006-04-24 11:26:00 +00:00
2006-10-24 04:10:12 +00:00
val->type = ASE_AWK_VAL_REX;
2006-04-24 11:26:00 +00:00
val->ref = 0;
val->len = len;
2006-10-24 04:10:12 +00:00
val->buf = ase_awk_strxdup (run->awk, buf, len);
if (val->buf == ASE_NULL)
2006-04-24 11:26:00 +00:00
{
2006-10-24 04:10:12 +00:00
ASE_AWK_FREE (run->awk, val);
return ASE_NULL;
2006-04-24 11:26:00 +00:00
}
2006-10-24 04:10:12 +00:00
val->code = ASE_AWK_MALLOC (run->awk, ASE_AWK_REX_LEN(code));
if (val->code == ASE_NULL)
2006-07-26 15:00:01 +00:00
{
2006-10-24 04:10:12 +00:00
ASE_AWK_FREE (run->awk, val->buf);
ASE_AWK_FREE (run->awk, val);
return ASE_NULL;
2006-07-26 15:00:01 +00:00
}
2006-10-24 04:10:12 +00:00
ASE_AWK_MEMCPY (run->awk, val->code, code, ASE_AWK_REX_LEN(code));
return (ase_awk_val_t*)val;
2006-04-24 11:26:00 +00:00
}
2006-04-21 17:24:31 +00:00
static void __free_map_val (void* run, void* v)
2006-04-17 16:12:02 +00:00
{
2006-04-18 10:28:03 +00:00
/*
2006-10-24 04:10:12 +00:00
xp_printf (ASE_T("refdown in map free..."));
2006-10-28 05:24:08 +00:00
ase_awk_dprintval (v);
2006-10-24 04:10:12 +00:00
xp_printf (ASE_T("\n"));
2006-04-18 10:28:03 +00:00
*/
2006-10-24 04:10:12 +00:00
ase_awk_refdownval (run, v);
2006-04-17 16:12:02 +00:00
}
2006-10-24 04:10:12 +00:00
ase_awk_val_t* ase_awk_makemapval (ase_awk_run_t* run)
2006-04-17 16:12:02 +00:00
{
2006-10-24 04:10:12 +00:00
ase_awk_val_map_t* val;
2006-04-17 16:12:02 +00:00
2006-10-24 04:10:12 +00:00
val = (ase_awk_val_map_t*) ASE_AWK_MALLOC (
2006-11-29 02:39:10 +00:00
run->awk, ASE_SIZEOF(ase_awk_val_map_t));
2006-10-24 04:10:12 +00:00
if (val == ASE_NULL) return ASE_NULL;
2006-04-17 16:12:02 +00:00
2006-10-24 04:10:12 +00:00
val->type = ASE_AWK_VAL_MAP;
2006-04-17 16:12:02 +00:00
val->ref = 0;
2006-10-24 04:10:12 +00:00
val->map = ase_awk_map_open (
ASE_NULL, run, 256, __free_map_val, run->awk);
if (val->map == ASE_NULL)
2006-04-17 16:12:02 +00:00
{
2006-10-24 04:10:12 +00:00
ASE_AWK_FREE (run->awk, val);
return ASE_NULL;
2006-04-06 16:25:37 +00:00
}
2006-10-24 04:10:12 +00:00
return (ase_awk_val_t*)val;
2006-04-06 16:25:37 +00:00
}
2006-10-24 04:10:12 +00:00
ase_awk_val_t* ase_awk_makerefval (ase_awk_run_t* run, int id, ase_awk_val_t** adr)
2006-08-20 15:49:48 +00:00
{
2006-10-24 04:10:12 +00:00
ase_awk_val_ref_t* val;
2006-08-20 15:49:48 +00:00
2006-08-21 02:53:42 +00:00
if (run->fcache_count > 0)
{
val = run->fcache[--run->fcache_count];
}
else
{
2006-10-24 04:10:12 +00:00
val = (ase_awk_val_ref_t*) ASE_AWK_MALLOC (
2006-11-29 02:39:10 +00:00
run->awk, ASE_SIZEOF(ase_awk_val_ref_t));
2006-10-24 04:10:12 +00:00
if (val == ASE_NULL) return ASE_NULL;
2006-08-21 02:53:42 +00:00
}
2006-08-20 15:49:48 +00:00
2006-10-24 04:10:12 +00:00
val->type = ASE_AWK_VAL_REF;
2006-08-20 15:49:48 +00:00
val->ref = 0;
val->id = id;
val->adr = adr;
2006-10-24 04:10:12 +00:00
return (ase_awk_val_t*)val;
2006-08-20 15:49:48 +00:00
}
2006-04-24 11:26:00 +00:00
2006-10-24 04:10:12 +00:00
ase_bool_t ase_awk_isbuiltinval (ase_awk_val_t* val)
2006-03-26 16:36:30 +00:00
{
2006-10-24 04:10:12 +00:00
return val == ASE_NULL ||
2006-11-23 14:27:52 +00:00
val == ase_awk_val_nil ||
val == ase_awk_val_zls ||
val == ase_awk_val_nl ||
val == ase_awk_val_zero ||
val == ase_awk_val_one ||
2006-10-24 04:10:12 +00:00
(val >= (ase_awk_val_t*)&__awk_int[0] &&
2006-11-29 02:39:10 +00:00
val <= (ase_awk_val_t*)&__awk_int[ASE_COUNTOF(__awk_int)-1]);
2006-03-26 16:36:30 +00:00
}
2006-10-24 04:10:12 +00:00
void ase_awk_freeval (ase_awk_run_t* run, ase_awk_val_t* val, ase_bool_t cache)
2006-03-04 15:54:37 +00:00
{
2006-10-24 04:10:12 +00:00
if (ase_awk_isbuiltinval(val)) return;
2006-03-22 16:05:50 +00:00
2006-10-24 04:10:12 +00:00
/*xp_printf (ASE_T("freeing [cache=%d] ... "), cache);
2006-10-28 05:24:08 +00:00
ase_awk_dprintval (val);
2006-10-24 04:10:12 +00:00
xp_printf (ASE_T("\n"));*/
if (val->type == ASE_AWK_VAL_NIL)
2006-03-04 15:54:37 +00:00
{
2006-10-24 04:10:12 +00:00
ASE_AWK_FREE (run->awk, val);
2006-08-20 15:49:48 +00:00
}
2006-10-24 04:10:12 +00:00
else if (val->type == ASE_AWK_VAL_INT)
2006-08-20 15:49:48 +00:00
{
2006-10-24 04:10:12 +00:00
if (cache == ase_true &&
2006-11-29 02:39:10 +00:00
run->icache_count < ASE_COUNTOF(run->icache))
2006-03-27 11:43:17 +00:00
{
2006-04-21 17:24:31 +00:00
run->icache[run->icache_count++] =
2006-10-24 04:10:12 +00:00
(ase_awk_val_int_t*)val;
2006-03-27 11:43:17 +00:00
}
2006-10-24 04:10:12 +00:00
else ASE_AWK_FREE (run->awk, val);
2006-08-20 15:49:48 +00:00
}
2006-10-24 04:10:12 +00:00
else if (val->type == ASE_AWK_VAL_REAL)
2006-08-20 15:49:48 +00:00
{
2006-10-24 04:10:12 +00:00
if (cache == ase_true &&
2006-11-29 02:39:10 +00:00
run->rcache_count < ASE_COUNTOF(run->rcache))
2006-03-28 16:33:09 +00:00
{
2006-04-21 17:24:31 +00:00
run->rcache[run->rcache_count++] =
2006-10-24 04:10:12 +00:00
(ase_awk_val_real_t*)val;
2006-03-28 16:33:09 +00:00
}
2006-10-24 04:10:12 +00:00
else ASE_AWK_FREE (run->awk, val);
2006-08-20 15:49:48 +00:00
}
2006-10-24 04:10:12 +00:00
else if (val->type == ASE_AWK_VAL_STR)
2006-08-20 15:49:48 +00:00
{
2006-10-24 04:10:12 +00:00
ASE_AWK_FREE (run->awk, ((ase_awk_val_str_t*)val)->buf);
ASE_AWK_FREE (run->awk, val);
2006-08-20 15:49:48 +00:00
}
2006-10-24 04:10:12 +00:00
else if (val->type == ASE_AWK_VAL_REX)
2006-08-20 15:49:48 +00:00
{
2006-10-24 04:10:12 +00:00
ASE_AWK_FREE (run->awk, ((ase_awk_val_rex_t*)val)->buf);
ase_awk_freerex (run->awk, ((ase_awk_val_rex_t*)val)->code);
ASE_AWK_FREE (run->awk, val);
2006-08-20 15:49:48 +00:00
}
2006-10-24 04:10:12 +00:00
else if (val->type == ASE_AWK_VAL_MAP)
2006-08-20 15:49:48 +00:00
{
2006-10-24 04:10:12 +00:00
ase_awk_map_close (((ase_awk_val_map_t*)val)->map);
ASE_AWK_FREE (run->awk, val);
2006-03-04 15:54:37 +00:00
}
2006-10-24 04:10:12 +00:00
else if (val->type == ASE_AWK_VAL_REF)
2006-08-20 15:49:48 +00:00
{
2006-10-24 04:10:12 +00:00
if (cache == ase_true &&
2006-11-29 02:39:10 +00:00
run->fcache_count < ASE_COUNTOF(run->fcache))
2006-08-21 02:53:42 +00:00
{
run->fcache[run->fcache_count++] =
2006-10-24 04:10:12 +00:00
(ase_awk_val_ref_t*)val;
2006-08-21 02:53:42 +00:00
}
2006-10-24 04:10:12 +00:00
else ASE_AWK_FREE (run->awk, val);
2006-08-20 15:49:48 +00:00
}
else
{
2006-10-30 14:31:37 +00:00
ASE_AWK_ASSERTX (run->awk,
!"should never happen - invalid value type",
2006-11-13 15:08:54 +00:00
"the type of a value should be one of ASE_AWK_VAL_XXX's defined in val.h");
2006-08-20 15:49:48 +00:00
}
2006-03-04 15:54:37 +00:00
}
2006-11-16 11:53:16 +00:00
void ase_awk_refupval (ase_awk_run_t* run, ase_awk_val_t* val)
2006-03-23 13:26:04 +00:00
{
2006-10-24 04:10:12 +00:00
if (ase_awk_isbuiltinval(val)) return;
2006-11-16 11:53:16 +00:00
2006-03-23 15:36:20 +00:00
/*
2006-12-13 14:13:07 +00:00
run->awk->sysfns.dprintf (ASE_T("ref up [ptr=%p] [count=%d] "), val, (int)val->ref);
2006-11-16 11:53:16 +00:00
ase_awk_dprintval (run, val);
2006-12-13 14:13:07 +00:00
run->awk->sysfns.dprintf (ASE_T("\n"));
2006-03-23 15:36:20 +00:00
*/
2006-11-16 11:53:16 +00:00
2006-03-23 13:26:04 +00:00
val->ref++;
}
2006-10-24 04:10:12 +00:00
void ase_awk_refdownval (ase_awk_run_t* run, ase_awk_val_t* val)
2006-03-23 13:26:04 +00:00
{
2006-10-24 04:10:12 +00:00
if (ase_awk_isbuiltinval(val)) return;
2006-03-23 15:36:20 +00:00
/*
2006-12-13 14:13:07 +00:00
run->awk->sysfns.dprintf (ASE_T("ref down [ptr=%p] [count=%d]\n"), val, (int)val->ref);
2006-11-16 11:53:16 +00:00
ase_awk_dprintval (run, val);
2006-12-13 14:13:07 +00:00
run->awk->sysfns.dprintf (ASE_T("\n"));
2006-03-23 15:36:20 +00:00
*/
2006-03-23 13:26:04 +00:00
2006-10-30 14:31:37 +00:00
ASE_AWK_ASSERTX (run->awk, val->ref > 0,
2006-11-13 15:08:54 +00:00
"the reference count of a value should be greater than zero for it to be decremented. check the source code for any bugs");
2006-10-30 14:31:37 +00:00
2006-03-23 13:26:04 +00:00
val->ref--;
2006-03-26 16:36:30 +00:00
if (val->ref <= 0)
{
2006-07-06 15:54:41 +00:00
/*
2006-10-24 04:10:12 +00:00
xp_printf (ASE_T("**FREEING ["));
2006-10-28 05:24:08 +00:00
ase_awk_dprintval (val);
2006-10-24 04:10:12 +00:00
xp_printf (ASE_T("]\n"));
2006-07-06 15:54:41 +00:00
*/
2006-10-24 04:10:12 +00:00
ase_awk_freeval(run, val, ase_true);
2006-03-26 16:36:30 +00:00
}
}
2006-10-24 04:10:12 +00:00
void ase_awk_refdownval_nofree (ase_awk_run_t* run, ase_awk_val_t* val)
2006-03-26 16:36:30 +00:00
{
2006-10-24 04:10:12 +00:00
if (ase_awk_isbuiltinval(val)) return;
2006-03-26 16:36:30 +00:00
2006-10-30 14:31:37 +00:00
ASE_AWK_ASSERTX (run->awk, val->ref > 0,
2006-11-13 15:08:54 +00:00
"the reference count of a value should be greater than zero for it to be decremented. check the source code for any bugs");
2006-03-26 16:36:30 +00:00
val->ref--;
2006-03-23 13:26:04 +00:00
}
2006-10-24 04:10:12 +00:00
ase_bool_t ase_awk_valtobool (ase_awk_run_t* run, ase_awk_val_t* val)
2006-03-15 15:34:59 +00:00
{
2006-10-24 04:10:12 +00:00
if (val == ASE_NULL) return ase_false;
2006-03-15 15:34:59 +00:00
switch (val->type)
{
2006-10-29 13:00:39 +00:00
case ASE_AWK_VAL_NIL:
return ase_false;
case ASE_AWK_VAL_INT:
return ((ase_awk_val_int_t*)val)->val != 0;
case ASE_AWK_VAL_REAL:
return ((ase_awk_val_real_t*)val)->val != 0.0;
case ASE_AWK_VAL_STR:
return ((ase_awk_val_str_t*)val)->len > 0;
case ASE_AWK_VAL_REX: /* TODO: is this correct? */
return ((ase_awk_val_rex_t*)val)->len > 0;
case ASE_AWK_VAL_MAP:
return ase_false; /* TODO: is this correct? */
case ASE_AWK_VAL_REF:
return ase_false; /* TODO: is this correct? */
2006-10-24 04:10:12 +00:00
}
2006-10-30 14:31:37 +00:00
ASE_AWK_ASSERTX (run->awk,
!"should never happen - invalid value type",
2006-11-13 15:08:54 +00:00
"the type of a value should be one of ASE_AWK_VAL_XXX's defined in val.h");
2006-10-24 04:10:12 +00:00
return ase_false;
2006-03-15 15:34:59 +00:00
}
2006-10-24 04:10:12 +00:00
ase_char_t* ase_awk_valtostr (
ase_awk_run_t* run, ase_awk_val_t* v,
int opt, ase_awk_str_t* buf, ase_size_t* len)
2006-06-21 11:45:26 +00:00
{
2006-10-24 04:10:12 +00:00
if (v->type == ASE_AWK_VAL_NIL)
2006-06-28 08:56:59 +00:00
{
2006-10-24 04:10:12 +00:00
return __str_to_str (run, ASE_T(""), 0, opt, buf, len);
2006-09-27 14:14:47 +00:00
}
2006-07-13 03:10:35 +00:00
2006-10-24 04:10:12 +00:00
if (v->type == ASE_AWK_VAL_INT)
2006-09-27 14:14:47 +00:00
{
2006-10-24 04:10:12 +00:00
ase_awk_val_int_t* vi = (ase_awk_val_int_t*)v;
2006-09-27 14:14:47 +00:00
2006-10-05 14:20:57 +00:00
/*
2006-10-24 04:10:12 +00:00
if (vi->nde != ASE_NULL && vi->nde->str != ASE_NULL)
2006-09-27 14:14:47 +00:00
{
return __str_to_str (
run, vi->nde->str, vi->nde->len,
2006-10-11 15:02:26 +00:00
opt, buf, len);
2006-06-28 08:56:59 +00:00
}
else
{
2006-10-05 14:20:57 +00:00
*/
2006-10-11 15:02:26 +00:00
return __val_int_to_str (run, vi, opt, buf, len);
2006-10-05 14:20:57 +00:00
/*}*/
2006-09-27 14:14:47 +00:00
}
2006-08-03 05:05:48 +00:00
2006-10-24 04:10:12 +00:00
if (v->type == ASE_AWK_VAL_REAL)
2006-09-27 14:14:47 +00:00
{
2006-10-24 04:10:12 +00:00
ase_awk_val_real_t* vr = (ase_awk_val_real_t*)v;
2006-09-27 14:14:47 +00:00
2006-10-05 14:24:38 +00:00
/*
2006-10-24 04:10:12 +00:00
if (vr->nde != ASE_NULL && vr->nde->str != ASE_NULL)
2006-09-27 14:14:47 +00:00
{
return __str_to_str (
run, vr->nde->str, vr->nde->len,
2006-10-11 15:02:26 +00:00
opt, buf, len);
2006-09-27 14:14:47 +00:00
}
else
2006-10-05 14:24:38 +00:00
{*/
2006-10-11 15:02:26 +00:00
return __val_real_to_str (run, vr, opt, buf, len);
2006-10-05 14:24:38 +00:00
/*}*/
2006-06-28 08:56:59 +00:00
}
2006-10-24 04:10:12 +00:00
if (v->type == ASE_AWK_VAL_STR)
2006-09-27 14:14:47 +00:00
{
2006-10-24 04:10:12 +00:00
ase_awk_val_str_t* vs = (ase_awk_val_str_t*)v;
2006-09-27 14:14:47 +00:00
return __str_to_str (
2006-10-11 15:02:26 +00:00
run, vs->buf, vs->len, opt, buf, len);
2006-09-27 14:14:47 +00:00
}
/* TODO: process more value types */
2006-12-13 14:13:07 +00:00
run->awk->sysfns.dprintf (
2006-11-15 05:49:22 +00:00
ASE_T("ERROR: WRONG VALUE TYPE [%d] in ase_awk_valtostr\n"),
v->type);
2006-09-27 14:14:47 +00:00
2006-10-24 04:10:12 +00:00
run->errnum = ASE_AWK_EVALTYPE;
return ASE_NULL;
2006-09-27 14:14:47 +00:00
}
2006-10-24 04:10:12 +00:00
static ase_char_t* __str_to_str (
ase_awk_run_t* run, const ase_char_t* str, ase_size_t str_len,
int opt, ase_awk_str_t* buf, ase_size_t* len)
2006-09-27 14:14:47 +00:00
{
2006-10-24 04:10:12 +00:00
if (buf == ASE_NULL)
2006-06-21 11:45:26 +00:00
{
2006-10-24 04:10:12 +00:00
ase_char_t* tmp;
tmp = ase_awk_strxdup (run->awk, str, str_len);
if (tmp == ASE_NULL)
2006-09-27 14:14:47 +00:00
{
2006-10-24 04:10:12 +00:00
run->errnum = ASE_AWK_ENOMEM;
return ASE_NULL;
2006-09-27 14:14:47 +00:00
}
2006-10-24 04:10:12 +00:00
if (len != ASE_NULL) *len = str_len;
2006-09-27 14:14:47 +00:00
return tmp;
}
else
{
2006-10-24 04:10:12 +00:00
ase_size_t n;
2006-06-21 11:45:26 +00:00
2006-10-24 04:10:12 +00:00
if (opt & ASE_AWK_VALTOSTR_CLEAR) ase_awk_str_clear (buf);
n = ase_awk_str_ncat (buf, str, str_len);
if (n == (ase_size_t)-1)
2006-06-21 11:45:26 +00:00
{
2006-10-24 04:10:12 +00:00
run->errnum = ASE_AWK_ENOMEM;
return ASE_NULL;
2006-06-21 11:45:26 +00:00
}
2006-10-24 04:10:12 +00:00
if (len != ASE_NULL) *len = ASE_AWK_STR_LEN(buf);
return ASE_AWK_STR_BUF(buf);
2006-09-27 14:14:47 +00:00
}
}
2006-10-24 04:10:12 +00:00
static ase_char_t* __val_int_to_str (
ase_awk_run_t* run, ase_awk_val_int_t* v,
int opt, ase_awk_str_t* buf, ase_size_t* len)
2006-09-27 14:14:47 +00:00
{
2006-10-24 04:10:12 +00:00
ase_char_t* tmp;
ase_long_t t;
ase_size_t l = 0;
2006-06-21 11:45:26 +00:00
2006-09-27 14:14:47 +00:00
t = v->val;
if (t == 0)
{
/* handle zero */
2006-10-24 04:10:12 +00:00
if (buf == ASE_NULL)
2006-06-21 11:45:26 +00:00
{
2006-10-24 04:10:12 +00:00
tmp = ASE_AWK_MALLOC (
2006-11-29 02:39:10 +00:00
run->awk, 2 * ASE_SIZEOF(ase_char_t));
2006-10-24 04:10:12 +00:00
if (tmp == ASE_NULL)
2006-06-21 11:45:26 +00:00
{
2006-10-24 04:10:12 +00:00
run->errnum = ASE_AWK_ENOMEM;
return ASE_NULL;
2006-06-21 11:45:26 +00:00
}
2006-10-24 04:10:12 +00:00
tmp[0] = ASE_T('0');
tmp[1] = ASE_T('\0');
if (len != ASE_NULL) *len = 1;
2006-09-27 14:14:47 +00:00
return tmp;
2006-06-21 11:45:26 +00:00
}
else
{
2006-10-24 04:10:12 +00:00
if (opt & ASE_AWK_VALTOSTR_CLEAR) ase_awk_str_clear (buf);
if (ase_awk_str_cat (buf, ASE_T("0")) == (ase_size_t)-1)
2006-06-21 11:45:26 +00:00
{
2006-10-24 04:10:12 +00:00
run->errnum = ASE_AWK_ENOMEM;
return ASE_NULL;
2006-06-21 11:45:26 +00:00
}
2006-09-27 14:14:47 +00:00
2006-10-24 04:10:12 +00:00
if (len != ASE_NULL) *len = ASE_AWK_STR_LEN(buf);
return ASE_AWK_STR_BUF(buf);
2006-06-21 11:45:26 +00:00
}
2006-09-27 14:14:47 +00:00
}
2006-06-21 11:45:26 +00:00
2006-09-27 14:14:47 +00:00
/* non-zero values */
if (t < 0) { t = -t; l++; }
while (t > 0) { l++; t /= 10; }
2006-06-21 11:45:26 +00:00
2006-10-24 04:10:12 +00:00
if (buf == ASE_NULL)
2006-09-27 14:14:47 +00:00
{
2006-10-24 04:10:12 +00:00
tmp = ASE_AWK_MALLOC (
2006-11-29 02:39:10 +00:00
run->awk, (l + 1) * ASE_SIZEOF(ase_char_t));
2006-10-24 04:10:12 +00:00
if (tmp == ASE_NULL)
2006-06-21 11:45:26 +00:00
{
2006-10-24 04:10:12 +00:00
run->errnum = ASE_AWK_ENOMEM;
return ASE_NULL;
2006-06-21 11:45:26 +00:00
}
2006-10-24 04:10:12 +00:00
tmp[l] = ASE_T('\0');
if (len != ASE_NULL) *len = l;
2006-09-27 14:14:47 +00:00
}
else
{
/* clear the buffer */
2006-10-24 04:10:12 +00:00
if (opt & ASE_AWK_VALTOSTR_CLEAR) ase_awk_str_clear (buf);
2006-09-27 14:14:47 +00:00
2006-10-24 04:10:12 +00:00
tmp = ASE_AWK_STR_BUF(buf) + ASE_AWK_STR_LEN(buf);
2006-06-21 11:45:26 +00:00
2006-09-27 14:14:47 +00:00
/* extend the buffer */
2006-10-24 04:10:12 +00:00
if (ase_awk_str_nccat (
buf, ASE_T(' '), l) == (ase_size_t)-1)
2006-08-03 05:05:48 +00:00
{
2006-10-24 04:10:12 +00:00
run->errnum = ASE_AWK_ENOMEM;
return ASE_NULL;
2006-08-03 05:05:48 +00:00
}
2006-06-21 11:45:26 +00:00
}
2006-09-27 14:14:47 +00:00
t = v->val;
if (t < 0) t = -t;
while (t > 0)
2006-07-17 04:17:40 +00:00
{
2006-10-24 04:10:12 +00:00
tmp[--l] = (ase_char_t)(t % 10) + ASE_T('0');
2006-09-27 14:14:47 +00:00
t /= 10;
}
2006-07-17 06:21:39 +00:00
2006-10-24 04:10:12 +00:00
if (v->val < 0) tmp[--l] = ASE_T('-');
2006-08-03 05:05:48 +00:00
2006-10-24 04:10:12 +00:00
if (buf != ASE_NULL)
2006-09-27 14:14:47 +00:00
{
2006-10-24 04:10:12 +00:00
tmp = ASE_AWK_STR_BUF(buf);
if (len != ASE_NULL) *len = ASE_AWK_STR_LEN(buf);
2006-09-27 14:14:47 +00:00
}
2006-07-17 06:21:39 +00:00
2006-09-27 14:14:47 +00:00
return tmp;
}
2006-07-17 06:21:39 +00:00
2006-10-24 04:10:12 +00:00
static ase_char_t* __val_real_to_str (
ase_awk_run_t* run, ase_awk_val_real_t* v,
int opt, ase_awk_str_t* buf, ase_size_t* len)
2006-09-27 14:14:47 +00:00
{
2006-11-16 11:53:16 +00:00
ase_char_t* tmp;
2006-11-15 15:05:36 +00:00
ase_size_t tmp_len;
2006-11-16 15:16:25 +00:00
ase_awk_str_t out, fbu;
2006-09-27 14:14:47 +00:00
2006-11-15 15:05:36 +00:00
if (opt & ASE_AWK_VALTOSTR_PRINT)
{
tmp = run->global.ofmt.ptr;
tmp_len = run->global.ofmt.len;
}
else
{
tmp = run->global.convfmt.ptr;
tmp_len = run->global.convfmt.len;
}
2006-10-11 15:02:26 +00:00
2006-11-16 15:16:25 +00:00
if (ase_awk_str_open (&out, 256, run->awk) == ASE_NULL)
{
run->errnum = ASE_AWK_ENOMEM;
return ASE_NULL;
}
if (ase_awk_str_open (&fbu, 256, run->awk) == ASE_NULL)
{
ase_awk_str_close (&out);
run->errnum = ASE_AWK_ENOMEM;
return ASE_NULL;
}
2006-11-18 15:36:57 +00:00
tmp = ase_awk_format (run, &out, &fbu, tmp, tmp_len,
2006-11-15 15:05:36 +00:00
(ase_size_t)-1, (ase_awk_nde_t*)v, &tmp_len);
2006-11-16 15:16:25 +00:00
if (tmp == ASE_NULL)
{
ase_awk_str_close (&fbu);
ase_awk_str_close (&out);
return ASE_NULL;
}
2006-11-15 15:05:36 +00:00
2006-10-24 04:10:12 +00:00
if (buf == ASE_NULL)
2006-06-21 11:45:26 +00:00
{
2006-11-16 15:16:25 +00:00
ase_awk_str_close (&fbu);
ase_awk_str_forfeit (&out);
2006-11-17 07:06:53 +00:00
if (len != ASE_NULL) *len = tmp_len;
2006-09-27 14:14:47 +00:00
}
else
{
2006-10-24 04:10:12 +00:00
if (opt & ASE_AWK_VALTOSTR_CLEAR) ase_awk_str_clear (buf);
2006-08-03 05:05:48 +00:00
2006-11-15 15:05:36 +00:00
if (ase_awk_str_ncat (buf, tmp, tmp_len) == (ase_size_t)-1)
2006-09-27 14:14:47 +00:00
{
2006-11-16 15:16:25 +00:00
ase_awk_str_close (&fbu);
ase_awk_str_close (&out);
2006-10-24 04:10:12 +00:00
run->errnum = ASE_AWK_ENOMEM;
return ASE_NULL;
2006-06-21 11:45:26 +00:00
}
2006-10-24 04:10:12 +00:00
tmp = ASE_AWK_STR_BUF(buf);
if (len != ASE_NULL) *len = ASE_AWK_STR_LEN(buf);
2006-11-16 15:16:25 +00:00
ase_awk_str_close (&fbu);
ase_awk_str_close (&out);
2006-06-21 11:45:26 +00:00
}
2006-09-27 14:14:47 +00:00
return tmp;
2006-06-21 11:45:26 +00:00
}
2006-10-24 04:10:12 +00:00
int ase_awk_valtonum (
ase_awk_run_t* run, ase_awk_val_t* v, ase_long_t* l, ase_real_t* r)
2006-07-17 04:17:40 +00:00
{
2006-10-24 04:10:12 +00:00
if (v->type == ASE_AWK_VAL_NIL)
2006-07-17 04:17:40 +00:00
{
*l = 0;
return 0;
}
2006-10-24 04:10:12 +00:00
if (v->type == ASE_AWK_VAL_INT)
2006-07-17 04:17:40 +00:00
{
2006-10-24 04:10:12 +00:00
*l = ((ase_awk_val_int_t*)v)->val;
2006-07-17 04:17:40 +00:00
return 0; /* long */
}
2006-10-24 04:10:12 +00:00
if (v->type == ASE_AWK_VAL_REAL)
2006-07-17 04:17:40 +00:00
{
2006-10-24 04:10:12 +00:00
*r = ((ase_awk_val_real_t*)v)->val;
2006-07-17 04:17:40 +00:00
return 1; /* real */
}
2006-10-24 04:10:12 +00:00
if (v->type == ASE_AWK_VAL_STR)
2006-07-17 04:17:40 +00:00
{
2006-12-02 16:26:29 +00:00
return ase_awk_strtonum (run,
((ase_awk_val_str_t*)v)->buf,
((ase_awk_val_str_t*)v)->len, l, r);
#if 0
2006-10-24 04:10:12 +00:00
const ase_char_t* endptr;
2006-07-17 04:17:40 +00:00
2006-10-24 04:10:12 +00:00
*l = ase_awk_strxtolong (run->awk,
((ase_awk_val_str_t*)v)->buf,
((ase_awk_val_str_t*)v)->len, 0, &endptr);
if (*endptr == ASE_T('.') ||
*endptr == ASE_T('E') ||
*endptr == ASE_T('e'))
2006-07-17 04:17:40 +00:00
{
2006-10-24 04:10:12 +00:00
*r = ase_awk_strxtoreal (run->awk,
((ase_awk_val_str_t*)v)->buf,
((ase_awk_val_str_t*)v)->len, ASE_NULL);
2006-10-06 03:37:40 +00:00
/* TODO: need to check if it is a valid number using endptr for strxtoreal? */
2006-07-17 04:17:40 +00:00
return 1; /* real */
}
2006-10-08 05:46:41 +00:00
/* TODO: do should i handle strings ending with invalid number characters like "123xx" or "dkdkdkd"? */
2006-07-17 04:17:40 +00:00
return 0; /* long */
2006-12-02 16:26:29 +00:00
#endif
2006-07-17 04:17:40 +00:00
}
2006-12-02 16:26:29 +00:00
#ifdef _DEBUG
2006-12-13 14:13:07 +00:00
run->awk->sysfns.dprintf (
2006-11-15 05:49:22 +00:00
ASE_T("ERROR: WRONG VALUE TYPE [%d] in ase_awk_valtonum\n"),
v->type);
2006-12-02 16:26:29 +00:00
#endif
2006-11-15 05:49:22 +00:00
2006-10-24 04:10:12 +00:00
run->errnum = ASE_AWK_EVALTYPE;
2006-07-17 04:17:40 +00:00
return -1; /* error */
}
2006-12-02 16:26:29 +00:00
int ase_awk_strtonum (
2006-12-04 12:59:01 +00:00
ase_awk_run_t* run, const ase_char_t* ptr, ase_size_t len,
2006-12-02 16:26:29 +00:00
ase_long_t* l, ase_real_t* r)
{
const ase_char_t* endptr;
*l = ase_awk_strxtolong (run->awk, ptr, len, 0, &endptr);
if (*endptr == ASE_T('.') ||
*endptr == ASE_T('E') ||
*endptr == ASE_T('e'))
{
*r = ase_awk_strxtoreal (run->awk, ptr, len, ASE_NULL);
/* TODO: need to check if it is a valid number using endptr for strxtoreal? */
return 1; /* real */
}
/* TODO: do should i handle strings ending with invalid number characters like "123xx" or "dkdkdkd"? */
return 0; /* long */
}
2006-12-13 14:13:07 +00:00
#define __DPRINTF run->awk->sysfns.dprintf
2006-10-28 05:24:08 +00:00
2006-10-24 04:10:12 +00:00
static int __print_pair (ase_awk_pair_t* pair, void* arg)
2006-04-20 05:44:29 +00:00
{
2006-10-28 05:24:08 +00:00
ase_awk_run_t* run = (ase_awk_run_t*)arg;
__DPRINTF (ASE_T(" %s=>"), pair->key);
ase_awk_dprintval ((ase_awk_run_t*)arg, pair->val);
__DPRINTF (ASE_T(" "));
2006-04-20 05:44:29 +00:00
return 0;
}
2006-10-28 05:24:08 +00:00
void ase_awk_dprintval (ase_awk_run_t* run, ase_awk_val_t* val)
2006-03-04 15:54:37 +00:00
{
2006-10-28 05:24:08 +00:00
/* TODO: better value printing ... */
2006-03-04 15:54:37 +00:00
switch (val->type)
{
2006-10-29 13:00:39 +00:00
case ASE_AWK_VAL_NIL:
__DPRINTF (ASE_T("nil"));
break;
case ASE_AWK_VAL_INT:
2006-11-19 15:08:13 +00:00
#if ASE_SIZEOF_LONG_LONG > 0
__DPRINTF (ASE_T("%lld"),
(long long)((ase_awk_val_int_t*)val)->val);
#elif ASE_SIZEOF___INT64 > 0
2006-10-29 13:00:39 +00:00
__DPRINTF (ASE_T("%I64d"),
(__int64)((ase_awk_nde_int_t*)val)->val);
2006-11-19 15:08:13 +00:00
#elif ASE_SIZEOF_LONG > 0
2006-10-29 13:00:39 +00:00
__DPRINTF (ASE_T("%ld"),
(long)((ase_awk_val_int_t*)val)->val);
2006-11-19 15:08:13 +00:00
#elif ASE_SIZEOF_INT > 0
__DPRINTF (ASE_T("%d"),
(int)((ase_awk_val_int_t*)val)->val);
2006-10-29 13:00:39 +00:00
#else
2006-11-19 15:08:13 +00:00
#error unsupported integer size
2006-10-29 13:00:39 +00:00
#endif
break;
case ASE_AWK_VAL_REAL:
__DPRINTF (ASE_T("%Lf"),
(long double)((ase_awk_val_real_t*)val)->val);
break;
case ASE_AWK_VAL_STR:
__DPRINTF (ASE_T("%s"), ((ase_awk_val_str_t*)val)->buf);
break;
case ASE_AWK_VAL_REX:
__DPRINTF (ASE_T("REX[%s]"), ((ase_awk_val_rex_t*)val)->buf);
break;
case ASE_AWK_VAL_MAP:
__DPRINTF (ASE_T("MAP["));
ase_awk_map_walk (((ase_awk_val_map_t*)val)->map, __print_pair, run);
__DPRINTF (ASE_T("]"));
break;
2006-08-20 15:49:48 +00:00
2006-10-29 13:00:39 +00:00
case ASE_AWK_VAL_REF:
__DPRINTF (ASE_T("REF[id=%d,val="), ((ase_awk_val_ref_t*)val)->id);
ase_awk_dprintval (run, *((ase_awk_val_ref_t*)val)->adr);
__DPRINTF (ASE_T("]"));
break;
default:
__DPRINTF (ASE_T("**** INTERNAL ERROR - INVALID VALUE TYPE ****\n"));
2006-03-04 15:54:37 +00:00
}
}