Программа "Лентяй"
Jun. 4th, 2021 11:59 pm...или об автоматизации 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 *)