summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--devel/policy/api.text64
-rw-r--r--libguile/ChangeLog7
-rw-r--r--libguile/strings.c36
-rw-r--r--libguile/strings.h1
4 files changed, 107 insertions, 1 deletions
diff --git a/devel/policy/api.text b/devel/policy/api.text
index f59825091..f73dfc6c7 100644
--- a/devel/policy/api.text
+++ b/devel/policy/api.text
@@ -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,
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
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.
diff --git a/libguile/ChangeLog b/libguile/ChangeLog
index 2dd1eb699..4a1e683bc 100644
--- a/libguile/ChangeLog
+++ b/libguile/ChangeLog
@@ -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>
* gh_data.c (gh_module_lookup): Use scm_str2symbol rather than
diff --git a/libguile/strings.c b/libguile/strings.c
index 680707261..dab7a18f8 100644
--- a/libguile/strings.c
+++ b/libguile/strings.c
@@ -336,6 +336,42 @@ SCM_DEFINE (scm_string_append, "string-append", 0, 0, 1,
}
#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
scm_init_strings ()
diff --git a/libguile/strings.h b/libguile/strings.h
index e7952cae2..ea1bf7132 100644
--- a/libguile/strings.h
+++ b/libguile/strings.h
@@ -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_string_append (SCM args);
SCM_API void scm_init_strings (void);
+SCM_API char *scm_c_string2str (SCM obj, char *str, size_t *lenp);