From 32c826e9c6ab69586f386ee7b83887f52686f6e3 Mon Sep 17 00:00:00 2001 From: Alex Coyte Date: Wed, 2 Nov 2016 10:36:24 +1100 Subject: [PATCH] have single dump function per engine --- CMakeLists.txt | 2 + src/nfa/castle_dump.cpp | 15 +++++--- src/nfa/castle_dump.h | 4 +- src/nfa/goughdump.cpp | 31 +++++++++++++-- src/nfa/goughdump.h | 8 +--- src/nfa/lbr_dump.cpp | 57 ++++++++++++++-------------- src/nfa/lbr_dump.h | 21 +++-------- src/nfa/limex.h | 4 +- src/nfa/limex_dump.cpp | 40 +++++++++----------- src/nfa/mcclellandump.cpp | 31 +++++++++++++-- src/nfa/mcclellandump.h | 10 ++--- src/nfa/mpv_dump.cpp | 14 ++++--- src/nfa/mpv_dump.h | 5 +-- src/nfa/nfa_dump_api.h | 11 ++---- src/nfa/nfa_dump_dispatch.cpp | 9 +---- src/nfa/shengdump.cpp | 15 +++++++- src/nfa/shengdump.h | 5 +-- src/nfa/tamarama_dump.cpp | 30 +++++---------- src/nfa/tamarama_dump.h | 5 +-- src/rose/rose_dump.cpp | 60 ++++++++---------------------- src/smallwrite/smallwrite_dump.cpp | 11 +----- src/util/dump_util.cpp | 42 +++++++++++++++++++++ src/util/dump_util.h | 39 +++++++++++++++++++ 23 files changed, 262 insertions(+), 207 deletions(-) create mode 100644 src/util/dump_util.cpp create mode 100644 src/util/dump_util.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8def2baf..52d54955 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -986,6 +986,8 @@ set(hs_dump_SRCS src/rose/rose_dump.h src/util/dump_charclass.cpp src/util/dump_charclass.h + src/util/dump_util.cpp + src/util/dump_util.h ) if (DUMP_SUPPORT) diff --git a/src/nfa/castle_dump.cpp b/src/nfa/castle_dump.cpp index 6d51b2ce..9426b6db 100644 --- a/src/nfa/castle_dump.cpp +++ b/src/nfa/castle_dump.cpp @@ -40,18 +40,18 @@ #include "shufticompile.h" #include "trufflecompile.h" #include "util/charreach.h" +#include "util/dump_util.h" #include "util/dump_charclass.h" #ifndef DUMP_SUPPORT #error No dump support! #endif -namespace ue2 { +/* Note: No dot files for castle */ -void nfaExecCastle_dumpDot(const struct NFA *, FILE *, - UNUSED const std::string &base) { - // No GraphViz output for Castles. -} +using namespace std; + +namespace ue2 { static void dumpTextSubCastle(const SubCastle &sub, FILE *f) { @@ -68,9 +68,11 @@ void dumpTextSubCastle(const SubCastle &sub, FILE *f) { 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); + FILE *f = fopen_or_throw((base + ".txt").c_str(), "w"); + fprintf(f, "Castle multi-tenant repeat engine\n"); fprintf(f, "\n"); 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); dumpTextSubCastle(sub[i], f); } + fclose(f); } } // namespace ue2 diff --git a/src/nfa/castle_dump.h b/src/nfa/castle_dump.h index d5ec7d3d..06e7e36e 100644 --- a/src/nfa/castle_dump.h +++ b/src/nfa/castle_dump.h @@ -31,15 +31,13 @@ #if defined(DUMP_SUPPORT) -#include #include struct NFA; namespace ue2 { -void nfaExecCastle_dumpDot(const NFA *nfa, FILE *file, const std::string &base); -void nfaExecCastle_dumpText(const NFA *nfa, FILE *file); +void nfaExecCastle_dump(const NFA *nfa, const std::string &base); } // namespace ue2 diff --git a/src/nfa/goughdump.cpp b/src/nfa/goughdump.cpp index 4e6e5425..1b37a0b1 100644 --- a/src/nfa/goughdump.cpp +++ b/src/nfa/goughdump.cpp @@ -37,6 +37,7 @@ #include "ue2common.h" #include "util/charreach.h" #include "util/dump_charclass.h" +#include "util/dump_util.h" #include "util/unaligned.h" #include @@ -259,8 +260,8 @@ void dumpTransitions(const NFA *nfa, FILE *f, fprintf(f, "\n"); } -void nfaExecGough8_dumpDot(const struct NFA *nfa, FILE *f, - UNUSED const string &base) { +static +void nfaExecGough8_dumpDot(const struct NFA *nfa, FILE *f) { assert(nfa->type == GOUGH_NFA_8); const mcclellan *m = (const mcclellan *)getImplNfa(nfa); @@ -279,6 +280,7 @@ void nfaExecGough8_dumpDot(const struct NFA *nfa, FILE *f, fprintf(f, "}\n"); } +static void nfaExecGough8_dumpText(const struct NFA *nfa, FILE *f) { assert(nfa->type == GOUGH_NFA_8); @@ -303,8 +305,8 @@ void nfaExecGough8_dumpText(const struct NFA *nfa, FILE *f) { dumpTextReverse(nfa, f); } -void nfaExecGough16_dumpDot(const struct NFA *nfa, FILE *f, - UNUSED const string &base) { +static +void nfaExecGough16_dumpDot(const struct NFA *nfa, FILE *f) { assert(nfa->type == GOUGH_NFA_16); const mcclellan *m = (const mcclellan *)getImplNfa(nfa); @@ -323,6 +325,7 @@ void nfaExecGough16_dumpDot(const struct NFA *nfa, FILE *f, fprintf(f, "}\n"); } +static void nfaExecGough16_dumpText(const struct NFA *nfa, FILE *f) { assert(nfa->type == GOUGH_NFA_16); const mcclellan *m = (const mcclellan *)getImplNfa(nfa); @@ -348,4 +351,24 @@ void nfaExecGough16_dumpText(const struct NFA *nfa, FILE *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 diff --git a/src/nfa/goughdump.h b/src/nfa/goughdump.h index b96938e4..2d204d5a 100644 --- a/src/nfa/goughdump.h +++ b/src/nfa/goughdump.h @@ -39,12 +39,8 @@ struct NFA; namespace ue2 { -void nfaExecGough8_dumpDot(const NFA *nfa, FILE *file, - 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); +void nfaExecGough8_dump(const NFA *nfa, const std::string &base); +void nfaExecGough16_dump(const NFA *nfa, const std::string &base); } // namespace ue2 diff --git a/src/nfa/lbr_dump.cpp b/src/nfa/lbr_dump.cpp index 9619b8d6..92cf7e03 100644 --- a/src/nfa/lbr_dump.cpp +++ b/src/nfa/lbr_dump.cpp @@ -42,38 +42,17 @@ #include "trufflecompile.h" #include "util/charreach.h" #include "util/dump_charclass.h" +#include "util/dump_util.h" #ifndef DUMP_SUPPORT #error No dump support! #endif +/* Note: No dot files for LBR */ +using namespace std; + 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 void lbrDumpCommon(const lbr_common *lc, FILE *f) { const RepeatInfo *info @@ -88,39 +67,52 @@ void lbrDumpCommon(const lbr_common *lc, FILE *f) { 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->type == LBR_NFA_DOT); const lbr_dot *ld = (const lbr_dot *)getImplNfa(nfa); + FILE *f = fopen_or_throw((base + ".txt").c_str(), "w"); lbrDumpCommon(&ld->common, f); fprintf(f, "DOT model\n"); fprintf(f, "\n"); 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->type == LBR_NFA_VERM); const lbr_verm *lv = (const lbr_verm *)getImplNfa(nfa); + + FILE *f = fopen_or_throw((base + ".txt").c_str(), "w"); + lbrDumpCommon(&lv->common, f); fprintf(f, "VERM model, scanning for 0x%02x\n", lv->c); fprintf(f, "\n"); 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->type == LBR_NFA_NVERM); const lbr_verm *lv = (const lbr_verm *)getImplNfa(nfa); + + FILE *f = fopen_or_throw((base + ".txt").c_str(), "w"); + lbrDumpCommon(&lv->common, f); fprintf(f, "NEGATED VERM model, scanning for 0x%02x\n", lv->c); fprintf(f, "\n"); 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->type == LBR_NFA_SHUF); + + FILE *f = fopen_or_throw((base + ".txt").c_str(), "w"); + const lbr_shuf *ls = (const lbr_shuf *)getImplNfa(nfa); 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()); fprintf(f, "\n"); 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->type == LBR_NFA_TRUF); + + FILE *f = fopen_or_throw((base + ".txt").c_str(), "w"); + const lbr_truf *lt = (const lbr_truf *)getImplNfa(nfa); lbrDumpCommon(<->common, f); @@ -142,6 +138,7 @@ void nfaExecLbrTruf_dumpText(const NFA *nfa, FILE *f) { describeClass(cr, 20, CC_OUT_TEXT).c_str(), cr.count()); fprintf(f, "\n"); dumpTextReverse(nfa, f); + fclose(f); } } // namespace ue2 diff --git a/src/nfa/lbr_dump.h b/src/nfa/lbr_dump.h index 06ed51e2..ea4e3f38 100644 --- a/src/nfa/lbr_dump.h +++ b/src/nfa/lbr_dump.h @@ -31,28 +31,17 @@ #ifdef DUMP_SUPPORT -#include #include struct NFA; namespace ue2 { -void nfaExecLbrDot_dumpDot(const struct NFA *nfa, FILE *file, - const std::string &base); -void nfaExecLbrVerm_dumpDot(const struct NFA *nfa, FILE *file, - const std::string &base); -void nfaExecLbrNVerm_dumpDot(const struct NFA *nfa, FILE *file, - 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); +void nfaExecLbrDot_dump(const struct NFA *nfa, const std::string &base); +void nfaExecLbrVerm_dump(const struct NFA *nfa, const std::string &base); +void nfaExecLbrNVerm_dump(const struct NFA *nfa, const std::string &base); +void nfaExecLbrShuf_dump(const struct NFA *nfa, const std::string &base); +void nfaExecLbrTruf_dump(const struct NFA *nfa, const std::string &base); } // namespace ue2 diff --git a/src/nfa/limex.h b/src/nfa/limex.h index 70bcdd1c..0223604d 100644 --- a/src/nfa/limex.h +++ b/src/nfa/limex.h @@ -41,9 +41,7 @@ extern "C" #define GENERATE_NFA_DUMP_DECL(gf_name) \ } /* extern "C" */ \ namespace ue2 { \ - void gf_name##_dumpDot(const struct NFA *nfa, FILE *file, \ - const std::string &base); \ - void gf_name##_dumpText(const struct NFA *nfa, FILE *file); \ + void gf_name##_dump(const struct NFA *nfa, const std::string &base); \ } /* namespace ue2 */ \ extern "C" { diff --git a/src/nfa/limex_dump.cpp b/src/nfa/limex_dump.cpp index 149e8107..852639ea 100644 --- a/src/nfa/limex_dump.cpp +++ b/src/nfa/limex_dump.cpp @@ -35,9 +35,10 @@ #include "limex_internal.h" #include "nfa_dump_internal.h" #include "ue2common.h" +#include "util/charreach.h" #include "util/dump_charclass.h" #include "util/dump_mask.h" -#include "util/charreach.h" +#include "util/dump_util.h" #include #include @@ -472,37 +473,32 @@ void dumpLimDotInfo(const limex_type *limex, u32 state, FILE *f) { } } -#define DUMP_TEXT_FN(ddf_n) \ - void nfaExecLimEx##ddf_n##_dumpText(const NFA *nfa, FILE *f) { \ - dumpLimexText((const LimExNFA##ddf_n *)getImplNfa(nfa), f); \ - } - -#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); \ +#define LIMEX_DUMP_FN(size) \ + void nfaExecLimEx##size##_dump(const NFA *nfa, const string &base) { \ + auto limex = (const LimExNFA##size *)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); \ u32 state_count = nfa->nPositions; \ dumpVertexDotInfo(limex, state_count, f, \ - limex_labeller(limex)); \ + limex_labeller(limex)); \ for (u32 i = 0; i < state_count; i++) { \ dumpLimDotInfo(limex, i, f); \ dumpExDotInfo(limex, i, f); \ } \ dumpDotTrailer(f); \ + fclose(f); \ } -#define LIMEX_DUMP_FNS(size) \ - DUMP_TEXT_FN(size) \ - DUMP_DOT_FN(size) - -LIMEX_DUMP_FNS(32) -LIMEX_DUMP_FNS(64) -LIMEX_DUMP_FNS(128) -LIMEX_DUMP_FNS(256) -LIMEX_DUMP_FNS(384) -LIMEX_DUMP_FNS(512) +LIMEX_DUMP_FN(32) +LIMEX_DUMP_FN(64) +LIMEX_DUMP_FN(128) +LIMEX_DUMP_FN(256) +LIMEX_DUMP_FN(384) +LIMEX_DUMP_FN(512) } // namespace ue2 diff --git a/src/nfa/mcclellandump.cpp b/src/nfa/mcclellandump.cpp index dcbb0915..9e04ad63 100644 --- a/src/nfa/mcclellandump.cpp +++ b/src/nfa/mcclellandump.cpp @@ -39,6 +39,7 @@ #include "ue2common.h" #include "util/charreach.h" #include "util/dump_charclass.h" +#include "util/dump_util.h" #include "util/unaligned.h" #include @@ -267,8 +268,8 @@ void dumpDotPreambleDfa(FILE *f) { fprintf(f, "0 [style=invis];\n"); } -void nfaExecMcClellan16_dumpDot(const NFA *nfa, FILE *f, - UNUSED const string &base) { +static +void nfaExecMcClellan16_dumpDot(const NFA *nfa, FILE *f) { assert(nfa->type == MCCLELLAN_NFA_16); const mcclellan *m = (const mcclellan *)getImplNfa(nfa); @@ -287,8 +288,8 @@ void nfaExecMcClellan16_dumpDot(const NFA *nfa, FILE *f, fprintf(f, "}\n"); } -void nfaExecMcClellan8_dumpDot(const NFA *nfa, FILE *f, - UNUSED const string &base) { +static +void nfaExecMcClellan8_dumpDot(const NFA *nfa, FILE *f) { assert(nfa->type == MCCLELLAN_NFA_8); 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) { assert(nfa->type == MCCLELLAN_NFA_16); const mcclellan *m = (const mcclellan *)getImplNfa(nfa); @@ -417,6 +419,7 @@ void nfaExecMcClellan16_dumpText(const NFA *nfa, FILE *f) { dumpTextReverse(nfa, f); } +static void nfaExecMcClellan8_dumpText(const NFA *nfa, FILE *f) { assert(nfa->type == MCCLELLAN_NFA_8); const mcclellan *m = (const mcclellan *)getImplNfa(nfa); @@ -437,4 +440,24 @@ void nfaExecMcClellan8_dumpText(const NFA *nfa, FILE *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 diff --git a/src/nfa/mcclellandump.h b/src/nfa/mcclellandump.h index efa61544..5b63a206 100644 --- a/src/nfa/mcclellandump.h +++ b/src/nfa/mcclellandump.h @@ -43,14 +43,10 @@ union AccelAux; namespace ue2 { -void nfaExecMcClellan8_dumpDot(const struct NFA *nfa, FILE *file, - 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); +void nfaExecMcClellan8_dump(const struct NFA *nfa, const std::string &base); +void nfaExecMcClellan16_dump(const struct NFA *nfa, const std::string &base); -/* 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); void describeEdge(FILE *f, const u16 *t, u16 i); diff --git a/src/nfa/mpv_dump.cpp b/src/nfa/mpv_dump.cpp index e91d378f..9a8a4067 100644 --- a/src/nfa/mpv_dump.cpp +++ b/src/nfa/mpv_dump.cpp @@ -36,6 +36,7 @@ #include "ue2common.h" #include "util/compare.h" #include "util/dump_mask.h" +#include "util/dump_util.h" #include #include @@ -46,11 +47,11 @@ #error No dump support! #endif -namespace ue2 { +/* Note: No dot files for MPV */ -void nfaExecMpv_dumpDot(UNUSED const NFA *nfa, UNUSED FILE *file, - UNUSED const std::string &base) { -} +using namespace std; + +namespace ue2 { static really_inline 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"); } -void nfaExecMpv_dumpText(const NFA *nfa, FILE *f) { +void nfaExecMpv_dump(const NFA *nfa, const string &base) { 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, "\n"); 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); + fclose(f); } } // namespace ue2 diff --git a/src/nfa/mpv_dump.h b/src/nfa/mpv_dump.h index b44d2b74..e587619e 100644 --- a/src/nfa/mpv_dump.h +++ b/src/nfa/mpv_dump.h @@ -31,16 +31,13 @@ #if defined(DUMP_SUPPORT) -#include #include struct NFA; namespace ue2 { -void nfaExecMpv_dumpDot(const struct NFA *nfa, FILE *file, - const std::string &base); -void nfaExecMpv_dumpText(const struct NFA *nfa, FILE *file); +void nfaExecMpv_dump(const struct NFA *nfa, const std::string &base); } // namespace ue2 diff --git a/src/nfa/nfa_dump_api.h b/src/nfa/nfa_dump_api.h index 1054a204..a0c4a9c9 100644 --- a/src/nfa/nfa_dump_api.h +++ b/src/nfa/nfa_dump_api.h @@ -35,7 +35,6 @@ #if defined(DUMP_SUPPORT) -#include #include struct NFA; @@ -43,13 +42,11 @@ struct NFA; namespace ue2 { /** - * \brief Dump (in Graphviz 'dot' format) a representation of the NFA into the - * file pointed to by dotFile. + * \brief Dump files representing the engine. All files dumped should begin with + * 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); - -/** \brief Dump a textual representation of the NFA. */ -void nfaDumpText(const struct NFA *fact, FILE *textFile); +void nfaGenerateDumpFiles(const struct NFA *nfa, const std::string &base); } // namespace ue2 diff --git a/src/nfa/nfa_dump_dispatch.cpp b/src/nfa/nfa_dump_dispatch.cpp index 84190232..3dea5ef7 100644 --- a/src/nfa/nfa_dump_dispatch.cpp +++ b/src/nfa/nfa_dump_dispatch.cpp @@ -82,13 +82,8 @@ namespace ue2 { assert(0); \ } -void nfaDumpDot(const struct NFA *nfa, FILE *dotFile, - const std::string &base) { - DISPATCH_BY_NFA_TYPE(_dumpDot(nfa, dotFile, base)); -} - -void nfaDumpText(const struct NFA *nfa, FILE *txtFile) { - DISPATCH_BY_NFA_TYPE(_dumpText(nfa, txtFile)); +void nfaGenerateDumpFiles(const struct NFA *nfa, const std::string &base) { + DISPATCH_BY_NFA_TYPE(_dump(nfa, base)); } } // namespace ue2 diff --git a/src/nfa/shengdump.cpp b/src/nfa/shengdump.cpp index a7e7fc2b..c2371601 100644 --- a/src/nfa/shengdump.cpp +++ b/src/nfa/shengdump.cpp @@ -38,6 +38,7 @@ #include "ue2common.h" #include "util/charreach.h" #include "util/dump_charclass.h" +#include "util/dump_util.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) { assert(nfa->type == SHENG_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; } -void nfaExecSheng_dumpDot(const NFA *nfa, FILE *f, const string &) { +static +void nfaExecSheng_dumpDot(const NFA *nfa, FILE *f) { assert(nfa->type == SHENG_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"); } +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 diff --git a/src/nfa/shengdump.h b/src/nfa/shengdump.h index 008d2aba..2bdffeb9 100644 --- a/src/nfa/shengdump.h +++ b/src/nfa/shengdump.h @@ -31,16 +31,13 @@ #ifdef DUMP_SUPPORT -#include #include struct NFA; namespace ue2 { -void nfaExecSheng_dumpDot(const struct NFA *nfa, FILE *file, - const std::string &base); -void nfaExecSheng_dumpText(const struct NFA *nfa, FILE *file); +void nfaExecSheng_dump(const struct NFA *nfa, const std::string &base); } // namespace ue2 diff --git a/src/nfa/tamarama_dump.cpp b/src/nfa/tamarama_dump.cpp index f03b842c..88cb33cc 100644 --- a/src/nfa/tamarama_dump.cpp +++ b/src/nfa/tamarama_dump.cpp @@ -38,6 +38,7 @@ #include "nfa_dump_api.h" #include "nfa_dump_internal.h" #include "nfa_internal.h" +#include "util/dump_util.h" #include #include @@ -46,27 +47,14 @@ #error No dump support! #endif +using namespace std; + namespace ue2 { -void nfaExecTamarama_dumpDot(const struct NFA *nfa, UNUSED FILE *f, - const std::string &base) { +void nfaExecTamarama_dump(const struct NFA *nfa, const string &base) { 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) { - const Tamarama *t = (const Tamarama *)getImplNfa(nfa); + FILE *f = fopen_or_throw((base + ".txt").c_str(), "w"); fprintf(f, "Tamarama container engine\n"); fprintf(f, "\n"); @@ -75,15 +63,17 @@ void nfaExecTamarama_dumpText(const struct NFA *nfa, FILE *f) { fprintf(f, "\n"); dumpTextReverse(nfa, f); fprintf(f, "\n"); + fclose(f); const u32 *subOffset = (const u32 *)((const char *)t + sizeof(struct Tamarama) + t->numSubEngines * sizeof(u32)); 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]); - nfaDumpText(sub, f); - fprintf(f, "\n"); + + stringstream sssub; + sssub << base << "_sub_" << i; + nfaGenerateDumpFiles(sub, sssub.str()); } } diff --git a/src/nfa/tamarama_dump.h b/src/nfa/tamarama_dump.h index 6e3f80ca..f40b7ecf 100644 --- a/src/nfa/tamarama_dump.h +++ b/src/nfa/tamarama_dump.h @@ -31,16 +31,13 @@ #if defined(DUMP_SUPPORT) -#include #include struct NFA; namespace ue2 { -void nfaExecTamarama_dumpDot(const NFA *nfa, FILE *file, - const std::string &base); -void nfaExecTamarama_dumpText(const NFA *nfa, FILE *file); +void nfaExecTamarama_dump(const NFA *nfa, const std::string &base); } // namespace ue2 diff --git a/src/rose/rose_dump.cpp b/src/rose/rose_dump.cpp index 36156a42..c0272348 100644 --- a/src/rose/rose_dump.cpp +++ b/src/rose/rose_dump.cpp @@ -917,24 +917,14 @@ void dumpNfas(const RoseEngine *t, bool dump_raw, const string &base) { const NfaInfo *nfa_info = getNfaInfoByQueue(t, i); const NFA *n = getNfaByInfo(t, nfa_info); - stringstream sstxt, ssdot, ssraw; - - sstxt << base << "rose_nfa_" << i << ".txt"; - 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); + stringstream ssbase; + ssbase << base << "rose_nfa_" << i; + nfaGenerateDumpFiles(n, ssbase.str()); 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); 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++) { const NFA *n = (const NFA *)(tp + rev_offsets[i]); - stringstream sstxt, ssdot, ssraw; - - sstxt << base << "som_rev_nfa_" << i << ".txt"; - 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); + stringstream ssbase; + ssbase << base << "rose_nfa_" << i; + nfaGenerateDumpFiles(n, ssbase.str()); 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); fclose(f); } @@ -1009,20 +989,10 @@ void dumpAnchored(const RoseEngine *t, const string &base) { while (curr) { const NFA *n = (const NFA *)((const char *)curr + sizeof(*curr)); - stringstream sstxt, ssdot; - sstxt << base << "anchored_" << i << ".txt"; - ssdot << base << "anchored_" << i << ".dot"; - - 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); + stringstream ssbase; + ssbase << base << "anchored_" << i; + nfaGenerateDumpFiles(n, ssbase.str()); curr = curr->next_offset ? (const anchored_matcher_info *) ((const char *)curr + curr->next_offset) : nullptr; diff --git a/src/smallwrite/smallwrite_dump.cpp b/src/smallwrite/smallwrite_dump.cpp index 0db97df5..bdf55c30 100644 --- a/src/smallwrite/smallwrite_dump.cpp +++ b/src/smallwrite/smallwrite_dump.cpp @@ -70,18 +70,11 @@ void smwrDumpNFA(const SmallWriteEngine *smwr, bool dump_raw, } const struct NFA *n = getSmwrNfa(smwr); - FILE *f; - f = fopen((base + "smallwrite_nfa.dot").c_str(), "w"); - nfaDumpDot(n, f, base); - fclose(f); - - f = fopen((base + "smallwrite_nfa.txt").c_str(), "w"); - nfaDumpText(n, f); - fclose(f); + nfaGenerateDumpFiles(n, base + "smallwrite_nfa"); 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); fclose(f); } diff --git a/src/util/dump_util.cpp b/src/util/dump_util.cpp new file mode 100644 index 00000000..5b961367 --- /dev/null +++ b/src/util/dump_util.cpp @@ -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 +#include + +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; +} diff --git a/src/util/dump_util.h b/src/util/dump_util.h new file mode 100644 index 00000000..487d2e7c --- /dev/null +++ b/src/util/dump_util.h @@ -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 + +/** + * Same as fopen(), but on error throws an exception rather than returning NULL. + */ +FILE *fopen_or_throw(const char *path, const char *mode); + +#endif