Branch: Tag:

1998-11-18

1998-11-18 04:54:36 by Per Hedbor <ph@opera.com>

Better locale support, moved parse_rxml to the configuration object, started workd on the new configuration interface

Rev: server/base_server/cache.pike:1.22
Rev: server/base_server/config/describers.pike:1.58
Rev: server/base_server/config/low_describers.pike:1.28
Rev: server/base_server/configlocale.pike:1.1
Rev: server/base_server/configuration.pike:1.167
Rev: server/base_server/fonts.pike:1.25
Rev: server/base_server/mainconfig.pike:1.116
Rev: server/base_server/module.pike:1.36
Rev: server/base_server/module_support.pike:1.19
Rev: server/base_server/roxen.pike:1.252
Rev: server/base_server/roxenlib.pike:1.89
Rev: server/base_server/roxenloader.pike:1.80
Rev: server/base_server/rxml.pike:1.1
Rev: server/base_server/wizard.pike:1.77
Rev: server/config_actions/cachestatus.pike:1.4
Rev: server/config_actions/debuginformation.pike:1.16
Rev: server/config_actions/feature_list.pike:1.4
Rev: server/config_actions/flush.pike:1.7
Rev: server/config_actions/listfonts.pike:1.4
Rev: server/config_actions/problems.pike:1.12
Rev: server/config_actions/reloadconfiginterface.pike:1.9
Rev: server/etc/include/roxen.h:1.8
Rev: server/etc/roxen_master.pike:1.49
Rev: server/modules/directories/indexfiles.pike:1.7
Rev: server/modules/filters/auto_gzip.pike:1.5
Rev: server/modules/graphics/business_graphics/business.pike:1.110
Rev: server/modules/graphics/counter.pike:1.22
Rev: server/modules/graphics/graphic_text.pike:1.156
Rev: server/modules/graphics/pimage.pike:1.12
Rev: server/modules/graphics/rimage/rimage.pike:1.8
Rev: server/modules/logging/home_logger.pike:1.19
Rev: server/modules/misc/gtext_creator.pike:1.1
Rev: server/modules/misc/language.pike:1.17
Rev: server/modules/misc/mirrorserver.pike:1.14
Rev: server/modules/proxies/ftpgateway.pike:1.26
Rev: server/modules/proxies/gopher.pike:1.15
Rev: server/modules/proxies/wais.pike:1.12
Rev: server/modules/scripting/cgi.pike:1.106
Rev: server/modules/scripting/pikescript.pike:1.30
Rev: server/modules/tags/doc/graphic_text:1.5
Rev: server/modules/tags/htmlparse.pike:1.153
Rev: server/modules/tags/lpctag.pike:1.19
Rev: server/modules/tags/wizard_tag.pike:1.18
Rev: server/protocols/ftp.pike:1.97
Rev: server/protocols/http.pike:1.121
Rev: server/start:1.54

1: + inherit "roxenlib";    -  + array (mapping) tag_callers, container_callers; + mapping (string:mapping(int:function)) real_tag_callers,real_container_callers; + array (object) parse_modules = ({ this_object() }); + string date_doc=#string "../modules/tags/doc/date_doc"; +  + #define TRACE_ENTER(A,B) do{if(id->misc->trace_enter)id->misc->trace_enter((A),(B));}while(0) + #define TRACE_LEAVE(A) do{if(id->misc->trace_leave)id->misc->trace_leave((A));}while(0) +  + string parse_doc(string doc, string tag) + { +  return replace(doc, ({"{","}","<tag>","<roxen-languages>"}), +  ({"&lt;", "&gt;", tag, +  String.implode_nicely(sort(indices(roxen->languages)), +  "and")})); + } +  + string handle_help(string file, string tag, mapping args) + { +  return parse_doc(replace(Stdio.read_bytes(file), +  "<date-attributes>",date_doc),tag); + } +  + array|string call_tag(string tag, mapping args, int line, int i, +  object id, object file, mapping defines, +  object client) + { +  string|function rf = real_tag_callers[tag][i]; +  id->misc->line = (string)line; +  if(args->help && Stdio.file_size("modules/tags/doc/"+tag) > 0) +  { +  TRACE_ENTER("tag &lt;"+tag+" help&gt", rf); +  string h = handle_help("modules/tags/doc/"+tag, tag, args); +  TRACE_LEAVE(""); +  return h; +  } +  if(stringp(rf)) return rf; +  +  TRACE_ENTER("tag &lt;" + tag + "&gt;", rf); + #ifdef MODULE_LEVEL_SECURITY +  if(id->conf->check_security(rf, id, id->misc->seclevel)) +  { +  TRACE_LEAVE("Access denied"); +  return 0; +  } + #endif +  mixed result=rf(tag,args,id,file,defines,client); +  TRACE_LEAVE(""); +  if(args->noparse && stringp(result)) return ({ result }); +  return result; + } +  + array(string)|string + call_container(string tag, mapping args, string contents, int line, +  int i, object id, object file, mapping defines, object client) + { +  id->misc->line = (string)line; +  string|function rf = real_container_callers[tag][i]; +  if(args->help && Stdio.file_size("modules/tags/doc/"+tag) > 0) +  { +  TRACE_ENTER("container &lt;"+tag+" help&gt", rf); +  string h = handle_help("modules/tags/doc/"+tag, tag, args)+contents; +  TRACE_LEAVE(""); +  return h; +  } +  if(stringp(rf)) return rf; +  TRACE_ENTER("container &lt;"+tag+"&gt", rf); +  if(args->preparse) contents = parse_rxml(contents, id); +  if(args->trimwhites) { +  sscanf(contents, "%*[ \t\n\r]%s", contents); +  contents = reverse(contents); +  sscanf(contents, "%*[ \t\n\r]%s", contents); +  contents = reverse(contents); +  } + #ifdef MODULE_LEVEL_SECURITY +  if(id->conf->check_security(rf, id, id->misc->seclevel)) +  { +  TRACE_LEAVE("Access denied"); +  return 0; +  } + #endif +  mixed result=rf(tag,args,contents,id,file,defines,client); +  TRACE_LEAVE(""); +  if(args->noparse && stringp(result)) return ({ result }); +  return result; + } +  +  + string do_parse(string to_parse, object id, object file, mapping defines, +  object my_fd) + { +  if(!id->misc->_tags) +  id->misc->_tags = copy_value(tag_callers[0]); +  if(!id->misc->_containers) +  id->misc->_containers = copy_value(container_callers[0]); +  to_parse=parse_html_lines(to_parse,id->misc->_tags,id->misc->_containers, +  0, id, file, defines, my_fd); +  for(int i = 1; i<sizeof(tag_callers); i++) +  to_parse=parse_html_lines(to_parse,tag_callers[i], container_callers[i], +  i, id, file, defines, my_fd); +  return to_parse; + } +  +  + /* parsing modules */ + void insert_in_map_list(mapping to_insert, string map_in_object) + { +  function do_call = this_object()["call_"+map_in_object]; +  array (mapping) in = this_object()[map_in_object+"_callers"]; +  mapping (string:mapping) in2= +  this_object()["real_"+map_in_object+"_callers"]; +  +  +  foreach(indices(to_insert), string s) +  { +  if(!in2[s]) in2[s] = ([]); +  int i; +  for(i=0; i<sizeof(in); i++) +  if(!in[i][s]) +  { +  in[i][s] = do_call; +  in2[s][i] = to_insert[s]; +  break; +  } +  if(i==sizeof(in)) +  { +  in += ({ ([]) }); +  if(map_in_object == "tag") +  container_callers += ({ ([]) }); +  else +  tag_callers += ({ ([]) }); +  in[i][s] = do_call; +  in2[s][i] = to_insert[s]; +  } +  } +  this_object()[map_in_object+"_callers"]=in; +  this_object()["real_"+map_in_object+"_callers"]=in2; + } +  +  + void build_callers() + { +  object o; +  real_tag_callers=([]); +  real_container_callers=([]); +  +  // misc_cache = ([]); +  tag_callers=({ ([]) }); +  container_callers=({ ([]) }); +  +  parse_modules-=({0}); +  +  foreach (parse_modules,o) +  { +  mapping foo; +  if(o->query_tag_callers) +  { +  foo=o->query_tag_callers(); +  if(mappingp(foo)) insert_in_map_list(foo, "tag"); +  } +  +  if(o->query_container_callers) +  { +  foo=o->query_container_callers(); +  if(mappingp(foo)) insert_in_map_list(foo, "container"); +  } +  } +  sort_lists(); + } +  + void add_parse_module(object o) + { +  parse_modules |= ({o}); +  remove_call_out(build_callers); +  call_out(build_callers,0); + } +  + void remove_parse_module(object o) + { +  parse_modules -= ({o}); +  remove_call_out(build_callers); +  call_out(build_callers,0); + } +  +  +  + string call_user_tag(string tag, mapping args, int line, mixed foo, object id) + { +  id->misc->line = line; +  args = id->misc->defaults[tag]|args; +  if(!id->misc->up_args) id->misc->up_args = ([]); +  TRACE_ENTER("user defined tag &lt;"+tag+"&gt;", call_user_tag); +  array replace_from = ({"#args#"})+ +  Array.map(indices(args)+indices(id->misc->up_args), +  lambda(string q){return "&"+q+";";}); +  array replace_to = (({make_tag_attributes( args + id->misc->up_args ) })+ +  values(args)+values(id->misc->up_args)); +  foreach(indices(args), string a) +  { +  id->misc->up_args["::"+a]=args[a]; +  id->misc->up_args[tag+"::"+a]=args[a]; +  } +  string r = replace(id->misc->tags[ tag ], replace_from, replace_to); +  TRACE_LEAVE(""); +  return r; + } +  + string call_user_container(string tag, mapping args, string contents, int line, +  mixed foo, object id) + { +  if(!id->misc->defaults[tag] && id->misc->defaults[""]) +  tag = ""; +  id->misc->line = line; +  args = id->misc->defaults[tag]|args; +  if(!id->misc->up_args) id->misc->up_args = ([]); +  if(args->preparse && +  (args->preparse=="preparse" || (int)args->preparse)) +  contents = parse_rxml(contents, id); +  TRACE_ENTER("user defined container &lt;"+tag+"&gt", call_user_container); +  array replace_from = ({"#args#", "<contents>"})+ +  Array.map(indices(args)+indices(id->misc->up_args), +  lambda(string q){return "&"+q+";";}); +  array replace_to = (({make_tag_attributes( args + id->misc->up_args ), +  contents })+ +  values(args)+values(id->misc->up_args)); +  foreach(indices(args), string a) +  { +  id->misc->up_args["::"+a]=args[a]; +  id->misc->up_args[tag+"::"+a]=args[a]; +  } +  string r = replace(id->misc->containers[ tag ], replace_from, replace_to); +  TRACE_LEAVE(""); +  return r; + } +  +  + void sort_lists() + { +  array ind, val, s; +  foreach(indices(real_tag_callers), string c) +  { +  ind = indices(real_tag_callers[c]); +  val = values(real_tag_callers[c]); +  sort(ind); +  s = Array.map(val, lambda(function f) { +  catch { +  return +  function_object(f)->query("_priority"); +  }; + // werror("no priority for tag function %O\n",f); +  return 4; +  }); +  sort(s,val); +  real_tag_callers[c]=mkmapping(ind,val); +  } +  foreach(indices(real_container_callers), string c) +  { +  ind = indices(real_container_callers[c]); +  val = values(real_container_callers[c]); +  sort(ind); +  s = Array.map(val, lambda(function f) { +  catch{ +  if (functionp(f)) +  return function_object(f)->query("_priority"); +  }; + // werror("no priority for tag function %O\n",f); +  return 4; +  }); +  sort(s,val); +  real_container_callers[c]=mkmapping(ind,val); +  } + } +  +  + #define _stat defines[" _stat"] + #define _error defines[" _error"] + #define _extra_heads defines[" _extra_heads"] + #define _rettext defines[" _rettext"] + #define _ok defines[" _ok"] +  + string parse_rxml(string what, object id, +  void|object file, +  void|mapping defines ) + { +  id->misc->_rxml_recurse++ + #ifdef RXML_DEBUG +  werror("parse_rxml( "+strlen(what)+" ) -> "); +  int time = gethrtime(); + #endif +  if(!defines) +  { +  defines = id->misc->defines||([]); +  if(!_error) +  _error=200; +  if(!_extra_heads) +  _extra_heads=([ ]); +  } +  if(!defines->sizefmt) +  { +  set_start_quote(set_end_quote(0)); +  defines->sizefmt = "abbrev"; +  _error=200; +  _extra_heads=([ ]); +  if(id->misc->stat) +  _stat=id->misc->stat; +  else if(file) +  _stat=file->stat(); +  } +  id->misc->defines = defines; +  +  what = do_parse(what, id, file||id->my_fd, defines, id->my_fd); +  +  if(sizeof(_extra_heads) && !id->misc->moreheads) +  { +  id->misc->moreheads= ([]); +  id->misc->moreheads |= _extra_heads; +  } +  id->misc->_rxml_recurse--; + #ifdef RXML_DEBUG +  werror("%d (%3.3fs)\n%s", strlen(what),(gethrtime()-time)/1000000.0, +  (" "*id->misc->_rxml_recurse)); + #endif +  return what; + } +  +  +  + string tag_help(string t, mapping args, object id) + { +  array tags = sort(Array.filter(get_dir("modules/tags/doc/"), +  lambda(string tag) { +  if(tag[0] != '#' && +  tag[-1] != '~' && +  tag[0] != '.' && +  tag != "CVS") +  return 1; +  })); +  string help_for = args["for"] || id->variables->_r_t_h; +  +  if(!help_for) +  { +  string out = "<h3>Roxen Interactive RXML Help</h3>" +  "<b>Here is a list of all documented tags. Click on the name to " +  "receive more detailed information.</b><p>"; +  array tag_links = ({}); +  foreach(tags, string tag) +  { +  tag_links += ({ sprintf("<a href=?_r_t_h=%s>%s</a>", tag, tag) }); +  } +  return out + String.implode_nicely(tag_links); +  } else if(Stdio.file_size("modules/tags/doc/"+help_for) > 0) { +  string h = handle_help("modules/tags/doc/"+help_for, help_for, args); +  return h; +  } else { +  return "<h3>No help available for "+help_for+".</h3>"; +  } + } +  +  + string tag_list_tags( string t, mapping args, object id, object f ) + { +  int verbose; +  string res=""; +  if(args->verbose) verbose = 1; +  +  for(int i = 0; i<sizeof(tag_callers); i++) +  { +  res += ("<b><font size=+1>Tags at prioity level "+i+": </b></font><p>"); +  foreach(sort(indices(tag_callers[i])), string tag) +  { +  res += " <a name=\""+replace(tag+i, "#", ".")+"\"><a href=\""+id->not_query+"?verbose="+replace(tag+i, "#","%23")+"#"+replace(tag+i, "#", ".")+"\">&lt;"+tag+"&gt;</a></a><br>"; +  if(verbose || id->variables->verbose == tag+i) +  { +  res += "<blockquote><table><tr><td>"; +  string tr; +  catch(tr=call_tag(tag, (["help":"help"]), +  id->misc->line,i, +  id, f, id->misc->defines, id->my_fd )); +  if(tr) res += tr; else res += "no help"; +  res += "</td></tr></table></blockquote>"; +  } +  } +  } +  +  for(int i = 0; i<sizeof(container_callers); i++) +  { +  res += ("<p><b><font size=+1>Containers at prioity level "+i+": </b></font><p>"); +  foreach(sort(indices(container_callers[i])), string tag) +  { +  res += " <a name=\""+replace(tag+i, "#", ".")+"\"><a href=\""+id->not_query+"?verbose="+replace(tag+i, "#", "%23")+"#"+replace(tag+i,"#",".")+"\">&lt;"+tag+"&gt;&lt;/"+tag+"&gt;</a></a><br>"; +  if(verbose || id->variables->verbose == tag+i) +  { +  res += "<blockquote><table><tr><td>"; +  string tr; +  catch(tr=call_container(tag, (["help":"help"]), "", +  id->misc->line, +  i, id,f, id->misc->defines, id->my_fd )); +  if(tr) res += tr; else res += "no help"; +  res += "</td></tr></table></blockquote>"; +  } +  } +  } +  return res; + } +  + string tag_line( string t, mapping args, object id) + { +  return id->misc->line; + } +  +  + string tag_use(string tag, mapping m, object id) + { +  mapping res = ([]); +  object nid = id->clone_me(); +  nid->misc->tags = 0; +  nid->misc->containers = 0; +  nid->misc->defines = ([]); +  nid->misc->_tags = 0; +  nid->misc->_containers = 0; +  nid->misc->defaults = ([]); +  +  if(m->packageinfo) +  { +  string res ="<dl>"; +  array dirs = get_dir("../rxml_packages"); +  if(dirs) +  foreach(dirs, string f) +  catch +  { +  string doc = ""; +  string data = Stdio.read_bytes("../rxml_packages/"+f); +  sscanf(data, "%*sdoc=\"%s\"", doc); +  parse_rxml(data, nid); +  res += "<dt><b>"+f+"</b><dd>"+doc+"<br>"; +  array tags = indices(nid->misc->tags||({})); +  array containers = indices(nid->misc->containers||({})); +  if(sizeof(tags)) +  res += "defines the following tag"+ +  (sizeof(tags)!=1?"s":"") +": "+ +  String.implode_nicely( sort(tags) )+"<br>"; +  if(sizeof(containers)) +  res += "defines the following container"+ +  (sizeof(tags)!=1?"s":"") +": "+ +  String.implode_nicely( sort(containers) )+"<br>"; +  }; +  else +  return "No package directory installed."; +  return res+"</dl>"; +  } +  +  +  if(!m->file && !m->package) +  return "<use help>"; +  +  if(id->pragma["no-cache"] || +  !(res = cache_lookup("macrofiles:"+ id->conf->name , +  (m->file || m->package)))) +  { +  res = ([]); +  string foo; +  if(m->file) +  foo = nid->conf->try_get_file( fix_relative(m->file,nid), nid ); +  else +  foo=Stdio.read_bytes("../rxml_packages/"+combine_path("/",m->package)); +  +  if(!foo) +  if(id->misc->debug) +  return "Failed to fetch "+(m->file||m->package); +  else +  return ""; +  parse_rxml( foo, nid ); +  res->tags = nid->misc->tags||([]); +  res->_tags = nid->misc->_tags||([]); +  foreach(indices(res->_tags), string t) +  if(!res->tags[t]) m_delete(res->_tags, t); +  res->containers = nid->misc->containers||([]); +  res->_containers = nid->misc->_containers||([]); +  foreach(indices(res->_containers), string t) +  if(!res->containers[t]) m_delete(res->_containers, t); +  res->defines = nid->misc->defines||([]); +  res->defaults = nid->misc->defaults||([]); +  m_delete(res->defines, "line"); +  cache_set("macrofiles:"+ id->conf->name, (m->file || m->package), res); +  } +  +  if(!id->misc->tags) +  id->misc->tags = res->tags; +  else +  id->misc->tags |= res->tags; +  +  if(!id->misc->containers) +  id->misc->containers = res->containers; +  else +  id->misc->containers |= res->containers; +  +  if(!id->misc->defaults) +  id->misc->defaults = res->defaults; +  else +  id->misc->defaults |= res->defaults; +  +  if(!id->misc->defines) +  id->misc->defines = res->defines; +  else +  id->misc->defines |= res->defines; +  +  foreach(indices(res->_tags), string t) +  id->misc->_tags[t] = res->_tags[t]; +  +  foreach(indices(res->_containers), string t) +  id->misc->_containers[t] = res->_containers[t]; +  +  if(id->misc->debug) +  return sprintf("<!-- Using the file %s, id %O -->", m->file, res); +  else +  return ""; + } +  + string tag_define(string tag, mapping m, string str, object id, object file, +  mapping defines) + { +  if (m->name) +  defines[m->name]=str; +  else if(m->variable) +  id->variables[m->variable] = str; +  else if (m->tag) +  { +  if(!id->misc->tags) +  id->misc->tags = ([]); +  if(!id->misc->defaults) +  id->misc->defaults = ([]); +  m->tag = lower_case(m->tag); +  if(!id->misc->defaults[m->tag]) +  id->misc->defaults[m->tag] = ([]); +  +  foreach( indices(m), string arg ) +  if( arg[0..7] == "default_" ) +  id->misc->defaults[m->tag] += ([ arg[8..]:m[arg] ]); +  +  id->misc->tags[m->tag] = str; +  id->misc->_tags[m->tag] = call_user_tag; +  } +  else if (m->container) +  { +  if(!id->misc->containers) +  id->misc->containers = ([]); +  +  if(!id->misc->defaults) +  id->misc->defaults = ([]); +  if(!id->misc->defaults[m->container]) +  id->misc->defaults[m->container] = ([]); +  +  foreach( indices(m), string arg ) +  if( arg[0..7] == "default_" ) +  id->misc->defaults[m->container] += ([ arg[8..]:m[arg] ]); +  +  id->misc->containers[m->container] = str; +  id->misc->_containers[m->container] = call_user_container; +  } +  else return "<!-- No name, tag or container specified for the define! " +  "&lt;define help&gt; for instructions. -->"; +  return ""; + } +  + string tag_undefine(string tag, mapping m, object id, object file, +  mapping defines) + { +  if (m->name) +  m_delete(defines,m->name); +  else if(m->variable) +  m_delete(id->variables,m->variable); +  else if (m->tag) +  { +  m_delete(id->misc->tags,m->tag); +  m_delete(id->misc->_tags,m->tag); +  } +  else if (m->container) +  { +  m_delete(id->misc->containers,m->container); +  m_delete(id->misc->_containers,m->container); +  } +  else return "<!-- No name, tag or container specified for undefine! " +  "&lt;undefine help&gt; for instructions. -->"; +  return ""; + } +  +  + mapping query_container_callers() + { +  return ([ +  "define":tag_define, +  ]); + } +  +  + mapping query_tag_callers() + { +  return ([ +  "list-tags":tag_list_tags, +  "undefine":tag_undefine, +  "help": tag_help, +  "line":tag_line, +  "use":tag_use, +  ]); + }   Newline at end of file added.