An even more compact mpsl_exec_i().
[mpsl.git] / mpsl_f.c
blob70a42c6320942e4a5b0f15b4dee3d3bed8f6c6b3
1 /*
3 MPSL - Minimum Profit Scripting Language
4 Copyright (C) 2003/2007 Angel Ortega <angel@triptico.com>
6 mpsl_f.c - Minimum Profit Scripting Language Function Library
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 http://www.triptico.com
26 #include "config.h"
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <wchar.h>
32 #include <time.h>
34 #include "mpdm.h"
35 #include "mpsl.h"
37 /*******************
38 Data
39 ********************/
41 /*******************
42 Code
43 ********************/
45 #define A(n) mpdm_aget(a, n)
46 #define A0 A(0)
47 #define A1 A(1)
48 #define A2 A(2)
49 #define IA(n) mpdm_ival(A(n))
50 #define IA0 IA(0)
51 #define IA1 IA(1)
52 #define IA2 IA(2)
53 #define IA3 IA(3)
54 #define RA(n) mpdm_rval(A(n))
55 #define RA0 RA(0)
56 #define RA1 RA(1)
57 #define RA2 RA(2)
58 #define RA3 RA(3)
60 static mpdm_t F_size(mpdm_t a) { return MPDM_I(mpdm_size(A0)); }
61 static mpdm_t F_clone(mpdm_t a) { return mpdm_clone(A0); }
62 static mpdm_t F_dump(mpdm_t a) { mpdm_dump(A0); return NULL; }
63 static mpdm_t F_dumper(mpdm_t a) { return mpdm_dumper(A0); }
64 static mpdm_t F_cmp(mpdm_t a) { return MPDM_I(mpdm_cmp(A0, A1)); }
66 static mpdm_t F_is_array(mpdm_t a) { return mpsl_boolean(MPDM_IS_ARRAY(A0)); }
67 static mpdm_t F_is_hash(mpdm_t a) { return mpsl_boolean(MPDM_IS_HASH(A0)); }
68 static mpdm_t F_is_exec(mpdm_t a) { return mpsl_boolean(MPDM_IS_EXEC(A0)); }
70 static mpdm_t F_splice(mpdm_t a) { return mpdm_splice(A0,A1,IA2,IA3); }
71 static mpdm_t F_expand(mpdm_t a) { return mpdm_expand(A0,IA1,IA2); }
72 static mpdm_t F_collapse(mpdm_t a) { return mpdm_collapse(A0,IA1,IA2); }
73 static mpdm_t F_ins(mpdm_t a) { return mpdm_ins(A0,A1,IA2); }
74 static mpdm_t F_adel(mpdm_t a) { return mpdm_adel(A0,IA1); }
75 static mpdm_t F_shift(mpdm_t a) { return mpdm_shift(A0); }
76 static mpdm_t F_push(mpdm_t a) { return mpdm_push(A0,A1); }
77 static mpdm_t F_pop(mpdm_t a) { return mpdm_pop(A0); }
78 static mpdm_t F_queue(mpdm_t a) { return mpdm_queue(A0,A1,IA2); }
79 static mpdm_t F_seek(mpdm_t a) { return MPDM_I(mpdm_seek(A0,A1,IA2)); }
80 static mpdm_t F_sort(mpdm_t a) { return mpdm_sort_cb(A0,1,A1); }
81 static mpdm_t F_split(mpdm_t a) { return mpdm_split(A0,A1); }
82 static mpdm_t F_join(mpdm_t a) { return mpdm_join(A0,A1); }
84 static mpdm_t F_hsize(mpdm_t a) { return MPDM_I(mpdm_hsize(A0)); }
85 static mpdm_t F_exists(mpdm_t a) { return mpsl_boolean(mpdm_exists(A0, A1)); }
86 static mpdm_t F_hdel(mpdm_t a) { return mpdm_hdel(A0, A1); }
87 static mpdm_t F_keys(mpdm_t a) { return mpdm_keys(A0); }
89 static mpdm_t F_open(mpdm_t a) { return mpdm_open(A0, A1); }
90 static mpdm_t F_close(mpdm_t a) { return mpdm_close(A0); }
91 static mpdm_t F_read(mpdm_t a) { return mpdm_read(A0); }
92 static mpdm_t F_write(mpdm_t a) { return MPDM_I(mpdm_write(A0,A1)); }
93 static mpdm_t F_getchar(mpdm_t a) { return mpdm_getchar(A0); }
94 static mpdm_t F_putchar(mpdm_t a) { return mpdm_putchar(A0, A1); }
95 static mpdm_t F_fseek(mpdm_t a) { return MPDM_I(mpdm_fseek(A0, IA1, IA2)); }
96 static mpdm_t F_ftell(mpdm_t a) { return MPDM_I(mpdm_ftell(A0)); }
98 static mpdm_t F_unlink(mpdm_t a) { return mpsl_boolean(mpdm_unlink(A0)); }
99 static mpdm_t F_stat(mpdm_t a) { return mpdm_stat(A0); }
100 static mpdm_t F_chmod(mpdm_t a) { return MPDM_I(mpdm_chmod(A0,A1)); }
101 static mpdm_t F_chown(mpdm_t a) { return MPDM_I(mpdm_chown(A0,A1,A2)); }
102 static mpdm_t F_glob(mpdm_t a) { return mpdm_glob(A0); }
103 static mpdm_t F_encoding(mpdm_t a) { return MPDM_I(mpdm_encoding(A0)); }
104 static mpdm_t F_popen(mpdm_t a) { return mpdm_popen(A0, A1); }
105 static mpdm_t F_pclose(mpdm_t a) { return mpdm_pclose(A0); }
107 static mpdm_t F_regex(mpdm_t a) { return mpdm_regex(A0,A1,IA2); }
108 static mpdm_t F_sregex(mpdm_t a) { return mpdm_sregex(A0,A1,A2,IA3); }
110 static mpdm_t F_gettext(mpdm_t a) { return mpdm_gettext(A0); }
111 static mpdm_t F_gettext_domain(mpdm_t a) { return MPDM_I(mpdm_gettext_domain(A0, A1)); }
113 static mpdm_t F_load(mpdm_t a) { return mpdm_exec(mpsl_compile_file(A0), NULL); }
114 static mpdm_t F_error(mpdm_t a) { return mpsl_error(A0); }
115 static mpdm_t F_sweep(mpdm_t a) { mpdm_sweep(IA0); return NULL; }
117 static mpdm_t F_uc(mpdm_t a) { return mpdm_ulc(A0, 1); }
118 static mpdm_t F_lc(mpdm_t a) { return mpdm_ulc(A0, 0); }
120 static mpdm_t F_time(mpdm_t a) { return MPDM_I(time(NULL)); }
122 static mpdm_t F_eval(mpdm_t a)
124 mpdm_t c;
126 a = mpdm_clone(a);
127 c = mpdm_adel(a, 0);
129 return mpsl_eval(c, a);
132 static mpdm_t F_sprintf(mpdm_t a)
134 mpdm_t f;
135 mpdm_t v;
137 a = mpdm_clone(a);
138 f = mpdm_adel(a, 0);
140 /* if the first argument is an array, take it as the arguments */
141 if ((v = mpdm_aget(a, 0)) != NULL && MPDM_IS_ARRAY(v))
142 a = v;
144 return mpdm_sprintf(f, a);
148 static mpdm_t F_print(mpdm_t a)
150 int n;
152 for (n = 0; n < mpdm_size(a); n++)
153 mpdm_write_wcs(stdout, mpdm_string(A(n)));
154 return NULL;
158 static mpdm_t F_chr(mpdm_t a)
160 wchar_t tmp[2];
162 tmp[0] = (wchar_t) mpdm_ival(mpdm_aget(a, 0));
163 tmp[1] = L'\0';
165 return MPDM_S(tmp);
169 static mpdm_t F_ord(mpdm_t a)
171 int ret = 0;
172 mpdm_t v = mpdm_aget(a, 0);
174 if (v != NULL) {
175 wchar_t * ptr = mpdm_string(v);
176 ret = (int) *ptr;
179 return MPDM_I(ret);
183 static mpdm_t F_map(mpdm_t a)
185 mpdm_t key = mpdm_aget(a, 0);
186 mpdm_t set = mpdm_aget(a, 1);
187 mpdm_t out;
189 /* map NULL to NULL */
190 if (set == NULL)
191 return NULL;
193 out = mpdm_ref(MPDM_A(mpdm_size(set)));
195 if (MPDM_IS_EXEC(key)) {
196 int n;
198 /* executes the code using the element as argument
199 and stores the result in the output array */
200 for (n = 0; n < mpdm_size(set); n++)
201 mpdm_aset(out, mpdm_exec_1(key, mpdm_aget(set, n)), n);
203 else
204 if(MPDM_IS_HASH(key)) {
205 int n;
207 /* maps each value using the element as key */
208 for (n = 0; n < mpdm_size(set); n++)
209 mpdm_aset(out, mpdm_hget(key, mpdm_aget(set, n)), n);
212 return mpdm_unref(out);
216 static mpdm_t F_grep(mpdm_t a)
218 mpdm_t key = mpdm_aget(a, 0);
219 mpdm_t set = mpdm_aget(a, 1);
220 mpdm_t out = mpdm_ref(MPDM_A(0));
222 if (MPDM_IS_EXEC(key)) {
223 int n;
225 /* it's executable */
226 for (n = 0; n < mpdm_size(set); n++) {
227 mpdm_t v = mpdm_aget(set, n);
229 if (mpsl_is_true(mpdm_exec_1(key, v)))
230 mpdm_push(out, v);
233 else
234 if(key->flags & MPDM_STRING) {
235 int n;
237 /* it's a string; use it as a regular expression */
238 for (n = 0; n < mpdm_size(set); n++) {
239 mpdm_t v = mpdm_aget(set, n);
241 if (mpdm_regex(key, v, 0))
242 mpdm_push(out, v);
246 return mpdm_size(mpdm_unref(out)) == 0 ? NULL : out;
249 static mpdm_t F_getenv(mpdm_t a)
251 char * ptr = mpdm_wcstombs(mpdm_string(mpdm_aget(a, 0)), NULL);
253 if (ptr != NULL)
254 ptr = getenv(ptr);
256 return ptr == NULL ? NULL : MPDM_MBS(ptr);
260 static struct {
261 wchar_t * name;
262 mpdm_t (* func)(mpdm_t);
263 } mpsl_funcs[] = {
264 { L"size", F_size },
265 { L"clone", F_clone },
266 { L"dump", F_dump },
267 { L"dumper", F_dumper },
268 { L"cmp", F_cmp },
269 { L"is_array", F_is_array },
270 { L"is_hash", F_is_hash },
271 { L"is_exec", F_is_exec },
272 { L"splice", F_splice },
273 { L"expand", F_expand },
274 { L"collapse", F_collapse },
275 { L"ins", F_ins },
276 { L"adel", F_adel },
277 { L"shift", F_shift },
278 { L"push", F_push },
279 { L"pop", F_pop },
280 { L"queue", F_queue },
281 { L"seek", F_seek },
282 { L"sort", F_sort },
283 { L"split", F_split },
284 { L"join", F_join },
285 { L"hsize", F_hsize },
286 { L"exists", F_exists },
287 { L"hdel", F_hdel },
288 { L"keys", F_keys },
289 { L"open", F_open },
290 { L"close", F_close },
291 { L"read", F_read },
292 { L"write", F_write },
293 { L"getchar", F_getchar },
294 { L"putchar", F_putchar },
295 { L"fseek", F_fseek },
296 { L"ftell", F_ftell },
297 { L"unlink", F_unlink },
298 { L"stat", F_stat },
299 { L"chmod", F_chmod },
300 { L"chown", F_chown },
301 { L"glob", F_glob },
302 { L"encoding", F_encoding },
303 { L"popen", F_popen },
304 { L"pclose", F_pclose },
305 { L"regex", F_regex },
306 { L"sregex", F_sregex },
307 { L"load", F_load },
308 { L"error", F_error },
309 { L"eval", F_eval },
310 { L"print", F_print },
311 { L"gettext", F_gettext },
312 { L"gettext_domain", F_gettext_domain },
313 { L"sprintf", F_sprintf },
314 { L"sweep", F_sweep },
315 { L"chr", F_chr },
316 { L"ord", F_ord },
317 { L"map", F_map },
318 { L"grep", F_grep },
319 { L"getenv", F_getenv },
320 { L"uc", F_uc },
321 { L"lc", F_lc },
322 { L"time", F_time },
323 { NULL, NULL }
328 * mpsl_argv - Fills the ARGV global array.
329 * @argc: number of arguments
330 * @argv: array of string values
332 * Fills the ARGV global MPSL array with an array of arguments. These
333 * are usually the ones sent to main().
335 void mpsl_argv(int argc, char * argv[])
337 int n;
338 mpdm_t ARGV;
340 /* create the ARGV array */
341 ARGV = MPDM_A(0);
343 for (n = 0; n < argc; n++)
344 mpdm_push(ARGV, MPDM_MBS(argv[n]));
346 mpdm_hset_s(mpdm_root(), L"ARGV", ARGV);
350 /* in mpsl_c.c */
351 mpdm_t mpsl_build_opcodes(void);
355 * mpsl_startup - Initializes MPSL.
357 * Initializes the Minimum Profit Scripting Language. Returns 0 if
358 * everything went OK.
360 int mpsl_startup(void)
362 int n;
363 mpdm_t r;
364 mpdm_t m;
365 mpdm_t c;
367 /* startup MPDM */
368 mpdm_startup();
370 r = mpdm_root();
372 /* creates all the symbols in the CORE library */
373 c = MPDM_H(0);
374 for (n = 0; mpsl_funcs[n].name != NULL; n++) {
375 mpdm_t f = MPDM_S(mpsl_funcs[n].name);
376 mpdm_t x = MPDM_X(mpsl_funcs[n].func);
378 mpdm_hset(r, f, x);
379 mpdm_hset(c, f, x);
382 /* creates INC, unless already defined */
383 if (mpdm_hget_s(r, L"INC") == NULL)
384 mpdm_hset_s(r, L"INC", MPDM_A(0));
386 /* the TRUE value */
387 mpdm_hset_s(r, L"TRUE", MPDM_I(1));
389 /* standard file descriptors */
390 mpdm_hset_s(r, L"STDIN", MPDM_F(stdin));
391 mpdm_hset_s(r, L"STDOUT", MPDM_F(stdout));
392 mpdm_hset_s(r, L"STDERR", MPDM_F(stderr));
394 /* home and application directories */
395 mpdm_hset_s(r, L"HOMEDIR", mpdm_home_dir());
396 mpdm_hset_s(r, L"APPDIR", mpdm_app_dir());
398 /* fill now the MPSL hash */
399 m = MPDM_H(0);
400 mpdm_hset_s(r, L"MPSL", m);
402 /* store things there */
403 mpdm_hset_s(m, L"VERSION", MPDM_MBS(VERSION));
404 mpdm_hset_s(m, L"OPCODE", mpsl_build_opcodes());
405 mpdm_hset_s(m, L"LC", MPDM_H(0));
406 mpdm_hset_s(m, L"CORE", c);
408 return 0;
413 * mpsl_shutdown - Shuts down MPSL.
415 * Shuts down MPSL. No MPSL functions should be used from now on.
417 void mpsl_shutdown(void)
419 mpdm_shutdown();