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

📄 value.cc

📁 linux 下的源代码分析阅读器 red hat公司新版
💻 CC
📖 第 1 页 / 共 5 页
字号:
type& Value::name()							\	{								\	if ( ! IsVecRef() )						\		fatal->Report( "bad use of subarray reference accessor" );\	if ( VecRefPtr()->Type() != tag )				\		Polymorph( tag );					\	return *(VecRefPtr()->name());					\	}DEFINE_REF_ACCESSOR(BoolRef,TYPE_BOOL,glish_boolref)DEFINE_REF_ACCESSOR(ByteRef,TYPE_BYTE,byteref)DEFINE_REF_ACCESSOR(ShortRef,TYPE_SHORT,shortref)DEFINE_REF_ACCESSOR(IntRef,TYPE_INT,intref)DEFINE_REF_ACCESSOR(FloatRef,TYPE_FLOAT,floatref)DEFINE_REF_ACCESSOR(DoubleRef,TYPE_DOUBLE,doubleref)DEFINE_REF_ACCESSOR(ComplexRef,TYPE_COMPLEX,complexref)DEFINE_REF_ACCESSOR(DcomplexRef,TYPE_DCOMPLEX,dcomplexref)DEFINE_REF_ACCESSOR(StringRef,TYPE_STRING,charptrref)#define XXX_VAL(name, val_type, rhs_elm, text_func, type_name, zero)	\val_type Value::name( int n ) const					\	{								\	if ( IsRef() )							\		return Deref()->name( n );				\									\	if ( length < 1 )						\		{							\		error->Report( "empty array converted to ", type_name );\		return zero;						\		}							\									\	if ( n < 1 || n > length )					\		{							\		error->Report( "in conversion to ", type_name, " index (=", n,\				") out of bounds, length =", length );	\		return zero;						\		}							\									\	switch ( type )							\		{							\		case TYPE_BOOL:						\			return val_type( BoolPtr()[n - 1] ? 1 : 0 );	\									\		case TYPE_BYTE:						\			return val_type( BytePtr()[n - 1] );		\									\		case TYPE_SHORT:					\			return val_type( ShortPtr()[n - 1] );		\									\		case TYPE_INT:						\			return val_type( IntPtr()[n - 1] );		\									\		case TYPE_FLOAT:					\			return val_type( FloatPtr()[n - 1] );		\									\		case TYPE_DOUBLE:					\			return val_type( DoublePtr()[n - 1] );		\									\		case TYPE_COMPLEX:					\			return val_type( ComplexPtr()[n - 1] rhs_elm );	\									\		case TYPE_DCOMPLEX:					\			return val_type( DcomplexPtr()[n - 1] rhs_elm );\									\		case TYPE_STRING:					\			{						\			int successful;				\			val_type result = val_type(			\				text_func( StringPtr()[n - 1], successful ) );\									\			if ( ! successful )				\				warn->Report( "string \"", this,	\					"\" converted to ", type_name );\			return result;					\			}						\									\		case TYPE_AGENT:					\		case TYPE_FUNC:						\		case TYPE_RECORD:					\		case TYPE_OPAQUE:					\			error->Report( "bad type", type_names[Type()],	\				"converted to ", type_name, ":", this );\			return zero;					\									\		case TYPE_SUBVEC_CONST:					\		case TYPE_SUBVEC_REF:					\			{						\			VecRef* ref = VecRefPtr();			\			int err;					\			int off = ref->TranslateIndex( n-1, &err );	\			if ( err )					\				{					\				error->Report( "bad sub-vector subscript" );\				return zero;				\			}						\			return ref->Val()->name( off );			\			}						\									\		default:						\			fatal->Report( "bad type in Value::XXX_VAL()" );\			return zero;					\		}							\	}XXX_VAL(BoolVal, glish_bool, .r, text_to_integer, "bool", glish_false)XXX_VAL(ByteVal, byte, .r, text_to_integer, "byte", 0)XXX_VAL(ShortVal, short, .r, text_to_integer, "short", 0)XXX_VAL(IntVal, int, .r, text_to_integer, "integer", 0)XXX_VAL(FloatVal, float, .r, text_to_double, "float", 0.0)XXX_VAL(DoubleVal, double, .r, text_to_double, "double", 0.0)XXX_VAL(ComplexVal, complex,, text_to_dcomplex, "complex", complex(0.0, 0.0))XXX_VAL(DcomplexVal, dcomplex,, text_to_dcomplex, "dcomplex",	dcomplex(0.0, 0.0))static void append_buf( char* &buf, char* &buf_ptr, unsigned int& buf_size,		const char* a = 0, const char* b = 0, const char* c = 0 )	{	a = a ? a : "";	b = b ? b : "";	c = c ? c : "";	int buf_remaining = &buf[buf_size] - buf_ptr;	int size_of_addition = strlen( a ) + strlen( b ) + strlen( c );	while ( size_of_addition >= buf_remaining - 5 /* slop */ )		{ // Need to grow the buffer.		int buf_ptr_offset = buf_ptr - buf;		buf_size *= 2;		buf = (char*) realloc_memory( (void*) buf, buf_size );		if ( ! buf )			fatal->Report( "out of memory in append_buf()" );		buf_ptr = buf + buf_ptr_offset;		buf_remaining = &buf[buf_size] - buf_ptr;		}	*buf_ptr = '\0';	strcat( buf_ptr, a );	strcat( buf_ptr, b );	strcat( buf_ptr, c );	buf_ptr += size_of_addition;	}char* Value::StringVal( char sep, int useAttributes ) const	{	if ( IsRef() )		return Deref()->StringVal( sep, useAttributes );	if ( type == TYPE_RECORD )		return RecordStringVal();	if ( type == TYPE_AGENT )		return strdup( "<agent>" );	if ( type == TYPE_FUNC )		return strdup( "<function>" );	if ( type == TYPE_OPAQUE )		return strdup( "<opaque>" );	if ( length == 0 )		return strdup( "" );	unsigned int buf_size;	// Make a guess as to a probable good size for buf.	if ( type == TYPE_STRING )		{		buf_size = strlen( StringPtr()[0] ) * (length + 1);		if ( buf_size == 0 )			buf_size = 8;		}	else if ( type == TYPE_COMPLEX  || type == TYPE_DCOMPLEX )		buf_size = length * 16 * 2 + 1;	else if ( type == TYPE_FLOAT  || type == TYPE_DOUBLE )		buf_size = length * 16;	else		buf_size = length * 8;	char* buf = new char[buf_size];	if ( ! buf )		fatal->Report( "out of memory in Value::StringVal()" );	char* buf_ptr = buf;	if ( type != TYPE_STRING && length > 1 )		{		// Insert []'s around value.		*buf_ptr++ = '[';		}	glish_bool* bool_ptr;	byte* byte_ptr;	short* short_ptr;	int* int_ptr;	float* float_ptr;	double* double_ptr;	complex* complex_ptr;	dcomplex* dcomplex_ptr;	charptr* string_ptr;	switch ( VecRefDeref()->type )		{#define ASSIGN_PTR(tag,ptr_name,source)					\	case tag:							\		ptr_name = source;					\		break;		ASSIGN_PTR(TYPE_BOOL,bool_ptr,BoolPtr())		ASSIGN_PTR(TYPE_INT,int_ptr,IntPtr())		ASSIGN_PTR(TYPE_BYTE,byte_ptr,BytePtr())		ASSIGN_PTR(TYPE_SHORT,short_ptr,ShortPtr())		ASSIGN_PTR(TYPE_FLOAT,float_ptr,FloatPtr())		ASSIGN_PTR(TYPE_DOUBLE,double_ptr,DoublePtr())		ASSIGN_PTR(TYPE_COMPLEX,complex_ptr,ComplexPtr())		ASSIGN_PTR(TYPE_DCOMPLEX,dcomplex_ptr,DcomplexPtr())		ASSIGN_PTR(TYPE_STRING,string_ptr,StringPtr())		default:			fatal->Report( "bad type in Value::StringVal()" );		}// Macro to generate the text corresponding to a single element of a given type.#define PLACE_ELEMENT_ACTION(buffer,str_buffer,indx)			\	case TYPE_BOOL:							\		strcpy( buffer, bool_ptr[indx] ? "T" : "F" );		\		break;							\									\	case TYPE_BYTE:							\		sprintf( buffer, "%d", byte_ptr[indx] );		\		break;							\									\	case TYPE_SHORT:						\		sprintf( buffer, "%d", short_ptr[indx] );		\		break;							\									\	case TYPE_INT:							\		sprintf( buffer, "%d", int_ptr[indx] );			\		break;							\									\	case TYPE_FLOAT:						\		sprintf( buffer, "%g", float_ptr[indx] );		\		break;							\									\	case TYPE_DOUBLE:						\		sprintf( buffer, "%g", double_ptr[indx] );		\		break;							\									\	case TYPE_COMPLEX:						\		sprintf( buffer, complex_ptr[indx].i >= 0.0 ? 		\				"%g+%gi" : "%g%gi", complex_ptr[indx].r,\				complex_ptr[indx].i );			\		break;							\									\	case TYPE_DCOMPLEX:						\		sprintf( buffer, dcomplex_ptr[indx].i >= 0.0 ?		\				"%g+%gi":"%g%gi",dcomplex_ptr[indx].r,	\				dcomplex_ptr[indx].i);			\		break;							\									\	case TYPE_STRING:						\		str_buffer = string_ptr[ indx ];			\		break;// Generate text for an element, translating subref indices if needed.#define PLACE_ELEMENT(buffer,str_buffer,indx,alloced)			\	switch ( type )							\		{							\		PLACE_ELEMENT_ACTION(buffer,str_buffer,indx)		\									\		case TYPE_SUBVEC_REF:					\		case TYPE_SUBVEC_CONST:					\			{						\			VecRef* ref = VecRefPtr();			\			int err;					\			int index = ref->TranslateIndex( indx, &err );	\			if ( err )					\				{					\				error->Report( "invalid sub-vector" );	\				delete alloced;				\				return strdup( "error" );		\				}					\			switch ( ref->Type() )				\				{					\				PLACE_ELEMENT_ACTION(buffer,str_buffer,index)\									\				default:				\					fatal->Report(			\				    "bad type in Value::StringVal()" ); \				} 					\			}						\			break;						\									\		default:						\			fatal->Report(					\			    "bad type in Value::StringVal()" );		\		}	char numeric_buf[256];	const attributeptr attr = AttributePtr();	const Value* shape_val;	int shape_len;	if ( ! useAttributes || ! attr || ! (shape_val = (*attr)["shape"]) || 	     ! shape_val->IsNumeric() ||	     (shape_len = shape_val->Length()) <= 1 )		{ // not an n-D array.		for ( int i = 0; i < length; ++i )			{			const char* addition = numeric_buf;			PLACE_ELEMENT(numeric_buf, addition, i, buf);			append_buf( buf, buf_ptr, buf_size, addition );			if ( i < length - 1 )				// More to come.				*buf_ptr++ = sep;			}		if ( type != TYPE_STRING && length > 1 )			{			// Insert []'s around value.			*buf_ptr++ = ']';			*buf_ptr = '\0';			}		return buf;		}	// Okay, from this point on it's an n-D array.	static char indent[] = "    ";	// Later the pivots for outputting by planes can be made variable	int r = 0;	int c = 1;	int shape_is_copy = 0;	int* shape = shape_val->CoerceToIntArray( shape_is_copy, shape_len );	// Store for setting up a plane in advance to get the proper	// spacing for the columns.  Note that these and the arrays	// created just below are static, so we don't free them on exit.	static int column_width_len = 64;	static int* column_width = new int[column_width_len];	// Arrays for iterating through the matrix.	static int indices_len = 32;	static int* indices = new int[indices_len];	static int* factor = new int[indices_len];	// Resize arrays as necessary.	while ( shape[c] > column_width_len )		{		column_width_len *= 2;		column_width = (int*) realloc_memory( (void*) column_width,					column_width_len * sizeof(int) );		if ( ! column_width )			fatal->Report( "out of memory in Value::StringVal()" );		}	while ( shape_len > indices_len )		{		indices_len *= 2;		indices = (int*) realloc_memory( (void*) indices,						indices_len * sizeof(int) );		factor = (int*) realloc_memory( (void*) factor,					indices_len * sizeof(int) );		if ( ! indices || ! factor )			fatal->Report( "out of memory in Value::StringVal()" );		}	// Calculate the size and the offset for the columns.	int size = 1;	int offset = 0;	for ( int i = 0; i < shape_len; ++i )		{		indices[i] = 0;		factor[i] = size;		size *= shape[i];		}	// Check to see if the vector length and the shape jive.	if ( size > length ) 		{		warn->Report( "\"::shape\"/length mismatch" );		delete buf;		if ( shape_is_copy )			delete shape;		return StringVal( sep, 0 );		}	int max_free = shape_len-1;	if ( shape_len > 2 )		for ( max_free = shape_len-1; max_free > 0; --max_free )			if ( max_free != r && max_free != c )				break;	while ( indices[max_free] < shape[max_free] )		{		// Output the plane label		for ( i = 0; i < shape_len; ++i )			{			if ( i == r )				sprintf( numeric_buf, "1:%d", shape[r] );			else if ( i != c )				sprintf( numeric_buf, "%d", indices[i] + 1 );			else				numeric_buf[0] = '\0';			if ( i < shape_len - 1 )				strcat( numeric_buf, "," );			else				strcat( numeric_buf, "]\n" );			append_buf( buf, buf_ptr, buf_size, i==0 ? "[" : 0,					numeric_buf );			}		// Calculate column widths.		for ( indices[r] = 0; indices[r] < shape[r]; ++indices[r] )			for ( indices[c] = 0; indices[c] < shape[c] - 1;			      ++indices[c] )				{				for ( i = 0, offset = 0; i < shape_len; ++i )					offset += factor[i] * indices[i];				char store[256];				const char* addition = store;				PLACE_ELEMENT(store,addition,offset,buf)				int add_len = strlen( addition );				if ( add_len > column_width[indices[c]] || 				     indices[r] == 0 )					column_width[indices[c]] = add_len;				}		// Output plane.		for ( indices[r] = 0; indices[r] < shape[r]; ++indices[r] )			{			for ( indices[c] = 0; indices[c] < shape[c];			      ++indices[c] )				{				for ( i = 0, offset = 0; i < shape_len; ++i )					offset += factor[i] * indices[i];				const char* addition = numeric_buf;				PLACE_ELEMENT(numeric_buf,addition,offset,buf);				char affix[256];				if ( indices[c] < shape[c] - 1 )					{					int n = column_width[indices[c]] -						strlen( addition ) + 1;					for ( i = 0; i < n; ++i )						affix[i] = ' ';					affix[i] = '\0';					}				else if ( offset != size - 1 )					{					affix[0] = '\n';					affix[1] = '\0';					}				else					affix[0] = '\0';				append_buf( buf, buf_ptr, buf_size,						indices[c] == 0 ? indent : 0,						addition, affix );				}			}		// Increment counters.		for ( i = 0; i <= max_free; ++i )			{			if ( i == r || i == c )				continue;			else if ( ++indices[i] < shape[i] )				break;			else if ( i != max_free )				indices[i] = 0;			}		}	if ( shape_is_copy )		delete shape;	append_buf( buf, buf_ptr, buf_size, "]" );	return buf;	}char* Value::RecordStringVal() const	{	if ( VecRefDeref()->Type() != TYPE_RECORD )		fatal->Report( "non-record type in Value::RecordStringVal()" );	recordptr rptr = RecordPtr();	int len = rptr->Length();	if ( len == 0 )		return strdup( "[=]" );	const char** key_strs = new const char*[len];	char** element_strs = new char*[len];	int total_len = 0;	for ( int i = 0; i < len; ++i )		{		Value* nth_val = rptr->NthEntry( i, key_strs[i] );		if ( ! nth_val )			fatal->Report(				"bad record in Value::RecordStringVal()" );		element_strs[i] = nth_val->StringVal();		total_len += strlen( element_strs[i] ) + strlen( key_strs[i] );		}	// We generate a result of the form [key1=val1, key2=val2, ...],	// so in addition to room for the keys and values we need 3 extra	// characters per element (for the '=', ',', and ' '), 2 more for	// the []'s (we could steal these from the last element since it	// doesn't have a ", " at the end of it, but that seems a bit	// evil), and 1 more for the end-of-string.	char* result = new char[total_len + 3 * len + 3];	strcpy( result, "[" );	for ( i = 0; i < len; ++i )		{

⌨️ 快捷键说明

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