$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r73488 - in sandbox/tools/profile_templates2: . src
From: dsaritz_at_[hidden]
Date: 2011-08-02 08:03:43
Author: psiha
Date: 2011-08-02 08:03:41 EDT (Tue, 02 Aug 2011)
New Revision: 73488
URL: http://svn.boost.org/trac/boost/changeset/73488
Log:
Refactored all the project modules to work as a single binary, communicating directly instead of through intermediate files.
Added a workaround for Xpressive stack overflows by increasing the reserved stack space for MSVC.
Minor other refactoring, stylistic changes and fixes.
Text files modified: 
   sandbox/tools/profile_templates2/profiler.cmake      |    82 ++++++++++--------                      
   sandbox/tools/profile_templates2/src/filter.cpp      |   170 +++++++++++++++++++++++---------------- 
   sandbox/tools/profile_templates2/src/filter.hpp      |     6                                         
   sandbox/tools/profile_templates2/src/postprocess.cpp |    47 +++++-----                              
   sandbox/tools/profile_templates2/src/postprocess.hpp |     6 +                                       
   sandbox/tools/profile_templates2/src/preprocess.cpp  |    31 ++++--                                  
   sandbox/tools/profile_templates2/src/preprocess.hpp  |     4                                         
   sandbox/tools/profile_templates2/src/profiler.cpp    |    96 ++++++++++++++++++----                  
   8 files changed, 280 insertions(+), 162 deletions(-)
Modified: sandbox/tools/profile_templates2/profiler.cmake
==============================================================================
--- sandbox/tools/profile_templates2/profiler.cmake	(original)
+++ sandbox/tools/profile_templates2/profiler.cmake	2011-08-02 08:03:41 EDT (Tue, 02 Aug 2011)
@@ -19,54 +19,64 @@
 include_directories( ${Boost_INCLUDE_DIRS} )
 add_executable(
     template.profiler
-    ${PROFILER_PATH}/src/preprocess.cpp
-    ${PROFILER_PATH}/src/preprocess.hpp
     ${PROFILER_PATH}/src/filter.cpp
     ${PROFILER_PATH}/src/filter.hpp
     ${PROFILER_PATH}/src/postprocess.cpp
     ${PROFILER_PATH}/src/postprocess.hpp
+    ${PROFILER_PATH}/src/preprocess.cpp
+    ${PROFILER_PATH}/src/preprocess.hpp
     ${PROFILER_PATH}/src/profiler.cpp
 )
-set_property(TARGET template.profiler PROPERTY RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/tools)
-if (NOT MSVC) # Use autolink for MSVC
-    target_link_libraries(template.profiler ${Boost_LIBRARIES})
+set_property( TARGET template.profiler PROPERTY RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/tools )
+if ( MSVC )
+    # A workaround for Xpressive stack overflows
+    set_property( TARGET template.profiler APPEND PROPERTY LINK_FLAGS /STACK:32000000 )
+endif()
+if ( NOT MSVC ) # Use autolink for MSVC
+    target_link_libraries( template.profiler ${Boost_LIBRARIES} )
 endif()
 
 ################################################################################
 # Make a function to compile foo and profile it
 ################################################################################
 function(template_profile target src)
-  if(CMAKE_GENERATOR MATCHES "Make")
-    set( profiler_cxx_flags ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}} )
-  else()
-    set( profiler_cxx_flags ${CMAKE_CXX_FLAGS_DEBUG} )
-  endif() 
-
-  get_directory_property( preprocessor_definitions COMPILE_DEFINITIONS )
-  foreach(preprocessor_definition ${preprocessor_definitions})
-    set(profiler_cxx_flags "${profiler_cxx_flags} -D${preprocessor_definition}")
-  endforeach()
-
-  get_directory_property(INCLUDES INCLUDE_DIRECTORIES)
-  foreach(INCLUDE ${INCLUDES})
-    set(INCLUDE_DIRECTORIES "${INCLUDE_DIRECTORIES} -I\"${INCLUDE}\"" )
-  endforeach()
-
-  if ( NOT EXISTS ${CMAKE_CXX_COMPILER} )
-    if ( MSVC )
-      get_filename_component( devenv_path ${CMAKE_MAKE_PROGRAM} PATH )
-      set( full_compiler_path "${devenv_path}/../../VS/bin/${CMAKE_CXX_COMPILER}" )
-      file( TO_NATIVE_PATH ${full_compiler_path} full_compiler_path )
-      set( ENV{PATH} "$ENV{PATH};$(ExecutablePath)" )
-    elseif()
-      find_program( full_compiler_path "${CMAKE_CXX_COMPILER}" )
+    if(CMAKE_GENERATOR MATCHES "Make")
+        set( profiler_cxx_flags ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}} )
+    else()
+        set( profiler_cxx_flags ${CMAKE_CXX_F  LAGS_DEBUG} )
     endif()
-  endif()
+  
+    # Suppress linking.
+    set( profiler_cxx_flags "${profiler_cxx_flags} -c" )
+
+    get_directory_property( preprocessor_definitions COMPILE_DEFINITIONS )
+    foreach(preprocessor_definition ${preprocessor_definitions})
+        set(profiler_cxx_flags "${profiler_cxx_flags} -D${preprocessor_definition}")
+    endforeach()
+
+    get_directory_property(INCLUDES INCLUDE_DIRECTORIES)
+    foreach(INCLUDE ${INCLUDES})
+        set(INCLUDE_DIRECTORIES "${INCLUDE_DIRECTORIES} -I\"${INCLUDE}\"" )
+    endforeach()
+    set(INCLUDE_DIRECTORIES "${INCLUDE_DIRECTORIES} -I\"${PROFILER_PATH}\"" )
+
+    if ( NOT EXISTS ${CMAKE_CXX_COMPILER} )
+        if ( MSVC )
+            get_filename_component( devenv_path ${CMAKE_MAKE_PROGRAM} PATH )
+            set( full_compiler_path "${devenv_path}/../../VC/bin/${CMAKE_CXX_COMPILER}" )
+            file( TO_NATIVE_PATH ${full_compiler_path} full_compiler_path )
+        elseif()
+            find_program( full_compiler_path "${CMAKE_CXX_COMPILER}" )
+        endif()
+    endif()
+
+    file( TO_NATIVE_PATH "${PROJECT_BINARY_DIR}/${target}.compiler_options.rsp" response_file_path )
 
-  add_custom_command(OUTPUT ${target}.template_profile
-                     COMMAND echo "${profiler_cxx_flags} ${INCLUDE_DIRECTORIES}" > ${target}.compiler_options.rsp
-                     COMMAND "${PROJECT_BINARY_DIR}/tools/${CMAKE_CFG_INTDIR}/template.profiler" "${full_compiler_path}" ${target}.compiler_options.rsp "${CMAKE_CURRENT_SOURCE_DIR}/${src}"
-                     DEPENDS ${src}
-                   )
-  add_custom_target( ${target} DEPENDS ${target}.template_profile )
+    add_custom_command(
+        OUTPUT ${target}.template_profile
+        COMMAND echo "${profiler_cxx_flags} ${INCLUDE_DIRECTORIES}" > "${PROJECT_BINARY_DIR}/${target}.compiler_options.rsp"
+        COMMAND "${PROJECT_BINARY_DIR}/tools/${CMAKE_CFG_INTDIR}/template.profiler" "${full_compiler_path}" "${response_file_path}" "${CMAKE_CURRENT_SOURCE_DIR}/${src}" "${target}.template_profile"
+        DEPENDS ${src} template.profiler
+    )
+    add_custom_target( ${target} DEPENDS ${target}.template_profile )
 endfunction()
Modified: sandbox/tools/profile_templates2/src/filter.cpp
==============================================================================
--- sandbox/tools/profile_templates2/src/filter.cpp	(original)
+++ sandbox/tools/profile_templates2/src/filter.cpp	2011-08-02 08:03:41 EDT (Tue, 02 Aug 2011)
@@ -26,102 +26,133 @@
 {
 //------------------------------------------------------------------------------
 
-const char* search("template_profiler");
+namespace
+{
+    char const search[] = "template_profiler";
 
-#if defined(_MSC_VER)
-    const char* back_trace_search("see reference to");
-#elif defined(__GNUC__)
-    const char* back_trace_search("instantiated from");
-#else
-    #error only Microsoft and gcc are supported.
-#endif
+    char const back_trace_search[] = 
+    #if defined( _MSC_VER )
+        "see reference to";
+    #elif defined( __GNUC__ )
+        "instantiated from";
+    #else
+        #error only Microsoft and gcc are supported.
+    #endif
+} // anonymous namespace
+
+void copy_flat_only( std::string const & input, std::string & output )
+{
+    output.reserve( input.size() );
+
+    unsigned int pos    (     0 );
+    unsigned int counter(     0 );
+    bool         matched( false );
 
-void copy_flat_only() {
     std::string buffer;
-    int ch;
-    int pos = 0;
-    bool matched = false;
-    int counter = 0;
-    while((ch = std::getchar()) != EOF) {
-        buffer.push_back(static_cast<char>(ch));
-        if(ch == '\n') {
-            if(matched) {
-                for(std::size_t i = 0; i < buffer.size(); ++i) {
-                    std::putchar(buffer[i]);
-                }
+
+    std::string::const_iterator       p_ch     ( input.begin() );
+    std::string::const_iterator const input_end( input.end  () );
+
+    while ( p_ch != input_end )
+    {
+        char const ch( *p_ch++ );
+        buffer.push_back( ch );
+        if ( ch == '\n' )
+        {
+            if ( matched )
+            {
+                output.append( buffer );
                 ++counter;
-#ifdef _MSC_VER
-                if(counter % 400 == 0) {
-                    std::fprintf(stderr, "On Instantiation %d\n", counter/4);
-                }
-#else
-                if(counter % 200 == 0) {
-                    std::fprintf(stderr, "On Instantiation %d\n", counter/2);
-                }
-#endif
+                #ifdef _MSC_VER
+                    if ( counter % 400 == 0 ) std::fprintf( stderr, "On Instantiation %d\n", counter/4 );
+                #else
+                    if ( counter % 200 == 0 ) std::fprintf( stderr, "On Instantiation %d\n", counter/2 );
+                #endif
             }
             buffer.clear();
             matched = false;
         }
-        if(ch == search[pos]) {
+        if ( ch == search[ pos ] )
+        {
             ++pos;
-            if(search[pos] == '\0') {
+            if ( search[ pos ] == '\0' )
+            {
                 matched = true;
             }
-        } else {
+        }
+        else
+        {
             pos = 0;
         }
     }
 }
 
-void copy_call_graph() {
+void copy_call_graph( std::string const & input, std::string & output )
+{
 #if defined(_MSC_VER) && 0
+    output.reserve( input.size() );
+
+    unsigned int pos    (     0 );
+    unsigned int counter(     0 );
+    bool         matched( false );
+
     std::string buffer;
-    int ch;
-    int pos = 0;
-    bool matched = false;
-    int counter = 0;
-    while((ch = std::getchar()) != EOF) {
-        buffer.push_back(static_cast<char>(ch));
-        if(ch == '\n') {
-            if(matched) {
-                for(std::size_t i = 0; i < buffer.size(); ++i) {
-                    std::putchar(buffer[i]);
-                }
-                if(++counter % 200 == 0) {
-                    std::fprintf(stderr, "On Instantiation %d\n", counter/2);
-                }
+
+    std::string::const_iterator       p_ch     ( input.begin() );
+    std::string::const_iterator const input_end( input.end  () );
+
+    while ( p_ch != input_end )
+    {
+        char const ch( *p_ch++ );
+        buffer.push_back( ch );
+        if ( ch == '\n' )
+        {
+            if ( matched )
+            {
+                output.append( buffer );
+                if ( ++counter % 200 == 0 ) std::fprintf( stderr, "On Instantiation %d\n", counter/2 );
                 buffer.clear();
                 matched = false;
                 // process instantiation back-trace
                 pos = 0;
-                while((ch = std::getchar()) != EOF) {
-                    if(ch == ' ') {
-                        buffer.push_back(static_cast<char>(ch));
-                        while((ch = std::getchar()) != EOF) {
-                            buffer.push_back(static_cast<char>(ch));
-                            if(ch == '\n') {
-                                if(matched) {
-                                    for(std::size_t i = 0; i < buffer.size(); ++i) {
-                                        std::putchar(buffer[i]);
-                                    }
+                while ( p_ch != input_end )
+                {
+                    char const ch( *p_ch++ );
+                    if ( ch == ' ' )
+                    {
+                        buffer.push_back( ch );
+                        while ( p_ch != input_end )
+                        {
+                            char const ch( *p_ch++ );
+                            buffer.push_back( ch );
+                            if ( ch == '\n' )
+                            {
+                                if ( matched )
+                                {
+                                    output.append( buffer );
                                 }
                                 buffer.clear();
                                 matched = false;
                                 pos = 0;
                                 break;
                             }
-                            if(ch == back_trace_search[pos]) {
+                            if ( ch == back_trace_search[ pos ] )
+                            {
                                 ++pos;
-                                if(back_trace_search[pos] == '\0') {
+                                if ( back_trace_search[ pos ] == '\0' )
+                                {
                                     matched = true;
                                 }
-                            } else {
+                            }
+                            else
+                            {
                                 pos = 0;
                             }
                         }
-                    } else {
-                        std::ungetc(ch, stdin);
+                    }
+                    else
+                    {
+                        --p_ch;
                         break;
                     }
                 }
@@ -130,21 +161,22 @@
             matched = false;
             pos = 0;
         }
-        if(ch == search[pos]) {
+        if ( ch == search[ pos ] )
+        {
             ++pos;
-            if(search[pos] == '\0') {
+            if ( search[ pos ] == '\0' )
+            {
                 matched = true;
             }
-        } else {
+        }
+        else
+        {
             pos = 0;
         }
     }
 #elif defined(__GNUC__) || 1
     // trying to figure out what we should copy is too hard.
-    int ch;
-    while((ch = std::getchar()) != EOF) {
-        std::putchar(ch);
-    }
+    output = input;
 #else
     #error Unknown compiler
 #endif
Modified: sandbox/tools/profile_templates2/src/filter.hpp
==============================================================================
--- sandbox/tools/profile_templates2/src/filter.hpp	(original)
+++ sandbox/tools/profile_templates2/src/filter.hpp	2011-08-02 08:03:41 EDT (Tue, 02 Aug 2011)
@@ -17,12 +17,14 @@
 #define filter_hpp__17451C87_D31A_43A8_B226_F0D430EB504E
 #pragma once
 //------------------------------------------------------------------------------
+#include <string>
+//------------------------------------------------------------------------------
 namespace boost
 {
 //------------------------------------------------------------------------------
 
-void copy_call_graph();
-void copy_flat_only ();
+void copy_call_graph( std::string const & input, std::string & output );
+void copy_flat_only ( std::string const & input, std::string & output );
 
 //------------------------------------------------------------------------------
 } // namespace boost
Modified: sandbox/tools/profile_templates2/src/postprocess.cpp
==============================================================================
--- sandbox/tools/profile_templates2/src/postprocess.cpp	(original)
+++ sandbox/tools/profile_templates2/src/postprocess.cpp	2011-08-02 08:03:41 EDT (Tue, 02 Aug 2011)
@@ -15,6 +15,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
 #undef BOOST_ENABLE_ASSERT_HANDLER
+//...zzz...#define BOOST_REGEX_USE_C_LOCALE
 
 #include "postprocess.hpp"
 
@@ -25,7 +26,6 @@
 #include <boost/ptr_container/ptr_vector.hpp>
 
 #include <string>
-#include <iostream>
 #include <fstream>
 #include <map>
 #include <set>
@@ -72,6 +72,8 @@
 
 #endif
 
+std::ofstream output;
+
 struct print {
     int* cummulative;
     int width;
@@ -79,7 +81,7 @@
     template<class T>
     void operator()(const T& t) {
         *cummulative += t.second;
-        std::cout << std::setw(width) << t.first << std::setw(10) << t.second << std::setw(10) << *cummulative << std::endl;
+        output << std::setw(width) << t.first << std::setw(10) << t.second << std::setw(10) << *cummulative << std::endl;
     }
 };
 
@@ -166,21 +168,16 @@
     node root;
 };
 
-int postprocess(int argc, char** argv) {
-    const char* input_file_name = 0;
-    bool use_call_graph = false;
-    for(int i = 1; i < argc; ++i) {
-        if(std::strcmp(argv[i], "--call-graph") == 0) {
-            use_call_graph = true;
-        } else {
-            input_file_name = argv[i];
-        }
-    }
-    if(input_file_name == 0) {
-        std::cerr << "Usage: " << argv[0] << " <input file>\n";
-        return(EXIT_FAILURE);
-    }
 
+void postprocess
+(
+    char const * const input_file_name,
+    char const * const output_file_name
+)
+{
+    bool const use_call_graph( true );
+
+    output.open( output_file_name );
 
     std::map<std::string, int> messages;
     std::string line;
@@ -199,10 +196,10 @@
     }
     std::vector<std::pair<std::string, int> > copy(messages.begin(), messages.end());
     std::sort(copy.begin(), copy.end(), compare());
-    std::cout << "Total instantiations: " << total_matches << std::endl;
+    output << "Total instantiations: " << total_matches << std::endl;
     int cummulative = 0;
-    std::cout << std::setw(max_match_length) << "Location" << std::setw(10) << "count" << std::setw(10) << "cum." << std::endl;
-    std::cout << std::setfill('-') << std::setw(max_match_length + 20) << '-' << std::setfill(' ') << std::endl;
+    output << std::setw(max_match_length) << "Location" << std::setw(10) << "count" << std::setw(10) << "cum." << std::endl;
+    output << std::setfill('-') << std::setw(max_match_length + 20) << '-' << std::setfill(' ') << std::endl;
     print p = { &cummulative, max_match_length };
     std::for_each(copy.begin(), copy.end(), p);
 
@@ -282,17 +279,17 @@
         std::vector<call_graph_node_t> call_graph;
         std::copy(graph.begin(), graph.end(), std::back_inserter(call_graph));
         std::sort(call_graph.begin(), call_graph.end(), call_graph_less());
-        std::cout << "\nCall Graph\n\n";
+        output << "\nCall Graph\n\n";
         BOOST_FOREACH(const call_graph_node_t& node, call_graph) {
-            std::cout << print_line_id(node.first) << " (" << node.second.count << ")\n";
+            output << print_line_id(node.first) << " (" << node.second.count << ")\n";
             typedef std::map<const line_id*, int>::const_reference node_t;
-            std::cout << "  Parents:\n";
+            output << "  Parents:\n";
             BOOST_FOREACH(node_t n, node.second.parents) {
-                std::cout << "    " << print_line_id(n.first) << " (" << n.second << ")\n";
+                output << "    " << print_line_id(n.first) << " (" << n.second << ")\n";
             }
-            std::cout << "  Children:\n";
+            output << "  Children:\n";
             BOOST_FOREACH(node_t n, node.second.children) {
-                std::cout << "    " << print_line_id(n.first) << " (" << n.second << "/" << graph[n.first].count << ")\n";
+                output << "    " << print_line_id(n.first) << " (" << n.second << "/" << graph[n.first].count << ")\n";
             }
         }
     }
Modified: sandbox/tools/profile_templates2/src/postprocess.hpp
==============================================================================
--- sandbox/tools/profile_templates2/src/postprocess.hpp	(original)
+++ sandbox/tools/profile_templates2/src/postprocess.hpp	2011-08-02 08:03:41 EDT (Tue, 02 Aug 2011)
@@ -21,7 +21,11 @@
 {
 //------------------------------------------------------------------------------
 
-void postprocess();
+void postprocess
+(
+    char const * input_file_name,
+    char const * output_file_name
+);
 
 //------------------------------------------------------------------------------
 } // namespace boost
Modified: sandbox/tools/profile_templates2/src/preprocess.cpp
==============================================================================
--- sandbox/tools/profile_templates2/src/preprocess.cpp	(original)
+++ sandbox/tools/profile_templates2/src/preprocess.cpp	2011-08-02 08:03:41 EDT (Tue, 02 Aug 2011)
@@ -19,6 +19,8 @@
 
 #define BOOST_XPRESSIVE_USE_C_TRAITS
 
+#include "preprocess.hpp"
+
 #include "boost/assert.hpp"
 #include "boost/concept_check.hpp"
 #include "boost/interprocess/file_mapping.hpp"
@@ -26,9 +28,10 @@
 #include "boost/range/iterator_range_core.hpp"
 #include "boost/xpressive/xpressive.hpp"
 
-#include <cassert>
 #include <iterator>
-#include <iostream>
+//------------------------------------------------------------------------------
+namespace boost
+{
 //------------------------------------------------------------------------------
 
 namespace regex
@@ -37,7 +40,8 @@
 
     cregex make_parens()
     {
-        cregex parens;// parens      = keep( '(' >> *keep( keep( +keep( ignored | ~(set= '(',')') ) | ( -!by_ref( parens ) ) ) ) >> ')' );
+        cregex parens; //parens = keep( '(' >> *keep( keep( +keep( ignored | ~(set= '(',')') ) | ( -!by_ref( parens ) ) ) ) >> ')' );
+        // Example from Xpressive documentation:
         parens =
         '('                            // is an opening parenthesis ...
          >>                           // followed by ...
@@ -77,7 +81,7 @@
     cregex const body_start = keep( *ws >> *(modifiers >> *ws) >> '{' );
 
     cregex const function_header = keep( start >> ( *body >> end ) >> body_start );
-}
+} // namespace regex
 
 struct formatter : boost::noncopyable
 {
@@ -113,7 +117,7 @@
             {
                 braces.push_back( " TEMPLATE_PROFILE_EXIT() }" );
                 static char const tail[] = " TEMPLATE_PROFILE_ENTER()";
-                out = std::copy( match.first      , match.second       , out );
+                out = std::copy( match.first         , match.second          , out );
                 out = std::copy( boost::begin( tail ), boost::end( tail ) - 1, out );
                 break;
             }
@@ -140,7 +144,7 @@
 };
 
 
-void preprocess( char const * const p_filename )
+void preprocess( char const * const p_filename, std::string & buffer )
 {
     using namespace boost;
 
@@ -154,17 +158,20 @@
         interprocess::read_only
     );
 
+    buffer.reserve( input_file_view.get_size() );
+
     iterator_range<char const *> input
     (
         static_cast<char const *>( input_file_view.get_address() ),
         static_cast<char const *>( input_file_view.get_address() ) + input_file_view.get_size()
     );
 
+    regex::match_results<char const *> search_results;
     using namespace regex;
     cregex const main_regex( (s1= ignored) | (s2=keep( class_header | function_header )) | (s3='{') | (s4='}') );
-    match_results<char const *> search_results;
 
-    std::cout << "#include <template_profiler.hpp>\n" << std::endl;
+    BOOST_ASSERT( buffer.empty() );
+    buffer = "#include <template_profiler.hpp>\n";
 
     // Implementation note:
     //   The whole file has to be searched at once in order to handle class/
@@ -172,10 +179,14 @@
     //                                    (01.08.2011.) (Domagoj Saric)
     regex_replace
     (
-        std::ostream_iterator<char>( std::cout ),
+        std::back_insert_iterator<std::string>( buffer ),
         input.begin(),
-        input.end(),
+        input.end  (),
         main_regex,
         formatter()
     );
 }
+
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
Modified: sandbox/tools/profile_templates2/src/preprocess.hpp
==============================================================================
--- sandbox/tools/profile_templates2/src/preprocess.hpp	(original)
+++ sandbox/tools/profile_templates2/src/preprocess.hpp	2011-08-02 08:03:41 EDT (Tue, 02 Aug 2011)
@@ -17,11 +17,13 @@
 #define preprocess_hpp__A0C9BD63_9A59_4F40_A70E_0026369C14C0
 #pragma once
 //------------------------------------------------------------------------------
+#include <string>
+//------------------------------------------------------------------------------
 namespace boost
 {
 //------------------------------------------------------------------------------
 
-void preprocess( char const * const p_filename );
+void preprocess( char const * p_filename, std::string & buffer );
 
 //------------------------------------------------------------------------------
 } // namespace boost
Modified: sandbox/tools/profile_templates2/src/profiler.cpp
==============================================================================
--- sandbox/tools/profile_templates2/src/profiler.cpp	(original)
+++ sandbox/tools/profile_templates2/src/profiler.cpp	2011-08-02 08:03:41 EDT (Tue, 02 Aug 2011)
@@ -14,25 +14,41 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //------------------------------------------------------------------------------
-#include "profiler.hpp"
-//------------------------------------------------------------------------------
-namespace boost
-{
-//------------------------------------------------------------------------------
-
 #undef BOOST_ENABLE_ASSERT_HANDLER
 
+#include "filter.hpp"
+#include "postprocess.hpp"
+#include "preprocess.hpp"
+
+#include "boost/assert.hpp"
+#include "boost/config.hpp"
+
+// POSIX implementation
+#ifdef BOOST_HAS_UNISTD_H
+    #include "sys/stat.h"
+    #include "unistd.h"
+#else
+    #include "io.h"
+#endif // BOOST_HAS_UNISTD_H
+#include "fcntl.h"
+#include "sys/stat.h"
+#include "sys/types.h"
+
 #include <cstdio>
 #include <cstdlib>
+#include <cstring>
 #include <exception>
 #include "process.h"
+#include <string>
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
 
 extern "C"
 int main( int const argc, char const * const argv[] )
 {
-    for ( unsigned i( 0 ); i < argc; ++i )
-        std::puts( argv[ i ] );
-    if ( argc != ( 1 + 3 ) )
+    if ( argc != ( 1 + 4 ) )
     {
         std::puts
         (
@@ -41,23 +57,67 @@
             "profiler\n"
                 "\t<compiler binary path>\n"
                 "\t<compiler response file with options to build the target source with>\n"
-                "\t<source to profile>."
+                "\t<source to profile>\n"
+                "\t<result file name>."
         );
         return EXIT_FAILURE;
     }
 
+    char const * const compiler_binary       ( argv[ 1 ] );
+    char const * const compiler_response_file( argv[ 2 ] );
+    char const * const source_to_profile     ( argv[ 3 ] );
+    char const * const result_file           ( argv[ 4 ] );
+
+    try
     {
-        char const * const compiler_argv[] = { "-E", argv[ 3 ], NULL };
-        int const result( /*std*/::execv( argv[ 1 ], compiler_argv ) );
-        if ( result != 0 )
+
+        static char const compiler_preprocessed_file[] = "template_profiler.compiler_preprocessed.i";
+
         {
-            std::puts( "Failed generating compiler preprocessed file." );
-            return EXIT_FAILURE;
+            std::string const full_command_line( std::string( compiler_binary ) + " " + source_to_profile + " @" + compiler_response_file + " -E > " + compiler_preprocessed_file );
+            int const result( /*std*/::system( full_command_line.c_str() ) );
+            if ( result != 0 )
+            {
+                std::puts( "Failed generating compiler preprocessed file." );
+                return EXIT_FAILURE;
+            }
         }
-    }
 
-    try
-    {
+        static char const prepared_file_to_compile[] = "template_profiler.preprocessed.cpp";
+        {
+            std::string preprocessed_input;
+            preprocess     ( compiler_preprocessed_file, preprocessed_input );
+            std::string filtered_input;
+            copy_call_graph( preprocessed_input, filtered_input );
+
+            int const file_id( /*std*/::open( prepared_file_to_compile, O_CREAT | O_WRONLY, S_IREAD | S_IWRITE ) );
+            if ( file_id < 0 )
+            {
+                std::puts( "Failed creating an intermediate file." );
+                return EXIT_FAILURE;
+            }
+            int const write_result( /*std*/::write( file_id, &filtered_input[ 0 ], filtered_input.size() ) );
+            BOOST_VERIFY( /*std*/::close( file_id ) == 0 );
+            if ( write_result < 0 )
+            {
+                std::puts( "Failed writing to an intermediate file." );
+                return EXIT_FAILURE;
+            }
+        }
+
+        static char const final_compiler_output[] = "template_profiler.final_compiler_output.txt";
+        {
+            std::string const full_command_line( std::string( compiler_binary ) + " " + prepared_file_to_compile + " @" + compiler_response_file + " > " + final_compiler_output );
+            int const result( /*std*/::system( full_command_line.c_str() ) );
+            if ( result != 0 )
+            {
+                std::puts( "Failed compiling an intermediate file." );
+                return EXIT_FAILURE;
+            }
+        }
+
+        postprocess( final_compiler_output, result_file );
+
         return EXIT_SUCCESS;
     }
     catch ( std::exception const & e )