// inner function for swfdec_as_array_sort_compare static int swfdec_as_array_sort_compare_values (SwfdecAsContext *cx, const SwfdecAsValue *a, const SwfdecAsValue *b, SortOption options, SwfdecAsFunction *custom_function) { int retval; g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (cx), 0); g_return_val_if_fail (SWFDEC_IS_AS_VALUE (a), 0); g_return_val_if_fail (SWFDEC_IS_AS_VALUE (b), 0); g_return_val_if_fail (custom_function == NULL || SWFDEC_IS_AS_FUNCTION (custom_function), 0); if (custom_function != NULL) { SwfdecAsValue argv[2] = { *a, *b }; SwfdecAsValue ret; SwfdecAsContext *context = swfdec_gc_object_get_context (custom_function); swfdec_as_function_call (custom_function, NULL, 2, argv, &ret); retval = swfdec_as_value_to_integer (context, &ret); } else if (options & SORT_OPTION_NUMERIC && (SWFDEC_AS_VALUE_IS_NUMBER (a) || SWFDEC_AS_VALUE_IS_NUMBER (b)) && !SWFDEC_AS_VALUE_IS_UNDEFINED (a) && !SWFDEC_AS_VALUE_IS_UNDEFINED (b)) { if (!SWFDEC_AS_VALUE_IS_NUMBER (a)) { retval = 1; } else if (!SWFDEC_AS_VALUE_IS_NUMBER (b)) { retval = -1; } else { double an = swfdec_as_value_to_number (cx, a); double bn = swfdec_as_value_to_number (cx, b); retval = (an < bn ? -1 : (an > bn ? 1 : 0)); } } else { // can't pass swfdec_as_value_to_string calls directly to compare // functions, since the order of these is important const char *a_str = swfdec_as_value_to_string (cx, a); const char *b_str = swfdec_as_value_to_string (cx, b); if (options & SORT_OPTION_CASEINSENSITIVE) { retval = g_strcasecmp (a_str, b_str); } else { retval = strcmp (a_str, b_str); } } if (options & SORT_OPTION_DESCENDING) retval = -retval; return retval; }
void broadcastMessage (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { SwfdecAsValue val; SwfdecAsObject *listeners, *o; gint i, length; const char *name; GSList *list = NULL, *walk; if (object == NULL) return; if (argc < 1) return; name = swfdec_as_value_to_string (cx, argv[0]); argv += 1; argc--; swfdec_as_object_get_variable (object, SWFDEC_AS_STR__listeners, &val); if (!SWFDEC_AS_VALUE_IS_COMPOSITE (val)) return; listeners = SWFDEC_AS_VALUE_GET_COMPOSITE (val); swfdec_as_object_get_variable (listeners, SWFDEC_AS_STR_length, &val); length = swfdec_as_value_to_integer (cx, val); /* return undefined if we won't try to call anything */ if (length <= 0) return; /* FIXME: solve this wth foreach, so it gets faster for weird cases */ for (i = 0; i < length; i++) { swfdec_as_object_get_variable (listeners, swfdec_as_integer_to_string (cx, i), &val); o = swfdec_as_value_to_object (cx, val); if (o == NULL) continue; list = g_slist_prepend (list, o); } if (list == NULL) return; list = g_slist_reverse (list); for (walk = list; walk; walk = walk->next) { swfdec_as_object_call (walk->data, name, argc, argv, &val); } g_slist_free (list); SWFDEC_AS_VALUE_SET_BOOLEAN (ret, TRUE); }
void swfdec_as_array_join (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { int i; const char *var, *str, *sep; SwfdecAsValue val; if (object == NULL || SWFDEC_IS_MOVIE (object)) return; if (argc > 0) { sep = swfdec_as_value_to_string (cx, &argv[0]); } else { sep = SWFDEC_AS_STR_COMMA; } // note: we don't cache length if (swfdec_as_array_length (object) > 0) { GString *string; swfdec_as_object_get_variable (object, SWFDEC_AS_STR_0, &val); str = swfdec_as_value_to_string (cx, &val); string = g_string_new (str); for (i = 1; i < swfdec_as_array_length (object); i++) { var = swfdec_as_integer_to_string (cx, i); swfdec_as_object_get_variable (object, var, &val); var = swfdec_as_value_to_string (cx, &val); g_string_append (string, sep); g_string_append (string, var); } str = swfdec_as_context_give_string (cx, g_string_free (string, FALSE)); } else { str = SWFDEC_AS_STR_EMPTY; } SWFDEC_AS_VALUE_SET_STRING (ret, str); }
void swfdec_as_array_sortOn (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { const char **fields; SortOption *options; gint32 i, num_fields; SwfdecAsObject *array; SwfdecAsValue val; if (object == NULL || SWFDEC_IS_MOVIE (object)) return; if (argc < 1) return; if (SWFDEC_AS_VALUE_IS_OBJECT (&argv[0])) { array = SWFDEC_AS_VALUE_GET_OBJECT (&argv[0]); if (!SWFDEC_IS_AS_ARRAY (array)) { SWFDEC_AS_VALUE_SET_OBJECT (ret, object); return; } num_fields = swfdec_as_array_get_length (SWFDEC_AS_ARRAY (array)); if (num_fields <= 0) { SWFDEC_AS_VALUE_SET_OBJECT (ret, object); return; } fields = g_new (const char *, num_fields + 1); for (i = 0; i < num_fields; i++) { swfdec_as_array_get_value (SWFDEC_AS_ARRAY (array), i, &val); if (SWFDEC_AS_VALUE_IS_OBJECT (&val) && SWFDEC_IS_AS_STRING (SWFDEC_AS_VALUE_GET_OBJECT (&val))) { fields[i] = SWFDEC_AS_STRING (SWFDEC_AS_VALUE_GET_OBJECT (&val))->string; } else { fields[i] = swfdec_as_value_to_string (cx, &val); } } fields[i] = NULL; } else {
/** * swfdec_as_native_function_checkv: * @cx: a #SwfdecAsContext * @object: this object passed to the native function * @type: expected type of @object * @result: pointer to variable taking cast result of @object * @argc: count of arguments passed to the function * @argv: arguments passed to the function * @args: argument conversion string * @varargs: pointers to variables taking converted arguments * * This is the valist version of swfdec_as_native_function_check(). See that * function for details. * * Returns: %TRUE if the conversion succeeded, %FALSE otherwise **/ gboolean swfdec_as_native_function_checkv (SwfdecAsContext *cx, SwfdecAsObject *object, GType type, gpointer *result, guint argc, SwfdecAsValue *argv, const char *args, va_list varargs) { guint i; gboolean optional = FALSE; g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (cx), FALSE); g_return_val_if_fail (type == 0 || result != NULL, FALSE); /* check that we got a valid type */ if (type) { if (G_TYPE_CHECK_INSTANCE_TYPE (object, type)) { *result = object; } else if (object && G_TYPE_CHECK_INSTANCE_TYPE (object->relay, type)) { *result = object->relay; } else { return FALSE; } } for (i = 0; *args && i < argc; i++, args++) { switch (*args) { case 'v': { SwfdecAsValue *val = va_arg (varargs, SwfdecAsValue *); *val = argv[i]; } break; case 'b': { gboolean *b = va_arg (varargs, gboolean *); *b = swfdec_as_value_to_boolean (cx, argv[i]); } break; case 'i': { int *j = va_arg (varargs, int *); *j = swfdec_as_value_to_integer (cx, argv[i]); } break; case 'm': case 'M': { SwfdecMovie *m; SwfdecMovie **arg = va_arg (varargs, SwfdecMovie **); if (SWFDEC_AS_VALUE_IS_MOVIE (argv[i])) { m = SWFDEC_AS_VALUE_GET_MOVIE (argv[i]); } else { m = NULL; } if (m == NULL && *args != 'M') return FALSE; *arg = m; } break; case 'n': { double *d = va_arg (varargs, double *); *d = swfdec_as_value_to_number (cx, argv[i]); } break; case 's': { const char **s = va_arg (varargs, const char **); *s = swfdec_as_value_to_string (cx, argv[i]); } break; case 'o': case 'O': { SwfdecAsObject **o = va_arg (varargs, SwfdecAsObject **); *o = swfdec_as_value_to_object (cx, argv[i]); if (*o == NULL && *args != 'O') return FALSE; } break; case '|': g_return_val_if_fail (optional == FALSE, FALSE); optional = TRUE; i--; break; default: g_warning ("'%c' is not a valid type conversion", *args); return FALSE; } } if (*args && !optional && *args != '|') return FALSE; return TRUE; }
int main (int argc, char **argv) { char *script_filename = NULL; GError *error = NULL; SwfdecAsContext *context; SwfdecAsObject *array; SwfdecScript *script; SwfdecAsValue val; int i, ret; gboolean dump = FALSE; gboolean no_check = FALSE, only_check = FALSE; GOptionEntry options[] = { { "dump", 'd', 0, G_OPTION_ARG_NONE, &dump, "dump informative output on failure", FALSE }, { "no-check", 0, 0, G_OPTION_ARG_NONE, &no_check, "don't check if the system is ok for running the testsuite", FALSE }, { "self-check", 0, 0, G_OPTION_ARG_NONE, &only_check, "run a system check and exit", FALSE }, { "player", 'p', 0, G_OPTION_ARG_STRING, &swfdec_test_plugin_name, "player to test", "NAME" }, { "script", 's', 0, G_OPTION_ARG_STRING, &script_filename, "script to execute if not ./default.sts", "FILENAME" }, { NULL } }; GOptionContext *ctx; /* set the right warning levels */ g_log_set_always_fatal (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING); /* by default get rid of the loads of warnings the tests produce */ g_setenv ("SWFDEC_DEBUG", "2", FALSE); g_thread_init (NULL); swfdec_init (); ctx = g_option_context_new (""); g_option_context_add_main_entries (ctx, options, "options"); g_option_context_parse (ctx, &argc, &argv, &error); g_option_context_free (ctx); if (error) { g_printerr ("ERROR: wrong command line arguments: %s\n", error->message); g_error_free (error); return EXIT_FAILURE; } if (only_check || !no_check) { gboolean result = check_system (only_check); if (!result) { g_print ("ERROR: System checked failed, aborting. Use --no-check to disable.\n"); return 1; } else if (only_check) { return 0; } } g_assert (!only_check); /* allow env vars instead of options - eases running make check with different settings */ if (swfdec_test_plugin_name == NULL) swfdec_test_plugin_name = g_strdup (g_getenv ("SWFDEC_TEST_PLAYER")); script = load_script (script_filename); g_free (script_filename); if (script == NULL) return EXIT_FAILURE; context = g_object_new (SWFDEC_TYPE_AS_CONTEXT, NULL); swfdec_as_context_startup (context); SWFDEC_AS_VALUE_SET_BOOLEAN (&val, dump); swfdec_as_object_set_variable (context->global, swfdec_as_context_get_string (context, "dump"), &val); swfdec_test_function_init_context (context); swfdec_as_context_run_init_script (context, swfdec_test_initialize, sizeof (swfdec_test_initialize), SWFDEC_TEST_VERSION); array = swfdec_as_array_new (context); if (array == NULL) { g_print ("ERROR: Not enough memory"); return EXIT_FAILURE; } if (argc < 2) { GDir *dir; const char *file; dir = g_dir_open (".", 0, NULL); while ((file = g_dir_read_name (dir))) { if (!g_str_has_suffix (file, ".swf")) continue; SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_get_string (context, file)); swfdec_as_array_push (SWFDEC_AS_ARRAY (array), &val); } g_dir_close (dir); } else { for (i = 1; i < argc; i++) { SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_get_string (context, argv[i])); swfdec_as_array_push (SWFDEC_AS_ARRAY (array), &val); } } SWFDEC_AS_VALUE_SET_OBJECT (&val, array); swfdec_as_object_set_variable (context->global, swfdec_as_context_get_string (context, "filenames"), &val); swfdec_as_object_run (context->global, script); if (swfdec_as_context_catch (context, &val)) { g_print ("ERROR: %s\n", swfdec_as_value_to_string (context, &val)); ret = EXIT_FAILURE; } else { g_print ("SUCCESS\n"); ret = EXIT_SUCCESS; } swfdec_script_unref (script); g_object_unref (context); return ret; }