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.
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.
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
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
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.
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.
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 } }
Die ersten beiden Punkte sind weniger interessant und sind aus den
Borland-Headern.
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 typeZeile 1115 wurde ersetzt durch
1115 unsigned char *Format;
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.
counters.cpp: In method `int TDList::InitializeModule()': counters.cpp:115: no matching function for call to `strstr (int, char[8])' ...
motors.cpp: In method `int TMList::InitializeModule()': motors.cpp:139: no matching function for call to `strstr (int, char[9])' ...die Fehler wird dadurch verursacht, das für die Function strupr kein Prototyp gefunden wird und diese Funktion deshalb implizit deklariert wird.
counters.cpp: In method `int TStoe_Psd::PsdStop()': counters.cpp:1367: `_AX' undeclared (first use this function)
kmpt1.c: In function `status_rd': kmpt1.c:455: `_AX' undeclared (first use in this function)
dlg_tpl.cpp: In function `int ModelessProc(struct HWND__ *, unsigned int, unsi gned int, long int)': dlg_tpl.cpp:118: Internal compiler error. dlg_tpl.cpp:118: Please submit a full bug report to `bug-g++@prep.ai.mit.edu'.
l_layer.cpp: In function `int SetFPOnData(int)': l_layer.cpp:347: label must be followed by statement
m_main.cpp: In function `long int DoCommandsFrame(struct HWND__ *, unsigned int, long int)': m_main.cpp:251: type `HINSTANCE__' is not a base type for type `HWND__' m_main.cpp:252: type `HINSTANCE__' is not a base type for type `HWND__' m_main.cpp: In function `long int FrameWndProc(struct HWND__ *, unsigned int, unsigned int, long int)': m_main.cpp:1059: type `HINSTANCE__' is not a base type for type `HWND__' m_main.cpp: In method `int TMDIWindow::SaveFile(int)':Hier scheint das Problem darin zu bestehen das wir eine andere/neuere Bibliothek von Borland benutzen.
m_main.cpp:1772: `READ_WRITE' undeclared (first use this function)
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.
counters.cpp: In method `void TPsd::SetAddedChannels(int)': counters.cpp:821: warning: implicit declaration of function `int max(...)' counters.cpp: In method `int TDevice::MeasureStart()': counters.cpp:400: warning: implicit declaration of function `int min(...)'das selbe in noch öffters
m_arscan.cpp:152: warning: implicit declaration of function `int strupr(...) m_arscan.cpp: In method `int TAreaScan::LoadOldData(int)': m_arscan.cpp:2010: warning: passing `int' to argument 1 of `strcmp(const char *, const char *)' lacks a cast m_arscan.cpp:2018: warning: passing `int' to argument 1 of `strcmp(const char *, const char *)' lacks a castund öffters
motors.cpp: In method `void TMotorParam::Dlg_OnCommand(struct HWND__ *, int, struct HWND__ *, unsigned int)': motors.cpp:867: warning: implicit declaration of function `int ltoa(...)
braunpsd.cpp: In method `TBraun_Psd::TBraun_Psd()': braunpsd.cpp:140: warning: ANSI C++ forbids cast to non-reference type used as lvalue ... braunpsd.cpp:143: warning: ANSI C++ forbids cast to non-reference type used as lvalue motors.cpp: In method `TC_812GPIB::TC_812GPIB()': motors.cpp:2353: warning: ANSI C++ forbids cast to non-reference type used as lvalue ... motors.cpp:2367: warning: ANSI C++ forbids cast to non-reference type used as lvalue
counters.cpp: In method `int TDevice::InitializeEvent(struct HWND__ *, int)': counters.cpp:352: warning: initialization to `int' from `double'' counters.cpp: In method `int TGenericDevice::SetParameters()': counters.cpp:542: warning: assignment to `long unsigned int' from `float' counters.cpp: In method `int TRadicon::InitializeEvent(struct HWND__ *, int)': counters.cpp:1823: warning: initialization to `int' from `double' counters.cpp: In method `int TCommonDevParam::CanClose()': counters.cpp:2109: warning: assignment to `long unsigned int' from `float' m_arscan.cpp: In method `int TAreaScan::SetMeasurementArea(struct {anonymous} (&)[4])': m_arscan.cpp:788: warning: assignment to `int' from `double' m_arscan.cpp: In method `int TAreaScan::GetShift(int)': m_arscan.cpp:1426: warning: return to `int' from `double' m_arscan.cpp: In method `int TAreaScan::SaveFile(int)': m_arscan.cpp:1572: warning: initialization to `short int' from `double' m_arscan.cpp: In method `int TAreaScan::UpdateFile()': m_arscan.cpp:1711: warning: initialization to `short int' from `double' m_arscan.cpp: In method `int TAreaScan::LoadMeasurementInfo(int)': m_arscan.cpp:1903: warning: assignment to `int' from `double' m_arscan.cpp:1908: warning: assignment to `int' from `double' m_arscan.cpp:1913: warning: assignment to `int' from `double' m_arscan.cpp: In method `int TCalibratePsd::GetBarEgde(int)': m_arscan.cpp:2695: warning: assignment to `int' from `double' m_arscan.cpp: In method `int TCalibratePsd::GetBarPos()': m_arscan.cpp:2704: warning: assignment to `int' from `double' m_data.cpp: In method `void TBitmapSource::DrawMeasurementArea(struct HDC__ *)': m_data.cpp:744: warning: assignment to `long int' from `double' m_data.cpp:745: warning: assignment to `long int' from `double' m_data.cpp: In method `void TBitmapSource::GenerateRLBitmap()': m_data.cpp:886: warning: assignment to `int' from `double' m_data.cpp:887: warning: assignment to `int' from `double' m_data.cpp: In method `void TBitmapSource::FormatDBaseToBitmapSource()': m_data.cpp:941: warning: assignment to `int' from `double' m_data.cpp:942: warning: assignment to `int' from `double' m_data.cpp: In method `void TPlotData::Size(struct HWND__ *, unsigned int, long int)': m_data.cpp:1133: warning: assignment to `int' from `double' m_data.cpp:1137: warning: assignment to `int' from `double' m_data.cpp: In method `void TPlotData::DrawCoordinateSystem(struct HDC__ *)': m_data.cpp:1369: warning: assignment to `long int' from `float' m_data.cpp:1390: warning: assignment to `long int' from `float' m_data.cpp:1404: warning: assignment to `long int' from `float' m_data.cpp:1422: warning: assignment to `long int' from `float' m_data.cpp:1443: warning: assignment to `long int' from `float' m_data.cpp:1453: warning: assignment to `long int' from `float' m_data.cpp:1476: warning: assignment to `int' from `double' m_data.cpp:1492: warning: assignment to `long int' from `double' m_data.cpp:1503: warning: assignment to `long int' from `float' m_data.cpp:1528: warning: assignment to `int' from `double' m_data.cpp:1537: warning: assignment to `int' from `double' m_data.cpp:1546: warning: assignment to `long int' from `double' m_data.cpp:1553: warning: assignment to `long int' from `double' m_data.cpp:1564: warning: assignment to `long int' from `float' m_data.cpp:1587: warning: assignment to `int' from `double' m_data.cpp:1595: warning: assignment to `int' from `double' m_data.cpp:1603: warning: assignment to `long int' from `double' m_data.cpp: In method `void TPlotData::FormatCurveToPLine(class TCurve *, struct tagPOINT *, int &)': m_data.cpp:1723: warning: assignment to `long int' from `double' m_data.cpp:1726: warning: assignment to `long int' from `double' m_data.cpp:1730: warning: assignment to `long int' from `double' m_data.cpp:1743: warning: assignment to `long int' from `double' m_data.cpp:1751: warning: assignment to `long int' from `double' m_data.cpp:1755: warning: assignment to `long int' from `double' m_device.cpp: In method `void TCounterWindow::Paint(struct HDC__ *, struct tagPAINTSTRUCT *)': m_device.cpp:239: warning: `float' used for argument 2 of `Rectangle(HDC__ *, int, int, int, int)' m_device.cpp:239: warning: `float' used for argument 3 of `Rectangle(HDC__ *, int, int, int, int)' m_device.cpp:239: warning: `float' used for argument 4 of `Rectangle(HDC__ *, int, int, int, int)' m_device.cpp:244: warning: `float' used for argument 2 of `Rectangle(HDC__ *, int, int, int, int)' m_device.cpp:244: warning: `float' used for argument 4 of `Rectangle(HDC__ *, int, int, int, int)' m_device.cpp:244: warning: `float' used for argument 5 of `Rectangle(HDC__ *, int, int, int, int)' m_device.cpp:247: warning: `float' used for argument 2 of `Rectangle(HDC__ *, int, int, int, int)' m_device.cpp:247: warning: `float' used for argument 3 of `Rectangle(HDC__ *, int, int, int, int)' m_device.cpp:247: warning: `float' used for argument 4 of `Rectangle(HDC__ *, int, int, int, int)' m_device.cpp:316: warning: `float' used for argument 2 of `Rectangle(HDC__ *, int, int, int, int)' m_device.cpp:316: warning: `float' used for argument 4 of `Rectangle(HDC__ *, int, int, int, int)' m_device.cpp:316: warning: `float' used for argument 5 of `Rectangle(HDC__ *, int, int, int, int)' m_steerg.cpp: In method `TScanCmd::TScanCmd(struct TCmdTag)': m_steerg.cpp:681: warning: assignment to `int' from `double' m_steerg.cpp: In method `TAreaScanCmd::TAreaScanCmd(struct TCmdTag)': m_steerg.cpp:1183: warning: assignment to `int' from `double' m_steerg.cpp:1184: warning: assignment to `int' from `double' motors.cpp: In method `int TMotor::Initialize()': motors.cpp:1331: warning: assignment to `short unsigned int' from `double' motors.cpp: In method `int TDC_Drive::SetSpeed(double)': motors.cpp:1874: warning: assignment to `long unsigned int' from `double' motors.cpp: In method `int TC_812::SetMoment(float)': motors.cpp:1991: warning: assignment to `short unsigned int' from `float
m_steerg.cpp: In method `void TEditWindow::rButtonDown(long int)': m_steerg.cpp:2635: warning: negative value `-1' passed as argument 3 of `AppendMenuA(HMENU__ *, unsigned int, unsigned int, const char *)'
rtk-g++/include/win32/winbase.h:487: warning: anonymous class type not used to declare any objects
rtk-g++/include/typeinfo.h:84: warning: `class typeinfo' only defines private constructors and has no friends
rtk-g++/include/iostream.h:42: warning: malformed `#pragma pack'taucht öfter auf, einige der Pragmas wurden auskommentiert
rtk-g++/include/win32/winnt.h:4320: warning: unnamed struct/union that defines no instances rtk-g++/include/win32/winnt.h:4336: warning: unnamed struct/union that defines no instances
noch zu ergänzen
.
Projekt: Software-Sanierung