moved ARGC and ARGV to base to std for simplication of the base implementation.
note C++ wrappers need the same changes
This commit is contained in:
		| @ -71,11 +71,10 @@ | ||||
|  * qse_awk_rtx_t* rtx; | ||||
|  * qse_awk_sio_t sio; // need to initialize it with callback functions | ||||
|  * qse_awk_rio_t rio; // need to initialize it with callback functions | ||||
|  * qse_cstr_t args[5]; // need to initialize it with strings | ||||
|  * | ||||
|  * awk = qse_awk_open (mmgr, 0, prm); // create an interpreter  | ||||
|  * qse_awk_parse (awk, &sio);          // parse a script  | ||||
|  * rtx = qse_awk_rtx_open (awk, 0, &rio, args); // create a runtime context  | ||||
|  * rtx = qse_awk_rtx_open (awk, 0, &rio); // create a runtime context  | ||||
|  * retv = qse_awk_rtx_loop (rtx);     // run a standard AWK loop  | ||||
|  * if (retv != QSE_NULL)  | ||||
|  *    qse_awk_rtx_refdownval (rtx, retv); // free return value | ||||
| @ -1029,10 +1028,15 @@ enum qse_awk_gbl_id_t | ||||
| { | ||||
| 	/* this table should match gtab in parse.c. | ||||
| 	 * in addition, qse_awk_rtx_setgbl also counts  | ||||
| 	 * on the order of these values */ | ||||
| 	 * on the order of these values. | ||||
| 	 *  | ||||
| 	 * note that set_global() in run.c contains code  | ||||
| 	 * preventing these global variables from being assigned | ||||
| 	 * with a map value. if you happen to add one that can  | ||||
| 	 * be a map, don't forget to change code in set_global(). | ||||
| 	 * but is this check really necessary??? | ||||
| 	 */ | ||||
|  | ||||
| 	QSE_AWK_GBL_ARGC, | ||||
| 	QSE_AWK_GBL_ARGV, | ||||
| 	QSE_AWK_GBL_CONVFMT, | ||||
| 	QSE_AWK_GBL_FILENAME, | ||||
| 	QSE_AWK_GBL_FNR, | ||||
| @ -1052,7 +1056,7 @@ enum qse_awk_gbl_id_t | ||||
| 	/* these are not not the actual IDs and are used internally only  | ||||
| 	 * Make sure you update these values properly if you add more  | ||||
| 	 * ID definitions, however */ | ||||
| 	QSE_AWK_MIN_GBL_ID = QSE_AWK_GBL_ARGC, | ||||
| 	QSE_AWK_MIN_GBL_ID = QSE_AWK_GBL_CONVFMT, | ||||
| 	QSE_AWK_MAX_GBL_ID = QSE_AWK_GBL_SUBSEP | ||||
| }; | ||||
| typedef enum qse_awk_gbl_id_t qse_awk_gbl_id_t; | ||||
| @ -1559,17 +1563,14 @@ qse_size_t qse_awk_longtostr ( | ||||
|  * It also allocates an extra memory block as large as the @a xtn bytes. | ||||
|  * 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 | ||||
|  * 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  | ||||
|  * this array must be set to #QSE_NULL and 0 respectively. | ||||
|  * destroyed.  | ||||
|  * | ||||
|  * @return new runtime context on success, #QSE_NULL on failure | ||||
|  */ | ||||
| qse_awk_rtx_t* qse_awk_rtx_open ( | ||||
| 	qse_awk_t*        awk, /**< awk */ | ||||
| 	qse_size_t        xtn, /**< size of extension in bytes */ | ||||
| 	qse_awk_rio_t*    rio, /**< runtime IO handlers */ | ||||
| 	const qse_cstr_t* arg /**< argument array to set ARGV */ | ||||
| 	qse_awk_rio_t*    rio  /**< runtime IO handlers */ | ||||
| ); | ||||
|  | ||||
| /** | ||||
|  | ||||
| @ -284,9 +284,6 @@ struct global_t | ||||
|  | ||||
| static global_t gtab[] = | ||||
| { | ||||
| 	{ QSE_T("ARGC"),         4,  0 }, | ||||
| 	{ QSE_T("ARGV"),         4,  0 }, | ||||
|  | ||||
| 	/* output real-to-str conversion format for other cases than 'print' */ | ||||
| 	{ QSE_T("CONVFMT"),      7,  0 }, | ||||
|  | ||||
|  | ||||
| @ -101,7 +101,7 @@ static qse_size_t push_arg_from_vals ( | ||||
| static int init_rtx (qse_awk_rtx_t* rtx, qse_awk_t* awk, qse_awk_rio_t* rio); | ||||
| static void fini_rtx (qse_awk_rtx_t* rtx, int fini_globals); | ||||
|  | ||||
| static int init_globals (qse_awk_rtx_t* rtx, const qse_cstr_t* arg); | ||||
| static int init_globals (qse_awk_rtx_t* rtx); | ||||
| static void refdown_globals (qse_awk_rtx_t* run, int pop); | ||||
|  | ||||
| static int run_pblocks  (qse_awk_rtx_t* rtx); | ||||
| @ -326,10 +326,12 @@ static int set_global ( | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	/* builtin variables except ARGV cannot be assigned a map */ | ||||
| 	if (val->type == QSE_AWK_VAL_MAP && | ||||
| 	    (idx >= QSE_AWK_GBL_ARGC && idx <= QSE_AWK_GBL_SUBSEP) && | ||||
| 	    idx != QSE_AWK_GBL_ARGV) | ||||
| 	/* all the basic builtin variables cannot be assigned a map. | ||||
| 	 * if you happen to add one and if that's allowed to be a map, | ||||
| 	 * you may have to change the condition here.  | ||||
| 	 * but is this check really necessary??? */ | ||||
| 	if (val->type == QSE_AWK_VAL_MAP &&  | ||||
| 	    idx >= QSE_AWK_MIN_GBL_ID && idx <= QSE_AWK_MAX_GBL_ID) | ||||
| 	{ | ||||
| 		/* TODO: better error code */ | ||||
| 		SETERR_COD (rtx, QSE_AWK_ESCALARTOMAP); | ||||
| @ -686,8 +688,7 @@ qse_htb_t* qse_awk_rtx_getnvmap (qse_awk_rtx_t* rtx) | ||||
| } | ||||
|  | ||||
| qse_awk_rtx_t* qse_awk_rtx_open ( | ||||
| 	qse_awk_t* awk, qse_size_t xtn, | ||||
| 	qse_awk_rio_t* rio, const qse_cstr_t* arg) | ||||
| 	qse_awk_t* awk, qse_size_t xtn, qse_awk_rio_t* rio) | ||||
| { | ||||
| 	qse_awk_rtx_t* rtx; | ||||
|  | ||||
| @ -726,7 +727,7 @@ qse_awk_rtx_t* qse_awk_rtx_open ( | ||||
| 		return QSE_NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (init_globals (rtx, arg) <= -1) | ||||
| 	if (init_globals (rtx) <= -1) | ||||
| 	{ | ||||
| 		awk->errinf = rtx->errinf; /* transfer error info */ | ||||
| 		fini_rtx (rtx, 0); | ||||
| @ -1078,101 +1079,6 @@ static void fini_rtx (qse_awk_rtx_t* rtx, int fini_globals) | ||||
| 	rtx->vmgr.rchunk = QSE_NULL; | ||||
| } | ||||
|  | ||||
| static int build_runarg ( | ||||
| 	qse_awk_rtx_t* rtx, const qse_cstr_t* runarg, qse_size_t* nargs) | ||||
| { | ||||
| 	const qse_cstr_t* p; | ||||
| 	qse_size_t argc; | ||||
| 	qse_awk_val_t* v_argc; | ||||
| 	qse_awk_val_t* v_argv; | ||||
| 	qse_awk_val_t* v_tmp; | ||||
| 	qse_char_t key[QSE_SIZEOF(qse_long_t)*8+2]; | ||||
| 	qse_size_t key_len; | ||||
|  | ||||
| 	v_argv = qse_awk_rtx_makemapval (rtx); | ||||
| 	if (v_argv == QSE_NULL) return -1; | ||||
|  | ||||
| 	qse_awk_rtx_refupval (rtx, v_argv); | ||||
|  | ||||
| 	if (runarg) | ||||
| 	{ | ||||
| 		for (argc = 0, p = runarg; p->ptr != QSE_NULL; argc++, p++) | ||||
| 		{ | ||||
| 			v_tmp = qse_awk_rtx_makestrval (rtx, p->ptr, p->len); | ||||
| 			if (v_tmp == QSE_NULL) | ||||
| 			{ | ||||
| 				qse_awk_rtx_refdownval (rtx, v_argv); | ||||
| 				return -1; | ||||
| 			} | ||||
|  | ||||
| 			key_len = qse_awk_longtostr ( | ||||
| 				rtx->awk, argc, 10, | ||||
| 				QSE_NULL, key, QSE_COUNTOF(key)); | ||||
| 			QSE_ASSERT (key_len != (qse_size_t)-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_argv)->map, | ||||
| 				key, key_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_argv is freed */ | ||||
| 				qse_awk_rtx_refdownval (rtx, v_argv); | ||||
|  | ||||
| 				SETERR_COD (rtx, QSE_AWK_ENOMEM); | ||||
| 				return -1; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	else argc = 0; | ||||
|  | ||||
| 	v_argc = qse_awk_rtx_makeintval (rtx, (qse_long_t)argc); | ||||
| 	if (v_argc == QSE_NULL) | ||||
| 	{ | ||||
| 		qse_awk_rtx_refdownval (rtx, v_argv); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	qse_awk_rtx_refupval (rtx, v_argc); | ||||
|  | ||||
| 	QSE_ASSERT ( | ||||
| 		STACK_GBL(rtx,QSE_AWK_GBL_ARGC) == qse_awk_val_nil); | ||||
|  | ||||
| 	if (qse_awk_rtx_setgbl (rtx, QSE_AWK_GBL_ARGC, v_argc) == -1) | ||||
| 	{ | ||||
| 		qse_awk_rtx_refdownval (rtx, v_argc); | ||||
| 		qse_awk_rtx_refdownval (rtx, v_argv); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (qse_awk_rtx_setgbl (rtx, QSE_AWK_GBL_ARGV, v_argv) == -1) | ||||
| 	{ | ||||
| 		/* ARGC is assigned nil when ARGV assignment has failed. | ||||
| 		 * However, this requires preconditions, as follows: | ||||
| 		 *  1. build_runarg should be called in a proper place | ||||
| 		 *     as it is not a generic-purpose routine. | ||||
| 		 *  2. ARGC should be nil before build_runarg is called  | ||||
| 		 * If the restoration fails, nothing can salvage it. */ | ||||
| 		qse_awk_rtx_setgbl (rtx, QSE_AWK_GBL_ARGC, qse_awk_val_nil); | ||||
| 		qse_awk_rtx_refdownval (rtx, v_argc); | ||||
| 		qse_awk_rtx_refdownval (rtx, v_argv); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	qse_awk_rtx_refdownval (rtx, v_argc); | ||||
| 	qse_awk_rtx_refdownval (rtx, v_argv); | ||||
|  | ||||
| 	*nargs = argc; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int update_fnr (qse_awk_rtx_t* rtx, qse_long_t fnr, qse_long_t nr) | ||||
| { | ||||
| 	qse_awk_val_t* tmp1, * tmp2; | ||||
| @ -1217,13 +1123,11 @@ static int update_fnr (qse_awk_rtx_t* rtx, qse_long_t fnr, qse_long_t nr) | ||||
| /*  | ||||
|  * create global variables into the runtime stack | ||||
|  * each variable is initialized to nil or zero. | ||||
|  * ARGC and ARGV are built in this function | ||||
|  */ | ||||
| static int prepare_globals (qse_awk_rtx_t* rtx, const qse_cstr_t* runarg) | ||||
| static int prepare_globals (qse_awk_rtx_t* rtx) | ||||
| { | ||||
| 	qse_size_t saved_stack_top; | ||||
| 	qse_size_t ngbls; | ||||
| 	qse_size_t nrunargs; | ||||
|  | ||||
| 	saved_stack_top = rtx->stack_top; | ||||
| 	ngbls = rtx->awk->tree.ngbls; | ||||
| @ -1243,9 +1147,6 @@ static int prepare_globals (qse_awk_rtx_t* rtx, const qse_cstr_t* runarg) | ||||
| 	if (qse_awk_rtx_setgbl ( | ||||
| 		rtx, QSE_AWK_GBL_NF, qse_awk_val_zero) <= -1) goto oops; | ||||
|  | ||||
| 	/* override ARGC and ARGV if necessary */ | ||||
| 	if (runarg && build_runarg (rtx, runarg, &nrunargs) <= -1) goto oops; | ||||
| 	 | ||||
| 	/* return success */ | ||||
| 	return 0; | ||||
|  | ||||
| @ -1337,13 +1238,13 @@ static void refdown_globals (qse_awk_rtx_t* run, int pop) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static int init_globals (qse_awk_rtx_t* rtx, const qse_cstr_t* arg) | ||||
| static int init_globals (qse_awk_rtx_t* rtx) | ||||
| { | ||||
| 	/* the stack must be clean when this function is invoked */ | ||||
| 	QSE_ASSERTX (rtx->stack_base == 0, "stack not clean"); | ||||
| 	QSE_ASSERTX (rtx->stack_top == 0, "stack not clean"); | ||||
|  | ||||
| 	if (prepare_globals (rtx, arg) == -1) return -1; | ||||
| 	if (prepare_globals (rtx) == -1) return -1; | ||||
| 	if (update_fnr (rtx, 0, 0) == -1) goto oops; | ||||
| 	if (defaultify_globals (rtx) == -1) goto oops; | ||||
| 	return 0; | ||||
|  | ||||
| @ -104,6 +104,8 @@ typedef struct xtn_t | ||||
| 		} out; | ||||
| 	} s; /* script/source handling */ | ||||
|  | ||||
| 	int gbl_argc; | ||||
| 	int gbl_argv; | ||||
| 	int gbl_environ; | ||||
| 	int gbl_procinfo; | ||||
| } xtn_t; | ||||
| @ -1179,6 +1181,8 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) | ||||
|  | ||||
| 	if (riod->mode == QSE_AWK_RIO_CONSOLE_READ) | ||||
| 	{ | ||||
| 		xtn_t* xtn = (xtn_t*)QSE_XTN (rtx->awk); | ||||
|  | ||||
| 		if (rxtn->c.in.files == QSE_NULL) | ||||
| 		{ | ||||
| 			/* if no input files is specified,  | ||||
| @ -1254,7 +1258,7 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) | ||||
| 			 * 'BEGIN { ARGV[1]="file3"; }  | ||||
| 			 *        { print $0; }' file1 file2 | ||||
| 			 */ | ||||
| 			argv = qse_awk_rtx_getgbl (rtx, QSE_AWK_GBL_ARGV); | ||||
| 			argv = qse_awk_rtx_getgbl (rtx, xtn->gbl_argv); | ||||
| 			QSE_ASSERT (argv != QSE_NULL); | ||||
| 			QSE_ASSERT (argv->type == QSE_AWK_VAL_MAP); | ||||
|  | ||||
| @ -1482,6 +1486,112 @@ static void fini_rxtn (qse_awk_rtx_t* rtx, void* ctx) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static int build_argcv ( | ||||
| 	qse_awk_rtx_t* rtx, int argc_id, int argv_id,  | ||||
| 	const qse_char_t* id, const qse_char_t*const icf[]) | ||||
| { | ||||
| 	const qse_char_t*const* p; | ||||
| 	qse_size_t argc; | ||||
| 	qse_awk_val_t* v_argc; | ||||
| 	qse_awk_val_t* v_argv; | ||||
| 	qse_awk_val_t* v_tmp; | ||||
| 	qse_char_t key[QSE_SIZEOF(qse_long_t)*8+2]; | ||||
| 	qse_size_t key_len; | ||||
|  | ||||
| 	v_argv = qse_awk_rtx_makemapval (rtx); | ||||
| 	if (v_argv == QSE_NULL) return -1; | ||||
|  | ||||
| 	qse_awk_rtx_refupval (rtx, v_argv); | ||||
|  | ||||
| 	/* make ARGV[0] */ | ||||
| 	v_tmp = qse_awk_rtx_makestrval0 (rtx, id); | ||||
| 	if (v_tmp == QSE_NULL)  | ||||
| 	{ | ||||
| 		qse_awk_rtx_refdownval (rtx, v_argv); | ||||
| 		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); | ||||
|  | ||||
| 	key_len = qse_strxcpy (key, QSE_COUNTOF(key), QSE_T("0")); | ||||
| 	if (qse_htb_upsert ( | ||||
| 		((qse_awk_val_map_t*)v_argv)->map, | ||||
| 		key, key_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_argv is freed */ | ||||
| 		qse_awk_rtx_refdownval (rtx, v_argv); | ||||
|  | ||||
| 		qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);  | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (icf) | ||||
| 	{ | ||||
| 		for (argc = 1, p = icf; *p; p++, argc++)  | ||||
| 		{ | ||||
| 			v_tmp = qse_awk_rtx_makestrval0 (rtx, *p); | ||||
| 			if (v_tmp == QSE_NULL) | ||||
| 			{ | ||||
| 				qse_awk_rtx_refdownval (rtx, v_argv); | ||||
| 				return -1; | ||||
| 			} | ||||
|  | ||||
| 			key_len = qse_awk_longtostr ( | ||||
| 				rtx->awk, argc, 10, | ||||
| 				QSE_NULL, key, QSE_COUNTOF(key)); | ||||
| 			QSE_ASSERT (key_len != (qse_size_t)-1); | ||||
|  | ||||
| 			qse_awk_rtx_refupval (rtx, v_tmp); | ||||
|  | ||||
| 			if (qse_htb_upsert ( | ||||
| 				((qse_awk_val_map_t*)v_argv)->map, | ||||
| 				key, key_len, v_tmp, 0) == QSE_NULL) | ||||
| 			{ | ||||
| 				qse_awk_rtx_refdownval (rtx, v_tmp); | ||||
| 				qse_awk_rtx_refdownval (rtx, v_argv); | ||||
| 				qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);  | ||||
| 				return -1; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	else argc = 1; | ||||
|  | ||||
| 	v_argc = qse_awk_rtx_makeintval (rtx, (qse_long_t)argc); | ||||
| 	if (v_argc == QSE_NULL) | ||||
| 	{ | ||||
| 		qse_awk_rtx_refdownval (rtx, v_argv); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	qse_awk_rtx_refupval (rtx, v_argc); | ||||
|  | ||||
| 	if (qse_awk_rtx_setgbl (rtx, argc_id, v_argc) <= -1) | ||||
| 	{ | ||||
| 		qse_awk_rtx_refdownval (rtx, v_argc); | ||||
| 		qse_awk_rtx_refdownval (rtx, v_argv); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (qse_awk_rtx_setgbl (rtx, argv_id, v_argv) <= -1) | ||||
| 	{ | ||||
| 		qse_awk_rtx_refdownval (rtx, v_argc); | ||||
| 		qse_awk_rtx_refdownval (rtx, v_argv); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	qse_awk_rtx_refdownval (rtx, v_argc); | ||||
| 	qse_awk_rtx_refdownval (rtx, v_argv); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int __build_environ ( | ||||
| 	qse_awk_rtx_t* rtx, int gbl_id, qse_env_char_t* envarr[]) | ||||
| { | ||||
| @ -1744,10 +1854,14 @@ static int build_procinfo (qse_awk_rtx_t* rtx, int gbl_id) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int make_additional_globals (qse_awk_rtx_t* rtx, xtn_t* xtn) | ||||
| static int make_additional_globals ( | ||||
| 	qse_awk_rtx_t* rtx, xtn_t* xtn,  | ||||
| 	const qse_char_t* id, const qse_char_t*const icf[]) | ||||
| { | ||||
| 	if (build_environ (rtx, xtn->gbl_environ) <= -1) return -1; | ||||
| 	if (build_procinfo (rtx, xtn->gbl_procinfo) <= -1) return -1; | ||||
| 	if (build_argcv (rtx, xtn->gbl_argc, xtn->gbl_argv, id, icf) <= -1 || | ||||
| 	    build_environ (rtx, xtn->gbl_environ) <= -1 || | ||||
| 	    build_procinfo (rtx, xtn->gbl_procinfo) <= -1) return -1; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -1772,65 +1886,18 @@ qse_awk_rtx_t* qse_awk_rtx_openstd ( | ||||
| 	xtn_t* xtn; | ||||
| 	qse_ntime_t now; | ||||
|  | ||||
| 	const qse_char_t*const* p; | ||||
| 	qse_cstr_t* p2; | ||||
|  | ||||
| 	qse_size_t argc = 0; | ||||
| 	qse_cstr_t argv[16]; | ||||
| 	qse_cstr_t* argvp = QSE_NULL; | ||||
|  | ||||
| 	xtn = (xtn_t*)QSE_XTN (awk); | ||||
|  | ||||
| 	rio.pipe = awk_rio_pipe; | ||||
| 	rio.file = awk_rio_file; | ||||
| 	rio.console = awk_rio_console; | ||||
|  | ||||
| 	if (icf) | ||||
| 	{ | ||||
| 		for (p = icf; *p != QSE_NULL; p++); | ||||
| 		argc = p - icf; | ||||
| 	} | ||||
|  | ||||
| 	argc++; /* for id */ | ||||
|  | ||||
| 	if (argc < QSE_COUNTOF(argv)) argvp = argv; | ||||
| 	else | ||||
| 	{ | ||||
| 		argvp = QSE_AWK_ALLOC ( | ||||
| 			awk, QSE_SIZEOF(*argvp) * (argc + 1)); | ||||
| 		if (argvp == QSE_NULL) | ||||
| 		{ | ||||
| 			qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); | ||||
| 			return QSE_NULL; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	p2 = argvp; | ||||
|  | ||||
| 	p2->ptr = id; | ||||
| 	p2->len = qse_strlen(id); | ||||
| 	p2++; | ||||
| 	 | ||||
| 	if (icf) | ||||
| 	{ | ||||
| 		for (p = icf; *p; p++, p2++)  | ||||
| 		{ | ||||
| 			p2->ptr = *p; | ||||
| 			p2->len = qse_strlen(*p); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	p2->ptr = QSE_NULL; | ||||
| 	p2->len = 0; | ||||
|  | ||||
| 	rtx = qse_awk_rtx_open ( | ||||
| 		awk,  | ||||
| 		QSE_SIZEOF(rxtn_t) + xtnsize, | ||||
| 		&rio, | ||||
| 		argvp | ||||
| 		&rio | ||||
| 	); | ||||
|  | ||||
| 	if (argvp && argvp != argv) QSE_AWK_FREE (awk, argvp); | ||||
| 	if (rtx == QSE_NULL) return QSE_NULL; | ||||
|  | ||||
| 	rxtn = (rxtn_t*) QSE_XTN (rtx); | ||||
| @ -1887,7 +1954,7 @@ qse_awk_rtx_t* qse_awk_rtx_openstd ( | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (make_additional_globals (rtx, xtn) <= -1) | ||||
| 	if (make_additional_globals (rtx, xtn, id, icf) <= -1) | ||||
| 	{ | ||||
| 		awk->errinf = rtx->errinf; /* transfer error info */ | ||||
| 		qse_awk_rtx_close (rtx); | ||||
| @ -2338,11 +2405,13 @@ static int add_globals (qse_awk_t* awk) | ||||
|  | ||||
| 	xtn = (xtn_t*) QSE_XTN (awk); | ||||
|  | ||||
| 	xtn->gbl_argc = qse_awk_addgbl (awk, QSE_T("ARGC"), 4); | ||||
| 	xtn->gbl_argv = qse_awk_addgbl (awk, QSE_T("ARGV"), 4); | ||||
| 	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; | ||||
|  | ||||
| 	if (xtn->gbl_argc <= -1 || xtn->gbl_argv <= -1 || | ||||
| 	    xtn->gbl_environ <= -1 || xtn->gbl_procinfo <= -1) return -1; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user