combined some awk options into QSE_AWK_EXTRAKWS.
deleted QSE_AWK_EXTRAOPS and enabled all new operators by default added === and !==. fixed a bug in printing the explicit concatenation operator(%%, %%=) improved @include handling
This commit is contained in:
parent
b53fe11c04
commit
8ac0963885
@ -382,23 +382,19 @@ struct opttab_t
|
|||||||
{
|
{
|
||||||
{ QSE_T("implicit"), QSE_AWK_IMPLICIT, QSE_T("allow undeclared variables") },
|
{ QSE_T("implicit"), QSE_AWK_IMPLICIT, QSE_T("allow undeclared variables") },
|
||||||
{ QSE_T("explicit"), QSE_AWK_EXPLICIT, QSE_T("allow declared variables(local,global)") },
|
{ QSE_T("explicit"), QSE_AWK_EXPLICIT, QSE_T("allow declared variables(local,global)") },
|
||||||
{ QSE_T("extraops"), QSE_AWK_EXTRAOPS, QSE_T("enable extra operators(<<,>>,^^,\\)") },
|
{ QSE_T("extrakws"), QSE_AWK_EXTRAKWS, QSE_T("enable abort,reset,nextofile,OFILENAME,@include") },
|
||||||
{ QSE_T("rio"), QSE_AWK_RIO, QSE_T("enable builtin I/O including getline & print") },
|
{ QSE_T("rio"), QSE_AWK_RIO, QSE_T("enable builtin I/O including getline & print") },
|
||||||
{ QSE_T("rwpipe"), QSE_AWK_RWPIPE, QSE_T("allow a dual-directional pipe") },
|
{ QSE_T("rwpipe"), QSE_AWK_RWPIPE, QSE_T("allow a dual-directional pipe") },
|
||||||
{ QSE_T("newline"), QSE_AWK_NEWLINE, QSE_T("enable a newline to terminate a statement") },
|
{ QSE_T("newline"), QSE_AWK_NEWLINE, QSE_T("enable a newline to terminate a statement") },
|
||||||
{ QSE_T("striprecspc"), QSE_AWK_STRIPRECSPC, QSE_T("strip spaces in splitting a record") },
|
{ QSE_T("striprecspc"), QSE_AWK_STRIPRECSPC, QSE_T("strip spaces in splitting a record") },
|
||||||
{ QSE_T("stripstrspc"), QSE_AWK_STRIPSTRSPC, QSE_T("strip spaces in string-to-number conversion") },
|
{ QSE_T("stripstrspc"), QSE_AWK_STRIPSTRSPC, QSE_T("strip spaces in string-to-number conversion") },
|
||||||
{ QSE_T("nextofile"), QSE_AWK_NEXTOFILE, QSE_T("enable 'nextofile'") },
|
|
||||||
{ QSE_T("reset"), QSE_AWK_RESET, QSE_T("enable 'reset'") },
|
|
||||||
{ QSE_T("crlf"), QSE_AWK_CRLF, QSE_T("use CRLF for a newline") },
|
{ QSE_T("crlf"), QSE_AWK_CRLF, QSE_T("use CRLF for a newline") },
|
||||||
{ QSE_T("maptovar"), QSE_AWK_MAPTOVAR, QSE_T("allow a map to be assigned or returned") },
|
{ QSE_T("maptovar"), QSE_AWK_MAPTOVAR, QSE_T("allow a map to be assigned or returned") },
|
||||||
{ QSE_T("pablock"), QSE_AWK_PABLOCK, QSE_T("enable pattern-action loop") },
|
{ QSE_T("pablock"), QSE_AWK_PABLOCK, QSE_T("enable pattern-action loop") },
|
||||||
{ QSE_T("rexbound"), QSE_AWK_REXBOUND, QSE_T("enable {n,m} in a regular expression") },
|
{ QSE_T("rexbound"), QSE_AWK_REXBOUND, QSE_T("enable {n,m} in a regular expression") },
|
||||||
{ QSE_T("ncmponstr"), QSE_AWK_NCMPONSTR, QSE_T("perform numeric comparsion on numeric strings") },
|
{ QSE_T("ncmponstr"), QSE_AWK_NCMPONSTR, QSE_T("perform numeric comparsion on numeric strings") },
|
||||||
{ QSE_T("strictnaming"), QSE_AWK_STRICTNAMING, QSE_T("enable the strict naming rule") },
|
{ QSE_T("strictnaming"), QSE_AWK_STRICTNAMING, QSE_T("enable the strict naming rule") },
|
||||||
{ QSE_T("include"), QSE_AWK_INCLUDE, QSE_T("enable '@include'") },
|
|
||||||
{ QSE_T("tolerant"), QSE_AWK_TOLERANT, QSE_T("make more fault-tolerant") },
|
{ QSE_T("tolerant"), QSE_AWK_TOLERANT, QSE_T("make more fault-tolerant") },
|
||||||
{ QSE_T("abort"), QSE_AWK_ABORT, QSE_T("enable 'abort'") },
|
|
||||||
{ QSE_NULL, 0, QSE_NULL }
|
{ QSE_NULL, 0, QSE_NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -525,23 +521,19 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
{
|
{
|
||||||
{ QSE_T(":implicit"), QSE_T('\0') },
|
{ QSE_T(":implicit"), QSE_T('\0') },
|
||||||
{ QSE_T(":explicit"), QSE_T('\0') },
|
{ QSE_T(":explicit"), QSE_T('\0') },
|
||||||
{ QSE_T(":extraops"), QSE_T('\0') },
|
{ QSE_T(":extrakws"), QSE_T('\0') },
|
||||||
{ QSE_T(":rio"), QSE_T('\0') },
|
{ QSE_T(":rio"), QSE_T('\0') },
|
||||||
{ QSE_T(":rwpipe"), QSE_T('\0') },
|
{ QSE_T(":rwpipe"), QSE_T('\0') },
|
||||||
{ QSE_T(":newline"), QSE_T('\0') },
|
{ QSE_T(":newline"), QSE_T('\0') },
|
||||||
{ QSE_T(":striprecspc"), QSE_T('\0') },
|
{ QSE_T(":striprecspc"), QSE_T('\0') },
|
||||||
{ QSE_T(":stripstrspc"), QSE_T('\0') },
|
{ QSE_T(":stripstrspc"), QSE_T('\0') },
|
||||||
{ QSE_T(":nextofile"), QSE_T('\0') },
|
|
||||||
{ QSE_T(":reset"), QSE_T('\0') },
|
|
||||||
{ QSE_T(":crlf"), QSE_T('\0') },
|
{ QSE_T(":crlf"), QSE_T('\0') },
|
||||||
{ QSE_T(":maptovar"), QSE_T('\0') },
|
{ QSE_T(":maptovar"), QSE_T('\0') },
|
||||||
{ QSE_T(":pablock"), QSE_T('\0') },
|
{ QSE_T(":pablock"), QSE_T('\0') },
|
||||||
{ QSE_T(":rexbound"), QSE_T('\0') },
|
{ QSE_T(":rexbound"), QSE_T('\0') },
|
||||||
{ QSE_T(":ncmponstr"), QSE_T('\0') },
|
{ QSE_T(":ncmponstr"), QSE_T('\0') },
|
||||||
{ QSE_T(":strictnaming"), QSE_T('\0') },
|
{ QSE_T(":strictnaming"), QSE_T('\0') },
|
||||||
{ QSE_T(":include"), QSE_T('\0') },
|
|
||||||
{ QSE_T(":tolerant"), QSE_T('\0') },
|
{ QSE_T(":tolerant"), QSE_T('\0') },
|
||||||
{ QSE_T(":abort"), QSE_T('\0') },
|
|
||||||
|
|
||||||
{ QSE_T(":call"), QSE_T('c') },
|
{ QSE_T(":call"), QSE_T('c') },
|
||||||
{ QSE_T(":file"), QSE_T('f') },
|
{ QSE_T(":file"), QSE_T('f') },
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
@section awk_content CONTENTS
|
@section awk_content CONTENTS
|
||||||
- @ref awk_intro "INTRODUCTION"
|
- @ref awk_intro "INTRODUCTION"
|
||||||
- @ref awk_lang "AWK LANGUAGE"
|
- @ref awk_lang "AWK LANGUAGE"
|
||||||
- @ref awk_ext "AWK LANGUAGE EXTENSIONS"
|
- @ref awk_litvar "LITERAL AND VARIABLE"
|
||||||
|
- @ref awk_ext_teq "TEQ OPERATOR"
|
||||||
- @ref awk_ext_vardecl "VARIABLE DECLARATION"
|
- @ref awk_ext_vardecl "VARIABLE DECLARATION"
|
||||||
- @ref awk_ext_include "INCLUDE"
|
- @ref awk_ext_include "INCLUDE"
|
||||||
- @ref awk_ext_print "EXTENDED PRINT/PRINTF"
|
- @ref awk_ext_print "EXTENDED PRINT/PRINTF"
|
||||||
@ -255,9 +256,74 @@ AWK has the following statement constructs.
|
|||||||
- printf
|
- printf
|
||||||
- expression
|
- expression
|
||||||
|
|
||||||
@section awk_ext AWK LANGUAGE EXTENSIONS
|
@subsection awk_litvar LITERAL AND VARIABLE
|
||||||
Some language extensions are implemented and those can be enabled by setting
|
|
||||||
the corresponding options.
|
Value type
|
||||||
|
- Scalar
|
||||||
|
-- String
|
||||||
|
-- Integer
|
||||||
|
-- Floating-Pointer number
|
||||||
|
- Hashed Map
|
||||||
|
- Regular expression
|
||||||
|
|
||||||
|
Scalar values are immutable while a hashed map value is mutable.
|
||||||
|
A regular expression value is specially treated.
|
||||||
|
|
||||||
|
A variable is tied to a value when it is assigned with a value.
|
||||||
|
If the variable is tied to a map value, it can't be assigned again.
|
||||||
|
You can use 'reset' to untie the variable from the value, and thus
|
||||||
|
restore the variable to the 'nil' state.
|
||||||
|
|
||||||
|
....
|
||||||
|
|
||||||
|
@subsection awk_ext_teq TEQ OPERATOR
|
||||||
|
|
||||||
|
The === operator compares two values and evaluates to a non-zero value
|
||||||
|
if both have the same internal type and the actual values are the same.
|
||||||
|
so 1 is not equal to 1.0 for the === operator.
|
||||||
|
|
||||||
|
A map comparison for the === operator is a bit special. The contents of
|
||||||
|
the map is never inspected. Comparing two maps always result in inequality.
|
||||||
|
|
||||||
|
However, if two variables points to the same map value, it can evaluate
|
||||||
|
to a non-zero value. This is possible if you allow assigning a map to
|
||||||
|
another non-map variable with #QSE_AWK_MAPTOVAR. In this case, a map
|
||||||
|
is not deep-copied but the reference to it is copied.
|
||||||
|
|
||||||
|
@code
|
||||||
|
BEGIN {
|
||||||
|
a[10]=20;
|
||||||
|
b=a;
|
||||||
|
b[20]=40;
|
||||||
|
for (i in a) print i, a[i];
|
||||||
|
print a===b;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
The === operator may be also useful when you want to indicate an error
|
||||||
|
with an uninitialized variable. The following code check if the function
|
||||||
|
returned a map. Since the variable 'nil' has never been assigned, its
|
||||||
|
internal type is 'NIL' and
|
||||||
|
|
||||||
|
@code
|
||||||
|
function a ()
|
||||||
|
{
|
||||||
|
x[10] = 2;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
t = a();
|
||||||
|
if (t === nil)
|
||||||
|
print "nil";
|
||||||
|
else
|
||||||
|
print "ok";
|
||||||
|
}
|
||||||
|
@endcode.
|
||||||
|
|
||||||
|
The !== operator is a negated form of the === operator.
|
||||||
|
|
||||||
|
|
||||||
@subsection awk_ext_vardecl VARIABLE DECLARATION
|
@subsection awk_ext_vardecl VARIABLE DECLARATION
|
||||||
|
|
||||||
@ -303,6 +369,16 @@ blocks appear. To use \@include, you must turn on #QSE_AWK_INCLUDE.
|
|||||||
BEGIN { func_in_abc (); }
|
BEGIN { func_in_abc (); }
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
A semicolon is optional after the included file name. The following is the
|
||||||
|
same as the sample above.
|
||||||
|
@code
|
||||||
|
@include "abc.awk";
|
||||||
|
BEGIN { func_in_abc(); }
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
If #QSE_AWK_NEWLINE is off, the semicolon is required.
|
||||||
|
|
||||||
|
|
||||||
@subsection awk_ext_print EXTENDED PRINT/PRINTF
|
@subsection awk_ext_print EXTENDED PRINT/PRINTF
|
||||||
When #QSE_AWK_TOLERANT is on, print and printf are treated as if
|
When #QSE_AWK_TOLERANT is on, print and printf are treated as if
|
||||||
they are function calls. In this mode, they return a negative number
|
they are function calls. In this mode, they return a negative number
|
||||||
|
@ -460,6 +460,7 @@ struct qse_awk_sio_lxc_t
|
|||||||
};
|
};
|
||||||
typedef struct qse_awk_sio_lxc_t qse_awk_sio_lxc_t;
|
typedef struct qse_awk_sio_lxc_t qse_awk_sio_lxc_t;
|
||||||
|
|
||||||
|
typedef struct qse_awk_sio_arg_t qse_awk_sio_arg_t;
|
||||||
struct qse_awk_sio_arg_t
|
struct qse_awk_sio_arg_t
|
||||||
{
|
{
|
||||||
const qse_char_t* name; /**< [IN] name of I/O object */
|
const qse_char_t* name; /**< [IN] name of I/O object */
|
||||||
@ -477,9 +478,8 @@ struct qse_awk_sio_arg_t
|
|||||||
qse_size_t colm;
|
qse_size_t colm;
|
||||||
|
|
||||||
qse_awk_sio_lxc_t last;
|
qse_awk_sio_lxc_t last;
|
||||||
struct qse_awk_sio_arg_t* next;
|
qse_awk_sio_arg_t* next;
|
||||||
};
|
};
|
||||||
typedef struct qse_awk_sio_arg_t qse_awk_sio_arg_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_awk_sio_impl_t type defines a source IO function
|
* The qse_awk_sio_impl_t type defines a source IO function
|
||||||
@ -901,14 +901,9 @@ enum qse_awk_trait_t
|
|||||||
QSE_AWK_EXPLICIT = (1 << 1),
|
QSE_AWK_EXPLICIT = (1 << 1),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* supports extra operators:
|
* enable abort,reset,nextofile,OFILENAME,@include.
|
||||||
* - @b <<, <<= left-shift
|
|
||||||
* - @b >>, >>= right-shiftt
|
|
||||||
* - @b ^^, ^^= xor
|
|
||||||
* - @b ~ bitwise-not
|
|
||||||
* - @b // idiv (get quotient)
|
|
||||||
*/
|
*/
|
||||||
QSE_AWK_EXTRAOPS = (1 << 2),
|
QSE_AWK_EXTRAKWS = (1 << 2),
|
||||||
|
|
||||||
/** supports @b getline and @b print */
|
/** supports @b getline and @b print */
|
||||||
QSE_AWK_RIO = (1 << 3),
|
QSE_AWK_RIO = (1 << 3),
|
||||||
@ -951,12 +946,6 @@ enum qse_awk_trait_t
|
|||||||
*/
|
*/
|
||||||
QSE_AWK_STRIPSTRSPC = (1 << 7),
|
QSE_AWK_STRIPSTRSPC = (1 << 7),
|
||||||
|
|
||||||
/** enables @b nextofile */
|
|
||||||
QSE_AWK_NEXTOFILE = (1 << 8),
|
|
||||||
|
|
||||||
/** enables @b reset */
|
|
||||||
QSE_AWK_RESET = (1 << 9),
|
|
||||||
|
|
||||||
/** CR + LF by default */
|
/** CR + LF by default */
|
||||||
QSE_AWK_CRLF = (1 << 10),
|
QSE_AWK_CRLF = (1 << 10),
|
||||||
|
|
||||||
@ -1005,9 +994,6 @@ enum qse_awk_trait_t
|
|||||||
*/
|
*/
|
||||||
QSE_AWK_TOLERANT = (1 << 17),
|
QSE_AWK_TOLERANT = (1 << 17),
|
||||||
|
|
||||||
/** enables @b abort */
|
|
||||||
QSE_AWK_ABORT = (1 << 18),
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* makes #qse_awk_t to behave compatibly with classical AWK
|
* makes #qse_awk_t to behave compatibly with classical AWK
|
||||||
* implementations
|
* implementations
|
||||||
@ -1112,18 +1098,18 @@ enum qse_awk_errnum_t
|
|||||||
QSE_AWK_EARGTF, /**< too few arguments */
|
QSE_AWK_EARGTF, /**< too few arguments */
|
||||||
QSE_AWK_EARGTM, /**< too many arguments */
|
QSE_AWK_EARGTM, /**< too many arguments */
|
||||||
QSE_AWK_EFUNNF, /**< function '${0}' not found */
|
QSE_AWK_EFUNNF, /**< function '${0}' not found */
|
||||||
QSE_AWK_ENOTIDX, /**< variable not indexable */
|
QSE_AWK_ENOTIDX, /**< not indexable */
|
||||||
QSE_AWK_ENOTDEL, /**< variable '${0}' not deletable */
|
QSE_AWK_ENOTDEL, /**< '${0}' not deletable */
|
||||||
QSE_AWK_ENOTMAP, /**< value not a map */
|
QSE_AWK_ENOTMAP, /**< value not a map */
|
||||||
QSE_AWK_ENOTMAPIN, /**< right-hand side of 'in' not a map */
|
QSE_AWK_ENOTMAPIN, /**< right-hand side of 'in' not a map */
|
||||||
QSE_AWK_ENOTMAPNILIN, /**< right-hand side of 'in' not a map nor nil */
|
QSE_AWK_ENOTMAPNILIN, /**< right-hand side of 'in' not a map nor nil */
|
||||||
QSE_AWK_ENOTREF, /**< value not referenceable */
|
QSE_AWK_ENOTREF, /**< value not referenceable */
|
||||||
QSE_AWK_ENOTASS, /**< value not assignable */
|
QSE_AWK_ENOTASS, /**< value not assignable */
|
||||||
QSE_AWK_EIDXVALASSMAP, /**< an indexed value cannot be assigned a map */
|
QSE_AWK_EIDXVALASSMAP, /**< indexed value cannot be assigned a map */
|
||||||
QSE_AWK_EPOSVALASSMAP, /**< a positional cannot be assigned a map */
|
QSE_AWK_EPOSVALASSMAP, /**< positional cannot be assigned a map */
|
||||||
QSE_AWK_EMAPTOSCALAR, /**< map '${0}' not assignable with a scalar */
|
QSE_AWK_EMAPNA, /**< map '${0}' not assignable */
|
||||||
|
QSE_AWK_EMAPPH, /**< map prohibited */
|
||||||
QSE_AWK_ESCALARTOMAP, /**< cannot change a scalar value to a map */
|
QSE_AWK_ESCALARTOMAP, /**< cannot change a scalar value to a map */
|
||||||
QSE_AWK_EMAPNA, /**< map not allowed */
|
|
||||||
QSE_AWK_EVALTYPE, /**< invalid value type */
|
QSE_AWK_EVALTYPE, /**< invalid value type */
|
||||||
QSE_AWK_ERNEXTBEG, /**< 'next' called from BEGIN block */
|
QSE_AWK_ERNEXTBEG, /**< 'next' called from BEGIN block */
|
||||||
QSE_AWK_ERNEXTEND, /**< 'next' called from END block */
|
QSE_AWK_ERNEXTEND, /**< 'next' called from END block */
|
||||||
|
@ -109,8 +109,8 @@ const qse_char_t* qse_awk_dflerrstr (const qse_awk_t* awk, qse_awk_errnum_t errn
|
|||||||
QSE_T("too few arguments"),
|
QSE_T("too few arguments"),
|
||||||
QSE_T("too many arguments"),
|
QSE_T("too many arguments"),
|
||||||
QSE_T("function '${0}' not found"),
|
QSE_T("function '${0}' not found"),
|
||||||
QSE_T("variable not indexable"),
|
QSE_T("not indexable"),
|
||||||
QSE_T("variable '${0}' not deletable"),
|
QSE_T("'${0}' not deletable"),
|
||||||
QSE_T("value not a map"),
|
QSE_T("value not a map"),
|
||||||
QSE_T("right-hand side of the 'in' operator not a map"),
|
QSE_T("right-hand side of the 'in' operator not a map"),
|
||||||
QSE_T("right-hand side of the 'in' operator not a map nor nil"),
|
QSE_T("right-hand side of the 'in' operator not a map nor nil"),
|
||||||
@ -118,9 +118,9 @@ const qse_char_t* qse_awk_dflerrstr (const qse_awk_t* awk, qse_awk_errnum_t errn
|
|||||||
QSE_T("value not assignable"),
|
QSE_T("value not assignable"),
|
||||||
QSE_T("indexed value cannot be assigned a map"),
|
QSE_T("indexed value cannot be assigned a map"),
|
||||||
QSE_T("positional value cannot be assigned a map"),
|
QSE_T("positional value cannot be assigned a map"),
|
||||||
QSE_T("map '${0}' not assignable with a scalar"),
|
QSE_T("map '${0}' not assignable"),
|
||||||
|
QSE_T("map prohibited"),
|
||||||
QSE_T("cannot change a scalar value to a map"),
|
QSE_T("cannot change a scalar value to a map"),
|
||||||
QSE_T("map not allowed"),
|
|
||||||
QSE_T("invalid value type"),
|
QSE_T("invalid value type"),
|
||||||
QSE_T("'next' called from BEGIN block"),
|
QSE_T("'next' called from BEGIN block"),
|
||||||
QSE_T("'next' called from END block"),
|
QSE_T("'next' called from END block"),
|
||||||
|
@ -651,11 +651,14 @@ static int fnc_split (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi)
|
|||||||
a1_ref = (qse_awk_val_t**)((qse_awk_val_ref_t*)a1)->adr;
|
a1_ref = (qse_awk_val_t**)((qse_awk_val_ref_t*)a1)->adr;
|
||||||
if ((*a1_ref)->type != QSE_AWK_VAL_NIL &&
|
if ((*a1_ref)->type != QSE_AWK_VAL_NIL &&
|
||||||
(*a1_ref)->type != QSE_AWK_VAL_MAP)
|
(*a1_ref)->type != QSE_AWK_VAL_MAP)
|
||||||
|
{
|
||||||
|
if (!(run->awk->opt.trait & QSE_AWK_MAPTOVAR))
|
||||||
{
|
{
|
||||||
/* cannot change a scalar value to a map */
|
/* cannot change a scalar value to a map */
|
||||||
qse_awk_rtx_seterrnum (run, QSE_AWK_ESCALARTOMAP, QSE_NULL);
|
qse_awk_rtx_seterrnum (run, QSE_AWK_ESCALARTOMAP, QSE_NULL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (a0->type == QSE_AWK_VAL_STR)
|
if (a0->type == QSE_AWK_VAL_STR)
|
||||||
{
|
{
|
||||||
@ -976,7 +979,7 @@ static int __substitute (qse_awk_rtx_t* run, qse_long_t max_count)
|
|||||||
if ((*a2_ref)->type == QSE_AWK_VAL_MAP)
|
if ((*a2_ref)->type == QSE_AWK_VAL_MAP)
|
||||||
{
|
{
|
||||||
/* a map is not allowed as the third parameter */
|
/* a map is not allowed as the third parameter */
|
||||||
qse_awk_rtx_seterrnum (run, QSE_AWK_EMAPNA, QSE_NULL);
|
qse_awk_rtx_seterrnum (run, QSE_AWK_EMAPPH, QSE_NULL);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,8 +28,8 @@ enum tok_t
|
|||||||
/* special token to direct the parser to include a file specified */
|
/* special token to direct the parser to include a file specified */
|
||||||
TOK_INCLUDE,
|
TOK_INCLUDE,
|
||||||
|
|
||||||
/* TOK_XXX_ASSNs should be in sync
|
/* TOK_XXX_ASSNs should be in sync with assop in assign_to_opcode.
|
||||||
* with assop in assign_to_opcode */
|
* it also should be in the order as qse_awk_assop_type_t in run.h */
|
||||||
TOK_ASSN,
|
TOK_ASSN,
|
||||||
TOK_PLUS_ASSN,
|
TOK_PLUS_ASSN,
|
||||||
TOK_MINUS_ASSN,
|
TOK_MINUS_ASSN,
|
||||||
@ -46,12 +46,15 @@ enum tok_t
|
|||||||
TOK_BOR_ASSN,
|
TOK_BOR_ASSN,
|
||||||
/* end of TOK_XXX_ASSN */
|
/* end of TOK_XXX_ASSN */
|
||||||
|
|
||||||
|
TOK_TEQ,
|
||||||
|
TOK_TNE,
|
||||||
TOK_EQ,
|
TOK_EQ,
|
||||||
TOK_NE,
|
TOK_NE,
|
||||||
TOK_LE,
|
TOK_LE,
|
||||||
TOK_LT,
|
TOK_LT,
|
||||||
TOK_GE,
|
TOK_GE,
|
||||||
TOK_GT,
|
TOK_GT,
|
||||||
|
TOK_MA, /* match */
|
||||||
TOK_NM, /* not match */
|
TOK_NM, /* not match */
|
||||||
TOK_LNOT, /* logical negation ! */
|
TOK_LNOT, /* logical negation ! */
|
||||||
TOK_PLUS,
|
TOK_PLUS,
|
||||||
@ -67,7 +70,7 @@ enum tok_t
|
|||||||
TOK_BOR,
|
TOK_BOR,
|
||||||
TOK_BXOR,
|
TOK_BXOR,
|
||||||
TOK_BAND,
|
TOK_BAND,
|
||||||
TOK_TILDE, /* used for unary bitwise-not and regex match */
|
TOK_BNOT, /* used for unary bitwise-not and regex match */
|
||||||
TOK_RS,
|
TOK_RS,
|
||||||
TOK_LS,
|
TOK_LS,
|
||||||
TOK_IN,
|
TOK_IN,
|
||||||
@ -259,7 +262,7 @@ static kwent_t kwtab[] =
|
|||||||
* also keep it sorted by the first field for binary search */
|
* also keep it sorted by the first field for binary search */
|
||||||
{ { QSE_T("BEGIN"), 5 }, TOK_BEGIN, QSE_AWK_PABLOCK },
|
{ { QSE_T("BEGIN"), 5 }, TOK_BEGIN, QSE_AWK_PABLOCK },
|
||||||
{ { QSE_T("END"), 3 }, TOK_END, QSE_AWK_PABLOCK },
|
{ { QSE_T("END"), 3 }, TOK_END, QSE_AWK_PABLOCK },
|
||||||
{ { QSE_T("abort"), 5 }, TOK_ABORT, QSE_AWK_ABORT },
|
{ { QSE_T("abort"), 5 }, TOK_ABORT, QSE_AWK_EXTRAKWS },
|
||||||
{ { QSE_T("break"), 5 }, TOK_BREAK, 0 },
|
{ { QSE_T("break"), 5 }, TOK_BREAK, 0 },
|
||||||
{ { QSE_T("continue"), 8 }, TOK_CONTINUE, 0 },
|
{ { QSE_T("continue"), 8 }, TOK_CONTINUE, 0 },
|
||||||
{ { QSE_T("delete"), 6 }, TOK_DELETE, 0 },
|
{ { QSE_T("delete"), 6 }, TOK_DELETE, 0 },
|
||||||
@ -272,14 +275,14 @@ static kwent_t kwtab[] =
|
|||||||
{ { QSE_T("global"), 6 }, TOK_GLOBAL, QSE_AWK_EXPLICIT },
|
{ { QSE_T("global"), 6 }, TOK_GLOBAL, QSE_AWK_EXPLICIT },
|
||||||
{ { QSE_T("if"), 2 }, TOK_IF, 0 },
|
{ { QSE_T("if"), 2 }, TOK_IF, 0 },
|
||||||
{ { QSE_T("in"), 2 }, TOK_IN, 0 },
|
{ { QSE_T("in"), 2 }, TOK_IN, 0 },
|
||||||
{ { QSE_T("include"), 7 }, TOK_INCLUDE, QSE_AWK_INCLUDE },
|
{ { QSE_T("include"), 7 }, TOK_INCLUDE, QSE_AWK_EXTRAKWS },
|
||||||
{ { QSE_T("local"), 5 }, TOK_LOCAL, QSE_AWK_EXPLICIT },
|
{ { QSE_T("local"), 5 }, TOK_LOCAL, QSE_AWK_EXPLICIT },
|
||||||
{ { QSE_T("next"), 4 }, TOK_NEXT, QSE_AWK_PABLOCK },
|
{ { QSE_T("next"), 4 }, TOK_NEXT, QSE_AWK_PABLOCK },
|
||||||
{ { QSE_T("nextfile"), 8 }, TOK_NEXTFILE, QSE_AWK_PABLOCK },
|
{ { QSE_T("nextfile"), 8 }, TOK_NEXTFILE, QSE_AWK_PABLOCK },
|
||||||
{ { QSE_T("nextofile"), 9 }, TOK_NEXTOFILE, QSE_AWK_PABLOCK | QSE_AWK_NEXTOFILE },
|
{ { QSE_T("nextofile"), 9 }, TOK_NEXTOFILE, QSE_AWK_PABLOCK | QSE_AWK_EXTRAKWS },
|
||||||
{ { QSE_T("print"), 5 }, TOK_PRINT, QSE_AWK_RIO },
|
{ { QSE_T("print"), 5 }, TOK_PRINT, QSE_AWK_RIO },
|
||||||
{ { QSE_T("printf"), 6 }, TOK_PRINTF, QSE_AWK_RIO },
|
{ { QSE_T("printf"), 6 }, TOK_PRINTF, QSE_AWK_RIO },
|
||||||
{ { QSE_T("reset"), 5 }, TOK_RESET, QSE_AWK_RESET },
|
{ { QSE_T("reset"), 5 }, TOK_RESET, QSE_AWK_EXTRAKWS },
|
||||||
{ { QSE_T("return"), 6 }, TOK_RETURN, 0 },
|
{ { QSE_T("return"), 6 }, TOK_RETURN, 0 },
|
||||||
{ { QSE_T("while"), 5 }, TOK_WHILE, 0 }
|
{ { QSE_T("while"), 5 }, TOK_WHILE, 0 }
|
||||||
};
|
};
|
||||||
@ -319,7 +322,7 @@ static global_t gtab[] =
|
|||||||
{ QSE_T("NR"), 2, QSE_AWK_PABLOCK },
|
{ QSE_T("NR"), 2, QSE_AWK_PABLOCK },
|
||||||
|
|
||||||
/* current output file name */
|
/* current output file name */
|
||||||
{ QSE_T("OFILENAME"), 9, QSE_AWK_PABLOCK | QSE_AWK_NEXTOFILE },
|
{ QSE_T("OFILENAME"), 9, QSE_AWK_PABLOCK | QSE_AWK_EXTRAKWS },
|
||||||
|
|
||||||
/* output real-to-str conversion format for 'print' */
|
/* output real-to-str conversion format for 'print' */
|
||||||
{ QSE_T("OFMT"), 4, QSE_AWK_RIO },
|
{ QSE_T("OFMT"), 4, QSE_AWK_RIO },
|
||||||
@ -385,12 +388,7 @@ static global_t gtab[] =
|
|||||||
qse_awk_seterror (awk, QSE_AWK_ENOERR, QSE_NULL, QSE_NULL)
|
qse_awk_seterror (awk, QSE_AWK_ENOERR, QSE_NULL, QSE_NULL)
|
||||||
|
|
||||||
#define SETERR_TOK(awk,code) \
|
#define SETERR_TOK(awk,code) \
|
||||||
do { \
|
qse_awk_seterror (awk, code, QSE_STR_CSTR((awk)->tok.name), &(awk)->tok.loc)
|
||||||
qse_cstr_t __ea; \
|
|
||||||
__ea.len = QSE_STR_LEN((awk)->tok.name); \
|
|
||||||
__ea.ptr = QSE_STR_PTR((awk)->tok.name); \
|
|
||||||
qse_awk_seterror (awk, code, &__ea, &(awk)->tok.loc); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define SETERR_COD(awk,code) \
|
#define SETERR_COD(awk,code) \
|
||||||
qse_awk_seterror (awk, code, QSE_NULL, QSE_NULL)
|
qse_awk_seterror (awk, code, QSE_NULL, QSE_NULL)
|
||||||
@ -673,6 +671,46 @@ int qse_awk_parse (qse_awk_t* awk, qse_awk_sio_t* sio)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int end_include (qse_awk_t* awk)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
qse_awk_sio_arg_t* cur;
|
||||||
|
|
||||||
|
if (awk->sio.inp == &awk->sio.arg) return 0; /* no include */
|
||||||
|
|
||||||
|
/* if it is an included file, close it and
|
||||||
|
* retry to read a character from an outer file */
|
||||||
|
|
||||||
|
CLRERR (awk);
|
||||||
|
x = awk->sio.inf (
|
||||||
|
awk, QSE_AWK_SIO_CLOSE,
|
||||||
|
awk->sio.inp, QSE_NULL, 0);
|
||||||
|
|
||||||
|
/* if closing has failed, still destroy the
|
||||||
|
* sio structure first as normal and return
|
||||||
|
* the failure below. this way, the caller
|
||||||
|
* does not call QSE_AWK_SIO_CLOSE on
|
||||||
|
* awk->sio.inp again. */
|
||||||
|
|
||||||
|
cur = awk->sio.inp;
|
||||||
|
awk->sio.inp = awk->sio.inp->next;
|
||||||
|
|
||||||
|
QSE_ASSERT (cur->name != QSE_NULL);
|
||||||
|
QSE_MMGR_FREE (awk->mmgr, cur);
|
||||||
|
awk->parse.depth.incl--;
|
||||||
|
|
||||||
|
if (x != 0)
|
||||||
|
{
|
||||||
|
/* the failure mentioned above is returned here */
|
||||||
|
if (ISNOERR(awk))
|
||||||
|
SETERR_ARG (awk, QSE_AWK_ECLOSE, QSE_T("<SIN>"), 5);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
awk->sio.last = awk->sio.inp->last;
|
||||||
|
return 1; /* ended the included file successfully */
|
||||||
|
}
|
||||||
|
|
||||||
static int begin_include (qse_awk_t* awk)
|
static int begin_include (qse_awk_t* awk)
|
||||||
{
|
{
|
||||||
qse_ssize_t op;
|
qse_ssize_t op;
|
||||||
@ -747,52 +785,23 @@ static int begin_include (qse_awk_t* awk)
|
|||||||
awk->sio.inp->line = 1;
|
awk->sio.inp->line = 1;
|
||||||
awk->sio.inp->colm = 1;
|
awk->sio.inp->colm = 1;
|
||||||
|
|
||||||
|
/* read in the first character in the included file.
|
||||||
|
* so the next call to get_token() sees the character read
|
||||||
|
* from this file. */
|
||||||
|
if (get_char (awk) <= -1)
|
||||||
|
{
|
||||||
|
end_include (awk);
|
||||||
|
/* since i've called end_include(), i don't go to oops */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
if (arg != QSE_NULL) QSE_MMGR_FREE (awk->mmgr, arg);
|
if (arg) QSE_MMGR_FREE (awk->mmgr, arg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int end_include (qse_awk_t* awk)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
qse_awk_sio_arg_t* cur;
|
|
||||||
|
|
||||||
if (awk->sio.inp == &awk->sio.arg) return 0; /* no include */
|
|
||||||
|
|
||||||
/* if it is an included file, close it and
|
|
||||||
* retry to read a character from an outer file */
|
|
||||||
|
|
||||||
CLRERR (awk);
|
|
||||||
x = awk->sio.inf (
|
|
||||||
awk, QSE_AWK_SIO_CLOSE,
|
|
||||||
awk->sio.inp, QSE_NULL, 0);
|
|
||||||
|
|
||||||
/* if closing has failed, still destroy the
|
|
||||||
* sio structure first as normal and return
|
|
||||||
* the failure below. this way, the caller
|
|
||||||
* does not call QSE_AWK_SIO_CLOSE on
|
|
||||||
* awk->sio.inp again. */
|
|
||||||
|
|
||||||
cur = awk->sio.inp;
|
|
||||||
awk->sio.inp = awk->sio.inp->next;
|
|
||||||
|
|
||||||
QSE_ASSERT (cur->name != QSE_NULL);
|
|
||||||
QSE_MMGR_FREE (awk->mmgr, cur);
|
|
||||||
awk->parse.depth.incl--;
|
|
||||||
|
|
||||||
if (x != 0)
|
|
||||||
{
|
|
||||||
/* the failure mentioned above is returned here */
|
|
||||||
if (ISNOERR(awk))
|
|
||||||
SETERR_ARG (awk, QSE_AWK_ECLOSE, QSE_T("<SIN>"), 5);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1; /* ended the included file successfully */
|
|
||||||
}
|
|
||||||
|
|
||||||
static qse_awk_t* parse_progunit (qse_awk_t* awk)
|
static qse_awk_t* parse_progunit (qse_awk_t* awk)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -850,8 +859,9 @@ retry:
|
|||||||
|
|
||||||
if (begin_include (awk) <= -1) return QSE_NULL;
|
if (begin_include (awk) <= -1) return QSE_NULL;
|
||||||
|
|
||||||
/* read the first meaningful token from the included file
|
/* i'm retrying to get the first top-level
|
||||||
* and recheck it by jumping to retry: */
|
* element as if parse_progunit() is called.
|
||||||
|
* so i need to skip NEWLINE tokens */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (get_token(awk) <= -1) return QSE_NULL;
|
if (get_token(awk) <= -1) return QSE_NULL;
|
||||||
@ -898,6 +908,10 @@ retry:
|
|||||||
|
|
||||||
awk->parse.id.block = PARSE_BEGIN_BLOCK;
|
awk->parse.id.block = PARSE_BEGIN_BLOCK;
|
||||||
if (parse_begin (awk) == QSE_NULL) return QSE_NULL;
|
if (parse_begin (awk) == QSE_NULL) return QSE_NULL;
|
||||||
|
|
||||||
|
/* skip a semicolon after an action block if any */
|
||||||
|
if (MATCH(awk,TOK_SEMICOLON) &&
|
||||||
|
get_token (awk) <= -1) return QSE_NULL;
|
||||||
}
|
}
|
||||||
else if (MATCH(awk,TOK_END))
|
else if (MATCH(awk,TOK_END))
|
||||||
{
|
{
|
||||||
@ -926,6 +940,10 @@ retry:
|
|||||||
|
|
||||||
awk->parse.id.block = PARSE_END_BLOCK;
|
awk->parse.id.block = PARSE_END_BLOCK;
|
||||||
if (parse_end (awk) == QSE_NULL) return QSE_NULL;
|
if (parse_end (awk) == QSE_NULL) return QSE_NULL;
|
||||||
|
|
||||||
|
/* skip a semicolon after an action block if any */
|
||||||
|
if (MATCH(awk,TOK_SEMICOLON) &&
|
||||||
|
get_token (awk) <= -1) return QSE_NULL;
|
||||||
}
|
}
|
||||||
else if (MATCH(awk,TOK_LBRACE))
|
else if (MATCH(awk,TOK_LBRACE))
|
||||||
{
|
{
|
||||||
@ -3629,8 +3647,7 @@ oops:
|
|||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_logical_or (
|
static qse_awk_nde_t* parse_logical_or (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
static binmap_t map[] =
|
static binmap_t map[] =
|
||||||
{
|
{
|
||||||
@ -3641,8 +3658,7 @@ static qse_awk_nde_t* parse_logical_or (
|
|||||||
return parse_binary (awk, xloc, 1, map, parse_logical_and);
|
return parse_binary (awk, xloc, 1, map, parse_logical_and);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_logical_and (
|
static qse_awk_nde_t* parse_logical_and (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
static binmap_t map[] =
|
static binmap_t map[] =
|
||||||
{
|
{
|
||||||
@ -3653,8 +3669,7 @@ static qse_awk_nde_t* parse_logical_and (
|
|||||||
return parse_binary (awk, xloc, 1, map, parse_in);
|
return parse_binary (awk, xloc, 1, map, parse_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_in (
|
static qse_awk_nde_t* parse_in (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
static binmap_t map[] =
|
static binmap_t map[] =
|
||||||
@ -3708,12 +3723,11 @@ oops:
|
|||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_regex_match (
|
static qse_awk_nde_t* parse_regex_match (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
static binmap_t map[] =
|
static binmap_t map[] =
|
||||||
{
|
{
|
||||||
{ TOK_TILDE, QSE_AWK_BINOP_MA },
|
{ TOK_MA, QSE_AWK_BINOP_MA },
|
||||||
{ TOK_NM, QSE_AWK_BINOP_NM },
|
{ TOK_NM, QSE_AWK_BINOP_NM },
|
||||||
{ TOK_EOF, 0 },
|
{ TOK_EOF, 0 },
|
||||||
};
|
};
|
||||||
@ -3721,8 +3735,7 @@ static qse_awk_nde_t* parse_regex_match (
|
|||||||
return parse_binary (awk, xloc, 0, map, parse_bitwise_or);
|
return parse_binary (awk, xloc, 0, map, parse_bitwise_or);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_bitwise_or (
|
static qse_awk_nde_t* parse_bitwise_or (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
static binmap_t map[] =
|
static binmap_t map[] =
|
||||||
{
|
{
|
||||||
@ -3733,8 +3746,7 @@ static qse_awk_nde_t* parse_bitwise_or (
|
|||||||
return parse_binary (awk, xloc, 0, map, parse_bitwise_xor);
|
return parse_binary (awk, xloc, 0, map, parse_bitwise_xor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_bitwise_xor (
|
static qse_awk_nde_t* parse_bitwise_xor (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
static binmap_t map[] =
|
static binmap_t map[] =
|
||||||
{
|
{
|
||||||
@ -3745,8 +3757,7 @@ static qse_awk_nde_t* parse_bitwise_xor (
|
|||||||
return parse_binary (awk, xloc, 0, map, parse_bitwise_and);
|
return parse_binary (awk, xloc, 0, map, parse_bitwise_and);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_bitwise_and (
|
static qse_awk_nde_t* parse_bitwise_and (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
static binmap_t map[] =
|
static binmap_t map[] =
|
||||||
{
|
{
|
||||||
@ -3757,11 +3768,12 @@ static qse_awk_nde_t* parse_bitwise_and (
|
|||||||
return parse_binary (awk, xloc, 0, map, parse_equality);
|
return parse_binary (awk, xloc, 0, map, parse_equality);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_equality (
|
static qse_awk_nde_t* parse_equality (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
static binmap_t map[] =
|
static binmap_t map[] =
|
||||||
{
|
{
|
||||||
|
{ TOK_TEQ, QSE_AWK_BINOP_TEQ },
|
||||||
|
{ TOK_TNE, QSE_AWK_BINOP_TNE },
|
||||||
{ TOK_EQ, QSE_AWK_BINOP_EQ },
|
{ TOK_EQ, QSE_AWK_BINOP_EQ },
|
||||||
{ TOK_NE, QSE_AWK_BINOP_NE },
|
{ TOK_NE, QSE_AWK_BINOP_NE },
|
||||||
{ TOK_EOF, 0 }
|
{ TOK_EOF, 0 }
|
||||||
@ -3770,8 +3782,7 @@ static qse_awk_nde_t* parse_equality (
|
|||||||
return parse_binary (awk, xloc, 0, map, parse_relational);
|
return parse_binary (awk, xloc, 0, map, parse_relational);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_relational (
|
static qse_awk_nde_t* parse_relational (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
static binmap_t map[] =
|
static binmap_t map[] =
|
||||||
{
|
{
|
||||||
@ -3782,12 +3793,10 @@ static qse_awk_nde_t* parse_relational (
|
|||||||
{ TOK_EOF, 0 }
|
{ TOK_EOF, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
return parse_binary (awk, xloc, 0, map,
|
return parse_binary (awk, xloc, 0, map, parse_shift);
|
||||||
((awk->opt.trait & QSE_AWK_EXTRAOPS)? parse_shift: parse_concat));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_shift (
|
static qse_awk_nde_t* parse_shift (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
static binmap_t map[] =
|
static binmap_t map[] =
|
||||||
{
|
{
|
||||||
@ -3799,8 +3808,7 @@ static qse_awk_nde_t* parse_shift (
|
|||||||
return parse_binary (awk, xloc, 0, map, parse_concat);
|
return parse_binary (awk, xloc, 0, map, parse_concat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_concat (
|
static qse_awk_nde_t* parse_concat (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
qse_awk_nde_t* left = QSE_NULL;
|
qse_awk_nde_t* left = QSE_NULL;
|
||||||
qse_awk_nde_t* right = QSE_NULL;
|
qse_awk_nde_t* right = QSE_NULL;
|
||||||
@ -3853,8 +3861,7 @@ oops:
|
|||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_additive (
|
static qse_awk_nde_t* parse_additive (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
static binmap_t map[] =
|
static binmap_t map[] =
|
||||||
{
|
{
|
||||||
@ -3866,8 +3873,7 @@ static qse_awk_nde_t* parse_additive (
|
|||||||
return parse_binary (awk, xloc, 0, map, parse_multiplicative);
|
return parse_binary (awk, xloc, 0, map, parse_multiplicative);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_multiplicative (
|
static qse_awk_nde_t* parse_multiplicative (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
static binmap_t map[] =
|
static binmap_t map[] =
|
||||||
{
|
{
|
||||||
@ -3882,8 +3888,7 @@ static qse_awk_nde_t* parse_multiplicative (
|
|||||||
return parse_binary (awk, xloc, 0, map, parse_unary);
|
return parse_binary (awk, xloc, 0, map, parse_unary);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_unary (
|
static qse_awk_nde_t* parse_unary (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
qse_awk_nde_t* left;
|
qse_awk_nde_t* left;
|
||||||
qse_awk_loc_t uloc;
|
qse_awk_loc_t uloc;
|
||||||
@ -3894,8 +3899,7 @@ static qse_awk_nde_t* parse_unary (
|
|||||||
opcode = (MATCH(awk,TOK_PLUS))? QSE_AWK_UNROP_PLUS:
|
opcode = (MATCH(awk,TOK_PLUS))? QSE_AWK_UNROP_PLUS:
|
||||||
(MATCH(awk,TOK_MINUS))? QSE_AWK_UNROP_MINUS:
|
(MATCH(awk,TOK_MINUS))? QSE_AWK_UNROP_MINUS:
|
||||||
(MATCH(awk,TOK_LNOT))? QSE_AWK_UNROP_LNOT:
|
(MATCH(awk,TOK_LNOT))? QSE_AWK_UNROP_LNOT:
|
||||||
((awk->opt.trait & QSE_AWK_EXTRAOPS) && MATCH(awk,TOK_TILDE))?
|
(MATCH(awk,TOK_BNOT))? QSE_AWK_UNROP_BNOT: -1;
|
||||||
QSE_AWK_UNROP_BNOT: -1;
|
|
||||||
|
|
||||||
/*if (opcode <= -1) return parse_increment (awk);*/
|
/*if (opcode <= -1) return parse_increment (awk);*/
|
||||||
if (opcode <= -1) return parse_exponent (awk, xloc);
|
if (opcode <= -1) return parse_exponent (awk, xloc);
|
||||||
@ -4023,8 +4027,7 @@ static qse_awk_nde_t* parse_unary (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_exponent (
|
static qse_awk_nde_t* parse_exponent (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
static binmap_t map[] =
|
static binmap_t map[] =
|
||||||
{
|
{
|
||||||
@ -4035,8 +4038,7 @@ static qse_awk_nde_t* parse_exponent (
|
|||||||
return parse_binary (awk, xloc, 0, map, parse_unary_exp);
|
return parse_binary (awk, xloc, 0, map, parse_unary_exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_unary_exp (
|
static qse_awk_nde_t* parse_unary_exp (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
qse_awk_nde_exp_t* nde;
|
qse_awk_nde_exp_t* nde;
|
||||||
qse_awk_nde_t* left;
|
qse_awk_nde_t* left;
|
||||||
@ -4046,8 +4048,7 @@ static qse_awk_nde_t* parse_unary_exp (
|
|||||||
opcode = (MATCH(awk,TOK_PLUS))? QSE_AWK_UNROP_PLUS:
|
opcode = (MATCH(awk,TOK_PLUS))? QSE_AWK_UNROP_PLUS:
|
||||||
(MATCH(awk,TOK_MINUS))? QSE_AWK_UNROP_MINUS:
|
(MATCH(awk,TOK_MINUS))? QSE_AWK_UNROP_MINUS:
|
||||||
(MATCH(awk,TOK_LNOT))? QSE_AWK_UNROP_LNOT:
|
(MATCH(awk,TOK_LNOT))? QSE_AWK_UNROP_LNOT:
|
||||||
((awk->opt.trait & QSE_AWK_EXTRAOPS) && MATCH(awk,TOK_TILDE))?
|
(MATCH(awk,TOK_BNOT))? QSE_AWK_UNROP_BNOT: -1;
|
||||||
QSE_AWK_UNROP_BNOT: -1;
|
|
||||||
|
|
||||||
if (opcode <= -1) return parse_increment (awk, xloc);
|
if (opcode <= -1) return parse_increment (awk, xloc);
|
||||||
|
|
||||||
@ -4085,8 +4086,7 @@ static qse_awk_nde_t* parse_unary_exp (
|
|||||||
return (qse_awk_nde_t*)nde;
|
return (qse_awk_nde_t*)nde;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_increment (
|
static qse_awk_nde_t* parse_increment (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
||||||
qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|
||||||
{
|
{
|
||||||
qse_awk_nde_exp_t* nde;
|
qse_awk_nde_exp_t* nde;
|
||||||
qse_awk_nde_t* left;
|
qse_awk_nde_t* left;
|
||||||
@ -5805,16 +5805,18 @@ static int get_symbols (qse_awk_t* awk, qse_cint_t c, qse_awk_tok_t* tok)
|
|||||||
|
|
||||||
static struct ops_t ops[] =
|
static struct ops_t ops[] =
|
||||||
{
|
{
|
||||||
|
{ QSE_T("==="), 3, TOK_TEQ, 0 },
|
||||||
{ QSE_T("=="), 2, TOK_EQ, 0 },
|
{ QSE_T("=="), 2, TOK_EQ, 0 },
|
||||||
{ QSE_T("="), 1, TOK_ASSN, 0 },
|
{ QSE_T("="), 1, TOK_ASSN, 0 },
|
||||||
|
{ QSE_T("!=="), 3, TOK_TNE, 0 },
|
||||||
{ QSE_T("!="), 2, TOK_NE, 0 },
|
{ QSE_T("!="), 2, TOK_NE, 0 },
|
||||||
{ QSE_T("!~"), 2, TOK_NM, 0 },
|
{ QSE_T("!~"), 2, TOK_NM, 0 },
|
||||||
{ QSE_T("!"), 1, TOK_LNOT, 0 },
|
{ QSE_T("!"), 1, TOK_LNOT, 0 },
|
||||||
{ QSE_T(">>="), 3, TOK_RS_ASSN, QSE_AWK_EXTRAOPS },
|
{ QSE_T(">>="), 3, TOK_RS_ASSN, 0 },
|
||||||
{ QSE_T(">>"), 2, TOK_RS, 0 },
|
{ QSE_T(">>"), 2, TOK_RS, 0 },
|
||||||
{ QSE_T(">="), 2, TOK_GE, 0 },
|
{ QSE_T(">="), 2, TOK_GE, 0 },
|
||||||
{ QSE_T(">"), 1, TOK_GT, 0 },
|
{ QSE_T(">"), 1, TOK_GT, 0 },
|
||||||
{ QSE_T("<<="), 3, TOK_LS_ASSN, QSE_AWK_EXTRAOPS },
|
{ QSE_T("<<="), 3, TOK_LS_ASSN, 0 },
|
||||||
{ QSE_T("<<"), 2, TOK_LS, 0 },
|
{ QSE_T("<<"), 2, TOK_LS, 0 },
|
||||||
{ QSE_T("<="), 2, TOK_LE, 0 },
|
{ QSE_T("<="), 2, TOK_LE, 0 },
|
||||||
{ QSE_T("<"), 1, TOK_LT, 0 },
|
{ QSE_T("<"), 1, TOK_LT, 0 },
|
||||||
@ -5824,8 +5826,8 @@ static int get_symbols (qse_awk_t* awk, qse_cint_t c, qse_awk_tok_t* tok)
|
|||||||
{ QSE_T("&&"), 2, TOK_LAND, 0 },
|
{ QSE_T("&&"), 2, TOK_LAND, 0 },
|
||||||
{ QSE_T("&="), 2, TOK_BAND_ASSN, 0 },
|
{ QSE_T("&="), 2, TOK_BAND_ASSN, 0 },
|
||||||
{ QSE_T("&"), 1, TOK_BAND, 0 },
|
{ QSE_T("&"), 1, TOK_BAND, 0 },
|
||||||
{ QSE_T("^^="), 3, TOK_BXOR_ASSN, QSE_AWK_EXTRAOPS },
|
{ QSE_T("^^="), 3, TOK_BXOR_ASSN, 0 },
|
||||||
{ QSE_T("^^"), 2, TOK_BXOR, QSE_AWK_EXTRAOPS },
|
{ QSE_T("^^"), 2, TOK_BXOR, 0 },
|
||||||
{ QSE_T("^="), 2, TOK_EXP_ASSN, 0 },
|
{ QSE_T("^="), 2, TOK_EXP_ASSN, 0 },
|
||||||
{ QSE_T("^"), 1, TOK_EXP, 0 },
|
{ QSE_T("^"), 1, TOK_EXP, 0 },
|
||||||
{ QSE_T("++"), 2, TOK_PLUSPLUS, 0 },
|
{ QSE_T("++"), 2, TOK_PLUSPLUS, 0 },
|
||||||
@ -5834,19 +5836,20 @@ static int get_symbols (qse_awk_t* awk, qse_cint_t c, qse_awk_tok_t* tok)
|
|||||||
{ QSE_T("--"), 2, TOK_MINUSMINUS, 0 },
|
{ QSE_T("--"), 2, TOK_MINUSMINUS, 0 },
|
||||||
{ QSE_T("-="), 2, TOK_MINUS_ASSN, 0 },
|
{ QSE_T("-="), 2, TOK_MINUS_ASSN, 0 },
|
||||||
{ QSE_T("-"), 1, TOK_MINUS, 0 },
|
{ QSE_T("-"), 1, TOK_MINUS, 0 },
|
||||||
{ QSE_T("**="), 3, TOK_EXP_ASSN, QSE_AWK_EXTRAOPS },
|
{ QSE_T("**="), 3, TOK_EXP_ASSN, 0 },
|
||||||
{ QSE_T("**"), 2, TOK_EXP, QSE_AWK_EXTRAOPS },
|
{ QSE_T("**"), 2, TOK_EXP, 0 },
|
||||||
{ QSE_T("*="), 2, TOK_MUL_ASSN, 0 },
|
{ QSE_T("*="), 2, TOK_MUL_ASSN, 0 },
|
||||||
{ QSE_T("*"), 1, TOK_MUL, 0 },
|
{ QSE_T("*"), 1, TOK_MUL, 0 },
|
||||||
{ QSE_T("/="), 2, TOK_DIV_ASSN, 0 },
|
{ QSE_T("/="), 2, TOK_DIV_ASSN, 0 },
|
||||||
{ QSE_T("/"), 1, TOK_DIV, 0 },
|
{ QSE_T("/"), 1, TOK_DIV, 0 },
|
||||||
{ QSE_T("\\="), 2, TOK_IDIV_ASSN, QSE_AWK_EXTRAOPS },
|
{ QSE_T("\\="), 2, TOK_IDIV_ASSN, 0 },
|
||||||
{ QSE_T("\\"), 1, TOK_IDIV, QSE_AWK_EXTRAOPS },
|
{ QSE_T("\\"), 1, TOK_IDIV, 0 },
|
||||||
{ QSE_T("%%="), 3, TOK_CONCAT_ASSN, QSE_AWK_EXPLICIT },
|
{ QSE_T("%%="), 3, TOK_CONCAT_ASSN, 0 },
|
||||||
{ QSE_T("%%"), 2, TOK_CONCAT, QSE_AWK_EXPLICIT },
|
{ QSE_T("%%"), 2, TOK_CONCAT, 0 },
|
||||||
{ QSE_T("%="), 2, TOK_MOD_ASSN, 0 },
|
{ QSE_T("%="), 2, TOK_MOD_ASSN, 0 },
|
||||||
{ QSE_T("%"), 1, TOK_MOD, 0 },
|
{ QSE_T("%"), 1, TOK_MOD, 0 },
|
||||||
{ QSE_T("~"), 1, TOK_TILDE, 0 },
|
{ QSE_T("~~"), 2, TOK_BNOT, 0 },
|
||||||
|
{ QSE_T("~"), 1, TOK_MA, 0 },
|
||||||
{ QSE_T("("), 1, TOK_LPAREN, 0 },
|
{ QSE_T("("), 1, TOK_LPAREN, 0 },
|
||||||
{ QSE_T(")"), 1, TOK_RPAREN, 0 },
|
{ QSE_T(")"), 1, TOK_RPAREN, 0 },
|
||||||
{ QSE_T("{"), 1, TOK_LBRACE, 0 },
|
{ QSE_T("{"), 1, TOK_LBRACE, 0 },
|
||||||
@ -5898,6 +5901,7 @@ static int get_token_into (qse_awk_t* awk, qse_awk_tok_t* tok)
|
|||||||
{
|
{
|
||||||
qse_cint_t c;
|
qse_cint_t c;
|
||||||
int n;
|
int n;
|
||||||
|
int skip_semicolon_after_include = 0;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
do
|
do
|
||||||
@ -5920,7 +5924,9 @@ retry:
|
|||||||
if (n <= -1) return -1;
|
if (n <= -1) return -1;
|
||||||
if (n >= 1)
|
if (n >= 1)
|
||||||
{
|
{
|
||||||
awk->sio.last = awk->sio.inp->last;
|
/*awk->sio.last = awk->sio.inp->last;*/
|
||||||
|
/* mark that i'm retrying after end of an included file */
|
||||||
|
skip_semicolon_after_include = 1;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5977,50 +5983,6 @@ retry:
|
|||||||
QSE_STR_PTR(tok->name),
|
QSE_STR_PTR(tok->name),
|
||||||
QSE_STR_LEN(tok->name));
|
QSE_STR_LEN(tok->name));
|
||||||
SET_TOKEN_TYPE (awk, tok, type);
|
SET_TOKEN_TYPE (awk, tok, type);
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (type == TOK_IDENT)
|
|
||||||
{
|
|
||||||
qse_awk_sio_lxc_t lc;
|
|
||||||
|
|
||||||
while (c == QSE_T(':'));
|
|
||||||
{
|
|
||||||
lc = awk->sio.last;
|
|
||||||
GET_CHAR_TO (awk, c);
|
|
||||||
if (c == QSE_T(':'))
|
|
||||||
{
|
|
||||||
GET_CHAR_TO (awk, c);
|
|
||||||
if (c == QSE_T('_') || QSE_AWK_ISALPHA (awk, c))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
ADD_TOKEN_CHAR (awk, tok, c);
|
|
||||||
GET_CHAR_TO (awk, c);
|
|
||||||
}
|
|
||||||
while (c == QSE_T('_') ||
|
|
||||||
QSE_AWK_ISALPHA (awk, c) ||
|
|
||||||
QSE_AWK_ISDIGIT (awk, c));
|
|
||||||
|
|
||||||
/* this set_token_type may get executed
|
|
||||||
* more than necessary if there are many
|
|
||||||
* segments. but never mind */
|
|
||||||
SET_TOKEN_TYPE (awk, tok, TOK_SEGIDENT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* TODO: return an error for the
|
|
||||||
* incomplete segmented identifier */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unget_char (awk, &awk->sio.last);
|
|
||||||
awk->sio.last = lc;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (c == QSE_T('\"'))
|
else if (c == QSE_T('\"'))
|
||||||
{
|
{
|
||||||
@ -6044,11 +6006,26 @@ retry:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
qse_char_t cc = (qse_char_t)c;
|
qse_char_t cc = (qse_char_t)c;
|
||||||
SETERR_ARG_LOC (
|
SETERR_ARG_LOC (awk, QSE_AWK_ELXCHR, &cc, 1, &tok->loc);
|
||||||
awk, QSE_AWK_ELXCHR, &cc, 1, &tok->loc);
|
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (skip_semicolon_after_include && (tok->type == TOK_SEMICOLON || tok->type == TOK_NEWLINE))
|
||||||
|
{
|
||||||
|
/* this handles the optional semicolon after the
|
||||||
|
* included file named as in @include "file-name"; */
|
||||||
|
skip_semicolon_after_include = 0;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skip_semicolon_after_include && !(awk->opt.trait & QSE_AWK_NEWLINE))
|
||||||
|
{
|
||||||
|
/* semiclon has not been skipped yet and the
|
||||||
|
* newline option is not set. */
|
||||||
|
qse_awk_seterror (awk, QSE_AWK_ESCOLON, QSE_STR_CSTR(tok->name), &tok->loc);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -161,6 +161,11 @@ static qse_awk_val_t* eval_binop_bxor (
|
|||||||
qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right);
|
qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right);
|
||||||
static qse_awk_val_t* eval_binop_band (
|
static qse_awk_val_t* eval_binop_band (
|
||||||
qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right);
|
qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right);
|
||||||
|
|
||||||
|
static qse_awk_val_t* eval_binop_teq (
|
||||||
|
qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right);
|
||||||
|
static qse_awk_val_t* eval_binop_tne (
|
||||||
|
qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right);
|
||||||
static qse_awk_val_t* eval_binop_eq (
|
static qse_awk_val_t* eval_binop_eq (
|
||||||
qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right);
|
qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right);
|
||||||
static qse_awk_val_t* eval_binop_ne (
|
static qse_awk_val_t* eval_binop_ne (
|
||||||
@ -309,12 +314,12 @@ static int set_global (
|
|||||||
/* once a variable becomes a map,
|
/* once a variable becomes a map,
|
||||||
* it cannot be changed to a scalar variable */
|
* it cannot be changed to a scalar variable */
|
||||||
|
|
||||||
if (var != QSE_NULL)
|
if (var)
|
||||||
{
|
{
|
||||||
/* global variable */
|
/* global variable */
|
||||||
SETERR_ARGX_LOC (
|
SETERR_ARGX_LOC (
|
||||||
rtx,
|
rtx,
|
||||||
QSE_AWK_EMAPTOSCALAR,
|
QSE_AWK_EMAPNA,
|
||||||
xstr_to_cstr(&var->id.name),
|
xstr_to_cstr(&var->id.name),
|
||||||
&var->loc
|
&var->loc
|
||||||
);
|
);
|
||||||
@ -324,7 +329,7 @@ static int set_global (
|
|||||||
/* qse_awk_rtx_setgbl has been called */
|
/* qse_awk_rtx_setgbl has been called */
|
||||||
qse_cstr_t ea;
|
qse_cstr_t ea;
|
||||||
ea.ptr = qse_awk_getgblname (rtx->awk, idx, &ea.len);
|
ea.ptr = qse_awk_getgblname (rtx->awk, idx, &ea.len);
|
||||||
SETERR_ARGX (rtx, QSE_AWK_EMAPTOSCALAR, &ea);
|
SETERR_ARGX (rtx, QSE_AWK_EMAPNA, &ea);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -656,7 +661,7 @@ int qse_awk_rtx_setofilename (
|
|||||||
qse_awk_val_t* tmp;
|
qse_awk_val_t* tmp;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (rtx->awk->opt.trait & QSE_AWK_NEXTOFILE)
|
if (rtx->awk->opt.trait & QSE_AWK_EXTRAKWS)
|
||||||
{
|
{
|
||||||
if (len == 0) tmp = qse_awk_val_zls;
|
if (len == 0) tmp = qse_awk_val_zls;
|
||||||
else
|
else
|
||||||
@ -2319,8 +2324,7 @@ static int run_return (qse_awk_rtx_t* run, qse_awk_nde_return_t* nde)
|
|||||||
/* cannot return a map */
|
/* cannot return a map */
|
||||||
qse_awk_rtx_refupval (run, val);
|
qse_awk_rtx_refupval (run, val);
|
||||||
qse_awk_rtx_refdownval (run, val);
|
qse_awk_rtx_refdownval (run, val);
|
||||||
|
SETERR_LOC (run, QSE_AWK_EMAPPH, &nde->loc);
|
||||||
SETERR_LOC (run, QSE_AWK_EMAPNA, &nde->loc);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2590,7 +2594,7 @@ static int run_delete_named (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int run_delete_nonnamed (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var)
|
static int run_delete_unnamed (qse_awk_rtx_t* rtx, qse_awk_nde_var_t* var)
|
||||||
{
|
{
|
||||||
qse_awk_val_t* val;
|
qse_awk_val_t* val;
|
||||||
|
|
||||||
@ -2693,7 +2697,7 @@ static int run_delete (qse_awk_rtx_t* rtx, qse_awk_nde_delete_t* nde)
|
|||||||
case QSE_AWK_NDE_GBLIDX:
|
case QSE_AWK_NDE_GBLIDX:
|
||||||
case QSE_AWK_NDE_LCLIDX:
|
case QSE_AWK_NDE_LCLIDX:
|
||||||
case QSE_AWK_NDE_ARGIDX:
|
case QSE_AWK_NDE_ARGIDX:
|
||||||
return run_delete_nonnamed (rtx, var);
|
return run_delete_unnamed (rtx, var);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
QSE_ASSERTX (
|
QSE_ASSERTX (
|
||||||
@ -3321,6 +3325,7 @@ static qse_awk_val_t* eval_assignment (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
|||||||
qse_awk_val_t* val2, * tmp;
|
qse_awk_val_t* val2, * tmp;
|
||||||
static binop_func_t binop_func[] =
|
static binop_func_t binop_func[] =
|
||||||
{
|
{
|
||||||
|
/* this table must match qse_awk_assop_type_t in run.h */
|
||||||
QSE_NULL, /* QSE_AWK_ASSOP_NONE */
|
QSE_NULL, /* QSE_AWK_ASSOP_NONE */
|
||||||
eval_binop_plus,
|
eval_binop_plus,
|
||||||
eval_binop_minus,
|
eval_binop_minus,
|
||||||
@ -3455,13 +3460,12 @@ static qse_awk_val_t* do_assignment_scalar (
|
|||||||
|
|
||||||
pair = qse_htb_search (
|
pair = qse_htb_search (
|
||||||
run->named, var->id.name.ptr, var->id.name.len);
|
run->named, var->id.name.ptr, var->id.name.len);
|
||||||
if (pair != QSE_NULL &&
|
if (pair && ((qse_awk_val_t*)QSE_HTB_VPTR(pair))->type == QSE_AWK_VAL_MAP)
|
||||||
((qse_awk_val_t*)QSE_HTB_VPTR(pair))->type == QSE_AWK_VAL_MAP)
|
|
||||||
{
|
{
|
||||||
/* once a variable becomes a map,
|
/* once a variable becomes a map,
|
||||||
* it cannot be changed to a scalar variable */
|
* it cannot be changed to a scalar variable */
|
||||||
SETERR_ARGX_LOC (
|
SETERR_ARGX_LOC (
|
||||||
run, QSE_AWK_EMAPTOSCALAR,
|
run, QSE_AWK_EMAPNA,
|
||||||
xstr_to_cstr(&var->id.name), &var->loc);
|
xstr_to_cstr(&var->id.name), &var->loc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -3495,7 +3499,7 @@ static qse_awk_val_t* do_assignment_scalar (
|
|||||||
/* once the variable becomes a map,
|
/* once the variable becomes a map,
|
||||||
* it cannot be changed to a scalar variable */
|
* it cannot be changed to a scalar variable */
|
||||||
SETERR_ARGX_LOC (
|
SETERR_ARGX_LOC (
|
||||||
run, QSE_AWK_EMAPTOSCALAR,
|
run, QSE_AWK_EMAPNA,
|
||||||
xstr_to_cstr(&var->id.name), &var->loc);
|
xstr_to_cstr(&var->id.name), &var->loc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -3514,7 +3518,7 @@ static qse_awk_val_t* do_assignment_scalar (
|
|||||||
/* once the variable becomes a map,
|
/* once the variable becomes a map,
|
||||||
* it cannot be changed to a scalar variable */
|
* it cannot be changed to a scalar variable */
|
||||||
SETERR_ARGX_LOC (
|
SETERR_ARGX_LOC (
|
||||||
run, QSE_AWK_EMAPTOSCALAR,
|
run, QSE_AWK_EMAPNA,
|
||||||
xstr_to_cstr(&var->id.name), &var->loc);
|
xstr_to_cstr(&var->id.name), &var->loc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -3718,6 +3722,8 @@ static qse_awk_val_t* eval_binary (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
|
|||||||
eval_binop_bxor,
|
eval_binop_bxor,
|
||||||
eval_binop_band,
|
eval_binop_band,
|
||||||
|
|
||||||
|
eval_binop_teq,
|
||||||
|
eval_binop_tne,
|
||||||
eval_binop_eq,
|
eval_binop_eq,
|
||||||
eval_binop_ne,
|
eval_binop_ne,
|
||||||
eval_binop_gt,
|
eval_binop_gt,
|
||||||
@ -4338,28 +4344,67 @@ static int __cmp_val (
|
|||||||
return func[left->type*4+right->type] (rtx, left, right);
|
return func[left->type*4+right->type] (rtx, left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_val_t* eval_binop_eq (
|
static int teq_val (qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
|
||||||
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
|
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (left == right)
|
if (left == right) n = 1;
|
||||||
|
else if (left->type != right->type) n = 0;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* array comparison is not allowed but this special check
|
switch (left->type)
|
||||||
allows comparsion of an array with itself. let's not
|
{
|
||||||
care about this loophole. */
|
case QSE_AWK_VAL_NIL:
|
||||||
return qse_awk_val_one;
|
n = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QSE_AWK_VAL_INT:
|
||||||
|
n = ((qse_awk_val_int_t*)left)->val ==
|
||||||
|
((qse_awk_val_int_t*)right)->val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QSE_AWK_VAL_FLT:
|
||||||
|
n = ((qse_awk_val_flt_t*)left)->val ==
|
||||||
|
((qse_awk_val_flt_t*)right)->val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QSE_AWK_VAL_STR:
|
||||||
|
n = qse_strxncmp (
|
||||||
|
((qse_awk_val_str_t*)left)->val.ptr,
|
||||||
|
((qse_awk_val_str_t*)left)->val.len,
|
||||||
|
((qse_awk_val_str_t*)right)->val.ptr,
|
||||||
|
((qse_awk_val_str_t*)right)->val.len) == 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* map-x and map-y are always different regardless of
|
||||||
|
* their contents. however, if they are pointing to the
|
||||||
|
* same map value, it won't reach here but will be
|
||||||
|
* handled by the first check in this function */
|
||||||
|
n = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
return n;
|
||||||
if (left->type != right->type &&
|
|
||||||
(left->type == QSE_AWK_VAL_MAP || right->type == QSE_AWK_VAL_MAP))
|
|
||||||
{
|
|
||||||
return qse_awk_val_zero;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
n = __cmp_val (rtx, left, right);
|
static qse_awk_val_t* eval_binop_teq (
|
||||||
|
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
|
||||||
|
{
|
||||||
|
return teq_val (rtx, left, right)? qse_awk_val_one: qse_awk_val_zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
static qse_awk_val_t* eval_binop_tne (
|
||||||
|
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
|
||||||
|
{
|
||||||
|
return teq_val (rtx, left, right)? qse_awk_val_zero: qse_awk_val_one;
|
||||||
|
}
|
||||||
|
|
||||||
|
static qse_awk_val_t* eval_binop_eq (
|
||||||
|
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
|
||||||
|
{
|
||||||
|
int n = __cmp_val (rtx, left, right);
|
||||||
if (n == CMP_ERROR) return QSE_NULL;
|
if (n == CMP_ERROR) return QSE_NULL;
|
||||||
return (n == 0)? qse_awk_val_one: qse_awk_val_zero;
|
return (n == 0)? qse_awk_val_one: qse_awk_val_zero;
|
||||||
}
|
}
|
||||||
@ -4367,25 +4412,7 @@ static qse_awk_val_t* eval_binop_eq (
|
|||||||
static qse_awk_val_t* eval_binop_ne (
|
static qse_awk_val_t* eval_binop_ne (
|
||||||
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
|
qse_awk_rtx_t* rtx, qse_awk_val_t* left, qse_awk_val_t* right)
|
||||||
{
|
{
|
||||||
int n;
|
int n = __cmp_val (rtx, left, right);
|
||||||
|
|
||||||
if (left == right)
|
|
||||||
{
|
|
||||||
/* array comparison is not allowed but this special check
|
|
||||||
allows comparsion of an array with itself. let's not
|
|
||||||
care about this loophole. */
|
|
||||||
return qse_awk_val_zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (left->type != right->type &&
|
|
||||||
(left->type == QSE_AWK_VAL_MAP || right->type == QSE_AWK_VAL_MAP))
|
|
||||||
{
|
|
||||||
return qse_awk_val_one;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
n = __cmp_val (rtx, left, right);
|
|
||||||
if (n == CMP_ERROR) return QSE_NULL;
|
if (n == CMP_ERROR) return QSE_NULL;
|
||||||
return (n != 0)? qse_awk_val_one: qse_awk_val_zero;
|
return (n != 0)? qse_awk_val_one: qse_awk_val_zero;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,12 @@
|
|||||||
enum qse_awk_assop_type_t
|
enum qse_awk_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 with binop_func of eval_assignment in run.c */
|
* synchronize it wit:
|
||||||
|
* - binop_func in eval_assignment of run.c
|
||||||
|
* - assop in assing_to_opcode of parse.c
|
||||||
|
* - TOK_XXX_ASSN in tok_t in parse.c
|
||||||
|
* - assop_str in tree.c
|
||||||
|
*/
|
||||||
QSE_AWK_ASSOP_NONE,
|
QSE_AWK_ASSOP_NONE,
|
||||||
QSE_AWK_ASSOP_PLUS, /* += */
|
QSE_AWK_ASSOP_PLUS, /* += */
|
||||||
QSE_AWK_ASSOP_MINUS, /* -= */
|
QSE_AWK_ASSOP_MINUS, /* -= */
|
||||||
@ -37,7 +42,7 @@ enum qse_awk_assop_type_t
|
|||||||
QSE_AWK_ASSOP_RS, /* >>= */
|
QSE_AWK_ASSOP_RS, /* >>= */
|
||||||
QSE_AWK_ASSOP_LS, /* <<= */
|
QSE_AWK_ASSOP_LS, /* <<= */
|
||||||
QSE_AWK_ASSOP_BAND, /* &= */
|
QSE_AWK_ASSOP_BAND, /* &= */
|
||||||
QSE_AWK_ASSOP_BXOR, /* ^= */
|
QSE_AWK_ASSOP_BXOR, /* ^^= */
|
||||||
QSE_AWK_ASSOP_BOR /* |= */
|
QSE_AWK_ASSOP_BOR /* |= */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,6 +58,8 @@ enum qse_awk_binop_type_t
|
|||||||
QSE_AWK_BINOP_BXOR,
|
QSE_AWK_BINOP_BXOR,
|
||||||
QSE_AWK_BINOP_BAND,
|
QSE_AWK_BINOP_BAND,
|
||||||
|
|
||||||
|
QSE_AWK_BINOP_TEQ,
|
||||||
|
QSE_AWK_BINOP_TNE,
|
||||||
QSE_AWK_BINOP_EQ,
|
QSE_AWK_BINOP_EQ,
|
||||||
QSE_AWK_BINOP_NE,
|
QSE_AWK_BINOP_NE,
|
||||||
QSE_AWK_BINOP_GT,
|
QSE_AWK_BINOP_GT,
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
static const qse_char_t* assop_str[] =
|
static const qse_char_t* assop_str[] =
|
||||||
{
|
{
|
||||||
|
/* this table must match qse_awk_assop_type_t in run.h */
|
||||||
QSE_T("="),
|
QSE_T("="),
|
||||||
QSE_T("+="),
|
QSE_T("+="),
|
||||||
QSE_T("-="),
|
QSE_T("-="),
|
||||||
@ -30,11 +31,12 @@ static const qse_char_t* assop_str[] =
|
|||||||
QSE_T("/="),
|
QSE_T("/="),
|
||||||
QSE_T("\\="),
|
QSE_T("\\="),
|
||||||
QSE_T("%="),
|
QSE_T("%="),
|
||||||
QSE_T("**="),
|
QSE_T("**="), /* exponentation, also ^= */
|
||||||
|
QSE_T("%%="),
|
||||||
QSE_T(">>="),
|
QSE_T(">>="),
|
||||||
QSE_T("<<="),
|
QSE_T("<<="),
|
||||||
QSE_T("&="),
|
QSE_T("&="),
|
||||||
QSE_T("^="),
|
QSE_T("^^="),
|
||||||
QSE_T("|=")
|
QSE_T("|=")
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -45,9 +47,11 @@ static const qse_char_t* binop_str[][2] =
|
|||||||
{ QSE_T("in"), QSE_T("in") },
|
{ QSE_T("in"), QSE_T("in") },
|
||||||
|
|
||||||
{ QSE_T("|"), QSE_T("|") },
|
{ QSE_T("|"), QSE_T("|") },
|
||||||
{ QSE_T("^"), QSE_T("^") },
|
{ QSE_T("^^"), QSE_T("^^") },
|
||||||
{ QSE_T("&"), QSE_T("&") },
|
{ QSE_T("&"), QSE_T("&") },
|
||||||
|
|
||||||
|
{ QSE_T("==="), QSE_T("===") },
|
||||||
|
{ QSE_T("!=="), QSE_T("!==") },
|
||||||
{ QSE_T("=="), QSE_T("==") },
|
{ QSE_T("=="), QSE_T("==") },
|
||||||
{ QSE_T("!="), QSE_T("!=") },
|
{ QSE_T("!="), QSE_T("!=") },
|
||||||
{ QSE_T(">"), QSE_T(">") },
|
{ QSE_T(">"), QSE_T(">") },
|
||||||
@ -64,9 +68,9 @@ static const qse_char_t* binop_str[][2] =
|
|||||||
{ QSE_T("/"), QSE_T("/") },
|
{ QSE_T("/"), QSE_T("/") },
|
||||||
{ QSE_T("\\"), QSE_T("\\") },
|
{ QSE_T("\\"), QSE_T("\\") },
|
||||||
{ QSE_T("%"), QSE_T("%") },
|
{ QSE_T("%"), QSE_T("%") },
|
||||||
{ QSE_T("**"), QSE_T("**") },
|
{ QSE_T("**"), QSE_T("**") }, /* exponentation, also ^ */
|
||||||
|
|
||||||
{ QSE_T(" "), QSE_T(".") },
|
{ QSE_T(" "), QSE_T("%%") }, /* take note of this entry */
|
||||||
{ QSE_T("~"), QSE_T("~") },
|
{ QSE_T("~"), QSE_T("~") },
|
||||||
{ QSE_T("!~"), QSE_T("!~") }
|
{ QSE_T("!~"), QSE_T("!~") }
|
||||||
};
|
};
|
||||||
@ -76,7 +80,7 @@ static const qse_char_t* unrop_str[] =
|
|||||||
QSE_T("+"),
|
QSE_T("+"),
|
||||||
QSE_T("-"),
|
QSE_T("-"),
|
||||||
QSE_T("!"),
|
QSE_T("!"),
|
||||||
QSE_T("~")
|
QSE_T("~~")
|
||||||
};
|
};
|
||||||
|
|
||||||
static const qse_char_t* incop_str[] =
|
static const qse_char_t* incop_str[] =
|
||||||
|
@ -106,7 +106,7 @@ static void free_uctx_node (qse_awk_rtx_t* rtx, uctx_list_t* list, uctx_node_t*
|
|||||||
|
|
||||||
list->map.tab[node->id] = QSE_NULL;
|
list->map.tab[node->id] = QSE_NULL;
|
||||||
|
|
||||||
uci_free_context (node->ctx);
|
if (node->ctx) uci_free_context (node->ctx);
|
||||||
|
|
||||||
if (list->map.high == node->id + 1)
|
if (list->map.high == node->id + 1)
|
||||||
{
|
{
|
||||||
@ -118,6 +118,7 @@ static void free_uctx_node (qse_awk_rtx_t* rtx, uctx_list_t* list, uctx_node_t*
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* otherwise, chain the node to the free list */
|
/* otherwise, chain the node to the free list */
|
||||||
|
node->ctx = QSE_NULL;
|
||||||
node->next = list->free;
|
node->next = list->free;
|
||||||
list->free = node;
|
list->free = node;
|
||||||
}
|
}
|
||||||
@ -135,7 +136,7 @@ static void free_uctx_node (qse_awk_rtx_t* rtx, uctx_list_t* list, uctx_node_t*
|
|||||||
{
|
{
|
||||||
curnode = list->free;
|
curnode = list->free;
|
||||||
list->free = list->free->next;
|
list->free = list->free->next;
|
||||||
uci_free_context (curnode->ctx);
|
QSE_ASSERT (curnode->ctx == QSE_NULL);
|
||||||
QSE_MMGR_FREE (mmgr, curnode);
|
QSE_MMGR_FREE (mmgr, curnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,11 +174,11 @@ PROGS="
|
|||||||
lang-045.awk!!!--newline=on -d-
|
lang-045.awk!!!--newline=on -d-
|
||||||
lang-046.awk!lang-046.dat2!!--newline=on -d- -vdatadir=@abs_srcdir@ -vdatafile=lang-046.dat1
|
lang-046.awk!lang-046.dat2!!--newline=on -d- -vdatadir=@abs_srcdir@ -vdatafile=lang-046.dat1
|
||||||
lang-047.awk!!!--newline=on --tolerant=on -d-
|
lang-047.awk!!!--newline=on --tolerant=on -d-
|
||||||
lang-048.awk!!!--newline=on --extraops=on -d-
|
lang-048.awk!!!--newline=on -d-
|
||||||
lang-049.awk!!!--newline=on -d-
|
lang-049.awk!!!--newline=on -d-
|
||||||
|
|
||||||
columnate.awk!passwd.dat!!--newline=on -F:
|
columnate.awk!passwd.dat!!--newline=on -F:
|
||||||
levenshtein-utests.awk!!!--newline=on --include=on
|
levenshtein-utests.awk!!!--newline=on --extrakws=on
|
||||||
rcalc.awk!!!--newline=on -v target=89000
|
rcalc.awk!!!--newline=on -v target=89000
|
||||||
quicksort.awk!quicksort.dat!!
|
quicksort.awk!quicksort.dat!!
|
||||||
quicksort2.awk!quicksort2.dat!!-vQSEAWK=\"${QSEAWK}\" -vSCRIPT_PATH=\"${SCRIPT_DIR}\"
|
quicksort2.awk!quicksort2.dat!!-vQSEAWK=\"${QSEAWK}\" -vSCRIPT_PATH=\"${SCRIPT_DIR}\"
|
||||||
|
@ -53,7 +53,6 @@ int main ()
|
|||||||
/* don't allow BEGIN, END, pattern-action blocks */
|
/* don't allow BEGIN, END, pattern-action blocks */
|
||||||
opt &= ~QSE_AWK_PABLOCK;
|
opt &= ~QSE_AWK_PABLOCK;
|
||||||
/* enable ** */
|
/* enable ** */
|
||||||
opt |= QSE_AWK_EXTRAOPS;
|
|
||||||
qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt);
|
qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt);
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ static int awk_main (int argc, qse_char_t* argv[])
|
|||||||
awk.setTrait (
|
awk.setTrait (
|
||||||
awk.getTrait() |
|
awk.getTrait() |
|
||||||
QSE_AWK_MAPTOVAR |
|
QSE_AWK_MAPTOVAR |
|
||||||
QSE_AWK_RESET);
|
QSE_AWK_EXTRAKWS);
|
||||||
|
|
||||||
if (ret >= 0) ret = run_awk (awk);
|
if (ret >= 0) ret = run_awk (awk);
|
||||||
if (ret <= -1)
|
if (ret <= -1)
|
||||||
|
@ -356,8 +356,7 @@ static int awk_main_2 (MyAwk& awk, int argc, qse_char_t* argv[])
|
|||||||
cmdline_t cmdline;
|
cmdline_t cmdline;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
awk.setTrait (awk.getTrait() | QSE_AWK_INCLUDE |
|
awk.setTrait (awk.getTrait() | QSE_AWK_EXTRAKWS | QSE_AWK_MAPTOVAR | QSE_AWK_RWPIPE);
|
||||||
QSE_AWK_MAPTOVAR | QSE_AWK_RWPIPE | QSE_AWK_EXTRAOPS);
|
|
||||||
|
|
||||||
// ARGV[0]
|
// ARGV[0]
|
||||||
if (awk.addArgument (QSE_T("awk08")) <= -1)
|
if (awk.addArgument (QSE_T("awk08")) <= -1)
|
||||||
|
@ -64,7 +64,7 @@ int main ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
qse_awk_getopt (awk, QSE_AWK_TRAIT, &opt);
|
qse_awk_getopt (awk, QSE_AWK_TRAIT, &opt);
|
||||||
opt |= QSE_AWK_NEXTOFILE;
|
opt |= QSE_AWK_EXTRAKWS;
|
||||||
qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt);
|
qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt);
|
||||||
|
|
||||||
psin.type = QSE_AWK_PARSESTD_STR;
|
psin.type = QSE_AWK_PARSESTD_STR;
|
||||||
|
@ -59,8 +59,6 @@ int main ()
|
|||||||
opt &= ~QSE_AWK_PABLOCK;
|
opt &= ~QSE_AWK_PABLOCK;
|
||||||
/* can assign a map to a variable */
|
/* can assign a map to a variable */
|
||||||
opt |= QSE_AWK_MAPTOVAR;
|
opt |= QSE_AWK_MAPTOVAR;
|
||||||
/* enable ** */
|
|
||||||
opt |= QSE_AWK_EXTRAOPS;
|
|
||||||
qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt);
|
qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt);
|
||||||
|
|
||||||
psin.type = QSE_AWK_PARSESTD_STR;
|
psin.type = QSE_AWK_PARSESTD_STR;
|
||||||
|
Loading…
Reference in New Issue
Block a user