1 /* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */
4 * This file is part of Seed, the GObject Introspection<->Javascript bindings.
6 * Seed is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation, either version 3 of
9 * the License, or (at your option) any later version.
10 * Seed 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 Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with Seed. If not, see <http://www.gnu.org/licenses/>.
17 * Copyright (C) Robert Carr 2009 <carrr@rpi.edu>
21 #include "seed-private.h"
26 JSValueRef seed_print_ref;
29 seed_include (JSContextRef ctx,
31 JSObjectRef this_object,
33 const JSValueRef arguments[], JSValueRef * exception)
35 JSStringRef file_contents, file_name;
38 gchar *import_file, *abs_path;
42 if (argumentCount != 1)
44 seed_make_exception (ctx, exception, "ArgumentError",
45 "Seed.include expected 1 argument, "
46 "got %zd", argumentCount);
47 return JSValueMakeNull (ctx);
50 import_file = seed_value_to_string (ctx, arguments[0], exception);
52 /* just try current dir if no path set, or use the absolute path */
53 if (!eng->search_path || g_path_is_absolute (import_file))
54 g_file_get_contents (import_file, &buffer, 0, NULL);
55 else /* A search path is set and path given is not absolute. */
57 len = g_strv_length (eng->search_path);
58 for (i = 0; i < len; ++i)
60 dir = g_dir_open (eng->search_path[i], 0, NULL);
62 if (!dir) /* skip bad path entries */
66 g_build_filename (eng->search_path[i], import_file, NULL);
68 if (g_file_get_contents (abs_path, &buffer, 0, NULL))
82 seed_make_exception (ctx, exception, "FileNotFound",
83 "File not found: %s", import_file);
87 return JSValueMakeNull (ctx);
99 walk = g_strdup (walk);
102 file_contents = JSStringCreateWithUTF8CString (walk);
103 file_name = JSStringCreateWithUTF8CString (import_file);
105 JSEvaluateScript (ctx, file_contents, NULL, file_name, 0, exception);
107 JSStringRelease (file_contents);
108 JSStringRelease (file_name);
109 g_free (import_file);
112 return JSValueMakeUndefined (ctx);
116 seed_scoped_include (JSContextRef ctx,
117 JSObjectRef function,
118 JSObjectRef this_object,
119 size_t argumentCount,
120 const JSValueRef arguments[], JSValueRef * exception)
124 JSStringRef file_contents, file_name;
126 gchar *import_file, *abs_path;
127 gchar *buffer, *walk;
130 if (argumentCount != 1)
132 seed_make_exception (ctx, exception, "ArgumentError",
133 "Seed.include expected 1 argument, "
134 "got %zd", argumentCount);
135 return JSValueMakeNull (ctx);
138 import_file = seed_value_to_string (ctx, arguments[0], exception);
140 /* just try current dir if no path set, or use the absolute path */
141 if (!eng->search_path || g_path_is_absolute (import_file))
142 g_file_get_contents (import_file, &buffer, 0, NULL);
143 else /* A search path is set and path given is not absolute. */
145 for (i = 0; i < g_strv_length (eng->search_path); ++i)
147 dir = g_dir_open (eng->search_path[i], 0, NULL);
149 if (!dir) /* skip bad path entries */
153 g_build_filename (eng->search_path[i], import_file, NULL);
155 if (g_file_get_contents (abs_path, &buffer, 0, NULL))
168 seed_make_exception (ctx, exception, "FileNotFound",
169 "File not found: %s", import_file);
171 g_free (import_file);
173 return JSValueMakeNull (ctx);
180 while (*walk != '\n')
185 walk = g_strdup (walk);
188 file_contents = JSStringCreateWithUTF8CString (walk);
189 file_name = JSStringCreateWithUTF8CString (import_file);
192 nctx = JSGlobalContextCreateInGroup (context_group, 0);
193 seed_prepare_global_context (nctx);
195 JSEvaluateScript (nctx, file_contents, NULL, file_name, 0, exception);
197 global = JSContextGetGlobalObject (nctx);
199 JSGlobalContextRelease ((JSGlobalContextRef) nctx);
201 JSStringRelease (file_contents);
202 JSStringRelease (file_name);
203 g_free (import_file);
210 seed_print (JSContextRef ctx,
211 JSObjectRef function,
212 JSObjectRef this_object,
213 size_t argumentCount,
214 const JSValueRef arguments[], JSValueRef * exception)
217 if (argumentCount != 1)
219 seed_make_exception (ctx, exception, "ArgumentError",
220 "print expected 1 argument, got %zd",
222 return JSValueMakeNull (ctx);
225 buf = seed_value_to_string (ctx, arguments[0], exception);
230 return JSValueMakeUndefined (ctx);
234 seed_g_type_name_to_string (GITypeInfo * type)
236 GITypeTag type_tag = g_type_info_get_tag (type);
238 const gchar *type_name;
239 GIBaseInfo *interface;
241 if (type_tag == GI_TYPE_TAG_INTERFACE)
243 interface = g_type_info_get_interface (type);
245 type_name = g_base_info_get_name (interface);
246 g_base_info_unref (interface);
250 type_name = g_type_tag_to_string (type_tag);
257 seed_introspect (JSContextRef ctx,
258 JSObjectRef function,
259 JSObjectRef this_object,
260 size_t argumentCount,
261 const JSValueRef arguments[], JSValueRef * exception)
265 GICallableInfo *info;
266 JSObjectRef data_obj, args_obj, argument;
269 if (argumentCount != 1)
271 seed_make_exception (ctx, exception, "ArgumentError",
272 "Seed.introspect expected 1 argument, "
273 "got %zd", argumentCount);
274 return JSValueMakeNull (ctx);
277 if (!JSValueIsObject (ctx, arguments[0]))
278 return JSValueMakeNull (ctx);
279 if (!JSValueIsObjectOfClass (ctx, arguments[0], gobject_method_class))
280 return JSValueMakeNull (ctx);
282 info = (GICallableInfo *) JSObjectGetPrivate ((JSObjectRef) arguments[0]);
283 data_obj = JSObjectMake (ctx, NULL, NULL);
285 seed_object_set_property (ctx, data_obj, "name", (JSValueRef)
286 seed_value_from_string (ctx, g_base_info_get_name
287 ((GIBaseInfo *) info),
290 seed_object_set_property (ctx, data_obj, "return_type",
291 seed_value_from_string
292 (ctx, seed_g_type_name_to_string
293 (g_callable_info_get_return_type (info)),
296 args_obj = JSObjectMake (ctx, NULL, NULL);
298 seed_object_set_property (ctx, data_obj, "args", args_obj);
300 nargs = g_callable_info_get_n_args (info);
301 for (i = 0; i < nargs; ++i)
303 argument = JSObjectMake (ctx, NULL, NULL);
305 const gchar *arg_name =
306 seed_g_type_name_to_string (g_arg_info_get_type
307 (g_callable_info_get_arg (info, i)));
309 seed_object_set_property (ctx, argument, "type",
310 seed_value_from_string (ctx,
311 arg_name, exception));
313 JSObjectSetPropertyAtIndex (ctx, args_obj, i, argument, NULL);
320 seed_check_syntax (JSContextRef ctx,
321 JSObjectRef function,
322 JSObjectRef this_object,
323 size_t argumentCount,
324 const JSValueRef arguments[], JSValueRef * exception)
327 if (argumentCount == 1)
329 jsstr = JSValueToStringCopy (ctx, arguments[0], exception);
331 JSCheckScriptSyntax (ctx, jsstr, 0, 0, exception);
333 JSStringRelease (jsstr);
337 seed_make_exception (ctx, exception, "ArgumentError",
338 "Seed.check_syntax expected "
339 "1 argument, got %zd", argumentCount);
341 return JSValueMakeNull (ctx);
345 seed_spawn (JSContextRef ctx,
346 JSObjectRef function,
347 JSObjectRef this_object,
348 size_t argumentCount,
349 const JSValueRef arguments[], JSValueRef * exception)
351 gchar *line, *stdoutstr, *stderrstr;
353 GError *error = NULL;
355 if (argumentCount != 1)
358 seed_make_exception (ctx, exception, "ArgumentError",
359 "Seed.spawn expected 1 argument");
360 return JSValueMakeNull (ctx);
363 line = seed_value_to_string (ctx, arguments[0], exception);
364 g_spawn_command_line_sync (line, &stdoutstr, &stderrstr, NULL, &error);
367 seed_make_exception_from_gerror (ctx, exception, error);
370 g_error_free (error);
371 return JSValueMakeNull (ctx);
374 ret = JSObjectMake (ctx, NULL, NULL);
375 seed_object_set_property (ctx, ret, "stdout",
376 seed_value_from_string (ctx, stdoutstr,
378 seed_object_set_property (ctx, ret, "stderr",
379 seed_value_from_string (ctx, stderrstr,
390 seed_quit (JSContextRef ctx,
391 JSObjectRef function,
392 JSObjectRef this_object,
393 size_t argumentCount,
394 const JSValueRef arguments[], JSValueRef * exception)
396 if (argumentCount == 1)
398 exit (seed_value_to_int (ctx, arguments[0], NULL));
400 else if (argumentCount > 1)
402 seed_make_exception (ctx, exception, "ArgumentError",
403 "Seed.quit expected " "1 argument, got %zd",
411 seed_breakpoint (JSContextRef ctx,
412 JSObjectRef function,
413 JSObjectRef this_object,
414 size_t argumentCount,
415 const JSValueRef arguments[], JSValueRef * exception)
418 return JSValueMakeUndefined (ctx);
423 seed_argv_get_property (JSContextRef ctx,
425 JSStringRef property_name, JSValueRef * exception)
427 SeedArgvPrivates *priv;
428 gchar *cproperty_name;
432 priv = JSObjectGetPrivate (object);
434 return JSValueMakeUndefined (ctx);
435 length = JSStringGetMaximumUTF8CStringSize (property_name);
436 cproperty_name = g_alloca (length * sizeof (gchar));
437 JSStringGetUTF8CString (property_name, cproperty_name, length);
439 if (!g_strcmp0 (cproperty_name, "length"))
441 return seed_value_from_int (ctx, priv->argc, exception);
443 index = atoi (cproperty_name);
444 return seed_value_from_string (ctx, priv->argv[index], exception);
447 JSClassDefinition seed_argv_def = {
448 0, /* Version, always 0 */
449 kJSClassAttributeNoAutomaticPrototype, /* JSClassAttributes */
450 "argv_array", /* Class Name */
451 NULL, /* Parent Class */
452 NULL, /* Static Values */
456 NULL, /* Has Property */
457 seed_argv_get_property, /* Get Property */
459 NULL, /* Delete Property */
460 NULL, /* Get Property Names */
461 NULL, /* Call As Function */
462 NULL, /* Call As Constructor */
463 NULL, /* Has Instance */
464 NULL /* Convert To Type */
467 JSClassRef seed_argv_class;
470 seed_init_builtins (SeedEngine * local_eng, gint * argc, gchar *** argv)
472 SeedArgvPrivates *priv;
473 JSObjectRef arrayObj;
475 (JSObjectRef) seed_object_get_property (local_eng->context,
479 seed_create_function (local_eng->context, "include", &seed_include, obj);
480 seed_create_function (local_eng->context, "scoped_include",
481 &seed_scoped_include, obj);
484 JSObjectMakeFunctionWithCallback (local_eng->context, NULL, &seed_print);
485 seed_object_set_property (local_eng->context, obj, "print", seed_print_ref);
486 seed_object_set_property (local_eng->context, local_eng->global, "print",
488 JSValueProtect (local_eng->context, seed_print_ref);
490 seed_create_function (local_eng->context,
491 "check_syntax", &seed_check_syntax, obj);
492 seed_create_function (local_eng->context,
493 "introspect", &seed_introspect, obj);
494 seed_create_function (local_eng->context, "spawn", &seed_spawn, obj);
495 seed_create_function (local_eng->context, "quit", &seed_quit, obj);
496 seed_create_function (local_eng->context, "breakpoint",
497 &seed_breakpoint, obj);
499 priv = g_new0 (SeedArgvPrivates, 1);
500 priv->argv = argv ? *argv : 0;
501 priv->argc = argc ? *argc : 0;
503 seed_argv_class = JSClassCreate (&seed_argv_def);
504 arrayObj = JSObjectMake (local_eng->context, seed_argv_class, priv);
506 seed_object_set_property (local_eng->context, obj, "argv", arrayObj);