Справочник по Ada 2005
B.4 Взаимодействие с COBOL
Средства, относящиеся к взаимодействию с языком COBOL, — это пакет Interfaces.COBOL и поддержка директив Import, Export и Convention с _идентификатором COBOL.
Пакет интерфейса COBOL предоставляет несколько наборов средств:
- Набор типов, соответствующих родным типам COBOL поддерживаемой реализации COBOL (так называемые «внутренние представления COBOL»), позволяющий передавать данные Ada в качестве параметров программам COBOL
- Набор типов и констант, отражающих внешние представления данных, такие как те, которые могут встречаться в файлах или базах данных, позволяющие программе Ada читать данные, сгенерированные COBOL, и данные, сгенерированные Ada, могут быть прочитаны программами COBOL
- Обобщённый пакет для преобразования между значением типа десятичных чисел Ada и внутренним или внешним представлением COBOL
Статическая семантика
Библиотечный пакет Interfaces.COBOL имеет следующую декларацию:
package Interfaces.COBOL is
pragma Preelaborate(COBOL);
pragma Preelaborate(COBOL);
-- Типы и операции для внутренних представлений данных
type Floating is digits определяется реализацией;
type Long_Floating is digits определяется реализацией;
type Long_Floating is digits определяется реализацией;
type Binary is range определяется реализацией;
type Long_Binary is range определяется реализацией;
type Long_Binary is range определяется реализацией;
Max_Digits_Binary : constant := определяется реализацией;
Max_Digits_Long_Binary : constant := определяется реализацией;
Max_Digits_Long_Binary : constant := определяется реализацией;
type Decimal_Element is mod определяется реализацией;
type Packed_Decimal is array (Positive range <>) of Decimal_Element;
pragma Pack(Packed_Decimal);
type Packed_Decimal is array (Positive range <>) of Decimal_Element;
pragma Pack(Packed_Decimal);
type COBOL_Character is тип символов, определяется реализацией;
Ada_To_COBOL : array (Character) of COBOL_Character := определяется реализацией;
COBOL_To_Ada : array (COBOL_Character) of Character := определяется реализацией;
type Alphanumeric is array (Positive range <>) of COBOL_Character;
pragma Pack(Alphanumeric);
pragma Pack(Alphanumeric);
function To_COBOL (Item : in String) return Alphanumeric;
function To_Ada (Item : in Alphanumeric) return String;
function To_Ada (Item : in Alphanumeric) return String;
procedure To_COBOL (Item : in String;
Target : out Alphanumeric;
Last : out Natural);
Target : out Alphanumeric;
Last : out Natural);
procedure To_Ada (Item : in Alphanumeric;
Target : out String;
Last : out Natural);
Target : out String;
Last : out Natural);
type Numeric is array (Positive range <>) of COBOL_Character;
pragma Pack(Numeric);
pragma Pack(Numeric);
-- Форматы для представлений данных COBOL
type Display_Format is private;
Unsigned : constant Display_Format;
Leading_Separate : constant Display_Format;
Trailing_Separate : constant Display_Format;
Leading_Nonseparate : constant Display_Format;
Trailing_Nonseparate : constant Display_Format;
Leading_Separate : constant Display_Format;
Trailing_Separate : constant Display_Format;
Leading_Nonseparate : constant Display_Format;
Trailing_Nonseparate : constant Display_Format;
type Binary_Format is private;
High_Order_First : constant Binary_Format;
Low_Order_First : constant Binary_Format;
Native_Binary : constant Binary_Format;
Low_Order_First : constant Binary_Format;
Native_Binary : constant Binary_Format;
type Packed_Format is private;
Packed_Unsigned : constant Packed_Format;
Packed_Signed : constant Packed_Format;
Packed_Signed : constant Packed_Format;
-- Типы для внешнего представления данных COBOL двоичного типа
type Byte is mod 2**COBOL_Character'Size;
type Byte_Array is array (Positive range <>) of Byte;
pragma Pack (Byte_Array);
type Byte_Array is array (Positive range <>) of Byte;
pragma Pack (Byte_Array);
Conversion_Error : exception;
generic
type Num is delta <> digits <>;
package Decimal_Conversions is
type Num is delta <> digits <>;
package Decimal_Conversions is
-- Форматы отображения: значения данных представлены как Numeric
function Valid (Item : in Numeric;
Format : in Display_Format) return Boolean;
Format : in Display_Format) return Boolean;
function Length (Format : in Display_Format) return Natural;
function To_Decimal (Item : in Numeric;
Format : in Display_Format) return Num;
Format : in Display_Format) return Num;
function To_Display (Item : in Num;
Format : in Display_Format) return Numeric;
Format : in Display_Format) return Numeric;
-- Упакованные форматы: значения данных представлены как Packed_Decimal
function Valid (Item : in Packed_Decimal;
Format : in Packed_Format) return Boolean;
Format : in Packed_Format) return Boolean;
function Length (Format : in Packed_Format) return Natural;
function To_Decimal (Item : in Packed_Decimal;
Format : in Packed_Format) return Num;
Format : in Packed_Format) return Num;
function To_Packed (Item : in Num;
Format : in Packed_Format) return Packed_Decimal;
Format : in Packed_Format) return Packed_Decimal;
-- Двоичные форматы: внешние значения данных представлены как Byte_Array
function Valid (Item : in Byte_Array;
Format : in Binary_Format) return Boolean;
Format : in Binary_Format) return Boolean;
function Length (Format : in Binary_Format) return Natural;
function To_Decimal (Item : in Byte_Array;
Format : in Binary_Format) return Num;
function To_Decimal (Item : in Byte_Array;
Format : in Binary_Format) return Num;
function To_Binary (Item : in Num;
Format : in Binary_Format) return Byte_Array;
Format : in Binary_Format) return Byte_Array;
-- Внутренние двоичные форматы: значения данных имеют тип Binary или Long_Binary
function To_Decimal (Item : in Binary) return Num;
function To_Decimal (Item : in Long_Binary) return Num;
function To_Decimal (Item : in Long_Binary) return Num;
function To_Binary (Item : in Num) return Binary;
function To_Long_Binary (Item : in Num) return Long_Binary;
function To_Long_Binary (Item : in Num) return Long_Binary;
end Decimal_Conversions;
private
... -- не определено языком
end Interfaces.COBOL;
... -- не определено языком
end Interfaces.COBOL;
Каждый из типов в Interfaces.COBOL совместим с COBOL.
Типы Floating и Long_Floating соответствуют родным типам в COBOL для элементов данных с вычислительным использованием, реализованным с плавающей точкой. Типы Binary и Long_Binary соответствуют родным типам в COBOL для элементов данных с двоичным использованием или с вычислительным использованием, реализованным с помощью двоичного типа.
Max_Digits_Binary — это наибольшее число десятичных разрядов в числовом значении, которое представлено как Binary. Max_Digits_Long_Binary — это наибольшее число десятичных разрядов в числовом значении, которое представлено как Long_Binary.
Тип Packed_Decimal соответствует использованию упакованных десятичных чисел в COBOL.
Тип COBOL_Character определяет используемый в реализации COBOL набор символов во время выполнения. Ada_To_COBOL и COBOL_To_Ada — это отображения между наборами символов Ada и COBOL во время выполнения.
Тип Alphanumeric соответствует категориям алфавитно-цифровых данных COBOL.
Каждая из функций To_COBOL и To_Ada преобразует свой параметр на основе отображений Ada_To_COBOL и COBOL_To_Ada соответственно. Длина результата для каждой из них равна длине параметра, а нижняя граница результата равна 1. Каждый компонент результата получается путём применения соответствующего отображения к соответствующему компоненту параметра.
Каждая из процедур To_COBOL и To_Ada копирует преобразованные элементы из Item в Target, используя соответствующее отображение (Ada_To_COBOL или COBOL_To_Ada соответственно). Индекс в Target последнего присвоенного элемента возвращается в Last (0, если Item — массив null). Если Item'Length превышает Target'Length, генерируется Constraint_Error.
Тип Numeric соответствует категории числовых данных COBOL с использованием отображения.
Типы Display_Format, Binary_Format и Packed_Format используются при преобразованиях между значениями типа десятичных чисел Ada и внутренними или внешними представлениями данных COBOL. Значение константы Native_Binary — либо High_Order_First, либо Low_Order_First, в зависимости от реализации.
function Valid (Item : in Numeric;
Format : in Display_Format) return Boolean;
Format : in Display_Format) return Boolean;
Функция Valid проверяет, что параметр Item имеет значение, совместимое со значением Format. Если значение Format отличается от Unsigned, Leading_Separate и Trailing_Separate, то поведение определяется реализацией. Если Format имеет одно из этих значений, применяются следующие правила:
- Format=Unsigned: если Item состоит из одной или нескольких десятичных цифр, то Valid возвращает True, иначе — False.
- Format=Leading_Separate: если Item состоит из одиночного символа плюса или минуса, а затем одной или нескольких десятичных цифр, то Valid возвращает True, иначе — False.
- Format=Trailing_Separate: если Item состоит из одной или нескольких десятичных цифр и, наконец, символа плюса или минуса, то Valid возвращает True, иначе — False.
функция Length (Format : в Display_Format) возвращает Natural;
Функция Length возвращает минимальную длину числового значения, достаточную для хранения любого значения типа Num, представленного в формате Format.
функция To_Decimal (Item : в Numeric;
Format : в Display_Format) возвращает Num;
Format : в Display_Format) возвращает Num;
Создаёт значение типа Num, соответствующее Item, представленному в формате Format. Количество цифр после предполагаемой запятой в Item равно Num'Scale. Ошибка преобразования распространяется, если значение, представленное Item, выходит за пределы диапазона Num.
функция To_Display (Item : в Num;
Format : в Display_Format) возвращает Numeric;
Format : в Display_Format) возвращает Numeric;
Эта функция возвращает числовое значение для Item, представленное в соответствии с Format. Длина возвращаемого значения равна Length(Format), а нижняя граница равна 1. Ошибка преобразования распространяется, если Num отрицательно, а Format — Unsigned.
функция Valid (Item : в Packed_Decimal;
Format : в Packed_Format) возвращает Boolean;
Format : в Packed_Format) возвращает Boolean;
Эта функция возвращает True, если Item имеет значение, согласованное с Format, и False в противном случае. Правила формирования значений Packed_Decimal определяются реализацией.
функция Length (Format : в Packed_Format) возвращает Natural;
Эта функция возвращает минимальную длину значения Packed_Decimal, достаточную для хранения любого значения типа Num, представленного в формате Format.
функция To_Decimal (Item : в Packed_Decimal;
Format : в Packed_Format) возвращает Num;
Format : в Packed_Format) возвращает Num;
Создаёт значение типа Num, соответствующее Item, представленному в формате Format. Num'Scale — количество цифр после предполагаемой запятой в Item. Ошибка преобразования распространяется, если значение, представленное Item, выходит за пределы диапазона Num.
функция To_Packed (Item : в Num;
Format : в Packed_Format) возвращает Packed_Decimal;
Format : в Packed_Format) возвращает Packed_Decimal;
Эта функция возвращает значение Packed_Decimal для Item, представленное в соответствии с Format. Длина возвращаемого значения равна Length(Format), а нижняя граница равна 1. Ошибка преобразования распространяется, если Num отрицательно, а Format — Packed_Unsigned.
функция Valid (Item : в Byte_Array;
Format : в Binary_Format) возвращает Boolean;
Format : в Binary_Format) возвращает Boolean;
Эта функция возвращает True, если Item имеет значение, согласованное с Format, и False в противном случае.
функция Length (Format : в Binary_Format) возвращает Natural;
Эта функция возвращает минимальную длину значения Byte_Array, достаточную для хранения любого значения типа Num, представленного в формате Format.
функция To_Decimal (Item : в Byte_Array;
Format : в Binary_Format) возвращает Num;
Format : в Binary_Format) возвращает Num;
Создаёт значение типа Num, соответствующее Item, представленному в формате Format. Num'Scale — количество цифр после предполагаемой запятой в Item. Ошибка преобразования распространяется, если значение, представленное Item, выходит за пределы диапазона Num.
функция To_Binary (Item : в Num;
Format : в Binary_Format) возвращает Byte_Array;
Format : в Binary_Format) возвращает Byte_Array;
Эта функция возвращает значение Byte_Array для Item, представленное в соответствии с Format. Длина возвращаемого значения равна Length(Format), а нижняя граница равна 1.
функция To_Decimal (Item : в Binary) возвращает Num;
функция To_Decimal (Item : в Long_Binary) возвращает Num;
функция To_Decimal (Item : в Long_Binary) возвращает Num;
Эти функции преобразуют формат двоичных данных COBOL в соответствующее значение десятичного типа Num. Ошибка преобразования распространяется, если Item слишком велик для Num.
функция To_Binary (Item : в Num) возвращает Binary;
функция To_Long_Binary (Item : в Num) возвращает Long_Binary;
функция To_Long_Binary (Item : в Num) возвращает Long_Binary;
Эти функции преобразуют десятичные данные Ada в двоичный формат COBOL. Ошибка преобразования распространяется, если значение Item слишком велико для представления в типе результата.
Требования к реализации
Реализация должна поддерживать pragma Convention с COBOL convention_идентификатор для типа, совместимого с COBOL (см. B.1).
Разрешения реализации
Реализация может предоставить дополнительные константы частных типов Display_Format, Binary_Format или Packed_Format.
Реализация может предоставить дополнительные типы с плавающей запятой и целые типы в Interfaces.COBOL для соответствия дополнительным типам COBOL, а также может предоставить соответствующие функции преобразования в обобщённом пакете Decimal_Conversions.
Рекомендации по реализации
Реализация Ada должна поддерживать следующие соответствия интерфейса между Ada и COBOL.
- Параметр Ada access T передаётся как элемент данных «ПО ССЫЛКЕ» соответствующего типа COBOL для T.
- Скалярный параметр Ada in передаётся как элемент данных «ПО ЗНАЧЕНИЮ» соответствующего типа COBOL.
- Любой другой параметр Ada передаётся как элемент данных «ПО ССЫЛКЕ» соответствующего типа COBOL; для скаляров, при необходимости, используется локальная копия для обеспечения семантики передачи по значению.
ПРИМЕЧАНИЯ
14 Реализация не обязана поддерживать pragma Convention для типов доступа, ни поддерживать pragma Import, Export или Convention для функций.
15 Если подпрограмма Ada экспортируется в COBOL, то вызов из COBOL может указать либо «ПО ЗНАЧЕНИЮ», либо «ПО ССЫЛКЕ».
Примеры
Примеры из Interfaces.COBOL:
with Interfaces.COBOL;
procedure Test_Call is
procedure Test_Call is
-- Вызов внешней программы COBOL
-- Предположим, что программа COBOL PROG имеет следующее объявление
-- в своей секции LINKAGE:
-- 01 Parameter-Area
-- 05 NAME PIC X(20).
-- 05 SSN PIC X(9).
-- 05 SALARY PIC 99999V99 USAGE COMP.
-- Эффект PROG — обновление SALARY на основе некоторого алгоритма
-- Предположим, что программа COBOL PROG имеет следующее объявление
-- в своей секции LINKAGE:
-- 01 Parameter-Area
-- 05 NAME PIC X(20).
-- 05 SSN PIC X(9).
-- 05 SALARY PIC 99999V99 USAGE COMP.
-- Эффект PROG — обновление SALARY на основе некоторого алгоритма
package COBOL renames Interfaces.COBOL;
type Salary_Type is delta 0.01 digits 7;
type COBOL_Record is
record
Name : COBOL.Numeric(1..20);
SSN : COBOL.Numeric(1..9);
Salary : COBOL.Binary; -- Предположим, что Binary = 32 бита
end record;
pragma Convention (COBOL, COBOL_Record);
record
Name : COBOL.Numeric(1..20);
SSN : COBOL.Numeric(1..9);
Salary : COBOL.Binary; -- Предположим, что Binary = 32 бита
end record;
pragma Convention (COBOL, COBOL_Record);
procedure Prog (Item : in out COBOL_Record);
pragma Import (COBOL, Prog, "PROG");
pragma Import (COBOL, Prog, "PROG");
package Salary_Conversions is
new COBOL.Decimal_Conversions(Salary_Type);
new COBOL.Decimal_Conversions(Salary_Type);
Some_Salary : Salary_Type := 12_345.67;
Some_Record : COBOL_Record :=
(Name => "Johnson, John ",
SSN => "111223333",
Salary => Salary_Conversions.To_Binary(Some_Salary));
Some_Record : COBOL_Record :=
(Name => "Johnson, John ",
SSN => "111223333",
Salary => Salary_Conversions.To_Binary(Some_Salary));
begin
Prog (Some_Record);
...
end Test_Call;
Prog (Some_Record);
...
end Test_Call;
with Interfaces.COBOL;
with COBOL_Sequential_IO; -- Предполагается, что реализация предоставляет его
procedure Test_External_Formats is
with COBOL_Sequential_IO; -- Предполагается, что реализация предоставляет его
procedure Test_External_Formats is
-- Используя данные, созданные программой COBOL
-- Предположим, что программа COBOL создала последовательный файл с
-- следующей структурой записи, и нам нужно
-- обработать записи в программе Ada
-- 01 EMPLOYEE-RECORD
-- 05 NAME PIC X(20).
-- 05 SSN PIC X(9).
-- 05 SALARY PIC 99999V99 USAGE COMP.
-- 05 ADJUST PIC S999V999 SIGN LEADING SEPARATE.
-- Данные COMP являются двоичными (32 бита), байты старшего порядка впереди
-- Предположим, что программа COBOL создала последовательный файл с
-- следующей структурой записи, и нам нужно
-- обработать записи в программе Ada
-- 01 EMPLOYEE-RECORD
-- 05 NAME PIC X(20).
-- 05 SSN PIC X(9).
-- 05 SALARY PIC 99999V99 USAGE COMP.
-- 05 ADJUST PIC S999V999 SIGN LEADING SEPARATE.
-- Данные COMP являются двоичными (32 бита), байты старшего порядка впереди
package COBOL renames Interfaces.COBOL;
type Salary_Type is delta 0.01 digits 7;
type Adjustments_Type is delta 0.001 digits 6;
type Adjustments_Type is delta 0.001 digits 6;
type COBOL_Employee_Record_Type is -- Внешнее представление
record
Name : COBOL.Alphanumeric(1..20);
SSN : COBOL.Alphanumeric(1..9);
Salary : COBOL.Byte_Array(1..4);
Adjust : COBOL.Numeric(1..7); -- Знак и 6 цифр
end record;
pragma Convention (COBOL, COBOL_Employee_Record_Type);
record
Name : COBOL.Alphanumeric(1..20);
SSN : COBOL.Alphanumeric(1..9);
Salary : COBOL.Byte_Array(1..4);
Adjust : COBOL.Numeric(1..7); -- Знак и 6 цифр
end record;
pragma Convention (COBOL, COBOL_Employee_Record_Type);
package COBOL_Employee_IO is
new COBOL_Sequential_IO(COBOL_Employee_Record_Type);
use COBOL_Employee_IO;
new COBOL_Sequential_IO(COBOL_Employee_Record_Type);
use COBOL_Employee_IO;
COBOL_File : File_Type;
type Ada_Employee_Record_Type is -- Внутреннее представление
record
Name : String(1..20);
SSN : String(1..9);
Salary : Salary_Type;
Adjust : Adjustments_Type;
end record;
record
Name : String(1..20);
SSN : String(1..9);
Salary : Salary_Type;
Adjust : Adjustments_Type;
end record;
COBOL_Record : COBOL_Employee_Record_Type;
Ada_Record : Ada_Employee_Record_Type;
Ada_Record : Ada_Employee_Record_Type;
package Salary_Conversions is
new COBOL.Decimal_Conversions(Salary_Type);
use Salary_Conversions;
new COBOL.Decimal_Conversions(Salary_Type);
use Salary_Conversions;
package Adjustments_Conversions is
new COBOL.Decimal_Conversions(Adjustments_Type);
use Adjustments_Conversions;
new COBOL.Decimal_Conversions(Adjustments_Type);
use Adjustments_Conversions;
begin
Open (COBOL_File, Name => "Some_File");
Open (COBOL_File, Name => "Some_File");
loop
Read (COBOL_File, COBOL_Record);
Read (COBOL_File, COBOL_Record);
Ada_Record.Name := To_Ada(COBOL_Record.Name);
Ada_Record.SSN := To_Ada(COBOL_Record.SSN);
Ada_Record.Salary :=
To_Decimal(COBOL_Record.Salary, COBOL.High_Order_First);
Ada_Record.Adjust :=
To_Decimal(COBOL_Record.Adjust, COBOL.Leading_Separate);
... -- Обработать Ada_Record
end loop;
exception
when End_Error => ...
end Test_External_Formats;
Ada_Record.SSN := To_Ada(COBOL_Record.SSN);
Ada_Record.Salary :=
To_Decimal(COBOL_Record.Salary, COBOL.High_Order_First);
Ada_Record.Adjust :=
To_Decimal(COBOL_Record.Adjust, COBOL.Leading_Separate);
... -- Обработать Ada_Record
end loop;
exception
when End_Error => ...
end Test_External_Formats;