mirror of
https://github.com/neovim/neovim.git
synced 2025-10-01 23:48:32 +00:00
eval: use gperf to generate the hash of builtin functions
make api functions highlighted as builtins in vim.vim
This commit is contained in:
106
src/genhash.c
106
src/genhash.c
@@ -1,106 +0,0 @@
|
||||
// Program used to generate static hashes
|
||||
//
|
||||
// Uses hashes from khash.h macros library.
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define USE_LIBC_ALLOCATOR
|
||||
#include "nvim/lib/khash.h"
|
||||
|
||||
KHASH_MAP_INIT_STR(hash, char *)
|
||||
|
||||
#define CHECK_FAIL(cond, ...) \
|
||||
do { \
|
||||
if (cond) { \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
putc('\n', stderr); \
|
||||
return 1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc == 2 && strcmp(argv[1], "--help") == 0) {
|
||||
puts("Usage:");
|
||||
puts(" genhash SOURCE TARGET TYPE NAME VALTYPE NULLVAL");
|
||||
puts("Transforms keys and values in a form \"key\\nval\\n\" into a hash");
|
||||
puts("literal.");
|
||||
puts("");
|
||||
puts("SOURCE is the file name to read keys and values from.");
|
||||
puts("TARGET is the file name to write to.");
|
||||
puts("TYPE is the name of the hash type (khash_t argument).");
|
||||
puts("NAME is the name of the generated hash.");
|
||||
puts("VALTYPE is the name of the value type.");
|
||||
puts("NULLVAL is the value used when no value is available.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
CHECK_FAIL(argc != 7, "Expecting six arguments, got %i.", argc);
|
||||
|
||||
const char *const source = argv[1];
|
||||
const char *const target = argv[2];
|
||||
const char *const type = argv[3];
|
||||
const char *const name = argv[4];
|
||||
const char *const valtype = argv[5];
|
||||
const char *const nullval = argv[6];
|
||||
|
||||
FILE *fin = fopen(source, "r");
|
||||
CHECK_FAIL(!fin, "Failed to open source: %s.", strerror(errno));
|
||||
|
||||
char keybuf[80];
|
||||
char valbuf[4096];
|
||||
khash_t(hash) hash = KHASH_EMPTY_TABLE(hash);
|
||||
while (fgets(keybuf, sizeof(keybuf), fin) != NULL) {
|
||||
CHECK_FAIL(ferror(fin), "Failed to read key %i from source: %s",
|
||||
(int) kh_size(&hash), strerror(ferror(fin)));
|
||||
keybuf[strlen(keybuf) - 1] = 0;
|
||||
CHECK_FAIL(!fgets(valbuf, sizeof(valbuf), fin),
|
||||
"Failed to read value for key %i (%s): %s",
|
||||
(int) kh_size(&hash), keybuf, (ferror(fin)
|
||||
? strerror(ferror(fin))
|
||||
: "EOF found"));
|
||||
valbuf[strlen(valbuf) - 1] = 0;
|
||||
char *const key_copy = strdup(keybuf);
|
||||
CHECK_FAIL(!key_copy, "Failed to allocate memory for a key");
|
||||
int put_ret;
|
||||
const khiter_t k = kh_put(hash, &hash, key_copy, &put_ret);
|
||||
CHECK_FAIL(put_ret != 1, "Expecting unused non-empty bucket for key %s",
|
||||
key_copy);
|
||||
kh_value(&hash, k) = strdup(valbuf);
|
||||
CHECK_FAIL(!kh_value(&hash, k), "Failed to allocate memory for a value");
|
||||
}
|
||||
CHECK_FAIL(fclose(fin), "Failed to close source: %s", strerror(errno));
|
||||
|
||||
FILE *f = fopen(target, "w");
|
||||
CHECK_FAIL(!f, strerror(errno));
|
||||
fprintf(f, "static const khash_t(%s) %s = {", type, name);
|
||||
fprintf(f, " .n_buckets = %i,\n", (int) hash.n_buckets);
|
||||
fprintf(f, " .size = %i,\n", (int) hash.size);
|
||||
fprintf(f, " .n_occupied = %i,\n", (int) hash.n_occupied);
|
||||
fprintf(f, " .upper_bound = %i,\n", (int) hash.upper_bound);
|
||||
fprintf(f, " .flags = (khint32_t[]) {\n");
|
||||
for (khint_t i = 0; i < kh_end(&hash); i++) {
|
||||
fprintf(f, " %i,\n", (int) hash.flags[i]);
|
||||
}
|
||||
fprintf(f, " },\n");
|
||||
fprintf(f, " .keys = (const char*[]) {\n");
|
||||
for (khint_t i = 0; i < kh_end(&hash); i++) {
|
||||
if (kh_exist(&hash, i)) {
|
||||
fprintf(f, " \"%s\",\n", hash.keys[i]);
|
||||
} else {
|
||||
fprintf(f, " NULL,\n");
|
||||
}
|
||||
}
|
||||
fprintf(f, " },\n");
|
||||
fprintf(f, " .vals = (%s[]) {\n", valtype);
|
||||
for (khint_t i = 0; i < kh_end(&hash); i++) {
|
||||
fprintf(f, " %s,\n", (kh_exist(&hash, i) ? hash.vals[i] : nullval));
|
||||
}
|
||||
fprintf(f, " },\n");
|
||||
fprintf(f, "};\n");
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
@@ -15,12 +15,13 @@ set(DISPATCH_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendispatch.lua)
|
||||
file(GLOB API_HEADERS api/*.h)
|
||||
file(GLOB MSGPACK_RPC_HEADERS msgpack_rpc/*.h)
|
||||
set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack)
|
||||
set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack)
|
||||
set(HEADER_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendeclarations.lua)
|
||||
set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include)
|
||||
set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch.c)
|
||||
set(GENERATED_EX_CMDS_ENUM ${GENERATED_INCLUDES_DIR}/ex_cmds_enum.generated.h)
|
||||
set(GENERATED_EX_CMDS_DEFS ${GENERATED_DIR}/ex_cmds_defs.generated.h)
|
||||
set(GENERATED_FUNCS_HASH_INPUT ${GENERATED_DIR}/funcs.generated.h.hsh)
|
||||
set(GENERATED_FUNCS_HASH_INPUT ${GENERATED_DIR}/funcs.generated.h.gperf)
|
||||
set(GENERATED_FUNCS ${GENERATED_DIR}/funcs.generated.h)
|
||||
set(GENERATED_EVENTS_ENUM ${GENERATED_INCLUDES_DIR}/auevents_enum.generated.h)
|
||||
set(GENERATED_EVENTS_NAMES_MAP ${GENERATED_DIR}/auevents_name_map.generated.h)
|
||||
@@ -39,9 +40,9 @@ set(UNICODEDATA_FILE ${UNICODE_DIR}/UnicodeData.txt)
|
||||
set(CASEFOLDING_FILE ${UNICODE_DIR}/CaseFolding.txt)
|
||||
set(EASTASIANWIDTH_FILE ${UNICODE_DIR}/EastAsianWidth.txt)
|
||||
set(GENERATED_UNICODE_TABLES ${GENERATED_DIR}/unicode_tables.generated.h)
|
||||
set(GENHASH_SOURCE ${PROJECT_SOURCE_DIR}/src/genhash.c)
|
||||
|
||||
include_directories(${GENERATED_DIR})
|
||||
include_directories(${CACHED_GENERATED_DIR})
|
||||
include_directories(${GENERATED_INCLUDES_DIR})
|
||||
|
||||
file(MAKE_DIRECTORY ${GENERATED_DIR})
|
||||
@@ -118,6 +119,10 @@ endforeach()
|
||||
if(NOT MSVC)
|
||||
set_source_files_properties(
|
||||
${CONV_SOURCES} PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-conversion")
|
||||
# gperf generates ANSI-C with incorrect linkage, ignore it.
|
||||
set_source_files_properties(
|
||||
eval.c PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-static-in-inline -Wno-conversion")
|
||||
|
||||
endif()
|
||||
|
||||
if(DEFINED MIN_LOG_LEVEL)
|
||||
@@ -210,7 +215,6 @@ list(APPEND NEOVIM_GENERATED_SOURCES
|
||||
"${GENERATED_EVENTS_NAMES_MAP}"
|
||||
"${GENERATED_OPTIONS}"
|
||||
"${GENERATED_UNICODE_TABLES}"
|
||||
"${GENERATED_FUNCS}"
|
||||
)
|
||||
|
||||
add_custom_command(OUTPUT ${GENERATED_EX_CMDS_ENUM} ${GENERATED_EX_CMDS_DEFS}
|
||||
@@ -219,13 +223,18 @@ add_custom_command(OUTPUT ${GENERATED_EX_CMDS_ENUM} ${GENERATED_EX_CMDS_DEFS}
|
||||
DEPENDS ${EX_CMDS_GENERATOR} ${EX_CMDS_DEFS_FILE}
|
||||
)
|
||||
|
||||
add_custom_command(OUTPUT ${GENERATED_FUNCS}
|
||||
if(NOT GPERF_PRG)
|
||||
message(FATAL_ERROR "gperf was not found.")
|
||||
endif()
|
||||
add_custom_command(OUTPUT ${GENERATED_FUNCS} ${FUNCS_DATA}
|
||||
COMMAND ${LUA_PRG} ${FUNCS_GENERATOR}
|
||||
${PROJECT_SOURCE_DIR}/src/nvim ${GENERATED_DIR} ${API_METADATA}
|
||||
COMMAND $<TARGET_FILE:genhash>
|
||||
${GENERATED_FUNCS_HASH_INPUT} ${GENERATED_FUNCS} functions functions VimLFuncDef "NOFUNC"
|
||||
DEPENDS ${FUNCS_GENERATOR} ${EVAL_DEFS_FILE} ${API_METADATA} genhash
|
||||
${PROJECT_SOURCE_DIR}/src/nvim ${GENERATED_DIR} ${API_METADATA} ${FUNCS_DATA}
|
||||
COMMAND ${GPERF_PRG}
|
||||
${GENERATED_FUNCS_HASH_INPUT} --output-file=${GENERATED_FUNCS}
|
||||
DEPENDS ${FUNCS_GENERATOR} ${EVAL_DEFS_FILE} ${API_METADATA}
|
||||
)
|
||||
list(APPEND NEOVIM_GENERATED_SOURCES
|
||||
"${GENERATED_FUNCS}")
|
||||
|
||||
add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP}
|
||||
COMMAND ${LUA_PRG} ${EVENTS_GENERATOR}
|
||||
@@ -293,8 +302,6 @@ if(WIN32)
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
endif()
|
||||
|
||||
add_executable(genhash ${GENHASH_SOURCE} ${NEOVIM_HEADERS})
|
||||
|
||||
if(CLANG_ASAN_UBSAN)
|
||||
message(STATUS "Enabling Clang address sanitizer and undefined behavior sanitizer for nvim.")
|
||||
check_c_compiler_flag(-fno-sanitize-recover=all SANITIZE_RECOVER_ALL)
|
||||
|
772
src/nvim/eval.c
772
src/nvim/eval.c
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@ end
|
||||
return {
|
||||
funcs={
|
||||
abs={args=1},
|
||||
acos={args=1}, -- WJMc
|
||||
acos={args=1, func="float_op_wrapper", data="&acos"}, -- WJMc
|
||||
add={args=2},
|
||||
['and']={args=2},
|
||||
api_info={},
|
||||
@@ -24,7 +24,7 @@ return {
|
||||
argidx={},
|
||||
arglistid={args={0, 2}},
|
||||
argv={args={0, 1}},
|
||||
asin={args=1}, -- WJMc
|
||||
asin={args=1, func="float_op_wrapper", data="&asin"}, -- WJMc
|
||||
assert_equal={args={2, 3}},
|
||||
assert_exception={args={1, 2}},
|
||||
assert_fails={args={1, 2}},
|
||||
@@ -33,7 +33,7 @@ return {
|
||||
assert_notequal={args={2, 3}},
|
||||
assert_notmatch={args={2, 3}},
|
||||
assert_true={args={1, 2}},
|
||||
atan={args=1, func="float_op_wrapper", data="atan"},
|
||||
atan={args=1, func="float_op_wrapper", data="&atan"},
|
||||
atan2={args=2},
|
||||
browse={args=4},
|
||||
browsedir={args=2},
|
||||
@@ -50,7 +50,7 @@ return {
|
||||
byteidx={args=2},
|
||||
byteidxcomp={args=2},
|
||||
call={args={2, 3}},
|
||||
ceil={args=1},
|
||||
ceil={args=1, func="float_op_wrapper", data="&ceil"},
|
||||
changenr={},
|
||||
char2nr={args={1, 2}},
|
||||
cindent={args=1},
|
||||
@@ -61,8 +61,8 @@ return {
|
||||
complete_check={},
|
||||
confirm={args={1, 4}},
|
||||
copy={args=1},
|
||||
cos={args=1},
|
||||
cosh={args=1},
|
||||
cos={args=1, func="float_op_wrapper", data="&cos"},
|
||||
cosh={args=1, func="float_op_wrapper", data="&cosh"},
|
||||
count={args={2, 4}},
|
||||
cscope_connection={args={0, 3}},
|
||||
cursor={args={1, 3}},
|
||||
@@ -81,7 +81,7 @@ return {
|
||||
execute={args=1},
|
||||
exepath={args=1},
|
||||
exists={args=1},
|
||||
exp={args=1},
|
||||
exp={args=1, func="float_op_wrapper", data="&exp"},
|
||||
expand={args={1, 3}},
|
||||
extend={args={2, 3}},
|
||||
feedkeys={args={1, 2}},
|
||||
@@ -92,7 +92,7 @@ return {
|
||||
finddir={args={1, 3}},
|
||||
findfile={args={1, 3}},
|
||||
float2nr={args=1},
|
||||
floor={args=1},
|
||||
floor={args=1, func="float_op_wrapper", data="&floor"},
|
||||
fmod={args=2},
|
||||
fnameescape={args=1},
|
||||
fnamemodify={args=2},
|
||||
@@ -184,8 +184,8 @@ return {
|
||||
line2byte={args=1},
|
||||
lispindent={args=1},
|
||||
localtime={},
|
||||
log={args=1},
|
||||
log10={args=1},
|
||||
log={args=1, func="float_op_wrapper", data="&log"},
|
||||
log10={args=1, func="float_op_wrapper", data="&log10"},
|
||||
map={args=2},
|
||||
maparg={args={1, 4}},
|
||||
mapcheck={args={1, 3}},
|
||||
@@ -223,7 +223,7 @@ return {
|
||||
['repeat']={args=2},
|
||||
resolve={args=1},
|
||||
reverse={args=1},
|
||||
round={args=1},
|
||||
round={args=1, func="float_op_wrapper", data="&round"},
|
||||
rpcnotify={args=varargs(2)},
|
||||
rpcrequest={args=varargs(2)},
|
||||
rpcstart={args={1, 2}},
|
||||
@@ -257,14 +257,14 @@ return {
|
||||
shellescape={args={1, 2}},
|
||||
shiftwidth={},
|
||||
simplify={args=1},
|
||||
sin={args=1},
|
||||
sinh={args=1},
|
||||
sin={args=1, func="float_op_wrapper", data="&sin"},
|
||||
sinh={args=1, func="float_op_wrapper", data="&sinh"},
|
||||
sort={args={1, 3}},
|
||||
soundfold={args=1},
|
||||
spellbadword={args={0, 1}},
|
||||
spellsuggest={args={1, 3}},
|
||||
split={args={1, 3}},
|
||||
sqrt={args=1},
|
||||
sqrt={args=1, func="float_op_wrapper", data="&sqrt"},
|
||||
str2float={args=1},
|
||||
str2nr={args={1, 2}},
|
||||
strchars={args={1,2}},
|
||||
@@ -291,8 +291,8 @@ return {
|
||||
tabpagewinnr={args={1, 2}},
|
||||
tagfiles={},
|
||||
taglist={args=1},
|
||||
tan={args=1},
|
||||
tanh={args=1},
|
||||
tan={args=1, func="float_op_wrapper", data="&tan"},
|
||||
tanh={args=1, func="float_op_wrapper", data="&tanh"},
|
||||
tempname={},
|
||||
termopen={args={1, 2}},
|
||||
test={args=1},
|
||||
@@ -301,7 +301,7 @@ return {
|
||||
tolower={args=1},
|
||||
toupper={args=1},
|
||||
tr={args=3},
|
||||
trunc={args=1},
|
||||
trunc={args=1, func="float_op_wrapper", data="&trunc"},
|
||||
type={args=1},
|
||||
undofile={args=1},
|
||||
undotree={},
|
||||
|
@@ -130,9 +130,7 @@ int main() {
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef USE_LIBC_ALLOCATOR
|
||||
# include "nvim/memory.h"
|
||||
#endif
|
||||
#include "nvim/memory.h"
|
||||
|
||||
#include "nvim/func_attr.h"
|
||||
|
||||
@@ -173,32 +171,17 @@ typedef khint_t khiter_t;
|
||||
#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBC_ALLOCATOR
|
||||
# ifndef kcalloc
|
||||
# define kcalloc(N,Z) calloc(N,Z)
|
||||
# endif
|
||||
# ifndef kmalloc
|
||||
# define kmalloc(Z) malloc(Z)
|
||||
# endif
|
||||
# ifndef krealloc
|
||||
# define krealloc(P,Z) realloc(P,Z)
|
||||
# endif
|
||||
# ifndef kfree
|
||||
# define kfree(P) free(P)
|
||||
# endif
|
||||
#else
|
||||
# ifndef kcalloc
|
||||
# define kcalloc(N,Z) xcalloc(N,Z)
|
||||
# endif
|
||||
# ifndef kmalloc
|
||||
# define kmalloc(Z) xmalloc(Z)
|
||||
# endif
|
||||
# ifndef krealloc
|
||||
# define krealloc(P,Z) xrealloc(P,Z)
|
||||
# endif
|
||||
# ifndef kfree
|
||||
# define kfree(P) xfree(P)
|
||||
# endif
|
||||
#ifndef kcalloc
|
||||
#define kcalloc(N,Z) xcalloc(N,Z)
|
||||
#endif
|
||||
#ifndef kmalloc
|
||||
#define kmalloc(Z) xmalloc(Z)
|
||||
#endif
|
||||
#ifndef krealloc
|
||||
#define krealloc(P,Z) xrealloc(P,Z)
|
||||
#endif
|
||||
#ifndef kfree
|
||||
#define kfree(P) xfree(P)
|
||||
#endif
|
||||
|
||||
#define __ac_HASH_UPPER 0.77
|
||||
|
Reference in New Issue
Block a user