/* Do not remove the headers from this file! see /USAGE for more info. */
/*
** This beast manages function dispatch for shell-specific functions.
** This is a bloody quick hack to get something working.
** It should probably use classes, and definitly should do
** simple checking on number of args.
** Created. John Viega(rust@Virginia.EDU). July 2, 1995
*/
nosave mapping dispatch = ([]);
private nosave mapping personal_bindings = ([]);
private nosave string* modules = ({});
private nosave mapping module_objects = ([]);
private nosave mapping module_func_names = ([]);
protected void call_user_func(string, mixed);
//:FUNCTION setup_for_save
//Sets up M_SAVE to save some variables
void setup_for_save()
{
/*
** Use the call_other() interface so that we are not statically
** bound to require M_SAVE. This object this modules is applied
** to may save natively rather than via M_SAVE.
** Hmm, I don't think saving personal_bindings here is going to do
** any good... =)
*/
this_object()->add_save(({ "personal_bindings", "modules" }));
}
protected void
shell_bind(string command, function f)
{
dispatch[command] = f;
}
protected void
shell_bind_if_undefined(string command, function f)
{
if ( !dispatch[command] )
dispatch[command] = f;
}
protected void
shell_unbind(string command)
{
map_delete(dispatch, command);
}
protected int
bind(string command, string *argv)
{
string fname;
if(sizeof(argv) != 1)
return -1;
fname = argv[0];
if(undefinedp(personal_bindings[command]) && dispatch[command])
return -2;
personal_bindings[command] = fname;
dispatch[command] = (:call_user_func, command :);
this_object()->save();
}
protected void
unbind(string* argv)
{
string command;
if(sizeof(argv) != 1)
return;
command = argv[0];
if(undefinedp(personal_bindings[command]))
return;
map_delete(personal_bindings, command);
map_delete(dispatch, command);
this_object()->save();
}
protected void
call_user_func(string fname, mixed argv)
{
string module;
foreach(module in modules)
{
if(member_array(fname, module_func_names[module]) != -1)
{
call_other(module_objects[module],fname,argv);
return;
}
}
}
protected int
load_module(mixed argv)
{
string* flist;
mapping finfo = ([]);
mixed item;
object module_ob;
string* funcnames = ({});
if(!(stringp(argv) || (arrayp(argv) && sizeof(argv) == 1 &&
stringp(argv=argv[0]))))
return 0;
if(!module_ob = load_object(argv))
return 0;
module_objects[argv] = module_ob;
flist = functions(module_ob,1);
foreach(item in flist)
{
if(strsrch(item[2],"protected") != -1 || strsrch(item[2],"private") != -1)
continue;
finfo[item[0]];
funcnames += ({item[0]});
}
module_func_names[argv] = funcnames;
return 1;
}
protected void
set_module_path(string* mpath)
{
modules = mpath;
map(modules, (: load_module :));
}