From e842df7d424b0fd0a96d78fbfd897fa9f3ebc9a6 Mon Sep 17 00:00:00 2001 From: Will Budic Date: Thu, 6 Feb 2025 09:49:04 +1100 Subject: [PATCH] Anechoic handling bettered, main CNF tag parsing routine revisited. --- system/modules/CNFMeta.pm | 7 +- system/modules/CNFParser.pm | 220 ++++++++++++++++++++---------------- 2 files changed, 126 insertions(+), 101 deletions(-) diff --git a/system/modules/CNFMeta.pm b/system/modules/CNFMeta.pm index 16496b2..532dfbe 100644 --- a/system/modules/CNFMeta.pm +++ b/system/modules/CNFMeta.pm @@ -13,7 +13,7 @@ use strict; use warnings; no warnings qw(experimental::signatures); ### -# Returns the regular expresion for any of the meta constances. +# Returns the regular expression for any of the meta constances. ## sub _meta { my $constance = shift; @@ -27,6 +27,9 @@ sub _meta { ### # Priority order no. for instructions. use constant PRIORITY => qr/(\s*\_+PRIORITY\_(\d+)\_+\s*)/o; +### +# ANONYMOUS tag name assigned where name is not given or tagged. +use constant ANN => '__ANN__'; ### # Globals, there is possible only four CNF data types. @@ -40,7 +43,7 @@ my $cnt =0; foreach(qw{BOOL INT NUMBER DATE TEXT}){$CNF_DATA_TYPES{$_}=++$cnt} $cnt =0; foreach(qw{IDX TABLE COLNAME}) {$REL_IDX{$_}=$cnt++}; } ### -# Global setting for SQL TEXT to CNF _TEXT_ specified data type range. Programatically changable. +# Global setting for SQL TEXT to CNF _TEXT_ specified data type range. Programmatically changeable. our $SQL_CNF_VAR_LENGTH = 2024; sub import { diff --git a/system/modules/CNFParser.pm b/system/modules/CNFParser.pm index af5bcd7..60a5fdf 100644 --- a/system/modules/CNFParser.pm +++ b/system/modules/CNFParser.pm @@ -19,7 +19,7 @@ require CNFDateTime; ##no critic qw(Subroutines::RequireFinalReturn) ##no critic Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions -use constant VERSION => '3.3.2'; +use constant VERSION => '3.3.3'; use constant APP_STS => 'APP_SETTINGS'; our @files; our %lists; @@ -31,8 +31,10 @@ our $SQL; # Package fields are always global in perl! ### our %ANONS; -#private -> Instance fields: - my $ANONS; +### +# Following is private -> Instance fields for package, every objects has its own not accessible from outside. +### + my $anechoic; #<- Not setting here by purpose to package global. As anon sub here is ideally an method. my @includes; my $CUR_SCRIPT; my %instructs; my $IS_IN_INCLUDE_MODE; @@ -76,10 +78,16 @@ sub new { my ($class, $path, $attrs, $del_keys, $self) = @_; }; } $CONSTREQ = $self->{CONSTANT_REQUIRED}; - if (!$self->{ANONS_ARE_PUBLIC}){ #Not public, means are private to this object, that is, anons are not static. - $self->{ANONS_ARE_PUBLIC} = 0; #<- Caveat of Perl, if this is not set to zero, it can't be accessed legally in a protected hash. - $self->{__ANONS__} = {}; + + if ($self->{'ANONS_ARE_PUBLIC'}){ + $anechoic = \%ANONS; + }else{ + #Not public, means are private to this object, that is, anons are not static. + $self->{ANONS_ARE_PUBLIC} = 0; #<- Caveat of Perl, if this is not set to zero, it can't be accessed legally in a protected hash. + $self->{__ANONS__} = {}; + $anechoic = $self->{__ANONS__}; } + if(exists $self->{'%LOG'}){ if(ref($self->{'%LOG'}) ne 'HASH'){ die '%LOG'. "passed attribute is not an hash reference." @@ -160,21 +168,22 @@ sub _isTrue{ } ### -# Post parsing instructed special item objects. They have lower priority to Order of apperance and from CNFNodes. +# Post parsing instructed special item objects. They have lower priority to Order of appearance and from CNFNodes. ## package InstructedDataItem { our %counters; - sub new { my ($class, $ele, $ins, $val) = @_; - my $priority = ($val =~ s/$meta_has_priority/""/sexi)?2:3; $val =~ s/$meta_priority/""/sexi; + sub new { my ($class, $ele, $ins, $val, $aid) = @_; + my $priority = ($val =~ s/$meta_has_priority/""/sexi)?2:3; + $val =~ s/$meta_priority/""/sexi; $priority = $2 if $2; my $dataItemCounter; if(exists $counters{$ele}){ $dataItemCounter = $counters{$ele}; }else{ - $dataItemCounter = {aid=>int(0)}; - $counters{$ele} = $dataItemCounter; + $dataItemCounter = {aid=>int(0)}; + $counters{$ele} = $dataItemCounter; } bless { ele => $ele, @@ -235,19 +244,22 @@ package PropertyValueStyle { # They can be; and are only dynamically set via the config instance directly. # That is, if it has the ANONS_ARE_PUBLIC property set, and by using the empty method of anon() with no arguments. # i.e. ${CNFParser->new()->anon()}{'MyDynamicAnon'} = 'something'; -# However a private config instance, will have its own anon's. And could be read only if it exist as a property, via this anon(NAME) method. +# However a private config instance, will have its own anon's. And could be read only if it exist as an property, via this anon(NAME) method. # This hasn't been yet fully specified in the PerlCNF specs. # i.e. ${CNFParser->new({ANONS_ARE_PUBLIC=>0})->anon('MyDynamicAnon') # <-- Will not be available. ## sub anon { my ($self, $n, $args)=@_; - my $anechoic = \%ANONS; + + my $this_anechoic; + if(ref($self) ne 'CNFParser'){ $n = $self; - }elsif (not $self->{'ANONS_ARE_PUBLIC'}){ - $anechoic = $self->{'__ANONS__'}; + $this_anechoic = $anechoic #To what ever is globally set. + }else{ + $this_anechoic = $self->{ANONS_ARE_PUBLIC} ? \%ANONS: $self->{__ANONS__}; } if($n){ - my $ret = %$anechoic{$n}; + my $ret = %$this_anechoic {$n}; return if !$ret; if($args){ my $ref = ref($args); @@ -255,7 +267,7 @@ sub anon { my ($self, $n, $args)=@_; my @arr = ($ret =~ m/(\$\$\$.+?\$\$\$)/gm); foreach my $find(@arr) {# <- MACRO TAG translate. -> my $s= $find; $s =~ s/^\$\$\$|\$\$\$$//g;# - my $r = %$anechoic{$s}; + my $r = $this_anechoic -> {$s}; if(!$r && exists $self->{$s}){#fallback to maybe constant property has been seek'd? $r = $self->{$s}; } @@ -281,18 +293,19 @@ sub anon { my ($self, $n, $args)=@_; $cnt++; } }else{ - my $val = %$anechoic{$args}; + my $val = $this_anechoic->{$args}; $ret =~ s/\$\$\$$args\$\$\$/$val/g; warn "Scalar argument passed $args, did you mean array to pass? For property $n=$ret\n" unless $self and not $self->{ENABLE_WARNINGS} } } my $ref = ref($ret); + return $ret if $ref eq ''; return $$ret if $ref eq "REF"; return $ret->val() if $ref eq "CNFNode"; return $ret; } - return $anechoic; + return $this_anechoic; } ### @@ -432,7 +445,14 @@ sub template { my ($self, $property, %macros) = @_; #private to parser sub. sub doInstruction { my ($self,$e,$t,$v) = @_; - my $DO_ENABLED = $self->{'DO_ENABLED'}; my $priority = 0; my $isMetaConst; + my $DO_ENABLED = $self->{'DO_ENABLED'}; my $priority = 4; my $isMetaConst; + if(!$t && !$v && ref($e) eq 'InstructedDataItem'){ + my $itm = $e; + $e = $itm->{ele} . $itm ->{aid}; + $t = $itm->{ins}; + $v = $itm->{val}; + $priority = $itm->{'^'}; + } $t = "" if not defined $t; if($t eq 'CONST' or $t eq 'CONSTANT'){#Single constant with mulit-line value; # It is NOT allowed to overwrite constant. @@ -445,7 +465,7 @@ sub doInstruction { my ($self,$e,$t,$v) = @_; } elsif($t eq 'VAR' or $t eq 'VARIABLE'){ $v =~ s/^\s//; - $ANONS->{$e} = $v; + $anechoic->{$e} = $v; } elsif($t eq 'DATA'){ $self->doDATAInstructions_($e,$v) @@ -463,7 +483,7 @@ sub doInstruction { my ($self,$e,$t,$v) = @_; if($isMetaConst){ $self ->{$e} = $v }else{ - $ANONS->{$e} = $v + $anechoic->{$e} = $v } }elsif($t eq 'FILE'){#@TODO Test case this $self->doLoadDataFile($e,$v); @@ -475,7 +495,7 @@ sub doInstruction { my ($self,$e,$t,$v) = @_; if ($isMetaConst){ $self -> {$e} = $v; }else{ - $ANONS = $v + $anechoic = $v } } my $prc_last = ($v =~ s/($meta_process_last)/""/ei)?1:0; @@ -486,9 +506,9 @@ sub doInstruction { my ($self,$e,$t,$v) = @_; $includes[@includes] = {script=>$v,local=>$CUR_SCRIPT,loaded=>0, prc_last=>$prc_last}; }elsif($t eq 'TREE'){ my $tree = 0; - if (!$v){ - $v = $e; - $e = 'LAST_DO'; + if( !$v ){ + $v = $e; + $e = CNFMeta::ANN(); } if( $v =~ s/($meta_has_priority)/""/ei ){ $priority = 1; @@ -496,9 +516,9 @@ sub doInstruction { my ($self,$e,$t,$v) = @_; if( $v =~ s/$meta_priority/""/sexi ){ $priority = $2; } - $tree = CNFNode->new({'_'=>$e,'~'=>$v,'^'=>$priority}); - $tree->{DEBUG} = 1 if $self->{DEBUG}; - $instructs{$e} = \$tree; + $tree = CNFNode->new({'_'=>$e,'~'=>$v,'^'=>$priority}); + $tree->{DEBUG} = 1 if $self->{DEBUG}; + $instructs{$e} = \$tree; }elsif($t eq 'TABLE'){ # This all have now be late bound and send via the CNFSQL package. since v.2.6 # It is hardly been used. But in the future this might change. my $type = "NONE"; if ($v =~ 'AUTOINCREMENT'){$type = "AUTOINCREMENT"} @@ -513,7 +533,7 @@ sub doInstruction { my ($self,$e,$t,$v) = @_; my $ret; if (!$v){ $v = $e; - $e = 'LAST_DO'; + $e = CNFMeta::ANN(); } if( $v =~ s/($meta_has_priority)/""/ei ){ $priority = 1; @@ -522,7 +542,7 @@ sub doInstruction { my ($self,$e,$t,$v) = @_; $priority = $2; } if( $v=~ s/($meta_on_demand)/""/ei ){ - $ANONS->{$e} = CNFNode -> new({'_'=>$e,'&'=>$v,'^'=>$priority}); + $anechoic->{$e} = CNFNode -> new({'_'=>$e,'&'=>$v,'^'=>$priority}); return; } ## no critic BuiltinFunctions::ProhibitStringyEval @@ -530,10 +550,10 @@ sub doInstruction { my ($self,$e,$t,$v) = @_; ## use critic if ($ret){ chomp $ret; - $ANONS->{$e} = $ret; + $anechoic->{$e} = $ret; }else{ $self->warn("Perl DO_ENABLED script evaluation failed to evalute: $e Error: $@"); - $ANONS->{$e} = '<>'; + $anechoic->{$e} = '<>'; } }else{ $self->warn("DO_ENABLED is set to false to process property: $e\n") @@ -548,14 +568,14 @@ sub doInstruction { my ($self,$e,$t,$v) = @_; use Module::Load; autoload $v; $v =~ s/^(.*\/)*|(\..*)$//g; - $ANONS->{$e} = $v; + $anechoic->{$e} = $v; }catch{ $self->warn("Module DO_ENABLED library failed to load: $v\n"); - $ANONS->{$e} = '<>' + $anechoic->{$e} = '<>' } }else{ $self->warn("DO_ENABLED is set to false to process a LIB property: $e\n"); - $ANONS->{$e} = '<>'; + $anechoic->{$e} = '<>'; } } elsif($t eq 'PLUGIN'){ @@ -590,14 +610,14 @@ sub doInstruction { my ($self,$e,$t,$v) = @_; #Register application statement as either an anonymous one. Or since v.1.2 a listing type tag. if($e !~ /\$\$$/){ #<- It is not matching {name}$$ here. if($self->{'HAS_EXTENSIONS'}){ - $ANONS->{$e} = InstructedDataItem->new($e,$t,$v) + $anechoic->{$e} = InstructedDataItem->new($e,$t,$v) }else{ - $v = $t if not $v; - if($e=~/^\$/){ - $self->{$e} = $v if !$self->{$e}; # Not allowed to overwrite constant. - }else{ - $ANONS->{$e} = $v - } + $v = $t if not $v; + if($e=~/^\$/){ + $self->{$e} = $v if !$self->{$e}; # Not allowed to overwrite constant. + }else{ + $anechoic->{$e} = $v + } } } else{ @@ -642,11 +662,11 @@ sub loadDataFile { my ($self,$e,$path,$v,$i)=@_; $tag = $kv[1]; $i = index $tag, "\n"; if($i==-1){ - $tag = $v = substr $tag, 0, (rindex $tag, ">>"); + $tag = $v = substr $tag, 0, (rindex $tag, ">>"); } else{ - $v = substr $tag, $i+1, (rindex $tag, ">>")-($i+1); - $tag = substr $tag, 0, $i; + $v = substr $tag, $i+1, (rindex $tag, ">>")-($i+1); + $tag = substr $tag, 0, $i; } if($tag eq 'DATA'){ $self->doDATAInstructions_($e,$v) @@ -657,8 +677,8 @@ sub loadDataFile { my ($self,$e,$path,$v,$i)=@_; } } ## -# DATA instructions are not preserved as CNF script values as would be redundand and a waist. -# They by default are only META translated into tables for efficiancy by data property name. +# DATA instructions are not preserved as CNF script values as would be redundant and a waist. +# They by default are only META translated into tables for efficiency by data property name. #private sub doDATAInstructions_{ my ($self,$e,$v,$t,$d)=@_; my $add_as_SQLTable = $v =~ s/${meta('SQL_TABLE')}/""/sexi; @@ -670,10 +690,10 @@ sub doDATAInstructions_{ my ($self,$e,$v,$t,$d)=@_; my @hdr; my @rows; my $autonumber = 0; my $ref = $self->{__DATA__}{$e}; if($ref){ - $ref = $$ref; - @hdr = @{$ref->{header}}; - @rows= @{$ref->{data}}; - $autonumber = $ref->{auto}; $isAutonumber = 1 if($autonumber || $isAutonumber); + $ref = $$ref; + @hdr = @{$ref->{header}}; + @rows= @{$ref->{data}}; + $autonumber = $ref->{auto}; $isAutonumber = 1 if($autonumber || $isAutonumber); } $v=~ s/^\s*//gm; foreach my $row(split(/~\s/,$v)){ @@ -746,11 +766,7 @@ sub doDATAInstructions_{ my ($self,$e,$v,$t,$d)=@_; sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; my @tags; - if($self->{'ANONS_ARE_PUBLIC'}){ - $ANONS = \%ANONS; - }else{ - $ANONS = $self->{'__ANONS__'}; - } + $cnf_file = $cnf_file -> {path} if ref($cnf_file) eq 'CNFGlobalFile'; # We control from here the constances, as we need to unlock them if a previous parse was run. unlock_hash(%$self); @@ -787,7 +803,7 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; foreach my $tag (@tags){ next if not $tag; next if $tag =~ m/^(>+)|^(<<)/; - if($tag =~ m/^<(\w*)\s+(.*?)>*$/gs){ # Original fastest and early format: <<>> + if($tag =~ m/^<\s*(\w*)\s+(.*?)>*$/gs){ # Original fastest and early format: <<>> my $t = $1; my $v = $2; if(isReservedWord($self, $t)){ @@ -802,7 +818,7 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; $line = $3; $line =~ s/^\s*(['"])(.*)\g{1}$/$2/ if $line;#strip quotes if(defined $name){ if($isVar && not $isMETAConst){ - $ANONS ->{$name} = $line if $line + $anechoic ->{$name} = $line if $line }else{ $name =~ s/^\$// if $isMETAConst; # It is NOT allowed to overwrite a constant, so check an issue warning. @@ -827,7 +843,7 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; $t = $1; $v = $2; } - $ANONS->{$t} = $v; + $anechoic->{$t} = $v; } }else{ @@ -836,11 +852,11 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; # Check if very old format and don't parse the data for old code compatibility to (still) do it. # This is interesting, as a newer format file is expected to use the DATA instruction and final data specified script rules. if($CNF_VER eq 'CNF2.2' && $tag =~ m/(\w+)\s*(<\d+>\s)\s*(.*\n)/mg){#It is old DATA format annon - $e = $1; - $t = $2; - $v = substr($tag,length($e)+length($t)); - $ANONS->{$e} = $v; - next; + $e = $1; + $t = $2; + $v = substr($tag,length($e)+length($t)); + $anechoic->{$e} = $v; + next; } # Before mauling into possible value types, let us go for the full expected tag specs first: # <<{$sig}{name}<{INSTRUCTION}>{value\n...value\n}>> @@ -858,13 +874,13 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; } }else{ ############################################################################# - $tag =~ m/\s*([@%\$\.\/\w]+)\s* # The name. - ([ <>\n]) # begin or close of instruction, where '\n' mark in script as instruction less. - ([^<^>^^\n]+) # instruction or value of anything - ([<>\n]?) # close mark for instruction or is less if \n encountered before. + $tag =~ m/\s*([@%\$\w\/\.]+)\s* # The name. + ([ <>\n]*)? # begin or close of instruction, where '\n' mark in script as instruction less. + ([^<>\n]+) # instruction or value of anything + ([ <>\n])? # close mark for instruction or is less if \n encountered before. (.*) # actual value is the rest. (>$)* # capture above value up to here from buffer, i.e. if coming from a >>> tag. - /gmxs; ############################################################################### + /gmsx; ############################################################################### $e =$1; if($e eq '@' or $2 eq '<' or ($2 eq '>' and !$4)){ @@ -891,9 +907,9 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; @array = @{$lists{$e}}; } if(!$t or $t ne 'DATA'){ - push @array, InstructedDataItem -> new($e, $t, $v); - $lists{$e} = \@array; - next; + push @array, InstructedDataItem -> new($e, $t, $v); + $lists{$e} = \@array; + next; } }elsif ($e eq '@'){#collection processing. my $isArray = $t=~ m/^@/; @@ -925,10 +941,10 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; my $macro = 0; if(exists($properties{$t})){ if($self->isReservedWord($t)){ - $self->warn("Skipped a try to overwrite a reserved property -> $t."); - next + $self->warn("Skipped a try to overwrite a reserved property -> $t."); + next }else{ - %hsh = %{$properties{$t}} + %hsh = %{$properties{$t}} } }else{ %hsh =(); @@ -950,7 +966,7 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; my @arr = ($value =~ m/(\$\$\$.+?\$\$\$)/gm); foreach my $find(@arr) { my $s = $find; $s =~ s/^\$\$\$|\$\$\$$//g; - my $r = $ANONS->{$s}; + my $r = $anechoic->{$s}; $r = $self->{$s} if !$r; $r = $instructs{$s} if !$r; CNFParserException->throw(error=>"Unable to find property for $t.$name -> $find\n",show_trace=>1) if !$r; @@ -976,11 +992,10 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; } # Do those autonumbering list anons, and for pre instruction processing prepare if have it. if(%lists){ - foreach my $arr(values %lists){ - foreach my $item(@$arr){ - my $e = $item->{ele} . $item ->{aid}; - doInstruction($self, $e, $item->{ins},$item->{val}); - } + foreach my $arr(values %lists){ + foreach my $itm(@$arr){ + doInstruction($self, $itm); + } } undef %InstructedDataItem::counters; } @@ -989,18 +1004,18 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; if(%instructs && not $IS_IN_INCLUDE_MODE){ my @items; foreach my $e(keys %instructs){ - my $struct = $instructs{$e}; - my $type = ref($struct); + my $struct = $instructs{$e}; + my $type = ref($struct); if ($type eq 'REF'){ $struct = $$struct; - $type = ref($struct); + $type = ref($struct); } if($type eq 'String'){ - my $v = $struct; + my $v = $struct; my @arr = ($v =~ m/(\$\$\$.+?\$\$\$)/gm); foreach my $find(@arr) {# <- MACRO TAG translate. -> my $s= $find; $s =~ s/^\$\$\$|\$\$\$$//g;# - my $r = %$ANONS{$s}; + my $r = %$anechoic{$s}; $r = $self->{$s} if !$r; if(!$r){ $self->warn("Unable to find property to translate macro expansion: $e -> $find\n"); @@ -1008,7 +1023,7 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; $v =~ s/\Q$find\E/$r/g; } } - $ANONS->{$e}=$v; + $anechoic->{$e}=$v; }else{ $items[@items] = $struct; } @@ -1021,7 +1036,14 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; my $type = ref($struct); if($type eq 'CNFNode' && $struct-> priority() > 0){ $struct->validate() if $self->{ENABLE_WARNINGS}; - $ANONS ->{$struct->name()} = $struct->process($self, $struct->script()); + if($struct->name() eq CNFMeta::ANN()){ + my $anode = $struct->process($self, $struct->script()); + foreach my $node($$anode->nodes()){ + $anechoic ->{$node->name()} = \$node; + } + }else{ + $anechoic ->{$struct->name()} = $struct->process($self, $struct->script()); + } splice @items, $idx, 1 } } @@ -1031,7 +1053,7 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; my $type = ref($struct); if($type eq 'CNFNode'){ $struct->validate() if $self->{ENABLE_WARNINGS}; - $ANONS->{$struct->name()} = $struct->process($self, $struct->script()); + $anechoic->{$struct->name()} = $struct->process($self, $struct->script()); }elsif($type eq 'InstructedDataItem'){ my $t = $struct->{ins}; if($t eq 'PLUGIN'){ @@ -1380,7 +1402,7 @@ sub writeOut { my ($self, $handle, $property) = @_; return 1; } else{ - $prp = $ANONS{$property}; + $prp = $anechoic->{$property}; $prp = $self->{$property} if !$prp; if (!$prp){ $buffer = "<Property not found!>>>\n" @@ -1417,11 +1439,11 @@ sub log { $message = "$type $message" if $isWarning; if($message =~ /^ERROR/ || ($isWarning && $self->{ENABLE_WARNINGS})){ - $message =~ s/(\s+line\s)(\d+)\.*\s+/:$2\n/gm; - warn $time . " " .$message; + $message =~ s/(\s+line\s)(\d+)\.*\s+/:$2\n/gm; + warn $time . " " .$message; } elsif(%log && $log{console}){ - print $time . " " .$message ."\n" + print $time . " " .$message ."\n" } if(%log && _isTrue($log{enabled}) && $message){ my $dir = $log{directory}; $dir = '.' if not $dir; $dir .= '/' if $dir !~ /\/$/; @@ -1501,8 +1523,8 @@ sub JSON { } ### -# CNFNodes are kept as anons by the TREE instruction, but these either could have been futher processed or -# externaly assigned too as nodes to the parser. +# CNFNodes are kept as anons by the TREE instruction, but these either could have been further processed or +# externally assigned too as nodes to the parser. ### our %NODES; sub addTree { @@ -1511,7 +1533,7 @@ sub addTree { $NODES{$name} = $node; } } -### Utility way to obtain CNFNodes from a configuration. +### Utility way to obtain CNFNodes from an configuration. sub getTree { my ($self, $name) = @_; return $NODES{$name} if exists $NODES{$name}; @@ -1519,10 +1541,10 @@ sub getTree { if(ref($ret) eq 'CNFNode'){ return \$ret; } - return; + return $ret } ## -# Conveniently ribs an cnf file for an pl source file to be next too in marriage. +# Conveniently ribs an cnf file for an pl source file to be next to in marriage. # Ribs means the config file is same name next to it. # @$const - Dynamic instance assignable hash with constances, optional can be undef. # @$file - Path to CNF file if missing will be created. -- 2.34.1