#!/usr/bin/perl # Read and parse commands.x to generate commands.c open(I,"commands.c") or exit(1); binmode(O); print O "/* THIS FILE IS AUTO-GENERATED, DO NOT EDIT */\n\n"; my $cmd = ""; my $linenumber = 0; my $CurrentBlock = "global"; my $Doc = {}; while(my $line = ) { chomp $line; ++$linenumber; next if ! $line; if ($line =~ /^#define/) { print O "$line\n"; next; } if ($line =~ /^\/\//) { print O "$line\n"; next; } if ($line eq '#') { AddDoc(""); next; } if ($line =~ /^#\s+(.+)/) { AddDoc($1); next; } if ($line =~ /^global (.+)$/) { AddGlobal($1); next; } if ($line =~ /^\s+/) { AddOutput($line); next; } StartBlock(lc $line); } close(I); print O "\n#include \"ninox.h\"\n\n"; foreach my $c (sort { $a cmp $b } keys %$Block) { print O "int $c(char *arg, char *val, int bval)\n\t{\n"; foreach my $l (@{$Block->{$c}}) { print O "$l\n"; } print O "\treturn(1);\n\t}\n\n"; if (exists $Doc->{$c}) { my $C = $c; $C =~ s/^_CMD_//; print O "int _HLP_$c(char *arg, char *val, int bval)\n\t{\n"; print O "\tPrint(\"\\nHelp for '%s'\\n\\n\",\"$C\");\n"; foreach my $l (@{$Doc->{$c}}) { $l =~ s/(['"])/\\$1/g; print O "\tPrint(\"\t$l\\n\");\n"; } print O "\texit(0);\n\t}\n\n"; } } print O "\n\n"; print O "struct cfunc Names[] = {\n"; foreach my $n (sort { $a cmp $b } keys %Names) { my $val = $Names{$n}; print O "\t{\"$n\" , $val },\n"; print O "\t{\"help-$n\" , _HLP_$val },\n" if exists $Doc->{$val}; } print O "\t{ \"\", NULL }};\n\n"; # Generate a function to display all global variables print O "int ShowGlobals()\n\t{\n"; print O "\tPrint(\"[ninox]\\n\");\n"; open(G,">globals.c") or die; binmode(G); open(H,">globals.h") or die; binmode(H); print H "/* THIS FILE IS AUTO-GENERATED, DO NOT EDIT */\n\n"; print G "/* THIS FILE IS AUTO-GENERATED, DO NOT EDIT */\n\n"; print G "#include \"ninox.h\"\n\n"; my @g = sort { my $A=lc $a; my $B=lc $b; $A =~ s/^\w+\s+\W*//; $B =~ s/^\w+\s+\W*//; $A cmp $B} keys %GLOBALS; foreach my $g (@g) { $g =~ s/\s+/\t/; print G "$g\n"; $g =~ s/\s*=.+$//; print H "extern $g;\n"; my ($type,$var) = $g =~ /^(\w+\W+)(\w+)/g; $type = '%d' if $type =~ /^int\s+/; $type = '%lf' if $type =~ /^double\s+/; $type = '%s' if $type =~ /^char\s+\*/; print O "\tPrint(\"$var=$type\\n\",$var);\n"; } print O "\t}\n"; print H "\nextern struct cfunc Names[];\n"; close(O); close(G); close(H); exit(0); #=============================================== sub AddOutput { push @{$Block->{$CurrentBlock}}, @_; } sub AddDoc { push @{$Doc->{$CurrentBlock}}, @_; } sub AddName { my $n = shift; my $pri = shift; die "duplicate name '$n' on line $linenumber" if exists $Names{$n}; $Names{$n} = $pri; } sub StartBlock { my $line = shift; my @names = split(/\s+/, $line); my $primary = shift @names; my $func = "_CMD_$primary"; $func =~ s/\-/_/g; AddName($primary,$func); # Collect aliases and add them too foreach my $n (@names) { AddName($n,$func); } $CurrentBlock = $func; } sub AddGlobal { my $var = shift; die "Duplicate global '$var' (line $linenumber)" if exists $GLOBALS{$var}; $GLOBALS{$var} = 1; }