Boost logo

Boost-Commit :

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 )


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk