Một vài năm trước, tôi đã chuyển thành công một mã 300.000 LOC cơ sở 23 tuổi di sản thành camelCase. Chỉ mất hai ngày. Nhưng có một vài ảnh hưởng kéo dài mất vài tháng để phân loại. Và nó là rất cách tốt để làm phiền các lập trình viên đồng nghiệp của bạn.
Tôi tin rằng cách tiếp cận đơn giản, câm, giống như sed có lợi thế.IDE dựa trên các công cụ, và như thế, không thể, như xa như tôi biết:
- thay đổi mã không biên soạn thông qua mã thay đổi
- # ifdef trên comment
Và mã di sản có được duy trì trên một số nền tảng trình biên dịch/hệ điều hành khác nhau (= rất nhiều #ifdefs).
Chính bất lợi bất lợi của một cách tiếp cận câm, giống như sed là các chuỗi (chẳng hạn như từ khóa) vô tình có thể bị thay đổi. Và tôi chỉ làm điều này cho C; C++ có thể là một loại cá khác.
Có khoảng năm giai đoạn:
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.
Đối với bước 1, để tạo ra một danh sách các thẻ mà bạn muốn thay đổi, lệnh:
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
sẽ sản xuất trong list1:
st_atime
time_t
...
Trong mẫu này, bạn thực sự không muốn thay đổi hai mã thông báo này, vì vậy hãy chỉnh sửa danh sách theo cách thủ công để xóa chúng . Nhưng bạn có lẽ sẽ bỏ lỡ một số, vì vậy, vì lợi ích của ví dụ này, giả sử bạn giữ chúng.
Bước tiếp theo, 2, là tạo tập lệnh để thực hiện các thay đổi. Ví dụ, lệnh:
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
sẽ thay đổi _a, _b, _C, và _T đến A, B, C và T, để sản xuất:
glob_sub "\<st_atime\>" xxxx_stAtime
glob_sub "\<time_t\>" xxxx_timeT
Bạn chỉ cần mở rộng nó để bìa d, e, f, ..., x, y, z,
Tôi giả sử bạn đã viết một cái gì đó như 'glob_sub' cho môi trường phát triển của bạn. (Nếu không, bỏ ngay bây giờ.) Phiên bản của tôi (csh, Cygwin) trông giống như:
#!/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
(Một số của sed của tôi không hỗ trợ tùy chọn --Trong chỗ, vì vậy tôi phải sử dụng một mv .)
Bước thứ ba là áp dụng tập lệnh này trong danh sách2 vào cơ sở mã của bạn. Ví dụ, trong csh sử dụng source list2
.
Bước thứ tư là biên dịch. Trình biên dịch sẽ (hy vọng!) Đối tượng xxxx_timeT
. Thật vậy, nó có thể sẽ chỉ phản đối timeT
nhưng thêm xxx_
thêm bảo hiểm. Vì vậy, đối với time_t bạn đã phạm sai lầm. Hoàn tác nó với ví dụ:
glob_sub "\<xxxx_timeT\>" time_t
Bước thứ năm và cuối cùng là để làm một kiểm tra thủ công thay đổi của bạn sử dụng tiện ích khác mà bạn yêu thích, và sau đó dọn dẹp bằng cách loại bỏ tất cả các mong muốn xxx_
tiền tố. Tham lam cho "xxx_
cũng sẽ giúp kiểm tra mã thông báo bằng chuỗi. (Thật vậy, việc thêm hậu tố _xxx có thể là một ý tưởng hay.)
có dấu gạch dưới nào trong mã bên cạnh các tên biến không? – drfrogsplat
umm có trong các hằng số, ví dụ:SOME_CONSTANT, những điều này sẽ không phải chịu bất kỳ thay đổi nào. – radman