2010-07-31 31 views
6

Tôi có một số tệp nguồn C đang dần mở rộng. Tôi có xu hướng giữ nguyên mẫu với tài liệu trong tệp .h theo thứ tự tốt, được nhóm thành các chức năng và loại có liên quan với #pragma mark. Mã được viết và ghi lại theo cách yêu cầu đọc tệp .h cùng với tệp .c. Tôi muốn các tập tin được sắp xếp theo cách tạo điều kiện này.Có công cụ nào để giữ các tệp nguồn C của tôi theo thứ tự không?

Có cách nào để giữ các khai báo hàm trong tệp .c theo thứ tự giống như các nguyên mẫu của chúng trong tệp .h không? Tôi đang tìm một công cụ để đọc tệp .h (với #pragma mark s nếu có thể) và sắp xếp lại tệp .c tương ứng.

Có thể?

+0

Công cụ này nên làm gì với các phần tử trong tệp '.c' không có phần tử tương ứng trong tệp' .h'? Ví dụ, các hàm tĩnh có thể liên quan đến các hàm toàn cầu và được đặt trước hoặc sau chúng. – jilles

+0

Không có trong danh sách yêu cầu. Nếu một công cụ đáp ứng các yêu cầu trên không tồn tại, tôi chắc chắn rằng nó sẽ có thể xử lý trường hợp này. – Joe

Trả lời

1

Tôi đã thực hiện mã băm nhỏ trước đây. Điều gần nhất bạn có thể nhận được là viết một (Theo như tôi biết). Sử dụng API phân tích tĩnh, bạn có thể phân tích cú pháp mã nguồn của mình, sau đó dựa trên mã trong mỗi tệp tiêu đề tổ chức tất cả các tệp trong tệp .c tương ứng.

Một công ty được gọi là SciTools gửi một bộ phân tích mã nguồn được gọi là 'hiểu 4 C++' có API C khiến việc này trở nên dễ dàng. Nhưng có lẽ bạn sẽ phải tự mình viết công cụ. Vì nó là, tôi đã viết một API được quản lý nằm trên đầu trang của API C của họ. Quản lý của tôi được tìm thấy trên codeplex tại đây: http://understandapi.codeplex.com/

Đây là cách tôi sẽ cấu trúc chương trình.

  1. Trước tiên, bạn phải tạo cơ sở dữ liệu về tất cả mã nguồn của mình. Bạn có thể làm điều này bằng cách sử dụng một tập lệnh batch nếu bạn muốn, hoặc một kịch bản PowerShell, hoặc bạn có thể tự mình làm điều đó. Nó thường đơn giản như chỉ vào một thư mục và có hiệu lực nói 'làm cho một cơ sở dữ liệu của tất cả các tập tin trong đó'. Bạn có thể xác định xem bạn có muốn tệp * .c, * .h hoặc * .cpp trong cơ sở dữ liệu của mình không.

  2. Sau đó, sử dụng API, bạn có thể duyệt tất cả các tệp có đuôi tệp .h.

  3. Đối với mỗi tệp tiêu đề, bạn xác minh có tệp .c tương ứng. Điều này được thực hiện bằng cách lấy một chuỗi tên tệp, thay thế phần mở rộng của tệp (.NET làm việc này dễ dàng) và kiểm tra xem tệp có tồn tại hay không. Nếu nó tồn tại, sau đó chuyển sang bước tiếp theo.

  4. Sau đó, chương trình sẽ lặp qua tất cả các thực thể được xác định trong tệp .h.

  5. Đối với mỗi thực thể, sau đó tìm thấy tham chiếu đến định nghĩa của nó (không khai báo) và xem liệu nó có tồn tại trong tệp .c tương ứng hay không. Nếu nó ở đó, nó sẽ tìm ra số dòng của định nghĩa mã, và mở tệp để đọc và đọc các dòng mã cần thiết (và các nhận xét cũng vậy) và ghi chúng ra một tệp tạm thời.

  6. Khi hoàn tất, hãy ghi đè tệp .c bằng tệp tạm thời.

  7. Tiếp tục với phần còn lại của tệp trong cơ sở dữ liệu.

Bây giờ nó không phải là dễ dàng. Bạn có thể gặp rắc rối trên đường đi theo hình thức: 1. Mã được biên dịch theo điều kiện, trong trường hợp này nó sẽ khó phân tích hơn, mặc dù nó có thể.Hiểu 4 C++ phân tích cú pháp các chỉ thị biên dịch có điều kiện và phân biệt giữa mã không hoạt động và hoạt động. Nhưng chỉ cần xử lý điều này sẽ làm cho nó thực sự khó khăn. 2. Không gian tên - Điều này sẽ làm phức tạp vấn đề.

Tuy nhiên, nếu bạn chỉ quan tâm đến việc tổ chức mã giữa các chỉ thị #pragma nhất định, điều đó có thể đơn giản hóa vấn đề một lần nữa.

Hãy cho tôi biết nếu bạn quan tâm nhiều hơn và chúng tôi nói chuyện riêng tư ngoại tuyến.

+0

Cảm ơn bạn đã trả lời. Tôi đang làm việc với C không phải C++, vì vậy chúng tôi chỉ nói các hàm, typedefs, structs, enums vv. Tôi nghĩ nếu tôi đã viết công cụ của riêng mình (tôi có thể làm điều đó) nó sẽ khá đơn giản, và theo cùng một loại bước (ít biến chứng C++). Tôi viết với một phong cách nhất quán, do đó, viết một số Python để cắt những thứ lên và đặt chúng lại với nhau như dây (không phải ASTs!) Sẽ không được khó khăn. – Joe

+0

Chúng ta hãy xem, công cụ này cũng làm C. Nó cũng làm ADA, Java, C#, Fortran, và một vài chi tiết bên cạnh tôi nghĩ. Ngoài ra nó chạy trên một loạt các hệ điều hành. –

1
  • Sử dụng IDE tốt ... Sẽ không cần giữ lại thứ tự trong tệp tiêu đề/tệp được căn chỉnh.

  • Nếu vẫn không phù hợp với bạn ... Giữ tất cả các khai báo và định nghĩa trong thứ tự chữ cái. Khi bạn thêm một hàm mới, bạn biết vị trí chèn hàm mới .

    P.S. Tôi tin rằng trong http://www.dmoz.org/ nói ::

    Humans Do it better 
    
+0

Con người có thể làm điều đó tốt hơn (có thể tranh cãi), nhưng chúng chậm hơn và tốn kém hơn! – Christo

+0

Bởi 'sử dụng một IDE tốt', bạn có nghĩa là một trong đó cho phép nhảy xung quanh mã nguồn? Tôi đang viết trong Xcode mà là tốt, nhưng tôi muốn mã có thể đọc được trong một trình soạn thảo văn bản trên bất kỳ nền tảng nào. Tôi thà gánh vác công việc vào cuối sản xuất để làm cho cuộc sống của người đọc dễ dàng hơn, không nói 'sử dụng một IDE tốt'. – Joe

+0

Và liên quan đến điểm thứ hai của bạn, tôi đặt các hàm theo thứ tự nhất định, ví dụ như xây dựng/hủy bỏ ADT, kiên trì, hoạt động trên ADT, vv. – Joe

1

tôi nghi ngờ bạn sẽ tìm thấy một công cụ như thế này off-the-shelf. Vì vậy, bạn cần một công cụ tùy chỉnh. Bạn không muốn thử làm điều này với một số phương pháp lấy cắp chuỗi (ví dụ: Perl) vì các chi tiết chính xác phân tích cú pháp C và C++ vượt xa những gì bạn có thể tin cậy theo cách này. Nếu bạn không nhớ chuỗi hacking làm hỏng các tập tin của bạn đôi khi, có thể bạn có thể nhận được đi với điều này.

Công ty của tôi DMS Software Reengineering Toolkit có thể được sử dụng để thực hiện điều này một cách đáng tin cậy.

DMS là công cụ chung để phân tích cú pháp, phân tích và chuyển đổi mã nguồn bằng cách sử dụng công nghệ trình biên dịch được tham số hóa bằng định nghĩa ngôn ngữ rõ ràng. DMS có định nghĩa ngôn ngữ mạnh mẽ cho nhiều ngôn ngữ, bao gồm C và C++ trong nhiều ngôn ngữ. Sử dụng kết thúc trước của DMS C hoặc C++, bạn có thể phân tích mã nguồn , xây dựng cấu trúc dữ liệu trình biên dịch được gọi là AST, thực hiện phân tích mã, chuyển đổi AST, và sau đó tạo lại mã compilable bao gồm cả nhận xét và tất cả chỉ thị prepreprocessor.

Thông báo trước phải làm với việc phân tích mã nguồn chứa các chỉ thị tiền xử lý: chúng phải được cấu trúc tốt [ví dụ: #ifdef #endif cần lồng xung quanh các câu lệnh khác giống như thường lệ nếu, v.v ... trái ngược với việc được sử dụng trên một đường biên báo cáo. Điều này xảy ra một số trong mã C; nhiều hơn ít hơn trong mã C++. Kinh nghiệm của chúng tôi là nếu bạn sẵn sàng sửa đổi mã nguồn C của bạn, bạn có thể làm cho vấn đề cụ thể này biến mất.

Đối với nhiệm vụ cụ thể của bạn, bạn làm khá nhiều là câu trả lời cho khoa học Toolworks mô tả:

  1. Chọn một đơn vị biên soạn, và phân tích nó bằng DMS. Bạn phải cung cấp tất cả thông tin giống nhau bạn cung cấp trình biên dịch, do đó, nó có thể định vị tệp tiêu đề, v.v.
  2. DMS tạo AST cho cả đơn vị biên dịch của bạn và cho tất cả các tệp tiêu đề.
  3. Đi bộ AST để trích xuất thứ tự khai báo trong tiêu đề và đơn vị biên dịch.
  4. Tái cấu trúc cây đơn vị biên soạn theo trình tự có nguồn gốc từ 3)
  5. prettyprint đơn vị biên soạn kết quả AST

[Một lý do để làm điều này với DMS chứ không phải là khoa học Toolworks được rằng DMS được thiết kế để phân tích cú pháp/chuyển đổi/tái tạo mã, trong khi SciTool IMHO thực sự chỉ được thiết kế để phân tích cú pháp và phân tích. DMS cung cấp quyền truy cập vào các chi tiết đẹp cần thiết để chuyển đổi mà SciTools không, ít nhất không phải là lần cuối cùng tôi nhìn].

Các biến chứng sẽ xảy ra do có điều kiện, macro, không gian tên, ... nhưng bạn sẽ quyết định chính sách để giải quyết. Ví dụ, nếu một tệp tiêu đề có một dấu #if ... #else .... #endif và các khai báo trong mệnh đề sau đó có thứ tự khác với thứ tự của chúng trong mệnh đề else, thứ tự mong muốn là gì? Điều gì xảy ra nếu định nghĩa hàm được tạo bởi macro trong tiêu đề? Nhưng, tất cả những điều này khiến cho việc xây dựng một công cụ thực sự, er, vui vẻ là .

Ý kiến ​​cá nhân của tôi là điều này có vẻ như khá nhiều công việc cho hiệu quả bạn đang nhận được. Nếu bạn thực hiện tất cả việc này, quy trình kỹ thuật phần mềm của bạn sẽ tốt hơn bao nhiêu? Chúng tôi thường sử dụng DMS để kiểm tra lỗi mã hóa hoặc thay đổi mã theo cách mà mọi người không thể (ví dụ: chèn công cụ thời gian chạy lời khuyên tạm thời hoặc AOP), nơi rõ ràng là động cơ cơ khí đã thanh toán.

+1

Tôi muốn có được đôi tay của mình trên DMS này đôi khi. Tôi đã quen thuộc với API của SCI, nhưng tôi luôn tìm cách mở rộng sự hiểu biết về công cụ này. –

Các vấn đề liên quan