migrated rand(), srand(), system() to modules
This commit is contained in:
parent
82a639045f
commit
fdce5fc592
@ -115,13 +115,6 @@ protected:
|
|||||||
int __build_environ (Run* run, void* envptr);
|
int __build_environ (Run* run, void* envptr);
|
||||||
|
|
||||||
// intrinsic functions
|
// intrinsic functions
|
||||||
int rand (Run& run, Value& ret, Value* args, size_t nargs,
|
|
||||||
const char_t* name, size_t len);
|
|
||||||
int srand (Run& run, Value& ret, Value* args, size_t nargs,
|
|
||||||
const char_t* name, size_t len);
|
|
||||||
int system (Run& run, Value& ret, Value* args, size_t nargs,
|
|
||||||
const char_t* name, size_t len);
|
|
||||||
|
|
||||||
qse_cmgr_t* getcmgr (const char_t* ioname);
|
qse_cmgr_t* getcmgr (const char_t* ioname);
|
||||||
|
|
||||||
int setioattr (Run& run, Value& ret, Value* args, size_t nargs,
|
int setioattr (Run& run, Value& ret, Value* args, size_t nargs,
|
||||||
@ -159,13 +152,11 @@ protected:
|
|||||||
flt_t pow (flt_t x, flt_t y);
|
flt_t pow (flt_t x, flt_t y);
|
||||||
flt_t mod (flt_t x, flt_t y);
|
flt_t mod (flt_t x, flt_t y);
|
||||||
|
|
||||||
void* modopen (const mod_spec_t* spec);
|
void* modopen (const mod_spec_t* spec);
|
||||||
void modclose (void* handle);
|
void modclose (void* handle);
|
||||||
void* modsym (void* handle, const char_t* name);
|
void* modsym (void* handle, const char_t* name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int_t seed;
|
|
||||||
uint_t prand;
|
|
||||||
qse_htb_t cmgrtab;
|
qse_htb_t cmgrtab;
|
||||||
bool cmgrtab_inited;
|
bool cmgrtab_inited;
|
||||||
|
|
||||||
|
@ -1623,7 +1623,7 @@ int Awk::addFunction (
|
|||||||
spec.arg.min = minArgs;
|
spec.arg.min = minArgs;
|
||||||
spec.arg.max = maxArgs;
|
spec.arg.max = maxArgs;
|
||||||
spec.arg.spec = argSpec;
|
spec.arg.spec = argSpec;
|
||||||
spec.impl = functionHandler;
|
spec.impl = this->functionHandler;
|
||||||
spec.trait = validOpts;
|
spec.trait = validOpts;
|
||||||
|
|
||||||
qse_awk_fnc_t* fnc = qse_awk_addfnc (awk, name, &spec);
|
qse_awk_fnc_t* fnc = qse_awk_addfnc (awk, name, &spec);
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include <qse/cmn/sio.h>
|
#include <qse/cmn/sio.h>
|
||||||
#include <qse/cmn/nwio.h>
|
#include <qse/cmn/nwio.h>
|
||||||
#include <qse/cmn/path.h>
|
#include <qse/cmn/path.h>
|
||||||
#include <qse/cmn/alg.h>
|
|
||||||
#include "awk.h"
|
#include "awk.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -128,11 +127,11 @@ int StdAwk::open ()
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addFunction (QSE_T("rand"), 0, 0, QSE_NULL, (FunctionHandler)&StdAwk::rand, 0) <= -1 ||
|
if (addFunction (QSE_T("rand"), 1, 0, QSE_T("math"), QSE_NULL, 0) <= -1 ||
|
||||||
addFunction (QSE_T("srand"), 0, 1, QSE_NULL, (FunctionHandler)&StdAwk::srand, 0) <= -1 ||
|
addFunction (QSE_T("srand"), 1, 0, QSE_T("math"), QSE_NULL, 0) <= -1 ||
|
||||||
addFunction (QSE_T("system"), 1, 1, QSE_NULL, (FunctionHandler)&StdAwk::system, 0) <= -1 ||
|
addFunction (QSE_T("system"), 1, 0, QSE_T("sys"), QSE_NULL, 0) <= -1 ||
|
||||||
addFunction (QSE_T("setioattr"), 3, 3, QSE_NULL, (FunctionHandler)&StdAwk::setioattr, QSE_AWK_RIO) <= -1 ||
|
addFunction (QSE_T("setioattr"), 3, 3, QSE_NULL, (FunctionHandler)&StdAwk::setioattr, QSE_AWK_RIO) <= -1 ||
|
||||||
addFunction (QSE_T("getioattr"), 3, 3, QSE_T("vvr"), (FunctionHandler)&StdAwk::getioattr, QSE_AWK_RIO) <= -1)
|
addFunction (QSE_T("getioattr"), 3, 3, QSE_T("vvr"), (FunctionHandler)&StdAwk::getioattr, QSE_AWK_RIO) <= -1)
|
||||||
{
|
{
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
@ -145,15 +144,6 @@ int StdAwk::open ()
|
|||||||
if (lt_dlinit() != 0) goto oops;
|
if (lt_dlinit() != 0) goto oops;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
qse_ntime_t now;
|
|
||||||
|
|
||||||
this->seed = (qse_gettime(&now) <= -1)? 0u: ((int_t)now.sec + (int_t)now.nsec);
|
|
||||||
/* i don't care if the seed becomes negative or overflows.
|
|
||||||
* i just convert the signed value to the unsigned one. */
|
|
||||||
this->prand = (uint_t)(this->seed * this->seed * this->seed);
|
|
||||||
/* make sure that the actual seeding is not 0 */
|
|
||||||
if (this->prand == 0) this->prand++;
|
|
||||||
|
|
||||||
this->cmgrtab_inited = false;
|
this->cmgrtab_inited = false;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -336,69 +326,6 @@ int StdAwk::make_additional_globals (Run* run)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StdAwk::rand (Run& run, Value& ret, Value* args, size_t nargs,
|
|
||||||
const char_t* name, size_t len)
|
|
||||||
{
|
|
||||||
#define RANDV_MAX QSE_TYPE_MAX(int_t)
|
|
||||||
|
|
||||||
#if defined(QSE_USE_AWK_INTMAX)
|
|
||||||
this->prand = qse_randxsuintmax (this->prand);
|
|
||||||
#else
|
|
||||||
this->prand = qse_randxsulong (this->prand);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int_t randv = this->prand % RANDV_MAX;
|
|
||||||
return ret.setFlt ((flt_t)randv / RANDV_MAX);
|
|
||||||
#undef RANDV_MAX
|
|
||||||
}
|
|
||||||
|
|
||||||
int StdAwk::srand (Run& run, Value& ret, Value* args, size_t nargs,
|
|
||||||
const char_t* name, size_t len)
|
|
||||||
{
|
|
||||||
int_t prevSeed = (int_t)this->seed;
|
|
||||||
|
|
||||||
qse_ntime_t now;
|
|
||||||
|
|
||||||
if (nargs <= 0)
|
|
||||||
{
|
|
||||||
this->seed = (qse_gettime (&now) <= -1)?
|
|
||||||
(this->seed * this->seed): ((int_t)now.sec + (int_t)now.nsec);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->seed = args[0].toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i don't care if the seed becomes negative or overflows.
|
|
||||||
* i just convert the signed value to the unsigned one. */
|
|
||||||
this->prand = (uint_t)(this->seed * this->seed * this->seed);
|
|
||||||
/* make sure that the actual seeding is not 0 */
|
|
||||||
if (this->prand == 0) this->prand++;
|
|
||||||
|
|
||||||
return ret.setInt ((int_t)prevSeed);
|
|
||||||
}
|
|
||||||
|
|
||||||
int StdAwk::system (Run& run, Value& ret, Value* args, size_t nargs,
|
|
||||||
const char_t* name, size_t len)
|
|
||||||
{
|
|
||||||
size_t l;
|
|
||||||
const char_t* ptr = args[0].toStr(&l);
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
return ret.setInt ((int_t)::_tsystem(ptr));
|
|
||||||
#elif defined(QSE_CHAR_IS_MCHAR)
|
|
||||||
return ret.setInt ((int_t)::system(ptr));
|
|
||||||
#else
|
|
||||||
|
|
||||||
qse_mchar_t* mbs;
|
|
||||||
mbs = qse_wcstombsdup (ptr, QSE_NULL, ((Awk*)run)->getMmgr());
|
|
||||||
if (mbs == QSE_NULL) return -1;
|
|
||||||
int n = ret.setInt ((int_t)::system(mbs));
|
|
||||||
QSE_MMGR_FREE (((Awk*)run)->getMmgr(), mbs);
|
|
||||||
return n;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
qse_cmgr_t* StdAwk::getcmgr (const char_t* ioname)
|
qse_cmgr_t* StdAwk::getcmgr (const char_t* ioname)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (this->cmgrtab_inited == true);
|
QSE_ASSERT (this->cmgrtab_inited == true);
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
#include "mod-str.h"
|
#include "mod-str.h"
|
||||||
#include <qse/cmn/str.h>
|
#include <qse/cmn/str.h>
|
||||||
#include <qse/cmn/chr.h>
|
#include <qse/cmn/chr.h>
|
||||||
|
#include <qse/cmn/alg.h>
|
||||||
|
#include <qse/cmn/time.h>
|
||||||
#include "../cmn/mem.h"
|
#include "../cmn/mem.h"
|
||||||
#include "fnc.h"
|
#include "fnc.h"
|
||||||
|
|
||||||
@ -53,6 +55,12 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct modctx_t
|
||||||
|
{
|
||||||
|
qse_awk_int_t seed;
|
||||||
|
qse_awk_uint_t prand; /* last random value returned */
|
||||||
|
} modctx_t;
|
||||||
|
|
||||||
static int fnc_math_1 (
|
static int fnc_math_1 (
|
||||||
qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi, qse_awk_math1_t f)
|
qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi, qse_awk_math1_t f)
|
||||||
{
|
{
|
||||||
@ -454,6 +462,73 @@ static int fnc_sqrt (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
|||||||
return fnc_math_1 (rtx, fi, math_sqrt);
|
return fnc_math_1 (rtx, fi, math_sqrt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static int fnc_rand (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||||
|
{
|
||||||
|
#define RANDV_MAX QSE_TYPE_MAX(qse_awk_int_t)
|
||||||
|
qse_awk_val_t* r;
|
||||||
|
qse_awk_int_t randv;
|
||||||
|
modctx_t* modctx;
|
||||||
|
|
||||||
|
modctx = (modctx_t*)fi->mod->ctx;
|
||||||
|
|
||||||
|
#if defined(QSE_USE_AWK_INTMAX)
|
||||||
|
modctx->prand = qse_randxsuintmax (modctx->prand);
|
||||||
|
#else
|
||||||
|
modctx->prand = qse_randxsulong (modctx->prand);
|
||||||
|
#endif
|
||||||
|
randv = modctx->prand % RANDV_MAX;
|
||||||
|
|
||||||
|
r = qse_awk_rtx_makefltval (rtx, (qse_awk_flt_t)randv / RANDV_MAX);
|
||||||
|
if (r == QSE_NULL) return -1;
|
||||||
|
|
||||||
|
qse_awk_rtx_setretval (rtx, r);
|
||||||
|
return 0;
|
||||||
|
#undef RANDV_MAX
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fnc_srand (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||||
|
{
|
||||||
|
qse_size_t nargs;
|
||||||
|
qse_awk_val_t* a0;
|
||||||
|
qse_awk_int_t lv;
|
||||||
|
qse_awk_val_t* r;
|
||||||
|
int n;
|
||||||
|
qse_awk_int_t prev;
|
||||||
|
qse_ntime_t now;
|
||||||
|
modctx_t* modctx;
|
||||||
|
|
||||||
|
modctx = (modctx_t*)fi->mod->ctx;
|
||||||
|
nargs = qse_awk_rtx_getnargs (rtx);
|
||||||
|
QSE_ASSERT (nargs == 0 || nargs == 1);
|
||||||
|
|
||||||
|
prev = modctx->seed;
|
||||||
|
|
||||||
|
if (nargs <= 0)
|
||||||
|
{
|
||||||
|
modctx->seed = (qse_gettime (&now) <= -1)?
|
||||||
|
(modctx->seed * modctx->seed): ((qse_awk_int_t)now.sec + (qse_awk_int_t)now.nsec);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a0 = qse_awk_rtx_getarg (rtx, 0);
|
||||||
|
n = qse_awk_rtx_valtoint (rtx, a0, &lv);
|
||||||
|
if (n <= -1) return -1;
|
||||||
|
modctx->seed = lv;
|
||||||
|
}
|
||||||
|
/* i don't care if the seed becomes negative or overflows.
|
||||||
|
* i just convert the signed value to the unsigned one. */
|
||||||
|
modctx->prand = (qse_awk_uint_t)(modctx->seed * modctx->seed * modctx->seed);
|
||||||
|
/* make sure that the actual seeding is not 0 */
|
||||||
|
if (modctx->prand == 0) modctx->prand++;
|
||||||
|
|
||||||
|
r = qse_awk_rtx_makeintval (rtx, prev);
|
||||||
|
if (r == QSE_NULL) return -1;
|
||||||
|
|
||||||
|
qse_awk_rtx_setretval (rtx, r);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
@ -478,10 +553,12 @@ static fnctab_t fnctab[] =
|
|||||||
{ QSE_T("floor"), { { 1, 1, QSE_NULL }, fnc_floor, 0 } },
|
{ QSE_T("floor"), { { 1, 1, QSE_NULL }, fnc_floor, 0 } },
|
||||||
{ QSE_T("log"), { { 1, 1, QSE_NULL }, fnc_log, 0 } },
|
{ QSE_T("log"), { { 1, 1, QSE_NULL }, fnc_log, 0 } },
|
||||||
{ QSE_T("log10"), { { 1, 1, QSE_NULL }, fnc_log10, 0 } },
|
{ QSE_T("log10"), { { 1, 1, QSE_NULL }, fnc_log10, 0 } },
|
||||||
|
{ QSE_T("rand"), { { 0, 0, QSE_NULL }, fnc_rand, 0 } },
|
||||||
{ QSE_T("round"), { { 1, 1, QSE_NULL }, fnc_round, 0 } },
|
{ QSE_T("round"), { { 1, 1, QSE_NULL }, fnc_round, 0 } },
|
||||||
{ QSE_T("sin"), { { 1, 1, QSE_NULL }, fnc_sin, 0 } },
|
{ QSE_T("sin"), { { 1, 1, QSE_NULL }, fnc_sin, 0 } },
|
||||||
{ QSE_T("sinh"), { { 1, 1, QSE_NULL }, fnc_sinh, 0 } },
|
{ QSE_T("sinh"), { { 1, 1, QSE_NULL }, fnc_sinh, 0 } },
|
||||||
{ QSE_T("sqrt"), { { 1, 1, QSE_NULL }, fnc_sqrt, 0 } },
|
{ QSE_T("sqrt"), { { 1, 1, QSE_NULL }, fnc_sqrt, 0 } },
|
||||||
|
{ QSE_T("srand"), { { 0, 1, QSE_NULL }, fnc_srand, 0 } },
|
||||||
{ QSE_T("tan"), { { 1, 1, QSE_NULL }, fnc_tan, 0 } },
|
{ QSE_T("tan"), { { 1, 1, QSE_NULL }, fnc_tan, 0 } },
|
||||||
{ QSE_T("tanh"), { { 1, 1, QSE_NULL }, fnc_tanh, 0 } }
|
{ QSE_T("tanh"), { { 1, 1, QSE_NULL }, fnc_tanh, 0 } }
|
||||||
};
|
};
|
||||||
@ -541,27 +618,44 @@ static int init (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
|
|||||||
|
|
||||||
static void fini (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
|
static void fini (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
|
||||||
{
|
{
|
||||||
/* TODO:
|
/* TODO: anything */
|
||||||
for (each pid for rtx) kill (pid, SIGKILL);
|
|
||||||
for (each pid for rtx) waitpid (pid, QSE_NULL, 0);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unload (qse_awk_mod_t* mod, qse_awk_t* awk)
|
static void unload (qse_awk_mod_t* mod, qse_awk_t* awk)
|
||||||
{
|
{
|
||||||
/* TODO: anything */
|
modctx_t* modctx;
|
||||||
|
|
||||||
|
modctx = (modctx_t*)mod->ctx;
|
||||||
|
qse_awk_freemem (awk, modctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_awk_mod_math (qse_awk_mod_t* mod, qse_awk_t* awk)
|
int qse_awk_mod_math (qse_awk_mod_t* mod, qse_awk_t* awk)
|
||||||
{
|
{
|
||||||
|
modctx_t* modctx;
|
||||||
|
qse_ntime_t now;
|
||||||
|
|
||||||
|
modctx = qse_awk_allocmem (awk, QSE_SIZEOF(*modctx));
|
||||||
|
if (modctx == QSE_NULL)
|
||||||
|
{
|
||||||
|
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSE_MEMSET (modctx, 0, QSE_SIZEOF(*modctx));
|
||||||
|
|
||||||
|
modctx->seed = (qse_gettime (&now) <= -1)? 0u: ((qse_awk_int_t)now.sec + (qse_awk_int_t)now.nsec);
|
||||||
|
/* i don't care if the seed becomes negative or overflows.
|
||||||
|
* i just convert the signed value to the unsigned one. */
|
||||||
|
modctx->prand = (qse_awk_uint_t)(modctx->seed * modctx->seed * modctx->seed);
|
||||||
|
/* make sure that the actual seeding is not 0 */
|
||||||
|
if (modctx->prand == 0) modctx->prand++;
|
||||||
|
|
||||||
mod->query = query;
|
mod->query = query;
|
||||||
mod->unload = unload;
|
mod->unload = unload;
|
||||||
|
|
||||||
mod->init = init;
|
mod->init = init;
|
||||||
mod->fini = fini;
|
mod->fini = fini;
|
||||||
/*
|
mod->ctx = modctx;
|
||||||
mod->ctx...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -301,10 +301,7 @@ static int init (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
|
|||||||
|
|
||||||
static void fini (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
|
static void fini (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
|
||||||
{
|
{
|
||||||
/* TODO:
|
/* TODO: anything */
|
||||||
for (each pid for rtx) kill (pid, SIGKILL);
|
|
||||||
for (each pid for rtx) waitpid (pid, QSE_NULL, 0);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unload (qse_awk_mod_t* mod, qse_awk_t* awk)
|
static void unload (qse_awk_mod_t* mod, qse_awk_t* awk)
|
||||||
|
@ -23,11 +23,13 @@
|
|||||||
#include <qse/cmn/time.h>
|
#include <qse/cmn/time.h>
|
||||||
#include <qse/cmn/nwif.h>
|
#include <qse/cmn/nwif.h>
|
||||||
#include <qse/cmn/nwad.h>
|
#include <qse/cmn/nwad.h>
|
||||||
|
#include <qse/cmn/mbwc.h>
|
||||||
#include "../cmn/mem.h"
|
#include "../cmn/mem.h"
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
# include <process.h>
|
# include <process.h>
|
||||||
|
# include <tchar.h>
|
||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
# define INCL_DOSPROCESS
|
# define INCL_DOSPROCESS
|
||||||
# define INCL_DOSEXCEPTIONS
|
# define INCL_DOSEXCEPTIONS
|
||||||
@ -42,7 +44,7 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h> /* getenv */
|
#include <stdlib.h> /* getenv, system */
|
||||||
|
|
||||||
static int fnc_fork (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
static int fnc_fork (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||||
{
|
{
|
||||||
@ -597,6 +599,56 @@ static int fnc_getnwifcfg (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fnc_system (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||||
|
{
|
||||||
|
qse_awk_val_t* v, * a0;
|
||||||
|
qse_char_t* str;
|
||||||
|
qse_size_t len;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
a0 = qse_awk_rtx_getarg (rtx, 0);
|
||||||
|
str = qse_awk_rtx_getvalstr (rtx, a0, &len);
|
||||||
|
if (str == QSE_NULL) return -1;
|
||||||
|
|
||||||
|
/* the target name contains a null character.
|
||||||
|
* make system return -1 */
|
||||||
|
if (qse_strxchr (str, len, QSE_T('\0')))
|
||||||
|
{
|
||||||
|
n = -1;
|
||||||
|
goto skip_system;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
n = _tsystem (str);
|
||||||
|
#elif defined(QSE_CHAR_IS_MCHAR)
|
||||||
|
n = system (str);
|
||||||
|
#else
|
||||||
|
|
||||||
|
{
|
||||||
|
qse_mchar_t* mbs;
|
||||||
|
mbs = qse_wcstombsdup (str, QSE_NULL, qse_awk_rtx_getmmgr(rtx));
|
||||||
|
if (mbs == QSE_NULL)
|
||||||
|
{
|
||||||
|
n = -1;
|
||||||
|
goto skip_system;
|
||||||
|
}
|
||||||
|
n = system (mbs);
|
||||||
|
qse_awk_rtx_freemem (rtx, mbs);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
skip_system:
|
||||||
|
qse_awk_rtx_freevalstr (rtx, a0, str);
|
||||||
|
|
||||||
|
v = qse_awk_rtx_makeintval (rtx, (qse_awk_int_t)n);
|
||||||
|
if (v == QSE_NULL) return -1;
|
||||||
|
|
||||||
|
qse_awk_rtx_setretval (rtx, v);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct fnctab_t fnctab_t;
|
typedef struct fnctab_t fnctab_t;
|
||||||
struct fnctab_t
|
struct fnctab_t
|
||||||
{
|
{
|
||||||
@ -630,6 +682,7 @@ static fnctab_t fnctab[] =
|
|||||||
{ QSE_T("kill"), { { 2, 2, QSE_NULL }, fnc_kill, 0 } },
|
{ QSE_T("kill"), { { 2, 2, QSE_NULL }, fnc_kill, 0 } },
|
||||||
{ QSE_T("settime"), { { 1, 1, QSE_NULL }, fnc_settime, 0 } },
|
{ QSE_T("settime"), { { 1, 1, QSE_NULL }, fnc_settime, 0 } },
|
||||||
{ QSE_T("sleep"), { { 1, 1, QSE_NULL }, fnc_sleep, 0 } },
|
{ QSE_T("sleep"), { { 1, 1, QSE_NULL }, fnc_sleep, 0 } },
|
||||||
|
{ QSE_T("system"), { { 1, 1, QSE_NULL }, fnc_system, 0 } },
|
||||||
{ QSE_T("wait"), { { 1, 1, QSE_NULL }, fnc_wait, 0 } }
|
{ QSE_T("wait"), { { 1, 1, QSE_NULL }, fnc_wait, 0 } }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2089,7 +2089,7 @@ static qse_awk_nde_t* parse_if (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: optimization. if you know 'tese' evaluates to true or false,
|
/* TODO: optimization. if you know 'test' evaluates to true or false,
|
||||||
* you can drop the 'if' statement and take either the 'then_part'
|
* you can drop the 'if' statement and take either the 'then_part'
|
||||||
* or 'else_part'. */
|
* or 'else_part'. */
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
#include <qse/cmn/path.h>
|
#include <qse/cmn/path.h>
|
||||||
#include <qse/cmn/htb.h>
|
#include <qse/cmn/htb.h>
|
||||||
#include <qse/cmn/env.h>
|
#include <qse/cmn/env.h>
|
||||||
#include <qse/cmn/alg.h>
|
|
||||||
#include "../cmn/mem.h"
|
#include "../cmn/mem.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -113,9 +112,6 @@ typedef struct xtn_t
|
|||||||
|
|
||||||
typedef struct rxtn_t
|
typedef struct rxtn_t
|
||||||
{
|
{
|
||||||
qse_awk_int_t seed;
|
|
||||||
qse_awk_uint_t prand; /* last random value returned */
|
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
@ -1903,7 +1899,6 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
|
|||||||
qse_awk_rio_t rio;
|
qse_awk_rio_t rio;
|
||||||
rxtn_t* rxtn;
|
rxtn_t* rxtn;
|
||||||
xtn_t* xtn;
|
xtn_t* xtn;
|
||||||
qse_ntime_t now;
|
|
||||||
|
|
||||||
xtn = (xtn_t*)QSE_XTN (awk);
|
xtn = (xtn_t*)QSE_XTN (awk);
|
||||||
|
|
||||||
@ -1938,13 +1933,6 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
|
|||||||
rxtn->ecb.close = fini_rxtn;
|
rxtn->ecb.close = fini_rxtn;
|
||||||
qse_awk_rtx_pushecb (rtx, &rxtn->ecb);
|
qse_awk_rtx_pushecb (rtx, &rxtn->ecb);
|
||||||
|
|
||||||
rxtn->seed = (qse_gettime (&now) <= -1)? 0u: ((qse_awk_int_t)now.sec + (qse_awk_int_t)now.nsec);
|
|
||||||
/* i don't care if the seed becomes negative or overflows.
|
|
||||||
* i just convert the signed value to the unsigned one. */
|
|
||||||
rxtn->prand = (qse_awk_uint_t)(rxtn->seed * rxtn->seed * rxtn->seed);
|
|
||||||
/* make sure that the actual seeding is not 0 */
|
|
||||||
if (rxtn->prand == 0) rxtn->prand++;
|
|
||||||
|
|
||||||
rxtn->c.in.files = icf;
|
rxtn->c.in.files = icf;
|
||||||
rxtn->c.in.index = 0;
|
rxtn->c.in.index = 0;
|
||||||
rxtn->c.in.count = 0;
|
rxtn->c.in.count = 0;
|
||||||
@ -1990,120 +1978,6 @@ void* qse_awk_rtx_getxtnstd (qse_awk_rtx_t* rtx)
|
|||||||
return (void*)((rxtn_t*)QSE_XTN(rtx) + 1);
|
return (void*)((rxtn_t*)QSE_XTN(rtx) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fnc_rand (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
|
||||||
{
|
|
||||||
#define RANDV_MAX QSE_TYPE_MAX(qse_awk_int_t)
|
|
||||||
qse_awk_val_t* r;
|
|
||||||
qse_awk_int_t randv;
|
|
||||||
rxtn_t* rxtn;
|
|
||||||
|
|
||||||
rxtn = (rxtn_t*) QSE_XTN (rtx);
|
|
||||||
|
|
||||||
#if defined(QSE_USE_AWK_INTMAX)
|
|
||||||
rxtn->prand = qse_randxsuintmax (rxtn->prand);
|
|
||||||
#else
|
|
||||||
rxtn->prand = qse_randxsulong (rxtn->prand);
|
|
||||||
#endif
|
|
||||||
randv = rxtn->prand % RANDV_MAX;
|
|
||||||
|
|
||||||
r = qse_awk_rtx_makefltval (rtx, (qse_awk_flt_t)randv / RANDV_MAX);
|
|
||||||
if (r == QSE_NULL) return -1;
|
|
||||||
|
|
||||||
qse_awk_rtx_setretval (rtx, r);
|
|
||||||
return 0;
|
|
||||||
#undef RANDV_MAX
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fnc_srand (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
|
||||||
{
|
|
||||||
qse_size_t nargs;
|
|
||||||
qse_awk_val_t* a0;
|
|
||||||
qse_awk_int_t lv;
|
|
||||||
qse_awk_val_t* r;
|
|
||||||
int n;
|
|
||||||
qse_awk_int_t prev;
|
|
||||||
qse_ntime_t now;
|
|
||||||
rxtn_t* rxtn;
|
|
||||||
|
|
||||||
rxtn = (rxtn_t*) QSE_XTN (rtx);
|
|
||||||
nargs = qse_awk_rtx_getnargs (rtx);
|
|
||||||
QSE_ASSERT (nargs == 0 || nargs == 1);
|
|
||||||
|
|
||||||
prev = rxtn->seed;
|
|
||||||
|
|
||||||
if (nargs <= 0)
|
|
||||||
{
|
|
||||||
rxtn->seed = (qse_gettime (&now) <= -1)?
|
|
||||||
(rxtn->seed * rxtn->seed): ((qse_awk_int_t)now.sec + (qse_awk_int_t)now.nsec);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
a0 = qse_awk_rtx_getarg (rtx, 0);
|
|
||||||
n = qse_awk_rtx_valtoint (rtx, a0, &lv);
|
|
||||||
if (n <= -1) return -1;
|
|
||||||
rxtn->seed = lv;
|
|
||||||
}
|
|
||||||
/* i don't care if the seed becomes negative or overflows.
|
|
||||||
* i just convert the signed value to the unsigned one. */
|
|
||||||
rxtn->prand = (qse_awk_uint_t)(rxtn->seed * rxtn->seed * rxtn->seed);
|
|
||||||
/* make sure that the actual seeding is not 0 */
|
|
||||||
if (rxtn->prand == 0) rxtn->prand++;
|
|
||||||
|
|
||||||
r = qse_awk_rtx_makeintval (rtx, prev);
|
|
||||||
if (r == QSE_NULL) return -1;
|
|
||||||
|
|
||||||
qse_awk_rtx_setretval (rtx, r);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fnc_system (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
|
||||||
{
|
|
||||||
qse_awk_val_t* v, * a0;
|
|
||||||
qse_char_t* str;
|
|
||||||
qse_size_t len;
|
|
||||||
int n = 0;
|
|
||||||
|
|
||||||
a0 = qse_awk_rtx_getarg (rtx, 0);
|
|
||||||
str = qse_awk_rtx_getvalstr (rtx, a0, &len);
|
|
||||||
if (str == QSE_NULL) return -1;
|
|
||||||
|
|
||||||
/* the target name contains a null character.
|
|
||||||
* make system return -1 */
|
|
||||||
if (qse_strxchr (str, len, QSE_T('\0')))
|
|
||||||
{
|
|
||||||
n = -1;
|
|
||||||
goto skip_system;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
n = _tsystem (str);
|
|
||||||
#elif defined(QSE_CHAR_IS_MCHAR)
|
|
||||||
n = system (str);
|
|
||||||
#else
|
|
||||||
|
|
||||||
{
|
|
||||||
qse_mchar_t* mbs;
|
|
||||||
mbs = qse_wcstombsdup (str, QSE_NULL, rtx->awk->mmgr);
|
|
||||||
if (mbs == QSE_NULL)
|
|
||||||
{
|
|
||||||
n = -1;
|
|
||||||
goto skip_system;
|
|
||||||
}
|
|
||||||
n = system (mbs);
|
|
||||||
QSE_AWK_FREE (rtx->awk, mbs);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
skip_system:
|
|
||||||
qse_awk_rtx_freevalstr (rtx, a0, str);
|
|
||||||
|
|
||||||
v = qse_awk_rtx_makeintval (rtx, (qse_awk_int_t)n);
|
|
||||||
if (v == QSE_NULL) return -1;
|
|
||||||
|
|
||||||
qse_awk_rtx_setretval (rtx, v);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int timeout_code (const qse_char_t* name)
|
static int timeout_code (const qse_char_t* name)
|
||||||
{
|
{
|
||||||
@ -2407,11 +2281,14 @@ struct fnctab_t
|
|||||||
|
|
||||||
static struct fnctab_t fnctab[] =
|
static struct fnctab_t fnctab[] =
|
||||||
{
|
{
|
||||||
{ QSE_T("rand"), { {0, 0, QSE_NULL}, fnc_rand, 0 } },
|
/* additional aliases to module functions */
|
||||||
{ QSE_T("srand"), { {0, 1, QSE_NULL}, fnc_srand, 0 } },
|
{ QSE_T("rand"), { {1, 0, QSE_T("math")}, QSE_NULL, 0 } },
|
||||||
{ QSE_T("system"), { {1, 1, QSE_NULL}, fnc_system , 0 } },
|
{ QSE_T("srand"), { {1, 0, QSE_T("math")}, QSE_NULL, 0 } },
|
||||||
{ QSE_T("setioattr"), { {3, 3, QSE_NULL}, fnc_setioattr, QSE_AWK_RIO } },
|
{ QSE_T("system"), { {1, 0, QSE_T("sys")}, QSE_NULL , 0 } },
|
||||||
{ QSE_T("getioattr"), { {3, 3, QSE_T("vvr")}, fnc_getioattr, QSE_AWK_RIO } }
|
|
||||||
|
/* additional functions */
|
||||||
|
{ QSE_T("setioattr"), { {3, 3, QSE_NULL}, fnc_setioattr, QSE_AWK_RIO } },
|
||||||
|
{ QSE_T("getioattr"), { {3, 3, QSE_T("vvr")}, fnc_getioattr, QSE_AWK_RIO } }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int add_functions (qse_awk_t* awk)
|
static int add_functions (qse_awk_t* awk)
|
||||||
|
Loading…
Reference in New Issue
Block a user