[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User]
Here is a Harbour (xBase/Clipper) implementation:

Harbour contribution module 'hbct' (CA-Tools compatibility library): contrib/hbct/tests/test.prg. Contains procedures: Main. This file provides legacy compatibility functions

[Assistant]
#require "hbct"
#require "hbtest"

PROCEDURE Main()

   LOCAL nTotal

   HBTEST AddAscii( "0000", 1, 1 )         IS "1000"
   HBTEST AddAscii( "0000", 1 )            IS "0001"
   HBTEST AddAscii( "AAAA", -255, 1 )      IS "BAAA"
   HBTEST AddAscii( "AAAA", -255 )         IS "AAAB"
   HBTEST AddAscii( "AAAA", 1, 2, .T. )    IS "ABAA"
   HBTEST AddAscii( "AAAA", 257, 2, .T. )  IS "BBAA"
   HBTEST AddAscii( "AAAA", 257, 2, .F. )  IS "ABAA"
   HBTEST AddAscii( "AAAA", 258,, .T. )    IS "AABC"
   HBTEST AddAscii( "ABBA", -257, 3, .T. ) IS "AAAA"

   HBTEST AsciiSum( Replicate( "A", 10000 ) ) IS 650000
   HBTEST AsciiSum( "0123456789" )            IS 525
   HBTEST AsciiSum( NIL )                     IS 0

   HBTEST AscPos( "0123456789" )     IS 57
   HBTEST AscPos( "0123456789", 1 )  IS 48
   HBTEST AscPos( "0123456789", 11 ) IS 0

   HBTEST ValPos( "1234x56789" )     IS 9
   HBTEST ValPos( "1234x56789", 1 )  IS 1
   HBTEST ValPos( "1234x56789", 11 ) IS 0
   HBTEST ValPos( "1234x56789", 5 )  IS 0

   HBTEST AfterAtNum( "..", "..This..is..a..test!" )       IS "test!"
   HBTEST AfterAtNum( "..", "..This..is..a..test!", 2 )    IS "is..a..test!"
   HBTEST AfterAtNum( "..", "..This..is..a..test!", 2, 2 ) IS "a..test!"
   HBTEST BeforAtNum( "..", "..This..is..a..test!" )       IS "..This..is..a"
   HBTEST BeforAtNum( "..", "..This..is..a..test!", 2 )    IS "..This"
   HBTEST BeforAtNum( "..", "..This..is..a..test!", 2, 2 ) IS "..This..is"

   HBTEST AtNum( "..", "..This..is..a..test!" )       IS 14
   HBTEST AtNum( "..", "..This..is..a..test!", 2 )    IS 7
   HBTEST AtNum( "..", "..This..is..a..test!", 2, 2 ) IS 11

   HBTEST AtRepl( "ABC", "ABCDABCDABC", "xx" )         IS "xxDxxDxx"
   HBTEST AtRepl( "ABC", "ABCDABC", "ZYXW" )           IS "ZYXWDZYXW"
   HBTEST AtRepl( "ABC", "ABCDABCDABC", "xx", 2 )      IS "xxDxxDABC"
   HBTEST AtRepl( "ABC", "ABCDABCDABC", "xx", 2, .T. ) IS "ABCDxxDABC"

   HBTEST CharEven( " 1 2 3 4 5" ) IS "12345"
   HBTEST CharEven( " 1 2 3 4 " )  IS "1234"
   HBTEST CharEven( " " )          IS ""

   HBTEST CharOdd( "1A2B3C4D5E" )  IS "12345"
   HBTEST CharOdd( "1A2B3C4D5" )   IS "12345"

   HBTEST CharSList( "Hello World !" ) IS " !HWdelor"
   HBTEST CharSList( "Hello World !" ) IS CharSort( CharList( "Hello World !" ) )
   HBTEST CharSList( NIL )             IS ""

   HBTEST CharHist( "Hello World !" )[ 109 ] IS 3
   HBTEST ( nTotal := 0, AEval( CharHist( "Hello World !" ), {| x | nTotal += x } ), nTotal ) IS Len( "Hello World !" )

   HBTEST CharList( "Hello World !" ) IS "Helo Wrd!"
   HBTEST CharList( NIL )             IS ""

   HBTEST CharNoList( CharNoList( "Hello World !" ) ) IS CharSList( "Hello World !" )
   HBTEST CharNoList( CharNoList( NIL ) )             IS ""

   HBTEST CharMirr( "racecar" )        IS "racecar"
   HBTEST CharMirr( "racecar  ", .T. ) IS "racecar  "
   HBTEST CharMirr( "racecar  ", .F. ) IS "  racecar"

   HBTEST CharMix( "ABC", "123" )  IS "A1B2C3"
   HBTEST CharMix( "ABCDE", "12" ) IS "A1B2C1D2E1"
   HBTEST CharMix( "AB", "12345" ) IS "A1B2"
   HBTEST CharMix( "HELLO", " " )  IS "H E L L O "
   HBTEST CharMix( "HELLO", "" )   IS "HELLO"

   HBTEST CharOne( "122333a123" )      IS "123a123"
   HBTEST CharOne( "A  B  CCCD" )      IS "A B CD"
   HBTEST CharOne( " ", "A  B  A  B" ) IS "A B A B"
   HBTEST CharOne( "o", "122oooB12o" ) IS "122oB12o"

   HBTEST WordOne( "12ABAB12" )       IS "12AB12"
   HBTEST WordOne( "1AAAA2" )         IS "1AAAA2"
   HBTEST WordOne( "12", "1212ABAB" ) IS "12ABAB"

   HBTEST CharOnly( "0123456789", "0211 - 38 99 77" ) IS "0211389977"
   HBTEST CharOnly( "0123456789", "0211/ 389 977" )   IS "0211389977"

   HBTEST WordOnly( "AABBCCDD", "XXAAYYBBZZ" ) IS "AABB"
   HBTEST WordOnly( "AABBCCDD", "XAAYYYBBZZ" ) IS "BB"

   HBTEST CharRem( " ", " 1  2  " ) IS "12"
   HBTEST CharRem( "3y", "xyz123" ) IS "xz12"

   HBTEST WordRem( "abcd", "0ab1cd" ) IS "0ab1"
   HBTEST WordRem( "abcd", "ab0cd1" ) IS "0cd1"

   HBTEST CharAdd( "012345678", hb_BChar( 1 ) )                     IS "123456789"
   HBTEST CharAdd( "012345678", hb_BChar( 1 ) + hb_BChar( 2 ) )     IS "133557799"
   HBTEST CharAdd( "123456789", hb_BChar( 255 ) )                   IS "012345678"
   HBTEST CharAdd( "123456789", hb_BChar( 255 ) + hb_BChar( 254 ) ) IS "002244668"
   HBTEST CharAnd( "012345678", hb_BChar( 254 ) )                   IS "002244668"
   HBTEST CharAnd( "012345678", hb_BChar( 254 ) + hb_BChar( 252 ) ) IS "002044648"

   HBTEST CharNot( hb_BChar( 85 ) + hb_BChar( 128 ) + hb_BChar( 170 ) + hb_BChar( 1 ) ) IS hb_BChar( 170 ) + hb_BChar( 127 ) + hb_BChar( 85 ) + hb_BChar( 254 )
   HBTEST CharNot( CharNot( "This is a test!" ) ) IS "This is a test!"

   HBTEST CharOr( "012345678", hb_BChar( 1 ) )                 IS "113355779"
   HBTEST CharOr( "012345678", hb_BChar( 1 ) + hb_BChar( 3 ) ) IS "133357779"

   HBTEST CharXor( CharXor( "This is top secret !", "My Password" ), "My Password" ) IS "This is top secret !"

   HBTEST CharSub( "123456789", hb_BChar( 1 ) )                     IS "012345678"
   HBTEST CharSub( "123456789", hb_BChar( 1 ) + hb_BChar( 2 ) )     IS "002244668"
   HBTEST CharSub( "012345678", hb_BChar( 255 ) )                   IS "123456789"
   HBTEST CharSub( "012345678", hb_BChar( 255 ) + hb_BChar( 254 ) ) IS "133557799"

   HBTEST CharShl( hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ), 3 ) IS hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ) + hb_BChar( 0 ) + hb_BChar( 0 ) + hb_BChar( 0 )
   HBTEST CharShr( hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ), 3 ) IS hb_BChar( 0 ) + hb_BChar( 0 ) + hb_BChar( 0 ) + hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 )
   HBTEST CharRll( hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ), 3 ) IS hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ) + hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 )
   HBTEST CharRlr( hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ), 3 ) IS hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ) + hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 )

   HBTEST CharRepl( "1234", "1x2y3z", "abcd" )            IS "axbycz"
   HBTEST CharRepl( "abcdefghij", "jhfdb", "1234567890" ) IS "08642"
   HBTEST CharRepl( "abcdefghij", "jhfdb", "12345" )      IS "55542"
   HBTEST CharRepl( "1234", "1234", "234A" )              IS "AAAA"
   HBTEST CharRepl( "1234", "1234", "234A", .T. )         IS "234A"

   HBTEST CharSort( "qwert" )                     IS "eqrtw"
   HBTEST CharSort( "qwert", 2 )                  IS "erqwt"
   HBTEST CharSort( "b1a4a3a2a1", 2, 1 )          IS "a2a1a3a4b1"
   HBTEST CharSort( "XXXqwert", 1, 1, 3 )         IS "XXXeqrtw"
   HBTEST CharSort( "b1a4a3a2a1", 2, 1, 0, 1 )    IS "a1b1a2a3a4"
   HBTEST CharSort( "384172852", 1, 1, 0, 0, 4 )  IS "134872852"
   HBTEST CharSort( "qwert",,,,,, .T. )           IS "wtrqe"

   HBTEST CharSwap( "0123456789" )  IS "1032547698"
   HBTEST CharSwap( "ABCDEFGHIJK" ) IS "BADCFEHGJIK"

   HBTEST WordSwap( "1234567890" )      IS "3412785690"
   HBTEST WordSwap( "1234567890", .T. ) IS "4321876590"

   HBTEST Floor( 1.1 )  IS 1.0
   HBTEST Floor( -1.1 ) IS -2.0
   HBTEST Ceiling( 1.1 )  IS 2.0
   HBTEST Ceiling( -1.1 ) IS -1.0
   HBTEST Sign( 1.1 )  IS 1
   HBTEST Sign( -1.1 ) IS -1
   HBTEST Sign( 0.0 )  IS 0
   HBTEST Log10( 10.0 )         IS 1.0
   HBTEST Log10( Sqrt( 10.0 ) ) IS 0.5
   HBTEST Fact( 0 ) IS 1
   HBTEST Fact( 1 ) IS 1
   HBTEST Fact( 4 ) IS 24
   HBTEST Round( FV( 1000, 0.00, 10 ), 1 ) IS 10000.0
   HBTEST Round( FV( 1000, 0.05, 10 ), 3 ) IS 12577.893
   HBTEST Round( PV( 100, 0.0, 60 ), 1 )   IS 6000.0


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User]
Write the following Harbour (xBase/Clipper) code:

Harbour contribution module 'hbfbird' (Firebird database client): contrib/hbfbird/tests/simple.prg. Contains procedures: Main. This file handles database operations

[Assistant]
#require "hbfbird"

PROCEDURE Main()

   LOCAL oServer, oQuery, oRow, i, x, aTables, aStruct, aKey

   LOCAL cServer := "localhost:"
   LOCAL cDatabase
   LOCAL cUser := "SYSDBA"
   LOCAL cPass := "masterkey"
   LOCAL nPageSize := 1024
   LOCAL cCharSet := "ASCII"
   LOCAL nDialect := 1
   LOCAL cQuery, cName

   hb_FNameSplit( hb_argv( 0 ), NIL, @cName, NIL )
   cDatabase := hb_DirTemp() + cName + ".fdb"

   IF hb_FileExists( cDatabase )
      FErase( cDatabase )
   ENDIF

   ? FBCreateDB( cServer + cDatabase, cUser, cPass, nPageSize, cCharSet, nDialect )

   ? "Connecting..."

   oServer := TFBServer():New( cServer + cDatabase, cUser, cPass, nDialect )

   IF oServer:NetErr()
      ? oServer:Error()
      QUIT
   ENDIF

   ? "Tables..."

   FOR x := 1 TO 1
      aTables := oServer:ListTables()

      FOR i := 1 TO Len( aTables )
         ? aTables[ i ]
      NEXT
   NEXT

   ? "Using implicit transaction..."

   IF oServer:TableExists( "TEST" )
      oServer:Execute( "DROP TABLE Test" )
      oServer:Execute( "DROP DOMAIN boolean_field" )
   ENDIF

   ? "Creating domain for boolean fields..."
   oServer:Execute( "create domain boolean_field as smallint default 0 not null check (value in (0,1))" )

   oServer:StartTransaction()
   ? "Creating test table..."
   cQuery := "CREATE TABLE test("
   cQuery += "     Code SmallInt not null primary key, "
   cQuery += "     dept Integer, "
   cQuery += "     Name Varchar(40), "
   cQuery += "     Sales boolean_field, "
   cQuery += "     Tax Float, "
   cQuery += "     Salary Double Precision, "
   cQuery += "     Budget Numeric(12,2), "
   cQuery += "     Discount Decimal(5,2), "
   cQuery += "     Creation Date, "
   cQuery += "     Description blob sub_type 1 segment size 40 ) "

   oServer:Execute( cQuery )

   IF oServer:NetErr()
      ? oServer:Error()
   ENDIF

   oServer:Commit()

   oServer:Query( "SELECT code, dept, name, sales, salary, creation FROM test" )
   WAIT

   ? "Structure of test table"
   aStruct := oServer:TableStruct( "test" )

   FOR i := 1 TO Len( aStruct )
      ?
      FOR x := 1 TO Len( aStruct[ i ] )
         ?? aStruct[ i, x ]
      NEXT
   NEXT

   ? "Inserting, declared transaction control "
   oServer:StartTransaction()

   FOR i := 1 TO 100
      cQuery := "INSERT INTO test(code, dept, name, sales, tax, salary, budget, Discount, Creation, Description) "
      cQuery += 'VALUES( ' + Str( i ) + ', 2, "TEST", 1, 5, 3000, 1500.2, 7.5, "12-22-2003", "Short Description about what ? ")'

      oServer:Execute( cQuery )

      IF oServer:NetErr()
         ? oServer:error()
      ENDIF
   NEXT

   oServer:Commit()

   oQuery := oServer:Query( "SELECT code, name, description, sales FROM test" )

   aStruct := oQuery:Struct()

   FOR i := 1 TO Len( aStruct )
      ? aStruct[ i, 1 ], aStruct[ i, 2 ], aStruct[ i, 3 ], aStruct[ i, 4 ]
   NEXT

   aKey := oQuery:GetKeyField()

   ? "Fields: ", oQuery:FCount(), "Primary Key: ", aKey[ 1 ]

   oRow := oQuery:Blank()

   ? ;
      oRow:FCount(), ;
      oRow:FieldPos( "code" ), ;
      oRow:FieldGet( 1 ), ;
      oRow:FieldName( 1 ), ;
      oRow:FieldType( 1 ), ;
      oRow:FieldDec( 1 ), ;
      oRow:FieldLen( 1 ), ;
      Len( oRow:Getkeyfield() )

   oRow:FieldPut( 1, 150 )
   oRow:FieldPut( 2, "MY TEST" )

   ? oRow:FieldGet( 1 ), oRow:FieldGet( 2 )

   ? oServer:Append( oRow )

   ? oServer:Delete( oQuery:blank(), "code = 200" )

   ? oServer:Execute( "error caused intentionaly" )

   DO WHILE ! oQuery:Eof()
      oQuery:Skip()
      ? ;
         oQuery:FieldGet( oQuery:FieldPos( "code" ) ), ;
         oQuery:FieldGet( 4 ), ;
         oQuery:FieldGet( 2 ), ;
         oQuery:FieldName( 1 ), ;
         oQuery:FieldType( 1 ), ;
         oQuery:FieldDec( 1 ), ;
         oQuery:FieldLen( 1 ), ;
         oQuery:FieldGet( 3 )

      IF oQuery:RecNo() == 50
         oRow := oQuery:getrow()

         oRow:FieldPut( 2, "My Second test" )
         ? "Update: ", oServer:Update( oRow )
      ENDIF

      IF oQuery:RecNo() == 60
         oRow := oQuery:getrow()
         ? "Delete: ", oServer:Delete( oRow )
      ENDIF
   ENDDO

   ? "Delete: ", oServer:Delete( oQuery:Blank(), "code = 70" )

   oQuery:Refresh()

   DO WHILE oQuery:Fetch()
      oRow := oQuery:getrow()

      ? ;
         oRow:FieldGet( oRow:FieldPos( "code" ) ), ;
         oRow:FieldGet( 4 ), ;
         oRow:FieldGet( 2 ), ;
         oRow:FieldName( 1 ), ;
         oRow:FieldType( 1 ), ;
         oRow:FieldDec( 1 ), ;
         oRow:FieldLen( 1 ), ;
         oRow:FieldGet( 3 )
   ENDDO

   oQuery:Destroy()

   oServer:Destroy()

   ? "Closing..."

   RETURN


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Write a Harbour program with procedures: Main. Harbour test program: tests/codebl2.prg. Contains procedures: Main. This test file tests specific function APIs

[Assistant]
PROCEDURE Main()

   LOCAL i, bBlock[ 3 ]

   MEMVAR  m_Var1, m_Var2, m_Var3, m_Macro
   PRIVATE m_Var1, m_Var2, m_Var3, m_Macro

   m_Var1 := "m_Var1"
   m_Var2 := "m_Var2"
   m_Var3 := "m_Var3"

   FOR i := 1 TO 3
      m_Macro := "m_Var" + Str( i, 1 )
      bBlock[ i ] := {|| &m_Macro }
   NEXT

   ? "Early (Simple):"

   FOR i := 1 TO 3
      ? Eval( bBlock[ i ] )
   NEXT

   FOR i := 1 TO 3
      m_Macro := "m_Var" + Str( i, 1 )
      bBlock[ i ] := {|| &m_Macro + "!" }
   NEXT

   ?
   ? "Early (Complex):"

   FOR i := 1 TO 3
      ? Eval( bBlock[ i ] )
   NEXT

   FOR i := 1 TO 3
      m_Macro := "m_Var" + Str( i, 1 )
      bBlock[ i ] := {|| &( m_Macro ) }
   NEXT

   ?
   ? "Late:"

   FOR i := 1 TO 3
      ? Eval( bBlock[ i ] )
   NEXT

   RETURN


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User]
Here is a Harbour (xBase/Clipper) implementation:

Harbour contribution module 'hbnf' (NanForum Toolkit - legacy Clipper compatibility functions): contrib/hbnf/savesets.prg. Provides functions: ft_SaveSets. This file provides legacy compatibility functions

[Assistant]
#define FT_EXTRA_SETS    2
#define FT_SET_CENTURY   _SET_COUNT + 1
#define FT_SET_BLINK     _SET_COUNT + 2

FUNCTION ft_SaveSets()

   LOCAL aOldSets := Array( _SET_COUNT + FT_EXTRA_SETS )

   AEval( aOldSets, ;
      {| xElement, nElementNo | HB_SYMBOL_UNUSED( xElement ), ;
      aOldSets[ nElementNo ] := Set( nElementNo ) } )

   aOldSets[ FT_SET_CENTURY ] := ft_SetCentury()
   aOldSets[ FT_SET_BLINK ]   := SetBlink()

   RETURN aOldSets


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Generate Harbour code for: Harbour contribution module 'hbfbird' (Firebird database client): contrib/hbfbird/tfirebrd.prg. Defines classes: TFbServer. This file handles database operations

[Assistant]
#include "hbclass.ch"

#define SQL_TEXT            452
#define SQL_VARYING         448
#define SQL_SHORT           500
#define SQL_LONG            496
#define SQL_FLOAT           482
#define SQL_DOUBLE          480
#define SQL_D_FLOAT         530
#define SQL_TIMESTAMP       510
#define SQL_BLOB            520
#define SQL_ARRAY           540
#define SQL_QUAD            550
#define SQL_TYPE_TIME       560
#define SQL_TYPE_DATE       570
#define SQL_INT64           580
#define SQL_DATE                        SQL_TIMESTAMP

CREATE CLASS TFbServer

   VAR db
   VAR trans
   VAR StartedTrans
   VAR nError
   VAR lError
   VAR dialect

   METHOD New( cServer, cUser, cPassword, nDialect )
   METHOD Destroy()  INLINE FBClose( ::db )
   METHOD Close()    INLINE FBClose( ::db )

   METHOD TableExists( cTable )
   METHOD ListTables()
   METHOD TableStruct( cTable )

   METHOD StartTransaction()
   METHOD Commit()
   METHOD Rollback()

   METHOD Execute( cQuery )
   METHOD Query( cQuery )

   METHOD Update( oRow, cWhere )
   METHOD Delete( oRow, cWhere )
   METHOD Append( oRow )

   METHOD NetErr()   INLINE ::lError
   METHOD Error()    INLINE FBError( ::nError )
   METHOD ErrorNo()  INLINE ::nError

ENDCLASS

METHOD New( cServer, cUser, cPassword, nDialect ) CLASS TFbServer

   hb_default( @nDialect, 1 )

   ::lError := .F.
   ::nError := 0
   ::StartedTrans := .F.
   ::Dialect := nDialect

   ::db := FBConnect( cServer, cUser, cPassword )

   IF HB_ISNUMERIC( ::db )
      ::lError := .T.
      ::nError := ::db
   ENDIF

   RETURN Self

METHOD StartTransaction() CLASS TFbServer

   LOCAL result := .F.

   ::trans := FBStartTransaction( ::db )

   IF HB_ISNUMERIC( ::trans )
      ::lError := .T.
      ::nError := ::trans
   ELSE
      result := .T.
      ::lError := .F.
      ::lnError := 0
      ::StartedTrans := .T.
   ENDIF

   RETURN result

METHOD Rollback() CLASS TFbServer

   LOCAL result := .F.
   LOCAL n

   IF ::StartedTrans
      IF ( n := FBRollback( ::trans ) ) < 0
         ::lError := .T.
         ::nError := n
      ELSE
         ::lError := .F.
         ::nError := 0
         result := .T.
         ::StartedTrans := .F.
      ENDIF
   ENDIF

   RETURN result

METHOD Commit() CLASS TFbServer

   LOCAL result := .F.
   LOCAL n

   IF ::StartedTrans
      IF ( n := FBCommit( ::trans ) ) < 0
         ::lError := .T.
         ::nError := n
      ELSE
         ::lError := .F.
         ::nError := 0
         result := .T.
         ::StartedTrans := .F.
      ENDIF
   ENDIF

   RETURN result

METHOD Execute( cQuery ) CLASS TFbServer

   LOCAL result
   LOCAL n

   cQuery := RemoveSpaces( cQuery )

   IF ::StartedTrans
      n := FBExecute( ::db, cQuery, ::dialect, ::trans )
   ELSE
      n := FBExecute( ::db, cQuery, ::dialect )
   ENDIF

   IF n < 0
      ::lError := .T.
      ::nError := n
      result := .F.
   ELSE
      ::lError := .F.
      ::nError := 0
      result := .T.
   ENDIF

   RETURN result

METHOD Query( cQuery ) CLASS TFbServer
   RETURN TFBQuery():New( ::db, cQuery, ::dialect )

METHOD TableExists( cTable ) CLASS TFbServer

   LOCAL cQuery
   LOCAL result := .F.
   LOCAL qry

   cQuery := 'select rdb$relation_name from rdb$relations where rdb$relation_name = "' + Upper( cTable ) + '"'

   qry := FBQuery( ::db, cQuery, ::dialect )

   IF HB_ISARRAY( qry )
      result := ( FBFetch( qry ) == 0 )

      FBFree( qry )
   ENDIF

   RETURN result

METHOD ListTables() CLASS TFbServer

   LOCAL result := {}
   LOCAL cQuery
   LOCAL qry

   cQuery := 'select rdb$relation_name '
   cQuery += '  from rdb$relations '
   cQuery += ' where rdb$relation_name not like "RDB$%" '
   cQuery += '   and rdb$view_blr is null '
   cQuery += ' order by 1 '

   qry := FBQuery( ::db, RemoveSpaces( cQuery ), ::dialect )

   IF HB_ISARRAY( qry )
      DO WHILE FBFetch( qry ) == 0
         AAdd( result, FBGetData( qry, 1 ) )
      ENDDO

      FBFree( qry )
   ENDIF

   RETURN result

METHOD TableStruct( cTable ) CLASS TFbServer

   LOCAL result := {}
   LOCAL cQuery, cType, nSize, cDomain, cField, nType, nDec
   LOCAL qry

   cQuery := 'select '
   cQuery += '  a.rdb$field_name,'
   cQuery += '  b.rdb$field_type,'
   cQuery += '  b.rdb$field_length,'
   cQuery += '  b.rdb$field_scale
   cQuery += '  and a.rdb$relation_name = "' + Upper( ctable ) + '" '
   cQuery += 'order by '
   cQuery += '  a.rdb$field_position '

   qry := FBQuery( ::db, RemoveSpaces( cQuery ), ::dialect )

   IF HB_ISARRAY( qry )
      DO WHILE FBFetch( qry ) == 0
         cField  := FBGetData( qry, 1 )
         nType   := Val( FBGetData( qry, 2 ) )
         nSize   := Val( FBGetData( qry, 3 ) )
         nDec    := Val( FBGetData( qry, 4 ) )
         cDomain := FBGetData( qry, 5 )

         SWITCH nType
         CASE 7
            IF "BOOL" $ cDomain
               cType := "L"
               nSize := 1
               nDec := 0
            ELSE
               cType := "N"
               nSize := 5
            ENDIF

            EXIT

         CASE 8
         CASE 9
            cType := "N"
            nSize := 9
            EXIT

         CASE 10
         CASE 11
            cType := "N"
            nSize := 15
            EXIT

         CASE 12
            cType := "D"
            nSize := 8
            EXIT

         CASE 13
            cType := "C"
            nSize := 10
            EXIT

         CASE 14
            cType := "C"
            EXIT

         CASE 16
            cType := "N"
            nSize := 9
            EXIT

         CASE 27
            cType := "N"
            nSize := 15
            EXIT

         CASE 35
            cType := "D"
            nSize := 8
            EXIT

         CASE 37
         CASE 40
            cType := "C"
            EXIT

         CASE 261
            cType := "M"
            nSize := 10
            EXIT

         OTHERWISE
            cType := "C"
            nDec := 0
         ENDSWITCH

         AAdd( result, { cField, cType, nSize, nDec } )

      ENDDO

      FBFree( qry )
   ENDIF

   RETURN result

METHOD Delete( oRow, cWhere ) CLASS TFbServer

   LOCAL result := .F.
   LOCAL aKeys, i, nField, xField, cQuery, aTables

   aTables := oRow:GetTables()

   IF ! HB_ISNUMERIC( ::db ) .AND. Len( aTables ) == 1

      IF cWhere == NIL
         aKeys := oRow:GetKeyField()

         cWhere := ""
         FOR i := 1 TO Len( aKeys )
            nField := oRow:FieldPos( aKeys[ i ] )
            xField := oRow:FieldGet( nField )

            cWhere += aKeys[ i ] + "=" + DataToSql( xField )

            IF i != Len( aKeys )
               cWhere += ","
            ENDIF
         NEXT
      ENDIF

      IF !( cWhere == "" )
         cQuery := 'DELETE FROM ' + aTables[ 1 ] + ' WHERE ' + cWhere

         result := ::Execute( cQuery )
      ENDIF
   ENDIF

   RETURN result

METHOD Append( oRow ) CLASS TFbServer

   LOCAL result := .F.
   LOCAL cQuery, i, aTables

   aTables := oRow:GetTables()

   IF ! HB_ISNUMERIC( ::db ) .AND. Len( aTables ) == 1

      cQuery := 'INSERT INTO ' + aTables[ 1 ] + '('
      FOR i := 1 TO oRow:FCount()
         IF oRow:Changed( i )

            cQuery += oRow:FieldName( i ) + ","
         ENDIF
      NEXT

      cQuery := Left( cQuery, Len( cQuery ) - 1 ) +  ") VALUES ("

      FOR i := 1 TO oRow:FCount()
         IF oRow:Changed( i )
            cQuery += DataToSql( oRow:FieldGet( i ) ) + ","
         ENDIF
      NEXT

      cQuery := Left( cQuery, Len( cQuery ) - 1  ) + ")"

      result := ::Execute( cQuery )
   ENDIF

   RETURN result

METHOD Update( oRow, cWhere ) CLASS TFbServer

   LOCAL result := .F.
   LOCAL aKeys, cQuery, i, nField, xField, aTables

   aTables := oRow:GetTables()

   IF ! HB_ISNUMERIC( ::db ) .AND. Len( aTables ) == 1

      IF cWhere == NIL
         aKeys := oRow:GetKeyField()

         cWhere := ""
         FOR i := 1 TO Len( aKeys )
            nField := oRow:FieldPos( aKeys[ i ] )
            xField := oRow:FieldGet( nField )


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Generate Harbour code for: Harbour contribution module 'hbnf' (NanForum Toolkit - legacy Clipper compatibility functions): contrib/hbnf/tests/woy.prg. Contains procedures: Main. This file provides legacy compatibility functions

[Assistant]
#require "hbnf"

PROCEDURE Main()

   LOCAL dDate
   LOCAL GetList := {}

   Set( _SET_DATEFORMAT, "yyyy-mm-dd" )

   DO WHILE .T.

      @ 2, 10 SAY "Date to Test"

      dDate := hb_SToD()
      @ 2, 24 GET dDate
      READ

      IF Empty( dDate )
         EXIT
      ENDIF

      @ 4, 10 SAY "Is Day Number " + Str( ft_DoY( dDate ), 10 )
      @ 6, 10 SAY "Is in Week Number " + Str( ft_WoY( dDate ), 10 )
      @ 7, 0

      WAIT

   ENDDO

   RETURN


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User]
Write the following Harbour (xBase/Clipper) code:

Harbour contribution module 'hbtip' (Internet protocol utilities (FTP, HTTP, SMTP, POP3)): contrib/hbtip/encb64.prg. Defines classes: TIPEncoderBase64. This file provides network protocol implementations

[Assistant]
#include "hbclass.ch"

CREATE CLASS TIPEncoderBase64 INHERIT TIPEncoder

   VAR bHttpExcept INIT .F.

   METHOD New() CONSTRUCTOR
   METHOD Encode( cData )
   METHOD Decode( cData )

ENDCLASS

METHOD New() CLASS TIPEncoderBase64

   ::cName := "base64"

   RETURN Self

METHOD Encode( cData ) CLASS TIPEncoderBase64
   RETURN hb_base64Encode( cData, iif( ::bHttpExcept, NIL, 76 ) )

METHOD Decode( cData ) CLASS TIPEncoderBase64
   RETURN hb_base64Decode( cData )


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Generate Harbour code for: Harbour contribution module 'gtwvg' (): contrib/gtwvg/dialog.prg. Defines classes: WvgDialog. This file provides platform-specific functionality

[Assistant]
#include "hbclass.ch"
#include "inkey.ch"
#include "hbgtinfo.ch"

#include "hbgtwvg.ch"
#include "wvtwin.ch"
#include "wvgparts.ch"

CREATE CLASS WvgDialog INHERIT WvgWindow

   VAR    oMenu
   VAR    aRect
   VAR    drawingArea
   VAR    tasklist                              INIT .T.

   METHOD new( oParent, oOwner, aPos, aSize, aPresParams, lVisible )
   METHOD create( oParent, oOwner, aPos, aSize, aPresParams, lVisible )
   METHOD configure( oParent, oOwner, aPos, aSize, aPresParams, lVisible )
   METHOD destroy()
   METHOD setFrameState( nState )
   METHOD getFrameState()
   METHOD menuBar()

   METHOD showModal()                           INLINE NIL
   METHOD setTitle( cTitle )                    INLINE ::title := cTitle, hb_gtInfo( HB_GTI_WINTITLE, cTitle )
   METHOD getTitle()                            INLINE hb_gtInfo( HB_GTI_WINTITLE )
   METHOD calcClientRect()                      INLINE ::aRect := wvg_GetClientRect( ::hWnd ), { 0, 0, ::aRect[ 3 ], ::aRect[ 4 ] }
   METHOD calcFrameRect()                       INLINE ::aRect := wvg_GetWindowRect( ::hWnd ), { ::aRect[ 1 ], ::aRect[ 2 ], ::aRect[ 3 ] - ::aRect[ 1 ], ::aRect[ 4 ] - ::aRect[ 2 ] }

ENDCLASS

METHOD WvgDialog:new( oParent, oOwner, aPos, aSize, aPresParams, lVisible )

   ::WvgWindow:new( oParent, oOwner, aPos, aSize, aPresParams, lVisible )

   ::className   := "WVGDIALOG"
   ::resizeMode  := 0
   ::mouseMode   := 0
   ::objType     := objTypeDialog

   ::style       := WS_THICKFRAME + WS_OVERLAPPED + WS_CAPTION + WS_SYSMENU + WS_MINIMIZEBOX + WS_MAXIMIZEBOX

   RETURN Self

METHOD WvgDialog:create( oParent, oOwner, aPos, aSize, aPresParams, lVisible )

   LOCAL oW

   ::WvgWindow:create( oParent, oOwner, aPos, aSize, aPresParams, lVisible )

   IF ::lModal
      ::pGT  := hb_gtCreate( "WGU" )
      ::pGTp := hb_gtSelect( ::pGT )
   ELSE
      hb_gtReload( "WGU" )
      ::pGT := hb_gtSelect()
   ENDIF

   hb_gtInfo( HB_GTI_PRESPARAMS, { ::exStyle, ::style, ::aPos[ 1 ], ::aPos[ 2 ], ;
      ::aSize[ 1 ], ::aSize[ 2 ], ::pGTp, .F., .F., HB_WNDTYPE_DIALOG } )

   IF ::visible
      hb_gtInfo( HB_GTI_SPEC, HB_GTS_SHOWWINDOW, SW_NORMAL )
   ELSE
      hb_gtInfo( HB_GTI_SPEC, HB_GTS_SHOWWINDOW, SW_HIDE )
   ENDIF

   ::hWnd := hb_gtInfo( HB_GTI_SPEC, HB_GTS_WINDOWHANDLE )

   hb_gtInfo( HB_GTI_RESIZABLE, ::resizable )
   hb_gtInfo( HB_GTI_CLOSABLE, ::closable  )
   hb_gtInfo( HB_GTI_WINTITLE, ::title     )

   IF ! Empty( ::icon )
      IF HB_ISNUMERIC( ::icon )
         hb_gtInfo( HB_GTI_ICONRES, ::icon )

      ELSEIF HB_ISSTRING( ::icon )
         hb_gtInfo( HB_GTI_ICONFILE, ::icon )

      ENDIF
   ENDIF

   IF ::lModal
      hb_gtInfo( HB_GTI_DISABLE, ::pGTp )
   ENDIF

   IF ::visible
      ::lHasInputFocus := .T.
   ENDIF

   oW := WvgDrawingArea():new( Self ):create( , , { 0, 0 }, Self:currentSize(), , .F. )
   IF ! Empty( oW:hWnd )
      ::drawingArea := oW
   ELSE
      ::drawingArea := Self
   ENDIF

   hb_gtInfo( HB_GTI_NOTIFIERBLOCK, {| nEvent, ... | ::notifier( nEvent, ... ) } )

   RETURN Self

METHOD WvgDialog:configure( oParent, oOwner, aPos, aSize, aPresParams, lVisible )

   ::WvgWindow:configure( oParent, oOwner, aPos, aSize, aPresParams, lVisible )

   RETURN Self

METHOD WvgDialog:destroy()

   IF HB_ISOBJECT( ::oMenu )
      ::oMenu:destroy()
   ENDIF

   IF Len( ::aChildren ) > 0
      AEval( ::aChildren, {| o | o:destroy() } )
   ENDIF

   IF ! Empty( ::hBrushBG )
      wvg_DeleteObject( ::hBrushBG )
   ENDIF

   ::pGT  := NIL
   ::pGTp := NIL

   RETURN Self

METHOD WvgDialog:setFrameState( nState )

   LOCAL lSuccess := .F.

   DO CASE

   CASE nState == WVGDLG_FRAMESTAT_MINIMIZED
      RETURN ::sendMessage( WM_SYSCOMMAND, SC_MINIMIZE, 0 ) != 0

   CASE nState == WVGDLG_FRAMESTAT_MAXIMIZED
      RETURN ::sendMessage( WM_SYSCOMMAND, SC_MAXIMIZE, 0 ) != 0

   CASE nState == WVGDLG_FRAMESTAT_NORMALIZED
      RETURN ::sendMessage( WM_SYSCOMMAND, SC_RESTORE, 0 ) != 0

   ENDCASE

   RETURN lSuccess

METHOD WvgDialog:getFrameState()

   IF wvg_IsIconic( ::hWnd )
      RETURN WVGDLG_FRAMESTAT_MINIMIZED
   ENDIF
   IF wvg_IsZoomed( ::hWnd )
      RETURN WVGDLG_FRAMESTAT_MAXIMIZED
   ENDIF

   RETURN WVGDLG_FRAMESTAT_NORMALIZED

METHOD WvgDialog:menuBar()

   IF ! HB_ISOBJECT( ::oMenu )
      ::oMenu := WvgMenuBar():New( Self ):create()
   ENDIF

   RETURN ::oMenu


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Write a Harbour program with procedures: Main. Harbour contribution module 'hbct' (CA-Tools compatibility library): contrib/hbct/tests/charhist.prg. Contains procedures: Main. This file provides legacy compatibility functions

[Assistant]
#ifdef __HARBOUR__
#require "hbct"
#endif

PROCEDURE Main()

   LOCAL nTotal := 0

   ctinit()

   ? "Begin test of CharHist()"
   ?

   ? "Simple tests:"
   ? '  CharHist( "Hello World !" )' + "'109' == 3 ? --> ", CharHist( "Hello World !" )' 109 '
   ? '  AEval( CharHist( "Hello World !" ), {| x | nTotal += x } ) '
   AEval( CharHist( "Hello World !" ), {| x | nTotal += x } )
   ? '    ==> nTotal == Len( "Hello World !" ) ? --> ', nTotal == Len( "Hello World !" )

   ? "End test of CharHist()"
   ?

   ctexit()

   RETURN


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Create Harbour preprocessor definitions: Header file for contribution module 'xhb' (Extended Harbour functions): contrib/xhb/wintypes.ch. Defines 10 constants including: __WINTYPES_CH, VOID, UINT, HANDLE, HICON. Defines error handling constants and codes

[Assistant]
#ifndef __WINTYPES_CH
#define __WINTYPES_CH

#include "cstruct.ch"

#define VOID                 CTYPE_VOID
#define UINT                 CTYPE_UNSIGNED_INT
#define HANDLE               CTYPE_UNSIGNED_LONG
#define HICON                CTYPE_UNSIGNED_LONG
#define HBITMAP              CTYPE_UNSIGNED_LONG
#define HCURSOR              CTYPE_UNSIGNED_LONG
#define HBRUSH               CTYPE_UNSIGNED_LONG
#define LPCSTR               CTYPE_CHAR_PTR
#define WNDPROC              CTYPE_UNSIGNED_LONG
#define BOOL                 CTYPE_LONG
#define LPVOID               CTYPE_VOID_PTR
#define DWORD                CTYPE_UNSIGNED_LONG
#define WORD                 CTYPE_UNSIGNED_SHORT
#define LPCTSTR              CTYPE_CHAR_PTR
#define COLORREF             CTYPE_UNSIGNED_LONG
#define BYTE                 CTYPE_CHAR
#define TCHAR                CTYPE_UNSIGNED_CHAR
#define HINSTANCE            CTYPE_UNSIGNED_LONG
#define HMENU                CTYPE_UNSIGNED_LONG
#define HTREEITEM            CTYPE_UNSIGNED_LONG
#define INT                  CTYPE_INT
#define int                  CTYPE_INT
#define HWND                 CTYPE_UNSIGNED_LONG
#define LPARAM               CTYPE_LONG
#define HGLOBAL              CTYPE_UNSIGNED_LONG
#define WPARAM               CTYPE_INT
#define HKEY                 CTYPE_UNSIGNED_LONG
#define char                 CTYPE_CHAR
#define LONG                 CTYPE_LONG
#define BCHAR                CTYPE_UNSIGNED_CHAR
#define WCHAR                CTYPE_UNSIGNED_SHORT
#define DOUBLE               CTYPE_DOUBLE
#define LPTSTR               CTYPE_CHAR_PTR
#define LPSTR                CTYPE_CHAR_PTR
#define ULONG                CTYPE_UNSIGNED_LONG
#define UCHAR                CTYPE_UNSIGNED_CHAR
#define SHORT                CTYPE_SHORT
#define USHORT               CTYPE_UNSIGNED_SHORT
#define PVOID                CTYPE_VOID_PTR
#define ULONG_PTR            CTYPE_UNSIGNED_LONG_PTR

#define LPOFNHOOKPROC        CTYPE_UNSIGNED_LONG
#define LPCFHOOKPROC         CTYPE_UNSIGNED_LONG
#define LPFRHOOKPROC         CTYPE_UNSIGNED_LONG
#define LPPAGESETUPHOOK      CTYPE_UNSIGNED_LONG
#define LPPAGEPAINTHOOK      CTYPE_UNSIGNED_LONG
#define LPPRINTHOOKPROC      CTYPE_UNSIGNED_LONG
#define LPSETUPHOOKPROC      CTYPE_UNSIGNED_LONG

#define BFFCALLBACK          CTYPE_UNSIGNED_LONG

#define HDC                  CTYPE_UNSIGNED_LONG
#define HIMAGELIST           CTYPE_UNSIGNED_LONG

#ytranslate CTYPE_Int( <x> ) => Int( <x> )

#endif


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Generate Harbour code for: Harbour test program: tests/regex.prg. Contains procedures: Main. This test file exercises basic Harbour language features

[Assistant]
PROCEDURE Main()

   LOCAL regex
   LOCAL aMatch
   LOCAL cStr, nRow := 2, nCol
   LOCAL aSource := { ;
      "First date to match: 2001-3-21", ;
      "2002-12/2", ;
      "Another can be 1999/5/12, and succeeds", ;
      "Could be 1999/534/12, but this will fail" }

   CLS

   @ 0, 15 SAY "Regular expression scan tests"

   regex := hb_regexComp( "([0-9]{4})[-/]([0-9]{1,2})[-/]([0-9]{1,2})" )

   FOR EACH cStr IN aSource
      @ nRow, 5 SAY "String is '" + cStr + "'"
      nRow++
      aMatch := hb_regex( regex, cStr )
      IF ! Empty( aMatch )
         @ nRow, 10 SAY "Matched: " + aMatch[ 1 ] + " ( Year: " + aMatch[ 2 ] + ", Month: " + ;
            aMatch[ 3 ] + ", Day: " + aMatch[ 4 ] + ")"
      ELSE
         @ nRow, 10 SAY "Match FAILED!"
      ENDIF
      nRow += 2
   NEXT

   cStr := "searching 'regex' here:"
   @ nRow, 5 SAY "A test of a regex compiled on the fly; " + cStr
   aMatch := hb_regex( "(.*)regex(.*)", cStr )
   nRow++
   IF Empty( aMatch )
      @ nRow, 10 SAY "NOT FOUND!"
   ELSE
      @ nRow, 10 SAY "Found (Before: <<" + aMatch[ 2 ] + ">>, After: <<" + aMatch[ 3 ] + ">>)"
   ENDIF

   nRow += 2

   cStr := "A str; with: separators :; here "
   @ nRow, 5 SAY "Split test; splitting '" + cStr + "' by ':|;'"
   nRow++
   aMatch := hb_regexSplit( ":|;", cStr )
   IF Empty( aMatch )
      @ nRow++, 10 SAY "Test failed"
   ELSE
      nCol := 10
      FOR EACH cStr IN aMatch
         @ nRow, nCol SAY cStr + "/"
         nCol += Len( cStr ) + 1
      NEXT
      nRow++
   ENDIF

   cStr := "A string without separators"
   @ nRow, 5 SAY "Split test; splitting '" + cStr + "' by ':|;'"
   nRow++
   aMatch := hb_regexSplit( ":|;", cStr )
   IF Empty( aMatch )
      @ nRow++, 10 SAY "Test failed"
   ELSE
      nCol := 10
      FOR EACH cStr IN aMatch
         @ nRow, nCol SAY cStr + "/"
         nCol += Len( cStr ) + 1
      NEXT
      nRow++
   ENDIF

   cStr := "Test for RegexAtX()"
   @ nRow, 5 SAY "RegexAtX() test; scanning '" + cStr + "' by 'Reg(.x)'"
   nRow++
   aMatch := hb_regexAtX( "Reg(.x)", cStr )
   IF Empty( aMatch )
      @ nRow++, 10 SAY "Test failed"
   ELSE
      nCol := 15
      FOR EACH cStr in aMatch
         @ nRow, nCol SAY "FOUND: '" + cStr[ 1 ] + "' Start: " + hb_ntos( cStr[ 2 ] ) + ;
            " End: " + hb_ntos( cStr[ 3 ] )
         nRow++
      NEXT
      nRow++
   ENDIF

   @ nRow, 1
   @ MaxRow(), 25 SAY "Press a key to continue"
   Inkey( 0 )

   RETURN


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Implement this Harbour module: Harbour test program: tests/fornext.prg. Contains procedures: Main. This test file exercises basic Harbour language features

[Assistant]
PROCEDURE Main()

   LOCAL n

   ? "Testing Harbour For Next loops. Going up quick"

   FOR n := 1 TO 10 STEP 4
      ? n
   NEXT

   ? "Going down"

   FOR n := 10 TO 1 STEP -1
      ? n
   NEXT

   ? "No step"

   FOR n := 1 TO 10
      ? n
   NEXT

   ? "No production"

   FOR n := 1 TO 10 STEP -1
      ? n
   NEXT

   ? "Ok!"

   RETURN


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Define Harbour macros and constants: Harbour contribution module 'hbct' (CA-Tools compatibility library): contrib/hbct/fcopy.prg. Provides 6 functions including: FileCopy, FileCOpen, FileCDaTi, FileCCont, FileCCLose. This file provides legacy compatibility functions

[Assistant]
#include "fileio.ch"

#define F_BLOCK   512

THREAD STATIC t_hSrcFile := F_ERROR
THREAD STATIC t_lSetDaTi := .T.
THREAD STATIC t_fileTime

FUNCTION FileCopy( cSource, cDest, lMode )

   LOCAL hDstFile
   LOCAL cBuffer := Space( F_BLOCK )
   LOCAL lDone := .F.
   LOCAL nSrcBytes, nDstBytes, nTotBytes := 0

   hb_default( @lMode, .F. )

   IF t_hSrcFile != F_ERROR
      FClose( t_hSrcFile )
   ENDIF
   t_hSrcFile := FOpen( cSource, FO_READ )
   IF t_hSrcFile != F_ERROR
      hDstFile := FCreate( cDest )
      IF hDstFile != F_ERROR
         DO WHILE .T.
            nSrcBytes := FRead( t_hSrcFile, @cBuffer, F_BLOCK )
            IF nSrcBytes == 0
               lDone := .T.
               EXIT
            ENDIF
            nDstBytes := FWrite( hDstFile, cBuffer, nSrcBytes )
            IF nDstBytes > 0
               nTotBytes += nDstBytes
            ENDIF
            IF nDstBytes < nSrcBytes
               IF lMode
                  FSeek( t_hSrcFile, nDstBytes - nSrcBytes, FS_RELATIVE )
               ENDIF
               EXIT
            ENDIF
         ENDDO
         FClose( hDstFile )
         IF lDone .OR. ! lMode
            FClose( t_hSrcFile )
            t_hSrcFile := F_ERROR
         ENDIF
         hb_FGetDateTime( cSource, @t_fileTime )
         IF t_lSetDaTi .and. !Empty( t_fileTime )
            hb_FSetDateTime( cDest, t_fileTime )
         ENDIF
      ELSE
         FClose( t_hSrcFile )
         t_hSrcFile := F_ERROR
      ENDIF
   ENDIF

   RETURN nTotBytes

FUNCTION FileCOpen()

   RETURN t_hSrcFile != F_ERROR

FUNCTION FileCDaTi( lNewMode )

   LOCAL lOldMode := t_lSetDaTi

   IF HB_ISLOGICAL( lNewMode )
      t_lSetDaTi := lNewMode
   ENDIF

   RETURN lOldMode

FUNCTION FileCCont( cDest )

   LOCAL hDstFile
   LOCAL cBuffer := Space( F_BLOCK )
   LOCAL lDone := .F.
   LOCAL nSrcBytes, nDstBytes, nTotBytes := 0

   IF t_hSrcFile != F_ERROR
      hDstFile := FCreate( cDest )
      IF hDstFile != F_ERROR
         DO WHILE .T.
            nSrcBytes := FRead( t_hSrcFile, @cBuffer, F_BLOCK )
            IF nSrcBytes == 0
               lDone := .T.
               EXIT
            ENDIF
            nDstBytes := FWrite( hDstFile, cBuffer, nSrcBytes )
            IF nDstBytes > 0
               nTotBytes += nDstBytes
            ENDIF
            IF nDstBytes < nSrcBytes
               EXIT
            ENDIF
         ENDDO
         FClose( hDstFile )
         IF lDone
            FClose( t_hSrcFile )
            t_hSrcFile := F_ERROR
         ENDIF
         IF t_lSetDaTi .and. !Empty( t_fileTime )
            hb_FSetDateTime( cDest, t_fileTime )
         ENDIF
      ENDIF
   ENDIF

   RETURN nTotBytes

FUNCTION FileCCLose()

   IF t_hSrcFile != F_ERROR
      FClose( t_hSrcFile )
      t_hSrcFile := F_ERROR
      RETURN .T.
   ENDIF

   RETURN .F.

FUNCTION FileAppend( cSrc, cDest )

   LOCAL cBuffer := Space( F_BLOCK )
   LOCAL hSrcFile, hDstFile
   LOCAL nSrcBytes, nDstBytes, nTotBytes := 0

   hSrcFile := FOpen( cSrc, FO_READ )
   IF hSrcFile != F_ERROR
      IF ! hb_FileExists( cDest )
         hDstFile := FCreate( cDest )
      ELSE
         hDstFile := FOpen( cDest, FO_WRITE )
         FSeek( hDstFile, 0, FS_END )
      ENDIF

      IF hDstFile != F_ERROR
         DO WHILE .T.
            nSrcBytes := FRead( hSrcFile, @cBuffer, F_BLOCK )
            IF nSrcBytes == 0
               EXIT
            ENDIF
            nDstBytes := FWrite( hDstFile, cBuffer, nSrcBytes )
            IF nDstBytes < nSrcBytes
               EXIT
            ENDIF
            nTotBytes += nDstBytes
         ENDDO
         FClose( hDstFile )
      ENDIF
      FClose( hSrcFile )
   ENDIF

   RETURN nTotBytes


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User]
Write the following Harbour (xBase/Clipper) code:

Harbour contribution module 'hbnf' (NanForum Toolkit - legacy Clipper compatibility functions): contrib/hbnf/tests/at2.prg. Contains procedures: Main. This file provides legacy compatibility functions

[Assistant]
#require "hbnf"

PROCEDURE Main()

   LOCAL cSearch, cTarget, var0

   CLS
   ? "TEST TO DEMONSTRATE EXAMPLES OF FT_AT2"
   ?
   cSearch := "t"
   ? "Find occurrences of 't' in: "
   cTarget := "This is the day that the Lord has made."
   ?? cTarget
   ?
   var0 := ft_At2( cSearch, cTarget )
   ? PadR( "ft_At2( cSearch, cTarget ) -> ", 40 )
   ?? var0
   ?
   var0 := ft_At2( cSearch, cTarget, 2 )
   ? PadR( "ft_At2( cSearch, cTarget, 2 ) -> ", 40 )
   ??var0
   ?
   var0 := ft_At2( cSearch, cTarget, 2, .F. )
   ? PadR( "ft_At2( cSearch, cTarget, 2, .F. ) -> ", 40 )
   ??var0
   ?

   RETURN


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User]
Write the following Harbour (xBase/Clipper) code:

Harbour Runtime Library file: src/rtl/tpopup.prg. Defines classes: PopupMenu. This file implements menu system classes

[Assistant]
#include "hbclass.ch"

#include "box.ch"
#include "button.ch"
#include "color.ch"

#ifdef HB_COMPAT_C53

CREATE CLASS PopupMenu FUNCTION HBPopupMenu

   EXPORTED:

   VAR cargo

   METHOD addItem( oItem )
   METHOD close( lCloseChild )
   METHOD delItem( nPos )
   METHOD display()
   METHOD getAccel( xKey )
   METHOD getFirst()
   METHOD getItem( nPos )
   METHOD getLast()
   METHOD getNext()
   METHOD getPrev()
   METHOD getShortCt( nKey )
   METHOD hitTest( nMRow, nMCol )
   METHOD insItem( nPos, oItem )
   METHOD isOpen()
   METHOD open()
   METHOD select( nPos )
   METHOD setItem( nPos, oItem )

   METHOD border( cBorder ) SETGET
   METHOD bottom( nBottom ) SETGET
   METHOD colorSpec( cColorSpec ) SETGET
   METHOD current() SETGET
   METHOD itemCount() SETGET
   METHOD left( nLeft ) SETGET
   METHOD right( nRight ) SETGET
   METHOD top( nTop ) SETGET
   METHOD width() SETGET

   METHOD Init( nTop, nLeft, nBottom, nRight )

   PROTECTED:

   VAR cBorder    INIT HB_B_SINGLE_UNI + HB_SEPARATOR_SINGLE_UNI
   VAR nBottom
   VAR cColorSpec
   VAR nCurrent   INIT 0
   VAR nItemCount INIT 0
   VAR nLeft
   VAR nRight
   VAR nTop
   VAR nWidth     INIT 0

   VAR aItems     INIT {}
   VAR aSaveScr

   VAR lShadowed  INIT .F.

   METHOD setMetrics()

ENDCLASS

METHOD addItem( oItem ) CLASS PopupMenu

   IF HB_ISOBJECT( oItem ) .AND. oItem:ClassName() == "MENUITEM"

      AAdd( ::aItems, oItem )
      ::nItemCount++

      ::nWidth := Max( __CapMetrics( oItem ), ::nWidth )

   ENDIF

   RETURN Self

METHOD close( lCloseChild ) CLASS PopupMenu

   __defaultNIL( @lCloseChild, .T. )

   IF ::isOpen()

      ::setMetrics()

      IF ::nCurrent > 0 .AND. ;
         ::aItems[ ::nCurrent ]:isPopUp() .AND. ;
         ::aItems[ ::nCurrent ]:data:isOpen()

         ::aItems[ ::nCurrent ]:data:Close()
      ENDIF

      RestScreen( ::aSaveScr[ 1 ], ::aSaveScr[ 2 ], ::aSaveScr[ 3 ], ::aSaveScr[ 4 ], ::aSaveScr[ 5 ] )

      ::aSaveScr := NIL
      ::nCurrent := 0
   ENDIF

   RETURN Self

METHOD delItem( nPos ) CLASS PopupMenu

   LOCAL nLen
   LOCAL nWidth
   LOCAL item

   IF nPos >= 1 .AND. nPos <= ::nItemCount

      nLen := Len( ::aItems[ nPos ]:caption )

      hb_ADel( ::aItems, nPos, .T. )
      ::nItemCount--

      IF ::nWidth == nLen + 2
         nWidth := 0
         FOR EACH item IN ::aItems
            nWidth := Max( __CapMetrics( item ), nWidth )
         NEXT
         ::nWidth := nWidth
      ENDIF
   ENDIF

   RETURN Self

METHOD display() CLASS PopupMenu

   LOCAL nTop
   LOCAL nLeft
   LOCAL nCurrent
   LOCAL item
   LOCAL nWidth
   LOCAL oPopup
   LOCAL nHotKeyPos
   LOCAL cCaption
   LOCAL nCharPos

   IF ::isOpen()

      ::setMetrics()

      nTop     := ::nTop
      nLeft    := ::nLeft
      nCurrent := ::nCurrent
      nWidth   := ::nWidth

      DispBegin()

      hb_DispBox( nTop, nLeft, ::nBottom, ::nRight, ;
                  SubStr( ::cBorder, 1, 8 ) + " ", ;
                  hb_ColorIndex( ::cColorSpec, 5 ) )

      IF ::lShadowed
         hb_Shadow( nTop, nLeft, ::nBottom, ::nRight )
      ENDIF

      nLeft++
      FOR EACH item IN ::aItems

         nTop++

         IF item:__issep

            hb_DispOutAtBox( nTop, nLeft - 1, SubStr( ::cBorder, 9, 1 ) + Replicate( SubStr( ::cBorder, 10, 1 ), nWidth ) + SubStr( ::cBorder, 11, 1 ), hb_ColorIndex( ::cColorSpec, 5 ) )

         ELSE
            cCaption := PadR( item:caption, nWidth - 1 )

            IF item:checked
               cCaption := SubStr( item:style, 1, 1 ) + cCaption
            ELSE
               cCaption := " " + cCaption
            ENDIF

            IF item:isPopup()

               oPopup := item:data
               oPopup:top    := nTop
               oPopup:left   := ::nRight + 1
               oPopup:bottom := NIL
               oPopup:right  := NIL

               cCaption += SubStr( item:style, 2, 1 )
            ELSE
               cCaption += " "
            ENDIF

            item:__row := nTop
            item:__col := nLeft

            IF ( nHotKeyPos := At( "&", cCaption ) ) == 0
               IF ( nCharPos := RAt( SubStr( item:style, 2, 1 ), cCaption ) ) > 0
                  cCaption := Stuff( cCaption, nCharPos - 1, 1, "" )
               ELSE
                  cCaption := hb_StrShrink( cCaption )
               ENDIF
            ELSEIF nHotKeyPos == Len( RTrim( cCaption ) )
               cCaption := hb_StrShrink( cCaption )
               nHotKeyPos := 0
            ELSE
               cCaption := Stuff( cCaption, nHotKeyPos, 1, "" )
            ENDIF

            hb_DispOutAt( nTop, nLeft, cCaption, hb_ColorIndex( ::cColorSpec, iif( item:__enumIndex() == nCurrent, 1, iif( item:enabled, 0, 4 ) ) ) )

            IF item:enabled .AND. nHotKeyPos != 0
               hb_DispOutAt( nTop, nLeft + nHotKeyPos - 1, SubStr( cCaption, nHotKeyPos, 1 ), hb_ColorIndex( ::cColorSpec, iif( item:__enumIndex() == nCurrent, 3, 2 ) ) )
            ENDIF
         ENDIF
      NEXT

      DispEnd()

   ENDIF

   RETURN Self

METHOD getAccel( xKey ) CLASS PopupMenu

   LOCAL cKey
   LOCAL item

   DO CASE
   CASE HB_ISSTRING( xKey )
      cKey := xKey
   CASE HB_ISNUMERIC( xKey )
      cKey := hb_keyChar( xKey )
   OTHERWISE
      RETURN 0
   ENDCASE

   IF Len( cKey ) > 0
      cKey := "&" + cKey
      FOR EACH item in ::aItems
         IF hb_AtI( cKey, item:caption ) > 0
            RETURN item:__enumIndex()
         ENDIF
      NEXT
   ENDIF

   RETURN 0

METHOD getFirst() CLASS PopupMenu

   LOCAL item

   FOR EACH item IN ::aItems
      IF item:enabled
         RETURN item:__enumIndex()
      ENDIF
   NEXT

   RETURN 0

METHOD getItem( nPos ) CLASS PopupMenu
   RETURN iif( nPos >= 1 .AND. nPos <= ::nItemCount, ::aItems[ nPos ], NIL )

METHOD getLast() CLASS PopupMenu

   LOCAL item

   FOR EACH item IN ::aItems DESCEND
      IF item:enabled
         RETURN item:__enumIndex()
      ENDIF
   NEXT

   RETURN 0

METHOD getNext() CLASS PopupMenu

   LOCAL nPos

   FOR nPos := ::nCurrent + 1 TO ::nItemCount
      IF ::aItems[ nPos ]:enabled
         RETURN nPos
      ENDIF
   NEXT

   RETURN 0

METHOD getPrev() CLASS PopupMenu

   LOCAL nPos

   FOR nPos := ::nCurrent - 1 TO 1 STEP -1
      IF ::aItems[ nPos ]:enabled
         RETURN nPos
      ENDIF
   NEXT

   RETURN 0

METHOD getShortCt( nKey ) CLASS PopupMenu

   LOCAL item

   FOR EACH item IN ::aItems
      IF item:shortcut == nKey
         RETURN item:__enumIndex()
      ENDIF
   NEXT

   RETURN 0

METHOD hitTest( nMRow, nMCol ) CLASS PopupMenu

   LOCAL nPos

   ::setMetrics()

   DO CASE
   CASE nMRow == ::nTop
      IF nMCol == ::nLeft
         RETURN HTTOPLEFT
      ELSEIF nMCol == ::nRight
         RETURN HTTOPRIGHT
      ELSEIF nMCol >= ::nLeft .AND. nMCol <= ::nRight
         RETURN HTTOP
      ENDIF
   CASE nMRow == ::nBottom
      IF nMCol == ::nLeft
         RETURN HTBOTTOMLEFT
      ELSEIF nMCol == ::nRight
         RETURN HTBOTTOMRIGHT
      ELSEIF nMCol >= ::nLeft .AND. nMCol <= ::nRight
         RETURN HTBOTTOM
      ENDIF
   CASE nMCol == ::nLeft
      IF nMRow >= ::nTop .AND. nMRow <= ::nBottom
         RETURN HTLEFT
      ELSE
         RETURN HTNOWHERE
      ENDIF
   CASE nMCol == ::nRight
      IF nMRow >= ::nTop .AND. nMRow <= ::nBottom
         RETURN HTRIGHT
      ELSE
         RETURN HTNOWHERE
      ENDIF
   CASE nMRow > ::nTop .AND. ;
        nMRow < ::nBottom .AND. ;
        nMCol > ::nLeft .AND. ;
        nMCol < ::nRight

      nPos := nMRow - ::nTop
      DO CASE
      CASE ::aItems[ nPos ]:__issep
         RETURN HTSEPARATOR
      OTHERWISE
         RETURN nPos
      ENDCASE
   ENDCASE

   RETURN HTNOWHERE

METHOD insItem( nPos, oItem ) CLASS PopupMenu

   IF nPos >= 1 .AND. nPos <= ::nItemCount .AND. ;
      HB_ISOBJECT( oItem ) .AND. oItem:ClassName() == "MENUITEM"

      hb_AIns( ::aItems, nPos, oItem, .T. )
      ::nItemCount++

      ::nWidth := Max( __CapMetrics( oItem ), ::nWidth )
   ENDIF

   RETURN Self

METHOD isOpen() CLASS PopupMenu
   RETURN ::aSaveScr != NIL


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User]
Write the following Harbour (xBase/Clipper) code:

Harbour contribution module 'hbnf' (NanForum Toolkit - legacy Clipper compatibility functions): contrib/hbnf/dayofyr.prg. Provides functions: ft_DayOfYr. This file provides legacy compatibility functions

[Assistant]
FUNCTION ft_DayOfYr( dGivenDate, nDayNum, lIsAcct )

   LOCAL nTemp, aRetVal

   IF HB_ISNUMERIC( dGivenDate )
      nDayNum    := dGivenDate
      dGivenDate := Date()
   ELSEIF HB_ISLOGICAL( dGivenDate )
      lIsAcct    := dGivenDate
      dGivenDate := Date()
   ELSEIF ! HB_ISDATE( dGivenDate )
      dGivenDate := Date()
   ENDIF

   IF HB_ISLOGICAL( lIsAcct )
      aRetVal := ft_AcctYear( dGivenDate )
   ELSE
      aRetVal := ft_Year( dGivenDate )
   ENDIF

   IF HB_ISNUMERIC( nDayNum )
      nTemp := aRetVal[ 3 ] - aRetVal[ 2 ] + 1
      IF nDayNum < 1 .OR. nDayNum > nTemp
         nDayNum := nTemp
      ENDIF
      aRetVal[ 1 ] := aRetVal[ 2 ] + nDayNum - 1
   ELSE
      aRetVal[ 1 ] += StrZero( dGivenDate - aRetVal[ 2 ] + 1, 3 )
   ENDIF

   RETURN aRetVal


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Create Harbour preprocessor definitions: Harbour contribution module 'hbsqlit3' (SQLite3 database client library): contrib/hbsqlit3/tests/blob.prg. Contains procedures: Main. This file handles database operations

[Assistant]
#require "hbsqlit3"

#define TABLE_SQL "CREATE TABLE image( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT(50), image BLOB )"

PROCEDURE Main()

   LOCAL lCreateIfNotExist := .T.
   LOCAL db := sqlite3_open( "test.s3db", lCreateIfNotExist )
   LOCAL stmt
   LOCAL buff, blob

   IF ! Empty( db )

      sqlite3_exec( db, "PRAGMA auto_vacuum=0" )
      sqlite3_exec( db, "PRAGMA page_size=8192" )

      sqlite3_exec( db, "DROP TABLE image" )

      sqlite3_exec( db, TABLE_SQL )

      stmt := sqlite3_prepare( db, "INSERT INTO image( title, image ) VALUES( :title, :image )" )
      IF ! Empty( stmt )
         buff := sqlite3_file_to_buff( "pngtest.png" )

         IF sqlite3_bind_text( stmt, 1, "pngtest.png" ) == SQLITE_OK .AND. ;
            sqlite3_bind_blob( stmt, 2, @buff ) == SQLITE_OK
            IF sqlite3_step( stmt ) == SQLITE_DONE
               ? "Save pngtest.png into BLOB"
               ? "INSERT INTO image( title, image ) VALUES( 'pngtest.png', 'pngtest.png' ) - Done"
            ENDIF
         ENDIF
         buff := NIL
         sqlite3_clear_bindings( stmt )
         sqlite3_finalize( stmt )
      ENDIF

      ? ""
      ? "The number of database rows that were changed: " + hb_ntos( sqlite3_changes( db ) )
      ? "Total changes: " + hb_ntos( sqlite3_total_changes( db ) )
      ? ""
      sqlite3_sleep( 3000 )

      blob := sqlite3_blob_open( db, NIL, "image", "image", sqlite3_last_insert_rowid( db ), 0  )
      IF ! Empty( blob )
         ? "Open BLOB image - Ok"

         buff := sqlite3_blob_read( blob )

         ? "The size in bytes of the blob - ", sqlite3_blob_bytes( blob )

         IF sqlite3_buff_to_file( "pngtest1.png", @buff ) == SQLITE_OK
            ? "Save BLOB into pngtest1.png - Done"
         ENDIF

         buff := NIL

         sqlite3_blob_close( blob )
         ? "Close BLOB"
      ENDIF
      sqlite3_sleep( 3000 )

      ? ""
      ? "Save BLOB using sqlite3_column_blob()"
      stmt := sqlite3_prepare( db, "SELECT image FROM image WHERE id == ?5 " )
      IF ! Empty( stmt )
         IF sqlite3_bind_int64( stmt, 5, sqlite3_last_insert_rowid( db ) ) == SQLITE_OK
            IF sqlite3_step( stmt ) == SQLITE_ROW
               buff := sqlite3_column_blob( stmt, 1 )
               IF sqlite3_buff_to_file( "pngtest2.png", @buff ) == SQLITE_OK
                  ? "Save BLOB into pngtest2.png - Done"
               ENDIF
               buff := NIL
            ENDIF
            sqlite3_clear_bindings( stmt )
            sqlite3_finalize( stmt )
         ENDIF
      ENDIF
      WAIT
   ENDIF

   RETURN


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User]
Write the following Harbour (xBase/Clipper) code:

Harbour contribution module 'hbhpdf' (PDF generation library (libharu)): contrib/hbhpdf/misc.prg. Provides functions: hb_HPDF_IsVersion. This file provides graphics and image processing capabilities

[Assistant]
FUNCTION hb_HPDF_IsVersion( ma, mi, mu )

   LOCAL HPDF_MAJOR_VERSION, HPDF_MINOR_VERSION, HPDF_BUGFIX_VERSION

   hb_HPDF_Version( @HPDF_MAJOR_VERSION, @HPDF_MINOR_VERSION, @HPDF_BUGFIX_VERSION )

   RETURN ;
      HPDF_MAJOR_VERSION > ma .OR. ;
      ( HPDF_MAJOR_VERSION == ma .AND. ;
      ( HPDF_MINOR_VERSION > mi .OR. ;
      ( HPDF_MINOR_VERSION == mi .AND. HPDF_BUGFIX_VERSION >= mu ) ) )


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Implement this Harbour module: Harbour test program: tests/datetime.prg. Contains procedures: Main. This test file exercises basic Harbour language features

[Assistant]
#include "simpleio.ch"

PROCEDURE Main()

   ? hb_DateTime( 1974 )

   ? " ValType( hb_DateTime() ) =>", ValType( hb_DateTime() )
   ? " Year(    hb_DateTime() ) =>", Year(    hb_DateTime() )
   ? " Month(   hb_DateTime() ) =>", Month(   hb_DateTime() )
   ? " Day(     hb_DateTime() ) =>", Day(     hb_DateTime() )
   ?

   ? " ValType( hb_DateTime( 1974, 5, 31 ) ) =>", ValType( hb_DateTime( 1974, 5, 31 ) )
   ? " Year(    hb_DateTime( 1974, 5, 31 ) ) =>", Year(    hb_DateTime( 1974, 5, 31 ) )
   ? " Month(   hb_DateTime( 1974, 5, 31 ) ) =>", Month(   hb_DateTime( 1974, 5, 31 ) )
   ? " Day(     hb_DateTime( 1974, 5, 31 ) ) =>", Day(     hb_DateTime( 1974, 5, 31 ) )
   ? " DToC(    hb_DateTime( 1974, 5, 31 ) ) =>", DToC(    hb_DateTime( 1974, 5, 31 ) )
   ?

   ? " ValType( hb_DateTime( 1974, 31, 5, NIL, NIL, NIL ) ) =>", ValType( hb_DateTime( 1974, 31, 5, NIL, NIL, NIL ) )
   ?

   ? " ValType( hb_DateTime( 2001, 10, 13, 18, 42, 16 ) ) =>", ValType( hb_DateTime( 2001, 10, 13, 18, 42, 16 ) )
   ?

   ? " ValType( hb_DateTime( NIL, NIL, NIL, 10, 36, 5 ) )     =>", ValType( hb_DateTime( NIL, NIL, NIL, 10, 36, 5 ) )
   ? "          hb_DateTime( NIL, NIL, NIL, 10, 36, 5 )       =>",          hb_DateTime( NIL, NIL, NIL, 10, 36, 5 )
   ?

   ? " ValType( hb_DateTime( NIL, NIL, NIL, 10, 36, 5, 176 ) ) =>", ValType( hb_DateTime( NIL, NIL, NIL, 10, 36, 5, 176 ) )
   ? "          hb_DateTime( NIL, NIL, NIL, 10, 36, 5, 176 )   =>",          hb_DateTime( NIL, NIL, NIL, 10, 36, 5, 176 )

   ? " ValType( hb_DateTime( 0, 0, 0, 10, 36, 5, 176 ) ) =>", ValType( hb_DateTime( 0, 0, 0, 10, 36, 5, 176 ) )
   ? "          hb_DateTime( 0, 0, 0, 10, 36, 5, 176 )   =>",          hb_DateTime( 0, 0, 0, 10, 36, 5, 176 )

   RETURN


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Write a Harbour program with procedures: Main, DrawFlake, KochFlake. Harbour contribution module 'hbgd' (Graphics drawing library (GD)): contrib/hbgd/tests/tpoly.prg. Contains procedures: Main, DrawFlake, KochFlake. This file provides graphics and image processing capabilities

[Assistant]
#require "hbgd"

#command TurnRight( <x> ) => s_nAngle += Pi() / 3
#define IMAGES_OUT "imgs_out" + hb_ps()

STATIC s_aCoords
STATIC s_nAngle, s_nCoordX, s_nCoordY

PROCEDURE Main()

   DrawFlake( .T. )
   DrawFlake( .F. )

   RETURN

PROCEDURE DrawFlake( lOpenPoly )

   LOCAL nOrder, nSide, nSides, nSideLen
   LOCAL gdImage, gdColor
   LOCAL cImageName

   nSides := 3
   nSideLen := 1500
   nOrder := 7

   cImageName := iif( lOpenPoly, "flakeo.png", "flake.png" )

   gdImage := gdImageCreate( 1900, 2100 )
   gdImageColorAllocate( gdImage, 0, 0, 0 )

   s_nCoordX := 200
   s_nCoordY := 600
   s_aCoords := { { s_nCoordX, s_nCoordY } }
   s_nAngle := 0

   FOR nSide := 1 TO nSides
      KochFlake( nOrder, nSideLen, .F. )
      s_nAngle += Pi()
   ? hb_StrFormat( "Drawing %d vertices", Len( s_aCoords ) )

   gdColor := gdImageColorAllocate( gdImage, 0, 255, 0 )

   IF lOpenPoly
      gdImageOpenPolygon( gdImage, s_aCoords, gdColor )
   ELSE
      gdImagePolygon( gdImage, s_aCoords, gdColor )
   ENDIF

   s_nCoordX := 200
   s_nCoordY := 600
   s_aCoords := { { s_nCoordX, s_nCoordY } }
   s_nAngle := 0

   FOR nSide := 1 TO nSides
      KochFlake( nOrder, nSideLen, .T. )
      s_nAngle += Pi()
   ? hb_StrFormat( "Drawing %d vertices", Len( s_aCoords ) )

   gdColor := gdImageColorAllocate( gdImage, 255, 255, 0 )

   IF lOpenPoly
      gdImageOpenPolygon( gdImage, s_aCoords, gdColor )
   ELSE
      gdImagePolygon( gdImage, s_aCoords, gdColor )
   ENDIF

   gdImagePng( gdImage, IMAGES_OUT + cImageName )

   RETURN

PROCEDURE KochFlake( nOrder, nSideLen, lLeftFirst )

   IF nOrder == 0
      AAdd( s_aCoords, { ;
         s_nCoordX += Cos( s_nAngle )


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User]
Here is a Harbour (xBase/Clipper) implementation:

Harbour test program: tests/usrrdd/exmemo.prg. Contains procedures: Main. This test file exercises basic Harbour language features

[Assistant]
REQUEST DBTCDX
REQUEST FPTCDX
REQUEST SMTCDX

PROCEDURE Main()

   dbCreate( "table1", { { "F1", "M", 4, 0 } }, "DBTCDX" )
   dbCreate( "table2", { { "F1", "M", 4, 0 } }, "FPTCDX" )
   dbCreate( "table3", { { "F1", "M", 4, 0 } }, "SMTCDX" )

   RETURN


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Generate Harbour code for: Harbour contribution module 'hbnf' (NanForum Toolkit - legacy Clipper compatibility functions): contrib/hbnf/tests/findith.prg. Contains procedures: Main. This file provides legacy compatibility functions

[Assistant]
#require "hbnf"

PROCEDURE Main( cCk, cStr, nOcc, xCase )

   LOCAL nFind

   IF PCount() != 4
      ? "usage: findith cCk cStr nOcc xCase"
   ELSE
      xCase := iif( xCase == "Y", .T., .F. )
      nOcc  := Val( nOcc )
      ? iif( xCase, "Ignoring ", "Observing " ) + "case:"

      ? cStr
      nFind := ft_FindITh( cCk, cStr, nOcc, xCase )
      ? iif( nFind > 0, Space( nFind - 1 ) + "^", "Not found" )
   ENDIF

   RETURN


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User]
Here is a Harbour (xBase/Clipper) implementation:

Harbour contribution module 'hbmxml' (XML generation library): contrib/hbmxml/tests/testmxml.prg. Contains procedures: Main. This file handles data format parsing and generation

[Assistant]
#require "hbmxml"

#include "simpleio.ch"

REQUEST HB_GT_CGI_DEFAULT

STATIC s_aTypes := { ;
   "MXML_ELEMENT", ;
   "MXML_INTEGER", ;
   "MXML_OPAQUE", ;
   "MXML_REAL", ;
   "MXML_TEXT" }

STATIC s_aSAXEventCounts := { 0, 0, 0, 0, 0, 0 }

PROCEDURE Main( cFileArg )

   LOCAL hTree
   LOCAL hNode
   LOCAL hInd
   LOCAL nNum, cStr
   LOCAL i

   IF Empty( cFileArg )
      OutErr( hb_StrFormat( "Usage: %1$s filename.xml", hb_ProgName() ) + hb_eol() )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   hTree := mxmlNewElement( MXML_NO_PARENT, "element" )
   IF Empty( hTree )
      OutErr( "ERROR: No parent node in basic test!" + hb_eol() )
      QUIT
   ENDIF

   nNum := mxmlGetType( hTree )
   IF nNum != MXML_ELEMENT
      IF nNum < MXML_ELEMENT .OR. nNum > MXML_TEXT
         OutErr( hb_StrFormat( "ERROR: Parent has type %s (%d), expected MXML_ELEMENT!", ;
            "UNKNOWN", nNum ) + hb_eol() )
      ELSE
         OutErr( hb_StrFormat( "ERROR: Parent has type %s (%d), expected MXML_ELEMENT!", ;
            s_aTypes[ nNum + 1 ], nNum ) + hb_eol() )
      ENDIF

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   cStr := mxmlGetElement( hTree )
   IF !( cStr == "element" )
      OutErr( hb_StrFormat( "ERROR: Parent value is '%s', expected 'element'", cStr ) + hb_eol() )

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   mxmlNewInteger( hTree, 123 )
   mxmlNewOpaque( hTree, "opaque" )
   mxmlNewReal( hTree, 123.4 )
   mxmlNewText( hTree, 1, "text" )

   mxmlLoadString( hTree, "<group type='string'>string string string</group>", MXML_NO_CALLBACK )
   mxmlLoadString( hTree, "<group type='integer'>1 2 3</group>", MXML_INTEGER_CALLBACK )
   mxmlLoadString( hTree, "<group type='real'>1.0 2.0 3.0</group>", MXML_REAL_CALLBACK )
   mxmlLoadString( hTree, "<group>opaque opaque opaque</group>", MXML_OPAQUE_CALLBACK )
   mxmlLoadString( hTree, "<foo><bar><one><two>value<two>value2</two></two></one></bar></foo>", MXML_OPAQUE_CALLBACK )

   IF Empty( hNode := mxmlGetFirstChild( hTree ) )
      OutErr( "ERROR: No first child in basic test!" + hb_eol() )

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   nNum := mxmlGetType( hNode )
   IF nNum != MXML_INTEGER
      IF nNum < MXML_ELEMENT .OR. nNum > MXML_TEXT
         OutErr( hb_StrFormat( "ERROR: First child has type %s (%d), expected MXML_TEXT!", ;
            "UNKNOWN", nNum ) + hb_eol() )
      ELSE
         OutErr( hb_StrFormat( "ERROR: First child has type %s (%d), expected MXML_TEXT!", ;
            s_aTypes[ nNum + 1 ], nNum ) + hb_eol() )
      ENDIF

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   nNum := mxmlGetInteger( hNode )
   IF nNum != 123
      OutErr( hb_StrFormat( "ERROR: First child value is %d, expected 123!", nNum ) + hb_eol() )

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   hNode := mxmlGetNextSibling( hNode )
   IF Empty( hNode )
      OutErr( "ERROR: No second child node in basic test!" + hb_eol() )

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   nNum := mxmlGetType( hNode )
   IF nNum != MXML_OPAQUE
      IF nNum < MXML_ELEMENT .OR. nNum > MXML_TEXT
         OutErr( hb_StrFormat( "ERROR: Second child has type %s (%d), expected MXML_OPAQUE!", ;
            "UNKNOWN", nNum ) + hb_eol() )
      ELSE
         OutErr( hb_StrFormat( "ERROR: Second child has type %s (%d), expected MXML_OPAQUE!", ;
            s_aTypes[ nNum + 1 ], nNum ) + hb_eol() )
      ENDIF

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   hNode := mxmlGetNextSibling( hNode )
   IF Empty( hNode )
      OutErr( "ERROR: No third child node in basic test!" + hb_eol() )

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   nNum := mxmlGetType( hNode )
   IF nNum != MXML_REAL
      IF nNum < MXML_ELEMENT .OR. nNum > MXML_TEXT
         OutErr( hb_StrFormat( "ERROR: Third child has type %s (%d), expected MXML_REAL!", ;
            "UNKNOWN", nNum ) + hb_eol() )
      ELSE
         OutErr( hb_StrFormat( "ERROR: Third child has type %s (%d), expected MXML_REAL!", ;
            s_aTypes[ nNum + 1 ], nNum ) + hb_eol() )
      ENDIF

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   nNum := mxmlGetReal( hNode )
   IF nNum != 123.4
      OutErr( hb_StrFormat( "ERROR: Third child value is %f, expected 123.4!", nNum ) + hb_eol() )

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   hNode := mxmlGetNextSibling( hNode )
   IF Empty( hNode )
      OutErr( "ERROR: No fourth child node in basic test!" + hb_eol() )

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   nNum := mxmlGetType( hNode )
   IF nNum != MXML_TEXT
      IF nNum < MXML_ELEMENT .OR. nNum > MXML_TEXT
         OutErr( hb_StrFormat( "ERROR: Fourth child has type %s (%d), expected MXML_TEXT!", ;
            "UNKNOWN", nNum ) + hb_eol() )
      ELSE
         OutErr( hb_StrFormat( "ERROR: Fourth child has type %s (%d), expected MXML_TEXT!", ;
            s_aTypes[ nNum + 1 ], nNum ) + hb_eol() )
      ENDIF

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   cStr := mxmlGetText( hNode, @nNum )
   IF nNum != 1 .OR. Empty( cStr ) .OR. !( cStr == "text" )
      OutErr( hb_StrFormat( "ERROR: Fourth child value is %d, '%s', expected 1, 'text'!", ;
         nNum, cStr ) + hb_eol() )

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   FOR i := 0 TO 3
      IF Empty( hNode := mxmlGetNextSibling( hNode ) )
         OutErr( hb_StrFormat( "ERROR: No group #%d child node in basic test!", i ) + hb_eol() )

         mxmlDelete( hTree )
         ErrorLevel( 1 )
         QUIT
      ENDIF

      IF ( ( nNum := mxmlGetType( hNode ) ) != MXML_ELEMENT )
         IF nNum < MXML_ELEMENT .OR. nNum > MXML_TEXT
            OutErr( hb_StrFormat( "ERROR: Group child #%d has type %s (%d), expected MXML_ELEMENT!", ;
               i + 1, "UNKNOWN", nNum ) + hb_eol() )
         ELSE
            OutErr( hb_StrFormat( "ERROR: Group child #%d has type %s (%d), expected MXML_ELEMENT!", ;
               s_aTypes[ nNum + 1 ], nNum ) + hb_eol() )
         ENDIF

         mxmlDelete( hTree )
         ErrorLevel( 1 )
         QUIT
      ENDIF
   NEXT

   hNode := mxmlFindPath( hTree, "*/two" )
   IF Empty( hNode )
      OutErr( "ERROR: Unable to find value for '*/two'." + hb_eol() )

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ELSEIF mxmlGetType( hNode ) != MXML_OPAQUE .OR. !( mxmlGetOpaque( hNode ) == "value" )
      OutErr( "ERROR: Bad value for '*/two'." + hb_eol() )

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   hNode := mxmlFindPath( hTree, "footwo'." + hb_eol() )

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ELSEIF mxmlGetType( hNode ) != MXML_OPAQUE .OR. !( mxmlGetOpaque( hNode ) == "value" )
      OutErr( "ERROR: Bad value for 'foo

   hInd := mxmlIndexNew( hTree )
   IF Empty( hInd )
      OutErr( "ERROR: Unable to create index of all nodes!" + hb_eol() )

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   IF ( nNum := mxmlIndexGetCount( hInd ) ) != 10
      OutErr( hb_StrFormat( "ERROR: Index of all nodes contains %d nodes; expected 10!", nNum ) + hb_eol() )

      mxmlIndexDelete( hInd )
      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   mxmlIndexReset( hInd )
   IF Empty( mxmlIndexFind( hInd, "group" ) )
      OutErr( "ERROR: mxmlIndexFind for 'group' failed!" + hb_eol() )

      mxmlIndexDelete( hInd )
      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   mxmlIndexDelete( hInd )

   hInd := mxmlIndexNew( hTree, "group" )
   IF Empty( hInd )
      OutErr( "ERROR: Unable to create index of groups!" + hb_eol() )

      mxmlDelete( hTree )
      ErrorLevel( 1 )
      QUIT
   ENDIF


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User]
Write the following Harbour (xBase/Clipper) code:

Harbour Runtime Library file: src/rtl/langcomp.prg. Provides functions: hb_langSelect, __LangStdToLangHb. This file provides utility functions

[Assistant]
#ifdef HB_LEGACY_LEVEL4

REQUEST HB_CODEPAGE_CS852
REQUEST HB_CODEPAGE_DE850
REQUEST HB_CODEPAGE_EL737
#endif

FUNCTION hb_langSelect( cLangID, cCP )

   LOCAL tmp
   LOCAL cCPDef
   LOCAL cLangIDBase

   IF HB_ISSTRING( cLangID )

      cCPDef := hb_cdpSelect()

#ifdef HB_LEGACY_LEVEL4

      SWITCH Upper( cLangID )
      CASE "BE866"  ; cCPDef := "BG866" ; cLangIDBase := "be" ; EXIT
      CASE "BEWIN"  ; cCPDef := "BGWIN" ; cLangIDBase := "be" ; EXIT
      CASE "BG866"  ; cCPDef := "BG866" ; cLangIDBase := "bg" ; EXIT
      CASE "BGISO"  ; cCPDef := "BGISO" ; cLangIDBase := "bg" ; EXIT
      CASE "BGMIK"  ; cCPDef := "BGMIK" ; cLangIDBase := "bg" ; EXIT
      CASE "BGWIN"  ; cCPDef := "BGWIN" ; cLangIDBase := "bg" ; EXIT
      CASE "CS852"  ; cCPDef := "CS852" ; cLangIDBase := "cs" ; EXIT
      CASE "CSISO"  ; cCPDef := "CSISO" ; cLangIDBase := "cs" ; EXIT
      CASE "CSKAM"  ; cCPDef := "CSKAMC"; cLangIDBase := "cs" ; EXIT
      CASE "CSWIN"  ; cCPDef := "CSWIN" ; cLangIDBase := "cs" ; EXIT
      CASE "DEWIN"  ; cCPDef := "DEWIN" ; cLangIDBase := "de" ; EXIT
      CASE "ELWIN"  ; cCPDef := "ELWIN" ; cLangIDBase := "el" ; EXIT
      CASE "ESWIN"  ; cCPDef := "ESWIN" ; cLangIDBase := "es" ; EXIT
      CASE "HE862"  ; cCPDef := "HE862" ; cLangIDBase := "he" ; EXIT
      CASE "HEWIN"  ; cCPDef := "HEWIN" ; cLangIDBase := "he" ; EXIT
      CASE "HR646"  ; cCPDef := "HR646" ; cLangIDBase := "hr" ; EXIT
      CASE "HR852"  ; cCPDef := "HR852" ; cLangIDBase := "hr" ; EXIT
      CASE "HRISO"  ; cCPDef := "HRISO" ; cLangIDBase := "hr" ; EXIT
      CASE "HRWIN"  ; cCPDef := "HRWIN" ; cLangIDBase := "hr" ; EXIT
      CASE "HU852"  ; cCPDef := "HU852" ; cLangIDBase := "hu" ; EXIT
      CASE "HUISO"  ; cCPDef := "HUISO" ; cLangIDBase := "hu" ; EXIT
      CASE "HUWIN"  ; cCPDef := "HUWIN" ; cLangIDBase := "hu" ; EXIT
      CASE "IS850"  ; cCPDef := "IS850" ; cLangIDBase := "is" ; EXIT
      CASE "LTWIN"  ; cCPDef := "LTWIN" ; cLangIDBase := "lt" ; EXIT
      CASE "PL852"  ; cCPDef := "PL852" ; cLangIDBase := "pl" ; EXIT
      CASE "PLISO"  ; cCPDef := "PLISO" ; cLangIDBase := "pl" ; EXIT
      CASE "PLMAZ"  ; cCPDef := "PLMAZ" ; cLangIDBase := "pl" ; EXIT
      CASE "PLWIN"  ; cCPDef := "PLWIN" ; cLangIDBase := "pl" ; EXIT
      CASE "PTISO"  ; cCPDef := "PTISO" ; cLangIDBase := "pt" ; EXIT
      CASE "RU866"  ; cCPDef := "RU866" ; cLangIDBase := "ru" ; EXIT
      CASE "RUKOI8" ; cCPDef := "RUKOI8"; cLangIDBase := "ru" ; EXIT
      CASE "RUWIN"  ; cCPDef := "RU1251"; cLangIDBase := "ru" ; EXIT
      CASE "SK852"  ; cCPDef := "SK852" ; cLangIDBase := "sk" ; EXIT
      CASE "SKISO"  ; cCPDef := "SKISO" ; cLangIDBase := "sk" ; EXIT
      CASE "SKKAM"  ; cCPDef := "SKKAMC"; cLangIDBase := "sk" ; EXIT
      CASE "SKWIN"  ; cCPDef := "SKWIN" ; cLangIDBase := "sk" ; EXIT
      CASE "SL646"  ; cCPDef := "SL646" ; cLangIDBase := "sl" ; EXIT
      CASE "SL852"  ; cCPDef := "SL852" ; cLangIDBase := "sl" ; EXIT
      CASE "SLISO"  ; cCPDef := "SLISO" ; cLangIDBase := "sl" ; EXIT
      CASE "SLWIN"  ; cCPDef := "SLWIN" ; cLangIDBase := "sl" ; EXIT
      CASE "SR852"  ; cCPDef := "SL852" ; cLangIDBase := "sr_lat" ; EXIT
      CASE "SRISO"  ; cCPDef := "SLISO" ; cLangIDBase := "sr_lat" ; EXIT
      CASE "SRWIN"  ; cCPDef := "SRWIN" ; cLangIDBase := "sr_cyr" ; EXIT
      CASE "SVWIN"  ; cCPDef := "SVWIN" ; cLangIDBase := "sv" ; EXIT
      CASE "TR857"  ; cCPDef := "TR857" ; cLangIDBase := "tr" ; EXIT
      CASE "TRWIN"  ; cCPDef := "TRWIN" ; cLangIDBase := "tr" ; EXIT
      CASE "UA866"  ; cCPDef := "UA866" ; cLangIDBase := "uk" ; EXIT
      CASE "UADOS"  ; cCPDef := "UA1125"; cLangIDBase := "uk" ; EXIT
      CASE "UAKOI8" ; cCPDef := "UAKOI8"; cLangIDBase := "uk" ; EXIT
      CASE "UAWIN"  ; cCPDef := "UA1251"; cLangIDBase := "uk" ; EXIT
      CASE "ZHB5"   ; cCPDef := "BIG5"  ; cLangIDBase := "zh" ; EXIT
      CASE "ZHGB"   ; cCPDef := "GBK"   ; cLangIDBase := "zh_sim" ; EXIT
      OTHERWISE

         SWITCH cLangID
         CASE "CA"     ; cCPDef := "DE850" ; cLangIDBase := "ca" ; EXIT
         CASE "DE"     ; cCPDef := "DE850" ; cLangIDBase := "de" ; EXIT
         CASE "EL"     ; cCPDef := "EL737" ; cLangIDBase := "el" ; EXIT
         CASE "EO"     ; cCPDef := "DE850" ; cLangIDBase := "eo" ; EXIT
         CASE "ES"     ; cCPDef := "DE850" ; cLangIDBase := "es" ; EXIT
         CASE "EU"     ; cCPDef := "DE850" ; cLangIDBase := "eu" ; EXIT
         CASE "FR"     ; cCPDef := "DE850" ; cLangIDBase := "fr" ; EXIT
         CASE "GL"     ; cCPDef := "DE850" ; cLangIDBase := "gl" ; EXIT
         CASE "ID"     ; cCPDef := "EN"    ; cLangIDBase := "id" ; EXIT
         CASE "IT"     ; cCPDef := "DE850" ; cLangIDBase := "it" ; EXIT

         CASE "NL"     ; cCPDef := "EN"    ; cLangIDBase := "nl" ; EXIT
         CASE "PT"     ; cCPDef := "DE850" ; cLangIDBase := "pt" ; EXIT
         CASE "RO"     ; cCPDef := "CS852" ; cLangIDBase := "ro" ; EXIT
         CASE "SV"     ; cCPDef := "DE850" ; cLangIDBase := "sv" ; EXIT
         ENDSWITCH
      ENDSWITCH

#endif

      IF ! HB_ISSTRING( cCP )
         cCP := cCPDef
      ENDIF

#ifdef HB_LEGACY_LEVEL4
      IF Empty( cLangIDBase )
#endif

         IF Empty( tmp := __LangStdToLangHb( cLangID ) )

            cLangIDBase := cLangID
         ELSE
            cLangID := cLangIDBase := tmp
         ENDIF
#ifdef HB_LEGACY_LEVEL4
      ELSE

         cLangID := cLangIDBase
      ENDIF
#endif

      IF ! hb_cdpIsUTF8( cCP )
         cLangID += "." + cCP
         hb_langNew( cLangID, cCP, cLangIDBase, "UTF8" )
      ENDIF
   ENDIF

   RETURN __hb_langSelect( cLangID )

STATIC FUNCTION __LangStdToLangHb( cLangStd )

   LOCAL cLangHb := ""

   IF HB_ISSTRING( cLangStd )
      SWITCH Lower( StrTran( cLangStd, "_", "-" ) )
      CASE "be"         ; cLangHb := "be" ; EXIT
      CASE "bg-bg"
      CASE "bg"         ; cLangHb := "bg" ; EXIT
      CASE "ca-es"
      CASE "ca"         ; cLangHb := "ca" ; EXIT
      CASE "cs-cz"
      CASE "cs"         ; cLangHb := "cs" ; EXIT
      CASE "de-at"      ; cLangHb := "de_at" ; EXIT
      CASE "de-ch"
      CASE "de-de"
      CASE "de-li"
      CASE "de-lu"
      CASE "de"         ; cLangHb := "de" ; EXIT
      CASE "el-gr"
      CASE "el"         ; cLangHb := "el" ; EXIT
      CASE "en-au"
      CASE "en-bz"
      CASE "en-ca"
      CASE "en-cb"
      CASE "en-gb"
      CASE "en-ie"
      CASE "en-jm"
      CASE "en-nz"
      CASE "en-ph"
      CASE "en-tt"
      CASE "en-us"
      CASE "en-za"
      CASE "en-zw"
      CASE "en"         ; cLangHb := "en" ; EXIT
      CASE "eo"         ; cLangHb := "eo" ; EXIT
      CASE "es-419"     ; cLangHb := "es_419" ; EXIT
      CASE "es-ar"
      CASE "es-bo"
      CASE "es-cl"
      CASE "es-co"
      CASE "es-cr"
      CASE "es-do"
      CASE "es-ec"
      CASE "es-es"
      CASE "es-gt"
      CASE "es-hn"
      CASE "es-mx"
      CASE "es-ni"
      CASE "es-pa"
      CASE "es-pe"
      CASE "es-pr"
      CASE "es-py"
      CASE "es-sv"
      CASE "es-uy"
      CASE "es-ve"
      CASE "es"         ; cLangHb := "es" ; EXIT
      CASE "eu-es"
      CASE "eu"         ; cLangHb := "eu" ; EXIT
      CASE "fr-be"
      CASE "fr-ca"
      CASE "fr-ch"
      CASE "fr-fr"
      CASE "fr-lu"
      CASE "fr-mc"
      CASE "fr"         ; cLangHb := "fr" ; EXIT
      CASE "gl-es"
      CASE "gl"         ; cLangHb := "gl" ; EXIT
      CASE "he-il"
      CASE "he"         ; cLangHb := "he" ; EXIT
      CASE "hr-hr"
      CASE "hr"         ; cLangHb := "hr" ; EXIT
      CASE "hu-hu"
      CASE "hu"         ; cLangHb := "hu" ; EXIT
      CASE "id-id"
      CASE "id"         ; cLangHb := "id" ; EXIT
      CASE "is-is"
      CASE "is"         ; cLangHb := "is" ; EXIT
      CASE "it-ch"
      CASE "it-it"
      CASE "it"         ; cLangHb := "it" ; EXIT
      CASE "ko-kr"
      CASE "ko"         ; cLangHb := "ko" ; EXIT
      CASE "lt-lt"
      CASE "lt"         ; cLangHb := "lt" ; EXIT
      CASE "nl-be"
      CASE "nl-nl"


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Implement the following Harbour classes: RadioGroup. Harbour Runtime Library file: src/rtl/radiogrp.prg. Defines classes: RadioGroup. This file provides utility functions

[Assistant]
#include "hbclass.ch"

#include "box.ch"
#include "button.ch"
#include "color.ch"
#include "setcurs.ch"

#ifdef HB_COMPAT_C53

CREATE CLASS RadioGroup FUNCTION HBRadioGroup

   EXPORTED:

   VAR cargo

   METHOD addItem( oRadioButton )
   METHOD delItem( nPos )
   METHOD display()
   METHOD getAccel( xKey )
   METHOD getItem( nPos )
   METHOD hitTest( nMRow, nMCol )
   METHOD insItem( nPos, oRadioButton )
   METHOD killFocus()
   METHOD nextItem()
   METHOD prevItem()
   METHOD select( xValue )
   METHOD setColor( cColorSpec )
   METHOD setFocus()
   METHOD setStyle( cStyle )

   METHOD bottom( nBottom ) SETGET
   METHOD buffer() SETGET
   METHOD capCol( nCapCol ) SETGET
   METHOD capRow( nCapRow ) SETGET
   METHOD caption( cCaption ) SETGET
   METHOD coldBox( cColdBox ) SETGET
   METHOD colorSpec( cColorSpec ) SETGET
   METHOD fBlock( bFBlock ) SETGET
   METHOD hasFocus() SETGET
   METHOD hotBox( cHotBox ) SETGET
   METHOD itemCount() SETGET
   METHOD left( nLeft ) SETGET
   METHOD message( cMessage ) SETGET
   METHOD right( nRight ) SETGET
   METHOD textValue() SETGET
   METHOD top( nTop ) SETGET
   METHOD typeOut() SETGET
   METHOD value() SETGET

   METHOD Init( nTop, nLeft, nBottom, nRight )

   PROTECTED:

   VAR nBottom
   VAR xBuffer
   VAR nCapCol
   VAR nCapRow
   VAR cCaption   INIT ""
   VAR cColdBox   INIT HB_B_SINGLE_UNI
   VAR cColorSpec
   VAR bFBlock
   VAR lHasFocus  INIT .F.
   VAR cHotBox    INIT HB_B_DOUBLE_UNI
   VAR nItemCount INIT 0
   VAR nLeft
   VAR cMessage   INIT ""
   VAR nRight
   VAR cTextValue INIT ""
   VAR nTop
   VAR nValue     INIT 0

   VAR aItems     INIT {}
   VAR nCursor    INIT 0

   METHOD changeButton( nUnselect, nSelect )

ENDCLASS

METHOD addItem( oRadioButton ) CLASS RadioGroup

   IF HB_ISOBJECT( oRadioButton ) .AND. oRadioButton:ClassName() == "RADIOBUTTN"
      AAdd( ::aItems, oRadioButton )
      ::nItemCount++
   ENDIF

   RETURN Self

METHOD delItem( nPos ) CLASS RadioGroup

   IF nPos >= 1 .AND. nPos <= ::nItemCount
      hb_ADel( ::aItems, nPos, .T. )
      ::nItemCount--
   ENDIF

   IF ::lHasFocus .AND. ::nItemCount < ::nValue
      ::nValue := ::nItemCount
      ::cTextValue := ::aItems[ ::nValue ]:data
      ::xBuffer := iif( HB_ISNUMERIC( ::xBuffer ), ::nValue, ::cTextValue )
   ENDIF

   RETURN Self

METHOD display() CLASS RadioGroup

   LOCAL cSelBox
   LOCAL cUnSelBox
   LOCAL cCaption
   LOCAL nPos

   DispBegin()

   IF ::lHasFocus
      cSelBox := ::cHotBox
      cUnSelBox := ::cColdbox
   ELSE
      cSelBox := ::cColdbox
      cUnSelBox := ::cHotBox
   ENDIF

   DO CASE
   CASE ! Empty( cSelBox )
      hb_DispBox( ::nTop, ::nLeft, ::nBottom, ::nRight, cSelBox, hb_ColorIndex( ::cColorSpec, 0 ) )
   CASE ! Empty( cUnSelBox )
      hb_DispBox( ::nTop, ::nLeft, ::nBottom, ::nRight, cUnSelBox, hb_ColorIndex( ::cColorSpec, 0 ) )
   ENDCASE

   IF ! Empty( cCaption := ::cCaption )

      IF ( nPos := At( "&", cCaption ) ) > 0
         IF nPos == Len( cCaption )
            nPos := 0
         ELSE
            cCaption := Stuff( cCaption, nPos, 1, "" )
         ENDIF
      ENDIF

      hb_DispOutAt( ::nCapRow, ::nCapCol, cCaption, hb_ColorIndex( ::cColorSpec, 1 ) )

      IF nPos > 0
         hb_DispOutAt( ::nCapRow, ::nCapCol + nPos - 1, SubStr( cCaption, nPos, 1 ), hb_ColorIndex( ::cColorSpec, 2 ) )
      ENDIF
   ENDIF

   AEval( ::aItems, {| o | o:display() } )

   DispEnd()

   RETURN Self

METHOD getAccel( xKey ) CLASS RadioGroup

   LOCAL cKey

   DO CASE
   CASE HB_ISSTRING( xKey )
      cKey := xKey
   CASE HB_ISNUMERIC( xKey )
      cKey := hb_keyChar( xKey )
   OTHERWISE
      RETURN 0
   ENDCASE

   IF Len( cKey ) > 0
      cKey := Lower( cKey )
      RETURN AScan( ::aItems, {| o | o:isAccel( cKey ) } )
   ENDIF

   RETURN 0

METHOD getItem( nPos ) CLASS RadioGroup
   RETURN iif( nPos >= 1 .AND. nPos <= ::nItemCount, ::aItems[ nPos ], NIL )

METHOD hitTest( nMRow, nMCol ) CLASS RadioGroup

   LOCAL nLen
   LOCAL nPos
   LOCAL item

   DO CASE
   CASE Empty( ::cColdbox + ::cHotBox )
   CASE nMRow == ::nTop
      DO CASE
      CASE nMCol == ::nLeft
         RETURN HTTOPLEFT
      CASE nMCol == ::nRight
         RETURN HTTOPRIGHT
      CASE nMCol >= ::nLeft .AND. nMCol <= ::nRight
         RETURN HTTOP
      ENDCASE
   CASE nMRow == ::nBottom
      DO CASE
      CASE nMCol == ::nLeft
         RETURN HTBOTTOMLEFT
      CASE nMCol == ::nRight
         RETURN HTBOTTOM
      CASE nMCol >= ::nLeft .AND. nMCol <= ::nRight
         RETURN HTBOTTOMRIGHT
      ENDCASE
   CASE nMCol == ::nLeft
      IF nMRow >= ::nTop .AND. ;
         nMRow <= ::nBottom
         RETURN HTLEFT
      ELSE
         RETURN HTNOWHERE
      ENDIF
   CASE nMCol == ::nRight
      IF nMRow >= ::nTop .AND. ;
         nMRow <= ::nBottom
         RETURN HTRIGHT
      ELSE
         RETURN HTNOWHERE
      ENDIF
   ENDCASE

   nLen := Len( ::cCaption )

   IF ( nPos := At( "&", ::cCaption ) ) > 0 .AND. nPos < nLen
      nLen--
   ENDIF

   DO CASE
   CASE Empty( ::cCaption )
   CASE nMRow != ::nCapRow
   CASE nMCol < ::nCapCol
   CASE nMCol < ::nCapCol + nLen
      RETURN HTCAPTION
   ENDCASE

   DO CASE
   CASE nMRow < ::nTop
   CASE nMRow > ::nBottom
   CASE nMCol < ::nLeft
   CASE nMCol <= ::nRight
      FOR EACH item IN ::aItems
         IF item:hitTest( nMRow, nMCol ) != HTNOWHERE
            RETURN item:__enumIndex()
         ENDIF
      NEXT
      RETURN HTCLIENT
   ENDCASE

   RETURN HTNOWHERE

METHOD insItem( nPos, oRadioButton ) CLASS RadioGroup

   IF HB_ISOBJECT( oRadioButton ) .AND. oRadioButton:ClassName() == "RADIOBUTTN" .AND. ;
      nPos < ::nItemCount

      hb_AIns( ::aItems, nPos, oRadioButton, .T. )
      ::nItemCount++
   ENDIF

   RETURN ::aItems[ nPos ]

METHOD killFocus() CLASS RadioGroup

   LOCAL item

   LOCAL nOldMCur

   IF ::lHasFocus

      ::lHasFocus := .F.

      IF HB_ISEVALITEM( ::bFBlock )
         Eval( ::bFBlock )
      ENDIF

      nOldMCur := MSetCursor( .F. )

      DispBegin()

      FOR EACH item IN ::aItems
         item:killFocus()
      NEXT

      ::display()

      DispEnd()

      MSetCursor( nOldMCur )
      SetCursor( ::nCursor )
   ENDIF

   RETURN Self

METHOD setFocus() CLASS RadioGroup

   LOCAL item

   LOCAL nOldMCur

   IF ! ::lHasFocus

      ::nCursor := SetCursor( SC_NONE )
      ::lHasFocus := .T.

      nOldMCur := MSetCursor( .F. )

      DispBegin()

      FOR EACH item IN ::aItems
         item:setFocus()
      NEXT

      ::display()

      DispEnd()

      MSetCursor( nOldMCur )

      IF HB_ISEVALITEM( ::bFBlock )
         Eval( ::bFBlock )
      ENDIF
   ENDIF

   RETURN Self

METHOD nextItem() CLASS RadioGroup

   LOCAL nValue

   IF ::lHasFocus .AND. ::nItemCount > 0
      ::changeButton( nValue := ::nValue, iif( nValue == ::nItemCount, 1, nValue + 1 ) )
   ENDIF

   RETURN Self

METHOD prevItem() CLASS RadioGroup

   LOCAL nValue
   LOCAL nPos

   IF ::lHasFocus .AND. ::nItemCount > 0

      nValue := ::nValue

      DO CASE
      CASE nValue == 0 ; nPos := 1
      CASE nValue == 1 ; nPos := ::nItemCount
      OTHERWISE        ; nPos := nValue - 1
      ENDCASE

      ::changeButton( nValue, nPos )
   ENDIF

   RETURN Self

METHOD select( xValue ) CLASS RadioGroup

   LOCAL nPos
   LOCAL nLen

   SWITCH ValType( xValue )
   CASE "C"

      nLen := ::nItemCount
      FOR nPos := 1 TO nLen
         IF ::aItems[ nPos ]:data == xValue

            IF ::xBuffer == NIL
               ::xBuffer := ""
            ENDIF

            ::changeButton( ::nValue, nPos )

            EXIT
         ENDIF
      NEXT

      IF nPos > nLen
         ::xBuffer := xValue
      ENDIF
      EXIT

   CASE "N"

      IF xValue >= 1 .AND. xValue <= ::nItemCount
         IF ::xBuffer == NIL
            ::xBuffer := 0
         ENDIF

         ::changeButton( ::nValue, xValue )
      ENDIF
      EXIT

   ENDSWITCH

   RETURN Self

METHOD setColor( cColorSpec ) CLASS RadioGroup

   LOCAL item

   FOR EACH item IN ::aItems


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Generate Harbour code for: Harbour contribution module 'hbnf' (NanForum Toolkit - legacy Clipper compatibility functions): contrib/hbnf/dectobin.prg. Provides functions: ft_Dec2Bin. This file provides legacy compatibility functions

[Assistant]
FUNCTION ft_Dec2Bin( x )

   LOCAL buffer := { "0", "0", "0", "0", "0", "0", "0", "0" }
   LOCAL i

   FOR i := 8 TO 1 STEP -1
      IF x >= 2 ^ ( i - 1 )
         x -= 2 ^ ( i - 1 )
         buffer[ 9 - i ] := "1"
      ENDIF
   NEXT

   RETURN ;
      buffer[ 1 ] + buffer[ 2 ] + buffer[ 3 ] + buffer[ 4 ] + ;
      buffer[ 5 ] + buffer[ 6 ] + buffer[ 7 ] + buffer[ 8 ]


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Write a Harbour program with procedures: Main, fi_Error. Harbour contribution module 'hbfimage' (FreeImage library wrapper): contrib/hbfimage/tests/test.prg. Contains procedures: Main, fi_Error. This file provides graphics and image processing capabilities

[Assistant]
#require "hbfimage"

#include "fileio.ch"
#include "simpleio.ch"

#define IMAGES_IN  ""
#define IMAGES_OUT "imgs_out" + hb_ps()

PROCEDURE Main()

   LOCAL im, clone, rotated, rotatedEx, rescale, im2, im3
   LOCAL centerX, centerY, width, height

   LOCAL bkcolor
   LOCAL bmpinfo
   LOCAL nH, nLen, cStr

   AltD()

   IF ! hb_DirExists( IMAGES_OUT )
      hb_DirCreate( IMAGES_OUT )
   ENDIF

   ? "Initialise"
   fi_Initialise()

   ? "Version          :", fi_GetVersion()
   ? "Copyright        :", fi_GetCopyrightMessage()
   ? "File type        :", fi_GetFileType( IMAGES_IN + "sample1.jpg" )

   ? "Set Error Message (symbol):", fi_SetOutputMessage( @fi_Error() )
   im := fi_Load( FIF_JPEG, IMAGES_IN + "nothere.jpg", JPEG_DEFAULT )
   ? "Set Error Message (block):", fi_SetOutputMessage( {| cFormat, cMessage | fi_Error( cFormat, cMessage ) } )
   im := fi_Load( FIF_JPEG, IMAGES_IN + "nothere.jpg", JPEG_DEFAULT )

   ? "Load JPEG directly from file"
   im := fi_Load( FIF_JPEG, IMAGES_IN + "sample1.jpg", JPEG_DEFAULT )

   ? "Clone image"
   clone := fi_Clone( im )

   ? "Pointer          :", hb_ValToExp( im )

   ? "Image Type       :", fi_GetImageType( im )
   ? "Color Used       :", fi_GetColorsUsed( im )
   ? "Pixel size       :", fi_GetBPP( im )
   ? "Width            :", fi_GetWidth( im )
   ? "Height           :", fi_GetHeight( im )
   ? "Byte Size        :", fi_GetLine( im )
   ? "Pitch            :", fi_GetPitch( im )
   ? "DIB Size         :", fi_GetDIBSize( im )
   ? "Dots per Meter X :", fi_GetDotsPerMeterX( im )
   ? "Dots per Meter Y :", fi_GetDotsPerMeterY( im )
   ? "Color Type       :", fi_GetColorType( im )
   ? "Red Mask         :", fi_GetRedMask( im )
   ? "Green Mask       :", fi_GetGreenMask( im )
   ? "Blue Mask        :", fi_GetBlueMask( im )
   ? "Transp. Count    :", fi_GetTransparencyCount( im )
   ? "Is Transparent ? :", fi_IsTransparent( im )
   ?
   ? "Save BMP ?       :", fi_Save( FIF_BMP , im, IMAGES_OUT + "sample1.bmp", BMP_DEFAULT  )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, im, IMAGES_OUT + "sample1.jpg", JPEG_DEFAULT )
   ? "Save PNG ?       :", fi_Save( FIF_PNG , im, IMAGES_OUT + "sample1.png", PNG_DEFAULT  )

   ? "Save TIFF ?      :", fi_Save( FIF_TIFF, clone, IMAGES_OUT + "sample1.tif", TIFF_DEFAULT )
   ? "Flip Horizontal ?:", fi_FlipHorizontal( clone )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, clone, IMAGES_OUT + "horizont.jpg", JPEG_DEFAULT )
   ? "Flip Vertical ?  :", fi_FlipVertical( clone )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, clone, IMAGES_OUT + "vertical.jpg", JPEG_DEFAULT )

   ? "Rotate Classic   :", hb_ValToExp( rotated := fi_RotateClassic( clone, 90 ) )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, rotated, IMAGES_OUT + "rotate.jpg", JPEG_DEFAULT )

   centerx := fi_GetWidth( clone ) / 2
   centery := fi_GetHeight( clone ) / 2
   ? "Rotate Ex        :", hb_ValToExp( rotatedEx := fi_RotateEx( clone, 15, 0, 0, centerx, centery, .T. ) )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, rotatedEx, IMAGES_OUT + "rotateex.jpg", JPEG_DEFAULT )

   width   := fi_GetWidth( im )
   height  := fi_GetHeight( im )

   ? "Rescale          :", hb_ValToExp( rescale := fi_Rescale( im, width / 2, height / 2, FILTER_BICUBIC ) )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, rescale, IMAGES_OUT + "rescale.jpg", JPEG_DEFAULT )

   im2 := fi_Clone( im )
   ? "Adjust Gamma ?   :", fi_AdjustGamma( im2, 3.0 )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, im2, IMAGES_OUT + "adjgamma.jpg", JPEG_DEFAULT )

   im2 := fi_Clone( im )
   ? "Adjust Brightness:", fi_AdjustBrightness( im2, - 30 )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, im2, IMAGES_OUT + "adjbrigh.jpg", JPEG_DEFAULT )

   im2 := fi_Clone( im )
   ? "Adjust Contrast ?:", fi_AdjustContrast( im2, - 30 )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, im2, IMAGES_OUT + "adjcontr.jpg", JPEG_DEFAULT )

   im2 := fi_Clone( im )
   ? "Invert ?         :", fi_Invert( im2 )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, im2, IMAGES_OUT + "invert.jpg", JPEG_DEFAULT )

   ? "Red Channel      :", hb_ValToExp( im2 := fi_GetChannel( im, FICC_RED ) )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, im2, IMAGES_OUT + "red.jpg", JPEG_DEFAULT )

   ? "Green Channel    :", hb_ValToExp( im2 := fi_GetChannel( im, FICC_GREEN ) )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, im2, IMAGES_OUT + "green.jpg", JPEG_DEFAULT )

   ? "Blue Channel     :", hb_ValToExp( im2 := fi_GetChannel( im, FICC_BLUE ) )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, im2, IMAGES_OUT + "blue.jpg", JPEG_DEFAULT )

   ? "Copy             :", hb_ValToExp( im2 := fi_Copy( im, 300, 100, 800, 200 ) )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, im2, IMAGES_OUT + "copy.jpg", JPEG_DEFAULT )

   im3 := fi_Clone( im )
   ? "Paste ?          :", fi_Paste( im3, im2, 10, 10, 70 )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, im3, IMAGES_OUT + "paste.jpg", JPEG_DEFAULT )

   ? "Allocate Bitmap  :", hb_ValToExp( im3 := fi_AllocateT( FIT_BITMAP, 320, 200, 32 ) )
   ? "Save JPG ?       :", fi_Save( FIF_JPEG, im3, IMAGES_OUT + "allocate.jpg", JPEG_DEFAULT )

   ? "Create ERROR     :"
   ? "Save GIF ?       :", fi_Save( FIF_GIF, im, IMAGES_OUT + "wrong.gif", 0 )

   bkcolor := hb_BChar( 0 ) + hb_BChar( 0 ) + hb_BChar( 205 ) + hb_BChar( 0 )
   ? fi_SetBackgroundColor( im, bkcolor )
   ? fi_GetBackgroundColor( im, @bkcolor )
   ? hb_StrToHex( bkcolor )

   IF ( nH := FOpen( IMAGES_IN + "sample1.jpg" ) ) != F_ERROR
      nLen := FSeek( nH, 0, FS_END )
      FSeek( nH, 0, FS_SET )
      cStr := Space( nLen )
      FRead( nH, @cStr, nLen )
      FClose( nH )

      ? "Load JPEG from memory"
      im := fi_LoadFromMemory( FIF_JPEG, cStr, JPEG_DEFAULT )

      ? "Pointer          :", hb_ValToExp( im )
      ? "Image Type       :", fi_GetImageType( im )
      ? "Save PNG ?       :", fi_Save( FIF_PNG, im, IMAGES_OUT + "sample2.png", PNG_DEFAULT  )
   ENDIF

   ? "DeInitialise"
   fi_DeInitialise()

   ?
   ? "Look at " + IMAGES_OUT + " folder for output images"
   ?

   RETURN

STATIC PROCEDURE fi_Error( cFormat, cMessage )

   ? "ERROR!.."
   ? "Format : ", cFormat
   ? "Message: ", cMessage
   ?

   RETURN


[System] You are an expert Harbour (xBase/Clipper) programmer. Write clean, efficient code following Harbour conventions. Use proper Hungarian notation for variable names (c=character, n=numeric, l=logical, a=array, o=object, b=codeblock).

[User] Write a Harbour program with procedures: Main. Harbour extra library: extras/rddado/tests/access1.prg. Contains procedures: Main. This file provides utility functions

[Assistant]
#require "rddado"

#include "adordd.ch"

REQUEST ADORDD

PROCEDURE Main()

   Set( _SET_DATEFORMAT, "yyyy-mm-dd" )

   USE ( hb_DirBase() + "test.mdb" ) VIA "ADORDD" TABLE "Table1"

   CLS
   Browse()

   USE

   RETURN