From 98a18b797c63ea9baab31768ed720ad32c0004e8 Mon Sep 17 00:00:00 2001 From: Guillaume Cottenceau Date: Mon, 14 May 2001 21:47:42 +0000 Subject: i can compile slang and newt with dietlibc now --- mdk-stage1/slang/slbstr.c | 615 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 615 insertions(+) create mode 100644 mdk-stage1/slang/slbstr.c (limited to 'mdk-stage1/slang/slbstr.c') diff --git a/mdk-stage1/slang/slbstr.c b/mdk-stage1/slang/slbstr.c new file mode 100644 index 000000000..b4b8c4c51 --- /dev/null +++ b/mdk-stage1/slang/slbstr.c @@ -0,0 +1,615 @@ +/* Copyright (c) 1998, 1999, 2001 John E. Davis + * This file is part of the S-Lang library. + * + * You may distribute under the terms of either the GNU General Public + * License or the Perl Artistic License. + */ +#include "slinclud.h" + +#include "slang.h" +#include "_slang.h" + +struct _SLang_BString_Type +{ + unsigned int num_refs; + unsigned int len; + int ptr_type; +#define IS_SLSTRING 1 +#define IS_MALLOCED 2 +#define IS_NOT_TO_BE_FREED 3 + union + { + unsigned char bytes[1]; + unsigned char *ptr; + } + v; +}; + +#define BS_GET_POINTER(b) ((b)->ptr_type ? (b)->v.ptr : (b)->v.bytes) + +static SLang_BString_Type *create_bstring_of_type (char *bytes, unsigned int len, int type) +{ + SLang_BString_Type *b; + unsigned int size; + + size = sizeof(SLang_BString_Type); + if (type == 0) + size += len; + + if (NULL == (b = (SLang_BString_Type *)SLmalloc (size))) + return NULL; + + b->len = len; + b->num_refs = 1; + b->ptr_type = type; + + switch (type) + { + case 0: + if (bytes != NULL) memcpy ((char *) b->v.bytes, bytes, len); + /* Now \0 terminate it because we want to also use it as a C string + * whenever possible. Note that sizeof(SLang_BString_Type) includes + * space for 1 character and we allocated len extra bytes. Thus, it is + * ok to add a \0 to the end. + */ + b->v.bytes[len] = 0; + break; + + case IS_SLSTRING: + if (NULL == (b->v.ptr = (unsigned char *)SLang_create_nslstring (bytes, len))) + { + SLfree ((char *) b); + return NULL; + } + break; + + case IS_MALLOCED: + case IS_NOT_TO_BE_FREED: + b->v.ptr = (unsigned char *)bytes; + bytes [len] = 0; /* NULL terminate */ + break; + } + + return b; +} + +SLang_BString_Type * +SLbstring_create (unsigned char *bytes, unsigned int len) +{ + return create_bstring_of_type ((char *)bytes, len, 0); +} + +/* Note that ptr must be len + 1 bytes long for \0 termination */ +SLang_BString_Type * +SLbstring_create_malloced (unsigned char *ptr, unsigned int len, int free_on_error) +{ + SLang_BString_Type *b; + + if (ptr == NULL) + return NULL; + + if (NULL == (b = create_bstring_of_type ((char *)ptr, len, IS_MALLOCED))) + { + if (free_on_error) + SLfree ((char *) ptr); + } + return b; +} + +SLang_BString_Type *SLbstring_create_slstring (char *s) +{ + if (s == NULL) + return NULL; + + return create_bstring_of_type (s, strlen (s), IS_SLSTRING); +} + +SLang_BString_Type *SLbstring_dup (SLang_BString_Type *b) +{ + if (b != NULL) + b->num_refs += 1; + + return b; +} + +unsigned char *SLbstring_get_pointer (SLang_BString_Type *b, unsigned int *len) +{ + if (b == NULL) + { + *len = 0; + return NULL; + } + *len = b->len; + return BS_GET_POINTER(b); +} + +void SLbstring_free (SLang_BString_Type *b) +{ + if (b == NULL) + return; + + if (b->num_refs > 1) + { + b->num_refs -= 1; + return; + } + + switch (b->ptr_type) + { + case 0: + case IS_NOT_TO_BE_FREED: + default: + break; + + case IS_SLSTRING: + SLang_free_slstring ((char *)b->v.ptr); + break; + + case IS_MALLOCED: + SLfree ((char *)b->v.ptr); + break; + } + + SLfree ((char *) b); +} + +int SLang_pop_bstring (SLang_BString_Type **b) +{ + return SLclass_pop_ptr_obj (SLANG_BSTRING_TYPE, (VOID_STAR *)b); +} + +int SLang_push_bstring (SLang_BString_Type *b) +{ + if (b == NULL) + return SLang_push_null (); + + b->num_refs += 1; + + if (0 == SLclass_push_ptr_obj (SLANG_BSTRING_TYPE, (VOID_STAR)b)) + return 0; + + b->num_refs -= 1; + return -1; +} + +static int +bstring_bstring_bin_op_result (int op, unsigned char a, unsigned char b, + unsigned char *c) +{ + (void) a; + (void) b; + switch (op) + { + default: + return 0; + + case SLANG_PLUS: + *c = SLANG_BSTRING_TYPE; + break; + + case SLANG_GT: + case SLANG_GE: + case SLANG_LT: + case SLANG_LE: + case SLANG_EQ: + case SLANG_NE: + *c = SLANG_CHAR_TYPE; + break; + } + return 1; +} + +static int compare_bstrings (SLang_BString_Type *a, SLang_BString_Type *b) +{ + unsigned int len; + int ret; + + len = a->len; + if (b->len < len) len = b->len; + + ret = memcmp ((char *)BS_GET_POINTER(b), (char *)BS_GET_POINTER(a), len); + if (ret != 0) + return ret; + + if (a->len > b->len) + return 1; + if (a->len == b->len) + return 0; + + return -1; +} + +static SLang_BString_Type * +concat_bstrings (SLang_BString_Type *a, SLang_BString_Type *b) +{ + unsigned int len; + SLang_BString_Type *c; + char *bytes; + + len = a->len + b->len; + + if (NULL == (c = SLbstring_create (NULL, len))) + return NULL; + + bytes = (char *)BS_GET_POINTER(c); + + memcpy (bytes, (char *)BS_GET_POINTER(a), a->len); + memcpy (bytes + a->len, (char *)BS_GET_POINTER(b), b->len); + + return c; +} + +static void free_n_bstrings (SLang_BString_Type **a, unsigned int n) +{ + unsigned int i; + + if (a == NULL) return; + + for (i = 0; i < n; i++) + { + SLbstring_free (a[i]); + a[i] = NULL; + } +} + +static int +bstring_bstring_bin_op (int op, + unsigned char a_type, VOID_STAR ap, unsigned int na, + unsigned char b_type, VOID_STAR bp, unsigned int nb, + VOID_STAR cp) +{ + char *ic; + SLang_BString_Type **a, **b, **c; + unsigned int n, n_max; + unsigned int da, db; + + (void) a_type; + (void) b_type; + + if (na == 1) da = 0; else da = 1; + if (nb == 1) db = 0; else db = 1; + + if (na > nb) n_max = na; else n_max = nb; + + a = (SLang_BString_Type **) ap; + b = (SLang_BString_Type **) bp; + for (n = 0; n < n_max; n++) + { + if ((*a == NULL) || (*b == NULL)) + { + SLang_verror (SL_VARIABLE_UNINITIALIZED, + "Binary string element[%u] not initialized for binary operation", n); + return -1; + } + a += da; b += db; + } + + a = (SLang_BString_Type **) ap; + b = (SLang_BString_Type **) bp; + ic = (char *) cp; + c = NULL; + + switch (op) + { + case SLANG_PLUS: + /* Concat */ + c = (SLang_BString_Type **) cp; + for (n = 0; n < n_max; n++) + { + if (NULL == (c[n] = concat_bstrings (*a, *b))) + goto return_error; + + a += da; b += db; + } + break; + + case SLANG_NE: + for (n = 0; n < n_max; n++) + { + ic [n] = (0 != compare_bstrings (*a, *b)); + a += da; + b += db; + } + break; + case SLANG_GT: + for (n = 0; n < n_max; n++) + { + ic [n] = (compare_bstrings (*a, *b) > 0); + a += da; + b += db; + } + break; + case SLANG_GE: + for (n = 0; n < n_max; n++) + { + ic [n] = (compare_bstrings (*a, *b) >= 0); + a += da; + b += db; + } + break; + case SLANG_LT: + for (n = 0; n < n_max; n++) + { + ic [n] = (compare_bstrings (*a, *b) < 0); + a += da; + b += db; + } + break; + case SLANG_LE: + for (n = 0; n < n_max; n++) + { + ic [n] = (compare_bstrings (*a, *b) <= 0); + a += da; + b += db; + } + break; + case SLANG_EQ: + for (n = 0; n < n_max; n++) + { + ic [n] = (compare_bstrings (*a, *b) == 0); + a += da; + b += db; + } + break; + } + return 1; + + return_error: + if (c != NULL) + { + free_n_bstrings (c, n); + while (n < n_max) + { + c[n] = NULL; + n++; + } + } + return -1; +} + +/* If preserve_ptr, then use a[i] as the bstring data. See how this function + * is called by the binary op routines for why. + */ +static SLang_BString_Type ** +make_n_bstrings (SLang_BString_Type **b, char **a, unsigned int n, int ptr_type) +{ + unsigned int i; + int malloc_flag; + + malloc_flag = 0; + if (b == NULL) + { + b = (SLang_BString_Type **) SLmalloc ((n + 1) * sizeof (SLang_BString_Type *)); + if (b == NULL) + return NULL; + malloc_flag = 1; + } + + for (i = 0; i < n; i++) + { + char *s = a[i]; + + if (s == NULL) + { + b[i] = NULL; + continue; + } + + if (NULL == (b[i] = create_bstring_of_type (s, strlen(s), ptr_type))) + { + free_n_bstrings (b, i); + if (malloc_flag) SLfree ((char *) b); + return NULL; + } + } + + return b; +} + +static int +bstring_string_bin_op (int op, + unsigned char a_type, VOID_STAR ap, unsigned int na, + unsigned char b_type, VOID_STAR bp, unsigned int nb, + VOID_STAR cp) +{ + SLang_BString_Type **b; + int ret; + + if (NULL == (b = make_n_bstrings (NULL, (char **)bp, nb, IS_NOT_TO_BE_FREED))) + return -1; + + b_type = SLANG_BSTRING_TYPE; + ret = bstring_bstring_bin_op (op, + a_type, ap, na, + b_type, (VOID_STAR) b, nb, + cp); + free_n_bstrings (b, nb); + SLfree ((char *) b); + return ret; +} + +static int +string_bstring_bin_op (int op, + unsigned char a_type, VOID_STAR ap, unsigned int na, + unsigned char b_type, VOID_STAR bp, unsigned int nb, + VOID_STAR cp) +{ + SLang_BString_Type **a; + int ret; + + if (NULL == (a = make_n_bstrings (NULL, (char **)ap, na, IS_NOT_TO_BE_FREED))) + return -1; + + a_type = SLANG_BSTRING_TYPE; + ret = bstring_bstring_bin_op (op, + a_type, (VOID_STAR) a, na, + b_type, bp, nb, + cp); + free_n_bstrings (a, na); + SLfree ((char *) a); + + return ret; +} + +static void bstring_destroy (unsigned char unused, VOID_STAR s) +{ + (void) unused; + SLbstring_free (*(SLang_BString_Type **) s); +} + +static int bstring_push (unsigned char unused, VOID_STAR sptr) +{ + (void) unused; + + return SLang_push_bstring (*(SLang_BString_Type **) sptr); +} + +static int string_to_bstring (unsigned char a_type, VOID_STAR ap, unsigned int na, + unsigned char b_type, VOID_STAR bp) +{ + char **s; + SLang_BString_Type **b; + + (void) a_type; + (void) b_type; + + s = (char **) ap; + b = (SLang_BString_Type **) bp; + + if (NULL == make_n_bstrings (b, s, na, IS_SLSTRING)) + return -1; + + return 1; +} + +static int bstring_to_string (unsigned char a_type, VOID_STAR ap, unsigned int na, + unsigned char b_type, VOID_STAR bp) +{ + char **s; + unsigned int i; + SLang_BString_Type **a; + + (void) a_type; + (void) b_type; + + s = (char **) bp; + a = (SLang_BString_Type **) ap; + + for (i = 0; i < na; i++) + { + SLang_BString_Type *ai = a[i]; + + if (ai == NULL) + { + s[i] = NULL; + continue; + } + + if (NULL == (s[i] = SLang_create_slstring ((char *)BS_GET_POINTER(ai)))) + { + while (i != 0) + { + i--; + SLang_free_slstring (s[i]); + s[i] = NULL; + } + return -1; + } + } + + return 1; +} + +static char *bstring_string (unsigned char type, VOID_STAR v) +{ + SLang_BString_Type *s; + unsigned char buf[128]; + unsigned char *bytes, *bytes_max; + unsigned char *b, *bmax; + + (void) type; + + s = *(SLang_BString_Type **) v; + bytes = BS_GET_POINTER(s); + bytes_max = bytes + s->len; + + b = buf; + bmax = buf + (sizeof (buf) - 4); + + while (bytes < bytes_max) + { + unsigned char ch = *bytes; + + if ((ch < 32) || (ch >= 127) || (ch == '\\')) + { + if (b + 4 > bmax) + break; + + sprintf ((char *) b, "\\%03o", ch); + b += 4; + } + else + { + if (b == bmax) + break; + + *b++ = ch; + } + + bytes++; + } + + if (bytes < bytes_max) + { + *b++ = '.'; + *b++ = '.'; + *b++ = '.'; + } + *b = 0; + + return SLmake_string ((char *)buf); +} + +static unsigned int bstrlen_cmd (SLang_BString_Type *b) +{ + return b->len; +} + +static SLang_Intrin_Fun_Type BString_Table [] = /*{{{*/ +{ + MAKE_INTRINSIC_1("bstrlen", bstrlen_cmd, SLANG_UINT_TYPE, SLANG_BSTRING_TYPE), + MAKE_INTRINSIC_0("pack", _SLpack, SLANG_VOID_TYPE), + MAKE_INTRINSIC_2("unpack", _SLunpack, SLANG_VOID_TYPE, SLANG_STRING_TYPE, SLANG_BSTRING_TYPE), + MAKE_INTRINSIC_1("pad_pack_format", _SLpack_pad_format, SLANG_VOID_TYPE, SLANG_STRING_TYPE), + MAKE_INTRINSIC_1("sizeof_pack", _SLpack_compute_size, SLANG_UINT_TYPE, SLANG_STRING_TYPE), + SLANG_END_INTRIN_FUN_TABLE +}; + +int _SLang_init_bstring (void) +{ + SLang_Class_Type *cl; + + if (NULL == (cl = SLclass_allocate_class ("BString_Type"))) + return -1; + (void) SLclass_set_destroy_function (cl, bstring_destroy); + (void) SLclass_set_push_function (cl, bstring_push); + (void) SLclass_set_string_function (cl, bstring_string); + + if (-1 == SLclass_register_class (cl, SLANG_BSTRING_TYPE, sizeof (char *), + SLANG_CLASS_TYPE_PTR)) + return -1; + + if ((-1 == SLclass_add_typecast (SLANG_BSTRING_TYPE, SLANG_STRING_TYPE, bstring_to_string, 1)) + || (-1 == SLclass_add_typecast (SLANG_STRING_TYPE, SLANG_BSTRING_TYPE, string_to_bstring, 1)) + || (-1 == SLclass_add_binary_op (SLANG_BSTRING_TYPE, SLANG_BSTRING_TYPE, bstring_bstring_bin_op, bstring_bstring_bin_op_result)) + || (-1 == SLclass_add_binary_op (SLANG_STRING_TYPE, SLANG_BSTRING_TYPE, string_bstring_bin_op, bstring_bstring_bin_op_result)) + || (-1 == SLclass_add_binary_op (SLANG_BSTRING_TYPE, SLANG_STRING_TYPE, bstring_string_bin_op, bstring_bstring_bin_op_result))) + + return -1; + + if (-1 == SLadd_intrin_fun_table (BString_Table, NULL)) + return -1; + + return 0; +} + -- cgit v1.2.1