have single dump function per engine

This commit is contained in:
Alex Coyte 2016-11-02 10:36:24 +11:00 committed by Matthew Barr
parent 71ff480b77
commit 32c826e9c6
23 changed files with 262 additions and 207 deletions

View File

@ -986,6 +986,8 @@ set(hs_dump_SRCS
src/rose/rose_dump.h src/rose/rose_dump.h
src/util/dump_charclass.cpp src/util/dump_charclass.cpp
src/util/dump_charclass.h src/util/dump_charclass.h
src/util/dump_util.cpp
src/util/dump_util.h
) )
if (DUMP_SUPPORT) if (DUMP_SUPPORT)

View File

@ -40,18 +40,18 @@
#include "shufticompile.h" #include "shufticompile.h"
#include "trufflecompile.h" #include "trufflecompile.h"
#include "util/charreach.h" #include "util/charreach.h"
#include "util/dump_util.h"
#include "util/dump_charclass.h" #include "util/dump_charclass.h"
#ifndef DUMP_SUPPORT #ifndef DUMP_SUPPORT
#error No dump support! #error No dump support!
#endif #endif
namespace ue2 { /* Note: No dot files for castle */
void nfaExecCastle_dumpDot(const struct NFA *, FILE *, using namespace std;
UNUSED const std::string &base) {
// No GraphViz output for Castles. namespace ue2 {
}
static static
void dumpTextSubCastle(const SubCastle &sub, FILE *f) { void dumpTextSubCastle(const SubCastle &sub, FILE *f) {
@ -68,9 +68,11 @@ void dumpTextSubCastle(const SubCastle &sub, FILE *f) {
fprintf(f, "\n"); fprintf(f, "\n");
} }
void nfaExecCastle_dumpText(const struct NFA *nfa, FILE *f) { void nfaExecCastle_dump(const struct NFA *nfa, const string &base) {
const Castle *c = (const Castle *)getImplNfa(nfa); const Castle *c = (const Castle *)getImplNfa(nfa);
FILE *f = fopen_or_throw((base + ".txt").c_str(), "w");
fprintf(f, "Castle multi-tenant repeat engine\n"); fprintf(f, "Castle multi-tenant repeat engine\n");
fprintf(f, "\n"); fprintf(f, "\n");
fprintf(f, "Number of repeat tenants: %u\n", c->numRepeats); fprintf(f, "Number of repeat tenants: %u\n", c->numRepeats);
@ -113,6 +115,7 @@ void nfaExecCastle_dumpText(const struct NFA *nfa, FILE *f) {
fprintf(f, "Sub %u:\n", i); fprintf(f, "Sub %u:\n", i);
dumpTextSubCastle(sub[i], f); dumpTextSubCastle(sub[i], f);
} }
fclose(f);
} }
} // namespace ue2 } // namespace ue2

View File

@ -31,15 +31,13 @@
#if defined(DUMP_SUPPORT) #if defined(DUMP_SUPPORT)
#include <cstdio>
#include <string> #include <string>
struct NFA; struct NFA;
namespace ue2 { namespace ue2 {
void nfaExecCastle_dumpDot(const NFA *nfa, FILE *file, const std::string &base); void nfaExecCastle_dump(const NFA *nfa, const std::string &base);
void nfaExecCastle_dumpText(const NFA *nfa, FILE *file);
} // namespace ue2 } // namespace ue2

View File

@ -37,6 +37,7 @@
#include "ue2common.h" #include "ue2common.h"
#include "util/charreach.h" #include "util/charreach.h"
#include "util/dump_charclass.h" #include "util/dump_charclass.h"
#include "util/dump_util.h"
#include "util/unaligned.h" #include "util/unaligned.h"
#include <cctype> #include <cctype>
@ -259,8 +260,8 @@ void dumpTransitions(const NFA *nfa, FILE *f,
fprintf(f, "\n"); fprintf(f, "\n");
} }
void nfaExecGough8_dumpDot(const struct NFA *nfa, FILE *f, static
UNUSED const string &base) { void nfaExecGough8_dumpDot(const struct NFA *nfa, FILE *f) {
assert(nfa->type == GOUGH_NFA_8); assert(nfa->type == GOUGH_NFA_8);
const mcclellan *m = (const mcclellan *)getImplNfa(nfa); const mcclellan *m = (const mcclellan *)getImplNfa(nfa);
@ -279,6 +280,7 @@ void nfaExecGough8_dumpDot(const struct NFA *nfa, FILE *f,
fprintf(f, "}\n"); fprintf(f, "}\n");
} }
static
void nfaExecGough8_dumpText(const struct NFA *nfa, FILE *f) { void nfaExecGough8_dumpText(const struct NFA *nfa, FILE *f) {
assert(nfa->type == GOUGH_NFA_8); assert(nfa->type == GOUGH_NFA_8);
@ -303,8 +305,8 @@ void nfaExecGough8_dumpText(const struct NFA *nfa, FILE *f) {
dumpTextReverse(nfa, f); dumpTextReverse(nfa, f);
} }
void nfaExecGough16_dumpDot(const struct NFA *nfa, FILE *f, static
UNUSED const string &base) { void nfaExecGough16_dumpDot(const struct NFA *nfa, FILE *f) {
assert(nfa->type == GOUGH_NFA_16); assert(nfa->type == GOUGH_NFA_16);
const mcclellan *m = (const mcclellan *)getImplNfa(nfa); const mcclellan *m = (const mcclellan *)getImplNfa(nfa);
@ -323,6 +325,7 @@ void nfaExecGough16_dumpDot(const struct NFA *nfa, FILE *f,
fprintf(f, "}\n"); fprintf(f, "}\n");
} }
static
void nfaExecGough16_dumpText(const struct NFA *nfa, FILE *f) { void nfaExecGough16_dumpText(const struct NFA *nfa, FILE *f) {
assert(nfa->type == GOUGH_NFA_16); assert(nfa->type == GOUGH_NFA_16);
const mcclellan *m = (const mcclellan *)getImplNfa(nfa); const mcclellan *m = (const mcclellan *)getImplNfa(nfa);
@ -348,4 +351,24 @@ void nfaExecGough16_dumpText(const struct NFA *nfa, FILE *f) {
dumpTextReverse(nfa, f); dumpTextReverse(nfa, f);
} }
void nfaExecGough16_dump(const NFA *nfa, const string &base) {
assert(nfa->type == GOUGH_NFA_16);
FILE *f = fopen_or_throw((base + ".txt").c_str(), "w");
nfaExecGough16_dumpText(nfa, f);
fclose(f);
f = fopen_or_throw((base + ".dot").c_str(), "w");
nfaExecGough16_dumpDot(nfa, f);
fclose(f);
}
void nfaExecGough8_dump(const NFA *nfa, const string &base) {
assert(nfa->type == GOUGH_NFA_8);
FILE *f = fopen_or_throw((base + ".txt").c_str(), "w");
nfaExecGough8_dumpText(nfa, f);
fclose(f);
f = fopen_or_throw((base + ".dot").c_str(), "w");
nfaExecGough8_dumpDot(nfa, f);
fclose(f);
}
} // namespace ue2 } // namespace ue2

View File

@ -39,12 +39,8 @@ struct NFA;
namespace ue2 { namespace ue2 {
void nfaExecGough8_dumpDot(const NFA *nfa, FILE *file, void nfaExecGough8_dump(const NFA *nfa, const std::string &base);
const std::string &base); void nfaExecGough16_dump(const NFA *nfa, const std::string &base);
void nfaExecGough16_dumpDot(const NFA *nfa, FILE *file,
const std::string &base);
void nfaExecGough8_dumpText(const NFA *nfa, FILE *file);
void nfaExecGough16_dumpText(const NFA *nfa, FILE *file);
} // namespace ue2 } // namespace ue2

View File

@ -42,38 +42,17 @@
#include "trufflecompile.h" #include "trufflecompile.h"
#include "util/charreach.h" #include "util/charreach.h"
#include "util/dump_charclass.h" #include "util/dump_charclass.h"
#include "util/dump_util.h"
#ifndef DUMP_SUPPORT #ifndef DUMP_SUPPORT
#error No dump support! #error No dump support!
#endif #endif
/* Note: No dot files for LBR */
using namespace std;
namespace ue2 { namespace ue2 {
void nfaExecLbrDot_dumpDot(UNUSED const NFA *nfa, UNUSED FILE *f,
UNUSED const std::string &base) {
// No impl
}
void nfaExecLbrVerm_dumpDot(UNUSED const NFA *nfa, UNUSED FILE *f,
UNUSED const std::string &base) {
// No impl
}
void nfaExecLbrNVerm_dumpDot(UNUSED const NFA *nfa, UNUSED FILE *f,
UNUSED const std::string &base) {
// No impl
}
void nfaExecLbrShuf_dumpDot(UNUSED const NFA *nfa, UNUSED FILE *f,
UNUSED const std::string &base) {
// No impl
}
void nfaExecLbrTruf_dumpDot(UNUSED const NFA *nfa, UNUSED FILE *f,
UNUSED const std::string &base) {
// No impl
}
static static
void lbrDumpCommon(const lbr_common *lc, FILE *f) { void lbrDumpCommon(const lbr_common *lc, FILE *f) {
const RepeatInfo *info const RepeatInfo *info
@ -88,39 +67,52 @@ void lbrDumpCommon(const lbr_common *lc, FILE *f) {
fprintf(f, "min period: %u\n", info->minPeriod); fprintf(f, "min period: %u\n", info->minPeriod);
} }
void nfaExecLbrDot_dumpText(const NFA *nfa, FILE *f) { void nfaExecLbrDot_dump(const NFA *nfa, const string &base) {
assert(nfa); assert(nfa);
assert(nfa->type == LBR_NFA_DOT); assert(nfa->type == LBR_NFA_DOT);
const lbr_dot *ld = (const lbr_dot *)getImplNfa(nfa); const lbr_dot *ld = (const lbr_dot *)getImplNfa(nfa);
FILE *f = fopen_or_throw((base + ".txt").c_str(), "w");
lbrDumpCommon(&ld->common, f); lbrDumpCommon(&ld->common, f);
fprintf(f, "DOT model\n"); fprintf(f, "DOT model\n");
fprintf(f, "\n"); fprintf(f, "\n");
dumpTextReverse(nfa, f); dumpTextReverse(nfa, f);
fclose(f);
} }
void nfaExecLbrVerm_dumpText(const NFA *nfa, FILE *f) { void nfaExecLbrVerm_dump(const NFA *nfa, const string &base) {
assert(nfa); assert(nfa);
assert(nfa->type == LBR_NFA_VERM); assert(nfa->type == LBR_NFA_VERM);
const lbr_verm *lv = (const lbr_verm *)getImplNfa(nfa); const lbr_verm *lv = (const lbr_verm *)getImplNfa(nfa);
FILE *f = fopen_or_throw((base + ".txt").c_str(), "w");
lbrDumpCommon(&lv->common, f); lbrDumpCommon(&lv->common, f);
fprintf(f, "VERM model, scanning for 0x%02x\n", lv->c); fprintf(f, "VERM model, scanning for 0x%02x\n", lv->c);
fprintf(f, "\n"); fprintf(f, "\n");
dumpTextReverse(nfa, f); dumpTextReverse(nfa, f);
fclose(f);
} }
void nfaExecLbrNVerm_dumpText(const NFA *nfa, FILE *f) { void nfaExecLbrNVerm_dump(const NFA *nfa, const string &base) {
assert(nfa); assert(nfa);
assert(nfa->type == LBR_NFA_NVERM); assert(nfa->type == LBR_NFA_NVERM);
const lbr_verm *lv = (const lbr_verm *)getImplNfa(nfa); const lbr_verm *lv = (const lbr_verm *)getImplNfa(nfa);
FILE *f = fopen_or_throw((base + ".txt").c_str(), "w");
lbrDumpCommon(&lv->common, f); lbrDumpCommon(&lv->common, f);
fprintf(f, "NEGATED VERM model, scanning for 0x%02x\n", lv->c); fprintf(f, "NEGATED VERM model, scanning for 0x%02x\n", lv->c);
fprintf(f, "\n"); fprintf(f, "\n");
dumpTextReverse(nfa, f); dumpTextReverse(nfa, f);
fclose(f);
} }
void nfaExecLbrShuf_dumpText(const NFA *nfa, FILE *f) { void nfaExecLbrShuf_dump(const NFA *nfa, const string &base) {
assert(nfa); assert(nfa);
assert(nfa->type == LBR_NFA_SHUF); assert(nfa->type == LBR_NFA_SHUF);
FILE *f = fopen_or_throw((base + ".txt").c_str(), "w");
const lbr_shuf *ls = (const lbr_shuf *)getImplNfa(nfa); const lbr_shuf *ls = (const lbr_shuf *)getImplNfa(nfa);
lbrDumpCommon(&ls->common, f); lbrDumpCommon(&ls->common, f);
@ -129,11 +121,15 @@ void nfaExecLbrShuf_dumpText(const NFA *nfa, FILE *f) {
describeClass(cr, 20, CC_OUT_TEXT).c_str(), cr.count()); describeClass(cr, 20, CC_OUT_TEXT).c_str(), cr.count());
fprintf(f, "\n"); fprintf(f, "\n");
dumpTextReverse(nfa, f); dumpTextReverse(nfa, f);
fclose(f);
} }
void nfaExecLbrTruf_dumpText(const NFA *nfa, FILE *f) { void nfaExecLbrTruf_dump(const NFA *nfa, const string &base) {
assert(nfa); assert(nfa);
assert(nfa->type == LBR_NFA_TRUF); assert(nfa->type == LBR_NFA_TRUF);
FILE *f = fopen_or_throw((base + ".txt").c_str(), "w");
const lbr_truf *lt = (const lbr_truf *)getImplNfa(nfa); const lbr_truf *lt = (const lbr_truf *)getImplNfa(nfa);
lbrDumpCommon(&lt->common, f); lbrDumpCommon(&lt->common, f);
@ -142,6 +138,7 @@ void nfaExecLbrTruf_dumpText(const NFA *nfa, FILE *f) {
describeClass(cr, 20, CC_OUT_TEXT).c_str(), cr.count()); describeClass(cr, 20, CC_OUT_TEXT).c_str(), cr.count());
fprintf(f, "\n"); fprintf(f, "\n");
dumpTextReverse(nfa, f); dumpTextReverse(nfa, f);
fclose(f);
} }
} // namespace ue2 } // namespace ue2

View File

@ -31,28 +31,17 @@
#ifdef DUMP_SUPPORT #ifdef DUMP_SUPPORT
#include <cstdio>
#include <string> #include <string>
struct NFA; struct NFA;
namespace ue2 { namespace ue2 {
void nfaExecLbrDot_dumpDot(const struct NFA *nfa, FILE *file, void nfaExecLbrDot_dump(const struct NFA *nfa, const std::string &base);
const std::string &base); void nfaExecLbrVerm_dump(const struct NFA *nfa, const std::string &base);
void nfaExecLbrVerm_dumpDot(const struct NFA *nfa, FILE *file, void nfaExecLbrNVerm_dump(const struct NFA *nfa, const std::string &base);
const std::string &base); void nfaExecLbrShuf_dump(const struct NFA *nfa, const std::string &base);
void nfaExecLbrNVerm_dumpDot(const struct NFA *nfa, FILE *file, void nfaExecLbrTruf_dump(const struct NFA *nfa, const std::string &base);
const std::string &base);
void nfaExecLbrShuf_dumpDot(const struct NFA *nfa, FILE *file,
const std::string &base);
void nfaExecLbrTruf_dumpDot(const struct NFA *nfa, FILE *file,
const std::string &base);
void nfaExecLbrDot_dumpText(const struct NFA *nfa, FILE *file);
void nfaExecLbrVerm_dumpText(const struct NFA *nfa, FILE *file);
void nfaExecLbrNVerm_dumpText(const struct NFA *nfa, FILE *file);
void nfaExecLbrTruf_dumpText(const struct NFA *nfa, FILE *file);
void nfaExecLbrShuf_dumpText(const struct NFA *nfa, FILE *file);
} // namespace ue2 } // namespace ue2

View File

@ -41,9 +41,7 @@ extern "C"
#define GENERATE_NFA_DUMP_DECL(gf_name) \ #define GENERATE_NFA_DUMP_DECL(gf_name) \
} /* extern "C" */ \ } /* extern "C" */ \
namespace ue2 { \ namespace ue2 { \
void gf_name##_dumpDot(const struct NFA *nfa, FILE *file, \ void gf_name##_dump(const struct NFA *nfa, const std::string &base); \
const std::string &base); \
void gf_name##_dumpText(const struct NFA *nfa, FILE *file); \
} /* namespace ue2 */ \ } /* namespace ue2 */ \
extern "C" { extern "C" {

View File

@ -35,9 +35,10 @@
#include "limex_internal.h" #include "limex_internal.h"
#include "nfa_dump_internal.h" #include "nfa_dump_internal.h"
#include "ue2common.h" #include "ue2common.h"
#include "util/charreach.h"
#include "util/dump_charclass.h" #include "util/dump_charclass.h"
#include "util/dump_mask.h" #include "util/dump_mask.h"
#include "util/charreach.h" #include "util/dump_util.h"
#include <algorithm> #include <algorithm>
#include <cstdio> #include <cstdio>
@ -472,37 +473,32 @@ void dumpLimDotInfo(const limex_type *limex, u32 state, FILE *f) {
} }
} }
#define DUMP_TEXT_FN(ddf_n) \ #define LIMEX_DUMP_FN(size) \
void nfaExecLimEx##ddf_n##_dumpText(const NFA *nfa, FILE *f) { \ void nfaExecLimEx##size##_dump(const NFA *nfa, const string &base) { \
dumpLimexText((const LimExNFA##ddf_n *)getImplNfa(nfa), f); \ auto limex = (const LimExNFA##size *)getImplNfa(nfa); \
}
#define DUMP_DOT_FN(ddf_n) \
void nfaExecLimEx##ddf_n##_dumpDot(const NFA *nfa, FILE *f, \
UNUSED const string &base) { \
const LimExNFA##ddf_n *limex = \
(const LimExNFA##ddf_n *)getImplNfa(nfa); \
\ \
FILE *f = fopen_or_throw((base + ".txt").c_str(), "w"); \
dumpLimexText(limex, f); \
fclose(f); \
\
f = fopen_or_throw((base + ".dot").c_str(), "w"); \
dumpDotPreamble(f); \ dumpDotPreamble(f); \
u32 state_count = nfa->nPositions; \ u32 state_count = nfa->nPositions; \
dumpVertexDotInfo(limex, state_count, f, \ dumpVertexDotInfo(limex, state_count, f, \
limex_labeller<LimExNFA##ddf_n>(limex)); \ limex_labeller<LimExNFA##size>(limex)); \
for (u32 i = 0; i < state_count; i++) { \ for (u32 i = 0; i < state_count; i++) { \
dumpLimDotInfo(limex, i, f); \ dumpLimDotInfo(limex, i, f); \
dumpExDotInfo(limex, i, f); \ dumpExDotInfo(limex, i, f); \
} \ } \
dumpDotTrailer(f); \ dumpDotTrailer(f); \
fclose(f); \
} }
#define LIMEX_DUMP_FNS(size) \ LIMEX_DUMP_FN(32)
DUMP_TEXT_FN(size) \ LIMEX_DUMP_FN(64)
DUMP_DOT_FN(size) LIMEX_DUMP_FN(128)
LIMEX_DUMP_FN(256)
LIMEX_DUMP_FNS(32) LIMEX_DUMP_FN(384)
LIMEX_DUMP_FNS(64) LIMEX_DUMP_FN(512)
LIMEX_DUMP_FNS(128)
LIMEX_DUMP_FNS(256)
LIMEX_DUMP_FNS(384)
LIMEX_DUMP_FNS(512)
} // namespace ue2 } // namespace ue2

View File

@ -39,6 +39,7 @@
#include "ue2common.h" #include "ue2common.h"
#include "util/charreach.h" #include "util/charreach.h"
#include "util/dump_charclass.h" #include "util/dump_charclass.h"
#include "util/dump_util.h"
#include "util/unaligned.h" #include "util/unaligned.h"
#include <cctype> #include <cctype>
@ -267,8 +268,8 @@ void dumpDotPreambleDfa(FILE *f) {
fprintf(f, "0 [style=invis];\n"); fprintf(f, "0 [style=invis];\n");
} }
void nfaExecMcClellan16_dumpDot(const NFA *nfa, FILE *f, static
UNUSED const string &base) { void nfaExecMcClellan16_dumpDot(const NFA *nfa, FILE *f) {
assert(nfa->type == MCCLELLAN_NFA_16); assert(nfa->type == MCCLELLAN_NFA_16);
const mcclellan *m = (const mcclellan *)getImplNfa(nfa); const mcclellan *m = (const mcclellan *)getImplNfa(nfa);
@ -287,8 +288,8 @@ void nfaExecMcClellan16_dumpDot(const NFA *nfa, FILE *f,
fprintf(f, "}\n"); fprintf(f, "}\n");
} }
void nfaExecMcClellan8_dumpDot(const NFA *nfa, FILE *f, static
UNUSED const string &base) { void nfaExecMcClellan8_dumpDot(const NFA *nfa, FILE *f) {
assert(nfa->type == MCCLELLAN_NFA_8); assert(nfa->type == MCCLELLAN_NFA_8);
const mcclellan *m = (const mcclellan *)getImplNfa(nfa); const mcclellan *m = (const mcclellan *)getImplNfa(nfa);
@ -397,6 +398,7 @@ void dumpTransitions(FILE *f, const NFA *nfa, const mcclellan *m,
} }
} }
static
void nfaExecMcClellan16_dumpText(const NFA *nfa, FILE *f) { void nfaExecMcClellan16_dumpText(const NFA *nfa, FILE *f) {
assert(nfa->type == MCCLELLAN_NFA_16); assert(nfa->type == MCCLELLAN_NFA_16);
const mcclellan *m = (const mcclellan *)getImplNfa(nfa); const mcclellan *m = (const mcclellan *)getImplNfa(nfa);
@ -417,6 +419,7 @@ void nfaExecMcClellan16_dumpText(const NFA *nfa, FILE *f) {
dumpTextReverse(nfa, f); dumpTextReverse(nfa, f);
} }
static
void nfaExecMcClellan8_dumpText(const NFA *nfa, FILE *f) { void nfaExecMcClellan8_dumpText(const NFA *nfa, FILE *f) {
assert(nfa->type == MCCLELLAN_NFA_8); assert(nfa->type == MCCLELLAN_NFA_8);
const mcclellan *m = (const mcclellan *)getImplNfa(nfa); const mcclellan *m = (const mcclellan *)getImplNfa(nfa);
@ -437,4 +440,24 @@ void nfaExecMcClellan8_dumpText(const NFA *nfa, FILE *f) {
dumpTextReverse(nfa, f); dumpTextReverse(nfa, f);
} }
void nfaExecMcClellan16_dump(const NFA *nfa, const string &base) {
assert(nfa->type == MCCLELLAN_NFA_16);
FILE *f = fopen_or_throw((base + ".txt").c_str(), "w");
nfaExecMcClellan16_dumpText(nfa, f);
fclose(f);
f = fopen_or_throw((base + ".dot").c_str(), "w");
nfaExecMcClellan16_dumpDot(nfa, f);
fclose(f);
}
void nfaExecMcClellan8_dump(const NFA *nfa, const string &base) {
assert(nfa->type == MCCLELLAN_NFA_8);
FILE *f = fopen_or_throw((base + ".txt").c_str(), "w");
nfaExecMcClellan8_dumpText(nfa, f);
fclose(f);
f = fopen_or_throw((base + ".dot").c_str(), "w");
nfaExecMcClellan8_dumpDot(nfa, f);
fclose(f);
}
} // namespace ue2 } // namespace ue2

View File

@ -43,14 +43,10 @@ union AccelAux;
namespace ue2 { namespace ue2 {
void nfaExecMcClellan8_dumpDot(const struct NFA *nfa, FILE *file, void nfaExecMcClellan8_dump(const struct NFA *nfa, const std::string &base);
const std::string &base); void nfaExecMcClellan16_dump(const struct NFA *nfa, const std::string &base);
void nfaExecMcClellan16_dumpDot(const struct NFA *nfa, FILE *file,
const std::string &base);
void nfaExecMcClellan8_dumpText(const struct NFA *nfa, FILE *file);
void nfaExecMcClellan16_dumpText(const struct NFA *nfa, FILE *file);
/* These functions are shared with the Haig dump code. */ /* These functions are shared with the Gough dump code. */
const mstate_aux *getAux(const NFA *n, dstate_id_t i); const mstate_aux *getAux(const NFA *n, dstate_id_t i);
void describeEdge(FILE *f, const u16 *t, u16 i); void describeEdge(FILE *f, const u16 *t, u16 i);

View File

@ -36,6 +36,7 @@
#include "ue2common.h" #include "ue2common.h"
#include "util/compare.h" #include "util/compare.h"
#include "util/dump_mask.h" #include "util/dump_mask.h"
#include "util/dump_util.h"
#include <cstdlib> #include <cstdlib>
#include <cstdio> #include <cstdio>
@ -46,11 +47,11 @@
#error No dump support! #error No dump support!
#endif #endif
namespace ue2 { /* Note: No dot files for MPV */
void nfaExecMpv_dumpDot(UNUSED const NFA *nfa, UNUSED FILE *file, using namespace std;
UNUSED const std::string &base) {
} namespace ue2 {
static really_inline static really_inline
u32 largest_puff_repeat(const mpv *m, const mpv_kilopuff *kp) { u32 largest_puff_repeat(const mpv *m, const mpv_kilopuff *kp) {
@ -128,9 +129,11 @@ void dumpCounter(FILE *f, const mpv_counter_info *c) {
fprintf(f, "\n"); fprintf(f, "\n");
} }
void nfaExecMpv_dumpText(const NFA *nfa, FILE *f) { void nfaExecMpv_dump(const NFA *nfa, const string &base) {
const mpv *m = (const mpv *)getImplNfa(nfa); const mpv *m = (const mpv *)getImplNfa(nfa);
FILE *f = fopen_or_throw((base + ".txt").c_str(), "w");
fprintf(f, "Puff the Magic Engines\n"); fprintf(f, "Puff the Magic Engines\n");
fprintf(f, "\n"); fprintf(f, "\n");
fprintf(f, "%u puffettes in %u kilopuffs\n", m->puffette_count, fprintf(f, "%u puffettes in %u kilopuffs\n", m->puffette_count,
@ -151,6 +154,7 @@ void nfaExecMpv_dumpText(const NFA *nfa, FILE *f) {
} }
dumpTextReverse(nfa, f); dumpTextReverse(nfa, f);
fclose(f);
} }
} // namespace ue2 } // namespace ue2

View File

@ -31,16 +31,13 @@
#if defined(DUMP_SUPPORT) #if defined(DUMP_SUPPORT)
#include <cstdio>
#include <string> #include <string>
struct NFA; struct NFA;
namespace ue2 { namespace ue2 {
void nfaExecMpv_dumpDot(const struct NFA *nfa, FILE *file, void nfaExecMpv_dump(const struct NFA *nfa, const std::string &base);
const std::string &base);
void nfaExecMpv_dumpText(const struct NFA *nfa, FILE *file);
} // namespace ue2 } // namespace ue2

View File

@ -35,7 +35,6 @@
#if defined(DUMP_SUPPORT) #if defined(DUMP_SUPPORT)
#include <cstdio>
#include <string> #include <string>
struct NFA; struct NFA;
@ -43,13 +42,11 @@ struct NFA;
namespace ue2 { namespace ue2 {
/** /**
* \brief Dump (in Graphviz 'dot' format) a representation of the NFA into the * \brief Dump files representing the engine. All files dumped should begin with
* file pointed to by dotFile. * path/prefix specified by base. Generally a text file and a grpahviz (dot)
* files should be produced.
*/ */
void nfaDumpDot(const struct NFA *nfa, FILE *dotFile, const std::string &base); void nfaGenerateDumpFiles(const struct NFA *nfa, const std::string &base);
/** \brief Dump a textual representation of the NFA. */
void nfaDumpText(const struct NFA *fact, FILE *textFile);
} // namespace ue2 } // namespace ue2

View File

@ -82,13 +82,8 @@ namespace ue2 {
assert(0); \ assert(0); \
} }
void nfaDumpDot(const struct NFA *nfa, FILE *dotFile, void nfaGenerateDumpFiles(const struct NFA *nfa, const std::string &base) {
const std::string &base) { DISPATCH_BY_NFA_TYPE(_dump(nfa, base));
DISPATCH_BY_NFA_TYPE(_dumpDot(nfa, dotFile, base));
}
void nfaDumpText(const struct NFA *nfa, FILE *txtFile) {
DISPATCH_BY_NFA_TYPE(_dumpText(nfa, txtFile));
} }
} // namespace ue2 } // namespace ue2

View File

@ -38,6 +38,7 @@
#include "ue2common.h" #include "ue2common.h"
#include "util/charreach.h" #include "util/charreach.h"
#include "util/dump_charclass.h" #include "util/dump_charclass.h"
#include "util/dump_util.h"
#include "util/simd_utils.h" #include "util/simd_utils.h"
@ -115,6 +116,7 @@ void dumpMasks(FILE *f, const sheng *s) {
} }
} }
static
void nfaExecSheng_dumpText(const NFA *nfa, FILE *f) { void nfaExecSheng_dumpText(const NFA *nfa, FILE *f) {
assert(nfa->type == SHENG_NFA); assert(nfa->type == SHENG_NFA);
const sheng *s = (const sheng *)getImplNfa(nfa); const sheng *s = (const sheng *)getImplNfa(nfa);
@ -243,7 +245,8 @@ void shengGetTransitions(const NFA *n, u16 state, u16 *t) {
t[TOP] = aux->top & SHENG_STATE_MASK; t[TOP] = aux->top & SHENG_STATE_MASK;
} }
void nfaExecSheng_dumpDot(const NFA *nfa, FILE *f, const string &) { static
void nfaExecSheng_dumpDot(const NFA *nfa, FILE *f) {
assert(nfa->type == SHENG_NFA); assert(nfa->type == SHENG_NFA);
const sheng *s = (const sheng *)getImplNfa(nfa); const sheng *s = (const sheng *)getImplNfa(nfa);
@ -262,4 +265,14 @@ void nfaExecSheng_dumpDot(const NFA *nfa, FILE *f, const string &) {
fprintf(f, "}\n"); fprintf(f, "}\n");
} }
void nfaExecSheng_dump(const NFA *nfa, const string &base) {
assert(nfa->type == SHENG_NFA);
FILE *f = fopen_or_throw((base + ".txt").c_str(), "w");
nfaExecSheng_dumpText(nfa, f);
fclose(f);
f = fopen_or_throw((base + ".dot").c_str(), "w");
nfaExecSheng_dumpDot(nfa, f);
fclose(f);
}
} // namespace ue2 } // namespace ue2

View File

@ -31,16 +31,13 @@
#ifdef DUMP_SUPPORT #ifdef DUMP_SUPPORT
#include <cstdio>
#include <string> #include <string>
struct NFA; struct NFA;
namespace ue2 { namespace ue2 {
void nfaExecSheng_dumpDot(const struct NFA *nfa, FILE *file, void nfaExecSheng_dump(const struct NFA *nfa, const std::string &base);
const std::string &base);
void nfaExecSheng_dumpText(const struct NFA *nfa, FILE *file);
} // namespace ue2 } // namespace ue2

View File

@ -38,6 +38,7 @@
#include "nfa_dump_api.h" #include "nfa_dump_api.h"
#include "nfa_dump_internal.h" #include "nfa_dump_internal.h"
#include "nfa_internal.h" #include "nfa_internal.h"
#include "util/dump_util.h"
#include <string> #include <string>
#include <sstream> #include <sstream>
@ -46,27 +47,14 @@
#error No dump support! #error No dump support!
#endif #endif
using namespace std;
namespace ue2 { namespace ue2 {
void nfaExecTamarama_dumpDot(const struct NFA *nfa, UNUSED FILE *f, void nfaExecTamarama_dump(const struct NFA *nfa, const string &base) {
const std::string &base) {
const Tamarama *t = (const Tamarama *)getImplNfa(nfa); const Tamarama *t = (const Tamarama *)getImplNfa(nfa);
const u32 *subOffset =
(const u32 *)((const char *)t + sizeof(struct Tamarama) +
t->numSubEngines * sizeof(u32));
for (u32 i = 0; i < t->numSubEngines; i++) {
std::stringstream ssdot;
ssdot << base << "rose_nfa_" << nfa->queueIndex
<< "_sub_" << i << ".dot";
const NFA *sub = (const struct NFA *)((const char *)t + subOffset[i]);
FILE *f1 = fopen(ssdot.str().c_str(), "w");
nfaDumpDot(sub, f1, base);
fclose(f1);
}
}
void nfaExecTamarama_dumpText(const struct NFA *nfa, FILE *f) { FILE *f = fopen_or_throw((base + ".txt").c_str(), "w");
const Tamarama *t = (const Tamarama *)getImplNfa(nfa);
fprintf(f, "Tamarama container engine\n"); fprintf(f, "Tamarama container engine\n");
fprintf(f, "\n"); fprintf(f, "\n");
@ -75,15 +63,17 @@ void nfaExecTamarama_dumpText(const struct NFA *nfa, FILE *f) {
fprintf(f, "\n"); fprintf(f, "\n");
dumpTextReverse(nfa, f); dumpTextReverse(nfa, f);
fprintf(f, "\n"); fprintf(f, "\n");
fclose(f);
const u32 *subOffset = const u32 *subOffset =
(const u32 *)((const char *)t + sizeof(struct Tamarama) + (const u32 *)((const char *)t + sizeof(struct Tamarama) +
t->numSubEngines * sizeof(u32)); t->numSubEngines * sizeof(u32));
for (u32 i = 0; i < t->numSubEngines; i++) { for (u32 i = 0; i < t->numSubEngines; i++) {
fprintf(f, "Sub %u:\n", i);
const NFA *sub = (const struct NFA *)((const char *)t + subOffset[i]); const NFA *sub = (const struct NFA *)((const char *)t + subOffset[i]);
nfaDumpText(sub, f);
fprintf(f, "\n"); stringstream sssub;
sssub << base << "_sub_" << i;
nfaGenerateDumpFiles(sub, sssub.str());
} }
} }

View File

@ -31,16 +31,13 @@
#if defined(DUMP_SUPPORT) #if defined(DUMP_SUPPORT)
#include <cstdio>
#include <string> #include <string>
struct NFA; struct NFA;
namespace ue2 { namespace ue2 {
void nfaExecTamarama_dumpDot(const NFA *nfa, FILE *file, void nfaExecTamarama_dump(const NFA *nfa, const std::string &base);
const std::string &base);
void nfaExecTamarama_dumpText(const NFA *nfa, FILE *file);
} // namespace ue2 } // namespace ue2

View File

@ -917,24 +917,14 @@ void dumpNfas(const RoseEngine *t, bool dump_raw, const string &base) {
const NfaInfo *nfa_info = getNfaInfoByQueue(t, i); const NfaInfo *nfa_info = getNfaInfoByQueue(t, i);
const NFA *n = getNfaByInfo(t, nfa_info); const NFA *n = getNfaByInfo(t, nfa_info);
stringstream sstxt, ssdot, ssraw; stringstream ssbase;
ssbase << base << "rose_nfa_" << i;
sstxt << base << "rose_nfa_" << i << ".txt"; nfaGenerateDumpFiles(n, ssbase.str());
ssdot << base << "rose_nfa_" << i << ".dot";
ssraw << base << "rose_nfa_" << i << ".raw";
FILE *f;
f = fopen(ssdot.str().c_str(), "w");
nfaDumpDot(n, f, base);
fclose(f);
f = fopen(sstxt.str().c_str(), "w");
nfaDumpText(n, f);
fclose(f);
if (dump_raw) { if (dump_raw) {
f = fopen(ssraw.str().c_str(), "w"); stringstream ssraw;
ssraw << base << "rose_nfa_" << i << ".raw";
FILE *f = fopen(ssraw.str().c_str(), "w");
fwrite(n, 1, n->length, f); fwrite(n, 1, n->length, f);
fclose(f); fclose(f);
} }
@ -977,24 +967,14 @@ void dumpRevNfas(const RoseEngine *t, bool dump_raw, const string &base) {
for (u32 i = 0; i < t->somRevCount; i++) { for (u32 i = 0; i < t->somRevCount; i++) {
const NFA *n = (const NFA *)(tp + rev_offsets[i]); const NFA *n = (const NFA *)(tp + rev_offsets[i]);
stringstream sstxt, ssdot, ssraw; stringstream ssbase;
ssbase << base << "rose_nfa_" << i;
sstxt << base << "som_rev_nfa_" << i << ".txt"; nfaGenerateDumpFiles(n, ssbase.str());
ssdot << base << "som_rev_nfa_" << i << ".dot";
ssraw << base << "som_nfa_nfa_" << i << ".raw";
FILE *f;
f = fopen(ssdot.str().c_str(), "w");
nfaDumpDot(n, f, base);
fclose(f);
f = fopen(sstxt.str().c_str(), "w");
nfaDumpText(n, f);
fclose(f);
if (dump_raw) { if (dump_raw) {
f = fopen(ssraw.str().c_str(), "w"); stringstream ssraw;
ssraw << base << "som_rev_nfa_" << i << ".raw";
FILE *f = fopen(ssraw.str().c_str(), "w");
fwrite(n, 1, n->length, f); fwrite(n, 1, n->length, f);
fclose(f); fclose(f);
} }
@ -1009,20 +989,10 @@ void dumpAnchored(const RoseEngine *t, const string &base) {
while (curr) { while (curr) {
const NFA *n = (const NFA *)((const char *)curr + sizeof(*curr)); const NFA *n = (const NFA *)((const char *)curr + sizeof(*curr));
stringstream sstxt, ssdot;
sstxt << base << "anchored_" << i << ".txt"; stringstream ssbase;
ssdot << base << "anchored_" << i << ".dot"; ssbase << base << "anchored_" << i;
nfaGenerateDumpFiles(n, ssbase.str());
FILE *f;
f = fopen(ssdot.str().c_str(), "w");
nfaDumpDot(n, f, base);
fclose(f);
f = fopen(sstxt.str().c_str(), "w");
nfaDumpText(n, f);
fclose(f);
curr = curr->next_offset ? (const anchored_matcher_info *) curr = curr->next_offset ? (const anchored_matcher_info *)
((const char *)curr + curr->next_offset) : nullptr; ((const char *)curr + curr->next_offset) : nullptr;

View File

@ -70,18 +70,11 @@ void smwrDumpNFA(const SmallWriteEngine *smwr, bool dump_raw,
} }
const struct NFA *n = getSmwrNfa(smwr); const struct NFA *n = getSmwrNfa(smwr);
FILE *f;
f = fopen((base + "smallwrite_nfa.dot").c_str(), "w"); nfaGenerateDumpFiles(n, base + "smallwrite_nfa");
nfaDumpDot(n, f, base);
fclose(f);
f = fopen((base + "smallwrite_nfa.txt").c_str(), "w");
nfaDumpText(n, f);
fclose(f);
if (dump_raw) { if (dump_raw) {
f = fopen((base + "smallwrite_nfa.raw").c_str(), "w"); FILE *f = fopen((base + "smallwrite_nfa.raw").c_str(), "w");
fwrite(n, 1, n->length, f); fwrite(n, 1, n->length, f);
fclose(f); fclose(f);
} }

42
src/util/dump_util.cpp Normal file
View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "dump_util.h"
#include <stdexcept>
#include <string>
using namespace std;
FILE *fopen_or_throw(const char *path, const char *mode) {
FILE *f = fopen(path, mode);
if (!f) {
throw runtime_error(string("Unable to open file: ") + path);
}
return f;
}

39
src/util/dump_util.h Normal file
View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DUMP_UTIL
#define DUMP_UTIL
#include <cstdio>
/**
* Same as fopen(), but on error throws an exception rather than returning NULL.
*/
FILE *fopen_or_throw(const char *path, const char *mode);
#endif