bake-toolkit 1.8.0.1 → 2.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/bake +14 -53
- data/bin/bakery +50 -43
- data/bin/createVSProjects +3 -3
- data/doc/cmd/install.html +1 -5
- data/doc/cmd/usecmd.html +29 -5
- data/doc/dyk/lint.html +21 -4
- data/doc/dyk/tipps.html +0 -6
- data/doc/eclipse/import.html +3 -1
- data/doc/eclipse/import/Import.png +0 -0
- data/doc/eclipse/use.html +8 -5
- data/doc/further/change.html +134 -1
- data/doc/further/issues.html +1 -0
- data/doc/further/wish.html +24 -21
- data/doc/index.html +1 -1
- data/doc/syntax/subst.html +8 -1
- data/doc/syntax/syntax.html +42 -14
- data/lib/bake/cache.rb +51 -59
- data/lib/bake/config/loader.rb +289 -0
- data/lib/bake/libElement.rb +134 -0
- data/lib/bake/mergeConfig.rb +1 -1
- data/lib/bake/model/language.rb +1 -1
- data/lib/bake/model/loader.rb +88 -0
- data/lib/bake/model/metamodel.rb +24 -16
- data/lib/bake/model/metamodel_ext.rb +9 -4
- data/lib/bake/options/options.rb +222 -0
- data/lib/bake/options/showConfigNames.rb +44 -0
- data/lib/bake/options/showDoc.rb +19 -0
- data/lib/bake/options/showLicense.rb +9 -0
- data/lib/bake/options/showToolchains.rb +39 -0
- data/lib/bake/options/usage.rb +54 -0
- data/lib/bake/process_output.rb +10 -0
- data/lib/bake/subst.rb +105 -40
- data/lib/bake/toolchain/clang.rb +44 -0
- data/lib/bake/toolchain/colorizing_formatter.rb +125 -0
- data/lib/bake/toolchain/diab.rb +53 -0
- data/lib/bake/toolchain/errorparser/diab_compiler_error_parser.rb +40 -0
- data/lib/bake/toolchain/errorparser/diab_linker_error_parser.rb +41 -0
- data/lib/bake/toolchain/errorparser/error_parser.rb +71 -0
- data/lib/bake/toolchain/errorparser/gcc_compiler_error_parser.rb +35 -0
- data/lib/bake/toolchain/errorparser/gcc_linker_error_parser.rb +35 -0
- data/lib/bake/toolchain/errorparser/greenhills_compiler_error_parser.rb +32 -0
- data/lib/bake/toolchain/errorparser/greenhills_linker_error_parser.rb +44 -0
- data/lib/bake/toolchain/errorparser/keil_compiler_error_parser.rb +40 -0
- data/lib/bake/toolchain/errorparser/keil_linker_error_parser.rb +30 -0
- data/lib/bake/toolchain/errorparser/lint_error_parser.rb +34 -0
- data/lib/bake/toolchain/errorparser/process_output.rb +3 -0
- data/lib/bake/toolchain/errorparser/ti_compiler_error_parser.rb +30 -0
- data/lib/bake/toolchain/errorparser/ti_linker_error_parser.rb +30 -0
- data/lib/bake/toolchain/gcc.rb +49 -0
- data/lib/bake/toolchain/gcc_param.rb +7 -0
- data/lib/bake/toolchain/greenhills.rb +52 -0
- data/lib/bake/toolchain/keil.rb +55 -0
- data/lib/bake/toolchain/lint.rb +20 -0
- data/lib/bake/toolchain/provider.rb +136 -0
- data/lib/bake/toolchain/ti.rb +47 -0
- data/lib/bake/util.rb +27 -15
- data/lib/bakery/buildPattern.rb +1 -1
- data/lib/bakery/model/language.rb +1 -1
- data/lib/bakery/model/loader.rb +56 -0
- data/lib/bakery/model/metamodel.rb +1 -1
- data/lib/bakery/options/options.rb +87 -0
- data/lib/bakery/toBake.rb +10 -6
- data/lib/blocks/block.rb +225 -0
- data/lib/blocks/blockBase.rb +155 -0
- data/lib/blocks/commandLine.rb +25 -0
- data/lib/blocks/compile.rb +382 -0
- data/lib/blocks/docu.rb +28 -0
- data/lib/blocks/executable.rb +143 -0
- data/lib/blocks/has_execute_command.rb +31 -0
- data/lib/blocks/library.rb +78 -0
- data/lib/blocks/lint.rb +53 -0
- data/lib/blocks/makefile.rb +87 -0
- data/lib/blocks/showIncludes.rb +114 -0
- data/lib/common/abortException.rb +4 -0
- data/lib/common/cleanup.rb +9 -0
- data/lib/common/exit_helper.rb +28 -0
- data/lib/common/ext/file.rb +88 -0
- data/lib/common/ext/stdout.rb +45 -0
- data/lib/common/ide_interface.rb +194 -0
- data/lib/common/options/option.rb +13 -0
- data/lib/common/options/parser.rb +59 -0
- data/lib/common/process.rb +64 -0
- data/lib/common/utils.rb +52 -0
- data/lib/{bake → common}/version.rb +3 -10
- data/lib/multithread/job.rb +44 -0
- data/lib/tocxx.rb +201 -932
- data/lib/vs/options.rb +3 -2
- data/license.txt +47 -22
- metadata +90 -30
- data/bin/bake-doc +0 -12
- data/lib/alias/loader.rb +0 -56
- data/lib/alias/model/language.rb +0 -22
- data/lib/alias/model/metamodel.rb +0 -29
- data/lib/bake/loader.rb +0 -92
- data/lib/bake/options.rb +0 -421
- data/lib/bakery/loader.rb +0 -57
- data/lib/bakery/options.rb +0 -105
- data/lib/option/parser.rb +0 -73
@@ -0,0 +1,31 @@
|
|
1
|
+
module Bake
|
2
|
+
|
3
|
+
module Blocks
|
4
|
+
|
5
|
+
module HasExecuteCommand
|
6
|
+
|
7
|
+
def executeCommand(commandLine, ignoreStr=nil)
|
8
|
+
puts commandLine if not Bake.options.verboseLow
|
9
|
+
puts "(executed in '#{@projectDir}')" if Bake.options.verboseHigh
|
10
|
+
cmd_result = false
|
11
|
+
output = ""
|
12
|
+
begin
|
13
|
+
Dir.chdir(@projectDir) do
|
14
|
+
cmd_result, output = ProcessHelper.run([commandLine], true)
|
15
|
+
end
|
16
|
+
rescue Exception=>e
|
17
|
+
puts e.message
|
18
|
+
puts e.backtrace if Bake.options.debug
|
19
|
+
end
|
20
|
+
|
21
|
+
if (cmd_result == false and (not ignoreStr or not output.include?ignoreStr))
|
22
|
+
Bake.formatter.printError("Command \"#{commandLine}\" failed", @config)
|
23
|
+
puts "(executed in '#{@projectDir}')" if not Bake.options.verboseHigh
|
24
|
+
raise SystemCommandFailed.new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'blocks/blockBase'
|
2
|
+
|
3
|
+
module Bake
|
4
|
+
|
5
|
+
module Blocks
|
6
|
+
|
7
|
+
class Library < BlockBase
|
8
|
+
|
9
|
+
def initialize(block, config, referencedConfigs, tcs, compileBlock)
|
10
|
+
super(block,config, referencedConfigs, tcs)
|
11
|
+
@compileBlock = compileBlock
|
12
|
+
|
13
|
+
block.set_library(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
def archive_name()
|
17
|
+
@archive_name ||= File.join([@output_dir, "lib#{@projectName}.a"])
|
18
|
+
end
|
19
|
+
|
20
|
+
def needed?
|
21
|
+
return false if Bake.options.linkOnly
|
22
|
+
return false if Bake.options.prepro
|
23
|
+
|
24
|
+
# lib
|
25
|
+
return "because library does not exist" if not File.exists?(archive_name)
|
26
|
+
|
27
|
+
aTime = File.mtime(archive_name)
|
28
|
+
|
29
|
+
# config
|
30
|
+
return "because config file has been changed" if aTime < File.mtime(@config.file_name)
|
31
|
+
return "because DefaultToolchain has been changed" if aTime < Bake::Config.defaultToolchainTime
|
32
|
+
|
33
|
+
# sources
|
34
|
+
@compileBlock.objects.each do |obj|
|
35
|
+
return "because object #{obj} does not exist" if not File.exists?(obj)
|
36
|
+
return "because object #{obj} is newer than executable" if aTime < File.mtime(obj)
|
37
|
+
end
|
38
|
+
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
def execute
|
43
|
+
|
44
|
+
Dir.chdir(@projectDir) do
|
45
|
+
reason = needed?
|
46
|
+
return unless reason
|
47
|
+
|
48
|
+
prepareOutput(archive_name)
|
49
|
+
|
50
|
+
archiver = @tcs[:ARCHIVER]
|
51
|
+
|
52
|
+
cmd = Utils.flagSplit(archiver[:COMMAND], false) # ar
|
53
|
+
cmd += Bake::Utils::flagSplit(archiver[:FLAGS],true) # --all_load
|
54
|
+
cmd += archiver[:ARCHIVE_FLAGS].split(" ")
|
55
|
+
cmd << archive_name
|
56
|
+
cmd += @compileBlock.objects
|
57
|
+
|
58
|
+
success, consoleOutput = ProcessHelper.run(cmd, false, false)
|
59
|
+
process_result(cmd, consoleOutput, archiver[:ERROR_PARSER], "Creating #{archive_name}", reason, success)
|
60
|
+
|
61
|
+
check_config_file()
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def clean
|
66
|
+
Dir.chdir(@projectDir) do
|
67
|
+
if File.exist?@output_dir
|
68
|
+
puts "Deleting folder #{@output_dir}" if Bake.options.verboseHigh
|
69
|
+
FileUtils.rm_rf(@output_dir)
|
70
|
+
end
|
71
|
+
end unless Bake.options.filename
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
data/lib/blocks/lint.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'blocks/compile'
|
2
|
+
|
3
|
+
module Bake
|
4
|
+
module Blocks
|
5
|
+
class Lint < Compile
|
6
|
+
|
7
|
+
def initialize(block, config, referencedConfigs, tcs)
|
8
|
+
super(block,config, referencedConfigs, tcs)
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute
|
12
|
+
Dir.chdir(@projectDir) do
|
13
|
+
compiler = @tcs[:COMPILER][:CPP]
|
14
|
+
calcSources
|
15
|
+
|
16
|
+
noFilesToLint = (@source_files.length == 0)
|
17
|
+
|
18
|
+
if Bake.options.lint_min >= 1 and Bake.options.lint_min >= @source_files.length
|
19
|
+
noFilesToLint = true
|
20
|
+
end
|
21
|
+
|
22
|
+
if Bake.options.lint_max >= 0 and Bake.options.lint_max < Bake.options.lint_min
|
23
|
+
noFilesToLint = true
|
24
|
+
end
|
25
|
+
|
26
|
+
if noFilesToLint
|
27
|
+
Bake.formatter.printInfo("No files to lint", @config)
|
28
|
+
else
|
29
|
+
@source_files = @source_files[Bake.options.lint_min..Bake.options.lint_max]
|
30
|
+
|
31
|
+
cmd = [compiler[:COMMAND]]
|
32
|
+
cmd += compiler[:COMPILE_FLAGS]
|
33
|
+
|
34
|
+
cmd += @include_array[:CPP]
|
35
|
+
cmd += @define_array[:CPP]
|
36
|
+
|
37
|
+
cmd += @tcs[:LINT_POLICY]
|
38
|
+
|
39
|
+
cmd += @source_files
|
40
|
+
|
41
|
+
printCmd(cmd, "Linting #{@source_files.length} file(s)...", nil, false)
|
42
|
+
success, consoleOutput = ProcessHelper.run(cmd, false)
|
43
|
+
process_result(cmd, consoleOutput, compiler[:ERROR_PARSER], "Linting...", nil, success)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def clean
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'blocks/has_execute_command'
|
2
|
+
|
3
|
+
module Bake
|
4
|
+
module Blocks
|
5
|
+
|
6
|
+
class Makefile
|
7
|
+
include HasExecuteCommand
|
8
|
+
|
9
|
+
MAKE_COMMAND = "make"
|
10
|
+
MAKE_FILE_FLAG = "-f"
|
11
|
+
MAKE_DIR_FLAG = "-C"
|
12
|
+
MAKE_CLEAN = "clean"
|
13
|
+
|
14
|
+
def initialize(config, referencedConfigs, block)
|
15
|
+
@config = config
|
16
|
+
@projectDir = config.get_project_dir
|
17
|
+
@path_to = ""
|
18
|
+
@flags = adjustFlags("",config.flags) if config.flags
|
19
|
+
@makefile = config.name
|
20
|
+
@target = config.target != "" ? config.target : "all"
|
21
|
+
calcPathTo(referencedConfigs)
|
22
|
+
calcCommandLine
|
23
|
+
calcCleanLine
|
24
|
+
|
25
|
+
block.lib_elements[config.line_number] = [LibElement.new(LibElement::LIB_WITH_PATH, config.lib)] if config.lib != ""
|
26
|
+
end
|
27
|
+
|
28
|
+
def calcCommandLine
|
29
|
+
@commandLine = remove_empty_strings_and_join([
|
30
|
+
MAKE_COMMAND, @target,
|
31
|
+
@flags,
|
32
|
+
MAKE_DIR_FLAG, File.dirname(@makefile),
|
33
|
+
MAKE_FILE_FLAG, File.basename(@makefile),
|
34
|
+
@path_to])
|
35
|
+
end
|
36
|
+
|
37
|
+
def calcCleanLine
|
38
|
+
@cleanLine = remove_empty_strings_and_join([
|
39
|
+
MAKE_COMMAND, MAKE_CLEAN,
|
40
|
+
MAKE_DIR_FLAG, File.dirname(@makefile),
|
41
|
+
MAKE_FILE_FLAG, File.basename(@makefile),
|
42
|
+
@path_to])
|
43
|
+
end
|
44
|
+
|
45
|
+
def calcPathTo(referencedConfigs)
|
46
|
+
@path_to = ""
|
47
|
+
if @config.pathTo != ""
|
48
|
+
pathHash = {}
|
49
|
+
@config.pathTo.split(",").each do |p|
|
50
|
+
nameOfP = p.strip
|
51
|
+
dirOfP = nil
|
52
|
+
if referencedConfigs.include?nameOfP
|
53
|
+
dirOfP = referencedConfigs[nameOfP].first.get_project_dir
|
54
|
+
else
|
55
|
+
Bake.options.roots.each do |r|
|
56
|
+
absIncDir = r+"/"+nameOfP
|
57
|
+
if File.exists?(absIncDir)
|
58
|
+
dirOfP = absIncDir
|
59
|
+
break
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
if dirOfP == nil
|
64
|
+
Bake.formatter.printError("Project '#{nameOfP}' not found", @config)
|
65
|
+
ExitHelper.exit(1)
|
66
|
+
end
|
67
|
+
pathHash[nameOfP] = File.rel_from_to_project(File.dirname(@projectDir),File.dirname(dirOfP))
|
68
|
+
end
|
69
|
+
path_to_array = []
|
70
|
+
pathHash.each { |k,v| path_to_array << "PATH_TO_#{k}=#{v}" }
|
71
|
+
@path_to = path_to_array.join(" ")
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
def execute
|
77
|
+
executeCommand(@commandLine)
|
78
|
+
end
|
79
|
+
|
80
|
+
def clean
|
81
|
+
executeCommand(@cleanLine, "No rule to make target 'clean'.") unless Bake.options.filename
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module Bake
|
2
|
+
module Blocks
|
3
|
+
class Show
|
4
|
+
|
5
|
+
def self.secureShow
|
6
|
+
begin
|
7
|
+
yield
|
8
|
+
rescue Exception => e
|
9
|
+
if (not SystemExit === e)
|
10
|
+
puts e
|
11
|
+
puts e.backtrace
|
12
|
+
ExitHelper.exit(1)
|
13
|
+
else
|
14
|
+
raise e
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.includes
|
20
|
+
secureShow {
|
21
|
+
Blocks::ALL_COMPILE_BLOCKS.sort.each do |projName, blocks|
|
22
|
+
print projName
|
23
|
+
incs = []
|
24
|
+
blocks.each { |block| incs += block.include_list }
|
25
|
+
incs.uniq.each { |inc| print "##{inc}" }
|
26
|
+
print "\n"
|
27
|
+
end
|
28
|
+
ExitHelper.exit(0) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.readInternalIncludes(mainConfig, mainBlock, mainTcs)
|
32
|
+
intIncs = []
|
33
|
+
iinc = mainConfig.defaultToolchain.internalIncludes
|
34
|
+
Dir.chdir(Bake.options.main_dir) do
|
35
|
+
if (iinc)
|
36
|
+
|
37
|
+
cppExe = File.which(mainTcs[:COMPILER][:CPP][:COMMAND])
|
38
|
+
cExe = File.which(mainTcs[:COMPILER][:C][:COMMAND])
|
39
|
+
asmExe = File.which(mainTcs[:COMPILER][:ASM][:COMMAND])
|
40
|
+
archiverExe = File.which(mainTcs[:ARCHIVER][:COMMAND])
|
41
|
+
linkerExe = File.which(mainTcs[:LINKER][:COMMAND])
|
42
|
+
|
43
|
+
iname = mainBlock.convPath(iinc)
|
44
|
+
if iname != ""
|
45
|
+
if not File.exists?(iname)
|
46
|
+
Bake.formatter.printError("InternalIncludes file #{iname} does not exist", iinc)
|
47
|
+
ExitHelper.exit(1)
|
48
|
+
end
|
49
|
+
IO.foreach(iname) do |x|
|
50
|
+
x.sub!("$(CPPPath)", cppExe)
|
51
|
+
x.sub!("$(CPath)", cExe)
|
52
|
+
x.sub!("$(ASMPath)", asmExe)
|
53
|
+
x.sub!("$(ArchiverPath)", archiverExe)
|
54
|
+
x.sub!("$(LinkerPath)", linkerExe)
|
55
|
+
add_line_if_no_comment(intIncs,x)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
return intIncs
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.readInternalDefines(mainConfig, mainBlock)
|
64
|
+
intDefs = {:CPP => [], :C => [], :ASM => []}
|
65
|
+
Dir.chdir(Bake.options.main_dir) do
|
66
|
+
mainConfig.defaultToolchain.compiler.each do |c|
|
67
|
+
if (c.internalDefines)
|
68
|
+
dname = mainBlock.convPath(c.internalDefines)
|
69
|
+
if dname != ""
|
70
|
+
if not File.exists?(dname)
|
71
|
+
Bake.formatter.printError("InternalDefines file #{dname} does not exist", c.internalDefines)
|
72
|
+
ExitHelper.exit(1)
|
73
|
+
end
|
74
|
+
IO.foreach(dname) {|x| add_line_if_no_comment(intDefs[c.ctype],x) }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
return intDefs
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.includesAndDefines(mainConfig, mainTcs)
|
83
|
+
secureShow {
|
84
|
+
mainBlock = Blocks::ALL_BLOCKS[Bake.options.main_project_name+","+Bake.options.build_config]
|
85
|
+
|
86
|
+
intIncs = readInternalIncludes(mainConfig, mainBlock, mainTcs)
|
87
|
+
intDefs = readInternalDefines(mainConfig, mainBlock)
|
88
|
+
|
89
|
+
|
90
|
+
Blocks::ALL_COMPILE_BLOCKS.sort.each do |projName, blocks|
|
91
|
+
|
92
|
+
blockIncs = []
|
93
|
+
blockDefs = {:CPP => [], :C => [], :ASM => []}
|
94
|
+
blocks.each do |block|
|
95
|
+
blockIncs += block.include_list
|
96
|
+
[:CPP, :C, :ASM].each { |type| blockDefs[type] += block.tcs[:COMPILER][type][:DEFINES] }
|
97
|
+
end
|
98
|
+
|
99
|
+
puts projName
|
100
|
+
puts " includes"
|
101
|
+
(blockIncs + intIncs).uniq.each { |i| puts " #{i}" }
|
102
|
+
[:CPP, :C, :ASM].each do |type|
|
103
|
+
puts " #{type} defines"
|
104
|
+
(blockDefs[type] + intDefs[type]).uniq.each { |d| puts " #{d}" }
|
105
|
+
end
|
106
|
+
puts " done"
|
107
|
+
|
108
|
+
end
|
109
|
+
ExitHelper.exit(0) }
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Bake
|
2
|
+
|
3
|
+
class ExitHelper
|
4
|
+
@@exit_code = 0
|
5
|
+
|
6
|
+
def self.set_exit_code(val)
|
7
|
+
@@exit_code = val
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.exit_code()
|
11
|
+
@@exit_code
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.reset_exit_code()
|
15
|
+
@@exit_code = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.exit(val)
|
19
|
+
@@exit_code = val
|
20
|
+
Kernel::exit
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
at_exit do
|
27
|
+
exit(Bake::ExitHelper.exit_code)
|
28
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'common/utils'
|
2
|
+
|
3
|
+
class File
|
4
|
+
|
5
|
+
SLASH = '/'
|
6
|
+
|
7
|
+
def self.is_absolute?(filename)
|
8
|
+
filename[0] == SLASH or filename[1] == ':'
|
9
|
+
end
|
10
|
+
|
11
|
+
# seems both are rel or both are abs in all cases
|
12
|
+
def self.rel_from_to_project(from,to,endWithSlash = true)
|
13
|
+
|
14
|
+
return nil if from.nil? or to.nil?
|
15
|
+
|
16
|
+
toSplitted = to.split('/')
|
17
|
+
fromSplitted = from.split('/')
|
18
|
+
|
19
|
+
max = [toSplitted.length, fromSplitted.length].min
|
20
|
+
|
21
|
+
|
22
|
+
return nil if max < 1
|
23
|
+
|
24
|
+
i = 0
|
25
|
+
|
26
|
+
# path letter in windows may be case different
|
27
|
+
toIsWindowsAbs = false
|
28
|
+
if toSplitted[0].length > 1 and fromSplitted[0].length > 1
|
29
|
+
toIsWindowsAbs = toSplitted[0][1] == ':'
|
30
|
+
i = 1 if toIsWindowsAbs and fromSplitted[0][1] == ':' and toSplitted[0][0].downcase == fromSplitted[0][0].downcase
|
31
|
+
end
|
32
|
+
|
33
|
+
if (toIsWindowsAbs and i==0)
|
34
|
+
res = to
|
35
|
+
res += "/" if endWithSlash
|
36
|
+
return res
|
37
|
+
end
|
38
|
+
|
39
|
+
while i < max
|
40
|
+
break if toSplitted[i] != fromSplitted[i]
|
41
|
+
i += 1
|
42
|
+
end
|
43
|
+
j = i
|
44
|
+
|
45
|
+
res = []
|
46
|
+
while i < fromSplitted.length
|
47
|
+
res << ".."
|
48
|
+
i += 1
|
49
|
+
end
|
50
|
+
|
51
|
+
while j < toSplitted.length
|
52
|
+
res << toSplitted[j]
|
53
|
+
j += 1
|
54
|
+
end
|
55
|
+
|
56
|
+
if res.length == 0
|
57
|
+
return ""
|
58
|
+
end
|
59
|
+
|
60
|
+
res = res.join('/')
|
61
|
+
res += "/" if endWithSlash
|
62
|
+
res
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def self.add_prefix(prefix, file)
|
67
|
+
if not prefix or is_absolute?(file)
|
68
|
+
file
|
69
|
+
else
|
70
|
+
prefix + file
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.which(cmd)
|
75
|
+
return "" if not cmd
|
76
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
77
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
78
|
+
exts.each { |ext|
|
79
|
+
exe = File.join(path, "#{cmd}#{ext}")
|
80
|
+
if File.executable?(exe) && !File.directory?(exe)
|
81
|
+
return File.dirname(exe.gsub(/[\\]/,'/'))
|
82
|
+
end
|
83
|
+
}
|
84
|
+
end
|
85
|
+
return ""
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|