test-conversion.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108
  1. /* Copyright (C) 1999,2000,2001,2003,2004, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
  2. *
  3. * This library is free software; you can redistribute it and/or
  4. * modify it under the terms of the GNU Lesser General Public
  5. * License as published by the Free Software Foundation; either
  6. * version 2.1 of the License, or (at your option) any later version.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * Lesser General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Lesser General Public
  14. * License along with this library; if not, write to the Free Software
  15. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  16. */
  17. #if HAVE_CONFIG_H
  18. # include <config.h>
  19. #endif
  20. #include <libguile.h>
  21. #include <stdio.h>
  22. #include <assert.h>
  23. #include <string.h>
  24. #ifdef HAVE_INTTYPES_H
  25. # include <inttypes.h>
  26. #endif
  27. #ifndef PRIiMAX
  28. # if (defined SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG >= 8)
  29. # define PRIiMAX "lli"
  30. # define PRIuMAX "llu"
  31. # else
  32. # define PRIiMAX "li"
  33. # define PRIuMAX "lu"
  34. # endif
  35. #endif
  36. static void
  37. test_1 (const char *str, scm_t_intmax min, scm_t_intmax max,
  38. int result)
  39. {
  40. int r = scm_is_signed_integer (scm_c_eval_string (str), min, max);
  41. if (r != result)
  42. {
  43. fprintf (stderr, "fail: scm_is_signed_integer (%s, "
  44. "%" PRIiMAX ", %" PRIiMAX ") == %d\n",
  45. str, min, max, result);
  46. exit (1);
  47. }
  48. }
  49. static void
  50. test_is_signed_integer ()
  51. {
  52. test_1 ("'foo",
  53. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  54. 0);
  55. test_1 ("3.0",
  56. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  57. 0);
  58. test_1 ("(inexact->exact 3.0)",
  59. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  60. 1);
  61. test_1 ("3.5",
  62. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  63. 0);
  64. test_1 ("most-positive-fixnum",
  65. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  66. 1);
  67. test_1 ("(+ most-positive-fixnum 1)",
  68. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  69. 1);
  70. test_1 ("most-negative-fixnum",
  71. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  72. 1);
  73. test_1 ("(- most-negative-fixnum 1)",
  74. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  75. 1);
  76. if (sizeof (scm_t_intmax) == 8)
  77. {
  78. test_1 ("(- (expt 2 63) 1)",
  79. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  80. 1);
  81. test_1 ("(expt 2 63)",
  82. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  83. 0);
  84. test_1 ("(- (expt 2 63))",
  85. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  86. 1);
  87. test_1 ("(- (- (expt 2 63)) 1)",
  88. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  89. 0);
  90. }
  91. else if (sizeof (scm_t_intmax) == 4)
  92. {
  93. test_1 ("(- (expt 2 31) 1)",
  94. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  95. 1);
  96. test_1 ("(expt 2 31)",
  97. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  98. 0);
  99. test_1 ("(- (expt 2 31))",
  100. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  101. 1);
  102. test_1 ("(- (- (expt 2 31)) 1)",
  103. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  104. 0);
  105. }
  106. else
  107. fprintf (stderr, "NOTE: skipped some tests.\n");
  108. /* bignum with range that fits into fixnum. */
  109. test_1 ("(+ most-positive-fixnum 1)",
  110. -32768, 32767,
  111. 0);
  112. /* bignum with range that doesn't fit into fixnum, but probably
  113. fits into long. */
  114. test_1 ("(+ most-positive-fixnum 1)",
  115. SCM_MOST_NEGATIVE_FIXNUM-1, SCM_MOST_POSITIVE_FIXNUM+1,
  116. 1);
  117. }
  118. static void
  119. test_2 (const char *str, scm_t_uintmax min, scm_t_uintmax max,
  120. int result)
  121. {
  122. int r = scm_is_unsigned_integer (scm_c_eval_string (str), min, max);
  123. if (r != result)
  124. {
  125. fprintf (stderr, "fail: scm_is_unsigned_integer (%s, "
  126. "%" PRIuMAX ", %" PRIuMAX ") == %d\n",
  127. str, min, max, result);
  128. exit (1);
  129. }
  130. }
  131. static void
  132. test_is_unsigned_integer ()
  133. {
  134. test_2 ("'foo",
  135. 0, SCM_T_UINTMAX_MAX,
  136. 0);
  137. test_2 ("3.0",
  138. 0, SCM_T_UINTMAX_MAX,
  139. 0);
  140. test_2 ("(inexact->exact 3.0)",
  141. 0, SCM_T_UINTMAX_MAX,
  142. 1);
  143. test_2 ("3.5",
  144. 0, SCM_T_UINTMAX_MAX,
  145. 0);
  146. test_2 ("most-positive-fixnum",
  147. 0, SCM_T_UINTMAX_MAX,
  148. 1);
  149. test_2 ("(+ most-positive-fixnum 1)",
  150. 0, SCM_T_UINTMAX_MAX,
  151. 1);
  152. test_2 ("most-negative-fixnum",
  153. 0, SCM_T_UINTMAX_MAX,
  154. 0);
  155. test_2 ("(- most-negative-fixnum 1)",
  156. 0, SCM_T_UINTMAX_MAX,
  157. 0);
  158. if (sizeof (scm_t_intmax) == 8)
  159. {
  160. test_2 ("(- (expt 2 64) 1)",
  161. 0, SCM_T_UINTMAX_MAX,
  162. 1);
  163. test_2 ("(expt 2 64)",
  164. 0, SCM_T_UINTMAX_MAX,
  165. 0);
  166. }
  167. else if (sizeof (scm_t_intmax) == 4)
  168. {
  169. test_2 ("(- (expt 2 32) 1)",
  170. 0, SCM_T_UINTMAX_MAX,
  171. 1);
  172. test_2 ("(expt 2 32)",
  173. 0, SCM_T_UINTMAX_MAX,
  174. 0);
  175. }
  176. else
  177. fprintf (stderr, "NOTE: skipped some tests.\n");
  178. /* bignum with range that fits into fixnum. */
  179. test_2 ("(+ most-positive-fixnum 1)",
  180. 0, 32767,
  181. 0);
  182. /* bignum with range that doesn't fit into fixnum, but probably
  183. fits into long. */
  184. test_2 ("(+ most-positive-fixnum 1)",
  185. 0, SCM_MOST_POSITIVE_FIXNUM+1,
  186. 1);
  187. }
  188. typedef struct {
  189. SCM val;
  190. scm_t_intmax min, max;
  191. scm_t_intmax result;
  192. } to_signed_data;
  193. static SCM
  194. out_of_range_handler (void *data, SCM key, SCM args)
  195. {
  196. return scm_equal_p (key, scm_from_locale_symbol ("out-of-range"));
  197. }
  198. static SCM
  199. wrong_type_handler (void *data, SCM key, SCM args)
  200. {
  201. return scm_equal_p (key, scm_from_locale_symbol ("wrong-type-arg"));
  202. }
  203. static SCM
  204. misc_error_handler (void *data, SCM key, SCM args)
  205. {
  206. return scm_equal_p (key, scm_from_locale_symbol ("misc-error"));
  207. }
  208. static SCM
  209. any_handler (void *data, SCM key, SCM args)
  210. {
  211. return SCM_BOOL_T;
  212. }
  213. static SCM
  214. to_signed_integer_body (void *data)
  215. {
  216. to_signed_data *d = (to_signed_data *)data;
  217. d->result = scm_to_signed_integer (d->val, d->min, d->max);
  218. return SCM_BOOL_F;
  219. }
  220. static void
  221. test_3 (const char *str, scm_t_intmax min, scm_t_intmax max,
  222. scm_t_intmax result, int range_error, int type_error)
  223. {
  224. to_signed_data data;
  225. data.val = scm_c_eval_string (str);
  226. data.min = min;
  227. data.max = max;
  228. if (range_error)
  229. {
  230. if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
  231. to_signed_integer_body, &data,
  232. out_of_range_handler, NULL)))
  233. {
  234. fprintf (stderr,
  235. "fail: scm_to_signed_int (%s, "
  236. "%" PRIiMAX ", %" PRIiMAX ") -> out of range\n",
  237. str, min, max);
  238. exit (1);
  239. }
  240. }
  241. else if (type_error)
  242. {
  243. if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
  244. to_signed_integer_body, &data,
  245. wrong_type_handler, NULL)))
  246. {
  247. fprintf (stderr,
  248. "fail: scm_to_signed_int (%s, "
  249. "%" PRIiMAX", %" PRIiMAX ") -> wrong type\n",
  250. str, min, max);
  251. exit (1);
  252. }
  253. }
  254. else
  255. {
  256. if (scm_is_true (scm_internal_catch (SCM_BOOL_T,
  257. to_signed_integer_body, &data,
  258. any_handler, NULL))
  259. || data.result != result)
  260. {
  261. fprintf (stderr,
  262. "fail: scm_to_signed_int (%s, "
  263. "%" PRIiMAX ", %" PRIiMAX ") = %" PRIiMAX "\n",
  264. str, min, max, result);
  265. exit (1);
  266. }
  267. }
  268. }
  269. static void
  270. test_to_signed_integer ()
  271. {
  272. test_3 ("'foo",
  273. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  274. 0, 0, 1);
  275. test_3 ("3.5",
  276. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  277. 0, 0, 1);
  278. test_3 ("12",
  279. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  280. 12, 0, 0);
  281. test_3 ("1000",
  282. -999, 999,
  283. 0, 1, 0);
  284. test_3 ("-1000",
  285. -999, 999,
  286. 0, 1, 0);
  287. test_3 ("most-positive-fixnum",
  288. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  289. SCM_MOST_POSITIVE_FIXNUM, 0, 0);
  290. test_3 ("most-negative-fixnum",
  291. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  292. SCM_MOST_NEGATIVE_FIXNUM, 0, 0);
  293. test_3 ("(+ most-positive-fixnum 1)",
  294. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  295. SCM_MOST_POSITIVE_FIXNUM+1, 0, 0);
  296. test_3 ("(- most-negative-fixnum 1)",
  297. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  298. SCM_MOST_NEGATIVE_FIXNUM-1, 0, 0);
  299. if (sizeof (scm_t_intmax) == 8)
  300. {
  301. test_3 ("(- (expt 2 63) 1)",
  302. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  303. SCM_T_INTMAX_MAX, 0, 0);
  304. test_3 ("(+ (- (expt 2 63)) 1)",
  305. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  306. SCM_T_INTMAX_MIN+1, 0, 0);
  307. test_3 ("(- (expt 2 63))",
  308. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  309. SCM_T_INTMAX_MIN, 0, 0);
  310. test_3 ("(expt 2 63)",
  311. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  312. 0, 1, 0);
  313. test_3 ("(- (- (expt 2 63)) 1)",
  314. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  315. 0, 1, 0);
  316. }
  317. else if (sizeof (scm_t_intmax) == 4)
  318. {
  319. test_3 ("(- (expt 2 31) 1)",
  320. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  321. SCM_T_INTMAX_MAX, 0, 0);
  322. test_3 ("(+ (- (expt 2 31)) 1)",
  323. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  324. SCM_T_INTMAX_MIN+1, 0, 0);
  325. test_3 ("(- (expt 2 31))",
  326. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  327. SCM_T_INTMAX_MIN, 0, 0);
  328. test_3 ("(expt 2 31)",
  329. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  330. 0, 1, 0);
  331. test_3 ("(- (- (expt 2 31)) 1)",
  332. SCM_T_INTMAX_MIN, SCM_T_INTMAX_MAX,
  333. 0, 1, 0);
  334. }
  335. else
  336. fprintf (stderr, "NOTE: skipped some tests.\n");
  337. }
  338. typedef struct {
  339. SCM val;
  340. scm_t_uintmax min, max;
  341. scm_t_uintmax result;
  342. } to_unsigned_data;
  343. static SCM
  344. to_unsigned_integer_body (void *data)
  345. {
  346. to_unsigned_data *d = (to_unsigned_data *)data;
  347. d->result = scm_to_unsigned_integer (d->val, d->min, d->max);
  348. return SCM_BOOL_F;
  349. }
  350. static void
  351. test_4 (const char *str, scm_t_uintmax min, scm_t_uintmax max,
  352. scm_t_uintmax result, int range_error, int type_error)
  353. {
  354. to_unsigned_data data;
  355. data.val = scm_c_eval_string (str);
  356. data.min = min;
  357. data.max = max;
  358. if (range_error)
  359. {
  360. if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
  361. to_unsigned_integer_body, &data,
  362. out_of_range_handler, NULL)))
  363. {
  364. fprintf (stderr,
  365. "fail: scm_to_unsigned_int (%s, "
  366. "%" PRIuMAX ", %" PRIuMAX ") -> out of range\n",
  367. str, min, max);
  368. exit (1);
  369. }
  370. }
  371. else if (type_error)
  372. {
  373. if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
  374. to_unsigned_integer_body, &data,
  375. wrong_type_handler, NULL)))
  376. {
  377. fprintf (stderr,
  378. "fail: scm_to_unsigned_int (%s, "
  379. "%" PRIuMAX ", %" PRIuMAX ") -> wrong type\n",
  380. str, min, max);
  381. exit (1);
  382. }
  383. }
  384. else
  385. {
  386. if (scm_is_true (scm_internal_catch (SCM_BOOL_T,
  387. to_unsigned_integer_body, &data,
  388. any_handler, NULL))
  389. || data.result != result)
  390. {
  391. fprintf (stderr,
  392. "fail: scm_to_unsigned_int (%s, "
  393. "%" PRIuMAX ", %" PRIuMAX ") == %" PRIuMAX "\n",
  394. str, min, max, result);
  395. exit (1);
  396. }
  397. }
  398. }
  399. static void
  400. test_to_unsigned_integer ()
  401. {
  402. test_4 ("'foo",
  403. 0, SCM_T_UINTMAX_MAX,
  404. 0, 0, 1);
  405. test_4 ("3.5",
  406. 0, SCM_T_UINTMAX_MAX,
  407. 0, 0, 1);
  408. test_4 ("12",
  409. 0, SCM_T_UINTMAX_MAX,
  410. 12, 0, 0);
  411. test_4 ("1000",
  412. 0, 999,
  413. 0, 1, 0);
  414. test_4 ("most-positive-fixnum",
  415. 0, SCM_T_UINTMAX_MAX,
  416. SCM_MOST_POSITIVE_FIXNUM, 0, 0);
  417. test_4 ("(+ most-positive-fixnum 1)",
  418. 0, SCM_T_UINTMAX_MAX,
  419. SCM_MOST_POSITIVE_FIXNUM+1, 0, 0);
  420. if (sizeof (scm_t_intmax) == 8)
  421. {
  422. test_4 ("(- (expt 2 64) 1)",
  423. 0, SCM_T_UINTMAX_MAX,
  424. SCM_T_UINTMAX_MAX, 0, 0);
  425. test_4 ("(expt 2 64)",
  426. 0, SCM_T_UINTMAX_MAX,
  427. 0, 1, 0);
  428. }
  429. else if (sizeof (scm_t_intmax) == 4)
  430. {
  431. test_4 ("(- (expt 2 32) 1)",
  432. 0, SCM_T_UINTMAX_MAX,
  433. SCM_T_UINTMAX_MAX, 0, 0);
  434. test_4 ("(expt 2 32)",
  435. 0, SCM_T_UINTMAX_MAX,
  436. 0, 1, 0);
  437. }
  438. else
  439. fprintf (stderr, "NOTE: skipped some tests.\n");
  440. }
  441. static void
  442. test_5 (scm_t_intmax val, const char *result)
  443. {
  444. SCM res = scm_c_eval_string (result);
  445. if (scm_is_false (scm_equal_p (scm_from_signed_integer (val), res)))
  446. {
  447. fprintf (stderr, "fail: scm_from_signed_integer (%" PRIiMAX ") == %s\n",
  448. val, result);
  449. exit (1);
  450. }
  451. }
  452. static void
  453. test_from_signed_integer ()
  454. {
  455. test_5 (12, "12");
  456. if (sizeof (scm_t_intmax) == 8)
  457. {
  458. test_5 (SCM_T_INTMAX_MAX, "(- (expt 2 63) 1)");
  459. test_5 (SCM_T_INTMAX_MIN, "(- (expt 2 63))");
  460. }
  461. else if (sizeof (scm_t_intmax) == 4)
  462. {
  463. test_5 (SCM_T_INTMAX_MAX, "(- (expt 2 31) 1)");
  464. test_5 (SCM_T_INTMAX_MIN, "(- (expt 2 31))");
  465. }
  466. test_5 (SCM_MOST_POSITIVE_FIXNUM, "most-positive-fixnum");
  467. test_5 (SCM_MOST_NEGATIVE_FIXNUM, "most-negative-fixnum");
  468. test_5 (SCM_MOST_POSITIVE_FIXNUM+1, "(+ most-positive-fixnum 1)");
  469. test_5 (SCM_MOST_NEGATIVE_FIXNUM-1, "(- most-negative-fixnum 1)");
  470. }
  471. static void
  472. test_6 (scm_t_uintmax val, const char *result)
  473. {
  474. SCM res = scm_c_eval_string (result);
  475. if (scm_is_false (scm_equal_p (scm_from_unsigned_integer (val), res)))
  476. {
  477. fprintf (stderr, "fail: scm_from_unsigned_integer (%"
  478. PRIuMAX ") == %s\n",
  479. val, result);
  480. exit (1);
  481. }
  482. }
  483. static void
  484. test_from_unsigned_integer ()
  485. {
  486. test_6 (12, "12");
  487. if (sizeof (scm_t_intmax) == 8)
  488. {
  489. test_6 (SCM_T_UINTMAX_MAX, "(- (expt 2 64) 1)");
  490. }
  491. else if (sizeof (scm_t_intmax) == 4)
  492. {
  493. test_6 (SCM_T_UINTMAX_MAX, "(- (expt 2 32) 1)");
  494. }
  495. test_6 (SCM_MOST_POSITIVE_FIXNUM, "most-positive-fixnum");
  496. test_6 (SCM_MOST_POSITIVE_FIXNUM+1, "(+ most-positive-fixnum 1)");
  497. }
  498. static void
  499. test_7s (SCM n, scm_t_intmax c_n, const char *result, const char *func)
  500. {
  501. SCM r = scm_c_eval_string (result);
  502. if (scm_is_false (scm_equal_p (n, r)))
  503. {
  504. fprintf (stderr, "fail: %s (%" PRIiMAX ") == %s\n", func, c_n, result);
  505. exit (1);
  506. }
  507. }
  508. #define TEST_7S(func,arg,res) test_7s (func(arg), arg, res, #func)
  509. static void
  510. test_7u (SCM n, scm_t_uintmax c_n, const char *result, const char *func)
  511. {
  512. SCM r = scm_c_eval_string (result);
  513. if (scm_is_false (scm_equal_p (n, r)))
  514. {
  515. fprintf (stderr, "fail: %s (%" PRIuMAX ") == %s\n", func, c_n, result);
  516. exit (1);
  517. }
  518. }
  519. #define TEST_7U(func,arg,res) test_7u (func(arg), arg, res, #func)
  520. typedef struct {
  521. SCM val;
  522. scm_t_intmax (*func) (SCM);
  523. scm_t_intmax result;
  524. } to_signed_func_data;
  525. static SCM
  526. to_signed_func_body (void *data)
  527. {
  528. to_signed_func_data *d = (to_signed_func_data *)data;
  529. d->result = d->func (d->val);
  530. return SCM_BOOL_F;
  531. }
  532. static void
  533. test_8s (const char *str, scm_t_intmax (*func) (SCM), const char *func_name,
  534. scm_t_intmax result, int range_error, int type_error)
  535. {
  536. to_signed_func_data data;
  537. data.val = scm_c_eval_string (str);
  538. data.func = func;
  539. if (range_error)
  540. {
  541. if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
  542. to_signed_func_body, &data,
  543. out_of_range_handler, NULL)))
  544. {
  545. fprintf (stderr,
  546. "fail: %s (%s) -> out of range\n", func_name, str);
  547. exit (1);
  548. }
  549. }
  550. else if (type_error)
  551. {
  552. if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
  553. to_signed_func_body, &data,
  554. wrong_type_handler, NULL)))
  555. {
  556. fprintf (stderr,
  557. "fail: %s (%s) -> wrong type\n", func_name, str);
  558. exit (1);
  559. }
  560. }
  561. else
  562. {
  563. if (scm_is_true (scm_internal_catch (SCM_BOOL_T,
  564. to_signed_func_body, &data,
  565. any_handler, NULL))
  566. || data.result != result)
  567. {
  568. fprintf (stderr,
  569. "fail: %s (%s) = %" PRIiMAX "\n", func_name, str, result);
  570. exit (1);
  571. }
  572. }
  573. }
  574. typedef struct {
  575. SCM val;
  576. scm_t_uintmax (*func) (SCM);
  577. scm_t_uintmax result;
  578. } to_unsigned_func_data;
  579. static SCM
  580. to_unsigned_func_body (void *data)
  581. {
  582. to_unsigned_func_data *d = (to_unsigned_func_data *)data;
  583. d->result = d->func (d->val);
  584. return SCM_BOOL_F;
  585. }
  586. static void
  587. test_8u (const char *str, scm_t_uintmax (*func) (SCM), const char *func_name,
  588. scm_t_uintmax result, int range_error, int type_error)
  589. {
  590. to_unsigned_func_data data;
  591. data.val = scm_c_eval_string (str);
  592. data.func = func;
  593. if (range_error)
  594. {
  595. if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
  596. to_unsigned_func_body, &data,
  597. out_of_range_handler, NULL)))
  598. {
  599. fprintf (stderr,
  600. "fail: %s (%s) -> out of range\n", func_name, str);
  601. exit (1);
  602. }
  603. }
  604. else if (type_error)
  605. {
  606. if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
  607. to_unsigned_func_body, &data,
  608. wrong_type_handler, NULL)))
  609. {
  610. fprintf (stderr,
  611. "fail: %s (%s) -> wrong type\n", func_name, str);
  612. exit (1);
  613. }
  614. }
  615. else
  616. {
  617. if (scm_is_true (scm_internal_catch (SCM_BOOL_T,
  618. to_unsigned_func_body, &data,
  619. any_handler, NULL))
  620. || data.result != result)
  621. {
  622. fprintf (stderr,
  623. "fail: %s (%s) = %" PRIiMAX "\n", func_name, str, result);
  624. exit (1);
  625. }
  626. }
  627. }
  628. /* We can't rely on the scm_to functions being proper functions but we
  629. want to pass them to test_8s and test_8u, so we wrap'em. Also, we
  630. need to give them a common return type.
  631. */
  632. #define DEFSTST(f) static scm_t_intmax tst_##f (SCM x) { return f(x); }
  633. #define DEFUTST(f) static scm_t_uintmax tst_##f (SCM x) { return f(x); }
  634. DEFSTST (scm_to_schar)
  635. DEFUTST (scm_to_uchar)
  636. DEFSTST (scm_to_char)
  637. DEFSTST (scm_to_short)
  638. DEFUTST (scm_to_ushort)
  639. DEFSTST (scm_to_int)
  640. DEFUTST (scm_to_uint)
  641. DEFSTST (scm_to_long)
  642. DEFUTST (scm_to_ulong)
  643. #if SCM_SIZEOF_LONG_LONG != 0
  644. DEFSTST (scm_to_long_long)
  645. DEFUTST (scm_to_ulong_long)
  646. #endif
  647. DEFSTST (scm_to_ssize_t)
  648. DEFUTST (scm_to_size_t)
  649. DEFSTST (scm_to_int8)
  650. DEFUTST (scm_to_uint8)
  651. DEFSTST (scm_to_int16)
  652. DEFUTST (scm_to_uint16)
  653. DEFSTST (scm_to_int32)
  654. DEFUTST (scm_to_uint32)
  655. #ifdef SCM_HAVE_T_INT64
  656. DEFSTST (scm_to_int64)
  657. DEFUTST (scm_to_uint64)
  658. #endif
  659. #define TEST_8S(v,f,r,re,te) test_8s (v, tst_##f, #f, r, re, te)
  660. #define TEST_8U(v,f,r,re,te) test_8u (v, tst_##f, #f, r, re, te)
  661. static void
  662. test_int_sizes ()
  663. {
  664. TEST_7U (scm_from_uchar, 91, "91");
  665. TEST_7S (scm_from_schar, 91, "91");
  666. TEST_7S (scm_from_char, 91, "91");
  667. TEST_7S (scm_from_short, -911, "-911");
  668. TEST_7U (scm_from_ushort, 911, "911");
  669. TEST_7S (scm_from_int, 911, "911");
  670. TEST_7U (scm_from_uint, 911, "911");
  671. TEST_7S (scm_from_long, 911, "911");
  672. TEST_7U (scm_from_ulong, 911, "911");
  673. #if SCM_SIZEOF_LONG_LONG != 0
  674. TEST_7S (scm_from_long_long, 911, "911");
  675. TEST_7U (scm_from_ulong_long, 911, "911");
  676. #endif
  677. TEST_7U (scm_from_size_t, 911, "911");
  678. TEST_7S (scm_from_ssize_t, 911, "911");
  679. TEST_7S (scm_from_int8, -128, "-128");
  680. TEST_7S (scm_from_int8, 127, "127");
  681. TEST_7S (scm_from_int8, 128, "-128");
  682. TEST_7U (scm_from_uint8, 255, "255");
  683. TEST_7S (scm_from_int16, -32768, "-32768");
  684. TEST_7S (scm_from_int16, 32767, "32767");
  685. TEST_7S (scm_from_int16, 32768, "-32768");
  686. TEST_7U (scm_from_uint16, 65535, "65535");
  687. TEST_7S (scm_from_int32, SCM_T_INT32_MIN, "-2147483648");
  688. TEST_7S (scm_from_int32, SCM_T_INT32_MAX, "2147483647");
  689. TEST_7S (scm_from_int32, SCM_T_INT32_MAX+1LL, "-2147483648");
  690. TEST_7U (scm_from_uint32, SCM_T_UINT32_MAX, "4294967295");
  691. #if SCM_HAVE_T_INT64
  692. TEST_7S (scm_from_int64, SCM_T_INT64_MIN, "-9223372036854775808");
  693. TEST_7S (scm_from_int64, SCM_T_INT64_MAX, "9223372036854775807");
  694. TEST_7U (scm_from_uint64, SCM_T_UINT64_MAX, "18446744073709551615");
  695. #endif
  696. TEST_8S ("91", scm_to_schar, 91, 0, 0);
  697. TEST_8U ("91", scm_to_uchar, 91, 0, 0);
  698. TEST_8S ("91", scm_to_char, 91, 0, 0);
  699. TEST_8S ("-911", scm_to_short, -911, 0, 0);
  700. TEST_8U ("911", scm_to_ushort, 911, 0, 0);
  701. TEST_8S ("-911", scm_to_int, -911, 0, 0);
  702. TEST_8U ("911", scm_to_uint, 911, 0, 0);
  703. TEST_8S ("-911", scm_to_long, -911, 0, 0);
  704. TEST_8U ("911", scm_to_ulong, 911, 0, 0);
  705. #if SCM_SIZEOF_LONG_LONG != 0
  706. TEST_8S ("-911", scm_to_long_long, -911, 0, 0);
  707. TEST_8U ("911", scm_to_ulong_long, 911, 0, 0);
  708. #endif
  709. TEST_8U ("911", scm_to_size_t, 911, 0, 0);
  710. TEST_8S ("911", scm_to_ssize_t, 911, 0, 0);
  711. TEST_8S ("-128", scm_to_int8, SCM_T_INT8_MIN, 0, 0);
  712. TEST_8S ("127", scm_to_int8, SCM_T_INT8_MAX, 0, 0);
  713. TEST_8S ("128", scm_to_int8, 0, 1, 0);
  714. TEST_8S ("#f", scm_to_int8, 0, 0, 1);
  715. TEST_8U ("255", scm_to_uint8, SCM_T_UINT8_MAX, 0, 0);
  716. TEST_8U ("256", scm_to_uint8, 0, 1, 0);
  717. TEST_8U ("-1", scm_to_uint8, 0, 1, 0);
  718. TEST_8U ("#f", scm_to_uint8, 0, 0, 1);
  719. TEST_8S ("-32768", scm_to_int16, SCM_T_INT16_MIN, 0, 0);
  720. TEST_8S ("32767", scm_to_int16, SCM_T_INT16_MAX, 0, 0);
  721. TEST_8S ("32768", scm_to_int16, 0, 1, 0);
  722. TEST_8S ("#f", scm_to_int16, 0, 0, 1);
  723. TEST_8U ("65535", scm_to_uint16, SCM_T_UINT16_MAX, 0, 0);
  724. TEST_8U ("65536", scm_to_uint16, 0, 1, 0);
  725. TEST_8U ("-1", scm_to_uint16, 0, 1, 0);
  726. TEST_8U ("#f", scm_to_uint16, 0, 0, 1);
  727. TEST_8S ("-2147483648", scm_to_int32, SCM_T_INT32_MIN, 0, 0);
  728. TEST_8S ("2147483647", scm_to_int32, SCM_T_INT32_MAX, 0, 0);
  729. TEST_8S ("2147483648", scm_to_int32, 0, 1, 0);
  730. TEST_8S ("#f", scm_to_int32, 0, 0, 1);
  731. TEST_8U ("4294967295", scm_to_uint32, SCM_T_UINT32_MAX, 0, 0);
  732. TEST_8U ("4294967296", scm_to_uint32, 0, 1, 0);
  733. TEST_8U ("-1", scm_to_uint32, 0, 1, 0);
  734. TEST_8U ("#f", scm_to_uint32, 0, 0, 1);
  735. #if SCM_HAVE_T_INT64
  736. TEST_8S ("-9223372036854775808", scm_to_int64, SCM_T_INT64_MIN, 0, 0);
  737. TEST_8S ("9223372036854775807", scm_to_int64, SCM_T_INT64_MAX, 0, 0);
  738. TEST_8S ("9223372036854775808", scm_to_int64, 0, 1, 0);
  739. TEST_8S ("#f", scm_to_int64, 0, 0, 1);
  740. TEST_8U ("18446744073709551615", scm_to_uint64, SCM_T_UINT64_MAX, 0, 0);
  741. TEST_8U ("18446744073709551616", scm_to_uint64, 0, 1, 0);
  742. TEST_8U ("-1", scm_to_uint64, 0, 1, 0);
  743. TEST_8U ("#f", scm_to_uint64, 0, 0, 1);
  744. #endif
  745. }
  746. static void
  747. test_9 (double val, const char *result)
  748. {
  749. SCM res = scm_c_eval_string (result);
  750. if (scm_is_false (scm_eqv_p (res, scm_from_double (val))))
  751. {
  752. fprintf (stderr, "fail: scm_from_double (%g) == %s\n", val, result);
  753. exit (1);
  754. }
  755. }
  756. /* The `infinity' and `not-a-number' values. */
  757. static double guile_Inf, guile_NaN;
  758. /* Initialize GUILE_INF and GUILE_NAN. Taken from `guile_ieee_init ()' in
  759. `libguile/numbers.c'. */
  760. static void
  761. ieee_init (void)
  762. {
  763. #ifdef INFINITY
  764. /* C99 INFINITY, when available.
  765. FIXME: The standard allows for INFINITY to be something that overflows
  766. at compile time. We ought to have a configure test to check for that
  767. before trying to use it. (But in practice we believe this is not a
  768. problem on any system guile is likely to target.) */
  769. guile_Inf = INFINITY;
  770. #elif HAVE_DINFINITY
  771. /* OSF */
  772. extern unsigned int DINFINITY[2];
  773. guile_Inf = (*((double *) (DINFINITY)));
  774. #else
  775. double tmp = 1e+10;
  776. guile_Inf = tmp;
  777. for (;;)
  778. {
  779. guile_Inf *= 1e+10;
  780. if (guile_Inf == tmp)
  781. break;
  782. tmp = guile_Inf;
  783. }
  784. #endif
  785. #ifdef NAN
  786. /* C99 NAN, when available */
  787. guile_NaN = NAN;
  788. #elif HAVE_DQNAN
  789. {
  790. /* OSF */
  791. extern unsigned int DQNAN[2];
  792. guile_NaN = (*((double *)(DQNAN)));
  793. }
  794. #else
  795. guile_NaN = guile_Inf / guile_Inf;
  796. #endif
  797. }
  798. static void
  799. test_from_double ()
  800. {
  801. test_9 (12, "12.0");
  802. test_9 (0.25, "0.25");
  803. test_9 (0.1, "0.1");
  804. test_9 (guile_Inf, "+inf.0");
  805. test_9 (-guile_Inf, "-inf.0");
  806. test_9 (guile_NaN, "+nan.0");
  807. }
  808. typedef struct {
  809. SCM val;
  810. double result;
  811. } to_double_data;
  812. static SCM
  813. to_double_body (void *data)
  814. {
  815. to_double_data *d = (to_double_data *)data;
  816. d->result = scm_to_double (d->val);
  817. return SCM_BOOL_F;
  818. }
  819. static void
  820. test_10 (const char *val, double result, int type_error)
  821. {
  822. to_double_data data;
  823. data.val = scm_c_eval_string (val);
  824. if (type_error)
  825. {
  826. if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
  827. to_double_body, &data,
  828. wrong_type_handler, NULL)))
  829. {
  830. fprintf (stderr,
  831. "fail: scm_double (%s) -> wrong type\n", val);
  832. exit (1);
  833. }
  834. }
  835. else
  836. {
  837. if (scm_is_true (scm_internal_catch (SCM_BOOL_T,
  838. to_double_body, &data,
  839. any_handler, NULL))
  840. || data.result != result)
  841. {
  842. fprintf (stderr,
  843. "fail: scm_to_double (%s) = %g\n", val, result);
  844. exit (1);
  845. }
  846. }
  847. }
  848. static void
  849. test_to_double ()
  850. {
  851. test_10 ("#f", 0.0, 1);
  852. test_10 ("12", 12.0, 0);
  853. test_10 ("0.25", 0.25, 0);
  854. test_10 ("1/4", 0.25, 0);
  855. test_10 ("+inf.0", guile_Inf, 0);
  856. test_10 ("-inf.0",-guile_Inf, 0);
  857. test_10 ("+1i", 0.0, 1);
  858. }
  859. typedef struct {
  860. SCM val;
  861. char *result;
  862. } to_locale_string_data;
  863. static SCM
  864. to_locale_string_body (void *data)
  865. {
  866. to_locale_string_data *d = (to_locale_string_data *)data;
  867. d->result = scm_to_locale_string (d->val);
  868. return SCM_BOOL_F;
  869. }
  870. static void
  871. test_11 (const char *str, const char *result, int misc_error, int type_error)
  872. {
  873. to_locale_string_data data;
  874. data.val = scm_c_eval_string (str);
  875. data.result = NULL;
  876. if (misc_error)
  877. {
  878. if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
  879. to_locale_string_body, &data,
  880. misc_error_handler, NULL)))
  881. {
  882. fprintf (stderr,
  883. "fail: scm_to_locale_string (%s) -> misc error\n", str);
  884. exit (1);
  885. }
  886. }
  887. else if (type_error)
  888. {
  889. if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
  890. to_locale_string_body, &data,
  891. wrong_type_handler, NULL)))
  892. {
  893. fprintf (stderr,
  894. "fail: scm_to_locale_string (%s) -> wrong type\n", str);
  895. exit (1);
  896. }
  897. }
  898. else
  899. {
  900. if (scm_is_true (scm_internal_catch (SCM_BOOL_T,
  901. to_locale_string_body, &data,
  902. any_handler, NULL))
  903. || data.result == NULL || strcmp (data.result, result))
  904. {
  905. fprintf (stderr,
  906. "fail: scm_to_locale_string (%s) = %s\n", str, result);
  907. exit (1);
  908. }
  909. }
  910. free (data.result);
  911. }
  912. static void
  913. test_locale_strings ()
  914. {
  915. const char *lstr = "This is not a string.";
  916. char *lstr2;
  917. SCM str, str2;
  918. char buf[20];
  919. size_t len;
  920. if (!scm_is_string (scm_c_eval_string ("\"foo\"")))
  921. {
  922. fprintf (stderr, "fail: scm_is_string (\"foo\") = true\n");
  923. exit (1);
  924. }
  925. str = scm_from_locale_string (lstr);
  926. if (!scm_is_string (str))
  927. {
  928. fprintf (stderr, "fail: scm_is_string (str) = true\n");
  929. exit (1);
  930. }
  931. lstr2 = scm_to_locale_string (str);
  932. if (strcmp (lstr, lstr2))
  933. {
  934. fprintf (stderr, "fail: lstr = lstr2\n");
  935. exit (1);
  936. }
  937. free (lstr2);
  938. buf[15] = 'x';
  939. len = scm_to_locale_stringbuf (str, buf, 15);
  940. if (len != strlen (lstr))
  941. {
  942. fprintf (stderr, "fail: scm_to_locale_stringbuf (...) = strlen(lstr)\n");
  943. exit (1);
  944. }
  945. if (buf[15] != 'x')
  946. {
  947. fprintf (stderr, "fail: scm_to_locale_stringbuf (...) no overrun\n");
  948. exit (1);
  949. }
  950. if (strncmp (lstr, buf, 15))
  951. {
  952. fprintf (stderr, "fail: scm_to_locale_stringbuf (...) = lstr\n");
  953. exit (1);
  954. }
  955. str2 = scm_from_locale_stringn (lstr, 10);
  956. if (!scm_is_string (str2))
  957. {
  958. fprintf (stderr, "fail: scm_is_string (str2) = true\n");
  959. exit (1);
  960. }
  961. lstr2 = scm_to_locale_string (str2);
  962. if (strncmp (lstr, lstr2, 10))
  963. {
  964. fprintf (stderr, "fail: lstr = lstr2\n");
  965. exit (1);
  966. }
  967. free (lstr2);
  968. buf[10] = 'x';
  969. len = scm_to_locale_stringbuf (str2, buf, 20);
  970. if (len != 10)
  971. {
  972. fprintf (stderr, "fail: scm_to_locale_stringbuf (...) = 10\n");
  973. exit (1);
  974. }
  975. if (buf[10] != 'x')
  976. {
  977. fprintf (stderr, "fail: scm_to_locale_stringbuf (...) no overrun\n");
  978. exit (1);
  979. }
  980. if (strncmp (lstr, buf, 10))
  981. {
  982. fprintf (stderr, "fail: scm_to_locale_stringbuf (...) = lstr\n");
  983. exit (1);
  984. }
  985. lstr2 = scm_to_locale_stringn (str2, &len);
  986. if (len != 10)
  987. {
  988. fprintf (stderr, "fail: scm_to_locale_stringn, len = 10\n");
  989. exit (1);
  990. }
  991. test_11 ("#f", NULL, 0, 1);
  992. test_11 ("\"foo\"", "foo", 0, 0);
  993. test_11 ("(string #\\f #\\nul)", NULL, 1, 0);
  994. }
  995. static void
  996. tests (void *data, int argc, char **argv)
  997. {
  998. test_is_signed_integer ();
  999. test_is_unsigned_integer ();
  1000. test_to_signed_integer ();
  1001. test_to_unsigned_integer ();
  1002. test_from_signed_integer ();
  1003. test_from_unsigned_integer ();
  1004. test_int_sizes ();
  1005. test_from_double ();
  1006. test_to_double ();
  1007. test_locale_strings ();
  1008. }
  1009. int
  1010. main (int argc, char *argv[])
  1011. {
  1012. ieee_init ();
  1013. scm_boot_guile (argc, argv, tests, NULL);
  1014. return 0;
  1015. }