Bram Moolenaar | 6de5e12 | 2017-04-20 21:55:44 +0200 | [diff] [blame] | 1 | " 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 | |
| 10 | let cmds = [] |
| 11 | let skipped_cmds = 0 |
| 12 | |
Bram Moolenaar | b731689 | 2019-05-01 18:08:42 +0200 | [diff] [blame^] | 13 | let lines = readfile('ex_cmds.h') |
| 14 | let idx = 0 |
| 15 | while idx < len(lines) |
| 16 | let line = lines[idx] |
Bram Moolenaar | 6de5e12 | 2017-04-20 21:55:44 +0200 | [diff] [blame] | 17 | 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 Moolenaar | b731689 | 2019-05-01 18:08:42 +0200 | [diff] [blame^] | 24 | |
| 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 Moolenaar | 6de5e12 | 2017-04-20 21:55:44 +0200 | [diff] [blame] | 43 | endif |
Bram Moolenaar | b731689 | 2019-05-01 18:08:42 +0200 | [diff] [blame^] | 44 | let idx += 1 |
| 45 | endwhile |
Bram Moolenaar | 6de5e12 | 2017-04-20 21:55:44 +0200 | [diff] [blame] | 46 | |
| 47 | let cmdidxs1 = {} |
| 48 | let cmdidxs2 = {} |
| 49 | |
| 50 | for 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 |
| 59 | endfor |
| 60 | |
| 61 | let output = [ '/* Automatically generated code by create_cmdidxs.vim' ] |
| 62 | let output += [ ' *' ] |
| 63 | let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ] |
| 64 | let output += [ ' * based on the first letter of a command.' ] |
| 65 | let output += [ ' */' ] |
| 66 | let output += [ 'static const unsigned short cmdidxs1[26] =' ] |
| 67 | let output += [ '{' ] |
| 68 | |
| 69 | let a_to_z = map(range(char2nr('a'), char2nr('z')), 'nr2char(v:val)') |
| 70 | for c1 in a_to_z |
| 71 | let line = ' /* ' . c1 . ' */ ' . cmdidxs1{c1} . ((c1 == 'z') ? '' : ',') |
| 72 | let output += [ line ] |
| 73 | endfor |
| 74 | let output += [ '};' ] |
| 75 | let output += [ '' ] |
| 76 | let output += [ '/*' ] |
| 77 | let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ] |
| 78 | let output += [ ' * based on the first 2 letters of a command.' ] |
| 79 | let output += [ ' * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they' ] |
| 80 | let output += [ ' * fit in a byte.' ] |
| 81 | let output += [ ' */' ] |
| 82 | let output += [ 'static const unsigned char cmdidxs2[26][26] =' ] |
| 83 | let 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 | |
| 85 | for 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 ] |
| 97 | endfor |
| 98 | |
| 99 | let output += [ '};' ] |
| 100 | let output += [ '' ] |
| 101 | let output += [ 'static const int command_count = ' . (len(cmds) + skipped_cmds) . ';' ] |
| 102 | |
| 103 | call writefile(output, "ex_cmdidxs.h") |
| 104 | quit |