markup.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <glib.h>
  4. #include "test.h"
  5. #define do_bad_test(s) do { char *r = markup_test (s); if (r == NULL) return FAILED ("Failed on test " # s); else free (r); } while (0)
  6. #define do_ok_test(s) do { char *r = markup_test (s); if (r != NULL) return FAILED ("Could not parse valid " # s); } while (0)
  7. static char *
  8. markup_test (const char *s)
  9. {
  10. GMarkupParser *parser = g_new0 (GMarkupParser, 1);
  11. GMarkupParseContext *context;
  12. GError *error = NULL;
  13. context = g_markup_parse_context_new (parser, 0, 0, 0);
  14. g_markup_parse_context_parse (context, s, strlen (s), &error);
  15. g_markup_parse_context_free (context);
  16. if (error != NULL){
  17. char *msg = g_strdup (error->message);
  18. g_error_free (error);
  19. g_free (parser);
  20. return msg;
  21. }
  22. g_free (parser);
  23. return NULL;
  24. }
  25. RESULT
  26. invalid_documents (void)
  27. {
  28. /* These should fail */
  29. do_bad_test ("<1>");
  30. do_bad_test ("<a<");
  31. do_bad_test ("</a>");
  32. do_bad_test ("<a b>");
  33. do_bad_test ("<a b=>");
  34. do_bad_test ("<a b=c>");
  35. return OK;
  36. }
  37. RESULT
  38. valid_documents (void)
  39. {
  40. /* These should fail */
  41. do_ok_test ("<a>");
  42. do_ok_test ("<a a=\"b\">");
  43. return OK;
  44. }
  45. /*
  46. * This is a test for the kind of files that the code in mono/domain.c
  47. * parses; This code comes from Mono
  48. */
  49. typedef struct {
  50. GSList *supported_runtimes;
  51. char *required_runtime;
  52. int configuration_count;
  53. int startup_count;
  54. } AppConfigInfo;
  55. static char *
  56. get_attribute_value (const gchar **attribute_names,
  57. const gchar **attribute_values,
  58. const char *att_name)
  59. {
  60. int n;
  61. for (n=0; attribute_names[n] != NULL; n++) {
  62. if (strcmp (attribute_names[n], att_name) == 0)
  63. return g_strdup (attribute_values[n]);
  64. }
  65. return NULL;
  66. }
  67. static void
  68. start_element (GMarkupParseContext *context,
  69. const gchar *element_name,
  70. const gchar **attribute_names,
  71. const gchar **attribute_values,
  72. gpointer user_data,
  73. GError **error)
  74. {
  75. AppConfigInfo* app_config = (AppConfigInfo*) user_data;
  76. if (strcmp (element_name, "configuration") == 0) {
  77. app_config->configuration_count++;
  78. return;
  79. }
  80. if (strcmp (element_name, "startup") == 0) {
  81. app_config->startup_count++;
  82. return;
  83. }
  84. if (app_config->configuration_count != 1 || app_config->startup_count != 1)
  85. return;
  86. if (strcmp (element_name, "requiredRuntime") == 0) {
  87. app_config->required_runtime = get_attribute_value (attribute_names, attribute_values, "version");
  88. } else if (strcmp (element_name, "supportedRuntime") == 0) {
  89. char *version = get_attribute_value (attribute_names, attribute_values, "version");
  90. app_config->supported_runtimes = g_slist_append (app_config->supported_runtimes, version);
  91. }
  92. }
  93. static void
  94. end_element (GMarkupParseContext *context,
  95. const gchar *element_name,
  96. gpointer user_data,
  97. GError **error)
  98. {
  99. AppConfigInfo* app_config = (AppConfigInfo*) user_data;
  100. if (strcmp (element_name, "configuration") == 0) {
  101. app_config->configuration_count--;
  102. } else if (strcmp (element_name, "startup") == 0) {
  103. app_config->startup_count--;
  104. }
  105. }
  106. static const GMarkupParser
  107. mono_parser = {
  108. start_element,
  109. end_element,
  110. NULL,
  111. NULL,
  112. NULL
  113. };
  114. AppConfigInfo *
  115. domain_test (char *text)
  116. {
  117. AppConfigInfo *app_config = g_new0 (AppConfigInfo, 1);
  118. GMarkupParseContext *context;
  119. context = g_markup_parse_context_new (&mono_parser, 0, app_config, NULL);
  120. if (g_markup_parse_context_parse (context, text, strlen (text), NULL)) {
  121. g_markup_parse_context_end_parse (context, NULL);
  122. }
  123. g_markup_parse_context_free (context);
  124. return app_config;
  125. }
  126. void
  127. domain_free (AppConfigInfo *info)
  128. {
  129. GSList *l;
  130. if (info->required_runtime)
  131. g_free (info->required_runtime);
  132. for (l = info->supported_runtimes; l != NULL; l = l->next){
  133. g_free (l->data);
  134. }
  135. g_slist_free (info->supported_runtimes);
  136. g_free (info);
  137. }
  138. RESULT
  139. mono_domain (void)
  140. {
  141. AppConfigInfo *info;
  142. info = domain_test ("<configuration><!--hello--><startup><!--world--><requiredRuntime version=\"v1\"><!--r--></requiredRuntime></startup></configuration>");
  143. if (info->required_runtime == NULL)
  144. return FAILED ("No required runtime section");
  145. if (strcmp (info->required_runtime, "v1") != 0)
  146. return FAILED ("Got a runtime version %s, expected v1", info->required_runtime);
  147. domain_free (info);
  148. info = domain_test ("<configuration><startup><requiredRuntime version=\"v1\"/><!--comment--></configuration><!--end-->");
  149. if (info->required_runtime == NULL)
  150. return FAILED ("No required runtime section on auto-close section");
  151. if (strcmp (info->required_runtime, "v1") != 0)
  152. return FAILED ("Got a runtime version %s, expected v1", info->required_runtime);
  153. domain_free (info);
  154. info = domain_test ("<!--start--><configuration><startup><supportedRuntime version=\"v1\"/><!--middle--><supportedRuntime version=\"v2\"/></startup></configuration>");
  155. if ((strcmp ((char*)info->supported_runtimes->data, "v1") == 0)){
  156. if (info->supported_runtimes->next == NULL)
  157. return FAILED ("Expected 2 supported runtimes");
  158. if ((strcmp ((char*)info->supported_runtimes->next->data, "v2") != 0))
  159. return FAILED ("Expected v1, v2, got %s", info->supported_runtimes->next->data);
  160. if (info->supported_runtimes->next->next != NULL)
  161. return FAILED ("Expected v1, v2, got more");
  162. } else
  163. return FAILED ("Expected `v1', got %s", info->supported_runtimes->data);
  164. domain_free (info);
  165. return NULL;
  166. }
  167. RESULT
  168. mcs_config (void)
  169. {
  170. return markup_test ("<configuration>\r\n <system.diagnostics>\r\n <trace autoflush=\"true\" indentsize=\"4\">\r\n <listeners>\r\n <add name=\"compilerLogListener\" type=\"System.Diagnostics.TextWriterTraceListener,System\"/> </listeners> </trace> </system.diagnostics> </configuration>");
  171. }
  172. RESULT
  173. xml_parse (void)
  174. {
  175. return markup_test ("<?xml version=\"1.0\" encoding=\"utf-8\"?><a></a>");
  176. }
  177. RESULT
  178. machine_config (void)
  179. {
  180. char *data;
  181. gsize size;
  182. if (g_file_get_contents ("../../data/net_1_1/machine.config", &data, &size, NULL)){
  183. return markup_test (data);
  184. }
  185. printf ("Ignoring this test\n");
  186. return NULL;
  187. }
  188. static Test markup_tests [] = {
  189. {"invalid_documents", invalid_documents},
  190. {"good_documents", valid_documents},
  191. {"mono_domain", mono_domain},
  192. {"mcs_config", mcs_config},
  193. {"xml_parse", xml_parse},
  194. {"machine_config", machine_config},
  195. {NULL, NULL}
  196. };
  197. DEFINE_TEST_GROUP_INIT(markup_tests_init, markup_tests)