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:
parent
5eca3cd4b5
commit
915ef99f07
@ -463,11 +463,17 @@ static void trace_exec (qse_sed_t* sed, qse_sed_exec_op_t op, const qse_sed_cmd_
|
||||
break;
|
||||
#endif
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -267,6 +267,12 @@ public:
|
||||
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
|
||||
/// number from an input console.
|
||||
|
@ -130,7 +130,9 @@ struct qse_sed_adr_t
|
||||
struct qse_sed_cmd_t
|
||||
{
|
||||
qse_char_t type;
|
||||
qse_sed_loc_t loc;
|
||||
|
||||
const qse_char_t* lid;
|
||||
qse_sed_loc_t loc;
|
||||
|
||||
int negated;
|
||||
|
||||
@ -521,18 +523,40 @@ void qse_sed_setlformatter (
|
||||
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.
|
||||
* @return current input line number
|
||||
*/
|
||||
qse_size_t qse_sed_getlinnum (
|
||||
qse_size_t qse_sed_getlinenum (
|
||||
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_size_t num /**< a line number */
|
||||
);
|
||||
|
@ -112,7 +112,8 @@ Sed::loc_t Sed::getErrorLocation () const
|
||||
if (sed == QSE_NULL)
|
||||
{
|
||||
loc_t loc;
|
||||
loc.line = 0; loc.colm = 0;
|
||||
loc.line = 0;
|
||||
loc.colm = 0;
|
||||
return loc;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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 ()
|
||||
{
|
||||
QSE_ASSERT (sed != QSE_NULL);
|
||||
return qse_sed_getlinnum (sed);
|
||||
return qse_sed_getlinenum (this->sed);
|
||||
}
|
||||
|
||||
void Sed::setConsoleLine (size_t num)
|
||||
{
|
||||
QSE_ASSERT (sed != QSE_NULL);
|
||||
qse_sed_setlinnum (sed, num);
|
||||
qse_sed_setlinenum (this->sed, num);
|
||||
}
|
||||
|
||||
Sed::ssize_t Sed::sin (
|
||||
|
@ -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_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 int emit_output (qse_sed_t* sed, int skipline);
|
||||
|
||||
@ -130,6 +131,7 @@ oops_1:
|
||||
void qse_sed_fini (qse_sed_t* sed)
|
||||
{
|
||||
free_all_command_blocks (sed);
|
||||
free_all_cids (sed);
|
||||
|
||||
qse_str_fini (&sed->e.txt.subst);
|
||||
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)
|
||||
{
|
||||
@ -1501,6 +1512,7 @@ static int get_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
qse_cint_t c;
|
||||
|
||||
c = CURSC (sed);
|
||||
cmd->lid = sed->src.cid? ((const qse_char_t*)(sed->src.cid + 1)): QSE_NULL;
|
||||
cmd->loc = sed->src.loc;
|
||||
switch (c)
|
||||
{
|
||||
@ -1739,20 +1751,13 @@ int qse_sed_comp (qse_sed_t* sed, qse_sed_io_fun_t inf)
|
||||
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_command_blocks (sed);
|
||||
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 */
|
||||
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;
|
||||
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)
|
||||
{
|
||||
int n;
|
||||
@ -3615,12 +3625,33 @@ void qse_sed_setlformatter (qse_sed_t* sed, qse_sed_lformatter_t 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -3634,3 +3665,4 @@ void qse_sed_setexectracer (qse_sed_t* sed, qse_sed_exec_tracer_t tracer)
|
||||
{
|
||||
sed->e.tracer = tracer;
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,12 @@ struct qse_sed_cmd_blk_t
|
||||
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
|
||||
*/
|
||||
@ -88,6 +94,7 @@ struct qse_sed_t
|
||||
qse_char_t buf[1024];
|
||||
int eof;
|
||||
|
||||
qse_sed_cid_t* cid;
|
||||
qse_sed_loc_t loc; /**< location */
|
||||
qse_cint_t cc; /**< last character read */
|
||||
const qse_char_t* ptr; /**< beginning of the source text */
|
||||
|
@ -45,6 +45,8 @@ struct xtn_t
|
||||
struct
|
||||
{
|
||||
xtn_in_t in;
|
||||
qse_char_t last;
|
||||
int newline_squeezed;
|
||||
} s;
|
||||
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)
|
||||
{
|
||||
return qse_sed_openstdwithmmgr (QSE_MMGR_GETDFL(), xtnsize);
|
||||
@ -151,7 +191,7 @@ static void close_main_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)
|
||||
{
|
||||
/*xtn_t* xtn = (xtn_t*) QSE_XTN (sed);*/
|
||||
xtn_t* xtn = (xtn_t*) QSE_XTN (sed);
|
||||
|
||||
QSE_ASSERT (io != QSE_NULL);
|
||||
switch (io->type)
|
||||
@ -185,6 +225,25 @@ static int open_input_stream (
|
||||
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;
|
||||
}
|
||||
|
||||
@ -257,7 +316,6 @@ static qse_ssize_t read_input_stream (
|
||||
qse_sed_iostd_t* io, * next;
|
||||
void* old, * new;
|
||||
qse_ssize_t n = 0;
|
||||
int newline_forced = 0;
|
||||
|
||||
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;
|
||||
|
||||
if (base == &xtn->s.in && xtn->s.newline_squeezed)
|
||||
{
|
||||
xtn->s.newline_squeezed = 0;
|
||||
goto open_next;
|
||||
}
|
||||
|
||||
QSE_ASSERT (io != QSE_NULL);
|
||||
|
||||
if (io->type == QSE_SED_IOSTD_MEM)
|
||||
{
|
||||
n = 0;
|
||||
@ -285,15 +350,9 @@ static qse_ssize_t read_input_stream (
|
||||
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
|
||||
* 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;
|
||||
xtn->s.last = buf[n-1];
|
||||
}
|
||||
|
||||
break;
|
||||
@ -303,6 +362,16 @@ static qse_ssize_t read_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;
|
||||
if (next->type == QSE_SED_IOSTD_NULL)
|
||||
{
|
||||
@ -327,25 +396,18 @@ static qse_ssize_t read_input_stream (
|
||||
n = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* successfuly opened the next input stream */
|
||||
new = arg->handle;
|
||||
|
||||
arg->handle = old;
|
||||
|
||||
/* close the previous stream */
|
||||
close_main_stream (sed, arg, io);
|
||||
|
||||
arg->handle = new;
|
||||
|
||||
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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user