mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
2001-12-08 Stefan Jahn <stefan@lkcc.org>
* strings.c (scm_c_string2str): New function. Converts a given Scheme string into a C string. Also put in two THINKME's regarding the malloc policy for the missing converter routines.
This commit is contained in:
parent
a7a7bb95eb
commit
4d4528e79a
4 changed files with 107 additions and 1 deletions
|
@ -1,4 +1,4 @@
|
||||||
* Intro / Index (last modified: $Date: 2001-11-14 20:47:40 $)
|
* Intro / Index (last modified: $Date: 2001-12-08 12:50:37 $)
|
||||||
|
|
||||||
This working document explains the design of the libguile API,
|
This working document explains the design of the libguile API,
|
||||||
specifically the interface to the C programming language.
|
specifically the interface to the C programming language.
|
||||||
|
@ -74,3 +74,65 @@ malloc with respect to libguile? Some specific questions:
|
||||||
* Should we provide something like scm_c_free() for pointers returned by
|
* Should we provide something like scm_c_free() for pointers returned by
|
||||||
these kind of functions?
|
these kind of functions?
|
||||||
|
|
||||||
|
The first proposal regarding a malloc policy has been rejected for the
|
||||||
|
following resons:
|
||||||
|
|
||||||
|
That would mean, users of guile - even on non M$ systems - would have to
|
||||||
|
keep track where their memory came from?
|
||||||
|
Assume there are users which have some kind of hash table where they store
|
||||||
|
strings in. The hash table is responsible for removing entries from the
|
||||||
|
table. Now, if you want to put strings from guile as well as other
|
||||||
|
strings into that table you would have to store a pointer to the
|
||||||
|
corresponding version of 'free' with every string? We should demand such
|
||||||
|
coding from all guile users?
|
||||||
|
|
||||||
|
The proposal itself read: For a clean memory interface of a client program
|
||||||
|
to libguile we use the following functions from libguile:
|
||||||
|
|
||||||
|
* scm_c_malloc -- should be used to allocate memory returned by some
|
||||||
|
of the SCM to C converter functions in libguile if the
|
||||||
|
client program does not supply memory
|
||||||
|
* scm_c_free -- must be used by the client program to free the memory
|
||||||
|
returned by the SCM to C converter functions in
|
||||||
|
libguile if the client program did not supply a buffer
|
||||||
|
* scm_c_realloc -- to be complete, do not know a real purpose yet
|
||||||
|
|
||||||
|
|
||||||
|
Yet another proposal regarding this problem reads as follows: We could make
|
||||||
|
life easier, if we supplied the following:
|
||||||
|
|
||||||
|
[in gc.h]
|
||||||
|
typedef void * (* scm_t_malloc_func) (size_t);
|
||||||
|
typedef void (* svz_t_free_func) (void *);
|
||||||
|
SCM_API scm_t_malloc_func scm_c_malloc;
|
||||||
|
SCM_API scm_t_free_func scm_c_free;
|
||||||
|
|
||||||
|
[in gc.c]
|
||||||
|
{
|
||||||
|
/* At some library initialization point. */
|
||||||
|
scm_c_malloc = malloc;
|
||||||
|
scm_c_free = free;
|
||||||
|
}
|
||||||
|
|
||||||
|
Then the SCM to C converters allocating memory to store their results use
|
||||||
|
scm_c_malloc() instead of simply malloc(). This way all libguile/Unix users
|
||||||
|
can stick to the previous free() policy, saying that you need to free()
|
||||||
|
pointers delivered by libguile. On the other hand M$-Windows users can pass
|
||||||
|
their own malloc()-function-pointer to the library and use their own free()
|
||||||
|
then. Basically this can be achieved in the following order:
|
||||||
|
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
scm_boot_guile (...);
|
||||||
|
scm_c_malloc = malloc;
|
||||||
|
str = scm_c_string2str (obj, NULL, NULL);
|
||||||
|
free (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
This policy is still discussed:
|
||||||
|
If there is one global variable scm_c_malloc, then setting it within one
|
||||||
|
thread may interfere with another thread that expects scm_c_malloc to be
|
||||||
|
set differently. In other words, you would have to introduce some locking
|
||||||
|
mechanism to guarantee that the sequence of setting scm_c_malloc and
|
||||||
|
calling scm_string2str can not be interrupted by a different thread that
|
||||||
|
sets scm_c_malloc to a different value.
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2001-12-08 Stefan Jahn <stefan@lkcc.org>
|
||||||
|
|
||||||
|
* strings.c (scm_c_string2str): New function. Converts a
|
||||||
|
given Scheme string into a C string. Also put in two
|
||||||
|
THINKME's regarding the malloc policy for the missing converter
|
||||||
|
routines.
|
||||||
|
|
||||||
2001-12-01 Neil Jerram <neil@ossau.uklinux.net>
|
2001-12-01 Neil Jerram <neil@ossau.uklinux.net>
|
||||||
|
|
||||||
* gh_data.c (gh_module_lookup): Use scm_str2symbol rather than
|
* gh_data.c (gh_module_lookup): Use scm_str2symbol rather than
|
||||||
|
|
|
@ -336,6 +336,42 @@ SCM_DEFINE (scm_string_append, "string-append", 0, 0, 1,
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
/* Converts the given Scheme string OBJ into a C string, containing a copy
|
||||||
|
of OBJ's content with a trailing null byte. If LENP is non-NULL, set
|
||||||
|
*LENP to the string's length.
|
||||||
|
|
||||||
|
When STR is non-NULL it receives the copy and is returned by the function,
|
||||||
|
otherwise new memory is allocated and the caller is responsible for
|
||||||
|
freeing it via free(). If out of memory, NULL is returned.
|
||||||
|
|
||||||
|
Note that Scheme strings may contain arbitrary data, including null
|
||||||
|
characters. This means that null termination is not a reliable way to
|
||||||
|
determine the length of the returned value. However, the function always
|
||||||
|
copies the complete contents of OBJ, and sets *LENP to the true length
|
||||||
|
of the string (if LENP is non-null). */
|
||||||
|
char *
|
||||||
|
scm_c_string2str (SCM obj, char *str, size_t *lenp)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
SCM_ASSERT (SCM_STRINGP (obj), obj, SCM_ARG1, "scm_c_string2str");
|
||||||
|
len = SCM_STRING_LENGTH (obj);
|
||||||
|
|
||||||
|
/* THINKME: What malloc policy? */
|
||||||
|
if (str == NULL)
|
||||||
|
str = (char *) malloc ((len + 1) * sizeof (char));
|
||||||
|
if (str == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memcpy (str, SCM_STRING_CHARS (obj), len);
|
||||||
|
/* THINKME: Is this necessary for arguments? I do not think so... */
|
||||||
|
scm_remember_upto_here_1 (obj);
|
||||||
|
str[len] = '\0';
|
||||||
|
|
||||||
|
if (lenp != NULL)
|
||||||
|
*lenp = len;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
scm_init_strings ()
|
scm_init_strings ()
|
||||||
|
|
|
@ -78,6 +78,7 @@ SCM_API SCM scm_string_set_x (SCM str, SCM k, SCM chr);
|
||||||
SCM_API SCM scm_substring (SCM str, SCM start, SCM end);
|
SCM_API SCM scm_substring (SCM str, SCM start, SCM end);
|
||||||
SCM_API SCM scm_string_append (SCM args);
|
SCM_API SCM scm_string_append (SCM args);
|
||||||
SCM_API void scm_init_strings (void);
|
SCM_API void scm_init_strings (void);
|
||||||
|
SCM_API char *scm_c_string2str (SCM obj, char *str, size_t *lenp);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue