Chúng tôi đã kế thừa một dự án rất hợp lý (500kloc) với lô của logic điều kiện tiền xử lý, hầu hết trong số đó không còn phù hợp nữa và tôi muốn xóa nó.Xử lý một phần tệp bằng bộ tiền xử lý
Tôi có thể sử dụng bộ tiền xử lý¹ để mở rộng chỉ một số của logic điều kiện và để lại tất cả các macro tiền xử lý khác, xác định và bao gồm một mình trong đầu ra không?
¹ Ở đây, bởi "bộ tiền xử lý", tôi thực sự có nghĩa là "công cụ bất kỳ", bộ tiền xử lý C chuẩn, thứ tôi có thể cài đặt hoặc thậm chí cả tập lệnh Perl hoặc Python bị tấn công.
Ví dụ, giả sử chúng ta có bộ mã này:
#include <foo>
#define baz
#define bar(a) do{(a)+1} \
while(0)
#ifdef X
#if Y > 20
#if Z > 5
so_far_so_good = true;
#endif
#ifdef baz
something();
#endif
#else
otherthing();
#endif
#else
#if Z > 10
wow().this.is.bad;
#endif
#endif
Các công cụ tôi muốn (và có thể cần phải viết nếu nó không tồn tại) sẽ là một phiên bản của CPP chấp nhận không chỉ danh sách các định nghĩa cho một lời gọi cụ thể, mà còn là một danh sách các định nghĩa để tôn trọng trong quá trình mở rộng. Bất kỳ ký hiệu tiền xử lý nào không có trong danh sách thứ hai hoàn toàn bị bỏ lại một mình. Một ví dụ là theo thứ tự:
cpptreadlight -DY=22 --only=Y
sẽ tạo ra:
#include <foo>
#define baz
#define bar(a) do{(a)+1} \
while(0)
#ifdef X
#if Z > 5
so_far_so_good = true;
#endif
#ifdef baz
something();
#endif
#else
#if Z > 10
wow().this.is.bad;
#endif
#endif
và:
cpptreadlight -DY=22 -DZ=8 -DX --only=Y,baz,Z
sẽ cho tôi:
#include <foo>
#define bar(a) do{(a)+1} \
while(0)
#ifdef X
so_far_so_good = true;
something();
#else
#endif
Chú ý rằng mặc dù X
được định nghĩa , nó bị bỏ lại, bởi vì nó không xuất hiện trong danh sách --only
. Cũng lưu ý rằng baz
là trong danh sách --only
và do đó đã được mở rộng sau khi được xác định trong nguồn.
Tôi đã thử một hack-giải pháp: thoát thứ không thú vị bằng cách sử dụng đường ống dẫn như sau (công cụ gsub riêng tôi được sử dụng, nhưng nó không những gì bạn có thể mong đợi):
function escape_tr() {
gsub "#(define|include)" '@@@\1' < $1 |
(echo '#include "simple.h"' && gsub '\\$' "%%%") |
cpp -C -P -DY=301 -DZ > $1.new
}
Bây giờ tôi có thể lọc ra rất nhiều thứ và sau đó đặt những thứ tôi muốn bộ tiền xử lý mở rộng trong simple.h
. Nhận xét chỉ còn lại một mình và các chỉ thị #line
bị bỏ qua.
Điều này gần như thực hiện thủ thuật, trong đó bao gồm không được kéo vào, #define
khối không được xác định và do đó không được mở rộng vào cơ thể. Nhưng tất nhiên nó không cho phép tôi chỉ định tập hợp logic điều kiện mà tôi muốn giữ ở đầu ra. Thật tồi tệ. Một số điều quan trọng là giữ điều kiện.
#if
tổ và các mã thông báo #else
và #endif
không tương xứng với nhau, đặt vấn đề vượt quá đường ống regex. Tôi cần một trình phân tích cú pháp toàn diện, một cái gì đó gần như giống hệt cpp, nhưng với sự kiểm soát chi tiết hơn về những gì được mở rộng.
Do đó, trước khi đào sâu vào một bộ tiền xử lý để thực hiện điều này, tôi nghĩ tôi sẽ hỏi liệu có ai đã giải quyết vấn đề này trước đây không.Tôi không thể là người duy nhất được thừa hưởng một tổ yến tiền xử lý đầy đủ các cành chết.
nhanh chóng. cảm ơn! – clord
Xác nhận rằng điều này kết hợp với kịch bản lệnh shell 'escape_tr' của tôi trong câu hỏi ban đầu có thể thực hiện tất cả các hành động tôi muốn thực hiện trên cơ sở nguồn này. Cảm ơn Paul. Một số thứ như 'cpptreadlight' sẽ tồn tại. Nó tổng quát cả 'unifdef' và' cpp'. – clord
Tôi không chắc tại sao bạn cần 'escape_tr', nhưng có thể tôi đang thiếu thứ gì đó. –