From 5df79c53745fde5d6c3340a2979b1429cd5892c1 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sat, 8 Oct 2011 20:30:28 +0200 Subject: Initial import of htcd system 1.0 Signed-off-by: Henrik Rydberg --- src/lang/func.cc | 249 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 src/lang/func.cc (limited to 'src/lang/func.cc') diff --git a/src/lang/func.cc b/src/lang/func.cc new file mode 100644 index 0000000..98cc04c --- /dev/null +++ b/src/lang/func.cc @@ -0,0 +1,249 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +const mstring cron_tag="cron."; +const int SSECS=4; + +TOK_IMPL(def) { + expr_t* x=env.arg(2); + func_t* tok=Func(*env.toks,env[0],x->expr,tok_t::PUBLIC,env[1]); + if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env); +} + +TOK_IMPL(redef) { + expr_t* x=env.arg(2); + func_t* tok=Func(*env.toks,env[0],x->expr,tok_t::PUBLIC,env[1],1); + if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env); +} + +TOK_IMPL(ldef) { + if(env.toks->get(env[0])) THROW("htc: local function would override global token"); + expr_t* x=env.arg(2); + func_t* tok=Func(env.loc,env[0],x->expr,tok_t::PUBLIC,env[1]); + if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env); +} + +TOK_IMPL(cron) { + mstring name=cron_tag+env[0]; + expr_t* x=env.arg(1); + cron_t* tok=Cron(*env.toks,name,x->expr,tok_t::PUBLIC,atoi(env[0])); + if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env); +} + +/////////////////////////////////////////////////// + +static void Run(tokmap& m,mstream& out,Env& env,const sref& s) throw(merror_t) { + tok_t* p=m.get(s); + if(!p) THROW("htc: cannot run "<is_reference()) env.parse(out,((reference_t*)p)->data); + else if(!p->is_runnable()) env.parse(out,p->body); + } + catch(const merror_t& e) { + out< cron; + int cont=1; for(tokmap* tok=env.toks;tok&&cont;tok=tok->up) { + for(Env::iterator p=tok->begin();p!=tok->end();++p) { + if((*p)->name.left(cron_tag.size())==cron_tag&&(*p)->is_cron()) { + cron.push_back((cron_t*)(*p)); + cont=0; + } + } + } + while(env.req->is_running()&&cron.size()) { + int cont=1; + for(int i=0;icron[i]->last+cron[i]->interval) { + mstream ms; + env.eval(ms,&cron[i]->x,0); + cron[i]->last=time(0); + cont=0; + } + } + if(cont) sleep(SSECS); + } +} + +////////////////////////////////////////////////////// + +void envAddFunc(tokmap& T) +{ + TOK_ADD(def,"xxr",tok_t::PUBLIC, + "%Define new global function\n" + "%Syntax: \\def{varname}{argument string [xr?*]}{body}\n" + "%\n" + "%The argument string is a sequence of characters describing\n" + "%the argument type, which is one of x (pre-evaluate), r (post-evaluate),\n" + "%? (optional post-evaluate) or * (optional at end, post-evaluate).\n" + "%The can be only one optional (?) argument.\n" + "%The body contains the function body. The arguments are retrieved\n" + "%as \\1, \\2 etc, except the optional argument which is retrieved as \\0,\n" + "%regardless of where it stands in the sequence.\n" + "%\n" + "%Generates an error if already defined.\n" + ); + TOK_ADD(redef,"xxr",tok_t::PRIVATE, + "%Redefine global function\n" + "%Syntax: \\def{varname}{argument string [xr?*]}{body}\n" + "%\n" + "%The argument string is a sequence of characters describing\n" + "%the argument type, which is one of x (pre-evaluate), r (post-evaluate),\n" + "%? (optional post-evaluate) or * (optional at end, post-evaluate).\n" + "%The can be only one optional (?) argument.\n" + "%The body contains the function body. The arguments are retrieved\n" + "%as \\1, \\2 etc, except the optional argument which is retrieved as \\0,\n" + "%regardless of where it stands in the sequence.\n" + "%\n" + "%Takes precedence over any existing function.\n" + ); + TOK_ADD(ldef,"xxr",tok_t::PUBLIC, + "%Define a local function\n" + "%Syntax: \\ldef{varname}{argument string [xr?*]}{body}\n" + "%\n" + "%The argument string is a sequence of characters describing\n" + "%the argument type, which is one of x (pre-evaluate), r (post-evaluate),\n" + "%? (optional post-evaluate) or * (optional at end, post-evaluate).\n" + "%The can be only one optional (?) argument.\n" + "%The body contains the function body. The arguments are retrieved\n" + "%as \\1, \\2 etc, except the optional argument which is retrieved as \\0,\n" + "%regardless of where it stands in the sequence.\n" + "%\n" + "%Local functions work just like global functions, but are only\n" + "%accessible from within the current stack frame.\n" + ); + TOK_ADD(cron,"xr",tok_t::SYSONLY, + "%Define a cron function\n" + "%Syntax: \\cron{interval}{body}\n" + "%\n" + "%A cron function is executed every interval seconds,\n" + "%when running in cron mode.\n" + "%\n" + "%See \\run.cron.\n" + ); + + ////////////////////////////////////////////////////// + + TOK_ADD(run,"x",tok_t::SYSONLY, + "%Evaluate the body of variable in current running mode\n" + "%Syntax: \\run{varname}\n" + "%\n" + "%The running modes are:\n" + "%\n" + "%XINIT Init mode is only used to collect meta information\n" + "%XSYSTEM The system mode - everything is accessible\n" + "%XPRIVATE Private mode - suitable for in-door custom programs\n" + "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n" + "% via the web. This is the default mode for all derivative\n" + "% functions, as well as for globals and constants.\n" + "%\n" + "%IT IS A MAJOR SECURITY HAZARD TO EVALUATE UNKNOWN\n" + "%VARIABLES IN XSYSTEM MODE!!\n" + "%\n" + "%If at all, user-supplied information should only be run\n" + "%in public mode, for instance to allow the expansion of latex\n" + "%commands. NEVER use this mode outside the core.\n" + ); + TOK_ADD(run_private,"x",tok_t::SYSONLY, + "%Evaluate the body of variable in private mode\n" + "%Syntax: \\run.private{varname}\n" + "%\n" + "%The running modes are:\n" + "%\n" + "%XINIT Init mode is only used to collect meta information\n" + "%XSYSONLY The system mode - everything is accessible\n" + "%XPRIVATE Private mode - suitable for in-door custom htc code\n" + "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n" + "% via the web. This is the default mode for all derivative\n" + "% functions, as well as for globals and constants.\n" + "%\n" + "%The execution of sysonly functions is silent, just as it wasn't there.\n" + ); + TOK_ADD(run_public,"x",tok_t::PRIVATE, + "%Evaluate the body of variable in public mode\n" + "%Syntax: \\run.public{varname}\n" + "%\n" + "%The running modes are:\n" + "%\n" + "%XINIT Init mode is only used to collect meta information\n" + "%XSYSONLY The system mode - everything is accessible\n" + "%XPRIVATE Private mode - suitable for in-door custom programs\n" + "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n" + "% via the web. This is the default mode for all derivative\n" + "% functions, as well as for globals and constants.\n" + "%\n" + "%The execution of sysonly or private functions is silent,\n" + "%just as they weren't there.\n" + ); + TOK_ADD(run_local,"x",tok_t::PRIVATE, + "%Evaluate the body of the local variable in public mode\n" + "%Syntax: \\run.local{varname}\n" + "%\n" + "%The running modes are:\n" + "%\n" + "%XINIT Init mode is only used to collect meta information\n" + "%XSYSTEM The system mode - everything is accessible\n" + "%XPRIVATE Private mode - suitable for in-door custom programs\n" + "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n" + "% via the web. This is the default mode for all derivative\n" + "% functions, as well as for globals and constants.\n" + "%\n" + "%The execution of sysonly or private functions is silent,\n" + "%just as they weren't there.\n" + ); + TOK_ADD(run_cron,"",tok_t::SYSONLY, + "%Go into an infinite loop and run the crontab command.\n" + "%Syntax: \\run.cron{}\n" + "%\n" + "%Note that only cron functions from the highest global level\n" + "%where a cron function is defined is run. Hence you may redefine\n" + "%earlier crontabs, but cannot mix between levels.\n" + "%\n" + "%You can only have one crontab of a certain interval.\n" + "%\n" + "%Produces no output.\n" + ); +} -- cgit v1.2.3