|
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