diff --git a/README.md b/README.md index 5d9f01d..e5acb24 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,78 @@ -# COBOL Examples -This is a collection of example and test COBOL programs I've written. I'm currently in the process of updating -each folder with a README.md file and more comments so that the examples are easier to follow along with. +# COBOL Examples +A collection of example and test COBOL programs demonstrating various COBOL language features, syntax, and techniques. All programs are written for and compiled with [GnuCOBOL](https://gnucobol.sourceforge.io/) on Linux. -All program were written using [GnuCOBOL](https://gnucobol.sourceforge.io/) in Linux. +## Examples Index + +| Directory | Main File(s) | Description | Prerequisites | +|-----------|-------------|-------------|---------------| +| [accept](accept/) | `accept.cbl`, `accept-secure.cbl`, `accept_from.cbl` | Various forms of the `ACCEPT` statement including secure input, timeouts, and environment data | Interactive (requires user input) | +| [comp_test](comp_test/) | `comp_test.cbl` | Converting between `COMP` (binary) and `DISPLAY` numeric types | Interactive | +| [display_test](display_test/) | `display-test.cbl` | `DISPLAY` statement options: screen positioning, colors, blank line, erase, and bell | Uses screen mode (ncurses) | +| [display_timing](display_timing/) | `display_timing.cbl` | Benchmarking screen write speed between two `DISPLAY AT` position syntaxes | Interactive, uses screen mode | +| [is_numeric](is_numeric/) | `is_numeric.cbl` | Using `IS NUMERIC` to validate input with plain, zero-fill, and trim approaches | Interactive | +| [json_generate](json_generate/) | `json_generate.cbl` | Generating JSON documents from COBOL records using `JSON GENERATE` | [json-c](https://github.com/json-c/json-c); GnuCOBOL built with `--with-json` | +| [merge_sort](merge_sort/) | `merge_sort_test.cbl` | `SORT` and `MERGE` verbs with file-based data | None | +| [mouse](mouse/) | `mouse_example.cbl` | Mouse input handling in a simple drawing program | Uses screen mode (ncurses), interactive | +| [numval_test](numval_test/) | `numval_test.cbl` | Converting `PIC X` to numeric using the `NUMVAL` intrinsic function | Interactive | +| [read_command_args](read_command_args/) | `read_cmd_line_args.cbl`, `read_specific_cmd_line_args.cbl` | Reading and parsing command-line arguments | None (pass arguments when running) | +| [redifines](redifines/) | `redefines.cbl` | `REDEFINES` clause to reinterpret data in different formats | None | +| [report_writer](report_writer/) | `report_test.cbl` | COBOL Report Writer generating a formatted report from an input file | None (uses included `input.txt`) | +| [screen_size](screen_size/) | `get_screen_size.cbl` | Getting terminal dimensions using `ACCEPT FROM LINES/COLUMNS` and `CBL_GET_SCR_SIZE` | Interactive, uses screen mode | +| [search](search/) | `search.cbl` | `SEARCH` (sequential) and `SEARCH ALL` (binary) on indexed tables | Interactive | +| [sql](sql/) | `sql_example.cbl` | Connecting to and querying a PostgreSQL database via embedded SQL | [esqlOC](https://sourceforge.net/p/gnucobol/contrib/HEAD/tree/trunk/esql/), PostgreSQL, unixODBC, odbc-postgresql | +| [sub_program](sub_program/) | `main_app.cbl`, `sub.cbl` | Calling sub-programs with `BY CONTENT` and `BY REFERENCE`, plus `CANCEL` | Interactive | +| [trim](trim/) | `trim.cbl` | Intrinsic `TRIM` function for leading/trailing space removal | None | +| [unstring](unstring/) | `unstring.cbl` | `UNSTRING` verb with various delimiter and pointer options | None | +| [xml_generate](xml_generate/) | `xml_generate.cbl` | Generating XML documents from COBOL records using `XML GENERATE` | [libxml2](https://github.com/GNOME/libxml2); GnuCOBOL built with `--with-xml2` | + +## Getting Started + +### Compiler + +All examples require [GnuCOBOL](https://gnucobol.sourceforge.io/) (`cobc`). Install it via your package manager or build from source. + +### General Compile and Run + +For most examples, compile and run with: + +```bash +cd +cobc -x .cbl +./ +``` + +The `-x` flag tells `cobc` to produce a standalone executable. + +### Multi-file Programs + +Some examples (like `sub_program`) require compiling multiple source files together: + +```bash +cobc -x main_app.cbl sub.cbl -o a.out +./a.out +``` + +### Special Builds + +- **JSON example** requires `json-c` and GnuCOBOL configured with `--with-json`. +- **XML example** requires `libxml2` and GnuCOBOL configured with `--with-xml2`. +- **SQL example** requires the esqlOC precompiler, PostgreSQL, and unixODBC. See the [sql/README.md](sql/README.md) for full build instructions. + +## Interactive Examples + +Many examples use `ACCEPT` to read user input and will wait for keyboard entry. If running in an automated or non-interactive environment, you can pipe input or use a timeout: + +```bash +echo "42" | ./ +timeout 10s ./ +``` + +Some examples enter COBOL "screen mode" (backed by ncurses on Linux) when using positioned `DISPLAY` or `ACCEPT` statements. In screen mode, output is rendered via ncurses rather than standard output. + +## License + +See [LICENSE](LICENSE) for details. diff --git a/accept/README.md b/accept/README.md index ff01748..076b5aa 100644 --- a/accept/README.md +++ b/accept/README.md @@ -1,6 +1,6 @@ -# Accept syntax examples +# Accept Syntax Examples -The ```ACCEPT``` statement assigns input from the user/environment/screen/etc to a variable. In its simpilest form, it is +The ```ACCEPT``` statement assigns input from the user/environment/screen/etc to a variable. In its simplest form, it is written as: ```accept ws-variable-name``` @@ -14,7 +14,23 @@ upper left hand corner of the terminal output. This can be done by either passin location in the output statements or using the ```screen section``` to define the screen's output. Those functionalities are covered in their related sub directories in this repo. +## How to Compile +```bash +cobc -x accept.cbl +cobc -x accept-secure.cbl +cobc -x accept_from.cbl +``` + +## How to Run + +```bash +./accept +./accept-secure +./accept_from "this is one cmd arg" these are individual +``` + +All three programs require interactive user input. `accept_from` also accepts command-line arguments to demonstrate `ACCEPT FROM COMMAND-LINE` and `ACCEPT FROM ARGUMENT-VALUE`. ## Accept diff --git a/comp_test/README.md b/comp_test/README.md new file mode 100644 index 0000000..78b45e9 --- /dev/null +++ b/comp_test/README.md @@ -0,0 +1,34 @@ +# COMP Conversion Test + +This example demonstrates converting between `COMP` (binary) and `DISPLAY` (human-readable) numeric data types in COBOL. + +`comp_test.cbl` shows how a `COMP` variable can be used in arithmetic, moved to a standard `DISPLAY` variable, and moved to a dynamically formatted variable using `PIC ZZ9` (zero-suppressed). + +## How to Compile + +```bash +cobc -x comp_test.cbl +``` + +## How to Run + +```bash +./comp_test +``` + +The program will prompt for a numeric value to convert. + +## Expected Output + +``` +COMP: 0024 +DISP:024 +DYNA: 24 +INPUT: 050 +INPUT: 050 +COMP: 0050 +``` + +## Prerequisites + +None beyond GnuCOBOL (`cobc`). This example requires user input. diff --git a/display_test/README.md b/display_test/README.md new file mode 100644 index 0000000..c997a69 --- /dev/null +++ b/display_test/README.md @@ -0,0 +1,33 @@ +# DISPLAY Statement Options + +This example demonstrates various `DISPLAY` statement options available in GnuCOBOL for screen-mode output. + +`display-test.cbl` shows: + +- Positioning text with `AT RRCC` syntax (e.g., `at 0505`) +- Positioning with `LINE` and `COLUMN` keywords +- `WITH BLANK LINE` to clear the rest of the line +- `WITH ERASE EOL` to erase to end of line +- `WITH BELL` to produce an audible alert +- Setting `BACKGROUND-COLOR` and `FOREGROUND-COLOR` + +## How to Compile + +```bash +cobc -x display-test.cbl +``` + +## How to Run + +```bash +./display-test +``` + +## Expected Behavior + +The program enters screen mode (ncurses) and displays "hello world" at several screen positions with different formatting options. One line will trigger a terminal bell sound. The final line is displayed with a cyan foreground on a cyan background. + +## Prerequisites + +- GnuCOBOL (`cobc`) +- A terminal that supports ncurses (screen mode is entered automatically when positional `DISPLAY` is used) diff --git a/display_timing/README.md b/display_timing/README.md new file mode 100644 index 0000000..0328e05 --- /dev/null +++ b/display_timing/README.md @@ -0,0 +1,34 @@ +# DISPLAY Timing Benchmark + +This example benchmarks screen write performance between two different `DISPLAY` positioning syntaxes in GnuCOBOL. + +`display_timing.cbl` fills an 80x20 screen grid with the `@` character 100 times using each syntax, repeating 10 runs per method, then computes and displays the average time per run. + +The two syntaxes compared are: + +1. `DISPLAY "@" AT RRCC` (packed row/column format) +2. `DISPLAY "@" LINE nn COLUMN nn` (keyword format) + +## How to Compile + +```bash +cobc -x display_timing.cbl +``` + +## How to Run + +```bash +./display_timing +``` + +The program will prompt you to press Enter to start. After each set of 10 runs it displays timing results and waits for input before continuing. + +## Expected Behavior + +The program runs in screen mode (ncurses). After both benchmarks complete, average timing results are displayed for each syntax. Actual times will vary depending on your system. + +## Prerequisites + +- GnuCOBOL (`cobc`) +- A terminal that supports ncurses +- Interactive (requires user input to start and advance between benchmarks) diff --git a/is_numeric/README.md b/is_numeric/README.md new file mode 100644 index 0000000..f8439da --- /dev/null +++ b/is_numeric/README.md @@ -0,0 +1,38 @@ +# IS NUMERIC Test + +This example demonstrates how to use the `IS NUMERIC` class condition to check whether an alphanumeric variable contains only digits. + +`is_numeric.cbl` shows three approaches: + +1. **Plain** -- A standard `PIC X(10)` variable. Trailing spaces cause the `IS NUMERIC` test to fail even when only digits are entered. +2. **Right justify + zero fill** -- Using `JUSTIFIED RIGHT` and `INSPECT REPLACING LEADING SPACES BY '0'` to pad the value so the numeric test passes. +3. **Trim** -- Using `FUNCTION TRIM` to strip spaces before testing, which also allows the numeric test to pass. + +## How to Compile + +```bash +cobc -x is_numeric.cbl +``` + +## How to Run + +```bash +./is_numeric +``` + +The program prompts for three separate values. + +## Expected Output + +``` +(plain) Enter a value: 123 +123 is not numeric. +(right justify, zero fill) Enter another value: 456 +0000000456 is numeric! +(trim) Enter a third value: 789 +789 is numeric! +``` + +## Prerequisites + +None beyond GnuCOBOL (`cobc`). This example requires user input. diff --git a/json_generate/README.md b/json_generate/README.md index 317e3ee..ba435ec 100644 --- a/json_generate/README.md +++ b/json_generate/README.md @@ -15,6 +15,17 @@ After configured, you will need to also run ```make``` ```make install``` to reb If successful, ```cobcrun --info``` should display: ```JSON library : json-c, version 0.15.99``` +## How to Compile + +```bash +cobc -x json_generate.cbl +``` + +## How to Run + +```bash +./json_generate +``` **Example output of program:** ``` diff --git a/merge_sort/README.md b/merge_sort/README.md new file mode 100644 index 0000000..eb21844 --- /dev/null +++ b/merge_sort/README.md @@ -0,0 +1,43 @@ +# SORT and MERGE Example + +This example demonstrates the COBOL `SORT` and `MERGE` verbs for sorting and merging sequential files. + +`merge_sort_test.cbl` performs the following: + +1. Creates two test data files (`test-file-1.txt` and `test-file-2.txt`) containing customer records with IDs, names, and contract numbers. +2. **Merges** both files into `merge-output.txt`, sorted in ascending order by customer ID using the `MERGE` verb. +3. **Sorts** the merged file into `sorted-contract-id.txt` in descending order by contract ID using the `SORT` verb. +4. Displays the contents of each output file. + +## How to Compile + +```bash +cobc -x merge_sort_test.cbl +``` + +## How to Run + +```bash +./merge_sort_test +``` + +## Expected Output + +``` +Creating test data files... +Merging and sorting files... +00001last-1 [...] comment-1 +00003last-03 [...] comment-03 +00005last-5 [...] comment-5 +... +Sorting merged file on descending contract id.... +00005last-5 [...] comment-5 +... +Done. +``` + +The program creates temporary working files in the current directory during execution. + +## Prerequisites + +None beyond GnuCOBOL (`cobc`). This example does not require user input. diff --git a/mouse/README.md b/mouse/README.md index e38dd5d..53cc795 100644 --- a/mouse/README.md +++ b/mouse/README.md @@ -1,10 +1,28 @@ # Mouse Example - This is a very simple example drawing program created to demonstrate the mouse functionality and how to use it. +## How to Compile + +```bash +cobc -x mouse_example.cbl +``` + +## How to Run + +```bash +./mouse_example +``` -**Example of running example program:** +The program enters screen mode and allows you to draw on the terminal using mouse clicks. + +## Expected Behavior ![Image of paint program with hello world written](https://i.imgur.com/6zq1Kia.png) +## Prerequisites + +- GnuCOBOL (`cobc`) +- A terminal that supports ncurses and mouse events +- Interactive (requires mouse input) + diff --git a/numval_test/README.md b/numval_test/README.md new file mode 100644 index 0000000..6cb418c --- /dev/null +++ b/numval_test/README.md @@ -0,0 +1,33 @@ +# NUMVAL Function Test + +This example demonstrates converting an alphanumeric (`PIC X`) value to a numeric value using the `FUNCTION NUMVAL` intrinsic function. + +`numval_test.cbl` accepts two numbers from the user -- one stored as `PIC X(10)` and another as `PIC 9(10)` -- then uses `FUNCTION NUMVAL` to convert the alphanumeric value for arithmetic and adds them together. + +## How to Compile + +```bash +cobc -x numval_test.cbl +``` + +## How to Run + +```bash +./numval_test +``` + +The program prompts for two numeric values. + +## Expected Output + +``` +Enter first number: 10 +Enter second number: 20 +Total: 3.00000000000000E+001 +``` + +The total is displayed in scientific notation because the result is stored in a `COMP-2` (double-precision floating point) variable. + +## Prerequisites + +None beyond GnuCOBOL (`cobc`). This example requires user input. diff --git a/read_command_args/README.md b/read_command_args/README.md new file mode 100644 index 0000000..2b7f678 --- /dev/null +++ b/read_command_args/README.md @@ -0,0 +1,55 @@ +# Reading Command-Line Arguments + +This directory contains two examples of reading command-line arguments in GnuCOBOL. + +## read_cmd_line_args.cbl + +Reads the full command-line string using `ACCEPT ... FROM COMMAND-LINE` and checks for a specific flag (`--test`) using `INSPECT TALLYING`. + +### How to Compile + +```bash +cobc -x read_cmd_line_args.cbl +``` + +### How to Run + +```bash +./read_cmd_line_args --test hello world +``` + +### Expected Output + +``` +Pass arg '--test' for special message +Full command line args: --test hello world +You entered the '--test' cmd arg! +``` + +## read_specific_cmd_line_args.cbl + +Iterates through each command-line argument individually using `ACCEPT ... FROM ARGUMENT-NUMBER` to get the count, then `DISPLAY ... UPON ARGUMENT-NUMBER` and `ACCEPT ... FROM ARGUMENT-VALUE` to retrieve each argument by index. + +### How to Compile + +```bash +cobc -x read_specific_cmd_line_args.cbl +``` + +### How to Run + +```bash +./read_specific_cmd_line_args "arg one" arg2 arg3 +``` + +### Expected Output + +``` +arg one +arg2 +arg3 +``` + +## Prerequisites + +None beyond GnuCOBOL (`cobc`). Pass arguments on the command line when running. diff --git a/redifines/README.md b/redifines/README.md index 721dab9..c9f1561 100644 --- a/redifines/README.md +++ b/redifines/README.md @@ -19,6 +19,21 @@ display or interpret data different ways. ```redefines.cbl``` demonstrates a couple of examples of using ```REDEFINES```. +## How to Compile + +```bash +cobc -x redefines.cbl +``` + +## How to Run + +```bash +./redefines +``` + +## Prerequisites + +None beyond GnuCOBOL (`cobc`). This example does not require user input. **Example of program output:** diff --git a/report_writer/README.md b/report_writer/README.md new file mode 100644 index 0000000..cc4b02e --- /dev/null +++ b/report_writer/README.md @@ -0,0 +1,52 @@ +# Report Writer Example + +This example demonstrates the COBOL Report Writer feature, which provides a declarative way to produce formatted reports. + +`report_test.cbl` reads student records from `input.txt` and generates a formatted report written to `report.txt`. The report includes: + +- A report heading with a title and page number +- Detail lines for each input record showing student ID, name, major, and number of courses +- Automatic page control (page limits, heading placement, detail line spacing) + +## How to Compile + +```bash +cobc -x report_test.cbl +``` + +## How to Run + +```bash +./report_test +``` + +The program reads from `input.txt` (included in this directory) and writes the formatted report to `report.txt` in the current directory. + +## Expected Output (console) + +``` +Starting test report program. +Init test report. +Generate report line. +Generate report line. +... +Terminate report. +Done. +``` + +The generated `report.txt` file will contain a paginated report with a header and detail lines. + +## Input File Format + +Each line in `input.txt` is a fixed-width record: + +| Field | Position | PIC | Description | +|-------|----------|-----|-------------| +| Student ID | 1-6 | `9(6)` | Numeric student ID | +| Student Name | 7-26 | `X(20)` | Student name | +| Major | 27-29 | `XXX` | Three-letter major code | +| Num Courses | 30-31 | `99` | Number of courses | + +## Prerequisites + +None beyond GnuCOBOL (`cobc`). The included `input.txt` file must be in the working directory when running. diff --git a/screen_size/README.md b/screen_size/README.md index 1b53be6..a5e061f 100644 --- a/screen_size/README.md +++ b/screen_size/README.md @@ -19,7 +19,25 @@ requires text locations specified for display statements or the use of the ```SC call 'CBL_GET_SRC_SIZE' using ws-num-lines ws-num-cols ``` +## How to Compile +```bash +cobc -x get_screen_size.cbl +``` + +## How to Run + +```bash +./get_screen_size +``` + +The program enters screen mode and displays the current terminal dimensions. It waits for you to resize the terminal and press Enter between each method to see updated values. + +## Prerequisites + +- GnuCOBOL (`cobc`) +- A terminal that supports ncurses +- Interactive (requires user input) **Example of program output:** diff --git a/search/README.md b/search/README.md index dffdf79..22153b2 100644 --- a/search/README.md +++ b/search/README.md @@ -23,6 +23,23 @@ are slower than binary searchs. ```search.cbl``` demonstrates a couple of examples of using ```SEARCH``` and ```SEARCH ALL``` in different forms. +## How to Compile + +```bash +cobc -x search.cbl +``` + +## How to Run + +```bash +./search +``` + +The program prompts for search IDs multiple times to demonstrate different search modes. + +## Prerequisites + +None beyond GnuCOBOL (`cobc`). This example requires user input. **Example of program output:** diff --git a/sub_program/README.md b/sub_program/README.md index 8cc38e5..288b7d5 100644 --- a/sub_program/README.md +++ b/sub_program/README.md @@ -1,11 +1,29 @@ -# Example calling a sub program - +# Example Calling a Sub Program This example shows how to call a sub program and pass variables by content and by reference. It also demonstrates how the working-storage section variables of the sub program retain their values until the sub program is cancelled using the cancel statement. Local-storage variables do not retain their values between sub program -calls. +calls. + +## How to Compile + +Both source files must be compiled together: + +```bash +cobc -x main_app.cbl sub.cbl -o a.out +``` + +## How to Run + +```bash +./a.out +``` + +The program prompts for two values, then demonstrates three sub-program calls: by content, by reference, and after a cancel. + +## Prerequisites +None beyond GnuCOBOL (`cobc`). This example requires user input. **Example program output:** diff --git a/trim/README.md b/trim/README.md index 10a6299..3f5f227 100644 --- a/trim/README.md +++ b/trim/README.md @@ -35,6 +35,21 @@ Example: ```trim.cbl``` demonstrates a couple of examples of using the ```trim``` function. +## How to Compile + +```bash +cobc -x trim.cbl +``` + +## How to Run + +```bash +./trim +``` + +## Prerequisites + +None beyond GnuCOBOL (`cobc`). This example does not require user input. **Example of program output:** diff --git a/unstring/README.md b/unstring/README.md index bcfa5fa..dae8b01 100644 --- a/unstring/README.md +++ b/unstring/README.md @@ -16,6 +16,21 @@ ```unstring.cbl``` demonstrates a couple of examples of using ```UNSTRING``` in different forms. +## How to Compile + +```bash +cobc -x unstring.cbl +``` + +## How to Run + +```bash +./unstring +``` + +## Prerequisites + +None beyond GnuCOBOL (`cobc`). This example does not require user input. **Example of program output:** diff --git a/xml_generate/README.md b/xml_generate/README.md index 5dcd6ba..a3caac0 100644 --- a/xml_generate/README.md +++ b/xml_generate/README.md @@ -14,6 +14,17 @@ After configured, you will need to also run ```make``` ```make install``` to reb If successful, ```cobcrun --info``` should display: ```XML library : libxml2, version 2.9.3``` +## How to Compile + +```bash +cobc -x xml_generate.cbl +``` + +## How to Run + +```bash +./xml_generate +``` **Example output of program:** ```