diff options
Diffstat (limited to 'mdk-stage1/slang/slpack.c')
| -rw-r--r-- | mdk-stage1/slang/slpack.c | 785 | 
1 files changed, 0 insertions, 785 deletions
| diff --git a/mdk-stage1/slang/slpack.c b/mdk-stage1/slang/slpack.c deleted file mode 100644 index 53ef63643..000000000 --- a/mdk-stage1/slang/slpack.c +++ /dev/null @@ -1,785 +0,0 @@ -/* Pack objects as a binary string */ -/* 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 <ctype.h> - -#include "slang.h" -#include "_slang.h" - -#ifndef isdigit -# define isdigit(c) (((c)>='0')&&((c)<= '9')) -#endif -#ifndef isspace -# define isspace(c) (((c)==' ') || ((c)=='\t') || ((c)=='\n')) -#endif - -/* format description: - * - *    s = string (null padded) - *    S = string (space padded) - *    c = signed char - *    C = unsigned char - *    h = short - *    H = unsigned short - *    i = int - *    I = unsigned int - *    l = long - *    L = unsigned long - *    j = 16 bit signed integer (short) - *    J = 16 bit unsigned integer (short) - *    k = 32 bit signed integer (long) - *    K = 32 bit unsigned integer (long) - *    f = float (native format) - *    F = 32 bit double - *    d = double (native format) - *    D = 64 bit double - *    x = null pad byte - *    > = big-endian mode - *    < = little-endian mode - *    = = native mode - */ - -#define NATIVE_ORDER		0 -#define BIGENDIAN_ORDER		1 -#define LILENDIAN_ORDER		2 -static int Native_Byte_Order = NATIVE_ORDER; - -typedef struct -{ -   char format_type; -   unsigned char data_type; -   unsigned int repeat; -   unsigned int sizeof_type; -   char pad; -   int byteorder; -   int is_scalar; -} -Format_Type; - -static int get_int_type_for_size (unsigned int size, unsigned char *s, unsigned char *u) -{ -   if (sizeof (int) == size) -     { -	if (s != NULL) *s = SLANG_INT_TYPE; -	if (u != NULL) *u = SLANG_UINT_TYPE; -	return 0; -     } - -   if (sizeof (short) == size) -     { -	if (s != NULL) *s = SLANG_SHORT_TYPE; -	if (u != NULL) *u = SLANG_USHORT_TYPE; -	return 1; -     } - -   if (sizeof (long) == size) -     { -	if (s != NULL) *s = SLANG_LONG_TYPE; -	if (u != NULL) *u = SLANG_ULONG_TYPE; -	return 1; -     } - -   if (s != NULL) *s = 0; -   if (u != NULL) *u = 0; -   SLang_verror (SL_NOT_IMPLEMENTED, -		 "This OS does not support a %u byte int", size); -   return -1; -} - -static int get_float_type_for_size (unsigned int size, unsigned char *s) -{ -   if (sizeof (float) == size) -     { -	*s = SLANG_FLOAT_TYPE; -	return 0; -     } - -   if (sizeof (double) == size) -     { -	*s = SLANG_DOUBLE_TYPE; -	return 0; -     } - -   SLang_verror (SL_NOT_IMPLEMENTED, -		 "This OS does not support a %u byte float", size); -   return -1; -} - -static int parse_a_format (char **format, Format_Type *ft) -{ -   char *f; -   char ch; -   unsigned repeat; - -   f = *format; - -   while (((ch = *f++) != 0) -	  && isspace (ch)) -     ; - -   switch (ch) -     { -      default: -	ft->byteorder = NATIVE_ORDER; -	break; - -      case '=': -	ft->byteorder = NATIVE_ORDER; -	ch = *f++; -	break; - -      case '>': -	ft->byteorder = BIGENDIAN_ORDER; -	ch = *f++; -	break; - -      case '<': -	ft->byteorder = LILENDIAN_ORDER; -	ch = *f++; -	break; -     } - -   if (ch == 0) -     { -	f--; -	*format = f; -	return 0; -     } - -   ft->format_type = ch; -   ft->repeat = 1; - -   if (isdigit (*f)) -     { -	repeat = (unsigned int) (*f - '0'); -	f++; - -	while (isdigit (*f)) -	  { -	     unsigned int repeat10 = 10 * repeat + (unsigned int)(*f - '0'); - -	     /* Check overflow */ -	     if (repeat != repeat10 / 10) -	       { -		  SLang_verror (SL_OVERFLOW, -				"Repeat count too large in [un]pack format"); -		  return -1; -	       } -	     repeat = repeat10; -	     f++; -	  } -	ft->repeat = repeat; -     } - -   *format = f; - -   ft->is_scalar = 1; -   ft->pad = 0; - -   switch (ft->format_type) -     { -      default: -	SLang_verror (SL_NOT_IMPLEMENTED, -		      "[un]pack format character '%c' not supported", ft->format_type); -	return -1; - -      case 'D': -	ft->sizeof_type = 8; -	if (-1 == get_float_type_for_size (8, &ft->data_type)) -	  return -1; -	break; - -      case 'd': -	ft->data_type = SLANG_DOUBLE_TYPE; -	ft->sizeof_type = sizeof (double); -	break; - -      case 'F': -	ft->sizeof_type = 4; -	if (-1 == get_float_type_for_size (4, &ft->data_type)) -	  return -1; -	break; -      case 'f': -	ft->data_type = SLANG_FLOAT_TYPE; -	ft->sizeof_type = sizeof (float); -	break; - -      case 'h': -	ft->data_type = SLANG_SHORT_TYPE; -	ft->sizeof_type = sizeof (short); -	break; -      case 'H': -	ft->data_type = SLANG_USHORT_TYPE; -	ft->sizeof_type = sizeof (unsigned short); -	break; -      case 'i': -	ft->data_type = SLANG_INT_TYPE; -	ft->sizeof_type = sizeof (int); -	break; -      case 'I': -	ft->data_type = SLANG_UINT_TYPE; -	ft->sizeof_type = sizeof (unsigned int); -	break; -      case 'l': -	ft->data_type = SLANG_LONG_TYPE; -	ft->sizeof_type = sizeof (long); -	break; -      case 'L': -	ft->data_type = SLANG_ULONG_TYPE; -	ft->sizeof_type = sizeof (unsigned long); -	break; - -	/* 16 bit ints */ -      case 'j': -	ft->sizeof_type = 2; -	if (-1 == get_int_type_for_size (2, &ft->data_type, NULL)) -	  return -1; -	break; -      case 'J': -	ft->sizeof_type = 2; -	if (-1 == get_int_type_for_size (2, NULL, &ft->data_type)) -	  return -1; -	break; - -	/* 32 bit ints */ -      case 'k': -	ft->sizeof_type = 4; -	if (-1 == get_int_type_for_size (4, &ft->data_type, NULL)) -	  return -1; -	break; -      case 'K': -	ft->sizeof_type = 4; -	if (-1 == get_int_type_for_size (4, NULL, &ft->data_type)) -	  return -1; -	break; - -      case 'x': -	ft->sizeof_type = 1; -	ft->data_type = 0; -	break; - -      case 'c': -	ft->sizeof_type = 1; -	ft->data_type = SLANG_CHAR_TYPE; -	break; - -      case 'C': -	ft->data_type = SLANG_UCHAR_TYPE; -	ft->sizeof_type = 1; -	break; - -      case 'S': -      case 'A': -	ft->pad = ' '; -      case 'a': -      case 's': -	ft->data_type = SLANG_BSTRING_TYPE; -	ft->sizeof_type = 1; -	ft->is_scalar = 0; -	break; -     } -   return 1; -} - -static int compute_size_for_format (char *format, unsigned int *num_bytes) -{ -   unsigned int size; -   Format_Type ft; -   int status; - -   *num_bytes = size = 0; - -   while (1 == (status = parse_a_format (&format, &ft))) -     size += ft.repeat * ft.sizeof_type; - -   *num_bytes = size; -   return status; -} - -static void byte_swap64 (unsigned char *ss, unsigned int n) /*{{{*/ -{ -   unsigned char *p, *pmax, ch; - -   if (n == 0) return; -   p = (unsigned char *) ss; -   pmax = p + 8 * n; -   while (p < pmax) -     { -	ch = *p; -	*p = *(p + 7); -	*(p + 7) = ch; - -	ch = *(p + 6); -	*(p + 6) = *(p + 1); -	*(p + 1) = ch; - -	ch = *(p + 5); -	*(p + 5) = *(p + 2); -	*(p + 2) = ch; - -	ch = *(p + 4); -	*(p + 4) = *(p + 3); -	*(p + 3) = ch; - -	p += 8; -     } -} - -/*}}}*/ -static void byte_swap32 (unsigned char *ss, unsigned int n) /*{{{*/ -{ -   unsigned char *p, *pmax, ch; - -   p = (unsigned char *) ss; -   pmax = p + 4 * n; -   while (p < pmax) -     { -	ch = *p; -	*p = *(p + 3); -	*(p + 3) = ch; - -	ch = *(p + 1); -	*(p + 1) = *(p + 2); -	*(p + 2) = ch; -	p += 4; -     } -} - -/*}}}*/ -static void byte_swap16 (unsigned char *p, unsigned int nread) /*{{{*/ -{ -   unsigned char *pmax, ch; - -   pmax = p + 2 * nread; -   while (p < pmax) -     { -	ch = *p; -	*p = *(p + 1); -	*(p + 1) = ch; -	p += 2; -     } -} - -/*}}}*/ - -static int byteswap (int order, unsigned char *b,  unsigned int size, unsigned int num) -{ -   if (Native_Byte_Order == order) -     return 0; - -   switch (size) -     { -      case 2: -	byte_swap16 (b, num); -	break; -      case 4: -	byte_swap32 (b, num); -	break; -      case 8: -	byte_swap64 (b, num); -	break; -      default: -	return -1; -     } - -   return 0; -} - -static void check_native_byte_order (void) -{ -   unsigned short x; - -   if (Native_Byte_Order != NATIVE_ORDER) -     return; - -   x = 0xFF; -   if (*(unsigned char *)&x == 0xFF) -     Native_Byte_Order = LILENDIAN_ORDER; -   else -     Native_Byte_Order = BIGENDIAN_ORDER; -} - -static SLang_BString_Type * -pack_according_to_format (char *format, unsigned int nitems) -{ -   unsigned int size, num; -   unsigned char *buf, *b; -   SLang_BString_Type *bs; -   Format_Type ft; - -   buf = NULL; - -   if (-1 == compute_size_for_format (format, &size)) -     goto return_error; - -   if (NULL == (buf = (unsigned char *) SLmalloc (size + 1))) -     goto return_error; - -   b = buf; - -   while (1 == parse_a_format (&format, &ft)) -     { -	unsigned char *ptr; -	unsigned int repeat; - -	repeat = ft.repeat; -	if (ft.data_type == 0) -	  { -	     memset ((char *) b, ft.pad, repeat); -	     b += repeat; -	     continue; -	  } - -	if (ft.is_scalar) -	  { -	     unsigned char *bstart; -	     num = repeat; - -	     bstart = b; -	     while (repeat != 0) -	       { -		  unsigned int nelements; -		  SLang_Array_Type *at; - -		  if (nitems == 0) -		    { -		       SLang_verror (SL_INVALID_PARM, -				     "Not enough items for pack format"); -		       goto return_error; -		    } - -		  if (-1 == SLang_pop_array_of_type (&at, ft.data_type)) -		    goto return_error; - -		  nelements = at->num_elements; -		  if (repeat < nelements) -		    nelements = repeat; -		  repeat -= nelements; - -		  nelements = nelements * ft.sizeof_type; -		  memcpy ((char *)b, (char *)at->data, nelements); - -		  b += nelements; -		  SLang_free_array (at); -		  nitems--; -	       } - -	     if (ft.byteorder != NATIVE_ORDER) -	       byteswap (ft.byteorder, bstart, ft.sizeof_type, num); - -	     continue; -	  } - -	/* Otherwise we have a string */ -	if (-1 == SLang_pop_bstring (&bs)) -	  goto return_error; - -	ptr = SLbstring_get_pointer (bs, &num); -	if (repeat < num) num = repeat; -	memcpy ((char *)b, (char *)ptr, num); -	b += num; -	repeat -= num; -	memset ((char *)b, ft.pad, repeat); -	SLbstring_free (bs); -	b += repeat; -	nitems--; -     } - -   *b = 0; -   bs = SLbstring_create_malloced (buf, size, 0); -   if (bs == NULL) -     goto return_error; - -   SLdo_pop_n (nitems); -   return bs; - -   return_error: -   SLdo_pop_n (nitems); -   if (buf != NULL) -     SLfree ((char *) buf); - -   return NULL; -} - -void _SLpack (void) -{ -   SLang_BString_Type *bs; -   char *fmt; -   int nitems; - -   check_native_byte_order (); - -   nitems = SLang_Num_Function_Args; -   if (nitems <= 0) -     { -	SLang_verror (SL_SYNTAX_ERROR, -		      "pack: not enough arguments"); -	return; -     } - -   if ((-1 == SLreverse_stack (nitems)) -       || (-1 == SLang_pop_slstring (&fmt))) -     bs = NULL; -   else -     { -	bs = pack_according_to_format (fmt, (unsigned int)nitems - 1); -	SLang_free_slstring (fmt); -     } - -   SLang_push_bstring (bs); -   SLbstring_free (bs); -} - -void _SLunpack (char *format, SLang_BString_Type *bs) -{ -   Format_Type ft; -   unsigned char *b; -   unsigned int len; -   unsigned int num_bytes; - -   check_native_byte_order (); - -   if (-1 == compute_size_for_format (format, &num_bytes)) -     return; - -   b = SLbstring_get_pointer (bs, &len); -   if (b == NULL) -     return; - -   if (len < num_bytes) -     { -	SLang_verror (SL_INVALID_PARM, -		      "unpack format %s is too large for input string", -		      format); -	return; -     } - -   while (1 == parse_a_format (&format, &ft)) -     { -	char *str, *s; - -	if (ft.repeat == 0) -	  continue; - -	if (ft.data_type == 0) -	  {			       /* skip padding */ -	     b += ft.repeat; -	     continue; -	  } - -	if (ft.is_scalar) -	  { -	     SLang_Array_Type *at; -	     int dims; - -	     if (ft.repeat == 1) -	       { -		  SLang_Class_Type *cl; - -		  cl = _SLclass_get_class (ft.data_type); -		  memcpy ((char *)cl->cl_transfer_buf, (char *)b, ft.sizeof_type); -		  if (ft.byteorder != NATIVE_ORDER) -		    byteswap (ft.byteorder, (unsigned char *)cl->cl_transfer_buf, ft.sizeof_type, 1); - -		  if (-1 == (cl->cl_apush (ft.data_type, cl->cl_transfer_buf))) -		    return; -		  b += ft.sizeof_type; -		  continue; -	       } - -	     dims = (int) ft.repeat; -	     at = SLang_create_array (ft.data_type, 0, NULL, &dims, 1); -	     if (at == NULL) -	       return; - -	     num_bytes = ft.repeat * ft.sizeof_type; -	     memcpy ((char *)at->data, (char *)b, num_bytes); -	     if (ft.byteorder != NATIVE_ORDER) -	       byteswap (ft.byteorder, (unsigned char *)at->data, ft.sizeof_type, ft.repeat); - -	     if (-1 == SLang_push_array (at, 1)) -	       return; - -	     b += num_bytes; -	     continue; -	  } - -	len = ft.repeat; -	str = SLmalloc (len + 1); -	if (str == NULL) -	  return; - -	memcpy ((char *) str, (char *)b, len); -	str [len] = 0; - -	if (ft.pad == ' ') -	  { -	     unsigned int new_len; - -	     s = str + len; -	     while (s > str) -	       { -		  s--; -		  if ((*s != ' ') && (*s != 0)) -		    { -		       s++; -		       break; -		    } -		  *s = 0; -	       } -	     new_len = (unsigned int) (s - str); - -	     if (new_len != len) -	       { -		  s = SLrealloc (str, new_len + 1); -		  if (s == NULL) -		    { -		       SLfree (str); -		       return; -		    } -		  str = s; -		  len = new_len; -	       } -	  } - -	/* Avoid a bstring if possible */ -	s = SLmemchr (str, 0, len); -	if (s == NULL) -	  { -	     if (-1 == SLang_push_malloced_string (str)) -	       return; -	  } -	else -	  { -	     SLang_BString_Type *new_bs; - -	     new_bs = SLbstring_create_malloced ((unsigned char *)str, len, 1); -	     if (new_bs == NULL) -	       return; - -	     if (-1 == SLang_push_bstring (new_bs)) -	       { -		  SLfree (str); -		  return; -	       } -	     SLbstring_free (new_bs); -	  } - -	b += ft.repeat; -     } -} - -unsigned int _SLpack_compute_size (char *format) -{ -   unsigned int n; - -   n = 0; -   (void) compute_size_for_format (format, &n); -   return n; -} - -void _SLpack_pad_format (char *format) -{ -   unsigned int len, max_len; -   Format_Type ft; -   char *buf, *b; - -   check_native_byte_order (); - -   /* Just check the syntax */ -   if (-1 == compute_size_for_format (format, &max_len)) -     return; - -   /* This should be sufficient to handle any needed xyy padding characters. -    * I cannot see how this will be overrun -    */ -   max_len = 4 * (strlen (format) + 1); -   if (NULL == (buf = SLmalloc (max_len + 1))) -     return; - -   b = buf; -   len = 0; -   while (1 == parse_a_format (&format, &ft)) -     { -	struct { char a; short b; } s_h; -	struct { char a; int b; } s_i; -	struct { char a; long b; } s_l; -	struct { char a; float b; } s_f; -	struct { char a; double b; } s_d; -	unsigned int pad; - -	if (ft.repeat == 0) -	  continue; - -	if (ft.data_type == 0) -	  {			       /* pad */ -	     sprintf (b, "x%u", ft.repeat); -	     b += strlen (b); -	     len += ft.repeat; -	     continue; -	  } - -	switch (ft.data_type) -	  { -	   default: -	   case SLANG_STRING_TYPE: -	   case SLANG_BSTRING_TYPE: -	   case SLANG_CHAR_TYPE: -	   case SLANG_UCHAR_TYPE: -	     pad = 0; -	     break; - -	   case SLANG_SHORT_TYPE: -	   case SLANG_USHORT_TYPE: -	     pad = ((unsigned int) ((char *)&s_h.b - (char *)&s_h.a)); -	     break; - -	   case SLANG_INT_TYPE: -	   case SLANG_UINT_TYPE: -	     pad = ((unsigned int) ((char *)&s_i.b - (char *)&s_i.a)); -	     break; - -	   case SLANG_LONG_TYPE: -	   case SLANG_ULONG_TYPE: -	     pad = ((unsigned int) ((char *)&s_l.b - (char *)&s_l.a)); -	     break; - -	   case SLANG_FLOAT_TYPE: -	     pad = ((unsigned int) ((char *)&s_f.b - (char *)&s_f.a)); -	     break; - -	   case SLANG_DOUBLE_TYPE: -	     pad = ((unsigned int) ((char *)&s_d.b - (char *)&s_d.a)); -	     break; -	  } - -	/* Pad to a length that is an integer multiple of pad. */ -	if (pad) -	  pad = pad * ((len + pad - 1)/pad) - len; - -	if (pad) -	  { -	     sprintf (b, "x%u", pad); -	     b += strlen (b); -	     len += pad; -	  } - -	*b++ = ft.format_type; -	if (ft.repeat > 1) -	  { -	     sprintf (b, "%u", ft.repeat); -	     b += strlen (b); -	  } - -	len += ft.repeat * ft.sizeof_type; -     } -   *b = 0; - -   (void) SLang_push_malloced_string (buf); -} | 
