added @pragma multilinestr on/off

This commit is contained in:
hyung-hwan 2020-03-11 07:13:02 +00:00
parent 059ba422ce
commit 689735eed8
5 changed files with 85 additions and 14 deletions

View File

@ -133,7 +133,7 @@ The typical execution begins with the BEGIN block, goes through pattern-action b
} }
### Value ### Values
- unitialized value - unitialized value
- integer - integer
@ -142,10 +142,22 @@ The typical execution begins with the BEGIN block, goes through pattern-action b
- byte string - byte string
- array - array
### Pragmas
A program item of the file scope can be placed in any source files.
A pragma item of the global scope can appear only once thoughout the all source files.
| | Scope | Values | Description |
|---------------|--------|---------------|--------------------------------------------------------|
| implicit | file | on, off | allow undeclared variables |
| multilinestr | file | on, off | allow a multiline string literal without continuation |
| entry | global | function name | change the program entry point |
| striprecspc | global | on, off | |
| striprecspc | global | on, off | trim leading and trailing spaces when convering a string to a number |
### Module ### Module
### Incompatibility with AWK ### Incompatibility with AWK
#### Parameter passing #### Parameter passing

View File

@ -499,6 +499,7 @@ struct opttab_t
} opttab[] = } opttab[] =
{ {
{ "implicit", HAWK_IMPLICIT, "allow undeclared variables" }, { "implicit", HAWK_IMPLICIT, "allow undeclared variables" },
{ "multilinestr", HAWK_MULTILINESTR, "allow raw multiline string and regular expression literals" },
{ "nextofile", HAWK_NEXTOFILE, "enable nextofile & OFILENAME" }, { "nextofile", HAWK_NEXTOFILE, "enable nextofile & OFILENAME" },
{ "rio", HAWK_RIO, "enable builtin I/O including getline & print" }, { "rio", HAWK_RIO, "enable builtin I/O including getline & print" },
{ "rwpipe", HAWK_RWPIPE, "allow a dual-directional pipe" }, { "rwpipe", HAWK_RWPIPE, "allow a dual-directional pipe" },
@ -640,6 +641,7 @@ static int process_argv (int argc, hawk_bch_t* argv[], struct arg_t* arg)
static hawk_bcli_lng_t lng[] = static hawk_bcli_lng_t lng[] =
{ {
{ ":implicit", '\0' }, { ":implicit", '\0' },
{ ":multilinestr", '\0' },
{ ":nextofile", '\0' }, { ":nextofile", '\0' },
{ ":rio", '\0' }, { ":rio", '\0' },
{ ":rwpipe", '\0' }, { ":rwpipe", '\0' },

View File

@ -379,7 +379,7 @@ void hawk_clear (hawk_t* awk)
awk->parse.depth.loop = 0; awk->parse.depth.loop = 0;
awk->parse.depth.expr = 0; awk->parse.depth.expr = 0;
awk->parse.depth.incl = 0; awk->parse.depth.incl = 0;
awk->parse.pragma.trait = (awk->opt.trait & (HAWK_IMPLICIT | HAWK_STRIPRECSPC | HAWK_STRIPSTRSPC)); /* implicit on if you didn't mask it off in awk->opt.trait with hawk_setopt */ awk->parse.pragma.trait = (awk->opt.trait & (HAWK_IMPLICIT | HAWK_MULTILINESTR | HAWK_STRIPRECSPC | HAWK_STRIPSTRSPC)); /* implicit on if you didn't mask it off in awk->opt.trait with hawk_setopt */
awk->parse.pragma.rtx_stack_limit = 0; awk->parse.pragma.rtx_stack_limit = 0;
awk->parse.pragma.entry[0] = '\0'; awk->parse.pragma.entry[0] = '\0';

View File

@ -1151,8 +1151,11 @@ enum hawk_trait_t
/** allows undeclared variables */ /** allows undeclared variables */
HAWK_IMPLICIT = (1 << 0), HAWK_IMPLICIT = (1 << 0),
/** allows multiline string literals or regular expression literals */
HAWK_MULTILINESTR = (1 << 1),
/** enables nextofile and NEXTOFILE */ /** enables nextofile and NEXTOFILE */
HAWK_NEXTOFILE = (1 << 1), HAWK_NEXTOFILE = (1 << 2),
/** supports \b getline, \b print, \b printf, \b close, \b fflush, /** supports \b getline, \b print, \b printf, \b close, \b fflush,
* piping, and file rediction */ * piping, and file rediction */

View File

@ -872,7 +872,7 @@ static int begin_include (hawk_t* awk, int once)
arg->pragma_trait = awk->parse.pragma.trait; arg->pragma_trait = awk->parse.pragma.trait;
/* but don't change awk->parse.pragma.trait. it means the included file inherits /* but don't change awk->parse.pragma.trait. it means the included file inherits
* the existing progma values. * the existing progma values.
awk->parse.pragma.trait = (awk->opt.trait & (HAWK_IMPLICIT | HAWK_STRIPRECSPC | HAWK_STRIPSTRSPC)); awk->parse.pragma.trait = (awk->opt.trait & (HAWK_IMPLICIT | HAWK_MULTILINESTR | HAWK_STRIPRECSPC | HAWK_STRIPSTRSPC));
*/ */
/* i update the current pointer after opening is successful */ /* i update the current pointer after opening is successful */
@ -1039,6 +1039,35 @@ static int parse_progunit (hawk_t* awk)
goto error_ident_on_off_expected_for_implicit; goto error_ident_on_off_expected_for_implicit;
} }
} }
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("multilinestr")) == 0)
{
if (get_token(awk) <= -1) return -1;
if (!MATCH(awk, TOK_IDENT))
{
error_ident_on_off_expected_for_multilinestr:
hawk_seterrfmt (awk, &awk->ptok.loc, HAWK_EIDENT, HAWK_T("identifier 'on' or 'off' expected for 'multilinestr'"));
return -1;
}
name.len = HAWK_OOECS_LEN(awk->tok.name);
name.ptr = HAWK_OOECS_PTR(awk->tok.name);
if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("on")) == 0)
{
awk->parse.pragma.trait |= HAWK_MULTILINESTR;
}
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("off")) == 0)
{
awk->parse.pragma.trait &= ~HAWK_MULTILINESTR;
}
else
{
goto error_ident_on_off_expected_for_multilinestr;
}
}
/* ---------------------------------------------------------------------
* the pragmas up to this point affect the parser
* the following pragmas affect runtime
* --------------------------------------------------------------------- */
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("stack_limit")) == 0) else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("stack_limit")) == 0)
{ {
hawk_int_t sl; hawk_int_t sl;
@ -6131,22 +6160,47 @@ static int get_string (
} }
} }
if (escaped == 0 && c == end_char) if (escaped == 99)
{
escaped = 0;
if (c == '\n') continue; /* backslash \r \n */
}
if (escaped == 0)
{
if (c == end_char)
{ {
/* terminating quote */ /* terminating quote */
/*GET_CHAR_TO (awk, c);*/ /*GET_CHAR_TO (awk, c);*/
GET_CHAR (awk); GET_CHAR (awk);
break; break;
} }
else if (c == esc_char)
if (escaped == 0 && c == esc_char)
{ {
escaped = 1; escaped = 1;
continue; continue;
} }
else if (!(awk->parse.pragma.trait & HAWK_MULTILINESTR) && c == '\n' || c == '\r')
{
hawk_seterrnum (awk, &awk->tok.loc, HAWK_ESTRNC);
return -1;
}
}
if (escaped == 1) if (escaped == 1)
{ {
if (c == '\n')
{
/* line continuation - a backslash at the end of line */
escaped = 0;
continue;
}
else if (c == '\r')
{
escaped = 99;
continue;
}
if (c == HAWK_T('n')) c = HAWK_T('\n'); if (c == HAWK_T('n')) c = HAWK_T('\n');
else if (c == HAWK_T('r')) c = HAWK_T('\r'); else if (c == HAWK_T('r')) c = HAWK_T('\r');
else if (c == HAWK_T('t')) c = HAWK_T('\t'); else if (c == HAWK_T('t')) c = HAWK_T('\t');