1430c0 | 2000-03-16 | Martin Nilsson | |
|
ea72a6 | 1999-11-27 | Per Hedbor | |
|
4f641b | 2000-07-03 | Martin Nilsson | | constant cvs_version = "$Id: piketag.pike,v 2.6 2000/07/03 06:43:20 nilsson Exp $";
|
ea72a6 | 1999-11-27 | Per Hedbor | | constant thread_safe=1;
inherit "module";
constant module_type = MODULE_PARSER;
constant module_name = "Pike tag";
constant module_doc =
#"This module adds a new tag, <pike></pike>. It makes it
|
197355 | 2000-02-10 | Martin Nilsson | | possible to insert some pike code directly in the document. <br>
<img src=\"internal-roxen-err_2\" align=\"left\" alt=\"Warning\"> <br>NOTE: Enabling this
|
ea72a6 | 1999-11-27 | Per Hedbor | | module is the same thing as letting your users run programs with the
same right as the server! Example:<p><pre> <pike> return
\"Hello world!\\n\"; </pike>\n</pre> <p>Arguments: Any, all
arguments are passed to the script in the mapping args. There are also
a few helper functions available, output(string fmt, mixed ... args)
is a fast way to add new data to a dynamic buffer, flush() returns the
contents of the buffer as a string. A flush() is done automatically
if the script does not return any data, thus, another way to write the
hello world script is <tt><pike>output(\"Hello %s\n\",
\"World\");</pike></tt><p> The request id is available as id.";
void create()
{
defvar (
"debugmode", "Log", "Error messages", TYPE_STRING_LIST | VAR_MORE,
"How to report errors (e.g. backtraces generated by the Pike code):\n"
"\n"
"<p><ul>\n"
|
4f641b | 2000-07-03 | Martin Nilsson | | "<li><i>Off</i> - Silent.</li>\n"
"<li><i>Log</i> - System debug log.</li>\n"
"<li><i>HTML comment</i> - Include in the generated page as an HTML comment.</li>\n"
"<li><i>HTML text</i> - Include in the generated page as normal text.</li>\n"
|
ea72a6 | 1999-11-27 | Per Hedbor | | "</ul>\n",
({"Off", "Log", "HTML comment", "HTML text"}));
defvar("program_cache_limit", 256, "Program cache limit", TYPE_INT|VAR_MORE,
"Maximum size of the cache for compiled programs.");
}
string reporterr (string header, string dump)
{
|
4f641b | 2000-07-03 | Martin Nilsson | | if (query("debugmode") == "Off") return "";
|
ea72a6 | 1999-11-27 | Per Hedbor | |
report_error( header + dump + "\n" );
|
4f641b | 2000-07-03 | Martin Nilsson | | switch (query("debugmode"))
|
ea72a6 | 1999-11-27 | Per Hedbor | | {
case "HTML comment":
|
4f641b | 2000-07-03 | Martin Nilsson | | return "\n<!-- " + Roxen.html_encode_string(header + dump) + "\n-->\n";
|
ea72a6 | 1999-11-27 | Per Hedbor | | case "HTML text":
|
4f641b | 2000-07-03 | Martin Nilsson | | return "\n<br><font color=\"red\"><b><pre>" + Roxen.html_encode_string (header) +
"</b></pre></font><pre>\n"+Roxen.html_encode_string (dump) + "</pre><br />\n";
|
ea72a6 | 1999-11-27 | Per Hedbor | | default:
return "";
}
}
class Helpers
{
|
4d2fc4 | 1999-12-21 | Per Hedbor | | inherit "roxenlib";
|
ea72a6 | 1999-11-27 | Per Hedbor | | string data = "";
void output(mixed ... args)
{
if(!sizeof(args))
return;
if(sizeof(args) > 1)
data += sprintf(@args);
else
data += args[0];
}
string flush()
{
string r = data;
data ="";
return r;
}
constant seteuid=0;
constant setegid=0;
constant setuid=0;
constant setgid=0;
constant call_out=0;
constant all_constants=0;
constant Privs=0;
}
string functions(string page, int line)
{
add_constant( "__magic_helpers", Helpers );
return
"inherit __magic_helpers;\n"
"#"+line+" \""+replace(page,"\"","\\\"")+"\"\n";
}
string pre(string what, object id)
{
if(search(what, "parse(") != -1)
return functions(id->not_query, id->misc->line);
if(search(what, "return") != -1)
return functions(id->not_query, id->misc->line) +
"string|int parse(RequestID id, mapping defines, object file, mapping args) { ";
else
return functions(id->not_query, id->misc->line) +
"string|int parse(RequestID id, mapping defines, object file, mapping args) { return ";
}
string post(string what)
{
if(search(what, "parse(") != -1)
return "";
if (!strlen(what) || what[-1] != ';')
return ";}";
else
return "}";
}
private static mapping(string:program) program_cache = ([]);
string container_pike(string tag, mapping m, string s, RequestID request_id,
object file, mapping defs)
{
program p;
object o;
string res;
mixed err;
request_id->misc->cacheable=0;
object e = ErrorContainer();
master()->set_inhibit_compile_errors(e);
if(err=catch
{
s = pre(s,request_id)+s+post(s);
p = program_cache[s];
if (!p)
{
p = compile_string(s, "Pike-tag("+request_id->not_query+":"+
request_id->misc->line+")");
|
4f641b | 2000-07-03 | Martin Nilsson | | if (sizeof(program_cache) > query("program_cache_limit"))
|
ea72a6 | 1999-11-27 | Per Hedbor | | {
array a = indices(program_cache);
int i;
|
4f641b | 2000-07-03 | Martin Nilsson | | for(i = query("program_cache_limit")/2; i > 0; i--)
|
ea72a6 | 1999-11-27 | Per Hedbor | | m_delete(program_cache, a[random(sizeof(a))]);
}
program_cache[s] = p;
}
})
{
master()->set_inhibit_compile_errors(0);
return reporterr(sprintf("Error compiling <pike> tag in %s:\n"
"%s\n\n", request_id->not_query, s),
e->get());
}
master()->set_inhibit_compile_errors(0);
if(err = catch{
res = (o=p())->parse(request_id, defs, file, m);
})
{
return (res || "") + (o && o->flush() || "") +
reporterr ("Error in <pike> tag in " + request_id->not_query + ":\n",
(describe_backtrace (err) / "\n")[0..1] * "\n");
}
res = (res || "") + (o && o->flush() || "");
if(o)
destruct(o);
return res;
}
|