⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trace.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
字号:
/* Swfdec * Copyright (C) 2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor,  * Boston, MA  02110-1301  USA */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <math.h>#include <stdlib.h>#include <string.h>#include <libswfdec/swfdec.h>#include "swfdec_interaction.h"typedef struct _Test Test;struct _Test {  char *	filename;		/* name of the file to be tested */  char *	output;			/* test result */  gboolean	success;		/* TRUE if test was successful, FALSE on error */  GMutex *	mutex;			/* NULL or mutex for protecting output */  GCond *	cond;			/* NULL or cond to signal after setting output */};static Test *test_new (char *filename){  Test *test;  test = g_slice_new0 (Test);  test->filename = filename;  return test;}static voidtest_free (Test *test){  g_free (test->filename);  g_free (test->output);  g_slice_free (Test, test);}static inttest_compare (gconstpointer a, gconstpointer b){  const Test *ta = (const Test *) a;  const Test *tb = (const Test *) b;  return strcmp (ta->filename, tb->filename);}static voidtrace_cb (SwfdecPlayer *player, const char *message, GString *string){  g_string_append_printf (string, "%s\n", message);}static voidfscommand_cb (SwfdecPlayer *player, const char *command, const char *parameter, gpointer data){  gboolean *quit = data;  if (g_str_equal (command, "quit")) {    *quit = TRUE;  }}static voidrun_test (gpointer testp, gpointer unused){  Test *test = testp;  SwfdecLoader *loader;  SwfdecPlayer *player;  SwfdecBuffer *buffer;  guint time_left;  char *str;  GString *string, *output;  GError *error = NULL;  gboolean quit = FALSE;  SwfdecInteraction *inter = NULL;  output = g_string_new ("");  g_string_append_printf (output, "Testing %s:\n", test->filename);  loader = swfdec_file_loader_new (test->filename);  if (loader->error) {    g_string_append_printf (output, "  ERROR: %s\n", loader->error);    goto fail;  }  string = g_string_new ("");  player = swfdec_player_new (NULL);  g_object_set (player, "memory-until-gc", (gulong) 0, NULL);  g_signal_connect (player, "trace", G_CALLBACK (trace_cb), string);  g_signal_connect (player, "fscommand", G_CALLBACK (fscommand_cb), &quit);  swfdec_player_set_loader (player, loader);  if (!swfdec_player_is_initialized (player)) {    g_string_append_printf (output, "  ERROR: player is not initialized\n");    g_object_unref (player);    goto fail;  }  str = g_strdup_printf ("%s.act", test->filename);  if (g_file_test (str, G_FILE_TEST_EXISTS)) {    inter = swfdec_interaction_new_from_file (str, &error);    if (inter == NULL) {      g_string_append_printf (output, "  ERROR: %s\n", error->message);      g_object_unref (player);      g_error_free (error);      g_free (str);      goto fail;    }    time_left = swfdec_interaction_get_duration (inter);  } else {    time_left = ceil (10000 / swfdec_player_get_rate (player));    inter = NULL;  }  g_free (str);  /* FIXME: Make the number of iterations configurable? */  while (quit == FALSE) {    /* FIXME: will not do 10 iterations if there's other stuff loaded */    guint advance = swfdec_player_get_next_event (player);    if (inter) {      int t = swfdec_interaction_get_next_event (inter);      g_assert (t >= 0);      advance = MIN (advance, (guint) t);    }    if (advance > time_left)      break;    swfdec_player_advance (player, advance);    time_left -= advance;    if (inter) {      swfdec_interaction_advance (inter, player, advance);      if (time_left == 0)	break;    }  }  g_signal_handlers_disconnect_by_func (player, trace_cb, string);  g_object_unref (player);  str = g_strdup_printf ("%s.trace", test->filename);  buffer = swfdec_buffer_new_from_file (str, &error);  if (buffer == NULL) {    g_string_append_printf (output, "  ERROR: %s\n", error->message);    g_error_free (error);    g_string_free (string, TRUE);    g_free (str);    goto fail;  }  if (string->len != buffer->length ||      memcmp (buffer->data, string->str, buffer->length) != 0) {    g_string_append (output, "  ERROR: unexpected trace output\n");    if (g_file_set_contents ("tmp", string->str, string->len, NULL)) {      const char *command[] = { "diff", "-u", str, "tmp", NULL };      char *result;      if (!g_spawn_sync (NULL, (char **) command, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,	  &result, NULL, NULL, &error)) {	g_string_append_printf (output, 	    "  ERROR: Could not spawn diff to compare the results: %s\n", 	    error->message);	g_error_free (error);      } else {	g_string_append (output, result);      }    }    g_string_free (string, TRUE);    swfdec_buffer_unref (buffer);    g_free (str);    goto fail;  }  g_free (str);  g_string_free (string, TRUE);  swfdec_buffer_unref (buffer);  g_string_append (output, "  OK\n");  test->success = TRUE;fail:  if (inter)    swfdec_interaction_free (inter);  if (test->mutex)    g_mutex_lock (test->mutex);  test->output = g_string_free (output, FALSE);  if (test->mutex) {    g_cond_signal (test->cond);    g_mutex_unlock (test->mutex);  }}intmain (int argc, char **argv){  GList *walk, *tests = NULL;  GString *failed_tests;  guint failures = 0;  GThreadPool *pool;  GError *error = NULL;  g_thread_init (NULL);  swfdec_init ();  failed_tests = g_string_new ("");  /* collect all tests into the tests list */  if (argc > 1) {    int i;    for (i = 1; i < argc; i++) {      tests = g_list_append (tests, test_new (g_strdup (argv[i])));    }  } else {    GDir *dir;    char *name;    const char *path, *file;    /* automake defines this */    path = g_getenv ("srcdir");    if (path == NULL)      path = ".";    dir = g_dir_open (path, 0, NULL);    while ((file = g_dir_read_name (dir))) {      if (!g_str_has_suffix (file, ".swf"))	continue;      name = g_build_filename (path, file, NULL);      tests = g_list_append (tests, test_new (name));    }    g_dir_close (dir);  }  /* sort the tests by filename */  tests = g_list_sort (tests, test_compare);  /* run them and put failed ones in failed_tests */  if (g_getenv ("SWFDEC_TEST_THREADS")) {    pool = g_thread_pool_new (run_test, NULL, -1, FALSE, &error);    if (pool == NULL) {      g_print ("  WARNING: Could not start thread pool: %s\n", error->message);      g_print ("  WARNING: testing unthreaded\n");      g_error_free (error);      error = NULL;    }  } else {    pool = NULL;  }  if (pool == NULL) {    for (walk = tests; walk; walk = walk->next) {      Test *test = walk->data;            run_test (test, NULL);      g_print ("%s", test->output);      if (!test->success) {	failures++;	g_string_append_printf (failed_tests, 	    "          %s\n", test->filename);      }      test_free (test);    }  } else {    GMutex *mutex = g_mutex_new ();    GCond *cond = g_cond_new ();    for (walk = tests; walk; walk = walk->next) {      Test *test = walk->data;      test->mutex = mutex;      test->cond = cond;      g_thread_pool_push (pool, test, &error);      if (error) {	/* huh? */	g_assert_not_reached ();	g_error_free (error);	error = NULL;      }    }    g_mutex_lock (mutex);    for (walk = tests; walk; walk = walk->next) {      Test *test = walk->data;      while (test->output == NULL)	g_cond_wait (cond, mutex);      g_print ("%s", test->output);      if (!test->success) {	failures++;	g_string_append_printf (failed_tests, 	    "          %s\n", test->filename);      }      test_free (test);    }    g_mutex_unlock (mutex);    g_cond_free (cond);    g_mutex_free (mutex);  }  g_list_free (tests);  /* report failures and exit */  if (failures > 0) {    g_print ("\nFAILURES: %u\n", failures);    g_print ("%s", failed_tests->str);    g_string_free (failed_tests, TRUE);    return EXIT_FAILURE;  } else {    g_print ("\nEVERYTHING OK\n");    g_string_free (failed_tests, TRUE);    return EXIT_SUCCESS;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -