blob: d39ac1614ae15669d8e089912372abc47e4d5e3b [file] [log] [blame]
Bram Moolenaare5e0fbc2017-03-25 14:51:01 +01001#!/usr/bin/perl -w
2#
3# This script generates the tables cmdidxs1[] and cmdidxs2[][] which,
4# given a Ex command, determine the first value to probe to find
5# a matching command in cmdnames[] based on the first character
6# and the first 2 characters of the command.
7# This is used to speed up lookup in cmdnames[].
8#
9# Script should be run every time new Ex commands are added in Vim,
10# from the src/vim directory, since it reads commands from "ex_cmds.h".
11
Bram Moolenaar980128c2017-03-26 21:46:28 +020012use strict;
13
Bram Moolenaare5e0fbc2017-03-25 14:51:01 +010014# Find the list of Vim commands from cmdnames[] table in ex_cmds.h
15my @cmds;
Bram Moolenaar980128c2017-03-26 21:46:28 +020016my $skipped_cmds;
Bram Moolenaare5e0fbc2017-03-25 14:51:01 +010017open(IN, "< ex_cmds.h") or die "can't open ex_cmds.h: $!\n";
18while (<IN>) {
19 if (/^EX\(CMD_\S*,\s*"([a-z][^"]*)"/) {
Bram Moolenaar980128c2017-03-26 21:46:28 +020020 push @cmds, $1;
Bram Moolenaare5e0fbc2017-03-25 14:51:01 +010021 } elsif (/^EX\(CMD_/) {
Bram Moolenaar980128c2017-03-26 21:46:28 +020022 ++$skipped_cmds;
Bram Moolenaare5e0fbc2017-03-25 14:51:01 +010023 }
24}
25
26my %cmdidxs1;
27my %cmdidxs2;
28
29for (my $i = $#cmds; $i >= 0; --$i) {
30 my $cmd = $cmds[$i];
31 my $c1 = substr($cmd, 0, 1); # First character of command.
32
33 $cmdidxs1{$c1} = $i;
34
35 if (length($cmd) > 1) {
36 my $c2 = substr($cmd, 1, 1); # Second character of command.
37 $cmdidxs2{$c1}{$c2} = $i if (('a' lt $c2) and ($c2 lt 'z'));
38 }
39}
40
41print "/* Beginning of automatically generated code by create_cmdidxs.pl\n",
42 " *\n",
43 " * Table giving the index of the first command in cmdnames[] to lookup\n",
44 " * based on the first letter of a command.\n",
45 " */\n",
46 "static const unsigned short cmdidxs1[26] =\n{\n",
47 join(",\n", map(" /* $_ */ $cmdidxs1{$_}", ('a' .. 'z'))),
48 "\n};\n",
49 "\n",
50 "/*\n",
51 " * Table giving the index of the first command in cmdnames[] to lookup\n",
52 " * based on the first 2 letters of a command.\n",
53 " * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they\n",
54 " * fit in a byte.\n",
55 " */\n",
56 "static const unsigned char cmdidxs2[26][26] =\n",
57 "{ /* a b c d e f g h i j k l m n o p q r s t u v w x y z */\n";
58for my $c1 ('a' .. 'z') {
59 print " /* $c1 */ {";
60 for my $c2 ('a' .. 'z') {
61 if (exists $cmdidxs2{$c1}{$c2}) {
62 printf "%3d,", $cmdidxs2{$c1}{$c2} - $cmdidxs1{$c1};
63 } else {
64 printf " 0,";
65 }
66 }
67 print " }";
68 print "," unless ($c1 eq 'z');
69 print "\n";
70}
71print "};\n",
72 "\n",
Bram Moolenaar980128c2017-03-26 21:46:28 +020073 "static const int command_count = ", scalar(@cmds) + $skipped_cmds, ";\n",
Bram Moolenaare5e0fbc2017-03-25 14:51:01 +010074 "\n",
75 "/* End of automatically generated code by create_cmdidxs.pl */\n";