GnuCOBOL  2.0
A free COBOL compiler
intrinsic.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 2005-2012, 2014-2016 Free Software Foundation, Inc.
3  Written by Roger While, Simon Sobisch, Edward Hart
4 
5  This file is part of GnuCOBOL.
6 
7  The GnuCOBOL runtime library is free software: you can redistribute it
8  and/or modify it under the terms of the GNU Lesser General Public License
9  as published by the Free Software Foundation, either version 3 of the
10  License, or (at your option) any later version.
11 
12  GnuCOBOL is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with GnuCOBOL. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 
22 #include "config.h"
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <stddef.h>
27 #include <stdarg.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <errno.h>
31 #include <time.h>
32 #ifdef HAVE_SYS_TIME_H
33 #include <sys/time.h>
34 #endif
35 #include <math.h>
36 
37 /* Note we include the Cygwin version of windows.h here */
38 #if defined(_WIN32) || defined(__CYGWIN__) || defined(HAVE_LANGINFO_CODESET)
39 #define LOCTIME_BUFSIZE 128
40 
41 #if defined(_WIN32) || defined(__CYGWIN__)
42 #undef HAVE_LANGINFO_CODESET
43 #define WIN32_LEAN_AND_MEAN
44 #include <windows.h>
45 #ifdef _WIN32
46 #include <sys/timeb.h>
47 #endif
48 #endif
49 
50 #ifdef HAVE_LANGINFO_CODESET
51 #include <langinfo.h>
52 #endif
53 #endif
54 
55 #ifdef HAVE_LOCALE_H
56 #include <locale.h>
57 #endif
58 
59 /* Force symbol exports */
60 #define COB_LIB_EXPIMP
61 
62 #include "libcob.h"
63 #include "coblocal.h"
64 
65 /* Function prototypes */
66 static cob_u32_t integer_of_date (const int, const int, const int);
67 static void get_iso_week (const int, int *, int *);
68 
69 /* Local variables */
70 
72 
74  {COB_TYPE_ALPHANUMERIC, 0, 0, 0, NULL};
75 
76 /* Working fields */
78 
79 static cob_decimal d1;
80 static cob_decimal d2;
81 static cob_decimal d3;
82 static cob_decimal d4;
83 static cob_decimal d5;
84 
85 static mpz_t cob_mexp;
86 static mpz_t cob_mpzt;
87 
88 static mpf_t cob_mpft;
89 static mpf_t cob_mpft2;
90 static mpf_t cob_mpft_get;
91 static mpf_t cob_log_half;
92 static mpf_t cob_sqrt_two;
93 static mpf_t cob_pi;
94 
95 
96 /* Stack definitions for created fields */
97 
98 struct calc_struct {
101  size_t calc_size;
102 };
103 
104 static struct calc_struct *calc_base;
107 
108 /* Constants for date/day calculations */
109 static const int normal_days[] =
110  {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
111 static const int leap_days[] =
112  {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};
113 static const int normal_month_days[] =
114  {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
115 static const int leap_month_days[] =
116  {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
117 
118 
119 #define COB_DATESTR_LEN 11
120 #define COB_DATESTR_MAX (COB_DATESTR_LEN - 1)
121 
122 #define COB_TIMEDEC_MAX 9
123 
124 #define COB_TIMESTR_LEN 26 /* including max decimal places */
125 #define COB_TIMESTR_MAX (COB_TIMESTR_LEN - 1)
126 
127 #define COB_DATETIMESTR_LEN 36
128 #define COB_DATETIMESTR_MAX (COB_DATETIMESTR_LEN - 1)
129 
130 /* Locale name to Locale ID table */
131 #if defined(_WIN32) || defined(__CYGWIN__)
132 
133 struct winlocale {
134  const char *winlocalename;
135  const int winlocaleid;
136 };
137 
138 static const struct winlocale wintable[] =
139 {
140  { "af_ZA", 0x0436 },
141  { "am_ET", 0x045e },
142  { "ar_AE", 0x3801 },
143  { "ar_BH", 0x3c01 },
144  { "ar_DZ", 0x1401 },
145  { "ar_EG", 0x0c01 },
146  { "ar_IQ", 0x0801 },
147  { "ar_JO", 0x2c01 },
148  { "ar_KW", 0x3401 },
149  { "ar_LB", 0x3001 },
150  { "ar_LY", 0x1001 },
151  { "ar_MA", 0x1801 },
152  { "ar_OM", 0x2001 },
153  { "ar_QA", 0x4001 },
154  { "ar_SA", 0x0401 },
155  { "ar_SY", 0x2801 },
156  { "ar_TN", 0x1c01 },
157  { "ar_YE", 0x2401 },
158  { "arn_CL", 0x047a },
159  { "as_IN", 0x044d },
160  { "az_Cyrl_AZ", 0x082c },
161  { "az_Latn_AZ", 0x042c },
162  { "ba_RU", 0x046d },
163  { "be_BY", 0x0423 },
164  { "bg_BG", 0x0402 },
165  { "bn_IN", 0x0445 },
166  { "bo_BT", 0x0851 },
167  { "bo_CN", 0x0451 },
168  { "br_FR", 0x047e },
169  { "bs_Cyrl_BA", 0x201a },
170  { "bs_Latn_BA", 0x141a },
171  { "ca_ES", 0x0403 },
172  { "cs_CZ", 0x0405 },
173  { "cy_GB", 0x0452 },
174  { "da_DK", 0x0406 },
175  { "de_AT", 0x0c07 },
176  { "de_CH", 0x0807 },
177  { "de_DE", 0x0407 },
178  { "de_LI", 0x1407 },
179  { "de_LU", 0x1007 },
180  { "dsb_DE", 0x082e },
181  { "dv_MV", 0x0465 },
182  { "el_GR", 0x0408 },
183  { "en_029", 0x2409 },
184  { "en_AU", 0x0c09 },
185  { "en_BZ", 0x2809 },
186  { "en_CA", 0x1009 },
187  { "en_GB", 0x0809 },
188  { "en_IE", 0x1809 },
189  { "en_IN", 0x4009 },
190  { "en_JM", 0x2009 },
191  { "en_MY", 0x4409 },
192  { "en_NZ", 0x1409 },
193  { "en_PH", 0x3409 },
194  { "en_SG", 0x4809 },
195  { "en_TT", 0x2c09 },
196  { "en_US", 0x0409 },
197  { "en_ZA", 0x1c09 },
198  { "en_ZW", 0x3009 },
199  { "es_AR", 0x2c0a },
200  { "es_BO", 0x400a },
201  { "es_CL", 0x340a },
202  { "es_CO", 0x240a },
203  { "es_CR", 0x140a },
204  { "es_DO", 0x1c0a },
205  { "es_EC", 0x300a },
206  { "es_ES", 0x040a },
207  { "es_GT", 0x100a },
208  { "es_HN", 0x480a },
209  { "es_MX", 0x080a },
210  { "es_NI", 0x4c0a },
211  { "es_PA", 0x180a },
212  { "es_PE", 0x280a },
213  { "es_PR", 0x500a },
214  { "es_PY", 0x3c0a },
215  { "es_SV", 0x440a },
216  { "es_US", 0x540a },
217  { "es_UY", 0x380a },
218  { "es_VE", 0x200a },
219  { "et_EE", 0x0425 },
220  { "eu_ES", 0x042d },
221  { "fa_IR", 0x0429 },
222  { "fi_FI", 0x040b },
223  { "fil_PH", 0x0464 },
224  { "fo_FO", 0x0438 },
225  { "fr_BE", 0x080c },
226  { "fr_CA", 0x0c0c },
227  { "fr_CH", 0x100c },
228  { "fr_FR", 0x040c },
229  { "fr_LU", 0x140c },
230  { "fr_MC", 0x180c },
231  { "fy_NL", 0x0462 },
232  { "ga_IE", 0x083c },
233  { "gbz_AF", 0x048c },
234  { "gd", 0x043c },
235  { "gl_ES", 0x0456 },
236  { "gsw_FR", 0x0484 },
237  { "gu_IN", 0x0447 },
238  { "ha_Latn_NG", 0x0468 },
239  { "he_IL", 0x040d },
240  { "hi_IN", 0x0439 },
241  { "hr_BA", 0x101a },
242  { "hr_HR", 0x041a },
243  { "hu_HU", 0x040e },
244  { "hy_AM", 0x042b },
245  { "id_ID", 0x0421 },
246  { "ig_NG", 0x0470 },
247  { "ii_CN", 0x0478 },
248  { "is_IS", 0x040f },
249  { "it_CH", 0x0810 },
250  { "it_IT", 0x0410 },
251  { "iu_Cans_CA", 0x045d },
252  { "iu_Latn_CA", 0x085d },
253  { "ja_JP", 0x0411 },
254  { "ka_GE", 0x0437 },
255  { "kh_KH", 0x0453 },
256  { "kk_KZ", 0x043f },
257  { "kl_GL", 0x046f },
258  { "kn_IN", 0x044b },
259  { "ko_KR", 0x0412 },
260  { "kok_IN", 0x0457 },
261  { "ky_KG", 0x0440 },
262  { "lb_LU", 0x046e },
263  { "lo_LA", 0x0454 },
264  { "lt_LT", 0x0427 },
265  { "lv_LV", 0x0426 },
266  { "mi_NZ", 0x0481 },
267  { "mk_MK", 0x042f },
268  { "ml_IN", 0x044c },
269  { "mn_Cyrl_MN", 0x0450 },
270  { "mn_Mong_CN", 0x0850 },
271  { "moh_CA", 0x047c },
272  { "mr_IN", 0x044e },
273  { "ms_BN", 0x083e },
274  { "ms_MY", 0x043e },
275  { "mt_MT", 0x043a },
276  { "nb_NO", 0x0414 },
277  { "ne_NP", 0x0461 },
278  { "nl_BE", 0x0813 },
279  { "nl_NL", 0x0413 },
280  { "nn_NO", 0x0814 },
281  { "ns_ZA", 0x046c },
282  { "oc_FR", 0x0482 },
283  { "or_IN", 0x0448 },
284  { "pa_IN", 0x0446 },
285  { "pl_PL", 0x0415 },
286  { "ps_AF", 0x0463 },
287  { "pt_BR", 0x0416 },
288  { "pt_PT", 0x0816 },
289  { "qut_GT", 0x0486 },
290  { "quz_BO", 0x046b },
291  { "quz_EC", 0x086b },
292  { "quz_PE", 0x0c6b },
293  { "rm_CH", 0x0417 },
294  { "ro_MO", 0x0818 },
295  { "ro_RO", 0x0418 },
296  { "ru_MO", 0x0819 },
297  { "ru_RU", 0x0419 },
298  { "rw_RW", 0x0487 },
299  { "sa_IN", 0x044f },
300  { "sah_RU", 0x0485 },
301  { "se_FI", 0x0c3b },
302  { "se_NO", 0x043b },
303  { "se_SE", 0x083b },
304  { "si_LK", 0x045b },
305  { "sk_SK", 0x041b },
306  { "sl_SI", 0x0424 },
307  { "sma_NO", 0x183b },
308  { "sma_SE", 0x1c3b },
309  { "smj_NO", 0x103b },
310  { "smj_SE", 0x143b },
311  { "smn_FI", 0x243b },
312  { "sms_FI", 0x203b },
313  { "sq_AL", 0x041c },
314  { "sr_Cyrl_BA", 0x1c1a },
315  { "sr_Cyrl_CS", 0x0c1a },
316  { "sr_Latn_BA", 0x181a },
317  { "sr_Latn_CS", 0x081a },
318  { "st", 0x0430 },
319  { "sv_FI", 0x081d },
320  { "sv_SE", 0x041d },
321  { "sw_KE", 0x0441 },
322  { "syr_SY", 0x045a },
323  { "ta_IN", 0x0449 },
324  { "te_IN", 0x044a },
325  { "tg_Cyrl_TJ", 0x0428 },
326  { "th_TH", 0x041e },
327  { "tk_TM", 0x0442 },
328  { "tmz_Latn_DZ", 0x085f },
329  { "tn_ZA", 0x0432 },
330  { "tr_IN", 0x0820 },
331  { "tr_TR", 0x041f },
332  { "ts", 0x0431 },
333  { "tt_RU", 0x0444 },
334  { "ug_CN", 0x0480 },
335  { "uk_UA", 0x0422 },
336  { "ur_PK", 0x0420 },
337  { "uz_Cyrl_UZ", 0x0843 },
338  { "uz_Latn_UZ", 0x0443 },
339  { "vi_VN", 0x042a },
340  { "wen_DE", 0x042e },
341  { "wo_SN", 0x0488 },
342  { "xh_ZA", 0x0434 },
343  { "yi", 0x043d },
344  { "yo_NG", 0x046a },
345  { "zh_CN", 0x0804 },
346  { "zh_HK", 0x0c04 },
347  { "zh_MO", 0x1404 },
348  { "zh_SG", 0x1004 },
349  { "zh_TW", 0x0404 },
350  { "zu_ZA", 0x0435 }
351 };
352 
353 #define WINLOCSIZE sizeof(wintable) / sizeof(struct winlocale)
354 
355 #endif
356 
357 
358 /* Pi - Next 3 digits 000 */
359 static const char cob_pi_str[] =
360  "3.141592653589793238462643383279502884197169399375"
361  "10582097494459230781640628620899862803482534211706"
362  "79821480865132823066470938446095505822317253594081"
363  "28481117450284102701938521105559644622948954930381"
364  "96442881097566593344612847564823378678316527120190"
365  "91456485669234603486104543266482133936072602491412"
366  "73724587006606315588174881520920962829254091715364"
367  "36789259036001133053054882046652138414695194151160"
368  "94330572703657595919530921861173819326117931051185"
369  "48074462379962749567351885752724891227938183011949"
370  "12983367336244065664308602139494639522473719070217"
371  "98609437027705392171762931767523846748184676694051"
372  "32000568127145263560827785771342757789609173637178"
373  "72146844090122495343014654958537105079227968925892"
374  "35420199561121290219608640344181598136297747713099"
375  "60518707211349999998372978049951059731732816096318"
376  "59502445945534690830264252230825334468503526193118"
377  "817101";
378 /* Sqrt 2 - Next 3 digits 001 */
379 static const char cob_sqrt_two_str[] =
380  "1.414213562373095048801688724209698078569671875376"
381  "94807317667973799073247846210703885038753432764157"
382  "27350138462309122970249248360558507372126441214970"
383  "99935831413222665927505592755799950501152782060571"
384  "47010955997160597027453459686201472851741864088919"
385  "86095523292304843087143214508397626036279952514079"
386  "89687253396546331808829640620615258352395054745750"
387  "28775996172983557522033753185701135437460340849884"
388  "71603868999706990048150305440277903164542478230684"
389  "92936918621580578463111596668713013015618568987237"
390  "23528850926486124949771542183342042856860601468247"
391  "20771435854874155657069677653720226485447015858801"
392  "62075847492265722600208558446652145839889394437092"
393  "65918003113882464681570826301005948587040031864803"
394  "42194897278290641045072636881313739855256117322040"
395  "24509122770022694112757362728049573810896750401836"
396  "98683684507257993647290607629969413804756548237289"
397  "97180326802474420629269124859052181004459842150591"
398  "12024944134172853147810580360337107730918286931471"
399  "01711116839165817268894197587165821521282295184884"
400  "72089694633862891562882765952635140542267653239694"
401  "61751129160240871551013515045538128756005263146801"
402  "71274026539694702403005174953188629256313851881634"
403  "78";
404 /* Log 0.5 - Next 3 digits 000 */
405 static const char cob_log_half_str[] =
406  "-0.69314718055994530941723212145817656807550013436"
407  "02552541206800094933936219696947156058633269964186"
408  "87542001481020570685733685520235758130557032670751"
409  "63507596193072757082837143519030703862389167347112"
410  "33501153644979552391204751726815749320651555247341"
411  "39525882950453007095326366642654104239157814952043"
412  "74043038550080194417064167151864471283996817178454"
413  "69570262716310645461502572074024816377733896385506"
414  "95260668341137273873722928956493547025762652098859"
415  "69320196505855476470330679365443254763274495125040"
416  "60694381471046899465062201677204245245296126879465"
417  "46193165174681392672504103802546259656869144192871"
418  "60829380317271436778265487756648508567407764845146"
419  "44399404614226031930967354025744460703080960850474"
420  "86638523138181676751438667476647890881437141985494"
421  "23151997354880375165861275352916610007105355824987"
422  "94147295092931138971559982056543928717";
423 
424 /* mpf_init2 length = ceil (log2 (10) * strlen (x)) */
425 #define COB_PI_LEN 2820UL
426 #define COB_SQRT_TWO_LEN 3827UL
427 #define COB_LOG_HALF_LEN 2784UL
428 
429 #define RETURN_IF_NOT_ZERO(expr) \
430  do { \
431  int error_pos = (expr); \
432  if (error_pos != 0) { \
433  return error_pos; \
434  } \
435  } ONCE_COB
436 
437 /* Local functions */
438 
439 static void
441 {
442  unsigned char *s;
443  struct calc_struct *calc_temp;
444 
445  calc_temp = calc_base + curr_entry;
446  curr_field = &calc_temp->calc_field;
447  if (f->size > calc_temp->calc_size) {
448  if (curr_field->data) {
449  cob_free (curr_field->data);
450  }
451  calc_temp->calc_size = f->size + 1;
452  s = cob_malloc (f->size + 1U);
453  } else {
454  s = curr_field->data;
455  memset (s, 0, f->size);
456  }
457 
458  *curr_field = *f;
459  calc_temp->calc_attr = *(f->attr);
460  curr_field->attr = &calc_temp->calc_attr;
461 
462  curr_field->data = s;
463 
464  if (++curr_entry >= COB_DEPTH_LEVEL) {
465  curr_entry = 0;
466  }
467 }
468 
469 static int
470 leap_year (const int year)
471 {
472  return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) ? 1 : 0;
473 }
474 
475 static int
476 comp_field (const void *m1, const void *m2)
477 {
478  cob_field *f1;
479  cob_field *f2;
480 
481  f1 = *(cob_field **) m1;
482  f2 = *(cob_field **) m2;
483  return cob_cmp (f1, f2);
484 }
485 
486 /* Reference modification */
487 static void
488 calc_ref_mod (cob_field *f, const int offset, const int length)
489 {
490  size_t calcoff;
491  size_t size;
492 
493  if ((size_t)offset <= f->size) {
494  calcoff = (size_t)offset - 1;
495  size = f->size - calcoff;
496  if (length > 0 && (size_t)length < size) {
497  size = (size_t)length;
498  }
499  f->size = size;
500  if (calcoff > 0) {
501  memmove (f->data, f->data + calcoff, size);
502  }
503  }
504 }
505 
506 /* Decimal <-> Decimal */
507 
508 static COB_INLINE COB_A_INLINE void
510 {
511  mpz_set (dst->value, src->value);
512  dst->scale = src->scale;
513 }
514 
515 /* Trim trailing zeros in decimal places */
516 static void
518 {
519  if (!mpz_sgn (d->value)) {
520  /* Value is zero */
521  d->scale = 0;
522  return;
523  }
524  for ( ; d->scale > 0; d->scale--) {
525  if (!mpz_divisible_ui_p (d->value, 10UL)) {
526  break;
527  }
528  mpz_tdiv_q_ui (d->value, d->value, 10UL);
529  }
530 }
531 
532 static void
533 cob_alloc_set_field_int (const int val)
534 {
535  cob_u16_t attrsign;
536  cob_field_attr attr;
537  cob_field field;
538 
539  if (val < 0) {
540  attrsign = COB_FLAG_HAVE_SIGN;
541  } else {
542  attrsign = 0;
543  }
545  0, attrsign, NULL);
546  COB_FIELD_INIT (4, NULL, &attr);
547  make_field_entry (&field);
548  memcpy (curr_field->data, &val, sizeof(int));
549 }
550 
551 static void
553 {
554  cob_field_attr attr;
555  cob_field field;
556 
558  0, 0, NULL);
559  COB_FIELD_INIT (4, NULL, &attr);
560  make_field_entry (&field);
561  memcpy (curr_field->data, &val, sizeof(cob_u32_t));
562 }
563 
564 static void
566 {
567  size_t bitnum;
568  size_t sign;
569  unsigned short attrsign;
570  short size, scale;
571  cob_field_attr attr;
572  cob_field field;
573 
574  if (unlikely(d->scale == COB_DECIMAL_NAN)) {
575  /* Check this */
578  0, 0, NULL);
579  COB_FIELD_INIT (4, NULL, &attr);
580  make_field_entry (&field);
581  return;
582  }
583 
584  if (mpz_sgn (d->value) < 0) {
585  attrsign = COB_FLAG_HAVE_SIGN;
586  sign = 1;
587  } else {
588  attrsign = 0;
589  sign = 0;
590  }
591 
592  cob_trim_decimal (d);
593 
594  bitnum = mpz_sizeinbase (d->value, 2);
595  if (bitnum < (33 - sign) && d->scale < 10) {
596  /* 4 bytes binary */
598  (short)d->scale, attrsign, NULL);
599  COB_FIELD_INIT (4, NULL, &attr);
600  make_field_entry (&field);
601  } else if (bitnum < (65 - sign) && d->scale < 19) {
602  /* 8 bytes binary */
604  (short)d->scale, attrsign, NULL);
605  COB_FIELD_INIT (8, NULL, &attr);
606  make_field_entry (&field);
607  } else {
608  /* Display decimal */
609  size = (short)mpz_sizeinbase (d->value, 10);
610  if (d->scale > size) {
611  size = (short)d->scale;
612  }
613  scale = (short)d->scale;
615  scale, attrsign, NULL);
616  COB_FIELD_INIT (size, NULL, &attr);
617  make_field_entry (&field);
618  }
619 }
620 
621 /* Common function for intrinsics MOD and REM */
622 
623 static cob_field *
624 cob_mod_or_rem (cob_field *f1, cob_field *f2, const int func_is_rem)
625 {
626  int sign;
627 
628  cob_set_exception (0);
629  cob_decimal_set_field (&d2, f1);
630  cob_decimal_set_field (&d3, f2);
631 
632  if (!mpz_sgn (d3.value)) {
633  /* Divide by zero */
636  return curr_field;
637  }
638 
639  cob_decimal_div (&d2, &d3);
640 
641  /* Caclulate integer / integer-part */
642  if (d2.scale < 0) {
643  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)-d2.scale);
644  mpz_mul (d2.value, d2.value, cob_mexp);
645  } else if (d2.scale > 0) {
646  sign = mpz_sgn (d2.value);
647  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)d2.scale);
648  if (func_is_rem) {
649  /* REMAINDER function - INTEGER-PART */
650  mpz_tdiv_q (d2.value, d2.value, cob_mexp);
651  } else {
652  /* MOD function - INTEGER */
653  mpz_tdiv_qr (d2.value, cob_mpzt, d2.value, cob_mexp);
654  /* Check negative and has decimal places */
655  if (sign < 0 && mpz_sgn (cob_mpzt)) {
656  mpz_sub_ui (d2.value, d2.value, 1UL);
657  }
658  }
659  }
660  d2.scale = 0;
661 
662  cob_decimal_set_field (&d1, f2);
663  cob_decimal_mul (&d2, &d1);
664  cob_decimal_set_field (&d1, f1);
665  cob_decimal_sub (&d1, &d2);
666 
667  cob_alloc_field (&d1);
668  (void)cob_decimal_get_field (&d1, curr_field, 0);
669  return curr_field;
670 }
671 
672 /* Validate NUMVAL-F item */
673 /* sp = spaces */
674 /* [sp][+|-][sp]{digits[.[digits]]|.digits}[sp][E[sp]{+|-}[sp]digits[sp]] */
675 
676 static int
677 cob_check_numval_f (const cob_field *srcfield)
678 {
679  unsigned char *p;
680  size_t plus_minus;
681  size_t digits;
682  size_t dec_seen;
683  size_t space_seen;
684  size_t e_seen;
685  size_t break_needed;
686  size_t exponent;
687  size_t e_plus_minus;
688  int n;
689  unsigned char dec_pt;
690 
691  if (!srcfield->size) {
692  return 1;
693  }
694  p = srcfield->data;
695  plus_minus = 0;
696  digits = 0;
697  dec_seen = 0;
698  space_seen = 0;
699  e_seen = 0;
700  break_needed = 0;
701  exponent = 0;
702  e_plus_minus = 0;
703  dec_pt = COB_MODULE_PTR->decimal_point;
704 
705  /* Check leading positions */
706  for (n = 0; n < (int)srcfield->size; ++n, ++p) {
707  switch (*p) {
708  case '0':
709  case '1':
710  case '2':
711  case '3':
712  case '4':
713  case '5':
714  case '6':
715  case '7':
716  case '8':
717  case '9':
718  break_needed = 1;
719  break;
720  case ' ':
721  continue;
722  case '+':
723  case '-':
724  if (plus_minus) {
725  return n + 1;
726  }
727  plus_minus = 1;
728  continue;
729  case ',':
730  case '.':
731  if (*p != dec_pt) {
732  return n + 1;
733  }
734  break_needed = 1;
735  break;
736  default:
737  return n + 1;
738  }
739  if (break_needed) {
740  break;
741  }
742  }
743 
744  if (n == (int)srcfield->size) {
745  return n + 1;
746  }
747 
748  for (; n < (int)srcfield->size; ++n, ++p) {
749  switch (*p) {
750  case '0':
751  case '1':
752  case '2':
753  case '3':
754  case '4':
755  case '5':
756  case '6':
757  case '7':
758  case '8':
759  case '9':
760  if (e_seen) {
761  if (++exponent > 4 || !e_plus_minus) {
762  return n + 1;
763  }
764  } else if (++digits > COB_MAX_DIGITS || space_seen) {
765  return n + 1;
766  }
767  continue;
768  case ',':
769  case '.':
770  if (dec_seen || space_seen || e_seen) {
771  return n + 1;
772  }
773  if (*p == dec_pt) {
774  dec_seen = 1;
775  continue;
776  }
777  return n + 1;
778  case ' ':
779  space_seen = 1;
780  continue;
781  case 'E':
782  if (e_seen) {
783  return n + 1;
784  }
785  e_seen = 1;
786  continue;
787  case '+':
788  case '-':
789  if (e_seen) {
790  if (e_plus_minus) {
791  return n + 1;
792  }
793  e_plus_minus = 1;
794  } else {
795  if (plus_minus) {
796  return n + 1;
797  }
798  plus_minus = 1;
799  }
800  continue;
801  default:
802  return n + 1;
803  }
804  }
805 
806  if (!digits || (e_seen && !exponent)) {
807  return n + 1;
808  }
809 
810  return 0;
811 }
812 
813 /* Decimal <-> GMP float */
814 
815 static void
816 cob_decimal_set_mpf (cob_decimal *d, const mpf_t src)
817 {
818  char *p;
819  char *q;
820  cob_sli_t scale;
821  cob_sli_t len;
822 
823  if (!mpf_sgn (src)) {
824  mpz_set_ui (d->value, 0UL);
825  d->scale = 0;
826  return;
827  }
828  q = mpf_get_str (NULL, &scale, 10, (size_t)96, src);
829  p = q;
830  mpz_set_str (d->value, p, 10);
831  if (*p == '-') {
832  ++p;
833  }
834  len = (cob_sli_t)strlen (p);
835  cob_gmp_free (q);
836  len -= scale;
837  if (len >= 0) {
838  d->scale = len;
839  } else {
840  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)-len);
841  mpz_mul (d->value, d->value, cob_mexp);
842  d->scale = 0;
843  }
844 }
845 
846 static void
847 cob_decimal_get_mpf (mpf_t dst, const cob_decimal *d)
848 {
849  cob_sli_t scale;
850 
851  mpf_set_z (dst, d->value);
852  scale = d->scale;
853  if (scale < 0) {
854  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)-scale);
855  mpf_set_z (cob_mpft_get, cob_mexp);
856  mpf_mul (dst, dst, cob_mpft_get);
857  } else if (scale > 0) {
858  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)scale);
859  mpf_set_z (cob_mpft_get, cob_mexp);
860  mpf_div (dst, dst, cob_mpft_get);
861  }
862 }
863 
864 /* Trigonometric formulae (formulas?) from Wikipedia */
865 
866 
867 /* Exp function */
868 /* e ^ x = {n = 0, ...} ( (x ^ n) / n! ) */
869 
870 static void
871 cob_mpf_exp (mpf_t dst_val, const mpf_t src_val)
872 {
873  mpf_t vf1, vf2, vf3;
874  mpf_t dst_temp;
875  cob_sli_t expon, i;
876  cob_uli_t n;
877  cob_u32_t is_negative;
878 
879 
880  mpf_init2 (dst_temp, COB_MPF_PREC);
881 
882  mpf_init2 (vf1, COB_MPF_PREC);
883  mpf_set (vf1, src_val);
884  mpf_init2 (vf2, COB_MPF_PREC);
885  mpf_set_ui (vf2, 1UL);
886  mpf_init2 (vf3, COB_MPF_PREC);
887 
888  mpf_set_ui (dst_temp, 1UL);
889 
890  if (mpf_sgn (vf1) < 0) {
891  mpf_neg (vf1, vf1);
892  is_negative = 1;
893  } else {
894  is_negative = 0;
895  }
896 
897  mpf_get_d_2exp (&expon, vf1);
898  if (expon > 0) {
899  mpf_div_2exp (vf1, vf1, (cob_uli_t)expon);
900  }
901 
902  n = 1;
903  do {
904  mpf_mul (vf2, vf2, vf1);
905  mpf_div_ui (vf2, vf2, (cob_uli_t)n);
906  mpf_set (vf3, dst_temp);
907  mpf_add (dst_temp, dst_temp, vf2);
908  ++n;
909  } while (!mpf_eq (vf3, dst_temp, COB_MPF_CUTOFF));
910 
911  for (i = 0; i < expon; ++i) {
912  mpf_mul (dst_temp, dst_temp, dst_temp);
913  }
914 
915  if (is_negative) {
916  mpf_ui_div (dst_temp, 1UL, dst_temp);
917  }
918 
919  mpf_set (dst_val, dst_temp);
920  mpf_clear (dst_temp);
921 
922  mpf_clear (vf3);
923  mpf_clear (vf2);
924  mpf_clear (vf1);
925 }
926 
927 /* Log function */
928 /* logn (x) = {n = 1, ...} ( ((1 - x) ^ n) / n ) */
929 
930 static void
931 cob_mpf_log (mpf_t dst_val, const mpf_t src_val)
932 {
933  mpf_t vf1, vf2, vf3, vf4;
934  mpf_t dst_temp;
935  cob_sli_t expon;
936  cob_uli_t n;
937 
938 
939 
940  if (mpf_sgn (src_val) <= 0 || !mpf_cmp_ui (src_val, 1UL)) {
941  mpf_set_ui (dst_val, 0UL);
942  return;
943  }
944 
945  mpf_init2 (dst_temp, COB_MPF_PREC);
946 
947  mpf_init2 (vf1, COB_MPF_PREC);
948  mpf_set (vf1, src_val);
949  mpf_init2 (vf2, COB_MPF_PREC);
950  mpf_init2 (vf3, COB_MPF_PREC);
951  mpf_set_si (vf3, -1L);
952  mpf_init2 (vf4, COB_MPF_PREC);
953 
954  mpf_set_ui (dst_temp, 0UL);
955  mpf_get_d_2exp (&expon, vf1);
956  if (expon != 0) {
957  mpf_set (dst_temp, cob_log_half);
958  if (expon > 0) {
959  mpf_mul_ui (dst_temp, dst_temp, (cob_uli_t)expon);
960  mpf_neg (dst_temp, dst_temp);
961  mpf_div_2exp (vf1, vf1, (cob_uli_t)expon);
962  } else {
963  mpf_mul_ui (dst_temp, dst_temp, (cob_uli_t)-expon);
964  mpf_mul_2exp (vf1, vf1, (cob_uli_t)-expon);
965  }
966  }
967  mpf_ui_sub (vf1, 1UL, vf1);
968 
969  n = 1;
970  do {
971  mpf_mul (vf3, vf3, vf1);
972  mpf_div_ui (vf2, vf3, n);
973  mpf_set (vf4, dst_temp);
974  mpf_add (dst_temp, dst_temp, vf2);
975  ++n;
976  } while (!mpf_eq (vf4, dst_temp, COB_MPF_CUTOFF));
977 
978  mpf_set (dst_val, dst_temp);
979  mpf_clear (dst_temp);
980 
981  mpf_clear (vf4);
982  mpf_clear (vf3);
983  mpf_clear (vf2);
984  mpf_clear (vf1);
985 }
986 
987 /* Log10 function */
988 /* log10 (x) = log (x) / log (10) */
989 
990 static void
991 cob_mpf_log10 (mpf_t dst_val, const mpf_t src_val)
992 {
993  mpf_t vf1;
994  mpf_t dst_temp;
995 
996  mpf_init2 (dst_temp, COB_MPF_PREC);
997 
998  mpf_init2 (vf1, COB_MPF_PREC);
999 
1000  cob_mpf_log (dst_temp, src_val);
1001  mpf_set_ui (vf1, 10UL);
1002  cob_mpf_log (vf1, vf1);
1003  mpf_div (dst_temp, dst_temp, vf1);
1004 
1005  mpf_set (dst_val, dst_temp);
1006  mpf_clear (dst_temp);
1007 
1008  mpf_clear (vf1);
1009 }
1010 
1011 /* Sin function */
1012 /* sin (x) = (reduce to pi/2) */
1013 /* {n = 0, ...} ( (-1 ^ n) * ( x ^ (2n + 1)) / (2n + 1) ) */
1014 
1015 static void
1016 cob_mpf_sin (mpf_t dst_val, const mpf_t src_val)
1017 {
1018  mpf_t vf1, vf2, vf3, vf4, vf5;
1019  mpf_t dst_temp;
1020  cob_uli_t arcquad;
1021  cob_uli_t n;
1022  int sign;
1023 
1024  mpf_init2 (dst_temp, COB_MPF_PREC);
1025 
1026  mpf_init2 (vf1, COB_MPF_PREC);
1027  mpf_init2 (vf2, COB_MPF_PREC);
1028  mpf_init2 (vf3, COB_MPF_PREC);
1029  mpf_init2 (vf4, COB_MPF_PREC);
1030  mpf_init2 (vf5, COB_MPF_PREC);
1031  sign = mpf_sgn (src_val);
1032 
1033  mpf_abs (vf4, src_val);
1034  mpf_set (vf3, cob_pi);
1035  mpf_div_2exp (vf3, vf3, 1UL);
1036  mpf_div (vf1, vf4, vf3);
1037  mpf_floor (vf4, vf1);
1038 
1039  if (mpf_cmp_ui (vf4, 4UL) >= 0) {
1040  mpf_div_2exp (vf2, vf4, 2UL);
1041  mpf_floor (vf2, vf2);
1042  mpf_mul_2exp (vf2, vf2, 2UL);
1043  mpf_sub (vf2, vf4, vf2);
1044  } else {
1045  mpf_set (vf2, vf4);
1046  }
1047 
1048  arcquad = mpf_get_ui (vf2);
1049  mpf_sub (vf2, vf1, vf4);
1050  mpf_mul (vf4, vf3, vf2);
1051 
1052  if (arcquad > 1) {
1053  sign = -sign;
1054  }
1055  if (arcquad & 1) {
1056  mpf_sub (vf4, vf3, vf4);
1057  }
1058 
1059  mpf_mul (vf3, vf4, vf4);
1060  mpf_neg (vf3, vf3);
1061 
1062  n = 1;
1063  mpf_set_ui (vf2, 1UL);
1064  mpf_set_ui (dst_temp, 1UL);
1065 
1066  do {
1067  ++n;
1068  mpf_div_ui (vf2, vf2, n);
1069  ++n;
1070  mpf_div_ui (vf2, vf2, n);
1071  mpf_mul (vf2, vf2, vf3);
1072  mpf_set (vf5, dst_temp);
1073  mpf_add (dst_temp, dst_temp, vf2);
1074  } while (!mpf_eq (vf5, dst_temp, COB_MPF_PREC));
1075 
1076  mpf_mul (dst_temp, dst_temp, vf4);
1077  if (sign < 0) {
1078  mpf_neg (dst_temp, dst_temp);
1079  }
1080 
1081  mpf_set (dst_val, dst_temp);
1082  mpf_clear (dst_temp);
1083 
1084  mpf_clear (vf5);
1085  mpf_clear (vf4);
1086  mpf_clear (vf3);
1087  mpf_clear (vf2);
1088  mpf_clear (vf1);
1089 }
1090 
1091 /* Cos function */
1092 /* cos (x) = sin ((pi / 2) - x) */
1093 
1094 static void
1095 cob_mpf_cos (mpf_t dst_val, const mpf_t src_val)
1096 {
1097  mpf_t vf1;
1098 
1099  mpf_init2 (vf1, COB_MPF_PREC);
1100 
1101  mpf_set (vf1, cob_pi);
1102  mpf_div_2exp (vf1, vf1, 1UL);
1103  mpf_sub (vf1, vf1, src_val);
1104  cob_mpf_sin (dst_val, vf1);
1105 
1106  mpf_clear (vf1);
1107 }
1108 
1109 /* Tan function */
1110 /* tan (x) = sin(x) / cos(x) */
1111 
1112 static void
1113 cob_mpf_tan (mpf_t dst_val, const mpf_t src_val)
1114 {
1115  mpf_t vf1;
1116  mpf_t vf2;
1117 
1118  mpf_init2 (vf1, COB_MPF_PREC);
1119  mpf_init2 (vf2, COB_MPF_PREC);
1120 
1121  cob_mpf_sin (vf1, src_val);
1122  cob_mpf_cos (vf2, src_val);
1123  mpf_div (dst_val, vf1, vf2);
1124 
1125  mpf_clear (vf1);
1126  mpf_clear (vf2);
1127 }
1128 
1129 /* Atan function */
1130 
1131 static void
1132 cob_mpf_atan (mpf_t dst_val, const mpf_t src_val)
1133 {
1134  mpf_t vf1, vf2, vf3, vf4;
1135  mpf_t dst_temp;
1136  cob_uli_t n;
1137 
1138  mpf_init2 (dst_temp, COB_MPF_PREC);
1139 
1140  mpf_init2 (vf1, COB_MPF_PREC);
1141  mpf_init2 (vf2, COB_MPF_PREC);
1142  mpf_init2 (vf3, COB_MPF_PREC);
1143  mpf_init2 (vf4, COB_MPF_PREC);
1144 
1145  mpf_abs (vf1, src_val);
1146  mpf_add_ui (vf3, cob_sqrt_two, 1UL);
1147 
1148  if (mpf_cmp (vf1, vf3) > 0) {
1149  mpf_set (dst_temp, cob_pi);
1150  mpf_div_2exp (dst_temp, dst_temp, 1UL);
1151  mpf_ui_div (vf1, 1UL, vf1);
1152  mpf_neg (vf1, vf1);
1153  } else {
1154  mpf_sub_ui (vf4, cob_sqrt_two, 1UL);
1155  if (mpf_cmp (vf1, vf4) > 0) {
1156  mpf_set (dst_temp, cob_pi);
1157  mpf_div_2exp (dst_temp, dst_temp, 2UL);
1158  mpf_sub_ui (vf3, vf1, 1UL);
1159  mpf_add_ui (vf4, vf1, 1UL);
1160  mpf_div (vf1, vf3, vf4);
1161  } else {
1162  mpf_set_ui (dst_temp, 0UL);
1163  }
1164  }
1165  mpf_mul (vf2, vf1, vf1);
1166  mpf_neg (vf2, vf2);
1167  mpf_add (dst_temp, dst_temp, vf1);
1168 
1169  n = 1;
1170 
1171  do {
1172  mpf_mul (vf1, vf1, vf2);
1173  mpf_div_ui (vf3, vf1, 2UL * n + 1UL);
1174  mpf_set (vf4, dst_temp);
1175  mpf_add (dst_temp, dst_temp, vf3);
1176  ++n;
1177  } while (!mpf_eq (vf4, dst_temp, COB_MPF_PREC));
1178 
1179  if (mpf_sgn (src_val) < 0) {
1180  mpf_neg (dst_temp, dst_temp);
1181  }
1182 
1183  mpf_set (dst_val, dst_temp);
1184  mpf_clear (dst_temp);
1185 
1186  mpf_clear (vf4);
1187  mpf_clear (vf3);
1188  mpf_clear (vf2);
1189  mpf_clear (vf1);
1190 }
1191 
1192 /* Asin function */
1193 /* asin (x) = 2 * atan (x / (1 + sqrt (1 - (x ** 2)))) */
1194 
1195 static void
1196 cob_mpf_asin (mpf_t dst_val, const mpf_t src_val)
1197 {
1198  mpf_t vf1, vf2;
1199  mpf_t dst_temp;
1200 
1201  mpf_init2 (dst_temp, COB_MPF_PREC);
1202 
1203  if (!mpf_cmp_ui (src_val, 1UL) || !mpf_cmp_si (src_val, -1L)) {
1204  mpf_set (dst_temp, cob_pi);
1205  mpf_div_ui (dst_temp, dst_temp, 2UL);
1206  if (mpf_sgn (src_val) < 0) {
1207  mpf_neg (dst_temp, dst_temp);
1208  }
1209  mpf_set (dst_val, dst_temp);
1210  mpf_clear (dst_temp);
1211  return;
1212  }
1213  if (!mpz_sgn (src_val)) {
1214  mpf_set_ui (dst_val, 0UL);
1215  mpf_clear (dst_temp);
1216  return;
1217  }
1218 
1219  mpf_init2 (vf1, COB_MPF_PREC);
1220  mpf_init2 (vf2, COB_MPF_PREC);
1221 
1222  mpf_mul (vf2, src_val, src_val);
1223  mpf_ui_sub (vf2, 1UL, vf2);
1224  mpf_sqrt (vf2, vf2);
1225 
1226  mpf_add_ui (vf2, vf2, 1UL);
1227 
1228  mpf_div (vf1, src_val, vf2);
1229  cob_mpf_atan (dst_temp, vf1);
1230  mpf_mul_ui (dst_temp, dst_temp, 2UL);
1231 
1232  mpf_set (dst_val, dst_temp);
1233  mpf_clear (dst_temp);
1234 
1235  mpf_clear (vf2);
1236  mpf_clear (vf1);
1237 }
1238 
1239 /* Acos function */
1240 /* acos (x) = 2 * atan (sqrt (1 - (x ** 2)) / (1 + x)) */
1241 
1242 static void
1243 cob_mpf_acos (mpf_t dst_val, const mpf_t src_val)
1244 {
1245  mpf_t vf1, vf2;
1246  mpf_t dst_temp;
1247 
1248  mpf_init2 (dst_temp, COB_MPF_PREC);
1249 
1250  if (!mpf_sgn (src_val)) {
1251  mpf_set (dst_temp, cob_pi);
1252  mpf_div_ui (dst_temp, dst_temp, 2UL);
1253  mpf_set (dst_val, dst_temp);
1254  mpf_clear (dst_temp);
1255  return;
1256  }
1257  if (!mpf_cmp_ui (src_val, 1UL)) {
1258  mpf_set_ui (dst_val, 0UL);
1259  mpf_clear (dst_temp);
1260  return;
1261  }
1262  if (!mpf_cmp_si (src_val, -1L)) {
1263  mpf_set (dst_val, cob_pi);
1264  mpf_clear (dst_temp);
1265  return;
1266  }
1267 
1268  mpf_init2 (vf1, COB_MPF_PREC);
1269  mpf_init2 (vf2, COB_MPF_PREC);
1270 
1271  mpf_add_ui (vf2, src_val, 1UL);
1272  mpf_mul (vf1, src_val, src_val);
1273  mpf_ui_sub (vf1, 1UL, vf1);
1274  mpf_sqrt (vf1, vf1);
1275  mpf_div (vf1, vf1, vf2);
1276  cob_mpf_atan (dst_temp, vf1);
1277  mpf_mul_ui (dst_temp, dst_temp, 2UL);
1278 
1279  mpf_set (dst_val, dst_temp);
1280  mpf_clear (dst_temp);
1281 
1282  mpf_clear (vf2);
1283  mpf_clear (vf1);
1284 }
1285 
1286 /* SUBSTITUTE(-CASE) functions */
1287 
1288 static size_t
1289 get_substituted_size (cob_field *original, cob_field **matches, cob_field **reps,
1290  const int numreps,
1291  int (*cmp_func)(const void *, const void *, size_t))
1292 {
1293  unsigned char *match_begin = original->data;
1294  size_t orig_size = original->size;
1295  size_t calcsize = 0;
1296  size_t cur_idx;
1297  size_t found = 0;
1298  int i;
1299 
1300  for (cur_idx = 0; cur_idx < orig_size; ) {
1301  /* Try to find a match at this point */
1302  for (i = 0; i < numreps; ++i) {
1303  /* If we overflow the string */
1304  if (cur_idx + matches[i]->size > orig_size) {
1305  continue;
1306  }
1307 
1308  /* If we find a match */
1309  if (!(*cmp_func) (match_begin, matches[i]->data, matches[i]->size)) {
1310  /* Go past it */
1311  match_begin += matches[i]->size;
1312  cur_idx += matches[i]->size;
1313  /* Keep track how long new string will be */
1314  calcsize += reps[i]->size;
1315 
1316  found = 1;
1317  break;
1318  }
1319  }
1320 
1321  if (found) {
1322  found = 0;
1323  } else {
1324  /* Move forward one char */
1325  ++cur_idx;
1326  ++match_begin;
1327  ++calcsize;
1328  }
1329  }
1330 
1331  return calcsize;
1332 }
1333 
1334 static void
1335 substitute_matches (cob_field *original, cob_field **matches, cob_field **reps,
1336  const int numreps,
1337  int (*cmp_func)(const void *, const void *, size_t),
1338  unsigned char *replaced_begin)
1339 {
1340  unsigned char *match_begin = original->data;
1341  size_t orig_size = original->size;
1342  size_t cur_idx;
1343  size_t found = 0;
1344  int i;
1345 
1346  for (cur_idx = 0; cur_idx < orig_size; ) {
1347  /* Try to find a match at this point. */
1348  for (i = 0; i < numreps; ++i) {
1349  /* If we overrucur_idx */
1350  if (cur_idx + matches[i]->size > orig_size) {
1351  continue;
1352  }
1353 
1354  /* If we find a match */
1355  if (!(*cmp_func) (match_begin, matches[i]->data, matches[i]->size)) {
1356  /* Write the replacement */
1357  memcpy (replaced_begin, reps[i]->data, reps[i]->size);
1358  /* Move past the match/replacement */
1359  match_begin += matches[i]->size;
1360  replaced_begin += reps[i]->size;
1361  cur_idx += matches[i]->size;
1362 
1363  found = 1;
1364  break;
1365  }
1366  }
1367 
1368  if (found) {
1369  found = 0;
1370  continue;
1371  } else {
1372  /* Add unmatched char to final string and move on one */
1373  ++cur_idx;
1374  *replaced_begin++ = *match_begin++;
1375  }
1376  }
1377 }
1378 
1379 static cob_field *
1380 substitute (const int offset, const int length, const int params,
1381  int (*cmp_func)(const void *, const void *, size_t),
1382  va_list args)
1383 {
1384 
1385  cob_field *original;
1386  cob_field **matches;
1387  cob_field **reps;
1388  int i;
1389  size_t calcsize;
1390  int numreps = params / 2;
1391  cob_field field;
1392 
1393  matches = cob_malloc ((size_t)numreps * sizeof (cob_field *));
1394  reps = cob_malloc ((size_t)numreps * sizeof (cob_field *));
1395 
1396  /* Extract args */
1397  original = va_arg (args, cob_field *);
1398  for (i = 0; i < params - 1; ++i) {
1399  if ((i % 2) == 0) {
1400  matches[i / 2] = va_arg (args, cob_field *);
1401  } else {
1402  reps[i / 2] = va_arg (args, cob_field *);
1403  }
1404  }
1405 
1406  va_end (args);
1407 
1408  /* Perform substitution */
1409 
1410  calcsize = get_substituted_size (original, matches, reps, numreps, cmp_func);
1411 
1412  COB_FIELD_INIT (0, NULL, &const_alpha_attr);
1413  field.size = calcsize;
1414  make_field_entry (&field);
1415 
1416  substitute_matches (original, matches, reps, numreps, cmp_func, curr_field->data);
1417 
1418  /* Output placed in curr_field */
1419 
1420  cob_free (matches);
1421  cob_free (reps);
1422 
1423  if (unlikely (offset > 0)) {
1424  calc_ref_mod (curr_field, offset, length);
1425  }
1426  return curr_field;
1427 }
1428 
1429 static int
1430 int_strncasecmp (const void *s1, const void *s2, size_t n)
1431 {
1432  return (int) strncasecmp (s1, s2, n);
1433 }
1434 
1435 /* NUMVAL */
1436 
1437 static int
1438 in_last_n_chars (const cob_field *field, const size_t n, const int i)
1439 {
1440  return i >= (field->size - n);
1441 }
1442 
1443 static int
1444 at_cr_or_db (const cob_field *srcfield, const int pos)
1445 {
1446  return memcmp (&srcfield->data[pos], "CR", (size_t)2) == 0
1447  || memcmp (&srcfield->data[pos], "DB", (size_t)2) == 0;
1448 }
1449 
1453 };
1454 
1455 static cob_field *
1456 numval (cob_field *srcfield, cob_field *currency, const enum numval_type type)
1457 {
1458  unsigned char *final_buff = cob_malloc (srcfield->size + 1U);
1459  unsigned char *currency_data = NULL;
1460  size_t i;
1461  int final_digits = 0;
1462  int decimal_digits = 0;
1463  int sign = 0;
1464  int decimal_seen = 0;
1465  unsigned char dec_pt = COB_MODULE_PTR->decimal_point;
1466  unsigned char cur_symb = COB_MODULE_PTR->currency_symbol;
1467 
1468  /* Validate source field */
1469  if (cob_check_numval (srcfield, currency, type == NUMVAL_C, 0)) {
1472  return curr_field;
1473  }
1474 
1475  if (currency && currency->size < srcfield->size) {
1476  currency_data = currency->data;
1477  }
1478 
1479  for (i = 0; i < srcfield->size; ++i) {
1480  if (!in_last_n_chars (srcfield, 2, i)
1481  && at_cr_or_db (srcfield, i)) {
1482  sign = 1;
1483  break;
1484  }
1485 
1486  if (currency_data) {
1487  if (!in_last_n_chars (srcfield, currency->size, i)
1488  && !memcmp (&srcfield->data[i], currency_data,
1489  currency->size)) {
1490  i += (currency->size - 1);
1491  continue;
1492  }
1493  } else if (type == NUMVAL_C && srcfield->data[i] == cur_symb) {
1494  continue;
1495  }
1496 
1497  if (srcfield->data[i] == ' ') {
1498  continue;
1499  }
1500  if (srcfield->data[i] == '+') {
1501  continue;
1502  }
1503  if (srcfield->data[i] == '-') {
1504  sign = 1;
1505  continue;
1506  }
1507  if (srcfield->data[i] == dec_pt) {
1508  decimal_seen = 1;
1509  continue;
1510  }
1511  if (srcfield->data[i] >= (unsigned char)'0' &&
1512  srcfield->data[i] <= (unsigned char)'9') {
1513  if (decimal_seen) {
1514  decimal_digits++;
1515  }
1516  final_buff[final_digits++] = srcfield->data[i];
1517  }
1518  if (final_digits > COB_MAX_DIGITS) {
1519  break;
1520  }
1521  }
1522 
1523  /* If srcfield is an empty string */
1524  if (!final_digits) {
1525  final_buff[0] = '0';
1526  }
1527 
1528  mpz_set_str (d1.value, (char *)final_buff, 10);
1529  cob_free (final_buff);
1530  if (sign && mpz_sgn (d1.value)) {
1531  mpz_neg (d1.value, d1.value);
1532  }
1533  d1.scale = decimal_digits;
1534  cob_alloc_field (&d1);
1535  (void)cob_decimal_get_field (&d1, curr_field, 0);
1536 
1537  return curr_field;
1538 }
1539 
1540 /* Numeric functions */
1541 
1542 static void
1543 get_min_and_max_of_args (const int num_args, va_list args, cob_field **min, cob_field **max)
1544 {
1545  int i;
1546  cob_field *f;
1547 
1548  *min = va_arg (args, cob_field *);
1549  *max = *min;
1550 
1551  for (i = 1; i < num_args; ++i) {
1552  f = va_arg (args, cob_field *);
1553  if (cob_cmp (f, *min) < 0) {
1554  *min = f;
1555  }
1556  if (cob_cmp (f, *max) > 0) {
1557  *max = f;
1558  }
1559  }
1560 }
1561 
1562 /* Uses d1 and d2. Return value in d1. */
1563 static void
1564 calc_mean_of_args (const int num_args, va_list args)
1565 {
1566  int i;
1567  cob_field *f;
1568 
1569  mpz_set_ui (d1.value, 0UL);
1570  d1.scale = 0;
1571 
1572  for (i = 0; i < num_args; ++i) {
1573  f = va_arg (args, cob_field *);
1574  cob_decimal_set_field (&d2, f);
1575  cob_decimal_add (&d1, &d2);
1576  }
1577 
1578  mpz_set_ui (d2.value, (cob_uli_t)num_args);
1579  d2.scale = 0;
1580  cob_decimal_div (&d1, &d2);
1581 }
1582 
1583 /* Return variance in d1. Uses d2, d3 and d4. */
1584 static void
1585 calc_variance_of_args (const int n, va_list numbers, cob_decimal *mean)
1586 {
1587  cob_field *f;
1588  int i;
1589  cob_decimal *difference = &d2;
1590  cob_decimal *sum = &d3;
1591  cob_decimal *num_numbers = &d4;
1592 
1593  if (n == 1) {
1594  mpz_set_ui (d1.value, 0UL);
1595  d1.scale = 0;
1596  return;
1597  }
1598 
1599  mpz_set_ui (sum->value, 0UL);
1600  sum->scale = 0;
1601 
1602  /* Get the sum of the squares of the differences from the mean */
1603  /* i.e., Sum ((arg - mean)^2) */
1604  for (i = 0; i < n; ++i) {
1605  f = va_arg (numbers, cob_field *);
1606 
1607  cob_decimal_set_field (difference, f);
1608  cob_decimal_sub (difference, mean);
1609  cob_decimal_mul (difference, difference);
1610  cob_decimal_add (sum, difference);
1611  }
1612 
1613  /* Divide sum by n */
1614  mpz_set_ui (num_numbers->value, (cob_uli_t)n);
1615  num_numbers->scale = 0;
1616  cob_decimal_div (sum, num_numbers);
1617 
1618  cob_decimal_set (&d1, sum);
1619 }
1620 
1621 /* Date/time functions */
1622 
1623 static void
1624 get_interval_and_current_year_from_args (const int num_args, va_list args,
1625  int * const interval, int * const current_year)
1626 {
1627  cob_field *f;
1628  time_t t;
1629  struct tm *timeptr;
1630 
1631  if (num_args > 1) {
1632  f = va_arg (args, cob_field *);
1633  *interval = cob_get_int (f);
1634  } else {
1635  *interval = 50;
1636  }
1637 
1638  if (num_args > 2) {
1639  f = va_arg (args, cob_field *);
1640  *current_year = cob_get_int (f);
1641  } else {
1642  t = time (NULL);
1643  timeptr = localtime (&t);
1644  *current_year = 1900 + timeptr->tm_year;
1645  }
1646 }
1647 
1648 /* Locale time */
1649 
1650 #if defined(_WIN32) || defined(__CYGWIN__) || defined (HAVE_LANGINFO_CODESET)
1651 #ifdef HAVE_LANGINFO_CODESET
1652 static int
1653 locale_time (const int hours, const int minutes, const int seconds,
1654  cob_field *locale_field, char *buff)
1655 {
1656  char *deflocale = NULL;
1657  struct tm tstruct;
1658  char buff2[LOCTIME_BUFSIZE] = { '\0' };
1659  char locale_buff[COB_SMALL_BUFF] = { '\0' };
1660 
1661  /* Initialize tstruct to given time */
1662  memset ((void *)&tstruct, 0, sizeof(struct tm));
1663  tstruct.tm_hour = hours;
1664  tstruct.tm_min = minutes;
1665  tstruct.tm_sec = seconds;
1666 
1667  if (locale_field) {
1668  if (locale_field->size >= COB_SMALL_BUFF) {
1669  return 1;
1670  }
1671  cob_field_to_string (locale_field, locale_buff,
1672  (size_t)COB_SMALL_MAX);
1673  deflocale = locale_buff;
1674  (void) setlocale (LC_TIME, deflocale);
1675  }
1676 
1677  /* Get strftime format string for locale */
1678  memset (buff2, 0, LOCTIME_BUFSIZE);
1679  snprintf(buff2, LOCTIME_BUFSIZE - 1, "%s", nl_langinfo(T_FMT));
1680 
1681  /* Set locale if not done yet */
1682  if (deflocale) {
1683  (void) setlocale (LC_ALL, cobglobptr->cob_locale);
1684  }
1685 
1686  strftime (buff, LOCTIME_BUFSIZE, buff2, &tstruct);
1687 
1688  return 0;
1689 }
1690 #else
1691 static int
1692 locale_time (const int hours, const int minutes, const int seconds,
1693  cob_field *locale_field, char *buff)
1694 {
1695  size_t len;
1696  unsigned char *p;
1697  LCID localeid = LOCALE_USER_DEFAULT;
1698  SYSTEMTIME syst;
1699  char locale_buff[COB_SMALL_BUFF] = { '\0' };
1700 
1701  /* Initialize syst with given time */
1702  memset ((void *)&syst, 0, sizeof(syst));
1703  syst.wHour = (WORD)hours;
1704  syst.wMinute = (WORD)minutes;
1705  syst.wSecond = (WORD)seconds;
1706 
1707  /* Get specified locale */
1708  if (locale_field) {
1709  if (locale_field->size >= COB_SMALL_BUFF) {
1710  return 1;
1711  }
1712  cob_field_to_string (locale_field, locale_buff,
1713  COB_SMALL_MAX);
1714 
1715  /* Null-terminate last char of the locale string */
1716  for (p = (unsigned char *)locale_buff; *p; ++p) {
1717  if (isalnum((int)*p) || *p == '_') {
1718  continue;
1719  }
1720  break;
1721  }
1722  *p = 0;
1723 
1724  /* Find locale ID */
1725  for (len = 0; len < WINLOCSIZE; ++len) {
1726  if (!strcmp(locale_buff, wintable[len].winlocalename)) {
1727  localeid = wintable[len].winlocaleid;
1728  break;
1729  }
1730  }
1731  if (len == WINLOCSIZE) {
1732  return 1;
1733  }
1734  }
1735 
1736  /* Get locale time */
1737  if (!GetTimeFormat (localeid, LOCALE_NOUSEROVERRIDE, &syst, NULL, buff,
1738  LOCTIME_BUFSIZE)) {
1739  return 1;
1740  }
1741 
1742  return 0;
1743 }
1744 #endif
1745 #endif
1746 
1747 /* offset and length are for reference modification */
1748 static void
1749 cob_alloc_set_field_str (char *str, const int offset, const int length)
1750 {
1751  const size_t str_len = strlen (str);
1752  cob_field field;
1753 
1754  COB_FIELD_INIT (str_len, NULL, &const_alpha_attr);
1755  make_field_entry (&field);
1756  memcpy (curr_field->data, str, str_len);
1757 
1758  if (unlikely(offset > 0)) {
1759  calc_ref_mod (curr_field, offset, length);
1760  }
1761 }
1762 
1763 static void
1765 {
1766  cob_field field;
1767 
1768  COB_FIELD_INIT (n, NULL, &const_alpha_attr);
1769  make_field_entry (&field);
1770  memset (curr_field->data, ' ', (size_t)n);
1771 }
1772 
1773 /* Date/time functions */
1774 
1775 static int
1776 days_in_year (const int year)
1777 {
1778  return 365 + leap_year (year);
1779 }
1780 
1781 static COB_INLINE COB_A_INLINE int
1782 in_range (const int min, const int max, const int val)
1783 {
1784  return min <= val && val <= max;
1785 }
1786 
1787 static int
1788 valid_integer_date (const int days)
1789 {
1790  return in_range (1, 3067671, days);
1791 }
1792 
1793 static int
1794 valid_year (const int year)
1795 {
1796  return in_range (1601, 9999, year);
1797 }
1798 
1799 static int
1800 valid_month (const int month)
1801 {
1802  return in_range (1, 12, month);
1803 }
1804 
1805 static int
1806 valid_day_of_year (const int year, const int day)
1807 {
1808  return in_range (1, days_in_year (year), day);
1809 }
1810 
1811 static int
1812 valid_day_of_month (const int year, const int month, const int day)
1813 {
1814  if (leap_year (year)) {
1815  return in_range (1, leap_month_days[month], day);
1816  } else {
1817  return in_range (1, normal_month_days[month], day);
1818  }
1819 }
1820 
1821 static int
1822 max_week (int year)
1823 {
1824  int first_day = integer_of_date (year, 1, 1);
1825  int last_day = first_day + days_in_year (year) - 1;
1826  int week;
1827 
1828  get_iso_week (last_day, &year, &week);
1829  return week;
1830 }
1831 
1832 /* 86400 = 60 * 60 * 24. We'll ignore leap seconds for now. */
1833 #define SECONDS_IN_DAY 86400
1834 
1835 static int
1836 valid_time (const int seconds_from_midnight)
1837 {
1838  return in_range (0, SECONDS_IN_DAY, seconds_from_midnight);
1839 }
1840 
1841 /* Uses d5. */
1842 static int
1843 valid_decimal_time (cob_decimal *seconds_from_midnight)
1844 {
1845  cob_decimal *seconds_in_day = &d5;
1846  mpz_set_ui (seconds_in_day->value, (unsigned long) SECONDS_IN_DAY);
1847  seconds_in_day->scale = 0;
1848 
1849  return cob_decimal_cmp (seconds_from_midnight, seconds_in_day) <= 0;
1850 }
1851 
1852 #undef SECONDS_IN_DAY
1853 
1854 static int
1855 valid_offset_time (const int offset)
1856 {
1857  const int minutes_in_day = 1440; /* 60 * 24 */
1858  return abs (offset) < minutes_in_day;
1859 }
1860 
1861 static void
1862 date_of_integer (int days, int *year, int *month, int *day)
1863 {
1864  int baseyear = 1601;
1865  int leapyear = 365;
1866  int i;
1867 
1868  while (days > leapyear) {
1869  days -= leapyear;
1870  ++baseyear;
1871  leapyear = days_in_year (baseyear);
1872  }
1873  for (i = 0; i < 13; ++i) {
1874  if (leap_year (baseyear)) {
1875  if (i && days <= leap_days[i]) {
1876  days -= leap_days[i - 1];
1877  break;
1878  }
1879  } else {
1880  if (i && days <= normal_days[i]) {
1881  days -= normal_days[i - 1];
1882  break;
1883  }
1884  }
1885  }
1886 
1887  *year = baseyear;
1888  *month = i;
1889  *day = days;
1890 }
1891 
1892 static void
1893 day_of_integer (int days, int *year, int *day)
1894 {
1895  int leapyear = 365;
1896 
1897  *year = 1601;
1898 
1899  while (days > leapyear) {
1900  days -= leapyear;
1901  ++*year;
1902  leapyear = days_in_year (*year);
1903  }
1904 
1905  *day = days;
1906 }
1907 
1908 static cob_u32_t
1909 days_up_to_year (const int year)
1910 {
1911  cob_u32_t totaldays = 0;
1912  int baseyear = 1601;
1913 
1914  while (baseyear != year) {
1915  totaldays += days_in_year (baseyear);
1916  ++baseyear;
1917  }
1918  return totaldays;
1919 }
1920 
1921 static cob_u32_t
1922 integer_of_date (const int year, const int month, const int days)
1923 {
1924  cob_u32_t totaldays;
1925 
1926  totaldays = days_up_to_year (year);
1927 
1928  if (leap_year (year)) {
1929  totaldays += leap_days[month - 1];
1930  } else {
1931  totaldays += normal_days[month - 1];
1932  }
1933  totaldays += days;
1934 
1935  return totaldays;
1936 }
1937 
1938 static cob_u32_t
1939 integer_of_day (const int year, const int days)
1940 {
1941  cob_u32_t totaldays;
1942 
1943  totaldays = days_up_to_year (year);
1944  totaldays += days;
1945 
1946  return totaldays;
1947 }
1948 
1953 };
1954 
1955 struct time_format {
1959 };
1960 
1961 /* Uses d2 */
1962 static void
1963 seconds_from_formatted_time (const struct time_format format, const char *str,
1964  cob_decimal *seconds_decimal)
1965 {
1966  const char *scanf_str = format.with_colons ? "%2d:%2d:%2d" : "%2d%2d%2d";
1967  int hours;
1968  int minutes;
1969  int seconds;
1970  int total_seconds;
1971  int offset;
1972  int end_of_decimal;
1973  int unscaled_fraction = 0;
1974  cob_decimal *fractional_seconds = &d2;
1975 
1976  if (unlikely(!sscanf (str, scanf_str, &hours, &minutes, &seconds))) {
1978  }
1979 
1980  total_seconds = (hours * 60 * 60) + (minutes * 60) + seconds;
1981 
1982  if (format.decimal_places != 0) {
1983  offset = format.with_colons ? 9 : 7;
1984  end_of_decimal = offset + format.decimal_places;
1985  for (; offset != end_of_decimal; ++offset) {
1986  unscaled_fraction = unscaled_fraction * 10 + cob_ctoi (str[offset]);
1987  }
1988 
1989  mpz_set_ui (fractional_seconds->value, unscaled_fraction);
1990  fractional_seconds->scale = format.decimal_places;
1991 
1992  mpz_set_ui (seconds_decimal->value, total_seconds);
1993  cob_decimal_add (seconds_decimal, fractional_seconds);
1994  } else {
1995  mpz_set_ui (seconds_decimal->value, total_seconds);
1996  seconds_decimal->scale = 0;
1997  }
1998 }
1999 
2000 static int
2001 valid_day_and_format (const int day, const char *format)
2002 {
2003  return valid_integer_date (day) && cob_valid_date_format (format);
2004 }
2005 
2006 static int
2007 num_leading_nonspace (const char *str)
2008 {
2009  size_t i;
2010  size_t str_len = strlen (str);
2011 
2012  for (i = 0; i < str_len && !isspace ((int) str[i]); ++i);
2013  return i;
2014 }
2015 
2016 static void
2017 format_as_yyyymmdd (const int day_num, const int with_hyphen, char *buff)
2018 {
2019  int day_of_month;
2020  int month;
2021  int year;
2022  const char *format_str;
2023 
2024  date_of_integer (day_num, &year, &month, &day_of_month);
2025 
2026  format_str = with_hyphen ? "%4.4d-%2.2d-%2.2d" : "%4.4d%2.2d%2.2d";
2027  sprintf (buff, format_str, year, month, day_of_month);
2028 }
2029 
2030 static void
2031 format_as_yyyyddd (const int day_num, const int with_hyphen, char *buff)
2032 {
2033  int day_of_year;
2034  int year;
2035  const char *format_str;
2036 
2037  day_of_integer (day_num, &year, &day_of_year);
2038 
2039  format_str = with_hyphen ? "%4.4d-%3.3d" : "%4.4d%3.3d";
2040  sprintf (buff, format_str, year, day_of_year);
2041 }
2042 
2043 /* 0 = Monday, ..., 6 = Sunday */
2044 static int
2045 get_day_of_week (const int day_num)
2046 {
2047  return (day_num - 1) % 7;
2048 }
2049 
2050 static int
2051 get_iso_week_one (const int day_num, const int day_of_year)
2052 {
2053  int jan_4 = day_num - day_of_year + 4;
2054  int day_of_week = get_day_of_week (jan_4);
2055  int first_monday = jan_4 - day_of_week;
2056  return first_monday;
2057 }
2058 
2059 /*
2060  * Derived from "Calculating the ISO week number for a date" by Julian M.
2061  * Bucknall (http://www.boyet.com/articles/publishedarticles/calculatingtheisoweeknumb.html).
2062  */
2063 static void
2064 get_iso_week (const int day_num, int *year, int *week)
2065 {
2066  int day_of_year;
2067  int days_to_dec_29;
2068  int dec_29;
2069  int week_one;
2070 
2071  day_of_integer (day_num, year, &day_of_year);
2072 
2073  days_to_dec_29 = days_in_year (*year) - 2;
2074  dec_29 = day_num - day_of_year + days_to_dec_29;
2075 
2076  if (day_num >= dec_29) {
2077  /* If the day is (after) December 29, it may be in the first
2078  week of the following year
2079  */
2080  week_one = get_iso_week_one (day_num + days_in_year (*year), day_of_year);
2081  if (day_num < week_one) {
2082  week_one = get_iso_week_one (day_num, day_of_year);
2083  } else {
2084  ++*year;
2085  }
2086  } else {
2087  week_one = get_iso_week_one (day_num, day_of_year);
2088 
2089  /* If the day is before December 29, it may be in the last week
2090  of the previous year
2091  */
2092  if (day_num < week_one) {
2093  --*year;
2094  week_one = get_iso_week_one (day_num - day_of_year,
2095  days_in_year (*year));
2096  }
2097  }
2098 
2099  *week = (day_num - week_one) / 7 + 1;
2100 }
2101 
2102 static void
2103 format_as_yyyywwwd (const int day_num, const int with_hyphen, char *buff)
2104 {
2105  int ignored_day_of_year;
2106  int week;
2107  int year;
2108  int day_of_week;
2109  const char *format_str;
2110 
2111  day_of_integer (day_num, &year, &ignored_day_of_year);
2112  get_iso_week (day_num, &year, &week);
2113  day_of_week = get_day_of_week (day_num);
2114 
2115  format_str = with_hyphen ? "%4.4d-W%2.2d-%1.1d" : "%4.4dW%2.2d%1.1d";
2116  sprintf (buff, format_str, year, week, day_of_week + 1);
2117 }
2118 
2123 };
2124 
2125 struct date_format {
2128 };
2129 
2130 static struct date_format
2131 parse_date_format_string (const char *format_str)
2132 {
2133  struct date_format format;
2134 
2135  if (!strcmp (format_str, "YYYYMMDD") || !strcmp (format_str, "YYYY-MM-DD")) {
2136  format.days = DAYS_MMDD;
2137  } else if (!strcmp (format_str, "YYYYDDD") || !strcmp (format_str, "YYYY-DDD")) {
2138  format.days = DAYS_DDD;
2139  } else { /* YYYYWwwD or YYYY-Www-D */
2140  format.days = DAYS_WWWD;
2141  }
2142 
2143  format.with_hyphens = format_str[4] == '-';
2144 
2145  return format;
2146 }
2147 
2148 static void
2149 format_date (const struct date_format format, const int days, char *buff)
2150 {
2151  void (*formatting_func) (int, int, char *);
2152 
2153  if (format.days == DAYS_MMDD) {
2154  formatting_func = &format_as_yyyymmdd;
2155  } else if (format.days == DAYS_DDD) {
2156  formatting_func = &format_as_yyyyddd;
2157  } else { /* DAYS_WWWD */
2158  formatting_func = &format_as_yyyywwwd;
2159  }
2160  (*formatting_func) (days, format.with_hyphens, buff);
2161 }
2162 
2163 /* Uses d5. */
2164 static void
2166 {
2167  int seconds;
2168  cob_decimal *whole_seconds;
2169 
2170 
2171  seconds = cob_get_int (time);
2172  whole_seconds = &d5;
2173  mpz_set_ui (whole_seconds->value, (unsigned long) seconds);
2174  whole_seconds->scale = 0;
2175 
2176  cob_decimal_set_field (fraction, time);
2177  cob_decimal_sub (fraction, whole_seconds);
2178 }
2179 
2180 static int
2181 decimal_places_for_seconds (const char *str, const ptrdiff_t point_pos)
2182 {
2183  ptrdiff_t offset = point_pos;
2184  int decimal_places = 0;
2185 
2186  while (str[++offset] == 's') {
2187  ++decimal_places;
2188  }
2189 
2190  return decimal_places;
2191 }
2192 
2193 static int
2194 rest_is_z (const char *str)
2195 {
2196  return !strcmp (str, "Z");
2197 }
2198 
2199 static int
2200 rest_is_offset_format (const char *str, const int with_colon)
2201 {
2202  if (with_colon) {
2203  return !strcmp (str, "+hh:mm");
2204  } else {
2205  return !strcmp (str, "+hhmm");
2206  }
2207 }
2208 
2209 /*
2210  This function is needed because, on MinGW, (int) pow (10, 8) == 9999999, not
2211  10^8. This also occurs with other powers. See http://stackoverflow.com/q/9704195.
2212 */
2213 static unsigned int
2214 int_pow (const unsigned int base, unsigned int power)
2215 {
2216  unsigned int ret = 1;
2217 
2218  while (power > 0) {
2219  ret *= base;
2220  --power;
2221  }
2222 
2223  return ret;
2224 }
2225 
2226 static void
2227 add_decimal_digits (int decimal_places, cob_decimal *second_fraction,
2228  char *buff, ptrdiff_t *buff_pos)
2229 {
2230  unsigned int scale = second_fraction->scale;
2231  unsigned int power_of_ten;
2232  unsigned int fraction = mpz_get_ui (second_fraction->value);
2233 
2234  /* Add decimal point */
2235  buff[*buff_pos] = COB_MODULE_PTR->decimal_point;
2236  ++*buff_pos;
2237 
2238  /* Append decimal digits from second_fraction from left to right */
2239  while (scale != 0 && decimal_places != 0) {
2240  --scale;
2241  power_of_ten = int_pow (10, scale);
2242  buff[*buff_pos] = '0' + (fraction / power_of_ten);
2243 
2244  fraction %= power_of_ten;
2245  ++*buff_pos;
2246  --decimal_places;
2247  }
2248 
2249  /* Set remaining digits to zero */
2250  if (decimal_places != 0) {
2251  memset (buff + *buff_pos, '0', decimal_places);
2252  *buff_pos += decimal_places;
2253  }
2254 }
2255 
2256 static void
2257 add_z (const ptrdiff_t buff_pos, char *buff)
2258 {
2259  buff[buff_pos] = 'Z';
2260 }
2261 
2262 static void
2263 add_offset_time (const int with_colon, int const *offset_time,
2264  const ptrdiff_t buff_pos, char *buff)
2265 {
2266  int hours;
2267  int minutes;
2268  const char *format_str;
2269 
2270  if (offset_time) {
2271  hours = *offset_time / 60;
2272  minutes = abs (*offset_time) % 60;
2273 
2274  format_str = with_colon ? "%+2.2d:%2.2d" : "%+2.2d%2.2d";
2275  sprintf (buff + buff_pos, format_str, hours, minutes);
2276  } else {
2277  sprintf (buff + buff_pos, "00000");
2278  }
2279 }
2280 
2281 static struct time_format
2282 parse_time_format_string (const char *str)
2283 {
2284  struct time_format format;
2285  ptrdiff_t offset;
2286 
2287  if (!strncmp (str, "hhmmss", 6)) {
2288  format.with_colons = 0;
2289  offset = 6;
2290  } else { /* "hh:mm:ss" */
2291  format.with_colons = 1;
2292  offset = 8;
2293  }
2294 
2295  if (str[offset] == '.' || str[offset] == ',') {
2296  format.decimal_places = decimal_places_for_seconds (str, offset);
2297  offset += format.decimal_places + 1;
2298  } else {
2299  format.decimal_places = 0;
2300  }
2301 
2302  if (strlen (str) > (size_t) offset) {
2303  if (rest_is_z (str + offset)) {
2304  format.extra = EXTRA_Z;
2305  } else { /* the rest is the offset time */
2306  format.extra = EXTRA_OFFSET_TIME;
2307  }
2308  } else {
2309  format.extra = EXTRA_NONE;
2310  }
2311 
2312  return format;
2313 }
2314 
2315 static int
2316 format_time (const struct time_format format, int time,
2317  cob_decimal *second_fraction, int *offset_time, char *buff)
2318 {
2319  int hours;
2320  int minutes;
2321  int seconds;
2322  int date_overflow = 0;
2323  ptrdiff_t buff_pos;
2324  const char *format_str;
2325 
2326  if (format.with_colons) {
2327  format_str = "%2.2d:%2.2d:%2.2d";
2328  buff_pos = 8;
2329  } else {
2330  format_str = "%2.2d%2.2d%2.2d";
2331  buff_pos = 6;
2332  }
2333 
2334  /* Duplication! */
2335  hours = time / 3600;
2336  time %= 3600;
2337  minutes = time / 60;
2338  seconds = time % 60;
2339 
2340  if (format.extra == EXTRA_Z) {
2341  if (offset_time == NULL) {
2343  return 0;
2344  }
2345 
2346  hours -= *offset_time / 60;
2347  minutes -= *offset_time % 60;
2348 
2349  /* Handle minute and hour overflow */
2350  if (minutes >= 60) {
2351  minutes -= 60;
2352  ++hours;
2353  } else if (minutes < 0) {
2354  minutes += 60;
2355  --hours;
2356  }
2357 
2358  if (hours >= 24) {
2359  hours -= 24;
2360  date_overflow = 1;
2361  } else if (hours < 0) {
2362  hours += 24;
2363  date_overflow = -1;
2364  }
2365  }
2366 
2367  sprintf (buff, format_str, hours, minutes, seconds);
2368 
2369  if (format.decimal_places != 0) {
2370  add_decimal_digits (format.decimal_places, second_fraction,
2371  buff, &buff_pos);
2372  }
2373 
2374  if (format.extra == EXTRA_Z) {
2375  add_z (buff_pos, buff);
2376  } else if (format.extra == EXTRA_OFFSET_TIME) {
2377  add_offset_time (format.with_colons, offset_time, buff_pos, buff);
2378  }
2379 
2380  return date_overflow;
2381 }
2382 
2383 static void
2384 split_around_t (const char *str, char *first, char *second)
2385 {
2386  int i;
2387  size_t first_length;
2388  size_t second_length;
2389 
2390  /* Find 'T' */
2391  for (i = 0; str[i] != '\0' && str[i] != 'T'; ++i);
2392 
2393  /* Copy everything before 'T' into first (if present) */
2394  first_length = i;
2395  if (first_length > COB_DATESTR_MAX) {
2396  first_length = COB_DATESTR_MAX;
2397  }
2398  if (first != NULL) {
2399  strncpy (first, str, first_length);
2400  first[first_length] = '\0';
2401  }
2402 
2403  /* If there is anything after 'T', copy it into second (if present) */
2404  if (second != NULL) {
2405  if (strlen (str) - i == 0) {
2406  second[0] = '\0';
2407  } else {
2408  second_length = strlen (str) - i - 1U;
2409  if (second_length > COB_TIMESTR_MAX) {
2410  second_length = COB_TIMESTR_MAX;;
2411  }
2412  strncpy (second, str + i + 1U, second_length);
2413  second[second_length] = '\0';
2414  }
2415  }
2416 }
2417 
2418 static int
2420  cob_field *offset_time_field, int *offset_time)
2421 {
2422  if (offset_time_field != NULL) {
2423  *offset_time = cob_get_int (offset_time_field);
2424  if (valid_offset_time (*offset_time)) {
2425  return 0;
2426  }
2427  } else {
2428  *offset_time = 0;
2429  return 0;
2430  }
2431 
2432  return 1;
2433 }
2434 
2435 static int *
2436 get_system_offset_time_ptr (int * const offset_time)
2437 {
2438  struct cob_time current_time;
2439 
2440  current_time = cob_get_current_date_and_time ();
2441  if (current_time.offset_known) {
2442  *offset_time = current_time.utc_offset;
2443  return offset_time;
2444  } else {
2445  return NULL;
2446  }
2447 }
2448 
2449 static int
2450 test_char_cond (const int cond, int *offset)
2451 {
2452  if (cond) {
2453  ++(*offset);
2454  return 0;
2455  } else {
2456  return *offset + 1;
2457  }
2458 }
2459 
2460 static int
2461 test_char (const char wanted, const char *str, int *offset)
2462 {
2463  return test_char_cond (wanted == str[*offset], offset);
2464 }
2465 
2466 static COB_INLINE COB_A_INLINE int
2467 test_digit (const unsigned char ch, int *offset)
2468 {
2469  return test_char_cond (isdigit (ch), offset);
2470 }
2471 
2472 static COB_INLINE COB_A_INLINE int
2473 test_char_in_range (const char min, const char max, const char ch, int *offset)
2474 {
2475  return test_char_cond (min <= ch && ch <= max, offset);
2476 }
2477 
2478 static int test_millenium (const char *date, int *offset, int *millenium)
2479 {
2480  RETURN_IF_NOT_ZERO (test_char_in_range ('1', '9', date[*offset], offset));
2481 
2482  *millenium = cob_ctoi (date[*offset - 1]);
2483  return 0;
2484 }
2485 
2486 static int
2487 test_century (const char *date, int *offset, int *state)
2488 {
2489  if (*state != 1) {
2490  RETURN_IF_NOT_ZERO (test_digit (date[*offset], offset));
2491  } else {
2492  RETURN_IF_NOT_ZERO (test_char_in_range ('6', '9', date[*offset],
2493  offset));
2494  }
2495 
2496  *state = *state * 10 + cob_ctoi (date[*offset - 1]);
2497  return 0;
2498 }
2499 
2500 static int
2501 test_decade (const char *date, int *offset, int *state)
2502 {
2503  RETURN_IF_NOT_ZERO (test_digit (date[*offset], offset));
2504  *state = *state * 10 + cob_ctoi (date[*offset - 1]);
2505  return 0;
2506 }
2507 
2508 static int
2509 test_unit_year (const char *date, int *offset, int *state)
2510 {
2511  if (*state != 160) {
2512  RETURN_IF_NOT_ZERO (test_digit (date[*offset], offset));
2513  } else {
2514  RETURN_IF_NOT_ZERO (test_char_in_range ('1', '9', date[*offset],
2515  offset));
2516  }
2517 
2518  *state = *state * 10 + cob_ctoi (date[*offset - 1]);
2519  return 0;
2520 }
2521 
2522 static int
2523 test_year (const char *date, int *offset, int *state)
2524 {
2525  RETURN_IF_NOT_ZERO (test_millenium (date, offset, state));
2526  RETURN_IF_NOT_ZERO (test_century (date, offset, state));
2527  RETURN_IF_NOT_ZERO (test_decade (date, offset, state));
2528  RETURN_IF_NOT_ZERO (test_unit_year (date, offset, state));
2529 
2530  return 0;
2531 }
2532 
2533 static int
2534 test_hyphen_presence (const int with_hyphens, const char *date, int *offset)
2535 {
2536  return with_hyphens ? test_char ('-', date, offset) : 0;
2537 }
2538 
2539 static int
2540 test_month (const char *date, int *offset, int *month)
2541 {
2542  int first_digit;
2543 
2544  /* Validate first digit */
2545  RETURN_IF_NOT_ZERO (test_char_cond (date[*offset] == '0' || date[*offset] == '1',
2546  offset));
2547  first_digit = cob_ctoi (date[*offset - 1]);
2548 
2549  /* Validate second digit */
2550  if (first_digit == 0) {
2551  RETURN_IF_NOT_ZERO (test_char_in_range ('1', '9', date[*offset],
2552  offset));
2553  } else { /* first digit == 1 */
2554  RETURN_IF_NOT_ZERO (test_char_in_range ('0', '2', date[*offset],
2555  offset));
2556  }
2557 
2558  *month = first_digit * 10 + cob_ctoi (date[*offset - 1]);
2559  return 0;
2560 }
2561 
2562 static int
2563 test_day_of_month (const char *date, const int year, const int month,
2564  int *offset)
2565 {
2566  int days_in_month;
2567  char max_first_digit;
2568  char max_second_digit;
2569  int first_digit;
2570 
2571  if (leap_year (year)) {
2572  days_in_month = leap_month_days[month];
2573  } else {
2574  days_in_month = normal_month_days[month];
2575  }
2576  max_first_digit = '0' + (char) (days_in_month / 10);
2577  max_second_digit = '0' + (char) (days_in_month % 10);
2578 
2579  /* Validate first digit */
2580  RETURN_IF_NOT_ZERO (test_char_in_range ('0', max_first_digit,
2581  date[*offset], offset));
2582  first_digit = date[*offset - 1];
2583 
2584  /* Validate second digit */
2585  if (first_digit == '0') {
2586  RETURN_IF_NOT_ZERO (test_char_in_range ('1', '9', date[*offset],
2587  offset));
2588  } else if (first_digit != max_first_digit) {
2589  RETURN_IF_NOT_ZERO (test_digit (date[*offset], offset));
2590  } else {
2591  RETURN_IF_NOT_ZERO (test_char_in_range ('0', max_second_digit,
2592  date[*offset], offset));
2593  }
2594 
2595  return 0;
2596 }
2597 
2598 static int
2599 test_day_of_year (const char *date, const int year, int *offset)
2600 {
2601  char max_last_digit;
2602  int state;
2603 
2604  /* Validate first digit */
2605  /* Check day is not greater than 399 */
2606  RETURN_IF_NOT_ZERO (test_char_in_range ('0', '3', date[*offset], offset));
2607  state = cob_ctoi (date[*offset - 1]);
2608 
2609  /* Validate second digit */
2610  if (state != 3) {
2611  RETURN_IF_NOT_ZERO (test_digit (date[*offset], offset));
2612  } else {
2613  /* Check day is not greater than 369 */
2614  RETURN_IF_NOT_ZERO (test_char_in_range ('0', '6', date[*offset],
2615  offset));
2616  }
2617  state = state * 10 + cob_ctoi (date[*offset - 1]);
2618 
2619  /* Validate third digit */
2620  if (state == 0) {
2621  RETURN_IF_NOT_ZERO (test_char_in_range ('1', '9', date[*offset],
2622  offset));
2623  } else if (state != 36) {
2624  RETURN_IF_NOT_ZERO (test_digit (date[*offset], offset));
2625  } else {
2626  /* Check day is not greater than 366/365 */
2627  max_last_digit = leap_year (year) ? '6' : '5';
2628  RETURN_IF_NOT_ZERO (test_char_in_range ('0', max_last_digit,
2629  date[*offset], offset));
2630  }
2631 
2632  return 0;
2633 }
2634 
2635 static int
2636 test_w_presence (const char *date, int *offset)
2637 {
2638  return test_char ('W', date, offset);
2639 }
2640 
2641 static int
2642 test_week (const char *date, const int year, int *offset)
2643 {
2644  int first_digit;
2645  char max_last_digit;
2646 
2647  /* Validate first digit */
2648  RETURN_IF_NOT_ZERO (test_char_in_range ('0', '5', date[*offset], offset));
2649  first_digit = cob_ctoi (date[*offset - 1]);
2650 
2651  /* Validate second digit */
2652  if (first_digit == 0) {
2653  RETURN_IF_NOT_ZERO (test_char_in_range ('1', '9', date[*offset],
2654  offset));
2655  } else if (first_digit != 5) {
2656  RETURN_IF_NOT_ZERO (test_digit (date[*offset], offset));
2657  } else {
2658  max_last_digit = max_week (year) == 53 ? '3' : '2';
2659  RETURN_IF_NOT_ZERO (test_char_in_range ('0', max_last_digit,
2660  date[*offset], offset));
2661  }
2662 
2663  return 0;
2664 }
2665 
2666 static int
2667 test_day_of_week (const char *date, int *offset)
2668 {
2669  RETURN_IF_NOT_ZERO (test_char_in_range ('1', '7', date[*offset], offset));
2670  return 0;
2671 }
2672 
2673 static int
2674 test_date_end (const struct date_format format, const char *date, const int year, int *offset)
2675 {
2676  int month;
2677 
2678  if (format.days == DAYS_MMDD) {
2679  RETURN_IF_NOT_ZERO (test_month (date, offset, &month));
2680  RETURN_IF_NOT_ZERO (test_hyphen_presence (format.with_hyphens, date, offset));
2681  RETURN_IF_NOT_ZERO (test_day_of_month (date, year, month, offset));
2682  } else if (format.days == DAYS_DDD) {
2683  RETURN_IF_NOT_ZERO (test_day_of_year (date, year, offset));
2684  } else { /* DAYS_WWWD */
2685  RETURN_IF_NOT_ZERO (test_w_presence (date, offset));
2686  RETURN_IF_NOT_ZERO (test_week (date, year, offset));
2687  RETURN_IF_NOT_ZERO (test_hyphen_presence (format.with_hyphens, date, offset));
2688  RETURN_IF_NOT_ZERO (test_day_of_week (date, offset));
2689  }
2690 
2691  return 0;
2692 }
2693 
2694 static int
2695 test_no_trailing_junk (const char *str, int offset, int end_of_string)
2696 {
2697  if (end_of_string) {
2698  /* Allow trailing spaces at the end of strings */
2699  while (str[offset] != '\0') {
2700  if (str[offset] != ' ') {
2701  return offset + 1;
2702  }
2703  ++offset;
2704  }
2705  return 0;
2706  } else {
2707  return str[offset] == '\0' ? 0 : offset + 1;
2708  }
2709 
2710 }
2711 
2712 static int
2713 test_formatted_date (const struct date_format format, const char *date,
2714  const int end_of_string)
2715 {
2716  int offset = 0;
2717  int year;
2718 
2719  RETURN_IF_NOT_ZERO (test_year (date, &offset, &year));
2720  RETURN_IF_NOT_ZERO (test_hyphen_presence (format.with_hyphens, date, &offset));
2721  RETURN_IF_NOT_ZERO (test_date_end (format, date, year, &offset));
2722  RETURN_IF_NOT_ZERO (test_no_trailing_junk (date, offset, end_of_string));
2723  return 0;
2724 }
2725 
2726 static int
2727 test_less_than_60 (const char *time, int *offset)
2728 {
2729  RETURN_IF_NOT_ZERO (test_char_in_range ('0', '5', time[*offset], offset));
2730  RETURN_IF_NOT_ZERO (test_digit (time[*offset], offset));
2731  return 0;
2732 }
2733 
2734 static int
2735 test_hour (const char *time, int *offset)
2736 {
2737  int first_digit;
2738 
2739  RETURN_IF_NOT_ZERO (test_char_in_range ('0', '2', time[*offset], offset));
2740  first_digit = cob_ctoi (time[*offset - 1]);
2741 
2742  if (first_digit != 2) {
2743  RETURN_IF_NOT_ZERO (test_digit (time[*offset], offset));
2744  } else {
2745  RETURN_IF_NOT_ZERO (test_char_in_range ('0', '3', time[*offset], offset));
2746  }
2747 
2748  return 0;
2749 }
2750 
2751 static int
2752 test_minute (const char *time, int *offset)
2753 {
2754  RETURN_IF_NOT_ZERO (test_less_than_60 (time, offset));
2755  return 0;
2756 }
2757 
2758 static int
2759 test_second (const char *time, int *offset)
2760 {
2761  RETURN_IF_NOT_ZERO (test_less_than_60 (time, offset));
2762  return 0;
2763 }
2764 
2765 static int
2766 test_colon_presence (const int with_colons, const char *time,
2767  int *offset)
2768 {
2769  if (with_colons) {
2770  RETURN_IF_NOT_ZERO (test_char (':', time, offset));
2771  }
2772 
2773  return 0;
2774 }
2775 
2776 static int
2777 test_decimal_places (const int num_decimal_places, const char decimal_point,
2778  const char *time, int *offset)
2779 {
2780  int i;
2781 
2782  if (num_decimal_places != 0) {
2783  RETURN_IF_NOT_ZERO (test_char (decimal_point, time, offset));
2784  for (i = 0; i < num_decimal_places; ++i) {
2785  RETURN_IF_NOT_ZERO (test_digit (time[*offset], offset));
2786  }
2787  }
2788 
2789  return 0;
2790 }
2791 
2792 static int
2793 test_z_presence (const char *time, int *offset)
2794 {
2795  return test_char ('Z', time, offset);
2796 }
2797 
2798 static int
2799 test_two_zeroes (const char *str, int *offset)
2800 {
2801  RETURN_IF_NOT_ZERO (test_char ('0', str, offset));
2802  RETURN_IF_NOT_ZERO (test_char ('0', str, offset));
2803  return 0;
2804 }
2805 
2806 static int
2807 test_offset_time (const struct time_format format, const char *time, int *offset)
2808 {
2809  if (time[*offset] == '+' || time[*offset] == '-') {
2810  ++*offset;
2811  RETURN_IF_NOT_ZERO (test_hour (time, offset));
2813  time, offset));
2814  RETURN_IF_NOT_ZERO (test_minute (time, offset));
2815  } else if (time[*offset] == '0') {
2816  ++*offset;
2817  RETURN_IF_NOT_ZERO (test_two_zeroes (time, offset));
2819  time, offset));
2820  RETURN_IF_NOT_ZERO (test_two_zeroes (time, offset));
2821  } else {
2822  return *offset + 1;
2823  }
2824 
2825  return 0;
2826 }
2827 
2828 static int
2829 test_time_end (const struct time_format format, const char *time,
2830  int *offset)
2831 {
2832  if (format.extra == EXTRA_Z) {
2833  RETURN_IF_NOT_ZERO (test_z_presence (time, offset));
2834  } else if (format.extra == EXTRA_OFFSET_TIME) {
2835  RETURN_IF_NOT_ZERO (test_offset_time (format, time, offset));
2836  }
2837 
2838  return 0;
2839 }
2840 
2841 static int
2842 test_formatted_time (const struct time_format format, const char *time,
2843  const char decimal_point)
2844 {
2845  int offset = 0;
2846 
2847  RETURN_IF_NOT_ZERO (test_hour (time, &offset));
2848  RETURN_IF_NOT_ZERO (test_colon_presence (format.with_colons, time, &offset));
2849  RETURN_IF_NOT_ZERO (test_minute (time, &offset));
2850  RETURN_IF_NOT_ZERO (test_colon_presence (format.with_colons, time, &offset));
2851  RETURN_IF_NOT_ZERO (test_second (time, &offset));
2853  decimal_point, time, &offset));
2854  RETURN_IF_NOT_ZERO (test_time_end (format, time, &offset));
2855  RETURN_IF_NOT_ZERO (test_no_trailing_junk (time, offset, 1));
2856 
2857  return 0;
2858 }
2859 
2860 #undef RETURN_IF_NOT_ZERO
2861 
2862 static cob_u32_t
2863 integer_of_mmdd (const struct date_format format, const int year,
2864  const char *final_part)
2865 {
2866  const char *scanf_str = format.with_hyphens ? "%2d-%2d" : "%2d%2d";
2867  int month;
2868  int day;
2869 
2870  if (unlikely(!sscanf (final_part, scanf_str, &month, &day))) {
2872  }
2873  return integer_of_date (year, month, day);
2874 
2875 }
2876 
2877 static cob_u32_t
2878 integer_of_ddd (const int year, const char *final_part)
2879 {
2880  int day;
2881 
2882  if (unlikely(!sscanf (final_part, "%3d", &day))) {
2884  }
2885  return integer_of_day (year, day);
2886 }
2887 
2888 static cob_u32_t
2889 integer_of_wwwd (const struct date_format format, const int year,
2890  const char *final_part)
2891 {
2892  int first_week_monday;
2893  const char *scanf_str = format.with_hyphens ? "W%2d-%1d" : "W%2d%1d";
2894  int week;
2895  int day_of_week;
2896  cob_u32_t total_days = 0;
2897 
2898  first_week_monday = get_iso_week_one (days_up_to_year (year) + 1, 1);
2899  if (unlikely(!sscanf (final_part, scanf_str, &week, &day_of_week))) {
2901  }
2902  total_days = first_week_monday + ((week - 1) * 7) + day_of_week - 1;
2903 
2904  return total_days;
2905 }
2906 
2907 static cob_u32_t
2909  const char *formatted_date)
2910 {
2911  int year;
2912  int final_part_start = 4 + format.with_hyphens;
2913 
2914  if (unlikely(!sscanf (formatted_date, "%4d", &year))) {
2916  }
2917 
2918  if (format.days == DAYS_MMDD) {
2919  return integer_of_mmdd (format, year, formatted_date + final_part_start);
2920  } else if (format.days == DAYS_DDD) {
2921  return integer_of_ddd (year, formatted_date + final_part_start);
2922  } else { /* DAYS_WWWD */
2923  return integer_of_wwwd (format, year, formatted_date + final_part_start);
2924  }
2925 
2926 }
2927 
2928 static void
2929 format_datetime (const struct date_format date_fmt,
2930  const struct time_format time_fmt,
2931  const int days,
2932  const int whole_seconds,
2933  cob_decimal *fractional_seconds,
2934  int *offset_time,
2935  char *buff)
2936 {
2937  int overflow;
2938  char formatted_time[COB_TIMESTR_LEN] = { '\0' };
2939  char formatted_date[COB_DATESTR_LEN] = { '\0' };
2940 
2941  overflow = format_time (time_fmt, whole_seconds, fractional_seconds,
2942  offset_time, formatted_time);
2943  format_date (date_fmt, days + overflow, formatted_date);
2944 
2945  sprintf (buff, "%sT%s", formatted_date, formatted_time);
2946 }
2947 
2948 /* Uses d1 */
2949 static void
2950 format_current_date (const struct date_format date_fmt,
2951  const struct time_format time_fmt,
2952  char *formatted_datetime)
2953 {
2954  struct cob_time time = cob_get_current_date_and_time ();
2955  int days
2956  = integer_of_date (time.year, time.month, time.day_of_month);
2957  int seconds_from_midnight
2958  = time.hour * 60 * 60 + time.minute * 60 + time.second;
2959  cob_decimal *fractional_second = &d1;
2960  int *offset_time;
2961 
2962  mpz_set_ui (fractional_second->value, (unsigned long) time.nanosecond);
2963  fractional_second->scale = 9;
2964 
2965  if (time.offset_known) {
2966  offset_time = &time.utc_offset;
2967  } else {
2968  offset_time = NULL;
2969  }
2970 
2971  format_datetime (date_fmt, time_fmt, days, seconds_from_midnight,
2972  fractional_second, offset_time, formatted_datetime);
2973 }
2974 
2975 /* Global functions */
2976 
2977 /* Return switch value as field */
2978 
2979 cob_field *
2980 cob_switch_value (const int id)
2981 {
2983  return curr_field;
2984 }
2985 
2986 /* Decimal exponentiation function */
2987 /* x ^ z = e ^ (z * log(x)) */
2988 
2989 void
2991 {
2992  cob_uli_t n;
2993  int sign;
2994 
2995  if (unlikely(pd1->scale == COB_DECIMAL_NAN)) {
2996  return;
2997  }
2998  if (unlikely(pd2->scale == COB_DECIMAL_NAN)) {
2999  pd1->scale = COB_DECIMAL_NAN;
3000  return;
3001  }
3002 
3003  sign = mpz_sgn (pd1->value);
3004 
3005  if (!mpz_sgn (pd2->value)) {
3006  /* Exponent is zero */
3007  if (!sign) {
3008  /* 0 ^ 0 */
3010  }
3011  mpz_set_ui (pd1->value, 1UL);
3012  pd1->scale = 0;
3013  return;
3014  }
3015  if (!sign) {
3016  /* Value is zero */
3017  pd1->scale = 0;
3018  return;
3019  }
3020 
3021  cob_trim_decimal (pd2);
3022 
3023  if (sign < 0 && pd2->scale) {
3024  /* Negative exponent and non-integer power */
3025  pd1->scale = COB_DECIMAL_NAN;
3027  return;
3028  }
3029 
3030  cob_trim_decimal (pd1);
3031 
3032  if (!pd2->scale) {
3033  /* Integer power */
3034  if (!mpz_cmp_ui (pd2->value, 1UL)) {
3035  /* Power is 1 */
3036  return;
3037  }
3038  if (mpz_sgn (pd2->value) < 0 && mpz_fits_slong_p (pd2->value)) {
3039  /* Negative power */
3040  mpz_abs (pd2->value, pd2->value);
3041  n = mpz_get_ui (pd2->value);
3042  mpz_pow_ui (pd1->value, pd1->value, n);
3043  if (pd1->scale) {
3044  pd1->scale *= n;
3045  cob_trim_decimal (pd1);
3046  }
3047  cob_decimal_set (pd2, pd1);
3048  mpz_set_ui (pd1->value, 1UL),
3049  pd1->scale = 0;
3050  cob_decimal_div (pd1, pd2);
3051  cob_trim_decimal (pd1);
3052  return;
3053  }
3054  if (mpz_fits_ulong_p (pd2->value)) {
3055  /* Positive power */
3056  n = mpz_get_ui (pd2->value);
3057  mpz_pow_ui (pd1->value, pd1->value, n);
3058  if (pd1->scale) {
3059  pd1->scale *= n;
3060  cob_trim_decimal (pd1);
3061  }
3062  return;
3063  }
3064  }
3065 
3066  if (sign < 0) {
3067  mpz_abs (pd1->value, pd1->value);
3068  }
3070  if (pd2->scale == 1 && !mpz_cmp_ui (pd2->value, 5UL)) {
3071  /* Square root short cut */
3072  mpf_sqrt (cob_mpft2, cob_mpft);
3073  } else {
3076  mpf_mul (cob_mpft, cob_mpft, cob_mpft2);
3078  }
3080  if (sign < 0) {
3081  mpz_neg (pd1->value, pd1->value);
3082  }
3083 }
3084 
3085 /* Indirect field get/put functions */
3086 
3087 void
3089 {
3090  make_field_entry (f);
3091  memcpy (curr_field->data, f->data, f->size);
3092  move_field = curr_field;
3093 }
3094 
3095 void
3097 {
3098  cob_move (move_field, f);
3099 }
3100 
3101 /* Indirect move */
3102 
3103 void
3105 {
3106  short size, scale;
3107  cob_field_attr attr;
3108  cob_field field;
3109 
3110  cob_decimal_set_field (&d1, src);
3111  cob_trim_decimal (&d1);
3112 
3113  size = (short)mpz_sizeinbase (d1.value, 10);
3114  if (d1.scale > size) {
3115  size = (short)d1.scale;
3116  }
3117  scale = (short)d1.scale;
3119  scale, COB_FLAG_HAVE_SIGN, NULL);
3120  COB_FIELD_INIT (size, NULL, &attr);
3121  make_field_entry (&field);
3122  (void)cob_decimal_get_field (&d1, curr_field, 0);
3123  cob_move (curr_field, dst);
3124 }
3125 
3126 /* TEST-NUMVAL implementation */
3127 
3128 /* Validate NUMVAL / NUMVAL-C item */
3129 /* [spaces][+|-][spaces]{digits[.[digits]]|.digits}[spaces] */
3130 /* [spaces]{digits[.[digits]]|.digits}[spaces][+|-|CR|DB][spaces] */
3131 int
3132 cob_check_numval (const cob_field *srcfield, const cob_field *currency,
3133  const int chkcurr, const int anycase)
3134 {
3135  unsigned char *p;
3136  unsigned char *begp;
3137  unsigned char *endp;
3138  size_t pos;
3139  size_t plus_minus;
3140  size_t digits;
3141  size_t dec_seen;
3142  size_t space_seen;
3143  size_t break_needed;
3144  size_t currcy_size;
3145  int n;
3146  unsigned char dec_pt;
3147  unsigned char cur_symb;
3148 
3149  begp = NULL;
3150  currcy_size = 0;
3151  if (currency) {
3152  endp = NULL;
3153  p = currency->data;
3154  for (pos = 0; pos < currency->size; pos++, p++) {
3155  switch (*p) {
3156  case '0':
3157  case '1':
3158  case '2':
3159  case '3':
3160  case '4':
3161  case '5':
3162  case '6':
3163  case '7':
3164  case '8':
3165  case '9':
3166  case '+':
3167  case '-':
3168  case '.':
3169  case ',':
3170  case '*':
3171  return 1;
3172  case ' ':
3173  break;
3174  default:
3175  if (pos < currency->size - 1) {
3176  if (!memcmp (p, "CR", (size_t)2)) {
3177  return 1;
3178  }
3179  if (!memcmp (p, "DB", (size_t)2)) {
3180  return 1;
3181  }
3182  }
3183  if (!begp) {
3184  begp = p;
3185  }
3186  endp = p;
3187  break;
3188  }
3189  }
3190  if (!begp) {
3191  return 1;
3192  }
3193  currcy_size = endp - begp;
3194  currcy_size++;
3195  if (currcy_size >= srcfield->size) {
3196  begp = NULL;
3197  currcy_size = 0;
3198  }
3199  } else if (chkcurr) {
3200  cur_symb = COB_MODULE_PTR->currency_symbol;
3201  begp = &cur_symb;
3202  currcy_size = 1;
3203  }
3204 
3205  if (!srcfield->size) {
3206  return 1;
3207  }
3208 
3209  p = srcfield->data;
3210  plus_minus = 0;
3211  digits = 0;
3212  dec_seen = 0;
3213  space_seen = 0;
3214  break_needed = 0;
3215  dec_pt = COB_MODULE_PTR->decimal_point;
3216 
3217  /* Check leading positions */
3218  for (n = 0; n < (int)srcfield->size; ++n, ++p) {
3219  switch (*p) {
3220  case '0':
3221  case '1':
3222  case '2':
3223  case '3':
3224  case '4':
3225  case '5':
3226  case '6':
3227  case '7':
3228  case '8':
3229  case '9':
3230  break_needed = 1;
3231  break;
3232  case ' ':
3233  continue;
3234  case '+':
3235  case '-':
3236  if (plus_minus) {
3237  return n + 1;
3238  }
3239  plus_minus = 1;
3240  continue;
3241  case ',':
3242  case '.':
3243  if (*p != dec_pt) {
3244  return n + 1;
3245  }
3246  break_needed = 1;
3247  break;
3248  default:
3249  if (begp && n < (int)(srcfield->size - currcy_size)) {
3250  if (!memcmp (p, begp, currcy_size)) {
3251  break;
3252  }
3253  }
3254  return n + 1;
3255  }
3256  if (break_needed) {
3257  break;
3258  }
3259  }
3260 
3261  if (n == (int)srcfield->size) {
3262  return n + 1;
3263  }
3264 
3265  for (; n < (int)srcfield->size; ++n, ++p) {
3266  switch (*p) {
3267  case '0':
3268  case '1':
3269  case '2':
3270  case '3':
3271  case '4':
3272  case '5':
3273  case '6':
3274  case '7':
3275  case '8':
3276  case '9':
3277  if (++digits > COB_MAX_DIGITS || space_seen) {
3278  return n + 1;
3279  }
3280  continue;
3281  case ',':
3282  case '.':
3283  if (dec_seen || space_seen) {
3284  return n + 1;
3285  }
3286  if (*p == dec_pt) {
3287  dec_seen = 1;
3288  } else if (!chkcurr) {
3289  return n + 1;
3290  }
3291  continue;
3292  case ' ':
3293  space_seen = 1;
3294  continue;
3295  case '+':
3296  case '-':
3297  if (plus_minus) {
3298  return n + 1;
3299  }
3300  plus_minus = 1;
3301  continue;
3302  case 'c':
3303  if (!anycase) {
3304  return n + 1;
3305  }
3306  /* Fall through */
3307  case 'C':
3308  if (plus_minus) {
3309  return n + 1;
3310  }
3311  if (n < (int)srcfield->size - 1) {
3312  if (*(p + 1) == 'R' ||
3313  (anycase && *(p + 1) == 'r')) {
3314  plus_minus = 1;
3315  p++;
3316  n++;
3317  continue;
3318  }
3319  }
3320  return n + 2;
3321  case 'd':
3322  if (!anycase) {
3323  return n + 1;
3324  }
3325  /* Fall through */
3326  case 'D':
3327  if (plus_minus) {
3328  return n + 1;
3329  }
3330  if (n < (int)srcfield->size - 1) {
3331  if (*(p + 1) == 'B' ||
3332  (anycase && *(p + 1) == 'b')) {
3333  plus_minus = 1;
3334  p++;
3335  n++;
3336  continue;
3337  }
3338  }
3339  return n + 2;
3340  default:
3341  return n + 1;
3342  }
3343  }
3344 
3345  if (!digits) {
3346  return n + 1;
3347  }
3348 
3349  return 0;
3350 }
3351 
3352 /* Date/time format validation */
3353 
3354 int
3355 cob_valid_date_format (const char *format)
3356 {
3357  return !strcmp (format, "YYYYMMDD")
3358  || !strcmp (format, "YYYY-MM-DD")
3359  || !strcmp (format, "YYYYDDD")
3360  || !strcmp (format, "YYYY-DDD")
3361  || !strcmp (format, "YYYYWwwD")
3362  || !strcmp (format, "YYYY-Www-D");
3363 }
3364 
3365 int
3366 cob_valid_time_format (const char *format, const char decimal_point)
3367 {
3368  int with_colons;
3369  ptrdiff_t format_offset;
3370  unsigned int decimal_places = 0;
3371 
3372  if (!strncmp (format, "hhmmss", 6)) {
3373  with_colons = 0;
3374  format_offset = 6;
3375  } else if (!strncmp (format, "hh:mm:ss", 8)) {
3376  with_colons = 1;
3377  format_offset = 8;
3378  } else {
3379  return 0;
3380  }
3381 
3382  /* Validate number of decimal places */
3383  if (format[format_offset] == decimal_point) {
3384  decimal_places = decimal_places_for_seconds (format, format_offset);
3385  format_offset += decimal_places + 1;
3386  if (!(1 <= decimal_places && decimal_places <= COB_TIMEDEC_MAX)) {
3387  return 0;
3388  }
3389  }
3390 
3391  /* Check for trailing garbage */
3392  if (strlen (format) > (size_t) format_offset
3393  && !rest_is_z (format + format_offset)
3394  && !rest_is_offset_format (format + format_offset, with_colons)) {
3395  return 0;
3396  }
3397 
3398  return 1;
3399 }
3400 
3401 int
3402 cob_valid_datetime_format (const char *format, const char decimal_point)
3403 {
3404  char date_format_str[COB_DATETIMESTR_LEN] = { '\0' };
3405  char time_format_str[COB_DATETIMESTR_LEN] = { '\0' };
3406  struct date_format date_format;
3407  struct time_format time_format;
3408 
3409  split_around_t (format, date_format_str, time_format_str);
3410 
3411  if (!cob_valid_date_format (date_format_str)
3412  || !cob_valid_time_format (time_format_str, decimal_point)) {
3413  return 0;
3414  }
3415 
3416  /* Check time and date formats match */
3417  date_format = parse_date_format_string (date_format_str);
3418  time_format = parse_time_format_string (time_format_str);
3419  if (date_format.with_hyphens != time_format.with_colons) {
3420  return 0;
3421  }
3422 
3423  return 1;
3424 }
3425 
3426 /* Numeric expressions */
3427 
3428 cob_field *
3430 {
3431  cob_decimal_set_field (&d1, f1);
3432  cob_decimal_set_field (&d2, f2);
3433  switch (op) {
3434  case '+':
3435  cob_decimal_add (&d1, &d2);
3436  break;
3437  case '-':
3438  cob_decimal_sub (&d1, &d2);
3439  break;
3440  case '*':
3441  cob_decimal_mul (&d1, &d2);
3442  break;
3443  case '/':
3444  cob_set_exception (0);
3445  if (!mpz_sgn (d2.value)) {
3446  /* Divide by zero */
3448  mpz_set_ui (d1.value, 0UL);
3449  d1.scale = 0;
3450  } else {
3451  cob_decimal_div (&d1, &d2);
3452  }
3453  break;
3454  case '^':
3455  cob_decimal_pow (&d1, &d2);
3456  break;
3457  default:
3458  break;
3459  }
3460 
3461  cob_alloc_field (&d1);
3462  (void)cob_decimal_get_field (&d1, curr_field, 0);
3463  return curr_field;
3464 }
3465 
3466 /* Intrinsics */
3467 
3468 cob_field *
3470 {
3471  if (COB_FIELD_IS_NATIONAL (srcfield)) {
3473  } else {
3475  }
3476  return curr_field;
3477 }
3478 
3479 cob_field *
3481 {
3483  return curr_field;
3484 }
3485 
3486 cob_field *
3488 {
3489  int sign;
3490 
3491  cob_decimal_set_field (&d1, srcfield);
3492  /* Check scale */
3493  if (d1.scale < 0) {
3494  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)-d1.scale);
3495  mpz_mul (d1.value, d1.value, cob_mexp);
3496  } else if (d1.scale > 0) {
3497  sign = mpz_sgn (d1.value);
3498  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)d1.scale);
3499  mpz_tdiv_qr (d1.value, cob_mpzt, d1.value, cob_mexp);
3500  /* Check negative and has decimal places */
3501  if (sign < 0 && mpz_sgn (cob_mpzt)) {
3502  mpz_sub_ui (d1.value, d1.value, 1UL);
3503  }
3504  }
3505  d1.scale = 0;
3506 
3507  cob_alloc_field (&d1);
3508  (void)cob_decimal_get_field (&d1, curr_field, 0);
3509  return curr_field;
3510 }
3511 
3512 cob_field *
3514 {
3515  cob_decimal_set_field (&d1, srcfield);
3516  /* Check scale */
3517  if (d1.scale < 0) {
3518  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)-d1.scale);
3519  mpz_mul (d1.value, d1.value, cob_mexp);
3520  } else if (d1.scale > 0) {
3521  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)d1.scale);
3522  mpz_tdiv_q (d1.value, d1.value, cob_mexp);
3523  }
3524  d1.scale = 0;
3525 
3526  cob_alloc_field (&d1);
3527  (void)cob_decimal_get_field (&d1, curr_field, 0);
3528  return curr_field;
3529 }
3530 
3531 cob_field *
3533 {
3534  cob_decimal_set_field (&d1, srcfield);
3535  /* Check scale */
3536  if (d1.scale > 0) {
3537  mpz_ui_pow_ui (cob_mexp, 10UL, (cob_uli_t)d1.scale);
3538  mpz_tdiv_r (d1.value, d1.value, cob_mexp);
3539  } else {
3540  /* No decimals */
3541  mpz_set_ui (d1.value, 0UL);
3542  d1.scale = 0;
3543  }
3544 
3545  cob_alloc_field (&d1);
3546  (void)cob_decimal_get_field (&d1, curr_field, 0);
3547  return curr_field;
3548 }
3549 
3550 cob_field *
3552 {
3553  cob_decimal_set_field (&d1, srcfield);
3554  cob_alloc_set_field_int (mpz_sgn (d1.value));
3555  return curr_field;
3556 }
3557 
3558 cob_field *
3559 cob_intr_upper_case (const int offset, const int length, cob_field *srcfield)
3560 {
3561  size_t i, size;
3562 
3563  make_field_entry (srcfield);
3564 
3565  size = srcfield->size;
3566  for (i = 0; i < size; ++i) {
3567  curr_field->data[i] = (cob_u8_t)toupper (srcfield->data[i]);
3568  }
3569  if (unlikely(offset > 0)) {
3570  calc_ref_mod (curr_field, offset, length);
3571  }
3572  return curr_field;
3573 }
3574 
3575 cob_field *
3576 cob_intr_lower_case (const int offset, const int length, cob_field *srcfield)
3577 {
3578  size_t i, size;
3579 
3580  make_field_entry (srcfield);
3581 
3582  size = srcfield->size;
3583  for (i = 0; i < size; ++i) {
3584  curr_field->data[i] = (cob_u8_t)tolower (srcfield->data[i]);
3585  }
3586  if (unlikely(offset > 0)) {
3587  calc_ref_mod (curr_field, offset, length);
3588  }
3589  return curr_field;
3590 }
3591 
3592 cob_field *
3593 cob_intr_reverse (const int offset, const int length, cob_field *srcfield)
3594 {
3595  size_t i, size;
3596 
3597  make_field_entry (srcfield);
3598 
3599  size = srcfield->size;
3600  for (i = 0; i < size; ++i) {
3601  curr_field->data[i] = srcfield->data[size - i - 1];
3602  }
3603  if (unlikely(offset > 0)) {
3604  calc_ref_mod (curr_field, offset, length);
3605  }
3606  return curr_field;
3607 }
3608 
3609 cob_field *
3611 {
3612  cob_field_attr attr;
3613  cob_field field;
3614  char buff[16];
3615 
3617  COB_FIELD_INIT (8, NULL, &attr);
3618  make_field_entry (&field);
3619  snprintf (buff, sizeof(buff), "%8.8u", COB_MODULE_PTR->module_date);
3620  memcpy (curr_field->data, buff, (size_t)8);
3621  return curr_field;
3622 }
3623 
3624 cob_field *
3626 {
3627  cob_field_attr attr;
3628  cob_field field;
3629  char buff[8];
3630 
3632  COB_FIELD_INIT (6, NULL, &attr);
3633  make_field_entry (&field);
3634  snprintf (buff, sizeof(buff), "%6.6u", COB_MODULE_PTR->module_time);
3635  memcpy (curr_field->data, buff, (size_t)6);
3636  return curr_field;
3637 }
3638 
3639 cob_field *
3641 {
3642  size_t calcsize;
3643  cob_field field;
3644 
3645  calcsize = strlen (COB_MODULE_PTR->module_name);
3646  COB_FIELD_INIT (calcsize, NULL, &const_alpha_attr);
3647  make_field_entry (&field);
3648  memcpy (curr_field->data, COB_MODULE_PTR->module_name, calcsize);
3649  return curr_field;
3650 }
3651 
3652 cob_field *
3654 {
3655  size_t calcsize;
3656  cob_field field;
3657 
3658  if (!COB_MODULE_PTR->next) {
3659  COB_FIELD_INIT (1, NULL, &const_alpha_attr);
3660  make_field_entry (&field);
3661  curr_field->size = 0;
3662  curr_field->data[0] = ' ';
3663  return curr_field;
3664  }
3665  calcsize = strlen (COB_MODULE_PTR->next->module_name);
3666  COB_FIELD_INIT (calcsize, NULL, &const_alpha_attr);
3667  make_field_entry (&field);
3668  memcpy (curr_field->data, COB_MODULE_PTR->next->module_name,
3669  calcsize);
3670  return curr_field;
3671 }
3672 
3673 cob_field *
3675 {
3676  size_t calcsize;
3677  cob_field field;
3678 
3679  calcsize = strlen (COB_MODULE_PTR->module_formatted_date);
3680  COB_FIELD_INIT (calcsize, NULL, &const_alpha_attr);
3681  make_field_entry (&field);
3682  memcpy (curr_field->data, COB_MODULE_PTR->module_formatted_date,
3683  calcsize);
3684  return curr_field;
3685 }
3686 
3687 cob_field *
3689 {
3690  size_t calcsize;
3691  cob_field field;
3692 
3693  calcsize = strlen (COB_MODULE_PTR->module_source);
3694  COB_FIELD_INIT (calcsize, NULL, &const_alpha_attr);
3695  make_field_entry (&field);
3696  memcpy (curr_field->data, COB_MODULE_PTR->module_source, calcsize);
3697  return curr_field;
3698 }
3699 
3700 cob_field *
3702 {
3703  size_t calcsize;
3704  cob_field field;
3705 
3706  if (!COB_MODULE_PTR->module_path ||
3707  !*(COB_MODULE_PTR->module_path)) {
3708  COB_FIELD_INIT (1, NULL, &const_alpha_attr);
3709  make_field_entry (&field);
3710  curr_field->size = 0;
3711  curr_field->data[0] = ' ';
3712  return curr_field;
3713  }
3714  calcsize = strlen (*(COB_MODULE_PTR->module_path));
3715  COB_FIELD_INIT (calcsize, NULL, &const_alpha_attr);
3716  make_field_entry (&field);
3717  memcpy (curr_field->data, *(COB_MODULE_PTR->module_path),
3718  calcsize);
3719  return curr_field;
3720 }
3721 
3722 cob_field *
3723 cob_intr_concatenate (const int offset, const int length,
3724  const int params, ...)
3725 {
3726  cob_field **f;
3727  unsigned char *p;
3728  size_t calcsize;
3729  int i;
3730  cob_field field;
3731  va_list args;
3732 
3733  f = cob_malloc ((size_t)params * sizeof (cob_field *));
3734 
3735  va_start (args, params);
3736 
3737  /* Extract args / calculate size */
3738  calcsize = 0;
3739  for (i = 0; i < params; ++i) {
3740  f[i] = va_arg (args, cob_field *);
3741  calcsize += f[i]->size;
3742  }
3743  va_end (args);
3744 
3745  COB_FIELD_INIT (calcsize, NULL, &const_alpha_attr);
3746  make_field_entry (&field);
3747 
3748  p = curr_field->data;
3749  for (i = 0; i < params; ++i) {
3750  memcpy (p, f[i]->data, f[i]->size);
3751  p += f[i]->size;
3752  }
3753 
3754  if (unlikely(offset > 0)) {
3755  calc_ref_mod (curr_field, offset, length);
3756  }
3757  cob_free (f);
3758  return curr_field;
3759 }
3760 
3761 cob_field *
3762 cob_intr_substitute (const int offset, const int length,
3763  const int params, ...)
3764 {
3765  cob_field *ret;
3766  va_list args;
3767 
3768  va_start (args, params);
3769  ret = substitute (offset, length, params, &memcmp, args);
3770  va_end (args);
3771 
3772  return ret;
3773 }
3774 
3775 cob_field *
3776 cob_intr_substitute_case (const int offset, const int length,
3777  const int params, ...)
3778 {
3779  cob_field *ret;
3780  va_list args;
3781 
3782  va_start (args, params);
3783  ret = substitute (offset, length, params, &int_strncasecmp, args);
3784  va_end (args);
3785 
3786  return ret;
3787 }
3788 
3789 cob_field *
3790 cob_intr_trim (const int offset, const int length,
3791  cob_field *srcfield, const int direction)
3792 {
3793  unsigned char *begin;
3794  unsigned char *end;
3795  size_t i;
3796  size_t size;
3797 
3798  make_field_entry (srcfield);
3799 
3800  for (i = 0; i < srcfield->size; ++i) {
3801  if (srcfield->data[i] != ' ') {
3802  break;
3803  }
3804  }
3805  if (i == srcfield->size) {
3806  curr_field->size = 0;
3807  curr_field->data[0] = ' ';
3808  return curr_field;
3809  }
3810 
3811  begin = srcfield->data;
3812  if (direction != 2) {
3813  for (; *begin == ' '; ++begin) ;
3814  }
3815  end = srcfield->data + srcfield->size - 1;
3816  if (direction != 1) {
3817  for (; *end == ' '; end--) ;
3818  }
3819 
3820  size = 0;
3821  for (i = 0; begin <= end; ++begin, ++i) {
3822  curr_field->data[i] = *begin;
3823  ++size;
3824  }
3825  curr_field->size = size;
3826  if (unlikely(offset > 0)) {
3827  calc_ref_mod (curr_field, offset, length);
3828  }
3829  return curr_field;
3830 }
3831 
3832 cob_field *
3834 {
3835  size_t flen;
3836  cob_field field;
3837 
3838  COB_FIELD_INIT (0, NULL, &const_alpha_attr);
3839  if (cobglobptr->cob_exception_code == 0 || !cobglobptr->cob_error_file ||
3840  (cobglobptr->cob_exception_code & 0x0500) != 0x0500) {
3841  field.size = 2;
3842  make_field_entry (&field);
3843  memcpy (curr_field->data, "00", (size_t)2);
3844  } else {
3845  flen = strlen (cobglobptr->cob_error_file->select_name);
3846  field.size = flen + 2;
3847  make_field_entry (&field);
3848  memcpy (curr_field->data,
3849  cobglobptr->cob_error_file->file_status, (size_t)2);
3850  memcpy (&(curr_field->data[2]),
3851  cobglobptr->cob_error_file->select_name, flen);
3852  }
3853  return curr_field;
3854 }
3855 
3856 cob_field *
3858 {
3859  char *buff;
3860  cob_field field;
3861 
3862  COB_FIELD_INIT (0, NULL, &const_alpha_attr);
3863  if (!cobglobptr->cob_got_exception || !cobglobptr->cob_orig_program_id) {
3864  field.size = 1;
3865  make_field_entry (&field);
3866  *(curr_field->data) = ' ';
3867  return curr_field;
3868  }
3869  buff = cob_malloc ((size_t)COB_SMALL_BUFF);
3870  if (cobglobptr->cob_orig_section && cobglobptr->cob_orig_paragraph) {
3871  snprintf (buff, (size_t)COB_SMALL_MAX, "%s; %s OF %s; %u",
3872  cobglobptr->cob_orig_program_id,
3873  cobglobptr->cob_orig_paragraph,
3874  cobglobptr->cob_orig_section,
3875  cobglobptr->cob_orig_line);
3876  } else if (cobglobptr->cob_orig_section) {
3877  snprintf (buff, (size_t)COB_SMALL_MAX, "%s; %s; %u",
3878  cobglobptr->cob_orig_program_id,
3879  cobglobptr->cob_orig_section,
3880  cobglobptr->cob_orig_line);
3881  } else if (cobglobptr->cob_orig_paragraph) {
3882  snprintf (buff, (size_t)COB_SMALL_MAX, "%s; %s; %u",
3883  cobglobptr->cob_orig_program_id,
3884  cobglobptr->cob_orig_paragraph,
3885  cobglobptr->cob_orig_line);
3886  } else {
3887  snprintf (buff, (size_t)COB_SMALL_MAX, "%s; ; %u",
3888  cobglobptr->cob_orig_program_id,
3889  cobglobptr->cob_orig_line);
3890  }
3891  buff[COB_SMALL_MAX] = 0; /* silence warnings */
3892  field.size = strlen (buff);
3893  make_field_entry (&field);
3894  memcpy (curr_field->data, buff, field.size);
3895  cob_free (buff);
3896  return curr_field;
3897 }
3898 
3899 cob_field *
3901 {
3902  const char *except_name;
3903  cob_field field;
3904 
3905  COB_FIELD_INIT (31, NULL, &const_alpha_attr);
3906  make_field_entry (&field);
3907 
3908  memset (curr_field->data, ' ', (size_t)31);
3909  if (cobglobptr->cob_exception_code) {
3910  except_name = cob_get_exception_name ();
3911  if (except_name == NULL) {
3912  except_name = "EXCEPTION-OBJECT";
3913  }
3914  memcpy (curr_field->data, except_name, strlen (except_name));
3915  }
3916  return curr_field;
3917 }
3918 
3919 cob_field *
3921 {
3922  size_t flen;
3923  cob_field field;
3924 
3925  COB_FIELD_INIT (31, NULL, &const_alpha_attr);
3926  make_field_entry (&field);
3927 
3928  memset (curr_field->data, ' ', (size_t)31);
3929  if (cobglobptr->cob_exception_code && cobglobptr->cob_orig_statement) {
3930  flen = strlen (cobglobptr->cob_orig_statement);
3931  if (flen > 31) {
3932  flen = 31;
3933  }
3934  memcpy (curr_field->data, cobglobptr->cob_orig_statement, flen);
3935  }
3936  return curr_field;
3937 }
3938 
3939 cob_field *
3940 cob_intr_when_compiled (const int offset, const int length, cob_field *f)
3941 {
3942  make_field_entry (f);
3943 
3944  memcpy (curr_field->data, f->data, f->size);
3945  if (unlikely(offset > 0)) {
3946  calc_ref_mod (curr_field, offset, length);
3947  }
3948  return curr_field;
3949 }
3950 
3951 cob_field *
3952 cob_intr_current_date (const int offset, const int length)
3953 {
3954  cob_field field;
3955  struct cob_time time;
3956  char buff[22] = { '\0' };
3957 
3958  COB_FIELD_INIT (21, NULL, &const_alpha_attr);
3959  make_field_entry (&field);
3960 
3962 
3963  sprintf (buff, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d%2.2d",
3964  time.year, time.month, time.day_of_month, time.hour,
3965  time.minute, time.second, (int) time.nanosecond / 10000000);
3966 
3967  add_offset_time (0, &time.utc_offset, 16, buff);
3968 
3969  memcpy (curr_field->data, buff, (size_t)21);
3970  if (unlikely(offset > 0)) {
3971  calc_ref_mod (curr_field, offset, length);
3972  }
3973  return curr_field;
3974 }
3975 
3976 cob_field *
3978 {
3979  int i;
3980  cob_field field;
3981 
3982  COB_FIELD_INIT (1, NULL, &const_alpha_attr);
3983  make_field_entry (&field);
3984 
3985  i = cob_get_int (srcfield);
3986  if (i < 1 || i > 256) {
3987  *curr_field->data = 0;
3988  } else {
3989  *curr_field->data = (unsigned char)i - 1;
3990  }
3991  return curr_field;
3992 }
3993 
3994 cob_field *
3996 {
3997  cob_alloc_set_field_uint ((cob_u32_t)(*srcfield->data + 1U));
3998  return curr_field;
3999 }
4000 
4001 cob_field *
4003 {
4004  unsigned char *p;
4005  cob_u32_t count;
4006 
4007  count = srcfield->size;
4008  p = srcfield->data + srcfield->size - 1;
4009  for (; count > 0; count--, p--) {
4010  if (*p != ' ') {
4011  break;
4012  }
4013  }
4014 
4015  cob_alloc_set_field_uint (count);
4016  return curr_field;
4017 }
4018 
4019 cob_field *
4021 {
4022  int srdays;
4023  cob_decimal *combined_datetime;
4024  cob_decimal *srtime;
4025  cob_decimal *hundred_thousand;
4026 
4027  cob_set_exception (0);
4028 
4029  /* Validate and extract the value of srcdays */
4030  srdays = cob_get_int (srcdays);
4031  if (!valid_integer_date (srdays)) {
4032  goto invalid_args;
4033  }
4034  combined_datetime = &d1;
4035  mpz_set_ui (combined_datetime->value, (unsigned long) srdays);
4036  combined_datetime->scale = 0;
4037 
4038  /* Extract and validate the value of srctime */
4039  srtime = &d2;
4040  cob_decimal_set_field (srtime, srctime);
4041  if (!valid_decimal_time (srtime)) {
4042  goto invalid_args;
4043  }
4044 
4045  /* Set a decimal to 100 000. */
4046  hundred_thousand = &d3;
4047  mpz_set_ui (hundred_thousand->value, 100000UL);
4048  hundred_thousand->scale = 0;
4049 
4050  /* Combined datetime = date + (time / 100 000) */
4051  cob_decimal_div (srtime, hundred_thousand);
4052  cob_decimal_add (combined_datetime, srtime);
4053 
4054  cob_alloc_field (combined_datetime);
4055  (void) cob_decimal_get_field (combined_datetime, curr_field, 0);
4056  goto end_of_func;
4057 
4058  invalid_args:
4061 
4062  end_of_func:
4063  return curr_field;
4064 }
4065 
4066 cob_field *
4068 {
4069  int days;
4070  int month;
4071  int year;
4072  cob_field_attr attr;
4073  cob_field field;
4074  char buff[16];
4075 
4077  COB_FIELD_INIT (8, NULL, &attr);
4078  make_field_entry (&field);
4079 
4080  cob_set_exception (0);
4081  /* Base 1601-01-01 */
4082  days = cob_get_int (srcdays);
4083  if (!valid_integer_date (days)) {
4085  memset (curr_field->data, '0', (size_t)8);
4086  return curr_field;
4087  }
4088 
4089  date_of_integer (days, &year, &month, &days);
4090 
4091  snprintf (buff, (size_t)15, "%4.4d%2.2d%2.2d", year, month, days);
4092  memcpy (curr_field->data, buff, (size_t)8);
4093  return curr_field;
4094 }
4095 
4096 cob_field *
4098 {
4099  int days;
4100  int baseyear;
4101  cob_field_attr attr;
4102  cob_field field;
4103  char buff[16];
4104 
4106  COB_FIELD_INIT (7, NULL, &attr);
4107  make_field_entry (&field);
4108 
4109  cob_set_exception (0);
4110  /* Base 1601-01-01 */
4111  days = cob_get_int (srcdays);
4112  if (!valid_integer_date (days)) {
4114  memset (curr_field->data, '0', (size_t)7);
4115  return curr_field;
4116  }
4117 
4118  day_of_integer (days, &baseyear, &days);
4119  snprintf (buff, (size_t)15, "%4.4d%3.3d", baseyear, days);
4120 
4121  memcpy (curr_field->data, buff, (size_t)7);
4122  return curr_field;
4123 }
4124 
4125 cob_field *
4127 {
4128  int indate;
4129  int days;
4130  int month;
4131  int year;
4132 
4133  cob_set_exception (0);
4134  /* Base 1601-01-01 */
4135  indate = cob_get_int (srcfield);
4136  year = indate / 10000;
4137  if (!valid_year (year)) {
4140  return curr_field;
4141  }
4142  indate %= 10000;
4143  month = indate / 100;
4144  if (!valid_month (month)) {
4147  return curr_field;
4148  }
4149  days = indate % 100;
4150  if (!valid_day_of_month (year, month, days)) {
4153  return curr_field;
4154  }
4155 
4156  cob_alloc_set_field_uint (integer_of_date (year, month, days));
4157  return curr_field;
4158 }
4159 
4160 cob_field *
4162 {
4163  int indate;
4164  int days;
4165  int year;
4166 
4167  cob_set_exception (0);
4168  /* Base 1601-01-01 */
4169  indate = cob_get_int (srcfield);
4170  year = indate / 1000;
4171  if (!valid_year (year)) {
4174  return curr_field;
4175  }
4176  days = indate % 1000;
4177  if (!valid_day_of_year (year, days)) {
4180  return curr_field;
4181  }
4182 
4184  return curr_field;
4185 }
4186 
4187 cob_field *
4189 {
4190  int indate;
4191  int days;
4192  int month;
4193  int year;
4194 
4195  /* Base 1601-01-01 */
4196  indate = cob_get_int (srcfield);
4197  year = indate / 10000;
4198  if (!valid_year (year)) {
4200  return curr_field;
4201  }
4202  indate %= 10000;
4203  month = indate / 100;
4204  if (!valid_month (month)) {
4206  return curr_field;
4207  }
4208  days = indate % 100;
4209  if (!valid_day_of_month (year, month, days)) {
4211  return curr_field;
4212  }
4214  return curr_field;
4215 }
4216 
4217 cob_field *
4219 {
4220  int indate;
4221  int days;
4222  int year;
4223 
4224  /* Base 1601-01-01 */
4225  indate = cob_get_int (srcfield);
4226  year = indate / 1000;
4227  if (!valid_year (year)) {
4229  return curr_field;
4230  }
4231  days = indate % 1000;
4232  if (!valid_day_of_year (year, days)) {
4234  return curr_field;
4235  }
4237  return curr_field;
4238 }
4239 
4240 cob_field *
4242 {
4243  int srcval;
4244 
4245  cob_set_exception (0);
4246  srcval = cob_get_int (srcfield);
4247  d1.scale = 0;
4248  if (srcval < 0) {
4251  return curr_field;
4252  } else {
4253  mpz_fac_ui (d1.value, (cob_uli_t)srcval);
4254  }
4255 
4256  cob_alloc_field (&d1);
4257  (void)cob_decimal_get_field (&d1, curr_field, 0);
4258  return curr_field;
4259 }
4260 
4261 cob_field *
4263 {
4264  mpf_set_ui (cob_mpft, 1UL);
4267  cob_alloc_field (&d1);
4268  (void)cob_decimal_get_field (&d1, curr_field, 0);
4269 
4270  return curr_field;
4271 }
4272 
4273 cob_field *
4275 {
4276  mpf_set (cob_mpft, cob_pi);
4278  cob_alloc_field (&d1);
4279  (void)cob_decimal_get_field (&d1, curr_field, 0);
4280 
4281  return curr_field;
4282 }
4283 
4284 cob_field *
4286 {
4287  cob_decimal_set_field (&d1, srcfield);
4288 
4289  cob_set_exception (0);
4290 
4291  if (!mpz_sgn (d1.value)) {
4292  /* Power is zero */
4294  return curr_field;
4295  }
4296 
4300  cob_alloc_field (&d1);
4301  (void)cob_decimal_get_field (&d1, curr_field, 0);
4302 
4303  return curr_field;
4304 }
4305 
4306 cob_field *
4308 {
4309  int sign;
4310 
4311  cob_decimal_set_field (&d1, srcfield);
4312 
4313  cob_set_exception (0);
4314 
4315  sign = mpz_sgn (d1.value);
4316  if (!sign) {
4317  /* Power is zero */
4319  return curr_field;
4320  }
4321 
4322  cob_trim_decimal (&d1);
4323 
4324  if (!d1.scale) {
4325  /* Integer positive/negative powers */
4326  if (sign < 0 && mpz_fits_sint_p (d1.value)) {
4327  mpz_abs (d1.value, d1.value);
4328  d1.scale = mpz_get_si (d1.value);
4329  mpz_set_ui (d1.value, 1UL);
4330  cob_alloc_field (&d1);
4331  (void)cob_decimal_get_field (&d1, curr_field, 0);
4332  return curr_field;
4333  }
4334  if (sign > 0 && mpz_fits_ulong_p (d1.value)) {
4335  mpz_ui_pow_ui (d1.value, 10UL, mpz_get_ui (d1.value));
4336  cob_alloc_field (&d1);
4337  (void)cob_decimal_get_field (&d1, curr_field, 0);
4338  return curr_field;
4339  }
4340  }
4341 
4342  mpz_set_ui (d2.value, 10UL);
4343  d2.scale = 0;
4344  cob_decimal_pow (&d2, &d1);
4345  cob_alloc_field (&d2);
4346  (void)cob_decimal_get_field (&d2, curr_field, 0);
4347 
4348  return curr_field;
4349 }
4350 
4351 cob_field *
4353 {
4354  cob_decimal_set_field (&d1, srcfield);
4355 
4356  cob_set_exception (0);
4357  if (mpz_sgn (d1.value) <= 0) {
4360  return curr_field;
4361  }
4362 
4363  if (d1.scale) {
4364  cob_trim_decimal (&d1);
4365  }
4366 
4367  if (!d1.scale && !mpz_cmp_ui (d1.value, 1UL)) {
4368  /* Log (1) = 0 */
4370  return curr_field;
4371  }
4372 
4376  cob_alloc_field (&d1);
4377  (void)cob_decimal_get_field (&d1, curr_field, 0);
4378 
4379  return curr_field;
4380 }
4381 
4382 cob_field *
4384 {
4385  cob_decimal_set_field (&d1, srcfield);
4386 
4387  cob_set_exception (0);
4388  if (mpz_sgn (d1.value) <= 0) {
4391  return curr_field;
4392  }
4393 
4394  if (d1.scale) {
4395  cob_trim_decimal (&d1);
4396  }
4397 
4398  if (!d1.scale && !mpz_cmp_ui (d1.value, 1UL)) {
4399  /* Log10 (1) = 0 */
4401  return curr_field;
4402  }
4403 
4407  cob_alloc_field (&d1);
4408  (void)cob_decimal_get_field (&d1, curr_field, 0);
4409 
4410  return curr_field;
4411 }
4412 
4413 cob_field *
4415 {
4416  cob_decimal_set_field (&d1, srcfield);
4417  mpz_abs (d1.value, d1.value);
4418 
4419  make_field_entry (srcfield);
4420  (void)cob_decimal_get_field (&d1, curr_field, 0);
4421  return curr_field;
4422 }
4423 
4424 cob_field *
4426 {
4427  cob_decimal_set_field (&d1, srcfield);
4428 
4429  mpz_set (d4.value, d1.value);
4430  mpz_set (d5.value, d1.value);
4431  d4.scale = d1.scale;
4432  d5.scale = d1.scale;
4433  mpz_set_si (d2.value, -1L);
4434  d2.scale = 0;
4435  mpz_set_ui (d3.value, 1UL);
4436  d3.scale = 0;
4437 
4438  cob_set_exception (0);
4439  if (cob_decimal_cmp (&d4, &d2) < 0 || cob_decimal_cmp (&d5, &d3) > 0) {
4442  return curr_field;
4443  }
4444 
4448  cob_alloc_field (&d1);
4449  (void)cob_decimal_get_field (&d1, curr_field, 0);
4450 
4451  return curr_field;
4452 }
4453 
4454 cob_field *
4456 {
4457  cob_decimal_set_field (&d1, srcfield);
4458 
4459  mpz_set (d4.value, d1.value);
4460  mpz_set (d5.value, d1.value);
4461  d4.scale = d1.scale;
4462  d5.scale = d1.scale;
4463  mpz_set_si (d2.value, -1L);
4464  d2.scale = 0;
4465  mpz_set_ui (d3.value, 1UL);
4466  d3.scale = 0;
4467 
4468  cob_set_exception (0);
4469  if (cob_decimal_cmp (&d4, &d2) < 0 || cob_decimal_cmp (&d5, &d3) > 0) {
4472  return curr_field;
4473  }
4474 
4475  if (!mpz_sgn (d1.value)) {
4476  /* Asin (0) = 0 */
4478  return curr_field;
4479  }
4480 
4484  cob_alloc_field (&d1);
4485  (void)cob_decimal_get_field (&d1, curr_field, 0);
4486 
4487  return curr_field;
4488 }
4489 
4490 cob_field *
4492 {
4493  cob_decimal_set_field (&d1, srcfield);
4494 
4495  cob_set_exception (0);
4496 
4497  if (!mpz_sgn (d1.value)) {
4498  /* Atan (0) = 0 */
4500  return curr_field;
4501  }
4502 
4506  cob_alloc_field (&d1);
4507  (void)cob_decimal_get_field (&d1, curr_field, 0);
4508 
4509  return curr_field;
4510 }
4511 
4512 cob_field *
4514 {
4515  cob_decimal_set_field (&d1, srcfield);
4516 
4517  cob_set_exception (0);
4518 
4522  cob_alloc_field (&d1);
4523  (void)cob_decimal_get_field (&d1, curr_field, 0);
4524 
4525  return curr_field;
4526 }
4527 
4528 cob_field *
4530 {
4531  cob_decimal_set_field (&d1, srcfield);
4532 
4533  cob_set_exception (0);
4534 
4538  cob_alloc_field (&d1);
4539  (void)cob_decimal_get_field (&d1, curr_field, 0);
4540 
4541  return curr_field;
4542 }
4543 
4544 cob_field *
4546 {
4547  cob_decimal_set_field (&d1, srcfield);
4548 
4549  cob_set_exception (0);
4550 
4554  cob_alloc_field (&d1);
4555  (void)cob_decimal_get_field (&d1, curr_field, 0);
4556 
4557  return curr_field;
4558 }
4559 
4560 cob_field *
4562 {
4563  cob_decimal_set_field (&d1, srcfield);
4564 
4565  cob_set_exception (0);
4566  if (mpz_sgn (d1.value) < 0) {
4569  return curr_field;
4570  }
4571 
4572  mpz_set_ui (d2.value, 5UL);
4573  d2.scale = 1;
4574  cob_trim_decimal (&d1);
4575  cob_decimal_pow (&d1, &d2);
4576 
4577  cob_alloc_field (&d1);
4578  (void)cob_decimal_get_field (&d1, curr_field, 0);
4579 
4580  return curr_field;
4581 }
4582 
4583 cob_field *
4585 {
4586  return numval (srcfield, NULL, NUMVAL);
4587 }
4588 
4589 cob_field *
4590 cob_intr_numval_c (cob_field *srcfield, cob_field *currency)
4591 {
4592  return numval (srcfield, currency, NUMVAL_C);
4593 }
4594 
4595 cob_field *
4597 {
4598  unsigned char *final_buff;
4599  unsigned char *p;
4600  size_t plus_minus;
4601  size_t digits;
4602  size_t decimal_digits;
4603  size_t dec_seen;
4604  size_t e_seen;
4605  size_t exponent;
4606  size_t e_plus_minus;
4607  size_t n;
4608  unsigned char dec_pt;
4609 
4610  /* Validate source field */
4611  if (cob_check_numval_f (srcfield)) {
4614  return curr_field;
4615  }
4616 
4617  plus_minus = 0;
4618  digits = 0;
4619  decimal_digits = 0;
4620  dec_seen = 0;
4621  e_seen = 0;
4622  exponent = 0;
4623  e_plus_minus = 0;
4624  dec_pt = COB_MODULE_PTR->decimal_point;
4625 
4626  final_buff = cob_malloc (srcfield->size + 1U);
4627  p = srcfield->data;
4628  for (n = 0; n < srcfield->size; ++n, ++p) {
4629  switch (*p) {
4630  case '0':
4631  case '1':
4632  case '2':
4633  case '3':
4634  case '4':
4635  case '5':
4636  case '6':
4637  case '7':
4638  case '8':
4639  case '9':
4640  if (e_seen) {
4641  exponent *= 10;
4642  exponent += (*p & 0x0F);
4643  } else {
4644  if (dec_seen) {
4645  decimal_digits++;
4646  }
4647  final_buff[digits++] = *p;
4648  }
4649  continue;
4650  case 'E':
4651  e_seen = 1;
4652  continue;
4653  case '-':
4654  if (e_seen) {
4655  e_plus_minus = 1;
4656  } else {
4657  plus_minus = 1;
4658  }
4659  continue;
4660  default:
4661  if (*p == dec_pt) {
4662  dec_seen = 1;
4663  }
4664  continue;
4665  }
4666  }
4667 
4668  if (!digits) {
4669  final_buff[0] = '0';
4670  }
4671 
4672  mpz_set_str (d1.value, (char *)final_buff, 10);
4673  cob_free (final_buff);
4674  if (!mpz_sgn (d1.value)) {
4675  /* Value is zero ; sign and exponent irrelevant */
4676  d1.scale = 0;
4677  cob_alloc_field (&d1);
4678  (void)cob_decimal_get_field (&d1, curr_field, 0);
4679  return curr_field;
4680  }
4681  if (plus_minus) {
4682  mpz_neg (d1.value, d1.value);
4683  }
4684  if (exponent) {
4685  if (e_plus_minus) {
4686  /* Negative exponent */
4687  d1.scale = decimal_digits + exponent;
4688  } else {
4689  /* Positive exponent */
4690  if (decimal_digits >= exponent) {
4691  d1.scale = decimal_digits - exponent;
4692  } else {
4693  exponent -= decimal_digits;
4694  mpz_ui_pow_ui (cob_mexp, 10UL,
4695  (cob_uli_t)exponent);
4696  mpz_mul (d1.value, d1.value, cob_mexp);
4697  d1.scale = 0;
4698  }
4699  }
4700  } else {
4701  /* No exponent */
4702  d1.scale = decimal_digits;
4703  }
4704 
4705  cob_alloc_field (&d1);
4706  (void)cob_decimal_get_field (&d1, curr_field, 0);
4707 
4708  return curr_field;
4709 }
4710 
4711 cob_field *
4712 cob_intr_annuity (cob_field *srcfield1, cob_field *srcfield2)
4713 {
4714  int sign;
4715 
4716  cob_decimal_set_field (&d1, srcfield1);
4717  cob_decimal_set_field (&d2, srcfield2);
4718 
4719  /* P1 >= 0, P2 > 0 and integer */
4720  sign = mpz_sgn (d1.value);
4721  if (sign < 0 || mpz_sgn (d2.value) <= 0 || d2.scale != 0) {
4724  return curr_field;
4725  }
4726 
4727  if (!sign) {
4728  mpz_set_ui (d1.value, 1UL);
4729  d1.scale = 0;
4730  cob_decimal_div (&d1, &d2);
4731  cob_alloc_field (&d1);
4732  (void)cob_decimal_get_field (&d1, curr_field, 0);
4733  return curr_field;
4734  }
4735 
4736  /* x = P1 / (1 - (1 + P1) ^ (-P2)) */
4737  mpz_neg (d2.value, d2.value);
4738 
4739  mpz_set (d3.value, d1.value);
4740  d3.scale = d1.scale;
4741  mpz_set_ui (d4.value, 1UL);
4742  d4.scale = 0;
4743  cob_decimal_add (&d3, &d4);
4744  cob_trim_decimal (&d3);
4745  cob_trim_decimal (&d2);
4746  cob_decimal_pow (&d3, &d2);
4747  mpz_set_ui (d4.value, 1UL);
4748  d4.scale = 0;
4749  cob_decimal_sub (&d4, &d3);
4750  cob_trim_decimal (&d4);
4751  cob_trim_decimal (&d1);
4752  cob_decimal_div (&d1, &d4);
4753  cob_alloc_field (&d1);
4754  (void)cob_decimal_get_field (&d1, curr_field, 0);
4755  return curr_field;
4756 }
4757 
4758 cob_field *
4759 cob_intr_sum (const int params, ...)
4760 {
4761  cob_field *f;
4762  va_list args;
4763  int i;
4764 
4765  mpz_set_ui (d1.value, 0UL);
4766  d1.scale = 0;
4767 
4768  va_start (args, params);
4769 
4770  for (i = 0; i < params; ++i) {
4771  f = va_arg (args, cob_field *);
4772  cob_decimal_set_field (&d2, f);
4773  cob_decimal_add (&d1, &d2);
4774  }
4775  va_end (args);
4776 
4777  cob_alloc_field (&d1);
4778  (void)cob_decimal_get_field (&d1, curr_field, 0);
4779  return curr_field;
4780 }
4781 
4782 cob_field *
4783 cob_intr_ord_min (const int params, ...)
4784 {
4785  cob_field *f;
4786  cob_field *basef;
4787  int i;
4788  cob_u32_t ordmin;
4789  va_list args;
4790 
4791  va_start (args, params);
4792 
4793  ordmin = 1;
4794  basef = va_arg (args, cob_field *);
4795  for (i = 1; i < params; ++i) {
4796  f = va_arg (args, cob_field *);
4797  if (cob_cmp (f, basef) < 0) {
4798  basef = f;
4799  ordmin = i + 1;
4800  }
4801  }
4802  va_end (args);
4803 
4804  cob_alloc_set_field_uint (ordmin);
4805  return curr_field;
4806 }
4807 
4808 cob_field *
4809 cob_intr_ord_max (const int params, ...)
4810 {
4811  cob_field *f;
4812  cob_field *basef;
4813  cob_u32_t ordmax;
4814  int i;
4815  va_list args;
4816 
4817  va_start (args, params);
4818 
4819  ordmax = 1;
4820  basef = va_arg (args, cob_field *);
4821  for (i = 1; i < params; ++i) {
4822  f = va_arg (args, cob_field *);
4823  if (cob_cmp (f, basef) > 0) {
4824  basef = f;
4825  ordmax = i + 1;
4826  }
4827  }
4828  va_end (args);
4829 
4830  cob_alloc_set_field_uint (ordmax);
4831  return curr_field;
4832 }
4833 
4834 cob_field *
4835 cob_intr_min (const int params, ...)
4836 {
4837  cob_field *f;
4838  cob_field *basef;
4839  va_list args;
4840  int i;
4841 
4842  va_start (args, params);
4843 
4844  basef = va_arg (args, cob_field *);
4845  for (i = 1; i < params; ++i) {
4846  f = va_arg (args, cob_field *);
4847  if (cob_cmp (f, basef) < 0) {
4848  basef = f;
4849  }
4850  }
4851  va_end (args);
4852 
4853  make_field_entry (basef);
4854  memcpy (curr_field->data, basef->data, basef->size);
4855  return curr_field;
4856 }
4857 
4858 cob_field *
4859 cob_intr_max (const int params, ...)
4860 {
4861  cob_field *f;
4862  cob_field *basef;
4863  va_list args;
4864  int i;
4865 
4866  va_start (args, params);
4867 
4868  basef = va_arg (args, cob_field *);
4869  for (i = 1; i < params; ++i) {
4870  f = va_arg (args, cob_field *);
4871  if (cob_cmp (f, basef) > 0) {
4872  basef = f;
4873  }
4874  }
4875  va_end (args);
4876 
4877  make_field_entry (basef);
4878  memcpy (curr_field->data, basef->data, basef->size);
4879  return curr_field;
4880 }
4881 
4882 cob_field *
4883 cob_intr_midrange (const int params, ...)
4884 {
4885  cob_field *basemin;
4886  cob_field *basemax;
4887  va_list args;
4888 
4889  va_start (args, params);
4890  get_min_and_max_of_args (params, args, &basemin, &basemax);
4891  va_end (args);
4892 
4893  /* Return (max + min) / 2 */
4894  cob_decimal_set_field (&d1, basemin);
4895  cob_decimal_set_field (&d2, basemax);
4896  cob_decimal_add (&d1, &d2);
4897  mpz_set_ui (d2.value, 2UL);
4898  d2.scale = 0;
4899  cob_decimal_div (&d1, &d2);
4900 
4901  cob_alloc_field (&d1);
4902  (void)cob_decimal_get_field (&d1, curr_field, 0);
4903  return curr_field;
4904 }
4905 
4906 cob_field *
4907 cob_intr_median (const int params, ...)
4908 {
4909  cob_field *f;
4910  cob_field **field_alloc;
4911  va_list args;
4912  int i;
4913 
4914  va_start (args, params);
4915 
4916  f = va_arg (args, cob_field *);
4917  if (params == 1) {
4918  va_end (args);
4919  make_field_entry (f);
4920  memcpy (curr_field->data, f->data, f->size);
4921  return curr_field;
4922  }
4923 
4924  field_alloc = cob_malloc ((size_t)params * sizeof (cob_field *));
4925  field_alloc[0] = f;
4926 
4927  for (i = 1; i < params; ++i) {
4928  field_alloc[i] = va_arg (args, cob_field *);
4929  }
4930  va_end (args);
4931 
4932  qsort (field_alloc, (size_t)params, (size_t)sizeof (cob_field *),
4933  comp_field);
4934 
4935  i = params / 2;
4936  if (params % 2) {
4937  f = field_alloc[i];
4938  make_field_entry (f);
4939  memcpy (curr_field->data, f->data, f->size);
4940  } else {
4941  cob_decimal_set_field (&d1, field_alloc[i-1]);
4942  cob_decimal_set_field (&d2, field_alloc[i]);
4943  cob_decimal_add (&d1, &d2);
4944  mpz_set_ui (d2.value, 2UL);
4945  d2.scale = 0;
4946  cob_decimal_div (&d1, &d2);
4947  cob_alloc_field (&d1);
4948  (void)cob_decimal_get_field (&d1, curr_field, 0);
4949  }
4950  cob_free (field_alloc);
4951  return curr_field;
4952 }
4953 
4954 cob_field *
4955 cob_intr_mean (const int params, ...)
4956 {
4957  cob_field *f;
4958  va_list args;
4959  int i;
4960 
4961  va_start (args, params);
4962 
4963  if (params == 1) {
4964  f = va_arg (args, cob_field *);
4965  va_end (args);
4966  make_field_entry (f);
4967  memcpy (curr_field->data, f->data, f->size);
4968  return curr_field;
4969  }
4970 
4971  mpz_set_ui (d1.value, 0UL);
4972  d1.scale = 0;
4973 
4974  for (i = 0; i < params; ++i) {
4975  f = va_arg (args, cob_field *);
4976  cob_decimal_set_field (&d2, f);
4977  cob_decimal_add (&d1, &d2);
4978  }
4979  va_end (args);
4980 
4981  mpz_set_ui (d2.value, (cob_uli_t)params);
4982  d2.scale = 0;
4983  cob_decimal_div (&d1, &d2);
4984 
4985  cob_alloc_field (&d1);
4986  (void)cob_decimal_get_field (&d1, curr_field, 0);
4987 
4988  return curr_field;
4989 }
4990 
4991 cob_field *
4992 cob_intr_mod (cob_field *srcfield1, cob_field *srcfield2)
4993 {
4994  return cob_mod_or_rem (srcfield1, srcfield2, 0);
4995 }
4996 
4997 cob_field *
4998 cob_intr_range (const int params, ...)
4999 {
5000  cob_field *basemin, *basemax;
5001  va_list args;
5002 
5003  va_start (args, params);
5004  get_min_and_max_of_args (params, args, &basemin, &basemax);
5005  va_end (args);
5006 
5007  cob_decimal_set_field (&d1, basemax);
5008  cob_decimal_set_field (&d2, basemin);
5009  cob_decimal_sub (&d1, &d2);
5010 
5011  cob_alloc_field (&d1);
5012  (void)cob_decimal_get_field (&d1, curr_field, 0);
5013  return curr_field;
5014 }
5015 
5016 cob_field *
5017 cob_intr_rem (cob_field *srcfield1, cob_field *srcfield2)
5018 {
5019  return cob_mod_or_rem (srcfield1, srcfield2, 1);
5020 }
5021 
5022 cob_field *
5023 cob_intr_random (const int params, ...)
5024 {
5025  cob_field *f;
5026  va_list args;
5027  double val;
5028  int seed;
5029  int randnum;
5030  cob_field_attr attr;
5031  cob_field field;
5032 
5034  COB_FIELD_INIT (sizeof(double), NULL, &attr);
5035  va_start (args, params);
5036 
5037  if (params) {
5038  f = va_arg (args, cob_field *);
5039  seed = cob_get_int (f);
5040  if (seed < 0) {
5041  seed = 0;
5042  }
5043 #ifdef __CYGWIN__
5044  srandom ((unsigned int)seed);
5045 #else
5046  srand ((unsigned int)seed);
5047 #endif
5048  }
5049  va_end (args);
5050 
5051 #ifdef __CYGWIN__
5052  randnum = (int)random ();
5053 #else
5054  randnum = rand ();
5055 #endif
5056  make_field_entry (&field);
5057  val = (double)randnum / (double)RAND_MAX;
5058  memcpy (curr_field->data, &val, sizeof(val));
5059  return curr_field;
5060 }
5061 
5062 #define GET_VARIANCE(num_args, args) \
5063  do { \
5064  /* Get mean in d1 */ \
5065  va_start (args, num_args); \
5066  calc_mean_of_args (num_args, args); \
5067  va_end (args); \
5068  \
5069  cob_decimal_set (&d5, &d1); \
5070  \
5071  /* Get variance in d1 */ \
5072  va_start (args, num_args); \
5073  calc_variance_of_args (num_args, args, &d5); \
5074  va_end (args); \
5075  } ONCE_COB
5076 
5077 cob_field *
5078 cob_intr_variance (const int num_args, ...)
5079 {
5080  va_list args;
5081 
5082  GET_VARIANCE (num_args, args);
5083 
5084  cob_alloc_field (&d1);
5085  (void)cob_decimal_get_field (&d1, curr_field, 0);
5086  return curr_field;
5087 }
5088 
5089 cob_field *
5090 cob_intr_standard_deviation (const int num_args, ...)
5091 {
5092  va_list args;
5093 
5094  GET_VARIANCE (num_args, args);
5095  cob_trim_decimal (&d1);
5096 
5097  cob_set_exception (0);
5098 
5099  /* Take square root of variance */
5100  mpz_set_ui (d3.value, 5UL);
5101  d3.scale = 1;
5102 
5103  cob_decimal_pow (&d1, &d3);
5104 
5105  cob_alloc_field (&d1);
5106  (void)cob_decimal_get_field (&d1, curr_field, 0);
5107  return curr_field;
5108 }
5109 
5110 #undef GET_VARIANCE
5111 
5112 cob_field *
5113 cob_intr_present_value (const int params, ...)
5114 {
5115  cob_field *f;
5116  va_list args;
5117  int i;
5118 
5119  va_start (args, params);
5120 
5121  f = va_arg (args, cob_field *);
5122 
5123  cob_decimal_set_field (&d1, f);
5124  mpz_set_ui (d2.value, 1UL);
5125  d2.scale = 0;
5126  cob_decimal_add (&d1, &d2);
5127 
5128  mpz_set_ui (d4.value, 0UL);
5129  d4.scale = 0;
5130 
5131  for (i = 1; i < params; ++i) {
5132  f = va_arg (args, cob_field *);
5133  cob_decimal_set_field (&d2, f);
5134  mpz_set (d3.value, d1.value);
5135  d3.scale = d1.scale;
5136  if (i > 1) {
5137  mpz_pow_ui (d3.value, d3.value, (cob_uli_t)i);
5138  d3.scale *= i;
5139  }
5140  cob_decimal_div (&d2, &d3);
5141  cob_decimal_add (&d4, &d2);
5142  }
5143  va_end (args);
5144 
5145  cob_alloc_field (&d4);
5146  (void)cob_decimal_get_field (&d4, curr_field, 0);
5147  return curr_field;
5148 }
5149 
5150 cob_field *
5151 cob_intr_year_to_yyyy (const int params, ...)
5152 {
5153  cob_field *f;
5154  struct tm *timeptr;
5155  va_list args;
5156  time_t t;
5157  int year;
5158  int interval;
5159  int current_year;
5160  int maxyear;
5161 
5162  cob_set_exception (0);
5163  va_start (args, params);
5164  f = va_arg (args, cob_field *);
5165  year = cob_get_int (f);
5166  if (params > 1) {
5167  f = va_arg (args, cob_field *);
5168  interval = cob_get_int (f);
5169  } else {
5170  interval = 50;
5171  }
5172  if (params > 2) {
5173  f = va_arg (args, cob_field *);
5174  current_year = cob_get_int (f);
5175  } else {
5176  t = time (NULL);
5177  timeptr = localtime (&t);
5178  current_year = 1900 + timeptr->tm_year;
5179  }
5180  va_end (args);
5181 
5182  if (year < 0 || year > 99) {
5185  return curr_field;
5186  }
5187  if (!valid_year (current_year)) {
5190  return curr_field;
5191  }
5192  maxyear = current_year + interval;
5193  if (maxyear < 1700 || maxyear > 9999) {
5196  return curr_field;
5197  }
5198  if (maxyear % 100 >= year) {
5199  year += 100 * (maxyear / 100);
5200  } else {
5201  year += 100 * ((maxyear / 100) - 1);
5202  }
5203  cob_alloc_set_field_int (year);
5204  return curr_field;
5205 }
5206 
5207 cob_field *
5208 cob_intr_date_to_yyyymmdd (const int params, ...)
5209 {
5210  cob_field *f;
5211  va_list args;
5212  int year;
5213  int mmdd;
5214  int interval;
5215  int current_year;
5216  int maxyear;
5217 
5218  cob_set_exception (0);
5219 
5220  va_start (args, params);
5221 
5222  f = va_arg (args, cob_field *);
5223  year = cob_get_int (f);
5224  mmdd = year % 10000;
5225  year /= 10000;
5226 
5227  get_interval_and_current_year_from_args (params, args, &interval,
5228  &current_year);
5229 
5230  va_end (args);
5231 
5232  maxyear = current_year + interval;
5233  /* The unusual year checks are as specified in the standard */
5234  if (year < 0 || year > 999999
5235  || !valid_year (current_year)
5236  || (maxyear < 1700 || maxyear > 9999)) {
5239  return curr_field;
5240  }
5241 
5242  if (maxyear % 100 >= year) {
5243  year += 100 * (maxyear / 100);
5244  } else {
5245  year += 100 * ((maxyear / 100) - 1);
5246  }
5247  year *= 10000;
5248  year += mmdd;
5249  cob_alloc_set_field_int (year);
5250  return curr_field;
5251 }
5252 
5253 cob_field *
5254 cob_intr_day_to_yyyyddd (const int params, ...)
5255 {
5256  cob_field *f;
5257  va_list args;
5258  int year;
5259  int days;
5260  int interval;
5261  int current_year;
5262  int maxyear;
5263 
5264  cob_set_exception (0);
5265 
5266  va_start (args, params);
5267 
5268  f = va_arg (args, cob_field *);
5269  year = cob_get_int (f);
5270  days = year % 1000;
5271  year /= 1000;
5272 
5273  get_interval_and_current_year_from_args (params, args, &interval,
5274  &current_year);
5275 
5276  va_end (args);
5277 
5278  if (year < 0 || year > 999999) {
5281  return curr_field;
5282  }
5283  if (!valid_year (current_year)) {
5286  return curr_field;
5287  }
5288  maxyear = current_year + interval;
5289  if (maxyear < 1700 || maxyear > 9999) {
5292  return curr_field;
5293  }
5294  if (maxyear % 100 >= year) {
5295  year += 100 * (maxyear / 100);
5296  } else {
5297  year += 100 * ((maxyear / 100) - 1);
5298  }
5299  year *= 1000;
5300  year += days;
5301  cob_alloc_set_field_int (year);
5302  return curr_field;
5303 }
5304 
5305 cob_field *
5307 {
5308  struct tm *timeptr;
5309  time_t t;
5310  int seconds;
5311 
5312  t = time (NULL);
5313  timeptr = localtime (&t);
5314  /* Leap seconds ? */
5315  if (timeptr->tm_sec >= 60) {
5316  timeptr->tm_sec = 59;
5317  }
5318  seconds = (timeptr->tm_hour * 3600) + (timeptr->tm_min * 60) +
5319  timeptr->tm_sec;
5320  cob_alloc_set_field_int (seconds);
5321  return curr_field;
5322 }
5323 
5324 cob_field *
5326 {
5327  size_t str_length;
5328  char format_str[COB_DATETIMESTR_LEN] = { '\0' };
5329  const char decimal_point = COB_MODULE_PTR->decimal_point;
5330  int is_datetime = 0;
5331  char time_str[COB_DATETIMESTR_LEN] = { '\0' };
5332  struct time_format time_fmt;
5333  cob_decimal *seconds = &d1;
5334 
5335  str_length = num_leading_nonspace ((char *) format_field->data);
5336  memcpy (format_str, format_field->data, str_length);
5337 
5338  cob_set_exception (0);
5339 
5340  /* Validate the format string */
5341  if (cob_valid_datetime_format (format_str, decimal_point)) {
5342  is_datetime = 1;
5343  } else if (!cob_valid_time_format (format_str, decimal_point)) {
5344  goto invalid_args;
5345  }
5346 
5347  /* Extract the time part of the strings */
5348  if (is_datetime) {
5349  split_around_t (format_str, NULL, format_str);
5350  split_around_t ((char *) time_field->data, NULL, time_str);
5351  } else {
5352  memcpy (time_str, time_field->data, str_length);
5353  }
5354 
5355  /* Validate the formatted time */
5356  time_fmt = parse_time_format_string (format_str);
5357  if (test_formatted_time (time_fmt, time_str, decimal_point) != 0) {
5358  goto invalid_args;
5359  }
5360 
5361  seconds_from_formatted_time (time_fmt, time_str, seconds);
5362 
5363  cob_alloc_field (seconds);
5364  (void) cob_decimal_get_field (seconds, curr_field, 0);
5365 
5366  return curr_field;
5367 
5368  invalid_args:
5371  return curr_field;
5372 }
5373 
5374 cob_field *
5375 cob_intr_locale_date (const int offset, const int length,
5376  cob_field *srcfield, cob_field *locale_field)
5377 {
5378 #if defined(_WIN32) || defined(__CYGWIN__) || defined(HAVE_LANGINFO_CODESET)
5379  size_t len;
5380  int indate;
5381  int days;
5382  int month;
5383  int year;
5384 #ifdef HAVE_LANGINFO_CODESET
5385  unsigned char *p;
5386  char *deflocale = NULL;
5387  struct tm tstruct;
5388  char buff2[128];
5389 #else
5390  unsigned char *p;
5391  LCID localeid = LOCALE_USER_DEFAULT;
5392  SYSTEMTIME syst;
5393 #endif
5394  char buff[128];
5395  char locale_buff[COB_SMALL_BUFF];
5396 #endif
5397 
5398  cob_set_exception (0);
5399 
5400 #if defined(_WIN32) || defined(__CYGWIN__) || defined(HAVE_LANGINFO_CODESET)
5401  if (COB_FIELD_IS_NUMERIC (srcfield)) {
5402  indate = cob_get_int (srcfield);
5403  } else {
5404  if (srcfield->size < 8) {
5405  goto derror;
5406  }
5407  p = srcfield->data;
5408  indate = 0;
5409  for (len = 0; len < 8; ++len, ++p) {
5410  if (isdigit (*p)) {
5411  indate *= 10;
5412  indate += (*p - '0');
5413  } else {
5414  goto derror;
5415  }
5416  }
5417  }
5418  year = indate / 10000;
5419  if (!valid_year (year)) {
5420  goto derror;
5421  }
5422  indate %= 10000;
5423  month = indate / 100;
5424  if (!valid_month (month)) {
5425  goto derror;
5426  }
5427  days = indate % 100;
5428  if (!valid_day_of_month (year, month, days)) {
5429  goto derror;
5430  }
5431 #ifdef HAVE_LANGINFO_CODESET
5432  month--;
5433 
5434  memset ((void *)&tstruct, 0, sizeof(struct tm));
5435  tstruct.tm_year = year - 1900;
5436  tstruct.tm_mon = month;
5437  tstruct.tm_mday = days;
5438  if (locale_field) {
5439  if (locale_field->size >= COB_SMALL_BUFF) {
5440  goto derror;
5441  }
5442  cob_field_to_string (locale_field, locale_buff,
5443  (size_t)COB_SMALL_MAX);
5444  deflocale = locale_buff;
5445  (void) setlocale (LC_TIME, deflocale);
5446  }
5447  memset (buff2, 0, sizeof(buff2));
5448  snprintf(buff2, sizeof(buff2) - 1, "%s", nl_langinfo(D_FMT));
5449  if (deflocale) {
5450  (void) setlocale (LC_ALL, cobglobptr->cob_locale);
5451  }
5452  strftime (buff, sizeof(buff), buff2, &tstruct);
5453 #else
5454  memset ((void *)&syst, 0, sizeof(syst));
5455  syst.wYear = (WORD)year;
5456  syst.wMonth = (WORD)month;
5457  syst.wDay = (WORD)days;
5458  if (locale_field) {
5459  if (locale_field->size >= COB_SMALL_BUFF) {
5460  goto derror;
5461  }
5462  cob_field_to_string (locale_field, locale_buff,
5463  COB_SMALL_MAX);
5464  locale_buff[COB_SMALL_MAX] = 0; /* silence warnings */
5465  for (p = (unsigned char *)locale_buff; *p; ++p) {
5466  if (isalnum(*p) || *p == '_') {
5467  continue;
5468  }
5469  break;
5470  }
5471  *p = 0;
5472  for (len = 0; len < WINLOCSIZE; ++len) {
5473  if (!strcmp(locale_buff, wintable[len].winlocalename)) {
5474  localeid = wintable[len].winlocaleid;
5475  break;
5476  }
5477  }
5478  if (len == WINLOCSIZE) {
5479  goto derror;
5480  }
5481  }
5482  if (!GetDateFormat (localeid, DATE_SHORTDATE, &syst, NULL, buff, sizeof(buff))) {
5483  goto derror;
5484  }
5485 #endif
5486  cob_alloc_set_field_str (buff, offset, length);
5487  return curr_field;
5488 derror:
5489 #endif
5492  return curr_field;
5493 }
5494 
5495 cob_field *
5496 cob_intr_locale_time (const int offset, const int length,
5497  cob_field *srcfield, cob_field *locale_field)
5498 {
5499 #if defined(_WIN32) || defined(__CYGWIN__) || defined(HAVE_LANGINFO_CODESET)
5500  unsigned char *p;
5501  size_t len;
5502  int indate;
5503  int hours;
5504  int minutes;
5505  int seconds;
5506  char buff[LOCTIME_BUFSIZE] = { '\0' };
5507 #endif
5508 
5509  cob_set_exception (0);
5510 
5511 #if defined(_WIN32) || defined(__CYGWIN__) || defined(HAVE_LANGINFO_CODESET)
5512  if (COB_FIELD_IS_NUMERIC (srcfield)) {
5513  indate = cob_get_int (srcfield);
5514  } else {
5515  if (srcfield->size < 6) {
5516  goto derror;
5517  }
5518  p = srcfield->data;
5519  indate = 0;
5520  for (len = 0; len < 6; ++len, ++p) {
5521  if (isdigit (*p)) {
5522  indate *= 10;
5523  indate += (*p - '0');
5524  } else {
5525  goto derror;
5526  }
5527  }
5528  }
5529  hours = indate / 10000;
5530  if (hours < 0 || hours > 24) {
5531  goto derror;
5532  }
5533  indate %= 10000;
5534  minutes = indate / 100;
5535  if (minutes < 0 || minutes > 59) {
5536  goto derror;
5537  }
5538  seconds = indate % 100;
5539  if (seconds < 0 || seconds > 59) {
5540  goto derror;
5541  }
5542 
5543  if (locale_time (hours, minutes, seconds, locale_field, buff)) {
5544  goto derror;
5545  }
5546 
5547  cob_alloc_set_field_str (buff, offset, length);
5548  return curr_field;
5549 derror:
5550 #endif
5553  return curr_field;
5554 }
5555 
5556 cob_field *
5557 cob_intr_lcl_time_from_secs (const int offset, const int length,
5558  cob_field *srcfield, cob_field *locale_field)
5559 {
5560 #if defined(_WIN32) || defined(__CYGWIN__) || defined(HAVE_LANGINFO_CODESET)
5561  int indate;
5562  int hours;
5563  int minutes;
5564  int seconds;
5565  char buff[LOCTIME_BUFSIZE] = { '\0' };
5566 #endif
5567 
5568  cob_set_exception (0);
5569 
5570 #if defined(_WIN32) || defined(__CYGWIN__) || defined(HAVE_LANGINFO_CODESET)
5571  if (COB_FIELD_IS_NUMERIC (srcfield)) {
5572  indate = cob_get_int (srcfield);
5573  } else {
5574  goto derror;
5575  }
5576  if (!valid_time (indate)) {
5577  goto derror;
5578  }
5579  hours = indate / 3600;
5580  indate %= 3600;
5581  minutes = indate / 60;
5582  seconds = indate % 60;
5583 
5584  if (locale_time (hours, minutes, seconds, locale_field, buff)) {
5585  goto derror;
5586  }
5587 
5588  cob_alloc_set_field_str (buff, offset, length);
5589  return curr_field;
5590 derror:
5591 #endif
5594  return curr_field;
5595 }
5596 
5597 cob_field *
5599 {
5600 #ifdef HAVE_LOCALECONV
5601  struct lconv *p;
5602  size_t size;
5603 #endif
5604  cob_field field;
5605 
5606  COB_FIELD_INIT (0, NULL, &const_alpha_attr);
5607  cob_set_exception (0);
5608 
5609 #ifdef HAVE_LOCALECONV
5610  p = localeconv ();
5611  size = strlen (p->mon_decimal_point);
5612  if (size) {
5613  field.size = size;
5614  } else {
5615  field.size = 1;
5616  }
5617  make_field_entry (&field);
5618  if (size) {
5619  memcpy (curr_field->data, p->mon_decimal_point, size);
5620  } else {
5621  curr_field->size = 0;
5622  curr_field->data[0] = 0;
5623  }
5624 #else
5625  field.size = 1;
5626  make_field_entry (&field);
5627  curr_field->data[0] = COB_MODULE_PTR->decimal_point;
5628 #endif
5629  return curr_field;
5630 }
5631 
5632 cob_field *
5634 {
5635 #ifdef HAVE_LOCALECONV
5636  struct lconv *p;
5637  size_t size;
5638 #endif
5639  cob_field field;
5640 
5641  COB_FIELD_INIT (0, NULL, &const_alpha_attr);
5642  cob_set_exception (0);
5643 
5644 #ifdef HAVE_LOCALECONV
5645  p = localeconv ();
5646  size = strlen (p->decimal_point);
5647  if (size) {
5648  field.size = size;
5649  } else {
5650  field.size = 1;
5651  }
5652  make_field_entry (&field);
5653  if (size) {
5654  memcpy (curr_field->data, p->decimal_point, size);
5655  } else {
5656  curr_field->size = 0;
5657  curr_field->data[0] = 0;
5658  }
5659 #else
5660  field.size = 1;
5661  make_field_entry (&field);
5662  curr_field->data[0] = COB_MODULE_PTR->decimal_point;
5663 #endif
5664  return curr_field;
5665 }
5666 
5667 cob_field *
5669 {
5670 #ifdef HAVE_LOCALECONV
5671  struct lconv *p;
5672  size_t size;
5673 #endif
5674  cob_field field;
5675 
5676  COB_FIELD_INIT (0, NULL, &const_alpha_attr);
5677  cob_set_exception (0);
5678 
5679 #ifdef HAVE_LOCALECONV
5680  p = localeconv ();
5681  size = strlen (p->mon_thousands_sep);
5682  if (size) {
5683  field.size = size;
5684  } else {
5685  field.size = 1;
5686  }
5687  make_field_entry (&field);
5688  if (size) {
5689  memcpy (curr_field->data, p->mon_thousands_sep, size);
5690  } else {
5691  curr_field->size = 0;
5692  curr_field->data[0] = 0;
5693  }
5694 #else
5695  field.size = 1;
5696  make_field_entry (&field);
5697  curr_field->data[0] = COB_MODULE_PTR->decimal_point;
5698 #endif
5699  return curr_field;
5700 }
5701 
5702 cob_field *
5704 {
5705 #ifdef HAVE_LOCALECONV
5706  struct lconv *p;
5707  size_t size;
5708 #endif
5709  cob_field field;
5710 
5711  COB_FIELD_INIT (0, NULL, &const_alpha_attr);
5712  cob_set_exception (0);
5713 
5714 #ifdef HAVE_LOCALECONV
5715  p = localeconv ();
5716  size = strlen (p->thousands_sep);
5717  if (size) {
5718  field.size = size;
5719  } else {
5720  field.size = 1;
5721  }
5722  make_field_entry (&field);
5723  if (size) {
5724  memcpy (curr_field->data, p->thousands_sep, size);
5725  } else {
5726  curr_field->size = 0;
5727  curr_field->data[0] = 0;
5728  }
5729 #else
5730  field.size = 1;
5731  make_field_entry (&field);
5732  curr_field->data[0] = COB_MODULE_PTR->decimal_point;
5733 #endif
5734  return curr_field;
5735 }
5736 
5737 cob_field *
5739 {
5740 #ifdef HAVE_LOCALECONV
5741  struct lconv *p;
5742  size_t size;
5743 #endif
5744  cob_field field;
5745 
5746  COB_FIELD_INIT (0, NULL, &const_alpha_attr);
5747  cob_set_exception (0);
5748 
5749 #ifdef HAVE_LOCALECONV
5750  p = localeconv ();
5751  size = strlen (p->currency_symbol);
5752  if (size) {
5753  field.size = size;
5754  } else {
5755  field.size = 1;
5756  }
5757  make_field_entry (&field);
5758  if (size) {
5759  memcpy (curr_field->data, p->currency_symbol, size);
5760  } else {
5761  curr_field->size = 0;
5762  curr_field->data[0] = 0;
5763  }
5764 #else
5765  field.size = 1;
5766  make_field_entry (&field);
5767  curr_field->data[0] = COB_MODULE_PTR->currency_symbol;
5768 #endif
5769  return curr_field;
5770 }
5771 
5772 cob_field *
5774 {
5775  cob_alloc_set_field_int (cob_check_numval (srcfield, NULL, 0, 0));
5776  return curr_field;
5777 }
5778 
5779 cob_field *
5781 {
5782  cob_alloc_set_field_int (cob_check_numval (srcfield, currency, 1, 0));
5783  return curr_field;
5784 }
5785 
5786 cob_field *
5788 {
5790  return curr_field;
5791 }
5792 
5793 cob_field *
5795 {
5796  cob_uli_t expo;
5797  cob_field field;
5798 
5799  switch (COB_FIELD_TYPE (srcfield)) {
5800  case COB_TYPE_ALPHANUMERIC:
5801  case COB_TYPE_NATIONAL:
5802  COB_FIELD_INIT (COB_FIELD_SIZE (srcfield), NULL, &const_alpha_attr);
5803  make_field_entry (&field);
5804  break;
5805 
5808  COB_FIELD_INIT (COB_FIELD_DIGITS (srcfield), NULL, &const_alpha_attr);
5809  make_field_entry (&field);
5810  break;
5811 
5813  if (!COB_FIELD_HAVE_SIGN (srcfield)) {
5815  break;
5816  }
5817  if (COB_FIELD_REAL_BINARY (srcfield) ||
5818  !COB_FIELD_BINARY_TRUNC (srcfield)) {
5819  expo = (cob_uli_t)((COB_FIELD_SIZE (srcfield) * 8U) - 1U);
5820  mpz_ui_pow_ui (d1.value, 2UL, expo);
5821  mpz_neg (d1.value, d1.value);
5822  d1.scale = COB_FIELD_SCALE (srcfield);
5823  cob_alloc_field (&d1);
5824  (void)cob_decimal_get_field (&d1, curr_field, 0);
5825  break;
5826  }
5827  expo = (cob_uli_t)COB_FIELD_DIGITS (srcfield);
5828  mpz_ui_pow_ui (d1.value, 10UL, expo);
5829  mpz_sub_ui (d1.value, d1.value, 1UL);
5830  mpz_neg (d1.value, d1.value);
5831  d1.scale = COB_FIELD_SCALE (srcfield);
5832  cob_alloc_field (&d1);
5833  (void)cob_decimal_get_field (&d1, curr_field, 0);
5834  break;
5835 
5840  break;
5841 
5845  if (!COB_FIELD_HAVE_SIGN (srcfield)) {
5847  break;
5848  }
5849  expo = (cob_uli_t)COB_FIELD_DIGITS (srcfield);
5850  mpz_ui_pow_ui (d1.value, 10UL, expo);
5851  mpz_sub_ui (d1.value, d1.value, 1UL);
5852  mpz_neg (d1.value, d1.value);
5853  d1.scale = COB_FIELD_SCALE (srcfield);
5854  cob_alloc_field (&d1);
5855  (void)cob_decimal_get_field (&d1, curr_field, 0);
5856  break;
5857  default:
5860  break;
5861  }
5862  return curr_field;
5863 }
5864 
5865 cob_field *
5867 {
5868  cob_uli_t expo;
5869  size_t size;
5870  cob_field field;
5871 
5872  switch (COB_FIELD_TYPE (srcfield)) {
5873  case COB_TYPE_ALPHANUMERIC:
5874  case COB_TYPE_NATIONAL:
5875  size = COB_FIELD_SIZE (srcfield);
5876  COB_FIELD_INIT (size, NULL, &const_alpha_attr);
5877  make_field_entry (&field);
5878  memset (curr_field->data, 255, size);
5879  break;
5880 
5883  size = COB_FIELD_DIGITS (srcfield);
5884  COB_FIELD_INIT (size, NULL, &const_alpha_attr);
5885  make_field_entry (&field);
5886  memset (curr_field->data, 255, size);
5887  break;
5888 
5890  if (COB_FIELD_REAL_BINARY (srcfield) ||
5891  !COB_FIELD_BINARY_TRUNC (srcfield)) {
5892  if (!COB_FIELD_HAVE_SIGN (srcfield)) {
5893  expo = COB_FIELD_SIZE (srcfield) * 8U;
5894  } else {
5895  expo = (COB_FIELD_SIZE (srcfield) * 8U) - 1U;
5896  }
5897  mpz_ui_pow_ui (d1.value, 2UL, expo);
5898  mpz_sub_ui (d1.value, d1.value, 1UL);
5899  d1.scale = COB_FIELD_SCALE (srcfield);
5900  cob_alloc_field (&d1);
5901  (void)cob_decimal_get_field (&d1, curr_field, 0);
5902  break;
5903  }
5904  expo = (cob_uli_t)COB_FIELD_DIGITS (srcfield);
5905  mpz_ui_pow_ui (d1.value, 10UL, expo);
5906  mpz_sub_ui (d1.value, d1.value, 1UL);
5907  d1.scale = COB_FIELD_SCALE (srcfield);
5908  cob_alloc_field (&d1);
5909  (void)cob_decimal_get_field (&d1, curr_field, 0);
5910  break;
5911 
5916  break;
5917 
5921  expo = (cob_uli_t)COB_FIELD_DIGITS (srcfield);
5922  mpz_ui_pow_ui (d1.value, 10UL, expo);
5923  mpz_sub_ui (d1.value, d1.value, 1UL);
5924  d1.scale = COB_FIELD_SCALE (srcfield);
5925  cob_alloc_field (&d1);
5926  (void)cob_decimal_get_field (&d1, curr_field, 0);
5927  break;
5928  default:
5931  break;
5932  }
5933  return curr_field;
5934 }
5935 
5936 cob_field *
5937 cob_intr_locale_compare (const int params, ...)
5938 {
5939  cob_field *f1;
5940  cob_field *f2;
5941  cob_field *locale_field;
5942 #ifdef HAVE_STRCOLL
5943  unsigned char *p;
5944  unsigned char *p1;
5945  unsigned char *p2;
5946  char *deflocale;
5947  size_t size;
5948  size_t size2;
5949  int ret;
5950 #endif
5951  cob_field field;
5952  va_list args;
5953 
5954  cob_set_exception (0);
5955  va_start (args, params);
5956  f1 = va_arg (args, cob_field *);
5957  f2 = va_arg (args, cob_field *);
5958  if (params > 2) {
5959  locale_field = va_arg (args, cob_field *);
5960  } else {
5961  locale_field = NULL;
5962  }
5963  va_end (args);
5964 
5965  COB_FIELD_INIT (1, NULL, &const_alpha_attr);
5966  make_field_entry (&field);
5967 
5968 #ifdef HAVE_STRCOLL
5969  deflocale = NULL;
5970 
5971  size = f1->size;
5972  size2 = size;
5973  for (p = f1->data + size - 1U; p != f1->data; --p) {
5974  if (*p != ' ') {
5975  break;
5976  }
5977  size2--;
5978  }
5979  p1 = cob_malloc (size2 + 1U);
5980  memcpy (p1, f1->data, size2);
5981 
5982  size = f2->size;
5983  size2 = size;
5984  for (p = f2->data + size - 1U; p != f2->data; --p) {
5985  if (*p != ' ') {
5986  break;
5987  }
5988  size2--;
5989  }
5990  p2 = cob_malloc (size2 + 1U);
5991  memcpy (p2, f2->data, size2);
5992 
5993  if (locale_field) {
5994  if (!locale_field->size) {
5995  goto derror;
5996  }
5997 #ifdef HAVE_SETLOCALE
5998  deflocale = cob_malloc (locale_field->size + 1U);
5999  cob_field_to_string (locale_field, deflocale,
6000  (size_t)(locale_field->size + 1U));
6001  (void) setlocale (LC_COLLATE, deflocale);
6002 #else
6003  goto derror;
6004 #endif
6005  }
6006 
6007  ret = strcoll ((char *)p1, (char *)p2);
6008  if (ret < 0) {
6009  curr_field->data[0] = '<';
6010  } else if (ret > 0) {
6011  curr_field->data[0] = '>';
6012  } else {
6013  curr_field->data[0] = '=';
6014  }
6015  cob_free (p1);
6016  cob_free (p2);
6017 
6018 #ifdef HAVE_SETLOCALE
6019  if (deflocale) {
6020  (void) setlocale (LC_ALL, cobglobptr->cob_locale);
6021  cob_free (deflocale);
6022  }
6023 #endif
6024 
6025  return curr_field;
6026 derror:
6027 #endif
6028  curr_field->data[0] = ' ';
6030 
6031  return curr_field;
6032 }
6033 
6034 cob_field *
6035 cob_intr_formatted_date (const int offset, const int length,
6036  cob_field *format_field, cob_field *days_field)
6037 {
6038  cob_field field;
6039  size_t field_length =
6040  num_leading_nonspace ((char *) format_field->data);
6041  char format_str[COB_DATESTR_LEN] = { '\0' };
6042  int days;
6043  struct date_format format;
6044  char buff[COB_DATESTR_LEN] = { '\0' };
6045 
6046  memcpy (format_str, format_field->data, field_length);
6047 
6048  COB_FIELD_INIT (field_length, NULL, &const_alpha_attr);
6049  make_field_entry (&field);
6050 
6051  cob_set_exception (0);
6052  days = cob_get_int (days_field);
6053 
6054  if (!valid_day_and_format (days, format_str)) {
6055  goto invalid_args;
6056  }
6057 
6058  format = parse_date_format_string (format_str);
6059  format_date (format, days, buff);
6060 
6061  memcpy (curr_field->data, buff, field_length);
6062  goto end_of_func;
6063 
6064  invalid_args:
6066  memset (curr_field->data, ' ', strlen (format_str));
6067 
6068  end_of_func:
6069  if (unlikely (offset > 0)) {
6070  calc_ref_mod (curr_field, offset, length);
6071  }
6072  return curr_field;
6073 }
6074 
6075 cob_field *
6076 cob_intr_formatted_time (const int offset, const int length,
6077  const int params, ...)
6078 {
6079  va_list args;
6081  cob_field *time_field;
6082  cob_field *offset_time_field;
6083  cob_field field;
6084  size_t field_length;
6085  char buff[COB_TIMESTR_LEN] = { '\0' };
6086  char format_str[COB_TIMESTR_LEN] = { '\0' };
6087  int whole_seconds;
6088  cob_decimal *fractional_seconds;
6089  int use_system_offset;
6090  int offset_time;
6091  int *offset_time_ptr;
6092  struct time_format format;
6093 
6094  if (!(params == 3 || params == 4)) {
6095  COB_FIELD_INIT (0, NULL, &const_alpha_attr);
6096  make_field_entry (&field);
6097  goto invalid_args;
6098  }
6099 
6100  /* Get args */
6101  va_start (args, params);
6102 
6103  format_field = va_arg (args, cob_field *);
6104  time_field = va_arg (args, cob_field *);
6105  if (params == 4) {
6106  offset_time_field = va_arg (args, cob_field *);
6107  } else {
6108  offset_time_field = NULL;
6109  }
6110  use_system_offset = va_arg (args, int);
6111 
6112  va_end (args);
6113 
6114  /* Initialise buffers */
6115  field_length = num_leading_nonspace ((char *) format_field->data);
6116  memcpy (format_str, format_field->data, field_length);
6117 
6118  COB_FIELD_INIT (field_length, NULL, &const_alpha_attr);
6119  make_field_entry (&field);
6120 
6121  cob_set_exception (0);
6122 
6123  /* Extract and validate the times and time format */
6124 
6125  whole_seconds = cob_get_int (time_field);
6126  if (!valid_time (whole_seconds)) {
6127  goto invalid_args;
6128  }
6129 
6130  fractional_seconds = &d2;
6131  get_fractional_seconds (time_field, fractional_seconds);
6132 
6133  if (!cob_valid_time_format (format_str, COB_MODULE_PTR->decimal_point)) {
6134  goto invalid_args;
6135  }
6136  format = parse_time_format_string (format_str);
6137 
6138  if (use_system_offset) {
6139  offset_time_ptr = get_system_offset_time_ptr (&offset_time);
6140  } else {
6141  if (try_get_valid_offset_time (format, offset_time_field,
6142  &offset_time)) {
6143  goto invalid_args;
6144  } else {
6145  offset_time_ptr = &offset_time;
6146  }
6147  }
6148 
6149  format_time (format, whole_seconds, fractional_seconds, offset_time_ptr,
6150  buff);
6151 
6152  memcpy (curr_field->data, buff, field_length);
6153  goto end_of_func;
6154 
6155  invalid_args:
6157  if (format_str != NULL) {
6158  memset (curr_field->data, ' ', strlen (format_str));
6159  }
6160 
6161  end_of_func:
6162  if (unlikely (offset > 0)) {
6163  calc_ref_mod (curr_field, offset, length);
6164  }
6165  return curr_field;
6166 }
6167 
6168 cob_field *
6169 cob_intr_formatted_datetime (const int offset, const int length,
6170  const int params, ...)
6171 {
6172  va_list args;
6173  cob_field *fmt_field;
6174  cob_field *days_field;
6175  cob_field *time_field;
6176  cob_field *offset_time_field;
6177  cob_field field;
6178  size_t field_length;
6179  char fmt_str[COB_DATETIMESTR_LEN] = { '\0' };
6180  char date_fmt_str[COB_DATESTR_LEN] = { '\0' };
6181  char time_fmt_str[COB_TIMESTR_LEN] = { '\0' };
6182  struct date_format date_fmt;
6183  struct time_format time_fmt;
6184  int days;
6185  int whole_seconds;
6186  cob_decimal *fractional_seconds;
6187  int use_system_offset;
6188  int offset_time;
6189  int *offset_time_ptr;
6190  char buff[COB_DATETIMESTR_LEN] = { '\0' };
6191 
6192  if (!(params == 4 || params == 5)) {
6193  COB_FIELD_INIT (0, NULL, &const_alpha_attr);
6194  make_field_entry (&field);
6195  goto invalid_args;
6196  }
6197 
6198  /* Get arguments */
6199  va_start (args, params);
6200 
6201  fmt_field = va_arg (args, cob_field *);
6202  days_field = va_arg (args, cob_field *);
6203  time_field = va_arg (args, cob_field *);
6204  if (params == 5) {
6205  offset_time_field = va_arg (args, cob_field *);
6206  } else {
6207  offset_time_field = NULL;
6208  }
6209  use_system_offset = va_arg (args, int);
6210 
6211  va_end (args);
6212 
6213  field_length = num_leading_nonspace ((char *) fmt_field->data);
6214  memcpy (fmt_str, fmt_field->data, field_length);
6215 
6216  COB_FIELD_INIT (field_length, NULL, &const_alpha_attr);
6217  make_field_entry (&field);
6218 
6219  cob_set_exception (0);
6220 
6221  /* Validate the formats, dates and times */
6222  if (!cob_valid_datetime_format (fmt_str, COB_MODULE_PTR->decimal_point)) {
6223  goto invalid_args;
6224  }
6225 
6226  days = cob_get_int (days_field);
6227  whole_seconds = cob_get_int (time_field);
6228 
6229  if (!valid_integer_date (days) || !valid_time (whole_seconds)) {
6230  goto invalid_args;
6231  }
6232 
6233  split_around_t (fmt_str, date_fmt_str, time_fmt_str);
6234 
6235  time_fmt = parse_time_format_string (time_fmt_str);
6236  if (use_system_offset) {
6237  offset_time_ptr = get_system_offset_time_ptr (&offset_time);
6238  } else {
6239  if (try_get_valid_offset_time (time_fmt, offset_time_field,
6240  &offset_time)) {
6241  goto invalid_args;
6242  } else {
6243  offset_time_ptr = &offset_time;
6244  }
6245  }
6246  date_fmt = parse_date_format_string (date_fmt_str);
6247 
6248  /* Format */
6249 
6250  fractional_seconds = &d1;
6251  get_fractional_seconds (time_field, fractional_seconds);
6252 
6253  format_datetime (date_fmt, time_fmt, days, whole_seconds,
6254  fractional_seconds, offset_time_ptr, buff);
6255 
6256  memcpy (curr_field->data, buff, (size_t) field_length);
6257  goto end_of_func;
6258 
6259  invalid_args:
6261  if (fmt_str != NULL) {
6262  memset (curr_field->data, ' ', strlen (fmt_str));
6263  }
6264 
6265  end_of_func:
6266  if (unlikely (offset > 0)) {
6267  calc_ref_mod (curr_field, offset, length);
6268  }
6269  return curr_field;
6270 }
6271 
6272 cob_field *
6274 cob_field *datetime_field)
6275 {
6276  char *datetime_format_str = (char *)format_field->data;
6277  char date_format_str[COB_DATESTR_LEN] = { '\0' };
6278  char time_format_str[COB_TIMESTR_LEN] = { '\0' };
6279  int date_present;
6280  int time_present;
6281  char *formatted_datetime = (char *)datetime_field->data;
6282  char formatted_date[COB_DATESTR_LEN] = { '\0' };
6283  char formatted_time[COB_TIMESTR_LEN] = { '\0' };
6284  int time_part_offset;
6285  int error_pos;
6286 
6287  cob_set_exception (0);
6288 
6289  /* Check whether date or time is present. */
6290  if (cob_valid_date_format (datetime_format_str)) {
6291  date_present = 1;
6292  time_present = 0;
6293  } else if (cob_valid_time_format (datetime_format_str,
6294  COB_MODULE_PTR->decimal_point)) {
6295  date_present = 0;
6296  time_present = 1;
6297  } else if (cob_valid_datetime_format (datetime_format_str,
6298  COB_MODULE_PTR->decimal_point)) {
6299  date_present = 1;
6300  time_present = 1;
6301  } else {
6302  goto invalid_args;
6303  }
6304 
6305  /* Move date/time to respective variables */
6306  if (date_present && time_present) {
6307  split_around_t (datetime_format_str, date_format_str, time_format_str);
6308  } else if (date_present) {
6309  strncpy (date_format_str, datetime_format_str, COB_DATESTR_MAX);
6310  } else { /* time_present */
6311  strncpy (time_format_str, datetime_format_str, COB_TIMESTR_MAX);
6312  }
6313 
6314  if (date_present && time_present) {
6315  split_around_t (formatted_datetime, formatted_date, formatted_time);
6316  } else if (date_present) {
6317  strncpy (formatted_date, formatted_datetime, COB_DATESTR_MAX);
6318  } else { /* time_present */
6319  strncpy (formatted_time, formatted_datetime, COB_TIMESTR_MAX);
6320  }
6321  /* silence warnings */
6322  formatted_date[COB_DATESTR_MAX] = formatted_time[COB_TIMESTR_MAX] = 0;
6323 
6324  /* Set time offset */
6325  if (date_present) {
6326  time_part_offset = strlen (formatted_date) + 1;
6327  } else {
6328  time_part_offset = 0;
6329  }
6330 
6331  /* Parse and validate the formatted date/time */
6332  if (date_present) {
6333  error_pos = test_formatted_date (parse_date_format_string (date_format_str),
6334  formatted_date, !time_present);
6335  if (error_pos != 0) {
6336  cob_alloc_set_field_uint (error_pos);
6337  goto end_of_func;
6338  }
6339  }
6340  if (time_present) {
6341  error_pos = test_formatted_time (parse_time_format_string (time_format_str),
6342  formatted_time, COB_MODULE_PTR->decimal_point);
6343  if (error_pos != 0) {
6344  cob_alloc_set_field_uint (time_part_offset + error_pos);
6345  goto end_of_func;
6346  }
6347  }
6348 
6350  goto end_of_func;
6351 
6352  invalid_args:
6355 
6356  end_of_func:
6357  return curr_field;
6358 }
6359 
6360 cob_field *
6362  cob_field *date_field)
6363 {
6364  char *format_field_data = (char *) format_field->data;
6365  char format_str[COB_DATESTR_LEN] = { '\0' };
6366  char *date_field_data = (char *) date_field->data;
6367  char date_str[COB_DATESTR_LEN] = { '\0' };
6368  int is_date;
6369  struct date_format date_fmt;
6370 
6371  cob_set_exception (0);
6372 
6373  /* Get date format string and parse it */
6374  is_date = cob_valid_date_format (format_field_data);
6375  if (is_date) {
6376  strncpy (format_str, format_field_data, COB_DATESTR_MAX);
6377  } else if (cob_valid_datetime_format (format_field_data,
6378  COB_MODULE_PTR->decimal_point)) { /* Datetime */
6379  split_around_t (format_field_data, format_str, NULL);
6380  } else { /* Invalid format string */
6381  goto invalid_args;
6382  }
6383  date_fmt = parse_date_format_string (format_str);
6384 
6385  /* Get formatted date and validate it */
6386  if (is_date) {
6387  strncpy (date_str, date_field_data, COB_DATESTR_MAX);
6388  } else { /* Datetime */
6389  split_around_t (date_field_data, date_str, NULL);
6390  }
6391  if (test_formatted_date (date_fmt, date_str, 1) != 0) {
6392  goto invalid_args;
6393  }
6394 
6395  cob_alloc_set_field_uint (integer_of_formatted_date (date_fmt, date_str));
6396  goto end_of_func;
6397 
6398  invalid_args:
6401 
6402  end_of_func:
6403  return curr_field;
6404 }
6405 
6406 cob_field *
6407 cob_intr_formatted_current_date (const int offset, const int length,
6409 {
6410  cob_field field;
6411  size_t field_length =
6412  num_leading_nonspace ((char *) format_field->data);
6413  char format_str[COB_DATETIMESTR_LEN] = { '\0' };
6414  char date_format_str[COB_DATESTR_LEN] = { '\0' };
6415  char time_format_str[COB_TIMESTR_LEN] = { '\0' };
6416  struct date_format date_fmt;
6417  struct time_format time_fmt;
6418  char formatted_date[COB_DATETIMESTR_LEN] = { '\0' };
6419 
6420  strncpy (format_str, (char *) format_field->data, field_length);
6421 
6422  COB_FIELD_INIT (field_length, NULL, &const_alpha_attr);
6423  make_field_entry (&field);
6424 
6425  cob_set_exception (0);
6426 
6427  /* Validate format */
6428  if (!cob_valid_datetime_format (format_str, COB_MODULE_PTR->decimal_point)) {
6430  memset (curr_field->data, ' ', field_length);
6431  goto end_of_func;
6432  }
6433 
6434  /* Parse format */
6435  split_around_t (format_str, date_format_str, time_format_str);
6436  date_fmt = parse_date_format_string (date_format_str);
6437  time_fmt = parse_time_format_string (time_format_str);
6438 
6439  /* Format current date */
6440  format_current_date (date_fmt, time_fmt, formatted_date);
6441  memcpy (curr_field->data, formatted_date, field_length);
6442 
6443  end_of_func:
6444  if (unlikely (offset > 0)) {
6445  calc_ref_mod (curr_field, offset, length);
6446  }
6447  return curr_field;
6448 }
6449 
6450 /* RXWRXW - To be implemented */
6451 
6452 cob_field *
6454 {
6455  COB_UNUSED (f1);
6456  COB_UNUSED (f2);
6457 
6459 }
6460 
6461 cob_field *
6463 {
6464  COB_UNUSED (srcfield);
6465 
6467 }
6468 
6469 cob_field *
6470 cob_intr_display_of (const int offset, const int length,
6471  const int params, ...)
6472 {
6473  COB_UNUSED (offset);
6474  COB_UNUSED (length);
6475  COB_UNUSED (params);
6476 
6478 }
6479 
6480 cob_field *
6482 {
6484 }
6485 
6486 cob_field *
6488 {
6490 }
6491 
6492 cob_field *
6494 {
6495  COB_UNUSED (srcfield);
6496 
6498 }
6499 
6500 cob_field *
6501 cob_intr_national_of (const int offset, const int length, const int params, ...)
6502 {
6503  COB_UNUSED (offset);
6504  COB_UNUSED (length);
6505  COB_UNUSED (params);
6506 
6508 }
6509 
6510 cob_field *
6511 cob_intr_standard_compare (const int params, ...)
6512 {
6513  COB_UNUSED (params);
6514 
6516 }
6517 
6518 /* Initialization/exit routines */
6519 
6520 void
6522 {
6523  struct calc_struct *calc_temp;
6524  cob_u32_t i;
6525 
6526  mpf_clear (cob_log_half);
6527  mpf_clear (cob_sqrt_two);
6528  mpf_clear (cob_pi);
6529 
6530  mpf_clear (cob_mpft_get);
6531  mpf_clear (cob_mpft2);
6532  mpf_clear (cob_mpft);
6533 
6534  mpz_clear (d5.value);
6535  mpz_clear (d4.value);
6536  mpz_clear (d3.value);
6537  mpz_clear (d2.value);
6538  mpz_clear (d1.value);
6539 
6540  mpz_clear (cob_mpzt);
6541  mpz_clear (cob_mexp);
6542 
6543  if (calc_base) {
6544  calc_temp = calc_base;
6545  for (i = 0; i < COB_DEPTH_LEVEL; ++i, ++calc_temp) {
6546  if (calc_temp->calc_field.data) {
6547  cob_free (calc_temp->calc_field.data);
6548  }
6549  }
6550  cob_free (calc_base);
6551  }
6552 }
6553 
6554 void
6556 {
6557  struct calc_struct *calc_temp;
6558  cob_u32_t i;
6559 
6560  cobglobptr = lptr;
6561 
6562  move_field = NULL;
6563  curr_entry = 0;
6564  curr_field = NULL;
6565  calc_base = cob_malloc (COB_DEPTH_LEVEL * sizeof(struct calc_struct));
6566  calc_temp = calc_base;
6567  for (i = 0; i < COB_DEPTH_LEVEL; ++i, ++calc_temp) {
6568  calc_temp->calc_field.data = cob_malloc ((size_t)256);
6569  calc_temp->calc_field.size = 256;
6570  calc_temp->calc_size = 256;
6571  }
6572 
6573  mpz_init2 (cob_mexp, COB_MPZ_DEF);
6574  mpz_init2 (cob_mpzt, COB_MPZ_DEF);
6575  mpz_init2 (d1.value, 1536UL);
6576  d1.scale = 0;
6577  mpz_init2 (d2.value, 1536UL);
6578  d2.scale = 0;
6579  mpz_init2 (d3.value, 1536UL);
6580  d3.scale = 0;
6581  mpz_init2 (d4.value, 1536UL);
6582  d4.scale = 0;
6583  mpz_init2 (d5.value, 1536UL);
6584  d5.scale = 0;
6585 
6586  mpf_init2 (cob_mpft, COB_MPF_PREC);
6587  mpf_init2 (cob_mpft2, COB_MPF_PREC);
6588  mpf_init2 (cob_mpft_get, COB_MPF_PREC);
6589 
6590  mpf_init2 (cob_pi, COB_PI_LEN);
6591  mpf_set_str (cob_pi, cob_pi_str, 10);
6592 
6593  mpf_init2 (cob_sqrt_two, COB_SQRT_TWO_LEN);
6594  mpf_set_str (cob_sqrt_two, cob_sqrt_two_str, 10);
6595 
6596  mpf_init2 (cob_log_half, COB_LOG_HALF_LEN);
6597  mpf_set_str (cob_log_half, cob_log_half_str, 10);
6598 }
6599 
6600 #undef COB_DATETIMESTR_LEN
6601 #undef COB_TIMESTR_LEN
6602 #undef COB_DATESTR_LEN
static void make_field_entry(cob_field *f)
Definition: intrinsic.c:440
#define COB_DECIMAL_NAN
Definition: coblocal.h:80
cob_field * cob_intr_log10(cob_field *srcfield)
Definition: intrinsic.c:4383
static void get_min_and_max_of_args(const int num_args, va_list args, cob_field **min, cob_field **max)
Definition: intrinsic.c:1543
void cob_free(void *mptr)
Definition: common.c:1284
cob_field * cob_intr_integer_of_day(cob_field *srcfield)
Definition: intrinsic.c:4161
static cob_decimal d2
Definition: intrinsic.c:80
cob_field * cob_intr_fraction_part(cob_field *srcfield)
Definition: intrinsic.c:3532
static int rest_is_z(const char *str)
Definition: intrinsic.c:2194
unsigned int cob_orig_line
Definition: common.h:1206
#define COB_TYPE_NATIONAL_EDITED
Definition: common.h:626
cob_field * cob_intr_concatenate(const int offset, const int length, const int params,...)
Definition: intrinsic.c:3723
static cob_decimal d3
Definition: intrinsic.c:81
cob_field * cob_intr_reverse(const int offset, const int length, cob_field *srcfield)
Definition: intrinsic.c:3593
#define COB_FERROR_CODEGEN
Definition: common.h:693
static void cob_alloc_set_field_int(const int val)
Definition: intrinsic.c:533
cob_field * cob_intr_present_value(const int params,...)
Definition: intrinsic.c:5113
#define COB_FIELD_SCALE(f)
Definition: common.h:664
cob_field * cob_intr_module_source(void)
Definition: intrinsic.c:3688
int decimal_places
Definition: intrinsic.c:1957
cob_field * cob_intr_integer_of_formatted_date(cob_field *format_field, cob_field *date_field)
Definition: intrinsic.c:6361
cob_file * cob_error_file
Definition: common.h:1187
int utc_offset
Definition: coblocal.h:272
static cob_field * move_field
Definition: intrinsic.c:77
void cob_decimal_mul(cob_decimal *, cob_decimal *)
Definition: numeric.c:1891
static mpz_t cob_mpzt
Definition: intrinsic.c:86
#define cob_u32_t
Definition: common.h:31
static const int leap_days[]
Definition: intrinsic.c:111
static int get_day_of_week(const int day_num)
Definition: intrinsic.c:2045
cob_field * cob_intr_cos(cob_field *srcfield)
Definition: intrinsic.c:4513
cob_field * cob_intr_year_to_yyyy(const int params,...)
Definition: intrinsic.c:5151
cob_field * cob_intr_mod(cob_field *srcfield1, cob_field *srcfield2)
Definition: intrinsic.c:4992
static void cob_mpf_acos(mpf_t dst_val, const mpf_t src_val)
Definition: intrinsic.c:1243
cob_field * cob_intr_substitute_case(const int offset, const int length, const int params,...)
Definition: intrinsic.c:3776
cob_field * cob_intr_variance(const int num_args,...)
Definition: intrinsic.c:5078
static int num_leading_nonspace(const char *str)
Definition: intrinsic.c:2007
static int test_date_end(const struct date_format format, const char *date, const int year, int *offset)
Definition: intrinsic.c:2674
static size_t get_substituted_size(cob_field *original, cob_field **matches, cob_field **reps, const int numreps, int(*cmp_func)(const void *, const void *, size_t))
Definition: intrinsic.c:1289
#define COB_TYPE_NUMERIC_PACKED
Definition: common.h:609
cob_field * cob_intr_integer(cob_field *srcfield)
Definition: intrinsic.c:3487
static int valid_integer_date(const int days)
Definition: intrinsic.c:1788
static cob_u32_t integer_of_date(const int, const int, const int)
Definition: intrinsic.c:1922
static void get_interval_and_current_year_from_args(const int num_args, va_list args, int *const interval, int *const current_year)
Definition: intrinsic.c:1624
static void cob_alloc_set_field_uint(const cob_u32_t val)
Definition: intrinsic.c:552
int day_of_month
Definition: coblocal.h:265
static int test_z_presence(const char *time, int *offset)
Definition: intrinsic.c:2793
cob_field * cob_intr_asin(cob_field *srcfield)
Definition: intrinsic.c:4455
cob_field * cob_intr_exception_statement(void)
Definition: intrinsic.c:3920
#define COB_FIELD_IS_NUMERIC(f)
Definition: common.h:674
void cob_move(cob_field *, cob_field *)
Definition: move.c:1170
cob_field * cob_intr_formatted_date(const int offset, const int length, cob_field *format_field, cob_field *days_field)
Definition: intrinsic.c:6035
static void format_datetime(const struct date_format date_fmt, const struct time_format time_fmt, const int days, const int whole_seconds, cob_decimal *fractional_seconds, int *offset_time, char *buff)
Definition: intrinsic.c:2929
cob_field * cob_intr_atan(cob_field *srcfield)
Definition: intrinsic.c:4491
enum formatted_time_extra extra
Definition: intrinsic.c:1958
static const int leap_month_days[]
Definition: intrinsic.c:115
static void date_of_integer(int days, int *year, int *month, int *day)
Definition: intrinsic.c:1862
#define COB_TYPE_ALPHANUMERIC
Definition: common.h:621
cob_field * cob_intr_pi(void)
Definition: intrinsic.c:4274
static cob_u32_t days_up_to_year(const int year)
Definition: intrinsic.c:1909
static void split_around_t(const char *str, char *first, char *second)
Definition: intrinsic.c:2384
cob_field * cob_intr_range(const int params,...)
Definition: intrinsic.c:4998
static const char cob_log_half_str[]
Definition: intrinsic.c:405
static cob_u32_t integer_of_ddd(const int year, const char *final_part)
Definition: intrinsic.c:2878
static void cob_mpf_tan(mpf_t dst_val, const mpf_t src_val)
Definition: intrinsic.c:1113
void cob_decimal_pow(cob_decimal *pd1, cob_decimal *pd2)
Definition: intrinsic.c:2990
static cob_u32_t integer_of_day(const int year, const int days)
Definition: intrinsic.c:1939
#define COB_FIELD_TYPE(f)
Definition: common.h:662
static const cob_field_attr const_alpha_attr
Definition: intrinsic.c:73
static cob_field * substitute(const int offset, const int length, const int params, int(*cmp_func)(const void *, const void *, size_t), va_list args)
Definition: intrinsic.c:1380
cob_field * cob_intr_date_of_integer(cob_field *srcdays)
Definition: intrinsic.c:4067
cob_field * cob_intr_day_to_yyyyddd(const int params,...)
Definition: intrinsic.c:5254
static int test_week(const char *date, const int year, int *offset)
Definition: intrinsic.c:2642
static COB_INLINE COB_A_INLINE int in_range(const int min, const int max, const int val)
Definition: intrinsic.c:1782
static mpf_t cob_mpft_get
Definition: intrinsic.c:90
cob_field * cob_intr_ord_max(const int params,...)
Definition: intrinsic.c:4809
cob_field * cob_intr_min(const int params,...)
Definition: intrinsic.c:4835
#define COB_DATETIMESTR_LEN
Definition: intrinsic.c:127
int cob_valid_time_format(const char *format, const char decimal_point)
Definition: intrinsic.c:3366
static int get_iso_week_one(const int day_num, const int day_of_year)
Definition: intrinsic.c:2051
cob_field * cob_intr_seconds_past_midnight(void)
Definition: intrinsic.c:5306
static unsigned int int_pow(const unsigned int base, unsigned int power)
Definition: intrinsic.c:2214
cob_field f2
Definition: cobxref.c.l.h:55
cob_field * cob_intr_char_national(cob_field *srcfield)
Definition: intrinsic.c:6462
cob_field * cob_intr_mon_thousands_sep(void)
Definition: intrinsic.c:5668
#define COB_SQRT_TWO_LEN
Definition: intrinsic.c:426
void cob_exit_intrinsic(void)
Definition: intrinsic.c:6521
static void cob_alloc_set_field_str(char *str, const int offset, const int length)
Definition: intrinsic.c:1749
int with_hyphens
Definition: intrinsic.c:2127
#define COB_SMALL_BUFF
Definition: common.h:540
cob_field * cob_intr_tan(cob_field *srcfield)
Definition: intrinsic.c:4545
#define COB_FERROR_FUNCTION
Definition: common.h:702
#define COB_INLINE
Definition: common.h:354
cob_field * cob_intr_display_of(const int offset, const int length, const int params,...)
Definition: intrinsic.c:6470
static int test_year(const char *date, int *offset, int *state)
Definition: intrinsic.c:2523
static int decimal_places_for_seconds(const char *str, const ptrdiff_t point_pos)
Definition: intrinsic.c:2181
int cob_ctoi(const char)
Definition: common.c:2651
void cob_decimal_set_field(cob_decimal *, cob_field *)
Definition: numeric.c:1612
cob_field * cob_intr_date_to_yyyymmdd(const int params,...)
Definition: intrinsic.c:5208
static int test_decade(const char *date, int *offset, int *state)
Definition: intrinsic.c:2501
const char * cob_orig_paragraph
Definition: common.h:1192
static int valid_day_of_year(const int year, const int day)
Definition: intrinsic.c:1806
cob_field * cob_intr_lower_case(const int offset, const int length, cob_field *srcfield)
Definition: intrinsic.c:3576
cob_field * cob_intr_sin(cob_field *srcfield)
Definition: intrinsic.c:4529
cob_field calc_field
Definition: intrinsic.c:99
static cob_u32_t curr_entry
Definition: intrinsic.c:106
static void cob_mpf_log(mpf_t dst_val, const mpf_t src_val)
Definition: intrinsic.c:931
#define COB_ATTR_INIT(u, v, x, y, z)
Definition: coblocal.h:150
static int test_formatted_date(const struct date_format format, const char *date, const int end_of_string)
Definition: intrinsic.c:2713
void cob_get_indirect_field(cob_field *f)
Definition: intrinsic.c:3096
static int valid_day_of_month(const int year, const int month, const int day)
Definition: intrinsic.c:1812
cob_field * cob_intr_log(cob_field *srcfield)
Definition: intrinsic.c:4352
static int leap_year(const int year)
Definition: intrinsic.c:470
static cob_u32_t integer_of_mmdd(const struct date_format format, const int year, const char *final_part)
Definition: intrinsic.c:2863
static cob_field * numval(cob_field *srcfield, cob_field *currency, const enum numval_type type)
Definition: intrinsic.c:1456
#define COB_SMALL_MAX
Definition: common.h:546
static int valid_time(const int seconds_from_midnight)
Definition: intrinsic.c:1836
unsigned char * data
Definition: common.h:952
cob_field * cob_intr_module_caller_id(void)
Definition: intrinsic.c:3653
cob_field * cob_intr_sum(const int params,...)
Definition: intrinsic.c:4759
static int rest_is_offset_format(const char *str, const int with_colon)
Definition: intrinsic.c:2200
static mpz_t cob_mexp
Definition: intrinsic.c:85
#define COB_MPZ_DEF
Definition: coblocal.h:86
static void cob_alloc_field(cob_decimal *d)
Definition: intrinsic.c:565
days_format
Definition: intrinsic.c:2119
static void cob_mpf_asin(mpf_t dst_val, const mpf_t src_val)
Definition: intrinsic.c:1196
cob_field * cob_intr_module_formatted_date(void)
Definition: intrinsic.c:3674
static void cob_mpf_atan(mpf_t dst_val, const mpf_t src_val)
Definition: intrinsic.c:1132
int cob_get_switch(const int n)
Definition: common.c:2296
static mpf_t cob_mpft2
Definition: intrinsic.c:89
int day_of_week
Definition: coblocal.h:266
static int test_char(const char wanted, const char *str, int *offset)
Definition: intrinsic.c:2461
#define COB_PI_LEN
Definition: intrinsic.c:425
#define COB_LOG_HALF_LEN
Definition: intrinsic.c:427
static mpf_t cob_mpft
Definition: intrinsic.c:88
cob_field * cob_intr_substitute(const int offset, const int length, const int params,...)
Definition: intrinsic.c:3762
#define COB_FIELD_IS_NATIONAL(f)
Definition: common.h:677
cob_field * cob_intr_locale_compare(const int params,...)
Definition: intrinsic.c:5937
unsigned char * file_status
Definition: common.h:1113
#define COB_FLAG_HAVE_SIGN
Definition: common.h:630
#define COB_MAX_DIGITS
Definition: common.h:562
#define cob_u8_t
Definition: common.h:27
cob_field * cob_intr_binop(cob_field *f1, const int op, cob_field *f2)
Definition: intrinsic.c:3429
cob_field * cob_intr_ord_min(const int params,...)
Definition: intrinsic.c:4783
static cob_u32_t integer_of_formatted_date(const struct date_format format, const char *formatted_date)
Definition: intrinsic.c:2908
cob_field * cob_intr_e(void)
Definition: intrinsic.c:4262
static cob_field * cob_mod_or_rem(cob_field *f1, cob_field *f2, const int func_is_rem)
Definition: intrinsic.c:624
int cob_get_int(cob_field *)
Definition: move.c:1626
#define SECONDS_IN_DAY
Definition: intrinsic.c:1833
cob_field * cob_intr_integer_of_boolean(cob_field *srcfield)
Definition: intrinsic.c:6493
#define COB_TYPE_NATIONAL
Definition: common.h:625
cob_field * cob_intr_midrange(const int params,...)
Definition: intrinsic.c:4883
#define cob_uli_t
Definition: common.h:33
cob_field * cob_intr_abs(cob_field *srcfield)
Definition: intrinsic.c:4414
cob_field * cob_intr_module_time(void)
Definition: intrinsic.c:3625
void cob_field_to_string(const cob_field *, void *, const size_t)
Definition: common.c:1492
static int test_formatted_time(const struct time_format format, const char *time, const char decimal_point)
Definition: intrinsic.c:2842
static void seconds_from_formatted_time(const struct time_format format, const char *str, cob_decimal *seconds_decimal)
Definition: intrinsic.c:1963
static int valid_month(const int month)
Definition: intrinsic.c:1800
static cob_decimal d5
Definition: intrinsic.c:83
static void format_field(cob_screen *s)
Definition: screenio.c:1025
static int valid_decimal_time(cob_decimal *seconds_from_midnight)
Definition: intrinsic.c:1843
#define RETURN_IF_NOT_ZERO(expr)
Definition: intrinsic.c:429
void cob_put_indirect_field(cob_field *f)
Definition: intrinsic.c:3088
static void calc_ref_mod(cob_field *f, const int offset, const int length)
Definition: intrinsic.c:488
void cob_fatal_error(const int fatal_error)
Definition: common.c:1601
static int test_offset_time(const struct time_format format, const char *time, int *offset)
Definition: intrinsic.c:2807
cob_field * cob_intr_test_day_yyyyddd(cob_field *srcfield)
Definition: intrinsic.c:4218
static void format_as_yyyyddd(const int day_num, const int with_hyphen, char *buff)
Definition: intrinsic.c:2031
cob_field * cob_intr_module_date(void)
Definition: intrinsic.c:3610
cob_field * cob_intr_module_path(void)
Definition: intrinsic.c:3701
#define COB_TYPE_NUMERIC_FLOAT
Definition: common.h:610
const char * cob_get_exception_name(void)
Definition: common.c:1199
cob_field * cob_intr_national_of(const int offset, const int length, const int params,...)
Definition: intrinsic.c:6501
cob_field * cob_intr_mean(const int params,...)
Definition: intrinsic.c:4955
cob_field * cob_intr_exception_file_n(void)
Definition: intrinsic.c:6481
cob_field * cob_intr_exception_location(void)
Definition: intrinsic.c:3857
static cob_global * cobglobptr
Definition: intrinsic.c:71
#define COB_FIELD_REAL_BINARY(f)
Definition: common.h:649
int year
Definition: coblocal.h:263
#define unlikely(x)
Definition: common.h:437
static void format_date(const struct date_format format, const int days, char *buff)
Definition: intrinsic.c:2149
#define COB_FIELD_INIT(x, y, z)
Definition: coblocal.h:144
static void day_of_integer(int days, int *year, int *day)
Definition: intrinsic.c:1893
cob_field * cob_intr_char(cob_field *srcfield)
Definition: intrinsic.c:3977
cob_field * cob_intr_exp(cob_field *srcfield)
Definition: intrinsic.c:4285
cob_field * cob_intr_boolean_of_integer(cob_field *f1, cob_field *f2)
Definition: intrinsic.c:6453
static void cob_decimal_get_mpf(mpf_t dst, const cob_decimal *d)
Definition: intrinsic.c:847
cob_field * cob_intr_exception_file(void)
Definition: intrinsic.c:3833
size_t calc_size
Definition: intrinsic.c:101
static void cob_mpf_log10(mpf_t dst_val, const mpf_t src_val)
Definition: intrinsic.c:991
int cob_check_numval(const cob_field *srcfield, const cob_field *currency, const int chkcurr, const int anycase)
Definition: intrinsic.c:3132
void cob_gmp_free(void *)
Definition: numeric.c:217
EC ARGUMENT EC EC BOUND EC BOUND EC BOUND EC BOUND TABLE EC DATA EC DATA EC DATA PTR NULL
Definition: exception.def:95
static void calc_variance_of_args(const int n, va_list numbers, cob_decimal *mean)
Definition: intrinsic.c:1585
#define COB_TIMEDEC_MAX
Definition: intrinsic.c:122
cob_field * cob_intr_lcl_time_from_secs(const int offset, const int length, cob_field *srcfield, cob_field *locale_field)
Definition: intrinsic.c:5557
cob_field * cob_intr_numval(cob_field *srcfield)
Definition: intrinsic.c:4584
cob_field * cob_intr_module_id(void)
Definition: intrinsic.c:3640
if sign
Definition: flag.def:42
static int test_hour(const char *time, int *offset)
Definition: intrinsic.c:2735
int cob_valid_date_format(const char *format)
Definition: intrinsic.c:3355
cob_field * cob_intr_random(const int params,...)
Definition: intrinsic.c:5023
static const char cob_pi_str[]
Definition: intrinsic.c:359
static const int normal_month_days[]
Definition: intrinsic.c:113
int cob_decimal_cmp(cob_decimal *, cob_decimal *)
Definition: numeric.c:1922
static mpf_t cob_sqrt_two
Definition: intrinsic.c:92
cob_field * cob_intr_exception_status(void)
Definition: intrinsic.c:3900
void cob_decimal_add(cob_decimal *, cob_decimal *)
Definition: numeric.c:1875
cob_field * cob_intr_day_of_integer(cob_field *srcdays)
Definition: intrinsic.c:4097
static struct calc_struct * calc_base
Definition: intrinsic.c:104
cob_field * cob_intr_acos(cob_field *srcfield)
Definition: intrinsic.c:4425
static void format_current_date(const struct date_format date_fmt, const struct time_format time_fmt, char *formatted_datetime)
Definition: intrinsic.c:2950
cob_field f1
Definition: cobxref.c.l.h:54
cob_field * cob_intr_factorial(cob_field *srcfield)
Definition: intrinsic.c:4241
cob_field * cob_intr_test_numval(cob_field *srcfield)
Definition: intrinsic.c:5773
formatted_time_extra
Definition: intrinsic.c:1949
cob_field * cob_intr_test_numval_c(cob_field *srcfield, cob_field *currency)
Definition: intrinsic.c:5780
#define COB_FIELD_BINARY_TRUNC(f)
Definition: common.h:654
#define COB_TYPE_NUMERIC_BINARY
Definition: common.h:608
cob_field * cob_intr_locale_time(const int offset, const int length, cob_field *srcfield, cob_field *locale_field)
Definition: intrinsic.c:5496
cob_field * cob_intr_currency_symbol(void)
Definition: intrinsic.c:5738
void cob_set_exception(const int id)
Definition: common.c:1212
#define GET_VARIANCE(num_args, args)
Definition: intrinsic.c:5062
static int test_two_zeroes(const char *str, int *offset)
Definition: intrinsic.c:2799
static int try_get_valid_offset_time(const struct time_format time_format, cob_field *offset_time_field, int *offset_time)
Definition: intrinsic.c:2419
cob_field * cob_intr_sqrt(cob_field *srcfield)
Definition: intrinsic.c:4561
static void cob_trim_decimal(cob_decimal *d)
Definition: intrinsic.c:517
static int int_strncasecmp(const void *s1, const void *s2, size_t n)
Definition: intrinsic.c:1430
cob_field * cob_intr_combined_datetime(cob_field *srcdays, cob_field *srctime)
Definition: intrinsic.c:4020
cob_field * cob_intr_when_compiled(const int offset, const int length, cob_field *f)
Definition: intrinsic.c:3940
static int max_week(int year)
Definition: intrinsic.c:1822
static int in_last_n_chars(const cob_field *field, const size_t n, const int i)
Definition: intrinsic.c:1438
static void add_offset_time(const int with_colon, int const *offset_time, const ptrdiff_t buff_pos, char *buff)
Definition: intrinsic.c:2263
#define COB_TYPE_ALPHANUMERIC_EDITED
Definition: common.h:623
cob_field * cob_switch_value(const int id)
Definition: intrinsic.c:2980
cob_field * cob_intr_ord(cob_field *srcfield)
Definition: intrinsic.c:3995
#define COB_TYPE_NUMERIC_DISPLAY
Definition: common.h:607
static mpf_t cob_pi
Definition: intrinsic.c:93
#define cob_sli_t
Definition: common.h:32
cob_field * cob_intr_num_decimal_point(void)
Definition: intrinsic.c:5633
cob_field * cob_intr_locale_date(const int offset, const int length, cob_field *srcfield, cob_field *locale_field)
Definition: intrinsic.c:5375
void cob_decimal_div(cob_decimal *, cob_decimal *)
Definition: numeric.c:1899
void cob_init_intrinsic(cob_global *lptr)
Definition: intrinsic.c:6555
#define cob_u16_t
Definition: common.h:29
static int valid_year(const int year)
Definition: intrinsic.c:1794
static int test_day_of_week(const char *date, int *offset)
Definition: intrinsic.c:2667
static int test_century(const char *date, int *offset, int *state)
Definition: intrinsic.c:2487
cob_field * cob_intr_stored_char_length(cob_field *srcfield)
Definition: intrinsic.c:4002
int cob_cmp(cob_field *f1, cob_field *f2)
Definition: common.c:2318
static int test_less_than_60(const char *time, int *offset)
Definition: intrinsic.c:2727
#define COB_MODULE_PTR
Definition: coblocal.h:185
#define COB_TIMESTR_MAX
Definition: intrinsic.c:125
const char * cob_orig_section
Definition: common.h:1191
static int test_colon_presence(const int with_colons, const char *time, int *offset)
Definition: intrinsic.c:2766
int cob_valid_datetime_format(const char *format, const char decimal_point)
Definition: intrinsic.c:3402
#define COB_DATESTR_LEN
Definition: intrinsic.c:119
cob_field * cob_intr_current_date(const int offset, const int length)
Definition: intrinsic.c:3952
void cob_decimal_move_temp(cob_field *src, cob_field *dst)
Definition: intrinsic.c:3104
static cob_decimal d1
Definition: intrinsic.c:79
cob_field * cob_intr_median(const int params,...)
Definition: intrinsic.c:4907
static int test_month(const char *date, int *offset, int *month)
Definition: intrinsic.c:2540
#define COB_DATESTR_MAX
Definition: intrinsic.c:120
static int test_w_presence(const char *date, int *offset)
Definition: intrinsic.c:2636
static void cob_mpf_cos(mpf_t dst_val, const mpf_t src_val)
Definition: intrinsic.c:1095
cob_field * cob_intr_upper_case(const int offset, const int length, cob_field *srcfield)
Definition: intrinsic.c:3559
void cob_decimal_sub(cob_decimal *, cob_decimal *)
Definition: numeric.c:1883
#define COB_DEPTH_LEVEL
Definition: coblocal.h:77
const char * cob_orig_statement
Definition: common.h:1189
unsigned int cob_got_exception
Definition: common.h:1207
static void get_fractional_seconds(cob_field *time, cob_decimal *fraction)
Definition: intrinsic.c:2165
#define COB_TIMESTR_LEN
Definition: intrinsic.c:124
cob_field * cob_intr_test_date_yyyymmdd(cob_field *srcfield)
Definition: intrinsic.c:4188
cob_field * cob_intr_formatted_datetime(const int offset, const int length, const int params,...)
Definition: intrinsic.c:6169
cob_field * cob_intr_formatted_time(const int offset, const int length, const int params,...)
Definition: intrinsic.c:6076
static void add_decimal_digits(int decimal_places, cob_decimal *second_fraction, char *buff, ptrdiff_t *buff_pos)
Definition: intrinsic.c:2227
#define COB_A_INLINE
Definition: common.h:440
static cob_field * curr_field
Definition: intrinsic.c:105
static int test_char_cond(const int cond, int *offset)
Definition: intrinsic.c:2450
cob_field * cob_intr_numval_c(cob_field *srcfield, cob_field *currency)
Definition: intrinsic.c:4590
static int test_time_end(const struct time_format format, const char *time, int *offset)
Definition: intrinsic.c:2829
cob_field * cob_intr_lowest_algebraic(cob_field *srcfield)
Definition: intrinsic.c:5794
static int cob_check_numval_f(const cob_field *srcfield)
Definition: intrinsic.c:677
int cob_decimal_get_field(cob_decimal *, cob_field *, const int)
Definition: numeric.c:1801
static int format_time(const struct time_format format, int time, cob_decimal *second_fraction, int *offset_time, char *buff)
Definition: intrinsic.c:2316
size_t size
Definition: common.h:951
#define COB_TYPE_NUMERIC_DOUBLE
Definition: common.h:611
static cob_u32_t integer_of_wwwd(const struct date_format format, const int year, const char *final_part)
Definition: intrinsic.c:2889
static int test_unit_year(const char *date, int *offset, int *state)
Definition: intrinsic.c:2509
static int test_millenium(const char *date, int *offset, int *millenium)
Definition: intrinsic.c:2478
strict implicit external call column overflow
Definition: warning.def:63
cob_field * cob_intr_formatted_current_date(const int offset, const int length, cob_field *format_field)
Definition: intrinsic.c:6407
static void calc_mean_of_args(const int num_args, va_list args)
Definition: intrinsic.c:1564
static cob_decimal d4
Definition: intrinsic.c:82
int with_colons
Definition: intrinsic.c:1956
const cob_field_attr * attr
Definition: common.h:953
cob_field * cob_intr_exception_location_n(void)
Definition: intrinsic.c:6487
cob_field * cob_intr_numval_f(cob_field *srcfield)
Definition: intrinsic.c:4596
static int valid_day_and_format(const int day, const char *format)
Definition: intrinsic.c:2001
#define COB_MPF_PREC
Definition: coblocal.h:89
struct cob_time cob_get_current_date_and_time(void)
Definition: common.c:2699
cob_field * cob_intr_exp10(cob_field *srcfield)
Definition: intrinsic.c:4307
cob_field * cob_intr_highest_algebraic(cob_field *srcfield)
Definition: intrinsic.c:5866
static void format_as_yyyymmdd(const int day_num, const int with_hyphen, char *buff)
Definition: intrinsic.c:2017
static struct time_format parse_time_format_string(const char *str)
Definition: intrinsic.c:2282
cob_field * cob_intr_mon_decimal_point(void)
Definition: intrinsic.c:5598
static void format_as_yyyywwwd(const int day_num, const int with_hyphen, char *buff)
Definition: intrinsic.c:2103
static int valid_offset_time(const int offset)
Definition: intrinsic.c:1855
void * cob_malloc(const size_t size)
Definition: common.c:1250
cob_field * cob_intr_annuity(cob_field *srcfield1, cob_field *srcfield2)
Definition: intrinsic.c:4712
int minute
Definition: coblocal.h:268
static const char cob_sqrt_two_str[]
Definition: intrinsic.c:379
int offset_known
Definition: coblocal.h:271
const char * cob_orig_program_id
Definition: common.h:1190
static void cob_mpf_sin(mpf_t dst_val, const mpf_t src_val)
Definition: intrinsic.c:1016
static void add_z(const ptrdiff_t buff_pos, char *buff)
Definition: intrinsic.c:2257
static void substitute_matches(cob_field *original, cob_field **matches, cob_field **reps, const int numreps, int(*cmp_func)(const void *, const void *, size_t), unsigned char *replaced_begin)
Definition: intrinsic.c:1335
#define COB_FIELD_HAVE_SIGN(f)
Definition: common.h:643
cob_field * cob_intr_max(const int params,...)
Definition: intrinsic.c:4859
cob_field * cob_intr_length(cob_field *srcfield)
Definition: intrinsic.c:3469
static mpf_t cob_log_half
Definition: intrinsic.c:91
static int test_second(const char *time, int *offset)
Definition: intrinsic.c:2759
#define COB_NATIONAL_SIZE
Definition: common.h:683
static int * get_system_offset_time_ptr(int *const offset_time)
Definition: intrinsic.c:2436
static struct date_format parse_date_format_string(const char *format_str)
Definition: intrinsic.c:2131
cob_field * cob_intr_byte_length(cob_field *srcfield)
Definition: intrinsic.c:3480
int cob_exception_code
Definition: common.h:1203
static COB_INLINE COB_A_INLINE int test_char_in_range(const char min, const char max, const char ch, int *offset)
Definition: intrinsic.c:2473
static void cob_alloc_set_field_spaces(const int n)
Definition: intrinsic.c:1764
char * cob_locale
Definition: common.h:1194
enum days_format days
Definition: intrinsic.c:2126
mpz_t value
Definition: common.h:985
int month
Definition: coblocal.h:264
int nanosecond
Definition: coblocal.h:270
cob_field * cob_intr_seconds_from_formatted_time(cob_field *format_field, cob_field *time_field)
Definition: intrinsic.c:5325
int second
Definition: coblocal.h:269
static COB_INLINE COB_A_INLINE void cob_decimal_set(cob_decimal *dst, const cob_decimal *src)
Definition: intrinsic.c:509
cob_field * cob_intr_num_thousands_sep(void)
Definition: intrinsic.c:5703
static int test_minute(const char *time, int *offset)
Definition: intrinsic.c:2752
static int days_in_year(const int year)
Definition: intrinsic.c:1776
static void get_iso_week(const int, int *, int *)
Definition: intrinsic.c:2064
#define COB_UNUSED(z)
Definition: common.h:535
static int test_hyphen_presence(const int with_hyphens, const char *date, int *offset)
Definition: intrinsic.c:2534
cob_field * cob_intr_trim(const int offset, const int length, cob_field *srcfield, const int direction)
Definition: intrinsic.c:3790
cob_field * cob_intr_standard_compare(const int params,...)
Definition: intrinsic.c:6511
cob_field * cob_intr_rem(cob_field *srcfield1, cob_field *srcfield2)
Definition: intrinsic.c:5017
#define COB_FIELD_DIGITS(f)
Definition: common.h:663
numval_type
Definition: intrinsic.c:1450
static const int normal_days[]
Definition: intrinsic.c:109
static int test_day_of_month(const char *date, const int year, const int month, int *offset)
Definition: intrinsic.c:2563
static void cob_decimal_set_mpf(cob_decimal *d, const mpf_t src)
Definition: intrinsic.c:816
const char * select_name
Definition: common.h:1112
strict implicit external call params
Definition: warning.def:60
static int test_no_trailing_junk(const char *str, int offset, int end_of_string)
Definition: intrinsic.c:2695
static void cob_mpf_exp(mpf_t dst_val, const mpf_t src_val)
Definition: intrinsic.c:871
Definition: parser.c:1853
cob_field * cob_intr_standard_deviation(const int num_args,...)
Definition: intrinsic.c:5090
cob_field * cob_intr_integer_part(cob_field *srcfield)
Definition: intrinsic.c:3513
#define COB_MPF_CUTOFF
Definition: coblocal.h:93
cob_field * cob_intr_sign(cob_field *srcfield)
Definition: intrinsic.c:3551
#define COB_TYPE_NUMERIC_EDITED
Definition: common.h:619
cob_field * cob_intr_test_formatted_datetime(cob_field *format_field, cob_field *datetime_field)
Definition: intrinsic.c:6273
cob_field * cob_intr_test_numval_f(cob_field *srcfield)
Definition: intrinsic.c:5787
#define COB_FIELD_SIZE(f)
Definition: common.h:671
static int at_cr_or_db(const cob_field *srcfield, const int pos)
Definition: intrinsic.c:1444
static int test_decimal_places(const int num_decimal_places, const char decimal_point, const char *time, int *offset)
Definition: intrinsic.c:2777
int hour
Definition: coblocal.h:267
static int test_day_of_year(const char *date, const int year, int *offset)
Definition: intrinsic.c:2599
int scale
Definition: common.h:986
static COB_INLINE COB_A_INLINE int test_digit(const unsigned char ch, int *offset)
Definition: intrinsic.c:2467
static int comp_field(const void *m1, const void *m2)
Definition: intrinsic.c:476
cob_field_attr calc_attr
Definition: intrinsic.c:100
cob_field * cob_intr_integer_of_date(cob_field *srcfield)
Definition: intrinsic.c:4126