2 голоса
 
773 просмотра
16.01.2017 / 17:26  Ginosaji

Поиск сигнатуры функции как в (git) diff

Вопрос интересующимся парсингом. git diff и утилита diff (с некоторой опцией) в выводе показывает первую строчку объявления функции. В C точно, в Java - не проверял. Пример: добавили строчку в довольно большую функцию и посмотрели git diff
  1. $ git diff
  2. diff --git a/cmd.c b/cmd.c
  3. index d3594bb..e37ab35 100644
  4. --- a/cmd.c
  5. +++ b/cmd.c
  6. @@ -1359,6 +1359,7 @@ int blablabla(struct blablaparam *param,
  7.         ...
  8. +       LOG("");
  9. ...
В заголовке есть сигнатура функции (её первая строчка точнее, это не важно). Предложите алгоритм, как diff производит поиск сигнатуры той функции , в которой было изменение.

Мне лень по исходникам гита лазить, может здесь быстрее ответят. Желательно шустрый алгоритм и без загрузки всего исходника в память для последующей обработки. Работать должно, если объявление функции занимает и одну, и несколько строчек.
Ответы
 
0 голосов
 
# 16.01.2017 / 22:26  Naik
Можно брать первую строку сверху изменения, в котор ой на 4 пробела меньше в начале
17.01.2017 / 00:07  Ginosaji
Минусы: чтобы такой дифф сработал, надо соблюдать строго такой стиль оформления. А если принято восемь отступов? А если не пробелами, а табуляцией? А если изменение было в блоке if, вложенном в цикл for? А если изменение было не в функции, а макрос поменяли, то что нам такой код "найдёт"? Решение должно быть универсальным.
 
0 голосов
 
# 16.01.2017 / 17:58  Ксакеп
diff работает с текстом, а не с исходниками си, тот факт, что он выдал сигнатуру — это следствие того, что ты изменил строчку с сигнатурой функции (так вышло случайно). Такого рода алгоритмы основываются на редакционном расстоянии (типа расстояния Левенштейна), возможно, оно тебе и нужно.

Если же тебе нужен diff AST, то на данный момент это нужно делать ручками (но использовать имеющиеся парсеры), хотя есть академические проекты, которые занимаются таким, но они не production-ready.
Изм. Ксакеп от 16.01.2017 / 17:59
16.01.2017 / 20:04  Ginosaji
тот факт, что он выдал сигнатуру — это следствие того, что ты изменил строчку с сигнатурой функцииНет, сигнатуру я не менял. Я в примере добавил только "LOG(...)" в большой функции.

Посмотрел в исходниках diff: там балуются с регекспами при опции show-c-function, как я и думал. Вопрос закрыт.
Всего: 2

Реклама

Мы в соцсетях

tw tg yt gt