Age Owner Branch data TLA Line data Source code
1 : : /* src/interfaces/ecpg/compatlib/informix.c */
2 : :
3 : : #define POSTGRES_ECPG_INTERNAL
4 : : #include "postgres_fe.h"
5 : :
6 : : #include <math.h>
7 : : #include <ctype.h>
8 : : #include <limits.h>
9 : :
10 : : #include "ecpg_informix.h"
11 : : #include "ecpgerrno.h"
12 : : #include "ecpgtype.h"
13 : : #include "pgtypes_date.h"
14 : : #include "pgtypes_error.h"
15 : : #include "pgtypes_numeric.h"
16 : : #include "sqlca.h"
17 : : #include "sqltypes.h"
18 : :
19 : : /* this is also defined in ecpglib/misc.c, by defining it twice we don't have to export the symbol */
20 : :
21 : : static struct sqlca_t sqlca_init =
22 : : {
23 : : {
24 : : 'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
25 : : },
26 : : sizeof(struct sqlca_t),
27 : : 0,
28 : : {
29 : : 0,
30 : : {
31 : : 0
32 : : }
33 : : },
34 : : {
35 : : 'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
36 : : },
37 : : {
38 : : 0, 0, 0, 0, 0, 0
39 : : },
40 : : {
41 : : 0, 0, 0, 0, 0, 0, 0, 0
42 : : },
43 : : {
44 : : '0', '0', '0', '0', '0'
45 : : }
46 : : };
47 : : static int
7228 bruce@momjian.us 48 :CBC 247 : deccall2(decimal *arg1, decimal *arg2, int (*ptr) (numeric *, numeric *))
49 : : {
50 : : numeric *a1,
51 : : *a2;
52 : : int i;
53 : :
8103 meskes@postgresql.or 54 [ - + ]: 247 : if ((a1 = PGTYPESnumeric_new()) == NULL)
8020 meskes@postgresql.or 55 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
56 : :
8103 meskes@postgresql.or 57 [ - + ]:CBC 247 : if ((a2 = PGTYPESnumeric_new()) == NULL)
58 : : {
8103 meskes@postgresql.or 59 :UBC 0 : PGTYPESnumeric_free(a1);
8020 60 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
61 : : }
62 : :
8103 meskes@postgresql.or 63 [ - + ]:CBC 247 : if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
64 : : {
8103 meskes@postgresql.or 65 :UBC 0 : PGTYPESnumeric_free(a1);
66 : 0 : PGTYPESnumeric_free(a2);
8020 67 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
68 : : }
69 : :
8103 meskes@postgresql.or 70 [ - + ]:CBC 247 : if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
71 : : {
8103 meskes@postgresql.or 72 :UBC 0 : PGTYPESnumeric_free(a1);
73 : 0 : PGTYPESnumeric_free(a2);
8020 74 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
75 : : }
76 : :
8069 bruce@momjian.us 77 :CBC 247 : i = (*ptr) (a1, a2);
78 : :
8103 meskes@postgresql.or 79 : 247 : PGTYPESnumeric_free(a1);
80 : 247 : PGTYPESnumeric_free(a2);
81 : :
2942 peter_e@gmx.net 82 : 247 : return i;
83 : : }
84 : :
85 : : static int
7228 bruce@momjian.us 86 : 901 : deccall3(decimal *arg1, decimal *arg2, decimal *result, int (*ptr) (numeric *, numeric *, numeric *))
87 : : {
88 : : numeric *a1,
89 : : *a2,
90 : : *nres;
91 : : int i;
92 : :
93 : : /*
94 : : * we must NOT set the result to NULL here because it may be the same
95 : : * variable as one of the arguments
96 : : */
7982 meskes@postgresql.or 97 [ + + + + ]: 901 : if (risnull(CDECIMALTYPE, (char *) arg1) || risnull(CDECIMALTYPE, (char *) arg2))
8095 98 : 116 : return 0;
99 : :
8103 100 [ - + ]: 785 : if ((a1 = PGTYPESnumeric_new()) == NULL)
8020 meskes@postgresql.or 101 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
102 : :
8103 meskes@postgresql.or 103 [ - + ]:CBC 785 : if ((a2 = PGTYPESnumeric_new()) == NULL)
104 : : {
8103 meskes@postgresql.or 105 :UBC 0 : PGTYPESnumeric_free(a1);
8020 106 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
107 : : }
108 : :
8103 meskes@postgresql.or 109 [ - + ]:CBC 785 : if ((nres = PGTYPESnumeric_new()) == NULL)
110 : : {
8103 meskes@postgresql.or 111 :UBC 0 : PGTYPESnumeric_free(a1);
112 : 0 : PGTYPESnumeric_free(a2);
8020 113 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
114 : : }
115 : :
8103 meskes@postgresql.or 116 [ - + ]:CBC 785 : if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
117 : : {
8103 meskes@postgresql.or 118 :UBC 0 : PGTYPESnumeric_free(a1);
119 : 0 : PGTYPESnumeric_free(a2);
120 : 0 : PGTYPESnumeric_free(nres);
8020 121 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
122 : : }
123 : :
8103 meskes@postgresql.or 124 [ - + ]:CBC 785 : if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
125 : : {
8103 meskes@postgresql.or 126 :UBC 0 : PGTYPESnumeric_free(a1);
127 : 0 : PGTYPESnumeric_free(a2);
128 : 0 : PGTYPESnumeric_free(nres);
8020 129 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
130 : : }
131 : :
8069 bruce@momjian.us 132 :CBC 785 : i = (*ptr) (a1, a2, nres);
133 : :
134 [ + + ]: 785 : if (i == 0) /* No error */
135 : : {
136 : :
137 : : /* set the result to null in case it errors out later */
7846 meskes@postgresql.or 138 : 771 : rsetnull(CDECIMALTYPE, (char *) result);
8103 139 : 771 : PGTYPESnumeric_to_decimal(nres, result);
140 : : }
141 : :
142 : 785 : PGTYPESnumeric_free(nres);
143 : 785 : PGTYPESnumeric_free(a1);
144 : 785 : PGTYPESnumeric_free(a2);
145 : :
2942 peter_e@gmx.net 146 : 785 : return i;
147 : : }
148 : :
149 : : /* we start with the numeric functions */
150 : : int
7228 bruce@momjian.us 151 : 226 : decadd(decimal *arg1, decimal *arg2, decimal *sum)
152 : : {
6962 meskes@postgresql.or 153 : 226 : errno = 0;
8103 154 : 226 : deccall3(arg1, arg2, sum, PGTYPESnumeric_add);
155 : :
156 [ + + ]: 226 : if (errno == PGTYPES_NUM_OVERFLOW)
8020 157 : 62 : return ECPG_INFORMIX_NUM_OVERFLOW;
6962 158 [ - + ]: 164 : else if (errno == PGTYPES_NUM_UNDERFLOW)
8020 meskes@postgresql.or 159 :UBC 0 : return ECPG_INFORMIX_NUM_UNDERFLOW;
6962 meskes@postgresql.or 160 [ - + ]:CBC 164 : else if (errno != 0)
6962 meskes@postgresql.or 161 :UBC 0 : return -1;
162 : : else
8069 bruce@momjian.us 163 :CBC 164 : return 0;
164 : : }
165 : :
166 : : int
7228 167 : 247 : deccmp(decimal *arg1, decimal *arg2)
168 : : {
2942 peter_e@gmx.net 169 : 247 : return deccall2(arg1, arg2, PGTYPESnumeric_cmp);
170 : : }
171 : :
172 : : void
7228 bruce@momjian.us 173 :UBC 0 : deccopy(decimal *src, decimal *target)
174 : : {
8033 meskes@postgresql.or 175 : 0 : memcpy(target, src, sizeof(decimal));
8196 176 : 0 : }
177 : :
178 : : static char *
395 peter@eisentraut.org 179 :CBC 16 : ecpg_strndup(const char *str, size_t len)
180 : : {
181 : 16 : size_t real_len = strlen(str);
182 [ - + ]: 16 : int use_len = (int) ((real_len > len) ? len : real_len);
183 : :
184 : 16 : char *new = malloc(use_len + 1);
185 : :
186 [ + - ]: 16 : if (new)
187 : : {
188 : 16 : memcpy(new, str, use_len);
189 : 16 : new[use_len] = '\0';
190 : : }
191 : : else
395 peter@eisentraut.org 192 :UBC 0 : errno = ENOMEM;
193 : :
395 peter@eisentraut.org 194 :CBC 16 : return new;
195 : : }
196 : :
197 : : int
2867 peter_e@gmx.net 198 : 16 : deccvasc(const char *cp, int len, decimal *np)
199 : : {
200 : : char *str;
6912 bruce@momjian.us 201 : 16 : int ret = 0;
202 : : numeric *result;
203 : :
8023 meskes@postgresql.or 204 : 16 : rsetnull(CDECIMALTYPE, (char *) np);
8096 205 [ - + ]: 16 : if (risnull(CSTRINGTYPE, cp))
8096 meskes@postgresql.or 206 :UBC 0 : return 0;
207 : :
395 peter@eisentraut.org 208 :CBC 16 : str = ecpg_strndup(cp, len); /* decimal_in always converts the complete
209 : : * string */
8196 meskes@postgresql.or 210 [ - + ]: 16 : if (!str)
8020 meskes@postgresql.or 211 :UBC 0 : ret = ECPG_INFORMIX_NUM_UNDERFLOW;
212 : : else
213 : : {
6962 meskes@postgresql.or 214 :CBC 16 : errno = 0;
8185 215 : 16 : result = PGTYPESnumeric_from_asc(str, NULL);
216 [ + + ]: 16 : if (!result)
217 : : {
8196 218 [ - + - ]: 1 : switch (errno)
219 : : {
8069 bruce@momjian.us 220 :UBC 0 : case PGTYPES_NUM_OVERFLOW:
8020 meskes@postgresql.or 221 : 0 : ret = ECPG_INFORMIX_NUM_OVERFLOW;
8069 bruce@momjian.us 222 : 0 : break;
8069 bruce@momjian.us 223 :CBC 1 : case PGTYPES_NUM_BAD_NUMERIC:
8020 meskes@postgresql.or 224 : 1 : ret = ECPG_INFORMIX_BAD_NUMERIC;
8069 bruce@momjian.us 225 : 1 : break;
8069 bruce@momjian.us 226 :UBC 0 : default:
8020 meskes@postgresql.or 227 : 0 : ret = ECPG_INFORMIX_BAD_EXPONENT;
8069 bruce@momjian.us 228 : 0 : break;
229 : : }
230 : : }
231 : : else
232 : : {
6505 bruce@momjian.us 233 :CBC 15 : int i = PGTYPESnumeric_to_decimal(result, np);
234 : :
5819 meskes@postgresql.or 235 : 15 : PGTYPESnumeric_free(result);
6598 236 [ + + ]: 15 : if (i != 0)
237 : 1 : ret = ECPG_INFORMIX_NUM_OVERFLOW;
238 : : }
239 : : }
240 : :
8103 241 : 16 : free(str);
8196 242 : 16 : return ret;
243 : : }
244 : :
245 : : int
7228 bruce@momjian.us 246 :UBC 0 : deccvdbl(double dbl, decimal *np)
247 : : {
248 : : numeric *nres;
8069 249 : 0 : int result = 1;
250 : :
8023 meskes@postgresql.or 251 : 0 : rsetnull(CDECIMALTYPE, (char *) np);
8069 bruce@momjian.us 252 [ # # ]: 0 : if (risnull(CDOUBLETYPE, (char *) &dbl))
8095 meskes@postgresql.or 253 : 0 : return 0;
254 : :
7017 255 : 0 : nres = PGTYPESnumeric_new();
8103 256 [ # # ]: 0 : if (nres == NULL)
8020 257 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
258 : :
8103 259 : 0 : result = PGTYPESnumeric_from_double(dbl, nres);
260 [ # # ]: 0 : if (result == 0)
261 : 0 : result = PGTYPESnumeric_to_decimal(nres, np);
262 : :
263 : 0 : PGTYPESnumeric_free(nres);
2942 peter_e@gmx.net 264 : 0 : return result;
265 : : }
266 : :
267 : : int
7228 bruce@momjian.us 268 :CBC 914 : deccvint(int in, decimal *np)
269 : : {
270 : : numeric *nres;
8069 271 : 914 : int result = 1;
272 : :
8023 meskes@postgresql.or 273 : 914 : rsetnull(CDECIMALTYPE, (char *) np);
8069 bruce@momjian.us 274 [ - + ]: 914 : if (risnull(CINTTYPE, (char *) &in))
8095 meskes@postgresql.or 275 :UBC 0 : return 0;
276 : :
7017 meskes@postgresql.or 277 :CBC 914 : nres = PGTYPESnumeric_new();
8103 278 [ - + ]: 914 : if (nres == NULL)
8020 meskes@postgresql.or 279 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
280 : :
8103 meskes@postgresql.or 281 :CBC 914 : result = PGTYPESnumeric_from_int(in, nres);
282 [ + - ]: 914 : if (result == 0)
283 : 914 : result = PGTYPESnumeric_to_decimal(nres, np);
284 : :
285 : 914 : PGTYPESnumeric_free(nres);
2942 peter_e@gmx.net 286 : 914 : return result;
287 : : }
288 : :
289 : : int
7228 bruce@momjian.us 290 : 11 : deccvlong(long lng, decimal *np)
291 : : {
292 : : numeric *nres;
8069 293 : 11 : int result = 1;
294 : :
8023 meskes@postgresql.or 295 : 11 : rsetnull(CDECIMALTYPE, (char *) np);
8069 bruce@momjian.us 296 [ - + ]: 11 : if (risnull(CLONGTYPE, (char *) &lng))
8095 meskes@postgresql.or 297 :UBC 0 : return 0;
298 : :
7017 meskes@postgresql.or 299 :CBC 11 : nres = PGTYPESnumeric_new();
8103 300 [ - + ]: 11 : if (nres == NULL)
8020 meskes@postgresql.or 301 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
302 : :
8103 meskes@postgresql.or 303 :CBC 11 : result = PGTYPESnumeric_from_long(lng, nres);
304 [ + - ]: 11 : if (result == 0)
305 : 11 : result = PGTYPESnumeric_to_decimal(nres, np);
306 : :
307 : 11 : PGTYPESnumeric_free(nres);
2942 peter_e@gmx.net 308 : 11 : return result;
309 : : }
310 : :
311 : : int
7228 bruce@momjian.us 312 : 225 : decdiv(decimal *n1, decimal *n2, decimal *result)
313 : : {
314 : : int i;
315 : :
6962 meskes@postgresql.or 316 : 225 : errno = 0;
7982 317 : 225 : i = deccall3(n1, n2, result, PGTYPESnumeric_div);
318 : :
8196 319 [ + + ]: 225 : if (i != 0)
320 [ + - - ]: 14 : switch (errno)
321 : : {
8069 bruce@momjian.us 322 : 14 : case PGTYPES_NUM_DIVIDE_ZERO:
8020 meskes@postgresql.or 323 : 14 : return ECPG_INFORMIX_DIVIDE_ZERO;
324 : : break;
8069 bruce@momjian.us 325 :UBC 0 : case PGTYPES_NUM_OVERFLOW:
8020 meskes@postgresql.or 326 : 0 : return ECPG_INFORMIX_NUM_OVERFLOW;
327 : : break;
8069 bruce@momjian.us 328 : 0 : default:
8020 meskes@postgresql.or 329 : 0 : return ECPG_INFORMIX_NUM_UNDERFLOW;
330 : : break;
331 : : }
332 : :
8103 meskes@postgresql.or 333 :CBC 211 : return 0;
334 : : }
335 : :
336 : : int
7228 bruce@momjian.us 337 : 225 : decmul(decimal *n1, decimal *n2, decimal *result)
338 : : {
339 : : int i;
340 : :
6962 meskes@postgresql.or 341 : 225 : errno = 0;
7982 342 : 225 : i = deccall3(n1, n2, result, PGTYPESnumeric_mul);
343 : :
8196 344 [ - + ]: 225 : if (i != 0)
8196 meskes@postgresql.or 345 [ # # ]:UBC 0 : switch (errno)
346 : : {
8069 bruce@momjian.us 347 : 0 : case PGTYPES_NUM_OVERFLOW:
8020 meskes@postgresql.or 348 : 0 : return ECPG_INFORMIX_NUM_OVERFLOW;
349 : : break;
8069 bruce@momjian.us 350 : 0 : default:
8020 meskes@postgresql.or 351 : 0 : return ECPG_INFORMIX_NUM_UNDERFLOW;
352 : : break;
353 : : }
354 : :
8103 meskes@postgresql.or 355 :CBC 225 : return 0;
356 : : }
357 : :
358 : : int
7228 bruce@momjian.us 359 : 225 : decsub(decimal *n1, decimal *n2, decimal *result)
360 : : {
361 : : int i;
362 : :
6962 meskes@postgresql.or 363 : 225 : errno = 0;
7982 364 : 225 : i = deccall3(n1, n2, result, PGTYPESnumeric_sub);
365 : :
8196 366 [ - + ]: 225 : if (i != 0)
8196 meskes@postgresql.or 367 [ # # ]:UBC 0 : switch (errno)
368 : : {
8069 bruce@momjian.us 369 : 0 : case PGTYPES_NUM_OVERFLOW:
8020 meskes@postgresql.or 370 : 0 : return ECPG_INFORMIX_NUM_OVERFLOW;
371 : : break;
8069 bruce@momjian.us 372 : 0 : default:
8020 meskes@postgresql.or 373 : 0 : return ECPG_INFORMIX_NUM_UNDERFLOW;
374 : : break;
375 : : }
376 : :
8103 meskes@postgresql.or 377 :CBC 225 : return 0;
378 : : }
379 : :
380 : : int
7228 bruce@momjian.us 381 : 939 : dectoasc(decimal *np, char *cp, int len, int right)
382 : : {
383 : : char *str;
384 : : numeric *nres;
385 : :
8023 meskes@postgresql.or 386 : 939 : rsetnull(CSTRINGTYPE, (char *) cp);
8069 bruce@momjian.us 387 [ + + ]: 939 : if (risnull(CDECIMALTYPE, (char *) np))
8096 meskes@postgresql.or 388 : 99 : return 0;
389 : :
7017 390 : 840 : nres = PGTYPESnumeric_new();
391 [ - + ]: 840 : if (nres == NULL)
7017 meskes@postgresql.or 392 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
393 : :
8103 meskes@postgresql.or 394 [ - + ]:CBC 840 : if (PGTYPESnumeric_from_decimal(np, nres) != 0)
395 : : {
7017 meskes@postgresql.or 396 :UBC 0 : PGTYPESnumeric_free(nres);
8020 397 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
398 : : }
399 : :
8196 meskes@postgresql.or 400 [ + + ]:CBC 840 : if (right >= 0)
8103 401 : 78 : str = PGTYPESnumeric_to_asc(nres, right);
402 : : else
7982 403 : 762 : str = PGTYPESnumeric_to_asc(nres, nres->dscale);
404 : :
8103 405 : 840 : PGTYPESnumeric_free(nres);
8196 406 [ - + ]: 840 : if (!str)
8196 meskes@postgresql.or 407 :UBC 0 : return -1;
408 : :
409 : : /*
410 : : * TODO: have to take care of len here and create exponential notation if
411 : : * necessary
412 : : */
6962 meskes@postgresql.or 413 [ + + ]:CBC 840 : if ((int) (strlen(str) + 1) > len)
414 : : {
415 [ + + ]: 108 : if (len > 1)
416 : : {
417 : 106 : cp[0] = '*';
418 : 106 : cp[1] = '\0';
419 : : }
420 : 108 : free(str);
421 : 108 : return -1;
422 : : }
423 : : else
424 : : {
425 : 732 : strcpy(cp, str);
426 : 732 : free(str);
427 : 732 : return 0;
428 : : }
429 : : }
430 : :
431 : : int
7228 bruce@momjian.us 432 : 13 : dectodbl(decimal *np, double *dblp)
433 : : {
434 : : int i;
7017 meskes@postgresql.or 435 : 13 : numeric *nres = PGTYPESnumeric_new();
436 : :
8103 437 [ - + ]: 13 : if (nres == NULL)
8020 meskes@postgresql.or 438 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
439 : :
8103 meskes@postgresql.or 440 [ - + ]:CBC 13 : if (PGTYPESnumeric_from_decimal(np, nres) != 0)
441 : : {
7017 meskes@postgresql.or 442 :UBC 0 : PGTYPESnumeric_free(nres);
8020 443 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
444 : : }
445 : :
8103 meskes@postgresql.or 446 :CBC 13 : i = PGTYPESnumeric_to_double(nres, dblp);
447 : 13 : PGTYPESnumeric_free(nres);
448 : :
449 : 13 : return i;
450 : : }
451 : :
452 : : int
7228 bruce@momjian.us 453 : 16 : dectoint(decimal *np, int *ip)
454 : : {
455 : : int ret;
8033 meskes@postgresql.or 456 : 16 : numeric *nres = PGTYPESnumeric_new();
457 : : int errnum;
458 : :
8103 459 [ - + ]: 16 : if (nres == NULL)
8020 meskes@postgresql.or 460 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
461 : :
8103 meskes@postgresql.or 462 [ - + ]:CBC 16 : if (PGTYPESnumeric_from_decimal(np, nres) != 0)
463 : : {
7017 meskes@postgresql.or 464 :UBC 0 : PGTYPESnumeric_free(nres);
8020 465 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
466 : : }
467 : :
530 dgustafsson@postgres 468 :CBC 16 : errno = 0;
8103 meskes@postgresql.or 469 : 16 : ret = PGTYPESnumeric_to_int(nres, ip);
530 dgustafsson@postgres 470 : 16 : errnum = errno;
7012 meskes@postgresql.or 471 : 16 : PGTYPESnumeric_free(nres);
472 : :
530 dgustafsson@postgres 473 [ + + + - ]: 16 : if (ret == -1 && errnum == PGTYPES_NUM_OVERFLOW)
8020 meskes@postgresql.or 474 : 3 : ret = ECPG_INFORMIX_NUM_OVERFLOW;
475 : :
8196 476 : 16 : return ret;
477 : : }
478 : :
479 : : int
7228 bruce@momjian.us 480 : 14 : dectolong(decimal *np, long *lngp)
481 : : {
482 : : int ret;
7017 meskes@postgresql.or 483 : 14 : numeric *nres = PGTYPESnumeric_new();
484 : : int errnum;
485 : :
8103 486 [ - + ]: 14 : if (nres == NULL)
8020 meskes@postgresql.or 487 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
488 : :
8103 meskes@postgresql.or 489 [ - + ]:CBC 14 : if (PGTYPESnumeric_from_decimal(np, nres) != 0)
490 : : {
7017 meskes@postgresql.or 491 :UBC 0 : PGTYPESnumeric_free(nres);
8020 492 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
493 : : }
494 : :
530 dgustafsson@postgres 495 :CBC 14 : errno = 0;
8103 meskes@postgresql.or 496 : 14 : ret = PGTYPESnumeric_to_long(nres, lngp);
530 dgustafsson@postgres 497 : 14 : errnum = errno;
7017 meskes@postgresql.or 498 : 14 : PGTYPESnumeric_free(nres);
499 : :
530 dgustafsson@postgres 500 [ + + + - ]: 14 : if (ret == -1 && errnum == PGTYPES_NUM_OVERFLOW)
8020 meskes@postgresql.or 501 : 3 : ret = ECPG_INFORMIX_NUM_OVERFLOW;
502 : :
8196 503 : 14 : return ret;
504 : : }
505 : :
506 : : /* Now the date functions */
507 : : int
8032 508 : 18 : rdatestr(date d, char *str)
509 : : {
8069 bruce@momjian.us 510 : 18 : char *tmp = PGTYPESdate_to_asc(d);
511 : :
8196 meskes@postgresql.or 512 [ - + ]: 18 : if (!tmp)
8020 meskes@postgresql.or 513 :UBC 0 : return ECPG_INFORMIX_DATE_CONVERT;
514 : :
515 : : /* move to user allocated buffer */
8088 meskes@postgresql.or 516 :CBC 18 : strcpy(str, tmp);
517 : 18 : free(tmp);
518 : :
8196 519 : 18 : return 0;
520 : : }
521 : :
522 : : /*
523 : : *
524 : : * the input for this function is mmddyyyy and any non-numeric
525 : : * character can be used as a separator
526 : : *
527 : : */
528 : : int
2867 peter_e@gmx.net 529 : 2 : rstrdate(const char *str, date * d)
530 : : {
6962 meskes@postgresql.or 531 : 2 : return rdefmtdate(d, "mm/dd/yyyy", str);
532 : : }
533 : :
534 : : void
7266 bruce@momjian.us 535 :UBC 0 : rtoday(date * d)
536 : : {
8196 meskes@postgresql.or 537 : 0 : PGTYPESdate_today(d);
538 : 0 : }
539 : :
540 : : int
1682 tgl@sss.pgh.pa.us 541 : 0 : rjulmdy(date d, short *mdy)
542 : : {
543 : : int mdy_int[3];
544 : :
8087 meskes@postgresql.or 545 : 0 : PGTYPESdate_julmdy(d, mdy_int);
8069 bruce@momjian.us 546 : 0 : mdy[0] = (short) mdy_int[0];
547 : 0 : mdy[1] = (short) mdy_int[1];
548 : 0 : mdy[2] = (short) mdy_int[2];
8196 meskes@postgresql.or 549 : 0 : return 0;
550 : : }
551 : :
552 : : int
2867 peter_e@gmx.net 553 :CBC 22 : rdefmtdate(date * d, const char *fmt, const char *str)
554 : : {
555 : : /* TODO: take care of DBCENTURY environment variable */
556 : : /* PGSQL functions allow all centuries */
557 : :
6962 meskes@postgresql.or 558 : 22 : errno = 0;
8194 559 [ + + ]: 22 : if (PGTYPESdate_defmt_asc(d, fmt, str) == 0)
8196 560 : 17 : return 0;
561 : :
562 [ + + + + : 5 : switch (errno)
- ]
563 : : {
8069 bruce@momjian.us 564 : 2 : case PGTYPES_DATE_ERR_ENOSHORTDATE:
8020 meskes@postgresql.or 565 : 2 : return ECPG_INFORMIX_ENOSHORTDATE;
8196 566 : 1 : case PGTYPES_DATE_ERR_EARGS:
567 : : case PGTYPES_DATE_ERR_ENOTDMY:
8020 568 : 1 : return ECPG_INFORMIX_ENOTDMY;
8069 bruce@momjian.us 569 : 1 : case PGTYPES_DATE_BAD_DAY:
8020 meskes@postgresql.or 570 : 1 : return ECPG_INFORMIX_BAD_DAY;
8069 bruce@momjian.us 571 : 1 : case PGTYPES_DATE_BAD_MONTH:
8020 meskes@postgresql.or 572 : 1 : return ECPG_INFORMIX_BAD_MONTH;
8069 bruce@momjian.us 573 :UBC 0 : default:
8020 meskes@postgresql.or 574 : 0 : return ECPG_INFORMIX_BAD_YEAR;
575 : : }
576 : : }
577 : :
578 : : int
2867 peter_e@gmx.net 579 :CBC 12 : rfmtdate(date d, const char *fmt, char *str)
580 : : {
6962 meskes@postgresql.or 581 : 12 : errno = 0;
8194 582 [ + - ]: 12 : if (PGTYPESdate_fmt_asc(d, fmt, str) == 0)
8196 583 : 12 : return 0;
584 : :
8196 meskes@postgresql.or 585 [ # # ]:UBC 0 : if (errno == ENOMEM)
8020 586 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
587 : :
588 : 0 : return ECPG_INFORMIX_DATE_CONVERT;
589 : : }
590 : :
591 : : int
1682 tgl@sss.pgh.pa.us 592 :CBC 1 : rmdyjul(short *mdy, date * d)
593 : : {
594 : : int mdy_int[3];
595 : :
8087 meskes@postgresql.or 596 : 1 : mdy_int[0] = mdy[0];
597 : 1 : mdy_int[1] = mdy[1];
598 : 1 : mdy_int[2] = mdy[2];
599 : 1 : PGTYPESdate_mdyjul(mdy_int, d);
8196 600 : 1 : return 0;
601 : : }
602 : :
603 : : int
8032 meskes@postgresql.or 604 :UBC 0 : rdayofweek(date d)
605 : : {
2942 peter_e@gmx.net 606 : 0 : return PGTYPESdate_dayofweek(d);
607 : : }
608 : :
609 : : /* And the datetime stuff */
610 : :
611 : : void
7266 bruce@momjian.us 612 : 0 : dtcurrent(timestamp * ts)
613 : : {
8069 614 : 0 : PGTYPEStimestamp_current(ts);
8196 meskes@postgresql.or 615 : 0 : }
616 : :
617 : : int
7266 bruce@momjian.us 618 : 0 : dtcvasc(char *str, timestamp * ts)
619 : : {
620 : : timestamp ts_tmp;
621 : : int i;
8069 622 : 0 : char **endptr = &str;
623 : :
6962 meskes@postgresql.or 624 : 0 : errno = 0;
8069 bruce@momjian.us 625 : 0 : ts_tmp = PGTYPEStimestamp_from_asc(str, endptr);
626 : 0 : i = errno;
627 [ # # ]: 0 : if (i)
628 : : /* TODO: rewrite to Informix error codes */
629 : 0 : return i;
630 [ # # ]: 0 : if (**endptr)
631 : : {
632 : : /* extra characters exist at the end */
8020 meskes@postgresql.or 633 : 0 : return ECPG_INFORMIX_EXTRA_CHARS;
634 : : }
635 : : /* TODO: other Informix error codes missing */
636 : :
637 : : /* everything went fine */
8069 bruce@momjian.us 638 : 0 : *ts = ts_tmp;
639 : :
8196 meskes@postgresql.or 640 : 0 : return 0;
641 : : }
642 : :
643 : : int
6962 644 : 0 : dtcvfmtasc(char *inbuf, char *fmtstr, timestamp * dtvalue)
645 : : {
646 : 0 : return PGTYPEStimestamp_defmt_asc(inbuf, fmtstr, dtvalue);
647 : : }
648 : :
649 : : int
7266 bruce@momjian.us 650 : 0 : dtsub(timestamp * ts1, timestamp * ts2, interval * iv)
651 : : {
8194 meskes@postgresql.or 652 : 0 : return PGTYPEStimestamp_sub(ts1, ts2, iv);
653 : : }
654 : :
655 : : int
7266 bruce@momjian.us 656 : 0 : dttoasc(timestamp * ts, char *output)
657 : : {
8069 658 : 0 : char *asctime = PGTYPEStimestamp_to_asc(*ts);
659 : :
660 : 0 : strcpy(output, asctime);
8088 meskes@postgresql.or 661 : 0 : free(asctime);
8196 662 : 0 : return 0;
663 : : }
664 : :
665 : : int
7266 bruce@momjian.us 666 : 0 : dttofmtasc(timestamp * ts, char *output, int str_len, char *fmtstr)
667 : : {
8194 meskes@postgresql.or 668 : 0 : return PGTYPEStimestamp_fmt_asc(ts, output, str_len, fmtstr);
669 : : }
670 : :
671 : : int
7266 bruce@momjian.us 672 :CBC 1 : intoasc(interval * i, char *str)
673 : : {
674 : : char *tmp;
675 : :
6962 meskes@postgresql.or 676 : 1 : errno = 0;
3739 677 : 1 : tmp = PGTYPESinterval_to_asc(i);
678 : :
679 [ - + ]: 1 : if (!tmp)
8194 meskes@postgresql.or 680 :UBC 0 : return -errno;
681 : :
565 michael@paquier.xyz 682 :CBC 1 : strcpy(str, tmp);
3739 meskes@postgresql.or 683 : 1 : free(tmp);
8196 684 : 1 : return 0;
685 : : }
686 : :
687 : : static struct
688 : : {
689 : : long val;
690 : : int maxdigits;
691 : : int digits;
692 : : int remaining;
693 : : char sign;
694 : : char *val_string;
695 : : } value;
696 : :
697 : : /**
698 : : * initialize the struct, which holds the different forms
699 : : * of the long value
700 : : */
701 : : static int
7678 bruce@momjian.us 702 : 10 : initValue(long lng_val)
703 : : {
704 : : int i,
705 : : j;
706 : : long l,
707 : : dig;
708 : :
709 : : /* set some obvious things */
710 : 10 : value.val = lng_val >= 0 ? lng_val : lng_val * (-1);
711 [ - + ]: 10 : value.sign = lng_val >= 0 ? '+' : '-';
712 : 10 : value.maxdigits = log10(2) * (8 * sizeof(long) - 1);
713 : :
714 : : /* determine the number of digits */
715 : 10 : i = 0;
716 : 10 : l = 1;
717 : : do
718 : : {
719 : 70 : i++;
720 : 70 : l *= 10;
721 : : }
722 [ + + + - ]: 70 : while ((l - 1) < value.val && l <= LONG_MAX / 10);
723 : :
724 [ + - ]: 10 : if (l <= LONG_MAX / 10)
725 : : {
726 : 10 : value.digits = i;
727 : 10 : l /= 10;
728 : : }
729 : : else
7678 bruce@momjian.us 730 :UBC 0 : value.digits = i + 1;
731 : :
7678 bruce@momjian.us 732 :CBC 10 : value.remaining = value.digits;
733 : :
734 : : /* convert the long to string */
6505 735 [ - + ]: 10 : if ((value.val_string = (char *) malloc(value.digits + 1)) == NULL)
6548 meskes@postgresql.or 736 :UBC 0 : return -1;
7678 bruce@momjian.us 737 :CBC 10 : dig = value.val;
738 [ + + ]: 80 : for (i = value.digits, j = 0; i > 0; i--, j++)
739 : : {
740 : 70 : value.val_string[j] = dig / l + '0';
741 : 70 : dig = dig % l;
742 : 70 : l /= 10;
743 : : }
744 : 10 : value.val_string[value.digits] = '\0';
6548 meskes@postgresql.or 745 : 10 : return 0;
746 : : }
747 : :
748 : : /* return the position of the right-most dot in some string */
749 : : static int
2867 peter_e@gmx.net 750 : 10 : getRightMostDot(const char *str)
751 : : {
8069 bruce@momjian.us 752 : 10 : size_t len = strlen(str);
753 : : int i,
754 : : j;
755 : :
756 : 10 : j = 0;
757 [ + + ]: 126 : for (i = len - 1; i >= 0; i--)
758 : : {
759 [ + + ]: 120 : if (str[i] == '.')
760 : 4 : return len - j - 1;
8159 meskes@postgresql.or 761 : 116 : j++;
762 : : }
763 : 6 : return -1;
764 : : }
765 : :
766 : : /* And finally some misc functions */
767 : : int
2867 peter_e@gmx.net 768 : 10 : rfmtlong(long lng_val, const char *fmt, char *outbuf)
769 : : {
8069 bruce@momjian.us 770 : 10 : size_t fmt_len = strlen(fmt);
771 : : size_t temp_len;
772 : : int i,
773 : : j, /* position in temp */
774 : : k,
775 : : dotpos;
776 : 10 : int leftalign = 0,
777 : 10 : blank = 0,
778 : 10 : sign = 0,
779 : 10 : entitydone = 0,
780 : 10 : signdone = 0,
781 : 10 : brackets_ok = 0;
782 : : char *temp;
783 : 10 : char tmp[2] = " ";
784 : 10 : char lastfmt = ' ',
785 : 10 : fmtchar = ' ';
786 : :
787 : 10 : temp = (char *) malloc(fmt_len + 1);
6153 meskes@postgresql.or 788 [ - + ]: 10 : if (!temp)
789 : : {
6153 meskes@postgresql.or 790 :UBC 0 : errno = ENOMEM;
791 : 0 : return -1;
792 : : }
793 : :
794 : : /* put all info about the long in a struct */
6153 meskes@postgresql.or 795 [ - + ]:CBC 10 : if (initValue(lng_val) == -1)
796 : : {
6153 meskes@postgresql.or 797 :UBC 0 : free(temp);
6548 798 : 0 : errno = ENOMEM;
799 : 0 : return -1;
800 : : }
801 : :
802 : : /* '<' is the only format, where we have to align left */
8069 bruce@momjian.us 803 [ + + ]:CBC 10 : if (strchr(fmt, (int) '<'))
8159 meskes@postgresql.or 804 : 3 : leftalign = 1;
805 : :
806 : : /* '(' requires ')' */
8069 bruce@momjian.us 807 [ + + + - ]: 10 : if (strchr(fmt, (int) '(') && strchr(fmt, (int) ')'))
8159 meskes@postgresql.or 808 : 1 : brackets_ok = 1;
809 : :
810 : : /*
811 : : * get position of the right-most dot in the format-string and fill the
812 : : * temp-string with '0's up to there.
813 : : */
814 : 10 : dotpos = getRightMostDot(fmt);
815 : :
816 : : /* start to parse the format-string */
817 : 10 : temp[0] = '\0';
8069 bruce@momjian.us 818 : 10 : k = value.digits - 1; /* position in the value_string */
819 [ + + ]: 189 : for (i = fmt_len - 1, j = 0; i >= 0; i--, j++)
820 : : {
821 : : /* qualify, where we are in the value_string */
822 [ + + ]: 179 : if (k < 0)
823 : : {
8159 meskes@postgresql.or 824 : 90 : blank = 1;
5847 825 [ + + ]: 90 : if (k == -1)
8159 826 : 30 : sign = 1;
6962 827 [ + + ]: 90 : if (leftalign)
828 : : {
829 : : /* can't use strncat(,,0) here, Solaris would freak out */
830 [ + - ]: 23 : if (sign)
831 [ - + ]: 23 : if (signdone)
832 : : {
6962 meskes@postgresql.or 833 :UBC 0 : temp[j] = '\0';
834 : 0 : break;
835 : : }
836 : : }
837 : : }
838 : : /* if we're right side of the right-most dot, print '0' */
8069 bruce@momjian.us 839 [ + + + + ]:CBC 179 : if (dotpos >= 0 && dotpos <= i)
840 : : {
841 [ + + ]: 11 : if (dotpos < i)
842 : : {
843 [ + + ]: 7 : if (fmt[i] == ')')
844 [ + - ]: 1 : tmp[0] = value.sign == '-' ? ')' : ' ';
845 : : else
846 : 6 : tmp[0] = '0';
847 : : }
848 : : else
8159 meskes@postgresql.or 849 : 4 : tmp[0] = '.';
850 : 11 : strcat(temp, tmp);
851 : 11 : continue;
852 : : }
853 : : /* the ',' needs special attention, if it is in the blank area */
8069 bruce@momjian.us 854 [ + + + + ]: 168 : if (blank && fmt[i] == ',')
855 : 4 : fmtchar = lastfmt;
856 : : else
857 : 164 : fmtchar = fmt[i];
858 : : /* waiting for the sign */
6962 meskes@postgresql.or 859 [ + + + + : 168 : if (k < 0 && leftalign && sign && !signdone && fmtchar != '+' && fmtchar != '-')
+ - + - +
+ + + ]
860 : 21 : continue;
861 : : /* analyse this format-char */
8069 bruce@momjian.us 862 [ + + + + : 147 : switch (fmtchar)
+ + + - +
+ + ]
863 : : {
8159 meskes@postgresql.or 864 : 8 : case ',':
865 : 8 : tmp[0] = ',';
866 : 8 : k++;
867 : 8 : break;
868 : 24 : case '*':
8069 bruce@momjian.us 869 [ + + ]: 24 : if (blank)
870 : 10 : tmp[0] = '*';
871 : : else
872 : 14 : tmp[0] = value.val_string[k];
8159 meskes@postgresql.or 873 : 24 : break;
874 : 11 : case '&':
8069 bruce@momjian.us 875 [ + + ]: 11 : if (blank)
876 : 4 : tmp[0] = '0';
877 : : else
878 : 7 : tmp[0] = value.val_string[k];
8159 meskes@postgresql.or 879 : 11 : break;
880 : 48 : case '#':
8069 bruce@momjian.us 881 [ + + ]: 48 : if (blank)
882 : 30 : tmp[0] = ' ';
883 : : else
884 : 18 : tmp[0] = value.val_string[k];
8159 meskes@postgresql.or 885 : 48 : break;
886 : 6 : case '-':
8069 bruce@momjian.us 887 [ + + + - : 6 : if (sign && value.sign == '-' && !signdone)
+ + ]
888 : : {
8159 meskes@postgresql.or 889 : 2 : tmp[0] = '-';
890 : 2 : signdone = 1;
891 : : }
8069 bruce@momjian.us 892 [ + + ]: 4 : else if (blank)
893 : 3 : tmp[0] = ' ';
894 : : else
895 : 1 : tmp[0] = value.val_string[k];
8159 meskes@postgresql.or 896 : 6 : break;
897 : 8 : case '+':
8069 bruce@momjian.us 898 [ + + + + ]: 8 : if (sign && !signdone)
899 : : {
8159 meskes@postgresql.or 900 : 3 : tmp[0] = value.sign;
901 : 3 : signdone = 1;
902 : : }
8069 bruce@momjian.us 903 [ + + ]: 5 : else if (blank)
904 : 3 : tmp[0] = ' ';
905 : : else
906 : 2 : tmp[0] = value.val_string[k];
8159 meskes@postgresql.or 907 : 8 : break;
908 : 1 : case '(':
8069 bruce@momjian.us 909 [ + - + - : 1 : if (sign && brackets_ok && value.sign == '-')
+ - ]
910 : 1 : tmp[0] = '(';
8069 bruce@momjian.us 911 [ # # ]:UBC 0 : else if (blank)
912 : 0 : tmp[0] = ' ';
913 : : else
914 : 0 : tmp[0] = value.val_string[k];
8159 meskes@postgresql.or 915 :CBC 1 : break;
8159 meskes@postgresql.or 916 :UBC 0 : case ')':
8069 bruce@momjian.us 917 [ # # # # ]: 0 : if (brackets_ok && value.sign == '-')
918 : 0 : tmp[0] = ')';
919 : : else
920 : 0 : tmp[0] = ' ';
8159 meskes@postgresql.or 921 : 0 : break;
8159 meskes@postgresql.or 922 :CBC 15 : case '$':
8069 bruce@momjian.us 923 [ + + + + ]: 15 : if (blank && !entitydone)
924 : : {
8159 meskes@postgresql.or 925 : 3 : tmp[0] = '$';
926 : 3 : entitydone = 1;
927 : : }
8069 bruce@momjian.us 928 [ + + ]: 12 : else if (blank)
929 : 5 : tmp[0] = ' ';
930 : : else
931 : 7 : tmp[0] = value.val_string[k];
8159 meskes@postgresql.or 932 : 15 : break;
6962 933 : 21 : case '<':
934 : 21 : tmp[0] = value.val_string[k];
935 : 21 : break;
8069 bruce@momjian.us 936 : 5 : default:
937 : 5 : tmp[0] = fmt[i];
938 : : }
8159 meskes@postgresql.or 939 : 147 : strcat(temp, tmp);
940 : 147 : lastfmt = fmt[i];
941 : 147 : k--;
942 : : }
943 : : /* safety-net */
944 : 10 : temp[fmt_len] = '\0';
945 : :
946 : : /* reverse the temp-string and put it into the outbuf */
947 : 10 : temp_len = strlen(temp);
948 : 10 : outbuf[0] = '\0';
8069 bruce@momjian.us 949 [ + + ]: 168 : for (i = temp_len - 1; i >= 0; i--)
950 : : {
8159 meskes@postgresql.or 951 : 158 : tmp[0] = temp[i];
8069 bruce@momjian.us 952 : 158 : strcat(outbuf, tmp);
953 : : }
8159 meskes@postgresql.or 954 : 10 : outbuf[temp_len] = '\0';
955 : :
956 : : /* cleaning up */
8072 tgl@sss.pgh.pa.us 957 : 10 : free(temp);
8159 meskes@postgresql.or 958 : 10 : free(value.val_string);
959 : :
8196 960 : 10 : return 0;
961 : : }
962 : :
963 : : void
8151 964 : 1 : rupshift(char *str)
965 : : {
966 [ + + ]: 16 : for (; *str != '\0'; str++)
7916 tgl@sss.pgh.pa.us 967 [ + + ]: 15 : if (islower((unsigned char) *str))
968 : 9 : *str = toupper((unsigned char) *str);
8151 meskes@postgresql.or 969 : 1 : }
970 : :
971 : : int
972 : 8 : byleng(char *str, int len)
973 : : {
8069 bruce@momjian.us 974 [ + - + + ]: 18 : for (len--; str[len] && str[len] == ' '; len--);
975 : 8 : return (len + 1);
976 : : }
977 : :
978 : : void
8151 meskes@postgresql.or 979 : 4 : ldchar(char *src, int len, char *dest)
980 : : {
6912 bruce@momjian.us 981 : 4 : int dlen = byleng(src, len);
982 : :
6962 meskes@postgresql.or 983 : 4 : memmove(dest, src, dlen);
984 : 4 : dest[dlen] = '\0';
8151 985 : 4 : }
986 : :
987 : : int
8196 meskes@postgresql.or 988 :UBC 0 : rgetmsg(int msgnum, char *s, int maxsize)
989 : : {
990 : : (void) msgnum; /* keep the compiler quiet */
991 : : (void) s; /* keep the compiler quiet */
992 : : (void) maxsize; /* keep the compiler quiet */
993 : 0 : return 0;
994 : : }
995 : :
996 : : int
997 : 0 : rtypalign(int offset, int type)
998 : : {
999 : : (void) offset; /* keep the compiler quiet */
1000 : : (void) type; /* keep the compiler quiet */
1001 : 0 : return 0;
1002 : : }
1003 : :
1004 : : int
1005 : 0 : rtypmsize(int type, int len)
1006 : : {
1007 : : (void) type; /* keep the compiler quiet */
1008 : : (void) len; /* keep the compiler quiet */
1009 : 0 : return 0;
1010 : : }
1011 : :
1012 : : int
8151 1013 : 0 : rtypwidth(int sqltype, int sqllen)
1014 : : {
1015 : : (void) sqltype; /* keep the compiler quiet */
1016 : : (void) sqllen; /* keep the compiler quiet */
1017 : 0 : return 0;
1018 : : }
1019 : :
1020 : : void
8121 1021 : 0 : ECPG_informix_set_var(int number, void *pointer, int lineno)
1022 : : {
5702 1023 : 0 : ECPGset_var(number, pointer, lineno);
8121 1024 : 0 : }
1025 : :
1026 : : void *
1027 : 0 : ECPG_informix_get_var(int number)
1028 : : {
5702 1029 : 0 : return ECPGget_var(number);
1030 : : }
1031 : :
1032 : : void
5867 1033 : 0 : ECPG_informix_reset_sqlca(void)
1034 : : {
1035 : 0 : struct sqlca_t *sqlca = ECPGget_sqlca();
1036 : :
3736 1037 [ # # ]: 0 : if (sqlca == NULL)
1038 : 0 : return;
1039 : :
206 peter@eisentraut.org 1040 : 0 : memcpy(sqlca, &sqlca_init, sizeof(struct sqlca_t));
1041 : : }
1042 : :
1043 : : int
8069 bruce@momjian.us 1044 :CBC 2663 : rsetnull(int t, char *ptr)
1045 : : {
7741 meskes@postgresql.or 1046 : 2663 : ECPGset_noind_null(t, ptr);
8109 1047 : 2663 : return 0;
1048 : : }
1049 : :
1050 : : int
2867 peter_e@gmx.net 1051 : 3646 : risnull(int t, const char *ptr)
1052 : : {
2942 1053 : 3646 : return ECPGis_noind_null(t, ptr);
1054 : : }
|