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

📄 value.cc

📁 linux 下的源代码分析阅读器 red hat公司新版
💻 CC
📖 第 1 页 / 共 5 页
字号:
// $Header$#include "system.h"#include <string.h>#include <stream.h>#include <stdlib.h>#include "Sds/sdsgen.h"#include "Glish/Value.h"#include "glish_event.h"#include "BinOpExpr.h"#include "Func.h"#include "Reporter.h"int num_Values_created = 0;int num_Values_deleted = 0;const char* type_names[NUM_GLISH_TYPES] =	{	"error", "ref", "const", "subref", "subconst",	"boolean", "byte", "short", "integer",	"float", "double", "string", "agent", "function", "record",	"complex", "dcomplex", "opaque",	};const Value* false_value;#define AGENT_MEMBER_NAME "*agent*"class SDS_ValueManager : public GlishObject {    public:	SDS_ValueManager( int sds_index )	{ sds = sds_index; }	~SDS_ValueManager()		{ 		sds_destroy( sds );		sds_discard( sds );		}    protected:	int sds;	};class DelObj : public GlishObject {public:	DelObj( GlishObject* arg_obj )	{ obj = arg_obj; ptr = 0; }	DelObj( void* arg_ptr )		{ obj = 0; ptr = arg_ptr; }	~DelObj();protected:	GlishObject* obj;	void* ptr;};DelObj::~DelObj()	{	Unref( obj );	delete ptr;	}#define DEFINE_SINGLETON_CONSTRUCTOR(constructor_type)			\Value::Value( constructor_type value )					\	{								\	InitValue();							\	SetValue( &value, 1, COPY_ARRAY );				\	}#define DEFINE_ARRAY_CONSTRUCTOR(constructor_type)			\Value::Value( constructor_type value[], int len, array_storage_type storage )\	{								\	InitValue();							\	SetValue( value, len, storage );				\	}#define DEFINE_ARRAY_REF_CONSTRUCTOR(constructor_type)			\Value::Value( constructor_type& value_ref )				\	{								\	InitValue();							\	SetValue( value_ref );						\	}#define DEFINE_CONSTRUCTORS(type,reftype)				\	DEFINE_SINGLETON_CONSTRUCTOR(type)				\	DEFINE_ARRAY_CONSTRUCTOR(type)					\	DEFINE_ARRAY_REF_CONSTRUCTOR(reftype)DEFINE_CONSTRUCTORS(glish_bool,glish_boolref)DEFINE_CONSTRUCTORS(byte,byteref)DEFINE_CONSTRUCTORS(short,shortref)DEFINE_CONSTRUCTORS(int,intref)DEFINE_CONSTRUCTORS(float,floatref)DEFINE_CONSTRUCTORS(double,doubleref)DEFINE_CONSTRUCTORS(complex,complexref)DEFINE_CONSTRUCTORS(dcomplex,dcomplexref)DEFINE_CONSTRUCTORS(charptr,charptrref)DEFINE_SINGLETON_CONSTRUCTOR(agentptr)DEFINE_SINGLETON_CONSTRUCTOR(funcptr)DEFINE_ARRAY_CONSTRUCTOR(funcptr)Value::Value( recordptr value, Agent* agent )	{	InitValue();	SetValue( value, agent );	}Value::Value( SDS_Index& value )	{	InitValue();	SetValue( value );	}Value::Value( Value* ref_value, value_type val_type )	{	InitValue();	storage = TAKE_OVER_ARRAY;	if ( val_type == VAL_CONST )		type = TYPE_CONST;	else if ( val_type == VAL_REF )		type = TYPE_REF;	else		fatal->Report( "bad value_type in Value::Value" );	if ( ref_value->IsConst() && val_type == VAL_REF )		warn->Report(			"\"ref\" reference created from \"const\" reference" );	ref_value = ref_value->Deref();	attributes = ref_value->CopyAttributePtr();	Ref( ref_value );	values = (void*) ref_value;	}Value::Value( Value* ref_value, int index[], int num_elements,		value_type val_type )	{	InitValue();	SetValue( ref_value, index, num_elements, val_type );	attributes = ref_value->CopyAttributePtr();	}void Value::TakeValue( Value* new_value )	{	new_value = new_value->Deref();	if ( new_value == this )		{		error->Report( "reference loop created" );		return;		}	DeleteValue();	int my_ref_count = ref_count;	*this = *new_value;	ref_count = my_ref_count;	new_value->type = TYPE_ERROR;	Unref( new_value );	}Value::~Value()	{	DeleteValue();	++num_Values_deleted;	}#define DEFINE_ARRAY_SET_VALUE(type, glish_type)			\void Value::SetValue( type array[], int len, array_storage_type arg_storage )\	{								\	SetType( glish_type );						\	max_size = length = len;					\	storage = arg_storage;						\	values = storage == COPY_ARRAY ? copy_values( array, type ) : array;\	}#define DEFINE_REF_SET_VALUE(reftype, glish_type)			\void Value::SetValue( reftype& value_ref )				\	{								\	SetType( glish_type );						\	max_size = length = value_ref.Length();				\	storage = COPY_ARRAY;						\	values = value_ref.DupVec();					\	}#define DEFINE_SET_VALUE(type, reftype, glish_type)			\DEFINE_ARRAY_SET_VALUE(type, glish_type)				\DEFINE_REF_SET_VALUE(reftype, glish_type)DEFINE_SET_VALUE(glish_bool,glish_boolref,TYPE_BOOL)DEFINE_SET_VALUE(byte,byteref,TYPE_BYTE)DEFINE_SET_VALUE(short,shortref,TYPE_SHORT)DEFINE_SET_VALUE(int,intref,TYPE_INT)DEFINE_SET_VALUE(float,floatref,TYPE_FLOAT)DEFINE_SET_VALUE(double,doubleref,TYPE_DOUBLE)DEFINE_SET_VALUE(complex,complexref,TYPE_COMPLEX)DEFINE_SET_VALUE(dcomplex,dcomplexref,TYPE_DCOMPLEX)DEFINE_ARRAY_SET_VALUE(agentptr,TYPE_AGENT)DEFINE_ARRAY_SET_VALUE(funcptr,TYPE_FUNC)DEFINE_REF_SET_VALUE(charptrref,TYPE_STRING)void Value::SetValue( const char* array[], int len,			array_storage_type arg_storage )	{	SetType( TYPE_STRING );	max_size = length = len;	storage = arg_storage;	if ( storage == COPY_ARRAY )		{		values = (void*) new charptr[len];		charptr* sptr = StringPtr();		for ( int i = 0; i < len; ++i )			sptr[i] = strdup( array[i] );		}	else		values = array;	}void Value::SetValue( recordptr value, Agent* agent )	{	SetType( TYPE_RECORD );	values = (void*) value;	max_size = length = 1;	storage = TAKE_OVER_ARRAY;	if ( agent )		RecordPtr()->Insert( strdup( AGENT_MEMBER_NAME ),					new Value( agent ) );	}void Value::SetValue( SDS_Index& value )	{	SetType( TYPE_OPAQUE );	values = (void*) value.Index();	max_size = length = 1;	storage = PRESERVE_ARRAY;	}void Value::SetValue( Value* ref_value, int index[], int num_elements,			value_type val_type )	{	if ( val_type == VAL_CONST )		SetType( TYPE_SUBVEC_CONST );	else if ( val_type == VAL_REF )		SetType( TYPE_SUBVEC_REF );	else		fatal->Report( "bad value_type in Value::Value" );	storage = TAKE_OVER_ARRAY;	if ( ref_value->IsConst() && val_type == VAL_REF )		warn->Report(			"\"ref\" reference created from \"const\" reference" );	ref_value = ref_value->Deref();	length = num_elements;	int max_index;	if ( ! IndexRange( index, num_elements, max_index ) )		fatal->Report( "bad index in Value::Value" );	if ( max_index > ref_value->Length() )		if ( ! ref_value->Grow( max_index ) )			return;	switch ( ref_value->Type() )		{		case TYPE_BOOL:		case TYPE_BYTE:		case TYPE_SHORT:		case TYPE_INT:		case TYPE_FLOAT:		case TYPE_DOUBLE:		case TYPE_COMPLEX:		case TYPE_DCOMPLEX:		case TYPE_STRING:		case TYPE_SUBVEC_REF:		case TYPE_SUBVEC_CONST:			values = (void*) new VecRef( ref_value, index,						num_elements, max_index );			break;		default:			fatal->Report( "bad Value in Value::Value" );		}	}void Value::InitValue()	{	type = TYPE_ERROR;	description = 0;	value_manager = 0;	attributes = 0;	++num_Values_created;	}void Value::SetType( glish_type new_type )	{	DeleteValue();	type = new_type;	}void Value::DeleteValue()	{	switch ( type )		{		case TYPE_CONST:		case TYPE_REF:			Unref( RefPtr() );			// So we don't also delete "values" ...			type = TYPE_ERROR;			break;		case TYPE_SUBVEC_CONST:		case TYPE_SUBVEC_REF:			Unref( VecRefPtr() );			type = TYPE_ERROR;			break;		case TYPE_STRING:			if ( ! value_manager && storage != PRESERVE_ARRAY )				{				charptr* sptr = StringPtr();				for ( int i = 0; i < length; ++i )					delete (char*) sptr[i];				}			break;		case TYPE_AGENT:			// Here we rely on the fact that Agent is derived			// GlishObject, which has a virtual destructor.			Unref( (GlishObject*) AgentVal() );			break;		case TYPE_RECORD:			{			delete_record( RecordPtr() );			// So we don't delete "values" again ...			type = TYPE_ERROR;			break;			}		default:			break;		}	if ( type != TYPE_ERROR )		{		if ( value_manager )			{			Unref( value_manager );			// It's important to get rid of our value_manager			// pointer here; a call to DeleteValue does not			// necessarily mean we're throwing away the entire			// Value object.  (For example, we may be called			// by SetType, called in turn by Polymorph.)  Thus			// as we're done with this value_manager, mark it			// as so.			value_manager = 0;			}		else if ( storage != PRESERVE_ARRAY )			delete values;		DeleteAttributes();		}	}void Value::DeleteAttributes()	{	Unref( attributes );	attributes = 0;	}void Value::DeleteAttribute( const Value* index )	{	char* index_string = index->StringVal();	DeleteAttribute( index_string );	delete index_string;	}void Value::DeleteAttribute( const char field[] )	{	attributeptr attr = ModAttributePtr();	if ( attr )		delete attr->Remove( field );	}int Value::IsNumeric() const	{	switch ( type )		{		case TYPE_BOOL:		case TYPE_BYTE:		case TYPE_SHORT:		case TYPE_INT:		case TYPE_FLOAT:		case TYPE_DOUBLE:		case TYPE_COMPLEX:		case TYPE_DCOMPLEX:			return 1;		case TYPE_CONST:		case TYPE_REF:		case TYPE_STRING:		case TYPE_AGENT:		case TYPE_FUNC:		case TYPE_RECORD:		case TYPE_OPAQUE:			return 0;		case TYPE_SUBVEC_CONST:		case TYPE_SUBVEC_REF:			return VecRefPtr()->Val()->IsNumeric();		case TYPE_ERROR:		default:			fatal->Report( "bad type in Value::IsNumeric()" );			return 0;	// for overly clever compilers		}	}int Value::IsAgentRecord() const	{	if ( VecRefDeref()->Type() == TYPE_RECORD &&	     (*RecordPtr())[AGENT_MEMBER_NAME] )		return 1;	else		return 0;	}#define DEFINE_CONST_ACCESSOR(name,tag,type)				\type Value::name() const						\	{								\	if ( IsVecRef() ) 						\		return ((const Value*) VecRefPtr()->Val())->name();	\	else if ( Type() != tag )					\		fatal->Report( "bad use of const accessor" );		\	return (type) values;						\	}DEFINE_CONST_ACCESSOR(BoolPtr,TYPE_BOOL,glish_bool*)DEFINE_CONST_ACCESSOR(BytePtr,TYPE_BYTE,byte*)DEFINE_CONST_ACCESSOR(ShortPtr,TYPE_SHORT,short*)DEFINE_CONST_ACCESSOR(IntPtr,TYPE_INT,int*)DEFINE_CONST_ACCESSOR(FloatPtr,TYPE_FLOAT,float*)DEFINE_CONST_ACCESSOR(DoublePtr,TYPE_DOUBLE,double*)DEFINE_CONST_ACCESSOR(ComplexPtr,TYPE_COMPLEX,complex*)DEFINE_CONST_ACCESSOR(DcomplexPtr,TYPE_DCOMPLEX,dcomplex*)DEFINE_CONST_ACCESSOR(StringPtr,TYPE_STRING,charptr*)DEFINE_CONST_ACCESSOR(FuncPtr,TYPE_FUNC,funcptr*)DEFINE_CONST_ACCESSOR(AgentPtr,TYPE_AGENT,agentptr*)DEFINE_CONST_ACCESSOR(RecordPtr,TYPE_RECORD,recordptr)#define DEFINE_ACCESSOR(name,tag,type)					\type Value::name()							\	{								\	if ( IsVecRef() ) 						\		return VecRefPtr()->Val()->name();			\	if ( Type() != tag )						\		Polymorph( tag );					\	return (type) values;						\	}DEFINE_ACCESSOR(BoolPtr,TYPE_BOOL,glish_bool*)DEFINE_ACCESSOR(BytePtr,TYPE_BYTE,byte*)DEFINE_ACCESSOR(ShortPtr,TYPE_SHORT,short*)DEFINE_ACCESSOR(IntPtr,TYPE_INT,int*)DEFINE_ACCESSOR(FloatPtr,TYPE_FLOAT,float*)DEFINE_ACCESSOR(DoublePtr,TYPE_DOUBLE,double*)DEFINE_ACCESSOR(ComplexPtr,TYPE_COMPLEX,complex*)DEFINE_ACCESSOR(DcomplexPtr,TYPE_DCOMPLEX,dcomplex*)DEFINE_ACCESSOR(StringPtr,TYPE_STRING,charptr*)DEFINE_ACCESSOR(FuncPtr,TYPE_FUNC,funcptr*)DEFINE_ACCESSOR(AgentPtr,TYPE_AGENT,agentptr*)DEFINE_ACCESSOR(RecordPtr,TYPE_RECORD,recordptr)#define DEFINE_CONST_REF_ACCESSOR(name,tag,type)			\type& Value::name() const						\	{								\	if ( ! IsVecRef() )						\		fatal->Report( "bad use of subarray reference accessor" );\	if ( VecRefPtr()->Type() != tag )				\		fatal->Report( "bad use of subarray reference accessor" );\	return *(VecRefPtr()->name());					\	}DEFINE_CONST_REF_ACCESSOR(BoolRef,TYPE_BOOL,glish_boolref)DEFINE_CONST_REF_ACCESSOR(ByteRef,TYPE_BYTE,byteref)DEFINE_CONST_REF_ACCESSOR(ShortRef,TYPE_SHORT,shortref)DEFINE_CONST_REF_ACCESSOR(IntRef,TYPE_INT,intref)DEFINE_CONST_REF_ACCESSOR(FloatRef,TYPE_FLOAT,floatref)DEFINE_CONST_REF_ACCESSOR(DoubleRef,TYPE_DOUBLE,doubleref)DEFINE_CONST_REF_ACCESSOR(ComplexRef,TYPE_COMPLEX,complexref)DEFINE_CONST_REF_ACCESSOR(DcomplexRef,TYPE_DCOMPLEX,dcomplexref)DEFINE_CONST_REF_ACCESSOR(StringRef,TYPE_STRING,charptrref)#define DEFINE_REF_ACCESSOR(name,tag,type)				\

⌨️ 快捷键说明

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