improved numeric string comparison for various contexts.

This commit is contained in:
2009-06-17 00:05:40 +00:00
parent ed6db12e27
commit e774c0bbd1
8 changed files with 294 additions and 289 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: Awk.cpp 199 2009-06-14 08:40:52Z hyunghwan.chung $
* $Id: Awk.cpp 202 2009-06-16 06:05:40Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -62,7 +62,7 @@ void Awk::Source::setHandle (void* handle)
// Awk::RIO
//////////////////////////////////////////////////////////////////
Awk::RIO::RIO (rtx_t* rtx, riod_t* riod): rtx (rtx), riod (riod)
Awk::RIO::RIO (rtx_t* rtx, rio_arg_t* riod): rtx (rtx), riod (riod)
{
}
@ -92,7 +92,7 @@ Awk::RIO::operator Awk::awk_t* () const
return qse_awk_rtx_getawk (this->rtx);
}
Awk::RIO::operator Awk::riod_t* () const
Awk::RIO::operator Awk::rio_arg_t* () const
{
return this->riod;
}
@ -106,7 +106,7 @@ Awk::RIO::operator Awk::rtx_t* () const
// Awk::Pipe
//////////////////////////////////////////////////////////////////
Awk::Pipe::Pipe (rtx_t* rtx, riod_t* riod): RIO (rtx, riod)
Awk::Pipe::Pipe (rtx_t* rtx, rio_arg_t* riod): RIO (rtx, riod)
{
}
@ -119,7 +119,7 @@ Awk::Pipe::Mode Awk::Pipe::getMode () const
// Awk::File
//////////////////////////////////////////////////////////////////
Awk::File::File (rtx_t* rtx, riod_t* riod): RIO (rtx, riod)
Awk::File::File (rtx_t* rtx, rio_arg_t* riod): RIO (rtx, riod)
{
}
@ -132,7 +132,7 @@ Awk::File::Mode Awk::File::getMode () const
// Awk::Console
//////////////////////////////////////////////////////////////////
Awk::Console::Console (rtx_t* rtx, riod_t* riod):
Awk::Console::Console (rtx_t* rtx, rio_arg_t* riod):
RIO (rtx, riod), filename(QSE_NULL)
{
}
@ -1635,7 +1635,7 @@ Awk::ssize_t Awk::sourceWriter (
}
Awk::ssize_t Awk::pipeHandler (
rtx_t* rtx, qse_awk_rio_cmd_t cmd, riod_t* riod,
rtx_t* rtx, rio_cmd_t cmd, rio_arg_t* riod,
char_t* data, size_t count)
{
rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx);
@ -1668,7 +1668,7 @@ Awk::ssize_t Awk::pipeHandler (
}
Awk::ssize_t Awk::fileHandler (
rtx_t* rtx, qse_awk_rio_cmd_t cmd, riod_t* riod,
rtx_t* rtx, rio_cmd_t cmd, rio_arg_t* riod,
char_t* data, size_t count)
{
rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx);
@ -1701,7 +1701,7 @@ Awk::ssize_t Awk::fileHandler (
}
Awk::ssize_t Awk::consoleHandler (
rtx_t* rtx, qse_awk_rio_cmd_t cmd, riod_t* riod,
rtx_t* rtx, rio_cmd_t cmd, rio_arg_t* riod,
char_t* data, size_t count)
{
rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx);

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.h 199 2009-06-14 08:40:52Z hyunghwan.chung $
* $Id: awk.h 202 2009-06-16 06:05:40Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -332,8 +332,8 @@ struct qse_awk_rtx_t
/* rio chain */
struct
{
qse_awk_riof_t handler[QSE_AWK_RIO_NUM];
qse_awk_riod_t* chain;
qse_awk_rio_fun_t handler[QSE_AWK_RIO_NUM];
qse_awk_rio_arg_t* chain;
} rio;
struct

View File

@ -1,5 +1,5 @@
/*
* $Id: rio.c 199 2009-06-14 08:40:52Z hyunghwan.chung $
* $Id: rio.c 202 2009-06-16 06:05:40Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -90,8 +90,8 @@ int qse_awk_rtx_readio (
qse_awk_rtx_t* run, int in_type,
const qse_char_t* name, qse_str_t* buf)
{
qse_awk_riod_t* p = run->rio.chain;
qse_awk_riof_t handler;
qse_awk_rio_arg_t* p = run->rio.chain;
qse_awk_rio_fun_t handler;
int io_type, io_mode, io_mask, ret, n;
qse_ssize_t x;
qse_awk_val_t* rs;
@ -130,8 +130,8 @@ int qse_awk_rtx_readio (
{
/* if the name doesn't exist in the chain, create an entry
* to the chain */
p = (qse_awk_riod_t*) QSE_AWK_ALLOC (
run->awk, QSE_SIZEOF(qse_awk_riod_t));
p = (qse_awk_rio_arg_t*) QSE_AWK_ALLOC (
run->awk, QSE_SIZEOF(qse_awk_rio_arg_t));
if (p == QSE_NULL)
{
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM);
@ -443,8 +443,8 @@ int qse_awk_rtx_writeio_str (
qse_awk_rtx_t* run, int out_type,
const qse_char_t* name, qse_char_t* str, qse_size_t len)
{
qse_awk_riod_t* p = run->rio.chain;
qse_awk_riof_t handler;
qse_awk_rio_arg_t* p = run->rio.chain;
qse_awk_rio_fun_t handler;
int io_type, io_mode, io_mask;
qse_ssize_t n;
@ -486,8 +486,8 @@ int qse_awk_rtx_writeio_str (
/* if there is not corresponding rio for name, create one */
if (p == QSE_NULL)
{
p = (qse_awk_riod_t*) QSE_AWK_ALLOC (
run->awk, QSE_SIZEOF(qse_awk_riod_t));
p = (qse_awk_rio_arg_t*) QSE_AWK_ALLOC (
run->awk, QSE_SIZEOF(qse_awk_rio_arg_t));
if (p == QSE_NULL)
{
qse_awk_rtx_seterror (
@ -582,8 +582,8 @@ int qse_awk_rtx_writeio_str (
int qse_awk_rtx_flushio (
qse_awk_rtx_t* run, int out_type, const qse_char_t* name)
{
qse_awk_riod_t* p = run->rio.chain;
qse_awk_riof_t handler;
qse_awk_rio_arg_t* p = run->rio.chain;
qse_awk_rio_fun_t handler;
int io_type, /*io_mode,*/ io_mask;
qse_ssize_t n;
qse_bool_t ok = QSE_FALSE;
@ -637,8 +637,8 @@ int qse_awk_rtx_flushio (
int qse_awk_rtx_nextio_read (
qse_awk_rtx_t* run, int in_type, const qse_char_t* name)
{
qse_awk_riod_t* p = run->rio.chain;
qse_awk_riof_t handler;
qse_awk_rio_arg_t* p = run->rio.chain;
qse_awk_rio_fun_t handler;
int io_type, /*io_mode,*/ io_mask;
qse_ssize_t n;
@ -715,8 +715,8 @@ int qse_awk_rtx_nextio_read (
int qse_awk_rtx_nextio_write (
qse_awk_rtx_t* run, int out_type, const qse_char_t* name)
{
qse_awk_riod_t* p = run->rio.chain;
qse_awk_riof_t handler;
qse_awk_rio_arg_t* p = run->rio.chain;
qse_awk_rio_fun_t handler;
int io_type, /*io_mode,*/ io_mask;
qse_ssize_t n;
@ -788,8 +788,8 @@ int qse_awk_rtx_nextio_write (
int qse_awk_rtx_closio_read (
qse_awk_rtx_t* run, int in_type, const qse_char_t* name)
{
qse_awk_riod_t* p = run->rio.chain, * px = QSE_NULL;
qse_awk_riof_t handler;
qse_awk_rio_arg_t* p = run->rio.chain, * px = QSE_NULL;
qse_awk_rio_fun_t handler;
int io_type, /*io_mode,*/ io_mask;
QSE_ASSERT (in_type >= 0 && in_type <= QSE_COUNTOF(in_type_map));
@ -814,7 +814,7 @@ int qse_awk_rtx_closio_read (
if (p->type == (io_type | io_mask) &&
qse_strcmp (p->name, name) == 0)
{
qse_awk_riof_t handler;
qse_awk_rio_fun_t handler;
handler = run->rio.handler[p->type & MASK_CLEAR];
if (handler != QSE_NULL)
@ -847,8 +847,8 @@ int qse_awk_rtx_closio_read (
int qse_awk_rtx_closio_write (
qse_awk_rtx_t* run, int out_type, const qse_char_t* name)
{
qse_awk_riod_t* p = run->rio.chain, * px = QSE_NULL;
qse_awk_riof_t handler;
qse_awk_rio_arg_t* p = run->rio.chain, * px = QSE_NULL;
qse_awk_rio_fun_t handler;
int io_type, /*io_mode,*/ io_mask;
QSE_ASSERT (out_type >= 0 && out_type <= QSE_COUNTOF(out_type_map));
@ -873,7 +873,7 @@ int qse_awk_rtx_closio_write (
if (p->type == (io_type | io_mask) &&
qse_strcmp (p->name, name) == 0)
{
qse_awk_riof_t handler;
qse_awk_rio_fun_t handler;
handler = run->rio.handler[p->type & MASK_CLEAR];
if (handler != QSE_NULL)
@ -905,7 +905,7 @@ int qse_awk_rtx_closio_write (
int qse_awk_rtx_closeio (qse_awk_rtx_t* run, const qse_char_t* name)
{
qse_awk_riod_t* p = run->rio.chain, * px = QSE_NULL;
qse_awk_rio_arg_t* p = run->rio.chain, * px = QSE_NULL;
while (p != QSE_NULL)
{
@ -913,7 +913,7 @@ int qse_awk_rtx_closeio (qse_awk_rtx_t* run, const qse_char_t* name)
* regardless of the io type */
if (qse_strcmp (p->name, name) == 0)
{
qse_awk_riof_t handler;
qse_awk_rio_fun_t handler;
handler = run->rio.handler[p->type & MASK_CLEAR];
if (handler != QSE_NULL)
@ -947,8 +947,8 @@ int qse_awk_rtx_closeio (qse_awk_rtx_t* run, const qse_char_t* name)
void qse_awk_rtx_cleario (qse_awk_rtx_t* run)
{
qse_awk_riod_t* next;
qse_awk_riof_t handler;
qse_awk_rio_arg_t* next;
qse_awk_rio_fun_t handler;
qse_ssize_t n;
while (run->rio.chain != QSE_NULL)

View File

@ -1,5 +1,5 @@
/*
* $Id: run.c 201 2009-06-15 08:22:48Z hyunghwan.chung $
* $Id: run.c 202 2009-06-16 06:05:40Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -4019,51 +4019,42 @@ static int __cmp_int_real (
}
static int __cmp_int_str (
qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
const qse_char_t* end;
qse_awk_rtx_valtostr_out_t out;
qse_long_t r;
int n;
r = qse_awk_strxtolong (
run->awk,
((qse_awk_val_str_t*)right)->ptr,
((qse_awk_val_str_t*)right)->len, 0,
&end
);
if (end == ((qse_awk_val_str_t*)right)->ptr +
((qse_awk_val_str_t*)right)->len)
{
if (((qse_awk_val_int_t*)left)->val > r) return 1;
if (((qse_awk_val_int_t*)left)->val < r) return -1;
return 0;
}
/* TODO: should i conver it to real and compare? */
else if (*end == QSE_T('.') || *end == QSE_T('E') || *end == QSE_T('e'))
if (rtx->awk->option & QSE_AWK_NUMCMPONSTR)
{
const qse_char_t* end;
qse_long_t ll;
qse_real_t rr;
rr = qse_awk_strxtoreal (
run->awk,
n = qse_awk_rtx_strtonum (
rtx, 1,
((qse_awk_val_str_t*)right)->ptr,
((qse_awk_val_str_t*)right)->len,
&end
&ll, &rr
);
if (end == ((qse_awk_val_str_t*)right)->ptr +
((qse_awk_val_str_t*)right)->len)
if (n == 0)
{
if (((qse_awk_val_int_t*)left)->val > rr) return 1;
if (((qse_awk_val_int_t*)left)->val < rr) return -1;
return 0;
/* a numeric integral string */
return (((qse_awk_val_int_t*)left)->val > ll)? 1:
(((qse_awk_val_int_t*)left)->val < ll)? -1: 0;
}
else if (n > 0)
{
/* a numeric floating-point string */
return (((qse_awk_val_int_t*)left)->val > rr)? 1:
(((qse_awk_val_int_t*)left)->val < rr)? -1: 0;
}
}
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
if (qse_awk_rtx_valtostr (run, left, &out) == QSE_NULL)
if (qse_awk_rtx_valtostr (rtx, left, &out) == QSE_NULL)
return CMP_ERROR;
if (run->gbl.ignorecase)
if (rtx->gbl.ignorecase)
{
n = qse_strxncasecmp (
out.u.cpldup.ptr,
@ -4082,7 +4073,7 @@ static int __cmp_int_str (
);
}
QSE_AWK_FREE (run->awk, out.u.cpldup.ptr);
QSE_AWK_FREE (rtx->awk, out.u.cpldup.ptr);
return n;
}
@ -4115,32 +4106,35 @@ static int __cmp_real_real (
}
static int __cmp_real_str (
qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right)
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
{
qse_awk_rtx_valtostr_out_t out;
const qse_char_t* end;
qse_real_t rr;
int n;
rr = qse_awk_strxtoreal (
run->awk,
((qse_awk_val_str_t*)right)->ptr,
((qse_awk_val_str_t*)right)->len,
&end
);
if (end == ((qse_awk_val_str_t*)right)->ptr +
((qse_awk_val_str_t*)right)->len)
if (rtx->awk->option & QSE_AWK_NUMCMPONSTR)
{
if (((qse_awk_val_real_t*)left)->val > rr) return 1;
if (((qse_awk_val_real_t*)left)->val < rr) return -1;
return 0;
const qse_char_t* end;
qse_real_t rr;
rr = qse_awk_strxtoreal (
rtx->awk,
((qse_awk_val_str_t*)right)->ptr,
((qse_awk_val_str_t*)right)->len,
&end
);
if (end == ((qse_awk_val_str_t*)right)->ptr +
((qse_awk_val_str_t*)right)->len)
{
return (((qse_awk_val_real_t*)left)->val > rr)? 1:
(((qse_awk_val_real_t*)left)->val < rr)? -1: 0;
}
}
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
if (qse_awk_rtx_valtostr (run, left, &out) == QSE_NULL)
if (qse_awk_rtx_valtostr (rtx, left, &out) == QSE_NULL)
return CMP_ERROR;
if (run->gbl.ignorecase)
if (rtx->gbl.ignorecase)
{
n = qse_strxncasecmp (
out.u.cpldup.ptr,
@ -4159,7 +4153,7 @@ static int __cmp_real_str (
);
}
QSE_AWK_FREE (run->awk, out.u.cpldup.ptr);
QSE_AWK_FREE (rtx->awk, out.u.cpldup.ptr);
return n;
}
@ -4192,7 +4186,7 @@ static int __cmp_str_str (
ls = (qse_awk_val_str_t*)left;
rs = (qse_awk_val_str_t*)right;
if (ls->nstr == 0 && rs->nstr == 0)
if (ls->nstr == 0 || rs->nstr == 0)
{
/* nother are definitely a string */
return (rtx->gbl.ignorecase)?
@ -4200,17 +4194,68 @@ static int __cmp_str_str (
qse_strxncmp (ls->ptr, ls->len, rs->ptr, rs->len);
}
n1 = qse_awk_rtx_strtonum (rtx, 0, ls->ptr, ls->len, &l1, &r1);
n2 = qse_awk_rtx_strtonum (rtx, 0, rs->ptr, rs->len, &l2, &r2);
if (n1 == 0)
if (ls->nstr == 1)
{
return (n2 == 0)? (l1 - l2): ((qse_real_t)l1 - r2);
qse_long_t ll;
ll = qse_awk_strxtolong (
rtx->awk, ls->ptr, ls->len, 0, QSE_NULL);
if (rs->nstr == 1)
{
qse_long_t rr;
rr = qse_awk_strxtolong (
rtx->awk, rs->ptr, rs->len, 0, QSE_NULL);
return (ll > rr)? 1:
(ll < rr)? -1: 0;
}
else
{
qse_real_t rr;
QSE_ASSERT (rs->nstr == 2);
rr = qse_awk_strxtoreal (
rtx->awk, rs->ptr, rs->len, QSE_NULL);
return (ll > rr)? 1:
(ll < rr)? -1: 0;
}
}
else
{
return (n2 == 0)? (r1 - (qse_real_t)l2): (r1 - r2);
}
qse_real_t ll;
QSE_ASSERT (ls->nstr == 2);
ll = qse_awk_strxtoreal (
rtx->awk, ls->ptr, ls->len, QSE_NULL);
if (rs->nstr == 1)
{
qse_long_t rr;
rr = qse_awk_strxtolong (
rtx->awk, rs->ptr, rs->len, 0, QSE_NULL);
return (ll > rr)? 1:
(ll < rr)? -1: 0;
}
else
{
qse_real_t rr;
QSE_ASSERT (rs->nstr == 2);
rr = qse_awk_strxtoreal (
rtx->awk, rs->ptr, rs->len, QSE_NULL);
return (ll > rr)? 1:
(ll < rr)? -1: 0;
}
}
}
static int __cmp_val (

View File

@ -1,5 +1,5 @@
/*
* $Id: std.c 195 2009-06-10 13:18:25Z hyunghwan.chung $
* $Id: std.c 202 2009-06-16 06:05:40Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -406,7 +406,7 @@ int qse_awk_parsestd (
/*** RTX_OPENSTD ***/
static qse_ssize_t awk_rio_pipe (
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_riod_t* riod,
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
qse_char_t* data, qse_size_t size)
{
switch (cmd)
@ -489,7 +489,7 @@ static qse_ssize_t awk_rio_pipe (
}
static qse_ssize_t awk_rio_file (
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_riod_t* riod,
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
qse_char_t* data, qse_size_t size)
{
switch (cmd)
@ -579,7 +579,7 @@ static qse_ssize_t awk_rio_file (
return -1;
}
static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_riod_t* riod)
static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod)
{
rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx);
@ -696,7 +696,7 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_riod_t* riod)
}
static qse_ssize_t awk_rio_console (
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_riod_t* riod,
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
qse_char_t* data, qse_size_t size)
{
rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx);