added qse_sed_setcompid() and related code

fixed the way how it squeezes in a new line into a script stream not ending with a newline
This commit is contained in:
hyung-hwan 2011-10-07 02:01:35 +00:00
parent 5eca3cd4b5
commit 915ef99f07
7 changed files with 191 additions and 43 deletions

View File

@ -463,11 +463,17 @@ static void trace_exec (qse_sed_t* sed, qse_sed_exec_op_t op, const qse_sed_cmd_
break; break;
#endif #endif
case QSE_SED_EXEC_MATCH: case QSE_SED_EXEC_MATCH:
qse_printf (QSE_T("matching address for [%c] at line %lu\n"), cmd->type, (unsigned long)cmd->loc.line); qse_printf (QSE_T("matching address for [%c] in %s at line %lu\n"),
cmd->type,
(cmd->lid? cmd->lid: QSE_T("<<UNKNOWN>>")),
(unsigned long)cmd->loc.line);
break; break;
case QSE_SED_EXEC_EXEC: case QSE_SED_EXEC_EXEC:
qse_printf (QSE_T("executing [%c] at line %lu\n"), cmd->type, (unsigned long)cmd->loc.line); qse_printf (QSE_T("executing [%c] in %s at line %lu\n"),
cmd->type,
(cmd->lid? cmd->lid: QSE_T("<<UNKNOWN>>")),
(unsigned long)cmd->loc.line);
break; break;
} }
} }

View File

@ -267,6 +267,12 @@ public:
const loc_t* loc = QSE_NULL ///< error location const loc_t* loc = QSE_NULL ///< error location
); );
const char_t* getCompileId () const;
const char_t* setCompileId (
const char_t* id
);
/// ///
/// The getConsoleLine() function returns the current line /// The getConsoleLine() function returns the current line
/// number from an input console. /// number from an input console.

View File

@ -130,7 +130,9 @@ struct qse_sed_adr_t
struct qse_sed_cmd_t struct qse_sed_cmd_t
{ {
qse_char_t type; qse_char_t type;
qse_sed_loc_t loc;
const qse_char_t* lid;
qse_sed_loc_t loc;
int negated; int negated;
@ -521,18 +523,40 @@ void qse_sed_setlformatter (
qse_sed_lformatter_t lformatter /**< text formatter */ qse_sed_lformatter_t lformatter /**< text formatter */
); );
/**
* The qse_sed_getcompid() function returns the latest
* identifier successfully set with qse_sed_setcompid().
*/
const qse_char_t* qse_sed_getcompid (
qse_sed_t* sed
);
/**
* The qse_sed_setcompid() functions duplicates a string
* pointed to by @a id and stores it internally to identify
* the script currently being compiled. The lid field of the
* current command being compiled in the script is set to the
* lastest identifer successfully set with this function.
* If this function fails, the location set in the command
* may be wrong.
*/
const qse_char_t* qse_sed_setcompid (
qse_sed_t* sed,
const qse_char_t* id
);
/** /**
* The qse_sed_getlinnum() function gets the current input line number. * The qse_sed_getlinnum() function gets the current input line number.
* @return current input line number * @return current input line number
*/ */
qse_size_t qse_sed_getlinnum ( qse_size_t qse_sed_getlinenum (
qse_sed_t* sed /**< stream editor */ qse_sed_t* sed /**< stream editor */
); );
/** /**
* The qse_sed_setlinnum() function changes the current input line number. * The qse_sed_setlinenum() function changes the current input line number.
*/ */
void qse_sed_setlinnum ( void qse_sed_setlinenum (
qse_sed_t* sed, /**< stream editor */ qse_sed_t* sed, /**< stream editor */
qse_size_t num /**< a line number */ qse_size_t num /**< a line number */
); );

View File

@ -112,7 +112,8 @@ Sed::loc_t Sed::getErrorLocation () const
if (sed == QSE_NULL) if (sed == QSE_NULL)
{ {
loc_t loc; loc_t loc;
loc.line = 0; loc.colm = 0; loc.line = 0;
loc.colm = 0;
return loc; return loc;
} }
return *qse_sed_geterrloc (sed); return *qse_sed_geterrloc (sed);
@ -129,16 +130,26 @@ void Sed::setError (errnum_t err, const cstr_t* args, const loc_t* loc)
qse_sed_seterror (sed, err, args, loc); qse_sed_seterror (sed, err, args, loc);
} }
const Sed::char_t* Sed::getCompileId () const
{
return qse_sed_getcompid (this->sed);
}
const Sed::char_t* Sed::setCompileId (const char_t* id)
{
return qse_sed_setcompid (this->sed, id);
}
Sed::size_t Sed::getConsoleLine () Sed::size_t Sed::getConsoleLine ()
{ {
QSE_ASSERT (sed != QSE_NULL); QSE_ASSERT (sed != QSE_NULL);
return qse_sed_getlinnum (sed); return qse_sed_getlinenum (this->sed);
} }
void Sed::setConsoleLine (size_t num) void Sed::setConsoleLine (size_t num)
{ {
QSE_ASSERT (sed != QSE_NULL); QSE_ASSERT (sed != QSE_NULL);
qse_sed_setlinnum (sed, num); qse_sed_setlinenum (this->sed, num);
} }
Sed::ssize_t Sed::sin ( Sed::ssize_t Sed::sin (

View File

@ -38,6 +38,7 @@ QSE_IMPLEMENT_COMMON_FUNCTIONS (sed)
static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd); static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd);
static void free_all_command_blocks (qse_sed_t* sed); static void free_all_command_blocks (qse_sed_t* sed);
static void free_all_cids (qse_sed_t* sed);
static void free_appends (qse_sed_t* sed); static void free_appends (qse_sed_t* sed);
static int emit_output (qse_sed_t* sed, int skipline); static int emit_output (qse_sed_t* sed, int skipline);
@ -130,6 +131,7 @@ oops_1:
void qse_sed_fini (qse_sed_t* sed) void qse_sed_fini (qse_sed_t* sed)
{ {
free_all_command_blocks (sed); free_all_command_blocks (sed);
free_all_cids (sed);
qse_str_fini (&sed->e.txt.subst); qse_str_fini (&sed->e.txt.subst);
qse_str_fini (&sed->e.txt.hold); qse_str_fini (&sed->e.txt.hold);
@ -582,6 +584,15 @@ static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
} }
} }
static void free_all_cids (qse_sed_t* sed)
{
while (sed->src.cid)
{
qse_sed_cid_t* next = sed->src.cid->next;
QSE_MMGR_FREE (sed->mmgr, sed->src.cid);
sed->src.cid = next;
}
}
static QSE_INLINE int xdigit_to_num (qse_cint_t c) static QSE_INLINE int xdigit_to_num (qse_cint_t c)
{ {
@ -1501,6 +1512,7 @@ static int get_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
qse_cint_t c; qse_cint_t c;
c = CURSC (sed); c = CURSC (sed);
cmd->lid = sed->src.cid? ((const qse_char_t*)(sed->src.cid + 1)): QSE_NULL;
cmd->loc = sed->src.loc; cmd->loc = sed->src.loc;
switch (c) switch (c)
{ {
@ -1739,20 +1751,13 @@ int qse_sed_comp (qse_sed_t* sed, qse_sed_io_fun_t inf)
return -1; return -1;
} }
/* store the source code pointers */
sed->src.fun = inf;
if (open_script_stream (sed) <= -1) return -1;
sed->src.loc.line = 1;
sed->src.loc.colm = 0;
sed->src.cc = QSE_CHAR_EOF;
NXTSC_GOTO (sed, c, oops);
/* free all the commands previously compiled */ /* free all the commands previously compiled */
free_all_command_blocks (sed); free_all_command_blocks (sed);
QSE_ASSERT (sed->cmd.lb == &sed->cmd.fb && sed->cmd.lb->len == 0); QSE_ASSERT (sed->cmd.lb == &sed->cmd.fb && sed->cmd.lb->len == 0);
/* free all the compilation identifiers */
free_all_cids (sed);
/* clear the label table */ /* clear the label table */
qse_map_clear (&sed->tmp.labs); qse_map_clear (&sed->tmp.labs);
@ -1760,6 +1765,11 @@ int qse_sed_comp (qse_sed_t* sed, qse_sed_io_fun_t inf)
sed->tmp.grp.level = 0; sed->tmp.grp.level = 0;
qse_str_clear (&sed->tmp.rex); qse_str_clear (&sed->tmp.rex);
/* open script */
sed->src.fun = inf;
if (open_script_stream (sed) <= -1) return -1;
NXTSC_GOTO (sed, c, oops);
while (1) while (1)
{ {
int n; int n;
@ -3615,12 +3625,33 @@ void qse_sed_setlformatter (qse_sed_t* sed, qse_sed_lformatter_t lf)
sed->lformatter = lf; sed->lformatter = lf;
} }
qse_size_t qse_sed_getlinnum (qse_sed_t* sed) const qse_char_t* qse_sed_getcompid (qse_sed_t* sed)
{
return sed->src.cid? ((const qse_char_t*)(sed->src.cid + 1)): QSE_NULL;
}
const qse_char_t* qse_sed_setcompid (qse_sed_t* sed, const qse_char_t* id)
{
qse_sed_cid_t* cid;
qse_size_t len;
len = qse_strlen (id);
cid = QSE_MMGR_ALLOC (sed->mmgr, QSE_SIZEOF(*cid) + ((len + 1) * QSE_SIZEOF(*id)));
if (cid == QSE_NULL) return QSE_NULL;
cid->next = sed->src.cid;
sed->src.cid = cid;
qse_strcpy ((qse_char_t*)(cid + 1), id);
return (const qse_char_t*)(cid + 1);
}
qse_size_t qse_sed_getlinenum (qse_sed_t* sed)
{ {
return sed->e.in.num; return sed->e.in.num;
} }
void qse_sed_setlinnum (qse_sed_t* sed, qse_size_t num) void qse_sed_setlinenum (qse_sed_t* sed, qse_size_t num)
{ {
sed->e.in.num = num; sed->e.in.num = num;
} }
@ -3634,3 +3665,4 @@ void qse_sed_setexectracer (qse_sed_t* sed, qse_sed_exec_tracer_t tracer)
{ {
sed->e.tracer = tracer; sed->e.tracer = tracer;
} }

View File

@ -55,6 +55,12 @@ struct qse_sed_cmd_blk_t
qse_sed_cmd_blk_t* next; qse_sed_cmd_blk_t* next;
}; };
typedef struct qse_sed_cid_t qse_sed_cid_t;
struct qse_sed_cid_t
{
qse_sed_cid_t* next;
};
/** /**
* The qse_sed_t type defines a stream editor * The qse_sed_t type defines a stream editor
*/ */
@ -88,6 +94,7 @@ struct qse_sed_t
qse_char_t buf[1024]; qse_char_t buf[1024];
int eof; int eof;
qse_sed_cid_t* cid;
qse_sed_loc_t loc; /**< location */ qse_sed_loc_t loc; /**< location */
qse_cint_t cc; /**< last character read */ qse_cint_t cc; /**< last character read */
const qse_char_t* ptr; /**< beginning of the source text */ const qse_char_t* ptr; /**< beginning of the source text */

View File

@ -45,6 +45,8 @@ struct xtn_t
struct struct
{ {
xtn_in_t in; xtn_in_t in;
qse_char_t last;
int newline_squeezed;
} s; } s;
struct struct
{ {
@ -54,6 +56,44 @@ struct xtn_t
}; };
static int int_to_str (qse_size_t val, qse_char_t* buf, qse_size_t buflen)
{
qse_size_t t;
qse_size_t rlen = 0;
t = val;
if (t == 0) rlen++;
else
{
/* non-zero values */
if (t < 0) { t = -t; rlen++; }
while (t > 0) { rlen++; t /= 10; }
}
if (rlen >= buflen) return -1; /* buffer too small */
buf[rlen] = QSE_T('\0');
t = val;
if (t == 0) buf[0] = QSE_T('0');
else
{
if (t < 0) t = -t;
/* fill in the buffer with digits */
while (t > 0)
{
buf[--rlen] = (qse_char_t)(t % 10) + QSE_T('0');
t /= 10;
}
/* insert the negative sign if necessary */
if (val < 0) buf[--rlen] = QSE_T('-');
}
return 0;
}
qse_sed_t* qse_sed_openstd (qse_size_t xtnsize) qse_sed_t* qse_sed_openstd (qse_size_t xtnsize)
{ {
return qse_sed_openstdwithmmgr (QSE_MMGR_GETDFL(), xtnsize); return qse_sed_openstdwithmmgr (QSE_MMGR_GETDFL(), xtnsize);
@ -151,7 +191,7 @@ static void close_main_stream (
static int open_input_stream ( static int open_input_stream (
qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_iostd_t* io, xtn_in_t* base) qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_iostd_t* io, xtn_in_t* base)
{ {
/*xtn_t* xtn = (xtn_t*) QSE_XTN (sed);*/ xtn_t* xtn = (xtn_t*) QSE_XTN (sed);
QSE_ASSERT (io != QSE_NULL); QSE_ASSERT (io != QSE_NULL);
switch (io->type) switch (io->type)
@ -185,6 +225,25 @@ static int open_input_stream (
return -1; return -1;
} }
if (base == &xtn->s.in)
{
/* reset script location */
if (io->type == QSE_SED_IOSTD_FILE)
{
qse_sed_setcompid (sed, io->u.file);
}
else
{
qse_char_t buf[64];
buf[0] = (io->type == QSE_SED_IOSTD_MEM)? QSE_T('M'): QSE_T('S');
buf[1] = QSE_T('#');
if (int_to_str (io - xtn->s.in.ptr, &buf[2], QSE_COUNTOF(buf) - 2) >= 0)
qse_sed_setcompid (sed, buf);
}
sed->src.loc.line = 1;
sed->src.loc.colm = 1;
}
return 0; return 0;
} }
@ -257,7 +316,6 @@ static qse_ssize_t read_input_stream (
qse_sed_iostd_t* io, * next; qse_sed_iostd_t* io, * next;
void* old, * new; void* old, * new;
qse_ssize_t n = 0; qse_ssize_t n = 0;
int newline_forced = 0;
if (len > QSE_TYPE_MAX(qse_ssize_t)) len = QSE_TYPE_MAX(qse_ssize_t); if (len > QSE_TYPE_MAX(qse_ssize_t)) len = QSE_TYPE_MAX(qse_ssize_t);
@ -265,7 +323,14 @@ static qse_ssize_t read_input_stream (
{ {
io = base->cur; io = base->cur;
if (base == &xtn->s.in && xtn->s.newline_squeezed)
{
xtn->s.newline_squeezed = 0;
goto open_next;
}
QSE_ASSERT (io != QSE_NULL); QSE_ASSERT (io != QSE_NULL);
if (io->type == QSE_SED_IOSTD_MEM) if (io->type == QSE_SED_IOSTD_MEM)
{ {
n = 0; n = 0;
@ -285,15 +350,9 @@ static qse_ssize_t read_input_stream (
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea); qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
} }
} }
else if (newline_forced) else if (base == &xtn->s.in)
{ {
/* set the line number to 0 for the newline xtn->s.last = buf[n-1];
* squeezed in. see the getnextsc() in sed.c
* to know how line and column numbers are
* incremented */
sed->src.loc.line = 0;
sed->src.loc.colm = 0;
n += newline_forced;
} }
break; break;
@ -303,6 +362,16 @@ static qse_ssize_t read_input_stream (
/* == end of file on the current input stream == */ /* == end of file on the current input stream == */
/* ============================================= */ /* ============================================= */
if (base == &xtn->s.in && xtn->s.last != QSE_T('\n'))
{
/* TODO: different line termination convension */
buf[0] = QSE_T('\n');
n = 1;
xtn->s.newline_squeezed = 1;
break;
}
open_next:
next = base->cur + 1; next = base->cur + 1;
if (next->type == QSE_SED_IOSTD_NULL) if (next->type == QSE_SED_IOSTD_NULL)
{ {
@ -327,25 +396,18 @@ static qse_ssize_t read_input_stream (
n = -1; n = -1;
break; break;
} }
/* successfuly opened the next input stream */
new = arg->handle; new = arg->handle;
arg->handle = old; arg->handle = old;
/* close the previous stream */
close_main_stream (sed, arg, io); close_main_stream (sed, arg, io);
arg->handle = new; arg->handle = new;
base->cur++; base->cur++;
if (base == &xtn->s.in && !newline_forced)
{
/* == ONLY FOR A SCRIPT STREAM ==
* squeeze in a new line in case the previous script
* stream doesn't end with a line terminator.*/
/* TODO: support different line terminator */
buf[0] = QSE_T('\n');
buf++; len--;
newline_forced = 1;
}
} }
while (1); while (1);