Вебинар: Использование статических анализаторов кода при разработке безопасного ПО - 19.12
Многие из вас слышали об одном из старейших языков программирования COBOL, а также о том, что как сильно сейчас нужны COBOL-программисты для поддержки старого кода. Существует еще один "старожил", о котором знают немногие, который используется сейчас и будет использоваться еще достаточно долгое время для написания программ в различных сферах человеческой деятельности (финансовой, банковской и др.). Имя этому языку - IBM RPG.
RPG - проприетарный язык программирования высокого уровня, являющийся собственностью корпорации IBM, для создания бизнес-приложений. Последние версии языка доступны только для операционной системы IBM i (и ее прошлых версий под старым названием OS/400).
У RPG более чем полувековая история. К концу 50-х IBM выпустила огромное количество электромеханических машин, называемых табуляторами. Последним серийным табулятором стала модель IBM 407 Accounting Machine:
Рисунок 1. IBM 407 в Арсенале армии США в 1961 году.
К слову, аренда такого табулятора в зависимости от модели стоила от $800 до $920 в месяц (в перерасчете на современный доллар - от $8100 до $9300), а прекращена их продажа была 17 декабря 1976 года.
Как известно, технический прогресс не стоял на месте, и к концу 50-ых годов стали появляться транзисторные компьютеры. Первым таким компьютером для IBM стал IBM 1401, вышедший в 1959 году:
Рисунок 2. IBM 1401 в Центре истории и наследия Эндикотта.
В Музее компьютерной истории находится вполне рабочий экземпляр, я думаю, вам будет интересно посмотреть, как все это работало (особенно "доставляют" слова "We need a little bit of cooling" на 4:41):
Для упрощения перехода своих клиентов на новые транзисторные компьютеры в 1959 году также были придуманы сразу два инструмента, имитирующие процесс обработки перфокарт на компьютере - FARGO (Fourteen-o-one Automatic Report Generation Operation) и RPG (Report Program Generator). Синтаксис обоих языков был схож с командным языком электромеханических табуляторов. Кроме этого, FARGO и RPG повторяли важную особенность табуляторов: они эмулировали их циклический режим работы (программный цикл), во время которого табуляторы считывали данные с перфокарт, суммировали их и печатали результаты. IBM и на сегодняшний момент обеспечивает обратную совместимость с программным циклом даже в последнем диалекте RPG IV.
Хоть RPG и создавался под влиянием FARGO, уже через несколько лет RPG вытеснил своего предшественника как более перспективный вариант. А следующей системой, куда "подвезли" RPG, был мейнфрейм IBM System/360 Model 20:
Рисунок 3. IBM System/360 Model 20 в Немецком музее.
А уже через пару лет (конец 60-ых) IBM предоставляет следующий диалект языка - RPG II - для среднего компьютера System/3:
Рисунок 4. Средний компьютер IBM System/3 Model 10 с оператором.
С тех пор RPG развился в высокоуровневый аналог языков COBOL и PL/I. Отличительной особенностью языка (по сравнению с современными) являлся "фиксированный формат" синтаксиса, затруднявшим чтение программ без специального отладочного шаблона.
Рисунок 5. Отладочный шаблон (нажмите на картинку для увеличения).
Программы начинались со спецификаций файлов (File Specifications) - списка всех файлов, подлежащих чтению, записи или обновлению. За ними шли спецификации определений данных (Data Definition Specifications) - список элементов программы, таких как структуры данных или массивы. Этот блок напоминает секцию рабочей памяти (Working-Storage) в языке COBOL или команды с ключевым словом "var" в Паскале. Для указания типа переменной в колонку 40 спецификации определений записывается соответствующий символ (см. таблицу ниже). Если он опущен, т.е. вместо него стоит пробел, то типом по умолчанию будет A при условии, что не заданы десятичные разряды. В противном случае типом по умолчанию будет P.
Тип данных |
Название |
Длина |
Описание |
---|---|---|---|
* |
Указатель на базированную переменную Указатель на процедуру Системный указатель |
16 байт |
Обращение к данным Обращение к активированной процедуре Обращение к объектному файлу |
A |
Буквенно-цифровой символ |
От 1 до 16 773 104 байт (фиксированная длина) От 1 до 16 773 100 байт (переменная длина) |
Буква или цифра |
B |
Двоичное число |
1 байт (8-бит) 2 байт (16-бит) 4 байт (32-бит) 8 байт (64-бит) |
Двоичное целое число со знаком |
C |
Символ в кодировке UCS-2 |
От 1 до 8 386 552 символов (фиксированная длина) От 1 до 8 386 550 символов (переменная длина) |
16-битный символ в кодировке UCS-2 (набор символов DBCS или EGCS) |
D |
Дата |
10 байт |
Дата: год, месяц, день |
F |
Число с плавающей точкой |
4 байт (32-бит) 8 байт (64-бит) |
Двоичное вещественное число с плавающей точкой, со знаком |
G |
Графический символ |
От 1 до 8 386 552 символов (фиксированная длина) от 1 до 8 386 550 символов (переменная длина) |
16-битный графический символ (набор символов DBCS или EGCS) |
I |
Целое число |
1 байт (8-бит) 2 байт (16-бит) 4 байт (32-бит) 8 байт (64-бит) |
Двоичное целое число со знаком |
N |
Индикатор символа |
1 байт |
'1' = TRUE '0' = FALSE |
O |
Объектный файл |
Размер неизвестен |
Ссылка на объектный файл |
P |
Упакованное десятичное число |
От 1 до 63 цифр, по 2 цифры на байт плюс знак |
Десятичное число с фиксированной точкой, со знаком, с целой и дробной частями |
S |
Распакованное десятичное число |
От 1 до 63 цифр, по 1 цифре на байт |
Десятичное число с фиксированной точкой, со знаком, с целой и дробной частями |
T |
Время |
8 байт |
Время: час, минута, секунда |
U |
Целое число |
1 байт (8-бит) 2 байт (16-бит) 4 байт (32-бит) 8 байт (64-бит) |
Целое число без знака |
Z |
Метка времени |
26 байт |
Дата и время: год, месяц, день, час, минута, секунда, микросекунды |
Далее указывались спецификации вычислений (Calculation Specifications) - список команд для исполнения. Также могли добавляться спецификации вывода (Output Specifications), определяющие вид выходных файлов или отчетов.
Приведу также дополнительную информацию о всех типах спецификаций:
А теперь небольшой пример для разминки ваших глаз (опущены спецификации файлов и определений данных):
* Звездочка (*) в колонке 7 определяет строку-комментарий
* В колонке 6 пишется спецификация одним символом. Определяет,
* что будет происходить в строке (например, раздел объявлений,
* раздел вычислений, ...).
* Спецификация "C" (calculation) - вычисление
C HOURS IFLE 40
C HOURS MULT RATE PAY
C ELSE
C RATE MULT 40 PAY 72
C HOURS SUB 40 OTIME 30
C RATE MULT 1.5 OTRATE 94
C OTRATE MULT OTIME OTPAY 72
C ADD OTPAY PAY
C END
Код сложен для восприятия, не правда ли? А здесь всего лишь производится расчет налога на заработную плату для сотрудника с почасовой оплатой труда (работники, переработавшие 40 часов, получают полуторную ставку).
В 1978 году IBM представляет одновременно средний компьютер System/38 и новый диалект языка - RPG III - для него:
Рисунок 6. Средний компьютер IBM System/38
С этого момента ограничения языка несколько ослабляются и разрешается писать спецификации вычислений в "свободном формате":
/free
If Hours <= 40;
Pay = Hours * Rate;
Else;
Pay = (40 * Rate) + ((Hours - 40) * (Rate * 1.5));
EndIf;
/end-free
И, наконец, последняя версия диалекта - RPG IV (иначе RPGLE, ILE RPG) - вышла в 1994 году. Тремя основными "фичами" можно назвать встроенные функции, процедуры и "свободный формат" программирования. До ноября 2013 года свободный формат был доступен только для спецификаций вычислений. В обновлении V7R1 TR7 команды "/free" и "/end-free" были упразднены, а язык наконец-то освободился от наследия эпохи перфокарт.
Сам же язык широко используется сейчас под ОС IBM i на аппаратной платформе IBM Power i:
Рисунок 7. Линейка серверов IBM Power i
В общей сложности, язык RPG успел побывать на таких компьютерах, как 1401, System/360, System/3, System/32, System/34, System/36, System/38, AS/400 и System i. Имелись и реализации для платформ Digital VAX, Sperry Univac BC/7, Univac system 80, Siemens BS2000, Burroughs B700, B1700, Hewlett Packard HP3000, серии ICL 2900, Honeywell 6220 и 2020, серий Four-Phase IV/70 и IV/90, Singer System 10 и WANG VS, а также разнообразные компиляторы и среды исполнения для Unix-систем, например, Infinite36 (бывшая Unibol 36), и PC (Baby/400, Lattice-RPG).
К настоящему времени язык RPG развился в сильный, жизнеспособный язык. Программы можно по-прежнему писать в обычном редакторе в черно-зеленой гамме (green-screen):
Рисунок 8. Green-screen.
Однако появилось и множество других инструментов. Среди них - Visual Age для RPG, разработанные IBM и продвигаемые Джоном Пэрисом (Jon Paris) и другими. Наиболее популярным редактором на данный момент является IBM Websphere Development Studio, позднее переименованный в RDi (Rational Developer for i), являющийся пользовательской реализацией Eclipse:
Рисунок 9. Rational Developer for i.
Также компилятор RPG реализован для платформы Microsoft .NET. Помимо базовой версии в него входят дополнительные расширения языка RPG IV, что позволяет Microsoft Windows и .NET пользоваться окружением Native и System/36, а также портировать файлы DB/2 в базы данных Microsoft Access и Microsoft SQL Server через интерфейс ODBC.
Хоть язык и представляет собой экзотику, мы понимаем, что на нем написано много кода для финансовой, банковской и других видов деятельности. Он достаточно многообразен: существует 4 диалекта, фиксированная и свободная формы синтаксиса. Необходимость в поддержке старого и написании нового кода вынуждает компании искать RPG-программистов, которые, по-видимому, уже занесены в Красную книгу. В таких условиях возникает потребность в использовании дополнительных инструментов по контролю качества кода, например, таких как статический анализатор.
Возможно, читатель уже догадался, почему мы решили написать эту статью, и к чему мы клоним. Да, мы подумываем создать статический анализатор кода для языка RPG. Думаю, такой анализатор станет отличным подспорьем тем, кто продолжает сопровождать и развивать программы на этом языке. Однако, решение ещё не принято. Думаю, вы понимаете, что это весьма специфическое направление.
Поэтому, если вы хотите, чтобы анализатор PVS-Studio научился искать ошибки в RPG программах, то напишите нам. Мы ищем Вас, уважаемых потенциальных клиентов PVS-Studio RPG. Пишите нам!
0