changed code to allow an empty label when QSE_SED_STRICT is not set
added qse_sed_stop() and qse_sed_isstop()
This commit is contained in:
parent
7de8b649ef
commit
8f9011bc1d
@ -29,6 +29,25 @@
|
|||||||
#include <qse/cmn/stdio.h>
|
#include <qse/cmn/stdio.h>
|
||||||
#include <qse/cmn/main.h>
|
#include <qse/cmn/main.h>
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
# include <windows.h>
|
||||||
|
# include <tchar.h>
|
||||||
|
# include <process.h>
|
||||||
|
#elif defined(__OS2__)
|
||||||
|
# define INCL_DOSPROCESS
|
||||||
|
# define INCL_DOSEXCEPTIONS
|
||||||
|
# define INCL_ERRORS
|
||||||
|
# include <os2.h>
|
||||||
|
# include <signal.h>
|
||||||
|
#elif defined(__DOS__)
|
||||||
|
# include <dos.h>
|
||||||
|
# include <signal.h>
|
||||||
|
#else
|
||||||
|
# include <unistd.h>
|
||||||
|
# include <errno.h>
|
||||||
|
# include <signal.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static const qse_char_t* g_script_file = QSE_NULL;
|
static const qse_char_t* g_script_file = QSE_NULL;
|
||||||
static qse_char_t* g_script = QSE_NULL;
|
static qse_char_t* g_script = QSE_NULL;
|
||||||
static qse_char_t* g_output_file = QSE_NULL;
|
static qse_char_t* g_output_file = QSE_NULL;
|
||||||
@ -36,6 +55,7 @@ static int g_infile_pos = 0;
|
|||||||
static int g_option = 0;
|
static int g_option = 0;
|
||||||
static int g_separate = 0;
|
static int g_separate = 0;
|
||||||
static qse_ulong_t g_memlimit = 0;
|
static qse_ulong_t g_memlimit = 0;
|
||||||
|
static qse_sed_t* g_sed = QSE_NULL;
|
||||||
|
|
||||||
#if defined(QSE_BUILD_DEBUG)
|
#if defined(QSE_BUILD_DEBUG)
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -93,7 +113,7 @@ static void print_usage (QSE_FILE* out, int argc, qse_char_t* argv[])
|
|||||||
qse_fprintf (out, QSE_T(" -r use the extended regular expression\n"));
|
qse_fprintf (out, QSE_T(" -r use the extended regular expression\n"));
|
||||||
qse_fprintf (out, QSE_T(" -R enable non-standard extensions to the regular expression\n"));
|
qse_fprintf (out, QSE_T(" -R enable non-standard extensions to the regular expression\n"));
|
||||||
qse_fprintf (out, QSE_T(" -s processes input files separately\n"));
|
qse_fprintf (out, QSE_T(" -s processes input files separately\n"));
|
||||||
qse_fprintf (out, QSE_T(" -a perform strict address check\n"));
|
qse_fprintf (out, QSE_T(" -a perform strict address and label check\n"));
|
||||||
qse_fprintf (out, QSE_T(" -w allow address format of start~step\n"));
|
qse_fprintf (out, QSE_T(" -w allow address format of start~step\n"));
|
||||||
qse_fprintf (out, QSE_T(" -x allow text on the same line as c, a, i\n"));
|
qse_fprintf (out, QSE_T(" -x allow text on the same line as c, a, i\n"));
|
||||||
qse_fprintf (out, QSE_T(" -y ensure a newline at text end\n"));
|
qse_fprintf (out, QSE_T(" -y ensure a newline at text end\n"));
|
||||||
@ -289,6 +309,126 @@ void print_exec_error (qse_sed_t* sed)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
static BOOL WINAPI stop_run (DWORD ctrl_type)
|
||||||
|
{
|
||||||
|
if (ctrl_type == CTRL_C_EVENT ||
|
||||||
|
ctrl_type == CTRL_CLOSE_EVENT)
|
||||||
|
{
|
||||||
|
qse_sed_stop (g_sed);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#elif defined(__OS2__)
|
||||||
|
|
||||||
|
static ULONG _System stop_run (
|
||||||
|
PEXCEPTIONREPORTRECORD p1,
|
||||||
|
PEXCEPTIONREGISTRATIONRECORD p2,
|
||||||
|
PCONTEXTRECORD p3,
|
||||||
|
PVOID pv)
|
||||||
|
{
|
||||||
|
if (p1->ExceptionNum == XCPT_SIGNAL)
|
||||||
|
{
|
||||||
|
if (p1->ExceptionInfo[0] == XCPT_SIGNAL_INTR ||
|
||||||
|
p1->ExceptionInfo[0] == XCPT_SIGNAL_KILLPROC ||
|
||||||
|
p1->ExceptionInfo[0] == XCPT_SIGNAL_BREAK)
|
||||||
|
{
|
||||||
|
APIRET rc;
|
||||||
|
|
||||||
|
qse_sed_stop (g_sed);
|
||||||
|
rc = DosAcknowledgeSignalException (p1->ExceptionInfo[0]);
|
||||||
|
return (rc != NO_ERROR)? 1: XCPT_CONTINUE_EXECUTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return XCPT_CONTINUE_SEARCH; /* exception not resolved */
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__DOS__)
|
||||||
|
|
||||||
|
static void setsignal (int sig, void(*handler)(int))
|
||||||
|
{
|
||||||
|
signal (sig, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void stop_run (int sig)
|
||||||
|
{
|
||||||
|
qse_sed_stop (g_sed);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static int setsignal (int sig, void(*handler)(int), int restart)
|
||||||
|
{
|
||||||
|
struct sigaction sa_int;
|
||||||
|
|
||||||
|
sa_int.sa_handler = handler;
|
||||||
|
sigemptyset (&sa_int.sa_mask);
|
||||||
|
|
||||||
|
sa_int.sa_flags = 0;
|
||||||
|
|
||||||
|
if (restart)
|
||||||
|
{
|
||||||
|
#ifdef SA_RESTART
|
||||||
|
sa_int.sa_flags |= SA_RESTART;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef SA_INTERRUPT
|
||||||
|
sa_int.sa_flags |= SA_INTERRUPT;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return sigaction (sig, &sa_int, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void stop_run (int sig)
|
||||||
|
{
|
||||||
|
int e = errno;
|
||||||
|
qse_sed_stop (g_sed);
|
||||||
|
errno = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__OS2__)
|
||||||
|
static EXCEPTIONREGISTRATIONRECORD os2_excrr = { 0 };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void set_intr_run (void)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
SetConsoleCtrlHandler (stop_run, TRUE);
|
||||||
|
#elif defined(__OS2__)
|
||||||
|
APIRET rc;
|
||||||
|
os2_excrr.ExceptionHandler = (ERR)stop_run;
|
||||||
|
rc = DosSetExceptionHandler (&os2_excrr);
|
||||||
|
/*if (rc != NO_ERROR)...*/
|
||||||
|
#elif defined(__DOS__)
|
||||||
|
setsignal (SIGINT, stop_run);
|
||||||
|
#else
|
||||||
|
/*setsignal (SIGINT, stop_run, 1); TO BE MORE COMPATIBLE WITH WIN32*/
|
||||||
|
setsignal (SIGINT, stop_run, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unset_intr_run (void)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
SetConsoleCtrlHandler (stop_run, FALSE);
|
||||||
|
#elif defined(__OS2__)
|
||||||
|
APIRET rc;
|
||||||
|
rc = DosUnsetExceptionHandler (&os2_excrr);
|
||||||
|
/*if (rc != NO_ERROR) ...*/
|
||||||
|
#elif defined(__DOS__)
|
||||||
|
setsignal (SIGINT, SIG_DFL);
|
||||||
|
#else
|
||||||
|
setsignal (SIGINT, SIG_DFL, 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int sed_main (int argc, qse_char_t* argv[])
|
int sed_main (int argc, qse_char_t* argv[])
|
||||||
{
|
{
|
||||||
qse_mmgr_t* mmgr = QSE_NULL;
|
qse_mmgr_t* mmgr = QSE_NULL;
|
||||||
@ -402,6 +542,7 @@ int sed_main (int argc, qse_char_t* argv[])
|
|||||||
print_exec_error (sed);
|
print_exec_error (sed);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
if (qse_sed_isstop (sed)) break;
|
||||||
|
|
||||||
g_infile_pos++;
|
g_infile_pos++;
|
||||||
}
|
}
|
||||||
@ -446,8 +587,12 @@ int sed_main (int argc, qse_char_t* argv[])
|
|||||||
QSE_NULL: g_output_file;
|
QSE_NULL: g_output_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_sed = sed;
|
||||||
|
set_intr_run ();
|
||||||
xx = qse_sed_execstd (sed, in, (g_output_file? &out: QSE_NULL));
|
xx = qse_sed_execstd (sed, in, (g_output_file? &out: QSE_NULL));
|
||||||
if (in) QSE_MMGR_FREE (qse_sed_getmmgr(sed), in);
|
if (in) QSE_MMGR_FREE (qse_sed_getmmgr(sed), in);
|
||||||
|
unset_intr_run ();
|
||||||
|
g_sed = QSE_NULL;
|
||||||
|
|
||||||
if (xx <= -1)
|
if (xx <= -1)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: Awk.hpp 516 2011-07-23 09:03:48Z hyunghwan.chung $
|
* $Id: Awk.hpp 570 2011-09-20 04:40:45Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -743,7 +743,7 @@ public:
|
|||||||
operator rtx_t* () const;
|
operator rtx_t* () const;
|
||||||
|
|
||||||
void stop () const;
|
void stop () const;
|
||||||
bool pendingStop () const;
|
bool isStop () const;
|
||||||
|
|
||||||
errnum_t getErrorNumber () const;
|
errnum_t getErrorNumber () const;
|
||||||
loc_t getErrorLocation () const;
|
loc_t getErrorLocation () const;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: awk.h 568 2011-09-17 15:41:26Z hyunghwan.chung $
|
* $Id: awk.h 570 2011-09-20 04:40:45Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -1639,10 +1639,10 @@ void qse_awk_stopall (
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_awk_pendingstop() function tests if qse_awk_rtx_stop() has been
|
* The qse_awk_rtx_isstop() function tests if qse_awk_rtx_stop() has been
|
||||||
* called.
|
* called.
|
||||||
*/
|
*/
|
||||||
qse_bool_t qse_awk_rtx_pendingstop (
|
qse_bool_t qse_awk_rtx_isstop (
|
||||||
qse_awk_rtx_t* rtx /**< runtime context */
|
qse_awk_rtx_t* rtx /**< runtime context */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sed.h 569 2011-09-19 06:51:02Z hyunghwan.chung $
|
* $Id: sed.h 570 2011-09-20 04:40:45Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -138,7 +138,7 @@ enum qse_sed_option_t
|
|||||||
QSE_SED_KEEPTBS = (1 << 1), /**< keep an trailing backslash */
|
QSE_SED_KEEPTBS = (1 << 1), /**< keep an trailing backslash */
|
||||||
QSE_SED_ENSURENL = (1 << 2), /**< ensure NL at the text end */
|
QSE_SED_ENSURENL = (1 << 2), /**< ensure NL at the text end */
|
||||||
QSE_SED_QUIET = (1 << 3), /**< do not print pattern space */
|
QSE_SED_QUIET = (1 << 3), /**< do not print pattern space */
|
||||||
QSE_SED_STRICT = (1 << 4), /**< do strict address check */
|
QSE_SED_STRICT = (1 << 4), /**< do strict address and label check */
|
||||||
QSE_SED_STARTSTEP = (1 << 5), /**< allow start~step */
|
QSE_SED_STARTSTEP = (1 << 5), /**< allow start~step */
|
||||||
QSE_SED_ZEROA1 = (1 << 6), /**< allow 0,/regex/ */
|
QSE_SED_ZEROA1 = (1 << 6), /**< allow 0,/regex/ */
|
||||||
QSE_SED_SAMELINE = (1 << 7), /**< allow text on the same line as c, a, i */
|
QSE_SED_SAMELINE = (1 << 7), /**< allow text on the same line as c, a, i */
|
||||||
@ -366,6 +366,21 @@ int qse_sed_exec (
|
|||||||
qse_sed_io_fun_t outf /**< stream writer */
|
qse_sed_io_fun_t outf /**< stream writer */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_sed_stop() function breaks running loop in qse_sed_exec().
|
||||||
|
* It doesn't affect blocking calls in stream handlers.
|
||||||
|
*/
|
||||||
|
void qse_sed_stop (
|
||||||
|
qse_sed_t* sed /**< stream editor */
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_sed_isstop() functions tests if qse_sed_stop() is called.
|
||||||
|
*/
|
||||||
|
int qse_sed_isstop (
|
||||||
|
qse_sed_t* sed /**< stream editor */
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_sed_getlformatter() function gets the text formatter for the 'l'
|
* The qse_sed_getlformatter() function gets the text formatter for the 'l'
|
||||||
* command.
|
* command.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: Awk.cpp 556 2011-08-31 15:43:46Z hyunghwan.chung $
|
* $Id: Awk.cpp 570 2011-09-20 04:40:45Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -859,10 +859,10 @@ void Awk::Run::stop () const
|
|||||||
qse_awk_rtx_stop (this->rtx);
|
qse_awk_rtx_stop (this->rtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Awk::Run::pendingStop () const
|
bool Awk::Run::isStop () const
|
||||||
{
|
{
|
||||||
QSE_ASSERT (this->rtx != QSE_NULL);
|
QSE_ASSERT (this->rtx != QSE_NULL);
|
||||||
return qse_awk_rtx_pendingstop (this->rtx)? true: false;
|
return qse_awk_rtx_isstop (this->rtx)? true: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Awk::errnum_t Awk::Run::getErrorNumber () const
|
Awk::errnum_t Awk::Run::getErrorNumber () const
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: run.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
|
* $Id: run.c 570 2011-09-20 04:40:45Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -747,7 +747,7 @@ void qse_awk_rtx_stop (qse_awk_rtx_t* rtx)
|
|||||||
rtx->exit_level = EXIT_ABORT;
|
rtx->exit_level = EXIT_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_bool_t qse_awk_rtx_pendingstop (qse_awk_rtx_t* rtx)
|
qse_bool_t qse_awk_rtx_isstop (qse_awk_rtx_t* rtx)
|
||||||
{
|
{
|
||||||
return (rtx->exit_level == EXIT_ABORT || rtx->awk->stopall);
|
return (rtx->exit_level == EXIT_ABORT || rtx->awk->stopall);
|
||||||
}
|
}
|
||||||
@ -6719,7 +6719,7 @@ qse_char_t* qse_awk_rtx_format (
|
|||||||
for (i = 0; i < fmt_len; i++)
|
for (i = 0; i < fmt_len; i++)
|
||||||
{
|
{
|
||||||
qse_long_t width = -1, prec = -1;
|
qse_long_t width = -1, prec = -1;
|
||||||
qse_bool_t minus = QSE_FALSE;
|
int minus = 0;
|
||||||
|
|
||||||
if (QSE_STR_LEN(fbu) == 0)
|
if (QSE_STR_LEN(fbu) == 0)
|
||||||
{
|
{
|
||||||
@ -6733,7 +6733,7 @@ qse_char_t* qse_awk_rtx_format (
|
|||||||
fmt[i] == QSE_T('0') || fmt[i] == QSE_T('+') ||
|
fmt[i] == QSE_T('0') || fmt[i] == QSE_T('+') ||
|
||||||
fmt[i] == QSE_T('-')))
|
fmt[i] == QSE_T('-')))
|
||||||
{
|
{
|
||||||
if (fmt[i] == QSE_T('-')) minus = QSE_TRUE;
|
if (fmt[i] == QSE_T('-')) minus = 1;
|
||||||
FMT_CHAR (fmt[i]); i++;
|
FMT_CHAR (fmt[i]); i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sed.c 569 2011-09-19 06:51:02Z hyunghwan.chung $
|
* $Id: sed.c 570 2011-09-20 04:40:45Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -102,7 +102,7 @@ int qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
|
|||||||
qse_map_mancbs(QSE_MAP_MANCBS_INLINE_KEY_COPIER)
|
qse_map_mancbs(QSE_MAP_MANCBS_INLINE_KEY_COPIER)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (qse_str_init (&sed->e.txt.appended, mmgr, 256) <= -1) goto oops_5;
|
if (qse_str_init (&sed->e.txt.append, mmgr, 256) <= -1) goto oops_5;
|
||||||
if (qse_str_init (&sed->e.txt.hold, mmgr, 256) <= -1) goto oops_6;
|
if (qse_str_init (&sed->e.txt.hold, mmgr, 256) <= -1) goto oops_6;
|
||||||
if (qse_str_init (&sed->e.txt.subst, mmgr, 256) <= -1) goto oops_7;
|
if (qse_str_init (&sed->e.txt.subst, mmgr, 256) <= -1) goto oops_7;
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ int qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
|
|||||||
oops_7:
|
oops_7:
|
||||||
qse_str_fini (&sed->e.txt.hold);
|
qse_str_fini (&sed->e.txt.hold);
|
||||||
oops_6:
|
oops_6:
|
||||||
qse_str_fini (&sed->e.txt.appended);
|
qse_str_fini (&sed->e.txt.append);
|
||||||
oops_5:
|
oops_5:
|
||||||
qse_map_fini (&sed->tmp.labs);
|
qse_map_fini (&sed->tmp.labs);
|
||||||
oops_3:
|
oops_3:
|
||||||
@ -134,7 +134,7 @@ void qse_sed_fini (qse_sed_t* 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);
|
||||||
qse_str_fini (&sed->e.txt.appended);
|
qse_str_fini (&sed->e.txt.append);
|
||||||
|
|
||||||
qse_map_fini (&sed->tmp.labs);
|
qse_map_fini (&sed->tmp.labs);
|
||||||
qse_str_fini (&sed->tmp.lab);
|
qse_str_fini (&sed->tmp.lab);
|
||||||
@ -342,9 +342,7 @@ static int matchtre (
|
|||||||
c == QSE_T(';') || IS_LINTERM(c) || \
|
c == QSE_T(';') || IS_LINTERM(c) || \
|
||||||
c == QSE_T('{') || c == QSE_T('}'))
|
c == QSE_T('{') || c == QSE_T('}'))
|
||||||
/* check if c can compose a label */
|
/* check if c can compose a label */
|
||||||
#define IS_LABCHAR(c) \
|
#define IS_LABCHAR(c) (!IS_CMDTERM(c) && !IS_WSPACE(c))
|
||||||
(QSE_ISALNUM(c) || c == QSE_T('.') || \
|
|
||||||
c == QSE_T('-') || c == QSE_T('_'))
|
|
||||||
|
|
||||||
#define CURSC(sed) ((sed)->src.cc)
|
#define CURSC(sed) ((sed)->src.cc)
|
||||||
#define NXTSC(sed) getnextsc(sed)
|
#define NXTSC(sed) getnextsc(sed)
|
||||||
@ -821,44 +819,52 @@ static int get_label (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
if (!IS_LABCHAR(c))
|
if (!IS_LABCHAR(c))
|
||||||
{
|
{
|
||||||
/* label name is empty */
|
/* label name is empty */
|
||||||
SETERR0 (sed, QSE_SED_ELABEM, &sed->src.loc);
|
if (sed->option & QSE_SED_STRICT)
|
||||||
return -1;
|
{
|
||||||
|
SETERR0 (sed, QSE_SED_ELABEM, &sed->src.loc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* empty label. noop command. don't register anything */
|
||||||
|
qse_str_clear (&sed->tmp.lab);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
qse_str_clear (&sed->tmp.lab);
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
if (qse_str_ccat (&sed->tmp.lab, c) == (qse_size_t)-1)
|
qse_str_clear (&sed->tmp.lab);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (qse_str_ccat (&sed->tmp.lab, c) == (qse_size_t)-1)
|
||||||
|
{
|
||||||
|
SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
c = NXTSC (sed);
|
||||||
|
}
|
||||||
|
while (IS_LABCHAR(c));
|
||||||
|
|
||||||
|
if (qse_map_search (
|
||||||
|
&sed->tmp.labs,
|
||||||
|
QSE_STR_PTR(&sed->tmp.lab),
|
||||||
|
QSE_STR_LEN(&sed->tmp.lab)) != QSE_NULL)
|
||||||
|
{
|
||||||
|
SETERR1 (
|
||||||
|
sed, QSE_SED_ELABDU,
|
||||||
|
QSE_STR_PTR(&sed->tmp.lab),
|
||||||
|
QSE_STR_LEN(&sed->tmp.lab),
|
||||||
|
&sed->src.loc
|
||||||
|
);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qse_map_insert (
|
||||||
|
&sed->tmp.labs,
|
||||||
|
QSE_STR_PTR(&sed->tmp.lab), QSE_STR_LEN(&sed->tmp.lab),
|
||||||
|
cmd, 0) == QSE_NULL)
|
||||||
{
|
{
|
||||||
SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL);
|
SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
c = NXTSC (sed);
|
|
||||||
}
|
|
||||||
while (IS_LABCHAR(c));
|
|
||||||
|
|
||||||
if (qse_map_search (
|
|
||||||
&sed->tmp.labs,
|
|
||||||
QSE_STR_PTR(&sed->tmp.lab),
|
|
||||||
QSE_STR_LEN(&sed->tmp.lab)) != QSE_NULL)
|
|
||||||
{
|
|
||||||
SETERR1 (
|
|
||||||
sed, QSE_SED_ELABDU,
|
|
||||||
QSE_STR_PTR(&sed->tmp.lab),
|
|
||||||
QSE_STR_LEN(&sed->tmp.lab),
|
|
||||||
&sed->src.loc
|
|
||||||
);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qse_map_insert (
|
|
||||||
&sed->tmp.labs,
|
|
||||||
QSE_STR_PTR(&sed->tmp.lab), QSE_STR_LEN(&sed->tmp.lab),
|
|
||||||
cmd, 0) == QSE_NULL)
|
|
||||||
{
|
|
||||||
SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (IS_SPACE(c)) c = NXTSC (sed);
|
while (IS_SPACE(c)) c = NXTSC (sed);
|
||||||
@ -1748,7 +1754,7 @@ static int read_file (
|
|||||||
|
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
if (qse_str_ccat (&sed->e.txt.appended, buf[i]) == (qse_size_t)-1)
|
if (qse_str_ccat (&sed->e.txt.append, buf[i]) == (qse_size_t)-1)
|
||||||
{
|
{
|
||||||
sed->e.in.fun (
|
sed->e.in.fun (
|
||||||
sed, QSE_SED_IO_CLOSE,
|
sed, QSE_SED_IO_CLOSE,
|
||||||
@ -1763,7 +1769,7 @@ static int read_file (
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (qse_str_ncat (&sed->e.txt.appended, buf, n) == (qse_size_t)-1)
|
if (qse_str_ncat (&sed->e.txt.append, buf, n) == (qse_size_t)-1)
|
||||||
{
|
{
|
||||||
sed->e.in.fun (
|
sed->e.in.fun (
|
||||||
sed, QSE_SED_IO_CLOSE,
|
sed, QSE_SED_IO_CLOSE,
|
||||||
@ -2585,7 +2591,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
|
|
||||||
case QSE_SED_CMD_APPEND:
|
case QSE_SED_CMD_APPEND:
|
||||||
if (qse_str_ncat (
|
if (qse_str_ncat (
|
||||||
&sed->e.txt.appended,
|
&sed->e.txt.append,
|
||||||
cmd->u.text.ptr,
|
cmd->u.text.ptr,
|
||||||
cmd->u.text.len) == (qse_size_t)-1)
|
cmd->u.text.len) == (qse_size_t)-1)
|
||||||
{
|
{
|
||||||
@ -3024,15 +3030,15 @@ static int emit_output (qse_sed_t* sed, int skipline)
|
|||||||
if (n <= -1) return -1;
|
if (n <= -1) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write text appended by a and r */
|
/* write text append by a and r */
|
||||||
n = write_str (
|
n = write_str (
|
||||||
sed,
|
sed,
|
||||||
QSE_STR_PTR(&sed->e.txt.appended),
|
QSE_STR_PTR(&sed->e.txt.append),
|
||||||
QSE_STR_LEN(&sed->e.txt.appended)
|
QSE_STR_LEN(&sed->e.txt.append)
|
||||||
);
|
);
|
||||||
if (n <= -1) return -1;
|
if (n <= -1) return -1;
|
||||||
|
|
||||||
qse_str_clear (&sed->e.txt.appended);
|
qse_str_clear (&sed->e.txt.append);
|
||||||
|
|
||||||
/* flush the output stream in case it's not flushed
|
/* flush the output stream in case it's not flushed
|
||||||
* in write functions */
|
* in write functions */
|
||||||
@ -3067,10 +3073,11 @@ int qse_sed_exec (qse_sed_t* sed, qse_sed_io_fun_t inf, qse_sed_io_fun_t outf)
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sed->e.stopreq = 0;
|
||||||
sed->e.last_rex = QSE_NULL;
|
sed->e.last_rex = QSE_NULL;
|
||||||
|
|
||||||
sed->e.subst_done = 0;
|
sed->e.subst_done = 0;
|
||||||
qse_str_clear (&sed->e.txt.appended);
|
qse_str_clear (&sed->e.txt.append);
|
||||||
qse_str_clear (&sed->e.txt.subst);
|
qse_str_clear (&sed->e.txt.subst);
|
||||||
qse_str_clear (&sed->e.txt.hold);
|
qse_str_clear (&sed->e.txt.hold);
|
||||||
if (qse_str_ccat (&sed->e.txt.hold, QSE_T('\n')) == (qse_size_t)-1)
|
if (qse_str_ccat (&sed->e.txt.hold, QSE_T('\n')) == (qse_size_t)-1)
|
||||||
@ -3144,7 +3151,7 @@ int qse_sed_exec (qse_sed_t* sed, qse_sed_io_fun_t inf, qse_sed_io_fun_t outf)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1)
|
while (!sed->e.stopreq)
|
||||||
{
|
{
|
||||||
n = read_line (sed, 0);
|
n = read_line (sed, 0);
|
||||||
if (n <= -1) { ret = -1; goto done; }
|
if (n <= -1) { ret = -1; goto done; }
|
||||||
@ -3152,6 +3159,10 @@ int qse_sed_exec (qse_sed_t* sed, qse_sed_io_fun_t inf, qse_sed_io_fun_t outf)
|
|||||||
|
|
||||||
if (sed->cmd.fb.len > 0)
|
if (sed->cmd.fb.len > 0)
|
||||||
{
|
{
|
||||||
|
/* the first command block contains at least 1 command
|
||||||
|
* to execute. an empty script like ' ' has no commands,
|
||||||
|
* so this block is skipped. */
|
||||||
|
|
||||||
qse_sed_cmd_t* c, * j;
|
qse_sed_cmd_t* c, * j;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
@ -3177,6 +3188,7 @@ int qse_sed_exec (qse_sed_t* sed, qse_sed_io_fun_t inf, qse_sed_io_fun_t outf)
|
|||||||
if (emit_output (sed, 0) <= -1) ret = -1;
|
if (emit_output (sed, 0) <= -1) ret = -1;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (sed->e.stopreq) goto done;
|
||||||
if (j == &sed->cmd.again) goto again;
|
if (j == &sed->cmd.again) goto again;
|
||||||
|
|
||||||
/* go to the next command */
|
/* go to the next command */
|
||||||
@ -3198,6 +3210,16 @@ done3:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qse_sed_stop (qse_sed_t* sed)
|
||||||
|
{
|
||||||
|
sed->e.stopreq = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qse_sed_isstop (qse_sed_t* sed)
|
||||||
|
{
|
||||||
|
return sed->e.stopreq;
|
||||||
|
}
|
||||||
|
|
||||||
qse_sed_lformatter_t qse_sed_getlformatter (qse_sed_t* sed)
|
qse_sed_lformatter_t qse_sed_getlformatter (qse_sed_t* sed)
|
||||||
{
|
{
|
||||||
return sed->lformatter;
|
return sed->lformatter;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sed.h 568 2011-09-17 15:41:26Z hyunghwan.chung $
|
* $Id: sed.h 570 2011-09-20 04:40:45Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -261,7 +261,7 @@ struct qse_sed_t
|
|||||||
/** text buffers */
|
/** text buffers */
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
qse_str_t appended;
|
qse_str_t append;
|
||||||
qse_str_t hold; /* hold space */
|
qse_str_t hold; /* hold space */
|
||||||
qse_str_t subst;
|
qse_str_t subst;
|
||||||
} txt;
|
} txt;
|
||||||
@ -270,6 +270,9 @@ struct qse_sed_t
|
|||||||
* since the last read on the input stream. */
|
* since the last read on the input stream. */
|
||||||
int subst_done;
|
int subst_done;
|
||||||
void* last_rex;
|
void* last_rex;
|
||||||
|
|
||||||
|
/** stop requested */
|
||||||
|
int stopreq;
|
||||||
} e;
|
} e;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user