fixed bugs in handling @include

This commit is contained in:
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.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;