Changes related to supporting "intern scripts." These are scripts that used to be installed in /share/functions, but now are just compiled-in strings. This should reduce the amount of I/O done at launch time.

This commit is contained in:
ridiculousfish 2012-01-05 11:44:57 -08:00
parent f78c4fa751
commit 57c9eeeecb
2 changed files with 98 additions and 67 deletions

View File

@ -66,7 +66,7 @@ funcs.sort(key=cfunc.cfunc_name)
fd = open('builtin_scripts.h', 'w') fd = open('builtin_scripts.h', 'w')
fd.write('/* This file is generated by internalize_scripts.py */\n\n') fd.write('/* This file is generated by internalize_scripts.py */\n\n')
fd.write("""struct builtin_script_t { fd.write("""struct builtin_script_t {
const char *name; const wchar_t *name;
const char *def; const char *def;
};""") };""")
@ -85,7 +85,7 @@ for func in funcs:
fd.write('\n') fd.write('\n')
# Output the refs # Output the refs
func_refs = ["{%s, %s}" % (stringize(func.name), func.cfunc_name()) for func in funcs] func_refs = ["{L%s, %s}" % (stringize(func.name), func.cfunc_name()) for func in funcs]
fd.write('const struct builtin_script_t internal_function_scripts[%d] =\n' % len(funcs)) fd.write('const struct builtin_script_t internal_function_scripts[%d] =\n' % len(funcs))
fd.write('{\n\t') fd.write('{\n\t')
fd.write(',\n\t'.join(func_refs)) fd.write(',\n\t'.join(func_refs))

View File

@ -20,6 +20,7 @@
#include <wchar.h> #include <wchar.h>
#include <map> #include <map>
#include <set> #include <set>
#include <algorithm>
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
@ -871,7 +872,7 @@ int parse_util_load( const wcstring &cmd,
/* Figure out which builtin-scripts array to search (if any) */ /* Figure out which builtin-scripts array to search (if any) */
const builtin_script_t *builtins = NULL; const builtin_script_t *builtins = NULL;
size_t builtin_count = 0; size_t builtin_count = 0;
if (cmd == L"fish_function_path") if (path_var_name == L"fish_function_path")
{ {
builtins = internal_function_scripts; builtins = internal_function_scripts;
builtin_count = sizeof internal_function_scripts / sizeof *internal_function_scripts; builtin_count = sizeof internal_function_scripts / sizeof *internal_function_scripts;
@ -908,6 +909,11 @@ int parse_util_load( const wcstring &cmd,
return res; return res;
} }
static bool script_name_precedes_script_name(const builtin_script_t &script1, const builtin_script_t &script2)
{
return wcscmp(script1.name, script2.name) < 0;
}
/** /**
This internal helper function does all the real work. By using two This internal helper function does all the real work. By using two
functions, the internal function can return on various places in functions, the internal function can return on various places in
@ -915,7 +921,7 @@ int parse_util_load( const wcstring &cmd,
*/ */
static int parse_util_load_internal( const wcstring &cmd, static int parse_util_load_internal( const wcstring &cmd,
const struct builtin_script_t *builtin_scripts, const builtin_script_t *builtin_scripts,
size_t builtin_script_count, size_t builtin_script_count,
void (*on_load)(const wchar_t *cmd), void (*on_load)(const wchar_t *cmd),
int reload, int reload,
@ -929,7 +935,6 @@ static int parse_util_load_internal( const wcstring &cmd,
/* Get the function */ /* Get the function */
autoload_function_t * func = loaded.get_function_with_name(cmd); autoload_function_t * func = loaded.get_function_with_name(cmd);
/* Return if already loaded and we are skipping reloading */ /* Return if already loaded and we are skipping reloading */
if( !reload && func ) if( !reload && func )
return 0; return 0;
@ -938,10 +943,32 @@ static int parse_util_load_internal( const wcstring &cmd,
if (func && time(NULL) - func->load_time <= 1) if (func && time(NULL) - func->load_time <= 1)
return 0; return 0;
/* /* The source of the script will end up here */
Look for built-in scripts. wcstring script_source;
*/ bool has_script_source = false;
/*
Look for built-in scripts via a binary search
*/
const builtin_script_t *matching_builtin_script = NULL;
if (builtin_script_count > 0)
{
const builtin_script_t test_script = {cmd.c_str(), NULL};
const builtin_script_t *array_end = builtin_scripts + builtin_script_count;
const builtin_script_t *found = std::lower_bound(builtin_scripts, array_end, test_script, script_name_precedes_script_name);
if (found != array_end && ! wcscmp(found->name, test_script.name))
{
/* We found it */
matching_builtin_script = found;
}
}
if (matching_builtin_script) {
has_script_source = true;
script_source = str2wcstring(matching_builtin_script->def);
}
if (! has_script_source)
{
/* /*
Iterate over path searching for suitable completion files Iterate over path searching for suitable completion files
*/ */
@ -957,7 +984,8 @@ static int parse_util_load_internal( const wcstring &cmd,
if( !func || (func->modification_time != buf.st_mtime ) ) if( !func || (func->modification_time != buf.st_mtime ) )
{ {
wcstring esc = escape_string(path, 1); wcstring esc = escape_string(path, 1);
wcstring src_cmd = L". " + esc; script_source = L". " + esc;
has_script_source = true;
if( !func ) if( !func )
func = loaded.create_function_with_name(cmd); func = loaded.create_function_with_name(cmd);
@ -968,16 +996,6 @@ static int parse_util_load_internal( const wcstring &cmd,
if( on_load ) if( on_load )
on_load(cmd.c_str()); on_load(cmd.c_str());
/*
Source the completion file for the specified completion
*/
if( exec_subshell( src_cmd.c_str(), 0 ) == -1 )
{
/*
Do nothing on failiure
*/
}
reloaded = 1; reloaded = 1;
} }
else if( func ) else if( func )
@ -1004,6 +1022,19 @@ static int parse_util_load_internal( const wcstring &cmd,
func->load_time = time(NULL); func->load_time = time(NULL);
func->is_placeholder = true; func->is_placeholder = true;
} }
}
/* If we have a script, either built-in or a file source, then run it */
if (has_script_source)
{
if( exec_subshell( script_source.c_str(), 0 ) == -1 )
{
/*
Do nothing on failiure
*/
}
}
return reloaded; return reloaded;
} }