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

📄 slstruct.c

📁 一个C格式的脚本处理函数库源代码,可让你的C程序具有执行C格式的脚本文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Structure type implementation *//* 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"/* #define SL_APP_WANTS_FOREACH */#include "slang.h"#include "_slang.h"void _SLstruct_delete_struct (_SLang_Struct_Type *s){   _SLstruct_Field_Type *field, *field_max;   if (s == NULL) return;   if (s->num_refs > 1)     {	s->num_refs -= 1;	return;     }   field = s->fields;   if (field != NULL)     {	field_max = field + s->nfields;	while (field < field_max)	  {	     SLang_free_object (&field->obj);	     SLang_free_slstring (field->name);   /* could be NULL */	     field++;	  }	SLfree ((char *) s->fields);     }   SLfree ((char *) s);}static _SLang_Struct_Type *allocate_struct (unsigned int nfields){   _SLang_Struct_Type *s;   _SLstruct_Field_Type *f;   unsigned int i, size;   s = (_SLang_Struct_Type *) SLmalloc (sizeof (_SLang_Struct_Type));   if (s == NULL) return NULL;   SLMEMSET((char *) s, 0, sizeof (_SLang_Struct_Type));   size = nfields * sizeof(_SLstruct_Field_Type);   if (NULL == (f = (_SLstruct_Field_Type *) SLmalloc (size)))     {	SLfree ((char *) s);	return NULL;     }   SLMEMSET ((char *) f, 0, size);   s->nfields = nfields;   s->fields = f;   /* By default, all structs will be created with elements set to NULL.  I    * do not know whether or not it is better to use SLANG_UNDEFINED_TYPE.    */   for (i = 0; i < nfields; i++)     f[i].obj.data_type = SLANG_NULL_TYPE;   return s;}static int push_struct_of_type (unsigned char type, _SLang_Struct_Type *s){   SLang_Object_Type obj;   obj.data_type = type;   obj.v.struct_val = s;   s->num_refs += 1;   if (0 == SLang_push (&obj))     return 0;   s->num_refs -= 1;   return -1;}int _SLang_push_struct (_SLang_Struct_Type *s){   return push_struct_of_type (SLANG_STRUCT_TYPE, s);}int _SLang_pop_struct (_SLang_Struct_Type **sp){   SLang_Object_Type obj;   SLang_Class_Type *cl;   unsigned char type;   if (0 != SLang_pop (&obj))     return -1;   type = obj.data_type;   if (type != SLANG_STRUCT_TYPE)     {	cl = _SLclass_get_class (type);	if (cl->cl_struct_def == NULL)	  {	     *sp = NULL;	     SLang_free_object (&obj);	     SLang_verror (SL_TYPE_MISMATCH,			   "Expecting struct type object.  Found %s",			   cl->cl_name);	     return -1;	  }     }   *sp = obj.v.struct_val;   return 0;}static void struct_destroy (unsigned char type, VOID_STAR vs){   (void) type;   _SLstruct_delete_struct (*(_SLang_Struct_Type **) vs);}static int struct_push (unsigned char type, VOID_STAR ptr){   return push_struct_of_type (type, *(_SLang_Struct_Type **) ptr);}static _SLstruct_Field_Type *find_field (_SLang_Struct_Type *s, char *name){   _SLstruct_Field_Type *f, *fmax;   f = s->fields;   fmax = f + s->nfields;   while (f < fmax)     {	/* Since both these are slstrings, only compare pointer */	if (name == f->name)	  return f;	f++;     }   return NULL;}static _SLstruct_Field_Type *pop_field (_SLang_Struct_Type *s, char *name,					_SLstruct_Field_Type *(*find)(_SLang_Struct_Type *, char *)){   _SLstruct_Field_Type *f;   f = (*find) (s, name);   if (f == NULL)     SLang_verror (SL_INVALID_PARM, "struct has no field named %s", name);   return f;}static _SLang_Struct_Type *  create_struct (unsigned int nfields,		 char **field_names,		 unsigned char *field_types,		 VOID_STAR *field_values){   _SLang_Struct_Type *s;   _SLstruct_Field_Type *f;   unsigned int i;   if (NULL == (s = allocate_struct (nfields)))     return NULL;   f = s->fields;   for (i = 0; i < nfields; i++)     {	unsigned char type;	SLang_Class_Type *cl;	VOID_STAR value;	char *name = field_names [i];	if (name == NULL)	  {	     SLang_verror (SL_APPLICATION_ERROR, "A struct field name cannot be NULL");	     goto return_error;	  }	if (-1 == _SLcheck_identifier_syntax (name))	  goto return_error;	if (NULL == (f->name = SLang_create_slstring (name)))	  goto return_error;	if ((field_values == NULL)	    || (NULL == (value = field_values [i])))	  {	     f++;	     continue;	  }	type = field_types[i];	cl = _SLclass_get_class (type);	if ((-1 == (cl->cl_apush (type, value)))	    || (-1 == SLang_pop (&f->obj)))	  goto return_error;	f++;     }   return s;   return_error:   _SLstruct_delete_struct (s);   return NULL;}int SLstruct_create_struct (unsigned int nfields,			    char **field_names,			    unsigned char *field_types,			    VOID_STAR *field_values){   _SLang_Struct_Type *s;      if (NULL == (s = create_struct (nfields, field_names, field_types, field_values)))     return -1;   if (0 == _SLang_push_struct (s))     return 0;   _SLstruct_delete_struct (s);   return -1;}/* Interpreter interface */int _SLstruct_define_struct (void){   int nfields;   _SLang_Struct_Type *s;   _SLstruct_Field_Type *f;   if (-1 == SLang_pop_integer (&nfields))     return -1;   if (nfields <= 0)     {	SLang_verror (SL_INVALID_PARM, "Number of struct fields must be > 0");	return -1;     }   if (NULL == (s = allocate_struct (nfields)))     return -1;   f = s->fields;   while (nfields)     {	char *name;	nfields--;	if (-1 == SLang_pop_slstring (&name))	  {	     _SLstruct_delete_struct (s);	     return -1;	  }	f[nfields].name = name;     }   if (-1 == _SLang_push_struct (s))     {	_SLstruct_delete_struct (s);	return -1;     }   return 0;}/* Simply make a struct that contains the same fields as struct s.  Do not * duplicate the field values. */static _SLang_Struct_Type *make_struct_shell (_SLang_Struct_Type *s){   _SLang_Struct_Type *new_s;   _SLstruct_Field_Type *new_f, *old_f;   unsigned int i, nfields;   nfields = s->nfields;   if (NULL == (new_s = allocate_struct (nfields)))     return NULL;   new_f = new_s->fields;   old_f = s->fields;   for (i = 0; i < nfields; i++)     {	if (NULL == (new_f[i].name = SLang_create_slstring (old_f[i].name)))	  {	     _SLstruct_delete_struct (new_s);	     return NULL;	  }     }   return new_s;}static int struct_init_array_object (unsigned char type, VOID_STAR addr){   SLang_Class_Type *cl;   _SLang_Struct_Type *s;   cl = _SLclass_get_class (type);   if (NULL == (s = make_struct_shell (cl->cl_struct_def)))     return -1;   s->num_refs = 1;   *(_SLang_Struct_Type **) addr = s;   return 0;}static inttypedefed_struct_datatype_deref (unsigned char type){   SLang_Class_Type *cl;   _SLang_Struct_Type *s;   cl = _SLclass_get_class (type);   if (NULL == (s = make_struct_shell (cl->cl_struct_def)))     return -1;   if (-1 == push_struct_of_type (type, s))     {	_SLstruct_delete_struct (s);	return -1;     }   return 0;}static _SLang_Struct_Type *duplicate_struct (_SLang_Struct_Type *s){   _SLang_Struct_Type *new_s;   _SLstruct_Field_Type *new_f, *f, *fmax;   new_s = make_struct_shell (s);   if (new_s == NULL)     return NULL;   f = s->fields;   fmax = f + s->nfields;   new_f = new_s->fields;   while (f < fmax)     {	SLang_Object_Type *obj;	obj = &f->obj;	if (obj->data_type != SLANG_UNDEFINED_TYPE)	  {	     if ((-1 == _SLpush_slang_obj (obj))		 || (-1 == SLang_pop (&new_f->obj)))	       {		  _SLstruct_delete_struct (new_s);		  return NULL;	       }	  }	new_f++;	f++;     }   return new_s;}static int struct_dereference (unsigned char type, VOID_STAR addr){   _SLang_Struct_Type *s;   if (NULL == (s = duplicate_struct (*(_SLang_Struct_Type **) addr)))     return -1;   if (-1 == push_struct_of_type (type, s))     {	_SLstruct_delete_struct (s);	return -1;     }   return 0;}/*{{{ foreach */struct _SLang_Foreach_Context_Type{   _SLang_Struct_Type *s;   char *next_field_name;};static SLang_Foreach_Context_Type *struct_foreach_open (unsigned char type, unsigned int num){   SLang_Foreach_Context_Type *c;   _SLang_Struct_Type *s;   char *next_name;   (void) type;   if (-1 == _SLang_pop_struct (&s))     return NULL;   switch (num)     {      case 0:	next_name = SLang_create_slstring ("next");	break;      case 1:	if (-1 == SLang_pop_slstring (&next_name))	  next_name = NULL;	break;      default:	next_name = NULL;	SLang_verror (SL_NOT_IMPLEMENTED,		      "'foreach (Struct_Type) using' requires single control value");	SLdo_pop_n (num);	break;     }   if (next_name == NULL)     {	_SLstruct_delete_struct (s);	return NULL;     }   c = (SLang_Foreach_Context_Type *)SLmalloc (sizeof (SLang_Foreach_Context_Type));   if (c == NULL)     {	_SLstruct_delete_struct (s);	SLang_free_slstring (next_name);	return NULL;     }   memset ((char *) c, 0, sizeof (SLang_Foreach_Context_Type));   c->next_field_name = next_name;   c->s = s;   return c;}static void struct_foreach_close (unsigned char type, SLang_Foreach_Context_Type *c){   (void) type;   if (c == NULL) return;   SLang_free_slstring (c->next_field_name);   if (c->s != NULL) _SLstruct_delete_struct (c->s);   SLfree ((char *) c);}static int struct_foreach (unsigned char type, SLang_Foreach_Context_Type *c){   _SLstruct_Field_Type *f;   _SLang_Struct_Type *next_s;   (void) type;   if (c == NULL)     return -1;   if (c->s == NULL)     return 0;			       /* done */   if (-1 == _SLang_push_struct (c->s))     return -1;   /* Now get the next one ready for the next foreach loop */   next_s = NULL;   if (NULL != (f = find_field (c->s, c->next_field_name)))     {	SLang_Class_Type *cl;	cl = _SLclass_get_class (f->obj.data_type);	/* Note that I cannot simply look for SLANG_STRUCT_TYPE since the	 * user may have typedefed another struct type.  So, look at the	 * class methods.	 */	if (cl->cl_foreach_open == struct_foreach_open)	  {	     next_s = f->obj.v.struct_val;	     next_s->num_refs += 1;	  }     }   _SLstruct_delete_struct (c->s);   c->s = next_s;   /* keep going */   return 1;}/*}}}*/static int struct_sput (unsigned char type, char *name){   _SLang_Struct_Type *s;   _SLstruct_Field_Type *f;   SLang_Object_Type obj;   (void) type;   if (-1 == _SLang_pop_struct (&s))     return -1;   if ((NULL == (f = pop_field (s, name, find_field)))       || (-1 == SLang_pop (&obj)))     {	_SLstruct_delete_struct (s);	return -1;     }   SLang_free_object (&f->obj);   f->obj = obj;   _SLstruct_delete_struct (s);   return 0;}static int struct_sget (unsigned char type, char *name){   _SLang_Struct_Type *s;   _SLstruct_Field_Type *f;   int ret;   (void) type;   if (-1 == _SLang_pop_struct (&s))     return -1;   if (NULL == (f = pop_field (s, name, find_field)))     {	_SLstruct_delete_struct (s);	return -1;     }   ret = _SLpush_slang_obj (&f->obj);   _SLstruct_delete_struct (s);   return ret;}static int struct_typecast  (unsigned char a_type, VOID_STAR ap, unsigned int na,   unsigned char b_type, VOID_STAR bp){   _SLang_Struct_Type **a, **b;   unsigned int i;   (void) a_type;   (void) b_type;

⌨️ 快捷键说明

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