so ich fange hier einfach mal einen neuen Thread an was man alles
erlebt wenn man eine Cl*pper Application nach Xbase++ "convertieren"
will.
Ausgangs Basis : S87 / V5.01a Clipper Application mit ca. 40 *.PRG
*.RMK : CLIPPER $* -M -B -N
*.LNK : FILE TIKMENUE
MAP = TIK52 A,S
BLINKER EXECUTABLE EXTENDED
nachdem ich also das ganze "Backup" (1994) entpackt und neu compiliert
habe kam bei starten unter XP sp2 (nicht für Cl*pper "optimiert" !!! )
gleich eine "schöne" Fehlermeldung :
na toll dachte ich mir, aber das XP sp2 System war ja nun nicht fürE:\VO\TIK>tik52.exe
BLX286 : 1313 : Ausnahmefehler (Exception-Fehler) 0D : Allgemeine Schutzverletzu
ng, Code = 0000h
Aktiver Host ist DPMI (v3.30 iP? 15360 Kb)
Reg Wert Grenze Base Flags Segment Modul Datei
CS 025F F857 03398658 FB00 0D TIK52 E:\VO\TIK\TIK52.EXE
DS 039F 9FFF 03452FB4 F300 ****
ES 0000 ****
SS 02C7 FFFF 03383554 F300 1A TIK52 E:\VO\TIK\TIK52.EXE
[Code-Byte CS] 0C 8B FB 8B F0 1E 8E DA [IP] A5 A5 A5 A5 1F 2B C0 5E 5F 8B
[Register] AX=9D14 BX=0000 CX=0000 DX=039F CS:IP=025F:D16E
SI=9D14 DI=0000 BP=7D7A SP=7D70
FL=3202 NV UP EI NT PL NZ NA PO NC
[Stackwert SS] 7D72 E1BA 025F 003C 038F 039F 02C7 4CA0 0010 30FC 039F 0000
[SP] 02C7 0010 0209 0000 0000 7D8A 77D2 023F 0000 0000 9D14 039F
[Stackrahmen SS] 039F 02C7 4CA0 0010 30FC 039F 0000 02C7 0010 0209 0000 0000
[BP] 7D8A 77D2 023F 0000 0000 9D14 039F 029F 7DC6 0B77 0227 0000
Cl*pper "optimiert". Trotzdem wollte ich natürlich wissen warum es
den GPF Fehler gab und hab es dann getestet :
schlussendlich hat sich dann mein MRDEBUG.LIB als der "Übertäter"BLIGPF v4.0 - Extrahiert Info über GPF-Fehler aus Blinker 3.x/4.x MAP-Dateien
(c)1994-1996 SuccessWare Int'l ♦ The Data Driver Pioneers ♦ 909-699-9657
TIK52.MAP wird abgesucht: 3218
Symbol-Adresse : 000D:D14A
Symbol-Typ : Res
Symbol-Name : __GTWPOS
Offset In Fktn. : 24h
rausgestellt den wir aber für Xbase++ eh nicht gebrauchen können
Code: Alles auswählen
Regel No. 1 : es können keine Clipper 16-Bit Lib´s für Xbase++ verwendet werden
per "command.com" (cmd geht nicht ? ) wird mit :
Code: Alles auswählen
DIR *.PRG /B > PROJECT.TXT
Code: Alles auswählen
PBUILD @PROJECT.TXT
Code: Alles auswählen
PROCEDURE MAIN
müssen wir und nur noch die "PROJECT.XPJ" vornehmen und paar
"Anpassung" vornehmen. Unter
Code: Alles auswählen
[PROJECT.XPJ]
PROJECT.EXE
[PROJECT.EXE]
xyz.PRG
unser "Main" PRG gleich an die 1st Stelle. somit kann man mit.
Code: Alles auswählen
PBUILD PROJECT.XPJ
Da man die unter Windows, ohne VX, so schlecht sieht verwende ich
folgenden "BAT"ch File :
Code: Alles auswählen
pbuild project.xpj > waslos.txt
start notepad waslos.txt
"damals" benutzt habe und Cl*pper die "schluckte", aber Xbase++ ist
da viel "penibler".
Das nächste "Problem" ist nun folgenden Konstruktion :
Code: Alles auswählen
FUNCTION tbm2
PARAMETERS neuindex
LOCAL first_flag := .T.
aha ... nun "klingelt" es ... oder ?Die Deklaration von Parametern kann allerdings auch mit dem Schlüsselwort PARAMETERS erfolgen. In diesem Fall werden die Parameter als Variablen der Speicherklasse PRIVATE erzeugt.
nun Xbase++ nimmt es auch da "penibler" und mag keine LOCAL "nach"
einer PRIVATE ... und das "könnte" einen "Rattenschwanz" haben ...
um nun nicht den ganzen "funktionsfähigen" Source zu verändern kann
man die "Konstante"
Code: Alles auswählen
#IFDEF __XPP__
< XBase++ code >
#ELSE
< Cl*pper Code >
#ENDIF
nun zu nächsten "grösserem" Problem :
das "-M" bedeutet ja das der *.PRG Name dann "übernommen" wirdCLIPPER $* -M -B -N
und als "Procedure" Namen fungiert ... aber nicht so bei Xbase++
ich hatte mir nun damals ein kleines Tool geschrieben um in jedes *.PRG,
nach den "#include" die Zeile "PROCEDURE xyz" zu schreiben ...
leider hab ich es auf dem "neuen" PC nicht gefunden, aber ich wollte es
ja nun wissen also "auf die schnelle" nochmal "gestrickt" :
Code: Alles auswählen
#include "Directry.ch"
#define CRLF Chr(13)+Chr(10)
PROCEDURE Main(cAction)
LOCAL saPrgFiles
// Create array with PRG file names
saPrgFiles := Directory("*.PRG")
IF Empty( saPrgFiles )
CLS
?
? "No PRG files found"
QUIT
ENDIF
IF PCOUNT() = 0
ALERT("Syntax : PROCINTO [INSERT]")
QUIT
ENDIF
DO CASE
CASE UPPER(cAction) = "INSERT" ; AEval( saPrgFiles, {|x| DONOW( x[F_NAME] ) })
ENDCASE
RETURN
PROCEDURE DONOW(cPrgFile)
LOCAL scPrgText, tcPrgText := ""
LOCAL i, iMax
LOCAL cText := ""
LOCAL cDummy
LOCAL cOut := StrTran(cPrgFile,".PRG",".XRG")
LOCAL cPRG := StrTran(cPrgFile,".PRG","")
LOCAL lNowMust := .F., lDidit:= .F.
CLS
IF UPPER(cPrgFile) = "PROCINTO.PRG" // this Source
RETURN
ENDIF
ALTD()
scPrgText := Memoread( cPrgFile )
iMax := MlCount( scPrgText, 250,,.F. ) // .F. = until (Chr(13)+Chr(10))
FOR i = 1 TO iMax
? cText := RTRIM(MemoLine( scPrgText, 250, i,,.F. )) // .F. = until (Chr(13)+Chr(10))
cDummy := UPPER(LTRIM(cText))
DO CASE
CASE EMPTY(cDummy)
CASE SUBSTR(cDummy,1,1) = "*"
CASE SUBSTR(cDummy,1,1) = "#"
CASE SUBSTR(cDummy,1,4) = "PROC" .AND. .NOT. lDidit ; lDidit:= .T.
CASE SUBSTR(cDummy,1,4) = "FUNC" .AND. .NOT. lDidit ; lDidit:= .T.
CASE SUBSTR(cDummy,1,2) = "/*"
CASE SUBSTR(cDummy,1,2) = "*/"
CASE SUBSTR(cDummy,1,4) = "LOCA" .AND. .NOT. lDidit ; lNowMust := .T.
CASE SUBSTR(cDummy,1,4) = "PRIV" .AND. .NOT. lDidit ; lNowMust := .T.
CASE SUBSTR(cDummy,1,4) = "STAT"
OTHERWISE
IF lDidit
ELSE
lNowMust := .T.
ENDIF
ENDCASE
IF lNowMust
IF lDidit
ELSE
lDidit:= .T.
tcPrgText += "PROCEDURE "+cPRG+CHR(9)+CHR(9)+"// insert by Xbase++ "+CRLF
ENDIF
ENDIF
tcPrgText += cText+CRLF
NEXT
MemoWrit( cOut, tcPrgText)
RETURN
die nächsten Probleme warten schon ...
gruss by OHR
Jimmy