Несколько лет назад я успешно преобразовал устаревшую 23 000-летнюю базу кода LOC 300 000 в camelCase. Это заняло всего два дня. Но было несколько затяжных аффектов, которые потребовались пару месяцев, чтобы разобраться. И это очень хороший способ раздражать ваших коллег-кодеров.
Я считаю, что простой, тупой, подобный седу подход имеет преимущества. Насколько мне известно, инструменты на основе IDE и т. П. Не могут:
- изменить код не скомпилировано с помощью # ifdef's
- изменить код в комментариях
А устаревший код нужно было поддерживать на нескольких разных платформах компилятора / ОС (= много #ifdefs).
Основным недостатком глупого, подобного седу подхода является то, что строки (например, ключевые слова) могут быть случайно изменены. И я сделал это только для C; C ++ может быть еще одним котелком рыбы.
Есть около пяти этапов:
1) Generate a list of tokens that you wish to change, and manually edit.
2) For each token in that list, determine the new token.
3) Apply these changes to your code base.
4) Compile.
5) Double-check via a manual diff, and do a final clean-up.
На шаге 1, чтобы сгенерировать список токенов, которые вы хотите изменить, введите команду:
cat *.[ch] | sed 's/\([_A-Za-z0-9][_A-Za-z0-9]*\)/\nzzz \1\n/g' | grep -w zzz | sed 's/^zzz //' | grep '_[a-z]' | sort -u > list1
будет производить в списке 1:
st_atime
time_t
...
В этом примере вы действительно не хотите менять эти два токена, поэтому отредактируйте список вручную, чтобы удалить их. Но вы, вероятно, пропустите некоторые из них, поэтому ради этого примера предположим, что вы сохраняете их.
Следующим шагом, 2, является создание сценария для внесения изменений. Например, команда:
cat list1 | sed 's/\(.*\)/glob_sub "\\<\1\\>" xxxx_\1/;s/\(xxxx_.*\)_a/\1A/g;s/\(xxxx_.*\)_b/\1B/g;s/\(xxxx_.*\)_a/\1C/g;s/\(xxxx_.*\)_t/\1T/g' | sed 's/zzz //' > list2
изменит _a, _b, _c и _t на A, B, C и T, чтобы произвести:
glob_sub "\<st_atime\>" xxxx_stAtime
glob_sub "\<time_t\>" xxxx_timeT
Вы просто должны расширить его, чтобы охватить d, e, f, ..., x, y, z,
Я предполагаю, что вы уже написали что-то вроде 'glob_sub' для своей среды разработки. (Если нет, откажитесь сейчас.) Моя версия (csh, Cygwin) выглядит так:
#!/bin/csh
foreach file (`grep -l "$1" */*.[ch] *.[ch]`)
/bin/mv -f $file $file.bak
/bin/sed "s/$1/$2/g" $file.bak > $file
end
(Некоторые из моих sed не поддерживают опцию --in-place, поэтому я должен использовать mv.)
Третий шаг - применить этот скрипт в списке list2 к вашей базе кода. Например, в csh используйте source list2
.
Четвертый шаг - компиляция. Компилятор будет (надеюсь!) Возражать против xxxx_timeT
. Действительно, он, скорее всего, должен возражать против timeT
, но дополнительные xxx_
добавляют страховку. Так что для time_t вы ошиблись. Отмените его, например,
glob_sub "\<xxxx_timeT\>" time_t
Пятым и последним шагом является ручная проверка ваших изменений с использованием вашей любимой утилиты diff, а затем очистка путем удаления всех нежелательных префиксов xxx_
. Grepping для "xxx_
также поможет проверить наличие токенов в строках. (Действительно, добавление суффикса _xxx, вероятно, является хорошей идеей.)