fixed many bugs in cli mode reader
This commit is contained in:
parent
0634bf26b3
commit
256472b2ea
@ -350,7 +350,6 @@ static HCL_INLINE int read_input (hcl_t* hcl, hcl_ioinarg_t* arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int read_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg)
|
static int read_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg)
|
||||||
{
|
{
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
@ -1888,7 +1887,11 @@ count++;
|
|||||||
else if (hcl->errnum == HCL_ESYNERR)
|
else if (hcl->errnum == HCL_ESYNERR)
|
||||||
{
|
{
|
||||||
print_synerr (hcl);
|
print_synerr (hcl);
|
||||||
if (xtn->reader_istty && hcl_getsynerrnum(hcl) != HCL_SYNERR_EOF) continue;
|
if (xtn->reader_istty && hcl_getsynerrnum(hcl) != HCL_SYNERR_EOF)
|
||||||
|
{
|
||||||
|
/* TODO: drain remaining data in the reader including the actual inputstream and buffered data in hcl */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
147
lib/read.c
147
lib/read.c
@ -2189,10 +2189,58 @@ static int read_object (hcl_t* hcl)
|
|||||||
|
|
||||||
static int read_object_in_cli_mode (hcl_t* hcl)
|
static int read_object_in_cli_mode (hcl_t* hcl)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
( ls -laF
|
||||||
|
pwd ) -> ( (ls -laF) (pwd) )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ls -laF (pwd) -> (ls -laF ( (pwd ) )
|
||||||
|
|
||||||
|
|
||||||
|
ls -laF -> (ls -laF)
|
||||||
|
|
||||||
|
|
||||||
|
( -> (
|
||||||
|
ls -laF -> (ls -laF)
|
||||||
|
pwd -> (pwd)
|
||||||
|
) -> )
|
||||||
|
|
||||||
|
|
||||||
|
( (
|
||||||
|
pwd ( (pwd (
|
||||||
|
ls -laF (ls -laF)
|
||||||
|
) ) )
|
||||||
|
) )
|
||||||
|
|
||||||
|
* SOME key test cases
|
||||||
|
------------
|
||||||
|
(pwd)
|
||||||
|
------------
|
||||||
|
(pwd
|
||||||
|
)
|
||||||
|
------------
|
||||||
|
(
|
||||||
|
pwd)
|
||||||
|
------------
|
||||||
|
(
|
||||||
|
pwd
|
||||||
|
)
|
||||||
|
------------
|
||||||
|
pwd (pwd)
|
||||||
|
------------
|
||||||
|
pwd (pwd
|
||||||
|
)
|
||||||
|
*
|
||||||
|
|
||||||
|
---------------
|
||||||
|
pwd) -------> error
|
||||||
|
|
||||||
|
*/
|
||||||
int level = 0, array_level = 0, flagv = 0;
|
int level = 0, array_level = 0, flagv = 0;
|
||||||
hcl_oop_t obj;
|
hcl_oop_t obj;
|
||||||
int start_virtual_list = 1;
|
int start_virtual_list = 1;
|
||||||
int prev_eoled = 0;
|
hcl_iotok_type_t prev_token_type = HCL_IOTOK_EOF;
|
||||||
|
|
||||||
if (TOKEN_TYPE(hcl) == HCL_IOTOK_LPAREN) start_virtual_list = 0;
|
if (TOKEN_TYPE(hcl) == HCL_IOTOK_LPAREN) start_virtual_list = 0;
|
||||||
|
|
||||||
@ -2207,7 +2255,7 @@ HCL_DEBUG0 (hcl, "STARTING vritual list...\n");
|
|||||||
|
|
||||||
/* push some data to simulate recursion into
|
/* push some data to simulate recursion into
|
||||||
* a list literal or an array literal */
|
* a list literal or an array literal */
|
||||||
if (enter_list(hcl, flagv) == HCL_NULL) return -1;
|
if (enter_list(hcl, flagv) == HCL_NULL) goto oops;
|
||||||
level++;
|
level++;
|
||||||
//if (LIST_FLAG_GET_CONCODE(flagv) == HCL_CONCODE_ARRAY) array_level++;
|
//if (LIST_FLAG_GET_CONCODE(flagv) == HCL_CONCODE_ARRAY) array_level++;
|
||||||
|
|
||||||
@ -2218,11 +2266,11 @@ HCL_DEBUG0 (hcl, "STARTING vritual list...\n");
|
|||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
hcl_setsynerr (hcl, HCL_SYNERR_ILTOK, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
hcl_setsynerr (hcl, HCL_SYNERR_ILTOK, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
||||||
return -1;
|
goto oops;
|
||||||
|
|
||||||
case HCL_IOTOK_EOF:
|
case HCL_IOTOK_EOF:
|
||||||
hcl_setsynerr (hcl, HCL_SYNERR_EOF, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
hcl_setsynerr (hcl, HCL_SYNERR_EOF, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
||||||
return -1;
|
goto oops;
|
||||||
|
|
||||||
case HCL_IOTOK_INCLUDE:
|
case HCL_IOTOK_INCLUDE:
|
||||||
/* TODO: should i limit where #include can be specified?
|
/* TODO: should i limit where #include can be specified?
|
||||||
@ -2231,58 +2279,47 @@ HCL_DEBUG0 (hcl, "STARTING vritual list...\n");
|
|||||||
if (TOKEN_TYPE(hcl) != HCL_IOTOK_STRLIT)
|
if (TOKEN_TYPE(hcl) != HCL_IOTOK_STRLIT)
|
||||||
{
|
{
|
||||||
hcl_setsynerr (hcl, HCL_SYNERR_STRING, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
hcl_setsynerr (hcl, HCL_SYNERR_STRING, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
||||||
return -1;
|
goto oops;
|
||||||
}
|
}
|
||||||
if (begin_include(hcl) <= -1) return -1;
|
if (begin_include(hcl) <= -1) goto oops;
|
||||||
goto redo;
|
goto redo;
|
||||||
|
|
||||||
case HCL_IOTOK_LPAREN: /* () */
|
case HCL_IOTOK_LPAREN: /* () */
|
||||||
{
|
|
||||||
/*int first = 1;
|
|
||||||
|
|
||||||
redo_lparen:*/
|
|
||||||
flagv = 0;
|
flagv = 0;
|
||||||
LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_XLIST);
|
LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_XLIST);
|
||||||
SET_TOKEN_TYPE (hcl, HCL_IOTOK_EOL); /* to have get_token() to ignore immediate <EOL> after ( */
|
|
||||||
/*start_list:*/
|
/*start_list:*/
|
||||||
if (level >= HCL_TYPE_MAX(int))
|
if (level >= HCL_TYPE_MAX(int))
|
||||||
{
|
{
|
||||||
/* the nesting level has become too deep */
|
/* the nesting level has become too deep */
|
||||||
hcl_setsynerr (hcl, HCL_SYNERR_NESTING, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
hcl_setsynerr (hcl, HCL_SYNERR_NESTING, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
||||||
return -1;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* push some data to simulate recursion into
|
/* push some data to simulate recursion into
|
||||||
* a list literal or an array literal */
|
* a list literal or an array literal */
|
||||||
HCL_DEBUG0 (hcl, "111 STARTING list...\n");
|
HCL_DEBUG0 (hcl, "111 STARTING list...\n");
|
||||||
if (enter_list(hcl, flagv) == HCL_NULL) return -1;
|
if (enter_list(hcl, flagv) == HCL_NULL) goto oops;
|
||||||
level++;
|
level++;
|
||||||
//if (LIST_FLAG_GET_CONCODE(flagv) == HCL_CONCODE_ARRAY) array_level++;
|
//if (LIST_FLAG_GET_CONCODE(flagv) == HCL_CONCODE_ARRAY) array_level++;
|
||||||
|
|
||||||
/*
|
|
||||||
if (first)
|
|
||||||
{
|
|
||||||
first = 0;
|
|
||||||
goto redo_lparen;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/* read the next token */
|
/* read the next token */
|
||||||
GET_TOKEN (hcl);
|
|
||||||
start_virtual_list = 1;
|
start_virtual_list = 1;
|
||||||
goto redo;
|
goto next_token;
|
||||||
}
|
|
||||||
|
|
||||||
case HCL_IOTOK_EOL:
|
case HCL_IOTOK_EOL:
|
||||||
{
|
{
|
||||||
int oldflagv;
|
int oldflagv;
|
||||||
//int concode;
|
//int concode;
|
||||||
|
|
||||||
|
if (prev_token_type == HCL_IOTOK_EOL || prev_token_type == HCL_IOTOK_LPAREN) goto next_token;
|
||||||
|
|
||||||
if (level <= 0)
|
if (level <= 0)
|
||||||
{
|
{
|
||||||
hcl_setsynerr (hcl, HCL_SYNERR_UNBALPBB, TOKEN_LOC(hcl), HCL_NULL);
|
hcl_setsynerr (hcl, HCL_SYNERR_UNBALPBB, TOKEN_LOC(hcl), HCL_NULL);
|
||||||
return -1;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HCL_DEBUG1 (hcl, "11 LEAVING LIST level->%d\n", (int)level);
|
||||||
//concode = LIST_FLAG_GET_CONCODE(flagv);
|
//concode = LIST_FLAG_GET_CONCODE(flagv);
|
||||||
obj = leave_list(hcl, &flagv, &oldflagv);
|
obj = leave_list(hcl, &flagv, &oldflagv);
|
||||||
|
|
||||||
@ -2298,43 +2335,67 @@ HCL_DEBUG0 (hcl, "111 STARTING list...\n");
|
|||||||
int oldflagv;
|
int oldflagv;
|
||||||
//int concode;
|
//int concode;
|
||||||
|
|
||||||
if (prev_eoled)
|
if (prev_token_type == HCL_IOTOK_LPAREN)
|
||||||
{
|
{
|
||||||
/* exit #1 */
|
hcl_setsynerr (hcl, HCL_SYNERR_EMPTYXLIST, TOKEN_LOC(hcl), HCL_NULL); /* TODO: change error code?? */
|
||||||
if (level <= 0)
|
goto oops;
|
||||||
{
|
|
||||||
hcl_setsynerr (hcl, HCL_SYNERR_UNBALPBB, TOKEN_LOC(hcl), HCL_NULL);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
else if (prev_token_type == HCL_IOTOK_EOL)
|
||||||
|
{
|
||||||
|
if (level <= 1) goto unbalpbb;
|
||||||
|
|
||||||
//concode = LIST_FLAG_GET_CONCODE(flagv);
|
|
||||||
obj = leave_list(hcl, &flagv, &oldflagv);
|
obj = leave_list(hcl, &flagv, &oldflagv);
|
||||||
level--;
|
level--;
|
||||||
//if (LIST_FLAG_GET_CONCODE(oldflagv) == HCL_CONCODE_ARRAY) array_level--;
|
//if (LIST_FLAG_GET_CONCODE(oldflagv) == HCL_CONCODE_ARRAY) array_level--;
|
||||||
|
|
||||||
if (!obj) return -1;
|
if (!obj) goto oops;
|
||||||
HCL_ASSERT (hcl, level > 0);
|
HCL_ASSERT (hcl, level > 0);
|
||||||
|
HCL_ASSERT (hcl, obj == hcl->_nil);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* exit #1 */
|
||||||
|
if (level <= 1) goto unbalpbb;
|
||||||
|
|
||||||
|
//concode = LIST_FLAG_GET_CONCODE(flagv);
|
||||||
|
HCL_DEBUG0 (hcl, "22 LEAVING LIST\n");
|
||||||
|
obj = leave_list(hcl, &flagv, &oldflagv);
|
||||||
|
level--;
|
||||||
|
//if (LIST_FLAG_GET_CONCODE(oldflagv) == HCL_CONCODE_ARRAY) array_level--;
|
||||||
|
|
||||||
|
if (!obj) goto oops;
|
||||||
|
HCL_ASSERT (hcl, level > 0);
|
||||||
|
|
||||||
|
if (obj != hcl->_nil)
|
||||||
|
{
|
||||||
|
//HCL_ASSERT (hcl, obj == hcl->_nil);
|
||||||
HCL_DEBUG1 (hcl, "00 ADDING TO LIST %O\n", obj);
|
HCL_DEBUG1 (hcl, "00 ADDING TO LIST %O\n", obj);
|
||||||
if (chain_to_list(hcl, obj) == HCL_NULL) return -1;
|
if (chain_to_list(hcl, obj) == HCL_NULL) goto oops;
|
||||||
clear_comma_colon_flag (hcl);
|
clear_comma_colon_flag (hcl);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* exit #2 */
|
/* exit #2 */
|
||||||
if (level <= 0)
|
if (level <= 0)
|
||||||
{
|
{
|
||||||
unbalpbb:
|
unbalpbb:
|
||||||
hcl_setsynerr (hcl, HCL_SYNERR_UNBALPBB, TOKEN_LOC(hcl), HCL_NULL);
|
hcl_setsynerr (hcl, HCL_SYNERR_UNBALPBB, TOKEN_LOC(hcl), HCL_NULL);
|
||||||
return -1;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HCL_DEBUG1 (hcl, "33 LEAVING LIST level %d\n", level);
|
||||||
//concode = LIST_FLAG_GET_CONCODE(flagv);
|
//concode = LIST_FLAG_GET_CONCODE(flagv);
|
||||||
obj = leave_list(hcl, &flagv, &oldflagv);
|
obj = leave_list(hcl, &flagv, &oldflagv); /* this object is added to the chain after break */
|
||||||
level--;
|
level--;
|
||||||
|
|
||||||
level--; /* double exit??? */
|
|
||||||
//if (LIST_FLAG_GET_CONCODE(oldflagv) == HCL_CONCODE_ARRAY) array_level--;
|
//if (LIST_FLAG_GET_CONCODE(oldflagv) == HCL_CONCODE_ARRAY) array_level--;
|
||||||
|
|
||||||
SET_TOKEN_TYPE (hcl, HCL_IOTOK_EOL); /* to have get_token() to ignore immediate <EOL> after ( */
|
if (!obj) goto oops;
|
||||||
|
if (obj == hcl->_nil)
|
||||||
|
{
|
||||||
|
/* consider an input like ls (pwd <EOL>) where EOL is '\n' */
|
||||||
|
goto next_token;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2349,7 +2410,7 @@ HCL_DEBUG0 (hcl, "111 STARTING list...\n");
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!obj) return -1;
|
if (!obj) goto oops;
|
||||||
|
|
||||||
/* check if we are at the top level */
|
/* check if we are at the top level */
|
||||||
if (level <= 0) break; /* yes */
|
if (level <= 0) break; /* yes */
|
||||||
@ -2357,17 +2418,21 @@ HCL_DEBUG0 (hcl, "111 STARTING list...\n");
|
|||||||
/* if not, append the element read into the current list.
|
/* if not, append the element read into the current list.
|
||||||
* if we are not at the top level, we must be in a list */
|
* if we are not at the top level, we must be in a list */
|
||||||
HCL_DEBUG1 (hcl, "11 ADDING TO LIST %O\n", obj);
|
HCL_DEBUG1 (hcl, "11 ADDING TO LIST %O\n", obj);
|
||||||
if (chain_to_list(hcl, obj) == HCL_NULL) return -1;
|
if (chain_to_list(hcl, obj) == HCL_NULL) goto oops;
|
||||||
clear_comma_colon_flag (hcl);
|
clear_comma_colon_flag (hcl);
|
||||||
|
|
||||||
prev_eoled = (TOKEN_TYPE(hcl) == HCL_IOTOK_EOL);
|
next_token:
|
||||||
|
prev_token_type = TOKEN_TYPE(hcl);
|
||||||
/* read the next token */
|
/* read the next token */
|
||||||
GET_TOKEN (hcl);
|
GET_TOKEN (hcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
hcl->c->r.e = obj;
|
hcl->c->r.e = obj;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
SET_TOKEN_TYPE (hcl, HCL_IOTOK_EOL); /* to make get_token() not return an immediate EOL after error */
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HCL_INLINE int __read (hcl_t* hcl)
|
static HCL_INLINE int __read (hcl_t* hcl)
|
||||||
|
Loading…
Reference in New Issue
Block a user