LINUX.ORG.RU

Форматирование фрагментов кода с помощью clang-format

 ,


0

1

Здравствуйте.

Имею, можно сказать, текстовый документ, содержащий фрагменты кода на C++. И есть необходимость эти фрагменты подвергнуть автоматическому форматированию с помощью clang-format.

clang-format умеет форматировать часть файла двумя способами:

  • с помощью параметра -lines begin:end
  • с помощью установки в тексте комментариев // clang-format on/off

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

Но у меня возникает проблема с форматированием первых строк кода. Например, если имеем такое содержимое документа:

// clang-format on
for(const auto& element: elements){if(element > 0){element++;}}
// clang-format off
some text
more text
// clang-format on
for(const auto& element: elements){if(element > 0){element++;}}
// clang-format off
some text

то после clang-format-а получаю:

// clang-format on
for(const auto& element: elements)
{
    if(element > 0)
    {
        element++;
    }
}
// clang-format off
some text
    // clang-format on                 <---------------
    for(const auto& element: elements) <---------------
{
    if(element > 0)
    {
        element++;
    }
}
// clang-format off
some text   

т.е. первые пару строк после текста съезжают вправо, что не радует.

Подскажите, это проблема настройки параметров clang-format или же что-то еще? Ну и по возможности подскажите, как исправить))


Директива // clang-format off только указывает, что помеченные строчки не нужно форматировать, но не указывает перестать парсить текст. Clang-format пытается продолжить выражение «more text». Точки с запятой нет, вот и предполагается, что дальше будет продолжение. Попробуй «more text» заменить на «more text;», например.

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

Спасибо, это помогло! Заменил

// clang-format on

на

;// clang-format on

и стало нормально)

Я изначально пытался с помощью python скрипта находить нужные мне фрагменты кода в тексте и скармливал их clang-format-у, но т.к. для каждой операции форматирования запускается отдельный экземпляр clang-format, получается довольно долго. Потом решил пробежаться скриптом по текстовому файлу, выделить фрагменты кода с помощью // clang-format on/off, скормить за раз clang-format-у, потом убрать эти метки скриптом. Получается значительно быстрее. Может быть, есть более оптимальный вариант?)

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

У clang-format есть опция --lines=N:M, которой можно указать диапазон строк, которые нужно форматировать. Документация упоминает, что опция --lines может использоваться много раз, и это добавляет диапазон к списку. По идее, так можно за один запуск отформатировать много кусочков файла. Там же в документации упоминаются ещё опции --offset и --length, для указания диапазонов в байтах, причём так же упоминается, что пар offset+length может быть больше одной.

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

подход с --lines=N:Mимеет свои плюсы, но с ним такая же проблема, как и с // clang-format on/off - если предыдущая строка не заканчивается «;», то форматирование первых строк ломается.

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

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

gogoer ()

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

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

нет. это не результат коммита. Поясню задачу более подробно)

Есть довольно большой файл, около 30К строк. В нем есть все подряд: текст, комментарии, код и др. С++ код в нем можно найти по определенным признакам, например, он начинается с cpp-begin и заканчивается cpp-end.

different text
cpp-begin
if(a>0){b=1};
cpp-end
Text again

так вот хотелось бы отформатировать только C++ код, остальное нужно оставить нетронутым.

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

Нужно просто разрезать файл по разделителям, скормить куски с Си++ кодом форматирующией утилите, склеить кусочки.

Если сильно беспокоит время на запуск clang-format, сделать на его основе разделяемую библиотеку, которую дёргать из скрипта на питоне. Скорее всего, экономия времени не окупит затраты на разработку. Проще будет запускать clang-format на каждый фрагмент.

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

Сейчас я примерно так и делаю, вырезаю в питоновском скрипте фрагмент кода и скармливаю его clang-format, но т.к. фрагментов много и каждый раз запускается новый процесс clang-format, получается довольно долго (в моем случае около 15 сек). Вот и ищу способы ускорить процесс)

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

Рекомендую сделать свою сборку clang-format, которая будет работать как сервер, принимая и выплёвывая по множеству кусочков за один запуск.

i-rinat ★★★★★ ()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.