Exercises — Chapter 23: Parameter Passing Patterns
Exercise 23.1: BY REFERENCE vs. BY CONTENT Experiment (Beginner)
Objective: Observe the difference between BY REFERENCE and BY CONTENT through direct experimentation.
Tasks:
-
Write a subprogram
MODIFIERthat: - Receives two parameters: LS-DATA (PIC X(20)) and LS-RC (PIC S9(4) COMP) - Moves 'MODIFIED BY SUBPROG' to LS-DATA - Moves 0 to LS-RC - Returns via GOBACK -
Write a driver program that: - Sets WS-DATA to 'ORIGINAL VALUE' - Displays WS-DATA - Calls MODIFIER with WS-DATA passed BY REFERENCE - Displays WS-DATA (what do you expect?) - Resets WS-DATA to 'ORIGINAL VALUE' - Calls MODIFIER with WS-DATA passed BY CONTENT - Displays WS-DATA (what do you expect?)
-
Document your observations. Which call preserved the caller's data?
Exercise 23.2: Return Code Standard (Beginner)
Objective: Implement and use a standardized return code convention.
Requirements:
-
Create a copybook
RETCODCP.cpywith: - Return code field (PIC S9(4) COMP) - Level 88 names for SUCCESS (0), WARNING (4), ERROR (8), SEVERE (12), FATAL (16) - Level 88 names for OK (0 THRU 4) and FAILED (8 THRU 16) -
Write a subprogram
AGECHKthat validates a person's age: - Input: age (PIC 9(3)) - Returns 0 if age is 18-65 (standard) - Returns 4 if age is 16-17 or 66-99 (warning — needs review) - Returns 8 if age < 0 or > 150 (error — invalid) - Returns 12 if age is non-numeric (severe — bad data) -
Write a driver that tests ages: 25, 17, 75, 0, 200, and displays the return code and a message for each.
Exercise 23.3: Error Structure Implementation (Intermediate)
Objective: Design and use a comprehensive error communication structure.
Requirements:
-
Create an error structure copybook
ERRSTRCP.cpycontaining: - Program ID (PIC X(8)) - Error code (PIC X(8)) - Short message (PIC X(40)) - Long message (PIC X(200)) - Field name (PIC X(30)) - Field value (PIC X(50)) - Timestamp (PIC X(26)) -
Write a subprogram
ADDRVAL(address validator) that: - Receives an address structure (street, city, state, zip) - Validates each field:- Street: not blank, max 40 chars
- City: not blank, max 30 chars
- State: must be a valid 2-letter state code (at least check for 5 states)
- ZIP: must be 5 digits or 5+4 format (NNNNN or NNNNN-NNNN)
- Populates the error structure for the FIRST validation failure
- Returns appropriate return code
-
Test with both valid and invalid addresses.
Exercise 23.4: COMMAREA Pattern (Intermediate)
Objective: Implement a communication area pattern for a multi-stage processing pipeline.
Scenario: A student registration system with three stages:
REGISTER (Driver)
├── CALL 'REGVALID' — Validate student data
├── CALL 'REGFEE' — Calculate fees
└── CALL 'REGENRL' — Create enrollment record
Requirements:
-
Design a COMMAREA copybook
REGCOMCP.cpycontaining: - Function code (which stage) - Student data (ID, name, major, GPA, credits) - Fee calculation results (tuition, fees, total) - Enrollment status - Return code and error information -
Implement REGISTER (driver) and at least REGVALID: - REGVALID checks: student ID format (9 digits), GPA range (0.0-4.0), credits range (0-200) - Return code 4 if GPA < 2.0 (academic probation warning) - Return code 8 for invalid data
-
Test with valid and invalid student data.
Exercise 23.5: Mixed Parameter Modes (Intermediate)
Objective: Practice using different passing modes on a single CALL.
Requirements:
Write a subprogram AMTFMT (amount formatter) with these parameters:
1. BY CONTENT: Input amount (PIC S9(9)V99 COMP-3) — protected input
2. BY CONTENT: Format code (PIC X(3)) — 'USD', 'EUR', 'PCT'
3. BY REFERENCE: Output string (PIC X(20)) — formatted result
4. BY REFERENCE: Return code (PIC S9(4) COMP) — status
Formatting rules: - 'USD': $Z,ZZZ,ZZ9.99 with leading dollar sign - 'EUR': Z,ZZZ,ZZ9.99€ with trailing euro symbol - 'PCT': ZZ9.99% with trailing percent
Test with amounts: 1234567.89, 0.50, -500.00, 999999999.99
Exercise 23.6: Optional Parameters with OMITTED (Advanced)
Objective: Implement a subprogram that handles optional parameters gracefully.
Requirements:
Write a logging subprogram LOGENTRY that accepts:
1. Log message (required) — PIC X(200)
2. Log level (optional) — PIC X(5), defaults to 'INFO'
3. Module name (optional) — PIC X(8), defaults to 'UNKNOWN'
4. Timestamp (optional) — PIC X(26), defaults to CURRENT-DATE
5. Return code (required) — PIC S9(4) COMP
The subprogram should: - Check ADDRESS OF for each optional parameter - Use defaults when parameters are OMITTED - Format and display the log entry
Write a driver that calls LOGENTRY in four ways:
* All parameters provided
CALL 'LOGENTRY' USING WS-MSG WS-LEVEL WS-MODULE
WS-TIMESTAMP WS-RC
* Only level omitted (use default INFO)
CALL 'LOGENTRY' USING WS-MSG OMITTED WS-MODULE
WS-TIMESTAMP WS-RC
* Level, module, and timestamp all omitted
CALL 'LOGENTRY' USING WS-MSG OMITTED OMITTED
OMITTED WS-RC
* Only message and return code
CALL 'LOGENTRY' USING WS-MSG OMITTED OMITTED
OMITTED WS-RC
Exercise 23.7: C Interop with BY VALUE (Advanced — GnuCOBOL)
Objective: Practice BY VALUE parameter passing for cross-language interoperability.
Requirements:
-
Write a C function:
c int compute_checksum(char *data, int length);That computes a simple checksum: sum of all byte values modulo 256. -
Write a COBOL program that: - Defines a data buffer (PIC X(50)) - Passes the buffer BY REFERENCE and its length BY VALUE - Captures the checksum via RETURNING - Displays the result
-
Compile and link with GnuCOBOL:
bash gcc -c checksum.c cobc -x -o checkprog checkprog.cbl checksum.o -
Compare the COBOL result with a manual calculation for a known input string.
Exercise 23.8: Return Code Propagation (Advanced)
Objective: Implement proper return code propagation through a multi-level call chain.
Scenario: A three-level call chain:
MAINPROG → LEVEL1 → LEVEL2
Requirements:
-
LEVEL2 subprogram: - Receives a number (PIC 9(5)) and return code - Returns 0 if number is 1-50000 - Returns 4 if number is 50001-99999 - Returns 8 if number is 0
-
LEVEL1 subprogram: - Receives an array of 5 numbers and a return code - Calls LEVEL2 for each number - Tracks the maximum (highest-severity) return code - Returns the maximum return code
-
MAINPROG: - Calls LEVEL1 with test arrays - Sets RETURN-CODE special register to the maximum - Tests with: [100, 200, 300, 400, 500] (expect RC=0) - Tests with: [100, 60000, 300, 0, 500] (expect RC=8)
-
Verify that the highest-severity return code propagates correctly from LEVEL2 through LEVEL1 to MAINPROG.