Initial check
This commit is contained in:
commit
788e96bf08
31
.gitignore
vendored
Normal file
31
.gitignore
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
# Ignore build artifacts
|
||||
*.o
|
||||
*.so
|
||||
*.exe
|
||||
*.int
|
||||
*.lst
|
||||
*.idb
|
||||
*.log
|
||||
*.bak
|
||||
*~
|
||||
*.i
|
||||
*.c
|
||||
*.c.h
|
||||
*.c.l.h
|
||||
|
||||
# Ignore compiled executables
|
||||
id3cobol
|
||||
zero-ord
|
||||
|
||||
# Ignore temporary files
|
||||
.DS_Store
|
||||
*.swp
|
||||
*.tmp
|
||||
*.temp
|
||||
|
||||
# Ignore system-specific files
|
||||
*.core
|
||||
|
||||
# Ignore intermediate .i files
|
||||
|
||||
audio.mp3
|
17
.vscode/launch.json
vendored
Normal file
17
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "COBOL debugger",
|
||||
"type": "gdb",
|
||||
"preLaunchTask": "Build All",
|
||||
"request": "launch",
|
||||
"cobcargs": ["-free", "-x", "-g","-debug", "-Wall", "-O0"] ,
|
||||
"group": ["id3cobol.cbl"],
|
||||
"env": {
|
||||
"COB_LIBRARY_PATH": "${workspaceFolder}",
|
||||
"COB_PRE_LOAD": "zero-ord",
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
62
.vscode/tasks.json
vendored
Normal file
62
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Build zero-ord module",
|
||||
"type": "shell",
|
||||
"command": "cobc",
|
||||
"args": [
|
||||
"-free",
|
||||
"-m",
|
||||
"-g",
|
||||
"-debug",
|
||||
"-Wall",
|
||||
"-O0",
|
||||
"zero-ord.cbl"
|
||||
],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "new"
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Build id3cobol",
|
||||
"type": "shell",
|
||||
"command": "cobc",
|
||||
"args": [
|
||||
"-free",
|
||||
"-x",
|
||||
"-g",
|
||||
"-debug",
|
||||
"-Wall",
|
||||
"-O0",
|
||||
"id3cobol.cbl"
|
||||
],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "new"
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Build All",
|
||||
"dependsOrder": "sequence",
|
||||
"dependsOn": [
|
||||
"Build zero-ord module",
|
||||
"Build id3cobol"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "new"
|
||||
},
|
||||
"problemMatcher": []
|
||||
}
|
||||
]
|
||||
}
|
57
Makefile
Normal file
57
Makefile
Normal file
@ -0,0 +1,57 @@
|
||||
# Makefile for COBOL project cleanup and building
|
||||
# Created on: May 4, 2025
|
||||
|
||||
# Compiler settings
|
||||
COBC = cobc
|
||||
COBFLAGS = -x -g -debug -Wall
|
||||
COBFLAGS_DEBUG = -x -g -debug -Wall -O0
|
||||
|
||||
# Source files
|
||||
SOURCES = hello.cob hello.cbl hello2.cbl
|
||||
C_SOURCES = hello.c hello2.c
|
||||
|
||||
# Executables
|
||||
EXECS = hello hello2
|
||||
|
||||
# Default target
|
||||
all: $(EXECS)
|
||||
|
||||
# Build rules
|
||||
hello: hello.cob
|
||||
$(COBC) $(COBFLAGS) -o $@ $<
|
||||
|
||||
hello.cbl.exe: hello.cbl
|
||||
$(COBC) $(COBFLAGS_DEBUG) -o $@ $<
|
||||
|
||||
hello2: hello2.cbl
|
||||
$(COBC) $(COBFLAGS) -o $@ $<
|
||||
|
||||
# Clean up intermediate files and executables
|
||||
clean:
|
||||
rm -f *.o *.so *.exe *.int *.lst *.idb *.c *.h *.i *.c.h
|
||||
rm -f id3cobol zero-ord
|
||||
|
||||
# Deep clean (includes all build artifacts)
|
||||
distclean: clean
|
||||
rm -f *.log *.bak *~
|
||||
|
||||
# Debug build with optimizations disabled
|
||||
debug: COBFLAGS = $(COBFLAGS_DEBUG)
|
||||
debug: all
|
||||
|
||||
# Help target
|
||||
help:
|
||||
@echo "Makefile targets:"
|
||||
@echo " all - Build all executables (default)"
|
||||
@echo " clean - Remove intermediate files (.i, .c, .c.h, etc.)"
|
||||
@echo " distclean - Remove intermediate files and executables"
|
||||
@echo " debug - Build with full debug options and no optimization"
|
||||
@echo " hello - Build only hello executable"
|
||||
@echo " hello2 - Build only hello2 executable"
|
||||
@echo ""
|
||||
@echo "Examples:"
|
||||
@echo " make clean - Clean intermediate files"
|
||||
@echo " make debug - Build with debugging enabled"
|
||||
|
||||
# Prevent conflicts with files named like our targets
|
||||
.PHONY: all clean distclean debug help
|
61
README.md
Normal file
61
README.md
Normal file
@ -0,0 +1,61 @@
|
||||
# MP3 ID3 Tag Reader
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
This project is a COBOL-based MP3 ID3 tag reader that parses and displays metadata from MP3 files. It uses GnuCOBOL for compilation and execution.
|
||||
|
||||
## Software Requirements
|
||||
|
||||
- **GnuCOBOL**: Version 3.2.0 or later
|
||||
- Ensure GnuCOBOL is installed and accessible via the `cobc` command.
|
||||
- **Operating System**: Linux (tested on May 5, 2025)
|
||||
- **Make**: Version 4.3 or later (for building the project)
|
||||
- **Git**: Version 2.30.0 or later (for version control)
|
||||
|
||||
## Project Structure
|
||||
|
||||
- `id3cobol.cbl`: Main COBOL program for reading and parsing MP3 ID3 tags.
|
||||
- `zero-ord.cbl`: COBOL module for zero-based ordinal conversion.
|
||||
- `Makefile`: Build automation file for compiling and cleaning the project.
|
||||
- `.gitignore`: Specifies files and directories to be ignored by Git.
|
||||
|
||||
## Build Instructions
|
||||
|
||||
1. **Compile the `zero-ord` module**:
|
||||
```bash
|
||||
make zero-ord
|
||||
```
|
||||
|
||||
2. **Compile the `id3cobol` program**:
|
||||
```bash
|
||||
make id3cobol
|
||||
```
|
||||
|
||||
3. **Clean up build artifacts**:
|
||||
```bash
|
||||
make clean
|
||||
```
|
||||
|
||||
4. **Perform a deep clean (removes all artifacts)**:
|
||||
```bash
|
||||
make distclean
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Run the compiled `id3cobol` program to parse the `audio.mp3` file:
|
||||
```bash
|
||||
./id3cobol
|
||||
```
|
||||
|
||||
> **Note**: Ensure you have an `audio.mp3` file in the same directory as the program. This file is required for the program to function.
|
||||
|
||||
## Debugging
|
||||
|
||||
To enable debugging, ensure the `WS-DEBUG-MODE` variable in `id3cobol.cbl` is set to `1`. This will display additional debug information during execution.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License. See the LICENSE file for details.
|
BIN
assets/images/cobol.png
Normal file
BIN
assets/images/cobol.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 MiB |
298
id3cobol.cbl
Normal file
298
id3cobol.cbl
Normal file
@ -0,0 +1,298 @@
|
||||
IDENTIFICATION DIVISION.
|
||||
PROGRAM-ID. MP3ID3INFO.
|
||||
|
||||
ENVIRONMENT DIVISION.
|
||||
INPUT-OUTPUT SECTION.
|
||||
FILE-CONTROL.
|
||||
SELECT MP3-FILE ASSIGN TO DYNAMIC WS-FILENAME
|
||||
ORGANIZATION IS BINARY SEQUENTIAL.
|
||||
|
||||
DATA DIVISION.
|
||||
FILE SECTION.
|
||||
FD MP3-FILE.
|
||||
01 FILE-RECORD PIC X(1).
|
||||
|
||||
WORKING-STORAGE SECTION.
|
||||
01 RecordLength PIC 9(5) COMP-5.
|
||||
*> Debug flag to enable/disable debug prints
|
||||
01 WS-DEBUG-MODE PIC 9 VALUE 1.
|
||||
|
||||
01 WS-FILENAME PIC X(255) VALUE "audio.mp3".
|
||||
01 WS-EOF-FLAG PIC 9 VALUE 0.
|
||||
88 WS-EOF VALUE 1.
|
||||
|
||||
*> ID3v2 Header Structure - Use simpler types for debugging
|
||||
01 ID3-HEADER.
|
||||
05 ID3-TAG PIC X(3). *> Should be "ID3"
|
||||
05 ID3-VERSION PIC X(2). *> Version (ID3v2.X)
|
||||
05 ID3-FLAGS PIC X(1). *> Flags
|
||||
05 ID3-SIZE PIC X(4). *> Sync-safe size
|
||||
|
||||
*> Frame Structure - Explicitly define each element for debugger
|
||||
01 ID3-FRAME-HEADER.
|
||||
05 ID3-FRAME-ID PIC X(4). *> Frame identifier
|
||||
05 ID3-FRAME-SIZE PIC X(4). *> Sync-safe frame size
|
||||
05 ID3-FRAME-FLAGS PIC X(2). *> Frame flags
|
||||
|
||||
*> Working variables - Use simpler COMP-5 instead of COMP for better debugger support
|
||||
01 WS-TAG-SIZE PIC 9(9) COMP-5.
|
||||
01 WS-FRAME-SIZE PIC 9(9) COMP-5.
|
||||
01 WS-CURRENT-POS PIC 9(9) COMP-5.
|
||||
01 WS-REMAINING-BYTES PIC S9(9) COMP-5.
|
||||
01 WS-FILE-POS PIC 9(9) COMP-5 VALUE 1.
|
||||
01 WS-I PIC 9(9) COMP-5.
|
||||
|
||||
*> Buffer for frame data - Keep fixed size for easier debugging
|
||||
01 WS-FRAME-DATA-SIZE PIC 9(5) COMP-5 VALUE 100000.
|
||||
01 WS-FRAME-DATA.
|
||||
05 WS-FRAME-CHAR PIC X OCCURS 100000 TIMES.
|
||||
|
||||
*> Variables for sync-safe integer conversion
|
||||
01 WS-BYTE PIC X OCCURS 4.
|
||||
01 WS-BYTE-VAL PIC 9(3) COMP-5 OCCURS 4.
|
||||
01 WS-SHIFT-RESULT PIC 9(9) COMP-5 OCCURS 4.
|
||||
01 WS-X-RESULT PIC 9(9) COMP-5 OCCURS 4.
|
||||
01 WS-Y-RESULT PIC 9(9).
|
||||
|
||||
01 WS-NUMBER PIC 9(5) VALUE 21154.
|
||||
01 WS-DIVIDEND PIC 9(5).
|
||||
|
||||
01 WS-BYTE-FIELD.
|
||||
05 WS-IW-BYTE-0 PIC X(1).
|
||||
05 WS-IW-BYTE-1 PIC X(1).
|
||||
05 WS-IW-BYTE-2 PIC X(1).
|
||||
05 WS-IW-BYTE-3 PIC X(1).
|
||||
|
||||
01 SYNC-SAFE-INT-IN.
|
||||
05 SYNC-SAFE-INT-1 PIC X(1).
|
||||
05 SYNC-SAFE-INT-2 PIC X(1).
|
||||
05 SYNC-SAFE-INT-3 PIC X(1).
|
||||
05 SYNC-SAFE-INT-4 PIC X(1).
|
||||
|
||||
01 SYNC-SAFE-INT-OUT PIC 9(9) COMP-5.
|
||||
|
||||
*> Debug display variables - explicit single items for easier debugging
|
||||
01 DBG-FRAME-SIZE PIC 9(9) COMP-5.
|
||||
01 DBG-ASCII-ID PIC X(4).
|
||||
01 DBG-LOOP-COUNT PIC 9(5) COMP-5.
|
||||
|
||||
01 WS-TEMP-CHAR PIC X(1).
|
||||
01 WS-ORD-RESULT PIC 9(5) COMP-5.
|
||||
|
||||
01 WS-BYTES-TO-READ PIC 9(5) COMP-5.
|
||||
01 BYTES-BUFFER PIC X(100000).
|
||||
01 WS-TEMP-BYTE PIC X(1).
|
||||
|
||||
01 WS-SHIFT-21 PIC 9(7) COMP-5 VALUE 2097152.
|
||||
01 WS-SHIFT-14 PIC 9(7) COMP-5 VALUE 16384.
|
||||
01 WS-SHIFT-7 PIC 9(7) COMP-5 VALUE 128.
|
||||
01 WS-SHIFT-0 PIC 9(7) COMP-5 VALUE 1.
|
||||
|
||||
01 WS-VAL PIC 9(7).
|
||||
01 WS-NEW-VAL PIC 9(7).
|
||||
|
||||
LINKAGE SECTION.
|
||||
01 LS-CHAR PIC X(1).
|
||||
01 LS-ORD-RESULT PIC 9(5) COMP-5.
|
||||
|
||||
PROCEDURE DIVISION.
|
||||
MAIN-PARA.
|
||||
DISPLAY "Starting MP3-ID3-INFO program".
|
||||
|
||||
PERFORM OPEN-FILE.
|
||||
|
||||
IF WS-EOF-FLAG = 0
|
||||
PERFORM READ-ID3-HEADER
|
||||
IF ID3-TAG = "ID3"
|
||||
PERFORM PROCESS-ID3-TAG
|
||||
ELSE
|
||||
DISPLAY "No ID3v2 tag found!"
|
||||
END-IF
|
||||
END-IF.
|
||||
|
||||
PERFORM CLOSE-FILE.
|
||||
|
||||
DISPLAY "Program execution complete".
|
||||
STOP RUN.
|
||||
|
||||
OPEN-FILE.
|
||||
DISPLAY "Opening file: " WS-FILENAME.
|
||||
OPEN INPUT MP3-FILE.
|
||||
IF WS-EOF-FLAG = 1
|
||||
DISPLAY "Error opening file!"
|
||||
END-IF.
|
||||
|
||||
CLOSE-FILE.
|
||||
DISPLAY "Closing file".
|
||||
CLOSE MP3-FILE.
|
||||
|
||||
*> Read ID3 header
|
||||
READ-ID3-HEADER.
|
||||
*> Read ID3 header (10 bytes)
|
||||
MOVE 10 TO WS-BYTES-TO-READ
|
||||
PERFORM READ-BYTES
|
||||
MOVE BYTES-BUFFER(1:10) TO ID3-HEADER.
|
||||
|
||||
PROCESS-ID3-TAG.
|
||||
*> Get the size which is 4-byte sync-safe integer
|
||||
MOVE ID3-SIZE TO SYNC-SAFE-INT-IN
|
||||
PERFORM CONVERT-SYNC-SAFE-INT
|
||||
MOVE SYNC-SAFE-INT-OUT TO WS-TAG-SIZE
|
||||
|
||||
DISPLAY "ID3v2 Version: "
|
||||
FUNCTION TRIM(FUNCTION HEX-OF(ID3-VERSION(1:1))) "."
|
||||
FUNCTION TRIM(FUNCTION HEX-OF(ID3-VERSION(2:1))).
|
||||
|
||||
*> Debug display
|
||||
IF WS-DEBUG-MODE = 1
|
||||
DISPLAY "Tag Size: " WS-TAG-SIZE " bytes"
|
||||
END-IF
|
||||
|
||||
MOVE 10 TO WS-FILE-POS. *> 10 bytes read so far (header)
|
||||
|
||||
*> Debug line with explicit break opportunity
|
||||
DISPLAY "Starting to read frames at position " WS-FILE-POS.
|
||||
|
||||
PERFORM READ-FRAMES
|
||||
UNTIL (WS-FILE-POS >= WS-TAG-SIZE + 10) OR WS-EOF.
|
||||
|
||||
READ-FRAMES.
|
||||
*> Debug counter for frame reading
|
||||
ADD 1 TO DBG-LOOP-COUNT
|
||||
|
||||
*> Reset values
|
||||
MOVE LOW-VALUES TO ID3-FRAME-HEADER.
|
||||
MOVE 0 TO WS-FRAME-SIZE.
|
||||
|
||||
*> Read frame header (10 bytes)
|
||||
MOVE 10 TO WS-BYTES-TO-READ
|
||||
PERFORM READ-BYTES
|
||||
MOVE BYTES-BUFFER(1:10) TO ID3-FRAME-HEADER
|
||||
|
||||
*> Update file position
|
||||
ADD 10 TO WS-FILE-POS.
|
||||
DISPLAY "Current position: " WS-FILE-POS.
|
||||
|
||||
*> Get Frame length
|
||||
MOVE ID3-FRAME-SIZE TO SYNC-SAFE-INT-IN
|
||||
PERFORM CONVERT-SYNC-SAFE-INT
|
||||
MOVE SYNC-SAFE-INT-OUT TO WS-FRAME-SIZE
|
||||
|
||||
IF WS-DEBUG-MODE = 1
|
||||
DISPLAY "-------------------------------"
|
||||
DISPLAY "FRAME HEADER: ID="
|
||||
ID3-FRAME-ID
|
||||
", SIZE=" WS-FRAME-SIZE
|
||||
END-IF
|
||||
|
||||
*> Check for invalid Frame Length
|
||||
IF WS-FRAME-SIZE <= 0
|
||||
DISPLAY "Invalid WS-FRAME-SIZE" WS-FRAME-SIZE
|
||||
EXIT PARAGRAPH
|
||||
END-IF.
|
||||
|
||||
*> Check for buffer overrun
|
||||
IF WS-FRAME-SIZE > 100000
|
||||
DISPLAY "Frame too large to process: " WS-FRAME-SIZE
|
||||
PERFORM SKIP-FRAME
|
||||
ELSE
|
||||
PERFORM READ-FRAME-DATA
|
||||
END-IF.
|
||||
|
||||
DISPLAY "Current position: " WS-FILE-POS.
|
||||
|
||||
*> Update file position
|
||||
ADD WS-FRAME-SIZE TO WS-FILE-POS.
|
||||
|
||||
COMPUTE WS-REMAINING-BYTES = (WS-TAG-SIZE + 10) - WS-FILE-POS.
|
||||
DISPLAY "Next position: " WS-FILE-POS.
|
||||
DISPLAY "Remaining: " WS-REMAINING-BYTES.
|
||||
|
||||
SKIP-FRAME.
|
||||
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > WS-FRAME-SIZE
|
||||
READ MP3-FILE
|
||||
AT END MOVE 1 TO WS-EOF-FLAG
|
||||
EXIT PERFORM
|
||||
END-READ
|
||||
END-PERFORM.
|
||||
|
||||
*> Read the Frame data
|
||||
*> We ignore pictures
|
||||
READ-FRAME-DATA.
|
||||
DISPLAY "Reading frame data: " WS-FRAME-SIZE " bytes".
|
||||
MOVE LOW-VALUES TO WS-FRAME-DATA.
|
||||
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > WS-FRAME-SIZE
|
||||
*> Add bounds check to prevent index errors
|
||||
IF WS-I >= 1 AND WS-I <= 100000
|
||||
READ MP3-FILE INTO WS-TEMP-BYTE
|
||||
AT END
|
||||
MOVE 1 TO WS-EOF-FLAG
|
||||
EXIT PERFORM
|
||||
END-READ
|
||||
MOVE WS-TEMP-BYTE TO WS-FRAME-CHAR(WS-I)
|
||||
ELSE
|
||||
DISPLAY "WARNING: Index " WS-I " out of bounds (1-100000)"
|
||||
EXIT PERFORM
|
||||
END-IF
|
||||
END-PERFORM.
|
||||
|
||||
*> Display appropriate message based on frame ID
|
||||
IF ID3-FRAME-ID = "APIC"
|
||||
DISPLAY "Frame: " ID3-FRAME-ID
|
||||
" - Data: [Picture]"
|
||||
ELSE
|
||||
DISPLAY "Frame: " ID3-FRAME-ID
|
||||
" - Data: " FUNCTION TRIM(WS-FRAME-DATA)
|
||||
END-IF.
|
||||
|
||||
*> Convert sync-safe integer to actual size
|
||||
*> Implementation of syncSafeToInt function using zero-based ORD
|
||||
*> Input: SYNC-SAFE-INT-IN (4 bytes)
|
||||
*> Output: SYNC-SAFE-INT-OUT (integer value)
|
||||
CONVERT-SYNC-SAFE-INT.
|
||||
MOVE 0 TO WS-VAL.
|
||||
|
||||
*> Extract the numeric value of each byte
|
||||
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 4
|
||||
MOVE SYNC-SAFE-INT-IN(WS-I:1) TO WS-TEMP-CHAR
|
||||
MOVE 0 TO WS-ORD-RESULT
|
||||
CALL "ZERO-BASED-ORD" USING WS-TEMP-CHAR, WS-ORD-RESULT
|
||||
MOVE WS-ORD-RESULT TO WS-BYTE-VAL(WS-I)
|
||||
END-PERFORM
|
||||
|
||||
*> Debug display of input bytes
|
||||
IF WS-DEBUG-MODE = 1
|
||||
DISPLAY "Byte 1: " WS-BYTE-VAL(1)
|
||||
" (hex: " FUNCTION HEX-OF(SYNC-SAFE-INT-IN(1:1)) ")"
|
||||
DISPLAY "Byte 2: " WS-BYTE-VAL(2)
|
||||
" (hex: " FUNCTION HEX-OF(SYNC-SAFE-INT-IN(2:1)) ")"
|
||||
DISPLAY "Byte 3: " WS-BYTE-VAL(3)
|
||||
" (hex: " FUNCTION HEX-OF(SYNC-SAFE-INT-IN(3:1)) ")"
|
||||
DISPLAY "Byte 4: " WS-BYTE-VAL(4)
|
||||
" (hex: " FUNCTION HEX-OF(SYNC-SAFE-INT-IN(4:1)) ")"
|
||||
END-IF
|
||||
|
||||
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 4
|
||||
MULTIPLY WS-VAL BY 256 GIVING WS-VAL
|
||||
MOVE WS-BYTE-VAL(WS-I) TO WS-NEW-VAL
|
||||
ADD WS-NEW-VAL TO WS-VAL
|
||||
END-PERFORM
|
||||
|
||||
MOVE WS-VAL TO SYNC-SAFE-INT-OUT
|
||||
|
||||
DISPLAY "Converted value: " SYNC-SAFE-INT-OUT.
|
||||
|
||||
*> Input: WS-BYTES-TO-READ = number of bytes to read
|
||||
*> Output: BYTES-BUFFER filled with data
|
||||
READ-BYTES SECTION.
|
||||
MOVE SPACES TO BYTES-BUFFER
|
||||
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL
|
||||
WS-I > WS-BYTES-TO-READ
|
||||
|
||||
READ MP3-FILE INTO WS-TEMP-BYTE
|
||||
AT END
|
||||
MOVE 1 TO WS-EOF-FLAG
|
||||
EXIT PERFORM
|
||||
END-READ
|
||||
MOVE WS-TEMP-BYTE TO BYTES-BUFFER(WS-I:1)
|
||||
END-PERFORM.
|
12
zero-ord.cbl
Normal file
12
zero-ord.cbl
Normal file
@ -0,0 +1,12 @@
|
||||
IDENTIFICATION DIVISION.
|
||||
PROGRAM-ID. ZERO-BASED-ORD.
|
||||
|
||||
DATA DIVISION.
|
||||
LINKAGE SECTION.
|
||||
01 LS-CHAR PIC X(1).
|
||||
01 LS-ORD-RESULT PIC 9(5) COMP-5.
|
||||
|
||||
PROCEDURE DIVISION USING LS-CHAR, LS-ORD-RESULT.
|
||||
COMPUTE LS-ORD-RESULT = FUNCTION ORD(LS-CHAR) - 1.
|
||||
EXIT PROGRAM.
|
||||
END PROGRAM ZERO-BASED-ORD.
|
Loading…
x
Reference in New Issue
Block a user