LINUX.ORG.RU

Kaitai Struct 0.5

 , , ,


7

5

После трёх месяцев разработки состоялся релиз Kaitai Struct 0.5 — языка описания форматов структур данных. Идея проекта состоит в том, что описав структуру формата файла или сетевого протокола единожды на формальном языке .ksy, можно скомплировать такое описание в исходный код парсера на любом поддерживаемом языке программирования.

Список нововведений внушительный, самые заметные из них:

  • полная поддержка C++/STL;
  • поддержка новых целевых языков PHP7 (благодаря ProtoH) и Perl;
  • генерация GraphViz-диаграмм для форматов (ранние примеры демонстрировались в галерее);
  • новые возможности языка: switch-подобная конструкция для типов (чтобы не писать много условий), атрибут doc (для генерации документации в комментариях на целевом языке), цикл repeat-until, поддержка булевых типов, поддержка операций с объектом потока из языка выражений (_io.eof, _io.size, _io.pos);
  • существенное улучшение строгости парсинга .ksy компилятором, понятные сообщения об ошибках;
  • работа консольного визуализатора на Windows.

Семейство инструментов, поддерживающих Kaitai Struct, пополнилось:

Как всегда, доступна онлайн-версия на JavaScript, в которой можно поэкспериментировать с компилятором без установки.

>>> Подробности

★★

Проверено: Falcon-peregrinus ()
Последнее исправление: sudopacman (всего исправлений: 1)
Ответ на: комментарий от coyotl

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

GreyCat ★★
() автор топика
Ответ на: комментарий от kirk_johnson

Эээ... растующие массивы это reallocarray и структура.

Растущие массивы - это всякие GArray в glib, gsl_vector в gsl или там kvec в klib. Чтобы был четкий и понятный способ передать «единым комплектом» сразу некую структуру, из которой бы можно было понять, сколько элементов в массиве, пройтись по нему вперед-назад, чтобы можно было адресоваться по номеру и т.д. И чтобы всем нравилось. А с этим тяжко :(

GreyCat ★★
() автор топика
Ответ на: комментарий от GreyCat

Растущие массивы - это всякие GArray в glib, gsl_vector в gsl или там kvec в klib. Чтобы был четкий и понятный способ передать «единым комплектом» сразу некую структуру, из которой бы можно было понять, сколько элементов в массиве, пройтись по нему вперед-назад, чтобы можно было адресоваться по номеру и т.д. И чтобы всем нравилось. А с этим тяжко :(

struct array {
    int    *elms;
    size_t  elms_cnt;
};

int array_add_elm(size_t pos, int value);
int array_get_elm(size_t pos, int *result);
int array_del_elm(size_t pos);

Функции сужения / расширения массива напишешь сам. Придется сделать немного макросной магии, чтобы генерировать структуру с даными нужного типа, но с этим, надеюсь, ты справишься.

kirk_johnson ★☆
()
Ответ на: комментарий от Manhunt

Чего только люди ни делают, лишь бы STL не пользоваться.

В C появился STL? Давно?

kirk_johnson ★☆
()
Ответ на: комментарий от kirk_johnson

Окей, а теперь попробуй притащить такое в какой-нибудь C-проект, где уже используется glib или есть подобный нескучный велосипед, и посмотрим, что там на это скажут.

GreyCat ★★
() автор топика
Ответ на: комментарий от GreyCat

Окей, а теперь попробуй притащить такое в какой-нибудь C-проект, где уже используется glib или есть подобный нескучный велосипед, и посмотрим, что там на это скажут.

Ну сделай возможность переопределять методы и сам тип.

kirk_johnson ★☆
()
Ответ на: комментарий от kirk_johnson

Ну сделай возможность переопределять методы и сам тип.

Значит, нужно придумывать какую-то возможность внутреннее устройство типа и спецификации методов. А они все на самом деле сильно различаются. Например, в glib:

struct GArray {
  gchar* data;
  guint len;
};

// новый чистый массив
GArray* g_array_new(gboolean zero_terminated, gboolean clear_, guint element_size);
// новый массив явно указанной длины
GArray* g_array_sized_new(gboolean zero_terminated, gboolean clear_, guint element_size, guint reserved_size);
// добавить в конец
#define g_array_append_val(a,v)
// получить указатель по индексу элемента
#define g_array_index(a,t,i)
// освободить массив
gchar* g_array_free(GArray* array, gboolean free_segment);

А вот, для сравнения, в klib:

// единого типа нет, структура определяется каждый раз явно макросом с параметром type
struct {
  size_t n; // сколько элементов allocated
  size_t m; // сколько элементов реально занято
  type *a;
}

// новый чистый массив
#define kv_init(v)
// новый массив явно указанной длины делается через чистый + resize
// сам resize
#define kv_resize(type, v, s)
// добавить в конец
#define kv_push(type, v, x)
// получить элемент по индексу (не указатель!)
#define kv_A(v, i)
// освободить массив
#define kv_destroy(v)

Общего мало. Формат структуры разный, методика инициализации разная, хранится разное, где-то что-то сделано макросами, где-то - функциями. Параметры разные и т.д.

Но в целом, наверное, да, в этом направлении надо двигаться, только тяжко.

GreyCat ★★
() автор топика
Ответ на: комментарий от GreyCat

для поддержки таких штук, как банальных штук

Судя по всему вы сейчас плотно работаете над хаскелем. Я прав?

phoen ★★
()
Ответ на: комментарий от GreyCat

Кстати, а почему тогда бы не подтянуть glib? И так много где используется. Или хотите меньше зависимостей для сгенерированного парсера?

h4tr3d ★★★★★
()
Ответ на: комментарий от h4tr3d

Ключевая фраза - «И чтобы всем нравилось». glib, к сожалению, даже не в 40-50% проектов используется - хорошо если в 5-7%. Хотя, да, наверное, с glib надо начинать.

GreyCat ★★
() автор топика
Ответ на: комментарий от GreyCat

Можно для C сделать несколько вариантов, с glib, klib, и что там ещё бывает.

Kaitai

Заполярные виабу?

anonymous
()
Ответ на: комментарий от GreyCat

Ну всё, что Gtk - glib уже есть. Qt тоже что-то от glib берёт. Консольные утилиты? Демоны? Тут не берусь судить, но судя по данным apt зависящих от glib немало:

$ apt rdepends libglib2.0-0 | grep -v glib | sort | uniq | wc -l
3050

а всего у меня пакетов поставлено 4707.

Выборка, конечно, так себе, но каждый проверить может.

h4tr3d ★★★★★
()
Ответ на: комментарий от h4tr3d

Все, что будет на Qt, будет скорее всего хотеть использовать отдельную C++ реализацию, но не на STL, а на Qt core. Когда-нибудь у нас, надеюсь, будет «cpp_qt», кроме «cpp_stl».

Потыкайте лучше прямо руками какую-нибудь выборку из тех, кто (1) написан на C, (2) как-то связан с парсингом каких-либо нетривиальных бинарных форматов. Что это будут за программы?

GreyCat ★★
() автор топика
Ответ на: комментарий от GreyCat

Не хватает базовых типов данных

glibc тоже не хватит?

строки или растущие массивы

А если у меня протокол не использует строки и массивы всегда вида TLV? Неполная поддержка С лучше, чем вообще никакой.

zabbal ★★★★★
()
Ответ на: комментарий от zabbal

glibc тоже не хватит?

0. точно glibc, а не glib? 1. glibc у нас есть, например, на Android или Windows? 2. glibc у нас внезапно реализует какие-то типы данных? насколько я помню, там все как раз по хардкору через char* и void*

Неполная поддержка С лучше, чем вообще никакой.

«Хотя какая-то» поддержка C и так фактически есть - пожалуйста, собирай с C++/STL, линкуйся с libstdc++ и вызывай _ZN20foo_tC1EPN6kaitai7kstreamEPNS0_7kstructEPS_ - никто не запрещает.

Бросаться делать «неполную» поддержку смысла, не продумав до конца основные концептуальные вопросы - бессмысленно. Ну, будет оно, может быть, проходить 2-3 теста из наших текущих 57. Для того, чтобы проходило остальные, надо все-таки все продумать, а потом выкинуть то, что есть и переписать все в новой парадигме.

GreyCat ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.