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

📄 value.cc

📁 linux 下的源代码分析阅读器 red hat公司新版
💻 CC
📖 第 1 页 / 共 5 页
字号:
							") is out of range");\					return;				\					}				\				offset_vec[i] += factor[j] * (cur-1);	\				}					\			XLATE						\			}						\									\		int is_copy;						\		type* vec = value->from_accessor( is_copy, ishape[0] );	\		type* ret = to_accessor();				\		for ( i = 0; i < ishape[0]; ++i )			\			ret[ offset_vec[i] ] = COPY_FUNC( vec[i] );	\		delete offset_vec;					\		if ( is_copy )						\			delete vec;					\		}							\		break;PICKASSIGN_ACTION(TYPE_BOOL,glish_bool,BoolPtr,CoerceToBoolArray,,)PICKASSIGN_ACTION(TYPE_BYTE,byte,BytePtr,CoerceToByteArray,,)PICKASSIGN_ACTION(TYPE_SHORT,short,ShortPtr,CoerceToShortArray,,)PICKASSIGN_ACTION(TYPE_INT,int,IntPtr,CoerceToIntArray,,)PICKASSIGN_ACTION(TYPE_FLOAT,float,FloatPtr,CoerceToFloatArray,,)PICKASSIGN_ACTION(TYPE_DOUBLE,double,DoublePtr,CoerceToDoubleArray,,)PICKASSIGN_ACTION(TYPE_COMPLEX,complex,ComplexPtr,CoerceToComplexArray,,)PICKASSIGN_ACTION(TYPE_DCOMPLEX,dcomplex,DcomplexPtr,CoerceToDcomplexArray,,)PICKASSIGN_ACTION(TYPE_STRING,charptr,StringPtr,CoerceToStringArray,strdup,)		case TYPE_SUBVEC_REF:		case TYPE_SUBVEC_CONST:			{			VecRef* ref = VecRefPtr();			Value* theVal = ref->Val();			switch ( theVal->Type() )				{#define PICKASSIGN_ACTION_XLATE						\	int err;							\	offset_vec[i] = ref->TranslateIndex( offset_vec[i], &err );	\	if ( err )							\		{							\		PICK_CLEANUP						\		delete offset_vec;					\		error->Report( "index number ", j, " (=",cur,		\			") is out of range. Sub-vector reference may be invalid" );\		return;							\		}PICKASSIGN_ACTION(TYPE_BOOL,glish_bool,BoolPtr,CoerceToBoolArray,,	PICKASSIGN_ACTION_XLATE)PICKASSIGN_ACTION(TYPE_BYTE,byte,BytePtr,CoerceToByteArray,,	PICKASSIGN_ACTION_XLATE)PICKASSIGN_ACTION(TYPE_SHORT,short,ShortPtr,CoerceToShortArray,,	PICKASSIGN_ACTION_XLATE)PICKASSIGN_ACTION(TYPE_INT,int,IntPtr,CoerceToIntArray,,	PICKASSIGN_ACTION_XLATE)PICKASSIGN_ACTION(TYPE_FLOAT,float,FloatPtr,CoerceToFloatArray,,	PICKASSIGN_ACTION_XLATE)PICKASSIGN_ACTION(TYPE_DOUBLE,double,DoublePtr,CoerceToDoubleArray,,	PICKASSIGN_ACTION_XLATE)PICKASSIGN_ACTION(TYPE_COMPLEX,complex,ComplexPtr,CoerceToComplexArray,,	PICKASSIGN_ACTION_XLATE)PICKASSIGN_ACTION(TYPE_DCOMPLEX,dcomplex,DcomplexPtr,CoerceToDcomplexArray,,	PICKASSIGN_ACTION_XLATE)PICKASSIGN_ACTION(TYPE_STRING,charptr,StringPtr,CoerceToStringArray,strdup,	PICKASSIGN_ACTION_XLATE)				default:					fatal->Report(					"bad type in Value::PickAssign" );				}			}			break;		default:			fatal->Report( "bad type in Value::PickAssign" );		}	PICK_CLEANUP	return;	}Value* Value::SubRef( const Value* index )	{	if ( VecRefDeref()->Type() == TYPE_RECORD )		{		if ( index->Type() == TYPE_STRING )			return GetOrCreateRecordElement( index );		Value* ret = NthField( index->IntVal() );		if ( ! ret )			{			error->Report( "record index (=", index->IntVal(),				") out of range (> ", Length(), ")" );			return error_value();			}		return ret;		}	int indices_are_copy;	int num_indices;	int* indices = GenerateIndices( index, num_indices, indices_are_copy );	if ( indices )		{		Value* result = TrueArrayRef( indices, num_indices );		if ( indices_are_copy )			delete indices;		return result;		}	else		return error_value();	}Value* Value::SubRef( const_value_list *args_val )	{	if ( ! IsNumeric() && VecRefDeref()->Type() != TYPE_STRING )		{		error->Report( "invalid type in subreference operation:",				this );		return error_value();		}	// Collect attributes.	const attributeptr ptr = AttributePtr();	const Value* shape_val = ptr ? (*ptr)["shape"] : 0;	if ( ! shape_val || ! shape_val->IsNumeric() )		{		warn->Report( "invalid or non-existant \"shape\" attribute" );		const Value* arg = (*args_val)[0];		if ( arg )			return SubRef( arg );		else			{			error->Report( "invalid missing argument" );			return error_value();			}		}	int shape_len = shape_val->Length();	int args_len = (*args_val).length();	if ( shape_len != args_len )		{		error->Report( "invalid number of indexes for:", this );		return error_value();		}	int shape_is_copy;	int* shape = shape_val->CoerceToIntArray( shape_is_copy, shape_len );	Value* op_val = (*ptr)["op[]"];	int* factor = new int[shape_len];	int cur_factor = 1;	int offset = 0;	int max_len = 0;	for ( int i = 0; i < args_len; ++i )		{		const Value* arg = (*args_val)[i];		if ( arg )			{			if ( ! arg->IsNumeric() )				{				error->Report( "index #", i+1, "into", this,						"is not numeric");				SUBOP_CLEANUP_1				return error_value();				}			if ( arg->length > max_len )				max_len = arg->length;			if ( max_len == 1 )				{				int ind = arg->IntVal();				if ( ind < 1 || ind > shape[i] )					{					error->Report( "index #", i+1, "into",						this, "is out of range");					SUBOP_CLEANUP_1					return error_value();					}				offset += cur_factor * (ind - 1);				}			}		else			{ // Missing subscript.			if ( shape[i] > max_len )				max_len = shape[i];			if ( max_len == 1 )				offset += cur_factor * (shape[i] - 1);			}		factor[i] = cur_factor;		cur_factor *= shape[i];		}	// Check to see if we're valid.	if ( cur_factor > Length() )		{		error->Report( "\"::shape\"/length mismatch" );		SUBOP_CLEANUP_1		return error_value();		}	if ( max_len == 1 ) 		{		SUBOP_CLEANUP_1		++offset;		return new Value( (Value*) this, &offset, 1, VAL_REF );		}	int* index_is_copy = new int[shape_len];	int** index = new int*[shape_len];	int* cur = new int[shape_len];	int* len = new int[shape_len];	int vecsize = 1;	int is_element = 1;	int spoof_dimension = 0;	for ( i = 0; i < args_len; ++i )		{		const Value* arg = (*args_val)[i];		if ( arg )			{			index[i] = GenerateIndices( arg, len[i],						index_is_copy[i], 0 );			spoof_dimension = 0;			}		else			{ // Spoof entire dimension.			len[i] = shape[i];			index[i] = new int[len[i]];			for ( int j = 0; j < len[i]; j++ )				index[i][j] = j+1;			index_is_copy[i] = 1;			spoof_dimension = 1;			}		if ( is_element && len[i] > 1 )			is_element = 0;		vecsize *= len[i];		cur[i] = 0;		if ( ! spoof_dimension )			{			for ( int j = 0; j < len[i]; ++j )				{				if ( index[i][j] >= 1 &&				     index[i][j] <= shape[i] )					continue;				if ( len[i] > 1 )					error->Report( "index #", i+1, ",",							j+1, " into ", this, 							"is out of range.");				else					error->Report( "index #", i+1, "into",						this, "is out of range.");				SUBOP_ABORT(i, error_value())				}			}		}	// Loop through filling resultant vector.	int* ret = new int[vecsize];	for ( int v = 0; v < vecsize; ++v )		{		// Calculate offset.		for ( i = 0, offset = 0; i < shape_len; ++i )			offset += factor[i] * (index[i][cur[i]] - 1);		// Set value.		ret[v] = offset + 1;		// Advance counters.		for ( i = 0; i < shape_len; ++i )			if ( ++cur[i] < len[i] )				break;			else				cur[i] = 0;		}	Value* result = new Value( (Value*) this, ret, vecsize, VAL_REF );	if ( ! is_element )		{		for ( int x = 0, z = 0; x < shape_len; ++x )			if ( len[x] > 1 )				len[z++] = len[x];		Value* len_v = new Value( len, z );		result->AssignAttribute( "shape", len_v );		if ( op_val )			result->AssignAttribute( "op[]", op_val );		}	else		delete len;	SUBOP_CLEANUP_2(shape_len)	return result;	}Value* Value::RecordRef( const Value* index ) const	{	if ( Type() != TYPE_RECORD )		{		error->Report( this, "is not a record" );		return error_value();		}	if ( index->Type() != TYPE_STRING )		{		error->Report( "non-string index in record reference:", index );		return error_value();		}	if ( index->Length() == 1 )		// Don't create a new record, just return the given element.		return copy_value( ExistingRecordElement( index ) );	recordptr new_record = create_record_dict();	charptr* indices = index->StringPtr();	int n = index->Length();	for ( int i = 0; i < n; ++i )		{		char* key = strdup( indices[i] );		new_record->Insert( key,				copy_value( ExistingRecordElement( key ) ) );		}	return new Value( new_record );	}const Value* Value::ExistingRecordElement( const Value* index ) const	{	char* index_string = index->StringVal();	const Value* result = ExistingRecordElement( index_string );	delete index_string;	return result;	}const Value* Value::ExistingRecordElement( const char* field ) const	{	if ( VecRefDeref()->Type() != TYPE_RECORD )		{		warn->Report( "operand to .", field, " is not a record" );		return false_value;		}	Value* member = (*RecordPtr())[field];	if ( ! member )		{		warn->Report( ".", field, " is not a field in", this );		return false_value;		}	else		return member;	}Value* Value::GetOrCreateRecordElement( const Value* index )	{	char* index_string = index->StringVal();	Value* result = GetOrCreateRecordElement( index_string );	delete index_string;	return result;	}Value* Value::GetOrCreateRecordElement( const char* field )	{	if ( VecRefDeref()->Type() != TYPE_RECORD )		{		warn->Report( "operand to .", field, " is not a record" );		return error_value();		}	Value* member = (*RecordPtr())[field];	if ( ! member )		{		member = new Value( glish_false );		RecordPtr()->Insert( strdup( field ), member );		}	return member;	}Value* Value::HasRecordElement( const char* field ) const	{	if ( VecRefDeref()->Type() != TYPE_RECORD )		fatal->Report( "non-record in Value::HasRecordElement" );	return (*RecordPtr())[field];	}Value* Value::Field( const Value* index )	{	char* index_string = index->StringVal();	Value* result = Field( index_string );	delete index_string;	return result;	}Value* Value::Field( const char* field )	{	if ( VecRefDeref()->Type() != TYPE_RECORD )		return 0;	Value* member = (*RecordPtr())[field];	if ( ! member )		return 0;	return member;	}Value* Value::Field( const char* field, glish_type t )	{	Value* result = Field( field );	if ( result )		result->Polymorph( t );	return result;	}Value* Value::NthField( int n )	{	if ( VecRefDeref()->Type() != TYPE_RECORD )		return 0;	Value* member = RecordPtr()->NthEntry( n - 1 );	if ( ! member )		return 0;	return member;	}const Value* Value::NthField( int n ) const	{	return ((Value*) this)->NthField( n );	}const char* Value::NthFieldName( int n ) const	{	if ( VecRefDeref()->Type() != TYPE_RECORD )		return 0;	const char* key;	Value* member = RecordPtr()->NthEntry( n - 1, key );	if ( ! member )		return 0;	return key;	}char* Value::NewFieldName()	{	if ( VecRefDeref()->Type() != TYPE_RECORD )		return 0;	static int counter = 0;	char buf[128];	do		sprintf( buf, "*%d", ++counter );	while ( Field( buf ) );	return strdup( buf );	}#define DEFINE_FIELD_VAL(tag,type,valfunc)				\int Value::FieldVal( const char* field, type& val, int num )		\	{								\	Value* result = Field( field, tag );				\	if ( ! result )							\		return 0;						\									\	val = result->valfunc( num );					\	return 1;							\	}DEFINE_FIELD_VAL(TYPE_BOOL, glish_bool, BoolVal)DEFINE_FIELD_VAL(TYPE_BYTE, byte, ByteVal)DEFINE_FIELD_VAL(TYPE_SHORT, short, ShortVal)DEFINE_FIELD_VAL(TYPE_INT, int, IntVal)DEFINE_FIELD_VAL(TYPE_FLOAT, float, FloatVal)DEFINE_FIELD_VAL(TYPE_DOUBLE, double, DoubleVal)DEFINE_FIELD_VAL(TYPE_COMPLEX, complex, ComplexVal)DEFINE_FIELD_VAL(TYPE_DCOMPLEX, dcomplex, DcomplexVal)int Value::FieldVal( const char* field, char*& val )	{	Value* result = Field( field, TYPE_STRING );	if ( ! result )		return 0;	val = result->StringVal();	return 1;	}#define DEFINE_FIELD_PTR(name,tag,type,accessor)			\type Value::name( const char* field, int& len )				\	{								\	Value* result = Field( field, tag );				\	if ( ! result )							\		return 0;						\									\	len = result->Length();						\	

⌨️ 快捷键说明

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