fixed a bug in StdAwk::SourceFile::open()
This commit is contained in:
parent
64753ed49f
commit
ce695db836
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: StdAwk.cpp 252 2009-08-11 01:28:32Z hyunghwan.chung $
|
* $Id: StdAwk.cpp 253 2009-08-12 13:39:37Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
|
||||||
@ -817,7 +817,7 @@ int StdAwk::SourceFile::open (Data& io)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char_t* file = name;
|
const char_t* file = ioname;
|
||||||
char_t fbuf[64];
|
char_t fbuf[64];
|
||||||
char_t* dbuf = QSE_NULL;
|
char_t* dbuf = QSE_NULL;
|
||||||
|
|
||||||
|
@ -20,8 +20,11 @@
|
|||||||
#include <qse/cmn/str.h>
|
#include <qse/cmn/str.h>
|
||||||
#include <qse/cmn/stdio.h>
|
#include <qse/cmn/stdio.h>
|
||||||
#include <qse/cmn/main.h>
|
#include <qse/cmn/main.h>
|
||||||
|
#include <qse/cmn/opt.h>
|
||||||
|
#include <qse/cmn/mem.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
@ -43,7 +46,17 @@ static void set_intr_run (void);
|
|||||||
static void unset_intr_run (void);
|
static void unset_intr_run (void);
|
||||||
|
|
||||||
MyAwk* app_awk = QSE_NULL;
|
MyAwk* app_awk = QSE_NULL;
|
||||||
static bool verbose = false;
|
|
||||||
|
static void print_error (const qse_char_t* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
|
||||||
|
qse_fprintf (QSE_STDERR, QSE_T("ERROR: "));
|
||||||
|
|
||||||
|
va_start (va, fmt);
|
||||||
|
qse_vfprintf (QSE_STDERR, fmt, va);
|
||||||
|
va_end (va);
|
||||||
|
}
|
||||||
|
|
||||||
class MyAwk: public QSE::StdAwk
|
class MyAwk: public QSE::StdAwk
|
||||||
{
|
{
|
||||||
@ -237,247 +250,142 @@ static void unset_intr_run (void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_error (const qse_char_t* msg)
|
static void print_usage (QSE_FILE* out, const qse_char_t* argv0)
|
||||||
{
|
{
|
||||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), msg);
|
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 print this message\n"));
|
||||||
|
qse_fprintf (out, QSE_T(" -f sourcefile set the source script file\n"));
|
||||||
|
qse_fprintf (out, QSE_T(" -o deparsedfile set the deparsing output file\n"));
|
||||||
|
qse_fprintf (out, QSE_T(" -F string set a field separator(FS)\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct cmdline_t
|
||||||
struct opttab_t
|
|
||||||
{
|
{
|
||||||
const qse_char_t* name;
|
qse_char_t* ins;
|
||||||
int opt;
|
qse_char_t* inf;
|
||||||
const qse_char_t* desc;
|
qse_char_t* outf;
|
||||||
} opttab[] =
|
qse_char_t* fs;
|
||||||
{
|
|
||||||
{ QSE_T("implicit"), MyAwk::OPT_IMPLICIT, QSE_T("allow undeclared variables") },
|
|
||||||
{ QSE_T("explicit"), MyAwk::OPT_EXPLICIT, QSE_T("allow declared variables(local,global)") },
|
|
||||||
{ QSE_T("extraops"), MyAwk::OPT_EXTRAOPS, QSE_T("enable extra operators(<<,>>,^^,//)") },
|
|
||||||
{ QSE_T("rio"), MyAwk::OPT_RIO, QSE_T("enable builtin I/O including getline & print") },
|
|
||||||
{ QSE_T("rwpipe"), MyAwk::OPT_RWPIPE, QSE_T("allow a dual-directional pipe") },
|
|
||||||
{ QSE_T("newline"), MyAwk::OPT_NEWLINE, QSE_T("enable a newline to terminate a statement") },
|
|
||||||
{ QSE_T("striprecspc"), MyAwk::OPT_STRIPRECSPC, QSE_T("strip spaces in splitting a record") },
|
|
||||||
{ QSE_T("stripstrspc"), MyAwk::OPT_STRIPSTRSPC, QSE_T("strip spaces in converting a string to a number") },
|
|
||||||
{ QSE_T("nextofile"), MyAwk::OPT_NEXTOFILE, QSE_T("enable 'nextofile'") },
|
|
||||||
{ QSE_T("reset"), MyAwk::OPT_RESET, QSE_T("enable 'reset'") },
|
|
||||||
{ QSE_T("crlf"), MyAwk::OPT_CRLF, QSE_T("use CRLF for a newline") },
|
|
||||||
{ QSE_T("maptovar"), MyAwk::OPT_MAPTOVAR, QSE_T("allow a map to be assigned or returned") },
|
|
||||||
{ QSE_T("pablock"), MyAwk::OPT_PABLOCK, QSE_T("enable pattern-action loop") },
|
|
||||||
{ QSE_T("rexbound"), MyAwk::OPT_REXBOUND, QSE_T("enable {n,m} in a regular expression") },
|
|
||||||
{ QSE_T("ncmponstr"), MyAwk::OPT_NCMPONSTR, QSE_T("perform numeric comparsion on numeric strings") },
|
|
||||||
{ QSE_T("strictnaming"), MyAwk::OPT_STRICTNAMING, QSE_T("enable the strict naming rule") },
|
|
||||||
{ QSE_T("include"), MyAwk::OPT_INCLUDE, QSE_T("enable 'include'") },
|
|
||||||
{ QSE_NULL, 0 }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void print_usage (const qse_char_t* argv0)
|
static int handle_cmdline (MyAwk& awk, int argc, qse_char_t* argv[], cmdline_t* cmdline)
|
||||||
{
|
{
|
||||||
const qse_char_t* base;
|
static qse_opt_t opt =
|
||||||
int j;
|
|
||||||
|
|
||||||
base = qse_strrchr(argv0, QSE_T('/'));
|
|
||||||
if (base == QSE_NULL) base = qse_strrchr(argv0, QSE_T('\\'));
|
|
||||||
if (base == QSE_NULL) base = argv0; else base++;
|
|
||||||
|
|
||||||
qse_printf (QSE_T("Usage: %s [-si file]? [-so file]? [-ci file]* [-co file]* [-w o:n]* \n"), base);
|
|
||||||
qse_printf (QSE_T(" -si file Specify the input source file\n"));
|
|
||||||
qse_printf (QSE_T(" The source code is read from stdin when it is not specified\n"));
|
|
||||||
qse_printf (QSE_T(" -so file Specify the output source file\n"));
|
|
||||||
qse_printf (QSE_T(" The deparsed code is not output when is it not specified\n"));
|
|
||||||
qse_printf (QSE_T(" -ci file Specify the input console file\n"));
|
|
||||||
qse_printf (QSE_T(" -co file Specify the output console file\n"));
|
|
||||||
qse_printf (QSE_T(" -w o:n Specify an old and new word pair\n"));
|
|
||||||
qse_printf (QSE_T(" o - an original word\n"));
|
|
||||||
qse_printf (QSE_T(" n - the new word to replace the original\n"));
|
|
||||||
qse_printf (QSE_T(" -v Print extra messages\n"));
|
|
||||||
|
|
||||||
|
|
||||||
qse_printf (QSE_T("\nYou may specify the following options to change the behavior of the interpreter.\n"));
|
|
||||||
for (j = 0; j < (int)QSE_COUNTOF(opttab); j++)
|
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T(" -%-20s -no%-20s\n"), opttab[j].name, opttab[j].name);
|
QSE_T("hF:f:o:"),
|
||||||
|
QSE_NULL
|
||||||
|
};
|
||||||
|
qse_cint_t c;
|
||||||
|
|
||||||
|
memset (cmdline, 0, QSE_SIZEOF(*cmdline));
|
||||||
|
while ((c = qse_getopt (argc, argv, &opt)) != QSE_CHAR_EOF)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case QSE_T('h'):
|
||||||
|
print_usage (QSE_STDOUT, argv[0]);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case QSE_T('F'):
|
||||||
|
cmdline->fs = opt.arg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QSE_T('f'):
|
||||||
|
cmdline->inf = opt.arg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QSE_T('o'):
|
||||||
|
cmdline->outf = opt.arg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QSE_T('?'):
|
||||||
|
print_error (QSE_T("illegal option - '%c'\n"), opt.opt);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
case QSE_T(':'):
|
||||||
|
print_error (QSE_T("bad argument for '%c'\n"), opt.opt);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
print_usage (QSE_STDERR, argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt.ind < argc && !cmdline->inf)
|
||||||
|
cmdline->ins = argv[opt.ind++];
|
||||||
|
|
||||||
|
while (opt.ind < argc)
|
||||||
|
{
|
||||||
|
if (awk.addArgument (argv[opt.ind++]) <= -1) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int awk_main (int argc, qse_char_t* argv[])
|
static int awk_main (int argc, qse_char_t* argv[])
|
||||||
{
|
{
|
||||||
MyAwk awk;
|
MyAwk awk;
|
||||||
MyAwk::Run* run;
|
MyAwk::Run* run;
|
||||||
|
cmdline_t cmdline;
|
||||||
int mode = 0;
|
int n;
|
||||||
const qse_char_t* srcin = QSE_T("");
|
|
||||||
const qse_char_t* srcout = NULL;
|
|
||||||
qse_size_t nsrcins = 0;
|
|
||||||
qse_size_t nsrcouts = 0;
|
|
||||||
|
|
||||||
if (awk.open() <= -1)
|
if (awk.open() <= -1)
|
||||||
{
|
{
|
||||||
print_error (awk.getErrorMessage());
|
print_error (QSE_T("%s\n"), awk.getErrorMessage());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
awk.setOption (awk.getOption() | awk.OPT_INCLUDE);
|
||||||
|
|
||||||
// ARGV[0]
|
// ARGV[0]
|
||||||
if (awk.addArgument (QSE_T("awk05")) <= -1)
|
if (awk.addArgument (QSE_T("awk08")) <= -1)
|
||||||
{
|
{
|
||||||
print_error (awk.getErrorMessage());
|
print_error (QSE_T("%s\n"), awk.getErrorMessage());
|
||||||
awk.close ();
|
awk.close ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++)
|
if ((n = handle_cmdline (awk, argc, argv, &cmdline)) <= 0)
|
||||||
{
|
{
|
||||||
if (mode == 0)
|
|
||||||
{
|
|
||||||
if (qse_strcmp(argv[i], QSE_T("-si")) == 0) mode = 1;
|
|
||||||
else if (qse_strcmp(argv[i], QSE_T("-so")) == 0) mode = 2;
|
|
||||||
else if (qse_strcmp(argv[i], QSE_T("-ci")) == 0) mode = 3;
|
|
||||||
else if (qse_strcmp(argv[i], QSE_T("-co")) == 0) mode = 4;
|
|
||||||
else if (qse_strcmp(argv[i], QSE_T("-w")) == 0) mode = 5;
|
|
||||||
else if (qse_strcmp(argv[i], QSE_T("-v")) == 0)
|
|
||||||
{
|
|
||||||
verbose = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (argv[i][0] == QSE_T('-'))
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
|
|
||||||
if (argv[i][1] == QSE_T('n') && argv[i][2] == QSE_T('o'))
|
|
||||||
{
|
|
||||||
for (j = 0; j < (int)QSE_COUNTOF(opttab); j++)
|
|
||||||
{
|
|
||||||
if (qse_strcmp(&argv[i][3], opttab[j].name) == 0)
|
|
||||||
{
|
|
||||||
awk.setOption (awk.getOption() & ~opttab[j].opt);
|
|
||||||
goto ok_valid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (j = 0; j < (int)QSE_COUNTOF(opttab); j++)
|
|
||||||
{
|
|
||||||
if (qse_strcmp(&argv[i][1], opttab[j].name) == 0)
|
|
||||||
{
|
|
||||||
awk.setOption (awk.getOption() | opttab[j].opt);
|
|
||||||
goto ok_valid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
print_usage (argv[0]);
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
ok_valid:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (argv[i][0] == QSE_T('-'))
|
|
||||||
{
|
|
||||||
print_usage (argv[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode == 1) // source input
|
|
||||||
{
|
|
||||||
if (nsrcins != 0)
|
|
||||||
{
|
|
||||||
print_usage (argv[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
srcin = argv[i];
|
|
||||||
nsrcins++;
|
|
||||||
mode = 0;
|
|
||||||
}
|
|
||||||
else if (mode == 2) // source output
|
|
||||||
{
|
|
||||||
if (nsrcouts != 0)
|
|
||||||
{
|
|
||||||
print_usage (argv[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
srcout = argv[i];
|
|
||||||
nsrcouts++;
|
|
||||||
mode = 0;
|
|
||||||
}
|
|
||||||
else if (mode == 3) // console input
|
|
||||||
{
|
|
||||||
if (awk.addArgument (argv[i]) <= -1)
|
|
||||||
{
|
|
||||||
print_error (QSE_T("too many console inputs"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mode = 0;
|
|
||||||
}
|
|
||||||
else if (mode == 4) // console output
|
|
||||||
{
|
|
||||||
if (awk.addConsoleOutput (argv[i]) <= -1)
|
|
||||||
{
|
|
||||||
print_error (QSE_T("too many console outputs"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mode = 0;
|
|
||||||
}
|
|
||||||
else if (mode == 5) // word replacement
|
|
||||||
{
|
|
||||||
const qse_char_t* p;
|
|
||||||
qse_size_t l;
|
|
||||||
qse_cstr_t ow, nw;
|
|
||||||
|
|
||||||
p = qse_strchr(argv[i], QSE_T(':'));
|
|
||||||
if (p == QSE_NULL)
|
|
||||||
{
|
|
||||||
print_usage (argv[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
l = qse_strlen (argv[i]);
|
|
||||||
|
|
||||||
ow.ptr = argv[i];
|
|
||||||
ow.len = p - argv[i];
|
|
||||||
|
|
||||||
nw.ptr = p + 1;
|
|
||||||
nw.len = l - (ow.len + 1);
|
|
||||||
|
|
||||||
awk.setWord (&ow, &nw);
|
|
||||||
mode = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode != 0)
|
|
||||||
{
|
|
||||||
print_usage (argv[0]);
|
|
||||||
awk.close ();
|
awk.close ();
|
||||||
return -1;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
MyAwk::SourceFile sin (srcin);
|
|
||||||
MyAwk::SourceFile sout (srcout);
|
|
||||||
|
|
||||||
run = awk.parse (sin, sout);
|
MyAwk::Source* in, * out;
|
||||||
|
MyAwk::SourceString in_str (cmdline.ins);
|
||||||
|
MyAwk::SourceFile in_file (cmdline.inf);
|
||||||
|
MyAwk::SourceFile out_file (cmdline.outf);
|
||||||
|
|
||||||
|
in = (cmdline.ins)? (MyAwk::Source*)&in_str: (MyAwk::Source*)&in_file;
|
||||||
|
out = (cmdline.outf)? (MyAwk::Source*)&out_file: &MyAwk::Source::NONE;
|
||||||
|
run = awk.parse (*in, *out);
|
||||||
if (run == QSE_NULL)
|
if (run == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_fprintf (stderr, QSE_T("cannot parse: LINE[%d] %s\n"),
|
print_error (
|
||||||
|
QSE_T("ERROR: LINE[%d] %s\n"),
|
||||||
awk.getErrorLine(), awk.getErrorMessage());
|
awk.getErrorLine(), awk.getErrorMessage());
|
||||||
awk.close ();
|
awk.close ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cmdline.fs)
|
||||||
|
{
|
||||||
|
// TODO: print error.... handle error properly
|
||||||
|
MyAwk::Value fs (run);
|
||||||
|
if (fs.setStr (cmdline.fs) <= -1) return -1;
|
||||||
|
if (awk.setGlobal (awk.GBL_FS, fs) <= -1) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
app_awk = &awk;
|
app_awk = &awk;
|
||||||
|
|
||||||
MyAwk::Value ret;
|
MyAwk::Value ret;
|
||||||
if (awk.loop (&ret) <= -1)
|
if (awk.loop (&ret) <= -1)
|
||||||
{
|
{
|
||||||
qse_fprintf (stderr, QSE_T("cannot run: LINE[%d] %s\n"),
|
print_error (
|
||||||
|
QSE_T("ERROR: LINE[%d] %s\n"),
|
||||||
awk.getErrorLine(), awk.getErrorMessage());
|
awk.getErrorLine(), awk.getErrorMessage());
|
||||||
awk.close ();
|
awk.close ();
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user