spamsink: (Default)
[personal profile] spamsink posting in [community profile] besm6
...или об автоматизации release management в прошлых веках.

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

В отсутствие каких бы то ни было систем контроля версий и трекинга изменений, кроме более или менее регулярных резервных копирований, полезно было также уметь коррелировать двоичный файл с версией исходного текста. Для этого после успешной компиляции/тестирования исходный текст редактировали, вписывая туда в комментарий дату/время/размер полученного двоичного файла. Это, видимо, достаточно часто забывали/ленились делать, поэтому была создана специальная программа "Лентяй", которая была пристыкована к запускалке компилятора.
Если при компиляции был указан псевдокомментарий (*=Л+*), то после успешной компиляции программа "Лентяй" пыталась найти в начале программы комментарий в определённом фиксированном формате, и заменяла его содержимое на дату/время/максимальный адрес загрузки полученной программы, а также печатала некоторую статистическую информацию.
         1. (*=P-,T-,M-*)_PROGRAM ЛEHTЯЙ;
         2. _LABEL 999;
         3. _CONST LF=’≡175’;DOT=’.’;SP=’ ’;
         4. _TYPE INT=INTEGER; DIGIT=’0’..’9’;
         5.   UNALFA=_ARRAY[1..6] _OF CHAR; ZONE=_ARRAY[0..1023] _OF INT;
         6. _VAR I, J, START, MID, FINISH, PIR, CHAI, TOT: INT;
         7. DATE:ALFA; UNPD:UNALFA; INBUF, OUTBUF:↑ZONE;
         8.
         9. _FUNCTION TIMESTAMP:ALFA;
        10. _VAR T, M:INT; A:UNALFA;RET:ALFA;
        11. _(
        12.   CODE(Э05310=,); T := ;
        13.   T := T _DIV 3000;
        14.   A[1] := ’ ’;
        15.   A[4] := ’.’;
        16.   M := T _DIV 600;
        17.   A[2] := ;
        18.   T := T - M * 600;
        19.   M := T _DIV 60;
        20.   A[3] := ;
        21.   T := T - M * 60;
        22.   M := T _DIV 10;
        23.   A[5] := ;
        24.   A[6] := CHR(T-M*10);
        25.   PCK(A[1], RET);
        26.   TIMESTAMP := RET;
        27. _);
        28.
        29. _FUNCTION TIME:INT;
        30. _(
        31.   CODE(Э0634=,);
        32.   TIME := ;
        33. _);
        34.
        35. _PROCED DIV100(T:INT);
        36. _(
        37.   WRITE(SP, T _DIV 100:1, ’.’);
        38.   T := T _MOD 100;
        39.   _IF T < 10 _THEN  WRITE(0:1);
        40.   WRITE(T:1);
        41. _);
        42.
        43. _FUNCTION GETDATE:ALFA;
        44. _VAR K:INT;L:ALFA;
        45. _(
        46.   K:=00003777776T;L:=’3 1   ’;
        47.   CODE(Э050114=,2CБ4=2PБ5,CД120=2ЗЧ4,MP=CД70,2ЗЧ5=MP,2CM5=CД140,17ЛC=2CM4,CД60=17ЛC,);
        48.   GETDATE:=;
        49. _);
        50.
        51. _PROCED FLUSH(NUZZZZ:INT);
        52. _(
        53.   NUZZZZ := NUZZZZ + 000034T;
        54.   CODE(2Э0703=,);
        55. _);
        56.
        57. _(
        58.   CODE(ИA67760=CЧ,ЗЧ75211=,15ПB74027=,);
        59.   J := 4;
        60.   _WHILE INPUT↑ <> LF _DO _( WRITE(INPUT↑); J := J + 1; GET(INPUT) _);
        61.   WRITE(LF);
        62.   GET(INPUT); _IF INPUT↑ <> ’(’ _THEN _GOTO 999;
        63.   GET(INPUT); _IF INPUT↑ <> ’*’ _THEN _GOTO 999;
        64.   GET(INPUT); _IF INPUT↑ <> SP _THEN _GOTO 999;
        65.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        66.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        67.   GET(INPUT); _IF INPUT↑ <> DOT _THEN _GOTO 999;
        68.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        69.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        70.   GET(INPUT); _IF INPUT↑ <> DOT _THEN _GOTO 999;
        71.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        72.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        73.   GET(INPUT); _IF INPUT↑ <> SP _THEN _GOTO 999;
        74.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        75.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        76.   GET(INPUT); _IF INPUT↑ <> DOT _THEN _GOTO 999;
        77.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        78.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        79.   GET(INPUT); _IF INPUT↑ <> SP _THEN _GOTO 999;
        80.   GET(INPUT); _IF INPUT↑ <> ’M’ _THEN _GOTO 999;
        81.   GET(INPUT); _IF INPUT↑ <> ’A’ _THEN _GOTO 999;
        82.   GET(INPUT); _IF INPUT↑ <> ’X’ _THEN _GOTO 999;
        83.   GET(INPUT); _IF INPUT↑ <> ’A’ _THEN _GOTO 999;
        84.   GET(INPUT); _IF INPUT↑ <> ’D’ _THEN _GOTO 999;
        85.   GET(INPUT); _IF INPUT↑ <> ’R’ _THEN _GOTO 999;
        86.   GET(INPUT); _IF INPUT↑ <> ’=’ _THEN _GOTO 999;
        87.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        88.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        89.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        90.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        91.   GET(INPUT); _IF _NOT (INPUT↑ _IN DIGIT) _THEN _GOTO 999;
        92.   GET(INPUT); _IF INPUT↑ <> SP _THEN _GOTO 999;
        93.   WRITE(’(* ’);
        94.   DATE :=   GETDATE;
        95.   UNPCK(UNPD[1], DATE);
        96.   WRITE(UNPD[1], UNPD[2], DOT, UNPD[3], UNPD[4], DOT, UNPD[5], UNPD[6], TIMESTAMP, ’ ’);
        97.   CODE(ИA66760=CЧ,); DATE := ; WRITE(DATE);
        98.   CODE(ИA66761=CЧ,); DATE := ; WRITE(DATE);
        99.   I := 1;
       100.   _WHILE I <= 12 _DO _( WRITE(INPUT↑); GET(INPUT); I := I + 1 _);
       101.   OUTBUF := PTR(70000B);
       102.   INBUF := PTR(72000B);
       103.   CODE(CЧ75224=,); J := ;
       104.   J := J - 72002B;
       105.   I := 0;
       106.   _WHILE I <= J _DO _( OUTBUF↑[I] := INBUF↑[I]; I := I + 1 _);
       107.   CODE(CЧ75211=); J := ;
       108.   FLUSH(SEL(J, 0, 18));
       109.   REWRITE(OUTPUT);
       110.   WRITELN(’ЗAФИKCИPOBAHO’);
       111.   CODE(CЧ75776=); START := ;
       112.   CODE(CЧ75775=); MID := ;
       113.   FINISH := TIME;
       114.   INS(DATE, 0, 40, 8);
       115.   MAPAI(DATE, J);
       116.   PIR := (MID - START) * 2;
       117.   CHAI := (FINISH - MID) * 2;
       118.   TOT := (FINISH - START) * 2;
       119.   WRITE(’ПИP =’);
       120.   DIV100(ROUND(PIR*1024/J));
       121.   WRITE(’ЧAЙ =’:7);
       122.   DIV100(ROUND(CHAI*1024/J));
       123.   WRITELN(’ CEK/ЗOHY’);
       124.   WRITE(’BCEГO:’);
       125.   DIV100( TOT );
       126.   WRITELN(’ CEK’);
       127.   CODE(ПБ76002=,);
       128. 999:
       129.   REWRITE(OUTPUT);
       130.   WRITELN(’HE BЫДEPЖAH CTAHДAPT’);
       131.   CODE(ПБ76002=,);
       132. _).

Особо оцените способ проверки соответствия шаблону.
Под лозунгами "ПИР" И "ЧАЙ" печатаются времена выполнения Паскаль-компилятора (им. С. И. Пирина) и Автокода ИТМ (им. М. Г. Чайковского).

Результат выглядит, например, так:
0001 (*=Р-,Т-,М-,Л+*)_РRОGRАМ ЛЕНТЯЙ;
0002 (* 05.06.21 00.14 МАХАDR=00615 *)

Profile

Сообщество любителей БЭСМ-6

December 2025

S M T W T F S
 123456
78910111213
14151617181920
21222324252627
282930 31   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 13th, 2026 05:40 am
Powered by Dreamwidth Studios