Added QSE_AWK_BLANKCONCAT
fixed getline parsing to accept $XXX
This commit is contained in:
parent
c6a0a99e84
commit
4e92c0ef1c
@ -388,6 +388,7 @@ struct opttab_t
|
|||||||
{ 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("blankconcat"), QSE_AWK_BLANKCONCAT, QSE_T("enable concatenation by blanks") },
|
||||||
{ 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") },
|
||||||
@ -527,6 +528,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
{ 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(":blankconcat"), 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') },
|
||||||
|
@ -964,6 +964,8 @@ enum qse_awk_trait_t
|
|||||||
*/
|
*/
|
||||||
QSE_AWK_STRIPSTRSPC = (1 << 7),
|
QSE_AWK_STRIPSTRSPC = (1 << 7),
|
||||||
|
|
||||||
|
QSE_AWK_BLANKCONCAT = (1 << 8),
|
||||||
|
|
||||||
/** CR + LF by default */
|
/** CR + LF by default */
|
||||||
QSE_AWK_CRLF = (1 << 10),
|
QSE_AWK_CRLF = (1 << 10),
|
||||||
|
|
||||||
@ -1016,9 +1018,10 @@ enum qse_awk_trait_t
|
|||||||
* makes #qse_awk_t to behave compatibly with classical AWK
|
* makes #qse_awk_t to behave compatibly with classical AWK
|
||||||
* implementations
|
* implementations
|
||||||
*/
|
*/
|
||||||
QSE_AWK_CLASSIC = QSE_AWK_IMPLICIT | QSE_AWK_RIO |
|
QSE_AWK_CLASSIC =
|
||||||
QSE_AWK_NEWLINE | QSE_AWK_PABLOCK |
|
QSE_AWK_IMPLICIT | QSE_AWK_RIO |
|
||||||
QSE_AWK_STRIPSTRSPC | QSE_AWK_STRICTNAMING
|
QSE_AWK_NEWLINE | QSE_AWK_BLANKCONCAT | QSE_AWK_PABLOCK |
|
||||||
|
QSE_AWK_STRIPSTRSPC | QSE_AWK_STRICTNAMING
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
@ -3533,13 +3533,13 @@ static qse_awk_nde_t* parse_binary (
|
|||||||
{
|
{
|
||||||
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;
|
||||||
|
qse_awk_loc_t rloc;
|
||||||
|
|
||||||
left = next_level_func (awk, xloc);
|
left = next_level_func (awk, xloc);
|
||||||
if (left == QSE_NULL) goto oops;
|
if (left == QSE_NULL) goto oops;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
qse_awk_loc_t rloc;
|
|
||||||
const binmap_t* p = binmap;
|
const binmap_t* p = binmap;
|
||||||
int matched = 0;
|
int matched = 0;
|
||||||
int opcode, fold;
|
int opcode, fold;
|
||||||
@ -3626,8 +3626,7 @@ static qse_awk_nde_t* parse_binary (
|
|||||||
|
|
||||||
tmp = new_exp_bin_node (awk, xloc, opcode, left, right);
|
tmp = new_exp_bin_node (awk, xloc, opcode, left, right);
|
||||||
if (tmp == QSE_NULL) goto oops;
|
if (tmp == QSE_NULL) goto oops;
|
||||||
left = tmp;
|
left = tmp; right = QSE_NULL;
|
||||||
right = QSE_NULL;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3807,6 +3806,7 @@ static qse_awk_nde_t* parse_concat (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;
|
||||||
|
qse_awk_loc_t rloc;
|
||||||
|
|
||||||
left = parse_additive (awk, xloc);
|
left = parse_additive (awk, xloc);
|
||||||
if (left == QSE_NULL) goto oops;
|
if (left == QSE_NULL) goto oops;
|
||||||
@ -3814,25 +3814,26 @@ static qse_awk_nde_t* parse_concat (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
qse_awk_nde_t* tmp;
|
qse_awk_nde_t* tmp;
|
||||||
qse_awk_loc_t rloc;
|
|
||||||
|
|
||||||
if (MATCH(awk,TOK_CONCAT))
|
if (MATCH(awk,TOK_CONCAT))
|
||||||
{
|
{
|
||||||
if (get_token(awk) <= -1) goto oops;
|
if (get_token(awk) <= -1) goto oops;
|
||||||
}
|
}
|
||||||
else if (MATCH(awk,TOK_LPAREN) ||
|
else if (awk->opt.trait & QSE_AWK_BLANKCONCAT)
|
||||||
MATCH(awk,TOK_DOLLAR) ||
|
|
||||||
MATCH(awk,TOK_PLUS) ||
|
|
||||||
MATCH(awk,TOK_MINUS) ||
|
|
||||||
MATCH(awk,TOK_PLUSPLUS) ||
|
|
||||||
MATCH(awk,TOK_MINUSMINUS) ||
|
|
||||||
MATCH(awk,TOK_LNOT) ||
|
|
||||||
((awk->opt.trait & QSE_AWK_TOLERANT) &&
|
|
||||||
(awk->tok.type == TOK_PRINT || awk->tok.type == TOK_PRINTF)) ||
|
|
||||||
awk->tok.type >= TOK_GETLINE)
|
|
||||||
{
|
{
|
||||||
/* TODO: is the check above sufficient? */
|
if (MATCH(awk,TOK_LPAREN) || MATCH(awk,TOK_DOLLAR) ||
|
||||||
if (!(awk->opt.trait & QSE_AWK_IMPLICIT)) break;
|
/* unary operators */
|
||||||
|
MATCH(awk,TOK_PLUS) || MATCH(awk,TOK_MINUS) ||
|
||||||
|
MATCH(awk,TOK_LNOT) || MATCH(awk,TOK_BNOT) ||
|
||||||
|
/* increment operators */
|
||||||
|
MATCH(awk,TOK_PLUSPLUS) || MATCH(awk,TOK_MINUSMINUS) ||
|
||||||
|
((awk->opt.trait & QSE_AWK_TOLERANT) &&
|
||||||
|
(awk->tok.type == TOK_PRINT || awk->tok.type == TOK_PRINTF)) ||
|
||||||
|
awk->tok.type >= TOK_GETLINE)
|
||||||
|
{
|
||||||
|
/* proceed to handle concatenation expression */
|
||||||
|
}
|
||||||
|
else break;
|
||||||
}
|
}
|
||||||
else break;
|
else break;
|
||||||
|
|
||||||
@ -3840,11 +3841,9 @@ static qse_awk_nde_t* parse_concat (qse_awk_t* awk, const qse_awk_loc_t* xloc)
|
|||||||
right = parse_additive (awk, &rloc);
|
right = parse_additive (awk, &rloc);
|
||||||
if (right == QSE_NULL) goto oops;
|
if (right == QSE_NULL) goto oops;
|
||||||
|
|
||||||
tmp = new_exp_bin_node (
|
tmp = new_exp_bin_node (awk, xloc, QSE_AWK_BINOP_CONCAT, left, right);
|
||||||
awk, xloc, QSE_AWK_BINOP_CONCAT, left, right);
|
if (tmp == QSE_NULL) goto oops;
|
||||||
if (left == QSE_NULL) goto oops;
|
left = tmp; right = QSE_NULL;
|
||||||
left = tmp;
|
|
||||||
right = QSE_NULL;
|
|
||||||
}
|
}
|
||||||
while (1);
|
while (1);
|
||||||
|
|
||||||
@ -4523,32 +4522,43 @@ static qse_awk_nde_t* parse_primary_nogetline (
|
|||||||
|
|
||||||
if (get_token(awk) <= -1) return QSE_NULL;
|
if (get_token(awk) <= -1) return QSE_NULL;
|
||||||
|
|
||||||
if (MATCH(awk,TOK_IDENT))
|
if (MATCH(awk,TOK_IDENT) || MATCH(awk,TOK_DOLLAR))
|
||||||
{
|
{
|
||||||
/* getline var */
|
/* getline var
|
||||||
|
* getline $XXX */
|
||||||
qse_awk_loc_t gloc = awk->tok.loc;
|
qse_awk_loc_t gloc = awk->tok.loc;
|
||||||
var = parse_primary (awk, &gloc);
|
var = parse_primary (awk, &gloc);
|
||||||
if (var == QSE_NULL) return QSE_NULL;
|
if (var == QSE_NULL) return QSE_NULL;
|
||||||
|
|
||||||
|
if (!is_var(var) && var->type != QSE_AWK_NDE_POS)
|
||||||
|
{
|
||||||
|
/* this is 'getline' followed by an expression probably.
|
||||||
|
* getline a()
|
||||||
|
* getline sys::WNOHANG
|
||||||
|
*/
|
||||||
|
SETERR_LOC (awk, QSE_AWK_EBADARG, &gloc);
|
||||||
|
qse_awk_clrpt (awk, var);
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MATCH(awk, TOK_LT))
|
if (MATCH(awk, TOK_LT))
|
||||||
{
|
{
|
||||||
|
qse_awk_loc_t ploc;
|
||||||
/* getline [var] < file */
|
/* getline [var] < file */
|
||||||
if (get_token(awk) <= -1)
|
if (get_token(awk) <= -1)
|
||||||
{
|
{
|
||||||
if (var != QSE_NULL) qse_awk_clrpt (awk, var);
|
if (var) qse_awk_clrpt (awk, var);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
ploc = awk->tok.loc;
|
||||||
qse_awk_loc_t ploc = awk->tok.loc;
|
/* TODO: is this correct? */
|
||||||
/* TODO: is this correct? */
|
/*in = parse_expr_dc (awk, &ploc);*/
|
||||||
/*in = parse_expr_dc (awk, &ploc);*/
|
in = parse_primary (awk, &ploc);
|
||||||
in = parse_primary (awk, &ploc);
|
|
||||||
}
|
|
||||||
if (in == QSE_NULL)
|
if (in == QSE_NULL)
|
||||||
{
|
{
|
||||||
if (var != QSE_NULL) qse_awk_clrpt (awk, var);
|
if (var) qse_awk_clrpt (awk, var);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4557,9 +4567,9 @@ static qse_awk_nde_t* parse_primary_nogetline (
|
|||||||
awk, QSE_SIZEOF(qse_awk_nde_getline_t));
|
awk, QSE_SIZEOF(qse_awk_nde_getline_t));
|
||||||
if (nde == QSE_NULL)
|
if (nde == QSE_NULL)
|
||||||
{
|
{
|
||||||
if (var != QSE_NULL) qse_awk_clrpt (awk, var);
|
|
||||||
if (in != QSE_NULL) qse_awk_clrpt (awk, in);
|
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
||||||
|
if (var) qse_awk_clrpt (awk, var);
|
||||||
|
if (in) qse_awk_clrpt (awk, in);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4602,12 +4612,11 @@ static qse_awk_nde_t* parse_primary_nogetline (
|
|||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_awk_nde_t* parse_primary (
|
static qse_awk_nde_t* parse_primary (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_nde_getline_t* nde;
|
qse_awk_nde_getline_t* nde;
|
||||||
qse_awk_nde_t* var;
|
qse_awk_nde_t* var = QSE_NULL;
|
||||||
|
|
||||||
left = parse_primary_nogetline (awk, xloc);
|
left = parse_primary_nogetline (awk, xloc);
|
||||||
|
|
||||||
@ -4621,46 +4630,40 @@ static qse_awk_nde_t* parse_primary (
|
|||||||
{
|
{
|
||||||
intype = QSE_AWK_IN_PIPE;
|
intype = QSE_AWK_IN_PIPE;
|
||||||
}
|
}
|
||||||
else if (MATCH(awk,TOK_LOR))
|
else if (MATCH(awk,TOK_LOR) &&
|
||||||
|
(awk->opt.trait & QSE_AWK_RWPIPE))
|
||||||
{
|
{
|
||||||
if (awk->opt.trait & QSE_AWK_RWPIPE)
|
intype = QSE_AWK_IN_RWPIPE;
|
||||||
intype = QSE_AWK_IN_RWPIPE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intype == -1) break;
|
if (intype == -1) break;
|
||||||
|
|
||||||
if (preget_token(awk) <= -1)
|
if (preget_token(awk) <= -1) goto oops;
|
||||||
{
|
|
||||||
qse_awk_clrpt (awk, left);
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (awk->ntok.type != TOK_GETLINE) break;
|
if (awk->ntok.type != TOK_GETLINE) break;
|
||||||
|
|
||||||
var = QSE_NULL;
|
/* consume ntok('getline') */
|
||||||
|
|
||||||
/* consume ntok */
|
|
||||||
get_token (awk);
|
get_token (awk);
|
||||||
|
|
||||||
/* get the next token */
|
/* get the next token */
|
||||||
if (get_token(awk) <= -1)
|
if (get_token(awk) <= -1) goto oops;
|
||||||
{
|
|
||||||
qse_awk_clrpt (awk, left);
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: is this correct? */
|
/* TODO: is this correct? */
|
||||||
if (MATCH(awk,TOK_IDENT))
|
if (MATCH(awk,TOK_IDENT) || MATCH(awk,TOK_DOLLAR))
|
||||||
{
|
{
|
||||||
/* command | getline var
|
/* command | getline var
|
||||||
* command || getline var */
|
* command || getline var */
|
||||||
qse_awk_loc_t gloc = awk->tok.loc;
|
qse_awk_loc_t gloc = awk->tok.loc;
|
||||||
var = parse_primary_ident (awk, &gloc);
|
var = parse_primary (awk, &gloc);
|
||||||
if (var == QSE_NULL)
|
if (var == QSE_NULL) goto oops;
|
||||||
|
|
||||||
|
if (!is_var(var) & var->type != QSE_AWK_NDE_POS)
|
||||||
{
|
{
|
||||||
qse_awk_clrpt (awk, left);
|
/* fucntion a() {}
|
||||||
return QSE_NULL;
|
* print ("ls -laF" | getline a()) */
|
||||||
|
SETERR_LOC (awk, QSE_AWK_EBADARG, &gloc);
|
||||||
|
goto oops;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4668,9 +4671,8 @@ static qse_awk_nde_t* parse_primary (
|
|||||||
awk, QSE_SIZEOF(qse_awk_nde_getline_t));
|
awk, QSE_SIZEOF(qse_awk_nde_getline_t));
|
||||||
if (nde == QSE_NULL)
|
if (nde == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_awk_clrpt (awk, left);
|
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
||||||
return QSE_NULL;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
nde->type = QSE_AWK_NDE_GETLINE;
|
nde->type = QSE_AWK_NDE_GETLINE;
|
||||||
@ -4681,10 +4683,16 @@ static qse_awk_nde_t* parse_primary (
|
|||||||
nde->in = left;
|
nde->in = left;
|
||||||
|
|
||||||
left = (qse_awk_nde_t*)nde;
|
left = (qse_awk_nde_t*)nde;
|
||||||
|
var = QSE_NULL;
|
||||||
}
|
}
|
||||||
while (1);
|
while (1);
|
||||||
|
|
||||||
return left;
|
return left;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
if (var) qse_awk_clrpt (awk, var);
|
||||||
|
qse_awk_clrpt (awk, left);
|
||||||
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FNTYPE_UNKNOWN 0
|
#define FNTYPE_UNKNOWN 0
|
||||||
|
@ -230,7 +230,7 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
|
|||||||
QSE_ASSERT (px->left->next == QSE_NULL);
|
QSE_ASSERT (px->left->next == QSE_NULL);
|
||||||
|
|
||||||
PUT_SRCSTR (awk, QSE_T(" "));
|
PUT_SRCSTR (awk, QSE_T(" "));
|
||||||
PUT_SRCSTR (awk, binop_str[px->opcode][(awk->opt.trait & QSE_AWK_IMPLICIT)? 0: 1]);
|
PUT_SRCSTR (awk, binop_str[px->opcode][(awk->opt.trait & QSE_AWK_BLANKCONCAT)? 0: 1]);
|
||||||
PUT_SRCSTR (awk, QSE_T(" "));
|
PUT_SRCSTR (awk, QSE_T(" "));
|
||||||
|
|
||||||
if (px->right->type == QSE_AWK_NDE_ASS)
|
if (px->right->type == QSE_AWK_NDE_ASS)
|
||||||
|
Loading…
Reference in New Issue
Block a user