1 /*
2 	rua_script.c
3 
4 	Script api for ruamoko
5 
6 	Copyright (C) 2004 Bill Currie
7 
8 	Author: Bill Currie
9 	Date: 2002/11/11
10 
11 	This program is free software; you can redistribute it and/or
12 	modify it under the terms of the GNU General Public License
13 	as published by the Free Software Foundation; either version 2
14 	of the License, or (at your option) any later version.
15 
16 	This program is distributed in the hope that it will be useful,
17 	but WITHOUT ANY WARRANTY; without even the implied warranty of
18 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 
20 	See the GNU General Public License for more details.
21 
22 	You should have received a copy of the GNU General Public License
23 	along with this program; if not, write to:
24 
25 		Free Software Foundation, Inc.
26 		59 Temple Place - Suite 330
27 		Boston, MA  02111-1307, USA
28 
29 */
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33 
34 #include <stdlib.h>
35 #ifdef HAVE_STRING_H
36 # include <string.h>
37 #endif
38 #ifdef HAVE_STRINGS_H
39 # include <strings.h>
40 #endif
41 
42 #include "QF/progs.h"
43 #include "QF/script.h"
44 
45 #include "rua_internal.h"
46 
47 typedef struct {
48 	script_t    script;
49 	string_t    dstr;
50 	progs_t    *pr;
51 	string_t    err_msg;
52 } rua_script_t;
53 
54 typedef struct {
55 	PR_RESMAP(rua_script_t) scripts;
56 } script_resources_t;
57 
58 static rua_script_t *
script_new(script_resources_t * res)59 script_new (script_resources_t *res)
60 {
61 	PR_RESNEW (rua_script_t, res->scripts);
62 }
63 
64 static void
script_free(script_resources_t * res,rua_script_t * script)65 script_free (script_resources_t *res, rua_script_t *script)
66 {
67 	PR_RESFREE (rua_script_t, res->scripts, script);
68 }
69 
70 static void
script_reset(script_resources_t * res)71 script_reset (script_resources_t *res)
72 {
73 	PR_RESRESET (rua_script_t, res->scripts);
74 }
75 
76 static inline rua_script_t *
script_get(script_resources_t * res,int index)77 script_get (script_resources_t *res, int index)
78 {
79 	PR_RESGET(res->scripts, index);
80 }
81 
82 static inline int
script_index(script_resources_t * res,rua_script_t * script)83 script_index (script_resources_t *res, rua_script_t *script)
84 {
85 	PR_RESINDEX(res->scripts, script);
86 }
87 
88 static void
bi_script_clear(progs_t * pr,void * data)89 bi_script_clear (progs_t *pr, void *data)
90 {
91 	script_resources_t *res = (script_resources_t *) data;
92 	script_reset (res);
93 }
94 
95 static void
bi_script_error(script_t * _script,const char * msg)96 bi_script_error (script_t *_script, const char *msg)
97 {
98 	rua_script_t *script = (rua_script_t *)_script;
99 	script->err_msg = PR_SetString (script->pr, msg);
100 }
101 
102 static void
bi_Script_New(progs_t * pr)103 bi_Script_New (progs_t *pr)
104 {
105 	script_resources_t *res = PR_Resources_Find (pr, "Script");
106 	rua_script_t *script = script_new (res);
107 
108 	if (!script)
109 		PR_RunError (pr, "out of memory");
110 
111 	script->dstr = PR_NewMutableString (pr);
112 	script->script.token = PR_GetMutableString (pr, script->dstr);
113 	script->script.error = bi_script_error;
114 	script->pr = pr;
115 	R_INT (pr) = script_index (res, script);
116 }
117 
118 static void
bi_Script_Delete(progs_t * pr)119 bi_Script_Delete (progs_t *pr)
120 {
121 	script_resources_t *res = PR_Resources_Find (pr, "Script");
122 	rua_script_t *script = script_get (res, P_INT (pr, 0));
123 
124 	if (!script)
125 		PR_RunError (pr, "invalid script handle");
126 	PR_FreeString (pr, script->dstr);
127 	script_free (res, script);
128 }
129 
130 static void
bi_Script_Start(progs_t * pr)131 bi_Script_Start (progs_t *pr)
132 {
133 	script_resources_t *res = PR_Resources_Find (pr, "Script");
134 	rua_script_t *script = script_get (res, P_INT (pr, 0));
135 
136 	if (!script)
137 		PR_RunError (pr, "invalid script handle");
138 	Script_Start (&script->script, P_GSTRING (pr, 1), P_GSTRING (pr, 2));
139 	R_STRING (pr) = script->dstr;
140 }
141 
142 static void
bi_Script_TokenAvailable(progs_t * pr)143 bi_Script_TokenAvailable (progs_t *pr)
144 {
145 	script_resources_t *res = PR_Resources_Find (pr, "Script");
146 	rua_script_t *script = script_get (res, P_INT (pr, 0));
147 
148 	if (!script)
149 		PR_RunError (pr, "invalid script handle");
150 	R_INT (pr) = Script_TokenAvailable (&script->script, P_INT (pr, 1));
151 }
152 
153 static void
bi_Script_GetToken(progs_t * pr)154 bi_Script_GetToken (progs_t *pr)
155 {
156 	script_resources_t *res = PR_Resources_Find (pr, "Script");
157 	rua_script_t *script = script_get (res, P_INT (pr, 0));
158 
159 	if (!script)
160 		PR_RunError (pr, "invalid script handle");
161 	R_INT (pr) = Script_GetToken (&script->script, P_INT (pr, 1));
162 }
163 
164 static void
bi_Script_UngetToken(progs_t * pr)165 bi_Script_UngetToken (progs_t *pr)
166 {
167 	script_resources_t *res = PR_Resources_Find (pr, "Script");
168 	rua_script_t *script = script_get (res, P_INT (pr, 0));
169 
170 	if (!script)
171 		PR_RunError (pr, "invalid script handle");
172 	Script_UngetToken (&script->script);
173 }
174 
175 static void
bi_Script_Error(progs_t * pr)176 bi_Script_Error (progs_t *pr)
177 {
178 	script_resources_t *res = PR_Resources_Find (pr, "Script");
179 	rua_script_t *script = script_get (res, P_INT (pr, 0));
180 
181 	if (!script)
182 		PR_RunError (pr, "invalid script handle");
183 	R_STRING (pr) = script->err_msg;
184 	script->err_msg = 0;
185 }
186 
187 static void
bi_Script_NoQuoteLines(progs_t * pr)188 bi_Script_NoQuoteLines (progs_t *pr)
189 {
190 	script_resources_t *res = PR_Resources_Find (pr, "Script");
191 	rua_script_t *script = script_get (res, P_INT (pr, 0));
192 
193 	if (!script)
194 		PR_RunError (pr, "invalid script handle");
195 	R_INT (pr) = script->script.no_quote_lines;
196 	script->script.no_quote_lines = P_INT (pr, 1);
197 }
198 
199 static builtin_t builtins[] = {
200 	{"Script_New",				bi_Script_New,				-1},
201 	{"Script_Delete",			bi_Script_Delete,			-1},
202 	{"Script_Start",			bi_Script_Start,			-1},
203 	{"Script_TokenAvailable",	bi_Script_TokenAvailable,	-1},
204 	{"Script_GetToken",			bi_Script_GetToken,			-1},
205 	{"Script_UngetToken",		bi_Script_UngetToken,		-1},
206 	{"Script_Error",			bi_Script_Error,			-1},
207 	{"Script_NoQuoteLines",		bi_Script_NoQuoteLines,		-1},
208 	{0}
209 };
210 
211 void
RUA_Script_Init(progs_t * pr,int secure)212 RUA_Script_Init (progs_t *pr, int secure)
213 {
214 	script_resources_t *res = calloc (1, sizeof (script_resources_t));
215 
216 	PR_Resources_Register (pr, "Script", res, bi_script_clear);
217 
218 	PR_RegisterBuiltins (pr, builtins);
219 }
220