Процесс портирования и создания средств разработки программ для KolibriOS продолжается. По наиболее активно используемым языкам программирования мы публикуем статьи. Сегодня мы начинаем рассказывать о языке С--, вокруг которого сложилось активное сообщество в 2000-е годы. Подробности под катом.
Кратко о языке с официального сайта:
C-- — это язык программирования, занимающий промежуточное положение между ассемблером и Cи. Идеально подходит для написания маленьких программ, резидентов (TSR), драйверов, обработчиков прерываний. Для работы с языком C-- необходимо знакомство с ассемблером и Cи. Сейчас С-- умеет генерировать 32-битный код под ДОС и Windows (прим. ред. а также под MenuetOS, KolibriOS).
Автором языка SPHINX C-- является Peter Cellik (CANADA). Последняя авторская версия SPHINX C-- v0.203 от 28.Oct.96. К сожалению автор отказался от дальнейшего развития языка. Сам язык вместе с исходные текстами был объявлен сиротой и отдан никому в никуда. Т.е. делайте что хотите. А почему бы и не сделать? На этой страничке Вы найдете самую последнюю (но уже не авторскую) версию самого языка, библиотеки, примеры программ, описание самого языка и библиотек в формате Notron Guide и много другой полезной информации по языку C--.
После Питера Селлика поддержкой занимался Михаил Шекер, но он прекратил разработку несколько лет назад. В прошлом году исходники были выложены на Github https://github.com/jossk/c--sphinx, но мы узнали об этом только в марте 2016 года.
Было решено рассказать о данном языке по двум причинам:
- На нём написаны несколько популярных программ KolibriOS, среди которых и Eolite — пожалуй, самый используемый файловый менеджер.

- Относительно недавно компилятор данного языка был портирован для KolibriOS (ответ на вопрос о лицензии можно найти тут).
Немного о процессе портирования от GerdtR:
Итак. Сначала я переделал код под gcc. Исходники просто были написаны для Watcom C, ну и пусть не значительная, но несовместимость была. Исправил пару названий переменных(extern в ваткоме можно, видимо), и обозначение 64битных чисел по другому. Потом уже Leency выявил, что gcc-версия совсем не ищет файлы в текущей папке, только в папке с самим экзешником. Когда и это исправил осталось самое сложное: порт для Колибри. Ну так как под С я в КОС не писал, то была стандартная проблема — с кем линковать, да и какие инклудники брать. Выбор не широкий, menuetlibc отпал сразу, как я, покопавшись в исходниках, увидел ещё старые функции обращения к файлам(ф56 вроде). Короче menuetlibc устарел сильно, остался newlib. Долго разбирался, как всё таки на выходе получить kex, а не PE, помог один Makefile, где писалась дополнительно обработка objcopy. Ну а дальше уже дописывание функций, которых нет в newlib(например stat не было, в port.c лежит его реализация). Ну и пара функций преобразования кодировок ANSI->ASCII, а точнее заглушек, потому как русских букв всё равно в строках компилятора нет. Ну и последней проблемой было, да и частично осталось вот это: из-за newlib(скорее всего, больше некому) текущий каталог устанавливается как путь до самого сmm(а обычно /rd/1), потому оказывается, что узнать, где лежит исходник компилятор не может, хоть откуда его запускай. Выход на данный момент — копировать компилятор в папку с исходниками, либо указывать абсолютный путь. Кстати, раньше символ '/' считался началом параметра и абсолютный путь указать было не возможно, сейчас можно. Но с абсолютным путём пока не уверен, что инклудники находить будет. Пока что-то не хочется с этим возиться, да и можно просто написать -IP="/hd1/1/my_source". В теории должно работать, на практике никто не спрашивал. Кстати… указать в форуме что ли, что параметры через '-' указывать теперь… И при запуске без параметров, в той таблице поправить, а то некоторая путаница получается. Ладно, потом как-нибудь. Ну вот в общем, вся история. Самое сложное было — это разобраться, откуда брать либы :) Сам код довольно несложный, не в супер порядке, но особо ковыряться в коде не пришлось
Руководство по языку находится по ссылке http://www.c--sphinx.narod.ru/c--doc.htm. Рассмотрим пример простого приложения для KolibriOS:
#define MEMSIZE 4096*10 #include "../lib/io.h" #include "../lib/gui.h" void main() { word id; dword file; io.dir.load(0,DIR_ONLYREAL); loop() switch(WaitEvent()) { case evButton: id=GetButtonID(); if (id==1) ExitProcess(); break; case evKey: GetKeys(); if (key_scancode == SCAN_CODE_ESC ) ExitProcess(); break; case evReDraw: draw_window(); break; } } void draw_window() { proc_info Form; int i; DefineAndDrawWindow(215,100,350,300,0x34,0xFFFFFF,"Window header"); GetProcessInfo(#Form, SelfInfo); for (i=0; i<io.dir.count; i++) { WriteText(5,i*8+3,0x80,0xFF00FF,io.dir.position(i)); } DrawCaptButton(100, 10, 100, 22, 22, 0xCCCccc, 0x000000, "Button"); WriteText(100,50,0x80,0,"Textline small"); WriteText(100,70,0x90,0,"Textline big"); DrawBar(100, 110, 100, 100, 0x66AF86); }

Как видите, данный код почти не отличается от кода на Си, но при этом есть возможность писать спокойно в почти ассемблерном стиле, аналогично написанию оберток для системных функций. Например, функция создания окна:
void DefineAndDrawWindow(dword x, y, size_w, size_h, byte WindowType,dword WindowAreaColor, EDI, ESI) { EAX = 12; EBX = 1; $int 0x40 $xor EAX,EAX EBX = x << 16 + size_w; ECX = y << 16 + size_h; EDX = WindowType << 24 | WindowAreaColor; $int 0x40 EAX = 12; EBX = 2; $int 0x40 }
Чем же он привлекателен для разработчиков ПО для KolibriOS? Во-первых тем, что начать писать на нём очень легко. Это был единственный язык, не считая FASM, на котором можно было просто начать писать, не заморачиваясь с настройкой кросс-компиляции (сейчас в этом деле Си уже набирает обороты). Во-вторых, для C-- было написано множество библиотек и различных оберток над системными функциями. Среди них собственный набор элементов интерфейса и даже неплохие шрифты:

Вы наверняка зададитесь вопросом: если всё так прекрасно, то в чем же проблема? Почему он не применяется повсеместно, хотя бы в рамках проекта KolibriOS?
Ответ следующий. Несмотря на преимущество в простоте освоения, при его использовании всплывают и недостатки:
- плохая оптимизация результирующего кода;
- практически отсутствуют приоритеты операций (C-- всё считает слева направо, т.е. 2+2*2=8, а не 6);
- самое главное, хоть он и похож на Си, но это другой язык программирования со своей сферой применения. В рамках KolibriOS он наиболее подходит для создания программ с графическим интерфейсом и почти не применяется в системном программировании.

