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.
Files changed (53) hide show
  1. data/bin/fhlow +186 -0
  2. data/lib/module_cmdparse/cmdparse.rb +480 -0
  3. data/lib/module_cmdparse/cmdparse/wrappers/optparse.rb +65 -0
  4. data/lib/module_config/config.rb +67 -0
  5. data/lib/module_config/configexception.rb +18 -0
  6. data/lib/module_config/configitems/complex.rb +71 -0
  7. data/lib/module_config/configitems/complexpackage.rb +67 -0
  8. data/lib/module_config/configitems/complexunit.rb +76 -0
  9. data/lib/module_config/configitems/simple.rb +56 -0
  10. data/lib/module_config/configitems/simplearchitecture.rb +52 -0
  11. data/lib/module_config/configitems/simplepackage.rb +47 -0
  12. data/lib/module_config/configitems/simpleunit.rb +53 -0
  13. data/lib/module_config/configs.test +24 -0
  14. data/lib/module_config/item.rb +34 -0
  15. data/lib/module_config/itemfactory.rb +55 -0
  16. data/lib/module_config/section.rb +69 -0
  17. data/lib/module_config/test.flw +20 -0
  18. data/lib/module_config/test.rb +85 -0
  19. data/lib/module_config/tmp +3 -0
  20. data/lib/module_config/unittests/config_1.flw +14 -0
  21. data/lib/module_config/unittests/config_1_fixed.flw +14 -0
  22. data/lib/module_config/unittests/config_2.flw +15 -0
  23. data/lib/module_config/unittests/config_3a.flw +16 -0
  24. data/lib/module_config/unittests/config_3b.flw +15 -0
  25. data/lib/module_config/unittests/config_test.rb +579 -0
  26. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configexception_rb.html +647 -0
  27. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-complex_rb.html +700 -0
  28. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-complexpackage_rb.html +694 -0
  29. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-complexunit_rb.html +704 -0
  30. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-simple_rb.html +685 -0
  31. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-simplepackage_rb.html +676 -0
  32. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-configitems-simpleunit_rb.html +682 -0
  33. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-item_rb.html +663 -0
  34. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-itemfactory_rb.html +687 -0
  35. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-myconfig_rb.html +687 -0
  36. data/lib/module_config/unittests/coverage/-home-simon-tmp-fhlow_v2-flw-core-lib-module_config-section_rb.html +692 -0
  37. data/lib/module_config/unittests/coverage/index.html +689 -0
  38. data/lib/module_fhlow/fhlowexception.rb +55 -0
  39. data/lib/module_fhlow/leaf.rb +197 -0
  40. data/lib/module_fhlow/leaf.rb~ +202 -0
  41. data/lib/module_fhlow/leaffactory.rb +97 -0
  42. data/lib/module_fhlow/leafs/Package.rb +55 -0
  43. data/lib/module_fhlow/leafs/Unit.rb +152 -0
  44. data/lib/module_fhlow/log.rb +100 -0
  45. data/lib/module_fhlow/node.rb +206 -0
  46. data/lib/module_fhlow/pen.rb +101 -0
  47. data/lib/module_fhlow/plugin.rb +54 -0
  48. data/lib/module_fhlow/pluginpool.rb +81 -0
  49. data/lib/module_fhlow/rootnode.rb +98 -0
  50. data/lib/module_fhlow/test.rb +15 -0
  51. data/lib/module_term/ansicolor.rb +102 -0
  52. data/tests/testsuite.rb +20 -0
  53. 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
+