1430c0 | 2000-03-16 | Martin Nilsson | |
|
ea72a6 | 1999-11-27 | Per Hedbor | |
|
3aca38 | 2000-08-09 | Per Hedbor | | constant cvs_version = "$Id: piketag.pike,v 2.10 2000/08/09 05:15:43 per Exp $";
|
ea72a6 | 1999-11-27 | Per Hedbor | | constant thread_safe=1;
inherit "module";
|
e123c7 | 2000-07-17 | Johan Sundström | | #include <module.h>
|
ea72a6 | 1999-11-27 | Per Hedbor | |
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];
}
|
325751 | 2000-08-09 | Per Hedbor | | void write(mixed ... args)
{
if(!sizeof(args))
return;
if(sizeof(args) > 1)
data += sprintf(@args);
else
data += args[0];
}
|
ea72a6 | 1999-11-27 | Per Hedbor | | string flush()
{
string r = data;
data ="";
return r;
}
|
3aca38 | 2000-08-09 | Per Hedbor | | string rxml( string what, object id )
{
return parse_rxml( what, id );
}
|
ea72a6 | 1999-11-27 | Per Hedbor | | 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)
{
|
325751 | 2000-08-09 | Per Hedbor | | add_constant( "__ps_magic_helpers", Helpers );
return "inherit __ps_magic_helpers;\n" +
"#"+line+" \""+replace(page,"\"","\\\"")+"\"\n";
|
ea72a6 | 1999-11-27 | Per Hedbor | | }
|
9266a3 | 2000-08-09 | Per Hedbor | | string pre(array fl, object id)
|
ea72a6 | 1999-11-27 | Per Hedbor | | {
|
9266a3 | 2000-08-09 | Per Hedbor | | foreach( fl, object token )
if( token == "parse" )
return functions(id->not_query, id->misc->line);
return functions(id->not_query, id->misc->line) +
"string|int parse(RequestID id) { ";
|
ea72a6 | 1999-11-27 | Per Hedbor | | }
|
9266a3 | 2000-08-09 | Per Hedbor | | string post(array fl)
|
ea72a6 | 1999-11-27 | Per Hedbor | | {
|
9266a3 | 2000-08-09 | Per Hedbor | | foreach( fl, object token )
if( token == "parse" )
return "";
|
325751 | 2000-08-09 | Per Hedbor | | return "}";
|
ea72a6 | 1999-11-27 | Per Hedbor | | }
private static mapping(string:program) program_cache = ([]);
|
325751 | 2000-08-09 | Per Hedbor | | string simple_pi_tag_pike( string tag, mapping m, string s,RequestID id )
{
return simpletag_pike( tag, ([]), s, id );
}
|
ea72a6 | 1999-11-27 | Per Hedbor | |
|
325751 | 2000-08-09 | Per Hedbor | | string simpletag_pike(string tag, mapping m, string s,RequestID request_id )
|
ea72a6 | 1999-11-27 | Per Hedbor | | {
program p;
object o;
string res;
mixed err;
request_id->misc->cacheable=0;
|
9266a3 | 2000-08-09 | Per Hedbor | | array flat=Parser.C.hide_whitespaces(Parser.C.tokenize(Parser.C.split(s)));
|
ea72a6 | 1999-11-27 | Per Hedbor | | object e = ErrorContainer();
master()->set_inhibit_compile_errors(e);
if(err=catch
{
|
3aca38 | 2000-08-09 | Per Hedbor | | object cip, cipup;
#define OCIP( ) \
if( cip ) \
{ \
cip->text=sprintf("write(rxml(%O,id));",cip->text); \
cip = 0; \
}
#define OCIPUP( ) \
if( cipup ) \
{ \
cipup->text=sprintf("write(%O);",cipup->text); \
cipup = 0; \
}
#define CIP(X) if( X ) \
{ \
flat[i]->text=flat[i]->trailing_whitespaces=""; \
X->text += flat[i]->text[3..]+"\n"; \
} \
else \
{ \
X = flat[i]; \
flat[i]->text = flat[i]->text[3..]+"\n"; \
}
|
9266a3 | 2000-08-09 | Per Hedbor | |
|
3aca38 | 2000-08-09 | Per Hedbor | | for( int i = 0; i<sizeof( flat ); i++ )
{
if( flat[i] == "." && flat[++i] != "." )
flat[i-1]->text = "->";
else if( flat[i]->text[..2] == "//#" )
{
OCIPUP();
CIP( cip );
}
else if( flat[i]->text[..2] == "//@" )
{
OCIP();
CIP( cipup );
}
else
{
OCIP();
OCIPUP();
}
}
OCIP();
OCIPUP();
s = pre(flat,request_id)+"\n"+
Parser.C.simple_reconstitute( flat )+
post(flat);
|
ea72a6 | 1999-11-27 | Per Hedbor | | p = program_cache[s];
if (!p)
{
|
325751 | 2000-08-09 | Per Hedbor | | object key = Roxen.add_scope_constants();
|
9266a3 | 2000-08-09 | Per Hedbor | |
|
ea72a6 | 1999-11-27 | Per Hedbor | | p = compile_string(s, "Pike-tag("+request_id->not_query+":"+
request_id->misc->line+")");
|
325751 | 2000-08-09 | Per Hedbor | | destruct( key );
|
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"
|
325751 | 2000-08-09 | Per Hedbor | | "%s\n\n", request_id->not_query,
s),
|
ea72a6 | 1999-11-27 | Per Hedbor | | e->get());
}
master()->set_inhibit_compile_errors(0);
if(err = catch{
|
325751 | 2000-08-09 | Per Hedbor | | res = (o=p())->parse(request_id);
|
ea72a6 | 1999-11-27 | Per Hedbor | | })
{
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;
}
|