From 5e21877849af7fee3a347cb615e0c9dbccd22c98 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sat, 14 Nov 2009 08:01:57 +0000 Subject: [PATCH] interim commit --- qse/include/qse/cmn/rex.h | 70 +++- qse/lib/cmn/Makefile.am | 4 +- qse/lib/cmn/Makefile.in | 13 +- qse/lib/cmn/rex.c | 4 +- qse/lib/cmn/rex1.c | 755 ++++++++++++++++++++++++++++++++++++ qse/samples/cmn/Makefile.am | 10 +- qse/samples/cmn/Makefile.in | 74 +++- qse/samples/cmn/rex.cpp | 347 +++++++++++++++++ 8 files changed, 1253 insertions(+), 24 deletions(-) create mode 100644 qse/lib/cmn/rex1.c create mode 100644 qse/samples/cmn/rex.cpp diff --git a/qse/include/qse/cmn/rex.h b/qse/include/qse/cmn/rex.h index bd79ac75..8ae3630e 100644 --- a/qse/include/qse/cmn/rex.h +++ b/qse/include/qse/cmn/rex.h @@ -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 ( diff --git a/qse/lib/cmn/Makefile.am b/qse/lib/cmn/Makefile.am index 6110b030..4cbb3c17 100644 --- a/qse/lib/cmn/Makefile.am +++ b/qse/lib/cmn/Makefile.am @@ -1,11 +1,11 @@ AUTOMAKE_OPTIONS = nostdinc -AM_CPPFLAGS = -I$(top_srcdir)/include +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 \ diff --git a/qse/lib/cmn/Makefile.in b/qse/lib/cmn/Makefile.in index 23a579c5..26f101c5 100644 --- a/qse/lib/cmn/Makefile.in +++ b/qse/lib/cmn/Makefile.in @@ -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) \ @@ -217,11 +217,11 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = nostdinc -AM_CPPFLAGS = -I$(top_srcdir)/include +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@ diff --git a/qse/lib/cmn/rex.c b/qse/lib/cmn/rex.c index 7a41b8bf..529d320f 100644 --- a/qse/lib/cmn/rex.c +++ b/qse/lib/cmn/rex.c @@ -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, diff --git a/qse/lib/cmn/rex1.c b/qse/lib/cmn/rex1.c new file mode 100644 index 00000000..3beff122 --- /dev/null +++ b/qse/lib/cmn/rex1.c @@ -0,0 +1,755 @@ +/* + * $Id$ + +{LICENSE HERE} + + */ + +#include +#include +#include +#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 => \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; +} diff --git a/qse/samples/cmn/Makefile.am b/qse/samples/cmn/Makefile.am index f42e1ed2..8a0d7f1d 100644 --- a/qse/samples/cmn/Makefile.am +++ b/qse/samples/cmn/Makefile.am @@ -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 diff --git a/qse/samples/cmn/Makefile.in b/qse/samples/cmn/Makefile.in index 5df5ddad..1bd2af32 100644 --- a/qse/samples/cmn/Makefile.in +++ b/qse/samples/cmn/Makefile.in @@ -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 diff --git a/qse/samples/cmn/rex.cpp b/qse/samples/cmn/rex.cpp new file mode 100644 index 00000000..00aa7dc5 --- /dev/null +++ b/qse/samples/cmn/rex.cpp @@ -0,0 +1,347 @@ +#include +#include +#include + +#include +#include + +#include +#include + +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("
"), 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(""), nodex, nodey); + } + else if (n->id == QSE_REX_NODE_END) + { + dc.DrawText (_T(""), nodex, nodey); + } + else if (n->id == QSE_REX_NODE_GROUP) + { + dc.DrawText (_T(""), nodex, nodey); + } + else if (n->id == QSE_REX_NODE_GROUPEND) + { + dc.DrawText (_T(""), nodex, nodey); + } + else if (n->id == QSE_REX_NODE_NOP) + { + dc.DrawText (_T(""), 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); + } +} + + +