Compare commits
16
Commits
d36d1a8675
...
xstack
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
158865a866 | ||
|
|
d516cd2e4b | ||
|
|
79296debb1 | ||
|
|
6999c3ac37 | ||
|
|
c3e4fd8457 | ||
|
|
7f7893d4d1 | ||
|
|
e9f55d259f | ||
|
|
55f8b4f611 | ||
|
|
c5f35799a5 | ||
|
|
26bc3fd397 | ||
|
|
3d8ce4dbcd | ||
|
|
0d313cf474 | ||
|
|
1ca8160e07 | ||
|
|
6e05998bc9 | ||
|
|
0b900e7d0d | ||
|
|
fe643c1c48 |
@@ -723,6 +723,9 @@ Common built-ins:
|
|||||||
- `NR`, `FNR`, `NF`
|
- `NR`, `FNR`, `NF`
|
||||||
- `FS`, `RS`, `OFS`, `ORS`
|
- `FS`, `RS`, `OFS`, `ORS`
|
||||||
- `FILENAME`, `OFILENAME`
|
- `FILENAME`, `OFILENAME`
|
||||||
|
- `ARGC`, `ARGV`
|
||||||
|
- `ENVIRON`
|
||||||
|
- `PIPECLOEXEC`
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -730,6 +733,27 @@ Example:
|
|||||||
{ print NR, NF, $0 }
|
{ print NR, NF, $0 }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Runtime-specific predefined variables:
|
||||||
|
|
||||||
|
| Name | Type | Description |
|
||||||
|
|------|------|-------------|
|
||||||
|
| `ARGC` | int | number of command-line arguments available via `ARGV` |
|
||||||
|
| `ARGV` | array | command-line argument vector. `ARGV[0]` is usually the program name |
|
||||||
|
| `ENVIRON` | map | process environment as a map. Values imported from the host environment may become `int`, `flt`, or `str` depending on content |
|
||||||
|
| `PIPECLOEXEC` | int/bool-like | controls whether file descriptors are opened with `CLOEXEC` when Hawk runs an external command for piping. `0` keeps the default inheritance behavior, `1` enables close-on-exec. This corresponds to `@pragma pipecloexec` |
|
||||||
|
|
||||||
|
`ENVIRON` affects child processes started by piping and `sys::system()`. Modifying it changes the environment passed to those children without changing the process-global environment of the embedding application.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```awk
|
||||||
|
BEGIN {
|
||||||
|
print ARGC, ARGV[0]
|
||||||
|
print ENVIRON["HOME"]
|
||||||
|
PIPECLOEXEC = 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Built-in Functions
|
## Built-in Functions
|
||||||
|
|
||||||
Hawk includes awk built-ins (e.g., `length`, `substr`, `split`, `index`) plus extensions in modules (see below).
|
Hawk includes awk built-ins (e.g., `length`, `substr`, `split`, `index`) plus extensions in modules (see below).
|
||||||
|
|||||||
+2
-1
@@ -34,6 +34,7 @@
|
|||||||
#include <hawk-ecs.h>
|
#include <hawk-ecs.h>
|
||||||
#include <hawk-dir.h>
|
#include <hawk-dir.h>
|
||||||
#include <hawk-glob.h>
|
#include <hawk-glob.h>
|
||||||
|
#include <hawk-utl.h>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
@@ -60,7 +61,7 @@ typedef enum segment_type_t segment_type_t;
|
|||||||
|
|
||||||
|
|
||||||
#define IS_ESC(c) HAWK_FNMAT_IS_ESC(c)
|
#define IS_ESC(c) HAWK_FNMAT_IS_ESC(c)
|
||||||
#define IS_SEP(c) HAWK_FNMAT_IS_SEP(c)
|
#define IS_SEP(c) HAWK_IS_PATH_SEP(c)
|
||||||
#define IS_NIL(c) ((c) == '\0')
|
#define IS_NIL(c) ((c) == '\0')
|
||||||
#define IS_SEP_OR_NIL(c) (IS_SEP(c) || IS_NIL(c))
|
#define IS_SEP_OR_NIL(c) (IS_SEP(c) || IS_NIL(c))
|
||||||
#define IS_DRIVE(c) HAWK_IS_PATH_DRIVE(c)
|
#define IS_DRIVE(c) HAWK_IS_PATH_DRIVE(c)
|
||||||
|
|||||||
+2
-1
@@ -34,6 +34,7 @@
|
|||||||
#include <hawk-ecs.h>
|
#include <hawk-ecs.h>
|
||||||
#include <hawk-dir.h>
|
#include <hawk-dir.h>
|
||||||
#include <hawk-glob.h>
|
#include <hawk-glob.h>
|
||||||
|
#include <hawk-utl.h>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
@@ -60,7 +61,7 @@ typedef enum segment_type_t segment_type_t;
|
|||||||
|
|
||||||
|
|
||||||
#define IS_ESC(c) HAWK_FNMAT_IS_ESC(c)
|
#define IS_ESC(c) HAWK_FNMAT_IS_ESC(c)
|
||||||
#define IS_SEP(c) HAWK_FNMAT_IS_SEP(c)
|
#define IS_SEP(c) HAWK_IS_PATH_SEP(c)
|
||||||
#define IS_NIL(c) ((c) == '\0')
|
#define IS_NIL(c) ((c) == '\0')
|
||||||
#define IS_SEP_OR_NIL(c) (IS_SEP(c) || IS_NIL(c))
|
#define IS_SEP_OR_NIL(c) (IS_SEP(c) || IS_NIL(c))
|
||||||
#define IS_DRIVE(c) HAWK_IS_PATH_DRIVE(c)
|
#define IS_DRIVE(c) HAWK_IS_PATH_DRIVE(c)
|
||||||
|
|||||||
+2
-2
@@ -510,7 +510,7 @@ HAWK_EXPORT hawk_htb_pair_t* hawk_htb_update (
|
|||||||
* if (pair == HAWK_NULL)
|
* if (pair == HAWK_NULL)
|
||||||
* {
|
* {
|
||||||
* // no existing key for the key
|
* // no existing key for the key
|
||||||
* return hawk_htb_allocpair (htb, kptr, klen, v->ptr, v->len);
|
* return hawk_htb_allocpair(htb, kptr, klen, v->ptr, v->len);
|
||||||
* }
|
* }
|
||||||
* else
|
* else
|
||||||
* {
|
* {
|
||||||
@@ -523,7 +523,7 @@ HAWK_EXPORT hawk_htb_pair_t* hawk_htb_update (
|
|||||||
*
|
*
|
||||||
* // allocate a new pair, but without filling the actual value.
|
* // allocate a new pair, but without filling the actual value.
|
||||||
* // note vptr is given HAWK_NULL for that purpose
|
* // note vptr is given HAWK_NULL for that purpose
|
||||||
* new_pair = hawk_htb_allocpair (
|
* new_pair = hawk_htb_allocpair(
|
||||||
* htb, kptr, klen, HAWK_NULL, HAWK_HTB_VLEN(pair) + 1 + v->len);
|
* htb, kptr, klen, HAWK_NULL, HAWK_HTB_VLEN(pair) + 1 + v->len);
|
||||||
* if (new_pair == HAWK_NULL) return HAWK_NULL;
|
* if (new_pair == HAWK_NULL) return HAWK_NULL;
|
||||||
*
|
*
|
||||||
|
|||||||
+103
@@ -69,6 +69,20 @@ typedef struct hawk_tree_t hawk_tree_t;
|
|||||||
#define HAWK_ENABLE_ATOMIC_SIG
|
#define HAWK_ENABLE_ATOMIC_SIG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* this part is kept for preservation of experiment only.
|
||||||
|
#if defined(HAVE_UCONTEXT_H)
|
||||||
|
#include <ucontext.h>
|
||||||
|
#define HAWK_ENABLE_UCONTEXT
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Use iterative (heap-stack) expression evaluation instead of C recursion.
|
||||||
|
* eval_expression, eval_expression0, and hawk_rtx_evalcall automatically
|
||||||
|
* route through the xstack variants when this is defined. Comment out to
|
||||||
|
* revert to the purely recursive implementation. */
|
||||||
|
/*#define HAWK_ENABLE_XSTACK_EVAL*/
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
/* private headers. some files are affected by feature macros above */
|
/* private headers. some files are affected by feature macros above */
|
||||||
@@ -437,6 +451,60 @@ struct hawk_var_xinfo_t
|
|||||||
hawk_loc_t loc;
|
hawk_loc_t loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct hawk_exec_stack_t
|
||||||
|
{
|
||||||
|
int state;
|
||||||
|
hawk_nde_t* nde;
|
||||||
|
hawk_nde_t* ptr; /* next statement in block (EXEC_STATE_BLK_STEP) */
|
||||||
|
hawk_oow_t iv; /* current forin index (EXEC_STATE_FORIN_*) */
|
||||||
|
hawk_oow_t base; /* forin snapshot base (EXEC_STATE_FORIN_*) */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct hawk_exec_stack_t hawk_exec_stack_t;
|
||||||
|
|
||||||
|
/* expression frame states for eval_expression0_xstack */
|
||||||
|
enum hawk_ef_state_t
|
||||||
|
{
|
||||||
|
HAWK_EF_EVAL = 0, /* dispatch on nde->type */
|
||||||
|
HAWK_EF_BIN_LEFT, /* binary: awaiting left result */
|
||||||
|
HAWK_EF_BIN_RIGHT, /* binary: left done (val=left refupped), awaiting right */
|
||||||
|
HAWK_EF_UNARY, /* unary: awaiting operand result */
|
||||||
|
HAWK_EF_CND, /* conditional: awaiting test result */
|
||||||
|
HAWK_EF_ASS_RHS, /* assignment: awaiting RHS result */
|
||||||
|
HAWK_EF_ASS_LHS, /* compound assign: RHS in val (refupped), awaiting LHS */
|
||||||
|
HAWK_EF_LAND_LEFT, /* logical AND: awaiting left result */
|
||||||
|
HAWK_EF_LAND_RIGHT, /* logical AND: left done and true (val=left), awaiting right */
|
||||||
|
HAWK_EF_LOR_LEFT, /* logical OR: awaiting left result */
|
||||||
|
HAWK_EF_LOR_RIGHT, /* logical OR: left done and false (val=left), awaiting right */
|
||||||
|
#if defined(HAWK_ENABLE_XSTACK_EVAL)
|
||||||
|
HAWK_EF_FNCALL_FUN_AWAIT /* user fn body executing on exec_stack; aux=exec_body_base */
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
typedef enum hawk_ef_state_t hawk_ef_state_t;
|
||||||
|
|
||||||
|
struct hawk_eframe_t
|
||||||
|
{
|
||||||
|
hawk_ef_state_t state;
|
||||||
|
hawk_nde_t* nde; /* composite node being processed */
|
||||||
|
hawk_val_t* val; /* intermediate value (refcount incremented) */
|
||||||
|
hawk_oow_t aux; /* FNCALL_FUN_AWAIT: exec_stack size when body frames were pushed */
|
||||||
|
};
|
||||||
|
typedef struct hawk_eframe_t hawk_eframe_t;
|
||||||
|
|
||||||
|
#if defined(HAWK_ENABLE_XSTACK_EVAL)
|
||||||
|
/* call frame: saves context for a user-defined function call made from within
|
||||||
|
* expression evaluation. stored in the call_stack. */
|
||||||
|
struct hawk_call_frame_t
|
||||||
|
{
|
||||||
|
hawk_nde_fncall_t* call; /* call-site node */
|
||||||
|
hawk_fun_t* fun; /* resolved function */
|
||||||
|
hawk_oow_t saved_stack_top; /* rtx->stack_top before the call */
|
||||||
|
hawk_oow_t saved_stack_base;/* rtx->stack_base before the call */
|
||||||
|
hawk_oow_t nargs; /* actual argument count pushed */
|
||||||
|
};
|
||||||
|
typedef struct hawk_call_frame_t hawk_call_frame_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct hawk_rtx_t
|
struct hawk_rtx_t
|
||||||
{
|
{
|
||||||
HAWK_RTX_HDR;
|
HAWK_RTX_HDR;
|
||||||
@@ -451,6 +519,41 @@ struct hawk_rtx_t
|
|||||||
hawk_oow_t stack_base;
|
hawk_oow_t stack_base;
|
||||||
hawk_oow_t stack_limit;
|
hawk_oow_t stack_limit;
|
||||||
|
|
||||||
|
/* heap-based stack for iterative statement execution */
|
||||||
|
hawk_exec_stack_t* exec_stack;
|
||||||
|
hawk_oow_t exec_stack_size;
|
||||||
|
hawk_oow_t exec_stack_limit;
|
||||||
|
|
||||||
|
/* heap-based stack for iterative expression evaluation (xstack variant) */
|
||||||
|
hawk_eframe_t* eframe_stack;
|
||||||
|
hawk_oow_t eframe_stack_size;
|
||||||
|
hawk_oow_t eframe_stack_limit;
|
||||||
|
|
||||||
|
#if defined(HAWK_ENABLE_XSTACK_EVAL)
|
||||||
|
/* heap-based call frame stack: user-defined function calls from eframe evaluation */
|
||||||
|
hawk_call_frame_t* call_stack;
|
||||||
|
hawk_oow_t call_stack_size;
|
||||||
|
hawk_oow_t call_stack_limit;
|
||||||
|
/* result register: eframe eval result delivered to exec AFTER_EVAL frames */
|
||||||
|
hawk_val_t* driver_eval_result;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAWK_ENABLE_UCONTEXT)
|
||||||
|
/* pool of reusable C stacks for coroutine-based function calls */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char* pool[16];
|
||||||
|
hawk_oow_t pool_size;
|
||||||
|
/* arguments for the next coroutine invocation */
|
||||||
|
hawk_nde_blk_t* pending_body;
|
||||||
|
int* pending_result;
|
||||||
|
/* depth at which the current C stack segment started */
|
||||||
|
hawk_oow_t stack_base;
|
||||||
|
/* nonzero when executing on a heap-allocated coroutine stack */
|
||||||
|
int in_coroutine;
|
||||||
|
} co;
|
||||||
|
#endif
|
||||||
|
|
||||||
int exit_level;
|
int exit_level;
|
||||||
int init_called;
|
int init_called;
|
||||||
|
|
||||||
|
|||||||
@@ -72,10 +72,8 @@ enum hawk_fnmat_flag_t
|
|||||||
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
|
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
|
||||||
/* i don't support escaping in these systems */
|
/* i don't support escaping in these systems */
|
||||||
# define HAWK_FNMAT_IS_ESC(c) (0)
|
# define HAWK_FNMAT_IS_ESC(c) (0)
|
||||||
# define HAWK_FNMAT_IS_SEP(c) ((c) == '/' || (c) == '\\')
|
|
||||||
#else
|
#else
|
||||||
# define HAWK_FNMAT_IS_ESC(c) ((c) == '\\')
|
# define HAWK_FNMAT_IS_ESC(c) ((c) == '\\')
|
||||||
# define HAWK_FNMAT_IS_SEP(c) ((c) == '/')
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
|||||||
@@ -72,10 +72,8 @@ enum hawk_fnmat_flag_t
|
|||||||
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
|
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
|
||||||
/* i don't support escaping in these systems */
|
/* i don't support escaping in these systems */
|
||||||
# define HAWK_FNMAT_IS_ESC(c) (0)
|
# define HAWK_FNMAT_IS_ESC(c) (0)
|
||||||
# define HAWK_FNMAT_IS_SEP(c) ((c) == '/' || (c) == '\\')
|
|
||||||
#else
|
#else
|
||||||
# define HAWK_FNMAT_IS_ESC(c) ((c) == '\\')
|
# define HAWK_FNMAT_IS_ESC(c) ((c) == '\\')
|
||||||
# define HAWK_FNMAT_IS_SEP(c) ((c) == '/')
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
|||||||
+6
-2
@@ -1922,12 +1922,14 @@ static HAWK_INLINE void hawk_geterruinf (hawk_t* hawk, hawk_erruinf_t* errinf) {
|
|||||||
* it automatically formatted.
|
* it automatically formatted.
|
||||||
*/
|
*/
|
||||||
#if defined(HAWK_HAVE_INLINE)
|
#if defined(HAWK_HAVE_INLINE)
|
||||||
static HAWK_INLINE void hawk_seterrnum (hawk_t* hawk, const hawk_loc_t* errloc, hawk_errnum_t errnum) { hawk_gem_seterrnum (hawk_getgem(hawk), errloc, errnum); }
|
static HAWK_INLINE void hawk_clrerror (hawk_t* hawk) { hawk_gem_seterrnum(hawk_getgem(hawk), HAWK_NULL, HAWK_ENOERR); }
|
||||||
static HAWK_INLINE void hawk_seterrinf (hawk_t* hawk, const hawk_errinf_t* errinf) { hawk_gem_seterrinf (hawk_getgem(hawk), errinf); }
|
static HAWK_INLINE void hawk_seterrnum (hawk_t* hawk, const hawk_loc_t* errloc, hawk_errnum_t errnum) { hawk_gem_seterrnum(hawk_getgem(hawk), errloc, errnum); }
|
||||||
|
static HAWK_INLINE void hawk_seterrinf (hawk_t* hawk, const hawk_errinf_t* errinf) { hawk_gem_seterrinf(hawk_getgem(hawk), errinf); }
|
||||||
static HAWK_INLINE void hawk_seterror (hawk_t* hawk, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_oocs_t* errarg) { hawk_gem_seterror(hawk_getgem(hawk), errloc, errnum, errarg); }
|
static HAWK_INLINE void hawk_seterror (hawk_t* hawk, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_oocs_t* errarg) { hawk_gem_seterror(hawk_getgem(hawk), errloc, errnum, errarg); }
|
||||||
static HAWK_INLINE const hawk_ooch_t* hawk_backuperrmsg (hawk_t* hawk) { return hawk_gem_backuperrmsg(hawk_getgem(hawk)); }
|
static HAWK_INLINE const hawk_ooch_t* hawk_backuperrmsg (hawk_t* hawk) { return hawk_gem_backuperrmsg(hawk_getgem(hawk)); }
|
||||||
static HAWK_INLINE void hawk_geterror (hawk_t* hawk, hawk_errnum_t* errnum, const hawk_ooch_t** errmsg, hawk_loc_t* errloc) { return hawk_gem_geterror(hawk_getgem(hawk), errnum, errmsg, errloc); }
|
static HAWK_INLINE void hawk_geterror (hawk_t* hawk, hawk_errnum_t* errnum, const hawk_ooch_t** errmsg, hawk_loc_t* errloc) { return hawk_gem_geterror(hawk_getgem(hawk), errnum, errmsg, errloc); }
|
||||||
#else
|
#else
|
||||||
|
#define hawk_clrerror(hawk) hawk_gem_seterrnum(hawk_getgem(hawk), HAWK_NULL, HAWK_ENOERR)
|
||||||
#define hawk_seterrnum(hawk, errloc, errnum) hawk_gem_seterrnum(hawk_getgem(hawk), errloc, errnum)
|
#define hawk_seterrnum(hawk, errloc, errnum) hawk_gem_seterrnum(hawk_getgem(hawk), errloc, errnum)
|
||||||
#define hawk_seterrinf(hawk, errinf) hawk_gem_seterrinf(hawk_getgem(hawk), errinf)
|
#define hawk_seterrinf(hawk, errinf) hawk_gem_seterrinf(hawk_getgem(hawk), errinf)
|
||||||
#define hawk_seterror(hawk, errloc, errnum, errarg) hawk_gem_seterror(hawk_getgem(hawk), errloc, errnum, errarg)
|
#define hawk_seterror(hawk, errloc, errnum, errarg) hawk_gem_seterror(hawk_getgem(hawk), errloc, errnum, errarg)
|
||||||
@@ -3119,11 +3121,13 @@ static HAWK_INLINE void hawk_rtx_geterror (hawk_rtx_t* rtx, hawk_errnum_t* errnu
|
|||||||
* The hawk_rtx_seterrinf() function sets error information.
|
* The hawk_rtx_seterrinf() function sets error information.
|
||||||
*/
|
*/
|
||||||
#if defined(HAWK_HAVE_INLINE)
|
#if defined(HAWK_HAVE_INLINE)
|
||||||
|
static HAWK_INLINE void hawk_rtx_clrerror (hawk_rtx_t* rtx) { hawk_gem_seterrnum(hawk_rtx_getgem(rtx), HAWK_NULL, HAWK_ENOERR); }
|
||||||
static HAWK_INLINE void hawk_rtx_seterrnum (hawk_rtx_t* rtx, const hawk_loc_t* errloc, hawk_errnum_t errnum) { hawk_gem_seterrnum (hawk_rtx_getgem(rtx), errloc, errnum); }
|
static HAWK_INLINE void hawk_rtx_seterrnum (hawk_rtx_t* rtx, const hawk_loc_t* errloc, hawk_errnum_t errnum) { hawk_gem_seterrnum (hawk_rtx_getgem(rtx), errloc, errnum); }
|
||||||
static HAWK_INLINE void hawk_rtx_seterrinf (hawk_rtx_t* rtx, const hawk_errinf_t* errinf) { hawk_gem_seterrinf (hawk_rtx_getgem(rtx), errinf); }
|
static HAWK_INLINE void hawk_rtx_seterrinf (hawk_rtx_t* rtx, const hawk_errinf_t* errinf) { hawk_gem_seterrinf (hawk_rtx_getgem(rtx), errinf); }
|
||||||
static HAWK_INLINE void hawk_rtx_seterror (hawk_rtx_t* rtx, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_oocs_t* errarg) { hawk_gem_seterror(hawk_rtx_getgem(rtx), errloc, errnum, errarg); }
|
static HAWK_INLINE void hawk_rtx_seterror (hawk_rtx_t* rtx, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_oocs_t* errarg) { hawk_gem_seterror(hawk_rtx_getgem(rtx), errloc, errnum, errarg); }
|
||||||
static HAWK_INLINE const hawk_ooch_t* hawk_rtx_backuperrmsg (hawk_rtx_t* rtx) { return hawk_gem_backuperrmsg(hawk_rtx_getgem(rtx)); }
|
static HAWK_INLINE const hawk_ooch_t* hawk_rtx_backuperrmsg (hawk_rtx_t* rtx) { return hawk_gem_backuperrmsg(hawk_rtx_getgem(rtx)); }
|
||||||
#else
|
#else
|
||||||
|
#define hawk_rtx_clrerror(rtx) hawk_gem_seterrnum(hawk_rtx_getgem(rtx), HAWK_NULL, HAWK_ENOERR)
|
||||||
#define hawk_rtx_seterrnum(rtx, errloc, errnum) hawk_gem_seterrnum(hawk_rtx_getgem(rtx), errloc, errnum)
|
#define hawk_rtx_seterrnum(rtx, errloc, errnum) hawk_gem_seterrnum(hawk_rtx_getgem(rtx), errloc, errnum)
|
||||||
#define hawk_rtx_seterrinf(rtx, errinf) hawk_gem_seterrinf(hawk_rtx_getgem(rtx), errinf)
|
#define hawk_rtx_seterrinf(rtx, errinf) hawk_gem_seterrinf(hawk_rtx_getgem(rtx), errinf)
|
||||||
#define hawk_rtx_seterror(rtx, errloc, errnum, errarg) hawk_gem_seterror(hawk_rtx_getgem(rtx), errloc, errnum, errarg)
|
#define hawk_rtx_seterror(rtx, errloc, errnum, errarg) hawk_gem_seterror(hawk_rtx_getgem(rtx), errloc, errnum, errarg)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
#define KTOB(htb,len) ((len) * (htb)->scale[HAWK_HTB_KEY])
|
#define KTOB(htb,len) ((len) * (htb)->scale[HAWK_HTB_KEY])
|
||||||
#define VTOB(htb,len) ((len) * (htb)->scale[HAWK_HTB_VAL])
|
#define VTOB(htb,len) ((len) * (htb)->scale[HAWK_HTB_VAL])
|
||||||
|
|
||||||
HAWK_INLINE pair_t* hawk_htb_allocpair (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen)
|
static HAWK_INLINE_ALWAYS pair_t* alloc_pair (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen)
|
||||||
{
|
{
|
||||||
pair_t* n;
|
pair_t* n;
|
||||||
copier_t kcop, vcop;
|
copier_t kcop, vcop;
|
||||||
@@ -115,7 +115,7 @@ HAWK_INLINE pair_t* hawk_htb_allocpair (hawk_htb_t* htb, void* kptr, hawk_oow_t
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
HAWK_INLINE void hawk_htb_freepair (hawk_htb_t* htb, pair_t* pair)
|
static HAWK_INLINE_ALWAYS void free_pair (hawk_htb_t* htb, pair_t* pair)
|
||||||
{
|
{
|
||||||
if (htb->style->freeer[HAWK_HTB_KEY] != HAWK_NULL)
|
if (htb->style->freeer[HAWK_HTB_KEY] != HAWK_NULL)
|
||||||
htb->style->freeer[HAWK_HTB_KEY](htb, KPTR(pair), KLEN(pair));
|
htb->style->freeer[HAWK_HTB_KEY](htb, KPTR(pair), KLEN(pair));
|
||||||
@@ -124,7 +124,17 @@ HAWK_INLINE void hawk_htb_freepair (hawk_htb_t* htb, pair_t* pair)
|
|||||||
hawk_gem_freemem(htb->gem, pair);
|
hawk_gem_freemem(htb->gem, pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HAWK_INLINE pair_t* change_pair_val (hawk_htb_t* htb, pair_t* pair, void* vptr, hawk_oow_t vlen)
|
pair_t* hawk_htb_allocpair (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen)
|
||||||
|
{
|
||||||
|
return alloc_pair(htb, kptr, klen, vptr, vlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hawk_htb_freepair (hawk_htb_t* htb, pair_t* pair)
|
||||||
|
{
|
||||||
|
free_pair(htb, pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HAWK_INLINE_ALWAYS pair_t* change_pair_val (hawk_htb_t* htb, pair_t* pair, void* vptr, hawk_oow_t vlen)
|
||||||
{
|
{
|
||||||
if (VPTR(pair) == vptr && VLEN(pair) == vlen)
|
if (VPTR(pair) == vptr && VLEN(pair) == vlen)
|
||||||
{
|
{
|
||||||
@@ -157,9 +167,9 @@ static HAWK_INLINE pair_t* change_pair_val (hawk_htb_t* htb, pair_t* pair, void*
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* need to reconstruct the pair */
|
/* need to reconstruct the pair */
|
||||||
pair_t* p = hawk_htb_allocpair(htb, KPTR(pair), KLEN(pair), vptr, vlen);
|
pair_t* p = alloc_pair(htb, KPTR(pair), KLEN(pair), vptr, vlen);
|
||||||
if (HAWK_UNLIKELY(!p)) return HAWK_NULL;
|
if (HAWK_UNLIKELY(!p)) return HAWK_NULL;
|
||||||
hawk_htb_freepair(htb, pair);
|
free_pair(htb, pair);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -436,7 +446,7 @@ static HAWK_INLINE int reorganize (hawk_htb_t* htb)
|
|||||||
#define ENSERT 3
|
#define ENSERT 3
|
||||||
#define INSERT 4
|
#define INSERT 4
|
||||||
|
|
||||||
static HAWK_INLINE pair_t* insert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen, int opt)
|
static HAWK_INLINE_ALWAYS pair_t* insert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen, int opt)
|
||||||
{
|
{
|
||||||
pair_t* pair, * p, * prev, * next;
|
pair_t* pair, * p, * prev, * next;
|
||||||
hawk_oow_t hc;
|
hawk_oow_t hc;
|
||||||
@@ -507,7 +517,7 @@ static HAWK_INLINE pair_t* insert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen,
|
|||||||
|
|
||||||
HAWK_ASSERT(pair == HAWK_NULL);
|
HAWK_ASSERT(pair == HAWK_NULL);
|
||||||
|
|
||||||
pair = hawk_htb_allocpair(htb, kptr, klen, vptr, vlen);
|
pair = alloc_pair(htb, kptr, klen, vptr, vlen);
|
||||||
if (HAWK_UNLIKELY(!pair)) return HAWK_NULL; /* error */
|
if (HAWK_UNLIKELY(!pair)) return HAWK_NULL; /* error */
|
||||||
|
|
||||||
NEXT(pair) = htb->bucket[hc];
|
NEXT(pair) = htb->bucket[hc];
|
||||||
@@ -617,7 +627,7 @@ int hawk_htb_delete (hawk_htb_t* htb, const void* kptr, hawk_oow_t klen)
|
|||||||
htb->bucket[hc] = NEXT(pair);
|
htb->bucket[hc] = NEXT(pair);
|
||||||
else NEXT(prev) = NEXT(pair);
|
else NEXT(prev) = NEXT(pair);
|
||||||
|
|
||||||
hawk_htb_freepair(htb, pair);
|
free_pair(htb, pair);
|
||||||
htb->size--;
|
htb->size--;
|
||||||
htb->rev++;
|
htb->rev++;
|
||||||
|
|
||||||
@@ -645,7 +655,7 @@ void hawk_htb_clear (hawk_htb_t* htb)
|
|||||||
while (pair)
|
while (pair)
|
||||||
{
|
{
|
||||||
next = NEXT(pair);
|
next = NEXT(pair);
|
||||||
hawk_htb_freepair(htb, pair);
|
free_pair(htb, pair);
|
||||||
htb->size--;
|
htb->size--;
|
||||||
pair = next;
|
pair = next;
|
||||||
}
|
}
|
||||||
|
|||||||
+189
-5
@@ -22,6 +22,15 @@
|
|||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <hawk-cfg.h>
|
||||||
|
#if defined(HAVE_ACCEPT4)
|
||||||
|
/* the runtime library has accept4. but accept4 is usually visiable
|
||||||
|
* if _GNU_SOURCE is defined */
|
||||||
|
# if !defined(_GNU_SOURCE)
|
||||||
|
# define _GNU_SOURCE
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mod-sys.h"
|
#include "mod-sys.h"
|
||||||
#include "hawk-prv.h"
|
#include "hawk-prv.h"
|
||||||
#include <hawk-pio.h>
|
#include <hawk-pio.h>
|
||||||
@@ -42,11 +51,8 @@
|
|||||||
#elif defined(__DOS__)
|
#elif defined(__DOS__)
|
||||||
# include <dos.h>
|
# include <dos.h>
|
||||||
#else
|
#else
|
||||||
# if !defined(_GNU_SOURCE)
|
|
||||||
# define _GNU_SOURCE
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# include "syscall.h"
|
# include "syscall.h"
|
||||||
|
# include <sys/utsname.h>
|
||||||
# if defined(HAVE_SYS_EPOLL_H)
|
# if defined(HAVE_SYS_EPOLL_H)
|
||||||
# include <sys/epoll.h>
|
# include <sys/epoll.h>
|
||||||
# if defined(HAVE_EPOLL_CREATE)
|
# if defined(HAVE_EPOLL_CREATE)
|
||||||
@@ -337,6 +343,42 @@ static void set_errmsg_on_sys_list (hawk_rtx_t* rtx, sys_list_t* sys_list, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const hawk_bch_t* get_machine_name_for_build (void)
|
||||||
|
{
|
||||||
|
#if defined(__x86_64__) || defined(_M_X64)
|
||||||
|
return "x86_64";
|
||||||
|
#elif defined(__i386__) || defined(_M_IX86)
|
||||||
|
return "x86";
|
||||||
|
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||||
|
return "aarch64";
|
||||||
|
#elif defined(__arm__) || defined(_M_ARM)
|
||||||
|
return "arm";
|
||||||
|
#elif defined(__powerpc64__) || defined(__ppc64__)
|
||||||
|
return "ppc64";
|
||||||
|
#elif defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC)
|
||||||
|
return "ppc";
|
||||||
|
#elif defined(__mips64)
|
||||||
|
return "mips64";
|
||||||
|
#elif defined(__mips__)
|
||||||
|
return "mips";
|
||||||
|
#elif defined(__riscv) && (__riscv_xlen == 64)
|
||||||
|
return "riscv64";
|
||||||
|
#elif defined(__riscv) && (__riscv_xlen == 32)
|
||||||
|
return "riscv32";
|
||||||
|
#elif defined(__sparc64__)
|
||||||
|
return "sparc64";
|
||||||
|
#elif defined(__sparc__)
|
||||||
|
return "sparc";
|
||||||
|
#else
|
||||||
|
return "unknown";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copy_bcstr_to_oocstr (hawk_rtx_t* rtx, hawk_ooch_t* buf, hawk_oow_t capa, const hawk_bch_t* str)
|
||||||
|
{
|
||||||
|
hawk_rtx_fmttooocstr(rtx, buf, capa, HAWK_T("%hs"), str);
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
static sys_node_t* new_sys_node_fd (hawk_rtx_t* rtx, sys_list_t* list, int fd)
|
static sys_node_t* new_sys_node_fd (hawk_rtx_t* rtx, sys_list_t* list, int fd)
|
||||||
@@ -2332,6 +2374,147 @@ static int fnc_gettid (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fnc_uname (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||||
|
{
|
||||||
|
sys_list_t* sys_list = rtx_to_sys_list(rtx, fi);
|
||||||
|
hawk_val_t* retv;
|
||||||
|
hawk_ooch_t sysname[64], nodename[256], release[64], version[128], machine[64];
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
OSVERSIONINFOEXA vi;
|
||||||
|
SYSTEM_INFO si;
|
||||||
|
DWORD nsz;
|
||||||
|
|
||||||
|
hawk_copy_oocstr(sysname, HAWK_COUNTOF(sysname), HAWK_T("Windows"));
|
||||||
|
hawk_copy_oocstr(nodename, HAWK_COUNTOF(nodename), HAWK_T("unknown"));
|
||||||
|
hawk_copy_oocstr(release, HAWK_COUNTOF(release), HAWK_T("unknown"));
|
||||||
|
hawk_copy_oocstr(version, HAWK_COUNTOF(version), HAWK_T("unknown"));
|
||||||
|
hawk_copy_oocstr(machine, HAWK_COUNTOF(machine), HAWK_T("unknown"));
|
||||||
|
|
||||||
|
nsz = HAWK_COUNTOF(nodename);
|
||||||
|
#if defined(HAWK_OOCH_IS_UCH)
|
||||||
|
GetComputerNameW((LPWSTR)nodename, &nsz);
|
||||||
|
#else
|
||||||
|
GetComputerNameA((LPSTR)nodename, &nsz);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HAWK_MEMSET(&vi, 0, HAWK_SIZEOF(vi));
|
||||||
|
vi.dwOSVersionInfoSize = HAWK_SIZEOF(vi);
|
||||||
|
if (GetVersionExA((OSVERSIONINFOA*)&vi))
|
||||||
|
{
|
||||||
|
hawk_rtx_fmttooocstr(rtx, release, HAWK_COUNTOF(release), HAWK_T("%u.%u.%u"),
|
||||||
|
(unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, (unsigned)vi.dwBuildNumber);
|
||||||
|
if (vi.szCSDVersion[0] != '\0')
|
||||||
|
{
|
||||||
|
hawk_rtx_fmttooocstr(rtx, version, HAWK_COUNTOF(version), HAWK_T("build %u %hs"),
|
||||||
|
(unsigned)vi.dwBuildNumber, vi.szCSDVersion);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hawk_rtx_fmttooocstr(rtx, version, HAWK_COUNTOF(version), HAWK_T("build %u"),
|
||||||
|
(unsigned)vi.dwBuildNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GetSystemInfo(&si);
|
||||||
|
switch (si.wProcessorArchitecture)
|
||||||
|
{
|
||||||
|
case PROCESSOR_ARCHITECTURE_AMD64:
|
||||||
|
hawk_copy_oocstr(machine, HAWK_COUNTOF(machine), HAWK_T("x86_64"));
|
||||||
|
break;
|
||||||
|
case PROCESSOR_ARCHITECTURE_INTEL:
|
||||||
|
hawk_copy_oocstr(machine, HAWK_COUNTOF(machine), HAWK_T("x86"));
|
||||||
|
break;
|
||||||
|
case PROCESSOR_ARCHITECTURE_ARM:
|
||||||
|
hawk_copy_oocstr(machine, HAWK_COUNTOF(machine), HAWK_T("arm"));
|
||||||
|
break;
|
||||||
|
case PROCESSOR_ARCHITECTURE_ARM64:
|
||||||
|
hawk_copy_oocstr(machine, HAWK_COUNTOF(machine), HAWK_T("aarch64"));
|
||||||
|
break;
|
||||||
|
case PROCESSOR_ARCHITECTURE_IA64:
|
||||||
|
hawk_copy_oocstr(machine, HAWK_COUNTOF(machine), HAWK_T("ia64"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
copy_bcstr_to_oocstr(rtx, machine, HAWK_COUNTOF(machine), get_machine_name_for_build());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__OS2__)
|
||||||
|
hawk_copy_oocstr(sysname, HAWK_COUNTOF(sysname), HAWK_T("OS/2"));
|
||||||
|
hawk_copy_oocstr(nodename, HAWK_COUNTOF(nodename), HAWK_T("unknown"));
|
||||||
|
hawk_copy_oocstr(release, HAWK_COUNTOF(release), HAWK_T("unknown"));
|
||||||
|
hawk_copy_oocstr(version, HAWK_COUNTOF(version), HAWK_T("unknown"));
|
||||||
|
copy_bcstr_to_oocstr(rtx, machine, HAWK_COUNTOF(machine), get_machine_name_for_build());
|
||||||
|
|
||||||
|
#elif defined(__DOS__)
|
||||||
|
hawk_copy_oocstr(sysname, HAWK_COUNTOF(sysname), HAWK_T("DOS"));
|
||||||
|
hawk_copy_oocstr(nodename, HAWK_COUNTOF(nodename), HAWK_T("unknown"));
|
||||||
|
hawk_copy_oocstr(release, HAWK_COUNTOF(release), HAWK_T("unknown"));
|
||||||
|
hawk_copy_oocstr(version, HAWK_COUNTOF(version), HAWK_T("unknown"));
|
||||||
|
copy_bcstr_to_oocstr(rtx, machine, HAWK_COUNTOF(machine), get_machine_name_for_build());
|
||||||
|
|
||||||
|
#else
|
||||||
|
struct utsname u;
|
||||||
|
|
||||||
|
if (uname(&u) <= -1)
|
||||||
|
{
|
||||||
|
hawk_copy_oocstr(sysname, HAWK_COUNTOF(sysname), HAWK_T("Linux/Unix"));
|
||||||
|
hawk_copy_oocstr(nodename, HAWK_COUNTOF(nodename), HAWK_T("unknown"));
|
||||||
|
hawk_copy_oocstr(release, HAWK_COUNTOF(release), HAWK_T("unknown"));
|
||||||
|
hawk_copy_oocstr(version, HAWK_COUNTOF(version), HAWK_T("unknown"));
|
||||||
|
copy_bcstr_to_oocstr(rtx, machine, HAWK_COUNTOF(machine), get_machine_name_for_build());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
copy_bcstr_to_oocstr(rtx, sysname, HAWK_COUNTOF(sysname), (const hawk_bch_t*)u.sysname);
|
||||||
|
copy_bcstr_to_oocstr(rtx, nodename, HAWK_COUNTOF(nodename), (const hawk_bch_t*)u.nodename);
|
||||||
|
copy_bcstr_to_oocstr(rtx, release, HAWK_COUNTOF(release), (const hawk_bch_t*)u.release);
|
||||||
|
copy_bcstr_to_oocstr(rtx, version, HAWK_COUNTOF(version), (const hawk_bch_t*)u.version);
|
||||||
|
copy_bcstr_to_oocstr(rtx, machine, HAWK_COUNTOF(machine), (const hawk_bch_t*)u.machine);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
hawk_val_map_data_t md[5];
|
||||||
|
HAWK_MEMSET(md, 0, HAWK_SIZEOF(md));
|
||||||
|
|
||||||
|
md[0].key.ptr = HAWK_T("sysname");
|
||||||
|
md[0].key.len = 7;
|
||||||
|
md[0].type = HAWK_VAL_MAP_DATA_OOCSTR;
|
||||||
|
md[0].vptr = sysname;
|
||||||
|
|
||||||
|
md[1].key.ptr = HAWK_T("nodename");
|
||||||
|
md[1].key.len = 8;
|
||||||
|
md[1].type = HAWK_VAL_MAP_DATA_OOCSTR;
|
||||||
|
md[1].vptr = nodename;
|
||||||
|
|
||||||
|
md[2].key.ptr = HAWK_T("release");
|
||||||
|
md[2].key.len = 7;
|
||||||
|
md[2].type = HAWK_VAL_MAP_DATA_OOCSTR;
|
||||||
|
md[2].vptr = release;
|
||||||
|
|
||||||
|
md[3].key.ptr = HAWK_T("version");
|
||||||
|
md[3].key.len = 7;
|
||||||
|
md[3].type = HAWK_VAL_MAP_DATA_OOCSTR;
|
||||||
|
md[3].vptr = version;
|
||||||
|
|
||||||
|
md[4].key.ptr = HAWK_T("machine");
|
||||||
|
md[4].key.len = 7;
|
||||||
|
md[4].type = HAWK_VAL_MAP_DATA_OOCSTR;
|
||||||
|
md[4].vptr = machine;
|
||||||
|
|
||||||
|
retv = hawk_rtx_makemapvalwithdata(rtx, md, HAWK_COUNTOF(md));
|
||||||
|
if (HAWK_UNLIKELY(!retv))
|
||||||
|
{
|
||||||
|
copy_error_to_sys_list(rtx, sys_list);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hawk_rtx_setretval(rtx, retv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int fnc_getppid (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
static int fnc_getppid (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||||
{
|
{
|
||||||
hawk_int_t rx;
|
hawk_int_t rx;
|
||||||
@@ -3096,7 +3279,7 @@ static int fnc_system (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
0,
|
0,
|
||||||
str,
|
str,
|
||||||
HAWK_PIO_SHELL | HAWK_PIO_NOCLOEXEC,
|
HAWK_PIO_SHELL | HAWK_PIO_NOCLOEXEC,
|
||||||
(rtx->rio.env_mk? pio_env_maker: HAWK_NULL),
|
(rtx->rio.env_mk? pio_env_maker: (hawk_pio_env_mk_t)HAWK_NULL),
|
||||||
rtx
|
rtx
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -6124,6 +6307,7 @@ static hawk_mod_fnc_tab_t fnctab[] =
|
|||||||
{ HAWK_T("tcgetattr"), { { 2, 2, HAWK_T("vr") }, fnc_tcgetattr, 0 } },
|
{ HAWK_T("tcgetattr"), { { 2, 2, HAWK_T("vr") }, fnc_tcgetattr, 0 } },
|
||||||
{ HAWK_T("tcsetattr"), { { 3, 3, HAWK_NULL }, fnc_tcsetattr, 0 } },
|
{ HAWK_T("tcsetattr"), { { 3, 3, HAWK_NULL }, fnc_tcsetattr, 0 } },
|
||||||
{ HAWK_T("tcsetraw"), { { 1, 1, HAWK_NULL }, fnc_tcsetraw, 0 } },
|
{ HAWK_T("tcsetraw"), { { 1, 1, HAWK_NULL }, fnc_tcsetraw, 0 } },
|
||||||
|
{ HAWK_T("uname"), { { 0, 0, HAWK_NULL }, fnc_uname, 0 } },
|
||||||
{ HAWK_T("unlink"), { { 1, 1, HAWK_NULL }, fnc_unlink, 0 } },
|
{ HAWK_T("unlink"), { { 1, 1, HAWK_NULL }, fnc_unlink, 0 } },
|
||||||
{ HAWK_T("unpack"), { { 2, A_MAX, HAWK_T("vvr") }, fnc_unpack, 0 } },
|
{ HAWK_T("unpack"), { { 2, A_MAX, HAWK_T("vvr") }, fnc_unpack, 0 } },
|
||||||
{ HAWK_T("wait"), { { 1, 3, HAWK_T("vrv") }, fnc_wait, 0 } },
|
{ HAWK_T("wait"), { { 1, 3, HAWK_T("vrv") }, fnc_wait, 0 } },
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
#define rotate_left(rbt,pivot) rotate(rbt,pivot,1);
|
#define rotate_left(rbt,pivot) rotate(rbt,pivot,1);
|
||||||
#define rotate_right(rbt,pivot) rotate(rbt,pivot,0);
|
#define rotate_right(rbt,pivot) rotate(rbt,pivot,0);
|
||||||
|
|
||||||
HAWK_INLINE hawk_rbt_pair_t* hawk_rbt_allocpair (
|
static HAWK_INLINE_ALWAYS hawk_rbt_pair_t* alloc_pair (
|
||||||
hawk_rbt_t* rbt, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen)
|
hawk_rbt_t* rbt, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen)
|
||||||
{
|
{
|
||||||
hawk_rbt_pair_t* pair;
|
hawk_rbt_pair_t* pair;
|
||||||
@@ -120,7 +120,7 @@ HAWK_INLINE hawk_rbt_pair_t* hawk_rbt_allocpair (
|
|||||||
return pair;
|
return pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
HAWK_INLINE void hawk_rbt_freepair (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair)
|
static HAWK_INLINE_ALWAYS void free_pair (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair)
|
||||||
{
|
{
|
||||||
if (rbt->style->freeer[HAWK_RBT_KEY])
|
if (rbt->style->freeer[HAWK_RBT_KEY])
|
||||||
rbt->style->freeer[HAWK_RBT_KEY](rbt, KPTR(pair), KLEN(pair));
|
rbt->style->freeer[HAWK_RBT_KEY](rbt, KPTR(pair), KLEN(pair));
|
||||||
@@ -129,6 +129,16 @@ HAWK_INLINE void hawk_rbt_freepair (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair)
|
|||||||
hawk_gem_freemem(rbt->gem, pair);
|
hawk_gem_freemem(rbt->gem, pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hawk_rbt_pair_t* hawk_rbt_allocpair (hawk_rbt_t* rbt, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen)
|
||||||
|
{
|
||||||
|
return alloc_pair(rbt, kptr, klen, vptr, vlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hawk_rbt_freepair (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair)
|
||||||
|
{
|
||||||
|
free_pair(rbt, pair);
|
||||||
|
}
|
||||||
|
|
||||||
static hawk_rbt_style_t style[] =
|
static hawk_rbt_style_t style[] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -450,7 +460,7 @@ static hawk_rbt_pair_t* change_pair_val (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* need to reconstruct the pair */
|
/* need to reconstruct the pair */
|
||||||
hawk_rbt_pair_t* p = hawk_rbt_allocpair(rbt, KPTR(pair), KLEN(pair), vptr, vlen);
|
hawk_rbt_pair_t* p = alloc_pair(rbt, KPTR(pair), KLEN(pair), vptr, vlen);
|
||||||
if (HAWK_UNLIKELY(!p)) return HAWK_NULL;
|
if (HAWK_UNLIKELY(!p)) return HAWK_NULL;
|
||||||
|
|
||||||
p->color = pair->color;
|
p->color = pair->color;
|
||||||
@@ -475,7 +485,7 @@ static hawk_rbt_pair_t* change_pair_val (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair,
|
|||||||
|
|
||||||
if (pair == rbt->root) rbt->root = p;
|
if (pair == rbt->root) rbt->root = p;
|
||||||
|
|
||||||
hawk_rbt_freepair(rbt, pair);
|
free_pair(rbt, pair);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -539,7 +549,7 @@ static hawk_rbt_pair_t* insert (hawk_rbt_t* rbt, void* kptr, hawk_oow_t klen, vo
|
|||||||
return HAWK_NULL;
|
return HAWK_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
x_new = hawk_rbt_allocpair(rbt, kptr, klen, vptr, vlen);
|
x_new = alloc_pair(rbt, kptr, klen, vptr, vlen);
|
||||||
if (HAWK_UNLIKELY(!x_new)) return HAWK_NULL;
|
if (HAWK_UNLIKELY(!x_new)) return HAWK_NULL;
|
||||||
|
|
||||||
if (x_par == HAWK_NULL)
|
if (x_par == HAWK_NULL)
|
||||||
@@ -819,7 +829,7 @@ static void delete_pair (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair)
|
|||||||
if (y->color == HAWK_RBT_BLACK && !IS_NIL(rbt,x))
|
if (y->color == HAWK_RBT_BLACK && !IS_NIL(rbt,x))
|
||||||
adjust_for_delete(rbt, x, parent);
|
adjust_for_delete(rbt, x, parent);
|
||||||
|
|
||||||
hawk_rbt_freepair(rbt, y);
|
free_pair(rbt, y);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -844,7 +854,7 @@ static void delete_pair (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair)
|
|||||||
if (pair->left->parent == pair) pair->left->parent = y;
|
if (pair->left->parent == pair) pair->left->parent = y;
|
||||||
if (pair->right->parent == pair) pair->right->parent = y;
|
if (pair->right->parent == pair) pair->right->parent = y;
|
||||||
|
|
||||||
hawk_rbt_freepair(rbt, pair);
|
free_pair(rbt, pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
rbt->size--;
|
rbt->size--;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ enum hawk_assop_type_t
|
|||||||
/* if you change this, you have to change assop_str in tree.c.
|
/* if you change this, you have to change assop_str in tree.c.
|
||||||
* synchronize it wit:
|
* synchronize it wit:
|
||||||
* - binop_func in eval_assignment of run.c
|
* - binop_func in eval_assignment of run.c
|
||||||
|
* - binop_func in eval_expression0_xstack in run.c
|
||||||
* - assop in assing_to_opcode of parse.c
|
* - assop in assing_to_opcode of parse.c
|
||||||
* - TOK_XXX_ASSN in tok_t in parse.c
|
* - TOK_XXX_ASSN in tok_t in parse.c
|
||||||
* - assop_str in tree.c
|
* - assop_str in tree.c
|
||||||
@@ -149,6 +150,18 @@ hawk_val_t* hawk_rtx_evalcall (
|
|||||||
void* eharg
|
void* eharg
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
hawk_val_t* hawk_rtx_evalcall_xstack (
|
||||||
|
hawk_rtx_t* rtx,
|
||||||
|
hawk_nde_fncall_t* call,
|
||||||
|
hawk_fun_t* fun,
|
||||||
|
hawk_oow_t(*argpusher)(hawk_rtx_t*,const hawk_loc_t* loc,void*),
|
||||||
|
void* apdata,
|
||||||
|
void(*errhandler)(void*),
|
||||||
|
void* eharg
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
int hawk_rtx_setsighandler (
|
int hawk_rtx_setsighandler (
|
||||||
hawk_rtx_t* rtx,
|
hawk_rtx_t* rtx,
|
||||||
int sig,
|
int sig,
|
||||||
|
|||||||
@@ -2133,7 +2133,7 @@ static hawk_ooi_t pio_handler_open (hawk_rtx_t* rtx, hawk_rio_arg_t* riod)
|
|||||||
0,
|
0,
|
||||||
riod->name,
|
riod->name,
|
||||||
flags | HAWK_PIO_SHELL | HAWK_PIO_TEXT | HAWK_PIO_IGNOREECERR,
|
flags | HAWK_PIO_SHELL | HAWK_PIO_TEXT | HAWK_PIO_IGNOREECERR,
|
||||||
(rtx->rio.env_mk? pio_env_maker: HAWK_NULL),
|
(rtx->rio.env_mk? pio_env_maker: (hawk_pio_env_mk_t)HAWK_NULL),
|
||||||
rtx
|
rtx
|
||||||
);
|
);
|
||||||
if (!handle) return -1;
|
if (!handle) return -1;
|
||||||
|
|||||||
+29
-27
@@ -231,7 +231,7 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde, int depth)
|
|||||||
PUT_SRCSTR(hawk, HAWK_T(" "));
|
PUT_SRCSTR(hawk, HAWK_T(" "));
|
||||||
PRINT_EXPR(hawk, px->right);
|
PRINT_EXPR(hawk, px->right);
|
||||||
|
|
||||||
HAWK_ASSERT (px->right->next == HAWK_NULL);
|
HAWK_ASSERT(px->right->next == HAWK_NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,7 +241,7 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde, int depth)
|
|||||||
|
|
||||||
PUT_SRCSTR(hawk, HAWK_T("("));
|
PUT_SRCSTR(hawk, HAWK_T("("));
|
||||||
PRINT_EXPR(hawk, px->left);
|
PRINT_EXPR(hawk, px->left);
|
||||||
HAWK_ASSERT (px->left->next == HAWK_NULL);
|
HAWK_ASSERT(px->left->next == HAWK_NULL);
|
||||||
|
|
||||||
PUT_SRCSTR(hawk, HAWK_T(" "));
|
PUT_SRCSTR(hawk, HAWK_T(" "));
|
||||||
PUT_SRCSTR(hawk, binop_str[px->opcode][(hawk->opt.trait & HAWK_BLANKCONCAT)? 0: 1]);
|
PUT_SRCSTR(hawk, binop_str[px->opcode][(hawk->opt.trait & HAWK_BLANKCONCAT)? 0: 1]);
|
||||||
@@ -252,7 +252,7 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde, int depth)
|
|||||||
PRINT_EXPR(hawk, px->right);
|
PRINT_EXPR(hawk, px->right);
|
||||||
if (px->right->type == HAWK_NDE_ASS)
|
if (px->right->type == HAWK_NDE_ASS)
|
||||||
PUT_SRCSTR(hawk, HAWK_T(")"));
|
PUT_SRCSTR(hawk, HAWK_T(")"));
|
||||||
HAWK_ASSERT (px->right->next == HAWK_NULL);
|
HAWK_ASSERT(px->right->next == HAWK_NULL);
|
||||||
PUT_SRCSTR(hawk, HAWK_T(")"));
|
PUT_SRCSTR(hawk, HAWK_T(")"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -260,7 +260,7 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde, int depth)
|
|||||||
case HAWK_NDE_EXP_UNR:
|
case HAWK_NDE_EXP_UNR:
|
||||||
{
|
{
|
||||||
hawk_nde_exp_t* px = (hawk_nde_exp_t*)nde;
|
hawk_nde_exp_t* px = (hawk_nde_exp_t*)nde;
|
||||||
HAWK_ASSERT (px->right == HAWK_NULL);
|
HAWK_ASSERT(px->right == HAWK_NULL);
|
||||||
|
|
||||||
PUT_SRCSTR(hawk, HAWK_T("("));
|
PUT_SRCSTR(hawk, HAWK_T("("));
|
||||||
PUT_SRCSTR(hawk, unrop_str[px->opcode]);
|
PUT_SRCSTR(hawk, unrop_str[px->opcode]);
|
||||||
@@ -274,7 +274,7 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde, int depth)
|
|||||||
case HAWK_NDE_EXP_INCPRE:
|
case HAWK_NDE_EXP_INCPRE:
|
||||||
{
|
{
|
||||||
hawk_nde_exp_t* px = (hawk_nde_exp_t*)nde;
|
hawk_nde_exp_t* px = (hawk_nde_exp_t*)nde;
|
||||||
HAWK_ASSERT (px->right == HAWK_NULL);
|
HAWK_ASSERT(px->right == HAWK_NULL);
|
||||||
|
|
||||||
PUT_SRCSTR(hawk, incop_str[px->opcode]);
|
PUT_SRCSTR(hawk, incop_str[px->opcode]);
|
||||||
PUT_SRCSTR(hawk, HAWK_T("("));
|
PUT_SRCSTR(hawk, HAWK_T("("));
|
||||||
@@ -286,7 +286,7 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde, int depth)
|
|||||||
case HAWK_NDE_EXP_INCPST:
|
case HAWK_NDE_EXP_INCPST:
|
||||||
{
|
{
|
||||||
hawk_nde_exp_t* px = (hawk_nde_exp_t*)nde;
|
hawk_nde_exp_t* px = (hawk_nde_exp_t*)nde;
|
||||||
HAWK_ASSERT (px->right == HAWK_NULL);
|
HAWK_ASSERT(px->right == HAWK_NULL);
|
||||||
|
|
||||||
PUT_SRCSTR(hawk, HAWK_T("("));
|
PUT_SRCSTR(hawk, HAWK_T("("));
|
||||||
PRINT_EXPR(hawk, px->left);
|
PRINT_EXPR(hawk, px->left);
|
||||||
@@ -659,14 +659,14 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde, int depth)
|
|||||||
hawk_ooch_t tmp[HAWK_SIZEOF(hawk_int_t)*8+2];
|
hawk_ooch_t tmp[HAWK_SIZEOF(hawk_int_t)*8+2];
|
||||||
hawk_oow_t n;
|
hawk_oow_t n;
|
||||||
hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
|
hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
|
||||||
HAWK_ASSERT (px->id.idxa != (hawk_oow_t)-1);
|
HAWK_ASSERT(px->id.idxa != (hawk_oow_t)-1);
|
||||||
|
|
||||||
n = hawk_int_to_oocstr(px->id.idxa, 10, HAWK_NULL, tmp, HAWK_COUNTOF(tmp));
|
n = hawk_int_to_oocstr(px->id.idxa, 10, HAWK_NULL, tmp, HAWK_COUNTOF(tmp));
|
||||||
|
|
||||||
PUT_SRCSTR(hawk, HAWK_T("__p"));
|
PUT_SRCSTR(hawk, HAWK_T("__p"));
|
||||||
PUT_SRCSTRN(hawk, tmp, n);
|
PUT_SRCSTRN(hawk, tmp, n);
|
||||||
|
|
||||||
HAWK_ASSERT (px->idx == HAWK_NULL);
|
HAWK_ASSERT(px->idx == HAWK_NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,8 +674,8 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde, int depth)
|
|||||||
{
|
{
|
||||||
hawk_oow_t n;
|
hawk_oow_t n;
|
||||||
hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
|
hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
|
||||||
HAWK_ASSERT (px->id.idxa != (hawk_oow_t)-1);
|
HAWK_ASSERT(px->id.idxa != (hawk_oow_t)-1);
|
||||||
HAWK_ASSERT (px->idx != HAWK_NULL);
|
HAWK_ASSERT(px->idx != HAWK_NULL);
|
||||||
|
|
||||||
PUT_SRCSTR(hawk, HAWK_T("__p"));
|
PUT_SRCSTR(hawk, HAWK_T("__p"));
|
||||||
n = hawk_int_to_oocstr(px->id.idxa, 10, HAWK_NULL, hawk->tmp.fmt, HAWK_COUNTOF(hawk->tmp.fmt));
|
n = hawk_int_to_oocstr(px->id.idxa, 10, HAWK_NULL, hawk->tmp.fmt, HAWK_COUNTOF(hawk->tmp.fmt));
|
||||||
@@ -687,10 +687,10 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde, int depth)
|
|||||||
case HAWK_NDE_NAMED:
|
case HAWK_NDE_NAMED:
|
||||||
{
|
{
|
||||||
hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
|
hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
|
||||||
/*HAWK_ASSERT (px->id.idxa == (hawk_oow_t)-1);
|
/*HAWK_ASSERT(px->id.idxa == (hawk_oow_t)-1);
|
||||||
* commented out the above assertion because
|
* commented out the above assertion because
|
||||||
* id.idxa field holds an index to the rtx->named_slots. */
|
* id.idxa field holds an index to the rtx->named_slots. */
|
||||||
HAWK_ASSERT (px->idx == HAWK_NULL);
|
HAWK_ASSERT(px->idx == HAWK_NULL);
|
||||||
|
|
||||||
PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
|
PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
|
||||||
break;
|
break;
|
||||||
@@ -699,8 +699,10 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde, int depth)
|
|||||||
case HAWK_NDE_NAMEDIDX:
|
case HAWK_NDE_NAMEDIDX:
|
||||||
{
|
{
|
||||||
hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
|
hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
|
||||||
HAWK_ASSERT (px->id.idxa == (hawk_oow_t)-1);
|
/*HAWK_ASSERT(px->id.idxa == (hawk_oow_t)-1);
|
||||||
HAWK_ASSERT (px->idx != HAWK_NULL);
|
* commented out the above assertion because
|
||||||
|
* id.idxa field holds an index to the rtx->named_slots. */
|
||||||
|
HAWK_ASSERT(px->idx != HAWK_NULL);
|
||||||
|
|
||||||
PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
|
PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
|
||||||
PRINT_EXPR_LIST_FOR_IDX(hawk, px->idx);
|
PRINT_EXPR_LIST_FOR_IDX(hawk, px->idx);
|
||||||
@@ -740,7 +742,7 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde, int depth)
|
|||||||
{
|
{
|
||||||
PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
|
PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
|
||||||
}
|
}
|
||||||
HAWK_ASSERT (px->idx == HAWK_NULL);
|
HAWK_ASSERT(px->idx == HAWK_NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -777,7 +779,7 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde, int depth)
|
|||||||
{
|
{
|
||||||
PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
|
PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
|
||||||
}
|
}
|
||||||
HAWK_ASSERT (px->idx != HAWK_NULL);
|
HAWK_ASSERT(px->idx != HAWK_NULL);
|
||||||
PRINT_EXPR_LIST_FOR_IDX(hawk, px->idx);
|
PRINT_EXPR_LIST_FOR_IDX(hawk, px->idx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -798,7 +800,7 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde, int depth)
|
|||||||
{
|
{
|
||||||
PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
|
PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
|
||||||
}
|
}
|
||||||
HAWK_ASSERT (px->idx == HAWK_NULL);
|
HAWK_ASSERT(px->idx == HAWK_NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -817,7 +819,7 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde, int depth)
|
|||||||
{
|
{
|
||||||
PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
|
PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
|
||||||
}
|
}
|
||||||
HAWK_ASSERT (px->idx != HAWK_NULL);
|
HAWK_ASSERT(px->idx != HAWK_NULL);
|
||||||
PRINT_EXPR_LIST_FOR_IDX(hawk, px->idx);
|
PRINT_EXPR_LIST_FOR_IDX(hawk, px->idx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1027,7 +1029,7 @@ static int print_stmt (hawk_t* hawk, hawk_nde_t* p, int depth, int flags)
|
|||||||
PRINT_EXPR(hawk, px->test);
|
PRINT_EXPR(hawk, px->test);
|
||||||
PUT_SRCSTR(hawk, HAWK_T(") "));
|
PUT_SRCSTR(hawk, HAWK_T(") "));
|
||||||
|
|
||||||
HAWK_ASSERT (px->then_part != HAWK_NULL);
|
HAWK_ASSERT(px->then_part != HAWK_NULL);
|
||||||
xflags = STMT_FLAG_NO_LEAD_INDENT;
|
xflags = STMT_FLAG_NO_LEAD_INDENT;
|
||||||
if (!px->else_part) xflags |= STMT_FLAG_NO_ENDING_NL;
|
if (!px->else_part) xflags |= STMT_FLAG_NO_ENDING_NL;
|
||||||
xdepth = depth + (px->then_part->type != HAWK_NDE_BLK);
|
xdepth = depth + (px->then_part->type != HAWK_NDE_BLK);
|
||||||
@@ -1202,7 +1204,7 @@ static int print_stmt (hawk_t* hawk, hawk_nde_t* p, int depth, int flags)
|
|||||||
hawk_getkwname(hawk, HAWK_KWID_RETURN, &kw);
|
hawk_getkwname(hawk, HAWK_KWID_RETURN, &kw);
|
||||||
PUT_SRCSTRN(hawk, kw.ptr, kw.len);
|
PUT_SRCSTRN(hawk, kw.ptr, kw.len);
|
||||||
PUT_SRCSTR(hawk, HAWK_T(" "));
|
PUT_SRCSTR(hawk, HAWK_T(" "));
|
||||||
HAWK_ASSERT (((hawk_nde_return_t*)p)->val->next == HAWK_NULL);
|
HAWK_ASSERT(((hawk_nde_return_t*)p)->val->next == HAWK_NULL);
|
||||||
|
|
||||||
PRINT_EXPR(hawk, ((hawk_nde_return_t*)p)->val);
|
PRINT_EXPR(hawk, ((hawk_nde_return_t*)p)->val);
|
||||||
PUT_SRCSTR(hawk, HAWK_T(";"));
|
PUT_SRCSTR(hawk, HAWK_T(";"));
|
||||||
@@ -1225,7 +1227,7 @@ static int print_stmt (hawk_t* hawk, hawk_nde_t* p, int depth, int flags)
|
|||||||
hawk_getkwname(hawk, (px->abort? HAWK_KWID_XABORT: HAWK_KWID_EXIT), &kw);
|
hawk_getkwname(hawk, (px->abort? HAWK_KWID_XABORT: HAWK_KWID_EXIT), &kw);
|
||||||
PUT_SRCSTRN(hawk, kw.ptr, kw.len);
|
PUT_SRCSTRN(hawk, kw.ptr, kw.len);
|
||||||
PUT_SRCSTR(hawk, HAWK_T(" "));
|
PUT_SRCSTR(hawk, HAWK_T(" "));
|
||||||
HAWK_ASSERT (px->val->next == HAWK_NULL);
|
HAWK_ASSERT(px->val->next == HAWK_NULL);
|
||||||
PRINT_EXPR(hawk, px->val);
|
PRINT_EXPR(hawk, px->val);
|
||||||
PUT_SRCSTR(hawk, HAWK_T(";"));
|
PUT_SRCSTR(hawk, HAWK_T(";"));
|
||||||
}
|
}
|
||||||
@@ -1494,8 +1496,8 @@ void hawk_clrpt (hawk_t* hawk, hawk_nde_t* tree)
|
|||||||
case HAWK_NDE_EXP_BIN:
|
case HAWK_NDE_EXP_BIN:
|
||||||
{
|
{
|
||||||
hawk_nde_exp_t* px = (hawk_nde_exp_t*)p;
|
hawk_nde_exp_t* px = (hawk_nde_exp_t*)p;
|
||||||
HAWK_ASSERT (px->left->next == HAWK_NULL);
|
HAWK_ASSERT(px->left->next == HAWK_NULL);
|
||||||
HAWK_ASSERT (px->right->next == HAWK_NULL);
|
HAWK_ASSERT(px->right->next == HAWK_NULL);
|
||||||
|
|
||||||
hawk_clrpt(hawk, px->left);
|
hawk_clrpt(hawk, px->left);
|
||||||
hawk_clrpt(hawk, px->right);
|
hawk_clrpt(hawk, px->right);
|
||||||
@@ -1508,7 +1510,7 @@ void hawk_clrpt (hawk_t* hawk, hawk_nde_t* tree)
|
|||||||
case HAWK_NDE_EXP_INCPST:
|
case HAWK_NDE_EXP_INCPST:
|
||||||
{
|
{
|
||||||
hawk_nde_exp_t* px = (hawk_nde_exp_t*)p;
|
hawk_nde_exp_t* px = (hawk_nde_exp_t*)p;
|
||||||
HAWK_ASSERT (px->right == HAWK_NULL);
|
HAWK_ASSERT(px->right == HAWK_NULL);
|
||||||
hawk_clrpt(hawk, px->left);
|
hawk_clrpt(hawk, px->left);
|
||||||
hawk_freemem(hawk, p);
|
hawk_freemem(hawk, p);
|
||||||
break;
|
break;
|
||||||
@@ -1605,7 +1607,7 @@ void hawk_clrpt (hawk_t* hawk, hawk_nde_t* tree)
|
|||||||
case HAWK_NDE_ARG:
|
case HAWK_NDE_ARG:
|
||||||
{
|
{
|
||||||
hawk_nde_var_t* px = (hawk_nde_var_t*)p;
|
hawk_nde_var_t* px = (hawk_nde_var_t*)p;
|
||||||
HAWK_ASSERT (px->idx == HAWK_NULL);
|
HAWK_ASSERT(px->idx == HAWK_NULL);
|
||||||
if (px->id.name.ptr) hawk_freemem(hawk, px->id.name.ptr);
|
if (px->id.name.ptr) hawk_freemem(hawk, px->id.name.ptr);
|
||||||
hawk_freemem(hawk, p);
|
hawk_freemem(hawk, p);
|
||||||
break;
|
break;
|
||||||
@@ -1617,7 +1619,7 @@ void hawk_clrpt (hawk_t* hawk, hawk_nde_t* tree)
|
|||||||
case HAWK_NDE_ARGIDX:
|
case HAWK_NDE_ARGIDX:
|
||||||
{
|
{
|
||||||
hawk_nde_var_t* px = (hawk_nde_var_t*)p;
|
hawk_nde_var_t* px = (hawk_nde_var_t*)p;
|
||||||
HAWK_ASSERT (px->idx != HAWK_NULL);
|
HAWK_ASSERT(px->idx != HAWK_NULL);
|
||||||
hawk_clrpt(hawk, px->idx);
|
hawk_clrpt(hawk, px->idx);
|
||||||
if (px->id.name.ptr) hawk_freemem(hawk, px->id.name.ptr);
|
if (px->id.name.ptr) hawk_freemem(hawk, px->id.name.ptr);
|
||||||
hawk_freemem(hawk, p);
|
hawk_freemem(hawk, p);
|
||||||
@@ -1678,7 +1680,7 @@ void hawk_clrpt (hawk_t* hawk, hawk_nde_t* tree)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
HAWK_ASSERT (!"should never happen - invalid node type");
|
HAWK_ASSERT(!"should never happen - invalid node type");
|
||||||
hawk_freemem(hawk, p);
|
hawk_freemem(hawk, p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -3261,14 +3261,14 @@ int hawk_fnmat_uchars_i (const hawk_uch_t* str, hawk_oow_t slen, const hawk_uch_
|
|||||||
* a period in the pattern explicitly
|
* a period in the pattern explicitly
|
||||||
*/
|
*/
|
||||||
if ((!no_first_period && sp == str) ||
|
if ((!no_first_period && sp == str) ||
|
||||||
(HAWK_FNMAT_IS_SEP(sp[-1]) && (flags & HAWK_FNMAT_PATHNAME)))
|
(HAWK_IS_PATH_SEP(sp[-1]) && (flags & HAWK_FNMAT_PATHNAME)))
|
||||||
{
|
{
|
||||||
if (pc != '.') return 0;
|
if (pc != '.') return 0;
|
||||||
sp++; pp++;
|
sp++; pp++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (HAWK_FNMAT_IS_SEP(sc) && (flags & HAWK_FNMAT_PATHNAME))
|
else if (HAWK_IS_PATH_SEP(sc) && (flags & HAWK_FNMAT_PATHNAME))
|
||||||
{
|
{
|
||||||
while (pc == '*')
|
while (pc == '*')
|
||||||
{
|
{
|
||||||
@@ -3277,7 +3277,7 @@ int hawk_fnmat_uchars_i (const hawk_uch_t* str, hawk_oow_t slen, const hawk_uch_
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* a path separator must be matched explicitly */
|
/* a path separator must be matched explicitly */
|
||||||
if (!HAWK_FNMAT_IS_SEP(pc)) return 0;
|
if (!HAWK_IS_PATH_SEP(pc)) return 0;
|
||||||
sp++; pp++;
|
sp++; pp++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -3307,7 +3307,7 @@ int hawk_fnmat_uchars_i (const hawk_uch_t* str, hawk_oow_t slen, const hawk_uch_
|
|||||||
const hawk_uch_t* s = sp;
|
const hawk_uch_t* s = sp;
|
||||||
for (s = sp; s < se; s++)
|
for (s = sp; s < se; s++)
|
||||||
{
|
{
|
||||||
if (HAWK_FNMAT_IS_SEP(*s)) return 0;
|
if (HAWK_IS_PATH_SEP(*s)) return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@@ -3317,7 +3317,7 @@ int hawk_fnmat_uchars_i (const hawk_uch_t* str, hawk_oow_t slen, const hawk_uch_
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (hawk_fnmat_uchars_i(sp, se - sp, pp, pe - pp, flags, 1)) return 1;
|
if (hawk_fnmat_uchars_i(sp, se - sp, pp, pe - pp, flags, 1)) return 1;
|
||||||
if (HAWK_FNMAT_IS_SEP(*sp) && (flags & HAWK_FNMAT_PATHNAME)) break;
|
if (HAWK_IS_PATH_SEP(*sp) && (flags & HAWK_FNMAT_PATHNAME)) break;
|
||||||
sp++;
|
sp++;
|
||||||
}
|
}
|
||||||
while (sp < se);
|
while (sp < se);
|
||||||
@@ -3492,14 +3492,14 @@ int hawk_fnmat_bchars_i (const hawk_bch_t* str, hawk_oow_t slen, const hawk_bch_
|
|||||||
* a period in the pattern explicitly
|
* a period in the pattern explicitly
|
||||||
*/
|
*/
|
||||||
if ((!no_first_period && sp == str) ||
|
if ((!no_first_period && sp == str) ||
|
||||||
(HAWK_FNMAT_IS_SEP(sp[-1]) && (flags & HAWK_FNMAT_PATHNAME)))
|
(HAWK_IS_PATH_SEP(sp[-1]) && (flags & HAWK_FNMAT_PATHNAME)))
|
||||||
{
|
{
|
||||||
if (pc != '.') return 0;
|
if (pc != '.') return 0;
|
||||||
sp++; pp++;
|
sp++; pp++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (HAWK_FNMAT_IS_SEP(sc) && (flags & HAWK_FNMAT_PATHNAME))
|
else if (HAWK_IS_PATH_SEP(sc) && (flags & HAWK_FNMAT_PATHNAME))
|
||||||
{
|
{
|
||||||
while (pc == '*')
|
while (pc == '*')
|
||||||
{
|
{
|
||||||
@@ -3508,7 +3508,7 @@ int hawk_fnmat_bchars_i (const hawk_bch_t* str, hawk_oow_t slen, const hawk_bch_
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* a path separator must be matched explicitly */
|
/* a path separator must be matched explicitly */
|
||||||
if (!HAWK_FNMAT_IS_SEP(pc)) return 0;
|
if (!HAWK_IS_PATH_SEP(pc)) return 0;
|
||||||
sp++; pp++;
|
sp++; pp++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -3538,7 +3538,7 @@ int hawk_fnmat_bchars_i (const hawk_bch_t* str, hawk_oow_t slen, const hawk_bch_
|
|||||||
const hawk_bch_t* s = sp;
|
const hawk_bch_t* s = sp;
|
||||||
for (s = sp; s < se; s++)
|
for (s = sp; s < se; s++)
|
||||||
{
|
{
|
||||||
if (HAWK_FNMAT_IS_SEP(*s)) return 0;
|
if (HAWK_IS_PATH_SEP(*s)) return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@@ -3548,7 +3548,7 @@ int hawk_fnmat_bchars_i (const hawk_bch_t* str, hawk_oow_t slen, const hawk_bch_
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (hawk_fnmat_bchars_i(sp, se - sp, pp, pe - pp, flags, 1)) return 1;
|
if (hawk_fnmat_bchars_i(sp, se - sp, pp, pe - pp, flags, 1)) return 1;
|
||||||
if (HAWK_FNMAT_IS_SEP(*sp) && (flags & HAWK_FNMAT_PATHNAME)) break;
|
if (HAWK_IS_PATH_SEP(*sp) && (flags & HAWK_FNMAT_PATHNAME)) break;
|
||||||
sp++;
|
sp++;
|
||||||
}
|
}
|
||||||
while (sp < se);
|
while (sp < se);
|
||||||
|
|||||||
+5
-5
@@ -1621,14 +1621,14 @@ int _fn_name_ (const _char_type_* str, hawk_oow_t slen, const _char_type_* ptn,
|
|||||||
* a period in the pattern explicitly
|
* a period in the pattern explicitly
|
||||||
*/
|
*/
|
||||||
if ((!no_first_period && sp == str) ||
|
if ((!no_first_period && sp == str) ||
|
||||||
(HAWK_FNMAT_IS_SEP(sp[-1]) && (flags & HAWK_FNMAT_PATHNAME)))
|
(HAWK_IS_PATH_SEP(sp[-1]) && (flags & HAWK_FNMAT_PATHNAME)))
|
||||||
{
|
{
|
||||||
if (pc != '.') return 0;
|
if (pc != '.') return 0;
|
||||||
sp++; pp++;
|
sp++; pp++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (HAWK_FNMAT_IS_SEP(sc) && (flags & HAWK_FNMAT_PATHNAME))
|
else if (HAWK_IS_PATH_SEP(sc) && (flags & HAWK_FNMAT_PATHNAME))
|
||||||
{
|
{
|
||||||
while (pc == '*')
|
while (pc == '*')
|
||||||
{
|
{
|
||||||
@@ -1637,7 +1637,7 @@ int _fn_name_ (const _char_type_* str, hawk_oow_t slen, const _char_type_* ptn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* a path separator must be matched explicitly */
|
/* a path separator must be matched explicitly */
|
||||||
if (!HAWK_FNMAT_IS_SEP(pc)) return 0;
|
if (!HAWK_IS_PATH_SEP(pc)) return 0;
|
||||||
sp++; pp++;
|
sp++; pp++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1667,7 +1667,7 @@ int _fn_name_ (const _char_type_* str, hawk_oow_t slen, const _char_type_* ptn,
|
|||||||
const _char_type_* s = sp;
|
const _char_type_* s = sp;
|
||||||
for (s = sp; s < se; s++)
|
for (s = sp; s < se; s++)
|
||||||
{
|
{
|
||||||
if (HAWK_FNMAT_IS_SEP(*s)) return 0;
|
if (HAWK_IS_PATH_SEP(*s)) return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1677,7 +1677,7 @@ int _fn_name_ (const _char_type_* str, hawk_oow_t slen, const _char_type_* ptn,
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (_fn_name_()(sp, se - sp, pp, pe - pp, flags, 1)) return 1;
|
if (_fn_name_()(sp, se - sp, pp, pe - pp, flags, 1)) return 1;
|
||||||
if (HAWK_FNMAT_IS_SEP(*sp) && (flags & HAWK_FNMAT_PATHNAME)) break;
|
if (HAWK_IS_PATH_SEP(*sp) && (flags & HAWK_FNMAT_PATHNAME)) break;
|
||||||
sp++;
|
sp++;
|
||||||
}
|
}
|
||||||
while (sp < se);
|
while (sp < se);
|
||||||
|
|||||||
@@ -215,6 +215,18 @@ void hawk_rtx_freevalchunk (
|
|||||||
);
|
);
|
||||||
|
|
||||||
#if defined(HAWK_HAVE_INLINE)
|
#if defined(HAWK_HAVE_INLINE)
|
||||||
|
/* the nocheck versions are defined in case you already know the value
|
||||||
|
* is a pointer and not a static value */
|
||||||
|
static HAWK_INLINE_ALWAYS void hawk_rtx_refupval_nocheck_inline (hawk_rtx_t* rtx, hawk_val_t* val)
|
||||||
|
{
|
||||||
|
#if defined(HAWK_USE_ATOMIC_REFCNT) && defined(HAWK_ATOMIC_FETCH_ADD)
|
||||||
|
HAWK_ATOMIC_FETCH_ADD(&val->v_refs, 1, HAWK_ATOMIC_RELAXED);
|
||||||
|
#else
|
||||||
|
val->v_refs++;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* regular refup with pointer check */
|
||||||
static HAWK_INLINE_ALWAYS void hawk_rtx_refupval_inline (hawk_rtx_t* rtx, hawk_val_t* val)
|
static HAWK_INLINE_ALWAYS void hawk_rtx_refupval_inline (hawk_rtx_t* rtx, hawk_val_t* val)
|
||||||
{
|
{
|
||||||
if (HAWK_VTR_IS_POINTER(val) && !HAWK_IS_STATICVAL(val))
|
if (HAWK_VTR_IS_POINTER(val) && !HAWK_IS_STATICVAL(val))
|
||||||
@@ -226,13 +238,22 @@ static HAWK_INLINE_ALWAYS void hawk_rtx_refupval_inline (hawk_rtx_t* rtx, hawk_v
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(HAWK_USE_ATOMIC_REFCNT) && defined(HAWK_ATOMIC_FETCH_ADD)
|
#elif defined(HAWK_USE_ATOMIC_REFCNT) && defined(HAWK_ATOMIC_FETCH_ADD)
|
||||||
|
|
||||||
|
#define hawk_rtx_refupval_nocheck_inline(rtx, val) do { \
|
||||||
|
HAWK_ATOMIC_FETCH_ADD(&(val)->v_refs, 1, HAWK_ATOMIC_RELAXED); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
#define hawk_rtx_refupval_inline(rtx, val) do { \
|
#define hawk_rtx_refupval_inline(rtx, val) do { \
|
||||||
if (HAWK_VTR_IS_POINTER(val) && !HAWK_IS_STATICVAL(val)) { \
|
if (HAWK_VTR_IS_POINTER(val) && !HAWK_IS_STATICVAL(val)) { \
|
||||||
HAWK_ATOMIC_FETCH_ADD(&(val)->v_refs, 1, HAWK_ATOMIC_RELAXED); \
|
HAWK_ATOMIC_FETCH_ADD(&(val)->v_refs, 1, HAWK_ATOMIC_RELAXED); \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
#define hawk_rtx_refupval_nocheck_inline(rtx, val) do { (val)->v_refs++; } while(0)
|
||||||
|
|
||||||
#define hawk_rtx_refupval_inline(rtx, val) do { \
|
#define hawk_rtx_refupval_inline(rtx, val) do { \
|
||||||
if (HAWK_VTR_IS_POINTER(val) && !HAWK_IS_STATICVAL(val)) (val)->v_refs++; \
|
if (HAWK_VTR_IS_POINTER(val) && !HAWK_IS_STATICVAL(val)) (val)->v_refs++; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ endif
|
|||||||
check_SCRIPTS += h-003.hawk h-004.hawk h-009.hawk h-010.hawk \
|
check_SCRIPTS += h-003.hawk h-004.hawk h-009.hawk h-010.hawk \
|
||||||
h-011.hawk h-012.hawk h-013.hawk h-014.hawk h-015.hawk \
|
h-011.hawk h-012.hawk h-013.hawk h-014.hawk h-015.hawk \
|
||||||
h-016.hawk h-017.hawk h-018.hawk h-019.hawk h-020.hawk \
|
h-016.hawk h-017.hawk h-018.hawk h-019.hawk h-020.hawk \
|
||||||
h-021.hawk h-022.hawk h-023.hawk h-024.hawk
|
h-021.hawk h-022.hawk h-023.hawk h-024.hawk h-025.hawk
|
||||||
|
|
||||||
check_SCRIPTS += regress-filename.sh regress-extra-info.sh regress-environ.sh
|
check_SCRIPTS += regress-filename.sh regress-extra-info.sh regress-environ.sh
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -659,7 +659,8 @@ check_SCRIPTS = $(am__append_1) h-003.hawk h-004.hawk h-009.hawk \
|
|||||||
h-010.hawk h-011.hawk h-012.hawk h-013.hawk h-014.hawk \
|
h-010.hawk h-011.hawk h-012.hawk h-013.hawk h-014.hawk \
|
||||||
h-015.hawk h-016.hawk h-017.hawk h-018.hawk h-019.hawk \
|
h-015.hawk h-016.hawk h-017.hawk h-018.hawk h-019.hawk \
|
||||||
h-020.hawk h-021.hawk h-022.hawk h-023.hawk h-024.hawk \
|
h-020.hawk h-021.hawk h-022.hawk h-023.hawk h-024.hawk \
|
||||||
regress-filename.sh regress-extra-info.sh regress-environ.sh
|
h-025.hawk regress-filename.sh regress-extra-info.sh \
|
||||||
|
regress-environ.sh
|
||||||
check_ERRORS = e-001.err
|
check_ERRORS = e-001.err
|
||||||
EXTRA_DIST = $(check_SCRIPTS) $(check_ERRORS) tap.inc err.sh \
|
EXTRA_DIST = $(check_SCRIPTS) $(check_ERRORS) tap.inc err.sh \
|
||||||
journal-toc.hawk journal-toc.in journal-toc.out journal-toc-html.out \
|
journal-toc.hawk journal-toc.in journal-toc.out journal-toc-html.out \
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
REM if you are two directories down from the top source directory,
|
||||||
|
REM you may run the command like this:
|
||||||
|
REM ..\..\t\cmd-tap-driver.cmd -- ..\..\t\run-hawk-test.cmd -f ..\..\t\h-001.hawk
|
||||||
|
REM -------------------------------------------------------------------------------
|
||||||
REM set HAWK_TEST_COMPILER=Z:\path\to\hawk\bld-mingw64\bin\.libs\hawk.exe
|
REM set HAWK_TEST_COMPILER=Z:\path\to\hawk\bld-mingw64\bin\.libs\hawk.exe
|
||||||
REM Z:\path\to\hawk\t\cmd-tap-driver.cmd --test-name h-011 --log-file h-011.log --trs-file h-011.trs -- Z:\path\to\hawk\t\t\run-hawk-test.cmd -f ..\..\t\h-011.hawk
|
REM Z:\path\to\hawk\t\cmd-tap-driver.cmd --test-name h-011 --log-file h-011.log --trs-file h-011.trs -- Z:\path\to\hawk\t\t\run-hawk-test.cmd -f ..\..\t\h-011.hawk
|
||||||
REM
|
REM
|
||||||
|
|
||||||
@echo off
|
|
||||||
setlocal EnableExtensions DisableDelayedExpansion
|
setlocal EnableExtensions DisableDelayedExpansion
|
||||||
|
|
||||||
set "test_name="
|
set "test_name="
|
||||||
|
|||||||
+14
-1
@@ -13,7 +13,7 @@ function on_sig (sig)
|
|||||||
|
|
||||||
function main ()
|
function main ()
|
||||||
{
|
{
|
||||||
@local r;
|
@local r, u;
|
||||||
@local badpid;
|
@local badpid;
|
||||||
|
|
||||||
g_seen = 0;
|
g_seen = 0;
|
||||||
@@ -84,5 +84,18 @@ function main ()
|
|||||||
r = sys::kill(badpid, sys::SIGINT);
|
r = sys::kill(badpid, sys::SIGINT);
|
||||||
tap_ensure (r, sys::RC_ESYSERR, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure (r, sys::RC_ESYSERR, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
u = sys::uname();
|
||||||
|
tap_ensure (hawk::type(u), hawk::VAL_MAP, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (hawk::typename(u.sysname), "str", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (hawk::typename(u.nodename), "str", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (hawk::typename(u.release), "str", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (hawk::typename(u.version), "str", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (hawk::typename(u.machine), "str", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (length(u.sysname) > 0, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (length(u.nodename) > 0, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (length(u.release) > 0, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (length(u.version) > 0, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (length(u.machine) > 0, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
tap_end ();
|
tap_end ();
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-2
@@ -3,7 +3,7 @@
|
|||||||
@include "tap.inc";
|
@include "tap.inc";
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
@local v, v2, m, m2, js;
|
@local v, v2, v3, m, m2, js;
|
||||||
|
|
||||||
|
|
||||||
v = json::parse("{\"a\":1,\"b\":true,\"c\":null,\"d\":[2,3],\"e\":{\"x\":\"y\"}}");
|
v = json::parse("{\"a\":1,\"b\":true,\"c\":null,\"d\":[2,3],\"e\":{\"x\":\"y\"}}");
|
||||||
@@ -26,7 +26,6 @@ BEGIN {
|
|||||||
m["nested"] = hawk::map();
|
m["nested"] = hawk::map();
|
||||||
m["nested"]["ok"] = 1;
|
m["nested"]["ok"] = 1;
|
||||||
m["nested"]["note"] = "hello\n\"world\"";
|
m["nested"]["note"] = "hello\n\"world\"";
|
||||||
|
|
||||||
js = json::stringify(m);
|
js = json::stringify(m);
|
||||||
m2 = json::parse(js);
|
m2 = json::parse(js);
|
||||||
|
|
||||||
@@ -41,5 +40,14 @@ BEGIN {
|
|||||||
tap_ensure(v2.a.b.c, 1, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(v2.a.b.c, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
tap_ensure(v2["a"].b["c"], 1, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(v2["a"].b["c"], 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
v3 = json::parse("[false,true,null,\"a\\tb\",-12.5]");
|
||||||
|
tap_ensure(hawk::type(v3), hawk::VAL_ARRAY, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(hawk::type(v3[1]), hawk::VAL_BOOL, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(v3[1], @false, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(v3[2], @true, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(hawk::isnil(v3[3]), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(v3[4], "a\tb", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(v3[5], -12.5, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
tap_end();
|
tap_end();
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-3
@@ -44,10 +44,17 @@ function main()
|
|||||||
{
|
{
|
||||||
## if PIPCLOEXEC is turned on, the file descriptor created by the shell (3> in run_pipe_test)
|
## if PIPCLOEXEC is turned on, the file descriptor created by the shell (3> in run_pipe_test)
|
||||||
## doesn't get inherited to the 'cat' commands in the following text
|
## doesn't get inherited to the 'cat' commands in the following text
|
||||||
|
@local uname;
|
||||||
|
|
||||||
run_pipe_test("inherit-default", "BEGIN { print \"hello\" | \"cat >&3\" }", "hello\n");
|
uname = sys::uname()
|
||||||
run_pipe_test("cloexec-global", "BEGIN { PIPECLOEXEC = 1; print \"hello\" | \"cat >&3\" }", "");
|
if (uname["sysname"] ~ /Linux|Unix/) {
|
||||||
run_pipe_test("cloexec-pragma", "@pragma pipecloexec on\nBEGIN { print \"hello\" | \"cat >&3\" }", "");
|
run_pipe_test("inherit-default", "BEGIN { print \"hello\" | \"cat >&3\" }", "hello\n");
|
||||||
|
run_pipe_test("cloexec-global", "BEGIN { PIPECLOEXEC = 1; print \"hello\" | \"cat >&3\" }", "");
|
||||||
|
run_pipe_test("inherit-global-off", "BEGIN { PIPECLOEXEC = 0; print \"hello\" | \"cat >&3\" }", "hello\n");
|
||||||
|
run_pipe_test("cloexec-pragma", "@pragma pipecloexec on\nBEGIN { print \"hello\" | \"cat >&3\" }", "");
|
||||||
|
} else {
|
||||||
|
tap_skip("PIPECLOEXEC not relevant");
|
||||||
|
}
|
||||||
|
|
||||||
tap_end();
|
tap_end();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,6 +139,18 @@ function main()
|
|||||||
tap_ensure(!!@[1], @true, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(!!@[1], @true, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
tap_ensure(!dummy, @false, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(!dummy, @false, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
tap_ensure(!!dummy, @true, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(!!dummy, @true, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tmp = 0;
|
||||||
|
tap_ensure(!tmp && 0, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(!tmp && 1, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(!tmp || 0, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(!tmp || 1, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(1 && !tmp, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(0 || !tmp, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tmp = 1;
|
||||||
|
tap_ensure(!tmp && 0, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(!tmp && 1, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(!tmp || 0, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(!tmp || 1, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
tap_ensure(sprintf("%d", @true), "1", @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(sprintf("%d", @true), "1", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
tap_ensure(sprintf("%d", @false), "0", @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(sprintf("%d", @false), "0", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|||||||
@@ -53,5 +53,9 @@ func main() {
|
|||||||
a["k"].fn = mul;
|
a["k"].fn = mul;
|
||||||
tap_ensure(a["k"].fn(4, 4), 16, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(a["k"].fn(4, 4), 16, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
a = @[ @{} ];
|
||||||
|
a[1].sum = add;
|
||||||
|
tap_ensure(a[1].sum(8, 9), 17, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
tap_end();
|
tap_end();
|
||||||
}
|
}
|
||||||
|
|||||||
+574
@@ -0,0 +1,574 @@
|
|||||||
|
## xstack expression evaluator tests
|
||||||
|
## Covers every eframe state in eval_expression0_xstack:
|
||||||
|
## HAWK_EF_BIN_LEFT/RIGHT - binary operators
|
||||||
|
## HAWK_EF_LAND_LEFT/RIGHT - logical && with short-circuit
|
||||||
|
## HAWK_EF_LOR_LEFT/RIGHT - logical || with short-circuit
|
||||||
|
## HAWK_EF_UNARY - unary operators
|
||||||
|
## HAWK_EF_CND - ternary conditional
|
||||||
|
## HAWK_EF_ASS_RHS - simple assignment
|
||||||
|
## HAWK_EF_ASS_LHS - compound assignment (read-modify-write)
|
||||||
|
|
||||||
|
@pragma entry main
|
||||||
|
@pragma implicit off
|
||||||
|
|
||||||
|
@include "tap.inc";
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## binary arithmetic operators
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_binary_arith( x)
|
||||||
|
{
|
||||||
|
tap_ensure(2 + 3, 5, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(10 - 4, 6, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(3 * 7, 21, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(15 / 4, 3.75, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(17 % 5, 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(2 ^ 10, 1024, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(17 \ 5, 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(-17 \ 5, -3, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## string concatenation (binary)
|
||||||
|
tap_ensure("hello" " " "world", "hello world", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure("a" "b" "c", "abc", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## binary comparison operators
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_binary_cmp()
|
||||||
|
{
|
||||||
|
tap_ensure((3 < 5), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((5 < 3), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((3 <= 3), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((4 <= 3), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((5 > 3), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((3 > 5), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((3 >= 3), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((2 >= 3), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((3 == 3), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((3 == 4), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((3 != 4), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((3 != 3), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## bitwise binary operators
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_binary_bitwise()
|
||||||
|
{
|
||||||
|
tap_ensure((0xF0 & 0xFF), 240, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((0x0F & 0xFF), 15, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((0xF0 | 0x0F), 255, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((0xFF ^^ 0x0F), 240, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((1 << 4), 16, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((256 >> 3), 32, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((0 << 10), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## deeply chained binary expressions (stress eframe stack growth)
|
||||||
|
## The eframe stack starts at 0 and grows 64 at a time; these chains
|
||||||
|
## push many BIN_LEFT frames before resolving any BIN_RIGHT frames.
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_binary_chain( x)
|
||||||
|
{
|
||||||
|
## left-associative chain (parser produces left-leaning tree)
|
||||||
|
x = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10;
|
||||||
|
tap_ensure(x, 55, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
x = 1 * 2 * 3 * 4 * 5;
|
||||||
|
tap_ensure(x, 120, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## deeply parenthesised right-associative nesting
|
||||||
|
x = (1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + 10)))))))));
|
||||||
|
tap_ensure(x, 55, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## mix of operators
|
||||||
|
x = 2 * 3 + 4 * 5 - 6 / 2;
|
||||||
|
tap_ensure(x, 23, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## 20-term sum (forces eframe realloc path)
|
||||||
|
x = 1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20;
|
||||||
|
tap_ensure(x, 210, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## logical AND -- HAWK_EF_LAND_LEFT / HAWK_EF_LAND_RIGHT
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_logical_and( r, se)
|
||||||
|
{
|
||||||
|
## short-circuit: right never evaluated when left is false
|
||||||
|
se = 0;
|
||||||
|
r = 0 && (se = 1);
|
||||||
|
tap_ensure(r, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(se, 0, @SCRIPTNAME, @SCRIPTLINE); ## right NOT evaluated
|
||||||
|
|
||||||
|
## both sides evaluated when left is true
|
||||||
|
se = 0;
|
||||||
|
r = 1 && (se = 99);
|
||||||
|
tap_ensure(r, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(se, 99, @SCRIPTNAME, @SCRIPTLINE); ## right WAS evaluated
|
||||||
|
|
||||||
|
## false right side
|
||||||
|
r = 1 && 0;
|
||||||
|
tap_ensure(r, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## chained AND
|
||||||
|
r = 1 && 1 && 1;
|
||||||
|
tap_ensure(r, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = 1 && 1 && 0;
|
||||||
|
tap_ensure(r, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## AND with complex subexpressions
|
||||||
|
r = (2 + 3 == 5) && (10 / 2 == 5);
|
||||||
|
tap_ensure(r, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = (2 + 3 == 5) && (10 / 2 == 4);
|
||||||
|
tap_ensure(r, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## logical OR -- HAWK_EF_LOR_LEFT / HAWK_EF_LOR_RIGHT
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_logical_or( r, se)
|
||||||
|
{
|
||||||
|
## short-circuit: right never evaluated when left is true
|
||||||
|
se = 0;
|
||||||
|
r = 1 || (se = 1);
|
||||||
|
tap_ensure(r, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(se, 0, @SCRIPTNAME, @SCRIPTLINE); ## right NOT evaluated
|
||||||
|
|
||||||
|
## both sides evaluated when left is false
|
||||||
|
se = 0;
|
||||||
|
r = 0 || (se = 77);
|
||||||
|
tap_ensure(r, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(se, 77, @SCRIPTNAME, @SCRIPTLINE); ## right WAS evaluated
|
||||||
|
|
||||||
|
## false || false
|
||||||
|
r = 0 || 0;
|
||||||
|
tap_ensure(r, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## chained OR
|
||||||
|
r = 0 || 0 || 1;
|
||||||
|
tap_ensure(r, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = 0 || 0 || 0;
|
||||||
|
tap_ensure(r, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## OR with complex subexpressions
|
||||||
|
r = (1 == 2) || (3 * 3 == 9);
|
||||||
|
tap_ensure(r, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = (1 == 2) || (2 + 2 == 5);
|
||||||
|
tap_ensure(r, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## mixed AND/OR with nested short-circuit
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_logical_mixed( r, se)
|
||||||
|
{
|
||||||
|
r = (1 && 1) || (0 && 1);
|
||||||
|
tap_ensure(r, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = (0 || 0) && (1 || 0);
|
||||||
|
tap_ensure(r, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = (0 || 1) && (1 && 1) && (0 || 1);
|
||||||
|
tap_ensure(r, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## right side of AND is never reached because left is short-circuit false
|
||||||
|
se = 0;
|
||||||
|
r = (0 && 1) || (se = 5);
|
||||||
|
tap_ensure(r, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(se, 5, @SCRIPTNAME, @SCRIPTLINE); ## OR's right WAS evaluated
|
||||||
|
|
||||||
|
## right side of OR never reached
|
||||||
|
se = 0;
|
||||||
|
r = (1 || (se = 3)) && 1;
|
||||||
|
tap_ensure(r, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(se, 0, @SCRIPTNAME, @SCRIPTLINE); ## OR's right NOT evaluated
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## unary operators -- HAWK_EF_UNARY
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_unary( x)
|
||||||
|
{
|
||||||
|
x = 5;
|
||||||
|
tap_ensure(-x, -5, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(+x, 5, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(!x, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(!0, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(~0, -1, @SCRIPTNAME, @SCRIPTLINE); ## bitwise NOT
|
||||||
|
|
||||||
|
## nested unary operators (each adds a UNARY frame)
|
||||||
|
tap_ensure(-(-x), 5, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(!!x, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(!!!x, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(~(~0), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## unary applied to binary subexpression
|
||||||
|
tap_ensure(-(2 + 3), -5, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(!(3 < 2), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(-(2 * 3), -6, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(~(0xF0 & 0xFF), -241, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## conditional (ternary) -- HAWK_EF_CND
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_conditional( a, b, x)
|
||||||
|
{
|
||||||
|
a = 10; b = 20;
|
||||||
|
|
||||||
|
## basic true/false branch selection
|
||||||
|
tap_ensure((a < b ? "lt" : "ge"), "lt", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((a > b ? "gt" : "le"), "le", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((a == 10 ? a : b), 10, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((a == 99 ? a : b), 20, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## nested ternary (each level adds a CND frame)
|
||||||
|
x = (a < b) ? (b < 30 ? "lt30" : "ge30") : "no";
|
||||||
|
tap_ensure(x, "lt30", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
x = (a > b) ? "no" : (b > 15 ? "gt15" : "le15");
|
||||||
|
tap_ensure(x, "gt15", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## ternary with binary expressions in all three positions
|
||||||
|
x = (a + b == 30) ? (a * b) : (a - b);
|
||||||
|
tap_ensure(x, 200, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
x = (a + b == 99) ? (a * b) : (a - b);
|
||||||
|
tap_ensure(x, -10, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## ternary result used in larger expression
|
||||||
|
tap_ensure((a < b ? a : b) + (a > b ? a : b), 30, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## ternary inside AND/OR
|
||||||
|
tap_ensure((1 && (a < b ? 1 : 0)), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((0 || (a > b ? 1 : 0)), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## simple assignment -- HAWK_EF_ASS_RHS (opcode == NONE path)
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_simple_assign( x, y, z)
|
||||||
|
{
|
||||||
|
x = 42;
|
||||||
|
tap_ensure(x, 42, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## assignment with complex RHS (exercises BIN/UNARY/CND inside ASS_RHS)
|
||||||
|
x = 3 * 4 + 5;
|
||||||
|
tap_ensure(x, 17, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
x = (2 < 3 ? 10 : 20) + 5;
|
||||||
|
tap_ensure(x, 15, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
x = !(1 == 2);
|
||||||
|
tap_ensure(x, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## chained assignment (right-to-left: z=7, y=7, x=7)
|
||||||
|
x = y = z = 7;
|
||||||
|
tap_ensure(x, 7, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(y, 7, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(z, 7, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## assignment used as expression in larger context
|
||||||
|
tap_ensure((x = 5) + 3, 8, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(x, 5, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## compound assignment -- HAWK_EF_ASS_LHS (opcode != NONE path)
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_compound_assign( x)
|
||||||
|
{
|
||||||
|
x = 10;
|
||||||
|
x += 5; tap_ensure(x, 15, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
x -= 3; tap_ensure(x, 12, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
x *= 4; tap_ensure(x, 48, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
x /= 6; tap_ensure(x, 8, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
x %= 3; tap_ensure(x, 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
x ^= 8; tap_ensure(x, 256, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
x \= 10; tap_ensure(x, 25, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## compound with complex RHS (BIN evaluator inside ASS_RHS)
|
||||||
|
x = 5;
|
||||||
|
x += 2 * 3; tap_ensure(x, 11, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
x = 100;
|
||||||
|
x -= (3 + 7); tap_ensure(x, 90, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
x = 4;
|
||||||
|
x *= (1 + 1); tap_ensure(x, 8, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## bitwise compound assignments
|
||||||
|
x = 0xFF;
|
||||||
|
x &= 0x0F; tap_ensure(x, 15, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
x = 0xF0;
|
||||||
|
x |= 0x0F; tap_ensure(x, 255, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
x = 0xFF;
|
||||||
|
x ^^= 0x0F; tap_ensure(x, 240, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
x = 1;
|
||||||
|
x <<= 4; tap_ensure(x, 16, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
x >>= 2; tap_ensure(x, 4, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## string concatenation compound assignment
|
||||||
|
x = "hello";
|
||||||
|
x = x " " "world";
|
||||||
|
tap_ensure(x, "hello world", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## function calls with complex argument expressions
|
||||||
|
## (exercises push_arg_from_nde_xstack for each argument)
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function add3(a, b, c) { return a + b + c; }
|
||||||
|
function mul_add(a, b, c) { return a * b + c; }
|
||||||
|
function identity(x) { return x; }
|
||||||
|
function choose(flag, a, b){ return flag ? a : b; }
|
||||||
|
function noop() { return 0; }
|
||||||
|
|
||||||
|
function test_fncall_args( r, tmp)
|
||||||
|
{
|
||||||
|
## args are binary expressions
|
||||||
|
r = add3(1 + 2, 3 * 4, 5 - 1);
|
||||||
|
tap_ensure(r, 19, @SCRIPTNAME, @SCRIPTLINE); ## 3 + 12 + 4
|
||||||
|
|
||||||
|
## arg is a conditional
|
||||||
|
r = choose(1 > 0, "yes", "no");
|
||||||
|
tap_ensure(r, "yes", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = choose(0 > 1, "yes", "no");
|
||||||
|
tap_ensure(r, "no", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## arg is a unary expression
|
||||||
|
r = identity(-(3 + 4));
|
||||||
|
tap_ensure(r, -7, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## arg is itself a function call with complex args
|
||||||
|
r = identity(add3(1, 2, 3));
|
||||||
|
tap_ensure(r, 6, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## arg mixing AND with function call
|
||||||
|
r = choose(1 && 1, add3(1, 2, 3), 0);
|
||||||
|
tap_ensure(r, 6, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = choose(1 && 0, add3(1, 2, 3), 99);
|
||||||
|
tap_ensure(r, 99, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## arg that is an assignment expression (side-effect)
|
||||||
|
tmp = 0;
|
||||||
|
r = add3((tmp = 10), tmp + 1, tmp + 2);
|
||||||
|
tap_ensure(r, 33, @SCRIPTNAME, @SCRIPTLINE); ## 10 + 11 + 12
|
||||||
|
tap_ensure(tmp, 10, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## deeply nested call in arg
|
||||||
|
r = mul_add(add3(1, 1, 1), identity(4), noop() + 2);
|
||||||
|
tap_ensure(r, 14, @SCRIPTNAME, @SCRIPTLINE); ## 3*4 + 2
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## recursive user-defined functions
|
||||||
|
## (each call goes through evalcall/evalcall_xstack)
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function fib(n) { return n <= 1 ? n : fib(n - 1) + fib(n - 2); }
|
||||||
|
function fact(n) { return n <= 1 ? 1 : n * fact(n - 1); }
|
||||||
|
function sum_to(n) { return n <= 0 ? 0 : n + sum_to(n - 1); }
|
||||||
|
function ack(m, n)
|
||||||
|
{
|
||||||
|
if (m == 0) return n + 1;
|
||||||
|
if (n == 0) return ack(m - 1, 1);
|
||||||
|
return ack(m - 1, ack(m, n - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_recursive()
|
||||||
|
{
|
||||||
|
@local r;
|
||||||
|
|
||||||
|
tap_ensure(fib(0), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(fib(1), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(fib(10), 55, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(fib(15), 610, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
tap_ensure(fact(0), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(fact(1), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(fact(10), 3628800, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
tap_ensure(sum_to(0), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(sum_to(100), 5050, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## Ackermann: moderate values to avoid stack overflow
|
||||||
|
tap_ensure(ack(0, 0), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(ack(1, 1), 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(ack(2, 2), 7, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(ack(3, 3), 61, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## deeply nested mixed expressions
|
||||||
|
## (combines BIN, UNARY, CND, ASS — many eframe levels at once)
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_deep_mixed()
|
||||||
|
{
|
||||||
|
@local t, a, b, c, x;
|
||||||
|
|
||||||
|
a = 3; b = 4; c = 5;
|
||||||
|
|
||||||
|
## Pythagorean triple check
|
||||||
|
x = (a*a + b*b == c*c) ? "right" : "wrong";
|
||||||
|
tap_ensure(x, "right", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## deeply nested: binary inside conditional inside assignment
|
||||||
|
x = (a < b) ? (b < c ? a + b + c : a * b) : (a - b) * c;
|
||||||
|
tap_ensure(x, 12, @SCRIPTNAME, @SCRIPTLINE); ## a+b+c = 12
|
||||||
|
|
||||||
|
## right-associated depth 10
|
||||||
|
x = (1+(2+(3+(4+(5+(6+(7+(8+(9+10)))))))));
|
||||||
|
tap_ensure(x, 55, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## logical chains mixed with arithmetic
|
||||||
|
x = (a > 0 && b > 0 && c > 0) ? a * b * c : 0;
|
||||||
|
tap_ensure(x, 60, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## unary inside conditional inside AND
|
||||||
|
x = (!(a > b)) && (-(a - b) > 0);
|
||||||
|
tap_ensure(x, 1, @SCRIPTNAME, @SCRIPTLINE); ## !(3>4)=1, -(3-4)=1 > 0
|
||||||
|
|
||||||
|
## assignment inside binary
|
||||||
|
x = (t = a + b) * (t - a);
|
||||||
|
tap_ensure(x, 28, @SCRIPTNAME, @SCRIPTLINE); ## t=7, 7*4=28
|
||||||
|
tap_ensure(t, 7, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## in operator (delegated to eval_binop_in, not iterative)
|
||||||
|
## Verify the default-case delegation path in eval_expression0_xstack.
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_in_operator()
|
||||||
|
{
|
||||||
|
@local m, r;
|
||||||
|
|
||||||
|
m["x"] = 1; m["y"] = 2;
|
||||||
|
|
||||||
|
tap_ensure(("x" in m), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(("z" in m), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## 'in' inside AND/OR (both iterative and delegated evaluators)
|
||||||
|
tap_ensure((("x" in m) && ("y" in m)), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((("x" in m) && ("z" in m)), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure((("z" in m) || ("x" in m)), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## 'in' inside conditional
|
||||||
|
r = ("x" in m) ? m["x"] : -1;
|
||||||
|
tap_ensure(r, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = ("z" in m) ? m["z"] : -1;
|
||||||
|
tap_ensure(r, -1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## 'in' inside unary
|
||||||
|
tap_ensure(!("z" in m), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(!("x" in m), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## pre/post increment and decrement
|
||||||
|
## (delegated to original eval_expression0 via default: branch)
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_incr_decr( x, r)
|
||||||
|
{
|
||||||
|
x = 5;
|
||||||
|
r = ++x; tap_ensure(r, 6, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(x, 6, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = x++; tap_ensure(r, 6, @SCRIPTNAME, @SCRIPTLINE); ## returns old value
|
||||||
|
tap_ensure(x, 7, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = --x; tap_ensure(r, 6, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(x, 6, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = x--; tap_ensure(r, 6, @SCRIPTNAME, @SCRIPTLINE); ## returns old value
|
||||||
|
tap_ensure(x, 5, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## incr/decr result used in binary expression
|
||||||
|
x = 10;
|
||||||
|
r = (++x) + (++x);
|
||||||
|
tap_ensure(r, 23, @SCRIPTNAME, @SCRIPTLINE); ## 11 + 12
|
||||||
|
tap_ensure(x, 12, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## positional variable ($n) — delegated path
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_positional()
|
||||||
|
{
|
||||||
|
@local r;
|
||||||
|
|
||||||
|
$1 = "hello";
|
||||||
|
$2 = "world";
|
||||||
|
r = $1 " " $2;
|
||||||
|
tap_ensure(r, "hello world", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## positional in conditional (force numeric comparison with +0)
|
||||||
|
$1 = 10;
|
||||||
|
r = ($1 + 0 > 5 ? $1 * 2 : $1 / 2);
|
||||||
|
tap_ensure(r, 20, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## positional in compound assignment
|
||||||
|
$1 = 3;
|
||||||
|
$1 += 7;
|
||||||
|
tap_ensure($1, 10, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
## match/no-match operators (delegated to eval_binop_ma / eval_binop_nm)
|
||||||
|
## -----------------------------------------------------------------------
|
||||||
|
function test_match_ops()
|
||||||
|
{
|
||||||
|
@local r;
|
||||||
|
|
||||||
|
r = ("hello" ~ /ell/);
|
||||||
|
tap_ensure(r, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = ("hello" ~ /xyz/);
|
||||||
|
tap_ensure(r, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = ("hello" !~ /xyz/);
|
||||||
|
tap_ensure(r, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
r = ("hello" !~ /ell/);
|
||||||
|
tap_ensure(r, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## match result in AND/OR
|
||||||
|
tap_ensure(("abc" ~ /a/) && ("xyz" ~ /x/), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(("abc" ~ /z/) || ("xyz" ~ /x/), 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## match result in conditional
|
||||||
|
r = ("hawk" ~ /awk/) ? "yes" : "no";
|
||||||
|
tap_ensure(r, "yes", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
function main()
|
||||||
|
{
|
||||||
|
test_binary_arith();
|
||||||
|
test_binary_cmp();
|
||||||
|
test_binary_bitwise();
|
||||||
|
test_binary_chain();
|
||||||
|
test_logical_and();
|
||||||
|
test_logical_or();
|
||||||
|
test_logical_mixed();
|
||||||
|
test_unary();
|
||||||
|
test_conditional();
|
||||||
|
test_simple_assign();
|
||||||
|
test_compound_assign();
|
||||||
|
test_fncall_args();
|
||||||
|
test_recursive();
|
||||||
|
test_deep_mixed();
|
||||||
|
test_in_operator();
|
||||||
|
test_incr_decr();
|
||||||
|
test_positional();
|
||||||
|
test_match_ops();
|
||||||
|
tap_end();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user