Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dupfind #22

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Dupfind #22

wants to merge 2 commits into from

Conversation

jcdkiki
Copy link
Collaborator

@jcdkiki jcdkiki commented Mar 13, 2024

В общем, написал критерий для дублирования кода отдельной программой. Не помню уже почему не получилось написать его как полноценный критерий для оклинта. МОЖЕТ БЫТЬ потом попробую снова. Но сейчас меня положение дел +- устраивает.

Этот "критерий" лежит в папке dupfind

make собирает его в текущей директории
make clean удаляет его из этой директории
sudo make install устанавливает его в /usr/local/bin
sudo make uninstall удаляет его оттуда

Как он работает?

Рассматривает поочередно строки. Если строка с номером N не похожа на все остальные, тогда создает группу с номером N. Если строка похожа на какую-то другую с номером M < N, тогда добавляет эту строку в группу M.

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

Как его использовать?

jcdkiki@pc:~/code/oclint_extensions/dupfind$ dupfind -h
Usage: dupfind [options] <file1> <file2>...
options:
  --show           show code that was duplicated
  --maxskip X      maximum allowed number of lines to skip
  --similarity X   similarity threshold (in percent)
  --reportlen X    minimal length of sequence to report it

Без дополнительных флагов результат может выглядеть следующим образом:

/home/jcdkiki/code/pr-2023-3384/Kuzmin_Kirill_lb1/src/main.c: [21, 24] duplicates [10, 13]

С помощью флага --show можно включить вывод продублированных частей кода:

/home/jcdkiki/code/pr-2023-3384/Kuzmin_Kirill_lb1/src/main.c: [21, 24] duplicates [10, 13]
...
     int ind = -1;
     for (int i = 0; i < n; i++){
         if (arr[i] < 0) {
             ind = i;
...
     int ind = -1;
     for (int i = n-1; i > 0; i--){
         if (arr[i] < 0) {
             ind = i;
...

Остальные опции:

  • --maxskip X: устанавливает максимальный размер "дыры" в последовательности. Может быть полезно, когда в последовательность, полученную путем ctrl+c ctrl+v, добавляется одна уникальная строчка, и это ломает алгоритм. Можно поставить maxskip равным 1 и тогда это строку можно будет "перепрыгнуть" и не потерять конец последовательности.
  • --similarity X: устанавливает порог "сходства" строк в процентах. Строки считаются идентичными и будут принадлежать одной группе, если процент их сходства больше или равен этому параметру.
  • --reportlen X: устанавливает минимальную длину последовательности, о которой следует сообщать. То есть если установить reportlen равным X, то последовательности-дубликаты длины меньшей X не будут считаться ошибкой.

Проверял этот критерий на репозитории pr-2023-3384, выглядит как +- рабочее решение. Если и появляются какие-то ложные срабатывания, то можно поиграться со флагами.

}).base(), s.end());
}

int str_distance(std::string &a, std::string &b)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Учтено ли в алгоритме то что в строках может быть разное число whitespace символов?

for i in $(find $1 -iname "*.c")
do
./dupfind --similarity 90 --show $i
done
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Как планируется этот прототип подключать к oclint?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants