Git init
[external/ifupdown.git] / defn2c.pl
1 #!/usr/bin/perl -w
2
3 use strict;
4
5 # declarations
6 my $address_family = "";
7 my %methods = ();
8 my $line = "";
9 my $match = "";
10
11 # subroutines
12 sub nextline {
13         $line = <>;
14         while($line and ($line =~ /^#/ or $line =~ /^\s*$/)) {
15                 $line = <>;
16         }
17         if (!$line) { return 0; }
18         chomp $line;
19         while ($line =~ m/^(.*)\\$/) {
20                 my $addon = <>;
21                 chomp $addon;
22                 $line = $1 . $addon;
23         }
24         return 1;
25 }
26 sub match {
27         my $line = $_[0];
28         my $cmd = "$_[1]" ? "$_[1]\\b\\s*" : "";;
29         my $indentexp = (@_ == 3) ? "$_[2]\\s+" : "";
30
31         if ($line =~ /^${indentexp}${cmd}(([^\s](.*[^\s])?)?)\s*$/) {
32                 $match = $1;
33                 return 1;
34         } else {
35                 return 0;
36         } 
37 }
38 sub get_address_family {
39         $address_family = $_[0] if ($address_family eq "");
40         nextline;
41 }
42 sub get_architecture {
43         my $arch = $_[0];
44         die("architecture declaration appears too late") if (keys %methods);
45         print "#include \"arch${arch}.h\"\n\n\n";
46         nextline;
47 }
48 sub get_method {
49         my $method = $_[0];
50         my $indent = ($line =~ /(\s*)[^\s]/) ? $1 : "";
51
52         die "Duplicate method $method\n" if ($methods{$method}++);
53
54         nextline;
55         if (match($line, "description", $indent)) {
56                 skip_section();
57         }
58         if (match($line, "options", $indent)) {
59                 skip_section();
60         }
61         if (match($line, "up", $indent)) {
62                 get_commands(${method}, "up");
63         } else {
64                 print "static int ${method}_up(interface_defn ifd) { return 0; }\n"
65         }
66         if (match($line, "down", $indent)) {
67                 get_commands(${method}, "down");
68         } else {
69                 print "static int ${method}_down(interface_defn ifd) { return 0; }\n"
70         }
71 }
72 sub skip_section {
73         my $struct = $_[0];
74         my $indent = ($line =~ /(\s*)[^\s]/) ? $1 : "";
75
76         1 while (nextline && match($line, "", $indent));
77 }
78 sub get_commands {
79         my $method = $_[0];
80         my $mode = $_[1];
81         my $function = "${method}_${mode}";
82         my $indent = ($line =~ /(\s*)[^\s]/) ? $1 : "";
83
84         print "static int ${function}(interface_defn *ifd, execfn *exec) {\n";
85
86         while (nextline && match($line, "", $indent)) {
87                 if ( $match =~ /^(.*[^\s])\s+if\s*\((.*)\)\s*$/ ) {
88                         print "if ( $2 ) {\n";
89                         print "  if (!execute(\"$1\", ifd, exec)) return 0;\n";
90                         print "}\n";
91                 } elsif ( $match =~ /^(.*[^\s])\s+elsif\s*\((.*)\)\s*$/ ) {
92                         print "else if ( $2 ) {\n";
93                         print "  if (!execute(\"$1\", ifd, exec)) return 0;\n";
94                         print "}\n";
95                 } elsif ( $match =~ /^(.*[^\s])\s*$/ ) {
96                         print "{\n";
97                         print "  if (!execute(\"$1\", ifd, exec)) return 0;\n";
98                         print "}\n";
99                 }
100         }
101
102         print "return 1;\n";
103         print "}\n";
104 }
105
106 # main code
107 print "#include \"header.h\"\n\n\n";
108 nextline;
109 while($line) {
110         if (match($line, "address_family")) {
111                 get_address_family $match;
112                 next;
113         }
114         if (match($line, "architecture")) {
115                 get_architecture $match;
116                 next;
117         }
118         if (match($line, "method")) {
119                 get_method $match;
120                 next;
121         }
122
123         # ...otherwise
124         die("Unknown command \"$line\"");
125 }
126 print "static method methods[] = {\n";
127 my $method;
128 foreach $method (keys %methods) {
129         print <<EOF;
130         {
131                 "$method",
132                 ${method}_up, ${method}_down,
133         },
134 EOF
135 }
136 print "};\n\n";
137
138 print <<EOF;
139 address_family addr_${address_family} = {
140         "$address_family",
141         sizeof(methods)/sizeof(struct method),
142         methods
143 };
144 EOF