made match() to accept up to 3 arguments only while keeping str::match() extended with up to 4 arguments
This commit is contained in:
parent
0603e3b1ba
commit
5830d8f9ed
12
README.md
12
README.md
@ -15,7 +15,7 @@ At its core, `Hawk` largely supports all the fundamental features of `AWK`, ensu
|
|||||||
|
|
||||||
1. Pattern-Action Statements: Hawk operates on a series of pattern-action statements. Each statement consists of a pattern that matches input records and an associated action that is executed when the pattern matches.
|
1. Pattern-Action Statements: Hawk operates on a series of pattern-action statements. Each statement consists of a pattern that matches input records and an associated action that is executed when the pattern matches.
|
||||||
1. Record Processing: Hawk processes input data by splitting it into records and fields. Records are typically lines in a file, while fields are segments of each record separated by a field separator (by default, whitespace). This enables powerful text processing capabilities.
|
1. Record Processing: Hawk processes input data by splitting it into records and fields. Records are typically lines in a file, while fields are segments of each record separated by a field separator (by default, whitespace). This enables powerful text processing capabilities.
|
||||||
1. Built-in Variables: Hawk provides a set of built-in variables that facilitate data manipulation. Commonly used variables include NF (number of fields in the current record), NR (current record number), and $n (the value of the nth field in the current record).
|
1. Built-in Variables: Hawk provides a set of built-in variables that facilitate data manipulation. Commonly used variables include `NF` (number of fields in the current record), `NR` (current record number), and `$n` (the value of the nth field in the current record).
|
||||||
1. Built-in Functions: Hawk offers a rich set of built-in functions to perform various operations on data. These functions include string manipulation, numeric calculations, regular expression matching, and more. You can harness their power to transform and analyze your input data effectively.
|
1. Built-in Functions: Hawk offers a rich set of built-in functions to perform various operations on data. These functions include string manipulation, numeric calculations, regular expression matching, and more. You can harness their power to transform and analyze your input data effectively.
|
||||||
1. Output Formatting: Hawk provides flexible control over the formatting and presentation of output. You can customize the field and record separators, control the output field width, and apply formatting rules to align columns.
|
1. Output Formatting: Hawk provides flexible control over the formatting and presentation of output. You can customize the field and record separators, control the output field width, and apply formatting rules to align columns.
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ BEGIN { @local a; a = 10; } # syntax ok - a is declared before use.
|
|||||||
|
|
||||||
### @include and @include_once
|
### @include and @include_once
|
||||||
|
|
||||||
The @include directive inserts the contents of the file specified in the following string as if they appeared in the source stream being processed.
|
The `@include` directive inserts the contents of the file specified in the following string as if they appeared in the source stream being processed.
|
||||||
|
|
||||||
Assuming the `hello.inc` file contains the print_hello() function as shown below,
|
Assuming the `hello.inc` file contains the print_hello() function as shown below,
|
||||||
|
|
||||||
@ -77,9 +77,9 @@ You may include the the file and use the function.
|
|||||||
BEGIN { print_hello(); }
|
BEGIN { print_hello(); }
|
||||||
```
|
```
|
||||||
|
|
||||||
The semicolon after the included file name is optional. You could write @include "hello.inc" without the ending semicolon.
|
The semicolon after the included file name is optional. You could write `@include "hello.inc"` without the ending semicolon.
|
||||||
|
|
||||||
@include_once is similar to @include except it doesn't include the same file multiple times.
|
`@include_once` is similar to `@include` except it doesn't include the same file multiple times.
|
||||||
|
|
||||||
```
|
```
|
||||||
@include_once "hello.inc";
|
@include_once "hello.inc";
|
||||||
@ -234,7 +234,7 @@ Hawk supports various modules.
|
|||||||
- hawk::GC_NUM_GENS
|
- hawk::GC_NUM_GENS
|
||||||
|
|
||||||
#### String
|
#### String
|
||||||
The *str* module provides an extensive set of string manipulation functions.
|
The `str` module provides an extensive set of string manipulation functions.
|
||||||
|
|
||||||
- str::fromcharcode
|
- str::fromcharcode
|
||||||
- str::gsub - equivalent to gsub
|
- str::gsub - equivalent to gsub
|
||||||
@ -253,7 +253,7 @@ The *str* module provides an extensive set of string manipulation functions.
|
|||||||
- str::isxdigit
|
- str::isxdigit
|
||||||
- str::length - equivalent to length
|
- str::length - equivalent to length
|
||||||
- str::ltrim
|
- str::ltrim
|
||||||
- str::match - equivalent to match
|
- str::match - similar to match. the optional third argument is the search start index. the optional fourth argument is equivalent to the thrid argument to match().
|
||||||
- str::normspace
|
- str::normspace
|
||||||
- str::printf - equivalent to sprintf
|
- str::printf - equivalent to sprintf
|
||||||
- str::rindex
|
- str::rindex
|
||||||
|
241
lib/fnc.c
241
lib/fnc.c
@ -29,10 +29,11 @@ static int fnc_fflush (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
|||||||
static int fnc_int (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
static int fnc_int (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
||||||
static int fnc_asort (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
static int fnc_asort (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
||||||
static int fnc_asorti (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
static int fnc_asorti (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
||||||
|
static int fnc_match (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
||||||
|
|
||||||
#define A_MAX HAWK_TYPE_MAX(hawk_oow_t)
|
#define A_MAX HAWK_TYPE_MAX(hawk_oow_t)
|
||||||
|
|
||||||
/* Argument Specifier
|
/* Argument Specifier
|
||||||
*
|
*
|
||||||
* Each character in the specifier indicates how a parameter
|
* Each character in the specifier indicates how a parameter
|
||||||
* of the corresponding postion should be passed to a function.
|
* of the corresponding postion should be passed to a function.
|
||||||
@ -40,11 +41,11 @@ static int fnc_asorti (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
|||||||
* - v: value. pass it after normal evaluation.
|
* - v: value. pass it after normal evaluation.
|
||||||
* - r: pass a variable by reference
|
* - r: pass a variable by reference
|
||||||
* - x: regular expression as it is. not evaluated as /rex/ ~ $0.
|
* - x: regular expression as it is. not evaluated as /rex/ ~ $0.
|
||||||
*
|
*
|
||||||
* NOTE: If min is greater than max, the specifier indicate the
|
* NOTE: If min is greater than max, the specifier indicate the
|
||||||
* name of the module where the function is located.
|
* name of the module where the function is located.
|
||||||
*/
|
*/
|
||||||
static hawk_fnc_t sysfnctab[] =
|
static hawk_fnc_t sysfnctab[] =
|
||||||
{
|
{
|
||||||
/* io functions */
|
/* io functions */
|
||||||
{ {HAWK_T("close"), 5}, 0, { {1, 2, HAWK_NULL}, fnc_close, HAWK_RIO }, HAWK_NULL},
|
{ {HAWK_T("close"), 5}, 0, { {1, 2, HAWK_NULL}, fnc_close, HAWK_RIO }, HAWK_NULL},
|
||||||
@ -56,12 +57,12 @@ static hawk_fnc_t sysfnctab[] =
|
|||||||
/* map(array) sort */
|
/* map(array) sort */
|
||||||
{ {HAWK_T("asort"), 5}, 0, { {1, 3, HAWK_T("rrv")}, fnc_asort, 0 }, HAWK_NULL},
|
{ {HAWK_T("asort"), 5}, 0, { {1, 3, HAWK_T("rrv")}, fnc_asort, 0 }, HAWK_NULL},
|
||||||
{ {HAWK_T("asorti"), 6}, 0, { {1, 3, HAWK_T("rrv")}, fnc_asorti, 0 }, HAWK_NULL},
|
{ {HAWK_T("asorti"), 6}, 0, { {1, 3, HAWK_T("rrv")}, fnc_asorti, 0 }, HAWK_NULL},
|
||||||
|
|
||||||
/* string functions */
|
/* string functions */
|
||||||
{ {HAWK_T("gsub"), 4}, 0, { {2, 3, HAWK_T("xvr")}, hawk_fnc_gsub, 0 }, HAWK_NULL},
|
{ {HAWK_T("gsub"), 4}, 0, { {2, 3, HAWK_T("xvr")}, hawk_fnc_gsub, 0 }, HAWK_NULL},
|
||||||
{ {HAWK_T("index"), 5}, 0, { {2, 3, HAWK_NULL}, hawk_fnc_index, 0 }, HAWK_NULL},
|
{ {HAWK_T("index"), 5}, 0, { {2, 3, HAWK_NULL}, hawk_fnc_index, 0 }, HAWK_NULL},
|
||||||
{ {HAWK_T("length"), 6}, 1, { {0, 1, HAWK_NULL}, hawk_fnc_length, 0 }, HAWK_NULL},
|
{ {HAWK_T("length"), 6}, 1, { {0, 1, HAWK_NULL}, hawk_fnc_length, 0 }, HAWK_NULL},
|
||||||
{ {HAWK_T("match"), 5}, 0, { {2, 4, HAWK_T("vxvr")}, hawk_fnc_match, 0 }, HAWK_NULL},
|
{ {HAWK_T("match"), 5}, 0, { {2, 3, HAWK_T("vxr")}, fnc_match, 0 }, HAWK_NULL},
|
||||||
{ {HAWK_T("split"), 5}, 0, { {2, 3, HAWK_T("vrx")}, hawk_fnc_split, 0 }, HAWK_NULL},
|
{ {HAWK_T("split"), 5}, 0, { {2, 3, HAWK_T("vrx")}, hawk_fnc_split, 0 }, HAWK_NULL},
|
||||||
{ {HAWK_T("sprintf"), 7}, 0, { {1, A_MAX, HAWK_NULL}, hawk_fnc_sprintf, 0 }, HAWK_NULL},
|
{ {HAWK_T("sprintf"), 7}, 0, { {1, A_MAX, HAWK_NULL}, hawk_fnc_sprintf, 0 }, HAWK_NULL},
|
||||||
{ {HAWK_T("sub"), 3}, 0, { {2, 3, HAWK_T("xvr")}, hawk_fnc_sub, 0 }, HAWK_NULL},
|
{ {HAWK_T("sub"), 3}, 0, { {2, 3, HAWK_T("xvr")}, hawk_fnc_sub, 0 }, HAWK_NULL},
|
||||||
@ -127,11 +128,11 @@ static hawk_fnc_t* add_fnc (hawk_t* hawk, const hawk_ooch_t* name, const hawk_fn
|
|||||||
if (spec->arg.spec)
|
if (spec->arg.spec)
|
||||||
{
|
{
|
||||||
tmp = fnc->name.ptr + fnc->name.len + 1;
|
tmp = fnc->name.ptr + fnc->name.len + 1;
|
||||||
hawk_copy_oocstr_unlimited (tmp, spec->arg.spec);
|
hawk_copy_oocstr_unlimited (tmp, spec->arg.spec);
|
||||||
fnc->spec.arg.spec = tmp;
|
fnc->spec.arg.spec = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hawk_htb_insert(hawk->fnc.user, (hawk_ooch_t*)ncs.ptr, ncs.len, fnc, 0) == HAWK_NULL)
|
if (!hawk_htb_insert(hawk->fnc.user, (hawk_ooch_t*)ncs.ptr, ncs.len, fnc, 0))
|
||||||
{
|
{
|
||||||
const hawk_ooch_t* bem = hawk_backuperrmsg(hawk);
|
const hawk_ooch_t* bem = hawk_backuperrmsg(hawk);
|
||||||
hawk_seterrfmt (hawk, HAWK_NULL, hawk_geterrnum(hawk), HAWK_T("unable to add function - %js - %js"), name, bem);
|
hawk_seterrfmt (hawk, HAWK_NULL, hawk_geterrnum(hawk), HAWK_T("unable to add function - %js - %js"), name, bem);
|
||||||
@ -163,7 +164,7 @@ hawk_fnc_t* hawk_addfncwithbcstr (hawk_t* hawk, const hawk_bch_t* name, const ha
|
|||||||
}
|
}
|
||||||
|
|
||||||
wcs.ptr = hawk_dupbtoucstr(hawk, name, &wcs.len, 0);
|
wcs.ptr = hawk_dupbtoucstr(hawk, name, &wcs.len, 0);
|
||||||
if (HAWK_UNLIKELY(!wcs.ptr))
|
if (HAWK_UNLIKELY(!wcs.ptr))
|
||||||
{
|
{
|
||||||
if (wspec.arg.spec) hawk_freemem (hawk, (hawk_uch_t*)wspec.arg.spec);
|
if (wspec.arg.spec) hawk_freemem (hawk, (hawk_uch_t*)wspec.arg.spec);
|
||||||
return HAWK_NULL;
|
return HAWK_NULL;
|
||||||
@ -277,10 +278,10 @@ static hawk_fnc_t* find_fnc (hawk_t* hawk, const hawk_oocs_t* name)
|
|||||||
hawk_htb_pair_t* pair;
|
hawk_htb_pair_t* pair;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* search the system function table
|
/* search the system function table
|
||||||
* though some optimization like binary search can
|
* though some optimization like binary search can
|
||||||
* speed up the search, i don't do that since this
|
* speed up the search, i don't do that since this
|
||||||
* function is called durting parse-time only.
|
* function is called durting parse-time only.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < HAWK_COUNTOF(sysfnctab); i++)
|
for (i = 0; i < HAWK_COUNTOF(sysfnctab); i++)
|
||||||
{
|
{
|
||||||
@ -340,7 +341,7 @@ static int fnc_close (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
|
|
||||||
hawk_ooch_t* name, * opt = HAWK_NULL;
|
hawk_ooch_t* name, * opt = HAWK_NULL;
|
||||||
hawk_oow_t len, optlen = 0;
|
hawk_oow_t len, optlen = 0;
|
||||||
|
|
||||||
nargs = hawk_rtx_getnargs(rtx);
|
nargs = hawk_rtx_getnargs(rtx);
|
||||||
HAWK_ASSERT (nargs == 1 || nargs == 2);
|
HAWK_ASSERT (nargs == 1 || nargs == 2);
|
||||||
|
|
||||||
@ -349,12 +350,12 @@ static int fnc_close (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
HAWK_ASSERT (a0 != HAWK_NULL);
|
HAWK_ASSERT (a0 != HAWK_NULL);
|
||||||
|
|
||||||
name = hawk_rtx_getvaloocstr(rtx, a0, &len);
|
name = hawk_rtx_getvaloocstr(rtx, a0, &len);
|
||||||
if (name == HAWK_NULL) return -1;
|
if (!name) return -1;
|
||||||
|
|
||||||
if (a1)
|
if (a1)
|
||||||
{
|
{
|
||||||
opt = hawk_rtx_getvaloocstr(rtx, a1, &optlen);
|
opt = hawk_rtx_getvaloocstr(rtx, a1, &optlen);
|
||||||
if (opt == HAWK_NULL)
|
if (!opt)
|
||||||
{
|
{
|
||||||
hawk_rtx_freevaloocstr(rtx, a0, name);
|
hawk_rtx_freevaloocstr(rtx, a0, name);
|
||||||
return -1;
|
return -1;
|
||||||
@ -363,14 +364,14 @@ static int fnc_close (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
/* getline or print doesn't allow an empty string for the
|
/* getline or print doesn't allow an empty string for the
|
||||||
* input or output file name. so close should not allow
|
* input or output file name. so close should not allow
|
||||||
* it either.
|
* it either.
|
||||||
* another reason for this is if close is called explicitly
|
* another reason for this is if close is called explicitly
|
||||||
* with an empty string, it may close the console that uses
|
* with an empty string, it may close the console that uses
|
||||||
* an empty string for its identification because closeio
|
* an empty string for its identification because closeio
|
||||||
* closes any ios that match the name given unlike
|
* closes any ios that match the name given unlike
|
||||||
* closeio_read or closeio_write. */
|
* closeio_read or closeio_write. */
|
||||||
n = -1;
|
n = -1;
|
||||||
goto skip_close;
|
goto skip_close;
|
||||||
}
|
}
|
||||||
@ -379,12 +380,12 @@ static int fnc_close (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
{
|
{
|
||||||
if (name[--len] == HAWK_T('\0'))
|
if (name[--len] == HAWK_T('\0'))
|
||||||
{
|
{
|
||||||
/* the name contains a null charater.
|
/* the name contains a null charater.
|
||||||
* make close return -1 */
|
* make close return -1 */
|
||||||
n = -1;
|
n = -1;
|
||||||
goto skip_close;
|
goto skip_close;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt)
|
if (opt)
|
||||||
{
|
{
|
||||||
@ -397,7 +398,7 @@ static int fnc_close (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
|
|
||||||
n = hawk_rtx_closeio(rtx, name, opt);
|
n = hawk_rtx_closeio(rtx, name, opt);
|
||||||
/* failure to close is not a critical error. instead, that is
|
/* failure to close is not a critical error. instead, that is
|
||||||
* flagged by the return value of close().
|
* flagged by the return value of close().
|
||||||
if (n <= -1 && rtx->errinf.num != HAWK_EIONMNF)
|
if (n <= -1 && rtx->errinf.num != HAWK_EIONMNF)
|
||||||
{
|
{
|
||||||
if (a0->type != HAWK_VAL_STR) hawk_rtx_freemem (rtx, name);
|
if (a0->type != HAWK_VAL_STR) hawk_rtx_freemem (rtx, name);
|
||||||
@ -410,7 +411,7 @@ skip_close:
|
|||||||
hawk_rtx_freevaloocstr (rtx, a0, name);
|
hawk_rtx_freevaloocstr (rtx, a0, name);
|
||||||
|
|
||||||
v = hawk_rtx_makeintval (rtx, (hawk_int_t)n);
|
v = hawk_rtx_makeintval (rtx, (hawk_int_t)n);
|
||||||
if (v == HAWK_NULL) return -1;
|
if (!v) return -1;
|
||||||
|
|
||||||
hawk_rtx_setretval (rtx, v);
|
hawk_rtx_setretval (rtx, v);
|
||||||
return 0;
|
return 0;
|
||||||
@ -429,13 +430,13 @@ static int flush_io (hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk_ooch_
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
if (rtx->errinf.num == HAWK_EIOIMPL) n = -1;
|
if (rtx->errinf.num == HAWK_EIOIMPL) n = -1;
|
||||||
else if (rtx->errinf.num == HAWK_EIONMNF)
|
else if (rtx->errinf.num == HAWK_EIONMNF)
|
||||||
{
|
{
|
||||||
if (n != 0) n = -2;
|
if (n != 0) n = -2;
|
||||||
}
|
}
|
||||||
else n = -99;
|
else n = -99;
|
||||||
*/
|
*/
|
||||||
if (hawk_rtx_geterrnum(rtx) == HAWK_EIONMNF)
|
if (hawk_rtx_geterrnum(rtx) == HAWK_EIONMNF)
|
||||||
{
|
{
|
||||||
if (n != 0) n = -2;
|
if (n != 0) n = -2;
|
||||||
}
|
}
|
||||||
@ -478,14 +479,14 @@ static int fnc_fflush (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
|
|
||||||
a0 = hawk_rtx_getarg(rtx, 0);
|
a0 = hawk_rtx_getarg(rtx, 0);
|
||||||
str0 = hawk_rtx_getvaloocstr(rtx, a0, &len0);
|
str0 = hawk_rtx_getvaloocstr(rtx, a0, &len0);
|
||||||
if (str0 == HAWK_NULL) return -1;
|
if (!str0) return -1;
|
||||||
|
|
||||||
/* the target name contains a null character.
|
/* the target name contains a null character.
|
||||||
* make fflush return -1 */
|
* make fflush return -1 */
|
||||||
ptr = str0; end = str0 + len0;
|
ptr = str0; end = str0 + len0;
|
||||||
while (ptr < end)
|
while (ptr < end)
|
||||||
{
|
{
|
||||||
if (*ptr == HAWK_T('\0'))
|
if (*ptr == HAWK_T('\0'))
|
||||||
{
|
{
|
||||||
n = -1;
|
n = -1;
|
||||||
goto skip_flush;
|
goto skip_flush;
|
||||||
@ -498,18 +499,18 @@ static int fnc_fflush (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
*
|
*
|
||||||
* flush("") flushes all output streams regardless of names.
|
* flush("") flushes all output streams regardless of names.
|
||||||
* pass HAWK_NULL for the name in that case so that the
|
* pass HAWK_NULL for the name in that case so that the
|
||||||
* callee matches any streams.
|
* callee matches any streams.
|
||||||
*
|
*
|
||||||
* fflush() doesn't specify the type of output streams
|
* fflush() doesn't specify the type of output streams
|
||||||
* so it attemps to flush all types of output streams.
|
* so it attemps to flush all types of output streams.
|
||||||
*
|
*
|
||||||
* though not useful, it's possible to have multiple
|
* though not useful, it's possible to have multiple
|
||||||
* streams with the same name but of different types.
|
* streams with the same name but of different types.
|
||||||
*
|
*
|
||||||
* BEGIN {
|
* BEGIN {
|
||||||
* print 1 | "/tmp/x";
|
* print 1 | "/tmp/x";
|
||||||
* print 1 > "/tmp/x";
|
* print 1 > "/tmp/x";
|
||||||
* fflush("/tmp/x");
|
* fflush("/tmp/x");
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -523,8 +524,8 @@ static int fnc_fflush (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
/*if (n == -99) return -1;*/
|
/*if (n == -99) return -1;*/
|
||||||
|
|
||||||
/* if n remains 1, no io handlers have been defined for
|
/* if n remains 1, no io handlers have been defined for
|
||||||
* file, pipe, and rwpipe. so make fflush return -1.
|
* file, pipe, and rwpipe. so make fflush return -1.
|
||||||
* if n is -2, no such named io has been found at all
|
* if n is -2, no such named io has been found at all
|
||||||
* if n is -1, the io handler has returned an error */
|
* if n is -1, the io handler has returned an error */
|
||||||
if (n != 0) n = -1;
|
if (n != 0) n = -1;
|
||||||
|
|
||||||
@ -533,7 +534,7 @@ static int fnc_fflush (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
v = hawk_rtx_makeintval (rtx, (hawk_int_t)n);
|
v = hawk_rtx_makeintval (rtx, (hawk_int_t)n);
|
||||||
if (v == HAWK_NULL) return -1;
|
if (!v) return -1;
|
||||||
|
|
||||||
hawk_rtx_setretval (rtx, v);
|
hawk_rtx_setretval (rtx, v);
|
||||||
return 0;
|
return 0;
|
||||||
@ -556,7 +557,7 @@ static int index_or_rindex (hawk_rtx_t* rtx, int rindex)
|
|||||||
rindex ("abcdefabcdx", "cd", 8);
|
rindex ("abcdefabcdx", "cd", 8);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (nargs >= 3)
|
if (nargs >= 3)
|
||||||
{
|
{
|
||||||
hawk_val_t* a2;
|
hawk_val_t* a2;
|
||||||
int n;
|
int n;
|
||||||
@ -605,12 +606,12 @@ static int index_or_rindex (hawk_rtx_t* rtx, int rindex)
|
|||||||
ptr = hawk_find_bchars_in_bchars(&str0[boundary-1], len0 - boundary + 1, str1, len1, rtx->gbl.ignorecase);
|
ptr = hawk_find_bchars_in_bchars(&str0[boundary-1], len0 - boundary + 1, str1, len1, rtx->gbl.ignorecase);
|
||||||
}
|
}
|
||||||
|
|
||||||
idx = (ptr == HAWK_NULL)? 0: ((hawk_int_t)(ptr - str0) + 1);
|
idx = (ptr? ((hawk_int_t)(ptr - str0) + 1): 0);
|
||||||
|
|
||||||
hawk_rtx_freevalbcstr (rtx, a1, str1);
|
hawk_rtx_freevalbcstr (rtx, a1, str1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
hawk_ooch_t* str0, * str1, * ptr;
|
hawk_ooch_t* str0, * str1, * ptr;
|
||||||
@ -651,7 +652,7 @@ static int index_or_rindex (hawk_rtx_t* rtx, int rindex)
|
|||||||
ptr = hawk_find_oochars_in_oochars(&str0[boundary-1], len0 - boundary + 1, str1, len1, rtx->gbl.ignorecase);
|
ptr = hawk_find_oochars_in_oochars(&str0[boundary-1], len0 - boundary + 1, str1, len1, rtx->gbl.ignorecase);
|
||||||
}
|
}
|
||||||
|
|
||||||
idx = (ptr == HAWK_NULL)? 0: ((hawk_int_t)(ptr - str0) + 1);
|
idx = (ptr? ((hawk_int_t)(ptr - str0) + 1): 0);
|
||||||
|
|
||||||
hawk_rtx_freevaloocstr (rtx, a1, str1);
|
hawk_rtx_freevaloocstr (rtx, a1, str1);
|
||||||
hawk_rtx_freevaloocstr (rtx, a0, str0);
|
hawk_rtx_freevaloocstr (rtx, a0, str0);
|
||||||
@ -686,7 +687,7 @@ int hawk_fnc_length (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
|
|
||||||
nargs = hawk_rtx_getnargs (rtx);
|
nargs = hawk_rtx_getnargs (rtx);
|
||||||
HAWK_ASSERT (nargs >= 0 && nargs <= 1);
|
HAWK_ASSERT (nargs >= 0 && nargs <= 1);
|
||||||
|
|
||||||
if (nargs == 0)
|
if (nargs == 0)
|
||||||
{
|
{
|
||||||
/* get the length of $0 */
|
/* get the length of $0 */
|
||||||
@ -821,7 +822,7 @@ static int fnc_split (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, int use_array)
|
|||||||
hawk_ooch_t* p;
|
hawk_ooch_t* p;
|
||||||
|
|
||||||
hawk_oow_t org_len;
|
hawk_oow_t org_len;
|
||||||
hawk_tre_t* fs_rex = HAWK_NULL;
|
hawk_tre_t* fs_rex = HAWK_NULL;
|
||||||
hawk_tre_t* fs_rex_free = HAWK_NULL;
|
hawk_tre_t* fs_rex_free = HAWK_NULL;
|
||||||
|
|
||||||
hawk_oocs_t tok;
|
hawk_oocs_t tok;
|
||||||
@ -872,7 +873,7 @@ static int fnc_split (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, int use_array)
|
|||||||
{
|
{
|
||||||
do_fld = 1;
|
do_fld = 1;
|
||||||
}
|
}
|
||||||
else if (fs.len > 1)
|
else if (fs.len > 1)
|
||||||
{
|
{
|
||||||
if (a2)
|
if (a2)
|
||||||
{
|
{
|
||||||
@ -946,7 +947,7 @@ static int fnc_split (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, int use_array)
|
|||||||
}
|
}
|
||||||
else if (do_fld)
|
else if (do_fld)
|
||||||
{
|
{
|
||||||
/* [NOTE] even if byte_str is true, the field seperator is of the ooch type.
|
/* [NOTE] even if byte_str is true, the field seperator is of the ooch type.
|
||||||
* there may be some data truncation and related issues */
|
* there may be some data truncation and related issues */
|
||||||
p = byte_str? (hawk_ooch_t*)hawk_rtx_fldbchars(rtx, (hawk_bch_t*)p, str.len, fs.ptr[1], fs.ptr[2], fs.ptr[3], fs.ptr[4], (hawk_bcs_t*)&tok):
|
p = byte_str? (hawk_ooch_t*)hawk_rtx_fldbchars(rtx, (hawk_bch_t*)p, str.len, fs.ptr[1], fs.ptr[2], fs.ptr[3], fs.ptr[4], (hawk_bcs_t*)&tok):
|
||||||
hawk_rtx_fldoochars(rtx, p, str.len, fs.ptr[1], fs.ptr[2], fs.ptr[3], fs.ptr[4], &tok);
|
hawk_rtx_fldoochars(rtx, p, str.len, fs.ptr[1], fs.ptr[2], fs.ptr[3], fs.ptr[4], &tok);
|
||||||
@ -957,13 +958,13 @@ static int fnc_split (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, int use_array)
|
|||||||
hawk_rtx_tokoocharswithoochars(rtx, p, str.len, fs.ptr, fs.len, &tok);
|
hawk_rtx_tokoocharswithoochars(rtx, p, str.len, fs.ptr, fs.len, &tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nflds == 0 && p == HAWK_NULL && tok.len == 0)
|
if (nflds == 0 && !p && tok.len == 0)
|
||||||
{
|
{
|
||||||
/* no field at all*/
|
/* no field at all*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
HAWK_ASSERT ((tok.ptr != HAWK_NULL && tok.len > 0) || tok.len == 0);
|
HAWK_ASSERT ((tok.ptr && tok.len > 0) || tok.len == 0);
|
||||||
|
|
||||||
/* create the field string - however, the split function must
|
/* create the field string - however, the split function must
|
||||||
* create a numeric value if the string is a number */
|
* create a numeric value if the string is a number */
|
||||||
@ -975,7 +976,7 @@ static int fnc_split (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, int use_array)
|
|||||||
|
|
||||||
if (use_array)
|
if (use_array)
|
||||||
{
|
{
|
||||||
if (hawk_rtx_setarrvalfld(rtx, t1, ++nflds, t2) == HAWK_NULL)
|
if (!hawk_rtx_setarrvalfld(rtx, t1, ++nflds, t2))
|
||||||
{
|
{
|
||||||
hawk_rtx_refupval (rtx, t2);
|
hawk_rtx_refupval (rtx, t2);
|
||||||
hawk_rtx_refdownval (rtx, t2);
|
hawk_rtx_refdownval (rtx, t2);
|
||||||
@ -991,7 +992,7 @@ static int fnc_split (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, int use_array)
|
|||||||
key_len = hawk_int_to_oocstr(++nflds, 10, HAWK_NULL, key_buf, HAWK_COUNTOF(key_buf));
|
key_len = hawk_int_to_oocstr(++nflds, 10, HAWK_NULL, key_buf, HAWK_COUNTOF(key_buf));
|
||||||
HAWK_ASSERT (key_len != (hawk_oow_t)-1);
|
HAWK_ASSERT (key_len != (hawk_oow_t)-1);
|
||||||
|
|
||||||
if (hawk_rtx_setmapvalfld(rtx, t1, key_buf, key_len, t2) == HAWK_NULL)
|
if (!hawk_rtx_setmapvalfld(rtx, t1, key_buf, key_len, t2))
|
||||||
{
|
{
|
||||||
hawk_rtx_refupval (rtx, t2);
|
hawk_rtx_refupval (rtx, t2);
|
||||||
hawk_rtx_refdownval (rtx, t2);
|
hawk_rtx_refdownval (rtx, t2);
|
||||||
@ -1009,7 +1010,7 @@ static int fnc_split (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, int use_array)
|
|||||||
else if (byte_str) { hawk_rtx_freevalbcstr (rtx, a0, (hawk_bch_t*)str.ptr); }
|
else if (byte_str) { hawk_rtx_freevalbcstr (rtx, a0, (hawk_bch_t*)str.ptr); }
|
||||||
else { hawk_rtx_freevaloocstr (rtx, a0, str.ptr); }
|
else { hawk_rtx_freevaloocstr (rtx, a0, str.ptr); }
|
||||||
|
|
||||||
if (fs_free)
|
if (fs_free)
|
||||||
{
|
{
|
||||||
if (byte_str && switch_fs_to_bchr)
|
if (byte_str && switch_fs_to_bchr)
|
||||||
hawk_rtx_freevalbcstr (rtx, t0, (hawk_bch_t*)fs_free);
|
hawk_rtx_freevalbcstr (rtx, t0, (hawk_bch_t*)fs_free);
|
||||||
@ -1017,7 +1018,7 @@ static int fnc_split (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, int use_array)
|
|||||||
hawk_rtx_freevaloocstr (rtx, t0, fs_free);
|
hawk_rtx_freevaloocstr (rtx, t0, fs_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs_rex_free)
|
if (fs_rex_free)
|
||||||
{
|
{
|
||||||
if (rtx->gbl.ignorecase)
|
if (rtx->gbl.ignorecase)
|
||||||
hawk_rtx_freerex (rtx, HAWK_NULL, fs_rex_free);
|
hawk_rtx_freerex (rtx, HAWK_NULL, fs_rex_free);
|
||||||
@ -1032,7 +1033,7 @@ static int fnc_split (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, int use_array)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
if (str.ptr)
|
if (str.ptr)
|
||||||
{
|
{
|
||||||
if (do_fld) { hawk_rtx_freemem (rtx, str.ptr); }
|
if (do_fld) { hawk_rtx_freemem (rtx, str.ptr); }
|
||||||
else if (byte_str) { hawk_rtx_freevalbcstr (rtx, a0, (hawk_bch_t*)str.ptr); }
|
else if (byte_str) { hawk_rtx_freevalbcstr (rtx, a0, (hawk_bch_t*)str.ptr); }
|
||||||
@ -1047,7 +1048,7 @@ oops:
|
|||||||
hawk_rtx_freevaloocstr (rtx, t0, fs_free);
|
hawk_rtx_freevaloocstr (rtx, t0, fs_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs_rex_free)
|
if (fs_rex_free)
|
||||||
{
|
{
|
||||||
if (rtx->gbl.ignorecase)
|
if (rtx->gbl.ignorecase)
|
||||||
hawk_rtx_freerex (rtx, HAWK_NULL, fs_rex_free);
|
hawk_rtx_freerex (rtx, HAWK_NULL, fs_rex_free);
|
||||||
@ -1214,8 +1215,8 @@ static int __substitute_oocs (hawk_rtx_t* rtx, hawk_oow_t* max_count, hawk_tre_t
|
|||||||
}
|
}
|
||||||
else n = 0;
|
else n = 0;
|
||||||
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
/* no more match found */
|
/* no more match found */
|
||||||
if (hawk_ooecs_ncat(new, cur.ptr, cur.len) == (hawk_oow_t)-1) goto oops;
|
if (hawk_ooecs_ncat(new, cur.ptr, cur.len) == (hawk_oow_t)-1) goto oops;
|
||||||
break;
|
break;
|
||||||
@ -1256,7 +1257,7 @@ static int __substitute_oocs (hawk_rtx_t* rtx, hawk_oow_t* max_count, hawk_tre_t
|
|||||||
{
|
{
|
||||||
m = hawk_ooecs_ncat(new, mat.ptr, mat.len);
|
m = hawk_ooecs_ncat(new, mat.ptr, mat.len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m = hawk_ooecs_ccat(new, s1->ptr[i]);
|
m = hawk_ooecs_ccat(new, s1->ptr[i]);
|
||||||
}
|
}
|
||||||
@ -1319,8 +1320,8 @@ static int __substitute_bcs (hawk_rtx_t* rtx, hawk_oow_t* max_count, hawk_tre_t*
|
|||||||
}
|
}
|
||||||
else n = 0;
|
else n = 0;
|
||||||
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
/* no more match found */
|
/* no more match found */
|
||||||
if (hawk_becs_ncat(new, cur.ptr, cur.len) == (hawk_oow_t)-1) goto oops;
|
if (hawk_becs_ncat(new, cur.ptr, cur.len) == (hawk_oow_t)-1) goto oops;
|
||||||
break;
|
break;
|
||||||
@ -1361,7 +1362,7 @@ static int __substitute_bcs (hawk_rtx_t* rtx, hawk_oow_t* max_count, hawk_tre_t*
|
|||||||
{
|
{
|
||||||
m = hawk_becs_ncat(new, mat.ptr, mat.len);
|
m = hawk_becs_ncat(new, mat.ptr, mat.len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m = hawk_becs_ccat(new, s1->ptr[i]);
|
m = hawk_becs_ccat(new, s1->ptr[i]);
|
||||||
}
|
}
|
||||||
@ -1446,7 +1447,7 @@ static int __substitute (hawk_rtx_t* rtx, hawk_oow_t max_count)
|
|||||||
s1.ptr = hawk_rtx_getvaloocstr(rtx, a1, &s1.len);
|
s1.ptr = hawk_rtx_getvaloocstr(rtx, a1, &s1.len);
|
||||||
s1_free = 1;
|
s1_free = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
r2 = hawk_rtx_getrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 2));
|
r2 = hawk_rtx_getrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 2));
|
||||||
|
|
||||||
@ -1502,9 +1503,9 @@ static int __substitute (hawk_rtx_t* rtx, hawk_oow_t max_count)
|
|||||||
if (rex_free)
|
if (rex_free)
|
||||||
{
|
{
|
||||||
if (rtx->gbl.ignorecase)
|
if (rtx->gbl.ignorecase)
|
||||||
hawk_rtx_freerex (rtx, HAWK_NULL, rex_free);
|
hawk_rtx_freerex (rtx, HAWK_NULL, rex_free);
|
||||||
else
|
else
|
||||||
hawk_rtx_freerex (rtx, rex_free, HAWK_NULL);
|
hawk_rtx_freerex (rtx, rex_free, HAWK_NULL);
|
||||||
rex_free = HAWK_NULL;
|
rex_free = HAWK_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1530,7 +1531,7 @@ static int __substitute (hawk_rtx_t* rtx, hawk_oow_t max_count)
|
|||||||
}
|
}
|
||||||
s1.ptr = HAWK_NULL;
|
s1.ptr = HAWK_NULL;
|
||||||
|
|
||||||
if (s0.ptr)
|
if (s0.ptr)
|
||||||
{
|
{
|
||||||
hawk_rtx_freevaloocstr (rtx, a0, s0.ptr);
|
hawk_rtx_freevaloocstr (rtx, a0, s0.ptr);
|
||||||
s0.ptr = HAWK_NULL;
|
s0.ptr = HAWK_NULL;
|
||||||
@ -1564,12 +1565,12 @@ static int __substitute (hawk_rtx_t* rtx, hawk_oow_t max_count)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
if (rex_free)
|
if (rex_free)
|
||||||
{
|
{
|
||||||
if (rtx->gbl.ignorecase)
|
if (rtx->gbl.ignorecase)
|
||||||
hawk_rtx_freerex (rtx, HAWK_NULL, rex_free);
|
hawk_rtx_freerex (rtx, HAWK_NULL, rex_free);
|
||||||
else
|
else
|
||||||
hawk_rtx_freerex (rtx, rex_free, HAWK_NULL);
|
hawk_rtx_freerex (rtx, rex_free, HAWK_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s2.ptr)
|
if (s2.ptr)
|
||||||
@ -1616,23 +1617,8 @@ int hawk_fnc_sub (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
return __substitute(rtx, 1);
|
return __substitute(rtx, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hawk_fnc_match (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
static int __fnc_match (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, int support_start_index)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
match("abcdefg", "cde");
|
|
||||||
match("abcdefgdefx", "def", 7);
|
|
||||||
------------------------------------
|
|
||||||
match("ab\uB098cdefgdefx", /(def)g(.+)/, 1, x);
|
|
||||||
q = length(x) / 2;
|
|
||||||
for (i = 1; i <= q; i++) print x[i,"start"], x[i,"length"];
|
|
||||||
print RSTART, RLENGTH;
|
|
||||||
* ------------------------------------
|
|
||||||
match(@b"ab\xB0\x98cdefgdefx", /(def)g(.+)/, 1, x);
|
|
||||||
q = length(x) / 2;
|
|
||||||
for (i = 1; i <= q; i++) print x[i,"start"], x[i,"length"];
|
|
||||||
print RSTART, RLENGTH;
|
|
||||||
*/
|
|
||||||
|
|
||||||
hawk_oow_t nargs;
|
hawk_oow_t nargs;
|
||||||
hawk_val_t* a0, * a1;
|
hawk_val_t* a0, * a1;
|
||||||
hawk_val_type_t a0_type;
|
hawk_val_type_t a0_type;
|
||||||
@ -1662,19 +1648,15 @@ int hawk_fnc_match (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
|
|
||||||
nargs = hawk_rtx_getnargs(rtx);
|
nargs = hawk_rtx_getnargs(rtx);
|
||||||
HAWK_ASSERT (nargs >= 2 && nargs <= 4);
|
HAWK_ASSERT (nargs >= 2 && nargs <= 4);
|
||||||
|
|
||||||
a0 = hawk_rtx_getarg(rtx, 0);
|
a0 = hawk_rtx_getarg(rtx, 0);
|
||||||
a1 = hawk_rtx_getarg(rtx, 1);
|
a1 = hawk_rtx_getarg(rtx, 1);
|
||||||
|
|
||||||
if (nargs >= 3)
|
if (support_start_index && nargs >= 3)
|
||||||
{
|
{
|
||||||
hawk_val_t* a2;
|
hawk_val_t* a2;
|
||||||
|
a2 = hawk_rtx_getarg(rtx, 2); /* when start index is support, this is the thrid argument */
|
||||||
a2 = hawk_rtx_getarg(rtx, 2);
|
if (hawk_rtx_valtoint(rtx, a2, &start) <= -1) return -1;
|
||||||
/* if the 3rd parameter is not an array,
|
|
||||||
* it is treated as a match start index */
|
|
||||||
n = hawk_rtx_valtoint(rtx, a2, &start);
|
|
||||||
if (n <= -1) return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HAWK_MEMSET (&submat, 0, HAWK_SIZEOF(submat));
|
HAWK_MEMSET (&submat, 0, HAWK_SIZEOF(submat));
|
||||||
@ -1694,7 +1676,7 @@ int hawk_fnc_match (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
tmp.ptr = str0.b + start - 1;
|
tmp.ptr = str0.b + start - 1;
|
||||||
tmp.len = len0 - start + 1;
|
tmp.len = len0 - start + 1;
|
||||||
|
|
||||||
n = hawk_rtx_matchvalwithbcs(rtx, a1, &tmp, &tmp, &mat.b, (nargs >= 4? submat.b: HAWK_NULL));
|
n = hawk_rtx_matchvalwithbcs(rtx, a1, &tmp, &tmp, &mat.b, (nargs >= support_start_index + 3? submat.b: HAWK_NULL));
|
||||||
hawk_rtx_freevalbcstr (rtx, a0, str0.b);
|
hawk_rtx_freevalbcstr (rtx, a0, str0.b);
|
||||||
|
|
||||||
if (n <= -1) return -1;
|
if (n <= -1) return -1;
|
||||||
@ -1716,10 +1698,10 @@ int hawk_fnc_match (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
tmp.ptr = str0.o + start - 1;
|
tmp.ptr = str0.o + start - 1;
|
||||||
tmp.len = len0 - start + 1;
|
tmp.len = len0 - start + 1;
|
||||||
|
|
||||||
n = hawk_rtx_matchvalwithoocs(rtx, a1, &tmp, &tmp, &mat.o, (nargs >= 4? submat.o: HAWK_NULL));
|
n = hawk_rtx_matchvalwithoocs(rtx, a1, &tmp, &tmp, &mat.o, (nargs >= support_start_index + 3? submat.o: HAWK_NULL));
|
||||||
hawk_rtx_freevaloocstr (rtx, a0, str0.o);
|
hawk_rtx_freevaloocstr (rtx, a0, str0.o);
|
||||||
|
|
||||||
if (n <= -1) return -1;
|
if (n <= -1) return -1;
|
||||||
|
|
||||||
/* RSTART: 0 on no match */
|
/* RSTART: 0 on no match */
|
||||||
idx = (n == 0)? 0: ((hawk_int_t)(mat.o.ptr - str0.o) + 1);
|
idx = (n == 0)? 0: ((hawk_int_t)(mat.o.ptr - str0.o) + 1);
|
||||||
@ -1731,11 +1713,12 @@ int hawk_fnc_match (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
|
|
||||||
/* RLENGTH: -1 on no match */
|
/* RLENGTH: -1 on no match */
|
||||||
HAWK_ASSERT (&mat.o.len == &mat.b.len);
|
HAWK_ASSERT (&mat.o.len == &mat.b.len);
|
||||||
|
//x1 = hawk_rtx_makeintval(rtx, ((n == 0)? (hawk_int_t)-1: (hawk_int_t)mat.o.len)); /* just use mat.o.len regardless of a0_type */
|
||||||
x1 = hawk_rtx_makeintval(rtx, ((n == 0)? (hawk_int_t)-1: (hawk_int_t)mat.o.len)); /* just use mat.o.len regardless of a0_type */
|
x1 = hawk_rtx_makeintval(rtx, ((n == 0)? (hawk_int_t)-1: (hawk_int_t)mat.o.len)); /* just use mat.o.len regardless of a0_type */
|
||||||
if (!x1) goto oops;
|
if (!x1) goto oops;
|
||||||
hawk_rtx_refupval (rtx, x1);
|
hawk_rtx_refupval (rtx, x1);
|
||||||
|
|
||||||
if (nargs >= 4)
|
if (nargs >= (3 + support_start_index))
|
||||||
{
|
{
|
||||||
const hawk_oocs_t* subsep;
|
const hawk_oocs_t* subsep;
|
||||||
hawk_int_t submatcount;
|
hawk_int_t submatcount;
|
||||||
@ -1783,10 +1766,10 @@ int hawk_fnc_match (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the caller of this function must be able to get the submatch count by
|
/* the caller of this function must be able to get the submatch count by
|
||||||
* dividing the array size by 2 */
|
* dividing the array size by 2 */
|
||||||
|
if (hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 2 + support_start_index), x2) <= -1) goto oops;
|
||||||
if (hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 3), x2) <= -1) goto oops;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hawk_rtx_setgbl(rtx, HAWK_GBL_RSTART, x0) <= -1 ||
|
if (hawk_rtx_setgbl(rtx, HAWK_GBL_RSTART, x0) <= -1 ||
|
||||||
@ -1809,6 +1792,44 @@ oops:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fnc_match (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
match("abcdefg", "cde");
|
||||||
|
match("abcdefgdefx", "def", 7);
|
||||||
|
------------------------------------
|
||||||
|
match("ab\uB098cdefgdefx", /(def)g(.+)/, x);
|
||||||
|
q = length(x) / 2;
|
||||||
|
for (i = 1; i <= q; i++) print x[i,"start"], x[i,"length"];
|
||||||
|
print RSTART, RLENGTH;
|
||||||
|
* ------------------------------------
|
||||||
|
match(@b"ab\xB0\x98cdefgdefx", /(def)g(.+)/, x);
|
||||||
|
q = length(x) / 2;
|
||||||
|
for (i = 1; i <= q; i++) print x[i,"start"], x[i,"length"];
|
||||||
|
print RSTART, RLENGTH;
|
||||||
|
*/
|
||||||
|
return __fnc_match(rtx, fi, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hawk_fnc_match (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
str::match("abcdefg", "cde");
|
||||||
|
str::match("abcdefgdefx", "def", 7);
|
||||||
|
------------------------------------
|
||||||
|
str::match("ab\uB098cdefgdefx", /(def)g(.+)/, 1, x);
|
||||||
|
q = length(x) / 2;
|
||||||
|
for (i = 1; i <= q; i++) print x[i,"start"], x[i,"length"];
|
||||||
|
print RSTART, RLENGTH;
|
||||||
|
* ------------------------------------
|
||||||
|
str::match(@b"ab\xB0\x98cdefgdefx", /(def)g(.+)/, 1, x);
|
||||||
|
q = length(x) / 2;
|
||||||
|
for (i = 1; i <= q; i++) print x[i,"start"], x[i,"length"];
|
||||||
|
print RSTART, RLENGTH;
|
||||||
|
*/
|
||||||
|
return __fnc_match(rtx, fi, 1);
|
||||||
|
}
|
||||||
|
|
||||||
int hawk_fnc_sprintf (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
int hawk_fnc_sprintf (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||||
{
|
{
|
||||||
hawk_oow_t nargs;
|
hawk_oow_t nargs;
|
||||||
@ -1837,7 +1858,7 @@ int hawk_fnc_sprintf (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
x.ptr = hawk_rtx_formatmbs(rtx, &rtx->fnc.bout, &fbu, cs0.ptr, cs0.len, nargs, HAWK_NULL, &x.len);
|
x.ptr = hawk_rtx_formatmbs(rtx, &rtx->fnc.bout, &fbu, cs0.ptr, cs0.len, nargs, HAWK_NULL, &x.len);
|
||||||
hawk_rtx_freevalbcstr (rtx, a0, cs0.ptr);
|
hawk_rtx_freevalbcstr (rtx, a0, cs0.ptr);
|
||||||
if (HAWK_UNLIKELY(!x.ptr)) goto oops_mbs;
|
if (HAWK_UNLIKELY(!x.ptr)) goto oops_mbs;
|
||||||
|
|
||||||
a0 = hawk_rtx_makembsvalwithbcs(rtx, &x);
|
a0 = hawk_rtx_makembsvalwithbcs(rtx, &x);
|
||||||
if (HAWK_UNLIKELY(!a0)) goto oops_mbs;
|
if (HAWK_UNLIKELY(!a0)) goto oops_mbs;
|
||||||
|
|
||||||
@ -1894,7 +1915,7 @@ static int fnc_int (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
|||||||
if (n <= -1) return -1;
|
if (n <= -1) return -1;
|
||||||
|
|
||||||
r = hawk_rtx_makeintval(rtx, lv);
|
r = hawk_rtx_makeintval(rtx, lv);
|
||||||
if (r == HAWK_NULL) return -1;
|
if (!r) return -1;
|
||||||
|
|
||||||
hawk_rtx_setretval (rtx, r);
|
hawk_rtx_setretval (rtx, r);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1922,7 +1943,7 @@ static HAWK_INLINE int asort_compare_ud (const void* x1, const void* x2, void* c
|
|||||||
|
|
||||||
args[0] = *(hawk_val_t**)x1;
|
args[0] = *(hawk_val_t**)x1;
|
||||||
args[1] = *(hawk_val_t**)x2;
|
args[1] = *(hawk_val_t**)x2;
|
||||||
r = hawk_rtx_callfun(cud->rtx, cud->fun, args, 2);
|
r = hawk_rtx_callfun(cud->rtx, cud->fun, args, 2);
|
||||||
if (!r) return -1;
|
if (!r) return -1;
|
||||||
if (hawk_rtx_valtoint(cud->rtx, r, &rv) <= -1) return -1;
|
if (hawk_rtx_valtoint(cud->rtx, r, &rv) <= -1) return -1;
|
||||||
*cv = rv;
|
*cv = rv;
|
||||||
@ -1971,7 +1992,7 @@ static HAWK_INLINE int __fnc_asort (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fun->nargs < 2)
|
if (fun->nargs < 2)
|
||||||
{
|
{
|
||||||
/* the comparison accepts less than 2 arguments */
|
/* the comparison accepts less than 2 arguments */
|
||||||
hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_EINVAL, HAWK_T("%.*js not accepting 2 arguments"), fun->name.len, fun->name.ptr);
|
hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_EINVAL, HAWK_T("%.*js not accepting 2 arguments"), fun->name.len, fun->name.ptr);
|
||||||
@ -2020,7 +2041,7 @@ val_map:
|
|||||||
{
|
{
|
||||||
const hawk_oocs_t* key = HAWK_VAL_MAP_ITR_KEY(&itr);
|
const hawk_oocs_t* key = HAWK_VAL_MAP_ITR_KEY(&itr);
|
||||||
va[i] = hawk_rtx_makestrvalwithoocs(rtx, key);
|
va[i] = hawk_rtx_makestrvalwithoocs(rtx, key);
|
||||||
if (HAWK_UNLIKELY(!va[i]))
|
if (HAWK_UNLIKELY(!va[i]))
|
||||||
{
|
{
|
||||||
while (i > 0)
|
while (i > 0)
|
||||||
{
|
{
|
||||||
@ -2080,7 +2101,7 @@ val_map:
|
|||||||
HAWK_NULL
|
HAWK_NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
if (hawk_rtx_setmapvalfld(rtx, rrv, ridx, ridx_len, va[i]) == HAWK_NULL)
|
if (!hawk_rtx_setmapvalfld(rtx, rrv, ridx, ridx_len, va[i]))
|
||||||
{
|
{
|
||||||
/* decrement the reference count of the values not added to the map */
|
/* decrement the reference count of the values not added to the map */
|
||||||
do
|
do
|
||||||
@ -2119,12 +2140,12 @@ val_arr:
|
|||||||
HAWK_ASSERT (msz <= ssz);
|
HAWK_ASSERT (msz <= ssz);
|
||||||
HAWK_ASSERT (msz <= HAWK_QINT_MAX);
|
HAWK_ASSERT (msz <= HAWK_QINT_MAX);
|
||||||
HAWK_ASSERT (ssz <= HAWK_QINT_MAX);
|
HAWK_ASSERT (ssz <= HAWK_QINT_MAX);
|
||||||
|
|
||||||
va = (hawk_val_t**)hawk_rtx_allocmem(rtx, msz * HAWK_SIZEOF(*va));
|
va = (hawk_val_t**)hawk_rtx_allocmem(rtx, msz * HAWK_SIZEOF(*va));
|
||||||
if (HAWK_UNLIKELY(!va)) return -1;
|
if (HAWK_UNLIKELY(!va)) return -1;
|
||||||
for (i = 0, j = 0; j < ssz; j++)
|
for (i = 0, j = 0; j < ssz; j++)
|
||||||
{
|
{
|
||||||
if (HAWK_ARR_SLOT(arr, j))
|
if (HAWK_ARR_SLOT(arr, j))
|
||||||
{
|
{
|
||||||
va[i] = sort_keys? hawk_rtx_makeintval(rtx, j): HAWK_ARR_DPTR(arr, j);
|
va[i] = sort_keys? hawk_rtx_makeintval(rtx, j): HAWK_ARR_DPTR(arr, j);
|
||||||
hawk_rtx_refupval (rtx, va[i]);
|
hawk_rtx_refupval (rtx, va[i]);
|
||||||
@ -2153,7 +2174,7 @@ val_arr:
|
|||||||
|
|
||||||
for (i = 0; i < msz; i++)
|
for (i = 0; i < msz; i++)
|
||||||
{
|
{
|
||||||
if (hawk_rtx_setarrvalfld(rtx, rrv, i + 1, va[i]) == HAWK_NULL) /* i + 1 for 1-based indexing*/
|
if (!hawk_rtx_setarrvalfld(rtx, rrv, i + 1, va[i])) /* i + 1 for 1-based indexing*/
|
||||||
{
|
{
|
||||||
/* decrement the reference count of the values not added to the map */
|
/* decrement the reference count of the values not added to the map */
|
||||||
do
|
do
|
||||||
@ -2182,12 +2203,12 @@ done:
|
|||||||
if (rrv)
|
if (rrv)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
/* rrv can be NULL when a jump has been made for an empty source
|
/* rrv can be NULL when a jump has been made for an empty source
|
||||||
* at the beginning of this fucntion */
|
* at the beginning of this fucntion */
|
||||||
hawk_rtx_refupval (rtx, rrv);
|
hawk_rtx_refupval (rtx, rrv);
|
||||||
x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, (nargs >= 2)), rrv);
|
x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, (nargs >= 2)), rrv);
|
||||||
hawk_rtx_refdownval (rtx, rrv);
|
hawk_rtx_refdownval (rtx, rrv);
|
||||||
if (x <= -1)
|
if (x <= -1)
|
||||||
{
|
{
|
||||||
hawk_rtx_freeval (rtx, r, 0);
|
hawk_rtx_freeval (rtx, r, 0);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2407,7 +2407,6 @@ HAWK_EXPORT hawk_val_t* hawk_rtx_execwithbcstrarr (
|
|||||||
# define hawk_rtx_execwithoocstrarr hawk_rtx_execwithucstrarr
|
# define hawk_rtx_execwithoocstrarr hawk_rtx_execwithucstrarr
|
||||||
|
|
||||||
# define hawk_rtx_call hawk_rtx_callwithucstr
|
# define hawk_rtx_call hawk_rtx_callwithucstr
|
||||||
# define hawk_rtx_call hawk_rtx_callwithucstrarr
|
|
||||||
# define hawk_rtx_exec hawk_rtx_execwithucstrarr
|
# define hawk_rtx_exec hawk_rtx_execwithucstrarr
|
||||||
#else
|
#else
|
||||||
# define hawk_rtx_callwithoocstr hawk_rtx_callwithbcstr
|
# define hawk_rtx_callwithoocstr hawk_rtx_callwithbcstr
|
||||||
@ -2415,7 +2414,6 @@ HAWK_EXPORT hawk_val_t* hawk_rtx_execwithbcstrarr (
|
|||||||
# define hawk_rtx_execwithoocstrarr hawk_rtx_execwithbcstrarr
|
# define hawk_rtx_execwithoocstrarr hawk_rtx_execwithbcstrarr
|
||||||
|
|
||||||
# define hawk_rtx_call hawk_rtx_callwithbcstr
|
# define hawk_rtx_call hawk_rtx_callwithbcstr
|
||||||
# define hawk_rtx_call hawk_rtx_callwithbcstrarr
|
|
||||||
# define hawk_rtx_exec hawk_rtx_execwithbcstrarr
|
# define hawk_rtx_exec hawk_rtx_execwithbcstrarr
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
79
t/h-002.hawk
79
t/h-002.hawk
@ -9,11 +9,11 @@ function main()
|
|||||||
## call by reference. change an argument to array in the callee
|
## call by reference. change an argument to array in the callee
|
||||||
{
|
{
|
||||||
@local ini, foo1, foo2, foo3, foo4;
|
@local ini, foo1, foo2, foo3, foo4;
|
||||||
|
|
||||||
test1(foo1);
|
test1(foo1);
|
||||||
test2(foo2);
|
test2(foo2);
|
||||||
test3(foo3);
|
test3(foo3);
|
||||||
test4(foo4);
|
test4(foo4);
|
||||||
tap_ensure (hawk::typename(foo1), "map", @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure (hawk::typename(foo1), "map", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
tap_ensure (hawk::typename(foo2), "map", @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure (hawk::typename(foo2), "map", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
tap_ensure (hawk::typename(foo3), "nil", @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure (hawk::typename(foo3), "nil", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
@ -24,7 +24,7 @@ function main()
|
|||||||
tap_ensure (foo4[1], ini, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure (foo4[1], ini, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
## gsub
|
## gsub
|
||||||
{
|
{
|
||||||
@local w, x, y, z, z1, z2;
|
@local w, x, y, z, z1, z2;
|
||||||
x = y = "x\\y";
|
x = y = "x\\y";
|
||||||
@ -94,8 +94,8 @@ function main()
|
|||||||
tap_ensure (y === @b"A", 1, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure (y === @b"A", 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
## gsub - POSIX rule for &, \&, \\&, \\\&
|
## gsub - POSIX rule for &, \&, \\&, \\\&
|
||||||
{
|
{
|
||||||
@local w, x, y, z, z1, z2, z3;
|
@local w, x, y, z, z1, z2, z3;
|
||||||
w = x = y = z = z1 = z2 = "xax";
|
w = x = y = z = z1 = z2 = "xax";
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ function main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
## gsub - POSIX rule for &, \&, \\&, \\\& - express the same test with a raw string literal
|
## gsub - POSIX rule for &, \&, \\&, \\\& - express the same test with a raw string literal
|
||||||
{
|
{
|
||||||
@local w, x, y, z;
|
@local w, x, y, z;
|
||||||
w = x = y = z = "xax";
|
w = x = y = z = "xax";
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ function main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
## sub - POSIX rule for &, \&, \\&, \\\& - express the same test with a raw string literal
|
## sub - POSIX rule for &, \&, \\&, \\\& - express the same test with a raw string literal
|
||||||
{
|
{
|
||||||
@local w, x, y, z;
|
@local w, x, y, z;
|
||||||
w = x = y = z = "xax";
|
w = x = y = z = "xax";
|
||||||
|
|
||||||
@ -579,6 +579,65 @@ function main()
|
|||||||
tap_ensure (c === @b'y' , 1, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure (c === @b'y' , 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
@local a, b;
|
||||||
|
|
||||||
|
RSTART=99;
|
||||||
|
RLENGTH=99;
|
||||||
|
tap_ensure (match("world", /hello/), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RSTART, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RLENGTH, -1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
tap_ensure (match(@b"world", /hello/), 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RSTART, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RLENGTH, -1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## match() doesn't support the start index.
|
||||||
|
## the result goes to the third argument.
|
||||||
|
tap_ensure (match("hello, world", /l/), 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RSTART, 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RLENGTH, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
tap_ensure (match(@b"hello, world", /l/), 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RSTART, 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RLENGTH, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
tap_ensure (match("hello, world", /(l)lo.*(l)/, a), 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RSTART, 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RLENGTH, 9, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (length(a), 4, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (a[1,"start"], 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (a[1,"length"], 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (a[2,"start"], 11, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (a[2,"length"], 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
## start::match() support the start index via the third parameter.
|
||||||
|
## the result goes to the fourth argument.
|
||||||
|
tap_ensure (str::match("hello, world", /(l)lo.*(l)/, 1, a), 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RSTART, 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RLENGTH, 9, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (length(a), 4, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (a[1,"start"], 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (a[1,"length"], 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (a[2,"start"], 11, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (a[2,"length"], 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
tap_ensure (str::match("hello, world, hello, world", /(l)lo.*(l)/, 4, a), 17, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RSTART, 17, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RLENGTH, 9, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (length(a), 4, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (a[1,"start"], 17, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (a[1,"length"], 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (a[2,"start"], 25, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (a[2,"length"], 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
|
||||||
|
b = 291210;
|
||||||
|
tap_ensure (str::match(b @b"what is this", /10/, 1, a), 5, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RSTART, 5, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure (RLENGTH, 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
}
|
||||||
tap_end ();
|
tap_end ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user