fixed a minor problem of returning a long option string with a leading colon in qse_getopt().
enhanced cmd/awk/awk.c cleaned up code a little
This commit is contained in:
parent
e66a372119
commit
385e1acc26
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: awk.c 205 2009-06-20 12:47:34Z hyunghwan.chung $
|
* $Id: awk.c 206 2009-06-21 13:33:05Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
|
||||||
@ -62,6 +62,10 @@ struct arg_t
|
|||||||
qse_size_t icfl; /* the number of input console files */
|
qse_size_t icfl; /* the number of input console files */
|
||||||
qse_map_t* gvm; /* global variable map */
|
qse_map_t* gvm; /* global variable map */
|
||||||
qse_char_t* fs; /* field separator */
|
qse_char_t* fs; /* field separator */
|
||||||
|
qse_char_t* call; /* function to call */
|
||||||
|
|
||||||
|
int opton;
|
||||||
|
int optoff;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gvmv_t
|
struct gvmv_t
|
||||||
@ -184,12 +188,6 @@ static qse_map_walk_t print_awk_value (
|
|||||||
return QSE_MAP_WALK_FORWARD;
|
return QSE_MAP_WALK_FORWARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_run_statement (
|
|
||||||
qse_awk_rtx_t* run, qse_size_t line, void* data)
|
|
||||||
{
|
|
||||||
/*dprint (L"running %d\n", (int)line);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
static qse_map_walk_t set_global (
|
static qse_map_walk_t set_global (
|
||||||
qse_map_t* map, qse_map_pair_t* pair, void* arg)
|
qse_map_t* map, qse_map_pair_t* pair, void* arg)
|
||||||
{
|
{
|
||||||
@ -207,10 +205,8 @@ static qse_map_walk_t set_global (
|
|||||||
return QSE_MAP_WALK_FORWARD;
|
return QSE_MAP_WALK_FORWARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_run_enter (qse_awk_rtx_t* rtx, void* data)
|
static int apply_fs_and_gvm (qse_awk_rtx_t* rtx, struct arg_t* arg)
|
||||||
{
|
{
|
||||||
struct arg_t* arg = (struct arg_t*)data;
|
|
||||||
|
|
||||||
if (arg->fs != QSE_NULL)
|
if (arg->fs != QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_awk_val_t* fs;
|
qse_awk_val_t* fs;
|
||||||
@ -237,7 +233,13 @@ static int on_run_enter (qse_awk_rtx_t* rtx, void* data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_run_exit (
|
static int on_loop_enter (qse_awk_rtx_t* rtx, void* data)
|
||||||
|
{
|
||||||
|
/* TODO: anything to do? */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_loop_exit (
|
||||||
qse_awk_rtx_t* rtx, qse_awk_val_t* ret, void* data)
|
qse_awk_rtx_t* rtx, qse_awk_val_t* ret, void* data)
|
||||||
{
|
{
|
||||||
qse_size_t len;
|
qse_size_t len;
|
||||||
@ -266,48 +268,10 @@ static void on_run_exit (
|
|||||||
dprint (QSE_T("[END NAMED VARIABLES]\n"));
|
dprint (QSE_T("[END NAMED VARIABLES]\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: remove otab... */
|
static void on_statement (
|
||||||
static struct
|
qse_awk_rtx_t* run, qse_size_t line, void* data)
|
||||||
{
|
{
|
||||||
const qse_char_t* name;
|
/*dprint (L"running %d\n", (int)line);*/
|
||||||
int opt;
|
|
||||||
} otab[] =
|
|
||||||
{
|
|
||||||
{ QSE_T("implicit"), QSE_AWK_IMPLICIT },
|
|
||||||
{ QSE_T("explicit"), QSE_AWK_EXPLICIT },
|
|
||||||
{ QSE_T("bxor"), QSE_AWK_BXOR },
|
|
||||||
{ QSE_T("shift"), QSE_AWK_SHIFT },
|
|
||||||
{ QSE_T("idiv"), QSE_AWK_IDIV },
|
|
||||||
{ QSE_T("rio"), QSE_AWK_RIO },
|
|
||||||
{ QSE_T("rwpipe"), QSE_AWK_RWPIPE },
|
|
||||||
{ QSE_T("newline"), QSE_AWK_NEWLINE },
|
|
||||||
{ QSE_T("stripspaces"), QSE_AWK_STRIPSPACES },
|
|
||||||
{ QSE_T("nextofile"), QSE_AWK_NEXTOFILE },
|
|
||||||
{ QSE_T("crfl"), QSE_AWK_CRLF },
|
|
||||||
{ QSE_T("reset"), QSE_AWK_RESET },
|
|
||||||
{ QSE_T("maptovar"), QSE_AWK_MAPTOVAR },
|
|
||||||
{ QSE_T("pablock"), QSE_AWK_PABLOCK }
|
|
||||||
};
|
|
||||||
|
|
||||||
static void print_usage (const qse_char_t* argv0)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
|
|
||||||
qse_printf (QSE_T("Usage: %s [options] -f sourcefile [ -- ] [datafile]*\n"), argv0);
|
|
||||||
qse_printf (QSE_T(" %s [options] [ -- ] sourcestring [datafile]*\n"), argv0);
|
|
||||||
qse_printf (QSE_T("Where options are:\n"));
|
|
||||||
qse_printf (QSE_T(" -h print this message\n"));
|
|
||||||
qse_printf (QSE_T(" -d show extra information\n"));
|
|
||||||
qse_printf (QSE_T(" -f/--file sourcefile set the source script file\n"));
|
|
||||||
qse_printf (QSE_T(" -o/--deparsed-file deparsedfile set the deparsing output file\n"));
|
|
||||||
qse_printf (QSE_T(" -F/--field-separator string set a field separator(FS)\n"));
|
|
||||||
qse_printf (QSE_T(" -v/--assign var=value add a global variable with a value\n"));
|
|
||||||
|
|
||||||
qse_printf (QSE_T("\nYou may specify the following options to change the behavior of the interpreter.\n"));
|
|
||||||
for (j = 0; j < QSE_COUNTOF(otab); j++)
|
|
||||||
{
|
|
||||||
qse_printf (QSE_T(" --%-20s --no%-20s\n"), otab[j].name, otab[j].name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fnc_sleep (
|
static int fnc_sleep (
|
||||||
@ -347,30 +311,87 @@ static int fnc_sleep (
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void out_of_memory (void)
|
static void print_err (const qse_char_t* fmt, ...)
|
||||||
{
|
{
|
||||||
qse_fprintf (QSE_STDERR, QSE_T("Error: out of memory\n"));
|
va_list va;
|
||||||
|
|
||||||
|
qse_fprintf (QSE_STDERR, QSE_T("ERROR: "));
|
||||||
|
|
||||||
|
va_start (va, fmt);
|
||||||
|
qse_vfprintf (QSE_STDERR, fmt, va);
|
||||||
|
va_end (va);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct opttab_t
|
||||||
|
{
|
||||||
|
const qse_char_t* name;
|
||||||
|
int opt;
|
||||||
|
const qse_char_t* desc;
|
||||||
|
} opttab[] =
|
||||||
|
{
|
||||||
|
{ 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("bxor"), QSE_AWK_BXOR, QSE_T("enable bit-wise xor operator(^)") },
|
||||||
|
{ QSE_T("shift"), QSE_AWK_SHIFT, QSE_T("enable shift operators(<<,>>)") },
|
||||||
|
{ QSE_T("idiv"), QSE_AWK_IDIV, QSE_T("enable idiv operator(//)") },
|
||||||
|
{ QSE_T("rio"), QSE_AWK_RIO, QSE_T("") },
|
||||||
|
{ QSE_T("rwpipe"), QSE_AWK_RWPIPE, QSE_T("allow a dual-directional pipe") },
|
||||||
|
{ QSE_T("newline"), QSE_AWK_NEWLINE, QSE_T("") },
|
||||||
|
{ QSE_T("stripspaces"), QSE_AWK_STRIPSPACES, QSE_T("") },
|
||||||
|
{ QSE_T("nextofile"), QSE_AWK_NEXTOFILE, QSE_T("") },
|
||||||
|
{ QSE_T("crfl"), QSE_AWK_CRLF, QSE_T("") },
|
||||||
|
{ QSE_T("reset"), QSE_AWK_RESET, QSE_T("") },
|
||||||
|
{ QSE_T("maptovar"), QSE_AWK_MAPTOVAR, QSE_T("") },
|
||||||
|
{ QSE_T("pablock"), QSE_AWK_PABLOCK, QSE_T("") },
|
||||||
|
{ QSE_T("rexbound"), QSE_AWK_REXBOUND, QSE_T("") },
|
||||||
|
{ QSE_T("ncmponstr"), QSE_AWK_NCMPONSTR, QSE_T("") },
|
||||||
|
{ QSE_NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void print_usage (QSE_FILE* out, const qse_char_t* argv0)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
|
||||||
|
qse_fprintf (out, QSE_T("USAGE: %s [options] -f sourcefile [ -- ] [datafile]*\n"), argv0);
|
||||||
|
qse_fprintf (out, QSE_T(" %s [options] [ -- ] sourcestring [datafile]*\n"), argv0);
|
||||||
|
qse_fprintf (out, QSE_T("Where options are:\n"));
|
||||||
|
qse_fprintf (out, QSE_T(" -h/--help print this message\n"));
|
||||||
|
qse_fprintf (out, QSE_T(" -d show extra information\n"));
|
||||||
|
qse_fprintf (out, QSE_T(" -c/--call name calls a function instead of entering\n"));
|
||||||
|
qse_fprintf (out, QSE_T(" the pattern-action loop\n"));
|
||||||
|
qse_fprintf (out, QSE_T(" -f/--file sourcefile set the source script file\n"));
|
||||||
|
qse_fprintf (out, QSE_T(" -o/--deparsed-file deparsedfile set the deparsing output file\n"));
|
||||||
|
qse_fprintf (out, QSE_T(" -F/--field-separator string set a field separator(FS)\n"));
|
||||||
|
qse_fprintf (out, QSE_T(" -v/--assign var=value add a global variable with a value\n"));
|
||||||
|
|
||||||
|
for (j = 0; opttab[j].name != QSE_NULL; j++)
|
||||||
|
{
|
||||||
|
qse_fprintf (out, QSE_T(" --%-18s on/off %s\n"), opttab[j].name, opttab[j].desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
||||||
{
|
{
|
||||||
static qse_opt_lng_t lng[] =
|
static qse_opt_lng_t lng[] =
|
||||||
{
|
{
|
||||||
{ QSE_T("implicit"), 0 },
|
{ QSE_T(":implicit"), QSE_T('\0') },
|
||||||
{ QSE_T("explicit"), 0 },
|
{ QSE_T(":explicit"), QSE_T('\0') },
|
||||||
{ QSE_T("bxor"), 0 },
|
{ QSE_T(":bxor"), QSE_T('\0') },
|
||||||
{ QSE_T("shift"), 0 },
|
{ QSE_T(":shift"), QSE_T('\0') },
|
||||||
{ QSE_T("idiv"), 0 },
|
{ QSE_T(":idiv"), QSE_T('\0') },
|
||||||
{ QSE_T("extio"), 0 },
|
{ QSE_T(":rio"), QSE_T('\0') },
|
||||||
{ QSE_T("newline"), 0 },
|
{ QSE_T(":rwpipe"), QSE_T('\0') },
|
||||||
{ QSE_T("stripspaces"), 0 },
|
{ QSE_T(":newline"), QSE_T('\0') },
|
||||||
{ QSE_T("nextofile"), 0 },
|
{ QSE_T(":stripspaces"), QSE_T('\0') },
|
||||||
{ QSE_T("crlf"), 0 },
|
{ QSE_T(":nextofile"), QSE_T('\0') },
|
||||||
{ QSE_T("reset"), 0 },
|
{ QSE_T(":crlf"), QSE_T('\0') },
|
||||||
{ QSE_T("maptovar"), 0 },
|
{ QSE_T(":reset"), QSE_T('\0') },
|
||||||
{ QSE_T("pablock"), 0 },
|
{ QSE_T(":maptovar"), QSE_T('\0') },
|
||||||
|
{ QSE_T(":pablock"), QSE_T('\0') },
|
||||||
|
{ QSE_T(":rexbound"), QSE_T('\0') },
|
||||||
|
{ QSE_T(":ncmponstr"), QSE_T('\0') },
|
||||||
|
|
||||||
{ QSE_T(":main"), QSE_T('m') },
|
{ QSE_T(":call"), QSE_T('c') },
|
||||||
{ QSE_T(":file"), QSE_T('f') },
|
{ QSE_T(":file"), QSE_T('f') },
|
||||||
{ QSE_T(":field-separator"), QSE_T('F') },
|
{ QSE_T(":field-separator"), QSE_T('F') },
|
||||||
{ QSE_T(":deparsed-file"), QSE_T('o') },
|
{ QSE_T(":deparsed-file"), QSE_T('o') },
|
||||||
@ -381,7 +402,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
|
|
||||||
static qse_opt_t opt =
|
static qse_opt_t opt =
|
||||||
{
|
{
|
||||||
QSE_T("hdm:f:F:o:v:"),
|
QSE_T("dc:f:F:o:v:h"),
|
||||||
lng
|
lng
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -400,20 +421,21 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
|
|
||||||
qse_map_t* gvm = QSE_NULL; /* global variable map */
|
qse_map_t* gvm = QSE_NULL; /* global variable map */
|
||||||
qse_char_t* fs = QSE_NULL; /* field separator */
|
qse_char_t* fs = QSE_NULL; /* field separator */
|
||||||
|
qse_char_t* call = QSE_NULL; /* function to call */
|
||||||
|
|
||||||
memset (arg, 0, QSE_SIZEOF(*arg));
|
memset (arg, 0, QSE_SIZEOF(*arg));
|
||||||
|
|
||||||
isf = (qse_char_t**) malloc (QSE_SIZEOF(*isf) * isfc);
|
isf = (qse_char_t**) malloc (QSE_SIZEOF(*isf) * isfc);
|
||||||
if (isf == QSE_NULL)
|
if (isf == QSE_NULL)
|
||||||
{
|
{
|
||||||
out_of_memory ();
|
print_err (QSE_T("out of memory\n"));
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
gvm = qse_map_open (QSE_NULL, 0, 30, 70);
|
gvm = qse_map_open (QSE_NULL, 0, 30, 70);
|
||||||
if (gvm == QSE_NULL)
|
if (gvm == QSE_NULL)
|
||||||
{
|
{
|
||||||
out_of_memory ();
|
print_err (QSE_T("out of memory\n"));
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
/*qse_map_setcopier (gvm, QSE_MAP_KEY, QSE_MAP_COPIER_INLINE);*/
|
/*qse_map_setcopier (gvm, QSE_MAP_KEY, QSE_MAP_COPIER_INLINE);*/
|
||||||
@ -425,13 +447,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 0:
|
|
||||||
/* TODO: handle long options ... */
|
|
||||||
qse_printf (QSE_T(">>> [%s] [%s]\n"), opt.lngopt, opt.arg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QSE_T('h'):
|
case QSE_T('h'):
|
||||||
print_usage (argv[0]);
|
|
||||||
if (isf != QSE_NULL) free (isf);
|
if (isf != QSE_NULL) free (isf);
|
||||||
if (gvm != QSE_NULL) qse_map_close (gvm);
|
if (gvm != QSE_NULL) qse_map_close (gvm);
|
||||||
return 0;
|
return 0;
|
||||||
@ -442,6 +458,12 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case QSE_T('c'):
|
||||||
|
{
|
||||||
|
call = opt.arg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case QSE_T('f'):
|
case QSE_T('f'):
|
||||||
{
|
{
|
||||||
if (isfl >= isfc-1) /* -1 for last QSE_NULL */
|
if (isfl >= isfc-1) /* -1 for last QSE_NULL */
|
||||||
@ -450,7 +472,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
tmp = (qse_char_t**) realloc (isf, QSE_SIZEOF(*isf)*(isfc+16));
|
tmp = (qse_char_t**) realloc (isf, QSE_SIZEOF(*isf)*(isfc+16));
|
||||||
if (tmp == QSE_NULL)
|
if (tmp == QSE_NULL)
|
||||||
{
|
{
|
||||||
out_of_memory ();
|
print_err (QSE_T("out of memory\n"));
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,7 +504,10 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
eq = qse_strchr(opt.arg, QSE_T('='));
|
eq = qse_strchr(opt.arg, QSE_T('='));
|
||||||
if (eq == QSE_NULL)
|
if (eq == QSE_NULL)
|
||||||
{
|
{
|
||||||
/* INVALID VALUE... */
|
if (opt.lngopt)
|
||||||
|
print_err (QSE_T("no value for '%s' in '%s'\n"), opt.arg, opt.lngopt);
|
||||||
|
else
|
||||||
|
print_err (QSE_T("no value for '%s' in '%c'\n"), opt.arg, opt.opt);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,22 +519,36 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
|
|
||||||
if (qse_map_upsert (gvm, opt.arg, qse_strlen(opt.arg), &gvmv, 1) == QSE_NULL)
|
if (qse_map_upsert (gvm, opt.arg, qse_strlen(opt.arg), &gvmv, 1) == QSE_NULL)
|
||||||
{
|
{
|
||||||
out_of_memory ();
|
print_err (QSE_T("out of memory\n"));
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case QSE_T('\0'):
|
||||||
|
{
|
||||||
|
/* a long option with no corresponding short option */
|
||||||
|
qse_size_t i;
|
||||||
|
for (i = 0; opttab[i].name != QSE_NULL; i++)
|
||||||
|
{
|
||||||
|
if (qse_strcmp (opt.lngopt, opttab[i].name) == 0)
|
||||||
|
{
|
||||||
|
if (qse_strcmp (opt.arg, QSE_T("off")) == 0)
|
||||||
|
arg->optoff |= opttab[i].opt;
|
||||||
|
else
|
||||||
|
arg->opton |= opttab[i].opt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case QSE_T('?'):
|
case QSE_T('?'):
|
||||||
{
|
{
|
||||||
if (opt.lngopt)
|
if (opt.lngopt)
|
||||||
{
|
print_err (QSE_T("illegal option - '%s'\n"), opt.lngopt);
|
||||||
qse_printf (QSE_T("Error: illegal option - %s\n"), opt.lngopt);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
print_err (QSE_T("illegal option - '%c'\n"), opt.opt);
|
||||||
qse_printf (QSE_T("Error: illegal option - %c\n"), opt.opt);
|
|
||||||
}
|
|
||||||
|
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
@ -517,13 +556,9 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
case QSE_T(':'):
|
case QSE_T(':'):
|
||||||
{
|
{
|
||||||
if (opt.lngopt)
|
if (opt.lngopt)
|
||||||
{
|
print_err (QSE_T("bad argument for '%s'\n"), opt.lngopt);
|
||||||
qse_printf (QSE_T("Error: bad argument for %s\n"), opt.lngopt);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
print_err (QSE_T("bad argument for '%c'\n"), opt.opt);
|
||||||
qse_printf (QSE_T("Error: bad argument for %c\n"), opt.opt);
|
|
||||||
}
|
|
||||||
|
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
@ -563,7 +598,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
icf = (qse_char_t**) malloc (QSE_SIZEOF(qse_char_t*)*icfc);
|
icf = (qse_char_t**) malloc (QSE_SIZEOF(qse_char_t*)*icfc);
|
||||||
if (icf == QSE_NULL)
|
if (icf == QSE_NULL)
|
||||||
{
|
{
|
||||||
out_of_memory ();
|
print_err (QSE_T("out of memory\n"));
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -587,6 +622,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
arg->icfl = icfl;
|
arg->icfl = icfl;
|
||||||
arg->gvm = gvm;
|
arg->gvm = gvm;
|
||||||
arg->fs = fs;
|
arg->fs = fs;
|
||||||
|
arg->call = call;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -608,8 +644,8 @@ static void freearg (struct arg_t* arg)
|
|||||||
|
|
||||||
static void print_awkerr (qse_awk_t* awk)
|
static void print_awkerr (qse_awk_t* awk)
|
||||||
{
|
{
|
||||||
qse_printf (
|
print_err (
|
||||||
QSE_T("ERROR: CODE [%d] LINE [%u] %s\n"),
|
QSE_T("CODE [%d] LINE [%u] %s\n"),
|
||||||
qse_awk_geterrnum(awk),
|
qse_awk_geterrnum(awk),
|
||||||
(unsigned int)qse_awk_geterrlin(awk),
|
(unsigned int)qse_awk_geterrlin(awk),
|
||||||
qse_awk_geterrmsg(awk)
|
qse_awk_geterrmsg(awk)
|
||||||
@ -618,8 +654,8 @@ static void print_awkerr (qse_awk_t* awk)
|
|||||||
|
|
||||||
static void print_rtxerr (qse_awk_rtx_t* rtx)
|
static void print_rtxerr (qse_awk_rtx_t* rtx)
|
||||||
{
|
{
|
||||||
qse_printf (
|
print_err (
|
||||||
QSE_T("ERROR: CODE [%d] LINE [%u] %s\n"),
|
QSE_T("CODE [%d] LINE [%u] %s\n"),
|
||||||
qse_awk_rtx_geterrnum(rtx),
|
qse_awk_rtx_geterrnum(rtx),
|
||||||
(unsigned int)qse_awk_rtx_geterrlin(rtx),
|
(unsigned int)qse_awk_rtx_geterrlin(rtx),
|
||||||
qse_awk_rtx_geterrmsg(rtx)
|
qse_awk_rtx_geterrmsg(rtx)
|
||||||
@ -657,12 +693,11 @@ static int awk_main (int argc, qse_char_t* argv[])
|
|||||||
qse_memset (&arg, 0, QSE_SIZEOF(arg));
|
qse_memset (&arg, 0, QSE_SIZEOF(arg));
|
||||||
|
|
||||||
i = comparg (argc, argv, &arg);
|
i = comparg (argc, argv, &arg);
|
||||||
if (i <= -1)
|
if (i <= 0)
|
||||||
{
|
{
|
||||||
print_usage (argv[0]);
|
print_usage (((i == 0)? QSE_STDOUT: QSE_STDERR), argv[0]);
|
||||||
return -1;
|
return i;
|
||||||
}
|
}
|
||||||
if (i == 0) return 0;
|
|
||||||
|
|
||||||
psin.type = arg.ist;
|
psin.type = arg.ist;
|
||||||
if (arg.ist == QSE_AWK_PARSESTD_CP) psin.u.cp = arg.isp.str;
|
if (arg.ist == QSE_AWK_PARSESTD_CP) psin.u.cp = arg.isp.str;
|
||||||
@ -681,6 +716,11 @@ static int awk_main (int argc, qse_char_t* argv[])
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i = qse_awk_getoption (awk);
|
||||||
|
if (arg.opton) i |= arg.opton;
|
||||||
|
if (arg.optoff) i &= ~arg.optoff;
|
||||||
|
qse_awk_setoption (awk, i);
|
||||||
|
|
||||||
/* TODO: get depth from command line */
|
/* TODO: get depth from command line */
|
||||||
qse_awk_setmaxdepth (
|
qse_awk_setmaxdepth (
|
||||||
awk, QSE_AWK_DEPTH_BLOCK_PARSE | QSE_AWK_DEPTH_EXPR_PARSE, 50);
|
awk, QSE_AWK_DEPTH_BLOCK_PARSE | QSE_AWK_DEPTH_EXPR_PARSE, 50);
|
||||||
@ -710,9 +750,9 @@ static int awk_main (int argc, qse_char_t* argv[])
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcb.on_enter = on_run_enter;
|
rcb.on_loop_enter = on_loop_enter;
|
||||||
rcb.on_statement = on_run_statement;
|
rcb.on_loop_exit = on_loop_exit;
|
||||||
rcb.on_exit = on_run_exit;
|
rcb.on_statement = on_statement;
|
||||||
rcb.data = &arg;
|
rcb.data = &arg;
|
||||||
|
|
||||||
rtx = qse_awk_rtx_openstd (awk, 0, QSE_T("qseawk"), arg.icf, QSE_NULL);
|
rtx = qse_awk_rtx_openstd (awk, 0, QSE_T("qseawk"), arg.icf, QSE_NULL);
|
||||||
@ -722,14 +762,31 @@ static int awk_main (int argc, qse_char_t* argv[])
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (apply_fs_and_gvm (rtx, &arg) <= -1)
|
||||||
|
{
|
||||||
|
print_awkerr (awk);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
app_rtx = rtx;
|
app_rtx = rtx;
|
||||||
qse_awk_rtx_setrcb (rtx, &rcb);
|
qse_awk_rtx_setrcb (rtx, &rcb);
|
||||||
|
|
||||||
set_intr_run ();
|
set_intr_run ();
|
||||||
ret = qse_awk_rtx_loop (rtx);
|
if (arg.call == QSE_NULL)
|
||||||
|
{
|
||||||
|
ret = qse_awk_rtx_loop (rtx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qse_awk_val_t* rv;
|
||||||
|
|
||||||
|
rv = qse_awk_rtx_call (rtx, arg.call, QSE_NULL, 0);
|
||||||
|
ret = (rv == QSE_NULL)? -1: 0;
|
||||||
|
qse_awk_rtx_refdownval (rtx, rv);
|
||||||
|
}
|
||||||
unset_intr_run ();
|
unset_intr_run ();
|
||||||
|
|
||||||
if (ret == -1)
|
if (ret <= -1)
|
||||||
{
|
{
|
||||||
print_rtxerr (rtx);
|
print_rtxerr (rtx);
|
||||||
goto oops;
|
goto oops;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: Awk.hpp 205 2009-06-20 12:47:34Z hyunghwan.chung $
|
* $Id: Awk.hpp 206 2009-06-21 13:33:05Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
|
||||||
@ -572,10 +572,10 @@ public:
|
|||||||
* to a number is compared with a number or vice versa.
|
* to a number is compared with a number or vice versa.
|
||||||
*
|
*
|
||||||
* For an expression (9 > "10.9"),
|
* For an expression (9 > "10.9"),
|
||||||
* - 9 is greater if #QSE_AWK_NUMCMPONSTR is off;
|
* - 9 is greater if #QSE_AWK_NCMPONSTR is off;
|
||||||
* - "10.9" is greater if #QSE_AWK_NUMCMPONSTR is on
|
* - "10.9" is greater if #QSE_AWK_NCMPONSTR is on
|
||||||
*/
|
*/
|
||||||
OPT_NUMCMPONSTR = QSE_AWK_NUMCMPONSTR
|
OPT_NCMPONSTR = QSE_AWK_NCMPONSTR
|
||||||
};
|
};
|
||||||
// end of enum Option
|
// end of enum Option
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: awk.h 205 2009-06-20 12:47:34Z hyunghwan.chung $
|
* $Id: awk.h 206 2009-06-21 13:33:05Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
|
||||||
@ -321,15 +321,15 @@ typedef struct qse_awk_rio_t qse_awk_rio_t;
|
|||||||
*/
|
*/
|
||||||
struct qse_awk_rcb_t
|
struct qse_awk_rcb_t
|
||||||
{
|
{
|
||||||
int (*on_enter) (
|
int (*on_loop_enter) (
|
||||||
qse_awk_rtx_t* rtx, void* data);
|
qse_awk_rtx_t* rtx, void* data);
|
||||||
|
|
||||||
|
void (*on_loop_exit) (
|
||||||
|
qse_awk_rtx_t* rtx, qse_awk_val_t* ret, void* data);
|
||||||
|
|
||||||
void (*on_statement) (
|
void (*on_statement) (
|
||||||
qse_awk_rtx_t* rtx, qse_size_t line, void* data);
|
qse_awk_rtx_t* rtx, qse_size_t line, void* data);
|
||||||
|
|
||||||
void (*on_exit) (
|
|
||||||
qse_awk_rtx_t* rtx, qse_awk_val_t* ret, void* data);
|
|
||||||
|
|
||||||
void* data;
|
void* data;
|
||||||
};
|
};
|
||||||
typedef struct qse_awk_rcb_t qse_awk_rcb_t;
|
typedef struct qse_awk_rcb_t qse_awk_rcb_t;
|
||||||
@ -408,10 +408,10 @@ enum qse_awk_option_t
|
|||||||
* to a number is compared with a number or vice versa.
|
* to a number is compared with a number or vice versa.
|
||||||
*
|
*
|
||||||
* For an expression (9 > "10.9"),
|
* For an expression (9 > "10.9"),
|
||||||
* - 9 is greater if #QSE_AWK_NUMCMPONSTR is off;
|
* - 9 is greater if #QSE_AWK_NCMPONSTR is off;
|
||||||
* - "10.9" is greater if #QSE_AWK_NUMCMPONSTR is on
|
* - "10.9" is greater if #QSE_AWK_NCMPONSTR is on
|
||||||
*/
|
*/
|
||||||
QSE_AWK_NUMCMPONSTR = (1 << 18),
|
QSE_AWK_NCMPONSTR = (1 << 18),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* makes #qse_awk_t to behave as compatibly as classical AWK
|
* makes #qse_awk_t to behave as compatibly as classical AWK
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: std.h 205 2009-06-20 12:47:34Z hyunghwan.chung $
|
* $Id: std.h 206 2009-06-21 13:33:05Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
|
||||||
@ -32,6 +32,7 @@
|
|||||||
*
|
*
|
||||||
* @todo
|
* @todo
|
||||||
* - StdAwk ARGV and console name handling
|
* - StdAwk ARGV and console name handling
|
||||||
|
* - add RQ and LQ for more powerful record splitting
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: Awk.cpp 202 2009-06-16 06:05:40Z hyunghwan.chung $
|
* $Id: Awk.cpp 206 2009-06-21 13:33:05Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
|
||||||
@ -1366,12 +1366,10 @@ int Awk::run (const char_t** args, size_t nargs)
|
|||||||
{
|
{
|
||||||
QSE_MEMSET (&rcb, 0, QSE_SIZEOF(rcb));
|
QSE_MEMSET (&rcb, 0, QSE_SIZEOF(rcb));
|
||||||
// TODO: deprecate onRunStart and onRunEnd
|
// TODO: deprecate onRunStart and onRunEnd
|
||||||
//rcb.on_start = onRunStart;
|
rcb.on_loop_enter = onRunEnter;
|
||||||
//rcb.on_end = onRunEnd;
|
rcb.on_loop_exit = onRunExit;
|
||||||
rcb.on_enter = onRunEnter;
|
rcb.on_statement = onRunStatement;
|
||||||
rcb.on_statement = onRunStatement;
|
rcb.data = &runctx;
|
||||||
rcb.on_exit = onRunExit;
|
|
||||||
rcb.data = &runctx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nargs > 0)
|
if (nargs > 0)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: run.c 204 2009-06-18 12:08:06Z hyunghwan.chung $
|
* $Id: run.c 206 2009-06-21 13:33:05Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
|
||||||
@ -1322,10 +1322,10 @@ static int run_bpae_loop (qse_awk_rtx_t* rtx)
|
|||||||
STACK_NARGS(rtx) = (void*)nargs;
|
STACK_NARGS(rtx) = (void*)nargs;
|
||||||
|
|
||||||
/* call the callback */
|
/* call the callback */
|
||||||
if (rtx->rcb.on_enter != QSE_NULL)
|
if (rtx->rcb.on_loop_enter != QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOERR);
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOERR);
|
||||||
ret = rtx->rcb.on_enter (rtx, rtx->rcb.data);
|
ret = rtx->rcb.on_loop_enter (rtx, rtx->rcb.data);
|
||||||
if (ret <= -1)
|
if (ret <= -1)
|
||||||
{
|
{
|
||||||
if (rtx->errinf.num == QSE_AWK_ENOMEM)
|
if (rtx->errinf.num == QSE_AWK_ENOMEM)
|
||||||
@ -1424,12 +1424,12 @@ static int run_bpae_loop (qse_awk_rtx_t* rtx)
|
|||||||
/* get the return value in the current stack frame */
|
/* get the return value in the current stack frame */
|
||||||
v = STACK_RETVAL(rtx);
|
v = STACK_RETVAL(rtx);
|
||||||
|
|
||||||
if (rtx->rcb.on_exit != QSE_NULL)
|
if (rtx->rcb.on_loop_exit != QSE_NULL)
|
||||||
{
|
{
|
||||||
/* we call the on_exit handler regardless of ret.
|
/* we call the on_exit handler regardless of ret.
|
||||||
* the return value passed is the global return value
|
* the return value passed is the global return value
|
||||||
* in the stack. */
|
* in the stack. */
|
||||||
rtx->rcb.on_exit (rtx, v, rtx->rcb.data);
|
rtx->rcb.on_loop_exit (rtx, v, rtx->rcb.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* end the life of the global return value */
|
/* end the life of the global return value */
|
||||||
@ -1462,9 +1462,6 @@ qse_awk_val_t* qse_awk_rtx_call (
|
|||||||
qse_awk_rtx_t* rtx, const qse_char_t* name,
|
qse_awk_rtx_t* rtx, const qse_char_t* name,
|
||||||
qse_awk_val_t** args, qse_size_t nargs)
|
qse_awk_val_t** args, qse_size_t nargs)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
int ret = 0;
|
|
||||||
#endif
|
|
||||||
qse_map_pair_t* pair;
|
qse_map_pair_t* pair;
|
||||||
qse_awk_fun_t* fun;
|
qse_awk_fun_t* fun;
|
||||||
struct capture_retval_data_t crdata;
|
struct capture_retval_data_t crdata;
|
||||||
@ -1475,7 +1472,7 @@ qse_awk_val_t* qse_awk_rtx_call (
|
|||||||
pafv.args = args;
|
pafv.args = args;
|
||||||
pafv.nargs = nargs;
|
pafv.nargs = nargs;
|
||||||
|
|
||||||
if (rtx->exit_level >= EXIT_NEXT)
|
if (rtx->exit_level >= EXIT_GLOBAL)
|
||||||
{
|
{
|
||||||
/* cannot call the function again when exit() is called
|
/* cannot call the function again when exit() is called
|
||||||
* in an AWK program or qse_awk_rtx_stop() is invoked */
|
* in an AWK program or qse_awk_rtx_stop() is invoked */
|
||||||
@ -1548,14 +1545,16 @@ qse_awk_val_t* qse_awk_rtx_call (
|
|||||||
qse_awk_rtx_refupval (rtx, v);
|
qse_awk_rtx_refupval (rtx, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtx->rcb.on_exit != QSE_NULL)
|
#if 0
|
||||||
|
if (rtx->rcb.on_loop_exit != QSE_NULL)
|
||||||
{
|
{
|
||||||
rtx->rcb.on_exit (
|
rtx->rcb.on_loop_exit (
|
||||||
rtx,
|
rtx,
|
||||||
((v == QSE_NULL)? qse_awk_val_nil: v),
|
((v == QSE_NULL)? qse_awk_val_nil: v),
|
||||||
rtx->rcb.data
|
rtx->rcb.data
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* return the return value with its reference count at least 1.
|
/* return the return value with its reference count at least 1.
|
||||||
* the caller of this function should count down its reference. */
|
* the caller of this function should count down its reference. */
|
||||||
@ -4027,7 +4026,7 @@ static int __cmp_int_str (
|
|||||||
qse_awk_rtx_valtostr_out_t out;
|
qse_awk_rtx_valtostr_out_t out;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (rtx->awk->option & QSE_AWK_NUMCMPONSTR)
|
if (rtx->awk->option & QSE_AWK_NCMPONSTR)
|
||||||
{
|
{
|
||||||
const qse_char_t* end;
|
const qse_char_t* end;
|
||||||
qse_long_t ll;
|
qse_long_t ll;
|
||||||
@ -4114,7 +4113,7 @@ static int __cmp_real_str (
|
|||||||
qse_awk_rtx_valtostr_out_t out;
|
qse_awk_rtx_valtostr_out_t out;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (rtx->awk->option & QSE_AWK_NUMCMPONSTR)
|
if (rtx->awk->option & QSE_AWK_NCMPONSTR)
|
||||||
{
|
{
|
||||||
const qse_char_t* end;
|
const qse_char_t* end;
|
||||||
qse_real_t rr;
|
qse_real_t rr;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: opt.c 76 2009-02-22 14:18:06Z hyunghwan.chung $
|
* $Id: opt.c 206 2009-06-21 13:33:05Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
|
||||||
@ -131,6 +131,10 @@ qse_cint_t qse_getopt (int argc, qse_char_t* const* argv, qse_opt_t* opt)
|
|||||||
/* match */
|
/* match */
|
||||||
opt->cur = EMSG;
|
opt->cur = EMSG;
|
||||||
opt->lngopt = o->str;
|
opt->lngopt = o->str;
|
||||||
|
|
||||||
|
/* for a long matching option, remove the leading colon */
|
||||||
|
if (opt->lngopt[0] == QSE_T(':')) opt->lngopt++;
|
||||||
|
|
||||||
if (*end == QSE_T('=')) opt->arg = end + 1;
|
if (*end == QSE_T('=')) opt->arg = end + 1;
|
||||||
|
|
||||||
if (*o->str != QSE_T(':'))
|
if (*o->str != QSE_T(':'))
|
||||||
@ -140,7 +144,7 @@ qse_cint_t qse_getopt (int argc, qse_char_t* const* argv, qse_opt_t* opt)
|
|||||||
}
|
}
|
||||||
else if (opt->arg == QSE_NULL)
|
else if (opt->arg == QSE_NULL)
|
||||||
{
|
{
|
||||||
/* Check if it has a remaining argument
|
/* check if it has a remaining argument
|
||||||
* available */
|
* available */
|
||||||
if (argc <= ++opt->ind) return BADARG;
|
if (argc <= ++opt->ind) return BADARG;
|
||||||
/* If so, the next available argument is
|
/* If so, the next available argument is
|
||||||
|
Loading…
Reference in New Issue
Block a user