2010-07-31 16 views
6

Mam niektóre pliki źródłowe C, które powoli się rozwijają. Mam tendencję do przechowywania prototypów z dokumentacją w pliku .h w odpowiedniej kolejności, pogrupowane w odpowiednie funkcje i typy z #pragma mark. Kod jest zapisany i udokumentowany w sposób, który wymaga przeczytania pliku .h wraz z plikiem .c. Chciałbym, żeby pliki były sortowane w sposób, który to ułatwia.Czy istnieje narzędzie do porządkowania plików źródłowych C?

Czy istnieje sposób na zachowanie deklaracji funkcji w pliku .c w tej samej kolejności, co ich prototypy w pliku .h? Szukam narzędzia do odczytu pliku .h (z #pragma mark s jeśli to możliwe) i odpowiednio zmienić kolejność pliku .c.

Możliwe?

+0

Co to narzędzie powinno zrobić z elementami w pliku '.c', które nie mają odpowiedniego elementu w pliku' .h'? Na przykład funkcje statyczne mogą być związane z funkcjami globalnymi i znajdować się przed nimi lub po nich. – jilles

+0

Tego nie ma na liście wymagań. Jeśli istnieje narzędzie spełniające powyższe wymagania, jestem pewien, że byłby w stanie obsłużyć tę sprawę. – Joe

Odpowiedz

1

Wykonałem już niszczenie kodu. Najbliższą rzeczą, jaką można uzyskać, jest napisanie jednego (o ile wiem). Za pomocą interfejsu API do analizy statycznej można przeanalizować kod źródłowy, a następnie w oparciu o kod w każdym pliku nagłówkowym uporządkować wszystkie pliki w odpowiednim pliku .c.

Firma o nazwie SciTools wysyła analizator kodu źródłowego o nazwie "understand 4 C++", który ma interfejs API C, co sprawia, że ​​jest to łatwe. Ale prawdopodobnie musiałbyś napisać to narzędzie samodzielnie. W rzeczywistości napisałem zarządzany interfejs API, który znajduje się na szczycie ich C API. Moje zarządzane znajduje się na codeplex tutaj: http://understandapi.codeplex.com/

Oto, w jaki sposób zorganizować program.

  1. Najpierw należy utworzyć bazę danych wszystkich kodów źródłowych. Możesz to zrobić za pomocą skryptu wsadowego, jeśli chcesz, lub skryptu powershell, lub możesz to zrobić samodzielnie. Zwykle jest to tak proste, jak wskazywanie katalogu i w efekcie powiedzenie "stwórz bazę danych wszystkich plików". Możesz określić, czy chcesz mieć w bazie danych pliki * .c, * .h lub * .cpp.

  2. Następnie za pomocą interfejsu API można przeglądać wszystkie pliki z rozszerzeniem .h.

  3. Dla każdego pliku nagłówkowego sprawdzasz, czy istnieje odpowiedni plik .c. Odbywa się to poprzez pobranie ciągu nazwy pliku, zastąpienie rozszerzenia pliku (.NET ułatwia to) i sprawdzenie, czy plik istnieje. Jeśli istnieje, przejdź do następnego kroku.

  4. Następnie program powinien wykonać iterację wszystkich zdefiniowanych elementów w pliku .h.

  5. Dla każdej encji, następnie znajduje odniesienie do jej definicji (nie deklaracji) i zobacz, czy istnieje w odpowiednim pliku .c. Jeśli tam jest, odnajduje numery linii definicji kodu i otwiera plik do odczytu, a także czyta niezbędne linie kodu (oraz komentarze) i zapisuje je do pliku tymczasowego.

  6. Po zakończeniu należy zastąpić plik .c plikiem tymczasowym.

  7. Przejdź do pozostałych plików w bazie danych.

Teraz to nie takie proste. Możesz napotkać kłopoty po drodze w postaci: 1. Warunkowo skompilowany kod, w takim przypadku utrudni to parsowanie, choć jest to możliwe.Zrozumieć, że 4 C++ analizuje kompilację warunkową i rozróżnia nieaktywny i aktywny kod. Ale samo postępowanie z tym sprawi, że będzie to naprawdę trudne. 2. Przestrzenie nazw - to by skomplikowało sprawy.

Jednak jeśli interesuje Cię tylko organizowanie kodu pomiędzy pewnymi dyrektywami #pragma, to może to jeszcze raz uprościć sprawę.

Daj mi znać, jeśli jesteś zainteresowany bardziej, a my porozmawiamy offline prywatnie.

+0

Dziękuję za odpowiedź. Pracuję z C nie C++, więc mówimy tylko o funkcjach, maszynopisach, strukturach, enumach itp. Myślę, że gdybym napisał własne narzędzie (może to zrobić) byłoby to całkiem proste, i podążałem za tymi samymi rodzajami kroki (mniej komplikacji C++). Piszę ze spójnym stylem, więc piszę trochę Pythona, żeby rozbijać rzeczy i składać je razem, ponieważ struny (a nie AST) nie będą trudne. – Joe

+0

Cóż, zobaczmy, to narzędzie też robi C. Robi też ADA, Java, C#, Fortran i jeszcze kilka innych, jak myślę. Działa również na wielu systemach operacyjnych. –

1
  • Użyj dobrego IDE ... Nie będzie potrzeby utrzymywania porządku w pliku nagłówkowym/c wyrównanym.

  • Jeśli to nadal nie wystarcza ... Zachowaj wszystkie deklaracje i definicje w porządku alfabetycznym . Gdy dodajesz nową funkcję, wiesz, gdzie wstawić nową funkcję .

    P.S. Wierzę w http://www.dmoz.org/ mówiąc ::

    Humans Do it better 
    
+0

Ludzie mogą zrobić to lepiej (dyskusyjnie), ale są wolniejsi i drożsi! – Christo

+0

"Używając dobrego IDE" masz na myśli takie, które umożliwia przeskakiwanie wokół kodu źródłowego? Piszę w Xcode, co jest w porządku, ale chcę, aby kod był czytelny w edytorze tekstu na dowolnej platformie. Wolałbym raczej popracować nad końcem produkcji, aby ułatwić życie czytelnikowi, a nie powiedzieć "użyj dobrego IDE". – Joe

+0

Co do drugiej kwestii, umieszczam funkcje w określonej kolejności, na przykład konstrukcja/zniszczenie ADT, trwałość, operacje na ADT itp. Narzucanie sztucznego schematu porządkowania, takiego jak alfabetyczny, nie jest idealne. – Joe

1

Wątpię znaleźć narzędzia takie jak to off-the-shelf. Potrzebne jest więc niestandardowe narzędzie. Nie próbuj tego zrobić przy użyciu metody hackowania ciągów (np. Perl), ponieważ szczegółowe informacje o analizie C i C++ są znacznie wykraczające poza to, co możesz niezawodnie wykonać w ten sposób. Jeśli nie masz nic przeciwko temu, że hakowanie stringów może czasem uszkodzić twoje pliki, może uda Ci się uciec.

Moja firma może DMS Software Reengineering Toolkit może być używana do tego niezawodnie modulo a caveat.

DMS to ogólny silnik do analizowania, analizowania i przekształcania kodu źródłowego przy użyciu technologii kompilującej, sparametryzowanej za pomocą jawnych definicji języka. DMS ma solidne definicje języka dla wielu języków, , w tym C i C++ w różnych dialektach. Korzystając z interfejsów DMS C lub C++, można przeanalizować źródłowy kod , zbudować struktury danych kompilatora o nazwie AST, przeprowadzić analizy kodu, przekształcić AST, , a następnie zregenerować kod kompilowany zawierający komentarze i wszystkie dyrektywy preprocesora.

Ograniczenia związane z przetwarzaniem kodu źródłowego zawierającego dyrektywy preprocesora: muszą być dobrze skonstruowane [np. #ifdef #endif musi zagnieżdżać się wokół innych instrukcji, tak samo jak zwykły , jeśli itp., w przeciwieństwie do bycia używanym przez granicę instrukcji. Zdarza się to w kodzie C; dużo mniej niż w C++. Nasze doświadczenie jest takie, że jeśli chcesz zmodyfikować swój kod C trochę, , możesz usunąć ten konkretny problem.

dla konkretnego zadania, zrobić dość dużo jako odpowiedź na Naukowego Toolworks opisane:

  1. Wybierz jednostkę kompilacji i analizować je za pomocą DMS. Musisz podać wszystkie te same informacje, podając kompilator, aby mógł zlokalizować pliki nagłówkowe itp.
  2. DMS tworzy AST zarówno dla twojej jednostki kompilacji, jak i dla wszystkich plików nagłówkowych.
  3. Chodzić AST, aby wyodrębnić kolejność deklaracji w nagłówkach i kompilacji.
  4. Restrukturyzacja drzewa urządzenia zestawienie według kolejności uzyskanych z 3)
  5. prettyprint w uzyskiwanej kompilacji AST

[Powodem tym celu z DMS zamiast Toolworks naukowych jest to, że DMS jest przeznaczony do przetwarzaj/transformuj/generuj kod, podczas gdy SciTool IMHO jest przeznaczony tylko do analizy i analizowania. DMS zapewnia dostęp do drobnych detali wymaganych do transformacji, których nie ma SciTools, przynajmniej nie ostatni raz, kiedy patrzyłem].

Komplikacje będą następować z powodu warunków, makr, przestrzeni nazw, ... ale musisz zdecydować o polityce dla rozwiązania. Na przykład, jeśli plik nagłówka ma #if ... #else .... #endif, a deklaracje w klauzuli then mają inną kolejność niż w klauzuli else, jaka jest pożądana kolejność? Co się stanie, jeśli definicja funkcji zostanie utworzona przez makro w nagłówku? Ale to wszystko sprawia, że ​​ buduje prawdziwe narzędzie, er, zabawę.

Moja osobista opinia jest taka, że ​​wydaje się dużo pracy za efekt, który otrzymujesz. Jeśli zrobisz to wszystko, o ile lepszy będzie twój proces inżynierii oprogramowania? Zwykle używamy DMS-a w celu sprawdzenia błędów kodowania lub zmiany kodu w sposób, w jaki ludzie nie mogą (np. Tymczasowo wstawiać oprzyrządowania wykonawczego ), gdzie jasne jest, że mechaniczny silnik wypłaci.

+1

Chciałbym kiedyś dostać się do tego DMS-a. Dokładnie zapoznałem się z API SCI, ale zawsze szukam sposobów na poszerzenie mojej wiedzy na ten temat. –

Powiązane problemy