fixed bugs in handling @include

This commit is contained in:
hyung-hwan 2009-08-10 21:29:59 +00:00
parent 8059913da3
commit 9eb2c2da4c
11 changed files with 252 additions and 91 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: Awk.hpp 249 2009-08-07 13:35:24Z hyunghwan.chung $
* $Id: Awk.hpp 250 2009-08-10 03:29:59Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -275,17 +275,15 @@ public:
* The Awk::Source::Data class is used to deliver information
* needed for source script I/O.
*/
class Data: protected qse_awk_sio_arg_t
class Data: protected sio_arg_t
{
public:
friend class Awk;
protected:
Data (Awk* awk, Mode mode):
awk (awk), mode (mode)
Data (Awk* awk, Mode mode, sio_arg_t* arg):
awk (awk), mode (mode), arg (arg)
{
this->name = QSE_NULL;
this->handle = QSE_NULL;
}
public:
@ -296,17 +294,17 @@ public:
const char_t* getName() const
{
return this->name;
return arg->name;
}
const void* getHandle () const
{
return this->handle;
return arg->handle;
}
void setHandle (void* handle)
{
this->handle = handle;
arg->handle = handle;
}
operator Awk* () const
@ -322,6 +320,7 @@ public:
protected:
Awk* awk;
Mode mode;
sio_arg_t* arg;
};
Source () {}
@ -1090,9 +1089,6 @@ protected:
map_t* functionMap;
Source::Data sourceIn;
Source::Data sourceOut;
Source* sourceReader;
Source* sourceWriter;

View File

@ -1,5 +1,5 @@
/*
* $Id: StdAwk.hpp 235 2009-07-15 10:43:31Z hyunghwan.chung $
* $Id: StdAwk.hpp 250 2009-08-10 03:29:59Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -45,7 +45,10 @@ public:
class SourceFile: public Source
{
public:
SourceFile (const char_t* name): name (name) {}
SourceFile (const char_t* name): name (name)
{
dir.ptr = QSE_NULL; dir.len = 0;
}
int open (Data& io);
int close (Data& io);
@ -54,6 +57,7 @@ public:
protected:
const char_t* name;
qse_cstr_t dir;
};
class SourceString: public Source

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.h 249 2009-08-07 13:35:24Z hyunghwan.chung $
* $Id: awk.h 250 2009-08-10 03:29:59Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -271,12 +271,21 @@ enum qse_awk_sio_cmd_t
};
typedef enum qse_awk_sio_cmd_t qse_awk_sio_cmd_t;
typedef struct qse_awk_sio_lxc_t qse_awk_sio_lxc_t;
struct qse_awk_sio_lxc_t
{
qse_cint_t c;
qse_size_t lin;
qse_size_t col;
const qse_char_t* file;
};
struct qse_awk_sio_arg_t
{
const qse_char_t* name; /**< [IN] name of I/O object */
void* handle; /**< [OUT] I/O handle set by a handler */
/*-- from here down, internal use only --*/
/*-- from here down, internal use only --*/
struct
{
qse_char_t buf[1024];
@ -287,6 +296,7 @@ struct qse_awk_sio_arg_t
qse_size_t lin;
qse_size_t col;
qse_awk_sio_lxc_t last;
struct qse_awk_sio_arg_t* next;
};
typedef struct qse_awk_sio_arg_t qse_awk_sio_arg_t;

View File

@ -1,5 +1,5 @@
/*
* $Id: Awk.cpp 249 2009-08-07 13:35:24Z hyunghwan.chung $
* $Id: Awk.cpp 250 2009-08-10 03:29:59Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -995,9 +995,7 @@ int Awk::Run::getGlobal (int id, Value& g) const
// Awk
//////////////////////////////////////////////////////////////////
Awk::Awk () : awk (QSE_NULL), functionMap (QSE_NULL),
sourceIn (this, Source::READ), sourceOut (this, Source::WRITE),
runctx (this)
Awk::Awk () : awk (QSE_NULL), functionMap (QSE_NULL), runctx (this)
{
errinf.num = (errnum_t)ERR_NOERR;
@ -1608,16 +1606,16 @@ Awk::ssize_t Awk::readSource (
char_t* data, size_t count)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
Source::Data sdat (xtn->awk, Source::READ, arg);
switch (cmd)
{
case QSE_AWK_SIO_OPEN:
xtn->awk->sourceIn.name = arg->name;
return xtn->awk->sourceReader->open (xtn->awk->sourceIn);
return xtn->awk->sourceReader->open (sdat);
case QSE_AWK_SIO_CLOSE:
return xtn->awk->sourceReader->close (xtn->awk->sourceIn);
return xtn->awk->sourceReader->close (sdat);
case QSE_AWK_SIO_READ:
return xtn->awk->sourceReader->read (xtn->awk->sourceIn, data, count);
return xtn->awk->sourceReader->read (sdat, data, count);
default:
return -1;
}
@ -1628,16 +1626,16 @@ Awk::ssize_t Awk::writeSource (
char_t* data, size_t count)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
Source::Data sdat (xtn->awk, Source::WRITE, arg);
switch (cmd)
{
case QSE_AWK_SIO_OPEN:
xtn->awk->sourceOut.name = arg->name;
return xtn->awk->sourceWriter->open (xtn->awk->sourceOut);
return xtn->awk->sourceWriter->open (sdat);
case QSE_AWK_SIO_CLOSE:
return xtn->awk->sourceWriter->close (xtn->awk->sourceOut);
return xtn->awk->sourceWriter->close (sdat);
case QSE_AWK_SIO_WRITE:
return xtn->awk->sourceWriter->write (xtn->awk->sourceOut, data, count);
return xtn->awk->sourceWriter->write (sdat, data, count);
default:
return -1;
}

View File

@ -1,5 +1,5 @@
/*
* $Id: StdAwk.cpp 241 2009-07-22 12:47:13Z hyunghwan.chung $
* $Id: StdAwk.cpp 250 2009-08-10 03:29:59Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -778,22 +778,78 @@ int StdAwk::vsprintf (
int StdAwk::SourceFile::open (Data& io)
{
qse_sio_t* sio;
const qse_char_t* ioname = io.getName();
if (name[0] == QSE_T('-') &&
name[1] == QSE_T('\0'))
if (ioname == QSE_NULL)
{
sio = (io.getMode() == READ)? qse_sio_in: qse_sio_out;
if (name[0] == QSE_T('-') && name[1] == QSE_T('\0'))
{
sio = (io.getMode() == READ)? qse_sio_in: qse_sio_out;
}
else
{
const qse_char_t* base;
sio = qse_sio_open (
((awk_t*)io)->mmgr,
0,
name,
(io.getMode() == READ?
QSE_SIO_READ:
(QSE_SIO_WRITE|QSE_SIO_CREATE|QSE_SIO_TRUNCATE))
);
if (sio == QSE_NULL) return -1;
base = qse_awk_basename ((awk_t*)io, name);
if (base != name)
{
dir.ptr = name;
dir.len = base - name;
}
}
}
else
{
const char_t* file = name;
char_t fbuf[64];
char_t* dbuf = QSE_NULL;
if (dir.len > 0)
{
size_t tmplen, totlen;
totlen = qse_strlen(ioname) + dir.len;
if (totlen >= QSE_COUNTOF(fbuf))
{
dbuf = (qse_char_t*) QSE_MMGR_ALLOC (
((awk_t*)io)->mmgr,
QSE_SIZEOF(qse_char_t) * (totlen + 1)
);
if (dbuf == QSE_NULL)
{
((Awk*)io)->setError (ERR_NOMEM);
return -1;
}
file = dbuf;
}
else file = fbuf;
tmplen = qse_strncpy (
(char_t*)file, dir.ptr, dir.len);
qse_strcpy ((char_t*)file + tmplen, ioname);
}
sio = qse_sio_open (
((awk_t*)io)->mmgr,
0,
name,
file,
(io.getMode() == READ?
QSE_SIO_READ:
(QSE_SIO_WRITE|QSE_SIO_CREATE|QSE_SIO_TRUNCATE))
);
if (dbuf != QSE_NULL) QSE_MMGR_FREE (((awk_t*)io)->mmgr, dbuf);
if (sio == QSE_NULL) return -1;
}
@ -827,27 +883,67 @@ StdAwk::ssize_t StdAwk::SourceFile::write (Data& io, char_t* buf, size_t len)
int StdAwk::SourceString::open (Data& io)
{
/* SourceString does not support writing */
if (io.getMode() == WRITE) return -1;
ptr = str;
qse_sio_t* sio;
const char_t* ioname = io.getName();
if (ioname == QSE_NULL)
{
/* SourceString does not support writing */
if (io.getMode() == WRITE) return -1;
ptr = str;
}
else
{
/* open an included file */
sio = qse_sio_open (
((awk_t*)io)->mmgr,
0,
ioname,
(io.getMode() == READ?
QSE_SIO_READ:
(QSE_SIO_WRITE|QSE_SIO_CREATE|QSE_SIO_TRUNCATE))
);
if (sio == QSE_NULL) return -1;
io.setHandle (sio);
}
return 1;
}
int StdAwk::SourceString::close (Data& io)
{
if (io.getName() != QSE_NULL)
qse_sio_close ((qse_sio_t*)io.getHandle());
return 0;
}
StdAwk::ssize_t StdAwk::SourceString::read (Data& io, char_t* buf, size_t len)
{
qse_size_t n = 0;
while (*ptr != QSE_T('\0') && n < len) buf[n++] = *ptr++;
return n;
if (io.getName() == QSE_NULL)
{
qse_size_t n = 0;
while (*ptr != QSE_T('\0') && n < len) buf[n++] = *ptr++;
return n;
}
else
{
return qse_sio_getsn ((qse_sio_t*)io.getHandle(), buf, len);
}
}
StdAwk::ssize_t StdAwk::SourceString::write (Data& io, char_t* buf, size_t len)
{
return -1;
if (io.getName() == QSE_NULL)
{
return -1;
}
else
{
// in fact, this block will never be reached as
// there is no included file concept for deparsing
return qse_sio_putsn ((qse_sio_t*)io.getHandle(), buf, len);
}
}
/////////////////////////////////

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.h 248 2009-08-06 08:27:14Z hyunghwan.chung $
* $Id: awk.h 250 2009-08-10 03:29:59Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -106,15 +106,6 @@ struct qse_awk_token_t
qse_size_t col;
};
typedef struct qse_awk_lxc_t qse_awk_lxc_t;
struct qse_awk_lxc_t
{
qse_cint_t c;
qse_size_t lin;
qse_size_t col;
const qse_char_t* file;
};
struct qse_awk_t
{
QSE_DEFINE_COMMON_FIELDS (sed)
@ -186,10 +177,10 @@ struct qse_awk_t
qse_awk_sio_fun_t inf;
qse_awk_sio_fun_t outf;
qse_awk_lxc_t last;
qse_awk_sio_lxc_t last;
qse_size_t nungots;
qse_awk_lxc_t ungot[5];
qse_awk_sio_lxc_t ungot[5];
qse_awk_sio_arg_t arg; /* for the top level source */
qse_awk_sio_arg_t* inp; /* current input */

View File

@ -1,5 +1,5 @@
/*
* $Id: misc.c 237 2009-07-16 12:43:47Z hyunghwan.chung $
* $Id: misc.c 250 2009-08-10 03:29:59Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -999,3 +999,17 @@ void qse_awk_rtx_free (qse_awk_rtx_t* rtx, void* ptr)
qse_awk_free (rtx->awk, ptr);
}
const qse_char_t* qse_awk_basename (qse_awk_t* awk, const qse_char_t* path)
{
const qse_char_t* p, * last = QSE_NULL;
for (p = path; *p != QSE_T('\0'); p++)
{
if (*p == QSE_T('/')) last = p;
#ifdef _WIN32
else if (*p == QSE_T('\\')) last = p;
#endif
}
return (last == QSE_NULL)? path: (last + 1);
}

View File

@ -1,5 +1,5 @@
/*
* $Id: misc.h 171 2009-06-01 09:34:34Z hyunghwan.chung $
* $Id: misc.h 250 2009-08-10 03:29:59Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -67,6 +67,11 @@ int qse_awk_matchrex (
qse_cstr_t* match, qse_awk_errnum_t* errnum
);
const qse_char_t* qse_awk_basename (
qse_awk_t* awk,
const qse_char_t* path
);
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/*
* $Id: parse.c 248 2009-08-06 08:27:14Z hyunghwan.chung $
* $Id: parse.c 250 2009-08-10 03:29:59Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -398,11 +398,7 @@ static int get_char (qse_awk_t* awk)
if (awk->sio.nungots > 0)
{
/* there are something in the unget buffer */
QSE_MEMCPY (
&awk->sio.last,
&awk->sio.ungot[--awk->sio.nungots],
QSE_SIZEOF(awk->sio.last)
);
awk->sio.last = awk->sio.ungot[--awk->sio.nungots];
return 0;
}
@ -433,31 +429,28 @@ static int get_char (qse_awk_t* awk)
awk->sio.inp->b.len = n;
}
awk->sio.last.c = awk->sio.inp->b.buf[awk->sio.inp->b.pos++];
awk->sio.last.lin = awk->sio.inp->lin;
awk->sio.last.col = awk->sio.inp->col;
awk->sio.last.file = awk->sio.inp->name;
awk->sio.inp->last.c = awk->sio.inp->b.buf[awk->sio.inp->b.pos++];
awk->sio.inp->last.lin = awk->sio.inp->lin;
awk->sio.inp->last.col = awk->sio.inp->col;
awk->sio.inp->last.file = awk->sio.inp->name;
if (awk->sio.last.c == QSE_T('\n'))
if (awk->sio.inp->last.c == QSE_T('\n'))
{
awk->sio.inp->lin++;
awk->sio.inp->col = 1;
}
else awk->sio.inp->col++;
awk->sio.last = awk->sio.inp->last;
return 0;
}
static void unget_char (qse_awk_t* awk, const qse_awk_lxc_t* c)
static void unget_char (qse_awk_t* awk, const qse_awk_sio_lxc_t* c)
{
/* Make sure that the unget buffer is large enough */
QSE_ASSERTX (awk->sio.nungots < QSE_COUNTOF(awk->sio.ungot),
"Make sure that you have increased the size of sio.ungot large enough");
QSE_MEMCPY (
&awk->sio.ungot[awk->sio.nungots++],
c, QSE_SIZEOF(*c)
);
awk->sio.ungot[awk->sio.nungots++] = *c;
}
const qse_char_t* qse_awk_getgblname (
@ -762,8 +755,8 @@ static int end_include (qse_awk_t* awk)
static qse_awk_t* parse_progunit (qse_awk_t* awk)
{
/*
@include "xxxx"
global xxx, xxxx;
include "xxxx";
BEGIN { action }
END { action }
pattern { action }
@ -5132,16 +5125,16 @@ static int skip_spaces (qse_awk_t* awk)
if (c == QSE_T('\\'))
{
qse_awk_lxc_t bs;
qse_awk_lxc_t cr;
qse_awk_sio_lxc_t bs;
qse_awk_sio_lxc_t cr;
int hascr = 0;
QSE_MEMCPY (&bs, &awk->sio.last, QSE_SIZEOF(bs));
bs = awk->sio.last;
GET_CHAR_TO (awk, c);
if (c == QSE_T('\r'))
{
hascr = 1;
QSE_MEMCPY (&cr, &awk->sio.last, QSE_SIZEOF(cr));
cr = awk->sio.last;
GET_CHAR_TO (awk, c);
}
@ -5157,7 +5150,7 @@ static int skip_spaces (qse_awk_t* awk)
/* push CR if any */
if (hascr) unget_char (awk, &cr);
/* restore the orginal backslash */
QSE_MEMCPY (&awk->sio.last, &bs, QSE_SIZEOF(bs));
awk->sio.last = bs;
}
}
@ -5176,7 +5169,7 @@ static int skip_spaces (qse_awk_t* awk)
static int skip_comment (qse_awk_t* awk)
{
qse_cint_t c = awk->sio.last.c;
qse_awk_lxc_t lc;
qse_awk_sio_lxc_t lc;
if (c == QSE_T('#'))
{
@ -5192,7 +5185,7 @@ static int skip_comment (qse_awk_t* awk)
if (c != QSE_T('/')) return 0; /* not a comment */
/* save the last character */
QSE_MEMCPY (&lc, &awk->sio.last, QSE_SIZEOF(lc));
lc = awk->sio.last;
/* read a new character */
GET_CHAR_TO (awk, c);
@ -5232,7 +5225,7 @@ static int skip_comment (qse_awk_t* awk)
/* unget '*' */
unget_char (awk, &awk->sio.last);
/* restore the previous state */
QSE_MEMCPY (&awk->sio.last, &lc, QSE_SIZEOF(lc));
awk->sio.last = lc;
return 0;
}
@ -5359,7 +5352,11 @@ retry:
{
n = end_include (awk);
if (n <= -1) return -1;
if (n >= 1) goto retry;
if (n >= 1)
{
awk->sio.last = awk->sio.inp->last;
goto retry;
}
ADD_TOKEN_STR (awk, token, QSE_T("<EOF>"), 5);
SET_TOKEN_TYPE (awk, token, TOKEN_EOF);
@ -5377,9 +5374,9 @@ retry:
}
else if (c == QSE_T('.'))
{
qse_awk_lxc_t lc;
qse_awk_sio_lxc_t lc;
QSE_MEMCPY (&lc, &awk->sio.last, QSE_SIZEOF(lc));
lc = awk->sio.last;
GET_CHAR_TO (awk, c);
if (!(awk->option & QSE_AWK_EXPLICIT) &&
@ -5387,7 +5384,7 @@ retry:
{
/* for a token such as .123 */
unget_char (awk, &awk->sio.last);
QSE_MEMCPY (&awk->sio.last, &lc, QSE_SIZEOF(lc));
awk->sio.last = lc;
if (get_number (awk, token) <= -1) return -1;
}

View File

@ -1,5 +1,5 @@
/*
* $Id: std.c 247 2009-07-31 13:01:04Z hyunghwan.chung $
* $Id: std.c 250 2009-08-10 03:29:59Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -45,6 +45,7 @@ typedef struct xtn_t
const qse_char_t* end;
} cpl;
} u;
qse_cstr_t dir;
qse_sio_t* handle; /* the handle to an open file */
} in;
@ -173,6 +174,8 @@ static qse_ssize_t sf_in_open (
}
else
{
const qse_char_t* base;
xtn->s.in.handle = qse_sio_open (
awk->mmgr,
0,
@ -190,6 +193,13 @@ static qse_ssize_t sf_in_open (
);
return -1;
}
base = qse_awk_basename (awk, xtn->s.in.u.file);
if (base != xtn->s.in.u.file)
{
xtn->s.in.dir.ptr = xtn->s.in.u.file;
xtn->s.in.dir.len = base - xtn->s.in.u.file;
}
}
return 1;
@ -208,11 +218,45 @@ static qse_ssize_t sf_in_open (
}
else
{
/* TODO: standard include path */
const qse_char_t* file = arg->name;
qse_char_t fbuf[64];
qse_char_t* dbuf = QSE_NULL;
if (xtn->s.in.dir.len > 0)
{
qse_size_t tmplen, totlen;
totlen = qse_strlen(arg->name) + xtn->s.in.dir.len;
if (totlen >= QSE_COUNTOF(fbuf))
{
dbuf = QSE_MMGR_ALLOC (
awk->mmgr,
QSE_SIZEOF(qse_char_t) * (totlen + 1)
);
if (dbuf == QSE_NULL)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM);
return -1;
}
file = dbuf;
}
else file = fbuf;
tmplen = qse_strncpy (
(qse_char_t*)file,
xtn->s.in.dir.ptr,
xtn->s.in.dir.len
);
qse_strcpy ((qse_char_t*)file + tmplen, arg->name);
}
arg->handle = qse_sio_open (
awk->mmgr, 0, arg->name, QSE_SIO_READ
awk->mmgr, 0, file, QSE_SIO_READ
);
if (arg->handle == QSE_NULL)
if (dbuf != QSE_NULL) QSE_MMGR_FREE (awk->mmgr, dbuf);
if (arg->handle == QSE_NULL)
{
qse_cstr_t ea;
ea.ptr = arg->name;

View File

@ -1,5 +1,5 @@
/*
* $Id: awk04.c 211 2009-06-24 09:50:10Z hyunghwan.chung $
* $Id: awk04.c 250 2009-08-10 03:29:59Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -33,7 +33,7 @@ int main ()
qse_size_t len;
qse_awk_val_t* v;
qse_awk_val_t* arg[2] = { QSE_NULL, QSE_NULL };
int ret, i;
int ret, i, opt;
/* create a main processor */
awk = qse_awk_openstd (0);
@ -43,8 +43,14 @@ int main ()
ret = -1; goto oops;
}
opt = qse_awk_getoption(awk);
/* don't allow BEGIN, END, pattern-action blocks */
qse_awk_setoption (awk, qse_awk_getoption(awk) & ~QSE_AWK_PABLOCK);
opt &= ~QSE_AWK_PABLOCK;
/* enable ** */
opt |= QSE_AWK_EXTRAOPS;
qse_awk_setoption (awk, opt);
psin.type = QSE_AWK_PARSESTD_CP;
psin.u.cp = src;