351
351
static int cob_switch[COB_SWITCH_MAX + 1];
353
/* BCD to Integer translation (full byte -> 0 - 99) */
354
static unsigned char b2i[256]=
355
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
356
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 255, 255, 255, 255, 255, 255,
357
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 255, 255, 255, 255, 255, 255,
358
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 255, 255, 255, 255, 255, 255,
359
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 255, 255, 255, 255, 255, 255,
360
50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 255, 255, 255, 255, 255, 255,
361
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 255, 255, 255, 255, 255, 255,
362
70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 255, 255, 255, 255, 255, 255,
363
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 255, 255, 255, 255, 255, 255,
364
90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 255, 255, 255, 255, 255, 255 };
366
#define IS_INVALID_BCD_DATA(c) (b2i[(unsigned char)c] == 255)
368
/* note: use of table d2i was tested and seen to be
369
slower for checking validity/invalidity
370
and only 0.2% faster for GET_D2I than COB_D2I */
371
#define IS_INVALID_DIGIT_DATA(c) (c < '0' || c > '9') /* not valid digits '0' - '9' */
372
#define IS_VALID_DIGIT_DATA(c) (c >= '0' && c <= '9') /* valid digits '0' - '9' */
353
374
/* Runtime exit handling */
354
375
static struct exit_handlerlist {
355
376
struct exit_handlerlist *next;
1871
1933
cob_cmp_all (cob_field *f1, cob_field *f2)
1873
1935
const unsigned char *col = COB_MODULE_PTR->collating_sequence;
1874
unsigned char *data;
1875
unsigned char buff[COB_MAX_DIGITS + 1];
1877
if (COB_FIELD_HAVE_SIGN (f1)) {
1878
/* drop sign for comparision, using a copy to not change
1879
the field during comparision */
1880
/* CHECKME: What should be returned if f1 is negative? */
1881
unsigned char *real_data = f1->data;
1882
f1->data = data = buff;
1883
memcpy (buff, real_data, f1->size);
1884
(void)cob_real_get_sign (f1);
1885
f1->data = real_data;
1936
const unsigned char *data1 = COB_FIELD_DATA (f1);
1937
const unsigned char *data2 = f2->data;
1938
const size_t size1 = COB_FIELD_SIZE (f1);
1939
const size_t size2 = f2->size;
1940
/* CHECKME: What should be returned if f1 is negative? */
1941
/* CHECKME: Do we ever get here with f2 being numeric? */
1942
const int sign = COB_GET_SIGN_ADJUST (f1);
1890
1945
/* check without collation */
1891
1946
if (col == NULL) {
1892
if (f2->size == 1) {
1893
if (f2->data[0] == ' ') {
1948
if (*data2 == ' ') {
1894
1949
/* check for IF VAR = [ALL] SPACE[S] */
1895
return compare_spaces (f1->data, f1->size);
1897
if (f2->data[0] == '0') {
1950
ret = compare_spaces (data1, size1);
1952
if (*data2 == '0') {
1898
1953
/* check for IF VAR = [ALL] ZERO[ES] */
1899
return compare_zeroes (f1->data, f1->size);
1954
ret = compare_zeroes (data1, size1);
1956
/* check for IF VAR = ALL '5' / HIGH-VALUE / ... */
1957
ret = compare_character (data1, size1, data2, 1);
1902
/* check for IF VAR = ALL ... / HIGH-VALUE / ... */
1903
if (f1->size > f2->size) {
1904
return compare_character (f1->data, f1->size, f2->data, f2->size);
1960
/* check for IF VAR = ALL ... / ... */
1961
if (size1 > size2) {
1962
ret = compare_character (data1, size1, data2, size2);
1906
return compare_character (f1->data, f1->size, f2->data, f1->size);
1964
ret = compare_character (data1, size1, data2, size1);
1910
1967
/* check with collation */
1911
if (f2->size == 1) {
1912
1969
/* check for IF VAR = ALL "9" / IF VAR = ZERO */
1913
return common_cmpc (data, f2->data[0], f1->size, col);
1970
ret = common_cmpc (data1, *data2, size1, col);
1915
1972
/* check for IF VAR = ALL "AB" ... */
1916
size_t size = f1->size;
1918
while (size >= f2->size) {
1919
if ((ret = common_cmps (data, f2->data, f2->size, col)) != 0) {
1973
const size_t chunk_size = size2;
1974
size_t size_loop = size1;
1975
while (size_loop >= chunk_size) {
1976
if ((ret = common_cmps (data1, data2, chunk_size, col)) != 0) {
1979
size_loop -= chunk_size;
1980
data1 += chunk_size;
1926
return common_cmps (data, f2->data, size, col);
1984
ret = common_cmps (data1, data2, size_loop, col);
1988
COB_PUT_SIGN_ADJUSTED (f1, sign);
1932
1992
/* compare content of field 'f1' to content of 'f2', space padded,
1935
1995
cob_cmp_alnum (cob_field *f1, cob_field *f2)
1937
1997
const unsigned char *col = COB_MODULE_PTR->collating_sequence;
1938
const size_t min = (f1->size < f2->size) ? f1->size : f2->size;
1998
const unsigned char *data1 = COB_FIELD_DATA (f1);
1999
const unsigned char *data2 = COB_FIELD_DATA (f2);
2000
const size_t size1 = COB_FIELD_SIZE (f1);
2001
const size_t size2 = COB_FIELD_SIZE (f2);
2002
const size_t min = (size1 < size2) ? size1 : size2;
1941
2005
if (col == NULL) { /* check without collation */
1943
2007
/* Compare common substring */
1944
if ((ret = memcmp (f1->data, f2->data, min)) != 0) {
2008
if ((ret = memcmp (data1, data2, min)) != 0) {
1948
2012
/* Compare the rest (if any) with spaces */
1949
if (f1->size > f2->size) {
1950
const size_t spaces_to_test = f1->size - min;
1951
return compare_spaces (f1->data + min, spaces_to_test);
1952
} else if (f1->size < f2->size) {
1953
const size_t spaces_to_test = f2->size - min;
1954
return -compare_spaces (f2->data + min, spaces_to_test);
2013
if (size1 > size2) {
2014
const size_t spaces_to_test = size1 - min;
2015
return compare_spaces (data1 + min, spaces_to_test);
2016
} else if (size1 < size2) {
2017
const size_t spaces_to_test = size2 - min;
2018
return -compare_spaces (data2 + min, spaces_to_test);
1957
2021
} else { /* check with collation */
1959
2023
/* Compare common substring */
1960
if ((ret = common_cmps (f1->data, f2->data, min, col)) != 0) {
2024
if ((ret = common_cmps (data1, data2, min, col)) != 0) {
1964
2028
/* Compare the rest (if any) with spaces */
1965
if (f1->size > f2->size) {
1966
const size_t spaces_to_test = f1->size - min;
1967
return common_cmpc (f1->data + min, ' ', spaces_to_test, col);
1968
} else if (f1->size < f2->size) {
1969
const size_t spaces_to_test = f2->size - min;
1970
return -common_cmpc (f2->data + min, ' ', spaces_to_test, col);
2029
if (size1 > size2) {
2030
const size_t spaces_to_test = size1 - min;
2031
return common_cmpc (data1 + min, ' ', spaces_to_test, col);
2032
} else if (size1 < size2) {
2033
const size_t spaces_to_test = size2 - min;
2034
return -common_cmpc (data2 + min, ' ', spaces_to_test, col);
2141
2205
cob_check_env_true (char * s)
2144
if (strlen (s) == 1 && (*s == 'Y' || *s == 'y' || *s == '1')) return 1;
2145
if (strcasecmp (s, "YES") == 0 || strcasecmp (s, "ON") == 0 ||
2146
strcasecmp (s, "TRUE") == 0) {
2207
return s && ((strlen (s) == 1 && (*s == 'Y' || *s == 'y' || *s == '1'))
2208
|| strcasecmp (s, "YES") == 0 || strcasecmp (s, "ON") == 0
2209
|| strcasecmp (s, "TRUE") == 0);
2154
2213
cob_check_env_false (char * s)
2156
2215
return s && ((strlen (s) == 1 && (*s == 'N' || *s == 'n' || *s == '0'))
2157
|| (strcasecmp (s, "NO") == 0 || strcasecmp (s, "NONE") == 0
2158
|| strcasecmp (s, "OFF") == 0 || strcasecmp (s, "FALSE") == 0));
2216
|| strcasecmp (s, "NO") == 0 || strcasecmp (s, "NONE") == 0
2217
|| strcasecmp (s, "OFF") == 0 || strcasecmp (s, "FALSE") == 0);
2161
2220
static char file_path_name [COB_FILE_BUFF] = "";
3273
3332
return (cob_u8_ptr)tmptr;
3276
/* stores the field's rtrimmed string content into the given buffer
3279
cob_field_to_string (const cob_field *f, void *str, const size_t maxsize)
3281
register unsigned char *end, *data, *s;
3284
snprintf (str, maxsize, "%s", ("NULL field"));
3292
/* check if field has data assigned (may be a BASED / LINKAGE item) */
3294
snprintf (str, maxsize, "%s", ("field with NULL address"));
3297
end = data + f->size - 1;
3298
while (end > data) {
3299
if (*end != ' ' && *end) {
3304
s = (unsigned char *)str;
3305
if (*end == ' ' || *end == 0) {
3310
/* note: the specified max does not contain the low-value */
3311
if ((size_t)(end - data) > maxsize) {
3312
end = data + maxsize;
3314
while (data <= end) {
3321
3336
call_exit_handlers_and_terminate (void)
3980
3959
if ((*p & 0x0F) <= 9) {
3981
*p = (*p & 0x0F) + '0';
3960
*p = COB_I2D (*p & 0x0F);
3989
3969
cob_check_numdisp (const cob_field *f)
3992
unsigned char *data;
3971
register const unsigned char *p = f->data;
3972
const unsigned char *end = p + f->size;
3998
3974
if (COB_FIELD_HAVE_SIGN (f)) {
3999
3975
/* Adjust for sign byte */
4001
3977
if (COB_FIELD_SIGN_LEADING (f)) {
4005
p = f->data + f->size - 1;
4007
3982
if (COB_FIELD_SIGN_SEPARATE (f)) {
4008
if (*p != '+' && *p != '-') {
4011
} else if (COB_MODULE_PTR->ebcdic_sign) {
3983
if (c != '+' && c != '-') {
3986
} else if (IS_INVALID_DIGIT_DATA (c)) {
3987
if (COB_MODULE_PTR->ebcdic_sign) {
4075
for (i = 0; i < size; ++i) {
4076
if (!isdigit (data[i])) {
4034
if (IS_INVALID_DIGIT_DATA (*p)) {
4107
4073
if (COB_FIELD_SIGN_SEPARATE (f)) {
4108
4074
return (*p == '-') ? -1 : 1;
4110
if (*p >= (unsigned char)'0' && *p <= (unsigned char)'9') {
4076
if (IS_VALID_DIGIT_DATA (*p)) {
4113
4079
if (*p == ' ') {
4114
4080
#if 0 /* RXWRXW - Space sign */
4115
*p = (unsigned char)'0';
4119
if (COB_MODULE_PTR->ebcdic_sign) {
4120
return cob_get_sign_ebcdic (p);
4085
if (adjust_ebcdic) {
4086
#ifdef COB_EBCDIC_MACHINE
4087
if (COB_MODULE_PTR->ebcdic_sign) {
4088
return cob_get_sign_ebcdic (p);
4090
return cob_get_sign_ascii (p) < 0 ? -2 : 2;
4092
if (COB_MODULE_PTR->ebcdic_sign) {
4093
return cob_get_sign_ebcdic (p) < 0 ? -2 : 2;
4095
return ((*p & 0xF0) == 0x70) ? -1 : 1;
4098
if (COB_MODULE_PTR->ebcdic_sign) {
4099
return cob_get_sign_ebcdic (p);
4101
return cob_get_sign_ascii (p);
4122
return cob_get_sign_ascii (p);
4123
4103
case COB_TYPE_NUMERIC_PACKED:
4124
4104
if (COB_FIELD_NO_SIGN_NIBBLE (f)) {
4248
4228
only in test "Alphanumeric and binary numeric" */
4250
4230
if (f1_is_numeric || f2_is_numeric) {
4251
/* CHECKME: What should be returned if field is negative?
4252
We suspicously change -12 to 12 here... */
4231
/* Note: the standard explicit defines how to handle that:
4232
intermediate MOVE to a NUMERIC_DISPLAY with same amount
4233
of digits (= drop sign and implied decimal point), then
4253
4235
cob_field field;
4254
4236
cob_field_attr attr;
4255
4237
unsigned char buff[COB_MAX_DIGITS + 10];
4257
/* CHECKME: may need to abort if we ever get here with float data */
4259
/* FIXME: must be converted to COB_TYPE_NUMERIC_EDITED with an
4260
internal PIC of COB_FIELD_DIGITS '9's and leading sign,
4261
otherwise we'll fail as soon as we enable COB_MAX_BINARY */
4239
/* note: the standard explicit forbits floating-point numeric
4262
4241
if (f1_is_numeric
4263
4242
&& f1_type != COB_TYPE_NUMERIC_DISPLAY) {
4264
4243
COB_FIELD_INIT (COB_FIELD_DIGITS (f1), buff, &attr);
4281
4260
if (COB_FIELD_HAVE_SIGN (f1)) {
4282
4261
/* Note: if field is numeric then it is always
4283
4262
USAGE DISPLAY here */
4286
/* drop sign for comparision, using a copy to not change
4287
the field during comparision */
4288
unsigned char buff2[COB_MAX_DIGITS + 10];
4289
const size_t size = f1->size;
4291
unsigned char *real_data = f1->data;
4292
memcpy (buff2, real_data, size);
4294
(void)cob_real_get_sign (f1);
4295
ret = cob_cmp_alnum (f1, f2);
4296
f1->data = real_data;
4264
const int sign = COB_GET_SIGN (f1);
4265
int ret = cob_cmp_alnum (f1, f2);
4266
COB_PUT_SIGN (f1, sign);
4299
4269
/* we operate on a buffer already, just go on */
4300
(void)cob_real_get_sign (f1);
4270
(void)cob_real_get_sign (f1, 0);
4301
4271
return cob_cmp_alnum (f1, f2);
4305
4275
if (COB_FIELD_HAVE_SIGN (f2)) {
4306
4276
/* Note: if field is numeric then it is always
4307
4277
USAGE DISPLAY here */
4309
4278
if (f2 != &field) {
4310
/* drop sign for comparision, using a copy to not change
4311
the field during comparision */
4312
unsigned char buff2[COB_MAX_DIGITS + 10];
4313
const size_t size = f2->size;
4315
unsigned char *real_data = f2->data;
4316
memcpy (buff2, real_data, size);
4318
(void)cob_real_get_sign (f2);
4319
ret = cob_cmp_alnum (f1, f2);
4320
f2->data = real_data;
4279
const int sign = COB_GET_SIGN (f2);
4280
int ret = cob_cmp_alnum (f1, f2);
4281
COB_PUT_SIGN (f2, sign);
4323
4284
/* we operate on a buffer already, just go on */
4324
(void)cob_real_get_sign (f2);
4285
(void)cob_real_get_sign (f2, 0);
4325
4286
return cob_cmp_alnum (f1, f2);
4369
4330
case COB_TYPE_NUMERIC_PACKED:
4332
register const unsigned char *p = f->data;
4333
const unsigned char *end = p + f->size - 1;
4337
const char sign = *end & 0x0F;
4338
if (COB_FIELD_NO_SIGN_NIBBLE (f)) {
4339
/* COMP-6 - Check last nibble */
4343
} else if (COB_FIELD_HAVE_SIGN (f)) {
4344
if (COB_MODULE_PTR->flag_host_sign
4346
/* all fine, go on */
4352
} else if (sign != 0x0F) {
4357
/* Check high nibble of last byte */
4358
if ((*end & 0xF0) > 0x90) {
4373
4362
/* Check digits */
4374
for (i = 0; i < f->size - 1; ++i) {
4375
if ((f->data[i] & 0xF0) > 0x90
4376
|| (f->data[i] & 0x0F) > 0x09) {
4380
/* Check high nibble of last byte */
4381
if ((f->data[i] & 0xF0) > 0x90) {
4385
if (COB_FIELD_NO_SIGN_NIBBLE (f)) {
4386
/* COMP-6 - Check last nibble */
4387
if ((f->data[i] & 0x0F) > 0x09) {
4394
sign = f->data[i] & 0x0F;
4395
if (COB_FIELD_HAVE_SIGN (f)) {
4396
if (sign == 0x0C || sign == 0x0D) {
4399
if (COB_MODULE_PTR->flag_host_sign
4403
} else if (sign == 0x0F) {
4364
if (IS_INVALID_BCD_DATA (*p)) {
4408
4372
case COB_TYPE_NUMERIC_DISPLAY:
4409
4373
return cob_check_numdisp (f);
4602
4587
cob_check_numeric (const cob_field *f, const char *name)
4604
unsigned char *data;
4609
4589
if (!cob_is_numeric (f)) {
4590
register unsigned char *data = f->data;
4591
unsigned char *end = data + f->size;
4610
4595
cob_set_exception (COB_EC_DATA_INCOMPATIBLE);
4611
4596
buff = cob_fast_malloc ((size_t)COB_SMALL_BUFF);
4614
4598
if (COB_FIELD_IS_NUMDISP(f) || COB_FIELD_IS_ANY_ALNUM(f)) {
4615
for (i = 0; i < f->size; ++i) {
4616
if (isprint (data[i])) {
4599
while (data < end) {
4600
if (isprint (*data)) {
4619
p += sprintf (p, "\\%03o", data[i]);
4603
p += sprintf (p, "\\%03o", *data++);
4623
4607
p += sprintf (p, "0x");
4624
for (i = 0; i < f->size; ++i) {
4625
p += sprintf (p, "%02x", data[i]);
4608
while (data < end) {
4609
p += sprintf (p, "%02x", *data++);
5159
5137
int yr, mm, dd, hh, mi, ss, ns;
5160
5138
int offset = 9999;
5163
5141
struct tm *tmptr;
5164
5142
char iso_timezone[7] = { 0 };
5165
char nanoseconds[10];
5143
unsigned char *p = (unsigned char*)cobsetptr->cob_date;
5167
if (cobsetptr == NULL
5168
|| cobsetptr->cob_date == NULL) {
5174
5149
/* skip quotes and space-characters */
5175
while (cobsetptr->cob_date[j] == '\''
5176
|| cobsetptr->cob_date[j] == '"'
5177
|| isspace((unsigned char)cobsetptr->cob_date[j])) {
5181
5156
/* extract epoch, if specified */
5182
if (cobsetptr->cob_date[j] == '@') {
5183
5158
/* @sssssssss seconds since epoch */
5184
ret = cob_set_date_from_epoch (&cobsetptr->cob_time_constant, cobsetptr->cob_date + j + 1);
5159
ret = cob_set_date_from_epoch (&cobsetptr->cob_time_constant, ++p);
5186
5161
cob_runtime_warning (_("COB_CURRENT_DATE '%s' is invalid"), cobsetptr->cob_date);
5331
5301
} else if (mi > 59) {
5334
if (cobsetptr->cob_date[j] == ':'
5335
|| cobsetptr->cob_date[j] == '-') {
5340
if (cobsetptr->cob_date[j] != 0
5341
&& cobsetptr->cob_date[j] != 'Z'
5342
&& cobsetptr->cob_date[j] != '+'
5343
&& cobsetptr->cob_date[j] != '-') {
5345
for (i = 0; cobsetptr->cob_date[j] != 0; j++) {
5346
if (isdigit ((unsigned char)cobsetptr->cob_date[j])) {
5347
ss = ss * 10 + COB_D2I (cobsetptr->cob_date[j]);
5315
for (i = 0; *p != 0; p++) {
5316
if (IS_INVALID_DIGIT_DATA (*p)) {
5319
ss = ss * 10 + COB_D2I (*p);
5351
5320
if (++i == 2) {
5357
5326
/* possible template with partial system lookup */
5358
if (cobsetptr->cob_date[j] == 'S') {
5359
while (cobsetptr->cob_date[j] == 'S') j++;
5328
while (*p == 'S') p++;
5370
5339
/* extract nanoseconds */
5371
if (cobsetptr->cob_date[j] != 0
5372
&& cobsetptr->cob_date[j] != 'Z'
5373
&& cobsetptr->cob_date[j] != '+'
5374
&& cobsetptr->cob_date[j] != '-') {
5376
if (cobsetptr->cob_date[j] == '.'
5377
|| cobsetptr->cob_date[j] == ':') {
5380
strcpy (nanoseconds, "000000000");
5381
for (i=0; cobsetptr->cob_date[j] != 0; j++) {
5382
if (isdigit ((unsigned char)cobsetptr->cob_date[j])) {
5383
nanoseconds[i] = cobsetptr->cob_date[j];
5349
for (i = 0; *p; p++) {
5350
if (IS_INVALID_DIGIT_DATA (*p)) {
5353
ns = ns * 10 + COB_D2I (*p);
5387
5354
if (++i == 9) {
5392
ns = atoi(nanoseconds);
5395
5361
/* extract UTC offset */
5396
if (cobsetptr->cob_date[j] == 'Z') {
5398
5364
iso_timezone[0] = 'Z';
5399
} else if (cobsetptr->cob_date[j] == '+'
5400
|| cobsetptr->cob_date[j] == '-') {
5401
int len = snprintf (&iso_timezone[0], 7, "%s", cobsetptr->cob_date + j);
5368
/* we operate on a buffer here to drop the included ":" */
5369
int len = snprintf (&iso_timezone[0], 7, "%s", p);
5402
5370
if (len == 3) {
5403
5371
memcpy (iso_timezone + 3, "00", 3);
5405
5373
if (len >= 5 && iso_timezone[3] == ':') {
5406
snprintf (&iso_timezone[3], 3, "%s", cobsetptr->cob_date + j + 4);
5374
snprintf (&iso_timezone[3], 3, "%s", p + 4);
5412
for (i=1; i < 5 && iso_timezone[i] != 0; i++) {
5413
if (!isdigit ((unsigned char)iso_timezone[i])) {
5380
for (i = 1; i < 5 && iso_timezone[i] != 0; i++) {
5381
if (IS_INVALID_DIGIT_DATA (iso_timezone[i])) {
5419
5387
offset = COB_D2I (iso_timezone[1]) * 60 * 10
5420
+ COB_D2I (iso_timezone[2]) * 60
5421
+ COB_D2I (iso_timezone[3]) * 10
5422
+ COB_D2I (iso_timezone[4]);
5388
+ COB_D2I (iso_timezone[2]) * 60
5389
+ COB_D2I (iso_timezone[3]) * 10
5390
+ COB_D2I (iso_timezone[4]);
5423
5391
if (iso_timezone[0] == '-') {
5849
/* DISPLAY ... UPON ENVIRONMENT VALUE */
5878
5851
cob_display_env_value (const cob_field *f)
5883
if (!cob_local_env) {
5884
cob_set_exception (COB_EC_IMP_DISPLAY);
5887
if (!*cob_local_env) {
5888
cob_set_exception (COB_EC_IMP_DISPLAY);
5891
env2 = cob_malloc (f->size + 1U);
5892
cob_field_to_string (f, env2, f->size);
5893
ret = cob_setenv (cob_local_env, env2, 1);
5856
|| !cob_local_env[0]) {
5857
cob_set_exception (COB_EC_IMP_DISPLAY);
5861
char buff[COB_MEDIUM_BUFF];
5862
int flen = cob_field_to_string (f, buff,
5863
COB_MEDIUM_MAX, CCM_NONE);
5865
cob_set_exception (COB_EC_IMP_DISPLAY);
5868
ret = cob_setenv (cob_local_env, buff, 1);
5895
5870
if (ret != 0) {
5896
5871
cob_set_exception (COB_EC_IMP_DISPLAY);
5911
5886
cob_get_environment (const cob_field *envname, cob_field *envval)
5888
char buff[COB_MEDIUM_BUFF];
5917
5892
if (envname->size == 0 || envval->size == 0) {
5918
5893
cob_set_exception (COB_EC_IMP_ACCEPT);
5922
buff = cob_malloc (envname->size + 1U);
5923
cob_field_to_string (envname, buff, envname->size);
5897
flen = cob_field_to_string (envname, buff,
5898
COB_MEDIUM_MAX, CCM_NONE);
5900
cob_set_exception (COB_EC_IMP_ACCEPT);
5924
5904
if (cobsetptr->cob_env_mangle) {
5925
const size_t len = strlen (buff);
5926
for (size = 0; size < len; ++size) {
5927
if (!isalnum ((int)buff[size])) {
5905
const char *p_end = buff + flen;
5906
for (p = buff; p < p_end; ++p) {
5907
if (!isalnum ((int)*p)) {
5932
5912
p = getenv (buff);
5914
cob_move_intermediate (envval, p, strlen (p));
5934
5916
cob_set_exception (COB_EC_IMP_ACCEPT);
5917
cob_move_intermediate (envval, " ", 1);
5937
cob_move_intermediate (envval, p, strlen (p));
5946
5926
if (cob_local_env) {
5947
5927
p = getenv (cob_local_env);
5930
cob_move_intermediate (f, p, strlen (p));
5950
5932
cob_set_exception (COB_EC_IMP_ACCEPT);
5933
cob_move_intermediate (f, " ", 1);
5953
cob_move_intermediate (f, p, strlen (p));
5957
5938
cob_chain_setup (void *data, const size_t parm, const size_t size)
5961
5940
/* only set if given on command-line, otherwise use normal
5962
5941
program internal initialization */
5963
5942
if (parm <= (size_t)cob_argc - 1) {
5943
const size_t len = strlen (cob_argv[parm]);
5964
5944
memset (data, ' ', size);
5965
len = strlen (cob_argv[parm]);
5966
5945
if (len <= size) {
5967
5946
memcpy (data, cob_argv[parm], len);
6643
6621
if (COB_MODULE_PTR->cob_procedure_params[1]) {
6644
6622
i = (int)COB_MODULE_PTR->cob_procedure_params[1]->size;
6645
if ((i == 4) && !strncmp (name, "argc", 4)) {
6623
if ((i == 4) && !memcmp (name, "argc", 4)) {
6646
6624
*((int *)data) = cob_argc;
6649
if ((i == 4) && !strncmp (name, "argv", 4)) {
6627
if ((i == 4) && !memcmp (name, "argv", 4)) {
6650
6628
*((char ***)data) = cob_argv;
6653
if ((i == 5) && !strncmp (name, "stdin", 5)) {
6631
if ((i == 5) && !memcmp (name, "stdin", 5)) {
6654
6632
*((FILE **)data) = stdin;
6657
if ((i == 6) && !strncmp (name, "stdout", 6)) {
6635
if ((i == 6) && !memcmp (name, "stdout", 6)) {
6658
6636
*((FILE **)data) = stdout;
6661
if ((i == 6) && !strncmp (name, "stderr", 6)) {
6639
if ((i == 6) && !memcmp (name, "stderr", 6)) {
6662
6640
*((FILE **)data) = stderr;
6665
if ((i == 5) && !strncmp (name, "errno", 5)) {
6643
if ((i == 5) && !memcmp (name, "errno", 5)) {
6666
6644
*((int **)data) = &errno;
6669
6647
#if defined (HAVE_TIMEZONE)
6670
if ((i == 6) && !strncmp (name, "tzname", 6)) {
6648
if ((i == 6) && !memcmp (name, "tzname", 6)) {
6671
6649
/* Recheck: bcc raises "suspicious pointer conversion */
6672
6650
*((char ***)data) = tzname;
6675
if ((i == 8) && !strncmp (name, "timezone", 8)) {
6653
if ((i == 8) && !memcmp (name, "timezone", 8)) {
6676
6654
*((long *)data) = timezone;
6679
if ((i == 8) && !strncmp (name, "daylight", 8)) {
6657
if ((i == 8) && !memcmp (name, "daylight", 8)) {
6680
6658
*((int *)data) = daylight;
7734
7713
cob_set_locale (cob_field *locale, const int category)
7736
7715
#ifdef HAVE_SETLOCALE
7716
char buff[COB_MINI_BUFF];
7742
if (locale->size == 0) {
7720
int flen = cob_field_to_string (locale, buff,
7721
COB_MINI_MAX, CCM_NONE);
7745
buff = cob_malloc (locale->size + 1U);
7746
cob_field_to_string (locale, buff, locale->size);
7751
7730
switch (category) {
7752
7731
case COB_LC_COLLATE:
7753
p = setlocale (LC_COLLATE, buff);
7732
p = setlocale (LC_COLLATE, p);
7755
7734
case COB_LC_CTYPE:
7756
p = setlocale (LC_CTYPE, buff);
7735
p = setlocale (LC_CTYPE, p);
7758
7737
#ifdef LC_MESSAGES
7759
7738
case COB_LC_MESSAGES:
7760
p = setlocale (LC_MESSAGES, buff);
7739
p = setlocale (LC_MESSAGES, p);
7763
7742
case COB_LC_MONETARY:
7764
p = setlocale (LC_MONETARY, buff);
7743
p = setlocale (LC_MONETARY, p);
7766
7745
case COB_LC_NUMERIC:
7767
p = setlocale (LC_NUMERIC, buff);
7746
p = setlocale (LC_NUMERIC, p);
7769
7748
case COB_LC_TIME:
7770
p = setlocale (LC_TIME, buff);
7749
p = setlocale (LC_TIME, p);
7772
7751
case COB_LC_ALL:
7773
p = setlocale (LC_ALL, buff);
7752
p = setlocale (LC_ALL, p);
7775
7754
case COB_LC_USER:
7776
7755
if (cobglobptr->cob_locale_orig) {