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