Use lua generator in place of ex_cmds_defs header trick

Closes #788
Fixes #379
Ref #549
This commit is contained in:
ZyX
2014-06-14 00:31:55 +04:00
parent bbefc73c55
commit 3becb5fd21
7 changed files with 2770 additions and 1135 deletions

87
scripts/genex_cmds.lua Normal file
View File

@@ -0,0 +1,87 @@
local nvimsrcdir = arg[1]
local includedir = arg[2]
local autodir = arg[3]
if nvimsrcdir == '--help' then
print ([[
Usage:
lua genex_cmds.lua src/nvim build/include build/src/nvim/auto
Will generate files build/include/ex_cmds_enum.generated.h with cmdidx_T
enum and build/src/nvim/auto/ex_cmds_defs.generated.h with main Ex commands
definitions.
]])
os.exit(0)
end
package.path = nvimsrcdir .. '/?.lua;' .. package.path
local enumfname = includedir .. '/ex_cmds_enum.generated.h'
local defsfname = autodir .. '/ex_cmds_defs.generated.h'
local enumfile = io.open(enumfname, 'w')
local defsfile = io.open(defsfname, 'w')
local defs = require('ex_cmds')
local lastchar = nil
local i
local cmd
local first = true
local prevfirstchar = nil
local byte_a = string.byte('a')
local byte_z = string.byte('z')
local cmdidxs = string.format([[
static cmdidx_T cmdidxs[%u] = {
]], byte_z - byte_a + 2)
enumfile:write([[
typedef enum CMD_index {
]])
defsfile:write([[
static CommandDefinition cmdnames[] = {
]])
for i, cmd in ipairs(defs) do
local enumname = cmd.enum or ('CMD_' .. cmd.command)
firstchar = string.byte(cmd.command)
if firstchar ~= prevfirstchar then
if (not prevfirstchar
or (byte_a <= firstchar and firstchar <= byte_z)
or (byte_a <= prevfirstchar and prevfirstchar <= byte_z)) then
if not first then
cmdidxs = cmdidxs .. ',\n'
end
cmdidxs = cmdidxs .. ' ' .. enumname
end
prevfirstchar = firstchar
end
if first then
first = false
else
defsfile:write(',\n')
end
enumfile:write(' ' .. enumname .. ',\n')
defsfile:write(string.format([[
[%s] = {
.cmd_name = (char_u *) "%s",
.cmd_func = &%s,
.cmd_argt = %uL
}]], enumname, cmd.command, cmd.func, cmd.flags))
end
defsfile:write([[
};
]])
enumfile:write([[
CMD_SIZE,
CMD_USER = -1,
CMD_USER_BUF = -2
} cmdidx_T;
]])
cmdidxs = cmdidxs .. [[
};
]]
defsfile:write(cmdidxs)

View File

@@ -0,0 +1,70 @@
#!/usr/bin/perl
use strict;
use warnings;
no utf8;
my $srcfname = shift @ARGV;
my $tgtfname = shift @ARGV;
if ($srcfname eq "--help") {
print << "EOF";
$0 path/to/ex_cmds_defs.h path/to/ex_cmds.lua
Translate Ex commands defines from old format to new one.
EOF
}
my $flag_const = qr((?:[A-Z]+[A-Z1-9]));
my $F;
open $F, "<", "$srcfname"
or die "Failed to open $srcfname";
my $T;
open $T, ">", "$tgtfname"
or die "Failed to open $tgtfname";
my ($enum_name, $cmd_name, $cmd_func);
my ($flags);
my $did_header = 0;
while (<$F>) {
if (/^#define\s+($flag_const)\s+(.*)/) {
my $const_name = $1;
my $const_value = $2;
$const_value =~ s@/\*.*|//.*@@g;
$const_value =~ s/\s+//g;
$const_value =~ s/\|/+/g;
$const_value =~ s/(?<=\d)L//g;
print $T "local $const_name = $const_value\n";
} elsif (/^\{/../^\}/) {
if (/^\s*EX\(\s*CMD_(\w+)\s*,\s*"((?:\\.|[^"\\])+)"\s*,\s*(\w+)\s*,\s*$/) {
$enum_name = $1;
$cmd_name = $2;
$cmd_func = $3;
} elsif (defined $enum_name and /^\s*($flag_const(?:\|$flag_const)*|0)/) {
if (not $did_header) {
print $T "return {\n";
$did_header = 1;
}
$flags = $1;
$flags =~ s/\|/+/g;
local $\ = "\n";
print $T " {";
print $T " command='$cmd_name',";
print $T " enum='CMD_$enum_name',"
if ($cmd_name ne $enum_name);
print $T " flags=$flags,";
print $T " func='$cmd_func',";
print $T " },";
undef $enum_name;
undef $cmd_name;
undef $cmd_func;
undef $flags;
} else {
next;
}
}
}
print $T "}\n";