>From f89a50238de62b73d9fc44ee7226461650ab119d Tue 18 Feb 2025 04:19:13 PM EST
From: "James K. Lowden" <[email protected]>
Date: Tue 18 Feb 2025 04:19:13 PM EST
Subject: [PATCH] COBOL 11/14 84K lhd: libgcobol header files
libgcobol/ChangeLog
* /charmaps.h: New file.
* /common-defs.h: New file.
* /ec.h: New file.
* /exceptl.h: New file.
* /gcobolio.h: New file.
* /gfileio.h: New file.
* /gmath.h: New file.
* /io.h: New file.
* /libgcobol.h: New file.
* /valconv.h: New file.
---
libgcobol/charmaps.h |
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
libgcobol/common-defs.h |
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
libgcobol/ec.h |
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
libgcobol/exceptl.h |
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
libgcobol/gcobolio.h |
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
libgcobol/gfileio.h | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
libgcobol/gmath.h | ++++++++++++++++++++++++++++++++++++++-
libgcobol/io.h |
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
libgcobol/libgcobol.h |
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
libgcobol/valconv.h |
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10 files changed, 2017 insertions(+), 10 deletions(-)
diff --git a/libgcobol/charmaps.h b/libgcobol/charmaps.h
new file mode 100644
index 00000000000..64270c6f08c
--- /dev/null
+++ b/libgcobol/charmaps.h
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 2021-2025 Symas Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of the Symas Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CHARMAPS_H
+#define CHARMAPS_H
+
+#include <unistd.h>
+
+/* There are four distinct codeset domains in the COBOL compiler.
+ *
+ * First is the codeset of the console. Established by looking at what
+ * setlocale() reports, this can be either UTF-8 or some ASCII based code
+ * page. (We assume CP1252). Data coming from the console or the system,
+ * ACCEPT statements; redirected console input, getenv() and other system
+ * calls are in the "console" domain.
+ *
+ * Second is the internal single-byte-coded codeset of the data, in memory,
+ * being manipulated by the generated code of the cobol executable. The
actual
+ * codeset of "internal" is either EBCDIC (in the form of Code Page 1140 or
+ * ASCII (Code Page 1252)
+ *
+ * Third is the C++ source code of the GCOBOL compiler; this comment is
+ * in that environment. We neither know, nor care, if this code is encoded in
+ * in UTF-8 (as is probable, in these enlighted days of 2022) or something
like
+ * Code Page1252. We are going to regard it as "ascii" under the
+ * assumption that there is no reason for any character in the compiler's
+ * source code to have a code point outside of the plain vanilla 0x20 through
+ * 0x7F range.
+ *
+ * Fourth is the "raw" COBOL source code that is the input to the GCOBOL
+ * compiler. This domain can be either UTF-8 or something like CodePage1252.
+ * Which encoding is relevant; The literal string MOVE "<euro>1234" is seven
+ * bytes long in UTF-8, and five bytes long in CP1252. We start with an
+ * assumption that it is UTF-8 and switch to CP1252 upon encountering a byte
+ * sequence with values above 0x80 that can't be UTF-8. We have provision for
+ * forcing it to be one or the other. Codepoints in that domain are
referenced
+ * as "raw". Codepoint in the "raw" domain don't last long; they are be
+ * converted to either "ascii" or "internal" early on, as necessary.
+ */
+
+
+/* Notes on character codesets:
+
+ This library is implemented to handle "native" codesets of either ASCII (in
+ the form of a single-byte-coded codeset like code page 1252) or EBCDIC (in
+ the form of a single-byte-coded codeset like code page 1140).
+
+ This C/C++ source code, however, is assumed to be an ASCII-based codeset,
+ so that a character constant like a space is assumed to encode as 0x20.
+
+ Furthermore, we assume that the codeset of the COBOL source code being
+ compiled is also ASCII-based, even if it is actually UTF-8. Said another
+ way, characters encoded between zero and 127 are regarded as ASCII.
+
+ This means that we are not going to try to compile EBCDIC COBOL source
code;
+ any such will have to be externally converted to ASCII before feeding it
+ through this compiler on an ASCII based Linux system.
+
+ This situation is rife for confusion here in the source code for the
+ library.
+
+ To help reduce that confusion, we are going to eschew character constants
+ in the C/C++ source code. Instead, we use symbolic versions. In general,
+ "source_space" means 0x20, while "internal_space" will be either 0x20
+ when using the ASCII-based native codeset, or it will be 0x40 when using
+ the EBCDIC-based native codeset.
+
+ Maintaining one's sanity while learning and working with this C/C++ code
+ will require a firm grip on context. You'll have to keep track of whether
+ the character is being used to analyze the ASCII-based COBOL source, or
+ whether the character in question is part of the native COBOL cobol data
+ that is being analyzed or generated.
+
+ For example, when a PICTURE string has in it a source_nine, the generated
+ result in the variable is based on character_zero.
+
+ Stay alert! */
+
+
+extern bool __gg__ebcdic_codeset_in_use;
+#define internal_is_ebcdic (__gg__ebcdic_codeset_in_use)
+
+extern unsigned short const *__gg__internal_codeset_map;
+
+#define NULLCH ('\0')
+#define DEGENERATE_HIGH_VALUE 0xFF
+#define DEGENERATE_LOW_VALUE 0x00
+
+#define ascii_A ((uint8_t)('A'))
+#define ascii_B ((uint8_t)('B'))
+#define ascii_C ((uint8_t)('C'))
+#define ascii_D ((uint8_t)('D'))
+#define ascii_E ((uint8_t)('E'))
+#define ascii_F ((uint8_t)('F'))
+#define ascii_G ((uint8_t)('G'))
+#define ascii_H ((uint8_t)('H'))
+#define ascii_I ((uint8_t)('I'))
+#define ascii_J ((uint8_t)('J'))
+#define ascii_K ((uint8_t)('K'))
+#define ascii_L ((uint8_t)('L'))
+#define ascii_M ((uint8_t)('M'))
+#define ascii_N ((uint8_t)('N'))
+#define ascii_O ((uint8_t)('O'))
+#define ascii_P ((uint8_t)('P'))
+#define ascii_Q ((uint8_t)('Q'))
+#define ascii_R ((uint8_t)('R'))
+#define ascii_S ((uint8_t)('S'))
+#define ascii_T ((uint8_t)('T'))
+#define ascii_U ((uint8_t)('U'))
+#define ascii_V ((uint8_t)('V'))
+#define ascii_W ((uint8_t)('W'))
+#define ascii_X ((uint8_t)('X'))
+#define ascii_Y ((uint8_t)('Y'))
+#define ascii_Z ((uint8_t)('Z'))
+#define ascii_a ((uint8_t)('a'))
+#define ascii_b ((uint8_t)('b'))
+#define ascii_c ((uint8_t)('c'))
+#define ascii_d ((uint8_t)('d'))
+#define ascii_e ((uint8_t)('e'))
+#define ascii_f ((uint8_t)('f'))
+#define ascii_g ((uint8_t)('g'))
+#define ascii_h ((uint8_t)('h'))
+#define ascii_i ((uint8_t)('i'))
+#define ascii_j ((uint8_t)('j'))
+#define ascii_k ((uint8_t)('k'))
+#define ascii_l ((uint8_t)('l'))
+#define ascii_m ((uint8_t)('m'))
+#define ascii_n ((uint8_t)('n'))
+#define ascii_o ((uint8_t)('o'))
+#define ascii_p ((uint8_t)('p'))
+#define ascii_q ((uint8_t)('q'))
+#define ascii_r ((uint8_t)('r'))
+#define ascii_s ((uint8_t)('s'))
+#define ascii_t ((uint8_t)('t'))
+#define ascii_u ((uint8_t)('u'))
+#define ascii_v ((uint8_t)('v'))
+#define ascii_w ((uint8_t)('w'))
+#define ascii_x ((uint8_t)('x'))
+#define ascii_y ((uint8_t)('y'))
+#define ascii_z ((uint8_t)('z'))
+#define ascii_space ((uint8_t)(' '))
+#define ascii_zero ((uint8_t)('0'))
+#define ascii_0 ((uint8_t)('0'))
+#define ascii_1 ((uint8_t)('1'))
+#define ascii_2 ((uint8_t)('2'))
+#define ascii_3 ((uint8_t)('3'))
+#define ascii_4 ((uint8_t)('4'))
+#define ascii_5 ((uint8_t)('5'))
+#define ascii_6 ((uint8_t)('6'))
+#define ascii_7 ((uint8_t)('7'))
+#define ascii_8 ((uint8_t)('8'))
+#define ascii_9 ((uint8_t)('9'))
+#define ascii_nine ((uint8_t)('9'))
+#define ascii_period ((uint8_t)('.'))
+#define ascii_colon ((uint8_t)(':'))
+#define ascii_comma ((uint8_t)(','))
+#define ascii_dquote ((uint8_t)('"'))
+#define ascii_oparen ((uint8_t)('('))
+#define ascii_caret ((uint8_t)('^'))
+#define ascii_slash ((uint8_t)('/'))
+#define ascii_plus ((uint8_t)('+'))
+#define ascii_minus ((uint8_t)('-'))
+#define ascii_hyphen ((uint8_t)('-'))
+#define ascii_underscore ((uint8_t)('_'))
+#define ascii_asterisk ((uint8_t)('*'))
+#define ascii_query ((uint8_t)('?'))
+#define ascii_cr ((uint8_t)('\r'))
+#define ascii_ff ((uint8_t)('\f'))
+#define ascii_newline ((uint8_t)('\n'))
+#define ascii_return ((uint8_t)('\r'))
+
+#define internal_space ((uint8_t)__gg__internal_codeset_map[ascii_space])
+#define internal_zero ((uint8_t)__gg__internal_codeset_map[ascii_zero])
+#define internal_period ((uint8_t)__gg__internal_codeset_map[ascii_period])
+#define internal_comma ((uint8_t)__gg__internal_codeset_map[ascii_comma])
+#define internal_dquote ((uint8_t)__gg__internal_codeset_map[ascii_dquote])
+#define internal_asterisk
((uint8_t)__gg__internal_codeset_map[ascii_asterisk])
+#define internal_plus ((uint8_t)__gg__internal_codeset_map[ascii_plus])
+#define internal_minus ((uint8_t)__gg__internal_codeset_map[ascii_minus])
+#define internal_cr ((uint8_t)__gg__internal_codeset_map[ascii_cr])
+#define internal_ff ((uint8_t)__gg__internal_codeset_map[ascii_ff])
+#define internal_newline ((uint8_t)__gg__internal_codeset_map[ascii_newline])
+#define internal_return ((uint8_t)__gg__internal_codeset_map[ascii_return])
+#define internal_0 ((uint8_t)__gg__internal_codeset_map[ascii_0])
+#define internal_1 ((uint8_t)__gg__internal_codeset_map[ascii_1])
+#define internal_2 ((uint8_t)__gg__internal_codeset_map[ascii_2])
+#define internal_3 ((uint8_t)__gg__internal_codeset_map[ascii_3])
+#define internal_4 ((uint8_t)__gg__internal_codeset_map[ascii_4])
+#define internal_5 ((uint8_t)__gg__internal_codeset_map[ascii_5])
+#define internal_6 ((uint8_t)__gg__internal_codeset_map[ascii_6])
+#define internal_7 ((uint8_t)__gg__internal_codeset_map[ascii_7])
+#define internal_8 ((uint8_t)__gg__internal_codeset_map[ascii_8])
+#define internal_9 ((uint8_t)__gg__internal_codeset_map[ascii_9])
+#define internal_colon ((uint8_t)__gg__internal_codeset_map[ascii_colon])
+#define internal_query ((uint8_t)__gg__internal_codeset_map[ascii_query])
+#define internal_A ((uint8_t)__gg__internal_codeset_map[ascii_A])
+#define internal_B ((uint8_t)__gg__internal_codeset_map[ascii_B])
+#define internal_C ((uint8_t)__gg__internal_codeset_map[ascii_C])
+#define internal_D ((uint8_t)__gg__internal_codeset_map[ascii_D])
+#define internal_E ((uint8_t)__gg__internal_codeset_map[ascii_E])
+#define internal_F ((uint8_t)__gg__internal_codeset_map[ascii_F])
+#define internal_G ((uint8_t)__gg__internal_codeset_map[ascii_G])
+#define internal_H ((uint8_t)__gg__internal_codeset_map[ascii_H])
+#define internal_I ((uint8_t)__gg__internal_codeset_map[ascii_I])
+#define internal_J ((uint8_t)__gg__internal_codeset_map[ascii_J])
+#define internal_K ((uint8_t)__gg__internal_codeset_map[ascii_K])
+#define internal_L ((uint8_t)__gg__internal_codeset_map[ascii_L])
+#define internal_M ((uint8_t)__gg__internal_codeset_map[ascii_M])
+#define internal_N ((uint8_t)__gg__internal_codeset_map[ascii_N])
+#define internal_O ((uint8_t)__gg__internal_codeset_map[ascii_O])
+#define internal_P ((uint8_t)__gg__internal_codeset_map[ascii_P])
+#define internal_Q ((uint8_t)__gg__internal_codeset_map[ascii_Q])
+#define internal_R ((uint8_t)__gg__internal_codeset_map[ascii_R])
+#define internal_S ((uint8_t)__gg__internal_codeset_map[ascii_S])
+#define internal_T ((uint8_t)__gg__internal_codeset_map[ascii_T])
+#define internal_U ((uint8_t)__gg__internal_codeset_map[ascii_U])
+#define internal_V ((uint8_t)__gg__internal_codeset_map[ascii_V])
+#define internal_W ((uint8_t)__gg__internal_codeset_map[ascii_W])
+#define internal_X ((uint8_t)__gg__internal_codeset_map[ascii_X])
+#define internal_Y ((uint8_t)__gg__internal_codeset_map[ascii_Y])
+#define internal_Z ((uint8_t)__gg__internal_codeset_map[ascii_Z])
+#define internal_a ((uint8_t)__gg__internal_codeset_map[ascii_a])
+#define internal_b ((uint8_t)__gg__internal_codeset_map[ascii_b])
+#define internal_c ((uint8_t)__gg__internal_codeset_map[ascii_c])
+#define internal_d ((uint8_t)__gg__internal_codeset_map[ascii_d])
+#define internal_e ((uint8_t)__gg__internal_codeset_map[ascii_e])
+#define internal_f ((uint8_t)__gg__internal_codeset_map[ascii_f])
+#define internal_g ((uint8_t)__gg__internal_codeset_map[ascii_g])
+#define internal_h ((uint8_t)__gg__internal_codeset_map[ascii_h])
+#define internal_i ((uint8_t)__gg__internal_codeset_map[ascii_i])
+#define internal_j ((uint8_t)__gg__internal_codeset_map[ascii_j])
+#define internal_k ((uint8_t)__gg__internal_codeset_map[ascii_k])
+#define internal_l ((uint8_t)__gg__internal_codeset_map[ascii_l])
+#define internal_m ((uint8_t)__gg__internal_codeset_map[ascii_m])
+#define internal_n ((uint8_t)__gg__internal_codeset_map[ascii_n])
+#define internal_o ((uint8_t)__gg__internal_codeset_map[ascii_o])
+#define internal_p ((uint8_t)__gg__internal_codeset_map[ascii_p])
+#define internal_q ((uint8_t)__gg__internal_codeset_map[ascii_q])
+#define internal_r ((uint8_t)__gg__internal_codeset_map[ascii_r])
+#define internal_s ((uint8_t)__gg__internal_codeset_map[ascii_s])
+#define internal_t ((uint8_t)__gg__internal_codeset_map[ascii_t])
+#define internal_u ((uint8_t)__gg__internal_codeset_map[ascii_u])
+#define internal_v ((uint8_t)__gg__internal_codeset_map[ascii_v])
+#define internal_w ((uint8_t)__gg__internal_codeset_map[ascii_w])
+#define internal_x ((uint8_t)__gg__internal_codeset_map[ascii_x])
+#define internal_y ((uint8_t)__gg__internal_codeset_map[ascii_y])
+#define internal_z ((uint8_t)__gg__internal_codeset_map[ascii_z])
+
+
+enum text_device_t
+ {
+ td_default_e,
+ td_sourcecode_e,
+ td_console_e,
+ };
+
+enum text_codeset_t
+ {
+ cs_default_e,
+ cs_utf8_e,
+ cs_cp1252_e,
+ cs_cp1140_e
+ };
+
+
+extern unsigned char __gg__data_space[1] ;
+extern unsigned char __gg__data_low_values[1] ;
+extern unsigned char __gg__data_zeros[1] ;
+extern unsigned char __gg__data_high_values[1] ;
+extern unsigned char __gg__data_quotes[1] ;
+extern unsigned char __gg__data_upsi_0[2] ;
+extern unsigned char __gg__data_return_code[2] ;
+
+// These are the various hardcoded tables used for conversions.
+extern const unsigned short __gg__one_to_one_values[256];
+extern const unsigned short __gg__cp1252_to_cp1140_values[256];
+extern const unsigned short __gg__cp1140_to_cp1252_values[256];
+
+// These are the two standard collations.
+extern const unsigned short __gg__cp1252_to_ebcdic_collation[256];
+extern const unsigned short __gg__ebcdic_to_cp1252_collation[256];
+
+// As described above, we have a number of operations we need to accomplish.
But
+// the actual routines are dependent on whether EBCDIC or ASCII is in use. We
+// implement that by having a function pointer for each function; those
pointers
+// are established when the __gg__ebcdic_codeset_in_use variable is
established.
+
+// These routines convert a single ASCII character to either ASCII or EBCDIC
+
+extern "C"
+char __gg__ascii_to_ascii_chr(char ch);
+extern "C"
+char __gg__ascii_to_ebcdic_chr(char ch);
+extern "C"
+char (*__gg__ascii_to_internal_chr)(char);
+#define ascii_to_internal(a) ((*__gg__ascii_to_internal_chr)(a))
+
+extern "C"
+void __gg__ascii_to_ascii(char *str, size_t length);
+extern "C"
+void __gg__ascii_to_ebcdic(char *str, size_t length);
+extern "C"
+void (*__gg__ascii_to_internal_str)(char *str, size_t length);
+#define ascii_to_internal_str(a, b) ((*__gg__ascii_to_internal_str)((a), (b)))
+
+extern "C"
+char *__gg__raw_to_ascii(char **dest, size_t *dest_size, const char *str,
size_t length);
+extern "C"
+char *__gg__raw_to_ebcdic(char **dest, size_t *dest_size, const char *in,
size_t length);
+extern "C"
+char *(*__gg__raw_to_internal)(char **dest, size_t *dest_length, const char
*in, size_t length);
+#define raw_to_internal(a, b, c, d) ((*__gg__raw_to_internal)((a), (b), (c),
(d)))
+
+extern "C"
+char *__gg__ascii_to_console(char **dest, size_t *dest_size, char const *
const str, const size_t length);
+extern "C"
+char *__gg__ebcdic_to_console(char **dest, size_t *dest_size, char const *
const str, const size_t length);
+extern "C"
+char *(*__gg__internal_to_console_cm)(char **dest, size_t *dest_size, const
char *in, size_t length);
+#define internal_to_console(a, b, c, d) ((*__gg__internal_to_console_cm)((a),
(b), (c), (d)))
+
+extern "C"
+void __gg__console_to_ascii(char * const str, size_t length);
+extern "C"
+void __gg__console_to_ebcdic(char * const str, size_t length);
+extern "C"
+void (*__gg__console_to_internal_cm)(char * const str, size_t length);
+#define console_to_internal(a, b) ((*__gg__console_to_internal_cm)((a), (b)))
+
+extern "C"
+void __gg__ebcdic_to_ascii(char *str, const size_t length);
+extern "C"
+void (*__gg__internal_to_ascii)(char *str, size_t length);
+#define internal_to_ascii(a, b) ((*__gg__internal_to_ascii)((a), (b)))
+
+extern "C" void __gg__set_internal_codeset(int use_ebcdic);
+
+extern "C"
+void __gg__text_conversion_override(text_device_t device,
+ text_codeset_t codeset);
+
+#endif
\ No newline at end of file
diff --git a/libgcobol/common-defs.h b/libgcobol/common-defs.h
new file mode 100644
index 00000000000..ebb4e8bd806
--- /dev/null
+++ b/libgcobol/common-defs.h
@@ -0,0 +1,496 @@
+/*
+ * Copyright (c) 2021-2025 Symas Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of the Symas Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef COMMON_DEFS_H_
+#define COMMON_DEFS_H_
+
+#include <stdint.h>
+#include <list>
+
+#define COUNT_OF(X) (sizeof(X) / sizeof(X[0]))
+
+// This constant establishes the maximum number of digits in a fixed point
+// number. We are using 37 digits as a maximum because a full-size 37-digit
+// number (10**37) takes 123 bits, and a full-size 38-digit number (10**38)
+// takes 127 bits. By using a maximum of 37, that gives us an additional digit
+// of headroom in order to accomplish rounding.
+
+// You should keep in mind that the _Float128 binary floating point numbers
that
+// we use can reliably reproduce numbers of 33 decimal digits when going to
+// binary and back.
+
+#define MAX_FIXED_POINT_DIGITS (37)
+
+// COBOL tables can have up to seven subscripts
+#define MAXIMUM_TABLE_DIMENSIONS 7
+
+// This bit gets turned on in the first or last byte (depending on the
leading_e attribute
+// phrase) of a NumericDisplay to indicate that the value is negative.
+
+// When running the EBCDIC character set, the meaning of this bit is flipped,
+// because an EBCDIC zero is 0xF0, while ASCII is 0x30
+#define NUMERIC_DISPLAY_SIGN_BIT 0x40
+
+#define LEVEL01 (1)
+#define LEVEL49 (49)
+#define LEVEL77 (77)
+
+// In the __gg__move_literala() call, we piggyback this bit onto the
+// cbl_round_t parameter, just to cut down on the number of parameters passed
+#define REFER_ALL_BIT 0x80
+
+
+/*
+ * User-defined names in IBM COBOL can have at most 30 characters.
+ * For DBCS, the maximum is 14.
+ *
+ * Per ISO/IEC 1989:2023(E), 8.3.2 COBOL words,
+ * "A COBOL word is a character-string of not more than 63 characters"
+ */
+typedef char cbl_name_t[64];
+
+// Note that the field_type enum is duplicated in the source code for the
+// COBOL-aware GDB, and so any changes here (or there) have to be reflected
+// there (or here)
+
+// Note further that if this list changes, then the valid_move() matrix has to
+// change as will. Currently that matrix is in util.cc.
+
+enum cbl_field_type_t {
+ FldInvalid, // uninitialized
+ FldGroup,
+ FldAlphanumeric, // For X(n).
+ FldNumericBinary, // For 999v9 comp big-endian, 1 to 16 bytes
+ FldFloat, // 4-, 8-, and 16-byte floating point. See ieeedec_e
and big_endian_e flags
+ FldPacked, // For 999v9 comp-3 internal decimal, packed
decimal representation;
+ FldNumericBin5, // For 999v9 comp-5 little-endian, 1 to 16 bytes.
(Native binary)
+ FldNumericDisplay, // For 999v9 one decimal character per byte
+ FldNumericEdited, // For 999.9 PIC BPVZ90/,.+-CRDB*cs; must
have one of B/Z0,.*+-CRDBcs
+ FldAlphaEdited, // PIC AX9B0/; must have at least
one A or X, and at least one B0/
+ FldLiteralA, // Alphanumeric literal
+ FldLiteralN, // Numeric literal
+ FldClass,
+ FldConditional, // Target for parser_relop()
+ FldForward,
+ FldIndex,
+ FldSwitch,
+ FldDisplay,
+ FldPointer,
+ FldBlob,
+};
+
+
+/* BINARY, COMP, COMPUTATIONAL, COMP-4, COMPUTATIONAL-4 are the same:
+ * Storage, by default, is big-endian.
+ * PIC 9(1 to 4) is 2 bytes
+ * PIC 9(5 to 9) is 4 bytes
+ * PIC 9(10 to 18) is 8 bytes
+ * PIC 9(19-37) is 16 bytes
+ * COMP-1, COMPUTATIONAL-1
+ * 4-byte floating point (single)
+ * COMP-2, COMPUTATIONAL-2
+ * 8-byte floating point (double)
+ * PACKED-DECIMAL, COMP-3, COMPUTATIONAL-3
+ * Packed decimal. Final nybble is 0xF for unsigned numbers. For signable
+ * values, it is 0xD for negative, and 0xC for
non-negative
+ * COMP-5, COMPUTATIONAL-5
+ * Native binary. The maximum number of digits is implied by
+ * the 2, 4, or 8 bytes of data storage. By "native", little-endian
+ * is implied on Intel processors.
+ */
+
+/*
+ * Enumerated bit mask of variable attributes.
+ * A field as either left- or right-justified.
+ * A field is padded (in the unjustified direction) either with 0 or SPC.
+ * (But maybe the fill character should just be an explicit character.)
+ */
+enum cbl_field_attr_t : size_t {
+ none_e = 0x0000000000,
+ figconst_1_e = 0x0000000001, // This needs to be 1 - don't change the
position
+ figconst_2_e = 0x0000000002, // This needs to be 2
+ figconst_4_e = 0x0000000004, // This needs to be 4
+ rjust_e = 0x0000000008, // justify right
+ ljust_e = 0x0000000010, // justify left
+ zeros_e = 0x0000000020, // zero fill
+ signable_e = 0x0000000040,
+ constant_e = 0x0000000080, // pre-assigned constant
+ function_e = 0x0000000100,
+ quoted_e = 0x0000000200,
+ filler_e = 0x0000000400,
+ _spare_e = 0x0000000800, //
+ intermediate_e = 0x0000001000, // Compiler-defined temporary variable
+ embiggened_e = 0x0000002000, // redefined numeric made 64-bit by USAGE
POINTER
+ all_alpha_e = 0x0000004000, // FldAlphanumeric, but all A's
+ all_x_e = 0x0000008000, // picture is all X's
+ all_ax_e = 0x000000a000, // picture is all A's or all X's
+ prog_ptr_e = 0x0000010000, // FUNCTION-POINTER or PROGRAM-POINTER
+ scaled_e = 0x0000020000,
+ refmod_e = 0x0000040000, // Runtime; indicates a refmod is active
+ based_e = 0x0000080000, // pointer capacity, for ADDRESS OF or
ALLOCATE
+ any_length_e = 0x0000100000, // inferred length of linkage in nested
program
+ global_e = 0x0000200000, // field has global scope
+ external_e = 0x0000400000, // field has external scope
+ blank_zero_e = 0x0000800000, // BLANK WHEN ZERO
+ // data division uses 2 low bits of high byte
+ linkage_e = 0x0001000000, // field is in linkage section
+ local_e = 0x0002000000, // field is in local section
+ leading_e = 0x0004000000, // leading sign (signable_e alone means
trailing)
+ separate_e = 0x0008000000, // separate sign
+ envar_e = 0x0010000000, // names an environment variable
+ dnu_1_e = 0x0020000000, // unused: this attribute bit is available
+ bool_encoded_e = 0x0040000000, // data.initial is a boolean string
+ hex_encoded_e = 0x0080000000, // data.initial is a hex-encoded string
+ depends_on_e = 0x0100000000, // A group hierachy contains a DEPENDING_ON
+ initialized_e = 0x0200000000, // Don't call parser_initialize from
parser_symbol_add
+ has_value_e = 0x0400000000, // Flag to hierarchical descendents to
ignore .initial
+ ieeedec_e = 0x0800000000, // Indicates a FldFloat is IEEE 754
decimal, rather than binary
+ big_endian_e = 0x1000000000, // Indicates a value is big-endian
+ same_as_e = 0x2000000000, // Field produced by SAME AS (cannot take
new members)
+ record_key_e = 0x4000000000,
+ typedef_e = 0x8000000000, // IS TYPEDEF
+ strongdef_e = typedef_e + intermediate_e, // STRONG TYPEDEF (not
temporary)
+};
+enum cbl_figconst_t
+ {
+ normal_value_e = 0, // This one must be zero
+ low_value_e = 1, // The order is important, because
+ null_value_e = 2,
+ zero_value_e = 3, // at times we compare, for example, low_value_e to
+ space_value_e = 4,
+ quote_value_e = 5, //
+ high_value_e = 6, // high_value_e to determine that low is less than high
+ };
+#define FIGCONST_MASK (figconst_1_e|figconst_2_e|figconst_4_e)
+#define DATASECT_MASK (linkage_e | local_e)
+
+enum cbl_file_org_t {
+ file_disorganized_e,
+ file_sequential_e,
+ file_line_sequential_e,
+ file_indexed_e,
+ file_relative_e,
+};
+
+enum cbl_file_access_t {
+ file_inaccessible_e,
+ file_access_seq_e,
+ file_access_rnd_e,
+ file_access_dyn_e,
+};
+
+enum cbl_file_mode_t {
+ file_mode_none_e,
+ file_mode_input_e = 'r',
+ file_mode_output_e = 'w',
+ file_mode_extend_e = 'a',
+ file_mode_io_e = '+',
+};
+
+enum cbl_round_t {
+ away_from_zero_e,
+ nearest_toward_zero_e,
+ toward_greater_e,
+ toward_lesser_e,
+ nearest_away_from_zero_e,
+ nearest_even_e,
+ prohibited_e,
+ truncation_e,
+};
+
+#define RELOP_START 0
+enum relop_t {
+ lt_op = RELOP_START,
+ le_op,
+ eq_op,
+ ne_op,
+ ge_op,
+ gt_op,
+};
+
+#define LOGOP_START 100
+enum logop_t {
+ not_op = LOGOP_START,
+ and_op,
+ or_op,
+ xor_op,
+ xnor_op,
+ true_op,
+ false_op,
+};
+
+#define SETOP_START 200
+enum setop_t {
+ is_op = SETOP_START,
+};
+
+enum bitop_t {
+ bit_set_op, // set bit on
+ bit_clear_op, // set bit off
+ bit_on_op, // true if bit is on
+ bit_off_op, // true if bit is off
+ bit_and_op,
+ bit_or_op,
+ bit_xor_op,
+};
+
+enum file_close_how_t {
+ file_close_no_how_e = 0x00,
+ file_close_removal_e = 0x01,
+ file_close_no_rewind_e = 0x02,
+ file_close_with_lock_e = 0x04,
+ file_close_reel_unit_e = 0x08,
+};
+
+enum cbl_compute_error_code_t {
+ compute_error_none = 0x0000,
+ compute_error_truncate = 0x0001,
+ compute_error_divide_by_zero = 0x0002,
+ compute_error_exp_zero_by_zero = 0x0004,
+ compute_error_exp_zero_by_minus = 0x0008,
+ compute_error_exp_minus_by_frac = 0x0010,
+ compute_error_overflow = 0x0020,
+ compute_error_underflow = 0x0040,
+};
+
+enum cbl_arith_format_t {
+ not_expected_e,
+ no_giving_e, giving_e,
+ corresponding_e };
+
+enum cbl_encoding_t {
+ ASCII_e, // STANDARD-1 (in caps to avoid conflict with ascii_e in
libgcobol.cc)
+ iso646_e, // STANDARD-2
+ EBCDIC_e, // NATIVE or EBCDIC
+ custom_encoding_e,
+};
+
+enum cbl_truncation_mode {
+ trunc_std_e,
+ trunc_opt_e,
+ trunc_bin_e,
+};
+
+enum cbl_inspect_bound_t {
+ bound_characters_e,
+ bound_all_e,
+ bound_first_e,
+ bound_leading_e,
+ bound_trailing_e,
+};
+
+// a SPECIAL-NAME
+enum special_name_t {
+ SYSIN_e, SYSIPT_e, SYSOUT_e,
+ SYSLIST_e, SYSLST_e,
+ SYSPUNCH_e, SYSPCH_e,
+ CONSOLE_e,
+ C01_e, C02_e, C03_e, C04_e, C05_e, C06_e,
+ C07_e, C08_e, C09_e, C10_e, C11_e, C12_e,
+ CSP_e,
+ S01_e, S02_e, S03_e, S04_e, S05_e,
+ AFP_5A_e,
+ STDIN_e, STDOUT_e, STDERR_e, SYSERR_e,
+ ARG_NUM_e, ARG_VALUE_e, ENV_NAME_e, ENV_VALUE_e,
+};
+
+enum classify_t {
+ ClassInvalidType,
+ ClassNumericType,
+ ClassAlphabeticType,
+ ClassLowerType,
+ ClassUpperType,
+ ClassDbcsType,
+ ClassKanjiType,
+};
+
+static inline const char *
+classify_str( enum classify_t classify ) {
+ switch(classify) {
+ case ClassInvalidType: return "ClassInvalidType";
+ case ClassNumericType: return "ClassNumericType";
+ case ClassAlphabeticType: return "ClassAlphabeticType";
+ case ClassLowerType: return "ClassLowerType";
+ case ClassUpperType: return "ClassUpperType";
+ case ClassDbcsType: return "ClassDbcsType";
+ case ClassKanjiType: return "ClassKanjiType";
+ };
+ return "(unknown classification)";
+}
+
+static inline const char *
+cbl_file_mode_str( cbl_file_mode_t mode ) {
+ switch(mode) {
+ case file_mode_none_e: return "file_mode_none_e";
+ case file_mode_input_e: return "file_mode_input_e: 'r'";
+ case file_mode_output_e: return "file_mode_output_e: 'w'";
+ case file_mode_io_e: return "file_mode_io_e: '+'";
+ case file_mode_extend_e: return "file_mode_extend_e: 'a'";
+ }
+ return "???";
+};
+
+enum module_type_t {
+ module_activating_e,
+ module_current_e,
+ module_nested_e,
+ module_stack_e,
+ module_toplevel_e,
+};
+
+
+static inline bool
+ec_cmp( ec_type_t raised, ec_type_t mask )
+{
+ if( raised == mask ) return true;
+
+ // Do not match on only the low byte.
+ if( 0 < (~EC_ALL_E & static_cast<uint32_t>(mask)) ) return false;
+
+ return 0 != ( static_cast<uint32_t>(raised)
+ &
+ static_cast<uint32_t>(mask) );
+}
+
+struct cbl_enabled_exception_t {
+ bool enabled, location;
+ ec_type_t ec;
+ size_t file;
+
+ cbl_enabled_exception_t()
+ : enabled(false)
+ , location(false)
+ , ec(ec_none_e)
+ , file(0)
+ {}
+
+ cbl_enabled_exception_t( bool enabled, bool location,
+ ec_type_t ec, size_t file = 0 )
+ : enabled(enabled)
+ , location(location)
+ , ec(ec)
+ , file(file)
+ {}
+
+ // sort by ec and file, not enablement
+ bool operator<( const cbl_enabled_exception_t& that ) const {
+ if( ec == that.ec ) return file < that.file;
+ return ec < that.ec;
+ }
+ // match on ec and file, not enablement
+ bool operator==( const cbl_enabled_exception_t& that ) const {
+ return ec == that.ec && file == that.file;
+ }
+};
+
+
+class cbl_enabled_exceptions_array_t;
+
+class cbl_enabled_exceptions_t : protected std::set<cbl_enabled_exception_t>
+{
+ friend cbl_enabled_exceptions_array_t;
+ void apply( const cbl_enabled_exception_t& elem ) {
+ auto inserted = insert( elem );
+ if( ! inserted.second ) {
+ erase(inserted.first);
+ insert(elem);
+ }
+ }
+
+ public:
+ bool turn_on_off( bool enabled, bool location, ec_type_t type,
+ std::set<size_t> files );
+
+ const cbl_enabled_exception_t * match( ec_type_t type, size_t file = 0 );
+
+ void dump() const;
+
+ void clear() { std::set<cbl_enabled_exception_t>::clear(); }
+
+ bool empty() const { return std::set<cbl_enabled_exception_t>::empty(); }
+ size_t size() const { return std::set<cbl_enabled_exception_t>::size(); }
+
+ cbl_enabled_exceptions_t& operator=( const cbl_enabled_exceptions_t& that ) {
+ std::set<cbl_enabled_exception_t>& self(*this);
+ self = that;
+ return *this;
+ }
+};
+
+extern cbl_enabled_exceptions_t enabled_exceptions;
+
+/*
+ * This class is passed to the runtime function evaluating the raised
exception.
+ * It is constructed in genapi.cc from the compile-time table.
+ */
+struct cbl_enabled_exceptions_array_t {
+ size_t nec;
+ cbl_enabled_exception_t *ecs;
+
+ cbl_enabled_exceptions_array_t( size_t nec, cbl_enabled_exception_t *ecs )
+ : nec(nec), ecs(ecs) {}
+
+ cbl_enabled_exceptions_array_t( const cbl_enabled_exceptions_t& input =
+ cbl_enabled_exceptions_t() )
+ : nec(input.size())
+ , ecs(NULL)
+ {
+ if( ! input.empty() ) {
+ ecs = new cbl_enabled_exception_t[nec];
+ std::copy(input.begin(), input.end(), ecs);
+ }
+ }
+
+ cbl_enabled_exceptions_array_t&
+ operator=( const cbl_enabled_exceptions_array_t& input);
+
+
+ bool match( ec_type_t ec, size_t file = 0 ) const;
+
+ size_t nbytes() const { return nec * sizeof(ecs[0]); }
+};
+
+template <typename T>
+T enabled_exception_match( T beg, T end, ec_type_t type, size_t file ) {
+ cbl_enabled_exception_t input( true, true, // don't matter
+ type, file );
+ auto output = std::find(beg, end, input);
+ if( output == end ) {
+ output = std::find_if( beg, end, // match any file
+ [ec = type]( const cbl_enabled_exception_t& elem ) {
+ return
+ elem.file == 0 &&
+ ec_cmp(ec, elem.ec); } );
+ }
+ return output;
+}
+
+
+
+#endif
diff --git a/libgcobol/ec.h b/libgcobol/ec.h
new file mode 100644
index 00000000000..1e3f7cfa7ea
--- /dev/null
+++ b/libgcobol/ec.h
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2021-2025 Symas Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of the Symas Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CBL_EC_H_
+#define _CBL_EC_H_
+
+#include <set>
+#include <assert.h>
+
+#define EC_ALL_E 0xFFFFFF00
+
+enum ec_type_t {
+ ec_none_e = 0x00000000,
+ ec_all_e = EC_ALL_E, // 0xFFFFFF00
+
+ ec_argument_e = 0x00000100,
+ ec_argument_function_e,
+ ec_argument_imp_e,
+ ec_argument_imp_command_e,
+ ec_argument_imp_environment_e,
+
+ ec_bound_e = 0x00000200,
+ ec_bound_func_ret_value_e,
+ ec_bound_imp_e,
+ ec_bound_odo_e,
+ ec_bound_overflow_e,
+ ec_bound_ptr_e,
+ ec_bound_ref_mod_e,
+ ec_bound_set_e,
+ ec_bound_subscript_e,
+ ec_bound_table_limit_e,
+
+ ec_data_e = 0x00000400,
+ ec_data_conversion_e,
+ ec_data_imp_e,
+ ec_data_incompatible_e,
+ ec_data_not_finite_e,
+ ec_data_overflow_e,
+ ec_data_ptr_null_e,
+
+ ec_external_e = 0x00000800,
+ ec_external_data_mismatch_e,
+ ec_external_file_mismatch_e,
+ ec_external_format_conflict_e,
+
+ ec_flow_e = 0x00001000,
+ ec_flow_global_exit_e,
+ ec_flow_global_goback_e,
+ ec_flow_imp_e,
+ ec_flow_release_e,
+ ec_flow_report_e,
+ ec_flow_return_e,
+ ec_flow_search_e,
+ ec_flow_use_e,
+
+ ec_function_e = 0x00002000,
+ ec_function_not_found_e,
+ ec_function_ptr_invalid_e,
+ ec_function_ptr_null_e,
+
+ ec_io_e = 0x00004000,
+ ec_io_at_end_e,
+ ec_io_invalid_key_e,
+ ec_io_permanent_error_e,
+ ec_io_logic_error_e,
+ ec_io_record_operation_e,
+ ec_io_file_sharing_e,
+ ec_io_record_content_e,
+ ec_io_imp_e,
+ ec_io_eop_e,
+ ec_io_eop_overflow_e,
+ ec_io_linage_e,
+
+ ec_imp_e = 0x00008000,
+ ec_imp_suffix_e,
+
+ ec_locale_e = 0x00010000,
+ ec_locale_imp_e,
+ ec_locale_incompatible_e,
+ ec_locale_invalid_e,
+ ec_locale_invalid_ptr_e,
+ ec_locale_missing_e,
+ ec_locale_size_e,
+
+ ec_oo_e = 0x00020000,
+ ec_oo_arg_omitted_e,
+ ec_oo_conformance_e,
+ ec_oo_exception_e,
+ ec_oo_imp_e,
+ ec_oo_method_e,
+ ec_oo_null_e,
+ ec_oo_resource_e,
+ ec_oo_universal_e,
+
+ ec_order_e = 0x00040000,
+ ec_order_imp_e,
+ ec_order_not_supported_e,
+
+ ec_overflow_e = 0x00080000,
+ ec_overflow_imp_e,
+ ec_overflow_string_e,
+ ec_overflow_unstring_e,
+
+ ec_program_e = 0x00100000,
+ ec_program_arg_mismatch_e,
+ ec_program_arg_omitted_e,
+ ec_program_cancel_active_e,
+ ec_program_imp_e,
+ ec_program_not_found_e,
+ ec_program_ptr_null_e,
+ ec_program_recursive_call_e,
+ ec_program_resources_e,
+
+ ec_raising_e = 0x00200000,
+ ec_raising_imp_e,
+ ec_raising_not_specified_e,
+
+ ec_range_e = 0x00400000,
+ ec_range_imp_e,
+ ec_range_index_e,
+ ec_range_inspect_size_e,
+ ec_range_invalid_e,
+ ec_range_perform_varying_e,
+ ec_range_ptr_e,
+ ec_range_search_index_e,
+ ec_range_search_no_match_e,
+
+ ec_report_e = 0x00800000,
+ ec_report_active_e,
+ ec_report_column_overlap_e,
+ ec_report_file_mode_e,
+ ec_report_imp_e,
+ ec_report_inactive_e,
+ ec_report_line_overlap_e,
+ ec_report_not_terminated_e,
+ ec_report_page_limit_e,
+ ec_report_page_width_e,
+ ec_report_sum_size_e,
+ ec_report_varying_e,
+
+ ec_screen_e = 0x01000000,
+ ec_screen_field_overlap_e,
+ ec_screen_imp_e,
+ ec_screen_item_truncated_e,
+ ec_screen_line_number_e,
+ ec_screen_starting_column_e,
+
+ ec_size_e = 0x02000000,
+ ec_size_address_e,
+ ec_size_exponentiation_e,
+ ec_size_imp_e,
+ ec_size_overflow_e,
+ ec_size_truncation_e,
+ ec_size_underflow_e,
+ ec_size_zero_divide_e,
+
+ ec_sort_merge_e = 0x04000000,
+ ec_sort_merge_active_e,
+ ec_sort_merge_file_open_e,
+ ec_sort_merge_imp_e,
+ ec_sort_merge_release_e,
+ ec_sort_merge_return_e,
+ ec_sort_merge_sequence_e,
+
+ ec_storage_e = 0x08000000,
+ ec_storage_imp_e,
+ ec_storage_not_alloc_e,
+ ec_storage_not_avail_e,
+
+ ec_user_e = 0x10000000,
+ ec_user_suffix_e,
+
+ ec_validate_e = 0x20000000,
+ ec_validate_content_e,
+ ec_validate_format_e,
+ ec_validate_imp_e,
+ ec_validate_relation_e,
+ ec_validate_varying_e,
+
+ ec_continue_e = 0x30000000,
+ ec_continue_less_than_zero,
+};
+
+
+#endif
diff --git a/libgcobol/exceptl.h b/libgcobol/exceptl.h
new file mode 100644
index 00000000000..35809034f4f
--- /dev/null
+++ b/libgcobol/exceptl.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2021-2025 Symas Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of the Symas Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CBL_EXCEPTC_H_
+#define _CBL_EXCEPTC_H_
+
+/* This file contains declarations needed by the libgcobol compilation. Some
+ of the information here is required by the gcc/cobol compilation, and so it
+ is safe to include in those files. */
+
+static const ec_type_t simon_says_important[] = {
+ ec_argument_function_e,
+ ec_bound_odo_e,
+ ec_bound_ref_mod_e,
+ ec_bound_subscript_e,
+ ec_data_incompatible_e,
+ ec_data_ptr_null_e,
+ ec_size_overflow_e,
+ ec_size_exponentiation_e,
+ ec_size_truncation_e,
+ ec_size_zero_divide_e,
+ ec_program_not_found_e,
+ ec_program_recursive_call_e,
+ ec_program_arg_mismatch_e,
+};
+
+enum ec_disposition_t {
+ ec_category_none_e,
+ ec_category_fatal_e,
+ ec_category_nonfatal_e,
+ ec_category_implementor_e,
+
+ // unimplemented equivalents
+ uc_category_none_e = 0x80 + ec_category_none_e,
+ uc_category_fatal_e = 0x80 + ec_category_fatal_e,
+ uc_category_nonfatal_e = 0x80 + ec_category_nonfatal_e,
+ uc_category_implementor_e = 0x80 + ec_category_implementor_e,
+};
+
+struct ec_descr_t {
+ ec_type_t type;
+ ec_disposition_t disposition;
+ const cbl_name_t name;
+ const char *description;
+
+ bool operator==( ec_type_t type ) const {
+ return this->type == type;
+ }
+};
+
+extern ec_type_t ec_type_of( const cbl_name_t name );
+
+extern ec_descr_t __gg__exception_table[];
+extern ec_descr_t *__gg__exception_table_end;
+
+/* Inventory of exceptions:
+ In except.hc::__gg__exception_table, unimplemented ECs have a uc_
disposition.
+
+ ec_function_argument_e ACOS
+ ANNUITY
+ ASIN
+ LOG
+ LOG10
+ PRESENT-VALUE
+ SQRT
+
+ ec_sort_merge_file_open_e FILE MERGE
+
+ ec_bound_subscript_e table subscript not an integer
+ table subscript less than 1
+ table subscript greater than occurs
+
+ ec_bound_ref_mod_e refmod start not an integer
+ refmod start less than 1
+ refmod start greater than variable size
+ refmod length not an integer
+ refmod length less than 1
+ refmod start+length exceeds variable size
+
+ ec_bound_odo_e DEPENDING not an integer
+ DEPENDING greater than occurs upper limit
+ DEPENDING less than occurs lower limit
+ subscript greater than DEPENDING for sending
item
+
+ ec_size_zero_divide_e For both fixed-point and floating-point
division
+
+ ec_size_truncation
+ ec_size_exponentiation
+
+ */
+
+// SymException
+struct cbl_exception_t {
+ size_t program, file;
+ ec_type_t type;
+ cbl_file_mode_t mode;
+};
+
+
+struct cbl_declarative_t {
+ enum { files_max = 16 };
+ size_t section; // implies program
+ bool global;
+ ec_type_t type;
+ uint32_t nfile, files[files_max];
+ cbl_file_mode_t mode;
+
+ cbl_declarative_t( cbl_file_mode_t mode = file_mode_none_e )
+ : section(0), global(false), type(ec_none_e)
+ , nfile(0)
+ , mode(mode)
+ {
+ std::fill(files, files + COUNT_OF(files), 0);
+ }
+ cbl_declarative_t( ec_type_t type )
+ : section(0), global(false), type(type)
+ , nfile(0)
+ , mode(file_mode_none_e)
+ {
+ std::fill(files, files + COUNT_OF(files), 0);
+ }
+
+ cbl_declarative_t( size_t section, ec_type_t type,
+ const std::list<size_t>& files,
+ cbl_file_mode_t mode, bool global = false )
+ : section(section), global(global), type(type)
+ , nfile(files.size())
+ , mode(mode)
+ {
+ assert( files.size() <= COUNT_OF(this->files) );
+ std::fill(this->files, this->files + COUNT_OF(this->files), 0);
+ if( nfile > 0 ) {
+ std::copy( files.begin(), files.end(), this->files );
+ }
+ }
+ cbl_declarative_t( const cbl_declarative_t& that )
+ : section(that.section), global(that.global), type(that.type)
+ , nfile(that.nfile)
+ , mode(that.mode)
+ {
+ std::fill(files, files + COUNT_OF(files), 0);
+ if( nfile > 0 ) {
+ std::copy( that.files, that.files + nfile, this->files );
+ }
+ }
+
+ /*
+ * Sort file names before file modes, and file modes before non-IO.
+ */
+ bool operator<( const cbl_declarative_t& that ) const {
+ // file name declaratives first, in section order
+ if( nfile != 0 ) {
+ if( that.nfile != 0 ) return section < that.section;
+ return true;
+ }
+ // file mode declaratives between file name declaratives and non-IO
+ if( mode != file_mode_none_e ) {
+ if( that.nfile != 0 ) return false;
+ if( that.mode == file_mode_none_e ) return true;
+ return section < that.section;
+ }
+ // all others by section, after names and modes
+ if( that.nfile != 0 ) return false;
+ if( that.mode != file_mode_none_e ) return false;
+ return section < that.section;
+ }
+
+ // TRUE if there are no files to match, or the provided file is in the list.
+ bool match_file( size_t file ) const {
+ static const auto pend = files + nfile;
+
+ return nfile == 0 || pend != std::find(files, files + nfile, file);
+ }
+
+ // USE Format 1 names a file mode, or at least one file, and not an EC.
+ bool is_format_1() const {
+ assert(type != ec_none_e || nfile > 0 || mode != file_mode_none_e);
+ return nfile > 0 || mode != file_mode_none_e;
+ }
+};
+
+
+/*
+ * ec_status_t represents the runtime exception condition status for
+ * any statement. Prior to execution, the generated code
+ * clears "type", and sets "source_file" and "lineno".
+ *
+ * If the statement includes some kind of ON ERROR
+ * clause, the generated code sets "handled" to the exception type
+ * handled by that clause, else it sets "handled" to ec_none_e.
+ *
+ * Post-execution, the generated code sets "type" to the appropriate
+ * exception, if any. The match-exception logic compares any raised
+ * exception to the set of declaratives, and returns a symbol-table
+ * index to the matching declarative, if any.
+ */
+class ec_status_t {
+ char msg[132];
+public:
+ ec_type_t type, handled;
+ cbl_name_t statement; // e.g., "ADD"
+ size_t lineno;
+ const char *source_file;
+
+ ec_status_t()
+ : type(ec_none_e)
+ , handled(ec_none_e)
+ , lineno(0)
+ , source_file(NULL)
+ {
+ msg[0] = statement[0] = '\0';
+ }
+
+ ec_status_t& update();
+ ec_status_t& enable( unsigned int mask );
+
+ const char * exception_location() {
+ snprintf(msg, sizeof(msg), "%s:%zu: '%s'", source_file, lineno, statement);
+ return msg;
+ }
+ ec_type_t unhandled() const {
+ return ec_type_t(static_cast<unsigned int>(type)
+ &
+ ~static_cast<unsigned int>(handled));
+ }
+};
+
+#endif
diff --git a/libgcobol/gcobolio.h b/libgcobol/gcobolio.h
new file mode 100644
index 00000000000..061f24f309d
--- /dev/null
+++ b/libgcobol/gcobolio.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2021-2025 Symas Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of the Symas Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef GCOBOLIO_H_
+#define GCOBOLIO_H_
+
+#include <stdio.h>
+#include <map>
+#include <unordered_map>
+#include <vector>
+
+typedef struct cblc_field_t
+ {
+ // This structure must match the code in structs.cc
+ unsigned char *data; // The runtime data. There is no null
terminator
+ size_t capacity; // The size of "data"
+ size_t allocated; // The number of bytes available for capacity
+ size_t offset; // Offset from our ancestor (see note below)
+ char *name; // The null-terminated name of this variable
+ char *picture; // The null-terminated picture string.
+ char *initial; // The null_terminated initial value
+ struct cblc_field_t *parent;// This field's immediate parent field
+ size_t occurs_lower; // non-zero for a table
+ size_t occurs_upper; // non-zero for a table
+ size_t attr; // See cbl_field_attr_t
+ signed char type; // A one-byte copy of cbl_field_type_t
+ signed char level; // This variable's level in the naming
heirarchy
+ signed char digits; // Digits specified in PIC string; e.g. 5 for
99v999
+ signed char rdigits; // Digits to the right of the decimal point. 3
for 99v999
+ int dummy; // GCC seems to want an even number of 32-bit
values
+ } cblc_field_t;
+
+/*
+ * Implementation details
+ */
+
+class supplemental_t;
+
+enum cblc_file_prior_op_t
+ {
+ file_op_none,
+ file_op_open,
+ file_op_start,
+ file_op_read,
+ file_op_write,
+ file_op_rewrite,
+ file_op_delete,
+ file_op_close,
+ };
+
+/* end implementation details */
+
+typedef struct cblc_file_t
+ {
+ // This structure must match the code in structs.cc
+ char *name; // This is the name of the
structure; might be the name of an environment variable
+ char *filename; // The name of the file to be opened
+ FILE *file_pointer; // The FILE *pointer
+ cblc_field_t *default_record; // The record_area
+ size_t record_area_min; // The size of the smallest 01
record in the FD
+ size_t record_area_max; // The size of the largest 01
record in the FD
+ cblc_field_t **keys; // For relative and indexed files.
The first is the primary key. Null-terminated.
+ int *key_numbers; // One per key -- each key has a
number. This table is key_number + 1
+ int *uniques; // One per key
+ cblc_field_t *password; //
+ cblc_field_t *status; // This must exist, and is the
cbl_field_t version of io_status
+ cblc_field_t *user_status; // This might exist, and is another
copy See 2014 standard, section 9.1.12
+ cblc_field_t *vsam_status; //
+ cblc_field_t *record_length; //
+ supplemental_t *supplemental; //
+ void *implementation; // reserved for any implementation
+ size_t reserve; // From I-O section RESERVE clause
+ long prior_read_location; // Location of immediately
preceding successful read
+ cbl_file_org_t org; // from ORGANIZATION clause
+ cbl_file_access_t access; // from ACCESS MODE clause
+ int mode_char; // 'r', 'w', '+', or 'a' from FILE
OPEN statement
+ int errnum; // most recent errno; can't reuse
"errno" as the name
+ file_status_t io_status; // See 2014 standard, section 9.1.12
+ int padding; // Actually a char
+ int delimiter; // ends a record; defaults to '\n'.
+ int flags; // cblc_file_flags_t
+ int recent_char; // This is the most recent char
sent to the file
+ int recent_key;
+ cblc_file_prior_op_t prior_op; // run-time type is INT
+ int dummy;
+ } cblc_file_t;
+
+#endif
diff --git a/libgcobol/gfileio.h b/libgcobol/gfileio.h
new file mode 100644
index 00000000000..e70d84fc91e
--- /dev/null
+++ b/libgcobol/gfileio.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2021-2025 Symas Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of the Symas Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef GFILEIO_H_
+#define GFILEIO_H_
+
+extern "C"
+{
+void __gg__handle_error(const char *function, const char *msg);
+
+void __gg__file_open( cblc_file_t *file,
+ char *filename,
+ int mode_char,
+ int is_quoted);
+
+void __gg__file_reopen(cblc_file_t *file, int mode_char);
+
+void __gg__file_close( cblc_file_t *file, int how );
+
+void __gg__file_read( cblc_file_t *file,
+ int where);
+
+void __gg__file_write( cblc_file_t *file,
+ unsigned char *location,
+ size_t length,
+ int after,
+ int lines,
+ int is_random );
+}
+
+#endif
\ No newline at end of file
diff --git a/libgcobol/gmath.h b/libgcobol/gmath.h
new file mode 100644
index 00000000000..9aa8f635f4a
--- /dev/null
+++ b/libgcobol/gmath.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021-2025 Symas Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of the Symas Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef GMATH_H_
+#define GMATH_H_
+
+extern "C"
+{
+
+}
+
+#endif
\ No newline at end of file
diff --git a/libgcobol/io.h b/libgcobol/io.h
new file mode 100644
index 00000000000..0c89ad6d0c9
--- /dev/null
+++ b/libgcobol/io.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2021-2025 Symas Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of the Symas Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * File status key values and meanings
+ * 0 Successful completion
+ * 0 No further information
+ * 2 Duplicate key READ
+ * 4 Short/long READ
+ * 5 OPEN optional file unavailable
+ * 7 Not a tape
+ * 1 At-end condition
+ * 0 Sequential READ EOF
+ * 4 Relative record too big
+ * 2 Invalid key condition
+ * 1 Sequence error
+ * 2 Duplicate key WRITE
+ * 3 Record not found
+ * 4 Sequential WRITE EOF
+ * 3 Permanent error
+ * 0 No further information
+ * 1 Filename inconsistent with operating system
+ * 4 Boundary violation
+ * 5 OPEN nonoptional file unavailable
+ * 7 OPEN EACCES
+ * 8 OPEN file previously closed with lock
+ * 9 OPEN wrong file type
+ * 4 Logic error condition
+ * 1 OPEN file already open
+ * 2 CLOSE file not open
+ * 3 REWRITE without prior READ
+ * 4 REWRITE/WRITE boundary violation
+ * 6 READ after failed READ
+ * 7 File not open for READ
+ * 8 File not open for WRITE
+ * 9 File not open for DELETE/REWRITE
+ * 9 Implementor-defined
+ * 0 VSAM/QSAM close on wrong thread
+ * 1 VSAM password failure
+ * 2 Logic error
+ * 3 Resource unavailable
+ * 5 Incomplete file information
+ * 6 VSAM no DD statement
+ * 7 VSAM File integrity verified
+ * 8 OPEN invalid environment variable contents
+ */
+
+#ifndef IO_H_
+#define IO_H_
+
+enum file_high_t {
+ FhSuccess = 0,
+ FhAtEnd = 1,
+ FhInvKey = 2,
+ FhOsError = 3,
+ FhLogicError = 4,
+ FhImplementor = 9,
+};
+
+enum file_status_t {
+ FsSuccess = FhSuccess,
+ FsDupRead = (FhSuccess * 10) + 2, // First digit is 0
+ FsRecordLength= (FhSuccess * 10) + 4,
+ FsUnavail = (FhSuccess * 10) + 5,
+ FsNotaTape = (FhSuccess * 10) + 7,
+
+ FsEofSeq = (FhAtEnd * 10) + 0, // First digit is 1
+ FsEofRel = (FhAtEnd * 10) + 4,
+
+ FsKeySeq = (FhInvKey * 10) + 1, // First digit is 2
+ FsDupWrite = (FhInvKey * 10) + 2,
+ FsNotFound = (FhInvKey * 10) + 3,
+ FsEofWrite = (FhInvKey * 10) + 4,
+
+ FsOsError = (FhOsError * 10) + 0, // First digit is 3
+ FsNameError = (FhOsError * 10) + 1,
+ FsBoundary = (FhOsError * 10) + 4,
+ FsNoFile = (FhOsError * 10) + 5,
+ FsNoAccess = (FhOsError * 10) + 7,
+ FsCloseLock = (FhOsError * 10) + 8,
+ FsWrongType = (FhOsError * 10) + 9,
+
+ FsLogicErr = (FhLogicError * 10) + 0, // First digit
is 4
+ FsIsOpen = (FhLogicError * 10) + 1,
+ FsCloseNotOpen= (FhLogicError * 10) + 2,
+ FsNoRead = (FhLogicError * 10) + 3,
+ FsBoundWrite = (FhLogicError * 10) + 4,
+ FsReadError = (FhLogicError * 10) + 6,
+ FsReadNotOpen = (FhLogicError * 10) + 7,
+ FsNoWrite = (FhLogicError * 10) + 8,
+ FsNoDelete = (FhLogicError * 10) + 9,
+
+ FsWrongThread = (FhImplementor * 10) + 0, // First digit
is 9
+ FsPassword = (FhImplementor * 10) + 1,
+ FsLogicOther = (FhImplementor * 10) + 2,
+ FsNoResource = (FhImplementor * 10) + 3,
+ FsIncomplete = (FhImplementor * 10) + 5,
+ FsNoDD = (FhImplementor * 10) + 6,
+ FsVsamOK = (FhImplementor * 10) + 7,
+ FsBadEnvVar = (FhImplementor * 10) + 8,
+
+ FsErrno = (1000000) // This means
"map errno to one of the above errors"
+};
+
+#define FhNotOkay FsEofSeq // Values less than 10 mean the data are valid
+
+extern "C" file_status_t __gg__file_status_word(enum file_status_t status,
+ int error_number);
+
+#endif
diff --git a/libgcobol/libgcobol.h b/libgcobol/libgcobol.h
new file mode 100644
index 00000000000..bd9446adf60
--- /dev/null
+++ b/libgcobol/libgcobol.h
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2021-2025 Symas Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of the Symas Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef LIBGCOBOL_H_
+#define LIBGCOBOL_H_
+
+#include <stdio.h>
+
+#include <map>
+#include <unordered_map>
+#include <vector>
+
+#define MIN_FIELD_BLOCK_SIZE (16)
+
+// RUNTIME structures *must* match the ones created in structs.c and
initialized
+// and used in genapi.c. It's actually not all that important to emphasize
that
+// fact, since the compiled executable will crash and burn quickly if they
don't
+// match precisely.
+
+// Note that it must match the same structure in the GDB-COBOL debugger
+
+#define A_ZILLION (1000000) // Absurdly large number for
__gg__call_parameter_count
+
+// These bits are used for the "call flags" of arithmetic operations
+#define ON_SIZE_ERROR 0x01
+#define REMAINDER_PRESENT 0x02
+
+/* 'offset' is overloaded for FldAlphanumeric/temporary/intermediate variables
+ * For such variables, offset is a copy of the initial capacity. This is in
+ * support of the FUNCTION TRIM function, which both needs to be able to
+ * reduce the capacity of the target variable, and then to reset it back to
+ * the original value
+ */
+
+enum substitute_flags_t
+ {
+ substitute_anycase_e = 1,
+ substitute_first_e = 2, // first and last are mutually exclusive
+ substitute_last_e = 4,
+ };
+
+enum cblc_file_flags_t
+ {
+ file_flag_optional_e = 0x00001,
+ file_flag_existed_e = 0x00002,
+ file_name_quoted_e = 0x00004,
+ file_flag_initialized_e = 0x00008,
+ };
+
+// For indexed files, there can be one or more indexes, one per key.
+// Each index is one or more fields.
+
+struct file_hole_t
+ {
+ long location;
+ size_t size;
+ };
+
+struct file_index_t
+ {
+ std::multimap<std::vector<unsigned char>, long> key_to_position;
+ std::multimap<std::vector<unsigned char>, long>::iterator current_iterator;
+ std::multimap<std::vector<unsigned char>, long>::iterator ending_iterator;
+ };
+
+class supplemental_t
+ {
+ public:
+ std::vector<file_hole_t> holes;
+ std::vector<file_index_t> indexes;
+ std::vector<int> uniques;
+ };
+
+struct cblc_subscript_t
+ {
+ cblc_field_t *field; // That's what it usually is:
+ unsigned int type; // When type is FldLiteralN, field is a pointer to
__int128
+ };
+
+#define REFER_T_ALL_FLAGS_MASK 0x0FF // We allow for seven subscripts
+#define REFER_T_MOVE_ALL 0x100 // This is the move_all flag
+#define REFER_T_ADDRESS_OF 0x200 // This is the address_of flag
+
+struct cblc_declarative_t
+ {
+ int format;
+ int culprit; //declarative_culprit_t
+ int nfiles;
+ };
+
+/* According to the standard, the first digit of the file operation status
+ register is interpreted like this:
+
+ EC-I-O-AT-END '1'
+ EC-I-O-INVALID-KEY '2'
+ EC-I-O-PERMANENT-ERROR '3'
+ EC-I-O-LOGIC-ERROR '4'
+ EC-I-O-RECORD-OPERATION '5'
+ EC-I-O-FILE-SHARING '6'
+ EC-I-O-IMP '9'
+
+When the tens digit is '0', there are a number of conditions for
+successful completion. See section 9.1.12.1
+
+ 00 unqualified success
+ 02 duplicate key detected
+ 04 the data read were either too short or too long
+ 05 the operator couldn't find the tape
+ 07 somebody tried to rewind the card reader.
+
+For now, I am going to treat the io_status as an integer 00 through 99. I
+anticipate mostly returning
+ 00 for ordinary success,
+ 04 for a mismatched record size
+ 10 for an end-of-file
+
+*/
+
+// This global variable is constantly being updated with the yylineno. This is
+// useful for creating error messages, and for handling EXCEPTION_CONDITIONS
+extern int __gg__exception_code;
+extern int __gg__exception_line_number;
+extern int __gg__exception_file_status;
+extern const char *__gg__exception_file_name;
+extern const char *__gg__exception_statement;
+extern const char *__gg__exception_source_file;
+extern const char *__gg__exception_program_id;
+extern const char *__gg__exception_section;
+extern const char *__gg__exception_paragraph;
+
+extern "C" void __gg__set_exception_code( ec_type_t ec,
+ int from_raise_statement=0);
+
+extern int * __gg__fourplet_flags;
+
+extern cblc_field_t ** __gg__treeplet_1f;
+extern size_t * __gg__treeplet_1o;
+extern size_t * __gg__treeplet_1s;
+extern cblc_field_t ** __gg__treeplet_2f;
+extern size_t * __gg__treeplet_2o;
+extern size_t * __gg__treeplet_2s;
+extern cblc_field_t ** __gg__treeplet_3f;
+extern size_t * __gg__treeplet_3o;
+extern size_t * __gg__treeplet_3s;
+extern cblc_field_t ** __gg__treeplet_4f;
+extern size_t * __gg__treeplet_4o;
+extern size_t * __gg__treeplet_4s;
+
+#if 1
+ static inline
+ void exception_raise(ec_type_t ec_code) { __gg__set_exception_code(ec_code);
}
+#else
+# define
exception_raise(ec_code)do{__gg__set_exception_code(ec_code);}while(0);
+#endif
+
+extern "C" __int128 __gg__power_of_ten(int n);
+
+extern "C" __int128 __gg__dirty_to_binary_source( const char *dirty,
+ int length,
+ int *rdigits);
+extern "C" __int128 __gg__dirty_to_binary_internal( const char *dirty,
+ int length,
+ int *rdigits);
+extern "C" __int128 __gg__binary_value_from_field( int *rdigits,
+ cblc_field_t *var);
+extern "C" int __gg__compare_2( cblc_field_t *left_side,
+ unsigned char *left_location,
+ size_t left_length,
+ int left_attr,
+ bool left_all,
+ bool left_address_of,
+ cblc_field_t *right_side,
+ unsigned char *right_location,
+ size_t right_length,
+ int right_attr,
+ bool right_all,
+ bool right_address_of,
+ int second_time_through);
+extern "C" void __gg__int128_to_field(cblc_field_t *tgt,
+ __int128 value,
+ int source_rdigits,
+ enum cbl_round_t rounded,
+ int *compute_error);
+extern "C" void __gg__float128_to_field(cblc_field_t *tgt,
+ _Float128 value,
+ enum cbl_round_t rounded,
+ int *compute_error);
+extern "C" void __gg__int128_to_qualified_field(cblc_field_t *tgt,
+ size_t offset,
+ size_t length,
+ __int128 value,
+ int source_rdigits,
+ enum cbl_round_t rounded,
+ int *compute_error);
+extern "C" void __gg__float128_to_qualified_field(cblc_field_t *tgt,
+ size_t tgt_offset,
+ _Float128 value,
+ enum cbl_round_t rounded,
+ int *compute_error);
+
+extern "C" void __gg__double_to_target( cblc_field_t *tgt,
+ double tgt_value,
+ cbl_round_t rounded);
+extern "C" char __gg__get_decimal_separator();
+extern "C" char __gg__get_decimal_point();
+extern "C" char * __gg__get_default_currency_string();
+
+extern "C" void __gg__clock_gettime(clockid_t clk_id, struct timespec *tp);
+extern "C" _Float128 __gg__float128_from_location(cblc_field_t *var,
+ unsigned char *location);
+extern "C" void __gg__adjust_dest_size(cblc_field_t *dest, size_t ncount);
+#define MINIMUM_ALLOCATION_SIZE 16
+extern "C" void __gg__realloc_if_necessary( char **dest,
+ size_t *dest_size,
+ size_t new_size);
+extern "C" void __gg__set_exception_file(cblc_file_t *file);
+extern "C" void __gg__internal_to_console_in_place(char *loc, size_t length);
+extern "C" __int128 __gg__binary_value_from_qualified_field(int
*rdigits,
+ cblc_field_t *var,
+ size_t offset,
+ size_t size);
+extern "C" _Float128 __gg__float128_from_qualified_field(cblc_field_t *field,
+ size_t offset,
+ size_t size);
+extern "C" __int128 __gg__integer_from_qualified_field(cblc_field_t *var,
+ size_t var_offset,
+ size_t var_size);
+void __gg__abort(const char *msg);
+
+
+#endif
diff --git a/libgcobol/valconv.h b/libgcobol/valconv.h
new file mode 100644
index 00000000000..d907e6f70ee
--- /dev/null
+++ b/libgcobol/valconv.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021-2025 Symas Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of the Symas Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __VALCONV_H
+#define __VALCONV_H
+
+extern int __gg__decimal_point ;
+extern int __gg__decimal_separator ;
+extern int __gg__quote_character ;
+extern int __gg__low_value_character ;
+extern int __gg__high_value_character ;
+extern char **__gg__currency_signs ;
+extern int __gg__default_currency_sign;
+extern char *__gg__ct_currency_signs[256]; // Compile-time currency signs
+
+
+// All "ordinals" are zero-based ordinals. The COBOL spec's ordinal values
+// for ordinary ASCII/EBCDIC ranger from 1 to 256, so we call them zero through
+// 255. We use unsigned ints so that when an custom alphabet is described, we
+// can make every unmentioned character have an ordinal greater than the final
+// ordinal of the custom list.
+struct alphabet_state
+ {
+ unsigned short collation[256];
+ unsigned char low_char;
+ unsigned char high_char;
+ };
+
+extern std::unordered_map<size_t, alphabet_state> __gg__alphabet_states;
+
+extern "C"
+ {
+ void __gg__realloc_if_necessary(char **dest, size_t *dest_size, size_t
new_size);
+ void __gg__alphabet_create(cbl_encoding_t encoding,
+ size_t alphabet_index,
+ unsigned char *alphabet,
+ int low_char,
+ int high_char );
+ bool __gg__string_to_numeric_edited(char * const dest,
+ char *source, // ASCII
+ int rdigits,
+ int is_negative,
+ const char *picture);
+ void __gg__string_to_alpha_edited(char *dest,
+ char *source,
+ int slength,
+ char *picture);
+ void __gg__currency_sign_init();
+ void __gg__currency_sign(int symbol, const char *sign);
+ void __gg__remove_trailing_zeroes(char *p);
+ }
+
+#endif