PageRenderTime 51ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/src/libjx/src/test/test009.c

https://github.com/jjinux/jenarix
C | 280 lines | 212 code | 32 blank | 36 comment | 21 complexity | 192658214edb82a41fa84529890ceab8 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /*
  2. Copyright (c) 2009, DeLano Scientific LLC, Palo Alto, California, USA.
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions are
  6. met:
  7. * Redistributions of source code must retain the above copyright
  8. notice, this list of conditions and the following disclaimer.
  9. * Redistributions in binary form must reproduce the above copyright
  10. notice, this list of conditions and the following disclaimer in the
  11. documentation and/or other materials provided with the distribution.
  12. * Neither the name of the DeLano Scientific LLC nor the names of its
  13. contributors may be used to endorse or promote products derived from
  14. this software without specific prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  18. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  19. HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  20. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  21. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  25. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include "jx_public.h"
  31. #define C1(ex,s1) printf("# %s (%s line %d,);\n",s1,__FILE__,__LINE__);
  32. #define P1(ex,s1) printf(ex " || die('fail: %s line %d.');\n",s1,__FILE__,__LINE__);
  33. #define P2(ex,s1,s2) printf(ex " || die('fail: %s line %d.');\n",s1,s2,__FILE__,__LINE__);
  34. #define JS(st) \
  35. { \
  36. { \
  37. jx_ob ob = jx_ob_from_jxon_str(st); \
  38. jx_ob jxon = jx_ob_to_jxon(ob); \
  39. P2("'%s' == '%s'", st,jx_ob_as_str(&jxon)); \
  40. P1("0 == %d", jx_ob_free(jxon)); \
  41. P1("0 == %d", jx_ob_free(ob)); \
  42. } \
  43. }
  44. #define JF(st) \
  45. { \
  46. { \
  47. jx_ob ob = jx_ob_from_jxon_str(st); \
  48. jx_ob jxon = jx_ob_to_jxon(ob); \
  49. P1("'null' == '%s'", jx_ob_as_str(&jxon)); \
  50. P1("0 == %d", jx_ob_free(jxon)); \
  51. P1("0 == %d", jx_ob_free(ob)); \
  52. } \
  53. }
  54. unsigned int randmask(unsigned int mask)
  55. {
  56. return ((unsigned int) random()) & mask;
  57. }
  58. void random_string(char *target, int mask)
  59. {
  60. char *c = target;
  61. int len = randmask(mask);
  62. while(len--) {
  63. *(c++) = 65 + randmask(0xF);
  64. }
  65. *c = 0;
  66. }
  67. jx_int random_int(void)
  68. {
  69. return random();
  70. }
  71. jx_float random_float(void)
  72. /* only return floats which are exact in both decimal and binary representations */
  73. {
  74. jx_float result;
  75. jx_int expo = randmask(0x7);
  76. jx_int negative = randmask(0x1);
  77. jx_int inverse = randmask(0x1);
  78. jx_int value = 1;
  79. while(expo--)
  80. value = value * 2;
  81. if(negative)
  82. value = -value;
  83. if(inverse)
  84. result = 1.0 / value;
  85. else
  86. result = value;
  87. return result;
  88. }
  89. #if 1
  90. /* allow non-string primitives to be hash keys */
  91. #define random_key random_primitive
  92. #else
  93. /* only string primitives as hash keys */
  94. jx_ob random_key(void)
  95. {
  96. char buffer[0xF + 1];
  97. random_string(buffer, 0xF);
  98. return jx_ob_from_str(buffer);
  99. }
  100. #endif
  101. jx_ob random_primitive(void)
  102. {
  103. jx_ob result = JX_OB_NULL;
  104. switch (randmask(0x7)) {
  105. case 0:
  106. result = jx_ob_from_null();
  107. break;
  108. case 1:
  109. result = jx_ob_from_bool(1);
  110. break;
  111. case 2:
  112. result = jx_ob_from_bool(0);
  113. break;
  114. case 3:
  115. case 4:
  116. result = jx_ob_from_int(random_int());
  117. break;
  118. case 5:
  119. case 6:
  120. result = jx_ob_from_float(random_float());
  121. break;
  122. case 7:
  123. {
  124. char buffer[0xF + 1];
  125. random_string(buffer, 0xF);
  126. result = jx_ob_from_str(buffer);
  127. }
  128. break;
  129. }
  130. return result;
  131. }
  132. jx_ob random_container(void)
  133. {
  134. jx_ob result = JX_OB_NULL;
  135. if(randmask(0x1)) {
  136. result = jx_list_new();
  137. } else {
  138. result = jx_hash_new();
  139. }
  140. return result;
  141. }
  142. #define MAX_DEPTH 12
  143. jx_ob random_tree(int count)
  144. {
  145. jx_ob stack[MAX_DEPTH + 1];
  146. int depth = 0;
  147. if(randmask(0x1)) {
  148. stack[depth] = jx_list_new();
  149. } else {
  150. stack[depth] = jx_hash_new();
  151. }
  152. while(count) {
  153. switch (randmask(0x3)) {
  154. case 0: /* exit */
  155. if(depth) {
  156. depth--;
  157. }
  158. break;
  159. case 1: /* nest */
  160. if(depth < MAX_DEPTH) {
  161. if(jx_list_check(stack[depth])) {
  162. stack[depth + 1] = random_container();
  163. jx_list_append(stack[depth], stack[depth + 1]);
  164. depth++;
  165. } else if(jx_hash_check(stack[depth])) {
  166. jx_ob key = random_key();
  167. stack[depth + 1] = random_container();
  168. jx_hash_set(stack[depth], key, stack[depth + 1]);
  169. depth++;
  170. }
  171. }
  172. break;
  173. default: /* extend */
  174. {
  175. jx_ob value = random_primitive();
  176. if(jx_list_check(stack[depth])) {
  177. jx_list_append(stack[depth], value);
  178. } else {
  179. jx_ob key = random_key();
  180. jx_hash_set(stack[depth], key, value);
  181. }
  182. count--;
  183. }
  184. break;
  185. }
  186. }
  187. return stack[0];
  188. }
  189. jx_int strsum(jx_char * c)
  190. {
  191. jx_int result = 0;
  192. jx_char ch;
  193. while((ch = *(c++)))
  194. result += ch;
  195. return result;
  196. }
  197. #define STOP_AFTER 100000
  198. int main(int argc, char **argv)
  199. {
  200. int complexity = 0;
  201. while(1) {
  202. jx_ob ob1 = random_tree(complexity);
  203. jx_ob jxon1 = jx_ob_to_jxon(ob1);
  204. int len1 = strlen(jx_ob_as_str(&jxon1));
  205. int sum1 = strsum(jx_ob_as_str(&jxon1));
  206. jx_ob ob2 = jx_ob_from_jxon_str(jx_ob_as_str(&jxon1));
  207. jx_ob jxon2 = jx_ob_to_jxon(ob2);
  208. int len2 = strlen(jx_ob_as_str(&jxon2));
  209. int sum2 = strsum(jx_ob_as_str(&jxon2));
  210. // printf("# %s\n# %s\n",jx_ob_as_str(&jxon1), jx_ob_as_str(&jxon2));
  211. // jx_ob_dump(stderr,"ob2",ob2);
  212. printf("# complexity = %d, JXON string length = %d\n", complexity, len1);
  213. P2("%d == %d", len1, len2);
  214. if(len1 != len2) {
  215. jx_jxon_dump(stdout, "1", jxon1);
  216. jx_jxon_dump(stdout, "2", jxon2);
  217. exit(1);
  218. }
  219. P2("%d == %d", sum1, sum2);
  220. P1("1 == %d", jx_ob_equal(ob1, ob2));
  221. if(complexity < 100) {
  222. complexity++;
  223. } else {
  224. complexity += complexity;
  225. }
  226. #if 0
  227. if(complexity > STOP_AFTER) {
  228. FILE *f = fopen("input.jxon", "wb");
  229. fprintf(f, "%s\n", jx_ob_as_str(&jxon1));
  230. fclose(f);
  231. f = fopen("output.jxon", "wb");
  232. fprintf(f, "%s\n", jx_ob_as_str(&jxon2));
  233. fclose(f);
  234. }
  235. #endif
  236. jx_ob_free(jxon1);
  237. jx_ob_free(jxon2);
  238. jx_ob_free(ob1);
  239. jx_ob_free(ob2);
  240. if(complexity > STOP_AFTER)
  241. break;
  242. }
  243. }