Mxx_ru 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +26 -0
- data/NEWS +52 -0
- data/README +21 -0
- data/Rakefile +32 -0
- data/examples/exe_and_lib/main.cpp +15 -0
- data/examples/exe_and_lib/prj.rb +11 -0
- data/examples/exe_and_lib/say.cpp +13 -0
- data/examples/exe_and_lib/say.hpp +11 -0
- data/examples/exe_and_lib/say.rb +7 -0
- data/examples/exe_dll_lib/inout.cpp +15 -0
- data/examples/exe_dll_lib/inout.hpp +26 -0
- data/examples/exe_dll_lib/inout.rb +18 -0
- data/examples/exe_dll_lib/main.cpp +23 -0
- data/examples/exe_dll_lib/prj.rb +11 -0
- data/examples/exe_dll_lib/say.cpp +13 -0
- data/examples/exe_dll_lib/say.hpp +12 -0
- data/examples/exe_dll_lib/say.rb +9 -0
- data/examples/exe_dll_lib_2/build.rb +7 -0
- data/examples/exe_dll_lib_2/inout/inout.cpp +15 -0
- data/examples/exe_dll_lib_2/inout/inout.hpp +26 -0
- data/examples/exe_dll_lib_2/inout/prj.rb +16 -0
- data/examples/exe_dll_lib_2/main/main.cpp +23 -0
- data/examples/exe_dll_lib_2/main/prj.rb +9 -0
- data/examples/exe_dll_lib_2/say/prj.rb +8 -0
- data/examples/exe_dll_lib_2/say/say.cpp +13 -0
- data/examples/exe_dll_lib_2/say/say.hpp +12 -0
- data/examples/simple_exe/main.cpp +26 -0
- data/examples/simple_exe/prj.rb +7 -0
- data/lib/mxx_ru/abstract_target.rb +283 -0
- data/lib/mxx_ru/binary_target.rb +89 -0
- data/lib/mxx_ru/binary_unittest.rb +130 -0
- data/lib/mxx_ru/cpp/analyzer.rb +230 -0
- data/lib/mxx_ru/cpp/composite.rb +106 -0
- data/lib/mxx_ru/cpp/detect_toolset.rb +122 -0
- data/lib/mxx_ru/cpp/mode.rb +85 -0
- data/lib/mxx_ru/cpp/obj_placement.rb +321 -0
- data/lib/mxx_ru/cpp/qt.rb +333 -0
- data/lib/mxx_ru/cpp/rucodegen.rb +114 -0
- data/lib/mxx_ru/cpp/source_file.rb +71 -0
- data/lib/mxx_ru/cpp/target.rb +1371 -0
- data/lib/mxx_ru/cpp/toolset.rb +1029 -0
- data/lib/mxx_ru/cpp/toolsets/bcc_win32_5.rb +52 -0
- data/lib/mxx_ru/cpp/toolsets/bcc_win32_family.rb +451 -0
- data/lib/mxx_ru/cpp/toolsets/c89_etk_nsk.rb +56 -0
- data/lib/mxx_ru/cpp/toolsets/c89_nsk.rb +56 -0
- data/lib/mxx_ru/cpp/toolsets/c89_nsk_family.rb +273 -0
- data/lib/mxx_ru/cpp/toolsets/gcc_cygwin.rb +54 -0
- data/lib/mxx_ru/cpp/toolsets/gcc_family.rb +382 -0
- data/lib/mxx_ru/cpp/toolsets/gcc_linux.rb +60 -0
- data/lib/mxx_ru/cpp/toolsets/gcc_mingw.rb +144 -0
- data/lib/mxx_ru/cpp/toolsets/gcc_sparc_solaris.rb +87 -0
- data/lib/mxx_ru/cpp/toolsets/vc7.rb +62 -0
- data/lib/mxx_ru/cpp/toolsets/vc8.rb +452 -0
- data/lib/mxx_ru/cpp/toolsets/vc_family.rb +428 -0
- data/lib/mxx_ru/cpp.rb +36 -0
- data/lib/mxx_ru/ex.rb +134 -0
- data/lib/mxx_ru/makestyle_generator.rb +138 -0
- data/lib/mxx_ru/textfile_unittest.rb +284 -0
- data/lib/mxx_ru/util.rb +258 -0
- data/tests/c/pcre/chartables.c +183 -0
- data/tests/c/pcre/config.h +99 -0
- data/tests/c/pcre/dftables.c +167 -0
- data/tests/c/pcre/get.c +349 -0
- data/tests/c/pcre/internal.h +677 -0
- data/tests/c/pcre/maketables.c +140 -0
- data/tests/c/pcre/pcre.c +8304 -0
- data/tests/c/pcre/pcre.h +193 -0
- data/tests/c/pcre/pcre.rb +14 -0
- data/tests/c/pcre/pcredemo.c +316 -0
- data/tests/c/pcre/pcregrep.c +642 -0
- data/tests/c/pcre/pcreposix.c +305 -0
- data/tests/c/pcre/pcreposix.h +88 -0
- data/tests/c/pcre/pcretest.c +1483 -0
- data/tests/c/pcre/perltest +211 -0
- data/tests/c/pcre/printint.c +360 -0
- data/tests/c/pcre/study.c +472 -0
- data/tests/cpp/mswin_res_dll/build.rb +14 -0
- data/tests/cpp/mswin_res_dll/dll.cpp +17 -0
- data/tests/cpp/mswin_res_dll/dll.rb +30 -0
- data/tests/cpp/mswin_res_dll/dll.rc +48 -0
- data/tests/cpp/mswin_res_dll/h/dll.hpp +8 -0
- data/tests/cpp/mswin_res_dll/h/res.h +3 -0
- data/tests/cpp/mswin_res_dll/main.cpp +13 -0
- data/tests/cpp/mswin_res_dll/main.rb +20 -0
- data/tests/cpp/mswin_res_dll/res/tree_fol.bmp +0 -0
- data/tests/cpp/mswin_res_dll/res/tree_state_1.bmp +0 -0
- data/tests/cpp/mswin_res_dll/res/tree_state_2.bmp +0 -0
- data/tests/cpp/mswin_res_exe/build.rb +23 -0
- data/tests/cpp/mswin_res_exe/h/res.h +3 -0
- data/tests/cpp/mswin_res_exe/main.cpp +17 -0
- data/tests/cpp/mswin_res_exe/main.rc +48 -0
- data/tests/cpp/mswin_res_exe/res/tree_fol.bmp +0 -0
- data/tests/cpp/mswin_res_exe/res/tree_state_1.bmp +0 -0
- data/tests/cpp/mswin_res_exe/res/tree_state_2.bmp +0 -0
- data/tests/cpp/rucodegen/host_config.cpp +20 -0
- data/tests/cpp/rucodegen/host_config.rb +14 -0
- data/tests/cpp/rucodegen/impl/conn_params.cpp +7 -0
- data/tests/cpp/rucodegen/impl/conn_params.rb +14 -0
- data/tests/cpp/rucodegen/impl/h/conn_params.hpp +10 -0
- data/tests/cpp/rucodegen/prj.rb +17 -0
- data/tests/cpp/textfile_unittest/build.rb +8 -0
- data/tests/cpp/textfile_unittest/etalons/out_0.txt +0 -0
- data/tests/cpp/textfile_unittest/etalons/out_1.txt +1 -0
- data/tests/cpp/textfile_unittest/etalons/out_128.txt +128 -0
- data/tests/cpp/textfile_unittest/main.cpp +89 -0
- data/tests/cpp/textfile_unittest/prj.rb +8 -0
- data/tests/cpp/textfile_unittest/prj.ut.rb +18 -0
- data/tests/cpp/toolset_name.rb +6 -0
- data/tests/cpp/vc_cleanup/cout.log +72 -0
- data/tests/cpp/vc_cleanup/dll_hi.cpp +5 -0
- data/tests/cpp/vc_cleanup/exe_hi.cpp +10 -0
- data/tests/cpp/vc_cleanup/lib_hi.cpp +5 -0
- data/tests/cpp/vc_cleanup/prj_dll_no_implib.rb +10 -0
- data/tests/cpp/vc_cleanup/prj_dll_no_implib_simple_target_root.rb +11 -0
- data/tests/cpp/vc_cleanup/prj_dll_with_implib.rb +11 -0
- data/tests/cpp/vc_cleanup/prj_dll_with_implib_simple_target_root.rb +14 -0
- data/tests/cpp/vc_cleanup/prj_exe_no_implib.rb +10 -0
- data/tests/cpp/vc_cleanup/prj_exe_no_implib_simple_target_root.rb +11 -0
- data/tests/cpp/vc_cleanup/prj_lib.rb +10 -0
- data/tests/cpp/vc_cleanup/prj_lib_with_simple_target_root.rb +11 -0
- data/tests/cpp/vc_cleanup/tc_vc_cleanup.rb +60 -0
- data/tests/mxx_ru/change_default_value/ignoring_by_build_root/build.rb +8 -0
- data/tests/mxx_ru/change_default_value/ignoring_by_build_root/child_1.rb +5 -0
- data/tests/mxx_ru/change_default_value/ignoring_by_child_1/build.rb +7 -0
- data/tests/mxx_ru/change_default_value/ignoring_by_child_1/child_1.rb +5 -0
- data/tests/mxx_ru/change_default_value/ignoring_by_child_1/child_2.rb +5 -0
- data/tests/mxx_ru/change_default_value/ok/build.rb +8 -0
- data/tests/mxx_ru/change_default_value/ok/child_1.rb +8 -0
- data/tests/mxx_ru/tc_makestyle_generator.rb +117 -0
- data/tests/mxx_ru/vc8/tc_actual_manifest.rb +230 -0
- data/tests/mxx_ru/vc8/tc_append_mt_commands.rb +104 -0
- data/tests/mxx_ru/vc8/tc_default_manifest.rb +17 -0
- data/tests/mxx_ru/vc8/tc_define_manifest.rb +173 -0
- data/tests/mxx_ru/vc8/tc_drop_default_manifest.rb +16 -0
- data/tests/mxx_ru/vc8/tc_invalid_params.rb +81 -0
- data/tests/mxx_ru/vc8/ts_vc8.rb +10 -0
- data/tests/qt/aclock/aclock.cpp +148 -0
- data/tests/qt/aclock/aclock.h +45 -0
- data/tests/qt/aclock/main.cpp +28 -0
- data/tests/qt/aclock/prj.rb +21 -0
- data/tests/qt/iconview/main.cpp +76 -0
- data/tests/qt/iconview/prj.rb +21 -0
- data/tests/qt/toplevel/main.cpp +9 -0
- data/tests/qt/toplevel/options.ui +587 -0
- data/tests/qt/toplevel/options.ui.h +98 -0
- data/tests/qt/toplevel/prj.rb +21 -0
- metadata +241 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 1996-2004, Yauheni Akhotnikau
|
|
3
|
+
# Copyright (c) 2004-2006, JSC Intervale
|
|
4
|
+
# Copyright (c) 2006, The Mxx_ru Project
|
|
5
|
+
# All rights reserved.
|
|
6
|
+
#
|
|
7
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
|
8
|
+
# are permitted provided that the following conditions are met:
|
|
9
|
+
#
|
|
10
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
# this list of conditions and the following disclaimer.
|
|
12
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
# and/or other materials provided with the distribution.
|
|
15
|
+
# 3. The name of the author may not be used to endorse or promote products derived
|
|
16
|
+
# from this software without specific prior written permission.
|
|
17
|
+
#
|
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
19
|
+
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
20
|
+
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
|
21
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
22
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
23
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
24
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
25
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
26
|
+
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
#++
|
|
28
|
+
|
|
29
|
+
require 'mxx_ru/abstract_target.rb'
|
|
30
|
+
|
|
31
|
+
module Mxx_ru
|
|
32
|
+
|
|
33
|
+
# A Generator, which allows to define simple make rules in a project.
|
|
34
|
+
#
|
|
35
|
+
# For example, if it's needed to get from ddl file two other files,
|
|
36
|
+
# cpp and hpp, using typegen program, it should be done like that:
|
|
37
|
+
# generator( Mxx_ru::Makestyle_generator.new(
|
|
38
|
+
# [ "myfile.cpp", "myfile.hpp" ],
|
|
39
|
+
# [ "myfile.ddl" ],
|
|
40
|
+
# [ "typegen --from myfile.ddl --cpp myfile.cpp --header myfile.hpp" ] ) )
|
|
41
|
+
#
|
|
42
|
+
# NOTE: For C++ projects current value of sources_root isn't taken into account.
|
|
43
|
+
class Makestyle_generator < Abstract_generator
|
|
44
|
+
# File names list, which should be built by given generator.
|
|
45
|
+
attr_reader :target_files
|
|
46
|
+
|
|
47
|
+
# File names list, result files depends from.
|
|
48
|
+
attr_reader :dependencies
|
|
49
|
+
|
|
50
|
+
# Command list, which should be ran in a sequence to get result files.
|
|
51
|
+
attr_reader :build_cmds
|
|
52
|
+
|
|
53
|
+
# Command list, which should be ran in a sequence to remove result files.
|
|
54
|
+
#
|
|
55
|
+
# If this list is empty, removal of result files would occur on clean operation.
|
|
56
|
+
attr_reader :clean_cmds
|
|
57
|
+
|
|
58
|
+
# Constructor.
|
|
59
|
+
#
|
|
60
|
+
# [_a_target_files_] Result files list.
|
|
61
|
+
# [_a_dependencies_] Dependencies list.
|
|
62
|
+
# [_a_build_cmds_] Command list, which should be ran in a sequence to get result files.
|
|
63
|
+
# [_a_clean_cmds_] Command list, which should be ran in a sequence to remove result files.
|
|
64
|
+
#
|
|
65
|
+
# NOTE: Single values may be defined as a strings instead of vectors. For example:
|
|
66
|
+
# Mxx_ru::Makestyle_generator.new( "myfile.cpp", "myfile.ddl",
|
|
67
|
+
# [ "typegen --from myfile.ddl --to myfile.cpp" ] )
|
|
68
|
+
# It's the same as:
|
|
69
|
+
# Mxx_ru::Makestyle_generator.new( [ "myfile.cpp" ], [ "myfile.ddl" ],
|
|
70
|
+
# "typegen --from myfile.ddl --to myfile.cpp" )
|
|
71
|
+
#
|
|
72
|
+
def initialize(
|
|
73
|
+
a_target_files,
|
|
74
|
+
a_dependencies,
|
|
75
|
+
a_build_cmds,
|
|
76
|
+
a_clean_cmds = Array.new )
|
|
77
|
+
|
|
78
|
+
@target_files = make_array( a_target_files )
|
|
79
|
+
@dependencies = make_array( a_dependencies )
|
|
80
|
+
@build_cmds = make_array( a_build_cmds )
|
|
81
|
+
@clean_cmds = make_array( a_clean_cmds )
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Perform the build of result files.
|
|
85
|
+
#
|
|
86
|
+
# NOTE: _target_ argument is ignored.
|
|
87
|
+
def build( target )
|
|
88
|
+
need_build = false
|
|
89
|
+
|
|
90
|
+
# Checking all result files. If one of them is obsolete, performing rebuild.
|
|
91
|
+
index = 0
|
|
92
|
+
while !need_build && index != @target_files.size
|
|
93
|
+
if Target_state::EXISTS != Target_state.detect(
|
|
94
|
+
@target_files[ index ], @dependencies ).state
|
|
95
|
+
need_build = true
|
|
96
|
+
else
|
|
97
|
+
index += 1
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
if need_build
|
|
102
|
+
# It's required to run all commands to build target.
|
|
103
|
+
Abstract_target.run( @build_cmds, [] )
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Perform the cleanup of result files.
|
|
108
|
+
#
|
|
109
|
+
# NOTE: _target_ argument is ignored.
|
|
110
|
+
def clean( target )
|
|
111
|
+
# If cleanup commands weren't set, deleting result files.
|
|
112
|
+
# Otherwise, it's required to run all commands in a sequence,
|
|
113
|
+
# ignoring return codes.
|
|
114
|
+
if 0 != @clean_cmds.size
|
|
115
|
+
@clean_cmds.each do |c|
|
|
116
|
+
system( c )
|
|
117
|
+
end
|
|
118
|
+
else
|
|
119
|
+
@target_files.each do |f|
|
|
120
|
+
Util.delete_file( f )
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
protected
|
|
126
|
+
# Conversion of single object into a vector, which contains that object.
|
|
127
|
+
# If source object is a vector, it's returned without any operations on it.
|
|
128
|
+
def make_array( a_object )
|
|
129
|
+
if a_object.instance_of? Array
|
|
130
|
+
return a_object
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
return [ a_object ]
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
end
|
|
138
|
+
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 1996-2004, Yauheni Akhotnikau
|
|
3
|
+
# Copyright (c) 2004-2006, JSC Intervale
|
|
4
|
+
# Copyright (c) 2006, The Mxx_ru Project
|
|
5
|
+
# All rights reserved.
|
|
6
|
+
#
|
|
7
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
|
8
|
+
# are permitted provided that the following conditions are met:
|
|
9
|
+
#
|
|
10
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
# this list of conditions and the following disclaimer.
|
|
12
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
# and/or other materials provided with the distribution.
|
|
15
|
+
# 3. The name of the author may not be used to endorse or promote products derived
|
|
16
|
+
# from this software without specific prior written permission.
|
|
17
|
+
#
|
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
19
|
+
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
20
|
+
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
|
21
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
22
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
23
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
24
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
25
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
26
|
+
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
#++
|
|
28
|
+
|
|
29
|
+
require 'mxx_ru/ex'
|
|
30
|
+
require 'mxx_ru/abstract_target'
|
|
31
|
+
|
|
32
|
+
module Mxx_ru
|
|
33
|
+
|
|
34
|
+
# The class of a target, which is binary unit-test application, which create
|
|
35
|
+
# one or many text files.
|
|
36
|
+
# Given target performs a build of application, and then runs it and compares results
|
|
37
|
+
# with files which contains correct results.
|
|
38
|
+
#
|
|
39
|
+
# The basic idea consists in the presence of project file, which controls the build
|
|
40
|
+
# of unit-test application. In that project file, target object is created, inherited
|
|
41
|
+
# from Mxx_ru::Binary_target.
|
|
42
|
+
# To start unit-test it's necessary to create one more file, where target object of
|
|
43
|
+
# Mxx_ru::Textfile_unittest_target class is created.
|
|
44
|
+
# For example:
|
|
45
|
+
#
|
|
46
|
+
# Unit-test application build file:
|
|
47
|
+
# Mxx_ru::setup_target(
|
|
48
|
+
# Mxx_ru::Cpp::Exe_target.new( "test/pack/prj.rb" ) {
|
|
49
|
+
# ...
|
|
50
|
+
# }
|
|
51
|
+
# )
|
|
52
|
+
#
|
|
53
|
+
# File to run unit-test:
|
|
54
|
+
# Mxx_ru::setup_target(
|
|
55
|
+
# Mxx_ru::Textfile_unittest_target.new(
|
|
56
|
+
# "test/pack/pack.ut.rb",
|
|
57
|
+
# "test/pack/prj.rb" ) {
|
|
58
|
+
#
|
|
59
|
+
# launch( "--loops 16 --out test/pack/out/16.txt",
|
|
60
|
+
# [ pair( "test/pack/out/16.txt",
|
|
61
|
+
# "test/pack/out/etalon/16.txt" ) ] )
|
|
62
|
+
#
|
|
63
|
+
# launch( "--loops 32 --out test/pack/out/32.txt",
|
|
64
|
+
# [ pair( "test/pack/out/32.txt",
|
|
65
|
+
# "test/pack/out/etalon/32.txt" ) ] )
|
|
66
|
+
# }
|
|
67
|
+
# )
|
|
68
|
+
#
|
|
69
|
+
# File which is using that unit-test.
|
|
70
|
+
# Mxx_ru::setup_target(
|
|
71
|
+
# Mxx_ru::Cpp::Composite_target( Mxx_ru::BUILD_ROOT ) {
|
|
72
|
+
# required_prj( "some/project/prj.rb" )
|
|
73
|
+
# required_prj( "test/pack/prj.ut.rb" )
|
|
74
|
+
# }
|
|
75
|
+
# )
|
|
76
|
+
#
|
|
77
|
+
class Textfile_unittest_target < Abstract_target
|
|
78
|
+
|
|
79
|
+
# Exception, thrown if one subordinated project generated more
|
|
80
|
+
# than one result name.
|
|
81
|
+
class Must_be_one_target_name_ex < Ex
|
|
82
|
+
# [_a_names_] Names generated.
|
|
83
|
+
def initialize( a_names )
|
|
84
|
+
super( "Only one name expected in [#{a_names.join(';')}]" )
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Exception, thrown if files are not equal.
|
|
89
|
+
class File_mismatch_ex < Build_ex
|
|
90
|
+
# [_a_cmdline_] Command string of test application.
|
|
91
|
+
# [_a_produced_] Name of file generated.
|
|
92
|
+
# [_a_etalon_] Name of file containing correct results.
|
|
93
|
+
# [_a_line_num_] String number where first mismatch was detected.
|
|
94
|
+
# [_a_produced_line_] String of generated file. Nil if EOF is reached.
|
|
95
|
+
# [_a_etalon_line_] String of correct file. Nil if EOF is reached.
|
|
96
|
+
def initialize( a_cmdline,
|
|
97
|
+
a_produced, a_etalon,
|
|
98
|
+
a_line_num,
|
|
99
|
+
a_produced_line, a_etalon_line )
|
|
100
|
+
a_produced_line = "<EOF>" if !a_produced_line
|
|
101
|
+
a_etalon_line = "<EOF>" if !a_etalon_line
|
|
102
|
+
|
|
103
|
+
super( a_cmdline, "Mismatch found in line #{a_line_num}. " +
|
|
104
|
+
"Line in '#{a_produced}' is '#{a_produced_line}'. " +
|
|
105
|
+
"Line in '#{a_etalon}' is '#{a_etalon_line}'" )
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Description of single pair of values compared.
|
|
110
|
+
class Pair
|
|
111
|
+
# Name of file generated.
|
|
112
|
+
attr_reader :produced
|
|
113
|
+
# Name of correct file.
|
|
114
|
+
attr_reader :etalon
|
|
115
|
+
|
|
116
|
+
# Constructor.
|
|
117
|
+
def initialize( a_produced, a_etalon )
|
|
118
|
+
@produced = a_produced
|
|
119
|
+
@etalon = a_etalon
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# A single run of test application description.
|
|
124
|
+
class Launch
|
|
125
|
+
# Command line parameters.
|
|
126
|
+
# Empty string if no parameters.
|
|
127
|
+
attr_reader :cmdline
|
|
128
|
+
# Files list to compare after application executed.
|
|
129
|
+
# Should be Array of Pair.
|
|
130
|
+
attr_reader :pairs
|
|
131
|
+
|
|
132
|
+
# Constructor.
|
|
133
|
+
def initialize( a_cmdline, a_pairs )
|
|
134
|
+
@cmdline = a_cmdline
|
|
135
|
+
@pairs = a_pairs
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Target, responsible for build of unit-test application.
|
|
140
|
+
attr_reader :mxx_target_project
|
|
141
|
+
# True if build method was already executed.
|
|
142
|
+
attr_reader :mxx_build_state
|
|
143
|
+
# Description of test application runs.
|
|
144
|
+
# Array of Launch.
|
|
145
|
+
attr_reader :mxx_launches
|
|
146
|
+
|
|
147
|
+
# Constructor.
|
|
148
|
+
#
|
|
149
|
+
# [_a_alias_] Self alias.
|
|
150
|
+
# [_a_target_project_] Project, responsible for build of unit-test application.
|
|
151
|
+
def initialize( a_alias, a_target_project, &block )
|
|
152
|
+
super( a_alias )
|
|
153
|
+
|
|
154
|
+
@mxx_build_state = nil
|
|
155
|
+
|
|
156
|
+
@mxx_target_project = required_prj( a_target_project )
|
|
157
|
+
|
|
158
|
+
@mxx_launches = Array.new
|
|
159
|
+
|
|
160
|
+
instance_eval( &block ) if block
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Create description of file pairs to compare.
|
|
164
|
+
#
|
|
165
|
+
# [_a_produced_] Name of generated file.
|
|
166
|
+
# [_a_etalon_] Name of correct file.
|
|
167
|
+
def pair( a_produced, a_etalon )
|
|
168
|
+
return Pair.new( a_produced, a_etalon )
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Add description of sequental run of test application.
|
|
172
|
+
#
|
|
173
|
+
# [_a_cmdline_] Command line parameters. May be empty string of nil
|
|
174
|
+
# if no parameters required.
|
|
175
|
+
# [_a_pairs_] A list of pairs of file names to compare. Should be Array of
|
|
176
|
+
# values returned by pair() method.
|
|
177
|
+
#
|
|
178
|
+
# Comparation will be performed in order they are defined in _a_pairs_.
|
|
179
|
+
# Comparation is interrupted on first mismatch.
|
|
180
|
+
def launch( a_cmdline, a_pairs )
|
|
181
|
+
a_cmdline = "" if !a_cmdline
|
|
182
|
+
@mxx_launches << Launch.new( a_cmdline, a_pairs )
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Build subordinated project and run it.
|
|
186
|
+
#
|
|
187
|
+
# If unit-test application returns exit code not equal to 0, exception is thrown.
|
|
188
|
+
def build
|
|
189
|
+
if !@mxx_build_state
|
|
190
|
+
@mxx_target_project.build
|
|
191
|
+
|
|
192
|
+
# Determining the name of application, which should be run.
|
|
193
|
+
full_names = @mxx_target_project.mxx_full_targets_names
|
|
194
|
+
if 1 != full_names.size
|
|
195
|
+
raise Must_be_one_target_name_ex.new( full_names )
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# No execution of commands in dry-run mode.
|
|
199
|
+
if !Mxx_ru::Util::Mode.instance.is_dry_run
|
|
200
|
+
puts "running unit test: #{full_names[0]}..."
|
|
201
|
+
do_all_launches( full_names[ 0 ] )
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
@mxx_build_state = Target_state.new( Target_state::REBUILT )
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
return @mxx_build_state
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Cleanup the project.
|
|
211
|
+
#
|
|
212
|
+
# Executes clean method from subordinated project.
|
|
213
|
+
# Deletes all files, defined as result files of unit-test application.
|
|
214
|
+
def clean
|
|
215
|
+
@mxx_target_project.clean
|
|
216
|
+
|
|
217
|
+
@mxx_launches.each { |launch|
|
|
218
|
+
launch.pairs.each { |pair|
|
|
219
|
+
Util.delete_file( pair.produced )
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
protected
|
|
225
|
+
# Perform all defined runs of test application.
|
|
226
|
+
# This method should not be executed in dry-run mode.
|
|
227
|
+
def do_all_launches( a_file_to_exec )
|
|
228
|
+
# On mswin32 platform if file name is in unix format and
|
|
229
|
+
# redirection of input/output is set, some problems with
|
|
230
|
+
# execution would occur.
|
|
231
|
+
native_file_name = Util::native_pathname( a_file_to_exec )
|
|
232
|
+
|
|
233
|
+
@mxx_launches.each { |launch|
|
|
234
|
+
cmdline = native_file_name + " " + launch.cmdline
|
|
235
|
+
puts "\tlaunching '#{cmdline}'..."
|
|
236
|
+
if !system( cmdline )
|
|
237
|
+
puts "\n\nunit test '#{cmdline}' FAILED! #{$?}"
|
|
238
|
+
raise Build_ex.new( cmdline, $? )
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Execution of application was successful.
|
|
242
|
+
# Let's compare files.
|
|
243
|
+
launch.pairs.each { |pair|
|
|
244
|
+
puts "\t\tcomparing '#{pair.produced}' and '#{pair.etalon}'"
|
|
245
|
+
do_file_compare( cmdline, pair.produced, pair.etalon )
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Perform comparation of two files.
|
|
251
|
+
# If they are not identical, File_mismatch_ex exception is thrown.
|
|
252
|
+
# If some system exceptions would occur (absence of file for example),
|
|
253
|
+
# Build_ex ewxception will be thrown.
|
|
254
|
+
def do_file_compare( a_cmdline, a_produced, a_etalon )
|
|
255
|
+
begin
|
|
256
|
+
produced_file = File.new( a_produced, "r" )
|
|
257
|
+
etalon_file = File.new( a_etalon, "r" )
|
|
258
|
+
|
|
259
|
+
line_num = 1
|
|
260
|
+
while true
|
|
261
|
+
l1 = produced_file.gets
|
|
262
|
+
l2 = etalon_file.gets
|
|
263
|
+
|
|
264
|
+
if l1 != l2
|
|
265
|
+
raise File_mismatch_ex.new( a_cmdline,
|
|
266
|
+
a_produced, a_etalon, line_num,
|
|
267
|
+
l1, l2 )
|
|
268
|
+
else
|
|
269
|
+
line_num += 1
|
|
270
|
+
if !l1
|
|
271
|
+
break
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
rescue Exception => ex
|
|
277
|
+
raise Build_ex.new( a_cmdline,
|
|
278
|
+
"Error during comparing files " +
|
|
279
|
+
"'#{a_produced}', '#{a_etalon}': #{ex}" )
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
end # module Mxx_ru
|
data/lib/mxx_ru/util.rb
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 1996-2004, Yauheni Akhotnikau
|
|
3
|
+
# Copyright (c) 2004-2006, JSC Intervale
|
|
4
|
+
# Copyright (c) 2006, The Mxx_ru Project
|
|
5
|
+
# All rights reserved.
|
|
6
|
+
#
|
|
7
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
|
8
|
+
# are permitted provided that the following conditions are met:
|
|
9
|
+
#
|
|
10
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
# this list of conditions and the following disclaimer.
|
|
12
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
# and/or other materials provided with the distribution.
|
|
15
|
+
# 3. The name of the author may not be used to endorse or promote products derived
|
|
16
|
+
# from this software without specific prior written permission.
|
|
17
|
+
#
|
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
19
|
+
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
20
|
+
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
|
21
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
22
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
23
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
24
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
25
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
26
|
+
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
#++
|
|
28
|
+
|
|
29
|
+
require 'rbconfig'
|
|
30
|
+
require 'singleton'
|
|
31
|
+
|
|
32
|
+
module Mxx_ru
|
|
33
|
+
|
|
34
|
+
module Util
|
|
35
|
+
# Regular expression to divide file name and it's extension.
|
|
36
|
+
MATCH_FILE_EXT_REGEX = Regexp.new( "^(.+)\\.([^\\./]+)$" )
|
|
37
|
+
|
|
38
|
+
# Ruby command line parameters, handled by Mxx_ru.
|
|
39
|
+
MXXARG_CLEAN = "--mxx-clean"
|
|
40
|
+
MXXARG_SHOW_CMD = "--mxx-show-cmd"
|
|
41
|
+
MXXARG_KEEP_TMPS = "--mxx-keep-tmps"
|
|
42
|
+
MXXARG_SHOW_TMPS = "--mxx-show-tmps"
|
|
43
|
+
MXXARG_DRY_RUN = "--mxx-dry-run"
|
|
44
|
+
|
|
45
|
+
# OS name, script is run on.
|
|
46
|
+
@@host_os = nil
|
|
47
|
+
|
|
48
|
+
# Class, which detects Mxx_ru current mode.
|
|
49
|
+
class Mode
|
|
50
|
+
include Singleton
|
|
51
|
+
|
|
52
|
+
attr_reader :is_clean
|
|
53
|
+
attr_reader :is_show_cmd
|
|
54
|
+
attr_reader :is_keep_tmps
|
|
55
|
+
attr_reader :is_show_tmps
|
|
56
|
+
|
|
57
|
+
# Constructor checks for special arguments in command line.
|
|
58
|
+
def initialize
|
|
59
|
+
@is_clean = ARGV.include?( MXXARG_CLEAN )
|
|
60
|
+
@is_show_cmd = ARGV.include?( MXXARG_SHOW_CMD )
|
|
61
|
+
@is_keep_tmps = ARGV.include?( MXXARG_KEEP_TMPS )
|
|
62
|
+
@is_show_tmps = ARGV.include?( MXXARG_SHOW_TMPS )
|
|
63
|
+
@is_dry_run = ARGV.include?( MXXARG_DRY_RUN )
|
|
64
|
+
@is_manual_dry_run = false
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Is dry-run mode set?
|
|
68
|
+
# Dry-run mode is set, if --mxx-dry-run command line parameter is set,
|
|
69
|
+
# or if it's manually set.
|
|
70
|
+
def is_dry_run
|
|
71
|
+
return ( @is_dry_run || @is_manual_dry_run )
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# On/Off manual dry-run mode.
|
|
75
|
+
# In some cases it's efficient to turn it on for some time.
|
|
76
|
+
# For example, it's used to handle subprojects with --mxx-cpp-1 option set.
|
|
77
|
+
def manual_dry_run( a_is_manual_dry_run )
|
|
78
|
+
@is_manual_dry_run = a_is_manual_dry_run
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Returns file name without last extension.
|
|
84
|
+
def Util.remove_file_ext( a_name )
|
|
85
|
+
match_result = MATCH_FILE_EXT_REGEX.match( a_name )
|
|
86
|
+
if nil == match_result
|
|
87
|
+
# No extension was present.
|
|
88
|
+
return String.new( a_name )
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
return match_result[ 1 ]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Returns filename with new last extension.
|
|
95
|
+
def Util.change_file_ext( name, ext )
|
|
96
|
+
remove_file_ext( name ) + ext
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Deleting file name without exception.
|
|
100
|
+
def Util.delete_file( a_name )
|
|
101
|
+
if FileTest.exists?( a_name )
|
|
102
|
+
File.delete( a_name )
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Class, responsible for creation and removal of temporary files.
|
|
107
|
+
# Temporary files are created in current folder.
|
|
108
|
+
# Temporary files are removed before application is exitted,
|
|
109
|
+
# if --mxx-keep-tmps option isn't set.
|
|
110
|
+
class Tmp_files
|
|
111
|
+
include Singleton
|
|
112
|
+
|
|
113
|
+
# Temporary file names.
|
|
114
|
+
@@names = Array.new
|
|
115
|
+
|
|
116
|
+
def initialize
|
|
117
|
+
if !Mode.instance.is_keep_tmps
|
|
118
|
+
ObjectSpace.define_finalizer( self, Proc.new{ Tmp_files.finalizer } )
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Counter to ensure unique file names.
|
|
122
|
+
@current = 0
|
|
123
|
+
|
|
124
|
+
# Indicies stack in @@names for push and pop methods.
|
|
125
|
+
@index_stack = Array.new
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def Tmp_files.finalizer
|
|
129
|
+
@@names.each { |d|
|
|
130
|
+
begin
|
|
131
|
+
File.delete( d )
|
|
132
|
+
rescue Exception => e
|
|
133
|
+
puts e
|
|
134
|
+
end
|
|
135
|
+
}
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Temporary file creation.
|
|
139
|
+
# The string given is stored to the temporary file.
|
|
140
|
+
# The name of temporary file is returned.
|
|
141
|
+
#
|
|
142
|
+
# [_a_content_] Should be an object of String type.
|
|
143
|
+
def create( a_content )
|
|
144
|
+
|
|
145
|
+
current = (@current += 1)
|
|
146
|
+
file_name = "tmpmxx_ru.#{$$}.#{current}"
|
|
147
|
+
file = File.new( file_name, "w" )
|
|
148
|
+
@@names << file_name
|
|
149
|
+
file << a_content
|
|
150
|
+
file.close
|
|
151
|
+
|
|
152
|
+
if Mode.instance.is_show_tmps
|
|
153
|
+
puts "<<<[#{file_name}]\t #{a_content}>>>"
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
return file_name
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Storing current vector size to the indicies stack.
|
|
160
|
+
def push()
|
|
161
|
+
if !Mode.instance.is_keep_tmps
|
|
162
|
+
@index_stack.push( @@names.size() )
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Removing all files, which are stored in a file names vector
|
|
167
|
+
# starting from first element from @index_stack position.
|
|
168
|
+
def pop()
|
|
169
|
+
if !Mode.instance.is_keep_tmps
|
|
170
|
+
index = @index_stack.pop
|
|
171
|
+
while @@names.size > index
|
|
172
|
+
file_to_delete = @@names.pop
|
|
173
|
+
Mxx_ru::Util::delete_file( file_to_delete )
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
end # class Tmp_files
|
|
179
|
+
|
|
180
|
+
# Auxiliary function for correct execution of build method of target object.
|
|
181
|
+
# Before execution Tmp_files.push is executed, and after execution of build method
|
|
182
|
+
# Tmp_files.pop is called. This way we are removing temporary files
|
|
183
|
+
# created during a compilation of given target.
|
|
184
|
+
def Util.build_call_wrapper( a_target )
|
|
185
|
+
begin
|
|
186
|
+
Tmp_files.instance.push
|
|
187
|
+
state = a_target.build
|
|
188
|
+
return state
|
|
189
|
+
ensure
|
|
190
|
+
Tmp_files.instance.pop
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Create folder if it isn't exist.
|
|
195
|
+
#
|
|
196
|
+
# All chain of names is tracked. For example, if we trying to create
|
|
197
|
+
# output/release/lib folder, and only output is exists, then release/lib folders
|
|
198
|
+
# are created.
|
|
199
|
+
def Util.create_dir( a_name )
|
|
200
|
+
# Dividing the chain.
|
|
201
|
+
chain = Array.new
|
|
202
|
+
chain.unshift( a_name )
|
|
203
|
+
|
|
204
|
+
to_split = a_name.clone
|
|
205
|
+
while to_split != "."
|
|
206
|
+
r = File.split( to_split )
|
|
207
|
+
chain.unshift( to_split = r[ 0 ] )
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
chain.each { |d|
|
|
211
|
+
if !FileTest.exists?( d )
|
|
212
|
+
Dir.mkdir( d )
|
|
213
|
+
end
|
|
214
|
+
}
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# To ensure folder is exist.
|
|
218
|
+
#
|
|
219
|
+
# If dry-run mode wasn't set, checking for existance.
|
|
220
|
+
# If it isn't exists, trying to create it.
|
|
221
|
+
#
|
|
222
|
+
# In a dry-run mode Mxx_ru always assumes folder is exists, even if it isn't.
|
|
223
|
+
def Util.ensure_path_exists( a_path_name )
|
|
224
|
+
if !Mxx_ru::Util::Mode.instance.is_dry_run
|
|
225
|
+
if !FileTest.exists?( a_path_name )
|
|
226
|
+
Mxx_ru::Util.create_dir( a_path_name )
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# Get OS name where script is exeuted.
|
|
232
|
+
def Util.host_os
|
|
233
|
+
if !@@host_os
|
|
234
|
+
@@host_os = Config::CONFIG[ "host_os" ]
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
return @@host_os
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# Transform separators in file names to correct ones on the given platform.
|
|
241
|
+
#
|
|
242
|
+
# For example on mswin32 we change "/" to "\".
|
|
243
|
+
#
|
|
244
|
+
# [_a_pathname_] Path to the file in unix style.
|
|
245
|
+
#
|
|
246
|
+
# *IMPORTANT! In current version only mswin32 platform is tracked!*
|
|
247
|
+
def Util.native_pathname( a_pathname )
|
|
248
|
+
if "mswin32" == Util::host_os
|
|
249
|
+
return a_pathname.gsub( "/", "\\" )
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
return a_pathname
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
end # module Util
|
|
256
|
+
|
|
257
|
+
end # module Mxx_ru
|
|
258
|
+
|