2010-11-10 52 views
5

Chúng tôi đã kế thừa một dự án rất hợp lý (500kloc) với 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 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#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.

Trả lời

8

Có một công cụ gọi là "unifdef" sẽ thực hiện những gì bạn muốn.

+0

nhanh chóng. cảm ơn! – clord

+0

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

+0

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ì đó. –

0

Bạn chắc chắn nên có một cái nhìn tại boost.wave

từ lời nói đầu boost.wave:

Vì vậy, những mục tiêu chính cho dự án sóng là:

  • đầy đủ phù hợp với C++ tiêu chuẩn (ISO/IEC 14882: 1998) 1 và với tiêu chuẩn C99 (INCITS/ISO/IEC 9899: 1999)
  • việc sử dụng Spirit [4] f hoặc các bộ phận phân tích của trò chơi (chắc chắn :-)
  • sử dụng tối đa của STL và/hoặc tăng cường các thư viện (ví chặt và bảo trì)
  • extendability đơn giản để thực hiện các tính năng bổ sung xây dựng một thư viện linh hoạt cho C++ khác nhau lexing và tiền xử lý cần
Các vấn đề liên quan