test-conversion.c 30 KB

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