⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slbstr.c

📁 一个C格式的脚本处理函数库源代码,可让你的C程序具有执行C格式的脚本文件
💻 C
字号:
/* Copyright (c) 1998, 1999, 2001, 2002, 2003 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 intbstring_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 intbstring_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 intbstring_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 intstring_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_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))       || (-1 == SLclass_add_binary_op (SLANG_BSTRING_TYPE, SLANG_BSTRING_TYPE, bstring_bstring_bin_op, bstring_bstring_bin_op_result)))     return -1;   if (-1 == SLadd_intrin_fun_table (BString_Table, NULL))     return -1;   return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -