fhlow 1.91.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/bin/fhlow +186 -0
- data/lib/module_cmdparse/cmdparse.rb +480 -0
- data/lib/module_cmdparse/cmdparse/wrappers/optparse.rb +65 -0
- data/lib/module_config/config.rb +67 -0
- data/lib/module_config/configexception.rb +18 -0
- data/lib/module_config/configitems/complex.rb +71 -0
- data/lib/module_config/configitems/complexpackage.rb +67 -0
- data/lib/module_config/configitems/complexunit.rb +76 -0
- data/lib/module_config/configitems/simple.rb +56 -0
- data/lib/module_config/configitems/simplearchitecture.rb +52 -0
- data/lib/module_config/configitems/simplepackage.rb +47 -0
- data/lib/module_config/configitems/simpleunit.rb +53 -0
- data/lib/module_config/configs.test +24 -0
- data/lib/module_config/item.rb +34 -0
- data/lib/module_config/itemfactory.rb +55 -0
- data/lib/module_config/section.rb +69 -0
- data/lib/module_config/test.flw +20 -0
- data/lib/module_config/test.rb +85 -0
- data/lib/module_config/tmp +3 -0
- data/lib/module_config/unittests/config_1.flw +14 -0
- data/lib/module_config/unittests/config_1_fixed.flw +14 -0
- data/lib/module_config/unittests/config_2.flw +15 -0
- data/lib/module_config/unittests/config_3a.flw +16 -0
- data/lib/module_config/unittests/config_3b.flw +15 -0
- data/lib/module_config/unittests/config_test.rb +579 -0
- data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configexception_rb.html +647 -0
- data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-complex_rb.html +700 -0
- data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-complexpackage_rb.html +694 -0
- data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-complexunit_rb.html +704 -0
- data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-simple_rb.html +685 -0
- data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-simplepackage_rb.html +676 -0
- data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-simpleunit_rb.html +682 -0
- data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-item_rb.html +663 -0
- data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-itemfactory_rb.html +687 -0
- data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-myconfig_rb.html +687 -0
- data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-section_rb.html +692 -0
- data/lib/module_config/unittests/coverage/index.html +689 -0
- data/lib/module_fhlow/fhlowexception.rb +55 -0
- data/lib/module_fhlow/leaf.rb +197 -0
- data/lib/module_fhlow/leaf.rb~ +202 -0
- data/lib/module_fhlow/leaffactory.rb +97 -0
- data/lib/module_fhlow/leafs/Package.rb +55 -0
- data/lib/module_fhlow/leafs/Unit.rb +152 -0
- data/lib/module_fhlow/log.rb +100 -0
- data/lib/module_fhlow/node.rb +206 -0
- data/lib/module_fhlow/pen.rb +101 -0
- data/lib/module_fhlow/plugin.rb +54 -0
- data/lib/module_fhlow/pluginpool.rb +81 -0
- data/lib/module_fhlow/rootnode.rb +98 -0
- data/lib/module_fhlow/test.rb +15 -0
- data/lib/module_term/ansicolor.rb +102 -0
- data/tests/testsuite.rb +20 -0
- metadata +106 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
#----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Copyright (C) 2007 Simon Lasselsberger
|
4
|
+
# simon.lasselsberger@fh-hagenberg.at
|
5
|
+
#
|
6
|
+
# This file is part of the _fhlow_ scripting environment.
|
7
|
+
#
|
8
|
+
# The _fhlow_ scripting environment is free software; you can redistribute
|
9
|
+
# it and/or modify it under the terms of the GNU General Public License
|
10
|
+
# as published by the Free Software Foundation; either version 2 of the
|
11
|
+
# License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# _fhlow_ is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with _fhlow_; if not, write to the Free Software
|
20
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
21
|
+
#
|
22
|
+
#----------------------------------------------------------------------------
|
23
|
+
|
24
|
+
module Fhlow
|
25
|
+
|
26
|
+
# This class implements the Factory Pattern in order to create concrete Leaf's
|
27
|
+
# (Package's and Unit's). There also needs to be a concrete PackageFactory and
|
28
|
+
# UnitFacotry because this class is _abstract_. Therefore it is very easy to
|
29
|
+
# implement new Leaf's if needed.
|
30
|
+
class LeafFactory
|
31
|
+
protected
|
32
|
+
# _Abstract_ constructor
|
33
|
+
def initialize()
|
34
|
+
end
|
35
|
+
|
36
|
+
public
|
37
|
+
|
38
|
+
# An Array of subclasses.
|
39
|
+
@@factories = []
|
40
|
+
|
41
|
+
# Is invoked when this class gets inherited. This mechanism makes a register
|
42
|
+
# function in subclasses obsolete because they register themselves when they
|
43
|
+
# inherit.
|
44
|
+
# +_lf+:: a sublcass of LeafFactory
|
45
|
+
def LeafFactory.inherited(_lf)
|
46
|
+
@@factories.push(_lf)
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
=begin def LeafFactory.getFactories()
|
51
|
+
@@factories
|
52
|
+
end
|
53
|
+
=end
|
54
|
+
|
55
|
+
# In order to request a concrete Leaf this function can be used by passing the
|
56
|
+
# __prefix_ (to specify which concrete Leaf is needed) and some arguments
|
57
|
+
# (which will be used to initialize the concrete Leaf).
|
58
|
+
# +_prefix+:: Is used to specify which concrete Leaf is needed.
|
59
|
+
# <tt>*_args</tt>:: see Package.create and Unit.create for more information.
|
60
|
+
def LeafFactory.getLeafFor(_prefix, *_args)
|
61
|
+
@@factories.each do |subclass|
|
62
|
+
if subclass.getPrefix == _prefix
|
63
|
+
return subclass.new.create(*_args)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
# This function loads all files with the extension _.rb_ from the specified directory.
|
70
|
+
# So concrete Leaf's are clearly seperated from the rest of the fhlow implementation.
|
71
|
+
# +_dirname+:: Absolute path to the directory.
|
72
|
+
def LeafFactory.load(_dirname)
|
73
|
+
Dir.open(_dirname).each do |file|
|
74
|
+
if file =~ /[.]rb$/
|
75
|
+
require _dirname+"/"+file
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
# This function is _abstract_ and has to be implemented in the subclasses. It's purpose
|
82
|
+
# is to return the prefix of the concrete Leaf.
|
83
|
+
def LeafFactory.getPrefix()
|
84
|
+
raise NotImplementedError, "You have to implement getPrefix() in sublcasses inherited from LeafFactory!"
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
# This function is _abstract_ and has to be implemented in the subclasses. It's purpose
|
89
|
+
# is to create an object of the subclass.
|
90
|
+
# <tt>*_args</tt>:: An Array of arguments that are passed to the constructor if the subclass.
|
91
|
+
def create(*_args)
|
92
|
+
raise NotImplementedError, "You have to implement create() in sublcasses inherited from LeafFactory!"
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'leaf'
|
2
|
+
require 'leaffactory'
|
3
|
+
|
4
|
+
module Fhlow
|
5
|
+
|
6
|
+
# This is a concrete implementation of the abstract class Leaf. A Package represents one Leaf
|
7
|
+
# with the prefix "pkg".
|
8
|
+
class Package < Leaf
|
9
|
+
|
10
|
+
# Calls the constructor of Leaf.
|
11
|
+
# +_name+:: The Name of the Leaf.
|
12
|
+
# +_parent+:: The reference to the parent.
|
13
|
+
# +_conf+:: The configuration information from higher levels.
|
14
|
+
# +_log+:: The reference to the Log object.
|
15
|
+
# +_pen+:: The reference to a Pen object.
|
16
|
+
def initialize(_name, _parent, _log, _pen)
|
17
|
+
super("pkg", _name, _parent, _log, _pen)
|
18
|
+
end
|
19
|
+
|
20
|
+
# This function returns an Array of filenames in respect of the dependency tree.
|
21
|
+
# +_deptype+:: Type of the requested dependencies (could be Units, BhvUnits, Packages and so on)
|
22
|
+
# +_istoplevel+:: Is used to indicate the first entrance to this function.
|
23
|
+
# +_caller+:: Reference to the caller of the function. This is needed to request architectures.
|
24
|
+
# +_files+:: The Array of the files which will be filled with the requested filenames and returned in the end.
|
25
|
+
def getFiles(_deptype, _istoplevel=true, _caller=nil, _files=Array.new)
|
26
|
+
@dependencies.values.each { |v| v.each { |dep| dep.getFiles(_deptype, false, self, _files)} } unless @dependencies.nil?
|
27
|
+
|
28
|
+
# only act if Packages are needed
|
29
|
+
if _deptype == "Packages"
|
30
|
+
_files.push(getPath+"src/"+name+"-p.vhd")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
# This is a concrete implementation of the _abstract_ class LeafFactory .
|
38
|
+
# A PackageFactory creates objects of Unit.
|
39
|
+
class PackageFactory < LeafFactory
|
40
|
+
|
41
|
+
# Return the prefix used by Units.
|
42
|
+
def PackageFactory.getPrefix()
|
43
|
+
return "pkg"
|
44
|
+
end
|
45
|
+
|
46
|
+
# Creates objects of Unit.
|
47
|
+
# <tt>*_args</tt>:: Array of argumens passed to the constructor of Unit. See Unit.initialize for more details.
|
48
|
+
def create(*_args)
|
49
|
+
return Package.new(*_args)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'leaf'
|
2
|
+
require 'leaffactory'
|
3
|
+
|
4
|
+
module Fhlow
|
5
|
+
|
6
|
+
# This is a concrete implementation of the abstract class Leaf. A Unit represents one Leaf
|
7
|
+
# with the prefix "unit". It also contains information about it's architectures.
|
8
|
+
# Architectures are stored in a Hash (@architectures) whose keys are references to Leafs that
|
9
|
+
# have dependencies on this Unit.
|
10
|
+
# == TODO
|
11
|
+
# * make this explaination more clear
|
12
|
+
class Unit < Leaf
|
13
|
+
|
14
|
+
# Calls the constructor of Leaf and initializes the _architecture_ member.
|
15
|
+
# +_name+:: The Name of the Leaf.
|
16
|
+
# +_parent+:: The reference to the parent.
|
17
|
+
# +_conf+:: The configuration information from higher levels.
|
18
|
+
# +_log+:: The reference to the Log object.
|
19
|
+
# +_pen+:: The reference to a Pen object.
|
20
|
+
def initialize (_name, _parent, _log, _pen)
|
21
|
+
super("unit", _name, _parent, _log, _pen)
|
22
|
+
@architectures = Hash.new
|
23
|
+
end
|
24
|
+
|
25
|
+
# Return the architectures needed by _caller_. Most likely a call of this function will look like this:
|
26
|
+
# someLeaf.getArchitectures(self)
|
27
|
+
# +_caller+:: The reference to the caller.
|
28
|
+
def getArchitectures(_caller)
|
29
|
+
@architectures[_caller]
|
30
|
+
end
|
31
|
+
|
32
|
+
# This function is an extension to Leaf.fetchDependencies. The section [Self] in the config file
|
33
|
+
# holds the information about the architectures which are needed by this Unit for itself.
|
34
|
+
def fetchDependencies()
|
35
|
+
|
36
|
+
# call the fetchDependencies() function from Leaf
|
37
|
+
super()
|
38
|
+
|
39
|
+
# there needs to be a [Self] section the config file
|
40
|
+
if @conf["Self"].nil?
|
41
|
+
raise FhlowException.new(getPath), "Couldn't find section [Self] in any config.flw file responsible for this leaf."
|
42
|
+
end
|
43
|
+
|
44
|
+
# iterate through all items of the [Dependencies] section
|
45
|
+
@conf["Self"].each do |item| # item -> one item of the [Self] section
|
46
|
+
raise FhlowException.new(getPath), "Wrong item found in section [Self] in any config.flw file responsible for this leaf." unless item.instance_of?(Config::SimpleArchitecture)
|
47
|
+
|
48
|
+
# The substition of "Architectures" with "Units" is done in order to improve the usability of the config files.
|
49
|
+
# The section [Self] contains only informations about architectures so the user should work with items with a
|
50
|
+
# proper name. Internally there should be no difference between the architectures from [Dependencies] and [Self]
|
51
|
+
# Architectures -> Units
|
52
|
+
# tbArchitectures -> tbUnits
|
53
|
+
addArchitectures(self, item.name.gsub("Architectures", "Units"), item.value)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# This function returns an Array of filenames in respect of the dependency tree.
|
60
|
+
# +_deptype+:: Type of the requested dependencies (could be Units, BhvUnits, Packages and so on)
|
61
|
+
# +_istoplevel+:: Is used to indicate the first entrance to this function.
|
62
|
+
# +_caller+:: Reference to the caller of the function. This is needed to request architectures.
|
63
|
+
# +_files+:: The Array of the files which will be filled with the requested filenames and returned in the end.
|
64
|
+
# == TODO
|
65
|
+
# * configuration handling -c::
|
66
|
+
# * file not found exception::
|
67
|
+
# * -e -ea -eac -ac handling::
|
68
|
+
def getFiles(_deptype, _istoplevel=true, _caller=nil, _files=Array.new)
|
69
|
+
@dependencies.values.each { |v| v.each { |dep| dep.getFiles(_deptype, false, self, _files)} } unless @dependencies.nil?
|
70
|
+
|
71
|
+
# only act if the Unit is able to handle the _deptype
|
72
|
+
case _deptype
|
73
|
+
when "Units", "BhvUnits", "tbUnits"
|
74
|
+
|
75
|
+
if _istoplevel and (getArchitectures(self).nil? or getArchitectures(self)[_deptype].nil?)
|
76
|
+
raise FhlowException.new(@prefix+@name), "No architectures for <#{_deptype}> specified!"
|
77
|
+
end
|
78
|
+
|
79
|
+
if getArchitectures(_istoplevel ? self : _caller) and
|
80
|
+
getArchitectures(_istoplevel ? self : _caller)[_deptype] and
|
81
|
+
!getArchitectures(_istoplevel ? self : _caller)[_deptype].empty?
|
82
|
+
|
83
|
+
localfiles = Dir[getPath+"src/"+ (_deptype=="tbUnits" ? "tb" : "") +@name+"-e.vhd"]
|
84
|
+
|
85
|
+
getArchitectures(_istoplevel ? self : _caller)[_deptype].each do |arch|
|
86
|
+
localfiles = localfiles | Dir[getPath+"src/"+ (_deptype=="tbUnits" ? "tb" : "") +@name+"-"+arch+"-{a,ea,eac,ac,c}.vhd"]
|
87
|
+
end
|
88
|
+
|
89
|
+
raise FhlowFileNotFoundException.new(getPath+"src/"), "No entity file found." unless localfiles.find { |str| str =~ /.*#{@name}-(e|\w+-e\w{1,2})\.vhd/ }
|
90
|
+
|
91
|
+
localfiles.each do |file|
|
92
|
+
raise FhlowFileNotFoundException.new(file), "File not found." unless File.exist?(file)
|
93
|
+
_files.push(file)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
_files.uniq!
|
99
|
+
_files
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
=begin def each(_name, _caller, &block)
|
104
|
+
@dependencies[_name].each{ |d| d.each(_name, self, &block) } unless @dependencies[_name].nil?
|
105
|
+
yield(self, _caller)
|
106
|
+
end
|
107
|
+
=end
|
108
|
+
|
109
|
+
|
110
|
+
# This function adds information to a Unit which of its architectures are needed by which owner-Unit.
|
111
|
+
# +_owner+:: Reference to the owner-Unit.
|
112
|
+
# +_deptype+:: Type of the dependency for which the architectures will be added. (could be Units, BhvUnits, Packages and so on)
|
113
|
+
# +_architectures+:: An Arra of architecture names.
|
114
|
+
def addArchitectures(_owner, _deptype, _architectures)
|
115
|
+
if @architectures.empty? || @architectures[_owner].nil? || @architectures[_owner][_deptype].nil?
|
116
|
+
if @architectures[_owner].nil?
|
117
|
+
@architectures[_owner] = { _deptype => _architectures}
|
118
|
+
else
|
119
|
+
@architectures[_owner][_deptype] = _architectures
|
120
|
+
end
|
121
|
+
else
|
122
|
+
@architectures[_owner][_deptype] += _architectures
|
123
|
+
end
|
124
|
+
|
125
|
+
@architectures[_owner][_deptype] = @architectures[_owner][_deptype].uniq
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
# This is a concrete implementation of the _abstract_ class LeafFactory .
|
135
|
+
# A UnitFactory creates objects of Unit.
|
136
|
+
class UnitFactory < LeafFactory
|
137
|
+
|
138
|
+
# Return the prefix used by Units.
|
139
|
+
def UnitFactory.getPrefix()
|
140
|
+
return "unit"
|
141
|
+
end
|
142
|
+
|
143
|
+
# Creates objects of Unit.
|
144
|
+
# <tt>*_args</tt>:: Array of argumens passed to the constructor of Unit. See Unit.initialize for more details.
|
145
|
+
def create(*_args)
|
146
|
+
return Unit.new(*_args)
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Copyright (C) 2007 Simon Lasselsberger
|
4
|
+
# simon.lasselsberger@fh-hagenberg.at
|
5
|
+
#
|
6
|
+
# This file is part of the _fhlow_ scripting environment.
|
7
|
+
#
|
8
|
+
# The _fhlow_ scripting environment is free software; you can redistribute
|
9
|
+
# it and/or modify it under the terms of the GNU General Public License
|
10
|
+
# as published by the Free Software Foundation; either version 2 of the
|
11
|
+
# License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# _fhlow_ is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with _fhlow_; if not, write to the Free Software
|
20
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
21
|
+
#
|
22
|
+
#----------------------------------------------------------------------------
|
23
|
+
|
24
|
+
|
25
|
+
require 'singleton'
|
26
|
+
require 'leaf'
|
27
|
+
|
28
|
+
module Fhlow
|
29
|
+
|
30
|
+
# A Log object records all the messages to the specified log file and optional
|
31
|
+
# direkt to the console.
|
32
|
+
class Log
|
33
|
+
|
34
|
+
# The loglevel specifies which messages are logged.
|
35
|
+
# These loglevels are valid:
|
36
|
+
# 3:: *logfile*: error;
|
37
|
+
# 2:: *logfile*: error, warning;
|
38
|
+
# 1:: *logfile*: error, warning, info;
|
39
|
+
# 0:: *logfile*: error, warning, info, debug;
|
40
|
+
# -1:: *logfile*: error, warning, info, debug; *console*: error;
|
41
|
+
# -2:: *logfile*: error, warning, info, debug; *console*: error, warning;
|
42
|
+
# -3:: *logfile*: error, warning, info, debug; *console*: error, warning, info;
|
43
|
+
# -4:: *logfile*: error, warning, info, debug; *console*: error, warning, info, debug;
|
44
|
+
attr_writer :loglevel
|
45
|
+
|
46
|
+
|
47
|
+
# Initializes the members and opens the logfile.
|
48
|
+
# +_logfilename+:: Filename of the logfile (may include the path).
|
49
|
+
# +_loglevel+:: See attrubute +loglevel+
|
50
|
+
# +_pen+:: Reference to the console output object.
|
51
|
+
# +_cwidth+:: Width of the caller collumn
|
52
|
+
def initialize(_logfilename, _loglevel, _pen, _cwidth=25)
|
53
|
+
@loglevel = _loglevel
|
54
|
+
@pen = _pen
|
55
|
+
@cwidth = _cwidth
|
56
|
+
@logfile = File.new(_logfilename,'w')
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
# Closes the logfile.
|
61
|
+
def close
|
62
|
+
@logfile.close if @logfile.instance_of?(File)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Logs a debug message if the loglevel fits.
|
66
|
+
# +_caller+:: Information about where this function was invoked.
|
67
|
+
# +_debugmsg+:: The actual message.
|
68
|
+
def debug(_caller, _debugmsg)
|
69
|
+
@logfile.puts("["+Time.now.to_s+"] DebugMsg by "+_caller.to_s.ljust(@cwidth)+" -> "+_debugmsg.to_s) if @loglevel <= 0
|
70
|
+
@pen.print("- DebugMsg - by "+_caller.to_s.ljust(@cwidth)+" -> "+_debugmsg.to_s+"\n") if @loglevel <= -4
|
71
|
+
end
|
72
|
+
|
73
|
+
# Logs an info message if the loglevel fits.
|
74
|
+
# +_caller+:: Information about where this function was invoked.
|
75
|
+
# +_info+:: The actual message.
|
76
|
+
def info(_caller, _info)
|
77
|
+
@logfile.puts("["+Time.now.to_s+"] Info by "+_caller.to_s.ljust(@cwidth)+" -> "+_info.to_s) if @loglevel <= 1
|
78
|
+
@pen.print("- Info - by "+_caller.to_s.ljust(@cwidth)+" -> "+_info.to_s+"\n") if @loglevel <= -3
|
79
|
+
end
|
80
|
+
|
81
|
+
# Logs a warning message if the loglevel fits.
|
82
|
+
# +_caller+:: Information about where this function was invoked.
|
83
|
+
# +_warning+:: The actual message.
|
84
|
+
def warning(_caller, _warning)
|
85
|
+
@logfile.puts("["+Time.now.to_s+"] Warning by "+_caller.to_s.ljust(@cwidth)+" -> "+_warning.to_s) if @loglevel <= 2
|
86
|
+
@pen.print(@pen.lightyellow, "- Warning - by "+_caller.to_s.ljust(@cwidth)+" -> "+_warning.to_s+"\n", @pen.clear) if @loglevel <= -2
|
87
|
+
end
|
88
|
+
|
89
|
+
# Logs an error message if the loglevel fits.
|
90
|
+
# +_caller+:: Information about where this function was invoked.
|
91
|
+
# +_error+:: The actual message.
|
92
|
+
def error(_caller, _error)
|
93
|
+
@logfile.puts("["+Time.now.to_s+"] Error by "+_caller.to_s.ljust(@cwidth)+" -> "+_error.to_s) if @loglevel <= 3
|
94
|
+
@pen.print(@pen.lightred, "- Error - by "+_caller.to_s.ljust(@cwidth)+" -> ",_error.to_s,"\n", @pen.clear) if @loglevel <= -1
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
@@ -0,0 +1,206 @@
|
|
1
|
+
#----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Copyright (C) 2006 Simon Lasselsberger
|
4
|
+
# simon.lasselsberger@fh-hagenberg.at
|
5
|
+
#
|
6
|
+
# This file is part of the _fhlow_ scripting environment.
|
7
|
+
#
|
8
|
+
# The _fhlow_ scripting environment is free software; you can redistribute
|
9
|
+
# it and/or modify it under the terms of the GNU General Public License
|
10
|
+
# as published by the Free Software Foundation; either version 2 of the
|
11
|
+
# License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# _fhlow_ is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with _fhlow_; if not, write to the Free Software
|
20
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
21
|
+
#
|
22
|
+
#----------------------------------------------------------------------------
|
23
|
+
|
24
|
+
require 'config'
|
25
|
+
|
26
|
+
module Fhlow
|
27
|
+
|
28
|
+
# Nodes are something like containers that are able to contain Leaf and Node objects.
|
29
|
+
# Each Node creates it's children (Leaf and Node objects) when it is created. So parsing
|
30
|
+
# the fhlow structure is implicitly done by creating the RootNode object.
|
31
|
+
# The valid prefixes of Node and Leaf objects for each nodelevel (see initialize) are stored
|
32
|
+
# in the default configfile (<fhlow-root>/flw/defaults.flw).
|
33
|
+
class Node
|
34
|
+
|
35
|
+
# The name of the node.
|
36
|
+
attr_reader :name
|
37
|
+
|
38
|
+
# The prefix of the node.
|
39
|
+
attr_reader :prefix
|
40
|
+
|
41
|
+
# The configuration object.
|
42
|
+
attr_reader :conf
|
43
|
+
|
44
|
+
public
|
45
|
+
# Initializes the members, creates the children (Leaf and Node objects) corresponding to the default
|
46
|
+
# configfile (<fhlow-root>/flw/defaults.flw) and reads the configuration file for this Node.
|
47
|
+
# +_prefix+:: Prefix of the Node.
|
48
|
+
# +_name+:: Name of the Node.
|
49
|
+
# +_parent+:: Reference to the parent Node.
|
50
|
+
# +_nodelevel+:: The level of the Node inside the fhlow structure.
|
51
|
+
# +_log+:: Reference to a Log object.
|
52
|
+
# +_pen+:: Reference to a Pen obejct (output to console).
|
53
|
+
def initialize(_prefix, _name, _parent, _nodelevel, _log, _pen)
|
54
|
+
@prefix = _prefix
|
55
|
+
@name = _name
|
56
|
+
|
57
|
+
# a hash is used for nodes and leafs because the key (prefix+nodename) can be used to
|
58
|
+
# directly access the desired object (by for example getObject) so we don't have
|
59
|
+
# to iterate through the whole structure _recursively_. a hash will therefore be
|
60
|
+
# much faster!
|
61
|
+
@nodes = Hash.new
|
62
|
+
@leafs = Hash.new
|
63
|
+
|
64
|
+
@nodelevel = _nodelevel
|
65
|
+
@parent = _parent
|
66
|
+
@log = _log
|
67
|
+
@pen = _pen
|
68
|
+
|
69
|
+
if File.exist?(@parent.getPath+@prefix+@name+"/config.flw")
|
70
|
+
# read the config file
|
71
|
+
@conf = Config::Config.new(@parent.getPath+@prefix+@name+"/config.flw")
|
72
|
+
# inherit the configurations from previous levels
|
73
|
+
@conf.merge(@parent.conf)
|
74
|
+
@log.debug(@prefix+@name, "Sucessfully merged inherited configs from #{@parent.prefix+@parent.name}.")
|
75
|
+
else
|
76
|
+
@log.warning(self, "config.flw does not exists in #{@prefix}#{@name}.")
|
77
|
+
raise FhlowException, "No configurations found in #{@prefix}#{@name}!" if @parent.conf.nil?
|
78
|
+
@conf = @parent.conf
|
79
|
+
end
|
80
|
+
|
81
|
+
raise FhlowException, "\"NodePrefixes\" in section \"fhlow\" is not set in any of your config files." unless @conf["fhlow"]["NodePrefixes"]
|
82
|
+
raise FhlowException, "\"LeafPrefixes\" in section \"fhlow\" is not set in any of your config files." unless @conf["fhlow"]["LeafPrefixes"]
|
83
|
+
|
84
|
+
@log.info(@prefix+@name, "initializing node...")
|
85
|
+
|
86
|
+
|
87
|
+
if @nodelevel < @conf["fhlow"]["NodePrefixes"].length
|
88
|
+
|
89
|
+
# add the nodes
|
90
|
+
@conf["fhlow"]["NodePrefixes"][@nodelevel].strip.split(",").each do |pf|
|
91
|
+
pf.strip!
|
92
|
+
Dir[getPath+pf+"*"].each do |nodename|
|
93
|
+
nodename = nodename.gsub(/.*\/#{pf}/, "")
|
94
|
+
@log.debug(@prefix+@name, "adding node "+" "*@nodelevel+pf+nodename)
|
95
|
+
# a hash is used for nodes because the key (prefix+nodename) can be used to
|
96
|
+
# directly access the desired object (by for example getObject) so we don't have
|
97
|
+
# to iterate through the whole structure _recursively_. a hash will therefore be
|
98
|
+
# much faster!
|
99
|
+
@nodes.store(pf+nodename, Node.new(pf, nodename, self, @nodelevel+1, @log, @pen))
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
if @nodelevel > 0 && @conf["fhlow"]["LeafPrefixes"][@nodelevel-@conf["fhlow"]["NodePrefixes"].length-1]
|
107
|
+
|
108
|
+
# add the leafs
|
109
|
+
@conf["fhlow"]["LeafPrefixes"][@nodelevel-@conf["fhlow"]["NodePrefixes"].length-1].strip.split(",").each do |prefix|
|
110
|
+
prefix.strip!
|
111
|
+
Dir[getPath+prefix+"*"].each do |leafname|
|
112
|
+
leafname = leafname.gsub(/.*\/#{prefix}/, "")
|
113
|
+
@log.debug(@prefix+@name, "adding leaf "+prefix+leafname)
|
114
|
+
# a hash is used for leafs because the key (prefix+leafname) can be used to
|
115
|
+
# directly access the desired object (by for example getObject) so we don't have
|
116
|
+
# to iterate through the whole structure _recursively_. a hash will therefore be
|
117
|
+
# much faster!
|
118
|
+
@leafs.store(prefix+leafname, LeafFactory.getLeafFor(prefix, leafname, self, @log, @pen))
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
# Returns the absolute path to the Node.
|
127
|
+
def getPath
|
128
|
+
@parent.getPath+@prefix+@name+"/"
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
# Tells each children to fetch its dependencies.
|
133
|
+
def fetchDependencies()
|
134
|
+
@nodes.each_value { |node| node.fetchDependencies() } unless @nodes.empty?
|
135
|
+
@leafs.each_value { |leaf| leaf.fetchDependencies() } unless @leafs.empty?
|
136
|
+
end
|
137
|
+
|
138
|
+
# Returns the requested Leaf.
|
139
|
+
# +_objectfootprint+:: An Array that specifies where in the fhlow structure the leaf can be found. may look like these:
|
140
|
+
# * ["Prol16", "Cpu"]
|
141
|
+
# * ["grp/Prol16", "unit/Cpu"]
|
142
|
+
# * ["Cpu"]
|
143
|
+
# * most likely the attribute +value+ from Config::SimpleUnit, Config::ComplexUnit, Config::SimplePackage or Config::ComplexPackage will be used
|
144
|
+
# +_passthrough+:: The amount of passthroughs to a lower level in the fhlow structure.
|
145
|
+
def getLeaf(_objectfootprint, _passthrough=0)
|
146
|
+
|
147
|
+
raise FhlowException.new(@prefix+@name), "illegal _passthrough value: #{_passthrough}" if _passthrough < 0
|
148
|
+
|
149
|
+
if _passthrough > 0
|
150
|
+
# passthrough the request until the object that should know the
|
151
|
+
# desired object is reached
|
152
|
+
# -> go some levels down in the fhlow tree
|
153
|
+
@parent.getLeaf(_objectfootprint, _passthrough-1)
|
154
|
+
|
155
|
+
else
|
156
|
+
# now request the desired object from child objects
|
157
|
+
# -> go some levels down in the fhlow tree
|
158
|
+
|
159
|
+
|
160
|
+
if _objectfootprint.length > 1
|
161
|
+
# there need to be nodes if there are more than one element in the _objectfootprint
|
162
|
+
|
163
|
+
if _objectfootprint[0] =~ /(.*)\/(.*)/
|
164
|
+
# take care of exact definitions (grp/Fhlow, prj/Fhlow, etc)
|
165
|
+
raise FhlowObjectNotFoundException.new(@prefix+@name), "No such object <#{$1}#{$2}>!" unless @nodes[$1+$2]
|
166
|
+
@nodes[$1+$2].getLeaf(_objectfootprint[1..-1])
|
167
|
+
else
|
168
|
+
# take care of multiple possiblities (unitTest and pkgTest in one group)
|
169
|
+
possibilities = Array.new
|
170
|
+
@nodes.each_key { |nodename| possibilities.push(nodename) if nodename =~ /.*#{_objectfootprint[0]}/ }
|
171
|
+
raise FhlowObjectNotFoundException.new(@prefix+@name), "There are multible possibilities for node #{_objectfootprint[0]}: "+possiblities.join(", ") if possibilities.length > 1
|
172
|
+
raise FhlowObjectNotFoundException.new(@prefix+@name), "No such node <"+ (possibilities.empty? ? _objectfootprint[0].to_s : possibilities[0].to_s)+">!" unless @nodes[possibilities[0]]
|
173
|
+
@nodes[possibilities[0]].getLeaf(_objectfootprint[1..-1])
|
174
|
+
end
|
175
|
+
|
176
|
+
else
|
177
|
+
|
178
|
+
if _objectfootprint[0] =~ /(.*)\/(.*)/
|
179
|
+
raise FhlowObjectNotFoundException.new(@prefix+@name), "No such object <#{$1}#{$2}>!" unless @leafs[$1+$2]
|
180
|
+
return @leafs[$1+$2] # finally the object can be returned
|
181
|
+
else
|
182
|
+
possibilities = Array.new
|
183
|
+
@leafs.each_key { |leafname| possibilities.push(leafname) if leafname =~ /.*#{_objectfootprint[0]}/ }
|
184
|
+
raise FhlowObjectNotFoundException.new(@prefix+@name), "There are multible possibilities for leaf #{_objectfootprint[0]}: "+posssibilities.join(", ") if possibilities.length > 1
|
185
|
+
raise FhlowObjectNotFoundException.new(@prefix+@name), "No such node <"+(possibilities.empty? ? _objectfootprint[0].to_s : possibilities[0].to_s)+">!" unless @leafs[possibilities[0]]
|
186
|
+
return @leafs[possibilities[0]] # finally the object can be returned
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
# Prints the name of this group and information about its children.
|
196
|
+
# +_prefix+:: A prefix that is used for the output.
|
197
|
+
def printMe(_prefix = " ")
|
198
|
+
@pen.print _prefix,@name+"\n"
|
199
|
+
@nodes.each_value {|x| x.printMe(_prefix+" "); puts x } unless @nodes.empty?
|
200
|
+
@leafs.each_value {|x| x.printMe(_prefix+" ") } unless @leafs.empty?
|
201
|
+
@pen.print "\n"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|