Compare commits

...

2 Commits

Author SHA1 Message Date
hyung-hwan 7b9cab4b47 added the octal number notation with the prefix 0o
continuous-integration/drone/push Build is passing
did some code refactor
2026-02-03 12:47:09 +09:00
hyung-hwan 62f1c3695f fixed the keyword check data and function 2026-01-27 15:24:34 +09:00
8 changed files with 157 additions and 54 deletions
Vendored
+3 -3
View File
@@ -617,7 +617,7 @@ PACKAGE_TARNAME='hawk'
PACKAGE_VERSION='1.0.0'
PACKAGE_STRING='hawk 1.0.0'
PACKAGE_BUGREPORT='Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)'
PACKAGE_URL='https://code.miflux.net/hyung-hwan/hawk'
PACKAGE_URL='https://code.miflux.com/hyung-hwan/hawk'
# Factoring default headers for most tests.
ac_includes_default="\
@@ -1617,7 +1617,7 @@ Use these variables to override the choices made by 'configure' or to help
it to find libraries and programs with nonstandard names/locations.
Report bugs to <Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)>.
hawk home page: <https://code.miflux.net/hyung-hwan/hawk>.
hawk home page: <https://code.miflux.com/hyung-hwan/hawk>.
_ACEOF
ac_status=$?
fi
@@ -30097,7 +30097,7 @@ Configuration commands:
$config_commands
Report bugs to <Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)>.
hawk home page: <https://code.miflux.net/hyung-hwan/hawk>."
hawk home page: <https://code.miflux.com/hyung-hwan/hawk>."
_ACEOF
ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
+1 -1
View File
@@ -1,6 +1,6 @@
dnl AC_PREREQ([2.71])
AC_INIT([hawk],[1.0.0],[Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)],[],[https://code.miflux.net/hyung-hwan/hawk])
AC_INIT([hawk],[1.0.0],[Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)],[],[https://code.miflux.com/hyung-hwan/hawk])
AC_CONFIG_HEADERS([lib/hawk-cfg.h])
AC_CONFIG_AUX_DIR([ac])
+1 -1
View File
@@ -466,7 +466,7 @@ enum hawk_nde_type_t
HAWK_NDE_CND,
HAWK_NDE_FNCALL_FNC,
HAWK_NDE_FNCALL_FUN,
HAWK_NDE_FNCALL_VAR,
HAWK_NDE_FNCALL_EXPR,
HAWK_NDE_CHAR,
HAWK_NDE_BCHR,
HAWK_NDE_INT,
+93 -38
View File
@@ -258,7 +258,7 @@ static hawk_nde_t* parse_hashidx (hawk_t* hawk, const hawk_oocs_t* name, const h
static hawk_nde_t* parse_dotidx (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc);
#define FNCALL_FLAG_NOARG (1 << 0) /* no argument */
#define FNCALL_FLAG_VAR (1 << 1)
#define FNCALL_FLAG_EXPR (1 << 1)
#define FNCALL_FLAG_MAP (1 << 2)
static hawk_nde_t* parse_fncall (hawk_t* hawk, const hawk_oocs_t* name, hawk_fnc_t* fnc, const hawk_loc_t* xloc, int flags, int closer_token);
@@ -290,7 +290,11 @@ struct kwent_t
static kwent_t kwtab[] =
{
/* keep this table in sync with the kw_t enums in "parse-prv.h".
* also keep it sorted by the first field for binary search */
* also keep it sorted by the first field for binary search.
* there are extra keywords that are alias to the main entries
* in classify_ident. e.g. "func". such aliases are not placed
* here because of direct access by index in hawk_getkwname() */
{ { HAWK_T("@abort"), 6 }, TOK_XABORT, 0 },
{ { HAWK_T("@argc"), 5 }, TOK_XARGC, 0 },
{ { HAWK_T("@argv"), 5 }, TOK_XARGV, 0 },
@@ -315,7 +319,6 @@ static kwent_t kwtab[] =
{ { HAWK_T("else"), 4 }, TOK_ELSE, 0 },
{ { HAWK_T("exit"), 4 }, TOK_EXIT, 0 },
{ { HAWK_T("for"), 3 }, TOK_FOR, 0 },
{ { HAWK_T("func"), 4 }, TOK_FUNCTION, 0 },
{ { HAWK_T("function"), 8 }, TOK_FUNCTION, 0 },
{ { HAWK_T("getbline"), 8 }, TOK_GETBLINE, HAWK_RIO },
{ { HAWK_T("getline"), 7 }, TOK_GETLINE, HAWK_RIO },
@@ -1102,16 +1105,18 @@ static int parse_progunit (hawk_t* hawk)
((trait = HAWK_PEDANTIC) && hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("pedantic"), 0) == 0) ||
((trait = HAWK_RWPIPE) && hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("rwpipe"), 0) == 0))
{
/* @pragma implicit on
/* @pragma implicit on (default)
* @pragma implicit off
* @pragma multilinestr on
* @pragma multilinestr off
* @pragma multilinestr off (defualt)
* @pragma pedantic on
* @pragma pedantic off
* @pragma rwpipe on
* @pragma pedantic off (default)
* @pragma rwpipe on (default)
* @pragma rwpipe off
*
* The initial values of these pragmas are set in hawk_clear()
* The pragma items defined in this block is compile-time only unlike
* the items defined in the next block.
*/
hawk_oocs_t value;
@@ -1155,8 +1160,15 @@ static int parse_progunit (hawk_t* hawk)
*
* The initial values of these pragmas are set in hawk_clear()
*
* Take note the global STRIPRECSPC is available for context based change.
* STRIPRECSPC takes precedence over this pragma.
* The effect of the pragma items listed here are modified at runtime
* with corresponding globals values. The interpreter uses these
* macros to detemine the actual effect as defined in hawk-prv.h.
* - HAWK_RTX_IS_NUMSTRDETECT_ON(rtx)
* - HAWK_RTX_IS_PIPECLOEXEC_ON(rtx)
* - HAWK_RTX_IS_STRIPRECSPC_ON(rtx)
* - HAWK_RTX_IS_STRIPSTRSPC_ON(rtx)
* In general, the runtime global variable value takes precedence
* over the compile-time pragma specifier value.
*/
int is_on;
hawk_oocs_t value;
@@ -4010,7 +4022,9 @@ static hawk_nde_t* parse_statement_nb (hawk_t* hawk, const hawk_loc_t* xloc)
else
{
if (nde) hawk_clrpt(hawk, nde);
hawk_seterrnum(hawk, &hawk->ptok.loc, HAWK_ESTMEND);
hawk_seterrbfmt(hawk, &hawk->tok.loc, HAWK_ESTMEND,
"statement not ending with a semicolon and got '%.*js'",
HAWK_OOECS_LEN(hawk->tok.name), HAWK_OOECS_PTR(hawk->tok.name));
return HAWK_NULL;
}
@@ -5562,8 +5576,8 @@ oops:
static hawk_nde_t* _parse_primary_array_or_map (hawk_t* hawk, const hawk_loc_t* xloc, const hawk_oocs_t* full, const hawk_oocs_t segs[], int nsegs, int closer_token)
{
/* treat it as if it's hawk::array() */
/* called for @[ or @{ handling. the caller of this function passes "hawk::array" or
* "hawk:map" via "full'. */
hawk_mod_t* mod;
hawk_mod_sym_t sym;
hawk_fnc_t fnc;
@@ -5587,6 +5601,7 @@ static hawk_nde_t* _parse_primary_array_or_map (hawk_t* hawk, const hawk_loc_t*
fnc.spec = sym.u.fnc_;
fnc.mod = mod;
/* convert it to a function call */
return parse_fncall(hawk, full, &fnc, xloc, (closer_token == TOK_RBRACE? FNCALL_FLAG_MAP: 0), closer_token);
}
@@ -6026,10 +6041,10 @@ static hawk_nde_t* parse_primary_nopipe (hawk_t* hawk, const hawk_loc_t* xloc)
case TOK_IDENT:
return parse_primary_ident(hawk, xloc);
case TOK_ATBRACK:
case TOK_ATBRACK: /* @[ */
return parse_primary_array(hawk, xloc);
case TOK_ATBRACE:
case TOK_ATBRACE: /* @{ */
return parse_primary_map(hawk, xloc);
case TOK_CHAR:
@@ -6262,7 +6277,7 @@ static hawk_nde_t* parse_variable (hawk_t* hawk, const hawk_loc_t* xloc, hawk_nd
#if defined(HAWK_ENABLE_FUN_AS_VALUE)
if (!is_fcv) return (hawk_nde_t*)nde;
return parse_fncall(hawk, (const hawk_oocs_t*)nde, HAWK_NULL, xloc, FNCALL_FLAG_VAR, TOK_RPAREN);
return parse_fncall(hawk, (const hawk_oocs_t*)nde, HAWK_NULL, xloc, FNCALL_FLAG_EXPR, TOK_RPAREN);
#else
return (hawk_nde_t*)nde;
#endif
@@ -6302,7 +6317,7 @@ static int dup_ident_and_get_next (hawk_t* hawk, const hawk_loc_t* xloc, hawk_oo
* TOK_XGLOBAL to TOK_XRESET are excuded from the check for that reason. */
if (!MATCH(hawk, TOK_IDENT) && !(MATCH_RANGE(hawk, TOK_BEGIN, TOK_GETLINE)))
{
hawk_seterrfmt(hawk, &hawk->tok.loc, HAWK_EIDENT, FMT_EIDENT, HAWK_OOECS_LEN(hawk->tok.name), HAWK_OOECS_PTR(hawk->tok.name));
hawk_seterrfmt(hawk, &hawk->tok.loc, HAWK_EIDENT, FMT_EIDENT, HAWK_OOECS_LEN(hawk->tok.name), HAWK_OOECS_PTR(hawk->tok.name));
goto oops;
}
@@ -6464,7 +6479,7 @@ static hawk_nde_t* parse_primary_ident_noseg (hawk_t* hawk, const hawk_loc_t* xl
*
* it is a function call so long as it's followed
* by a left parenthesis if concatenation by blanks
* is not allowed.
* (HAWK_BLANKCONCAT) is not allowed.
*/
int is_fncall_var = 0;
@@ -6524,7 +6539,7 @@ static hawk_nde_t* parse_primary_ident_noseg (hawk_t* hawk, const hawk_loc_t* xl
#if defined(HAWK_ENABLE_FUN_AS_VALUE)
if (is_fncall_var)
nde = parse_fncall(hawk, (const hawk_oocs_t*)nde, HAWK_NULL, xloc, FNCALL_FLAG_VAR, TOK_RPAREN);
nde = parse_fncall(hawk, (const hawk_oocs_t*)nde, HAWK_NULL, xloc, FNCALL_FLAG_EXPR, TOK_RPAREN);
#endif
}
}
@@ -6771,7 +6786,7 @@ oops:
return -1;
}
static hawk_nde_t* finalize_hashidx (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc, hawk_nde_t* idx)
static hawk_nde_t* make_hashidx_access_node (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc, hawk_nde_t* idx)
{
hawk_nde_var_t* nde;
hawk_oow_t idxa;
@@ -6779,7 +6794,6 @@ static hawk_nde_t* finalize_hashidx (hawk_t* hawk, const hawk_oocs_t* name, cons
nde = (hawk_nde_var_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*nde));
if (HAWK_UNLIKELY(!nde))
{
hawk_clrpt(hawk, idx);
ADJERR_LOC(hawk, xloc);
return HAWK_NULL;
}
@@ -6882,17 +6896,19 @@ static hawk_nde_t* finalize_hashidx (hawk_t* hawk, const hawk_oocs_t* name, cons
return (hawk_nde_t*)nde;
}
/* -- ERROR down here -- */
/* undefined variable */
hawk_seterrfmt(hawk, xloc, HAWK_EUNDEF, FMT_EUNDEF, name->len, name->ptr);
exit_func:
hawk_clrpt(hawk, idx);
/* didn't take over 'name' and 'idx'. just free the node structure
* using hawk_freemem(). no call to hawk_clrpt() */
hawk_freemem(hawk, nde);
return HAWK_NULL;
}
static hawk_nde_t* parse_hashidx_common (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc)
static hawk_nde_t* parse_idx_chain (hawk_t* hawk, const hawk_loc_t* xloc)
{
nde_chain_t idx = { HAWK_NULL, HAWK_NULL };
@@ -6903,34 +6919,47 @@ static hawk_nde_t* parse_hashidx_common (hawk_t* hawk, const hawk_oocs_t* name,
#if defined(HAWK_ENABLE_GC)
while (MATCH(hawk, TOK_LBRACK) || MATCH(hawk, TOK_PERIOD))
{
hawk_nde_t* tmp;
hawk_nde_t* splitter;
/* additional index - a[10][20] or a.b.c ...
* use the NULL node as a splitter */
tmp = (hawk_nde_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*tmp));
if (HAWK_UNLIKELY(!tmp))
splitter = (hawk_nde_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*splitter));
if (HAWK_UNLIKELY(!splitter))
{
ADJERR_LOC(hawk, xloc);
goto oops;
}
tmp->type = HAWK_NDE_NULL;
splitter->type = HAWK_NDE_NULL;
HAWK_ASSERT(idx.tail != HAWK_NULL);
idx.tail->next = tmp;
idx.tail = tmp;
idx.tail->next = splitter;
idx.tail = splitter;
if (parse_single_idx(hawk, &idx) <= -1) goto oops;
}
#endif
return finalize_hashidx(hawk, name, xloc, idx.head);
return idx.head;
oops:
if (idx.head) hawk_clrpt(hawk, idx.head);
return HAWK_NULL;
}
static hawk_nde_t* parse_hashidx_common (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc)
{
hawk_nde_t* idx;
hawk_nde_t* h;
idx = parse_idx_chain(hawk, xloc);
if (HAWK_UNLIKELY(!idx)) return HAWK_NULL;
h = make_hashidx_access_node(hawk, name, xloc, idx);
if (HAWK_UNLIKELY(!h)) hawk_clrpt(hawk, idx);
return h;
}
static hawk_nde_t* parse_hashidx (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc)
{
HAWK_ASSERT(MATCH(hawk, TOK_LBRACK));
@@ -6979,19 +7008,29 @@ static hawk_nde_t* parse_fncall (hawk_t* hawk, const hawk_oocs_t* name, hawk_fnc
if (MATCH(hawk, closer_token))
{
if ((flags & FNCALL_FLAG_MAP) && (nargs & 1))
{
/* a value part is missing after colon inside @{} */
goto colon_expected;
}
if (get_token(hawk) <= -1) goto oops;
break;
}
if ((flags & FNCALL_FLAG_MAP) && (nargs & 1))
{
/* inside @{},
* - it expects a colon after each key
* - after value, a comma is expected */
if (!MATCH(hawk, TOK_COLON))
{
colon_expected:
hawk_seterrfmt(hawk, &hawk->tok.loc, HAWK_ECOLON, FMT_ECOLON, HAWK_OOECS_LEN(hawk->tok.name), HAWK_OOECS_PTR(hawk->tok.name));
goto oops;
}
}
else {
else
{
if (!MATCH(hawk, TOK_COMMA))
{
hawk_seterrfmt(hawk, &hawk->tok.loc, HAWK_ECOMMA, FMT_ECOMMA, HAWK_OOECS_LEN(hawk->tok.name), HAWK_OOECS_PTR(hawk->tok.name));
@@ -7005,7 +7044,6 @@ static hawk_nde_t* parse_fncall (hawk_t* hawk, const hawk_oocs_t* name, hawk_fnc
}
while (MATCH(hawk,TOK_NEWLINE));
}
}
make_node:
@@ -7016,11 +7054,13 @@ make_node:
goto oops;
}
if (flags & FNCALL_FLAG_VAR)
if (flags & FNCALL_FLAG_EXPR)
{
call->type = HAWK_NDE_FNCALL_VAR;
/* special case. "name" is not of the const hawk_oocs_t* type.
* it points to the node directly */
call->type = HAWK_NDE_FNCALL_EXPR;
call->loc = *xloc;
call->u.var.var = (hawk_nde_var_t*)name; /* name is a pointer to a variable node */
call->u.expr.callable = (hawk_nde_t*)name; /* name is a pointer to a callable expression node */
call->args = head;
call->nargs = nargs;
}
@@ -7068,8 +7108,8 @@ make_node:
return (hawk_nde_t*)call;
oops:
if (call) hawk_freemem(hawk, call);
if (head) hawk_clrpt(hawk, head);
if (call) hawk_freemem(hawk, call); /* destroy the call node itself */
if (head) hawk_clrpt(hawk, head); /* clear the argument list separately from the call node */
return HAWK_NULL;
}
@@ -7099,6 +7139,13 @@ static int get_number (hawk_t* hawk, hawk_tok_t* tok)
return 0;
}
else if (c == 'o' || c == 'O')
{
/* octal number */
ADD_TOKEN_CHAR(hawk, tok, c);
GET_CHAR_TO(hawk, c);
goto octal;
}
else if (c == 'b' || c == 'B')
{
/* binary number */
@@ -7114,6 +7161,7 @@ static int get_number (hawk_t* hawk, hawk_tok_t* tok)
else if (c != '.')
{
/* octal number */
octal:
while (c >= '0' && c <= '7')
{
ADD_TOKEN_CHAR(hawk, tok, c);
@@ -8187,7 +8235,14 @@ static int classify_ident (hawk_t* hawk, const hawk_oocs_t* name)
/* declaring left, right, mid to be the int type is ok
* because we know kwtab is small enough. */
int left = 0, right = HAWK_COUNTOF(kwtab) - 1, mid;
int left, right, mid;
/* extra alias keywords which are not part of the main kwtab */
if (hawk_comp_oochars_bcstr(name->ptr, name->len, "func", 0) == 0) return TOK_FUNCTION;
/* search in the main kwtab */
left = 0;
right = HAWK_COUNTOF(kwtab) - 1;
while (left <= right)
{
+36 -4
View File
@@ -7408,13 +7408,35 @@ static HAWK_INLINE hawk_val_t* eval_fncall_fun (hawk_rtx_t* rtx, hawk_nde_t* nde
return hawk_rtx_evalcall(rtx, call, fun, push_arg_from_nde, HAWK_NULL/*fun->argspec*/, HAWK_NULL, HAWK_NULL);
}
static HAWK_INLINE int nde_is_var (const hawk_nde_t* nde)
{
switch (nde->type)
{
case HAWK_NDE_NAMED:
case HAWK_NDE_GBL:
case HAWK_NDE_LCL:
case HAWK_NDE_ARG:
case HAWK_NDE_NAMEDIDX:
case HAWK_NDE_GBLIDX:
case HAWK_NDE_LCLIDX:
case HAWK_NDE_ARGIDX:
return 1;
default:
return 0;
}
}
static hawk_val_t* eval_fncall_var (hawk_rtx_t* rtx, hawk_nde_t* nde)
{
hawk_nde_fncall_t* call = (hawk_nde_fncall_t*)nde;
hawk_nde_t* callee;
hawk_val_t* fv, * rv;
hawk_fun_t* fun;
fv = eval_expression(rtx, (hawk_nde_t*)call->u.var.var);
callee = call->u.expr.callable;
fv = eval_expression(rtx, callee);
if (HAWK_UNLIKELY(!fv)) return HAWK_NULL;
hawk_rtx_refupval(rtx, fv);
@@ -7422,14 +7444,24 @@ static hawk_val_t* eval_fncall_var (hawk_rtx_t* rtx, hawk_nde_t* nde)
if (HAWK_UNLIKELY(!fun))
{
if (hawk_rtx_geterrnum(rtx) == HAWK_EINVAL)
hawk_rtx_seterrfmt(rtx, &nde->loc, HAWK_ENOTFUN, HAWK_T("non-function value in %.*js"), call->u.var.var->id.name.len, call->u.var.var->id.name.ptr);
{
if (nde_is_var(callee))
{
hawk_nde_var_t* v = (hawk_nde_var_t*)callee;
hawk_rtx_seterrfmt(rtx, &nde->loc, HAWK_ENOTFUN,
HAWK_T("non-function value in '%.*js'"),
v->id.name.len, v->id.name.ptr);
}
else
{
hawk_rtx_seterrnum(rtx, &nde->loc, HAWK_ENOTFUN);
}
}
ADJERR_LOC(rtx, &nde->loc);
rv = HAWK_NULL;
}
else if (call->nargs > fun->nargs && !fun->variadic)
{
/* TODO: is this correct? what if i want to
* allow arbitarary numbers of arguments? */
hawk_rtx_seterrfmt(rtx, &nde->loc, HAWK_EARGTM, HAWK_T("too many arguments to '%.*js'"), fun->name.len, fun->name.ptr);
rv = HAWK_NULL;
}
+3 -3
View File
@@ -235,7 +235,7 @@ struct hawk_nde_var_t
hawk_uint8_t is_const;
};
/* HAWK_NDE_FNCALL_FNC, HAWK_NDE_FNCALL_FUN, HAWK_NDE_FNCALL_VAR */
/* HAWK_NDE_FNCALL_FNC, HAWK_NDE_FNCALL_FUN, HAWK_NDE_FNCALL_EXPR */
struct hawk_nde_fncall_t
{
HAWK_NDE_HDR;
@@ -257,8 +257,8 @@ struct hawk_nde_fncall_t
struct
{
hawk_nde_var_t* var;
} var;
hawk_nde_t* callable;
} expr;
} u;
hawk_nde_t* args;
hawk_oow_t nargs;
+4 -4
View File
@@ -788,10 +788,10 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde)
break;
}
case HAWK_NDE_FNCALL_VAR:
case HAWK_NDE_FNCALL_EXPR:
{
hawk_nde_fncall_t* px = (hawk_nde_fncall_t*)nde;
PRINT_EXPR(hawk, (hawk_nde_t*)px->u.var.var);
PRINT_EXPR(hawk, (hawk_nde_t*)px->u.expr.callable);
PUT_SRCSTR(hawk, HAWK_T("("));
PRINT_EXPR_LIST(hawk, px->args);
PUT_SRCSTR(hawk, HAWK_T(")"));
@@ -1624,10 +1624,10 @@ void hawk_clrpt (hawk_t* hawk, hawk_nde_t* tree)
break;
}
case HAWK_NDE_FNCALL_VAR:
case HAWK_NDE_FNCALL_EXPR:
{
hawk_nde_fncall_t* px = (hawk_nde_fncall_t*)p;
hawk_clrpt(hawk, (hawk_nde_t*)px->u.var.var);
hawk_clrpt(hawk, (hawk_nde_t*)px->u.expr.callable);
hawk_clrpt(hawk, px->args);
hawk_freemem(hawk, p);
break;
+16
View File
@@ -2726,6 +2726,10 @@ hawk_int_t hawk_uchars_to_int (const hawk_uch_t* str, hawk_oow_t len, int option
{
p++; base = 16;
}
else if (*p == 'o' || *p == 'O')
{
p++; base = 8;
}
else if (*p == 'b' || *p == 'B')
{
p++; base = 2;
@@ -2738,6 +2742,10 @@ hawk_int_t hawk_uchars_to_int (const hawk_uch_t* str, hawk_oow_t len, int option
{
if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2;
}
else if (rem >= 2 && base == 8)
{
if (*p == '0' && (*(p + 1) == 'o' || *(p + 1) == 'O')) p += 2;
}
else if (rem >= 2 && base == 2)
{
if (*p == '0' && (*(p + 1) == 'b' || *(p + 1) == 'B')) p += 2;
@@ -2947,6 +2955,10 @@ hawk_uint_t hawk_uchars_to_uint (const hawk_uch_t* str, hawk_oow_t len, int opti
{
p++; base = 16;
}
else if (*p == 'o' || *p == 'O')
{
p++; base = 8;
}
else if (*p == 'b' || *p == 'B')
{
p++; base = 2;
@@ -2959,6 +2971,10 @@ hawk_uint_t hawk_uchars_to_uint (const hawk_uch_t* str, hawk_oow_t len, int opti
{
if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2;
}
else if (rem >= 2 && base == 8)
{
if (*p == '0' && (*(p + 1) == 'o' || *(p + 1) == 'O')) p += 2;
}
else if (rem >= 2 && base == 2)
{
if (*p == '0' && (*(p + 1) == 'b' || *(p + 1) == 'B')) p += 2;