Spec-Zone.ru › GnuCOBOL

GnuCOBOL

Руководство по программированию GnuCOBOL

1. Введение

В данном документе описывается синтаксис, семантика и использование языка программирования COBOL, реализованного в GnuCOBOL (ранее известном как OpenCOBOL).

Первоначальными основными разработчиками GnuCOBOL были Кеисуке Нисида и Роджер Уайл. С тех пор в его разработке участвовали многие члены сообщества.

Этот документ призван служить полным справочником и руководством пользователя, подходящим как для тех, кто впервые изучает COBOL в качестве учебного пособия, так и для тех, кто уже знаком с другим диалектом COBOL.

Отдельный справочник, содержащий только подробности реализации GnuCOBOL и предназначенный для опытных программистов COBOL, был извлечен из этого руководства. Этот документ (GnuCOBOL Quick Reference) не содержит учебного материала.

Другие документы, которые следует прочитать, это gnucobol.pdf, находящийся в каталоге doc исходных кодов компилятора, и файл NEWS, поставляемый с исходным кодом компилятора GnuCOBOL в корневом каталоге. Там вы найдете последние добавленные функции языка COBOL, некоторые из которых могут отсутствовать в этом документе из-за ограничений по времени. Если вы обнаружите какие-либо, пожалуйста, сообщите об этом как об ошибке в Руководстве программиста, чтобы она могла быть исправлена.

Еще один документ, который необходимо прочитать и который углубляется в компилятор, — это часто задаваемые вопросы (FAQ), доступные через GnuCOBOL Руководства и Справочники, хотя его можно было бы немного улучшить, чтобы облегчить чтение и поиск необходимой информации.

1.1. Дополнительные источники ссылок

Для тех, кто хочет впервые изучить COBOL, Гэри настоятельно рекомендует следующие ресурсы.

Если вы предпочитаете бумажную книгу, я настоятельно рекомендую Murach’s Structured COBOL, Майкла Мурача, Энн Принс и Рауля Менендеса (2000) — ISBN 9781890774059. Майкл Мурач и его различные соавторы на протяжении десятилетий писали выдающиеся учебники по COBOL. Это отличная книга для тех, кто знаком с концепциями программирования на других языках, но не знаком с COBOL.

Вы предпочитаете онлайн-учебник? Попробуйте сайт COBOL Университета Лимерика (Ирландия) — сайт COBOL.

Кроме того, есть часто задаваемые вопросы GnuCOBOL GnuCOBOL FAQ — количество страниц которого превысило сейчас 1400 — доступный в формате HTML или в виде загружаемого файла .pdf.

Вместе с каждым выпуском исходных кодов компилятора прилагается файл NEWS. Он содержит самые актуальные обновления о компиляторе и дополнительных элементах языка COBOL, которые могут не быть ещё включены в данное руководство.

1.2. Введение в COBOL

Если вы уже знаете язык программирования, отличный от COBOL, скорее всего, это Java, C или C++. Вы обнаружите, что COBOL сильно отличается от них; иногда различия – это хорошо, а иногда – нет. Важно помнить об этом: COBOL был разработан для решения бизнес-задач.

COBOL, впервые представленный программистам в 1959 году, стал первым языком программирования, получившим стандартизацию (в 1960 году). Это означало, что программа COBOL, соответствующая стандарту, написанная на компьютере «A» компании «B», могла быть скомпилирована и выполнена на компьютере «X» компании «Y» с очень небольшими, если таковыми были, изменениями. Сегодня это может показаться не таким уж большим достижением, но это было радикальным отходом от всех языков программирования, существовавших до него, и даже многих, появившихся после него.

Название COBOL на самом деле говорит само за себя — COBOL — это аббревиатура, расшифровывающаяся как «(CO)mmоn (B)usiness (O)riented (L)anguage». Обратите внимание на то, что слово «общего» стоит перед всеми остальными. Слово «бизнес» идёт вторым. В этом и заключается ключ к успеху COBOL.

1.2.1. Почему вам стоит изучить COBOL

Несмотря на заявления «инсайдеров» индустрии, язык программирования COBOL не умер, даже несмотря на то, что более новые и так называемые «современные» языки, такие как Java, C#, .NET, Ruby on Rails и т.д., стали языками выбора в мире информационных технологий. Эти языки стали популярными, потому что они отвечают следующим желаемым требованиям для «современного» программирования:

Просто потому, что COBOL традиционно не поддерживает объекты, классы и тому подобное, не означает, что его «процедурный» подход к вычислениям не имеет ценности — в конце концов, он обрабатывает 70% бизнес-транзакций в мире и делает это:

  • Используя программы, которые, по большей части, намного более самодокументированы, чем это было бы в случае с любым другим языком программирования.
  • Легко обеспечивая точность арифметики до 31 знака с производительностью, приближающейся к производительности хорошо написанных программ на языке ассемблера. Не стоит думать, что это не критически важно для банков, инвестиционных домов и любого бизнеса, заинтересованного в отслеживании доходов, расходов и прибыли (ну, как ВСЕ они).
  • Хорошо интегрируясь с инфраструктурами, не основанными на COBOL, такими как XML, SOA, MQ, практически любыми СУБД, платформами обработки транзакций, средствами управления очередями и другими языками программирования.
  • Работая практически на таком же количестве различных вычислительных платформ, что и Java. Вы не можете запускать программы COBOL на смартфоне, но настольные компьютеры, рабочие станции, мини-фреймы/серверы, мэйнфреймы и суперкомпьютеры – все это допустимые варианты.

Современные ИТ-менеджеры и руководители бизнеса сталкиваются с непростой дилеммой — как поддерживать огромную базу кода COBOL, на которой до сих пор работают их предприятия, когда академические круги практически отказались от этого языка, необходимый их сотрудникам для поддержания работы систем? Проблема усугубляется тем, что программисты, владеющие навыками COBOL, выходят на пенсию, забирая с собой свои знания. В некоторых рынках это приводит к росту стоимости ресурсов (программистов COBOL), предложение которых становится всё меньше и меньше. Давление по обновлению приложений для использования более современных графических пользовательских интерфейсов также рассматривается как причина отказа от COBOL в пользу удобных для GUI языков, таких как Java.

Компании решают проблему COBOL различными способами:

  1. Путем проведения так называемых «проектов модернизации», в которых существующие приложения либо переписываются на «современные» языки, либо полностью заменяются приобретёнными пакетами. Большинство этих компаний используют такие мероприятия как предлог для отказа от «дорогих» мэйнфреймов в пользу (предположительно) менее дорогих решений «открытых систем» (мидфреймы/серверы).
  2. Во многих случаях эти компании обнаруживают, что стоимость инфраструктуры систем/сетевого оборудования, операционного управления и мониторинга, а также управления рисками (т. е. восстановления после катастрофы), необходимой для поддержки действительно критически важных приложений, настолько высока, что «менее дорогое» решение на самом деле не является таковым; в таких случаях мэйнфрейм может остаться лучшим вариантом, оставив COBOL в игре, и компании ищут другое решение по крайней мере для части своей базы приложений.
  3. Обучая своих собственных программистов COBOL. Поскольку колледжи, университеты и технические школы потеряли интерес к этому, многие компании взяли на себя задачу «выращивания» нового поколения программистов COBOL. Страх быть ограниченными одной нишевой технологией является фактором, препятствующим многим современным программистам добровольно участвовать в таком обучении.
  4. Путем перемещения пользовательского интерфейса на рабочий стол; такие усилия включают запуск клиентских приложений современных языков на рабочих столах пользователей (или ноутбуках, или смартфонах и т. д.) с программами COBOL, обеспечивающими серверную функциональность на мэйнфреймах или мидфреймах, предоставляя все «тяжёлые» задачи по обработке баз данных и файлов на заднем плане. Такие решения предоставляют пользователям желаемые/нужные пользовательские интерфейсы, одновременно используя сильные стороны COBOL на (возможно) урезанных системах мэйнфреймов или мидфреймов.

Вероятно, ИТ-специалисту больше нельзя позволять COBOL быть единственным инструментом в их арсенале, но с огромной базой кода, всё ещё находящейся в производстве сейчас и в обозримом будущем, добавление COBOL в многоязычный резюме (да — они РАЗНЫЕ) не является плохим решением. Знание COBOL наряду с языком «моды» сделает вас самым умным человеком в комнате, когда начнется обсуждение миграции текущей «наследственной» среды на «современную» реализацию.

Вы обнаружите, что COBOL — это лёгкий язык для изучения и гораздо легче освоить, чем многие «современные» языки.

По всей видимости, причина, по которой вы читаете это, заключается в том, что вы открыли для себя GnuCOBOL — ещё одну реализацию COBOL помимо уже упомянутых. Отличительной чертой GnuCOBOL от других является то, что GnuCOBOL является БЕСПЛАТНЫМ открытым исходным кодом и, следовательно, БЕСПЛАТЕН для получения и использования. Он улучшается и поддерживается сообществом. Позже в этом документе (см. Что такое GnuCOBOL?) вы начнёте узнавать больше о возможностях этой реализации COBOL.

1.2.2. Производительность программистов

На протяжении всей истории компьютерного программирования поиск новых способов повышения производительности программистов был важным фактором. Помимо любителей, программирование — это деятельность, выполняемая за деньги, и предприятия не любят тратить больше, чем абсолютно необходимо; даже государственные учреждения пытаются потратить как можно меньше денег на проекты.

Объём программирования, необходимого для выполнения заданной задачи, включая переработку, необходимую для исправления любых ошибок, обнаруженных во время тестирования (тестирование иногда шутливо определяется как: время, когда приложение фактически находится в производстве, позволяя пользователям обнаруживать проблемы), является мерой производительности программиста. Всё, что уменьшает эти усилия, соответственно уменьшает время, затраченное на такие действия, и, следовательно, уменьшает расходы на них. Когда расходы на программирование снижаются, повышается производительность программистов.

Иногда поиск повышения производительности программистов (и, следовательно, снижения расходов на программирование) принимал форму введения новых функций в языках программирования или даже в новых языках вообще. Иногда это приводило к новым способам использования существующих языков.

Хотя многие технологические и процедурные разработки внесли эволюционные улучшения в производительность программистов, каждое из следующих трёх событий стало причиной революционных улучшений:

  • Развитие так называемых языков программирования «высокого уровня», которые позволяют программисту в одном операторе языка указать действие, для которого в предыдущих языках программирования потребовалось бы гораздо больше отдельных операторов. Стандартизация таких языков, позволяющая использовать их на широком спектре компьютеров и операционных систем, являлась ключевым аспектом этого развития. COBOL был новаторским развитием в этой области, являясь прямым потомком первого языка высокого уровня (FLOW-MATIC, разработанного лейтенантом ВМС США Грейс Хоппер) и первым стандартизированным языком.
  • Разработка методик программирования, которые делают программы более читаемыми и, следовательно, более понятными. Такие методики не только уменьшают объем переработки, необходимой просто для того, чтобы программа работала так, как задумано, но и сокращают время, необходимое программисту для изучения существующей программы, чтобы адаптировать её к изменяющимся бизнес-требованиям. Главным развитием в этой области было структурное программирование. Введенный в конце 1970-х годов, этот подход к программированию породил новые языки программирования (PASCAL, ALGOL, PL/1 и так далее), разработанные на его основе. Со стандартом ANSI 85, COBOL также принял принципы, проповедуемые экспертами в области структурного программирования, а также любых языков, разработанных строго на его основе.
  • Разработка методик программирования и внедрение возможностей языков программирования для облегчения повторного использования кода программ. Всё, что способствует повторному использованию кода, может существенно повлиять на время разработки новых приложений или внесения значительных изменений в существующие. В последние годы объектно-ориентированное программирование (ООП) стало для отрасли «образцовым примером» для повторного использования кода. Позволяя логике программы и структурам данных, которые обрабатывает эта логика, быть инкапсулированными в легко сохраняемые и извлекаемые (и, следовательно, «переиспользуемые») модули, называемые классами, объектно-ориентированные языки, такие как Java, C++ и C#, стали фаворитами в академических кругах. Поскольку студенты обучаются именно этим языкам, неудивительно, что сегодня объектно-ориентированные языки программирования являются любимцами отрасли.

    Однако на самом деле опытные программисты практикуют повторное использование кода уже более полувека. До недавнего времени у программистов COBOL были одни из лучших инструментов для повторного использования кода — они делали это с помощью копий и подпрограмм, а не классов, методов и атрибутов, но конечный результат был похожим. Благодаря стандартам COBOL2002 и COBOL 2014, язык программирования COBOL стал таким же «объектно-ориентированным», как и «современные» языки, сохраняя при этом возможность поддержки, модификации, компиляции и выполнения «наследованных» программ COBOL.

Хотя GnuCOBOL поддерживает лишь немногие из конструкций ООП, определённых стандартами COBOL2002 и COBOL2014, он поддерживает все аспекты стандарта ANSI 85, а значит, полностью удовлетворяет потребностям пунктов #1 и #2, указанных выше. Благодаря своему набору функций (см. Что такое GnuCOBOL?), он предоставляет значительные возможности для повышения производительности программистов.

1.3. Что такое GnuCOBOL?

GnuCOBOL — это свободный и открытый компилятор COBOL и среда выполнения, написанная на языке программирования C. GnuCOBOL обычно распространяется в виде исходного кода и должен быть скомпилирован для операционной системы вашего компьютера с помощью системного компилятора C и загрузчика. Хотя первоначально он был разработан для операционных систем UNIX и Linux, GnuCOBOL также успешно был скомпилирован для компьютеров под управлением OSX и Windows с использованием возможностей эмуляции UNIX, таких как Cygwin и MinGW. Также см. веб-сайт GNU для получения дополнительной информации.

Подход с использованием MinGW является личным фаворитом автора этого руководства, так как он создаёт компилятор и библиотеку времени выполнения GnuCOBOL, которым требуется только одна DLL MinGW для компилятора, библиотеки времени выполнения и пользовательских программ GnuCOBOL. Эта DLL распространяется бесплатно на условиях GNU General Public License. Сборка GnuCOBOL под MinGW легко помещается на флэш-накопитель объёмом 128 МБ и запускается с него без необходимости установки каких-либо программ на компьютер под управлением Windows, который будет его использовать. Однако некоторые функции языка, связанные с обменом файлами между одновременно выполняемыми программами GnuCOBOL и блокировкой записей в определённых типах файлов, жертвуются, так как необходимые для их реализации системные функции операционной системы недоступны в Windows и не предоставляются MinGW. Текущая версия для MinGW доступна по ссылке для скачивания, наряду с другими платформами на веб-сайте загрузки GnuCOBOL .

GnuCOBOL также был разработан как полностью нативное приложение для Windows, используя бесплатный пакет Visual Studio Express от Microsoft для предоставления компилятора C и компоновщика/загрузчика. Этот подход не подходит для «портативного» распространения.

Компилятор GnuCOBOL генерирует код C из ваших программ COBOL; этот код C затем автоматически компилируется и компонуется с помощью системного компилятора C (обычно, но не только, gcc).

GnuCOBOL полностью поддерживает стандарт ANSI 85 для COBOL (единственное существенное исключение — Модуль связи) и также поддерживает некоторые компоненты стандартов COBOL2002 и COBOL2014, такие как SCREEN SECTION (см. РАЗДЕЛ ЭКРАНА), табличные SORT (см. СОРТИРОВКА ТАБЛИЦ) и пользовательские функции. Есть и другие, и почти каждую неделю добавляются новые.

2. Основы COBOL

В этой главе описывается синтаксис, семантика и использование языка программирования COBOL, реализованного в текущей версии GnuCOBOL. В дальнейшем в этом документе язык будет обозначаться как COBOL для удобства чтения, однако имя компилятора сохраняет смешанный регистр GnuCOBOL.

Этот документ предназначен в качестве исчерпывающего справочника и руководства пользователя, подходящего как для читателей, впервые изучающих COBOL, так и для тех, кто уже знаком с некоторыми диалектами языка COBOL.

Существует отдельный справочник, содержащий только подробности грамматики Cobol, реализованной в GnuCOBOL, который предназначен строго для опытных программистов COBOL, и он взят из этого руководства. Он НЕ содержит учебного материала.

Эти дополнительные руководства: «Быстрый справочник GnuCOBOL», содержащий только семантику/грамматику COBOL в кратком документе, а другой — «Примеры программ GnuCOBOL», демонстрирует подробные примеры программ Cobol с указанием синтаксиса, используемого в каждой программе.

Для каждой реализации компилятора GnuCOBOL следует также прочитать файлы NEWS для получения любых последних обновлений, а также файлы README и INSTALL для сборки компилятора.

2.1. Язык COBOL — Основы

2.1.1. Зарезервированные слова языка

Программы Cobol состоят из последовательности слов и символов. Слова, состоящие из последовательности букв (строчных и/или прописных), цифр, дефисов (‘-’) и/или подчеркиваний (‘_’), могут иметь предварительно определенное, специфическое значение для компилятора или быть придуманы программистом для своих целей.

Спецификация языка GnuCOBOL определяет более 1130 зарезервированных слов — слов, которым компилятор присваивает специальное значение. Этот список и число относятся к стандартному списку, который охватывает многие реализации, и что возможно ограничить список либо конкретной реализацией с помощью -std=xyz[-strict], либо вручную разрезервировать слова, если они используются в существующих источниках как пользовательские слова.

Программисты могут использовать зарезервированное слово как часть слова, которое они создают сами, но не могут создавать свои собственные слова как точные дубликаты (не обращая внимания на регистр) зарезервированного слова COBOL. Обратите внимание, что зарезервированное слово включает все классы, такие как встроенные функции, мнемоники, системные процедуры и зарезервированные слова. Список зарезервированных слов можно изменить, добавив или удалив определенные слова для данного компиляции или по умолчанию с помощью управляющей команды -std и -conf. См. конкретные файлы конфигурации, которые по умолчанию хранятся в /usr/local/share/gnucobol/config. Также использование опции ‘FUNCTION ALL INTRINSIC’ добавит еще 100+ зарезервированных слов. Их можно изменить, чтобы соответствовать требованиям бизнес- или проектной группы, но будьте осторожны, что они обновляются при построении новой версии компилятора, поэтому может быть более целесообразно создать собственную конфигурацию на основе существующей, но с другим именем.

Кроме того, вы можете добавлять и/или удалять зарезервированные слова, добавив одну из этих опций в cobc, чтобы добавить -freserved-words=value или -freserved=word или, чтобы удалить, -fnot-reserved=word. А также -freserved=word:alias, чтобы создать псевдоним для слова, а также -fnot-register=word или -fregister=word, чтобы удалить или добавить специальное зарезервированное слово.

См. Приложение B — Список зарезервированных слов для получения полного списка зарезервированных слов GnuCOBOL.

Для любой версии GnuCOBOL вы также можете перечислить весь текущий набор зарезервированных слов, запустив cobc с --list-reserved, --list-intrinsic, --list-system, а также --list-mnemonics. Опять же, это может изменяться в зависимости от использования команды --std.

2.1.2. Пользовательские слова

При написании программ GnuCOBOL вам необходимо создать различные слова для представления различных аспектов программы, данных программы и внешней среды, в которой будет работать программа. Это будет включать внутренние имена, по которым будут ссылаться на файлы данных, имена элементов данных и имена процедур исполняемого логического кода.

Пользовательские слова могут быть составлены из символов ‘A’ до ‘Z’ (строчных и/или прописных), ‘0’ до ‘9’, дефиса (‘-’) и подчеркивания (‘_’). Пользовательские слова не могут начинаться или заканчиваться дефисом или символом подчеркивания.

Другие языки программирования предоставляют программисту аналогичную возможность создавать свои собственные слова (имена) для частей программы; COBOL несколько необычен по сравнению с другими языками тем, что пользовательские слова могут начинаться с цифры.

За исключением имен процедур логики, которые могут состоять только из цифр, пользовательские слова должны содержать по крайней мере одну букву.

2.1.3. Нечувствительность к регистру

Все реализации COBOL позволяют использовать как прописные, так и строчные буквы в кодировании программ. GnuCOBOL полностью нечувствителен к регистру при написании зарезервированных слов или пользовательских имен. Таким образом, AAAAA, aaaaa, Aaaaa и AaAaA — это одно и то же слово с точки зрения GnuCOBOL.

Единственный случай, когда регистр имеет значение, — это внутри строковых литералов, где значения символов будут точно такими, как закодированы.

Согласно принятой в этом документе конвенции, служебные слова COBOL будут отображаться полностью в UPPER-CASE, а слова, созданные программистом, будут представлены маркерами в смешанном или нижнем регистре.

Это не плохая практика для использования в реальных программах, так как она приводит к программам, в которых гораздо легче различать служебные слова и слова, определенные пользователем!

2.1.4. Читабельность программ

Критики COBOL часто фокусируются на многословности языка, часто приводя в качестве примера программу «Hello World» как «доказательство» того, что программирование на COBOL значительно более трудоёмкое, чем на более «современных» языках. Эта трудоёмкость рассматривается как значительное влияние на производительность программистов, по их мнению, COBOL не может исчезнуть достаточно быстро.

Ниже приведены две различные программы «Hello World», одна написанная на Java, а вторая — на GnuCOBOL. Сначала версия на Java:

    Class HelloWorld {
        public static void main(String[] args) {
            System.out.println("Hello World!");
        }
    }

И вот та же программа, написанная на GnuCOBOL:

    IDENTIFICATION DIVISION.
    PROGRAM-ID. HelloWorld.
    PROCEDURE DIVISION.
        DISPLAY "Hello World!".

Обе вышеперечисленные программы могли бы быть написаны в одну строку, если бы этого желали, и оба языка позволяют программисту использовать (или не использовать) отступы по своему усмотрению для улучшения читабельности программы. На данный момент это похоже на ничью.

Давайте посмотрим, насколько больше «многословнее» COBOL по сравнению с Java. Посчитайте количество символов в обеих программах. Программа на Java содержит 95 символов (не считая символов возврата каретки и отступов). Программа на COBOL содержит 89 символов (опять же, не считая символов возврата каретки и отступов)! Теоретически, их могло быть всего 65, так как заголовок IDENTIFICATION DIVISION. фактически является необязательным. Очевидно, что «Hello World» выглядит не более лаконично на Java, чем на COBOL.

Давайте рассмотрим другую задачу. Конечно, программа, которая попросит пользователя ввести положительное целое число, вычислит сумму всех положительных целых чисел от 1 до этого числа и затем выведет результат, будет намного короче и намного проще для понимания, когда она написана на Java, чем на COBOL, верно?

Вы можете судить сами. Сначала версия на Java:

    import java.util.Scanner;
    public class sumofintegers {
        public static void main(String[] arg) {
            System.out.println("Enter a positive integer");
            Scanner scan=new Scanner(System.in);
            int n=scan.nextInt();
            int sum=0;
            for (int i=1;i<=n;i++) {
                sum+=i;
            }
            System.out.println("The sum is "+sum);
        }
    }

И теперь версия на COBOL:

    IDENTIFICATION DIVISION.
    PROGRAM-ID. SumOfIntegers.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01 n   BINARY-LONG.
    01 i   BINARY-LONG.
    01 sum BINARY-LONG VALUE 0.
    PROCEDURE DIVISION.
    DISPLAY "Enter a positive integer"
    ACCEPT n
    PERFORM VARYING i FROM 1 BY 1 UNTIL i > n
        ADD i TO sum
    END-PERFORM
    DISPLAY "The sum is " sum.

Моя осведомленность о COBOL может предвзято влиять на моё мнение, но мне не кажется, что код на Java проще, чем код на COBOL. Если вас интересует количество символов, код на Java содержит 278 символов (не считая символов отступа). Код на COBOL — 298 символов (274 без заголовка IDENTIFICATION DIVISION.).

Несмотря на то, что вы увидели здесь, чем сложнее программная логика, тем более лаконичным будет выглядеть код на Java, даже по сравнению с COBOL стандарта 2002 года. Однако такая краткость имеет свою цену — читабельность программного кода. Программы на Java (или C, C++, C#) обычно понятны только подготовленным программистам. Программы на COBOL могут быть достаточно понятны и непрограммистам. Это фактически побочный эффект «многословности» языка, где инструкции COBOL используют естественные английские слова для описания своих действий. Эта встроенная читабельность много раз помогала мне на протяжении всей моей карьеры, когда мне приходилось изучать неясные бизнес-(или юридические) процессы, читая код программ на COBOL, который их поддерживает.

В «современных» языках, таких как Java, также есть собственная «шаблонная» инфраструктурная накладная, которая должна быть закодирована для написания необходимой логики в программе. Например, рассмотрите инструкции public static void main(String[] arg) и import java.util.Scanner;. Критики склонны забывать об этом, когда критикуют COBOL за его структурную «накладную».

Когда COBOL был разработан, его легко читаемый синтаксис резко отличался от всего, что было раньше. Впервые появилась возможность описывать логику таким образом, который — по крайней мере в некоторой степени — был понятен даже непрограммистам. Например, рассмотрим следующий код, написанный на FORTRAN — языке, разработанном всего за год до COBOL:

    EXT = PRICE * IQTY
    INVTOT = INVTOT + EXT

С его первоначальным ограничением на длину имён переменных (имена длиной от одного до шести символов, состоящие из буквы, за которой следует до пяти букв и/или цифр), его неявным правилом, согласно которому переменные автоматически создавались как вещественные (с плавающей точкой), если их имя не начиналось с буквы в диапазоне I-N, и его использованием алгебраической нотации для выражения выполняемых действий, FORTRAN не был особенно удобочитаемым языком, даже для программистов. Сравните это с эквивалентным кодом COBOL:

    MULTIPLY price BY quantity GIVING extended-amount
    ADD extended-amount TO invoice-total

Очевидно, даже непрограммист мог бы по крайней мере концептуально понять, что происходит! Со временем языки, подобные FORTRAN, эволюционировали к более мощным именам переменных, а COBOL ввёл более формулированную синтаксическую возможность для арифметических операций, но FORTRAN так и не стал таким удобочитаемым, как COBOL.

Благодаря своей встроенной читабельности, я гораздо предпочел бы получить задание внести существенные изменения в программу на COBOL, о которой я ничего не знаю, чем быть попрошенным сделать то же самое с программой на C, C++, C# или Java.

Те, кто утверждают, что программирование программы на COBOL «с нуля» слишком скучно/непродуктивно/долго/обидно (выберите одно), явно не знают следующих фактов:

  • Многие системы имеют инструменты разработки программ, облегчающие процесс кодирования программ; инструменты, ориентированные на COBOL, способны предоставлять шаблоны для большей части «вспомогательного» словесного оформления любой программы…
  • Опытные программисты — на протяжении десятилетий — поддерживали собственные каркасные «шаблонные» программы для различных типов программ; просто загрузите шаблон в текстовый редактор, и у вас будет хорошее начало программы…
  • Существует легенда, что на самом деле была только ОДНА программа, написанная на COBOL, и все программы, «написанные» впоследствии, были просто производными от этой одной. Хотя это явно задуманная (вероятно, плохая) шутка, тем не менее, она близка к очень простой истине, что многие программисты «переиспользуют» существующие программы COBOL при создании новых. Конечно, ничего не мешает этому происходить с программами, написанными на других языках, но это, похоже, чаще происходит в компаниях, использующих COBOL. Иронично, что «повторное использование кода» — один из аргументов, используемых для оправдания существования «современных» языков.

2.1.5. Разделы Организуют Программы

Программы COBOL структурированы в четыре основных области кодирования, каждая со своей целью. Эти четыре области известны как разделы.

Каждый раздел может состоять из различных секций, а каждая секция состоит из одного или нескольких параграфов. Параграф состоит из предложений, каждое из которых состоит из одного или нескольких операторов.

Эта иерархическая структура компонентов программы стандартизирует состав всех программ COBOL. Большая часть этого руководства описывает различные разделы, секции, параграфы и операторы, которые могут составлять любую программу COBOL. %%%CODE_BLOCK_18%% оператор (см. COPY)

2.1.6. Книжки-копии

Книга-копия — это фрагмент программного кода, который может использоваться несколькими программами, просто добавив в эти программы использование COPY оператора для импорта этого кода. Этот код может определять файлы, структуры данных или процедурный код.

Современные языки программирования имеют оператор (обычно этот оператор называется «импорт», «включение» или «#include»), который выполняет ту же функцию. Однако то, что отличает функцию книги-копии COBOL от функции «включения» в новых языках, заключается в том, что COPY оператор может редактировать импортированный исходный код по мере его копирования. Эта возможность делает библиотеки книг-копий чрезвычайно ценными для повторного использования кода. Также см. раздел 3. Команды компилятора COPY и REPLACE.

2.1.7. Структурированные данные

Непрерывный участок памяти в адресном пространстве программы, который может ссылаться по имени в программе COBOL, называется Элементом данных. Другие языки программирования используют термины переменная, свойство или атрибут для описания того же.

COBOL представил понятие структурированных данных. Принцип структурированных данных в COBOL основан на возможности группировать связанные и непрерывно размещенные элементы данных вместе в один агрегированный элемент данных, называемый Групповым элементом. Например, групповой элемент «Имя-сотрудника» длиной 35 символов может состоять из элемента «Фамилия» длиной 20 символов, за которым следует элемент «Имя» длиной 14 символов и инициал среднего имени длиной 1 символ.

Элемент данных, который сам по себе не образован из других элементов данных, в COBOL называется Элементарным элементом. В предыдущем примере «Фамилия», «Имя» и «Инициал среднего имени» — все элементарные элементы.

2.1.8. Файлы

Одно из преимуществ COBOL заключается в широком разнообразии файлов данных, к которым он может получить доступ. Программы GnuCOBOL, как и те, которые созданы с другими реализациями COBOL, должны иметь описание структуры любых файлов, которые они будут читать и/или записывать. Наиболее высокий уровень характеристик структуры файла определяется указанием организации файла следующим образом:

ORGANIZATION LINE SEQUENTIAL

Это файлы с простейшей внутренней структурой. Их содержимое структурировано просто как серия записей данных одинакового или разного размера, каждая из которых завершается специальным символом разделителя конца записи. Символ ASCII новой строки (шестнадцатеричный 0A) является символом разделителя конца записи, используемым в любом билде GnuCOBOL под UNIX или псевдо-UNIX (MinGW, Cygwin, OSX). Истинный билд под Windows будет использовать последовательность возврата каретки, новой строки (шестнадцатеричный 0D0A).

Записи должны читаться или записываться в эти файлы исключительно последовательным образом. Единственный способ прочитать (или записать) запись номер 100 — это предварительно прочитать (или записать) записи с номера 1 по 99.

Когда файл записывается программой GnuCOBOL, последовательность разделителей автоматически добавляется к каждой записи данных при записи в файл. Операция WRITE (см. WRITE) в этом типе файла будет выполняться так, как если бы был указан BEFORE ADVANCING 1 LINE-оператор в WRITE, если ADVANCING-оператор не указан.

При чтении файла система выполнения GnuCOBOL удалит последовательность разделителей из каждой записи. Данные будут дополнены пробелами справа, если прочитанные данные короче области, описанной для записей данных в программе. Если данные слишком длинные, они будут усечены, и избыток будет потерян.

Эти файлы не должны быть определены как содержащие какие-либо точные бинарные поля данных, потому что содержимое этих полей может случайно содержать последовательность конца записи в качестве части своих значений — это могло бы сбить систему выполнения при чтении файла, и она могла бы интерпретировать это значение как фактическую последовательность конца записи.

LINE ADVANCING

Это файлы с внутренней структурой, аналогичной структуре файла с последовательной записью по строкам. Эти файлы определяются (без явного указания ORGANIZATION-оператор) с помощью LINE ADVANCING-оператор в операторе SELECT (см. SELECT).

Когда этот тип файла записывается программой GnuCOBOL, последовательность разделителей конца записи будет автоматически добавлена к каждой записи данных при записи в файл. Операция WRITE в этом типе файла будет выполняться так, как если бы был указан AFTER ADVANCING 1 LINE-оператор в WRITE, если ADVANCING-оператор не указан.

Как и файлы с последовательной записью по строкам, эти файлы не должны быть определены как содержащие какие-либо точные бинарные поля данных, так как содержимое этих полей может случайно включать последовательность конца записи в свои значения — это могло бы сбить систему выполнения при чтении файла и привести к её неправильной интерпретации значения как последовательности конца записи.

ORGANIZATION SEQUENTIAL

В этих файлах также простая внутренняя структура. Их содержимое организовано как произвольно длинная последовательность символов данных. Эта последовательность символов будет обрабатываться как серия записей фиксированной длины, просто логически разбивая последовательность символов на сегменты фиксированной длины, каждый длиной, равной максимальному размеру записи, определённому в программе. В файле нет специальных символов разделителей конца записи, и при записи файла программой GnuCOBOL никакая последовательность разделителей к данным не добавляется.

Записи в этом типе файла имеют одинаковую физическую длину, за исключением, возможно, последней записи в файле, которая может быть короче других. Если в программе определены логические записи переменной длины, то занимаемое каждым физическим записям в файле пространство будет соответствовать пространству, описанному самой длинной записью в программе.

Итак, если файл содержит 1275 символов данных, а программа определяет структуру этого файла как содержащую записи по 100 символов, то содержимое файла будет состоять из двенадцати (12) записей по 100 символов, а последняя запись будет содержать только 75 символов.

По-видимому, можно найти и обработать любую запись в файле непосредственно, просто вычислив её начальную позицию символа на основе размера записи, определённого программой. Однако, тем не менее, записи всё ещё должны читаться или записываться в эти файлы исключительно последовательно. Единственный способ прочитать (или записать) запись номер 100 — это предварительно прочитать (или записать) записи с номерами от 1 до 99.

При чтении файла данные передаются в программу точно так же, как они существуют в файле. В случае, если короткая запись считывается как последняя запись, эта запись будет дополнена (справа) пробелами.

Следует принять меры, чтобы программы, читающие такой файл, описывали записи, длина которых точно соответствует длине, используемой программой, которая создала файл. Например, ниже показано содержимое файла SEQUENTIAL, созданного программой, которая записала в него пять записей по 6 символов. Значения «A», «B», … отражают записи, которые были записаны в файл:

‘AAAAAA’
‘BBBBBB’
‘CCCCCC’
‘DDDDDD’
‘EEEEEE’

Теперь предположим, что другая программа читает этот файл, но описывает записи по 10 символов вместо 6. Вот записи, которые эта программа будет читать:

‘AAAAAABBBB’
‘BBCCCCCCDD’
‘DDDDEEEEEE’

Иногда это именно то, что вам нужно. Однако чаще всего такого поведения нежелательно. Рекомендация: используйте копибук для описания структуры записей любого файла; это гарантирует, что несколько программ, обращающихся к этому файлу, будут «видеть» одни и те же размеры и структуры записей, закодировав оператор COPY, (см. COPY) для импорта структуры записи, а не кодируя её вручную.

Эти файлы могут содержать точные бинарные поля данных. Поскольку никакая последовательность символов не является разделителем конца записи, содержимое полей записи не имеет значения для процесса чтения.

ORGANIZATION RELATIVE

Содержимое этих файлов состоит из серии записей данных фиксированной длины, предваряемых четырёхбайтовым заголовком записи. Заголовок записи содержит длину данных в байтах. Счёт байтов не включает четырёхбайтовый заголовок записи.

Все записи в этом типе файла имеют одинаковую физическую длину. Если в программе определены логические записи переменной длины, то занимаемое каждым физическим записям в файле пространство будет соответствовать максимальному возможному пространству, а поле длины логической записи будет содержать количество байтов данных в записи, которые фактически используются.

Данная организация файлов была разработана для поддержки как последовательной, так и произвольной обработки. С файлом RELATIVE, можно напрямую читать или записывать запись 100, не читая или не записывая предварительно записи с номерами 1-99. Система выполнения GnuCOBOL использует заданный программой максимальный размер записи для вычисления относительной байтовой позиции в файле, где начинаются заголовок записи и данные, а затем передаёт необходимые данные в программу или из программы.

При записи файла программой GnuCOBOL никакая последовательность разделителей к данным не добавляется, но в начало каждого физического файла добавляется поле длины записи.

При чтении файла данные передаются в программу точно так же, как они существуют в файле.

Следует принять меры, чтобы программы, читающие такой файл, описывали записи, длина которых точно соответствует длине, используемой программами, которые создали файл. Плохо, если библиотека GnuCOBOL runtime интерпретирует четырёхбайтовую строку ASCII символов как длину записи при передаче данных из файла в программу!

Рекомендация: используйте копибук для описания структуры записей любого файла; это гарантирует, что несколько программ, обращающихся к этому файлу, будут «видеть» одни и те же размеры и структуры записей, закодировав оператор COPY, (см. COPY) для импорта структуры записи, а не кодируя её вручную.

Эти файлы могут содержать точные бинарные поля данных. Содержимое полей записи не имеет значения для процесса чтения, так как нет разделителя конца записи.

ORGANIZATION INDEXED

Это самая продвинутая структура файлов, доступная для программ GnuCOBOL. Невозможно описать физическую структуру таких файлов, поскольку она будет зависеть от того, какие средства управления файлами были включены в сборку GnuCOBOL, которую вы будете использовать (Berkeley Database [BDB], VBISAM и т. д.). Вместо этого мы обсудим логическую структуру файла.

Для файла INDEXED будет храниться несколько структур. Первая будет компонентом данных, который можно представить как аналогичный внутренней структуре файла с относительным адресом. Однако к записям данных нельзя получить прямой доступ по их номеру записи, как в случае с файлом с относительным адресом, и их нельзя обработать последовательно по их физической последовательности в файле.

Остальные структуры будут одним или несколькими компонентами индексов. Компонент индекса — это структура данных, которая (как-то) позволяет преобразовать содержимое поля, называемого первичным ключом, в каждой записи данных (номер клиента, номер сотрудника, код продукта, имя и т. д.), в номер записи, чтобы запись данных для любого заданного значения первичного ключа можно было непосредственно читать, записывать и/или удалять. Кроме того, структура данных индекса определена таким образом, чтобы позволить обрабатывать файл последовательно, запись за записью, в возрастающей последовательности значений поля первичного ключа. То, существует ли эта структура индекса в виде структуры двоичного поиска (b-дерево), сложной структуры хешей или чего-то еще, практически не имеет значения для программиста — поведение структуры будет таким, как только что описано. Фактический используемый механизм будет зависеть от пакета расширенного управления файлами, включенного в вашу реализацию GnuCOBOL при её построении.

Система выполнения не позволит записывать две записи в индексированный файл с одинаковым значением первичного ключа.

Существует возможность определения дополнительного поля в качестве так называемого альтернативного ключа. Поля альтернативных ключей ведут себя так же, как первичные ключи, позволяя осуществлять как прямой, так и последовательный доступ к данным записи на основе значений поля альтернативного ключа, за исключением одного момента. Это тот факт, что альтернативным ключам может быть разрешено иметь дублирующие значения, в зависимости от того, как альтернативное поле ключа описано компилятору GnuCOBOL.

Может быть любое количество альтернативных ключей, но каждое поле ключа имеет свою цену в занимаемом дисковом пространстве, а также цену во времени выполнения. По мере увеличения количества полей альтернативных ключей запись и/или изменение записей в файле будет занимать всё больше и больше времени.

Эти файлы могут содержать поля точных двоичных данных. Содержимое полей записи не имеет значения для процесса чтения, так как нет разделителя конца записи.

Все файлы изначально описываются программе GnuCOBOL с помощью оператора SELECT (см. SELECT). Помимо определения имени, по которому файл будет ссылаться внутри программы, оператор SELECT будет указывать имя и путь, по которому файл будет известен операционной системе, вместе с его атрибутами организации, блокировки и совместного использования.

Описание файла в FILE SECTION (см. РАЗДЕЛ ФАЙЛОВ) определит структуру записей внутри файла, включая возможность переменной длины записей и, если это возможно, минимальную и максимальную длину. Кроме того, запись описания файла может указывать размеры блоков ввода-вывода файла.

2.1.9. Обработка таблиц

В других языках программирования есть массивы; в COBOL есть таблицы. По сути, это одно и то же. В языке COBOL есть два специальных оператора — SEARCH и SEARCH ALL — которые упрощают поиск данных в таблице.

SEARCH выполняет последовательный поиск в таблице, останавливаясь только тогда, когда найдена запись таблицы, соответствующая одному из любого количества условий поиска, или когда все записи таблицы были проверены по критериям поиска и ни одна из них не соответствовала ни одному из этих критериев.

SEARCH ALL выполняет чрезвычайно быстрый поиск в отсортированной по ключевому полю таблице, содержащейся в каждой записи таблицы. Алгоритм, используемый для такого поиска, — это двоичный поиск. Алгоритм гарантирует, что для поиска желаемой записи или определения того, что желаемой записи в таблице нет, необходимо проверить лишь небольшое количество записей в таблице. Чем больше таблица, тем эффективнее этот поиск. Например, двоичный поиск в таблице, содержащей 32 768 записей, найдёт конкретную запись или определит, что её нет, проверив не более пятнадцати (15) записей! Алгоритм подробно описан в документации оператора SEARCH ALL (см. SEARCH ALL).

Наконец, COBOL имеет возможность выполнять сортировку данных в таблице на месте.

2.1.10. Сортировка и слияние данных

Язык COBOL включает мощный оператор SORT, который может сортировать большие объемы данных по произвольно сложным структурам ключей. Эти данные могут поступать из программы или содержаться в одном или нескольких внешних файлах. Отсортированные данные могут быть автоматически записаны в один или несколько выходных файлов или обработаны по записи в отсортированной последовательности.

Сопутствующее утверждение — MERGE — может объединить содержимое нескольких файлов, при условии, что все эти файлы предварительно отсортированы похожим образом по той же структуре ключей. Результирующий вывод будет состоять из содержимого всех входных файлов, объединенных вместе и упорядоченных в соответствии с общей структурой ключей. Вывод, сгенерированный утверждением MERGE, может быть автоматически записан в один или несколько выходных файлов или может быть обработан внутри программы.

Существует специальная форма утверждения SORT, предназначенная для сортировки данных, находящихся в таблице. Это особенно полезно, если вы хотите использовать SEARCH ALL для работы с таблицей.

2.1.11. Обработка строк

Были разработаны языки программирования, специально предназначенные для обработки текстовых строк, и были разработаны языки программирования, предназначенные исключительно для выполнения сложных числовых вычислений. Большинство языков программирования занимают промежуточное положение.

COBOL не является исключением, хотя он включает некоторые очень мощные возможности работы со строками; GnuCOBOL фактически обладает еще большими возможностями обработки строк, чем многие другие реализации COBOL. Ниже приводится краткое описание возможностей обработки строк в GnuCOBOL:

Конкатенация двух или более строк
  • CONCATENATE встроенная функция (см. CONCATENATE).
  • STRING оператор (см. STRING).
Преобразование числового времени или даты в отформатированную строку символов
  • LOCALE-TIME встроенная функция (см. LOCALE-TIME).
  • LOCALE-DATE встроенная функция (см. LOCALE-DATE).
Преобразование двоичного значения в соответствующий символ в наборе символов программы
  • CHAR встроенная функция (см. CHAR). Добавить 1 к аргументу перед вызовом функции; описание CHAR встроенной функции представляет технику использования оператора MOVE, которая позволит добиться того же результата без необходимости предварительного добавления 1 к числовому значению аргумента.
Преобразование строковой переменной в нижний регистр
  • LOWER-CASE встроенная функция (см. LOWER-CASE).
  • C$TOLOWER встроенная системная подпрограмма (см. C$TOLOWER).
  • CBL_TOLOWER встроенная системная подпрограмма (см. CBL_TOLOWER).
Преобразование строковой переменной в верхний регистр
  • UPPER-CASE встроенная функция (см. UPPER-CASE).
  • C$TOUPPER встроенная системная подпрограмма (см. C$TOUPPER).
  • CBL_TOUPPER встроенная системная подпрограмма (см. CBL_TOUPPER).
Преобразование строковой переменной в набор только печатных символов
  • C$PRINTABLE встроенная системная подпрограмма (см. C$PRINTABLE).
Преобразование символа в его числовое значение в наборе символов программы
  • ORD встроенная функция (см. ORD). Вычесть 1 из результата; описание ORD встроенной функции представляет технику использования оператора MOVE, которая позволит добиться того же результата без необходимости предварительного добавления 1 к числовому значению аргумента.
Подсчёт вхождений подстрок в большей строке
  • INSPECT оператор (см. INSPECT) с TALLYING оговоркой.
Декодирование отформатированной числовой строки в числовое значение
  • NUMVAL встроенная функция (см. NUMVAL).
  • NUMVAL-C встроенная функция (см. NUMVAL-C).
Определение длины строки или элемента данных, способного хранить строки
  • LENGTH встроенная функция (см. LENGTH).
  • BYTE-LENGTH встроенная функция (см. BYTE-LENGTH).
Извлечение подстроки из строки на основе её начальной позиции символа и длины
  • Использование модификатора ссылки для поля строки - См. Модификаторы ссылок.
Форматирование числового элемента для вывода, включая разделители тысяч (‘,’ в США), знаки валюты (‘$’ в США), десятичные точки, знаки кредита/дебета, ведущие или хвостовые знаки
  • MOVE оператор (см. MOVE) с применением редактирования символов формата к принимаемому полю:
Выравнивание (слева, справа или по центру) поля строки
  • C$JUSTIFY встроенная системная подпрограмма (см. C$JUSTIFY).
Моноалфавитное замещение одного или нескольких символов в строке другими символами
  • INSPECT оператор (см. INSPECT) с CONVERTING.
  • TRANSFORM оператор (см. TRANSFORM).
  • SUBSTITUTE встроенная функция (см. SUBSTITUTE).
  • SUBSTITUTE-CASE встроенная функция (см. SUBSTITUTE-CASE).
Разбор строки, разделение её на подстроки на основе одной или нескольких разделяющих последовательностей символов1
  • UNSTRING оператор (см. UNSTRING).
Удаление начальных или конечных пробелов из строки
  • TRIM встроенная функция (см. TRIM).
Замена одной подстроки на другую одинаковой длины, исходя из начальной позиции и длины подстрок
  • MOVE оператор (см. MOVE) с модификатором ссылки на поле “приёмника” (см. Модификаторы ссылок).
Замена одной или нескольких подстрок в строке на строки-заменители той же длины, независимо от их расположения
  • INSPECT оператор (см. INSPECT) с REPLACING оговоркой.
  • SUBSTITUTE встроенная функция (см. SUBSTITUTE).
  • SUBSTITUTE-CASE встроенная функция (см. SUBSTITUTE-CASE).
Замена одной или нескольких подстрок в строке на строки-заменители потенциально разной длины, независимо от их расположения
  • SUBSTITUTE встроенная функция (см. SUBSTITUTE).
  • SUBSTITUTE-CASE встроенная функция (см. SUBSTITUTE-CASE).

2.1.12. Функции форматирования экрана

Стандарт COBOL2002 формализует расширения языка COBOL, позволяющие определять и обрабатывать текстовые экраны, как это типично для компьютеров мэйнфреймов и мидфреймов, а также для многих систем продаж (например, «кассовых аппаратов»). GnuCOBOL реализует практически все функции обработки экрана, описанные в COBOL2002.

Эти функции позволяют отображать поля в определённых позициях строки/столбца, назначать различные цвета и атрибуты видео полям экрана и обнаруживать нажатие определённых функциональных клавиш (F1, F2 и т. д.). Всё это происходит благодаря использованию SCREEN SECTION (см. РАЗДЕЛ ЭКРАНА) и специальных форматов оператора ACCEPT (см. ACCEPT) и оператора DISPLAY (см. DISPLAY).

Стандарт COBOL2002, а следовательно, и GnuCOBOL, охватывает только экраны текстового пользовательского интерфейса (TUI) (состоящие из символов ASCII, представленных с помощью различных визуальных атрибутов), а не более продвинутые возможности графического пользовательского интерфейса (GUI) для проектирования и обработки экранов, встроенные в большинство современных операционных систем. Доступны пакеты подпрограмм, которые могут обеспечить полное представление GUI — большинство из них может вызываться программами GnuCOBOL с умеренными временными затратами на исследование (например, Tcl/Tk) — но ни один из них в настоящее время не включён в GnuCOBOL.

2.1.12.1. Пример экрана

Пример экрана, созданный программой GnuCOBOL:

================================================================================
 GCic (2014/01/02 11:24) GnuCOBOL 2.1 23NOV2013 Interactive Compilation
+------------------------------------------------------------------------------+
: Filename: GCic.cbl                                                           :
: Folder:   E:\Programs\GCic\2013-11-23                                        :
+------------------------------------------------------------------------------+
 Set/Clr Switches Via F1-F9; Set Config Via F12; ENTER Key Compiles; ESC Quits
+------------------------------------------------------------------------------+
: F1  Assume WITH DEBUGGING MODE  F6 >"FUNCTION" Is Optional      : Current    :
: F2  Procedure+Statement Trace   F7 >Enable All Warnings         : Config:    :
: F3  Make a Library (DLL)        F8  Source Is Free-Format       : DEFAULT    :
: F4  Execute If Compilation OK   F9 >No COMP/BINARY Truncation   :            :
: F5  Listing Off                                                 :            :
+------------------------------------------------------------------------------+
 Extra "cobc" Switches, If Any ("-save-temps=xxx" Prevents Listings):
+------------------------------------------------------------------------------+
: ____________________________________________________________________________ :
: ____________________________________________________________________________ :
+------------------------------------------------------------------------------+
 Program Execution Arguments, If Any:
+------------------------------------------------------------------------------+
: ____________________________________________________________________________ :
: ____________________________________________________________________________ :
+------------------------------------------------------------------------------+
 GCic for Windows/MinGW Copyright (C) 2009-2014, Gary L. Cutler, GPL
================================================================================

Вышеприведённый экран был создан интерактивным компилятором GnuCOBOL или GCic. См. GCic в Примеры программ GnuCOBOL для просмотра исходного кода и списка перекрестных ссылок этой программы. Версии этого документа в формате PDF будут включать фактическое графическое изображение этого примера экрана.

Экраны определяются в разделе экрана раздела данных. После определения экраны используются во время выполнения с помощью операторов ACCEPT и DISPLAY.

2.1.12.2. Цветовая палитра и атрибуты видео

GnuCOBOL поддерживает следующие спецификации визуальных атрибутов в SCREEN SECTION (см. РАЗДЕЛ ЭКРАНА):

Цвет

Для фона (экрана) и переднего плана (текста) любой ячейки строки/столбца на экране можно указать восемь (8) различных цветов. Цвета задаются числом, хотя в справочнике, поставляемом со всеми дистрибутивами GnuCOBOL (screenio.cpy), определены COB-COLOR-xxxxxx имена для различных цветов, поэтому их можно указать более осмысленным именем, а не числом. Восемь цветов по номерам с соответствующими именами констант, определенными в screenio.cpy, приведены ниже:

Black

COB-COLOR-ЧЁРНЫЙ

Blue

COB-COLOR-СИНИЙ

Green

COB-COLOR-ЗЕЛЁНЫЙ

Cyan

COB-COLOR-ГОЛУБОЙ

Red

COB-COLOR-КРАСНЫЙ

Magenta

COB-COLOR-ПУРПУРНЫЙ

Yellow

COB-COLOR-ЖЁЛТЫЙ

White

COB-COLOR-БЕЛЫЙ

Яркость текста

Для текста поддерживаются три уровня яркости — низкая (тусклый), нормальная и высокая (яркий). Не все реализации GnuCOBOL поддерживают все три уровня (некоторые рассматривают низкую яркость как нормальную). Решающим фактором для определения того, поддерживаются два или три уровня, является версия пакета curses, используемого. Это утилитарный пакет ввода-вывода на экране, который включён в библиотеку выполнения GnuCOBOL при сборке программного обеспечения GnuCOBOL.

Как общее правило, реализации для Windows поддерживают два уровня, а для Unix — все три.

Мигание

Это тоже функция видео, которая зависит от пакета curses, встроенного в вашу версию GnuCOBOL. Если мигание включено в этом пакете, текст, отображаемый в полях, определённых в разделе экрана как мигающий, будет бесконечно циклировать между наиболее яркой настройкой (высокая яркость) и «невидимым» режимом, где цвет текста соответствует цвету фона поля. В сборках для Windows, которые обычно используют пакет «pcurses», используется более яркий, чем обычно, цвет фона для обозначения «мигания».

Обратный видеорежим

Этот атрибут видео просто меняет местами цвета переднего и заднего плана и параметры отображения.

Обводка поля

Если это поддерживается используемым пакетом curses, возможно рисование границ по верхнему, левому и/или нижнему краю поля.

Защищённый ввод

По желанию, поля экрана, используемые как поля ввода, могут быть определены как «защищённые», где каждый введённый символ (независимо от того, что было фактически введено) будет отображаться как символ звёздочка (*). Фактический символ, клавиша которого была нажата, всё равно будет сохранён в поле в программе. Это очень полезно для полей паролей или номеров счетов.

Символ подсказки

В поля ввода можно поместить любой символ в качестве заполнителя. Эти символы заполнителя предоставляют визуальное представление размера поля ввода и автоматически преобразуются в пробелы при обработке поля ввода программой. Если для поля ввода не определён такой символ, будет предполагаться подчёркивание (‘_’).

2.1.13. Функции генератора отчетов

GnuCOBOL включает реализацию системы управления генерацией отчетов (RWCS). Модуль генератора отчетов был полностью реализован в версии 3.0. Это стандартная, необязательная дополнительная функция языка COBOL, которая автоматизирует многие механизмы, связанные с генерацией печатных отчетов:

  1. Управление постраничной разбивкой отчетов, включая:
    1. Автоматическое создание однократного сообщения на первой странице отчета (заголовок отчета).
    2. Создание нуля или более заголовков на каждой странице отчета (заголовок страницы).
    3. Создание нуля или более подвалов на каждой странице отчета (подвал страницы).
    4. Автоматическое нумерование печатных страниц.
    5. Форматирование строк отчета, составляющих основную часть отчета (детали).
    6. Полное отслеживание того, где «перо» собирается «писать» на текущей странице, что автоматически вызывает перенос на новую страницу, а также автоматическое создание подвала страницы для закрытия старой страницы и/или заголовка страницы для начала новой.
    7. Создание однократного сообщения в конце последней страницы отчета (подвал отчета).
  2. Выполнение специальных действий по отчетности на основе того, что данные, используемые для генерации отчета, отсортированы по одному или нескольким ключевым полям:
    1. Автоматическое подавление отображения одного или нескольких полей данных из группы деталей, когда значение(я) поля(ей) дублирует(ют) те, что были в ранее сгенерированной группе деталей. Такие поля называются полями, указывающими на группу.
    2. Автоматическое повторное отображение подавленных полей, указывающих на группу деталей, если группа деталей печатается на новой странице.
    3. Определение, когда контрольные поля отчета — поля, связанные с теми, которые использовались в качестве SORT (см. SORT) ключей — изменились. Это известно как разрыв контроля. RWCS может автоматически выполнить следующие действия по отчетности при возникновении разрыва контроля:
      • Создание подвала, известного как подвал контроля, после строк деталей, которые имели то же старое значение для контрольного поля.
      • Создание заголовка, известного как заголовок контроля, перед строками деталей, которые имеют то же новое значение для контрольного поля.
  3. Выполнение суммирования данных следующим образом:
    1. Автоматическое генерирование промежуточных итогов в контрольных и/или подвалах отчета, суммирующих значения любых полей в группе деталей.
    2. Автоматическое генерирование итоговых сумм в группах деталей. Это будут суммы двух или более значений, представленных в группе деталей.

Документация по REPORT SECTION (см. REPORT SECTION) описывает описание отчетов, а глава PROCEDURE DIVISION (см. PROCEDURE DIVISION) документирует различные языковые инструкции, которые фактически генерируют отчеты. Перед чтением этих документов, вам может быть полезно прочитать Использование Report Writer, который посвящен объединению всех элементов.

2.1.14. Инициализация данных

Существует три способа инициализации данных секции данных.

  1. Когда программа или подпрограмма выполняется впервые, большая часть данных в ее секции данных будет инициализирована следующим образом:
    • Символьные и буквенные (т.е. текстовые) данные будут инициализированы значением SPACES.
    • Числовые данные будут инициализированы значением ZERO.
    • Элементы данных с явным VALUE (см. VALUE) в их определении будут инициализированы этим значением.

    У разных секций секции данных свои правила, когда происходят описанные выше действия — для получения дополнительной информации см. документацию по этим секциям.

    Эти правила по умолчанию для инициализации могут существенно отличаться в разных реализациях COBOL. Например, очень распространённым случаем является инициализация памяти секции данных всеми двоичными нулями, за исключением тех элементов данных, где присутствуют VALUE фрагменты. Будьте внимательны при работе с приложениями, изначально разработанными для другой реализации COBOL, чтобы убедиться, что правила инициализации по умолчанию GnuCOBOL не вызовут сбоев.

  2. Программист может использовать оператор INITIALIZE (см. INITIALIZE) для инициализации любой группы или элемента данных в любое время. Данный оператор предоставляет больше вариантов инициализации, чем простые правила, указанные выше.
  3. Когда оператор ALLOCATE (см. ALLOCATE) используется для выделения элемента данных или просто для выделения области памяти заданного размера на ALLOCATE, это выделение может происходить с инициализацией или без неё, в соответствии с потребностями программиста.

2.1.15. Конвенции диаграмм синтаксиса

Синтаксис языка GnuCOBOL будет описан в специальных диаграммах синтаксиса, используя следующие технические приёмы описания синтаксиса:

MANDATORY-RESERVED-WORD
~~~~~~~~~~~~~~~~~~~~~~~

Зарезервированные слова языка COBOL будут отображаться заглавными буквами. Когда они подчеркнуты, как это слово, они являются обязательными зарезервированными словами.

OPTIONAL-RESERVED-WORD

Когда зарезервированные слова отображаются без подчеркивания, как это, они являются необязательными; такие зарезервированные слова доступны в синтаксисе языка только для повышения читабельности — их присутствие или отсутствие не влияет на программу.

ABBREVIATION
~~~~

Когда подчеркнута только часть зарезервированного слова, это означает, что слово можно ввести в полном виде или сократить до подчеркнутой части.

substitutable-items

Общие термины, представляющие определяемые пользователем заменяемые элементы, будут полностью отображаться строчными буквами в диаграммах синтаксиса. Когда такие элементы упоминаются в тексте, они будут отображаться как заменяемые-элементы.

Complex-Syntax-Clause

Элементы, отображаемые в смешанном регистре в диаграмме синтаксиса, представляют собой сложные предложения других синтаксических элементов, которые могут появиться в этом месте. Некоторые синтаксические конструкции COBOL довольно сложны, и использование такой условной записи значительно упрощает диаграммы синтаксиса. Когда такие элементы упоминаются в тексте, они отображаются как Сложное-синтаксическое-предложение.

[ ]

Метасимволы квадратных скобок в диаграммах синтаксиса отображают синтаксис языка, который является необязательным. Сами символы [] не должны быть введены. Если диаграмма синтаксиса содержит «a [b] c», то элементы синтаксиса «a» и «c» являются обязательными, но элемент «b» — необязательным.

|

Метасимволы вертикальной черты в диаграммах синтаксиса отображают простые варианты. Сам символ | не должен быть введён. Если диаграмма синтаксиса содержит «a|b|c», должен быть выбран ровно один из элементов «a», «b» или «c».

{ xxxxxx }
{ yyyyyy }
{ zzzzzz }

Вертикальный список элементов, ограниченный несколькими фигурными скобками, является ещё одним способом обозначения выбора между рядом элементов, где должен быть выбран ровно один элемент. Эта форма используется для отображения выбора, когда один или несколько вариантов являются более сложными, чем просто одно слово, или когда вариантов слишком много, чтобы представить их горизонтально с метасимволами «|».

| xxxxxx |
| yyyyyy |
| zzzzzz |

Вертикальный список элементов, ограниченный несколькими символами вертикальной черты, обозначает выбор между рядом элементов, где можно выбрать один или несколько вариантов.

...

Последовательность метасимволов ... указывает, что синтаксический элемент, непосредственно предшествующий ей, может повторяться. Сама последовательность ... не должна быть введена. Если диаграмма синтаксиса содержит a b... c, синтаксический элемент «a» должен следовать за по крайней мере одним элементом «b» (возможно, более чем одним), и вся последовательность должна завершаться синтаксическим элементом «c».

{ }

Метасимволы фигурные скобки («{» и «}») могут использоваться для группирования последовательности синтаксических элементов вместе, чтобы они могли обрабатываться как единое целое. Сами символы {} не должны быть введены. Обычно они используются в сочетании с метасимволами «|» или «...».

$*^()-+=:"'<,>./

Любой из этих символов, появляющихся в диаграмме синтаксиса, должен интерпретироваться буквально, и являются символами, которые должны быть введены — где это разрешено — в предложении, формат которого описывается. Обратите внимание, что символ «.» — это буквальный символ, который должен быть введён в предложении, а символ «...» — это упомянутая выше метасимвольная последовательность.

2.1.16. Формат строк программного кода

До стандарта COBOL2002, строки исходного кода в программах COBOL были структурированы вокруг 80-колонных перфокарт. Это означает, что каждая строка исходного кода программы COBOL состояла из пяти различных «областей», определённых по номеру(ам) колонки.

Начиная со стандарта COBOL2002, теперь существует второй режим для кода COBOL — в этом режиме операция, строки COBOL могут иметь длину до 255 символов без каких-либо конкретных требований к тому, что должно отображаться в определённых колонках.

Конечно, в соответствии с долгой традицией COBOL по поддержанию обратной совместимости со старыми стандартами, программисты (и, конечно же, совместимые компиляторы COBOL) способны работать в любом из этих режимов. Даже возможно переключаться между ними в одной программе. Термины Режим фиксированного формата и Режим свободного формата используются для обозначения этих двух режимов форматирования исходного кода.

Компилятор GnuCOBOL (cobc) поддерживает оба этих режима форматирования строк исходного кода, по умолчанию используя режим фиксированного формата, если нет другой информации.

Компилятор можно настроить на работу в любом из этих режимов четырьмя способами:

  1. Используя переключатель компилятора — используйте переключатель -fixed для запуска в режиме фиксированного формата (запомните, что это значение по умолчанию) или переключатель -free для запуска в режиме свободного формата.
  2. Вы можете использовать SOURCEFORMAT AS FIXED и SOURCEFORMAT AS FREE пункты директивы >>SET CDF (см. >>SET) в вашем исходном коде для переключения в режим фиксированного или свободного формата соответственно.
  3. Вы можете использовать >>FORMAT IS FIXED и FORMAT IS FREE пункты директивы >>DEFINE CDF (см. >>DEFINE) в вашем исходном коде для переключения в режим фиксированного или свободного формата соответственно.
  4. Вы можете использовать директиву >>SOURCE CDF (см. >>SOURCE) для переключения в режим свободного формата (>>SOURCE FORMAT IS FREE) или фиксированного формата (%%%CODE_BLOCK_148%%).

Используя методы 2-4 выше, вы можете переключаться между двумя форматами по своему желанию.

Последние три варианта выше являются эквивалентными; все три поддерживаются GnuCOBOL, чтобы сохранить совместимость исходного кода с широким спектром других реализаций COBOL. Во всех трёх случаях, если компилятор в настоящее время находится в режиме фиксированного формата, >> должен начинаться со столбца 8 или дальше, при условии, что ни одна часть директивы не выходит за пределы столбца 72. Если компилятор в настоящее время находится в режиме свободного формата, >> может появляться в любом столбце, при условии, что ни одна часть директивы не выходит за пределы столбца 255.

В зависимости от режима исходного формата, в котором находится компилятор, вам необходимо будет следовать различным правилам для текущего режима формата. Эти правила представлены в следующих абзацах.

В следующем обсуждении представлены различные компоненты каждой строки исходного кода GnuCOBOL, когда компилятор работает в режиме фиксированного формата. Помните, что это режим по умолчанию для компилятора GnuCOBOL.

1-6

Область номера последовательности

Исторически, во времена, когда для подачи исходного кода программы COBOL в компилятор COBOL использовались перфокарты, эта часть оператора COBOL была зарезервирована для шестизначного порядкового номера. Хотя содержимое этой области игнорируется компиляторами COBOL, оно существовало для того, чтобы программа, фактически пробитая на карточках с 80 символами, — если бы колода карт упала на пол, — могла быть обработана сортировщиком карт и восстановлена в правильной последовательности. Конечно, это не нужно сегодня; если говорить откровенно, это уже давно не нужно.

См. Отметка изменений в программах для обсуждения ценного использования области порядкового номера сегодня.

7

Область индикатора

Столбец 7 служит индикатором, в котором будет отображаться одно из пяти возможных значений — пробел, D (или d), - (тире), / или *. Значения этих символов следующие:

пробел

Нет специального значения — это обычный символ, который будет отображаться в этой области.

D/d

Строка содержит действительное утверждение GnuCOBOL, которое обычно обрабатывается как комментарий, если программа не компилируется в режиме отладки.

*

Строка является комментарием.

/

Строка является комментарием, который также заставит компилятор перейти на новую страницу в списке компиляции. Хотя GnuCOBOL будет учитывать такую строку как комментарий, он не будет подавать сигнал перехода на новую страницу при генерации списка.

-

Строка является продолжением предыдущей строки. Они необходимы только в том случае, если алфавитно-цифровое литерал (строка символов в кавычках), ключевое слово или определенное пользователем слово разбиты на несколько строк.

8-11

Область A

Заголовки разделов языка DIVISION, SECTION и параграфов должны начинаться в области A, а также номера уровней 01, 77 в записях описания данных и заголовки файлов FD и SD и описания SORT.

12-72

Область B

Все другие компоненты языка программирования COBOL кодируются в этих столбцах.

73-80

Область имени программы

Это еще одна устаревшая область операторов COBOL. Эта часть каждого оператора также восходит ко временам, когда программы пробивались на картах; ожидалось, что имя программы (или, по крайней мере, первые 8 символов) будут пробиты здесь, чтобы — если колода исходного кода COBOL содержала более одной программы — этот удобный сортировщик карт мог использоваться для предварительного разделения карт по имени программы, а затем для сортировки по порядковому номеру. Сегодняшние компиляторы COBOL (включая GnuCOBOL) просто игнорируют все, что находится за пределами столбца 72.

См. Отметка изменений в программах для обсуждения ценного использования области имени программы сегодня.

2.1.17. Структура программы

Полный синтаксис программы GnuCOBOL

 [ IDENTIFICATION DIVISION. ]
   ~~~~~~~~~~~~~~~~~~~~~~~
   PROGRAM-ID|FUNCTION-ID.  name-1 [ Program-Options ] .
   ~~~~~~~~~~ ~~~~~~~~~~~
 [ ENVIRONMENT DIVISION. ]
   ~~~~~~~~~~~ ~~~~~~~~
 [ CONFIGURATION SECTION. ]
   ~~~~~~~~~~~~~ ~~~~~~~
 [ SOURCE-COMPUTER.         Compilation-Computer-Specification . ]
   ~~~~~~~~~~~~~~~
 [ OBJECT-COMPUTER.         Execution-Computer-Specification . ]
   ~~~~~~~~~~~~~~~
 [ REPOSITORY.              Function-Specification... . ]
   ~~~~~~~~~~
 [ SPECIAL-NAMES.           Program-Configuration-Specification . ]
   ~~~~~~~~~~~~~
 [ INPUT-OUTPUT SECTION. ]
   ~~~~~~~~~~~~ ~~~~~~~
 [ FILE-CONTROL.            General-File-Description... . ]
   ~~~~~~~~~~~~
 [ I-O-CONTROL.             File-Buffering-Specification... . ]
   ~~~~~~~~~~~
 [ DATA DIVISION. ]
   ~~~~~~~~~~~~~
 [ FILE SECTION.            Detailed-File-Description... . ]
   ~~~~~~~~~~~~
 [ WORKING-STORAGE SECTION. Permanent-Data-Definition... . ]
   ~~~~~~~~~~~~~~~ ~~~~~~~
 [ LOCAL-STORAGE SECTION.   Temporary-Data-Definition... . ]
   ~~~~~~~~~~~~~ ~~~~~~~
 [ LINKAGE SECTION.         Subprogram-Argument-Description... . ]
   ~~~~~~~ ~~~~~~~
 [ REPORT SECTION.          Report-Description... . ]
   ~~~~~~ ~~~~~~~
 [ SCREEN SECTION.          Screen-Layout-Definition... . ]
   ~~~~~~ ~~~~~~~
   PROCEDURE DIVISION [ { USING Subprogram-Argument...      } ]
   ~~~~~~~~~ ~~~~~~~~   { ~~~~~                             }
                        { CHAINING Main-Program-Argument... }
                          ~~~~~~~~
                      [   RETURNING identifier-1 ] .
 [ DECLARATIVES. ]        ~~~~~~~~~
   ~~~~~~~~~~~~
 [ Event-Handler-Routine... . ]
 [ END DECLARATIVES. ]
   ~~~ ~~~~~~~~~~~~
   General-Program-Logic
 [ Nested-Subprogram... ]
 [ END PROGRAM|FUNCTION name-1 ]
   ~~~ ~~~~~~~ ~~~~~~~~

Каждая программа состоит из до четырёх разделов (крупных группировок разделов, параграфов и описаний или процедурных кодов, которые все относятся к одной общей цели), именованных Идентификация, Окружение, Данные и Процедура.

  1. Не все разделы необходимы в каждой программе, но они должны быть указаны в том порядке, в котором используются.
  2. Следующие пункты относятся к разделу идентификации
    • Заголовок IDENTIFICATION DIVISION. всегда является необязательным.
  3. Следующие пункты относятся к разделу среды:
    • Если оба необязательных раздела этого раздела закодированы, они должны быть закодированы в показанном порядке.
    • Каждый из этих разделов состоит из ряда специфических параграфов (SOURCE-COMPUTER и OBJECT-COMPUTER, например). Каждый из этих параграфов выполняет определенную функцию. Если для цели, которую выполняет один из параграфов, не требуется код, весь параграф можно опустить.
    • Если ни один из параграфов в одном из разделов не закодирован, сам заголовок раздела можно опустить.
    • Параграфы в каждом разделе могут быть закодированы только в этом разделе, но могут быть закодированы в любом порядке.
    • Если ни один из разделов в разделе среды не закодирован, сам заголовок ENVIRONMENT DIVISION. можно опустить.
  4. Следующие пункты относятся к разделу данных:
    • Раздел данных состоит из шести необязательных разделов — при использовании эти разделы должны быть закодированы в порядке, показанном на диаграмме синтаксиса.
    • Каждый из этих разделов состоит из кода, который выполняет определенную функцию. Если для цели, которую выполняет один из этих разделов, не требуется код, весь раздел, включая его заголовок, можно опустить.
    • Если ни один из разделов в разделе данных не закодирован (высоко маловероятная, но теоретически возможная ситуация), сам заголовок DATA DIVISION. можно опустить.
  5. Следующие пункты относятся к разделу обработки:
    • Как и в других разделах, раздел обработки может состоять из разделов, а эти разделы, в свою очередь, могут состоять из параграфов. В отличие от других разделов, однако, имена разделов и параграфов определяются программистом, и их вообще может не быть, если программист этого пожелает.
    • Каждая обработка событий будет отдельным разделом, посвященным перехвату определенного события во время выполнения. Если таких разделов не закодировано, строки DECLARATIVES. и END DECLARATIVES. могут быть опущены.
  6. Один файл исходного кода COBOL может содержать:
    • Часть программы; эти файлы известны как копибуки
    • Одну программу. В этом случае утверждение END PROGRAM или END FUNCTION является необязательным.
    • Несколько программ, разделенных друг от друга операторами END PROGRAM или END FUNCTION. Последней программе в таком файле исходного кода не обязательно иметь оператор END PROGRAM или END FUNCTION.
  7. Подпрограмма «B» может быть вложена в программу «A», включив исходный код программы B в конец раздела обработки программы A без промежуточного оператора END PROGRAM A. или END FUNCTION A.. На данный момент это всё, что будет сказано о вложении. Более подробную информацию см. в разделе Independent vs Contained vs Nested Subprograms.
  8. Независимо от того, сколько программ составляют один файл исходного кода GnuCOBOL, при компиляции из этого файла будет сгенерирована только одна исполняемая программа.

2.1.18. Комментарии

В следующей информации описано, как можно встроить комментарии в исходный код программы GnuCOBOL для создания документации.

Тип комментария Режим источника — Описание
Пустые строки FIXED — Пустые строки можно вставлять по желанию.

FREE — Пустые строки можно вставлять по желанию.

Комментарии на всю строку FIXED — Вся строка исходного кода будет обрабатываться как комментарий (и игнорироваться компилятором) путём ввода звёздочки (‘*’) в седьмой (7) столбец.

FREE — Вся строка исходного кода будет обрабатываться как комментарий (и игнорироваться компилятором) путём ввода последовательности ‘*>’ в любом столбце, как первых непустых символов строки.

Комментарии на всю строку с формой подачи FIXED — Вся строка исходного кода будет обрабатываться как комментарий путём ввода косой черты (‘/’) в седьмой (7) столбец. Многие компиляторы COBOL также будут выводить форму подачи в списке программы, чтобы строка ‘/’ находилась вверху новой страницы. Компилятор GnuCOBOL не поддерживает такое поведение с формой подачи.

Интерактивный компилятор GnuCOBOL или GCic поддерживает это поведение с формой подачи при генерации списков исходного кода! См. GCic в Примерах программ GnuCOBOL для исходного и перекрестного списка (сгенерированного GCic) этой программы — вы можете увидеть эффект ‘/’ там.

FREE — В свободном режиме нет эквивалента ‘/’.

Комментарии части строки FIXED — Любой текст, следующий за последовательностью символов ‘*>’ в строке исходного кода, будет обрабатываться как комментарий. ‘*’ должен появляться в седьмом (7) столбце или правее.

FREE — Любой текст, следующий за последовательностью символов ‘*>’ в строке исходного кода, будет обрабатываться как комментарий. ‘*’ может появляться в любом столбце.

Комментарии, которые могут обрабатываться как код, обычно для отладки FIXED — Ввод ‘D’ в столбец 7 (строчные или прописные буквы) приведет к тому, что компилятор обработает строку исходного кода GnuCOBOL как комментарий.

FREE — Указание последовательности символов ‘>>D’ (строчные или прописные буквы) в качестве первых непустых символов строки исходного кода приведет к тому, что компилятор обработает строку исходного кода GnuCOBOL как комментарий.

Предложения для отладки могут быть скомпилированы, либо указав переключатель -fdebugging-line в компиляторе GnuCOBOL, либо добавив WITH DEBUGGING MODE предложение в SOURCE-COMPUTER абзац.

2.1.19. Литералы

Литералы — это постоянные значения, которые не изменятся во время выполнения программы. Существуют два основных типа литералов — числовые и алфавитно-цифровые.

2.1.19.1. Числовые литералыЧисловой литерал

  • Целые числа, такие как 1, 56, 2192 или -54.
  • Нецелые значения с фиксированной точкой, такие как 1.317 или -2.95.
  • Значения с плавающей запятой, использующие обозначение ‘Enn’, такие как 9.92E25, представляющее 9.92 x 1025 (10 в степени 25) или 5.7E-14, представляющее 5.7 x 10-14 (10 в степени -14). И мантисса (число перед ‘E’), и экспонента (число после ‘E’) могут быть явно указаны как положительные (с ‘+’), отрицательные (с ‘-’) или без знака (и, следовательно, неявно положительные). Значение литерала с плавающей запятой должно быть в диапазоне от -1.7 x 10308 до +1.7 x 10308 с не более чем 15 десятичными цифрами точности.
  • Шестнадцатеричные числовые литералы
  • Литералы с нулевым завершением
  • Сырая строка C, использующая L"characters".
  • Двоичные, использующие B#0 или 1.
  • Восьмеричные, использующие O#0 - 7. (Это буква ‘O’).
  • Шестнадцатеричное число, использующее H# или X# ‘0’ - ‘F’.
  • Булевы литералы (Стандарт) B" character ".
  • Булевы литералы (Шестнадцатеричные) BX" hex character ".
  • Национальные литералы (Стандарт) N" character " или NC" character ".
  • Национальные литералы (Шестнадцатеричные) NX" character ".

2.1.19.2. Алфавитно-цифровые литералы

Алфавитно-цифровой литерал

Алфавитно-цифровой литерал не может быть использован в арифметических выражениях, пока не будет преобразован в его числовой вычислительный эквивалент; в GnuCOBOL есть три встроенные числовые функции преобразования, которые могут выполнить это преобразование — NUMVAL (см. NUMVAL), NUMVAL-C (см. NUMVAL-C) и NUMVAL-F (см. NUMVAL-F).

Алфавитно-цифровые литералы могут иметь любой из следующих форматов:

  • Последовательность символов, заключенная в пару одинарных кавычек (‘'’)
  • Литерал, образованный по тем же правилам, что и строковый литерал (выше), но с префиксом буквы ‘Z’ (строчная или прописная) представляет нуль-ограниченный строковый литерал. Эти литералы отличаются от обычных строковых литералов тем, что они будут явно завершены байтом с шестнадцатеричным значением 00. Эти Нуль-ограниченные алфавитно-цифровые литералы
  • Шестнадцатеричный алфавитно-цифровой литерал

Алфавитно-цифровые литералы, слишком длинные для одной строки, могут быть продолжены на следующей строке двумя способами:

  1. При использовании режима фиксированного формата, алфавитно-цифровое литерал может быть размещено до и включая столбец 72. Литерал может быть продолжен на следующей строке после столбца 11, добавив другую кавычку или апостроф (в зависимости от того, какой символ использовался для начала литерала). В строке продолжения также должен быть тире (-) .
         1         2         3         4         5         6         7   
1234567890123456789012345678901234567890123456789012345678901234567890123

       01  LONG-LITERAL-VALUE-DEMO     PIC X(60) VALUE "This is a long l
      -                                                "ong literal that
      -                                                " must be continu
      -                                                "ed.".
  1. Независимо от того, работает ли компилятор в режиме фиксированного или свободного формата, GnuCOBOL позволяет разбивать алфавитно-цифровые литералы на отдельные фрагменты. Эти фрагменты имеют свои начальные и конечные кавычки/апострофы и «склеиваются» во время компиляции с использованием символа ‘&’
         1         2         3         4         5         6         7   
1234567890123456789012345678901234567890123456789012345678901234567890123

      01  LONG-LITERAL-VALUE-DEMO      PIC X(60) VALUE "This is a" &
                                        " long literal that must " &
                                                    "be continued.".

Если ваша программа использует режим свободного формата, нет необходимости продолжать длинные алфавитно-цифровые литералы, так как операторы могут быть длиной до 255 символов.

Числовые литералы могут быть разделены на строки так же, как и алфавитно-цифровые литералы, используя любой из указанных выше методов, а также зарезервированные и пользовательские слова могут быть разделены на строки (используя первый метод). Продолжение числовых литералов и пользовательских/зарезервированных слов предоставляется только для обеспечения совместимости со старыми версиями и программами COBOL, но не должно использоваться в новых программах — это просто делает программы непривлекательными для чтения.

2.1.19.3. Фигуративные константы

Фигуративные константы — это зарезервированные слова, которые могут использоваться в качестве литералов, где значение фигуративной константы может интерпретироваться как произвольно длинная последовательность соответствующих символов. Когда требуется определённая длина, например, в качестве аргумента подпрограммы, фигуративная константа не может быть использована. Таким образом, следующие примеры являются допустимыми:


05 FILLER                PIC 9(10) VALUE ZEROS.
   ...
MOVE SPACES TO Employee-Name

Но это недопустимо:


CALL "SUBPGM" USING SPACES

Ниже приведены фигуративные константы GnuCOBOL и их соответствующие значения.

ZERO

Эта фигуративная константа имеет значение численного 0 (ноль). ZEROS и ZEROES — синонимы ZERO.

SPACE

Эта фигуративная константа имеет значение одного или нескольких пробелов. SPACES — синоним SPACE.

QUOTE

Эта фигуративная константа имеет значение одного или нескольких символов двойной кавычки ("). QUOTES — синоним QUOTE.

LOW-VALUE

Эта фигуративная константа имеет значение одного или нескольких символов, занимающих самое низкое положение в наборе символов программы, как определено в параграфе OBJECT-COMPUTER (см. OBJECT-COMPUTER) или — если такое указание не было сделано — в наборе символов по умолчанию, используемом программой (как правило, это набор символов ASCII). LOW-VALUES — синоним LOW-VALUE.

Если используется набор символов ASCII без модификаций набора символов, значение фигуративной константы LOW-VALUES — символ ASCII NUL. Однако, поскольку наборы символов могут быть переопределены, не следует полагаться на это. Используйте вместо этого фигуративную константу NULL.

HIGH-VALUE

Эта фигуративная константа имеет значение одного или нескольких символов, занимающих самое высокое положение в наборе символов программы, как определено в параграфе OBJECT-COMPUTER или — если такое указание не было сделано — в наборе символов по умолчанию, используемом программой (как правило, это набор символов ASCII). HIGH-VALUES — синоним HIGH-VALUE.

NULL

Символ, состоящий только из нулевых битов (независимо от набора символов программы).

Программисты могут создавать свои собственные фигуративные константы с помощью пункта SYMBOLIC CHARACTERS (см. Symbolic-Characters-Clause) параграфа SPECIAL-NAMES (см. SPECIAL-NAMES).

2.1.20. Пунктуация

Запятая (‘,’)

Использование запятых может вызвать путаницу у компилятора COBOL, если в параграфе SPECIAL-NAMES (см. SPECIAL-NAMES) используется пункт DECIMAL POINT IS COMMA, как это может быть в Европе. Следующее утверждение, которое вызывает подпрограмму, передавая ей два аргумента (числовые константы 1 и 2):

CALL "SUBROUTINE" USING 1,2

В случае использования DECIMAL POINT IS COMMA будет интерпретироваться как вызов подпрограммы с одним аргументом (нецелое числовое литерал со значением 1 и 2 десятых). Поэтому лучше всегда следовать запятой пробелом.

Точка (‘.’)

Правила использования точек в процедурной части несколько сложны. Подробности см. в разделе Использование точек.

2.1.21. Взаимодействие с другими средами

С помощью оператора CALL программы COBOL могут вызывать другие программы COBOL, используемые в качестве подпрограмм. Это очень похоже на возможности связи между программами, предоставляемые другими языками программирования. В случае GnuCOBOL, функция CALL достаточно мощная, чтобы её можно было настроить так, чтобы программа GnuCOBOL могла взаимодействовать с API операционной системы, системы управления базами данных и библиотеки времени выполнения, даже если они не написаны на COBOL. См. GnuCOBOL Основные программы CALLing C Подпрограммы, чтобы посмотреть пример, как программа GnuCOBOL может вызывать подпрограмму на C, передавая информацию туда и обратно.

Тот факт, что GnuCOBOL поддерживает полнофункциональный двусторонний интерфейс с программами на C, означает, что — даже если вы не можете напрямую получить доступ к API библиотеки — вы всегда можете сделать это через небольшую программу-оболочку на C, которая CALL вызывается программой GnuCOBOL.

2.2. Язык COBOL - Расширенные методы

2.2.1. Ссылочные таблицы

COBOL использует скобки для указания индексов, используемых для ссылки на записи в таблице (таблицы в COBOL — это то, что другие языки программирования называют массивами).

Например, рассмотрите следующую структуру данных, которая определяет сетку символов размером 4 столбца × 3 строки:

01  GRID.
     05 GRID-ROW OCCURS 3 TIMES.
        10 GRID-COLUMN OCCURS 4 TIMES.
            15 GRID-CHARACTER       PIC X(1).

Если структура содержит следующую сетку символов:

A B C D
E F G H
I J K L

Тогда GRID-CHARACTER (2, 3) ссылается на символ ‘G’, а GRID-CHARACTER (3, 2) ссылается на символ ‘J’.

Индексы могут быть заданы как числовые (целочисленные) литералы, числовые (целочисленные) данные, данные, созданные с помощью целочисленных спецификаций без формата USAGE (см. USAGE), USAGE INDEX данных или арифметических выражений, результатом которых является ненулевое целое число.

В приведённых выше примерах запятая используется в качестве разделителя между двумя значениями индекса; точки с запятой (;) также являются допустимыми разделителями индексов, а также пробелы! Использование запятой или точки с запятой в такой ситуации технически необязательно, но по соглашению большинство программистов COBOL используют один из них. Использование отсутствия разделителя символов (кроме пробела) не рекомендуется, даже если это синтаксически правильно, так как такая практика может привести к трудночитаемому коду. Прочитать и понять GRID-CHARACTER(2 3), несложно, но это совсем другая история, когда пытаешься понять GRID-CHARACTER(I + 1 J / 3) (вместо GRID-CHARACTER(I + 1, J / 3)). Компилятор его принимает, но слишком много такого сделает мне плохо.

2.2.2. Квалификация имён данных

COBOL позволяет дублировать имена данных в программе, при условии, что к этим именам данных можно обратиться таким образом, чтобы сделать эти ссылки уникальными с помощью процесса, известного как квалификация.

Чтобы увидеть квалификацию в работе, рассмотрите следующие фрагменты двух записей данных, определённых в программе COBOL:

01  EMPLOYEE.                     01  CUSTOMER.
    05 MAILING-ADDRESS.               05 MAILING-ADDRESS.
       10 STREET        PIC X(35).       10 STREET        PIC X(35).
       10 CITY          PIC X(15).       10 CITY          PIC X(15).
       10 STATE         PIC X(2).        10 STATE         PIC X(2).
       10 ZIP-CODE.                      10 ZIP-CODE.
          15 ZIP-CODE-5 PIC 9(5).           15 ZIP-CODE-5 PIC 9(5).
          15 FILLER     PIC X(4).           15 FILLER     PIC X(4).

Теперь давайте рассмотрим проблему установки CITY части EMPLOYEE MAILING-ADDRESS на ‘Филадельфия’. Очевидно, MOVE 'Philadelphia' TO CITY не сработает, потому что компилятор не сможет определить, к какому из двух CITY полей вы хотите обратиться.

В попытке исправить проблему, мы могли бы квалифицировать ссылку на CITY как MOVE 'Philadelphia' TO CITY OF MAILING-ADDRESS.

К сожалению, этого тоже недостаточно, потому что это всё ещё недостаточно конкретизирует, к какому CITY мы обращаемся. Чтобы действительно определить, какой конкретный CITY вы хотите, нужно написать MOVE 'Philadelphia' TO CITY OF MAILING-ADDRESS OF EMPLOYEE.

Теперь нет никакой путаницы относительно того, какой CITY изменяется. К счастью, вам не нужно быть настолько конкретными; COBOL позволяет опустить промежуточные и ненужные уровни квалификации. Это позволяет MOVE 'Philadelphia' TO CITY OF EMPLOYEE хорошо справляться с задачей.

Если вам нужно квалифицировать ссылку на таблицу, сделайте это, записав что-то вроде identifier-1 OF identifier-2 ( subscript(s) ).

Зарезервированное слово IN может быть использовано вместо OF.

2.2.3. Модификаторы ссылок

Синтаксис модификатора ссылки (формат 1)

 identifier-1 [ OF|IN identifier-2 ] [ (subscript...) ] (start:[ length ])
                ~~ ~~

Синтаксис модификатора ссылки (формат 2)

 intrinsic-function-reference (start:[ length ])

Стандарт COBOL 1985 ввёл понятие модификатора ссылки для упрощения ссылок только на часть элемента данных; GnuCOBOL полностью поддерживает модификацию ссылки.

Значение start указывает начальную позицию символа, на которую ссылаются (положения символов начинаются с 1, а не с 0, как в некоторых языках программирования), а length указывает количество необходимых символов.

Если length не указан, предполагается значение, равное оставшимся позициям символов от start до конца identifier-1 или до конца возвращаемого значения функцией.

И start, и length могут быть указаны как целочисленные числовые литералы, целочисленные числовые данные или арифметические выражения с целочисленным значением.

Вот несколько примеров:

CUSTOMER-LAST-NAME (1:3)

Ссылка на первые три символа CUSTOMER-LAST-NAME.

CUSTOMER-LAST-NAME (4:)

Ссылка на все позиции символов CUSTOMER-LAST-NAME начиная с четвёртой.

FUNCTION CURRENT-DATE (5:2)

Ссылка на текущий месяц в виде двузначного числа. См. CURRENT-DATE для получения дополнительной информации.

Hex-Digits (Nibble + 1:1)

Предполагая, что Nibble — это числовой элемент данных со значением в диапазоне 0-15, а Hex-Digits — это PIC X(16) элемент данных со значением 0123456789ABCDEF, эта функция преобразует числовое значение в шестнадцатеричную цифру.

Table-Entry (6) (7:5)

Ссылка на символы с 7-го по 11-й (5 символов в общей сложности) в шестом вхождении Table-Entry.

Модификация ссылки может быть использована везде, где допустимо идентификатор, включая использование в качестве поля приёма в операторах, таких как MOVE (см. MOVE), STRING (см. STRING) и ACCEPT (см. ACCEPT), и не только.

2.2.4. Арифметические выражения

Синтаксис арифметического выражения

 Unary-Expression-1 { **|^ } Unary-Expression-2
                    {  *|/ }
                    {  +|- }

Синтаксис унарного выражения

 { [ +|- ] { ( Arithmetic-Expression-1 )          } }
 {         { [ LENGTH OF ] { identifier-1       } } }
 {         {   ~~~~~~ ~~   { literal-1          } } }
 {         {               { Function-Reference } } }
 { Arithmetic-Expression-2                          }

Арифметические выражения формируются с использованием четырёх категорий операций — возведение в степень, умножение и деление, сложение и вычитание, и указание знака.

В сложных выражениях, состоящих из нескольких операторов и операндов, применяется приоритет операций, согласно которому операции с более высоким приоритетом вычисляются первыми перед операциями с более низким приоритетом.

Как и в большинстве других языков программирования, программист всегда может использовать скобки для заключения подвыражений сложных выражений, которые должны быть вычислены перед другими подвыражениями, вместо того, чтобы следовать приоритету операторов.

В порядке убывания приоритета, ниже приведён анализ каждой категории операций:

Уровень 1 (Наивысший) — Указание унарного знака (+ и - с одним аргументом)

Унарный оператор «минус» (-) возвращает арифметическое отрицание своего единственного аргумента, фактически возвращая значение, являющееся произведением аргумента и -1.

Унарный оператор «плюс» (+) возвращает значение своего единственного аргумента, фактически возвращая значение, являющееся произведением аргумента и +1.

Уровень 2 — Возведение в степень (** или ^)

Значение левого аргумента возводится в степень, указанную правым аргументом. Допускаются нецелые степени. Операторы ^ и ** поддерживаются для обеспечения совместимости с программами, написанными для других реализаций COBOL.

Уровень 3 — Умножение (* и деление (/)

Оператор * вычисляет произведение левого и правого аргументов, а оператор / вычисляет значение левого аргумента, делённое на значение правого аргумента. Если правый аргумент имеет значение ноль, вычисление выражения будет преждевременно завершено до получения значения. Это может привести к ошибке программы во время выполнения.

Последовательность нескольких операций 3-го уровня (A * B / C, например) будет вычисляться в строгом порядке слева направо, если не используются скобки для управления порядком вычисления.

Уровень 4 — Сложение (+ или вычитание (+)

Оператор + вычисляет сумму левого и правого аргументов, а оператор - вычисляет значение правого аргумента, вычтенного из значения левого аргумента.

Последовательность нескольких операций 4-го уровня (A - B + C, например) будет вычисляться в строгом порядке слева направо, если не используются скобки для управления порядком вычисления.

Синтаксические правила COBOL, допускающие дефис (-) в именах элементов данных, могут привести к неоднозначности.

01  C        PIC 9 VALUE 5.
01  D        PIC 9 VALUE 2.
01  C-D      PIC 9 VALUE 7.
01  I        PIC 9 VALUE 0.
…
COMPUTE I=C-D+1

Оператор COMPUTE (см. COMPUTE) вычислит арифметическое выражение C-D+1 и сохранит результат в I.

Какое значение будет сохранено в I? Число 4, которое является результатом вычитания значения D (2) из значения C (5), а затем добавления 1? Или это будет число 8, которое равно значению добавления 1 к значению элемента данных C-D (7)?

Правильный ответ — 8 — значение элемента данных C-D плюс 1! Надеюсь, это и было предполагаемым результатом.

Компилятор GnuCOBOL фактически прошёл через следующий логический процесс принятия решений при генерации кода для оператора COMPUTE:

  1. Существует ли элемент данных с именем C-D? Если да, то используйте его значение для последовательности символов C-D.
  2. Если элемента данных C-D нет, то есть ли элементы данных C и D? Если нет, то оператор COMPUTE содержит ошибку. Если они есть, то будет сгенерирован код для вычитания значения D из C и добавления 1 к результату.

Если бы перед и/или после - было хотя бы одно пробельное пространство, неоднозначности не было бы — компилятор был бы вынужден использовать отдельные элементы данных C и D.

Чтобы избежать возможных неоднозначностей и улучшить читаемость программы, считается хорошей практикой программирования на COBOL всегда использовать по крайней мере один пробел слева и справа от каждого оператора в арифметических выражениях, а также символ = в операторе COMPUTE.

Вот несколько примеров того, как приоритет операций влияет на результаты арифметических выражений (все примеры используют числовые литералы для упрощения обсуждения).

Выражение Результат Примечания
3 * 4 + 1 13 Умножение (*) имеет приоритет над сложением (+)
4 * 2 ^ 3 - 10 22 2^3 равно 8 (^ имеет приоритет над *), умножить на 4 равно 32, минус 10 равно 22.
(4 * 2) ^ 3 - 10 502 Скобки позволяют рекурсивно применять правила арифметических выражений, позволяя изменять приоритет операций. 4 умножить на 2 равно 8 (использование скобок «перебивает» оператор возведения в степень, поэтому умножение происходит сначала); 8 ^ 3 равно 512, минус 10 равно 502.
5 / 2.5 + 7 * 2 - 1.15 15.35 Целочисленные и нецелочисленные операнды могут быть свободно смешаны

Конечно, операнды арифметических выражений могут быть числовыми данными (любой USAGE, кроме POINTER или PROGRAM POINTER), а также числовыми литералами.

2.2.5. Условные выражения

Условные выражения определяют условия, при которых программа может выполнить действие или прекратить его. Таким образом, условные выражения возвращают значение TRUE или FALSE.

Существует семь типов условных выражений, которые рассматриваются в следующих разделах.

2.2.5.1. Имена условий

Это самые простые условия. Обратите внимание на следующий код:

05  SHIRT-SIZE               PIC 99V9.
    88 TINY                  VALUE 0 THRU 12.5
    88 XS                    VALUE 13 THRU 13.5.
    88 S                     VALUE 14, 14.5.
    88 M                     VALUE 15, 15.5.
    88 L                     VALUE 16, 16.5.
    88 XL                    VALUE 17, 17.5.
    88 XXL                   VALUE 18, 18.5.
    88 XXXL                  VALUE 19, 19.5.
    88 VERY-LARGE            VALUE 20 THRU 99.9.

Имена условий TINY, XS, S, M, L, XL, XXL, XXXL и VERY-LARGE будут иметь значения TRUE или FALSE на основе значений в родительском элементе данных (SHIRT-SIZE).

Программа, которая хочет проверить, может ли текущее значение SHIRT-SIZE быть классифицировано как XL, может закодировать это решение как комбинированное условие (самый сложный тип условного выражения), либо как:

IF SHIRT-SIZE = 17 OR SHIRT-SIZE = 17.5

- or -

IF SHIRT-SIZE = 17 OR 17.5

Или она может просто использовать имя условия XL следующим образом:

IF XL

2.2.5.2. Условия класса

Синтаксис условия класса

 identifier-1 IS [ NOT ] { NUMERIC          }
                   ~~~   { ~~~~~~~          }
                         { ALPHABETIC       }
                         { ~~~~~~~~~~       }
                         { ALPHABETIC-LOWER }
                         { ~~~~~~~~~~~~~~~~ }
                         { ALPHABETIC-UPPER }
                         { ~~~~~~~~~~~~~~~~ }
                         { OMITTED          }
                         { ~~~~~~~          }
                         { class-name-1     }

Условия класса оценивают тип данных, хранящихся в элементе данных.

  1. Тест класса NUMERIC рассматривает только символы ‘0’, ‘1’, … , ‘9’ как числовые; только элемент данных, содержащий только цифры, пройдет тест класса NUMERIC. Пробелы, десятичные точки, запятые, знаки валюты, знаки плюс, минус и любые другие символы, кроме цифр, не пройдут тест класса NUMERIC.
  2. Тест класса ALPHABETIC рассматривает только заглавные и строчные буквы, а также пробелы как алфавитные.
  3. Условия класса ALPHABETIC-LOWER и ALPHABETIC-UPPER рассматривают только пробелы и соответствующие типы букв как допустимые для прохождения теста класса.
  4. Опция NOT инвертирует значение условия TRUE/FALSE.
  5. Обратите внимание, что то, что считается «буквой» (или заглавной/строчной буквой), может быть изменено с помощью спецификаций CHARACTER CLASSIFICATION в пункте OBJECT-COMPUTER (см. OBJECT-COMPUTER).
  6. Только элементы данных, тип USAGE (см. USAGE) которых явно или неявно определен как DISPLAY, могут использоваться в условиях класса NUMERIC или любом из условий класса ALPHABETIC.
  7. Некоторые реализации COBOL не позволяют использовать групповые элементы или PIC A элементы с условиями класса NUMERIC, а также PIC 9 элементы с условиями класса ALPHABETIC. В GnuCOBOL таких ограничений нет.
  8. Условие класса OMITTED используется, когда подпрограмме необходимо определить, был ли ей передан определенный аргумент. В таких условиях identifier-1 должен быть элементом секции связи, определенным в USING пункте заголовка подпрограммы PROCEDURE DIVISION. Дополнительная информация представлена в разделе PROCEDURE DIVISION USING.

Опция class-name-1 позволяет проверять пользовательский класс. Вот пример. Предположим следующее определение пользовательского класса ‘Hexadecimal’ в SPECIAL-NAMES (см. SPECIAL-NAMES):

SPECIAL-NAMES.
    CLASS Hexadecimal IS '0' THRU '9', 'A' THRU 'F', 'a' THRU 'f'.

Теперь рассмотрим следующий код, который выполнит процедуру 150-Process-Hex-Value, если Entered-Value содержит только допустимые шестнадцатеричные цифры:

    IF Entered-Value IS Hexadecimal
        PERFORM 150-Process-Hex-Value
    END-IF

2.2.5.3. Условия знака

Синтаксис условия знака

 identifier-1 IS [ NOT ] { POSITIVE }
                   ~~~   { ~~~~~~~~ }
                         { NEGATIVE }
                         { ~~~~~~~~ }
                         { ZERO     }
                           ~~~~

Условие для проверки состояния числового элемента данных, определённого с помощью PICTURE (см. PICTURE) и/или USAGE (см. USAGE), поддерживающего числовые значения.

  1. Условие класса POSITIVE или NEGATIVE будет истинным, только если значение identifier-1 строго больше или меньше нуля соответственно.
  2. Условие класса ZERO может быть истинным только если значение identifier-1 равно нулю.
  3. Опция NOT инвертирует значение TRUE/FALSE условия.

2.2.5.4. Условия состояния переключателя

В параграфе SPECIAL-NAMES имя внешнего переключателя может быть связано с одним или несколькими именами условий. Эти имена условий могут затем использоваться для проверки состояния ВКЛ/ВЫКЛ внешнего переключателя.

Ниже приведены соответствующие фрагменты кода в программе под названием testprog, предназначенной для простого объявления, если SWITCH-1 включён:

…
ENVIRONMENT DIVISION.
SPECIAL-NAMES.
    SWITCH-1 ON STATUS IS Switch-1-Is-ON.
…
PROCEDURE DIVISION.
…
    IF Switch-1-Is-ON
        DISPLAY "Switch 1 Is On"
    END-IF
…

Ниже представлены два различных сеанса работы с командной строкой — слева на системе Unix/Cygwin/OSX, а справа на системе Windows — которые включат переключатель и затем выполнят программу testprog. Обратите внимание, как сообщение, указывающее, что программа обнаружила установку переключателя, отображается в обоих примерах:

$ COB_SWITCH_1=ON           C:>SET COB_SWITCH_1=ON
$ export COB_SWITCH_1       C:>testprog
$ ./testprog                Switch 1 Is On
Switch 1 Is On              C:>
$

2.2.5.5. Условия соотношения

Синтаксис условия соотношения

 { identifier-1            } IS [ NOT ] RelOp { identifier-2            }
 { literal-1               }      ~~~         { literal-2               }
 { arithmetic-expression-1 }                  { arithmetic-expression-2 }
 { index-name-1            }                  { index-name-2            }

Синтаксис RelOp

 { EQUAL TO                 }
 { ~~~~~                    }
 { EQUALS                   }
 { ~~~~~~                   }
 { GREATER THAN             }
 { ~~~~~~~                  }
 { GREATER THAN OR EQUAL TO }
 { ~~~~~~~      ~~ ~~~~~    }
 { LESS THAN                }
 { ~~~~                     }
 { LESS THAN OR EQUAL TO    }
 { ~~~~      ~~ ~~~~~       }
 { =                        }
 { >                        }
 { >=                       }
 { <                        }
 { <=                       }

Эти условия оценивают, как два разных значения "соотносятся" друг с другом.

  1. При сравнении одного числового значения с другим, USAGE (см. USAGE) и количество значащих цифр в любом из значений не имеют значения, поскольку сравнение выполняется с использованием фактических алгебраических значений.
  2. При сравнении строк сравнение выполняется на основе сортировочной последовательности программы. Когда два строковых аргумента имеют различную длину, более короткий считается дополненным (справа) достаточным числом пробелов, чтобы сделать две строки одинаковой длины. Сравнение строк происходит посимвольно слева направо до тех пор, пока не будет установлено значение TRUE/FALSE для проверки соотношения. Символы сравниваются в соответствии с их относительным положением в сортировочной последовательности программы COLLATING SEQUENCE (как определено в SPECIAL-NAMES (см. SPECIAL-NAMES)), а не по значениям битового шаблона, которые символы имеют в памяти.
  3. По умолчанию сортировочная последовательность программы COLLATING SEQUENCE будет основана исключительно на значениях битовых шаблонов различных символов.
  4. Нет функциональной разницы между использованием словесного варианта (IS EQUAL TO, IS LESS THAN, …) и символьного варианта (=, <, …) фактических операторов соотношения.

2.2.5.6. Объединённые условия

Синтаксис объединённого условия

 [ ( ] Condition-1 [ ) ] { AND } [ ( ] Condition-2 [ ) ]
                         { ~~~ }
                         { OR  }
                         { ~~  }

Объединённое условие — это условие, которое вычисляет значение TRUE/FALSE из значений TRUE/FALSE двух других условий (которые сами могут быть объединёнными условиями).

  1. Если значение любого из условий равно TRUE, результат OR этих двух значений будет равен TRUE. OR двух FALSE условий даст значение FALSE.
  2. Для того, чтобы AND дало значение TRUE, оба условия должны иметь значение TRUE. Во всех других случаях AND даёт значение FALSE.
  3. При объединении нескольких аналогичных условий с одним и тем же оператором (ИЛИ/И) и общими подлежащими левого и правого аргументов, возможно сократить код программы. Например:
    IF ACCOUNT-STATUS = 1 OR ACCOUNT-STATUS = 2 OR ACCOUNT-STATUS = 7
    

    Можно сократить до:

    IF ACCOUNT-STATUS = 1 OR 2 OR 7
    
  4. Так же как умножение имеет приоритет над сложением в арифметических выражениях, так и AND имеет приоритет над OR в объединённых условиях. Для изменения этого приоритета, при необходимости, используйте скобки. Например:
    FALSE AND FALSE OR TRUE AND TRUE

    Вычисляется как TRUE

    (FALSE AND FALSE) OR (TRUE AND TRUE)

    Вычисляется как TRUE (так как И имеет приоритет над ИЛИ) — это идентично предыдущему примеру

    (FALSE AND (FALSE OR TRUE)) AND TRUE

    Вычисляется как FALSE

2.2.5.7. Отрицаемые условия

Синтаксис отрицаемого условия

 NOT Condition-1
 ~~~

Условие может быть отрицательным, добавив оператор NOT перед ним.

  1. Оператор NOT имеет наивысший приоритет среди всех логических операторов, так же как и унарный минус (который «отрицает» числовое значение) — наивысший приоритет арифметических операторов.
  2. Скобки должны использоваться для явного указания последовательности, в которой условия оцениваются и обрабатываются, если приоритет по умолчанию нежелателен. Например:
    NOT TRUE AND FALSE AND NOT FALSE

    Вычисляется как FALSE AND FALSE AND TRUE, что вычисляется как FALSE

    NOT (TRUE AND FALSE AND NOT FALSE)

    Вычисляется как NOT (FALSE), что вычисляется как TRUE

    NOT TRUE AND (FALSE AND NOT FALSE)

    Вычисляется как FALSE AND (FALSE AND TRUE), что вычисляется как FALSE

2.2.6. Использование точек

Все реализации COBOL различают предложения и операторы в разделе процедур. Оператор — это единственная исполняемая команда COBOL. Например, следующие являются операторами:

MOVE SPACES TO Employee-Address
ADD 1 TO Record-Counter
DISPLAY "Record-Counter=" Record-Counter

У некоторых операторов COBOL есть сфера применимости, где один или несколько других операторов могут рассматриваться как часть или связанные с данным оператором. Пример такой ситуации может быть следующим, где рассчитывается и отображается процентная ставка по кредиту в 4% для баланса кредита менее 10 000$, и в 4.5% в противном случае. (ПРЕДУПРЕЖДЕНИЕ: следующий код содержит ошибку!):

IF Loan-Balance < 10000
    MULTIPLY Loan-Balance BY 0.04 GIVING Interest
ELSE
    MULTIPLY Loan-Balance BY 0.045 GIVING Interest
DISPLAY "Interest Amount = " Interest

В этом примере оператор IF фактически имеет область, которая может включать два набора связанных операторов: один набор для выполнения, когда условие IF (см. IF) имеет значение TRUE, и другой, если это FALSE.

К сожалению, есть проблема с вышеприведенным примером. Человек, смотрящий на этот код, вероятно, предположит, что оператор DISPLAY (см. DISPLAY), из-за отсутствия отступов, должен выполняться независимо от значения условия TRUE/FALSE IF. К сожалению, компилятор (любой компилятор COBOL) не будет видеть это так, потому что его совершенно не интересует вид используемых отступов. Фактически, любой компилятор COBOL будет одинаково рад видеть код, написанный так:

IF Loan-Balance < 10000 MULTIPLY Loan-balance
BY 0.04 GIVING Interest ELSE MULTIPLY
Loan-Balance BY 0.045 GIVING Interest DISPLAY
"Interest Amount = " Interest

Как же мы сообщим компилятору, что оператор DISPLAY находится вне области оператора IF?

Здесь на помощь приходят предложения.

Предложение COBOL определяется как произвольно длинная последовательность операторов, за которой следует символ точки (.). Символ точки завершает область набора операторов. Следовательно, наш пример должен был быть закодирован так:

IF Loan-Balance < 10000
    MULTIPLY Loan-Balance BY 0.04 GIVING Interest
ELSE
    MULTIPLY Loan-Balance BY 0.045 GIVING Interest.
DISPLAY "Interest Amount = " Interest

Видите точку в конце второго оператора MULTIPLY (см. MULTIPLY)? Именно она завершает область операторов IF, тем самым делая выполнение оператора DISPLAY полностью независимым от значения TRUE/FALSE условия IF.

2.2.7. Использование конструкций VERB/END-VERB

До стандарта COBOL 1985 использование точки было единственным способом обозначить конец области действия оператора.

К сожалению, это вызвало некоторые проблемы. Посмотрите на этот код:

IF A = 1
    IF B = 1
        DISPLAY "A & B = 1"
ELSE *> This ELSE has a problem!
    IF B = 1
        DISPLAY "A NOT = 1 BUT B = 1"
    ELSE
        DISPLAY "NEITHER A NOR B = 1".

Проблема с этим кодом заключается в том, что отступы — настолько важные для улучшения читабельности программы человеком — могут дать ошибочное представление о логическом потоке. Оператор ELSE всегда связан с самым последним встреченным оператором IF; это означает, что выделенный оператор ELSE будет связан с оператором IF B = 1, а не с оператором IF A = 1, как может показаться по отступам.

Этот вид проблемы привел к появлению временного решения, добавленного к языку COBOL: ключевое слово NEXT SENTENCE.

IF A = 1
    IF B = 1
        DISPLAY "A & B = 1"
    ELSE
        NEXT SENTENCE
ELSE
    IF B = 1
        DISPLAY "A NOT = 1 BUT B = 1"
    ELSE
        DISPLAY "NEITHER A NOR B = 1".

NEXT SENTENCE сообщает компилятору, что если условие B = 1 ложно, управление должно перейти к первому оператору, следующему за следующей точкой.

В стандарте COBOL 1985 был представлен гораздо более элегантный способ решения. Любой оператор COBOL (первое ключевое слово оператора), которому необходимо это, может использовать конструкцию END-verb для завершения области без нарушения области любого другого оператора, в котором он мог находиться. Любой компилятор COBOL 85 допустил бы следующее решение нашей проблемы:

IF A = 1
    IF B = 1
        DISPLAY "A & B = 1"
    END-IF
ELSE
    IF B = 1
        DISPLAY "A NOT = 1 BUT B = 1"
    ELSE
        DISPLAY "NEITHER A NOR B = 1".

Эта новая возможность сделала точку практически устаревшей, так как наш фрагмент программы, вероятно, был бы закодирован так сегодня:

IF A = 1
    IF B = 1
        DISPLAY "A & B = 1"
    END-IF
ELSE
    IF B = 1
        DISPLAY "A NOT = 1 BUT B = 1"
    ELSE
        DISPLAY "NEITHER A NOR B = 1"
    END-IF
END-IF

COBOL (включая GnuCOBOL) по-прежнему требует, чтобы каждый параграф раздела процедур содержал хотя бы одно предложение, если в нем есть исполняемый код, но популярным стилем кодирования сейчас является простое кодирование одной точки непосредственно перед концом каждого параграфа.

Стандарт языка COBOL показывает, что различные ключевые слова END-verb являются необязательными, так как использование точки в качестве разделителя областей остается допустимым.

Если вы будете портировать существующий код в GnuCOBOL, вы обнаружите, что это полезная возможность, позволяющая соответствовать используемым языковым и стилистическим стандартам. Однако, если вы создаете новые программы GnuCOBOL, я настоятельно рекомендую вам использовать структуры END-verb в этих программах.

2.2.8. Одновременный доступ к файлам

Обработка данных файлов является одним из больших преимуществ языка COBOL. В COBOL есть функции для решения проблемы одновременного доступа к одному и тому же файлу несколькими программами. Одновременный доступ нескольких программ обрабатывается двумя способами — совместное использование файлов и блокировка записей.

Не все реализации GnuCOBOL поддерживают совместное использование файлов и блокировку записей. Это зависит от операционной системы, для которой они были созданы, и опций сборки, которые использовались при создании конкретной реализации GnuCOBOL.

2.2.8.1. Совместное использование файлов

GnuCOBOL управляет одновременным доступом к файлам на самом высоком уровне с помощью концепции совместного использования файлов, которая применяется при попытке программы открыть файл. Это достигается с помощью системной процедуры UNIX, называемой fcntl. Этот модуль в настоящее время не поддерживается Windows и отсутствует в пакете эмуляции Unix MinGW. GnuCOBOL-сборки, созданные с помощью среды MinGW, не смогут поддерживать контроль совместного использования файлов — файлы всегда будут совместно использоваться в таких средах. GnuCOBOL-сборка, созданная с использованием среды Cygwin в Windows, будет иметь доступ к fcntl и, следовательно, будет поддерживать совместное использование файлов. Конечно, у реальных сборок GnuCOBOL для Unix, а также для OSX не должно быть проблем, так как fcntl должно быть доступно.

Любые ограничения, наложенные на успешное OPEN (см. OPEN), останутся в силе до тех пор, пока ваша программа не выполнит CLOSE (см. CLOSE) для файла или пока программа не завершится.

Совместное использование файлов контролируется с помощью SHARING-клаузы:

    SHARING WITH { ALL OTHER }
    ~~~~~~~      { ~~~       }
                 { NO OTHER  }
                 { ~~        }
                 { READ ONLY }
                   ~~~~ ~~~~

Эта клауза может использоваться в операторе SELECT файла (см. SELECT), операторе OPEN (см. OPEN), который инициирует использование файла вашей программой, или в обоих. Если SHARING вариант указан в обоих местах, указания, сделанные в операторе OPEN, будут иметь приоритет над указаниями из оператора SELECT.

Вот значения трех вариантов:

ALL OTHER

Когда ваша программа открывает файл с этим вариантом совместного использования, никаких ограничений не будет накладываться на другие программы, пытающиеся OPEN файл после вашей программы. Это режим совместного использования по умолчанию.

NO OTHER

Когда ваша программа открывает файл с этим вариантом совместного использования, ваша программа объявляет, что не позволит никаким другим программам иметь доступ к файлу, пока вы используете этот файл; OPEN попытки в других программах будут неуспешны со статусом файла 37 (PERMISSION DENIED) до тех пор, пока вы не CLOSE (см. CLOSE) файл.

READ ONLY

Открытие файла с этим вариантом совместного использования означает, что вы согласны позволить другим программам OPEN файл для чтения, пока вы его держите открытым. Если они попытаются любое другое OPEN, у них это не получится со статусом файла 37. Конечно, ваша программа может потерпеть неудачу, если кто-то другой получил доступ к файлу раньше и открыл его с вариантом совместного использования, который наложил ограничения на совместное использование файлов.

Если SELECT файла закодирована с FILE STATUS клаузой, OPEN неудачи — включая те, которые вызваны проблемами с совместным использованием — будут определяемы программой, и будет возможна плавная работа восстановления (или, по крайней мере, плавное завершение).

Однако, если такая клауза не была закодирована, будет выведено сообщение во время выполнения, и программа завершится.

2.2.8.2. Блокировка записей

Блокировка записей поддерживается усовершенствованным программным обеспечением для управления файлами, встроенным в используемую вами реализацию GnuCOBOL. Это программное обеспечение предоставляет единую точку контроля доступа к файлам — обычно к файлам ORGANIZATION INDEXED. Одним из таких пакетов выполнения, способных сделать это, является пакет Berkeley Database (BDB) — часто используемый пакет в GnuCOBOL-сборках для поддержки индексированных файлов.

Различные операторы ввода-вывода, которые может выполнить ваша программа, могут наложить ограничения на доступ других одновременно выполняемых программ к записи файла, к которой они только что получили доступ. Эти ограничения синтаксически налагаются путём блокирования записи с использованием LOCK клаузы. Другие записи в файле остаются доступными, предполагая, что ограничения совместного использования файлов, наложенные при открытии файла, не препятствовали доступу ко всему файлу.

  1. Если используемая вами сборка GnuCOBOL была настроена на использование пакета Berkeley Database (BDB) для ввода-вывода индексированных файлов, блокировка записей будет доступна с помощью переменной среды выполнения DB_HOME.
  2. Если оператор SELECT (см. SELECT) или файл OPEN (см. OPEN) указывает SHARING WITH NO OTHER, блокировка записей будет отключена.
  3. Если SELECT файла содержит предложение LOCK MODE IS AUTOMATIC, каждый раз при чтении записи из файла эта запись автоматически блокируется. Другие программы могут обращаться к другим записям в файле, но не к заблокированной записи.
  4. Если SELECT файла содержит предложение LOCK MODE IS MANUAL, блокировки записей устанавливаются только тогда, когда оператор READ, выполняемый над файлом, включает предложение LOCK (это предложение будет рассмотрено вскоре).
  5. Если предложение LOCK ON указано в SELECT файла, блокировки (автоматически или вручную полученные) будут накапливаться по мере чтения всё большего и большего числа записей, пока они явно не будут освобождены. Это называется блокировкой нескольких записей.

    Блокировки, полученные посредством блокировки нескольких записей, остаются в силе до тех пор, пока программа, удерживающая блокировку…

    • …не завершится, или …
    • …не выполнит оператор CLOSE (см. CLOSE) над файлом, или …
    • …не выполнит оператор UNLOCK (см. UNLOCK) над файлом, или …
    • …не выполнит оператор COMMIT (см. COMMIT) или …
    • …не выполнит оператор ROLLBACK (см. ROLLBACK).
  6. Если предложение LOCK ON не указано, то следующий оператор ввода-вывода, выполняемый вашей программой, за исключением START (см. START), освободит блокировку. Это называется блокировкой одной записи.
  7. Предложение LOCK, которое может быть включено в операторах READ (см. READ), REWRITE (см. REWRITE) или WRITE (см. WRITE), выглядит следующим образом:
        { IGNORING LOCK    }
        { ~~~~~~~~ ~~~~    }
        { WITH [ NO ] LOCK }
        {        ~~   ~~~~ }
        { WITH KEPT LOCK   }
        {      ~~~~ ~~~~   }
        { WITH IGNORE LOCK }
        {      ~~~~~~ ~~~~ }
        { WITH WAIT        }
               ~~~~
    

    Вариант WITH [ NO ] LOCK — единственный доступный для операторов REWRITE или WRITE.

    Значения различных вариантов блокировки записей следующие:

    IGNORING LOCK
    WITH IGNORE LOCK

    Эти варианты (синонимичные) сообщают GnuCOBOL, что любые блокировки, удерживаемые другими программами, должны игнорироваться.

    WITH LOCK

    Доступ к записи другими программами будет запрещен.

    WITH NO LOCK

    Запись не будет заблокирована. Это значение по умолчанию для всех операторов.

    WITH KEPT LOCK

    При блокировке одной записи, когда к новой записи осуществляется доступ, блокировки, полученные для предыдущих записей, освобождаются. Используя этот вариант, не только новая доступная запись блокируется (как это сделало бы WITH LOCK), но и блокировки предыдущих записей сохраняются. Последующий оператор READ без опции KEPT LOCK освободит все «сохраненные» блокировки, как и оператор UNLOCK.

    WITH WAIT

    Этот вариант сообщает GnuCOBOL, что программа готова дождаться освобождения блокировки, удерживаемой (другой программой) на считываемой записи.

    Без этого варианта попытка чтения заблокированной записи будет немедленно прервана, и будет возвращён код состояния файла 51.

    С этим вариантом программа будет ждать в течение заданного времени освобождения блокировки. Если блокировка будет освобождена в течение установленного времени ожидания, чтение будет успешным. Если установленное время ожидания истечёт до освобождения блокировки, попытка чтения будет прервана, и будет выдан код состояния файла 51.

3. CDF - Директивы компилятора

Директивы компилятора, или CDF, предоставляют способ управления компиляцией программ GnuCOBOL. CDF обеспечивает механизм для динамической установки или сброса определённых переключателей компилятора, введения нового исходного кода из одной или нескольких библиотек исходного кода, внесения динамических изменений в исходный код и условной обработки или игнорирования операторов исходного кода. Это достигается с помощью набора специальных операторов и директив CDF, которые будут отображаться в исходном коде программы.

Когда компилятор работает в режиме фиксированного формата, все операторы CDF должны начинаться с восьмого (8) или последующих столбцов.

В GnuCOBOL поддерживаются два типа операторов CDF — операторы обработки текста и директивы компилятора.

Операторы обработки текста CDF COPY и REPLACE используются для введения нового кода в программы с или без изменений, или могут быть использованы для изменения существующих операторов в программе. Операторы обработки текста всегда завершаются точкой.

Директивы CDF, обозначаемые наличием последовательности символов >> в имени оператора, влияют на процесс компиляции программы.

Директивы компилятора никогда не завершаются точкой.

Опция компилятора -D предоставляет дополнительный контроль (см. cobc - Компилятор GnuCOBOL).

3.1. >>CALL-CONVENTION

Синтаксис CDF >>CALL-CONVENTION

 >>CALL-CONVENTION    { COBOL   }
 ~~~~~~~~~~~~~~~~~    { EXTERN  }
                      { STDCALL }
                      { STATIC  } 

Данная директива указывает компилятору, как обращаться к именам программ, и может использоваться для определения других деталей взаимодействия с функцией или программой. Существует четыре варианта, по умолчанию используется COBOL.

COBOL

Имя программы обрабатывается как слово COBOL, которое сопоставляется с внешним именем вызываемой, отменяемой или упоминаемой программы в идентификаторе адреса программы, применяя те же правила сопоставления, что и для имени программы, для которого не указана фраза AS. (Это значение по умолчанию.)

EXTERN

Имя программы обрабатывается как внешняя ссылка.

STDCALL

[требуется дополнительная информация]

STATIC

Имя программы вызывается как включённый элемент и не динамически, что является стандартным значением по умолчанию.

3.2. COPY

Синтаксис оператора CDF COPY

 COPY copybook-name
 ~~~~
 [ IN|OF library-name ]
   ~~ ~~
 [ SUPPRESS PRINTING ]
   ~~~~~~~~
 [ REPLACING { Phrase-Clause | String-Clause }... ] .
   ~~~~~~~~~

Синтаксис фразы-описания CDF COPY

 { ==pseudo-text-1== } BY { ==pseudo-text-2== }
 { identifier-1      } ~~ { identifier-2      }
 { literal-1         }    { literal-2         }
 { word-1            }    { word-2            }

Синтаксис строки CDF COPY

 [ LEADING|TRAILING ] ==partial-word-1== BY ==partial-word-2==
   ~~~~~~~ ~~~~~~~~                      ~~
  1. операторы COPY используются для импорта копибуков (см. Копибуки) в программу.
  2. операторы COPY могут использоваться в любом месте программы COBOL, где код, содержащийся в копибуке, был бы синтаксически корректным.
  3. необязательная фраза SUPPRESS (с необязательным служебным словом PRINTING) синтаксически верна, но не функциональна. Она поддерживается для обеспечения совместимости с исходным кодом, написанным для других версий COBOL.
  4. Нет никакой разницы между использованием слова IN и слова OF — используйте то, которое вам больше нравится.
  5. Точка строго обязательна в конце каждого оператора COPY, даже если оператор находится в области действия другого оператора, где точка может показаться нарушающей, например, в области действия оператора IF (см. IF). Однако эта обязательная точка в конце оператора не влияет на область действия оператора, в которой находится оператор COPY.
  6. И pseudo-text-2, и partial-word-2 могут быть пустыми.
  7. Все операторы COPY располагаются, и содержимое соответствующих копибуков вставляется в исходный код программы до начала фактического процесса компиляции. Если копибук содержит оператор COPY, процесс вставки копибука будет повторяться для разрешения встроенного оператора COPY. Это будет продолжаться до тех пор, пока не останется неразрешённых операторов COPY. В этот момент начнется фактическая компиляция программы.
  8. См. Расположение копибуков для получения подробных правил о том, как компилятор ищет копибуки.
  9. Необязательная фраза REPLACING позволяет выполнить одно или несколько из следующих типов замен текста:
    Фраза-описание

    Замена одного или нескольких полных служебных слов, пользовательских идентификаторов или литералов; для этого варианта справедливы следующие замечания:

    • Этот вариант нельзя использовать для замены части слова, идентификатора или литерала.
    • Всё, что предшествует BY, здесь рассматривается как строка поиска.
    • Строки поиска из одного элемента можно указать, закодировав заменяемые identifier-1, literal-1 или word-1.
    • Строки поиска из нескольких элементов можно указать, используя опцию ==pseudo-text-1==. Например, чтобы заменить все вхождения UPON PRINTER, нужно указать ==UPON PRINTER==.
    • Строка замены, которая следует за BY, может быть указана любым из четырёх вариантов.
    • Если строка замены — многоэлементная фраза или должна быть полностью удалена, нужно использовать опцию ==pseudo-text-2==. Если pseudo-text-2 пусто (то есть текст замены задан как ====), все обнаруженные вхождения строки поиска будут удалены.
    Строка-описание

    С помощью этого варианта можно заменить последовательности символов, которые встречаются в начале (см. LEADING) или конце (см. TRAILING) служебных или пользовательских слов. Например, чтобы изменить все слова вида «0100-xxxxxx» на «020-xxxxxx», нужно закодировать LEADING ==0100-== BY ==020-==. Чтобы просто удалить все префиксы «0100-» из слов, нужно закодировать LEADING ==0100-== BY ====.

3.3. REPLACE

Синтаксис оператора CDF REPLACE (форма 1)

 REPLACE [ ALSO ] { Phrase-Clause | String-Clause }... .
 ~~~~~~~   ~~~~

Синтаксис оператора CDF REPLACE (форма 2)

 REPLACE [ LAST ] OFF .
 ~~~~~~~   ~~~~   ~~~

Синтаксис фразы CDF REPLACE

 { ==pseudo-text-1== } BY { ==pseudo-text-2== }
                       ~~

Синтаксис строки CDF REPLACE

 [ LEADING|TRAILING ] ==partial-word-1== BY ==partial-word-2==
   ~~~~~~~ ~~~~~~~~                      ~~
  1. Инструкция REPLACE предоставляет механизм изменения всех или части одного или нескольких операторов GnuCOBOL.
  2. Точка является абсолютно обязательной в конце каждого оператора REPLACE (любой формат), даже если оператор находится в области действия другого оператора, где точка может показаться помехой (например, в области действия оператора IF (см. IF)); точка, однако, не повлияет на область действия оператора, в котором находится REPLACE.
  3. Следующие пункты относятся к формату 1 инструкции REPLACE:
    1. Формат 1 инструкции REPLACE может использоваться для изменения исходного кода программы аналогично опции REPLACING инструкции COPY с помощью этих опций:
      Phrase-Clause

      Заменить один или несколько полных ключевых слов, определяемых пользователем идентификаторов или литералов; следующие пункты относятся к этой опции:

      • Эта опция не может использоваться для замены части слова, идентификатора или литерала.
      • Всё, что предшествует BY, будет здесь называться строкой поиска.
      • Строки поиска в REPLACE всегда указываются с использованием опции ==pseudo-text-1==. Например, чтобы заменить все вхождения UPON PRINTER, вы бы указали ==UPON PRINTER==.
      • Строка замены, которая следует за BY, указывается с использованием опции ==pseudo-text-2==. Если pseudo-text-2 пуста (то есть, текст замены указан как ====), все найденные вхождения строки поиска будут удалены.
      String-Clause

      С помощью этого вы можете заменить последовательности символов, которые встречаются в начале (см. LEADING) или в конце (см. TRAILING) ключевых или определяемых пользователем слов. Например, чтобы изменить все слова вида "0100-xxxxxx" на "020-xxxxxx", используйте LEADING ==0100-== BY ==020-==. Чтобы просто удалить все префиксы "0100-" из слов, используйте LEADING ==0100-== BY ====.

    2. После обнаружения инструкции REPLACE Формат 1 в текущем компилируемом исходном файле, режим замены становится активным, и указанные в этой инструкции изменения будут автоматически внесены во все последующие операторы исходного кода, которые компилятор считывает из файла.
    3. Режим замены сохраняется — продолжая вносить изменения в исходный код — до тех пор, пока не будет обнаружена другая инструкция REPLACE Формат 1, пока не будет достигнут конец компилируемой программы или пока не будет обнаружена инструкция REPLACE Формат 2.
    4. Когда встречается инструкция REPLACE Формат 1 с ключевым словом ALSO, без того, чтобы Режим замены был активен, эффект будет таким, как если бы ALSO не было указано. Если Режим замены уже был активен, эффект будет заключаться в «добавлении» текущей спецификации изменения на вершину стека и добавлении спецификаций нового оператора к тем, которые уже действовали.
    5. При встрече инструкции REPLACE Формат 1 без ключевого слова ALSO, любые сохранённые спецификации изменений, если таковые имеются, будут удалены, и текущая спецификация изменения, если таковая имеется, будет заменена спецификациями нового оператора.
    6. По достижении конца текущего компилируемого исходного файла, Режим замены деактивируется, и любые сохранённые спецификации замены будут удалены — компиляция следующего исходного файла (если таковой имеется) начнётся с неактивным Режимом замены и без спецификаций изменения в стеке.
  4. Следующие пункты относятся к формату 2 инструкции REPLACE:
    1. Если Режим замены в данный момент неактивен, инструкция REPLACE Формат 2 будет проигнорирована.
    2. Если Режим замены в данный момент активен, оператор REPLACE OFF. деактивирует Режим замены и удалит любые спецификации замены из стека. Компилятор продолжит работу так, как будто REPLACE никогда не встречалось, до тех пор, пока не встретится другая инструкция REPLACE Формат 1.
    3. Если Режим замены в данный момент активен, оператор REPLACE LAST OFF. заменит текущие спецификации замены на те, которые были извлечены из вершины стека. Если спецификаций замены в стеке не было, эффект будет таким, как если бы была закодирована инструкция REPLACE OFF..

3.4. >>DEFINE

CDF >>DEFINE Directive Syntax

 >>DEFINE [ CONSTANT ] cdf-variable-1 AS { OFF                    }
 ~~~~~~~~   ~~~~~~~~                     { ~~~                    }
                                         { literal-1 [ OVERRIDE ] }
                                         {             ~~~~~~~~   }
                                         { PARAMETER [ OVERRIDE ] }
                                           ~~~~~~~~~   ~~~~~~~~

Используйте директиву >>DEFINE CDF для создания переменных CDF и (необязательно) присваивания им значений — литералов или переменных среды.

  1. Зарезервированное слово AS является необязательным и может быть включено или нет по усмотрению программиста. Наличие или отсутствие этого слова не влияет на программу.
  2. Переменные CDF, определённые таким образом, становятся неопределёнными после столкновения с директивой END PROGRAM или END FUNCTION в исходном коде.
  3. Директива CDF >>DEFINE — один из способов создания переменных CDF, которые могут обрабатываться другими операторами CDF, такими как >>IF (см. >>IF). Директива CDF >>SET (см. >>SET) предоставляет другой способ их создания.
  4. Имена переменных CDF следуют правилам стандартных имен, определённых пользователем в GnuCOBOL, и не могут дублировать какие-либо зарезервированные слова CDF. Имена переменных CDF могут дублировать зарезервированные слова COBOL, при условии, что опция CONSTANT не указана, но такие имена не рекомендуются.
  5. Опция CONSTANT допустима только в сочетании с literal-1. Когда CONSTANT указана, переменная CDF, которая создаётся, может использоваться в вашем обычном коде COBOL, как если бы это было значение литерала. Без этой опции переменная CDF может быть использована только в других операторах CDF. Опция OFF используется для создания переменной без присваивания ей какого-либо значения.
  6. Опция PARAMETER используется для создания переменной, значение которой соответствует значению переменной среды с тем же именем. Обратите внимание, что это присваивание значения происходит во время компиляции, а не во время выполнения программы.
  7. При отсутствии опции OVERRIDE, cdf-variable-1 ещё не должна быть определена. Когда опция OVERRIDE указана, cdf-variable-1 будет создана со значением, указанным в опции, если она ещё не была определена. Если она была определена ранее, она будет переопределена с новым значением.

3.5. >>IF

Синтаксис директивы CDF >>IF

 >>IF CDF-Conditional-Expression-1
 ~~~~     [ Program-Source-Lines-1 ]

 [ >>ELIF CDF-Conditional-Expression-2
   ~~~~~~ [ Program-Source-Lines-2 ] ]...

 [ >>ELSE
   ~~~~~~ [ Program-Source-Lines-3 ] ]

 >>END-IF
 ~~~~~~~~

Синтаксис CDF-условного выражения

 { cdf-variable-1 } IS [ NOT ] { DEFINED                      }
 { literal-1      }      ~~~   { ~~~~~~~                      }
                               { SET                          }
                               { ~~~                          }
                               { CDF-RelOp { cdf-variable-2 } }
                               {           { literal-2      } }

Синтаксис CDF-RelOp

 >=    or    GREATER THAN OR EQUAL TO
             ~~~~~~~      ~~ ~~~~~
 >     or    GREATER THAN
             ~~~~~~~
 <=    or    LESS THAN OR EQUAL TO
             ~~~~      ~~ ~~~~~
 <     or    LESS THAN
             ~~~~
 =     or    EQUAL TO
             ~~~~~
 <>    or    EQUAL TO (with "NOT")
             ~~~~~

Директива CDF >>IF заставляет компилятор GnuCOBOL обрабатывать или игнорировать операторы исходного кода COBOL, операторы обработки текста CDF и/или директивы CDF в зависимости от значения одного или нескольких условных выражений, основанных на переменных CDF.

  1. Зарезервированные слова IS, THAN и TO являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Каждая директива >>IF должна завершаться директивой >>END-IF.
  3. После директивы >>IF может следовать любое количество >>ELIF разделов, включая ноль.
  4. После директивы >>IF может быть не более одного раздела >>ELSE. Если используется >>ELSE, он должен следовать за >>IF и всеми >>ELIF разделами.
  5. Компилятор может обработать только один из блоков операторов Program-Source-Lines-n, находящихся в области действия >>IF … >>END-IF. Какой именно (если таковой имеется) будет обработан, определяется следующим образом:
    1. Каждое выражение CDF-Conditional-Expression-n оценивается поочередно в том порядке, в котором они записаны в операторе >>IF и любых >>ELIF разделах, которые могут присутствовать, до тех пор, пока одно из них не примет значение TRUE. Как только одно из выражений примет значение TRUE, блок операторов Program-Source-Lines-n, соответствующий выражению CDF-Conditional-Expression-n, будет обработан. Все остальные блоки в области действия >>IF->>END-IF будут проигнорированы.
    2. Если ни одно выражение CDF-Conditional-Expression не примет значение TRUE, и существует раздел >>ELSE, блок операторов Program-Source-Lines-3, следующий за разделом >>ELSE, будет обработан компилятором, а все остальные блоки в области действия >>IF->>END-IF будут проигнорированы.
    3. Если ни одно выражение CDF-Conditional-Expression-n не примет значение TRUE и раздел >>ELSE отсутствует, то ни один из блоков операторов Program-Source-Lines-n в области действия >>IF->>END-IF не будет обработан компилятором.
    4. Если выбранный для обработки блок операторов Program-Source-Lines-n пустой, ошибки не возникает — просто не будет сгенерирован код из структуры >>IF->>END-IF.
  6. Блок Program-Source-Lines-n может содержать любой допустимый код COBOL или CDF.
  7. Следующие пункты относятся к любому выражению CDF-Conditional-Expression-n:
    1. Опция DEFINED проверяет, был ли cdf-variable-1 определён, но ещё не присвоено значение (>>DEFINE … OFF); используйте опцию NOT для проверки того, что переменная не определена.
    2. Опция SET проверяет, было ли переменной cdf-variable-1 присвоено значение, либо с помощью оператора >>SET, либо с помощью оператора >>DEFINE без опции OFF.
    3. Два CDF-переменных, два литерала или одна CDF-переменная и один литерал могут быть сравнены друг с другом с помощью оператора отношения. В отличие от стандартного оператора GnuCOBOL IF (см. IF), несколько сравнений не могут быть объединены или сцеплены; однако вы можете вложить второе >>IF внутрь первого, чтобы смоделировать оператор AND, и оператор OR может быть смоделирован с помощью опции >>ELIF.
    4. Символ <> обозначает NOT EQUAL TO.

3.6. >>SET

CDF >>SET Директива синтаксиса

 >>SET { [ CONSTANT ] cdf-variable-1 literal-1 ] }
 ~~~~~ {   ~~~~~~~~                              }
       { SOURCEFORMAT AS FIXED|FREE              }
       { ~~~~~~~~~~~~    ~~~~~ ~~~~              }
       { NOFOLDCOPYNAME                          }
       { ~~~~~~~~~~~~~~                          }
       { FOLDCOPYNAME AS UPPER|LOWER             }
         ~~~~~~~~~~~~    ~~~~~ ~~~~~

Директива CDF >>SET предоставляет альтернативный способ выполнения действий директив >>DEFINE и >>SOURCE, а также способ управления переключателями компилятора -free, -fixed и -ffold-copy внутри исходного кода программы.

  1. Зарезервированное слово AS является необязательным (только в SOURCEFORMAT и FOLDCOPYNAME разделах) и может быть включено или нет по усмотрению программиста. Его наличие или отсутствие не влияет на программу.
  2. CDF-переменные, определённые таким образом, становятся неопределёнными после встреченного оператора END PROGRAM или END FUNCTION в исходном коде.
  3. Опция FOLDCOPYNAME обеспечивает эквивалент указания переключателя компилятора -ffold-copy=xxx, где xxx представляет собой либо UPPER, либо LOWER.
  4. Опция NOFOLDCOPYNAME отключает действие оператора >>SET FOLDCOPYNAME или переключателя компилятора -ffold-copy=xxx.
  5. Если используется опция CONSTANT, literal-1 также должно быть указано. Эта опция предоставляет другой способ определения констант, которые могут быть использованы в любой части программы там, где может быть указан литерал.
  6. Остальные опции директивы CDF >>SET обеспечивают эквивалентную функциональность директив >>DEFINE и >>SOURCE, как показано ниже:
    >>SET cdf-variable-1

    >>DEFINE cdf-variable-1 AS OFF

    >>SET cdf-variable-1 AS literal-1

    >>DEFINE cdf-variable-1 AS literal-1

    >>SET CONSTANT cdf-variable-1 literal-1

    >>DEFINE CONSTANT cdf-variable-1 literal-1

    >>SET SOURCEFORMAT AS FIXED

    >>SOURCE FORMAT IS FIXED

    >>SET SOURCEFORMAT AS FREE

    >>SOURCE FORMAT IS FREE

    >>SET XFD literal-1

    [необходимо сделать]

    >>SET Micro-Focus-Directive

    [необходимо сделать]

3.7. >>SOURCE

CDF >>SOURCE Директива синтаксиса

 >>SOURCE FORMAT IS FIXED|FREE|VARIABLE
 ~~~~~~~~           ~~~~~ ~~~~ ~~~~~~~~

Директива >>SOURCE CDF помещает компилятор в режим формата исходного кода FIXED или FREE. Это, по сути, предоставляет ещё один механизм управления переключателями компилятора -free и -fixed.

  1. Зарезервированные слова FORMAT и IS являются необязательными и могут быть включены или не включены по усмотрению программиста. Наличие или отсутствие этих слов не оказывает влияния на программу.
  2. Вы можете переключаться между режимами FIXED и FREE по желанию.
  3. Вы также можете использовать директиву >>SET CDF для выполнения этой функции.
  4. Если компилятор уже находится в указанном режиме, эта инструкция не повлияет на него.

3.8. >>TURN

Синтаксис директивы CDF >>TURN

 >>TURN { exception-name-1 [ file-name-1 ]... }...
 ~~~~~~
    { OFF                           }
    { ~~~                           }
    { CHECKING ON [ WITH LOCATION ] }
      ~~~~~~~~ ~~        ~~~~~~~~

Директива (де-)активирует проверки исключений.

3.9. >>D

Синтаксис директивы CDF >>D

 >>D
 ~~~

Директива удаляет все строки отладки с плавающей точкой, если режим отладки не активен. В противном случае игнорирует часть директивы в строке.

3.10. >>DISPLAY

Синтаксис директивы CDF >>DISPLAY

 >>DISPLAY source-text [ VCS = version-string ]
 ~~~~~~~~~               ~~~

Директива является расширением v1.0 и будет отображать сообщения во время компиляции.

3.11. >>PAGE

Синтаксис директивы CDF >>PAGE

 >>PAGE
 ~~~~~~

Директива позволяет использовать управляющие символы страниц IBM: EJECT, SKIP1, SKIP2, SKIP3 и TITLE.

3.12. >>LISTING

Синтаксис директивы CDF >>LISTING

 >>LISTING  {ON}
 ~~~~~~~~~  {OFF}

Директива позволяет де-(активировать) вывод списка программы.

3.13. >>LEAP-SECONDS

Синтаксис директивы CDF >>LEAP-SECONDS

 >>LEAP-SECONDS
 ~~~~~~~~~~~~~~

Директива >>LEAP-SECONDS CDF синтаксически распознается, но в остальном не функциональна.

Позволяет использовать более 60 секунд в минуте.

3.14. $ Директивы

Синтаксис директивы CDF $

 $ (Dollar) Directives - Active.

 These directives are active and have the same function as ones starting with >>:

 $DEFINE
 $DISPLAY ON|OFF
 $IF
 $ELIF
 $ELSE
 $ELSE-IF
 $END
 $SET

 It is recommend to use the standard directives only instead of the MF directives
 (when possible) as these have a a higher chance for being portable.

 $ (Dollar) Directives - Not Active.
 These are NOT active and will produce a warning message:

 $DISPLAY VCS ...

 Recognised but otherwise ignored.

 @OPTIONS options-text

 Additional Micro-Focus directives accepted :

 ADDRSV | ADD-RSV literal-1
 ADDSYN | ADD-SYN literal-1 = literal-2
 ASSIGN  "EXTERNAL" | "DYNAMIC"
 BOUND
 CALLFH  literal-1
 COMP1  |  COMP-1  "BINARY" | "FLOAT"
 FOLDCOPYNAME | FOLD-COPY-NAME  AS "UPPER" | "LOWER"
 MAKESYN  |  MAKE-SYN
 NOBOUND  |  NO-BOUND
 NOFOLDCOPYNAME  |  NOFOLD-COPY-NAME  |  NO-FOLD-COPY-NAME
 OVERRIDE  literal-1 = literal-2
 REMOVE  literal-1
 SOURCEFORMAT | SOURCE-FORMAT "FIXED" | "FREE" | "VARIABLE"
 SSRANGE "2"
 NOSSRANGE  |  NO-SSRANGE

Предлагает поддержку директив компилятора MF.

3.15. Предопределённые переменные компиляции

GnuCOBOL определяет переменные компиляции, когда выполняются различные условия. Если условие, связанное с переменной, ложно, переменная не определена.

DEBUG

Указан флаг отладки -d.

EXECUTABLE

Модуль, который компилируется, содержит главную программу.

GCCOMP

Размер COMP элемента определяется в соответствии со схемой GnuCOBOL, где для длины описания:

1 - 2

элемент = 1 байт

3 - 4

элемент = 2 байта

5 - 9

элемент = 4 байта

10 - 18

элемент = 8 байт

GNUCOBOL

GnuCOBOL компилирует блок исходного кода.

HOSTSIGNS

Значение числового элемента со знаком, представленного в формате упакованных десятичных чисел, может считаться NUMERIC , если знак = X"F".

IBMCOMP

Размер элемента COMP элемент определяется по схеме IBM, где для длины описания:

1 - 4

элемент = 2 байта

5 - 9

элемент = 4 байта

10 - 18

элемент = 8 байт

MODULE

Компилируемый элемент не содержит главную программу.

NOHOSTSIGNS

Значение числового элемента со знаком, представленного в формате упакованных десятичных чисел, не может считаться NUMERIC , если знак = X"F".

NOIBMCOMP

Размер элемента COMP не определяется по схеме IBM.

NOSTICKY-LINKAGE

Вязкая связь (элементы секции связи, остающиеся выделенными между вызовами) не активна.

NOTRUNC

Числовые данные обрезаются в соответствии с их внутренней формой представления.

P64

Указатели больше 32 бит.

STICKY-LINKAGE

Вязкая связь (элементы секции связи, остающиеся выделенными между вызовами) активна.

TRUNC

Числовые данные обрезаются в соответствии с их PICTURE пунктами.

Хотя эта функция всё ещё поддерживается, она может быть удалена в будущем и не должна использоваться. Вместо этого используйте GCCOMP и GNUCOBOL.

OCCOMP

Размер COMP элемента определяется по схеме GnuCOBOL, где для длины описания:

1 - 2

элемент = 1 байт

3 - 4

элемент = 2 байта

5 - 9

элемент = 4 байта

10 - 18

элемент = 8 байт

OPENCOBOL

GnuCOBOL компилирует блок исходного кода.

4. РАЗДЕЛ ИДЕНТИФИКАЦИИ

Синтаксис раздела IDENTIFICATION DIVISION

[{ IDENTIFICATION } DIVISION. ]
 { ~~~~~~~~~~~~~~ } ~~~~~~~~
 { ID             }
   ~~
 { PROGRAM-ID.  } { program name } .
 { ~~~~~~~~~~   } { literal-1    } [ AS { literal-2 } ] [ Type-clause ] .
 { FUNCTION-ID. } { literal-3 } [ AS literal-4 ] .
   ~~~~~~~~~~~    { function-name } .
 { OPTIONS. }
   ~~~~~~~
 [ DEFAULT ROUNDED MODE IS {AWAY-FROM-ZERO         }
   ~~~~~~~ ~~~~~~~         {NEAREST-AWAY-FROM-ZERO }
                           {NEAREST-EVEN           }
                           {NEAREST-TOWARDS-ZERO   }
                           {PROHIBITED             }
                           {TOWARDS-GREATER        }
                           {TOWARDS-LESSER         }
                           {TRUNCATION             }]
 [ ENTRY-CONVENTION IS {COBOL   }
   ~~~~~~~~~~~~~~~~    {EXTERN  }
                       {STDCALL }]
 [ AUTHOR.        comment-1. ]
   ~~~~~~
 [ DATE-COMPILED. comment-2. ]
   ~~~~~~~~~~~~~
 [ DATE-MODIFIED. comment-3. ]
   ~~~~~~~~~~~~~
 [ DATE-WRITTEN.  comment-4. ]
   ~~~~~~~~~~~~
 [ INSTALLATION.  comment-5. ]
   ~~~~~~~~~~~~
 [ REMARKS.       comment-6. ]
   ~~~~~~~
 [ SECURITY.      comment-7. ]
   ~~~~~~~~

Абзацы AUTHOR, DATE-COMPILED, DATE-MODIFIED, DATE-WRITTEN, INSTALLATION, REMARKS и SECURITY поддерживаются только GnuCOBOL для обеспечения совместимости с программами, написанными по стандартам ANS1974 (или более ранним). Согласно стандарту ANS1985, эти пункты устарели и не должны использоваться в новых программах.

Синтаксис пункта типа PROGRAM-ID

 IS [ COMMON ] [ INITIAL|RECURSIVE PROGRAM ]
      ~~~~~~     ~~~~~~~ ~~~~~~~~~

Раздел идентификации предоставляет основную информацию об идентификации программы, присваивая ей имя и, по желанию, определяя некоторые характеристики высокого уровня через восемь предопределённых абзацев, которые могут быть указаны.

  1. Приведённые выше абзацы могут быть записаны в любом порядке.
  2. Зарезервированные слова AS, IS и PROGRAM являются необязательными и могут быть включены или опущены по усмотрению программиста. Наличие или отсутствие этих слов не влияет на программу.
  3. Пункт Type Clause может быть записан только при указании PROGRAM-ID. Если он указан, необходимо указать COMMON, COMMON INITIAL или COMMON RECURSIVE.
  4. Хотя заголовки IDENTIFICATION DIVISION или ID DIVISION необязательны, абзацы PROGRAM-ID / FUNCTION-ID — нет; может быть указан только один из них.
  5. Переключатель компилятора -Wobsolete заставит компилятор GnuCOBOL выдавать предупреждающие сообщения, если используется устаревший синтаксис (или любой другой устаревший синтаксис) в программе.
  6. Если указан, literal-1 должен быть фактическим алфавитно-цифровым литералом и не может быть фигуральной константой.
  7. Абзацы PROGRAM-ID и FUNCTION-ID служат для идентификации программы для внешней среды (т. е. операционной системы). Если нет пункта AS, program-id будет служить этой внешней идентификацией. Если указан пункт AS, указанный литерал будет служить внешней идентификацией. В дальнейшем в этом документе эта «внешняя идентификация» будет называться основным именем точки входа.
  8. Слова INITIAL, COMMON и RECURSIVE используются только внутри подпрограмм, выполняющих роль подпрограмм. Их назначение таково:
    1. COMMON следует использовать только внутри подпрограмм, которые являются вложенными подпрограммами. Вложенную подпрограмму, объявленную как COMMON, можно вызывать из любой вложенной программы в исходном файле, который компилируется, а не только из тех, которые находятся «выше» её в структуре вложения.
    2. Пункт RECURSIVE, если он есть, заставит компилятор сгенерировать другой объектный код для подпрограммы, который позволит ей вызывать себя и правильно возвращаться в программу, которая её вызвала.

      Пользовательские функции (т. е. FUNCTION-ID) всегда рекурсивны.

    3. Пункт INITIAL, если он указан, гарантирует, что подпрограмма будет находиться в своём начальном (т. е. скомпилированном) состоянии каждый раз при выполнении, а не только в первый раз.

5. РАЗДЕЛ ОКРУЖАЮЩЕЙ СРЕДЫ

Синтаксис РАЗДЕЛА ОКРУЖАЮЩЕЙ СРЕДЫ

   ENVIRONMENT DIVISION.
   ~~~~~~~~~~~ ~~~~~~~~
 [ CONFIGURATION SECTION. ]
   ~~~~~~~~~~~~~ ~~~~~~~~
 [ SOURCE-COMPUTER.         Compilation-Computer-Specification . ]
   ~~~~~~~~~~~~~~~
 [ OBJECT-COMPUTER.         Execution-Computer-Specification . ]
   ~~~~~~~~~~~~~~~
 [ SPECIAL-NAMES.           Program-Configuration-Specification . ]
   ~~~~~~~~~~~~~
 [ REPOSITORY.              Function-Specification... . ]
   ~~~~~~~~~~
 [ INPUT-OUTPUT SECTION. ]
   ~~~~~~~~~~~~ ~~~~~~~
 [ FILE-CONTROL.            General-File-Description... . ]
   ~~~~~~~~~~~~
 [ I-O-CONTROL.             File-Buffering Specification... . ]
   ~~~~~~~~~~~

Этот раздел определяет внешнюю вычислительную среду, в которой будет работать программа. Это включает в себя определение любых файлов, которые может использовать программа.

  • Если оба необязательных раздела этого раздела записаны, они должны быть записаны в указанном порядке.
  • Абзацы внутри разделов могут быть записаны в любом порядке.
  • Эти разделы состоят из ряда специфических, предопределённых абзацев (SOURCE-COMPUTER и OBJECT-COMPUTER, например), каждый из которых служит определённой цели. Если для цели, которую служит абзац, не требуется код, весь абзац можно опустить.
  • Если какой-либо из абзацев в одном из разделов указан, сам заголовок раздела должен быть указан.
  • Если ни один из абзацев в одном из разделов не указан, сам заголовок раздела можно опустить.
  • Если ни один из разделов в разделе среды не указан, сам заголовок ENVIRONMENT DIVISION. можно опустить.

5.1. РАЗДЕЛ КОНФИГУРАЦИИ

Синтаксис РАЗДЕЛА КОНФИГУРАЦИИ

   CONFIGURATION SECTION.
   ~~~~~~~~~~~~~ ~~~~~~~
 [ SOURCE-COMPUTER. Compilation-Computer-Specification . ]
   ~~~~~~~~~~~~~~~
 [ OBJECT-COMPUTER. Execution-Computer-Specification . ]
   ~~~~~~~~~~~~~~~
 [ SPECIAL-NAMES.   Program-Configuration-Specification . ]
   ~~~~~~~~~~~~~
 [ REPOSITORY.      Function-Specification... . ]
   ~~~~~~~~~~

Этот раздел определяет компьютерную систему, на которой компилируется и выполняется программа, а также указывает любые специальные характеристики конфигурации среды или совместимости.

  1. Четыре абзаца в этом разделе могут быть указаны в любом порядке, но если не в этом порядке, будет выведено предупреждение.
  2. Раздел конфигурации не разрешён во вложенных подпрограммах. Вложенная программа наследует настройки раздела конфигурации своей родительской программы.
  3. Если ни одна из функций, предоставляемых разделом конфигурации, не требуется программой, сам заголовок CONFIGURATION SECTION. может быть опущен из программы.

5.1.1. SOURCE-COMPUTER

Синтаксис SOURCE-COMPUTER

 SOURCE-COMPUTER. computer-name [ WITH DEBUGGING MODE ] .
 ~~~~~~~~~~~~~~~                       ~~~~~~~~~ ~~~~

Этот абзац определяет компьютер, на котором компилируется программа, и предоставляет один способ активации отладочного кода, встроенного в программу.

  1. Зарезервированное слово WITH является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Этот абзац не разрешен во вложенной подпрограмме. Вложенная программа наследует настройки SOURCE-COMPUTER родительской программы.
  3. Значение, указанное для computer-name, не имеет значения, при условии, что это действительное слово COBOL, которое не совпадает ни с одним зарезервированным словом GnuCOBOL. Значение computer-name может содержать пробелы. Это необязательно должно совпадать со значением computer-name, используемым в абзаце OBJECT-COMPUTER, если таковой имеется.
  4. Оператор DEBUGGING MODE, если он присутствует, информирует компилятор о том, что строки отладки (те, у которых в 7-м столбце есть ‘D’ в режиме фиксированного исходного кода или те, которые начинаются с >>D в режиме свободного исходного кода) — обычно обрабатываемые как комментарии — должны быть скомпилированы.
  5. Даже без оператора DEBUGGING MODE, строки отладки по-прежнему можно скомпилировать. Строки отладки также можно скомпилировать, указав переключатель -fdebugging-line компилятору GnuCOBOL.

5.1.2. ОБЪЕКТ-КОМПЬЮТЕР

Синтаксис ОБЪЕКТ-КОМПЬЮТЕР

 OBJECT-COMPUTER.  [ computer-name ]
 ~~~~~~~~~~~~~~~
 [ MEMORY SIZE IS integer-1 WORDS|CHARACTERS ]
   ~~~~~~ ~~~~              ~~~~~ ~~~~~~~~~~
 [ PROGRAM COLLATING SEQUENCE IS alphabet-name-1 ]
           ~~~~~~~~~
 [ SEGMENT-LIMIT IS integer-2 ]
   ~~~~~~~~~~~~~
 [ CHARACTER CLASSIFICATION IS { locale-name-1  } ]
             ~~~~~~~~~~~~~~    { LOCALE         }
                               { ~~~~~~         }
                               { USER-DEFAULT   }
                               { ~~~~~~~~~~~~   }
                               { SYSTEM-DEFAULT }
                                 ~~~~~~~~~~~~~~
 .

Операторы MEMORY SIZE и SEGMENT-LIMIT синтаксически распознаются, но в остальном не функциональны.

Этот абзац описывает компьютер, на котором будет выполняться программа.

  1. computer-name, если указано, должен следовать непосредственно за именем абзаца OBJECT-COMPUTER. Остальные операторы могут быть записаны в любом порядке.
  2. Зарезервированные слова CHARACTER, IS, PROGRAM и SEQUENCE являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  3. Значение, указанное для computer-name, если оно есть, не имеет значения, при условии, что это действительное слово COBOL, которое не совпадает ни с одним зарезервированным словом GnuCOBOL. computer-name может содержать пробелы. Это необязательно должно совпадать со значением computer-name, используемым в абзаце SOURCE-COMPUTER, если таковой имеется.
  4. Абзац OBJECT-COMPUTER не разрешен во вложенной подпрограмме. Вложенная программа наследует настройки OBJECT-COMPUTER родительской программы.
  5. Оператор COLLATING SEQUENCE позволяет указать настроенную последовательность сортировки символов для сравнения алфавитно-цифровых значений. Данные всё равно будут храниться в нативном наборе символов компьютера, но логическая последовательность упорядочения символов для целей сравнения может быть изменена по сравнению с определённой нативным набором символов компьютера. alphabet-name-1, который вы указываете, должен быть определён в абзаце SPECIAL-NAMES (см. SPECIAL-NAMES).
  6. Если не указан оператор COLLATING SEQUENCE, будет использоваться последовательность сортировки, подразумеваемая нативным набором символов компьютера (обычно ASCII).
  7. Необязательный оператор CLASSIFICATION может быть использован для указания локали для среды выполнения программы, чтобы повлиять на сопоставление прописных и строчных букв символов для функций UPPER-CASE (см. UPPER-CASE) и LOWER-CASE (см. LOWER-CASE) и классификации символов для проверок класса ALPHABETIC, ALPHABETIC-LOWER и ALPHABETIC-UPPER. Определения этих классов взяты из спецификации культурных соглашений (LC_CTYPE) из указанной локали.

    Значения четырёх спецификаций локали следующие:

    1. locale-name-1 ссылается на определение LOCALE (см. SPECIAL-NAMES).
    2. Ключевое слово LOCALE относится к текущей локали (действующей в момент выполнения программы)
    3. Ключевое слово USER-DEFAULT относится к локали по умолчанию, указанной для пользователя, выполняющего эту программу.
    4. Ключевое слово SYSTEM-DEFAULT обозначает локаль по умолчанию, указанную для компьютера, на котором выполняется программа.
  8. Отсутствие оператора CLASSIFICATION приведет к классификации символов в соответствии с правилами нативного набора символов компьютера (ASCII, EBCDIC и т. д.).

5.1.3. SPECIAL-NAMES

Синтаксис SPECIAL-NAMES

 SPECIAL-NAMES.
 ~~~~~~~~~~~~~
  [ CALL-CONVENTION integer-1 IS mnemonic-name-1 ]
    ~~~~~~~~~~~~~~~
  [ CONSOLE IS CRT ]
    ~~~~~~~    ~~~
  [ CRT STATUS IS identifier-1 ]
    ~~~ ~~~~~~
  [ CURRENCY SIGN IS literal-1 ]
    ~~~~~~~~ ~~~~
  [ CURSOR IS identifier-2 ]
    ~~~~~~
  [ DECIMAL-POINT IS COMMA ]
    ~~~~~~~~~~~~~    ~~~~~
  [ EVENT STATUS IS identifier-3 ]
    ~~~~~ ~~~~~~
  [ LOCALE locale-name-1 IS literal-2 ]...
    ~~~~~~
  [ NUMERIC SIGN IS TRAILING SEPARATE ]
    ~~~~~~~ ~~~~    ~~~~~~~~ ~~~~~~~~
  [ SCREEN CONTROL IS identifier-4 ]
    ~~~~~~ ~~~~~~~
  [ device-name-1 IS mnemonic-name-2 ]...

  [ feature-name-1 IS mnemonic-name-3 ]...

  [ Alphabet-Clause ]...

  [ Class-Definition-Clause ]...

  [ Switch-Definition-Clause ]...

  [ Symbolic-Characters-Clause ]...
  .

Операторы EVENT STATUS и SCREEN CONTROL синтаксически распознаются, но в остальном не функциональны.

Alphabet-Name-Clause, Class-Definition-Clause,
Switch-Definition-Clause и Symbolic-Characters-Clause
подробно обсуждаются в следующих четырёх разделах.

Абзац SPECIAL-NAMES предоставляет способ указания различных параметров конфигурации программы и операционной среды.

  1. Различные пункты, которые могут быть указаны в параграфе SPECIAL-NAMES, могут быть закодированы в любом порядке.
  2. Зарезервированное слово IS является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  3. Параграф SPECIAL-NAMES не допускается во вложенной подпрограмме. Вложенная программа наследует настройки SPECIAL-NAMES своей родительской программы.
  4. Только заключительный пункт, указанный в этом параграфе, должен заканчиваться точкой.
  5. Пункт CALL-CONVENTION позволяет связать десятичное целое число, представляющее серию установок переключателей ВКЛ/ВЫКЛ, со смысловым именем, которое затем можно закодировать в операторе CALL (см. CALL). Установки переключателей, определенные этим смысловым именем, затем будут контролировать, как будет обрабатываться связь с подпрограммой, вызванной оператором CALL, который ссылается на mnemonic-name-1.
  6. Пункт CONSOLE IS CRT, если указан, заставит оператор DISPLAY, у которого отсутствует явный пункт UPON, быть обработанным как оператор DISPLAY screen-data-item (см. DISPLAY screen-data-item), а любой оператор ACCEPT, у которого отсутствует пункт FROM, быть обработанным как оператор ACCEPT screen-data-item (см. ACCEPT screen-data-item).
  7. Если пункт CRT STATUS не указан, будет выделен неявный идентификатор COB-CRT-STATUS (со PICTURE 9(4)) для получения статусов экрана ACCEPT. Если CRT STATUS указан, то identifier-1 должен быть определен в программе как поле PICTURE 9(4).
  8. Пункт CURRENCY SIGN может быть использован для переопределения символа, используемого в качестве знака валюты в пункте PICTURE (см. PICTURE). Знак валюты по умолчанию – знак доллара (‘$’). Вы можете указать любой символ, *кроме* 0-9, A-Z, a-z, +, -, ,, ., *, /, ;, (, ), =, \\, кавычки (‘"’) или пробела.
  9. Пункт CURSOR IS позволяет указать элемент данных из 4 или 6 символов, в который будет помещено положение курсора на экране в момент удовлетворения запроса экрана ACCEPT. Значение будет возвращено как *rrcc* или *rrrccc*, в зависимости от длины указанного identifier-2, где *rr* и *rrr* представляют номер строки (начиная с нуля), а *cc* и *ccc* – номер столбца (также начиная с нуля). Если пункт CURSOR IS не указан, то выделенный элемент данных для этого нет, и программисту необходимо определить identifier-2, если этот пункт указан.
  10. Пункт DECIMAL POINT IS COMMA меняет определение символов ‘,’ и ‘.’ при использовании их как символов редактирования PICTURE и в числовых литералах. Это может иметь нежелательные последствия – см. Punctuation.
  11. Пункт LOCALE может быть использован для связывания внешних названий локалей, определенных ОС (literal-2), с внутренним именем (locale-name-1), которое затем может быть использовано в программе. Имена локалей определяются операционной системой и/или компилятором C, который будет использоваться GnuCOBOL на вашем компьютере.
  1. Ниже приведен список возможных кодов локали, например, доступных на компьютере Windows, на котором запущена версия GnuCOBOL, скомпилированная с использованием эмулятора Unix MinGW и компилятора GNU C (gcc):
    А

    af_ZA, am_ET, ar_AE, ar_BH, ar_DZ, ar_EG, ar_IQ, ar_JO, ar_KW, ar_LB, ar_LY, ar_MA, ar_OM, ar_QA, ar_SA, ar-SY, ar_TN, ar_YE, arn_CL, as_IN, az_Cyrl_AZ, az_Latn_AZ

    Б

    ba_R, be_BY, bg_BG, bn_IN bo_BT, bo_CN, br_FR, bs_Cyrl_BA, bs_Latn_BA

    В

    ca_ES, cs_CZ, cy_GB

    Г

    da_DK, de_AT, de_CH, de_DE, de_LI, de_LU, dsb_DE, dv_MV

    Д

    el_GR, en_029, en_AU, en_BZ, en_CA, en_GB, en_IE, en_IN, en_JM, en_MY en_NZ, en_PH, en_SG, en_TT, en_US, en_ZA, en_ZW, es_AR, es_BO, es_CL, es_CO, es_CR, es_DO, es_EC, es_ES, es_GT, es_HN, es_MX, es_NI, es_PA, es_PE, es_PR, es_PY, es_SV, es_US, es_UY es_VE, et_EE, eu_ES

    Е

    fa_IR, fi_FI, fil_PH, fo_FO, fr_BE, fr_CA, fr_CH, fr_FR, fr_LU, fr_MC, fy_NL

    Ж

    ga_IE, gbz_AF, gl_ES, gsw_FR, gu_IN

    З

    ha_Latn_NG, he_IL, hi_IN, hr_BA, hr_HR, hu_HU, hy_AM

    И

    id_ID, ig_NG, ii_CN, is_IS, it_CH, it_IT, iu_Cans_CA, iu_Latn_CA

    К

    ja_JP

    Л

    ka_GE, kh_KH, kk_KZ, kl_GL, kn_IN, ko_KR, kok_IN, ky_KG

    М

    lb_LU, lo_LA, lt_LT, lv_LV

    Н

    mi_NZ, mk_MK, ml_IN, mn_Cyrl_MN, mn_Mong_CN moh_CA, mr_IN, ms_BN, ms_MY, mt_MT

    О

    nb_NO, ne_NP, nl_BE, nl_NL, nn_NO, ns_ZA

    П

    oc_FR, or_IN

    Р

    pa_IN, pl_PL, ps_AF, pt_BR, pt_PT

    С

    qut_GT, quz_BO, quz_EC, quz_PE

    Т

    rm_CH, ro_RO, ru_RU, rw_RW

    У

    sa_IN, sah_RU, se_FI, se_NO se_SE, si_LK, sk_SK, sl_SI, sma_NO, sma_SE, smj_NO, smj_SE, smn_FI, sms_FI, sq_AL, sr_Cyrl_BA, sr_Cyrl_CS, sr_Latn_BA, sr_Latn_CS, sv_FI, sv_SE, sw_KE syr_SY

    Ф

    ta_IN, te_IN, tg_Cyrl_TJ, th_TH tk_TM, tmz_Latn_DZ, tn_ZA, tr_IN, tr_TR, tt_RU

    Х

    ug_CN, uk_UA, ur_PK, uz_Cyrl_UZ, uz_Latn_UZ

    Ц

    vi_VN

    Ч

    wen_DE, wo_SN

    Ш

    xh_ZA

    Щ

    yo_NG

    З

    zh_CN, zh_HK, zh_MO, zh_SG, zh_TW, zu_ZA

  2. Указание NUMERIC SIGN TRAILING SEPARATE вызывает создание всех подписанных числовых USAGE DISPLAY элементов данных так, как если бы в их определениях была включена фраза SIGN IS TRAILING SEPARATE CHARACTER.
  3. Фраза device-name-1 IS mnemonic-name-2 позволяет указать альтернативное имя (device-name-1) для одного из встроенных имен устройств GnuCOBOL mnemonic-name-2. Список имен устройств, встроенных в GnuCOBOL, и физическое устройство, связанное с этим именем, следующие:
    CONSOLE

    Это (режим экрана) дисплей ПК или системы Unix.

    STDIN
    SYSIN
    SYSIPT

    Эти устройства (они все являются синонимами) представляют стандартный ввод системы (поток 0). В системе PC или UNIX это обычно клавиатура. Содержимое файла может быть передано программе GnuCOBOL для доступа через одно из этих имен устройств путем добавления последовательности «0< имя_файла» в конец команды выполнения программы.

    PRINTER
    STDOUT
    SYSLIST
    SYSLST
    SYSOUT

    Эти устройства (они все являются синонимами) представляют стандартный вывод системы (поток 1). В системе PC или UNIX это обычно дисплей. Вывод, отправленный одному из этих устройств программой GnuCOBOL, может быть отправлен в файл путем добавления последовательности «1> имя_файла» в конец команды выполнения программы.

    STDERR
    SYSERR

    Эти устройства (они являются синонимами) представляют стандартный вывод ошибок системы (поток 2). В системе PC или UNIX это обычно дисплей. Вывод, отправленный одному из этих устройств программой GnuCOBOL, может быть отправлен в файл путем добавления последовательности «2> имя_файла» в конец команды выполнения программы.

  4. Фраза feature-name-1 IS mnemonic-name-3 позволяет назначать мнемонические имена до 13 позициям каналов принтера (т.е. вертикальное позиционирование страницы) с именами функций Cnn (nn=01-12) и CSP. После того, как позиции канала получили мнемоническое имя, можно записать указанный печатный документ в позиции канала, назначенного mnemonic-name-3 , используя оператор WRITE record-name AFTER ADVANCING mnemonic-name-3.

    Принтеры, поддерживающие позиционирование каналов, обычно являются принтерами типа мэйнфреймов. При записи на принтеры, не поддерживающие позиционирование каналов, будет выдан управляющий символ перехода на новую страницу.

    Опция позиционирования CSP означает «без пробелов». Тестирование на сборке MinGW GnuCOBOL показывает, что это также приводит к выводу управляющего символа перехода на новую страницу.

5.1.3.1. Оператор_имени_алфавита

Синтаксис_оператор_спец_имен_Алфавит

 ALPHABET alphabet-name-1 IS { ASCII             }
 ~~~~~~~~                    { ~~~~~             }
                             { EBCDIC            }
                             { ~~~~~~            }
                             { NATIVE            }
                             { ~~~~~~            }
                             { STANDARD-1        }
                             { ~~~~~~~~~~        }
                             { STANDARD-2        }
                             { ~~~~~~~~~~        }
                             { Literal-Clause... }

Синтаксис_оператор_спец_имен_Алфавит_буквальный

 literal-1 [ { THRU|THROUGH literal-2 } ]
             { ~~~~ ~~~~~~~           }
             { {ALSO literal-3}...    }
                ~~~~

Оператор ALPHABET связывает alphabet-name-1 со специфицированным набором символов или порядком сортировки, включая набор, определённый вами с помощью опции literal-1.

  1. Зарезервированное слово IS является необязательным и может быть опущено. Наличие или отсутствие этого слова не оказывает влияния на программу.
  2. Зарезервированные слова THRU и THROUGH взаимозаменяемы.
  3. GnuCOBOL считает ASCII, STANDARD-1 и STANDARD-2 взаимозаменяемыми.
  4. NATIVE указывает системный набор символов по умолчанию.
  5. Следующие пункты относятся к использованию спецификаций literal-n для составления настраиваемого набора символов:
    1. Значения literal-n являются либо целыми числами, либо буквенно-цифровыми символами в кавычках. Они представляют собой отдельный символ в наборе символов NATIVE, либо по фактическому текстовому значению (буквенно-цифровой символ в кавычках), либо по порядковому номеру в наборе символов NATIVE (целое число).
    2. Последовательность определения символов в этом операторе определяет относительный порядок этих символов при сравнениях с использованием этого алфавита.
    3. Позиции символов в этом списке не влияют на фактические значения двоичного представления символов. Двоичные значения всё равно будут теми, что соответствуют набору символов NATIVE.
    4. Вы можете указать любые из фигуративных констант SPACE, SPACES, ZERO, ZEROS, ZEROES, QUOTE, QUOTES, HIGH-VALUE, HIGH-VALUES, LOW-VALUE или LOW-VALUES для любых спецификаций literal-1, literal-2 или literal-3.
  6. После определения имени алфавита это имя может быть использовано в спецификациях в CODE-SET, COLLATING SEQUENCE, или SYMBOLIC CHARACTERS операторах в другой части программы.

5.1.3.2. Оператор определения класса

Синтаксис оператора определения класса SPECIAL-NAMES

 CLASS class-name-1 IS { literal-1 [ THRU|THROUGH literal-2 ] }...
 ~~~~~                               ~~~~ ~~~~~~~
  1. Зарезервированное слово IS является необязательным и может быть опущено. Наличие или отсутствие этого слова не оказывает влияния на программу.
  2. Зарезервированные слова THRU и THROUGH взаимозаменяемы.
  3. И literal-1, и literal-2 должны быть буквенно-цифровыми литералами длиной 1.
  4. Литерал(ы), указанные в этом операторе, определяют возможные символы, которые могут быть найдены в значении элемента данных, чтобы считаться частью класса.
  5. Например, следующее определяет класс под названием Hexadecimal, определение которого указывает единственные символы, которые могут присутствовать в буквенно-цифровом элементе данных, если этот элемент данных должен быть частью класса Hexadecimal:
    CLASS Hexadecimal IS '0' THRU '9'
                         'A' THRU 'F'
                         'a' THRU 'f'
    
  6. После определения класса Hexadecimal, код программы может использовать оператор, такой как IF input-item IS Hexadecimal, чтобы определить, являются ли значения символов в элементе данных допустимыми в соответствии с этим классом.

5.1.3.3. Оператор определения переключателя

Синтаксис оператора определения переключателя SPECIAL-NAMES

 switch-name-1 [ IS mnemonic-name-1 ]

   [ ON STATUS IS condition-name-1 ]
     ~~
   [ OFF STATUS IS condition-name-2 ]
     ~~~

Оператор определения переключателя связывает имя условия с переключателем исполнения во время выполнения, чтобы статус этого переключателя мог быть проверен в программе.

  1. Зарезервированные слова IS и STATUS являются необязательными и могут быть опушены. Наличие или отсутствие этих слов не оказывает влияния на программу.
  2. Допустимые имена switch-name-1 — это SWITCH-n (n = 0-36).
  3. Если программа компилируется с переключателем -fsyntax-extension, имена переключателей SWn (n = 0-15) также являются допустимыми; они соответствуют SWITCH-0 через SWITCH-15, а также SWITCH-16 через SWITCH-36, SWITCH 0 через SWITCH 26 и SWITCH A через SWITCH Z.
  4. Во время выполнения каждый переключатель будет связан с переменной среды выполнения COB_SWITCH_n, где n будет иметь значение ‘0’ до ‘15’. Любая из этих шестнадцати переменных среды, имеющая значение ON (независимо от регистра), будет считаться установленной «включённой». Любая из этих шестнадцати переменных среды, не имеющая значения или имеющая значение, отличное от ON, будет считаться OFF.
  5. Каждый указанный переключатель должен иметь по крайней мере одну из опций IS mnemonic-name-1, ON STATUS или OFF STATUS, в противном случае не будет способа обратиться к переключателю внутри программы GnuCOBOL.
  6. Синтаксис IS mnemonic-name-1 предоставляет способ установки переключателя в значение ON или OFF через оператор SET (см. SET).
  7. Синтаксис ON STATUS и OFF STATUS предоставляет способ связывания имени условия с включённым или выключенным состоянием переключателя, чтобы статус можно было проверить во время выполнения с помощью оператора IF (см. IF).

5.1.3.4. Оператор символьных символов

Синтаксис оператора символьных символов SPECIAL-NAMES

 SYMBOLIC CHARACTERS
 ~~~~~~~~
   { symbolic-character-1... IS|ARE integer-1... }...

   [ IN alphabet-name-1 ]
     ~~

Этот оператор может быть использован для определения собственных фигуративных констант.

  1. Зарезервированные слова ARE, CHARACTERS и IS являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Должно быть указано ровно столько значений integer-1, сколько существует имён symbolic-character-1.

  3. Каждое имя символического символа будет ассоциировано с соответствующим integer-1-м символом в алфавите, указанном в IN пункте. Значения целых чисел выбирают символы из алфавита по их порядковому положению, а не по их числовому значению; таким образом, целое число 15 выберет 15-й символ в указанном алфавите, независимо от фактического числового значения битового шаблона, составляющего этот символ.
  4. Если alphabet-name-1 не указан, предполагается системная кодовая страница.
  5. Следующие два примера кода определяют один и тот же набор имён фиктивных констант для пяти управляющих символов ASCII (предполагается, что ASCII — это системная кодовая страница). Два примера идентичны по своему действию, хотя способ определения фиктивных констант различен.
    Индивидуально
    SYMBOLIC CHARACTERS NUL IS 1
                        SOH IS 2
                        BEL IS 8
                        DC1 IS 18
                        DC2 IS 19
    
    Соответственно
    SYMBOLIC CHARACTERS NUL SOH BEL DC1 DC2
                    ARE   1   2   8  18  19
    

5.1.4. РЕПОЗИТОРИЙ

Синтаксис РЕПОЗИТОРИЯ

 REPOSITORY.
 ~~~~~~~~~~
    FUNCTION { function-prototype-name-1 [ AS literal-1 ] }...
    ~~~~~~~~ {                             ~~             }
             { intrinsic-function-name-1 [ AS literal-2 ] }
             {                             ~~             }
             { intrinsic-function-name-2 INTRINSIC        }
             { ALL INTRINSIC             ~~~~~~~~~        }
               ~~~ ~~~~~~~~~

Параграф РЕПОЗИТОРИЙ предоставляет способ управления доступом к различным встроенным внутренним функциям и любым пользовательским функциям, которые будет использовать ваша программа.

  1. Параграф REPOSITORY не допускается во вложенной подпрограмме. Вложенная программа наследует настройки REPOSITORY родительской программы.
  2. Оператор INTRINSIC позволяет пометить одну или несколько (или ALL) встроенных внутренних функций как используемые без необходимости кодирования ключевого слова FUNCTION перед именами функций.
  3. В качестве альтернативы использованию оператора ALL INTRINSIC, вы можете скомпилировать свои программы GnuCOBOL, используя переключатель -fintrinsics=ALL.
  4. Параметр function-prototype-name-1 необходим для указания имени пользовательской функции, которую будет использовать ваша программа. Дополнительно, если потребуется, вы можете указать псевдоним, по которому вы будете ссылаться на эту пользовательскую функцию. Если нужно, вы также можете использовать оператор AS для предоставления псевдонима для встроенной внутренней функции.
  5. В следующем примере
    • разрешаются все встроенные функции для указания без использования ключевого слова FUNCTION,
    • называются две пользовательские функции под названием MY-FUNCTION-1 и MY-FUNCTION-2, которые будут использоваться программой, и
    • указываются псевдонимы SIGMA для внутренней функции STANDARD-DEVIATION и MF2 для MY-FUNCTION-2.
    REPOSITORY.
        FUNCTION ALL INTRINSIC.
        FUNCTION MY-FUNCTION-1.
        FUNCTION MY-FUNCTION-2 AS "MF2".
        FUNCTION STANDARD-DEVIATION AS "SIGMA".
    

Замечание о пользовательских функциях — поскольку вам необходимо назвать пользовательскую функцию, которую будет использовать ваша программа в параграфе REPOSITORY, вы всегда можете ссылаться на эту функцию в разделе процедур своей программы без необходимости использования ключевого слова FUNCTION.

5.2. ВВОД-ВЫВОД

Синтаксис ВВОД-ВЫВОД

 [ INPUT-OUTPUT SECTION. ]
   ~~~~~~~~~~~~ ~~~~~~~
 [ FILE-CONTROL. ]
   ~~~~~~~~~~~~
     [ SELECT-Statement... ]

 [ I-O-CONTROL. ]
   ~~~~~~~~~~~
     [ MULTIPLE-FILE-Statement ]

     [ SAME-RECORD-Statement ]

Раздел INPUT-OUTPUT предоставляет определение всех файлов, к которым будет обращаться программа, а также управление буферизацией ВВОД-ВЫВОД для этих файлов посредством параграфов FILE-CONTROL и I-O-CONTROL соответственно.

  1. Как показывает диаграмма, в двух параграфах этого раздела могут встречаться три типа операторов. Если ни один из операторов не закодирован в конкретном параграфе, этот параграф может быть опущен, в противном случае он требуется.
  2. Если ни один параграф не закодирован, заголовок INPUT-OUTPUT SECTION. сам по себе может быть опущен, в противном случае он обычно требуется.
  3. Если в файле конфигурации компилятора (см. Файлы конфигурации компилятора) используется параметр relaxed-syntax-check со значением ‘yes’, параграфы FILE-CONTROL и I-O-CONTROL могут быть указаны без кодирования заголовка INPUT-OUTPUT SECTION.
  4. Если оба типа операторов закодированы в параграфе I-O-CONTROL, порядок их кодирования не имеет значения.

5.2.1. ВЫБОР

Синтаксис оператора ВЫБОР

 SELECT [ [ NOT ] OPTIONAL ] file-name-1
 ~~~~~~     ~~~   ~~~~~~~~
 [ ASSIGN { TO    } [{ EXTERNAL }] [{ DISC|DISK      }] [{ identifier-1 }] ]
   ~~~~~~ { USING }  { ~~~~~~~~ }   { ~~~~ ~~~~      }   { word-1       }
                     { DYNAMIC  }   { DISPLAY        }   { literal-1    }
                       ~~~~~~~      { ~~~~~~~        }
                                    { KEYBOARD       }
                                    { ~~~~~~~~       }
                                    { LINE ADVANCING }
                                    { ~~~~ ~~~~~~~~~ }
                                    { PRINTER        }
                                    { ~~~~~~~        }
                                    { RANDOM         }
                                    { ~~~~~~         }
                                    { TAPE           }
                                      ~~~~
 [ COLLATING SEQUENCE IS alphabet-name-1 ]
   ~~~~~~~~~
 [ FILE|SORT ] STATUS IS identifier-2 [ identifier-3 ] ]
   ~~~~ ~~~~   ~~~~~~
 [ LOCK MODE IS { MANUAL|AUTOMATIC                                } ]
   ~~~~         { ~~~~~~ ~~~~~~~~~                                }
                { EXCLUSIVE [ WITH { LOCK ON MULTIPLE RECORDS } ] }
                  ~~~~~~~~~        { ~~~~ ~~ ~~~~~~~~ ~~~~~~~ }
                                   { LOCK ON RECORD           }
                                   { ~~~~ ~~ ~~~~~~           }
                                   { ROLLBACK                 }
                                   { ~~~~~~~~                 }
 [ ORGANIZATION Clause ]
   ~~~~~~~~~~~~
 [ ORGANISATION Clause ]
   ~~~~~~~~~~~~
 [ RECORD DELIMITER IS STANDARD-1 ]
   ~~~~~~ ~~~~~~~~~    ~~~~~~~~~~
 [ RESERVE integer-1 AREAS ]
   ~~~~~~~
 [ SHARING WITH { ALL OTHER } ]
   ~~~~~~~      { ~~~       }
                { NO OTHER  }
                { ~~        }
                { READ ONLY }
                  ~~~~ ~~~~

Операторы COLLATING SEQUENCE, RECORD DELIMITER, RESERVE и ALL OTHER синтаксически распознаются, но при этом не выполняют никаких действий.

Оператор SELECT создаёт определение файла и связывает это определение COBOL с внешней операционной средой.

  1. Зарезервированные слова AREAS, IS, MODE, OTHER, SEQUENCE, TO, USING и WITH являются необязательными и могут быть опущены. Их присутствие или отсутствие не влияет на программу.
  2. После file-name-1 различные предложения можно указывать в любом порядке.
  3. После последнего предложения должно стоять точка.
  4. Предложение OPTIONAL, используемое только для файлов, которые будут использоваться для ввода данных в программу, указывает, что файл может или не может быть доступен во время выполнения. Попытки OPEN файла OPTIONAL при отсутствии файла приведут к специальному значению состояния файла (см. статус 05 в списке значений статуса файла ниже), указывающему, что файла нет; последующая попытка READ этого файла вернёт состояние "конец файла" (end-of-file). По желанию файлы могут быть обозначены как NOT OPTIONAL. Это полезно при указании переключателя компилятора -foptional-file, который автоматически делает все файлы OPTIONAL за исключением тех, которые явно объявлены как NOT OPTIONAL.
  5. Значение file-name-1, которое вы укажете, будет именем, с помощью которого вы будете ссылаться на файл в вашей программе. Это имя должно соответствовать правилам для имен, определённых пользователем (см. Пользовательские слова).
  6. Необязательное предложение ASSIGN определяет, как — во время выполнения, когда file-name-1 открывается — будет ассоциирован либо логический прибор (STDIN, STDOUT) либо файл в любой точке одной из смонтированных файловых систем с file-name-1, следующим образом:
    1. Предложение ASSIGN состоит из трёх компонентов:
      Type

      EXTERNAL, DYNAMIC или ни то ни другое

      Device

      список вариантов устройств

      Locator

      представлен как выбор между identifier-1, word-1 и literal-1.

    2. ASSIGN TO DISC file-name-1 будет предположено, если нет предложения ASSIGN в SELECT.
    3. Если предложение ASSIGN записано без Device, будет предполагаться устройство DISC.
    4. Если указано предложение Locator, файл COBOL file-name-1 будет присоединён к файлу данных в любой смонтированной и доступной файловой системе в момент открытия file-name-1. Способ идентификации этого файла зависит от указанного Locator, как показано ниже:
      1. Если указано literal-1, значение литерала послужит строкой расположения файла, которая идентифицирует файл данных.
      2. Если указано identifier-1, значение идентификатора послужит строкой расположения файла, которая идентифицирует файл данных.
      3. Если указано word-1 (синтаксически допустимое слово, не дублирующее зарезервированное или пользовательское слово), и Type имеет значение EXTERNAL, то само word-1 послужит строкой расположения файла, которая идентифицирует файл данных. Однако, если Type не указан, компилятор создаст элемент данных PIC X(1024) с именем word-1 в программе; содержимое этого элемента данных в момент открытия программы file-name-1 послужит строкой расположения файла, которая идентифицирует файл данных.
      4. Строки расположения файлов будут рассмотрены вскоре.
    5. Если предложение Locator не указано, file-name-1 будет присоединён к логическому устройству или файлу на основе указанного (или предполагаемого) Device, как показано ниже:
      1. DISC или DISK предполагают присоединение к файлу с именем file-name-1 в текущей директории в момент открытия файла.
      2. DISPLAY предполагает присоединение к логическому устройству STDOUT; эти файлы следует использовать только для вывода.
      3. KEYBOARD предполагает присоединение к логическому устройству STDIN; эти файлы следует использовать только для ввода.
      4. PRINTER предполагает присоединение к логическому устройству/порту LPT1; эти файлы следует использовать только для вывода.
      5. RANDOM или TAPE ведут себя точно так же, как и DISC. Эти два дополнительных Device предоставляются для облегчения компиляции исходного кода COBOL из других реализаций COBOL.
    6. Устройство LINE ADVANCING требует указания Locator; эти файлы следует использовать только для вывода. Файл COBOL с продвижением строк позволит писать символы управления переводом строки, такие как символы перевода строки и перевода страницы, в присоединённый файл операционной системы через предложение ADVANCING оператора WRITE (см. WRITE).
    7. Строки расположения файлов используются (во время выполнения) для идентификации пути и имени файла данных, который должен быть присоединён к file-name-1 при открытии этого файла.
    1. Если в файле конфигурации компилятора (см. Файлы конфигурации компилятора) для компиляции программы было задано значение filename-mapping, равное yes, система выполнения GnuCOBOL сначала попытается определить текущую переменную среды, значение которой будет использоваться в качестве пути и имени файла данных, следующим образом:
      1. Если в файле конфигурации компилятора (см. Файлы конфигурации компилятора) (см. Файлы конфигурации компилятора) для компиляции программы было задано значение mf в качестве assign-clause, то строка поиска файла будет интерпретироваться в соответствии с правилами Microfocus COBOL — а именно, всё перед последним символом «-» в строке поиска файла будет проигнорировано; символы после последнего «-» будут рассматриваться как основа имени переменной среды. Если символ «-» отсутствует в строке поиска файла, вся строка поиска файла будет служить основой имени переменной среды. Это поведение по умолчанию для каждого файла конфигурации, кроме ibm.
      2. Если же в файле конфигурации компилятора (см. Файлы конфигурации компилятора) для компиляции программы было задано значение mf в качестве assign-clause, то строка поиска файла будет интерпретироваться в соответствии с правилами IBM COBOL — а именно, ожидается, что строка поиска файла будет иметь вид S-xxx или AS-xxx, в этом случае xxx будет рассматриваться как основа имени переменной среды. Если символ «-» отсутствует в строке поиска файла, вся строка поиска файла будет служить основой имени переменной среды.
      3. После определения основы имени переменной среды (назовём её bbbb), система выполнения будет искать первую из следующих переменных среды, которая существует в указанном порядке:
        DD_bbbb
        dd_bbbb
        bbbb
        

        В системах Windows регистр переменных среды не учитывается, поэтому при использовании реализации GnuCOBOL, созданной для Windows/MinGW или нативной Windows, нет разницы между первыми двумя.

        Если переменная среды найдена, её значение будет использоваться в качестве пути и имени файла данных.

    2. Если переменная среды не найдена или в файле конфигурации компилятора (см. Файлы конфигурации компилятора), используемом для компиляции программы, значение filename-mapping равно NO, тогда значение строки поиска файла будет использоваться в качестве пути и имени файла данных.
    3. Пути и имена файлов могут быть указаны на абсолютной (C:\\Data\\datafile.dat, /Data/datafile.dat, …) или относительной (Data\\datafile.dat, Data/datafile.dat, …) к текущей директории основе. Если имя директории не указано (datafile.dat), файл должен находиться в текущей директории.
  1. Оператор FILE STATUS или SORT STATUS (они эквивалентны и только один из них, если нужно, должен быть указан) используется для указания имени двузначного числового элемента данных, в который будет сохранён код состояния ввода-вывода после выполнения любой команды ввода-вывода для файла. Это не приводит к фактическому выделению элемента данных — вы должны определить его самостоятельно в разделе данных. Обратите внимание, что следующий список не является исчерпывающим: можно добавить больше элементов, а все тесты должны включать проверку на значения, отличные от нуля, как общий случай. Возможные коды состояния, которые могут быть возвращены в элемент данных FILE STATUS, следующие:
    00

    Успех

    02

    Успех (запись с дублирующим ключом)

    04

    Успех (неполный)

    05

    Успех (необязательный файл не найден)

    07

    Успех (нет устройства)

    10

    Достигнут конец файла при чтении вперёд или начало файла при чтении назад

    14

    Выход за пределы диапазона ключа

    21

    Неверный ключ

    22

    Ключ уже существует

    23

    Ключ не найден

    24

    Нарушение границ ключа

    30

    Постоянная ошибка ввода-вывода

    31

    Несогласованное имя файла

    34

    Нарушение границ

    35

    Файл не найден

    37

    Доступ запрещён

    38

    Закрыто с блокировкой

    39

    Конфликт атрибутов

    41

    Файл уже открыт

    42

    Файл не открыт

    43

    Чтение не завершено

    44

    Переполнение записи

    46

    Ошибка чтения

    47

    Доступ OPEN INPUT запрещён (недостаточно прав для чтения файла)

    48

    Доступ OPEN OUTPUT запрещён (недостаточно прав для записи в файл)

    49

    Доступ OPEN I-O запрещён (недостаточно прав для чтения и/или записи файла)

    51

    Запись заблокирована

    52

    Конец страницы

    57

    LINAGE некорректное описание (строка ввода-вывода)

    61

    Ошибка совместного использования файла

    71

    Неверный символ

    91

    Файл недоступен

  2. Оператор SHARING определяет условия, при которых программа позволит другим программам, выполняющимся одновременно, получить доступ к файлу. Подробности см. в разделе File Sharing.
  3. Оператор LOCK определяет, как будет управляться одновременный доступ к файлу на уровне каждой записи. Подробности см. в разделе Record Locking.
  4. Подробности синтаксиса оператора ORGANIZATION см. в следующих параграфах.
  5. Оператор SELECT без явно указанного оператора ORGANIZATION будет обрабатываться так, как будто указан следующий оператор ORGANIZATION:
    ORGANIZATION IS SEQUENTIAL
    ACCESS MODE IS SEQUENTIAL
    

5.2.1.1. ORGANIZATION SEQUENTIAL

ORGANIZATION SEQUENTIAL Clause Syntax

 [ ORGANIZATION|ORGANISATION IS ] RECORD BINARY SEQUENTIAL
   ~~~~~~~~~~~~ ~~~~~~~~~~~~                    ~~~~~~~~~~
    [ ACCESS MODE IS SEQUENTIAL ]
      ~~~~~~         ~~~~~~~~~~

Файлы, объявленные как ORGANIZATION SEQUENTIAL, будут содержать записи без явного разделителя конца записи; записи в таких файлах «определяются» вычисленным смещением байтов (на основе максимальной длины записи) в файле.

  1. Зарезервированные слова BINARY, IS, MODE и RECORD являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированные слова ORGANIZATION и ORGANISATION взаимозаменяемы.
  3. Фраза ORGANIZATION IS (и её интернационализированный аналог ORGANISATION IS) является необязательной для обеспечения совместимости с теми (несколькими) реализациями COBOL, которые считают ORGANIZATION необязательным. Большинство реализаций COBOL требуют слова ORGANIZATION, поэтому его следует использовать в новых программах.
  4. Эти файлы нельзя подготовить с помощью стандартных текстовых редакторов или программ для обработки текста, так как все такие программы будут вставлять разделительные символы в конце записей (используйте ORGANIZATION IS LINE SEQUENTIAL вместо этого).
  5. Эти файлы могут содержать данные типа USAGE DISPLAY или USAGE COMPUTATIONAL (любой разновидности), так как никакая последовательность двоичных данных не может быть случайно интерпретирована как разделитель конца записи.
  6. Хотя записи в файле ORGANIZATION SEQUENTIAL могут быть определены как имеющие переменную длину, файл будет структурирован таким образом, чтобы зарезервировать место для каждой записи, равное размеру самой большой возможной записи, исходя из описания файла в FILE SECTION.
  7. Оператор ACCESS MODE SEQUENTIAL является необязательным, потому что в случае его отсутствия он всё равно подразумевается для этого типа файлов. Внутренняя структура этих файлов такова, что они могут обрабатываться только последовательно; например, для чтения 100-й записи в таком файле сначала необходимо прочитать записи с 1 по 99.
  8. Последовательные файлы обрабатываются с помощью следующих операторов:
    • CLOSE (см. CLOSE)
    • COMMIT (см. COMMIT)
    • DELETE (см. DELETE)
    • MERGE (см. MERGE)
    • OPEN (см. OPEN)
    • READ (см. READ)
    • REWRITE (см. REWRITE)
    • SORT (см. SORT)
    • UNLOCK (см. UNLOCK)
    • WRITE (см. WRITE)

5.2.1.2. ОРГАНИЗАЦИЯ ПО СТРОКАМ ПОСЛЕДОВАТЕЛЬНО

Синтаксис предложения ORGANIZATION LINE SEQUENTIAL

 [ ORGANIZATION|ORGANISATION IS ] LINE SEQUENTIAL
   ~~~~~~~~~~~~ ~~~~~~~~~~~~      ~~~~ ~~~~~~~~~~
    [ ACCESS MODE IS SEQUENTIAL ]
      ~~~~~~         ~~~~~~~~~~
    [ PADDING CHARACTER IS literal-1 | identifier-1 ]
      ~~~~~~~

Предложение PADDING CHARACTER синтаксически распознаётся, но в остальном не функционально.

Файлы, объявленные как ORGANIZATION LINE SEQUENTIAL, будут состоять из записей, завершённых символом или последовательностью символов конца записи.

  1. Зарезервированные слова CHARACTER, IS и MODE являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированные слова ORGANIZATION и ORGANISATION взаимозаменяемы.
  3. Фраза ORGANIZATION IS (и её интернационализированный аналог ORGANISATION IS) является необязательной для обеспечения совместимости с теми (несколькими) реализациями COBOL, которые считают это слово необязательным. Большинство реализаций COBOL требуют слова ORGANIZATION, поэтому его следует использовать в новых программах.
  4. Это единственный ORGANIZATION допустимый для файлов, назначенных на устройство PRINTER.
  5. Эти файлы могут быть созданы с помощью любого стандартного текстового редактора или программы для обработки текста, способной создавать текстовые файлы. Такие файлы не должны содержать данные типа USAGE COMPUTATIONAL или BINARY (любой разновидности), так как такие поля могут случайно содержать последовательности байтов, которые могут быть интерпретированы как разделитель конца записи.
  6. Поддерживаются форматы записей с фиксированной и переменной длиной.
  7. Последовательность разделителей конца записи будет X‘0A’ (символ ASCII перевода строки) или X‘0D0A’ (последовательность ASCII возврата каретки + перевода строки). Первый вариант используется в реализациях GnuCOBOL на Unix (включая Windows/MinGW, Windows/Cygwin и OSX), а второй - в родных реализациях Windows.
  8. При чтении файла LINE SEQUENTIAL, записи, превышающие размер, подразумеваемый описанием файла в FILE SECTION, будут усечены, а записи, короче этого размера, будут дополнены справа SPACES.
  9. Предложение ACCESS MODE SEQUENTIAL является необязательным, так как в случае его отсутствия оно предполагается для этого типа файла. Внутренняя структура этих файлов такова, что данные могут обрабатываться только последовательно; например, для чтения 100-й записи в таком файле сначала необходимо прочитать записи с 1 по 99.
  10. Файлы, назначенные на устройства PRINTER или CONSOLE, должны быть указаны как ORGANIZATION LINE SEQUENTIAL.
  11. Файлы ORGANIZATION LINE SEQUENTIAL обрабатываются с помощью следующих операторов:
    • CLOSE (см. CLOSE)
    • COMMIT (см. COMMIT)
    • DELETE (см. DELETE)
    • MERGE (см. MERGE)
    • OPEN (см. OPEN)
    • READ (см. READ)
    • REWRITE (см. REWRITE)
    • SORT (см. SORT)
    • UNLOCK (см. UNLOCK)
    • WRITE (см. WRITE)

5.2.1.3. Относительная организация

Синтаксис оператора ORGANIZATION RELATIVE

 [ ORGANIZATION|ORGANISATION IS ] RELATIVE
   ~~~~~~~~~~~~ ~~~~~~~~~~~~      ~~~~~~~~
    [ ACCESS MODE IS { SEQUENTIAL } ]
      ~~~~~~         { ~~~~~~~~~~ }
                     { DYNAMIC    }
                     { ~~~~~~~    }
                     { RANDOM     }
                       ~~~~~~
    [ RELATIVE KEY IS identifier-1 ]
      ~~~~~~~~

Эти файлы имеют внутреннюю организацию, позволяющую обрабатывать записи последовательно, основываясь на их физическом расположении в файле, или случайным образом, позволяя читать, записывать или обновлять записи, указывая относительный номер записи в файле.

  1. Зарезервированные слова IS, KEY и MODE являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированные слова ORGANIZATION и ORGANISATION взаимозаменяемы.
  3. Фраза ORGANIZATION IS (и её международная альтернатива ORGANISATION IS) является необязательной для обеспечения совместимости с теми (немногими) реализациями COBOL, которые считают это слово необязательным. Большинство реализаций COBOL требуют слова ORGANIZATION, поэтому его следует использовать в новых программах.
  4. Файлы с организацией ORGANIZATION RELATIVE не могут быть назначены устройствам CONSOLE, DISPLAY, LINE ADVANCING или PRINTER.
  5. Оператор RELATIVE KEY является необязательным только в случае указания ACCESS MODE SEQUENTIAL.
  6. Хотя файл с организацией ORGANIZATION RELATIVE может быть определён как содержащий записи переменной длины, файл будет структурирован таким образом, чтобы резервировать место для каждой записи размером, равным размеру самой большой возможной записи, как определено описанием файла в FILE SECTION.
  7. ACCESS MODE SEQUENTIAL, значение по умолчанию для ACCESS MODE, если не указано иное, означает, что записи файла будут обрабатываться последовательно, в соответствии с их физической последовательностью в файле.
  8. ACCESS MODE RANDOM означает, что записи будут обрабатываться в случайном порядке, указав их номер записи в файле каждый раз при чтении или записи файла.
  9. ACCESS MODE DYNAMIC указывает, что программа может переключаться между режимами SEQUENTIAL и RANDOM во время выполнения. Файл первоначально открывается в режиме SEQUENTIAL, но программа может использовать оператор START (см. START), чтобы переключаться между последовательным и случайным доступом.
  10. Данные элемента RELATIVE KEY - это числовой элемент данных, который не может быть определён как поле в записях этого файла. Его назначение — возвращать текущий относительный номер записи относительного файла, который обрабатывается в режиме доступа SEQUENTIAL, и служить ключом для указания относительного номера записи, подлежащей чтению или записи при обработке относительного файла в режиме доступа RANDOM.
  11. Относительные файлы обрабатываются с помощью следующих операторов:
    • CLOSE (см. CLOSE)
    • COMMIT (см. COMMIT)
    • DELETE (см. DELETE)
    • MERGE (см. MERGE), ACCESS MODE RANDOM запрещено
    • OPEN (см. OPEN)
    • READ (см. READ)
    • REWRITE (см. REWRITE)
    • SORT (см. SORT), ACCESS MODE RANDOM запрещено
    • START (см. START)
    • UNLOCK (см. UNLOCK)
    • WRITE (см. WRITE)

5.2.1.4. Индексированная организация

Синтаксис оператора ORGANIZATION INDEXED

 [ ORGANIZATION|ORGANISATION IS ] INDEXED
   ~~~~~~~~~~~~ ~~~~~~~~~~~~      ~~~~~~~
    [ ACCESS MODE IS { SEQUENTIAL } ]
      ~~~~~~         { ~~~~~~~~~  }
                     { DYNAMIC    }
                     { ~~~~~~~    }
                     { RANDOM     }
                       ~~~~~~
    [ RECORD KEY IS { [ data-name-1       ]
      ~~~~~~
                    { [ record-key-name-1 ]
                      [ =|{SOURCE IS} data-name-2 ] ... ] }
                           ~~~~~~
    [ ALTERNATE RECORD KEY IS { [ data-name-3       ]
      ~~~~~~~~~ ~~~~~~
                              { [ record-key-name-2 ]
                                [ =|{SOURCE IS} data-name-4 ] ... ] }
                                     ~~~~~~
                              [ WITH DUPLICATES ] ]...
                                     ~~~~~~~~~~
                              [ SUPPRESS WHEN ALL literal     ]
                                ~~~~~~~~~~~~~~~~~
                              [ SUPPRESS WHEN SPACES | ZEROES ]
                                ~~~~~~~~~~~~~~~~~~~~   ~~~~~~

Файлы с индексированной организацией, как и файлы с относительной организацией, могут иметь записи, обрабатываемые как последовательно, так и случайным образом. Однако в отличие от файлов с относительной организацией, фактическое расположение записи в индексированном файле вычисляется автоматически на основе значения(й) одного или нескольких буквенно-цифровых полей в записях файла. Например, индексированный файл с данными о продуктах может использовать код идентификации продукта в качестве ключа записи. Это означает, что вы можете прочитать, записать или обновить A6G4328-ю запись или Z8X7723-ю запись напрямую, основываясь на значении идентификатора продукта этих записей!

  1. Зарезервированные слова IS, KEY и MODE являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированные слова ORGANIZATION и ORGANISATION взаимозаменяемы.
  3. Фраза ORGANIZATION IS (и ее интернационализированный аналог ORGANISATION IS) необязательна для обеспечения совместимости с теми (немногими) реализациями COBOL, которые считают это слово необязательным. Большинство реализаций COBOL требуют слова ORGANIZATION, поэтому его следует использовать в новых программах.
  4. Файлы ORGANIZATION INDEXED не могут быть назначены CONSOLE, DISPLAY, KEYBOARD, LINE ADVANCING или PRINTER.
  5. ACCESS MODE SEQUENTIAL, значение по умолчанию ACCESS MODE, если не указано иное, указывает, что записи файла будут обрабатываться последовательно относительно значений RECORD KEY или ALTERNATE RECORD KEY, ссылок на них в последнем операторе START (см. START).
  6. ACCESS MODE RANDOM означает, что записи будут обрабатываться в случайном порядке путем доступа к записи со специфическими значениями ключа записи или альтернативного ключа записи.
  7. ACCESS MODE DYNAMIC позволяет обрабатывать файл в режиме RANDOM или SEQUENTIAL; программа может переключаться между этими режимами по мере необходимости. Оператор START используется для переключения между режимами.
  8. Оператор RECORD KEY определяет поле в записи, используемое для основного доступа к записям в файле. Две записи в файле не будут иметь одинакового значения поля PRIMARY KEY. Оператор SOURCE IS используется с Split Keys.
  9. Оператор ALTERNATE RECORD KEY, если используется, определяет дополнительное поле в записи, которое предоставляет альтернативный способ прямого доступа к записям или дополнительное поле, с помощью которого можно последовательно обрабатывать содержимое файла. Вы можете разрешить дублирование значений альтернативных ключей, если необходимо.
  10. Может быть несколько операторов ALTERNATE RECORD KEY, каждый из которых определяет дополнительный альтернативный ключ для файла.
  11. Использование оператора SUPPRESS WHEN используется, когда требуются Sparse Keys, которые могут принимать вид литерала, пробелов или нулей.
  12. Индексированные файлы обрабатываются с помощью следующих операторов:
    • CLOSE (см. CLOSE)
    • COMMIT (см. COMMIT)
    • DELETE (см. DELETE)
    • MERGE (см. MERGE), ACCESS MODE RANDOM не разрешено
    • OPEN (см. OPEN)
    • READ (см. READ)
    • REWRITE (см. REWRITE)
    • SORT (см. SORT), ACCESS MODE RANDOM не разрешено
    • START (см. START)
    • UNLOCK (см. UNLOCK)
    • WRITE (см. WRITE)

5.2.2. ОБЛАСТЬ ОДНОЙ ЗАПИСИ

Синтаксис I/O-УПРАВЛЕНИЯ ОБЛАСТЬЮ ОДНОЙ ЗАПИСИ

 SAME { SORT-MERGE } AREA FOR file-name-1... .
 ~~~~ { ~~~~~~~~~~ }
      { SORT       }
      { ~~~~       }
      { RECORD     }
        ~~~~~~

Операторы SAME SORT-MERGE и SAME SORT синтаксически распознаются, но в противном случае не функциональны.

Оператор SAME RECORD AREA позволяет указать, что несколько файлов должны совместно использовать одни и те же буферы ввода-вывода.

  1. Зарезервированные слова AREA и FOR являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Данный оператор должен быть завершен точкой.
  3. Хотя при кодировании допустим только один имя файла (повторённый элемент file-name-1), этот оператор не повлияет на программу, если не указано по крайней мере два файла.
  4. Данный оператор приведет к тому, что указанные файлы будут совместно использовать один и тот же буфер ввода-вывода в памяти. Эти буферы могут быть довольно большими, и, имея несколько файлов, разделяющих один буфер памяти, вы можете значительно уменьшить количество используемой памяти программой (тем самым освободив "место" для большего кода процедур или данных). Если вы используете эту функцию, позаботьтесь о том, чтобы не более одного из указанных файлов были одновременно открытыми.

5.2.3. НЕСКОЛЬКО ФАЙЛОВ

Синтаксис I/O-УПРАВЛЕНИЯ НЕСКОЛЬКИМИ ФАЙЛАМИ

 MULTIPLE FILE TAPE CONTAINS
 ~~~~~~~~
    { file-name-1 [ POSITION integer-1 ] }...
                    ~~~~~~~~
    .

Оператор MULTIPLE FILE TAPE устарел и поэтому распознается, но не функционален.

6. РАЗДЕЛ ДАННЫХ

Синтаксис РАЗДЕЛА ДАННЫХ

   DATA DIVISION.
   ~~~~ ~~~~~~~~
 [ FILE SECTION.
   ~~~~ ~~~~~~~
   { File/Sort-Description [ { FILE-SECTION-Data-Item } ]... }... ]
   {                         { 01-Level-Constant      }      }
   {                         { 78-Level-Constant      }      }
   { 01-Level-Constant                                       }
   { 78-Level-Constant                                       }
 [ WORKING-STORAGE SECTION.
   ~~~~~~~~~~~~~~~ ~~~~~~~
   [ { WORKING-STORAGE-SECTION-Data-Item } ]... ]
     { 01-Level-Constant                 }
     { 78-Level-Constant                 }
 [ LOCAL-STORAGE SECTION.
   ~~~~~~~~~~~~~ ~~~~~~~
   [ { LOCAL-STORAGE-SECTION-Data-Item } ]... ]
     { 01-Level-Constant               }
     { 78-Level-Constant               }
 [ LINKAGE SECTION.
   ~~~~~~~ ~~~~~~~
   [ { LINKAGE-SECTION-Data-Item } ]... ]
     { 01-Level-Constant         }
     { 78-Level-Constant         }
 [ REPORT SECTION.
   ~~~~~~ ~~~~~~~
   { Report-Description [ { Report-Group-Definition } ]... }... ]
   {                      { 01-Level-Constant       }      }
   {                      { 78-Level-Constant       }      }
   { 01-Level-Constant                                     }
   { 78-Level-Constant                                     }
 [ SCREEN SECTION.
   ~~~~~~ ~~~~~~~
   [ { SCREEN-SECTION-Data-Item } ]... ]
     { 01-Level-Constant        }
     { 78-Level-Constant        }

Все данные, используемые любой программой COBOL, должны быть определены в одном из шести разделов раздела данных в зависимости от назначения данных.

  1. Если данные не будут описаны в одном из разделов раздела данных, заголовок этого раздела можно опустить.
  2. Если разделы раздела данных не нужны, можно опустить сам заголовок DATA DIVISION..
  3. Если в разделе данных требуется более одного раздела (обычная ситуация), разделы должны быть закодированы в порядке, представленном выше.

6.1. Принципы определения данных

Данные элементы GnuCOBOL, как и в других реализациях COBOL, описываются иерархически. Это позволяет разбивать данные элементы на подчиненные элементы. Например, рассмотрим следующую логическую структуру части данных, имеющей имя Employee:

                           Employee
                               |                     Additional
              :----------------:----------------:--> Data Items ...
              |                                 |
        Employee-name                    Employment-Dates
              |                                 |
    :---------:-------------:           :-------:-------:
    |         |             |           |               |
Last-Name First-Name Middle-Initial From-Date        To-Date
                                        |               |
                                   :----:----:     :----:----:
                                   |    |    |     |    |    |
                                 Year Month Day  Year Month Day

Данный элемент Employee состоит из двух подчиненных элементов — элемента Employee-Name и элемента Employment-Dates (вероятно, там будет много других, но нас сейчас они не интересуют). Как показывает диаграмма, каждый из этих элементов, в свою очередь, разбивается на подчиненные элементы. Такая иерархия данных элементов может стать довольно deep, и GnuCOBOL, как и другие реализации COBOL, может обрабатывать до 49 уровней таких иерархических структур.

Как уже говорилось ранее (см. Структурированные данные), элемент данных, разбитый на другие элементы данных, называется групповым элементом, а элемент, который не разбивается, называется элементарным элементом.

COBOL использует понятие уровня для указания уровня, на котором элемент данных находится в структуре данных, как показано в примере выше. При определении этих элементов данных все они определяются вместе с числом в диапазоне от 1 до 49, указанным перед их именами. С течением времени среди программистов COBOL сложилась конвенция, согласно которой номера уровней всегда кодируются двузначными числами — их не обязательно указывать двузначными числами, но во всех примерах в этом документе используется именно такой подход!

Элемент данных на вершине, также называемый записью, всегда имеет номер уровня 01. После этого вы можете назначать номера уровней по своему усмотрению (01–02–03–04…, 01–05–10–15…, и т. д.), соблюдая следующие простые правила:

  1. Каждый элемент данных на одном уровне диаграммы иерархии, такой как та, которую вы видите здесь (если бы вы её создали, что вы редко, если вообще когда-либо, сделаете, после того как освоите эту концепцию), должен иметь одинаковый номер уровня.
  2. Каждый новый уровень использует номер уровня, строго больший, чем номер уровня родительского (следующего выше) уровня.
  3. При описании иерархий данных вы никогда не должны использовать номер уровня, больший 49 (за исключением 66, 77, 78 и 88, которые имеют очень специальное значение (см. Специальные элементы данных).

Таким образом, определение этих элементов данных в программе GnuCOBOL будет примерно таким:

    01  Employee
        05 Employee-Name
           10 Last-Name
           10 First-Name
           10 Middle-Initial
        05 Employment-Dates
           10 From-Date
              15 Year
              15 Month
              15 Day
           10 To-Date
              15 Year
              15 Month
              15 Day

Отступы используются по усмотрению программиста, чтобы упростить чтение для человека (компилятор об этом не беспокоится). Раньше в реализациях COBOL, требующих исходные программы в формате фиксированной ширины, требовалось, чтобы номер уровня 01 начинался в области А, а всё остальное — в области В. В GnuCOBOL требуется только, чтобы весь синтаксис определения данных находился в колонках с 8 по 72. В режиме свободного формата, конечно, таких ограничений нет.

Вы заметили, что определено по два элемента данных Year, Month и Day? Это вполне законно, при условии, что каждый может быть однозначно qualified, чтобы отличаться от другого. Например, элементы Year. Один определен как часть элемента данных From-Date, а другой — как часть элемента данных To-Date. В COBOL мы фактически кодируем ссылки на эти два элемента данных как Year OF From-Date и Year OF To-Date или Year IN From-Date и Year IN To-Date (COBOL разрешает использовать IN или OF). Так как эти ссылки прояснят для нас, к какому элементу Year мы ссылаемся, компилятор GnuCOBOL тоже не запутается.

Приведенный выше пример кодирования неполный; он описывает только имена элементов данных и их иерархические отношения друг к другу. Кроме того, любое допустимое определение элемента данных также должно описать тип данных, который должен содержаться в элементе данных (числовой? буквенно-цифровой? буквенный?), сколько данных может храниться в элементе данных и множество других характеристик.

При определении групповых элементов подчиненным элементам можно назначить «имя» FILLER. В рамках группового элемента можно определить любое количество элементов FILLER. Элемент данных с именем FILLER не может быть непосредственно ссылаемым; эти элементы обычно используются для указания неиспользуемой части общего объёма памяти, выделенной для группового элемента. Обратите внимание, что имя самого группового элемента может быть указано как FILLER, если нет необходимости напрямую ссылаться на саму структуру группы.

6.2. РАЗДЕЛ ФАЙЛОВ

Синтаксис РАЗДЕЛА ФАЙЛОВ

 [ FILE SECTION.
   ~~~~ ~~~~~~~
   { File/Sort-Description [ { FILE-SECTION-Data-Item } ]... }... ]
   {                         { 01-Level-Constant      }      }
   {                         { 78-Level-Constant      }      }
   { 01-Level-Constant                                       }
   { 78-Level-Constant                                       }

Каждый файл, на который ссылается оператор SELECT (см. ВЫБОР), также должен быть описан в разделе файла раздела данных.

Файлы, предназначенные для использования в качестве файлов работы сортировки/слияния, должны быть описаны с помощью описания файла сортировки/слияния (SD) , а все остальные файлы — с помощью описания файла (FD). Каждое из этих описаний почти всегда сопровождается по крайней мере одним описанием записи.

6.2.1. Описание файла/сортировки

Синтаксис описания файла/сортировки

 FD|SD file-name-1 [ IS EXTERNAL|GLOBAL ]
 ~~ ~~                  ~~~~~~~~ ~~~~~~
 [ BLOCK CONTAINS [ integer-1 TO ] integer-2 CHARACTERS|RECORDS ]
   ~~~~~                      ~~             ~~~~~~~~~~ ~~~~~~~
 [ CODE-SET IS alphabet-name-1 ]
   ~~~~~~~~
 [ DATA { RECORD IS   } identifier-1... ]
   ~~~~ { ~~~~~~      }
        { RECORDS ARE }
          ~~~~~~~
 [ LABEL { RECORD IS   } OMITTED|STANDARD ]
   ~~~~~ { ~~~~~~      } ~~~~~~~ ~~~~~~~~
         { RECORDS ARE }
           ~~~~~~~
 [ LINAGE IS integer-3 | identifier-2 LINES
   ~~~~~~
     [ LINES AT BOTTOM integer-4 | identifier-3 ]
                ~~~~~~
     [ LINES AT TOP integer-5 | identifier-4 ]
                ~~~
     [ WITH FOOTING AT integer-6 | identifier-5 ] ]
            ~~~~~~~
 [ RECORD { CONTAINS [ integer-7 TO ] integer-8 CHARACTERS   } ]
   ~~~~~~ {                      ~~                          }
          { IS VARYING IN SIZE                               }
          {    ~~~~~~~                                       }
          {     [ FROM [ integer-7 TO ] integer-8 CHARACTERS }
          {                        ~~                        }
          {         DEPENDING ON identifier-6 ]              }
                    ~~~~~~~~~
 [ RECORDING MODE IS recording-mode ]
   ~~~~~~~~~
 [ { REPORT IS   } report-name-1... ]
   { ~~~~~~      }
   { REPORTS ARE }
     ~~~~~~~
 [ VALUE OF implementor-name-1 IS literal-1 | identifier-7 ] .
   ~~~~~ ~~

Клаузы BLOCK CONTAINS, DATA RECORD, LABEL RECORD, RECORDING MODE и VALUE OF синтаксически распознаются, но устарели и не функциональны. Эти клаузы не должны использоваться в новых программах.

  1. Зарезервированные слова ARE, AT, CHARACTERS (только в RECORD разделе), CONTAINS, FROM, IN, IS, ON и WITH являются необязательными и могут быть включены или исключены по усмотрению программиста. Наличие или отсутствие этих слов не влияет на программу.
  2. Термины RECORD IS и RECORDS ARE взаимозаменяемы.
  3. Термины REPORT IS и REPORTS ARE взаимозаменяемы.
  4. Только файлы, предназначенные для использования в качестве рабочих файлов для инструкций SORT (см. SORT) или MERGE (см. MERGE), должны быть закодированы с SD — все остальные файлы должны быть определены с FD.
  5. Последовательность определения файлов с помощью FD или SD, по сравнению с последовательностью кодирования их SELECT инструкций, не имеет значения.
  6. Имя, указанное как file-name-1, должно точно совпадать с именем, указанным в SELECT инструкции файла.
  7. Раздел CODE-SET позволяет связать файл с пользовательской кодировкой символов, определённой в разделе SPECIAL-NAMES (см. SPECIAL-NAMES). Этот раздел допустим только при использовании файлов последовательного или построчного доступа.
  8. Раздел LINAGE может быть указан только в описании FD файла последовательного или построчного доступа. Если он используется с файлом последовательного доступа, организация этого файла будет неявно изменена на построчный. Различные компоненты раздела LINAGE определяют макет печатных страниц следующим образом:
    LINES AT TOP

    Количество неиспользуемых (т.е. оставленных пустыми) строк в верхней части каждой страницы. По умолчанию, если этот параметр не указан, он равен нулю.

    LINES AT BOTTOM

    Количество неиспользуемых (т.е. оставленных пустыми) строк в нижней части каждой страницы. По умолчанию, если этот параметр не указан, он равен нулю.

    LINAGE IS n LINES

    Общее количество используемых/доступных строк на странице.

    Сумма трёх предыдущих спецификаций должна составлять общее количество возможных строк на одной печатной странице.
    FOOTING AT

    Номер строки, за которым ничего не может быть напечатано, кроме подписи, которая должна отображаться на каждой странице. По умолчанию, если этот параметр не указан, он равен нулю, что означает отсутствие подписей. Это значение не может быть больше значения LINAGE IS n LINES.

  9. Эта структура страницы — после её определения — может быть автоматически применена инструкцией WRITE (см. WRITE).
  10. Указание раздела LINAGE в FD приведет к созданию специального регистра LINAGE-COUNTER для файла. Эта автоматически созданная переменная всегда будет содержать текущий относительный номер строки на обрабатываемой странице, что послужит отправной точкой для инструкции WRITE.
  11. Разделы RECORD CONTAINS и RECORD IS VARYING игнорируются (с выводом предупреждающего сообщения) при работе с файлами построчного доступа. При других организациях файлов эти взаимоисключающие разделы определяют длину записей данных в файле. Переменная, указанная как identifier-6, должна быть определена в одном из описаний записей файла file-name-1.
  12. Раздел REPORT IS сообщает компилятору, что файл будет предназначен для системы управления отчетами (RWCS); в разделе указаны один или несколько отчётов, каждый из которых должен быть описан в разделе отчётов. При использовании раздела REPORT применяются следующие специальные правила:
    1. Раздел может быть указан только в описании FD файла последовательного или построчного доступа. Если он используется с файлом последовательного доступа, организация этого файла будет неявно изменена на построчный.
    2. Раздел FD не может быть после описаний записей. Подробные описания данных, которые должны быть напечатаны в файл, будут определены в разделе REPORT SECTION (см. REPORT SECTION).
    3. Если также указан раздел LINAGE, значения, указанные для LINAGE IS и FOOTING AT, будут проигнорированы. Значения LINES AT BOTTOM и LINES AT TOP, если таковые имеются, будут учтены.
  13. Следующие специальные правила применяются только к файлам сортировки/слияния:
    1. Файлы сортировки/слияния должны быть назначены на DISK (или DISC) в их SELECT инструкциях.
    2. Сортировка и слияние будут выполняться в памяти, если объём сортируемых данных позволяет.
    3. Если по объёму данных сортировки или слияния необходимы реальные файлы на диске, они будут автоматически выделены на диске в папке, определённой:
      • Переменной среды выполнения TMPDIR (см. Run Time Environment Variables)
      • Переменной среды выполнения TMP
      • Переменной среды выполнения TEMP

      (в указанном порядке).

    4. Эти файлы на диске будут автоматически удалены при завершении SORT или MERGE. Они также будут удалены, если программа завершится аномально до завершения SORT или MERGE. Для временных файлов сортировки/слияния, если нужно, они будут именоваться cob*.tmp.
    5. Если вы укажете конкретное имя файла в SELECT файла сортировки/слияния, оно будет проигнорировано.
  1. См. Разделы описания данных, для получения информации об опциях EXTERNAL и GLOBAL.

6.2.2. Элемент данных раздела ФАЙЛ

Синтаксис элемента данных раздела ФАЙЛ

 level-number [ identifier-1 | FILLER ] [ IS GLOBAL|EXTERNAL ]
                               ~~~~~~        ~~~~~~ ~~~~~~~~
 [ BLANK WHEN ZERO ]
   ~~~~~      ~~~~
 [ JUSTIFIED RIGHT ]
   ~~~~
 [ OCCURS [ integer-1 TO ] integer-2 TIMES
   ~~~~~~             ~~
        [ DEPENDING ON identifier-2 ]
          ~~~~~~~~~
        [ ASCENDING|DESCENDING KEY IS identifier-3 ]
          ~~~~~~~~~ ~~~~~~~~~~
        [ INDEXED BY identifier-4 ] ]
          ~~~~~~~
 [ PICTURE IS picture-string ]
   ~~~
 [ REDEFINES identifier-5 ]
   ~~~~~~~~~
 [ SIGN IS LEADING|TRAILING [ SEPARATE [CHARACTER] ] ]
   ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~
 [ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
   ~~~~        ~~~~           ~~~~ ~~~~~
 [ USAGE IS data-item-usage ] . [ FILE-SECTION-Data-Item ]...
   ~~~~~

Разделы LEFT и RIGHT (СИНХРОНИЗИРОВАННО) синтаксически распознаются, но в остальном не функциональны.

Каждое описание файла сортировки (SD или FD) должно сопровождаться по меньшей мере одним элементом данных уровня 01, за исключением описаний файлов, содержащих раздел REPORT IS. Эти элементы данных уровня 01, в свою очередь, могут быть разбиты на подчиненные групповые и элементарные элементы. Элемент данных уровня 01, определенный здесь в разделе файла, также известен как запись, даже если это элементарный элемент, при условии, что элементарный элемент не имеет атрибута CONSTANT.

  1. Зарезервированные слова BY, IS, KEY, ON и WHEN являются необязательными и могут быть включены или не включены по усмотрению программиста. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированные слова SYNCRONIZED и SYNCRONIZED взаимозаменяемы. Оба могут быть сокращены до SYNC.
  3. Зарезервированное слово PICTURE может быть сокращено до PIC.
  4. Как показывает синтаксическая диаграмма, определение Элемента данных раздела ФАЙЛ является рекурсивным, т.е. после FD или SD может быть любое количество таких спецификаций. Первая такая спецификация должна иметь уровень 01 и будет описывать определенный формат записи данных в файле. Следующие за ней спецификации могут иметь уровень, больший чем 01, в этом случае они определяют иерархическое разбиение записи. Определение записи завершается, когда происходит одно из следующих событий:
    Найден другой элемент уровня 01

    указывает на начало другой компоновки записи для файла.

    Найден другой FD или SD

    помечает завершение подробного описания файла и начинает другое.

    Найден заголовок раздела или подразделения

    также отмечает завершение подробного описания файла и обозначает конец раздела файла.

  5. Каждое описание Элемента данных раздела ФАЙЛ должно завершаться точкой.
  6. Если для данного FD или SD присутствуют несколько описаний записей, запись с наибольшей длиной определит размер буфера записи, в который команда READ (см. READ) или команда RETURN (см. RETURN) передадут данные, прочитанные из файла, и из которого команда WRITE (см. WRITE) или команда RELEASE (см. RELEASE) извлекут данные для записи в файл.
  7. Различные описания записей уровня 01 для описания файла неявно используют один общий буфер записи (таким образом, они предоставляют разные способы просмотра структуры данных, которые могут существовать в файле). Буферы записей могут быть совместно использованы между файлами с помощью раздела SAME RECORD AREA (см. ОБЩАЯ ОБЛАСТЬ ЗАПИСИ).
  8. Единственно допустимые номера уровней — 01-49, 66, 77, 78 и 88. Уровни 66, 77, 78 и 88 имеют специальное назначение — См. Специальные элементы данных для получения подробностей.
  9. Не указание идентификатор-1 или FILLER сразу после номера уровня имеет тот же эффект, что и если бы было указано FILLER. Элемент данных с именем FILLER не может быть непосредственно обращен; эти элементы обычно используются для указания неиспользуемой части всего хранилища, выделенного для группового элемента, или для описания группового элемента, содержимое которого будет обращаться только по именам тех элементов, которые ему принадлежат.
  10. EXTERNAL нельзя комбинировать с GLOBAL или REDEFINES.
  11. Буферы данных раздела файла (и, следовательно, все компоновки записей уровня 01, определенные в разделе файла) инициализируются нулями в двоичной системе, когда программа загружается в память.
  12. См. Разделы описания данных для получения информации об использовании различных разделов описания данных.

6.3. РАЗДЕЛ РАБОЧЕЙ ПАМЯТИ

Синтаксис элемента данных раздела РАБОЧЕЙ ПАМЯТИ

 level-number [ identifier-1 | FILLER ] [ IS GLOBAL | EXTERNAL ]
                               ~~~~~~        ~~~~~~   ~~~~~~~~
 [ BASED ]
   ~~~~~
 [ BLANK WHEN ZERO ]
   ~~~~~      ~~~~
 [ JUSTIFIED RIGHT ]
   ~~~~
 [ OCCURS [ integer-1 TO ] integer-2 TIMES
   ~~~~~~             ~~
       [ DEPENDING ON identifier-2 ]
         ~~~~~~~~~
       [ ASCENDING|DESCENDING KEY IS identifier-3 ]
         ~~~~~~~~~ ~~~~~~~~~~
       [ INDEXED BY identifier-4 ] ]
         ~~~~~~~
 [ PICTURE IS picture-string ]
   ~~~
 [ REDEFINES identifier-5 ]
   ~~~~~~~~~
 [ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
   ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~
 [ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
   ~~~~        ~~~~           ~~~~ ~~~~~
 [ USAGE IS data-item-usage ]
   ~~~~~
 [ VALUE IS [ ALL ] literal-1 ] . [ WORKING-STORAGE-SECTION-Data-Item ]...
   ~~~~~      ~~~

Разделы LEFT и RIGHT (СИНХРОНИЗИРОВАННО) синтаксически распознаются, но в остальном не функциональны.

Раздел рабочей памяти используется для описания элементов данных, которые не являются частью файлов, экранов или отчетов и значения данных которых сохраняются на протяжении всего выполнения программы.

  1. Зарезервированные слова BY, CHARACTER, IS, KEY, ON, RIGHT (JUSTIFIED), TIMES и WHEN являются необязательными и могут быть включены или исключены по усмотрению программиста. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированные слова SYNCRONIZED и SYNCHRONISED взаимозаменяемы. Оба могут быть сокращены до SYNC.
  3. Зарезервированное слово PICTURE может быть сокращено до PIC.
  4. Зарезервированное слово JUSTIFIED может быть сокращено до JUST.
  5. Как показывает диаграмма синтаксиса, определение WORKING-STORAGE-SECTION-Data-Item является рекурсивным, то есть может быть любое количество таких спецификаций, записанных друг за другом. Первая такая спецификация должна иметь уровень 01. Спецификации, которые следуют за ней, могут иметь уровни, большие чем 01, в этом случае они определяют иерархическое разбиение записи. Определение записи завершается, когда происходит одно из следующего:
    • Встречается элемент уровня 01 — это означает конец определения одной записи и начало другой.
    • Встречается элемент уровня 77 — это означает конец определения записи и начало определения специального элемента данных; см. Элементы данных уровня 77 для получения дополнительной информации.
    • Встречается заголовок раздела или секции — это также отмечает завершение записи и означает конец раздела рабочей памяти.
  6. Каждое описание WORKING-STORAGE-SECTION-Data-Item должно завершаться точкой.
  7. Единственно допустимые номера уровней — 01-49, 66, 77, 78 и 88. Номера уровней от 01 до 49 используются для определения элементов данных, которые могут быть частью иерархической структуры. Номер уровня 01 также может использоваться для определения константы — элемента с неизменяемым значением, заданным на этапе компиляции.
  8. Номера уровней 66, 77, 78 и 88 имеют специальные применения — см. Специальные элементы данных для получения подробной информации.
  9. Отсутствие identifier-1 или FILLER сразу после номера уровня имеет тот же эффект, что и если бы было указано FILLER. Элемент данных с именем FILLER не может быть обращен к нему напрямую; эти элементы обычно используются для указания неиспользуемой части общего хранилища элемента группы или для описания элемента группы, содержимое которого будет обращено только к именам тех элементов, которые к нему относятся.
  10. Элементы данных, определенные в разделе рабочей памяти, инициализируются автоматически один раз — при загрузке программы, в которой определены данные, в память. Подпрограммы могут загружаться в память более одного раза (см. инструкцию CANCEL (см. CANCEL)), в этом случае инициализация происходит каждый раз при их загрузке. См. Инициализация данных для обсуждения правил инициализации.
  11. См. Описания данных для получения информации об использовании различных пунктов описания данных.

6.4. РАЗДЕЛ ЛОКАЛЬНОГО ХРАНЕНИЯ

Синтаксис элемента данных РАЗДЕЛА ЛОКАЛЬНОГО ХРАНЕНИЯ

 level-number [ identifier-1 | FILLER ] [ IS GLOBAL|EXTERNAL ]
                               ~~~~~~        ~~~~~~ ~~~~~~~~
 [ BASED ]
   ~~~~~
 [ BLANK WHEN ZERO ]
   ~~~~~      ~~~~
 [ JUSTIFIED RIGHT ]
   ~~~~
 [ OCCURS [ integer-1 TO ] integer-2 TIMES
   ~~~~~~             ~~
       [ DEPENDING ON identifier-2 ]
         ~~~~~~~~~
       [ ASCENDING|DESCENDING KEY IS identifier-3 ]
         ~~~~~~~~~ ~~~~~~~~~~
       [ INDEXED BY identifier-4 ] ]
         ~~~~~~~
 [ PICTURE IS picture-string ]
   ~~~
 [ REDEFINES identifier-5 ]
   ~~~~~~~~~
 [ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
   ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~
 [ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
   ~~~~        ~~~~           ~~~~ ~~~~~
 [ USAGE IS data-item-usage ]
   ~~~~~
 [ VALUE IS [ ALL ] literal-1 ] . [ LOCAL-STORAGE-SECTION-Data-Item ]...
   ~~~~~      ~~~

Описания LEFT и RIGHT (SYNCRONIZED) распознаются синтаксически, но не являются функциональными.

Раздел локального хранения похож на раздел рабочей памяти, но описывает данные внутри подпрограммы, которые будут динамически выделены и инициализированы (автоматически) каждый раз при выполнении подпрограммы. См. Инициализация данных для правил инициализации данных.

  1. Зарезервированные слова BY, CHARACTER IS, KEY, ON, RIGHT (JUSTIFIED), TIMES и WHEN являются необязательными и могут быть включены или пропущены по усмотрению программиста. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированные слова SYNCRONIZED и SYNCHRONISED взаимозаменяемы. Оба могут быть сокращены до SYNC.
  3. Зарезервированное слово PICTURE может быть сокращено до PIC.
  4. Зарезервированное слово JUSTIFIED может быть сокращено до JUST.
  5. Как показывает синтаксическая диаграмма, определение LOCAL-STORAGE-SECTION-Data-Item является рекурсивным, то есть может содержать любое количество таких спецификаций, записанных друг за другом. Первая такая спецификация должна иметь уровень 01. Последующие спецификации могут иметь уровни, большие чем 01, в этом случае они определяют иерархическое разбиение записи. Определение записи завершается, когда происходит одно из следующих событий:
    • Найден элемент уровня 01 — это означает конец определения одной записи и начало другой.
    • Найден заголовок раздела или подраздела — это также отмечает завершение записи и конец раздела локального хранилища.
  6. Каждое описание LOCAL-STORAGE-SECTION-Data-Item должно заканчиваться точкой.
  7. Единственно допустимые номера уровней — 01-49, 66, 77, 78 и 88. Номера уровней от 01 до 49 используются для определения элементов данных, которые могут быть частью иерархической структуры. Номер уровня 01 также может использоваться для определения константы — элемента с неизменным значением, заданным во время компиляции.
  8. Номера уровней 66, 77, 78 и 88 имеют специальное назначение — см. Специальные элементы данных для получения подробной информации.
  9. Отсутствие identifier-1 или FILLER сразу после номера уровня имеет тот же эффект, что и указание FILLER. Элемент данных с именем FILLER не может быть напрямую ссылаться; эти элементы обычно используются для указания неиспользуемой части общего объема памяти, выделенной для элемента группы, или для описания элемента группы, содержимое которого будет ссылаться только с помощью имен элементов, принадлежащих ему.
  10. Локальное хранилище не может быть использовано во вложенных подпрограммах.
  11. См. Описания элементов данных для получения информации об использовании различных описаний элементов данных.

6.5. РАЗДЕЛ СВЯЗИ

Синтаксис элементов данных раздела связи

 level-number [ identifier-1 | FILLER ] [ IS GLOBAL|EXTERNAL ]
                               ~~~~~~        ~~~~~~ ~~~~~~~~
 [ ANY LENGTH ]
   ~~~ ~~~~~~
 [ BASED ]
   ~~~~~
 [ BLANK WHEN ZERO ]
   ~~~~~      ~~~~
 [ JUSTIFIED RIGHT ]
   ~~~~
 [ OCCURS [ integer-1 TO ] integer-2 TIMES
   ~~~~~~             ~~
       [ DEPENDING ON identifier-3 ]
         ~~~~~~~~~
       [ ASCENDING|DESCENDING KEY IS identifier-4 ]
         ~~~~~~~~~ ~~~~~~~~~~
       [ INDEXED BY identifier-5 ] ]
         ~~~~~~~
 [ PICTURE IS picture-string ]
   ~~~
 [ REDEFINES identifier-6 ]
   ~~~~~~~~~
 [ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
   ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~
 [ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
   ~~~~        ~~~~           ~~~~ ~~~~~
 [ USAGE IS data-item-usage ] . [ LINKAGE-SECTION-Data-Item ]...
   ~~~~~

Оператор LEFT и оператор RIGHT (SYNCRONIZED) синтаксически распознаются, но в остальном не функциональны.

Раздел связи описывает данные внутри подпрограммы, которые служат либо входными аргументами, либо выходными результатами подпрограммы.

  1. Зарезервированные слова BY, CHARACTER, IS, KEY, ON и WHEN являются необязательными и могут быть включены или не включены по усмотрению программиста. Наличие или отсутствие этих слов не оказывает влияния на программу.
  2. Зарезервированные слова SYNCRONIZED и “SYNCHRONISED” взаимозаменяемы. Оба могут быть сокращены до SYNC.
  3. Зарезервированное слово PICTURE может быть сокращено до PIC.
  4. Зарезервированное слово JUSTIFIED может быть сокращено до JUST.
  5. Как показывает синтаксическая диаграмма, определение LINKAGE-SECTION-Data-Item является рекурсивным, то есть может содержать любое количество таких спецификаций, записанных друг за другом. Первая такая спецификация должна иметь уровень 01. Спецификации, следующие за ней, могут иметь уровни, большие, чем 01, в этом случае они определяют иерархическое разбиение записи. Определение записи завершается, когда происходит одно из следующих событий:
    • Найден элемент уровня 01 — это означает конец определения одной записи и начало другой.
    • Найден заголовок раздела или секции — это также отмечает завершение записи и означает конец секции связи.
  6. Описание каждого LINKAGE-SECTION-Data-Item должно завершаться точкой.
  7. Единственно допустимые уровни — 01-49, 66, 77, 78 и 88. Уровни с 01 по 49 используются для определения элементов данных, которые могут быть частью иерархической структуры. Уровень 01 также может быть использован для определения константы — элемента с неизменяемым значением, указанным во время компиляции.
  8. Уровни 66, 77, 78 и 88 имеют специальное назначение — см. Специальные элементы данных для получения подробной информации.
  9. Ожидается, что:
    1. Секция связи должна встречаться только внутри подпрограммы. Однако компилятор не запрещает ее использование в основной программе.
    2. Все элементы данных уровня 01, описанные в секции связи подпрограммы, должны появляться в PROCEDURE DIVISION USING (см. Использование PROCEDURE DIVISION) или в качестве аргументов в операторе ENTRY.
    3. Каждый элемент данных уровня 01, описанный в секции связи подпрограммы, должен соответствовать аргументу, переданному в операторе CALL (см. CALL) или аргументу в вызове функции подпрограммы.
  10. Не указание identifier-1 или FILLER сразу после номера уровня имеет тот же эффект, что и если было указано FILLER. Элемент данных с именем FILLER не может быть напрямую ссылаться; такие элементы обычно используются для указания неиспользуемой части всего выделенного хранилища для группового элемента или для описания группового элемента, содержимое которого будет ссылаться только по именам тех элементов, которые к нему принадлежат. В секции связи элементы данных уровня 01 не могут быть названы FILLER.
  11. Для данных, определенных в секции связи, не выделяется памяти; описания данных там служат лишь для определения областей памяти, которые будут переданы подпрограмме вызывающей программой. Следовательно, любые обсуждения по умолчанию инициализации таких данных неактуальны. Тем не менее, возможно вручную выделять элементы данных секции связи, которые не являются аргументами подпрограммы, с помощью оператора ALLOCATE (см. ALLOCATE). В таких случаях инициализация происходит в соответствии с документацией данного оператора.
  12. См. Положения описания данных для получения информации об использовании различных положений описания данных.

6.6. РАЗДЕЛ ОТЧЁТА

Синтаксис РАЗДЕЛА ОТЧЁТА

 [ REPORT SECTION.
   ~~~~~~ ~~~~~~~
   { Report-Description [ { Report-Group-Definition } ]... }... ]
   {                      { 01-Level-Constant       }      }
   {                      { 78-Level-Constant       }      }
   { 01-Level-Constant                                     }
   { 78-Level-Constant                                     }

Синтаксис Описания отчёта (RD)

 RD report-name [ IS GLOBAL ]
 ~~                  ~~~~~~
 [ CODE IS literal-1 | identifier-1 ]
   ~~~~
 [ { CONTROL IS   } { FINAL        }... ]
   { ~~~~~~~      } { ~~~~~        }
   { CONTROLS ARE } { identifier-2 }
     ~~~~~~~~
 [ PAGE [ { LIMIT IS   } ] [ { literal-2    } LINES ]
   ~~~~   { ~~~~~      }     { identifier-3 } ~~~~
          { LIMITS ARE }
            ~~~~~~
       [ literal-3 | identifier-4 COLUMNS|COLS ]
                                  ~~~~~~~ ~~~~
       [ HEADING IS literal-4 | identifier-5 ]
         ~~~~~~~
       [ FIRST DE|DETAIL IS literal-5 | identifier-6 ]
         ~~~~~ ~~ ~~~~~~
       [ LAST CH|{CONTROL HEADING} IS literal-6 | identifier-7 ]
         ~~~~ ~~  ~~~~~~~ ~~~~~~~
       [ LAST DE|DETAIL IS literal-7 | identifier-8 ]
         ~~~~ ~~ ~~~~~~
       [ FOOTING IS literal-8 | identifier-9 ] ] .
         ~~~~~~~

Этот раздел описывает макет печатных отчётов, а также многие функциональные аспекты генерации отчётов, которые будут созданы с помощью Системы управления созданием отчётов. Важно сохранять порядок этих положений и гарантировать, что все поля, определённые или используемые в этом разделе, фактически определены в WORKING-STORAGE SECTION и нигде больше.

  1. Зарезервированные слова ARE и IS необязательны и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Фразы CONTROL IS и CONTROLS ARE взаимозаменяемы, как и фразы PAGE LIMIT и PAGE LIMITS.
  3. Зарезервированное слово LINES может быть сокращено до LINE.
  4. Зарезервированное слово COLUMNS может быть сокращено до COLS.
  5. Каждый отчет, на который ссылается раздел REPORT IS (см. Описание файла/сортировки), должен быть описан описанием отчета (RD).
  6. См. GLOBAL для получения информации об опции GLOBAL.
  7. Пожалуйста, ознакомьтесь с Функциями редактора отчетов, если вы этого еще не сделали. Это поможет вам ознакомиться с терминологией редактора отчетов, которая следует далее.
  8. Следующие правила относятся к разделу PAGE LIMITS:
    1. Если раздел PAGE LIMITS не указан, весь отчет будет сгенерирован как будто он состоит из одной произвольно длинной страницы.
    2. Все литералы (literal-2 до literal-8) должны быть числовыми с ненулевыми положительными целочисленными значениями.
    3. Все идентификаторы (identifier-2 до identifier-8) должны быть числовыми, необработанными с ненулевыми положительными целочисленными значениями.
    4. Любое значение, указанное для literal-2 или identifier-2, определит общее количество доступных строк на любой странице отчета, не считая любых неиспользуемых полей вверху и/или внизу страницы (определенных значениями LINES AT TOP и LINES AT BOTTOM в разделе LINAGE отчета FD — этот раздел связан с — см. Описание файла/сортировки).
    5. Любое значение, указанное для literal-3 или identifier-3, будет проигнорировано.
    6. Раздел HEADING определяет номер первой строки, в которой может быть представлен заголовок отчета или заголовок страницы.
    7. Раздел FIRST DETAIL определяет первую строку, в которой может быть представлена группа деталей.
    8. Раздел LAST CONTROL HEADING определяет последнюю строку, в которой может быть представлена любая строка заголовка управления.
    9. Раздел LAST DETAIL определяет последнюю строку, в которой может быть представлена любая строка группы деталей.
    10. Раздел FOOTING определяет последнюю строку, в которой может быть представлена любая строка группы подвала управления.
    11. Следующие правила устанавливают значения по умолчанию для различных разделов PAGE LIMIT, предполагая, что существует один:
      HEADING

      значение по умолчанию — один (1)

      FIRST DETAIL HEADING

      используется значение

      LAST CONTROL HEADING

      значение из LAST DETAIL или, если его нет, значение из FOOTING или, если его тоже нет, значение из PAGE LIMIT

      LAST DETAIL

      значение из FOOTING или, если его нет, значение из PAGE LIMIT

      FOOTING

      значение из LAST DETAIL или, если его нет, значение из PAGE LIMIT

    12. Для того, чтобы значения, указанные в разделе PAGE LIMIT, были корректными, должны выполняться все следующие условия:
      • FIRST DETAIL ≤ HEADING
      • LAST CONTROL HEADING ≤ FIRST DETAIL
      • LAST DETAIL ≤ LAST CONTROL HEADING
      • FOOTING ≤ LAST DETAIL
  1. Следующие правила относятся к фрагменту CONTROL:
    1. Если фрагмент CONTROL отсутствует, отчёт не будет содержать разрывов управления; это означает, что в этом RD, не могут быть определены группы отчёта CONTROL HEADING или CONTROL FOOTING.
    2. Включите зарезервированное слово FINAL, если вы хотите включить специальное заголовка управления перед генерацией первой строки детали (CONTROL HEADING FINAL) или после генерации последней строки детали (CONTROL FOOTING FINAL).
    3. Если вы указываете FINAL, оно должно быть первым именем разрыва управления в RD.
    4. Любые спецификации identifier-9, включенные в CONTROL фрагмент, ссылаются на имена данных, определённые в любом разделе описания данных, кроме раздела отчёта.
    5. Для каждой identifier-9 должна быть определена группа отчёта CONTROL HEADING и/или CONTROL FOOTING в разделе отчёта.
    6. Во время выполнения:
      • Каждый раз, когда выполняется инструкция GENERATE (см. GENERATE) по отношению к группе отчёта детали, определённой для этого RD, RWCS проверит содержимое каждого элемента данных identifier-2; всякий раз, когда значение identifier-9 изменилось с момента предыдущего GENERATE, условие разрыва управления будет активным для этого identifier-2.
      • После определения списка разрывов управления будет представлена CONTROL FOOTING для каждого identifier-2 с разрывом управления (если такая группа отчёта определена).
      • Далее будет представлена CONTROL HEADING для каждого identifier-2 с разрывом управления (если такая группа отчёта определена).
      • Группы отчёта CONTROL FOOTING и CONTROL HEADING будут представлены в порядке их перечисления в CONTROL фрагменте.
      • Лишь после этого обработки будет представлена группа отчёта детали, указанная в GENERATE фрагменте.
  2. Для каждого RD будет выделено следующее:
    1. Специальный регистр PAGE-COUNTER (см. Специальные Регистры), который будет содержать текущий номер страницы отчёта.
      • Этот регистр будет установлен в значение 1 при выполнении инструкции INITIATE (см. INITIATE) для отчёта и будет увеличиваться на 1 каждый раз, когда RWCS начинает новую страницу отчёта.
      • Ссылки на PAGE-COUNTER внутри раздела отчёта будут неявно квалифицированы именем отчёта, к которому относится группа отчёта, ссылающаяся на регистр.
      • Ссылки на PAGE-COUNTER в разделе процедур должны быть квалифицированы соответствующим именем отчёта, если определено несколько RD.
    2. Специальный регистр LINE-COUNTER, который будет содержать текущий номер строки на текущей странице.
  3. Фрагмент RD должен быть последован хотя бы одной группой отчета уровня 01.

6.6.1. Определения групп отчёта

Синтаксис определения группы отчёта

 01 [ identifier-1 ]

 [ LINE NUMBER IS { integer-1 [ [ ON NEXT PAGE ] } ]
   ~~~~           {                  ~~~~ ~~~~   }
                  { +|PLUS integer-1             }
                  {   ~~~~                       }
                  { ON NEXT PAGE                 }
                       ~~~~ ~~~~
 [ NEXT GROUP IS { [ +|PLUS ] integer-2  } ]
   ~~~~ ~~~~~    {     ~~~~              }
                 { NEXT|{NEXT PAGE}|PAGE }
                   ~~~~  ~~~~ ~~~~  ~~~~
 [ TYPE IS { RH|{REPORT HEADING}                      } ]
   ~~~~    { ~~  ~~~~~~ ~~~~~~~                       }
           { PH|{PAGE HEADING}                        }
           { ~~  ~~~~ ~~~~~~~                         }
           { CH|{CONTROL HEADING} FINAL|identifier-2  }
           { ~~  ~~~~~~~ ~~~~~~~  ~~~~~               }
           { DE|DETAIL                                }
           { ~~ ~~~~~~                                }
           { CF|{CONTROL FOOTING} FINAL|identifier-2  }
           { ~~  ~~~~~~~ ~~~~~~~  ~~~~~               }
           { PF|{PAGE FOOTING}                        }
           {  ~~ ~~~~ ~~~~~~~                         }
           { RF|{REPORT FOOTING}                      }
             ~~  ~~~~~~ ~~~~~~~
 . [ REPORT-SECTION-Data-Item ]...

Здесь показан синтаксис определения группы отчёта для отчёта. Этот синтаксис допустим только в разделе отчёта и только после фрагмента RD.

  1. Зарезервированные слова IS, NUMBER и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Термины RH и REPORT HEADING взаимозаменяемы, как и PH и PAGE HEADING, CH и CONTROL HEADING, DE и DETAIL, CF и CONTROL FOOTING, PF и PAGE FOOTING, а также RF и REPORT FOOTING.
  3. Определяемая группа отчёта будет частью наиболее недавно закодированного RD.
  4. Фрагмент TYPE (см. TYPE) указывает тип определяемой группы отчёта.
  5. Номер уровня для определения группы отчёта должен быть 01.
  6. Необязательная спецификация identifier-1 присваивает имя этой группе отчёта, чтобы группа могла быть использована в инструкции GENERATE или в USE BEFORE REPORTING.
  7. Две группы отчёта в одном отчёте (RD) не могут иметь одинаковое имя identifier-1. Однако могут быть несколько определений identifier-1 в разных отчётах. В таких случаях ссылки на identifier-1 должны быть квалифицированы именем отчёта.
  8. Может быть только один заголовок отчёта, подвал отчёта, окончательный заголовок управления, окончательный подвал управления, заголовок страницы и подвал страницы на отчёт.
  9. Объявления групп отчёта должны быть последованные по крайней мере одной REPORT-SECTION-Data-Item с номером уровня в диапазоне от 02 до 49.
  10. Сведения об использовании различных фрагментов описания данных см. в разделе Фрагменты описания данных.

6.6.2. Элементы данных раздела отчёта

Синтаксис элементов данных раздела отчёта

 level-number [ identifier-1 ]

 [ BLANK WHEN ZERO ]
   ~~~~~      ~~~~
 [ COLUMN [ { NUMBER IS   } ] [ +|PLUS ] integer-1 ]
   ~~~      { ~~~~~~      }       ~~~~
            { NUMBERS ARE }
              ~~~~~~~
 [ GROUP INDICATE ]
   ~~~~~ ~~~~~~~~
 [ JUSTIFIED RIGHT ]
   ~~~~
 [ LINE NUMBER IS { integer-2 [ [ ON NEXT PAGE ] } ]
   ~~~~           { +|PLUS integer-2 ~~~~ ~~~~   }
                  {   ~~~~                       }
                  { ON NEXT PAGE                 }
                       ~~~~ ~~~~
 [ OCCURS [ integer-3 TO ] integer-4 TIMES
   ~~~~~~             ~~
     [ DEPENDING ON identifier-2 ]
       ~~~~~~~~~
     [ STEP integer-5 ]
       ~~~~
     [ VARYING identifier-3 FROM { identifier-4 } BY { identifier-5 } ]
       ~~~~~~~              ~~~~ { integer-6    } ~~ { integer-7    }
 [ PICTURE IS picture-string ]
   ~~~
 [ PRESENT WHEN condition-name ]
   ~~~~~~~ ~~~~
 [ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
   ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~
 [ { SOURCE IS literal-1|identifier-6 [ ROUNDED ]                   } ]
   { ~~~~~~                             ~~~~~~~                     }
   { SUM OF { identifier-7 }... [ { RESET ON FINAL|identifier-8 } ] }
   { ~~~    { literal-2    }      { ~~~~~    ~~~~~              }   }
   { VALUE IS [ ALL ] literal-3   { UPON identifier-9           }   }
     ~~~~~      ~~~                 ~~~~
 . [ REPORT-SECTION-Data-Item ]...

Описания элементов данных, описывающие строки и поля отчёта, которые составляют содержание группы отчёта, непосредственно следуют за определением этой группы.

  1. Зарезервированные слова IS, NUMBER, OF, ON, RIGHT, TIMES и WHEN (BLANK) являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированное слово COLUMN может быть сокращено до COL.
  3. Зарезервированное слово JUSTIFIED может быть сокращено до JUST.
  4. Зарезервированное слово PICTURE может быть сокращено до PIC.
  5. Определения SOURCE (см. SOURCE), SUM (см. SUM) и VALUE (см. VALUE), допустимые только для элементарных пунктов, взаимно исключают друг друга.
  6. Групповые пункты (без PICTURE пунктов) часто используются для описания целых строк отчёта, в то время как элементарные пункты (с пунктом рисунка) часто используются для описания конкретных полей информации в отчёте. При использовании этой кодировочной схемы, групповые пункты будут иметь LINE (см. LINE) пунктов и не будут иметь COLUMN (см. COLUMN) пунктов, в то время как элементарные пункты будут описываться наоборот.
  7. См. Описание пунктов данных для получения информации об использовании различных пунктов описания данных.

6.7. БЛОК ЭКРАНА

Синтаксис элемента данных БЛОКА ЭКРАНА

 level-number [ identifier-1 | FILLER ]
                               ~~~~~~
 [ AUTO | AUTO-SKIP | AUTOTERMINATE ] [ BELL | BEEP ]
   ~~~~   ~~~~~~~~~   ~~~~~~~~~~~~~     ~~~~   ~~~~
 [ BACKGROUND-COLOR|BACKGROUND-COLOUR IS integer-1 | identifier-2 ]
   ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
 [ BLANK LINE|SCREEN ] [ ERASE EOL|EOS ]
   ~~~~~ ~~~~ ~~~~~~     ~~~~~ ~~~ ~~~
 [ BLANK WHEN ZERO ] [ JUSTIFIED RIGHT ]
   ~~~~~      ~~~~     ~~~~
 [ BLINK ] [ HIGHLIGHT | LOWLIGHT ] [ REVERSE-VIDEO ]
   ~~~~~     ~~~~~~~~~   ~~~~~~~~     ~~~~~~~~~~~~~
 [ COLUMN NUMBER IS [ +|PLUS ] integer-2 | identifier-3 ]
   ~~~                  ~~~~
 [ FOREGROUND-COLOR|FOREGROUND-COLOUR IS integer-3 | identifier-4 ]
   ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
 [ { FROM literal-1 | identifier-5 } ]
   { ~~~~                          }
   { TO identifier-5               }
   { ~~                            }
   { USING identifier-5            }
   { ~~~~~                         }
   { VALUE IS [ ALL ] literal-1    }
     ~~~~~      ~~~
 [ FULL | LENGTH-CHECK ] [ REQUIRED | EMPTY-CHECK ] [ SECURE | NO-ECHO ]
   ~~~~   ~~~~~~~~~~~~     ~~~~~~~~   ~~~~~~~~~~~     ~~~~~~   ~~~~~~~
 [ LEFTLINE ] [ OVERLINE ] [ UNDERLINE ]
   ~~~~~~~~     ~~~~~~~~     ~~~~~~~~~
 [ LINE NUMBER IS [ +|PLUS ] integer-4 | identifier-6 ]
   ~~~~               ~~~~
 [ OCCURS integer-5 TIMES ]
   ~~~~~~
 [ PICTURE IS picture-string ]
   ~~~
 [ PROMPT [ CHARACTER IS literal-2 | identifier-7 ]
   ~~~~~~   ~~~~~~~~~
 [ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
   ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~
 . [ SCREEN-SECTION-Data-Item ]...

Блок экрана описывает экраны, которые должны отображаться во время взаимодействия с терминалом/консолью.

  1. Зарезервированные слова CHARACTER (пункт SEPARATE), IS, NUMBER, RIGHT, TIMES и WHEN являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированное слово COLUMN может быть сокращено до COL.
  3. Зарезервированное слово PICTURE может быть сокращено до PIC.
  4. Следующие наборы зарезервированных слов взаимозаменяемы:
    • AUTO, AUTO-SKIP и AUTOTERMINATE
    • BACKGROUND-COLOR и BACKGROUND-COLOUR
    • BELL и BEEP
    • FOREGROUND-COLOR и FOREGROUND-COLOUR
    • FULL и LENGTH-CHECK
    • REQUIRED и EMPTY-CHECK
    • SECURE и NO-ECHO
  5. Элементы данных, определённые в блоке экрана, описывают макеты экранов для ввода, вывода или их комбинации, которые будут использоваться с инструкцией ACCEPT screen-data-item (см. ACCEPT screen-data-item) или инструкцией DISPLAY screen-data-item (см. DISPLAY screen-data-item). Эти макеты экранов могут определять всю доступную область экрана или любую её подмножество.
  6. Термин доступная область экрана является расплывчатым в тех средах, где сеансы командной строки вызываются внутри графической среды пользователя, как это происходит в Windows, OSX и большинстве систем Unix/Linux — эти среды позволяют окнам сеансов командной строки существовать с переменным числом доступных строк и столбцов экрана. При проектировании экранов GnuCOBOL необходимо учитывать логическую геометрию строк/столбцов экрана, в которой будет выполняться программа.
  7. Элементы данных с уровнями 01 (Константы), 66, 78 и 88 могут быть использованы в блоке экрана; они имеют тот же синтаксис, правила и использование, что и в других разделах отдела данных.
  8. Без пунктов LINE (см. СТРОКА) или COLUMN (см. СТОЛБЕЦ), поля блока экрана будут отображаться на окне консоли, начиная с координат строки/столбца, указанных или подразумеваемых инструкцией ACCEPT screen-data-item или DISPLAY screen-data-item, которая отображает элемент экрана. После того, как поле отображено на окне консоли, следующее поле будет отображено сразу после него.
  9. Пункт LINE явно указанный в определении элемента данных блока экрана, переопределит любой пункт LINE включённый в инструкции ACCEPT screen-data-item или DISPLAY screen-data-item , которая отображает этот элемент данных на экране. То же самое касается пунктов COLUMN.
  10. Клавиши Tab и Back-Tab (Shift-Tab на большинстве клавиатур) расположат курсор от поля к полю в последовательности строк/столбцов, в которой поля отображаются на экране во время выполнения, независимо от последовательности, в которой они были определены в блоке экрана.
  11. См. Описание пунктов данных для получения информации об использовании различных пунктов описания данных.

6.8. Специальные элементы данных

6.8.1. Константы уровня 01

Синтаксис константы уровня 01

 01 constant-name-1 CONSTANT [ IS GLOBAL ]
                    ~~~~~~~~      ~~~~~~
   { AS { literal-1                           } } .
   {    { { BYTE-LENGTH } OF { identifier-1 } } }
   {    { { ~~~~~~~~~~~ }    { usage-name   } } }
   {    { { LENGTH      }                     } }
   {        ~~~~~~                              }
   { FROM CDF-variable-name-1                   }
     ~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, SCREEN.

Постоянная 01-го уровня является одним из четырёх типов констант времени компиляции, которые могут быть объявлены в программе. Другие три типа — это >>DEFINE директивы CDF (см. >>DEFINE) константы, >>SET директивы CDF (см. >>SET) константы и константы 78-го уровня (см. Элементы данных 78-го уровня).

  1. Зарезервированные слова AS, IS и OF являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. См. GLOBAL, для получения информации об опции GLOBAL.
  3. Этот конкретный тип объявления констант предоставляет возможность определить длину элемента данных или размер памяти, связанный с определённым числовым USAGE (см. USAGE) типом — то, что невозможно с другими типами констант.
  4. Константы, определённые таким образом, становятся неопределёнными после того, как в входном источнике встретится END PROGRAM или END FUNCTION.
  5. Описания данных такого вида фактически не выделяют никакой памяти — они просто определяют имя (constant-name-1), которое может быть использовано везде, где может использоваться числовая литерал (см. BYTE-LENGTH или LENGTH опции) или литерал того же типа, что и literal-1.
  6. Имя constant-name-1 не может быть использовано в директиве CDF.
  7. Следует быть внимательным, чтобы constant-name-1 не дублировало любое другое имя элемента данных, определённое в программе, поскольку ссылки на это имя элемента данных будут ссылаться на константу, а не на элемент данных. Компилятор GnuCOBOL не выдаст предупреждения об этом условии.
  8. Значение, указанное для usage-name, может быть любым USAGE, который не использует PICTURE (см. PICTURE) пункт. Это могут быть любые из BINARY-C-LONG, BINARY-CHAR, BINARY-DOUBLE, BINARY-LONG, BINARY-SHORT, COMP-1 (или COMPUTATIONAL-1), COMP-2 (или COMPUTATIONAL-2), FLOAT-DECIMAL-16, FLOAT-DECIMAL-34, FLOAT-LONG, FLOAT-SHORT, POINTER, или PROGRAM-POINTER.
  9. Пункт BYTE-LENGTH создаст числовое значение для constant-name-1, идентичное тому, которое вернёт функция BYTE-LENGTH по отношению к identifier-1 или элементу данных, объявленному с USAGE usage-name.
  10. Пункт LENGTH создаст числовое значение для constant-name-1, идентичное тому, которое вернёт функция LENGTH по отношению к identifier-1 или элементу данных, объявленному с USAGE usage-name.

Вот пример программы GnuCOBOL, которая использует константы 01-го уровня для отображения длины (в байтах) различных типов использования без формата изображения.

    IDENTIFICATION DIVISION.
    PROGRAM-ID. Usage Lengths.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01  Len-BINARY-C-LONG    CONSTANT AS LENGTH OF BINARY-C-LONG.
    01  Len-BINARY-CHAR      CONSTANT AS LENGTH OF BINARY-CHAR.
    01  Len-BINARY-DOUBLE    CONSTANT AS LENGTH OF BINARY-DOUBLE.
    01  Len-BINARY-LONG      CONSTANT AS LENGTH OF BINARY-LONG.
    01  Len-BINARY-SHORT     CONSTANT AS LENGTH OF BINARY-SHORT.
    01  Len-COMP-1           CONSTANT AS LENGTH OF COMP-1.
    01  Len-COMP-2           CONSTANT AS LENGTH OF COMP-2.
    01  Len-FLOAT-DECIMAL-16 CONSTANT AS LENGTH OF FLOAT-DECIMAL-16.
    01  Len-FLOAT-DECIMAL-34 CONSTANT AS LENGTH OF FLOAT-DECIMAL-34.
    01  Len-FLOAT-LONG       CONSTANT AS LENGTH OF FLOAT-LONG.
    01  Len-FLOAT-SHORT      CONSTANT AS LENGTH OF FLOAT-SHORT.
    01  Len-POINTER          CONSTANT AS LENGTH OF POINTER.
    01  Len-PROGRAM-POINTER  CONSTANT AS LENGTH OF PROGRAM-POINTER.
    PROCEDURE DIVISION.
    000-Main.
        DISPLAY "On this system, with this build of GnuCOBOL, the"
        DISPLAY "PICTURE-less USAGE's have these lengths (in bytes):"
        DISPLAY " "
        DISPLAY "BINARY-C-LONG:    " Len-BINARY-C-LONG
        DISPLAY "BINARY-CHAR:      " Len-BINARY-CHAR
        DISPLAY "BINARY-DOUBLE:    " Len-BINARY-DOUBLE
        DISPLAY "BINARY-LONG:      " Len-BINARY-LONG
        DISPLAY "BINARY-SHORT:     " Len-BINARY-SHORT
        DISPLAY "COMP-1:           " Len-COMP-1
        DISPLAY "COMP-2:           " Len-COMP-2
        DISPLAY "FLOAT-DECIMAL-16: " Len-FLOAT-DECIMAL-16
        DISPLAY "FLOAT-DECIMAL-34: " Len-FLOAT-DECIMAL-34
        DISPLAY "FLOAT-LONG:       " Len-FLOAT-LONG
        DISPLAY "FLOAT-SHORT:      " Len-FLOAT-SHORT
        DISPLAY "POINTER:          " Len-POINTER
        DISPLAY "PROGRAM-POINTER:  " Len-PROGRAM-POINTER
        STOP RUN
        .

Вывод этой программы на системе Windows 7 с 32-разрядной сборкой MinGW GnuCOBOL:

    On this system, with this build of GnuCOBOL, the
    PICTURE-less USAGE's have these lengths (in bytes):

    BINARY-C-LONG:    4
    BINARY-CHAR:      1
    BINARY-DOUBLE:    8
    BINARY-LONG:      4
    BINARY-SHORT:     2
    COMP-1:           4
    COMP-2:           8
    FLOAT-DECIMAL-16: 8
    FLOAT-DECIMAL-34: 16
    FLOAT-LONG:       8
    FLOAT-SHORT:      4
    POINTER:          4
    PROGRAM-POINTER:  4

6.8.2. Элементы данных 66-го уровня

Синтаксис элементов данных 66-го уровня

 66 identifier-1 RENAMES identifier-2 [ THRU|THROUGH identifier-3 ] .
                 ~~~~~~~                ~~~~ ~~~~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE

Элемент данных 66-го уровня объединяет ранее определённые элементы, задавая альтернативные, возможно перекрывающиеся, группировки элементарных элементов данных.

  1. Зарезервированные слова THRU и THROUGH взаимозаменяемы.
  2. Элемент данных 66-го уровня не может переименовать элемент данных 66-го, 01-го, 77-го или 88-го уровня.
  3. Может быть несколько элементов данных 66-го уровня, переименовывающих элементы данных, содержащиеся в одном описании записи 01-го уровня.
  4. Все RENAMES записи, связанные с одной логической записью, должны следовать сразу после последней записи описания данных данной записи.

6.8.3. Элементы данных 77-го уровня

Синтаксис элемента данных 77-го уровня

 77 identifier-1 [ IS GLOBAL|EXTERNAL ]
                      ~~~~~~ ~~~~~~~~
 [ BASED ]
   ~~~~~
 [ BLANK WHEN ZERO ]
   ~~~~~      ~~~~
 [ JUSTIFIED RIGHT ]
   ~~~~
 [ PICTURE IS picture-string ]
   ~~~
 [ REDEFINES identifier-5 ]
   ~~~~~~~~~
 [ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
   ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~
 [ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
   ~~~~        ~~~~           ~~~~ ~~~~~
 [ USAGE IS data-item-usage ]
   ~~~~~
 [ VALUE IS [ ALL ] literal-1 ] .
   ~~~~~      ~~~

Пункты LEFT и RIGHT (SYNCRONIZED) синтаксически распознаются, но в остальном не функциональны.

Этот синтаксис допустим в следующих разделах: WORKING-STORAGE, LOCAL-STORAGE, LINKAGE

Цель элемента 77-го уровня — возможность создания самостоятельного элементарных данных.

  1. Зарезервированные слова CHARACTER, IS, RIGHT (JUSTIFIED) и WHEN являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированное слово JUSTIFIED может быть сокращено до JUST, зарезервированное слово PICTURE может быть сокращено до PIC, а зарезервированные слова SYNCRONIZED и SYNCHRONISED могут быть сокращены до SYNC.
  3. Новые программы, требующие самостоятельного элементарного элемента, должны быть закодированы с использованием уровня 01, а не 77.
  4. См. Разделы описания данных, для получения информации об использовании различных разделов описания данных.

6.8.4. Элементы данных 78-го уровня

Синтаксис констант 78-го уровня

 78 constant-name-1 VALUE IS literal-1 .
                    ~~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, SCREEN

Постоянная величина 78-го уровня — один из четырёх типов констант времени компиляции, которые можно объявить в программе. Другие три типа — константы директивы >>DEFINE CDF (см. >>DEFINE), константы директивы >>SET CDF (см. >>SET) и константы 01-го уровня (см. Константы 01-го уровня).

  1. Зарезервированное слово IS является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Константы, определённые таким образом, становятся неопределёнными после того, как в исходном коде встретится END PROGRAM или END FUNCTION.
  3. Описания данных такого формата фактически не выделяют памяти — они просто определяют имя (constant-name-1), которое можно использовать в любом месте, где может использоваться литерал того же типа, что и literal-1.
  4. Имя constant-name-1 не может быть использовано в директиве CDF.
  5. Следует позаботиться о том, чтобы constant-name-1 не дублировало никакое другое имя элемента данных, определённое в программе, так как ссылки на это имя элемента данных будут относиться к константе, а не к элементу данных. Компилятор GnuCOBOL не выведет предупреждение об этом условии.

6.8.5. Элементы данных 88-го уровня

Синтаксис элементов данных 88-го уровня

 88 condition-name-1 { VALUE IS   } {literal-1 [ THRU|THROUGH literal-2 ]}...
                     { ~~~~~      }              ~~~~ ~~~~~~~
                     { VALUES ARE }
                       ~~~~~~

   [ WHEN SET TO FALSE IS literal-3 ] .
                 ~~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

Имена условий — это булевы (т.е. TRUE / FALSE) элементы данных, которые получают свои значения TRUE и FALSE на основе значений элемента данных без уровня 88, определение которого непосредственно следует за ними.

  1. Зарезервированные слова ARE, IS, SET и TO являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированные слова THRU и THROUGH взаимозаменяемы.
  3. Имена условий всегда определяются подчинено другому (не 88-уровневому) элементу данных. Этот элемент данных должен быть элементарным. Всякий раз, когда родительский элемент данных принимает одно из значений, указанных в пункте VALUE (см. VALUE) элемента 88-го уровня, condition-name-1 примет значение TRUE.
  4. Имена условий не занимают памяти.
  5. Необязательный пункт THROUGH позволяет указать диапазон возможных значений TRUE.
  6. Всякий раз, когда родительский элемент данных принимает любое значение, кроме одного из значений, указанных в пункте VALUE элемента condition-name-1, condition-name-1 примет значение FALSE.
  7. Выполнение оператора SET condition-name-1 TO TRUE заставит родительский элемент данных condition-name-1 принять первое значение, указанное в пункте VALUE элемента condition-name-1.
  8. Выполнение оператора SET condition-name-1 TO FALSE заставит родительский элемент данных condition-name-1 принять значение, указанное в пункте FALSE элемента condition-name-1. Если у condition-name-1 нет пункта FALSE, оператор SET (см. SET) сгенерирует сообщение об ошибке во время компиляции.
  9. Дополнительную информацию см. в разделе Имена условий.

6.9. Описания элементов данных

6.9.1. ANY LENGTH

Синтаксис атрибута ANY LENGTH

 ANY LENGTH
 ~~~ ~~~~~~

Этот синтаксис допустим в следующих разделах: LINKAGE

Элементы данных, объявленные с атрибутом ANY LENGTH, не имеют фиксированной длины во время компиляции. Такие элементы могут быть определены только в разделе связывания подпрограммы, так как они могут служить только описаниями аргументов подпрограммы. Эти элементы должны иметь пункт PICTURE (см. PICTURE), который указывает ровно один символ A, X или 9.

  1. Пункты ANY LENGTH и BASED (см. BASED) не могут использоваться вместе в одном описании элемента данных.

6.9.2. AUTO

Синтаксис атрибута AUTO

 AUTO
 ~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Поле, описание которого включает этот атрибут, заставит курсор автоматически переместиться к следующему полю экрана, которое можно ввести, если поле полностью заполнено входными данными.

  1. Пункты AUTO, AUTO-SKIP (см. AUTO-SKIP) и AUTOTERMINATE (см. AUTOTERMINATE) взаимозаменяемы и не могут использоваться вместе в одном описании элемента данных.

6.9.3. AUTO-SKIP

Синтаксис атрибута AUTO-SKIP

 AUTO-SKIP
 ~~~~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Поле, описание которого включает этот атрибут, заставит курсор автоматически переместиться к следующему полю экрана, которое можно ввести, если поле полностью заполнено входными данными.

  1. Пункты AUTO (см. AUTO), AUTO-SKIP и AUTOTERMINATE (см. AUTOTERMINATE) взаимозаменяемы и не могут использоваться вместе в одном описании элемента данных.

6.9.4. AUTOTERMINATE

AUTOTERMINATE Атрибут синтаксиса

 AUTOTERMINATE
 ~~~~~~~~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Поле, описание которого включает этот атрибут, заставит курсор автоматически перейти к следующему полю, поддерживающему ввод на экране, если поле полностью заполнено входными данными.

  1. Приведенные AUTO (см. AUTO), AUTO-SKIP (см. AUTO-SKIP) и AUTOTERMINATE пункты взаимозаменяемы и не могут использоваться вместе в описании одного и того же элемента данных.

6.9.5. BACKGROUND-COLOR

BACKGROUND-COLOR Атрибут синтаксиса

 BACKGROUND-COLOR|BACKGROUND-COLOUR IS integer-1 | identifier-1
 ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Этот пункт используется для указания цвета фона экрана для элемента данных экрана или цвета фона по умолчанию для подчиненных элементов, если он используется для группового элемента.

  1. Зарезервированное слово IS необязательно и может быть опущено. Наличие или отсутствие этого слова не оказывает влияния на программу.
  2. Зарезервированные слова BACKGROUND-COLOR и BACKGROUND-COLOUR взаимозаменяемы.
  3. Цвета можно указать по номеру (0-7) или используя имена констант, предоставленные в копибуке screenio.cpy (предоставляется со всеми дистрибутивами исходного кода GnuCOBOL).
  4. Цвета также можно указать с помощью числового неотредактированного идентификатора, значение которого находится в диапазоне 0-7.

Для составных DISPLAY атрибуты всегда применяются только к предыдущему элементу-источнику, но также позволяют изменять значение переменной или литералом, то есть

DISPLAY "Name: "   BACKGROUND-COLOR COB-YELLOW
         NAME-VAR  BACKGROUND-COLOR COB-BLACK
END-DISPLAY

См. Палитру цветов и атрибуты видео для получения дополнительной информации о цветах экрана и атрибутах видео.

6.9.6. BASED

BASED Атрибут синтаксиса

 BASED
 ~~~~~

Этот синтаксис допустим в следующих разделах: WORKING-STORAGE, LOCAL-STORAGE, LINKAGE

Элементы данных, объявленные с BASED, не выделяют памяти во время компиляции. Во время выполнения, ALLOCATE (см. ALLOCATE) или SET ADDRESS (см. УСТАНОВИТЬ АДРЕС) операторы используются для выделения памяти для таких элементов и (необязательно) их инициализации.

  1. BASED и ANY LENGTH (см. ЛЮБОЙ ДЛИНЫ) пункты не могут использоваться вместе в описании одного и того же элемента данных.
  2. BASED пункт может быть использован только для элементов данных уровня 01 и уровня 77.

6.9.7. BEEP

BEEP Атрибут синтаксиса

 BEEP
 ~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

  1. BEEP и BELL (см. ЗВОНОК) пункты взаимозаменяемы и не могут использоваться вместе в описании одного и того же элемента данных.
  2. Используйте этот пункт, чтобы вызвать звуковой сигнал при DISPLAY элементе экрана.

6.9.8. BELL

BELL Атрибут синтаксиса

 BELL
 ~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

  1. BEEP (см. BEEP) и BELL пункты взаимозаменяемы и не могут использоваться вместе в описании одного и того же элемента данных.
  2. Используйте этот пункт, чтобы вызвать звуковой сигнал при DISPLAY элементе экрана.

6.9.9. BLANK

BLANK Атрибут синтаксиса

 BLANK LINE|SCREEN
 ~~~~~ ~~~~ ~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Этот пункт очистит весь экран (BLANK SCREEN) или только строку, в которой данные будут отображаться (BLANK LINE).

  1. Очищенные области будут иметь цвета переднего и заднего плана, установленные в соответствии с атрибутами поля, содержащего BLANK пункт.
  2. Этот пункт полезен, когда один элемент экрана отображается поверх ранее отображенного.

6.9.10. BLANK WHEN ZERO

BLANK-WHEN-ZERO Атрибут синтаксиса

 BLANK WHEN ZERO
 ~~~~~      ~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

Этот пункт приведет к автоматическому преобразованию значения элемента в пробелы, если значение 0 когда-либо MOVE будет назначено элементу.

  1. Зарезервированное слово WHEN необязательно и может быть опущено. Наличие или отсутствие этого слова не оказывает влияния на программу.
  2. Этот пункт может использоваться только для элемента данных PIC 9 с USAGE (см. USAGE) значения DISPLAY.

6.9.11. BLINK

BLINK Атрибут синтаксиса

 BLINK
 ~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

BLINK пункт изменяет визуальное отображение поля, заставляя содержимое поля мигать.

См. Палитру цветов и атрибуты видео для получения дополнительной информации о цветах экрана и атрибутах видео.

6.9.12. COLUMN

COLUMN (РАЗДЕЛ ОТЧЕТА) Синтаксис пункта

 COLUMN [ { NUMBER IS   } ] [ +|PLUS ] integer-1 ]
 ~~~      { NUMBERS ARE }       ~~~~

COLUMN (РАЗДЕЛ ЭКРАНА) Синтаксис пункта

 COLUMN NUMBER IS [ +|PLUS ] integer-2 | identifier-3 ]
 ~~~                  ~~~~

Этот синтаксис допустим в следующих разделах: REPORT, SCREEN

Оператор COLUMN определяет колонку, в которой поле должно быть представлено на экране или в отчёте.

  1. Зарезервированные слова ARE, IS, NUMBER и NUMBERS являются необязательными и могут быть опущены. Их присутствие или отсутствие не влияет на программу.
  2. Зарезервированное слово COLUMN может быть сокращено до COL.
  3. Позиция строки поля в отчёте или на экране будет определена оператором LINE (см. LINE).
  4. Значение integer-1 должно быть 1 или больше.
  5. Если identifier-1 используется для указания абсолютной или относительной позиции столбца, identifier-1 должно быть определено как числовой элемент любого USAGE (см. USAGE), кроме COMPUTATIONAL-1 или COMPUTATIONAL-2, без редактирования символов. Значение identifier-1 в момент вывода данных на экран должно быть 1 или больше. Обратите внимание, что идентификатор COMPUTATIONAL-1 или COMPUTATIONAL-2 будет принят компилятором, но приведет к непредсказуемым результатам во время выполнения.
  6. Координата столбца поля может быть указана в абсолютном формате (например COLUMN 5) или в относительном формате, основанном на конце ранее выведенного поля (например COLUMN PLUS 1).
  7. Символ ‘+’ может быть использован вместо слова PLUS, если необходимо; однако, если используется символ ‘+’, должно быть хотя бы одно пробельное разделитель между ним и integer-1. Отсутствие пробела приведёт к тому, что символ ‘+’ будет просто обработан как часть integer-1, и оператор COLUMN будет интерпретироваться как абсолютная, а не относительная, спецификация столбца.
  8. Использование относительного позиционирования столбца (COLUMN PLUS) имеет несколько отличающееся поведение в зависимости от раздела, в котором используется оператор, как следует:
    1. При использовании в разделе отчёта COLUMN PLUS поместит начало значения нового поля так, чтобы между концом предыдущего поля и началом текущего поля было integer-1 пустых столбцов.

      Если описание элемента данных отчёта включает операторы SOURCE (см. SOURCE), SUM (см. SUM) или VALUE (см. VALUE), но не включает COLUMN, то COLUMN PLUS 1 будет предположено.

    2. При использовании в разделе экрана COLUMN PLUS разместит новое поле так, чтобы оно начиналось ровно на integer-1 или identifier-1 символов после последнего символа предыдущего поля. Таким образом, COLUMN PLUS 1 не оставит пустых позиций между концом предыдущего поля и началом текущего.

      Если описание элемента данных экрана включает операторы FROM (см. FROM), TO (см. TO), USING (см. USING) или VALUE (см. VALUE), но не включает COLUMN, новое поле на экране начнется в координате столбца последнего символа предыдущего поля.

6.9.13. CONSTANT

Синтаксис атрибута CONSTANT

 CONSTANT
 ~~~~~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, SCREEN

Этот параметр указывает, что элемент данных 01-уровня, в объявлении которого указан CONSTANT, будет рассматриваться как символическое имя для литерального значения, которое может быть использовано там, где может быть использован литерал соответствующего типа.

  1. Значение элемента данных, определенного как константа, не может быть изменено во время выполнения. Фактически, использование такого элемента данных в качестве целевого поля любого оператора раздела процедуры, который сохраняет значение, не допустимо с точки зрения синтаксиса.
  2. См. 01-Уровневые константы для дополнительной информации.

6.9.14. EMPTY-CHECK

Синтаксис атрибута EMPTY-CHECK

 EMPTY-CHECK
 ~~~~~~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Этот оператор требует от пользователя ввода данных в поле, для которого он указан (или во все подчиненные поля ввода, если EMPTY-CHECK указан для группового элемента).

  1. Операторы EMPTY-CHECK и REQUIRED (см. REQUIRED) взаимозаменяемы и не могут быть использованы вместе в описании одного элемента данных.
  2. Для активации этого оператора пользователь должен сначала переместить курсор в поле, для которого он определён.
  3. Оператор ACCEPT screen-data-item (см. ACCEPT screen-data-item) игнорирует клавишу Enter и любые другие клавиши перемещения курсора, которые могли бы переместить курсор в другой элемент экрана, если в поле не были введены данные. Функциональные клавиши всё ещё могут быть использованы для завершения ACCEPT.
  4. Для функционирования данного атрибута необходима поддержка подлежащего пакета «curses» в вашей реализации GnuCOBOL. На данный момент пакет «PDCurses» (используемый для нативных сборок Windows или MinGW) не поддерживает EMPTY-CHECK.

6.9.15. ERASE

Синтаксис оператора ERASE

 ERASE EOL|EOS
 ~~~~~ ~~~ ~~~

Этот синтаксис допустим в следующих разделах: SCREEN

ERASE очистит содержимое экрана с места отображения элемента данных экрана, описание которого содержит эту клаузу, до конца экрана (ERASE EOS)

  1. Очищенные области получат цвета переднего и заднего плана, соответствующие атрибутам поля, содержащего клаузу ERASE.
  2. Эта клауза полезна, когда один элемент экрана отображается поверх ранее отображенного.

См. Цветовая палитра и атрибуты видео для получения дополнительной информации о цветах экрана и атрибутах видео.

6.9.16. EXTERNAL

Синтаксис атрибута EXTERNAL

 EXTERNAL
 ~~~~~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE

Эта клауза отмечает описание элемента данных, FD или SD, как доступное для обмена с другими программами, выполняемыми из того же потока выполнения. См. Описание файла/сортировки.

  1. Указав клаузу EXTERNAL в описании файла или FD, или SD, описание файла может быть общим для всех программ, выполняемых из одного потока выполнения, при условии, что клауза EXTERNAL с описанием файла прописана в каждой программе, которой оно необходимо. Это совместное использование позволяет открывать, читать и/или записывать и закрывать файл в различных программах. Это совместное использование также распространяется на описания записей, подчиненных описанию файла.
  2. Указав клаузу EXTERNAL в описании элемента данных, этот элемент может быть общим для всех программ, выполняемых из того же потока выполнения, при условии, что элемент данных прописан (с клаузой EXTERNAL) в каждой программе, которой он нужен.
  3. Следующие моменты относятся к указанию EXTERNAL в определении элемента данных:
    1. Клаузу EXTERNAL можно указывать только на уровнях 77 или 01.
    2. Элемент EXTERNAL должен иметь имя данных, которое не может быть FILLER.
    3. EXTERNAL нельзя комбинировать с BASED (см. BASED), GLOBAL (см. GLOBAL) или REDEFINES (см. REDEFINES).

6.9.17. FALSE

Синтаксис клаузы FALSE

 WHEN SET TO FALSE IS literal-1
             ~~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

Эта клауза, которая может появляться только в определении имени условия уровня 88, используется для указания значения элемента данных, являющегося родителем имени условия уровня 88, которое заставит имя условия принять значение FALSE.

  1. Зарезервированные слова IS, SET, TO и WHEN являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. См. Элементы данных уровня 88 или Имена условий для получения дополнительной информации.

6.9.18. FOREGROUND-COLOR

Синтаксис атрибута FOREGROUND-COLOR

 FOREGROUND-COLOR|FOREGROUND-COLOUR IS integer-1 | identifier-1
 ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Эта клауза используется для указания цвета текста в элементе данных экрана или цвета текста по умолчанию для подчиненных элементов, если она используется в групповом элементе.

  1. Зарезервированное слово IS является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Зарезервированные слова FOREGROUND-COLOR и FOREGROUND-COLOUR взаимозаменяемы.
  3. Цвета задаются числом (0-7) или с использованием имен констант, предоставленных в копибуке screenio.cpy (который предоставляется со всеми дистрибутивами исходного кода GnuCOBOL).
  4. Цвета также можно задать с помощью числового неотредактированного идентификатора, значение которого находится в диапазоне от 0 до 7.

См. Цветовая палитра и атрибуты видео для получения дополнительной информации о цветах экрана и атрибутах видео.

6.9.19. FROM

Синтаксис клаузы FROM

 FROM literal-1 | identifier-5
 ~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Эта клауза используется для указания элемента данных, от которого поле секции экрана получает значение при отображении экрана, или литерала, который задаст значение этого поля.

  1. Клаузы FROM, TO (см. TO), USING (см. USING) и VALUE (см. VALUE) взаимоисключают друг друга в определении любого элемента данных секции экрана.

6.9.20. FULL

Синтаксис атрибута FULL

 FULL
 ~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Клауза FULL заставляет пользователя вводить данные в поле, для которого она указана (или во все подчиненные поля, способные принимать ввод, если она указана для группового элемента), достаточно для заполнения всех позиций символов поля.

  1. Операторы FULL и LENGTH-CHECK (см. LENGTH-CHECK) взаимозаменяемы и не могут использоваться вместе в одном описании элемента данных.
  2. Для того, чтобы этот оператор вступил в силу во время выполнения, пользователь должен переместить курсор в поле, в определении которого он указан.
  3. Оператор ACCEPT screen-data-item (см. ACCEPT screen-data-item) проигнорирует клавишу Enter и любые другие клавиши перемещения курсора, которые могли бы переместить курсор на другой элемент экрана, если в поле не было введено необходимое количество данных. Однако функциональные клавиши по-прежнему будут разрешены для завершения ACCEPT.
  4. Для функционирования этого атрибута он должен поддерживаться базовым пакетом «curses», с которым была построена ваша реализация GnuCOBOL. На данный момент пакет «PDCurses» (используемый для нативных сборок Windows или MinGW) не поддерживает FULL.

6.9.21. GLOBAL

GLOBAL Атрибут Синтаксис

 GLOBAL
 ~~~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, REPORT

Этот оператор помечает элемент данных, константу уровня 01, FD (см. Описание файла/сортировки), SD (см. Описание файла/сортировки) или RD (см. Раздел отчета) как разделяемый с любыми вложенными подпрограммами.

  1. Указав оператор GLOBAL в описании файла или отчета, это описание может быть разделено между программой и любыми вложенными подпрограммами в ней, при условии, что оператор FD, SD или RD (с оператором GLOBAL) закодирован в каждой вложенной подпрограмме, требующей его. Эта совместная работа позволяет файлу открываться, читаться и/или записываться, а также закрываться, или отчёту запускаться или завершаться в этих программах. Разные скомпилированные программы не могут использовать общее описание файла GLOBAL, но они могут использовать общее описание файла EXTERNAL (см. EXTERNAL). Эта совместная работа распространяется также на описания записей, подчиненные описанию файла, и на группы отчетов, подчиненные описанию RD.
  2. Указав оператор GLOBAL в описании элемента данных, этот элемент данных может быть разделен между программой и любыми вложенными подпрограммами в ней, при условии, что элемент данных закодирован (с оператором GLOBAL ) в каждой программе, которая его требует.
  3. Следующие моменты относятся к указанию GLOBAL в определении элемента данных:
    1. Оператор GLOBAL может быть указан только на уровне 77 или 01.
    2. Элемент GLOBAL должен иметь имя данных, и это имя не может быть FILLER.
    3. GLOBAL не может быть объединён с EXTERNAL (см. EXTERNAL), REDEFINES (см. REDEFINES) или BASED (см. BASED).

6.9.22. GROUP INDICATE

GROUP-INDICATE Атрибут Синтаксис

 GROUP INDICATE
 ~~~~~ ~~~~~~~~

Этот синтаксис допустим в следующих разделах: REPORT

Оператор GROUP INDICATE указывает, что элемент данных, в определении которого он указан, будет отображаться только в очень ограниченных обстоятельствах.

  1. Этот оператор может быть указан только внутри группы отчета DETAIL (см. TYPE).
  2. При наличии этого оператора, элемент данных в вопросе будет отображаться только при следующих обстоятельствах:
    1. При первом отображении детализированной группы после INITIATE (см. INITIATE) отчета.
    2. При первом отображении детализированной группы после начала каждой новой страницы.
    3. При первом отображении детализированной группы после любого разрыва контроля.

6.9.23. HIGHLIGHT

HIGHLIGHT Атрибут Синтаксис

 HIGHLIGHT
 ~~~~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Этот оператор управляет интенсивностью текста (FOREGROUND-COLOR (см. FOREGROUND-COLOR)), установив эту интенсивность на максимальное из трёх возможных значений.

  1. Этот оператор, наряду с оператором LOWLIGHT (см. LOWLIGHT), предназначен для обеспечения трёхступенчатой схемы интенсивности (LOWLIGHT … ничего (Нормальный) … HIGHLIGHT).

См. Цветовая палитра и видеоатрибуты, для получения дополнительной информации о цветах экрана и видеоатрибутах.

6.9.24. JUSTIFIED

JUSTIFIED Атрибут Синтаксис

 JUSTIFIED RIGHT
 ~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

Наличие оператора JUSTIFIED RIGHT в определении элемента данных изменяет способ хранения данных в поле с дефолтного «выравнивания по левому краю, заполнение пробелами» на «выравнивание по правому краю, заполнение пробелами».

  1. Зарезервированное слово RIGHT необязательно и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Зарезервированное слово JUSTIFIED может быть сокращено до JUST.
  3. Этот пункт действителен только для символьных (PIC A) или буквенно-цифровых (PIC X) данных.
  4. Наличие или отсутствие этого пункта влияет на поведение оператора MOVE (см. MOVE), а также описания данных FROM (см. FROM), SOURCE (см. SOURCE) и USING (см. USING).
  5. Если значение, сохраняемое в поле, имеет такую же длину, как и принимающее поле, наличие или отсутствие пункта JUSTIFIED RIGHT в описании этого поля не имеет значения.
  6. Следующие примеры иллюстрируют поведение наличия и отсутствия пункта JUSTIFIED RIGHT в случае, когда размер поля отличается от размера сохраняемого значения. В этих примерах символ b представляет пробел.

    Когда значение короче размера поля:

    Без JUSTIFIED С JUSTIFIED
    01  A PIC X(6).
    MOVE @code{ABC} TO A
    
    01  A PIC X(6) JUSTIFIED RIGHT.
    MOVE @code{ABC} TO A
    
    Результат Результат
    ABCbbb bbbABC

    Когда значение длиннее размера поля:

    Без JUSTIFIED С JUSTIFIED
    01  A PIC X(6).
    MOVE 'ABCDEFGHI' TO A
    
    01  A PIC X(6) JUSTIFIED RIGHT.
    MOVE 'ABCDEFGHI' TO A
    
    Результат Результат
    ABCDEF DEFGHI

6.9.25. LEFTLINE

LEFTLINE Атрибут Синтаксис

 LEFTLINE
 ~~~~~~~~

Этот синтаксис действителен в следующих разделах: SCREEN

Пункт LEFTLINE добавит вертикальную линию на левом краю поля экрана.

  1. Пункты LEFTLINE, OVERLINE (см. OVERLINE) и UNDERLINE (см. UNDERLINE) могут быть использованы в любой комбинации в описании одного поля.
  2. Этот пункт фактически не функционален при использовании в средах командной оболочки Windows (cmd.exe) и при выполнении программ, скомпилированных с использованием реализации GnuCOBOL, построенной на основе «PDCurses» (например, сборки Windows/MinGW).
  3. Будет ли этот пункт работать в системах Cygwin или UNIX/Linux/OSX, зависит от возможностей атрибутов видео вывода терминала и используемого программного обеспечения «curses».

См. Цветовая палитра и атрибуты видео для получения дополнительной информации о цветах экрана и атрибутах видео.

6.9.26. LENGTH-CHECK

LENGTH-CHECK Атрибут Синтаксис

 LENGTH-CHECK
 ~~~~~~~~~~~~

Этот синтаксис действителен в следующих разделах: SCREEN

Пункт LENGTH-CHECK заставляет пользователя вводить данные в поле, для которого он указан (или во все подчиненные поля, если указан для группового элемента), достаточные для заполнения каждой позиции символа в поле.

  1. Пункты FULL (см. FULL) и LENGTH-CHECK взаимозаменяемы и не могут использоваться вместе в одном описании данных.
  2. Для того, чтобы этот пункт вступил в действие во время выполнения, пользователь должен переместить курсор в поле, в котором этот пункт указан в его определении.
  3. Оператор ACCEPT screen-data-item (см. ACCEPT screen-data-item) проигнорирует нажатие клавиши Enter и любые другие нажатия клавиш перемещения курсора, которые могли бы переместить курсор в другой элемент экрана, пока не будет введено необходимое количество данных в поле. Функциональные клавиши все же будут разрешены для завершения ACCEPT, однако.
  4. Для функционирования этот атрибут должен поддерживаться базовым пакетом «curses» вашей реализации GnuCOBOL. На данный момент пакет «PDCurses» (используемый для собственных сборок Windows или MinGW) не поддерживает LENGTH-CHECK.

6.9.27. LINE

LINE (РАЗДЕЛ ОТЧЕТА) Синтаксис пункта

 LINE NUMBER IS { integer-2 [ [ ON NEXT PAGE ] }
 ~~~~           {                  ~~~~ ~~~~   }
                { +|PLUS integer-2             }
                {   ~~~~                       }
                { ON NEXT PAGE                 }
                     ~~~~ ~~~~

LINE (РАЗДЕЛ ЭКРАНА) Синтаксис пункта

 [ LINE NUMBER IS [ +|PLUS ] integer-4 | identifier-6 ]
   ~~~~               ~~~~

Этот синтаксис действителен в следующих разделах: REPORT, SCREEN

Этот пункт предоставляет возможность явно указать, на какой строке должно быть представлено поле на окне консоли (раздел экрана) или в отчете (раздел отчета).

  1. Зарезервированные слова IS, NUMBER и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Следующие пункты описывают использование формата 1 пункта LINE:
    1. Положение столбца элемента отчета определяется пунктом COLUMN (см. COLUMN).
    2. Значение integer-1 должно быть 1 или больше.
    3. Номер строки отчета, на которой будет отображаться элемент данных, содержащий этот пункт, а также любые подчиненные элементы данных, может быть указан в абсолютном формате (например LINE 5) или в относительном формате, основанном на ранее отображенной строке (например LINE PLUS 1).
    4. Символ ‘+’ может быть использован вместо слова PLUS, если это необходимо; однако, если используется ‘+’, между ним и integer-1 должен быть хотя бы один пробел. Отсутствие пробела приведет к тому, что ‘+’ будет просто считаться частью integer-1, и пункт LINE будет интерпретирован как абсолютная спецификация строки, а не относительная.
    5. Необязательный пункт NEXT PAGE указывает, что — независимо от того, может ли группа отчета поместиться на текущей странице отчета, она будет вынужденно отображаться на новой странице.
  3. Следующие пункты описывают использование формата 2 пункта LINE:
    1. Положение столбца поля раздела экрана определяется пунктом COLUMN (см. COLUMN).
    2. Значение integer-1 должно быть 1 или больше.
    3. Если identifier-1 используется для указания абсолютного или относительного положения столбца, identifier-1 должен быть определен как числовой элемент любого типа USAGE (см. USAGE), кроме COMPUTATIONAL-1 или COMPUTATIONAL-2, без редактирования символов. Значение identifier-1 в момент отображения элемента данных экрана должно быть 1 или больше. Обратите внимание, что идентификаторы COMPUTATIONAL-1 или COMPUTATIONAL-2 будут приняты компилятором, но могут привести к непредсказуемым результатам во время выполнения.
    4. Номер строки экрана, на которой будет отображаться элемент данных, содержащий этот пункт, а также любые подчиненные элементы данных, может быть указан в абсолютном формате (например LINE 5) или в относительном формате, основанном на ранее отображенной строке (например LINE PLUS 1).
    5. Символ ‘+’ может быть использован вместо слова PLUS, если это необходимо; однако, если используется ‘+’, между ним и integer-1 должен быть хотя бы один пробел. Отсутствие пробела приведет к тому, что ‘+’ будет просто считаться частью integer-1, и пункт LINE будет интерпретирован как абсолютная спецификация строки, а не относительная.
    6. Если описание элемента данных экрана включает пункты FROM (см. FROM), TO (см. TO), USING (см. USING) или VALUE (см. VALUE), но не содержит пункта LINE, будет предполагаться «текущая строка экрана».

6.9.28. LOWLIGHT

Синтаксис атрибута LOWLIGHT

 LOWLIGHT
 ~~~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Пункт LOWLIGHT управляет интенсивностью текста (FOREGROUND-COLOR) путем установки этой интенсивности на минимальное из трех возможных значений.

  1. Этот пункт, наряду с HIGHLIGHT (см. HIGHLIGHT), предназначен для обеспечения трехступенчатой схемы интенсивности (LOWLIGHT … ничего (Нормальное) … HIGHLIGHT). В средах, таких как консоль Windows, где поддерживается только два уровня интенсивности, LOWLIGHT эквивалентен опущению этого пункта.

См. Цветовая палитра и видеоатрибуты для получения дополнительной информации о цветах экрана и видеоатрибутах.

6.9.29. NEXT GROUP

Синтаксис пункта NEXT-GROUP

 NEXT GROUP IS { [ +|PLUS ] integer-2  }
 ~~~~ ~~~~~    {     ~~~~              }
               { NEXT|{NEXT PAGE}|PAGE }
                 ~~~~  ~~~~ ~~~~  ~~~~

Этот синтаксис допустим в следующих разделах: REPORT

Этот пункт определяет правила, согласно которым следующая группа, подлежащая отображению в отчете, начнется с точки зрения строк относительно последней строки группы, в которой этот пункт появляется.

  1. Зарезервированное слово IS является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Термины NEXT, NEXT PAGE и PAGE взаимозаменяемы.
  3. Группа отчета должна содержать по крайней мере один пункт LINE NUMBER для того, чтобы также содержать пункт NEXT GROUP.
  4. Если пункт RD (см. РАЗДЕЛ ОТЧЕТА) в котором находится группа отчета, содержащая пункт NEXT GROUP, не содержит пункта PAGE LIMITS, может быть указан только параметр PLUS integer-1.
  5. Параметр NEXT PAGE не может быть использован в PAGE FOOTING.
  6. Параметр NEXT GROUP не может быть указан ни в REPORT HEADING, ни в PAGE HEADING.
  7. Эффекты NEXT GROUP будут дополнять любой интервал строк, определенный пунктом LINE NUMBER следующей отображаемой группы.

6.9.30. NO-ECHO

Синтаксис атрибута NO-ECHO

 NO-ECHO
 ~~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Оператор NO-ECHO заставит все данные, введенные в поле, отображаться на экране звёздочками.

  1. Операторы NO-ECHO и SECURE (см. SECURE) взаимозаменяемы и не могут использоваться вместе в одном описании элемента данных.
  2. Данный оператор может быть использован только в поле, допускающем ввод данных (поле, содержащее оператор USING (см. USING) или TO (см. TO)).

Дополнительную информацию о цветовых палитрах и атрибутах видео см. в разделе Цветовая палитра и атрибуты видео.

6.9.31. OCCURS

Синтаксис оператора OCCURS (раздел отчёта)

 OCCURS [ integer-1 TO ] integer-2 TIMES
 ~~~~~~             ~~
   [ DEPENDING ON identifier-1 ]
     ~~~~~~~~~
   [ STEP integer-3 ]
     ~~~~
   [ VARYING identifier-2 FROM { identifier-3 } BY { identifier-4 } ]
     ~~~~~~~              ~~~~ { integer-4    } ~~ { integer-5    }

Синтаксис оператора OCCURS (раздел экрана)

 OCCURS integer-2 TIMES
 ~~~~~~

Синтаксис оператора OCCURS (все остальные разделы)

 OCCURS [ integer-1 TO ] integer-2 TIMES
 ~~~~~~             ~~
      [ DEPENDING ON identifier-1 ]
        ~~~~~~~~~
      [ ASCENDING|DESCENDING KEY IS identifier-5... ]...
        ~~~~~~~~~ ~~~~~~~~~~
      [ INDEXED BY identifier-6 ]
        ~~~~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

Оператор OCCURS используется для создания структуры данных, называемой таблицей, где записи в этой структуре повторяются многократно.

  1. Зарезервированные слова BY (INDEXED), IS, KEY, ON и TIMES являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Значение integer-2 определяет, сколько записей будет выделено в таблице.
  3. Ниже приведен пример того, как может быть определена таблица:
    05 QUARTERLY-REVENUE OCCURS 4 TIMES PIC 9(7)V99.
    

    Это выделит следующее:

    QUARTERLY-REVENUE(1)
    QUARTERLY-REVENUE(2)
    QUARTERLY-REVENUE(3)
    QUARTERLY-REVENUE(4)
    

    Каждая запись ссылается с использованием синтаксиса индексации (числовой литерал, арифметическое выражение или числовой идентификатор в скобках), показанного выше.

  4. Оператор OCCURS также может использоваться на уровне группы, в этом случае вся структура группы повторяется, как показано ниже:
    05 GRP OCCURS 3 TIMES.
        10 A     PIC X(1).
        10 B     PIC X(1).
        10 C     PIC X(1).
    

    Это позволит ссылаться на любое из следующего:

    GRP(1)   includes A(1), B(1) and C(1)
    GRP(2)   includes A(2), B(2) and C(2)
    GRP(3)   includes A(3), B(3) and C(3)
    

    или каждый элемент A, B, C можно ссылаться следующим образом:

    A(1)   character #1 of GRP(1)
    B(1)   character #2 of GRP(1)
    C(1)   character #3 of GRP(1)
    A(2)   character #1 of GRP(2)
    B(2)   character #2 of GRP(2)
    C(2)   character #3 of GRP(2)
    A(3)   character #1 of GRP(3)
    B(3)   character #2 of GRP(3)
    C(3)   character #3 of GRP(3)
    
  5. Необязательный оператор DEPENDING ON может быть добавлен к OCCURS для создания таблицы переменной длины. В таких случаях значение integer-1 определяет минимальное количество записей в таблице, а integer-2 — максимальное. Такие таблицы будут выделены до максимального размера, указанного как integer-2. Во время выполнения значение identifier-1 определит, сколько элементов таблицы доступно.
  6. Для получения объяснений операторов SEARCH (см. SEARCH), SEARCH ALL (см. SEARCH ALL) и SORT (см. SORT) см. документацию операторов KEY и INDEXED BY.
  7. Оператор OCCURS не может быть указан в записи описания данных, имеющей уровень 01, 66, 77 или 88, хотя он допустим в элементах данных, описанных подчинённо элементу данных уровня 01.
  8. Следующие пункты относятся к оператору OCCURS в разделе отчёта:
    1. Необязательный оператор STEP определяет значение приращения, которое будет добавляться к любым абсолютным значениям LINE (см. LINE) или COLUMN (см. COLUMN), которые могут быть частью или подчинены определению этого элемента данных.
    2. Необязательный оператор VARYING определяет идентификатор, который может быть использован в качестве индекса для множественных вхождений этого или любого подчиненного элемента данных, если оператор SOURCE (см. SOURCE) или SUM (см. SUM) в этом или подчиненных элементах данных ссылается на записи в таблице. Элемент данных identifier-2 динамически создается по мере необходимости и не может быть использован за пределами области определения элемента данных отчёта.
    3. Два следующих примера иллюстрируют два различных способа включения в отчёт данных о продажах за четыре квартала — один «сложным способом» и один с использованием расширенных возможностей операторов OCCURS из STEP и VARYING. Оба примера предполагают определение следующей таблицы в рабочем хранилище:
      05 SALES OCCURS 4 TIMES PIC 9(7)V99.

      Сначала «Сложный способ»:

      10 COL 7  PIC $(7)9.99 SOURCE SALES(1).
      10 COL 17 PIC $(7)9.99 SOURCE SALES(2).
      10 COL 27 PIC $(7)9.99 SOURCE SALES(3).
      10 COL 37 PIC $(7)9.99 SOURCE SALES(4).
      

      А затем с использованием STEP и VARYING:

      10 COL 7  OCCURS 4 TIMES STEP 10 VARYING QTR FROM 1 BY 1
                PIC $(7)9.99 SOURCE SALES(QTR).
      

6.9.32. OVERLINE

Синтаксис атрибута OVERLINE

 OVERLINE
 ~~~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Оператор OVERLINE нарисует горизонтальную линию в верхней части поля экрана.

  1. Оператор LEFTLINE (см. LEFTLINE), OVERLINE и UNDERLINE (см. UNDERLINE) могут быть использованы в любом сочетании в описании одного поля.
  2. Этот оператор фактически не выполняет никаких функций при использовании в средах командной оболочки Windows (cmd.exe) и при запуске программ, скомпилированных с использованием реализации GnuCOBOL, построенной на базе «PDCurses» (например, сборки Windows/MinGW).
  3. Будет ли этот оператор работать в системах Cygwin или UNIX/Linux/OSX, зависит от возможностей атрибутов видео драйверов терминального вывода и используемого программного обеспечения «curses».

См. Цветовые палитры и атрибуты видео для получения дополнительной информации о цветах экрана и атрибутах видео.

6.9.33. PICTURE

Синтаксис оператора PICTURE

 PICTURE IS picture-string
 ~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

Оператор PICTURE определяет класс (числовой, алфавитный или буквенно-цифровой), размер и формат данных, которые могут храниться в определяемом элементе данных. Иногда эту роль выполняет оператор USAGE (см. USAGE), а в некоторых случаях эта роль полностью возлагается на этот оператор.

  1. Зарезервированное слово IS является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Зарезервированное слово PICTURE может быть сокращено до PIC. Большинство программистов предпочитают использовать последнее.
  3. Оператор PICTURE может быть указан только для элементарных элементов.
  4. picture-string — это последовательность специальных символов: ‘$’, ‘*’, ‘+’, ‘,’, ‘-’, ‘.’, ‘/’, ‘0’ (ноль), ‘9’, ‘A’, ‘B’, CR, DB, ‘S’, ‘V’, ‘X’ и ‘Z’.
  5. В общем случае, каждый символ PICTURE представляет либо один символ в памяти, либо одну десятичную цифру. Есть несколько исключений, которые будут рассмотрены по мере необходимости.
  6. Когда picture-string содержит повторяющуюся последовательность символов — PIC 9999/99/99 — например, повторение можно указать с помощью указания числа повторений в скобках, как в PIC 9(4)/9(2)/9(2). Использование указаний повторений является необязательным, и их использование (или отсутствие) полностью зависит от программиста. Многие программисты используют повторение для небольших последовательностей (PIC XXX) и указания повторений для более крупных (%%%CODE_BLOCK_2132%%).
  7. Этот первый набор символов PICTURE определяет базовый тип данных элемента данных. Каждый символ представляет один символ памяти.
    ‘A’

    Определяет память, зарезервированную для одного буквенного символа (‘A’-‘Z’, ‘a’-‘z’).

    ‘N’

    Определяет память, зарезервированную для одного символа в национальном наборе символов компьютера. Поддержка национальных наборов символов в GnuCOBOL в настоящее время реализована частично, и действие символа ‘N’ в PICTURE аналогично тому, как если бы был набран X(2), с дополнительным эффектом, что такое поле будет квалифицироваться как поле NATIONAL или NATIONAL-EDITED в операторе INITIALIZE (см. INITIALIZE).

    ‘X’

    Определяет память, зарезервированную для одного буквенно-цифрового символа (любого символа).

    ‘9’

    Определяет память, зарезервированную для одного цифрового символа (‘0’-‘9’).

    Обычно в одном операторе PICTURE используется только один тип каждого из этих символов, но это не обязательно. Элементы данных, использующие только символы ‘A’ среди вышеперечисленных символов, называются алфавитными элементами данных, в то время как те, которые используют символы ‘9’ без символов ‘A’ или ‘X’ (или имеющие USAGE без PICTURE) называются числовыми элементами данных. Все остальные элементы данных называются буквенно-цифровыми элементами данных.

    Если вам нужно выделить место для элемента данных, имеющего формат из двух букв, за которыми следуют пять цифр и три буквы, вы можете использовать picture-string AA99999AAA, A(2)9(5)A(3) XXXXXXXXXX или X(10). Абсолютно нет никакой функциональной разницы между этими четырьмя вариантами — ни один из них не предоставляет функциональность, которой не обладают другие. Первые два, вероятно, лучше отражают документацию ожидаемого содержимого поля, но они не предоставляют возможностей проверки во время выполнения.

    Однако с точки зрения проверки как алфавитные, так и числовые строки PICTURE обеспечивают возможности проверки как на этапе компиляции, так и на этапе выполнения. В случае проверки на этапе компиляции компилятор может выводить предупреждающие сообщения, если вы пытаетесь указать нечисловое значение для числового элемента данных или пытаетесь MOVE (см. MOVE) нечисловой элемент данных в числовой. Аналогичные возможности существуют для алфавитных элементов данных. Во время выполнения вы можете использовать специальный тест класса (см. Условия класса), чтобы определить, содержит ли элемент данных только цифровые или только буквенные данные.

  1. Следующие символы картинок могут быть использованы с числовыми элементами данных.
    ‘P’

    Определяет предполагаемую позицию цифры, которая будет рассматриваться как ноль при обращении к элементу данных во время выполнения. Этот символ используется для того, чтобы элементы данных, которые будут содержать очень большие значения, можно было выделять с меньшим объемом памяти, предполагая наличие определенного количества конечных нулей (по одному на ‘P’) в конце значений.

    Символ ‘P’ не допускается в сочетании с ‘N’.

    Символ ‘P’ может использоваться только в начале или конце пункта изображения.

    ‘P’ — это повторяющийся символ.

    Все вычисления и операции MOVE (см. MOVE) с таким элементом данных будут выполняться так, как если бы нули были фактически там.

    Например, предположим, что вам нужно выделить элемент данных, который содержит количество миллионов долларов выручки вашей компании в этом году:

    01 Gross-Revenue PIC 9(9).

    В этом случае будет зарезервировано 9 символов памяти. Значения от 000000000 до 999999999 будут представлять валовую выручку. Но если отслеживаются только миллионы (то есть последние шесть цифр всегда будут 0), вы можете определить поле как:

    01 Gross-Revenue PIC 9(3)P(6).

    Всякий раз, когда выручка Gross-Revenue используется в расчетах или когда ее значение перемещается в другой элемент данных, значение Gross-Revenue будет рассматриваться так, как если бы оно было nnn000000, где nnn — фактическое значение в памяти.

    Если вы хотите сохранить значение 128 миллионов в этом поле, вы сделаете это, как если бы ‘P’ были ‘9’:

    MOVE 128000000 TO Gross-Revenue
    

    Вывод DISPLAY (см. DISPLAY) элемента данных, содержащего символы ‘P’, немного необычен. Выводимое значение будет таким, какое фактически хранится в памяти, но общий размер выводимого значения будет таким, как если бы символы ‘P’ были заменены на ‘9’. Таким образом, после выполнения вышеуказанного оператора для Gross-Revenue, DISPLAY Gross-Revenue выведет вывод ‘000000128’.

    ‘S’

    Если этот символ используется, он должен быть первым символом в значении PICTURE. ‘S’ указывает, что элемент данных является Signed, то есть для этого элемента данных возможны отрицательные значения. Без ‘S’ любые отрицательные значения, записанные в этот элемент данных с помощью MOVE или арифметического оператора, будут лишены отрицательного знака (фактически становясь абсолютным значением).

    Символ ‘S’ не допускается в сочетании с ‘N’.

    Символ ‘S’ может встречаться только один раз в строке изображения. См. SIGN IS для получения дополнительной информации о том, как хранить отрицательные значения в числовом элементе данных.

    ‘V’

    Этот символ используется для определения расположения предполагаемой десятичной точки (если она есть) в числовом элементе. Так же как может быть только одна десятичная точка в числе, так и ‘V’ не может быть более одного в PICTURE. Предполагаемые десятичные точки не занимают места в памяти — они просто определяют, как используются значения. Например, если значение 1234 находится в памяти в поле, определенном как PIC 999V9, это значение будет интерпретироваться как 123,4 в любых операциях, в которых оно упоминается.

    Символ ‘V’ не допускается в сочетании с ‘N’.

    Символ ‘V’ может встречаться только один раз в строке изображения.

  2. Любые символы редактирования, введенные после этой точки, если они закодированы в пункте изображения иначе числового элемента данных, преобразуют этот элемент данных из числового в редактируемый числовой элемент данных. Редактируемые числовые элементы данных обрабатываются как буквенно-цифровые и не могут использоваться в качестве индексов таблиц или в качестве аргументов источника в арифметическом операторе.
  3. Ниже приведены фиксированные символы редактирования вставки, которые могут быть указаны в строке изображения. Каждый из этих символов редактирования вставит специальный символ в значение поля в позиции, указанной в строке изображения. Эти символы редактирования каждый добавляют один дополнительный символ в общий размер поля для каждого вхождения символа в строке изображения.
    ‘B’

    Символ редактирования вставки ‘B’ вставляет пробел в значение поля для каждого вхождения.

    Можно закодировать несколько символов ‘B’.

    Следующий пример отформатирует десятизначное число (вероятно, телефонный номер) в формате ‘### ### ####’:

        ...
            05 Phone-Number       PIC 9(3)B9(3)B9(4).
        ...
            MOVE 5185551212 TO Phone-Number
            DISPLAY Phone-Number
    

    Этот код отобразит ‘518 555 1212’.

    ‘0’

    Символ редактирования вставки ‘0’ (ноль) вставляет один символ «0» в значение поля для каждого вхождения в строку изображения.

    Можно закодировать несколько символов ‘0’.

    Вот пример:

        ...
            05  Output-Item     PIC 909090909.
        ...
            MOVE 12345 TO Output-Item
            DISPLAY Output-Item
    

    Вышеупомянутое отобразит ‘102030405’.

    ‘/’

    Символ редактирования вставки ‘/’ вставляет один символ «/» в значение поля для каждого вхождения в строку изображения.

    Можно закодировать несколько символов ‘/’.

    Этот символ редактирования чаще всего используется для форматирования дат, как показано ниже:

        ...
            05  Year-Month-Day   PIC 9(4)/9(2)/9(2).
        ...
            MOVE 20140207 TO Year-Month-Day
            DISPLAY Year-Month-Day
    

    Этот пример отобразит ‘2014/02/07’.

  1. Ниже приведены символы числового форматирования, которые могут быть указаны в строке изображения. Каждый из этих символов редактирования вставит специальные символы в значение поля, чтобы представить числа в «дружественном» формате. Каждый из этих символов редактирования добавит по одному дополнительному символу к общему размеру поля для каждого вхождения символа в строку изображения. Числовые поля, чья строка описания содержит эти символы, не могут использоваться в качестве исходных полей в любом вычислении, ни могут служить исходными полями для передачи значений данных ни в какой элемент данных, кроме алфавитно-цифрового поля.
    ‘.’

    Символ ‘.’ вставляет десятичную точку в числовое значение поля. Когда содержимое числового элемента отправляющего поля перемещается в элемент принимающего поля, чья строка описания содержит символ редактирования ‘.’, неявная (‘V’) или фактическая десятичная точка в элементе отправляющего поля или литерале, соответственно, будет выровнена со символом ‘.’ в принимающем поле. Затем цифры передаются из отправляющего поля в принимающее поле, начиная от ‘V’ или ‘.’ отправляющего поля, усекая цифры отправляющего поля, если в принимающем поле не хватает позиций. Любые позиции цифр в принимающем поле, которые не получают цифры из отправляющего поля, если таковые имеются, будут установлены в 0.

    Символ ‘.’ не допускается в сочетании с ‘N’.

    Пример, вероятно, поможет:

        ...
        05  Source-Field   PIC 9(2)V9 VALUE 7.2.
        05  Dest-Field     PIC 9(5).9(2).
        ...
        MOVE 1234567.89 TO Dest-Field
        DISPLAY Dest-Field
        MOVE 19 TO Dest-Field
        DISPLAY Dest-Field
        MOVE Source-Field TO Dest-Field
        DISPLAY Dest-Field
    

    Пример покажет три результата — ‘34567.89’, ‘00019.00’ и ‘00007.20’.

    Оба определения элементов данных, похоже, содержат две десятичные точки в своих строках описания. На самом деле это не так, потому что последний символ каждого определения элемента данных всегда является точкой — точка, которая завершает определение.

    ‘,’

    Символ ‘,’ служит разделителем тысяч. Часто вы видите большие числа, отформатированные с этими символами — например, 123 456 789. Это можно легко сделать, добавив символы разделителей тысяч в строку описания. Разделители тысяч, которые не нужны, будут вести себя так, как если бы они были ‘9’.

    Символ ‘,’ не допускается в сочетании с ‘N’.

    Вот пример:

        ...
        05  My-Lottery-Winnings   PIC 9(3),9(3),9(3).
        ...
        MOVE 12345 TO My-Lottery-Winnings
        DISPLAY My-Lottery-Winnings
    

    Будет отображено значение ‘0000012 345’ (очень разочаровывающее для моих планов на пенсию, но хорошая демонстрация разделителей тысяч). Обратите внимание, как, поскольку первая запятая не была нужна из-за скудного количества, которое я выиграл, она вела себя как ещё одна ‘9’.

    При желании вы можете изменить роли символов редактирования ‘.’ и ‘,’, указав DECIMAL POINT IS COMMA в SPECIAL-NAMES (см. SPECIAL-NAMES) абзаце.

  2. Ниже приведены символы вставки. Они используются для вставки дополнительного символа (двух в случае CR и DB) для обозначения знака (положительного или отрицательного) числового значения, которое перемещается в поле, чья строка описания содержит один из этих символов, или факта, что элемент данных представляет собой денежную сумму. Только один из символов ‘+’, ‘-’, CR или DB может использоваться в строке описания. В этом контексте, когда любой из этих символов используется в picture-string, они должны быть в конце. Символы ‘+’, ‘-’ и/или валюты также могут использоваться в качестве плавающих символов редактирования в начале picture-string — тема, которая будет рассмотрена в следующем абзаце с номером.
    ‘+’

    Если значение числового значения, перемещаемого в поле, положительное (0 или больше), будет вставлен символ ‘+’. Если значение отрицательное (меньше 0), вставляется символ ‘-’.

    Символ ‘+’ не допускается в сочетании с ‘N’.

    ‘-’

    Если значение числового значения, перемещаемого в поле, положительное (0 или больше), вставляется пробел. Если значение отрицательное (меньше 0), вставляется символ ‘-’.

    Символ ‘-’ не допускается в сочетании с ‘N’.

    CR

    Этот символ кодируется как два символа ‘C’ и ‘R’. Если значение числового значения, перемещаемого в поле, положительное (0 или больше), будут вставлены два пробела. Если значение отрицательное (меньше 0), вставляются символы CR (кредит).

    Символ CR не допускается в сочетании с ‘N’.

    DB

    Этот символ кодируется как два символа ‘D’ и ‘B’. Если значение числового значения, перемещаемого в поле, положительное (0 или больше), будут вставлены два пробела. Если значение отрицательное (меньше 0), вставляются символы DB (дебет).

    Символ DB не допускается в сочетании с ‘N’.

    ‘$’

    Независимо от значения, перемещаемого в поле, этот символ вставит символ валюты в значение элемента данных в позиции, где он встречается в picture-string (см. SPECIAL-NAMES).

    Символ ‘$’ не допускается в сочетании с ‘N’.

  1. Эти символы редактирования известны как символы плавающей замены. Эти символы могут встречаться последовательностями перед любыми символами редактирования ‘9’ в picture-string числового элемента данных. Использование этих символов преобразует этот числовой элемент данных в числовой отредактированный элемент данных, который больше нельзя использовать в расчётах или подстрочных индексах.
  2. Каждый из следующих символов ведёт себя как символ ‘9’, пока все цифры в числовом значении не будут исчерпаны и не возникнет необходимость вставки ведущих нулей. По сути, эти символы редактирования определяют, что должно произойти с этими ведущими нулями.
    ‘$’

    Из тех символов валюты, которые соответствуют позициям символов, в которых находятся ведущие нули, самый правый будет иметь своё значение ‘0’ заменённым символом валюты, действующим для программы (см. SPECIAL-NAMES). Любые оставшиеся ведущие нули, занимающие позиции, описанные этим символом, будут заменены пробелами.

    Символ ‘$’ не допускается в сочетании с ‘N’.

    Любой символ валюты, закодированный справа от ‘.’, будет обрабатываться точно так же, как ‘9’.

    ‘*’

    Этот символ называется символом защиты от подделки. Все символы защиты от подделки, соответствующие позициям символов, в которых находятся ведущие нули, будут иметь свои значения ‘0’ заменёнными на ‘*’.

    Символ ‘*’ не допускается в сочетании с ‘N’.

    Любой символ подавления проверки, закодированный справа от ‘.’, будет обрабатываться точно так же, как ‘9’.

    ‘+’

    Из тех символов ‘+’, которые соответствуют позициям символов, в которых находятся ведущие нули, самый правый будет иметь своё значение ‘0’ заменённым на ‘+’, если значение в элементе данных равно или больше нуля, или на ‘-’ в противном случае. Любые оставшиеся ведущие нули, занимающие позиции, описанные этим символом, будут заменены пробелами. Вы не можете использовать оба ‘+’ и ‘-’ в одной и той же picture-string.

    Символ ‘+’ не допускается в сочетании с ‘N’.

    Любой символ ‘+’, закодированный справа от ‘.’, будет обрабатываться точно так же, как ‘9’.

    ‘-’

    Из тех символов ‘-’, которые соответствуют позициям символов, в которых находятся ведущие нули, самый правый будет иметь своё значение ‘0’ заменённым пробелом, если значение в элементе данных равно или больше нуля, или на ‘-’ в противном случае. Любые оставшиеся ведущие нули, занимающие позиции, описанные этим символом, будут заменены пробелами. Вы не можете использовать оба ‘+’ и ‘-’ в одной и той же picture-string.

    Символ ‘-’ не допускается в сочетании с ‘N’.

    Любой символ ‘-’, закодированный справа от ‘.’, будет обрабатываться точно так же, как ‘9’.

    ‘Z’

    Все символы ‘Z’, соответствующие позициям символов, в которых находятся ведущие нули, будут иметь свои значения ‘0’ заменёнными пробелами.

    Любой символ подавления нулей, закодированный справа от ‘.’, будет обрабатываться точно так же, как ‘9’.

    ‘Z’ и ‘*’ не должны быть закодированы в одной picture-string

    ‘+’ и ‘-’ не должны быть закодированы в одной picture-string

    Когда закодированы несколько плавающих символов, даже если используется только один из них, все они будут считаться плавающими и смогут принимать свойства друг друга. Например, если элемент данных имеет picture-string, и значение 1 перемещается в это поле во время выполнения, результирующее значение будет (символ b представляет пробел) bbbb+$1.00. Это не соответствует многим другим реализациям COBOL, где результатом было бы +$bbbb1.00.

    Большинство других реализаций COBOL отклоняют использование нескольких вхождений нескольких плавающих символов редактирования. Например, они отклонят picture-string такие как +++$$$9.99, $$$ZZZ9.99 и так далее. GnuCOBOL принимает эти. Программисты, создающие программы GnuCOBOL, должны избегать таких picture-stringов, если есть вероятность, что эти программы могут быть использованы с другими реализациями COBOL.

6.9.34. PRESENT WHEN

PRESENT-WHEN Оператор синтаксиса

 PRESENT WHEN condition-name
 ~~~~~~~ ~~~~

Этот синтаксис допустим в следующих разделах: REPORT

Этот оператор называет существующее Condition Name (см. Имена условий), которое будет использоваться в качестве переключателя, управляющего представлением или подавлением группы отчёта.

  1. Если указанному имени условия присвоено значение FALSE, когда оператор GENERATE (см. GENERATE) вызывает представление группы отчёта, представление этой группы будет подавлено.
  2. Если имя условия имеет значение TRUE, группа будет представлена.
  3. См. Имена условий для получения дополнительной информации.

6.9.35. PROMPT

PROMPT Оператор синтаксиса

 PROMPT [ CHARACTER IS literal-1 | identifier-1 ]
 ~~~~~~   ~~~~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Этот оператор определяет символ, который будет использоваться в качестве символа заполнения для любых входных полей на экране.

  1. Зарезервированное слово IS является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Знак подсказки по умолчанию, если не указано CHARACTER, или если PROMPT отсутствует, представляет собой подчёркивание (‘_’).
  3. Символы подсказки будут автоматически преобразованы в пробелы при вводе.

См. Палитру цветов и атрибуты видео для получения дополнительной информации о цветах экрана и атрибутах видео.

6.9.36. ЗАЩИЩЕННЫЙ

Синтаксис атрибута PROTECTED

 PROTECTED SIZE IS { identifier }
 ~~~~~~~~  ~~~~    { integer    }

Этот синтаксис допустим в следующих разделах: SCREEN

  1. Расширенная фраза PROTECTED будет ограничивать размер указанного поля, независимо от размера изображения.2
  2. Фраза SIZE указывает размер (длину) поля. После завершения ACCEPT или DISPLAY, курсор размещается непосредственно после поля, определенного этой фразой, если это не выводит курсор за пределы текущего окна терминала. В этом случае курсор перемещается в начало следующей строки (с прокруткой окна, если необходимо).
  3. Если фраза SIZE не используется, то длина поля по умолчанию соответствует размеру вводимого или отображаемого элемента. Однако, если используется фраза CONVERT, размер поля зависит от типа данных элемента и используемого глагола.
    1. Если выполняется глагол DISPLAY, то размер соответствует размеру, как если бы фраза CONVERT не была указана, за исключением числовых элементов. Для числовых элементов размер составляет количество цифр в элементе плюс один, если он не является целым числом, плюс один, если он со знаком. Остальные случаи описывают размер при использовании инструкции ACCEPT.
    2. Если элемент числовой или числовой отформатированный, то размер равен количеству цифр в элементе плюс один, если он не является целым числом, плюс один, если он со знаком.
    3. Если элемент буквенно-цифровой отформатированный, то размер устанавливается в количество позиций ‘A’ или ‘X’, указанных в его фразе PICTURE.
    4. Для всех других типов данных размер поля устанавливается в размер элемента (также, как если бы CONVERT не было указано).
  4. Обратите внимание, что фраза OUTPUT изменяет способ вычисления размера поля по умолчанию. Подробности см. в заголовке выше. Также обратите внимание, что фраза OUTPUT влияет только на отображение элементов на экране; внутренний формат принимаемых данных не затрагивается.
  5. Обратите внимание, что вы не можете использовать фразу CONVERT в разделе экрана. Таким образом, размер поля раздела экрана всегда соответствует размеру его экранного ввода, если не указана фраза SIZE.

6.9.37. ПЕРЕОПРЕДЕЛЯЕТ

Синтаксис фразы REDEFINES

 REDEFINES identifier-1
 ~~~~~~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE

Фраза REDEFINES заставляет элемент данных, в определении которого указана фраза REDEFINES (далее – объект переопределения), занимать то же физическое место в памяти, что и identifier-1 (далее – субъект переопределения).

  1. Следующие правила должны быть соблюдены для использования REDEFINES:
    1. Номер уровня элементов данных субъекта и объекта должен быть одинаковым.
    2. Номера уровней элементов данных субъекта и объекта не могут быть 66, 78 или 88.
    3. Если N представляет номер уровня объекта, то между субъектом и объектом не могут быть определены другие элементы данных с номером уровня N, если они тоже не являются REDEFINES субъекта.
    4. Если N представляет номер уровня объекта, то между субъектом и объектом не могут быть определены другие элементы данных с номером уровня меньше N.
    5. Общий выделенный размер элемента данных субъекта должен быть таким же, как и общий выделенный размер элемента данных объекта.
    6. Никакая фраза OCCURS (см. OCCURS) не может быть частью определения ни субъекта, ни объекта. Однако, любой из них может быть групповым элементом, который *содержит* элементы данных с фразами OCCURS.
    7. Никакая фраза VALUE (см. VALUE) не может быть определена для элемента данных объекта, и ни один элемент данных, подчиненный элементу данных объекта, не может иметь фразу VALUE, за исключением имён условий уровня 88.

6.9.38. ПЕРЕИМЕНОВАНИЕ

Синтаксис фразы RENAMES

 RENAMES identifier-1 [ THRU|THROUGH identifier-2
 ~~~~~~~                ~~~~ ~~~~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE

Фраза RENAMES перегруппировывает ранее определенные элементы, указывая альтернативные, возможно перекрывающиеся, группировки элементарных элементов данных.

  1. Зарезервированные слова THRU и THROUGH взаимозаменяемы.
  2. Вы должны использовать номер уровня 66 для записей описания данных, содержащих предложение RENAMES.
  3. Элементы данных identifier-1 и identifier-2, а также все элементы данных, определенные между этими двумя элементами в исходном коде программы, должны быть включены в одно описание записи уровня 01.
  4. Для получения дополнительной информации о предложении RENAMES см. раздел Элементы данных уровня 66.

6.9.39. ОБЯЗАТЕЛЬНО

Синтаксис атрибута REQUIRED

 REQUIRED
 ~~~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Это условие заставляет пользователя вводить данные в поле, на котором оно указано (или во все подчиненные поля, допускающие ввод, если REQUIRED указано для элемента группы).

  1. Предложения EMPTY-CHECK (см. EMPTY-CHECK) и REQUIRED взаимозаменяемы и не могут использоваться вместе в описании одного элемента данных.
  2. Для вступления в силу пользователь должен сначала переместить курсор в поле, содержащее это условие в своём определении.
  3. Предложение ACCEPT screen-data-item (см. ACCEPT screen-data-item) проигнорирует нажатие клавиши Enter и любые другие нажатия клавиш, перемещающие курсор на другой элемент экрана, за исключением случаев, когда в поле были введены данные. Функциональные клавиши всё ещё будут разрешены для завершения ACCEPT.
  4. Для функционирования этот атрибут должен поддерживаться базовым пакетом «curses», с которым была создана ваша реализация GnuCOBOL. На данный момент пакет «PDCurses» (используемый для нативных сборок Windows или MinGW) не поддерживает REQUIRED.

6.9.40. ОБРАТНЫЙ_ВИДЕО

Синтаксис атрибута REVERSE-VIDEO

 REVERSE-VIDEO
 ~~~~~~~~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Атрибут REVERSE-VIDEO меняет местами указанные или подразумеваемые атрибуты FOREGROUND-COLOR (см. FOREGROUND-COLOR) и BACKGROUND-COLOR (см. BACKGROUND-COLOR) для поля, определение которого содержит это условие (или для всех подчиненных полей, если оно используется для элемента группы).

См. Цветовая палитра и атрибуты видео для получения дополнительной информации о цветах экрана и атрибутах видео.

6.9.41. ЗАЩИЩЁННЫЙ

Синтаксис атрибута SECURE

 SECURE
 ~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Это условие заставит все введенные в поле данные отображаться на экране в виде звездочек.

  1. Предложения NO-ECHO (см. NO-ECHO) и SECURE взаимозаменяемы и не могут использоваться вместе в одном описании элемента данных.
  2. Это условие может быть использовано только для поля, допускающего ввод данных (поле, содержащее либо предложение USING (см. USING), либо TO (см. TO)).

См. Цветовая палитра и атрибуты видео для получения дополнительной информации о цветах экрана и атрибутах видео.

6.9.42. SIGN IS

Синтаксис условия SIGN-IS

 SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ]
 ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

Это условие, разрешенное только для числовых элементов данных USAGE DISPLAY, определяет, как символ 'S' будет интерпретироваться в предложении 'picture' элемента данных.

  1. Зарезервированные слова CHARACTER и IS являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Без опции SEPARATE CHARACTER, знак значения элемента данных будет закодирован путем преобразования последней (см. TRAILING) или первой (см. LEADING) цифры следующим образом:
    Первая/Последняя цифра Значение для положительного Значение для отрицательного
    0 0 p
    1 1 q
    2 2 r
    3 3 s
    4 4 t
    5 5 u
    6 6 v
    7 7 w
    8 8 x
    9 9 y
  3. Если используется пункт SEPARATE CHARACTER, то фактический символ ‘+’ или ‘-’ будет вставлен в значение поля как первый (LEADING) или последний (TRAILING) символ. Обратите внимание, что наличие этого символа в хранилище элемента данных не препятствует использованию элемента данных в качестве исходного поля в арифметических операциях.
  4. При указании SEPARATE CHARACTER, символ ‘S’ в элементе данных PICTURE необходимо учитывать при определении размера элемента данных.
  5. Ни наличие закодированной цифры (см. выше), ни фактический символ ‘+’ или ‘-’ символ, встроенный в хранилище элемента данных, не препятствуют использованию элемента данных в качестве исходного поля в арифметических операциях.

6.9.43. Источник

Синтаксис пункта SOURCE

 SOURCE IS literal-1 | identifier-1 [ ROUNDED ]
 ~~~~~~                               ~~~~~~~

Этот синтаксис допустим в следующих разделах: REPORT

Этот пункт логически присоединяет элемент данных раздела отчета к другому элементу данных, определенному в другом месте раздела данных.

  1. Зарезервированное слово IS является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. При представлении группы отчета, содержащей этот пункт, значение указанного числового литерала или идентификатора будет автоматически перемещено в элемент данных отчета перед представлением.
  3. Указанный идентификатор может быть определен в любом месте раздела данных, но если он определен в разделе отчета, он может быть только PAGE-COUNTER, LINE-COUNTER или счетчиком SUM (см. СУММА).
  4. PICTURE (см. PICTURE) элемента данных отчета должен быть таким, чтобы было законно MOVE (см. MOVE) указанный литерал или идентификатор в элемент данных с этим PICTURE.
  5. Опция ROUNDED вступает в силу, если количество цифр справа от фактической или предполагаемой десятичной точки отличается между значением указанного литерала или идентификатора (значение «источника») и PICTURE , указанным для поля, в определении которого появляется пункт SOURCE (поле «назначения»). Без ROUNDED, избыточные цифры в исходном значении будут просто усечены, чтобы соответствовать полю назначения. С ROUNDED, значение источника будет арифметически округлено, чтобы соответствовать полю назначения. См. ROUNDED, для получения информации о правиле округления NEAREST-AWAY-FROM-ZERO, которое будет применяться.

6.9.44. СУММА

Синтаксис пункта SUM-OF

 SUM OF { identifier-7 }... [ { RESET ON FINAL|identifier-8 } ]
 ~~~    { literal-2    }      { ~~~~~    ~~~~~              }
                              { UPON identifier-9           }
                                ~~~~

Этот синтаксис допустим в следующих разделах: REPORT

Пункт SUM устанавливает счетчик суммирования, значение которого будет арифметически вычисляться всякий раз, когда поле представляется.

  1. Зарезервированные слова OF и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Оператор SUM может появляться только в группе отчёта CONTROL FOOTING.
  3. Если элементу данных, в котором появляется оператор SUM, присвоено собственное имя идентификатора, и это имя не FILLER, то этот элемент данных называется счётчиком суммы.
  4. Все элементы данных identifier-7 должны быть числовыми, не требующими редактирования.
  5. Если любой элемент данных identifier-7 определён в разделе отчёта, он должен быть счётчиком суммы.
  6. Любые элементы данных identifier-7, являющиеся счётчиками суммы, должны быть определены либо в той же группе отчёта, что и элемент данных, в котором появляется этот оператор SUM, либо в элементе данных отчёта, находящемся на более низком уровне в иерархии управления этим отчётом. Дополнительную информацию см. в разделе Иерархия управления.
  7. Значение элемента данных отчёта, в описании которого присутствует этот оператор SUM, должно быть таким, чтобы было законно выполнить операцию MOVE (см. MOVE) указанного значения identifier-7 или literal-2 в элемент данных с таким же PICTURE.
  8. Следующие пункты относятся к опции UPON:
    1. Элемент данных identifier-9 должен быть именем группы подробностей, указанной в том же отчёте, что и группа итогов управления, в которой появляется этот оператор SUM.
    2. Наличие оператора UPON ограничивает оператор SUM добавлением указанного числового литерала или значения идентификатора в счётчик суммы только при выполнении оператора GENERATE identifier-9.
    3. Если оператор UPON не указан, значение identifier-7 или literal-2 будет добавляться в счётчик суммы всякий раз, когда выполняется операция GENERATE (см. GENERATE) любой группы отчёта о деталях в отчёте.
    4. Если в определении отчёта имеется только одна группа подробностей, оператор UPON не имеет смысла.
  9. Следующие пункты относятся к опции RESET:
    1. Если закодирована опция RESET, FINAL или identifier-8 (которое закодировано в RESET) должно быть одним из контрольных разрывов отчёта, указанных в операторе CONTROLS.
    2. Если опция RESET не закодирована, счётчик суммы будет сброшен до нуля после каждого отображения итоговой группы управления, содержащей оператор SUM. Это типичное ожидаемое поведение.
    3. Однако, если вы хотите сбросить счётчик SUM только при отображении итоговой группы управления для контрольного разрыва, расположенного выше в иерархии управления, укажите этот более высокий контрольный разрыв в опции RESET.

6.9.45. SYNCRONIZED

Синтаксис SYNCRONIZED

 SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ]
 ~~~~        ~~~~           ~~~~ ~~~~~

Операторы LEFT и RIGHT (SYNCRONIZED) синтаксически распознаются, но в остальном не являются функциональными.

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE

Этот необязательный оператор оптимизирует хранение двоичных числовых элементов, чтобы сделать их чтение процессором максимально быстрым.

  1. Зарезервированные слова SYNCRONIZED и SYNCHRONISED взаимозаменяемы и могут быть сокращены до SYNC.
  2. Если оператор SYNCRONIZED закодирован не для числового элемента данных с USAGE (см. USAGE), который определяет хранение данных в двоичной форме, то оператор SYNCRONIZED будет проигнорирован.
  3. Синхронизация выполняется (компилятором) следующим образом:
    1. Если двоичный элемент занимает один байт памяти, синхронизация не выполняется.
    2. Если двоичный элемент занимает два байта памяти, двоичный элемент размещается на следующей границе полуслова.
    3. Если двоичный элемент занимает четыре байта памяти, двоичный элемент размещается на следующей границе слова.
    4. Если двоичный элемент занимает четыре байта памяти, двоичный элемент размещается на следующей границе слова.

6.9.46. TO

Синтаксис оператора TO

 TO identifier-5
 ~~

Этот синтаксис допустим в следующих разделах: SCREEN

Этот оператор логически прикрепляет элемент данных раздела экрана к другому элементу данных, определённому в другом месте раздела данных.

  1. Оператор TO используется для определения поля ввода данных без начального значения; при вводе значения оно сохранится в указанном идентификаторе.
  2. Операторы FROM (см. FROM), TO, USING (см. USING) и VALUE (см. VALUE) являются взаимоисключающими для любого элемента данных раздела экрана.

6.9.47. TYPE

Синтаксис оператора TYPE

 [ TYPE IS { RH|{REPORT HEADING}                      } ]
   ~~~~    { ~~  ~~~~~~ ~~~~~~~                       }
           { PH|{PAGE HEADING}                        }
           { ~~  ~~~~ ~~~~~~~                         }
           { CH|{CONTROL HEADING} FINAL|identifier-2  }
           { ~~  ~~~~~~~ ~~~~~~~  ~~~~~               }
           { DE|DETAIL                                }
           { ~~ ~~~~~~                                }
           { CF|{CONTROL FOOTING} FINAL|identifier-2  }
           { ~~  ~~~~~~~ ~~~~~~~  ~~~~~               }
           { PF|{PAGE FOOTING}                        }
           {  ~~ ~~~~ ~~~~~~~                         }
           { RF|{REPORT FOOTING}                      }
             ~~  ~~~~~~ ~~~~~~~

Этот синтаксис допустим в следующих разделах: REPORT

Этот оператор определяет тип группы отчёта, который определяется для отчёта.

  1. Этот пункт обязателен для всех определений данных на уровне 01 (кроме констант уровня 01) в разделе отчета. Этот пункт недействителен для других определений данных в разделе отчета.
  2. Может быть максимум одна (1) группа отчета на RD определенная с TYPE REPORT HEADING, PAGE HEADING, PAGE FOOTING и REPORT FOOTING.
  3. Для каждой записи, указанной в пункте CONTROLS ARE RD, должен быть указан либо CONTROL HEADING, либо CONTROL FOOTING, или оба.
  4. Различные группы отчетов, составляющие отчет, могут быть определены в любом порядке.
  5. См. Лексикон RWCS для описания семи различных типов групп отчетов.

6.9.48. ПОДЧЁРКИВАНИЕ

Синтаксис атрибута ПОДЧЁРКИВАНИЕ

 UNDERLINE
 ~~~~~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Пункт UNDERLINE выведет горизонтальную линию в нижней части поля экрана.

  1. Пункты LEFTLINE (см. LEFTLINE), OVERLINE (см. OVERLINE) и UNDERLINE могут быть использованы в любом сочетании в описании одного поля.
  2. Этот пункт фактически нефункционален при использовании в средах командной оболочки Windows (cmd.exe) и при выполнении программ, скомпилированных с помощью реализации GnuCOBOL, построенной с использованием «PDCurses» (например, сборки Windows/MinGW).
  3. Будет ли этот пункт работать в системах Cygwin или UNIX/Linux/OSX, зависит от возможностей атрибутов видео выходных драйверов терминала и используемого программного обеспечения «curses».

См. Цветовая палитра и атрибуты видео для получения дополнительной информации о цветах экрана и атрибутах видео.

6.9.49. ИСПОЛЬЗОВАНИЕ

Синтаксис пункта ИСПОЛЬЗОВАНИЕ

 USAGE IS data-item-usage
 ~~~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT

Пункт USAGE определяет формат, который будет использоваться для хранения значения элемента данных.

  1. Зарезервированное слово IS необязательно и может быть опущено. Наличие или отсутствие этого слова не оказывает влияния на программу.
  1. Следующая таблица обобщает различные спецификации ИСПОЛЬЗОВАНИЯ, доступные в GnuCOBOL.

    BINARY~~~~~~

    Диапазон значений: Определяется количеством символов ‘9’ и наличием или отсутствием символа ‘S’ в PICTURE
    Формат хранения: Совместимый двоичный целoe число
    Разрешены отрицательные значения?: Если PICTURE содержит ‘S’
    PICTURE используется?: Да

    BINARY-C-LONG [ SIGNED ]~~~~~~~~~~~~~

    Так же, как BINARY-DOUBLE SIGNED

    BINARY-C-LONG UNSIGNED~~~~~~~~~~~~~ ~~~~~~~~

    Диапазон значений: Обычно 0 – 4 294 967 295
    Формат хранения: Нативный двоичный целoe число
    Разрешены отрицательные значения?: Нет
    PICTURE используется?: Нет

    BINARY-CHAR [ SIGNED ]~~~~~~~~~~~

    Диапазон значений: -128 – 127
    Формат хранения: Нативный двоичный целoe число
    Разрешены отрицательные значения?: Да
    PICTURE используется?: Нет

    BINARY-CHAR UNSIGNED~~~~~~~~~~~ ~~~~~~~~

    Диапазон значений: 0 – 255
    Формат хранения: Нативный двоичный целoe число
    Разрешены отрицательные значения?: Нет
    PICTURE используется?: Нет

    BINARY-DOUBLE [ SIGNED ]~~~~~~~~~~~~~

    Диапазон значений: -9 223 372 036 854 775 808 – 9 223 372 036 854 775 807
    Формат хранения: Нативный двоичный целoe число
    Разрешены отрицательные значения?: Да
    PICTURE используется?: Нет

    BINARY-DOUBLE UNSIGNED~~~~~~~~~~~~~ ~~~~~~~~

    Диапазон значений: 0 – 18 446 744 073 709 551 615
    Формат хранения: Нативный двоичный целoe число
    Разрешены отрицательные значения?: Нет
    PICTURE используется?: Нет

    BINARY-INT~~~~~~~~~~

    Так же, как BINARY-LONG SIGNED

    BINARY-LONG [ SIGNED ]~~~~~~~~~~~

    Диапазон значений: -2 147 483 648 – 2 147 483 647
    Формат хранения: Нативный двоичный целoe число
    Разрешены отрицательные значения?: Да
    PICTURE используется?: Нет

    BINARY-LONG UNSIGNED~~~~~~~~~~~ ~~~~~~~~

    Диапазон значений: 0 – 4 294 967 295
    Формат хранения: Нативный двоичный целoe число
    Разрешены отрицательные значения?: Нет
    PICTURE используется?: Нет

    BINARY-LONG-LONG~~~~~~~~~~~~~~~~

    Так же, как BINARY-DOUBLE SIGNED

    BINARY-SHORT [ SIGNED ]~~~~~~~~~~~~

    Диапазон значений: -32 768 – 32 767
    Формат хранения: Нативный двоичный целoe число
    Разрешены отрицательные значения?: Да
    PICTURE используется?: Нет

    BINARY-SHORT UNSIGNED~~~~~~~~~~~~ ~~~~~~~~

    Диапазон значений: 0 – 65 535
    Формат хранения: Нативный двоичный целoe число
    Разрешены отрицательные значения?: Нет
    PICTURE используется?: Нет

    COMPUTATIONAL~~~~

    Так же, как BINARY

    COMP[UTATIONAL]-1~~~~ ~~

  1. То же самое, что и FLOAT-SHORT

    COMP[UTATIONAL]-2~~~~ ~~

    То же самое, что и FLOAT-LONG

    COMP[UTATIONAL]-3~~~~ ~~

    То же самое, что и PACKED-DECIMAL

    COMP[UTATIONAL]-4~~~~ ~~

    То же самое, что и BINARY

    COMP[UTATIONAL]-5~~~~ ~~

    Диапазон значений: Зависит от количества символов ‘9’ в PICTURE и параметра binary-size в файле конфигурации, используемом для компиляции программы
    Формат хранения: Целое число в собственном двоичном формате
    Разрешены ли отрицательные значения?: Если PICTURE содержит ‘S’
    PICTURE используется?: Да

    COMP[UTATIONAL]-6~~~~ ~~

    Диапазон значений: Определяется количеством символов ‘9’ и наличием или отсутствием символа ‘S’ в PICTURE
    Формат хранения: Беззнаковое упакованное десятичное число
    Разрешены ли отрицательные значения?: Нет
    PICTURE используется?: Да

    COMP[UTATIONAL]-X~~~~ ~~

    Диапазон значений: Если используется с PIC X, выделяет один байт памяти на каждый символ ‘X’; диапазон значений от 0 до максимального значения, которое может быть хранимо в указанном количестве байтов. Если используется с PIC 9, диапазон значений зависит от количества символов ‘9’ в PICTURE
    Формат хранения: Двоичное беззнаковое (X) или со знаком (9)
    Разрешены ли отрицательные значения?: Если PICTURE содержит 9 и ‘S’
    PICTURE используется?: Да

    DISPLAY~~~~~~~

    Диапазон значений: Зависит от PICTURE — один символ на каждый X, A, 9, точку, $, Z, 0, *, S (если указан SEPARATE CHARACTER), +, -, или символ B в PICTURE; Добавьте еще 2 байта, если используются символы редактирования DB или CR
    Формат хранения: Символы
    Разрешены ли отрицательные значения?: Если PICTURE содержит ‘S’
    PICTURE используется?: Да

    FLOAT-DECIMAL-16~~~~~~~~~~~~~~~~

    Диапазон значений: -9.999999999999999 * 10383 – 9.999999999999999 * 10384
    Формат хранения: Десятичное число с плавающей запятой IEEE 754 Decimal64 в собственном формате
    Разрешены ли отрицательные значения?: Да
    PICTURE используется?: Нет

    FLOAT-DECIMAL-34~~~~~~~~~~~~~~~~

    Диапазон значений: -9.99999... * 106143 – 9.99999... * 106144
    Формат хранения: Десятичное число с плавающей запятой IEEE 754 Decimal128 в собственном формате
    Разрешены ли отрицательные значения?: Да
    PICTURE используется?: Нет

    FLOAT-LONG~~~~~~~~~~

    Диапазон значений: Приблизительно -1.797693134862316 * 10308 – 1.797693134862316 * 10308
    Формат хранения: Двоичное число с плавающей запятой IEEE 754 Binary64 в собственном формате
    Разрешены ли отрицательные значения?: Да
    PICTURE используется?: Нет

    FLOAT-SHORT~~~~~~~~~~~

    Диапазон значений: Приблизительно -3.4028235 * 1038 – 3.4028235 * 1038
    Формат хранения: Двоичное число с плавающей запятой IEEE 754 Binary32 в собственном формате
    Разрешены ли отрицательные значения?: Да
    PICTURE используется?: Нет

    INDEX~~~~~

  1. Диапазон значений: От 0 до максимального возможного адреса (32 или 64 бита)
    Формат хранения: Нативный двоичный целое
    Разрешены отрицательные значения?: Нет
    PICTURE Используется?: Нет

    NATIONAL~~~~~~~~

    USAGE NATIONAL, хотя синтаксически распознается, не поддерживается GnuCOBOL

    PACKED-DECIMAL~~~~~~~~~~~~~~

    Диапазон значений: Определяется количеством «9» и наличием или отсутствием «S» в описании формата данных
    Формат хранения: Знаковый упакованный десятичный
    Разрешены отрицательные значения?: Если PICTURE содержит «S»
    PICTURE Используется?: Да

    POINTER~~~~~~~

    Диапазон значений: От 0 до максимального возможного адреса (32 или 64 бита)
    Формат хранения: Нативный двоичный целое
    Разрешены отрицательные значения?: Нет
    PICTURE Используется?: Нет

    PROCEDURE-POINTER~~~~~~~~~~~~~~~~~

    То же, что и PROGRAM-POINTER

    PROGRAM-POINTER~~~~~~~~~~~~~~~

    Диапазон значений: От 0 до максимального возможного адреса (32 или 64 бита)
    Формат хранения: Нативный двоичный целое
    Разрешены отрицательные значения?: Нет
    PICTURE Используется?: Нет

    SIGNED-INT~~~~~~~~~~

    То же, что и BINARY-LONG SIGNED

    SIGNED-LONG~~~~~~~~~~~

    То же, что и BINARY-DOUBLE SIGNED

    SIGNED-SHORT~~~~~~~~~~~~

    То же, что и BINARY-SHORT SIGNED

    UNSIGNED-INT~~~~~~~~~~~~

    То же, что и BINARY-LONG UNSIGNED

    UNSIGNED-LONG~~~~~~~~~~~~~

    То же, что и BINARY-DOUBLE UNSIGNED

    UNSIGNED-SHORT~~~~~~~~~~~~~~

    То же, что и BINARY-SHORT UNSIGNED
  2. Двоичные данные (целые или с плавающей точкой) могут храниться в формате Big-Endian или Little-Endian.

    При использовании схемы размещения данных Big-Endian байты, составляющие двоичную величину, размещаются таким образом, что наименее значимый байт находится справа. Например, четырехбайтовая двоичная величина, имеющая значение 20 в десятичной системе, будет размещена в формате big-endian как 00000014 (показано в шестнадцатеричном формате).

    При использовании схемы размещения данных Little-Endian байты, составляющие двоичную величину, размещаются таким образом, что наименее значимый байт находится слева. Например, четырехбайтовая двоичная величина, имеющая значение 20 в десятичной системе, будет размещена в формате little-endian как 14000000 (показано в шестнадцатеричном формате).

    Все процессоры способны понимать формат big-endian, что делает его наиболее совместимым форматом двоичного хранения на различных компьютерных системах.

    Некоторые процессоры, такие как процессоры архитектуры Intel/AMD i386/x64, используемые в большинстве ПК с Windows, предпочитают обрабатывать двоичные данные в формате little-endian. Поскольку этот формат более эффективен на этих системах, он называется нативным двоичным форматом.

    В системе, поддерживающей только один формат двоичного хранения (обычно это big-endian), термины наиболее эффективный и нативный формат являются синонимами.

  3. Элементы данных, имеющие атрибут UNSIGNED явно в коде, или DISPLAY, PACKED-DECIMAL, COMP-5, COMP-X элементы, не содержащие символ «S» в описании формата данных, не могут сохранять отрицательные значения, которые могут быть сохранены в них. Хранение отрицательного значения в таком поле фактически приведет к удалению знака, фактически сохраняя абсолютное значение в элементе данных.
  1. Данные с упакованной десятичной записью (т.е. USAGE PACKED-DECIMAL, USAGE COMP-3 или USAGE COMP-6) хранятся как серия байтов, в каждом из которых содержится два 4-битных поля, называемые нибблами (поскольку они составляют половину «байта», они просто «нибблы» — не стоните, я не выдумываю это!). Каждый ниббл представляет «9» в PICTURE и содержит одну десятичную цифру, закодированную как её двоичное значение (0 = 0000, 1 = 0001, … , 9 = 1001).

    Последний байт данных PACKED-DECIMAL или COMP-3 всегда содержит свой левый ниббл, соответствующий последней цифре «9» в PICTURE, и его правый ниббл, резервированный для индикатора знака. Этот индикатор знака всегда присутствует независимо от того, содержал ли PICTURE символ «S».

    Первый байт элемента данных будет содержать неиспользуемый левый ниббл, если у PICTURE было чётное количество символов «9».

    Индикатор знака будет иметь значение от шестнадцатеричного A до F. Стандартные правила кодирования упакованной десятичной записи предполагают шестнадцатеричные значения F, A, C или E («FACE») в ниббле знака для обозначения положительного значения и B или D для представления отрицательного значения (шестнадцатеричные цифры 0-9 не определены). Тестирование с использованием реализации Windows MinGW/GnuCOBOL показывает, что фактически шестнадцатеричная цифра D представляет отрицательное число, а любая другая шестнадцатеричная цифра — положительное. Поэтому поле упакованной десятичной записи PIC S9(3) COMP-3 со значением -15 будет храниться внутри как шестнадцатеричное 015D в GnuCOBOL.

    Если вы попытаетесь сохранить отрицательное число в поле упакованной десятичной записи, в котором в PICTURE нет «S», то фактически будет сохранено абсолютное значение отрицательного числа.

    USAGE COMP-6 не допускает отрицательных значений, поэтому ниббл знака не будет выделен. Элемент данных USAGE COMP-6 с нечётным количеством символов «9» в PICTURE оставит свой крайний левый ниббл неиспользованным.

  2. Спецификации USAGE FLOAT-DECIMAL-16 и FLOAT-DECIMAL-34 будут кодировать данные в формате IEEE 754 Decimal64 и Decimal128 соответственно. Первый позволяет использовать до 16 знаков точности, а второй — 34. Термин «точная точность» используется потому, что традиционные двоичные представления десятичных действительных чисел в формате с плавающей точкой (FLOAT-LONG и FLOAT-SHORT, например) дают только приближение фактического значения, потому что многие десятичные дроби не могут быть точно представлены в двоичном формате. Однако Decimal64 и Decimal128 представляют десятичные действительные числа в кодированном десятичном формате примерно так же, как PACKED-DECIMAL представляет десятичное целое число в виде десятичного представления цифры за цифрой. Точный способ выполнения этого преобразования сложен (в Википедии есть отличная статья на эту тему — просто найдите Decimal64).
  3. GnuCOBOL хранит элементы данных FLOAT-DECIMAL-16 и FLOAT-DECIMAL-34 в формате Big-Endian или Little-Endian, в зависимости от того, какой формат используется в системе.
  4. Спецификации USAGE FLOAT-LONG и FLOAT-SHORT используют форматы IEEE 754 Binary64 и Binary32 соответственно. Это двоичные кодировки десятичных чисел с плавающей точкой, и, как таковые, они не могут представлять все возможные значения между минимальным и максимальным значениями в диапазоне для этих применений. В Википедии есть отличная статья о схемах кодирования Binary64 и Binary32 — просто найдите Binary32 или Binary64.

    GnuCOBOL хранит элементы данных FLOAT-LONG и FLOAT-SHORT в формате Big-Endian или Little-Endian, в зависимости от того, какой формат используется в системе.

  5. Оператор USAGE, указанный на уровне группового элемента, применим к всем подчиненным элементам данных, кроме тех, у которых есть оператор USAGE.
  6. Единственный оператор USAGE, разрешённый в разделе отчёта, — USAGE DISPLAY.

6.9.50. USING

Синтаксис оператора USING

 USING identifier-1
 ~~~~~

Этот синтаксис допустим в следующих разделах: SCREEN

Этот оператор логически привязывает элемент данных раздела экрана к другому элементу данных, определённому в другом месте раздела данных.

  1. При отображении элемента экрана, определение которого содержит этот оператор, значение, текущее в identifier-1, будет автоматически перемещено в элемент экрана в первую очередь.
  2. При обработке элемента экрана, определение которого содержит этот оператор (или его родительского элемента), текущее содержимое элемента экрана будет сохранено обратно в identifier-1 по завершении ACCEPT.
  3. Операторы FROM (см. FROM), TO (см. TO), USING и VALUE (см. VALUE) являются взаимоисключающими в определении любого элемента данных раздела экрана.

6.9.51. VALUE

Синтаксис оператора VALUE (имена условий)

 { VALUE IS   } {literal-1 [ THRU|THROUGH literal-2 ]}...
 { ~~~~~      }              ~~~~ ~~~~~~~
 { VALUES ARE }
   ~~~~~~

Синтаксис оператора VALUE (другие элементы данных)

 VALUE IS [ ALL ] literal-1
 ~~~~~      ~~~

Этот синтаксис допустим в следующих разделах: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

Оператор VALUE используется для определения имён условий или для присваивания значений (во время компиляции) элементам данных.

  1. Зарезервированные слова ARE и IS являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Этот пункт не может быть указан в том же элементе данных, что и пункт FROM (см. FROM), TO (см. TO) или USING (см. USING).
  3. Следующие пункты относятся к использованию пункта VALUE в определении имени условия:
    1. Пункты VALUE IS и VALUES ARE взаимозаменяемы.
    2. Зарезервированные слова THRU и THROUGH взаимозаменяемы.
    3. См. Элементы данных уровня 88, чтобы узнать, как этот формат VALUE используется для создания имён условий.
    4. См. Имена условий, чтобы узнать, как используются имена условий.
  4. Следующие пункты относятся к использованию пункта VALUE в определении любого другого элемента данных:
    1. В этом контексте VALUE задаёт начальное значение, которое будет присвоено памяти, занимаемой элементом данных в объектном коде программы, сгенерированном компилятором.
    2. Пункт VALUE игнорируется для элементов данных EXTERNAL (см. EXTERNAL) или для элементов данных, определённых как подчиненные элементу данных EXTERNAL.
    3. Этот формат пункта VALUE не может быть использован нигде в описании элемента 01 (или любого из его подчиненных элементов), используемого как описание записи FD или SD.
    4. Если используется необязательный пункт ALL, он может быть использован только с алфавитно-цифровым литеральным значением; значение будет повторяться по мере необходимости, чтобы полностью заполнить элемент данных. Вот некоторые примеры с пунктом ALL и без него (символ b обозначает пробел):
      PIC X(5) VALUE ‘A’      *> Abbbb
      PIC X(5) VALUE ALL ‘A’  *> AAAAA
      PIC 9(3) VALUE 1        *> 001
      PIC 9(3) VALUE ALL ‘1’  *> 111
      
    5. При использовании в определении элемента данных экрана:
      1. Фигуральная константа не может быть предоставлена в качестве literal-1.
      2. Любой пункт FROM (см. FROM), TO (см. TO) или USING (см. USING) в определении того же элемента данных будет проигнорирован.
      3. Если пункт picture не указан, размер элемента данных экрана будет равен длине значения literal-1.
      4. Если пункт picture не указан и задан параметр ALL, то параметр ALL будет проигнорирован.
    6. Назначение таблице начального значения на этапе компиляции является одним из наиболее сложных аспектов определения данных в COBOL. В основном используются три стандартных метода и четвёртый, который могут быть интересным для людей, знакомых с другими реализациями COBOL, но не знакомых с GnuCOBOL. Вот три стандартных подхода:
      1. Не беспокойтесь об этом на этапе компиляции. Используйте пункт INITIALIZE (см. INITIALIZE) для инициализации всех вхождений элемента данных в таблице (во время выполнения) до значений по умолчанию, специфичных для типа данных (числа: 0, алфавитные и алфавитно-цифровые: пробелы).
      2. Инициализировать небольшие таблицы во время компиляции, включив пункт VALUE в элемент группы, являющийся родителем таблицы, следующим образом:
        05  SHIRT-SIZES          VALUE "S 14M 15L 16XL17".
            10 SHIRT-SIZE-TBL    OCCURS 4 TIMES.
               15 SST-SIZE       PIC X(2).
               15 SST-NECK       PIC 9(2).
        
      3. Инициализировать таблицы почти любого размера на этапе компиляции, используя пункт REDEFINES (см. REDEFINES):
        05  SHIRT-SIZE-VALUES.
            10 PIC X(4)          VALUE "S 14".
            10 PIC X(4)          VALUE "M 15".
            10 PIC X(4)          VALUE "L 16".
            10 PIC X(4)          VALUE XL17.
        05  SHIRT-SIZES          REDEFINES SHIRT-SIZE-VALUES.
            10 SHIRT-SIZE-TBL    OCCURS 4 TIMES.
               15 SST-SIZE       PIC X(2).
               15 SST-NECK       PIC 9(2).
        

        Необходимо отметить, что эта таблица значительно более объёмна, чем та, которая представлена с группой VALUE. Однако, преимуществом этого метода инициализации является то, что вы можете иметь столько FILLER и VALUE элементов, сколько вам нужно для большей таблицы, и эти значения могут быть сколь угодно длинными!

    7. Многие компиляторы COBOL не позволяют использовать VALUE и OCCURS (см. OCCURS) в одном элементе данных; кроме того, они не позволяют использовать пункт VALUE для элемента данных, подчиненного элементу OCCURS. Однако в GnuCOBOL таких ограничений нет!

      Рассмотрим следующий пример, который демонстрирует четвёртый способ инициализации таблиц в GnuCOBOL:

      05  X           OCCURS 6 TIMES.
          10 A        PIC X(1) VALUE '?'.
          10 B        PIC X(1) VALUE '%'.
          10 N        PIC 9(2) VALUE 10.
      

      В этом примере все шесть элементов ‘A’ будут инициализированы значением ‘?’, все шесть элементов ‘B’ — значением ‘%’, а все шесть элементов ‘N’ — значением 10. Непонятно, в скольких случаях подобная инициализация окажется полезной, но она доступна при необходимости.

  5. Пункты FROM (см. FROM), TO (см. TO), USING (см. USING) и VALUE являются взаимоисключающими в определении любого элемента данных раздела экрана.

7. PROCEDURE DIVISION

Синтаксис PROCEDURE DIVISION

   PROCEDURE DIVISION [ { USING Subprogram-Argument...     } ]
   ~~~~~~~~~ ~~~~~~~~   { ~~~~~                            }
                        { CHAINING Main-Program-Argument...}
                          ~~~~~~~~
                      [ RETURNING identifier-1 ] .
 [ DECLARATIVES. ]      ~~~~~~~~~
   ~~~~~~~~~~~~
 [ Event-Handler-Routine... . ]

 [ END DECLARATIVES. ]
   ~~~ ~~~~~~~~~~~~
   General-Program-Logic

 [ Nested-Subprogram... ]

 [ END PROGRAM|FUNCTION name-1 ]
   ~~~ ~~~~~~~ ~~~~~~~~

Раздел PROCEDURE DIVISION любой программы GnuCOBOL обозначает точку, в которой записывается весь исполняемый код.

7.1. PROCEDURE DIVISION USING

Синтаксис подпрограммы-аргумента PROCEDURE DIVISION

 [ BY { REFERENCE [ OPTIONAL ]                       } ] identifier-1
      { ~~~~~~~~~   ~~~~~~~~                         }
      { VALUE [ [ UNSIGNED ] SIZE IS { AUTO      } ] }
        ~~~~~     ~~~~~~~~   ~~~~    { ~~~~      }
                                     { DEFAULT   }
                                     { ~~~~~~~   }
                                     { integer-1 }

Пункт USING определяет аргументы, которые будут переданы программе GnuCOBOL, выступающей в роли подпрограммы.

  1. Зарезервированные слова BY и IS являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Оператор USING должен использоваться только в заголовке раздела процедур подпрограмм (подпрограмм или пользовательских функций).
  3. Вызывающая программа передаст ноль или более элементов данных, известных как аргументы, этой подпрограмме — должно быть ровно столько элементов данных identifier-1, указанных в операторе USING, сколько максимальное число аргументов, которое подпрограмма может принять.
  4. Если подпрограмма не ожидает никаких аргументов, она не должна иметь оператор USING в заголовке раздела процедур.
  5. Порядок определения аргументов в операторе USING должен соответствовать порядку передачи этих аргументов в подпрограмму вызывающей программой.
  6. Идентификаторы, указанные в операторе USING, должны быть определены в разделе связи подпрограммы. На самом деле для этих идентификаторов не выделяется память в подпрограмме, так как фактическая память для них будет существовать в вызывающей программе.
  7. Подпрограмма GnuCOBOL ожидает, что все ее аргументы будут одним из двух:
    • Адрес памяти фактического элемента данных (выделенного в вызывающей программе), передаваемого подпрограмме.
    • Численное целое значение (т.е. USAGE BINARY-LONG (см. USAGE)), которое является фактическим аргументом, передаваемым подпрограмме.

    В первом случае оператор USING в заголовке раздела процедур должен описывать аргумент с помощью оператора BY REFERENCE — во втором случае должна быть указана спецификация BY VALUE. Это позволяет сгенерированному компилятором коду правильно ссылаться на аргументы подпрограммы во время выполнения.

  8. BY REFERENCE — предполагаемый по умолчанию для первого аргумента USING, если не указан оператор BY. Последующие аргументы будут предполагать спецификацию BY аргумента, предшествующего им, если у них нет собственного оператора BY.
  9. Изменения, внесенные подпрограммой в значение аргумента, указанного в операторе USING, будут «видимыми» для вызывающей программы только в том случае, если BY REFERENCE был явно указан или неявно предполагался для аргумента в заголовке раздела процедур подпрограммы и аргумент был передан подпрограмме BY REFERENCE вызывающей программой. Дополнительную информацию о механике передачи аргументов в подпрограммы см. в разделе Аргументы подпрограммы.
  10. Необязательный оператор SIZE позволяет указать количество байт, которое займет аргумент BY VALUE, где SIZE DEFAULT указывает 4 байта (это значение по умолчанию, если не используется оператор SIZE), SIZE AUTO указывает размер аргумента в вызывающей программе, а SIZE integer-1 указывает конкретное количество байт.
  11. Необязательное ключевое слово UNSIGNED, допустимое только при наличии SIZE AUTO или SIZE integer-1, добавит атрибут unsigned к спецификации аргумента в сгенерированном коде заголовка функции C для подпрограммы. Хотя это не приносит пользы, когда вызывающая программа является программой GnuCOBOL, это может улучшить совместимость с вызывающей программой на языке C.
  12. Ключевое слово OPTIONAL, допустимое только для аргументов BY REFERENCE, позволяет вызывающим программам использовать OMITTED для соответствующего аргумента при вызове этой подпрограммы. Дополнительную информацию об этой функции см. в разделе CALL.

7.2. ЦЕПОВЫЕ ПРОЦЕДУРНЫЕ РАЗДЕЛЫ

Синтаксис аргумента главного раздела процедур

 [ BY REFERENCE ] [ OPTIONAL ] identifier-1
      ~~~~~~~~~     ~~~~~~~~

Термин CHAINING предоставляет программисту один механизм получения аргументов командной строки, передаваемых программе во время выполнения.

  1. PROCEDURE DIVISION CHAINING может быть закодирован только в основной программе (то есть, первой программе, выполняемой при выполнении единицы компиляции GnuCOBOL). Он не может использоваться ни в какой форме подпрограммы.
  2. Оператор CHAINING определяет аргументы, которые будут переданы основной программе из операционной системы. Идентификаторы аргументов, указанные в операторе CHAINING, будут заполнены строками символов, состоящими из параметров, указанных для программы в командной строке, которая ее выполнила, следующим образом:
    1. При выполнении программы GnuCOBOL из командной строки текст всей командной строки будет разбиваться на серию токенов, где каждый токен идентифицируется как слово, отделенное от других в тексте команды по меньшей мере одним пробелом. Например, если командная строка была /usr/local/myprog THIS IS A TEST, операционная система идентифицирует пять токенов — ‘/usr/local/myprog’, ‘THIS’, ‘IS’, ‘A’ и ‘TEST’.
    2. Несколько разделяемых пробелами токенов могут обрабатываться как один токен, если они заключены в кавычки. Например, из командной строки C:\Pgms\myprog.exe ‘THIS IS A’ TEST генерируются только три токена — ‘C:\Pgms\myprog.exe’, ‘THIS IS A’ и ‘TEST’. Когда для создания многословных токенов используются символы кавычек, сами символы кавычек удаляются из значения токена.
    3. После идентификации токенов первый из них (команда) будет отброшен; остальные будут сохранены в аргументах CHAINING при запуске программы, при этом второй токен пойдет в первый аргумент, третий токен — во второй аргумент и так далее.
    4. Если токенов больше, чем аргументов, избыточные токены будут отброшены.
    5. Если токенов меньше, чем аргументов, избыточные аргументы будут инициализированы так, как если бы был выполнен оператор INITIALIZE identifier-1 (см. INITIALIZE).
    6. Все идентификаторы, указанные в операторе CHAINING, должны быть определены как PIC X, PIC A, групповые элементы (которые неявно рассматриваются как PIC X) или как PIC 9 USAGE DISPLAY. Использование элементов данных типа USAGE BINARY (или аналогичных) в качестве аргументов CHAINING не рекомендуется, поскольку все токены командной строки будут сохранены в их исходной символьной форме при перемещении в элементы данных аргументов.
    7. Если размер хранилища идентификатора аргумента меньше, чем значение токена, который должен быть в него сохранен, избыточные символы в правой части значения токена будут усечены при перемещении значения. Любой оператор JUSTIFIED RIGHT для такого идентификатора аргумента будет проигнорирован.
    8. Если размер хранилища аргумента больше, чем значение токена, который должен быть в него сохранен, значение токена будет перемещено в идентификатор аргумента с выравниванием слева. Неизмененные позиции байтов в идентификаторе будут заполнены пробелами, если аргумент не определен как PIC 9 USAGE DISPLAY, в этом случае неизмененные байты будут заполнены символами ‘0’ из набора символов системы.

      Это поведение при определении аргумента как PIC 9 может быть неприемлемым, поскольку аргумент, определенный как PIC 9(3), но переданный со значением ‘1’ из командной строки, получит значение ‘100’, а не ‘001’. Рекомендуется определять «числовые» аргументы командной строки как PIC X и затем использовать встроенную функцию NUMVAL (см. NUMVAL) для определения соответствующего числового значения.

7.3. Операторы PROCEDURE DIVISION RETURNING

Синтаксис PROCEDURE DIVISION RETURNING

 RETURNING identifier-1
 ~~~~~~~~~

Оператор RETURNING в заголовке PROCEDURE DIVISION указывает, что подпрограмма, в которой он появляется, вернет числовое значение обратно программе, ее вызвавшей.

  1. Оператор RETURNING является необязательным внутри подпрограммы, поскольку не все подпрограммы возвращают значение своему вызывающему объекту.
  2. Оператор RETURNING является обязательным внутри определяемой пользователем функции, так как все такие функции должны возвращать числовой результат.
  3. Элемент данных identifier-1 должен быть определен как элемент данных USAGE BINARY-LONG.
  4. Основные программы, которые хотят «передать обратно» код возврата в операционную систему при выходе, не используют RETURNING — они делают это, просто переместив значение в специальный регистр RETURN-CODE.
  5. Это не единственный механизм, который подпрограмма может использовать для передачи значения обратно своему вызывающему объекту. Другие возможности:
    1. Подпрограмма может изменить любой аргумент, указанный как BY REFERENCE в ее заголовке PROCEDURE DIVISION. Возможность для вызывающей программы «увидеть» какие-либо изменения зависит от того, как вызывающая программа передала аргумент подпрограмме. См. CALL для получения дополнительной информации.
    2. Элемент данных с атрибутом GLOBAL (см. GLOBAL), указанным в его описании в вызывающей программе, автоматически виден и может быть обновлен подпрограммой, вложенной в вызывающую программу. См. Независимые vs содержащиеся vs вложенные подпрограммы для получения дополнительной информации о вложенных подпрограммах.
    3. Элемент данных, определенный с атрибутом EXTERNAL (см. EXTERNAL) в подпрограмме и вызывающей программе (одно и то же имя в обеих программах), автоматически виден и может быть обновлен обеими программами, даже если эти программы скомпилированы независимо друг от друга.

7.4. Разделы и абзацы раздела PROCEDURE DIVISION

Раздел PROCEDURE DIVISION — единственный из разделов COBOL, который позволяет создавать собственные разделы и абзацы. Они совместно называются Процедурами, а имена, которые вы создаёте для этих разделов и абзацев, называются Именами процедур.

Имена процедур необязательны в разделе PROCEDURE DIVISION и, когда используются, назначаются в соответствии с потребностями и желаниями программиста.

Имена процедур могут иметь длину до тридцати одного (31) символа и могут состоять из букв, цифр, дефисов и нижних подчеркиваний. Имя процедуры не может начинаться или заканчиваться символом дефиса («-») или нижнего подчеркивания («_»). Это означает, что Main, 0100-Read-Transaction и 17 — все являются допустимыми именами процедур.

Существует три случая, в которых использование определённых инструкций или опций GnuCOBOL потребует указания процедур. Эти ситуации:

  1. Когда DECLARATIVES (см. DECLARATIVES) указаны.
  2. Когда используется инструкция ENTRY (см. ENTRY).
  3. При использовании любой инструкции раздела PROCEDURE DIVISION, которая ссылается на процедуры. Эти инструкции:
    • ALTER procedure-name
    • GO TO procedure-name
    • MERGE … OUTPUT PROCEDURE procedure-name
    • PERFORM procedure-name
    • SORT … INPUT PROCEDURE procedure-name и/или SORT … INPUT PROCEDURE procedure-name

7.5. DECLARATIVES

Синтаксис DECLARATIVES

section-name-1 SECTION.

 USE { [ GLOBAL ] AFTER STANDARD { EXCEPTION } PROCEDURE ON { INPUT       } }
 ~~~ {   ~~~~~~                  { ~~~~~~~~~ }              { ~~~~~       } }
     {                           { ERROR     }              { OUTPUT      } }
     {                             ~~~~~                    { ~~~~~~      } }
     {                                                      { I-O         } }
     { FOR DEBUGGING ON { procedure-name-1           }      { ~~~         } }
     {     ~~~~~~~~~    { ALL PROCEDURES             }      { EXTEND      } }
     {                  { ~~~ ~~~~~~~~~~             }      { ~~~~~~      } }
     {                  { REFERENCES OF identifier-1 }      { file-name-1 } }
     {                                                                      }
     { [ GLOBAL ] BEFORE REPORTING identifier-2                             }
     {   ~~~~~~   ~~~~~~ ~~~~~~~~~                                          }
     {                                                                      }
     { AFTER EC|{EXCEPTION CONDITION}                                       }
             ~~  ~~~~~~~~~ ~~~~~~~~~

Операторные сочетания AFTER EXCEPTION CONDITION и AFTER EC синтаксически распознаются, но при этом не являются функциональными.

В области DECLARATIVES раздела PROCEDURE DIVISION программист может определить ряд «ловушечных» процедур (называемых декларативными процедурами), способных перехватывать определённые события, которые могут произойти во время выполнения программы. На диаграмме синтаксиса показан формат одной такой процедуры.

  1. Зарезервированные слова AFTER, FOR, ON, PROCEDURE и STANDARD являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. EC и EXCEPTION CONDITION взаимозаменяемы.
  3. Область деклараций может содержать любое количество декларативных процедур, но две декларативные процедуры не должны быть запрограммированы для обработки одного и того же события.
  4. Следующие пункты относятся к разделу USE BEFORE REPORTING:
    1. identifier-2 должен быть группой отчетов.
    2. Во время выполнения процедура деклараций будет выполнена перед обработкой представления указанной группы отчетов; внутри процедуры вы можете выполнить любое из следующих действий:
      • Вы можете изменить значение(я) любых элементов, на которые ссылаются в SUM (см. SUM) или SOURCE (см. SOURCE) разделах в группе отчетов.
      • Вы можете выполнить оператор SUPPRESS (см. SUPPRESS), чтобы полностью подавить отображение указанной группы отчетов. Обратите внимание, что вы будете подавлять только это конкретное представление группы, а не все.
  5. Следующие пункты относятся к разделу USE FOR DEBUGGING:
    1. Этот раздел позволяет определить декларативную процедуру, которая будет вызвана всякий раз, когда…
      • …identifier-1 упоминается в любом операторе.
      • …выполняется procedure-name-1.
      • …выполняется любая процедура (ALL PROCEDURES).
    2. Декларативная процедура USE FOR DEBUGGING будет проигнорирована на стадии компиляции, если не указано WITH DEBUGGING MODE в разделе SOURCE-COMPUTER (см. SOURCE-COMPUTER). Ни переключатель компилятора -fdebugging-line, ни переключатель -debug не активируют эту функцию.
    3. Все декларативные процедуры USE FOR DEBUGGING будут проигнорированы на стадии выполнения, если переменная среды выполнения COB_SET_DEBUG (см. Переменные среды выполнения) не установлена в значение ‘Y’, ‘y’ или ‘1’.
    4. Типичное использование декларативной процедуры USE FOR DEBUGGING — отображение специального регистра DEBUG-ITEM, который будет неявно и автоматически создан в вашей программе, если WITH DEBUGGING MODE активен.

      Структура DEBUG-ITEM будет следующей:

      01  DEBUG-ITEM.
          05 DEBUG-LINE      PIC X(6).
          05 FILLER          PIC X(1) VALUE SPACE.
          05 DEBUG-NAME      PIC X(31).
          05 FILLER          PIC X(1) VALUE SPACE.
          05 DEBUG-SUB-1     PIC S9(4) SIGN LEADING SEPARATE.
          05 FILLER          PIC X(1) VALUE SPACE.
          05 DEBUG-SUB-2     PIC S9(4) SIGN LEADING SEPARATE.
          05 FILLER          PIC X(1) VALUE SPACE.
          05 DEBUG-SUB-3     PIC S9(4) SIGN LEADING SEPARATE.
          05 FILLER          PIC X(1) VALUE SPACE.
          05 DEBUG-CONTENTS  PIC X(31).
      

      где…

      DEBUG-LINE

      … это номер строки программы, которая вызвала процедуру деклараций.

      DEBUG-NAME

      … это имя процедуры или идентификатора, которое вызвало процедуру деклараций.

      DEBUG-SUB-1

      … это значение первого индекса (если есть) для ссылки на идентификатор, который вызвал процедуру деклараций.

      DEBUG-SUB-2

      … это значение второго индекса (если есть) для ссылки на идентификатор, который вызвал процедуру деклараций.

      DEBUG-SUB-3

      … это значение третьего индекса (если есть) для ссылки на идентификатор, который вызвал процедуру деклараций.

      DEBUG-CONTENTS

      … это (краткое) описание способа выполнения процедуры, которая вызвала процедуру деклараций, или первые 31 символ значения идентификатора, ссылка на который вызвала процедуру деклараций (значение после выполнения оператора).

  6. Раздел USE AFTER STANDARD ERROR PROCEDURE определяет декларативную процедуру, которая вызывается всякий раз, когда возникает ошибка с указанным типом ввода-вывода (или по отношению к указанным файлам).
  7. Опция GLOBAL (см. GLOBAL), если используется, позволяет использовать декларативную процедуру во всей программе, содержащей оператор USE и любых вложенных в неё подпрограммах.
  8. Декларативные процедуры не могут ссылаться на другие процедуры, определённые вне области DECLARATIVES.

7.6. Общие разделы управляемых операторов

7.6.1. AT END + NOT AT END

Синтаксис AT END

 [ AT END imperative-statement-1 ]
      ~~~
 [ NOT AT END imperative-statement-2 ]
   ~~~    ~~~

AT END разделы могут быть указаны в операторах READ (см. READ), RETURN (см. RETURN), SEARCH (см. SEARCH) и SEARCH ALL (см. SEARCH ALL).

  1. Следующие пункты относятся к использованию этих пунктов в операторах READ (см. READ) и RETURN (см. RETURN):
    1. Пункт AT END — при наличии — приведет к выполнению imperative-statement-1 (см. Оператор приказа) в случае, если оператор завершится ошибкой из-за статуса файла 10 (конец файла). См. Коды статуса файла для списка возможных кодов статуса файла.

      Пункт AT END не будет обнаруживать другие значения статуса файла, отличные от нуля.

      Используйте процедуру DECLARATIVES (см. ДЕКЛАРАТИВЫ) или явное поле статуса файла, проверенное после READ или RETURN, для обнаружения условий ошибки, отличных от конца файла.

    2. Пункт NOT AT END приведет к выполнению imperative-statement-2 в случае успешного выполнения попытки READ или RETURN.
  2. Следующие пункты относятся к использованию этих пунктов в операторах SEARCH (см. SEARCH) и SEARCH ALL (см. SEARCH ALL):
    1. Пункт AT END обнаруживает и обрабатывает случай, когда поиск таблицы по одному из указанных типов не обнаруживает записи, удовлетворяющей используемым условиям поиска.
    2. Пункт NOT AT END не разрешен для поиска таблицы ни по одному из указанных типов.

7.6.2. СООТВЕТСТВУЮЩИЕ

Три оператора GnuCOBOL — ADD (см. ADD CORRESPONDING), MOVE (см. MOVE CORRESPONDING) и SUBTRACT (см. SUBTRACT CORRESPONDING) поддерживают использование опции CORRESPONDING:

ADD CORRESPONDING group-item-1 TO group-item-2
MOVE CORRESPONDING group-item-1 TO group-item-2
SUBTRACT CORRESPONDING group-item-1 FROM group-item-2

Эта опция позволяет сопоставить один или несколько элементов данных в одном групповом элементе (group-item-1 — первый, указанный в операторе) с соответствующими элементами (отсюда и название) во втором групповом элементе (group-item-2 — второй, указанный в операторе). Содержимое group-item-1 не изменится, а один или несколько элементов данных в group-item-2 будут изменены.

Для того, чтобы data-item-1, определенный как подчиненный групповому элементу group-item-1, являлся соответствующим элементом data-item-2, подчиненному group-item-2, должны выполняться все следующие условия:

  1. data-item-1 и data-item-2 должны иметь одинаковые имена, и это имя не может быть явно или неявно FILLER.
  2. data-item-1 и data-item-2…
    1. …должны существовать на одинаковой относительной структурной «глубине» определения в group-item-1 и group-item-2 соответственно.
    2. …и все родительские элементы данных, определенные в каждом групповом элементе, должны иметь одинаковые (но не FILLER) имена.
  3. При использовании глагола %%%CODE_BLOCK_2727%%…
    1. …разрешается использовать в качестве data-item-1 или data-item-2 (но не оба одновременно) групповой элемент.
    2. …и должно быть возможно выполнить перемещение data-item-1 В data-item-2.
  4. При использовании глаголов ADD или SUBTRACT оба data-item-1 и data-item-2 должны быть числовыми, элементарными, неизмененными элементами.
  5. Ни data-item-1, ни data-item-2 не могут быть REDEFINES (см. REDEFINES) или RENAMES (см. RENAMES) другого элемента данных.
  6. Ни data-item-1, ни data-item-2 не могут содержать пункт OCCURS (см. OCCURS), хотя в них могут содержаться подчиненные элементы данных, которые имеют пункт OCCURS (при условии, что правило 3a применяется).

Обратите внимание на определения элементов данных ‘Q’ и ‘Y’…

01  Q.                           01  Y.
    03 X.                            02 A         PIC X(1).
       05 A         PIC 9(1).        02 G1.
       05 G1.                           03 G2.
          10 G2.                           04 B   PIC X(1).
             15 B   PIC X(1).        02 C         PIC X(1).
       05 C.                         02 G3.
          10 FILLER PIC X(1).           03 G5.
       05 G3.                              04 D   PIC X(1).
          10 G4.                        03 G6     PIC X(1).
             15 D   PIC X(1).        02 E         PIC 9(1).
       05 E         PIC X(1).        02 F         PIC X(1).
       05 F         REDEFINES V1     02 G         PIC X(4).
                    PIC X(1).        02 H         OCCURS 4 TIMES
       05 G.                                      PIC X(1).
          10 G6     OCCURS 4 TIMES   66 I         RENAMES E.
                    PIC X(1).        02 J.
       05 H         PIC X(4).           03 K.
       05 I         PIC 9(1).              04 L.
       05 J.                                  05 M.
          10 K.
             15 M   PIC X(1).

Ниже приведены допустимые CORRESPONDING соответствия при выполнении оператора MOVE CORRESPONDING X TO Y (нет допустимых соответствий для ADD CORRESPONDING или SUBTRACT CORRESPONDING, поскольку каждое потенциальное соответствие нарушает правило № 4):

A, B, C, G

Ниже приведены CORRESPONDING соответствия, которые удовлетворили правилу № 1 (но потерпели неудачу на другом правиле), и причины неудачи.

Элемент данных Причина ошибки
D Ошибка из-за правила #2b
E Ошибка из-за правила #3b
F Ошибка из-за правила #5
G1 Ошибка из-за правила #3a
G2 Ошибка из-за правила #3a
G3 Ошибка из-за правила #3a
G4 Ошибка из-за правила #1
G5 Ошибка из-за правила #1
G6 Ошибка из-за правила #6
H Ошибка из-за правила #6
I Ошибка из-за правила #5
J Ошибка из-за правила #3a
K Ошибка из-за правила #3a
L Ошибка из-за правила #1
M Ошибка из-за правила #2a

7.6.3. INVALID KEY + NOT INVALID KEY

Синтаксис INVALID KEY

 [ INVALID KEY imperative-statement-1 ]
   ~~~~~~~
 [ NOT INVALID KEY imperative-statement-2 ]
   ~~~ ~~~~~~~

Оператор INVALID KEY может быть указан в операторах DELETE (см. DELETE), READ (см. Random READ), REWRITE (см. REWRITE), START (см. START) и WRITE (см. WRITE).

Указание оператора INVALID KEY позволит вашей программе перехватить условие ошибки ввода-вывода (с кодом ошибки ввода-вывода в поле FILE-STATUS (см. SELECT) записи) , возникшее из-за отсутствия записи, и обработать его должным образом, выполнив imperative-statement-1 (см. Imperative Statement).

Необязательное условие NOT INVALID KEY заставит выполнить imperative-statement-2, если выполнение оператора прошло успешно.

7.6.4. ON EXCEPTION + NOT ON EXCEPTION

Синтаксис ON EXCEPTION

 [ ON EXCEPTION imperative-statement-1 ]
      ~~~~~~~~~
 [ NOT ON EXCEPTION imperative-statement-2 ]
   ~~~    ~~~~~~~~~

Оператор EXCEPTION может быть указан в операторах ACCEPT (см. ACCEPT), CALL (см. CALL) и DISPLAY (см. DISPLAY).

Указание условия исключения позволит вашей программе перехватить условие ошибки и обработать его должным образом, выполнив imperative-statement-1 (см. Imperative Statement). Если такое условие возникает во время выполнения без указания одного из этих условий, будет выведено сообщение об ошибке (библиотекой GnuCOBOL runtime) на устройство SYSERR (канал 2). Программа также может быть завершена, в зависимости от типа и степени ошибки.

Необязательное условие NOT ON EXCEPTION заставит выполнить imperative-statement-2, если выполнение оператора прошло успешно.

7.6.5. ON OVERFLOW + NOT ON OVERFLOW

Синтаксис ON OVERFLOW

 [ ON OVERFLOW imperative-statement-1 ]
      ~~~~~~~~
 [ NOT ON OVERFLOW imperative-statement-2 ]
   ~~~    ~~~~~~~~

Оператор OVERFLOW может быть указан в операторах CALL (см. CALL), STRING (см. STRING) и UNSTRING (см. UNSTRING).

Оператор ON OVERFLOW позволит вашей программе перехватить условие ошибки и обработать его должным образом, выполнив imperative-statement-1 (см. Imperative Statement). Если такое условие возникает во время выполнения без указания одного из этих условий, будет выведено сообщение об ошибке (библиотекой GnuCOBOL runtime) на устройство SYSERR (канал 2). Программа также может быть завершена, в зависимости от типа и степени ошибки.

Необязательное условие NOT ON OVERFLOW заставит выполнить imperative-statement-2, если выполнение оператора прошло успешно.

7.6.6. ON SIZE ERROR + NOT ON SIZE ERROR

Синтаксис ON SIZE ERROR

 [ ON SIZE ERROR imperative-statement-1 ]
      ~~~~ ~~~~~
 [ NOT ON SIZE ERROR imperative-statement-2 ]
   ~~~    ~~~~ ~~~~~

Операторы SIZE ERROR могут быть включены в операторах ADD (см. ADD), COMPUTE (см. COMPUTE), DIVIDE (см. DIVIDE), MULTIPLY (см. MULTIPLY) и SUBTRACT (см. SUBTRACT).

Включение ON SIZE ERROR в арифметическое выражение позволит вашей программе перехватывать ошибки арифметического выражения (либо при генерации результата, слишком большого для поля-приёмника, либо при попытке деления на ноль) и корректно обрабатывать их, выполнив imperative-statement-1 (см. Инструкцию). Переполнение размеров поля происходит без сообщений, обычно без каких-либо сообщений во время выполнения, хотя такие события редко приводят к корректным результатам. Ошибки деления на ноль, когда ON SIZE ERROR отсутствует, приведут к сообщению об ошибке (библиотекой GnuCOBOL) в SYSERR устройство (труба 2) и также прервут выполнение программы.

Необязательная NOT ON SIZE ERROR позволит выполнить imperative-statement-2, если выполнение арифметического выражения прошло успешно.

7.6.7. ROUNDED

ROUNDED Синтаксис

 ROUNDED [ MODE IS { AWAY-FROM-ZERO         }
 ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                   { NEAREST-AWAY-FROM-ZERO }
                   { ~~~~~~~~~~~~~~~~~~~~~~ }
                   { NEAREST-EVEN           }
                   { ~~~~~~~~~~~~           }
                   { NEAREST-TOWARD-ZERO    }
                   { ~~~~~~~~~~~~~~~~~~~    }
                   { PROHIBITED             }
                   { ~~~~~~~~~~             }
                   { TOWARD-GREATER         }
                   { ~~~~~~~~~~~~~~         }
                   { TOWARD-LESSER          }
                   { ~~~~~~~~~~~~~          }
                   { TRUNCATION             }
                     ~~~~~~~~~~

GnuCOBOL предоставляет возможность управления окончательным округлением результатов, применяемого к полям-приёмникам во всех арифметических операциях. Каждое из арифметических выражений (ADD (см. ADD), COMPUTE (см. COMPUTE), DIVIDE (см. DIVIDE), MULTIPLY (см. MULTIPLY) и SUBTRACT (см. SUBTRACT)) допускает необязательную ROUNDED для каждого поля данных-приёмника.

Следующие правила применяются к поведению округления, заданному этой клаузой.

  1. Округление применяется только тогда, когда результат, сохраняемый в поле-приёмнике с ROUNDED клаузой, является нецелым числом.
  2. Отсутствие ROUNDED клаузы эквивалентно указанию ROUNDED MODE IS TRUNCATION.
  3. Использование ROUNDED клаузы без указания MODE эквивалентно указанию ROUNDED MODE IS NEAREST-AWAY-FROM-ZERO.

Поведение восьми различных режимов округления определяется в следующей таблице. Обратите внимание, что «…» означает, что последняя цифра повторяется. Примеры предполагают целочисленное поле-приёмник.

AWAY-FROM-ZERO

Округление до ближайшего значения большего модуля.

-3.510 ⇒ -4 +3.510 ⇒ +4
-3.500 ⇒ -4 +3.500 ⇒ +4
-3.499… ⇒ -4 +3.499… ⇒ +4
-2.500 ⇒ -3 +2.500 ⇒ +3
-2.499… ⇒ -3 +2.499… ⇒ +3
NEAREST-AWAY-FROM-ZERO

Округление до ближайшего значения (большего или меньшего). Если два значения находятся на одинаковом расстоянии, выбирается значение с большим абсолютным значением.

-3.510 ⇒ -4 +3.510 ⇒ +4
-3.500 ⇒ -4 +3.500 ⇒ +4
-3.499… ⇒ -3 +3.499… ⇒ +3
-2.500 ⇒ -3 +2.500 ⇒ +3
-2.499… ⇒ -2 +2.499… ⇒ +2
NEAREST-EVEN

Округление до ближайшего значения (большего или меньшего). Если два значения находятся на одинаковом расстоянии, выбирается значение, правая цифра которого является чётной. Этот режим иногда называется «банковским округлением».

-3.510 ⇒ -4 +3.510 ⇒ +4
-3.500 ⇒ -4 +3.500 ⇒ +4
-3.499… ⇒ -3 +3.499… ⇒ +3
-2.500 ⇒ -2 +2.500 ⇒ +2
-2.499… ⇒ -2 +2.499… ⇒ +2
NEAREST-TOWARD-ZERO

Округление до ближайшего значения (большего или меньшего). Если два значения находятся на одинаковом расстоянии, выбирается значение с меньшим абсолютным значением.

-3.510 ⇒ -4 +3.510 ⇒ +4
-3.500 ⇒ -3 +3.500 ⇒ +3
-3.499… ⇒ -3 +3.499… ⇒ +3
-2.500 ⇒ -2 +2.500 ⇒ +2
-2.499… ⇒ -2 +2.499… ⇒ +2
PROHIBITED

Округление не выполняется. Если значение нельзя точно представить в желаемом формате, устанавливается условие %%%CODE_BLOCK_2809%% (код исключения 1005) (и может быть получено через %%%CODE_BLOCK_2810%% (см. ACCEPT FROM Runtime-Info)) и результаты операции не определены.

-3.510 ⇒ Не определено +3.510 ⇒ Не определено
-3.500 ⇒ Не определено +3.500 ⇒ Не определено
-3.499… ⇒ Не определено +3.499… ⇒ Не определено
-2.500 ⇒ Не определено +2.500 ⇒ Не определено
-2.499… ⇒ Не определено +2.499… ⇒ Не определено
TOWARD-GREATER

Округление к ближайшему значению, алгебраическое значение которого больше.

-3.510 ⇒ -3 +3.510 ⇒ +4
-3.500 ⇒ -3 +3.500 ⇒ +4
-3.499… ⇒ -3 +3.499… ⇒ +4
-2.500 ⇒ -2 +2.500 ⇒ +3
-2.499… ⇒ -2 +2.499… ⇒ +3
TOWARD-LESSER

Округление к ближайшему значению, алгебраическое значение которого меньше.

-3.510 ⇒ -4 +3.510 ⇒ +3
-3.500 ⇒ -4 +3.500 ⇒ +3
-3.499… ⇒ -4 +3.499… ⇒ +3
-2.500 ⇒ -3 +2.500 ⇒ +2
-2.499… ⇒ -3 +2.499… ⇒ +2
TRUNCATION

Округление до ближайшего значения, модуль которого меньше.

-3.510 ⇒ -3 +3.510 ⇒ +3
-3.500 ⇒ -3 +3.500 ⇒ +3
-3.499… ⇒ -3 +3.499… ⇒ +3
-2.500 ⇒ -2 +2.500 ⇒ +2
-2.499… ⇒ -2 +2.499… ⇒ +2

7.7. Специальные регистры

GnuCOBOL, как и другие диалекты COBOL, включает ряд элементов данных, которые автоматически доступны программисту, без необходимости фактического определения их в разделе данных. COBOL называет такие элементы регистрами или специальными регистрами. Специальные регистры, доступные программе GnuCOBOL, перечислены ниже:

COB-CRT-STATUS

PIC 9(4) — Это стандартный элемент данных, выделенный для использования в операторе ACCEPT screen-data-item (см. ACCEPT screen-data-item), если не указан ни один оператор CRT STATUS (см. SPECIAL-NAMES).

DEBUG-ITEM

Элемент группы — элемент группы, в котором отладочная информация, сгенерированная разделом USE FOR DEBUGGING в области описаний процедурного раздела, разместит информацию, документирующую, почему была вызвана процедура USE FOR DEBUGGING. Обратитесь к документации по DECLARATIVES (см. DECLARATIVES) для получения информации о структуре этого регистра.

LINAGE-COUNTER

BINARY-LONG SIGNED — экземпляр этого регистра существует для каждого выбранного файла, имеющего оператор LINAGE (см. File/Sort-Description). Если существует несколько файлов, описания которых содержат операторы LINAGE, любые явные ссылки на этот регистр потребуют квалификации (используя OF file-name). Значение этого регистра будет текущим логическим номером строки в теле страницы. Значение этого регистра изменить нельзя.

LINE-COUNTER

BINARY-LONG SIGNED — экземпляр этого регистра существует для каждого отчета, определенного в программе (через оператор RD (см. REPORT SECTION)). Если отчетов несколько, любые явные ссылки на этот регистр, не сделанные в разделе отчета, потребуют квалификации (OF report-name). Значение этого регистра будет текущим логическим номером строки на текущей странице. Значение этого регистра изменить нельзя.

NUMBER-OF-CALL-PARAMETERS

BINARY-LONG SIGNED — Этот регистр содержит количество аргументов, переданных подпрограмме — то же значение, что и возвращаемое встроенной системной подпрограммой C$NARG (см. C$NARG). Его значение будет равно нулю при обращении в основной программе. При обращении из пользовательской функции этот регистр возвращает значение один («1»), если функция имеет любое количество аргументов, и ноль, если аргументов нет.

PAGE-COUNTER

BINARY-LONG SIGNED — Экземпляр этого регистра существует для каждого отчета, имеющего оператор RD (см. REPORT SECTION). Если таких отчетов несколько, любые явные ссылки на этот регистр, не сделанные в разделе отчета, потребуют квалификации (OF report-name). Значение этого регистра будет текущим номером страницы отчета. Значение этого регистра изменить нельзя.

RETURN-CODE

BINARY-LONG SIGNED — Этот регистр предоставляет числовой элемент данных, в который подпрограмма может MOVE (см. MOVE) значение (которое затем будет доступно вызывающей программе) перед передачей управления обратно программе, которая ее вызвала, или в который главная программа может MOVE значение перед возвратом управления операционной системе. Многие встроенные подпрограммы возвращают значение, используя этот регистр. Эти значения по соглашению используются для обозначения успеха (обычно со значением 0) или неудачи (обычно с ненулевым значением) процесса, который пыталась выполнить программа. Этот регистр также может быть изменен подпрограммой в результате использования ею оператора RETURNING (см. PROCEDURE DIVISION RETURNING).

SORT-RETURN

BINARY-LONG SIGNED — Этот регистр используется для сообщения об успехе/неудачи оператора RELEASE (см. RELEASE) или RETURN (см. RETURN). Значение 0 сообщается об успехе. Значение 16 указывает на ошибку. Условие AT END (см. AT END + NOT AT END) на RETURN не считается ошибкой.

WHEN-COMPILED

PIC X(16) — Этот регистр содержит дату и время компиляции программы в формате «мм/дд/ггчч.мм.сс». Обратите внимание, что представлен только двухзначный год.

LENGTH OF Синтаксис

 LENGTH OF numeric-literal-1 | identifier-1
 ~~~~~~

Алфавитно-цифровые литералы и идентификаторы могут быть необязательно снабжены оператором LENGTH OF. Значение, созданное на этапе компиляции этим оператором, будет числом байтов в алфавитно-цифровом литерале или определенным размером (в байтах) идентификатора.

  1. Зарезервированное слово OF необязательно и может быть опущено. Наличие или отсутствие этого слова не влияет на программу. Вот пример. Следующие два оператора GnuCOBOL показывают один и тот же результат (27):
    01  Demo-Identifier          PIC X(27).
    ...
        DISPLAY LENGTH OF "This is a LENGTH OF Example"
        DISPLAY LENGTH OF Demo-Identifier
    
  2. Оператор LENGTH OF для литерала или ссылки на идентификатор обычно может использоваться везде, где может быть указан числовой литерал, за исключением следующих случаев:
    • В качестве части оператора FROM оператора WRITE (см. WRITE) или оператора RELEASE (см. RELEASE).
    • В качестве части оператора TIMES оператора PERFORM (см. PERFORM).

7.8. Операторы GnuCOBOL

7.8.1. ACCEPT

7.8.1.1. ACCEPT FROM CONSOLE

ACCEPT FROM CONSOLE Синтаксис

   ACCEPT { identifier-1 }   [ FROM mnemonic-name-1 ]
   ~~~~~~                      ~~~~
          { OMITTED      }
            ~~~~~~~

 [ END-ACCEPT ]
   ~~~~~~~~~~

Этот формат оператора ACCEPT используется для чтения значения из окна консоли или стандартного устройства ввода и сохранения его в элемент данных (identifier-1).

  1. Если оговорка FROM не указана, предполагается FROM CONSOLE.
  2. Указанное значение mnemonic-name-1 должно быть либо одним из встроенных имён устройств CONSOLE, STDIN, SYSIN или SYSIPT, либо пользовательским псевдонимом (см. SPECIAL-NAMES), привязанным к одному из этих четырёх имён устройств.
  3. Данные будут считываться либо из окна консоли (CONSOLE) или из стандартного системного ввода (пайп 0 = STDIN, SYSIN или SYSIPT) и будут сохранены в identifier-1.
  4. Если identifier-1 является числовым элементом данных, символьное значение, считанное с консоли или устройства стандартного ввода, будет обработано в соответствии с правилами ввода для встроенной функции NUMVAL (см. NUMVAL), за исключением того, что ни один из форматов последующего знака не учитывается.

7.8.1.2. ПРИЁМ ИЗ КОМАНДНОЙ СТРОКИ

Синтаксис ПРИЁМ ИЗ КОМАНДНОЙ СТРОКИ

   ACCEPT identifier-1
   ~~~~~~
          FROM { COMMAND-LINE                                }
          ~~~~ { ~~~~~~~~~~~~                                }
               { ARGUMENT-NUMBER                             }
               { ~~~~~~~~~~~~~~~                             }
               { ARGUMENT-VALUE                              }
               { ~~~~~~~~~~~~~~                              }
               { [ ON EXCEPTION imperative-statement-1 ]     }
               {      ~~~~~~~~~                              }
               { [ NOT ON EXCEPTION imperative-statement-2 ] }
 [ END-ACCEPT ]    ~~~    ~~~~~~~~~
   ~~~~~~~~~~

Этот формат оператора ACCEPT используется для извлечения информации из командной строки программы.

  1. Зарезервированное слово ON является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. При приёме из опции COMMAND-LINE вы получите весь набор аргументов, введённых в командной строке при запуске программы, точно так, как они были указаны. Обработка полученных данных для извлечения содержащейся в них информации — ваша обязанность.
  3. Использование COMMAND-LINE или ARGUMENT-VALUE в *nix-системах, включая Linux, OSX, BSD, и в средах Windows с msys или MinGW и т. п., приведёт к расширению оболочкой любых аргументов, содержащих символ «*» в списке, таких как «a*», «abc*.*» и т. д., и созданию списка всех файлов, соответствующих шаблону. Чтобы избежать этого, если это не нужно, заключите такие аргументы в кавычки, например, progundertest "a*" b c d "ef*" "*hg", и текст в кавычках будет передан программе без изменений (как в примере progundertest).
  4. При приёме из ARGUMENT-NUMBER, вы попросите систему выполнения GnuCOBOL разобрать аргументы из командной строки и вернуть количество найденных аргументов. Обработка будет проводиться по следующим правилам:
    1. Аргументы будут разделены с использованием пробелов и/или символов табуляции в качестве разделителей между ними. Количество таких разделителей, разделяющих два непустых значения аргументов, не имеет значения.
    2. Строки, заключённые в двойные кавычки (‘"’), будут обрабатываться как один аргумент независимо от количества пробелов или символов табуляции (если таковые имеются) внутри кавычек.
    3. В системах Windows одинарные кавычки (‘'’) будут обрабатываться как любые другие символы данных и не будут разграничивать строки аргументов.
  5. При приёме из ARGUMENT-VALUE, вы попросите систему выполнения GnuCOBOL разобрать аргументы из командной строки и вернуть «текущий» аргумент. Вы указываете номер аргумента, который является «текущим», с помощью опции ARGUMENT-NUMBER в операторе DISPLAY (см. DISPLAY UPON COMMAND-LINE). Обработка аргументов будет проводиться в соответствии с правилами, описанными выше.
  6. Необязательные оговорки ON EXCEPTION и NOT ON EXCEPTION могут использоваться для определения и реакции на неудачу или успех попытки извлечения ARGUMENT-VALUE. Дополнительная информация приведена в разделе ON EXCEPTION + NOT ON EXCEPTION.

7.8.1.3. ПРИЁМ ИЗ ОКРУЖЕНИЯ

Синтаксис ПРИЁМ ИЗ ОКРУЖЕНИЯ

   ACCEPT identifier-1
   ~~~~~~
          FROM { ENVIRONMENT-VALUE            }
          ~~~~ { ~~~~~~~~~~~~~~~~~            }
               { ENVIRONMENT { literal-1    } }
               { ~~~~~~~~~~~ { identifier-1 } }
        [ ON EXCEPTION imperative-statement-1 ]
             ~~~~~~~~~
        [ NOT ON EXCEPTION imperative-statement-2 ]
          ~~~    ~~~~~~~~~
 [ END-ACCEPT ]
   ~~~~~~~~~~

Этот формат оператора ACCEPT используется для получения значений переменных среды.

  1. Зарезервированное слово ON является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. При приёме из ENVIRONMENT-VALUE, вы попросите систему выполнения GnuCOBOL получить значение переменной среды, имя которой в данный момент содержится в регистре ENVIRONMENT-NAME. Значение можно поместить в регистр ENVIRONMENT-NAME с помощью опции ENVIRONMENT-NAME оператора DISPLAY (см. DISPLAY UPON ENVIRONMENT-NAME).
  3. Более простой способ получения значения переменной среды — использовать опцию ENVIRONMENT, в которой вы указываете переменную среды, значение которой необходимо получить непосредственно в операторе ACCEPT.
  4. Необязательные оговорки ON EXCEPTION и NOT ON EXCEPTION могут использоваться для определения и реакции на попытку получения значения несуществующей переменной среды или успешного получения значения переменной среды. Дополнительная информация приведена в разделе ON EXCEPTION + NOT ON EXCEPTION.

7.8.1.4. ПРИЁМ screen-data-item

Синтаксис ПРИЁМ screen-data-item

   ACCEPT { identifier-1 }
   ~~~~~~
          { OMITTED      }
            ~~~~~~~
                           [{ FROM EXCEPTION-STATUS }]
                              ~~~~ ~~~~~~~~~~~~~~~~
                           [{ FROM CRT ] [ MODE IS BLOCK ]}
                              ~~~~ ~~~     ~~~~    ~~~~~

          [ AT { | LINE NUMBER { integer-1    }                | } ]
            ~~ { | ~~~~        { identifier-2 }                | }
               { | COLUMN|COL|POSITION|POS NUMBER { integer-2    }
               { | ~~~~~~ ~~~ ~~~~~~~~ ~~~        { identifier-3 }
               {                                                 }
               { { integer-3    }                                }
               { { identifier-4 }                                }

          [ WITH [ Attribute-Specification ]...
            ~~~~
                 [ LOWER|UPPER ]
                   ~~~~~ ~~~~~
                 [ SCROLL { UP   } [ { integer-4    } LINE|LINES ] ]
                   ~~~~~~ { ~~   }   { identifier-5 }
                          { DOWN }
                            ~~~~
                 [ TIMEOUT|TIME-OUT AFTER { integer-5    } ]
                   ~~~~~~~ ~~~~~~~~       { identifier-6 }
                 [ CONVERSION ]
                   ~~~~~~~~~~
                 [ UPDATE ]
                   ~~~~~~
                 [ SIZE  { integer-6    } ]
                   ~~~~  { identifier-7 }
          [ ON EXCEPTION imperative-statement-1 ]
               ~~~~~~~~~
          [ NOT ON EXCEPTION imperative-statement-2 ]
            ~~~    ~~~~~~~~~
 [ END-ACCEPT ]
   ~~~~~~~~~~

Оговорки FROM CRT, MODE IS BLOCK и CONVERSION синтаксически распознаются, но в остальном не выполняют никакой функции.

Этот формат оператора ACCEPT используется для получения данных с экрана форматированного консольного окна.

  1. Зарезервированные слова AFTER, IS, NUMBER и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированные слова COLUMN, COL и POSITION взаимозаменяемы.
  3. Зарезервированные слова TIMEOUT и TIME-OUT взаимозаменяемы.
  4. Если identifier-1 определен в SCREEN SECTION (см. РАЗДЕЛ ЭКРАНА), любые AT, Attribute-Specification, LOWER, UPPER или SCROLL предложения будут проигнорированы. В этих случаях произойдет неявное DISPLAY (см. ЭЛЕМЕНТ ДАННЫХ ЭКРАНА) для identifier-1 перед тем, как принять ввод. Кодирование явного DISPLAY identifier-1 перед ACCEPT identifier-1 избыточно и повлечет за собой штрафные расходы на производительность из-за повторной отрисовки содержимого экрана.
  5. Различные предложения AT позволяют установить курсор в определенную точку на экране перед чтением экрана. Может быть использовано одно или другое (но не оба), как показано ниже:
    1. Предложения LINE и COLUMN предоставляют один механизм для указания строки и столбца, в которые будет помещен курсор перед тем, как разрешить пользователю ввести данные. При отсутствии одного из них по умолчанию принимается значение 1 для отсутствующего. Однако предпочтение автора — явно кодировать оба.
    2. Значение literal-3 или identifier-4, если указано, должно быть четырех- или шестизначным значением, где первая половина числа указывает строку, в которую должен быть помещен курсор, а вторая половина — столбец. В любом предложении ACCEPT вы можете кодировать только одно из каждого предложения.
  6. Опции WITH (включая различные отдельные Attribute-Specifications) должны быть закодированы только один раз.
  7. Следующие предложения Attribute-Specification разрешены в операторе ACCEPT; эти же предложения разрешены для элементов данных SCREEN SECTION. Конкретное предложение Attribute-Specification может быть использовано только один раз в любом ACCEPT:
    • AUTO (см. AUTO), AUTO-SKIP (см. AUTO-SKIP), AUTOTERMINATE (см. AUTOTERMINATE), TAB
    • BACKGROUND-COLOR (см. ЦВЕТ ФОНА)
    • BEEP (см. BEEP), BELL (см. ЗВОНОК)
    • BLINK (см. МИГАНИЕ)
    • FOREGROUND-COLOR (см. ЦВЕТ ПЕРЕДНЕГО ПЛАНА)
    • FULL (см. FULL), LENGTH-CHECK (см. ПРОВЕРКА ДЛИНЫ)
    • HIGHLIGHT (см. ВЫДЕЛЕНИЕ)
    • LEFTLINE (см. ЛЕВАЯ ЛИНИЯ)
    • LOWLIGHT (см. ПРИТУШЕНИЕ)
    • OVERLINE (см. ЛИНИЯ СВЕРХУ)
    • PROMPT (см. ЗАПРОС)
    • PROTECTED (см. ЗАЩИЩЕННЫЙ)
    • REQUIRED (см. ОБЯЗАТЕЛЬНЫЙ), EMPTY-CHECK (см. ПРОВЕРКА НА ПУСТОТУ)
    • REVERSE-VIDEO (см. ОБРАТНЫЙ ВИДЕОРЕЖИМ)
    • SECURE (см. БЕЗОПАСНЫЙ), NO-ECHO (см. БЕЗ ЭХО)
    • UNDERLINE (см. ЛИНИЯ ПОД ЧЕРТОЙ)
  8. Опция SCROLL заставит весь экран прокрутиться на UP или DOWN указанное количество строк перед отображением любого значения на экране. Синтаксически допустимо указать как предложение SCROLL UP, так и предложение SCROLL DOWN. В таком случае будет учтено последнее из указанных. Если не указано предложение LINES, предполагается 1 LINE.
  9. Опция TIMEOUT заставит ACCEPT подождать не более указанного количества секунд для ввода. Время ожидания может быть указано как положительное целое число или числовым элементом данных с положительным значением.
  10. Опция UPDATE позволит обновить предоставленное поле данных, отображенное на экране до ввода данных, перезаписывая, если необходимо. Если эта опция не используется, поле ввода очищается перед вводом, и это значение по умолчанию, но его можно изменить с помощью команды компилятора -faccept-with-update, которую можно ввести при запуске компилятора или включить в файл конфигурации, например, default.conf, используемый по умолчанию -std=default. Для получения дополнительной информации см. cobc - Компилятор GnuCOBOL (переключатели опций) и Файлы конфигурации компилятора.
  1. Этот формат оператора ACCEPT завершится любым из следующих событий:
    1. При нажатии клавиши Enter.
    2. Истечение времени таймера TIMEOUT — это будет считаться как нажатие клавиши Enter без ввода данных.
    3. При нажатии функциональной клавиши (Fn).
    4. При нажатии клавиш PgUp или PgDn, если переменная среды выполнения COB_SCREEN_EXCEPTIONS (см. Переменные среды выполнения) установлена в любое отличное от пустого значение.
    5. При нажатии клавиши Esc, если обе переменные среды выполнения COB_SCREEN_ESC и COB_SCREEN_EXCEPTIONS установлены в любое отличное от пустого значение.
    6. При нажатии клавиш Up-arrow, Down-Arrow или PrtSc (Print Screen). Однако эти клавиши не распознаются в системах Windows.
  2. Следующее применяется, когда identifier-1 определён в SCREEN SECTION:
    1. Данные, введённые в identifier-1 или любой элемент экрана, подчиненный ему, должны соответствовать пункту PICTURE (см. PICTURE) этого элемента. Это будет проверено во время выполнения оператором ACCEPT.
    2. Если identifier-1 или любой подчиненный ему элемент экрана определены как числовые, введённые данные должны быть приемлемы в качестве входных данных для встроенной функции NUMVAL (см. NUMVAL) (десятичные точки не допускаются). Сохранённое значение в элементе экрана будет таким, как если бы входные данные были переданы этой функции.
    3. Если identifier-1 или любой подчиненный ему элемент экрана определены как числовые, отформатированные, введённые данные должны быть приемлемы в качестве входных данных для встроенной функции NUMVAL-C (см. NUMVAL-C) (снова, десятичные точки не допускаются). Сохранённое значение в элементе экрана будет таким, как если бы входные данные были переданы этой функции.
  3. Следующее применяется, когда identifier-1 не определён в SCREEN SECTION:
    1. Данные, введённые в identifier-1, должны соответствовать пункту PICTURE (см. PICTURE) этого элемента, хотя это не будет проверяться оператором ACCEPT. Вы можете использовать Class Conditions (см. Условий класса) после принятия данных для проверки типа данных.
    2. Если identifier-1 определён как числовой, введённые данные должны быть приемлемы в качестве входных данных для встроенной функции NUMVAL (см. NUMVAL) (десятичные точки не допускаются). Сохранённое значение в identifier-1 будет таким, как если бы входные данные были переданы этой функции.
    3. Если identifier-1 определён как числовой, отформатированный, введённые данные должны быть приемлемы в качестве входных данных для встроенной функции NUMVAL-C (см. NUMVAL-C) (снова, десятичные точки не допускаются). Сохранённое значение в identifier-1 будет таким, как если бы входные данные были переданы этой функции.
  4. Необязательные пункты ON EXCEPTION и NOT ON EXCEPTION могут использоваться для обнаружения и реакции соответственно на неудачу или успех попытки ввода-вывода экрана. Дополнительную информацию см. в разделе ON EXCEPTION + NOT ON EXCEPTION.

    После выполнения этого формата оператора ACCEPT, идентификатор программы CRT STATUS (см. SPECIAL-NAMES) будет заполнен одним из следующих значений:

  1. Код Значение
    0000 ENTER нажата клавиша
    1001–1064 F1–F64, соответственно, были нажаты
    2001 PgUp была нажата
    2002 PgDn была нажата
    2003 Up-Arrow была нажата
    2004 Down-Arrow была нажата
    2005 Esc была нажата. Кнопка подтверждения пропущена
    2006 PrtSc (Print Screen) была нажата
    2007 Tab
    2008 Back Tab
    2009 Key Left
    2010 Key Right
    2011 Insert Кнопка подтверждения пропущена
    2012 Delete Кнопка подтверждения пропущена
    2013 Backspace Кнопка подтверждения пропущена
    2014 Home Кнопка подтверждения пропущена
    2015 End Кнопка подтверждения пропущена
    2040- Ключи исключений для обработки мыши 2095
    2040 Перемещение мыши
    2041 Левая кнопка нажата
    2042 Левая кнопка отпущена
    2043 Двойной щелчок левой кнопкой
    2044 Средняя кнопка нажата
    2045 Средняя кнопка отпущена
    2046 Двойной щелчок средней кнопкой
    2047 Правая кнопка нажата
    2048 Правая кнопка отпущена
    2049 Двойной щелчок правой кнопкой
    2050 Перемещение мыши со Shift
    2051 Левая кнопка нажата со Shift
    2052 Левая кнопка отпущена со Shift
    2053 Двойной щелчок левой кнопкой со Shift
    2054 Средняя кнопка нажата со Shift
    2055 Средняя кнопка отпущена со Shift
    2056- Двойной щелчок средней кнопкой со Shift
    2057 Правая кнопка нажата со Shift
    2058 Правая кнопка отпущена со Shift
    2059 Двойной щелчок правой кнопкой со Shift
    2060 Перемещение мыши с Ctrl
    2061 Левая кнопка нажата с Ctrl
    2062 Левая кнопка отпущена с Ctrl
    2063 Двойной щелчок левой кнопкой с Ctrl
    2064 Средняя кнопка нажата с Ctrl
    2065 Средняя кнопка отпущена с Ctrl
    2066 Двойной щелчок средней кнопкой с Ctrl
    2067 Правая кнопка нажата с Ctrl
    2068 Правая кнопка отпущена с Ctrl
    2069 Двойной щелчок правой кнопкой с Ctrl
    2070 Перемещение мыши с Alt
    2071 Левая кнопка нажата с Alt
    2072 Левая кнопка отпущена с Alt
    2073- Двойной щелчок левой кнопкой с Alt
    2074 Средняя кнопка нажата с Alt
    2075 Средняя кнопка отпущена с Alt
    2076 Двойной щелчок средней кнопкой с Alt
    2077 Правая кнопка нажата с Alt
    2078 Правая кнопка отпущена с Alt
    2079 Двойной щелчок правой кнопкой с Alt
    2080 Прокрутка вверх
    2081 Прокрутка вниз
    2082 Прокрутка влево
    2083 Прокрутка вправо
    2084 Прокрутка вверх со Shift
    2085 Прокрутка вниз со Shift
    2086 Прокрутка влево со Shift
    2087 Прокрутка вправо со Shift
    2088 Прокрутка вверх с Ctrl
    2089 Прокрутка вниз с Ctrl
    2090 Прокрутка влево с Ctrl
    2091 Прокрутка вправо с Ctrl
    2092 Прокрутка вверх с Alt
    2093 Прокрутка вниз с Alt
    2094 Прокрутка влево с Alt
  1. 2095 Альтернативная кнопка вправо
    Валидация ввода
    8000 Поле отсутствует
    8001 Таймаут
    Другие ошибки
    9000 Критическая ошибка
    9001 Предельное поле
  2. Фактический нажатый ключ для генерации функциональной клавиши (Fn) зависит от типа используемого терминального устройства (ПК, Macintosh, VT100 и т. д.) и типа настроек драйвера расширенного дисплея, используемого с вашей версией GnuCOBOL.

    Например, в сборке GnuCOBOL для ПК с Windows, использующей MinGW и «PDCurses», F1–F12 — это фактические функциональные клавиши на клавиатуре ПК, F13–F24 вводятся с нажатой клавишей Shift, F25–F36 вводятся с нажатой клавишей Ctrl, а F37–F48 вводятся с нажатой клавишей Alt. С другой стороны, реализация GnuCOBOL, созданная для Windows с использованием Cygwin и NCurses, обрабатывает клавиши ПК F1–F12 как фактические F1–F12, а функциональные клавиши со нажатой Shift — как F11–F20. С Cygwin/NCurses не распознаются функциональные клавиши с нажатыми Ctrl и Alt, а также Shift-F11 и Shift-F12.

    Коды клавиш мыши заполняются только в том случае, если управление мышью включено. Для включения мыши необходимо сначала установить COB_MOUSE_FLAGS (либо внешне через команду терминала, либо внутренне через SET ENVIRONMENT до соответствующей маски мыши (указывающей, какие действия вы хотите, чтобы программа обнаруживала). Вот пример настройки маски из программы на COBOL:

    COPY screenio.cpy.
    
    01  mouse-flags PIC 9(4).
    
    ...
    
        COMPUTE mouse-flags = COB-AUTO-MOUSE-HANDLING
                            + COB-ALLOW-LEFT-DOWN
                            + COB-ALLOW-MIDDLE-DOWN
                            + COB-ALLOW-RIGHT-DOWN
    
        SET ENVIRONMENT "COB_MOUSE_FLAGS" TO mouse-flags.
    
    
  3. После этого каждый (расширенный) ACCEPT вернет значение в COB_CRT_STATUS, отражающее активность мыши при её возникновении. Соответствующие значения указаны в screenio.cpy в разделе «Ключи исключений для обработки мыши». Если вы определите переменную в SPECIAL NAMES следующим образом:
    SPECIAL-NAMES.
       CURSOR IS data-name.   *> where data-name is PIC 9(4) or 9(6).
    
  4. Также будет возвращено положение курсора или мыши. Положение выражается строкой и столбцом (rrcc или rrrccc).
  5. Клавиши цифровой клавиатуры не распознаются в сборках GnuCOBOL для Windows MinGW/PDCurses независимо от настроек Num Lock. Сборки Windows Cygwin/NCurses распознают ввод с цифровой клавиатуры корректно. Хотя при подготовке этой документации это не тестировалось, я ожидал бы, что собственные сборки Windows с PDCurses будут вести себя так же, как сборки MinGW, а собственные сборки Unix с NCurses — как сборки Cygwin.
  6. Дополнительная EXCEPTION-STATUS-клауза может использоваться для обнаружения исключений из предыдущей арифметической команды, например, COMPUTE, для восстановления любых возникших ошибок. Они восстанавливаются с помощью функции EXCEPTION-STATUS.

7.8.1.5. ACCEPT FROM DATE/TIME

ACCEPT FROM DATE/TIME Синтаксис

   ACCEPT identifier-1 FROM { DATE [ YYYYMMDD ] }
   ~~~~~~              ~~~~ { ~~~~   ~~~~~~~~   }
                            { DAY [ YYYYDDD ]   }
                            { ~~~   ~~~~~~~     }
                            { DAY-OF-WEEK       }
                            { ~~~~~~~~~~~       }
 [ END-ACCEPT ]             { TIME              }
   ~~~~~~~~~~

Этот формат инструкции ACCEPT используется для получения текущей даты, времени или текущего дня недели системы и сохранения их в элемент данных.

  1. Данные, полученные из системы, и формат их структуры будут различаться следующим образом:
    Синтаксис Полученные данные Формат
    DATE Текущая дата в григорианском формате yymmdd
    DATE YYYYMMDD Текущая дата в григорианском формате yyyymmdd
    DAY Текущая дата в юлианском формате yyddd
    DAY YYYYDDD Текущая дата в юлианском формате yyyyddd
    TIME Время, включая сотые доли секунды (nn) hhmmssnn

7.8.1.6. ACCEPT FROM Screen-Info

ACCEPT FROM Screen-Info Синтаксис

   ACCEPT identifier-1
   ~~~~~~
          FROM { LINES|LINE-NUMBER }
          ~~~~ { ~~~~~ ~~~~~~~~~~~ }
               { COLS|COLUMNS      }
               { ~~~~ ~~~~~~~      }
               { ESCAPE KEY        }
                 ~~~~~~ ~~~
 [ END-ACCEPT ]
   ~~~~~~~~~~

Этот формат инструкции ACCEPT используется для получения информации о консольном окне или о взаимодействии пользователя с ним.

  1. Зарезервированные слова LINES и LINE-NUMBER взаимозаменяемы.
  2. Зарезервированные слова COLS и COLUMNS взаимозаменяемы.
  3. Следующие пункты касаются использования опций LINES и COLUMNS:
    1. Опции LINES и COLUMNS получат соответствующие компоненты размера дисплея консоли.
    2. Когда консоль выполняется в оконной среде, это будет размер окна, в котором выполняется программа, в количестве горизонтальных (COLUMNS) или вертикальных (LINES) символов — а не пикселей.
    3. Когда система не работает в оконной среде, будут возвращены атрибуты физического экрана консоли.
    4. Значения 0 будут возвращены, если GnuCOBOL не был сгенерирован для включения ввода/вывода экрана.
    5. См. документацию по встроенной системной подпрограмме CBL_GET_SCR_SIZE (см. CBL_GET_SCR_SIZE) для другого способа получения этой информации.
  4. Опция ESCAPE KEY может быть использована после выполнения оператора ACCEPT FROM Screen-Info (см. ACCEPT FROM Screen-Info). Возвращаемое значение будет четырехзначным идентификатором CRT STATUS (см. SPECIAL-NAMES). См. CRT STATUS Codes для конкретных значений кодов.

7.8.1.7. ПРИНЯТЬ ОТ Runtime-Info

Синтаксис ПРИНЯТЬ ОТ Runtime-Info

   ACCEPT identifier-1
   ~~~~~~
          FROM { EXCEPTION STATUS }
          ~~~~ { ~~~~~~~~~ ~~~~~~ }
               { USER NAME        }
                 ~~~~ ~~~~
 [ END-ACCEPT ]
   ~~~~~~~~~~

Этот формат оператора ACCEPT используется для получения информации о времени выполнения, такой как код последней исключительной ошибки и имя текущего пользователя.

  1. Следующие пункты касаются использования опции EXCEPTION STATUS:
    1. identifier-1 должен быть определён как элемент PIC X(4).
    2. См. Error Exception Codes для полного списка кодов исключений и их значений.
    3. Альтернативой использованию ACCEPT FROM Runtime-Info является использование встроенной функции EXCEPTION-STATUS (см. EXCEPTION-STATUS).
  2. Следующие пункты касаются использования опции USER NAME:
    1. Возвращаемое значение — идентификатор пользователя, который использовался для входа в систему, а не фактическое имя и/или фамилия пользователя (если, конечно, эта информация не используется в качестве идентификатора входа). Это не номера PID или UID, а имя, связанное с UID в системах на основе *nix.
    2. identifier-1 должен быть достаточно большим, чтобы принять самое длинное имя пользователя в системе.
    3. Если выделено недостаточно места, возвращаемое значение будет усечено.
    4. Если выделено избыточное место, возвращаемое значение будет дополнено пробелами (справа).

7.8.1.8. ПРИНЯТЬ ПРОПУЩЕННОЕ

Синтаксис ПРИНЯТЬ ПРОПУЩЕННОЕ

   ACCEPT OMITTED
   ~~~~~~

   1.  For console : See 6.17.1.1 (ACCEPT FROM CONSOLE Syntax)

   2.  For Screen  : See 6.17.1.4 (ACCEPT screen-data-item Syntax)

 [ END-ACCEPT ]
   ~~~~~~~~~~

Этот формат оператора ACCEPT будет ждать события ввода с клавиатуры, которое завершит ввод; среди других, функциональные клавиши или Enter/Return. CRT STATUS (COB-CRT-STATUS CRT STATUS (см. SPECIAL-NAMES), если не определён явно) устанавливается с кодом клавиши, указанным в copy/screenio.cpy. Он также обрабатывает несколько других кодов клавиш, не используемых обычно для завершения расширенного приема.

  1. Примеры кодов клавиш:
    COB-SCR-INSERT
    COB-SCR-DELETE
    COB-SCR-BACKSPACE
    COB-SCR-KEY-HOME
    COB-SCR-KEY-END
    
  2. Вы можете использовать расширенные атрибуты, полезные для установки тайм-аутов или позиционирования.

7.8.1.9. ПРИНЯТЬ ОТ EXCEPTION-STATUS

Синтаксис ПРИНЯТЬ ОТ EXCEPTION-STATUS

   ACCEPT exception-status-pic-9-4   FROM EXCEPTION-STATUS
   ~~~~~~                            ~~~~ ~~~~~~~~~~~~~~~~

 [ END-ACCEPT ]
   ~~~~~~~~~~

Этот формат оператора ACCEPT получит статус любых исключений, возникших в результате предыдущей успешной команды.

  1. Пример использования:
     In WS:
     01  exception-status  pic 9(4).
    ..
     In PD:
    
     ACCEPT unexpected-rounding  FROM EXCEPTION-STATUS
     IF unexpected-rounding NOT EQUAL "0000" THEN
        DISPLAY "Unexpected rounding. Code " unexpected-rounding
                 UPON SYSERR
     END-IF
    

7.8.2. СЛОЖЕНИЕ

7.8.2.1. СЛОЖЕНИЕ С

Синтаксис СЛОЖЕНИЕ С

   ADD { literal-1    }...
   ~~~ { identifier-1 }

       TO { identifier-2
       ~~
          [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
            ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                              { NEAREST-AWAY-FROM-ZERO }
                              { ~~~~~~~~~~~~~~~~~~~~~~ }
                              { NEAREST-EVEN           }
                              { ~~~~~~~~~~~~           }
                              { NEAREST-TOWARD-ZERO    }
                              { ~~~~~~~~~~~~~~~~~~~    }
                              { PROHIBITED             }
                              { ~~~~~~~~~~             }
                              { TOWARD-GREATER         }
                              { ~~~~~~~~~~~~~~         }
                              { TOWARD-LESSER          }
                              { ~~~~~~~~~~~~~          }
                              { TRUNCATION             }
                                ~~~~~~~~~~
     [ ON SIZE ERROR imperative-statement-1 ]
          ~~~~ ~~~~~
     [ NOT ON SIZE ERROR imperative-statement-2 ]
       ~~~    ~~~~ ~~~~~
 [ END-ADD ]
   ~~~~~~~

Этот формат оператора ADD генерирует промежуточную арифметическую сумму значений всех элементов identifier-1 и literal-1). Значение каждого identifier-2 будет заменено, по очереди, суммой значения этого identifier-2 и промежуточной суммы.

  1. Зарезервированные слова IS и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. И identifier-1, и identifier-2 должны быть числовыми неотформатированными данными, а literal-1 — числовой литералом.
  3. Элемент данных identifier-1 также может быть закодирован как identifier-2. Однако обратите внимание, что значение такого элемента данных будет включено дважды в результате.
  4. Содержимое каждого identifier-1 останется неизменным в результате этого оператора.
  5. Необязательная ROUNDED (см. ROUNDED) -определяющая фраза, доступная для каждого identifier-2, будет контролировать, как будут сохраняться результаты, не являющиеся целыми числами.
  6. Необязательные ON SIZE ERROR и NOT ON SIZE ERROR фразы могут быть использованы для обнаружения и реагирования на неудачу или успех попытки выполнения вычисления соответственно. В этом случае неудача определяется как identifier-2 с недостаточным количеством разрядов слева от предполагаемой десятичной точки. См. ON SIZE ERROR + NOT ON SIZE ERROR для дополнительной информации.

7.8.2.2. Сложение с результатом

Синтаксис ADD GIVING

   ADD { literal-1    }...
   ~~~ { identifier-1 }

     [ TO identifier-2 ]
       ~~
       GIVING { identifier-3
       ~~~~~~
         [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
           ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                             { NEAREST-AWAY-FROM-ZERO }
                             { ~~~~~~~~~~~~~~~~~~~~~~ }
                             { NEAREST-EVEN           }
                             { ~~~~~~~~~~~~           }
                             { NEAREST-TOWARD-ZERO    }
                             { ~~~~~~~~~~~~~~~~~~~    }
                             { PROHIBITED             }
                             { ~~~~~~~~~~             }
                             { TOWARD-GREATER         }
                             { ~~~~~~~~~~~~~~         }
                             { TOWARD-LESSER          }
                             { ~~~~~~~~~~~~~          }
                             { TRUNCATION             }
                               ~~~~~~~~~~
     [ ON SIZE ERROR imperative-statement-1 ]
          ~~~~ ~~~~~
     [ NOT ON SIZE ERROR imperative-statement-2 ]
       ~~~    ~~~~ ~~~~~
 [ END-ADD ]
   ~~~~~~~

Этот формат оператора ADD генерирует арифметическую сумму значений всех элементов identifier-1, literal-1) и identifier-2 (если таковые имеются), а затем сохраняет эту сумму в каждый identifier-3.

  1. Зарезервированные слова IS и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. И identifier-1, и identifier-2 должны быть числовыми неотформатированными элементами данных, а literal-1 — числовым литералом; identifier-3 может быть числовым или отформатированным числовым элементом данных.
  3. Элемент данных identifier-1 или identifier-2 может использоваться как identifier-3, если это необходимо.
  4. Содержимое каждого identifier-1 и identifier-2 останется неизменным в результате этого оператора, если только они не будут также указаны как identifier-3.
  5. Текущее значение в каждом identifier-3 в начале выполнения оператора не имеет значения, так как содержимое каждого identifier-3 будет просто заменено вычисленной суммой.
  6. Необязательная ROUNDED (см. ROUNDED) -определяющая фраза, доступная для каждого identifier-3, будет контролировать, как будут сохраняться результаты, не являющиеся целыми числами.
  7. Необязательные ON SIZE ERROR и NOT ON SIZE ERROR фразы могут быть использованы для обнаружения и реагирования на неудачу или успех попытки выполнения вычисления соответственно. В этом случае неудача определяется как identifier-3 с недостаточным количеством разрядов слева от предполагаемой десятичной точки. См. ON SIZE ERROR + NOT ON SIZE ERROR для дополнительной информации.

7.8.2.3. Сложение по соответствию

Синтаксис ADD CORRESPONDING

   ADD CORRESPONDING identifier-1
   ~~~
       TO identifier-2
       ~~
     [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ]
       ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                         { NEAREST-AWAY-FROM-ZERO }
                         { ~~~~~~~~~~~~~~~~~~~~~~ }
                         { NEAREST-EVEN           }
                         { ~~~~~~~~~~~~           }
                         { NEAREST-TOWARD-ZERO    }
                         { ~~~~~~~~~~~~~~~~~~~    }
                         { PROHIBITED             }
                         { ~~~~~~~~~~             }
                         { TOWARD-GREATER         }
                         { ~~~~~~~~~~~~~~         }
                         { TOWARD-LESSER          }
                         { ~~~~~~~~~~~~~          }
                         { TRUNCATION             }
                           ~~~~~~~~~~
     [ ON SIZE ERROR imperative-statement-1 ]
          ~~~~ ~~~~~
     [ NOT ON SIZE ERROR imperative-statement-2 ]
       ~~~    ~~~~ ~~~~~
 [ END-ADD ]
   ~~~~~~~

Этот формат оператора ADD генерирует код, эквивалентный отдельным операторам ADD TO (см. ADD TO) для соответствующих совпадений элементов данных, найденных подчиненно двум идентификаторам.

  1. Зарезервированные слова IS и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. И identifier-1, и identifier-2 должны быть группами элементов.
  3. См. CORRESPONDING для информации о том, как будут находиться соответствующие совпадения между identifier-1 и identifier-2.
  4. Необязательная ROUNDED (см. ROUNDED) -определяющая фраза, доступная для каждого identifier-3, будет контролировать, как будут сохраняться результаты, не являющиеся целыми числами.
  5. Необязательные ON SIZE ERROR и NOT ON SIZE ERROR фразы могут быть использованы для обнаружения и реагирования на неудачу или успех попытки выполнения вычисления соответственно. В этом случае неудача определяется как identifier-3 с недостаточным количеством разрядов слева от предполагаемой десятичной точки. См. ON SIZE ERROR + NOT ON SIZE ERROR для дополнительной информации.

7.8.3. Выделение памяти

Синтаксис ALLOCATE

 ALLOCATE { expression-1 CHARACTERS } [ { INITIALIZED } ]
 ~~~~~~~~ { identifier-1 ~~~~~~~~~~ }   { ~~~~~~~~~~~ }
                                        { INITIALISED }
     [ RETURNING identifier-2 ]           ~~~~~~~~~~~
       ~~~~~~~~~

Оператор ALLOCATE используется для динамического выделения памяти во время выполнения.

  1. Зарезервированные слова INITIALIZED и INITIALISED взаимозаменяемы.
  2. Оба identifier-1 и RETURNING identifier-2 не могут быть указаны в одном операторе.
  3. Если используется, expression-1 должно быть арифметическим выражением с положительным целым значением, отличным от нуля.
  4. Если используется, identifier-1 должен быть элементом 01-уровня, определенным в рабочей или локальной памяти с атрибутом BASED (см. BASED). Он может быть элементом 01, определенным в разделе связи без атрибута BASED, но использование такого элемента данных не рекомендуется.
  5. Если используется, identifier-2 должен быть элементом данных типа POINTER (см. USAGE).
  6. Необязательная RETURNING-клауза вернет адрес выделенного блока памяти в указанный USAGE POINTER элемент данных identifier-2. При использовании этого варианта программа сохранит информацию о первоначально запрошенном размере выделенного блока памяти, если когда-либо будет выдан оператор FREE (см. FREE) для identifier-2.
  7. При использовании опции identifier-1 совместно с INITIALIZED (или его международным аналогом INITIALISED) выделенный блок памяти будет инициализирован так, как если бы был выполнен оператор INITIALIZE identifier-1 WITH FILLER ALL TO VALUE THEN TO DEFAULT (см. INITIALIZE).
  8. При использовании опции expression-1 CHARACTERS INITIALIZED инициализирует выделенный блок памяти двоичными нулями. Если INITIALIZED не используется, начальное содержимое выделенной памяти будет определяться правилами выделения памяти для операционной системы, в которой работает программа.
  9. Существует два основных способа использования этого оператора. Самый простой:
    ALLOCATE My-01-Item
    

    В этом формате блок памяти, равный по размеру определенному размеру My-01-Item (который должен быть определен с атрибутом BASED), будет выделен. Адрес этого блока памяти станет базовым адресом My-01-Item, так что он и его подчиненные элементы данных станут доступны внутри программы.

    Второй (и эквивалентный) подход:

    ALLOCATE LENGTH OF My-01-Item CHARACTERS RETURNING The-Pointer
    SET ADDRESS OF My-01-Item TO The-Pointer
    
  10. В этом формате My-01-Item может быть определен с атрибутом BASED или определен в разделе LINKAGE. Вместо LENGTH OF My-01-Item можно использовать и меньший размер, до максимального размера поля, при условии, что поле полностью не используется.
  11. Обращение к элементу данных BASED до выделения памяти или после её освобождения (через оператор FREE) приведёт к «непредсказуемым результатам». Так описывают подобные ситуации справочные материалы и спецификации стандартов. По собственному опыту автора, результаты довольно предсказуемы: программа прерывается при попытке обратиться к незарезервированной области памяти.

7.8.4. ALTER

ALTER Синтаксис

 ALTER procedure-name-1 TO PROCEED TO procedure-name-2
 ~~~~~                  ~~

Оператор ALTER использовался в ранние годы языка COBOL для изменения объектного кода программы во время выполнения, изменяя оператор GO TO (см. Simple GO TO) на переход к другой точке программы, отличной от той, на которую оператор GO TO был первоначально скомпилирован.

  1. Зарезервированные слова PROCEED и TO (то, что после PROCEED) являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. procedure-name-1 должно содержать только один оператор, и этот оператор должен быть простым GO TO.
  3. Эффект этого оператора будет таким, как будто сгенерированный машинный код для оператора GO TO в procedure-name-1 изменён таким образом, что оператор GO TO теперь передает управление procedure-name-2, а не тому имени процедуры, которое было указано в исходном коде.
  4. Поддержка глагола ALTER была добавлена в GnuCOBOL для обеспечения возможности прохождения тестов Национального института стандартов и технологий (NIST) для языка программирования COBOL, которые требуют поддержки ALTER.
  5. Из-за катастрофического влияния этого оператора на читаемость программы, а следовательно, на способность программиста отлаживать проблемы с логикой программы, использование ALTER в новых программах НАСТОЛЬКО не рекомендуется.

7.8.5. CALL

CALL Синтаксис

   CALL [ { STDCALL         } ] { literal-1    }
   ~~~~   { ~~~~~~~         }   { identifier-1 }
          { STATIC          }
          { ~~~~~~          }
          { mnemonic-name-1 }

        [ USING CALL-Argument... ]
          ~~~~~
        [ RETURNING|GIVING identifier-2 ]
          ~~~~~~~~~ ~~~~~~
        [ ON OVERFLOW|EXCEPTION imperative-statement-1 ]
             ~~~~~~~~ ~~~~~~~~~
        [ NOT ON OVERFLOW|EXCEPTION imperative-statement-2 ]
          ~~~    ~~~~~~~~ ~~~~~~~~~
 [ END-CALL ]
   ~~~~~~~~

CALL Синтаксис аргументов

 [ BY { REFERENCE } ]
      { ~~~~~~~~~ }
      { CONTENT   }
      { ~~~~~~~   }
      { VALUE     }
        ~~~~~

      { OMITTED                                                   }
      { ~~~~~~~                                                   }
      { [ UNSIGNED ] [ SIZE IS { AUTO      } ] [ { literal-2    } }
          ~~~~~~~~     ~~~~    { ~~~~      }     { identifier-2 }
                               { DEFAULT   }
                               { ~~~~~~~   }
                               { integer-1 }

Оператор CALL используется для передачи управления подпрограмме. См. Sub-Programming для получения подробной информации об использовании подпрограмм в программах GnuCOBOL.

  1. Зарезервированные слова BY, IS и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не оказывает влияния на программу.
  2. Зарезервированные слова EXCEPTION и OVERFLOW взаимозаменяемы.
  3. Зарезервированные слова GIVING и RETURNING взаимозаменяемы.
  4. Ожидается, что подпрограмма в конечном итоге вернет управление обратно вызывающей программе, в этот момент вызывающая программа возобновит выполнение, начиная с инструкции, следующей за CALL. Подпрограммы не обязаны возвращаться к своим вызывающим программам и могут остановить выполнение программы по желанию.
  5. Опция mnemonic-name-1 / STATIC / STDCALL, если используется, влияет на соглашения о связывании, используемые для вызываемой подпрограммы, следующим образом:
    STATIC

    приводит к выполнению связывания с подпрограммой таким образом, что подпрограмма должна быть статически связана с вызывающей программой. Обратите внимание, что это позволяет использовать статическое связывание на выборочной основе для каждой подпрограммы.

    STDCALL

    позволяет использовать стандартные соглашения вызова системы (в отличие от соглашений вызова GnuCOBOL) при вызове подпрограммы. Определение того, что считается «стандартными соглашениями системы», может варьироваться от одной операционной системы к другой. Для использования этого необходимы специальные знания о требованиях к связыванию подпрограмм, которые вы планируете CALL. Подпрограммы, написанные на GnuCOBOL, не нуждаются в этой опции.

    mnemonic-name-1

    позволяет использовать настраиваемое соглашение вызова. Такие мнемонические имена определяются с помощью пункта CALL-CONVENTION (см. SPECIAL-NAMES). Этот пункт связывает десятичное целое значение с mnemonic-name-1 таким образом, что отдельные биты, установленные или сброшенные в двоичном эквиваленте целого числа, влияют на связывание с подпрограммой, как описано в следующей таблице. Строки таблицы, помеченные «Нет» в столбце Поддерживается, представляют битовые позиции (настройки переключателей) в целочисленном значении, которые в настоящее время принимаются (для обеспечения совместимости с другими реализациями COBOL), если запрограммированы, но в противном случае не поддерживаются.

    Обратите внимание, что бит 0 — это самый младший бит в двоичном значении.

    Бит Поддерживается Значение, если 0 Значение, если 1
    0 Нет Аргументы передаются в порядке справа налево Аргументы передаются в порядке слева направо.
    1 Нет Вызывающая программа удалит обработанные аргументы из стека аргументов. Вызываемая программа (подпрограмма) удалит обработанные аргументы из стека аргументов.
    2 Да Регистр RETURN-CODE (см. Специальные регистры) будет обновлен дополнительно к любым данным элементам RETURNING или GIVING. Регистр RETURN-CODE не будет обновлен (но любые данные элементов RETURNING или GIVING все равно будут).
    3 Да Если используется CALL literal, подпрограмма будет расположена и связана с вызывающей программой во время компиляции или может быть динамически расположена и загружена во время выполнения, в зависимости от настроек переключателей компилятора и возможностей операционной системы. Если используется CALL literal, подпрограмма может быть расположена и связана с вызывающей программой только во время компиляции.
    4 Нет Соглашения OS/2 «OPTLINK» не будут использованы для ВЫЗОВА подпрограммы. Соглашения OS/2 «OPTLINK» будут использованы для ВЫЗОВА подпрограммы.
    5 Нет Windows 16-разрядное «эмулирование» не будет активным. Windows 16-разрядное «эмулирование» будет использовано для вызова подпрограммы как DLL.
    6 Да Соглашение STDCALL не будет использоваться. Соглашение STDCALL, необходимое для использования API Microsoft Win32, будет использоваться.

    Использование опции STATIC в инструкции CALL эквивалентно использованию CALL-CONVENTION 8 (только бит 3 установлен).

    Использование опции STDCALL в инструкции CALL эквивалентно использованию CALL CONVENTION 64 (только бит 6 установлен).

  6. Значение literal-1 или identifier-1 — это точка входа в подпрограмму, которую вы хотите вызвать.
  7. При вызове подпрограммы с помощью identifier-1 вы заставляете систему выполнения вызвать динамически загружаемую подпрограмму. Содержимое identifier-1 будет именем точки входа в этот модуль. Если это первый вызов любой точки входа в модуль, выполняемый во время выполнения, содержимое identifier-1 должно быть основным именем точки входа в модуль (которое также должно совпадать с именем файла без указанных операционной системой расширений) исполняемого файла, составляющего модуль).
  1. Вы можете принудительно загрузить все динамически загружаемые модули, которые могут быть вызваны программой, в момент запуска программы. Это достигается с помощью переменной среды выполнения COB_PRE_LOAD (см. Переменные среды выполнения). Если используется, это будет загружать только те модули, которые вызываются через CALL literal-1, поскольку содержимое среды выполнения identifier-1 не может быть предсказано.
  2. Если вызываемая подпрограмма — это программа GnuCOBOL, и если у этой программы был указан атрибут INITIAL (см. РАЗДЕЛ ИДЕНТИФИКАЦИИ) в её PROGRAM-ID-командном блоке, все данные разделов данных подпрограммы будут возвращены в исходное состояние каждый раз при выполнении подпрограммы, независимо от точки входа в подпрограмму.

    Это [повторное] поведение инициализации всегда будет применяться к локальному хранилищу любой подпрограммы (если оно есть), независимо от использования (или отсутствия) INITIAL.

  3. Команда USING определяет список аргументов, которые могут передаваться из вызывающей программы в подпрограмму. Способ передачи аргумента подпрограмме зависит от команды BY (если она есть) для этого аргумента, следующим образом:
    BY REFERENCE

    передаёт адрес аргумента подпрограмме. Если подпрограмма изменяет содержимое этого аргумента, изменение будет «видимо» для вызывающей программы.

    BY CONTENT

    передаёт адрес копии аргумента подпрограмме. Если подпрограмма изменяет значение такого аргумента, изменение затрагивает только копию в вызывающей программе, а не оригинальную версию.

    BY VALUE

    передаёт фактическое числовое значение содержимого литерала или идентификаторов в качестве аргумента. Эта возможность существует для обеспечения совместимости с C, C++ и другими языками и обычно не используется при вызове подпрограмм GnuCOBOL. В этом случае должны передаваться только числовые литералы или числовые данные.

    Если у аргумента отсутствует команда BY, будет принята самая последняя встречавшаяся команда BY в команде CALL. Если у первого аргумента, указанного в CALL, отсутствует команда BY, будет принято значение BY REFERENCE.

  4. В подпрограмму может быть передано не более 251 аргумента, если компилятор GnuCOBOL не был скомпилирован с другим ограничением по аргументам. Если у вас есть доступ к исходному коду GnuCOBOL, вы можете изменить это ограничение, изменив значение COB_MAX_FIELD_PARAMS в файле call.c (в папке libcob), а также последнее показанное значение #if MAX_CALL_FIELD_PARAMS перед запуском make для построения компилятора и библиотеки времени выполнения.
  5. Команда RETURNING позволяет указать числовой элемент данных, в который подпрограмма должна вернуть числовое значение. Если вы используете эту команду в CALL, подпрограмма должна включать команду RETURNING (см. РАЗДЕЛ ПРОЦЕДУР ВОЗВРАЩАЕТ) в заголовке раздела процедур. Конечно, подпрограмма может передать значение любого типа в любой переданный BY REFERENCE аргумент.
  6. Необязательные команды ON OVERFLOW и NOT ON OVERFLOW (или ON EXCEPTION и NOT ON EXCEPTION — они взаимозаменяемы) могут использоваться для обнаружения и реакции соответственно на неудачу или успех попытки CALL подпрограммы. Неудачей в данном контексте считается невозможность найти или загрузить объектный код подпрограммы во время выполнения. Смотрите ON OVERFLOW + NOT ON OVERFLOW для получения дополнительной информации.
  7. Вызов также поддерживает использование точки входа, хранящейся в PROGRAM-POINTER, избегая динамического поиска во время выполнения. GnuCOBOL хранит кэш поисков во время выполнения программы. Повторное использование именованной функции не влечёт значительных потерь производительности, но PROGRAM-POINTER будет чуть быстрее. Чтобы установить PROGRAM-POINTER, используйте SET program-reference TO ENTRY "name" (или получите адрес из API и участвуйте в программировании обратного вызова).
  8. Расширение CALL позволяет вызвать Program-Pointer-1, который предварительно задаётся с помощью SET program-pointer-1 TO ENTRY x. Дополнительно, команда RETURNING может вернуть указатель на данные или PROGRAM-POINTER

7.8.6. CANCEL

CANCEL Синтаксис

 CANCEL { literal-1    }...
 ~~~~~~ { identifier-1 }

Команда CANCEL выгружает динамически загружаемый модуль подпрограммы, содержащий точку входа, указанную как literal-1 или identifier-1, из памяти.

  1. Если динамически загружаемый модуль, выгруженный командой CANCEL , впоследствии повторно выполняется, все данные раздела данных этого модуля снова будут в исходном состоянии.
  2. Является ли команда CANCEL фактически физическим выгрузкой динамически загружаемого модуля или просто помечает его как логически выгруженный, зависит от использования и значения переменной среды выполнения COB_PHYSICAL_CANCEL (см. Переменные среды выполнения).

7.8.7. CLOSE

CLOSE Синтаксис

 CLOSE { file-name-1 [ { REEL|UNIT [ FOR REMOVAL ] } ] }...
 ~~~~~                 { ~~~~ ~~~~       ~~~~~~~   }
                       { WITH LOCK                 }
                       {      ~~~~                 }
                       { WITH NO REWIND            }
                              ~~ ~~~~~~

Указанные REEL, LOCK и NO REWIND пункты распознаются синтаксически, но в остальном не функциональны, за исключением оператора CLOSE…NO REWIND, который задаст статус файла 07 вместо обычного 00 (но не выполнит никаких других действий).

Оператор CLOSE завершает доступ программы к указанному файлу(ам).

  1. Зарезервированные слова FOR и WITH являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированные слова REEL и UNIT взаимозаменяемы.
  3. Оператор CLOSE может быть выполнен только над файлами, которые были успешно открыты.
  4. Успешное выполнение CLOSE запишет все оставшиеся незаписанные буферы записей в файл (подобно оператору UNLOCK (см. UNLOCK)) и освободит любые блокировки файла, независимо от режима открытия. Закрытый файл больше не будет доступен для последующих операций ввода-вывода до тех пор, пока он не будет снова открыт (OPENED).
  5. При закрытии файла типа ORGANIZATION LINE SEQUENTIAL (см. ORGANIZATION LINE SEQUENTIAL) или LINE ADVANCING (см. LINE ADVANCING), в файл будет записана конечная последовательность разделителей, сигнализирующая о точке завершения последней записи данных в файле. Это необходимо только в том случае, если последняя запись в файл была записана с опцией AFTER ADVANCING (см. WRITE).

7.8.8. COMMIT

COMMIT Синтаксис

 COMMIT
 ~~~~~~

Оператор COMMIT выполняет UNLOCK над каждым открытым в данный момент файлом, но не закрывает ни одного из файлов. Дополнительные сведения см. в операторе UNLOCK (см. UNLOCK).

7.8.9. COMPUTE

COMPUTE Синтаксис

   COMPUTE { identifier-1
   ~~~~~~~
       [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] }...
         ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                           { NEAREST-AWAY-FROM-ZERO }
                           { ~~~~~~~~~~~~~~~~~~~~~~ }
                           { NEAREST-EVEN           }
                           { ~~~~~~~~~~~~           }
                           { NEAREST-TOWARD-ZERO    }
                           { ~~~~~~~~~~~~~~~~~~~    }
                           { PROHIBITED             }
                           { ~~~~~~~~~~             }
                           { TOWARD-GREATER         }
                           { ~~~~~~~~~~~~~~         }
                           { TOWARD-LESSER          }
                           { ~~~~~~~~~~~~~          }
                           { TRUNCATION             }
                             ~~~~~~~~~~
         =|EQUAL arithmetic-expression-1
           ~~~~~
       [ ON SIZE ERROR imperative-statement-1 ]
            ~~~~ ~~~~~
       [ NOT ON SIZE ERROR imperative-statement-2 ]
         ~~~    ~~~~ ~~~~~
 [ END-COMPUTE ]
   ~~~~~~~~~~~

Оператор COMPUTE предоставляет способ удобного выполнения сложных арифметических операций одной строкой вместо использования громоздких и, возможно, запутанных последовательностей операторов ADD, SUBTRACT, MULTIPLY и DIVIDE. COMPUTE также позволяет использовать возведение в степень — арифметическую операцию, для которой в COBOL нет других операторов.

  1. Зарезервированные слова IS и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированное слово EQUAL взаимозаменяемо с использованием ‘=’.
  3. Каждый identifier-1 должен быть числовым или числовым отформатированным элементом данных.
  4. Необязательный ROUNDED (см. ROUNDED) пункт, доступный для каждого identifier-1, будет управлять тем, как будут сохраняться результаты, не являющиеся целыми числами.
  5. См. Арифметические выражения для получения дополнительной информации об арифметических выражениях.
  6. Необязательные пункты ON SIZE ERROR и NOT ON SIZE ERROR могут быть использованы для обнаружения и реакции соответственно на неудачу или успех попытки выполнения вычисления. В этом случае неудача определяется как наличие identifier-3 с недостаточным количеством разрядов слева от предполагаемой десятичной точки или попытка деления на ноль. Для получения дополнительной информации см. ON SIZE ERROR + NOT ON SIZE ERROR.

7.8.10. CONTINUE

CONTINUE Синтаксис

 CONTINUE
 ~~~~~~~~

                 { identifier-1            }
 CONTINUE AFTER  { literal-1               }   SECONDS
 ~~~~~~~~ ~~~~~  { arithmetic-expression-1 }   ~~~~~~~

Оператор CONTINUE — это оператор бездействия, который может быть записан в любом месте, где может быть записан императивный оператор (см. Императивный оператор).

  1. Оператор CONTINUE не влияет на выполнение программы.
  2. Этот оператор (возможно, в сочетании с соответствующей или двумя комментариями) делает удобный «заполнитель» — особенно в пунктах ELSE (см. IF) или WHEN (см. EVALUATE), где в данный момент не ожидается код, но место для кода для обработки соответствующих условий может быть зарезервировано на случай его необходимости.
  3. Необязательное расширение (AFTER) при использовании с оператором CONTINUE приостанавливает выполнение на заданный промежуток времени.

7.8.11. DELETE

DELETE Синтаксис

   DELETE file-name-1 RECORD
   ~~~~~~
     [ INVALID KEY imperative-statement-1 ]
       ~~~~~~~
     [ NOT INVALID KEY imperative-statement-2 ]
       ~~~ ~~~~~~~
 [ END-DELETE ]
   ~~~~~~~~~~

Оператор DELETE логически удаляет запись из файла COBOL.

  1. Зарезервированные слова KEY и RECORD являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Имя файла file-name-1 не может быть ORGANIZATION LINE SEQUENTIAL (см. ORGANIZATION LINE SEQUENTIAL).
  3. Файл file-name-1 не может быть файлом сортировки/слияния (файлом, описанным с помощью SD (см. File/Sort-Description)).
  4. Для файлов в режиме доступа SEQUENTIAL, последняя инструкция ввода-вывода, выполненная над file-name-1 до выполнения инструкции DELETE, должна быть успешно выполненной инструкцией последовательного формата READ (см. Sequential READ). Это READ позволит определить запись, подлежащую удалению.
  5. Если file-name-1 — это файл RELATIVE, у которого ACCESS MODE (см. ORGANIZATION RELATIVE) равно либо RANDOM, либо DYNAMIC, запись, подлежащая удалению, — это запись, относительный номер которой в данный момент равен значению поля, указанного как RELATIVE KEY в инструкции SELECT.
  6. Если file-name-1 — это файл INDEXED, у которого ACCESS MODE (см. ORGANIZATION INDEXED) равно RANDOM или DYNAMIC, запись, подлежащая удалению, — это запись, первичный ключ которой в данный момент равен значению поля, указанного как RECORD KEY в инструкции файла SELECT.
  7. Необязательные INVALID KEY и NOT INVALID KEY клаузы могут быть использованы для обнаружения и реакции соответственно на неудачу или успех попытки удаления записи. Дополнительную информацию см. в INVALID KEY + NOT INVALID KEY.
  8. Никакие INVALID KEY или NOT INVALID KEY клаузы не могут быть указаны для файла, у которого ACCESS MODE IS SEQUENTIAL.

7.8.12. DISPLAY

7.8.12.1. DISPLAY UPON устройство

DISPLAY UPON устройство Синтаксис

   DISPLAY { literal-1    }...
   ~~~~~~~ { identifier-1 }
      [ UPON mnemonic-name-1 ]
        ~~~~
      [ WITH NO ADVANCING ]
             ~~ ~~~~~~~~~
      [ ON EXCEPTION imperative-statement-1 ]
           ~~~~~~~~~
      [ NOT ON EXCEPTION imperative-statement-2 ]
        ~~~    ~~~~~~~~~
 [ END-DISPLAY ]
   ~~~~~~~~~~~

Этот формат инструкции DISPLAY отображает указанные идентификаторы и/или значения литералов на системном устройстве вывода, заданном с помощью клаузы UPON.

  1. Зарезервированные слова ON и WITH являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Если клауза UPON не указана, будет принято UPON CONSOLE. Если клауза UPON указана, mnemonic-name-1 должно быть одним из встроенных имён устройств вывода CONSOLE, PRINTER, STDERR, STDOUT, SYSERR, SYSLIST, SYSLST или SYSOUT или именем мнемоники, назначенным одному из этих устройств через SPECIAL-NAMES (см. SPECIAL-NAMES).

    При отображении на устройствах STDERR или SYSERR или на mnemonic-name-1, присоединённом к одному из этих двух устройств, вывод будет записан в выходной канал #2, что обычно приводит к появлению вывода в окне консольного вывода. При желании вы можете перенаправить этот вывод в файл, добавив 2> имя_файла в конец команды выполнения программы. Это относится как к Windows (любого типа), так и к Unix-версиям GnuCOBOL.

    При отображении на устройствах CONSOLE, PRINTER, STDOUT, SYSLIST, SYSLST или SYSOUT или на mnemonic-name-1, присоединённом к одному из них, вывод будет записан в выходной канал #1, что обычно приводит к появлению вывода в окне консольного вывода. При желании вы можете перенаправить этот вывод в файл, добавив 1> имя_файла или просто > имя_файла в конец команды выполнения программы. Это относится как к Windows (любого типа), так и к Unix-версиям GnuCOBOL.

  3. Клауза NO ADVANCING, если используется, подавляет последовательность возврата каретки/перевода строки, которая обычно добавляется в конец любого консольного вывода.
  4. Необязательные ON EXCEPTION и NOT ON EXCEPTION клаузы могут быть использованы для обнаружения и реакции соответственно на неудачу или успех попытки отобразить вывод на указанное устройство. Дополнительную информацию см. в ON EXCEPTION + NOT ON EXCEPTION.

7.8.12.2. DISPLAY UPON КОМАНДНАЯ_СТРОКА

DISPLAY UPON КОМАНДНАЯ_СТРОКА Синтаксис

   DISPLAY { literal-1    }...
   ~~~~~~~ { identifier-1 }
        UPON { ARGUMENT-NUMBER|COMMAND-LINE }
        ~~~~ { ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ }
      [ ON EXCEPTION imperative-statement-1 ]
           ~~~~~~~~~
      [ NOT ON EXCEPTION imperative-statement-2 ]
        ~~~    ~~~~~~~~~
 [ END-DISPLAY ]
   ~~~~~~~~~~~

Этот формат инструкции DISPLAY может быть использован для задания номера аргумента командной строки, который должен быть получен последующей инструкцией ACCEPT FROM ARGUMENT-VALUE (см. ACCEPT FROM КОМАНДНАЯ_СТРОКА) или для задания нового значения для самих аргументов командной строки.

  1. Зарезервированное слово ON является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Отобразив числовое целое значение UPON ARGUMENT-NUMBER, вы укажете, какой аргумент (по его относительному номеру) будет извлечен последующим оператором ACCEPT FROM ARGUMENT-VALUE.
  3. Выполнение оператора DISPLAY UPON COMMAND-LINE повлияет на последующие операторы ACCEPT FROM COMMAND-LINE (которые затем вернут отображённое значение), но не повлияет на последующие операторы ACCEPT FROM ARGUMENT-VALUE — они продолжат возвращать исходные параметры выполнения программы.
  4. Необязательные пункты ON EXCEPTION и NOT ON EXCEPTION могут быть использованы для обнаружения и реакции соответственно на неудачу или успех попытки отобразить вывод в указанный элемент. См. ON EXCEPTION + NOT ON EXCEPTION для получения дополнительной информации.

7.8.12.3. ОТОБРАЖЕНИЕ В ИМЯ ОКРУЖЕНИЯ

Синтаксис ОТОБРАЖЕНИЯ В ИМЯ ОКРУЖЕНИЯ

   DISPLAY { literal-1    }... UPON { ENVIRONMENT-VALUE }
   ~~~~~~~ { identifier-1 }    ~~~~ { ~~~~~~~~~~~~~~~~~ }
                                    { ENVIRONMENT-NAME  }
                                      ~~~~~~~~~~~~~~~~
      [ ON EXCEPTION imperative-statement-1 ]
           ~~~~~~~~~
      [ NOT ON EXCEPTION imperative-statement-2 ]
        ~~~    ~~~~~~~~~
 [ END-DISPLAY ]
   ~~~~~~~~~~~

Этот вид оператора DISPLAY может использоваться для создания или изменения переменных среды.

  1. Зарезервированное слово ON является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Для создания или изменения переменной среды потребуются два оператора DISPLAY. Следующий пример устанавливает переменную среды MY_ENV_VAR со значением ‘Демонстрационное значение’:
    DISPLAY "MY_ENV_VAR" UPON ENVIRONMENT-NAME
    DISPLAY "Demonstration Value" UPON ENVIRONMENT-VALUE
    
  3. Переменные среды, созданные или изменённые внутри программ GnuCOBOL, будут доступны для всех дочерних процессов оболочки, запущенных этой программой (например, CALL 'SYSTEM' (см. SYSTEM)), но не будут известны оболочке или окну консоли, которые запустили программу GnuCOBOL.
  4. Рассмотрите использование оператора SET ENVIRONMENT (см. УСТАНОВИТЬ СРЕДУ) вместо DISPLAY для установки переменных среды, так как он гораздо проще.
  5. Необязательные пункты ON EXCEPTION и NOT ON EXCEPTION могут быть использованы для обнаружения и реакции соответственно на неудачу или успех попытки отобразить вывод в указанный элемент. См. ON EXCEPTION + NOT ON EXCEPTION для получения дополнительной информации.

7.8.12.4. ОТОБРАЖЕНИЕ данных-экрана

Синтаксис ОТОБРАЖЕНИЕ данных-экрана

   DISPLAY identifier-1 [ UPON CRT|CRT-UNDER ]
   ~~~~~~~                ~~~~ ~~~ ~~~~~~~~~
       [ AT { | LINE NUMBER { integer-1    }            | } ]
         ~~ { | ~~~~        { identifier-2 }            | }
            { | COLUMN|COL|POSITION|POS NUMBER { integer-2    }
            { | ~~~~~~ ~~~ ~~~~~~~~ ~~~        { identifier-3 }
            {                                             }
            { { integer-3    }                            }
            { { identifier-4 }                            }

       [ WITH [ Attribute-Specification ]...
         ~~~~
              [ SCROLL { UP   } [ { integer-4    } LINE|LINES ] ]
                ~~~~~~ { ~~   }   { identifier-5 }
                       { DOWN }
                         ~~~~
              [ SIZE { integer-5    }
                ~~~~ { identifier-6 }  ]
       [ ON EXCEPTION imperative-statement-1 ]
            ~~~~~~~~~
       [ NOT ON EXCEPTION imperative-statement-2 ]
         ~~~    ~~~~~~~~~
 [ END-DISPLAY ]
   ~~~~~~~~~~~

Пункты UPON CRT, UPON CRT-UNDER и CONVERSION синтаксически распознаются, но в противном случае не являются функциональными. Они поддерживаются для обеспечения совместимости с исходным кодом COBOL, написанным для других реализаций COBOL.

Этот формат оператора DISPLAY отображает данные на отформатированный экран.

  1. Зарезервированные слова AFTER, LINE, LINES, NUMBER и ON являются необязательными и могут быть опущены. Их присутствие или отсутствие не влияет на программу.
  2. Зарезервированные слова COLUMN и POSITION взаимозаменяемы.
  3. Зарезервированные слова LINE и LINES взаимозаменяемы.
  4. Если identifier-1 определён в разделе SCREEN SECTION (см. РАЗДЕЛ ЭКРАНА), любые AT, Attribute-Specification и WITH пункты будут проигнорированы. Все определения полей, позиционирование курсора и управление экраном будут определяться в разделе экрана identifier-1.
  5. Если identifier-1 не определён в разделе экрана, применяются следующие правила:
    1. Цель пункта AT — определить место отображения identifier-1 на экране. Дополнительная информация содержится в ПРИНЯТЬ screen-data-item.
    2. Цель пункта WITH — определить визуальные атрибуты identifier-1 при отображении на экране, а также другие характеристики управления представлением.
    3. В пункте DISPLAY допустимы следующие Attribute-Specification пункты — они совпадают с теми, которые допустимы для данных identifier-1. Конкретный Attribute-Specification может использоваться только один раз в любом DISPLAY:
      • BACKGROUND-COLOR (см. ЦВЕТ ФОНА)
      • BEEP (см. СИГНАЛ), BELL (см. ЗВОНОК)
      • BLANK (см. ПУСТОЙ)
      • BLINK (см. МИГАНИЕ)
      • ERASE (см. СТЕРЕТЬ)
      • FOREGROUND-COLOR (см. ЦВЕТ ПЕРЕДНЕГО ПЛАНА)
      • HIGHLIGHT (см. ВЫДЕЛЕНИЕ)
      • LOWLIGHT (см. СЛАБОЕ ВЫДЕЛЕНИЕ)
      • OVERLINE (см. НАДСТРОКА)
      • REVERSE-VIDEO (см. ОБРАТНЫЙ РЕЖИМ)
      • UNDERLINE (см. ПОДЧЕРКИВАНИЕ)
    4. Дополнительная информация о других вариантах пункта WITH содержится в ПРИНЯТЬ screen-data-item.
  6. Необязательные ON EXCEPTION и NOT ON EXCEPTION пункты могут быть использованы для обнаружения и реакции соответственно на ошибку или успех попытки ввода/вывода на экран. Дополнительная информация содержится в ON EXCEPTION + NOT ON EXCEPTION.

При использовании DISPLAY с указанием строки и столбца, где используются несколько переменных или литералов до LINE, отобразится только первая.

Если это необходимо, следует использовать CONCATENATE, чтобы объединить несколько элементов перед отображением, например, DISPLAY FUNCTION CONCATENATE (VARS-1 VARS-2) AT 0201.

При использовании DISPLAY без управления строкой или столбцом на одной строке может отображаться только одна переменная или литерал, поэтому следует использовать пример выше.

7.8.13. ДЕЛЕНИЕ

7.8.13.1. ДЕЛЕНИЕ НА

Синтаксис ДЕЛЕНИЕ НА

 DIVIDE { literal-1    } INTO { identifier-2
 ~~~~~~ { identifier-1 } ~~~~

       [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
         ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                           { NEAREST-AWAY-FROM-ZERO }
                           { ~~~~~~~~~~~~~~~~~~~~~~ }
                           { NEAREST-EVEN           }
                           { ~~~~~~~~~~~~           }
                           { NEAREST-TOWARD-ZERO    }
                           { ~~~~~~~~~~~~~~~~~~~    }
                           { PROHIBITED             }
                           { ~~~~~~~~~~             }
                           { TOWARD-GREATER         }
                           { ~~~~~~~~~~~~~~         }
                           { TOWARD-LESSER          }
                           { ~~~~~~~~~~~~~          }
                           { TRUNCATION             }
                             ~~~~~~~~~~
    [ ON SIZE ERROR imperative-statement-1 ]
         ~~~~ ~~~~~
    [ NOT ON SIZE ERROR imperative-statement-2 ]
      ~~~    ~~~~ ~~~~~
 [ END-DIVIDE ]
   ~~~~~~~~~~

Этот формат оператора DIVIDE разделит числовое значение (указанное как литерал или числовой элемент данных) на один или несколько числовых элементов данных, заменив значение в каждом из этих элементов результатом(ами).

  1. Зарезервированные слова IS и ON являются необязательными и могут быть опущены. Их присутствие или отсутствие не влияет на программу.
  2. identifier-1 и identifier-2 должны быть числовыми элементами данных без редактирования, а literal-1 — числовым литералом.
  3. Операция деления выполняется для каждого identifier-2 по очереди. Результаты этих делений сохраняются в соответствующих элементах данных identifier-2.
  4. Если identifier-2 — целочисленный числовой элемент данных, результат вычисления при делении identifier-2 на literal-1 или identifier-1 также будет целым — любой остаток от деления будет отброшен.
  5. Необязательный ROUNDED (см. ОКРУГЛЁННО) пункт, доступный для каждого identifier-2, будет управлять тем, как будут сохраняться нецелые результаты.
  6. Необязательные ON SIZE ERROR и NOT ON SIZE ERROR пункты могут быть использованы для обнаружения и реакции соответственно на ошибку или успех попытки выполнения вычисления. В этом случае ошибка определяется как числовое усечение, вызванное identifier-2 с недостаточным количеством позиций цифр слева от предполагаемой десятичной точки, или попытка деления на ноль. Дополнительная информация содержится в ON SIZE ERROR + NOT ON SIZE ERROR.

7.8.13.2. ДЕЛЕНИЕ НА, ДАВАЯ

Синтаксис ДЕЛЕНИЕ НА, ДАВАЯ

 DIVIDE { literal-1    } INTO { literal-2    } GIVING { identifier-3
 ~~~~~~ { identifier-1 } ~~~~ { identifier-2 } ~~~~~~

            [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
              ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                                { NEAREST-AWAY-FROM-ZERO }
                                { ~~~~~~~~~~~~~~~~~~~~~~ }
                                { NEAREST-EVEN           }
                                { ~~~~~~~~~~~~           }
                                { NEAREST-TOWARD-ZERO    }
                                { ~~~~~~~~~~~~~~~~~~~    }
                                { PROHIBITED             }
                                { ~~~~~~~~~~             }
                                { TOWARD-GREATER         }
                                { ~~~~~~~~~~~~~~         }
                                { TOWARD-LESSER          }
                                { ~~~~~~~~~~~~~          }
                                { TRUNCATION             }
    [ REMAINDER identifier-4 ]    ~~~~~~~~~~
      ~~~~~~~~~
    [ ON SIZE ERROR imperative-statement-1 ]
         ~~~~ ~~~~~
    [ NOT ON SIZE ERROR imperative-statement-2 ]
      ~~~    ~~~~ ~~~~~
 [ END-DIVIDE ]
   ~~~~~~~~~~

Этот формат оператора DIVIDE разделит одно числовое значение (указанное как литерал или числовой элемент данных) на другое числовое значение (также указанное как литерал или числовой элемент данных), а затем заменит содержимое одного или нескольких элементов данных-приемников результатами этого деления.

  1. Зарезервированные слова IS и ON необязательны и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Как identifier-1, так и identifier-2 должны быть числовыми элементами данных без изменений, в то время как как identifier-3, так и identifier-4 должны быть числовыми (с изменениями или без) элементами данных.
  3. Как literal-1, так и literal-2 должны быть числовыми литералами.
  4. Если указан пункт REMAINDER, может быть указан только один identifier-3.
  5. Вычисляется результат деления значения literal-2 или identifier-2 на значение literal-1 или identifier-1; этот результат затем перемещается в каждый identifier-3 по очереди, применяя правила, определённые пунктом ROUNDED (см. ROUNDED) (если таковой имеется) для данного identifier-3 к операции перемещения.
  6. Если указан пункт REMAINDER, значение единственного identifier-3 (как было сказано ранее, если указан REMAINDER, то в операторе может быть указан только один identifier-3) после присвоения ему значения в соответствии с предыдущим правилом будет умножено на значение literal-1 или identifier-1; результат этого умножения затем вычитается из значения literal-2 или identifier-2, и этот результат является значением, которое перемещается в identifier-4.
  7. Необязательные пункты ON SIZE ERROR и NOT ON SIZE ERROR могут использоваться для обнаружения и реагирования на неудачу или успех попытки выполнения вычисления соответственно. В этом случае неудача определяется как identifier-2 с недостаточным количеством разрядов слева от предполагаемой десятичной точки или попытка деления на ноль. Дополнительную информацию см. в разделе ON SIZE ERROR + NOT ON SIZE ERROR.

7.8.13.3. ДЕЛЕНИЕ С ПРИСВАИВАНИЕМ

Синтаксис ДЕЛЕНИЕ С ПРИСВАИВАНИЕМ

 DIVIDE { literal-1    } BY { literal-2    } GIVING { identifier-3
 ~~~~~~ { identifier-1 } ~~ { identifier-2 } ~~~~~~

            [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
              ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                                { NEAREST-AWAY-FROM-ZERO }
                                { ~~~~~~~~~~~~~~~~~~~~~~ }
                                { NEAREST-EVEN           }
                                { ~~~~~~~~~~~~           }
                                { NEAREST-TOWARD-ZERO    }
                                { ~~~~~~~~~~~~~~~~~~~    }
                                { PROHIBITED             }
                                { ~~~~~~~~~~             }
                                { TOWARD-GREATER         }
                                { ~~~~~~~~~~~~~~         }
                                { TOWARD-LESSER          }
                                { ~~~~~~~~~~~~~          }
                                { TRUNCATION             }
    [ REMAINDER identifier-4 ]    ~~~~~~~~~~
      ~~~~~~~~~
    [ ON SIZE ERROR imperative-statement-1 ]
         ~~~~ ~~~~~
    [ NOT ON SIZE ERROR imperative-statement-2 ]
      ~~~    ~~~~ ~~~~~
 [ END-DIVIDE ]
   ~~~~~~~~~~

Этот формат оператора DIVIDE разделит одно числовое значение (указанное как литерал или числовой элемент данных) на другое числовое значение (также указанное как литерал или числовой элемент данных), а затем заменит содержимое одного или нескольких элементов данных-приемников результатами этого деления.

  1. Зарезервированные слова IS и ON необязательны и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Как identifier-1, так и identifier-2 должны быть числовыми элементами данных без изменений, в то время как как identifier-3, так и identifier-4 должны быть числовыми (с изменениями или без) элементами данных.
  3. Как literal-1, так и literal-2 должны быть числовыми литералами.
  4. Если указан пункт REMAINDER, может быть указан только один identifier-3.
  5. Вычисляется результат деления значения literal-1 или identifier-1 на значение literal-2 или identifier-2; этот результат затем перемещается в каждый identifier-3 по очереди, применяя правила, определённые пунктом ROUNDED (см. ROUNDED) (если таковой имеется) для данного identifier-3 к операции перемещения.
  6. Если указан пункт REMAINDER, значение единственного identifier-3 (как было сказано ранее, если указан REMAINDER, то в операторе может быть указан только один identifier-3) после присвоения ему значения в соответствии с предыдущим правилом будет умножено на значение literal-2 или identifier-2; результат этого умножения затем вычитается из значения literal-1 или identifier-1, и этот результат является значением, которое перемещается в identifier-4.
  7. Необязательные пункты ON SIZE ERROR и NOT ON SIZE ERROR могут использоваться для обнаружения и реагирования на неудачу или успех попытки выполнения вычисления соответственно. В этом случае неудача определяется как identifier-2 с недостаточным количеством разрядов слева от предполагаемой десятичной точки или попытка деления на ноль. Дополнительную информацию см. в разделе ON SIZE ERROR + NOT ON SIZE ERROR.

7.8.14. ENTRY

Синтаксис ENTRY

 ENTRY literal-1 [ USING ENTRY-Argument... ]
 ~~~~~             ~~~~~

Синтаксис аргумента ENTRY

 [ BY { REFERENCE } ] identifier-1
      { ~~~~~~~~~ }
      { CONTENT   }
      { ~~~~~~~   }
      { VALUE     }
        ~~~~~

Оператор ENTRY используется для определения альтернативной точки входа в подпрограмму, а также аргументов, которые подпрограмма будет ожидать.

  1. Зарезервированное слово BY является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Вы не можете использовать оператор ENTRY в вложенной подпрограмме, а также в любом виде пользовательской функции.
  3. Оператор USING определяет аргументы, поддерживаемые точкой входа подпрограммы. Этот список аргументов должен соответствовать оператору USING любого оператора CALL, который будет вызывать подпрограмму с помощью этой точки входа.
  4. Каждый ENTRY-Argument, указанный в операторе ENTRY, должен быть определен в секции связи подпрограммы, в которой существует оператор ENTRY.
  5. Значение literal-1 укажет имя точки входа подпрограммы. Оно должно быть указано точно в операторах CALL (с учётом регистра символов) так, как оно указано в операторе ENTRY.
  6. Значения REFERENCE, CONTENT и VALUE имеют такое же значение, как и аналогичные спецификации в операторе CALL (см. CALL). Любая спецификация, используемая для аргумента в операторе CALL данной точки входа, должна соответствовать спецификации, используемой в соответствующем ENTRY-Argument. Те же правила относительно наличия или отсутствия оператора BY в операторе CALL применяются к наличию или отсутствию оператора BY в соответствующем аргументе оператора ENTRY.

7.8.15. EVALUATE

EVALUATE Синтаксис

   EVALUATE Selection-Subject-1 [ ALSO Selection-Subject-2 ]...
   ~~~~~~~~                       ~~~~
 { { WHEN Selection-Object-1 [ ALSO Selection-Object-2 ] }...
     ~~~~                      ~~~~
         [ imperative-statement-1 ] }...
   [ WHEN OTHER
     ~~~~ ~~~~~
         imperative-statement-other ]

 [ END-EVALUATE ]
   ~~~~~~~~~~~~

Синтаксис объекта выбора EVALUATE

 { TRUE         }
 { ~~~~         }
 { FALSE        }
 { ~~~~~        }
 { expression-1 }
 { identifier-1 }
 { literal-1    }

Синтаксис объекта выбора EVALUATE

 { ANY                                                }
 { ~~~                                                }
 { TRUE                                               }
 { ~~~~                                               }
 { FALSE                                              }
 { ~~~~~                                              }
 { partial-expression-1                               }
 {                                                    }
 { { expression-2 } [ THRU|THROUGH { expression-3 } ] }
 { { identifier-2 }   ~~~~ ~~~~~~~ { identifier-3 }   }
 { { literal-2    }                { literal-3    }   }

Оператор EVALUATE предоставляет способ определения обработки, которая должна выполняться при любом количестве взаимоисключающих условий.

  1. Зарезервированные слова THRU и THROUGH взаимозаменяемы.
  2. Должна быть указана по крайней мере одна WHEN (в дополнение к любой WHEN OTHER) в любом операторе EVALUATE.
  3. В операторе EVALUATE должно быть указано по крайней мере одно Selection-Subject. Можно указать любое количество дополнительных Selection-Subject, используя зарезервированное слово ALSO для разделения каждого из них с предыдущим.
  4. Каждая WHEN (кроме WHEN OTHER, если таковая есть) должна иметь то же количество Selection-Object, что и Selection-Subject.
  5. При использовании THRU, значения с обеих сторон THRU должны быть одного класса (оба числовые, оба буквенно-цифровые и т. д.).
  6. partial-expression — это одно из следующего:
    1. Условие класса без ведущего identifier-1 (см. Условие класса).
    2. Условие знака без ведущего identifier-1 (см. Условие знака).
    3. Условие отношения без чего-либо слева от оператора отношения (см. Условие отношения).
  7. Во время выполнения каждый Selection-Subject в операторе EVALUATE будет сопоставлен с соответствующим Selection-Object в WHEN пункте, по очереди, до тех пор, пока:
    1. В WHEN пункте каждый Selection-Object(ов) успешно сопоставлен соответствующим Selection-Subject; это будет называться ’Выбранным WHEN пунктом’.
    2. Не весь список WHEN пунктов (кроме WHEN OTHER пункта, если таковой есть) не исчерпан. В этом случае нет ’Выбранного WHEN пункта’.
  8. Если был определён ’Выбранный WHEN пункт’:
    1. imperative-statement-1 (см. Оперативное выражение) непосредственно после ’Выбранного WHEN пункта’ будет выполнено. Если в ’Выбранном WHEN пункте’ отсутствует imperative-statement-1, первое imperative-statement-1, найденное после любого последующего WHEN пункта, будет выполнено.
    2. После выполнения imperative-statement-1 или если imperative-statement-1 не найдено после ’Выбранного WHEN пункта’, управление перейдёт к следующему оператору после END-EVALUATE или, если END-EVALUATE отсутствует, к первому оператору, следующему за последующей точкой. Однако, если imperative-statement-1 включал оператор GO TO, и этот GO TO был выполнен, то управление будет передано процедуре, указанной в GO TO.
  9. Если ’Выбранный WHEN пункт’ не был определён:
    1. imperative-statement-other пункта WHEN OTHER будет выполнен, если такой пункт был закодирован.
    2. Управление затем перейдёт к оператору, следующему за END-EVALUATE, или к первому оператору, следующему за последующей точкой, если END-EVALUATE отсутствует. Однако, если imperative-statement-other включал оператор GO TO, и этот GO TO был выполнен, то управление будет передано процедуре, указанной в GO TO вместо этого.
  10. Чтобы Selection-Subject соответствовал соответствующему Selection-Object в WHEN пункте, должно быть выполнено хотя бы одно из следующих условий:
    1. Selection-Object — ANY
    2. Неявное условие отношения Selection-Subject = Selection Object — TRUE — см. Условие отношения для правил сравнения.
    3. Значение Selection-Subject попадает в диапазон значений, указанный в THRU пункте Selection-Object
    4. Если Selection-Object — partial-expression, то условное выражение, которое было бы представлено кодированием Selection-Subject Selection-Object, имеет значение TRUE
  11. Вот пример программы, которая иллюстрирует оператор EVALUATE.
    IDENTIFICATION DIVISION.
    PROGRAM-ID. DEMOEVALUATE.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01  Test-Digit                  PIC 9(1).
        88 Digit-Is-Odd VALUE 1, 3, 5, 7, 9.
        88 Digit-Is-Prime VALUE 1, 3, 5, 7.
    PROCEDURE DIVISION.
    P1. PERFORM UNTIL EXIT
        DISPLAY "Enter a digit (0 Quits): "
            WITH NO ADVANCING
        ACCEPT Test-Digit
        IF Test-Digit = 0
            EXIT PERFORM
        END-IF
        EVALUATE Digit-Is-Odd ALSO Digit-Is-Prime
        WHEN TRUE ALSO FALSE
            DISPLAY Test-Digit " is ODD"
                WITH NO ADVANCING
        WHEN TRUE ALSO TRUE
            DISPLAY Test-Digit " is PRIME"
                WITH NO ADVANCING
        WHEN FALSE ALSO ANY
            DISPLAY Test-Digit " is EVEN"
                WITH NO ADVANCING
        END-EVALUATE
        EVALUATE Test-Digit
        WHEN < 5
            DISPLAY " and it's small too"
        WHEN < 8
            DISPLAY " and it's medium too"
        WHEN OTHER
            DISPLAY " and it's large too"
        END-EVALUATE
    END-PERFORM
    DISPLAY "Bye!"
    STOP RUN
    .
    

    Вывод на консоль при запуске (ввод пользователя следует за двоеточиями в запросах ввода):

    Enter a digit (0 Quits): 1
    1 is PRIME and it's small too
    Enter a digit (0 Quits): 2
    2 is EVEN and it's small too
    Enter a digit (0 Quits): 3
    3 is PRIME and it's small too
    Enter a digit (0 Quits): 4
    4 is EVEN and it's small too
    Enter a digit (0 Quits): 5
    5 is PRIME and it's medium too
    Enter a digit (0 Quits): 6
    6 is EVEN and it's medium too
    Enter a digit (0 Quits): 7
    7 is PRIME and it's medium too
    Enter a digit (0 Quits): 8
    8 is EVEN and it's large too
    Enter a digit (0 Quits): 9
    9 is ODD and it's large too
    Enter a digit (0 Quits): 0
    Bye!
    

7.8.16. EXIT

Синтаксис EXIT

 EXIT [ { PROGRAM           } ]
 ~~~~   { ~~~~~~~           }
        { FUNCTION          }
        { ~~~~~~~~          }
        { PERFORM [ CYCLE ] }
        { ~~~~~~~   ~~~~~   }
        { SECTION           }
        { ~~~~~~~           }
        { PARAGRAPH         }
          ~~~~~~~~~

Оператор EXIT — это многоцелевой оператор; он может обеспечить общую конечную точку для ряда процедур, выйти из PERFORM (встроенная процедура, абзац или раздел), или он может обозначать логический конец подпрограммы, возвращая управление обратно вызывающей программе.

  1. Оператор EXIT PROGRAM не является допустимым внутри пользовательской функции.
  2. Оператор EXIT FUNCTION не может использоваться внутри подпрограммы.
  3. Ни EXIT PROGRAM, ни EXIT FUNCTION не могут использоваться внутри подпрограммы USE GLOBAL в DECLARATIVES (см. ДЕКЛАРАТИВЫ).
  4. Следующие пункты описывают оператор EXIT без дополнительных опций:
    1. При использовании этого варианта оператора EXIT, он должен быть единственным оператором в процедуре (абзаце или разделе), в которой он находится. Это не проверяется в GnuCOBOL.
    2. Это использование оператора EXIT просто предоставляет общую точку "перехода" для серии процедур, как показано в следующем примере:
      01  Switches.
          05 Input-File-Switch PIC X(1).
             88 EOF-On-Input-File VALUE ``Y'' FALSE ``N''.
      …
          SET EOF-On-Input-File TO FALSE.
          PERFORM 100-Process-A-Transaction THRU 199-Exit
              UNTIL EOF-On-Input-File.
      …
      100-Process-A-Transaction.
          READ Input-File AT END
              SET EOF-On-Input-File TO TRUE
              GO TO 199-Exit
          END-READ.
          IF Input-Rec of Input-File = SPACES
              GO TO 199-Exit  *> IGNORE BLANK RECORDS!
          END-IF.
          <<process the record just read>>
      199-Exit.
          EXIT.
      
    3. В этом случае оператор EXIT не выполняет никаких дополнительных действий во время выполнения.
  5. Следующие пункты относятся к операторам EXIT PARAGRAPH и EXIT SECTION:
    1. Если оператор EXIT PARAGRAPH или оператор EXIT SECTION находится в абзаце внутри области процедурного оператора PERFORM (см. Процедурный PERFORM), управление будет возвращено оператору PERFORM для оценки опций TIMES, VARYING и/или UNTIL.
    2. Если оператор EXIT PARAGRAPH или оператор EXIT SECTION находится вне области процедурного оператора PERFORM, управление просто передается первому исполняемому оператору в следующем абзаце (EXIT PARAGRAPH) или разделе (EXIT SECTION).
    3. Следующий пример демонстрирует, как предыдущий пример можно было бы закодировать без оператора GO TO, используя оператор EXIT PARAGRAPH.
      01  Switches.
          05 Input-File-Switch PIC X(1).
             88 EOF-On-Input-File VALUE ``Y'' FALSE ``N''.
      …
          SET EOF-On-Input-File TO FALSE.
          PERFORM 100-Process-A-Transaction
              UNTIL EOF-On-Input-File.
      …
      100-Process-A-Transaction.
          READ Input-File AT END
              SET EOF-On-Input-File TO TRUE
              EXIT PARAGRAPH
          END-READ.
          IF Input-Rec of Input-File = SPACES
              EXIT PARAGRAPH *> IGNORE BLANK RECORDS!
          END-IF.
          <<process the record just read>>
      
  6. Следующие пункты относятся к операторам EXIT PERFORM и EXIT PERFORM CYCLE:
    1. Операторы EXIT PERFORM и EXIT PERFORM CYCLE предназначены для совместного использования с оператором PERFORM (см. Встроенный PERFORM).
    2. Оператор EXIT PERFORM CYCLE завершит текущую итерацию встроенного оператора PERFORM, передав управление опциям TIMES, VARYING и/или UNTIL, чтобы они определили, нужна ли ещё одна циклическая итерация.
    3. Оператор EXIT PERFORM полностью завершит встроенный PERFORM, передав управление первому оператору, следующему за END-PERFORM (если он есть), или следующему оператору после PERFORM, если оператор END-PERFORM отсутствует.
    4. Этот последний пример демонстрирует окончательное изменение в предыдущих примерах, используя встроенный оператор PERFORM вместе с операторами EXIT PERFORM и EXIT PERFORM CYCLE:
      PERFORM FOREVER
          READ Input-File AT END
              EXIT PERFORM
          END-READ
          IF Input-Rec of Input-File = SPACES
              EXIT PERFORM CYCLE *> IGNORE BLANK RECORDS!
          END-IF
          <<process the record just read>>
      END PERFORM
      
  7. Следующие пункты относятся к операторам EXIT PROGRAM и EXIT FUNCTION:
    1. Операторы EXIT PROGRAM и EXIT FUNCTION завершают выполнение подпрограммы (т.е. программы, вызываемой другой программой с помощью CALL) или пользовательской функции соответственно, возвращая управление вызывающей программе.
    2. Оператор EXIT PROGRAM возвращает управление оператору, следующему за оператором CALL (см. CALL) подпрограммы. Оператор EXIT FUNCTION возвращает управление обработке оператора в вызывающей программе, которая вызвала пользовательскую функцию.
    3. Если операторы выполняются основной программой, ни оператор EXIT PROGRAM, ни оператор EXIT FUNCTION не выполняют никаких действий.
    4. Стандарт COBOL2002 ввёл общее расширение языка COBOL — оператор GOBACK (см. GOBACK) — стандартный элемент языка; оператор GOBACK следует рассмотреть в качестве предпочтительной альтернативы операторам EXIT PROGRAM и EXIT FUNCTION для новых подпрограмм.

7.8.17. FREE

Синтаксис FREE

 FREE { [ ADDRESS OF ] identifier-1 }...
 ~~~~     ~~~~~~~

Оператор FREE освобождает память, ранее выделенную программе оператором ALLOCATE (см. ALLOCATE).

  1. Оператор ADDRESS OF является необязательным и может быть опущен. Его присутствие или отсутствие не влияет на программу.
  2. identifier-1 должен иметь USAGE (см. USAGE) POINTER, или это должен быть элемент данных уровня 01 с атрибутом BASED (см. BASED).
  3. Если identifier-1 является элементом данных типа указатель и содержит допустимый адрес, оператор FREE освободит блок памяти, на который ссылается указатель. Кроме того, все элементы данных BASED, для которых указатель использовался для указания адреса, станут безбазовыми и, следовательно, непригодными для использования. Если identifier-1 не содержал допустимого адреса, никаких действий не будет выполнено.
  4. Если identifier-1 является элементом данных типа указатель и этот элемент данных в настоящее время является базирующимся (то есть в настоящее время имеет выделенную память), его память освобождается, и identifier-1 становится безбазовым и, следовательно, непригодным для использования. Если identifier-1 не был базирующимся, никаких действий не будет выполнено.

7.8.18. GENERATE

Синтаксис GENERATE

 GENERATE { report-name-1 }
 ~~~~~~~~ { identifier-1  }

Оператор GENERATE предоставляет данные для отчета.

  1. Следующие пункты применяются, когда указан identifier-1:
    1. identifier-1 должен быть именем группы отчётов DETAIL (см. Словарь RWCS).
    2. При необходимости identifier-1 можно квалифицировать именем отчёта.
    3. Файл, в котором существует FD для отчёта, в котором identifier-1 является группой деталей, должен быть открыт для OUTPUT или EXTEND в момент выполнения GENERATE. См. OPEN для информации о режимах открытия файлов.
    4. Отчёт, в котором identifier-1 является группой DETAIL, должен быть успешно инициирован с помощью оператора INITIATE (см. INITIATE) и ещё не завершён оператором TERMINATE (см. TERMINATE) в момент выполнения GENERATE.
    5. Если по крайней мере один оператор GENERATE данной формы выполняется относительно отчёта, отчёт называется отчётом деталей. Если операторы GENERATE данной формы не выполняются относительно отчёта, отчёт называется отчётом сводки.
  2. Следующие пункты применяются, когда указано report-name-1:
    1. report-name-1 должен быть именем отчёта, для которого в разделе отчёта определён RD.
    2. Для report-name-1 должна быть определена хотя бы одна группа CONTROL (см. Словарь RWCS).
    3. Для report-name-1 не может быть определено более одной группы DETAIL.
    4. Файл, в котором существует FD для REPORT report-name-1, должен быть открыт для OUTPUT или EXTEND в момент выполнения GENERATE.
    5. report-name-1 должен быть успешно инициирован (через INITIATE report-name-1) и ещё не завершён (через TERMINATE) в момент выполнения GENERATE. См. OPEN для информации о режимах открытия файлов.
    6. Группа DETAIL, определённая для report-name-1, будет обработана, но фактически не будет представлена ни одной странице отчёта. Это позволит выполнить обработку сводки. Если все операторы GENERATE являются такого вида, отчёт называется отчётом сводки. Если выполняется хотя бы один оператор GENERATE identifier-1, отчёт считается отчётом деталей.
  3. При выполнении первого оператора GENERATE для отчёта содержимое всех управляющих полей сохраняется, чтобы оно могло быть использовано во время обработки последующих операторов GENERATE.
  4. При обработке последующего оператора GENERATE, если определяется, что значение управляющего поля изменилось (т.е. произошёл разрыв управления), выполнится соответствующая обработка подвалов и заголовков управления, а также будет сохранён снимок текущих значений всех управляющих полей.

7.8.19. Возврат

Синтаксис GOBACK

 GOBACK [ { RETURNING|GIVING { literal-1    }  ]
 ~~~~~~   { ~~~~~~~~~ ~~~~~~ { identifier-1 }

Оператор GOBACK используется для логического завершения выполняемой программы.

  1. Если он выполняется в подпрограмме (т.е. в подпрограмме или определяемой пользователем функции), GOBACK ведет себя как оператор EXIT PROGRAM или EXIT FUNCTION соответственно.
  2. Если он выполняется в основной программе, GOBACK будет действовать как оператор STOP RUN.
  3. Необязательная часть RETURNING предоставляет возможность вернуть числовое значение операционной системе (технически, статус выхода). Способ, которым операционная система запрашивает значение статуса выхода, различается. Windows может использовать %ERRORLEVEL% для запроса статуса выхода, в то время как оболочки Unix, такие как sh, bash и ksh, могут запрашивать статус выхода как $?. У других оболочек Unix могут быть иные способы доступа к статусу выхода.

7.8.20. Перейти к

7.8.20.1. Простой переход

Синтаксис простого перехода

 GO TO procedure-name-1
 ~~

Этот вид оператора GO TO безусловно передает управление в программе первому исполняемому оператору в указанной procedure-name-1.

  1. Зарезервированное слово TO необязательно и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Если этот формат оператора GO TO появляется в последовательности императивных операторов (см. Императивный оператор) в предложении, он должен быть последним оператором в этом предложении.
  3. Если оператор GO TO выполняется в области действия…
    1. ...встроенного PERFORM (см. PERFORM), оператор PERFORM завершается, так как управление передаётся процедуре procedure-name-1.
    2. ...процедурного PERFORM (см. PERFORM), и procedure-name-1 находится вне области действия этого PERFORM, оператор PERFORM завершается, так как управление передаётся процедуре procedure-name-1.
    3. ...оператора MERGE (см. MERGE) OUTPUT PROCEDURE или в области действия либо INPUT PROCEDURE или OUTPUT PROCEDURE оператора SORT (см. File-Based SORT), и procedure-name-1 находится вне области действия этой процедуры, операция SORT или MERGE прерывается, и управление передаётся процедуре procedure-name-1. Любые отсортированные или объединённые данные, накопленные к этому моменту, теряются.

7.8.20.2. GO TO DEPENDING ON

GO TO DEPENDING ON Синтаксис

 GO TO procedure-name-1...
 ~~
      DEPENDING ON identifier-1
      ~~~~~~~~~

Этот вид оператора GO TO передаст управление одной из нескольких указанных процедур в зависимости от числового значения идентификатора, указанного в операторе.

  1. Зарезервированное слово TO необязательно и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Тип PICTURE (см. PICTURE) и/или USAGE (см. USAGE) указанного identifier-1 должен быть таким, чтобы определить его как числовой, неотредактированный, предпочтительно беззнаковый целочисленный элемент данных.
  3. Если значение identifier-1 равно 1, управление будет передано первой указанной процедуре. Если значение равно 2, управление будет передано второй процедуре и так далее.

    Если управление передаётся процедуре, указанной в операторе, и оператор GO TO выполняется в области действия…

    1. ...встроенного PERFORM (см. PERFORM), оператор PERFORM завершается, так как управление передаётся процедуре, указанной в операторе.
    2. ...процедурного PERFORM (см. PERFORM), и procedure-name-1 находится вне области действия этого PERFORM, оператор PERFORM завершается, так как управление передаётся процедуре, указанной в операторе.
    3. ...оператора MERGE (см. MERGE) OUTPUT PROCEDURE или в области действия либо INPUT PROCEDURE или OUTPUT PROCEDURE оператора SORT (см. File-Based SORT), и procedure-name-1 находится вне области действия этой процедуры, операция SORT или MERGE прерывается, и управление передаётся процедуре, указанной в операторе. Любые отсортированные или объединённые данные, накопленные к этому моменту, теряются.
  4. Если значение identifier-1 меньше 1 или превышает общее количество процедур, указанных в операторе, управление просто перейдёт к следующему оператору после GO TO.
  5. Следующий пример показывает, как GO TO ... DEPENDING ON может быть использован в реальной ситуации применения, и сравнивает его с альтернативой — EVALUATE (см. EVALUATE).
    GO TO DEPENDING ON EVALUATE
        GO TO
          ACCT-TYPE-1
          ACCT-TYPE-2
          ACCT-TYPE-3
        DEPENDING ON Acct-Type.
        <<< Invalid Acct Type >>>
        GO TO All-Done.
    Acct-Type-1.
        <<< Handle Acct Type 1 >>>
        GO TO All-Done.
    Acct-Type-2.
        <<< Handle Acct Type 2 >>>
        GO TO All-Done.
    Acct-Type-3.
        <<< Handle Acct Type 3 >>>
    All-Done.
    
    EVALUATE Acct-Type
    WHEN 1
        <<< Handle Acct Type 1 >>>
    WHEN 2
        <<< Handle Acct Type 2 >>>
    WHEN 3
        <<< Handle Acct Type 3 >>>
    WHEN OTHER
        <<< Invalid Acct Type >>>
    END-EVALUATE.
    
  6. Современная философия программирования отдаёт предпочтение использованию оператора EVALUATE по сравнению с этим видом оператора GO TO.

7.8.21. IF

IF Синтаксис

   IF conditional-expression
   ~~
   THEN { imperative-statement-1 }
        { NEXT SENTENCE          }
          ~~~~ ~~~~~~~~
 [ ELSE { imperative-statement-2 } ]
   ~~~~ { NEXT SENTENCE          }
          ~~~~ ~~~~~~~~
 [ END-IF ]
   ~~~~~~

Оператор IF используется для условного выполнения императивного оператора (см. Императивный оператор) или для выбора одного из двух различных императивных операторов для выполнения на основе значения TRUE/FALSE условного выражения.

  1. Зарезервированное слово THEN является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Вы не можете использовать одновременно NEXT SENTENCE и END-IF терминатор области в одном и том же операторе IF.
  3. Если условное выражение оценивается как TRUE, оператор-1 будет выполнен независимо от наличия или отсутствия ELSE. После выполнения оператор-1 управление передаётся в первую инструкцию, следующую за END-IF, или к первой инструкции следующего предложения, если нет END-IF.
  4. Если необязательная ELSE фраза присутствует и условное выражение оценивается как ложь, то (и только тогда) оператор-2 будет выполнен. После выполнения оператор-2 управление передаётся в первую инструкцию, следующую за END-IF, или к первой инструкции следующего предложения, если нет END-IF фразы.
  5. Фраза NEXT SENTENCE может быть заменена на любой из операторов, но не на оба. Если управление достигает NEXT SENTENCE фразы в результате истинности или ложности условного выражения, управление будет передано первой инструкции следующего предложения в программе (первой инструкции после следующей точки).

    NEXT SENTENCE требовалось для программ COBOL, которые были закодированы согласно стандартам до 1985 года, которые желали вложить один оператор IF в другой. См. Использование конструкций VERB/END-VERB, чтобы понять, почему NEXT SENTENCE был необходим.

    Программы, закодированные для стандартов 1985 года (и позже), не нуждаются в нём, вместо этого используя явный терминатор области END-IF для указания компилятору, где заканчивается оператор-2 (или оператор-1, если нет ELSE). Новые программы GnuCOBOL должны быть закодированы с использованием терминатора области END-IF для операторов IF. См. Использование конструкций VERB/END-VERB, для дополнительной информации.

7.8.22. INITIALIZE

INITIALIZE Синтаксис

  INITIALIZE|INITIALISE identifier-1...
  ~~~~~~~~~~ ~~~~~~~~~~
      [ WITH FILLER ]
             ~~~~~~
      [ { category-name-1 } TO VALUE ]
        { ALL             }    ~~~~~
          ~~~
      [ THEN REPLACING { category-name-2 DATA BY
             ~~~~~~~~~                        ~~
            [ LENGTH OF ] { literal-1    } }... ]
              ~~~~~~      { identifier-1 }

      [ THEN TO DEFAULT ]
                ~~~~~~~

Оператор INITIALIZE инициализирует каждый идентификатор-1 определёнными значениями, в зависимости от указанных опций.

  1. Зарезервированные слова DATA, OF, THEN, TO и WITH являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированные слова INITIALIZE и INITIALISE взаимозаменяемы.
  3. Определения WITH FILLER, REPLACING и DEFAULT имеют смысл только если identifier-1 является элементом группы. Они будут приняты, если это элементарный элемент, но не будут выполнять никакой функции. Определение VALUE имеет смысл в обоих случаях.
  4. category-name-1 и/или category-name-2 могут быть любыми из следующих:
    ALPHABETIC

    Изображение PICTURE (см. PICTURE) элемента данных содержит только символы A.

    ALPHANUMERIC

    Изображение PICTURE элемента данных содержит только X или комбинацию символов A и 9.

    ALPHANUMERIC-EDITED

    Изображение PICTURE элемента данных содержит только символы X или комбинацию символов A и 9, а также как минимум один символ B, 0 (ноль) или /.

    NUMERIC

    Элемент данных описывается изображением с использованием опции USAGE (см. USAGE) или имеет изображение, состоящее только из символов P, 9, S и V.

    NUMERIC-EDITED

    Изображение PICTURE элемента данных содержит только символ 9 и как минимум один из символов редактирования $, +, -, CR, DB, ., ,, * или Z.

    NATIONAL

    Элемент данных содержит только символ N.

    NATIONAL-EDITED

    Элемент данных содержит только символы N, B, / и 0.

  5. Из последовательности элементов данных identifier-1, указанных в инструкции INITIALIZE, список инициализированных полей, называемый в дальнейшей части этого раздела списком полей, будет включать:
    1. Каждый элемент identifier-1, являющийся элементарным элементом, включая любой элемент, который может иметь определение REDEFINES (см. REDEFINES) в своем описании.
    2. Каждый не-FILLER 3элементарный элемент, подчиненный identifier-1, при условии, что элементарный элемент не содержит определения REDEFINES и не принадлежит элементу группы, подчиненному identifier-1, который содержит определение REDEFINES.
    3. Если в инструкции INITIALIZE используется необязательная WITH FILLER часть, то каждый элементарный элемент FILLER, подчиненный identifier-1, также будет включен, при условии, что элементарный элемент не содержит определения REDEFINES и не принадлежит элементу группы, подчиненному identifier-1, который содержит определение REDEFINES.
  6. После определения списка полей, каждый элемент в этом списке будет инициализирован, как если бы была закодирована отдельная инструкция MOVE (см. MOVE). Правила инициализации следующие:
  7. Если не указаны VALUE, REPLACING или DEFAULT определения, каждый элемент списка полей будет инициализирован как если бы к нему перемещалась образцовая константа ZERO (если элемент списка полей является числовым или числовым с редактированием) или SPACES (в противном случае).
  8. Если в инструкции INITIALIZE используется определение VALUE, каждый соответствующий элемент списка полей, имеющий значение VALUE (см. VALUE), указанное во время компиляции, будет инициализирован этим значением. Элементы списка полей с VALUE определениями будут соответствовать этим правилам следующим образом:
    1. Если в определении VALUE используется ключевое слово ALL, все элементы списка полей с VALUE определениями будут соответствовать.
    2. Если вместо ALL указано category-name-1, только те элементы списка полей с VALUE определениями, которые также соответствуют критериям, установленным для указанного category-name (см. список выше), будут соответствовать.
    3. Если необходимо применить инициализацию VALUE к нескольким значениям category-name-1, необходимо использовать несколько инструкций INITIALIZE.
  9. Если в инструкции INITIALIZE указано определение REPLACING, каждый соответствующий элемент списка полей, который еще не был инициализирован определением VALUE, если таковое имеется, будет инициализирован указанным значением literal-1 или identifier-1.

    Только еще не инициализированные элементы списка, соответствующие критериям, установленным для указанного category-name-2, будут соответствовать этой инициализации.

    Если необходимо применить инициализацию REPLACING к нескольким значениям category-name-2, необходимо повторить синтаксис после зарезервированного слова REPLACING, по мере необходимости.

  1. Если указан пункт DEFAULT, все оставшиеся неинициализированные члены списка полей будут инициализированы в соответствии с умолчанием для их класса (числовые и числовые, отформатированные, инициализируются значением ZERO, все остальные инициализируются значением SPACES).
  2. Следующий пример может помочь вам понять, как работает инструкция INITIALIZE. Пример кода использует программу COBDUMP, чтобы вывести информацию о том, инициализируется ли хранилище (или нет). Обратитесь к COBDUMP в Примерах программ GnuCOBOL для получения исходного кода и перекрестной ссылки на программу COBDUMP.
    IDENTIFICATION DIVISION.
    PROGRAM-ID. DemoInitialize.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01  Item-1.
        05 I1-A VALUE ALL '*'.
           10 FILLER                PIC X(1).
           10 I1-A-1                PIC 9(1) VALUE 9.
        05 I1-B                     USAGE BINARY-CHAR.
        05 I1-C                     PIC A(1) VALUE 'C'.
        05 I1-D                     PIC X/X VALUE 'ZZ'.
        05 I1-E                     OCCURS 2 TIMES PIC 9.
    PROCEDURE DIVISION.
    000-Main.
        DISPLAY "MOVE HIGH-VALUES TO Item-1"
            PERFORM 100-Init-Item-1
            CALL "COBDUMP" USING Item-1
            DISPLAY " "
    
        DISPLAY "INITIALIZE Item-1"
            INITIALIZE Item-1
            CALL "COBDUMP" USING Item-1
            PERFORM 100-Init-Item-1
            DISPLAY " "
    
        DISPLAY "INITIALIZE Item-1 WITH FILLER"
            MOVE HIGH-VALUES TO Item-1
            INITIALIZE Item-1 WITH FILLER
            CALL "COBDUMP" USING Item-1
            PERFORM 100-Init-Item-1
            DISPLAY " "
    
        DISPLAY "INITIALIZE Item-1 ALL TO VALUE"
            MOVE HIGH-VALUES TO Item-1
            INITIALIZE Item-1 ALPHANUMERIC TO VALUE
            CALL "COBDUMP" USING Item-1
            PERFORM 100-Init-Item-1
            DISPLAY " "
    
        DISPLAY "INITIALIZE Item-1 REPLACING NUMERIC BY 1"
            MOVE HIGH-VALUES TO Item-1
            INITIALIZE Item-1 REPLACING NUMERIC BY 1
            CALL "COBDUMP" USING Item-1
            PERFORM 100-Init-Item-1
            DISPLAY " "
    
        STOP RUN
        .
    
    100-Init-Item-1.
        MOVE HIGH-VALUES TO Item-1
        .
    

    При выполнении эта программа выводит следующий результат:

    MOVE HIGH-VALUES TO Item-1
    <-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
    ======== ==== =============================================== ================
    00404058    1 FF FF FF FF FF FF FF FF FF                      .........
    
    INITIALIZE Item-1
    <-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
    ======== ==== =============================================== ================
    00404058    1 FF 30 00 20 20 2F 20 30 30                      .0.  / 00
    
    INITIALIZE Item-1 WITH FILLER
    <-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
    ======== ==== =============================================== ================
    00404058    1 20 30 00 20 20 2F 20 30 30                       0.  / 00
    
    INITIALIZE Item-1 ALL TO VALUE
    <-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
    ======== ==== =============================================== ================
    00404058    1 2A 2A FF 43 5A 5A 20 FF FF                      **.CZZ ..
    
    INITIALIZE Item-1 REPLACING NUMERIC BY 1
    <-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
    ======== ==== =============================================== ================
    00404058    1 FF 31 01 FF FF FF FF 31 31                      .1.....11
    

7.8.23. INITIATE

INITIATE Синтаксис

 INITIATE report-name-1
 ~~~~~~~~

Инструкция INITIATE запускает обработку системы управления отчётами (RWCS) для отчёта.

  1. Каждый report-name-1 должен быть именем отчёта, для которого определён раздел RD (см. РАЗДЕЛ REPORT).
  2. Файл, в описании которого FD (см. Описание файла/сортировки) присутствует пункт REPORT report-name-1, должен быть открыт для OUTPUT или EXTEND в момент выполнения инструкции INITIATE. См. OPEN для получения дополнительной информации о режимах открытия файлов.
  3. Инструкция INITIATE инициализирует следующие параметры для каждого отчёта, указанного в инструкции:
    • Все суммарные счётчики, если таковые имеются, будут установлены в 0
    • Специальный регистр отчёта LINE-COUNTER (см. Специальные регистры) будет установлен в 0
    • Специальный регистр отчёта PAGE-COUNTER будет установлен в 1
  4. В результате успешного выполнения инструкции INITIATE содержимое отчёта фактически не будет отображено в файле отчёта — это произойдёт только после выполнения первой инструкции GENERATE (см. GENERATE).

7.8.24. INSPECT

INSPECT Синтаксис

 INSPECT { literal-1            }
 ~~~~~~~ { identifier-1         }
         { function-reference-1 }

  [ TALLYING { identifier-2 FOR { ALL|LEADING|TRAILING { literal-2    } }
    ~~~~~~~~                ~~~ { ~~~ ~~~~~~~ ~~~~~~~~ { identifier-3 } }
                                { CHARACTERS                            }
                                  ~~~~~~~~~~
               [ | { AFTER|BEFORE } INITIAL { literal-3    } | ] }... ]
                 |   ~~~~~ ~~~~~~           { identifier-4 } |

  [ REPLACING { { { ALL|FIRST|LEADING|TRAILING { literal-4    } }
    ~~~~~~~~~   { { ~~~ ~~~~~ ~~~~~~~ ~~~~~~~~ { identifier-5 } }
                { CHARACTERS                                    }
                { ~~~~~~~~~~                                    }

                 BY { [ ALL ] literal-5 }
                 ~~ {   ~~~             }
                    { identifier-6      }

               [ | { AFTER|BEFORE } INITIAL { literal-6    } | ] }... ]
                 |   ~~~~~ ~~~~~~           { identifier-7 } |

  [ CONVERTING { { literal-7    } TO { literal-8    }
    ~~~~~~~~~~   { identifier-8 } ~~ { identifier-9 }

               [ | { AFTER|BEFORE } INITIAL { literal-9     } | ] ]
                 |   ~~~~~ ~~~~~~           { identifier-10 } |

Инструкция INSPECT используется для выполнения различных операций подсчёта и/или изменения данных в строках.

  1. Зарезервированное слово INITIAL является необязательным и может быть опущено. Наличие или отсутствие этого слова не оказывает влияния на программу.
  2. Если указан пункт CONVERTING, ни пункт TALLYING, ни пункт REPLACING не могут быть использованы.
  3. Если указаны пункты TALLYING или REPLACING, пункт CONVERTING использовать нельзя.
  4. Если указаны оба пункта TALLYING и REPLACING, они должны быть указаны в порядке, показанном.
  5. Все литералы и идентификаторы должны быть явно или неявно определены как алфавитно-цифровые или алфавитные.
  6. Если указан function-reference-1, он должен быть вызовом внутренней функции, возвращающей строковый результат. Кроме того, может быть указан только пункт TALLYING.
  7. Если указан literal-1, может быть указан только пункт TALLYING.
  8. Какой бы из элементов — literal-1, identifier-1 или function-reference-1 — ни был указан, этот элемент будет упоминаться в последующих обсуждениях как ’объект инспекции’.
  9. Три необязательных пункта контролируют работу этого оператора следующим образом:
    1. Пункт CONVERTING заменяет один или несколько отдельных символов, найденных в объекте инспекции, другим символом, примерно так же, как это возможно с оператором TRANSFORM (см. TRANSFORM).
    2. Пункт REPLACING заменяет один или несколько подстрок, расположенных в объекте инспекции, другой, но такой же длины, подстрокой. Если вам нужно заменить подстроку другой подстрокой разной длины, рассмотрите использование внутренней функции SUBSTITUTE (см. SUBSTITUTE) или внутренней функции SUBSTITUTE-CASE (см. SUBSTITUTE-CASE).
    3. Пункт TALLYING подсчитывает количество вхождений одной или нескольких строк символов в объекте инспекции.
  10. Необязательные пункты INITIAL могут быть использованы для ограничения диапазона символов в объекте инспекции, на который будут распространяться инструкции CONVERTING, REPLACING или TALLYING, в которых они встречаются. Мы называем это ’целевым диапазоном’ объекта инспекции. Целевой диапазон определяется следующим образом:
    1. Если не указан пункт INITIAL, целевой диапазон — весь объект инспекции.
    2. Может быть указана фраза BEFORE, фраза AFTER или обе. Они могут быть указаны в любом порядке.
    3. Начальной точкой целевого диапазона будет первый символ, следующий за подстрокой, идентифицированной спецификацией AFTER. Конечной точкой будет последний символ, непосредственно предшествующий подстроке, идентифицированной спецификацией BEFORE.
    4. Если не указан AFTER, позиция первого символа целевого диапазона будет позицией символа #1 в объекте инспекции.
    5. Если не указан BEFORE, позиция последнего символа целевого диапазона будет последней позицией символа в объекте инспекции.
  1. Следующие пункты относятся к использованию TALLYING пункта:
    1. Обычно будет только один набор инструкций подсчета на INSPECT:
      INSPECT Character-String
          TALLYING C-ABC FOR ALL "ABC"
      

      Могут быть указаны несколько инструкций подсчета:

      INSPECT Character-String
          TALLYING C-ABC FOR ALL "ABC"
                   C-BCDE FOR ALL "BCDE"
      

      Когда есть несколько инструкций, первая указанная будет иметь приоритет над второй (и так далее), по мере того, как INSPECT последовательно обрабатывает исследуемый объект, символ за символом.

      В приведенном примере, если исследуемый объект был --ABCDEF----BCDEF--, окончательный результат подсчета будет таким, что C-ABC будет увеличен на 1, а C-BCDE будет увеличен только один раз; хотя человеческий глаз ясно видит две последовательности «BCDE», INSPECT ... TALLYING увидит только вторую — первая будет обработана первой (имеющей более высокий приоритет) инструкцией подсчета.

    2. Каждый набор инструкций подсчета содержит следующую информацию:
      1. Диапазон цели, указанный наличием AFTER INITIAL и/или BEFORE INITIAL пункта; правила указания диапазонов целей были рассмотрены ранее.
      2. Подстрока цели — это последовательность символов, которую нужно найти где-то в исследуемом объекте и подсчитать. Подстроки целей могут быть определены как буквальное значение (разрешены образные константы) или содержимым идентификатора. Если подстрока цели задана как образная константа, предполагается, что она имеет длину один (‘1’) символ. Ключевые слова перед буквальным значением или идентификатором контролируют, сколько подстрок целей можно определить из этой инструкции замены, следующим образом:

        ALL — определяет все возможные подстроки цели, встречающиеся в диапазоне цели. В aXXabbXXccXXdd встречается три вхождения ALL 'XX'.

        LEADING — определяет только одно вхождение подстроки цели, которое находится либо в первой позиции диапазона цели, либо непосредственно после ранее найденного вхождения. В aXXabbXXccXXdd нет вхождений LEADING 'XX', но есть одно вхождение LEADING 'a' (первый символ).

        TRAILING — определяет только одно вхождение подстроки цели, которое находится либо в конце диапазона цели, либо к концу, за которым ничего, кроме других вхождений. В aXXabbXXccXXdd нет вхождений LEADING 'XX', но есть два вхождения TRAILING 'd'.

        Вариант CHARACTERS соответствует любому одному символу, независимо от того, какой это символ.

    3. identifier-2 будет увеличиваться на 1 каждый раз, когда подстрока цели будет найдена в диапазоне цели исследуемого объекта. Оператор INSPECT не обнуляет identifier-2 в начале выполнения INSPECT — программисту необходимо убедиться, что все элементы данных identifier-2 правильно инициализированы до желаемых начальных значений перед выполнением INSPECT.
  1. Следующие пункты относятся к использованию клаузы REPLACING:
    1. Обычно будет только один набор инструкций по замене на INSPECT:
      INSPECT Character-String
          REPLACING ALL "ABC" BY "DEF"
      

      Могут быть несколько инструкций по замене:

      INSPECT Character-String
          REPLACING ALL "ABC" BY "DEF"
                    ALL "BCDE" BY "WXYZ"
      

      Когда есть несколько инструкций по замене, инструкция, указанная первой, будет иметь приоритет над указанной второй (и так далее), по мере того, как INSPECT будет проходить по проверяемому объекту, символ за символом.

      В приведенном выше примере, если проверяемый объект будет --ABCDEF----BCDEF--, конечный результат замены будет --DEFDEF----WXYZF--.

    2. Каждый набор инструкций по замене содержит следующую информацию:
      1. Диапазон целей, указанный наличием клаузы AFTER INITIAL и/или BEFORE INITIAL; правила указания диапазонов целей были рассмотрены ранее.
      2. Целевой подстрока — это последовательность символов, которая должна быть найдена где-то в проверяемом объекте и затем заменена новым значением. Целевые подстроки, которые указаны перед ключевым словом BY, могут быть определены как литеральное значение (разрешены образные константы) или содержимое идентификатора. Если целевая подстрока задана как образная константа, она будет считаться имеющей длину в один (‘1’) символ. Ключевые слова перед литералом или идентификатором управляют тем, сколько целевых подстрок можно идентифицировать из этой инструкции по замене, следующим образом:

        ALL — идентифицирует все возможные целевые подстроки, которые встречаются в заданном диапазоне. В aXXabbXXccXXdd встречаются три вхождения ALL 'XX'.

        FIRST — первое вхождение целевой подстроки, найденной в заданном диапазоне. Вхождение FIRST 'XX' в aXXabbXXccXXdd будет тем, что находится между символами ‘a’ и ‘b’.

        LEADING — вхождение целевой подстроки, найденное либо в первой позиции целевого диапазона, либо непосредственно после ранее найденного вхождения. В aXXabbXXccXXdd нет вхождений LEADING 'XX', но есть одно вхождение LEADING 'a' (первый символ).

        TRAILING — вхождение целевой подстроки, найденное либо в самом конце целевого диапазона, либо ближе к концу, за которым ничего не следует, кроме других вхождений. В aXXabbXXccXXdd нет вхождений LEADING 'XX', но есть два вхождения TRAILING 'd'.

        Вариант CHARACTERS будет соответствовать любому одному символу. Когда вы используете этот вариант, подстрока замены (см. следующий пункт) должна иметь длину ровно один символ.

      3. Подстрока замены — это последовательность символов, которые должны заменить целевую подстроку. Подстроки замены указываются после ключевого слова BY. Они также могут быть указаны как литерал, с или без префикса ALL (опять же, разрешены образные константы) или значением идентификатора. Если закодирована образная константа, будет предполагаться ключевое слово ALL, даже если оно не было указано. Литералы без ALL будут либо усечены, либо дополнены пробелами справа, чтобы соответствовать длине целевой подстроки. Литералы с ALL или образные константы будут повторяться по мере необходимости, чтобы соответствовать длине целевой подстроки. Идентификаторы, заданные в качестве подстрок замены, должны быть определены с длиной, равной длине целевой подстроки.
    3. Когда указаны как REPLACING, так и TALLYING:
      1. Оператор INSPECT выполнит одно прохождение по последовательности символов, составляющих проверяемый объект. Когда указатель на текущий проверяемый целевой символ достигнет точки, попадающей в явный или неявный диапазон целей, указанные в оперативных инструкциях двух клауз, действия, заданные этими инструкциями, станут доступными для выполнения. Когда указатель символа достигнет точки, находящейся за пределами диапазонов целей, инструкции, относящиеся к этим диапазонам целей, станут неактивными.
      2. В любой момент времени может быть несколько активных инструкций REPLACING и/или TALLYING. Только одна из инструкций TALLYING и одна из инструкций REPLACING (если таковые имеются) могут быть выполнены для любой позиции указателя символа. В каждом случае будет первой из инструкций в каждой категории, которая найдет соответствие в своем спецификации целевой строки.
      3. Когда и инструкция TALLYING, и инструкция REPLACING были выбраны для выполнения, инструкция TALLYING будет выполнена первой. Это гарантирует, что TALLYING будет рассчитывать вхождения, исходя из начального значения проверяемого объекта до выполнения каких-либо замен.
  1. Следующие пункты относятся к использованию CONVERTING оператора:
    1. Оператор CONVERTING выполняет серию замещений символов по одному в элементе данных, аналогично возможностям оператора TRANSFORM (см. TRANSFORM).
    2. В отличие от операторов TALLYING и REPLACING, в которых могут быть указаны несколько операций, оператор CONVERTING имеет только одну операцию на INSPECT.
    3. Если длина literal-7 или identifier-8 (строки «из») превышает длину literal-8 или identifier-9 (строки «в»), то строка «в» будет дополнена пробелами справа до длины строки «из».
    4. Если длина строки «из» меньше длины строки «в», то строка «в» будет усечена до длины строки «из».
    5. Каждый символ строки «из» последовательно ищется в целевом диапазоне проверяемого объекта. Каждая найденная встреча заменяется соответствующим символом из строки «в».

7.8.25. СЛИЯНИЕ

Синтаксис СЛИЯНИЯ

 MERGE sort-file-1
 ~~~~~
    { ON { ASCENDING  } KEY identifier-1... }...
         { ~~~~~~~~~  }
         { DESCENDING }
           ~~~~~~~~~~
    [ WITH DUPLICATES IN ORDER ]
           ~~~~~~~~~~
    [ COLLATING SEQUENCE IS alphabet-name-1 ]
      ~~~~~~~~~
      USING file-name-1 file-name-2...
      ~~~~~
    { OUTPUT PROCEDURE IS procedure-name-1    }
    { ~~~~~~ ~~~~~~~~~                        }
    {       [ THRU|THROUGH procedure-name-2 ] }
    {         ~~~~ ~~~~~~~                    }
    { GIVING file-name-3...                   }
    { ~~~~~~                                  }

Оператор DUPLICATES синтаксически распознаётся, но не выполняет никаких функций.

Оператор MERGE объединяет содержимое двух или более файлов, предварительно отсортированных по набору идентичных ключей.

  1. Зарезервированные слова IN, IS, KEY, ON, ORDER, SEQUENCE и WITH являются необязательными и могут быть опущены. Их присутствие или отсутствие не влияет на программу.
  2. Зарезервированные слова THRU и THROUGH взаимозаменяемы.
  3. GnuCOBOL всегда ведет себя так, как будто оператор WITH DUPLICATES IN ORDER указан, даже если его нет.

    Хотя средства сортировки и слияния любой реализации COBOL гарантируют, что записи с дублирующимися значениями ключа будут в правильной последовательности относительно других записей с разными значениями ключа, они обычно не дают никаких гарантий относительно относительной последовательности записей с дублирующимися значениями ключа друг относительно друга.

    Некоторые реализации COBOL предоставляют этот необязательный оператор, чтобы заставить их средства сортировки и слияния сохранять записи с дублирующимися значениями ключа в исходной последовательности входных данных относительно друг друга.

  4. Файл sort-file-1, указанный в операторе MERGE, должен быть определён с помощью описания сортировки (SD (см. Файл/ОписаниеСортировки)). Этот файл в дальнейшем обсуждении называется рабочим файлом слияния.
  5. Каждый file-name-1, file-name-2 и file-name-3 (если указаны) должны ссылаться на файлы ORGANIZATION LINE SEQUENTIAL (см. ОРГАНИЗАЦИЯ ПОСЛЕДОВАТЕЛЬНАЯ С ЛИНИЯМИ) или ORGANIZATION SEQUENTIAL (см. ОРГАНИЗАЦИЯ ПОСЛЕДОВАТЕЛЬНАЯ). Эти файлы должны быть определены с помощью описания файла (FD (см. Файл/ОписаниеСортировки)).
  6. Поле(я) identifier-1 … должны быть определены как поле(я) в записи файла sort-file-1.
  7. Описания записей file-name-1, file-name-2, file-name-3 (если есть) и sort-file-1 предполагаются идентичными по структуре и размеру. Хотя фактические имена полей, используемые в записях этих файлов, могут отличаться, структура записей, PICTURE (см. PICTURE) полей, USAGE (см. USAGE) полей, размер полей и расположение полей в записях должны совпадать поле за полем во всех файлах, по крайней мере, в отношении полей KEY.
  8. Распространённый приём программирования при использовании оператора MERGE заключается в определении записей всех участвующих файлов как простых элементарных элементов вида 01 record-name PIC X(n)., где n — размер записи. Единственный файл, в котором записи описаны подробно, — sort-file-1.
  9. Следующие правила применяются к файлам, указанным в операторе USING:
    1. Ни один из них не может быть открыт в момент выполнения оператора MERGE.
    2. Каждый из этих файлов предполагается уже отсортированным согласно спецификациям, указанным в операторе MERGE, в разделе KEY.
    3. Ни два из этих файлов не могут быть использованы в операторах SAME RECORD AREA (см. ОДНА ОБЛАСТЬ ЗАПИСЕЙ), SAME SORT AREA или SAME SORT-MERGE AREA.
  1. Процесс слияния выполняется следующим образом:
    1. При запуске оператора MERGE, автоматически считывается первый элемент каждого из файлов USING.
    2. При выполнении оператора MERGE, текущий элемент из каждого из файлов USING проверяется и сравнивается с другими элементами в соответствии с правилами, установленными в пункте KEY, и алфавитом (см. Alphabet-Name-Clause), указанным в пункте COLLATING SEQUENCE. Элемент, который должен следовать следующим в последовательности, записывается в файл промежуточной обработки, а файл USING, из которого он был получен, считывается, чтобы его следующий элемент был доступен. По достижении конца файла в файлах USING, эти файлы исключаются из дальнейшей обработки — обработка продолжается с оставшимися файлами, пока не будут израсходованы все их содержимое.
    3. После заполнения файла промежуточной обработки объединенные данные будут записаны в каждый файл file-name-3, если был указан пункт GIVING, или будут обработаны с использованием OUTPUT PROCEDURE.
    4. Если указан GIVING, ни один из файлов file-name-3 не может быть открыт в момент выполнения оператора MERGE.
    5. Если используется процедура вывода, то указанные в пункте OUTPUT PROCEDURE процедуры будут вызваны, как если бы они были оператором процедурного PERFORM (см. Procedural PERFORM) без указанных опций VARYING, TIMES или UNTIL. Объединенные записи могут считываться из файла промежуточной обработки — по одному за раз — внутри процедуры вывода с использованием оператора RETURN (см. RETURN).

      Оператор GO TO (см. GO TO), который передает управление за пределы процедуры вывода, завершит оператор MERGE, но позволит программе продолжить выполнение с точки, в которой оператор GO TO передал управление. После того, как процедура вывода была «прервана» с помощью оператора GO TO, её нельзя возобновить, и содержимое файла промежуточной обработки теряется. Однако вы можете повторно выполнить сам оператор MERGE. Использование оператора GO TO для преждевременного завершения слияния или перезапуска ранее отменённого слияния не считается хорошим стилем программирования и следует избегать.

      Процедура вывода должна завершаться так же, как и оператор процедурного PERFORM. Обычно это действие выполняется после того, как оператор RETURN указывает, что все записи в файле промежуточной обработки были обработаны, но завершение может произойти в любое время — с помощью оператора EXIT (см. EXIT) — если это необходимо.

      Ни оператор файлового SORT (см. File-Based SORT), ни другой оператор MERGE не могут быть выполнены в рамках процедур, составляющих процедуру вывода, если эти операторы не используют другой файл сортировки или файл промежуточной обработки.

    6. После завершения процедуры вывода или заполнения последнего файла file-name-3 объединёнными данными, фаза вывода — и сам оператор MERGE — завершены.

7.8.26. MOVE

7.8.26.1. Простой MOVE

Синтаксис простого MOVE

 MOVE { literal-1    } TO identifier-2...
 ~~~~ { identifier-1 } ~~

Оператор Simple MOVE перемещает определенное значение в один или несколько целевых элементов данных.

  1. Оператор MOVE заменит содержимое одного или нескольких целевых элементов данных (identifier-2) новым значением — указанным literal-1 или identifier-1.
  2. В числовой элемент данных (identifier-2) или числовой элемент с редактированием (identifier-2) могут быть перемещены только числовые данные. MOVE, включающий числовые данные, выполнит все необходимые преобразования формата, которые могут потребоваться из-за различных спецификаций USAGE (см. USAGE).
  3. Содержимое элемента данных identifier-1 не изменится, если этот же элемент данных не указан как identifier-2. В таких ситуациях компилятор выдаст сообщение об ошибке, если сообщения об ошибках включены.

7.8.26.2. MOVE CORRESPONDING

Синтаксис MOVE CORRESPONDING

 MOVE CORRESPONDING identifier-1 TO identifier-2...
 ~~~~ ~~~~                       ~~

Оператор MOVE CORRESPONDING аналогичным образом перемещает элементы из одной группы элементов в другую.

  1. Зарезервированное слово CORRESPONDING может быть сокращено до CORR.
  2. И identifier-1, и identifier-2 должны быть группами элементов.
  3. См. CORRESPONDING, для обсуждения того, как устанавливаются соответствующие соответствия между двумя группами элементов.
  4. Когда соответствующие соответствия устанавливаются, эффект оператора MOVE CORRESPONDING на эти соответствия будет таким, как если бы была выполнена серия отдельных операторов MOVE — по одному для каждого соответствия.

7.8.27. MULTIPLY

7.8.27.1. MULTIPLY BY

Синтаксис MULTIPLY BY

 MULTIPLY { literal-1    } BY { identifier-2
 ~~~~~~~~ { identifier-1 } ~~

      [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
        ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                          { NEAREST-AWAY-FROM-ZERO }
                          { ~~~~~~~~~~~~~~~~~~~~~~ }
                          { NEAREST-EVEN           }
                          { ~~~~~~~~~~~~           }
                          { NEAREST-TOWARD-ZERO    }
                          { ~~~~~~~~~~~~~~~~~~~    }
                          { PROHIBITED             }
                          { ~~~~~~~~~~             }
                          { TOWARD-GREATER         }
                          { ~~~~~~~~~~~~~~         }
                          { TOWARD-LESSER          }
                          { ~~~~~~~~~~~~~          }
                          { TRUNCATION             }
                            ~~~~~~~~~~
    [ ON SIZE ERROR imperative-statement-1 ]
         ~~~~ ~~~~~
    [ NOT ON SIZE ERROR imperative-statement-2 ]
      ~~~    ~~~~ ~~~~~
 [ END-MULTIPLY ]
   ~~~~~~~~~~~~

Оператор MULTIPLY BY вычисляет произведение одного или нескольких элементов данных (identifier-2) и либо числовой константы, либо другого элемента данных.

  1. Зарезервированные слова IS и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. И identifier-1, и identifier-2 должны быть числовыми неотредактированными данными; literal-1 должен быть числовой константой.
  3. Произведение identifier-1 или literal-1 и каждого identifier-2 по очереди будет вычислено и помещено в каждый элемент данных identifier-2, заменяя предыдущее содержимое.
  4. Значение identifier-1 не изменяется, если этот же элемент данных не встречается как identifier-2.
  5. Необязательная ROUNDED (см. ROUNDED) фраза, доступная для каждого identifier-2, будет управлять тем, как будут сохраняться нецелые результаты.
  6. Необязательные ON SIZE ERROR и NOT ON SIZE ERROR фразы могут использоваться для обнаружения и реагирования соответственно на ошибку или успех попытки выполнения вычисления. В этом случае ошибка определяется как identifier-2 с недостаточным количеством разрядов слева от предполагаемой десятичной точки. См. ON SIZE ERROR + NOT ON SIZE ERROR для дополнительной информации.

7.8.27.2. УМНОЖЕНИЕ С РЕЗУЛЬТАТОМ

Синтаксис УМНОЖЕНИЕ С РЕЗУЛЬТАТОМ

 MULTIPLY { literal-1    } BY { literal-2    } GIVING { identifier-3
 ~~~~~~~~ { identifier-1 } ~~ { identifier-2 } ~~~~~~

      [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
        ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                          { NEAREST-AWAY-FROM-ZERO }
                          { ~~~~~~~~~~~~~~~~~~~~~~ }
                          { NEAREST-EVEN           }
                          { ~~~~~~~~~~~~           }
                          { NEAREST-TOWARD-ZERO    }
                          { ~~~~~~~~~~~~~~~~~~~    }
                          { PROHIBITED             }
                          { ~~~~~~~~~~             }
                          { TOWARD-GREATER         }
                          { ~~~~~~~~~~~~~~         }
                          { TOWARD-LESSER          }
                          { ~~~~~~~~~~~~~          }
                          { TRUNCATION             }
                            ~~~~~~~~~~
    [ ON SIZE ERROR imperative-statement-1 ]
         ~~~~ ~~~~~
    [ NOT ON SIZE ERROR imperative-statement-2 ]
      ~~~    ~~~~ ~~~~~
 [ END-MULTIPLY ]
   ~~~~~~~~~~~~

Утверждение MULTIPLY GIVING вычисляет произведение двух констант и/или элементов данных и сохраняет этот результат в одном или нескольких других элементах данных.

  1. Зарезервированные слова IS и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. И identifier-1, и identifier-2 должны быть числовыми неотредактированными элементами данных; literal-1 и literal-2 должны быть числовыми константами.
  3. Произведение identifier-1 или literal-1 и identifier-2 или literal-2 будет вычислено и помещено в каждый из элементов данных identifier-3, заменяя их старое содержимое.
  4. Значение ни identifier-1, ни identifier-2 не будет изменено, если они не встречаются как identifier-3.
  5. Необязательная ROUNDED (см. ROUNDED) фраза, доступная для каждого identifier-2, будет управлять тем, как будут сохраняться нецелые результаты.
  6. Необязательные ON SIZE ERROR и NOT ON SIZE ERROR фразы могут использоваться для обнаружения и реакции соответственно на ошибку или успех попытки выполнения вычисления. В этом случае ошибка определяется как identifier-2 с недостаточным количеством разрядов слева от предполагаемой десятичной точки. См. ON SIZE ERROR + NOT ON SIZE ERROR для дополнительной информации.

7.8.28. ОТКРЫТИЕ

Синтаксис ОТКРЫТИЯ

 OPEN { { INPUT  } [ SHARING WITH { ALL OTHER } ] file-name-1
 ~~~~   { ~~~~~  }   ~~~~~~~      { ~~~       }
        { OUTPUT }                { NO OTHER  }
        { ~~~~~~ }                { ~~        }
        { I-O    }                { READ ONLY }
        { ~~~    }                  ~~~~ ~~~~
        { EXTEND }
          ~~~~~~
      [ { REVERSED           } ] }...
        { ~~~~~~~~           }
        { WITH { NO REWIND } }
        {      { ~~ ~~~~~~ } }
        {      { LOCK      } }
                 ~~~~

Фразы NO REWIND, и REVERSED синтаксически распознаются, но в остальном не функциональны.

Утверждение OPEN делает доступными для использования один или несколько файлов, описанных в вашей программе.

  1. Зарезервированные слова OTHER и WITH являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Оба пункта SHARING и WITH LOCK не могут быть указаны в одном и том же операторе OPEN.
  3. Любой файл, определенный в программе GnuCOBOL, должен быть успешно открыт, прежде чем он или какие-либо его описания записей могут быть использованы в:

    Операторе CLOSE (см. CLOSE)

    Операторе DELETE (см. DELETE)

    Операторе READ (см. READ)

    Операторе REWRITE (см. REWRITE)

    Операторе START (см. START)

    Операторе UNLOCK (см. UNLOCK)

    Операторе WRITE (см. WRITE)

  4. Любая попытка открыть уже открытый файл завершится ошибкой с кодом состояния файла 41 (см. Коды состояния файла).
  5. Любая ошибка открытия (включая код 41) может быть перехвачена с помощью DECLARATIVES (см. ДЕКЛАРАТИВНЫЕ БЛОКИ) или с помощью процедуры обработки ошибок, установленной с помощью встроенной системной подпрограммы CBL_ERROR_PROC (см. CBL_ERROR_PROC) или просто проверкой поля статуса. Разработчик должен проверять коды статуса и реагировать на них, например, закрывать файл перед обработкой ошибки.
  6. Режимы открытия INPUT, OUTPUT, I-O и EXTEND сообщают GnuCOBOL о том, как вы хотите использовать файл следующим образом:
    INPUT

    Вы можете только читать существующее содержимое файла — разрешены только операторы CLOSE, READ, START и UNLOCK. Эта проверка осуществляется во время выполнения, а не во время компиляции.

    OUTPUT

    Вы можете только записывать новое содержимое (которое полностью заменит предыдущее содержимое файла) в файл — разрешены только операторы CLOSE, UNLOCK и WRITE. Эта проверка осуществляется во время выполнения, а не во время компиляции.

    I-O

    Вы можете выполнять любые операции с файлом — разрешены все операторы ввода-вывода файлов.

    EXTEND

    Вы можете только записывать новое содержимое (которое будет добавленно после существующего содержимого файла) в файл — разрешены только операторы CLOSE, UNLOCK и WRITE. Эта проверка осуществляется во время выполнения, а не во время компиляции. Вы не можете расширить пустой файл; это не сгенерирует ошибку во время выполнения, но в файле ничего не появится.

  7. Оператор SHARING сообщает модулям runtime GnuCOBOL, как вы хотите взаимодействовать с другими программами GnuCOBOL, которые могут попытаться открыть этот же файл после вашей программы. См. Разделение файлов для объяснения оператора SHARING.
  8. Опция WITH LOCK будет функциональной только в том случае, если ваш GnuCOBOL-билд ее поддерживает. GnuCOBOL, скомпилированный для MinGW или native Windows, не будет, потому что утилита Unix fcntl не существует в этих средах. GnuCOBOL, скомпилированный для Cygwin или Unix, будет.

7.8.29. PERFORM

7.8.29.1. Процедурный PERFORM

Синтаксис процедурного PERFORM

 PERFORM procedure-name-1 [ THRU|THROUGH procedure-name-2 ]
 ~~~~~~~                    ~~~~ ~~~~~~~
    [ { [ WITH TEST { BEFORE } ] { VARYING-Clause                 } } ]
      {        ~~~~ { ~~~~~~ }   { UNTIL conditional-expression-1 } }
      {             { AFTER  }     ~~~~~                            }
      {               ~~~~~                                         }
      { UNTIL EXIT|FOREVER                                          }
      { ~~~~~ ~~~~ ~~~~~~~                                          }
      { { literal-1    } TIMES                                      }
      { { identifier-1 } ~~~~~                                      }

Этот формат оператора PERFORM используется для передачи управления одной или нескольким процедурам, которые вернут управление обратно по завершении. Выполнение процедуры(ы) может быть выполнено один раз, несколько раз, многократно до тех пор, пока условие не станет TRUE или постоянно (с каким-либо способом выхода из управления PERFORM или остановки выполнения программы внутри процедуры(ы)).

  1. Зарезервированное слово WITH является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Зарезервированные слова THRU и THROUGH взаимозаменяемы.
  3. Зарезервированное слово и фраза FOREVER и UNTIL EXIT взаимозаменяемы.
  4. Оба procedure-name-1 и procedure-name-2 должны быть секциями или параграфами раздела процедур, определенными в той же программе, что и PERFORM оператор. Если procedure-name-2 указан, он должен следовать за procedure-name-1 в исходном коде программы.
  5. Область действия perform определяется как операторы внутри procedure-name-1, операторы внутри procedure-name-2 и все операторы во всех процедурах, определенных между ними.
  6. literal-1 должен быть числовой константой или ссылкой на функцию, возвращающую числовое значение. Значение должно быть целым числом, большим нуля.
  7. identifier-1 должен быть элементарным неотредактированным числовым элементом данных со значением целого числа, большим нуля.
  8. Без UNTIL, UNTIL EXIT, TIMES, VARYING-Clause (см. VARYING) или FOREVER операторов код внутри области действия perform будет выполнен один раз, после чего управление вернется к оператору, следующему за PERFORM.
  9. Опция FOREVER будет многократно выполнять код внутри области действия perform без определения условий для прекращения повторения — программисту необходимо включить оператор EXIT SECTION (см. EXIT) или оператор EXIT PARAGRAPH внутри выполняемой процедуры(ей), которые прервут цикл.
  10. Опция TIMES повторит выполнение кода внутри области действия perform определенное количество раз. Когда оператор PERFORM начинает выполнение, внутренний счётчик повторений (недоступный для программиста) устанавливается в значение literal-1 или значения из identifier-1.

    Если счётчик имеет значение больше нуля, операторы внутри PERFORM области будут выполнены, после чего счётчик будет уменьшен на 1 на каждом повторении. Как только счётчик достигнет нуля, повторение прекратится, и управление перейдёт к следующему оператору после PERFORM.

    Если была использована опция identifier-1, изменение значения этого элемента данных внутри области действия perform не повлияет на счётчик повторений.

  11. Опция UNTIL conditional-expression-1 будет повторять код внутри области действия perform до тех пор, пока указанное условное выражение не примет значение TRUE.
  12. Необязательная WITH TEST часть будет управлять тем, происходит ли UNTIL проверка BEFORE операторов в области действия perform на каждой итерации (создавая возможность — если conditional-expression-1 изначально TRUE — что операторы в области действия perform никогда не будут выполнены) или AFTER (гарантируя, что операторы в области действия perform будут выполнены как минимум один раз).

    По умолчанию, если эта часть отсутствует, то WITH TEST BEFORE.

    Эта часть не может быть использована при использовании TIMES части.

  13. Необязательная VARYING-Clause — это механизм, который создаёт расширенный механизм управления циклом, включающий в себя автоматическое инкрементирование (или декрементирование) одного или нескольких числовых элементов данных на каждой итерации цикла, а также управление завершением цикла с помощью UNTIL части. См. VARYING для деталей.

7.8.29.2. Встроенный PERFORM

Синтаксис встроенного PERFORM

   PERFORM
   ~~~~~~~
    [ { [ WITH TEST { BEFORE } ] { VARYING-Clause                 } } ]
      {        ~~~~ { ~~~~~~ }   { UNTIL conditional-expression-1 } }
      {             { AFTER  }     ~~~~~                            }
      {               ~~~~~                                         }
      { UNTIL EXIT|FOREVER                                          }
      { ~~~~~ ~~~~ ~~~~~~~                                          }
      { { literal-1    } TIMES                                      }
      { { identifier-1 } ~~~~~                                      }

      imperative-statement-1

 [ END-PERFORM ]
   ~~~~~~~~~~~

Этот формат оператора PERFORM идентичен по действию процедурному оператору PERFORM, за исключением того, что операторы, составляющие область действия perform (imperative-statement-1) (см. Операторы), теперь указаны встроенными в PERFORM код, а не в процедурах, расположенных в других местах программы.

7.8.29.3. VARYING

Синтаксис VARYING

 VARYING identifier-2 FROM { literal-2    } [ BY { literal-3    } ]
 ~~~~~~~              ~~~~ { identifier-3 }   ~~ { identifier-4 }
         [ UNTIL conditional-expression-1 ]
           ~~~~~
 [ AFTER identifier-5 FROM { literal-4    } [ BY { literal-5    } ]
   ~~~~~              ~~~~ { identifier-6 }   ~~ { identifier-7 }
         [ UNTIL conditional-expression-2 ] ]...
           ~~~~~

Часть VARYING, доступная в обоих форматах оператора PERFORM, является механизмом цикла, который позволяет указать один или несколько числовых элементов данных, которые будут инициализированы программистом и автоматически инкрементированы другим заданным программистом значением после каждой итерации цикла.

  1. Все идентификаторы, используемые в VARYING-Clause, должны быть элементарными, необработанными числовыми данными. Все литералы должны быть числовыми литералами.
  2. Следующие пункты описывают последовательность событий, происходящих в результате части VARYING предложения:
    1. Когда PERFORM начинает выполнение, значение FROM будет перемещено в identifier.
    2. Если PERFORM указывает или подразумевает WITH TEST BEFORE, conditional-expression-1 будет вычислена, и обработка PERFORM прекратится, если выражение вычислится в TRUE. Если WITH TEST BEFORE не было указано или подразумевалось, или если условное выражение вычислилось в FALSE, обработка продолжается с шагом C.
    3. Выполнятся инструкции в области perform. Если инструкция GO TO в области perform передаёт управление в точку за пределами области perform, обработка PERFORM прекратится.
    4. Когда инструкции в области perform завершают итерацию цикла, одним из способов:
      • позволяя потоку выполнения перейти за последнюю инструкцию в области perform
      • выполнив инструкцию EXIT PERFORM CYCLE (см. EXIT)
      • выполнив инструкцию EXIT PARAGRAPH или инструкцию EXIT SECTION при наличии только одного абзаца (или раздела) в области perform (этот вариант применим только к процедурному PERFORM)

      Если WITH TEST AFTER было указано, управление вернётся в PERFORM, где conditional-expression-1 будет вычислена, и обработка PERFORM прекратится, если выражение вычислится в TRUE. Если WITH TEST AFTER не было указано или если условное выражение вычислилось в FALSE, обработка продолжается со следующей ступени.

    5. Значение BY, если таковое имеется, будет добавлено к identifier-2. Если BY не указано, оно будет считаться эквивалентным BY 1.
    6. Возврат к шагу C.
  3. У большинства VARYING-Clause нет указанного AFTER. Те, у которых он есть, устанавливают ситуацию цикла в цикле, где процесс, описанный выше в шагах (‘A’) до (‘F’), будет выполняться начиная с AFTER, и эти шесть шагов обработки фактически заменяют шаг C в VARYING. Этот процесс «вложения» может продолжаться неограниченно, с каждым дополнительным AFTER.

Пример действительно поможет вам увидеть это в действии. Рассмотрите следующий код, определяющий двумерную таблицу (3 строки по 4 столбца) и пару числовых данных, которые будут использоваться для индексации ссылок на каждый элемент таблицы:

01  PERFORM-DEMO.
    05 PD-ROW             OCCURS 3 TIMES.
       10 PD-COL          OCCURS 4 TIMES
          15 PD           PIC X(1).
01  PD-Col-No             PIC 9 COMP.
01  PD-Row-No             PIC 9 COMP.

Предположим, что у 3x4 «сетки», определённой выше, такие значения:

A B C D
E F G H
I J K L

Этот код отобразит ABCDEFGHIJKL на окне консольного вывода:

PERFORM WITH TEST AFTER
        VARYING PD-Row-No FROM 1 BY 1 UNTIL PD-Row-No = 3
          AFTER PD-Col-No FROM 1 BY 1 UNTIL PD-Col-No = 4
    DISPLAY PD (PD-Row-No, PD-Col-No) WITH NO ADVANCING
END-PERFORM

В то время как этот код отобразит AEIBFJCGKDHL на окне консольного вывода:

PERFORM WITH TEST AFTER
        VARYING PD-Col-No FROM 1 BY 1 UNTIL PD-Col-No = 4
          AFTER PD-Row-No FROM 1 BY 1 UNTIL PD-Row-No = 3
    DISPLAY PD (PD-Row-No, PD-Col-No) WITH NO ADVANCING
END-PERFORM

Пока мы рассматриваем пример кода, этот код отображает ABCEFG:

PERFORM
        VARYING PD-Row-No FROM 1 BY 1 UNTIL PD-Row-No = 3
          AFTER PD-Col-No FROM 1 BY 1 UNTIL PD-Col-No = 4
    DISPLAY PD (PD-Row-No, PD-Col-No) WITH NO ADVANCING
END-PERFORM

Убирая WITH TEST предложение, инструкция теперь предполагает WITH TEST BEFORE. Так как проверка теперь происходит *до* того, как выполняется инструкция DISPLAY, когда PD-Row-No равно 3, а PD-Col-No равно 4, инструкция DISPLAY не будет выполнена.

Большинство программистов COBOL, при использовании WITH TEST BEFORE явно или неявно, выработали привычку использовать ‘>’ вместо ‘=’ в UNTIL предложениях. Это привело бы к следующему примеру кода:

PERFORM
        VARYING PD-Row-No FROM 1 BY 1 UNTIL PD-Row-No > 3
          AFTER PD-Col-No FROM 1 BY 1 UNTIL PD-Col-No > 4
    DISPLAY PD (PD-Row-No, PD-Col-No) WITH NO ADVANCING
END-PERFORM

С этим изменением ABCDEFGHIJKL снова отобразится.

7.8.30. Чтение

7.8.30.1. Последовательное чтение

Синтаксис последовательного чтения

   READ file-name-1 [ { NEXT|PREVIOUS } ] RECORD [ INTO identifier-1 ]
   ~~~~               { ~~~~ ~~~~~~~~ }            ~~~~
    [ { IGNORING LOCK    } ]
      { ~~~~~~~~ ~~~~    }
      { WITH [ NO ] LOCK }
      {        ~~   ~~~~ }
      { WITH KEPT LOCK   }
      {      ~~~~ ~~~~   }
      { WITH IGNORE LOCK }
      {      ~~~~~~ ~~~~ }
      { WITH WAIT        }
             ~~~~
    [ AT END imperative-statement-1 ]
         ~~~
    [ NOT AT END imperative-statement-2 ]
      ~~~    ~~~
 [ END-READ ]
   ~~~~~~~~

Этот вариант инструкции READ извлекает следующий (или предыдущий) запис из файла.

  1. Зарезервированные слова AT, RECORD и WITH являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Файл file-name-1 обязательно должен быть определен с помощью FD (см. File/Sort-Description), а не SD.
  3. Файл file-name-1 должен быть в настоящее время открыт для INPUT (см. Режимы открытия файлов) или I-O.
  4. Если file-name-1 является файлом типа ORGANIZATION RELATIVE (см. ORGANIZATION RELATIVE) или ORGANIZATION INDEXED (см. ORGANIZATION INDEXED) с ACCESS MODE RANDOM, данное оператор нельзя использовать.
  5. Если file-name-1 был задан как ACCESS MODE SEQUENTIAL, это единственный доступный формат оператора READ.
  6. Если file-name-1 является файлом типа ORGANIZATION RELATIVE (см. ORGANIZATION RELATIVE) или ORGANIZATION INDEXED (см. ORGANIZATION INDEXED) с ACCESS MODE DYNAMIC, этот оператор, а также случайный READ (см. Случайное чтение) могут быть использованы.
  7. Ключевые слова NEXT и PREVIOUS указывают, в каком «направлении» будет происходить чтение файла. Если ни одно не указано, предполагается NEXT.
  8. Опция PREVIOUS доступна только для файлов ORGANIZATION INDEXED.
  9. При чтении последовательного (любого типа организации) или относительного файла «следующее» направление соответствует физической последовательности записей в файле. При чтении индексированного файла «следующее» и «предыдущее» направления относятся к последовательности значений первичного или альтернативного ключа записи в записях файла, независимо от физического расположения записей в файле.
  10. Минимальный оператор READ file-name-1 является законным в обоих форматах чтения. По этой причине, когда ACCESS MODE DYNAMIC задано, и вы хотите указать компилятору GnuCOBOL, что этот минимальный оператор должен обрабатываться как последовательный READ, необходимо добавить либо NEXT, либо PREVIOUS в оператор (в противном случае он будет обработан как случайный READ).
  11. Успешное последовательное чтение извлечёт следующую доступную запись из file-name-1, в направлении «следующая» или «предыдущая» от последней прочитанной записи, в зависимости от использования опции NEXT или PREVIOUS. Данные извлечённой записи будут сохранены в структуру(ы) записи уровня 01, которая/ые непосредственно следуют за FD файла. Если присутствует необязательная фраза INTO, копия только что извлечённой записи будет автоматически перемещена в identifier-1.
  12. После успешного чтения файла типа ORGANIZATION RELATIVE, поле RELATIVE KEY (см. ORGANIZATION RELATIVE) файла будет автоматически заполнено относительным номером записи (порядковый номер) записи в файле.
  13. Необязательные опции LOCK могут быть использованы для ручного управления доступом к извлечённой записи другими программами во время работы данной программы. См. Блокировка записей, чтобы ознакомиться с различными поведением блокировки записей.
  14. Необязательная фраза AT END, если она задана, используется для обнаружения и реакции на ошибку попытки извлечения другой записи из файла из-за условия конца файла (т. е. больше нет записей).
  15. Необязательная фраза NOT AT END, если она задана, будет проверять значение статуса файла на 00. См. Коды состояния файла для дополнительной информации.

7.8.30.2. Случайное чтение

Синтаксис случайного чтения

   READ file-name-1 RECORD [ INTO identifier-1 ]
   ~~~~                      ~~~~
    [ { IGNORING LOCK    } ]
      { ~~~~~~~~ ~~~~    }
      { WITH [ NO ] LOCK }
      {        ~~   ~~~~ }
      { WITH KEPT LOCK   }
      {      ~~~~ ~~~~   }
      { WITH IGNORE LOCK }
      {      ~~~~~~ ~~~~ }
      { WITH WAIT        }
             ~~~~
    [ KEY IS identifier-2 ]
      ~~~
    [ INVALID KEY imperative-statement-1 ]
      ~~~~~~~
    [ NOT INVALID KEY imperative-statement-2 ]
      ~~~ ~~~~~~~
 [ END-READ ]
   ~~~~~~~~

Этот вид оператора READ извлекает произвольную запись из файла типа ORGANIZATION RELATIVE (см. ORGANIZATION RELATIVE) или ORGANIZATION INDEXED (см. ORGANIZATION INDEXED).

  1. Зарезервированные слова IS, KEY (в пунктах INVALID и NOT INVALID), RECORD и WITH являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Файл file-name-1 обязательно должен быть определен через FD (см. File/Sort-Description), а не через SD.
  3. Файл file-name-1 в данный момент должен быть открыт для INPUT (см. Режимы открытия файла) или I-O.
  4. Если ACCESS MODE файла file-name-1 имеет значение SEQUENTIAL, или ORGANIZATION файла имеет последовательный формат, этот формат оператора READ использовать нельзя.
  5. Если ACCESS MODE файла file-name-1 имеет значение RANDOM, это единственный доступный формат оператора READ.
  6. Если file-name-1 является файлом типа ORGANIZATION RELATIVE (см. ORGANIZATION RELATIVE) или ORGANIZATION INDEXED (см. ORGANIZATION INDEXED) с ACCESS MODE DYNAMIC, можно использовать этот оператор, а также последовательное READ (см. Последовательное чтение).
  7. Минимальный оператор READ file-name-1 является допустимым в обоих форматах чтения. По этой причине, когда ACCESS MODE DYNAMIC указан, и вы хотите сообщить компилятору GnuCOBOL, что этот минимальный оператор должен обрабатываться как случайный оператор READ, необходимо опустить NEXT или PREVIOUS, доступные в последовательном формате оператора READ, чтобы убедиться, что оператор будет обработан как случайный READ.
  8. Необязательный пункт KEY указывает компилятору, как следует искать запись в файле.

    Если пункт KEY отсутствует, и файл является

    ORGANIZATION RELATIVE

    содержимое поля, объявленного как RELATIVE KEY файла, будет использоваться для идентификации записи

    ORGANIZATION INDEXED

    содержимое поля, объявленного как RECORD KEY файла, будет использоваться для идентификации записи.

    Если пункт KEY указан, и файл является

    ORGANIZATION RELATIVE

    содержимое identifier-2 будет использоваться в качестве относительного номера записи для доступа. identifier-2 не обязательно должно быть полем RELATIVE KEY (см. ORGANIZATION RELATIVE) файла (хотя это может быть так, если нужно).

    ORGANIZATION INDEXED

    identifier-2 обязательно должно быть полем RECORD KEY (см. ORGANIZATION INDEXED) или одним из полей ALTERNATE RECORD KEY файла (если таковые имеются). Текущее содержимое этого поля будет идентифицировать доступную запись. Если используется альтернативный ключ записи, и этот ключ допускает дублирование значений, то доступной записью будет первая запись, имеющая это значение ключа.

  9. После считывания из файла данные новой записи будут сохранены в структуре записи уровня 01, которая непосредственно следует за FD файла. Если присутствует необязательный пункт INTO, копия только что прочитанной записи будет автоматически перемещена в identifier-1.
  10. Когда файл типа ORGANIZATION RELATIVE успешно прочитан, поле RELATIVE KEY (см. ORGANIZATION RELATIVE) файла автоматически заполняется относительным номером записи (порядковым номером) записи в файле.
  11. Необязательные опции LOCK могут быть использованы для ручного управления доступом к прочитанной записи другими программами во время выполнения этой программы. См. Блокировка записей для ознакомления с различными режимами блокировки записей.
  12. Необязательные пункты INVALID KEY и NOT INVALID KEY могут использоваться для обнаружения и реагирования соответственно на ошибку или успех, обнаруживая ненулевые (как правило, 23 = ключ не найден = запись не найдена) и 00 коды статуса файла соответственно. См. Коды статуса файла для получения дополнительной информации.

7.8.31. Отслеживание READY

Синтаксис READY TRACE

 READY TRACE
 ~~~~~ ~~~~~

Оператор READY TRACE включает отслеживание процедур или процедур и операторов.

  1. Для функционирования этого оператора необходимо, чтобы код отслеживания был сгенерирован в скомпилированной программе с использованием переключателя -ftrace (только процедуры) или -ftraceall (процедуры и операторы).
  2. Отслеживание может быть выключено в любой момент выполнением оператора RESET TRACE (см. RESET TRACE).
  3. Переменная среды выполнения COB_SET_TRACE (см. Переменные среды выполнения) предоставляет еще один способ управления отслеживанием. Если эта переменная среды установлена в значение ‘Y’ перед началом выполнения программы, отслеживание начинается с момента запуска программы, как если бы READY TRACE был первым выполненным оператором.

7.8.32. RELEASE

Синтаксис RELEASE

 RELEASE record-name-1 [ FROM { literal-1    } ]
 ~~~~~~~                 ~~~~ { identifier-1 }

Оператор RELEASE добавляет новую запись в файл сортировки.

  1. Это утверждение допустимо только внутри INPUT PROCEDURE файла SORT (см. Файловый СОРТИРОВКА).
  2. Указанное record-name-1 должно быть записываю определенной в описании сортировки (SD (см. Описание файла/Сортировки)) файла сортировки, который обрабатывается текущей сортировкой.
  3. Необязательная FROM часть заставит literal-1 или identifier-1 автоматически переместиться в record-name-1 перед записью содержимого record-name-1 в file-name-1. Если этот пункт не указан, программист несет ответственность за заполнение record-name-1 желаемыми данными перед выполнением RELEASE.

7.8.33. СБРОС ТРЕКИНГА

Синтаксис СБРОС ТРЕКИНГА

 RESET TRACE
 ~~~~~ ~~~~~

Утверждение RESET TRACE отключает отслеживание процедур или процедур и инструкций.

  1. По умолчанию отслеживание процедур и процедур-инструкций отключено при запуске программы. Утверждение READY TRACE (см. ВКЛЮЧИТЬ ТРЕКИНГ) может использоваться для включения отслеживания.
  2. Для правильной работы этого утверждения код отслеживания должен быть сгенерирован в скомпилированную программу с помощью переключателя -ftrace (только процедуры) или -ftraceall (процедуры и инструкции).
  3. Переменная среды выполнения COB_SET_TRACE (см. Переменные среды выполнения) предоставляет другой способ управления отслеживанием. Если эта переменная среды установлена в значение 'Y' перед запуском программы, отслеживание запускается в момент запуска программы, как если бы READY TRACE была первой выполненной инструкцией. Утверждение RESET TRACE, если выполняется, отключит отслеживание.

7.8.34. RETURN

Синтаксис RETURN

   RETURN sort-file-name-1 RECORD
   ~~~~~~
    [ INTO identifier-1 ]
      ~~~~
      AT END imperative-statement-1
         ~~~
    [ NOT AT END imperative-statement-2 ]
      ~~~    ~~~
 [ END-RETURN ]
   ~~~~~~~~~~

Утверждение RETURN считывает запись из файла работы сортировки или слияния.

  1. Зарезервированные слова AT и RECORD являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Утверждение RETURN допустимо только внутри OUTPUT PROCEDURE файла SORT (см. Файловый СОРТИРОВКА) или инструкции MERGE (см. СЛИЯНИЕ).
  3. Файл sort-file-name-1 должен быть файлом работы сортировки или слияния, определенным с помощью SD (см. Описание файла/Сортировки), а не FD.
  4. Успешное выполнение RETURN извлечет следующую доступную запись из sort-file-name-1. Данные новой извлеченной записи будут сохранены в структуру(ы) записи уровня 01, непосредственно следующих за SD файла. Если необязательная INTO часть присутствует, копия только что извлеченной записи будет автоматически перемещена в identifier-1.
  5. Обязательная AT END часть используется для обнаружения и реакции на неудачную попытку извлечения другой записи из файла из-за состояния конца файла (т. е. больше нет записей).
  6. Необязательная NOT AT END часть, если используется, будет проверять наличие значения статуса файла 00. Дополнительную информацию см. в разделе Коды статуса файла.

7.8.35. ПЕРЕЗАПИСЬ

Синтаксис ПЕРЕЗАПИСЬ

   REWRITE record-name-1
   ~~~~~~~
      [ FROM { literal-1    } ]
        ~~~~ { identifier-1 }

      [ WITH [ NO ] LOCK ]
               ~~   ~~~~
      [ INVALID KEY imperative-statement-1 ]
        ~~~~~~~
      [ NOT INVALID KEY imperative-statement-2 ]
        ~~~ ~~~~~~~
 [ END-REWRITE ]
   ~~~~~~~~~~~

Утверждение REWRITE заменяет логическую запись в файле на диске.

  1. Зарезервированные слова KEY и WITH являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. record-name-1, указанный в операторе, должен быть определен как запись уровня 01, подчиненная описанию файла (FD (см. Описание файла/сортировки)) файла, который в данный момент открыт для I-O (см. Режимы открытия файла).
  3. Необязательная FROM-клауза заставит literal-1 или identifier-1 автоматически переместиться в record-name-1 перед записью содержимого record-name-1 в file-name-1. Если эта клауза не указана, программисту необходимо заполнить record-name-1 желаемыми данными перед выполнением REWRITE.
  4. Этот оператор не может использоваться с файлами ORGANIZATION LINE SEQUENTIAL (см. Последовательные файлы организации строк).
  5. Перезапись записи не приводит к физическому обновлению содержимого файла до тех пор, пока не будет прочитан следующий блок файла, не будет выпущен оператор COMMIT (см. COMMIT) или UNLOCK (см. UNLOCK), или пока файл не будет закрыт.
  6. Если файл имеет ORGANIZATION SEQUENTIAL (см. Последовательная организация):
    1. Запись, подлежащая перезаписи, будет той, которая была получена последним выполненным оператором READ (см. READ) файла.
    2. Если FD файла содержит клаузу RECORD CONTAINS или RECORD IS VARYING, и эта клауза допускает изменение размера записи, размер record-name-1 изменить нельзя.
  7. Если файл имеет ORGANIZATION RELATIVE (см. Организация относительная) или ORGANIZATION INDEXED (см. Индексированная организация):
    1. Если файл имеет ACCESS MODE SEQUENTIAL, запись, подлежащая перезаписи, будет той, которая была получена последним выполненным оператором READ файла. Если файл имеет ACCESS MODE RANDOM или ACCESS MODE DYNAMIC, перед перезаписью записи READ не требуется — определение RELATIVE KEY или RECORD KEY для файла, соответственно, укажет запись, подлежащую обновлению.
    2. Если FD файла содержит клаузу RECORD CONTAINS или RECORD IS VARYING, и эта клауза допускает изменение размера записи, размер можно изменить.
  8. Необязательные LOCK параметры могут использоваться для ручного управления доступом к перезаписанной записи другими программами во время работы этой программы. См. Блокировка записей, чтобы ознакомиться с различными способами блокировки записей.
  9. Необязательные INVALID KEY и NOT INVALID KEY клаузы могут использоваться для обнаружения и реакции на ошибку или успех, соответственно, обнаруживая ненулевые (обычно 23 = ключ не найден = запись не найдена) и 00 кодов состояния файла, соответственно. Дополнительную информацию см. в разделе Коды состояния файла.

7.8.36. ROLLBACK

Синтаксис ROLLBACK

 ROLLBACK
 ~~~~~~~~

Оператор ROLLBACK имеет тот же эффект, что и оператор UNLOCK (см. UNLOCK) для каждого открытого файла в программе.

  1. Все блокировки, в настоящее время удерживаемые для всех открытых файлов, будут освобождены.
  2. См. Блокировка записей, чтобы ознакомиться с различными способами блокировки записей.

7.8.37. SEARCH

Синтаксис SEARCH

   SEARCH table-name-1
   ~~~~~~
      [ VARYING index-name-1 ]
        ~~~~~~~
      [ AT END imperative-statement-1 ]
           ~~~
      { WHEN conditional-expression-1 imperative-statement-2 }...
        ~~~~
 [ END-SEARCH ]
   ~~~~~~~~~~

Оператор SEARCH используется для последовательного поиска в таблице, останавливаясь либо после обнаружения определенного значения в таблице, либо после полного поиска таблицы.

  1. Зарезервированное слово AT является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Процесс поиска будет управляться с помощью Индекса поиска — элемента данных с USAGE (см. ИСПОЛЬЗОВАНИЕ) INDEX. Индекс поиска — это идентификатор index-name-1, указанный в VARYING или, если VARYING не указан, элемент данных USAGE INDEX, неявно созданный INDEXED BY (см. OCCURS) в определении таблицы.
  3. В момент выполнения оператора SEARCH текущее значение элемента данных индекса поиска определит начальную позицию в таблице, с которой начнется процесс поиска. Обычно индекс инициализируется значением 1 перед запуском SEARCH с помощью SET search-index TO 1.
  4. Каждый из conditional-expression-n в WHEN должен использовать элемент данных внутри таблицы, индексированный с помощью индекса поиска.
  5. Процесс поиска осуществляется следующим образом:
    1. Каждый conditional-expression-n будет оцениваться по очереди до тех пор, пока не будет получено значение TRUE или все будут оценены как FALSE.
    2. Оператор imperative-statement-n (см. Оператор-команда), указанный в WHEN, условное выражение conditional-expression-n которого получило значение TRUE, будет выполнен; после этого поиск считается завершенным, и управление переходит к первой исполняемой инструкции после SEARCH.
    3. Если все conditional-expression-n получили значение FALSE:
      • Индекс поиска увеличивается на 1
      • Если индекс поиска теперь больше, чем количество записей в таблице, поиск считается неудачным, и выполняется оператор imperative-statement-1 в необязательной AT END строке, если она есть. После этого управление переходит к первой исполняемой строке после SEARCH.
      • Если индекс поиска теперь меньше или равен количеству записей в таблице, процесс поиска возвращается к шагу A.

7.8.38. ПОИСК ВСЕХ

Синтаксис ПОИСКА ВСЕХ

   SEARCH ALL table-name-1
   ~~~~~~ ~~~
      [ AT END imperative-statement-1 ]
           ~~~
        WHEN conditional-expression-1 imperative-statement-2
        ~~~~
 [ END-SEARCH ]
   ~~~~~~~~~~

Оператор SEARCH ALL выполняет двоичный, или полуинтервальный, поиск в отсортированной таблице. Это, как правило, значительно быстрее, чем последовательный SEARCH таблицы, особенно если таблица содержит большое количество записей.

  1. Зарезервированное слово AT является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Чтобы быть подходящим для поиска через SEARCH ALL:
    1. Оператор OCCURS таблицы table-name-1 должен содержать следующие элементы:
      • Элемент INDEXED BY для определения неявного индекса поиска данных с USAGE (см. USAGE) INDEX.
      • Оператор ASCENDING KEY или DESCENDING KEY для указания поля в таблице, по которому сортируются все записи в таблице.
    2. Просто потому, что таблица имеет один или несколько операторов KEY, не означает, что данные фактически расположены в этой последовательности в таблице — фактическая последовательность данных должна совпадать с операторами KEY! Табличный оператор SORT (см. Table SORT) может быть очень полезным в этом отношении.
    3. Ни две записи в таблице не могут иметь одинаковые значения поля KEY. Если таблица имеет несколько определений KEY, то ни две записи в таблице не могут иметь одинаковую комбинацию значений поля KEY.
  3. Если правило A нарушено, компилятор отклонит SEARCH ALL. Если нарушены правила B и/или C, компилятор не выведет сообщение, но результаты выполнения SEARCH ALL по отношению к таблице, вероятно, будут некорректными.
  4. conditional-expression-1 должен включать поле(а) KEY, используя индекс поиска (имя индекса таблицы INDEXED BY) в качестве индекса.
  5. Функция единственного обязательного оператора WHEN заключается в сравнении поля(ей) ключа таблицы, индексируемых данными индекса поиска, с любыми значениями литералов и/или идентификаторов, с которыми вы сравниваете поля ключа в conditional-expression-1, чтобы найти нужную запись в таблице. Индекс поиска будет автоматически изменён таким образом, чтобы потребовать минимального количества проверок.
  6. Внутренняя обработка оператора SEARCH ALL начинается с задания внутренних указателей «первый» и «последний» на 1-ю и последнюю записи в таблице. Затем обработка выполняется следующим образом:
    1. Определяется запись, находящаяся посередине между «первым» и «последним». Мы будем называть её «текущей» записью и установить её местоположение в таблице в index-name-1.
    2. Вычисляется conditional-expression-1. Это сравнение ключа(ей) со значениями литералов/идентификаторов может иметь один из трёх возможных исходов:
      • Если ключ(и) и значения совпадают, выполняется imperative-statement-2 (см. Imperative Statement), после чего управление переходит к следующему оператору после SEARCH ALL.
      • Если ключ(и) меньше значений, то запись, которую мы ищем, может находиться только в диапазоне от «текущей» до «последней» записи в таблице, поэтому новое значение указателя «первый» устанавливается (оно будет равно указателю «текущий»).
      • Если ключ(и) больше значений, то запись, которую мы ищем, может находиться только в диапазоне от «первого» до «текущего» в таблице, поэтому устанавливается новое значение указателя «последний» (оно будет равно указателю «текущий»).
    3. Если новые указатели «первый» и «последний» отличаются от старых указателей «первый» и «последний», есть ещё что искать, поэтому вернитесь к пункту A и продолжайте.
    4. Если новые указатели «первый» и «последний» такие же, как старые указатели «первый» и «последний», таблица исчерпана, и искомая запись не найдена; выполняется imperative-statement-1, после чего управление переходит к следующему оператору после SEARCH ALL. Если оператора AT END нет, управление просто переходит к следующему оператору после SEARCH ALL.
  7. Чистый эффект вышеупомянутого алгоритма заключается в том, что для определения наличия или отсутствия конкретной записи нужно проверить лишь часть элементов в таблице. Это происходит потому, что каждый раз, когда проверяется запись, половина оставшихся записей отбрасывается.
  8. Компьютерные специалисты сравнят два метода, реализованные операторами SEARCH и SEARCH ALL следующим образом:
  9. При поиске в таблице с N записями последовательный поиск потребует в среднем N/2 проверок и в худшем случае N проверок для поиска записи и N проверок для определения отсутствия записи.
  10. При поиске в таблице с N записями бинарный поиск потребует в худшем случае log2(N) проверок для поиска записи и log2(N) проверок для определения отсутствия записи (N = число записей в таблице), где log2 — функция логарифма по основанию 2.

Вот более практичный взгляд на разницу. Предположим, что таблица содержит 1000 записей. При последовательном поиске в среднем вам придётся проверить 500 записей, чтобы найти запись, и все 1000, чтобы убедиться, что её нет.

При бинарном поиске представьте число записей в двоичном виде (1000 = 1111101000), посчитайте количество цифр в результате (это, по сути, то, что такое логарифм, когда он округляется до ближайшего целого числа — количество цифр, которые имела бы десятичная запись, если бы она была выражена в основании логарифма). В этом случае мы получаем 10 — это максимальное количество проверок, необходимое для поиска записи или определения её отсутствия. Это значительное улучшение!

7.8.39. SET

7.8.39.1. СРЕДА SET

Синтаксис SET ENVIRONMENT

 SET ENVIRONMENT { literal-1    } TO { literal-2    }
 ~~~ ~~~~~~~~~~~ { identifier-1 } ~~ { identifier-2 }

Оператор SET ENVIRONMENT предоставляет простой способ установки значений среды из программы.

  1. Значение literal-1 или identifier-1 указывает имя переменной среды, которую нужно установить.
  2. Значение literal-2 или identifier-2 указывает значение, которое нужно назначить переменной среды.
  3. Переменные среды, созданные или изменённые внутри программ GnuCOBOL, будут доступны любым дочерним процессам оболочки, запущенным этой программой (например, CALL "SYSTEM") но не будут известны оболочке или консольному окну, которые запустили программу GnuCOBOL.

Это намного проще и понятнее, чем использование оператора DISPLAY UPON ENVIRONMENT-NAME (см. DISPLAY UPON ENVIRONMENT-NAME). Например, эти два фрагмента кода дают одинаковый результат:

DISPLAY "VARNAME" UPON ENVIRONMENT-NAME
DISPLAY "VALUE" UPON ENVIRONMENT-VALUE

SET ENVIRONMENT "VARNAME" TO "VALUE"

7.8.39.2. Установка указателя программы

Синтаксис SET Program-Pointer

 SET program-pointer-1 TO ENTRY { literal-1    }
 ~~~                   ~~ ~~~~~ { identifier-1 }

Оператор SET Program-Pointer позволяет получить адрес модуля кода раздела процедур — конкретно PROGRAM-ID, FUNCTION-ID или точку входа, установленную с помощью оператора ENTRY (см. ENTRY).

  1. Тип USAGE (см. USAGE) program-pointer-1 должен быть PROGRAM-POINTER.
  2. Указанное значение literal-1 или identifier-1 должно называть имя первичной точки входа (PROGRAM-ID подпрограммы или FUNCTION-ID пользовательской функции) или альтернативной точки входа, определённой с помощью оператора ENTRY внутри подпрограммы.
  3. После получения адреса области кода раздела процедур таким способом, адрес можно передать подпрограмме (обычно написанной на C) для использования по назначению. Примеры работы с PROGRAM-POINTER см. в обсуждениях встроенной системной подпрограммы CBL_ERROR_PROC (см. CBL_ERROR_PROC) и встроенной системной подпрограммы CBL_EXIT_PROC (см. CBL_EXIT_PROC).

7.8.39.3. SET ADDRESS

Синтаксис SET ADDRESS

 SET [ ADDRESS OF ] { pointer-name-1 }...
 ~~~   ~~~~~~~ ~~   { identifier-1   }

     TO [ ADDRESS OF ]  { pointer-name-2 }
     ~~   ~~~~~~~ ~~    { identifier-2   }

Оператор SET ADDRESS может использоваться для работы с адресами элементов данных, а не с их содержимым.

  1. При использовании фрагмента ADDRESS OF перед TO, этот оператор используется для изменения адреса раздела связи или BASED (см. BASED) элемента данных. Без этого фрагмента вы будете назначать адрес одному или нескольким элементам данных, тип USAGE (см. USAGE) которых POINTER.
  2. При использовании фрагмента ADDRESS OF после TO, этот оператор определит адрес identifier-2 как адрес, который нужно назначить identifier-1 или сохранить в pointer-name-1.
  3. Если фрагмент ADDRESS OF отсутствует после TO, содержимое pointer-name-2 будет служить адресом для назначения.

7.8.39.4. Установка индекса

Синтаксис SET Index

 SET index-name-1 TO { literal-1    }
 ~~~              ~~ { identifier-2 }

Этот оператор присваивает значение элементу данных типа USAGE INDEX.

  1. Либо тип USAGE (см. USAGE) index-name-1 должен быть INDEX, либо index-name-1 должен быть идентифицирован в фрагменте таблицы INDEXED BY.

7.8.39.5. SET UP/DOWN

Синтаксис SET UP/DOWN

 SET identifier-1 { UP   } BY [ LENGTH OF ] { literal-1    }
 ~~~              { ~~   } ~~   ~~~~~~ ~~   { identifier-2 }
                  { DOWN }
                    ~~~~

Используйте этот оператор для инкремента или декремента значения индекса или указателя на заданную величину.

  1. Тип USAGE (см. USAGE) identifier-1 должен быть INDEX, POINTER или PROGRAM-POINTER.
  2. Типичное использование, когда identifier-1 — элемент данных типа USAGE INDEX, — это увеличение его значения UP или DOWN на 1, так как индекс обычно используется для последовательного просмотра элементов таблицы.

7.8.39.6. Установка имени условия

Синтаксис SET Condition Name

 SET condition-name-1... TO { TRUE  }
 ~~~                     ~~ { ~~~~  }
                            { FALSE }
                              ~~~~~

Оператор SET Condition Name предоставляет способ задания значения TRUE / FALSE имени условия уровня-88.

  1. Установив указанные condition-name-1(ы) в значение TRUE или FALSE, вы фактически присваиваете значение родительским элементам данных, которым подчинены элементы данных имени условия.
  2. При указании TRUE, значение, присвоенное каждому родительскому элементу данных, будет первым значением, указанным в фрагменте имени условия VALUE.
  3. При указании FALSE, значение, присвоенное каждому родительскому элементу данных, будет значением, указанным в фрагменте FALSE определения имени условия; если у любой condition-name-1 отсутствует фрагмент FALSE, оператор SET будет отклонен компилятором.

7.8.39.7. Установка переключателя

Синтаксис переключения SET

 SET mnemonic-name-1... TO { ON  }
 ~~~                    ~~ { ~~  }
                           { OFF }
                             ~~~

Этот вид оператора SET используется для включения или выключения переключателей.

  1. Переключатели определяются с помощью оператора SPECIAL-NAMES (см. раздел SPECIAL-NAMES).
  2. Переключатели можно проверить с помощью оператора IF (см. IF) и условия состояния переключателя. Дополнительную информацию см. в разделе Условия состояния переключателя.

7.8.39.8. УСТАНОВКА АТРИБУТА

Синтаксис УСТАНОВКИ АТРИБУТА

 SET identifier-1 ATTRIBUTE { { BELL          } { ON  }...
 ~~~              ~~~~~~~~~   { ~~~~          } { ~~  }
                              { BLINK         } { OFF }
                              { ~~~~~         }   ~~~
                              { HIGHLIGHT     }
                              { ~~~~~~~~~     }
                              { LEFTLINE      }
                              { ~~~~~~~~      }
                              { LOWLIGHT      }
                              { ~~~~~~~~      }
                              { OVERLINE      }
                              { ~~~~~~~~      }
                              { REVERSE-VIDEO }
                              { ~~~~~~~~~~~~~ }
                              { UNDERLINE     }
                                ~~~~~~~~~

Оператор SET ATTRIBUTE может использоваться для изменения одного или нескольких атрибутов элемента данных раздела экрана во время выполнения.

  1. При изменении атрибута identifier-1, изменение не отобразится на экране до тех пор, пока элемент данных раздела экрана, содержащий identifier-1, не будет принят (если identifier-1 — поле ввода) или не будет отображен (если identifier-1 — не поле ввода).
  2. Атрибуты, показанные в диаграмме синтаксиса, являются единственными, которые могут быть изменены этим оператором. Сведения об их использовании см. в разделе Разделы описания данных.

7.8.39.9. УСТАНОВКА ПОСЛЕДНЕЙ ОШИБКИ

Синтаксис УСТАНОВКИ АТРИБУТА

 SET LAST EXCEPTION TO { OFF }
 ~~~ ~~~~ ~~~~~~~~~ ~~   ~~~

Оператор SET LAST EXCEPTION установит статус последней ошибки программы, указав отсутствие ошибки.

  1. Предварительно определенный объект ссылки EXCEPTION-OBJECT устанавливается в значение null, и статус последней ошибки устанавливается, чтобы указывать отсутствие ошибки.
  2. Это действие полностью сбросит глобальный объект исключения (ФУНКЦИЯ EXCEPTION-{Файл, Локация, Оператор, Статус}) и не отобразит ничего после этого, независимо от последней ошибки (такой как деление на ноль). Используйте с осторожностью.

7.8.40. СОРТИРОВКА

7.8.40.1. СОРТИРОВКА по файлам

Синтаксис СОРТИРОВКИ по файлам

 SORT sort-file-1
 ~~~~
    { ON { ASCENDING  } KEY identifier-1... }...
         { ~~~~~~~~~  }
         { DESCENDING }
           ~~~~~~~~~~
    [ WITH DUPLICATES IN ORDER ]
           ~~~~~~~~~~
    [ COLLATING SEQUENCE IS alphabet-name-1 ]
      ~~~~~~~~~

    { INPUT PROCEDURE IS procedure-name-1      }
    { ~~~~~~ ~~~~~~~~~                         }
    {       [ THRU|THROUGH procedure-name-2 ]  }
    {         ~~~~ ~~~~~~~                     }
    { USING file-name-1...                     }
      ~~~~~
    { OUTPUT PROCEDURE IS procedure-name-3     }
    { ~~~~~~ ~~~~~~~~~                         }
    {       [ THRU|THROUGH procedure-name-4 ]  }
    {         ~~~~ ~~~~~~~                     }
    { GIVING file-name-2...                    }
      ~~~~~~

Оператор DUPLICATES синтаксически распознается, но в остальном не функционален.

Этот формат оператора SORT предназначен для сортировки больших объемов данных по одному или нескольким ключевым полям.

  1. Зарезервированные слова IN, IS, KEY, ON, ORDER, SEQUENCE и WITH являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированные слова THRU и THROUGH взаимозаменяемы.
  3. GnuCOBOL всегда ведет себя так, как будто указан пункт WITH DUPLICATES IN ORDER, даже если его нет.

    Хотя любые средства сортировки или слияния в реализации COBOL гарантируют, что записи с дублирующими значениями ключей будут в правильной последовательности относительно других записей с различными значениями ключей, они, как правило, не дают никаких обещаний относительно относительной последовательности записей с дублирующими значениями ключей.

    Некоторые реализации COBOL предоставляют этот необязательный пункт, чтобы заставить средства сортировки и слияния сохранять записи с дублирующими значениями ключей в исходной последовательности входных данных относительно друг друга.

  4. Файл sort-file-1, указанный в инструкции SORT, должен быть определен с помощью описания сортировки (SD (см. Файл/Описание сортировки)). Этот файл в дальнейшем упоминается как рабочий файл сортировки.
  5. Если указаны, file-name-1 и file-name-2 должны ссылаться на файлы ORGANIZATION LINE SEQUENTIAL (см. ОРГАНИЗАЦИЯ ПОСТРОЧНО ПОСЛЕДОВАТЕЛЬНАЯ) или ORGANIZATION SEQUENTIAL (см. ОРГАНИЗАЦИЯ ПОСЛЕДОВАТЕЛЬНАЯ). Эти файлы должны быть определены с помощью описания файла (FD (см. Файл/Описание сортировки)). Те же файлы могут использоваться для file-name-1 и file-name-2.
  6. Поле(я) identifier-1 … должны быть определены как поле(я) в записи файла sort-file-1.
  7. Рабочий файл сортировки никогда не открывается и не закрывается.
  8. Процесс сортировки происходит в трех этапах — Этап ввода, Этап сортировки и Этап вывода.
  9. Следующие пункты относятся к этапу ввода:
    1. Данные, подлежащие сортировке, загружаются в рабочий файл сортировки, либо путем копирования всего содержимого файла(ов), указанного в пункте USING (выполняется автоматически сортировкой), либо с помощью процедуры ввода.
    2. Когда USING указан, ни один из файлов file-name-1 не может быть открыт в момент выполнения инструкции SORT.
    3. При использовании процедуры ввода, указанные в пункте INPUT PROCEDURE процедуры будут вызваны, как если бы это была процедурная инструкция PERFORM (см. Процедурная PERFORM) без указания параметров VARYING, TIMES или UNTIL. Записи будут загружаться в рабочий файл сортировки — по одной за раз — в рамках процедуры ввода с использованием инструкции RELEASE (см. RELEASE). Это, кстати, как можно отсортировать содержимое файлов относительного или индексированного доступа.

      Инструкция GO TO (см. GO TO), передающая управление из процедуры ввода, завершит выполнение инструкции SORT, но позволит программе продолжить выполнение с точки, в которой инструкция GO TO передала управление. После того, как процедура ввода была «прервана» с использованием GO TO, ее невозможно возобновить, и содержимое рабочего файла сортировки теряется. Однако вы можете повторно выполнить инструкцию SORT.3

      Процедура ввода должна завершаться так же, как и процедурная инструкция PERFORM.

      Ни инструкция SORT на основе файла, ни инструкция MERGE не могут быть выполнены в рамках процедуры ввода, если эти инструкции не используют другой рабочий файл сортировки или слияния.

    4. После завершения процедуры ввода фаза ввода завершена.
    5. По мере загрузки данных в рабочий файл сортировки они фактически буферизуются в динамически выделяемой памяти. Только если объем данных, подлежащих сортировке, превышает объем доступной памяти сортировки (128 МБ), будут выделены и использованы фактические файлы на диске. Существует переменная среды выполнения COB_SORT_MEMORY (см. Переменные среды выполнения), которую вы можете использовать для выделения большего или меньшего объема памяти для процесса сортировки.
  1. Следующие пункты относятся к стадии сортировки:
    1. Сортировка выполняется путем упорядочивания записей данных в последовательности, определенной спецификацией KEY в инструкции SORT в соответствии с COLLATING SEQUENCE, указанным в SORT (если указано), или — если не определено — в соответствии с PROGRAM COLLATING SEQUENCE (см. OBJECT-COMPUTER). Ключи могут быть любым поддерживаемым типом данных и USAGE (см. USAGE), за исключением элементов данных уровня 78 или уровня 88.
    2. Например, предположим, что мы сортируем ряд финансовых транзакций. Инструкция SORT может выглядеть так:
      SORT Sort-File
          ASCENDING  KEY Transaction-Date
          ASCENDING  KEY Account-Number
          DESCENDING KEY Transaction-Amount
      

      Результат выполнения этой инструкции будет заключаться в сортировке всех транзакций в порядке возрастания даты их совершения (от самой ранней к самой поздней). Скорее всего, для любой даты в базе будет много транзакций. Поэтому внутри каждой группы транзакций с одинаковой датой транзакции будут подсортированы в порядке возрастания номера счета, к которому они относятся. Поскольку вполне возможно, что для любого счета в любой заданный день может быть несколько транзакций, на третьем уровне подсортировка будет упорядочивать все транзакции для одного счета в один день в порядке убывания фактической суммы транзакции (от наибольшей к наименьшей). Если для счета №12345 от 31 августа 2009 г. были зарегистрированы две или более транзакции по 100 долларов США, эти транзакции будут сохранены в порядке, в котором они были загружены в файл сортировки.

    3. Если для сортировки необходимо использовать файлы на диске из-за большого объема данных, они будут автоматически выделены на диске в папке, определенной переменной среды выполнения TMPDIR, TMP переменной среды выполнения или TEMP переменной среды выполнения (см. Переменные среды выполнения) (проверка существования в указанном порядке). Эти файлы на диске будут автоматически удалены при завершении работы SORT или при завершении выполнения программы (обычное или иное завершение).
  2. Следующие пункты относятся к стадии вывода:
    1. После завершения стадии сортировки копия отсортированных данных будет записана в каждый файл file-name-2, если был указан GIVING предложение. Ни один из файлов file-name-2 не может быть открыт в момент выполнения сортировки.
    2. При использовании процедуры вывода процедура(ы), указанная в OUTPUT PROCEDURE предложении, будет вызвана так, как если бы это была процедурная инструкция PERFORM (см. Процедурное PERFORM), без указания VARYING, TIMES или UNTIL параметров. Записи будут извлекаться из файла сортировки — по одной за раз — внутри процедуры вывода с помощью инструкции RETURN (см. RETURN).

      Инструкция GO TO (см. GO TO), передающая управление за пределы процедуры вывода, завершит выполнение инструкции SORT, но позволит программе продолжить выполнение с точки, в которую инструкция GO TO передала управление. После того, как процедура вывода была «прервана» с помощью инструкции GO TO, ее нельзя возобновить, и содержимое файла сортировки будет потеряно. Однако вы можете повторно выполнить инструкцию SORT само по себе. Использование инструкции GO TO 4

      Процедура вывода должна быть завершена так же, как и процедурная инструкция PERFORM.

      Ни инструкция SORT , базирующаяся на файлах, ни инструкция MERGE не может быть выполнена внутри процедуры вывода, если эти инструкции не используют другой файл сортировки или слияния.

    3. После завершения процедуры вывода сортировка завершена.

7.8.40.2. Таблица SORT

Синтаксис таблицы SORT

 SORT table-name-1
 ~~~~
    { ON { ASCENDING  } KEY identifier-1... }...
         { ~~~~~~~~~  }
         { DESCENDING }
           ~~~~~~~~~~
    [ WITH DUPLICATES IN ORDER ]
           ~~~~~~~~~~
    [ COLLATING SEQUENCE IS alphabet-name-1 ]
      ~~~~~~~~~

Предложение DUPLICATES синтаксически распознаётся, но при этом не выполняется.

Этот формат инструкции SORT сортирует относительно небольшие объемы данных — в частности, данные, содержащиеся в таблице отдела данных, — по одному или нескольким ключевым полям.

  1. Зарезервированные слова IN, IS, KEY, ON, ORDER, SEQUENCE и WITH являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. GnuCOBOL всегда ведет себя так, как будто указан WITH DUPLICATES IN ORDER операнд, даже если он не указан.

    В то время как любые возможности сортировки или слияния в реализации COBOL гарантируют, что записи с дублирующими значениями ключей будут в правильной последовательности по отношению к другим записям с различными значениями ключей, они, как правило, не дают никаких обещаний относительно относительной последовательности записей с дублирующими значениями ключей друг относительно друга.

    Некоторые реализации COBOL предоставляют этот необязательный операнд, чтобы заставить свои средства сортировки и слияния сохранять записи с дублирующими значениями ключей в исходной последовательности ввода, относительно друг друга.

  3. Данные элемента table-name-1 должны быть таблицей, определённой в любом разделе описания данных, кроме отчётов или экранов.
  4. Данные в table-name-1 будут отсортированы на месте (т.е. файл сортировки не требуется).
  5. Сортировка выполнится путем переупорядочения данных в table-name-1 в соответствии с последовательностью, определённой KEY спецификацией(ями) в операторе SORT, в соответствии с COLLATING SEQUENCE , указанной в операторе SORT (если есть) или — если не определена — в PROGRAM COLLATING SEQUENCE (см. OBJECT-COMPUTER). Ключи могут быть любого поддерживаемого типа данных и USAGE (см. USAGE), за исключением элементов данных уровня 78 или 88.
  6. Если вы сортируете table-name-1 для подготовки таблицы к использованию с оператором SEARCH ALL (см. SEARCH ALL), необходимо убедиться, что KEY спецификации в операторе SORT совпадают со спецификациями в определении таблицы.
  7. Хотя указание одного или нескольких KEY операндов является необязательным, в настоящее время сортировка таблицы без KEY спецификации(й) в операторе SORT не поддерживается GnuCOBOL и будет отклонена компилятором.

7.8.41. START

Синтаксис START

   START file-name-1
   ~~~~~
     [ { FIRST                                                    } ]
       { ~~~~~                                                    }
       { LAST                                                     }
       { ~~~~                                                     }
       { KEY { IS EQUAL TO | IS = | EQUALS         } identifier-1 }
             {    ~~~~~             ~~~~~~         }
             { IS GREATER THAN | IS >              }
             {    ~~~~~~~                          }
             { IS GREATER THAN OR EQUAL TO | IS >= }
             {    ~~~~~~~      ~~ ~~~~~            }
             { IS NOT LESS THAN                    }
             {    ~~~ ~~~~                         }
             { IS LESS THAN | IS <                 }
             {    ~~~~                             }
             { IS LESS THAN OR EQUAL TO | IS <=    }
             {    ~~~~      ~~ ~~~~~               }
             { IS NOT GREATER THAN                 }
                  ~~~ ~~~~~~~
    [ INVALID KEY imperative-statement-1 ]
      ~~~~~~~
    [ NOT INVALID KEY imperative-statement-2 ]
      ~~~ ~~~~~~~
 [ END-START ]
   ~~~~~~~~~

Оператор START определяет логическую точку начала в файле с относительной или индексированной структурой для последующих последовательных операций чтения. Он устанавливает внутренний логический указатель записи на определённую запись в файле, но не передает какие-либо данные этой записи в буфер записи.

  1. Зарезервированные слова IS, KEY, THAN и TO являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Для использования этого оператора file-name-1 должен быть файлом типа ORGANIZATION RELATIVE (см. ORGANIZATION RELATIVE) или ORGANIZATION INDEXED (см. ORGANIZATION INDEXED), который должен быть определён с помощью ACCESS MODE DYNAMIC или ACCESS MODE SEQUENTIAL в операторе SELECT (см. SELECT).
  3. В момент выполнения этого оператора file-name-1 должен быть открыт в режиме INPUT или I-O (см. File OPEN Modes).
  4. Если file-name-1 — это относительный файл, identifier-1 должен быть определённым RELATIVE KEY файла.
  5. Если file-name-1 — это индексированный файл, identifier-1 должен быть определённым RECORD KEY файла или любым из полей ALTERNATE RECORD KEY файла.
  6. Если не указаны FIRST, LAST или KEY операторы, предполагается KEY IS EQUAL TO xxx, где xxx — определённый RELATIVE KEY (если file-name-1 — относительный файл) или определённый RECORD KEY (если file-name-1 — индексированный файл).
  7. После успешного выполнения оператора START, внутренний логический указатель записи в данные file-name-1 будет установлен на запись, удовлетворяющую указанию фактического или предполагаемого FIRST, LAST или KEY оператора, как следует:
    FIRST

    логический указатель записи будет указывать на первую запись в файле.

    LAST

    логический указатель записи будет указывать на последнюю запись в файле.

    KEY

    (указанное или подразумеваемое), и используется отношение

    EQUAL TO, GREATER THAN или GREATER THAN OR EQUAL TO (или эквивалент)

    логический указатель записи будет установлен на первую запись, удовлетворяющую условию отношения; для идентификации этой записи. Содержимое файла обрабатывается с начала до конца (в соответствии с порядком ключа, подразумеваемого оператором KEY), при условии, что отношение является

    LESS THAN, LESS THAN OR EQUAL TO или NOT GREATER THAN (или эквивалент)

    логический указатель записи будет установлен на последнюю запись, удовлетворяющую условию отношения; для идентификации этой записи. Содержимое файла обрабатывается с конца до начала (в соответствии с порядком ключа, подразумеваемого оператором KEY).

    Следующий оператор READ прочитает запись, на которую указывает логический указатель записи.

  8. Необязательные INVALID KEY и NOT INVALID KEY операторы могут использоваться для обнаружения и реагирования на неудачу или успех соответственно, обнаруживая ненулевые (обычно 23 = ключ не найден = запись не найдена) и 00 коды состояния файла соответственно. Дополнительную информацию см. в разделе File Status Codes.

7.8.42. STOP

STOP Syntax

 STOP { RUN [ { RETURNING|GIVING { literal-1    }           } ] }
 ~~~~ { ~~~   { ~~~~~~~~~ ~~~~~~ { identifier-1 }           }   }
      {       {                                             }   }
      {       { WITH { ERROR  } STATUS [ { literal-2    } ] }   }
      {       {      { ~~~~~  }          { identifier-2 }   }   }
      {       {      { NORMAL }                             }   }
      {                ~~~~~~                                   }
      { literal-3                                               }

Оператор STOP приостанавливает выполнение программы. Некоторые варианты позволят возобновить выполнение программы, а другие вернут управление операционной системе.

  1. Зарезервированные слова STATUS и WITH являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированные слова RETURNING и GIVING взаимозаменяемы.
  3. Оператор RUN останавливает программу без отображения специального сообщения об этом.
  4. Оператор literal-3 отображает указанный текст на устройстве SYSOUT/STDOUT, ожидает нажатия пользователем клавиши Enter и затем — после нажатия клавиши — позволяет программе продолжить выполнение.
  5. Необязательный RETURNING оператор предоставляет возможность возвратить числовое значение операционной системе (код завершения). Способ запроса операционной системой кода завершения варьируется, но Windows может использовать %ERRORLEVEL% для запроса кода завершения, а Unix-оболочки, такие как sh, bash и ksh, могут запрашивать код завершения как $?. Другие Unix-оболочки могут иметь разные способы доступа к значениям кода возврата.
  6. Оператор STATUS предоставляет другой способ возвращения кода завершения. Использование оператора STATUS функционально эквивалентно использованию оператора RETURNING.
  7. Использование оператора STATUS без literal-2 или identifier-2 вернёт код завершения 0, если используется ключевое слово NORMAL, или 1, если было указано ERROR.
  8. Ваша программа всегда возвращает код завершения, даже если не указан ни один из операторов RETURNING или STATUS. При отсутствии этих операторов, значение в специальном регистре RETURN-CODE (см. Специальные регистры) на момент выполнения оператора STOP будет использовано как код завершения.
  9. Любая определённая программистом процедура завершения (установленная с помощью встроенной системной подпрограммы CBL_EXIT_PROC (см. CBL_EXIT_PROC)) будет выполнена STOP RUN, но не STOP literal-3.
  10. Действительные значения кода возврата могут находиться в диапазоне от -2147483648 до +2147483647.
  11. Три фрагмента кода ниже эквивалентны. Они демонстрируют различные способы кодирования программы GnuCOBOL для передачи значения кода завершения 16 обратно операционной системе и последующей остановки.
    1. STOP RUN RETURNING 16
      
    2. MOVE 16 TO RETURN-CODE
      STOP RUN
      
    3. STOP RUN WITH ERROR STATUS 16
      

7.8.43. STRING

STRING Синтаксис

   STRING
   ~~~~~~
      { { literal-1    } [ DELIMITED BY { SIZE         } ] }...
        { identifier-1 }   ~~~~~~~~~    { ~~~~         }
                                        { literal-2    }
                                        { identifier-2 }
        INTO identifier-3
        ~~~~
      [ WITH POINTER identifier-4 ]
             ~~~~~~~
      [ ON OVERFLOW imperative-statement-1 ]
           ~~~~~~~~
      [ NOT ON OVERFLOW imperative-statement-2 ]
        ~~~    ~~~~~~~~
 [ END-STRING ]
   ~~~~~~~~~~

Оператор STRING используется для конкатенации всех или части одной или нескольких строк, формируя новую строку.

  1. Ключевые слова BY, ON и WITH являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Все литералы и идентификаторы (кроме identifier-4) должны быть явно или неявно определены с помощью USAGE (см. USAGE) типа DISPLAY. Любой из идентификаторов может быть элементом группы.
  3. Элемент данных POINTER — identifier-4 — должен быть целочисленным неотредактированным элементарным числовым элементом данных со значением больше нуля.
  4. Каждый literal-1 / identifier-1 будет называться исходным элементом. Элемент данных приема — identifier-3.
  5. Обработка оператора STRING основана на текущей позиции указателя символов. Начальное значение текущей позиции указателя символов будет равно значению identifier-4 в момент начала выполнения оператора STRING. Если не указан оператор POINTER, предполагается значение 1 (означающее «первая позиция символа») для начального значения текущей позиции указателя символов.
  6. Для каждого исходного элемента содержимое отправляемого элемента будет копироваться — символ за символом — в identifier-3 в позиции, указанной текущей позицией указателя символов. После копирования каждого символа текущая позиция указателя символов будет инкрементирована на 1, чтобы она указывала на позицию в identifier-3, куда должен быть скопирован следующий символ.
  7. Оператор DELIMITED BY определяет, сколько символов каждого исходного элемента будет скопировано в identifier-3. DELIMITED BY SIZE (значение по умолчанию, если не указан оператор DELIMITED BY) приводит к копированию всего содержимого исходного элемента в identifier-3.
  8. Использование DELIMITED BY literal-2 или DELIMITED BY identifier-2 приводит к копированию только содержимого исходного элемента до, но не включая, указанную последовательность символов литерала или идентификатора.
  9. Обработка STRING прекратится, когда произойдет одно из следующих событий:
    1. Начальное значение текущей позиции указателя символов меньше 1 или больше, чем количество символов в identifier-3, или…
    2. Значение текущей позиции указателя символов превышает размер identifier-3 в момент, когда оператор STRING пытается скопировать символ в identifier-3, или…
    3. Все отправленные элементы были полностью обработаны
  10. Если произойдёт событие A, identifier-3 останется без изменений.
  11. Происхождение любого из событий A или B вызывает так называемое состояние переполнения.
  12. identifier-3) не инициализируется автоматически (пробелами или любым другим значением) в начале оператора STRING и не будет заполняться пробелами, если общее количество символов отправляемых элементов, скопированных в него, меньше его размера. Вы можете явно инициализировать identifier-3 с помощью операторов INITIALIZE (см. INITIALIZE) или MOVE (см. MOVE) перед выполнением оператора STRING, если хотите.
  13. Необязательные операторы ON OVERFLOW и NOT ON OVERFLOW могут использоваться для обнаружения и реакции на возникновение или отсутствие, соответственно, состояния переполнения. Дополнительную информацию см. в разделе ON OVERFLOW + NOT ON OVERFLOW.

7.8.44. ВЫЧИТАНИЕ

7.8.44.1. ВЫЧИТАНИЕ ИЗ

Синтаксис ВЫЧИТАНИЕ ИЗ

   SUBTRACT { literal-1    }... FROM { identifier-2
   ~~~~~~~~ { identifier-1 }    ~~~~

          [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
            ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                              { NEAREST-AWAY-FROM-ZERO }
                              { ~~~~~~~~~~~~~~~~~~~~~~ }
                              { NEAREST-EVEN           }
                              { ~~~~~~~~~~~~           }
                              { NEAREST-TOWARD-ZERO    }
                              { ~~~~~~~~~~~~~~~~~~~    }
                              { PROHIBITED             }
                              { ~~~~~~~~~~             }
                              { TOWARD-GREATER         }
                              { ~~~~~~~~~~~~~~         }
                              { TOWARD-LESSER          }
                              { ~~~~~~~~~~~~~          }
                              { TRUNCATION             }
                                ~~~~~~~~~~
     [ ON SIZE ERROR imperative-statement-1 ]
          ~~~~ ~~~~~
     [ NOT ON SIZE ERROR imperative-statement-2 ]
       ~~~    ~~~~ ~~~~~
 [ END-SUBTRACT ]
   ~~~~~~~~~~~~

Этот формат оператора SUBTRACT генерирует арифметическую сумму всех аргументов, которые появляются перед FROM (identifier-1 или literal-1) и вычитает эту сумму из каждого identifier-2.

  1. Ключевые слова IS и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. И identifier-1, и identifier-2 должны быть числовыми неотредактированными элементами данных.
  3. literal-1 должен быть числовым литералом.
  4. Необязательный оператор ROUNDED (см. ROUNDED), доступный для каждого identifier-2, будет управлять тем, как будут сохраняться нецелые результаты.
  5. Необязательные операторы ON SIZE ERROR и NOT ON SIZE ERROR могут использоваться для обнаружения и реакции на неудачу или успешность, соответственно, попытки выполнить вычисление. В этом случае неудача определяется как identifier-2 с недостаточным количеством позиций цифр слева от любой предполагаемой десятичной точки. Дополнительную информацию см. в разделе ON SIZE ERROR + NOT ON SIZE ERROR.

7.8.44.2. ВЫЧИТАНИЕ С РЕЗУЛЬТАТОМ

Синтаксис ВЫЧИТАНИЕ С РЕЗУЛЬТАТОМ

   SUBTRACT { literal-1    }... FROM identifier-2
   ~~~~~~~~ { identifier-1 }    ~~~~

       GIVING { identifier-3
       ~~~~~~
          [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
            ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                              { NEAREST-AWAY-FROM-ZERO }
                              { ~~~~~~~~~~~~~~~~~~~~~~ }
                              { NEAREST-EVEN           }
                              { ~~~~~~~~~~~~           }
                              { NEAREST-TOWARD-ZERO    }
                              { ~~~~~~~~~~~~~~~~~~~    }
                              { PROHIBITED             }
                              { ~~~~~~~~~~             }
                              { TOWARD-GREATER         }
                              { ~~~~~~~~~~~~~~         }
                              { TOWARD-LESSER          }
                              { ~~~~~~~~~~~~~          }
                              { TRUNCATION             }
                                ~~~~~~~~~~
     [ ON SIZE ERROR imperative-statement-1 ]
          ~~~~ ~~~~~
     [ NOT ON SIZE ERROR imperative-statement-2 ]
       ~~~    ~~~~ ~~~~~
 [ END-SUBTRACT ]
   ~~~~~~~~~~~~

Оператор SUBTRACT GIVING генерирует арифметическую сумму всех аргументов, которые появляются перед FROM (identifier-1 или literal-1), вычитает эту сумму из содержимого identifier-2 и затем заменяет содержимое идентификаторов, перечисленных после GIVING (identifier-3), этим результатом.

  1. Зарезервированные слова IS и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. И identifier-1, и identifier-2 должны быть числовыми необработанными данными.
  3. literal-1 должен быть числовой литеральной константой.
  4. identifier-3 должен быть числовым (обработанным или необработанным) элементом данных.
  5. Необязательная ROUNDED (см. ROUNDED) клауза, доступная для каждого identifier-2, будет контролировать, как будут сохраняться нецелые результаты.
  6. Необязательные ON SIZE ERROR и NOT ON SIZE ERROR клаузы могут быть использованы для обнаружения и реакции на ошибку или успех попытки выполнения вычисления соответственно. В этом случае ошибка определяется как identifier-2 с недостаточным количеством разрядов слева от предполагаемой десятичной точки. См. ON SIZE ERROR + NOT ON SIZE ERROR для дополнительной информации.

7.8.44.3. ВЫЧИТАНИЕ СООТВЕТСТВУЮЩИХ

Синтаксис ВЫЧИТАНИЕ СООТВЕТСТВУЮЩИХ

   SUBTRACT CORRESPONDING identifier-1 FROM identifier-2
   ~~~~~~~~                            ~~~~
     [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ]
       ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                         { NEAREST-AWAY-FROM-ZERO }
                         { ~~~~~~~~~~~~~~~~~~~~~~ }
                         { NEAREST-EVEN           }
                         { ~~~~~~~~~~~~           }
                         { NEAREST-TOWARD-ZERO    }
                         { ~~~~~~~~~~~~~~~~~~~    }
                         { PROHIBITED             }
                         { ~~~~~~~~~~             }
                         { TOWARD-GREATER         }
                         { ~~~~~~~~~~~~~~         }
                         { TOWARD-LESSER          }
                         { ~~~~~~~~~~~~~          }
                         { TRUNCATION             }
                           ~~~~~~~~~~
     [ ON SIZE ERROR imperative-statement-1 ]
          ~~~~ ~~~~~
     [ NOT ON SIZE ERROR imperative-statement-2 ]
       ~~~    ~~~~ ~~~~~
 [ END-SUBTRACT ]
   ~~~~~~~~~~~~

Выражение SUBTRACT CORRESPONDING генерирует код, эквивалентный отдельным SUBTRACT FROM выражениям для соответствующих совпадений элементов данных, расположенных подчиненно двум идентификаторам.

  1. Зарезервированные слова IS и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. И identifier-1, и identifier-2 должны быть группами элементов.
  3. См. CORRESPONDING для информации о том, как будут находиться соответствующие совпадения между identifier-1 и identifier-2.
  4. Необязательная ROUNDED (см. ROUNDED) клауза, доступная для каждого identifier-2, будет контролировать, как будут сохраняться нецелые результаты.
  5. Необязательные ON SIZE ERROR и NOT ON SIZE ERROR клаузы могут быть использованы для обнаружения и реакции на ошибку или успех попытки выполнения вычисления соответственно. В этом случае ошибка определяется как identifier-2 с недостаточным количеством разрядов слева от предполагаемой десятичной точки. См. ON SIZE ERROR + NOT ON SIZE ERROR для дополнительной информации.

7.8.45. ПОДАВЛЕНИЕ

Синтаксис ПОДАВЛЕНИЕ

 SUPPRESS PRINTING
 ~~~~~~~~

Выражение SUPPRESS приводит к подавлению представления группы отчёта.

  1. Зарезервированное слово PRINTING является необязательным и может быть опущено. Наличие или отсутствие этого слова не влияет на программу.
  2. Это выражение может появиться только внутри процедуры USE BEFORE REPORTING (в DECLARATIVES (см. DECLARATIVES)).
  3. SUPPRESS только предотвращает представление группы отчёта внутри процедуры USE BEFORE REPORTING, в которой находится это выражение.
  4. Это выражение должно выполняться каждый раз, когда необходимо подавить представление группы отчёта.
  5. Когда представление группы отчёта подавлено, ни одна из следующих операций для отчёта не будет выполнена:
    1. Фактическое представление группы отчёта.
    2. Обработка любых LINE (см. LINE) клауз внутри группы отчёта.
    3. Обработка клаузы NEXT GROUP (см. NEXT GROUP) (если есть) внутри группы отчёта.
    4. Любые изменения в специальном регистре LINE-COUNTER (см. Special Registers).
    5. Любые изменения в специальном регистре PAGE-COUNTER.

7.8.46. ЗАВЕРШИТЬ

Синтаксис ЗАВЕРШИТЬ

 TERMINATE report-name-1...
 ~~~~~~~~~

Выражение TERMINATE завершает обработку указанного(ых) отчёта(ов).

  1. Каждый report-name-1 должен быть именем отчёта, для которого определён RD (см. REPORT SECTION).
  2. Указанное(ые) имя(на) отчёта(ов) должны быть инициированы (через INITIATE (см. INITIATE)) и не должны быть завершены.
  3. Выражение TERMINATE представит каждую CONTROL FOOTING (если есть), в обратном порядке иерархии управления, начиная с наименее важного до FINAL (если есть). Во время представления этих групп и обработки любых процедур USE BEFORE REPORTING для этих групп будут доступны предыдущие значения элементов данных управления, как будто был обнаружен разрыв управления в имени данных управления наивысшего уровня.
  4. Во время представления групп CONTROL FOOTING будут также представлены необходимые группы PAGE FOOTING и PAGE HEADING.
  5. Наконец, будет представлена группа REPORT FOOTING, если таковая имеется.
  6. Если INITIATE следует за TERMINATE, без промежуточных GENERATE (см. GENERATE) выражений (конечно, все относящиеся к одному отчёту), никакие группы отчётов не будут представлены в выходной файл.

7.8.47. ПРЕОБРАЗОВАТЬ

Синтаксис ПРЕОБРАЗОВАТЬ

 TRANSFORM identifier-1 FROM { literal-1    } TO { literal-2    }
 ~~~~~~~~~              ~~~~ { identifier-2 } ~~ { identifier-3 }

Выражение TRANSFORM сканирует элемент данных, выполняя серию моноалфавитных подстановок, определённых аргументами до и после клаузы TO.

  1. Оба literal-1 и/или literal-2 должны быть буквенно-цифровыми литералами.
  2. Все identifier-1, identifier-2 и identifier-3 должны быть либо элементами группы, либо буквенно-цифровыми данными. Числовые данные с USAGE (см. ИСПОЛЬЗОВАНИЕ) DISPLAY принимаются, но приведут к предупреждениям компилятора.
  3. Выражение TRANSFORM заменит символы в identifier-1, которые встречаются в строке, указанной перед TO, соответствующими символами из строки, указанной после TO.
  4. Это выражение присутствует в GnuCOBOL для обеспечения совместимости с COBOL-программами, написанными по стандартам до 1985 года. Выражение TRANSFORM было устаревшим в стандарте COBOL 1985 года, будучи заменённым клаузой CONVERTING выражения INSPECT (см. INSPECT). Новые программы должны быть написаны с использованием INSPECT CONVERTING, а не TRANSFORM.

7.8.48. РАЗБЛОКИРОВАТЬ

Синтаксис РАЗБЛОКИРОВАТЬ

 UNLOCK filename-1 RECORD|RECORDS
 ~~~~~~

Это выражение синхронизирует любые еще не записанные буферы ввода-вывода файла с указанным файлом (если таковой имеется) и освобождает любые блокировки записей, удерживаемые для записей, принадлежащих file-name-1.

  1. Зарезервированные слова RECORD и RECORDS являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Если file-name-1 является файлом работы сортировки/слияния, никаких действий не будет произведено.
  3. Не все реализации GnuCOBOL поддерживают блокировки. Поддержка зависит от операционной системы, для которой они были построены, и от параметров сборки, использованных при создании GnuCOBOL. Когда программа, использующая одну из таких реализаций GnuCOBOL, выполняет РАЗБЛОКИРОВАТЬ, она будет проигнорирована. Сообщение компилятора не будет выдано. Синхронизация буфера, если необходимо, всё равно произойдёт.
  4. См. Блокировка записей для получения дополнительной информации о блокировке записей.

7.8.49. РАЗДЕЛИТЬ

Синтаксис РАЗДЕЛИТЬ

   UNSTRING identifier-1
   ~~~~~~~~
        DELIMITED BY { [ ALL ] literal-1 } [ OR { [ ALL ] literal-2 } ]...
        ~~~~~~~~~    {   ~~~             }   ~~ {   ~~~             }
                     { identifier-2      }      { identifier-3      }

        INTO { identifier-4
        ~~~~ [ DELIMITER IN identifier-5 ] [ COUNT IN identifier-6 ] }...
               ~~~~~~~~~                     ~~~~~
      [ WITH POINTER identifier-7 ]
             ~~~~~~~
      [ TALLYING IN identifier-8 ]
        ~~~~~~~~
      [ ON OVERFLOW imperative-statement-1 ]
           ~~~~~~~~
      [ NOT ON OVERFLOW imperative-statement-2 ]
        ~~~    ~~~~~~~~
 [ END-UNSTRING ]
   ~~~~~~~~~~~~

Выражение UNSTRING анализирует строку, извлекая любое количество подстрок из неё.

  1. Зарезервированные слова BY, IN и ON являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. identifier-1 по identifier-5 должны быть явно или неявно определены с USAGE (см. USAGE) типа DISPLAY. Любой из этих идентификаторов может быть групповым элементом.
  3. И literal-1, и literal-2 должны быть алфавитно-цифровыми литералами.
  4. Каждый из identifier-6, identifier-7 и identifier-8 должен быть элементарным неотредактированным целочисленным числовым элементом.
  5. В момент начала выполнения оператора UNSTRING, identifier-7 должен иметь значение больше 0.
  6. identifier-1 будет называться исходной строкой, а каждый identifier-4 — полем назначения в последующих обсуждениях.
  7. Обработка оператора UNSTRING основана на текущем указателе символа, начальное значение которого будет равно значению identifier-7 в момент начала выполнения оператора UNSTRING. Если не указан POINTER-оператор, за начальное значение текущего указателя символа будет принято значение 1 (означающее «первая позиция символа»).
  8. Исходная строка будет разделяться на подстроки, начиная с позиции текущего указателя символа. Подстроки идентифицируются с использованием различных разделительных строк, указанных в DELIMITED BY-операторе, как разделители между подстроками.
  9. Использование ALL-опции позволяет разделительной последовательности быть произвольно длинной последовательностью вхождений разделительного литерала, в то время как его отсутствие рассматривает каждое вхождение как отдельный разделитель. При указании нескольких разделителей они будут искаться в исходной строке в том порядке, в котором они закодированы.
  10. Две последовательные разделительные последовательности идентифицируют пустую подстроку.
  11. Идентифицированные подстроки будут перемещаться в каждое поле назначения в том порядке, в котором они идентифицируются; значения, перемещенные в поле назначения, будут усечены, если длина подстроки превышает длину поля назначения, или дополнены пробелами, если длина поля назначения превышает длину подстроки. Как усечение, так и заполнение будут контролироваться наличием или отсутствием JUSTIFIED (см. JUSTIFIED) -оператора в поле назначения.
  12. Каждое поле назначения может иметь необязательный DELIMITER-оператор. Если указан DELIMITER-оператор, identifier-5 получит строку разделителя, используемую для идентификации подстроки для поля назначения, которая в нее переместится. Если поле назначения не было изменено (потому что не было идентифицировано достаточное количество подстрок), identifier-5 для этого поля назначения также останется без изменений.
  13. Каждое поле назначения может иметь необязательный COUNT-оператор. Если указан COUNT-оператор, identifier-6 получит размер подстроки (в символах) для поля назначения, которое в нее переместится. Если поле назначения не было изменено (потому что не было идентифицировано достаточное количество подстрок), identifier-6 для этого поля назначения также останется без изменений.
  14. Если закодирован TALLYING-оператор, identifier-8 будет инкрементироваться на 1 каждый раз, когда поле назначения заполняется.
  15. Ни один из identifier-4, identifier-5, identifier-6, identifier-7 или identifier-8 не инициализируется оператором UNSTRING. Необходимо выполнить это самостоятельно с помощью оператора MOVE (см. MOVE) или INITIALIZE (см. INITIALIZE).
  16. Обработка UNSTRING прекратится, когда произойдет одно из следующих событий:
    1. Начальное значение текущего указателя символа меньше 1 или больше числа позиций символов в identifier-1, или…
    2. Все поля назначения были полностью обработаны
  17. Если произойдет событие A, содержимое ни одного поля назначения (или содержимое их DELIMITER или идентификаторов COUNT) не изменится.
  18. Состояние переполнения возникает, если происходит событие A или если происходит событие B с как минимум одной позицией символа в identifier-1, которая не была обработана.
  19. Необязательные ON OVERFLOW и NOT ON OVERFLOW-операторы могут использоваться для обнаружения и реакции соответственно на возникновение или отсутствие состояния переполнения. Дополнительную информацию см. в разделе ON OVERFLOW + NOT ON OVERFLOW.

Следующая примерная программа иллюстрирует оператор UNSTRING.

IDENTIFICATION DIVISION.
PROGRAM-ID. DEMOUNSTRING.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  Full-Name                   PIC X(40).
01  Parsed-Info.
    05 Last-Name                PIC X(15).
    05 First-Name               PIC X(15).
    05 MI                       PIC X(1).
    05 Delim-LN                 PIC X(1).
    05 Delim-FN                 PIC X(1).
    05 Delim-MI                 PIC X(1).
    05 Count-LN                 BINARY-CHAR.
    05 Count-FN                 BINARY-CHAR.
    05 Count-MI                 BINARY-CHAR.
    05 Tallying-Ctr             BINARY-CHAR.
PROCEDURE DIVISION.
P1. PERFORM UNTIL EXIT
      DISPLAY "Enter Full Name (null quits):"
          WITH NO ADVANCING
      ACCEPT Full-Name
      IF Full-Name = SPACES
        EXIT PERFORM
      END-IF
      INITIALIZE Parsed-Info
      UNSTRING Full-Name
        DELIMITED BY ", "
                  OR ","
                  OR ALL SPACES
        INTO Last-Name
                 DELIMITER IN Delim-LN
                 COUNT IN Count-LN
             First-Name
                 DELIMITER IN Delim-FN
                 COUNT IN Count-FN
             MI
                 DELIMITER IN Delim-MI
                 COUNT IN Count-MI
        TALLYING Tallying-Ctr
    DISPLAY "First-Name=" First-Name
            " Delim='"    Delim-FN
            "' Count="    Count-FN
    DISPLAY "MI        =" MI "              "
            " Delim='"    Delim-MI
            "' Count="    Count-MI
    DISPLAY "Last-Name =" Last-Name
            " Delim='"    Delim-LN
            "' Count="    Count-LN
    DISPLAY "Tally=     " Tallying-Ctr
  END-PERFORM
  DISPLAY "Bye!"
  STOP RUN   .

Следующее — примерный вывод программы:

Enter Full Name (null quits):Cutler, Gary L
First-Name=Gary            Delim=' ' Count=+004
MI        =L               Delim=' ' Count=+001
Last-Name =Cutler          Delim=',' Count=+006
Tally=     +003
Enter Full Name (null quits):Snoddgrass,Throckmorton,P
First-Name=Throckmorton    Delim=',' Count=+012
MI        =P               Delim=' ' Count=+001
Last-Name =Snoddgrass      Delim=',' Count=+010
Tally=     +003
Enter Full Name (null quits):Munster   Herman
First-Name=Herman          Delim=' ' Count=+006
MI        =                Delim=' ' Count=+000
Last-Name =Munster         Delim=' ' Count=+007
Tally=     +002
Enter Full Name (null quits):
Bye!

7.8.50. WRITE

Синтаксис WRITE

   WRITE record-name-1
   ~~~~~
      [ FROM { literal-1    } ]
        ~~~~ { identifier-1 }

      [ WITH [ NO ] LOCK ]
               ~~   ~~~~
      [ { BEFORE } ADVANCING { { literal-2    } LINE|LINES } ]
        { ~~~~~~ }           { { identifier-2              }
        { AFTER  }           { PAGE                        }
          ~~~~~              { ~~~~                        }
                             { mnemonic-name-1             }

      [ AT END-OF-PAGE|EOP imperative-statement-1 ]
           ~~~~~~~~~~~ ~~~
      [ NOT AT END-OF-PAGE|EOP imperative-statement-2 ]
        ~~~    ~~~~~~~~~~~ ~~~
      [ INVALID KEY imperative-statement-3 ]
        ~~~~~~~
      [ NOT INVALID KEY imperative-statement-4 ]
        ~~~ ~~~~~~~
 [ END-WRITE ]
   ~~~~~~~~~

Оператор WRITE записывает новую запись в открытый файл.

  1. Зарезервированные слова ADVANCING, AT, KEY, LINE, LINES и WITH являются необязательными и могут быть опущены. Наличие или отсутствие этих слов не влияет на программу.
  2. Зарезервированные слова END-OF-PAGE и EOP взаимозаменяемы.
  3. record-name-1, указанное в инструкции, должно быть определено как запись уровня 01, подчиненная описанию файла (FD (см. Описание файла/сортировки)) файла, который в настоящее время открыт для OUTPUT (см. Режимы открытия файла), EXTEND или I-O.
  4. Необязательная фраза FROM заставит literal-1 или identifier-1 автоматически переместиться в record-name-1 перед записью содержимого record-name-1 в соответствующий файл. Если эта фраза не указана, программисту необходимо заполнить record-name-1 необходимыми данными перед выполнением WRITE.
  5. Необязательные параметры LOCK могут использоваться для ручного управления доступом к только что записанной записи другими программами во время работы этой программы. Обратитесь к Блокировке записей для ознакомления с различными поведением блокировки записей.
  6. Необязательные фразы INVALID KEY и NOT INVALID KEY могут использоваться при записи в относительные или индексированные файлы для обнаружения и реакции на ошибку (код состояния файла не равен нулю) или успех (код состояния файла равен 00) инструкции соответственно. Для получения дополнительной информации см. Коды состояния файла.
  7. При использовании WRITE с файлом ORGANIZATION LINE SEQUENTIAL (см. Последовательный файл организации строк) с или без опции LINE ADVANCING (см. Переход на следующую строку) в файл будет записана последовательность символов разделителя конца записи, обозначающая конец одной записи и начало следующей. Эта последовательность разделителей будет следующей:
    • Последовательность символов завершения строки, состоящая из последовательности символов возврата каретки/перевода строки ASCII (X'0D0A'), если вы используете сборку GnuCOBOL MinGW или родную Windows
    • Последовательность символов завершения строки, состоящая из символа ASCII перевода строки (X'0A'), если вы используете сборку GnuCOBOL Cygwin, Linux, Unix или OSX
  1. Следующие пункты касаются использования (или неиспользования) предложения ADVANCING:
    1. Использование этого предложения с любой организацией, кроме ORGANIZATION LINE SEQUENTIAL, будет либо полностью отклонено компилятором (относительные или индексированные файлы), либо может ввести нежелательные символы в файл (ORGANIZATION SEQUENTIAL (см. ОРГАНИЗАЦИЯ ПОСЛЕДОВАТЕЛЬНАЯ)).
    2. Если предложение ADVANCING не указано в файле WRITE для файла с продвижением на новую строку, будет предполагаться AFTER ADVANCING 1 LINE; в других файлах, кроме файлов с продвижением на новую строку, будет предполагаться BEFORE ADVANCING 1 LINE.
    3. Когда используется (или подразумевается) BEFORE ADVANCING, запись записывается в файл до того, как действие ADVANCING запишет символы конца строки в файл.
    4. Если используется (или подразумевается) AFTER ADVANCING, действие ADVANCING запишет символы конца строки в файл, а затем данные записи запишутся в файл.
    5. Предложение ADVANCING n LINES введёт в файл указанное количество последовательностей символов конца строки, либо перед записанной записью (AFTER ADVANCING) либо после записанной записи (BEFORE ADVANCING).
    6. Если предложение LINAGE (см. Описание файла/Сортировки) отсутствует в описании файла FD:
      1. Предложение ADVANCING PAGE введёт символ ASCII-перевода страницы в файл, либо перед записанной записью (AFTER PAGE) либо после записанной записи (BEFORE PAGE).
      2. Управление областями на печатной странице, такими как заголовки начала страницы, подписи конца страницы, обработка ситуаций «полная страница» и т.п., полностью лежит на ответственности программиста.
    7. Если предложение LINAGE присутствует в описании файла FD:
      1. Предложение ADVANCING PAGE введёт в файл соответствующее количество последовательностей символов конца строки, либо перед записанной записью (AFTER ADVANCING) либо после записанной записи (BEFORE ADVANCING) для того, чтобы заставить принтер автоматически перейти к новой странице при печати файла. Символы перевода страницы не будут генерироваться при указании LINAGE, вместо этого предполагается, что принтер, на который будет напечатан отчёт, загружен специальными формами, соответствующими спецификациям, определённым предписанием LINAGE.
      2. Управление областями на печатной странице, такими как заголовки начала страницы, подписи конца страницы, обработка ситуаций «полная страница» и т.п., теперь лежит на совместной ответственности программиста и библиотеки времени выполнения GnuCOBOL, которая предоставляет инструменты, такие как специальный регистр LINAGE-COUNTER (см. Специальные регистры) и предложение END-OF-PAGE для обработки вопросов форматирования страницы.
      3. Предложение AT END-OF-PAGE будет активировано, тем самым выполнив команда-1 (см. Команда), если предложение WRITE введёт строку данных или символ перевода строки в файл в позиции строки внутри области подписи страницы, определённой предложением LINAGE. Предложение NOT AT END-OF-PAGE будет активировано (выполняя команда-2), если в ходе WRITE не произошло состояния конца страницы.

8. Функции

8.1. Встроенные функции

GnuCOBOL поддерживает широкий спектр «встроенных функций», которые можно использовать в разделе PROCEDURE DIVISION там, где разрешён литерал. Например:

MOVE FUNCTION LENGTH(Employee-Last-Name) TO Employee-LN-Len

Обратите внимание, как слово FUNCTION является частью синтаксиса при использовании встроенной функции. Вы можете использовать встроенные функции без необходимости включения служебного слова FUNCTION с помощью настроек в разделе REPOSITORY (см. РЕПОЗИТОРИЙ). Того же результата можно достичь, указав переключатель -fintrinsics компилятору GnuCOBOL при компиляции программ.

Пользовательские функции (см. Типы подпрограмм) никогда не требуют ключевого слова FUNCTION при выполнении, поскольку каждая пользовательская функция, используемая программой, должна быть включена в раздел REPOSITORY этой программы, что делает ключевое слово FUNCTION необязательным.

Следующие встроенные функции, известные другим «диалектам» COBOL, определены в GnuCOBOL как служебные слова, но в настоящее время не реализованы. Любые попытки использовать эти функции приведут к сообщению об ошибке компиляции. Однако они описаны в конце этой главы.

BOOLEAN-OF-INTEGER
CHAR-NATIONAL
DISPLAY-OF
EXCEPTION-FILE-N
EXCEPTION-LOCATION-N
INTEGER-OF-BOOLEAN
NATIONAL-OF
STANDARD-COMPARE

Поддерживаемые встроенные функции перечислены в следующих разделах, вместе с их синтаксисом и замечаниями по использованию.

8.1.1. ABS

Синтаксис функции ABS

 ABS(number)
 ~~~

Эта функция определяет и возвращает абсолютное значение числа (числового литерала или элемента данных), переданного в качестве аргумента.

Обратите внимание, что ABSOLUTE-VALUE имеет псевдоним для этой функции.

8.1.2. ACOS

Синтаксис функции ACOS

 ACOS(cosine)
 ~~~~

Функция ACOS определяет и возвращает тригонометрический арккосинус, или обратный косинус, значения косинуса (числового литерала или элемента данных), переданного в качестве аргумента.

Результат будет углом, выраженным в радианах. Вы можете преобразовать это в угол, измеренный в градусах, следующим образом:

COMPUTE degrees = ( radians * 180 ) / FUNCTION PI

8.1.3. ANNUITY

Синтаксис функции ANNUITY

 ANNUITY(interest-rate, number-of-periods)
 ~~~~~~~

Эта функция возвращает числовое значение, приближённо равное отношению аннуитета, выплачиваемого со ставкой interest-rate (числовой элемент данных или литерал) в течение каждого из number-of-periods (числовые элементы данных или литералы).

interest-rate — это процентная ставка, начисляемая при каждом платеже. Если у вас есть только годовая процентная ставка, и вы хотите вычислить ежемесячные аннуитетные платежи, разделите годовую процентную ставку на 12 и используйте это значение для interest-rate.

Умножьте результат этой функции на желаемую сумму основного долга, чтобы определить сумму платежа за каждый период.

Примечание для тех, кто не очень разбирается в финансах: аннуитет — это, по сути, обратный кредит; бухгалтер мог бы взять результат этой функции, умноженный на -1 и на сумму основного долга, чтобы рассчитать платеж по кредиту, который вы вносите.

8.1.4. ASIN

Синтаксис функции ASIN

 ASIN(sine)
 ~~~~

Функция ASIN определяет и возвращает тригонометрический арксинус, или обратный синус, значения sine (числовой литерал или элемент данных), заданного в качестве аргумента.

Результат будет углом, выраженным в радианах. Вы можете преобразовать его в угол, измеренный в градусах, следующим образом:

COMPUTE degrees = ( radians * 180 ) / FUNCTION PI

8.1.5. ATAN

Синтаксис функции ATAN

 ATAN(tangent)
 ~~~~

Используйте эту функцию для определения и возврата тригонометрического арктангенса, или обратного тангенса, значения tangent (числовой литерал или элемент данных), заданного в качестве аргумента.

Результат будет углом, выраженным в радианах. Вы можете преобразовать его в угол, измеренный в градусах, следующим образом:

COMPUTE degrees = ( radians * 180 ) / FUNCTION PI

8.1.6. BYTE-LENGTH

Синтаксис функции BYTE-LENGTH

 BYTE-LENGTH(string)
 ~~~~~~~~~~~

BYTE-LENGTH возвращает длину — в байтах — строки string (групповой элемент, USAGE DISPLAY элементарный элемент или буквенно-цифровой литерал). Эта встроенная функция идентична функции LENGTH-AN (см. LENGTH-AN). Обратите внимание, что возвращаемое значение этой функции не обязательно является количеством символов, составляющих string, а скорее количеством фактических байтов, необходимых для его хранения.

Например, если string закодирован с использованием набора символов с двойной шириной, такого как Unicode UTF-16 (где каждый символ представлен 16 битами памяти, а не 8 битами, присущими таким наборам символов, как ASCII или EBCDIC), то вызов этой функции со строковым аргументом string, чей PICTURE (см. PICTURE) равен X(4) вернёт значение 8, а не 4.

Противопоставьте это функции LENGTH (см. LENGTH).

8.1.7. CHAR

Синтаксис функции CHAR

 CHAR(integer)
 ~~~~

Эта функция возвращает символ в порядковой позиции, указанной integer (числовой целочисленный литерал или элемент данных со значением 1 или больше), из используемого программой набора символов COLLATING SEQUENCE (см. OBJECT-COMPUTER).

Например, если программа использует (по умолчанию) набор символов ASCII, CHAR(34) возвращает 34-й символ в наборе символов ASCII — знак восклицания (‘!’). Если вы используете эту функцию для преобразования числового значения в соответствующий символ ASCII, вы должны использовать значение аргумента на единицу больше числового значения.

Если указан аргумент со значением меньше 1 или больше 256, возвращается символ в последовательности сортировки программы, соответствующий значению всех нулевых битов.

Следующий код является альтернативным подходом, когда вы просто хотите преобразовать число в его эквивалент ASCII:

01  Char-Value.
    05 Numeric-Value        USAGE BINARY-CHAR.
…
    MOVE numeric-character-value TO Numeric-Value

Элемент Char-Value теперь имеет соответствующее значение символа ASCII.

8.1.8. COMBINED-DATETIME

Синтаксис функции COMBINED-DATETIME

 COMBINED-DATETIME(days, seconds)
 ~~~~~~~~~~~~~~~~~

Эта функция возвращает 12-значный числовой результат, первые семь цифр которого — целое значение аргумента days (элемент числовых данных или литерал), а последние пять — целое значение аргумента seconds (также элемент числовых данных или литерал).

Если days меньше 1 или больше 3 067 671, или если seconds меньше 1 или больше 86 400, возвращается значение 0, и произойдёт ошибка выполнения.

8.1.9. CONCATENATE

Синтаксис функции CONCATENATE

 CONCATENATE(string-1 [, string-2 ]...)
 ~~~~~~~~~~~

Эта функция конкатенирует string-1, string-2, … (групповые элементы, USAGE DISPLAY элементарные элементы и/или буквенно-цифровые литералы) в одну строку-результат.

Если в качестве аргумента указан числовой литерал или PIC 9 идентификатор, десятичные точки, если они есть, будут удалены, а знак «минус» в PIC S9 полях или числовых литералах будут вставлены так, как определено в SIGN IS (см. SIGN IS) пункте (или отсутствии такового). Числовые литералы обрабатываются так, как будто SIGN IS TRAILING SEPARATE вступило в силу.

8.1.10. COS

Синтаксис функции COS

 COS(angle)
 ~~~

Функция COS определяет и возвращает тригонометрический косинус значения angle (числовой литерал или элемент данных), заданного в качестве аргумента.

угол предполагается, что значение выражено в радианах. Если вам нужно определить косинус угла, измеренного в градусах, вам сначала необходимо преобразовать этот угол в радианы следующим образом:

COMPUTE radians = ( degrees * FUNCTION PI) / 180

8.1.11. СИМВОЛ_ВАЛЮТЫ

Синтаксис функции СИМВОЛ_ВАЛЮТЫ

 CURRENCY-SYMBOL
 ~~~~~~~~~~~~~~~

Функция CURRENCY-SYMBOL возвращает символ валюты, который в настоящее время действует для региональных параметров, в соответствии с которыми выполняется ваша программа. В системах UNIX ваш регион устанавливается с помощью переменной среды LANG (см. Переменные среды выполнения) переменной среды. В Windows регион определяется в Панели управления в разделе «Региональные и языковые параметры».

Изменение символа валюты с помощью SPECIAL-NAMES (см. СПЕЦИАЛЬНЫЕ_ИМЕНА) параметра CURRENCY SYMBOL не повлияет на значение, возвращаемое этой функцией.

8.1.12. ТЕКУЩАЯ_ДАТА

Синтаксис функции ТЕКУЩАЯ_ДАТА

 CURRENT-DATE
 ~~~~~~~~~~~~

Возвращает текущую дату и время в следующем формате 21-символьной структуры:

01  CURRENT-DATE-AND-TIME.
    05 CDT-Year                PIC 9(4).
    05 CDT-Month               PIC 9(2). *> 01-12
    05 CDT-Day                 PIC 9(2). *> 01-31
    05 CDT-Hour                PIC 9(2). *> 00-23
    05 CDT-Minutes             PIC 9(2). *> 00-59
    05 CDT-Seconds             PIC 9(2). *> 00-59
    05 CDT-Hundredths-Of-Secs  PIC 9(2). *> 00-99
    05 CDT-GMT-Diff-Hours      PIC S9(2)
                               SIGN LEADING SEPARATE.
    05 CDT-GMT-Diff-Minutes    PIC 9(2). *> 00 or 30

Поскольку эта функция не имеет аргументов, скобки не должны быть указаны.

8.1.13. ДАТА_ОТ_ЦЕЛОГО

Синтаксис функции ДАТА_ОТ_ЦЕЛОГО

 DATE-OF-INTEGER(integer)
 ~~~~~~~~~~~~~~~

Эта функция возвращает числовую календарную дату в формате ггггммдд (т.е. григорианском). Дата определяется путем добавления количества дней, указанных как целое (числовой целочисленный элемент данных или литерал), к дате 31 декабря 1600 года. Например, DATE-OF-INTEGER(1) возвращает 16010101, а DATE-OF-INTEGER(150000) возвращает 20110908.

Значение меньше 1 или больше 3067671 (9999/12/31) вернёт 0.

8.1.14. ДАТА_В_ГГГГММДД

Синтаксис функции ДАТА_В_ГГГГММДД

 DATE-TO-YYYYMMDD(yymmdd [, yy-cutoff [, yy-execution-time ]])
 ~~~~~~~~~~~~~~~~

Вы можете использовать эту функцию для преобразования шестизначной григорианской даты, указанной как ггммдд (числовой целочисленный элемент данных или литерал), в восьмизначный формат (ггггммдд).

Необязательный аргумент гг-порог (числовой целочисленный элемент данных или литерал) представляет собой год-порог, используемый для определения столетий; если компонент года даты достигает или превышает это значение порога, результатом будет 19ггммдд; если компонент года даты меньше значения порога, результатом будет 20ггммдд. Значение порога по умолчанию, если второй аргумент не задан, будет 50.

Необязательный аргумент гг-время_выполнения (числовой целочисленный элемент данных или литерал) Значение времени выполнения по умолчанию, если третий аргумент не задан, будет эквивалентно указанию (FUNCTION NUMVAL (FUNCTION CURRENT-DATE (1:4))).

8.1.15. ДЕНЬ_ОТ_ЦЕЛОГО

Синтаксис функции ДЕНЬ_ОТ_ЦЕЛОГО

 DAY-OF-INTEGER(integer)
 ~~~~~~~~~~~~~~

Эта функция возвращает календарную дату в формате ггггддд (т.е. юлианском). Дата определяется путем добавления числа дней, указанных как целое (числовой целочисленный элемент данных или литерал), к 31 декабря 1600 года. Например, DAY-OF-INTEGER(1) возвращает 1601001, а DAY-OF-INTEGER(250000) возвращает 2011251.

Значение меньше 1 или больше 3067671 (9999/12/31) вернёт 0.

8.1.16. ДЕНЬ_В_ГГГГДДД

Синтаксис функции ДЕНЬ_В_ГГГГДДД

 DAY-TO-YYYYDDD(yyddd [, yy-cutoff [, yy-execution-time ]])
 ~~~~~~~~~~~~~~

Вы можете использовать эту функцию для преобразования пятизначной юлианской даты, указанной как ггддд (числовой целочисленный элемент данных или литерал), в семизначный числовой юлианский формат (ггггддд).

Необязательный аргумент гг-порог (числовой целочисленный элемент данных или литерал) представляет собой год-порог, используемый для определения столетий; если компонент года даты достигает или превышает это значение порога, результатом будет 19ггддд; если компонент года даты меньше, результатом будет 20ггддд. Значение порога по умолчанию, если второй аргумент не задан, будет 50.

Необязательный аргумент гг-время_выполнения (числовой целочисленный элемент данных или литерал) Значение времени выполнения по умолчанию, если третий аргумент не задан, будет эквивалентно указанию (FUNCTION NUMVAL (FUNCTION CURRENT-DATE (1:4))).

8.1.17. E

Синтаксис функции E

 E
 ~

Эта функция возвращает математическую константу E (основание натуральных логарифмов). Максимальная точность, с которой может быть возвращено это значение, составляет 2.7182818284590452353602874713526625.

Поскольку эта функция не имеет аргументов, скобки не должны быть указаны.

8.1.18. ФАЙЛ_ИСКЛЮЧЕНИЯ

Синтаксис функции ФАЙЛ_ИСКЛЮЧЕНИЯ

 EXCEPTION-FILE
 ~~~~~~~~~~~~~~

Эта функция возвращает информацию об исключениях ввода-вывода из последней выполненной инструкции ввода-вывода. Информация возвращается как строка из 34 символов, где первые два символа — это двухзначное значение состояния файла (см. Коды статуса файла), а оставшиеся 32 — это спецификация имя_файла-1 из спецификации файла из инструкции SELECT (см. SELECT).

Имя, возвращаемое после информации о состоянии файла, будет возвращено только в том случае, если возвращенное значение состояния файла не равно 00.

Документация встроенной системной подпрограммы CBL_ERROR_PROC (см. CBL_ERROR_PROC) демонстрирует использование этой функции.

8.1.19. МЕСТОПОЛОЖЕНИЕ_ИСКЛЮЧЕНИЯ

Синтаксис функции МЕСТОПОЛОЖЕНИЕ_ИСКЛЮЧЕНИЯ

 EXCEPTION-LOCATION
 ~~~~~~~~~~~~~~~~~~

Эта функция возвращает информацию об исключении из последнего некорректно выполненного оператора. Информация возвращается в строке длиной до 1023 символов в одном из следующих форматов, в зависимости от природы ошибки:

  • имя_главной_точки_входа; абзац РАЗДЕЛА; номер_оператора
  • имя_главной_точки_входа; раздел; номер_оператора
  • имя_главной_точки_входа; абзац; номер_оператора
  • имя_главной_точки_входа; номер_оператора

Поскольку эта функция не принимает аргументов, скобки указывать не следует.

Для получения осмысленной информации от этой функции программа должна быть скомпилирована со флагом -debug, -ftraceall или -g.

Использование этой функции проиллюстрировано в документации встроенной системной подпрограммы CBL_ERROR_PROC (см. CBL_ERROR_PROC).

8.1.20. ОПЕРАТОР_ИСКЛЮЧЕНИЯ

Синтаксис функции ОПЕРАТОР_ИСКЛЮЧЕНИЯ

 EXCEPTION-STATEMENT
 ~~~~~~~~~~~~~~~~~~~

Эта функция возвращает последний оператор COBOL, который сгенерировал условие исключения.

Поскольку эта функция не принимает аргументов, скобки указывать не следует.

Для получения осмысленной информации от этой функции программа должна быть скомпилирована со флагом -debug, -ftraceall или -g.

Использование этой функции проиллюстрировано в документации встроенной системной подпрограммы CBL_ERROR_PROC (см. CBL_ERROR_PROC).

8.1.21. СТАТУС_ИСКЛЮЧЕНИЯ

Синтаксис функции СТАТУС_ИСКЛЮЧЕНИЯ

 EXCEPTION-STATUS
 ~~~~~~~~~~~~~~~~

Эта функция возвращает тип ошибки (текстовая строка — см. столбец 2 следующей таблицы для возможных значений) из последнего оператора COBOL, который сгенерировал условие исключения.

Поскольку эта функция не принимает аргументов, скобки указывать не следует.

Использование этой функции проиллюстрировано в документации встроенной системной подпрограммы CBL_ERROR_PROC (см. CBL_ERROR_PROC).

Ниже приведены строки типа ошибки, их соответствующие коды исключений и описания.

Код Тип ошибки Описание
0101 EC-ARGUMENT-FUNCTION Ошибка аргумента функции
0202 EC-BOUND-ODO OCCURS … DEPENDING индекс элемента данных выходит за пределы
0204 EC-BOUND-PTR Указатель данных содержит адрес, выходящий за пределы допустимого диапазона
0205 EC-BOUND-REF-MOD Выход модификатора ссылки за пределы допустимого диапазона
0207 EC-BOUND-SUBSCRIPT Индекс выходит за пределы допустимого диапазона
0303 EC-DATA-INCOMPATIBLE Исключение несовместимых данных
0500 EC-I-O Исключение ввода-вывода
0501 EC-I-O-AT-END Статус ВВОД/ВЫВОД 1x
0502 EC-I-O-EOP Произошло условие конца страницы
0504 EC-I-O-FILE-SHARING Статус ВВОД/ВЫВОД 6x
0505 EC-I-O-IMP Статус ВВОД/ВЫВОД 9x
0506 EC-I-O-INVALID-KEY Статус ВВОД/ВЫВОД 2x
0508 EC-I-O-LOGIC-ERROR Статус ВВОД/ВЫВОД 4x
0509 EC-I-O-PERMANENT-ERROR Статус ВВОД/ВЫВОД 3x
050A EC-I-O-RECORD-OPERATION Статус ВВОД/ВЫВОД 5x
0601 EC-IMP-ACCEPT Условие принятия, определённое реализацией
0602 EC-IMP-DISPLAY Условие отображения, определённое реализацией
0A00 EC-OVERFLOW Условие переполнения
0A02 EC-OVERFLOW-STRING STRING условие переполнения
0A03 EC-OVERFLOW-UNSTRING UNSTRING условие переполнения
0B05 EC-PROGRAM-NOT-FOUND Вызываемая программа не найдена
0D03 EC-RANGE-INSPECT-SIZE Размер заменяемого элемента в инспектировании отличается
1000 EC-SIZE Исключение ошибки размера
1004 EC-SIZE-OVERFLOW Арифметическое переполнение при вычислении
1005 EC-SIZE-TRUNCATION Отброшенные значащие цифры при сохранении
1007 EC-SIZE-ZERO-DIVIDE Деление на ноль
1202 EC-STORAGE-NOT-ALLOC Указатель данных, заданный в инструкции FREE, не идентифицирует выделенную память
1203 EC-STORAGE-NOT-AVAIL Запрошенное объём памяти инструкцией ALLOCATE недоступен

8.1.22. EXP

EXP Функция Синтаксис

 EXP(number)
 ~~~

Вычисляет и возвращает значение математической константы e, возведенной в степень, указанную в number (числовой литерал или элемент данных).

8.1.23. EXP10

EXP10 Функция Синтаксис

 EXP10(number)
 ~~~~~

Вычисляет и возвращает значение 10, возведенное в степень, указанную в number (числовой литерал или элемент данных).

8.1.24. FACTORIAL

FACTORIAL Функция Синтаксис

 FACTORIAL(number)
 ~~~~~~~~~

Эта функция вычисляет и возвращает факториал значения number (числовой литерал или элемент данных).

8.1.25. FORMATTED-CURRENT-DATE

FORMATTED-CURRENT-DATE Функция Синтаксис

 FORMATTED-CURRENT-DATE ( argument-1 )
 ~~~~~~~~~~~~~~~~~~~~~~

FORMATTED-CURRENT-DATE возвращает текущую дату и время, предоставленные системой во время выполнения, отформатированные в соответствии с форматом даты и времени в зависимости от типа аргумента.

Аргумент функции должен быть национальным или буквенно-цифровым литералом, а содержимое – объединённым форматом даты и времени.

Возвращаемое значение отформатировано так же, как и argument-1.

8.1.26. FORMATTED-DATE

FORMATTED-DATE Функция Синтаксис

 FORMATTED-DATE ( argument-1, argument-2 )
 ~~~~~~~~~~~~~~

FORMATTED-DATE использует формат для преобразования даты в целочисленном формате даты в дату в запрошенном формате. Возвращаемое значение будет в формате даты.

argument-1 должен быть национальным или буквенно-цифровым литералом.

argument-2 должен быть значением в целочисленном формате даты.

8.1.27. FORMATTED-DATETIME

Функция FORMATTED-DATETIME Синтаксис

 FORMATTED-DATETIME ( argument-1, argument-2, argument-3, argument-4 )
 ~~~~~~~~~~~~~~~~~~

FORMATTED-DATETIME использует комбинированный формат времени и даты для преобразования и объединения даты в целочисленном формате и числового времени, выраженного в секундах после полуночи по UTC.

argument-1 должен быть национальным или буквенно-цифровым литералом.

argument-2 должен быть значением в целочисленном формате даты.

argument-3 должен быть значением в стандартном числовом формате времени.

argument-4 — целое число, определяющее смещение от UTC в минутах. Если указано, но имеет значение, равное или меньшее 1439.

Примечание: значение смещения 1439 представляет 23 часа 59 минут, что на одну минуту меньше, чем один день.

argument-4 не должен быть указан, если часть времени в argument-1 не является форматом UTC или смещения.

Возвращаемое значение — представление даты, содержащейся в argument-2, соединенной со временем, содержащимся в argument-3, в соответствии с форматом в argument-1.

Если формат в argument-1 указывает, что возвращаемое значение должно быть выражено в UTC, часть времени возвращаемого значения отражает корректировку значения в argument-3 смещением в argument-4.

Если формат в argument-1 указывает, что время должно быть возвращено как смещение от UTC, значение в argument-3 отражается непосредственно в части времени возвращаемого значения, а смещение в argument-4 отражается непосредственно в части смещения возвращаемого значения.

8.1.28. FORMATTED-TIME

Функция FORMATTED-TIME Синтаксис

 FORMATTED-TIME ( argument-1, argument-2, argument-3 )
 ~~~~~~~~~~~~~~

FORMATTED-TIME преобразует значение, представляющее секунды после полуночи, отформатированное время суток с необязательным смещением.

argument-1 должен быть национальным или буквенно-цифровым литералом.

argument-2 должен быть значением в целочисленном формате времени.

argument-3 — целое число, определяющее смещение от UTC в минутах. Если указано, но имеет значение, равное или меньшее 1439.

Примечание: значение смещения 1439 представляет 23 часа 59 минут, что на одну минуту меньше, чем один день.

argument-3 не должен быть указан, если часть времени в argument-1 не является форматом UTC или смещения.

Возвращаемое значение:

Представляет собой представление стандартного числового времени, содержащегося в argument-2, в соответствии с форматом в argument-1.

Если формат в argument-1 указывает, что возвращаемое значение должно быть выражено в UTC, часть времени возвращаемого значения отражает корректировку значения в argument-2 смещением в argument-3.

Если формат в argument-1 указывает, что время должно быть возвращено как смещение от UTC, значение в argument-2 отражается непосредственно в части времени возвращаемого значения, а смещение в argument-3 отражается непосредственно в части смещения возвращаемого значения.

8.1.29. FRACTION-PART

Функция FRACTION-PART Синтаксис

 FRACTION-PART(number)
 ~~~~~~~~~~~~~

Эта функция возвращает часть number (элемента данных числового типа или числового литерала), которая находится справа от десятичной точки. FRACTION-PART(3.1415), например, возвращает значение 0,1415. Эта функция эквивалентна выражению:

number -- FUNCTION INTEGER-PART(number)

8.1.30. HIGHEST-ALGEBRAIC

Функция HIGHEST-ALGEBRAIC Синтаксис

 HIGHEST-ALGEBRAIC(numeric-identifier)
 ~~~~~~~~~~~~~~~~~

Эта функция возвращает наибольшее (т. е. наибольшее или самое удаленное от 0 в положительном направлении, если numeric-identifier имеет знак) значение, которое может быть хранено в numeric-identifier.

8.1.31. INTEGER

Функция INTEGER Синтаксис

 INTEGER(number)
 ~~~~~~~

Функция INTEGER возвращает наибольшее целое значение, которое меньше или равно number (числовому литералу или элементу данных).

8.1.32. INTEGER-OF-DATE

Функция INTEGER-OF-DATE Синтаксис

 INTEGER-OF-DATE(date)
 ~~~~~~~~~~~~~~~

Эта функция преобразует date (элемент данных числового целого типа или литерал), предположительно представляющий стандартную дату григорианского календаря (ГГГГММДД), в внутренний формат даты (количество дней, прошедших с 1600/12/31).

После этого математические операции могут быть выполнены над внутренней датой перед преобразованием её обратно в дату с использованием функции DATE-OF-INTEGER (см. DATE-OF-INTEGER) или DAY-OF-INTEGER (см. DAY-OF-INTEGER).

8.1.33. INTEGER-OF-DAY

Функция INTEGER-OF-DAY Синтаксис

 INTEGER-OF-DAY(date)
 ~~~~~~~~~~~~~~

Эта функция преобразует date (элемент данных числового целого типа или литерал), предположительно представляющий стандартную дату юлианского календаря (ГГГГДДД), во внутренний формат даты (количество дней, прошедших с 1600/12/31).

После приведения к этому формату, над внутренней датой можно выполнить математические операции перед преобразованием её обратно в дату с использованием функции DATE-OF-INTEGER (см. DATE-OF-INTEGER) или DAY-OF-INTEGER (см. DAY-OF-INTEGER).

8.1.34. INTEGER-OF-FORMATTED-DATE

INTEGER-OF-FORMATTED-DATE Функция синтаксиса

 INTEGER-OF-FORMATTED-DATE ( argument-1, argument-2 )
 ~~~~~~~~~~~~~~~~~~~~~~~~~

INTEGER-OF-FORMATTED-DATE преобразует дату, которая находится в заданном формате, в целочисленную форму даты.

argument-1 должен быть национальным или буквенно-цифровым литералом. Содержимое должно быть либо форматом даты, либо комбинированным форматом даты и времени.

argument-2 должен быть элементом данных того же типа, что и argument-1.

Если argument-1 представляет собой формат даты, содержимое argument-2 должно быть допустимой датой в этом формате.

Если argument-1 представляет собой комбинированный формат даты и времени, содержимое argument-2 должно быть допустимым комбинированным форматом даты и времени в том же формате.

8.1.35. INTEGER-PART

INTEGER-PART Функция синтаксиса

 INTEGER-PART(number)
 ~~~~~~~~~~~~

Возвращает целую часть числа (числового литерала или элемента данных).

8.1.36. LENGTH

LENGTH Функция синтаксиса

 LENGTH(string)
 ~~~~~~

Возвращает длину — в символах — строки (элемента группы, USAGE DISPLAY элементарного элемента или буквенно-цифрового литерала).

Значение, возвращаемое этой функцией, не является количеством байтов памяти, занимаемой строкой, а скорее количеством фактических символов, составляющих строку. Например, если строка закодирована с использованием набора символов с двойной длиной, такого как Unicode UTF-16 (где каждый символ представлен 16 битами памяти, а не 8 битами, присущими наборам символов, таким как ASCII или EBCDIC), тогда вызов этой функции с аргументом строки, чьё PICTURE is X(4) вернёт значение 4, а не 8 (фактическое количество байтов памяти, занимаемой этим элементом).

Сравните эту функцию с функциями BYTE-LENGTH (см. BYTE-LENGTH) и LENGTH-AN (см. LENGTH-AN).

8.1.37. LENGTH-AN

LENGTH-AN Функция синтаксиса

 LENGTH-AN(string)
 ~~~~~~~~~

Эта функция возвращает длину — в байтах памяти — строки (элемента группы, USAGE DISPLAY элементарного элемента или буквенно-цифрового литерала).

Эта встроенная функция идентична функции BYTE-LENGTH (см. BYTE-LENGTH).

Обратите внимание, что возвращаемое значение этой функции не является количеством символов, составляющих строку, а количеством фактических байтов памяти, необходимых для хранения строки. Например, если строка закодирована с использованием набора символов с двойной длиной, такого как Unicode UTF-16 (где каждый символ представлен 16 битами памяти, а не 8 битами, присущими наборам символов, таким как ASCII или EBCDIC), тогда вызов этой функции с аргументом строки, чьё PICTURE is X(4) вернёт значение 8, а не 4.

Сравните с функцией LENGTH (см. LENGTH).

8.1.38. LOCALE-COMPARE

LOCALE-COMPARE Функция синтаксиса

 LOCALE-COMPARE(argument-1, argument-2 [ , locale ])
 ~~~~~~~~~~~~~~

Функция LOCALE-COMPARE возвращает символ, указывающий на результат сравнения argument-1 и argument-2 с использованием упорядочивания, предпочитаемого культурой, определённого locale.

Любой или оба из первых двух аргументов могут быть буквенно-цифровым литералом, элементом группы или элементарным элементом, подходящим для хранения буквенных или буквенно-цифровых данных. Если длины двух аргументов не равны, более короткая предполагается дополненной справа пробелами.

Два аргумента будут сравниваться посимвольно друг с другом, пока не будет определено их взаимоотношение. Сравнение выполняется в соответствии с культурными правилами, действующими для locale имени или для текущего locale, если аргумент locale не указан. Как только это отношение будет определено, возвращаемое буквенно-цифровое значение будет следующим:

  • ‘<’ — Если argument-1 определяется как меньше argument-2
  • ‘=’ — Если два аргумента равны друг другу
  • ‘>’ — Если argument-1 определяется как больше argument-2

См. LOCALE Имена для списка обычно доступных имён locale.

8.1.39. LOCALE-DATE

LOCALE-DATE Функция синтаксиса

 LOCALE-DATE(date [, locale ])
 ~~~~~~~~~~~

Преобразует восьмизначный григорианский date (числовой целочисленный элемент данных или литерал) из формата yyyymmdd в формат, соответствующий текущему locale. В системе Windows это будет формат «короткая дата», установленный в Панели управления.

Вы можете включить необязательный второй аргумент для указания имени locale (элемент группы или PIC X идентификатор), который вы хотите использовать для форматирования даты. Если используется, этот второй аргумент обязательно должен быть идентификатором. Имена locale задаются с использованием стандартных имён UNIX.

8.1.40. LOCALE-TIME

LOCALE-TIME Функция синтаксиса

 LOCALE-TIME(time [, locale ])
 ~~~~~~~~~~~

Преобразует четырёхзначное (ччмм) или шестизначное (ччммсс) значение time (числовой целочисленный элемент данных или литерал) в формат, соответствующий текущему языковому стандарту. В системах Windows это будет формат «время», установленный в панели управления.

Можно указать необязательное имя locale (элемент группы или PIC X идентификатор), которое нужно использовать для форматирования времени. Если используется, этот второй аргумент обязательно должен быть идентификатором. Имена языковых стандартов задаются с использованием стандартных имён UNIX.

8.1.41. LOCALE-TIME-FROM-SECONDS

LOCALE-TIME-FROM-SECONDS Синтаксис функции

 LOCALE-TIME-FROM-SECONDS(seconds [, locale ])
 ~~~~~~~~~~~~~~~~~~~~~~~~

Преобразует количество секунд с полуночи (числовой целочисленный элемент данных или литерал) в формат, соответствующий текущему языковому стандарту. В системах Windows это будет формат «время», установленный в панели управления.

Можно указать необязательное имя locale (элемент группы или PIC X идентификатор), которое нужно использовать для форматирования времени. Если используется, этот второй аргумент обязательно должен быть идентификатором. Имена языковых стандартов задаются с использованием стандартных имён UNIX.

См. Имена языковых стандартов для списка доступных имен языковых стандартов.

8.1.42. LOG

LOG Синтаксис функции

 LOG(number)
 ~~~

Вычисляет и возвращает натуральный логарифм (по основанию e) от number (числовая литерал или элемент данных).

8.1.43. LOG10

LOG10 Синтаксис функции

 LOG10(number)
 ~~~~~

Вычисляет и возвращает логарифм по основанию 10 от number (числовая литерал или элемент данных).

8.1.44. LOWER-CASE

LOWER-CASE Синтаксис функции

 LOWER-CASE(string)
 ~~~~~~~~~~

Эта функция возвращает значение string (элемент группы, USAGE DISPLAY элемент или буквенно-цифровая литерал), полностью преобразованное в нижний регистр.

Что считается «буквой» (или заглавной/строчной, в таком случае) может влиять на использование CHARACTER CLASSIFICATION (см. ОБЪЕКТ-КОМПЬЮТЕР).

8.1.45. LOWEST-ALGEBRAIC

LOWEST-ALGEBRAIC Синтаксис функции

 LOWEST-ALGEBRAIC(numeric-identifier)
 ~~~~~~~~~~~~~~~~

Эта функция возвращает наименьшее (т.е. самое маленькое или самое удалённое от 0 в отрицательном направлении, если numeric-identifier имеет знак) значение, которое может быть хранено в numeric-identifier.

8.1.46. MAX

MAX Синтаксис функции

 MAX(number-1 [, number-2 ]...)
 ~~~

Эта функция возвращает максимальное значение из указанного списка чисел (каждое number-n может быть числовым элементом данных или числовой литерал).

8.1.47. MEAN

MEAN Синтаксис функции

 MEAN(number-1 [, number-2 ]...)
 ~~~~

Эта функция возвращает среднее статистическое значение указанного списка чисел (каждое number-n может быть числовым элементом данных или числовой литерал).

8.1.48. MEDIAN

MEDIAN Синтаксис функции

 MEDIAN(number-1 [, number-2 ]...)
 ~~~~~~

Эта функция возвращает медианное статистическое значение указанного списка чисел (каждое number-n может быть числовым элементом данных или числовой литерал).

8.1.49. MIDRANGE

MIDRANGE Синтаксис функции

 MIDRANGE(number-1 [, number-2 ]...)
 ~~~~~~~~

Функция MIDRANGE (средний диапазон) возвращает числовое значение, которое является средним арифметическим (средним) значений минимального и максимального чисел из предоставленного списка. Каждое number-n может быть числовым элементом данных или числовой литерал.

8.1.50. MIN

MIN Синтаксис функции

 MIN(number-1 [, number-2 ]...)
 ~~~

Эта функция возвращает минимальное значение из указанного списка чисел (каждое number-n может быть числовым элементом данных или числовой литерал).

8.1.51. MOD

MOD Синтаксис функции

 MOD(value, modulus)
 ~~~

Эта функция возвращает значение value по модулю modulus (в сущности остаток от деления value на modulus). Оба аргумента могут быть числовыми элементами данных или числовыми литералами. Любой (или оба) может иметь нецелое значение.

8.1.52. MODULE-CALLER-ID

MODULE-CALLER-ID Синтаксис функции

 MODULE-CALLER-ID
 ~~~~~~~~~~~~~~~~

Эта функция возвращает пустую строку, если она выполняется в основной программе. При выполнении с подпрограммой она возвращает имя точки входа программы, которая вызвала подпрограмму.

Описание функции MODULE-TIME (см. MODULE-TIME) включает пример программы, использующей эту функцию.

Поскольку у этой функции нет аргументов, скобки не должны указываться.

8.1.53. MODULE-DATE

MODULE-DATE Синтаксис функции

 MODULE-DATE
 ~~~~~~~~~~~

Эта функция возвращает дату компиляции программы GnuCOBOL, которая выполняет функцию, в формате ггггммдд.

Описание функции MODULE-TIME (см. MODULE-TIME) включает пример программы, использующей эту функцию.

Поскольку у этой функции нет аргументов, скобки не должны указываться.

8.1.54. MODULE-FORMATTED-DATE

MODULE-FORMATTED-DATE Синтаксис функции

 MODULE-FORMATTED-DATE
 ~~~~~~~~~~~~~~~~~~~~~

Эта функция возвращает полностью отформатированную дату и время компиляции программы, которая выполняет функцию. Точный формат возвращаемой строковой величины может отличаться в зависимости от операционной системы и типа сборки GnuCOBOL.

Обсуждение функции MODULE-TIME (см. MODULE-TIME) включает пример программы, использующей эту функцию.

Поскольку эта функция не имеет аргументов, скобки не должны указываться.

8.1.55. MODULE-ID

Синтаксис функции MODULE-ID

 MODULE-ID
 ~~~~~~~~~

Эта функция возвращает имя основного точки входа (т. е. PROGRAM-ID или FUNCTION-ID программы). См. IDENTIFICATION DIVISION для информации об этих пунктах.

Обсуждение функции MODULE-TIME (см. MODULE-TIME) включает пример программы, использующей эту функцию.

Поскольку эта функция не имеет аргументов, скобки не должны указываться.

8.1.56. MODULE-PATH

Синтаксис функции MODULE-PATH

 MODULE-PATH
 ~~~~~~~~~~~

Эта функция возвращает полный путь к исполняемому файлу этой программы GnuCOBOL. Компонент имени файла в этом значении будет точно таким, как набрано в командной строке, вплоть до использования прописных и строчных букв и наличия (или отсутствия) расширения.

Обсуждение функции MODULE-TIME (см. MODULE-TIME) включает пример программы, использующей эту функцию.

Поскольку эта функция не имеет аргументов, скобки не должны указываться.

8.1.57. MODULE-SOURCE

Синтаксис функции MODULE-SOURCE

 MODULE-SOURCE
 ~~~~~~~~~~~~~

Имя файла исходного кода программы (как указано в командной строке cobc при компиляции программы) возвращается этой функцией.

Обсуждение функции MODULE-TIME (см. MODULE-TIME) включает пример программы, использующей эту функцию.

Поскольку эта функция не имеет аргументов, скобки не должны указываться.

8.1.58. MODULE-TIME

Синтаксис функции MODULE-TIME

 MODULE-TIME
 ~~~~~~~~~~~

Эта функция возвращает время компиляции программы GnuCOBOL в формате ччммсс.

Поскольку эта функция не имеет аргументов, скобки не должны указываться.

Следующая примерная программа использует все функции MODULE-:

IDENTIFICATION DIVISION.
PROGRAM-ID. DEMOMODULE.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
    FUNCTION ALL INTRINSIC.
PROCEDURE DIVISION.
000-Main.
    DISPLAY "MODULE-CALLER-ID      = [" MODULE-CALLER-ID ‘]’
    DISPLAY "MODULE-DATE           = [" MODULE-DATE ‘]’
    DISPLAY "MODULE-FORMATTED-DATE = [" MODULE-FORMATTED-DATE ‘]’
    DISPLAY "MODULE-ID             = [" MODULE-ID ‘]’
    DISPLAY "MODULE-PATH           = [" MODULE-PATH ‘]’
    DISPLAY "MODULE-SOURCE         = [" MODULE-SOURCE ‘]’
    DISPLAY "MODULE-TIME           = [" MODULE-TIME ‘]’
    STOP RUN
    .

Программа выводит такой результат при выполнении:

MODULE-CALLER-ID = []
MODULE-DATE = [20180522]
MODULE-FORMATTED-DATE = [May 22 2018 12:43:14]
MODULE-ID = [DEMOMODULE]
MODULE-PATH = [/home/vince/cobolsrc/ACAS/demomodule]
MODULE-SOURCE = [demomodule.cbl]
MODULE-TIME = [124314]

8.1.59. MONETARY-DECIMAL-POINT

Синтаксис функции MONETARY-DECIMAL-POINT

 MONETARY-DECIMAL-POINT
 ~~~~~~~~~~~~~~~~~~~~~~

MONETARY-DECIMAL-POINT возвращает символ, используемый для разделения целой части от дробной части значения денежной валюты в соответствии с правилами, действующими для региональных настроек, в которых работает ваша программа.

В системах UNIX (включая OSX, Windows/Cygwin и Windows/MinGW) ваш регион устанавливается посредством переменной среды LANG (см. Переменные среды выполнения). В Windows регион определяется в панели управления в разделе «Язык и региональные параметры».

Использование пункта DECIMAL-POINT IS COMMA (см. SPECIAL-NAMES) в вашей программе не повлияет на значение, возвращаемое этой функцией.

Поскольку эта функция не имеет аргументов, скобки не должны указываться.

8.1.60. MONETARY-THOUSANDS-SEPARATOR

Синтаксис функции MONETARY-THOUSANDS-SEPARATOR

 MONETARY-THOUSANDS-SEPARATOR
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Эта функция возвращает символ, используемый для разделения группировок разрядов тысяч денежных значений в соответствии с правилами, действующими для региональных настроек, в которых работает ваша программа.

В системах UNIX (включая OSX, Windows/Cygwin и Windows/MinGW) ваш регион устанавливается посредством переменной среды LANG (см. Переменные среды выполнения). В Windows регион определяется в панели управления в разделе «Язык и региональные параметры».

Использование пункта DECIMAL-POINT IS COMMA (см. SPECIAL-NAMES) в вашей программе не повлияет на значение, возвращаемое этой функцией.

Поскольку эта функция не имеет аргументов, скобки не должны указываться.

8.1.61. NUMERIC-DECIMAL-POINT

Синтаксис функции NUMERIC-DECIMAL-POINT

 NUMERIC-DECIMAL-POINT
 ~~~~~~~~~~~~~~~~~~~~~

Эта функция возвращает символ, используемый для разделения целой части нецелого числового элемента от дробной части в соответствии с правилами, действующими для региональных настроек, в которых работает ваша программа.

В системах UNIX (включая OSX, Windows/Cygwin и Windows/MinGW) ваш регион устанавливается посредством переменной среды LANG (см. Переменные среды выполнения). В Windows регион определяется в панели управления в разделе «Язык и региональные параметры».

Использование пункта DECIMAL-POINT IS COMMA (см. SPECIAL-NAMES) в вашей программе не повлияет на значение, возвращаемое этой функцией.

Поскольку эта функция не имеет аргументов, скобки не должны указываться.

8.1.62. NUMERIC-THOUSANDS-SEPARATOR

Синтаксис функции NUMERIC-THOUSANDS-SEPARATOR

 NUMERIC-THOUSANDS-SEPARATOR
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~

Эта функция возвращает символ, используемый для разделения группировок разрядов тысяч числовых значений в соответствии с правилами, действующими для региональных настроек, в которых работает ваша программа.

В системах UNIX (включая OSX, Windows/Cygwin и Windows/MinGW) ваш регион устанавливается с помощью переменной среды LANG (см. Переменные среды выполнения) переменной среды. В Windows регион определяется в Панели управления в разделе «Язык и региональные стандарты».

Использование DECIMAL-POINT IS COMMA (см. SPECIAL-NAMES) в вашей программе не повлияет на значение, возвращаемое этой функцией.

Поскольку эта функция не имеет аргументов, не следует указывать скобки.

8.1.63. NUMVAL

Синтаксис функции NUMVAL

 NUMVAL(string)
 ~~~~~~

Функция NUMVAL преобразует строку (элемент группы, USAGE DISPLAY элементарный элемент или буквенно-цифровое литерал) в соответствующее числовое значение.

Строка string должна иметь один из следующих форматов, где «#» представляет последовательность одной или нескольких десятичных цифр:

# -# +# #- #+ #CR #DB
#.# -#.# +#.# #.#- #.#+ #.#CR #.#DB

В строке должно быть как минимум одна цифра.

Допускаются начальные и/или конечные пробелы, а также пробелы перед первой цифрой.

Символ точки в строке argument-1 представляет десятичный разделитель. Символ запятой в argument-1 представляет разделитель групп. При указании DECIMAL-POINT IS COMMA запятая в argument-1 должна представлять десятичный разделитель, а точка – разделитель групп.

Примечание: Эквивалент функциональности, основанной на регионе, аналогично NUMVAL, может быть получен с использованием функции NUMVAL-C с ключевым словом LOCALE. Знак валюты в NUMVAL-C является необязательным. Будет использована категория локали LC_MONETARY, поскольку в категории локали LC_NUMERIC нет указания на соглашение о знаках.

Возвращаемые значения:

Возвращаемое значение – это числовое значение, представленное строкой.

Если она содержит CR, DB, или знак минус (‘-’), возвращаемое значение отрицательное.

8.1.64. NUMVAL-C

Синтаксис функции NUMVAL-C

 NUMVAL-C (string [, symbol               ]
 ~~~~~~~~
                  [, LOCALE locale-name-1 ] [, ANYCASE ])

Эта функция преобразует строку (элемент группы, USAGE DISPLAY элементарный элемент или буквенно-цифровое литерал), представляющую значение валюты, в соответствующее числовое значение.

Любые символы валюты и любые разделители групп, предшествующие десятичному разделителю, игнорируются. При необходимости символы валюты, соглашение о знаках, разделитель групп и десятичный разделитель, разрешённые в строке символов, могут быть определены категорией локали LC-MONETARY, или символы валюты могут быть заданы с помощью символа.

Необязательный символ символ представляет символ валюты (непробельный односимвольный элемент группы, USAGE DISPLAY элементарный элемент или буквенно-цифровое литерал), который может использоваться в качестве символа валюты в строке. Любые пробелы, включая начальные и конечные, игнорируются. Если символ не указан, используется значение, которое вернула бы встроенная функция CURRENCY-SYMBOL (см. CURRENCY-SYMBOL).

Если это относится к LOCALE :

Изменение символа валюты путём настройки SPECIAL-NAMES пункта CURRENCY SYMBOL не повлияет на значение, возвращаемое этой функцией.

В то время как NUMVAL-C всегда будет использовать символ валюты, указанный в пункте SPECIAL-NAMES CURRENCY SYMBOL (или системный по умолчанию, который в настоящее время всегда «$»).

Строка может иметь любой из следующих форматов, где «#» представляет последовательность одной или нескольких десятичных цифр, а «$» представляет символ символа:

# -# +# #- #+ #CR #DB
#.# -#.# +#.# #.#- #.#+ #.#CR #.#DB
$# -$# +$# $#- $#+ $#CR $#DB
$#.# -$#.# +$#.# $#.#- $#.#+ $#.#CR $#.#DB

В строке должно быть как минимум одна цифра.

Допускаются начальные и/или конечные пробелы, а также пробелы перед и/или после символа валюты, знака, символов CR и DB.

Если используется ключевое слово ANYCASE, правила сопоставления для обнаружения строки валюты в argument-1 нечувствительны к регистру. Если ключевое слово ANYCASE не указано, правила сопоставления чувствительны к регистру.

Если ни символ, ни ключевое слово LOCALE не указаны, будет использоваться только одна строка валюты, либо знак валюты по умолчанию, либо строка валюты, указанная в пункте SPECIAL-NAMES.

Возвращаемое значение – это числовое значение, представленное строкой.

Когда указано ключевое слово LOCALE, возвращаемое значение отрицательно, если строка содержит знак минус.

Когда ключевое слово LOCALE не указано, возвращаемое значение отрицательно, если строка содержит CR, DB или знак минус.

8.1.64B. NUMVAL-C-2

Синтаксис функции NUMVAL-C

 NUMVAL-C (argument-1 [, argument-2           ]
 ~~~~~~~~
                      [, LOCALE locale-name-1 ] [, ANYCASE ])

Эта функция возвращает числовое значение, представленное строкой символов, указанной в argument-1 и определенной как буквенно-цифровое.

argument-2, любая строка валюты и любые разделители групп, предшествующие десятичному разделителю, игнорируются. При необходимости строка валюты, соглашение о знаках, разделитель групп и десятичный разделитель, разрешённые в строке символов, могут быть определены категорией локали LC-MONETARY, или строка валюты может быть задана с помощью argument-2.

Необязательный буквенно-цифровой символ argument-2 представляет собой символ валюты (не пробел и как минимум один символ, который может использоваться в качестве символа валюты в argument-1). Любые пробелы, включая начальные и конечные, игнорируются. Если argument-2 не указан, используется значение, возвращаемое функцией CURRENCY-SYMBOL (см. CURRENCY-SYMBOL). argument-2 не должен содержать цифр от 0 до 9, символов ‘*’, ‘+’, ‘-’, ‘,’ или ‘.’; или двух последовательных букв CR или DB, независимо от регистра или их комбинации.

argument-2 задает строку валюты, которая может присутствовать в argument-1.

Если указано ключевое слово ANYCASE, правила сопоставления для обнаружения строки валюты в argument-1 нечувствительны к регистру. Если оно не указано, правила сопоставления чувствительны к регистру.

Если ни argument-2, ни ключевое слово LOCALE не указаны, должна использоваться только одна строка валюты, либо символ валюты по умолчанию, либо строка валюты, указанная в параграфе SPECIAL-NAMES.

Хотя NUMVAL-C всегда будет использовать символ валюты, указанный в параграфе SPECIAL-NAMES (или системный по умолчанию, который в настоящее время всегда ’$’), argument-1 должен иметь любой из следующих форматов, где ’#’ представляет последовательность одной или нескольких десятичных цифр, а ’$’ представляет символ symbol:

# -# +# #- #+ #CR #DB
#.# -#.# +#.# #.#- #.#+ #.#CR #.#DB
$# -$# +$# $#- $#+ $#CR $#DB
$#.# -$#.# +$#.# $#.#- $#.#+ $#.#CR $#.#DB

В строке должно быть как минимум одна цифра.

Допускаются начальные и/или конечные пробелы, а также пробелы перед и/или после символа валюты, знака, символов CR и DB.

Возвращаемое значение — это числовое значение, представленное argument-1.

Когда указано ключевое слово LOCALE, возвращаемое значение отрицательное, если строка содержит знак минус; в противном случае возвращаемое значение отрицательное, если строка содержит CR, DB или знак минус.

8.1.65. NUMVAL-F

NUMVAL-F Функция Синтаксис

 NUMVAL-F(char)
 ~~~~~~~~

Эта функция преобразует строку (элемент группы, USAGE DISPLAY элементарный элемент или буквенно-цифровое значение) представляющую значение с плавающей запятой в соответствующее числовое значение.

# -# +# #E# -#E# +#E#
#E+# -#E+# +#E+# #E-# -#E-# +#E-#
#.# -#.# +#.# #.#E# -#.#E# +#.#E#
#.#E+# -#.#E+# +#.#E+# #.#E-# -#.#E-# +#.#E-#

В строке должно быть как минимум одна цифра как до, так и после E.

Допускаются начальные и/или конечные пробелы, а также пробелы перед и/или после любых знаков.

8.1.66. ORD

ORD Функция Синтаксис

 ORD(char)
 ~~~

Эта функция возвращает порядковый номер в программной кодировочной таблице (обычно ASCII) соответствующий первому символу аргумента char (элемент группы, USAGE DISPLAY элементарный элемент или буквенно-цифровое значение).

Например, если программа использует стандартную кодировочную таблицу ASCII, ORD('!') возвращает 34, поскольку ‘!’ является 34-м символом ASCII. Если вы используете эту функцию для преобразования символа ASCII в его числовое значение, вы должны вычесть 1 из результата.

Следующий код является альтернативным подходом, когда вы просто хотите преобразовать символ ASCII в его числовой эквивалент:

01  Char-Value.
    05 Numeric-Value        USAGE BINARY-CHAR.
…
    MOVE "character" TO Char-Value

Numeric-Value теперь имеет числовое значение character.

8.1.67. ORD-MAX

ORD-MAX Функция Синтаксис

 ORD-MAX(char-1 [, char-2 ]...)
 ~~~~~~~

Эта функция возвращает порядковый номер в списке аргументов, соответствующий char-n, чей первый символ имеет наибольший порядковый номер в программной кодировочной таблице (обычно ASCII).

Например, если программа использует стандартную кодировочную таблицу ASCII, ORD-MAX('Z', 'z', '!') возвращает 2, поскольку второй символ в списке аргументов (символ ASCII ‘z’) встречается после ‘Z’ и ‘!’ в программной кодировочной таблице. Каждый аргумент char-n может быть элементом группы, USAGE DISPLAY элементарным элементом или буквенно-цифровым значением.

8.1.68. ORD-MIN

ORD-MIN Функция Синтаксис

 ORD-MIN(char-1 [, char-2 ]...)
 ~~~~~~~

Эта функция возвращает порядковый номер в списке аргументов, соответствующий char-n, чей первый символ имеет наименьший порядковый номер в программной кодировочной таблице (обычно ASCII).

Например, если программа использует стандартную кодировочную таблицу ASCII, ORD-MIN('Z', 'z', '!') возвращает 3, поскольку третий символ в списке аргументов (символ ASCII ‘!’) встречается перед ‘Z’ и ‘z’ в программной кодировочной таблице. Каждый аргумент char-n может быть элементом группы, USAGE DISPLAY элементарным элементом или буквенно-цифровым значением.

8.1.69. PI

PI Функция Синтаксис

 PI
 ~~

Эта функция возвращает математическую константу PI. Максимальная точность, с которой это значение может быть возвращено, составляет 3.1415926535897932384626433832795029.

Поскольку эта функция не имеет аргументов, скобки указывать не нужно.

8.1.70. ТЕКУЩАЯ_СТОИМОСТЬ

Синтаксис функции ТЕКУЩАЯ_СТОИМОСТЬ

 PRESENT-VALUE(rate, value-1 [, value-2 ])
 ~~~~~~~~~~~~~

Функция PRESENT-VALUE возвращает значение, приближающее текущую стоимость серии будущих сумм, указанных различными аргументами value-n, по ставке дисконтирования, указанной аргументом rate.

Все аргументы — числовые данные и/или числовые литералы.

8.1.71. СЛУЧАЙНОЕ_ЧИСЛО

Синтаксис функции СЛУЧАЙНОЕ_ЧИСЛО

 RANDOM[(seed)]
 ~~~~~~

Эта функция возвращает псевдослучайное нецелое значение в диапазоне от 0 до 1 (например, 0,123456789).

Цель необязательного аргумента seed — инициализировать цепочку псевдослучайных чисел, которые будет возвращать функция. Вызовы этой функции с одинаковым значением seed будут возвращать одинаковые псевдослучайные числа, а также все последующие вызовы функции без seed. Это полезно при тестировании программы, так как можно получить последовательность «случайных» чисел, если каждый раз использовать одинаковый seed.

Аргумент seed может быть любым литералом или элементом данных. Если seed числовой, его числовое значение будет использоваться как значение семени. Если seed алфавитно-цифровой, для него будет определено значение, как если бы он был аргументом функции NUMVAL (см. NUMVAL).

Рассмотрим, например, следующую программу:

    IDENTIFICATION DIVISION.
    PROGRAM-ID. DEMORANDOM.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01  Pseudo-Random-Number        USAGE COMP-1.
    PROCEDURE DIVISION.
    000-Main.
        MOVE FUNCTION RANDOM(1) TO Pseudo-Random-Number
        DISPLAY Pseudo-Random-Number
        PERFORM 4 TIMES
            MOVE FUNCTION RANDOM    TO Pseudo-Random-Number
            DISPLAY Pseudo-Random-Number
        END-PERFORM
        STOP RUN
        .

Каждый раз при выполнении этой программы будет получен одинаковый результат, потому что будет сгенерирована одна и та же последовательность псевдослучайных чисел:

    0.41
    0.18467
    0.63340002
    0.26499999
    0.19169

Стоит отметить, что если первое выполнение RANDOM в вашей программе не содержит аргумента seed, результат будет таким же, как если бы в нём было указано значение аргумента seed равное 1.

После тщательного тестирования программы вам понадобятся разные последовательности при каждом запуске. Один из способов добиться этого — использовать seed, который, скорее всего, будет отличаться при каждом запуске программы, как и в том случае, если первая инструкция MOVE в предыдущем примере будет заменена на:

    MOVE RANDOM(FUNCTION CURRENT-DATE(1:16))
      TO Pseudo-Random-Number

Первые 16 символов, возвращаемых функцией CURRENT-DATE (см. CURRENT-DATE), будут числом в формате YYYYMMDDhhmmssnn, где YYYYMMDD — текущая дата, а hhmmssnn — текущее время до сотых долей секунды. Поскольку два разных выполнения программы никогда не получат одинаковые значения CURRENT-DATE (если они не выполняются в очень короткий промежуток времени), использование этих первых шестнадцати символов в качестве семени seed гарантирует, что получение одинаковой последовательности псевдослучайных чисел при двух разных запусках программы будет крайне маловероятным.

8.1.72. ДИАПАЗОН

Синтаксис функции ДИАПАЗОН

 RANGE(number-1 [, number-2 ]...)
 ~~~~~

Функция RANGE возвращает значение, равное максимальному значению аргумента number-n в списке аргументов минус минимальное значение аргумента number-n.

Все аргументы number-n — числовые данные и/или числовые литералы.

8.1.73. ОСТАТОК

Синтаксис функции ОСТАТОК

 REM(number,divisor)
 ~~~

Эта функция возвращает числовое значение, которое является остатком от деления number на divisor. Оба аргумента должны быть числовыми элементами данных или числовыми литералами.

8.1.74. ОБРАТНЫЙ

Синтаксис функции ОБРАТНЫЙ

 REVERSE(string)
 ~~~~~~~

Эта функция возвращает значение, полученное побайтовым обращением строки string (групповой элемент, USAGE DISPLAY элемент или алфавитно-цифровой литерал).

8.1.75. СЕКУНДЫ_ОТ_ФОРМАТИРОВАННОГО_ВРЕМЕНИ

Синтаксис функции СЕКУНДЫ_ОТ_ФОРМАТИРОВАННОГО_ВРЕМЕНИ

 SECONDS-FROM-FORMATTED-TIME(format,time)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~

Эта функция декодирует строку time — значение которой представляет отформатированное время — и возвращает общее количество секунд, представленных этой строкой.

Строка time должна содержать часы, минуты и секунды. Аргумент времени может быть задан как групповой элемент, USAGE DISPLAY элемент или алфавитно-цифровой литерал.

Аргумент format — строка (групповой элемент, USAGE DISPLAY элемент или алфавитно-цифровой литерал), документирующая формат time с использованием hh, mm и ss для обозначения мест, где можно найти соответствующую информацию о времени. Любые другие символы в format представляют позиции символов, которые будут проигнорированы. Например, формат hhmmss указывает, что time будет рассматриваться как шестизначное строковое значение, где первые две цифры — число часов, следующие две — минуты, а последние две — секунды. Формат hh:mm:ss, однако, описывает time как восьмисимвольную строку, где символы 3 и 6 будут проигнорированы.

8.1.76. СЕКУНДЫ_С_ПОЛНОЧИ

Синтаксис функции СЕКУНДЫ_С_ПОЛНОЧИ

 SECONDS-PAST-MIDNIGHT
 ~~~~~~~~~~~~~~~~~~~~~

Эта функция возвращает текущее время суток, выраженное как общее количество прошедших секунд с полуночи.

Поскольку эта функция не имеет аргументов, скобки указывать не нужно.

8.1.77. ЗНАК

Синтаксис функции SIGN

 SIGN(number)
 ~~~~

Функция SIGN возвращает -1, если значение number (числовая литерал или числовой элемент данных) отрицательное, 0, если значение number равно точно нулю, и 1, если значение number больше 0.

8.1.78. SIN

Синтаксис функции SIN

 SIN(angle)
 ~~~

Эта функция определяет и возвращает тригонометрический синус угла angle (числовая литерал или числовой элемент данных).

Угол angle предполагается выраженным в радианах. Если вам нужно определить синус угла, измеренного в градусах, вам сначала необходимо преобразовать этот угол в радианы следующим образом:

COMPUTE radians = ( degrees * FUNCTION PI) / 180

8.1.79. SQRT

Синтаксис функции SQRT

 SQRT(number)
 ~~~~

Функция SQRT возвращает числовое значение, приближенное к квадратному корню из number (числовой элемент данных или числовая литерал с неотрицательным значением).

Следующие два оператора производят одинаковые результаты:

01  Result           PIC 9(4).9(10).
…
    MOVE FUNCTION SQRT(15) TO Result
    COMPUTE Result = 15 ^ 0.5

8.1.80. STANDARD-DEVIATION

Синтаксис функции STANDARD-DEVIATION

 STANDARD-DEVIATION(number-1 [, number-2 ]...)
 ~~~~~~~~~~~~~~~~~~

Эта функция возвращает статистическую стандартную девиацию списка аргументов number-n (числовые элементы данных или числовые литералы).

8.1.81. STORED-CHAR-LENGTH

Синтаксис функции STORED-CHAR-LENGTH

 STORED-CHAR-LENGTH(string)
 ~~~~~~~~~~~~~~~~~~

Возвращает длину, в байтах, указанного string (групповой элемент, USAGE DISPLAY элементарный элемент или буквенно-цифровая литерал), за вычетом общего количества пробелов в конце, если таковые имеются.

8.1.82. SUBSTITUTE

Синтаксис функции SUBSTITUTE

 SUBSTITUTE(string, from-1, to-1 [, from-n, to-n ]...)
 ~~~~~~~~~~

Эта функция анализирует string, заменяя все вхождения строк from-n соответствующими строками to-n.

Строки from-n должны точно совпадать с последовательностями в string с учетом значения и регистра.

Строка from-n не должна иметь такую же длину, как соответствующая ей строка to-n.

Все аргументы являются групповыми элементами, USAGE DISPLAY элементарными элементами или буквенно-цифровыми литералами.

Строка to-n со значением null будет обрабатываться как одиночный пробел.

8.1.83. SUBSTITUTE-CASE

Синтаксис функции SUBSTITUTE-CASE

 SUBSTITUTE-CASE(string, from-1, to-1 [, from-n, to-n ]...)
 ~~~~~~~~~~~~~~~

Функция SUBSTITUTE-CASE работает так же, как функция SUBSTITUTE (см. SUBSTITUTE), за исключением того, что сопоставление строк from-n выполняется без учета регистра.

Все аргументы являются групповыми элементами, USAGE DISPLAY элементарными элементами или буквенно-цифровыми литералами.

8.1.84. SUM

Синтаксис функции SUM

 SUM(number-1 [, number-2 ]...)
 ~~~

Функция SUM возвращает значение, являющееся суммой аргументов number-n (они могут быть числовыми элементами данных или числовыми литералами).

8.1.85. TAN

Синтаксис функции TAN

 TAN(angle)
 ~~~

Эта функция определяет и возвращает тригонометрический тангенс угла angle (числовая литерал или числовой элемент данных).

Угол angle предполагается выраженным в радианах. Если вам нужно определить тангенс угла, измеренного в градусах, вам сначала необходимо преобразовать этот угол в радианы следующим образом:

COMPUTE radians = ( degrees * FUNCTION PI) / 180

8.1.86. TEST-DATE-YYYYMMDD

Синтаксис функции TEST-DATE-YYYYMMDD

 TEST-DATE-YYYYMMDD(date)
 ~~~~~~~~~~~~~~~~~~

Эта функция определяет, является ли переданный аргумент date (числовой целочисленный элемент данных или литерал) допустимой датой.

Допустимая дата имеет вид yyyymmdd в диапазоне от 1601/01/01 до 9999/12/31, не содержа более максимального числа дней в месяце, учитывая високосный год.

Если date является допустимой, возвращается значение 0. В противном случае возвращается значение 1, 2 или 3, указывающее, что проблема связана с годом, месяцем или днем соответственно.

8.1.87. TEST-DAY-YYYYDDD

Синтаксис функции TEST-DAY-YYYYDDD

 TEST-DATE-YYYYDDD(date)
 ~~~~~~~~~~~~~~~~~

Эта функция определяет, является ли переданная date (числовой целочисленный элемент данных или литерал) допустимой датой.

Допустимая дата имеет вид yyyyddd в диапазоне от 1601001 до 9999365. Високосный год учитывается при определении максимального числа дней в году.

Если дата допустима, возвращается значение 0. В противном случае возвращается значение 1 или 2, указывающее, что проблема связана с годом или днем соответственно.

8.1.88. TEST-FORMATTED-DATETIME

Синтаксис функции TEST-FORMATTED-DATETIME

 TEST-FORMATTED-DATETIME ( argument-1, argument-2 )
 ~~~~~~~~~~~~~~~~~~~~~~~

TEST-FORMATTED-DATETIME проверяет, является ли дата-литерал, представляющий дату, время или комбинированную дату и время, допустимым в соответствии с указанным форматом.

argument-1 должен быть национальным или буквенно-цифровым литералом. Содержимое должно быть либо форматом даты, либо комбинированным форматом даты и времени.

argument-2 должен быть элементом данных того же типа, что и argument-1.

Возвращаемое значение:

Если при оценке argument-2 в соответствии с форматом в argument-1 не возникнет проблем с форматом или диапазоном, возвращаемое значение равно нулю. В противном случае возвращаемое значение — порядковый номер символа, в котором была обнаружена первая ошибка в argument-2.

8.1.89. TEST-NUMVAL

Синтаксис функции TEST-NUMVAL

 TEST-NUMVAL(string)
 ~~~~~~~~~~~

Функция TEST-NUMVAL проверяет, подходит ли строка (элемент группы, USAGE DISPLAY элементарный элемент или буквенно-цифровая константа) для использования в качестве аргумента строка функции NUMVAL (см. NUMVAL), возвращая 0, если подходит, иначе — позицию первого некорректного символа или длину поля плюс один в случае ошибок, таких как только пробелы или неполный формат.

К таким ошибкам относятся, но не ограничиваются: пустая строка (строка), содержащая только пробелы или содержащая допустимые символы, но неполная, например, строка ‘+.’.

8.1.90. TEST-NUMVAL-C

Синтаксис функции TEST-NUMVAL-C

 TEST-NUMVAL-C(string[,symbol])
 ~~~~~~~~~~~~~

Функция проверяет, подходит ли строка (элемент группы, USAGE DISPLAY элементарный элемент или буквенно-цифровая константа) для использования в качестве аргумента строка функции NUMVAL-C (см. NUMVAL-C), возвращая 0, если подходит, иначе — позицию первого некорректного символа или длину поля плюс один в случае ошибок, таких как только пробелы или неполный формат.

К таким ошибкам относятся, но не ограничиваются: пустая строка (строка), содержащая только пробелы или содержащая допустимые символы, но неполная, например, строка ‘+.’.

Необязательный аргумент символ выполняет ту же функцию — и имеет те же значения по умолчанию и возможные значения — что и соответствующий аргумент функции NUMVAL-C.

8.1.91. TEST-NUMVAL-F

Синтаксис функции TEST-NUMVAL-F

 TEST-NUMVAL-F(string)
 ~~~~~~~~~~~~~

Функция проверяет, подходит ли строка (элемент группы, USAGE DISPLAY элементарный элемент или буквенно-цифровая константа) для использования в качестве аргумента строка функции NUMVAL-F (см. NUMVAL-F), возвращая 0, если подходит, иначе — позицию первого некорректного символа или длину поля плюс один в случае ошибок, таких как только пробелы или неполный формат.

К таким ошибкам относятся, но не ограничиваются: пустая строка (строка), содержащая только пробелы или содержащая допустимые символы, но неполная, например, строка ‘+.’.

8.1.92. TRIM

Синтаксис функции TRIM

 TRIM(string [, LEADING|TRAILING ])
 ~~~~           ~~~~~~~ ~~~~~~~~

Эта функция удаляет LEADING или TRAILING пробелы из строки (элемент группы, USAGE DISPLAY элементарный элемент или буквенно-цифровая константа).

Второй аргумент задается как ключевое слово, а не как строка в кавычках или идентификатор. Если второй аргумент не указан, удаляются и ведущие, и хвостовые пробелы. Регистр этого аргумента (заглавные, строчные или смешанные) не имеет значения.

8.1.93. UPPER-CASE

Синтаксис функции UPPER-CASE

 UPPER-CASE(string)
 ~~~~~~~~~~

Эта функция возвращает значение строки (элемент группы, USAGE DISPLAY элементарный элемент или буквенно-цифровая константа), преобразованное полностью в верхний регистр.

Что считается «буквой» (или верхним/нижним регистром, кстати) может влиять использование CHARACTER CLASSIFICATION (см. OBJECT-COMPUTER).

8.1.94. VARIANCE

Синтаксис функции VARIANCE

 VARIANCE(number-1 [, number-2 ]...)
 ~~~~~~~~

Эта функция возвращает статистическую дисперсию указанного списка аргументов число-n (это могут быть числовые данные или числовые литералы).

8.1.95. WHEN-COMPILED

Синтаксис функции WHEN-COMPILED

 WHEN-COMPILED
 ~~~~~~~~~~~~~

Встроенная функция WHEN-COMPILED, не следует путать с специальным регистром WHEN-COMPILED (см. Специальные регистры), возвращает дату и время компиляции программы в ASCII.

Так как у этой функции нет аргументов, скобки не должны быть указаны.

В отличие от специального регистра WHEN-COMPILED, который имеет значение ASCII даты/времени компиляции в формате mm/dd/yyhh.mm.ss, встроенная функция WHEN-COMPILED возвращает дату/время компиляции как строку ASCII в формате yyyymmddhhmmssnnooooo, где yyyymmdd — дата, hhmmss — время, nn — сотые доли секунды компонента времени компиляции, если доступны (или 00, если нет), а ooooo — смещение часового пояса от GMT.

Если переключатель -fintrinsics=WHEN-COMPILED или -fintrinsics=ALL указан компилятору, или REPOSITORY (см. REPOSITORY) абзац указывает FUNCTION WHEN-COMPILED INTRINSIC или FUNCTION ALL INTRINSIC, то ссылки на WHEN-COMPILED (без ключевого слова FUNCTION) всегда будут ссылаться на эту встроенную функцию, и доступа к специальному регистру WHEN-COMPILED не будет.

8.1.96. YEAR-TO-YYYY

Синтаксис функции YEAR-TO-YYYY

 YEAR-TO-YYYY(yy [, yy-cutoff [, yy-execution-time ]])
 ~~~~~~~~~~~~

Функция YEAR-TO-YYYY преобразует yy — двухзначный год — в четырёхзначный формат (yyyy).

Дополнительный аргумент yy-cutoff — это значение отсечения года, используемое для определения веков; если yy равно или превышает это значение отсечения, результат будет 19yy; если yy меньше отсечения, результат будет 20yy. Значение по умолчанию для отсечения, если второй аргумент не указан, будет 50.

Дополнительный аргумент yy-execution-time (числовое целочисленное данное или литерал) Значение времени выполнения по умолчанию, если третий аргумент не указан, будет эквивалентно указанию (FUNCTION NUMVAL (FUNCTION CURRENT-DATE (1:4))).

Все аргументы должны быть числовыми данными или числовыми литералами.

8.1.97. BOOLEAN-OF-INTEGER

BOOLEAN-OF-INTEGER Синтаксис функции

 BOOLEAN-OF-INTEGER(argument-1 argument-2)
 ~~~~~~~~~~~~~~~~~~

Этот параметр еще не реализован.

Включенный файл NEWS укажет, когда это будет сделано.

BOOLEAN-OF-INTEGER возвращает логический элемент, представляющий двоичное значение argument-1. argument-2 определяет длину возвращаемого логического элемента.

argument-1 должен быть положительным целым числом.

argument-2 должен быть положительным целым числом, отличным от нуля.

Возвращаемое значение — логический элемент с той же битовой конфигурацией, что и двоичное представление значения argument-1, где правая позиция логического элемента — младший двоичный разряд. Логическое значение заполняется нулями или усекается слева, если необходимо, чтобы вернуть логический элемент, длина которого задана argument-2 в терминах логических позиций.

8.1.98. CHAR-NATIONAL

CHAR-NATIONAL Синтаксис функции

 CHAR-NATIONAL(argument-1)
 ~~~~~~~~~~~~~

Этот параметр еще не реализован.

Включенный файл NEWS укажет, когда это будет сделано.

CHAR-NATIONAL возвращает значение одного символа, являющееся символом в национальной сортировочной последовательности программы, имеющим порядковый номер, равный значению аргумента.

argument-1 должен быть целым числом, большим нуля и меньше или равным количеству позиций в национальной сортировочной последовательности программы.

8.1.99. DISPLAY-OF

DISPLAY-OF Синтаксис функции

 DISPLAY-OF(argument-1 [ argument-2] )
 ~~~~~~~~~~

Этот параметр еще не реализован.

Включенный файл NEWS укажет, когда это будет сделано.

DISPLAY-OF возвращает строку символов, содержащую представление набора символов в алфавитном кодировании национальных символов в аргументе.

argument-1 должен быть класса national.

argument-2 должен быть класса alphabetic или alphanumeric и иметь длину в одну позицию. Он указывает символ алфавитно-цифровой замены для использования при преобразовании национальных символов, для которых нет соответствующего алфавитно-цифрового символа.

Возвращается строка символов, в которой каждый национальный символ argument-1 преобразуется в соответствующее алфавитно-цифровое представление, если оно существует.

Если argument-2 указан, то для каждого национального символа в argument-1, для которого нет соответствующего алфавитно-цифрового представления, возвращается символ алфавитно-цифровой замены.

Если argument-2 не указан, а argument-1 содержит национальный символ, для которого нет соответствующего алфавитно-цифрового представления, используется символ замены в качестве соответствующего алфавитно-цифрового символа, и устанавливается условие исключения EC-DATA-CONVERSION.

Длина возвращаемого значения равна количеству позиций символов типа display, необходимых для хранения преобразованного аргумента, и зависит от количества символов в argument-1.

8.1.100. EXCEPTION-FILE-N

EXCEPTION-FILE-N Синтаксис функции

 EXCEPTION-FILE-N
 ~~~~~~~~~~~~~~~~

Этот параметр еще не реализован.

Включенный файл NEWS укажет, когда это будет сделано.

EXCEPTION-FILE-N возвращает строку национальных символов, представляющую значение статуса ввода-вывода и имя файла коннектора файла, если таковой имеется, связанного с последним статусом исключения.

Возвращаемое значение имеет длину, которая основана на его содержимом, и содержимое таково:

Если последний статус исключения не является EC-I-O условием исключения, возвращаемое значение — два национальных нуля.

Возвращаемое значение — два национальных пробела, когда последний статус исключения указывает на EC-I-O условие исключения, исходящее из одного из следующих операторов:

  • оператора RAISE.
  • оператора EXIT или GOBACK, с фразой RAISING, которая указывает имя исключения EC-I-O.

В противном случае возвращаемое значение — строка символов, длина которой необходима для хранения значения статуса ввода-вывода и имени файла. Первые два символа — это значение статуса ввода-вывода в национальных символах. Последующие символы содержат имя файла точно так, как указано в SELECT разделе, преобразованное во время выполнения в национальный набор символов среды выполнения.

Документация встроенной системной подпрограммы CBL_ERROR_PROC (см. CBL_ERROR_PROC) иллюстрирует использование этой функции.

8.1.101. EXCEPTION-LOCATION-N

EXCEPTION-LOCATION-N Синтаксис функции

 EXCEPTION-LOCATION-N
 ~~~~~~~~~~~~~~~~~~~~

Этот параметр еще не реализован.

Включенный файл NEWS укажет, когда это будет сделано.

EXCEPTION-LOCATION-N возвращает строку национальных символов, содержащую информацию об ошибке из последнего невыполненного оператора. Информация возвращается в строку длиной до 1023 символов в одном из следующих форматов, в зависимости от характера ошибки:

  • имя_первичной_точки_входа; абзац РАЗДЕЛА; номер_оператора
  • имя_первичной_точки_входа; раздел; номер_оператора
  • имя_первичной_точки_входа; абзац; номер_оператора
  • имя_первичной_точки_входа; номер_оператора

Поскольку эта функция не имеет аргументов, скобки указывать не следует.

Для того, чтобы эта функция возвращала осмысленную информацию, программа должна быть скомпилирована с ключом -debug, -ftraceall или -g.

Документация встроенной системной подпрограммы CBL_ERROR_PROC (см. CBL_ERROR_PROC) демонстрирует использование этой функции.

8.1.102. INTEGER-OF-BOOLEAN

INTEGER-OF-BOOLEAN Синтаксис функции

 INTEGER-OF-BOOLEAN(argument-1)
 ~~~~~~~~~~~~~~~~~~

Эта опция пока не реализована.

Включенный файл NEWS укажет, когда это будет сделано.

INTEGER-OF-BOOLEAN возвращает числовое значение булевой строки в аргумент-1, которая относится к классу boolean.

Возвращаемое значение, как аргумент-1, присваивается временной булевой переменной с использованием бит, описанных с тем же количеством позиций boolean.

Определяется беззнаковое двоичное значение, представленное той же конфигурацией битов, что и конфигурация битов этой временной булевой переменной.

Примечание: Двоичное представление — это математическая концепция. Не требуется, чтобы это представление было таким же, как представление в COBOL.

8.1.103. NATIONAL-OF

NATIONAL-OF Синтаксис функции

NATIONAL-OF(argument-1 [argument-2] )
~~~~~~~~~~~

Эта опция пока не реализована.

Включенный файл NEWS укажет, когда это будет сделано.

NATIONAL-OF возвращает строку, содержащую национальное представление символов в аргументе, который должен принадлежать классу boolean.

Возвращается строка, в которой каждый буквенно-цифровой символ в аргумент-1 преобразуется в соответствующее национальное кодированное представление.

Если аргумент-2 указан, каждый символ в аргумент-1, для которого нет соответствующего национального представления, преобразуется в символ подстановки, указанный в аргумент-2.

Если аргумент-2 не указан и аргумент-1 содержит буквенно-цифровой символ, для которого нет соответствующего национального представления, используется символ подстановки в качестве соответствующего национального символа и устанавливается существование исключительного условия EC-DATA-CONVERSION.

Длина возвращаемого значения равна количеству позиций символов типа национального, необходимых для хранения преобразованного аргумента, и зависит от количества символов в аргумент-1.

8.1.104. STANDARD-COMPARE

STANDARD-COMPARE Синтаксис функции

STANDARD-COMPARE(argument-1 argument-2 [ordering-name-1] [argument-4] )
~~~~~~~~~~~~~~~~

Эта опция пока не реализована.

Включенный файл NEWS укажет, когда это будет сделано.

STANDARD-COMPARE возвращает символ, указывающий результат сравнения аргумент-1 как буквенно-цифровой и аргумент-2 с использованием таблицы культурного упорядочения.

  1. аргумент-1 должен принадлежать классу буквенному, буквенно-цифровому или национальному.
  2. аргумент-2 должен принадлежать классу буквенному, буквенно-цифровому или национальному.
  3. аргумент-1 и аргумент-2 могут принадлежать к разным классам.
  4. Ни аргумент-1, ни аргумент-2 не должны быть нулевой длины.
  5. имя_упорядочения-1, если указано, должно быть связано с таблицей культурного упорядочения в ORDER TABLE пункте SPECIAL-NAMES. имя_упорядочения-1 идентифицирует таблицу упорядочения, которая должна быть использована для сравнения. Если имя_упорядочения-1 не указано, используется таблица упорядочения по умолчанию ‘ISO14651_2010_TABLE1’, описанная в Приложении A к ISO/IEC 14651:2011.
  6. аргумент-4, если указан, должен быть положительным ненулевым целым числом.

Возвращаемые значения:

  1. Если argument-4 не указан, для сравнения используется наивысший уровень, определённый в таблице упорядочивания.
  2. Если таблица культурного упорядочивания недоступна на процессоре, или указанный уровень упорядочивания недоступен, или номер уровня, указанный argument-4, не определён в таблице упорядочивания, устанавливается состояние исключения EC-ORDER-NOT-SUPPORTED.
  3. Если аргументы имеют разные классы, и один из них национальный, другой аргумент преобразуется в класс национальный для целей сравнения.
  4. Для целей сравнения пробелы в конце операндов усекаются, за исключением случая, когда операнд состоит только из пробелов, тогда он усекается до одного пробела.
  5. argument-1 и argument-2 сравниваются в соответствии с используемой таблицей упорядочивания и уровнем.

    Примечание: Это сравнение учитывает культурные особенности, и стандартная таблица упорядочивания подходит для большинства культур. Это не обязательно сравнение символ за символом и не обязательно чувствительное к регистру. Для использования этой функции пользователи должны понимать типы сравнений, указанные в ISO/IEC 14651:2D11, и таблицы упорядочивания, используемые в их установке.

  6. Возвращаемое значение:
    ‘=’

    аргументы равны,

    ‘-=.:’

    argument-1 меньше argument-2,

    ‘:>’

    argument-1 больше argument-2.

  7. Длина возвращаемого значения равна 1.

8.2. Встроенные системные подпрограммы

В GnuCOBOL включено несколько встроенных системных подпрограмм.

В целом, эти подпрограммы предназначены для соответствия подпрограммам, доступным в Micro Focus COBOL, ACUCOBOL и непосредственно в GnuCOBOL.

Рекомендуется изменить CBL_OC подпрограммы на CBL_GC для обеспечения совместимости в будущем, так как в какой-то момент они будут удалены, поскольку являются пережитком Open Cobol.

Объяснение префикса:

C$

–> ACU

CBL_

–> MF

CBL_GC_

(Для обратной совместимости некоторые подпрограммы также доступны как CBL_OC_): но эти замечательные расширения только доступны с GnuCOBOL.

Эти подпрограммы, все выполняемые через свои имена в верхнем регистре с помощью инструкции CALL (см. ВЫЗОВ), способны выполнять следующие функции:

  • Изменение текущей директории
  • Копирование файлов
  • Создание директории
  • Создание, открытие, закрытие, чтение и запись файлов потокового типа
  • Удаление директорий (папок)
  • Удаление файлов
  • Определение количества аргументов, переданных подпрограмме
  • Получение информации о файле (размер и дата/время последнего изменения)
  • Получение длины (в байтах) аргумента, переданного подпрограмме
  • Выравнивание поля по левому, правому или центру
  • Перемещение файлов (деструктивная «копирование»)
  • «Засыпание» программы, указав время сна в секундах
  • «Засыпание» программы, указав время сна в наносекундах; Предостережение: хотя вы и укажете время в наносекундах, системы Windows смогут заснуть только с точностью до миллисекунды
  • Получение информации о текущей выполняемой программе
  • Отправка команды в оболочку среды, соответствующей используемой версии GnuCOBOL для выполнения

В ранних версиях Micro Focus COBOL программисты могли получить доступ к различным подпрограммам библиотеки времени выполнения, используя единственное двухзначное шестнадцатеричное число в качестве имени точки входа. Эти подпрограммы были известны как подпрограммы вызова по номеру. Со временем Micro Focus COBOL эволюционировал, заменив большинство подпрограмм вызова по номеру подпрограммами, доступными с помощью более традиционной техники вызова по имени.

Большинство подпрограмм вызова по номеру эволюционировали в ещё более мощные подпрограммы вызова по имени, многие из которых поддерживаются GnuCOBOL.

Некоторые оригинальные подпрограммы вызова по номеру так и не эволюционировали в эквиваленты вызова по имени; GnuCOBOL поддерживает некоторые из этих подпрограмм.

В следующих разделах описываются различные встроенные подпрограммы. Все аргументы подпрограммы обязательны, если не указано обратное. Любая подпрограмма, возвращающая значение в специальный регистр RETURN-CODE (см. Специальные регистры), может использовать клаузу RETURNING в инструкции CALL для возврата результата обратно в элемент данных целого слова в двоичном формате вашего выбора.

8.2.1. C$CALLEDBY

Синтаксис встроенной подпрограммы C$CALLEDBY

 CALL "C$CALLEDBY" USING prog-name-area
 ~~~~              ~~~~~

Эта подпрограмма возвращает имя программы, вызвавшей текущую выполняемую программу. Имя программы будет возвращено, выровненным по левому краю и заполненным пробелами, в аргументе prog-name-area, который должен быть PIC X элементарным элементом или групповым элементом. Если prog-name-area слишком мал для получения всего имени программы, значение имени программы будет усечено (справа) для соответствия.

Специальный регистр RETURN-CODE (см. Специальные регистры) будет установлен на одно из следующих значений:

-1 Произошла ошибка. Содержимое prog-name-area останется без изменений.
0 Программа, вызвавшая C$CALLEDBY, не была вызвана никакой другой программой (то есть это главная программа). Содержимое prog-name-area будет полностью заполнено пробелами.
1 Программа, вызвавшая C$CALLEDBY, была действительно вызвана другой программой, и имя этой программы сохранено в prog-name-area.

8.2.2. C$CHDIR

Синтаксис встроенной подпрограммы C$CHDIR

 CALL "C$CHDIR" USING directory-path, result
 ~~~~           ~~~~~

Эта подпрограмма устанавливает directory-path (буквенно-цифровую литерал или идентификатор) в качестве текущей директории.

Код возврата операции возвращается как в аргументе result (любой нередактируемый числовой идентификатор), так и в специальном регистре RETURN-CODE (см. Специальные регистры). Код возврата операции будет либо 0=Успех, либо 128=ошибка.

Изменение директории действует до завершения программы (при этом исходная текущая директория, установленная при запуске программы, будет автоматически восстановлена) или до выполнения другой C$CHDIR или встроенной подпрограммы системы CBL_CHANGE_DIR (см. CBL_CHANGE_DIR).

8.2.3. C$COPY

Синтаксис встроенной подпрограммы C$COPY

 CALL "C$COPY" USING src-file-path, dest-file-path, 0
 ~~~~          ~~~~~

Используйте эту подпрограмму для копирования файла src-file-path в dest-file-path, как если бы это делалось с помощью команды cp (Unix/OSX) или COPY (Windows).

Оба аргумента пути к файлу могут быть буквенно-цифровыми литералами или идентификаторами.

Третий аргумент обязателен, но не используется.

Если попытка копирования файла завершается неудачей (например, файла или целевой директории не существует), специальный регистр RETURN-CODE (см. Специальные регистры) будет установлен в 128; при успешном завершении он будет установлен в 0.

8.2.4. C$DELETE

Синтаксис встроенной подпрограммы C$DELETE

 CALL "C$DELETE" USING file-path, 0
 ~~~~            ~~~~~

Эта подпрограмма удаляет файл, указанный аргументом file-path (буквенно-цифровая литерал или идентификатор), точно так же, как если бы это делалось с помощью команды rm (Unix/OSX) или ERASE (Windows).

Второй аргумент обязателен, но не используется.

Если попытка удалить файл завершается неудачей (например, файла не существует), специальный регистр RETURN-CODE (см. Специальные регистры) будет установлен в 128; при успешном завершении он будет установлен в 0.

8.2.5. C$FILEINFO

Синтаксис встроенной подпрограммы C$FILEINFO

 CALL "C$FILEINFO" USING file-path, file-info
 ~~~~              ~~~~~

С помощью этой подпрограммы можно получить размер файла, указанного в аргументе file-path (буквенно-цифровая литерал или идентификатор), и дату/время последнего изменения файла. Информация о размере файла может быть недоступна в конкретной сборке GnuCOBOL / операционной системе, которую вы используете, и поэтому всегда может возвращаться как ноль. Информация возвращается в аргумент file-info, который определен как следующая 16-байтовая область:

01  File-Info.
    05 File-Size-In-Bytes  PIC 9(18) COMP.
    05 Mod-YYYYMMDD        PIC 9(8)  COMP. *> Modification Date
    05 Mod-HHMMSS00        PIC 9(8)  COMP. *> Modification Time

Последние две десятичные цифры во времени изменения всегда будут 00.

Если подпрограмма выполняется успешно, в специальном регистре RETURN-CODE (см. Специальные регистры) будет возвращено значение 0. Если невозможно получить необходимые статистические данные о файле, то в специальном регистре RETURN-CODE будет возвращено значение 35. Передача меньше двух аргументов приведет к значению специального регистра 128 RETURN-CODE.

8.2.6. C$GETPID

Синтаксис встроенной подпрограммы C$GETPID

 CALL "C$GETPID"
 ~~~~

Используйте эту подпрограмму для возврата PID (ID процесса) выполняемой программы GnuCOBOL. Значение PID возвращается в специальный регистр RETURN-CODE (см. Специальные регистры).

Эта подпрограмма не имеет аргументов.

8.2.7. C$JUSTIFY

Синтаксис встроенной подпрограммы C$JUSTIFY

 CALL "C$JUSTIFY" USING data-item, "justification-type"
 ~~~~             ~~~~~

Используйте C$JUSTIFY для выравнивания по левому, правому или центру буквенного, буквенно-цифрового или числового отредактированного элемента данных. Необязательный аргумент justification-type указывает тип выравнивания. Его значение интерпретируется следующим образом:

‘C’

значение будет центрировано

‘R’

значение будет выровнено по правому краю, заполненное пробелами слева

‘L’

значение будет выровнено по левому краю, заполненное пробелами справа

Если он начинается с чего-либо другого или отсутствует, он будет обрабатываться так, как если бы он присутствовал и начинался с заглавной буквы ‘R’

8.2.8. C$MAKEDIR

Синтаксис встроенной подпрограммы C$MAKEDIR

 CALL "C$MAKEDIR" USING dir-path
 ~~~~             ~~~~~

С помощью этой подпрограммы можно создать новую директорию — имя которой предоставляется в качестве аргумента dir-path (буквенно-цифровой литерал или идентификатор).

Можно создать только директорию самого низкого уровня (последнюю) в указанном пути — все остальные должны уже существовать. Эта подпрограмма не будет вести себя как mkdir -p (Unix) или mkdir /p (Windows).

В специальный регистр (см. Специальные регистры) будет помещен код возврата операции; значение будет либо 0=Успех, либо 128=Неудачно.

8.2.9. C$NARG

Синтаксис встроенной подпрограммы C$NARG

 CALL "C$NARG" USING arg-count-result
 ~~~~          ~~~~~

Эта подпрограмма возвращает количество аргументов, переданных программе, которая её вызывает, в числовом поле arg-count-result. При вызове из определяемой пользователем функции возвращается значение один (1), если функции были переданы какие-либо аргументы, или ноль (0) в противном случае.

При вызове из основной программы возвращаемое значение всегда будет 0.

8.2.10. C$PARAMSIZE

Синтаксис встроенной подпрограммы C$PARAMSIZE

 CALL "C$PARAMSIZE" USING argument-number
 ~~~~               ~~~~~

Эта подпрограмма возвращает размер (в байтах) аргумента подпрограммы, предоставленного с помощью параметра argument-number (числовая константа или элемент данных).

Размер возвращается в специальном регистре (см. Специальные регистры).

Если указанный аргумент отсутствует или указан недопустимый номер аргумента, возвращается значение 0.

8.2.11. C$PRINTABLE

Синтаксис встроенной подпрограммы C$PRINTABLE

 CALL "C$PRINTABLE" USING data-item [ , char ]
 ~~~~               ~~~~~

Подпрограмма преобразует содержимое элемента данных, указанного в качестве первого аргумента, в символы, пригодные для печати. Символы, которые считаются символами, пригодными для печати (как определено набором символов, используемым data-item), остаются неизменными, а символы, которые НЕ пригодны для печати, преобразуются в символ, указанный как второй аргумент.

Если аргумент char не указан, используется точка (‘.’).

Примечание: CBL_GC_PRINTABLE заменяет эту функцию, хотя она всё ещё поддерживается по соображениям совместимости.

8.2.12. C$SLEEP

Синтаксис встроенной подпрограммы C$SLEEP

 CALL "C$SLEEP" USING seconds-to-sleep
 ~~~~           ~~~~~

C$SLEEP приостанавливает выполнение программы на указанное количество секунд. Аргумент seconds-to-sleep может быть числовой константой или элементом данных.

Значения времени приостановки меньше 1 будут интерпретироваться как 0, что немедленно возвращает управление вызывающей программе без задержки приостановки.

8.2.13. C$TOLOWER

Синтаксис встроенной подпрограммы C$TOLOWER

 CALL "C$TOLOWER" USING data-item, BY VALUE convert-length
 ~~~~             ~~~~~               ~~~~~

Эта процедура преобразует convert-length (числовая константа или элемент данных) ведущих символов data-item (идентификатор буквенно-цифрового символа) в нижний регистр.

Аргумент convert-length должен быть указан BY VALUE (см. CALL). Любые символы в data-item после указанного convert-length останутся без изменений.

Если convert-length отрицательное или нулевое, преобразование не будет выполнено.

8.2.14. C$TOUPPER

Синтаксис встроенной подпрограммы C$TOUPPER

 CALL "C$TOUPPER" USING data-item, BY VALUE convert-length
 ~~~~             ~~~~~               ~~~~~

Эта процедура преобразует convert-length (числовая константа или элемент данных) ведущих символов data-item (идентификатор буквенно-цифрового символа) в верхний регистр.

Аргумент convert-length должен быть указан BY VALUE (см. CALL). Любые символы в data-item после указанного convert-length останутся без изменений.

Если convert-length отрицательное или нулевое, преобразование не будет выполнено.

8.2.15. CBL_AND

Синтаксис встроенной подпрограммы CBL_AND

 CALL "CBL_AND" USING item-1, item-2, BY VALUE byte-length
 ~~~~           ~~~~~                    ~~~~~
 Old    Old    New
Arg 1  Arg 2  Arg 2
 Bit    Bit    Bit
=====  =====  =====
  0      0      0
  0      1      0
  1      0      0
  1      1      1
Эта подпрограмма выполняет побитовое логическое AND операцию между крайними 8*byte-length соответствующими битами item-1 и item-2, сохраняя результирующую строку битов в item-2. Таблица истинности слева документирует AND процесс. Аргумент item-1 может быть буквенно-цифровой константой или элементом данных, а item-2 — обязательно элементом данных. Длина как item-1, так и item-2 должна быть не менее 8*byte-length.

Аргумент byte-length может быть числовой константой или элементом данных и должен быть указан с помощью BY VALUE (см. CALL).

Любые биты в item-2 после 8*byte-length останутся без изменений.

Ноль будет возвращён в специальном регистре (см. Специальные регистры).

8.2.16. CBL_CHANGE_DIR

Синтаксис встроенной подпрограммы CBL_CHANGE_DIR

 CALL "CBL_CHANGE_DIR" USING directory-path
 ~~~~                  ~~~~~

Эта процедура устанавливает directory-path (буквенно-цифровая константа или идентификатор) в качестве текущего каталога.

Код возврата операции, который будет либо 0=Успех, либо 128=Неудачно, возвращается в специальном регистре (см. Специальные регистры).

Изменение каталога остается в силе до завершения программы (в этом случае исходный текущий каталог в момент запуска программы будет автоматически восстановлен) или до выполнения другой CBL_CHANGE_DIR или встроенной подпрограммы системы (см. C$CHDIR).

8.2.17. CBL_CHECK_FILE_EXIST

Синтаксис встроенной подпрограммы CBL_CHECK_FILE_EXIST

 CALL "CBL_CHECK_FILE_EXIST" USING file-path, file-info
 ~~~~                        ~~~~~

С помощью этой процедуры можно получить размер файла, указанного в аргументе file-path (алфавитно-цифровое литеральное значение или идентификатор), и дату/время последнего изменения этого файла. Информация о размере файла может быть недоступна в конкретной сборке GnuCOBOL/операционной системе, которую вы используете, и поэтому всегда может возвращаться как ноль.

Информация возвращается в аргумент file-info, который определяется как следующая 16-байтовая область:

01  file-info.
    05 File-Size-In-Bytes  PIC 9(18)  COMP.
    05 Mod-DD              PIC 9(2)   COMP.  *> Modification Date
    05 Mod-MO              PIC 9(2)   COMP.
    05 Mod-YYYY            PIC 9(4)   COMP.
    05 Mod-HH              PIC 9(2)   COMP.  *> Modification Time
    05 Mod-MM              PIC 9(2)   COMP.
    05 Mod-SS              PIC 9(2)   COMP.
    05 FILLER              PIC 9(2)   COMP.  *> Always 00

Если подпрограмма выполнена успешно, значение 0 будет возвращено в специальный регистр RETURN-CODE (см. Специальные регистры). Невозможность извлечения необходимой статистики о файле приведет к тому, что значение специального регистра RETURN-CODE будет равно 35. Предоставление менее двух аргументов приведет к значению специального регистра 128 RETURN-CODE.

8.2.18. CBL_CLOSE_FILE

Синтаксис встроенной подпрограммы CBL_CLOSE_FILE

 CALL "CBL_CLOSE_FILE" USING file-handle
 ~~~~                  ~~~~~

Подпрограмма CBL_CLOSE_FILE закрывает файл потока байтов, ранее открытый либо встроенной системной подпрограммой CBL_OPEN_FILE (см. CBL_OPEN_FILE), либо встроенной системной подпрограммой CBL_CREATE_FILE (см. CBL_CREATE_FILE).

Если файл, определенный аргументом file-handle (элемент данных PIC X(4) USAGE COMP-X ), был открыт для вывода, неявная встроенная системная подпрограмма CBL_FLUSH_FILE (см. CBL_FLUSH_FILE) будет выполнена перед закрытием файла.

Если подпрограмма выполнена успешно, значение 0 будет возвращено в специальный регистр RETURN-CODE (см. Специальные регистры). Ошибка приведет к возвращению значения специального регистра RETURN-CODE равного -1.

8.2.19. CBL_COPY_FILE

Синтаксис встроенной подпрограммы CBL_COPY_FILE

 CALL "CBL_COPY_FILE" USING src-file-path, dest-file-path
 ~~~~                 ~~~~~

Используйте эту подпрограмму для копирования файла src-file-path в dest-file-path так, как если бы это выполнялось через команду cp (Unix/OSX) или COPY (Windows).

Оба аргумента могут быть алфавитно-цифровыми литералами или идентификаторами.

Если попытка копирования файла завершится неудачей (например, файла или целевой директории не существует), специальный регистр RETURN-CODE (см. Специальные регистры) будет установлен в значение 128; при успешном выполнении он будет установлен в 0.

8.2.20. CBL_CREATE_DIR

Синтаксис встроенной подпрограммы CBL_CREATE_DIR

 CALL "CBL_CREATE_DIR" USING dir-path
 ~~~~                  ~~~~~

С помощью этой процедуры можно создать новую директорию — имя которой передается в аргументе dir-path (алфавитно-цифровое литеральное значение или идентификатор).

Можно создать только директорию самого низкого уровня (последнюю) в указанном пути — все остальные должны уже существовать. Эта подпрограмма не будет вести себя как команда mkdir -p (Unix) или mkdir /p (Windows).

Специальный регистр RETURN-CODE (см. Специальные регистры) будет установлен в код возврата операции; значение будет равно либо 0=Успех, либо 128=Ошибка.

8.2.21. CBL_CREATE_FILE

Синтаксис встроенной подпрограммы CBL_CREATE_FILE

 CALL "CBL_CREATE_FILE" USING file-path, 2, 0, 0, file-handle
 ~~~~                   ~~~~~

Подпрограмма CBL_CREATE_FILE создает новый файл, указанный с помощью аргумента file-path, и открывает его для вывода в качестве файла потока байтов, используемого подпрограммой CBL_WRITE_FILE (см. CBL_WRITE_FILE).

Аргументы 2, 3 и 4 следует записывать как показанные константные значения. CBL_CREATE_FILE фактически является частным случаем подпрограммы CBL_OPEN_FILE (см. CBL_OPEN_FILE) — см. описание значений аргументов 2, 3 и 4 в этой подпрограмме.

Будет возвращен дескриптор файла file-handle (PIC X(4) USAGE COMP-X) ), который можно использовать в последующих вызовах подпрограммы CBL_WRITE_FILE (см. CBL_WRITE_FILE) или подпрограммы CBL_CLOSE_FILE (см. CBL_CLOSE_FILE).

Об успехе или неудаче подпрограммы будет сообщено в специальном регистре RETURN-CODE (см. Специальные регистры), где значение -1 указывает на недействительный аргумент, а значение 0 — на успех.

8.2.22. CBL_DELETE_DIR

Синтаксис встроенной подпрограммы CBL_DELETE_DIR

 CALL "CBL_DELETE_DIR" USING dir-path
 ~~~~                  ~~~~~

Эта подпрограмма удаляет пустую директорию.

Единственный аргумент — dir-path (алфавитно-цифровое литеральное значение или идентификатор) — имя удаляемой директории.

Будет удалена только директория самого низкого уровня (последняя) в указанном пути, и эта директория должна быть пустой для удаления.

Специальный регистр RETURN-CODE (см. Специальные регистры) будет установлен в код возврата операции; значение будет равно либо 0=Успех, либо 128=Ошибка.

8.2.23. CBL_DELETE_FILE

Синтаксис встроенной подпрограммы CBL_DELETE_FILE

 CALL "CBL_DELETE_FILE" USING file-path
 ~~~~                   ~~~~~

Эта процедура удаляет файл, указанный аргументом file-path (алфавитно-цифровое литеральное значение или идентификатор), так же, как это делается с помощью команды rm (Unix/OSX) или ERASE (Windows).

Если попытка удалить файл завершится неудачно (например, файла не существует), специальный регистр (см. Специальные регистры) будет установлен в значение 128; при успешном завершении он будет установлен в 0.

8.2.24. CBL_EQ

Синтаксис встроенной подпрограммы CBL_EQ

 CALL "CBL_EQ" USING item-1, item-2, BY VALUE byte-length
 ~~~~          ~~~~~                    ~~~~~
 Old    Old    New
Arg 1  Arg 2  Arg 2
 Bit    Bit    Bit
=====  =====  =====
  0      0      1
  0      1      0
  1      0      0
  1      1      1
Эта подпрограмма выполняет побитовое сравнение между 8*byte-length старшими битами item-1 и item-2, сохраняя результат в item-2. Таблица истинности слева документирует процесс EQ. Аргумент item-1 может быть алфавитно-цифровым литералом или элементом данных, а item-2 обязательно должен быть элементом данных. Длина обоих item-1 и item-2 должна быть не менее 8*byte-length.

Аргумент byte-length может быть числовым литералом или элементом данных и должен быть указан с помощью BY VALUE (см. CALL).

Любые биты в item-2 после позиции 8*byte-length останутся неизменными.

Результат в виде нуля будет возвращен в специальный регистр RETURN-CODE (см. Специальные регистры).

8.2.25. CBL_ERROR_PROC

Синтаксис встроенной подпрограммы CBL_ERROR_PROC

 CALL "CBL_ERROR_PROC" USING function, program-pointer
 ~~~~                  ~~~~~

Эта процедура регистрирует общую обработку ошибок.

Аргумент function должен быть числовым литералом или 32-битным бинарным элементом данных (USAGE BINARY-LONG, например) со значением 0 или 1. Значение 0 означает, что вы регистрируете («устанавливаете») процедуру обработки ошибок, а значение 1 указывает на дерегистрацию («снятие») ранее установленной процедуры обработки ошибок.

Аргумент program-pointer должен быть элементом данных с USAGE (см. USAGE) PROGRAM-POINTER, содержащим адрес вашей процедуры обработки ошибок. Этот элемент должен быть присвоен значение с помощью оператора SET Program-Pointer (см. Указание Program-Pointer). Если процедура обработки ошибок написана на GnuCOBOL, она должна быть подпрограммой, а не пользовательской функцией.

Результат успеха (0) или неудачи (не 0) будет возвращен в специальный регистр RETURN-CODE (см. Специальные регистры).

Пользовательская процедура обработки ошибок будет вызвана при возникновении условия ошибки во время выполнения. Процедуру обработки ошибок может зарегистрировать главная программа или подпрограмма, но независимо от того, откуда она была зарегистрирована, она относится ко всему программному комплексу компиляции и будет вызвана при возникновении ошибки во время выполнения в любой части исполняемой программы. Если процедура обработки ошибок была определена подпрограммой, эта программа должна быть загружена в момент выполнения процедуры обработки ошибок.

Процедура обработки ошибок может быть использована для выполнения любых действий, которые могут потребоваться для отображения дополнительной информации или для корректного завершения текущей работы, но она не может предотвратить завершение выполнения программы; если процедура обработки ошибок не выпустит свой собственный STOP RUN, управление будет возвращено стандартной процедуре обработки ошибок после завершения процедуры обработки ошибок.

Код внутри обработчика будет выполнен, и — после того, как обработчик выпустит return, если он был написан на C, или оператор EXIT PROGRAM (см. EXIT) или GOBACK (см. EXIT), если он был написан на GnuCOBOL, будет выполнена системная стандартная процедура обработки ошибок.

Одновременно может быть активна только одна пользовательская процедура обработки ошибок.

Ниже приведен пример программы GnuCOBOL, регистрирующей процедуру обработки ошибок. Также показан вывод этой программы. Как видите, сообщения обработчика ошибок отображаются, за которыми следует стандартное сообщение GnuCOBOL.

1.     IDENTIFICATION DIVISION.
2.     PROGRAM-ID. DemoERRPROC.
3.     ENVIRONMENT DIVISION.
4.     DATA DIVISION.
5.     WORKING-STORAGE SECTION.
6.     01  Err-Proc-Address            USAGE PROGRAM-POINTER.
7.     PROCEDURE DIVISION.
8.     S1.
9.         DISPLAY 'Program is starting'
10.        SET Err-Proc-Address TO ENTRY 'ErrProc'
11.        CALL 'CBL_ERROR_PROC' USING 0, Err-Proc-Address
12.        CALL 'Tilt' *> THIS DOESN'T EXIST!!!!
13.        DISPLAY 'Program is stopping'
14.        STOP RUN
15.        .
16.    END PROGRAM DemoERRPROC.
17.
18.    IDENTIFICATION DIVISION.
19.    PROGRAM-ID. ErrProc.
20.    PROCEDURE DIVISION.
21.    000-Main.
22.        DISPLAY 'Error: ' FUNCTION EXCEPTION-LOCATION
23.        DISPLAY '       ' FUNCTION EXCEPTION-STATEMENT
24.        DISPLAY '       ' FUNCTION EXCEPTION-FILE
25.        DISPLAY '       ' FUNCTION EXCEPTION-STATUS
26.        DISPLAY '*** Returning to Standard Error Routine ***'
27.        EXIT PROGRAM
28.        .
29.    END PROGRAM ErrProc.

При выполнении эта программа генерирует следующий вывод в консоли.

E:\Programs\Demos>demoerrproc
Program is starting
Error: DemoERRPROC; S1; 12
       CALL
       00
       EC-PROGRAM-NOT-FOUND
*** Returning to Standard Error Routine ***
DEMOERRPROC.cbl: 27: libcob: Cannot find module 'Tilt'

E:\Programs\Demos>

8.2.26. CBL_EXIT_PROC

Синтаксис встроенной подпрограммы CBL_EXIT_PROC

 CALL "CBL_EXIT_PROC" USING function, program-pointer
 ~~~~                 ~~~~~

Эта процедура регистрирует общую процедуру обработки завершения.

Аргумент function должен быть числовым литералом или 32-битным бинарным элементом данных (USAGE BINARY-LONG, например) со значением 0 или 1. Значение 0 означает, что вы регистрируете («устанавливаете») процедуру выхода, а значение 1 указывает на дерегистрацию («снятие») ранее установленной процедуры выхода.

Аргумент program-pointer должен быть элементом данных с USAGE (см. USAGE) PROGRAM-POINTER, содержащим адрес вашей процедуры выхода.

Результат успеха (0) или неудачи (не 0) будет возвращен в специальный регистр RETURN-CODE (см. Специальные регистры).

Процедура выхода, после регистрации, будет вызываться всякий раз, когда выполняется оператор STOP RUN (см. STOP) или GOBACK (см. GOBACK) в любой части программы. Процедура выхода может выполнить любой необходимый код для упорядоченного завершения работы программы. После того, как процедура выхода завершится выполнением оператора EXIT PROGRAM (см. EXIT) или GOBACK (см. EXIT), будет выполнена системная стандартная процедура завершения программы.

Одновременно может быть активна только одна пользовательская процедура выхода.

Ниже приведен пример программы GnuCOBOL, регистрирующей процедуру выхода. Также показан вывод этой программы.

IDENTIFICATION DIVISION.
PROGRAM-ID. demoexitproc.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  Exit-Proc-Address           USAGE PROGRAM-POINTER.
PROCEDURE DIVISION.
000-Register-Exit-Proc.
    SET Exit-Proc-Address TO ENTRY "ExitProc"
    CALL "CBL_EXIT_PROC" USING 0, Exit-Proc-Address
    IF RETURN-CODE NOT = 0
        DISPLAY 'Error: Could not register Exit Procedure'
    END-IF
    .
099-Now-Test-Exit-Proc.
    DISPLAY
        'Executing a STOP RUN...'
    END-DISPLAY
    GOBACK.
END PROGRAM demoexitproc.

IDENTIFICATION DIVISION.
PROGRAM-ID. ExitProc.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  Display-Date                PIC XXXX/XX/XX.
01  Display-Time                PIC XX/XX/XX.
01  Now                         PIC X(8).
01  Today                       PIC X(8).
PROCEDURE DIVISION.
000-Main.
    DISPLAY '*** STOP RUN has been executed ***'
    ACCEPT Today FROM DATE YYYYMMDD
    ACCEPT Now   FROM TIME
    MOVE Today TO Display-Date
    MOVE Now   TO Display-Time
    INSPECT Display-Time REPLACING ALL '/' BY ':'
    DISPLAY '***    ' Display-Date '  ' Display-Time '    ***'
    GOBACK.
END PROGRAM ExitProc.

8.2.27. CBL_FLUSH_FILE

Синтаксис встроенной подпрограммы CBL_FLUSH_FILE

 CALL "CBL_FLUSH_FILE" USING file-handle
 ~~~~                  ~~~~~

В Micro Focus COBOL вызов этой подпрограммы очищает все ещё не записанные буферы для файла (вывода), дескриптор которого указан в качестве аргумента для диска.

Эта процедура не функциональна в GnuCOBOL. Она существует только для обеспечения совместимости с приложениями, которые могут быть разработаны для Micro Focus COBOL.

8.2.28. CBL_GC_FORK

Синтаксис встроенной подпрограммы CBL_GC_FORK

 CALL "CBL_GC_FORK" USING Child-PID
 ~~~~               ~~~~~

CBL_GC_FORK позволяет разделить текущий процесс COBOL на новый.

Текущее содержимое памяти процесса (включая LOCAL-STORAGE) будет идентичным, все дескрипторы файлов станут недействительными в новом процессе, позиции и блокировки файлов и записей доступны только исходному процессу.

Эта системная процедура недоступна в Windows (исключение: GCC на Cygwin).

Параметры: нет

Возвращаемое значение: pid (дочерний процесс получает ‘0’, вызывающий процесс получает pid созданного дочернего процесса).

Отрицательные значения возвращаются для системных кодов ошибок, и -1, если функция недоступна в текущей системе.

CBL_GC_FORK позволяет разделить текущий процесс COBOL на новый. Текущее содержимое памяти процесса (включая LOCAL-STORAGE) будет идентичным, все дескрипторы файлов станут недействительными в новом процессе, позиции и блокировки файлов/записей доступны только исходному процессу. Эта системная процедура недоступна в Windows (исключение: gcc в Cygwin). Параметры: нет Возвращаемое значение: pid (дочерний процесс получает 0, вызывающий процесс получает pid созданных дочерних процессов). Отрицательные значения возвращаются для системных кодов ошибок, и -1, если функция недоступна в текущей системе.

 IDENTIFICATION DIVISION.
 PROGRAM-ID. prog.
 DATA DIVISION.
 WORKING-STORAGE SECTION.
 01  CHILD-PID      PIC S9(9) BINARY.
 01  WAIT-STS       PIC S9(9) BINARY.
 PROCEDURE DIVISION.
     CALL     "CBL_GC_FORK" RETURNING CHILD-PID END-CALL
     EVALUATE TRUE
              WHEN CHILD-PID = ZERO
                   PERFORM CHILD-CODE
              WHEN CHILD-PID > ZERO
                   PERFORM PARENT-CODE
              WHEN CHILD-PID = -1
                   DISPLAY 'CBL_GC_FORK is not available on the current'
                   ' system!'
                   PERFORM CHILD-CODE
                   MOVE 0 TO CHILD-PID
                   PERFORM PARENT-CODE
              WHEN OTHER
                   MULTIPLY -1 BY CHILD-PID END-MULTIPLY
                   DISPLAY 'CBL_GC_FORK returned system error: ' CHILD-PID
     END-EVALUATE
     STOP     RUN.
 CHILD-CODE.
     CALL     "C$SLEEP" USING 1 END-CALL
     DISPLAY  "Hello, I am the child"
     MOVE     2 TO RETURN-CODE.
 PARENT-CODE.
     DISPLAY  "Hello, I am the parent"
     CALL     "CBL_GC_WAITPID" USING CHILD-PID RETURNING WAIT-STS
     MOVE     0 TO RETURN-CODE
     EVALUATE TRUE
              WHEN WAIT-STS >= 0
                   DISPLAY 'Child ended with status: ' WAIT-STS
              WHEN WAIT-STS = -1
                   DISPLAY 'CBL_GC_WAITPID is not available on the '
                   'current system!'
              WHEN WAIT-STS < -1
                   MULTIPLY -1 BY WAIT-STS END-MULTIPLY
                   DISPLAY 'CBL_GC_WAITPID returned system error: ' WAIT-STS
     END-EVALUATE.

8.2.29. CBL_GC_GETOPT

Синтаксис встроенной подпрограммы CBL_GC_GETOPT

 CALL "CBL_GC_GETOPT" USING BY REFERENCE SHORTOPTIONS LONGOPTIONS LONGIND
 ~~~~                 ~~~~~
                            BY VALUE LONG-ONLY
                            BY REFERENCE RETURN-CHAR OPT-VAL

CBL_GC_GETOPT адаптирует известный парсер опций getopt к GnuCOBOL.

Использование этой системной процедуры описано на примере.

 IDENTIFICATION DIVISION.
 PROGRAM-ID. PROG.
 DATA DIVISION.
 WORKING-STORAGE SECTION.
 78  SHORTOPTIONS VALUE "jkl".
 01  LONGOPTIONS.
     05 OPTIONRECORD OCCURS 2 TIMES.
        10  OPTIONNAME   PIC X(25).
        10  HAS-VALUE    PIC 9.
        10  VALPOINT     POINTER VALUE NULL.
        10  RETURN-VALUE PIC X(4).
 01  LONGIND             PIC 99.
 01  LONG-ONLY           PIC 9 VALUE 1.
 01  RETURN-CHAR         PIC X(4).
 01  OPT-VAL             PIC X(10).
 01  COUNTER             PIC 9 VALUE 0.

Сначала нам нужно определить необходимые поля для getopt’s shortoptions, longoptions, индекса длинной опции (longind), длинной опции (long-only) и также поля для значений возврата return-char и opt-val (произвольного размера с обрезкой, см. коды возврата).

shortoptions записываются как буквенно-цифровое поле (т.е., строка произвольного размера) следующим образом:

"ab:c::d"

Это означает, что мы хотим, чтобы getopt искал короткие опции с именами ‘a’, ‘b’, ‘c’ или ‘d’, требовать значения опции для ‘b’ и принимать необязательные значения для ‘c’.

longoptions определяются как таблица записей с oname, has-value, valpoint и val.5

oname определяет имя длинной опции. has-value определяет, требуется ли значение опции (has-val = 1), необязательно (has-val = 2) или не требуется (has-val = 0).

valpoint — указатель, используемый для указания адреса, в который нужно сохранить значение возврата getopt's. Указатель является необязательным. Если он NULL, getopt возвращает значение как обычно. Если вы используете указатель, он должен указывать на поле PIC X(4). Поле val — это PIC X(4) символ, который возвращается, если длинная опция распознана.

Структура длинной опции неизменна! Вы можете только изменить количество записей.

Теперь у нас есть инструменты для запуска CBL_GC_GETOPT в разделе Procedure Division.

PROCEDURE DIVISION.
     MOVE     "version" to OPTIONNAME (1).
     MOVE     0 TO HAS-VALUE (1).
     MOVE     ‘V’ TO RETURN-VALUE (1).
     MOVE     "verbose" TO OPTIONNAME (2).
     MOVE     0 TO HAS-VALUE (2).
     MOVE     ‘V’ TO RETURN-VALUE (2).
     PERFORM  WITH TEST AFTER UNTIL RETURN-CODE = -1
              CALL 'CBL_GC_GETOPT' USING
                  BY REFERENCE SHORTOPTIONS LONGOPTIONS LONGIND
                  BY VALUE LONG-ONLY
                  BY REFERENCE RETURN-CHAR OPT-VAL
              END-CALL
              DISPLAY RETURN-CHAR END-DISPLAY
              DISPLAY OPT-VAL END-DISPLAY
     END-PERFORM
     STOP RUN.

Пример показывает, как мы инициализируем все параметры и вызываем процедуру до тех пор, пока CBL_GC_GETOPT не исчерпает опции и не вернёт -1.

return-char может содержать следующие символы, если опция была распознана:

?

неопределённая или неоднозначная опция

1

не опция (только если первый байт so — ‘-’)

0

valpoint != NULL и мы записываем значение возврата по указанному адресу

-1

больше нет опций (или достигнута первая не опция, если первый байт shortoptions — ‘+’)

Коды возврата CBL_GC_GETOPT:

1

не опция (только если первый байт so — ‘-’)

0

valpoint != NULL и мы записываем значение возврата по указанному адресу

-1

больше нет опций (или достигнута первая не опция, если первый байт shortoptions — ‘+’)

2

обрезанное значение опции в opt-val (потому что opt-val было слишком маленьким)

3

обычный ответ от getopt

8.2.30. CBL_GC_HOSTED

Синтаксис встроенной подпрограммы CBL_GC_HOSTED

 CALL "CBL_GC_HOSTED" USING ARG-1  ARG-2
 ~~~~                 ~~~~~

 Note replaces CBL_OC_HOSTED which is kept as a legacy item.

CBL_GC_HOSTED предоставляет доступ к следующим переменным C, размещённым в памяти:

argc

binary-long by value

argv

pointer to char **

stdin, stdout, stderr

pointer

errno

указание адреса errno в указателе на binary-long, для получения более подробной информации используйте based

Прямой доступ и условный доступ к следующим переменным:

tzname

pointer to pointer to array of two char pointer

timezone

C long, будет секундами к западу от UTC

daylight

C int, примет значение 1 во время летнего времени

Для получения осмысленных результатов система потребует, чтобы HAVE TIMEZONE было определено. Попытки получить результат, когда значения не доступны, вернут 1 из CBL GC HOSTED.

Возвращает 0 при совпадении, 1 при ошибке. Различаются регистр и длина. "arg" не будет совпадать.

Использование этой системной процедуры описано в следующем примере.

IDENTIFICATION DIVISION.
 PROGRAM-ID. HOSTED.
 DATA DIVISION.
 WORKING-STORAGE SECTION.
 01  Argc        BINARY-LONG.
 01  Argv        POINTER.
 01  Stdin       POINTER.
 01  Stdout      POINTER.
 01  Stderr      POINTER.
 01  Errno       POINTER.
 01  Err         BINARY-LONG BASED.
 01  Domain      FLOAT-LONG VALUE 3.0.
 01  Tzname      POINTER.
 01  Tznames     POINTER BASED.
     05  Tzs     POINTER OCCURS 2.
 01  Timezone    BINARY-LONG.
 01  Daylight    BINARY-SHORT.
*>
 PROCEDURE DIVISION.
     call     "CBL_GC_HOSTED" using stdin "stdin"
     display  "stdin : " stdin
     call     "feof" using by value stdin
     display  "feof stdin : " return-code
     call     "CBL_GC_HOSTED" using stdout "stdout"
     display  "stdout : " stdout
     call     "fprintf" using by value stdout by content "Hello" & x"0a"
     call     "CBL_GC_HOSTED" using stderr "stderr"
     display  "stderr : " stderr
     call     "fprintf" using by value stderr by content "on err" & x"0a"
     call     "CBL_GC_HOSTED" using argc "argc"
     display  "argc : " argc
     call     "CBL_GC_HOSTED" using argv "argv"
     display  "argv : " argv
     call     "args" using by value argc argv
     call     "CBL_GC_HOSTED" using errno "errno"
     display  "&errno : " errno
     set      address of err to errno
     display  "errno : " err
     call     "acos" using by value domain
     display  "errno after acos(3.0): " err ", EDOM is 33"
     call     "CBL_GC_HOSTED" using argc "arg"
     display  "'arg' lookup : " return-code
     call     "CBL_GC_HOSTED" using null "argc"
     display  "null with argc : " return-code
     display  "argc is still : " argc
*> the following only returns zero if the system has HAVE_TIMEZONE set
     call     "CBL_GC_HOSTED" using daylight "daylight "
     display  "'timezone' lookup : " return-code
     if       return-code not = 0
              display "system doesn't has timezone"
     else
              display "timezone is : " timezone
              call "CBL_GC_HOSTED" using daylight "daylight "
              display "'daylight' lookup : " return-code
              display "daylight is : " daylight
              set environment "TZ" to "PST8PDT"
              call static "tzset" returning omitted on exception
                        continue end-call
              call "CBL_GC_HOSTED" using tzname "tzname"
              display "'tzname' lookup : " return-code
*> tzs(1) will point to z"PST" and tzs(2) to z"PDT"
              if   return-code equal 0 and tzname not equal null then
                   set address of tznames to tzname
                   if   tzs(1) not equal null then
                        display "tzs #1 : " tzs(1)
                   end-if
                   if   tzs(2) not equal null then
                        display "tzs #2 : " tzs(2)
                   end-if
              end-if
     end-if
     goback.
 end program hosted.

Обратите внимание, что устаревшее имя этой процедуры, начинающееся с CBL_OC, устарело, как и NANOSLEEP, но по-прежнему работает. Рекомендуется заменить все имена процедур библиотеки, начинающиеся с CBL_OC, на CBL_GC, чтобы минимизировать проблемы.

8.2.31. CBL_GC_NANOSLEEP

CBL_GC_NANOSLEEP Синтаксис встроенной подпрограммы

 CALL "CBL_GC_NANOSLEEP" USING nanoseconds-to-sleep
 ~~~~                    ~~~~~

 Note replaces CBL_OC_NANOSLEEP which is kept as a legacy item.

Эта подпрограмма приостанавливает выполнение программы на указанное количество наносекунд.

Эффективная точность значений nanoseconds-to-sleep зависит от точности системных часов вашего компьютера и точности тайминга операционной системы, на которой работает этот компьютер.

Например, вы не ожидаете увидеть разницы между значениями 1, 100, 500 или 1000, но вы должны увидеть разницу между значениями, такими как 250000000 и 500000000.

Аргумент nanoseconds-to-sleep — это числовая константа или элемент данных.

В одной секунде содержится один миллиард наносекунд, поэтому, если вы хотите приостановить программу на 1/4 секунды, используйте значение nanoseconds-to-sleep 250000000.

Обратите внимание, что устаревшее имя этой процедуры, начинающееся с «CBL_OC», устарело, как и HOSTED, но по-прежнему работает. Рекомендуется заменить все имена процедур библиотеки, начинающиеся с «CBL_OC», на «CBL_GC», чтобы минимизировать проблемы.

8.2.32. CBL_GC_PRINTABLE

CBL_GC_PRINTABLE Синтаксис встроенной подпрограммы

 CALL "CBL_GC_PRINTABLE" USING data-item [ , char ]
 ~~~~                    ~~~~~

Note replaces C$PRINTABLE which is kept as a legacy item.

Подпрограмма CBL_GC_PRINTABLE преобразует содержимое элемента данных, указанного в качестве первого аргумента, в печатные символы.

Символы, которые считаются печатными (как определено набором символов, используемым data-item), останутся неизменными, а символы, которые не являются печатными, будут преобразованы в символ, указанный в качестве второго аргумента.

Если аргумент char не указан, будет использоваться точка (‘.’).

8.2.33. CBL_GC_WAITPID

CBL_GC_WAITPID Синтаксис встроенной подпрограммы

 CALL "CBL_GC_WAITPID" USING ARG-1
 ~~~~                  ~~~~~
                       RETURNING RET-STATUS
                       ~~~~~~~~~

CBL_GC_WAITPID позволяет дождаться завершения другого системного процесса.

Кроме того, вы можете проверить код возврата процесса.

Параметры: нет

Возвращаемые значения: статус функции / статус дочернего процесса

Отрицательные значения возвращаются для системных кодов ошибок и -1, если функция недоступна в текущей системе.

CALL     "CBL_GC_WAITPID" USING CHILD-PID RETURNING WAIT-STS
MOVE     0 TO RETURN-CODE
DISPLAY  'CBL_GC_WAITPID ended with status: ' WAIT-STS

8.2.34. CBL_GET_CSR_POS

CBL_GET_CSR_POS Синтаксис встроенной подпрограммы

 CALL "CBL_GET_CSR_POS" USING cursor-locn-buffer
 ~~~~                   ~~~~~

Эта подпрограмма получит текущее положение курсора на экране, вернув 2-байтовое значение в предоставленный cursor-locn-buffer. Первый байт cursor-locn-buffer получит текущую строку (строку) расположения, а второй — текущее расположение столбца.

Возвращаемые данные о расположении будут в двоичном формате и будут основаны на начальных значениях 0, то есть, если курсор расположен в строке 15, столбце 12 в момент вызова этой процедуры, будет возвращено значение (14,11).

Ниже приведен типичный пример определения cursor-locn-buffer:

01  CURSOR-LOCN-BUFFER.
    05 CURSOR-LINE          USAGE BINARY-CHAR.
    05 CURSOR-COLUMN        USAGE BINARY-CHAR.

Значения 1 (строка) и 1 (столбец) будут возвращены, если GnuCOBOL не был сгенерирован для включения ввода-вывода экрана.

8.2.35. CBL_GET_CURRENT_DIR

CBL_GET_CURRENT_DIR Синтаксис встроенной подпрограммы

 CALL "CBL_GET_CURRENT_DIR" USING BY VALUE 0,
 ~~~~                       ~~~~~    ~~~~~
                                  BY VALUE length,
                                     ~~~~~
                                  BY REFERENCE buffer
                                     ~~~~~~~~~

Эта процедура получает полностью квалифицированный путь текущей директории, сохраняя до length символов этого имени в buffer.

Первый аргумент не используется, но должен быть указан. Он должен быть указан BY VALUE (см. ВЫЗОВ).

Аргумент length должен быть указан BY VALUE. Аргумент buffer должен быть указан BY REFERENCE.

Указанное значение для аргумента length (числовая константа или элемент данных) не должно превышать фактической длины аргумента buffer.

Если значение, указанное для аргумента length, меньше фактической длины аргумента buffer, путь к текущей директории будет выровнен по левому краю и заполнен пробелами в первых length байтах buffer — любые байты в buffer после этой точки останутся неизменными.

Если процедура выполнена успешно, значение 0 будет возвращено в специальный регистр (см. Специальные регистры). Если процедура завершилась неудачно из-за проблемы с аргументом (например, отрицательной или нулевой длиной), результат будет 128. Наконец, если значение первого аргумента не равно нулю, процедура завершится с значением 129.

8.2.36. CBL_GET_SCR_SIZE

Синтаксис встроенной подпрограммы CBL_GET_SCR_SIZE

 CALL "CBL_GET_SCR_SIZE" USING no-of-lines, no-of-cols
 ~~~~                    ~~~~~

Используйте эту подпрограмму для получения текущего размера экрана консоли.

Когда система работает в оконном режиме, это будет размер окна консоли, в котором выполняется программа. Когда система не работает в оконном режиме, будут возвращены атрибуты физического экрана консоли. В таких средах, как окно консоли Windows, где логический размер окна может значительно превышать размер физического окна консоли, возвращаемый размер будет соответствовать размеру физического окна консоли. Будут возвращены два однобайтовых значения — первое будет текущим количеством строк (строк), а второе — количеством столбцов.

Возвращаемые данные размера будут в двоичном формате.

Ниже приведены типичные определения no-of-lines и no-of-columns:

01  NO-OF-LINES             USAGE BINARY-CHAR.
01  NO-OF-COLUMNS           USAGE BINARY-CHAR.

Управление экраном GnuCOBOL должно быть инициализировано до вызова этой подпрограммы для получения осмысленных значений. Это означает, что оператор DISPLAY screen-data-item (см. DISPLAY screen-data-item) или оператор ACCEPT screen-data-item (см. ACCEPT screen-data-item) должен быть выполнен до выполнения оператора CALL.

Если экран не был инициализирован, будут возвращены нулевые значения, а значения 24 (строк) и 80 (столбцов) будут возвращены, если GnuCOBOL не был сгенерирован для включения ввода-вывода экрана.

8.2.37. CBL_IMP

Синтаксис встроенной подпрограммы CBL_IMP

 CALL "CBL_IMP" USING item-1, item-2, BY VALUE byte-length
 ~~~~           ~~~~~                    ~~~~~
 Old    Old    New
Arg 1  Arg 2  Arg 2
 Bit    Bit    Bit
=====  =====  =====
  0      0      1
  0      1      1
  1      0      0
  1      1      1
Эта подпрограмма выполняет побитовое логическое имплицитное преобразование между левыми 8*byte-length соответствующими битами item-1 и item-2, сохраняя результирующую строку битов в item-2. Таблица истинности слева документирует процесс IMP. Аргумент item-1 может быть алфавитно-цифровым литералом или данными, а item-2 должен быть данными. Длина item-1 и item-2 должна быть не менее 8*byte-length.

Аргумент byte-length может быть числовым литералом или данными и должен быть указан с использованием BY VALUE (см. CALL).

Любые биты в item-2 после 8*byte-length точки останутся неизменными.

Результат ноль будет передан обратно в специальный регистр RETURN-CODE (см. Специальные регистры).

8.2.38. CBL_NIMP

Синтаксис встроенной подпрограммы CBL_NIMP

 CALL "CBL_NIMP" USING item-1, item-2, BY VALUE byte-length
 ~~~~            ~~~~~                    ~~~~~
 Old    Old    New
Arg 1  Arg 2  Arg 2
 Bit    Bit    Bit
=====  =====  =====
  0      0      0
  0      1      0
  1      0      1
  1      1      0
Эта подпрограмма выполняет отрицание побитового логического имплицитного преобразования между левыми 8*byte-length соответствующими битами item-1 и item-2, сохраняя результирующую строку битов в item-2. Таблица истинности слева документирует процесс NIMP. Аргумент item-1 может быть алфавитно-цифровым литералом или данными, а item-2 должен быть данными. Длина item-1 и item-2 должна быть не менее 8*byte-length.

Аргумент byte-length может быть числовым литералом или данными и должен быть указан с использованием BY VALUE (см. CALL).

Любые биты в item-2 после 8*byte-length точки останутся неизменными.

Результат ноль будет передан обратно в специальный регистр RETURN-CODE (см. Специальные регистры).

8.2.39. CBL_NOR

Синтаксис встроенной подпрограммы CBL_NOR

 CALL "CBL_NOR" USING item-1, item-2, BY VALUE byte-length
 ~~~~           ~~~~~                    ~~~~~
 Old    Old    New
Arg 1  Arg 2  Arg 2
 Bit    Bit    Bit
=====  =====  =====
  0      0      1
  0      1      0
  1      0      0
  1      1      0
Эта подпрограмма выполняет отрицание побитового логического или преобразования между левыми 8*byte-length соответствующими битами item-1 и item-2, сохраняя результирующую строку битов в item-2. Таблица истинности слева документирует процесс NOR. Аргумент item-1 может быть алфавитно-цифровым литералом или данными, а item-2 должен быть данными. Длина item-1 и item-2 должна быть не менее 8*byte-length.

Аргумент byte-length может быть числовым литералом или данными и должен быть указан с использованием BY VALUE (см. CALL).

Любые биты в item-2 после 8*byte-length точки останутся неизменными.

Результат ноль будет передан обратно в специальный регистр RETURN-CODE (см. Специальные регистры).

8.2.40. CBL_NOT

Синтаксис встроенной подпрограммы CBL_NOT

 CALL "CBL_NOT" USING item-1, BY VALUE byte-length
 ~~~~           ~~~~~            ~~~~~

Эта подпрограмма «инвертирует» левые 8*byte-length битов item-1, меняя биты 0 на 1, и биты 1 на 0. Изменения выполняются непосредственно в item-1.

Аргумент item-1 должен быть элементом данных. Длина item-1 должна быть не менее 8*byte-length.

Аргумент byte-length может быть числовой литералью или элементом данных и должен быть передан с помощью BY VALUE (см. CALL).

Любые биты в item-1 после позиции 8*byte-length не будут затронуты.

Результат нулевого значения будет возвращен в специальный регистр RETURN-CODE (см. Специальные регистры).

8.2.42. CBL_OPEN_FILE

Синтаксис встроенной подпрограммы CBL_OPEN_FILE

 CALL "CBL_OPEN_FILE" USING file-path, access-mode, 0, 0, handle
 ~~~~                 ~~~~~

Эта подпрограмма открывает существующий файл для использования в качестве файла потока байтов, который можно использовать с CBL_WRITE_FILE или CBL_READ_FILE.

Аргумент file-path является буквенно-цифровой литералью или элементом данных.

Аргумент access-mode — это числовая литераль или элемент данных с PIC X USAGE COMP-X (или USAGE BINARY-CHAR) определением; он определяет, как вы хотите использовать файл следующим образом:

1

вход (только чтение)

2

выход (только запись)

3

ввод и/или вывод

Третий и четвертый аргументы определяли бы режим блокировки и спецификацию устройства соответственно, но они не реализованы в GnuCOBOL (по крайней мере, на данный момент) — просто укажите каждый как 0.

Последний аргумент (handle) — это элемент PIC X(4) USAGE COMP-X, который получит дескриптор файла. Этот дескриптор используется во всех других функциях потока байтов для ссылки на этот конкретный файл.

Значение специального регистра RETURN-CODE (см. Специальные регистры) -1 указывает на неверный аргумент, а значение 0 — на успех. Значение 35 означает, что файл не существует.

8.2.43. CBL_OR

Синтаксис встроенной подпрограммы CBL_OR

 CALL "CBL_OR" USING item-1, item-2, BY VALUE byte-length
 ~~~~          ~~~~~                    ~~~~~
 Old    Old    New
Arg 1  Arg 2  Arg 2
 Bit    Bit    Bit
=====  =====  =====
  0      0      0
  0      1      1
  1      0      1
  1      1      1
Эта подпрограмма выполняет побитовое логическое или-действие между 8*byte-length соответствующими битами слева item-1 и item-2, сохраняя результирующую строку битов в item-2. Таблица истинности, показанная слева, документирует OR процесс. Аргумент item-1 может быть буквенно-цифровой литералью или элементом данных, а item-2 — элементом данных. Длина обоих item-1 и item-2 должна быть не менее 8*byte-length.

Аргумент byte-length может быть числовой литералью или элементом данных и должен быть указан с помощью BY VALUE (см. CALL).

Любые биты в item-2 после точки 8*byte-length не будут затронуты.

Результат нулевого значения будет возвращен в специальный регистр RETURN-CODE (см. Специальные регистры).

8.2.44. CBL_READ_FILE

Синтаксис встроенной подпрограммы CBL_READ_FILE

 CALL "CBL_READ_FILE" USING handle, offset, nbytes, flag, buffer
 ~~~~                 ~~~~~

Эта подпрограмма считывает nbytes данных, начиная с байта с номером offset из потокового файла байтов, определенного handle, в buffer.

Аргумент handle (PIC X(4) USAGE COMP-X) должен быть заполнен предыдущим вызовом CBL_OPEN_FILE встроенной системной подпрограммы (см. CBL_OPEN_FILE).

Аргумент offset (PIC X(8) USAGE COMP-X) определяет положение в файле первого байта для чтения. Первый байт файла имеет смещение 0.

Аргумент nbytes (PIC X(4) USAGE COMP-X) определяет количество байтов (максимум), которые будут считаны. Если аргумент flag указан как 128, размер файла (в байтах) будет возвращен в аргумент смещения файла (аргумент 2) после завершения. Не все операционные системы/среды GnuCOBOL могут получить размер файла в таких случаях, будет возвращено значение ноль. Единственное другое допустимое значение для флагов — 0. Этот аргумент можно указать как числовую литераль или как PIC X USAGE COMP-X элемент данных.

После завершения RETURN-CODE специальный регистр (см. Специальные регистры) будет установлен в 0, если чтение было успешным, или в 10, если возникло состояние «конец файла». Если возвращено значение -1, с аргументами подпрограммы была обнаружена проблема.

8.2.45. CBL_READ_KBD_CHAR

Синтаксис встроенной подпрограммы CBL_READ_KBD_CHAR

 CALL "CBL_READ_KBD_CHAR" USING char RETURNING status-code.
 ~~~~                     ~~~~~      ~~~~~~~~~

Ожидает, пока символ не будет введен с терминала, а затем читает его без отображения.

Параметры: char PIC X. Получает введенный символ в ASCII.

код_статуса PIC XX COMP-5.

Если RETURNING не используется, специальный регистр RETURN-CODE получает код статуса, где ноль означает успех, а ненулевое значение — нет.

[Вышеприведенная информация взята из руководства MF WB].

8.2.46. CBL_RENAME_FILE

Синтаксис встроенной подпрограммы CBL_RENAME_FILE

 CALL "CBL_RENAME_FILE" USING old-file-path, new-file-path
 ~~~~                   ~~~~~

Вы можете использовать эту подпрограмму для переименования файла.

Файл, указанный в old-file-path, будет «переименован» в имя, указанное в new-file-path. Каждый аргумент может быть буквенно-цифровой литералью или элементом данных.

Несмотря на то, что название этой процедуры может заставить вас поверить в то, что она просто переименовывает файл, на самом деле она перемещает файл, указанный в качестве 1-го аргумента, в файл, указанный в качестве 2-го аргумента. Представьте себе последовательность из двух шагов: сначала копирование файла old-file-path в файл new-file-path, а затем второй шаг, где old-file-path удаляется.

Если попытка переместить файл завершается неудачей (например, файла не существует), специальный регистр RETURN-CODE будет установлен в 128; при успешном завершении он будет установлен в 0.

8.2.47. CBL_SET_CSR_POS

CBL_SET_CSR_POS Синтаксис встроенной подпрограммы

 CALL "CBL_SET_CSR_POS" USING cursor-locn-buffer ?
 ~~~~                   ~~~~~

Установить текущую позицию на терминале.

8.2.48. CBL_TOLOWER

CBL_TOLOWER Синтаксис встроенной подпрограммы

 CALL "CBL_TOLOWER" USING data-item, BY VALUE convert-length
 ~~~~               ~~~~~               ~~~~~

Эта подпрограмма преобразует первые convert-length (числовая константа или элемент данных) символов из data-item (идентификатор буквенно-цифрового элемента) в нижний регистр.

Аргумент convert-length должен быть указан BY VALUE (см. CALL). Он определяет количество (ведущих) символов в элементе данных, которые будут преобразованы — все символы после этого останутся без изменений.

Если convert-length отрицателен или равен нулю, преобразование не будет выполнено.

8.2.49. CBL_TOUPPER

CBL_TOUPPER Синтаксис встроенной подпрограммы

 CALL "CBL_TOUPPER" USING data-item, BY VALUE convert-length
 ~~~~               ~~~~~               ~~~~~

Эта подпрограмма преобразует первые convert-length (числовая константа или элемент данных) символов из data-item (идентификатор буквенно-цифрового элемента) в верхний регистр.

Аргумент convert-length должен быть указан BY VALUE (см. CALL). Он определяет количество (ведущих) символов в элементе данных, которые будут преобразованы — все символы после этого останутся без изменений.

Если convert-length отрицателен или равен нулю, преобразование не будет выполнено.

8.2.50. CBL_WRITE_FILE

CBL_WRITE_FILE Синтаксис встроенной подпрограммы

 CALL "CBL_WRITE_FILE" USING handle, offset, nbytes, 0, buffer
 ~~~~                  ~~~~~

Эта подпрограмма записывает nbytes данных из buffer в поток байтов файла, определённый handle, начиная с байта с номером offset в файле.

Аргумент handle (PIC X(4) USAGE COMP-X) должен быть заполнен предыдущим вызовом CBL_OPEN_FILE. Аргумент offset (PIC X(4) USAGE COMP-X) определяет местоположение в файле первого байта, который будет записан. Первый байт файла имеет смещение 0.

Аргумент nbytes (PIC X(4) USAGE COMP-X) указывает количество (максимальное) байтов, которые будут записаны.

В настоящее время единственное допустимое значение для аргумента flags равно 0. Этот аргумент можно указать либо как числовую константу, либо как PIC X(1) USAGE COMP-X элемент данных.

После завершения RETURN-CODE специальный регистр (см. Специальные регистры) будет установлен в 0, если запись прошла успешно, или в 30, если произошла ошибка ввода-вывода. Если возвращается значение -1, проблема была обнаружена с аргументами подпрограммы.

8.2.51. CBL_XOR

CBL_XOR Синтаксис встроенной подпрограммы

 CALL "CBL_XOR" USING item-1, item-2, BY VALUE byte-length
 ~~~~           ~~~~~                    ~~~~~
 Old    Old    New
Arg 1  Arg 2  Arg 2
 Bit    Bit    Bit
=====  =====  =====
  0      0      0
  0      1      1
  1      0      1
  1      1      0
Эта подпрограмма выполняет побитовое логическое исключающее ИЛИ между левыми 8*byte-length соответствующими битами item-1 и item-2, сохраняя результирующую строку битов в item-2. Таблица истинности, показанная слева, документирует XOR процесс. Аргумент item-1 может быть буквенно-цифровой константой или элементом данных, а item-2 должен быть элементом данных. Длина обоих item-1 и item-2 должна быть как минимум 8*byte-length.

Аргумент byte-length может быть числовой константой или элементом данных и должен быть указан с помощью BY VALUE (см. CALL).

Любые биты в item-2 после точки 8*byte-length не будут затронуты.

Результат 0 будет возвращён в RETURN-CODE специальный регистр (см. Специальные регистры).

8.2.52. SYSTEM

SYSTEM Синтаксис встроенной подпрограммы

 CALL "SYSTEM" USING command
 ~~~~          ~~~~~

Эта подпрограмма отправляет command (буквенно-цифровая константа или элемент данных) в командную оболочку для выполнения так, как будто она была введена в окно консоли/терминала.

Оболочка будет открыта в подчинении программе GnuCOBOL, вызывающей SYSTEM.

Вывод команды (если таковой имеется) будет отображаться в окне команд, в котором была запущена программа GnuCOBOL.

В системе Unix среда оболочки будет создана с использованием программы стандартной оболочки. Это также верно при использовании сборки GnuCOBOL, созданной с использованием и для OSX или эмулятора Unix Cygwin.

При использовании собственных сборок Windows/MinGW среда оболочки будет командным процессором окна консоли Windows (обычно cmd.exe) соответствующим используемой версии Windows.

Чтобы перехватить вывод выполненной команды и обработать его внутри программы GnuCOBOL, используйте перенаправление («>»), чтобы направить вывод команды в временный файл, который вы прочитаете внутри программы после возвращения управления.

Код завершения выполненной команды будет доступен в RETURN-CODE специальном регистре.

8.2.53. X"91"

X"91" Синтаксис встроенной подпрограммы

 CALL X"91" USING return-code, function-code, binary-variable-arg
 ~~~~       ~~~~~

Оригинальная версия Micro Focus этой процедуры способна предоставлять широкий спектр функций. GnuCOBOL поддерживает только три из них:

  • Включение управляющих переключателей выполнения (SWITCH-1, … , SWITCH-8)
  • Выключение управляющих переключателей выполнения (SWITCH-1, … , SWITCH-8)
  • Получение количества аргументов, переданных подпрограмме.

Аргумент return-code должен быть однобайтовым двоичным числовым данными (рекомендуется USAGE BINARY-CHAR). Он получит значение 0, если операция выполнена успешно, и 1 в противном случае.

Аргумент function-code должен быть либо числовой литеральной, либо однобайтовой двоичной числовой данными (рекомендуется USAGE BINARY-CHAR).

Третий аргумент — variable-arg — определяется по-разному в зависимости от значения function-code, как указано ниже:

11

Устанавливает и/или сбрасывает все восемь переключателей COBOL (SWITCH-1 до SWITCH-8). См. SPECIAL-NAMES для объяснения этих переключателей.

Аргумент variable-arg должен быть таблицей OCCURS 8 TIMES из USAGE BINARY-CHAR.

Каждая запись, установленная в значение ноль до CALL X"91", приведет к сбросу соответствующего переключателя. Каждая запись, установленная в 1 до CALL X"91", приведет к установке соответствующего переключателя.

Значения, отличные от 0 или 1, будут проигнорированы.

12

Считывает все восемь переключателей COBOL (SWITCH-1 до SWITCH-8)

Аргумент variable-arg должен быть таблицей OCCURS 8 TIMES из USAGE BINARY-CHAR.

Первые восемь элементов массива будут установлены в 0 или 1 — 1, если соответствующий переключатель установлен, 0 в противном случае.

16

Получает количество аргументов, переданных программе, выполняющей CALL X"91", сохраняя это число в аргументе variable-arg. Это должно быть двоичное числовое поле (рекомендуется USAGE BINARY-CHAR).

8.2.54. X"E4"

X"E4" Синтаксис встроенной подпрограммы

 CALL X"E4"
 ~~~~

Используйте X"E4" для очистки экрана. Аргументов нет, и значения не возвращаются.

8.2.55. X"E5"

X"E5" Синтаксис встроенной подпрограммы

 CALL X"E5"
 ~~~~

Процедура X"E5" прозвучит звуковой сигнал на ПК. Аргументов нет, и значения не возвращаются.

8.2.56. X"F4"

X"F4" Синтаксис встроенной подпрограммы

 CALL X"F4" USING byte, table
 ~~~~       ~~~~~

Эта процедура упаковывает младший (правый) бит из каждого из восьми 1-байтовых элементов в table в соответствующие битовые позиции однобайтового поля данных byte.

Поле данных byte должно быть только одного байта. Если оно длиннее, избыток не повлияет на эту подпрограмму.

Поле данных table должно быть как минимум 8 байт длиной. Если оно длиннее, избыток будет проигнорирован этой подпрограммой.

Обычно таблица определяется следующим образом:

01  Table-Arg.
    05 Each-Byte OCCURS 8 TIMES USAGE BINARY-CHAR.

8.2.57. X"F5"

X"F5" Синтаксис встроенной подпрограммы

 CALL X"F5" USING byte, table
 ~~~~       ~~~~~

Эта процедура распаковывает каждый бит однобайтового поля данных byte в младший (правый) бит каждого из соответствующих восьми 1-байтовых элементов в table. Остальные семь битовых позиций каждого из первых восьми элементов в table будут установлены в ноль.

Поле данных byte должно быть только одного байта. Если оно длиннее, избыток не повлияет на эту подпрограмму.

Поле данных table должно быть как минимум 8 байт длиной. Если оно длиннее, избыток будет проигнорирован этой подпрограммой.

Обычно таблица определяется следующим образом:

01  Table-Arg.
    05 Each-Byte OCCURS 8 TIMES USAGE BINARY-CHAR.

9. Использование модуля отчётов

9.1. Лексикон RWCS

Существует ряд терминов, описывающих различные аспекты работы системы управления модулем отчетов (RWCS). Понимание значений этих терминов имеет решающее значение для понимания данной темы.

Разрыв управления

Событие, которое срабатывает, когда значение поля управления в отчете, сгенерированном RWCS, изменяется. Именно эти события запускают генерацию групп заголовка и подвала управления.

Поле управления

Поле данных, отображаемое в группе деталей; по мере представления различных групп деталей, составляющих отчет, предполагается, что они появляются в отсортированном порядке полей управления, содержащихся в них. Например, отчет о продажах по отделам для сети магазинов, вероятно, будет отсортирован по номеру магазина и — внутри одинаковых номеров магазинов — дополнительно отсортирован по номеру отдела. Номер магазина, безусловно, будет служить полем управления для отчета, позволяя представлять группы заголовков управления перед каждой последовательностью групп деталей для одного и того же магазина и группы подвалов управления после каждой такой последовательности.

Подвал управления

Группа отчета, появляющаяся непосредственно после одной или нескольких групп деталей сгенерированного RWCS отчета. Такие создаются автоматически в результате разрыва управления. Этот тип группы обычно служит сводкой группы(и) деталей, предшествующей ей, как, например, в случае с отчетом о продажах для сети магазинов, где группы деталей, документирующие продажи по каждому отделу (по одному отделу на группу деталей) из одного и того же магазина, могут быть последовать за подвалом управления, который предоставляет сводку продаж по отделам для этого магазина.

Заголовок управления

Группа отчета, которая появляется непосредственно перед одной или несколькими группами деталей сгенерированного RWCS отчета. Такие создаются автоматически в результате разрыва управления. Этот тип группы обычно служит введением к группе(ам) деталей, которые следуют за ней, как, например, в случае с отчетом о продажах для сети магазинов, где группы деталей, документирующие продажи по каждому отделу (по одному отделу на группу деталей) из одного и того же магазина, могут быть предшествованы заголовком управления, указывающим полное название и местоположение магазина.

Группа деталей

Группа отчета, содержащая подробные данные, отображаемые для отчета.

Подвал страницы

Группа отчета, которая появляется внизу каждой страницы сгенерированного RWCS отчета. Информация, обычно встречающаяся в такой группе отчета, может быть:

  • Дата генерации отчета
  • Текущий номер страницы отчета
Заголовок страницы

Группа отчета, которая появляется вверху каждой страницы сгенерированного RWCS отчета. Информация, обычно встречающаяся в такой группе отчета, может быть:

  • Заголовок отчета
  • Дата генерации отчета
  • Текущий номер страницы отчета
  • Заголовки столбцов, описывающие поля в группе(ах) деталей
Подвал отчета

Группа отчета, которая встречается только один раз в сгенерированном RWCS отчете — как последняя представленная группа отчета. Они обычно служат визуальным указанием на то, что отчет завершен.

Группа отчета

Одна или несколько последовательных строк в отчете, которые служат общей информационной цели или функции. Например, строки текста, отображаемые вверху или внизу каждой напечатанной страницы отчета.

Заголовок отчета

Группа отчета, которая встречается только один раз в сгенерированном RWCS отчете — как первая представленная группа отчета. Они обычно служат введением к отчету.

9.2. Структура отчета

Каждый отчет имеет одинаковую базовую структуру, как показано здесь, хотя не все отчеты будут содержать все группы. На самом деле, это очень необычный отчет, который действительно содержит все эти группы:

  • ЗАГОЛОВОК ОТЧЕТА
  • ЗАГОЛОВОК СТРАНИЦЫ [1]
  • ЗАГОЛОВОК УПРАВЛЕНИЯ [2]
  • ГРУППА ДЕТАЛЕЙ [2]
  • ПОДВАЛ УПРАВЛЕНИЯ [2]
  • КОНЕЧНЫЙ ПОДВАЛ УПРАВЛЕНИЯ
  • ПОДВАЛ СТРАНИЦЫ [1]
  • ПОДВАЛ ОТЧЕТА
[1] Представлена по мере необходимости в отчете
[2] Повторяется по мере необходимости

Эти группы будут отображаться (печататься) на необходимом количестве отформатированных страниц. Ни одна группа отчета не будет пересекать границы страниц.

Управление постраничностью, соблюдение правила «группы не могут пересекать страницы» и почти каждый аспект генерации отчетов полностью контролируются системой управления созданием отчетов.

9.3. Структура страницы отчета

Каждая страница отчета разделена на максимум пять (5) областей, как показано на следующей диаграмме.

  _______________________________ 
 |                               |
 | Top-of-page Unusable Area     |—# Lines: LINES AT TOP (LINAGE)
 |_______________________________|
 |                               |—Line #: HEADING (RD)
 | Heading Area                  |
 |_______________________________|—Line #: FIRST DETAIL (RD) - 1
 |                               |—Line #: FIRST DETAIL (RD)
 |                               |
 | Body Area                     |—Line #: LAST CONTROL HEADING (RD)
 |                               |—Line #: LAST DETAIL (RD)
 |_______________________________|—Line #: FOOTING (RD)
 |                               |—Line #: FOOTING (RD) + 1
 | Footing Area                  |
 |_______________________________|
 |                               |
 | Bottom-of-page Unusable Area  |—# Lines: LINES AT BOTTOM (LINAGE)
 |_______________________________|

При описании отчета через RD (см. РАЗДЕЛ ОТЧЕТА) предложение, общее количество используемых строк указывается как значение PAGE LIMIT; это значение равно сумме количества строк в областях заголовка, тела и подвала.

Неиспользуемые области страницы (если таковые имеются) будут отображаться сверху и снизу этой области. Вы не указываете неиспользуемую область в RD, а скорее используете LINAGE (см. Описание файла/сортировки) в FD файла, к которому прикреплен отчет.

Различные группы отчета будут отображаться в различных областях страницы следующим образом:

REPORT HEADING

Область заголовка — Исключением из этого является ситуация, когда группа заголовка отчета содержит опцию NEXT GROUP NEXT PAGE (см. следующая группа); в этих случаях заголовок отчета будет представлен на отдельной странице (в любом месте этой страницы) в начале отчета.

PAGE HEADING

Область заголовка

CONTROL HEADING

Область тела, но строка заголовка управления не допускается после строки, указанной номером LAST CONTROL HEADING

DETAIL

Область тела, но строка группы детали отчета не допускается после строки, указанной номером LAST DETAIL

CONTROL FOOTING

Область тела, но строка группы подвала управления отчета не допускается после строки, указанной номером FOOTING

PAGE FOOTING

Область подвала

REPORT FOOTING

Область подвала — Исключением из этого является ситуация, когда группа подвала отчета содержит опцию NEXT PAGE в своем LINE (см. СТРОКА); в этих случаях подвал отчета будет представлен на отдельной странице в конце отчета.

9.4. Как RWCS создает страницы отчета

Отчет, созданный с помощью оператора WRITE (см. WRITE), будет содержать управляющую информацию о переносе. В частности, в файл отчета будут записаны символы перевода страницы (X’0C’) для поддержки опции оператора ADVANCING PAGE. Будет ли информация о строке отчета, созданной с помощью ADVANCING PAGE, до или после символа перевода страницы, зависит от того, запрограммировал ли программист WRITE record-name BEFORE ADVANCING PAGE или WRITE record-name AFTER ADVANCING PAGE, соответственно.

Реализация RWCS в GnuCOBOL не передает никакой управляющей информации о переносе в файлы отчетов — вместо этого она полагается на информацию, закодированную в RD для отчета (в частности, PAGE LIMITS и связанные опции) и генерируемом и управляемом внутри регистре LINE-COUNTER (см. Специальные регистры) для отчета, чтобы знать, когда передавать пустые строки в файл для заполнения конца печатной страницы.

Поскольку GnuCOBOL RWCS работает таким образом, чтобы разработать отчет, генерируемый RWCS, вам нужно будет знать ответы на следующие вопросы:

  1. На каком принтере(ах) будет печататься отчет?
  2. Какую ориентацию бумаги вы будете использовать — альбомную (длинная сторона бумаги вверху и внизу страницы) или портретную (длинная сторона бумаги слева и справа страницы)?
  3. Какой инструмент будет использоваться для печати отчета (прямая печать на устройство, notepad.exe, MS-Word, …)?
  4. Какой шрифт и размер шрифта будут использоваться для отчета при его печати? Отчеты, генерируемые RWCS, предполагают использование шрифта с фиксированной шириной, такого как «Courier», «Lucida Console», «Consolas» и аналогичных, так как шрифты с переменной шириной делают правильное выравнивание столбцов данных в отчетах практически невозможным.
  5. Если существуют области, которые нельзя печатать, по всем четырём краям бумаги? Это обычно вызвано самим принтером или его драйвером.
  6. Каково максимальное количество строк на странице, которое может быть напечатано на одном листе бумаги?
  7. Каково максимальное количество символов, которое можно напечатать в одной строке?

Узнав ответы на вопросы 1-4, вы легко можете определить ответы на оставшиеся вопросы следующим образом:

  1. Подготовьте текстовый файл, содержащий 100 и более записей, каждая из которых содержит числовую шкалу (123456789012345678901234…).
  2. Распечатайте файл в соответствии с вашими ответами на вопросы 1-4.
  3. Добавьте необходимые дополнительные цифры к каждой записи в вашем тестовом файле (если строки не были заполнены) или удалите символы с конца каждой записи, если строки переносились. Если вы внесли изменения, перепечатайте файл.
  4. Теперь, когда вы точно знаете, какой длины может быть каждая запись, добавьте дополнительные записи и перепечатайте. Продолжайте до тех пор, пока печать не перейдет на вторую страницу.
  5. Первая напечатанная вами страница теперь является идеальной моделью для использования при разработке отчетов — она показывает, учитывая ответы на вопросы 1-4, каждую доступную позицию для печати на странице! Количество напечатанных строк на этой странице становится значением PAGE LIMIT для RD.

Оставшиеся значения PAGE LIMIT могут быть установлены по мере необходимости для вашего отчета(ов).

Использование идентификатора вместо целого числа в спецификациях RD позволит вашей программе в момент выполнения адаптироваться к нескольким принтерам, шрифтам, размерам шрифтов и ориентации бумаги. Просто выполните вышеуказанные шаги для каждой комбинации, которую вы хотите, чтобы ваша программа поддерживала.

9.5. Иерархия управления

Каждый отчет, использующий контрольные разделы, имеет естественную иерархию этих контрольных разделов, основанную на порядке данных, из которых генерируется отчет. Это понятие лучше всего понять на примере, который предполагает разработку программы COBOL для обработки данных продаж, собранных с каждого компьютерного кассового аппарата в сети магазинов с несколькими отделами.

Приложение, которое собирает данные с различных кассовых аппаратов в каждом магазине, будет генерировать записи данных, которые выглядят для программы COBOL следующим образом:

01  Sales-For-Register.
    05 Sales-Date            PIC 9(8).
    05 Time-Collected        PIC 9(6).
    05 Register-Number       PIC 9(7).
    05 Store-Number          PIC 9(3).
    05 Department-Number     PIC 9(3).
    05 Total-Sales           PIC 9(6)V99.

Ваша задача состоит в разработке отчета, который показывает общую сумму продаж с каждого кассового аппарата и суммирует эти продажи по отделам внутри каждого магазина, по магазинам, а также генерирует общую сумму продаж за день по всем магазинам.

Для достижения этой цели вы будете использовать оператор SORT (см. SORT) для сортировки файла данных о продажах с кассовых аппаратов в:

  1. Возрастающей последовательности номера магазина
  2. Внутри каждого магазина данные будут отсортированы в порядке возрастания номера отдела
  3. Если в конкретном отделе определенного магазина есть несколько кассовых аппаратов, данные необходимо дополнительно отсортировать, чтобы кассовые аппараты были упорядочены в последовательности их номера.

Итак, предположим, что файл сортировки определен, и его структура записей (по существу, зеркало исходного файла данных) определена следующим образом:

01  Sorted-Sales-For-Register.
    05 Sorted-Sales-Date            PIC 9(8).
    05 Sorted-Time-Collected        PIC 9(6).
    05 Sorted-Register-Number       PIC 9(7).
    05 Sorted-Store-Number          PIC 9(3).
    05 Sorted-Department-Number     PIC 9(3).
    05 Sorted-Total-Sales           PIC 9(6)V99.

Тогда оператор SORT для достижения желаемой последовательности будет:

SORT SORT-FILE
    ASCENDING KEY Sorted-Store-Number
                  Sorted-Department-Number
                  Sorted-Register-Number
    USING Input-file
    OUTPUT PROCEDURE 100-Generate-Report

В результате сортировки наша программа может ожидать увидеть данные примерно так (дата, время и суммы продаж показаны как «…»):

   +-------------------- Register Number
   |      +------------- Store Number
   |      |  +---------- Department Number
   |      |  |
...0535240001001...
...0589130001001...
...0625174001001...
...0122234001002...
...0732345001002...
...0003423001003...
...2038774001004...
...0112646002001...
...9963348002002...
...3245677002003...
...4456778002003...
...0002345002004...

Из-за сортировки наиболее часто изменяющимся из трех ключей сортировки будет Sorted-Register-Number. Это по существу определяет уровень «детали» отчета.

Следующее по частоте изменения значение — это Sorted-Department-Number, а наименее часто изменяющееся значение — Sorted-Store-Number. Помните, что программа должна генерировать итоги каждый раз, когда изменяется одно из этих двух значений, а также итоговую сумму продаж в конце отчета. Эти три момента являются контрольными точками отчета.

При определении отчета его RD будет содержать CONTROLS ARE предложение, перечисляющее контрольные точки в порядке наименьшей к наибольшей частоте изменения. Это будет закодировано как:

CONTROLS ARE FINAL, Sorted-Store-Number, Sorted-Department-Number

Контрольная точка FINAL происходит только один раз, в самом конце отчета. CONTROL FOOTING для этой точки будет той, которая производит общую сумму продаж по всем магазинам.

Следующая точка, перечисленная в CONTROLS предложении, — это та, которая встречается следующей по частоте (Sorted-Store-Number). Эта контрольная точка будет той, которая производит суммирование по всему магазину, и будет иметь свою CONTROL FOOTING.

Следующая (и последняя в данном случае) точка, перечисленная в CONTROLS предложении, — это та, которая встречается еще чаще (Sorted-Department-Number). CONTROL FOOTING для этого поля будет тем, которое суммирует продажи по каждому отделу в магазине.

Эта последовательность контрольных точек от наименее часто встречающейся к наиболее часто встречающейся (то есть в порядке их появления в CONTROLS ARE предложении) — это «иерархия контрольных точек» отчета; контрольные точки, которые встречаются чаще, чем другие, считаются находящимися на более низком уровне в иерархии контрольных точек.

Определение иерархии контрольных точек (через CONTROLS ARE) которая не соответствует фактической последовательности обработки данных, — это отличный способ гарантировать «нерабочий» отчет. Я покажу вам пример в следующей части.

9.6. Пример

Этот раздел содержит пример работы RWCS. Полная программа, представленная здесь, — это упрощенная версия программы, которую я использовал для генерации отчета для курса, который я преподаю по аппаратным средствам ПК. Этот отчет предоставит статистику производительности различных популярных процессоров AMD и Intel. Данные для отчета были получены с сайта www.cpubenchmark.net в декабре 2013 года. К тому времени, когда вы будете читать это, эти данные, скорее всего, станут устаревшими, но они достаточно хорошо иллюстрируют RWCS.

9.6.1. Данные

Вот данные, которые программа будет читать. Каждая запись отражает агрегированную оценку производительности одного конкретного процессора, поскольку оценки результатов тестов для этого процессора были отправлены на сайт cpubenchmark.net программным обеспечением PassMark для тестирования производительности. Данные состоят из четырех полей. Поля разделены друг от друга запятой. Описания полей следующие:

Оценка производительности

Пятизначное число, показывающее агрегированные оценки производительности процессора; чем выше это число, тем лучше процессор показал себя в тестах производительности.

Производитель

Название производителя процессора. В этих данных это будет либо «AMD» (American Micro Devices), либо «INTEL».

Серия

Семейство процессоров (7 символов), к которому принадлежит процессор. Это могут быть такие значения, как «A4», «A10», «Core i5», «Core i7» и т. д.

Модель

Конкретная модель процессора в рамках семейства.

Первая строка данных, показанная ниже, показывает, что агрегированная оценка всех тестов производительности для процессора AMD A10-4600M составляет 3145, по сравнению со второй строкой, которая показывает, что агрегированная оценка всех тестов производительности для процессора Intel Core-i7-4960X составляет 14291.

Ниже приводится полный набор входных данных, используемых для этого примера. Это отнюдь не полный набор данных, доступный на cpubenchmark.net — это просто представительная выборка, используемая в этом примере. Для моего класса я даю своим студентам отчет, показывающий результаты почти для тысячи процессоров.

Для краткости, в этом документе данные перечислены в трех столбцах.

03145,AMD,A10,4600M            05421,AMD,FX,6100              03917,Intel,Core i5,4300U
14291,Intel,Core i7,4960X      05813,AMD,FX,6120              01743,Intel,Core i5,4300Y
02505,AMD,A10,4655M            06194,AMD,FX,6200              04804,Intel,Core i5,4330M
03449,AMD,A10,4657M            06388,AMD,FX,6300              03604,Intel,Core i5,4350U
04251,AMD,A10,5700             07017,AMD,FX,6350              06282,Intel,Core i5,4430
02758,AMD,A10,5745M            06163,AMD,FX,8100              05954,Intel,Core i5,4430S
03332,AMD,A10,5750M            06605,AMD,FX,8120              06517,Intel,Core i5,4440
03253,AMD,A10,5757M            06845,AMD,FX,8140              07061,Intel,Core i5,4570
04798,AMD,A10,5800B            07719,AMD,FX,8150              06474,Intel,Core i5,4570R
04677,AMD,A10,5800K            08131,AMD,FX,8320              06803,Intel,Core i5,4570S
04767,AMD,A10,6700             09067,AMD,FX,8350              02503,Intel,Core i5,4570T
05062,AMD,A10,6800K            09807,AMD,FX,9370              07492,Intel,Core i5,4670
00677,AMD,A4,1200              10479,AMD,FX,9590              07565,Intel,Core i5,4670K
00559,AMD,A4,1250              03076,Intel,Core i3,3110M      06351,Intel,Core i5,4670T
01583,AMD,A4,3300              03301,Intel,Core i3,3120M      03701,Intel,Core i7,3517U
01237,AMD,A4,3300M             03655,Intel,Core i3,3130M      03449,Intel,Core i7,3517UE
01227,AMD,A4,3305M             03820,Intel,Core i3,3210       04588,Intel,Core i7,3520M
01263,AMD,A4,3310MX            02266,Intel,Core i3,3217U      03912,Intel,Core i7,3537U
01193,AMD,A4,3320M             04219,Intel,Core i3,3220       04861,Intel,Core i7,3540M
01343,AMD,A4,3330MX            03724,Intel,Core i3,3220T      04009,Intel,Core i7,3555LE
01625,AMD,A4,3400              04407,Intel,Core i3,3225       06144,Intel,Core i7,3610QE
01768,AMD,A4,3420              02575,Intel,Core i3,3227U      07532,Intel,Core i7,3610QM
01685,AMD,A4,4300M             01885,Intel,Core i3,3229Y      06988,Intel,Core i7,3612QE
01169,AMD,A4,4355M             04259,Intel,Core i3,3240       06907,Intel,Core i7,3612QM
01919,AMD,A4,5000              03793,Intel,Core i3,3240T      05495,Intel,Core i7,3615QE
01973,AMD,A4,5150M             04414,Intel,Core i3,3245       07310,Intel,Core i7,3615QM
02078,AMD,A4,5300              04757,Intel,Core i3,3250       07759,Intel,Core i7,3630QM
01632,AMD,A4,5300B             03443,Intel,Core i3,4000M      07055,Intel,Core i7,3632QM
02305,AMD,A4,6300              02459,Intel,Core i3,4010U      06516,Intel,Core i7,3635QM
01634,AMD,A6,1450              02003,Intel,Core i3,4010Y      04032,Intel,Core i7,3667U
01964,AMD,A6,3400M             04904,Intel,Core i3,4130       04271,Intel,Core i7,3687U
02101,AMD,A6,3410MX            04041,Intel,Core i3,4130T      03479,Intel,Core i7,3689Y
02078,AMD,A6,3420M             05115,Intel,Core i3,4330       08347,Intel,Core i7,3720QM
02277,AMD,A6,3430MX            05117,Intel,Core i3,4340       08512,Intel,Core i7,3740QM
01995,AMD,A6,3500              03807,Intel,Core i5,3210M      09420,Intel,Core i7,3770
02798,AMD,A6,3600              03995,Intel,Core i5,3230M      09578,Intel,Core i7,3770K
02892,AMD,A6,3620              03126,Intel,Core i5,3317U      09074,Intel,Core i7,3770S
03232,AMD,A6,3650              04101,Intel,Core i5,3320M      08280,Intel,Core i7,3770T
03327,AMD,A6,3670              05902,Intel,Core i5,3330       08995,Intel,Core i7,3820
01630,AMD,A6,4400M             05690,Intel,Core i5,3330S      08548,Intel,Core i7,3820QM
01296,AMD,A6,4455M             05781,Intel,Core i5,3335S      09025,Intel,Core i7,3840QM
02440,AMD,A6,5200              03280,Intel,Core i5,3337U      09196,Intel,Core i7,3920XM
01958,AMD,A6,5350M             02252,Intel,Core i5,3339Y      12107,Intel,Core i7,3930K
01878,AMD,A6,5357M             06282,Intel,Core i5,3340       09052,Intel,Core i7,3940XM
01906,AMD,A6,5400B             04327,Intel,Core i5,3340M      12718,Intel,Core i7,3960X
02174,AMD,A6,5400K             05372,Intel,Core i5,3340S      12823,Intel,Core i7,3970X
02384,AMD,A6,6400K             06199,Intel,Core i5,3350P      03992,Intel,Core i7,4500U
02050,AMD,A8,3500M             04314,Intel,Core i5,3360M      04507,Intel,Core i7,4558U
02426,AMD,A8,3510MX            04555,Intel,Core i5,3380M      04892,Intel,Core i7,4600M
02245,AMD,A8,3520M             03589,Intel,Core i5,3427U      04484,Intel,Core i7,4600U
02276,AMD,A8,3530MX            03479,Intel,Core i5,3437U      03680,Intel,Core i7,4610Y
02866,AMD,A8,3550MX            03057,Intel,Core i5,3439Y      04345,Intel,Core i7,4650U
03215,AMD,A8,3800              06442,Intel,Core i5,3450       07352,Intel,Core i7,4700EQ
03217,AMD,A8,3820              06071,Intel,Core i5,3450S      08161,Intel,Core i7,4700HQ
03552,AMD,A8,3850              06576,Intel,Core i5,3470       07946,Intel,Core i7,4700MQ
03682,AMD,A8,3870K             06077,Intel,Core i5,3470S      08002,Intel,Core i7,4702HQ
02709,AMD,A8,4500M             04591,Intel,Core i5,3470T      07647,Intel,Core i7,4702MQ
02193,AMD,A8,4555M             05991,Intel,Core i5,3475S      08066,Intel,Core i7,4750HQ
04052,AMD,A8,5500              06828,Intel,Core i5,3550       07367,Intel,Core i7,4765T
03464,AMD,A8,5500B             06631,Intel,Core i5,3550S      09969,Intel,Core i7,4770
02434,AMD,A8,5545M             06993,Intel,Core i5,3570       10190,Intel,Core i7,4770K
03052,AMD,A8,5550M             07118,Intel,Core i5,3570K      09803,Intel,Core i7,4770S
02935,AMD,A8,5557M             06709,Intel,Core i5,3570S      08803,Intel,Core i7,4770T
04348,AMD,A8,5600K             05414,Intel,Core i5,3570T      10078,Intel,Core i7,4771
04390,AMD,A8,6500              04333,Intel,Core i5,4200M      08567,Intel,Core i7,4800MQ
04719,AMD,A8,6600K             03355,Intel,Core i5,4200U      09969,Intel,Core i7,4820K
04055,AMD,FX,4100              02358,Intel,Core i5,4200Y      09331,Intel,Core i7,4850HQ
04153,AMD,FX,4130              02382,Intel,Core i5,4210Y      09323,Intel,Core i7,4900MQ
04094,AMD,FX,4150              03482,Intel,Core i5,4250U      13620,Intel,Core i7,4930K
04774,AMD,FX,4170              04381,Intel,Core i5,4258U      09754,Intel,Core i7,4930MX
04711,AMD,FX,4300              04663,Intel,Core i5,4288U      10262,Intel,Core i7,4960HQ
05247,AMD,FX,4350              04786,Intel,Core i5,4300M

9.6.2. Программа

Вот программа, которая будет генерировать отчет. Обратите внимание на то, как сортируются данные и как иерархия управления (CONTROLS ARE) связана с SORT.

IDENTIFICATION DIVISION.
PROGRAM-ID. DEMORWCS.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY. FUNCTION ALL INTRINSIC.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT CPU-FILE             ASSIGN TO "CPUDATA.txt"
                                LINE SEQUENTIAL.
    SELECT REPORT-FILE          ASSIGN TO "CPUREPORT.txt"
                                LINE SEQUENTIAL.
    SELECT SORT-FILE            ASSIGN TO DISK.
DATA DIVISION.
FILE SECTION.
FD  CPU-FILE.
01  CPU-REC                     PIC X(26).

FD  REPORT-FILE
    REPORT IS CPU-Report.

SD  SORT-FILE.
01  SORT-REC.
    05 F-SR-Score-NUM           PIC 9(5).
    05 F-SR-Vendor-TXT          PIC X(5).
    05 F-SR-Family-TXT          PIC X(7).
    05 F-SR-Model-TXT           PIC X(6).
WORKING-STORAGE SECTION.
01  WS-Date                     PIC 9(8).

01  WS-Family-Counters.
    05 WS-FC-AVE                PIC 9(5)V99.
    05 WS-FC-Qty                BINARY-LONG.
    05 WS-FC-Total-NUM          BINARY-LONG.

01  WS-Flags.
    05 WS-F-EOF                 PIC X(1).

01  WS-One-Const                PIC 9 VALUE 1.

01  WS-Overall-Counters.
    05 WS-OC-AVE                PIC 9(5)V99.
    05 WS-OC-Qty                BINARY-LONG.
    05 WS-OC-Total-NUM          BINARY-LONG.

01  WS-Starz                    PIC X(44) VALUE ALL '*'.

01  WS-Vendor-Counters.
    05 WS-VC-AVE                PIC 9(5)V99.
    05 WS-VC-Qty                BINARY-LONG.
    05 WS-VC-Total-NUM          BINARY-LONG.

REPORT SECTION.
RD  CPU-Report
    CONTROLS ARE FINAL
                 F-SR-Vendor-TXT
                 F-SR-Family-TXT

    PAGE LIMIT IS    36 LINES
        HEADING      1
        FIRST DETAIL 5
        LAST DETAIL  36.

01  TYPE IS PAGE HEADING.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE WS-Date                PIC 9999/99/99.
       10 COL 14 VALUE 'CPU Benchmark Scores'.
       10 COL 37 VALUE 'Page:'.
       10 COL 43 SOURCE PAGE-COUNTER           PIC Z9.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE WS-Starz               PIC X(44).
    05 LINE NUMBER PLUS 1.
       10 COL 1  VALUE '**'.
       10 COL 6  VALUE 'All CPU Data From cpubenchmark.net'.
       10 COL 43 VALUE '**'.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE WS-Starz               PIC X(44).

01  TYPE CONTROL HEADING F-SR-Family-TXT.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE F-SR-Vendor-TXT        PIC X(6).
       10 COL 8  SOURCE F-SR-Family-TXT        PIC X(7).
    05 LINE NUMBER PLUS 1.
       10 COL 1  VALUE 'Family'.
       10 COL 9  VALUE 'Model'.
       10 COL 16 VALUE 'Benchmark Score (High to Low)'.
    05 LINE NUMBER PLUS 1.
       10 COL 1  VALUE '======'.
       10 COL 9  VALUE '======'.
       10 COL 16 VALUE '============================='.

01  Detail-Line TYPE IS DETAIL.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE F-SR-Family-TXT PIC X(7) GROUP INDICATE.
       10 COL 9  PIC X(6)       SOURCE F-SR-Model-TXT.
       10 COL 16 PIC ZZZZ9      SOURCE F-SR-Score-NUM.

01  End-Family TYPE IS CONTROL FOOTING F-SR-Family-TXT.
    05 LINE NUMBER PLUS 1.
       10 COL 9                 VALUE  'Ave...'.
       10 COL 16 PIC ZZZZ9.99   SOURCE WS-FC-AVE.
       10 COL 25                VALUE  '('.
       10 COL 26 PIC ZZ9        SUM    WS-One-Const.
       10 COL 30                VALUE  'Family CPUs)'.

01  End-Vendor TYPE IS CONTROL FOOTING F-SR-Vendor-TXT.
    05 LINE NUMBER PLUS 1.
       10 COL 9                 VALUE  'Ave...'.
       10 COL 16 PIC ZZZZ9.99   SOURCE WS-VC-AVE.
       10 COL 25                VALUE  '('.
       10 COL 26 PIC ZZ9        SUM    WS-One-Const.
       10 COL 30                VALUE  'Vendor CPUs)'.

01  End-Overall TYPE IS CONTROL FOOTING FINAL.
    05 LINE NUMBER PLUS 1.
       10 COL 9                 VALUE  'Ave...'.
       10 COL 16 PIC ZZZZ9.99   SOURCE WS-OC-AVE.
       10 COL 25                VALUE  '('.
       10 COL 26 PIC ZZ9        SUM    WS-One-Const.
       10 COL 30                VALUE  'CPUs)'.

PROCEDURE DIVISION.
DECLARATIVES.
000-End-Family SECTION.
    USE BEFORE REPORTING End-Family.
1.  IF WS-FC-Qty > 0
        COMPUTE WS-FC-AVE = WS-FC-Total-NUM / WS-FC-Qty
    ELSE
        MOVE 0 TO WS-FC-AVE
    END-IF
    MOVE 0 TO WS-FC-Qty
              WS-FC-Total-NUM
    .
000-End-Vendor SECTION.
    USE BEFORE REPORTING End-Vendor.
1.  IF WS-VC-Qty > 0
        COMPUTE WS-VC-AVE = WS-VC-Total-NUM / WS-VC-Qty
    ELSE
        MOVE 0 TO WS-VC-AVE
    END-IF
    MOVE 0 TO WS-VC-Qty
              WS-VC-Total-NUM
    .
000-End-Overall SECTION.
    USE BEFORE REPORTING End-Overall.
1.  IF WS-OC-Qty > 0
        COMPUTE WS-OC-AVE = WS-OC-Total-NUM / WS-OC-Qty
    ELSE
        MOVE 0 TO WS-OC-AVE
    END-IF
    MOVE 0 TO WS-OC-Qty
              WS-OC-Total-NUM
    .
END DECLARATIVES.

010-Main SECTION.
1.  ACCEPT WS-Date FROM DATE YYYYMMDD
    SORT SORT-FILE
        ASCENDING KEY    F-SR-Vendor-TXT
                         F-SR-Family-TXT
        DESCENDING KEY   F-SR-Score-NUM
        ASCENDING KEY    F-SR-Model-TXT
        INPUT PROCEDURE  100-Pre-Process-Data
        OUTPUT PROCEDURE 200-Generate-Report
    STOP RUN
    .
100-Pre-Process-Data SECTION.
1.  OPEN INPUT CPU-FILE
    PERFORM FOREVER
        READ CPU-FILE
        AT END
            EXIT PERFORM
        END-READ
        MOVE SPACES TO SORT-REC
        UNSTRING CPU-REC DELIMITED BY ','
            INTO F-SR-Score-NUM,
                 F-SR-Vendor-TXT,
                 F-SR-Family-TXT,
                 F-SR-Model-TXT
        RELEASE SORT-REC
    END-PERFORM
    CLOSE CPU-FILE
    .
200-Generate-Report SECTION.
1.  INITIALIZE WS-Family-Counters
               WS-Flags
    OPEN OUTPUT REPORT-FILE
    INITIATE CPU-Report
    RETURN SORT-FILE
    AT END
        MOVE 'Y' TO WS-F-EOF
    END-RETURN
    PERFORM UNTIL WS-F-EOF = 'Y'
        GENERATE Detail-Line
        ADD 1              TO WS-FC-Qty
                              WS-OC-Qty
                              WS-VC-Qty
        ADD F-SR-Score-NUM TO WS-FC-Total-NUM
                              WS-OC-Total-NUM
                              WS-VC-Total-NUM
        RETURN SORT-FILE
        AT END
            MOVE 'Y' TO WS-F-EOF
        END-RETURN
    END-PERFORM
    TERMINATE CPU-Report
    CLOSE REPORT-FILE
    .

9.6.3. Сгенерированные страницы отчета

И наконец, вот отчет, который генерирует программа!

2013/12/24   CPU Benchmark Scores   Page:  1
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
AMD    A10
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A10     6800K   5062
        5800B   4798
        6700    4767
        5800K   4677
        5700    4251
        4657M   3449
        5750M   3332
        5757M   3253
        4600M   3145
        5745M   2758
        4655M   2505
        Ave...  3817.90 ( 11 Family CPUs)
AMD    A4
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A4      6300    2305
        5300    2078
        5150M   1973
        5000    1919
        3420    1768
        4300M   1685
        5300B   1632
        3400    1625
        3300    1583
        3330MX  1343
        3310MX  1263
        3300M   1237
        3305M   1227
        3320M   1193
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  2
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
A4      4355M   1169
        1200     677
        1250     559
        Ave...  1484.47 ( 17 Family CPUs)
AMD    A6
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A6      3670    3327
        3650    3232
        3620    2892
        3600    2798
        5200    2440
        6400K   2384
        3430MX  2277
        5400K   2174
        3410MX  2101
        3420M   2078
        3500    1995
        3400M   1964
        5350M   1958
        5400B   1906
        5357M   1878
        1450    1634
        4400M   1630
        4455M   1296
        Ave...  2220.22 ( 18 Family CPUs)
AMD    A8
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A8      6600K   4719
        6500    4390
        5600K   4348
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  3
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
A8      5500    4052
        3870K   3682
        3850    3552
        5500B   3464
        3820    3217
        3800    3215
        5550M   3052
        5557M   2935
        3550MX  2866
        4500M   2709
        5545M   2434
        3510MX  2426
        3530MX  2276
        3520M   2245
        4555M   2193
        3500M   2050
        Ave...  3148.68 ( 19 Family CPUs)
AMD    FX
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
FX      9590   10479
        9370    9807
        8350    9067
        8320    8131
        8150    7719
        6350    7017
        8140    6845
        8120    6605
        6300    6388
        6200    6194
        8100    6163
        6120    5813
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  4
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
FX      6100    5421
        4350    5247
        4170    4774
        4300    4711
        4130    4153
        4150    4094
        4100    4055
        Ave...  6457.00 ( 19 Family CPUs)
        Ave...  3448.86 ( 84 Vendor CPUs)
Intel  Core i3
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
Core i3 4340    5117
        4330    5115
        4130    4904
        3250    4757
        3245    4414
        3225    4407
        3240    4259
        3220    4219
        4130T   4041
        3210    3820
        3240T   3793
        3220T   3724
        3130M   3655
        4000M   3443
        3120M   3301
        3110M   3076
        3227U   2575
        4010U   2459
        3217U   2266
        4010Y   2003
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  5
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
Core i3 3229Y   1885
        Ave...  3677.76 ( 21 Family CPUs)
Intel  Core i5
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
Core i5 4670K   7565
        4670    7492
        3570K   7118
        4570    7061
        3570    6993
        3550    6828
        4570S   6803
        3570S   6709
        3550S   6631
        3470    6576
        4440    6517
        4570R   6474
        3450    6442
        4670T   6351
        3340    6282
        4430    6282
        3350P   6199
        3470S   6077
        3450S   6071
        3475S   5991
        4430S   5954
        3330    5902
        3335S   5781
        3330S   5690
        3570T   5414
        3340S   5372
        4330M   4804
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  6
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
Core i5 4300M   4786
        4288U   4663
        3470T   4591
        3380M   4555
        4258U   4381
        4200M   4333
        3340M   4327
        3360M   4314
        3320M   4101
        3230M   3995
        4300U   3917
        3210M   3807
        4350U   3604
        3427U   3589
        4250U   3482
        3437U   3479
        4200U   3355
        3337U   3280
        3317U   3126
        3439Y   3057
        4570T   2503
        4210Y   2382
        4200Y   2358
        3339Y   2252
        4300Y   1743
        Ave...  5026.13 ( 52 Family CPUs)
Intel  Core i7
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
Core i7 4960X  14291
        4930K  13620
        3970X  12823
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  7
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
Core i7 3960X  12718
        3930K  12107
        4960HQ 10262
        4770K  10190
        4771   10078
        4770    9969
        4820K   9969
        4770S   9803
        4930MX  9754
        3770K   9578
        3770    9420
        4850HQ  9331
        4900MQ  9323
        3920XM  9196
        3770S   9074
        3940XM  9052
        3840QM  9025
        3820    8995
        4770T   8803
        4800MQ  8567
        3820QM  8548
        3740QM  8512
        3720QM  8347
        3770T   8280
        4700HQ  8161
        4750HQ  8066
        4702HQ  8002
        4700MQ  7946
        3630QM  7759
        4702MQ  7647
        3610QM  7532
        4765T   7367
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  8
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
Core i7 4700EQ  7352
        3615QM  7310
        3632QM  7055
        3612QE  6988
        3612QM  6907
        3635QM  6516
        3610QE  6144
        3615QE  5495
        4600M   4892
        3540M   4861
        3520M   4588
        4558U   4507
        4600U   4484
        4650U   4345
        3687U   4271
        3667U   4032
        3555LE  4009
        4500U   3992
        3537U   3912
        3517U   3701
        4610Y   3680
        3689Y   3479
        3517UE  3449
        Ave...  7725.58 ( 58 Family CPUs)
        Ave...  6005.16 (131 Vendor CPUs)
        Ave...  5006.42 (215 CPUs)





____________________________________________

9.7. Иерархия управления (повторно)

Примерная программа, о которой только что говорилось, предоставляет прекрасную возможность показать, что может произойти, если вы неправильно определите иерархию управления отчетом.

Я изменил CONTROLS ARE предложение в образце программы с этого:

CONTROLS ARE FINAL
             F-SR-Vendor-TXT
             F-SR-Family-TXT

На это:

CONTROLS ARE FINAL
             F-SR-Family-TXT
             F-SR-Vendor-TXT

И затем снова запустил отчет. Вот первые две страницы этого нового отчета. Что произошло с разрывами управления?

2013/12/24   CPU Benchmark Scores   Page:  1
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
AMD    A10
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A10     6800K   5062
        5800B   4798
        6700    4767
        5800K   4677
        5700    4251
        4657M   3449
        5750M   3332
        5757M   3253
        4600M   3145
        5745M   2758
        4655M   2505
        Ave...  3817.90 ( 11 Vendor CPUs)
        Ave...  3817.90 ( 11 Family CPUs)
AMD    A4
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A4      6300    2305
        5300    2078
        5150M   1973
        5000    1919
        3420    1768
        4300M   1685
        5300B   1632
        3400    1625
        3300    1583
        3330MX  1343
        3310MX  1263
        3300M   1237
        3305M   1227
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  2
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
A4      3320M   1193
        4355M   1169
        1200     677
        1250     559
        Ave...  1484.47 ( 17 Vendor CPUs)
        Ave...  1484.47 ( 17 Family CPUs)
AMD    A6
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A6      3670    3327
        3650    3232
        3620    2892
        3600    2798
        5200    2440
        6400K   2384
        3430MX  2277
        5400K   2174
        3410MX  2101
        3420M   2078
        3500    1995
        3400M   1964
        5350M   1958
        5400B   1906
        5357M   1878
        1450    1634
        4400M   1630
        4455M   1296
        Ave...  2220.22 ( 18 Vendor CPUs)
        Ave...  2220.22 ( 18 Family CPUs)
AMD    A8
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A8      6600K   4719

____________________________________________

9.8. Преобразование физического форматирования страниц в логическое форматирование

Вы можете довольно легко обмануть RWCS, чтобы она использовала значения PAGE LIMIT в качестве логических спецификаций, а не физических — просто включите символ подачи страницы ASCII (X'0C') в дизайн заголовка страницы! Вот как можно легко изменить примерную программу, показанную ранее:

Просто измените это…

01  TYPE IS PAGE HEADING.
    05 LINE NUMBER 1.
       10 COL 1  SOURCE WS-Date PIC 9999/99/99.
       10 COL 14 VALUE 'CPU Benchmark Scores'.
       10 COL 37 VALUE 'Page:'.
       10 COL 43 SOURCE PAGE-COUNTER PIC Z9.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE WS-Starz PIC X(44).
    05 LINE NUMBER PLUS 1.
       10 COL 1  VALUE '**'.
       10 COL 6  VALUE 'All CPU Data From ' &
                       'cpubenchmark.net'.
       10 COL 43 VALUE '**'.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE WS-Starz PIC X(44).

На это…

01  TYPE IS PAGE HEADING.
    05 LINE NUMBER 1.                          *> NEW
       10 COL 1  VALUE X’0C’.                  *> NEW
    05 LINE NUMBER PLUS 1.                 *> CHANGED
       10 COL 1  SOURCE WS-Date PIC 9999/99/99.
       10 COL 14 VALUE 'CPU Benchmark Scores'.
       10 COL 37 VALUE 'Page:'.
       10 COL 43 SOURCE PAGE-COUNTER PIC Z9.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE WS-Starz PIC X(44).
    05 LINE NUMBER PLUS 1.
       10 COL 1  VALUE '**'.
       10 COL 6  VALUE 'All CPU Data From ' &
                       'cpubenchmark.net'.
       10 COL 43 VALUE '**'.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE WS-Starz PIC X(44).

RWCS по-прежнему будет считать строки, чтобы определить, когда необходимо закрыть одну страницу и начать новую, но когда начнется новая страница, ее заголовок будет физически подавать страницу принтеру при печати отчета. До тех пор, пока любой принтер, который вы планируете использовать, поддерживает как минимум столько же физических линий печати, сколько определено как значение PAGE LIMIT в любой ориентации бумаги и шрифте, которые вы планируете (или к которым ограничены) печатью, вы теперь отделили свою программу от физических реалий принтера!

Конечно, любое программное обеспечение, которое вы используете для доставки печатного документа на принтер, должно позволять символу подачи страницы ASCII проходить на принтер.

10. Взаимодействие с ОС

10.1. Компиляция программ

Исходные файлы программ должны иметь расширения .cob или .cbl.

Имена файлов программ должны точно соответствовать спецификации PROGRAM-ID (включая регистр).

Пробелы не могут быть включены в имена основных точек входа и поэтому не должны включаться в имена файлов программ.

Компилятор GnuCOBOL преобразует вашу программу COBOL в исходный код C, скомпилирует этот исходный код C в исполняемый двоичный формат с помощью указанного при создании GnuCOBOL компилятора языка C и свяжет этот исполняемый двоичный файл в:

Непосредственно исполняемая форма

Это исполняемый файл, который можно непосредственно выполнить из командной строки. На компьютерах с Windows это был бы файл .exe. В системах Unix это будет файл без конкретного расширения, но с правами выполнения. Этот файл будет включать главную программу, а также любые статически связанные подпрограммы.

Форма для статической компоновки

Это одна подпрограмма, скомпилированная в объектный код, готовая для компоновки с основной программой для создания непосредственно исполняемой программы. На компьютерах с Windows эти файлы обычно имеют расширение .o (объектный код).

Форма динамически загружаемого исполняемого файла

Это файлы объектного кода, которые можно динамически загружать и вызывать из других программ во время выполнения. В системах Windows это были бы файлы .dll, а в системах Unix — обычно файлы .so (OSX использует .dylib).

10.1.1. cobc — Компилятор GnuCOBOL

Компилятор GnuCOBOL называется cobc (cobc.exe в системе Windows).

Следующее описывает синтаксис и переключатели параметров команды cobc. Эту информацию можно отобразить, введя команду cobc --help или cobc -h.

GnuCOBOL compiler for most COBOL dialects with lots of extensions as of v3.1.

Usage: cobc [options]... file...

Options:
  -h, -help              display this help and exit
  -V, -version           display compiler version and exit
  -i, -info              display compiler information (build/environment)
                         and exit
  -v, -verbose           display compiler version and the commands
                         invoked by the compiler
  -vv, -verbose=2        like -v but additional pass verbose option
                         to assembler/compiler
  -vvv, -verbose=3       like -vv but additional pass verbose option
                         to linker
  -q, -brief             reduced displays, commands invoked not shown
  -###                   like -v but commands not executed
  -x                     build an executable program
  -m                     build a dynamically loadable module (default)
  -j [<args>], -job[=<args>]	run program after build, passing <args>
  -std=<dialect>         warnings/features for a specific dialect
                         <dialect> can be one of:
                         default, cobol2014, cobol2002, cobol85, xopen,
                         ibm-strict, ibm, mvs-strict, mvs,
                         mf-strict, mf, bs2000-strict, bs2000,
                         acu-strict, acu, rm-strict, rm;
                         see configuration files in directory config
  -F, -free              use free source format
  -fixed                 use fixed source format (default)
  -O, -O2, -O3, -Os      enable optimization
  -O0                    disable optimization
  -g                     enable C compiler debug / stack check / trace
  -d, -debug             enable all run-time error checking
  -o <file>              place the output into <file>
  -b                     combine all input files into a single
                         dynamically loadable module
  -E                     preprocess only; do not compile or link
  -C                     translation only; convert COBOL to C
  -S                     compile only; output assembly file
  -c                     compile and assemble, but do not link
  -T <file>              generate and place a wide program listing into <file>
  -t <file>              generate and place a program listing into <file>
  --tlines=<lines>       specify lines per page in listing, default = 55
  -P[=<dir or file>]     generate preprocessed program listing (.lst)
  -Xref                  generate cross reference through 'cobxref'
                         (V. Coen's 'cobxref' must be in path)
                         {This uses the internal tool only. See 10.1.1.1 for example output.
                         To use Cobxref you must run this separately. See second example as 10.1.1.2}

  -I <directory>         add <directory> to copy/include search path
  -L <directory>         add <directory> to library search path
  -l <lib>               link the library <lib>
  -A <options>           add <options> to the C compile phase
  -Q <options>           add <options> to the C link phase
  -D <define>            define <define> for COBOL compilation
  -K <entry>             generate CALL to <entry> as static
  -conf=<file>           user-defined dialect configuration; see -std
  -list-reserved         display reserved words
  -list-intrinsics       display intrinsic functions
  -list-mnemonics        display mnemonic names
  -list-system           display system routines
  -save-temps[=<dir>]    save intermediate files
                         * default: current directory
  -ext <extension>       add file extension for resolving COPY

Warning options:
  -W                     enable all warnings
  -Wall                  enable most warnings (all except as noted below)
  -Warchaic              warn if archaic features are used
  -Warithmetic-osvs      warn if arithmetic expression precision has changed
  -Wcall-params          warn about non 01/77 items for CALL parameters
                         * NOT set with -Wall
  -Wcolumn-overflow      warn about text after program-text area, FIXED format
                         * NOT set with -Wall
  -Wconstant-expression  warn about expressions that always resolve to true/false
  -Wcorresponding        warn about CORRESPONDING with no matching items
  -Werror                treat all warnings as errors
  -Werror=<warning>      treat specified <warning> as error
  -Wimplicit-define      warn about implicitly defined data items
  -Winitial-value        warn if initial VALUE clause is ignored
  -Wlinkage              warn about dangling LINKAGE items
                         * NOT set with -Wall
  -Wno-<warning>         disable warning enabled by -W or -Wall
  -Wno-dialect           do not warn about dialect specific issues
                         * ALWAYS active
  -Wno-pending           do not warn if pending features are mentioned
                         * ALWAYS active
  -Wno-unfinished        do not warn if unfinished features are used
                         * ALWAYS active
  -Wobsolete             warn if obsolete features are used
  -Wothers               do not warn about different issues
                         * ALWAYS active
  -Woverlap              warn about overlapping MOVE of items
  -Wparentheses          warn about lack of parentheses around AND within OR
  -Wpossible-overlap     warn about MOVE of items that may overlap depending on variables
                         * NOT set with -Wall
  -Wpossible-truncate    warn about possible field truncation
                         * NOT set with -Wall
  -Wprototypes           warn about missing FUNCTION prototypes/definitions
  -Wredefinition         warn about incompatible redefinition of data items
  -Wstrict-typing        warn strictly about type mismatch
  -Wterminator           warn about lack of scope terminator END-XXX
                         * NOT set with -Wall
  -Wtruncate             warn about field truncation from constant assignments
  -Wunreachable          warn about likely unreachable statements
                         * NOT set with -Wall

Compiler options:
  -facucomment           '$' in indicator area treated as '*',
                         '|' treated as floating comment
  -fcallfh=<function>    use external provided EXTFH interface module
                         <function> for I/O
  -fdebugging-line       enable debugging lines
                         * 'D' in indicator column or floating >>D
  -fdefaultbyte=<value>	 initialize fields without VALUE to value
                         * decimal 0..255 or any quoted character
                         * default: initialize to picture
  -fdump=<scope>         dump data fields on abort, <scope> may be
                         a combination of: ALL, WS, LS, RD, FD, SC
  -ffold-call=[UPPER|LOW ER]	fold PROGRAM-ID, CALL, CANCEL subject to value
                         * default: no transformation
  -ffold-copy=[UPPER|LOW ER]	fold COPY subject to value
                         * default: no transformation
  -fibmcomp              sets -fbinary-size=2-4-8 -fsynchronized-clause=ok
  -fimplicit-init        automatic initialization of the COBOL runtime system
  -finline-intrinsic	whe n possible resolve intrinsic FUNCTIONs at compile time
  -fintrinsics=[ALL|intr insic function name(,name,...)]
                         intrinsics to be used without FUNCTION keyword
  -fmax-errors=<number>	 maximum number of errors to report before
                         compilation is aborted
                         * default: 100
  -fmf-files             Sequential & Relative files will match Micro Focus format
  -fmfcomment            '*' or '/' in column 1 treated as comment
                         * FIXED format only
  -fno-gen-c-decl-static -call	disable generation of C function declarations
                         for subroutines with static CALL
  -fno-ibmcomp           sets -fbinary-size=1--8  -fsynchronized-clause=ignore
  -fno-recursive-check   disable check of recursive program call;
                         effectively compiling as RECURSIVE program
  -fno-remove-unreachabl e	disable remove of unreachable code
                         * turned off by -g
  -fno-theaders          suppress all headers and output of compilation
                         options from listing while keeping page breaks
  -fno-tmessages         suppress warning and error summary from listing
  -fno-tsource           suppress source from listing
  -fnotrunc              allow numeric field overflow
                         * non-ANSI behaviour
  -fodoslide             adjust items following OCCURS DEPENDING
                         * implies -fcomplex-odo
  -foptional-file        treat all files as OPTIONAL
                         * unless NOT OPTIONAL specified
  -fsign=[ASCII|EBCDIC]	 define display sign representation
                         * default: machine native
  -fsingle-quote         use a single quote (apostrophe) for QUOTE
                         * default: double quote
  -fsource-location      generate source location code
                         * turned on by -debug/-g/-ftraceall
  -fstack-check          PERFORM stack checking
                         * turned on by -debug or -g
  -fstatic-call          output static function calls for the CALL statement
  -fsyntax-only          syntax error checking only; don't emit any output
  -ftrace                generate trace code
                         * scope: executed SECTION/PARAGRAPH
  -ftraceall             generate trace code
                         * scope: executed SECTION/PARAGRAPH/STATEMENTS
                         * turned on by -debug
  -ftsymbols             specify symbols in listing
  -fwrite-after          use AFTER 1 for WRITE of LINE SEQUENTIAL
                         * default: BEFORE 1

Compiler dialect configuration options:
  -faccept-auto           Set WITH AUTO clause as default for ACCEPT dest-item,
                          instead of WITH TAB
  -faccept-display-extensions=<support>
                          Extensions to ACCEPT and DISPLAY
  -faccept-update         Set WITH UPDATE clause as default for ACCEPT dest-item,
                          instead of WITH NO UPDATE
  -facu-literals=<support>
                          ACUCOBOL-GT literals (#B #O #H #X)
  -falter-statement=<support>
                          ALTER statement
  -farithmetic-osvs       Limit precision in intermediate results to precision
                          of final result (less accurate)
  -fassign-clause=<value>
                          Set way of interpreting ASSIGN
  -fbinary-byteorder=<value>
                          Binary byte order, may be one of: native, big-endian
  -fbinary-comp-1         COMP-1 is a 16-bit signed integer
  -fbinary-size=<value>   Binary byte size - defines the allocated bytes according
                          to PIC, may be one of: 2-4-8, 1-2-4-8, 1--8
  -fbinary-sync-clause=<support>
                          BINARY-SHORT/LONG/DOUBLE SYNCHRONIZED clause
  -fbinary-truncate       Numeric truncation according to ANSI
  -fcall-convention-linkage=<support>
                          Specifying call-convention by WITH ... LINKAGE
  -fcall-convention-mnemonic=<support>
                          Specifying call-convention by mnemonic
  -fcall-overflow=<support>
                          OVERFLOW clause for CALL
  -fcomment-paragraphs=<support>
                          Comment paragraphs in IDENTIFICATION DIVISION (AUTHOR,
                          DATE-WRITTEN, ...)
  -fcomplex-odo           Allow complex OCCURS DEPENDING ON
  -fconsole-is-crt        Assume CONSOLE IS CRT if not set otherwise
  -fconstant-01=<support>
                          Constant with level 01 CONSTANT AS/FROM item
  -fconstant-78=<support>
                          Constant with level 78 item (note: has left to right
                          precedence in expressions)
  -fconstant-folding      Evaluate constant expressions at compile time
  -fcontinue-after=<support>
                          AFTER phrase in CONTINUE statement
  -fdata-records-clause=<support>
                          DATA-RECORDS clause
  -fdebugging-mode=<support>
                          DEBUGGING MODE and debugging indicator
  -fdefine-constant-directive=<support>
                          Allow >> DEFINE CONSTANT var AS literal
  -fdepending-on-not-fixed=<support>
                          Depending-on-not-fixed
  -fdisplay-special-fig-consts
                          Special behaviour of
                          DISPLAY SPACE/ALL X'01'/ALL X'02'/ALL X'07'
  -fentry-statement=<support>
                          ENTRY statement
  -ffilename-mapping      Resolve file names at run time using environment variables.
  -ffree-redefines-position=<support>
                          REDEFINES clause not following entry-name in definition
  -fgoto-entry=<support>
                          ENTRY FOR GOTO and GOTO ENTRY statements
  -fgoto-statement-without-name=<support>
                          GOTO statement without name
  -fhexadecimal-boolean=<support>
                          Hexadecimal-boolean literals (BX'A')
  -fhexadecimal-national-literals=<support>
                          Hexadecimal-national literals (NX'265E')
  -fhostsign              Allow hexadecimal value 'F' for NUMERIC test of signed
                          PACKED DECIMAL field
  -fhp-octal-literals=<support>
                          HP COBOL octal literals (%377)
  -fincorrect-conf-sec-order=<support>
                          Incorrect order of CONFIGURATION SECTION paragraphs
  -findirect-redefines    Allow REDEFINES to other than last equal level number
  -flabel-records-clause=<support>
                          LABEL-RECORDS clause
  -flarger-redefines-ok
                          Allow larger REDEFINES items
  -flength-in-data-division
                          Length in data division
  -fline-col-zero-default
                          Assume the first item in a field DISPLAY goes at
                          LINE 0 COL 0, not LINE 1 COL 1
  -flisting-statements=<support>
                          Listing-directive statements EJECT, SKIP1, SKIP2, SKIP3
  -fliteral-length=<number>
                          Maximum literal size in general
  -fmemory-size-clause=<support>
                          MEMORY-SIZE clause
  -fmissing-statement=<support>
                          Missing statement (e.g. empty IF / PERFORM)
  -fmove-figurative-constant-to-numeric=<support>
                          Move figurative constants to numeric
  -fmove-figurative-quote-to-numeric=<support>
                          Move figurative constant QUOTE to numeric
  -fmove-figurative-space-to-numeric=<support>
                          Move figurative constant SPACE to numeric
  -fmove-ibm              MOVE operates as on IBM (left to right, byte by byte),
                          otherwise no propagating move
  -fmove-non-numeric-lit-to-numeric-is-zero
                          Imply zero in move of non-numeric literal to numeric items
  -fmove-noninteger-to-alphanumeric=<support>
                          Move noninteger to alphanumeric
  -fmultiple-file-tape-clause=<support>
                          MULTIPLE-FILE-TAPE clause
  -fnational-character-literals=<support>
                          Non-standard national literals (NC'UTF-16 string')
  -fnational-literals=<support>
                          National literals (N'UTF-16 string')
  -fnext-sentence-phrase=<support>
                          NEXT SENTENCE phrase
  -fno-echo-means-secure
                          NO-ECHO
                          Hides input with asterisks like SECURE
  -fnonnumeric-with-numeric-group-usage=<support>
                          Non-Numeric item with Numeric Group USAGE clause
  -fnot-exception-before-exception=<support>
                          NOT ON EXCEPTION before ON EXCEPTION
  -fnumeric-boolean=<support>
                          Boolean literals (B'1010')
  -fnumeric-literal-length=1..38
                          Maximum numeric literal size
  -fnumeric-value-for-edited-item=<support>
                          Numeric literals in VALUE clause of numeric-edited items
  -foccurs-max-length-without-subscript
                          Occurs max length without subscript
  -fodo-without-to=<support>
                          OCCURS DEPENDING ON without to
  -fpadding-character-clause=<support>
                          PADDING CHARACTER clause
  -fperform-osvs          exit point of any currently executing perform is recognized
                          if reached
  -fperform-varying-without-by=<support>
                          PERFORM VARYING without BY phrase (implies BY 1)
  -fpic-length=<number>   Maximum number of characters allowed in the PICTURE
                          character-string
  -fpretty-display        Alternate formatting of numeric fields
  -fprogram-name-redefinition
                          Program names don't lead to a reserved identifier
  -fprogram-prototypes=<support>
                          CALL/CANCEL with program-prototype-name
  -frecord-delim-with-fixed-recs=<support>
                          RECORD DELIMITER clause on file with fixed-length records
  -frecord-delimiter=<support>
                          RECORD DELIMITER clause
  -frecords-mismatch-record-clause=<support>
                          Record sizes does not match RECORD clause
  -freference-out-of-declaratives=<support>
                          References to sections not in DECLARATIVES from within
                          DECLARATIVES
  -frelax-level-hierarchy
                          Allow non-matching level numbers
  -frelax-syntax-checks   Allow certain syntax variations (e.g. REDEFINES position)
  -frenames-uncommon-levels=<support>
                          RENAMES of 01-, 66- and 77-level items
  -freserved-words=<value>
                          Use of complete/fixed reserved words
  -fscreen-section-rules=<value>
                          Which compiler's rules to apply to SCREEN SECTION
                          item clauses
  -fsection-segments=<support>
                          Section segments
  -fselect-working        Require ASSIGN USING items to be in WORKING-STORAGE
  -fsequential-delimiters=<support>
                          BINARY-SEQUENTIAL and LINE-SEQUENTIAL phrases in
                          RECORD DELIMITER
  -fsticky-linkage        LINKAGE-SECTION items remain allocated between invocations
  -fstop-identifier-statement=<support>
                          STOP-identifier statement
  -fstop-literal-statement=<support>
                          STOP-literal statement
  -fsymbolic-constant=<support>
                          Constants defined in SPECIAL-NAMES
  -fsynchronized-clause=<support>
                          SYNCHRONIZED clause
  -ftab-width=1..12       Set number of spaces that are assumed for tabs
  -ftext-column=72..255   Set right margin for source (fixed format only)
  -ftitle-statement=<support>
                          Listing-directive statement TITLE
  -ftop-level-occurs-clause=<support>
                          OCCURS clause on top-level
  -fuse-for-debugging=<support>
                          USE FOR DEBUGGING
  -fvalue-of-clause=<support>
                          VALUE-OF clause
  -fword-continuation=<support>
                          Continuation of COBOL words
  -fword-length=1..63     Maximum word-length for COBOL (= programmer defined) words
  -fxml-generate-extra-phrases=<support>
                          XML GENERATE's phrases other than COUNT IN
  -fzero-length-literals=<support>
                          Zero-length literals, e.g. '@w{}' and ""
     where <support> is one of the following:
     	'ok', 'warning', 'archaic', 'obsolete', 'skip', 'ignore', 'error',
      'unconformable'

  -fnot-reserved=<word>   Word to be taken out of the reserved words list
  -freserved=<word>       Word to be added to reserved words list
  -freserved=<word>:<alias>
                          Word to be added to reserved words list as alias
  -fnot-register=<word>   Special register to disable
  -fregister=<word>       Special register to enable

Каждый файл, указанный в команде cobc, представляет собой единицу компиляции. Единицей компиляции может быть одна программа GnuCOBOL — с вложенными подпрограммами (см. Независимые против содержащихся против вложенных подпрограмм) — или несколько программ GnuCOBOL, разделенных соответствующими маркерными строками END PROGRAM или END FUNCTION. См. Независимые против содержащихся против вложенных подпрограмм для некоторых примеров таких маркерных строк.

Единицей компиляции также может быть программа на языке C, распознаваемая по расширению файла .c или программа на языке ассемблера, распознаваемая по расширению файла .s. В таком случае компиляция COBOL этого файла будет пропущена командой cobc; вместо этого файл будет передан непосредственно компилятору C или ассемблеру (выполняется автоматически командой cobc).

Единица компиляции может также быть модулем объектного кода (выходной файл компилятора C), распознаваемый по расширению файла .o. В этих случаях вся компиляция будет пропущена, а объектный код будет «связан» в генерируемый исполняемый файл компоновщиком (команда ld выполняется внутри команды cobc).

Предварительно скомпилированные подпрограммы объектного кода могут автоматически находиться компилятором GnuCOBOL и загрузчиком с помощью переменной среды LD_LIBRARY_PATH времени компиляции (см. Переменные среды времени компиляции). Если их можно найти через эту переменную среды, их не нужно указывать в команде cobc.

Набор единиц компиляции, предоставленных при одном выполнении cobc, составляют Группу компиляции. Весь исполняемый код, созданный из одной группы компиляции, будет собран вместе в один исполняемый файл, имя которого будет таким же, как имя первой единицы компиляции, указанной в команде cobc.

Самый простой режим компиляции — это генерация одного исполняемого файла из одного или нескольких исходных файлов GnuCOBOL:

cobc -x mainprog.cbl sub1.cbl sub2.cbl

Главная программа должна быть первой программой, найденной в первой единице компиляции (mainprog.cbl). Остальная часть этой единицы компиляции, а также остальные файлы в группе компиляции (sub1.cbl и sub2.cbl) должны быть независимыми и/или содержащими подпрограммами (см. Независимые против содержащих против вложенных подпрограмм).

Эта команда предполагает, что все исходные файлы находятся в каталоге, из которого была выполнена команда cobc. Вы, конечно, можете включить полные пути с любым именем файла, если это необходимо.

С переключателем -x в команде компилятора будет сгенерирован один непосредственно исполняемый исполняемый файл (UNIX, Windows/Cygwin, OSX) или файл «exe» (Windows, Windows/MinGW). Этот исполняемый файл содержит скомпилированный код для всех программ COBOL, содержащихся в группе компиляции, указанной в команде cobc в файле.

Любые подпрограммы или определенные пользователем функции, которые не были включены ни в один из исходных файлов, составляющих группу компиляции, будут обрабатываться как динамически загружаемые подпрограммы (см. Динамические против статических подпрограмм).

По желанию, переключатель -o может быть использован в дополнение к -x для указания имени генерируемого исполняемого файла. Если переключатель -o не указан, имя файла первой единицы компиляции будет использоваться как имя исполняемого файла. Соответствующее расширение для генерируемого файла (.exe, например, на компьютере с Windows) будет добавлено к имени файла, которое явно указано или подразумевается для выходного файла.

Компиляции могут выполняться для генерации динамически загружаемых модулей (или динамически загружаемых библиотек, как их часто называют). Эти компиляции выполняются с использованием переключателя -m вместо переключателя -x:

cobc -m mainprog.cbl sub1.cbl sub2.cbl

Когда используется переключатель -m, генерируется динамически загружаемый модуль, специфичный для операционной системы, для каждой отдельной единицы компиляции, используя имя файла каждой единицы компиляции как имя файла модуля и расширение .so (UNIX, Windows/Cygwin), .dylib (OSX) или .dll (Windows, Windows/MinGW).

Вы можете скомпилировать подпрограммы GnuCOBOL в исходный код ассемблера, который затем может быть собран и связан с главной программой, когда эта главная программа компилируется. Чтобы создать такой файл исходного кода ассемблера, скомпилируйте подпрограмму(ы) следующим образом:

cobc -S sprog1.cbl

Вышеупомянутое генерирует файл исходного кода ассемблера с именем sprog1.s. Если у вас несколько подпрограмм для компиляции таким образом, просто укажите их имена файлов в команде. Каждый из них будет переведён в свой собственный файл исходного кода ассемблера.

Позже, когда вы захотите скомпилировать программу вызова и объединить необходимые подпрограммы языка ассемблера в (как статические подпрограммы — см. Динамические против статических подпрограмм), используйте команду, такую как эта:

cobc -x mainprog.cbl sprog1.s

10.1.1.1. Пример использования опции cobc -Xref

Ниже показан вывод при использовании -Xref.

   Using the internal -Xref as extra options -X -t prog.list:

   GnuCOBOL 3.1-dev.0      prog.cbl             Fri Dec  6 14:17:52 2019  Page 0001

LINE    PG/LN  A...B............................................................

000001  000001 IDENTIFICATION   DIVISION.
000002  000002 PROGRAM-ID.      prog.
000003  000003 ENVIRONMENT DIVISION.
000004  000004 CONFIGURATION SECTION.
000005  000005 DATA             DIVISION.
000006  000006 WORKING-STORAGE  SECTION.
000007  000007 COPY 'values.cpy'.
000001C 000001 78  I   VALUE 20.
000002C 000002 78  J   VALUE 5000.
000003C 000003 78  M   VALUE 5.
000008  000008 01  SETUP-REC.
000009  000009     05  FL1       PIC X(04).
000010  000010     05  FL2       PIC ZZZZZ.
000011  000011     05  FL3       PIC 9(04).
000012  000012     05  FL4       PIC 9(08) COMP.
000013  000013     05  FL5       PIC 9(04) COMP-4.
000014  000014     05  FL6       PIC Z,ZZZ.99.
000015  000015     05  FL7       PIC S9(05) SIGN LEADING SEPARATE.
000016  000016     05  FL8       PIC X(04).
000017  000017     05  FL9 REDEFINES FL8 PIC 9(04).
000018  000018     05  FLA.
000019  000019         10  FLB OCCURS I TIMES.
000020  000020             15  FLC PIC X(02).
000021  000021         10  FLD   PIC X(20).
000022  000022     05  FLD1      PIC X(100).
000023  000025     05  FLD3      PIC X(3).
000024  000026     05  FLD4      PIC X(4).
000025  000023     05  FLD2 OCCURS M TO J TIMES DEPENDING ON FL5.
000026  000024         10  FILLER PIC X(01).
000027  000027 PROCEDURE        DIVISION.
000028  000028     STOP RUN.

GnuCOBOL 3.1-dev.0      prog.cbl             Fri Dec  6 14:17:52 2019  Page 0002

NAME                           DEFINED                REFERENCES

SETUP-REC                      8      referenced by child
FL1                            9      not referenced
FL2                            10     not referenced
FL3                            11     not referenced
FL4                            12     not referenced
FL5                            13       25
FL6                            14     not referenced
FL7                            15     not referenced
FL8                            16     not referenced
FL9                            17     not referenced
FLA                            18     not referenced
FLB                            19     not referenced
FLC                            20     not referenced
FLD                            21     not referenced
FLD1                           22     not referenced
FLD3                           23     not referenced
FLD4                           24     not referenced
FLD2                           25     not referenced

GnuCOBOL 3.1-dev.0      prog.cbl             Fri Dec  6 14:17:52 2019  Page 0003

LABEL                          DEFINED                REFERENCES

E prog                         27

0 warnings in compilation group
0 errors in compilation group

10.1.1.2. Список перекрестных ссылок с использованием cobxref

Эта программа находится в области contrib или сама по себе в Sourceforge под своим собственным именем (cobxref).

Ниже показан вывод при использовании cobxref с тем же примером программы.

Using cobxref with command cobxref prog.cbl :

ACS Cobol Xref v2.02.02          Dictionary File for PROG    06/12/2019  14:19:09:39                                   Page    1

     1  000001 IDENTIFICATION   DIVISION.
     2  000002 PROGRAM-ID.      prog.
     3  000003 ENVIRONMENT DIVISION.
     4  000004 CONFIGURATION SECTION.
     5  000005 DATA             DIVISION.
     6  000006 WORKING-STORAGE  SECTION.
     7  000007*COPY 'values.cpy'.
     8  000001 78  I   VALUE 20.
     9  000002 78  J   VALUE 5000.
    10  000003 78  M   VALUE 5.
    11  000008 01  SETUP-REC.
    12  000009     05  FL1       PIC X(04).
    13  000010     05  FL2       PIC ZZZZZ.
    14  000011     05  FL3       PIC 9(04).
    15  000012     05  FL4       PIC 9(08) COMP.
    16  000013     05  FL5       PIC 9(04) COMP-4.
    17  000014     05  FL6       PIC Z,ZZZ.99.
    18  000015     05  FL7       PIC S9(05) SIGN LEADING SEPARATE.
    19  000016     05  FL8       PIC X(04).
    20  000017     05  FL9 REDEFINES FL8 PIC 9(04).
    21  000018     05  FLA.
    22  000019         10  FLB OCCURS I TIMES.
    23  000020             15  FLC PIC X(02).
    24  000021         10  FLD   PIC X(20).
    25  000022     05  FLD1      PIC X(100).
    26  000025     05  FLD3      PIC X(3).
    27  000026     05  FLD4      PIC X(4).
    28  000023     05  FLD2 OCCURS M TO J TIMES DEPENDING ON FL5.
    29  000024         10  FILLER PIC X(01).
    30  000027 PROCEDURE        DIVISION.
    31  000028     STOP RUN.
    32        *>>>Info: Total Copy Depth Used = 02

ACS Cobol Xref v2.02.02          Dictionary File for PROG    06/12/2019  14:19:09:39                                   Page    2
Symbols of Module: PROG (PROG)
------------------------------

Data Section (WORKING-STORAGE)  Defn     Locations
-------------------------------+---------------------------------------------------------------

FL1                             000012W
FL2                             000013W
FL3                             000014W
FL4                             000015W
FL5                             000016W  000028
FL6                             000017W
FL7                             000018W
FL8                             000019W  000020
FL9                             000020W
FLA                             000021W
FLB                             000022W
FLC                             000023W
FLD                             000024W
FLD1                            000025W
FLD2                            000028W
FLD3                            000026W
FLD4                            000027W
I                               000008W  000022
J                               000009W  000028
M                               000010W  000028
SETUP-REC                       000011W

ACS Cobol Xref v2.02.02          Dictionary File for PROG    06/12/2019  14:19:09:39                                   Page    3
Symbols of Module: PROG (PROG)
------------------------------
Procedure                       Defn     Locations
-------------------------------+---------------------------------------------------------------

None

ACS Cobol Xref v2.02.02          Dictionary File for PROG    06/12/2019  14:19:09:39                                   Page    4
Symbols of Module: PROG (PROG)
------------------------------
Unreferenced Working Storage Symbols

FL1                             000012W
FL2                             000013W
FL3                             000014W
FL4                             000015W
FL6                             000017W
FL7                             000018W
FL9                             000020W
FLA                             000021W
FLB                             000022W
FLC                             000023W
FLD                             000024W
FLD1                            000025W
FLD2                            000028W
FLD3                            000026W
FLD4                            000027W
SETUP-REC                       000011W

ACS Cobol Xref v2.02.02          Dictionary File for PROG    06/12/2019  14:19:09:39                                   Page    5
Symbols of Module: PROG (PROG)
------------------------------
Unreferenced Procedures

None

10.1.2. Переменные среды времени компиляции

Ниже перечислены различные переменные среды, которые могут играть роль в компиляции программ GnuCOBOL.

COB_CC

Установите имя C-компилятора, который вы хотите использовать с GnuCOBOL.

Используйте эту функцию на свой страх и риск — вы всегда должны использовать C-компилятор, для которого был сгенерирован ваш gnucobol build.

COB_CFLAGS

Установите любые флаги, которые вы хотите передать C-компилятору из компилятора cobc, (в дополнение к любым, которые cobc укажет).

COB_CONFIG_DIR

Установите путь к папке, где хранятся файлы конфигурации GnuCOBOL (config).

COB_COPY_DIR

Если необходимые вашему программе копибуки не хранятся в той же директории, что и ваша программа, установите эту переменную окружения на папку, в которой можно найти копибуки (программисты IBM mainframe узнают это как SYSLIB).

COB_LDADD

Установите любые дополнительные флаги компоновщика (ld), которые могут указать, где можно найти стандартные библиотеки, которые необходимо связать с программой. По умолчанию это "" (пустая строка).

COB_CONFIG_DIR

Установите любые флаги компоновщика (ld), которые вы хотите передать C-компилятору из компилятора cobc (в дополнение к любым, которые cobc укажет).

COB_LIBS

Установите любые флаги компоновщика (ld), которые указывают, где находятся стандартные библиотеки, которые необходимо связать с программой.

COBCPY

Эта переменная среды предоставляет дополнительный способ указать, где компилятор может найти копибуки (см. также COB_COPY_DIR выше).

LD_LIBRARY_PATH

Если вы планируете использовать статически связанные библиотеки подпрограмм, установите эту переменную на путь к директории, содержащей ваши библиотеки.

TMPDIR
TMP

Установите каталог/папку для создания временных файлов. Здесь будут создаваться промежуточные рабочие файлы, созданные компилятором (и будут удалены, когда они больше не нужны).

Сначала проверяется переменная TMPDIR на наличие допустимого пути; если она не установлена, проверяется TMP.

В системе Windows переменная среды TMP обычно устанавливается при входе в систему. Если вы хотите использовать другую временную папку, вы можете установить TMPDIR самостоятельно, не опасаясь нарушить работу других программ Windows, которые полагаются на TMP.

* У переменных окружения, отмеченных звездочкой, выше есть значения по умолчанию, установленные при создании используемой вами версии GnuCOBOL. Чтобы увидеть эти значения по умолчанию, а также другую информацию, специфичную для сборки, выполните команду:
cobc -i

10.1.3. Предопределённые переменные компиляции

GnuCOBOL определяет переменные компиляции, когда выполняются определённые условия.

Если условие, связанное с переменной, ложно, переменная не определена во время компиляции.

DEBUG

Указан флаг отладки -d.

EXECUTABLE

Модуль, который компилируется, содержит главную программу.

GCCOMP

Размер элемента COMP определяется по схеме GnuCOBOL, где для элемента PICTURE длиной:

1-2

элемент имеет 1 байт

3-4

элемент имеет 2 байта

5-9

элемент имеет 4 байта

10-18

элемент имеет 8 байт.

GNUCOBOL

GnuCOBOL компилирует исходный модуль.

HOSTSIGNS

Значение знакового упакованного десятичного элемента может рассматриваться как NUMERIC, если знак имеет значение X"F".

IBMCOMP

Размер элемента COMP определяется по схеме IBM, где для элемента PICTURE длиной:

1-4

элемент имеет 2 байта

5-9

элемент имеет 4 байта

10-18

элемент имеет 8 байт.

MODULE

Модуль, который компилируется, не содержит главную программу.

NOHOSTSIGNS

Значение знакового упакованного десятичного элемента не может рассматриваться как

NUMERIC

если знак имеет значение X"F".

NOIBMCOMP

Размер элемента COMP не определяется по схеме IBM.

NOSTICKYLINKAGE

Вязкая связь (элементы секции связи остаются выделенными между вызовами) не включена.

NOTRUNC

Числовые данные усекаются в соответствии с их внутренним представлением.

P64

Указатели длиннее 32 бит.

STICKY-LINKAGE

Вязкая связь (элементы секции связи остаются выделенными между вызовами) включена.

TRUNC

Числовые данные усекаются в соответствии с их PICTURE разделами.

10.1.4. Поиск копибуков

Компилятор GnuCOBOL попытается найти копибуки, выполнив поиск в следующих папках. Поиск будет выполняться в указанном ниже порядке, и прекратится, как только копибук будет найден.

  1. Папка с именем library-name-1 в операторе COPY (см. COPY).
  2. Папка, в которой находится компилируемая программа.
  3. Папка, указанная в переключателе -I.
  4. Каждая из папок, указанных в переменной среды времени компиляции COBCPY (см. Переменные среды времени компиляции).

    Можно указать одну папку или несколько, разделенных символом-разделителем, соответствующим операционной системе. Если указано несколько папок, они будут проверяться в порядке их указания в переменной среды.

    Если используемая вами компилятор GnuCOBOL была скомпилирована для использования среды Windows, используйте символ точки с запятой (‘;’) в качестве разделителя.

    Однако, если компилятор GnuCOBOL был скомпилирован для среды Unix, OSX или Linux, или для среды Windows с использованием эмуляторов Unix Cygwin или MinGW, используйте двоеточие (‘:’) в качестве разделителя.

  5. Единственная папка, указанная в переменной среды COB_COPY_DIR.

При поиске в каждой из вышеперечисленных папок буклета — COPY XXXXXXXX., например, компилятор GnuCOBOL будет пытаться найти файл буклета с любым из следующих имен в указанном порядке:

  • XXXXXXXX.CPY
  • XXXXXXXX.CBL
  • XXXXXXXX.COB
  • XXXXXXXX.cpy
  • XXXXXXXX.cbl
  • XXXXXXXX.cob
  • XXXXXXXX

Оператор COPY чувствителен к регистру в системах UNIX; COPY copybookname и COPY COPYBOOKNAME оба не смогут найти буклет CopyBookName в системе UNIX.

Реализации GnuCOBOL под Windows могут быть чувствительны или нечувствительны к регистру имён буклета в зависимости от версии Windows и параметров сборки GnuCOBOL — безопаснее всего просто считать команду COPY чувствительной к регистру во всех средах.

Однако можно автоматически привести все имена всех буклета в операторах COPY к верхнему регистру, указав переключатель -ffold-copy с параметром upper (т.е. --fold-copy=upper) в компиляторе GnuCOBOL. Аналогично, имена можно привести к нижнему регистру, используя параметр lower (т.е. --fold-copy=lower). Если библиотеки буклета поддерживаются только с файлами и расширениями в верхнем или нижнем регистре, любой из этих параметров позволит найти буклеты независимо от того, как программист ввел их имена в операторах COPY.

Смену регистра можно включать и выключать в исходном коде программы с помощью оператора CDF >>SET (см. >>SET).

10.1.5. Файлы конфигурации компилятора

GnuCOBOL использует файлы конфигурации компилятора для определения различных параметров, которые будут управлять процессом компиляции. Эти файлы конфигурации указываются с помощью переключателя компиляции -conf и находятся в папке, определенной переменной среды времени компиляции COB_CONFIG_DIR (см. Переменные среды времени компиляции).

Если эта переменная не определена в *nix, по умолчанию используется /usr/local/share/gnucobol/config.

Ниже приводится дословный список файла конфигурации по умолчанию (который используется, если вы не указываете переключатель -conf), чтобы показать вам типы параметров, которые могут в нём присутствовать:

# GnuCOBOL compiler configuration
#
# Copyright (C) 2001-2012, 2014-2017 Free Software Foundation, Inc.
# Written by Keisuke Nishida, Roger While, Simon Sobisch, Edward Hart
#

# Value: any string
name: "GnuCOBOL"

# Value: enum
standard-define                 0
#        CB_STD_OC = 0,
#        CB_STD_MF,
#        CB_STD_IBM,
#        CB_STD_MVS,
#        CB_STD_BS2000,
#        CB_STD_ACU,
#        CB_STD_85,
#        CB_STD_2002,
#        CB_STD_2014

# Value: int
tab-width:                      8
text-column:                    72
# Maximum word-length for COBOL words / Programmer defined words
# Be aware that GC checks the word length against COB_MAX_WORDLEN
# first (currently 61)
word-length:                    61

# Maximum literal size in general
literal-length:                 8191

# Maximum numeric literal size (absolute maximum: 38)
numeric-literal-length: 38

# Maximum number of characters allowed in the character-string (max. 255)
pic-length:                             255

# Value: 'mf', 'ibm'
#
assign-clause:                  mf

# If yes, file names are resolved at run time using
# environment variables.
# For example, given ASSIGN TO "DATAFILE", the file name will be
#  1. the value of environment variable 'DD_DATAFILE' or
#  2. the value of environment variable 'dd_DATAFILE' or
#  3. the value of environment variable 'DATAFILE' or
#  4. the literal "DATAFILE"
# If no, the value of the assign clause is the file name.
#
filename-mapping:               yes

# Alternate formatting of numeric fields
pretty-display:                 yes

# Allow complex OCCURS DEPENDING ON
complex-odo:                    no

# Allow REDEFINES to other than last equal level number
indirect-redefines:             no

# Binary byte size - defines the allocated bytes according to PIC
# Value:         signed  unsigned  bytes
#                ------  --------  -----
# '2-4-8'        1 -  4    same        2
#                5 -  9    same        4
#               10 - 18    same        8
#
# '1-2-4-8'      1 -  2    same        1
#                3 -  4    same        2
#                5 -  9    same        4
#               10 - 18    same        8
#
# '1--8'         1 -  2    1 -  2      1
#                3 -  4    3 -  4      2
#                5 -  6    5 -  7      3
#                7 -  9    8 -  9      4
#               10 - 11   10 - 12      5
#               12 - 14   13 - 14      6
#               15 - 16   15 - 16      7
#               17 - 18   17 - 18      8
#
binary-size:                    1-2-4-8

# Numeric truncation according to ANSI
binary-truncate:                yes

# Binary byte order
# Value: 'native', 'big-endian'
binary-byteorder:               big-endian

# Allow larger REDEFINES items
larger-redefines-ok:            no

# Allow certain syntax variations (eg. REDEFINES position)
relax-syntax-checks:            no

# Perform type OSVS - If yes, the exit point of any currently
# executing perform is recognized if reached.
perform-osvs:                   no

# Compute intermediate decimal results like IBM OSVS
arithmetic-osvs:                no

# MOVE like IBM (mvc); left to right, byte by byte
move-ibm:               no

# If yes, linkage-section items remain allocated
# between invocations.
sticky-linkage:                 no

# If yes, allow non-matching level numbers
relax-level-hierarchy:          no

# If yes, evaluate constant expressions at compile time
constant-folding:               yes

# Allow Hex 'F' for NUMERIC test of signed PACKED DECIMAL field
hostsign:                       no

# If yes, set WITH UPDATE clause as default for ACCEPT dest-item,
# except if WITH NO UPDATE clause is used
accept-update:                  no

# If yes, set WITH AUTO clause as default for ACCEPT dest-item,
# except if WITH TAB clause is used
accept-auto:                    no

# If yes, DISPLAY's and ACCEPT's are, by default, done on the CRT (i.e.,
# using curses).
console-is-crt:                 no

# If yes, allow redefinition of the current program's name. This prevents
# its use in a prototype-format CALL/CANCEL statement.
program-name-redefinition:      yes

# If yes, NO ECHO/NO-ECHO/OFF is the same as SECURE (hiding input with
# asterisks, not spaces).
no-echo-means-secure:           no

# Dialect features
# Value: 'ok', 'warning', 'archaic', 'obsolete', 'skip', 'ignore', 'error',
#        'unconformable'

alter-statement:                        obsolete
comment-paragraphs:                     obsolete
call-overflow:                          archaic
data-records-clause:                    obsolete
debugging-mode:                         ok
use-for-debugging:                      obsolete
listing-statements:                     skip  # may be a user-defined word
title-statement:                        skip  # may be a user-defined word
entry-statement:                        ok
goto-statement-without-name:            obsolete
label-records-clause:                   obsolete
memory-size-clause:                     obsolete
move-noninteger-to-alphanumeric:        error
move-figurative-constant-to-numeric:    archaic
move-figurative-quote-to-numeric:       obsolete
multiple-file-tape-clause:              obsolete
next-sentence-phrase:                   archaic
odo-without-to:                         warning
padding-character-clause:               obsolete
section-segments:                       ignore
stop-literal-statement:                 obsolete
stop-identifier-statement:              obsolete
synchronized-clause:                    ok
top-level-occurs-clause:                ok
value-of-clause:                        obsolete
numeric-boolean:                        ok
hexadecimal-boolean:                    ok
national-literals:                      ok
hexadecimal-national-literals:          ok
acu-literals:                   unconformable
word-continuation:                      warning
not-exception-before-exception:         ok
accept-display-extensions:              ok
renames-uncommon-levels:                ok
constant-01:                            ok
constant-78:                            ok
program-prototypes:                     ok
reference-out-of-declaratives:          warning
numeric-value-for-edited-item:          ok
incorrect-conf-sec-order:               warning
define-constant-directive:              archaic

# use complete word list; synonyms and exceptions are specified below
reserved-words:         default

# not-reserved:
# Value: Word to be taken out of the reserved words list
not-reserved:   TERMINAL

# reserved:
# Entries of the form word-1=word-2 define word-1 as an alias for default
# reserved word word-2. No spaces are allowed around the equal sign.
reserved:       AUTO-SKIP=AUTO
reserved:       AUTOTERMINATE=AUTO
reserved:       BACKGROUND-COLOUR=BACKGROUND-COLOR
reserved:       BEEP=BELL
reserved:       BINARY-INT=BINARY-LONG
reserved:       BINARY-LONG-LONG=BINARY-DOUBLE
reserved:       EMPTY-CHECK=REQUIRED
reserved:       EQUALS=EQUAL
reserved:       FOREGROUND-COLOUR=FOREGROUND-COLOR
reserved:       INITIALISE=INITIALIZE
reserved:       INITIALISED=INITIALIZED
reserved:       LENGTH-CHECK=FULL
reserved:       ORGANISATION=ORGANIZATION
reserved:       SYNCHRONISED=SYNCHRONIZED
reserved:       TIMEOUT=TIME-OUT

10.2. Запуск программ

После компиляции программ GnuCOBOL в непосредственно исполняемые программы (созданные с помощью переключателя -x) или загружаемые динамически библиотеки (созданные с помощью переключателя -m), эти программы можно запустить из любой оболочки. Точный способ их запуска будет отличаться, как описано в следующих разделах.

10.2.1. Прямой запуск

Программы GnuCOBOL, скомпилированные с помощью переключателя -x, будут сгенерированы как непосредственно исполняемые программы. Например, собственная сборка GnuCOBOL для Windows или Windows/MinGW создаст файл .exe, когда для компилятора используется переключатель -x.

В сборках под Unix, OSX или Windows/Cygwin, переключатель -x сгенерирует исполняемый бинарный файл, обычно без какого-либо расширения, если оно не запрошено явно у компилятора с помощью переключателя -o.

В системе UNIX это означает, что программы могут запускаться из оболочки командной строки, такой как bash, csh, ksh и так далее. Когда программа GnuCOBOL выполняется на системе Windows, она выполняется в окне консоли (т.е. cmd.exe). Версии GnuCOBOL для OSX работают в окне terminal.app.

Взаимодействие программы с пользователем происходит с использованием стандартных потоков ввода, вывода и ошибок. Любой вывод в экран, выполняемый программой, будет происходить в окне терминала.

Синтаксис прямого запуска программы: [path]program [arguments].

Например:

/usr/local/printaccount ACCT=6625378

или

C:\\Users\\Me\\Documents\\Programs\\printaccount.exe ACCT=6625378

10.2.2. Запуск динамически загружаемых библиотек

Как обсуждалось ранее, динамически загружаемые библиотеки создаются с помощью переключателя компилятора -m. После создания программы в этих библиотеках выполняются из командной строки (через утилиту GnuCOBOL cobcrun или как динамически загружаемые подпрограммы.

10.2.2.1. cobcrun - Выполнение из командной строки

Можно сгенерировать исполняемые модули для всех программ GnuCOBOL, а не только подпрограмм, выбрав опцию переключателя -m для указания формата выходных данных загрузчика, даже для основных программ.

Некоторые могут предпочесть компилировать свои основные программы GnuCOBOL в эти динамически загружаемые модули, чтобы использовать одну и ту же команду компиляции для всех программ, без необходимости думать «Это основная программа или подпрограмма?».

Основные программы, скомпилированные таким образом, должны выполняться следующим образом:

[path]cobcrun program [arguments]

Не указывайте расширение .so или .dll для имени программы. Значение program должно точно соответствовать имени первичной точки входа основной программы (включая прописные и строчные буквы), если вы не планируете использовать свертку вызовов (см. Динамически загруженные подпрограммы).

Общие использование и синтаксис cobcrun приведены в выводе cobcrun -h (или –help):

COBOL driver program for GnuCOBOL modules

Usage: cobcrun [options] PROGRAM [parameter ...]
  or:  cobcrun options

Options:
  -h, -help                      display this help and exit
  -V, -version                   display cobcrun and runtime version and exit
  -i, -info                      display runtime information (build/environment)
  -c <file>, -config=<file>      set runtime configuration from <file>
  -r, -runtime-conf              display current runtime configuration
                                 (value and origin for all settings)
  -M <module>, -module=<module>  set entry point module name and/or load path
                                 where -M module prepends any directory to the
                                 dynamic link loader library search path
                                 and any basename to the module preload list
                                 (COB_LIBRARY_PATH and/or COB_PRELOAD)

Вот два примера использования cobcrun. Во-первых, на системах Unix, OSX или Windows/Cygwin:

cd /usr/local
cobcrun printaccount acct=6625378

Или на системах Native Windows или Windows/MinGW:

cd C:\Users\Me\Documents\Programs
cobcrun printaccount.exe acct=6625378

Обратите внимание, как команда cobcrun не позволяет указывать путь к имени программы — каталог, в котором находится динамически загружаемый модуль программы, должен быть либо текущим каталогом, либо должен быть определён в текущем PATH.

10.2.2.2. Динамически загруженные подпрограммы

Динамически загруженные подпрограммы выполняются (с точки зрения синтаксиса COBOL) как и любые другие подпрограммы. Однако, что делает их уникальными, так это то, что они загружаются в память только тогда, когда они фактически используются в первый раз во время выполнения программы.

Когда необходимо загрузить динамически загружаемый модуль (потому что он ещё не находится в памяти из предыдущего выполнения подпрограммы), динамически загружаемая библиотека будет искаться в том же каталоге, из которого загружалась основная программа. Если её не удаётся найти там, каждый каталог, указанный в переменной среды выполнения PATH (см. Переменные среды выполнения), будет проверен. Если библиотека не была найдена ни в одном из этих каталогов, будет проверен каталог, указанный в переменной среды выполнения COB_LIBRARY_PATH. Наконец, если её по-прежнему не удаётся найти, выполнение будет прекращено с сообщением об ошибке (libcob: Не удаётся найти модуль ’xxxxxxxx’).

Процесс поиска динамически загружаемых модулей чувствителен к регистру на системах UNIX; CALL "dynsub" и CALL "DYNSUB" оба не найдут библиотеку DynSub.so на системе UNIX.

Реализации GnuCOBOL на Windows могут быть или не быть аналогично чувствительными к регистру имён библиотек, в зависимости от версии Windows и параметров сборки GnuCOBOL — безопаснее просто рассматривать имена библиотек как чувствительные к регистру во всех средах.

Однако можно автоматически привести все имена библиотек к верхнему регистру, указав переключатель -ffold-call с опцией «upper» (т. е. --fold-call=upper) в компиляторе GnuCOBOL. Аналогично, имена библиотек можно привести к нижнему регистру, используя опцию «lower» (т. е. --fold-call=lower. Если библиотеки поддерживаются только с использованием имён файлов с заглавными или строчными буквами, любой из этих вариантов позволит найти библиотеки независимо от того, как программист ввёл их в инструкции CALL.

См. Подпрограммирование для полного обсуждения подпрограммирования.

10.2.3. Переменные среды выполнения

Ниже приведен список различных переменных среды, которые могут играть роль в выполнении программ GnuCOBOL.

COB_DISPLAY_WARNINGS

Если установлено значение ‘Y’, любые предупреждения во время выполнения (такие как указание на неявное закрытие открытых файлов при выполнении оператора GOBACK (см. GOBACK) или оператора STOP (см. STOP) с опцией RUN) будут отображаться. Любое другое значение этой переменной среды (включая отсутствие установки переменной) подавит такие сообщения.

COB_LIBRARY_PATH

Во время выполнения GnuCOBOL попытается найти и загрузить любые динамически загружаемые библиотеки приложения, используя каталог, в котором был найден исполняемый файл программы, или, если он не был найден там, используя переменную среды PATH. Если эти библиотечные файлы могут быть где-то еще, укажите путь к каталогу с помощью этой переменной.

COB_LOAD_CASE

Если установлено значение UPPER или LOWER, эта переменная среды будет внутренне преобразовывать имена точек входа, на которые есть ссылки, в верхний или нижний регистр, прежде чем начать поиск динамически загружаемых модулей. Значения UPPER и LOWER переменной среды фактически нечувствительны к регистру.

COB_PHYSICAL_CANCEL

Если установлено значение ‘Y’, ‘y’ или ‘1’, оператор CANCEL (см. CANCEL) физически разгрузит динамически загружаемый модуль подпрограммы. Если установлено другое значение, оператор CANCEL (см. CANCEL) логически разгрузит модуль, так что последующее использование повторно инициализирует модуль, как если бы он был фактически перезагружен, но накладные расходы на фактическую перезагрузку модуля будут устранены.

COB_PRE_LOAD

Если установлено любое ненулевое значение, эта переменная заставит все динамически загружаемые библиотеки загружаться при запуске программы (вместо поиска и загрузки модуля при первом использовании).

COB_SET_DEBUG

Если существует раздел USE FOR DEBUGGING (см. DECLARATIVES), код в нём будет отключён, если эта переменная среды не установлена в значение ‘Y’, ‘y’ или ‘1’.

COB_SET_TRACE

Если при компиляции программы использовался переключатель -ftrace (отслеживание процедур) или -ftraceall (отслеживание процедур и операторов), установка этой переменной среды в значение ‘Y’ активирует отслеживание в момент запуска программы. Установка этой переменной среды в любое другое значение (или её отсутствие) отключит отслеживание. Отслеживание, если оно настроено одним из двух описанных выше переключателей, также может контролироваться оператором READY TRACE (см. READY TRACE) и оператором RESET TRACE (см. RESET TRACE). Если COB_SET_TRACE установлено в Y, то отслеживание всегда будет происходить независимо от наличия READY TRACE или RESET TRACE, поэтому они не будут иметь никакого влияния на выполнение программы.

COB_SCREEN_ESC

Если установлено любое непустое значение, эта переменная позволяет оператору ACCEPT screen-data-item (см. ACCEPT screen-data-item) обнаруживать клавишу Esc.

COB_SCREEN_EXCEPTIONS

Установка этой переменной в любое непустое значение позволит оператору ACCEPT screen-data-item (см. ACCEPT screen-data-item) обнаруживать нажатие клавиш Esc, PgUp и PgDn.

COB_SORT_MEMORY

Значение этой переменной (целое число) будет использоваться для определения объёма памяти, который будет выделен для сортировки. Если значение равно 1048576 или больше, это значение будет использовано «как есть» как объем памяти (в байтах) для выделения. Если значение меньше 1048576, оно укажет объем памяти в МБ для выделения. Значение по умолчанию для памяти сортировки — 128 МБ.

COB_SWITCH_n

(n=0 до 15); Эти переменные среды соответствуют SWITCH-0 по SWITCH-15, определённым в параграфе SPECIAL-NAMES (см. SPECIAL-NAMES). Установка их в ON активирует их; любое другое значение отключает их.

COB_SYNC

Если установлено значение в верхнем или нижнем регистре ‘p’, эта переменная будет принудительно производить фиксацию файла каждый раз, когда в файл записывается информация (обеспечивая, что данные будут немедленно записаны в файл, а не храниться в памяти до момента будущей фиксации). Это замедлит доступ к обновлениям файлов, но обеспечит лучшую целостность в случае сбоя программы.

COB_TRACE_FILE

Если установлено любое ненулевое значение, эта переменная среды указывает файл, в который будет записан весь вывод переключателей -ftrace и -ftraceall. Если это значение НЕ установлено, весь вывод переключателей -ftrace и -ftraceall будет записан в STDERR, где он может быть перенаправлен через «2> имя_файла» в команде, которая выполняет программу.

DB_HOME

Если ваша сборка GnuCOBOL использует пакет Berkeley Database (BDB), используйте эту переменную среды для указания папки, в которой будут храниться файлы управления блокировкой, связанные со всеми файлами, не являющимися SORT, открытыми программой. Файлы ORGANIZATION INDEXED (см. ORGANIZATION INDEXED) также будут иметь свой файл данных, выделенный в папке, на которую указывает эта переменная среды, если она существует. Определение этой переменной активирует функции блокировки записей в операторе READ (см. READ), операторе REWRITE (см. REWRITE) и операторе WRITE (см. WRITE). Даже с DB_HOME блокировка не будет работать с ORGANIZATION SEQUENTIAL (см. ORGANIZATION SEQUENTIAL), ORGANIZATION LINE SEQUENTIAL (см. ORGANIZATION LINE SEQUENTIAL) или файлами ORGANIZATION RELATIVE, созданными в GnuCOBOL для Windows/MinGW. ORGANIZATION INDEXED блокировки будут работать с Windows/MinGW + BDB, и все блокировки будут работать для всех организаций файлов с UNIX GnuCOBOL сборками.

PATH

Директория GnuCOBOL «bin» должна быть определена в переменной PATH.

TMPDIR
TMP
TEMP

Одна из этих переменных среды должна быть установлена на каталог/папку, подходящую для создания временных файлов. Они будут проверяться в указанном порядке. Это будет использовано оператором SORT (см. SORT) и оператором MERGE (см. MERGE) для создания временных рабочих файлов. Вы также можете использовать эту папку для любых временных файлов, которые может потребовать ваше приложение.

Также во время выполнения программ используется runtime.cfg, также расположенный в /usr/local/share/gnucobol/config для *nix, и этот файл также может быть изменён для соответствия вашей среде, если необходимо. При просмотре обратите внимание на параметры по умолчанию.

10.2.3.1. Общие инструкции

 The initial runtime.cfg file is found in the  $COB_CONFIG_DIR/config
 (  COB_CONFIG_DIR  defaults to  installdir/gnucobol  ).
 The environment variable  COB_RUNTIME_CONFIG  may define a different runtime
 configuration file to read.

 If settings are included in the runtime environment file multiple times
 then the last setting value is used, no warning occurs.

 Settings via environment variables always take precedence over settings
 that are given in runtime configuration files. And the environment is
 checked after completing processing of the runtime configuration file(s)

 All values set to string variables or environment variables are checked
 for  ${envvar}  and replacement is done at the time of the setting.

 Any environment variable may be set with the directive  setenv  .
 Example:  setenv COB_LIBRARY_PATH ${LD_LIBRARY_PATH}

 Any environment variable may be unset with the directive  unsetenv
 (one var per line).
 Example:  unsetenv COB_LIBRARY_PATH

 Runtime configuration files can include other files with the directive
 include.
 Example:  include my-runtime-configuration-file

 To include another configuration file only if it is present use the directive
 includeif.
 You can also use  ${envvar}  inside this.
 Example:  includeif ${HOME}/mygc.cfg

 If you want to reset a parameter to its default value use:
    reset parametername

 Most runtime variables have boolean values, some are switches, some have
 string values, integer values and some are size values.
 The boolean values will be evaluated as following:
       to true:          1, Y, ON, YES, TRUE  (no matter of case)
       to false:         0, N, OFF
 A 'size' value is an integer optionally followed by K, M, or G for kilo, mega
 or giga.

 For convenience a parameter in the runtime.cfg file may be defined by using
 either the environment variable name or the parameter name.
 In most cases the environment variable name is the parameter name (in upper
 case) with the prefix  COB_  .

 Note: If you want to *slightly* speed up a program's startup time, remove all
       of the comments from the actual real configuration file that is processed

10.2.3.2. Общая среда

 Environment name:  COB_DISABLE_WARNINGS
   Parameter name:  disable_warnings
          Purpose:  turn off runtime warning messages
             Type:  boolean
          Default:  false
          Example:  DISABLE_WARNINGS  TRUE

 Environment name:  COB_ENV_MANGLE
   Parameter name:  env_mangle
          Purpose:  names checked in the environment would get non alphanumeric
                    change to '_'
             Type:  boolean
          Default:  false
          Example:  ENV_MANGLE  TRUE

 Environment name:  COB_SET_DEBUG
   Parameter name:  debugging_mode
          Purpose:  to enable USE ON DEBUGGING procedures that were active
                    during compile-time because of WITH DEBUGGING MODE,
                    otherwise the code generated will be skipped
             Type:  boolean
          Default:  false
          Example:  COB_SET_DEBUG  1

 Environment name:  COB_SET_TRACE
   Parameter name:  set_trace
          Purpose:  to enable COBOL trace feature
             Type:  boolean
          Default:  false
          Example:  SET_TRACE  TRUE

 Environment name:  COB_TRACE_FILE
   Parameter name:  trace_file
          Purpose:  to define where COBOL trace output should go
             Type:  string
          Default:  stderr
          Example:  TRACE_FILE  ${HOME}/mytrace.log

 Environment name:  COB_TRACE_FORMAT
   Parameter name:  trace_format
          Purpose:  to define format of COBOL trace output
             Type:  string
          Default:  "%P %S Line: %L"
                    %P is replaced by Program-Id/Function-Id minimal length 29
                       with prefix
                    %I is replaced by Program-Id/Function-Id variable length,
                       without prefix
                    %L is replaced by Line number, right justified, length 6
                    %S is replaced by statement type and name
                    %F is replaced by source file name
          Example:  TRACE_FORMAT  "Line: %L %S"
             Note:  format of GC2.2 and older:
                    "PROGRAM-ID: %I    Line: %L        %S"

For v4.0+
 Environment name:  COB_TRACE_IO
  Parameter name:  trace_io
         Purpose:  define if I/O details should be added to trace
            Type:  boolean
         Default:  false
         Example:  TRACE_IO true

 Environment name:  COB_DUMP_FILE
   Parameter name:  dump_file
          Purpose:  to define where COBOL dump output should go
             Note:  The -fdump=all compile option prepares for dump
             Type:  string       : $$ is replaced by process id
          Default:  stderr
          Example:  DUMP_FILE  ${HOME}/mytrace.log

 Environment name:  COB_DUMP_WIDTH
   Parameter name:  dump_width
          Purpose:  to define COBOL dump line length
             Type:  integer
          Default:  100
          Example:  dump_width 120

For v4.0+
 Environment name:  COB_STATS_RECORD
  Parameter name:  stats_record
         Purpose:  define if I/O statistics should be written
            Type:  boolean
         Default:  false
         Example:  STATS_RECORD true

For v4.0+
 Environment name:  COB_STATS_FILE
  Parameter name:  stats_file
         Purpose:  to define where COBOL I/O statistics should be written
                   The file is appended to
            Type:  string
         Default:  stderr
         Example:  STATS_FILE  ${HOME}/mystats.txt

 Environment name:  COB_CURRENT_DATE
   Parameter name:  current_date
          Purpose:  specify an alternate Date/Time to be returned to ACCEPT
                    clauses this is used for testing purposes or to tweak
                    a missing offset partial setting is allowed
             Type:  numeric string in format YYYYDDMMHH24MISS or date string
          Default:  the operating system date is used
          Example:  COB_CURRENT_DATE "2016/03/16 16:40:52"
                    current_date YYYYMMDDHHMMSS+01:00

10.2.3.3. Среда вызова

 Environment name:  COB_LIBRARY_PATH
   Parameter name:  library_path
          Purpose:  paths for dynamically-loadable modules
             Type:  string
             Note:  the default paths .:/installpath/extras are always
                    added to the given paths
          Example:  LIBRARY_PATH    /opt/myapp/test:/opt/myapp/production

 Environment name:  COB_PRE_LOAD
   Parameter name:  pre_load
          Purpose:  modules that are loaded during startup, can be used
                    to CALL COBOL programs or C functions that are part
                    of a module library
             Type:  string
             Note:  the modules listed should NOT include extensions, the
                    runtime will use the right ones on the various platforms,
                    COB_LIBRARY_PATH is used to locate the modules
          Example:  PRE_LOAD      COBOL_function_library:external_c_library

 Environment name:  COB_LOAD_CASE
   Parameter name:  load_case
          Purpose:  resolve ALL called program names to UPPER or LOWER case
             Type:  Only use  UPPER  or  LOWER
          Default:  if not set program names in CALL are case sensitive
          Example:  LOAD_CASE  UPPER

 Environment name:  COB_PHYSICAL_CANCEL
   Parameter name:  physical_cancel
          Purpose:  physically unload a dynamically-loadable module on CANCEL,
                    this frees some RAM and allows the change of modules during
                    run-time but needs more time to resolve CALLs (both to
                    active and not-active programs)
            Alias:  default_cancel_mode, LOGICAL_CANCELS (0 = yes)
             Type:  boolean (evaluated for true only)
          Default:  false
          Example:  PHYSICAL_CANCEL  TRUE

10.2.3.4. Ввод/вывод файлов

 Environment name:  COB_VARSEQ_FORMAT
   Parameter name:  varseq_format
          Purpose:  declare format used for variable length sequential files
                    - different types and lengths precede each record
                    - 'length' is the data length, does not include the prefix
             Type:  0   means 2 byte record length (big-endian) + 2 NULs
                    1   means 4 byte record length (big-endian)
                    2   means 4 byte record length (local machine int)
                    3   means 2 byte record length (big-endian)
          Default:  0
          Example:  VARSEQ_FORMAT 1

For v4.0+
 Environment name: COB_VARREL_FORMAT
  Parameter name: varrel_format
         Purpose: declare format to be used for variable length relative files
            Type: gc  means 'size_t' record length (local machine) precedes
                            maxiumum length data record
                  mf  means file is in Micro Focus format
                 b32  means Big-Endian 32-bit 'int' record length precedes data
                 b64  means Big-Endian 64-bit 'int' record length precedes data
                 l32  means Little-Endian 32-bit 'int' record length precedes data
                 l64  means Little-Endian 64-bit 'int' record length precedes data
         Default: gc
            NOTE: 'gc' results in files which cannot be used if copied between
                       machines of different hardware archeticture
         Example: VARREL_FORMAT mf

For v4.0+
 Environment name:  COB_FIXREL_FORMAT
  Parameter name:  fixrel_format
         Purpose:  declare format to be used for fixed length relative
                   files (different types and lengths preceding each record)
            Type:  b32 means 4 byte record length (big-endian)
                   l32 means 4 byte record length (little-endian)
                   b64 means 8 byte record length (big-endian)
                   l64 means 8 byte record length (little-endian)
                   mf  means Micro Focus default
                   gc  means GnuCOBOL default (local 'size_t')
         Default:  gc  fixed size with no record length prefix
         Example:  FIXREL_FORMAT B32

For v4.0+
 Environment name: COB_VARFIX_FORMAT
  Parameter name: varfix_format
         Purpose: declare format to be used for fixed length relative files
            Type: gc  means 'size_t' record length (local machine) precedes
                            fixed length data record
                  mf  means file is in Micro Focus format
                 b32  means Big-Endian 32-bit 'int' record length precedes data
                 b64  means Big-Endian 64-bit 'int' record length precedes data
                 l32  means Little-Endian 32-bit 'int' record length precedes data
                 l64  means Little-Endian 64-bit 'int' record length precedes data
         Default: gc
            NOTE: 'gc' results in files which cannot be used if copied between
                       machines of different hardware archeticture
         Example: VARFIX_FORMAT mf

 Environment name:  COB_FILE_PATH
   Parameter name:  file_path
          Purpose:  define default location where data files are stored
             Type:  file path directory
          Default:  .  (current directory)
          Example:  FILE_PATH ${HOME}/mydata

 Environment name:  COB_LS_FIXED
   Parameter name:  ls_fixed
          Purpose:  Defines if LINE SEQUENTIAL files should be fixed length
                    (or variable, by removing trailing spaces)
            Alias:  STRIP_TRAILING_SPACES  (0 = yes)
             Type:  boolean
          Default:  false
          Example:  LS_FIXED TRUE

 Environment name:  COB_LS_NULLS
   Parameter name:  ls_nulls
          Purpose:  Defines for LINE SEQUENTIAL files what to do with data
                    which is not DISPLAY type.  This could happen if a LINE
                    SEQUENTIAL record has BINARY/COMP data fields in it.
                    For v4.0+ (may change before its release candidate)
                    This option is only for GnuCOBOL format files
             Type:  boolean
          Default:  false
             Note:  The TRUE setting will insert a null character x"00" before
                    those values to escape them, and redo on read-in.
          Example:  LS_NULL = TRUE

For v4.0+
Environment name:  COB_LS_SPLIT
  Parameter name:  ls_split
         Purpose:  Defines for LINE SEQUENTIAL files what to do when a record
                   is longer than the program handles. If 'ls_split=true' then
                   the data is returned as multiple records
            Type:  boolean
         Default:  false
                   The record is truncated and the file skips to the next LF
         Example:  LS_SPLIT = TRUE

For v4.0+
Environment name:  COB_LS_VALIDATE
  Parameter name:  ls_validate
         Purpose:  Defines for LINE SEQUENTIAL files that the data should be
                   validated. If any record has non-DISPLAY characters then
                   an error status of 34 is returned
                   For v4.0+ (may change before its release candidate)
                   This option is only for GnuCOBOL format files
            Type:  boolean
         Default:  true
            Note:  The TRUE setting does data validation
                   The FALSE setting lets non-DISPLAY characters be written
                   If LS_NULLS is set, then LS_VALIDATE is not checked
         Example:  LS_VALIDATE = FALSE

For v4.0+ (may be replaced before its release candidate)
 Environment name: COB_MF_FILES
  Parameter name: mf_files
         Purpose:  Declares that all files in the program should be in
                   Micro Focus compatible format.
            Type:  boolean (evaluated for true only)
         Default:  false
         Example:  mf_files True

For v4.0+ (may be replaced before its release candidate)
 Environment name:  COB_MF_LS_NULLS
  Parameter name:  mf_ls_nulls
         Purpose:  Defines for Micro Focus compatible LINE SEQUENTIAL files
                   what to do with data which is not DISPLAY type.
                   This could happen if a LINE SEQUENTIAL record has
                   BINARY/COMP data fields in it.
            Type:  boolean
         Default:  true
            Note:  The TRUE setting will handle files that contain COMP data
                   in a similar manner to the method used by Micro Focus COBOL
         Example:  MF_LS_NULLS = TRUE

For v4.0+ (may be replaced before its release candidate)
 Environment name:  COB_MF_LS_INSTAB
   Parameter name:  mf_ls_instab
          Purpose:  Defines for LINE SEQUENTIAL files that multiple spaces
                    should be replaced by a TAB character, assuming a 'tab set'
                    value of 8. Each TAB means to skip to the next column that
                    is a multiple of 8
                    Similar to Micro Focus INSERTTAB=ON option
             Type:  boolean
          Default:  false
          Example:  MF_LS_INSTAB = TRUE

For v4.0+ (may be replaced before its release candidate)
 Environment name:  COB_MF_LS_SPLIT
  Parameter name:  mf_ls_split
         Purpose:  Defines for Micro Focus compatible LINE SEQUENTIAL files what
                   to do when a record is longer than the program handles.
                   If 'mf_ls_split=true' then
                   the data is returned as multiple records
            Type:  boolean
         Default:  true
         Example:  MF_LS_SPLIT = FALSE

For v4.0+ (may be replaced before its release candidate)
 Environment name:  COB_MF_LS_VALIDATE
  Parameter name:  mf_ls_validate
         Purpose:  Defines for Micro Focus compatible LINE SEQUENTIAL files
                   that the data should be validated.
                   If any record has non-DISPLAY characters then
                   an error status of 34 is returned
            Type:  boolean
         Default:  false
            Note:  The TRUE setting does data validation
                   The FALSE setting lets non-DISPLAY characters be written
                   If MF_LS_NULLS is set, then MF_LS_VALIDATE is not checked
         Example:  MF_LS_VALIDATE = FALSE

For v4.0+
 Environment name:  COB_SHARE_MODE
  Parameter name:  share_mode
         Purpose:  Defines what file sharing option should be used
            Type:  -- choice of values ---
                   none - nothing overrides application code
                   read - files opened as SHARE READ ONLY
                   all  - files opened as SHARE ALL OTHERS
                   no   - files opened as SHARE NO OTHERS
         Default:  none
         Example:  share_mode = ALL

For v4.0+
 Environment name:  COB_RETRY_MODE
  Parameter name:  retry_mode
         Purpose:  Defines what I/O retry sharing option should be used
            Type:  --- choice of values ---
                   none    - nothing overrides application code
                   never   - I/O is never retried
                   forever - I/O will be retried until success
         Default:  none
         Example:  retry_mode = never

For v4.0+
 Environment name:  COB_RETRY_TIMES
  Parameter name:  retry_times
         Purpose:  Defines how many times I/O should be retried
            Type:  integer
         Default:  0
         Example:  retry_times = 10

For v4.0+
 Environment name:  COB_RETRY_SECONDS
  Parameter name:  retry_seconds
         Purpose:  Defines how many seconds I/O should be retried
            Type:  integer
         Default:  0
         Example:  retry_seconds = 6

For v4.0+
 Environment name:  COB_KEYCHECK
  Parameter name:  keycheck
         Purpose:  Must INDEXED file keys match COBOL SELECT exactly
            Type:  boolean
         Default:  true
         Example:  keycheck = off

 Environment name:  COB_SYNC
   Parameter name:  sync
          Purpose:  Should the file be synced to disk after each write/update
             Type:  boolean
          Default:  false
          Example:  SYNC: TRUE

 Environment name:  COB_SORT_MEMORY
   Parameter name:  sort_memory
          Purpose:  Defines how much RAM to assign for sorting data
                    if this size is exceeded the  SORT  will be done
                    on disk instead of memory
             Type:  size  but must be more than 1M
          Default:  128M
          Example:  SORT_MEMORY 64M

 Environment name:  COB_SORT_CHUNK
   Parameter name:  sort_chunk
          Purpose:  Defines how much RAM to assign for sorting data in chunks
             Type:  size  but must be within 128K and 16M
          Default:  256K
          Example:  SORT_CHUNK 1M

10.2.3.5. Ввод/вывод экрана

 Environment name:  COB_BELL
   Parameter name:  bell
          Purpose:  Defines how a request for the screen to beep is handled
             Type:  FLASH, SPEAKER, FALSE, BEEP
          Default:  BEEP
          Example:  BELL SPEAKER

 Environment name:  COB_REDIRECT_DISPLAY
   Parameter name:  redirect_display
          Purpose:  Defines if DISPLAY output should be sent to 'stderr'
             Type:  boolean
          Default:  false
          Example:  redirect_display Yes

 Environment name:  COB_SCREEN_ESC
   Parameter name:  screen_esc
          Purpose:  Enable handling of ESC key during ACCEPT
             Type:  boolean
          Default:  false
             Note:  is only evaluated if COB_SCREEN_EXCEPTIONS is active
          Example:  screen_esc Yes

 Environment name:  COB_SCREEN_EXCEPTIONS
   Parameter name:  screen_exceptions
          Purpose:  enable exceptions for function keys during ACCEPT
             Type:  boolean
          Default:  false
          Example:  screen_exceptions Yes

 Environment name:  COB_TIMEOUT_SCALE
   Parameter name:  timeout_scale
          Purpose:  specify translation in milliseconds for ACCEPT clauses
                    BEFORE TIME value / AFTER TIMEOUT
             Type:  integer
                    0 means 1000 (Micro Focus COBOL compatible), 1 means 100
                    (ACUCOBOL compatible), 2 means 10, 3 means 1
          Default:  0
          Example:  timeout_scale 3

 Environment name:  COB_INSERT_MODE
   Parameter name:  insert_mode
          Purpose:  specify default insert mode for ACCEPT; 0=off, 1=on
             Type:  boolean
          Default:  false
             Note:  also sets the cursor type (if available)
          Example:  insert_mode Y

 Environment name:  COB_MOUSE_FLAGS
  Parameter name:  mouse_flags
         Purpose:  specify which mouse events will be sent as function key
                   to the application during ACCEPT and how they will be
                   handled
            Type:  int (by bits)
         Default:  1
            Note:  0 disables the mouse cursor, any other value enables it,
                   any value containing 1 will enable internal handling (click
                   to position, double-click to enter).
                   See copy/screenio.cpy for list of events and their values.
           Alias:  MOUSE_FLAGS
         Example:  11 (enable internal handling => 1, left press => 2,
                       double-click => 8; 1+2+8=11)
 Environment name:  COB_MOUSE_INTERVAL
  Parameter name:  mouse_interval
         Purpose:  specifies the maximum time (in thousands of a second)
                   that can elapse between press and release events for them
                   to be recognized as a click.
            Type:  int (0 - 166)
         Default:  100
            Note:  0 disables the click resolution (instead press + release
                   are recognized), also disables positioning by mouse click

 Environment name:  COB_DISPLAY_PRINT_PIPE
  Parameter name:  display_print_pipe
         Purpose:  Defines command line used for sending output of
                   DISPLAY UPON PRINTER to (via pipe)
                   This is very similar to Micro Focus COBPRINTER
            Note:  Each executed DISPLAY UPON PRINTER statement causes a
                   new invocation of command-line (= new process start).
                   Each invocation receives the data referenced in
                   the DISPLAY statement and is followed by an
                   end-of-file condition.
                   COB_DISPLAY_PRINT_FILE, if set, takes precedence
                   over COB_DISPLAY_PRINT_PIPE.
           Alias:  COBPRINTER
            Type:  string
         Default:  not set
         Example:  print 'cat >>/tmp/myprt.log'

 Environment name:  COB_DISPLAY_PRINT_FILE
  Parameter name:  display_print_file
         Purpose:  Defines file to be appended to by DISPLAY UPON PRINTER
            Note:  Each DISPLAY UPON PRINTER opens, appends and closes the file.
            Type:  string       : $$ is replaced by process id
         Default:  not set
         Example:  display_printer '/tmp/myprt.log'

 Environment name:  COB_DISPLAY_PUNCH_FILE
  Parameter name:  display_punch_file
         Purpose:  Defines file to be created on first
                   DISPLAY UPON SYSPUNCH/SYSPCH
            Note:  The file will be only be closed on runtime exit.
            Type:  string       : $$ is replaced by process id
         Default:  not set
         Example:  display_punch './punch_$$.out'

 Environment name:  COB_LEGACY
   Parameter name:  legacy
          Purpose:  keep behaviour of former runtime versions, currently only
                    for setting screen attributes for non input fields
             Type:  boolean
          Default:  not set
          Example:  legacy true

 Environment name:  COB_EXIT_WAIT
   Parameter name:  exit_wait
          Purpose:  to wait on main program exit if an extended screenio
                    DISPLAY was issued without an ACCEPT following
             Type:  boolean
          Default:  true
          Example:  COB_EXIT_WAIT off

 Environment name:  COB_EXIT_MSG
   Parameter name:  exit_msg
          Purpose:  string to display if COB_EXIT_WAIT is processed, set to '@w{}'
                    if no actual display but an ACCEPT should be done
             Type:  string
          Default:  'end of program, please press a key to exit' (localized)
          Example:  COB_EXIT_MSG '@w{}'

10.2.3.6. Ввод/вывод отчётов

 Environment name:  COB_COL_JUST_LRC
   Parameter name:  col_just_lrc
          Purpose:  If true, then COLUMN defined as LEFT, RIGHT or CENTER
                    will have the data justified within the field limits
                    If false, then the data is just copied into the column as is
             Type:  boolean
          Default:  TRUE
          Example:  col_just_lrc True

10.2.3.7. Переменные среды для ввода/вывода файлов и/или файл словаря

GnuCOBOL 4.+ only!

Before a file is opened a check is done for environment variables that
may define various attributes of the file
First a check is made for attributes for files of the same ORGANIZATION
IX_OPTIONS for INDEXED, SQ_OPTIONS for SEQUENTIAL, RL_OPTIONS for RELATIVE
LS_OPTIONS for LINE SEQUENTIAL, LA_OPTIONS for LINE ADVANCING SEQUENTIAL
If none of these are present, it then checks for IO_OPTIONS

Then an additional check is done for IO_asgnmame where 'asgname' was
the ASSIGN EXTERNAL name used in the program

The environment variable (or dictionary file) may contain any of the
following keywords, separated by spaces and/or commas

You can specify just the keyword and it is assumed to mean set to true,
or no-keyword (or no_keyword or nokeyword) which means set to false,
or keyword=true or keyword=false.  The valid keywords are:
Keyword          Meaning
=========        ======================================================
type=xx          Set file organization where 'xx' is one of
                 IX = INDEXED, SQ = SEQUENTIAL, RL = RELATIVE
                 LS = LINE SEQUENTIAL, LA = LINE ADVANCING
mf               Set file to Micro Focus compatible format
gc               Set to original GnuCOBOL default format
recsz            The size for fixed size record file
maxsz            Maximum record size for variable length records
minsz            Minimum record size for variable length records
ls_nulls         Do NUL insertion before characters less than a SPACE,
                 Default: false
ls_validate      Validate data for LINE Sequential Files, Default: true
crlf             Lines end with CR LF (Windows format for text files)
lf               Lines end with LF (Unix format for text files)
sync             Sync all writes to disk
B32              Use 32-bit Big-Endian format 'int' as record length
L32              Use 32-bit Little-Endian format 'int' as record length
B64              Use 64-bit Big-Endian format 'int' or 'size_t' as record length
L64              Use 64-bit Little-Endian format 'int' or 'size_t' as record length
trace            Enable I/O trace when program execution tracing is enabled
stats            Write I/O statistic information on file close
retry_times      Default number of times to retry I/O
retry_seconds    Number of seconds between I/O retry attempts
retry_forever    Retry I/O forever
retry_never      Never retry I/O operations
ignore_lock      Ignore record locks
advancing_lock   Advance to the next record if lock condition
share_all        Share file with ALL others
share_read       Share file for READ only
share_no         Share file with NO others

 ---- For INDEXED files -----
format=ixhandler INDEXED file format: CISAM,DISAM,VBISAM,BDB,LMDB
format=auto      INDEXED file format is determined by inspecting the file
nkeys=n          number of indexes
key1=(loc:len)   loc (zero relative) of key, len of key
key2=(loc:len,loc:len ...)
                 define composite index
dupn=Y           index allows dups

  ---- For INDEXED BDB files -----
big_endian       Set internal 'int' byte order to BIG ENDIAN
little_endian    Set internal 'int' byte order to LITTLE ENDIAN

10.2.4. Аргументы программы

Независимо от способа выполнения основной программы (т. е. непосредственно или через cobcrun), любые аргументы, указанные для программы, могут быть получены с помощью любого из следующего:

  • ACCEPT FROM COMMAND-LINE (см. ACCEPT FROM COMMAND-LINE)
  • PROCEDURE DIVISION CHAINING (см. PROCEDURE DIVISION CHAINING)

10.3. Обрезка двоичных данных

По умолчанию компилятор GnuCOBOL обрезает двоичные данные до точности, указанной в их PICTURE (см. PICTURE) фрагменте, если таковой имеется. Это относится только к элементам COMP, BINARY и COMP-4. Однако обрезка двоичных данных существенно влияет на производительность программ GnuCOBOL. При включенной обрезке двоичных данных операции арифметики, выполняемые над всеми типами числовых элементов данных (даже USAGE DISPLAY), замедляются.

Прежде чем продолжить, стоит отметить, что речь идёт не об астрономических снижениях производительности. Современные компьютеры очень быстрые, и пользователю, сидящему за клавиатурой и запускающему программу GnuCOBOL, вряд ли удастся это заметить. Однако, если у вас есть программа GnuCOBOL, которая должна обрабатывать большие объёмы данных, выполняя значительные вычисления над этими данными по мере продвижения, влияние обрезки может стать заметным.

Следующая программа сравнивает производительность выполнения арифметических операций (совершенно ненаучным и нестрогим способом) над элементами данных с USAGE (см. USAGE) DISPLAY, COMP и BINARY-LONG. На самом деле, когда я первоначально писал программу, я хотел просто продемонстрировать относительные различия в производительности между различными типами хранения числовых данных, и она, безусловно, выполнила эту цель.

IDENTIFICATION DIVISION.
PROGRAM-ID. DEMOMATH.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  Begin-Time.
    05 BT-HH                    PIC 9(2).
    05 BT-MM                    PIC 9(2).
    05 BT-SS                    PIC 9(2).
    05 BT-HU                    PIC 9(2).
01  Binary-Item         BINARY-LONG SIGNED VALUE 0.
01  Comp-Item           COMP    PIC S9(9)  VALUE 0.
01  Display-Item        DISPLAY PIC S9(9)  VALUE 0.
01  End-Time.
    05 ET-HH                    PIC 9(2).
    05 ET-MM                    PIC 9(2).
    05 ET-SS                    PIC 9(2).
    05 ET-HU                    PIC 9(2).
78  Repeat-Count                VALUE 10000000.
01  Time-Diff                   PIC ZZ9.99.
PROCEDURE DIVISION.
010-Test-Usage-DISPLAY.
    ACCEPT  Begin-Time FROM TIME
    PERFORM Repeat-Count TIMES
        ADD 7 TO Display-Item
    END-PERFORM
    PERFORM 100-Determine-Time-Diff
    DISPLAY 'USAGE DISPLAY: ' Time-Diff ' SECONDS'
    .
020-Test-Usage-COMP.
    ACCEPT Begin-Time FROM TIME
    PERFORM Repeat-Count TIMES
        ADD 7 TO Comp-Item
    END-PERFORM
    PERFORM 100-Determine-Time-Diff
    DISPLAY 'USAGE COMP:    ' Time-Diff ' SECONDS'
    .
040-Test-Usage-BINARY.
    ACCEPT Begin-Time FROM TIME
    PERFORM Repeat-Count TIMES
        ADD 7 TO Binary-Item
    END-PERFORM
    PERFORM 100-Determine-Time-Diff
    DISPLAY 'USAGE BINARY:  ' Time-Diff ' SECONDS'
    .
099-Done.
    STOP RUN
    .
100-Determine-Time-Diff.
    ACCEPT End-Time FROM TIME
    COMPUTE Time-Diff =
      ( (ET-HH * 360000 + ET-MM * 6000 + ET-SS * 100 + ET-HU)
      - (BT-HH * 360000 + BT-MM * 6000 + BT-SS * 100 + BT-HU) )
      / 100
    .

Каждое значение увеличивается на 7 десять миллионов раз.

Время (до сотых долей секунды) будет получено до и после каждого теста, а разница между двумя значениями будет отображена. Вот почему вычисления выполнялись так много раз — чтобы убедиться, что измерение времени было возможным только с «секундомером» в 1/100 секунды.

Я также выполнял тесты несколько раз, чтобы убедиться, что я получил последовательные результаты (я это сделал). Как я упоминал ранее, это не строгий научный эталон производительности чисел; это просто быстрое и грязное сравнение.

Вот результаты:

Test 1:
USAGE DISPLAY:   1.72 SECONDS
USAGE COMP:      0.62 SECONDS
USAGE BINARY:    0.02 SECONDS

Test 2:
USAGE DISPLAY:   1.69 SECONDS
USAGE COMP:      0.61 SECONDS
USAGE BINARY:    0.02 SECONDS

Test 3:
USAGE DISPLAY:   1.69 SECONDS
USAGE COMP:      0.65 SECONDS
USAGE BINARY:    0.02 SECONDS

Результаты, которые я увидел здесь, соответствовали результатам, которые можно было бы получить от большинства реализаций COBOL, с которыми я когда-либо работал — USAGE COMP имеет значительное преимущество в производительности по сравнению с USAGE DISPLAY и USAGE BINARY-LONG (и, предположительно, другие BINARY-xxx использования тоже) работают одинаково, в рамках допусков измерения теста.

Однако, к моему удивлению, я обнаружил, что использование переключателя -fnotrunc также повлияло на результат:

Test 4:
USAGE DISPLAY:   1.72 SECONDS
USAGE COMP:      0.07 SECONDS
USAGE BINARY:    0.02 SECONDS

Test 5:
USAGE DISPLAY:   1.72 SECONDS
USAGE COMP:      0.07 SECONDS
USAGE BINARY:    0.02 SECONDS

Test 6:
USAGE DISPLAY:   1.73 SECONDS
USAGE COMP:      0.06 SECONDS
USAGE BINARY:    0.02 SECONDS

Как вы можете видеть, время выполнения USAGE COMP значительно сократилось при отключении усечения. В результате я не вижу никаких оснований для того, чтобы переключатель -fnotrunc не использовался при всех компиляциях GnuCOBOL.

Если вы хотите извлечь максимальную производительность из своих программ GnuCOBOL, не забудьте изучить переключатель -O, переключатель -O2 и переключатель -Os, все из которых влияют на оптимизацию скомпилированного кода. Фактически запустите программы с различными переключателями оптимизации (или без них) и сравните время выполнения с временем выполнения несжатых скомпилированных версий ваших программ. Не ограничивайтесь сравнением сгенерированного кода C, так как иногда различия не видны на уровне исходного кода C.

Test 7:
cobc -x demomath.cbl -O2;demomath
USAGE DISPLAY:   1.68 SECONDS
USAGE COMP:      0.60 SECONDS
USAGE BINARY:    0.00 SECONDS

Test 8:
cobc -x demomath.cbl -fnotrunc -O2;demomath
USAGE DISPLAY:   1.67 SECONDS
USAGE COMP:      0.01 SECONDS
USAGE BINARY:    0.00 SECONDS

Все тесты выше проводились под Linux с процессором AMD FX8350 при очень низкой нагрузке перед запуском теста. Я также хотел бы попробовать на i7-7700, но это под Windows 10, и у меня нет версии GC на нём — Винс.

11. Подпрограммы

11.1. Типы подпрограмм

Проще говоря, подпрограмма — это программа, которая вызывается другой программой; подпрограмма выполняет свои заданные операции и — по завершении — обычно возвращает управление программе, которая её вызвала. GnuCOBOL поддерживает два разных типа подпрограмм: подпрограммы и пользовательские функции. Различие между этими двумя типами подпрограмм заключается в способе их выполнения.

Когда программа A вызывает подпрограмму B в качестве подпрограммы, она делает это с помощью специальной инструкции для этой функции (инструкция CALL (см. CALL), как если бы B была одной из встроенных системных подпрограмм.

Когда программа A вызывает программу B в качестве пользовательской функции, она делает это так же, как если бы B была одной из многих встроенных функций.

В обоих случаях программа A называется вызывающей программой, а программа B — вызываемой программой. Программы GnuCOBOL могут быть вызывающей программой, вызываемой программой или обеими.

Программа, написанная на языке программирования C, также может выполнять роль вызывающей или вызываемой программы. Вызываемая программа может действовать как вызывающая программа для другой вызываемой программы. Когда вызывающая программа не выполняет роль вызываемой программы для какой-либо программы, эта вызывающая программа называется главной программой.

Как подпрограммы, так и пользовательские функции могут возвращать значение. Возвращаемое значение должно быть целым числом в диапазоне от -2147483648 до +2147483647. Это значение будет доступно в специальном регистре RETURN-CODE (см. Специальные регистры), а также в качестве значения элемента данных, указанного в RETURNING (см. CALL) фрагменте подпрограммы CALL.

11.2. Независимые, вложенные и вложенные подпрограммы

Подпрограммы (будь то подпрограммы или пользовательские функции) могут быть реализованы тремя различными способами.

Независимые подпрограммы

Это подпрограммы, которые закодированы как единственная программа COBOL в их Компиляционной единице (см. Компиляционная единица).

Вложенные подпрограммы

Это подпрограммы, которые встречаются в той же Компиляционной единице, что и главная программа и/или другие подпрограммы. Каждая вложенная подпрограмма отделена от следующей с помощью маркера END PROGRAM. В качестве примера…

IDENTIFICATION DIVISION.
PROGRAM-ID. SUB1.
…
END PROGRAM SUB1.
IDENTIFICATION DIVISION.
PROGRAM-ID. SUB2.
…
END PROGRAM SUB2.

Исходный код программы может быть склеен, как показано здесь, при условии использования маркера END PROGRAM, называющего PROGRAM-ID только что завершённой программы, для разделения одной программы от другой.

Нет никаких причин, по которым пользовательские функции не могут быть включены — они просто будут иметь FUNCTION-ID и будут завершаться маркерами END FUNCTION.

Последней программе в любом исходном файле GnuCOBOL не нужен маркер END.

Когда в исходном файле присутствует несколько программ, предполагается, что программы связаны друг с другом, и они будут CALL или выполняться как функции из других.

Вложенные подпрограммы

Также возможно создавать исходные файлы, где программы GnuCOBOL вложены друг в друга. Возьмите, например, эти четыре программы GnuCOBOL:

IDENTIFICATION DIVISION.
PROGRAM-ID. PROG1.
…
IDENTIFICATION DIVISION.
PROGRAM-ID. PROG2.
…
IDENTIFICATION DIVISION.
PROGRAM-ID. PROG3.
…
END PROGRAM PROG3.
END PROGRAM PROG2.
IDENTIFICATION DIVISION.
PROGRAM-ID. PROG4.
…
END PROGRAM PROG4.
END PROGRAM PROG1.

Здесь мы видим, что PROG2 вложена в PROG1, потому что нет маркера END PROGRAM, разделяющего их. Это означает, что элементы данных или файлы, определённые в PROG1, могут использоваться в PROG2, просто добавив атрибут GLOBAL (см. GLOBAL) к ним обратно в PROG1 при их определении.

Аналогично, поскольку нет маркера END PROGRAM для разделения PROG3 от PROG2, PROG3 может получить доступ к файлам и элементам данных GLOBAL, определённым в PROG2. Так как PROG2 вложена в PROG1, все GLOBAL ресурсы, определённые в PROG1, также будут доступны PROG3.

Два маркера END PROGRAM для PROG3 и PROG2 (обратите внимание на их последовательность) означают, что PROG4 вложена только в PROG1. Она не будет иметь доступа к любым GLOBAL ресурсам, определённым в PROG2 или PROG3.

Маркер END PROGRAM PROG1., поскольку он является последней строкой в исходном файле, полностью необязателен.

11.3. Альтернативные точки входа

Любая подпрограмма может иметь несколько определённых в ней точек входа. Это означает, что к подпрограмме можно обратиться либо через инструкцию CALL 'program-id', либо через инструкцию CALL 'entry-point'. В подпрограмме может быть любое количество альтернативных точек входа.

Альтернативные точки входа обеспечивают несколько способов вызова одной и той же подпрограммы; предположительно, каждая точка входа будет обеспечивать некоторую различную функциональность вызывающей программе. Например, если вы хотите написать подпрограмму, которая обрабатывает записи «студентов» в базе данных, вы можете сделать так, чтобы основная точка входа получала запись студента из базы данных, а альтернативные точки входа Add-Student, Update-Student и Delete-Student могли бы предоставлять альтернативные функции, подразумеваемые их именами точек входа.

Альтернатива использованию нескольких точек входа в вашей подпрограмме — включение дополнительного аргумента в основную (и единственную) точку входа подпрограммы; этот новый аргумент может быть назван STUDENT-FUNCTION и может иметь значения ‘FETCH’, ‘ADD’, ‘UPDATE’ или ‘DELETE’.

Основная точка входа любой подпрограммы всегда является первой исполняемой инструкцией после любого DECLARATIVES (см. DECLARATIVES) в разделе процедур. Имя этой точки входа (то имя, которое будет вызываться) — это PROGRAM-ID подпрограммы (см. IDENTIFICATION DIVISION).

Альтернативная точка входа добавляется в подпрограмму с помощью инструкции ENTRY (см. ENTRY).

При вызове альтернативной точки входа выполнение внутри подпрограммы начнется с первой исполняемой инструкции, следующей за инструкцией ENTRY.

11.4. Динамические и статические подпрограммы

Любая подпрограмма может быть загружена в память статически или динамически.

Статическая подпрограмма — это подпрограмма, которая находилась в той же Компиляционной единице (см. Компиляционная единица) с другими программами, которые ее вызывают, что означает, что ее исполняемый объектный код является частью того же исполняемого файла, что и программа-вызывающая программа. Статическая подпрограмма была загружена в память как часть и одновременно с вызывающей программой.

Динамическая подпрограмма — это подпрограмма, исполняемый объектный код которой существует в отдельном исполняемом файле от файла, содержащего вызывающую программу; эти две программы были, следовательно, скомпилированы в своих собственных отдельных Компиляционных группах (см. Компиляционная группа). Динамические подпрограммы обнаруживаются и загружаются в память при первом выполнении. Динамические подпрограммы могут быть выгружены из памяти с помощью инструкции CANCEL (см. CANCEL), если это необходимо.

Подпрограммы GnuCOBOL могут быть созданы как статические или динамические подпрограммы по желанию программиста.

Для демонстрации предположим, что главная программа GnuCOBOL (код которой находится в файле M.cbl) будет вызывать три подпрограммы, названные A, B и C (это PROGRAM-ID этих трёх подпрограмм, а их исходный код можно найти в файлах A.cbl, B.cbl и C.cbl соответственно).

Вот как эти четыре программы будут компилироваться, если три подпрограммы будут статическими:

cobc -x M.cbl A.cbl B.cbl C.cbl

Эта команда сообщает компилятору (cobc), что необходимо скомпилировать четыре программы (первой в команде всегда должна быть главная программа), и создать один исполняемый файл (благодаря переключателю -x).

Вот как главную программу и три подпрограммы можно скомпилировать, если три подпрограммы будут динамическими:

cobc -x M.cbl
cobc -m A.cbl B.cbl C.cbl

Эти команды создадут исполняемый файл для главной программы (-x переключатель) и три отдельных динамически загружаемых библиотеки (см. переключатель -m), по одной для каждой из трёх подпрограмм. Если бы мы захотели, мы могли бы создать одну динамически загружаемую библиотеку, содержащую все три подпрограммы, добавив переключатель -b к их компиляции:

cobc -m -b A.cbl B.cbl C.cbl

Динамически загружаемые библиотеки также известны как динамически загружаемые модули. Эти два термина являются синонимами.

Вот правила работы с динамически загружаемыми модулями GnuCOBOL:

  1. В одной динамически загружаемой библиотеке может быть несколько подпрограмм GnuCOBOL, если используется переключатель -b в дополнение к -m. В противном случае каждая подпрограмма будет скомпилирована в отдельную динамически загружаемую библиотеку.
  2. Динамически загружаемые модули будут именоваться xxxxxxxx.dll в системе Windows, xxxxxxxx.so в системе Unix или xxxxxxxx.dylib в системе OSX, где xxxxxxxx точно соответствует, включая использование заглавных и строчных букв, имени основной точки входа (PROGRAM-ID или FUNCTION-ID) или имени альтернативной точки входа, определённой через инструкцию ENTRY (см. ENTRY) любой из программ GnuCOBOL, включённых в этот модуль.
  3. В первый раз, когда любая из подпрограмм GnuCOBOL в динамически загружаемом модуле вызывается, должна быть использована точка входа, для которой и был назван файл .dll, .so или .dylib.
  4. Когда необходимо загрузить динамически загружаемый модуль (поскольку он не находится в памяти из предыдущего выполнения подпрограммы), будет выполнен поиск динамически загружаемой библиотеки в той же директории, из которой была загружена главная программа. Если он не будет найден там, будет просмотрен каждый каталог, указанный в переменной среды выполнения PATH (см. Переменные среды выполнения). Если библиотека не будет найдена ни в одном из этих каталогов, будет выполнен поиск в каталоге, указанном в переменной среды выполнения COB_LIBRARY_PATH. И наконец, если он по-прежнему не будет найден, выполнение будет завершено с сообщением об ошибке (libcob: Невозможно найти модуль ’xxxxxxxx’).
  5. После успешной загрузки динамически загружаемого модуля, все точки входа, содержащиеся в нём, теперь доступны для обращения.
  6. Динамически загружаемые модули могут быть удалены из памяти с помощью инструкции CANCEL (см. CANCEL).
  7. После того, как динамически загружаемый модуль фактически загружен в память, даже если он позже выгружен (с помощью инструкции CANCEL), его список точек входа остаётся доступным для библиотеки выполнения GnuCOBOL, и последующие повторные выполнения этих точек входа смогут обойти поиск (правило #4), а также правило первого выполнения (правило #3).

Обратитесь к документации по переменной среды выполнения COB_PRE_LOAD, переменной среды выполнения COB_PHYSICAL_CANCEL и переменной среды выполнения COB_LOAD_CASE (см. Переменные среды выполнения) для получения дополнительных опций при использовании динамически загружаемых модулей.

11.5. Поток выполнения подпрограммы

Когда вызывается подпрограмма, порядок выполнения будет немного отличаться в зависимости от того, является ли подпрограмма подпрограммой-процедурой или пользовательской функцией.

11.5.1. Поток выполнения подпрограммы-процедуры

Когда вызывается подпрограмма-процедура:

  1. Вызывающая программа выполняет оператор вида CALL 'entry-point' USING ... для передачи управления подпрограмме.
  2. Исполняемый файл вызываемой программы будет найден и загружен в память:
    1. Если это статическая подпрограмма, она уже будет частью исполняемого файла, который выпустил CALL (см. CALL).
    2. Если это динамическая подпрограмма, система выполнения GnuCOBOL проверит, был ли уже найден динамически загружаемый модуль, содержащий точку входа подпрограммы. Если да, дальнейшие действия по поиску не требуются. Если нет, динамически загружаемый модуль будет найден (см. Поиск динамически загружаемых модулей).
    3. После того, как модуль был найден (если поиск был необходим), он будет загружен в память (если он ещё не загружен).
  3. Выполнение вызывающей программы приостанавливается, и управление передаётся вызываемой программе следующим образом:
    1. Если в разделе PROGRAM-ID (см. РАЗДЕЛ ИДЕНТИФИКАЦИИ) подпрограммы был включён раздел INITIAL, программа будет перезапущена до состояния во время компиляции. Это произойдёт независимо от раздела INITIAL при первом выполнении подпрограммы.
    2. Если необходимо, будет выделена и инициализирована локальная память.
    3. Выполнение начнётся с первой исполняемой команды после точки входа подпрограммы. Точка входа будет либо первой исполняемой командой после любого раздела DECLARATIVES (см. ДЕКЛАРАТИВЫ), который может присутствовать (если подпрограмма вызвана по имени основного входа), либо первой исполняемой командой после оператора ENTRY (см. ENTRY), называющего точку входа, указанную в CALL , если подпрограмма вызвана через альтернативную точку входа.
  4. Затем поток выполнения будет проходить через код подпрограммы, как и в любом другом программном коде.
  5. Если подпрограмма выполняет оператор STOP (см. STOP) с параметром RUN, выполнение программы прекращается, и управление возвращается операционной системе или оболочке, вызвавшей основную программу.
  6. Если подпрограмма хочет вернуть управление вызывающей программе, она сделает это с помощью оператора GOBACK (см. GOBACK) или оператора EXIT PROGRAM (см. EXIT). В этот момент:
    1. Если в заголовке процедурного раздела подпрограммы или в операторе ENTRY был раздел RETURNING, значение элемента данных, найденного в этом разделе, перемещается в специальный регистр RETURN-CODE (см. Специальные регистры); это поведение можно изменить, используя функцию CALL-CONVENTION (см. SPECIAL-NAMES), чтобы оставить RETURN-CODE неизменным.
    2. Локальная память, если таковая имеется, освобождается.
    3. Если вызывающая программа включала раздел RETURNING в операторе CALL , вызвавшем подпрограмму, значение элемента данных RETURNING в подпрограмме перемещается в этот элемент данных. Если в подпрограмме не было указано RETURNING, значение специального регистра RETURN-CODE перемещается в этот элемент данных.
    4. Выполнение возобновляется в вызывающей программе с первой исполняемой команды после оператора CALL , вызвавшего подпрограмму.

11.5.2. Поток выполнения пользовательской функции

При выполнении пользовательской функции:

  1. Код объекта вызываемой программы (пользовательской функции) будет расположен следующим образом:
    1. Если это статическая пользовательская функция, она уже будет частью исполняемого файла, содержащего вызывающую программу.
    2. Если это динамическая пользовательская функция, система выполнения GnuCOBOL проверит, не был ли уже найден модуль динамической загрузки, содержащий точку входа функции. Если был, дальнейшие действия по «поиску» не требуются. Если нет, модуль динамической загрузки будет найден (см. Поиск модулей динамической загрузки).
    3. После того, как модуль будет найден (если поиск был необходим), он будет загружен в память (если он ещё не загружен).
  2. Выполнение вызывающей программы приостанавливается, и управление передаётся вызываемой программе следующим образом:
    1. Если необходимо, будет выделена и инициализирована локальная память.
    2. Выполнение начнется с первой исполняемой инструкции в разделе процедур после любых DECLARATIVES (см. ДЕКЛАРАТИВЫ), которые могут быть присутствовать.
  3. Затем поток выполнения будет продвигаться через код функции, как это происходит с любой другой программой.
  4. Если функция выполняет инструкцию STOP (см. STOP) с параметром RUN, выполнение программы завершается, и управление возвращается операционной системе или оболочке выполнения, которая вызвала главную программу.
  5. Если функция хочет вернуть управление вызывающей программе, она сделает это с помощью инструкции GOBACK (см. GOBACK) или инструкции EXIT FUNCTION (см. EXIT). В этот момент:
    1. Значение данных, найденных в пункте PROCEDURE DIVISION RETURNING (см. PROCEDURE DIVISION RETURNING) пользовательской функции, перемещается в специальный регистр RETURN-CODE (см. Специальные регистры).
    2. Если необходимо, локальная память дезаллицируется.
    3. Выполнение возобновится в вызывающей программе в той точке, где требуется возвращаемое значение функции. В этот момент значение в специальном регистре RETURN-CODE будет использоваться для значения функции.

11.6. Обмен данными между вызывающей и вызываемой программами

11.6.1. Аргументы подпрограммы

11.6.1.1. Соображения вызывающей программы

Элементы данных, определенные в вызывающей программе, могут передаваться в вызываемую программу (подпрограмму или пользовательскую функцию) в качестве аргументов.

Аргументы должны быть описаны как в вызывающей, так и в вызываемой программе, и, хотя им не нужно иметь одинаковые имена в обеих программах, они должны быть описаны одинаковым образом по следующим характеристикам:

  • PICTURE (см. PICTURE) (включая тип и длину)
  • SIGN (см. SIGN)
  • SYNCRONIZED (см. SYNCRONIZED)
  • USAGE (см. USAGE)

Подпрограмме может быть передано не более 251 аргумента; если вы сами собираете программное обеспечение GnuCOBOL из исходного кода, вы можете изменить это значение, изменив определенное значение COB_MAX_FIELD_PARAMS в заголовочном файле call.h, но также см. 7.8.5.11 для получения дополнительной информации. В GnuCOBOL нет встроенного ограничения на то, сколько аргументов может быть передано пользовательской функции.

Влияние изменений, внесенных в аргумент внутри подпрограммы, на вызывающую программу зависит от того, как был передан аргумент. Существует три способа передачи аргументов из вызывающей программы в подпрограмму, определенные с использованием необязательных BY-клауз в списке аргументов инструкции CALL (см. CALL).

Например, следующая инструкция передает три аргумента подпрограмме — каждый аргумент передается по-разному.

CALL "subroutine" USING BY REFERENCE arg-1
                        BY CONTENT arg-2
                        BY VALUE arg-3
END-CALL

Три способа передачи аргументов следующие.

BY REFERENCE

При передаче аргумента подпрограмме BY REFERENCE, подпрограмме передаётся адрес фактического элемента данных, передаваемого в качестве аргумента. Элемент может быть любым элементом, определённым в разделе данных программы. Если подпрограмма изменяет содержимое этого аргумента, вызывающая программа увидит результаты этого изменения при возвращении управления от подпрограммы. Это стандартный способ передачи аргументов подпрограмме в GnuCOBOL, если не включены BY пункты в CALL.

BY CONTENT

При передаче аргумента подпрограмме BY CONTENT, подпрограмме передаётся адрес копии фактических данных, передаваемых в качестве аргумента. Элемент может быть любым элементом, определённым в разделе данных программы. Копия создаётся каждый раз при выполнении CALL инструкции, сразу перед CALL. Если подпрограмма изменяет содержимое этого аргумента, изменяется именно копия, а не исходный элемент данных; поэтому вызывающая программа не увидит результатов этого изменения при возвращении управления от подпрограммы.

BY VALUE

Передача аргумента подпрограмме BY VALUE передаёт фактическое значение передаваемых данных в качестве аргумента. Элемент может быть любым элементарным бинарным числовым элементом, определённым в разделе данных программы. Если подпрограмма изменяет содержимое этого аргумента, вызывающая программа не увидит результатов этого изменения при возвращении управления от подпрограммы.

Два первых способа передачи аргументов (BY REFERENCE и BY CONTENT) предназначены для использования при вызове программы GnuCOBOL, а первый и третий (BY REFERENCE и BY VALUE) – для вызова программы C. Вы можете использовать аргументы BY VALUE, вызывая подпрограммы GnuCOBOL, но помните, что эти аргументы ограничены числовыми бинарными элементами данных.

Аргументы пользовательских функций всегда передаются BY REFERENCE.

11.6.1.2. Соображения по вызываемой программе

При написании подпрограммы GnuCOBOL (подпрограммы или пользовательской функции) все аргументы подпрограммы должны быть определены в разделе связи подпрограммы.

Эти аргументы должны быть явно включены в PROCEDURE DIVISION USING (см. PROCEDURE DIVISION USING) пункт, перечисляющий аргументы в том порядке, в котором они будут переданы подпрограмме.

Эти аргументы, описанные в PROCEDURE DIVISION USING пункте, могут быть определены как BY REFERENCE, если вызывающая программа передаёт их либо BY REFERENCE, либо BY CONTENT, или как BY VALUE, если они передаются BY VALUE.

По умолчанию все аргументы предполагаются BY REFERENCE, если явно не указано иное в заголовке раздела PROCEDURE DIVISION.

Аргументы пользовательской функции всегда должны быть указаны как BY REFERENCE (явно или путём отсутствия BY).

Если подпрограмма возвращает значение, элемент данных, в котором возвращается значение, также должен быть определён в разделе связи подпрограммы, с USAGE (см. USAGE) BINARY-LONG SIGNED, или его эквивалентом.

11.6.2. Глобальные элементы данных

Ещё один способ обмена элементом данных между вызывающей программой (A) и вызываемой программой (B) – определить элемент данных в вызывающей программе и добавить к нему GLOBAL (см. GLOBAL) пункт, чтобы он мог использоваться в вызываемой программе. Для этого программа B (вызываемая программой A) должна быть вложенной подпрограммой внутри программы A.

Вот небольшой пример:

IDENTIFICATION DIVISION.
PROGRAM-ID. DemoGLOBAL.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  Arg GLOBAL                     PIC X(10).
PROCEDURE DIVISION.
000-Main.
    MOVE ALL "X" TO Arg
    CALL "DemoSub" END-CALL
    DISPLAY "DemoGLOBAL: " Arg END-DISPLAY
    GOBACK
    .
IDENTIFICATION DIVISION.
PROGRAM-ID. DemoSub.
PROCEDURE DIVISION.
000-Main.
    MOVE ALL "*" TO Arg.
    GOBACK
    .
END PROGRAM DemoSub.
END PROGRAM DemoGLOBAL.

При выполнении программы выводится результат:

DemoGLOBAL: **********

11.6.3. Внешние элементы данных

Последний способ обмена элементом данных между вызывающей программой (A) и вызываемой программой (B) – определить элемент данных (с тем же именем) в обеих программах и добавить к нему EXTERNAL (см. EXTERNAL) пункт (снова, в обеих программах). Этот подход работает независимо от того, вложена ли вызываемая программа в вызывающую программу или нет. Он также работает, даже если две программы скомпилированы отдельно.

Демонстрация:

IDENTIFICATION DIVISION.
PROGRAM-ID. DemoEXTERNAL.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  Arg EXTERNAL                PIC X(10).
PROCEDURE DIVISION.
000-Main.
    MOVE ALL "X" TO Arg
    CALL "DemoSub" END-CALL
    DISPLAY "DemoEXTERNAL: " Arg END-DISPLAY
    GOBACK
    .
END PROGRAM DemoEXTERNAL.
IDENTIFICATION DIVISION.
PROGRAM-ID. DemoSub.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  Arg EXTERNAL                PIC X(10).
PROCEDURE DIVISION.
000-Main.
    MOVE ALL "*" TO Arg.
    GOBACK
    .
END PROGRAM DemoSub.

При выполнении программы выводится результат:

DemoEXTERNAL: **********

11.7. Рекурсивные подпрограммы

Подпрограмма может CALL себя, напрямую или косвенно из другой подпрограммы или пользовательской функции, которую она CALL. Любая подпрограмма, использующая подобное поведение (называемое рекурсией), называется Рекурсивной подпрограммой.

Любая подпрограмма GnuCOBOL может быть рекурсивно вызвана только в том случае, если она определена для компилятора GnuCOBOL как рекурсивная подпрограмма. Это достигается добавлением атрибута RECURSIVE к её PROGRAM-ID (см. IDENTIFICATION DIVISION).

Все пользовательские функции автоматически способны к рекурсивному выполнению.

END_OF_DOCUMENT_MARKER

Вот пример основной программы (DEMOFACT), которая вызывает как подпрограмму (SUB), так и пользовательскую функцию (FUNC) для вычисления факториала числа.

IDENTIFICATION DIVISION.
PROGRAM-ID. DEMOFACT.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
    FUNCTION RECURSIVEFUNC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  Result    USAGE BINARY-LONG.
01  Arg       USAGE BINARY-LONG.
PROCEDURE DIVISION.
000-Main.
    MOVE 6 TO Arg
    CALL "RECURSIVESUB"
        USING BY CONTENT Arg
        RETURNING Result
    DISPLAY Arg "! = "
            Result
    DISPLAY Arg "! = "
            RECURSIVEFUNC(Arg)
    GOBACK
    .
END PROGRAM DEMOFACT.
IDENTIFICATION DIVISION.
PROGRAM-ID. SUB RECURSIVE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  Result      USAGE BINARY-LONG.
01  Next-Arg    USAGE BINARY-LONG.
01  Next-Result USAGE BINARY-LONG.
LINKAGE SECTION.
01  Arg         USAGE BINARY-LONG.
PROCEDURE DIVISION USING Arg
               RETURNING Result.
000-Main.
    DISPLAY "Entering SUB"
            " Arg=" Arg
    IF Arg = 1
      MOVE 1 TO Result
      DISPLAY "Leaving SUB"
              " Returning " Result
    ELSE
      SUBTRACT 1 FROM Arg
          GIVING Next-Arg
      CALL "SUB"
           USING BY CONTENT Next-Arg
           RETURNING Next-Result
      COMPUTE Result =
              Arg * Next-Result
      DISPLAY "Leaving SUB"
              " Returning "
              Result "=" Arg "*"
              Next-Result
    END-IF
    GOBACK
    .
END PROGRAM SUB.
IDENTIFICATION DIVISION.
FUNCTION-ID. FUNC.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
    FUNCTION RECURSIVEFUNC.
DATA DIVISION.
WORKING-STORAGE SECTION.
LINKAGE SECTION.
01  Arg     USAGE BINARY-LONG.
01  Result  USAGE BINARY-LONG
            SIGNED.
PROCEDURE DIVISION USING Arg
               RETURNING Result.
000-Main.
    DISPLAY "Entering FUNC"
            " Arg=" Arg
    IF Arg = 1
      MOVE 1 TO Result
    ELSE
      COMPUTE Result = Arg *
              FUNC(Arg - 1)
    END-IF
    DISPLAY "Leaving FUNC"
            " Returning " Result
    GOBACK
    .
END FUNCTION FUNC.

При выполнении DEMOFACT генерируется вывод, показанный ниже.

E:\Programs\Demos>demofact
Entering RECURSIVESUB Arg=+0000000006
Entering RECURSIVESUB Arg=+0000000005
Entering RECURSIVESUB Arg=+0000000004
Entering RECURSIVESUB Arg=+0000000003
Entering RECURSIVESUB Arg=+0000000002
Entering RECURSIVESUB Arg=+0000000001
Leaving RECURSIVESUB Returning +0000000001
Leaving RECURSIVESUB Returning +0000000002=+0000000002*+0000000001
Leaving RECURSIVESUB Returning +0000000006=+0000000003*+0000000002
Leaving RECURSIVESUB Returning +0000000024=+0000000004*+0000000006
Leaving RECURSIVESUB Returning +0000000120=+0000000005*+0000000024
Leaving RECURSIVESUB Returning +0000000720=+0000000006*+0000000120
+0000000006! = +0000000720
Entering RECURSIVEFUNC Arg=+0000000006
Entering RECURSIVEFUNC Arg=+0000000005
Entering RECURSIVEFUNC Arg=+0000000004
Entering RECURSIVEFUNC Arg=+0000000003
Entering RECURSIVEFUNC Arg=+0000000002
Entering RECURSIVEFUNC Arg=+0000000001
Leaving RECURSIVEFUNC Returning +0000000001
Leaving RECURSIVEFUNC Returning +0000000002
Leaving RECURSIVEFUNC Returning +0000000006
Leaving RECURSIVEFUNC Returning +0000000024
Leaving RECURSIVEFUNC Returning +0000000120
Leaving RECURSIVEFUNC Returning +0000000720
+0000000006! = +0000000720

11.8. Объединение программ GnuCOBOL и C

Следующие разделы рассматривают вопросы, связанные с вызовом программ на языке C из программ GnuCOBOL и наоборот. Два дополнительных раздела содержат примеры, иллюстрирующие, как эти проблемы решаются в реальном коде программы.

11.8.1. Требования к библиотеке времени выполнения GnuCOBOL

Как и большинство других реализаций языка COBOL, GnuCOBOL использует библиотеку времени выполнения. Когда первой программой, выполняемой в заданной последовательности, является программа GnuCOBOL, любая инициализация библиотеки времени выполнения будет выполнена скомпилированным кодом COBOL таким образом, что программист, работающий с языком C, этого не заметит. Однако, если первой выполняется программа C, ответственность за выполнение инициализации библиотеки времени выполнения GnuCOBOL ложится на программу C. См. C-Главные программы, вызывающие подпрограммы GnuCOBOL для примера того, как это сделать.

11.8.2. Различия в выделении памяти для строк между GnuCOBOL и C

Оба языка хранят строки как непрерывную последовательность символов фиксированной длины.

COBOL хранит эти последовательности символов до определенного лимита, накладываемого клаузой PICTURE (см. PICTURE) элемента данных. Например: 01 LastName PIC X(15)..

Никогда не возникает проблемы с точной длиной строки, содержащейся в элементе данных USAGE DISPLAY (см. USAGE) — всегда есть ровно столько символов, сколько разрешено клаузой PICTURE. В примере выше LastName всегда будет содержать ровно пятнадцать символов; конечно, может быть от 0 до 15 хвостовых пробелов (SPACES) в качестве части текущего значения LastName.

В языке C нет типа данных «строка»; он хранит строки как массив элементов типа char данных, где каждый элемент массива — отдельный символ. Будучи массивом, существует верхний предел количества символов, которые могут быть сохранены в данной «строке». Например:

char lastName[15]; /* 15 chars: lastName[0] through lastName[14] */

C предоставляет набор функций для работы со строками, чтобы копировать строки из одного массива char в другой, искать в строках определенные символы, сравнивать один массив char с другим, конкатенировать массивы char и так далее. Для возможности этих функций необходимо было определить логический конец строки. C достигает этого, ожидая, что все строки (массивы char) будут завершаться нулевым символом (x'00'). Конечно, никто не заставляет программиста делать это, но если он/она хочет использовать стандартные функции C для работы со строкой, то лучше завершать строки нулевым символом!

Таким образом, программисты GnuCOBOL, ожидающие передачи строк в программы C или получения строк из них, должны быть готовы к проблеме завершения нулем, следующим образом:

  1. Передавать строковую литерал из GnuCOBOL в C как строковую литерал с нулевым разделителем (Z'string').
  2. Передавать символьные (PIC X) или буквенные (PIC A) элементы данных подпрограммам C, добавляя символ ASCII NUL (X'00') к ним. Например, чтобы передать элемент данных LastName (15 символов) описанный выше, подпрограмме C:
    01  LastName-Arg-to-C     PIC X(16).
    ...
        MOVE FUNCTION CONCATENATE(LastName,X'00') TO LastName-Arg-to-C
    

    А затем передать LastName-Arg-to-C в подпрограмму C!

  3. Когда программе COBOL требуется обработать данные строки, подготовленные программой C, необходимо учитывать вложенный нулевой символ. Это легко достигается с помощью инструкции INSPECT (см. INSPECT), например, следующей:
    INSPECT Data-From-a-C-Program
        REPLACING FIRST X'00' BY SPACE
                  CHARACTERS BY SPACE AFTER INITIAL X'00'
    

11.8.3. Сопоставление типов данных C с типами USAGE GnuCOBOL

Сопоставление числовых типов USAGE GnuCOBOL с эквивалентами типов данных языка C возможно с помощью следующей таблицы:

COBOL C
BINARY-CHAR UNSIGNED unsigned char
BINARY-CHAR [ SIGNED ] signed char
BINARY-SHORT UNSIGNED unsigned unsigned int unsigned short unsigned short int
BINARY-SHORT [ SIGNED ] int short short int signed int signed short signed short int
BINARY-LONG UNSIGNED unsigned long unsigned long int
BINARY-LONG [ SIGNED ] BINARY-INT long long int signed long signed long int
BINARY-C-LONG [ SIGNED ] long
BINARY-DOUBLE UNSIGNED unsigned long long unsigned long long int
BINARY-DOUBLE [ SIGNED ] BINARY-LONG-LONG long long int signed long long int
COMPUTATIONAL-1 float
COMPUTATIONAL-2 double
N/A (no GnuCOBOL equivalent) long double

Эти размеры соответствуют стандарту COBOL, и минимальные размеры типов COBOL такие же, как и минимальные размеры соответствующих типов данных C. Официальной совместимости между ними нет. Обратите внимание, что значения в квадратных скобках ’[]’ являются значениями по умолчанию.

11.8.4. Основные программы GnuCOBOL, вызывающие подпрограммы C

Вот пример программы GnuCOBOL, вызывающей подпрограмму C.

COBOL Calling Program               C Called Program
==================================  ===============================
IDENTIFICATION DIVISION.            #include <stdio.h>
PROGRAM-ID. maincob.                int subc(char *arg1,
DATA DIVISION.                               char *arg2,
WORKING-STORAGE SECTION.                     unsigned long *arg3) {
01  Arg1     PIC X(7).                char nu1[7]="New1";
01  Arg2     PIC X(7).                char nu2[7]="New2";
01  Arg3     USAGE BINARY-LONG.       printf("Starting subc\n");
PROCEDURE DIVISION.                   printf("Arg1=%s\n",arg1);
000-Main.                             printf("Arg2=%s\n",arg2);
    DISPLAY 'Starting maincob'        printf("Arg3=%d\n",*arg3);
    MOVE Z'Arg1'   TO Arg1            arg1[0]='X';
    MOVE Z'Arg2'   TO Arg2            arg2[0]='Y';
    MOVE 123456789 TO Arg3            *arg3=987654321;
    CALL 'subc'                       return 2;
        USING BY CONTENT   Arg1,    }
              BY REFERENCE Arg2,
              BY REFERENCE Arg3
    DISPLAY 'Back'
    DISPLAY 'Arg1=' Arg1
    DISPLAY 'Arg2=' Arg2
    DISPLAY 'Arg3=' Arg3
    DISPLAY 'Returned value='
            RETURN-CODE
    STOP RUN
    .

Идея заключается в том, чтобы передать две строковые и одно целое беззнаковое значение в подпрограмму, позволить подпрограмме вывести их, изменить все три и вернуть код возврата 2 вызывающей программе. Затем вызывающая программа повторно отобразит три аргумента (показывая изменения только для двух BY REFERENCE аргументов), отобразит код возврата и завершит работу.

Несмотря на простоту, эти две программы довольно хорошо иллюстрируют требуемые техники.

Обратите внимание, как программа COBOL гарантирует, что на обоих строковых аргументах присутствует нулевой терминатор строки.

Поскольку программа C планирует внести изменения во все три аргумента, она объявляет все три аргумента как указатели в заголовке функции и ссылается на третий аргумент как на указатель в теле функции. На самом деле у нее не было выбора для двух строковых аргументов (массивов символов) — они должны быть определены как указатели в функции, даже если код функции ссылается на них без ведущего ‘*’, который обычно указывает на указатели.

Эти программы компилируются и выполняются следующим образом.

$ cobc -x maincob.cbl subc.c
$ maincob
Starting maincob
Starting subc
Arg1=Arg1
Arg2=Arg2
Arg3=123456789
Back
Arg1=Arg1
Arg2=Yrg2
Arg3=+0987654321
Returned value=+000000002
$

Помните, что нулевые символы фактически находятся в элементах данных GnuCOBOL Arg1 и Arg2. Они не отображаются в выводе, но они там есть.

Вы заметили вывод, показывающий содержимое Arg1 после вызова подпрограммы? Это содержимое не изменилось! Подпрограмма определенно изменила этот аргумент, но поскольку программа COBOL передала этот аргумент BY CONTENT, изменение было внесено в копию аргумента, а не в сам Arg1 элемент данных.

11.8.5. C-программы, вызывающие подпрограммы GnuCOBOL

Теперь роли двух языков в предыдущем разделе будут перевёрнуты, и C-программа будет запускать подпрограмму GnuCOBOL.

C Calling Program                              GNU-COBOL Called Program
=============================================  =================================
#include <libcob.h> /* COB RUN-TIME */         IDENTIFICATION DIVISION.
#include <stdio.h>                             PROGRAM-ID. subcob.
int main (int argc, char **argv) {             DATA DIVISION.
   int returnCode;                             LINKAGE SECTION.
   char arg1[7] = "Arg1";                      01  Arg1      PIC X(7).
   char arg2[7] = "Arg2";                      01  Arg2      PIC X(7).
   unsigned long arg3 = 123456789;             01  Arg3      USAGE BINARY-LONG.
   printf("Starting mainc...\n");              PROCEDURE DIVISION USING
   cob_init (argc, argv); /* COB RUN-TIME */       BY VALUE     Arg1,
   returnCode = subcob(arg1,arg2,&arg3);           BY REFERENCE Arg2,
   printf("Back\n");                               BY REFERENCE Arg3.
   printf("Arg1=%s\n",arg1);                   000-Main.
   printf("Arg2=%s\n",arg2);                       DISPLAY 'Starting cobsub.cbl'
   printf("Arg3=%d\n",arg3);                       DISPLAY 'Arg1=' Arg1
   printf("Returned value=%d\n",returnCode);       DISPLAY 'Arg2=' Arg2
   return returnCode;                              DISPLAY 'Arg3=' Arg3
}                                                  MOVE 'X' TO Arg1 (1:1)
                                                   MOVE 'Y' TO Arg2 (1:1)
                                                   MOVE 987654321 TO Arg3
                                                   MOVE 2 TO RETURN-CODE
                                                   GOBACK
                                                   .

Поскольку C-программа будет выполняться первой, перед подпрограммой GnuCOBOL, бремя инициализации среды выполнения GnuCOBOL ложится на эту C-программу; ей потребуется вызвать функцию cob_init, которая является частью библиотеки libcob. Две требуемые C-строки показаны выделенными.

Аргументы для процедуры cob_init — это параметры количества и значения аргументов, переданные в главную функцию при запуске программы. Передав их в подпрограмму GnuCOBOL, эта программа GnuCOBOL сможет получить командную строку или отдельные аргументы командной строки. Если это не потребуется, можно указать cob_init(0,NULL);.

Поскольку C-программа хочет разрешить arg3 быть изменённым подпрограммой, она предваряет его символом ‘&’ для принудительной передачи CALL BY REFERENCE для этого аргумента. Поскольку arg1 и arg2 являются строками (массивами символов), они автоматически передаются по ссылке.

Вот вывод процесса компиляции, а также выполнения программы. Пример предполагает систему Windows с сборкой GnuCOBOL, которая использует GNU C-компилятор на этой системе; этот метод работает одинаково хорошо независимо от того, какой C-компилятор и какую операционную систему вы используете.

C:\Users\Gary\Documents\Programs> cobc -S subcob.cbl
C:\Users\Gary\Documents\Programs> gcc mainc.c subcob.s -o mainc.exe -llibcob
C:\Users\Gary\Documents\Programs> mainc.exe
Starting mainc...
Starting cobsub.cbl
Arg1=Arg1
Arg2=Arg2
Arg3=+0123456789
Back
Arg1=Xrg1
Arg2=Yrg2
Arg3=987654321
Returned value=2
C:\Users\Gary\Documents\Programs>

Обратите внимание, что хотя мы сказали GnuCOBOL, что первый аргумент должен быть BY VALUE, он обрабатывался так, как будто он был BY REFERENCE . Строковые аргументы (массивы символов), переданные от вызывающих C-подпрограмм к подпрограммам GnuCOBOL, будут изменяемы подпрограммой. Лучше передавать копию таких данных, если вы хотите гарантировать, что подпрограмма их не изменит.

Однако третий аргумент отличается. Поскольку это не массив, у вас есть выбор передать его либо BY REFERENCE или BY VALUE.

12. Рекомендации по стилю программирования

В этой главе рассматриваются различные стилистические вопросы, которые могут быть интересны начинающим программистам COBOL. Большая часть главы содержит рекомендации и советы по написанию собственных программ. Примеры программ в документе Примеры программ (см. Верх в Примеры программ) были написаны почти во всех этих рекомендациях.

Представленные здесь темы не имеют определенного порядка важности.

12.1. Отмечание изменений в программах

Исторически, в начале 60-х годов программы сначала печатались на перфоленте, а к середине 60-х годов это было почти полностью заменено перфокартами, хотя перфоленты по-прежнему использовались программистами для редких изменений в исходных кодах, хранящихся на магнитной ленте или диске, так как портативный перфоратор перфолент можно было носить с собой в кармане. Теперь проблема с перфокартами заключалась в том, что в одной коробке было 2000 карт, и их можно было и, на самом деле, роняли. Поэтому в колонках с 1 по 6 (cc) указывался номер последовательности карты, и таким образом, если коробка падала, карты можно было подавать в сортировщик карт для исправления. Это происходило после очистки карт, чтобы все они были в одном направлении, что помогало вырезать один угол.

В конце 70-х годов перфокарты также начали отходить на второй план, в то время как начали использоваться персональные компьютеры (и нет, они не были произведены компанией IBM), поэтому эти колонки могли быть использованы для других целей, в том числе колонки с 73 по 80 вместо указания 8-символьного имени программы, которое было максимальным размером, разрешенным в системе IBM.

Уже довольно долго (с конца 1970-х годов) область номера последовательности оператора COBOL (колонки 1-6) используется как область индикатора изменений. Программисты помещали код в колонки 1-6 каждой строки, которую они изменяли в программе. Автор работает в компании, использующей COBOL, где индикаторы изменений вида «xxmmyy» требуются для каждой изменённой строки программы — «xx» это инициалы программиста, а «mmyy» — месяц и двузначный год даты внесения изменения. К этому часто добавляется блок комментариев в начале или около начала программы COBOL, содержащий общие сведения о внесенных изменениях и используемом индикаторе изменений для маркировки этого изменения.

Пример исходного кода программы GCic (см. GCic в Примерах программ GnuCOBOL) является отличным примером такой документации.

Этот метод использования колонок 1-6 в качестве индикатора изменений будет только работать, если установлен фиксированный формат записи исходного кода.

Некоторые компании, использующие COBOL, предпочитают использовать восьмисимвольную область имени программы (колонки 73-80) как область кода изменений.

Отметка изменений становится более сложной, когда используется свободный формат исходного кода. Создание блока комментариев в начале программы для общего описания внесенных изменений не сложно, даже в свободном формате. Однако сложно придумать схему для пометки изменений по операторам, которая не приведет к чрезмерному увеличению количества строк в программе. Я не уверен, что есть хорошее решение этой проблемы (если у читателя есть, пожалуйста, сообщите мне). Как правило, я заметил, что компании, использующие свободные соглашения для своего исходного кода COBOL, придерживаются только блока комментариев в начале программы в сочетании с минимальными блоками комментариев, разбросанными по всей программе, отмечая области, которые претерпели значительные изменения.

12.2. Кодирование и правила именования данных

Когда программы становятся очень большими, становится все сложнее отслеживать данные, которые будут использоваться в программе. Здесь, в произвольном порядке важности, представлены различные соглашения, которые могут упростить эту задачу.

Помните, что описанные здесь пункты предназначены для того, чтобы облегчить работу вам, программистам. Ни один компилятор COBOL не обращает внимания на то, следуете ли вы этим рекомендациям.

  1. Избегайте использования элементов данных уровня 77 в новых программах. Когда-то (в 1968 году и ранее) существовали веские причины для создания элементов данных уровня 77, но с момента стандарта ANSI COBOL 1974 года не было никаких оснований для использования элемента данных уровня 77 вместо элемента данных уровня 01.
  2. Размещайте элементы данных уровня 01 в алфавитном порядке в исходном коде программы, где это практично. Это значительно упростит поиск определений элементов уровня 01 в исходном коде программы без необходимости обращения к списку перекрестных ссылок компиляции и/или команде «найти» текстового редактора для их поиска.
  3. Рассмотрите возможность добавления префикса к элементам данных, указывающего на место их создания в структуре программы. Например:
    • Все, определенное в разделе файла, начинайте с «F-»
    • Все, определенное в рабочей памяти, начинайте с «WS-»
    • Все, определенное в локальном хранилище, начинайте с «LS-»
    • Все, определенное в разделе связи, начинайте с «L-»
    • Все, определенное в разделе экрана, начинайте с «S-»
    • Все, определенное в разделе отчета, начинайте с «R-»

    Такая конвенция упрощает, когда вы просматриваете код в разделе процедур, определить, в каком разделе раздела данных следует искать подробное описание элемента данных. После того, как вы окажетесь в нужном разделе, конвенция кодирования №2 поможет в поиске определения элемента данных.

  4. Рассмотрите возможность включения заключительного описателя характера всех элементов данных в их именах. Следующая таблица содержит различные описатели, с которыми автор сталкивался и использовал на протяжении многих лет.
    -ADDR

    Элемент данных содержит все или часть адреса (City-ADDR, State-ADDR, Street-ADDR, …)

    -BOOL

    Элемент данных уровня 88 (который имеет только значение TRUE или FALSE)

    -CD

    Код, значение которого обозначает информацию, содержащуюся сверх простого значения. Некоторые примеры могут быть Error-CD, Status-CD, Billing-CD

    -CHR

    Элемент данных, содержащий один символ данных.

    -CONST

    Константа, заданная как элемент данных уровня 78, элемент уровня 01 с атрибутом CONST

    -DT

    Элемент данных содержит полную или частичную дату (Birth-DT, Birth-Month-DT, Birth-Year-DT, …)

    -DTTM

    Элемент данных, содержащий как дату, так и время

    -FILE

    Имя файла. Обратите внимание, что эти элементы, вероятно, также будут иметь префикс «F-».

    -IDX

    Элемент данных, используемый в качестве индекса таблицы (см. раздел 12.3)

    -NM

    Все или часть имени человека. Они могут быть расширены, чтобы включать имена компаний, имена продуктов и т. д.

    -PTR

    Элемент данных, у которого USAGE равно POINTER

    -NUM

    Общий числовой элемент данных, который не подходит ни под одну из других категорий

    -QTY

    Подсчёт чего-либо

    -REC

    Элемент уровня 01, определенный в FILE SECTION (составляющий структуру записи внутри файла). Обратите внимание, что эти элементы, вероятно, также будут иметь префикс «F-».

    -SCR

    Элемент данных содержит полное или частичное описание экрана (подходящее для элементов данных уровня 01 в разделе SCREEN SECTION).

    -SUB

    Числовой элемент, используемый в качестве индекса таблицы (см. раздел 12.3)

    -TEL

    Все или часть телефонного номера

    -TM

    Элемент данных содержит полное или частичное значение времени

    -TXT

    Элемент данных содержит общий текстовый элемент данных, который не подходит ни под одну из других категорий.

    Это отнюдь не исчерпывающий список, но хорошие программисты будут использовать как можно меньше из этих описателей, так как слишком много из них перевешивают любые преимущества такой классификации/документации.

  5. Рассмотрите возможность включения аббревиатуры, которая будет вставлена в имя любого элемента данных, определенного непосредственно или косвенно подчиненного элементу уровня 01, как правило, после любого тега уровня раздела, если вы их используете. Например, рассмотрите имена, используемые в следующей структуре:
    01  WS-File-Status-Message-TXT.
        05 FILLER                     PIC X(13) VALUE 'Status Code: '.
        05 WS-FSM-Status-CD           PIC 9(2).
        05 FILLER                     PIC X(11) VALUE ', Meaning: '.
        05 WS-FSM-Msg-TXT             PIC X(25).
    

    Аббревиатуры «-FSM-» упрощают поиск описания элемента уровня 01, к которому относятся элементы кода состояния и текста сообщения.

12.3. Использование индексов и подстрочных индексов в таблицах

Элементы таблицы могут быть сосланы либо с использованием подстрочного индекса, либо индекса. Синтаксически это кодируется с использованием круглых скобок, как показано в следующих трех примерах, все из которых записывают букву «A» в 17-ю запись элемента данных с именем WSS-Output-Image-TXT:

  1. MOVE 'A' TO WSS-Output-Image-TXT (17)
  2. MOVE 17 TO WSS-OI-SUB MOVE 'A' TO WSS-Output-Image-TXT (WSS-OI-SUB)
  3. SET WSS-OI-IDX TO 17 MOVE 'A' TO WSS-Output-Image-TXT (WSS-OI-IDX)

Первый и второй примеры относятся к подстрочному индексированию, а третий — к индексированию. Различие довольно простое.

Индексирование — это процесс обращения к элементу таблицы, используя элемент данных с явно или неявно определённым USAGE (см. USAGE) для выбора нужного вхождения, в то время как …

Подстрочный индекс — это процесс обращения к элементу таблицы, используя либо числовую константу, либо необработанный числовой элемент данных для выбора нужного вхождения.

Различные реализации COBOL генерируют объектный код, который сильно отличается в каждом из этих трёх случаев, и GnuCOBOL не является исключением.

В общем случае, ссылки на таблицы, такие как пример #1 (постоянный индекс), генерируют самый короткий, простой и быстрый объектный код, в то время как ссылки на таблицы, такие как пример #2 (индекс в виде числового элемента данных), генерируют самый большой, сложный и медленный объектный код.

Ссылки на таблицы, такие как пример #3 (индексирование таблицы), генерируют объектный код, который находится посередине между двумя другими, но по эффективности значительно ближе к примеру #1, чем к #2.

Некоторые инструкции COBOL (SEARCH (см. SEARCH), SEARCH ALL (см. SEARCH ALL) и основанные на таблице SORT (см. Таблица SORT)) требуют индексирования затронутой таблицы и использования этого индекса в этих инструкциях. При любых других ссылках на таблицы выбор подхода остается за программистом. В общем, следуйте этим правилам:

  1. Используйте постоянные индексы (пример #1), где это возможно/практично.
  2. Если обращение к элементам таблицы будет выполняться много раз (десятки или сотни тысяч раз или более) во время выполнения программы, вы, вероятно, заметите заметное сокращение времени выполнения программы, если будете использовать индексирование вместо подстрочного индекса.

Невозможно выполнить арифметические операции над элементом индекса непосредственно (кроме простой инкрементации или декрементации с помощью инструкции SET UP/DOWN (см. SET UP/DOWN)). Ситуации, где требуются нетривиальные вычисления для расчета эффективного номера вхождения в таблице, потребуют использования обычного необработанного числового элемента данных в качестве поля для вычисления. Вычисленное значение затем нужно будет сохранить в элемент индекса с помощью инструкции SET Index .

Если вычисляемый номер вхождения нужен только один раз, вы можете использовать вычисленное значение как подстрочный индекс. Однако, если вам нужно использовать вычисленный «подстрочный индекс» многократно, накладные расходы на преобразование этого значения в индекс (через SET Index) будут стоить потраченного времени на написание кода.

Уф!

Если обращения к элементам таблицы не будут выполняться много раз, то выбор между индексированием и подстрочным индексом вряд ли существенно повлияет на результат.

Если вы знакомы с языком программирования C, вам может быть полезной следующая простая программа GnuCOBOL для изучения различий между подстрочным индексом и индексированием:

IDENTIFICATION DIVISION.
PROGRAM-ID.  SUBVSINDEX.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  WS-TABLE-SUB                BINARY-LONG.
01  WS-TABLE.
    05 WS-TABLE-ENTRY           OCCURS 20 TIMES
                                INDEXED BY WS-TABLE-IDX
                                PIC X(1).
PROCEDURE DIVISION.
000-Main SECTION.
E1. MOVE 'A' TO WS-TABLE-ENTRY (17)
    .
E2. MOVE 17 TO WS-TABLE-SUB
    MOVE 'A' TO WS-TABLE-ENTRY (WS-TABLE-SUB)
    .
E3. SET WS-TABLE-IDX TO 17
    MOVE 'A' TO WS-TABLE-ENTRY (WS-TABLE-SUB)
    .

Компилируйте эту программу следующим образом (предполагается, что вы выполняете команду cobc из каталога, в котором находится исходный код программы (subvsindex.cbl).

cobc -C -save-temps subvsindex.cbl\

После выполнения этой команды файл subvsindex.c будет содержать процедурный раздел кода C, а subvsindex.c.1.h — код рабочей области C. Сравните сгенерированный код C для каждой из трёх MOVE инструкций.

12.4. Конвенции и использование именования копибуков

Поскольку цель копибука — вставить код COBOL в определённую точку программы с помощью инструкции COPY (см. COPY), всегда рекомендуется добавлять префикс к имени копибука, который указывает, где в программе должно быть COPY содержимое.

Например:

IDxxxxxxxx

Копибуки, содержащие код, предназначенный для раздела идентификации. Эти копибуки встречаются редко, так как в разделе идентификации почти никогда не встречается скопированный код.

EDxxxxxxxx

Копибуки, содержащие код, предназначенный для использования в разделе окружения. Эти копибуки обычно используются для предопределённых SPECIAL-NAMES (см. SPECIAL-NAMES) или FILE-CONTROL (см. РАЗДЕЛ ВВОДА-ВЫВОДА) синтаксиса.

DDxxxxxxxx

Копибуки, содержащие определения данных.

PDxxxxxxxx

Копибуки, содержащие исполняемые инструкции.

12.5. Разделы PROCEDURE DIVISION по сравнению с параграфами

Вопрос о том, использовать ли имена разделов и/или параграфов (в совокупности называемые именами процедур) в разделе PROCEDURE DIVISION, имеет для многих программистов COBOL почти религиозное значение.

Стандарты программирования COBOL, используемые во многих организациях, которые используют этот язык, обычно предписывают именам процедур:

  1. Содержать ведущую числовую компоненту (например: 2000-Update-Customer), И…
  2. Определяться в разделе PROCEDURE DIVISION в порядке не убывания этой числовой компоненты.

Когда вы смотрите или редактируете большую программу COBOL, созданную по стандартам программирования, включающим эти два правила, всегда легко узнать, относится ли ссылка на процедуру к коду, расположенному до или после вашего текущего местоположения в программе, просто сравнив числовую часть имени текущей процедуры с интересующей вас процедурой.

Технически, GnuCOBOL не требует определения ИМЕНИ НИ ОДНОЙ процедуры, ЕСЛИ:

  1. Вы используете инструкцию ALTER (см. ALTER) (использование которой следует избегать всеми возможными способами)
  2. Вы используете инструкцию процедурного PERFORM (см. Процедурный PERFORM)
  3. Вы используете инструкцию GO TO (см. GO TO)
  4. Вы используете инструкцию MERGE (см. MERGE) с OUTPUT PROCEDURE
  5. Вы используете инструкцию SORT (см. SORT) с INPUT PROCEDURE или OUTPUT PROCEDURE (или с обоими)
  6. Вы используете DECLARATIVES (см. DECLARATIVES)

Поскольку сложно написать любую непростую программу COBOL, не использующую ни одного из вышеперечисленных пунктов, давайте предположим, что вы будете включать по крайней мере один раздел или абзац в свои программы GnuCOBOL.

Мне нравится использовать разделы и абзацы раздела процедуры следующим образом:

  1. Первая определённая процедура в разделе процедур моих программ, если не определены DECLARATIVES (см. DECLARATIVES), будет разделом, названным 000-Main. Объявление этой процедуры будет следовать сразу после заголовка раздела процедур (или END DECLARATIVES, если используются DECLARATIVES).
  2. Любые процедуры, на которые ссылаются инструкции MERGE, PERFORM, или SORT, будут определены как разделы.
  3. Любые процедуры, на которые ссылаются инструкции GO TO, будут определены как абзацы, и эти абзацы будут определены в том же разделе, что и инструкции GO TO, которые на них ссылаются. Другими словами, инструкции GO TO нельзя использовать для передачи управления в точку в другом разделе. Это не правило GnuCOBOL — это моя личная практика программирования, направленная на улучшение читабельности и поддерживаемости моих программ.
  4. Я всегда включаю числовой префикс ко всем именам процедур, которые я определяю, по тем же причинам, что и ранее.
  5. Я не использую THRU с MERGE, PERFORM или SORT инструкциями, если только стандарты программирования того предприятия, где я работаю, этого не требуют. Моё обоснование состоит в том, что очень легко случайно ввести новую процедуру в область действия THRU.

12.6. COMPUTE по сравнению с ADD-SUBTRACT-MULTIPLY-DIVIDE

На протяжении многих лет велись споры об эффективности и точности арифметических вычислений при использовании инструкции COMPUTE (см. COMPUTE) вместо четырёх основных арифметических инструкций.

Вот факты — сделайте свои выводы о том, какой подход более подходящий в каких обстоятельствах.

  1. Инструкция COMPUTE поддерживает возведение в степень (через оператор ‘**’), чего нет среди инструкций базовых арифметических операций. Хотя вы могли бы смоделировать возведение в целую степень (возведение значения в третью степень, например) с помощью инструкций MULTIPLY, и вы можете использовать встроенную функцию SQRT (см. SQRT) для нахождения квадратного корня, но нет простого (лёгкого) способа найти кубический корень значения без использования инструкции COMPUTE.
  2. Для нетривиальных вычислений инструкции COMPUTE «читаются» лучше. Вот пример:
    COMPUTE R = (A + B * C) / D
    

    По сравнению с этим:

    MULTIPLY B BY C GIVING TEMP
    ADD A TO TEMP
    DIVIDE TEMP BY D GIVING R
    

    Для нетривиальных вычислений инструкции COMPUTE могут выполняться быстрее, чем эквивалентная цепочка инструкций базовых арифметических операций. Например, показанная выше инструкция COMPUTE выполняется примерно на 25% быстрее на моём компьютере с использованием GnuCOBOL, чем последовательность MULTIPLY-ADD-DIVIDE.

  3. Для тривиальных вычислений, с другой стороны, я предпочитаю изначальную читаемость такой инструкции:
    ADD 1 TO WSS-Input-Trans-QTY
    

    чем этой:

    COMPUTE WS-Input-Trans-QTY = WS-Input-Trans-QTY + 1
    

Приложение A - Словарь терминов

Элемент данных с алфавитным значением

Элемент данных, PICTURE которого позволяет ему содержать только прописные и/или строчные буквы. См. PICTURE.

Элемент данных с алфавитно-цифровым значением

Элемент данных, PICTURE которого позволяет ему содержать любые символы. См. PICTURE. Групповые элементы (см. Структурированные данные) также неявно считаются алфавитно-цифровыми элементами данных.

Алфавитно-цифровая константа

Последовательность символов, заключённая в пару кавычек (‘"’) или апострофов (‘'’). См. Алфавитно-цифровые литералы.

Вызываемая программа

Другое название подпрограммы. Обратите внимание, что вызываемая программа также может быть программой-вызывающей.

Программа-вызывающая

Программа, выполняющая подпрограмму. Обратите внимание, что программа-вызывающая также может быть вызываемой программой.

Последовательность сортировки

Порядок, в котором символы, допустимые для компьютера, упорядочены для целей сортировки, слияния, сравнения и обработки. Программы GnuCOBOL могут использовать стандартные последовательности сортировки наборов символов (например, определённые наборами символов ASCII или EBCDIC) или определённые пользователем пользовательские последовательности, как указано в абзаце OBJECT-COMPUTER (раздел 4.1.2) и определённые в абзаце SPECIAL-NAMES (раздел 4.1.4).

Группа компиляции

Совокупность всех единиц компиляции, компилируемых одной операцией компилятора GnuCOBOL.

Единица компиляции

Один исходный файл, компилируемый компилятором GnuCOBOL. Единица компиляции может содержать одну или несколько программ.

Разрыв контроля

Событие, которое срабатывает, когда значение поля управления в отчёте, сгенерированном RWCS, изменяется. Именно эти события запускают создание заголовков и подвалов контроля.

Поле управления

Поле данных, представленное в группе детали; поскольку различные группы деталей, составляющие отчёт, представляются, предполагается, что они появляются в отсортированном порядке полей управления, содержащихся в них. Например, отчёт о продажах по отделам для сети магазинов, вероятно, будет отсортирован по номеру магазина и — внутри одинаковых номеров магазинов — дополнительно отсортирован по номеру отдела. Номер магазина, безусловно, будет служить полем управления для отчёта, позволяя представлять заголовки контроля перед каждой последовательностью групп деталей для того же магазина и подвалы контроля после каждой такой последовательности.

Подвал контроля

Группа отчёта, появляющаяся непосредственно после одной или нескольких групп деталей отчёта, сгенерированного RWCS. Такие группы создаются автоматически в результате разрыва контроля. Этот тип группы обычно служит сводкой данных группы деталей, предшествующей ей, как это может быть в случае отчёта о продажах для сети магазинов, где группы деталей, документирующие продажи по каждому отделу (один отдел на группу деталей) из одного магазина, могут следовать подвалу контроля, который предоставляет сводку продаж по отделам для этого магазина.

Заголовок контроля

Группа отчёта, появляющаяся непосредственно перед одной или несколькими группами деталей отчёта, сгенерированного RWCS. Такие группы создаются автоматически в результате разрыва контроля. Этот тип группы обычно служит введением к группам деталей, следующим за ней, как это может быть в случае отчёта о продажах для сети магазинов, где группы деталей, документирующие продажи по каждому отделу (один отдел на группу деталей) из одного магазина, могут предшествовать заголовку контроля, который указывает полное название и местоположение магазина.

Иерархия контроля

Естественная иерархия разрывов контроля в отчёте, контролируемом RWCS, основанная на порядке сортировки данных, из которых генерируется отчёт.

Файл кода

Часть кода программы, которая может использоваться несколькими программами, просто добавив в программу оператор COPY, чтобы импортировать этот код. Несмотря на сходство с механизмом «включения» в многих других языках программирования, механизм файлов кода COBOL на самом деле значительно мощнее. См. Файлы кода для общего обсуждения. См. COPY для подробностей о операторе COPY.

Элемент данных

Соседний участок памяти в адресном пространстве программы, который может быть указан по имени в программе COBOL. Другие языки программирования используют термин переменная, свойство или атрибут для описания того же понятия. См. Структурированные данные.

Группа детали

Группа отчёта, содержащая подробные данные, представленные в отчёте.

Отчёт с подробными данными

Отчёт, сгенерированный RWCS, которому представлена хотя бы одна группа деталей.

Раздел

Совокупность нуля, одной или более секций абзацев, называемых телом раздела, которые образуются и комбинируются в соответствии с определённым набором правил. Каждый раздел состоит из заголовка раздела и соответствующего тела раздела. В программе GnuCOBOL есть четыре раздела: Идентификации, Окружения, Данных и Процедуры (в таком порядке). См. Структура программы.

Динамическая подпрограмма

Подпрограмма, объектный код которой содержится в отдельном исполняемом файле по сравнению с вызывающей программой. Динамические подпрограммы, следовательно, загружаются в память по мере необходимости.

Элементарный элемент

Элемент данных, который сам по себе не состоит из других элементов данных. См. Структурированные данные.

Точка входа

Место в процедурной части, где программа может начать выполнение, когда она выполняется из операционной системы, вызывается как пользовательская функция или вызывается другой программой.

В каждой программе есть по крайней мере одна точка входа — известная как основная точка входа — которая соответствует первой исполняемой инструкции в процедурной части после области деклараций, если таковая имеется.

Дополнительные точки входа могут быть определены с помощью инструкции %%%CODE_BLOCK_5943%% (см. ENTRY).

Имя точки входа

У каждой точки входа есть имя. Это имя должно быть уникальным для всех программ, которые составляют исполняемую программу. Имена точек входа определяются в абзаце подпрограммы PROGRAM-ID, в абзаце пользовательской функции FUNCTION-ID, или с помощью инструкций ENTRY (см. ENTRY) в процедурной части подпрограммы.

Исполняемый файл

Компилятор GnuCOBOL может создавать соответствующие операционной системе файлы, которые могут быть выполнены непосредственно из среды операционной системы. В системах Windows это будут файлы .exe, а в системах UNIX у них не будет специальных расширений. Переключатель компилятора -x используется для создания исполняемых файлов. Только главные программы должны компилироваться таким образом.

Поток выполнения

Полный набор исполняемого кода, который выполняется во время выполнения программы. Это включает главную программу, а также все исполняемые подпрограммы, включая те, которые загружаются динамически и статически.

Фигуративные константы

GnuCOBOL, как и другие реализации COBOL, поддерживает ряд зарезервированных слов, которые могут быть использованы для представления определенного значения литерала. Они известны как фигуративные константы. Более подробная информация приведена в разделе Фигуративные константы.

Режим фиксированного формата

Режим работы компилятора GnuCOBOL, в котором инструкции исходного кода ограничены стандартом до 2002 года, ограничивая операторы COBOL 80 столбцами, с различными ограничениями на то, какой синтаксис COBOL можно в них указать. Дополнительная информация приведена в разделе Формат строк исходного кода программы.

Режим свободного формата

Режим работы компилятора GnuCOBOL, в котором строки исходного кода могут иметь длину до 255 символов без ограничений или требований относительно столбцов, в которых должны появляться различные синтаксические элементы. Дополнительная информация приведена в разделе Формат строк исходного кода программы.

Групповой элемент

Иерархическая структура данных, где групповой элемент — сам по себе элемент данных — фактически состоит из двух или более других смежных элементов данных. Например, Employee-Name может быть элементом данных длиной 35 символов, состоящим из элемента данных Last-Name длиной 20 символов, за которым следуют элемент First-Name длиной 14 символов и элемент Middle-Initial длиной 1 символ. См. Структурированные данные.

Шестнадцатеричная буквенно-цифровая константа

Это буквенно-цифровые константы, последовательность символов которых задается шестнадцатеричным значением. Эти константы формируются при помощи заключённой в кавычки или апострофы последовательности чётного числа шестнадцатеричных цифр (в верхнем или нижнем регистре), префиксной буквой 'X' (также в верхнем или нижнем регистре). Например, строка символов “Demo” может быть задана как шестнадцатеричная буквенно-цифровая константа X'44656D6F', предполагая набор символов ASCII. См. Буквенно-цифровые константы.

Шестнадцатеричная числовая константа

Числовой литерал, значение которого задаётся шестнадцатеричным значением. Эти литералы формируются при помощи заключённой в кавычки или апострофы последовательности от 1 до 16 шестнадцатеричных цифр (в верхнем или нижнем регистре), префиксной буквой 'H' (также в верхнем или нижнем регистре). Например, число 123456 может быть задано как шестнадцатеричная числовая константа H'01E240'. См. Числовые константы.

Идентификаторы

Это элементы данных, с которыми будет работать программа COBOL. Подавляющее большинство идентификаторов определяется пользователем (программистом), а несколько — предопределены компилятором GnuCOBOL. Идентификаторы, предопределённые компилятором, называются специальными регистрами. Другие языки программирования обычно называют идентификаторы «переменными».

Инструкции-команды

Это инструкция, которая начинается с глагола, не связанного с принятием решений, и задаёт безусловное действие, которое должно быть выполнено, или условный глагол, такой как IF или EVALUATE, ограниченный явным ограничителем области действия (например, END-IF или END-EVALUATE). Инструкция-команда может состоять из последовательности инструкций-команд.

Встроенная функция

Встроенная процедура, которая принимает аргументы и возвращает значение; синтаксически, они могут использоваться во всех местах, где допустимы идентификаторы GnuCOBOL. См. Встроенные функции, для документации всех встроенных функций GnuCOBOL.

Уровень

Число от 1 до 2 знаков, указывающее иерархическое положение элемента данных в группе элементов или особые свойства записи описания данных.

Номера уровней в диапазоне от 1 до 49 указывают положение элемента данных в иерархической структуре логической записи. Номера уровней в диапазоне от 1 до 9 могут быть записаны как однозначные или как нуль, за которым следует значащая цифра.

Номера уровней 66, 77, 78 и 88 идентифицируют особые свойства записи описания данных.

Литерал

Общее название для константного значения, закодированного в программе, которое может быть либо числовой, либо алфавитно-цифровой литералью.

Главная программа

Программа, которая выполняется непосредственно из операционной системы или события оболочки. Главные программы не выполняются из других программ (т. е. они не вызываемые программы).

Национальный набор символов

Набор символов, который поддерживает символы, использующие другие символы, кроме традиционных символов латинского алфавита, используемых набором символов ASCII. Обычно такой набор символов использует кодировку UTF-16 (т. е. 16 бит на символ) набора символов Unicode.

Поддержка национальных наборов символов в GnuCOBOL в настоящее время реализована только частично, и эффект компиляции и выполнения использования символа N в предложении PICTURE (см. PICTURE) для определения поля, содержащего национальные символы, такой же, как если бы X(2) было закодировано, с дополнительным эффектом, что такое поле будет квалифицироваться как поле NATIONAL или NATIONAL-EDITED в предложении INITIALIZE (см. INITIALIZE).

Числовой элемент данных

Элемент данных, чей PICTURE-оператор позволяет ему содержать только цифровые символы 0-9 (со знаком или без знака), или элемент данных, чья комбинация PICTURE/USAGE позволяет ему содержать фактические двоичные числа в формате целых, с фиксированной запятой, с плавающей запятой или упакованной десятичной форме. Числовые элементы данных — единственные, которые могут использоваться в качестве индексов таблиц или в качестве аргументов в арифметических операциях. PICTURE (см. PICTURE) или USAGE (см. USAGE).

Числовой отформатированный элемент данных

В противном случае числовой элемент данных, чей PICTURE-оператор (см. PICTURE) также содержит любые из символов редактирования «$», «*», «+», «,», «-», «.», «/», «0» (ноль), «B», «CR», «DB» или «Z». Числовые отформатированные элементы данных не могут быть использованы в качестве индексов таблиц или аргументов в арифметических операциях.

Числовая литераль

Числовая константа. См. Числовые литералы.

Подвал страницы

Группа отчетов, которая появляется в нижней части каждой страницы отчета, генерируемого RWCS. Информация, обычно встречающаяся в такой группе отчетов, может включать:

  • Дату генерации отчета
  • Номер текущей страницы отчета
Заголовок страницы

Группа отчетов, которая появляется в верхней части каждой страницы отчета, генерируемого RWCS. Информация, обычно встречающаяся в такой группе отчетов, может включать:

  • Заголовок отчета
  • Дату генерации отчета
  • Номер текущей страницы отчета
  • Заголовки столбцов, описывающие поля в группе деталей
Основная точка входа

См. точку входа.

Процедура

Все выполняемые операторы кода в одном параграфе или разделе раздела процедур.

Имя процедуры

Имя секции или параграфа, определенное программистом, в разделе процедур, назначенное процедуре. Имена процедур служат средством, с помощью которого оператор может ссылаться на операторы, следующие за именем процедуры.

Программа

Главная программа GnuCOBOL или подпрограмма.

Квалификация

Процесс установления уникальной ссылки на элемент данных, имя которого дублируется в программе. Это делается с помощью использования дублированного имени данных и имени любого из его родительских элементов данных, соединенных с помощью OF или IN, таким образом, что сочетание этих двух имен данных является уникальным в программе.

Запись

Группа элементов, которая не является частью группы элементов более высокого уровня. См. Принципы определения данных. Элементарный элемент с номером уровня 01 также может называться записью, если его определение находится в разделе файла, при условии, что его определение не включает атрибут CONSTANT. См. FILE-SECTION-Элемент данных.

Подвал отчета

Группа отчетов, которая встречается только один раз в отчете, генерируемом RWCS, — как последняя представленная группа отчетов отчета. Они обычно служат визуальным указанием на то, что отчет завершен.

Группа отчета

Одна или несколько последовательных строк в отчете, которые служат общей информационной цели или функции. Например, строки текста, отображаемые вверху или внизу каждой распечатанной страницы отчета.

Заголовок отчета

Группа отчетов, которая встречается только один раз в отчете, генерируемом RWCS, — как первая представленная группа отчетов отчета. Они обычно служат введением к отчету.

Зарезервированное слово

Слово, закодированное в программе GnuCOBOL без кавычек или апострофов вокруг него (что преобразовало бы эту последовательность символов в строковую литерал), имеющее очень специфическое значение для компилятора. См. Зарезервированные слова языка для общего обсуждения концепции. См. Список зарезервированных слов приложения B для полного списка зарезервированных слов GnuCOBOL.

Предложение

Произвольно длинная последовательность операторов, завершающаяся точкой.

Специальные регистры

Специальные данные, автоматически определённые для вашего использования компилятором GnuCOBOL. См. Специальные регистры для полного списка.

Оператор

Один исполняемый оператор COBOL. Все операторы начинаются с глагола (DISPLAY, IF, MOVE, ...) за которым следуют операнды и дополнительные элементы синтаксиса, описывающие выполняемые действия.

Статический подпрограмма

Подпрограмма, исполняемый объектный код которой является частью того же исполняемого файла, что и вызывающая программа. Следовательно, статические подпрограммы загружаются в память одновременно со своим вызывающим объектом.

Подпрограмма

Программа, вызываемая напрямую другой программой таким образом, что она может вернуть управление обратно другой программе, непосредственно в точку, где была вызвана подпрограмма.

Подпрограмма

Подпрограмма, выполняемая из другой с помощью оператора GnuCOBOL CALL (см. CALL) (или эквивалентного в любом языке программирования, на котором написана другая программа).

Отчёт резюме

Генерируемый RWCS отчёт, которому не представлены детальные группы.

Пользовательская функция

Подпрограмма, написанная на GnuCOBOL, которая выполняется аналогичным образом с точки зрения синтаксиса, как и различные встроенные функции.

Пользовательские имена

Либо имя идентификатора, либо процедура в программе. GnuCOBOL ограничивает имена, заданные пользователем, максимум 31 символом, взятыми из набора числовых цифр, прописных и строчных букв, дефисов и подчёркиваний. Пользовательское имя не может начинаться и не может заканчиваться дефисом или подчёркиванием. Пользовательские имена, используемые в качестве имён файлов, кроме того, не могут начинаться с цифры, хотя — в отличие от многих других языков программирования — пользовательские имена, используемые в качестве идентификаторов или имён процедур, могут.

Глагол

Первое зарезервированное слово оператора COBOL.

Альфа-цифровые литералы с нулевым разделителем

Альфа-цифровая литерала, префикс которой имеет прописную или строчную букву «Z» — например, Z'ABC'. Эти литералы на один символ длиннее, чем значение внутри апострофов или кавычек, которое они предполагают. Дополнительный символ (последний символ) будет нулевым символом (состоящим целиком из нулевых битов). Эти литералы идеально подходят для определения или присвоения значений альфа-цифровым данным, которые будут переданы в качестве аргументов подпрограмме C. См. Альфа-цифровые литералы.

Приложение B - Список зарезервированных слов

Ниже приведён полный список ВСЕХ зарезервированных слов в сборке GnuCOBOL 3.1 RC-1 от июля 2020 года. Даже если функциональность за некоторыми из этих слов не реализована в этой версии GnuCOBOL, ни одно из них нельзя использовать в качестве пользовательского имени. Этот список включает ВСЕ зарезервированные, встроенные, мнемоники, системные и показывает около 1100+ слов в общей сложности. Кроме того, есть арифметические и реляционные символы, см. 1.3.15, а также дополнительные слова, которые можно добавить, и существующие слова, которые можно удалить, используя содержимое файла –std, см. конкретный файл, используемый для каждого подмножества.

3

3-D

A

ОТСУТСТВУЕТ, ABS, ПРИНИМАТЬ, ДОСТУП, ACOS, ДЕЙСТВИЕ, АКТИВНЫЙ-КЛАСС, АКТИВНЫЙ-X, АДРЕС, ДОБАВИТЬ, РЕГУЛИРУЕМЫЕ-СТОЛБЦЫ, ПЕРЕХОДЯЩИЙ, ПОСЛЕ, ВЫРАВНЯННЫЙ, ВЫРАВНИВАНИЕ, РАЗМЕСТИТЬ, ВСЕ, АЛФАВИТНЫЕ-МАЛЫЕ, АЛФАВИТНЫЕ-БОЛЬШИЕ, АЛФАВИТНЫЕ, АЛФАВИТ, АЛФАЦИФРОВЫЙ-РЕДАКТИРОВАННЫЙ, АЛФАЦИФРОВЫЙ, ТАКЖЕ, ВТОРИЧНЫЙ, ИЗМЕНИТЬ, И, АНУИТЕТ, ЛЮБОЙ_РЕГИСТР, ЛЮБОЙ, ОБЛАСТИ, ОБЛАСТЬ, ЯВЛЯЮТСЯ, ЧИСЛО_АРГУМЕНТА, ЗНАЧЕНИЕ_АРГУМЕНТА, АРИФМЕТИЧЕСКИЙ, ВОЗРАСТАЮЩИЙ, ASCII, ASIN, ПРИСВОИТЬ, КАК, В, АТАН, АТРИБУТ, АВТОР, АВТОМАТИЧЕСКОЕ_ДЕСЯТИЧНОЕ, АВТОМАТИЧЕСКИЙ, АВТОМАТИЧЕСКАЯ_ПРОПУСКАЕТ, АВТОМАТИЧЕСКОЕ_ВРАЩЕНИЕ, АВТОМАТИЧЕСКИЙ_ЗАВЕРШЕНИЕ, АВТО, ОТ_НУЛЯ

B

ЦВЕТ_ФОНТА, ЦВЕТ_ФОНТА, ВЫСОКИЙ_ФОН, НИЗКИЙ_ФОН, СТАНДАРТНЫЙ_ФОН, И, ПАНЕЛЬ, ОБОСНОВАНО, ЗВУК, ПЕРЕД, ЗВОНОК, ДВОИЧНЫЙ_СИМВОЛ, ДВОИЧНЫЙ_C_ДЛИННЫЙ, ДВОИЧНЫЙ_ДВОЙНОЙ, ДВОИЧНЫЙ_ЦЕЛЫЙ, ДВОИЧНЫЙ_ДЛИННЫЙ_ДЛИННЫЙ, ДВОИЧНЫЙ_ДЛИННЫЙ, ДВОИЧНЫЙ_ПОСЛЕДОВАТЕЛЬНЫЙ, ДВОИЧНЫЙ_КОРОТКИЙ, ДВОИЧНЫЙ, КАРТИНКА_КОНЕЦ, ДЕСКРИПТОР_КАРТИНКИ, НОМЕР_КАРТИНКИ, КАРТИНКА_НАЧАЛО, ТАЙМЕР_КАРТИНКИ, КАРТИНКА_ЗАДНЯЯ_ЧАСТЬ, ЦВЕТ_ПРОЗРАЧНОСТИ_КАРТИНКИ, ШИРИНА_КАРТИНКИ, КАРТИНКА, БИТ, ПУСТОЕ, МЕРЦАНИЕ, БЛОК, НЕ, ЛОГИЧЕСКИЙ, ЛОГИЧЕСКИЙ_ИЗ_ЦЕЛОГО, ИЛИ, НИЖНЯЯ_ЧАСТЬ, В_рамке, РАМКА, ЗАНЯТО, КНОПКИ, ИСКЛЮЧАЮЩЕЕ_ИЛИ, ДЛИНА_БАЙТА, ПО

C

C01, C02, C03, C04, C05, C06, C07, C08, C09, C10, C11, C12, ШРИФТ_КАЛЕНДАРЯ, КОНВЕНЦИЯ_ВЫЗОВА, ВЫЗОВ, КНОПКА_ОТМЕНА, ОТМЕНА, ЕМКОСТЬ, ПЕРФОРИРОВАННАЯ_КАРТА, ЧТЕЦ_ПЕРФОРИРОВАННЫХ_КАРТ, КАССЕТА, CBL_И, CBL_ИЗМЕНИТЬ_ДИРЕКТОРИЮ, CBL_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_ФАЙЛА, CBL_ЗАКРЫТЬ_ФАЙЛ, CBL_СКОПИРОВАТЬ_ФАЙЛ, CBL_СОЗДАТЬ_ДИРЕКТОРИЮ, CBL_СОЗДАТЬ_ФАЙЛ, CBL_УДАЛИТЬ_ДИРЕКТОРИЮ, CBL_УДАЛИТЬ_ФАЙЛ, CBL_РАВНО, CBL_ОБРАБОТКА_ОШИБОК, CBL_ВЫХОД_ИЗ_ОБРАБОТЧИКА, CBL_ОЧИСТИТЬ_ФАЙЛ, CBL_GC_ВИЛКА, CBL_GC_ПОЛУЧИТЬ_ПАРАМЕТР, CBL_GC_ХОСТИНГ, CBL_GC_NANOSLEEP, CBL_GC_ПЕЧАТАЕМОЕ, CBL_GC_ЖДАТЬ_ПРОЦЕСС, CBL_ПОЛУЧИТЬ_ПОЗИЦИЮ_УКАЗАТЕЛЯ, CBL_ПОЛУЧИТЬ_ТЕКУЩУЮ_ДИРЕКТОРИЮ, CBL_ПОЛУЧИТЬ_РАЗМЕР_ЭКРАНА, CBL_IMP, CBL_NIMP, CBL_НЕ, CBL_НЕ, CBL_OC_ПОЛУЧИТЬ_ПАРАМЕТР, CBL_OC_ХОСТИНГ, CBL_OC_NANOSLEEP, CBL_ОТКРЫТЬ_ФАЙЛ, CBL_ИЛИ, CBL_ПРОЧИТАТЬ_ФАЙЛ, CBL_ПРОЧИТАТЬ_СИМВОЛ_С_КЛАВИАТУРЫ, CBL_ПЕРЕИМЕНОВАТЬ_ФАЙЛ, CBL_УСТАНОВИТЬ_ПОЗИЦИЮ_УКАЗАТЕЛЯ, CBL_В_НИЖНИЙ_РЕГИСТР, CBL_В_ВЕРХНИЙ_РЕГИСТР, CBL_ЗАПИСАТЬ_ФАЙЛ, CBL_ИСКЛЮЧАЮЩЕЕ_ИЛИ, C$ВЫЗВАННЫЙ, C$ИЗМЕНИТЬ_ДИРЕКТОРИЮ, CCOL, C$СКОПИРОВАТЬ, C$УДАЛИТЬ, CD, ЦВЕТ_ЯЧЕЙКИ, ДАННЫЕ_ЯЧЕЙКИ, ШРИФТ_ЯЧЕЙКИ, ЗАЩИТА_ЯЧЕЙКИ, ЯЧЕЙКИ, ЯЧЕЙКА, ЦЕНТРИРОВАННЫЕ_ЗАГОЛОВКИ, ЦЕНТР, ДАТА_В_ВЕКЕ, C$ИНФОРМАЦИЯ_О_ФАЙЛЕ, CF, C$ПОЛУЧИТЬ_PID, ЦЕПЛЕНИЕ, ЦЕПЬ, СИМВОЛЫ, СИМВОЛ, НАЦИОНАЛЬНЫЙ_СИМВОЛ, СИМВОЛ, ЧЕКБОКС, CH, C$ВЫРАВНИВАНИЕ, ИД_КЛАССА, КЛАССИФИКАЦИЯ, КЛАСС, ОЧИСТКА_ВЫБОРА, СТРОКИ, СТРОКА, ЗАКРЫТЬ, C$СОЗДАТЬ_ДИРЕКТОРИЮ, C$NARG, COB-CRT-СОСТОЯНИЕ, КОБОЛ, КОДИРОВКА, КОД, СОРТИРОВКА, ЦВЕТА, ЦВЕТ, ЦВЕТА, COLS, ЦВЕТ_СТОЛБЦА, РАЗДЕЛИТЕЛИ_СТОЛБЦОВ, ШРИФТ_СТОЛБЦА, ЗАГОЛОВКИ_СТОЛБЦОВ, ЗАЩИТА_СТОЛБЦА, СТОЛБЦЫ, СТОЛБЕЦ, COL, ОБЪЕДИНЕННАЯ_ДАТА_ВРЕМЯ, КОМБО-КОРОБКА, КОМАНДНАЯ_СТРОКА, ЗАПЯТАЯ, ЗАПИСЬ, ОБЩИЙ, КОММУНИКАЦИЯ, COMP-1, COMP-2, COMP-3, COMP-4, COMP-5, COMP-6, ВЫЧИСЛИТЕЛЬНЫЙ-1, ВЫЧИСЛИТЕЛЬНЫЙ-2, ВЫЧИСЛИТЕЛЬНЫЙ-3, ВЫЧИСЛИТЕЛЬНЫЙ-4, ВЫЧИСЛИТЕЛЬНЫЙ-5, ВЫЧИСЛИТЕЛЬНЫЙ-6, ВЫЧИСЛИТЕЛЬНЫЙ-X, ВЫЧИСЛИТЕЛЬНЫЙ, ВЫЧИСЛИТЬ, COMP-X, COMP, СОЕДИНИТЬ, УСЛОВИЕ, КОНФИГУРАЦИЯ, КОНСОЛЬ, КОНСТАНТА, СОДЕРЖИТ, СОДЕРЖИМОЕ, ПРОДОЛЖИТЬ, УПРАВЛЕНИЯ, УПРАВЛЕНИЕ, ПРЕОБРАЗОВАНИЕ, ПРЕОБРАЗОВАНИЕ, КОПИРОВАНИЕ_ВЫБОРА, КОПИЯ, СООТВЕТСТВУЮЩИЙ, КОЭФФИЦИЕНТ, КОС, СЧЕТ, C$РАЗМЕР_ПАРАМЕТРА, C$ПЕЧАТАЕМОЕ, CRT_НИЗ, CRT, CSIZE, C$ЖДАТЬ, CSP, C$В_НИЖНИЙ_РЕГИСТР, C$В_ВЕРХНИЙ_РЕГИСТР, ВАЛЮТНЫЙ_СИМВОЛ, ВАЛЮТА, ТЕКУЩАЯ_ДАТА, ЦВЕТ_УКАЗАТЕЛЯ, СТОЛБЕЦ_УКАЗАТЕЛЯ, ШИРИНА_КАДРА_УКАЗАТЕЛЯ, СТРОКА_УКАЗАТЕЛЯ, КООРДИНАТА_X_УКАЗАТЕЛЯ, УКАЗАТЕЛЬ, КООРДИНАТА_Y_УКАЗАТЕЛЯ, КСТРУМА_ПО_ЗАДАННОМУ_ШАБЛОНУ, ЦИКЛ

D

ПУНТИРНЫЙ, СТОЛБЦЫ_ДАННЫХ, УКАЗАТЕЛЬ_ДАННЫХ, ТИПЫ_ДАННЫХ, ДАННЫЕ, КОМПЛЕКТАЦИЯ, ВВОД_ДАТЫ, ИЗМЕНЕНИЯ_ДАТЫ, ДАТА_ЦЕЛОГО_ЧИСЛА, ДАТА_В_ФОРМАТЕ_ГГГГММДД, ДАТА_ЗАПИСИ, ДАТА, ДЕНЬ_ЦЕЛОГО_ЧИСЛА, ДЕНЬ_НЕДЕЛИ, ДЕНЬ_В_ФОРМАТЕ_ГГГГДД, ДЕНЬ, ОТЛАДКА, ЭЛЕМЕНТ_ОТЛАДКИ, ДЕСЯТИЧНАЯ_ТОЧКА, ДЕКЛАРАТИВЫ, КНОПКА_ПО_УМОЛЧАНИЮ, ШРИФТ_ПО_УМОЛЧАНИЮ, ПО_УМОЛЧАНИЮ, УДАЛИТЬ, ОГРАНИЧЕННЫЙ, РАЗДЕЛИТЕЛЬ, ЗАВИСЯЩИЙ, УБЫВАЮЩИЙ, НАЗНАЧЕНИЕ, УНИЧТОЖИТЬ, ДЕТАЛЬ, ДЕ, ОТКЛЮЧИТЬ, ДИСК, ДИСК, СТОЛБЦЫ_ОТОБРАЖЕНИЯ, ФОРМАТ_ОТОБРАЖЕНИЯ, ОТОБРАЖЕНИЕ, РАЗДЕЛИТЕЛЬНЫЙ_ЦВЕТ, РАЗДЕЛИТЕЛИ, ДЕЛИТЬ, РАЗДЕЛ, ПУНТИР, ПУНКТЫРНЫЙ, ДВОЙНОЙ, ВНИЗ, ЦВЕТ_ПЕРЕТАСКИВАНИЯ, ВЫПАДАЮЩИЙ, СПИСОК_ВЫПАДАЮЩИЙ, ДУБЛИКАТЫ, ДИНАМИЧЕСКИЙ

E

E, EBCDIC, ЭХО, EC, EGI, ИНАЧЕ, EMI, ПРОВЕРКА_ПУСТОТЫ, ВКЛЮЧИТЬ, КОНЕЦ_ПРИНЯТИЯ, КОНЕЦ_ДОБАВЛЕНИЯ, КОНЕЦ_ВЫЗОВА, КОНЕЦ_ЦЕПИ, КОНЕЦ_ЦВЕТА, КОНЕЦ_ВЫЧИСЛЕНИЯ, КОНЕЦ_УДАЛЕНИЯ, КОНЕЦ_ОТОБРАЖЕНИЯ, КОНЕЦ_ДЕЛЕНИЯ, КОНЕЦ_ОЦЕНКИ, КОНЕЦ_ЕСЛИ, КОНЕЦ_МОДИФИКАЦИИ, КОНЕЦ_УМНОЖЕНИЯ, КОНЕЦ_СТРАНИЦЫ, КОНЕЦ_ВЫПОЛНЕНИЯ, КОНЕЦ_ЧТЕНИЯ, КОНЕЦ_ПРИЁМА, КОНЕЦ_ВОЗВРАТА, КОНЕЦ_ПЕРЕЗАПИСИ, КОНЕЦ_ПОИСКА, КОНЕЦ_НАЧАЛА, КОНЕЦ_СТРОКИ, КОНЕЦ_ВЫЧИТАНИЯ, КОНЕЦ_РАЗДЕЛЕНИЯ, КОНЕЦ_ЗАПИСИ, КОНЕЦ, ВЫГРУБЛЕННЫЙ, УБЕДИТЬСЯ_В_ВИДИМОСТИ, КОНВЕНЦИЯ_ВВОДА, ПОЛЕ_ВВОДА, ПРИЧИНА_ВВОДА, ВВОД, ИМЯ_СРЕДЫ, ЗНАЧЕНИЕ_СРЕДЫ, СРЕДА, КОНЕЦ_СТРОКИ, EO, КОНЕЦ_СТРАНИЦЫ, КОНЕЦ_СТРОКИ, РАВНО, РАВНО, СТИРАТЬ, ОШИБКА, КНОПКА_ОТМЕНЫ, ОТМЕНА, ESI, ОЦЕНКА, СПИСОК_СОБЫТИЙ, СОБЫТИЕ, ФАЙЛ_ИСКЛЮЧЕНИЯ_N, ФАЙЛ_ИСКЛЮЧЕНИЯ, МЕСТОПОЛОЖЕНИЕ_ИСКЛЮЧЕНИЯ_N, МЕСТОПОЛОЖЕНИЕ_ИСКЛЮЧЕНИЯ, ОБЪЕКТ_ИСКЛЮЧЕНИЯ, УКАЗАНИЕ_ИСКЛЮЧЕНИЯ, СОСТОЯНИЕ_ИСКЛЮЧЕНИЯ, ЗНАЧЕНИЕ_ИСКЛЮЧЕНИЯ, ИСКЛЮЧЕНИЕ, ИСКЛЮЧИТЕЛЬНЫЙ, ВЫХОД, EXP10, РАСШИРЯЕТ, РАСШИРИТЬ, EXP, РАСШИРИТЬ, ВНЕШНЯЯ_ФОРМА, ВНЕШНИЙ, ВНЕШНИЙ

F

F, ФАКТОРИАЛ, ФАКТОРИЙ, ЛОЖЬ, FD, УПРАВЛЕНИЕ_ФАЙЛАМИ, ИД_ФАЙЛА, ИМЯ_ФАЙЛА, ПОЗИЦИЯ_ФАЙЛА, ФАЙЛ, ЗАЛИВКА_ЦВЕТА2, ЦВЕТ_ЗАЛИВКИ, ЗАПОЛНИТЕЛЬ, ПРОЦЕНТ_ЗАЛИВКИ, КОНЕЧНЫЙ, ПРИЧИНА_ОКОНЧАНИЯ, ПЕРВЫЙ, ФИКСИРОВАННЫЙ_ШРИФТ, ФИКСИРОВАННАЯ_ШИРИНА, ФИКСИРОВАННЫЙ, ПЛОСКИЕ_КНОПКИ, ПЛОСКИЙ, ПЛАВАЮЩАЯ_ТОЧКА_ДВОИЧНАЯ_128, ПЛАВАЮЩАЯ_ТОЧКА_ДВОИЧНАЯ_32, ПЛАВАЮЩАЯ_ТОЧКА_ДВОИЧНАЯ_64, ПЛАВАЮЩАЯ_ТОЧКА_ДЕСЯТИЧНАЯ_16, ПЛАВАЮЩАЯ_ТОЧКА_ДЕСЯТИЧНАЯ_34, ПЛАВАЮЩАЯ_ТОЧКА_РАСШИРЕННАЯ, БЕСКОНЕЧНОСТЬ_ПЛАВАЮЩАЯ_ТОЧКА, ПЛАВАЮЩАЯ_ТОЧКА, ПЛАВАЮЩАЯ_ТОЧКА_ДЛИННАЯ, ПЛАВАЮЩАЯ_ТОЧКА_НЕ_ЧИСЛО, ПЛАВАЮЩАЯ_ТОЧКА_КОРОТКАЯ, ПЛАВАЮЩАЯ_ТОЧКА, ШРИФТ, ПОДВАЛ, ЦВЕТ_ПЕРЕДНЕГО_ПЛАНА, ЦВЕТ_ПЕРЕДНЕГО_ПЛАНА, ВЕЧНО, ФОРМАТ, ФОРМАТИРОВАННАЯ_ТЕКУЩАЯ_ДАТА, ФОРМАТИРОВАННАЯ_ДАТА_ВРЕМЯ, ФОРМАТИРОВАННАЯ_ДАТА, ФОРМАТИРОВАННОЕ_ВРЕМЯ, ПЕРЕВОД_СТРАНИЦЫ, ДЛЯ, ДРОБНАЯ_ЧАСТЬ, ОГРАНИЧЕННЫЙ, РАМКА, СВОБОДНЫЙ, ОТ, ПОЛНАЯ_ВЫСОТА, ПОЛНЫЙ, ИД_ФУНКЦИИ, УКАЗАТЕЛЬ_ФУНКЦИИ, ФУНКЦИЯ

G

ГЕНЕРИРОВАТЬ, ПОЛУЧИТЬ, ДАВАЯ, ГЛОБАЛЬНЫЙ, ВОЗВРАТ, ВОЗВРАТ, ПЕРЕЙТИ_ВПЕРЕД, ПЕРЕЙТИ_ДОМОЙ, ПЕРЕЙТИ_В_ПОИСК, ПЕРЕЙТИ, ГРАФИЧЕСКИЙ, БОЛЬШЕ, СЕТКА, ИСПОЛЬЗОВАНИЕ_ГРУППЫ, ЗНАЧЕНИЕ_ГРУППЫ, ГРУППА

H

ДЕСКРИПТОР, ИМЕЕТ_ПОТОМКОВ, ЦВЕТ_ЗАГОЛОВКА, ЦВЕТ_РАЗДЕЛИТЕЛЯ_ЗАГОЛОВКА, ШРИФТ_ЗАГОЛОВКА, ЗАГОЛОВОК, ЖЁСТКИЙ, ВЫСОТА_В_ЯЧЕЙКАХ, СКРЫТЫЕ_ДАННЫЕ, ЦВЕТ_ВЫСОКОГО_КАЧЕСТВА, ВЫСОЧАЙШИЙ_АЛГЕБРАИЧЕСКИЙ, ВЫДЕЛЕНИЕ, ВЫСОКИЕ_ЗНАЧЕНИЯ, ВЫСОКОЕ_ЗНАЧЕНИЕ, ПОДСВЕТКА, ПОЗИЦИЯ_ГОРИЗОНТАЛЬНОЙ_СТРОЛКИ, ГОРИЗОНТАЛЬНАЯ_СТРОЛКА

I
END_OF_DOCUMENT_MARKER

ИКОНА, ИДЕНТИФИКАЦИЯ, ИДЕНТИФИЦИРОВАННЫЙ, ИД, ЕСЛИ, ИГНОРИРОВАТЬ, ИГНОРИРУЯ, РЕАЛИЗУЕТ, НЕЗАВИСИМЫЙ, ИНДЕКСИРОВАННЫЙ, ИНДЕКС, УКАЗАТЬ, НАСЛЕДУЕТ, ИНИЦИАЛИЗИРОВАННЫЙ, ИНИЦИАЛИЗИРОВАТЬ, ИНИЦИАЛИЗИРОВАННЫЙ, ИНИЦИАЛИЗИРОВАТЬ, НАЧАЛЬНЫЙ, ИНИЦИИРОВАТЬ, ВВОД-ВЫВОД, ВВОД, ЗАПРОСИТЬ, ИНДЕКС-ВСТАВКИ, ВСТАВИТЬ-СТРОКИ, ИНСПЕКТИРОВАТЬ, УСТАНОВКА, ЦЕЛОЕ-ИЗ-БУЛЕВОГО, ЦЕЛОЕ-ИЗ-ДАТЫ, ЦЕЛОЕ-ИЗ-ДНЯ, ЦЕЛОЕ-ИЗ-ФОРМАТИРОВАННОЙ-ДАТЫ, ЦЕЛАЯ_ЧАСТЬ, ЦЕЛОЕ, ИД_ИНТЕРФЕЙСА, ИНТЕРФЕЙС, ПРОМЕЖУТОЧНЫЙ, В, ВНУТРЕННИЙ, НЕВЕРНЫЙ, ВЫЗВАТЬ, В, УПРАВЛЕНИЕ_ВВОДОМ_ВЫВОДОМ, ВВОД_ВЫВОД, ЕСТЬ, ТЕКСТ_ЭЛЕМЕНТА, ЭЛЕМЕНТ_ДЛЯ_ДОБАВЛЕНИЯ, ЭЛЕМЕНТ_ДЛЯ_УДАЛЕНИЯ, ЭЛЕМЕНТ_ДЛЯ_ОЧИСТКИ, ЗНАЧЕНИЕ_ЭЛЕМЕНТА, ЭЛЕМЕНТ

J

ВЫРАВНЯННЫЙ_В_ПРАВО, ВЫРАВНЯННЫЙ

K

СОХРАНЕННЫЙ, КЛЮЧ, КЛАВИАТУРА

L

СМЕЩЕНИЕ_МЕТКИ, МЕТКА, ШРИФТ_БОЛЬШОГО_РАЗМЕРА, БОЛЬШОЕ_СМЕЩЕНИЕ, ПОСЛЕДНЯЯ_СТРОКА, ПОСЛЕДНИЙ, ДАННЫЕ_МАКЕТА, УПРАВЛЯЮЩИЙ_ЭЛЕМЕНТ_МАКЕТА, LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME, ВЕДУЩИЙ_СДВИГ, ВЕДУЩИЙ, ВЫРАВНЯТЬ_ВЛЕВО, ЛЕВАЯ_ЛИНИЯ, ЛЕВЫЙ_ТЕКСТ, ЛЕВЫЙ, ДЛИНА_AN, ПРОВЕРКА_ДЛИНЫ, ДЛИНА, МЕНЬШЕ, ПРЕДЕЛЫ, ПРЕДЕЛ, СЧЕТЧИК_СТРОК, СТРОКИ, СЧЕТЧИК_ЛИНИЙ, СТРОКИ_В_КОРНЕ, ПОСЛЕДОВАТЕЛЬНОСТЬ_СТРОК, СТРОКИ, СТРОКА, СВЯЗЬ, СПИСОК, ИЗМЕНЕНИЕ_РАЗМЕРА_LM, СРАВНЕНИЕ_ЛОКАЛИ, ДАТА_ЛОКАЛИ, ВРЕМЯ_ЛОКАЛИ_ИЗ_СЕКУНД, ВРЕМЯ_ЛОКАЛИ, ЛОКАЛЬ, ЛОКАЛЬНОЕ_ХРАНЕНИЕ, БЛОКИРОВКА, LOG10, ЛОГ, ДАТА_ДЛИННОГО_ФОРМАТА, ЦВЕТ_НИЗКОГО_РАЗРЕШЕНИЯ, МАЛЫЕ_БУКВЫ, ОПУЩЕННЫЙ, МАЛЫЕ_БУКВЫ, НАИМЕНЬШИЙ_АЛГЕБРАИЧЕСКИ, ВЫДЕЛЕНИЕ_С_ОТТЕНКОМ, НИЗКИЕ_ЗНАЧЕНИЯ, НИЗКОЕ_ЗНАЧЕНИЕ

M

МАГНИТНАЯ_ЛЕНТА, РУЧНОЙ, МАССОВОЕ_ОБНОВЛЕНИЕ, MAX_ЛИНИЙ, MAX_ПРОГРЕСС, MAX_ТЕКСТ, MAX_ЗНАЧ, MAX, СРЕДНЕЕ, МЕДИАНА, ШРИФТ_СРЕДНЕГО_РАЗМЕРА, ПАМЯТЬ, МЕНЮ, СЛИЯНИЕ, СООБЩЕНИЕ, ИД_МЕТОДА, МЕТОД, СРЕДНЕГО_ДИАПАЗОНА, МИНУС, MIN_ЗНАЧ, MIN, РЕЖИМ, ИЗМЕНЕНИЕ, ИД_ВЫЗОВЩИКА_МОДУЛЯ, ДАТА_МОДУЛЯ, ФОРМАТИРОВАННАЯ_ДАТА_МОДУЛЯ, ИД_МОДУЛЯ, ПУТЬ_К_МОДУЛЮ, ИСТОЧНИК_МОДУЛЯ, МОДУЛИ, ВРЕМЯ_МОДУЛЯ, MOD, ДЕСЯТИЧНАЯ_ТОЧКА_ВАЛЮТЫ, РАЗДЕЛИТЕЛЬ_ТЫСЯЧ_ВАЛЮТЫ, ПЕРЕМЕСТИТЬ, МНОГОСТРОЧНЫЙ, МНОЖЕСТВЕННЫЙ, УМНОЖАТЬ

N

ИМЯ, НАЦИОНАЛЬНОЕ_РЕДАКТИРОВАНИЕ, НАЦИОНАЛЬНОЕ_ИЗ, НАЦИОНАЛЬНЫЙ, НАТИВНЫЙ, НАВИГИРОВАТЬ_URL, БЛИЖАЙШИЙ_В_НАПРАВЛЕНИИ_ОТ_НУЛЯ, БЛИЖАЙШИЙ_ЧЁТНЫЙ, БЛИЖАЙШИЙ_К_НУЛЮ, ОТРИЦАТЕЛЬНЫЙ, ВЛОЖЕННЫЙ, НОВЫЙ, СЛЕДУЮЩИЙ_ЭЛЕМЕНТ, СЛЕДУЮЩИЙ, БЕЗ_АВТО_ДЕФОЛЬТ, БЕЗ_АВТОСЕЛЕКЦИИ, БЕЗ_РАМОК, БЕЗ_РАЗДЕЛИТЕЛЕЙ, БЕЗ_ЭХО, БЕЗ_F4, БЕЗ_ФОКУСА, БЕЗ_ГРУППОВОГО_ТАБА, БЕЗ_КЛЮЧЕВОЙ_БУКВЫ, НИКАКОЙ, НОРМАЛЬНЫЙ, БЕЗ_ПОИСКА, БЕЗ_ТАБА, НИЧЕГО, УВЕДОМЛЕНИЕ_О_ИЗМЕНЕНИИ, УВЕДОМЛЕНИЕ_О_ДВОЙНОМ_ЩЕЛЧКЕ, УВЕДОМЛЕНИЕ_О_ИЗМЕНЕНИИ_ВЫБОРА, УВЕДОМЛЕНИЕ, НЕ, БЕЗ_ВВЕРХ_ВНИЗ, НЕТ, NULLS, NULL, КОЛИЧЕСТВО_ПАРАМЕТРОВ_ВЫЗОВА, ЧИСЛА, ЧИСЛО, ЗАГОЛОВКИ_КОЛОНКИ_ЧИСЛА, ДЕСЯТИЧНАЯ_ТОЧКА_ЧИСЛА, РЕДАКТИРОВАННОЕ_ЧИСЛО, РАЗДЕЛИТЕЛЬ_ТЫСЯЧ_ЧИСЛА, ЧИСЛО, КОЛИЧЕСТВО_СТРОК, NUMVAL-C, NUMVAL-F, NUMVAL

O

ОБЪЕКТ-КОМПЬЮТЕР, ОБЪЕКТ-ССЫЛКА, ОБЪЕКТ, ПРОИСХОДИТ, ВЫКЛ, ИЗ, КНОПКА_ОК, ПРОПУЩЕНО, ТОЛЬКО, ВКЛ, ОТКРЫТЬ, НЕОБЯЗАТЕЛЬНО, ВАРИАНТЫ, ПОРЯДОК, ORD_MAX, ORD_MIN, ORD, ОРГАНИЗАЦИЯ, ИЛИ, ДРУГОЙ, ВЫВОД, ПРЕВЫШЕНИЕ, ПЕРЕКРЕСТИЕ_СЛЕВА, ПЕРЕКРЕСТИЕ_СВЕРХУ, ПОДЧЕРКНУТО, ПЕРЕОПРЕДЕЛЕНИЕ

P

УПАКОВАННЫЙ_ДЕСЯТИЧНЫЙ, ОТСТУП, СЧЕТЧИК_СТРАНИЦ, РАЗДЕЛЕННЫЙ_НА_СТРАНИЦЫ, НАСТРОЙКА_СТРАНИЦЫ, СТРАНИЦА, АБЗАЦ, РОДИТЕЛЬСКИЙ, ПАРОЛЬ, ВЫПОЛНЯТЬ, ПОСТОЯННЫЙ, PF, PH, ФИЗИЧЕСКИЙ, ВИД, PIC, ПИКСЕЛИ, ПИКСЕЛЬ, PI, РАЗМЕЩЕНИЕ, ПЛЮС, УКАЗАТЕЛЬ, ВЫПАДАЮЩЕЕ_МЕНЮ, СДВИГ_ПОЗИЦИИ, ПОЗИЦИЯ, ПОЛОЖИТЕЛЬНЫЙ, ПРЕФИКС, ТЕКУЩЕЕ_ЗНАЧЕНИЕ, ТЕКУЩИЙ, ПРЕДЫДУЩИЙ, ПЕЧАТАТЬ, ПРИНТЕР_1, ПРИНТЕР, ПЕЧАТЬ, ПЕЧАТЬ_БЕЗ_ЗАПРОСА, ПРЕДПРОСМОТР_ПЕЧАТИ, ПЕЧАТЬ, ПРИОРИТЕТ, УКАЗАТЕЛЬ_ПРОЦЕДУРЫ, ПРОЦЕДУРЫ, ПРОЦЕДУРА, ПРОДОЛЖИТЬ, ИД_ПРОГРАММЫ, УКАЗАТЕЛЬ_ПРОГРАММЫ, ПРОГРАММА, ПРОГРЕСС, ЗАПРЕЩЕНО, ЗАПРОС, СВОЙСТВА, СВОЙСТВО, ЗАЩИЩЕННЫЙ, ПРОТОТИП, ОЧИСТКА, КНОПКА_ВЫЗОВА

Q

ИНДЕКС_ЗАПРОСА, ОЧЕРЕДЬ, КАВЫЧКИ, КАВЫЧКА

R

КНОПКА_РАДИО, ВЫСОТА, ПОДНЯТЬ, ПОДНИМАНИЕ, СЛУЧАЙНЫЙ, ДИАПАЗОН, RD, ТОЛЬКО_ЧТЕНИЕ, ЧИТАТЬ, ПОЛУЧИТЬ, ДАННЫЕ_ЗАПИСИ, ЗАПИСЬ, ЗАПИСИ, ЗАПИСЬ_ДЛЯ_ДОБАВЛЕНИЯ, ЗАПИСЬ_ДЛЯ_УДАЛЕНИЯ, ЗАПИСЬ, РЕКУРСИВНЫЙ, ПЕРЕОПРЕДЕЛЯЕТ, КАТУШКА, ССЫЛКА, ССЫЛКИ, ОБНОВЛЕНИЕ, ЦВЕТ_ОБЛАСТИ, ОТНОШЕНИЕ, ОТНОСИТЕЛЬНЫЙ, ОТПУСТИТЬ, ОСТАТОК, ЗАМЕЧАНИЯ, УДАЛЕНИЕ, REM, ПЕРЕИМЕНОВЫВАЕТ, ЗАМЕНИТЬ, ЗАМЕНЯЯ, ОТЧЁТНОСТЬ, ОТЧЁТЫ, ОТЧЁТ, РЕПОЗИТОРИЙ, НЕОБХОДИМО, ЗАПАС, СБРОС_РЕШЁТКИ, СБРОС_СПИСКА, СБРОС_ВКЛАДОК, СБРОС, ВОЗОБНОВИТЬ, ПОВТОРИТЬ, КОД_ВОЗВРАТА, ВОЗВРАЩАЯ, ВОЗВРАТ, ОБОРОТЕННЫЙ, ОБОРОТЕННЫЙ_ВИДЕО, ОБОРОТЕННЫЙ, ПЕРЕМОТАТЬ, ПЕРЕЗАПИСЬ, RF, RH, ВЫРАВНЯТЬ_В_ПРАВО, ВЫРАВНЯТЬ_В_ПРАВО, ПРАВО, ОГРАННИЧЕННЫЙ, ОТКАТ, ОКРУГЛЕННЫЙ, ОКРУГЛЕНИЕ, ПАТЕРН_ЦВЕТА_СТРОКИ, ЦВЕТ_СТРОКИ, РАЗДЕЛИТЕЛИ_СТРОК, ШРИФТ_СТРОКИ, ЗАГОЛОВКИ_СТРОК, ЗАЩИТА_СТРОК, ЗАПУСТИТЬ

S

S, ОДИНАКОВЫЙ, СОХРАНИТЬ_КАК_БЕЗ_ЗАПРОСА, СОХРАНИТЬ_КАК, ЭКРАН, ПАНЕЛЬ_ПРОКРУТКИ, ПРОКРУТКА, SD, ВАРИАНТЫ_ПОИСКА, ТЕКСТ_ПОИСКА, ПОИСК, СЕКУНДЫ_ИЗ_ФОРМАТИРОВАННОГО_ВРЕМЕНИ, СЕКУНДЫ_ПОСЛЕ_ПОЛУНОЧИ, СЕКУНДЫ, РАЗДЕЛ, БЕЗОПАСНЫЙ, БЕЗОПАСНОСТЬ, ПРЕДЕЛ_СЕГМЕНТА, СЕГМЕНТ, ВЫБРАТЬ_ВСЕ, ИНДЕКС_ВЫБОРА, ТЕКСТ_ВЫБОРА, ВЫБРАТЬ, САМО_ДЕЙСТВИЕ, САМО, ОТПРАВИТЬ, ПРЕДЛОЖЕНИЕ, ОТДЕЛЬНЫЙ, РАЗДЕЛЕНИЕ, ПОСЛЕДОВАТЕЛЬНОСТЬ, ПОСЛЕДОВАТЕЛЬНЫЙ, УСТАНОВИТЬ, ЗАТЕНЕНИЕ, ТЕЕНЬ, ОБМЕН, КОРОТКАЯ_ДАТА, ПОКАЗАТЬ_ЛИНИИ, ПОКАЗАТЬ_НИЧЕГО, ПОКАЗАТЬ_ВЫБОР_ВСЕГДА, ЦЕЛОЕ_С_ЗНАКОМ, ДЛИННОЕ_ЦЕЛОЕ_С_ЗНАКОМ, КОРОТКОЕ_ЦЕЛОЕ_С_ЗНАКОМ, С_ЗНАКОМ, ЗНАК, SIN, РАЗМЕР, ШРИФТ_МАЛОГО_РАЗМЕРА, СОРТИРОВКА_СЛИЯНИЕ, ПОРЯДОК_СОРТИРОВКИ, ВОЗВРАТ_СОРТИРОВКИ, СОРТИРОВКА, ИСТОЧНИК_КОМПЬЮТЕРА, ИСТОЧНИКИ, ИСТОЧНИК, ЗАПОЛНЕНИЕ_ПРОБЕЛАМИ, ПРОБЕЛЫ, ПРОБЕЛ, СПЕЦИАЛЬНЫЕ_ИМЕНА, СПИННЕР, SQRT, КВАДРАТ, СТАНДАРТ_1, СТАНДАРТ_2, СТАНДАРТНЫЙ_ДВОИЧНЫЙ, СТАНДАРТНОЕ_СРАВНЕНИЕ, СТАНДАРТНЫЙ_ДЕСЯТИЧНЫЙ, СТАНДАРТНОЕ_СТАНДАРТНОЕ_ОТКЛОНЕНИЕ, СТАНДАРТ, START_X, СТАРТ, START_Y, ОПЕРАТОР, СТАТИЧЕСКИЙ_СПИСОК, СТАТИЧЕСКИЙ, ПАНЕЛЬ_СТATUS, ТЕКСТ_СТATUS, СТATUS, STDCALL, STDERR, STDIN, STDOUT, ШАГ, ОСТАНОВИТЬ, ДЛИНА_ХРАНИМОЙ_СТРОКИ, СТРОКА, СИЛЬНЫЙ, СТИЛЬ, ПОДОЧЕРЕДЬ_1, ПОДОЧЕРЕДЬ_2, ПОДОЧЕРЕДЬ_3, ЗАМЕНА_РЕГИСТРА, ЗАМЕНА, ВЫЧИТАТЬ, ПОДОКНО, СУММА, СУММА, СВЕРХУ, ПОДАВИТЬ, ВЫКЛ_0, ВЫКЛ_10, ВЫКЛ_11, ВЫКЛ_12, ВЫКЛ_13, ВЫКЛ_14, ВЫКЛ_15, ВЫКЛ_16, ВЫКЛ_17, ВЫКЛ_18, ВЫКЛ_19, ВЫКЛ_1, ВЫКЛ_20, ВЫКЛ_21, ВЫКЛ_22, ВЫКЛ_23, ВЫКЛ_24, ВЫКЛ_25, ВЫКЛ_26, ВЫКЛ_27, ВЫКЛ_28, ВЫКЛ_29, ВЫКЛ_2, ВЫКЛ_30, ВЫКЛ_31, ВЫКЛ_32, ВЫКЛ_33, ВЫКЛ_34, ВЫКЛ_35, ВЫКЛ_36, ВЫКЛ_3, ВЫКЛ_4, ВЫКЛ_5, ВЫКЛ_6, ВЫКЛ_7, ВЫКЛ_8, ВЫКЛ_9, СИМВОЛИЧЕСКИЙ, СИМВОЛ, СИНХРОНИЗИРОВАННЫЙ, СИНХРОНИЗИРОВАННЫЙ, SYNC, SYSERR, SYSIN, SYSIPT, SYSLIST, SYSLST, SYSOUT, СИСТЕМА, СИСТЕМНЫЙ_ДЕФОЛЬТ, СИСТЕМНОЕ_СМЕЩЕНИЕ

T

TABLE, TAB-TO-ADD, TAB-TO-DELETE, TAB, TALLYING, TALLY, TAN, TAPE, TEMPORARY, TERMINATE, TERMINATION-VALUE, TEST-DATE-YYYYMMDD, TEST-DAY-YYYYDDD, TEST-FORMATTED-DATETIME, TEST-NUMVAL-C, TEST-NUMVAL-F, TEST-NUMVAL, TEXT, THAN, THEN, THREADS, THREAD, THROUGH, THRU, THUMB-POSITION, TILED-HEADINGS, TIMEOUT, TIME-OUT, TIMES, TIME, TITLE-POSITION, TITLE, TOP, TOWARD-GREATER, TOWARD-LESSER, TO, TRADITIONAL-FONT, TRAILING-SHIFT, TRAILING-SIGN, TRAILING, TRANSFORM, TRANSPARENT, TREE-VIEW, TRIM, TRUE, TRUNCATION, TYPEDEF, TYPE

U

U, UCS-4, UNBOUNDED, UNDERLINE, UNFRAMED, UNIT, UNIVERSAL, UNLOCK, UNSIGNED-INT, UNSIGNED-LONG, UNSIGNED-SHORT, UNSIGNED, UNSORTED, UNSTRING, UNTIL, UPDATE, UPON, UPPER-CASE, UPPER, UP, USAGE, USE-ALT, USER-DEFAULT, USE-RETURN, USER, USE-TAB, USE, USING, UTF-16, UTF-8

V

V, VALIDATE-STATUS, VALIDATE, VALID, VAL-STATUS, VALUE-FORMAT, VALUES, VALUE, VARIABLE, VARIANCE, VARIANT, VARYING, VERTICAL, VERY-HEAVY, VIRTUAL-WIDTH, VPADDING, VSCROLL-BAR, VSCROLL-POS, VSCROLL, VTOP

W

WAIT, WEB-BROWSER, WHEN-COMPILED, WHEN, WIDTH-IN-CELLS, WIDTH, WINDOW, WITH, WORDS, WORKING-STORAGE, WRAP, WRITE

X

X, X"91", X"E4", X"E5", X"F4", X"F5"

Y

Y, YEAR-TO-YYYY, YYYYDDD, YYYYMMDD

Z

ZEROES, ZERO-FILL, ZEROS, ZERO

Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
Licensed under the GNU Free Documentation License.
https://gnucobol.sourceforge.io/HTML/gnucobpg.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API