interim commit
This commit is contained in:
parent
e384e1d044
commit
5e21877849
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: rex.h 287 2009-09-15 10:01:02Z hyunghwan.chung $
|
||||
* $Id: rex.h 300 2009-11-13 14:01:57Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -91,6 +91,7 @@ typedef enum qse_rex_errnum_t qse_rex_errnum_t;
|
||||
|
||||
typedef struct qse_rex_t qse_rex_t;
|
||||
|
||||
#if 0
|
||||
struct qse_rex_t
|
||||
{
|
||||
QSE_DEFINE_COMMON_FIELDS (rex)
|
||||
@ -105,6 +106,63 @@ struct qse_rex_t
|
||||
|
||||
void* code;
|
||||
};
|
||||
#endif
|
||||
|
||||
enum qse_rex_node_id_t
|
||||
{
|
||||
QSE_REX_NODE_START,
|
||||
QSE_REX_NODE_END,
|
||||
QSE_REX_NODE_NOP,
|
||||
QSE_REX_NODE_ANYCHAR, /* dot */
|
||||
QSE_REX_NODE_CHAR, /* single character */
|
||||
QSE_REX_NODE_CHARSET, /* character set */
|
||||
QSE_REX_NODE_BRANCH,
|
||||
QSE_REX_NODE_GROUP,
|
||||
QSE_REX_NODE_GROUPEND
|
||||
};
|
||||
typedef enum qse_rex_node_id_t qse_rex_node_id_t;
|
||||
|
||||
typedef struct qse_rex_node_t qse_rex_node_t;
|
||||
struct qse_rex_node_t
|
||||
{
|
||||
qse_rex_node_t* link; /* link for management. not used for startnode */
|
||||
qse_rex_node_t* next;
|
||||
|
||||
qse_rex_node_id_t id;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
qse_mmgr_t* mmgr;
|
||||
qse_rex_node_t* link;
|
||||
} s;
|
||||
|
||||
qse_char_t c;
|
||||
qse_char_t* cs; /* charset */
|
||||
|
||||
struct
|
||||
{
|
||||
qse_rex_node_t* left;
|
||||
qse_rex_node_t* right;
|
||||
} b;
|
||||
|
||||
struct
|
||||
{
|
||||
qse_rex_node_t* head;
|
||||
} g;
|
||||
|
||||
struct
|
||||
{
|
||||
qse_rex_node_t* group;
|
||||
} ge;
|
||||
} u;
|
||||
|
||||
struct
|
||||
{
|
||||
qse_size_t min;
|
||||
qse_size_t max;
|
||||
} occ;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -114,26 +172,26 @@ QSE_DEFINE_COMMON_FUNCTIONS (rex)
|
||||
|
||||
qse_rex_t* qse_rex_open (
|
||||
qse_mmgr_t* mmgr,
|
||||
qse_size_t xtn
|
||||
qse_size_t xtn,
|
||||
void* code
|
||||
);
|
||||
|
||||
void qse_rex_close (
|
||||
qse_rex_t* rex
|
||||
);
|
||||
|
||||
int qse_rex_build (
|
||||
qse_rex_node_t* qse_rex_comp (
|
||||
qse_rex_t* rex,
|
||||
const qse_char_t* ptn,
|
||||
qse_size_t len
|
||||
);
|
||||
|
||||
int qse_rex_match (
|
||||
int qse_rex_exec (
|
||||
qse_rex_t* rex,
|
||||
const qse_char_t* str,
|
||||
qse_size_t len,
|
||||
const qse_char_t* substr,
|
||||
qse_size_t sublen,
|
||||
qse_cstr_t* match
|
||||
qse_size_t sublen
|
||||
);
|
||||
|
||||
void* qse_buildrex (
|
||||
|
@ -5,7 +5,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
lib_LTLIBRARIES = libqsecmn.la
|
||||
libqsecmn_la_SOURCES = \
|
||||
syscall.h mem.h \
|
||||
mem.c chr.c chr_cnv.c rex.c \
|
||||
mem.c chr.c chr_cnv.c rex.c rex1.c \
|
||||
str_bas.c str_cnv.c str_dyn.c str_utl.c \
|
||||
lda.c map.c sll.c dll.c opt.c \
|
||||
tio.c tio_get.c tio_put.c \
|
||||
|
@ -55,10 +55,10 @@ am__installdirs = "$(DESTDIR)$(libdir)"
|
||||
libLTLIBRARIES_INSTALL = $(INSTALL)
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
libqsecmn_la_DEPENDENCIES =
|
||||
am_libqsecmn_la_OBJECTS = mem.lo chr.lo chr_cnv.lo rex.lo str_bas.lo \
|
||||
str_cnv.lo str_dyn.lo str_utl.lo lda.lo map.lo sll.lo dll.lo \
|
||||
opt.lo tio.lo tio_get.lo tio_put.lo fio.lo pio.lo sio.lo \
|
||||
time.lo misc.lo assert.lo main.lo stdio.lo
|
||||
am_libqsecmn_la_OBJECTS = mem.lo chr.lo chr_cnv.lo rex.lo rex1.lo \
|
||||
str_bas.lo str_cnv.lo str_dyn.lo str_utl.lo lda.lo map.lo \
|
||||
sll.lo dll.lo opt.lo tio.lo tio_get.lo tio_put.lo fio.lo \
|
||||
pio.lo sio.lo time.lo misc.lo assert.lo main.lo stdio.lo
|
||||
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
|
||||
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
@ -221,7 +221,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
lib_LTLIBRARIES = libqsecmn.la
|
||||
libqsecmn_la_SOURCES = \
|
||||
syscall.h mem.h \
|
||||
mem.c chr.c chr_cnv.c rex.c \
|
||||
mem.c chr.c chr_cnv.c rex.c rex1.c \
|
||||
str_bas.c str_cnv.c str_dyn.c str_utl.c \
|
||||
lda.c map.c sll.c dll.c opt.c \
|
||||
tio.c tio_get.c tio_put.c \
|
||||
@ -316,6 +316,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rex.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rex1.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sio.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sll.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdio.Plo@am__quote@
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: rex.c 299 2009-10-19 13:33:40Z hyunghwan.chung $
|
||||
* $Id: rex.c 300 2009-11-13 14:01:57Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -341,6 +341,7 @@ static struct __char_class_t __char_class[] =
|
||||
{ QSE_NULL, 0, QSE_NULL }
|
||||
};
|
||||
|
||||
#if 0
|
||||
qse_rex_t* qse_rex_open (qse_mmgr_t* mmgr, qse_size_t xtn)
|
||||
{
|
||||
qse_rex_t* rex;
|
||||
@ -394,6 +395,7 @@ int qse_rex_match (
|
||||
rex->mmgr, rex->depth.match, rex->code, rex->option,
|
||||
str, len, substr, sublen, match, &rex->errnum);
|
||||
}
|
||||
#endif
|
||||
|
||||
void* qse_buildrex (
|
||||
qse_mmgr_t* mmgr, qse_size_t depth, int option,
|
||||
|
755
qse/lib/cmn/rex1.c
Normal file
755
qse/lib/cmn/rex1.c
Normal file
@ -0,0 +1,755 @@
|
||||
/*
|
||||
* $Id$
|
||||
|
||||
{LICENSE HERE}
|
||||
|
||||
*/
|
||||
|
||||
#include <qse/cmn/rex.h>
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/cmn/lda.h>
|
||||
#include "mem.h"
|
||||
|
||||
#define GETC(c) do { if getc(c) <= -1) return -1; } while (0)
|
||||
#define OCC_MAX QSE_TYPE_MAX(qse_size_t)
|
||||
|
||||
struct qse_rex_t
|
||||
{
|
||||
QSE_DEFINE_COMMON_FIELDS (rex)
|
||||
|
||||
int errnum;
|
||||
qse_rex_node_t* code;
|
||||
};
|
||||
|
||||
typedef struct comp_t comp_t;
|
||||
struct comp_t
|
||||
{
|
||||
qse_rex_t* rex;
|
||||
|
||||
qse_cstr_t re;
|
||||
const qse_char_t* ptr;
|
||||
const qse_char_t* end;
|
||||
qse_cint_t c;
|
||||
qse_size_t grouplvl;
|
||||
|
||||
qse_rex_node_t* start;
|
||||
};
|
||||
|
||||
typedef struct exec_t exec_t;
|
||||
struct exec_t
|
||||
{
|
||||
qse_rex_t* rex;
|
||||
|
||||
qse_cstr_t str;
|
||||
qse_cstr_t sub;
|
||||
|
||||
qse_lda_t cand[2]; /* candidate arrays */
|
||||
int xxx, yyy;
|
||||
qse_size_t matched;
|
||||
};
|
||||
|
||||
typedef struct pair_t pair_t;
|
||||
struct pair_t
|
||||
{
|
||||
qse_rex_node_t* head;
|
||||
qse_rex_node_t* tail;
|
||||
};
|
||||
|
||||
typedef struct group_t group_t;
|
||||
struct group_t
|
||||
{
|
||||
qse_rex_node_t* node;
|
||||
qse_size_t occ;
|
||||
group_t* next;
|
||||
};
|
||||
|
||||
typedef struct cand_t cand_t;
|
||||
struct cand_t
|
||||
{
|
||||
qse_rex_node_t* node;
|
||||
qse_size_t occ;
|
||||
group_t* group;
|
||||
};
|
||||
|
||||
qse_rex_t* qse_rex_open (qse_mmgr_t* mmgr, qse_size_t xtn, void* code)
|
||||
{
|
||||
qse_rex_t* rex;
|
||||
|
||||
if (mmgr == QSE_NULL)
|
||||
{
|
||||
mmgr = QSE_MMGR_GETDFL();
|
||||
|
||||
QSE_ASSERTX (mmgr != QSE_NULL,
|
||||
"Set the memory manager with QSE_MMGR_SETDFL()");
|
||||
|
||||
if (mmgr == QSE_NULL) return QSE_NULL;
|
||||
}
|
||||
|
||||
rex = (qse_rex_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_rex_t) + xtn);
|
||||
if (rex == QSE_NULL) return QSE_NULL;
|
||||
|
||||
QSE_MEMSET (rex, 0, QSE_SIZEOF(*rex));
|
||||
rex->mmgr = mmgr;
|
||||
/* TODO: must duplicate? */
|
||||
rex->code = code;
|
||||
|
||||
return rex;
|
||||
}
|
||||
|
||||
static void freenode (qse_rex_node_t* node, qse_mmgr_t* mmgr)
|
||||
{
|
||||
if (node->id == QSE_REX_NODE_CHARSET)
|
||||
{
|
||||
// TODO:
|
||||
QSE_MMGR_FREE (mmgr, node->u.cs);
|
||||
}
|
||||
|
||||
QSE_MMGR_FREE (mmgr, node);
|
||||
}
|
||||
|
||||
static void freeallnodes (qse_rex_node_t* start)
|
||||
{
|
||||
qse_rex_node_t* x, * y;
|
||||
qse_mmgr_t* mmgr;
|
||||
|
||||
QSE_ASSERT (start->id == QSE_REX_NODE_START);
|
||||
|
||||
mmgr = start->u.s.mmgr;
|
||||
x = start->u.s.link;
|
||||
while (x != QSE_NULL)
|
||||
{
|
||||
y = x->link;
|
||||
freenode (x, mmgr);
|
||||
x = y;
|
||||
}
|
||||
|
||||
QSE_MMGR_FREE (mmgr, start);
|
||||
}
|
||||
|
||||
void qse_rex_close (qse_rex_t* rex)
|
||||
{
|
||||
if (rex->code != QSE_NULL) freeallnodes (rex->code);
|
||||
QSE_MMGR_FREE (rex->mmgr, rex);
|
||||
}
|
||||
|
||||
static qse_rex_node_t* newnode (comp_t* c, qse_rex_node_id_t id)
|
||||
{
|
||||
qse_rex_node_t* node;
|
||||
|
||||
node = (qse_rex_node_t*)
|
||||
QSE_MMGR_ALLOC (c->rex->mmgr, QSE_SIZEOF(qse_rex_node_t));
|
||||
if (node == QSE_NULL)
|
||||
{
|
||||
// TODO set error code
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
QSE_MEMSET (node, 0, QSE_SIZEOF(*node));
|
||||
node->id = id;
|
||||
|
||||
if (c->start != QSE_NULL)
|
||||
{
|
||||
QSE_ASSERT (c->start->id == QSE_REX_NODE_START);
|
||||
node->link = c->start->u.s.link;
|
||||
c->start->u.s.link = node;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static qse_rex_node_t* newstartnode (comp_t* c)
|
||||
{
|
||||
qse_rex_node_t* n = newnode (c, QSE_REX_NODE_START);
|
||||
if (n != QSE_NULL)
|
||||
{
|
||||
n->u.s.mmgr = c->rex->mmgr;
|
||||
n->u.s.link = QSE_NULL;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static qse_rex_node_t* newendnode (comp_t* c)
|
||||
{
|
||||
return newnode (c, QSE_REX_NODE_END);
|
||||
}
|
||||
|
||||
static qse_rex_node_t* newnopnode (comp_t* c)
|
||||
{
|
||||
return newnode (c, QSE_REX_NODE_NOP);
|
||||
}
|
||||
|
||||
static qse_rex_node_t* newgroupnode (comp_t* c, qse_rex_node_t* head)
|
||||
{
|
||||
qse_rex_node_t* n = newnode (c, QSE_REX_NODE_GROUP);
|
||||
if (n != QSE_NULL) n->u.g.head = head;
|
||||
return n;
|
||||
}
|
||||
|
||||
static qse_rex_node_t* newgroupendnode (comp_t* c, qse_rex_node_t* group)
|
||||
{
|
||||
qse_rex_node_t* n = newnode (c, QSE_REX_NODE_GROUPEND);
|
||||
if (n != QSE_NULL) n->u.ge.group = group;
|
||||
return n;
|
||||
}
|
||||
|
||||
static qse_rex_node_t* newcharnode (comp_t* c, qse_char_t ch)
|
||||
{
|
||||
qse_rex_node_t* n = newnode (c, QSE_REX_NODE_CHAR);
|
||||
if (n != QSE_NULL) n->u.c = ch;
|
||||
return n;
|
||||
}
|
||||
|
||||
static qse_rex_node_t* newbranchnode (
|
||||
comp_t* c, qse_rex_node_t* left, qse_rex_node_t* right)
|
||||
{
|
||||
qse_rex_node_t* n = newnode (c, QSE_REX_NODE_BRANCH);
|
||||
if (n != QSE_NULL)
|
||||
{
|
||||
n->u.b.left = left;
|
||||
n->u.b.right = right;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static int getc (comp_t* c)
|
||||
{
|
||||
c->c = (c->ptr < c->end)? *c->ptr++: QSE_CHAR_EOF;
|
||||
if (c->c == QSE_CHAR_EOF)
|
||||
qse_printf (QSE_T("getc => <EOF>\n"));
|
||||
else qse_printf (QSE_T("getc => %c\n"), c->c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static qse_rex_node_t* comp0 (comp_t* c, qse_rex_node_t* ge);
|
||||
|
||||
static qse_rex_node_t* comp2 (comp_t* c)
|
||||
{
|
||||
qse_rex_node_t* n;
|
||||
|
||||
switch (c->c)
|
||||
{
|
||||
case QSE_T('('):
|
||||
{
|
||||
qse_rex_node_t* x, * ge;
|
||||
|
||||
n = newgroupnode (c, QSE_NULL);
|
||||
if (n == QSE_NULL) return QSE_NULL;
|
||||
|
||||
ge = newgroupendnode (c, n);
|
||||
if (ge == QSE_NULL)
|
||||
{
|
||||
// free n
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
if (getc(c) <= -1)
|
||||
{
|
||||
// freere (ge);
|
||||
// freere (n);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
c->grouplvl++;
|
||||
x = comp0 (c, ge);
|
||||
if (x == QSE_NULL)
|
||||
{
|
||||
// freere (ge);
|
||||
// freere (n);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
if (c->c != QSE_T(')'))
|
||||
{
|
||||
qse_printf (QSE_T("expecting )\n"));
|
||||
// UNBALANCED PAREN.
|
||||
// freere (x);
|
||||
// freere (n);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
c->grouplvl--;
|
||||
if (getc(c) <= -1)
|
||||
{
|
||||
// freere (x);
|
||||
// freere (n);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
n->u.g.head = x;
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_T('.'):
|
||||
n = newnode (c, QSE_REX_NODE_ANYCHAR);
|
||||
if (n == QSE_NULL) return QSE_NULL;
|
||||
if (getc(c) <= -1)
|
||||
{
|
||||
// TODO: error handling..
|
||||
return QSE_NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
case QSE_T('['):
|
||||
....
|
||||
*/
|
||||
|
||||
default:
|
||||
/* normal character */
|
||||
n = newcharnode (c, c->c);
|
||||
if (n == QSE_NULL) return QSE_NULL;
|
||||
if (getc(c) <= -1)
|
||||
{
|
||||
// TODO: error handling..
|
||||
return QSE_NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* handle the occurrence specifier, if any */
|
||||
switch (c->c)
|
||||
{
|
||||
case QSE_T('?'):
|
||||
n->occ.min = 0;
|
||||
n->occ.max = 1;
|
||||
if (getc(c) <= -1)
|
||||
{
|
||||
// TODO: error handling..
|
||||
//free n
|
||||
return QSE_NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case QSE_T('*'):
|
||||
n->occ.min = 0;
|
||||
n->occ.max = OCC_MAX;
|
||||
if (getc(c) <= -1)
|
||||
{
|
||||
// TODO: error handling..
|
||||
//free n
|
||||
return QSE_NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case QSE_T('+'):
|
||||
n->occ.min = 1;
|
||||
n->occ.max = OCC_MAX;
|
||||
if (getc(c) <= -1)
|
||||
{
|
||||
// TODO: error handling..
|
||||
//free n
|
||||
return QSE_NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
case QSE_T('{'):
|
||||
// TODO --------------
|
||||
break;
|
||||
*/
|
||||
|
||||
default:
|
||||
n->occ.min = 1;
|
||||
n->occ.max = 1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static qse_rex_node_t* comp1 (comp_t* c, pair_t* pair)
|
||||
{
|
||||
pair->head = newnopnode (c);
|
||||
if (pair->head == QSE_NULL) return QSE_NULL;
|
||||
|
||||
pair->tail = pair->head;
|
||||
|
||||
while (c->c != QSE_T('|') && c->c != QSE_CHAR_EOF &&
|
||||
!(c->grouplvl >= 0 && c->c == QSE_T(')')))
|
||||
{
|
||||
qse_rex_node_t* tmp = comp2 (c);
|
||||
if (tmp == QSE_NULL)
|
||||
{
|
||||
/* TODO: free all nodes... from head down to tail... */
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
pair->tail->next = tmp;
|
||||
pair->tail = tmp;
|
||||
}
|
||||
|
||||
return pair->head;
|
||||
}
|
||||
|
||||
static qse_rex_node_t* comp0 (comp_t* c, qse_rex_node_t* ge)
|
||||
{
|
||||
qse_rex_node_t* left, * right, * tmp;
|
||||
pair_t xpair;
|
||||
|
||||
left = comp1 (c, &xpair);
|
||||
if (left == QSE_NULL) return QSE_NULL;
|
||||
xpair.tail->next = ge;
|
||||
|
||||
while (c->c == QSE_T('|'))
|
||||
{
|
||||
if (getc (c) <= -1)
|
||||
{
|
||||
//freere (left);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
right = comp1 (c, &xpair);
|
||||
if (right == QSE_NULL)
|
||||
{
|
||||
//freere (l and r);
|
||||
return QSE_NULL;
|
||||
}
|
||||
xpair.tail->next = ge;
|
||||
|
||||
tmp = newbranchnode (c, left, right);
|
||||
if (tmp == QSE_NULL)
|
||||
{
|
||||
//freere (left and right);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
left = tmp;
|
||||
}
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
qse_rex_node_t* qse_rex_comp (
|
||||
qse_rex_t* rex, const qse_char_t* ptr, qse_size_t len)
|
||||
{
|
||||
comp_t c;
|
||||
|
||||
if (rex->code != QSE_NULL)
|
||||
{
|
||||
freeallnodes (rex->code);
|
||||
rex->code = QSE_NULL;
|
||||
}
|
||||
|
||||
c.rex = rex;
|
||||
c.re.ptr = ptr;
|
||||
c.re.len = len;
|
||||
|
||||
c.ptr = ptr;
|
||||
c.end = ptr + len;
|
||||
c.c = QSE_CHAR_EOF;
|
||||
c.grouplvl = 0;
|
||||
c.start = QSE_NULL;
|
||||
|
||||
if (getc(&c) <= -1) return QSE_NULL;
|
||||
|
||||
c.start = newstartnode (&c);
|
||||
if (c.start != QSE_NULL)
|
||||
{
|
||||
qse_rex_node_t* end;
|
||||
end = newendnode (&c);
|
||||
if (end == QSE_NULL)
|
||||
{
|
||||
freenode (c.start, c.rex->mmgr);
|
||||
c.start = QSE_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_rex_node_t* tmp;
|
||||
//tmp = comp0 (&c, QSE_NULL);
|
||||
tmp = comp0 (&c, end);
|
||||
if (tmp == QSE_NULL)
|
||||
{
|
||||
//freenode (c.start, c.rex->mmgr);
|
||||
freeallnodes (c.start);
|
||||
c.start = QSE_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_printf (QSE_T("start has tmp...\n"));
|
||||
c.start->next = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rex->code = c.start;
|
||||
return rex->code;
|
||||
}
|
||||
|
||||
static group_t* pushgroup (exec_t* e, group_t* pg, qse_rex_node_t* gn)
|
||||
{
|
||||
group_t* g;
|
||||
QSE_ASSERT (gn->id == QSE_REX_NODE_GROUP);
|
||||
|
||||
g = (group_t*) QSE_MMGR_ALLOC (e->rex->mmgr, QSE_SIZEOF(*g));
|
||||
if (g == QSE_NULL)
|
||||
{
|
||||
/* TODO: set error info */
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
g->node = gn;
|
||||
g->occ = 0;
|
||||
g->next = pg;
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
static int addsimplecand (
|
||||
exec_t* e, cand_t* pcand, qse_rex_node_t* node, qse_size_t occ)
|
||||
{
|
||||
QSE_ASSERT (
|
||||
node->id == QSE_REX_NODE_CHAR ||
|
||||
node->id == QSE_REX_NODE_CHARSET
|
||||
);
|
||||
|
||||
cand_t cand;
|
||||
|
||||
cand.node = node;
|
||||
cand.occ = occ;
|
||||
cand.group = pcand->group;
|
||||
|
||||
if (node->id == QSE_REX_NODE_CHAR)
|
||||
qse_printf (QSE_T("adding %d %c\n"), node->id, node->u.c);
|
||||
else
|
||||
qse_printf (QSE_T("adding %d NA\n"), node->id);
|
||||
|
||||
if (qse_lda_insert (
|
||||
&e->cand[e->xxx],
|
||||
QSE_LDA_SIZE(&e->cand[e->xxx]),
|
||||
&cand, 1) == (qse_size_t)-1)
|
||||
{
|
||||
/* TODO: set error code: ENOERR */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int addnextcands (exec_t* e, group_t* group, qse_rex_node_t* cur)
|
||||
{
|
||||
/* skip all NOP nodes */
|
||||
while (cur && cur->id == QSE_REX_NODE_NOP) cur = cur->next;
|
||||
|
||||
/* nothing to add */
|
||||
if (cur == QSE_NULL) return 0;
|
||||
|
||||
if (cur->id == QSE_REX_NODE_END)
|
||||
{
|
||||
qse_printf (QSE_T("== ADDING THE END(MATCH) NODE MEANING MATCH FOUND == \n"));
|
||||
e->matched++;
|
||||
}
|
||||
else if (cur->id == QSE_REX_NODE_BRANCH)
|
||||
{
|
||||
#if 0
|
||||
QSE_ASSERT (cur->next == QSE_NULL);
|
||||
if (addnextcands (e, group, cur->u.b.left) <= -1) return -1;
|
||||
if (addnextcands (e, group, cur->u.b.right) <= -1) return -1;
|
||||
#endif
|
||||
}
|
||||
else if (cur->id == QSE_REX_NODE_GROUP)
|
||||
{
|
||||
group_t* g = pushgroup (e, group, cur);
|
||||
if (g == QSE_NULL) return -1;
|
||||
|
||||
/* add the first node in the group */
|
||||
if (addnextcands (e, g, cur->u.g.head) <= -1) return -1;
|
||||
|
||||
if (cur->occ.min <= 0)
|
||||
{
|
||||
/* if the group node is optional,
|
||||
* add the next node to the candidate array.
|
||||
* branch case => dup group */
|
||||
if (addnextcands (e, group, cur->next) <= -1) return -1;
|
||||
}
|
||||
}
|
||||
else if (cur->id == QSE_REX_NODE_GROUPEND)
|
||||
{
|
||||
group_t* group;
|
||||
qse_rex_node_t* node;
|
||||
|
||||
group = cand->group;
|
||||
QSE_ASSERT (group != QSE_NULL);
|
||||
|
||||
node = group->node;
|
||||
QSE_ASSERT (node == cur->u.ge.group);
|
||||
|
||||
if (group->occ < node->occ.max)
|
||||
{
|
||||
/* need to repeat itself */
|
||||
group->occ++;
|
||||
if (addnextcands (e, cand, node->u.g.head) <= -1) return -1;
|
||||
}
|
||||
|
||||
if (group->occ >= node->occ.min)
|
||||
{
|
||||
/* take the next atom as a candidate.
|
||||
* it is actually a branch case. */
|
||||
|
||||
cand = dupgrouppoppingtop (cand);
|
||||
|
||||
if (addnextcands (e, pg, node->next) <= -1) return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addsimplecand (e, cand, cur, 1) <= -1) return -1;
|
||||
if (cur->occ.min <= 0)
|
||||
{
|
||||
/* if the node is optional,
|
||||
* add the next node to the candidate array */
|
||||
if (addnextcands (e, pg, cur->next) <= -1) return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int match (exec_t* e, const qse_char_t* curp)
|
||||
{
|
||||
qse_size_t i;
|
||||
qse_char_t curc = *curp;
|
||||
|
||||
for (i = 0; i < QSE_LDA_SIZE(&e->cand[e->yyy]); i++)
|
||||
{
|
||||
cand_t* cand = QSE_LDA_DPTR(&e->cand[e->yyy],i);
|
||||
qse_rex_node_t* node = cand->node;
|
||||
|
||||
if (node->id == QSE_REX_NODE_CHAR)
|
||||
{
|
||||
if (node->u.c == curc)
|
||||
{
|
||||
qse_printf (QSE_T("matched %c\n"), node->u.c);
|
||||
|
||||
if (cand->occ < node->occ.max)
|
||||
{
|
||||
if (addsimplecand (e, cand, node, cand->occ+1) <= -1) return -1;
|
||||
}
|
||||
if (cand->occ >= node->occ.min)
|
||||
{
|
||||
|
||||
if (addnextcands (e, cand, node->next) <= -1) return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QSE_ASSERT (node->id == QSE_REX_NODE_CHARSET);
|
||||
qse_printf (QSE_T("charset not implemented...\n"));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int exec (exec_t* e)
|
||||
{
|
||||
const qse_char_t* ptr = e->sub.ptr;
|
||||
const qse_char_t* end = e->sub.ptr + e->sub.len;
|
||||
|
||||
e->matched = 0;
|
||||
e->xxx = 0;
|
||||
e->yyy = 1;
|
||||
|
||||
/* collect the initial candidates to cand[xxx] */
|
||||
qse_lda_clear (&e->cand[e->xxx]);
|
||||
|
||||
if (addnextcands (e, QSE_NULL, e->rex->code->next) <= -1) return -1;
|
||||
|
||||
while (ptr < end)
|
||||
{
|
||||
/* kind of swap cand[xxx] and cand[yyy] by swapping indices */
|
||||
int tmp = e->xxx;
|
||||
e->xxx = e->yyy;
|
||||
e->yyy = tmp;
|
||||
|
||||
/* check if there are any next candidates */
|
||||
if (QSE_LDA_SIZE(&e->cand[e->yyy]) <= 0)
|
||||
{
|
||||
/* if none, break */
|
||||
break;
|
||||
}
|
||||
|
||||
/* clear the array to hold the next candidates */
|
||||
qse_lda_clear (&e->cand[e->xxx]);
|
||||
|
||||
qse_printf (QSE_T("MATCHING %c\n"), *ptr);
|
||||
if (match (e, ptr) <= -1) return -1;
|
||||
|
||||
ptr++;
|
||||
}
|
||||
|
||||
qse_printf (QSE_T("TOTAL MATCHES FOUND... %d\n"), e->matched);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_exec_dds (exec_t* e, qse_mmgr_t* mmgr)
|
||||
{
|
||||
/* initializes dynamic data structures */
|
||||
if (qse_lda_init (&e->cand[0], mmgr, 100) == QSE_NULL)
|
||||
{
|
||||
/* TOOD: set error */
|
||||
return -1;
|
||||
}
|
||||
if (qse_lda_init (&e->cand[1], mmgr, 100) == QSE_NULL)
|
||||
{
|
||||
/* TOOD: set error */
|
||||
qse_lda_fini (&e->cand[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
qse_lda_setscale (&e->cand[0], QSE_SIZEOF(cand_t));
|
||||
qse_lda_setscale (&e->cand[1], QSE_SIZEOF(cand_t));
|
||||
|
||||
qse_lda_setcopier (&e->cand[0], QSE_LDA_COPIER_INLINE);
|
||||
qse_lda_setcopier (&e->cand[1], QSE_LDA_COPIER_INLINE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fini_exec_dds (exec_t* e)
|
||||
{
|
||||
qse_lda_fini (&e->cand[1]);
|
||||
qse_lda_fini (&e->cand[0]);
|
||||
}
|
||||
|
||||
int qse_rex_exec (qse_rex_t* rex,
|
||||
const qse_char_t* str, qse_size_t len,
|
||||
const qse_char_t* substr, qse_size_t sublen)
|
||||
{
|
||||
exec_t e;
|
||||
int n = 0;
|
||||
|
||||
if (rex->code == QSE_NULL)
|
||||
{
|
||||
//* TODO: set error code: no regular expression compiled.
|
||||
return -1;
|
||||
}
|
||||
|
||||
QSE_MEMSET (&e, 0, QSE_SIZEOF(e));
|
||||
e.rex = rex;
|
||||
e.str.ptr = str;
|
||||
e.str.len = len;
|
||||
e.sub.ptr = substr;
|
||||
e.sub.len = sublen;
|
||||
|
||||
if (init_exec_dds (&e, rex->mmgr) <= -1) return -1;
|
||||
|
||||
// TOOD: may have to execute exec in case sublen is 0.
|
||||
while (e.sub.len > 0)
|
||||
{
|
||||
n = exec (&e);
|
||||
if (n <= -1)
|
||||
{
|
||||
n = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (e.matched > 0) break;
|
||||
|
||||
e.sub.ptr++;
|
||||
e.sub.len--;
|
||||
}
|
||||
|
||||
fini_exec_dds (&e);
|
||||
|
||||
return n;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include -DNDEBUG
|
||||
|
||||
bin_PROGRAMS = chr str sll map lda fio pio sio time
|
||||
bin_PROGRAMS = chr str sll map lda fio pio sio time rex
|
||||
|
||||
LDFLAGS = -L../../lib/cmn
|
||||
LDADD = -lqsecmn
|
||||
@ -14,3 +14,9 @@ fio_SOURCES = fio.c
|
||||
pio_SOURCES = pio.c
|
||||
sio_SOURCES = sio.c
|
||||
time_SOURCES = time.c
|
||||
|
||||
rex_SOURCES = rex.cpp
|
||||
rex_CXXFLAGS = -I/usr/lib/wx/include/gtk2-unicode-release-2.8 -I/usr/include/wx-2.8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__ -pthread
|
||||
|
||||
#rex_LDFLAGS = -pthread -Wl,-Bsymbolic-functions -lwx_gtk2u_richtext-2.8 -lwx_gtk2u_aui-2.8 -lwx_gtk2u_xrc-2.8 -lwx_gtk2u_qa-2.8 -lwx_gtk2u_html-2.8 -lwx_gtk2u_adv-2.8 -lwx_gtk2u_core-2.8 -lwx_baseu_xml-2.8 -lwx_baseu_net-2.8 -lwx_baseu-2.8
|
||||
rex_LDFLAGS = -pthread -Wl,-Bsymbolic-functions -lwx_gtk2ud_richtext-2.8 -lwx_gtk2ud_aui-2.8 -lwx_gtk2ud_xrc-2.8 -lwx_gtk2ud_qa-2.8 -lwx_gtk2ud_html-2.8 -lwx_gtk2ud_adv-2.8 -lwx_gtk2ud_core-2.8 -lwx_baseud_xml-2.8 -lwx_baseud_net-2.8 -lwx_baseud-2.8
|
||||
|
@ -34,7 +34,7 @@ build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
bin_PROGRAMS = chr$(EXEEXT) str$(EXEEXT) sll$(EXEEXT) map$(EXEEXT) \
|
||||
lda$(EXEEXT) fio$(EXEEXT) pio$(EXEEXT) sio$(EXEEXT) \
|
||||
time$(EXEEXT)
|
||||
time$(EXEEXT) rex$(EXEEXT)
|
||||
subdir = samples/cmn
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
@ -71,6 +71,13 @@ am_pio_OBJECTS = pio.$(OBJEXT)
|
||||
pio_OBJECTS = $(am_pio_OBJECTS)
|
||||
pio_LDADD = $(LDADD)
|
||||
pio_DEPENDENCIES =
|
||||
am_rex_OBJECTS = rex-rex.$(OBJEXT)
|
||||
rex_OBJECTS = $(am_rex_OBJECTS)
|
||||
rex_LDADD = $(LDADD)
|
||||
rex_DEPENDENCIES =
|
||||
rex_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CXXLD) $(rex_CXXFLAGS) $(CXXFLAGS) \
|
||||
$(rex_LDFLAGS) $(LDFLAGS) -o $@
|
||||
am_sio_OBJECTS = sio.$(OBJEXT)
|
||||
sio_OBJECTS = $(am_sio_OBJECTS)
|
||||
sio_LDADD = $(LDADD)
|
||||
@ -99,12 +106,21 @@ CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
CXXLD = $(CXX)
|
||||
CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(lda_SOURCES) $(map_SOURCES) \
|
||||
$(pio_SOURCES) $(sio_SOURCES) $(sll_SOURCES) $(str_SOURCES) \
|
||||
$(time_SOURCES)
|
||||
DIST_SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(lda_SOURCES) \
|
||||
$(map_SOURCES) $(pio_SOURCES) $(sio_SOURCES) $(sll_SOURCES) \
|
||||
$(pio_SOURCES) $(rex_SOURCES) $(sio_SOURCES) $(sll_SOURCES) \
|
||||
$(str_SOURCES) $(time_SOURCES)
|
||||
DIST_SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(lda_SOURCES) \
|
||||
$(map_SOURCES) $(pio_SOURCES) $(rex_SOURCES) $(sio_SOURCES) \
|
||||
$(sll_SOURCES) $(str_SOURCES) $(time_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
@ -244,7 +260,7 @@ target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include -DNDEBUG
|
||||
LDADD = -lqsecmn
|
||||
chr_SOURCES = chr.c
|
||||
str_SOURCES = str.c
|
||||
@ -255,10 +271,15 @@ fio_SOURCES = fio.c
|
||||
pio_SOURCES = pio.c
|
||||
sio_SOURCES = sio.c
|
||||
time_SOURCES = time.c
|
||||
rex_SOURCES = rex.cpp
|
||||
rex_CXXFLAGS = -I/usr/lib/wx/include/gtk2-unicode-release-2.8 -I/usr/include/wx-2.8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__ -pthread
|
||||
|
||||
#rex_LDFLAGS = -pthread -Wl,-Bsymbolic-functions -lwx_gtk2u_richtext-2.8 -lwx_gtk2u_aui-2.8 -lwx_gtk2u_xrc-2.8 -lwx_gtk2u_qa-2.8 -lwx_gtk2u_html-2.8 -lwx_gtk2u_adv-2.8 -lwx_gtk2u_core-2.8 -lwx_baseu_xml-2.8 -lwx_baseu_net-2.8 -lwx_baseu-2.8
|
||||
rex_LDFLAGS = -pthread -Wl,-Bsymbolic-functions -lwx_gtk2ud_richtext-2.8 -lwx_gtk2ud_aui-2.8 -lwx_gtk2ud_xrc-2.8 -lwx_gtk2ud_qa-2.8 -lwx_gtk2ud_html-2.8 -lwx_gtk2ud_adv-2.8 -lwx_gtk2ud_core-2.8 -lwx_baseud_xml-2.8 -lwx_baseud_net-2.8 -lwx_baseud-2.8
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
.SUFFIXES: .c .cpp .lo .o .obj
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
@ -331,6 +352,9 @@ map$(EXEEXT): $(map_OBJECTS) $(map_DEPENDENCIES)
|
||||
pio$(EXEEXT): $(pio_OBJECTS) $(pio_DEPENDENCIES)
|
||||
@rm -f pio$(EXEEXT)
|
||||
$(LINK) $(pio_OBJECTS) $(pio_LDADD) $(LIBS)
|
||||
rex$(EXEEXT): $(rex_OBJECTS) $(rex_DEPENDENCIES)
|
||||
@rm -f rex$(EXEEXT)
|
||||
$(rex_LINK) $(rex_OBJECTS) $(rex_LDADD) $(LIBS)
|
||||
sio$(EXEEXT): $(sio_OBJECTS) $(sio_DEPENDENCIES)
|
||||
@rm -f sio$(EXEEXT)
|
||||
$(LINK) $(sio_OBJECTS) $(sio_LDADD) $(LIBS)
|
||||
@ -355,6 +379,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lda.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rex-rex.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sio.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sll.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str.Po@am__quote@
|
||||
@ -381,6 +406,41 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
.cpp.o:
|
||||
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
|
||||
|
||||
.cpp.obj:
|
||||
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
|
||||
.cpp.lo:
|
||||
@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
|
||||
|
||||
rex-rex.o: rex.cpp
|
||||
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rex_CXXFLAGS) $(CXXFLAGS) -MT rex-rex.o -MD -MP -MF $(DEPDIR)/rex-rex.Tpo -c -o rex-rex.o `test -f 'rex.cpp' || echo '$(srcdir)/'`rex.cpp
|
||||
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/rex-rex.Tpo $(DEPDIR)/rex-rex.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='rex.cpp' object='rex-rex.o' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rex_CXXFLAGS) $(CXXFLAGS) -c -o rex-rex.o `test -f 'rex.cpp' || echo '$(srcdir)/'`rex.cpp
|
||||
|
||||
rex-rex.obj: rex.cpp
|
||||
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rex_CXXFLAGS) $(CXXFLAGS) -MT rex-rex.obj -MD -MP -MF $(DEPDIR)/rex-rex.Tpo -c -o rex-rex.obj `if test -f 'rex.cpp'; then $(CYGPATH_W) 'rex.cpp'; else $(CYGPATH_W) '$(srcdir)/rex.cpp'; fi`
|
||||
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/rex-rex.Tpo $(DEPDIR)/rex-rex.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='rex.cpp' object='rex-rex.obj' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rex_CXXFLAGS) $(CXXFLAGS) -c -o rex-rex.obj `if test -f 'rex.cpp'; then $(CYGPATH_W) 'rex.cpp'; else $(CYGPATH_W) '$(srcdir)/rex.cpp'; fi`
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
|
347
qse/samples/cmn/rex.cpp
Normal file
347
qse/samples/cmn/rex.cpp
Normal file
@ -0,0 +1,347 @@
|
||||
#include <qse/cmn/rex.h>
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/cmn/stdio.h>
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/cmdline.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
|
||||
class MyApp: public wxApp
|
||||
{
|
||||
public:
|
||||
virtual bool OnInit();
|
||||
|
||||
virtual int OnExit();
|
||||
virtual int OnRun();
|
||||
|
||||
virtual void OnInitCmdLine(wxCmdLineParser& parser);
|
||||
virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
|
||||
|
||||
|
||||
wxString matPattern;
|
||||
wxString matString;
|
||||
};
|
||||
|
||||
DECLARE_APP(MyApp)
|
||||
|
||||
class MyFrame: public wxFrame
|
||||
{
|
||||
public:
|
||||
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
|
||||
~MyFrame ()
|
||||
{
|
||||
if (rex) qse_rex_close (rex);
|
||||
}
|
||||
|
||||
void OnQuit(wxCommandEvent& event);
|
||||
void OnAbout(wxCommandEvent& event);
|
||||
void OnComp(wxCommandEvent& event);
|
||||
|
||||
void OnPaint (wxPaintEvent& event);
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
protected:
|
||||
qse_rex_t* rex;
|
||||
qse_rex_node_t* start;
|
||||
|
||||
void drawArrow (wxDC& dc, qse_rex_node_t* f, qse_rex_node_t* t);
|
||||
void drawNode (wxDC& dc, qse_rex_node_t* n);
|
||||
void drawChain (wxDC& dc, qse_rex_node_t* n);
|
||||
|
||||
int nodex, nodey;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ID_Quit = 1,
|
||||
ID_Comp,
|
||||
ID_About,
|
||||
};
|
||||
|
||||
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||
EVT_MENU(ID_Quit, MyFrame::OnQuit)
|
||||
EVT_MENU(ID_Comp, MyFrame::OnComp)
|
||||
EVT_MENU(ID_About, MyFrame::OnAbout)
|
||||
EVT_PAINT(MyFrame::OnPaint)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
IMPLEMENT_APP(MyApp)
|
||||
|
||||
bool MyApp::OnInit()
|
||||
{
|
||||
if (!wxApp::OnInit()) return false;
|
||||
|
||||
MyFrame *frame = new MyFrame(
|
||||
_T("\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?"),
|
||||
wxPoint(50,50), wxSize(450,340)
|
||||
);
|
||||
|
||||
frame->Show(TRUE);
|
||||
SetTopWindow(frame);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int MyApp::OnExit()
|
||||
{
|
||||
// clean up
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MyApp::OnRun()
|
||||
{
|
||||
int exitcode = wxApp::OnRun();
|
||||
|
||||
//wxTheClipboard->Flush();
|
||||
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
void MyApp::OnInitCmdLine(wxCmdLineParser& parser)
|
||||
{
|
||||
static const wxCmdLineEntryDesc g_cmdLineDesc [] =
|
||||
{
|
||||
{ wxCMD_LINE_SWITCH, wxT("h"), wxT("help"),
|
||||
wxT("displays help on the command line parameters"),
|
||||
wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
|
||||
|
||||
//{ wxCMD_LINE_SWITCH, wxT("t"), wxT("test"),
|
||||
// wxT("test switch"),
|
||||
// wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_MANDATORY },
|
||||
|
||||
{ wxCMD_LINE_PARAM, NULL, NULL, wxT("pattern"),
|
||||
wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
|
||||
|
||||
{ wxCMD_LINE_PARAM, NULL, NULL, wxT("string"),
|
||||
wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
|
||||
|
||||
{ wxCMD_LINE_NONE }
|
||||
};
|
||||
|
||||
parser.SetDesc (g_cmdLineDesc);
|
||||
// must refuse '/' as parameter starter or cannot use "/path" style paths
|
||||
parser.SetSwitchChars (wxT("-"));
|
||||
}
|
||||
|
||||
bool MyApp::OnCmdLineParsed(wxCmdLineParser& parser)
|
||||
{
|
||||
//silent_mode = parser.Found(wxT("s"));
|
||||
|
||||
// to get at your unnamed parameters use
|
||||
/*
|
||||
wxArrayString files;
|
||||
for (int i = 0; i < parser.GetParamCount(); i++)
|
||||
{
|
||||
files.Add(parser.GetParam(i));
|
||||
}
|
||||
*/
|
||||
if (parser.GetParamCount() != 2)
|
||||
{
|
||||
wxMessageBox(_T("Usage: XXXXXXXXXXXXXXXXXXXXXXXXXXXXx"),
|
||||
_T("Error"), wxOK | wxICON_INFORMATION, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
matPattern = parser.GetParam(0);
|
||||
matString = parser.GetParam(1);
|
||||
|
||||
// and other command line parameters
|
||||
// then do what you need with them.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
MyFrame::MyFrame (
|
||||
const wxString& title, const wxPoint& pos, const wxSize& size)
|
||||
: wxFrame((wxFrame *)NULL, -1, title, pos, size), rex (NULL)
|
||||
{
|
||||
wxMenu *menuFile = new wxMenu;
|
||||
|
||||
menuFile->Append( ID_About, _T("&About...") );
|
||||
menuFile->Append( ID_Comp, _T("&Compile...") );
|
||||
menuFile->AppendSeparator();
|
||||
menuFile->Append( ID_Quit, _T("E&xit") );
|
||||
|
||||
wxMenuBar *menuBar = new wxMenuBar;
|
||||
menuBar->Append( menuFile, _T("&File") );
|
||||
|
||||
SetMenuBar( menuBar );
|
||||
|
||||
/*
|
||||
wxPanel *panel = new wxPanel(this, -1);
|
||||
wxFlexGridSizer* fgs = new wxFlexGridSizer (1, 2);
|
||||
|
||||
wxButton* but = new wxButton (panel, wxID_ANY, _T("XXXX"));
|
||||
wxTextCtrl* textctrl = new wxTextCtrl(panel, -1, wxT(""), wxPoint(-1, -1),
|
||||
wxSize(250, 150));
|
||||
|
||||
fgs->Add (but);
|
||||
fgs->Add (textctrl, 1, wxEXPAND);
|
||||
|
||||
panel->SetSizer (fgs);
|
||||
*/
|
||||
|
||||
CreateStatusBar();
|
||||
SetStatusText( _T("Welcome to wxWidgets!") );
|
||||
SetSize (wxSize (700,500));
|
||||
}
|
||||
|
||||
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
Close(TRUE);
|
||||
}
|
||||
|
||||
void MyFrame::OnComp(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
if (rex == NULL)
|
||||
{
|
||||
rex = qse_rex_open (QSE_NULL, 0, QSE_NULL);
|
||||
if (rex == NULL)
|
||||
{
|
||||
wxMessageBox(_T("Cannot open rex"),
|
||||
_T("Error"), wxOK | wxICON_INFORMATION, this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//const qse_char_t* x = QSE_T("y(abc|def|xyz|1234)x");
|
||||
//const qse_char_t* x = QSE_T("(abc|def|xyz|1234)x");
|
||||
//const qse_char_t* x = QSE_T("y(abc|def|xyz|1234");
|
||||
//const qse_char_t* x = QSE_T("(abc|abcdefg)");
|
||||
const qse_char_t* x = QSE_T("a*b?c*defg");
|
||||
|
||||
//((MyApp*)wxTheApp)->matPattern;
|
||||
MyApp& app = wxGetApp();
|
||||
|
||||
start = qse_rex_comp (rex, app.matPattern.wx_str(), app.matPattern.Len());
|
||||
if (start == QSE_NULL)
|
||||
{
|
||||
wxMessageBox(_T("Cannot compile rex"),
|
||||
_T("Error"), wxOK | wxICON_INFORMATION, this);
|
||||
return;
|
||||
}
|
||||
|
||||
//const qse_char_t* text = QSE_T("abcyabcxxx");
|
||||
const qse_char_t* text = QSE_T("abcdefg");
|
||||
qse_rex_exec (rex,
|
||||
app.matString.wx_str(),app.matString.Len(),
|
||||
app.matString.wx_str(),app.matString.Len());
|
||||
|
||||
Refresh ();
|
||||
}
|
||||
|
||||
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxMessageBox(_T("This is a wxWidgets Hello world sample"),
|
||||
_T("\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?"), wxOK | wxICON_INFORMATION, this);
|
||||
}
|
||||
|
||||
void MyFrame::drawArrow (wxDC& dc, qse_rex_node_t* f, qse_rex_node_t* t)
|
||||
{
|
||||
}
|
||||
|
||||
void MyFrame::drawNode (wxDC& dc, qse_rex_node_t* n)
|
||||
{
|
||||
if (n->id == QSE_REX_NODE_BRANCH)
|
||||
{
|
||||
dc.DrawText (_T("<BR>"), nodex, nodey);
|
||||
}
|
||||
else if (n->id == QSE_REX_NODE_CHAR)
|
||||
{
|
||||
qse_char_t x[2];
|
||||
|
||||
x[0] = n->u.c;
|
||||
x[1] = QSE_T('\0');
|
||||
dc.DrawText (x, nodex, nodey);
|
||||
}
|
||||
else if (n->id == QSE_REX_NODE_START)
|
||||
{
|
||||
dc.DrawText (_T("<ST>"), nodex, nodey);
|
||||
}
|
||||
else if (n->id == QSE_REX_NODE_END)
|
||||
{
|
||||
dc.DrawText (_T("<E>"), nodex, nodey);
|
||||
}
|
||||
else if (n->id == QSE_REX_NODE_GROUP)
|
||||
{
|
||||
dc.DrawText (_T("<G>"), nodex, nodey);
|
||||
}
|
||||
else if (n->id == QSE_REX_NODE_GROUPEND)
|
||||
{
|
||||
dc.DrawText (_T("<GE>"), nodex, nodey);
|
||||
}
|
||||
else if (n->id == QSE_REX_NODE_NOP)
|
||||
{
|
||||
dc.DrawText (_T("<NOP>"), nodex, nodey);
|
||||
}
|
||||
}
|
||||
|
||||
void MyFrame::drawChain (wxDC& dc, qse_rex_node_t* n)
|
||||
{
|
||||
qse_rex_node_t* t = n;
|
||||
|
||||
while (t != QSE_NULL)
|
||||
{
|
||||
if (t->id == QSE_REX_NODE_BRANCH)
|
||||
{
|
||||
drawNode (dc, t);
|
||||
nodex += 50;
|
||||
|
||||
int oldx = nodex;
|
||||
drawChain (dc, t->u.b.left);
|
||||
|
||||
nodex = oldx;
|
||||
nodey += 50;
|
||||
drawChain (dc, t->u.b.right);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawNode (dc, t);
|
||||
nodex += 50;
|
||||
}
|
||||
|
||||
if (t->id == QSE_REX_NODE_GROUP)
|
||||
t = t->u.g.head;
|
||||
else if (t->id == QSE_REX_NODE_GROUPEND)
|
||||
t = t->u.ge.group->next;
|
||||
else t = t->next;
|
||||
}
|
||||
}
|
||||
|
||||
void MyFrame::OnPaint(wxPaintEvent& event)
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
//wxClientDC dc (this);
|
||||
|
||||
dc.SetPen(*wxBLACK_PEN);
|
||||
dc.SetBrush(*wxGREY_BRUSH);
|
||||
|
||||
// Get window dimensions
|
||||
wxSize sz = GetClientSize();
|
||||
|
||||
#if 0
|
||||
// Our rectangle dimensions
|
||||
wxCoord w = 100, h = 50;
|
||||
|
||||
// Center the rectangle on the window, but never
|
||||
// draw at a negative position.
|
||||
int x = wxMax (0, (sz.x - w) / 2);
|
||||
int y = wxMax (0, (sz.y - h) / 2);
|
||||
|
||||
wxRect rectToDraw(x, y, w, h);
|
||||
|
||||
// For efficiency, do not draw if not exposed
|
||||
if (IsExposed(rectToDraw)) dc.DrawRectangle(rectToDraw);
|
||||
#endif
|
||||
|
||||
if (start)
|
||||
{
|
||||
nodex = 5; nodey = 5;
|
||||
drawChain (dc, start);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user