1 /* Processed by ecpg (regression mode) */
2 /* These include files are added by the preprocessor */
3 #include <ecpglib.h>
4 #include <ecpgerrno.h>
5 #include <sqlca.h>
6 /* Needed for informix compatibility */
7 #include <ecpg_informix.h>
8 /* End of automatic include section */
9 #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
10 
11 #line 1 "dec_test.pgc"
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <pgtypes_numeric.h>
15 #include <pgtypes_error.h>
16 #include <decimal.h>
17 #include <sqltypes.h>
18 
19 
20 #line 1 "regression.h"
21 
22 
23 
24 
25 
26 
27 #line 8 "dec_test.pgc"
28 
29 
30 
31 #line 1 "printf_hack.h"
32 /*
33  * print_double(x) has the same effect as printf("%g", x), but is intended
34  * to produce the same formatting across all platforms.
35  */
fmt_xm_read_info(dmoz_file_t * file,const uint8_t * data,size_t length)36 static void
37 print_double(double x)
38 {
39 #ifdef WIN32
40 	/* Change Windows' 3-digit exponents to look like everyone else's */
41 	char		convert[128];
42 	int			vallen;
43 
44 	sprintf(convert, "%g", x);
45 	vallen = strlen(convert);
46 
47 	if (vallen >= 6 &&
48 		convert[vallen - 5] == 'e' &&
49 		convert[vallen - 3] == '0')
50 	{
51 		convert[vallen - 3] = convert[vallen - 2];
52 		convert[vallen - 2] = convert[vallen - 1];
53 		convert[vallen - 1] = '\0';
54 	}
55 
56 	printf("%s", convert);
57 #else
58 	printf("%g", x);
59 #endif
60 }
61 
62 #line 10 "dec_test.pgc"
63 
64 
65 
66 /*
67 TODO:
68 	deccmp => DECUNKNOWN
69 	decimal point: , and/or . ?
70 	ECPG_INFORMIX_BAD_EXPONENT ?
71 */
72 
73 char* decs[] = { "2E394", "-2", ".794", "3.44", "592.49E21", "-32.84e4",
74 				 "2E-394", ".1E-2", "+.0", "-592.49E-07", "+32.84e-4",
75 				 ".500001", "-.5000001",
76 				 "1234567890123456789012345678.91", /* 30 digits should fit
77 				                                       into decimal */
load_xm_patterns(song_t * song,struct xm_file_header * hdr,slurp_t * fp)78 				 "1234567890123456789012345678.921", /* 31 digits should NOT
79 				                                        fit into decimal */
80 				 "not a number",
81 				 NULL};
82 
83 
84 static void
85 check_errno(void);
86 
87 #define BUFSIZE 200
88 
89 int
90 main(void)
91 {
92 	decimal *dec, *din;
93 	char buf[BUFSIZE];
94 	long l;
95 	int i, j, k, q, r, count = 0;
96 	double dbl;
97 	decimal **decarr = (decimal **) calloc(1, sizeof(decimal));
98 
99 	ECPGdebug(1, stderr);
100 
101 	for (i = 0; decs[i]; i++)
102 	{
103 		dec = PGTYPESdecimal_new();
104 		r = deccvasc(decs[i], strlen(decs[i]), dec);
105 		if (r)
106 		{
107 			check_errno();
108 			printf("dec[%d,0]: r: %d\n", i, r);
109 			PGTYPESdecimal_free(dec);
110 			continue;
111 		}
112 		decarr = realloc(decarr, sizeof(decimal *) * (count + 1));
113 		decarr[count++] = dec;
114 
115 		r = dectoasc(dec, buf, BUFSIZE-1, -1);
116 		if (r < 0) check_errno();
117 		printf("dec[%d,1]: r: %d, %s\n", i, r, buf);
118 
119 		r = dectoasc(dec, buf, BUFSIZE-1, 0);
120 		if (r < 0) check_errno();
121 		printf("dec[%d,2]: r: %d, %s\n", i, r, buf);
122 		r = dectoasc(dec, buf, BUFSIZE-1, 1);
123 		if (r < 0) check_errno();
124 		printf("dec[%d,3]: r: %d, %s\n", i, r, buf);
125 		r = dectoasc(dec, buf, BUFSIZE-1, 2);
126 		if (r < 0) check_errno();
127 		printf("dec[%d,4]: r: %d, %s\n", i, r, buf);
128 
129 		din = PGTYPESdecimal_new();
130 		r = dectoasc(din, buf, BUFSIZE-1, 2);
131 		if (r < 0) check_errno();
132 		printf("dec[%d,5]: r: %d, %s\n", i, r, buf);
133 
134 		r = dectolong(dec, &l);
135 		if (r) check_errno();
136 		printf("dec[%d,6]: %ld (r: %d)\n", i, r?0L:l, r);
137 		if (r == 0)
138 		{
139 			r = deccvlong(l, din);
140 			if (r) check_errno();
141 			dectoasc(din, buf, BUFSIZE-1, 2);
142 			q = deccmp(dec, din);
143 			printf("dec[%d,7]: %s (r: %d - cmp: %d)\n", i, buf, r, q);
144 		}
145 
146 		r = dectoint(dec, &k);
147 		if (r) check_errno();
148 		printf("dec[%d,8]: %d (r: %d)\n", i, r?0:k, r);
149 		if (r == 0)
150 		{
151 			r = deccvint(k, din);
152 			if (r) check_errno();
153 			dectoasc(din, buf, BUFSIZE-1, 2);
154 			q = deccmp(dec, din);
155 			printf("dec[%d,9]: %s (r: %d - cmp: %d)\n", i, buf, r, q);
156 		}
157 
158 		if (i != 6)
159 		{
160 			/* underflow does not work reliable on several archs, so not testing it here */
161 			/* this is a libc problem since we only call strtod() */
162 			r = dectodbl(dec, &dbl);
163 			if (r) check_errno();
164 			printf("dec[%d,10]: ", i);
165 			print_double(r ? 0.0 : dbl);
166 			printf(" (r: %d)\n", r);
167 		}
168 
169 		PGTYPESdecimal_free(din);
170 		printf("\n");
171 	}
172 
173 	/* add a NULL value */
174 	dec = PGTYPESdecimal_new();
175 	decarr = realloc(decarr, sizeof(decimal *) * (count + 1));
176 	decarr[count++] = dec;
177 
178 	rsetnull(CDECIMALTYPE, (char *) decarr[count-1]);
179 	printf("dec[%d]: %sNULL\n", count-1,
180 		risnull(CDECIMALTYPE, (char *) decarr[count-1]) ? "" : "NOT ");
181 	printf("dec[0]: %sNULL\n",
182 		risnull(CDECIMALTYPE, (char *) decarr[0]) ? "" : "NOT ");
183 
184 	r = dectoasc(decarr[3], buf, -1, -1);
185 	check_errno(); printf("dectoasc with len == -1: r: %d\n", r);
186 	r = dectoasc(decarr[3], buf, 0, -1);
187 	check_errno(); printf("dectoasc with len == 0: r: %d\n", r);
188 
189 	for (i = 0; i < count; i++)
190 	{
191 		for (j = 0; j < count; j++)
192 		{
193 			decimal a, s, m, d;
194 			int c;
195 			c = deccmp(decarr[i], decarr[j]);
196 			printf("dec[c,%d,%d]: %d\n", i, j, c);
197 
198 			r = decadd(decarr[i], decarr[j], &a);
199 			if (r)
200 			{
201 				check_errno();
202 				printf("r: %d\n", r);
203 			}
204 			else
205 			{
206 				dectoasc(&a, buf, BUFSIZE-1, -1);
207 				printf("dec[a,%d,%d]: %s\n", i, j, buf);
208 			}
209 
210 			r = decsub(decarr[i], decarr[j], &s);
211 			if (r)
212 			{
213 				check_errno();
214 				printf("r: %d\n", r);
215 			}
216 			else
217 			{
218 				dectoasc(&s, buf, BUFSIZE-1, -1);
219 				printf("dec[s,%d,%d]: %s\n", i, j, buf);
220 			}
221 
222 			r = decmul(decarr[i], decarr[j], &m);
223 			if (r)
224 			{
225 				check_errno();
226 				printf("r: %d\n", r);
227 			}
228 			else
229 			{
230 				dectoasc(&m, buf, BUFSIZE-1, -1);
231 				printf("dec[m,%d,%d]: %s\n", i, j, buf);
232 			}
233 
234 			r = decdiv(decarr[i], decarr[j], &d);
235 			if (r)
236 			{
237 				check_errno();
238 				printf("r: %d\n", r);
239 			}
240 			else
241 			{
242 				dectoasc(&d, buf, BUFSIZE-1, -1);
243 				printf("dec[d,%d,%d]: %s\n", i, j, buf);
244 			}
245 		}
246 	}
247 
248 	for (i = 0; i < count; i++)
249 	{
250 		dectoasc(decarr[i], buf, BUFSIZE-1, -1);
251 		printf("%d: %s\n", i, buf);
252 
253 		PGTYPESdecimal_free(decarr[i]);
254 	}
255 	free(decarr);
256 
257 	return 0;
258 }
259 
260 static void
261 check_errno(void)
262 {
263 	switch(errno)
264 	{
265 		case 0:
266 			printf("(no errno set) - ");
267 			break;
268 		case ECPG_INFORMIX_NUM_OVERFLOW:
269 			printf("(errno == ECPG_INFORMIX_NUM_OVERFLOW) - ");
270 			break;
271 		case ECPG_INFORMIX_NUM_UNDERFLOW:
272 			printf("(errno == ECPG_INFORMIX_NUM_UNDERFLOW) - ");
273 			break;
274 		case PGTYPES_NUM_OVERFLOW:
275 			printf("(errno == PGTYPES_NUM_OVERFLOW) - ");
276 			break;
277 		case PGTYPES_NUM_UNDERFLOW:
278 			printf("(errno == PGTYPES_NUM_UNDERFLOW) - ");
279 			break;
280 		case PGTYPES_NUM_BAD_NUMERIC:
281 			printf("(errno == PGTYPES_NUM_BAD_NUMERIC) - ");
282 			break;
283 		case PGTYPES_NUM_DIVIDE_ZERO:
284 			printf("(errno == PGTYPES_NUM_DIVIDE_ZERO) - ");
285 			break;
286 		default:
287 			printf("(unknown errno (%d))\n", errno);
288 			printf("(libc: (%s)) ", strerror(errno));
289 			break;
290 	}
291 }
292