blob: 1d73c5faafc9a05b72c388eef54eb7d58ad76077 [file] [log] [blame]
Bram Moolenaar6de5e122017-04-20 21:55:44 +02001" This script generates the tables cmdidxs1[] and cmdidxs2[][] which,
2" given a Ex command, determine the first value to probe to find
3" a matching command in cmdnames[] based on the first character
4" and the first 2 characters of the command.
5" This is used to speed up lookup in cmdnames[].
6"
7" Script should be run every time new Ex commands are added in Vim,
8" from the src/vim directory, since it reads commands from "ex_cmds.h".
9
10let cmds = []
11let skipped_cmds = 0
12
Bram Moolenaarb7316892019-05-01 18:08:42 +020013let lines = readfile('ex_cmds.h')
14let idx = 0
15while idx < len(lines)
16 let line = lines[idx]
Bram Moolenaar6de5e122017-04-20 21:55:44 +020017 if line =~ '^EX(CMD_'
18 let m = matchlist(line, '^EX(CMD_\S*,\s*"\([a-z][^"]*\)"')
19 if len(m) >= 2
20 let cmds += [ m[1] ]
21 else
22 let skipped_cmds += 1
23 endif
Bram Moolenaarb7316892019-05-01 18:08:42 +020024
25 let idx += 1
26 let flags = lines[idx]
27 let idx += 1
28 let addr_type = lines[idx]
29
30 if flags =~ '\<RANGE\>'
31 if addr_type =~ 'ADDR_NONE'
32 echoerr 'ex_cmds.h:' .. (idx - 1) .. ': Using RANGE with ADDR_NONE: ' .. line
33 endif
34 else
35 if addr_type !~ 'ADDR_NONE'
36 echoerr 'ex_cmds.h:' .. (idx - 1) .. ': Missing ADDR_NONE: ' .. line
37 endif
38 endif
39
40 if flags =~ '\<DFLALL\>' && (addr_type =~ 'ADDR_OTHER' || addr_type =~ 'ADDR_NONE')
41 echoerr 'ex_cmds.h:' .. (idx - 1) .. ': Missing misplaced DFLALL: ' .. line
42 endif
Bram Moolenaar6de5e122017-04-20 21:55:44 +020043 endif
Bram Moolenaarb7316892019-05-01 18:08:42 +020044 let idx += 1
45endwhile
Bram Moolenaar6de5e122017-04-20 21:55:44 +020046
47let cmdidxs1 = {}
48let cmdidxs2 = {}
49
50for i in range(len(cmds) - 1, 0, -1)
51 let cmd = cmds[i]
52 let c1 = cmd[0] " First character of command
53 let c2 = cmd[1] " Second character of command (if any)
54
55 let cmdidxs1{c1} = i
56 if c2 >= 'a' && c2 <= 'z'
57 let cmdidxs2{c1}{c2} = i
58 endif
59endfor
60
61let output = [ '/* Automatically generated code by create_cmdidxs.vim' ]
62let output += [ ' *' ]
63let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ]
64let output += [ ' * based on the first letter of a command.' ]
65let output += [ ' */' ]
66let output += [ 'static const unsigned short cmdidxs1[26] =' ]
67let output += [ '{' ]
68
69let a_to_z = map(range(char2nr('a'), char2nr('z')), 'nr2char(v:val)')
70for c1 in a_to_z
71 let line = ' /* ' . c1 . ' */ ' . cmdidxs1{c1} . ((c1 == 'z') ? '' : ',')
72 let output += [ line ]
73endfor
74let output += [ '};' ]
75let output += [ '' ]
76let output += [ '/*' ]
77let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ]
78let output += [ ' * based on the first 2 letters of a command.' ]
79let output += [ ' * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they' ]
80let output += [ ' * fit in a byte.' ]
81let output += [ ' */' ]
82let output += [ 'static const unsigned char cmdidxs2[26][26] =' ]
83let output += [ '{ /* 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 */' ]
84
85for c1 in a_to_z
86 let line = ' /* ' . c1 . ' */ {'
87 for c2 in a_to_z
88 if exists('cmdidxs2{c1}{c2}')
89 let line .= printf('%3d', cmdidxs2{c1}{c2} - cmdidxs1{c1})
90 else
91 let line .= ' 0'
92 endif
93 let line .= (c2 == 'z') ? '' : ','
94 endfor
95 let line .= ' }' . ((c1 == 'z') ? '' : ',')
96 let output += [ line ]
97endfor
98
99let output += [ '};' ]
100let output += [ '' ]
101let output += [ 'static const int command_count = ' . (len(cmds) + skipped_cmds) . ';' ]
102
103call writefile(output, "ex_cmdidxs.h")
104quit