]> git.sur5r.net Git - i3/i3/blobdiff - generate-command-parser.pl
generate-command-parser: make input/output configurable
[i3/i3] / generate-command-parser.pl
index 9220b30e8f722798c3f3b5eff6201b98010d04a3..ed05efd420577bf56e83367fab1683e4269159c9 100755 (executable)
 use strict;
 use warnings;
 use Data::Dumper;
+use Getopt::Long;
 use v5.10;
 
+my $input = '';
+my $prefix = '';
+my $result = GetOptions(
+    'input=s' => \$input,
+    'prefix=s' => \$prefix
+);
+
+die qq|Input file "$input" does not exist!| unless -e $input;
+
 # reads in a whole file
 sub slurp {
     open my $fh, '<', shift;
@@ -24,8 +34,6 @@ sub slurp {
 # Stores the different states.
 my %states;
 
-# XXX: don’t hardcode input and output
-my $input = '../parser-specs/commands.spec';
 my @raw_lines = split("\n", slurp($input));
 my @lines;
 
@@ -90,7 +98,7 @@ for my $line (@lines) {
                 next_state => $action,
             };
             if (exists $states{$current_state}) {
-                push $states{$current_state}, $store_token;
+                push @{$states{$current_state}}, $store_token;
             } else {
                 $states{$current_state} = [ $store_token ];
             }
@@ -103,7 +111,7 @@ for my $line (@lines) {
 # It is important to keep the order the same, so we store the keys once.
 my @keys = keys %states;
 
-open(my $enumfh, '>', 'GENERATED_enums.h');
+open(my $enumfh, '>', "GENERATED_${prefix}_enums.h");
 
 # XXX: we might want to have a way to do this without a trailing comma, but gcc
 # seems to eat it.
@@ -117,9 +125,8 @@ say $enumfh '} cmdp_state;';
 close($enumfh);
 
 # Third step: Generate the call function.
-open(my $callfh, '>', 'GENERATED_call.h');
-say $callfh 'static char *GENERATED_call(const int call_identifier) {';
-say $callfh '    char *output = NULL;';
+open(my $callfh, '>', "GENERATED_${prefix}_call.h");
+say $callfh 'static void GENERATED_call(const int call_identifier, struct CommandResult *result) {';
 say $callfh '    switch (call_identifier) {';
 my $call_id = 0;
 for my $state (@keys) {
@@ -143,17 +150,17 @@ for my $state (@keys) {
         say $callfh '#ifndef TEST_PARSER';
         my $real_cmd = $cmd;
         if ($real_cmd =~ /\(\)/) {
-            $real_cmd =~ s/\(/(&current_match/;
+            $real_cmd =~ s/\(/(&current_match, result/;
         } else {
-            $real_cmd =~ s/\(/(&current_match, /;
+            $real_cmd =~ s/\(/(&current_match, result, /;
         }
-        say $callfh "             output = $real_cmd;";
+        say $callfh "             $real_cmd;";
         say $callfh '#else';
         # debug
         $cmd =~ s/[^(]+\(//;
         $cmd =~ s/\)$//;
         $cmd = ", $cmd" if length($cmd) > 0;
-        say $callfh qq|           printf("$fmt\\n"$cmd);|;
+        say $callfh qq|           fprintf(stderr, "$fmt\\n"$cmd);|;
         say $callfh '#endif';
         say $callfh "             state = $next_state;";
         say $callfh "             break;";
@@ -164,17 +171,16 @@ for my $state (@keys) {
 say $callfh '        default:';
 say $callfh '            printf("BUG in the parser. state = %d\n", call_identifier);';
 say $callfh '    }';
-say $callfh '    return output;';
 say $callfh '}';
 close($callfh);
 
 # Fourth step: Generate the token datastructures.
 
-open(my $tokfh, '>', 'GENERATED_tokens.h');
+open(my $tokfh, '>', "GENERATED_${prefix}_tokens.h");
 
 for my $state (@keys) {
     my $tokens = $states{$state};
-    say $tokfh 'cmdp_token tokens_' . $state . '[' . scalar @$tokens . '] = {';
+    say $tokfh 'static cmdp_token tokens_' . $state . '[' . scalar @$tokens . '] = {';
     for my $token (@$tokens) {
         my $call_identifier = 0;
         my $token_name = $token->{token};
@@ -194,7 +200,7 @@ for my $state (@keys) {
     say $tokfh '};';
 }
 
-say $tokfh 'cmdp_token_ptr tokens[' . scalar @keys . '] = {';
+say $tokfh 'static cmdp_token_ptr tokens[' . scalar @keys . '] = {';
 for my $state (@keys) {
     my $tokens = $states{$state};
     say $tokfh '    { tokens_' . $state . ', ' . scalar @$tokens . ' },';