summaryrefslogtreecommitdiff
path: root/cesar/common/tools/compact-ecos-config
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/common/tools/compact-ecos-config')
-rwxr-xr-xcesar/common/tools/compact-ecos-config122
1 files changed, 122 insertions, 0 deletions
diff --git a/cesar/common/tools/compact-ecos-config b/cesar/common/tools/compact-ecos-config
new file mode 100755
index 0000000000..71e78c3ce0
--- /dev/null
+++ b/cesar/common/tools/compact-ecos-config
@@ -0,0 +1,122 @@
+#!/usr/bin/perl
+#
+# Read an ecos configuration and generate a minimal script to regenerate this
+# configuration.
+#
+use strict;
+use warnings;
+
+my $string_re = qr/ " (?: [^\\] | \\. )* " /sx;
+# Limitation: braces can nest only once.
+my $brace_re = qr/ (?: [^{}] | { [^{}]* } )* /sx;
+my $cmd_re = qr( [-<>./\w]+ )x;
+my $arg_re = qr/ $cmd_re | $string_re | { $brace_re } /x;
+my $option_cmd_re = qr/(?:value_source|(?:user|wizard|inferred)_value)/;
+
+sub read_config_check
+{
+ my ($file, $target, $tmpl) = @_;
+ # Open ecosconfig output.
+ open CONFIG, "ecosconfig --config='$file' check|"
+ or die "can not read ecosconfig output\n";
+ # Decode target and template.
+ $_ = <CONFIG>; chomp;
+ /^Target: (\w+)$/ or die "target expected\n";
+ $$target = $1;
+ $_ = <CONFIG>; chomp;
+ /^Template: (\w+)$/ or die "template expected\n";
+ $$tmpl = $1;
+ print "ecosconfig --config=\$config new $$target $$tmpl\n";
+ # Decode added and removed.
+ $_ = <CONFIG>; chomp;
+ for my $i (['Added', 'add'], ['Removed', 'remove'])
+ {
+ my ($re, $cmd) = @$i;
+ if (/^$re:$/)
+ {
+ while ($_ = <CONFIG>, chomp, /^ (\w+)/)
+ {
+ print "ecosconfig --config=\$config $cmd $1\n";
+ }
+ }
+ }
+ /^No conflicts$/ or die "no conflicts expected\n";
+ # Close.
+ close CONFIG;
+}
+
+sub read_config_file
+{
+ my ($file, $target, $tmpl) = @_;
+ # Open file.
+ open CONFIG, "<$file" or die "can not open \"$file\"\n";
+ # Slurp config text.
+ local $/;
+ local $_ = <CONFIG>;
+ close CONFIG;
+ tr/\t/ /;
+ # Decode.
+ while ($_)
+ {
+ s/^ *(?:#.*)?\n// and next;
+ s/^cdl_savefile_version 1;\n// and next;
+ s/^cdl_savefile_command $cmd_re {$brace_re};\n// and next;
+ s/^cdl_configuration eCos {($brace_re)};\n//
+ and do { decode_conf ($1, $target, $tmpl); next; };
+ s/^(cdl_(?:package|component|option|interface) \w+) {($brace_re)};\n//
+ and do { decode_option ($1, $2); next; };
+ die "unmatched text: \"" . (/(.{200})/s, $1) . "...\".\n";
+ }
+}
+
+sub decode_conf
+{
+ local $_ = shift;
+ my ($target, $tmpl) = @_;
+ while ($_)
+ {
+ s/^ *(?:#.*)?\n// and next;
+ s/^ *description +$arg_re *;\n// and next;
+ s/^ *hardware +($arg_re) *;\n// and do {
+ $target eq $1 or die "target mismatch\n";
+ next;
+ };
+ s/^ *template +($arg_re) *;\n// and do {
+ $tmpl eq $1 or die "target mismatch\n";
+ next;
+ };
+ s/^ *package +-(?:hardware|template) +$arg_re +$arg_re +;// and next;
+ s/^ *package +($arg_re) +$arg_re +;// and next;
+ die "unmatched text in conf: \"" . (/(.{200})/s, $1) . "...\".\n";
+ }
+}
+
+sub decode_option
+{
+ my $option = shift;
+ local $_ = shift;
+ my $open = 0;
+ while ($_)
+ {
+ s/^ *(?:#.*)?\n// and next;
+ s/^( *$option_cmd_re(?: +$arg_re){1,2}\n)// and do {
+ print $option, " {\n" unless $open;
+ $open = 1;
+ print $1;
+ } and next;
+ die "unmatched text in conf: \"" . (/(.{200})/s, $1) . "...\".\n";
+ }
+ print "}\n" if $open;
+}
+
+$#ARGV == 0 or die "syntax: $0 FILE\n";
+my $config_file = $ARGV[0];
+
+my ($target, $tmpl);
+
+print "config=\${1:-ecos-gen.ecc}\n";
+read_config_check ($config_file, \$target, \$tmpl);
+print "cat >> \$config <<'EOF'\n";
+read_config_file ($config_file, $target, $tmpl);
+print "EOF\n";
+print "ecosconfig --config=\$config check\n";