added QSE_SIO_KEEPPATH and qse_sio_getpath().
fixed a file inclusion bug in awk and xli
This commit is contained in:
parent
8bc5ea07e3
commit
639391d887
@ -207,21 +207,19 @@ public:
|
|||||||
return this->mode;
|
return this->mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getFlags () const
|
|
||||||
{
|
|
||||||
return arg->flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char_t* getName() const
|
const char_t* getName() const
|
||||||
{
|
{
|
||||||
return this->arg->name;
|
return this->arg->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// since it doesn't copy the contents,
|
const char_t* getPrevName() const
|
||||||
// it should point to something that outlives this object.
|
|
||||||
void setName (const char_t* name)
|
|
||||||
{
|
{
|
||||||
this->arg->name = name;
|
return this->arg->prev->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const void* getPrevHandle() const
|
||||||
|
{
|
||||||
|
return this->arg->prev->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* getHandle () const
|
void* getHandle () const
|
||||||
|
@ -505,21 +505,10 @@ enum qse_awk_sio_arg_flag_t
|
|||||||
typedef struct qse_awk_sio_arg_t qse_awk_sio_arg_t;
|
typedef struct qse_awk_sio_arg_t qse_awk_sio_arg_t;
|
||||||
struct qse_awk_sio_arg_t
|
struct qse_awk_sio_arg_t
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* [IN] bitwise-ORed of #qse_awk_sio_arg_flag_t.
|
|
||||||
* The field is set with #QSE_AWK_SIO_INCLUDED if an included file
|
|
||||||
* is handled.
|
|
||||||
*/
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [IN/OUT] name of I/O object.
|
* [IN/OUT] name of I/O object.
|
||||||
* if #QSE_AWK_SIO_INCLUDED is not set, the name is set to #QSE_NULL.
|
* It is #QSE_NULL for the top-level stream. It points to a stream name
|
||||||
* the source stream handler(#qse_awk_sio_impl_t) can change this field
|
* for an included stream.
|
||||||
* to give useful information back to the parser.
|
|
||||||
*
|
|
||||||
* if #QSE_AWK_SIO_INCLUDED is set in the flags field,
|
|
||||||
* the name field is set to the name of the included file.
|
|
||||||
*/
|
*/
|
||||||
const qse_char_t* name;
|
const qse_char_t* name;
|
||||||
|
|
||||||
@ -531,6 +520,12 @@ struct qse_awk_sio_arg_t
|
|||||||
*/
|
*/
|
||||||
void* handle;
|
void* handle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [IN] points to the includer. #QSE_NULL for the toplevel.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
qse_awk_sio_arg_t* prev;
|
||||||
|
|
||||||
/*-- from here down, internal use only --*/
|
/*-- from here down, internal use only --*/
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -543,7 +538,6 @@ struct qse_awk_sio_arg_t
|
|||||||
qse_size_t colm;
|
qse_size_t colm;
|
||||||
|
|
||||||
qse_awk_sio_lxc_t last;
|
qse_awk_sio_lxc_t last;
|
||||||
qse_awk_sio_arg_t* next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,6 +38,7 @@ enum qse_sio_flag_t
|
|||||||
* the range is represented by QSE_FIO_RESERVED. */
|
* the range is represented by QSE_FIO_RESERVED. */
|
||||||
QSE_SIO_IGNOREMBWCERR = (1 << 1),
|
QSE_SIO_IGNOREMBWCERR = (1 << 1),
|
||||||
QSE_SIO_NOAUTOFLUSH = (1 << 2),
|
QSE_SIO_NOAUTOFLUSH = (1 << 2),
|
||||||
|
QSE_SIO_KEEPPATH = (1 << 3),
|
||||||
|
|
||||||
/* ensure that the following enumerators are one of
|
/* ensure that the following enumerators are one of
|
||||||
* qse_fio_flags_t enumerators */
|
* qse_fio_flags_t enumerators */
|
||||||
@ -112,6 +113,8 @@ struct qse_sio_t
|
|||||||
qse_mchar_t inbuf[2048];
|
qse_mchar_t inbuf[2048];
|
||||||
qse_mchar_t outbuf[2048];
|
qse_mchar_t outbuf[2048];
|
||||||
|
|
||||||
|
qse_char_t* path;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
int status;
|
int status;
|
||||||
#endif
|
#endif
|
||||||
@ -195,6 +198,15 @@ QSE_EXPORT qse_ubi_t qse_sio_gethandleasubi (
|
|||||||
const qse_sio_t* sio
|
const qse_sio_t* sio
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_sio_getpath() returns the file path used to open the stream.
|
||||||
|
* It returns #QSE_NULL if #QSE_SIO_HANDLE was on or #QSE_SIO_KEEPPATH
|
||||||
|
* was off at the time of opening.
|
||||||
|
*/
|
||||||
|
QSE_EXPORT const qse_char_t* qse_sio_getpath (
|
||||||
|
qse_sio_t* sio
|
||||||
|
);
|
||||||
|
|
||||||
QSE_EXPORT qse_ssize_t qse_sio_flush (
|
QSE_EXPORT qse_ssize_t qse_sio_flush (
|
||||||
qse_sio_t* sio
|
qse_sio_t* sio
|
||||||
);
|
);
|
||||||
|
@ -614,6 +614,12 @@ typedef int qse_mcint_t;
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct qse_link_t qse_link_t;
|
||||||
|
struct qse_link_t
|
||||||
|
{
|
||||||
|
qse_link_t* link;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_mxstr_t type defines a structure combining a pointer to a character
|
* The qse_mxstr_t type defines a structure combining a pointer to a character
|
||||||
* string and the number of characters. It is designed to be interchangeable
|
* string and the number of characters. It is designed to be interchangeable
|
||||||
|
@ -227,29 +227,13 @@ struct qse_xli_io_lxc_t
|
|||||||
const qse_char_t* file; /**< file */
|
const qse_char_t* file; /**< file */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum qse_xli_io_arg_flag_t
|
|
||||||
{
|
|
||||||
QSE_XLI_IO_INCLUDED = (1 << 0)
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct qse_xli_io_arg_t qse_xli_io_arg_t;
|
typedef struct qse_xli_io_arg_t qse_xli_io_arg_t;
|
||||||
struct qse_xli_io_arg_t
|
struct qse_xli_io_arg_t
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* [IN] bitwise-ORed of #qse_xli_io_arg_flag_t.
|
* [IN] name of I/O object.
|
||||||
* The field is set with #QSE_XLI_SIO_INCLUDED if an included file
|
* It is #QSE_NULL for the top-level stream. It points to a stream name
|
||||||
* is handled.
|
* for an included stream.
|
||||||
*/
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [IN/OUT] name of I/O object.
|
|
||||||
* if #QSE_XLI_SIO_INCLUDED is not set, the name is set to #QSE_NULL.
|
|
||||||
* the source stream handler(#qse_xli_io_impl_t) can change this field
|
|
||||||
* to give useful information back to the parser.
|
|
||||||
*
|
|
||||||
* if #QSE_XLI_SIO_INCLUDED is set in the flags field,
|
|
||||||
* the name field is set to the name of the included file.
|
|
||||||
*/
|
*/
|
||||||
const qse_char_t* name;
|
const qse_char_t* name;
|
||||||
|
|
||||||
@ -261,6 +245,11 @@ struct qse_xli_io_arg_t
|
|||||||
*/
|
*/
|
||||||
void* handle;
|
void* handle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [IN] points to the includer
|
||||||
|
*/
|
||||||
|
qse_xli_io_arg_t* prev;
|
||||||
|
|
||||||
/*-- from here down, internal use only --*/
|
/*-- from here down, internal use only --*/
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -273,7 +262,6 @@ struct qse_xli_io_arg_t
|
|||||||
qse_size_t colm;
|
qse_size_t colm;
|
||||||
|
|
||||||
qse_xli_io_lxc_t last;
|
qse_xli_io_lxc_t last;
|
||||||
qse_xli_io_arg_t* next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1500,7 +1500,7 @@ int StdAwk::SourceFile::open (Data& io)
|
|||||||
{
|
{
|
||||||
qse_sio_t* sio;
|
qse_sio_t* sio;
|
||||||
|
|
||||||
if (!(io.getFlags() & QSE_AWK_SIO_INCLUDED))
|
if (io.getName() == QSE_NULL)
|
||||||
{
|
{
|
||||||
// open the main source file.
|
// open the main source file.
|
||||||
|
|
||||||
@ -1519,32 +1519,23 @@ int StdAwk::SourceFile::open (Data& io)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const qse_char_t* base;
|
|
||||||
|
|
||||||
sio = open_sio (
|
sio = open_sio (
|
||||||
io, QSE_NULL, this->name,
|
io, QSE_NULL, this->name,
|
||||||
(io.getMode() == READ?
|
(io.getMode() == READ?
|
||||||
(QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR):
|
(QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR | QSE_SIO_KEEPPATH):
|
||||||
(QSE_SIO_WRITE | QSE_SIO_CREATE |
|
(QSE_SIO_WRITE | QSE_SIO_CREATE |
|
||||||
QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR))
|
QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR))
|
||||||
);
|
);
|
||||||
if (sio == QSE_NULL) return -1;
|
if (sio == QSE_NULL) return -1;
|
||||||
|
|
||||||
if (this->cmgr) qse_sio_setcmgr (sio, this->cmgr);
|
|
||||||
base = qse_basename (this->name);
|
|
||||||
if (base != this->name)
|
|
||||||
{
|
|
||||||
dir.ptr = this->name;
|
|
||||||
dir.len = base - this->name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
io.setName (this->name);
|
if (this->cmgr) qse_sio_setcmgr (sio, this->cmgr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// open an included file
|
// open an included file
|
||||||
const char_t* ioname, * file;
|
const char_t* ioname, * file, * outer;
|
||||||
char_t fbuf[64];
|
char_t fbuf[64];
|
||||||
char_t* dbuf = QSE_NULL;
|
char_t* dbuf = QSE_NULL;
|
||||||
|
|
||||||
@ -1552,11 +1543,18 @@ int StdAwk::SourceFile::open (Data& io)
|
|||||||
QSE_ASSERT (ioname != QSE_NULL);
|
QSE_ASSERT (ioname != QSE_NULL);
|
||||||
|
|
||||||
file = ioname;
|
file = ioname;
|
||||||
if (dir.len > 0 && ioname[0] != QSE_T('/'))
|
outer = qse_sio_getpath ((qse_sio_t*)io.getPrevHandle());
|
||||||
|
if (outer)
|
||||||
{
|
{
|
||||||
size_t tmplen, totlen;
|
const qse_char_t* base;
|
||||||
|
|
||||||
totlen = qse_strlen(ioname) + dir.len;
|
base = qse_basename (outer);
|
||||||
|
if (base != outer && ioname[0] != QSE_T('/'))
|
||||||
|
{
|
||||||
|
size_t tmplen, totlen, dirlen;
|
||||||
|
|
||||||
|
dirlen = base - outer;
|
||||||
|
totlen = qse_strlen(ioname) + dirlen;
|
||||||
if (totlen >= QSE_COUNTOF(fbuf))
|
if (totlen >= QSE_COUNTOF(fbuf))
|
||||||
{
|
{
|
||||||
dbuf = (qse_char_t*) QSE_MMGR_ALLOC (
|
dbuf = (qse_char_t*) QSE_MMGR_ALLOC (
|
||||||
@ -1573,14 +1571,15 @@ int StdAwk::SourceFile::open (Data& io)
|
|||||||
}
|
}
|
||||||
else file = fbuf;
|
else file = fbuf;
|
||||||
|
|
||||||
tmplen = qse_strncpy ((char_t*)file, dir.ptr, dir.len);
|
tmplen = qse_strncpy ((char_t*)file, outer, dirlen);
|
||||||
qse_strcpy ((char_t*)file + tmplen, ioname);
|
qse_strcpy ((char_t*)file + tmplen, ioname);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sio = open_sio (
|
sio = open_sio (
|
||||||
io, QSE_NULL, file,
|
io, QSE_NULL, file,
|
||||||
(io.getMode() == READ?
|
(io.getMode() == READ?
|
||||||
(QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR):
|
(QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR | QSE_SIO_KEEPPATH):
|
||||||
(QSE_SIO_WRITE | QSE_SIO_CREATE |
|
(QSE_SIO_WRITE | QSE_SIO_CREATE |
|
||||||
QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR))
|
QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR))
|
||||||
);
|
);
|
||||||
@ -1615,7 +1614,7 @@ int StdAwk::SourceString::open (Data& io)
|
|||||||
{
|
{
|
||||||
qse_sio_t* sio;
|
qse_sio_t* sio;
|
||||||
|
|
||||||
if (!(io.getFlags() & QSE_AWK_SIO_INCLUDED))
|
if (io.getName() == QSE_NULL)
|
||||||
{
|
{
|
||||||
// open the main source file.
|
// open the main source file.
|
||||||
// SourceString does not support writing.
|
// SourceString does not support writing.
|
||||||
|
@ -151,15 +151,6 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_awk_prm_t* pr
|
|||||||
if (init_token (mmgr, &awk->tok) == -1) goto oops;
|
if (init_token (mmgr, &awk->tok) == -1) goto oops;
|
||||||
if (init_token (mmgr, &awk->ntok) == -1) goto oops;
|
if (init_token (mmgr, &awk->ntok) == -1) goto oops;
|
||||||
|
|
||||||
awk->sio_names = qse_htb_open (
|
|
||||||
mmgr, QSE_SIZEOF(awk), 128, 70, QSE_SIZEOF(qse_char_t), 1
|
|
||||||
);
|
|
||||||
if (awk->sio_names == QSE_NULL) goto oops;
|
|
||||||
*(qse_awk_t**)QSE_XTN(awk->sio_names) = awk;
|
|
||||||
qse_htb_setstyle (awk->sio_names,
|
|
||||||
qse_gethtbstyle(QSE_HTB_STYLE_INLINE_KEY_COPIER)
|
|
||||||
);
|
|
||||||
|
|
||||||
/* TODO: initial map size?? */
|
/* TODO: initial map size?? */
|
||||||
awk->tree.funs = qse_htb_open (
|
awk->tree.funs = qse_htb_open (
|
||||||
mmgr, QSE_SIZEOF(awk), 512, 70, QSE_SIZEOF(qse_char_t), 1
|
mmgr, QSE_SIZEOF(awk), 512, 70, QSE_SIZEOF(qse_char_t), 1
|
||||||
@ -256,7 +247,6 @@ oops:
|
|||||||
if (awk->parse.named) qse_htb_close (awk->parse.named);
|
if (awk->parse.named) qse_htb_close (awk->parse.named);
|
||||||
if (awk->parse.funs) qse_htb_close (awk->parse.funs);
|
if (awk->parse.funs) qse_htb_close (awk->parse.funs);
|
||||||
if (awk->tree.funs) qse_htb_close (awk->tree.funs);
|
if (awk->tree.funs) qse_htb_close (awk->tree.funs);
|
||||||
if (awk->sio_names) qse_htb_close (awk->sio_names);
|
|
||||||
fini_token (&awk->ntok);
|
fini_token (&awk->ntok);
|
||||||
fini_token (&awk->tok);
|
fini_token (&awk->tok);
|
||||||
fini_token (&awk->ptok);
|
fini_token (&awk->ptok);
|
||||||
@ -286,12 +276,13 @@ int qse_awk_close (qse_awk_t* awk)
|
|||||||
qse_htb_close (awk->parse.funs);
|
qse_htb_close (awk->parse.funs);
|
||||||
|
|
||||||
qse_htb_close (awk->tree.funs);
|
qse_htb_close (awk->tree.funs);
|
||||||
qse_htb_close (awk->sio_names);
|
|
||||||
|
|
||||||
fini_token (&awk->ntok);
|
fini_token (&awk->ntok);
|
||||||
fini_token (&awk->tok);
|
fini_token (&awk->tok);
|
||||||
fini_token (&awk->ptok);
|
fini_token (&awk->ptok);
|
||||||
|
|
||||||
|
qse_awk_clearsionames (awk);
|
||||||
|
|
||||||
/* destroy dynamically allocated options */
|
/* destroy dynamically allocated options */
|
||||||
for (i = 0; i < QSE_COUNTOF(awk->opt.mod); i++)
|
for (i = 0; i < QSE_COUNTOF(awk->opt.mod); i++)
|
||||||
{
|
{
|
||||||
@ -391,9 +382,9 @@ int qse_awk_clear (qse_awk_t* awk)
|
|||||||
awk->tree.chain_size = 0;
|
awk->tree.chain_size = 0;
|
||||||
|
|
||||||
/* this table must not be cleared here as there can be a reference
|
/* this table must not be cleared here as there can be a reference
|
||||||
* to an entry of this table from errinf.fil when qse_awk_parse()
|
* to an entry of this table from errinf.loc.file when qse_awk_parse()
|
||||||
* failed. this table is cleared in qse_awk_parse().
|
* failed. this table is cleared in qse_awk_parse().
|
||||||
* qse_htb_clear (awk->sio_names);
|
* qse_awk_claersionames (awk);
|
||||||
*/
|
*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ struct qse_awk_t
|
|||||||
qse_awk_sio_arg_t arg; /* for the top level source */
|
qse_awk_sio_arg_t arg; /* for the top level source */
|
||||||
qse_awk_sio_arg_t* inp; /* current input argument. */
|
qse_awk_sio_arg_t* inp; /* current input argument. */
|
||||||
} sio;
|
} sio;
|
||||||
qse_htb_t* sio_names;
|
qse_link_t* sio_names;
|
||||||
|
|
||||||
/* previous token */
|
/* previous token */
|
||||||
qse_awk_tok_t ptok;
|
qse_awk_tok_t ptok;
|
||||||
|
@ -605,19 +605,19 @@ oops:
|
|||||||
* closed. close them */
|
* closed. close them */
|
||||||
while (awk->sio.inp != &awk->sio.arg)
|
while (awk->sio.inp != &awk->sio.arg)
|
||||||
{
|
{
|
||||||
qse_awk_sio_arg_t* next;
|
qse_awk_sio_arg_t* prev;
|
||||||
|
|
||||||
/* nothing much to do about a close error */
|
/* nothing much to do about a close error */
|
||||||
awk->sio.inf (
|
awk->sio.inf (
|
||||||
awk, QSE_AWK_SIO_CLOSE,
|
awk, QSE_AWK_SIO_CLOSE,
|
||||||
awk->sio.inp, QSE_NULL, 0);
|
awk->sio.inp, QSE_NULL, 0);
|
||||||
|
|
||||||
next = awk->sio.inp->next;
|
prev = awk->sio.inp->prev;
|
||||||
|
|
||||||
QSE_ASSERT (awk->sio.inp->name != QSE_NULL);
|
QSE_ASSERT (awk->sio.inp->name != QSE_NULL);
|
||||||
QSE_MMGR_FREE (awk->mmgr, awk->sio.inp);
|
QSE_MMGR_FREE (awk->mmgr, awk->sio.inp);
|
||||||
|
|
||||||
awk->sio.inp = next;
|
awk->sio.inp = prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ret == 0)
|
else if (ret == 0)
|
||||||
@ -649,6 +649,17 @@ oops:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qse_awk_clearsionames (qse_awk_t* awk)
|
||||||
|
{
|
||||||
|
qse_link_t* cur;
|
||||||
|
while (awk->sio_names)
|
||||||
|
{
|
||||||
|
cur = awk->sio_names;
|
||||||
|
awk->sio_names = cur->link;
|
||||||
|
QSE_MMGR_FREE (awk->mmgr, cur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int qse_awk_parse (qse_awk_t* awk, qse_awk_sio_t* sio)
|
int qse_awk_parse (qse_awk_t* awk, qse_awk_sio_t* sio)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
@ -667,7 +678,7 @@ int qse_awk_parse (qse_awk_t* awk, qse_awk_sio_t* sio)
|
|||||||
QSE_ASSERT (awk->parse.depth.expr == 0);
|
QSE_ASSERT (awk->parse.depth.expr == 0);
|
||||||
|
|
||||||
qse_awk_clear (awk);
|
qse_awk_clear (awk);
|
||||||
qse_htb_clear (awk->sio_names);
|
qse_awk_clearsionames (awk);
|
||||||
|
|
||||||
QSE_MEMSET (&awk->sio, 0, QSE_SIZEOF(awk->sio));
|
QSE_MEMSET (&awk->sio, 0, QSE_SIZEOF(awk->sio));
|
||||||
awk->sio.inf = sio->in;
|
awk->sio.inf = sio->in;
|
||||||
@ -708,7 +719,7 @@ static int end_include (qse_awk_t* awk)
|
|||||||
* awk->sio.inp again. */
|
* awk->sio.inp again. */
|
||||||
|
|
||||||
cur = awk->sio.inp;
|
cur = awk->sio.inp;
|
||||||
awk->sio.inp = awk->sio.inp->next;
|
awk->sio.inp = awk->sio.inp->prev;
|
||||||
|
|
||||||
QSE_ASSERT (cur->name != QSE_NULL);
|
QSE_ASSERT (cur->name != QSE_NULL);
|
||||||
QSE_MMGR_FREE (awk->mmgr, cur);
|
QSE_MMGR_FREE (awk->mmgr, cur);
|
||||||
@ -728,9 +739,8 @@ static int end_include (qse_awk_t* awk)
|
|||||||
|
|
||||||
static int begin_include (qse_awk_t* awk)
|
static int begin_include (qse_awk_t* awk)
|
||||||
{
|
{
|
||||||
qse_ssize_t op;
|
|
||||||
qse_awk_sio_arg_t* arg = QSE_NULL;
|
qse_awk_sio_arg_t* arg = QSE_NULL;
|
||||||
qse_htb_pair_t* pair = QSE_NULL;
|
qse_link_t* link;
|
||||||
|
|
||||||
if (qse_strlen(QSE_STR_PTR(awk->tok.name)) != QSE_STR_LEN(awk->tok.name))
|
if (qse_strlen(QSE_STR_PTR(awk->tok.name)) != QSE_STR_LEN(awk->tok.name))
|
||||||
{
|
{
|
||||||
@ -746,50 +756,49 @@ static int begin_include (qse_awk_t* awk)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store the file name to awk->sio_names */
|
|
||||||
pair = qse_htb_ensert (
|
|
||||||
awk->sio_names,
|
|
||||||
QSE_STR_PTR(awk->tok.name),
|
|
||||||
QSE_STR_LEN(awk->tok.name) + 1, /* to include '\0' */
|
|
||||||
QSE_NULL, 0
|
|
||||||
);
|
|
||||||
if (pair == QSE_NULL)
|
|
||||||
{
|
|
||||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, &awk->ptok.loc);
|
|
||||||
goto oops;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*QSE_HTB_VPTR(pair) = QSE_HTB_KPTR(pair);
|
|
||||||
QSE_HTB_VLEN(pair) = QSE_HTB_KLEN(pair);*/
|
|
||||||
|
|
||||||
if (awk->opt.incldirs.ptr)
|
if (awk->opt.incldirs.ptr)
|
||||||
{
|
{
|
||||||
/* include directory is set... */
|
/* include directory is set... */
|
||||||
/* TODO: */
|
/* TODO: */
|
||||||
}
|
}
|
||||||
|
|
||||||
arg = (qse_awk_sio_arg_t*) qse_awk_callocmem (awk, QSE_SIZEOF(*arg));
|
/* store the include-file name into a list
|
||||||
|
* and this list is not deleted after qse_awk_parse.
|
||||||
|
* the errinfo.loc.file can point to a string here. */
|
||||||
|
link = (qse_link_t*) qse_awk_callocmem (awk, QSE_SIZEOF(*link) +
|
||||||
|
QSE_SIZEOF(*arg) + QSE_SIZEOF(qse_char_t) * (QSE_STR_LEN(awk->tok.name) + 1));
|
||||||
|
if (link == QSE_NULL)
|
||||||
|
{
|
||||||
|
ADJERR_LOC (awk, &awk->ptok.loc);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
qse_strncpy ((qse_char_t*)(link + 1), QSE_STR_PTR(awk->tok.name), QSE_STR_LEN(awk->tok.name));
|
||||||
|
link->link = awk->sio_names;
|
||||||
|
awk->sio_names = link;
|
||||||
|
|
||||||
|
arg = (qse_awk_sio_arg_t*) qse_awk_callocmem (awk, QSE_SIZEOF(*awk));
|
||||||
if (arg == QSE_NULL)
|
if (arg == QSE_NULL)
|
||||||
{
|
{
|
||||||
ADJERR_LOC (awk, &awk->ptok.loc);
|
ADJERR_LOC (awk, &awk->ptok.loc);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg->flags = QSE_AWK_SIO_INCLUDED;
|
arg->name = (const qse_char_t*)(link + 1);
|
||||||
arg->name = QSE_HTB_KPTR(pair);
|
|
||||||
arg->line = 1;
|
arg->line = 1;
|
||||||
arg->colm = 1;
|
arg->colm = 1;
|
||||||
|
|
||||||
|
/* let the argument's prev field point to the current */
|
||||||
|
arg->prev = awk->sio.inp;
|
||||||
|
|
||||||
CLRERR (awk);
|
CLRERR (awk);
|
||||||
op = awk->sio.inf (awk, QSE_AWK_SIO_OPEN, arg, QSE_NULL, 0);
|
if (awk->sio.inf (awk, QSE_AWK_SIO_OPEN, arg, QSE_NULL, 0) <= -1)
|
||||||
if (op <= -1)
|
|
||||||
{
|
{
|
||||||
if (ISNOERR(awk)) SETERR_TOK (awk, QSE_AWK_EOPEN);
|
if (ISNOERR(awk)) SETERR_TOK (awk, QSE_AWK_EOPEN);
|
||||||
else awk->errinf.loc = awk->tok.loc; /* adjust error location */
|
else awk->errinf.loc = awk->tok.loc; /* adjust error location */
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg->next = awk->sio.inp;
|
/* i update the current pointer after opening is successful */
|
||||||
awk->sio.inp = arg;
|
awk->sio.inp = arg;
|
||||||
awk->parse.depth.incl++;
|
awk->parse.depth.incl++;
|
||||||
|
|
||||||
@ -807,6 +816,8 @@ static int begin_include (qse_awk_t* awk)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
|
/* i don't need to free 'link' here since it's linked to awk->sio_names
|
||||||
|
* that's freed at the beginning of qse_awk_parse() or by qse_awk_close(). */
|
||||||
if (arg) QSE_MMGR_FREE (awk->mmgr, arg);
|
if (arg) QSE_MMGR_FREE (awk->mmgr, arg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,10 @@ int qse_awk_initgbls (
|
|||||||
qse_awk_t* awk
|
qse_awk_t* awk
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void qse_awk_clearsionames (
|
||||||
|
qse_awk_t* awk
|
||||||
|
);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -84,11 +84,8 @@ typedef struct xtn_t
|
|||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct
|
/* nothing to maintain here for file */
|
||||||
{
|
|
||||||
qse_sio_t* sio; /* the handle to an open file */
|
|
||||||
qse_cstr_t dir;
|
|
||||||
} file;
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
const qse_char_t* ptr;
|
const qse_char_t* ptr;
|
||||||
@ -669,7 +666,7 @@ static qse_sio_t* open_sio_std_rtx (qse_awk_rtx_t* rtx, qse_sio_std_t std, int f
|
|||||||
|
|
||||||
/*** PARSESTD ***/
|
/*** PARSESTD ***/
|
||||||
|
|
||||||
static int open_parsestd (qse_awk_t* awk, xtn_t* xtn, qse_size_t index)
|
static int open_parsestd (qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn, qse_size_t index)
|
||||||
{
|
{
|
||||||
qse_awk_parsestd_t* psin = &xtn->s.in.x[index];
|
qse_awk_parsestd_t* psin = &xtn->s.in.x[index];
|
||||||
|
|
||||||
@ -689,37 +686,27 @@ static int open_parsestd (qse_awk_t* awk, xtn_t* xtn, qse_size_t index)
|
|||||||
if (tmp == QSE_NULL) return -1;
|
if (tmp == QSE_NULL) return -1;
|
||||||
|
|
||||||
if (index >= 1 && xtn->s.in.x[index-1].type == QSE_AWK_PARSESTD_FILE)
|
if (index >= 1 && xtn->s.in.x[index-1].type == QSE_AWK_PARSESTD_FILE)
|
||||||
qse_sio_close (xtn->s.in.u.file.sio);
|
qse_sio_close (arg->handle);
|
||||||
|
|
||||||
xtn->s.in.u.file.sio = tmp;
|
arg->handle = tmp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qse_sio_t* tmp;
|
qse_sio_t* tmp;
|
||||||
const qse_char_t* base;
|
|
||||||
|
|
||||||
tmp = open_sio (awk, psin->u.file.path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
|
tmp = open_sio (awk, psin->u.file.path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR | QSE_SIO_KEEPPATH);
|
||||||
if (tmp == QSE_NULL) return -1;
|
if (tmp == QSE_NULL) return -1;
|
||||||
|
|
||||||
if (index >= 1 && xtn->s.in.x[index-1].type == QSE_AWK_PARSESTD_FILE)
|
if (index >= 1 && xtn->s.in.x[index-1].type == QSE_AWK_PARSESTD_FILE)
|
||||||
qse_sio_close (xtn->s.in.u.file.sio);
|
qse_sio_close (arg->handle);
|
||||||
xtn->s.in.u.file.sio = tmp;
|
arg->handle = tmp;
|
||||||
|
|
||||||
base = qse_basename (psin->u.file.path);
|
|
||||||
if (base != psin->u.file.path)
|
|
||||||
{
|
|
||||||
xtn->s.in.u.file.dir.ptr = psin->u.file.path;
|
|
||||||
xtn->s.in.u.file.dir.len = base - psin->u.file.path;
|
|
||||||
}
|
}
|
||||||
|
if (psin->u.file.cmgr) qse_sio_setcmgr (arg->handle, psin->u.file.cmgr);
|
||||||
}
|
|
||||||
if (psin->u.file.cmgr)
|
|
||||||
qse_sio_setcmgr (xtn->s.in.u.file.sio, psin->u.file.cmgr);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case QSE_AWK_PARSESTD_STR:
|
case QSE_AWK_PARSESTD_STR:
|
||||||
if (index >= 1 && xtn->s.in.x[index-1].type == QSE_AWK_PARSESTD_FILE)
|
if (index >= 1 && xtn->s.in.x[index-1].type == QSE_AWK_PARSESTD_FILE)
|
||||||
qse_sio_close (xtn->s.in.u.file.sio);
|
qse_sio_close (arg->handle);
|
||||||
|
|
||||||
xtn->s.in.u.str.ptr = psin->u.str.ptr;
|
xtn->s.in.u.str.ptr = psin->u.str.ptr;
|
||||||
xtn->s.in.u.str.end = psin->u.str.ptr + psin->u.str.len;
|
xtn->s.in.u.str.end = psin->u.str.ptr + psin->u.str.len;
|
||||||
@ -734,21 +721,23 @@ static int open_parsestd (qse_awk_t* awk, xtn_t* xtn, qse_size_t index)
|
|||||||
static qse_ssize_t sf_in_open (
|
static qse_ssize_t sf_in_open (
|
||||||
qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn)
|
qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn)
|
||||||
{
|
{
|
||||||
if (arg == QSE_NULL || !(arg->flags & QSE_AWK_SIO_INCLUDED))
|
if (arg->name == QSE_NULL)
|
||||||
{
|
{
|
||||||
/* handle normal source input streams specified
|
/* handle normal source input streams specified
|
||||||
* to qse_awk_parsestd() */
|
* to qse_awk_parsestd() */
|
||||||
|
|
||||||
qse_ssize_t x;
|
qse_ssize_t x;
|
||||||
x = open_parsestd (awk, xtn, 0);
|
x = open_parsestd (awk, arg, xtn, 0);
|
||||||
if (x >= 0)
|
if (x >= 0)
|
||||||
{
|
{
|
||||||
xtn->s.in.xindex = 0; /* update the current stream index */
|
xtn->s.in.xindex = 0; /* update the current stream index */
|
||||||
|
#if 0
|
||||||
/* perform some manipulation about the top-level input information */
|
/* perform some manipulation about the top-level input information */
|
||||||
if (xtn->s.in.x[0].type == QSE_AWK_PARSESTD_FILE)
|
if (xtn->s.in.x[0].type == QSE_AWK_PARSESTD_FILE)
|
||||||
awk->sio.arg.name = xtn->s.in.x[0].u.file.path;
|
awk->sio.arg.name = xtn->s.in.x[0].u.file.path;
|
||||||
else
|
else
|
||||||
awk->sio.arg.name = QSE_NULL;
|
awk->sio.arg.name = QSE_NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
@ -756,18 +745,25 @@ static qse_ssize_t sf_in_open (
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* handle the included source file - @include */
|
/* handle the included source file - @include */
|
||||||
const qse_char_t* file;
|
const qse_char_t* path, * outer;
|
||||||
qse_char_t fbuf[64];
|
qse_char_t fbuf[64];
|
||||||
qse_char_t* dbuf = QSE_NULL;
|
qse_char_t* dbuf = QSE_NULL;
|
||||||
|
|
||||||
QSE_ASSERT (arg->name != QSE_NULL);
|
QSE_ASSERT (arg->name != QSE_NULL);
|
||||||
|
|
||||||
file = arg->name;
|
path = arg->name;
|
||||||
if (xtn->s.in.u.file.dir.len > 0 && arg->name[0] != QSE_T('/'))
|
outer = qse_sio_getpath (arg->prev->handle);
|
||||||
|
if (outer)
|
||||||
{
|
{
|
||||||
qse_size_t tmplen, totlen;
|
const qse_char_t* base;
|
||||||
|
|
||||||
totlen = qse_strlen(arg->name) + xtn->s.in.u.file.dir.len;
|
base = qse_basename (outer);
|
||||||
|
if (base != outer && arg->name[0] != QSE_T('/'))
|
||||||
|
{
|
||||||
|
qse_size_t tmplen, totlen, dirlen;
|
||||||
|
|
||||||
|
dirlen = base - outer;
|
||||||
|
totlen = qse_strlen(arg->name) + dirlen;
|
||||||
if (totlen >= QSE_COUNTOF(fbuf))
|
if (totlen >= QSE_COUNTOF(fbuf))
|
||||||
{
|
{
|
||||||
dbuf = qse_awk_allocmem (
|
dbuf = qse_awk_allocmem (
|
||||||
@ -775,20 +771,17 @@ static qse_ssize_t sf_in_open (
|
|||||||
);
|
);
|
||||||
if (dbuf == QSE_NULL) return -1;
|
if (dbuf == QSE_NULL) return -1;
|
||||||
|
|
||||||
file = dbuf;
|
path = dbuf;
|
||||||
}
|
}
|
||||||
else file = fbuf;
|
else path = fbuf;
|
||||||
|
|
||||||
tmplen = qse_strncpy (
|
tmplen = qse_strncpy ((qse_char_t*)path, outer, dirlen);
|
||||||
(qse_char_t*)file,
|
qse_strcpy ((qse_char_t*)path + tmplen, arg->name);
|
||||||
xtn->s.in.u.file.dir.ptr,
|
}
|
||||||
xtn->s.in.u.file.dir.len
|
|
||||||
);
|
|
||||||
qse_strcpy ((qse_char_t*)file + tmplen, arg->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arg->handle = qse_sio_open (
|
arg->handle = qse_sio_open (
|
||||||
awk->mmgr, 0, file, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR
|
awk->mmgr, 0, path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR | QSE_SIO_KEEPPATH
|
||||||
);
|
);
|
||||||
|
|
||||||
if (dbuf) QSE_MMGR_FREE (awk->mmgr, dbuf);
|
if (dbuf) QSE_MMGR_FREE (awk->mmgr, dbuf);
|
||||||
@ -808,12 +801,13 @@ static qse_ssize_t sf_in_open (
|
|||||||
static qse_ssize_t sf_in_close (
|
static qse_ssize_t sf_in_close (
|
||||||
qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn)
|
qse_awk_t* awk, qse_awk_sio_arg_t* arg, xtn_t* xtn)
|
||||||
{
|
{
|
||||||
if (arg == QSE_NULL || !(arg->flags & QSE_AWK_SIO_INCLUDED))
|
if (arg->name == QSE_NULL)
|
||||||
{
|
{
|
||||||
switch (xtn->s.in.x[xtn->s.in.xindex].type)
|
switch (xtn->s.in.x[xtn->s.in.xindex].type)
|
||||||
{
|
{
|
||||||
case QSE_AWK_PARSESTD_FILE:
|
case QSE_AWK_PARSESTD_FILE:
|
||||||
qse_sio_close (xtn->s.in.u.file.sio);
|
QSE_ASSERT (arg->handle != QSE_NULL);
|
||||||
|
qse_sio_close (arg->handle);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QSE_AWK_PARSESTD_STR:
|
case QSE_AWK_PARSESTD_STR:
|
||||||
@ -839,8 +833,7 @@ static qse_ssize_t sf_in_read (
|
|||||||
qse_awk_t* awk, qse_awk_sio_arg_t* arg,
|
qse_awk_t* awk, qse_awk_sio_arg_t* arg,
|
||||||
qse_char_t* data, qse_size_t size, xtn_t* xtn)
|
qse_char_t* data, qse_size_t size, xtn_t* xtn)
|
||||||
{
|
{
|
||||||
|
if (arg->name == QSE_NULL)
|
||||||
if (arg == QSE_NULL || !(arg->flags & QSE_AWK_SIO_INCLUDED))
|
|
||||||
{
|
{
|
||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
|
|
||||||
@ -848,8 +841,8 @@ static qse_ssize_t sf_in_read (
|
|||||||
switch (xtn->s.in.x[xtn->s.in.xindex].type)
|
switch (xtn->s.in.x[xtn->s.in.xindex].type)
|
||||||
{
|
{
|
||||||
case QSE_AWK_PARSESTD_FILE:
|
case QSE_AWK_PARSESTD_FILE:
|
||||||
QSE_ASSERT (xtn->s.in.u.file.sio != QSE_NULL);
|
QSE_ASSERT (arg->handle != QSE_NULL);
|
||||||
n = qse_sio_getstrn (xtn->s.in.u.file.sio, data, size);
|
n = qse_sio_getstrn (arg->handle, data, size);
|
||||||
if (n <= -1)
|
if (n <= -1)
|
||||||
{
|
{
|
||||||
qse_cstr_t ea;
|
qse_cstr_t ea;
|
||||||
@ -889,18 +882,11 @@ static qse_ssize_t sf_in_read (
|
|||||||
if (xtn->s.in.x[next].type != QSE_AWK_PARSESTD_NULL)
|
if (xtn->s.in.x[next].type != QSE_AWK_PARSESTD_NULL)
|
||||||
{
|
{
|
||||||
/* open the next stream if available. */
|
/* open the next stream if available. */
|
||||||
if (open_parsestd (awk, xtn, next) <= -1) n = -1;
|
if (open_parsestd (awk, arg, xtn, next) <= -1) n = -1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* if successful, close the current stream */
|
/* if successful, close the current stream */
|
||||||
xtn->s.in.xindex = next; /* update the next to the current */
|
xtn->s.in.xindex = next; /* update the next to the current */
|
||||||
|
|
||||||
/* perform some manipulation about the top-level input information */
|
|
||||||
if (xtn->s.in.x[next].type == QSE_AWK_PARSESTD_FILE)
|
|
||||||
awk->sio.arg.name = xtn->s.in.x[next].u.file.path;
|
|
||||||
else
|
|
||||||
awk->sio.arg.name = QSE_NULL;
|
|
||||||
|
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2536,11 +2522,8 @@ done:
|
|||||||
|
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
qse_awk_val_t* retv;
|
|
||||||
|
|
||||||
if (rv)
|
if (rv)
|
||||||
{
|
{
|
||||||
int x;
|
|
||||||
qse_awk_rtx_refupval (rtx, rv);
|
qse_awk_rtx_refupval (rtx, rv);
|
||||||
ret = qse_awk_rtx_setrefval (rtx, qse_awk_rtx_getarg (rtx, 2), rv);
|
ret = qse_awk_rtx_setrefval (rtx, qse_awk_rtx_getarg (rtx, 2), rv);
|
||||||
qse_awk_rtx_refdownval (rtx, rv);
|
qse_awk_rtx_refdownval (rtx, rv);
|
||||||
|
@ -119,6 +119,14 @@ qse_sio_t* qse_sio_openstd (
|
|||||||
qse_sio_t* sio;
|
qse_sio_t* sio;
|
||||||
qse_fio_hnd_t hnd;
|
qse_fio_hnd_t hnd;
|
||||||
|
|
||||||
|
/* Is this necessary?
|
||||||
|
if (flags & QSE_SIO_KEEPATH)
|
||||||
|
{
|
||||||
|
sio->errnum = QSE_SIO_EINVAL;
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (qse_getstdfiohandle (std, &hnd) <= -1) return QSE_NULL;
|
if (qse_getstdfiohandle (std, &hnd) <= -1) return QSE_NULL;
|
||||||
|
|
||||||
sio = qse_sio_open (mmgr, xtnsize,
|
sio = qse_sio_open (mmgr, xtnsize,
|
||||||
@ -146,7 +154,7 @@ void qse_sio_close (qse_sio_t* sio)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int qse_sio_init (
|
int qse_sio_init (
|
||||||
qse_sio_t* sio, qse_mmgr_t* mmgr, const qse_char_t* file, int flags)
|
qse_sio_t* sio, qse_mmgr_t* mmgr, const qse_char_t* path, int flags)
|
||||||
{
|
{
|
||||||
int mode;
|
int mode;
|
||||||
int topt = 0;
|
int topt = 0;
|
||||||
@ -162,21 +170,30 @@ int qse_sio_init (
|
|||||||
* this function, a user can specify a sio flag enumerator not
|
* this function, a user can specify a sio flag enumerator not
|
||||||
* present in the fio flag enumerator. mask off such an enumerator. */
|
* present in the fio flag enumerator. mask off such an enumerator. */
|
||||||
if (qse_fio_init (
|
if (qse_fio_init (
|
||||||
&sio->file, mmgr, file,
|
&sio->file, mmgr, path,
|
||||||
(flags & ~QSE_FIO_RESERVED), mode) <= -1)
|
(flags & ~QSE_FIO_RESERVED), mode) <= -1)
|
||||||
{
|
{
|
||||||
sio->errnum = fio_errnum_to_sio_errnum (&sio->file);
|
sio->errnum = fio_errnum_to_sio_errnum (&sio->file);
|
||||||
return -1;
|
goto oops00;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & QSE_SIO_IGNOREMBWCERR) topt |= QSE_TIO_IGNOREMBWCERR;
|
if (flags & QSE_SIO_IGNOREMBWCERR) topt |= QSE_TIO_IGNOREMBWCERR;
|
||||||
if (flags & QSE_SIO_NOAUTOFLUSH) topt |= QSE_TIO_NOAUTOFLUSH;
|
if (flags & QSE_SIO_NOAUTOFLUSH) topt |= QSE_TIO_NOAUTOFLUSH;
|
||||||
|
|
||||||
|
if ((flags & QSE_SIO_KEEPPATH) && !(flags & QSE_SIO_HANDLE))
|
||||||
|
{
|
||||||
|
sio->path = qse_strdup (path, sio->mmgr);
|
||||||
|
if (sio->path == QSE_NULL)
|
||||||
|
{
|
||||||
|
sio->errnum = QSE_SIO_ENOMEM;
|
||||||
|
goto oops01;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (qse_tio_init(&sio->tio.io, mmgr, topt) <= -1)
|
if (qse_tio_init(&sio->tio.io, mmgr, topt) <= -1)
|
||||||
{
|
{
|
||||||
sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io);
|
sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io);
|
||||||
qse_fio_fini (&sio->file);
|
goto oops02;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
/* store the back-reference to sio in the extension area.*/
|
/* store the back-reference to sio in the extension area.*/
|
||||||
QSE_ASSERT (QSE_XTN(&sio->tio.io) == &sio->tio.xtn);
|
QSE_ASSERT (QSE_XTN(&sio->tio.io) == &sio->tio.xtn);
|
||||||
@ -187,12 +204,19 @@ int qse_sio_init (
|
|||||||
{
|
{
|
||||||
if (sio->errnum == QSE_SIO_ENOERR)
|
if (sio->errnum == QSE_SIO_ENOERR)
|
||||||
sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io);
|
sio->errnum = tio_errnum_to_sio_errnum (&sio->tio.io);
|
||||||
qse_tio_fini (&sio->tio.io);
|
goto oops03;
|
||||||
qse_fio_fini (&sio->file);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
oops03:
|
||||||
|
qse_tio_fini (&sio->tio.io);
|
||||||
|
oops02:
|
||||||
|
if (sio->path) QSE_MMGR_FREE (sio->mmgr, sio->path);
|
||||||
|
oops01:
|
||||||
|
qse_fio_fini (&sio->file);
|
||||||
|
oops00:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_sio_initstd (
|
int qse_sio_initstd (
|
||||||
@ -227,6 +251,7 @@ void qse_sio_fini (qse_sio_t* sio)
|
|||||||
qse_sio_flush (sio);
|
qse_sio_flush (sio);
|
||||||
qse_tio_fini (&sio->tio.io);
|
qse_tio_fini (&sio->tio.io);
|
||||||
qse_fio_fini (&sio->file);
|
qse_fio_fini (&sio->file);
|
||||||
|
if (sio->path) QSE_MMGR_FREE (sio->mmgr, sio->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_mmgr_t* qse_sio_getmmgr (qse_sio_t* sio)
|
qse_mmgr_t* qse_sio_getmmgr (qse_sio_t* sio)
|
||||||
@ -265,6 +290,12 @@ qse_ubi_t qse_sio_gethandleasubi (const qse_sio_t* sio)
|
|||||||
return qse_fio_gethandleasubi (&sio->file);
|
return qse_fio_gethandleasubi (&sio->file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const qse_char_t* qse_sio_getpath (qse_sio_t* sio)
|
||||||
|
{
|
||||||
|
/* this path is valid if QSE_SIO_HANDLE is off and QSE_SIO_KEEPPATH is on */
|
||||||
|
return sio->path;
|
||||||
|
}
|
||||||
|
|
||||||
qse_ssize_t qse_sio_flush (qse_sio_t* sio)
|
qse_ssize_t qse_sio_flush (qse_sio_t* sio)
|
||||||
{
|
{
|
||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
@ -636,3 +667,4 @@ static qse_ssize_t file_output (
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ static int end_include (qse_xli_t* xli)
|
|||||||
* xli->sio.inp again. */
|
* xli->sio.inp again. */
|
||||||
|
|
||||||
cur = xli->sio.inp;
|
cur = xli->sio.inp;
|
||||||
xli->sio.inp = xli->sio.inp->next;
|
xli->sio.inp = xli->sio.inp->prev;
|
||||||
|
|
||||||
QSE_ASSERT (cur->name != QSE_NULL);
|
QSE_ASSERT (cur->name != QSE_NULL);
|
||||||
QSE_MMGR_FREE (xli->mmgr, cur);
|
QSE_MMGR_FREE (xli->mmgr, cur);
|
||||||
@ -299,43 +299,35 @@ static int end_include (qse_xli_t* xli)
|
|||||||
|
|
||||||
static int begin_include (qse_xli_t* xli)
|
static int begin_include (qse_xli_t* xli)
|
||||||
{
|
{
|
||||||
qse_ssize_t op;
|
qse_link_t* link;
|
||||||
qse_xli_io_arg_t* arg = QSE_NULL;
|
qse_xli_io_arg_t* arg = QSE_NULL;
|
||||||
qse_htb_pair_t* pair = QSE_NULL;
|
|
||||||
|
|
||||||
/* store the file name to xli->sio_names */
|
link = (qse_xli_io_arg_t*) qse_xli_callocmem (xli,
|
||||||
pair = qse_htb_ensert (
|
QSE_SIZEOF(*link) + QSE_SIZEOF(qse_char_t) * (QSE_STR_LEN(xli->tok.name) + 1));
|
||||||
xli->sio_names,
|
if (link == QSE_NULL) goto oops;
|
||||||
QSE_STR_PTR(xli->tok.name),
|
|
||||||
QSE_STR_LEN(xli->tok.name) + 1, /* to include '\0' */
|
|
||||||
QSE_NULL, 0
|
|
||||||
);
|
|
||||||
if (pair == QSE_NULL)
|
|
||||||
{
|
|
||||||
qse_xli_seterror (xli, QSE_XLI_ENOMEM, QSE_NULL, &xli->tok.loc);
|
|
||||||
goto oops;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*QSE_HTB_VPTR(pair) = QSE_HTB_KPTR(pair);
|
qse_strncpy ((qse_char_t*)(link + 1), QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name));
|
||||||
QSE_HTB_VLEN(pair) = QSE_HTB_KLEN(pair);*/
|
link->link = xli->sio_names;
|
||||||
|
xli->sio_names = link;
|
||||||
|
|
||||||
arg = (qse_xli_io_arg_t*) qse_xli_callocmem (xli, QSE_SIZEOF(*arg));
|
arg = (qse_xli_io_arg_t*) qse_xli_callocmem (xli, QSE_SIZEOF(*arg));
|
||||||
if (arg == QSE_NULL) goto oops;
|
if (arg == QSE_NULL) goto oops;
|
||||||
|
|
||||||
arg->flags = QSE_XLI_IO_INCLUDED;
|
arg->name = (const qse_char_t*)(link + 1);
|
||||||
arg->name = QSE_HTB_KPTR(pair);
|
|
||||||
arg->line = 1;
|
arg->line = 1;
|
||||||
arg->colm = 1;
|
arg->colm = 1;
|
||||||
|
|
||||||
op = xli->sio.inf (xli, QSE_XLI_IO_OPEN, arg, QSE_NULL, 0);
|
/* let the argument's prev point field to the current */
|
||||||
if (op <= -1)
|
arg->prev = xli->sio.inp;
|
||||||
|
|
||||||
|
if (xli->sio.inf (xli, QSE_XLI_IO_OPEN, arg, QSE_NULL, 0) <= -1)
|
||||||
{
|
{
|
||||||
if (xli->errnum == QSE_XLI_ENOERR)
|
if (xli->errnum == QSE_XLI_ENOERR)
|
||||||
qse_xli_seterrnum (xli, QSE_XLI_EIOUSR, QSE_NULL);
|
qse_xli_seterrnum (xli, QSE_XLI_EIOUSR, QSE_NULL);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg->next = xli->sio.inp;
|
/* i update the current pointer after opening is successful */
|
||||||
xli->sio.inp = arg;
|
xli->sio.inp = arg;
|
||||||
/* xli->parse.depth.incl++; */
|
/* xli->parse.depth.incl++; */
|
||||||
|
|
||||||
@ -353,6 +345,9 @@ static int begin_include (qse_xli_t* xli)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
|
/* i don't need to free 'link' since it's linked to
|
||||||
|
* xli->sio_names that's freed at the beginning of qse_xli_read()
|
||||||
|
* or by qse_xli_fini() */
|
||||||
if (arg) QSE_MMGR_FREE (xli->mmgr, arg);
|
if (arg) QSE_MMGR_FREE (xli->mmgr, arg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -726,6 +721,17 @@ oops:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qse_xli_clearsionames (qse_xli_t* xli)
|
||||||
|
{
|
||||||
|
qse_link_t* cur;
|
||||||
|
while (xli->sio_names)
|
||||||
|
{
|
||||||
|
cur = xli->sio_names;
|
||||||
|
xli->sio_names = cur->link;
|
||||||
|
QSE_MMGR_FREE (xli->mmgr, cur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io)
|
int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||||
{
|
{
|
||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
@ -741,7 +747,7 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io)
|
|||||||
xli->sio.arg.line = 1;
|
xli->sio.arg.line = 1;
|
||||||
xli->sio.arg.colm = 1;
|
xli->sio.arg.colm = 1;
|
||||||
xli->sio.inp = &xli->sio.arg;
|
xli->sio.inp = &xli->sio.arg;
|
||||||
qse_htb_clear (xli->sio_names);
|
qse_xli_clearsionames (xli);
|
||||||
|
|
||||||
n = xli->sio.inf (xli, QSE_XLI_IO_OPEN, xli->sio.inp, QSE_NULL, 0);
|
n = xli->sio.inf (xli, QSE_XLI_IO_OPEN, xli->sio.inp, QSE_NULL, 0);
|
||||||
if (n <= -1)
|
if (n <= -1)
|
||||||
@ -771,15 +777,15 @@ oops:
|
|||||||
* closed. close them */
|
* closed. close them */
|
||||||
while (xli->sio.inp != &xli->sio.arg)
|
while (xli->sio.inp != &xli->sio.arg)
|
||||||
{
|
{
|
||||||
qse_xli_io_arg_t* next;
|
qse_xli_io_arg_t* prev;
|
||||||
|
|
||||||
/* nothing much to do about a close error */
|
/* nothing much to do about a close error */
|
||||||
close_stream (xli);
|
close_stream (xli);
|
||||||
|
|
||||||
next = xli->sio.inp->next;
|
prev = xli->sio.inp->prev;
|
||||||
QSE_ASSERT (xli->sio.inp->name != QSE_NULL);
|
QSE_ASSERT (xli->sio.inp->name != QSE_NULL);
|
||||||
QSE_MMGR_FREE (xli->mmgr, xli->sio.inp);
|
QSE_MMGR_FREE (xli->mmgr, xli->sio.inp);
|
||||||
xli->sio.inp = next;
|
xli->sio.inp = prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
close_stream (xli);
|
close_stream (xli);
|
||||||
|
@ -33,11 +33,10 @@ typedef struct xtn_t
|
|||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct
|
/*
|
||||||
{
|
nothing to maintain for file here
|
||||||
qse_sio_t* sio; /* the handle to an open file */
|
*/
|
||||||
qse_cstr_t dir;
|
|
||||||
} file;
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
const qse_char_t* ptr;
|
const qse_char_t* ptr;
|
||||||
@ -150,47 +149,29 @@ static qse_sio_t* open_sio_std (qse_xli_t* xli, qse_sio_std_t std, int flags)
|
|||||||
return sio;
|
return sio;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int open_readstd (qse_xli_t* xli, xtn_t* xtn)
|
static qse_ssize_t sf_in_open (qse_xli_t* xli, qse_xli_io_arg_t* arg, xtn_t* xtn)
|
||||||
{
|
{
|
||||||
|
if (arg->name == QSE_NULL)
|
||||||
|
{
|
||||||
qse_xli_iostd_t* psin = xtn->s.in.x;
|
qse_xli_iostd_t* psin = xtn->s.in.x;
|
||||||
|
|
||||||
switch (psin->type)
|
switch (psin->type)
|
||||||
{
|
{
|
||||||
/* normal source files */
|
/* normal source files */
|
||||||
|
|
||||||
case QSE_XLI_IOSTD_FILE:
|
case QSE_XLI_IOSTD_FILE:
|
||||||
if (psin->u.file.path == QSE_NULL ||
|
if (psin->u.file.path == QSE_NULL ||
|
||||||
(psin->u.file.path[0] == QSE_T('-') &&
|
(psin->u.file.path[0] == QSE_T('-') &&
|
||||||
psin->u.file.path[1] == QSE_T('\0')))
|
psin->u.file.path[1] == QSE_T('\0')))
|
||||||
{
|
{
|
||||||
/* no path name or - -> stdin */
|
/* no path name or - -> stdin */
|
||||||
qse_sio_t* tmp;
|
arg->handle = open_sio_std (xli, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
|
||||||
|
|
||||||
tmp = open_sio_std (xli, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
|
|
||||||
if (tmp == QSE_NULL) return -1;
|
|
||||||
|
|
||||||
xtn->s.in.u.file.sio = tmp;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qse_sio_t* tmp;
|
arg->handle = open_sio (xli, psin->u.file.path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR | QSE_SIO_KEEPPATH);
|
||||||
const qse_char_t* base;
|
|
||||||
|
|
||||||
tmp = open_sio (xli, psin->u.file.path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
|
|
||||||
if (tmp == QSE_NULL) return -1;
|
|
||||||
|
|
||||||
xtn->s.in.u.file.sio = tmp;
|
|
||||||
|
|
||||||
base = qse_basename (psin->u.file.path);
|
|
||||||
if (base != psin->u.file.path)
|
|
||||||
{
|
|
||||||
xtn->s.in.u.file.dir.ptr = psin->u.file.path;
|
|
||||||
xtn->s.in.u.file.dir.len = base - psin->u.file.path;
|
|
||||||
}
|
}
|
||||||
|
if (arg->handle == QSE_NULL) return -1;
|
||||||
}
|
if (psin->u.file.cmgr) qse_sio_setcmgr (arg->handle, psin->u.file.cmgr);
|
||||||
if (psin->u.file.cmgr)
|
|
||||||
qse_sio_setcmgr (xtn->s.in.u.file.sio, psin->u.file.cmgr);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case QSE_XLI_IOSTD_STR:
|
case QSE_XLI_IOSTD_STR:
|
||||||
@ -202,45 +183,33 @@ static int open_readstd (qse_xli_t* xli, xtn_t* xtn)
|
|||||||
qse_xli_seterrnum (xli, QSE_XLI_EINTERN, QSE_NULL);
|
qse_xli_seterrnum (xli, QSE_XLI_EINTERN, QSE_NULL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static qse_ssize_t sf_in_open (
|
|
||||||
qse_xli_t* xli, qse_xli_io_arg_t* arg, xtn_t* xtn)
|
|
||||||
{
|
|
||||||
if (arg == QSE_NULL || !(arg->flags & QSE_XLI_IO_INCLUDED))
|
|
||||||
{
|
|
||||||
/* handle normal source input streams specified
|
|
||||||
* to qse_xli_readstd() */
|
|
||||||
|
|
||||||
qse_ssize_t x;
|
|
||||||
|
|
||||||
x = open_readstd (xli, xtn);
|
|
||||||
if (x >= 0)
|
|
||||||
{
|
|
||||||
/* perform some manipulation about the top-level input information */
|
|
||||||
if (xtn->s.in.x->type == QSE_XLI_IOSTD_FILE)
|
|
||||||
xli->sio.arg.name = xtn->s.in.x->u.file.path;
|
|
||||||
else
|
|
||||||
xli->sio.arg.name = QSE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
QSE_ASSERT (arg->prev != QSE_NULL);
|
||||||
|
|
||||||
/* handle the included file - @include */
|
/* handle the included file - @include */
|
||||||
const qse_char_t* file;
|
const qse_char_t* path, * outer;
|
||||||
qse_char_t fbuf[64];
|
qse_char_t fbuf[64];
|
||||||
qse_char_t* dbuf = QSE_NULL;
|
qse_char_t* dbuf = QSE_NULL;
|
||||||
|
|
||||||
QSE_ASSERT (arg->name != QSE_NULL);
|
QSE_ASSERT (arg->name != QSE_NULL);
|
||||||
|
|
||||||
file = arg->name;
|
path = arg->name;
|
||||||
if (xtn->s.in.u.file.dir.len > 0 && arg->name[0] != QSE_T('/'))
|
outer = qse_sio_getpath (arg->prev->handle);
|
||||||
|
if (outer)
|
||||||
{
|
{
|
||||||
qse_size_t tmplen, totlen;
|
const qse_char_t* base;
|
||||||
|
|
||||||
totlen = qse_strlen(arg->name) + xtn->s.in.u.file.dir.len;
|
/* i'm being included from another file */
|
||||||
|
base = qse_basename (outer);
|
||||||
|
if (base != outer && arg->name[0] != QSE_T('/'))
|
||||||
|
{
|
||||||
|
qse_size_t tmplen, totlen, dirlen;
|
||||||
|
|
||||||
|
dirlen = base - outer;
|
||||||
|
|
||||||
|
totlen = qse_strlen(arg->name) + dirlen;
|
||||||
if (totlen >= QSE_COUNTOF(fbuf))
|
if (totlen >= QSE_COUNTOF(fbuf))
|
||||||
{
|
{
|
||||||
dbuf = qse_xli_allocmem (
|
dbuf = qse_xli_allocmem (
|
||||||
@ -248,20 +217,17 @@ static qse_ssize_t sf_in_open (
|
|||||||
);
|
);
|
||||||
if (dbuf == QSE_NULL) return -1;
|
if (dbuf == QSE_NULL) return -1;
|
||||||
|
|
||||||
file = dbuf;
|
path = dbuf;
|
||||||
}
|
}
|
||||||
else file = fbuf;
|
else path = fbuf;
|
||||||
|
|
||||||
tmplen = qse_strncpy (
|
tmplen = qse_strncpy ((qse_char_t*)path, outer, dirlen);
|
||||||
(qse_char_t*)file,
|
qse_strcpy ((qse_char_t*)path + tmplen, arg->name);
|
||||||
xtn->s.in.u.file.dir.ptr,
|
}
|
||||||
xtn->s.in.u.file.dir.len
|
|
||||||
);
|
|
||||||
qse_strcpy ((qse_char_t*)file + tmplen, arg->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arg->handle = qse_sio_open (
|
arg->handle = qse_sio_open (
|
||||||
xli->mmgr, 0, file, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR
|
xli->mmgr, 0, path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR | QSE_SIO_KEEPPATH
|
||||||
);
|
);
|
||||||
|
|
||||||
if (dbuf) QSE_MMGR_FREE (xli->mmgr, dbuf);
|
if (dbuf) QSE_MMGR_FREE (xli->mmgr, dbuf);
|
||||||
@ -278,15 +244,17 @@ static qse_ssize_t sf_in_open (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static qse_ssize_t sf_in_close (
|
static qse_ssize_t sf_in_close (
|
||||||
qse_xli_t* xli, qse_xli_io_arg_t* arg, xtn_t* xtn)
|
qse_xli_t* xli, qse_xli_io_arg_t* arg, xtn_t* xtn)
|
||||||
{
|
{
|
||||||
if (arg == QSE_NULL || !(arg->flags & QSE_XLI_IO_INCLUDED))
|
if (arg->name == QSE_NULL)
|
||||||
{
|
{
|
||||||
switch (xtn->s.in.x->type)
|
switch (xtn->s.in.x->type)
|
||||||
{
|
{
|
||||||
case QSE_XLI_IOSTD_FILE:
|
case QSE_XLI_IOSTD_FILE:
|
||||||
qse_sio_close (xtn->s.in.u.file.sio);
|
QSE_ASSERT (arg->handle != QSE_NULL);
|
||||||
|
qse_sio_close (arg->handle);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QSE_XLI_IOSTD_STR:
|
case QSE_XLI_IOSTD_STR:
|
||||||
@ -312,16 +280,15 @@ static qse_ssize_t sf_in_read (
|
|||||||
qse_xli_t* xli, qse_xli_io_arg_t* arg,
|
qse_xli_t* xli, qse_xli_io_arg_t* arg,
|
||||||
qse_char_t* data, qse_size_t size, xtn_t* xtn)
|
qse_char_t* data, qse_size_t size, xtn_t* xtn)
|
||||||
{
|
{
|
||||||
|
if (arg->name == QSE_NULL)
|
||||||
if (arg == QSE_NULL || !(arg->flags & QSE_XLI_IO_INCLUDED))
|
|
||||||
{
|
{
|
||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
|
|
||||||
switch (xtn->s.in.x->type)
|
switch (xtn->s.in.x->type)
|
||||||
{
|
{
|
||||||
case QSE_XLI_IOSTD_FILE:
|
case QSE_XLI_IOSTD_FILE:
|
||||||
QSE_ASSERT (xtn->s.in.u.file.sio != QSE_NULL);
|
QSE_ASSERT (arg->handle != QSE_NULL);
|
||||||
n = qse_sio_getstrn (xtn->s.in.u.file.sio, data, size);
|
n = qse_sio_getstrn (arg->handle, data, size);
|
||||||
if (n <= -1)
|
if (n <= -1)
|
||||||
{
|
{
|
||||||
qse_cstr_t ea;
|
qse_cstr_t ea;
|
||||||
@ -382,6 +349,8 @@ static qse_ssize_t sf_in (
|
|||||||
{
|
{
|
||||||
xtn_t* xtn = QSE_XTN (xli);
|
xtn_t* xtn = QSE_XTN (xli);
|
||||||
|
|
||||||
|
QSE_ASSERT (arg != QSE_NULL);
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case QSE_XLI_IO_OPEN:
|
case QSE_XLI_IO_OPEN:
|
||||||
|
@ -67,22 +67,12 @@ int qse_xli_init (qse_xli_t* xli, qse_mmgr_t* mmgr)
|
|||||||
xli->tok.name = qse_str_open (mmgr, 0, 128);
|
xli->tok.name = qse_str_open (mmgr, 0, 128);
|
||||||
if (xli->tok.name == QSE_NULL) goto oops;
|
if (xli->tok.name == QSE_NULL) goto oops;
|
||||||
|
|
||||||
xli->sio_names = qse_htb_open (
|
|
||||||
mmgr, QSE_SIZEOF(xli), 128, 70, QSE_SIZEOF(qse_char_t), 1
|
|
||||||
);
|
|
||||||
if (xli->sio_names == QSE_NULL) goto oops;
|
|
||||||
*(qse_xli_t**)QSE_XTN(xli->sio_names) = xli;
|
|
||||||
qse_htb_setstyle (xli->sio_names,
|
|
||||||
qse_gethtbstyle(QSE_HTB_STYLE_INLINE_KEY_COPIER)
|
|
||||||
);
|
|
||||||
|
|
||||||
xli->root.type = QSE_XLI_LIST;
|
xli->root.type = QSE_XLI_LIST;
|
||||||
xli->xnil.type = QSE_XLI_NIL;
|
xli->xnil.type = QSE_XLI_NIL;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
|
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
|
||||||
if (xli->sio_names) qse_htb_close (xli->sio_names);
|
|
||||||
if (xli->tok.name) qse_str_close (xli->tok.name);
|
if (xli->tok.name) qse_str_close (xli->tok.name);
|
||||||
|
|
||||||
for (i = QSE_COUNTOF(xli->tmp); i > 0; )
|
for (i = QSE_COUNTOF(xli->tmp); i > 0; )
|
||||||
@ -97,13 +87,14 @@ void qse_xli_fini (qse_xli_t* xli)
|
|||||||
qse_size_t i;
|
qse_size_t i;
|
||||||
|
|
||||||
qse_xli_clear (xli);
|
qse_xli_clear (xli);
|
||||||
qse_htb_close (xli->sio_names);
|
|
||||||
qse_str_close (xli->tok.name);
|
qse_str_close (xli->tok.name);
|
||||||
|
|
||||||
for (i = QSE_COUNTOF(xli->tmp); i > 0; )
|
for (i = QSE_COUNTOF(xli->tmp); i > 0; )
|
||||||
{
|
{
|
||||||
if (xli->tmp[--i]) qse_str_close (xli->tmp[i]);
|
if (xli->tmp[--i]) qse_str_close (xli->tmp[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qse_xli_clearsionames (xli);
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_mmgr_t* qse_xli_getmmgr (qse_xli_t* xli)
|
qse_mmgr_t* qse_xli_getmmgr (qse_xli_t* xli)
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include <qse/xli/xli.h>
|
#include <qse/xli/xli.h>
|
||||||
#include <qse/cmn/str.h>
|
#include <qse/cmn/str.h>
|
||||||
#include <qse/cmn/htb.h>
|
|
||||||
#include "../cmn/mem.h"
|
#include "../cmn/mem.h"
|
||||||
|
|
||||||
typedef struct qse_xli_tok_t qse_xli_tok_t;
|
typedef struct qse_xli_tok_t qse_xli_tok_t;
|
||||||
@ -63,7 +62,7 @@ struct qse_xli_t
|
|||||||
qse_xli_io_arg_t arg; /* for top level */
|
qse_xli_io_arg_t arg; /* for top level */
|
||||||
qse_xli_io_arg_t* inp; /* current */
|
qse_xli_io_arg_t* inp; /* current */
|
||||||
} sio;
|
} sio;
|
||||||
qse_htb_t* sio_names;
|
qse_link_t* sio_names;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -78,6 +77,8 @@ void qse_xli_fini (qse_xli_t* xli);
|
|||||||
const qse_char_t* qse_xli_dflerrstr (
|
const qse_char_t* qse_xli_dflerrstr (
|
||||||
const qse_xli_t* xli, qse_xli_errnum_t errnum);
|
const qse_xli_t* xli, qse_xli_errnum_t errnum);
|
||||||
|
|
||||||
|
void qse_xli_clearsionames (qse_xli_t* xli);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user