added ENVIRON and PROCINFO for unix/linux
This commit is contained in:
parent
d6c8bd4a1b
commit
c7cea1d985
@ -1560,8 +1560,8 @@ qse_size_t qse_awk_longtostr (
|
|||||||
* You can get the pointer to the beginning of the block with
|
* You can get the pointer to the beginning of the block with
|
||||||
* qse_awk_rtx_getxtn(). The block is destroyed when the runtime context is
|
* qse_awk_rtx_getxtn(). The block is destroyed when the runtime context is
|
||||||
* destroyed. The argument array @a arg, if not #QSE_NULL, is used to set
|
* destroyed. The argument array @a arg, if not #QSE_NULL, is used to set
|
||||||
* @b ARGV. The @b ptr field and the @b len field of the last member of the
|
* @b ARGV. The @b ptr field and the @b len field of the last member of
|
||||||
* array must be set to #QSE_NULL and 0 respectively.
|
* this array must be set to #QSE_NULL and 0 respectively.
|
||||||
*
|
*
|
||||||
* @return new runtime context on success, #QSE_NULL on failure
|
* @return new runtime context on success, #QSE_NULL on failure
|
||||||
*/
|
*/
|
||||||
|
@ -1094,8 +1094,7 @@ static int build_runarg (
|
|||||||
|
|
||||||
qse_awk_rtx_refupval (rtx, v_argv);
|
qse_awk_rtx_refupval (rtx, v_argv);
|
||||||
|
|
||||||
if (runarg == QSE_NULL) argc = 0;
|
if (runarg)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
for (argc = 0, p = runarg; p->ptr != QSE_NULL; argc++, p++)
|
for (argc = 0, p = runarg; p->ptr != QSE_NULL; argc++, p++)
|
||||||
{
|
{
|
||||||
@ -1132,6 +1131,7 @@ static int build_runarg (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else argc = 0;
|
||||||
|
|
||||||
v_argc = qse_awk_rtx_makeintval (rtx, (qse_long_t)argc);
|
v_argc = qse_awk_rtx_makeintval (rtx, (qse_long_t)argc);
|
||||||
if (v_argc == QSE_NULL)
|
if (v_argc == QSE_NULL)
|
||||||
@ -1241,10 +1241,10 @@ static int prepare_globals (qse_awk_rtx_t* rtx, const qse_cstr_t* runarg)
|
|||||||
|
|
||||||
/* override NF to zero */
|
/* override NF to zero */
|
||||||
if (qse_awk_rtx_setgbl (
|
if (qse_awk_rtx_setgbl (
|
||||||
rtx, QSE_AWK_GBL_NF, qse_awk_val_zero) == -1) goto oops;
|
rtx, QSE_AWK_GBL_NF, qse_awk_val_zero) <= -1) goto oops;
|
||||||
|
|
||||||
/* override ARGC and ARGV if necessary */
|
/* override ARGC and ARGV if necessary */
|
||||||
if (runarg && build_runarg (rtx, runarg, &nrunargs) == -1) goto oops;
|
if (runarg && build_runarg (rtx, runarg, &nrunargs) <= -1) goto oops;
|
||||||
|
|
||||||
/* return success */
|
/* return success */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <qse/cmn/time.h>
|
#include <qse/cmn/time.h>
|
||||||
#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/stdio.h> /* TODO: remove dependency on qse_vsprintf */
|
#include <qse/cmn/stdio.h> /* TODO: remove dependency on qse_vsprintf */
|
||||||
#include "../cmn/mem.h"
|
#include "../cmn/mem.h"
|
||||||
|
|
||||||
@ -37,6 +38,12 @@
|
|||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
# include <tchar.h>
|
# include <tchar.h>
|
||||||
|
#elif defined(__OS2__)
|
||||||
|
/* anything ? */
|
||||||
|
#elif defined(__DOS__)
|
||||||
|
/* anything ? */
|
||||||
|
#else
|
||||||
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef QSE_HAVE_CONFIG_H
|
#ifndef QSE_HAVE_CONFIG_H
|
||||||
@ -94,6 +101,8 @@ typedef struct xtn_t
|
|||||||
} out;
|
} out;
|
||||||
} s; /* script/source handling */
|
} s; /* script/source handling */
|
||||||
|
|
||||||
|
int gbl_environ;
|
||||||
|
int gbl_procinfo;
|
||||||
} xtn_t;
|
} xtn_t;
|
||||||
|
|
||||||
typedef struct rxtn_t
|
typedef struct rxtn_t
|
||||||
@ -288,6 +297,7 @@ static int custom_awk_sprintf (
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int add_globals (qse_awk_t* awk);
|
||||||
static int add_functions (qse_awk_t* awk);
|
static int add_functions (qse_awk_t* awk);
|
||||||
|
|
||||||
qse_awk_t* qse_awk_openstd (qse_size_t xtnsize)
|
qse_awk_t* qse_awk_openstd (qse_size_t xtnsize)
|
||||||
@ -323,8 +333,9 @@ qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize)
|
|||||||
xtn = (xtn_t*) QSE_XTN (awk);
|
xtn = (xtn_t*) QSE_XTN (awk);
|
||||||
QSE_MEMSET (xtn, 0, QSE_SIZEOF(xtn_t));
|
QSE_MEMSET (xtn, 0, QSE_SIZEOF(xtn_t));
|
||||||
|
|
||||||
/* add intrinsic functions */
|
/* add intrinsic global variables and functions */
|
||||||
if (add_functions (awk) <= -1)
|
if (add_globals(awk) <= -1 ||
|
||||||
|
add_functions (awk) <= -1)
|
||||||
{
|
{
|
||||||
qse_awk_close (awk);
|
qse_awk_close (awk);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
@ -1468,6 +1479,262 @@ static void fini_rxtn (qse_awk_rtx_t* rtx, void* ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __build_environ (
|
||||||
|
qse_awk_rtx_t* rtx, int gbl_id, qse_env_char_t* envarr[])
|
||||||
|
{
|
||||||
|
qse_awk_val_t* v_env;
|
||||||
|
qse_awk_val_t* v_tmp;
|
||||||
|
|
||||||
|
v_env = qse_awk_rtx_makemapval (rtx);
|
||||||
|
if (v_env == QSE_NULL) return -1;
|
||||||
|
|
||||||
|
qse_awk_rtx_refupval (rtx, v_env);
|
||||||
|
|
||||||
|
if (envarr)
|
||||||
|
{
|
||||||
|
qse_env_char_t* eq;
|
||||||
|
qse_char_t* kptr, * vptr;
|
||||||
|
qse_size_t klen, count;
|
||||||
|
|
||||||
|
for (count = 0; envarr[count]; count++)
|
||||||
|
{
|
||||||
|
#if ((defined(QSE_ENV_CHAR_IS_MCHAR) && defined(QSE_CHAR_IS_MCHAR)) || \
|
||||||
|
(defined(QSE_ENV_CHAR_IS_WCHAR) && defined(QSE_CHAR_IS_WCHAR)))
|
||||||
|
eq = qse_strchr (envarr[count], QSE_T('='));
|
||||||
|
if (eq == QSE_NULL || eq == envarr[count]) continue;
|
||||||
|
|
||||||
|
kptr = envarr[count];
|
||||||
|
klen = eq - envarr[count];
|
||||||
|
vptr = eq + 1;
|
||||||
|
#elif defined(QSE_ENV_CHAR_IS_MCHAR)
|
||||||
|
eq = qse_mbschr (envarr[count], QSE_MT('='));
|
||||||
|
if (eq == QSE_NULL || eq == envarr[count]) continue;
|
||||||
|
|
||||||
|
*eq = QSE_MT('\0');
|
||||||
|
|
||||||
|
kptr = qse_mbstowcsdup (envarr[count], rtx->awk->mmgr);
|
||||||
|
vptr = qse_mbstowcsdup (eq + 1, rtx->awk->mmgr);
|
||||||
|
if (kptr == QSE_NULL || vptr == QSE_NULL)
|
||||||
|
{
|
||||||
|
if (kptr) QSE_MMGR_FREE (rtx->awk->mmgr, kptr);
|
||||||
|
qse_awk_rtx_refdownval (rtx, v_env);
|
||||||
|
|
||||||
|
/* mbstowcsdup() may fail for invalid encoding.
|
||||||
|
* so setting the error code to ENOMEM may not
|
||||||
|
* be really accurate */
|
||||||
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
klen = qse_wcslen (kptr);
|
||||||
|
*eq = QSE_MT('=');
|
||||||
|
#else
|
||||||
|
eq = qse_wcschr (envarr[count], QSE_WT('='));
|
||||||
|
if (eq == QSE_NULL || eq == envarr[count]) continue;
|
||||||
|
|
||||||
|
*eq = QSE_WT('\0');
|
||||||
|
|
||||||
|
kptr = qse_wcstombsdup (envarr[count], rtx->awk->mmgr);
|
||||||
|
vptr = qse_wcstombsdup (eq + 1, rtx->awk->mmgr);
|
||||||
|
if (kptr == QSE_NULL || vptr == QSE_NULL)
|
||||||
|
{
|
||||||
|
if (kptr) QSE_MMGR_FREE (rtx->awk->mmgr, kptr);
|
||||||
|
qse_awk_rtx_refdownval (rtx, v_env);
|
||||||
|
|
||||||
|
/* mbstowcsdup() may fail for invalid encoding.
|
||||||
|
* so setting the error code to ENOMEM may not
|
||||||
|
* be really accurate */
|
||||||
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
klen = qse_mbslen (kptr);
|
||||||
|
*eq = QSE_WT('=');
|
||||||
|
#endif
|
||||||
|
|
||||||
|
v_tmp = qse_awk_rtx_makestrval0 (rtx, vptr);
|
||||||
|
if (v_tmp == QSE_NULL)
|
||||||
|
{
|
||||||
|
#if ((defined(QSE_ENV_CHAR_IS_MCHAR) && defined(QSE_CHAR_IS_MCHAR)) || \
|
||||||
|
(defined(QSE_ENV_CHAR_IS_WCHAR) && defined(QSE_CHAR_IS_WCHAR)))
|
||||||
|
/* nothing to do */
|
||||||
|
#else
|
||||||
|
if (vptr) QSE_MMGR_FREE (rtx->awk->mmgr, vptr);
|
||||||
|
if (kptr) QSE_MMGR_FREE (rtx->awk->mmgr, kptr);
|
||||||
|
#endif
|
||||||
|
qse_awk_rtx_refdownval (rtx, v_env);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* increment reference count of v_tmp in advance as if
|
||||||
|
* it has successfully been assigned into ARGV. */
|
||||||
|
qse_awk_rtx_refupval (rtx, v_tmp);
|
||||||
|
|
||||||
|
if (qse_htb_upsert (
|
||||||
|
((qse_awk_val_map_t*)v_env)->map,
|
||||||
|
kptr, klen, v_tmp, 0) == QSE_NULL)
|
||||||
|
{
|
||||||
|
/* if the assignment operation fails, decrements
|
||||||
|
* the reference of v_tmp to free it */
|
||||||
|
qse_awk_rtx_refdownval (rtx, v_tmp);
|
||||||
|
|
||||||
|
#if ((defined(QSE_ENV_CHAR_IS_MCHAR) && defined(QSE_CHAR_IS_MCHAR)) || \
|
||||||
|
(defined(QSE_ENV_CHAR_IS_WCHAR) && defined(QSE_CHAR_IS_WCHAR)))
|
||||||
|
/* nothing to do */
|
||||||
|
#else
|
||||||
|
if (vptr) QSE_MMGR_FREE (rtx->awk->mmgr, vptr);
|
||||||
|
if (kptr) QSE_MMGR_FREE (rtx->awk->mmgr, kptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* the values previously assigned into the
|
||||||
|
* map will be freeed when v_env is freed */
|
||||||
|
qse_awk_rtx_refdownval (rtx, v_env);
|
||||||
|
|
||||||
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ((defined(QSE_ENV_CHAR_IS_MCHAR) && defined(QSE_CHAR_IS_MCHAR)) || \
|
||||||
|
(defined(QSE_ENV_CHAR_IS_WCHAR) && defined(QSE_CHAR_IS_WCHAR)))
|
||||||
|
/* nothing to do */
|
||||||
|
#else
|
||||||
|
if (vptr) QSE_MMGR_FREE (rtx->awk->mmgr, vptr);
|
||||||
|
if (kptr) QSE_MMGR_FREE (rtx->awk->mmgr, kptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qse_awk_rtx_setgbl (rtx, gbl_id, v_env) == -1)
|
||||||
|
{
|
||||||
|
qse_awk_rtx_refdownval (rtx, v_env);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_awk_rtx_refdownval (rtx, v_env);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int build_environ (qse_awk_rtx_t* rtx, int gbl_id)
|
||||||
|
{
|
||||||
|
qse_env_t env;
|
||||||
|
int xret;
|
||||||
|
|
||||||
|
if (qse_env_init (&env, rtx->awk->mmgr, 1) <= -1)
|
||||||
|
{
|
||||||
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
xret = __build_environ (rtx, gbl_id, qse_env_getarr(&env));
|
||||||
|
|
||||||
|
qse_env_fini (&env);
|
||||||
|
return xret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int build_procinfo (qse_awk_rtx_t* rtx, int gbl_id)
|
||||||
|
{
|
||||||
|
qse_awk_val_t* v_info;
|
||||||
|
qse_awk_val_t* v_tmp;
|
||||||
|
qse_size_t i;
|
||||||
|
|
||||||
|
static qse_cstr_t names[] =
|
||||||
|
{
|
||||||
|
{ QSE_T("pid"), 4 },
|
||||||
|
{ QSE_T("ppid"), 5 },
|
||||||
|
{ QSE_T("pgrp"), 4 },
|
||||||
|
{ QSE_T("uid"), 3 },
|
||||||
|
{ QSE_T("gid"), 3 },
|
||||||
|
{ QSE_T("euid"), 4 },
|
||||||
|
{ QSE_T("egid"), 4 }
|
||||||
|
};
|
||||||
|
|
||||||
|
v_info = qse_awk_rtx_makemapval (rtx);
|
||||||
|
if (v_info == QSE_NULL) return -1;
|
||||||
|
|
||||||
|
qse_awk_rtx_refupval (rtx, v_info);
|
||||||
|
|
||||||
|
if (qse_awk_rtx_setgbl (rtx, gbl_id, v_info) == -1)
|
||||||
|
{
|
||||||
|
qse_awk_rtx_refdownval (rtx, v_info);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < QSE_COUNTOF(names); i++)
|
||||||
|
{
|
||||||
|
qse_long_t val;
|
||||||
|
|
||||||
|
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
val = getpid();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
val = getppid();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
val = getpgrp();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
val = getuid();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
val = getgid();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
val = geteuid();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
val = getegid();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
v_tmp = qse_awk_rtx_makeintval (rtx, val);
|
||||||
|
if (v_tmp == QSE_NULL)
|
||||||
|
{
|
||||||
|
qse_awk_rtx_refdownval (rtx, v_info);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* increment reference count of v_tmp in advance as if
|
||||||
|
* it has successfully been assigned into ARGV. */
|
||||||
|
qse_awk_rtx_refupval (rtx, v_tmp);
|
||||||
|
|
||||||
|
if (qse_htb_upsert (
|
||||||
|
((qse_awk_val_map_t*)v_info)->map,
|
||||||
|
names[i].ptr, names[i].len, v_tmp, 0) == QSE_NULL)
|
||||||
|
{
|
||||||
|
/* if the assignment operation fails, decrements
|
||||||
|
* the reference of v_tmp to free it */
|
||||||
|
qse_awk_rtx_refdownval (rtx, v_tmp);
|
||||||
|
|
||||||
|
/* the values previously assigned into the
|
||||||
|
* map will be freeed when v_env is freed */
|
||||||
|
qse_awk_rtx_refdownval (rtx, v_info);
|
||||||
|
|
||||||
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_awk_rtx_refdownval (rtx, v_info);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int make_additional_globals (qse_awk_rtx_t* rtx, xtn_t* xtn)
|
||||||
|
{
|
||||||
|
if (build_environ (rtx, xtn->gbl_environ) <= -1) return -1;
|
||||||
|
if (build_procinfo (rtx, xtn->gbl_procinfo) <= -1) return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
qse_awk_rtx_t* qse_awk_rtx_openstd (
|
qse_awk_rtx_t* qse_awk_rtx_openstd (
|
||||||
qse_awk_t* awk,
|
qse_awk_t* awk,
|
||||||
qse_size_t xtnsize,
|
qse_size_t xtnsize,
|
||||||
@ -1486,12 +1753,17 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
|
|||||||
qse_awk_rtx_t* rtx;
|
qse_awk_rtx_t* rtx;
|
||||||
qse_awk_rio_t rio;
|
qse_awk_rio_t rio;
|
||||||
rxtn_t* rxtn;
|
rxtn_t* rxtn;
|
||||||
|
xtn_t* xtn;
|
||||||
qse_ntime_t now;
|
qse_ntime_t now;
|
||||||
|
|
||||||
const qse_char_t*const* p;
|
const qse_char_t*const* p;
|
||||||
|
qse_cstr_t* p2;
|
||||||
|
|
||||||
qse_size_t argc = 0;
|
qse_size_t argc = 0;
|
||||||
qse_cstr_t argv[16];
|
qse_cstr_t argv[16];
|
||||||
qse_cstr_t* argvp = QSE_NULL, * p2;
|
qse_cstr_t* argvp = QSE_NULL;
|
||||||
|
|
||||||
|
xtn = (xtn_t*)QSE_XTN (awk);
|
||||||
|
|
||||||
rio.pipe = awk_rio_pipe;
|
rio.pipe = awk_rio_pipe;
|
||||||
rio.file = awk_rio_file;
|
rio.file = awk_rio_file;
|
||||||
@ -1599,6 +1871,13 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (make_additional_globals (rtx, xtn) <= -1)
|
||||||
|
{
|
||||||
|
awk->errinf = rtx->errinf; /* transfer error info */
|
||||||
|
qse_awk_rtx_close (rtx);
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return rtx;
|
return rtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2014,7 +2293,7 @@ done:
|
|||||||
/* the return value of -1 for an error may be confusing since
|
/* the return value of -1 for an error may be confusing since
|
||||||
* a literal value of -1 can be returned for some attribute
|
* a literal value of -1 can be returned for some attribute
|
||||||
* names */
|
* names */
|
||||||
if (rv == QSE_NULL) rv = qse_awk_rtx_makeintval (rtx, -1);;
|
if (rv == QSE_NULL) rv = qse_awk_val_negone;
|
||||||
qse_awk_rtx_setretval (rtx, rv);
|
qse_awk_rtx_setretval (rtx, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2037,6 +2316,21 @@ qse_cmgr_t* qse_awk_rtx_getcmgrstd (
|
|||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int add_globals (qse_awk_t* awk)
|
||||||
|
{
|
||||||
|
xtn_t* xtn;
|
||||||
|
|
||||||
|
xtn = (xtn_t*) QSE_XTN (awk);
|
||||||
|
|
||||||
|
xtn->gbl_environ = qse_awk_addgbl (awk, QSE_T("ENVIRON"), 7);
|
||||||
|
if (xtn->gbl_environ <= -1) return -1;
|
||||||
|
|
||||||
|
xtn->gbl_procinfo = qse_awk_addgbl (awk, QSE_T("PROCINFO"), 8);
|
||||||
|
if (xtn->gbl_procinfo <= -1) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#define ADDFNC(awk,name,min,max,fnc,valid) \
|
#define ADDFNC(awk,name,min,max,fnc,valid) \
|
||||||
if (qse_awk_addfnc (\
|
if (qse_awk_addfnc (\
|
||||||
(awk), (name), qse_strlen(name), \
|
(awk), (name), qse_strlen(name), \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user