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.
|
||||
|
||||
@ -817,7 +817,7 @@ int StdAwk::SourceFile::open (Data& io)
|
||||
}
|
||||
else
|
||||
{
|
||||
const char_t* file = name;
|
||||
const char_t* file = ioname;
|
||||
char_t fbuf[64];
|
||||
char_t* dbuf = QSE_NULL;
|
||||
|
||||
|
@ -20,8 +20,11 @@
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/cmn/stdio.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include <qse/cmn/opt.h>
|
||||
#include <qse/cmn/mem.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
@ -43,7 +46,17 @@ static void set_intr_run (void);
|
||||
static void unset_intr_run (void);
|
||||
|
||||
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
|
||||
{
|
||||
@ -237,247 +250,142 @@ static void unset_intr_run (void)
|
||||
#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 opttab_t
|
||||
struct cmdline_t
|
||||
{
|
||||
const qse_char_t* name;
|
||||
int opt;
|
||||
const qse_char_t* desc;
|
||||
} opttab[] =
|
||||
{
|
||||
{ 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 }
|
||||
qse_char_t* ins;
|
||||
qse_char_t* inf;
|
||||
qse_char_t* outf;
|
||||
qse_char_t* fs;
|
||||
};
|
||||
|
||||
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;
|
||||
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++)
|
||||
static qse_opt_t opt =
|
||||
{
|
||||
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[])
|
||||
{
|
||||
MyAwk awk;
|
||||
MyAwk::Run* run;
|
||||
|
||||
int mode = 0;
|
||||
const qse_char_t* srcin = QSE_T("");
|
||||
const qse_char_t* srcout = NULL;
|
||||
qse_size_t nsrcins = 0;
|
||||
qse_size_t nsrcouts = 0;
|
||||
cmdline_t cmdline;
|
||||
int n;
|
||||
|
||||
if (awk.open() <= -1)
|
||||
{
|
||||
print_error (awk.getErrorMessage());
|
||||
print_error (QSE_T("%s\n"), awk.getErrorMessage());
|
||||
return -1;
|
||||
}
|
||||
|
||||
awk.setOption (awk.getOption() | awk.OPT_INCLUDE);
|
||||
|
||||
// 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 ();
|
||||
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 ();
|
||||
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)
|
||||
{
|
||||
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.close ();
|
||||
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;
|
||||
|
||||
MyAwk::Value ret;
|
||||
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.close ();
|
||||
return -1;
|
||||
|
Loading…
Reference in New Issue
Block a user