> Projekt: Software-Sanierung > Entwicklerdokumentation > Tabelle zu den Entwicklerdokumenten > Gesamtsystem > Implementation > Metriken

"Portierung" Borland => gcc

Autor: Stefan Luetzkendorf
Datum: 07.12.98

INHALT


Ziel/Aufgabe


Ziel war es das McCabe-Tool zur Analyse des vorhandenen Quellen nutzen zu können. Das McCabe-Tool hat verschiedene Parser für verschiedene C/C++-Dialekte, eine Borland-Variante stand aber leider nicht zur Verfügung.

Da der gcc-Dialekt vom McCabe-Tool unterstützt wird und der gcc auf Solaris zur Verfügung steht sollte eine Konvertierung der Quellen in diesen Dialekt statt finden.

Lösungs-Weg


Das McCabe-Tool schickt die Quellen vor der Analyse durch einen Präprozessor eigener Wahl. Das ist der Punkt an dem sich viele der Inkompatibilitäten beseitigen lassen ohne die Quellen bearbeiten zu müssen.
Zu den Quellen gehört neben unseren eigenen C/C++-Files die Dateien aus dem Borland-include-Verzeichniss.

Systematische Probleme und die entsprechenden Änderungen
dos2unix


Der Präprozessor hat in einigen Fällen Probleme mit der DOS-Zeilenende-Marke CR NL; und zwar immer dann wenn Macros über mehrere Zeilen gehen und die Zeilenenden durch Backslash '\' versteckt werden. Der Präprocessor erwartet nach den Backslash ein NL es kommt aber ein CR.
Beispiel:

#if defined(_MPPC_)  && \
    ( (defined(_MSC_VER) || defined(__SC__) || defined(__MWERKS__)) && \
    !defined(NO_NULL_VTABLE_ENTRY) )
   #define BEGIN_INTERFACE virtual void a() {}
   #define END_INTERFACE
#endif
Pfadangaben in #include-Direktiven


in den Borland-Headern kommen relativ oft include-Direktiven mit Pfad-Angaben vor da das dort benutzt wird um die verschiedenen Versionen für 16 und 32-Bit auseinander zu halten. Das Problem besteht in der Verwendung von '\' statt '/' als Verzeichnistrenner.
Beispiel:

#ifdef __FLAT__
#include <win32\windows.h>
#else
#include <win16\windows.h>
#endif
Groß- und Kleinschreibung in #include-Direktiven
Borland-Spezifische Schlüsselwörter


Der Borland-Compiler stellt eine Reihe eigener Schlüsselwörter zu verfügung. Die 3 häufigsten Gruppen sind die für Aufrufkonventionen (_pascal, _stdcall, ...), dir für die Kennzeichnung der verscheidenen Speichermodelle (_near, _far, _huge ...), sowie die für den Ex/Import fon Funtionen in/aus dll's.

Aus unserer Sicht lassen sich formal 2 Gruppen bilden.

    Schlüsselwörter die als modifier an Standart-C-Konstrukten stehen und die, wenn man sie entfernt, valide C/C++-Konstrukte zurücklassen. (Das sind z.B. die oben genannten Schlüsselwörter für Aufrufkonventionen und Speichermodelle)

    Diese lassen durch den Präprocessor entfernt, in dem diese Symbole als leere Zeichenketten definiert werden. Das lässt sich am leichtesten über Kommandozeilen-Optionen des Compiler/Präprozessor machen. Im folgenden Beispiel werden für die Schlüsselwörter _far und _pascal die entsprechenden Präprozessorsymbole als leere Zeichenketten definiert und __inline wird durch sein gcc-konformes Äquivalent ersetzt:

    g++ ... -D_far= -D_pascal= -D__inline=inline ...
    Schüsselwörter die spezielle Konstrukte einleiten. Wenn man diese durch der Präprozessor entfernen lässt bleib Code übrig der nicht valid ist.
    Aus der Gruppe B sind zu nennen
    1. eingebetteter Assamblercode
    2. Int64ShraMod32(LONGLONG Value, DWORD ShiftCount) {
          __asm {
              mov     ecx, ShiftCount
              mov     eax, dword ptr [Value]
              mov     edx, dword ptr [Value+4]
              shrd    eax, edx, cl
              sar     edx, cl
          }
      }
    3. __declspec( ... )-Anweisungen
    4. __try/__execpt-Blöcke für Exception-Handling in C-Code
    Für die ersten beiden Fälle blieb nichts weiter übrig als die entsprechenden Stellen in den System-Header-Files auszukommentieren. Zu Glück waren das relative wenige. Die Anweisungen aus Punkt 3 tauchten überhaupt nicht auf.
Spezielle Probleme und die entsprechenden Änderungen


Die ersten beiden Punkte sind weniger interessant und sind aus den Borland-Headern.

<rpcndr.h>
1112   typedef struct _MIDL_FORMAT_STRING 
1113   {
1114       short Pad;
1115       unsigned char Format[];
1116   } MIDL_FORMAT_STRING;
führt zu Fehler
.../rpcndr.h:1115: field 'Format' has inclomplete type
Zeile 1115 wurde ersetzt durch
1115       unsigned char *Format;
<winnt.h>
Das schenke ich mir ganz da der Ausschnitt etwas größer sein müsste. Das Problem scheint ein echter Bug zu sein, der dadurch zutage tritt daß wir einen anderen Satz an Präprozessor-Symbolen definiert haben, als es der Borland-Compiler standartmäßig tut.
undefinierte Typen UINT, DWORD etc. ("comhead.h")


dieses Problem scheint seine Ursache darin zu haben, daß ich den Standard-Satz an Präprozessor-Symbolen den der Borland-Compiler benutzt nicht kenne oder das wir die Bibliothek eines Compilers in einer anderen Version benutzten. (Darauf lassen auch einige Fehler schliessen die noch nicht beseitigt sind.)

In <mmsystem.h> stellt der Compiler fest, daß Typen verwendet werden, die nicht definiert sind (UINT, DWORD, ... ). Dieser Header definiert die Typen nicht und inkludiert auch keinen Header der dies tut. Folglich muß man diesen Header nachdem man sicher ist das diese Typen definiert sind (schön ist das nicht). <mmsystem.h> wird in "comhead.h" inkludiert. Ich habe nun davor #include <wtypes.h> eingefügt um die Typen vorher bekannt zu machen. Ob diese Wahl die günstigste ist weiß ich nicht aber es ist einer von mehreren(!) die die gesuchten Typen definieren.

Anmerkung: das ist die einzige Änderung (außer "dos2unix") die bisher an unseren Quellen notwendig war.

Alle Änderungen an den Quellen sind mit >>LUETZKEN<< markiert. Ausnahmen sind die von Punkt 'dos2unix' und '#include-Direktiven'.
Fehler die gcc noch meldet
die Warnungen gcc noch meldet
Warnungen aus 'unseren' Quellen


Die ersten 3 Gruppen stehen in engem Zusammenhang mit einigen der noch auftretenden Fehler und sind mit diesen sicher noch zu beseitigen. Die anderen sind potentielle Fehlerquellen und sind deshalb hier aufgelistet.

Warnungen aus Borland-Header-Files.
McCabe-Tool starten


noch zu ergänzen


. Projekt: Software-Sanierung
Stefan Lützkendorf letzte Änderung 9.12.98