From 23adf747f69f658ba9d88a6b7bc908f56e7941ae Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Wed, 24 Aug 2005 23:34:05 +0000 Subject: [PATCH] * copied {pre,}config.in and mnemosyne.pl from branches/0.1 git-svn-id: svn://svn.opensde.net/mnemosyne/trunk@5 e2230855-02ff-0310-8c61-eb8030571770 --- config.in | 45 ++++ mnemosyne.pl | 648 +++++++++++++++++++++++++++++++++++++++++++++++++++ preconfig.in | 15 ++ 3 files changed, 708 insertions(+) create mode 100644 config.in create mode 100644 mnemosyne.pl create mode 100644 preconfig.in diff --git a/config.in b/config.in new file mode 100644 index 0000000..ae955fd --- /dev/null +++ b/config.in @@ -0,0 +1,45 @@ +#!/bin/sh +# --- T2-COPYRIGHT-NOTE-BEGIN --- +# This copyright note is auto-generated by ./scripts/Create-CopyPatch. +# +# T2 SDE: target/mnemosyne/config.in +# Copyright (C) 2004 - 2005 The T2 SDE Project +# +# More information can be found in the files COPYING and README. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. A copy of the +# GNU General Public License can be found in the file COPYING. +# --- T2-COPYRIGHT-NOTE-END --- + +if [ ! -s $cfgtmpdir/config.mnemosyne.in ]; then + rm -f $cfgtmpdir/{config,rules,awkgen}.mnemosyne.in + + perl ./target/mnemosyne/mnemosyne.pl "./target/mnemosyne/pkgsel" TRG_MNEMOSYNE \ + $cfgtmpdir/config.mnemosyne.in \ + $cfgtmpdir/rules.mnemosyne.in \ + $cfgtmpdir/awkgen.mnemosyne.in + +fi + +bool 'Copy cache files of mnemoc`s optional packages' SDECFG_TRG_MNEMOSYNE_COPYCACHE 0 +block_end + +block_begin 5 + if [ -s $cfgtmpdir/config.mnemosyne.in ]; then + . $cfgtmpdir/rules.mnemosyne.in + . $cfgtmpdir/config.mnemosyne.in + else + comment ' ' + comment 'ERROR: plugins config was not rendered!' + fi +block_end + +if [ -s $cfgtmpdir/awkgen.mnemosyne.in ]; then + . $cfgtmpdir/awkgen.mnemosyne.in DISABLE_ALL \ + > $cfgtmpdir/pkgsel.mnemosyne.awk + pkgfilter awk -f $cfgtmpdir/pkgsel.mnemosyne.awk +fi + +block_begin 7 diff --git a/mnemosyne.pl b/mnemosyne.pl new file mode 100644 index 0000000..1b3a4c9 --- /dev/null +++ b/mnemosyne.pl @@ -0,0 +1,648 @@ +#!/usr/bin/perl +# --- T2-COPYRIGHT-NOTE-BEGIN --- +# This copyright note is auto-generated by ./scripts/Create-CopyPatch. +# +# T2 SDE: target/mnemosyne/mnemosyne.pl +# Copyright (C) 2004 - 2005 The T2 SDE Project +# +# More information can be found in the files COPYING and README. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. A copy of the +# GNU General Public License can be found in the file COPYING. +# --- T2-COPYRIGHT-NOTE-END --- + +use warnings; +use strict; +use IPC::Open2; + +use constant {ALL => 0, ASK => 1, CHOICE => 2 }; +%::FOLDER=(); +%::MODULE=(); + +sub scandir { + my ($pkgseldir,$prefix) = @_; + my %current=('location', $pkgseldir, 'var', "CFGTEMP_$prefix"); + + # $current{desc,var} for sub-pkgsel dirs + if ($pkgseldir ne $::ROOT) { + my ($relative,$dirvar,$dirname); + $_ = $pkgseldir; + $relative = (m/^$::ROOT\/(.*)/i)[0]; + + $dirvar = "CFGTEMP_$prefix\_$relative"; + $dirvar =~ tr,a-z\/,A-Z_,; + + $dirname=$relative; + $dirname=~ s/.*\///g; + + $current{desc} = $dirname; + $current{var} = $dirvar; + } + + # make this folder global + $::FOLDER{$current{var}} = \%current; + + { + # make scandir recursive + my @children; + opendir(my $DIR, $pkgseldir); + foreach( grep { ! /^\./ } sort readdir($DIR) ) { + $_ = "$pkgseldir/$_"; + if ( -d $_ ) { + my $subdir = scandir($_,$prefix); + push @children,$subdir; + } else { + my $module=scanmodule($_,$prefix,$current{var}); + if ($module) { + push @children,$module unless grep(/^$module$/,@children); + } + } + } + closedir $DIR; + $current{children} = \@children; + return $current{var}; + } + +} + +sub scanmodule { + my ($file,$prefix,$folder)=@_; + my (%current,$FILE); + + # this defines dir,key,option and kind acording to the following format. + # $dir/[$prio-]$var[$option].$kind + do { + my ($dir,$key,$option,$kind); + m/^(.*)\/(\d+-)?([^\.]*).?([^\.]*)?\.([^\/\.]*)/i; + ($dir,$key,$option,$kind) = ($1,$3,$4,$5); + + if ($kind eq 'choice') { $current{kind} = CHOICE; $current{option} = $option; } + elsif ($kind eq 'all') { $current{kind} = ALL; } + elsif ($kind eq 'ask') { $current{kind} = ASK; } + else { return; } + + $current{location} = $dir; + $current{key} = $key; + $current{file} = $file; + + } for $file; + + open($FILE,'<',$file); + while(<$FILE>) { + if (/^#[^#: ]+: /) { + my ($field,$value) = m/^#([^#: ]+): (.*)$/i; + if ($field eq 'Description') { + $current{desc} = $value; + } elsif ($field eq 'Variable') { + $current{var} = $value; + } elsif ($field eq 'Default') { + $current{default} = $value; + } elsif ($field eq 'Forced') { + $current{forced} = $value; + } elsif ($field eq 'Imply') { + $current{imply} = $value; + } elsif ($field eq 'Dependencies') { + $current{deps} = $value; + # } else { + # print "$file:$field:$value.\n"; + } + } + } + close($FILE); + + # var name + $current{var} = uc $current{key} + unless exists $current{var}; + $current{var} = "SDECFG_$prefix\_" . $current{var} + unless $current{var} =~ /^SDECFG_$prefix\_/; + + # for choices, we use $option instead of $key as description + ($current{desc} = $current{option}) =~ s/_/ /g + if exists $current{option} && ! exists $current{desc}; + ($current{desc} = $current{key}) =~ s/_/ /g + unless exists $current{desc}; + + # dependencies + # NOTE: don't use spaces on the pkgsel file, only to delimite different dependencies + if (exists $current{deps}) { + my @deps; + for ( split (/\s+/,$current{deps}) ) { + $_="SDECFG_$prefix\_$_" unless /^SDECFG/; + + if (/=/) { + m/(.*)(==|!=|=)(.*)/i; + $_="\"\$$1\" $2 $3"; + } else { + $_="\"\$$_\" == 1"; + } + + push @deps,$_; + } + $current{deps} = \@deps; + } + + # forced modules + if (exists $current{forced}) { + my @forced; + for ( split (/\s+/,$current{forced}) ) { + $_="SDECFG_$prefix\_$_" unless /^SDECFG/; + + $_="$_=1" unless /=/; + push @forced,$_; + } + $current{forced} = \@forced; + } + + # implied options + if (exists $current{imply}) { + my @imply = split (/\s+/,$current{imply}); + $current{imply} = \@imply; + } + + # make this module global + if ( $current{kind} == CHOICE ) { + + # prepare the option for this choice + my %option; + for ('desc','forced','imply','deps','option','file') { + $option{$_}=$current{$_} if exists $current{$_}; + } + + if ( exists $::MODULE{$current{var}} ) { + push @{ $::MODULE{$current{var}}{options} },\%option; + } else { + # prepare and add this choice module + my @options = (\%option); + + $::MODULE{$current{var}} = { + 'kind', CHOICE, + 'options', \@options, + }; + + for ('key','location','var') { + $::MODULE{$current{var}}{$_}=$current{$_} + if exists $current{$_}; + } + } + + } else { + $::MODULE{$current{var}} = {}; + for ('key','location','var','desc','forced','deps','file','kind') { + $::MODULE{$current{var}}{$_}=$current{$_} + if exists $current{$_}; + } + } + + # default value + $::MODULE{$current{var}}{folder} = $folder; + $::MODULE{$current{var}}{default} = $current{default} + if exists $current{default}; + + return $current{var}; + } + +sub process_modules { + my ($READ,$WRITE); + my $i=0; + my $first; + +# print STDERR "process_modules...\n"; + open2($READ, $WRITE, 'tsort'); + # prepare topographic modules map + for my $module (values %::MODULE) { + $first=$module->{var} unless $first; + + print $WRITE "$module->{var}\n"; + $i++; + for (@{exists $module->{deps} ? $module->{deps} : []} ) { + my $dep = (m/"\$([^"]+)"/i)[0]; + print $WRITE "$dep $module->{var}\n"; + $i++ + } + for (@{exists $module->{forced} ? $module->{forced} : []} ) { + my $forced = (m/([^"]+)=/i)[0]; + print $WRITE "$module->{var} $forced\n"; + $i++ + } + } +# print STDERR "\t... $i ". ($i % 2) . "\n"; + + print $WRITE "$first\n$first\n" unless ( $i % 2 ); + + close($WRITE); + + # and populate the sorted list + my @sorted; + while(<$READ>) { + if (/(.*)\n/) { push @sorted, $1; } + } + + # and remember the sorted list + $::MODULES=\@sorted; +} + +sub process_folders { + my ($READ,$WRITE); + my $i=0; + my $first; + +# print STDERR "process_folders...\n"; + open2($READ, $WRITE, 'tsort | tac'); + # prepare topographic modules map + for my $folder (values %::FOLDER) { + for (@{exists $folder->{children} ? $folder->{children} : []} ) { + $first=$folder->{var} unless $first; + print $WRITE "$folder->{var} $_\n" unless /^SDECFG/; + $i++; + } + } +# print STDERR "\t... $i ". ($i % 2) . "\n"; + print $WRITE "$first\n$first\n" unless ( $i % 2 ); + + close($WRITE); + + # and populate the sorted list + my @sorted; + while(<$READ>) { + if (/(.*)\n/) { push @sorted, $1; } + } + + # and remember the sorted list + $::FOLDERS=\@sorted; +} + +sub render_widgets_folder { + my ($folder,$offset) = @_; + for (@{$folder->{children}}) { + if (/^CFGTEMP/) { + my $subfolder=$::FOLDER{$_}; + print "\n${offset}# $_\n${offset}#\n"; + + # opening + print "${offset}if [ \"\$$subfolder->{var}\" == 1 ]; then\n"; + print "${offset}\tcomment '-- $subfolder->{desc}'\n"; + print "${offset}\tblock_begin 2\n"; + print "${offset}fi\n"; + + render_widgets_folder($::FOLDER{$_},"$offset\t"); + + # closing + print "${offset}if [ \"\$$subfolder->{var}\" == 1 ]; then\n"; + print "${offset}\tblock_end\n"; + print "${offset}fi\n"; + } else { + my $module=$::MODULE{$_}; + my $var=$module->{var}; + my $conffile="$module->{location}/$module->{key}.conf" + if -f "$module->{location}/$module->{key}.conf"; + + print "${offset}# $var\n"; + + if ($module->{kind} == CHOICE) { + # CHOICE + my $tmpvar = "CFGTEMP_$1" if $var =~ m/^SDECFG_(.*)/i; + my $listvar = "$tmpvar\_LIST"; + my $defaultvar = "$tmpvar\_DEFAULT"; + + print "${offset}if \[ -n \"\$$var\" \]; then\n"; + print "${offset}\tchoice $var \$$defaultvar \$$listvar\n"; + print "${offset}\t. $conffile\n" if $conffile; + print "${offset}fi\n"; + + } elsif ($module->{kind} == ASK) { + # ASK + my $default=0; + $default = $module->{default} if exists $module->{default}; + + print "${offset}if \[ -n \"\$$var\" \]; then\n"; + print "${offset}\tbool '$module->{desc}' $module->{var} $default\n"; + print "${offset}\t\[ \"\$$var\" == 1 \] && . $conffile\n" if $conffile; + print "${offset}fi\n"; + } elsif ($conffile) { + # ALL, only if $conffile + print "${offset}if \[ -n \"\$$var\" \]; then\n"; + print "${offset}\t. $conffile\n" if $conffile; + print "${offset}fi\n"; + } + } + } + } +sub render_widgets { + open(my $FILE,'>',$_[0]); + my $root="CFGTEMP_$_[1]"; + + select $FILE; + render_widgets_folder($::FOLDER{$root},''); + select STDOUT; + close($FILE); + } + +sub pkgsel_parse { + my ($action,$patternlist) = @_; + if ($action eq 'X' or $action eq 'x' ) { + $action = '$1="X"'; + } elsif ($action eq 'O' or $action eq 'o') { + $action = '$1="O"'; + } elsif ($action eq '-') { + $action = 'next'; + } else { + $action = '{ exit; }'; + } + + my ($address,$first,$others)= ('','( ','&& '); + + for (split(/\s+/,$patternlist)) { + if (! $address and $_ eq '!') { + $address = '! '; + $others = '|| $4"/"$5 ~'; + } else { + $_="\*/$_" unless /\//; + s,[^a-zA-Z0-9_/\*+\.-],,g; + s,([/\.\+]),\\$1,g; + s,\*,[^/]*,g; + next unless $_; + $address = "$address$first"; + $address = "$address / $_ /"; + $first = "$others"; + } + +=for nobody + [ "$pattern" ] || continue + address="$address$first" + address="$address / $pattern /" + first=" $others" + +=cut + } + + print "\techo '$address ) { $action; }'\n"; + return 1; +} +sub render_awkgen { + open(my $OUTPUT,'>',$_[0]); + select $OUTPUT; + + # initially change packages $4 and $5 to be able to correctly match repo based. + print "echo '{'\n"; + print "echo '\trepo=\$4 ;'\n"; + print "echo '\tpkg=\$5 ;'\n"; + print "echo '\t\$5 = \$4 \"/\" \$5 ;'\n"; + print "echo '\t\$4 = \"placeholder\" ;'\n"; + + # if awkgen is sourced with DISABLE_ALL as argument + # we disable everything before starting + print "if [ \"\$1\" == DISABLE_ALL ]; then\n"; + print "\techo '\t\$1=\"O\" ;'\n"; + print "fi\n"; + + print "echo '}'\n"; + + for (values %::MODULE) { + my $module=$_; + if ($module->{kind} == CHOICE) { + my %options; + + # the list of options and their implyed options + for (@{ $module->{options} }) { + my $option = $_; + my @array=("\$$module->{var} == $_->{option}"); + $options{$_->{option}} = \@array; + if (exists $option->{imply}) { + for (@{ $option->{imply} }) { + push @{$options{$option->{option}}}, + "\$module->{var} == $_"; + } + } + } + + print "\n"; + # and finally, render. + for (@{ $module->{options} }) { + print "if [ " . join(' -o ',@{ $options{ $_->{option} }}). " ]; then\n"; + + open(my $FILE,'<',$_->{file}); + my $hasrules=0; + while(<$FILE>) { + next if /^#/; + next if /^\s*$/; + pkgsel_parse($1,$2) if m/^([^\s]+)\s+(.*)\s*\n?$/i; + $hasrules=1; + } + close($FILE); + print "\ttrue\n" unless $hasrules; + + print "fi\n"; + } + } else { + print "\nif [ \"\$$module->{var}\" == 1 ]; then\n"; + open(my $FILE,'<',$module->{file}); + my $hasrules=0; + while(<$FILE>) { + next if /^#/; + next if /^\s*$/; + pkgsel_parse($1,$2) if m/^([^\s]+)\s+(.*)\s*\n?$/i; + $hasrules=1; + } + close($FILE); + print "\ttrue\n" unless $hasrules; + print "fi\n"; + } + } + + # ... restore $4 and $5, and print the resulting line + print "echo '{'\n"; + print "echo '\t\$4=repo ;'\n"; + print "echo '\t\$5=pkg ;'\n"; + print "echo '\tprint ;'\n"; + print "echo '}'\n"; + + select STDOUT; + close($OUTPUT); + } + +sub render_rules_module { + my ($module,$offset) = @_; + my $var = $module->{var}; + + if ($module->{kind} == CHOICE) { + my $tmpvar = "CFGTEMP_$1" if $var =~ m/^SDECFG_(.*)/i; + my $listvar = "$tmpvar\_LIST"; + my $defaultvar = "$tmpvar\_DEFAULT"; + my $default = "undefined"; + my $forcer; + + $default = $module->{default} if exists $module->{default}; + + # initialize the list + print "${offset}$listvar=\n"; + + print "${offset}$defaultvar=$default\n"; + print "${offset}\[ -n \"\$$var\" \] || $var=$default\n\n"; + + for ( @{ $module->{options} } ) { + my $option = $_; + (my $desc = $option->{desc}) =~ s/ /_/g; + + # has something to force? + if (exists $option->{forced}) { $forcer = 1; } + + if (exists $option->{deps}) { + print "${offset}if [ " . + join(' -a ', @{ $option->{deps} } ) . + " ]; then\n"; + print "${offset}\t$listvar=\"\$$listvar $option->{option} $desc\"\n"; + print "${offset}fi\n"; + } else { + print "${offset}$listvar=\"\$$listvar $option->{option} $desc\"\n"; + } + } + + # enable the folder display + print "${offset}if \[ -n \"\$$listvar\" \]; then\n"; + print "${offset}\t$module->{folder}=1\n"; + print "${offset}else\n"; + print "${offset}\tunset $module->{var}\n"; + print "${offset}fi\n"; + + # has something to force? + if ($forcer) { + print "\n${offset}case \"\$$var\" in\n"; + for ( @{ $module->{options} } ) { + my $option = $_; + if (exists $option->{forced}) { + print "${offset}\t$option->{option})\n"; + for ( @{ $option->{forced} } ) { + print "$offset\t\t$_\n"; + print "$offset\t\tSDECFGSET_$1\n" if $_ =~ m/^SDECFG_(.*)/i; + } + print "${offset}\t\t;;\n"; + } + } + print "${offset}esac\n"; + } + + # printref($var,$module,$offset); + } elsif ($module->{kind} == ASK) { + my $default=0; + $default = $module->{default} if exists $module->{default}; + + #enable the folder display + print "$offset$module->{folder}=1\n"; + + # and set the default value if none is set. + print "$offset\[ -n \"\$$var\" \] || $var=$default\n"; + + # if enabled, append pkgsel and force the forced + + if (exists $module->{forced}) { + print "\n${offset}if [ \"\$$var\" == 1 ]; then\n"; + for ( @{ $module->{forced} } ) { + print "$offset\t$_\n"; + print "$offset\tSDECFGSET_$1\n" if $_ =~ m/^SDECFG_(.*)/i; + } + print $offset."fi\n"; + } + } else { + # just enable the feature + print "$offset$var=1\n"; + + # forced list doesn't make sense for {kind} == ALL + } + + } +sub render_rules_nomodule { + my ($module,$offset) = @_; + my $var = $module->{var}; + + # unset the choice list, and the var + if ($module->{kind} == CHOICE) { + my $listvar = "CFGTEMP_$1_LIST" if $var =~ m/^SDECFG_(.*)/i; + print "${offset}unset $listvar\n"; + } + print "${offset}unset SDECFGSET_$1\n" if $var =~ m/^SDECFG_(.*)/i; + print "${offset}unset $var\n"; + } + +sub render_rules { + open(my $FILE,'>',$_[0]); + select $FILE; + + # clean folder enablers + print "#\n# folder enablers\n#\n\n"; + for (@$::FOLDERS) { print "$_=\n"; } + + # pkgsel list + for (@$::MODULES) { + my $module = $::MODULE{$_}; + print "\n#\n# $module->{var} (" + . ($module->{kind} == ALL ? "ALL" : ($module->{kind} == ASK ? "ASK" : "CHOICE" ) ) + . ")\n#\n"; + + + if (exists $module->{deps}) { + print "if [ " . join(' -a ', @{ $module->{deps} } ) . " ]; then\n"; + render_rules_module($module,"\t"); + print "else\n"; + render_rules_nomodule($module,"\t"); + print "fi\n"; + } else { + render_rules_module($module,""); + } + } + + print "\n#\n# enable folder with enabled subfolders\n#\n"; + for (@$::FOLDERS) { + my $folder = $::FOLDER{$_}; + my @subdirs = grep(/^CFGTEMP/,@{$folder->{children}}); + if ( @subdirs ) { + print "if [ -n \"\$".join('$', @subdirs )."\" ]; then\n"; + print "\t$folder->{var}=1\n"; + print "fi\n"; + } + } + + select STDOUT; + close($FILE); + } + +# print the content of a hash +sub printref { + my ($name,$ref,$offset) = @_; + my $typeof = ref($ref); + + print "$offset$name:"; + if ($typeof eq '') { + print " '$ref'\n"; + } elsif ($typeof eq 'HASH') { + print "\n"; + for (sort keys %{ $ref }) { + printref($_,$ref->{$_},"$offset\t"); + } + } elsif ($typeof eq 'ARRAY') { + my $i=0; + print "\n"; + for (@{ $ref }) { + printref("[$i]",$_,"$offset\t"); + $i++; + } + } else { + print " -> $typeof\n"; + } +} + +if ($#ARGV != 4) { + print "Usage mnemosyne.pl: \n"; + exit (1); + } + +$| = 1; + +$::ROOT=$ARGV[0]; +scandir($ARGV[0],$ARGV[1]); +process_modules(); +process_folders(); +render_rules($ARGV[3],$ARGV[1]); +render_widgets($ARGV[2],$ARGV[1]); +render_awkgen($ARGV[4],$ARGV[1]); diff --git a/preconfig.in b/preconfig.in new file mode 100644 index 0000000..98cb744 --- /dev/null +++ b/preconfig.in @@ -0,0 +1,15 @@ +# --- T2-COPYRIGHT-NOTE-BEGIN --- +# This copyright note is auto-generated by ./scripts/Create-CopyPatch. +# +# T2 SDE: target/mnemosyne/preconfig.in +# Copyright (C) 2004 - 2005 The T2 SDE Project +# +# More information can be found in the files COPYING and README. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. A copy of the +# GNU General Public License can be found in the file COPYING. +# --- T2-COPYRIGHT-NOTE-END --- + +var_append CFGTEMP_TARGETLIST ' ' "mnemosyne2 Mnemosyne_Linux_(TRUNK)"