make_aligned_string etc. changes
Fergus Henderson
fjh at kryten.cs.mu.OZ.AU
Wed Feb 19 11:47:28 AEDT 1997
Hi dgj,
Can you please review this one?
Some improvements to const-correctness in the string handling code.
runtime/mercury_string.h:
Change make_aligned_string() so that the first (target)
argument is of type `ConstString' (const char *)
rather than of type `String' (char *), since it should
be const, because it can point to a string literal.
Also improve the documentation.
library/std_util.m:
Change the code so that it matches the new definition
of make_aligned_string.
Also make the `functor' field of expand_info a `ConstString'
rather than a `String', since it can point to a string literal.
library/io.m:
Change a call to make_aligned_string so that it matches the new
definition.
--- old/mercury_string.h Wed Feb 19 11:34:30 1997
+++ new/mercury-string.h Wed Feb 19 11:32:48 1997
@@ -14,35 +14,77 @@
#include "heap.h" /* for incr_hp_atomic */
-typedef char Char; /* we may eventually move to using wchar_t */
+/*
+** Mercury characters are given type `Char', which is a typedef for `char'.
+** Mercury strings are stored as pointers to '\0'-terminated arrays of Char.
+**
+** We may eventually move to using wchar_t for Mercury characters and strings,
+** so it is important to use these typedefs.
+*/
+typedef char Char;
typedef Char *String;
typedef const Char *ConstString;
+/*
+** string_const("...", len):
+** Given a C string literal and its length, returns a Mercury string.
+*/
#define string_const(string, len) ((Word)string)
-#define string_equal(s1,s2) (strcmp((char*)(s1),(char*)(s2))==0)
+/*
+** bool string_equal(ConstString s1, ConstString s2):
+** Return true iff the two Mercury strings s1 and s2 are equal.
+*/
+#define string_equal(s1,s2) (strcmp((char*)(s1),(char*)(s2))==0)
/*
-** If the string is aligned, set ptr equal to it, otherwise allocate one
-** on the heap.
+** void make_aligned_string(ConstString & ptr, const char * string):
+** Given a C string `string', set `ptr' to be a Mercury string
+** with the same contents. (`ptr' must be an lvalue.)
+** If the resulting Mercury string is to be used by Mercury code,
+** then the string pointed to by `string' should have been either
+** statically allocated or allocated on the Mercury heap.
+**
+** BEWARE: this may modify `hp', so it must only be called from
+** places where `hp' is valid. If calling it from inside a C function,
+** rather than inside Mercury code, you may need to call
+** save/restore_transient_regs().
+**
+** Algorithm: if the string is aligned, just set ptr equal to it.
+** Otherwise, allocate space on the heap and copy the C string to
+** the Mercury string.
*/
-#define make_aligned_string(ptr, string) \
- ( tag((Word)string) != 0 ? \
- (incr_hp_atomic(LVALUE_CAST(Word, (ptr)), \
- (strlen(string) + sizeof(Word)) / sizeof(Word)), \
- strcpy((ptr), (string))) \
- : \
- ((ptr) = (string)) \
- )
+#define make_aligned_string(ptr, string) \
+ do { \
+ Word make_aligned_string_tmp; \
+ char * make_aligned_string_ptr; \
+ \
+ if (tag((Word) (string)) != 0) { \
+ incr_hp_atomic(make_aligned_string_tmp, \
+ (strlen(string) + sizeof(Word)) / sizeof(Word)); \
+ make_aligned_string_ptr = \
+ (char *) make_aligned_string_tmp; \
+ strcpy(make_aligned_string_ptr, (string)); \
+ (ptr) = make_aligned_string_ptr; \
+ } else { \
+ (ptr) = (string); \
+ } \
+ } while(0)
/*
+** do_hash_string(int & hash, Word string):
+** Given a Mercury string `string', set `hash' to the hash value
+** for that string. (`hash' must be an lvalue.)
+**
+** This is an implementation detail used to implement hash_string().
+** It should not be used directly. Use hash_string() instead.
+**
** Note that hash_string is also defined in library/string.m.
** The definition here and the definition in string.m
** must be kept equivalent.
*/
-
-#define do_hash_string(hash,s) \
+#define do_hash_string(hash, s) \
{ \
int len = 0; \
hash = 0; \
@@ -54,19 +96,23 @@
hash ^= len; \
}
-extern int hash_string(Word);
+/*
+** hash_string(s):
+** Given a Mercury string `s', return a hash value for that string.
+*/
+int hash_string(Word);
#ifdef __GNUC__
#define hash_string(s) \
({ int hash; \
- do_hash_string(hash,s); \
+ do_hash_string(hash, s); \
hash; \
})
#endif
/*
-** if we're not using gcc, the actual definition of hash_string is in aux.c
-** it uses the macro HASH_STRING_FUNC_BODY below
+** If we're not using gcc, the actual definition of hash_string is in misc.c;
+** it uses the macro HASH_STRING_FUNC_BODY below.
*/
#define HASH_STRING_FUNC_BODY \
Index: std_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/std_util.m,v
retrieving revision 1.70
diff -u -r1.70 std_util.m
--- 1.70 1997/02/13 16:41:15
+++ std_util.m 1997/02/18 18:57:18
@@ -855,7 +855,7 @@
typedef struct mercury_expand_info {
- String functor;
+ ConstString functor;
int arity;
Word *argument_vector;
Word *type_info_vector;
@@ -1031,7 +1031,7 @@
/* the functors are stored after the enum_indicator and
* the number of functors
*/
- info->functor = (String) ((Word *) entry_value)[data_value +
+ info->functor = (ConstString) ((Word *) entry_value)[data_value +
TYPELAYOUT_CONST_FUNCTOR_OFFSET];
info->arity = 0;
info->argument_vector = NULL;
@@ -1057,7 +1057,7 @@
* the number of functors
*/
- info->functor = (String) ((Word *) entry_value)[data_value +
+ info->functor = (ConstString) ((Word *) entry_value)[data_value +
TYPELAYOUT_ENUM_FUNCTOR_OFFSET];
info->arity = 0;
info->argument_vector = NULL;
@@ -1158,11 +1158,14 @@
/* XXX should escape characters correctly */
if (info->need_functor) {
- incr_saved_hp_atomic(LVALUE_CAST(Word, info->functor),
+ char *str;
+
+ incr_saved_hp_atomic(LVALUE_CAST(Word, str),
(strlen((String) data_value) + 2 +
sizeof(Word)) / sizeof(Word));
- sprintf(info->functor, ""%c%s%c"", '""',
+ sprintf(str, ""%c%s%c"", '""',
(String) data_value, '""');
+ info->functor = str;
}
info->argument_vector = NULL;
info->type_info_vector = NULL;
@@ -1173,11 +1176,14 @@
if (info->need_functor) {
char buf[500];
Float f;
+ char *str;
+
f = word_to_float(data_value);
sprintf(buf, ""%#.15g"", f);
- incr_saved_hp_atomic(LVALUE_CAST(Word, info->functor),
+ incr_saved_hp_atomic(LVALUE_CAST(Word, str),
(strlen(buf) + sizeof(Word)) / sizeof(Word));
- strcpy(info->functor, buf);
+ strcpy(str, buf);
+ info->functor = str;
}
info->argument_vector = NULL;
info->type_info_vector = NULL;
@@ -1187,11 +1193,13 @@
case TYPELAYOUT_INT_VALUE:
if (info->need_functor) {
char buf[500];
+ char *str;
sprintf(buf, ""%ld"", (long) data_value);
- incr_saved_hp_atomic(LVALUE_CAST(Word, info->functor),
+ incr_saved_hp_atomic(LVALUE_CAST(Word, str),
(strlen(buf) + sizeof(Word)) / sizeof(Word));
- strcpy(info->functor, buf);
+ strcpy(str, buf);
+ info->functor = str;
}
info->argument_vector = NULL;
@@ -1203,9 +1211,12 @@
/* XXX should escape characters correctly */
if (info->need_functor) {
- incr_saved_hp_atomic(LVALUE_CAST(Word, info->functor),
+ char *str;
+
+ incr_saved_hp_atomic(LVALUE_CAST(Word, str),
(3 + sizeof(Word)) / sizeof(Word));
- sprintf(info->functor, ""\'%c\'"", (char) data_value);
+ sprintf(str, ""\'%c\'"", (char) data_value);
+ info->functor = str;
}
info->argument_vector = NULL;
info->type_info_vector = NULL;
@@ -1225,8 +1236,7 @@
case TYPELAYOUT_PREDICATE_VALUE:
if (info->need_functor) {
- make_aligned_string(LVALUE_CAST(String, info->functor),
- ""<<predicate>>"");
+ make_aligned_string(info->functor, ""<<predicate>>"");
}
info->argument_vector = NULL;
info->type_info_vector = NULL;
@@ -1330,7 +1340,7 @@
restore_transient_registers();
/* Copy functor onto the heap */
- make_aligned_string(LVALUE_CAST(String, Functor), info.functor);
+ make_aligned_string(LVALUE_CAST(ConstString, Functor), info.functor);
Arity = info.arity;
@@ -1404,7 +1414,7 @@
restore_transient_registers();
/* Get functor */
- make_aligned_string(LVALUE_CAST(String, Functor), info.functor);
+ make_aligned_string(LVALUE_CAST(ConstString, Functor), info.functor);
/* Get arity */
Arity = info.arity;
Index: io.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/io.m,v
retrieving revision 1.111
diff -u -r1.111 io.m
--- 1.111 1997/02/13 23:58:28
+++ io.m 1997/02/19 00:37:11
@@ -2024,8 +2024,8 @@
it should be of type `ConstString' (const char *),
but fixing that requires a fair bit of work
on the compiler. */
- make_aligned_string(PrognameOut,
- (String) (Word) progname);
+ make_aligned_string(LVALUE_CAST(PrognameOut, ConstString),
+ progname);
} else {
PrognameOut = DefaultProgname;
}
More information about the developers
mailing list