informix.c

来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 1,014 行 · 第 1/2 页

C
1,014
字号
#include <stdlib.h>#include <string.h>#include <errno.h>#include <math.h>#include <ctype.h>#include <limits.h>#include <ecpgtype.h>#include <ecpg_informix.h>#include <pgtypes_error.h>#include <pgtypes_date.h>#include <pgtypes_numeric.h>#include <sqltypes.h>char       *ECPGalloc(long, int);static intdeccall2(decimal * arg1, decimal * arg2, int (*ptr) (numeric *, numeric *)){	numeric    *a1,			   *a2;	int			i;	if ((a1 = PGTYPESnumeric_new()) == NULL)		return ECPG_INFORMIX_OUT_OF_MEMORY;	if ((a2 = PGTYPESnumeric_new()) == NULL)	{		PGTYPESnumeric_free(a1);		return ECPG_INFORMIX_OUT_OF_MEMORY;	}	if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)	{		PGTYPESnumeric_free(a1);		PGTYPESnumeric_free(a2);		return ECPG_INFORMIX_OUT_OF_MEMORY;	}	if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)	{		PGTYPESnumeric_free(a1);		PGTYPESnumeric_free(a2);		return ECPG_INFORMIX_OUT_OF_MEMORY;	}	i = (*ptr) (a1, a2);	PGTYPESnumeric_free(a1);	PGTYPESnumeric_free(a2);	return (i);}static intdeccall3(decimal * arg1, decimal * arg2, decimal * result, int (*ptr) (numeric *, numeric *, numeric *)){	numeric    *a1,			   *a2,			   *nres;	int			i;	/* we must NOT set the result to NULL here because it may be the same variable as one of the arguments */	if (risnull(CDECIMALTYPE, (char *) arg1) || risnull(CDECIMALTYPE, (char *) arg2))		return 0;	if ((a1 = PGTYPESnumeric_new()) == NULL)		return ECPG_INFORMIX_OUT_OF_MEMORY;	if ((a2 = PGTYPESnumeric_new()) == NULL)	{		PGTYPESnumeric_free(a1);		return ECPG_INFORMIX_OUT_OF_MEMORY;	}	if ((nres = PGTYPESnumeric_new()) == NULL)	{		PGTYPESnumeric_free(a1);		PGTYPESnumeric_free(a2);		return ECPG_INFORMIX_OUT_OF_MEMORY;	}	if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)	{		PGTYPESnumeric_free(a1);		PGTYPESnumeric_free(a2);		PGTYPESnumeric_free(nres);		return ECPG_INFORMIX_OUT_OF_MEMORY;	}	if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)	{		PGTYPESnumeric_free(a1);		PGTYPESnumeric_free(a2);		PGTYPESnumeric_free(nres);		return ECPG_INFORMIX_OUT_OF_MEMORY;	}	i = (*ptr) (a1, a2, nres);	if (i == 0)					/* No error */	{				/* set the result to null in case it errors out later */		rsetnull(CDECIMALTYPE, (char *) result);		PGTYPESnumeric_to_decimal(nres, result);	}		PGTYPESnumeric_free(nres);	PGTYPESnumeric_free(a1);	PGTYPESnumeric_free(a2);	return (i);}/* we start with the numeric functions */intdecadd(decimal * arg1, decimal * arg2, decimal * sum){	deccall3(arg1, arg2, sum, PGTYPESnumeric_add);	if (errno == PGTYPES_NUM_OVERFLOW)		return ECPG_INFORMIX_NUM_OVERFLOW;	else if (errno != 0)		return ECPG_INFORMIX_NUM_UNDERFLOW;	else		return 0;}intdeccmp(decimal * arg1, decimal * arg2){	return (deccall2(arg1, arg2, PGTYPESnumeric_cmp));}voiddeccopy(decimal * src, decimal * target){	memcpy(target, src, sizeof(decimal));}static char *ecpg_strndup(const char *str, size_t len){	int			real_len = strlen(str);	int			use_len = (real_len > len) ? len : real_len;	char	   *new = malloc(use_len + 1);	if (new)	{		memcpy(new, str, use_len);		new[use_len] = '\0';	}	else		errno = ENOMEM;	return new;}intdeccvasc(char *cp, int len, decimal * np){	char	   *str = ecpg_strndup(cp, len); /* decimal_in always converts the										 * complete string */	int			ret = 0;	numeric    *result;	rsetnull(CDECIMALTYPE, (char *) np);	if (risnull(CSTRINGTYPE, cp))		return 0;	if (!str)		ret = ECPG_INFORMIX_NUM_UNDERFLOW;	else	{		result = PGTYPESnumeric_from_asc(str, NULL);		if (!result)		{			switch (errno)			{				case PGTYPES_NUM_OVERFLOW:					ret = ECPG_INFORMIX_NUM_OVERFLOW;					break;				case PGTYPES_NUM_BAD_NUMERIC:					ret = ECPG_INFORMIX_BAD_NUMERIC;					break;				default:					ret = ECPG_INFORMIX_BAD_EXPONENT;					break;			}		}		else		{			if (PGTYPESnumeric_to_decimal(result, np) != 0)				ret = ECPG_INFORMIX_NUM_OVERFLOW;			free(result);		}	}	free(str);	return ret;}intdeccvdbl(double dbl, decimal * np){	numeric    *nres = PGTYPESnumeric_new();	int			result = 1;	rsetnull(CDECIMALTYPE, (char *) np);	if (risnull(CDOUBLETYPE, (char *) &dbl))		return 0;	if (nres == NULL)		return ECPG_INFORMIX_OUT_OF_MEMORY;	result = PGTYPESnumeric_from_double(dbl, nres);	if (result == 0)		result = PGTYPESnumeric_to_decimal(nres, np);	PGTYPESnumeric_free(nres);	return (result);}intdeccvint(int in, decimal * np){	numeric    *nres = PGTYPESnumeric_new();	int			result = 1;	rsetnull(CDECIMALTYPE, (char *) np);	if (risnull(CINTTYPE, (char *) &in))		return 0;	if (nres == NULL)		return ECPG_INFORMIX_OUT_OF_MEMORY;	result = PGTYPESnumeric_from_int(in, nres);	if (result == 0)		result = PGTYPESnumeric_to_decimal(nres, np);	PGTYPESnumeric_free(nres);	return (result);}intdeccvlong(long lng, decimal * np){	numeric    *nres = PGTYPESnumeric_new();	int			result = 1;	rsetnull(CDECIMALTYPE, (char *) np);	if (risnull(CLONGTYPE, (char *) &lng))		return 0;	if (nres == NULL)		return ECPG_INFORMIX_OUT_OF_MEMORY;	result = PGTYPESnumeric_from_long(lng, nres);	if (result == 0)		result = PGTYPESnumeric_to_decimal(nres, np);	PGTYPESnumeric_free(nres);	return (result);}intdecdiv(decimal * n1, decimal * n2, decimal * result){		int			i;	i = deccall3(n1, n2, result, PGTYPESnumeric_div);	if (i != 0)		switch (errno)		{			case PGTYPES_NUM_DIVIDE_ZERO:				return ECPG_INFORMIX_DIVIDE_ZERO;				break;			case PGTYPES_NUM_OVERFLOW:				return ECPG_INFORMIX_NUM_OVERFLOW;				break;			default:				return ECPG_INFORMIX_NUM_UNDERFLOW;				break;		}	return 0;}intdecmul(decimal * n1, decimal * n2, decimal * result){	int			i;		i = deccall3(n1, n2, result, PGTYPESnumeric_mul);	if (i != 0)		switch (errno)		{			case PGTYPES_NUM_OVERFLOW:				return ECPG_INFORMIX_NUM_OVERFLOW;				break;			default:				return ECPG_INFORMIX_NUM_UNDERFLOW;				break;		}	return 0;}intdecsub(decimal * n1, decimal * n2, decimal * result){	int			i;		i = deccall3(n1, n2, result, PGTYPESnumeric_sub);	if (i != 0)		switch (errno)		{			case PGTYPES_NUM_OVERFLOW:				return ECPG_INFORMIX_NUM_OVERFLOW;				break;			default:				return ECPG_INFORMIX_NUM_UNDERFLOW;				break;		}	return 0;}intdectoasc(decimal * np, char *cp, int len, int right){	char	   *str;	numeric    *nres = PGTYPESnumeric_new();	if (nres == NULL)		return ECPG_INFORMIX_OUT_OF_MEMORY;	rsetnull(CSTRINGTYPE, (char *) cp);	if (risnull(CDECIMALTYPE, (char *) np))		return 0;	if (PGTYPESnumeric_from_decimal(np, nres) != 0)		return ECPG_INFORMIX_OUT_OF_MEMORY;	if (right >= 0)		str = PGTYPESnumeric_to_asc(nres, right);	else		str = PGTYPESnumeric_to_asc(nres, nres->dscale);	PGTYPESnumeric_free(nres);	if (!str)		return -1;	/*	 * TODO: have to take care of len here and create exponatial notion if	 * necessary	 */	strncpy(cp, str, len);	free(str);	return 0;}intdectodbl(decimal * np, double *dblp){	numeric    *nres = PGTYPESnumeric_new();	int			i;	if (nres == NULL)		return ECPG_INFORMIX_OUT_OF_MEMORY;	if (PGTYPESnumeric_from_decimal(np, nres) != 0)		return ECPG_INFORMIX_OUT_OF_MEMORY;	i = PGTYPESnumeric_to_double(nres, dblp);	PGTYPESnumeric_free(nres);	return i;}intdectoint(decimal * np, int *ip){	int			ret;	numeric    *nres = PGTYPESnumeric_new();	if (nres == NULL)		return ECPG_INFORMIX_OUT_OF_MEMORY;	if (PGTYPESnumeric_from_decimal(np, nres) != 0)		return ECPG_INFORMIX_OUT_OF_MEMORY;	ret = PGTYPESnumeric_to_int(nres, ip);	if (ret == PGTYPES_NUM_OVERFLOW)		ret = ECPG_INFORMIX_NUM_OVERFLOW;	return ret;}intdectolong(decimal * np, long *lngp){	int			ret;	numeric    *nres = PGTYPESnumeric_new();;	if (nres == NULL)		return ECPG_INFORMIX_OUT_OF_MEMORY;	if (PGTYPESnumeric_from_decimal(np, nres) != 0)		return ECPG_INFORMIX_OUT_OF_MEMORY;	ret = PGTYPESnumeric_to_long(nres, lngp);	if (ret == PGTYPES_NUM_OVERFLOW)		ret = ECPG_INFORMIX_NUM_OVERFLOW;	return ret;}/* Now the date functions */intrdatestr(date d, char *str){	char	   *tmp = PGTYPESdate_to_asc(d);	if (!tmp)		return ECPG_INFORMIX_DATE_CONVERT;	/* move to user allocated buffer */	strcpy(str, tmp);	free(tmp);	return 0;}/*** the input for this function is mmddyyyy and any non-numeric* character can be used as a separator**/intrstrdate(char *str, date * d){	date		dat;	char strbuf[10];	int i,j;	rsetnull(CDATETYPE, (char *)&dat);		/* 	* we have to flip the year month date around for postgres	* expects yyyymmdd	*	*/		for (i=0,j=0; i < 10; i++ )	{		/* ignore non-digits */		if ( isdigit((unsigned char) str[i]) )		{						/* j only increments if it is a digit */			switch(j)			{				/* stick the month into the 4th, 5th position */				case 0:				case 1:					strbuf[j+4] = str[i];					break;				/* stick the day into the 6th, and 7th position */				case 2:				case 3:					strbuf[j+4] = str[i];					break;				/* stick the year into the first 4 positions */				case 4:				case 5:				case 6:				case 7:					strbuf[j-4] = str[i];					break;							}			j++;		} 	}		strbuf[8] = '\0';	dat = PGTYPESdate_from_asc(strbuf, NULL);	if (errno && errno != PGTYPES_DATE_BAD_DATE)		return ECPG_INFORMIX_BAD_DATE;	*d = dat;	return 0;}void

⌨️ 快捷键说明

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