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 *)
This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

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. 14th, 2026 11:05 pm
Powered by Dreamwidth Studios