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

Reply via email to