@@ -60,9 +60,7 @@ cmd_compat_c = \
quiet_cmd_xlat_headers = GEN $@
cmd_xlat_headers = \
- while read what name; do \
- $(SHELL) $(srctree)/tools/get-fields.sh "$$what" compat_$$name $< || exit $$?; \
- done <$(patsubst $(obj)/compat/%,$(obj)/compat/.xlat/%,$(basename $<)).lst >$@.new; \
+ $(PERL) $(srctree)/tools/compat-xlat-header.pl $< $(patsubst $(obj)/compat/%,$(obj)/compat/.xlat/%,$(basename $<)).lst > $@.new; \
mv -f $@.new $@
targets += $(headers-y)
@@ -80,7 +78,7 @@ $(obj)/compat/%.c: $(src)/public/%.h $(srcdir)/xlat.lst $(srctree)/tools/compat-
$(call if_changed,compat_c)
targets += $(patsubst compat/%, compat/.xlat/%, $(headers-y))
-$(obj)/compat/.xlat/%.h: $(obj)/compat/%.h $(obj)/compat/.xlat/%.lst $(srctree)/tools/get-fields.sh FORCE
+$(obj)/compat/.xlat/%.h: $(obj)/compat/%.h $(obj)/compat/.xlat/%.lst $(srctree)/tools/compat-xlat-header.pl FORCE
$(call if_changed,xlat_headers)
quiet_cmd_xlat_lst = GEN $@
new file mode 100755
@@ -0,0 +1,539 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+open COMPAT_LIST, "<$ARGV[1]" or die "can't open $ARGV[1], $!";
+open HEADER, "<$ARGV[0]" or die "can't open $ARGV[0], $!";
+
+my @typedefs;
+
+my @header_tokens;
+while (<HEADER>) {
+ next if m/^\s*#.*/;
+ s/([\]\[,;:{}])/ $1 /g;
+ s/^\s+//;
+ push(@header_tokens, split(/\s+/));
+}
+
+sub get_fields {
+ my ($looking_for) = @_;
+ my $level = 1;
+ my $aggr = 0;
+ my ($name, @fields);
+
+ foreach (@header_tokens) {
+ if (/^(struct|union)$/) {
+ unless ($level != 1) {
+ $aggr = 1;
+ @fields = ();
+ $name = '';
+ }
+ } elsif ($_ eq '{') {
+ $level++;
+ } elsif ($_ eq '}') {
+ $level--;
+ if ($level == 1 and $name eq $looking_for) {
+ push (@fields, $_);
+ return @fields;
+ }
+ } elsif (/^[a-zA-Z_].*/) {
+ unless ($aggr == 0 or $name ne "") {
+ $name = $_;
+ }
+ }
+ unless ($aggr == 0) {
+ push (@fields, $_);
+ }
+ }
+ return ();
+}
+
+sub get_typedefs {
+ my $level = 1;
+ my $state = 0;
+ my @typedefs;
+ foreach (@_) {
+ if ($_ eq 'typedef') {
+ unless ($level != 1) {
+ $state = 1;
+ }
+ } elsif (m/^COMPAT_HANDLE\(.*\)$/) {
+ unless ($level != 1 or $state != 1) {
+ $state = 2;
+ }
+ } elsif (m/^[\[\{]$/) {
+ $level++;
+ } elsif (m/^[\]\}]$/) {
+ $level--;
+ } elsif ($_ eq ';') {
+ unless ($level != 1) {
+ $state = 0;
+ }
+ } elsif (m/^[a-zA-Z_].*$/) {
+ unless ($level != 1 or $state != 2) {
+ push (@typedefs, $_);
+ }
+ }
+ }
+ return @typedefs;
+}
+
+sub build_enums {
+ my ($name, @tokens) = @_;
+
+ my $level = 1;
+ my $kind = '';
+ my $named = '';
+ my (@fields, @members, $id);
+
+ foreach (@tokens) {
+ if (m/^(struct|union)$/) {
+ unless ($level != 2) {
+ @fields = ('');
+ }
+ $kind="$_;$kind";
+ } elsif ($_ eq '{') {
+ $level++;
+ } elsif ($_ eq '}') {
+ $level--;
+ if ($level == 1) {
+ my $subkind = $kind;
+ $subkind =~ s/;.*//;
+ if ($subkind eq 'union') {
+ print "\nenum XLAT_$name {\n";
+ foreach (@members) {
+ print " XLAT_${name}_$_,\n";
+ }
+ print "};\n";
+ }
+ return;
+ } elsif ($level == 2) {
+ $named = '?';
+ }
+ } elsif (/^[a-zA-Z_].*$/) {
+ $id = $_;
+ my $k = $kind;
+ $k =~ s/.*?;//;
+ if ($named ne '' and $k ne '') {
+ shift @fields if @fields > 0 and $fields[0] eq '';
+ build_enums("${name}_$_", @fields);
+ $named = '!';
+ }
+ } elsif ($_ eq ',') {
+ unless ($level != 2) {
+ push (@members, $id);
+ }
+ } elsif ($_ eq ';') {
+ unless ($level != 2) {
+ push (@members, $id);
+ }
+ unless ($named eq '') {
+ $kind =~ s/.*?;//;
+ }
+ $named = '';
+ }
+ unless (@fields == 0) {
+ push (@fields, $_);
+ }
+ }
+}
+
+sub handle_field {
+ my ($prefix, $name, $id, $type, @fields) = @_;
+
+ if (@fields == 0) {
+ print " \\\n";
+ if ($type eq '') {
+ print "$prefix\(_d_)->$id = (_s_)->$id;"
+ } else {
+ my $k = $id;
+ $k =~ s/\./_/g;
+ print "${prefix}XLAT_${name}_HNDL_${k}(_d_, _s_);";
+ }
+ } elsif ("@fields" !~ m/[{}]/) {
+ my $tag = "@fields";
+ $tag =~ s/\s*(struct|union)\s+(compat_)?(\w+)\s.*/$3/;
+ print " \\\n";
+ print "${prefix}XLAT_$tag(&(_d_)->$id, &(_s_)->$id);"
+ } else {
+ my $func_id = $id;
+ my @func_tokens = @fields;
+ my $kind = '';
+ my $array = "";
+ my $level = 1;
+ my $arrlvl = 1;
+ my $array_type = '';
+ my $id = '';
+ my $type = '';
+ @fields = ();
+ foreach (@func_tokens) {
+ if (/^(struct|union)$/) {
+ unless ($level != 2) {
+ @fields = ('');
+ }
+ if ($level == 1) {
+ $kind = $_;
+ if ($kind eq 'union') {
+ my $tmp = $func_id;
+ $tmp =~ s/\./_/g;
+ print " \\\n";
+ print "${prefix}switch ($tmp) {"
+ }
+ }
+ } elsif ($_ eq '{') {
+ $level++;
+ $id = '';
+ } elsif ($_ eq '}') {
+ $level--;
+ $id = '';
+ if ($level == 1 and $kind eq 'union') {
+ print " \\\n";
+ print "$prefix}"
+ }
+ } elsif ($_ eq '[') {
+ if ($level != 2 or $arrlvl != 1) {
+ # skip
+ } elsif ($array eq '') {
+ $array = ' ';
+ } else {
+ $array = "$array;";
+ }
+ $arrlvl++;
+ } elsif ($_ eq ']') {
+ $arrlvl--;
+ } elsif (m/^COMPAT_HANDLE\((.*)\)$/) {
+ if ($level == 2 and $id eq '') {
+ $type = $1;
+ $type =~ s/^compat_//;
+ }
+ } elsif ($_ eq "compat_domain_handle_t") {
+ if ($level == 2 and $id eq '') {
+ $array_type = $_;
+ }
+ } elsif (m/^[a-zA-Z_].*$/) {
+ if ($id eq '' and $type eq '' and $array_type eq '') {
+ foreach $id (@typedefs) {
+ unless ($id ne $_) {
+ $type = $id;
+ }
+ }
+ if ($type eq '') {
+ $id = $_;
+ } else {
+ $id = '';
+ }
+ } else {
+ $id = $_;
+ }
+ } elsif (m/^[,;]$/) {
+ if ($level == 2 and $id !~ /^_pad\d*$/) {
+ if ($kind eq 'union') {
+ my $tmp = "$func_id.$id";
+ $tmp =~ s/\./_/g;
+ print " \\\n";
+ print "${prefix}case XLAT_${name}_$tmp:";
+ shift @fields if @fields > 0 and $fields[0] eq '';
+ handle_field("$prefix ", $name, "$func_id.$id", $type, @fields);
+ } elsif ($array eq '' and $array_type eq '') {
+ shift @fields if @fields > 0 and $fields[0] eq '';
+ handle_field($prefix, $name, "$func_id.$id", $type, @fields);
+ } elsif ($array eq '') {
+ copy_array(" ", "$func_id.$id");
+ } else {
+ $array =~ s/^.*?;//;
+ shift @fields if @fields > 0 and $fields[0] eq '';
+ handle_array($prefix, $name, "$func_id.$id", $array, $type, @fields);
+ }
+ unless ($_ ne ';') {
+ @fields = ();
+ $id = '';
+ $type = '';
+ }
+ $array = '';
+ if ($kind eq 'union') {
+ print " \\\n";
+ print "$prefix break;";
+ }
+ }
+ } else {
+ if ($array ne '') {
+ $array = "$array $_";
+ }
+ }
+ unless (@fields == 0) {
+ push (@fields, $_);
+ }
+ }
+ }
+}
+
+sub copy_array {
+ my ($prefix, $id) = @_;
+
+ print " \\\n";
+ print "${prefix}if ((_d_)->$id != (_s_)->$id) \\\n";
+ print "$prefix memcpy((_d_)->$id, (_s_)->$id, sizeof((_d_)->$id));";
+}
+
+sub handle_array {
+ my ($prefix, $name, $id, $array, $type, @fields) = @_;
+
+ my $i = $array;
+ $i =~ s/[^;]//g;
+ $i = length($i);
+ $i = "i$i";
+
+ print " \\\n";
+ print "$prefix\{ \\\n";
+ print "$prefix unsigned int $i; \\\n";
+ my $tmp = $array;
+ $tmp =~ s/;.*$//;
+ $tmp =~ s/^\s*(.*)\s*$/$1/;
+ print "$prefix for ($i = 0; $i < $tmp; ++$i) {";
+ if ($array !~ m/^.*?;/) {
+ handle_field("$prefix ", $name, "$id\[$i]", $type, @fields);
+ } else {
+ handle_array("$prefix " ,$name, "$id\[$i]", $', $type, @fields);
+ }
+ print " \\\n";
+ print "$prefix } \\\n";
+ print "$prefix\}";
+}
+
+sub build_body {
+ my ($name, @tokens) = @_;
+ my $level = 1;
+ my $id = '';
+ my $array = '';
+ my $arrlvl = 1;
+ my $array_type = '';
+ my $type = '';
+ my @fields;
+
+ printf "\n#define XLAT_$name(_d_, _s_) do {";
+
+ foreach (@tokens) {
+ if (/^(struct|union)$/) {
+ unless ($level != 2) {
+ @fields = ('');
+ }
+ } elsif ($_ eq '{') {
+ $level++;
+ $id = '';
+ } elsif ($_ eq '}') {
+ $level--;
+ $id = '';
+ } elsif ($_ eq '[') {
+ if ($level != 2 or $arrlvl != 1) {
+ # skip
+ } elsif ($array eq '') {
+ $array = ' ';
+ } else {
+ $array = "$array;";
+ }
+ $arrlvl++;
+ } elsif ($_ eq ']') {
+ $arrlvl--;
+ } elsif (m/^COMPAT_HANDLE\((.*)\)$/) {
+ if ($level == 2 and $id eq '') {
+ $type = $1;
+ $type =~ s/^compat_//;
+ }
+ } elsif ($_ eq "compat_domain_handle_t") {
+ if ($level == 2 and $id eq '') {
+ $array_type = $_;
+ }
+ } elsif (m/^[a-zA-Z_].*$/) {
+ if ($array ne '') {
+ $array = "$array $_";
+ } elsif ($id eq '' and $type eq '' and $array_type eq '') {
+ foreach $id (@typedefs) {
+ unless ($id eq $_) {
+ $type = $id;
+ }
+ }
+ if ($type eq '') {
+ $id = $_;
+ } else {
+ $id = '';
+ }
+ } else {
+ $id = $_;
+ }
+ } elsif (m/^[,;]$/) {
+ if ($level == 2 and $id !~ /^_pad\d*$/) {
+ if ($array eq '' and $array_type eq '') {
+ shift @fields if @fields > 0 and $fields[0] eq '';
+ handle_field(" ", $name, $id, $type, @fields);
+ } elsif ($array eq '') {
+ copy_array(" ", $id);
+ } else {
+ my $tmp = $array;
+ $tmp =~ s/^.*?;//;
+ shift @fields if @fields > 0 and $fields[0] eq '';
+ handle_array(" ", $name, $id, $tmp, $type, @fields);
+ }
+ unless ($_ ne ';') {
+ @fields = ();
+ $id = '';
+ $type = '';
+ }
+ $array = '';
+ }
+ } else {
+ if ($array ne '') {
+ $array = "$array $_";
+ }
+ }
+ unless (@fields == 0) {
+ push (@fields, $_);
+ }
+ }
+ print " \\\n} while (0)\n";
+}
+
+sub check_field {
+ my ($kind, $name, $field, @extrafields) = @_;
+
+ if ("@extrafields" !~ m/[{}]/) {
+ print "; \\\n";
+ if (@extrafields != 0) {
+ foreach (@extrafields) {
+ if (m/^(struct|union)$/) {
+ # skip
+ } elsif (m/^[a-zA-Z_].*/) {
+ s/^xen_//;
+ print " CHECK_$_";
+ last;
+ } else {
+ die "Malformed compound declaration: '$_'";
+ }
+ }
+ } elsif ($field !~ m/\./) {
+ print " CHECK_FIELD_($kind, $name, $field)";
+ } else {
+ my $n = $field =~ s/\./, /g;
+ print " CHECK_SUBFIELD_${n}_($kind, $name, $field)";
+ }
+ } else {
+ my $level = 1;
+ my @fields = ();
+ my $id = '';
+
+ foreach (@extrafields) {
+ if (m/^(struct|union)$/) {
+ unless ($level != 2) {
+ @fields = ('');
+ }
+ } elsif ($_ eq '{') {
+ $level++;
+ $id = '';
+ } elsif ($_ eq '}') {
+ $level--;
+ $id = '';
+ } elsif (/^compat_.*_t$/) {
+ if ($level == 2) {
+ @fields = ('');
+ s/_t$//;
+ s/^compat_//;
+ }
+ } elsif (/^evtchn_.*_compat_t$/) {
+ if ($level == 2 and $_ ne "evtchn_port_compat_t") {
+ @fields = ('');
+ s/_compat_t$//;
+ }
+ } elsif (/^[a-zA-Z_].*$/) {
+ $id = $_;
+ } elsif (/^[,;]$/) {
+ if ($level == 2 and $id !~ /^_pad\d*$/) {
+ shift @fields if @fields > 0 and $fields[0] eq '';
+ check_field($kind, $name, "$field.$id", @fields);
+ unless ($_ ne ";") {
+ @fields = ();
+ $id = '';
+ }
+ }
+ }
+ unless (@fields == 0) {
+ push (@fields, $_);
+ }
+ }
+ }
+}
+
+sub build_check {
+ my ($name, @tokens) = @_;
+ my $level = 1;
+ my (@fields, $kind, $id);
+ my $arrlvl = 1;
+
+ print "\n";
+ print "#define CHECK_$name \\\n";
+
+ foreach (@tokens) {
+ if (/^(struct|union)$/) {
+ if ($level == 1) {
+ $kind = $_;
+ print " CHECK_SIZE_($kind, $name)";
+ } elsif ($level == 2) {
+ @fields = ('');
+ }
+ } elsif ($_ eq '{') {
+ $level++;
+ $id = '';
+ } elsif ($_ eq '}') {
+ $level--;
+ $id = '';
+ } elsif ($_ eq '[') {
+ $arrlvl++;
+ } elsif ($_ eq ']') {
+ $arrlvl--;
+ } elsif (/^compat_.*_t$/) {
+ if ($level == 2 and $_ ne "compat_argo_port_t") {
+ @fields = ('');
+ s/_t$//;
+ s/^compat_//;
+ }
+ } elsif (/^[a-zA-Z_].*$/) {
+ unless ($level != 2 or $arrlvl != 1) {
+ $id = $_;
+ }
+ } elsif (/^[,;]$/) {
+ if ($level == 2 and $id !~ /^_pad\d*$/) {
+ shift @fields if @fields > 0 and $fields[0] eq '';
+ check_field($kind, $name, $id, @fields);
+ unless ($_ ne ";") {
+ @fields = ();
+ $id = '';
+ }
+ }
+ }
+
+ unless (@fields == 0) {
+ push (@fields, $_);
+ }
+ }
+ print "\n";
+}
+
+@typedefs = get_typedefs(@header_tokens);
+
+while (<COMPAT_LIST>) {
+ my ($what, $name) = split(/\s+/, $_);
+ $name =~ s/^xen//;
+
+ my @fields = get_fields("compat_$name");
+ if (@fields == 0) {
+ die "Fields of 'compat_$name' not found in '$ARGV[1]'";
+ }
+
+ if ($what eq "!") {
+ build_enums($name, @fields);
+ build_body($name, @fields);
+ } elsif ($what eq "?") {
+ build_check($name, @fields);
+ } else {
+ die "Invalid translation indicator: '$what'";
+ }
+}
deleted file mode 100644
@@ -1,528 +0,0 @@
-test -n "$1" -a -n "$2" -a -n "$3"
-set -ef
-
-SED=sed
-if test -x /usr/xpg4/bin/sed; then
- SED=/usr/xpg4/bin/sed
-fi
-if test -z ${PYTHON}; then
- PYTHON=`/usr/bin/env python`
-fi
-if test -z ${PYTHON}; then
- echo "Python not found"
- exit 1
-fi
-
-get_fields ()
-{
- local level=1 aggr=0 name= fields=
- for token in $2
- do
- case "$token" in
- struct|union)
- test $level != 1 || aggr=1 fields= name=
- ;;
- "{")
- level=$(expr $level + 1)
- ;;
- "}")
- level=$(expr $level - 1)
- if [ $level = 1 -a $name = $1 ]
- then
- echo "$fields }"
- return 0
- fi
- ;;
- [a-zA-Z_]*)
- test $aggr = 0 -o -n "$name" || name="$token"
- ;;
- esac
- test $aggr = 0 || fields="$fields $token"
- done
-}
-
-get_typedefs ()
-{
- local level=1 state=
- for token in $1
- do
- case "$token" in
- typedef)
- test $level != 1 || state=1
- ;;
- COMPAT_HANDLE\(*\))
- test $level != 1 -o "$state" != 1 || state=2
- ;;
- [\{\[])
- level=$(expr $level + 1)
- ;;
- [\}\]])
- level=$(expr $level - 1)
- ;;
- ";")
- test $level != 1 || state=
- ;;
- [a-zA-Z_]*)
- test $level != 1 -o "$state" != 2 || echo "$token"
- ;;
- esac
- done
-}
-
-build_enums ()
-{
- local level=1 kind= fields= members= named= id= token
- for token in $2
- do
- case "$token" in
- struct|union)
- test $level != 2 || fields=" "
- kind="$token;$kind"
- ;;
- "{")
- level=$(expr $level + 1)
- ;;
- "}")
- level=$(expr $level - 1)
- if [ $level = 1 ]
- then
- if [ "${kind%%;*}" = union ]
- then
- echo
- echo "enum XLAT_$1 {"
- for m in $members
- do
- echo " XLAT_${1}_$m,"
- done
- echo "};"
- fi
- return 0
- elif [ $level = 2 ]
- then
- named='?'
- fi
- ;;
- [a-zA-Z]*)
- id=$token
- if [ -n "$named" -a -n "${kind#*;}" ]
- then
- build_enums ${1}_$token "$fields"
- named='!'
- fi
- ;;
- ",")
- test $level != 2 || members="$members $id"
- ;;
- ";")
- test $level != 2 || members="$members $id"
- test -z "$named" || kind=${kind#*;}
- named=
- ;;
- esac
- test -z "$fields" || fields="$fields $token"
- done
-}
-
-handle_field ()
-{
- if [ -z "$5" ]
- then
- echo " \\"
- if [ -z "$4" ]
- then
- printf %s "$1(_d_)->$3 = (_s_)->$3;"
- else
- printf %s "$1XLAT_${2}_HNDL_$(echo $3 | $SED 's,\.,_,g')(_d_, _s_);"
- fi
- elif [ -z "$(echo "$5" | $SED 's,[^{}],,g')" ]
- then
- local tag=$(echo "$5" | ${PYTHON} -c '
-import re,sys
-for line in sys.stdin.readlines():
- sys.stdout.write(re.subn(r"\s*(struct|union)\s+(compat_)?(\w+)\s.*", r"\3", line)[0].rstrip() + "\n")
-')
- echo " \\"
- printf %s "${1}XLAT_$tag(&(_d_)->$3, &(_s_)->$3);"
- else
- local level=1 kind= fields= id= array= arrlvl=1 array_type= type= token
- for token in $5
- do
- case "$token" in
- struct|union)
- test $level != 2 || fields=" "
- if [ $level = 1 ]
- then
- kind=$token
- if [ $kind = union ]
- then
- echo " \\"
- printf %s "${1}switch ($(echo $3 | $SED 's,\.,_,g')) {"
- fi
- fi
- ;;
- "{")
- level=$(expr $level + 1) id=
- ;;
- "}")
- level=$(expr $level - 1) id=
- if [ $level = 1 -a $kind = union ]
- then
- echo " \\"
- printf %s "$1}"
- fi
- ;;
- "[")
- if [ $level != 2 -o $arrlvl != 1 ]
- then
- :
- elif [ -z "$array" ]
- then
- array=" "
- else
- array="$array;"
- fi
- arrlvl=$(expr $arrlvl + 1)
- ;;
- "]")
- arrlvl=$(expr $arrlvl - 1)
- ;;
- COMPAT_HANDLE\(*\))
- if [ $level = 2 -a -z "$id" ]
- then
- type=${token#COMPAT_HANDLE?}
- type=${type%?}
- type=${type#compat_}
- fi
- ;;
- compat_domain_handle_t)
- if [ $level = 2 -a -z "$id" ]
- then
- array_type=$token
- fi
- ;;
- [a-zA-Z]*)
- if [ -z "$id" -a -z "$type" -a -z "$array_type" ]
- then
- for id in $typedefs
- do
- test $id != "$token" || type=$id
- done
- if [ -z "$type" ]
- then
- id=$token
- else
- id=
- fi
- else
- id=$token
- fi
- ;;
- [\,\;])
- if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ]
- then
- if [ $kind = union ]
- then
- echo " \\"
- printf %s "${1}case XLAT_${2}_$(echo $3.$id | $SED 's,\.,_,g'):"
- handle_field "$1 " $2 $3.$id "$type" "$fields"
- elif [ -z "$array" -a -z "$array_type" ]
- then
- handle_field "$1" $2 $3.$id "$type" "$fields"
- elif [ -z "$array" ]
- then
- copy_array " " $3.$id
- else
- handle_array "$1" $2 $3.$id "${array#*;}" "$type" "$fields"
- fi
- test "$token" != ";" || fields= id= type=
- array=
- if [ $kind = union ]
- then
- echo " \\"
- printf %s "$1 break;"
- fi
- fi
- ;;
- *)
- if [ -n "$array" ]
- then
- array="$array $token"
- fi
- ;;
- esac
- test -z "$fields" || fields="$fields $token"
- done
- fi
-}
-
-copy_array ()
-{
- echo " \\"
- echo "${1}if ((_d_)->$2 != (_s_)->$2) \\"
- printf %s "$1 memcpy((_d_)->$2, (_s_)->$2, sizeof((_d_)->$2));"
-}
-
-handle_array ()
-{
- local i="i$(echo $4 | $SED 's,[^;], ,g' | wc -w | $SED 's,[[:space:]]*,,g')"
- echo " \\"
- echo "$1{ \\"
- echo "$1 unsigned int $i; \\"
- printf %s "$1 for ($i = 0; $i < "${4%%;*}"; ++$i) {"
- if [ "$4" = "${4#*;}" ]
- then
- handle_field "$1 " $2 $3[$i] "$5" "$6"
- else
- handle_array "$1 " $2 $3[$i] "${4#*;}" "$5" "$6"
- fi
- echo " \\"
- echo "$1 } \\"
- printf %s "$1}"
-}
-
-build_body ()
-{
- echo
- printf %s "#define XLAT_$1(_d_, _s_) do {"
- local level=1 fields= id= array= arrlvl=1 array_type= type= token
- for token in $2
- do
- case "$token" in
- struct|union)
- test $level != 2 || fields=" "
- ;;
- "{")
- level=$(expr $level + 1) id=
- ;;
- "}")
- level=$(expr $level - 1) id=
- ;;
- "[")
- if [ $level != 2 -o $arrlvl != 1 ]
- then
- :
- elif [ -z "$array" ]
- then
- array=" "
- else
- array="$array;"
- fi
- arrlvl=$(expr $arrlvl + 1)
- ;;
- "]")
- arrlvl=$(expr $arrlvl - 1)
- ;;
- COMPAT_HANDLE\(*\))
- if [ $level = 2 -a -z "$id" ]
- then
- type=${token#COMPAT_HANDLE?}
- type=${type%?}
- type=${type#compat_}
- fi
- ;;
- compat_domain_handle_t)
- if [ $level = 2 -a -z "$id" ]
- then
- array_type=$token
- fi
- ;;
- [a-zA-Z_]*)
- if [ -n "$array" ]
- then
- array="$array $token"
- elif [ -z "$id" -a -z "$type" -a -z "$array_type" ]
- then
- for id in $typedefs
- do
- test $id != "$token" || type=$id
- done
- if [ -z "$type" ]
- then
- id=$token
- else
- id=
- fi
- else
- id=$token
- fi
- ;;
- [\,\;])
- if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ]
- then
- if [ -z "$array" -a -z "$array_type" ]
- then
- handle_field " " $1 $id "$type" "$fields"
- elif [ -z "$array" ]
- then
- copy_array " " $id
- else
- handle_array " " $1 $id "${array#*;}" "$type" "$fields"
- fi
- test "$token" != ";" || fields= id= type=
- array=
- fi
- ;;
- *)
- if [ -n "$array" ]
- then
- array="$array $token"
- fi
- ;;
- esac
- test -z "$fields" || fields="$fields $token"
- done
- echo " \\"
- echo "} while (0)"
-}
-
-check_field ()
-{
- if [ -z "$(echo "$4" | $SED 's,[^{}],,g')" ]
- then
- echo "; \\"
- local n=$(echo $3 | $SED 's,[^.], ,g' | wc -w | $SED 's,[[:space:]]*,,g')
- if [ -n "$4" ]
- then
- for n in $4
- do
- case $n in
- struct|union)
- ;;
- [a-zA-Z_]*)
- printf %s " CHECK_${n#xen_}"
- break
- ;;
- *)
- echo "Malformed compound declaration: '$n'" >&2
- exit 1
- ;;
- esac
- done
- elif [ $n = 0 ]
- then
- printf %s " CHECK_FIELD_($1, $2, $3)"
- else
- printf %s " CHECK_SUBFIELD_${n}_($1, $2, $(echo $3 | $SED 's!\.!, !g'))"
- fi
- else
- local level=1 fields= id= token
- for token in $4
- do
- case "$token" in
- struct|union)
- test $level != 2 || fields=" "
- ;;
- "{")
- level=$(expr $level + 1) id=
- ;;
- "}")
- level=$(expr $level - 1) id=
- ;;
- compat_*_t)
- if [ $level = 2 ]
- then
- fields=" "
- token="${token%_t}"
- token="${token#compat_}"
- fi
- ;;
- evtchn_*_compat_t)
- if [ $level = 2 -a $token != evtchn_port_compat_t ]
- then
- fields=" "
- token="${token%_compat_t}"
- fi
- ;;
- [a-zA-Z]*)
- id=$token
- ;;
- [\,\;])
- if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ]
- then
- check_field $1 $2 $3.$id "$fields"
- test "$token" != ";" || fields= id=
- fi
- ;;
- esac
- test -z "$fields" || fields="$fields $token"
- done
- fi
-}
-
-build_check ()
-{
- echo
- echo "#define CHECK_$1 \\"
- local level=1 fields= kind= id= arrlvl=1 token
- for token in $2
- do
- case "$token" in
- struct|union)
- if [ $level = 1 ]
- then
- kind=$token
- printf %s " CHECK_SIZE_($kind, $1)"
- elif [ $level = 2 ]
- then
- fields=" "
- fi
- ;;
- "{")
- level=$(expr $level + 1) id=
- ;;
- "}")
- level=$(expr $level - 1) id=
- ;;
- "[")
- arrlvl=$(expr $arrlvl + 1)
- ;;
- "]")
- arrlvl=$(expr $arrlvl - 1)
- ;;
- compat_*_t)
- if [ $level = 2 -a $token != compat_argo_port_t ]
- then
- fields=" "
- token="${token%_t}"
- token="${token#compat_}"
- fi
- ;;
- [a-zA-Z_]*)
- test $level != 2 -o $arrlvl != 1 || id=$token
- ;;
- [\,\;])
- if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ]
- then
- check_field $kind $1 $id "$fields"
- test "$token" != ";" || fields= id=
- fi
- ;;
- esac
- test -z "$fields" || fields="$fields $token"
- done
- echo ""
-}
-
-list="$($SED -e 's,^[[:space:]]#.*,,' -e 's!\([]\[,;:{}]\)! \1 !g' $3)"
-fields="$(get_fields $(echo $2 | $SED 's,^compat_xen,compat_,') "$list")"
-if [ -z "$fields" ]
-then
- echo "Fields of '$2' not found in '$3'" >&2
- exit 1
-fi
-name=${2#compat_}
-name=${name#xen}
-case "$1" in
-"!")
- typedefs="$(get_typedefs "$list")"
- build_enums $name "$fields"
- build_body $name "$fields"
- ;;
-"?")
- build_check $name "$fields"
- ;;
-*)
- echo "Invalid translation indicator: '$1'" >&2
- exit 1
- ;;
-esac
The get-fields.sh which generate all the include/compat/.xlat/*.h headers is quite slow. It takes for example nearly 3 seconds to generate platform.h on a recent machine, or 2.3 seconds for memory.h. Since it's only text processing, rewriting the mix of shell/sed/python into a single perl script make the generation of those file a lot faster. I tried to keep a similar look for the code, to keep the code similar between the shell and perl, and to ease review. So some code in perl might look weird or could be written better. No functional change, the headers generated are identical. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- Notes: v2: - Add .pl extension to the perl script - remove "-w" from the shebang as it is duplicate of "use warning;" - Add a note in the commit message that the "headers generated are identical". xen/include/Makefile | 6 +- xen/tools/compat-xlat-header.pl | 539 ++++++++++++++++++++++++++++++++ xen/tools/get-fields.sh | 528 ------------------------------- 3 files changed, 541 insertions(+), 532 deletions(-) create mode 100755 xen/tools/compat-xlat-header.pl delete mode 100644 xen/tools/get-fields.sh