Branch: Tag:

1998-03-23

1998-03-23 08:20:58 by David Hedbor <david@hedbor.org>

o Added new module type, MODULE_PROVIDER. This is a module type which
enables other modules, scripts or protocols to call it very
simply. Function needed in the module:
"string|array|multiset query_provides()" - Return the name of the
data this module provides. One existing example is "counter"
(which is the graphical counter module).

Functions available to other modules:
object conf->get_provider(string for);
Get the first (highest priority) provider for "for".
array (object) conf->get_providers(string for);
Dito, but return all matching modules.
void map_providers(string for, string fun, mixed ... args);
Run the function "fun" in all modules providing "for", with the
optional arguments "args".
mixed call_provider(string for, string fun, mixed ... args);
Run the function "fun" in all modules providing "for", with the
optional arguments "args" until a positive response
(!zero). Return the result. This is the main way of calling
functions in provider modules from other places.

o Added new tag - echo. It's usable with one of the following syntaxes:
<echo var='Remote Host'> <echo remote_host> <insert remote_host>
Case doesn't matter and in the first syntax, ' ' and '_' are
interchangable. The available variables are identical to the SSI
<!--#echo var="..." -->

Rev: CHANGES:1.107
Rev: server/base_server/config/low_describers.pike:1.24
Rev: server/base_server/configuration.pike:1.112
Rev: server/base_server/mainconfig.pike:1.99
Rev: server/base_server/module.pike:1.30
Rev: server/etc/include/module.h:1.14
Rev: server/modules/graphics/counter.pike:1.17
Rev: server/modules/scripting/cgi.pike:1.78
Rev: server/modules/tags/htmlparse.pike:1.90

1: - string cvs_version = "$Id: configuration.pike,v 1.111 1998/03/20 03:34:09 per Exp $"; + string cvs_version = "$Id: configuration.pike,v 1.112 1998/03/23 08:20:54 neotron Exp $";   #include <module.h>   #include <roxen.h>   
130:       mapping (string:array(object)) extension_modules = ([ ]);    mapping (string:array(object)) file_extension_modules = ([ ]); +  mapping (object:multiset) provider_modules = ([ ]);          void stop()    { -  foreach(url_modules, object m) catch { m->stop(); }; -  foreach(logger_modules, object m) catch { m->stop(); }; -  foreach(filter_modules, object m) catch { m->stop(); }; -  foreach(location_modules, object m)catch { m->stop(); }; -  foreach(last_modules, object m) catch { m->stop(); }; -  foreach(first_modules, object m) catch { m->stop(); }; +  foreach(url_modules, object m) catch { m->stop(); }; +  foreach(logger_modules, object m) catch { m->stop(); }; +  foreach(filter_modules, object m) catch { m->stop(); }; +  foreach(location_modules, object m) catch { m->stop(); }; +  foreach(last_modules, object m) catch { m->stop(); }; +  foreach(first_modules, object m) catch { m->stop(); }; +  foreach(indices(provider_modules), object m) catch { m->stop(); };    }   }   
267:   private array (array (string|function)) location_module_cache;   private mapping (string:array (function)) extension_module_cache=([]);   private mapping (string:array (function)) file_extension_module_cache=([]); + private mapping (string:array (object)) provider_module_cache=([]);         // Call stop in all modules.
315:    return 0;   }    + // Return an array with all provider modules that provides "provides". + array (object) get_providers(string provides) + { +  if(!provider_module_cache[provides]) +  { +  int i; +  provider_module_cache[provides] = ({ }); +  for(i = 9; i >= 0; i--) +  { +  object d; +  foreach(indices(pri[i]->provider_modules), d) +  if(pri[i]->provider_modules[ d ][ provides ]) +  provider_module_cache[provides] += ({ d }); +  } +  } +  return provider_module_cache[provides]; + }    -  + // Return the first provider module that provides "provides". + object get_provider(string provides) + { +  array (object) prov = get_providers(provides); +  if(sizeof(prov)) +  return prov[0]; +  return 0; + }    -  + // map the function "fun" over all matching provider modules. + void map_providers(string provides, string fun, mixed ... args) + { +  array (object) prov = get_providers(provides); +  array error; +  foreach(prov, object mod) { +  if(!objectp(mod)) +  continue; +  if(functionp(mod[fun])) +  error = catch(mod[fun](@args)); +  else +  error = 0; +  if(arrayp(error)) +  werror(describe_backtrace(error + ({ "Error in map_providers:"}))); +  } + } +  + // map the function "fun" over all matching provider modules and + // return the first positive response. + mixed call_provider(string provides, string fun, mixed ... args) + { +  array (object) prov = get_providers(provides); +  array error; +  mixed ret; +  foreach(prov, object mod) { +  if(!objectp(mod)) +  continue; +  if(functionp(mod[fun])) +  error = catch { +  ret = mod[fun](@args); +  }; +  else +  error = ret = 0; +  if(arrayp(error)) +  throw(error + ({ "Error in call_provider:"})); +  if(ret) +  return ret; +  } + } +    array (function) extension_modules(string ext, object id)   {    if(!extension_module_cache[ext])
334:    return extension_module_cache[ext];   }    +    array (function) file_extension_modules(string ext, object id)   {    if(!file_extension_module_cache[ext])
853:    logger_module_cache = 0;    extension_module_cache = ([]);    file_extension_module_cache = ([]); +  provider_module_cache = ([]);   #ifdef MODULE_LEVEL_SECURITY    if(misc_cache)    misc_cache = ([ ]);
2046:    module = modules[ modname ];    }    + #if constant(gethrtime)    int start_time = gethrtime(); -  + #endif    if( module )    {    object me;
2099:   #endif    if (module->type & (MODULE_LOCATION | MODULE_EXTENSION |    MODULE_FILE_EXTENSION | MODULE_LOGGER | -  MODULE_URL | MODULE_LAST | +  MODULE_URL | MODULE_LAST | MODULE_PROVIDER |    MODULE_FILTER | MODULE_PARSER | MODULE_FIRST))    {    me->defvar("_priority", 5, "Priority", TYPE_INT_LIST,
2108:    "called in random order",    ({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}));    -  if(module->type != MODULE_LOGGER) +  if(module->type != MODULE_LOGGER && +  module->type != MODULE_PROVIDER)    {    if(!(module->type & MODULE_PROXY))    {
2244:    }    }    +  if(module->type & MODULE_PROVIDER) { +  if (err = catch { +  mixed provs = me->query_provides(); +  if(stringp(provs)) +  provs = (< provs >); +  if(arrayp(provs)) +  provs = mkmultiset(provs); +  if (multisetp(provs)) { +  pri[pr]->provider_modules [ me ] = provs; +  } +  }) { +  report_error("Error while initiating module copy of " + +  module->name + "\n" + describe_backtrace(err)); +  } +  } +     if(module->type & MODULE_TYPES)    {    types_module = me;
2320:    }    invalidate_cache();   #ifdef MODULE_DEBUG - #if efun(gethrtime) + #if constant(gethrtime)    perror(" Done (%3.3f seconds).\n", (gethrtime()-start_time)/1000000.0);   #else    perror(" Done.\n");
2547:    pri[pr]->file_extension_modules[foo]-=({me});    }    +  if(module->type & MODULE_PROVIDER) { +  for(pr=0; pr<10; pr++) +  m_delete(pri[pr]->provider_modules, me); +  } +     if(module["type"] & MODULE_TYPES)    {    types_module = 0;