summaryrefslogtreecommitdiff
path: root/src/lang/func.cc
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
committerHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
commit5df79c53745fde5d6c3340a2979b1429cd5892c1 (patch)
tree1a81af141708b826e9c61e8a04019994fcca8298 /src/lang/func.cc
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/lang/func.cc')
-rw-r--r--src/lang/func.cc249
1 files changed, 249 insertions, 0 deletions
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 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <lang/env.h>
21#include <unistd.h>
22
23const mstring cron_tag="cron.";
24const int SSECS=4;
25
26TOK_IMPL(def) {
27 expr_t* x=env.arg(2);
28 func_t* tok=Func(*env.toks,env[0],x->expr,tok_t::PUBLIC,env[1]);
29 if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env);
30}
31
32TOK_IMPL(redef) {
33 expr_t* x=env.arg(2);
34 func_t* tok=Func(*env.toks,env[0],x->expr,tok_t::PUBLIC,env[1],1);
35 if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env);
36}
37
38TOK_IMPL(ldef) {
39 if(env.toks->get(env[0])) THROW("htc: local function would override global token");
40 expr_t* x=env.arg(2);
41 func_t* tok=Func(env.loc,env[0],x->expr,tok_t::PUBLIC,env[1]);
42 if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env);
43}
44
45TOK_IMPL(cron) {
46 mstring name=cron_tag+env[0];
47 expr_t* x=env.arg(1);
48 cron_t* tok=Cron(*env.toks,name,x->expr,tok_t::PUBLIC,atoi(env[0]));
49 if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env);
50}
51
52///////////////////////////////////////////////////
53
54static void Run(tokmap& m,mstream& out,Env& env,const sref& s) throw(merror_t) {
55 tok_t* p=m.get(s);
56 if(!p) THROW("htc: cannot run "<<s<<"; does not exist");
57 try {
58 if(p->is_reference()) env.parse(out,((reference_t*)p)->data);
59 else if(!p->is_runnable()) env.parse(out,p->body);
60 }
61 catch(const merror_t& e) {
62 out<<e.desc;
63 }
64}
65
66TOK_IMPL(run) {
67 Env e(env,env.mod,env.pwd);
68 Run(*env.toks,out,e,env[0]);
69}
70TOK_IMPL(run_private) {
71 Env e(env,XPRIVATE,env.pwd);
72 Run(*env.toks,out,e,env[0]);
73}
74TOK_IMPL(run_public) {
75 Env e(env,XPUBLIC,env.pwd);
76 Run(*env.toks,out,e,env[0]);
77}
78TOK_IMPL(run_local) {
79 try {
80 Env e(env,XPUBLIC,env.pwd);
81 e.parse(out,env.gloc(env[0]));
82 }
83 catch(const merror_t& e) {
84 out<<e.desc;
85 }
86}
87TOK_IMPL(run_cron) {
88 mrvec<cron_t*> cron;
89 int cont=1; for(tokmap* tok=env.toks;tok&&cont;tok=tok->up) {
90 for(Env::iterator p=tok->begin();p!=tok->end();++p) {
91 if((*p)->name.left(cron_tag.size())==cron_tag&&(*p)->is_cron()) {
92 cron.push_back((cron_t*)(*p));
93 cont=0;
94 }
95 }
96 }
97 while(env.req->is_running()&&cron.size()) {
98 int cont=1;
99 for(int i=0;i<cron.size()&&cont;i++) {
100 if(time(0)>cron[i]->last+cron[i]->interval) {
101 mstream ms;
102 env.eval(ms,&cron[i]->x,0);
103 cron[i]->last=time(0);
104 cont=0;
105 }
106 }
107 if(cont) sleep(SSECS);
108 }
109}
110
111//////////////////////////////////////////////////////
112
113void envAddFunc(tokmap& T)
114{
115 TOK_ADD(def,"xxr",tok_t::PUBLIC,
116 "%Define new global function\n"
117 "%Syntax: \\def{varname}{argument string [xr?*]}{body}\n"
118 "%\n"
119 "%The argument string is a sequence of characters describing\n"
120 "%the argument type, which is one of x (pre-evaluate), r (post-evaluate),\n"
121 "%? (optional post-evaluate) or * (optional at end, post-evaluate).\n"
122 "%The can be only one optional (?) argument.\n"
123 "%The body contains the function body. The arguments are retrieved\n"
124 "%as \\1, \\2 etc, except the optional argument which is retrieved as \\0,\n"
125 "%regardless of where it stands in the sequence.\n"
126 "%\n"
127 "%Generates an error if already defined.\n"
128 );
129 TOK_ADD(redef,"xxr",tok_t::PRIVATE,
130 "%Redefine global function\n"
131 "%Syntax: \\def{varname}{argument string [xr?*]}{body}\n"
132 "%\n"
133 "%The argument string is a sequence of characters describing\n"
134 "%the argument type, which is one of x (pre-evaluate), r (post-evaluate),\n"
135 "%? (optional post-evaluate) or * (optional at end, post-evaluate).\n"
136 "%The can be only one optional (?) argument.\n"
137 "%The body contains the function body. The arguments are retrieved\n"
138 "%as \\1, \\2 etc, except the optional argument which is retrieved as \\0,\n"
139 "%regardless of where it stands in the sequence.\n"
140 "%\n"
141 "%Takes precedence over any existing function.\n"
142 );
143 TOK_ADD(ldef,"xxr",tok_t::PUBLIC,
144 "%Define a local function\n"
145 "%Syntax: \\ldef{varname}{argument string [xr?*]}{body}\n"
146 "%\n"
147 "%The argument string is a sequence of characters describing\n"
148 "%the argument type, which is one of x (pre-evaluate), r (post-evaluate),\n"
149 "%? (optional post-evaluate) or * (optional at end, post-evaluate).\n"
150 "%The can be only one optional (?) argument.\n"
151 "%The body contains the function body. The arguments are retrieved\n"
152 "%as \\1, \\2 etc, except the optional argument which is retrieved as \\0,\n"
153 "%regardless of where it stands in the sequence.\n"
154 "%\n"
155 "%Local functions work just like global functions, but are only\n"
156 "%accessible from within the current stack frame.\n"
157 );
158 TOK_ADD(cron,"xr",tok_t::SYSONLY,
159 "%Define a cron function\n"
160 "%Syntax: \\cron{interval}{body}\n"
161 "%\n"
162 "%A cron function is executed every interval seconds,\n"
163 "%when running in cron mode.\n"
164 "%\n"
165 "%See \\run.cron.\n"
166 );
167
168 //////////////////////////////////////////////////////
169
170 TOK_ADD(run,"x",tok_t::SYSONLY,
171 "%Evaluate the body of variable in current running mode\n"
172 "%Syntax: \\run{varname}\n"
173 "%\n"
174 "%The running modes are:\n"
175 "%\n"
176 "%XINIT Init mode is only used to collect meta information\n"
177 "%XSYSTEM The system mode - everything is accessible\n"
178 "%XPRIVATE Private mode - suitable for in-door custom programs\n"
179 "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n"
180 "% via the web. This is the default mode for all derivative\n"
181 "% functions, as well as for globals and constants.\n"
182 "%\n"
183 "%IT IS A MAJOR SECURITY HAZARD TO EVALUATE UNKNOWN\n"
184 "%VARIABLES IN XSYSTEM MODE!!\n"
185 "%\n"
186 "%If at all, user-supplied information should only be run\n"
187 "%in public mode, for instance to allow the expansion of latex\n"
188 "%commands. NEVER use this mode outside the core.\n"
189 );
190 TOK_ADD(run_private,"x",tok_t::SYSONLY,
191 "%Evaluate the body of variable in private mode\n"
192 "%Syntax: \\run.private{varname}\n"
193 "%\n"
194 "%The running modes are:\n"
195 "%\n"
196 "%XINIT Init mode is only used to collect meta information\n"
197 "%XSYSONLY The system mode - everything is accessible\n"
198 "%XPRIVATE Private mode - suitable for in-door custom htc code\n"
199 "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n"
200 "% via the web. This is the default mode for all derivative\n"
201 "% functions, as well as for globals and constants.\n"
202 "%\n"
203 "%The execution of sysonly functions is silent, just as it wasn't there.\n"
204 );
205 TOK_ADD(run_public,"x",tok_t::PRIVATE,
206 "%Evaluate the body of variable in public mode\n"
207 "%Syntax: \\run.public{varname}\n"
208 "%\n"
209 "%The running modes are:\n"
210 "%\n"
211 "%XINIT Init mode is only used to collect meta information\n"
212 "%XSYSONLY The system mode - everything is accessible\n"
213 "%XPRIVATE Private mode - suitable for in-door custom programs\n"
214 "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n"
215 "% via the web. This is the default mode for all derivative\n"
216 "% functions, as well as for globals and constants.\n"
217 "%\n"
218 "%The execution of sysonly or private functions is silent,\n"
219 "%just as they weren't there.\n"
220 );
221 TOK_ADD(run_local,"x",tok_t::PRIVATE,
222 "%Evaluate the body of the local variable in public mode\n"
223 "%Syntax: \\run.local{varname}\n"
224 "%\n"
225 "%The running modes are:\n"
226 "%\n"
227 "%XINIT Init mode is only used to collect meta information\n"
228 "%XSYSTEM The system mode - everything is accessible\n"
229 "%XPRIVATE Private mode - suitable for in-door custom programs\n"
230 "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n"
231 "% via the web. This is the default mode for all derivative\n"
232 "% functions, as well as for globals and constants.\n"
233 "%\n"
234 "%The execution of sysonly or private functions is silent,\n"
235 "%just as they weren't there.\n"
236 );
237 TOK_ADD(run_cron,"",tok_t::SYSONLY,
238 "%Go into an infinite loop and run the crontab command.\n"
239 "%Syntax: \\run.cron{}\n"
240 "%\n"
241 "%Note that only cron functions from the highest global level\n"
242 "%where a cron function is defined is run. Hence you may redefine\n"
243 "%earlier crontabs, but cannot mix between levels.\n"
244 "%\n"
245 "%You can only have one crontab of a certain interval.\n"
246 "%\n"
247 "%Produces no output.\n"
248 );
249}