File indexing completed on 2024-05-19 12:20:44
0001 ## 0002 # This file is part of KDevelop 0003 # Copyright (C) 2013-2015 Miquel Sabaté Solà <mikisabate@gmail.com> 0004 # 0005 # This program is free software: you can redistribute it and/or modify 0006 # it under the terms of the GNU General Public License as published by 0007 # the Free Software Foundation, either version 3 of the License, or 0008 # (at your option) any later version. 0009 # 0010 # This program is distributed in the hope that it will be useful, 0011 # but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 # GNU General Public License for more details. 0014 # 0015 # You should have received a copy of the GNU General Public License 0016 # along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 0018 0019 require 'find' 0020 require 'fileutils' 0021 require 'benchmark' 0022 0023 0024 # This script can be called as follows: 0025 # --syntax -> check that there's no syntax error when parsing the Ruby 0026 # standard library. 0027 # --valgrind -> generate files inside the /tmp/kdev-ruby directory containing 0028 # the results as given by memcheck, massif and callgrind. 0029 # There's also the --memcheck, --massif and --callgrind options to run only the 0030 # specified tool instead of all of them. 0031 0032 0033 # Public: Print beautifully 0034 # 0035 # msg - A String containing the message to be printed. 0036 # error - True if this is an error message, false otherwise (Default: false) 0037 def putb(msg, error = false) 0038 num = error ? 31 : 32 0039 puts "\033[#{num}m#{msg}\033[0m" 0040 end 0041 0042 # Returns true if our beloved user requested some candy from valgrind. 0043 # 0044 # param - A String containing the name of the tool. 0045 def valgrind(param) 0046 ARGV.include?("--#{param}") || ARGV.include?('--valgrind') 0047 end 0048 0049 # Public: execute a valgrind tool. 0050 # 0051 # tool - A String containing the name of the Valgrind's tool. 0052 # opts - A String containing the options to be passed to Valgrind. 0053 # file - A String containing the path to the log file. 0054 def execute(tool, opts, file) 0055 FileUtils.rm_rf file 0056 putb "Calling Valgrind\'s #{tool} tool with: #{opts}" 0057 `valgrind #{opts} #{PARSER} #{TMP} 1` 0058 putb "#{tool.capitalize} output left at #{file}" unless file.empty? 0059 end 0060 0061 0062 # Setup some basic constants 0063 TMP_D = '/tmp/kdev-ruby' 0064 TMP = File.join(TMP_D, 'stdlib.rb') 0065 PARSER = '../ruby-parser' 0066 if ENV['MRI'].nil? 0067 putb 'You have to set the MRI environment variable.', true 0068 exit 0069 end 0070 LIB = File.join(ENV['MRI'], 'lib/') 0071 0072 0073 # If the -c parameter has been passed, just check the syntax for each of 0074 # the files inside the MRI lib/ directory. 0075 if ARGV.include? '--syntax' 0076 res = { fails: 0, oks: 0 } 0077 Find.find(LIB) do |path| 0078 if path.end_with? '.rb' 0079 print "#{path.gsub(LIB, '')} " 0080 got = `#{PARSER} #{path}` 0081 0082 if got.include? 'syntax error' 0083 puts '=> Fail!' 0084 res[:fails] += 1 0085 else 0086 puts '=> OK' 0087 res[:oks] += 1 0088 end 0089 end 0090 end 0091 0092 totals = (res[:oks] + res[:fails]).to_f 0093 win = (100 * res[:oks].to_f/ totals).round(2) 0094 damn = (100 * res[:fails].to_f/ totals).round(2) 0095 puts "Holy says: Oks: #{res[:oks]} (#{win}%), Fails: #{res[:fails]} (#{damn}%)" 0096 exit 0097 end 0098 0099 # Generate the stdlib file 0100 putb "Generating temporary file '#{TMP}' from '#{LIB}'" 0101 FileUtils.mkdir_p TMP_D 0102 FileUtils.rm_rf TMP 0103 File.open(TMP, 'a+', 0644) do |f| 0104 Find.find(LIB) do |path| 0105 next unless path.end_with? '.rb' 0106 # Writing to the file. Note that we remove __END__ so it doesn't stop 0107 # at the middle of the script. 0108 f.write IO.read(path).gsub('__END__', '') 0109 end 0110 end 0111 ok = false 0112 0113 # 0114 # Valgrind is in da house ! 0115 # 0116 0117 if valgrind 'memcheck' 0118 file = File.join(TMP_D, 'memcheck.txt') 0119 opts = "--track-origins=yes --tool=memcheck --leak-check=full --show-reachable=yes -v --log-file=#{file}" 0120 execute 'memcheck', opts, file 0121 ok = true 0122 end 0123 0124 if valgrind 'callgrind' 0125 callgrind = File.join(TMP_D, 'callgrind.out') 0126 opts = '--tool=callgrind -q -v --dump-instr=yes' 0127 execute 'callgrind', opts, callgrind 0128 out = Dir.glob("#{File.expand_path(File.dirname(__FILE__))}/callgrind*").first 0129 FileUtils.mv out, callgrind 0130 ok = true 0131 end 0132 0133 if valgrind 'massif' 0134 massif = File.join(TMP_D, 'massif.out') 0135 opts = '--tool=massif --tool=massif -q -v --stacks=yes' 0136 execute 'massif', opts, massif 0137 out = Dir.glob("#{File.expand_path(File.dirname(__FILE__))}/massif*").first 0138 FileUtils.mv out, massif 0139 ok = true 0140 end 0141 0142 # 0143 # Benchmarking like a boss 0144 # 0145 0146 if ARGV.include? '--bench' 0147 Benchmark.bm do |x| 0148 x.report('parser: ') { 10.times { `#{PARSER} #{TMP}` } } 0149 end 0150 ok = true 0151 end 0152 0153 # Try to GTFO ! 0154 exit if ok 0155 0156 # 0157 # Wow ! You're a looser !! 0158 # 0159 puts <<-USAGE 0160 Usage: ruby holy.rb [options] 0161 --syntax \t Just check the syntax parsing. 0162 --bench \t Let's benchmark this thing ! 0163 --valgrind \t Execute all the tools from Valgrind that we're able to execute. 0164 --memcheck \t Just call Valgrind's memcheck tool. 0165 --massif \t Just call Valgrind's massif tool. 0166 --callgrind \t Just call Valgrind's callgrind tool. 0167 USAGE