On Wed, 01 Apr 2009, Przemyslaw Czerpak wrote:
> I've just written such simple parser.
[...]
Below is corrected version.
I removed one redundant line I left by mistake in copy and past
and added some basic translation for well know Clipper, Blinker,
ExoSpace, SIX, Class(y) files.
For sure it does not cover all possibilities but for many users
should be enough and if they will want then can extend this list.
best regards,
Przemek
proc main( ... )
local cCommandLine := "", cParam
local cFileOut := ""
local aFileList, aLibList
local lOK
/* I need it only to test the code in Linux */
set filecase lower
set dircase lower
set dirseparator "\"
/* take all parameters as rtlink/blinker ones
* here some local only parameters can be stripped if necessary
*/
for each cParam in hb_aParams()
cCommandLine += cParam + " "
next
altd()
lOK := rtlnk_process( cCommandLine, @cFileOut, @aFileList, @aLibList )
?
? iif( lOK, "linker parameters preporcessed correctly", ;
"error during preprocessing linker parameters" )
rtlnk_libtrans( aLibList )
rtlnk_filetrans( aFileList )
? "outputfile:", cFileOut
? "files: "
aeval( aFileList, {|f,i| iif( i > 1, qqout( ", " ), ), qqout( f ) } )
? "libraries: "
aeval( aLibList, {|f,i| iif( i > 1, qqout( ", " ), ), qqout( f ) } )
return
#define RTLNK_MODE_NONE 0
#define RTLNK_MODE_OUT 1
#define RTLNK_MODE_FILE 2
#define RTLNK_MODE_FILENEXT 3
#define RTLNK_MODE_LIB 4
#define RTLNK_MODE_LIBNEXT 5
#define RTLNK_MODE_SKIP 6
#define RTLNK_MODE_SKIPNEXT 7
static procedure rtlnk_libtrans( aLibList )
static hTrans := { ;
"CT" => "hbct" , ;
"CTP" => "hbct" , ;
"CLASSY" => NIL , ;
"CSYINSP" => NIL , ;
"SIX3" => NIL , ;
"NOMACH6" => NIL , ;
"BLXRATEX" => NIL , ;
"BLXCLP50" => NIL , ;
"BLXCLP52" => NIL , ;
"BLXCLP53" => NIL , ;
"EXOSPACE" => NIL , ;
"CLIPPER" => NIL , ;
"EXTEND" => NIL , ;
"TERMINAL" => NIL , ;
"PCBIOS" => NIL , ;
"ANSITERM" => NIL , ;
"DBFBLOB" => NIL , ;
"DBFMEMO" => NIL , ;
"DBFNTX" => NIL , ;
"DBFCDX" => NIL , ;
"_DBFCDX" => NIL , ;
"CLD" => NIL , ;
"CLDR" => NIL }
local cLib
for each cLib in aLibList descend
if upper( right( cLib, 4 ) ) == ".LIB"
cLib := left( cLib, len( cLib ) - 4 )
endif
if upper( cLib ) $ hTrans
cLib := hTrans[ upper( cLib ) ]
if cLib == NIL
hb_aDel( aLibList, cLib:__enumIndex(), .t. )
endif
endif
next
return
static procedure rtlnk_filetrans( aFileList )
static hTrans := { ;
"CTUS" => NIL , ;
"CTUSP" => NIL , ;
"CTINT" => NIL , ;
"CTINTP" => NIL , ;
"__WAIT" => NIL , ;
"__WAIT_4" => NIL , ;
"__WAIT_B" => NIL , ;
"BLXCLP50" => NIL , ;
"BLXCLP52" => NIL , ;
"BLXCLP53" => NIL , ;
"BLDCLP50" => NIL , ;
"BLDCLP52" => NIL , ;
"BLDCLP53" => NIL , ;
"SIXCDX" => NIL , ;
"SIXNSX" => NIL , ;
"SIXNTX" => NIL , ;
"DBT" => NIL , ;
"FPT" => NIL , ;
"SMT" => NIL , ;
"NOMEMO" => NIL , ;
"CLD.LIB" => NIL }
local cFile
for each cFile in aFileList descend
if upper( right( cFile, 4 ) ) == ".OBJ"
cFile := left( cFile, len( cFile ) - 4 )
endif
if upper( cFile ) $ hTrans
cFile := hTrans[ upper( cFile ) ]
if cFile == NIL
hb_aDel( aFileList, cFile:__enumIndex(), .t. )
endif
endif
next
return
static function rtlnk_read( cFileName, aPrevFiles )
local cFileBody
local cPath, cFile, cExt
local hFile
hb_FNameSplit( cFileName, @cPath, @cFile, @cExt )
if empty( cExt )
cExt := ".lnk"
endif
cFileName := hb_FNameMerge( cPath, cFile, ".lnk" )
/* it's blinker extnession, look for .lnk file in paths
* specified by LIB envvar
*/
if !hb_fileExists( cFileName ) .and. ;
!left( cFileName, 1 ) $ hb_osPathDelimiters() .and. ;
!substr( cFileName, 2, 1 ) == hb_osDriveSeparator()
for each cPath in hb_aTokens( getenv( "LIB" ), hb_osPathListSeparator() )
cFile := hb_FNameMerge( cPath, cFileName )
if hb_fileExists( cFile )
cFileName := cFile
exit
endif
next
endif
/* protection against recursive calls */
if ascan( aPrevFiles, { |x| x == cFileName } ) == 0
if ( hFile := fopen( cFileName ) ) != -1
cFileBody := space( fseek( hFile, 0, 2 ) )
fseek( hFile, 0, 0 )
if fread( hFile, @cFileBody, len( cFileBody ) ) != len( cFileBody )
cFileBody := NIL
endif
fclose( hFile )
endif
aadd( aPrevFiles, cFileName )
else
cFileBody := ""
endif
return cFileBody
static function rtlnk_process( cCommands, cFileOut, aFileList, aLibList, ;
aPrevFiles )
local nCh, nMode
local cLine, cWord
cCommands := strtran( strtran( cCommands, chr( 13 ) ), ",", " , " )
for each nCh in @cCommands
switch asc( nCh )
case 9
case 11
case 12
case asc( ";" )
nCh := " "
endswitch
next
nMode := RTLNK_MODE_NONE
if !valtype( aFileList ) == "A"
aFileList := {}
endif
if !valtype( aLibList ) == "A"
aLibList := {}
endif
if !valtype( aPrevFiles ) == "A"
aPrevFiles := {}
endif
for each cLine in hb_aTokens( cCommands, chr( 10 ) )
cLine := alltrim( cLine )
if !empty( cLine ) .and. !cLine = "#" .and. !cLine = "//"
if nMode == RTLNK_MODE_NONE
/* blinker extenssion */
if upper( cLine ) = "ECHO "
? "=>", substr( cLine, 6 )
loop
elseif upper( cLine ) = "BLINKER "
/* skip blinker commands */
loop
else /* TODO: add other blinker commands */
endif
endif
for each cWord in hb_aTokens( cLine )
if nMode == RTLNK_MODE_OUT
cFileOut := cWord
nMode := RTLNK_MODE_FILENEXT
elseif nMode == RTLNK_MODE_FILE
if !cWord == ","
if ascan( aFileList, { |x| x == cWord } ) == 0
aadd( aFileList, cWord )
endif
nMode := RTLNK_MODE_FILENEXT
endif
elseif nMode == RTLNK_MODE_LIB
if !cWord == ","
aadd( aLibList, cWord )
nMode := RTLNK_MODE_LIBNEXT
endif
elseif nMode == RTLNK_MODE_SKIP
if !cWord == ","
nMode := RTLNK_MODE_SKIPNEXT
endif
elseif cWord == ","
if nMode == RTLNK_MODE_FILENEXT
nMode := RTLNK_MODE_FILE
elseif nMode == RTLNK_MODE_LIBNEXT
nMode := RTLNK_MODE_LIB
elseif nMode == RTLNK_MODE_SKIPNEXT
nMode := RTLNK_MODE_SKIP
endif
elseif cWord = "@"
cWord := substr( cWord, 2 )
cCommands := rtlnk_read( @cWord, aPrevFiles )
if cCommands == NIL
? "cannot open:", cWord, "file."
return .F.
endif
if !rtlnk_process( cCommands, @cFileOut, @aFileList, @aLibList, ;
aPrevFiles )
return .F.
endif
else
cWord := upper( cWord )
if len( cWord ) >= 2
if "OUTPUT" = cWord
nMode := RTLNK_MODE_OUT
elseif "FILE" = cWord
nMode := RTLNK_MODE_FILE
elseif "LIBRARY" = cWord
nMode := RTLNK_MODE_LIB
elseif "MODULE" = cWord .or. ;
"EXCLUDE" = cWord .or. ;
"REFER" = cWord .or. ;
"INTO" = cWord
nMode := RTLNK_MODE_SKIP
endif
endif
endif
next
endif
next
return .t.
_______________________________________________
Harbour mailing list
[email protected]
http://lists.harbour-project.org/mailman/listinfo/harbour