📄 value.c
字号:
/*
* value.c -- Generic type (holds all types)
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* $Id: value.c,v 1.1.1.1 2004/11/23 21:37:01 sgollako Exp $
*/
/******************************** Description *********************************/
/*
* This module provides a generic type that can hold all possible types.
* It is designed to provide maximum effeciency.
*/
/********************************* Includes ***********************************/
#ifdef UEMF
#include "uemf.h"
#else
#include "basic/basicInternal.h"
#endif
/*********************************** Locals ***********************************/
#ifndef UEMF
static value_t value_null; /* All zeros */
/***************************** Forward Declarations ***************************/
static void coerce_types(value_t* v1, value_t* v2);
static int value_to_integer(value_t* vp);
#endif /*!UEMF*/
/*********************************** Code *************************************/
/*
* Initialize a integer value.
*/
value_t valueInteger(long value)
{
value_t v;
memset(&v, 0x0, sizeof(v));
v.valid = 1;
v.type = integer;
v.value.integer = value;
return v;
}
/******************************************************************************/
/*
* Initialize a string value.
*/
value_t valueString(char_t* value, int flags)
{
value_t v;
memset(&v, 0x0, sizeof(v));
v.valid = 1;
v.type = string;
if (flags & VALUE_ALLOCATE) {
v.allocated = 1;
v.value.string = gstrdup(B_L, value);
} else {
v.allocated = 0;
v.value.string = value;
}
return v;
}
/******************************************************************************/
/*
* Free any storage allocated for a value.
*/
void valueFree(value_t* v)
{
if (v->valid && v->allocated && v->type == string &&
v->value.string != NULL) {
bfree(B_L, v->value.string);
}
#ifndef UEMF
if (v->valid && v->type == symbol && v->value.symbol.data != NULL &&
v->value.symbol.freeCb !=NULL) {
v->value.symbol.freeCb(v->value.symbol.data);
}
#endif
v->type = undefined;
v->valid = 0;
v->allocated = 0;
}
#ifndef UEMF
/******************************************************************************/
/*
* Initialize an invalid value.
*/
value_t valueInvalid()
{
value_t v;
v.valid = 0;
v.type = undefined;
return v;
}
/******************************************************************************/
/*
* Initialize a flag value.
*/
value_t valueBool(int value)
{
value_t v;
memset(&v, 0x0, sizeof(v));
v.type = flag;
v.valid = 1;
v.value.flag = (char) value;
return v;
}
/******************************************************************************/
/*
* Initialize a byteint value.
*/
value_t valueByteint(char value)
{
value_t v;
memset(&v, 0x0, sizeof(v));
v.valid = 1;
v.type = byteint;
v.value.byteint = value;
return v;
}
/******************************************************************************/
/*
* Initialize a shortint value.
*/
value_t valueShortint(short value)
{
value_t v;
memset(&v, 0x0, sizeof(v));
v.valid = 1;
v.type = shortint;
v.value.shortint = value;
return v;
}
#ifdef FLOATING_POINT_SUPPORT
/******************************************************************************/
/*
* Initialize a floating value.
*/
value_t valueFloating(double value)
{
value_t v;
memset(&v, 0x0, sizeof(v));
v.valid = 1;
v.type = floating;
v.value.floating = value;
return v;
}
#endif /* FLOATING_POINT_SUPPORT */
/******************************************************************************/
/*
* Initialize a big value.
*/
value_t valueBig(long high_word, long low_word)
{
value_t v;
memset(&v, 0x0, sizeof(v));
v.valid = 1;
v.type = big;
v.value.big[BLOW] = low_word;
v.value.big[BHIGH] = high_word;
return v;
}
/******************************************************************************/
/*
* Initialize a hex value.
*/
value_t valueHex(int value)
{
value_t v;
memset(&v, 0x0, sizeof(v));
v.valid = 1;
v.type = hex;
v.value.integer = value;
return v;
}
/******************************************************************************/
/*
* Initialize a octal value.
*/
value_t valueOctal(int value)
{
value_t v;
memset(&v, 0x0, sizeof(v));
v.valid = 1;
v.type = octal;
v.value.integer = value;
return v;
}
/******************************************************************************/
/*
* Initialize a percent value.
*/
value_t valuePercent(int value)
{
value_t v;
memset(&v, 0x0, sizeof(v));
v.valid = 1;
v.type = percent;
v.value.percent = (char) value;
return v;
}
/******************************************************************************/
/*
* Initialize an byte array. Note: no allocation, just store the ptr
*/
value_t valueBytes(char* value, int flags)
{
value_t v;
memset(&v, 0x0, sizeof(v));
v.valid = 1;
v.type = bytes;
if (flags & VALUE_ALLOCATE) {
v.allocated = 1;
v.value.bytes = bstrdupA(B_L, value);
} else {
v.allocated = 0;
v.value.bytes = value;
}
return v;
}
/******************************************************************************/
/*
* Initialize a symbol value.
* Value parameter can hold a pointer to any type of value
* Free parameter can be NULL, or a function pointer to a function that will
* free the value
*/
value_t valueSymbol(void *value, freeCallback freeCb)
{
value_t v;
memset(&v, 0x0, sizeof(v));
v.valid = 1;
v.type = symbol;
v.value.symbol.data = value;
v.value.symbol.freeCb = freeCb;
return v;
}
/******************************************************************************/
/*
* Initialize an error message value.
*/
value_t valueErrmsg(char_t* value)
{
value_t v;
memset(&v, 0x0, sizeof(v));
v.valid = 1;
v.type = errmsg;
v.value.errmsg = value;
return v;
}
/******************************************************************************/
/*
* Copy a value. If the type is 'string' then allocate another string.
* Note: we allow the copy of a null value.
*/
value_t valueCopy(value_t v2)
{
value_t v1;
v1 = v2;
if (v2.valid && v2.type == string && v2.value.string != NULL) {
v1.value.string = gstrdup(B_L, v2.value.string);
v1.allocated = 1;
}
return v1;
}
/******************************************************************************/
/*
* Add a value.
*/
value_t valueAdd(value_t v1, value_t v2)
{
value_t v;
a_assert(v1.valid);
a_assert(v2.valid);
memset(&v, 0x0, sizeof(v));
v.valid = 1;
if (v1.type != v2.type)
coerce_types(&v1, &v2);
switch (v1.type) {
default:
case string:
case bytes:
a_assert(0);
break;
#ifdef FLOATING_POINT_SUPPORT
case floating:
v1.value.floating += v2.value.floating;
return v1;
#endif
case flag:
v1.value.bool |= v2.value.flag;
return v1;
case byteint:
case percent:
v1.value.byteint += v2.value.byteint;
return v1;
case shortint:
v1.value.shortint += v2.value.shortint;
return v1;
case hex:
case integer:
case octal:
v1.value.integer += v2.value.integer;
return v1;
case big:
v.type = big;
badd(v.value.big, v1.value.big, v2.value.big);
return v;
}
return v1;
}
/******************************************************************************/
/*
* Subtract a value.
*/
value_t valueSub(value_t v1, value_t v2)
{
value_t v;
a_assert(v1.valid);
a_assert(v2.valid);
memset(&v, 0x0, sizeof(v));
v.valid = 1;
if (v1.type != v2.type)
coerce_types(&v1, &v2);
switch (v1.type) {
default:
a_assert(0);
break;
#ifdef FLOATING_POINT_SUPPORT
case floating:
v1.value.floating -= v2.value.floating;
return v1;
#endif
case flag:
v1.value.flag &= v2.value.flag;
return v1;
case byteint:
case percent:
v1.value.byteint -= v2.value.byteint;
return v1;
case shortint:
v1.value.shortint -= v2.value.shortint;
return v1;
case hex:
case integer:
case octal:
v1.value.integer -= v2.value.integer;
return v1;
case big:
v.type = big;
bsub(v.value.big, v1.value.big, v2.value.big);
return v;
}
return v1;
}
/******************************************************************************/
/*
* Multiply a value.
*/
value_t valueMul(value_t v1, value_t v2)
{
value_t v;
a_assert(v1.valid);
a_assert(v2.valid);
memset(&v, 0x0, sizeof(v));
v.valid = 1;
if (v1.type != v2.type)
coerce_types(&v1, &v2);
switch (v1.type) {
default:
a_assert(0);
break;
case flag:
a_assert(v1.type != flag);
break;
#ifdef FLOATING_POINT_SUPPORT
case floating:
v1.value.floating *= v2.value.floating;
return v1;
#endif
case byteint:
case percent:
v1.value.byteint *= v2.value.byteint;
return v1;
case shortint:
v1.value.shortint *= v2.value.shortint;
return v1;
case hex:
case integer:
case octal:
v1.value.integer *= v2.value.integer;
return v1;
case big:
v.type = big;
bmul(v.value.big, v1.value.big, v2.value.big);
return v;
}
return v1;
}
/******************************************************************************/
/*
* Divide a value.
*/
value_t valueDiv(value_t v1, value_t v2)
{
value_t v;
a_assert(v1.valid);
a_assert(v2.valid);
memset(&v, 0x0, sizeof(v));
v.valid = 1;
if (v1.type != v2.type)
coerce_types(&v1, &v2);
switch (v1.type) {
default:
a_assert(0);
break;
case flag:
a_assert(v1.type != flag);
break;
#ifdef FLOATING_POINT_SUPPORT
case floating:
v1.value.floating /= v2.value.floating;
return v1;
#endif
case byteint:
case percent:
v1.value.byteint /= v2.value.byteint;
return v1;
case shortint:
v1.value.shortint /= v2.value.shortint;
return v1;
case hex:
case integer:
case octal:
v1.value.integer /= v2.value.integer;
return v1;
case big:
v.type = big;
bdiv(v.value.big, v1.value.big, v2.value.big);
return v;
}
return v1;
}
/******************************************************************************/
/*
* Compare a value.
*/
int valueCmp(value_t v1, value_t v2)
{
a_assert(v1.valid);
a_assert(v2.valid);
if (v1.type != v2.type)
coerce_types(&v1, &v2);
if (v1.type != v2.type) {
/*
* Make v2 == v1
*/
a_assert(v1.type == v2.type);
v2 = v1;
return 0;
}
switch (v1.type) {
case string:
if (v1.value.string == NULL && v2.value.string == NULL) {
return 0;
} else if (v1.value.string == NULL) {
return -1;
} else if (v2.value.string == NULL) {
return 1;
} else {
return gstrcmp(v1.value.string, v2.value.string);
}
/* Nobody here */
case flag:
if (v1.value.flag < v2.value.flag)
return -1;
else if (v1.value.flag == v2.value.flag)
return 0;
else return 1;
#ifdef FLOATING_POINT_SUPPORT
case floating:
if (v1.value.floating < v2.value.floating)
return -1;
else if (v1.value.floating == v2.value.floating)
return 0;
else return 1;
#endif
case byteint:
case percent:
if (v1.value.byteint < v2.value.byteint)
return -1;
else if (v1.value.byteint == v2.value.byteint)
return 0;
else return 1;
case shortint:
if (v1.value.shortint < v2.value.shortint)
return -1;
else if (v1.value.shortint == v2.value.shortint)
return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -