Pull to refresh
1473.04
Timeweb Cloud
То самое облако

Правка чужого кода

Reading time6 min
Views18K
Всегда приятно, когда удаётся сделать мир чуточку лучше.


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

Старожилы знают, что в комплекте с различными версиями ДОС шли дополнительные утилиты, и среди них была «замечательная» утилита debug, которая убога чуть более, чем полностью. Ещё во времена моей молодости эта утилита вызывала у меня самые противоречивые чувства, то сейчас и подавно. Пользоваться ей без успокоительных очень сложно, с другой стороны, хорошо, что она есть. Но мне возможностей и удобства этой утилиты не хватало, поэтому пришлось искать другой подходящий инструмент. После длительного гугления наткнулся на исходники утилиты RAM View.

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

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

Компиляция


Поскольку утилита поставляется только в исходных кодах, то её необходимо собрать. Как я не пытался, найти исполняемого файла мне не удалось. Поэтому придётся пройти этот тернистый путь, благо хотя бы компиляторы все в доступе.

Для того чтобы собрать и проверить эту утилиту, мне понадобится программа DOSBOX. До того как запускать коробку с ДОС, создаю папку DOS в корне диска C, либо ~/DOS в любимом Linux.

Перехожу в эту папку и клонирую туда этот проект:

git clone https://github.com/aurelitec/ramview.git

Сборка старых программ – это определённый квест, доступный не каждому: старые компиляторы, у которых есть свои особенности работы с ними, описанные в книгах, сданных в макулатуру. Поскольку ранее с компилятором Borland C++ дел не имел, пришлось идти в ретрочатик t.me/retrocomps и просить помощи.

Согласно описанию в гите, мне нужен Borland C++ 3.1, который я скачал отсюда. Выбрал портабельную последнюю версию, чтобы не заниматься установкой, и распаковываю её в папку C:\DOS\BC\.

После чего запускаю DOSBOX и монтирую локальную папку C:\DOS, как диск C:\:



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

Первое – это нужно получить Makefile из самого проекта, делается это командой PRJ2MAK (не забываем указать пути к исполняемому файлу):

PRJ2MAK RAMVIEW.PRJ



После этого у нас появится Makefile RAMVIEW.MAK, в котором уже можно посмотреть пути, где должен обитать компилятор.



Теперь осталось перенести компилятор в папку BORLANDC и должно произойти чудо.


Переименование папки

Запускаю компилятор, собираю и да, полный успех!



Казалось бы, вот оно счастье! Программа собралась, и можно пользоваться.

После всех неочевидных манипуляций запускаю программу и вижу такую картину:



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

Ну что ж, пришла пора исправлять чужие ошибки в старой программе.

Исправление ошибок в чужом коде


Проблема достаточно банальная, автор программы писал во времена DOS, в кодировке IBM CP866, а потом исходники видимо кочевали по разным дискам, вот и потерялись различные спецсимволы, которые затем были некорректно декодированы при заливке на github.

В этом можно убедиться, если открыть Notepad++ и посмотреть исходники, то достаточно быстро можно найти подобные места:




Некорректное отображение символов

Если в настройках сменить кодировку на CP866 (в моём случае это кириллица), то места станут намного более очевидными. А главное, они сразу будут узнаваемы с теми символами, что на скриншоте.




Проблемные места в кодировке CP866

Всё достаточно банально, нужно просто подобрать в ASCII-кодах подходящие символы и вставить их в нужные места. Первые две «сломанные» строки – это явно вертикальный символ, а нижний – это красивая деталь разделитель рамки.


Таблица ASCII – кириллица

Результатом стал выбор символа 0xB3 для вертикальной черты, и 0xBA для детали рамки.

cputs(" Version 0.1 \xb3 Copyright (c) 1997 Aurelitec");
…
cputs("\xb3 F10 = Exit");
…
strcat(buffer, " \xba");

Очень удобно редактировать код в Notepad++, а затем собирать в DOSBOX, новейшие технологии стучатся в наши двери (сарказм). После перекомпиляции получаем программу, которая выглядит и работает, так как надо:


Область памяти с ROM BIOS

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

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

Поскольку автор предоставляет нам как лицензионную, так и просто человеческую возможность вносить изменения в свою программу:
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Этой возможностью мы и воспользуемся.

Оформление изменений в чужой проект


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

Если попробовать закоммитить полученные изменения в репозиторий, из которого мы склонировали, то ничего не выйдет. Для этого в github есть другой механизм, по-русски называемый запросом на слияние. В gitlab он называется merge request, в github именуется pull request. Так как мне довелось достаточно долго поработать с github и gitlab, то я больше люблю за удобство gitlab, он сделан людьми для людей. Но человек ко всему привыкает и даже к таким ужасным вещам, как неочевидный интерфейс github.

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


Кнопка — создание форка репозитория


Клонирование репозитория к себе, в моём случае форк уже создан

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



В локальном репозитории выполняем:

git remote set-url origin https://github.com/dlinyj/ramview.git

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

git add <files>
git commit -m "Fixed minor bugs with the display of symbols"
git push

И тут начинается самое интересное. Вообще, как я понимаю, можно сделать и локально запрос на слияние, но мне удобнее через web-интерфейс.

В веб-интерфейсе вашего удалённого репозитория нужно зайти «Pull requests» и там нажать кнопку «New pull request».



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


Как выглядит запрос на слияние

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

На этом ваши приключения не заканчиваются, а только начинаются. Это самая интересная, может кому-то неприятная, часть заливки кода в чужеродный репозиторий.

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

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

Делается это следующей командой:

git commit --amend

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

git push --force

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

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

Выводы



Реальное применение исправленной программы

Достаточно часто встречаю от начинающих программистов вопрос: как мне набраться опыта в программировании? И всем им даю один и тот же ответ: идите на гитхаб и принимайте участие в каком-либо проекте. Правка чужого кода – это лучший способ научиться программировать. Поэтому настоятельно рекомендую не стесняться и делать такие правки, в худшем случае отклонят ваш запрос на слияние. В любом случае вы получите полезный опыт.

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

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

Полезные ссылки:


  1. Оригинальный репозиторий.
  2. Моя исправления копия.
  3. Оформленный запрос на слияние.
  4. Готовая собранная программа.

P.S. Попробуем правила 6 рукопожатий, быть может, кто-то из вас знает владельца репозитория и попросит его посмотреть мой запрос на слияние?
UPD Запрос на слияние был одобрен, всем спасибо!

Tags:
Hubs:
Total votes 68: ↑67 and ↓1+89
Comments50

Articles

Information

Website
timeweb.cloud
Registered
Founded
Employees
201–500 employees
Location
Россия
Representative
Timeweb Cloud