]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
Windows porting: port hyperscan and chimera tools to windows.
authorLu, Qi <qi1.lu@intel.com>
Tue, 8 May 2018 16:05:44 +0000 (12:05 -0400)
committerWang, Xiang W <xiang.w.wang@intel.com>
Mon, 9 Jul 2018 15:40:43 +0000 (11:40 -0400)
34 files changed:
CMakeLists.txt
chimera/ch_runtime.c
chimera/ch_runtime.h
src/hs_runtime.h
src/rose/rose_build_merge.cpp
src/runtime.c
src/scratch.h
src/ue2common.h
src/util/bitfield.h
src/util/dump_charclass.cpp
src/util/multibit.h
src/util/multibit_build.cpp
src/util/multibit_build.h
tools/CMakeLists.txt
tools/hsbench/CMakeLists.txt
tools/hsbench/engine_chimera.cpp
tools/hsbench/engine_hyperscan.cpp
tools/hsbench/engine_pcre.cpp
tools/hsbench/main.cpp
tools/hscheck/CMakeLists.txt
tools/hscheck/main.cpp
tools/hscollider/CMakeLists.txt
tools/hscollider/GroundTruth.cpp
tools/hscollider/Thread.cpp
tools/hscollider/Thread.h
tools/hscollider/UltimateTruth.cpp
tools/hscollider/args.cpp
tools/hscollider/main.cpp
tools/hscollider/sig.cpp
tools/hscollider/sig.h
tools/hsdump/CMakeLists.txt
tools/hsdump/main.cpp
unit/CMakeLists.txt
util/win_getopt.h [new file with mode: 0644]

index 3a8cef0bfb98eb206b64152bf5a8f4ebc85906e2..9a452561aad0c3139cfdca3d48bffafd7a6787a3 100644 (file)
@@ -70,16 +70,6 @@ include_directories(SYSTEM include)
 
 include (${CMAKE_MODULE_PATH}/boost.cmake)
 
-# PCRE check, we have a fixed requirement for PCRE to use Chimera
-# and hscollider
-set(PCRE_REQUIRED_MAJOR_VERSION 8)
-set(PCRE_REQUIRED_MINOR_VERSION 41)
-set(PCRE_REQUIRED_VERSION ${PCRE_REQUIRED_MAJOR_VERSION}.${PCRE_REQUIRED_MINOR_VERSION})
-include (${CMAKE_MODULE_PATH}/pcre.cmake)
-if (NOT CORRECT_PCRE_VERSION)
-    message(STATUS "PCRE ${PCRE_REQUIRED_VERSION} not found")
-endif()
-
 # -- make this work? set(python_ADDITIONAL_VERSIONS 2.7 2.6)
 find_package(PythonInterp)
 find_program(RAGEL ragel)
@@ -455,20 +445,33 @@ else()
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
 endif()
 
+add_subdirectory(util)
+add_subdirectory(doc/dev-reference)
+
+if (NOT WIN32)
+# PCRE check, we have a fixed requirement for PCRE to use Chimera
+# and hscollider
+set(PCRE_REQUIRED_MAJOR_VERSION 8)
+set(PCRE_REQUIRED_MINOR_VERSION 41)
+set(PCRE_REQUIRED_VERSION ${PCRE_REQUIRED_MAJOR_VERSION}.${PCRE_REQUIRED_MINOR_VERSION})
+include (${CMAKE_MODULE_PATH}/pcre.cmake)
+if (NOT CORRECT_PCRE_VERSION)
+    message(STATUS "PCRE ${PCRE_REQUIRED_VERSION} not found")
+endif()
+
 # we need static libs for Chimera - too much deep magic for shared libs
 if (CORRECT_PCRE_VERSION AND BUILD_STATIC_LIBS)
     set(BUILD_CHIMERA TRUE)
 endif()
 
-add_subdirectory(util)
 add_subdirectory(unit)
-add_subdirectory(doc/dev-reference)
 if (EXISTS ${CMAKE_SOURCE_DIR}/tools/CMakeLists.txt)
     add_subdirectory(tools)
 endif()
 if (EXISTS ${CMAKE_SOURCE_DIR}/chimera/CMakeLists.txt AND BUILD_CHIMERA)
     add_subdirectory(chimera)
 endif()
+endif()
 
 # do substitutions
 configure_file(${CMAKE_MODULE_PATH}/config.h.in ${PROJECT_BINARY_DIR}/config.h)
@@ -497,6 +500,31 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS}")
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXX_FLAGS}")
 endif()
 
+if (WIN32)
+# PCRE check, we have a fixed requirement for PCRE to use Chimera
+# and hscollider
+set(PCRE_REQUIRED_MAJOR_VERSION 8)
+set(PCRE_REQUIRED_MINOR_VERSION 41)
+set(PCRE_REQUIRED_VERSION ${PCRE_REQUIRED_MAJOR_VERSION}.${PCRE_REQUIRED_MINOR_VERSION})
+include (${CMAKE_MODULE_PATH}/pcre.cmake)
+if (NOT CORRECT_PCRE_VERSION)
+    message(STATUS "PCRE ${PCRE_REQUIRED_VERSION} not found")
+endif()
+
+# we need static libs for Chimera - too much deep magic for shared libs
+if (CORRECT_PCRE_VERSION AND BUILD_STATIC_LIBS)
+    set(BUILD_CHIMERA TRUE)
+endif()
+
+add_subdirectory(unit)
+if (EXISTS ${CMAKE_SOURCE_DIR}/tools/CMakeLists.txt)
+    add_subdirectory(tools)
+endif()
+if (EXISTS ${CMAKE_SOURCE_DIR}/chimera/CMakeLists.txt AND BUILD_CHIMERA)
+    add_subdirectory(chimera)
+endif()
+endif()
+
 if(NOT WIN32)
 set(RAGEL_C_FLAGS "-Wno-unused")
 endif()
index 4685192be6cf77bdb58bbdb45dfc057fb59f5aa4..212bbc7bec371bff23196908e737f47472e75577 100644 (file)
@@ -92,7 +92,7 @@ void pq_pop_nice(struct match_pq *pq) {
 
 /** dummy event handler for use when user does not provide one */
 static
-int null_onEvent(UNUSED unsigned id, UNUSED unsigned long long from,
+int HS_CDECL null_onEvent(UNUSED unsigned id, UNUSED unsigned long long from,
                  UNUSED unsigned long long to, UNUSED unsigned flags,
                  UNUSED unsigned size, UNUSED const ch_capture_t *captured,
                  UNUSED void *ctxt) {
@@ -108,12 +108,12 @@ struct HybridContext {
     struct ch_scratch *scratch;
     struct match_pq *pq;
     /** \brief user-supplied match callback */
-    int (*match_callback)(unsigned int id, unsigned long long from,
+    int (HS_CDECL *match_callback)(unsigned int id, unsigned long long from,
                           unsigned long long to, unsigned int flags,
                           unsigned int size, const ch_capture_t *capture,
                           void *ctx);
     /** \brief user-supplied error callback */
-    int (*error_callback)(ch_error_event_t error_type, unsigned int id,
+    int (HS_CDECL *error_callback)(ch_error_event_t error_type, unsigned int id,
                           void *info, void *ctx);
     /** \brief user-supplied context */
     void *context;
@@ -363,7 +363,7 @@ ch_error_t catchupPcre(struct HybridContext *hyctx, unsigned int id,
 
 /** \brief Callback used for internal Hyperscan multi-matcher. */
 static
-int multiCallback(unsigned int id, unsigned long long from,
+int HS_CDECL multiCallback(unsigned int id, unsigned long long from,
                   unsigned long long to, UNUSED unsigned int flags,
                   void *ctx) {
     assert(ctx);
index 79593f1d43d406882eea48625f11f59a49e8aab7..6aefcad1b06a43648e19ab63cf1caf652e826295 100644 (file)
@@ -201,7 +201,7 @@ typedef struct ch_capture {
  *      pattern, while a return value of @ref CH_CALLBACK_SKIP_PATTERN will
  *      cease matching this pattern but continue matching the next pattern.
  */
-typedef ch_callback_t (*ch_match_event_handler)(unsigned int id,
+typedef ch_callback_t (HS_CDECL *ch_match_event_handler)(unsigned int id,
                                                 unsigned long long from,
                                                 unsigned long long to,
                                                 unsigned int flags,
@@ -233,11 +233,12 @@ typedef ch_callback_t (*ch_match_event_handler)(unsigned int id,
  *      function.
  *
  * @return
- *      The callback can return @ref CH_CALLBACK_SKIP_PATTERN to cease matching this
- *      pattern but continue matching the next pattern. Otherwise, we stop
+ *      The callback can return @ref CH_CALLBACK_SKIP_PATTERN to cease matching
+ *      this pattern but continue matching the next pattern. Otherwise, we stop
  *      matching for all patterns with @ref CH_CALLBACK_TERMINATE.
  */
- typedef ch_callback_t (*ch_error_event_handler)(ch_error_event_t error_type,
+ typedef ch_callback_t (HS_CDECL *ch_error_event_handler)(
+                                                 ch_error_event_t error_type,
                                                  unsigned int id, void *info,
                                                  void *ctx);
 
index 9bf6748668adb8645d0384b7289b9dfd38fcedf1..6d34b6c4847a7dd9eba9c27b6770e3606d2b27a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, Intel Corporation
+ * Copyright (c) 2015-2018, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -122,11 +122,11 @@ typedef struct hs_scratch hs_scratch_t;
  *      subsequent calls to @ref hs_scan_stream() for that stream will
  *      immediately return with @ref HS_SCAN_TERMINATED.
  */
-typedef int (*match_event_handler)(unsigned int id,
-                                   unsigned long long from,
-                                   unsigned long long to,
-                                   unsigned int flags,
-                                   void *context);
+typedef int (HS_CDECL *match_event_handler)(unsigned int id,
+                                            unsigned long long from,
+                                            unsigned long long to,
+                                            unsigned int flags,
+                                            void *context);
 
 /**
  * Open and initialise a stream.
index cc450a89a3006aea4f7e0347d71201b365603268..5066dbd57814e6b007e49af8ee8061cbbeec431c 100644 (file)
@@ -1437,7 +1437,19 @@ void mergeLeftfixesVariableLag(RoseBuildImpl &build) {
 
         assert(!parents.empty());
 
+#ifndef _WIN32
         engine_groups[MergeKey(left, parents)].push_back(left);
+#else
+        // On windows, when passing MergeKey object into map 'engine_groups',
+        // it will not be copied, but will be freed along with
+        // engine_groups.clear().
+        // If we construct MergeKey object on the stack, it will be destructed
+        // on its life cycle ending, then on engine_groups.clear(), which
+        // will cause is_block_type_valid() assertion error in MergeKey
+        // destructor.
+        MergeKey *mk = new MergeKey(left, parents);
+        engine_groups[*mk].push_back(left);
+#endif
     }
 
     vector<vector<left_id>> chunks;
index df276551e22ea27ebee76a2fea7669345d59d9ff..052449f61f460db5e055b06d7f1cba7342f1b901 100644 (file)
@@ -67,9 +67,9 @@ void prefetch_data(const char *data, unsigned length) {
 
 /** dummy event handler for use when user does not provide one */
 static
-int null_onEvent(UNUSED unsigned id, UNUSED unsigned long long from,
-                 UNUSED unsigned long long to, UNUSED unsigned flags,
-                 UNUSED void *ctxt) {
+int HS_CDECL null_onEvent(UNUSED unsigned id, UNUSED unsigned long long from,
+                          UNUSED unsigned long long to, UNUSED unsigned flags,
+                          UNUSED void *ctxt) {
     return 0;
 }
 
index 0653b7437f112c399e46ede05cc7a2ff920e844b..59aa02c69fc49520b12979ff74d6ef92e8b1c74c 100644 (file)
@@ -36,6 +36,7 @@
 #ifndef SCRATCH_H_DA6D4FC06FF410
 #define SCRATCH_H_DA6D4FC06FF410
 
+#include "hs_common.h"
 #include "ue2common.h"
 #include "rose/rose_types.h"
 
@@ -88,8 +89,9 @@ struct core_info {
     void *userContext; /**< user-supplied context */
 
     /** \brief user-supplied match callback */
-    int (*userCallback)(unsigned int id, unsigned long long from,
-                        unsigned long long to, unsigned int flags, void *ctx);
+    int (HS_CDECL *userCallback)(unsigned int id, unsigned long long from,
+                                 unsigned long long to, unsigned int flags,
+                                 void *ctx);
 
     const struct RoseEngine *rose;
     char *state; /**< full stream state */
index 4bec83155197434350593c89d1d687a202ca8223..5705af7be438f2df59856b299b148187da57cd33 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, Intel Corporation
+ * Copyright (c) 2015-2018, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -66,8 +66,13 @@ typedef signed int s32;
 /* We append the 'a' for aligned, since these aren't common, garden variety
  * 64 bit values. The alignment is necessary for structs on some platforms,
  * so we don't end up performing accidental unaligned accesses. */
+#if defined(_WIN32) && ! defined(_WIN64)
+typedef unsigned long long ALIGN_ATTR(4) u64a;
+typedef signed long long ALIGN_ATTR(4) s64a;
+#else
 typedef unsigned long long ALIGN_ATTR(8) u64a;
 typedef signed long long ALIGN_ATTR(8) s64a;
+#endif
 
 /* get the SIMD types */
 #include "util/simd_types.h"
index 24c0c5804f72d48c772ffd505d535cf51a0e4962..a580da7b608f43424905dd7e0dd1ed9ff786a7ab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, Intel Corporation
+ * Copyright (c) 2015-2018, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -305,9 +305,10 @@ public:
     }
 
     /// Bitwise OR.
-    bitfield operator|(bitfield a) const {
-        a |= *this;
-        return a;
+    bitfield operator|(const bitfield &a) const {
+        bitfield b = a;
+        b |= *this;
+        return b;
     }
 
     /// Bitwise OR-equals.
@@ -325,9 +326,10 @@ public:
     }
 
     /// Bitwise AND.
-    bitfield operator&(bitfield a) const {
-        a &= *this;
-        return a;
+    bitfield operator&(const bitfield &a) const {
+        bitfield b = a;
+        b &= *this;
+        return b;
     }
 
     /// Bitwise AND-equals.
index 4535777d14706497da05cf05915c7771f110fd00..d0659a8bde8cd0a587ce0ba7ef37b22b2d734fa7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, Intel Corporation
+ * Copyright (c) 2015-2018, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -56,7 +56,11 @@ void describeChar(ostream &os, char c, enum cc_output_t out_type) {
 
     const string backslash((out_type == CC_OUT_DOT ? 2 : 1), '\\');
 
+#ifdef _WIN32
+    if (c >= 0x21 && c < 0x7F && c != '\\') {
+#else
     if (isgraph(c) && c != '\\') {
+#endif
         if (escaped.find(c) != string::npos) {
             os << backslash << c;
         } else if (out_type == CC_OUT_DOT
index 4df8733aeab87dfd976a5da407539de673b9ef64..c3a4ba461aecbaa8f3079df45e3294691700fccc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, Intel Corporation
+ * Copyright (c) 2015-2018, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -1197,7 +1197,11 @@ u32 mmbit_sparse_iter_begin(const u8 *bits, u32 total_bits, u32 *idx,
     assert(ISALIGNED_N(it_root, alignof(struct mmbit_sparse_iter)));
 
     // Our state _may_ be on the stack
+#ifndef _WIN32
     assert(ISALIGNED_N(s, alignof(struct mmbit_sparse_state)));
+#else
+    assert(ISALIGNED_N(s, 4));
+#endif
 
     MDEBUG_PRINTF("%p total_bits %u\n", bits, total_bits);
     // iterator should have _something_ at the root level
@@ -1305,7 +1309,11 @@ u32 mmbit_sparse_iter_next(const u8 *bits, u32 total_bits, u32 last_key,
     assert(ISALIGNED_N(it_root, alignof(struct mmbit_sparse_iter)));
 
     // Our state _may_ be on the stack
+#ifndef _WIN32
     assert(ISALIGNED_N(s, alignof(struct mmbit_sparse_state)));
+#else
+    assert(ISALIGNED_N(s, 4));
+#endif
 
     MDEBUG_PRINTF("%p total_bits %u\n", bits, total_bits);
     MDEBUG_PRINTF("NEXT (total_bits=%u, last_key=%u)\n", total_bits, last_key);
@@ -1458,7 +1466,11 @@ void mmbit_sparse_iter_unset(u8 *bits, u32 total_bits,
     assert(ISALIGNED_N(it, alignof(struct mmbit_sparse_iter)));
 
     // Our state _may_ be on the stack
+#ifndef _WIN32
     assert(ISALIGNED_N(s, alignof(struct mmbit_sparse_state)));
+#else
+    assert(ISALIGNED_N(s, 4));
+#endif
 
     MDEBUG_PRINTF("%p total_bits %u\n", bits, total_bits);
 
index fd7b4e80e62b1d96c6012667cbe2034715378624..ad6a0d6a69b541b5732b55a6a758392538bdebeb 100644 (file)
@@ -46,7 +46,7 @@ using namespace std;
 
 namespace ue2 {
 
-u32 HS_CDECL mmbit_size(u32 total_bits) {
+u32 mmbit_size(u32 total_bits) {
     if (total_bits > MMB_MAX_BITS) {
         throw ResourceLimitError();
     }
index 60c07995ba101d71db8c1b6d433f70350883bb14..24f1bb55b061ccbeb98cfcadf33537eae1590173 100644 (file)
@@ -63,10 +63,8 @@ namespace ue2 {
  *
  * This will throw a resource limit assertion if the requested mmbit is too
  * large.
- *
- * TODO:add temporary HS_CDECL for chimera on Windows, need improve this.
  */
-u32 HS_CDECL mmbit_size(u32 total_bits);
+u32 mmbit_size(u32 total_bits);
 
 /** \brief Construct a sparse iterator over the values in \a bits for a
  * multibit of size \a total_bits. */
index 61bb00f20f0e3c758b786ce796fe545516bf8631..6ca3fd8a91768f08ef2f4e2bee87c4bbc6dcfcc8 100644 (file)
@@ -1,6 +1,3 @@
-if (WIN32)
-    return()
-endif()
 find_package(Threads)
 
 # remove some warnings
@@ -12,11 +9,18 @@ include_directories(${PROJECT_SOURCE_DIR})
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src)
 include_directories(${PROJECT_SOURCE_DIR}/util)
 
-# add any subdir with a cmake file
-file(GLOB dirents RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *)
-foreach(e ${dirents})
-    if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${e} AND
-       EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${e}/CMakeLists.txt)
-        add_subdirectory(${e})
-    endif ()
-endforeach ()
+if (WIN32)
+    add_subdirectory(hscheck)
+    add_subdirectory(hsbench)
+    add_subdirectory(hsdump)
+    add_subdirectory(hscollider)
+else()
+    # add any subdir with a cmake file
+    file(GLOB dirents RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *)
+    foreach(e ${dirents})
+        if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${e} AND
+           EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${e}/CMakeLists.txt)
+            add_subdirectory(${e})
+        endif ()
+    endforeach ()
+endif()
index c580a7b9c85df7f898237117d83c05a1c8056488..465081a8b295e0c6003dd41383fc168ed80ec9e5 100644 (file)
@@ -61,8 +61,13 @@ endif()
 add_executable(hsbench ${hsbench_SOURCES})
 if (BUILD_CHIMERA)
     include_directories(${PCRE_INCLUDE_DIRS})
-    target_link_libraries(hsbench hs chimera ${PCRE_LDFLAGS} databaseutil
-        expressionutil ${SQLITE3_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT})
+    if(NOT WIN32)
+        target_link_libraries(hsbench hs chimera ${PCRE_LDFLAGS} databaseutil
+            expressionutil ${SQLITE3_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT})
+    else()
+        target_link_libraries(hsbench hs chimera pcre databaseutil
+            expressionutil ${SQLITE3_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT})
+    endif()
 else()
     target_link_libraries(hsbench hs databaseutil expressionutil
         ${SQLITE3_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT})
index 16374f36c1d1a5fd50ef1808e0f06b34768a3636..8a15c5bee2480442a1d14d0c2496e1c06cbbbadc 100644 (file)
@@ -68,8 +68,9 @@ struct ScanCHContext {
  * "echo matches" is off.
  */
 static
-int onMatch(unsigned int, unsigned long long, unsigned long long, unsigned int,
-            unsigned int, const ch_capture_t *, void *ctx) {
+int HS_CDECL onMatch(unsigned int, unsigned long long, unsigned long long,
+                     unsigned int, unsigned int, const ch_capture_t *,
+                     void *ctx) {
     ScanCHContext *sc = static_cast<ScanCHContext *>(ctx);
     assert(sc);
     sc->result.matches++;
@@ -82,8 +83,9 @@ int onMatch(unsigned int, unsigned long long, unsigned long long, unsigned int,
  * matches" is enabled.
  */
 static
-int onMatchEcho(unsigned int id, unsigned long long, unsigned long long to,
-                unsigned int, unsigned int, const ch_capture_t *, void *ctx) {
+int HS_CDECL onMatchEcho(unsigned int id, unsigned long long,
+                         unsigned long long to, unsigned int, unsigned int,
+                         const ch_capture_t *, void *ctx) {
     ScanCHContext *sc = static_cast<ScanCHContext *>(ctx);
     assert(sc);
     sc->result.matches++;
@@ -166,12 +168,23 @@ void EngineChimera::printStats() const {
     }
     printf("Signatures:        %s\n", compile_stats.signatures.c_str());
     printf("Chimera info:      %s\n", compile_stats.db_info.c_str());
+#ifndef _WIN32
     printf("Expression count:  %'zu\n", compile_stats.expressionCount);
     printf("Bytecode size:     %'zu bytes\n", compile_stats.compiledSize);
+#else
+    printf("Expression count:  %zu\n", compile_stats.expressionCount);
+    printf("Bytecode size:     %zu bytes\n", compile_stats.compiledSize);
+#endif
     printf("Database CRC:      0x%x\n", compile_stats.crc32);
+#ifndef _WIN32
     printf("Scratch size:      %'zu bytes\n", compile_stats.scratchSize);
     printf("Compile time:      %'0.3Lf seconds\n", compile_stats.compileSecs);
     printf("Peak heap usage:   %'u bytes\n", compile_stats.peakMemorySize);
+#else
+    printf("Scratch size:      %zu bytes\n", compile_stats.scratchSize);
+    printf("Compile time:      %0.3Lf seconds\n", compile_stats.compileSecs);
+    printf("Peak heap usage:   %u bytes\n", compile_stats.peakMemorySize);
+#endif
 }
 
 void EngineChimera::sqlStats(SqlDB &sqldb) const {
index 685c1076ce579eeae6ce0317205258d91824f1cd..3390c2638314759339c62f86ea8f920c90fc1abc 100644 (file)
@@ -87,8 +87,8 @@ struct ScanHSContext {
  * "echo matches" is off.
  */
 static
-int onMatch(unsigned int, unsigned long long, unsigned long long, unsigned int,
-            void *ctx) {
+int HS_CDECL onMatch(unsigned int, unsigned long long,
+                     unsigned long long, unsigned int, void *ctx) {
     ScanHSContext *sc = static_cast<ScanHSContext *>(ctx);
     assert(sc);
     sc->result.matches++;
@@ -101,8 +101,8 @@ int onMatch(unsigned int, unsigned long long, unsigned long long, unsigned int,
  * matches" is enabled.
  */
 static
-int onMatchEcho(unsigned int id, unsigned long long, unsigned long long to,
-                unsigned int, void *ctx) {
+int HS_CDECL onMatchEcho(unsigned int id, unsigned long long,
+                         unsigned long long to, unsigned int, void *ctx) {
     ScanHSContext *sc = static_cast<ScanHSContext *>(ctx);
     assert(sc);
     sc->result.matches++;
@@ -250,15 +250,30 @@ void EngineHyperscan::printStats() const {
     }
     printf("Signatures:        %s\n", compile_stats.signatures.c_str());
     printf("Hyperscan info:    %s\n", compile_stats.db_info.c_str());
+#ifndef _WIN32
     printf("Expression count:  %'zu\n", compile_stats.expressionCount);
     printf("Bytecode size:     %'zu bytes\n", compile_stats.compiledSize);
+#else
+    printf("Expression count:  %zu\n", compile_stats.expressionCount);
+    printf("Bytecode size:     %zu bytes\n", compile_stats.compiledSize);
+#endif
     printf("Database CRC:      0x%x\n", compile_stats.crc32);
     if (compile_stats.streaming) {
+#ifndef _WIN32
         printf("Stream state size: %'zu bytes\n", compile_stats.streamSize);
+#else
+        printf("Stream state size: %zu bytes\n", compile_stats.streamSize);
+#endif
     }
+#ifndef _WIN32
     printf("Scratch size:      %'zu bytes\n", compile_stats.scratchSize);
     printf("Compile time:      %'0.3Lf seconds\n", compile_stats.compileSecs);
     printf("Peak heap usage:   %'u bytes\n", compile_stats.peakMemorySize);
+#else
+    printf("Scratch size:      %zu bytes\n", compile_stats.scratchSize);
+    printf("Compile time:      %0.3Lf seconds\n", compile_stats.compileSecs);
+    printf("Peak heap usage:   %u bytes\n", compile_stats.peakMemorySize);
+#endif
 }
 
 void EngineHyperscan::sqlStats(SqlDB &sqldb) const {
index b24ba4b56c67e1de7901152302b98bb16bb27baa..85616e987aa8b52a662bcaf132955f7d03f75c83 100644 (file)
@@ -26,6 +26,9 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifdef _WIN32
+#define PCRE_STATIC
+#endif
 #include "config.h"
 
 #include "common.h"
@@ -38,6 +41,8 @@
 #include "util/make_unique.h"
 #include "util/unicode_def.h"
 
+#include <algorithm>
+
 using namespace std;
 
 EnginePCREContext::EnginePCREContext(int capture_cnt) {
@@ -207,11 +212,19 @@ void EnginePCRE::printStats() const {
     }
     printf("Signatures:        %s\n", compile_stats.signatures.c_str());
     printf("PCRE info:         %s\n", compile_stats.db_info.c_str());
+#ifndef _WIN32
     printf("Expression count:  %'zu\n", compile_stats.expressionCount);
     printf("Bytecode size:     %'zu bytes\n", compile_stats.compiledSize);
     printf("Scratch size:      %'zu bytes\n", compile_stats.scratchSize);
     printf("Compile time:      %'0.3Lf seconds\n", compile_stats.compileSecs);
     printf("Peak heap usage:   %'u bytes\n", compile_stats.peakMemorySize);
+#else
+    printf("Expression count:  %zu\n", compile_stats.expressionCount);
+    printf("Bytecode size:     %zu bytes\n", compile_stats.compiledSize);
+    printf("Scratch size:      %zu bytes\n", compile_stats.scratchSize);
+    printf("Compile time:      %0.3Lf seconds\n", compile_stats.compileSecs);
+    printf("Peak heap usage:   %u bytes\n", compile_stats.peakMemorySize);
+#endif
 }
 
 void EnginePCRE::sqlStats(SqlDB &sqldb) const {
index e99b052eade0c05df1ed269e61b0c8c610748d8a..fecdd3305e1e058adfa3192db3957a0164070dcc 100644 (file)
 #include <set>
 #include <thread>
 
+#ifndef _WIN32
 #include <getopt.h>
+#else
+#include "win_getopt.h"
+#endif
 #ifndef _WIN32
 #include <pthread.h>
 #if defined(HAVE_PTHREAD_NP_H)
@@ -138,6 +142,16 @@ public:
 
     // Apply processor affinity (if available) to this thread.
     bool affine(UNUSED int cpu) {
+
+#if defined(_WIN32)
+        SYSTEM_INFO system_info;
+        GetSystemInfo(&system_info);
+        assert(cpu >= 0 && (DWORD)cpu < system_info.dwNumberOfProcessors);
+        DWORD_PTR mask = 1 << cpu;
+        DWORD_PTR rv = SetThreadAffinityMask(thr.native_handle(), mask);
+        return rv != 0;
+#endif
+
 #ifdef HAVE_DECL_PTHREAD_SETAFFINITY_NP
 #if defined(__FreeBSD__)
         cpuset_t cpuset;
@@ -191,7 +205,7 @@ void usage(const char *error) {
     printf("  -H              Benchmark using Chimera (if supported).\n");
     printf("  -P              Benchmark using PCRE (if supported).\n");
 #endif
-#ifdef HAVE_DECL_PTHREAD_SETAFFINITY_NP
+#if defined(HAVE_DECL_PTHREAD_SETAFFINITY_NP) || defined(_WIN32)
     printf("  -T CPU,CPU,...  Benchmark with threads on these CPUs.\n");
 #endif
     printf("  -i DIR          Don't compile, load from files in DIR"
@@ -225,7 +239,7 @@ static
 void processArgs(int argc, char *argv[], vector<BenchmarkSigs> &sigSets,
                  UNUSED unique_ptr<Grey> &grey) {
     const char options[] = "-b:c:Cd:e:E:G:hHi:n:No:p:PsS:Vw:z:"
-#ifdef HAVE_DECL_PTHREAD_SETAFFINITY_NP
+#if defined(HAVE_DECL_PTHREAD_SETAFFINITY_NP) || defined(_WIN32)
         "T:" // add the thread flag
 #endif
         ;
@@ -332,7 +346,7 @@ void processArgs(int argc, char *argv[], vector<BenchmarkSigs> &sigSets,
         case 'S':
             sigName.assign(optarg);
             break;
-#ifdef HAVE_DECL_PTHREAD_SETAFFINITY_NP
+#if defined(HAVE_DECL_PTHREAD_SETAFFINITY_NP) || defined(_WIN32)
         case 'T':
             if (!strToList(optarg, threadCores)) {
                 usage("Couldn't parse argument to -T flag, should be"
@@ -704,7 +718,11 @@ void displayPerScanResults(const vector<unique_ptr<ThreadContext>> &threads,
         for (size_t j = 0; j != results.size(); j++) {
             const auto &r = results[j];
             double mbps = calc_mbps(r.seconds, bytesPerRun);
+#ifndef _WIN32
             printf("T %2u Scan %2zu: %'0.2f Mbit/sec\n", t->num, j, mbps);
+#else
+            printf("T %2u Scan %2zu: %0.2f Mbit/sec\n", t->num, j, mbps);
+#endif
         }
     }
     printf("\n");
@@ -749,6 +767,7 @@ void displayResults(const vector<unique_ptr<ThreadContext>> &threads,
         }
     }
 
+#ifndef _WIN32
     printf("Time spent scanning:       %'0.3f seconds\n", totalSecs);
     printf("Corpus size:               %'llu bytes ", bytesPerRun);
     switch (scan_mode) {
@@ -764,22 +783,56 @@ void displayResults(const vector<unique_ptr<ThreadContext>> &threads,
         printf("(%'zu blocks)\n", corpus_blocks.size());
         break;
     }
+#else
+    printf("Time spent scanning:       %0.3f seconds\n", totalSecs);
+    printf("Corpus size:               %llu bytes ", bytesPerRun);
+    switch (scan_mode) {
+    case ScanMode::STREAMING:
+        printf("(%zu blocks in %llu streams)\n", corpus_blocks.size(),
+               count_streams(corpus_blocks));
+        break;
+    case ScanMode::VECTORED:
+        printf("(%zu blocks in %llu vectors)\n", corpus_blocks.size(),
+               count_streams(corpus_blocks));
+        break;
+    case ScanMode::BLOCK:
+        printf("(%zu blocks)\n", corpus_blocks.size());
+        break;
+    }
+#endif
 
     u64a totalBytes = bytesPerRun * repeats * threads.size();
     u64a totalBlocks = corpus_blocks.size() * repeats * threads.size();
 
     double matchRate = ((double)matchesPerRun * 1024) / bytesPerRun;
+#ifndef _WIN32
     printf("Matches per iteration:     %'llu (%'0.3f matches/kilobyte)\n",
            matchesPerRun, matchRate);
+#else
+    printf("Matches per iteration:     %llu (%0.3f matches/kilobyte)\n",
+           matchesPerRun, matchRate);
+#endif
 
     double blockRate = (double)totalBlocks / (double)totalSecs;
+#ifndef _WIN32
     printf("Overall block rate:        %'0.2f blocks/sec\n", blockRate);
     printf("Mean throughput (overall): %'0.2Lf Mbit/sec\n",
            calc_mbps(totalSecs, totalBytes));
 
+#else
+    printf("Overall block rate:        %0.2f blocks/sec\n", blockRate);
+    printf("Mean throughput (overall): %0.2Lf Mbit/sec\n",
+           calc_mbps(totalSecs, totalBytes));
+
+#endif
     double lowestScanTime = fastestResult(threads);
+#ifndef _WIN32
     printf("Max throughput (per core): %'0.2Lf Mbit/sec\n",
            calc_mbps(lowestScanTime, bytesPerRun));
+#else
+    printf("Max throughput (per core): %0.2Lf Mbit/sec\n",
+           calc_mbps(lowestScanTime, bytesPerRun));
+#endif
     printf("\n");
 
     if (display_per_scan) {
@@ -892,7 +945,7 @@ void runBenchmark(const Engine &db,
         numThreads = 1;
     } else {
         numThreads = threadCores.size();
-#ifdef HAVE_DECL_PTHREAD_SETAFFINITY_NP
+#if defined(HAVE_DECL_PTHREAD_SETAFFINITY_NP) || defined(_WIN32)
         useAffinity = true;
 #else
         useAffinity = false;
@@ -932,7 +985,7 @@ void runBenchmark(const Engine &db,
 } // namespace
 
 /** Main driver. */
-int main(int argc, char *argv[]) {
+int HS_CDECL main(int argc, char *argv[]) {
     unique_ptr<Grey> grey;
 #if !defined(RELEASE_BUILD)
     grey = make_unique<Grey>();
index 781d6b39c8cd32f39284e263fd1badc0a79fec27..8f45765a80ba93cc768fea4311f7ebd932607fc9 100644 (file)
@@ -10,9 +10,16 @@ if (BUILD_CHIMERA)
     include_directories(${PCRE_INCLUDE_DIRS})
     add_definitions(-DHS_HYBRID)
     add_executable(hscheck ${hscheck_SOURCES})
-    target_link_libraries(hscheck hs chimera ${PCRE_LDFLAGS} expressionutil pthread)
+    if(NOT WIN32)
+        target_link_libraries(hscheck hs chimera ${PCRE_LDFLAGS} expressionutil pthread)
+    else()
+        target_link_libraries(hscheck hs chimera pcre expressionutil)
+    endif()
 else()
     add_executable(hscheck ${hscheck_SOURCES})
-    target_link_libraries(hscheck hs expressionutil pthread)
+    if(NOT WIN32)
+        target_link_libraries(hscheck hs expressionutil pthread)
+    else()
+        target_link_libraries(hscheck hs expressionutil)
+    endif()
 endif()
-
index 27416028c8451b8a8fdcdf4250d42091fe0dc060..595c8b84fa059b02f91bc530932d897860d53c61 100644 (file)
 #include <stdexcept>
 #include <string>
 #include <thread>
-
+#ifndef _WIN32
 #include <getopt.h>
+#else
+#include "win_getopt.h"
+#endif
 #include <boost/algorithm/string/trim.hpp>
 
 using namespace std;
@@ -625,7 +628,7 @@ void loadSignatureBuildSigs(const string &inFile,
     }
 }
 
-int main(int argc, char **argv) {
+int HS_CDECL main(int argc, char **argv) {
     num_of_threads = max(1u, std::thread::hardware_concurrency());
 
 #if !defined(RELEASE_BUILD)
index 7b2891fc3b2430bba3acffb469aeea27725e1fb9..0a6878a7245a1946a0a64e6511ccadebfeb82fe4 100644 (file)
@@ -74,7 +74,8 @@ if(HAVE_BACKTRACE)
         "${BACKTRACE_CFLAGS}")
 endif()
 else() # WIN32
-    target_link_libraries(hscollider hs chimera ${PCRE_LDFLAGS} databaseutil
+    set_target_properties(hscollider PROPERTIES LINK_FLAGS "/STACK:8388608,8388608")
+    target_link_libraries(hscollider hs chimera pcre databaseutil
         expressionutil corpusomatic crosscompileutil)
 endif()
 
index fcb476852712c5cfa7cdfedf0d7d5ade91bd092d..fe038c818c266f4f38fceec39574fa1e07cb8896 100644 (file)
@@ -26,6 +26,9 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifdef _WIN32
+#define PCRE_STATIC
+#endif
 #include "config.h"
 
 #include "common.h"
index 537fa0dd0219e7da942e7ac8f93dc652de2625a8..5fff82398ce62f014fb972962ca29dfcf15a97ff 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Intel Corporation
+ * Copyright (c) 2015-2018, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -35,8 +35,7 @@
 #include <cstdlib>
 #include <iostream>
 
-#include <pthread.h>
-
+#ifndef _WIN32
 static const size_t COLLIDER_THREAD_STACK_SIZE = 8192 * 1024;
 
 void Thread::start() {
@@ -79,6 +78,16 @@ create_thread:
     }
 }
 
+void Thread::join() { pthread_join(thread, nullptr); }
+
+#else // windows
+
+void Thread::start() { thread = std::thread(&runThread, this); }
+
+void Thread::join() { thread.join(); }
+
+#endif
+
 // Dispatch
 void *Thread::runThread(void *thr) {
     if (!no_signal_handler) {
@@ -88,7 +97,6 @@ void *Thread::runThread(void *thr) {
     return nullptr;
 }
 
-void Thread::join() { pthread_join(thread, nullptr); }
 
 Thread::Thread(size_t num) : thread_id(num) {}
 
index 2ca50e38bd260e164b79a2c27eb2f53d23acbb3d..c6675dad966fa40aad18ddeae99cfa45b50c940a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Intel Corporation
+ * Copyright (c) 2015-2018, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
 
 #include <cstdlib>
 
+#ifndef _WIN32
 #include <pthread.h>
+#else
+#include <thread>
+#endif
 
 #include <boost/core/noncopyable.hpp>
 
@@ -54,7 +58,11 @@ protected:
     const size_t thread_id;
 
 private:
+#ifndef _WIN32
     pthread_t thread;
+#else
+    std::thread thread;
+#endif
 };
 
 #endif // UE2COLLIDER_THREAD_H
index 4b8724e8b46ea4cf195908b37dfcb792a5b578c1..c37e39ba3e78dd496249fbd58212311f520c1d42 100644 (file)
@@ -169,8 +169,9 @@ struct MultiContext {
 
 // Callback used for all (both single and multi-mode) scans.
 static
-int callbackMulti(unsigned int id, unsigned long long from,
-                  unsigned long long to, UNUSED unsigned int flags, void *ctx) {
+int HS_CDECL callbackMulti(unsigned int id, unsigned long long from,
+                           unsigned long long to,
+                           UNUSED unsigned int flags, void *ctx) {
     MultiContext *mctx = static_cast<MultiContext *>(ctx);
     assert(mctx);
     assert(mctx->rs);
@@ -269,7 +270,7 @@ int callbackMulti(unsigned int id, unsigned long long from,
 
 // Hybrid matcher callback.
 static
-ch_callback_t callbackHybrid(unsigned id, unsigned long long from,
+ch_callback_t HS_CDECL callbackHybrid(unsigned id, unsigned long long from,
                              unsigned long long to, unsigned, unsigned size,
                              const ch_capture_t *captured, void *ctx) {
     MultiContext *mctx = static_cast<MultiContext *>(ctx);
@@ -322,8 +323,9 @@ ch_callback_t callbackHybrid(unsigned id, unsigned long long from,
 
 // Hybrid matcher error callback.
 static
-ch_callback_t errorCallback(UNUSED ch_error_event_t errorType, UNUSED unsigned int id, void *,
-                            void *ctx) {
+ch_callback_t HS_CDECL errorCallback(UNUSED ch_error_event_t errorType,
+                                     UNUSED unsigned int id, void *,
+                                     void *ctx) {
     UNUSED MultiContext *mctx = static_cast<MultiContext *>(ctx);
     assert(mctx);
     assert(mctx->rs);
index 3f53f8bc4122ca0d46b5e8db2368effb17607aff..3b515027f5cb7a50a13cdabec8f6d9376b9a7244 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, Intel Corporation
+ * Copyright (c) 2015-2018, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
 #include <sstream>
 #include <string>
 #include <vector>
+#ifndef _WIN32
 #include <getopt.h>
+#else
+#include "win_getopt.h"
+#endif
 
 #define xstr(s) str(s)
 #define str(s) #s
@@ -467,7 +471,7 @@ void processArgs(int argc, char *argv[], CorpusProperties &corpus_gen_prop,
                     exit(1);
                 }
                 break;
-            case 'Z':
+            case 'Z': {     // Parentheses save VS C2360
                 static constexpr unsigned ALIGN_LIMIT = MAX_MAX_UE2_ALIGN - 1;
                 if (optarg == string("R")) {
                     // Random min alignment selected.
@@ -481,6 +485,7 @@ void processArgs(int argc, char *argv[], CorpusProperties &corpus_gen_prop,
                 }
                 max_ue2_align = min_ue2_align + 1;
                 break;
+            }
             case '8':
                 force_utf8 = true;
                 break;
index 4eaa3962453e201979ca5e134072543bb150516f..ec7cd6be5142db4778299b3b8f9d724d458c3b2a 100644 (file)
@@ -1840,13 +1840,17 @@ unique_ptr<CorporaSource> buildCorpora(const vector<string> &corporaFiles,
 static
 bool needsQuotes(const char *s) {
     size_t len = strlen(s);
-    // don't confuse the correct isblank for the one in locale
-    int (*blank)(int) = &std::isblank;
 
     if (len == 0) {
         return true;
     }
+#ifndef _WIN32
+    // don't confuse the correct isblank for the one in locale
+    int (*blank)(int) = &std::isblank;
     if (find_if(s, s + len, blank) != s + len) {
+#else
+    if (find_if(s, s + len, [](unsigned char c){ return std::isblank(c); }) != s + len) {
+#endif
         return true;
     }
 
@@ -1910,7 +1914,7 @@ bool runTests(CorporaSource &corpora_source, const ExpressionMap &exprMap,
     return !summary.hasFailure();
 }
 
-int main(int argc, char *argv[]) {
+int HS_CDECL main(int argc, char *argv[]) {
     Grey grey;
     vector<string> corporaFiles;
 
index b48be98a95de8ed61c1fdafd1b6cf73577ad3a5b..dc8151400625a189c794580aeb7c8811cab6af19 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, Intel Corporation
+ * Copyright (c) 2015-2018, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -36,7 +36,7 @@
 #include <ctype.h>
 #include <string>
 
-#ifdef HAVE_SIGACTION
+#if defined(HAVE_SIGACTION) || defined(_WIN32)
 #include <signal.h>
 #endif
 
@@ -56,8 +56,12 @@ TLS_VARIABLE volatile size_t debug_corpus_len = 0;
 
 extern std::string g_cmdline;
 
-#ifdef HAVE_SIGACTION
+#if defined(_WIN32)
+static void __cdecl sighandler(int signum) {
+#elif defined(HAVE_SIGACTION)
 static void sighandler(int signum) {
+#endif
+#if defined(HAVE_SIGACTION) || defined(_WIN32)
     /* NOTE: This signal handler is designed solely to provide more information
      * when a crash occurs in ue2collider -- it makes calls to signal-unsafe
      * functions like printf() and backtrace() by design, since we're already
@@ -141,7 +145,13 @@ static void sighandler(int signum) {
 #endif // HAVE_SIGACTION
 
 void installSignalHandler(void) {
-#ifdef HAVE_SIGACTION
+
+#ifdef _WIN32
+    signal(SIGABRT, sighandler);
+    signal(SIGFPE, sighandler);
+    signal(SIGILL, sighandler);
+    signal(SIGSEGV, sighandler);
+#elif defined(HAVE_SIGACTION)
     struct sigaction act;
     memset(&act, 0, sizeof(act));
     act.sa_handler = sighandler;
index fc64382691a5c7d5db4e4055b86cddf22625b52c..4b24e95f6ef8589f6e7701ca958a0df7dc8491c1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Intel Corporation
+ * Copyright (c) 2015-2018, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
 #define STAGE_GRAPH_COMPILE 6
 #define STAGE_GRAPH_RUN 7
 
+#ifndef WIN32
 #define TLS_VARIABLE __thread
+#else
+#define TLS_VARIABLE __declspec(thread)
+#endif
 
 extern TLS_VARIABLE volatile int debug_stage;
 extern TLS_VARIABLE volatile int debug_expr;
index c3db52353a3846c2fd15403ed2b63628e13a94cf..4350b0f6d95135e2dba23dc484ff5259d792be03 100644 (file)
@@ -3,10 +3,6 @@ if (NOT DUMP_SUPPORT)
     return()
 endif ()
 
-if (WIN32)
-    return()
-endif ()
-
 include_directories(${PROJECT_SOURCE_DIR})
 include_directories(${PROJECT_SOURCE_DIR}/util)
 
index 53a72d208929ecc3868ee04acd6a4def5defe54c..3221d1b69d25359a27ca9176dffab3898df1dfb7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, Intel Corporation
+ * Copyright (c) 2015-2018, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
 #include <string>
 #include <vector>
 
+#ifndef _WIN32
 #include <getopt.h>
+#else
+#include "win_getopt.h"
+#endif
 #include <sys/stat.h>
+
+#ifndef _WIN32
 #include <dirent.h>
+#else
+#include <direct.h>
+#define stat _stat
+#endif
 
 #include <boost/ptr_container/ptr_vector.hpp>
 
@@ -318,6 +328,7 @@ u32 buildDumpFlags(void) {
     return flags;
 }
 
+#ifndef _WIN32
 static
 void clearDir(const string &path) {
     DIR *dir = opendir(path.c_str());
@@ -341,15 +352,54 @@ void clearDir(const string &path) {
     }
     closedir(dir);
 }
+#else // windows
+static
+void clearDir(const string &path) {
+    WIN32_FIND_DATA ffd;
+    HANDLE hFind = INVALID_HANDLE_VALUE;
+    string glob = path + "/*";
+    hFind = FindFirstFile(glob.c_str(), &ffd);
+    if (hFind == INVALID_HANDLE_VALUE) {
+        printf("ERROR: couldn't open location %s\n", path.c_str());
+        exit(1);
+    }
+    do {
+        string basename(ffd.cFileName);
+        string fname(path);
+        fname.push_back('/');
+        fname.append(basename);
+
+        // Ignore '.' and '..'
+        if (basename == "." || basename == "..") {
+            continue;
+        }
+
+        if (!DeleteFile(fname.c_str())) {
+            printf("ERROR: couldn't remove file %s\n", fname.c_str());
+        }
+
+    } while (FindNextFile(hFind, &ffd) != 0);
+    FindClose(hFind);
+}
+#endif
+
+static
+int makeDirectory(const string &dirName) {
+#ifndef _WIN32
+    mode_t mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP |
+                  S_IROTH | S_IXOTH;
+    return mkdir(dirName.c_str(), mode);
+#else
+    return _mkdir(dirName.c_str());
+#endif
+}
 
 static
 void prepareDumpLoc(string parent, string path, u32 flags, Grey &grey) {
     struct stat st;
     if (stat(parent.c_str(), &st)) {
         // Create dump location if not found
-        mode_t mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP |
-                      S_IROTH | S_IXOTH;
-        if (mkdir(parent.c_str(), mode) < 0) {
+        if (makeDirectory(parent) < 0) {
             printf("ERROR: could not create dump location %s: %s\n",
                    parent.c_str(), strerror(errno));
             exit(1);
@@ -365,9 +415,7 @@ void prepareDumpLoc(string parent, string path, u32 flags, Grey &grey) {
     path = parent.append(path);
     if (stat(path.c_str(), &st)) {
         // Create dump location if not found
-        mode_t mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP |
-                      S_IROTH | S_IXOTH;
-        if (mkdir(path.c_str(), mode) < 0) {
+        if (makeDirectory(path) < 0) {
             printf("ERROR: could not create dump location %s: %s\n",
                    path.c_str(), strerror(errno));
             exit(1);
@@ -546,7 +594,7 @@ unsigned int dumpData(const ExpressionMap &exprMap, Grey &grey) {
     return dumpDataMulti(patterns, flags, ids, ext, grey);
 }
 
-int main(int argc, char *argv[]) {
+int HS_CDECL main(int argc, char *argv[]) {
     Grey grey;
     grey.dumpFlags = Grey::DUMP_BASICS;
 
index 47b0ae9b1bf0c11bd0b3b096e49d54718129e268..32e014508e1cbc418401bf91a56ffa4021eb7deb 100644 (file)
@@ -1,6 +1,13 @@
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS}")
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXX_FLAGS}")
 
+if(CMAKE_C_FLAGS MATCHES "/Gv" )
+    string(REPLACE "/Gv" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+endif()
+if(CMAKE_CXX_FLAGS MATCHES "/Gv" )
+    string(REPLACE "/Gv" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+endif()
+
 set(gtest_SOURCES gtest/gtest-all.cc gtest/gtest.h)
 include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR})
 include_directories(${PROJECT_SOURCE_DIR})
@@ -31,6 +38,10 @@ endif()
 
 add_definitions(-DGTEST_HAS_PTHREAD=0 -DSRCDIR=${PROJECT_SOURCE_DIR})
 
+if (WIN32)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4309 /wd4018")
+endif()
+
 set(unit_hyperscan_SOURCES
     ${gtest_SOURCES}
     hyperscan/allocators.cpp
diff --git a/util/win_getopt.h b/util/win_getopt.h
new file mode 100644 (file)
index 0000000..7ec9abf
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2018, 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 WIN_GETOPT_H
+#define WIN_GETOPT_H
+
+#include <windows.h>
+#define ILLEGAL (int)'?'
+#define END -1
+#define SPECIAL_OPT 1
+
+int optind = 0;
+char *optarg;
+static char EMPT[] = "";
+static char *ptr = EMPT;
+static int no_argument = 0;
+static int required_argument = 1;
+static const char no_arg[] = "option doesn't take an argument --%.*s";
+static const char non_opt_string[] = "not an option : %s";
+static const char ill_shortopt_char[] = "unknown option -%c";
+static const char ill_longopt_string[] = "unknown option --%s";
+static const char req_arg_string[] = "option requires an argument --%s";
+static const char req_arg_char[] = "option requires an argument -%c";
+
+struct option {
+    const char *name;
+    int has_arg;
+    int *flag;
+    int value;
+};
+
+static
+void warn(const char *fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    vfprintf(stdout, fmt, args);
+    fprintf(stdout, "\n");
+    va_end(args);
+}
+
+int getopt_long(int nargc, char *const *nargv, const char *options,
+                const struct option *long_options, int *idx) {
+    char *check, *equal;
+    size_t current_opt_len;
+    bool all_flag = false;
+    int match = -1;
+    // illegal
+    if (options == NULL) {
+        return ILLEGAL;
+    }
+    if (optind == 0) {
+        optind = 1;
+    }
+    if (optind >= nargc) {
+        return END;
+    }
+    if (*options == '-') {
+        all_flag = true;
+        ++options;
+    }
+    optarg = NULL;
+    // illegal
+    if (*(ptr = nargv[optind]) != '-') {
+        ptr = EMPT;
+        if (all_flag) {
+            optarg = nargv[optind++];
+            return SPECIAL_OPT;
+        } else {
+            warn(non_opt_string, nargv[optind]);
+            return ILLEGAL;
+        }
+    }
+    // likely a short option ?
+    if (ptr[1] != '\0' && *++ptr != '-' && ptr[1] == '\0') {
+        char opt_char = *ptr;
+        ptr = EMPT;
+        // really short option ?
+        if ((check = (char *)strchr(options, opt_char)) != NULL) {
+            if (check[1] == ':') {
+                ++optind;
+                if (optind >= nargc) {
+                    warn(req_arg_char, opt_char);
+                    return ILLEGAL;
+                } else {
+                    optarg = nargv[optind];
+                }
+            }
+            ++optind;
+            return opt_char;
+        } else { // illegal
+            warn(ill_shortopt_char, opt_char);
+            return ILLEGAL;
+        }
+    }
+    // we meet '--'
+    if (*ptr == '-' && ptr[1] == '\0') {
+        ptr = EMPT;
+        return END;
+    }
+    // we meet '--foo' , long option
+    if (long_options != NULL && *ptr == '-' && ptr[1] != '\0') {
+        ++ptr;
+        if ((equal = strchr(ptr, '=')) != NULL) {
+            // found --option=arg
+            current_opt_len = equal - ptr;
+            ++equal;
+        } else {
+            current_opt_len = strlen(ptr);
+        }
+        for (int i = 0; long_options[i].name; i++) {
+            if (!strcmp(ptr, long_options[i].name )) {
+                match = i;
+                break;
+            }
+        }
+        if (match == -1) { // don't match
+            warn(ill_longopt_string, ptr);
+            ptr = EMPT;
+            return ILLEGAL;
+        } else {
+            ++optind;
+            if (long_options[match].has_arg == required_argument) {
+                if (equal) {
+                    optarg = equal;
+                } else if (optind < nargc) {
+                    optarg = nargv[optind++];
+                } else {
+                    warn(req_arg_string, ptr);
+                    ptr = EMPT;
+                    return ILLEGAL;
+                }
+            }
+            if (long_options[match].has_arg == no_argument && equal) {
+                warn(no_arg, (int)current_opt_len, ptr);
+                ptr = EMPT;
+                return ILLEGAL;
+            }
+            ptr = EMPT;
+            if (long_options[match].flag) {
+                *long_options[match].flag = long_options[match].value;
+                return 0;
+            } else {
+                return (long_options[match].value);
+            }
+        }
+    }
+    warn(non_opt_string, ptr);
+    ptr = EMPT;
+    return ILLEGAL;
+}
+
+#endif