* fixed a rounding bug of reallocation size in _realloc_merge of qse_xma_t.
* replaced rex with tre in qse_sed_t * added submatch reference for the 's' command into qse_sed_t * changed some options and functions for tre integration in qse_sed_t
This commit is contained in:
parent
1efa41052e
commit
3fe32033cb
@ -137,7 +137,7 @@ static void print_usage (QSE_FILE* out, int argc, qse_char_t* argv[])
|
|||||||
qse_fprintf (out, QSE_T(" -h show this message\n"));
|
qse_fprintf (out, QSE_T(" -h show this message\n"));
|
||||||
qse_fprintf (out, QSE_T(" -n disable auto-print\n"));
|
qse_fprintf (out, QSE_T(" -n disable auto-print\n"));
|
||||||
qse_fprintf (out, QSE_T(" -a perform strict address check\n"));
|
qse_fprintf (out, QSE_T(" -a perform strict address check\n"));
|
||||||
qse_fprintf (out, QSE_T(" -r allow {n,m} in a regular expression\n"));
|
qse_fprintf (out, QSE_T(" -r use the extended regular expression\n"));
|
||||||
qse_fprintf (out, QSE_T(" -s allow text on the same line as c, a, i\n"));
|
qse_fprintf (out, QSE_T(" -s allow text on the same line as c, a, i\n"));
|
||||||
qse_fprintf (out, QSE_T(" -l ensure a newline at text end\n"));
|
qse_fprintf (out, QSE_T(" -l ensure a newline at text end\n"));
|
||||||
qse_fprintf (out, QSE_T(" -f file specify a script file\n"));
|
qse_fprintf (out, QSE_T(" -f file specify a script file\n"));
|
||||||
@ -190,7 +190,7 @@ static int handle_args (int argc, qse_char_t* argv[])
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case QSE_T('r'):
|
case QSE_T('r'):
|
||||||
g_option |= QSE_SED_REXBOUND;
|
g_option |= QSE_SED_EXTENDEDREX;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QSE_T('s'):
|
case QSE_T('s'):
|
||||||
@ -237,26 +237,25 @@ qse_char_t* load_script_file (const qse_char_t* file)
|
|||||||
fp = qse_fopen (file, QSE_T("r"));
|
fp = qse_fopen (file, QSE_T("r"));
|
||||||
if (fp == QSE_NULL) return QSE_NULL;
|
if (fp == QSE_NULL) return QSE_NULL;
|
||||||
|
|
||||||
if (qse_str_init (&script, QSE_MMGR_GETDFL(), 1024) == QSE_NULL)
|
if (qse_str_init (&script, QSE_MMGR_GETDFL(), 1024) <= -1)
|
||||||
{
|
{
|
||||||
qse_fclose (fp);
|
qse_fclose (fp);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
while ((c = qse_fgetc (fp)) != QSE_CHAR_EOF)
|
while ((c = qse_fgetc (fp)) != QSE_CHAR_EOF)
|
||||||
{
|
{
|
||||||
if (qse_str_ccat (&script, c) == (qse_size_t)-1)
|
if (qse_str_ccat (&script, c) == (qse_size_t)-1)
|
||||||
{
|
{
|
||||||
qse_fclose (fp);
|
|
||||||
qse_str_fini (&script);
|
qse_str_fini (&script);
|
||||||
|
qse_fclose (fp);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_fclose (fp);
|
|
||||||
qse_str_yield (&script, &xstr, 0);
|
qse_str_yield (&script, &xstr, 0);
|
||||||
qse_str_fini (&script);
|
qse_str_fini (&script);
|
||||||
|
qse_fclose (fp);
|
||||||
|
|
||||||
return xstr.ptr;
|
return xstr.ptr;
|
||||||
}
|
}
|
||||||
@ -293,7 +292,7 @@ int sed_main (int argc, qse_char_t* argv[])
|
|||||||
|
|
||||||
qse_sed_setoption (sed, g_option);
|
qse_sed_setoption (sed, g_option);
|
||||||
|
|
||||||
if (g_script_file != QSE_NULL)
|
if (g_script_file)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (g_script == QSE_NULL);
|
QSE_ASSERT (g_script == QSE_NULL);
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ int qse_tre_execx (
|
|||||||
const qse_char_t* str,
|
const qse_char_t* str,
|
||||||
qse_size_t len,
|
qse_size_t len,
|
||||||
qse_tre_match_t* pmatch,
|
qse_tre_match_t* pmatch,
|
||||||
qse_size_t nmatch,
|
qse_size_t nmatch,
|
||||||
int eflags
|
int eflags
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ int qse_tre_exec (
|
|||||||
qse_tre_t* tre,
|
qse_tre_t* tre,
|
||||||
const qse_char_t* str,
|
const qse_char_t* str,
|
||||||
qse_tre_match_t* pmatch,
|
qse_tre_match_t* pmatch,
|
||||||
qse_size_t nmatch,
|
qse_size_t nmatch,
|
||||||
int eflags
|
int eflags
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: Sed.hpp 507 2011-07-15 15:53:49Z hyunghwan.chung $
|
* $Id: Sed.hpp 558 2011-09-02 15:27:44Z 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.
|
||||||
@ -54,8 +54,10 @@ public:
|
|||||||
typedef qse_sed_io_arg_t io_arg_t;
|
typedef qse_sed_io_arg_t io_arg_t;
|
||||||
/// The option_t type redefines an option type
|
/// The option_t type redefines an option type
|
||||||
typedef qse_sed_option_t option_t;
|
typedef qse_sed_option_t option_t;
|
||||||
|
#if 0
|
||||||
/// The depth_t type redefines an depth IDs
|
/// The depth_t type redefines an depth IDs
|
||||||
typedef qse_sed_depth_t depth_t;
|
typedef qse_sed_depth_t depth_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The Stream class is a base class for I/O operation during
|
/// The Stream class is a base class for I/O operation during
|
||||||
@ -214,6 +216,7 @@ public:
|
|||||||
int opt ///< option code
|
int opt ///< option code
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#if 0
|
||||||
///
|
///
|
||||||
/// The getMaxDepth() function gets the maximum processing depth for
|
/// The getMaxDepth() function gets the maximum processing depth for
|
||||||
/// an operation type identified by @a id.
|
/// an operation type identified by @a id.
|
||||||
@ -229,6 +232,7 @@ public:
|
|||||||
int ids, ///< 0 or a number OR'ed of depth_t values
|
int ids, ///< 0 or a number OR'ed of depth_t values
|
||||||
size_t depth ///< 0 maximum depth
|
size_t depth ///< 0 maximum depth
|
||||||
);
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The getErrorMessage() function gets the description of the last
|
/// The getErrorMessage() function gets the description of the last
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sed.h 507 2011-07-15 15:53:49Z hyunghwan.chung $
|
* $Id: sed.h 558 2011-09-02 15:27:44Z 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.
|
||||||
@ -131,29 +131,17 @@ typedef const qse_char_t* (*qse_sed_errstr_t) (
|
|||||||
*/
|
*/
|
||||||
enum qse_sed_option_t
|
enum qse_sed_option_t
|
||||||
{
|
{
|
||||||
QSE_SED_STRIPLS = (1 << 0), /**< strip leading spaces from text */
|
QSE_SED_STRIPLS = (1 << 0), /**< strip leading spaces from text */
|
||||||
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 check */
|
||||||
QSE_SED_STARTSTEP = (1 << 5), /**< allow start~step */
|
QSE_SED_STARTSTEP = (1 << 5), /**< allow start~step */
|
||||||
QSE_SED_REXBOUND = (1 << 6), /**< allow {n,m} in regular expression */
|
QSE_SED_EXTENDEDREX = (1 << 6), /**< allow {n,m} in regular expression */
|
||||||
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 */
|
||||||
};
|
};
|
||||||
typedef enum qse_sed_option_t qse_sed_option_t;
|
typedef enum qse_sed_option_t qse_sed_option_t;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The qse_sed_depth_t type defines IDs for qse_sed_getmaxdepth() and
|
|
||||||
* qse_sed_setmaxdepth().
|
|
||||||
*/
|
|
||||||
enum qse_sed_depth_t
|
|
||||||
{
|
|
||||||
QSE_SED_DEPTH_REX_BUILD = (1 << 0),
|
|
||||||
QSE_SED_DEPTH_REX_MATCH = (1 << 1)
|
|
||||||
};
|
|
||||||
typedef enum qse_sed_depth_t qse_sed_depth_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_sed_io_cmd_t type defines I/O command codes. The code indicates
|
* The qse_sed_io_cmd_t type defines I/O command codes. The code indicates
|
||||||
* the action to take in an I/O handler.
|
* the action to take in an I/O handler.
|
||||||
@ -246,23 +234,6 @@ void qse_sed_setoption (
|
|||||||
int opt /**< 0 or a number OR'ed of #qse_sed_option_t values */
|
int opt /**< 0 or a number OR'ed of #qse_sed_option_t values */
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
* The qse_sed_getmaxdepth() gets the maximum processing depth.
|
|
||||||
*/
|
|
||||||
qse_size_t qse_sed_getmaxdepth (
|
|
||||||
qse_sed_t* sed, /**< stream editor */
|
|
||||||
qse_sed_depth_t id /**< one of qse_sed_depth_t values */
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The qse_sed_setmaxdepth() sets the maximum processing depth.
|
|
||||||
*/
|
|
||||||
void qse_sed_setmaxdepth (
|
|
||||||
qse_sed_t* sed, /**< stream editor */
|
|
||||||
int ids, /**< 0 or a number OR'ed of #qse_sed_depth_t values */
|
|
||||||
qse_size_t depth /**< maximum depth level */
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_sed_geterrstr() gets an error string getter.
|
* The qse_sed_geterrstr() gets an error string getter.
|
||||||
*/
|
*/
|
||||||
|
@ -47,7 +47,7 @@ qse_tre_t* qse_tre_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
|
|||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QSE_NULL;
|
return tre;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qse_tre_close (qse_tre_t* tre)
|
void qse_tre_close (qse_tre_t* tre)
|
||||||
|
@ -49,8 +49,8 @@ struct qse_xma_blk_t
|
|||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
qse_xma_blk_t* prev; /**< link to the previous block */
|
qse_xma_blk_t* prev; /**< link to the previous adjacent block */
|
||||||
qse_xma_blk_t* next; /**< link to the next block */
|
qse_xma_blk_t* next; /**< link to the next adjacent block */
|
||||||
} b;
|
} b;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -379,7 +379,7 @@ void* qse_xma_alloc (qse_xma_t* xma, qse_size_t size)
|
|||||||
for (++xfi; xfi < XFIMAX(xma) - 1; xfi++)
|
for (++xfi; xfi < XFIMAX(xma) - 1; xfi++)
|
||||||
{
|
{
|
||||||
free = alloc_from_freelist (xma, xfi, size);
|
free = alloc_from_freelist (xma, xfi, size);
|
||||||
if (free != QSE_NULL) break;
|
if (free) break;
|
||||||
}
|
}
|
||||||
if (free == QSE_NULL) return QSE_NULL;
|
if (free == QSE_NULL) return QSE_NULL;
|
||||||
}
|
}
|
||||||
@ -392,16 +392,20 @@ static void* _realloc_merge (qse_xma_t* xma, void* b, qse_size_t size)
|
|||||||
{
|
{
|
||||||
qse_xma_blk_t* blk = USR_TO_SYS(b);
|
qse_xma_blk_t* blk = USR_TO_SYS(b);
|
||||||
|
|
||||||
|
/* rounds up 'size' to be multiples of ALIGN */
|
||||||
|
size = ((size + ALIGN - 1) / ALIGN) * ALIGN;
|
||||||
|
|
||||||
if (size > blk->size)
|
if (size > blk->size)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* grow the current block
|
* grow the current block
|
||||||
*/
|
*/
|
||||||
|
qse_size_t req;
|
||||||
qse_size_t req = size - blk->size;
|
|
||||||
qse_xma_blk_t* n;
|
qse_xma_blk_t* n;
|
||||||
qse_size_t rem;
|
qse_size_t rem;
|
||||||
|
|
||||||
|
req = size - blk->size;
|
||||||
|
|
||||||
n = blk->b.next;
|
n = blk->b.next;
|
||||||
|
|
||||||
/* check if the next adjacent block is available */
|
/* check if the next adjacent block is available */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: Sed.cpp 441 2011-04-22 14:28:43Z hyunghwan.chung $
|
* $Id: Sed.cpp 558 2011-09-02 15:27:44Z 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.
|
||||||
@ -80,6 +80,7 @@ void Sed::setOption (int opt)
|
|||||||
qse_sed_setoption (sed, opt);
|
qse_sed_setoption (sed, opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
Sed::size_t Sed::getMaxDepth (depth_t id) const
|
Sed::size_t Sed::getMaxDepth (depth_t id) const
|
||||||
{
|
{
|
||||||
QSE_ASSERT (sed != QSE_NULL);
|
QSE_ASSERT (sed != QSE_NULL);
|
||||||
@ -91,6 +92,7 @@ void Sed::setMaxDepth (int ids, size_t depth)
|
|||||||
QSE_ASSERT (sed != QSE_NULL);
|
QSE_ASSERT (sed != QSE_NULL);
|
||||||
qse_sed_setmaxdepth (sed, ids, depth);
|
qse_sed_setmaxdepth (sed, ids, depth);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const Sed::char_t* Sed::getErrorMessage () const
|
const Sed::char_t* Sed::getErrorMessage () const
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sed.c 557 2011-09-01 14:45:06Z hyunghwan.chung $
|
* $Id: sed.c 558 2011-09-02 15:27:44Z 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.
|
||||||
@ -20,17 +20,19 @@
|
|||||||
|
|
||||||
#include "sed.h"
|
#include "sed.h"
|
||||||
#include "../cmn/mem.h"
|
#include "../cmn/mem.h"
|
||||||
#include <qse/cmn/rex.h>
|
|
||||||
#include <qse/cmn/chr.h>
|
#include <qse/cmn/chr.h>
|
||||||
|
|
||||||
|
#ifdef USE_REX
|
||||||
|
# include <qse/cmn/rex.h>
|
||||||
|
#else
|
||||||
|
# include <qse/cmn/tre.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
QSE_IMPLEMENT_COMMON_FUNCTIONS (sed)
|
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 int qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr);
|
|
||||||
static void qse_sed_fini (qse_sed_t* sed);
|
|
||||||
|
|
||||||
#define SETERR0(sed,num,loc) \
|
#define SETERR0(sed,num,loc) \
|
||||||
do { qse_sed_seterror (sed, num, QSE_NULL, loc); } while (0)
|
do { qse_sed_seterror (sed, num, QSE_NULL, loc); } while (0)
|
||||||
|
|
||||||
@ -73,7 +75,7 @@ void qse_sed_close (qse_sed_t* sed)
|
|||||||
QSE_MMGR_FREE (sed->mmgr, sed);
|
QSE_MMGR_FREE (sed->mmgr, sed);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
|
int qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
|
||||||
{
|
{
|
||||||
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
|
||||||
|
|
||||||
@ -121,7 +123,7 @@ oops_1:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static 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);
|
||||||
|
|
||||||
@ -145,6 +147,8 @@ int qse_sed_getoption (qse_sed_t* sed)
|
|||||||
return sed->option;
|
return sed->option;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_REX
|
||||||
qse_size_t qse_sed_getmaxdepth (qse_sed_t* sed, qse_sed_depth_t id)
|
qse_size_t qse_sed_getmaxdepth (qse_sed_t* sed, qse_sed_depth_t id)
|
||||||
{
|
{
|
||||||
return (id & QSE_SED_DEPTH_REX_BUILD)? sed->depth.rex.build:
|
return (id & QSE_SED_DEPTH_REX_BUILD)? sed->depth.rex.build:
|
||||||
@ -156,6 +160,75 @@ void qse_sed_setmaxdepth (qse_sed_t* sed, int ids, qse_size_t depth)
|
|||||||
if (ids & QSE_SED_DEPTH_REX_BUILD) sed->depth.rex.build = depth;
|
if (ids & QSE_SED_DEPTH_REX_BUILD) sed->depth.rex.build = depth;
|
||||||
if (ids & QSE_SED_DEPTH_REX_MATCH) sed->depth.rex.match = depth;
|
if (ids & QSE_SED_DEPTH_REX_MATCH) sed->depth.rex.match = depth;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static qse_tre_t* maketre (
|
||||||
|
qse_sed_t* sed, const qse_cstr_t* str, const qse_sed_loc_t* loc)
|
||||||
|
{
|
||||||
|
qse_tre_t* tre;
|
||||||
|
|
||||||
|
tre = qse_tre_open (sed->mmgr, 0);
|
||||||
|
if (tre == QSE_NULL)
|
||||||
|
{
|
||||||
|
SETERR0 (sed, QSE_SED_ENOMEM, loc);
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qse_tre_compx (tre, str->ptr, str->len, QSE_NULL,
|
||||||
|
((sed->option & QSE_SED_EXTENDEDREX)? QSE_TRE_EXTENDED: 0)) <= -1)
|
||||||
|
{
|
||||||
|
SETERR1 (sed, QSE_SED_EREXBL, str->ptr, str->len, loc);
|
||||||
|
qse_tre_close (tre);
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tre;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QSE_INLINE void freetre (qse_sed_t* sed, qse_tre_t* tre)
|
||||||
|
{
|
||||||
|
qse_tre_close (tre);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int matchtre (
|
||||||
|
qse_sed_t* sed, qse_tre_t* tre, int opt,
|
||||||
|
const qse_cstr_t* str, qse_cstr_t* mat,
|
||||||
|
qse_cstr_t submat[9], const qse_sed_loc_t* loc)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
qse_tre_match_t match[10];
|
||||||
|
|
||||||
|
n = qse_tre_execx (tre, str->ptr, str->len, match, 10, opt);
|
||||||
|
if (n <= -1)
|
||||||
|
{
|
||||||
|
if (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMATCH) return 0;
|
||||||
|
SETERR0 (sed, QSE_SED_EREXMA, loc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSE_ASSERT (match[0].rm_so != -1);
|
||||||
|
if (mat)
|
||||||
|
{
|
||||||
|
mat->ptr = &str->ptr[match[0].rm_so];
|
||||||
|
mat->len = match[0].rm_eo - match[0].rm_so;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (submat)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* you must intialize submat before you pass into this
|
||||||
|
* function because it can abort filling */
|
||||||
|
for (i = 1; i <= 10; i++)
|
||||||
|
{
|
||||||
|
if (match[i].rm_so == -1) break;
|
||||||
|
submat[i-1].ptr = &str->ptr[match[i].rm_so];
|
||||||
|
submat[i-1].len = match[i].rm_eo - match[i].rm_so;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* check if c is a space character */
|
/* check if c is a space character */
|
||||||
#define IS_SPACE(c) ((c) == QSE_T(' ') || (c) == QSE_T('\t') || (c) == QSE_T('\r'))
|
#define IS_SPACE(c) ((c) == QSE_T(' ') || (c) == QSE_T('\t') || (c) == QSE_T('\r'))
|
||||||
@ -200,13 +273,15 @@ static void free_address (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
if (cmd->a2.type == QSE_SED_ADR_REX)
|
if (cmd->a2.type == QSE_SED_ADR_REX)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (cmd->a2.u.rex != QSE_NULL);
|
QSE_ASSERT (cmd->a2.u.rex != QSE_NULL);
|
||||||
qse_freerex (sed->mmgr, cmd->a2.u.rex);
|
/*qse_freerex (sed->mmgr, cmd->a2.u.rex);*/
|
||||||
|
freetre (sed, cmd->a2.u.rex);
|
||||||
cmd->a2.type = QSE_SED_ADR_NONE;
|
cmd->a2.type = QSE_SED_ADR_NONE;
|
||||||
}
|
}
|
||||||
if (cmd->a1.type == QSE_SED_ADR_REX)
|
if (cmd->a1.type == QSE_SED_ADR_REX)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (cmd->a1.u.rex != QSE_NULL);
|
QSE_ASSERT (cmd->a1.u.rex != QSE_NULL);
|
||||||
qse_freerex (sed->mmgr, cmd->a1.u.rex);
|
/*qse_freerex (sed->mmgr, cmd->a1.u.rex);*/
|
||||||
|
freetre (sed, cmd->a1.u.rex);
|
||||||
cmd->a1.type = QSE_SED_ADR_NONE;
|
cmd->a1.type = QSE_SED_ADR_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,7 +360,8 @@ static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
if (cmd->u.subst.rpl.ptr)
|
if (cmd->u.subst.rpl.ptr)
|
||||||
QSE_MMGR_FREE (sed->mmgr, cmd->u.subst.rpl.ptr);
|
QSE_MMGR_FREE (sed->mmgr, cmd->u.subst.rpl.ptr);
|
||||||
if (cmd->u.subst.rex)
|
if (cmd->u.subst.rex)
|
||||||
qse_freerex (sed->mmgr, cmd->u.subst.rex);
|
/*qse_freerex (sed->mmgr, cmd->u.subst.rex);*/
|
||||||
|
freetre (sed, cmd->u.subst.rex);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QSE_SED_CMD_TRANSLATE:
|
case QSE_SED_CMD_TRANSLATE:
|
||||||
@ -300,7 +376,9 @@ static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
|
|
||||||
static void* compile_rex (qse_sed_t* sed, qse_char_t rxend)
|
static void* compile_rex (qse_sed_t* sed, qse_char_t rxend)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_REX
|
||||||
void* code;
|
void* code;
|
||||||
|
#endif
|
||||||
qse_cint_t c;
|
qse_cint_t c;
|
||||||
|
|
||||||
qse_str_clear (&sed->tmp.rex);
|
qse_str_clear (&sed->tmp.rex);
|
||||||
@ -346,43 +424,11 @@ static void* compile_rex (qse_sed_t* sed, qse_char_t rxend)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_REX
|
||||||
#if 0
|
|
||||||
{
|
|
||||||
qse_tre_t* tre;
|
|
||||||
|
|
||||||
tre = qse_tre_open (sed->mmgr, 0);
|
|
||||||
if (tre)
|
|
||||||
{
|
|
||||||
if (qse_tre_comp (tre,
|
|
||||||
QSE_STR_PTR(&sed->tmp.rex),
|
|
||||||
QSE_STR_LEN(&sed->tmp.rex),
|
|
||||||
QSE_NULL,
|
|
||||||
QSE_TRE_EXTENDED) <= -1)
|
|
||||||
{
|
|
||||||
qse_tre_close (tre);
|
|
||||||
goto fail:
|
|
||||||
}
|
|
||||||
return tre;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SETERR1 (
|
|
||||||
sed, QSE_SED_EREXBL,
|
|
||||||
QSE_STR_PTR(&sed->tmp.rex),
|
|
||||||
QSE_STR_LEN(&sed->tmp.rex),
|
|
||||||
&sed->src.loc
|
|
||||||
);
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
code = qse_buildrex (
|
code = qse_buildrex (
|
||||||
sed->mmgr,
|
sed->mmgr,
|
||||||
sed->depth.rex.build,
|
sed->depth.rex.build,
|
||||||
((sed->option&QSE_SED_REXBOUND)? 0:QSE_REX_NOBOUND),
|
((sed->option&QSE_SED_EXTENDEDREX)? 0:QSE_REX_NOBOUND),
|
||||||
QSE_STR_PTR(&sed->tmp.rex),
|
QSE_STR_PTR(&sed->tmp.rex),
|
||||||
QSE_STR_LEN(&sed->tmp.rex),
|
QSE_STR_LEN(&sed->tmp.rex),
|
||||||
QSE_NULL
|
QSE_NULL
|
||||||
@ -399,6 +445,10 @@ static void* compile_rex (qse_sed_t* sed, qse_char_t rxend)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
|
||||||
|
#else
|
||||||
|
return maketre (sed, QSE_STR_CSTR(&sed->tmp.rex), &sed->src.loc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_sed_adr_t* get_address (qse_sed_t* sed, qse_sed_adr_t* a)
|
static qse_sed_adr_t* get_address (qse_sed_t* sed, qse_sed_adr_t* a)
|
||||||
@ -809,12 +859,14 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
{
|
{
|
||||||
CHECK_CMDIC (sed, cmd, c, goto oops);
|
CHECK_CMDIC (sed, cmd, c, goto oops);
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (c == QSE_T('\\'))
|
if (c == QSE_T('\\'))
|
||||||
{
|
{
|
||||||
c = NXTSC (sed);
|
c = NXTSC (sed);
|
||||||
CHECK_CMDIC (sed, cmd, c, goto oops);
|
CHECK_CMDIC (sed, cmd, c, goto oops);
|
||||||
if (c == QSE_T('n')) c = QSE_T('\n');
|
if (c == QSE_T('n')) c = QSE_T('\n');
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (qse_str_ccat (t[i], c) == (qse_size_t)-1)
|
if (qse_str_ccat (t[i], c) == (qse_size_t)-1)
|
||||||
{
|
{
|
||||||
@ -895,10 +947,12 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
terminate_command (sed) <= -1) goto oops;
|
terminate_command (sed) <= -1) goto oops;
|
||||||
|
|
||||||
QSE_ASSERT (cmd->u.subst.rex == QSE_NULL);
|
QSE_ASSERT (cmd->u.subst.rex == QSE_NULL);
|
||||||
|
|
||||||
|
#ifdef USE_REX
|
||||||
cmd->u.subst.rex = qse_buildrex (
|
cmd->u.subst.rex = qse_buildrex (
|
||||||
sed->mmgr,
|
sed->mmgr,
|
||||||
sed->depth.rex.build,
|
sed->depth.rex.build,
|
||||||
((sed->option&QSE_SED_REXBOUND)? 0:QSE_REX_NOBOUND),
|
((sed->option&QSE_SED_EXTENDEDREX)? 0:QSE_REX_NOBOUND),
|
||||||
QSE_STR_PTR(t[0]),
|
QSE_STR_PTR(t[0]),
|
||||||
QSE_STR_LEN(t[0]),
|
QSE_STR_LEN(t[0]),
|
||||||
QSE_NULL
|
QSE_NULL
|
||||||
@ -913,6 +967,10 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
);
|
);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
cmd->u.subst.rex = maketre (sed, QSE_STR_CSTR(t[0]), &sed->src.loc);
|
||||||
|
if (cmd->u.subst.rex == QSE_NULL) goto oops;
|
||||||
|
#endif
|
||||||
|
|
||||||
qse_str_yield (t[1], &cmd->u.subst.rpl, 0);
|
qse_str_yield (t[1], &cmd->u.subst.rpl, 0);
|
||||||
if (cmd->u.subst.g == 0 && cmd->u.subst.occ == 0) cmd->u.subst.occ = 1;
|
if (cmd->u.subst.g == 0 && cmd->u.subst.occ == 0) cmd->u.subst.occ = 1;
|
||||||
@ -1833,7 +1891,9 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
{
|
{
|
||||||
qse_cstr_t mat, pmat;
|
qse_cstr_t mat, pmat;
|
||||||
int opt = 0, repl = 0, n;
|
int opt = 0, repl = 0, n;
|
||||||
|
#ifdef USE_REX
|
||||||
qse_rex_errnum_t errnum;
|
qse_rex_errnum_t errnum;
|
||||||
|
#endif
|
||||||
|
|
||||||
qse_cstr_t str, cur;
|
qse_cstr_t str, cur;
|
||||||
const qse_char_t* str_end;
|
const qse_char_t* str_end;
|
||||||
@ -1842,7 +1902,11 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
QSE_ASSERT (cmd->type == QSE_SED_CMD_SUBSTITUTE);
|
QSE_ASSERT (cmd->type == QSE_SED_CMD_SUBSTITUTE);
|
||||||
|
|
||||||
qse_str_clear (&sed->e.txt.subst);
|
qse_str_clear (&sed->e.txt.subst);
|
||||||
|
#ifdef USE_REX
|
||||||
if (cmd->u.subst.i) opt = QSE_REX_IGNORECASE;
|
if (cmd->u.subst.i) opt = QSE_REX_IGNORECASE;
|
||||||
|
#else
|
||||||
|
if (cmd->u.subst.i) opt = QSE_TRE_IGNORECASE;
|
||||||
|
#endif
|
||||||
|
|
||||||
str.ptr = QSE_STR_PTR(&sed->e.in.line);
|
str.ptr = QSE_STR_PTR(&sed->e.in.line);
|
||||||
str.len = QSE_STR_LEN(&sed->e.in.line);
|
str.len = QSE_STR_LEN(&sed->e.in.line);
|
||||||
@ -1863,6 +1927,7 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
* end of string($) needs to be tested */
|
* end of string($) needs to be tested */
|
||||||
while (cur.ptr <= str_end)
|
while (cur.ptr <= str_end)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_REX
|
||||||
if (max_count == 0 || sub_count < max_count)
|
if (max_count == 0 || sub_count < max_count)
|
||||||
{
|
{
|
||||||
n = qse_matchrex (
|
n = qse_matchrex (
|
||||||
@ -1871,14 +1936,29 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
cmd->u.subst.rex, opt,
|
cmd->u.subst.rex, opt,
|
||||||
&str, &cur, &mat, &errnum
|
&str, &cur, &mat, &errnum
|
||||||
);
|
);
|
||||||
|
if (n <= -1)
|
||||||
|
{
|
||||||
|
SETERR0 (sed, QSE_SED_EREXMA, &cmd->loc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else n = 0;
|
else n = 0;
|
||||||
|
#else
|
||||||
|
qse_cstr_t submat[9];
|
||||||
|
|
||||||
if (n <= -1)
|
QSE_MEMSET (submat, 0, QSE_SIZEOF(submat));
|
||||||
|
if (max_count == 0 || sub_count < max_count)
|
||||||
{
|
{
|
||||||
SETERR0 (sed, QSE_SED_EREXMA, &cmd->loc);
|
n = matchtre (
|
||||||
return -1;
|
sed,
|
||||||
|
cmd->u.subst.rex,
|
||||||
|
((str.ptr == cur.ptr)? opt: (opt | QSE_TRE_NOTBOL)),
|
||||||
|
&cur, &mat, submat, &cmd->loc
|
||||||
|
);
|
||||||
|
if (n <= -1) return -1;
|
||||||
}
|
}
|
||||||
|
else n = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
@ -1930,11 +2010,49 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
for (i = 0; i < cmd->u.subst.rpl.len; i++)
|
for (i = 0; i < cmd->u.subst.rpl.len; i++)
|
||||||
{
|
{
|
||||||
if ((i+1) < cmd->u.subst.rpl.len &&
|
if ((i+1) < cmd->u.subst.rpl.len &&
|
||||||
cmd->u.subst.rpl.ptr[i] == QSE_T('\\') &&
|
cmd->u.subst.rpl.ptr[i] == QSE_T('\\'))
|
||||||
cmd->u.subst.rpl.ptr[i+1] == QSE_T('&'))
|
|
||||||
{
|
{
|
||||||
m = qse_str_ccat (
|
qse_char_t nc = cmd->u.subst.rpl.ptr[i+1];
|
||||||
&sed->e.txt.subst, QSE_T('&'));
|
|
||||||
|
#ifndef USE_REX
|
||||||
|
if (nc >= QSE_T('1') && nc <= QSE_T('9'))
|
||||||
|
{
|
||||||
|
int smi = nc - QSE_T('1');
|
||||||
|
m = qse_str_ncat (&sed->e.txt.subst, submat[smi].ptr, submat[smi].len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
switch (nc)
|
||||||
|
{
|
||||||
|
case QSE_T('n'):
|
||||||
|
nc = QSE_T('\n');
|
||||||
|
break;
|
||||||
|
case QSE_T('r'):
|
||||||
|
nc = QSE_T('\r');
|
||||||
|
break;
|
||||||
|
case QSE_T('t'):
|
||||||
|
nc = QSE_T('\t');
|
||||||
|
break;
|
||||||
|
case QSE_T('f'):
|
||||||
|
nc = QSE_T('\f');
|
||||||
|
break;
|
||||||
|
case QSE_T('b'):
|
||||||
|
nc = QSE_T('\b');
|
||||||
|
break;
|
||||||
|
case QSE_T('v'):
|
||||||
|
nc = QSE_T('\v');
|
||||||
|
break;
|
||||||
|
case QSE_T('a'):
|
||||||
|
nc = QSE_T('\a');
|
||||||
|
break;
|
||||||
|
#ifndef USE_REX
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m = qse_str_ccat (&sed->e.txt.subst, nc);
|
||||||
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else if (cmd->u.subst.rpl.ptr[i] == QSE_T('&'))
|
else if (cmd->u.subst.rpl.ptr[i] == QSE_T('&'))
|
||||||
@ -2032,10 +2150,12 @@ static int match_a (qse_sed_t* sed, qse_sed_cmd_t* cmd, qse_sed_adr_t* a)
|
|||||||
|
|
||||||
case QSE_SED_ADR_REX:
|
case QSE_SED_ADR_REX:
|
||||||
{
|
{
|
||||||
|
#ifdef USE_REX
|
||||||
int n;
|
int n;
|
||||||
qse_cstr_t match;
|
|
||||||
qse_cstr_t line;
|
|
||||||
qse_rex_errnum_t errnum;
|
qse_rex_errnum_t errnum;
|
||||||
|
qse_cstr_t match;
|
||||||
|
#endif
|
||||||
|
qse_cstr_t line;
|
||||||
|
|
||||||
QSE_ASSERT (a->u.rex != QSE_NULL);
|
QSE_ASSERT (a->u.rex != QSE_NULL);
|
||||||
|
|
||||||
@ -2045,6 +2165,7 @@ static int match_a (qse_sed_t* sed, qse_sed_cmd_t* cmd, qse_sed_adr_t* a)
|
|||||||
if (line.len > 0 &&
|
if (line.len > 0 &&
|
||||||
line.ptr[line.len-1] == QSE_T('\n')) line.len--;
|
line.ptr[line.len-1] == QSE_T('\n')) line.len--;
|
||||||
|
|
||||||
|
#ifdef USE_REX
|
||||||
n = qse_matchrex (
|
n = qse_matchrex (
|
||||||
sed->mmgr,
|
sed->mmgr,
|
||||||
sed->depth.rex.match,
|
sed->depth.rex.match,
|
||||||
@ -2058,6 +2179,10 @@ static int match_a (qse_sed_t* sed, qse_sed_cmd_t* cmd, qse_sed_adr_t* a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
#else
|
||||||
|
return matchtre (sed, a->u.rex, 0, &line, QSE_NULL, QSE_NULL, &cmd->loc);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
case QSE_SED_ADR_DOL:
|
case QSE_SED_ADR_DOL:
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sed.h 441 2011-04-22 14:28:43Z hyunghwan.chung $
|
* $Id: sed.h 558 2011-09-02 15:27:44Z 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.
|
||||||
@ -28,6 +28,23 @@
|
|||||||
#define QSE_MAP_AS_RBT
|
#define QSE_MAP_AS_RBT
|
||||||
#include <qse/cmn/map.h>
|
#include <qse/cmn/map.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define USE_REX to use rex.h on behalf of tre.h
|
||||||
|
* rex.h currently does not support backreference.
|
||||||
|
*/
|
||||||
|
#ifdef USE_REX
|
||||||
|
enum qse_sed_depth_t
|
||||||
|
{
|
||||||
|
QSE_SED_DEPTH_REX_BUILD = (1 << 0),
|
||||||
|
QSE_SED_DEPTH_REX_MATCH = (1 << 1)
|
||||||
|
};
|
||||||
|
typedef enum qse_sed_depth_t qse_sed_depth_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define QSE_SED_CMD_NOOP QSE_T('\0')
|
||||||
|
#define QSE_SED_CMD_QUIT QSE_T('q')
|
||||||
|
|
||||||
typedef struct qse_sed_adr_t qse_sed_adr_t;
|
typedef struct qse_sed_adr_t qse_sed_adr_t;
|
||||||
typedef struct qse_sed_cmd_t qse_sed_cmd_t;
|
typedef struct qse_sed_cmd_t qse_sed_cmd_t;
|
||||||
typedef struct qse_sed_cmd_blk_t qse_sed_cmd_blk_t;
|
typedef struct qse_sed_cmd_blk_t qse_sed_cmd_blk_t;
|
||||||
@ -50,8 +67,6 @@ struct qse_sed_adr_t
|
|||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define QSE_SED_CMD_NOOP QSE_T('\0')
|
|
||||||
#define QSE_SED_CMD_QUIT QSE_T('q')
|
|
||||||
#define QSE_SED_CMD_QUIT_QUIET QSE_T('Q')
|
#define QSE_SED_CMD_QUIT_QUIET QSE_T('Q')
|
||||||
#define QSE_SED_CMD_APPEND QSE_T('a')
|
#define QSE_SED_CMD_APPEND QSE_T('a')
|
||||||
#define QSE_SED_CMD_INSERT QSE_T('i')
|
#define QSE_SED_CMD_INSERT QSE_T('i')
|
||||||
@ -262,7 +277,39 @@ struct qse_sed_t
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const qse_char_t* qse_sed_dflerrstr (qse_sed_t* sed, qse_sed_errnum_t errnum);
|
int qse_sed_init (
|
||||||
|
qse_sed_t* sed,
|
||||||
|
qse_mmgr_t* mmgr
|
||||||
|
);
|
||||||
|
|
||||||
|
void qse_sed_fini (
|
||||||
|
qse_sed_t* sed
|
||||||
|
);
|
||||||
|
|
||||||
|
const qse_char_t* qse_sed_dflerrstr (
|
||||||
|
qse_sed_t* sed,
|
||||||
|
qse_sed_errnum_t errnum
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_REX
|
||||||
|
/**
|
||||||
|
* The qse_sed_getmaxdepth() gets the maximum processing depth.
|
||||||
|
*/
|
||||||
|
qse_size_t qse_sed_getmaxdepth (
|
||||||
|
qse_sed_t* sed, /**< stream editor */
|
||||||
|
qse_sed_depth_t id /**< one of qse_sed_depth_t values */
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_sed_setmaxdepth() sets the maximum processing depth.
|
||||||
|
*/
|
||||||
|
void qse_sed_setmaxdepth (
|
||||||
|
qse_sed_t* sed, /**< stream editor */
|
||||||
|
int ids, /**< 0 or a number OR'ed of #qse_sed_depth_t values */
|
||||||
|
qse_size_t depth /**< maximum depth level */
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user