gh_data.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2004, 2006 Free Software Foundation, Inc.
  2. * This library is free software; you can redistribute it and/or
  3. * modify it under the terms of the GNU Lesser General Public
  4. * License as published by the Free Software Foundation; either
  5. * version 2.1 of the License, or (at your option) any later version.
  6. *
  7. * This library is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. * Lesser General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU Lesser General Public
  13. * License along with this library; if not, write to the Free Software
  14. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  15. */
  16. /* data initialization and C<->Scheme data conversion */
  17. #ifdef HAVE_CONFIG_H
  18. # include <config.h>
  19. #endif
  20. #include "libguile/gh.h"
  21. #ifdef HAVE_STRING_H
  22. #include <string.h>
  23. #endif
  24. #include <assert.h>
  25. #if SCM_ENABLE_DEPRECATED
  26. /* data conversion C->scheme */
  27. SCM
  28. gh_bool2scm (int x)
  29. {
  30. return scm_from_bool(x);
  31. }
  32. SCM
  33. gh_int2scm (int x)
  34. {
  35. return scm_from_long ((long) x);
  36. }
  37. SCM
  38. gh_ulong2scm (unsigned long x)
  39. {
  40. return scm_from_ulong (x);
  41. }
  42. SCM
  43. gh_long2scm (long x)
  44. {
  45. return scm_from_long (x);
  46. }
  47. SCM
  48. gh_double2scm (double x)
  49. {
  50. return scm_from_double (x);
  51. }
  52. SCM
  53. gh_char2scm (char c)
  54. {
  55. return SCM_MAKE_CHAR (c);
  56. }
  57. SCM
  58. gh_str2scm (const char *s, size_t len)
  59. {
  60. return scm_from_locale_stringn (s, len);
  61. }
  62. SCM
  63. gh_str02scm (const char *s)
  64. {
  65. return scm_from_locale_string (s);
  66. }
  67. /* Copy LEN characters at SRC into the *existing* Scheme string DST,
  68. starting at START. START is an index into DST; zero means the
  69. beginning of the string.
  70. If START + LEN is off the end of DST, signal an out-of-range
  71. error. */
  72. void
  73. gh_set_substr (const char *src, SCM dst, long start, size_t len)
  74. {
  75. char *dst_ptr;
  76. size_t dst_len;
  77. SCM_ASSERT (scm_is_string (dst), dst, SCM_ARG3, "gh_set_substr");
  78. dst_len = scm_i_string_length (dst);
  79. SCM_ASSERT (start + len <= dst_len, dst, SCM_ARG4, "gh_set_substr");
  80. dst_ptr = scm_i_string_writable_chars (dst);
  81. memmove (dst_ptr + start, src, len);
  82. scm_i_string_stop_writing ();
  83. scm_remember_upto_here_1 (dst);
  84. }
  85. /* Return the symbol named SYMBOL_STR. */
  86. SCM
  87. gh_symbol2scm (const char *symbol_str)
  88. {
  89. return scm_from_locale_symbol(symbol_str);
  90. }
  91. SCM
  92. gh_ints2scm (const int *d, long n)
  93. {
  94. long i;
  95. SCM v = scm_c_make_vector (n, SCM_UNSPECIFIED);
  96. for (i = 0; i < n; ++i)
  97. SCM_SIMPLE_VECTOR_SET (v, i, scm_from_int (d[i]));
  98. return v;
  99. }
  100. SCM
  101. gh_doubles2scm (const double *d, long n)
  102. {
  103. long i;
  104. SCM v = scm_c_make_vector (n, SCM_UNSPECIFIED);
  105. for(i = 0; i < n; i++)
  106. SCM_SIMPLE_VECTOR_SET (v, i, scm_from_double (d[i]));
  107. return v;
  108. }
  109. SCM
  110. gh_chars2byvect (const char *d, long n)
  111. {
  112. char *m = scm_malloc (n);
  113. memcpy (m, d, n * sizeof (char));
  114. return scm_take_s8vector ((scm_t_int8 *)m, n);
  115. }
  116. SCM
  117. gh_shorts2svect (const short *d, long n)
  118. {
  119. char *m = scm_malloc (n * sizeof (short));
  120. memcpy (m, d, n * sizeof (short));
  121. assert (sizeof (scm_t_int16) == sizeof (short));
  122. return scm_take_s16vector ((scm_t_int16 *)m, n);
  123. }
  124. SCM
  125. gh_longs2ivect (const long *d, long n)
  126. {
  127. char *m = scm_malloc (n * sizeof (long));
  128. memcpy (m, d, n * sizeof (long));
  129. assert (sizeof (scm_t_int32) == sizeof (long));
  130. return scm_take_s32vector ((scm_t_int32 *)m, n);
  131. }
  132. SCM
  133. gh_ulongs2uvect (const unsigned long *d, long n)
  134. {
  135. char *m = scm_malloc (n * sizeof (unsigned long));
  136. memcpy (m, d, n * sizeof (unsigned long));
  137. assert (sizeof (scm_t_uint32) == sizeof (unsigned long));
  138. return scm_take_u32vector ((scm_t_uint32 *)m, n);
  139. }
  140. SCM
  141. gh_floats2fvect (const float *d, long n)
  142. {
  143. char *m = scm_malloc (n * sizeof (float));
  144. memcpy (m, d, n * sizeof (float));
  145. return scm_take_f32vector ((float *)m, n);
  146. }
  147. SCM
  148. gh_doubles2dvect (const double *d, long n)
  149. {
  150. char *m = scm_malloc (n * sizeof (double));
  151. memcpy (m, d, n * sizeof (double));
  152. return scm_take_f64vector ((double *)m, n);
  153. }
  154. /* data conversion scheme->C */
  155. int
  156. gh_scm2bool (SCM obj)
  157. {
  158. return (scm_is_false (obj)) ? 0 : 1;
  159. }
  160. unsigned long
  161. gh_scm2ulong (SCM obj)
  162. {
  163. return scm_to_ulong (obj);
  164. }
  165. long
  166. gh_scm2long (SCM obj)
  167. {
  168. return scm_to_long (obj);
  169. }
  170. int
  171. gh_scm2int (SCM obj)
  172. {
  173. return scm_to_int (obj);
  174. }
  175. double
  176. gh_scm2double (SCM obj)
  177. {
  178. return scm_to_double (obj);
  179. }
  180. char
  181. gh_scm2char (SCM obj)
  182. #define FUNC_NAME "gh_scm2char"
  183. {
  184. SCM_VALIDATE_CHAR (SCM_ARG1, obj);
  185. return SCM_CHAR (obj);
  186. }
  187. #undef FUNC_NAME
  188. /* Convert a vector, weak vector, string, substring or uniform vector
  189. into an array of chars. If result array in arg 2 is NULL, malloc a
  190. new one. If out of memory, return NULL. */
  191. char *
  192. gh_scm2chars (SCM obj, char *m)
  193. {
  194. long i, n;
  195. long v;
  196. SCM val;
  197. if (SCM_IMP (obj))
  198. scm_wrong_type_arg (0, 0, obj);
  199. switch (SCM_TYP7 (obj))
  200. {
  201. case scm_tc7_vector:
  202. case scm_tc7_wvect:
  203. n = SCM_SIMPLE_VECTOR_LENGTH (obj);
  204. for (i = 0; i < n; ++i)
  205. {
  206. val = SCM_SIMPLE_VECTOR_REF (obj, i);
  207. if (SCM_I_INUMP (val))
  208. {
  209. v = SCM_I_INUM (val);
  210. if (v < -128 || v > 255)
  211. scm_out_of_range (0, obj);
  212. }
  213. else
  214. scm_wrong_type_arg (0, 0, obj);
  215. }
  216. if (m == 0)
  217. m = (char *) malloc (n * sizeof (char));
  218. if (m == NULL)
  219. return NULL;
  220. for (i = 0; i < n; ++i)
  221. m[i] = SCM_I_INUM (SCM_SIMPLE_VECTOR_REF (obj, i));
  222. break;
  223. case scm_tc7_smob:
  224. if (scm_is_true (scm_s8vector_p (obj)))
  225. {
  226. scm_t_array_handle handle;
  227. size_t len;
  228. ssize_t inc;
  229. const scm_t_int8 *elts;
  230. elts = scm_s8vector_elements (obj, &handle, &len, &inc);
  231. if (inc != 1)
  232. scm_misc_error (NULL, "only contiguous vectors are supported: ~a",
  233. scm_list_1 (obj));
  234. if (m == 0)
  235. m = (char *) malloc (len);
  236. if (m != NULL)
  237. memcpy (m, elts, len);
  238. scm_array_handle_release (&handle);
  239. if (m == NULL)
  240. return NULL;
  241. break;
  242. }
  243. else
  244. goto wrong_type;
  245. case scm_tc7_string:
  246. n = scm_i_string_length (obj);
  247. if (m == 0)
  248. m = (char *) malloc (n * sizeof (char));
  249. if (m == NULL)
  250. return NULL;
  251. memcpy (m, scm_i_string_chars (obj), n * sizeof (char));
  252. break;
  253. default:
  254. wrong_type:
  255. scm_wrong_type_arg (0, 0, obj);
  256. }
  257. return m;
  258. }
  259. static void *
  260. scm2whatever (SCM obj, void *m, size_t size)
  261. {
  262. scm_t_array_handle handle;
  263. size_t len;
  264. ssize_t inc;
  265. const void *elts;
  266. elts = scm_uniform_vector_elements (obj, &handle, &len, &inc);
  267. if (inc != 1)
  268. scm_misc_error (NULL, "only contiguous vectors can be converted: ~a",
  269. scm_list_1 (obj));
  270. if (m == 0)
  271. m = malloc (len * sizeof (size));
  272. if (m != NULL)
  273. memcpy (m, elts, len * size);
  274. scm_array_handle_release (&handle);
  275. return m;
  276. }
  277. #define SCM2WHATEVER(obj,pred,utype,mtype) \
  278. if (scm_is_true (pred (obj))) \
  279. { \
  280. assert (sizeof (utype) == sizeof (mtype)); \
  281. return (mtype *)scm2whatever (obj, m, sizeof (utype)); \
  282. }
  283. /* Convert a vector, weak vector or uniform vector into an array of
  284. shorts. If result array in arg 2 is NULL, malloc a new one. If
  285. out of memory, return NULL. */
  286. short *
  287. gh_scm2shorts (SCM obj, short *m)
  288. {
  289. long i, n;
  290. long v;
  291. SCM val;
  292. if (SCM_IMP (obj))
  293. scm_wrong_type_arg (0, 0, obj);
  294. SCM2WHATEVER (obj, scm_s16vector_p, scm_t_int16, short)
  295. switch (SCM_TYP7 (obj))
  296. {
  297. case scm_tc7_vector:
  298. case scm_tc7_wvect:
  299. n = SCM_SIMPLE_VECTOR_LENGTH (obj);
  300. for (i = 0; i < n; ++i)
  301. {
  302. val = SCM_SIMPLE_VECTOR_REF (obj, i);
  303. if (SCM_I_INUMP (val))
  304. {
  305. v = SCM_I_INUM (val);
  306. if (v < -32768 || v > 65535)
  307. scm_out_of_range (0, obj);
  308. }
  309. else
  310. scm_wrong_type_arg (0, 0, obj);
  311. }
  312. if (m == 0)
  313. m = (short *) malloc (n * sizeof (short));
  314. if (m == NULL)
  315. return NULL;
  316. for (i = 0; i < n; ++i)
  317. m[i] = SCM_I_INUM (SCM_SIMPLE_VECTOR_REF (obj, i));
  318. break;
  319. default:
  320. scm_wrong_type_arg (0, 0, obj);
  321. }
  322. return m;
  323. }
  324. /* Convert a vector, weak vector or uniform vector into an array of
  325. longs. If result array in arg 2 is NULL, malloc a new one. If out
  326. of memory, return NULL. */
  327. long *
  328. gh_scm2longs (SCM obj, long *m)
  329. {
  330. long i, n;
  331. SCM val;
  332. if (SCM_IMP (obj))
  333. scm_wrong_type_arg (0, 0, obj);
  334. SCM2WHATEVER (obj, scm_s32vector_p, scm_t_int32, long)
  335. switch (SCM_TYP7 (obj))
  336. {
  337. case scm_tc7_vector:
  338. case scm_tc7_wvect:
  339. n = SCM_SIMPLE_VECTOR_LENGTH (obj);
  340. for (i = 0; i < n; ++i)
  341. {
  342. val = SCM_SIMPLE_VECTOR_REF (obj, i);
  343. if (!SCM_I_INUMP (val) && !SCM_BIGP (val))
  344. scm_wrong_type_arg (0, 0, obj);
  345. }
  346. if (m == 0)
  347. m = (long *) malloc (n * sizeof (long));
  348. if (m == NULL)
  349. return NULL;
  350. for (i = 0; i < n; ++i)
  351. {
  352. val = SCM_SIMPLE_VECTOR_REF (obj, i);
  353. m[i] = SCM_I_INUMP (val)
  354. ? SCM_I_INUM (val)
  355. : scm_to_long (val);
  356. }
  357. break;
  358. default:
  359. scm_wrong_type_arg (0, 0, obj);
  360. }
  361. return m;
  362. }
  363. /* Convert a vector, weak vector or uniform vector into an array of
  364. floats. If result array in arg 2 is NULL, malloc a new one. If
  365. out of memory, return NULL. */
  366. float *
  367. gh_scm2floats (SCM obj, float *m)
  368. {
  369. long i, n;
  370. SCM val;
  371. if (SCM_IMP (obj))
  372. scm_wrong_type_arg (0, 0, obj);
  373. /* XXX - f64vectors are rejected now.
  374. */
  375. SCM2WHATEVER (obj, scm_f32vector_p, float, float)
  376. switch (SCM_TYP7 (obj))
  377. {
  378. case scm_tc7_vector:
  379. case scm_tc7_wvect:
  380. n = SCM_SIMPLE_VECTOR_LENGTH (obj);
  381. for (i = 0; i < n; ++i)
  382. {
  383. val = SCM_SIMPLE_VECTOR_REF (obj, i);
  384. if (!SCM_I_INUMP (val)
  385. && !(SCM_BIGP (val) || SCM_REALP (val)))
  386. scm_wrong_type_arg (0, 0, val);
  387. }
  388. if (m == 0)
  389. m = (float *) malloc (n * sizeof (float));
  390. if (m == NULL)
  391. return NULL;
  392. for (i = 0; i < n; ++i)
  393. {
  394. val = SCM_SIMPLE_VECTOR_REF (obj, i);
  395. if (SCM_I_INUMP (val))
  396. m[i] = SCM_I_INUM (val);
  397. else if (SCM_BIGP (val))
  398. m[i] = scm_to_long (val);
  399. else
  400. m[i] = SCM_REAL_VALUE (val);
  401. }
  402. break;
  403. default:
  404. scm_wrong_type_arg (0, 0, obj);
  405. }
  406. return m;
  407. }
  408. /* Convert a vector, weak vector or uniform vector into an array of
  409. doubles. If result array in arg 2 is NULL, malloc a new one. If
  410. out of memory, return NULL. */
  411. double *
  412. gh_scm2doubles (SCM obj, double *m)
  413. {
  414. long i, n;
  415. SCM val;
  416. if (SCM_IMP (obj))
  417. scm_wrong_type_arg (0, 0, obj);
  418. /* XXX - f32vectors are rejected now.
  419. */
  420. SCM2WHATEVER (obj, scm_f64vector_p, double, double)
  421. switch (SCM_TYP7 (obj))
  422. {
  423. case scm_tc7_vector:
  424. case scm_tc7_wvect:
  425. n = SCM_SIMPLE_VECTOR_LENGTH (obj);
  426. for (i = 0; i < n; ++i)
  427. {
  428. val = SCM_SIMPLE_VECTOR_REF (obj, i);
  429. if (!SCM_I_INUMP (val)
  430. && !(SCM_BIGP (val) || SCM_REALP (val)))
  431. scm_wrong_type_arg (0, 0, val);
  432. }
  433. if (m == 0)
  434. m = (double *) malloc (n * sizeof (double));
  435. if (m == NULL)
  436. return NULL;
  437. for (i = 0; i < n; ++i)
  438. {
  439. val = SCM_SIMPLE_VECTOR_REF (obj, i);
  440. if (SCM_I_INUMP (val))
  441. m[i] = SCM_I_INUM (val);
  442. else if (SCM_BIGP (val))
  443. m[i] = scm_to_long (val);
  444. else
  445. m[i] = SCM_REAL_VALUE (val);
  446. }
  447. break;
  448. default:
  449. scm_wrong_type_arg (0, 0, obj);
  450. }
  451. return m;
  452. }
  453. /* string conversions between C and Scheme */
  454. /* gh_scm2newstr() -- Given a Scheme string STR, return a pointer to a
  455. new copy of its contents, followed by a null byte. If lenp is
  456. non-null, set *lenp to the string's length.
  457. This function uses malloc to obtain storage for the copy; the
  458. caller is responsible for freeing it. If out of memory, NULL is
  459. returned.
  460. Note that Scheme strings may contain arbitrary data, including null
  461. characters. This means that null termination is not a reliable way
  462. to determine the length of the returned value. However, the
  463. function always copies the complete contents of STR, and sets
  464. *LEN_P to the true length of the string (when LEN_P is non-null). */
  465. char *
  466. gh_scm2newstr (SCM str, size_t *lenp)
  467. {
  468. char *ret_str;
  469. /* We can't use scm_to_locale_stringn directly since it does not
  470. guarantee null-termination when lenp is non-NULL.
  471. */
  472. ret_str = scm_to_locale_string (str);
  473. if (lenp)
  474. *lenp = scm_i_string_length (str);
  475. return ret_str;
  476. }
  477. /* Copy LEN characters at START from the Scheme string SRC to memory
  478. at DST. START is an index into SRC; zero means the beginning of
  479. the string. DST has already been allocated by the caller.
  480. If START + LEN is off the end of SRC, silently truncate the source
  481. region to fit the string. If truncation occurs, the corresponding
  482. area of DST is left unchanged. */
  483. void
  484. gh_get_substr (SCM src, char *dst, long start, size_t len)
  485. {
  486. size_t src_len, effective_length;
  487. SCM_ASSERT (scm_is_string (src), src, SCM_ARG3, "gh_get_substr");
  488. src_len = scm_i_string_length (src);
  489. effective_length = (len < src_len) ? len : src_len;
  490. memcpy (dst + start, scm_i_string_chars (src), effective_length * sizeof (char));
  491. /* FIXME: must signal an error if len > src_len */
  492. scm_remember_upto_here_1 (src);
  493. }
  494. /* gh_scm2newsymbol() -- Given a Scheme symbol 'identifier, return a
  495. pointer to a string with the symbol characters "identifier",
  496. followed by a null byte. If lenp is non-null, set *lenp to the
  497. string's length.
  498. This function uses malloc to obtain storage for the copy; the
  499. caller is responsible for freeing it. If out of memory, NULL is
  500. returned.*/
  501. char *
  502. gh_symbol2newstr (SCM sym, size_t *lenp)
  503. {
  504. return gh_scm2newstr (scm_symbol_to_string (sym), lenp);
  505. }
  506. /* create a new vector of the given length, all initialized to the
  507. given value */
  508. SCM
  509. gh_make_vector (SCM len, SCM fill)
  510. {
  511. return scm_make_vector (len, fill);
  512. }
  513. /* set the given element of the given vector to the given value */
  514. SCM
  515. gh_vector_set_x (SCM vec, SCM pos, SCM val)
  516. {
  517. return scm_vector_set_x (vec, pos, val);
  518. }
  519. /* retrieve the given element of the given vector */
  520. SCM
  521. gh_vector_ref (SCM vec, SCM pos)
  522. {
  523. return scm_vector_ref (vec, pos);
  524. }
  525. /* returns the length of the given vector */
  526. unsigned long
  527. gh_vector_length (SCM v)
  528. {
  529. return (unsigned long) scm_c_vector_length (v);
  530. }
  531. /* uniform vector support */
  532. /* returns the length as a C unsigned long integer */
  533. unsigned long
  534. gh_uniform_vector_length (SCM v)
  535. {
  536. return (unsigned long) scm_c_uniform_vector_length (v);
  537. }
  538. /* gets the given element from a uniform vector; ilist is a list (or
  539. possibly a single integer) of indices, and its length is the
  540. dimension of the uniform vector */
  541. SCM
  542. gh_uniform_vector_ref (SCM v, SCM ilist)
  543. {
  544. return scm_uniform_vector_ref (v, ilist);
  545. }
  546. /* sets an individual element in a uniform vector */
  547. /* SCM */
  548. /* gh_list_to_uniform_array ( */
  549. /* Data lookups between C and Scheme
  550. Look up a symbol with a given name, and return the object to which
  551. it is bound. gh_lookup examines the Guile top level, and
  552. gh_module_lookup checks the module namespace specified by the
  553. `vec' argument.
  554. The return value is the Scheme object to which SNAME is bound, or
  555. SCM_UNDEFINED if SNAME is not bound in the given context.
  556. */
  557. SCM
  558. gh_lookup (const char *sname)
  559. {
  560. return gh_module_lookup (scm_current_module (), sname);
  561. }
  562. SCM
  563. gh_module_lookup (SCM module, const char *sname)
  564. #define FUNC_NAME "gh_module_lookup"
  565. {
  566. SCM sym, var;
  567. SCM_VALIDATE_MODULE (SCM_ARG1, module);
  568. sym = scm_from_locale_symbol (sname);
  569. var = scm_sym2var (sym, scm_module_lookup_closure (module), SCM_BOOL_F);
  570. if (var != SCM_BOOL_F)
  571. return SCM_VARIABLE_REF (var);
  572. else
  573. return SCM_UNDEFINED;
  574. }
  575. #undef FUNC_NAME
  576. #endif /* SCM_ENABLE_DEPRECATED */
  577. /*
  578. Local Variables:
  579. c-file-style: "gnu"
  580. End:
  581. */