|
Boost-Commit : |
From: steven_at_[hidden]
Date: 2008-05-09 15:28:06
Author: steven_watanabe
Date: 2008-05-09 15:28:05 EDT (Fri, 09 May 2008)
New Revision: 45254
URL: http://svn.boost.org/trac/boost/changeset/45254
Log:
imported into sandbox svn
Added:
sandbox/tools/profile_templates/
sandbox/tools/profile_templates/preprocess.cpp (contents, props changed)
sandbox/tools/profile_templates/preprocess.pl (contents, props changed)
sandbox/tools/profile_templates/profile_templates.jam (contents, props changed)
sandbox/tools/profile_templates/src/
sandbox/tools/profile_templates/src/Jamfile.v2 (contents, props changed)
sandbox/tools/profile_templates/src/postprocess.cpp (contents, props changed)
sandbox/tools/profile_templates/template_profiler.hpp (contents, props changed)
sandbox/tools/profile_templates/test/
sandbox/tools/profile_templates/test/Jamfile.v2 (contents, props changed)
sandbox/tools/profile_templates/test/test.cpp (contents, props changed)
sandbox/tools/profile_templates/test/test_dir/
sandbox/tools/profile_templates/test/test_dir/test.hpp (contents, props changed)
Added: sandbox/tools/profile_templates/preprocess.cpp
==============================================================================
--- (empty file)
+++ sandbox/tools/profile_templates/preprocess.cpp 2008-05-09 15:28:05 EDT (Fri, 09 May 2008)
@@ -0,0 +1,21 @@
+#include <boost/regex.hpp>
+#include <string>
+#include <iostream>
+#include <map>
+#include <iterator>
+#include <algorithm>
+
+boost::regex brace("{");
+
+int main(int argc, const char* argv) {
+ std::string input;
+
+ {
+ std::fstream in(argv[1]);
+ input.assign(std::istreambuf_iterator<char>(in.rdbuf), std::istreambuf_iterator<char>());
+ }
+
+ for()
+ boost::smatch match;
+ std::cout << boost::regex_replace(input, match, brace, "{ PROFILE_TRACER(); ") << std::endl;
+}
Added: sandbox/tools/profile_templates/preprocess.pl
==============================================================================
--- (empty file)
+++ sandbox/tools/profile_templates/preprocess.pl 2008-05-09 15:28:05 EDT (Fri, 09 May 2008)
@@ -0,0 +1,28 @@
+# preprocess.pl
+#
+# Copyright (c) 2008
+# Steven Watanabe
+#
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+#add "~" to the end of the backup file name
+$^I = "~";
+
+#read the whole file at once
+undef $/;
+
+$backslashed_lines = qr/(?>(?>\\(?>\n|\r\n)|.)*)/;
+$string = qr/(?:\"(?>\\\\|\\\"|[^\"])*\"|'(?>\\\\|\\'|[^'])*')/;
+$comment = qr{(?>//$backslashed_lines|/\*(?>[^*]|\*(?!/))*\*/)}; #as far as we are concerned any text between off and on is a comment
+$pp = qr/(?:#$backslashed_lines)/;
+$ignored = qr/(?>$string|$comment|$pp)/;
+
+
+while(<>) {
+ s/($ignored)|((?:class|struct)[^\{;()#]*\{)/$1?$1:"$2 PROFILE_TRACER\(\); "/ge;
+ print "#include <template_profiler.hpp>\n";
+ print;
+}
+
Added: sandbox/tools/profile_templates/profile_templates.jam
==============================================================================
--- (empty file)
+++ sandbox/tools/profile_templates/profile_templates.jam 2008-05-09 15:28:05 EDT (Fri, 09 May 2008)
@@ -0,0 +1,207 @@
+# profile_templates.jam
+#
+# Copyright (c) 2008
+# Steven Watanabe
+#
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import numbers ;
+import regex ;
+import property-set ;
+import sequence ;
+import type ;
+import "class" : new ;
+import generators ;
+import virtual-target ;
+import path ;
+import project ;
+import toolset : flags ;
+import os ;
+import feature ;
+import modules ;
+import errors ;
+
+type.register INSTRUMENTED_TEMPLATE_HPP : : HPP ;
+
+type.set-generated-target-suffix INSTRUMENTED_TEMPLATE_HPP : : hpp ;
+
+.empty = [ property-set.empty ] ;
+
+module-location = [ path.parent [ path.make [ modules.binding profile_templates ] ] ] ;
+
+PREPROCESS-ACTION = perl [ path.native [ path.join $(module-location) preprocess.pl ] ] ;
+
+class instrumented_template_generator : generator {
+ rule __init__ ( ) {
+ generator.__init__ instrumented_template_generator : HPP : INSTRUMENTED_TEMPLATE_HPP ;
+ }
+ rule run ( project name : properties : sources * : multiple ? ) {
+ local new-a = [ new non-scanning-action $(sources) : profile_templates.transform-copy :
+ $(.empty) ] ;
+ return [ new file-target $(name) exact : INSTRUMENTED_TEMPLATE_HPP : $(project) : $(new-a) ] ;
+ }
+}
+
+instrument-generator = [ new instrumented_template_generator ] ;
+
+rule is-noninclude ( property ) {
+ if [ regex.match "(.*<include>.*)" : $(property) : ] {
+ return ;
+ } else {
+ return 1 ;
+ }
+}
+
+rule transform_properties ( properties : curr_project ) {
+ local includes = [ $(properties).get <include> ] ;
+ local new-props = <include>$(module-location) ;
+ local build-dir = [ $(curr_project).build-dir ] ;
+ for local dir in $(includes) {
+ local new-dir = [ get-new-dir ] ;
+ local new-include-dir = [ path.join $(build-dir) $(new-dir) ] ;
+ new-props += <include>$(new-include-dir)&&$(dir) ;
+ local dep = [ transform-dir $(dir) : $(new-dir) : $(curr_project) ] ;
+ new-props += <dependency>$(dep) ;
+ }
+ local raw-props = [ $(properties).raw ] ;
+ local without-include = [ property-set.create [ sequence.filter is-noninclude : $(raw-props) ] ] ;
+ local result = [ $(without-include).refine [ property-set.create $(new-props) ] ] ;
+ return $(result) ;
+}
+
+rule transform-copy {
+}
+
+actions transform-copy {
+ "$(PREPROCESS-ACTION)" <"$(>)" >"$(<)"
+}
+
+.next-dir-num = 0 ;
+
+rule get-new-dir {
+ local result = profile_tmp_dir$(.next-dir-num) ;
+ .next-dir-num = [ numbers.increment .next-dir-num ] ;
+ return $(result) ;
+}
+
+rule transform-dir ( old-dir : new-dir : current-project ) {
+ local headers = [ path.glob-tree $(old-dir) : *.hpp : profile_tmp_dir* ] ;
+ local result = ;
+ for local h in $(headers) {
+ local relative = [ path.relative $(h) $(old-dir) ] ;
+ local new-header = [ path.join $(new-dir) $(relative) ] ;
+ local file-target = [ virtual-target.from-file $(h) : [ $(current-project).get source-location ] : $(current-project) ] ;
+ result += [ $(instrument-generator).run $(current-project) $(new-header) : $(.empty) : $(file-target) ] ;
+ }
+ return $(result) ;
+}
+
+type.register RAW_TEMPLATE_PROFILE : rtp ;
+
+class warn-generator : generator {
+
+ import profile_templates ;
+
+ rule __init__ ( ) {
+ generator.__init__ profile_templates.build-generic : CPP : RAW_TEMPLATE_PROFILE ;
+ }
+ rule run ( project name : properties : sources * : multiple ? ) {
+ local new-properties = [ profile_templates.transform_properties $(properties) : $(project) ] ;
+ local toolset = [ $(new-properties).get <toolset> ] ;
+ if ! $(toolset) {
+ errors.error "No toolset specified" ;
+ }
+ switch $(toolset) {
+ case msvc* :
+ toolset = msvc ;
+ case gcc* :
+ toolset = gcc ;
+ case * :
+ errors.error unrecognized toolset $(toolset) ;
+ }
+ return [ generator.run $(project) $(name) : [ $(new-properties).add-raw <profile-template-toolset>$(toolset) ] : $(sources) : $(multiple) ] ;
+ }
+}
+
+generators.register [ new warn-generator ] ;
+
+feature.feature <profile-template-toolset> : msvc gcc : free ;
+
+flags profile_templates.build-generic INVOCATION-COMMAND <profile-template-toolset>msvc : cl /W4 /c /D PROFILE_TEMPLATES ;
+flags profile_templates.build-generic INCLUDE-COMMAND <profile-template-toolset>msvc : /I ;
+
+flags profile_templates.build-generic INVOCATION-COMMAND <profile-template-toolset>gcc : g++ -Wall -c -D PROFILE_TEMPLATES ;
+flags profile_templates.build-generic INCLUDE-COMMAND <profile-template-toolset>gcc : -I ;
+
+flags profile_templates.build-generic INCLUDES <include> ;
+
+rule build-generic {
+}
+
+actions build-generic {
+ $(INVOCATION-COMMAND) "$(INCLUDE-COMMAND)$(INCLUDES)" "$(>)" >"$(<)" 2>&1
+}
+
+flags profile_templates.build-msvc INCLUDES <include> ;
+
+type.register TEMPLATE_PROFILE : tp ;
+
+class final_profile_generator : generator {
+
+ import targets ;
+ import profile_templates ;
+ import path ;
+ import modules ;
+
+ rule __init__ ( ) {
+ generator.__init__ profile_templates.process_raw_profile : RAW_TEMPLATE_PROFILE : TEMPLATE_PROFILE ;
+ }
+ rule run ( project name : properties : sources * : multiple ? ) {
+
+ current_path = [ modules.peek profile_templates : module-location ] ;
+
+ local postprocess-main-target = [ targets.resolve-reference [ path.join $(current_path) src ] : $(project) ] ;
+ postprocess-main-target = [ $(postprocess-main-target[1]).main-target postprocess ] ;
+ local postprocess-binary-dependencies = [ $(postprocess-main-target).generate [ $(properties).propagated ] ] ;
+ postprocess-binary-dependencies = $(postprocess-binary-dependencies[2-]) ;
+ local postprocess-binary = ;
+
+ for local target in $(postprocess-binary-dependencies) {
+ if [ $(target).type ] = EXE {
+ postprocess-binary =
+ [ path.native
+ [ path.join
+ [ $(target).path ]
+ [ $(target).name ]
+ ]
+ ] ;
+ }
+ }
+
+ if ! $(postprocess-binary) {
+ errors.error Could not find postprocessor binary ;
+ }
+
+ switch [ $(properties).get <target-os> ] {
+ case cygwin :
+ }
+
+ local new-properties = [ $(properties).add-raw <dependency>$(postprocess-binary-dependencies) <postprocess-binary>$(postprocess-binary) ] ;
+ return [ generator.run $(project) $(name) : $(new-properties) : $(sources) : $(multiple) ] ;
+ }
+}
+
+generators.register [ new final_profile_generator ] ;
+
+feature.feature <postprocess-binary> : : path incidental ;
+
+flags profile_templates.process_raw_profile POSTPROCESS-BINARY <postprocess-binary> ;
+
+rule process_raw_profile {
+}
+
+actions process_raw_profile {
+ "$(POSTPROCESS-BINARY)" <"$(>)" >"$(<)"
+}
Added: sandbox/tools/profile_templates/src/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/tools/profile_templates/src/Jamfile.v2 2008-05-09 15:28:05 EDT (Fri, 09 May 2008)
@@ -0,0 +1,13 @@
+# Jamfile.v2
+#
+# Copyright (c) 2008
+# Steven Watanabe
+#
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+project src : :
+ requirements <include>$(BOOST_ROOT) <link>static ;
+
+exe postprocess : postprocess.cpp $(BOOST_ROOT)/libs/regex/build//boost_regex ;
Added: sandbox/tools/profile_templates/src/postprocess.cpp
==============================================================================
--- (empty file)
+++ sandbox/tools/profile_templates/src/postprocess.cpp 2008-05-09 15:28:05 EDT (Fri, 09 May 2008)
@@ -0,0 +1,57 @@
+#include <boost/regex.hpp>
+#include <string>
+#include <iostream>
+#include <map>
+#include <exception>
+#include <iterator>
+#include <algorithm>
+
+#ifdef _MSC_VER
+
+boost::regex warning_message("(.*) : warning C4150: deletion of pointer to incomplete type 'template_profiler::incomplete'; no destructor called");
+
+#elif defined(__GNUC__)
+
+boost::regex warning_message("(.*): warning: division by zero in `template_profiler_value / 0'");
+
+#else
+
+#error Unknown Compiler
+
+#endif
+
+struct print {
+ int* cummulative;
+ typedef void result_type;
+ template<class T>
+ void operator()(const T& t) {
+ *cummulative += t.second;
+ std::cout << t.first << ' ' << t.second << " " << *cummulative << std::endl;
+ }
+};
+
+struct compare {
+ template<class T>
+ bool operator()(const T& lhs, const T& rhs) const {
+ return(lhs.second > rhs.second);
+ }
+};
+
+int main() {
+ std::map<std::string, int> messages;
+ std::string line;
+ int total_matches = 0;
+ while(std::getline(std::cin, line)) {
+ boost::smatch match;
+ if(boost::regex_match(line, match, warning_message)) {
+ ++messages[match[1]];
+ ++total_matches;
+ }
+ }
+ 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;
+ int cummulative = 0;
+ print p = { &cummulative };
+ std::for_each(copy.begin(), copy.end(), p);
+}
Added: sandbox/tools/profile_templates/template_profiler.hpp
==============================================================================
--- (empty file)
+++ sandbox/tools/profile_templates/template_profiler.hpp 2008-05-09 15:28:05 EDT (Fri, 09 May 2008)
@@ -0,0 +1,24 @@
+#ifndef TEMPLATE_PROFILER_HPP_INLUCDED
+#define TEMPLATE_PROFILER_HPP_INLUCDED
+
+namespace template_profiler {
+ struct incomplete;
+}
+
+#ifdef PROFILE_TEMPLATES
+
+#if defined(_MSC_VER)
+ #define PROFILE_TRACER() enum template_profiler_test { template_profiler_value = sizeof(delete ((::template_profiler::incomplete*)0),0) };
+#elif defined(__GNUC__)
+ #define PROFILE_TRACER() struct template_profiler_test { int f() { int template_profiler_value = 1; return template_profiler_value/0; } };
+#else
+ #error Unknown compiler
+#endif
+
+#else
+
+ #define PROFILE_TRACER()
+
+#endif
+
+#endif
Added: sandbox/tools/profile_templates/test/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/tools/profile_templates/test/Jamfile.v2 2008-05-09 15:28:05 EDT (Fri, 09 May 2008)
@@ -0,0 +1,13 @@
+# Jamfile.v2
+#
+# Copyright (c) 2008
+# Steven Watanabe
+#
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import modules ;
+modules.load profile_templates : ../profile_templates.jam ;
+
+template-profile test : test.cpp : <include>test_dir ;
Added: sandbox/tools/profile_templates/test/test.cpp
==============================================================================
--- (empty file)
+++ sandbox/tools/profile_templates/test/test.cpp 2008-05-09 15:28:05 EDT (Fri, 09 May 2008)
@@ -0,0 +1,5 @@
+#include <test.hpp>
+
+int main() {
+ X<int> x;
+}
Added: sandbox/tools/profile_templates/test/test_dir/test.hpp
==============================================================================
--- (empty file)
+++ sandbox/tools/profile_templates/test/test_dir/test.hpp 2008-05-09 15:28:05 EDT (Fri, 09 May 2008)
@@ -0,0 +1,8 @@
+// class
+namespace {
+}
+
+template<class T>
+struct X {};
+
+struct Y {};
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