2 # --- T2-COPYRIGHT-NOTE-BEGIN ---
3 # This copyright note is auto-generated by ./scripts/Create-CopyPatch.
5 # T2 SDE: target/mnemosyne/mnemosyne.pl
6 # Copyright (C) 2004 - 2006 The T2 SDE Project
8 # More information can be found in the files COPYING and README.
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; version 2 of the License. A copy of the
13 # GNU General Public License can be found in the file COPYING.
14 # --- T2-COPYRIGHT-NOTE-END ---
20 use constant
{ALL
=> 0, ASK
=> 1, CHOICE
=> 2 };
25 my ($pkgseldir,$prefix) = @_;
26 my %current=('location', $pkgseldir, 'var', "CFGTEMP_$prefix");
28 # $current{desc,var} for sub-pkgsel dirs
29 if ($pkgseldir ne $::ROOT
) {
30 my ($relative,$dirvar,$dirname);
32 $relative = (m/^$::ROOT\/(.*)/i
)[0];
34 $dirvar = "CFGTEMP_$prefix\_$relative";
35 $dirvar =~ tr
,a
-z\
/ ,A
-Z__
,;
40 $current{desc
} = $dirname;
41 $current{var
} = $dirvar;
44 # make this folder global
45 $::FOLDER
{$current{var
}} = \
%current;
48 # make scandir recursive
50 opendir(my $DIR, $pkgseldir);
51 foreach( grep { ! /^\./ } sort readdir($DIR) ) {
54 my $subdir = scandir
($_,$prefix);
55 push @children,$subdir;
57 my $module=scanmodule
($_,$prefix,$current{var
});
59 push @children,$module unless grep(/^$module$/,@children);
64 $current{children
} = \
@children;
71 my ($file,$prefix,$folder)=@_;
74 # this defines dir,key,option and kind acording to the following format.
75 # $dir/[$prio-]$var[$option].$kind
77 my ($dir,$key,$option,$kind);
78 m/^(.*)\/(\d
+-)?
([^\
.]*).?
([^\
.]*)?\
.([^\
/\.]*)/i;
79 ($dir,$key,$option,$kind) = ($1,$3,$4,$5);
81 if ($kind eq 'choice') { $current{kind
} = CHOICE
; $current{option
} = $option; }
82 elsif ($kind eq 'all') { $current{kind
} = ALL
; }
83 elsif ($kind eq 'ask') { $current{kind
} = ASK
; }
86 $current{location
} = $dir;
88 $current{file
} = $file;
92 open($FILE,'<',$file);
95 my ($field,$value) = m/^#([^#: ]+): (.*)$/i;
96 if ($field eq 'Description') {
97 $current{desc
} = $value;
98 } elsif ($field eq 'Variable') {
99 $current{var
} = $value;
100 } elsif ($field eq 'Default') {
101 $current{default} = $value;
102 } elsif ($field eq 'Forced') {
103 $current{forced
} = $value;
104 } elsif ($field eq 'Imply') {
105 $current{imply
} = $value;
106 } elsif ($field eq 'Dependencies') {
107 $current{deps
} = $value;
109 # print "$file:$field:$value.\n";
116 $current{var
} = uc $current{key
}
117 unless exists $current{var
};
118 $current{var
} = "SDECFG_$prefix\_" . $current{var
}
119 unless $current{var
} =~ /^SDECFG_$prefix\_/;
121 # for choices, we use $option instead of $key as description
122 ($current{desc
} = $current{option
}) =~ s/_/ /g
123 if exists $current{option
} && ! exists $current{desc
};
124 ($current{desc
} = $current{key
}) =~ s/_/ /g
125 unless exists $current{desc
};
128 # NOTE: don't use spaces on the pkgsel file, only to delimite different dependencies
129 if (exists $current{deps
}) {
131 for ( split (/\s+/,$current{deps
}) ) {
132 $_="SDECFG_$prefix\_$_" unless /^(SDECFG|CFGTEMP)/;
135 m/(.*?)(==|!=|=)(.*)/i;
143 $current{deps
} = \
@deps;
147 if (exists $current{forced
}) {
149 for ( split (/\s+/,$current{forced
}) ) {
150 $_="SDECFG_$prefix\_$_" unless /^SDECFG/;
152 $_="$_=1" unless /=/;
155 $current{forced
} = \
@forced;
159 if (exists $current{imply
}) {
160 my @imply = split (/\s+/,$current{imply
});
161 $current{imply
} = \
@imply;
164 # make this module global
165 if ( $current{kind
} == CHOICE
) {
167 # prepare the option for this choice
169 for ('desc','forced','imply','deps','option','file') {
170 $option{$_}=$current{$_} if exists $current{$_};
173 if ( exists $::MODULE
{$current{var
}} ) {
174 push @
{ $::MODULE
{$current{var
}}{options
} },\
%option;
176 # prepare and add this choice module
177 my @options = (\
%option);
179 $::MODULE
{$current{var
}} = {
181 'options', \
@options,
184 for ('key','location','var') {
185 $::MODULE
{$current{var
}}{$_}=$current{$_}
186 if exists $current{$_};
191 $::MODULE
{$current{var
}} = {};
192 for ('key','location','var','desc','forced','deps','file','kind') {
193 $::MODULE
{$current{var
}}{$_}=$current{$_}
194 if exists $current{$_};
199 $::MODULE
{$current{var
}}{folder
} = $folder;
200 $::MODULE
{$current{var
}}{default} = $current{default}
201 if exists $current{default};
203 return $current{var
};
206 sub process_modules
{
207 my ($READ,$WRITE,$pid);
210 $pid = open2
($READ, $WRITE, 'tsort');
211 # prepare topographic modules map
212 for my $module (values %::MODULE
) {
215 if ($module->{kind
} == CHOICE
) {
216 for (@
{ $module->{options
} }) {
218 for (@
{exists $option->{deps
} ?
$option->{deps
} : []} ) {
219 my $dep = (m/"\$([^"]+)"/i)[0];
220 print $WRITE "$dep $module->{var}\n";
223 for (@
{exists $option->{forced
} ?
$option->{forced
} : []} ) {
224 my $forced = (m/([^"]+)=/i)[0];
225 print $WRITE "$module->{var} $forced\n";
230 for (@
{exists $module->{deps
} ?
$module->{deps
} : []} ) {
231 my $dep = (m/"\$([^"]+)"/i)[0];
232 print $WRITE "$dep $module->{var}\n";
235 for (@
{exists $module->{forced
} ?
$module->{forced
} : []} ) {
236 my $forced = (m/([^"]+)=/i)[0];
237 print $WRITE "$module->{var} $forced\n";
243 print $WRITE "$module->{var} $module->{var}\n";
249 # and populate the sorted list
252 if (/(.*)\n/) { push @sorted, $1; }
258 # and remember the sorted list
262 sub process_folders
{
263 my ($READ,$WRITE,$pid);
265 $pid = open2
($READ, $WRITE, 'tsort | tac');
266 # prepare topographic modules map
267 for my $folder (values %::FOLDER
) {
268 for ( exists $folder->{children
} ?
grep(!/^SDECFG/, @
{$folder->{children
}}) : [] ) {
269 print $WRITE "$folder->{var} $_\n";
274 # and populate the sorted list
277 if (/(.*)\n/) { push @sorted, $1; }
283 # and remember the sorted list
287 sub render_widgets_folder
{
288 my ($folder,$offset) = @_;
289 for (@
{$folder->{children
}}) {
291 my $subfolder=$::FOLDER
{$_};
292 print "\n${offset}# $_\n${offset}#\n";
295 print "${offset}if [ \"\$$subfolder->{var}\" == 1 ]; then\n";
296 print "${offset}\tmenu_begin $subfolder->{var} '$subfolder->{desc}'\n";
297 print "${offset}fi\n";
299 render_widgets_folder
($::FOLDER
{$_},"$offset\t");
302 print "${offset}if [ \"\$$subfolder->{var}\" == 1 ]; then\n";
303 print "${offset}\tmenu_end\n";
304 print "${offset}fi\n";
306 my $module=$::MODULE
{$_};
307 my $var=$module->{var
};
308 my $conffile="$module->{location}/$module->{key}.conf"
309 if -f
"$module->{location}/$module->{key}.conf";
310 my $noconffile="$module->{location}/$module->{key}-no.conf"
311 if -f
"$module->{location}/$module->{key}-no.conf";
313 print "${offset}# $var\n";
315 if ($module->{kind
} == CHOICE
) {
317 my $tmpvar = "CFGTEMP_$1" if $var =~ m/^SDECFG_(.*)/i;
318 my $listvar = "$tmpvar\_LIST";
319 my $defaultvar = "$tmpvar\_DEFAULT";
321 print "${offset}if \[ -n \"\$$var\" \]; then\n";
322 print "${offset}\tchoice $var \$$defaultvar \$$listvar\n";
323 print "${offset}\t. $conffile\n" if $conffile;
324 print "${offset}\telse\n" if $noconffile;
325 print "${offset}\t. $noconffile\n" if $noconffile;
326 print "${offset}fi\n";
328 } elsif ($module->{kind
} == ASK
) {
331 $default = $module->{default} if exists $module->{default};
333 print "${offset}if \[ -n \"\$$var\" \]; then\n";
334 print "${offset}\tbool '$module->{desc}' $module->{var} $default\n";
335 print "${offset}\t\[ \"\$$var\" == 1 \] && . $conffile\n" if $conffile;
336 print "${offset}\t\[ \"\$$var\" != 1 \] && . $noconffile\n" if $noconffile;
337 print "${offset}fi\n";
338 } elsif ($conffile) {
339 # ALL, only if $conffile
340 print "${offset}if \[ -n \"\$$var\" \]; then\n";
341 print "${offset}\t. $conffile\n" if $conffile;
342 print "${offset}\telse\n" if $noconffile;
343 print "${offset}\t. $noconffile\n" if $noconffile;
344 print "${offset}fi\n";
350 open(my $FILE,'>',$_[0]);
351 my $root="CFGTEMP_$_[1]";
354 render_widgets_folder
($::FOLDER
{$root},'');
360 my ($action,$patternlist) = @_;
361 if ($action eq 'X' or $action eq 'x' ) {
363 } elsif ($action eq 'O' or $action eq 'o') {
365 } elsif ($action eq '-') {
368 $action = '{ exit; }';
371 my ($address,$first,$others)= ('','( ','&& ');
373 for (split(/\s+/,$patternlist)) {
374 if (! $address and $_ eq '!') {
376 $others = '|| $4"/"$5 ~';
378 $_="\*/$_" unless /\
//;
379 s
,[^a
-zA
-Z0
-9_
/\
*+\
.-],,g
;
383 $address = "$address$first";
384 $address = "$address / $_ /";
389 [ "$pattern" ] || continue
390 address="$address$first"
391 address="$address / $pattern /"
397 print "\techo '$address ) { $action; }'\n";
402 open(my $OUTPUT,'>',$_[0]);
403 my $root="CFGTEMP_$_[1]";
407 # initially change packages $4 and $5 to be able to correctly match repo based.
409 print "echo '\trepo=\$4 ;'\n";
410 print "echo '\tpkg=\$5 ;'\n";
411 print "echo '\t\$5 = \$4 \"/\" \$5 ;'\n";
412 print "echo '\t\$4 = \"placeholder\" ;'\n";
415 render_awkgen_folder
($::FOLDER
{$root});
417 # ... restore $4 and $5, and print the resulting line
418 print "echo '\n{'\n";
419 print "echo '\t\$4=repo ;'\n";
420 print "echo '\t\$5=pkg ;'\n";
421 print "echo '\tprint ;'\n";
428 sub render_awkgen_folder
{
430 for (@
{$folder->{children
}}) {
432 render_awkgen_folder
($::FOLDER
{$_});
434 my $module=$::MODULE
{$_};
435 if ($module->{kind
} == CHOICE
) {
438 # the list of options
439 for (@
{ $module->{options
} }) {
441 my @array=("\"\$$module->{var}\" == $_->{option}");
442 $options{$_->{option
}} = \
@array;
444 # and their implyed options
445 for (@
{ $module->{options
} }) {
447 for (@
{exists $option->{imply
}?
$option->{imply
} : [] }) {
448 push @
{$options{$_}},
449 "\"\$$module->{var}\" == $option->{option}";
454 # and finally, render.
455 for (@
{ $module->{options
} }) {
456 print "if [ " . join(' -o ',@
{ $options{ $_->{option
} }}). " ]; then\n";
458 open(my $FILE,'<',$_->{file
});
463 pkgsel_parse
($1,$2) if m/^([^\s]+)\s+(.*)\s*\n?$/i;
467 print "\ttrue\n" unless $hasrules;
472 print "\nif [ \"\$$module->{var}\" == 1 ]; then\n";
473 open(my $FILE,'<',$module->{file
});
478 pkgsel_parse
($1,$2) if m/^([^\s]+)\s+(.*)\s*\n?$/i;
482 print "\ttrue\n" unless $hasrules;
489 sub render_rules_module
{
490 my ($module,$offset) = @_;
491 my $var = $module->{var
};
493 if ($module->{kind
} == CHOICE
) {
494 my $tmpvar = "CFGTEMP_$1" if $var =~ m/^SDECFG_(.*)/i;
495 my $listvar = "$tmpvar\_LIST";
496 my $defaultvar = "$tmpvar\_DEFAULT";
497 my $default = "undefined";
500 $default = $module->{default} if exists $module->{default};
502 # initialize the list
503 print "${offset}$listvar=\n";
505 print "${offset}$defaultvar=$default\n";
506 print "${offset}\[ -n \"\$$var\" \] || $var=$default\n\n";
508 for ( @
{ $module->{options
} } ) {
510 (my $desc = $option->{desc
}) =~ s/ /_/g;
512 # has something to force?
513 if (exists $option->{forced
}) { $forcer = 1; }
515 if (exists $option->{deps
}) {
516 print "${offset}if [ " .
517 join(' -a ', @
{ $option->{deps
} } ) .
519 print "${offset}\t$listvar=\"\$$listvar $option->{option} $desc\"\n";
520 print "${offset}fi\n";
522 print "${offset}$listvar=\"\$$listvar $option->{option} $desc\"\n";
526 # enable the folder display
527 print "${offset}if \[ -n \"\$$listvar\" \]; then\n";
528 print "${offset}\t$module->{folder}=1\n";
529 print "${offset}else\n";
530 print "${offset}\tunset $module->{var}\n";
531 print "${offset}fi\n";
533 # has something to force?
535 print "\n${offset}case \"\$$var\" in\n";
536 for ( @
{ $module->{options
} } ) {
538 if (exists $option->{forced
}) {
539 print "${offset}\t$option->{option})\n";
540 for ( @
{ $option->{forced
} } ) {
541 print "$offset\t\t$_\n";
542 print "$offset\t\tSDECFGSET_$1\n" if $_ =~ m/^SDECFG_(.*)/i;
544 print "${offset}\t\t;;\n";
547 print "${offset}esac\n";
550 # printref($var,$module,$offset);
551 } elsif ($module->{kind
} == ASK
) {
553 $default = $module->{default} if exists $module->{default};
555 #enable the folder display
556 print "$offset$module->{folder}=1\n";
558 # and set the default value if none is set.
559 print "$offset\[ -n \"\$$var\" \] || $var=$default\n";
561 # if enabled, append pkgsel and force the forced
563 if (exists $module->{forced
}) {
564 print "\n${offset}if [ \"\$$var\" == 1 ]; then\n";
565 for ( @
{ $module->{forced
} } ) {
566 print "$offset\t$_\n";
567 print "$offset\tSDECFGSET_$1\n" if $_ =~ m/^SDECFG_(.*)/i;
569 print $offset."fi\n";
572 # just enable the feature
573 print "$offset$var=1\n";
575 # forced list doesn't make sense for {kind} == ALL
579 sub render_rules_nomodule
{
580 my ($module,$offset) = @_;
581 my $var = $module->{var
};
583 # unset the choice list, and the var
584 if ($module->{kind
} == CHOICE
) {
585 my $listvar = "CFGTEMP_$1_LIST" if $var =~ m/^SDECFG_(.*)/i;
586 print "${offset}unset $listvar\n";
588 print "${offset}unset SDECFGSET_$1\n" if $var =~ m/^SDECFG_(.*)/i;
589 print "${offset}unset $var\n";
593 open(my $FILE,'>',$_[0]);
594 my $root="CFGTEMP_$_[1]";
597 # clean folder enablers
598 print "#\n# folder enablers\n#\n\n";
599 for (@
$::FOLDERS
) { print "$_=\n" unless /^$root$/; }
603 if (exists $::MODULE
{$_}) {
604 my $module = $::MODULE
{$_};
605 print "\n#\n# $module->{var} ("
606 . ($module->{kind
} == ALL ?
"ALL" : ($module->{kind
} == ASK ?
"ASK" : "CHOICE" ) )
610 if (exists $module->{deps
}) {
611 print "if [ " . join(' -a ', @
{ $module->{deps
} } ) . " ]; then\n";
612 render_rules_module
($module,"\t");
614 render_rules_nomodule
($module,"\t");
617 render_rules_module
($module,"");
622 print "\n#\n# enable folder with enabled subfolders\n#\n";
624 my $folder = $::FOLDER
{$_};
625 my @subdirs = grep(/^CFGTEMP/,@
{$folder->{children
}});
627 print "if [ -n \"\$".join('$', @subdirs )."\" ]; then\n";
628 print "\t$folder->{var}=1\n";
637 # print the content of a hash
639 my ($name,$ref,$offset) = @_;
640 my $typeof = ref($ref);
642 print "$offset$name:";
645 } elsif ($typeof eq 'HASH') {
647 for (sort keys %{ $ref }) {
648 printref
($_,$ref->{$_},"$offset\t");
650 } elsif ($typeof eq 'ARRAY') {
654 printref
("[$i]",$_,"$offset\t");
658 print " -> $typeof\n";
663 print "Usage mnemosyne.pl: <pkgseldir> <prefix> <configfile> <rulesfile> <awkgenerator>\n";
670 scandir
($ARGV[0],$ARGV[1]);
673 render_rules
($ARGV[3],$ARGV[1]);
674 render_widgets
($ARGV[2],$ARGV[1]);
675 render_awkgen
($ARGV[4],$ARGV[1]);