Skip to content

Commit

Permalink
Merge SVN 5038, 5039, 5040, 5041, 5043
Browse files Browse the repository at this point in the history
  • Loading branch information
ddeclerck committed Nov 18, 2024
1 parent 9b8f7de commit 01b3b1e
Show file tree
Hide file tree
Showing 11 changed files with 465 additions and 262 deletions.
16 changes: 9 additions & 7 deletions cobc/reserved.c
Original file line number Diff line number Diff line change
Expand Up @@ -3964,30 +3964,32 @@ struct list_reserved_line {

/*
Upper-casing for reserved words.
We use cob_lower_tab (C locale table) instead of toupper for efficiency.
We use cob_lower_tab (7bit C locale table) instead of toupper for efficiency.
*/
static COB_INLINE COB_A_INLINE unsigned char
res_toupper (unsigned char c)
{
if (cob_lower_tab[c]) {
return cob_lower_tab[c];
const unsigned char tab_entry = cob_lower_tab[c];
if (tab_entry) {
return tab_entry;
}
return c;
}

/* Upper-casing for reserved words using efficient C locale table lookup. */
/* Upper-casing for reserved words using efficient 7bit C locale table lookup. */
unsigned char
cb_toupper (const unsigned char c)
{
return res_toupper (c);
}

/* Lower-casing for reserved words using efficient C locale table lookup. */
/* Lower-casing for reserved words using efficient 7bit C locale table lookup. */
unsigned char
cb_tolower (const unsigned char c)
{
if (cob_upper_tab[c]) {
return cob_upper_tab[c];
const unsigned char tab_entry = cob_upper_tab[c];
if (tab_entry) {
return tab_entry;
}
return c;
}
Expand Down
19 changes: 19 additions & 0 deletions libcob/ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,25 @@
* fileio.c (cob_file_sort_options), common.h: new function to pass more
options, so far only used to set flag_merge

2023-05-09 Simon Sobisch <[email protected]>

* cconv.c (cob_field_to_string): moved from common.c
* cconv.c (cob_init_cconv), coblocal.h, common.c: added
* cconv.c (cob_toupper, cob_tolower, cob_init_cconv), coblocal.h:
included (copy from cobc/reserved.c)
* coblocal.h (enum cob_case_modifier): new enum to select case-adjustment
* cconv.c (cob_field_to_string), coblocal.h: adjusted function signature,
allowing for optional change of case during copy and returning the size
to process or negative error values in case of "no data to process"
* cconv.c (cob_field_to_string): return error if truncating would be
necessary
* reportio.c, intrinsic.c, fileio.c->fextfh.c,fsqlxfd.c, common.c, call.c: adjusted for new
signature of cob_field_to_string
* intrinsic.c (locale_time, cob_intr_locale_date, cob_intr_locale_compare):
always use full locale string passed, error handling improved
* common.c (cob_set_locale, cob_get_environment, cob_display_env_value):
use local buffer, error handling improved

2023-04-28 Simon Sobisch <[email protected]>

* common.c (explain_field_type): distinguish COMP-6 and unsigned packed
Expand Down
22 changes: 11 additions & 11 deletions libcob/call.c
Original file line number Diff line number Diff line change
Expand Up @@ -1204,7 +1204,7 @@ void *
cob_call_field (const cob_field *f, const struct cob_call_struct *cs,
const unsigned int errind, const int fold_case)
{
char *buff, *entry, *dirent;
char *name, *entry, *dirent;
void *p;

/* LCOV_EXCL_START */
Expand All @@ -1213,23 +1213,23 @@ cob_call_field (const cob_field *f, const struct cob_call_struct *cs,
}
/* LCOV_EXCL_STOP */

buff = cob_get_buff (f->size + 1);
cob_field_to_string (f, buff, f->size);
name = cob_get_buff (f->size + 1);
cob_field_to_string (f, name, f->size, CCM_NONE);

/* check for uncommon leading space - trim it */
if (*buff == ' ') {
if (*name == ' ') {
size_t len;
/* same warning as in cobc/typeck.c */
cob_runtime_warning (
_("'%s' literal includes leading spaces which are omitted"), buff);
len = strlen (buff);
while (*buff == ' ') {
memmove (buff, buff + 1, --len);
_("'%s' literal includes leading spaces which are omitted"), name);
len = strlen (name);
while (*name == ' ') {
memmove (name, name + 1, --len);
}
buff[len] = 0;
name[len] = 0;
}

entry = cob_chk_call_path (buff, &dirent);
entry = cob_chk_call_path (name, &dirent);
cobglobptr->cob_call_name_hash = cob_get_name_hash (entry);

/* Check if contained program - which may override otherwise
Expand Down Expand Up @@ -1367,7 +1367,7 @@ cob_cancel_field (const cob_field *f, const struct cob_call_struct *cs)
return;
}
name = cob_get_buff (f->size + 1);
cob_field_to_string (f, name, f->size);
cob_field_to_string (f, name, f->size, CCM_NONE);
entry = cob_chk_dirp (name);

/* Check if contained program */
Expand Down
200 changes: 197 additions & 3 deletions libcob/cconv.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,76 @@
#include "sysdefines.h"
#include "coblocal.h"

#ifdef HAVE_DESIGNATED_INITS
static const unsigned char lower_tab[256] = {
['a'] = 'A',
['b'] = 'B',
['c'] = 'C',
['d'] = 'D',
['e'] = 'E',
['f'] = 'F',
['g'] = 'G',
['h'] = 'H',
['i'] = 'I',
['j'] = 'J',
['k'] = 'K',
['l'] = 'L',
['m'] = 'M',
['n'] = 'N',
['o'] = 'O',
['p'] = 'P',
['q'] = 'Q',
['r'] = 'R',
['s'] = 'S',
['t'] = 'T',
['u'] = 'U',
['v'] = 'V',
['w'] = 'W',
['x'] = 'X',
['y'] = 'Y',
['z'] = 'Z'
};
static const unsigned char upper_tab[256] = {
['A'] = 'a',
['B'] = 'b',
['C'] = 'c',
['D'] = 'd',
['E'] = 'e',
['F'] = 'f',
['G'] = 'g',
['H'] = 'h',
['I'] = 'i',
['J'] = 'j',
['K'] = 'k',
['L'] = 'l',
['M'] = 'm',
['N'] = 'n',
['O'] = 'o',
['P'] = 'p',
['Q'] = 'q',
['R'] = 'r',
['S'] = 's',
['T'] = 't',
['U'] = 'u',
['V'] = 'v',
['W'] = 'w',
['X'] = 'x',
['Y'] = 'y',
['Z'] = 'z'
};
#else
static unsigned char lower_tab[256];
static unsigned char upper_tab[256];
static const unsigned char plower_tab[] = "abcdefghijklmnopqrstuvwxyz";
static const unsigned char plower_val[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
#endif

static int
cob_convert_hex_digit (char h)
{
if (h >= '0' && h <= '9') return h - '0';
else if (h >= 'A' && h <= 'F') return 10 + h - 'A';
else if (h >= 'a' && h <= 'f') return 10 + h - 'a';
if (h >= '0' && h <= '9') return COB_D2I (h);
h = cob_toupper (h);
if (h >= 'A' && h <= 'F') return 10 + h - 'A';
else return -1;
}

Expand Down Expand Up @@ -171,3 +235,133 @@ cob_load_collation (const char *col_name,

return 0;
}

/* Upper-casing for internal words using efficient 7bit C locale table lookup. */
unsigned char
cob_toupper (const unsigned char c)
{
const unsigned char tab_entry = lower_tab[c];
if (tab_entry) {
return tab_entry;
}
return c;
}

/* Lower-casing for internal words using efficient 7bit C locale table lookup. */
unsigned char
cob_tolower (const unsigned char c)
{
const unsigned char tab_entry = upper_tab[c];
if (tab_entry) {
return tab_entry;
}
return c;
}

/* stores the field's rtrimmed string content into the given buffer
with maxlength, optionally doing upper-/lowercasing on the fly,
returns negative values on error, otherwise size of the data
processed */
int
cob_field_to_string (const cob_field *f, void *str, const size_t maxsize,
const enum cob_case_modifier target_case)
{
register unsigned char *end, *data, *s;

if (f == NULL) {
snprintf (str, maxsize, "%s", ("NULL field"));
return -1;
}

if (f->size == 0) {
return -2;
}
data = f->data;
/* check if field has data assigned (may be a BASED / LINKAGE item) */
if (data == NULL) {
snprintf (str, maxsize, "%s", ("field with NULL address"));
return -3;
}
end = data + f->size - 1;
while (end > data) {
if (*end != ' ' && *end) {
break;
}
end--;
}
s = (unsigned char *)str;
if (*end == ' ' || *end == 0) {
*s = 0;
return 0;
}

/* note: the specified max does not contain the low-value */
if ((size_t)(end - data) > maxsize) {
#if 0 /* Simon: it is likely not a good idea to just ignore the data */
end = data + maxsize;
#else
return -4;
#endif
}
switch (target_case) {
case CCM_NONE:
while (data <= end) {
*s++ = *data++;
}
break;
case CCM_LOWER:
while (data <= end) {
*s++ = cob_tolower (*data++);
}
break;
case CCM_UPPER:
while (data <= end) {
*s++ = cob_toupper (*data++);
}
break;
case CCM_LOWER_LOCALE:
while (data <= end) {
*s++ = tolower (*data++);
}
break;
case CCM_UPPER_LOCALE:
while (data <= end) {
*s++ = toupper (*data++);
}
break;
}
*s = 0;
return end + 1 - f->data;
}


#ifndef HAVE_DESIGNATED_INITS
/* initialize the 7bit upper/lower table */
static void
init_upper_lower (void)
{
const unsigned char *p, *v;

memset (lower_tab, 0, sizeof (lower_tab));
v = plower_val;
p = plower_tab;
for (; *p; ++p, ++v) {
lower_tab[*p] = *v;
}
memset (upper_tab, 0, sizeof (upper_tab));
p = plower_val;
v = plower_tab;
for (; *p; ++p, ++v) {
upper_tab[*p] = *v;
}
}
#endif


void
cob_init_cconv (cob_global *lptr)
{
#ifndef HAVE_DESIGNATED_INITS
init_upper_lower ();
#endif
}
15 changes: 13 additions & 2 deletions libcob/coblocal.h
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ struct config_tbl {
COB_EXPIMP const char * cob_io_version (const int, const int);
COB_EXPIMP const char * cob_io_name (const int);
COB_HIDDEN void cob_init_numeric (cob_global *);
COB_HIDDEN void cob_init_cconv (cob_global *);
COB_HIDDEN void cob_init_termio (cob_global *, cob_settings *);
COB_HIDDEN void cob_init_fileio (cob_global *, cob_settings *);
COB_HIDDEN void cob_init_reportio (cob_global *, cob_settings *);
Expand Down Expand Up @@ -460,10 +461,20 @@ COB_HIDDEN void cob_add_exception (const int);
COB_HIDDEN int cob_check_env_true (char*);
COB_HIDDEN int cob_check_env_false (char*);
COB_HIDDEN const char *cob_get_last_exception_name (void);
COB_EXPIMP void cob_field_to_string (const cob_field *, void *,
const size_t);
COB_HIDDEN void cob_parameter_check (const char *, const int);

enum cob_case_modifier {
CCM_NONE,
CCM_LOWER,
CCM_UPPER,
CCM_LOWER_LOCALE,
CCM_UPPER_LOCALE
};
COB_HIDDEN unsigned char cob_toupper (const unsigned char);
COB_HIDDEN unsigned char cob_tolower (const unsigned char);
COB_EXPIMP int cob_field_to_string (const cob_field *, void *,
const size_t, const enum cob_case_modifier target_case);

COB_HIDDEN cob_settings *cob_get_settings_ptr (void);
COB_HIDDEN char *cob_strndup (const char *, const size_t);

Expand Down
Loading

0 comments on commit 01b3b1e

Please sign in to comment.