- deleted unnecessary callback functions - on_loop_enter() & on_loop_exit()
- modified qse_awk_rtx_loop() and Awk::loop() to return the return value - deprecated the callback totally from the Awk class: may readd it in the future. - added POC code to pass arguments by reference for intrinsic functions. POC ok. more works needed for full support. not enabled.
This commit is contained in:
		@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * $Id: awk.c 220 2009-07-01 13:14:39Z hyunghwan.chung $
 | 
					 * $Id: awk.c 236 2009-07-16 08:27:53Z hyunghwan.chung $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
					   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -233,14 +233,7 @@ static int apply_fs_and_gvm (qse_awk_rtx_t* rtx, struct arg_t* arg)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int on_loop_enter (qse_awk_rtx_t* rtx, void* data)
 | 
					static void dprint_return (qse_awk_rtx_t* rtx, qse_awk_val_t* ret)
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	/* TODO: anything to do? */
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void on_loop_exit (
 | 
					 | 
				
			||||||
	qse_awk_rtx_t* rtx, qse_awk_val_t* ret, void* data)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	qse_size_t len;
 | 
						qse_size_t len;
 | 
				
			||||||
	qse_char_t* str;
 | 
						qse_char_t* str;
 | 
				
			||||||
@ -274,8 +267,7 @@ static void on_statement (
 | 
				
			|||||||
	/*dprint (L"running %d\n", (int)line);*/
 | 
						/*dprint (L"running %d\n", (int)line);*/
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fnc_sleep (
 | 
					static int fnc_sleep (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
 | 
				
			||||||
	qse_awk_rtx_t* run, const qse_char_t* fnm, qse_size_t fnl)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	qse_size_t nargs;
 | 
						qse_size_t nargs;
 | 
				
			||||||
	qse_awk_val_t* a0;
 | 
						qse_awk_val_t* a0;
 | 
				
			||||||
@ -681,6 +673,7 @@ static int awk_main (int argc, qse_char_t* argv[])
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	qse_awk_t* awk = QSE_NULL;
 | 
						qse_awk_t* awk = QSE_NULL;
 | 
				
			||||||
	qse_awk_rtx_t* rtx = QSE_NULL;
 | 
						qse_awk_rtx_t* rtx = QSE_NULL;
 | 
				
			||||||
 | 
						qse_awk_val_t* retv;
 | 
				
			||||||
	qse_awk_rcb_t rcb;
 | 
						qse_awk_rcb_t rcb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
@ -751,8 +744,6 @@ static int awk_main (int argc, qse_char_t* argv[])
 | 
				
			|||||||
		goto oops;
 | 
							goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rcb.on_loop_enter = on_loop_enter;
 | 
					 | 
				
			||||||
	rcb.on_loop_exit = on_loop_exit;
 | 
					 | 
				
			||||||
	rcb.on_statement = on_statement;
 | 
						rcb.on_statement = on_statement;
 | 
				
			||||||
	rcb.udd = &arg;
 | 
						rcb.udd = &arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -773,18 +764,18 @@ static int awk_main (int argc, qse_char_t* argv[])
 | 
				
			|||||||
	qse_awk_rtx_setrcb (rtx, &rcb);
 | 
						qse_awk_rtx_setrcb (rtx, &rcb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	set_intr_run ();
 | 
						set_intr_run ();
 | 
				
			||||||
	if (arg.call == QSE_NULL)
 | 
					
 | 
				
			||||||
 | 
						retv = (arg.call == QSE_NULL)?
 | 
				
			||||||
 | 
							qse_awk_rtx_loop (rtx):
 | 
				
			||||||
 | 
							qse_awk_rtx_call (rtx, arg.call, QSE_NULL, 0);
 | 
				
			||||||
 | 
						if (retv != QSE_NULL)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ret = qse_awk_rtx_loop (rtx);
 | 
							qse_awk_rtx_refdownval (rtx, retv);
 | 
				
			||||||
	}
 | 
							ret = 0;
 | 
				
			||||||
	else
 | 
					
 | 
				
			||||||
	{
 | 
							dprint_return (rtx, retv);
 | 
				
			||||||
		qse_awk_val_t* rv;
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		rv = qse_awk_rtx_call (rtx, arg.call, QSE_NULL, 0);
 | 
					 | 
				
			||||||
		ret = (rv == QSE_NULL)? -1: 0;
 | 
					 | 
				
			||||||
		qse_awk_rtx_refdownval (rtx, rv);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unset_intr_run ();
 | 
						unset_intr_run ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ret <= -1)
 | 
						if (ret <= -1)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * $Id: Awk.hpp 235 2009-07-15 10:43:31Z hyunghwan.chung $
 | 
					 * $Id: Awk.hpp 236 2009-07-16 08:27:53Z hyunghwan.chung $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
					   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -255,7 +255,9 @@ protected:
 | 
				
			|||||||
	void retrieveError (Run* run);
 | 
						void retrieveError (Run* run);
 | 
				
			||||||
	/*@}*/
 | 
						/*@}*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
	class NoSource;
 | 
						class NoSource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	/** 
 | 
						/** 
 | 
				
			||||||
	 * The Source class is an abstract class to encapsulate
 | 
						 * The Source class is an abstract class to encapsulate
 | 
				
			||||||
@ -677,6 +679,7 @@ public:
 | 
				
			|||||||
		static const char_t* EMPTY_STRING;
 | 
							static const char_t* EMPTY_STRING;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Defines an identifier of predefined global variables.
 | 
						 * Defines an identifier of predefined global variables.
 | 
				
			||||||
	 * Awk::setGlobal and Awk::getGlobal can take one of these enumerators.
 | 
						 * Awk::setGlobal and Awk::getGlobal can take one of these enumerators.
 | 
				
			||||||
@ -802,24 +805,26 @@ public:
 | 
				
			|||||||
	 * @return a Run object on success, #QSE_NULL on failure
 | 
						 * @return a Run object on success, #QSE_NULL on failure
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	Awk::Run* parse (
 | 
						Awk::Run* parse (
 | 
				
			||||||
		Source& in,  /**< script to parse */
 | 
							Source& in,  ///< script to parse 
 | 
				
			||||||
		Source& out  /**< deparsing target */
 | 
							Source& out  ///< deparsing target 
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Executes the BEGIN block, pattern-action blocks, and the END block.
 | 
						 * Executes the BEGIN block, pattern-action blocks, and the END block.
 | 
				
			||||||
	 * @return 0 on succes, -1 on failure
 | 
						 * @return 0 on succes, -1 on failure
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	int loop ();
 | 
						int loop (
 | 
				
			||||||
 | 
							Value* ret  ///< return value holder
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Calls a function
 | 
						 * Calls a function
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	int call (
 | 
						int call (
 | 
				
			||||||
		const char_t* name,
 | 
							const char_t* name,  ///< function name
 | 
				
			||||||
		Value*        ret,
 | 
							Value*        ret,   ///< return value holder
 | 
				
			||||||
		const Value*  args,
 | 
							const Value*  args,  ///< argument array
 | 
				
			||||||
		size_t        nargs
 | 
							size_t        nargs  ///< number of arguments
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
@ -982,16 +987,6 @@ public:
 | 
				
			|||||||
	int deleteFunction (const char_t* name);
 | 
						int deleteFunction (const char_t* name);
 | 
				
			||||||
	/*@}*/
 | 
						/*@}*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Enables the run-time callback
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	void enableRunCallback ();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Disables the run-time callback
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	void disableRunCallback ();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @name Word Substitution
 | 
						 * @name Word Substitution
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
@ -1058,11 +1053,6 @@ protected:
 | 
				
			|||||||
	virtual int     nextConsole  (Console& io) = 0;
 | 
						virtual int     nextConsole  (Console& io) = 0;
 | 
				
			||||||
	/*@}*/
 | 
						/*@}*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// run-time callbacks
 | 
					 | 
				
			||||||
	virtual bool onLoopEnter (Run& run);
 | 
					 | 
				
			||||||
	virtual void onLoopExit (Run& run, const Value& ret);
 | 
					 | 
				
			||||||
	virtual void onStatement (Run& run, size_t line);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	// primitive handlers 
 | 
						// primitive handlers 
 | 
				
			||||||
	virtual real_t pow (real_t x, real_t y) = 0;
 | 
						virtual real_t pow (real_t x, real_t y) = 0;
 | 
				
			||||||
	virtual int    vsprintf (char_t* buf, size_t size,
 | 
						virtual int    vsprintf (char_t* buf, size_t size,
 | 
				
			||||||
@ -1086,10 +1076,6 @@ protected:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	static int functionHandler (rtx_t* rtx, const cstr_t* name);
 | 
						static int functionHandler (rtx_t* rtx, const cstr_t* name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static int  onLoopEnter (rtx_t* run, void* data);
 | 
					 | 
				
			||||||
	static void onLoopExit (rtx_t* run, val_t* ret, void* data);
 | 
					 | 
				
			||||||
	static void onStatement (rtx_t* run, size_t line, void* data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	static real_t pow     (awk_t* data, real_t x, real_t y);
 | 
						static real_t pow     (awk_t* data, real_t x, real_t y);
 | 
				
			||||||
	static int    sprintf (awk_t* data, char_t* buf, size_t size,
 | 
						static int    sprintf (awk_t* data, char_t* buf, size_t size,
 | 
				
			||||||
	                       const char_t* fmt, ...);
 | 
						                       const char_t* fmt, ...);
 | 
				
			||||||
@ -1108,8 +1094,6 @@ protected:
 | 
				
			|||||||
	Source* sourceReader;
 | 
						Source* sourceReader;
 | 
				
			||||||
	Source* sourceWriter;
 | 
						Source* sourceWriter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool     runCallback;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct xstrs_t
 | 
						struct xstrs_t
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		xstrs_t (): ptr (QSE_NULL), len (0), capa (0) {}
 | 
							xstrs_t (): ptr (QSE_NULL), len (0), capa (0) {}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * $Id: awk.h 235 2009-07-15 10:43:31Z hyunghwan.chung $
 | 
					 * $Id: awk.h 236 2009-07-16 08:27:53Z hyunghwan.chung $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
					   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -58,7 +58,9 @@
 | 
				
			|||||||
 * awk = qse_awk_open (mmgr, 0, prm); // create an interpreter 
 | 
					 * awk = qse_awk_open (mmgr, 0, prm); // create an interpreter 
 | 
				
			||||||
 * qse_awk_parse (awk, &sio);          // parse a script 
 | 
					 * 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, args); // create a runtime context 
 | 
				
			||||||
 * qse_awk_rtx_loop (rtx);            // run a standard AWK loop 
 | 
					 * retv = qse_awk_rtx_loop (rtx);     // run a standard AWK loop 
 | 
				
			||||||
 | 
					 * if (retv != QSE_NULL) 
 | 
				
			||||||
 | 
					 *    qse_awk_rtx_refdownval (rtx, retv); // free return value
 | 
				
			||||||
 * qse_awk_rtx_close (rtx);           // destroy the runtime context
 | 
					 * qse_awk_rtx_close (rtx);           // destroy the runtime context
 | 
				
			||||||
 * qse_awk_close (awk);               // destroy the interpreter
 | 
					 * qse_awk_close (awk);               // destroy the interpreter
 | 
				
			||||||
 * @endcode
 | 
					 * @endcode
 | 
				
			||||||
@ -466,20 +468,6 @@ typedef struct qse_awk_rio_t qse_awk_rio_t;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
struct qse_awk_rcb_t
 | 
					struct qse_awk_rcb_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/** 
 | 
					 | 
				
			||||||
	 * called by qse_awk_rtx_loop() before entering pattern-action loop.
 | 
					 | 
				
			||||||
	 * A @b BEGIN block is executed after this callback.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	int (*on_loop_enter) (
 | 
					 | 
				
			||||||
		qse_awk_rtx_t* rtx, void* udd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * called by qse_awk_rtx_loop() when exiting pattern-action loop.
 | 
					 | 
				
			||||||
	 * An @b END block is executed before this callback.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	void (*on_loop_exit) (
 | 
					 | 
				
			||||||
		qse_awk_rtx_t* rtx, qse_awk_val_t* ret, void* udd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * called by qse_awk_rtx_loop() and qse_awk_rtx_call() for
 | 
						 * called by qse_awk_rtx_loop() and qse_awk_rtx_call() for
 | 
				
			||||||
	 * each statement executed.
 | 
						 * each statement executed.
 | 
				
			||||||
@ -1304,22 +1292,25 @@ void qse_awk_rtx_close (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * The qse_awk_rtx_loop() function executes the BEGIN block, pattern-action
 | 
					 * The qse_awk_rtx_loop() function executes the BEGIN block, pattern-action
 | 
				
			||||||
 * blocks and the END blocks in an AWk program. Multiple invocations of the
 | 
					 * blocks and the END blocks in an AWk program. It returns the global return 
 | 
				
			||||||
 * function for the lifetime of a runtime context is not desirable.
 | 
					 * value of which the reference count must be decremented when not necessary. 
 | 
				
			||||||
 | 
					 * Multiple invocations of the function for the lifetime of a runtime context 
 | 
				
			||||||
 | 
					 * is not desirable.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * The example shows typical usage of the function.
 | 
				
			||||||
 * @code
 | 
					 * @code
 | 
				
			||||||
 *  The example shows typical usage of the function.
 | 
					 * rtx = qse_awk_rtx_open (awk, 0, rio, QSE_NULL);
 | 
				
			||||||
 *    rtx = qse_awk_rtx_open (awk, 0, rio, QSE_NULL);
 | 
					 * if (rtx != QSE_NULL)
 | 
				
			||||||
 *    if (rtx != QSE_NULL)
 | 
					 * {
 | 
				
			||||||
 *    {
 | 
					 *    retv = qse_awk_rtx_loop (rtx);
 | 
				
			||||||
 *        qse_awk_rtx_loop (rtx);
 | 
					 *    if (retv != QSE_NULL) qse_awk_rtx_refdownval (rtx, retv);
 | 
				
			||||||
 *        qse_awk_rtx_close (rtx);
 | 
					 *    qse_awk_rtx_close (rtx);
 | 
				
			||||||
 *    }
 | 
					 * }
 | 
				
			||||||
 * @endcode
 | 
					 * @endcode
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @return 0 on success, -1 on failure.
 | 
					 * @return return value on success, QSE_NULL on failure.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int qse_awk_rtx_loop (
 | 
					qse_awk_val_t* qse_awk_rtx_loop (
 | 
				
			||||||
	qse_awk_rtx_t* rtx /**< runtime context */
 | 
						qse_awk_rtx_t* rtx /**< runtime context */
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * $Id: rex.h 203 2009-06-17 12:43:50Z hyunghwan.chung $
 | 
					 * $Id: rex.h 236 2009-07-16 08:27:53Z hyunghwan.chung $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
					   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -54,6 +54,7 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * @todo
 | 
					 * @todo
 | 
				
			||||||
 * - support \\n to refer to the nth matching substring
 | 
					 * - support \\n to refer to the nth matching substring
 | 
				
			||||||
 | 
					 * - change to adopt Thomson's NFA (http://swtch.com/~rsc/regexp/regexp1.html)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define QSE_REX_NA(code) (*(qse_size_t*)(code))
 | 
					#define QSE_REX_NA(code) (*(qse_size_t*)(code))
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * $Id: Awk.cpp 235 2009-07-15 10:43:31Z hyunghwan.chung $
 | 
					 * $Id: Awk.cpp 236 2009-07-16 08:27:53Z hyunghwan.chung $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
					   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -21,6 +21,9 @@
 | 
				
			|||||||
#include "../cmn/mem.h"
 | 
					#include "../cmn/mem.h"
 | 
				
			||||||
#include "awk.h"
 | 
					#include "awk.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// enable this once addFunction() is extended with argument spec (rxv...).
 | 
				
			||||||
 | 
					//#define PASS_BY_REFERENCE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/////////////////////////////////
 | 
					/////////////////////////////////
 | 
				
			||||||
QSE_BEGIN_NAMESPACE(QSE)
 | 
					QSE_BEGIN_NAMESPACE(QSE)
 | 
				
			||||||
/////////////////////////////////
 | 
					/////////////////////////////////
 | 
				
			||||||
@ -994,7 +997,7 @@ int Awk::Run::getGlobal (int id, Value& g) const
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Awk::Awk () : awk (QSE_NULL), functionMap (QSE_NULL),
 | 
					Awk::Awk () : awk (QSE_NULL), functionMap (QSE_NULL),
 | 
				
			||||||
	sourceIn (this, Source::READ), sourceOut (this, Source::WRITE),
 | 
						sourceIn (this, Source::READ), sourceOut (this, Source::WRITE),
 | 
				
			||||||
	runCallback (false), runctx (this)
 | 
						runctx (this)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	errinf.num = (errnum_t)ERR_NOERR;
 | 
						errinf.num = (errnum_t)ERR_NOERR;
 | 
				
			||||||
@ -1140,7 +1143,6 @@ int Awk::open ()
 | 
				
			|||||||
	qse_map_setfreeer (functionMap, QSE_MAP_VAL, free_function_map_value);
 | 
						qse_map_setfreeer (functionMap, QSE_MAP_VAL, free_function_map_value);
 | 
				
			||||||
	qse_map_setscale (functionMap, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t));
 | 
						qse_map_setscale (functionMap, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	runCallback = false;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1162,7 +1164,6 @@ void Awk::close ()
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	clearError ();
 | 
						clearError ();
 | 
				
			||||||
	runCallback = false;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Awk::Run* Awk::parse (Source& in, Source& out) 
 | 
					Awk::Run* Awk::parse (Source& in, Source& out) 
 | 
				
			||||||
@ -1195,19 +1196,27 @@ Awk::Run* Awk::parse (Source& in, Source& out)
 | 
				
			|||||||
	return &runctx;
 | 
						return &runctx;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int Awk::loop () 
 | 
					int Awk::loop (Value* ret)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	QSE_ASSERT (awk != QSE_NULL);
 | 
						QSE_ASSERT (awk != QSE_NULL);
 | 
				
			||||||
	QSE_ASSERT (runctx.rtx != QSE_NULL);
 | 
						QSE_ASSERT (runctx.rtx != QSE_NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int n = qse_awk_rtx_loop (runctx.rtx);
 | 
						val_t* rv = qse_awk_rtx_loop (runctx.rtx);
 | 
				
			||||||
	if (n <= -1) retrieveError (&runctx);
 | 
						if (rv == QSE_NULL) 
 | 
				
			||||||
	return n;
 | 
						{
 | 
				
			||||||
 | 
							retrieveError (&runctx);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret->setVal (&runctx, rv);
 | 
				
			||||||
 | 
						qse_awk_rtx_refdownval (runctx.rtx, rv);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int Awk::call (
 | 
					int Awk::call (
 | 
				
			||||||
	const char_t* name, Value* ret,
 | 
						const char_t* name, Value* ret,
 | 
				
			||||||
	const Value* args, size_t nargs) 
 | 
						const Value* args, size_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	QSE_ASSERT (awk != QSE_NULL);
 | 
						QSE_ASSERT (awk != QSE_NULL);
 | 
				
			||||||
	QSE_ASSERT (runctx.rtx != QSE_NULL);
 | 
						QSE_ASSERT (runctx.rtx != QSE_NULL);
 | 
				
			||||||
@ -1260,21 +1269,11 @@ int Awk::init_runctx ()
 | 
				
			|||||||
	if (runctx.rtx != QSE_NULL) return 0;
 | 
						if (runctx.rtx != QSE_NULL) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	qse_awk_rio_t rio;
 | 
						qse_awk_rio_t rio;
 | 
				
			||||||
	qse_awk_rcb_t rcb;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rio.pipe    = pipeHandler;
 | 
						rio.pipe    = pipeHandler;
 | 
				
			||||||
	rio.file    = fileHandler;
 | 
						rio.file    = fileHandler;
 | 
				
			||||||
	rio.console = consoleHandler;
 | 
						rio.console = consoleHandler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (runCallback)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		QSE_MEMSET (&rcb, 0, QSE_SIZEOF(rcb));
 | 
					 | 
				
			||||||
		rcb.on_loop_enter = onLoopEnter;
 | 
					 | 
				
			||||||
		rcb.on_loop_exit  = onLoopExit;
 | 
					 | 
				
			||||||
		rcb.on_statement  = onStatement;
 | 
					 | 
				
			||||||
		rcb.udd           = &runctx;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rtx_t* rtx = qse_awk_rtx_open (
 | 
						rtx_t* rtx = qse_awk_rtx_open (
 | 
				
			||||||
		awk, QSE_SIZEOF(rxtn_t), &rio, (qse_cstr_t*)runarg.ptr);
 | 
							awk, QSE_SIZEOF(rxtn_t), &rio, (qse_cstr_t*)runarg.ptr);
 | 
				
			||||||
	if (rtx == QSE_NULL) 
 | 
						if (rtx == QSE_NULL) 
 | 
				
			||||||
@ -1288,7 +1287,6 @@ int Awk::init_runctx ()
 | 
				
			|||||||
	rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx);
 | 
						rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx);
 | 
				
			||||||
	rxtn->run = &runctx;
 | 
						rxtn->run = &runctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (runCallback) qse_awk_rtx_setrcb (rtx, &rcb);
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1357,12 +1355,23 @@ int Awk::dispatch_function (Run* run, const cstr_t* name)
 | 
				
			|||||||
	for (i = 0; i < nargs; i++)
 | 
						for (i = 0; i < nargs; i++)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		val_t* v = qse_awk_rtx_getarg (run->rtx, i);
 | 
							val_t* v = qse_awk_rtx_getarg (run->rtx, i);
 | 
				
			||||||
 | 
					#ifdef PASS_BY_REFERENCE
 | 
				
			||||||
 | 
							QSE_ASSERT (v->type == QSE_AWK_VAL_REF);
 | 
				
			||||||
 | 
							val_t** ref = (val_t**)((qse_awk_val_ref_t*)v)->adr;
 | 
				
			||||||
 | 
							if (args[i].setVal (run, *ref) == -1)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								run->setError (ERR_NOMEM);
 | 
				
			||||||
 | 
								if (args != buf) delete[] args;
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
		if (args[i].setVal (run, v) == -1)
 | 
							if (args[i].setVal (run, v) == -1)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			run->setError (ERR_NOMEM);
 | 
								run->setError (ERR_NOMEM);
 | 
				
			||||||
			if (args != buf) delete[] args;
 | 
								if (args != buf) delete[] args;
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	Value ret (run);
 | 
						Value ret (run);
 | 
				
			||||||
@ -1372,6 +1381,28 @@ int Awk::dispatch_function (Run* run, const cstr_t* name)
 | 
				
			|||||||
	try { n = (this->*handler) (*run, ret, args, nargs, name); }
 | 
						try { n = (this->*handler) (*run, ret, args, nargs, name); }
 | 
				
			||||||
	catch (...) { n = -1; }
 | 
						catch (...) { n = -1; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef PASS_BY_REFERENCE
 | 
				
			||||||
 | 
						if (n >= 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							for (i = 0; i < nargs; i++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								QSE_ASSERTX (args[i].run == run, 
 | 
				
			||||||
 | 
									"Do NOT change Run from function handler");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								val_t* v = qse_awk_rtx_getarg (run->rtx, i);
 | 
				
			||||||
 | 
								val_t* nv = args[i].toVal();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (nv == v) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								QSE_ASSERT (v->type == QSE_AWK_VAL_REF);
 | 
				
			||||||
 | 
								val_t** ref = (val_t**)((qse_awk_val_ref_t*)v)->adr;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
								qse_awk_rtx_refdownval (run->rtx, *ref);
 | 
				
			||||||
 | 
								*ref = nv;
 | 
				
			||||||
 | 
								qse_awk_rtx_refupval (run->rtx, *ref);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	if (args != buf) delete[] args;
 | 
						if (args != buf) delete[] args;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (n <= -1) 
 | 
						if (n <= -1) 
 | 
				
			||||||
@ -1505,9 +1536,15 @@ int Awk::addFunction (
 | 
				
			|||||||
	
 | 
						
 | 
				
			||||||
	size_t nameLen = qse_strlen(name);
 | 
						size_t nameLen = qse_strlen(name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void* p = qse_awk_addfnc (awk, name, nameLen,
 | 
						void* p = qse_awk_addfnc (
 | 
				
			||||||
	                          0, minArgs, maxArgs, QSE_NULL, 
 | 
							awk, name, nameLen,
 | 
				
			||||||
	                          functionHandler);
 | 
							0, minArgs, maxArgs,
 | 
				
			||||||
 | 
					#ifdef PASS_BY_REFERENCE
 | 
				
			||||||
 | 
							QSE_T("R"), // pass all arguments by reference
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
							QSE_NULL,
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							functionHandler);
 | 
				
			||||||
	if (p == QSE_NULL) 
 | 
						if (p == QSE_NULL) 
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		qse_awk_free (awk, tmp);
 | 
							qse_awk_free (awk, tmp);
 | 
				
			||||||
@ -1542,16 +1579,6 @@ int Awk::deleteFunction (const char_t* name)
 | 
				
			|||||||
	return n;
 | 
						return n;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Awk::enableRunCallback () 
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	runCallback = true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Awk::disableRunCallback () 
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	runCallback = false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int Awk::getWord (
 | 
					int Awk::getWord (
 | 
				
			||||||
	const char_t* ow, qse_size_t owl,
 | 
						const char_t* ow, qse_size_t owl,
 | 
				
			||||||
	const char_t** nw, qse_size_t* nwl) 
 | 
						const char_t** nw, qse_size_t* nwl) 
 | 
				
			||||||
@ -1590,20 +1617,6 @@ int Awk::unsetAllWords ()
 | 
				
			|||||||
	return qse_awk_setword (awk, QSE_NULL, 0, QSE_NULL, 0);
 | 
						return qse_awk_setword (awk, QSE_NULL, 0, QSE_NULL, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
bool Awk::onLoopEnter (Run& run)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Awk::onLoopExit (Run& run, const Value& ret)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Awk::onStatement (Run& run, size_t line)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Awk::ssize_t Awk::readSource (
 | 
					Awk::ssize_t Awk::readSource (
 | 
				
			||||||
	awk_t* awk, qse_awk_sio_cmd_t cmd, char_t* data, size_t count)
 | 
						awk_t* awk, qse_awk_sio_cmd_t cmd, char_t* data, size_t count)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -1762,28 +1775,6 @@ int Awk::functionHandler (rtx_t* rtx, const cstr_t* name)
 | 
				
			|||||||
	return rxtn->run->awk->dispatch_function (rxtn->run, name);
 | 
						return rxtn->run->awk->dispatch_function (rxtn->run, name);
 | 
				
			||||||
}	
 | 
					}	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int Awk::onLoopEnter (rtx_t* rtx, void* data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	Run* run = (Run*)data;
 | 
					 | 
				
			||||||
	return run->awk->onLoopEnter(*run)? 0: -1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Awk::onLoopExit (rtx_t* rtx, val_t* ret, void* data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	Run* run = (Run*)data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Value x;
 | 
					 | 
				
			||||||
	if (x.setVal (run, ret) == -1) 
 | 
					 | 
				
			||||||
		qse_awk_rtx_seterrnum (run->rtx, (errnum_t)ERR_NOMEM);
 | 
					 | 
				
			||||||
	else run->awk->onLoopExit (*run, x);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Awk::onStatement (rtx_t* rtx, size_t line, void* data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	Run* run = (Run*)data;
 | 
					 | 
				
			||||||
	run->awk->onStatement (*run, line);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Awk::real_t Awk::pow (awk_t* awk, real_t x, real_t y)
 | 
					Awk::real_t Awk::pow (awk_t* awk, real_t x, real_t y)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
 | 
						xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * $Id: run.c 235 2009-07-15 10:43:31Z hyunghwan.chung $
 | 
					 * $Id: run.c 236 2009-07-16 08:27:53Z hyunghwan.chung $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
					   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1318,30 +1318,17 @@ static void exit_stack_frame (qse_awk_rtx_t* run)
 | 
				
			|||||||
	run->stack_base = (qse_size_t)run->stack[run->stack_base+0];
 | 
						run->stack_base = (qse_size_t)run->stack[run->stack_base+0];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int run_bpae_loop (qse_awk_rtx_t* rtx)
 | 
					static qse_awk_val_t* run_bpae_loop (qse_awk_rtx_t* rtx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	qse_awk_nde_t* nde;
 | 
						qse_awk_nde_t* nde;
 | 
				
			||||||
	qse_size_t nargs, i;
 | 
						qse_size_t nargs, i;
 | 
				
			||||||
	qse_awk_val_t* v;
 | 
						qse_awk_val_t* retv;
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* set nargs to zero */
 | 
						/* set nargs to zero */
 | 
				
			||||||
	nargs = 0;
 | 
						nargs = 0;
 | 
				
			||||||
	STACK_NARGS(rtx) = (void*)nargs;
 | 
						STACK_NARGS(rtx) = (void*)nargs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* call the callback */
 | 
					 | 
				
			||||||
	if (rtx->rcb.on_loop_enter != QSE_NULL)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOERR);
 | 
					 | 
				
			||||||
		ret = rtx->rcb.on_loop_enter (rtx, rtx->rcb.udd);
 | 
					 | 
				
			||||||
		if (ret <= -1) 
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			if (rtx->errinf.num == QSE_AWK_ENOMEM)
 | 
					 | 
				
			||||||
				qse_awk_rtx_seterrnum (rtx, QSE_AWK_EUNKNOWN);
 | 
					 | 
				
			||||||
			ret = -1;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* execute the BEGIN block */
 | 
						/* execute the BEGIN block */
 | 
				
			||||||
	for (nde = rtx->awk->tree.begin; 
 | 
						for (nde = rtx->awk->tree.begin; 
 | 
				
			||||||
	     ret == 0 && nde != QSE_NULL && rtx->exit_level < EXIT_GLOBAL;
 | 
						     ret == 0 && nde != QSE_NULL && rtx->exit_level < EXIT_GLOBAL;
 | 
				
			||||||
@ -1357,7 +1344,7 @@ static int run_bpae_loop (qse_awk_rtx_t* rtx)
 | 
				
			|||||||
		if (run_block (rtx, blk) == -1) ret = -1;
 | 
							if (run_block (rtx, blk) == -1) ret = -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ret == -1 && rtx->errinf.num == QSE_AWK_ENOERR) 
 | 
						if (ret <= -1 && rtx->errinf.num == QSE_AWK_ENOERR) 
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* an error is returned with no error number set.
 | 
							/* an error is returned with no error number set.
 | 
				
			||||||
		 * this feature is used by eval_expression() to
 | 
							 * this feature is used by eval_expression() to
 | 
				
			||||||
@ -1374,10 +1361,10 @@ static int run_bpae_loop (qse_awk_rtx_t* rtx)
 | 
				
			|||||||
	     rtx->awk->tree.end != QSE_NULL) && 
 | 
						     rtx->awk->tree.end != QSE_NULL) && 
 | 
				
			||||||
	     rtx->exit_level < EXIT_GLOBAL)
 | 
						     rtx->exit_level < EXIT_GLOBAL)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (run_pattern_blocks(rtx) == -1) ret = -1;
 | 
							if (run_pattern_blocks(rtx) <= -1) ret = -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ret == -1 && rtx->errinf.num == QSE_AWK_ENOERR)
 | 
						if (ret <= -1 && rtx->errinf.num == QSE_AWK_ENOERR)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* an error is returned with no error number set.
 | 
							/* an error is returned with no error number set.
 | 
				
			||||||
		 * this feature is used by eval_expression() to
 | 
							 * this feature is used by eval_expression() to
 | 
				
			||||||
@ -1401,7 +1388,7 @@ static int run_bpae_loop (qse_awk_rtx_t* rtx)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		rtx->active_block = blk;
 | 
							rtx->active_block = blk;
 | 
				
			||||||
		rtx->exit_level = EXIT_NONE;
 | 
							rtx->exit_level = EXIT_NONE;
 | 
				
			||||||
		if (run_block (rtx, blk) == -1) ret = -1;
 | 
							if (run_block (rtx, blk) <= -1) ret = -1;
 | 
				
			||||||
		else if (rtx->exit_level >= EXIT_GLOBAL) 
 | 
							else if (rtx->exit_level >= EXIT_GLOBAL) 
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/* once exit is called inside one of END blocks,
 | 
								/* once exit is called inside one of END blocks,
 | 
				
			||||||
@ -1410,7 +1397,7 @@ static int run_bpae_loop (qse_awk_rtx_t* rtx)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ret == -1 && rtx->errinf.num == QSE_AWK_ENOERR)
 | 
						if (ret <= -1 && rtx->errinf.num == QSE_AWK_ENOERR)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* an error is returned with no error number set.
 | 
							/* an error is returned with no error number set.
 | 
				
			||||||
		 * this feature is used by eval_expression() to
 | 
							 * this feature is used by eval_expression() to
 | 
				
			||||||
@ -1430,39 +1417,34 @@ static int run_bpae_loop (qse_awk_rtx_t* rtx)
 | 
				
			|||||||
		qse_awk_rtx_refdownval (rtx, STACK_ARG(rtx,i));
 | 
							qse_awk_rtx_refdownval (rtx, STACK_ARG(rtx,i));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* get the return value in the current stack frame */
 | 
						/* get the return value in the current stack frame */
 | 
				
			||||||
	v = STACK_RETVAL(rtx);
 | 
						retv = STACK_RETVAL(rtx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (rtx->rcb.on_loop_exit != QSE_NULL)
 | 
						if (ret <= -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* we call the on_exit handler regardless of ret. 
 | 
							/* end the life of the global return value upon error */
 | 
				
			||||||
		 * the return value passed is the global return value
 | 
							qse_awk_rtx_refdownval (rtx, retv);
 | 
				
			||||||
		 * in the stack. */
 | 
							retv = QSE_NULL;
 | 
				
			||||||
		rtx->rcb.on_loop_exit (rtx, v, rtx->rcb.udd);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* end the life of the global return value */
 | 
						return retv;
 | 
				
			||||||
	qse_awk_rtx_refdownval (rtx, v);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* start the BEGIN-pattern block-END loop */
 | 
					/* start the BEGIN-pattern block-END loop */
 | 
				
			||||||
int qse_awk_rtx_loop (qse_awk_rtx_t* rtx)
 | 
					qse_awk_val_t* qse_awk_rtx_loop (qse_awk_rtx_t* rtx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret;
 | 
						qse_awk_val_t* retv = QSE_NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rtx->exit_level = EXIT_NONE;
 | 
						rtx->exit_level = EXIT_NONE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = enter_stack_frame (rtx);
 | 
						if (enter_stack_frame (rtx) == 0)
 | 
				
			||||||
	if (ret == 0)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ret = run_bpae_loop (rtx);
 | 
							retv = run_bpae_loop (rtx);
 | 
				
			||||||
		exit_stack_frame (rtx);
 | 
							exit_stack_frame (rtx);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* reset the exit level */
 | 
						/* reset the exit level */
 | 
				
			||||||
	rtx->exit_level = EXIT_NONE;
 | 
						rtx->exit_level = EXIT_NONE;
 | 
				
			||||||
	return ret;
 | 
						return retv;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* call an AWK function */
 | 
					/* call an AWK function */
 | 
				
			||||||
@ -5846,7 +5828,8 @@ static qse_size_t push_arg_from_nde (
 | 
				
			|||||||
			 qse_strlen(fnc_arg_spec) > nargs));
 | 
								 qse_strlen(fnc_arg_spec) > nargs));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (fnc_arg_spec != QSE_NULL && 
 | 
							if (fnc_arg_spec != QSE_NULL && 
 | 
				
			||||||
		    fnc_arg_spec[nargs] == QSE_T('r'))
 | 
							    (fnc_arg_spec[nargs] == QSE_T('r') ||
 | 
				
			||||||
 | 
							     fnc_arg_spec[0] == QSE_T('R')))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			qse_awk_val_t** ref;
 | 
								qse_awk_val_t** ref;
 | 
				
			||||||
			      
 | 
								      
 | 
				
			||||||
@ -5872,6 +5855,7 @@ static qse_size_t push_arg_from_nde (
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			v = eval_expression (rtx, p);
 | 
								v = eval_expression (rtx, p);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (v == QSE_NULL)
 | 
							if (v == QSE_NULL)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			UNWIND_RTX_STACK_ARG (rtx, nargs);
 | 
								UNWIND_RTX_STACK_ARG (rtx, nargs);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * $Id: tree.h 235 2009-07-15 10:43:31Z hyunghwan.chung $
 | 
					 * $Id: tree.h 236 2009-07-16 08:27:53Z hyunghwan.chung $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
					   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -76,6 +76,8 @@ enum qse_awk_nde_type_t
 | 
				
			|||||||
	QSE_AWK_NDE_GETLINE
 | 
						QSE_AWK_NDE_GETLINE
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum qse_awk_nde_type_t qse_awk_nde_type_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum qse_awk_in_type_t
 | 
					enum qse_awk_in_type_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* the order of these values match 
 | 
						/* the order of these values match 
 | 
				
			||||||
@ -149,7 +151,7 @@ struct qse_awk_fun_t
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define QSE_AWK_NDE_HDR \
 | 
					#define QSE_AWK_NDE_HDR \
 | 
				
			||||||
	int type; \
 | 
						qse_awk_nde_type_t type; \
 | 
				
			||||||
	qse_size_t line; \
 | 
						qse_size_t line; \
 | 
				
			||||||
	qse_awk_nde_t* next
 | 
						qse_awk_nde_t* next
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -162,7 +164,7 @@ struct qse_awk_nde_t
 | 
				
			|||||||
struct qse_awk_nde_blk_t
 | 
					struct qse_awk_nde_blk_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	QSE_AWK_NDE_HDR;
 | 
						QSE_AWK_NDE_HDR;
 | 
				
			||||||
	qse_size_t nlcls;
 | 
						qse_size_t nlcls; /* number of local variables */
 | 
				
			||||||
	qse_awk_nde_t* body;
 | 
						qse_awk_nde_t* body;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * $Id: awk01.c 195 2009-06-10 13:18:25Z hyunghwan.chung $ 
 | 
					 * $Id: awk01.c 236 2009-07-16 08:27:53Z hyunghwan.chung $ 
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
					   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -35,13 +35,14 @@ int main ()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	qse_awk_t* awk = QSE_NULL;
 | 
						qse_awk_t* awk = QSE_NULL;
 | 
				
			||||||
	qse_awk_rtx_t* rtx = QSE_NULL;
 | 
						qse_awk_rtx_t* rtx = QSE_NULL;
 | 
				
			||||||
 | 
						qse_awk_val_t* retv;
 | 
				
			||||||
	qse_awk_parsestd_in_t psin;
 | 
						qse_awk_parsestd_in_t psin;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	awk = qse_awk_openstd (0);
 | 
						awk = qse_awk_openstd (0);
 | 
				
			||||||
	if (awk == QSE_NULL)  
 | 
						if (awk == QSE_NULL)  
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		qse_fprintf (QSE_STDERR, QSE_T("error: cannot open awk\n"));
 | 
							qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
 | 
				
			||||||
		goto oops;
 | 
							goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -49,11 +50,11 @@ int main ()
 | 
				
			|||||||
	psin.u.cp  = src;
 | 
						psin.u.cp  = src;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = qse_awk_parsestd (awk, &psin, QSE_NULL);
 | 
						ret = qse_awk_parsestd (awk, &psin, QSE_NULL);
 | 
				
			||||||
	if (ret == -1)
 | 
						if (ret <= -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), 
 | 
							qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), 
 | 
				
			||||||
			qse_awk_geterrmsg(awk));
 | 
								qse_awk_geterrmsg(awk));
 | 
				
			||||||
		goto oops;
 | 
							ret = -1; goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rtx = qse_awk_rtx_openstd (
 | 
						rtx = qse_awk_rtx_openstd (
 | 
				
			||||||
@ -65,22 +66,25 @@ int main ()
 | 
				
			|||||||
	);
 | 
						);
 | 
				
			||||||
	if (rtx == QSE_NULL) 
 | 
						if (rtx == QSE_NULL) 
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), 
 | 
							qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), 
 | 
				
			||||||
			qse_awk_geterrmsg(awk));
 | 
								qse_awk_geterrmsg(awk));
 | 
				
			||||||
		goto oops;
 | 
							ret = -1; goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	ret = qse_awk_rtx_loop (rtx);
 | 
						retv = qse_awk_rtx_loop (rtx);
 | 
				
			||||||
	if (ret == -1)
 | 
						if (retv == QSE_NULL)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), 
 | 
							qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), 
 | 
				
			||||||
			qse_awk_rtx_geterrmsg(rtx));
 | 
								qse_awk_rtx_geterrmsg(rtx));
 | 
				
			||||||
		goto oops;
 | 
							ret = -1; goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						qse_awk_rtx_refdownval (rtx, retv);
 | 
				
			||||||
 | 
						ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oops:
 | 
					oops:
 | 
				
			||||||
	if (rtx != QSE_NULL) qse_awk_rtx_close (rtx);
 | 
						if (rtx != QSE_NULL) qse_awk_rtx_close (rtx);
 | 
				
			||||||
	if (awk != QSE_NULL) qse_awk_close (awk);
 | 
						if (awk != QSE_NULL) qse_awk_close (awk);
 | 
				
			||||||
	return -1;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * $Id: awk02.c 195 2009-06-10 13:18:25Z hyunghwan.chung $ 
 | 
					 * $Id: awk02.c 236 2009-07-16 08:27:53Z hyunghwan.chung $ 
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
					   Copyright 2006-2009 Chung, Hyung-Hwan.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -38,6 +38,7 @@ int main ()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	qse_awk_t* awk = QSE_NULL;
 | 
						qse_awk_t* awk = QSE_NULL;
 | 
				
			||||||
	qse_awk_rtx_t* rtx = QSE_NULL;
 | 
						qse_awk_rtx_t* rtx = QSE_NULL;
 | 
				
			||||||
 | 
						qse_awk_val_t* retv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	qse_awk_parsestd_in_t psin;
 | 
						qse_awk_parsestd_in_t psin;
 | 
				
			||||||
	qse_awk_parsestd_out_t psout;
 | 
						qse_awk_parsestd_out_t psout;
 | 
				
			||||||
@ -47,8 +48,8 @@ int main ()
 | 
				
			|||||||
	awk = qse_awk_openstd (0);
 | 
						awk = qse_awk_openstd (0);
 | 
				
			||||||
	if (awk == QSE_NULL)  
 | 
						if (awk == QSE_NULL)  
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		qse_fprintf (QSE_STDERR, QSE_T("error: cannot open awk\n"));
 | 
							qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
 | 
				
			||||||
		goto oops;
 | 
							ret = -1; goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	qse_memset (srcout, QSE_T(' '), QSE_COUNTOF(srcout)-1);
 | 
						qse_memset (srcout, QSE_T(' '), QSE_COUNTOF(srcout)-1);
 | 
				
			||||||
@ -60,11 +61,11 @@ int main ()
 | 
				
			|||||||
	psout.u.cp  = srcout;
 | 
						psout.u.cp  = srcout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = qse_awk_parsestd (awk, &psin, &psout);
 | 
						ret = qse_awk_parsestd (awk, &psin, &psout);
 | 
				
			||||||
	if (ret == -1)
 | 
						if (ret <= -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), 
 | 
							qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), 
 | 
				
			||||||
			qse_awk_geterrmsg(awk));
 | 
								qse_awk_geterrmsg(awk));
 | 
				
			||||||
		goto oops;
 | 
							ret = -1; goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	qse_printf (QSE_T("DEPARSED SOURCE:\n%s\n"), srcout);
 | 
						qse_printf (QSE_T("DEPARSED SOURCE:\n%s\n"), srcout);
 | 
				
			||||||
@ -80,19 +81,22 @@ int main ()
 | 
				
			|||||||
	);
 | 
						);
 | 
				
			||||||
	if (rtx == QSE_NULL) 
 | 
						if (rtx == QSE_NULL) 
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), 
 | 
							qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), 
 | 
				
			||||||
			qse_awk_geterrmsg(awk));
 | 
								qse_awk_geterrmsg(awk));
 | 
				
			||||||
		goto oops;
 | 
							ret = -1; goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	ret = qse_awk_rtx_loop (rtx);
 | 
						retv = qse_awk_rtx_loop (rtx);
 | 
				
			||||||
	if (ret == -1)
 | 
						if (retv == QSE_NULL)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), 
 | 
							qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), 
 | 
				
			||||||
			qse_awk_rtx_geterrmsg(rtx));
 | 
								qse_awk_rtx_geterrmsg(rtx));
 | 
				
			||||||
		goto oops;
 | 
							ret = -1; goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						qse_awk_rtx_refdownval (rtx, retv);
 | 
				
			||||||
 | 
						ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oops:
 | 
					oops:
 | 
				
			||||||
	if (rtx != QSE_NULL) qse_awk_rtx_close (rtx);
 | 
						if (rtx != QSE_NULL) qse_awk_rtx_close (rtx);
 | 
				
			||||||
	if (awk != QSE_NULL) qse_awk_close (awk);
 | 
						if (awk != QSE_NULL) qse_awk_close (awk);
 | 
				
			||||||
 | 
				
			|||||||
@ -49,8 +49,9 @@ static int run_awk (QSE::StdAwk& awk)
 | 
				
			|||||||
	// parse the script string and deparse it to awk05.out.
 | 
						// parse the script string and deparse it to awk05.out.
 | 
				
			||||||
	if (awk.parse (in, out) == QSE_NULL) return -1;
 | 
						if (awk.parse (in, out) == QSE_NULL) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QSE::StdAwk::Value r;
 | 
				
			||||||
	// execute the BEGIN, pattern-action, END blocks.
 | 
						// execute the BEGIN, pattern-action, END blocks.
 | 
				
			||||||
	return awk.loop ();
 | 
						return awk.loop (&r);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int awk_main (int argc, qse_char_t* argv[])
 | 
					static int awk_main (int argc, qse_char_t* argv[])
 | 
				
			||||||
 | 
				
			|||||||
@ -37,6 +37,7 @@ static int run_awk (QSE::StdAwk& awk)
 | 
				
			|||||||
		"function add (a, b) { return a + b }\n"
 | 
							"function add (a, b) { return a + b }\n"
 | 
				
			||||||
		"function mul (a, b) { return a * b }\n"
 | 
							"function mul (a, b) { return a * b }\n"
 | 
				
			||||||
		"function div (a, b) { return a / b }\n"
 | 
							"function div (a, b) { return a / b }\n"
 | 
				
			||||||
 | 
							"function sine (a) { return sin(a) }\n"
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QSE::StdAwk::SourceString in (script);
 | 
						QSE::StdAwk::SourceString in (script);
 | 
				
			||||||
@ -52,16 +53,25 @@ static int run_awk (QSE::StdAwk& awk)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// ret = add (-20, 51) 
 | 
						// ret = add (-20, 51) 
 | 
				
			||||||
	QSE::StdAwk::Value ret;
 | 
						QSE::StdAwk::Value ret;
 | 
				
			||||||
	if (awk.call (QSE_T("add"), &ret, arg, QSE_COUNTOF(arg)) <= -1) return -1;
 | 
						if (awk.call (QSE_T("add"), &ret, arg, 2) <= -1) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// ret = mul (ret, 51);
 | 
						// ret = mul (ret, 51);
 | 
				
			||||||
	arg[0] = ret;
 | 
						arg[0] = ret;
 | 
				
			||||||
	if (awk.call (QSE_T("mul"), &ret, arg, QSE_COUNTOF(arg)) <= -1) return -1;
 | 
						if (awk.call (QSE_T("mul"), &ret, arg, 2) <= -1) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// ret = div (ret, 2);
 | 
						// ret = div (ret, 2);
 | 
				
			||||||
	arg[0] = ret;
 | 
						arg[0] = ret;
 | 
				
			||||||
	if (arg[1].setReal (run, 2) <= -1) return -1;
 | 
						if (arg[1].setReal (run, 2) <= -1) return -1;
 | 
				
			||||||
	if (awk.call (QSE_T("div"), &ret, arg, QSE_COUNTOF(arg)) <= -1) return -1;
 | 
						if (awk.call (QSE_T("div"), &ret, arg, 2) <= -1) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// output the result in various types
 | 
				
			||||||
 | 
						qse_printf (QSE_T("RESULT: (int) [%lld]\n"), (long long)ret.toInt());
 | 
				
			||||||
 | 
						qse_printf (QSE_T("        (real) [%Lf]\n"), (long double)ret.toReal());
 | 
				
			||||||
 | 
						qse_printf (QSE_T("        (str) [%s]\n"), ret.toStr(QSE_NULL));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ret = sine (ret);
 | 
				
			||||||
 | 
						arg[0] = ret;
 | 
				
			||||||
 | 
						if (awk.call (QSE_T("sine"), &ret, arg, 1) <= -1) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// output the result in various types
 | 
						// output the result in various types
 | 
				
			||||||
	qse_printf (QSE_T("RESULT: (int) [%lld]\n"), (long long)ret.toInt());
 | 
						qse_printf (QSE_T("RESULT: (int) [%lld]\n"), (long long)ret.toInt());
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user