[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 'hbhttpd' (Multithreaded HTTP/HTTPS server framework): contrib/hbhttpd/widgets.prg. Defines classes: UWMain, UWLayoutGrid, UWHtml, UWLabel, UWForm. Provides 12 functions including: UWMainNew, UWLayoutGridNew, UWHtmlNew, UWLabelNew, UWFormNew. This file provides network protocol implementations

[Assistant]
#include "hbclass.ch"

#pragma -km+

MEMVAR session, server, get, post

CREATE CLASS UWMain

   VAR aChilds     INIT {}

   METHOD Add( oWidget )
   METHOD Paint()

ENDCLASS

FUNCTION UWMainNew()

   LOCAL oW := UWMain()

   session[ "_uthis" ][ "main" ] := oW

   RETURN oW

METHOD Paint() CLASS UWMain

   UWrite( '<link href="/files/main.css" type=text/css rel=stylesheet>' )
   UWrite( '<meta http-equiv="content-type" content="text/html; charset=UTF-8">' )
   UWrite( '' )
   UWrite( '' )
   AEval( ::aChilds, {| x | x:Paint() } )
   UWrite( '' )

   RETURN Self

METHOD Add( oWidget ) CLASS UWMain

   AAdd( ::aChilds, oWidget )

   RETURN Self

CREATE CLASS UWLayoutGrid

   VAR aChilds     INIT { { {} } }

   METHOD Add( oWidget, nRow, nCol )
   METHOD Paint()

ENDCLASS

FUNCTION UWLayoutGridNew()
   RETURN UWLayoutGrid()

METHOD Paint() CLASS UWLayoutGrid

   LOCAL aRow, aCell

   UWrite( '
' )
   FOR EACH aRow IN ::aChilds
      UWrite( '
' )
      FOR EACH aCell IN aRow
         UWrite( '' )
         AEval( aCell, {| o | o:Paint() } )
         UWrite( '	' )
      NEXT
      UWrite( '
' )
   NEXT
   UWrite( '
' )

   RETURN Self

METHOD Add( oWidget, nRow, nCol ) CLASS UWLayoutGrid

   LOCAL nI, nJ, aI

   IF nRow > Len( ::aChilds )
      FOR nI := Len( ::aChilds ) + 1 TO nRow
         aI := Array( Len( ::aChilds[ 1 ] ) )
         FOR nJ := 1 TO Len( ::aChilds[ 1 ] )
            aI[ nJ ] := {}
         NEXT
         AAdd( ::aChilds, aI )
      NEXT
   ENDIF
   IF nCol > Len( ::aChilds[ 1 ] )
      FOR nI := Len( ::aChilds[ 1 ] ) + 1 TO nCol
         AEval( ::aChilds, {| x | AAdd( x, {} ) } )
      NEXT
   ENDIF
   AAdd( ::aChilds[ nRow ][ nCol ], oWidget )

   RETURN Self

CREATE CLASS UWHtml

   VAR cText

   METHOD Paint()

ENDCLASS

FUNCTION UWHtmlNew( cText )

   LOCAL oW := UWHtml()

   oW:cText := cText

   RETURN oW

METHOD Paint() CLASS UWHtml

   UWrite( ::cText )

   RETURN Self

CREATE CLASS UWLabel

   VAR cText
   VAR cID
   VAR cStyle

   METHOD Paint()

ENDCLASS

FUNCTION UWLabelNew( cText, cID, cStyle )

   LOCAL oW := UWLabel()

   oW:cText := cText
   SetWId( oW, cID )
   oW:cStyle := cStyle

   RETURN oW

METHOD Paint() CLASS UWLabel

   UWrite( '
' + ;
      UHtmlEncode( ::cText ) + '' )

   RETURN Self

CREATE CLASS UWForm

   VAR cAction
   VAR cMethod   INIT "POST"
   VAR aChilds   INIT {}

   METHOD Add( oWidget )
   METHOD Paint()

ENDCLASS

FUNCTION UWFormNew( cAction )

   LOCAL oW := UWForm()

   oW:cAction := cAction

   RETURN oW

METHOD Add( oWidget ) CLASS UWForm

   AAdd( ::aChilds, oWidget )

   RETURN Self

METHOD Paint() CLASS UWForm

   UWrite( '<form action="' + ::cAction + '" method="' + ::cMethod + '">' )
   AEval( ::aChilds, {| x | x:Paint() } )
   UWrite( '</form>' )

   RETURN Self

CREATE CLASS UWInput

   VAR cName
   VAR cValue
   VAR cID
   VAR cStyle

   METHOD Paint()

ENDCLASS

FUNCTION UWInputNew( cName, cValue, cID, cStyle )

   LOCAL oW := UWInput()

   oW:cName := cName
   oW:cValue := cValue
   SetWId( oW, cID )
   oW:cStyle := cStyle

   RETURN oW

METHOD Paint() CLASS UWInput

   UWrite( '<input type="text" name="' + iif( ::cName != NIL, ::cName, "" ) + ;
      '" value="' + iif( ::cValue != NIL, UHtmlEncode( ::cValue ), "" ) + '">' )

   RETURN Self

CREATE CLASS UWPassword

   VAR cName
   VAR cValue

   METHOD Paint()

ENDCLASS

FUNCTION UWPasswordNew( cName )

   LOCAL oW := UWPassword()

   oW:cName := cName

   RETURN oW

METHOD Paint() CLASS UWPassword

   UWrite( '<input type="password" name="' + iif( ::cName != NIL, ::cName, "" ) + ;
      '" value="' + iif( ::cValue != NIL, ::cValue, "" ) + '">' )

   RETURN Self

CREATE CLASS UWSubmit

   VAR cName
   VAR cValue

   METHOD Paint()

ENDCLASS

FUNCTION UWSubmitNew( cName, cValue )

   LOCAL oW := UWSubmit()

   oW:cName := cName
   oW:cValue := cValue

   RETURN oW

METHOD Paint() CLASS UWSubmit

   UWrite( '<input type="submit" name="' + iif( ::cName != NIL, ::cName, "" ) + ;
      '" value="' + iif( ::cValue != NIL, UHtmlEncode( ::cValue ), "" ) + '">' )

   RETURN Self

CREATE CLASS UWSeparator

   METHOD Paint()

ENDCLASS

FUNCTION UWSeparatorNew()
   RETURN UWSeparator()

METHOD Paint() CLASS UWSeparator

   UWrite( '
' )

   RETURN Self

CREATE CLASS UWMenu

   VAR aItems    INIT {}

   METHOD AddItem( cTitle, cLink )
   METHOD Paint()

ENDCLASS

FUNCTION UWMenuNew()
   RETURN UWMenu()

METHOD AddItem( cTitle, cLink ) CLASS UWMenu

   AAdd( ::aItems, { cTitle, cLink } )

   RETURN Self

METHOD Paint() CLASS UWMenu

   LOCAL nI

   UWrite( '
' )
   FOR nI := 1 TO Len( ::aItems )
      IF nI != 1
         UWrite( ' | ' )
      ENDIF
      UWrite( '' + UHtmlEncode( ::aItems[ nI ][ 1 ] ) + '' )
   NEXT
   UWrite( '
' )

   RETURN Self

CREATE CLASS UWBrowse

   VAR aColumns   INIT {}
   VAR nPageSize  INIT 0
   VAR nPos       INIT 0

   METHOD AddColumn( nID, cTitle, cField, lRaw )
   METHOD Output()

ENDCLASS

FUNCTION UWBrowseNew()
   RETURN UWBrowse()

METHOD AddColumn( nID, cTitle, cField, lRaw ) CLASS UWBrowse

   AAdd( ::aColumns, { nID, cTitle, cField, ! Empty( lRaw ) } )

   RETURN Self

METHOD Output() CLASS UWBrowse

   LOCAL cRet := "", nI, xI, xField, nPos, cUrl, cI, lValidate

   cRet += '

'

   cRet += '
'
   FOR nI := 1 TO Len( ::aColumns )
      cRet += '' + UHtmlEncode( ::aColumns[ nI ][ 2 ] ) + '	'
   NEXT
   cRet += '
'

   nPos := 0
   dbGoTop()
   IF ::nPageSize > 0 .AND. ::nPos > 0
      dbSkip( ::nPos )
   ENDIF
   DO WHILE ! Eof()
      cRet += '
'
      FOR nI := 1 TO Len( ::aColumns )
         xField := ::aColumns[ nI ][ 3 ]
         DO CASE
         CASE HB_ISSTRING( xField )
            xI := FieldGet( FieldPos( xField ) )
         CASE HB_ISEVALITEM( xField )
            xI := Eval( xField )
         ENDCASE
         SWITCH ValType( xI )
         CASE "C"  ; xI := RTrim( xI ); EXIT
         CASE "N"  ; xI := Str( xI ); EXIT
         CASE "D"  ; xI := DToC( xI ); EXIT
         OTHERWISE ; xI := "ValType()==" + ValType( xI )
         ENDSWITCH
         IF ! ::aColumns[ nI ][ 4 ]
            xI := UHtmlEncode( xI )
         ENDIF
         cRet += '<nobr>' + xI + '</nobr>	'
      NEXT
      cRet += '
'
      dbSkip()
      IF ++nPos >= ::nPageSize
         EXIT
      ENDIF
   ENDDO
   cRet += '
'
   IF ! Eof() .OR. ::nPos > 0
      cUrl := server[ "REQUEST_URI" ]
      IF ( nI := At( "?_ucs=", cUrl ) ) == 0
         nI := At( "&_ucs=", cUrl )
      ENDIF
      IF ( lValidate := nI > 0 )
         cUrl := Left( cUrl, nI - 1 )
      ENDIF
      IF ( nI := At( "?_pos=", cUrl ) ) == 0
         nI := At( "&_pos=", cUrl )
      ENDIF
      IF nI > 0
         cUrl := Left( cUrl, nI - 1 )
      ENDIF
      cUrl += iif( "?" $ cUrl, "&", "?" ) + "_pos="
      cRet := '
' + cRet
      IF ! Eof()
         cI := cUrl + hb_ntos( ::nPos + ::nPageSize )
         cRet := '>>' + cRet
      ENDIF
      IF ::nPos > 0
         cI := cUrl + hb_ntos( Max( 0, ::nPos - ::nPageSize ) )
         cRet := '<<  ' + cRet
      ENDIF
   ENDIF

   RETURN cRet

CREATE CLASS UWOption

   VAR aOption   INIT {}
   VAR cValue

   METHOD Add( cTitle, cCode, lRaw )
   METHOD Output()

ENDCLASS

FUNCTION UWOptionNew()
   RETURN UWOption()

METHOD Add( cTitle, cCode, lRaw ) CLASS UWOption

   AAdd( ::aOption, { iif( Empty( lRaw ), UHtmlEncode( cTitle ), cTitle ), cCode } )

   RETURN Self

METHOD Output() CLASS UWOption

   LOCAL cRet := ""


[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 Harbour functions: ft_AEMinLen. Harbour contribution module 'hbnf' (NanForum Toolkit - legacy Clipper compatibility functions): contrib/hbnf/aeminlen.prg. Provides functions: ft_AEMinLen. This file provides legacy compatibility functions

[Assistant]
FUNCTION ft_AEMinLen( aArray, nDimension, nStart, nCount )

   LOCAL i, nLast, nMinlen := NIL, nLen

   __defaultNIL( @nDimension, 1 )
   __defaultNIL( @nStart, 1 )
   __defaultNIL( @nCount, Len( aArray ) - nStart + 1 )

   nLast := Min( nStart + nCount - 1, Len( aArray ) )

   FOR i := nStart TO nLast

      SWITCH ValType( aArray[ i ] )
      CASE "C"
         nLen := Len( aArray[ i ] )
         EXIT
      CASE "A"
         nLen := Len( LTrim( Transform( aArray[ i ][ nDimension ], "@X" ) ) )
         EXIT
      OTHERWISE
         nLen := Len( LTrim( Transform( aArray[ i ], "@X" ) ) )
      ENDSWITCH

      nMinlen := iif( nMinLen == NIL, nLen, Min( nMinlen, nLen ) )
   NEXT

   IF nMinLen == NIL
      nMinLen := 65519
   ENDIF

   RETURN nMinlen


[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 Harbour functions: Two, Three, Four. Harbour test program: tests/procname.prg. Provides functions: Two, Three, Four, Five. Contains procedures: Main. This test file tests specific function APIs

[Assistant]
PROCEDURE Main()

   Two()

   RETURN

FUNCTION Two()

   Three()

   RETURN NIL

FUNCTION Three()

   Four()

   RETURN NIL

FUNCTION Four()

   Five()

   RETURN NIL

FUNCTION Five()

   LOCAL n := 0

   WHILE ! Empty( ProcName( n ) )
      ?? "Called from: ", ProcName( n ), ProcLine( n++ ), hb_eol()
   ENDDO

   RETURN 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 Harbour functions: test_main. Harbour test program: tests/rddtest/ntxcl53.prg. Provides functions: test_main. This test file tests specific function APIs

[Assistant]
REQUEST dbfntx
#define _TESTRDD "dbfntx"
#include "rddtst.prg"

FUNCTION test_main()

RDDTESTC {0,.t.,.t.,.f.}, LOCAL n
RDDTESTF "DBFNTX", {0,.t.,.t.,.f.}, RDDSETDEFAULT()
RDDTESTC {1,.t.,.t.,.f.}, USE "_tst" SHARED
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBGOTOP()
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBGOBOTTOM()
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBSKIP(0)
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBGOTO(0)
RDDTESTF NIL, {1,.f.,.t.,.f.}, DBSKIP(1)
RDDTESTF NIL, {1,.t.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {1,.t.,.f.,.f.}, DBSKIP(0)
RDDTESTC {1,.t.,.f.,.f.}, SET DELETE ON
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBGOTOP()
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBGOBOTTOM()
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBSKIP(0)
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBGOTO(0)
RDDTESTF NIL, {1,.f.,.t.,.f.}, DBSKIP(1)
RDDTESTF NIL, {1,.t.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {1,.t.,.f.,.f.}, DBSKIP(0)
RDDTESTC {1,.t.,.f.,.f.}, SET DELETE OFF
RDDTESTC {1,.t.,.t.,.f.}, INDEX on FNUM to TG_N
RDDTESTC {1,.t.,.t.,.f.}, INDEX on FSTR to TG_C
RDDTESTF "TG_C", {1,.t.,.t.,.f.}, ORDSETFOCUS()
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBGOTOP()
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBGOBOTTOM()
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBSKIP(0)
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBGOTO(0)
RDDTESTF NIL, {1,.f.,.t.,.f.}, DBSKIP(1)
RDDTESTF NIL, {1,.t.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {1,.t.,.f.,.f.}, DBSKIP(0)
RDDTESTC {1,.t.,.f.,.f.}, SET DELETE ON
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBGOTOP()
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBGOBOTTOM()
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBSKIP(0)
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBGOTO(0)
RDDTESTF NIL, {1,.f.,.t.,.f.}, DBSKIP(1)
RDDTESTF NIL, {1,.t.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {1,.t.,.f.,.f.}, DBSKIP(0)
RDDTESTF NIL, {1,.t.,.t.,.f.}, DBGOTO(0)
RDDTESTF .f., {1,.t.,.t.,.f.}, DBSEEK("", .T.,.F.)
RDDTESTF .f., {1,.t.,.t.,.f.}, DBSEEK("", .T.,.T.)
RDDTESTF .f., {1,.t.,.t.,.f.}, DBSEEK("", .F.,.F.)
RDDTESTF .f., {1,.t.,.t.,.f.}, DBSEEK("", .F.,.T.)
RDDTESTC {1,.t.,.t.,.f.}, SET DELETE OFF
RDDTESTC {15,.f.,.f.,.f.}, for n:=1 to 15                    ; dbappend()                          ; replace FNUM with int((n+2)/3)      ; replace FSTR with chr(FNUM+48)      ; next
RDDTESTF NIL, {15,.f.,.f.,.f.}, dbcommit()
RDDTESTF NIL, {15,.f.,.f.,.f.}, dbunlock()
RDDTESTF "TG_C", {15,.f.,.f.,.f.}, ORDSETFOCUS(1)
RDDTESTF "TG_C", {15,.f.,.f.,.f.}, ORDSETFOCUS()
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(0,.T.,.F.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(0,.T.,.T.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(0.5,.T.,.F.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(0.5,.T.,.T.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(1.0,.T.,.F.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(1.0,.T.,.T.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(2.0,.T.,.F.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(2.0,.T.,.T.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(2.5,.T.,.F.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(2.5,.T.,.T.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(5.0,.T.,.F.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(5.0,.T.,.T.)
RDDTESTF "TG_C", {1,.f.,.f.,.f.}, ORDSETFOCUS(2)
RDDTESTF "TG_C", {1,.f.,.f.,.f.}, ORDSETFOCUS()
RDDTESTF .t., {1,.f.,.f.,.t.}, DBSEEK("", .T.,.F.)
RDDTESTF .t., {1,.f.,.f.,.t.}, DBSEEK("", .T.,.T.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(" ",.T.,.F.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(" ",.T.,.T.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK("0",.T.,.F.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK("0",.T.,.T.)
RDDTESTF .t., {1,.f.,.f.,.t.}, DBSEEK("1",.T.,.F.)
RDDTESTF .t., {1,.f.,.f.,.t.}, DBSEEK("1",.T.,.T.)
RDDTESTF .t., {4,.f.,.f.,.t.}, DBSEEK("2",.T.,.F.)
RDDTESTF .t., {4,.f.,.f.,.t.}, DBSEEK("2",.T.,.T.)
RDDTESTF .t., {7,.f.,.f.,.t.}, DBSEEK("3",.T.,.F.)
RDDTESTF .t., {7,.f.,.f.,.t.}, DBSEEK("3",.T.,.T.)
RDDTESTF .t., {10,.f.,.f.,.t.}, DBSEEK("4",.T.,.F.)
RDDTESTF .t., {10,.f.,.f.,.t.}, DBSEEK("4",.T.,.T.)
RDDTESTF .t., {13,.f.,.f.,.t.}, DBSEEK("5",.T.,.F.)
RDDTESTF .t., {13,.f.,.f.,.t.}, DBSEEK("5",.T.,.T.)
RDDTESTF .f., {16,.f.,.t.,.f.}, DBSEEK("6",.T.,.F.)
RDDTESTF .f., {16,.f.,.t.,.f.}, DBSEEK("6",.T.,.T.)
RDDTESTF .t., {1,.f.,.f.,.t.}, DBSEEK("", .T.,.F.)
RDDTESTF .t., {1,.f.,.f.,.t.}, DBSEEK("", .T.,.T.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(" ",.T.,.F.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK(" ",.T.,.T.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK("0",.T.,.F.)
RDDTESTF .f., {1,.f.,.f.,.f.}, DBSEEK("0",.T.,.T.)
RDDTESTF .t., {1,.f.,.f.,.t.}, DBSEEK("1",.T.,.F.)
RDDTESTF .t., {1,.f.,.f.,.t.}, DBSEEK("1",.T.,.T.)
RDDTESTF .t., {4,.f.,.f.,.t.}, DBSEEK("2",.T.,.F.)
RDDTESTF .t., {4,.f.,.f.,.t.}, DBSEEK("2",.T.,.T.)
RDDTESTF .t., {7,.f.,.f.,.t.}, DBSEEK("3",.T.,.F.)
RDDTESTF .t., {7,.f.,.f.,.t.}, DBSEEK("3",.T.,.T.)
RDDTESTF .t., {10,.f.,.f.,.t.}, DBSEEK("4",.T.,.F.)
RDDTESTF .t., {10,.f.,.f.,.t.}, DBSEEK("4",.T.,.T.)
RDDTESTF .t., {13,.f.,.f.,.t.}, DBSEEK("5",.T.,.F.)
RDDTESTF .t., {13,.f.,.f.,.t.}, DBSEEK("5",.T.,.T.)
RDDTESTF .f., {16,.f.,.t.,.f.}, DBSEEK("6",.T.,.F.)
RDDTESTF .f., {16,.f.,.t.,.f.}, DBSEEK("6",.T.,.T.)
RDDTESTC {13,.f.,.f.,.f.}, INDEX on FSTR to TG_C DESCEND
RDDTESTF .t., {13,.f.,.f.,.t.}, DBSEEK("",.T.,.F.)
RDDTESTF .t., {13,.f.,.f.,.t.}, DBSEEK("",.T.,.T.)
RDDTESTF .f., {16,.f.,.t.,.f.}, DBSEEK(" ",.T.,.F.)
RDDTESTF .f., {16,.f.,.t.,.f.}, DBSEEK(" ",.T.,.T.)
RDDTESTF .f., {16,.f.,.t.,.f.}, DBSEEK("0",.T.,.F.)
RDDTESTF .f., {16,.f.,.t.,.f.}, DBSEEK("0",.T.,.T.)
RDDTESTF .t., {1,.f.,.f.,.t.}, DBSEEK("1",.T.,.F.)
RDDTESTF .t., {1,.f.,.f.,.t.}, DBSEEK("1",.T.,.T.)
RDDTESTF .t., {4,.f.,.f.,.t.}, DBSEEK("2",.T.,.F.)
RDDTESTF .t., {4,.f.,.f.,.t.}, DBSEEK("2",.T.,.T.)
RDDTESTF .t., {7,.f.,.f.,.t.}, DBSEEK("3",.T.,.F.)
RDDTESTF .t., {7,.f.,.f.,.t.}, DBSEEK("3",.T.,.T.)
RDDTESTF .t., {10,.f.,.f.,.t.}, DBSEEK("4",.T.,.F.)
RDDTESTF .t., {10,.f.,.f.,.t.}, DBSEEK("4",.T.,.T.)
RDDTESTF .t., {13,.f.,.f.,.t.}, DBSEEK("5",.T.,.F.)
RDDTESTF .t., {13,.f.,.f.,.t.}, DBSEEK("5",.T.,.T.)
RDDTESTF .f., {13,.f.,.f.,.f.}, DBSEEK("6",.T.,.F.)
RDDTESTF .f., {13,.f.,.f.,.f.}, DBSEEK("6",.T.,.T.)
RDDTESTC {1,.f.,.f.,.f.}, INDEX on FSTR to TG_C
RDDTESTF NIL, {1,.f.,.f.,.f.}, DBGOTOP()
RDDTESTF NIL, {1,.f.,.f.,.f.}, DBSKIP(0)
RDDTESTF NIL, {1,.t.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {1,.t.,.f.,.f.}, DBSKIP(0)
RDDTESTF NIL, {15,.f.,.f.,.f.}, DBGOBOTTOM()
RDDTESTF NIL, {15,.f.,.f.,.f.}, DBSKIP(0)
RDDTESTF NIL, {16,.f.,.t.,.f.}, DBSKIP(1)
RDDTESTF NIL, {16,.f.,.t.,.f.}, DBSKIP(0)
RDDTESTF NIL, {1,.f.,.f.,.f.}, DBGOTO(1)
RDDTESTF NIL, {1,.t.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {2,.f.,.f.,.f.}, DBSKIP(1)
RDDTESTF NIL, {7,.f.,.f.,.f.}, DBSKIP(5)
RDDTESTF NIL, {12,.f.,.f.,.f.}, DBSKIP(5)
RDDTESTF NIL, {16,.f.,.t.,.f.}, DBSKIP(5)
RDDTESTF NIL, {15,.f.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {10,.f.,.f.,.f.}, DBSKIP(-5)
RDDTESTF NIL, {16,.f.,.t.,.f.}, DBSKIP(10)
RDDTESTF NIL, {11,.f.,.f.,.f.}, DBSKIP(-5)
RDDTESTF NIL, {16,.t.,.t.,.f.}, DBGOTO(16)
RDDTESTF NIL, {15,.f.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {1,.f.,.f.,.f.}, DBGOTO(1)
RDDTESTF NIL, {2,.f.,.f.,.f.}, DBSKIP(1)
RDDTESTF NIL, {1,.f.,.f.,.f.}, DBGOTO(1)
RDDTESTF NIL, {1,.t.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {4,.f.,.f.,.f.}, DBGOTO(4)
RDDTESTF NIL, {5,.f.,.f.,.f.}, DBSKIP(1)
RDDTESTF NIL, {4,.f.,.f.,.f.}, DBGOTO(4)
RDDTESTF NIL, {3,.f.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {6,.f.,.f.,.f.}, DBGOTO(6)
RDDTESTF NIL, {7,.f.,.f.,.f.}, DBSKIP(1)
RDDTESTF NIL, {6,.f.,.f.,.f.}, DBGOTO(6)
RDDTESTF NIL, {5,.f.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {7,.f.,.f.,.f.}, DBGOTO(7)
RDDTESTF NIL, {8,.f.,.f.,.f.}, DBSKIP(1)
RDDTESTF NIL, {7,.f.,.f.,.f.}, DBGOTO(7)
RDDTESTF NIL, {6,.f.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {12,.f.,.f.,.f.}, DBGOTO(12)
RDDTESTF NIL, {13,.f.,.f.,.f.}, DBSKIP(1)
RDDTESTF NIL, {12,.f.,.f.,.f.}, DBGOTO(12)
RDDTESTF NIL, {11,.f.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {13,.f.,.f.,.f.}, DBGOTO(13)
RDDTESTF NIL, {14,.f.,.f.,.f.}, DBSKIP(1)
RDDTESTF NIL, {13,.f.,.f.,.f.}, DBGOTO(13)
RDDTESTF NIL, {12,.f.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {14,.f.,.f.,.f.}, DBGOTO(14)
RDDTESTF NIL, {13,.f.,.f.,.f.}, DBSKIP(-1)
RDDTESTF NIL, {16,.t.,.t.,.f.}, DBGOTO(16)
RDDTESTF NIL, {15,.f.,.f.,.f.}, DBSKIP(-1)
RDDTESTF "TG_C", {15,.f.,.f.,.f.}, ORDSETFOCUS(0)
RDDTESTF NIL, {1,.f.,.f.,.f.}, DBGOTOP()


[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 these Harbour functions: Harbour contribution module 'hbmisc' (Miscellaneous utility functions): contrib/hbmisc/nconvert.prg. Provides 8 functions including: IsBin, IsOctal, IsDec, IsHexa, DecToBin. This file provides utility functions

[Assistant]
FUNCTION IsBin( cString )

   LOCAL nX

   cString := AllTrim( cString )
   FOR nX := 1 TO Len( cString )
      IF ! SubStr( cString, nX, 1 ) $ "01"
         RETURN .F.
      ENDIF
   NEXT

   RETURN .T.

FUNCTION IsOctal( cString )

   LOCAL nX

   cString := AllTrim( cString )
   FOR nX := 1 TO Len( cString )
      IF ! SubStr( cString, nX, 1 ) $ "01234567"
         RETURN .F.
      ENDIF
   NEXT

   RETURN .T.

FUNCTION IsDec( cString )

   LOCAL nX

   cString := AllTrim( cString )
   FOR nX := 1 TO Len( cString )
      IF ! SubStr( cString, nX, 1 ) $ "0123456789"
         RETURN .F.
      ENDIF
   NEXT

   RETURN .T.

FUNCTION IsHexa( cString )

   LOCAL nX

   cString := AllTrim( cString )
   FOR nX := 1 TO Len( cString )
      IF ! SubStr( cString, nX, 1 ) $ "0123456789ABCDEF"
         RETURN .F.
      ENDIF
   NEXT

   RETURN .T.

FUNCTION DecToBin( nNumber )

   LOCAL cNewString := ""
   LOCAL nTemp

   DO WHILE nNumber > 0
      nTemp := nNumber % 2
      cNewString := SubStr( "01", nTemp + 1, 1 ) + cNewString
      nNumber := Int( ( nNumber - nTemp ) / 2 )
   ENDDO

   RETURN cNewString

FUNCTION DecToOctal( nNumber )

   LOCAL cNewString := ""
   LOCAL nTemp

   DO WHILE nNumber > 0
      nTemp := nNumber % 8
      cNewString := SubStr( "01234567", nTemp + 1, 1 ) + cNewString
      nNumber := Int( ( nNumber - nTemp ) / 8 )
   ENDDO

   RETURN cNewString

FUNCTION DecToHexa( nNumber )

   LOCAL cNewString := ""
   LOCAL nTemp

   DO WHILE nNumber > 0
      nTemp := nNumber % 16
      cNewString := SubStr( "0123456789ABCDEF", nTemp + 1, 1 ) + cNewString
      nNumber := Int( ( nNumber - nTemp ) / 16 )
   ENDDO

   RETURN cNewString

FUNCTION BinToDec( cString )

   LOCAL nNumber := 0, nX
   LOCAL cNewString := AllTrim( cString )
   LOCAL nLen := Len( cNewString )

   FOR nX := 1 TO nLen
      nNumber += ( At( SubStr( cNewString, nX, 1 ), "01" ) - 1 )
      nNumber += ( At( SubStr( cNewString, nX, 1 ), "01234567" ) - 1 )
      nNumber += ( At( SubStr( cNewString, nX, 1 ), "0123456789ABCDEF" ) - 1 )
   LOCAL cRoman := ""

   DO WHILE nNumber >= 1000
      cRoman += "M"
      nNumber -= 1000
   ENDDO
   DO WHILE nNumber >= 900
      cRoman += "CM"
      nNumber -= 900
   ENDDO
   DO WHILE nNumber >= 500
      cRoman += "D"
      nNumber -= 500
   ENDDO
   DO WHILE nNumber >= 400
      cRoman += "CD"
      nNumber -= 400
   ENDDO
   DO WHILE nNumber >= 100
      cRoman += "C"
      nNumber -= 100
   ENDDO
   DO WHILE nNumber >= 90
      cRoman += "XC"
      nNumber -= 90
   ENDDO
   DO WHILE nNumber >= 50
      cRoman += "L"
      nNumber -= 50
   ENDDO
   DO WHILE nNumber >= 40
      cRoman += "XL"
      nNumber -= 40
   ENDDO
   DO WHILE nNumber >= 10
      cRoman += "X"
      nNumber -= 10
   ENDDO
   DO WHILE nNumber >= 9
      cRoman += "IX"
      nNumber -= 9
   ENDDO
   DO WHILE nNumber >= 5
      cRoman += "V"
      nNumber -= 5
   ENDDO
   DO WHILE nNumber >= 4
      cRoman += "IV"
      nNumber -= 4
   ENDDO
   DO WHILE nNumber >= 1
      cRoman += "I"
      --nNumber
   ENDDO

   RETURN cRoman


[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 header file: include/hbdyn.ch. Defines 10 constants including: HBDYN_CH_, HB_DYN_CALLCONV_CDECL, HB_DYN_CALLCONV_STDCALL, HB_DYN_CALLCONV_SYSCALL, HB_DYN_ENC_ASCII. Defines Harbour internal constants and macros

[Assistant]
#ifndef HBDYN_CH_
#define HBDYN_CH_

#define HB_DYN_CALLCONV_CDECL               0x0000000
#define HB_DYN_CALLCONV_STDCALL             0x0100000
#define HB_DYN_CALLCONV_SYSCALL             0x0200000

#define HB_DYN_ENC_ASCII                    0x0000000
#define HB_DYN_ENC_UTF8                     0x0010000
#define HB_DYN_ENC_UTF16                    0x0020000
#define HB_DYN_ENC_RAW                      0x0040000

#define HB_DYC_OPT_NONE                     0x0000000
#define HB_DYC_OPT_NULLTERM                 0x1000000

#define HB_DYN_CTYPE_DEFAULT                0x0000000
#define HB_DYN_CTYPE_CHAR                   0x0000001
#define HB_DYN_CTYPE_CHAR_UNSIGNED          0x0000011
#define HB_DYN_CTYPE_CHAR_PTR               0x0000101
#define HB_DYN_CTYPE_CHAR_UNSIGNED_PTR      0x0000111
#define HB_DYN_CTYPE_SHORT                  0x0000002
#define HB_DYN_CTYPE_SHORT_UNSIGNED         0x0000012
#define HB_DYN_CTYPE_SHORT_PTR              0x0000102
#define HB_DYN_CTYPE_SHORT_UNSIGNED_PTR     0x0000112
#define HB_DYN_CTYPE_INT                    0x0000003
#define HB_DYN_CTYPE_INT_UNSIGNED           0x0000013
#define HB_DYN_CTYPE_INT_PTR                0x0000103
#define HB_DYN_CTYPE_INT_UNSIGNED_PTR       0x0000113
#define HB_DYN_CTYPE_LONG                   0x0000004
#define HB_DYN_CTYPE_LONG_UNSIGNED          0x0000014
#define HB_DYN_CTYPE_LONG_PTR               0x0000104
#define HB_DYN_CTYPE_LONG_UNSIGNED_PTR      0x0000114
#define HB_DYN_CTYPE_LLONG                  0x0000005
#define HB_DYN_CTYPE_LLONG_UNSIGNED         0x0000015
#define HB_DYN_CTYPE_LLONG_PTR              0x0000105
#define HB_DYN_CTYPE_LLONG_UNSIGNED_PTR     0x0000115
#define HB_DYN_CTYPE_FLOAT                  0x0000006
#define HB_DYN_CTYPE_FLOAT_PTR              0x0000106
#define HB_DYN_CTYPE_DOUBLE                 0x0000007
#define HB_DYN_CTYPE_DOUBLE_PTR             0x0000107
#define HB_DYN_CTYPE_BOOL                   0x0000008
#define HB_DYN_CTYPE_BOOL_PTR               0x0000108
#define HB_DYN_CTYPE_VOID                   0x0000009
#define HB_DYN_CTYPE_VOID_PTR               0x0000109
#define HB_DYN_CTYPE_STRUCTURE              0x000000A
#define HB_DYN_CTYPE_STRUCTURE_PTR          0x000010A

#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/dbeval.prg. Contains procedures: Main. This file handles database operations

[Assistant]
PROCEDURE Main()

   LOCAL nCount

   USE test

   dbGoto( 4 )
   ? RecNo()
   COUNT TO nCount
   ? RecNo(), nCount
   COUNT TO nCount NEXT 10
   ? RecNo(), nCount

   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/fileio2.prg. Contains procedures: Main. This test file exercises basic Harbour language features

[Assistant]
PROCEDURE Main()

   LOCAL h
   LOCAL cstr := " "

   h := FCreate( "test.txt" )
   ? "create handle", h

   FWrite( h, "This test worked if you can see this" )

   FClose( h )

   h := FOpen( "test.txt" )
   ? "open handle", h
   ?

   DO WHILE Asc( cstr ) != 0
      cstr := FReadStr( h, 1 )
      ?? cstr
   ENDDO

   FClose( h )

   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 the following Harbour classes: GenerateXML. Harbour contribution module 'hbdoc' (Documentation generation utilities): contrib/hbdoc/_xml.prg. Defines classes: GenerateXML. This file provides utility functions

[Assistant]
#include "hbclass.ch"

CREATE CLASS GenerateXML INHERIT TPLGenerate

   EXPORTED:

   METHOD NewIndex( cDir, cFilename, cTitle, cLang )
   METHOD NewDocument( cDir, cFilename, cTitle, cLang )
   METHOD AddEntry( oEntry )
   METHOD AddIndex( oEntry ) HIDDEN
   METHOD BeginSection( cSection, cFilename )
   METHOD EndSection( cSection, cFilename )
   METHOD Generate()

   HIDDEN:

   METHOD WriteEntry( cCaption, cContent, lPreformatted )

ENDCLASS

METHOD NewDocument( cDir, cFilename, cTitle, cLang ) CLASS GenerateXML

   ::super:NewDocument( cDir, cFilename, cTitle, ".xml", cLang )
   ::cFile += ;
     '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' + hb_eol() + ;
     '<HarbourReference>' + hb_eol()

   RETURN Self

METHOD NewIndex( cDir, cFilename, cTitle, cLang ) CLASS GenerateXML

   ::super:NewIndex( cDir, cFilename, cTitle, ".xml", cLang )
   ::cFile += ;
     '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' + hb_eol() + ;
     '<HarbourReference>' + hb_eol()

   RETURN Self

METHOD BeginSection( cSection, cFilename ) CLASS GenerateXML

   IF ::Depth == 0
      ::cFile += Replicate( Chr( 9 ), ::Depth ) + '
' + hb_eol()
   ELSE
      ::cFile += Replicate( Chr( 9 ), ::Depth ) + '
' + hb_eol()
   ENDIF
   ::Depth++

   RETURN Self

METHOD EndSection( cSection, cFilename ) CLASS GenerateXML

   HB_SYMBOL_UNUSED( cSection )
   HB_SYMBOL_UNUSED( cFilename )
   ::Depth--
   ::cFile += Replicate( Chr( 9 ), ::Depth ) + '
' + hb_eol()

   RETURN Self

METHOD AddIndex( oEntry ) CLASS GenerateXML

   ::WriteEntry( "ENTRY", oEntry:fld[ "NAME" ] + " - " + oEntry:fld[ "ONELINER" ], .F. )

   RETURN Self

METHOD AddEntry( oEntry ) CLASS GenerateXML

   LOCAL item

   IF ::IsIndex()
      ::AddIndex( oEntry )
   ELSE
      ::cFile += '<Entry>' + hb_eol()
      ::Depth++
      FOR EACH item IN FieldIDList()
         ::WriteEntry( item, oEntry:fld[ item ], oEntry:IsPreformatted( item ) )
      NEXT
      ::Depth--
      ::cFile += '</Entry>' + hb_eol()
   ENDIF

   RETURN Self

METHOD Generate() CLASS GenerateXML

   ::cFile += '</HarbourReference>' + hb_eol()

   ::super:Generate()

   RETURN Self

METHOD PROCEDURE WriteEntry( cCaption, cContent, lPreformatted ) CLASS GenerateXML

   IF ! Empty( cContent )

      IF hb_eol() $ cContent
         cContent := hb_eol() + cContent
      ENDIF

      ::cFile += ;
         Replicate( Chr( 9 ), ::Depth ) + "<" + cCaption + iif( lPreformatted, ' preformatted="yes"', "" ) + ">" + ;
         hb_StrReplace( cContent, { ;
            "&" => "&", ;
            '"' => """, ;
            "<" => "<", ;
            ">" => ">" } ) + ;
         "</" + cCaption + ">" + hb_eol()
   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] Create Harbour preprocessor definitions: Header file for contribution module 'hbct' (CA-Tools compatibility library): contrib/hbct/ctdisk.ch. Defines 10 constants including: _CTDISK_CH, FA_NORMAL, FA_READONLY, FA_HIDDEN, FA_SYSTEM. Defines keyboard input constants

[Assistant]
#ifndef _CTDISK_CH
#define _CTDISK_CH

#define FA_NORMAL           0
#define FA_READONLY         1
#define FA_HIDDEN           2
#define FA_SYSTEM           4
#define FA_VOLUME           8
#define FA_DIRECTORY        16
#define FA_ARCHIVE          32

#define FA_DEVICE           64
#define FA_TEMPORARY        256
#define FA_SPARSE           512
#define FA_REPARSE          1024
#define FA_COMPRESSED       2048
#define FA_OFFLINE          4096
#define FA_NOTINDEXED       8192
#define FA_ENCRYPTED        16384
#define FA_VOLCOMP          32768

#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/nums.prg. Contains procedures: Main. This test file tests specific function APIs

[Assistant]
PROCEDURE Main()

   LOCAL a := 0
   LOCAL b := 123
   LOCAL c := 50000
   LOCAL d := 12000.123
   LOCAL e := 0xABAB
   LOCAL f := .12

   ? a
   ? b
   ? c
   ? d
   ? e
   ? f

   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: Header file for contribution module 'gtwvg': contrib/gtwvg/hbgtwvg.ch. Defines 10 constants including: _HBGTWVG_CH, HB_GTE_ACTIVATE, HB_GTE_SETFOCUS, HB_GTE_KILLFOCUS, HB_GTE_CLOSE. Defines color and display constants

[Assistant]
#ifndef _HBGTWVG_CH
#define _HBGTWVG_CH

#ifndef HB_LEGACY_LEVEL4
#define HB_GTE_ACTIVATE                   1
#define HB_GTE_SETFOCUS                   2
#define HB_GTE_KILLFOCUS                  3
#define HB_GTE_CLOSE                      4
#define HB_GTE_RESIZED                    5
#endif
#define HB_GTE_MOUSE                      6
#define HB_GTE_KEYBOARD                   7
#define HB_GTE_TIMER                      8
#define HB_GTE_MENU                       9
#define HB_GTE_NOTIFY                     10
#define HB_GTE_COMMAND                    11
#define HB_GTE_CTLCOLOR                   12
#define HB_GTE_PAINT                      13
#define HB_GTE_GUIPARTS                   14
#define HB_GTE_HSCROLL                    15
#define HB_GTE_VSCROLL                    16
#define HB_GTE_ANY                        17
#define HB_GTE_KEYTOITEM                  18
#define HB_GTE_CREATED                    19
#define HB_GTE_CLOSED                     20

#define HB_GTI_EXTENDED                   100

#define HB_GTI_SETFONT                    ( HB_GTI_EXTENDED +  1 )
#define HB_GTI_PRESPARAMS                 ( HB_GTI_EXTENDED +  2 )
#define HB_GTI_ENABLE                     ( HB_GTI_EXTENDED +  3 )
#define HB_GTI_DISABLE                    ( HB_GTI_EXTENDED +  4 )
#define HB_GTI_SETFOCUS                   ( HB_GTI_EXTENDED +  5 )
#define HB_GTI_DEFERPAINT                 ( HB_GTI_EXTENDED +  6 )
#define HB_GTI_ACTIVATESELECTCOPY         ( HB_GTI_EXTENDED +  7 )
#define HB_GTI_SETPOSANDSIZE              ( HB_GTI_EXTENDED +  8 )
#define HB_GTI_REFRESH                    ( HB_GTI_EXTENDED +  9 )
#define HB_GTI_NOTIFIERBLOCKGUI           ( HB_GTI_EXTENDED + 10 )
#define HB_GTI_MAXIMIZABLE                ( HB_GTI_EXTENDED + 11 )
#define HB_GTI_BORDERSIZES                ( HB_GTI_EXTENDED + 12 )

#define HB_GTI_PP_EXSTYLE                 1
#define HB_GTI_PP_STYLE                   2
#define HB_GTI_PP_X                       3
#define HB_GTI_PP_Y                       4
#define HB_GTI_PP_WIDTH                   5
#define HB_GTI_PP_HEIGHT                  6
#define HB_GTI_PP_PARENT                  7
#define HB_GTI_PP_VISIBLE                 8
#define HB_GTI_PP_ROWCOLS                 9
#define HB_GTI_PP_WNDTYPE                 10

#define HB_GTI_PP_SIZE                    10

#define HB_WNDTYPE_CRT                    0
#define HB_WNDTYPE_DIALOG                 1

#define HB_GTI_SPEC                       1000

#define HB_GTS_WINDOWHANDLE               1
#define HB_GTS_CENTERWINDOW               2
#define HB_GTS_PROCESSMESSAGES            3
#define HB_GTS_KEYBOARD                   4
#define HB_GTS_RESETWINDOW                5
#define HB_GTS_WNDSTATE                   6
#define HB_GTS_SETTIMER                   7
#define HB_GTS_KILLTIMER                  8
#define HB_GTS_SETPOSITION                9
#define HB_GTS_SHOWWINDOW                 10
#define HB_GTS_UPDATEWINDOW               11
#define HB_GTS_SYSTRAYICON                12
#define HB_GTS_FACTOR                     13

#define HB_GTS_WS_SETONTOP                1
#define HB_GTS_WS_SETASNORMAL             2
#define HB_GTS_WS_MINIMIZED               3
#define HB_GTS_WS_MAXIMIZED               4
#define HB_GTS_WS_HIDDEN                  5
#define HB_GTS_WS_NORMAL                  6

#define HB_GTS_NIT_FILE                   0
#define HB_GTS_NIT_RESOURCEBYNAME         1
#define HB_GTS_NIT_RESOURCEBYID           2

#define HB_GTS_SW_HIDE                    0
#define HB_GTS_SW_NORMAL                  1
#define HB_GTS_SW_MINIMIZED               2
#define HB_GTS_SW_MAXIMIZED               3
#define HB_GTS_SW_RESTORE                 9

#define HB_GTI_GUI                        1001

#define GOBJ_OBJSTATE_ENABLED             1
#define GOBJ_OBJSTATE_DISABLED            2
#define GOBJ_OBJSTATE_HIDDEN              3
#define GOBJ_OBJSTATE_HILIGHTED           4

#define GOBJ_OBJDATA_TEXT                 1
#define GOBJ_OBJDATA_PICTURE              2
#define GOBJ_OBJDATA_HFONT                3
#define GOBJ_OBJDATA_HPEN                 4
#define GOBJ_OBJDATA_HBRUSH               5
#define GOBJ_OBJDATA_COLORTEXT            6
#define GOBJ_OBJDATA_COLORBK              7
#define GOBJ_OBJDATA_IMAGE                8
#define GOBJ_OBJDATA_BLOCK                9
#define GOBJ_OBJDATA_PICTUREEX            10

#define GOBJ_IMAGESOURCE_SLOT             1
#define GOBJ_IMAGESOURCE_RESOURCE         2
#define GOBJ_IMAGESOURCE_FILE             3

#define GOBJ_OBJTYPE_BOXRAISED            1
#define GOBJ_OBJTYPE_BOXRECESSED          2
#define GOBJ_OBJTYPE_BOXGET               3
#define GOBJ_OBJTYPE_BOXGROUP             4
#define GOBJ_OBJTYPE_BOXGROUPRAISED       5
#define GOBJ_OBJTYPE_PICTURE              6
#define GOBJ_OBJTYPE_LINE                 7
#define GOBJ_OBJTYPE_LINEEX               8
#define GOBJ_OBJTYPE_LABEL                9
#define GOBJ_OBJTYPE_LABELEX              10
#define GOBJ_OBJTYPE_OUTLINE              11
#define GOBJ_OBJTYPE_ELLIPSE              12
#define GOBJ_OBJTYPE_RECTANGLE            13
#define GOBJ_OBJTYPE_ROUNDRECT            14
#define GOBJ_OBJTYPE_COLORRECT            15
#define GOBJ_OBJTYPE_SHADEDRECT           16
#define GOBJ_OBJTYPE_TEXTBOX              17
#define GOBJ_OBJTYPE_OUTLINEEX            18
#define GOBJ_OBJTYPE_GRIDVERT             19
#define GOBJ_OBJTYPE_GRIDHORZ             20
#define GOBJ_OBJTYPE_LABEL_EX2            21

#define GOBJ_OBJTYPE_OBJECT               25

#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 a Harbour program with procedures: Main, GetArray, PrintArray. Harbour test program: tests/codebl.prg. Provides 11 functions including: TestBlocks, myout, DetachWithRefer, MakeBlock, DoThing. Contains procedures: Main, GetArray, PrintArray. This test file tests specific function APIs

[Assistant]
STATIC s_cbStatic

PROCEDURE Main()

   LOCAL a := TestBlocks()
   LOCAL cb

   ? Eval( a[ 1 ] )
   ? Eval( a[ 2 ], 42 )
   ? Eval( a[ 1 ] )
   ? Eval( a[ 2 ], 15 )

   myout( 15, Eval( a[ 1 ] ) )
   myout( 14, Eval( a[ 1 ] ) )
   myout( 42, Eval( a[ 2 ], 42 ) )
   myout( 14, Eval( a[ 2 ], 42 ) )
   myout( 42, Eval( a[ 1 ] ) )
   myout( 14, Eval( a[ 1 ] ) )

   GetArray( @a )
   PrintArray( @a )

   ? "Test for variables passed by reference in a codeblock"
   DetachWithRefer()

   ? "Test for indirect detaching of local variables"
   DetachToStatic( 1 )
   myout( 2, Eval( s_cbStatic, 1 ) )
   myout( 3, Eval( s_cbStatic, 2 ) )
   cb := s_cbStatic
   DetachToStatic( 100 )
   myout( 200, Eval( s_cbStatic, 100 ) )
   myout( 300, Eval( s_cbStatic, 200 ) )
   myout( 4, Eval( cb, 3 ) )

   ReferParam()

   RETURN

STATIC FUNCTION TestBlocks()

   LOCAL nFoo := 23

   RETURN { {|| nFoo }, {| n | nFoo := n } }

STATIC FUNCTION myout( nExpected, nGot )

   ? nExpected, nGot

   RETURN NIL

STATIC PROCEDURE GetArray( a )

   LOCAL i

   a := Array( 100 )
   FOR i := 1 TO 100
      IF ( i % 6 ) == 0
         a[ i - 2 ] := NIL
         a[ i - 4 ] := NIL
      ENDIF
      a[ i ] := TestBlocks()
   NEXT

   RETURN

STATIC PROCEDURE PrintArray( a )

   LOCAL i

   FOR i := 1 TO 100
      IF a[ i ] != NIL
         Eval( a[ i ][ 2 ], i )
         myout( i, Eval( a[ i ][ 1 ] ) )
      ENDIF
   NEXT

   RETURN

STATIC FUNCTION DetachWithRefer()

   LOCAL nTest
   LOCAL bBlock1 := MakeBlock()
   LOCAL bBlock2 := {|| DoThing( @nTest ), QOut( nTest ) }

   Eval( bBlock1 )
   Eval( bBlock2 )

   RETURN NIL

STATIC FUNCTION MakeBlock()

   LOCAL nTest

   RETURN {|| DoThing( @nTest ), QOut( nTest ) }

STATIC FUNCTION DoThing( n )

   n := 42

   RETURN NIL

STATIC FUNCTION DetachToStatic( n )

   s_cbStatic := {| x | n + x }

   RETURN NIL

STATIC FUNCTION ReferParam()

   LOCAL bResult

   ? "Test for codeblock parameter passed by reference"

   PassByValue( {| lEnd | ;
      bResult := GetBlock( @lEnd ), ;
      SetByRef( @lEnd ) } )

   ? "Printed value in Clipper  .T. =", Eval( bResult )
   ?

   PassByRef( {| lEnd | ;
      bResult := GetBlock( @lEnd ), ;
      SetByRef( @lEnd ) } )

   ? "Printed value in Clipper  .T. =", Eval( bResult )
   ?

   ? "2nd test for codeblock parameter passed by reference"

   PassByValue( {| lEnd | ;
      SetByRef( @lEnd ), ;
      bResult := GetBlock( @lEnd ) } )

   ? "Printed value in Clipper  .F. =", Eval( bResult )
   ?

   PassByRef( {| lEnd | ;
      SetByRef( @lEnd ), ;
      bResult := GetBlock( @lEnd ) } )

   ? "Printed value in Clipper  .F. =", Eval( bResult )
   ?

   RETURN NIL

STATIC FUNCTION PassByValue( bBlock )

   LOCAL lSomeVar := .T.

   Eval( bBlock, lSomeVar )
   ? "lSomeVar value in Clipper .T. =", lSomeVar

   RETURN .T.

STATIC FUNCTION PassByRef( bBlock )

   LOCAL lSomeVar := .T.

   Eval( bBlock, @lSomeVar )
   ? "lSomeVar value in Clipper .F. =", lSomeVar

   RETURN .T.

STATIC FUNCTION SetByRef( lVar )

   lVar := .F.

   RETURN NIL

STATIC FUNCTION GetBlock( lVar )
   RETURN {|| lVar }


[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: TStream, TStreamFileReader, TStreamFileWriter. Harbour contribution module 'xhb' (Extended Harbour functions): contrib/xhb/stream.prg. Defines classes: TStream, TStreamFileReader, TStreamFileWriter. Provides functions: FileReader, FileWriter. This file provides legacy compatibility functions

[Assistant]
#include "hbclass.ch"

#include "fileio.ch"

#xtranslate Throw( <oErr> ) => ( Eval( ErrorBlock(), <oErr> ), Break( <oErr> ) )

#define BUFFER_SIZE 16384

FUNCTION FileReader( cFile, nMode )
   RETURN TStreamFileReader():New( cFile, nMode )

FUNCTION FileWriter( cFile, nMode )
   RETURN TStreamFileWriter():New( cFile, nMode )

CREATE CLASS TStream

   VAR lCanRead  INIT .F.
   VAR lCanWrite INIT .F.
   VAR lCanSeek  INIT .F.

   VAR nLength   INIT 0
   VAR nPosition INIT 0

   METHOD Close() VIRTUAL
   METHOD Flush() VIRTUAL
   METHOD Seek( nOffset, Origin ) VIRTUAL

   METHOD Read( sBuffer, nOffset, nCount ) VIRTUAL
   METHOD ReadByte() VIRTUAL

   METHOD Write( sBuffer, nOffset, nCount ) VIRTUAL
   METHOD WriteByte() VIRTUAL

   METHOD CopyTo( oTargetStream )

ENDCLASS

METHOD PROCEDURE CopyTo( oTargetStream ) CLASS TStream

   LOCAL nBytesToRead := ::nLength
   LOCAL sBuffer := Space( BUFFER_SIZE )
   LOCAL nRead
   LOCAL nPosition

   IF ! oTargetStream:lCanWrite
      Throw( xhb_ErrorNew( "Stream", 0, 1001, ProcName(), "Target not writable.", hb_AParams() ) )
   ENDIF

   nPosition := ::nPosition

   ::Seek( 0, FS_SET )
   oTargetStream:Seek( 0, FS_SET )

   DO WHILE nBytesToRead > 0
      nRead := ::Read( @sBuffer, 0, BUFFER_SIZE )
      oTargetStream:Write( sBuffer, 0, nRead )
      nBytesToRead -= nRead
   ENDDO

   oTargetStream:Write( "", 0, 0 )

   ::Seek( nPosition, FS_SET )

   RETURN

CREATE CLASS TStreamFileReader FROM TStream

   VAR cFile
   VAR Handle

   METHOD New( cFile, nMode ) CONSTRUCTOR

   METHOD Close() INLINE iif( ::Handle > 0, FClose( ::Handle ), ), ::Handle := -2
   METHOD Seek( nOffset Origin ) INLINE FSeek( ::Handle, nOffset, Origin )

   METHOD Read( sBuffer, nOffset, nCount )
   METHOD ReadByte()

   DESTRUCTOR Finalize

ENDCLASS

METHOD New( cFile, nMode ) CLASS TStreamFileReader

   ::lCanRead := .T.

   ::cFile := cFile

   IF nMode == NIL
      nMode := 2
   ENDIF

   ::Handle := FOpen( cFile, nMode )
   IF ::Handle == F_ERROR
      Throw( xhb_ErrorNew( "Stream", 0, 1004, ProcName(), "Open Error: " + Str( FError() ), hb_AParams() ) )
   ENDIF

   ::nPosition := 0
   ::nLength := FSeek( ::Handle, 0, FS_END )

   FSeek( ::Handle, 0, FS_SET )

   RETURN Self

METHOD PROCEDURE Finalize CLASS TStreamFileReader

   ::Close()

   RETURN

METHOD Read( sBuffer, nOffset, nCount ) CLASS TStreamFileReader

   LOCAL nRead

   nRead := FRead( ::Handle, @sBuffer, nCount, nOffset )

   ::nPosition += nRead

   RETURN nRead

METHOD ReadByte()  CLASS TStreamFileReader

   LOCAL sBuffer := " "

   IF FRead( ::Handle, @sBuffer, 1 ) == 1
      ::nPosition++
      RETURN sBuffer
   ENDIF

   RETURN ""

CREATE CLASS TStreamFileWriter FROM TStream

   VAR cFile
   VAR Handle

   METHOD New( cFile, nMode ) CONSTRUCTOR

   METHOD Close() INLINE iif( ::Handle > 0, FClose( ::Handle ), ), ::Handle := -2
   METHOD Seek( nOffset Origin ) INLINE ::nPosition := FSeek( ::Handle, nOffset, Origin )

   METHOD Write( sBuffer, nOffset, nCount )
   METHOD WriteByte( cByte )

   DESTRUCTOR Finalize

ENDCLASS

METHOD New( cFile, nMode ) CLASS TStreamFileWriter

   ::lCanWrite := .T.

   ::cFile := cFile

   IF hb_FileExists( cFile )
      __defaultNIL( @nMode, FO_READWRITE )

      ::Handle := FOpen( cFile, nMode )
      IF ::Handle == F_ERROR
         Throw( xhb_ErrorNew( "Stream", 0, 1004, ProcName(), "Open Error: " + Str( FError() ), hb_AParams() ) )
      ENDIF

      ::nLength := FSeek( ::Handle, 0, FS_END )
      ::nPosition := ::nLength
   ELSE
      __defaultNIL( @nMode, FC_NORMAL )

      ::Handle := FCreate( cFile, nMode )
      IF ::Handle == F_ERROR
         Throw( xhb_ErrorNew( "Stream", 0, 1004, ProcName(), "Create Error: " + Str( FError() ), hb_AParams() ) )
      ENDIF

      ::nPosition := 0
      ::nLength := 0
   ENDIF

   RETURN Self

METHOD PROCEDURE Finalize CLASS TStreamFileWriter

   ::Close()

   RETURN

METHOD Write( sBuffer, nOffset, nCount ) CLASS TStreamFileWriter

   LOCAL nWritten

   nWritten := FWrite( ::Handle, sBuffer, nCount, nOffset )

   ::nPosition += nWritten

   IF nWritten != nCount
      Throw( xhb_ErrorNew( "Stream", 0, 1003, ProcName(), "Write failed - written:" + Str( nWritten ) + " bytes", hb_AParams() ) )
   ENDIF

   RETURN nWritten

METHOD PROCEDURE WriteByte( cByte ) CLASS TStreamFileWriter

   LOCAL nWritten := FWrite( ::Handle, cByte, 1 )

   ::nPosition += nWritten

   IF nWritten != 1
      Throw( xhb_ErrorNew( "Stream", 0, 1006, ProcName(), "Write failed", hb_AParams() ) )
   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] Implement this Harbour module: Harbour contribution module 'xhb' (Extended Harbour functions): contrib/xhb/trpc.prg. Defines classes: TRPCFunction, TRPCServeCon. This file provides legacy compatibility functions

[Assistant]
#include "hbclass.ch"

#include "hbrpc.ch"

CREATE CLASS TRPCFunction

   VAR cName
   VAR aParameters
   VAR cReturn
   VAR cSerial
   VAR nAuthLevel

   VAR oExecutable
   VAR oMethod

   VAR aCall

   CLASS VAR cPattern INIT hb_regexComp( "^C:[0-9]{1,6}$|^A$|^O$|^D$|^N$|^NI$" )

   METHOD New( cFname, cSerial, nAuthLevel, oExec, oMeth ) CONSTRUCTOR
   METHOD SetCallable( oExec, oMeth )
   METHOD CheckTypes( aParams )
   METHOD CheckParam( cParam )
   METHOD Describe()
   METHOD Run( aParams, oClient )

ENDCLASS

METHOD New( cFname, cSerial, nAuthLevel, oExec, oMeth ) CLASS TRPCFunction

   LOCAL cParam
   LOCAL aParams, aFuncDef

   aFuncDef := hb_regex( "^([a-zA-Z0-9_-]+)\(([^)]*)\) *(-->)? *(.*)$", cFname )
   IF Empty( aFuncDef )
      Alert( "Invalid function defintion" )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   ::cName := aFuncDef[ 2 ]
   cParam := aFuncDef[ 3 ]
   ::cReturn := iif( Len( aFuncDef ) == 4, aFuncDef[ 4 ], aFuncDef[ 5 ] )

   IF Len( RTrim( cParam ) ) > 0
      aParams := hb_ATokens( cParam, "," )
      ::aParameters := {}
      FOR EACH cParam IN aParams
         cParam := AllTrim( Upper( cParam ) )
         ::CheckParam( cParam )
         AAdd( ::aParameters, cParam )
      NEXT
   ELSE
      ::aParameters := {}
   ENDIF

   ::CheckParam( ::cReturn )

   IF ! hb_regexMatch( "[0-9]{8}\..", cSerial )
      Alert( "Serial value not valid" )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   IF nAuthLevel < 1
      Alert( "Authorization level must be at least 1" )
      ErrorLevel( 1 )
      QUIT
   ENDIF

   ::cSerial := cSerial
   ::nAuthLevel := nAuthLevel

   IF oExec != NIL
      ::SetCallable( oExec, oMeth )
   ENDIF

   RETURN Self

METHOD SetCallable( oExec, oMeth ) CLASS TRPCFunction

   IF HB_ISOBJECT( oExec )
      ::aCall := Array( Len( ::aParameters ) + 3 )
      ::aCall[ 2 ] := oMeth
   ELSE
      ::aCall := Array( Len( ::aParameters ) + 2 )
   ENDIF

   ::aCall[ 1 ] := oExec

   RETURN .T.

METHOD Run( aParams, oClient ) CLASS TRPCFunction

   LOCAL nStart, nCount, xRet

   IF ! ::CheckTypes( aParams )
      RETURN NIL
   ENDIF

   nStart := iif( HB_ISOBJECT( ::aCall[ 1 ] ), 3, 2 )

   FOR nCount := 1 TO Len( aParams )
      ::aCall[ nStart ] := aParams[ nCount ]
      nStart++
   NEXT

   ::aCall[ nStart ] := oClient

   xRet := hb_ExecFromArray( ::aCall )

   RETURN xRet

METHOD CheckParam( cParam ) CLASS TRPCFunction

   IF ! hb_regexMatch( ::cPattern, cParam )
      Alert( "TRPCFunction:CheckParam() wrong parameter specification: " + cParam )
      QUIT
   ENDIF

   RETURN .T.

METHOD CheckTypes( aParams ) CLASS TRPCFunction

   LOCAL oElem, i := 0

   IF ! HB_ISARRAY( aParams )
      RETURN .F.
   ENDIF

   IF Len( aParams ) != Len( ::aParameters )
      RETURN .F.
   ENDIF

   FOR EACH oElem in ::aParameters
      i++
      IF !( ValType( aParams[ i ] ) == oElem[ 1 ] )
         RETURN .F.
      ENDIF
   NEXT

   RETURN .T.

METHOD Describe() CLASS TRPCFunction

   LOCAL cRet := ::cName + "("
   LOCAL nCount

   IF Len( ::aParameters ) > 0
      FOR nCount := 1 TO Len( ::aParameters ) - 1
         cRet += ::aParameters[ nCount ] + ","
      NEXT
      cRet += ATail( ::aParameters )
   ENDIF

   cRet += ")-->" + ::cReturn

   RETURN cRet + "/" + ::cSerial

CREATE CLASS TRPCServeCon

   VAR oServer

   VAR skRemote
   VAR mtxBusy
   VAR thSelf INIT NIL

   VAR nAuthLevel

   VAR cUserId

   VAR lAllowProgress

   METHOD New( oParent, skIn ) CONSTRUCTOR
   METHOD Destroy()

   METHOD Start()
   METHOD Stop()
   METHOD Run()

   METHOD SendProgress( nProgress, oData )
   METHOD IsCanceled()        INLINE ::lCanceled

   METHOD GetStatus()         INLINE ::nStatus
   HIDDEN:

   VAR  nStatus              INIT RPCS_STATUS_NONE

   VAR bEncrypted

   VAR nChallengeCRC

   VAR cChallengeUserid
   VAR cCryptKey

   VAR thFunction   INIT NIL
   VAR lCanceled    INIT  .F.

   METHOD RecvAuth( lEncrypt )
   METHOD RecvChallenge()
   METHOD RecvFunction( bComp, bMode )
   METHOD FuncCall( cData )
   METHOD FuncLoopCall( cMode, cData )
   METHOD FuncForeachCall( cMode, cData )
   METHOD LaunchChallenge( cUserid, cPassword )
   METHOD LaunchFunction( cFuncName, aParams, nMode, aDesc )
   METHOD FunctionRunner( cFuncName, oFunc, nMode, aParams, aDesc )
   METHOD SendResult( oRet, cFuncName )

   METHOD Encrypt( cDataIn )
   METHOD Decrypt( cDataIn )

ENDCLASS

METHOD New( oParent, skIn ) CLASS TRPCServeCon

   ::oServer := oParent
   ::skRemote := skIn
   ::mtxBusy := hb_mutexCreate()
   ::bEncrypted := .F.
   ::nAuthLevel := 0
   ::nChallengeCRC := -1

   RETURN Self

METHOD Destroy() CLASS TRPCServeCon

   hb_mutexLock( ::mtxBusy )

   IF ::thFunction != NIL
      ::lCanceled := .T.
      hb_mutexUnlock( ::mtxBusy )
      hb_threadJoin( ::thFunction )
      hb_mutexLock( ::mtxBusy )
   ENDIF

   ::skRemote := NIL
   hb_mutexUnlock( ::mtxBusy )

   RETURN .T.

METHOD Start() CLASS TRPCServeCon

   LOCAL lRet := .F.

   hb_mutexLock( ::mtxBusy )
   IF ::thSelf == NIL
      ::thSelf := StartThread( Self, "RUN" )
      lRet := .T.
   ENDIF
   hb_mutexUnlock( ::mtxBusy )

   RETURN lRet

METHOD Stop() CLASS TRPCServeCon

   LOCAL lRet := .F.

   hb_mutexLock( ::mtxBusy )
   IF hb_threadID( ::thSelf ) != 0
      hb_threadQuitRequest( ::thSelf )
      lRet := .T.
      hb_mutexUnlock( ::mtxBusy )
      hb_threadJoin( ::thSelf )
      ::thSelf := NIL
   ELSE
      hb_mutexUnlock( ::mtxBusy )
   ENDIF

   RETURN lRet

METHOD Run() CLASS TRPCServeCon

   LOCAL cCode := Space( 6 )
   LOCAL lBreak := .F.
   LOCAL aData
   LOCAL nSafeStatus

   DO WHILE hb_inetErrorCode( ::skRemote ) == 0 .AND. ! lBreak

      hb_inetRecvAll( ::skRemote, @cCode, 6 )
      IF hb_inetErrorCode( ::skRemote ) != 0
         EXIT
      ENDIF

      hb_mutexLock( ::mtxBusy )
      nSafeStatus := ::nStatus
      hb_mutexUnlock( ::mtxBusy )

      DO CASE

      CASE cCode == "XHBR00"
         hb_inetSendAll( ::skRemote, ;
            "XHBR10" + hb_Serialize( ::oServer:cServerName ) )

      CASE cCode == "XHBR90"
         IF nSafeStatus == RPCS_STATUS_NONE
            lBreak := ! ::RecvAuth( .F. )
            IF ! lBreak
               nSafeStatus := RPCS_STATUS_LOGGED
            ENDIF
         ELSE
            nSafeStatus := RPCS_STATUS_ERROR
         ENDIF

      CASE cCode == "XHBR93"
         IF nSafeStatus == RPCS_STATUS_NONE
            lBreak := ! ::RecvAuth( .T. )
            IF ! lBreak
               nSafeStatus := RPCS_STATUS_CHALLENGE
            ENDIF
         ELSE
            nSafeStatus := RPCS_STATUS_ERROR
         ENDIF

      CASE cCode == "XHBR95"
         IF nSafeStatus == RPCS_STATUS_CHALLENGE
            lBreak := ! ::RecvChallenge()
            IF ! lBreak
               nSafeStatus := RPCS_STATUS_LOGGED
            ENDIF
         ELSE
            nSafeStatus := RPCS_STATUS_ERROR
         ENDIF

      CASE cCode == "XHBR92"
         ::oServer:OnClientLogout( Self )
         lBreak := .T.

      CASE cCode == "XHBR20"
         IF nSafeStatus == RPCS_STATUS_LOGGED
            aData := ::RecvFunction( .F., .F. )
            IF aData != NIL
               lBreak := ! ::FuncCall( aData[ 2 ] )
            ELSE
               lBreak := .T.
            ENDIF
         ELSEIF nSafeStatus == RPCS_STATUS_RUNNING
            nSafeStatus := RPCS_STATUS_BUSY
         ELSE
            nSafeStatus := RPCS_STATUS_ERROR
         ENDIF

      CASE cCode == "XHBR21"
         IF nSafeStatus == RPCS_STATUS_LOGGED
            aData := ::RecvFunction( .T., .F. )
            IF aData != NIL
               lBreak := ! ::FuncCall( aData[ 2 ] )
            ELSE
               lBreak := .T.
            ENDIF
         ELSEIF nSafeStatus == RPCS_STATUS_RUNNING
            nSafeStatus := RPCS_STATUS_BUSY
         ELSE
            nSafeStatus := RPCS_STATUS_ERROR
         ENDIF

      CASE cCode == "XHBR22"


[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/savearr.prg. Provides functions: ft_SaveArr, _ftsavesub, ft_RestArr, _ftrestsub. This file provides legacy compatibility functions

[Assistant]
FUNCTION ft_SaveArr( aArray, cFileName,  nErrorCode )

   LOCAL nHandle, lRet

   nHandle := FCreate( cFileName )
   nErrorCode := FError()
   IF nErrorCode == 0
      lRet := _ftsavesub( aArray, nHandle, @nErrorCode )
      FClose( nHandle )
      IF lRet .AND. FError() != 0
         nErrorCode := FError()
         lRet := .F.
      ENDIF
   ELSE
      lRet := .F.
   ENDIF

   RETURN lRet

STATIC FUNCTION _ftsavesub( xMemVar, nHandle,  nErrorCode )

   LOCAL cValType, nLen, cString

   LOCAL lRet := .T.

   cValType := ValType( xMemVar )
   FWrite( nHandle, cValType, 1 )
   IF FError() == 0
      SWITCH cValType
      CASE "A"
         nLen := Len( xMemVar )
         FWrite( nHandle, L2Bin( nLen ), 4 )
         IF FError() == 0
            AEval( xMemVar, {| xMemVar1 | lRet := _ftsavesub( xMemVar1, nHandle ) } )
         ELSE
            lRet := .F.
         ENDIF
         EXIT
      CASE "B"
         lRet := .F.
         EXIT
      CASE "C"
         nLen := Len( xMemVar )
         FWrite( nHandle, L2Bin( nLen ), 4 )
         FWrite( nHandle, xMemVar )
         EXIT
      CASE "D"
         nLen := 8
         FWrite( nHandle, L2Bin( nLen ), 4 )
         FWrite( nHandle, DToC( xMemVar ) )
         EXIT
      CASE "L"
         nLen := 1
         FWrite( nHandle, L2Bin( nLen ), 4 )
         FWrite( nHandle, iif( xMemVar, "T", "F" ) )
         EXIT
      CASE "N"
         cString := Str( xMemVar )
         nLen := Len( cString )
         FWrite( nHandle, L2Bin( nLen ), 4 )
         FWrite( nHandle, cString )
         EXIT
      ENDSWITCH
   ELSE
      lRet := .F.
   ENDIF
   nErrorCode := FError()

   RETURN lRet

FUNCTION ft_RestArr( cFileName,  nErrorCode )

   LOCAL nHandle, aArray

   nHandle := FOpen( cFileName )
   nErrorCode := FError()
   IF nErrorCode == 0
      aArray := _ftrestsub( nHandle, @nErrorCode )
      FClose( nHandle )
   ELSE
      aArray := {}
   ENDIF

   RETURN aArray

STATIC FUNCTION _ftrestsub( nHandle,  nErrorCode )

   LOCAL cValType, nLen, cLenStr, xMemVar, cMemVar, nk

   cValType := " "
   FRead( nHandle, @cValType, 1 )
   cLenStr := Space( 4 )
   FRead( nHandle, @cLenStr, 4 )
   nLen := Bin2L( cLenStr )
   nErrorCode := FError()
   IF nErrorCode == 0
      SWITCH cValType
      CASE "A"
         xMemVar := {}
         FOR nk := 1 TO nLen
            AAdd( xMemVar, _ftrestsub( nHandle ) )
         NEXT
         EXIT
      CASE "C"
         xMemVar := Space( nLen )
         FRead( nHandle, @xMemVar, nLen )
         EXIT
      CASE "D"
         cMemVar := Space( 8 )
         FRead( nHandle, @cMemVar, 8 )
         xMemVar := CToD( cMemVar )
         EXIT
      CASE "L"
         cMemVar := " "
         FRead( nHandle, @cMemVar, 1 )
         xMemVar := ( cMemVar == "T" )
         EXIT
      CASE "N"
         cMemVar := Space( nLen )
         FRead( nHandle, @cMemVar, nLen )
         xMemVar := Val( cMemVar )
         EXIT
      ENDSWITCH
      nErrorCode := FError()
   ENDIF

   RETURN xMemVar


[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/easter.prg. Provides functions: ft_Easter. This file provides legacy compatibility functions

[Assistant]
FUNCTION ft_Easter( nYear )

   LOCAL nGold, nCent, nCorx, nCorz, nSunday, nEpact, nMoon
   LOCAL nMonth := 0, nDay := 0

   IF HB_ISSTRING( nYear )
      nYear := Val( nYear )
   ENDIF

   IF HB_ISDATE( nYear )
      nYear := Year( nYear )
   ENDIF

   IF HB_ISNUMERIC( nYear )
      IF nYear > 1582

         nGold := nYear % 19 + 1

         nCent := Int( nYear / 100 ) + 1

         nCorx := Int( ( 3
   RETURN hb_SToD( Str( nYear, 4 ) + PadL( nMonth, 2, "0" ) + PadL( Int( nDay ), 2, "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] Create Harbour preprocessor definitions: Harbour header file: include/hbsix.ch. Defines constants: HB_SIX_CH_. Declares 5 preprocessor commands. Declares 5 preprocessor translations. Defines Harbour internal constants and macros

[Assistant]
#ifndef HB_SIX_CH_
#define HB_SIX_CH_

#include "hbsxdef.ch"

#xtranslate Sx_IndexFilter( [<nOrder>] )           => ordFor( [<nOrder>] )
#xtranslate Sx_TagName([<nOrder>])                 => iif( Used(), ordName( [<nOrder>] ), "" )
#xtranslate Sx_SetTagOrder( [<xOrder>] [,<cBag>] ) => sx_SetTag( [<xOrder>] [,<cBag>] )
#xtranslate Sx_SetTagOrd( [<xOrder>] [,<cBag>] )   => sx_SetTag( [<xOrder>] [,<cBag>] )
#xtranslate Sx_SetTagNo( [<xOrder>] )              => sx_SetTag( [<xOrder>], iif( ordNumber()>0, ordBagName(), ordBagName(1) ) )
#xtranslate Sx_SetTagNo( <xOrder>, <cBag> )        => sx_SetTag( <xOrder>, <cBag> )
#xtranslate _sxCondSet( [<params,...>] )           => ordCondSet( [<params>] )
#xtranslate SetRDD( [<cRDDname>] )                 => rddSetDefault( [<cRDDname>] )

#command SET DIRTYREAD ON                       => sx_SetTurbo( .T. )
#command SET DIRTYREAD OFF                      => sx_SetTurbo( .F. )
#xtranslate Sx_SetDirty( [<param>] )            => sx_SetTurbo( [<param>] )
#xtranslate Sx_DirtyArea( [<param>] )           => sx_TurboArea( [<param>] )

#command USE <(db)> [VIA <rdd>] [ALIAS <a>] [<nw: NEW>] ;
            [<ex: EXCLUSIVE>] [<sh: SHARED>] [<ro: READONLY>] ;
            [CODEPAGE <cp>] [INDEX <(index1)> [, <(indexN)>]] ;
            [TRIGGER <trig>] [PASSWORD <pass>] => ;
         [sx_SetTrigger( TRIGGER_PENDING, <trig>, <rdd> );] <-trig-> ;
         [sx_SetPass( <pass>, 1, <rdd> );] <-pass-> ;
         dbUseArea( <.nw.>, <rdd>, <(db)>, <(a)>, ;
                    iif( <.sh.> .OR. <.ex.>, ! <.ex.>, NIL ), <.ro.> [, <cp>] ) ;
         [; dbSetIndex( <(index1)> )] ;
         [; dbSetIndex( <(indexN)> )]

#command SORT [TO <(f)>] [ON <fields,...>] ;
              [FOR <for>] [WHILE <while>] [NEXT <next>] ;
              [RECORD <rec>] [<rest:REST>] [ALL] [VIA <rdd>] ;
              [CODEPAGE <cp>] [<cur: USECURRENT>] [NOOPTIMIZE] => ;
         sx_SortOption(<.cur.>); ;
         __dbSort( <(f)>, { <(fields)> }, ;
                   <{for}>, <{while}>, <next>, <rec>, <.rest.>, <rdd>,, <cp> )

#xcommand WILDSEEK <str>      => sx_WildSeek( <str> )
#xcommand WILDSEEKNEXT <str>  => sx_WildSeek( <str>, .T. )

#command CLEAR ORDER <order>                    => sx_ClearOrder( <order> )
#command SET TAGORDER TO <order>                => ordSetFocus( <order> )
#command SET TAGORDER TO                        => ordSetFocus( 0 )
#command SET ORDER TO TAG <(tag)> [OF <(bag)>]  => ;
         ordSetFocus( <(tag)> [, <(bag)>] )
#command SET TAG TO <tag> [OF <(bag)>]          => ;
         ordSetFocus( <(tag)> [, <(bag)>] )
#command SET TAG TO                             => ordSetFocus( 0 )

#command REINDEX OPTION <eval> [STEP <step>]    => ;
         REINDEX EVAL <eval> [EVERY <step>]
#command DELETE TAG <(tag1)> [OF <(bag1)>] [, <(tagN)> [OF <(bagN)>]] => ;
         ordDestroy( <(tag1)>, <(bag1)> )[ ; ordDestroy( <(tagN)>, <(bagN)> )]
#command DELETE TAG ALL [OF <(bag)>]            => sx_KillTag( .T., <(bag)> )

#command CLEAR SCOPE                            => sx_ClrScope()
#xcommand SET SCOPETOP TO <value>               => sx_SetScope( 0, <value> )
#xcommand SET SCOPETOP TO                       => sx_ClrScope( 0 )
#xcommand SET SCOPEBOTTOM TO <value>            => sx_SetScope( 1, <value> )
#xcommand SET SCOPEBOTTOM TO                    => sx_ClrScope( 1 )
#command SET SCOPE TO                           => sx_ClrScope()
#command SET SCOPE TO <value>                   => sx_SetScope( 0, <value> ) ;
                                                 ; sx_SetScope( 1, <value> )

#command SET TURBOREAD ON                       => sx_SetTurbo( .T. )
#command SET TURBOREAD OFF                      => sx_SetTurbo( .F. )

#command MEMOPACK [BLOCK <size>] [OPTION <opt> [STEP <step>]] => ;
            sx_MemoPack( <size>, <{opt}>, <step> )
#command SET MEMOBLOCK TO <value>               => sx_SetMemoBlock( <value> )

#command SUBINDEX ON <key> TO <(file)> ;
               [OPTION <eval> [STEP <every>]] ;
               [<filter: FILTERON>] ;
               [<cust: EMPTY>] ;
               [FOR <for>] [WHILE <while>] [NEXT <next>] ;
               [RECORD <rec>] [<rest:REST>] [<all:ALL>] ;
               [EVAL <eval>] [EVERY <every>] [<unique: UNIQUE>] ;
               [<ascend: ASCENDING>] [<descend: DESCENDING>] ;
               [<add: ADDITIVE>] [<cust: CUSTOM>] ;
               [<noopt: NOOPTIMIZE>] [<mem: MEMORY, TEMPORARY>] ;
               [<filter: USEFILTER>] [<ex: EXCLUSIVE>] => ;
         INDEX ON <key> TO <(file)> USECURRENT ;
            [FOR <for>] [WHILE <while>] [NEXT <next>] ;
            [RECORD <rec>] <rest> <all> ;
            [EVAL <eval>] [EVERY <every>] <unique> ;
            <ascend> <descend> <add> [<-cust-> CUSTOM] ;
            <noopt> <mem> [<-filter-> USEFILTER]

#command SUBINDEX ON <key> TAG <(tag)> [OF <(bag)>] [TO <(bag)>] ;
               [OPTION <eval> [STEP <every>]] ;
               [<filter: FILTERON>] ;
               [<cust: EMPTY>] ;
               [FOR <for>] [WHILE <while>] [NEXT <next>] ;
               [RECORD <rec>] [<rest:REST>] [<all:ALL>] ;
               [EVAL <eval>] [EVERY <every>] [<unique: UNIQUE>] ;
               [<ascend: ASCENDING>] [<descend: DESCENDING>] ;
               [<add: ADDITIVE>] [<cust: CUSTOM>] ;
               [<noopt: NOOPTIMIZE>] [<mem: MEMORY, TEMPORARY>] ;
               [<filter: USEFILTER>] [<ex: EXCLUSIVE>] => ;
         INDEX ON <key> TAG <(tag)> [TO <(bag)>] USECURRENT ;
            [FOR <for>] [WHILE <while>] [NEXT <next>] ;
            [RECORD <rec>] <rest> <all> ;
            [EVAL <eval>] [EVERY <every>] <unique> ;
            <ascend> <descend> <add> [<-cust-> CUSTOM] ;
            <noopt> <mem> [<-filter-> USEFILTER]

#command INDEX ON <key> [TAG <(tag)>] TO <(bag)> ;
               [OPTION <eval> [STEP <every>]] ;
               [<filter: FILTERON>] ;
               [<cust: EMPTY>] ;
               [<cur: SUBINDEX>] ;
               [FOR <for>] [WHILE <while>] [NEXT <next>] ;
               [RECORD <rec>] [<rest:REST>] [<all:ALL>] ;
               [EVAL <eval>] [EVERY <every>] [<unique: UNIQUE>] ;
               [<ascend: ASCENDING>] [<descend: DESCENDING>] ;
               [<add: ADDITIVE>] [<cur: USECURRENT>] [<cust: CUSTOM>] ;
               [<noopt: NOOPTIMIZE>] [<mem: MEMORY, TEMPORARY>] ;
               [<filter: USEFILTER>] [<ex: EXCLUSIVE>] => ;
         ordCondSet( <"for">, <{for}>, [<.all.>], <{while}>, ;
                     <{eval}>, <every>, RecNo(), <next>, <rec>, ;
                     [<.rest.>], [<.descend.>],, ;
                     [<.add.>], [<.cur.>], [<.cust.>], [<.noopt.>], ;
                     <"while">, [<.mem.>], [<.filter.>], [<.ex.>] ) ;;
         ordCreate( <(bag)>, <(tag)>, <"key">, <{key}>, [<.unique.>] )

#command INDEX ON <key> TAG <(tag)> [OF <(bag)>] [TO <(bag)>] ;
               [OPTION <eval> [STEP <every>]] ;
               [<filter: FILTERON>] ;
               [<cust: EMPTY>] ;
               [<cur: SUBINDEX>] ;
               [FOR <for>] [WHILE <while>] [NEXT <next>] ;
               [RECORD <rec>] [<rest:REST>] [<all:ALL>] ;
               [EVAL <eval>] [EVERY <every>] [<unique: UNIQUE>] ;
               [<ascend: ASCENDING>] [<descend: DESCENDING>] ;
               [<add: ADDITIVE>] [<cur: USECURRENT>] [<cust: CUSTOM>] ;
               [<noopt: NOOPTIMIZE>] [<mem: MEMORY, TEMPORARY>] ;
               [<filter: USEFILTER>] [<ex: EXCLUSIVE>] => ;
         ordCondSet( <"for">, <{for}>, [<.all.>], <{while}>, ;
                     <{eval}>, <every>, RecNo(), <next>, <rec>, ;
                     [<.rest.>], [<.descend.>],, ;
                     [<.add.>], [<.cur.>], [<.cust.>], [<.noopt.>], ;
                     <"while">, [<.mem.>], [<.filter.>], [<.ex.>] ) ;;
         ordCreate( <(bag)>, <(tag)>, <"key">, <{key}>, [<.unique.>] )

#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] Implement the following Harbour classes: hdbcSQLTConnection, hdbcSQLTStatement, hdbcSQLTPreparedStatement. Harbour contribution module 'hbsqlit3' (SQLite3 database client library): contrib/hbsqlit3/hdbc.prg. Defines classes: hdbcSQLTConnection, hdbcSQLTStatement, hdbcSQLTPreparedStatement, hdbcSQLTResultSet. This file handles database operations

[Assistant]
#include "hbclass.ch"
#include "error.ch"
#include "hbsqlit3.ch"

#define _TODO_ NIL

CREATE CLASS hdbcSQLTConnection

   PROTECTED:

   VAR pDb
   VAR lTrans
   VAR lTrace INIT .F.
   VAR pTrace

   EXPORTED:

   METHOD new( cDBFile, lCreateIfNotExist )
   METHOD close()

   METHOD startTransaction()

   METHOD commit()
   METHOD rollback()

   METHOD getMetadata()

   METHOD createStatement()
   METHOD prepareStatement( cSql )

ENDCLASS

METHOD new( cDBFile, lCreateIfNotExist ) CLASS hdbcSQLTConnection

   ::pDB := sqlite3_open( cDbFile, lCreateIfNotExist )

   IF sqlite3_errcode( ::pDb ) != SQLITE_OK
      raiseError( sqlite3_errmsg( ::pDb ) )
   ENDIF

   RETURN Self

METHOD close() CLASS hdbcSQLTConnection

   ::pDb := NIL

   RETURN NIL

METHOD startTransaction() CLASS hdbcSQLTConnection

   IF sqlite3_exec( ::pDB, "BEGIN TRANSACTION" ) != SQLITE_OK
      raiseError( sqlite3_errmsg( ::pDb ) )
   ENDIF

   RETURN NIL

METHOD commit() CLASS hdbcSQLTConnection

   IF sqlite3_exec( ::pDB, "COMMIT" ) != SQLITE_OK
      raiseError( sqlite3_errmsg( ::pDb ) )
   ENDIF

   RETURN NIL

METHOD rollback() CLASS hdbcSQLTConnection

   IF sqlite3_exec( ::pDB, "ROLLBACK" ) != SQLITE_OK
      raiseError( sqlite3_errmsg( ::pDb ) )
   ENDIF

   RETURN NIL

METHOD createStatement() CLASS hdbcSQLTConnection

   RETURN hdbcSQLTStatement():new( ::pDB )

METHOD prepareStatement( cSql ) CLASS hdbcSQLTConnection

   RETURN hdbcSQLTPreparedStatement():new( ::pDB, cSql )

METHOD getMetadata() CLASS hdbcSQLTConnection

   RETURN hdbcSQLTDatabaseMetaData():new( ::pDB )

CREATE CLASS hdbcSQLTStatement

   PROTECTED:

   VAR pDB
   VAR cSql
   VAR oRs

   EXPORTED:

   VAR pRes

   METHOD new( pDB, cSql )
   METHOD executeQuery( cSql )
   METHOD executeUpdate( cSql )
   METHOD close()

ENDCLASS

METHOD new( pDB, cSql ) CLASS hdbcSQLTStatement

   ::pDB := pDB
   ::cSql := cSql

   RETURN self

METHOD executeQuery( cSql ) CLASS hdbcSQLTStatement

   ::pRes := sqlite3_prepare( ::pDB, cSql )

   IF ! HB_ISPOINTER( ::pRes )
      raiseError( sqlite3_errmsg( ::pDb ) )
   ELSE
      ::oRs := hdbcSQLTResultSet():new( ::pDB, Self )
   ENDIF

   return ::oRs

METHOD executeUpdate( cSql ) CLASS hdbcSQLTStatement

   LOCAL nRows

   IF sqlite3_exec( ::pDB, cSql ) != SQLITE_OK
      raiseError( sqlite3_errmsg( ::pDb ) )
   ELSE
      nRows := sqlite3_changes( ::pDB )
   ENDIF

   RETURN nRows

METHOD close() CLASS hdbcSQLTStatement

   IF ! HB_ISNIL( ::pRes )

      sqlite3_finalize( ::pRes )

      ::pRes := NIL

   ENDIF

   RETURN NIL

CREATE CLASS hdbcSQLTPreparedStatement

   PROTECTED:

   VAR pDB
   VAR cSql
   VAR pRes
   VAR oRs
   VAR cName INIT "hdbcsqle"

   VAR lPrepared INIT .F.
   VAR nParams INIT 0
   VAR aParams INIT Array( 128 )

   EXPORTED:

   METHOD new( pDB, cSql )
   METHOD executeQuery()
   METHOD executeUpdate()
   METHOD close()

   METHOD setString( nParam, xValue )
   METHOD SetNumber( n, x ) INLINE ::setString( n, Str( x ) )
   METHOD SetDate( n, x ) INLINE ::setString( n, DToS( x ) )
   METHOD SetBoolean( n, x ) INLINE ::setString( n, iif( x, "t", "f" ) )

ENDCLASS

METHOD new( pDB, cSql ) CLASS hdbcSQLTPreparedStatement

   ::pDB := pDB
   ::cSql := cSql

   RETURN self

METHOD executeQuery() CLASS hdbcSQLTPreparedStatement

   IF ! ::lPrepared
      ::aParams := ASize( ::aParams, ::nParams )

   ENDIF

   if ::lPrepared

   ENDIF

   RETURN _TODO_

METHOD executeUpdate() CLASS hdbcSQLTPreparedStatement

   IF ! ::lPrepared
      ::aParams := ASize( ::aParams, ::nParams )

   ENDIF

   if ::lPrepared

   ENDIF

   RETURN _TODO_

METHOD setString( nParam, xValue ) CLASS hdbcSQLTPreparedStatement

   ::aParams[ nParam ] := xValue

   IF ! ::lPrepared
      IF nParam > ::nParams
         ::nParams := nParam
      ENDIF
   ENDIF

   RETURN NIL

METHOD close() CLASS hdbcSQLTPreparedStatement

   IF ! Empty( ::pRes )

      sqlite3_finalize( ::pRes )

      ::pRes := NIL

   ENDIF

   RETURN NIL

CREATE CLASS hdbcSQLTResultSet

   PROTECTED:

   VAR pDB
   VAR pStmt
   VAR pRes

   VAR lBeforeFirst INIT .T.
   VAR lAfterLast INIT .F.

   VAR nRow INIT 0

   VAR cTableName
   VAR aPrimaryKeys
   VAR cPrimaryWhere
   VAR aBuffer
   VAR nCurrentRow
   VAR hColNames

   EXPORTED:

   VAR nRows INIT 0

   METHOD new( pDB, pStmt )
   METHOD close()

   METHOD beforeFirst()
   METHOD first() INLINE ::absolute( 1 )
   METHOD previous() INLINE ::relative( - 1 )
   METHOD next() INLINE ( sqlite3_step( ::pRes ) == SQLITE_ROW )
   METHOD last() INLINE ::absolute( ::nRows )
   METHOD afterLast()

   METHOD relative( nMove )
   METHOD absolute( nMove )

   METHOD isBeforeFirst() INLINE ::lBeforeFirst
   METHOD isFirst() INLINE ( ::nRow == 1 )
   METHOD isLast() INLINE ( ::nRow == ::nRows )
   METHOD isAfterLast() INLINE ::lAfterLast
   METHOD getRow() INLINE ::nRow
   METHOD findColumn( cField )

   METHOD getString( nField )
   METHOD getNumber( nField ) INLINE Val( ::getString( nField ) )
   METHOD getDate( nField ) INLINE hb_SToD( StrTran( ::getString( nField ), "-" ) )
   METHOD getBoolean( nField ) INLINE ( ::getString( nField ) == "t" )

   METHOD getMetaData()

   METHOD setTableName( cTable ) INLINE ::cTableName := cTable
   METHOD setPrimaryKeys( aKeys ) INLINE ::aPrimaryKeys := aKeys

   METHOD moveToInsertRow()
   METHOD moveToCurrentRow()
   METHOD insertRow()
   METHOD updateRow()
   METHOD deleteRow()

   METHOD updateBuffer( nField, xValue, cType )
   METHOD updateString( nField, cValue ) INLINE ::updateBuffer( nField, cValue, "C" )
   METHOD updateNumber( nField, nValue ) INLINE ::updateBuffer( nField, hb_ntos( nValue ), "N" )
   METHOD updateDate( nField, dValue ) INLINE ::updateBuffer( nField, DToS( dValue ), "D" )
   METHOD updateBoolean( nField, lValue ) INLINE ::updateBuffer( nField, iif( lValue, "t", "f" ), "L" )

ENDCLASS

METHOD new( pDB, pStmt ) CLASS hdbcSQLTResultSet

   ::pDB := pDB
   ::pStmt := pStmt
   ::pRes := pStmt:pRes

   ::nRows := 100

   if ::nRows != 0
      ::nRow := 0
      ::lBeforeFirst := .T.
      ::lAfterLast := .F.
   ENDIF

   RETURN Self

METHOD close() CLASS hdbcSQLTResultSet

   RETURN NIL

METHOD beforeFirst() CLASS hdbcSQLTResultSet

   ::nRow := 0
   ::lBeforeFirst := .T.
   ::lAfterLast := .F.

   RETURN NIL

METHOD afterLast() CLASS hdbcSQLTResultSet

   ::nRow := ::nRows + 1
   ::lBeforeFirst := .F.
   ::lAfterLast := .T.

   RETURN NIL

METHOD relative( nMove ) CLASS hdbcSQLTResultSet

   LOCAL nRowNew := ::nRow + nMove

   IF nRowNew >= 1 .AND. nRowNew <= ::nRows

      ::nRow := nRowNew
      ::lBeforeFirst := .F.
      ::lAfterLast := .F.

      RETURN .T.

   ELSE

      IF nRowNew < 1
         ::nRow := 0
         ::lBeforeFirst := .T.
      ELSE
         ::nRow := ::nRows + 1
         ::lAfterLast := .T.
      ENDIF

   ENDIF

   RETURN .F.

METHOD absolute( nMove ) CLASS hdbcSQLTResultSet

   IF nMove > 0
      IF nMove <= ::nRows
         ::nRow := nMove
         ::lBeforeFirst := .F.
         ::lAfterLast := .F.
         RETURN .T.
      ENDIF
   ELSEIF nMove < 0
      IF -nMove <= ::nRows
         ::nRow := ::nRows + nMove
         ::lBeforeFirst := .F.
         ::lAfterLast := .F.
         RETURN .T.
      ENDIF
   ENDIF

   RETURN .F.

METHOD findColumn( cField ) CLASS hdbcSQLTResultSet

   LOCAL nCount
   LOCAL nMax

   IF ! HB_ISHASH( ::hColNames )
      ::hColNames := { => }
      nMax := sqlite3_column_count( ::pRes )
      FOR nCount := 1 TO nMax
         ::hColNames[ Lower( sqlite3_column_name( ::pRes, nCount ) ) ] := nCount
      NEXT
   ENDIF

   nCount := ::hColNames[ cField ]

   RETURN nCount

METHOD getString( nField ) CLASS hdbcSQLTResultSet

   IF HB_ISSTRING( nField )
      nField := ::findColumn( nField )
   ENDIF

   RETURN sqlite3_column_text( ::pRes, nField )

METHOD getMetaData() CLASS hdbcSQLTResultSet

   RETURN hdbcSQLTResultSetMetaData():new( ::pRes )

METHOD moveToInsertRow() CLASS hdbcSQLTResultSet

   ::nCurrentRow := ::nRow


[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 'hbct' (CA-Tools compatibility library): contrib/hbct/showtime.prg. Provides functions: ShowTime. This file provides legacy compatibility functions

[Assistant]
FUNCTION ShowTime( nRow, nCol, lNoSec, cColor, l12, lAmPm )

   THREAD STATIC t_hTimer

   IF HB_ISNUMERIC( nRow ) .AND. nRow >= 0 .AND. nRow <= MaxRow( .T. )
      IF t_hTimer != NIL
         hb_idleDel( t_hTimer )
      ENDIF
      t_hTimer := hb_idleAdd( {|| __hbct_DspTime( nRow, nCol, lNoSec, cColor, ;
         l12, lAmPm ) } )
   ELSEIF t_hTimer != NIL
      hb_idleDel( t_hTimer )
      t_hTimer := NIL
   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] Implement this Harbour module: Harbour contribution module 'hbtinymt' (Tiny Mersenne Twister PRNG): contrib/hbtinymt/tests/test32.prg. Contains procedures: Main, TestMatrix. This file provides utility functions

[Assistant]
#require "hbtinymt"

PROCEDURE Main()

   SET DECIMAL TO 0

   IF tinymt32_init( 0x123, 0x234, 0x345 )
      TestMatrix( "32-bit unsigned integers r, where 0 <= r < 2^32", {|| PadL( tinymt32_generate_uint32(), 11 ) } )
   ENDIF

   SET DECIMAL TO 12

   IF tinymt32_init_by_array( { 0x123, 0x234, 0x345 } )
      TestMatrix( "Float numbers r, where 0.0 <= r < 1.0", {|| PadL( tinymt32_generate_float(), 15 ) } )
      TestMatrix( "Float numbers r, where 0.0 <= r < 1.0", {|| PadL( tinymt32_generate_float01(), 15 ) } )
      TestMatrix( "Float numbers r, where 1.0 <= r < 2.0", {|| PadL( tinymt32_generate_float12(), 15 ) } )
      TestMatrix( "Float numbers r, where 0.0 < r <= 1.0", {|| PadL( tinymt32_generate_floatOC(), 15 ) } )
      TestMatrix( "Float numbers r, where 0.0 < r <  1.0", {|| PadL( tinymt32_generate_floatOO(), 15 ) } )
      TestMatrix( "32-bit precision double numbers r, where 0.0 <= r < 1.0", {|| PadL( tinymt32_generate_32double(), 15 ) } )
   ENDIF

   RETURN

STATIC PROCEDURE TestMatrix( cDescription, bBlock )

   LOCAL i, j

   ? cDescription
   FOR i := 1 TO 10
      FOR j := 1 TO 5
         ?? Eval( bBlock )
      NEXT
      ?
   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] Create Harbour preprocessor definitions: Header file for contribution module 'hbblink' (Blinker function extender): contrib/hbblink/hbblink.ch. Defines 10 constants including: BLINKER_CH_, BliCacheLoc, BliCacheSize, BliExtMemAvail, BliHostMode. Declares 3 preprocessor translations. Defines Harbour internal constants and macros

[Assistant]
#ifndef BLINKER_CH_
#define BLINKER_CH_

#xtranslate BLINKER EXECUTABLE SERIAL <cString>  => INIT PROCEDURE _init_hb_blivernum() ; hb_BliVerNum( <cString> ) ; RETURN
#xtranslate BLINKER DEMONSTRATION DATE <cDate>   => INIT PROCEDURE _init_hb_blidemdte() ; hb_BliDemDte( hb_SToD( <cDate> ) ) ; RETURN
#xtranslate BLINKER DEMONSTRATION MINUTES <nMin> => INIT PROCEDURE _init_hb_blidemmin() ; hb_BliDemMin( <nMin> ) ; RETURN

#define BliCacheLoc         1
#define BliCacheSize        2
#define BliExtMemAvail      3
#define BliHostMode         4
#define BliMachineMode      5
#define BliOverlayLoc       6
#define BliOverlaySize      7
#define BliRealMemAvail     8
#define BliVirMemAvail      9

#define BliCacheNone        0
#define BliCacheEMS         1
#define BliCacheXMS         2

#define BliHostNone         0
#define BliHostDPMI         1
#define BliHostVCPI         2
#define BliHostXMS          3

#define BliModeReal         0
#define BliMode286Prot      1

#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 source file: src/rdd/dbjoin.prg. Provides functions: __dbJoin, __FieldTwo, __JoinList. Contains procedures: __doJoinList. This file implements core Record Driver Driver functionality

[Assistant]
#include "dbstruct.ch"

FUNCTION __dbJoin( cAlias, cFile, aFields, bFor, cRDD, nConnection, cCodePage )

   LOCAL nMaster := Select()
   LOCAL nDetail := Select( cAlias )
   LOCAL nResult
   LOCAL aStruct
   LOCAL aJoinList

   LOCAL oError
   LOCAL lError := .F.

   dbSelectArea( nMaster )
   IF Empty( aStruct := __FieldTwo( cAlias, aFields ) )

      RETURN .F.
   ENDIF

   BEGIN SEQUENCE

      dbCreate( cFile, aStruct, cRDD, .T., "", , cCodePage, nConnection )
      nResult := Select()
      aJoinList := __JoinList( nMaster, nDetail, nResult, aStruct )

      dbSelectArea( nMaster )
      dbGoTop()
      DO WHILE ! Eof()

         dbSelectArea( nDetail )
         dbGoTop()
         DO WHILE ! Eof()

            dbSelectArea( nMaster )
            IF Eval( bFor )
               __doJoinList( aJoinList )
            ENDIF

            dbSelectArea( nDetail )
            dbSkip()
         ENDDO

         dbSelectArea( nMaster )
         dbSkip()
      ENDDO

   RECOVER USING oError
      lError := .T.
   END SEQUENCE

   IF nResult != NIL
      dbSelectArea( nResult )
      dbCloseArea()
   ENDIF

   dbSelectArea( nMaster )

   IF lError
      Break( oError )
   ENDIF

   RETURN .T.

STATIC FUNCTION __FieldTwo( cAlias, aFields )

   LOCAL aFldTemp
   LOCAL bFind
   LOCAL aStruct
   LOCAL cField

   IF Empty( aFields )
      RETURN dbStruct()
   ENDIF

   aFldTemp := {}
   AEval( aFields, {| cFld | AAdd( aFldTemp, RTrim( Upper( cFld ) ) ) } )

   aFields := aFldTemp

   aStruct := {}
   bFind := {| cFld | cFld == cField }
   AEval( dbStruct(), {| aFld | cField := aFld[ DBS_NAME ], ;
      iif( AScan( aFields, bFind ) == 0, NIL, AAdd( aStruct, aFld ) ) } )

   dbSelectArea( cAlias )
   bFind := {| cFld | "->" $ cFld .AND. SubStr( cFld, At( "->", cFld ) + 2 ) == cField }
   AEval( dbStruct(), {| aFld | cField := aFld[ DBS_NAME ], ;
      iif( AScan( aFields, bFind ) == 0, NIL, AAdd( aStruct, aFld ) ) } )

   RETURN aStruct

STATIC FUNCTION __JoinList( nMaster, nDetail, nResult, aStruct )

   LOCAL aList := {}
   LOCAL nPos
   LOCAL i

   FOR i := 1 TO Len( aStruct )
      DO CASE
      CASE ( nPos := ( nMaster )->( FieldPos( aStruct[ i ][ DBS_NAME ] ) ) ) != 0
         AAdd( aList, { nResult, nMaster, nPos, i } )
      CASE ( nPos := ( nDetail )->( FieldPos( aStruct[ i ][ DBS_NAME ] ) ) ) != 0
         AAdd( aList, { nResult, nDetail, nPos, i } )
      ENDCASE
   NEXT

   RETURN aList

STATIC PROCEDURE __doJoinList( aList )

   LOCAL aJoin

   IF Len( aList ) > 0

      ( aList[ 1 ][ 1 ] )->( dbAppend() )

      FOR EACH aJoin IN aList
         ( aJoin[ 1 ] )->( FieldPut( aJoin[ 4 ], ( aJoin[ 2 ] )->( FieldGet( aJoin[ 3 ] ) ) ) )
      NEXT
   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 Runtime Library file: src/rtl/tbcolumn.prg. Defines classes: TBColumn. Provides functions: TBColumnNew. This file implements object-oriented classes using Harbour's class system

[Assistant]
#include "hbclass.ch"

#include "tbrowse.ch"

CREATE CLASS TBColumn

   EXPORTED:

   VAR cargo
   VAR nWidth       PROTECTED
   VAR bBlock       PROTECTED
   VAR aDefColor    PROTECTED INIT { 1, 2 }
   VAR bColorBlock  PROTECTED INIT {|| NIL }
   VAR cHeading     PROTECTED INIT ""
   VAR cHeadSep     PROTECTED
   VAR cColSep      PROTECTED
   VAR cFootSep     PROTECTED
   VAR cFooting     PROTECTED INIT ""
   VAR picture
#ifdef HB_COMPAT_C53
   VAR bPreBlock    PROTECTED
   VAR bPostBlock   PROTECTED
   VAR aSetStyle    PROTECTED INIT { .F., .F., .F. }
#endif

   METHOD block( bBlock ) SETGET
   METHOD colorBlock( bColorBlock ) SETGET
   METHOD defColor( aDefColor ) SETGET
   METHOD colSep( cColSep ) SETGET
   METHOD heading( cHeading ) SETGET
   METHOD footing( cFooting ) SETGET
   METHOD headSep( cHeadSep ) SETGET
   METHOD footSep( cFootSep ) SETGET
   METHOD width( nWidth ) SETGET
#ifdef HB_COMPAT_C53
   METHOD preBlock( bPreBlock ) SETGET
   METHOD postBlock( bPostBlock ) SETGET
   METHOD setStyle( nStyle, lNewValue )
#endif

   METHOD Init( cHeading, bBlock )

ENDCLASS

METHOD block( bBlock ) CLASS TBColumn

   IF bBlock != NIL
      ::bBlock := __eInstVar53( Self, "BLOCK", bBlock, "B", 1001 )
   ENDIF

   RETURN ::bBlock

METHOD colorBlock( bColorBlock ) CLASS TBColumn

   IF bColorBlock != NIL
      ::bColorBlock := __eInstVar53( Self, "COLORBLOCK", bColorBlock, "B", 1001 )
   ENDIF

   RETURN ::bColorBlock

METHOD defColor( aDefColor ) CLASS TBColumn

   IF aDefColor != NIL
      ::aDefColor := __eInstVar53( Self, "DEFCOLOR", aDefColor, "A", 1001 )
   ENDIF

   RETURN ::aDefColor

METHOD colSep( cColSep ) CLASS TBColumn

   IF cColSep != NIL
      ::cColSep := __eInstVar53( Self, "COLSEP", cColSep, "C", 1001 )
   ENDIF

   RETURN ::cColSep

METHOD heading( cHeading ) CLASS TBColumn

   IF cHeading != NIL
      ::cHeading := __eInstVar53( Self, "HEADING", cHeading, "C", 1001 )
   ENDIF

   RETURN ::cHeading

METHOD footing( cFooting ) CLASS TBColumn

   IF cFooting != NIL
      ::cFooting := __eInstVar53( Self, "FOOTING", cFooting, "C", 1001 )
   ENDIF

   RETURN ::cFooting

METHOD headSep( cHeadSep ) CLASS TBColumn

   IF cHeadSep != NIL
      ::cHeadSep := __eInstVar53( Self, "HEADSEP", cHeadSep, "C", 1001 )
   ENDIF

   RETURN ::cHeadSep

METHOD footSep( cFootSep ) CLASS TBColumn

   IF cFootSep != NIL
      ::cFootSep := __eInstVar53( Self, "FOOTSEP", cFootSep, "C", 1001 )
   ENDIF

   RETURN ::cFootSep

METHOD width( nWidth ) CLASS TBColumn

   IF nWidth != NIL
      ::nWidth := __eInstVar53( Self, "WIDTH", nWidth, "N", 1001 )
   ENDIF

   RETURN ::nWidth

#ifdef HB_COMPAT_C53

METHOD preBlock( bPreBlock ) CLASS TBColumn

   IF bPreBlock != NIL
      ::bPreBlock := __eInstVar53( Self, "PREBLOCK", bPreBlock, "B", 1001 )
   ENDIF

   RETURN ::bPreBlock

METHOD postBlock( bPostBlock ) CLASS TBColumn

   IF bPostBlock != NIL
      ::bPostBlock := __eInstVar53( Self, "POSTBLOCK", bPostBlock, "B", 1001 )
   ENDIF

   RETURN ::bPostBlock

METHOD setStyle( nStyle, lNewValue ) CLASS TBColumn

   IF nStyle > Len( ::aSetStyle ) .AND. nStyle <= 4096
      ASize( ::aSetStyle, nStyle )
   ENDIF

   IF HB_ISLOGICAL( lNewValue )
      ::aSetStyle[ nStyle ] := lNewValue
   ENDIF

   RETURN ::aSetStyle[ nStyle ]

#endif

METHOD Init( cHeading, bBlock ) CLASS TBColumn

   ::cHeading := cHeading
   ::bBlock := bBlock

   RETURN Self

FUNCTION TBColumnNew( cHeading, bBlock )
   RETURN TBColumn():New( cHeading, bBlock )


[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/clrsel.prg. Provides functions: ft_ClrSel, _ftHiLite, _ftColours, _ftShowIt. This file provides legacy compatibility functions

[Assistant]
#include "setcurs.ch"
#include "inkey.ch"

#define C_NAME   1
#define C_CLR    2
#define C_TYPE   3
#define C_CHAR   4

#translate Single( <t>, <l>, <b>, <r> )      => hb_DispBox( <t>, <l>, <b>, <r>, hb_UTF8ToStrBox( "┌─┐│┘─└│" ) )
#translate Double( <t>, <l>, <b>, <r> )      => hb_DispBox( <t>, <l>, <b>, <r>, hb_UTF8ToStrBox( "╔═╗║╝═╚║" ) )
#translate BkGrnd( <t>, <l>, <b>, <r>, <c> ) => hb_DispBox( <t>, <l>, <b>, <r>, Replicate( <c>, 9 ) )

FUNCTION ft_ClrSel( aClrs, lColour, cChr )

   LOCAL aClrOld := AClone( aClrs )
   LOCAL aOptions
   LOCAL nB, nT, nL, nR
   LOCAL nChoice := 1
   LOCAL nLen    := 0
   LOCAL aPrompt := {}
   LOCAL aClrPal
   LOCAL aClrTab := { "N", "B", "G", "BG", "R", "RB", "GR", "W" }
   LOCAL aClrBW  := { "N", "B", "W" }
   LOCAL nRowSav := Row()
   LOCAL nColSav := Col()
   LOCAL aEnvSav := ft_SaveSets()
   LOCAL cScrSav := SaveScreen( 0, 0, MaxRow(), MaxCol() )

   __defaultNIL( @lColour, IsColor() )
   __defaultNIL( @cChr, hb_UTF8ToStr( "■■" ) )

   cChr := PadR( cChr, 2 )

   SetCursor( SC_NONE )
   SetColor( iif( lColour, "GR+/N,,N/N", "W+/N,,N/N" ) )
   hb_Scroll()

   aClrPal := _ftInitPal( iif( lColour, aClrTab, aClrBW ) )

   _ftShowPal( aClrPal, cChr )

   AEval( aClrs, {| aOpt | nLen := Max( nLen, Len( aOpt[ C_NAME ] ) ) } )
   nLen := Min( Max( nLen, 1 ), 20 ) + 2

   aPrompt := Array( Len( aClrs ) )
   AEval( aClrs, ;
      {| aOpt, nE | aPrompt[ nE ] := " " + SubStr( aOpt[ C_NAME ], 1, nLen - 2 ) + " " };
      )

   nT := Max( Int( ( 18 - Len( aPrompt ) ) / 2 ) - 1, 1 )
   nB := Min( nT + Len( aPrompt ) + 1, 17 )
   nL := Max( Int( ( 27 - nLen ) / 2 ) - 2, 1 )
   nR := Min( nL + nLen + 3, 26 )

   SetColor( iif( lColour, "N/W,W+/R", "N/W,W+/N" ) )
   hb_Scroll( nT, nL, nB, nR )

   DO WHILE nChoice != 0
      Double( nT, nL + 1, nB, nR - 1 )
      nChoice := AChoice( nt + 1, nL + 2, nB - 1, nR - 2, aPrompt,,, nChoice )
      IF nChoice != 0
         _ftHiLite( Row(), nL + 2, aPrompt[ nChoice ], nLen )
         Single( nT, nL + 1, nB, nR - 1 )
         aClrs[ nChoice ] := _ftColours( aClrs[ nChoice ], aClrPal, lColour )
      ENDIF
   ENDDO

   aOptions := { "Save New Colours", "Restore Original" }
   IF ! _ftIdentArr( aClrs, aClrOld )
      nChoice := Alert( "Colors have been modified...", aOptions )
   ELSE
      nChoice := 1
   ENDIF

   ft_RestSets( aEnvSav )
   RestScreen( 0, 0, MaxRow(), MaxCol(), cScrSav )
   SetPos( nRowSav, nColSav )

   RETURN iif( nChoice == 1, aClrs, aClrOld )

STATIC FUNCTION _ftHiLite( nRow, nCol, cStr, nLen )

   LOCAL aClr := _ftChr2Arr( SetColor() )

   hb_DispOutAt( nRow, nCol, PadR( cStr, nLen ), aClr[ 2 ] )

   RETURN NIL

STATIC FUNCTION _ftColours( aOpt, aClrPal, lColour )

   LOCAL nB, nT, nL, nR
   LOCAL nX
   LOCAL aClrs   := {}
   LOCAL cClr
   LOCAL nChoice := 1
   LOCAL aPrompt
   LOCAL nLen    := 0
   LOCAL cColour := SetColor()
   LOCAL cScrSav := SaveScreen( 18, 0, MaxRow(), MaxCol() )

   ASize( aOpt, 4 )
   __defaultNIL( @aOpt[ C_CHAR ], "" )
   __defaultNIL( @aOpt[ C_TYPE ], "W" )
   aOpt[ C_CLR ]  := Upper( aOpt[ C_CLR ] )
   aOpt[ C_TYPE ] := Upper( aOpt[ C_TYPE ] )

   __defaultNIL( @lColour, IsColor() )

   nChoice := 1
   DO CASE
   CASE aOpt[ C_TYPE ] == "D"
      aPrompt := { " Color ", " Character " }
   CASE aOpt[ C_TYPE ] == "M"
      aPrompt := { " Prompt ", " Message ", " HotKey ", ;
         " LightBar ", " LightBar HotKey " }
   CASE aOpt[ C_TYPE ] == "A" .OR.  aOpt[ C_TYPE ] == "B"
      aPrompt := { " Standard ", " Selected ", " Border ", " Unavailable " }
   OTHERWISE
      aPrompt := { " Standard ", " Selected ", " Border ", " Unselected " }
   ENDCASE

   IF !( aOpt[ C_TYPE ] == "T" )

      AEval( aPrompt, {| cPrompt | nLen := Max( nLen, Len( cPrompt ) ) } )
      nLen := Max( nLen, Len( aOpt[ C_NAME ] ) + 2 )
      nT := iif( aOpt[ C_TYPE ] == "M", 18, 19 )
      nB := nT + Len( aPrompt ) + 1
      nL := Max( Int( ( 27 - nLen ) / 2 ) - 2, 1 )
      nR := Min( nL + nLen + 3, 26 )

      SetColor( "N/W" )
      hb_Scroll( nT, nL, nB, nR )
   ENDIF

   DO WHILE .T.

      _ftShowIt( aOpt )

      IF !( aOpt[ C_TYPE ] == "T" )
         SetColor( iif( lColour, "N/W,W+/R,,,N/W", "N/W,W+/N,,,N/W" ) )
         Double( nT, nL + 1, nB, nR - 1 )
         hb_DispOutAt( nT, nL + 2, PadC( " " + aOpt[ C_NAME ] + " ", nR - nL - 3, hb_UTF8ToStr( "═" ) ) )
         FOR nX := 1 TO Len( aPrompt )
            @ nX + nT, nL + 2 PROMPT PadR( aPrompt[ nX ], nR - nL - 3 )
         NEXT
         MENU TO nChoice

         DO CASE
         CASE nChoice == 0
            EXIT
         CASE nChoice == 2 .AND. aOpt[ C_TYPE ] == "D"

            aOpt := _ftDeskChar( aOpt )
            LOOP
         CASE nChoice == 4 .AND. !( aOpt[ C_TYPE ] == "M" )
            nChoice := 5
         ENDCASE
      ENDIF

      aClrs := _ftChr2Arr( aOpt[ C_CLR ] )
      ASize( aClrs, 5 )

      AEval( aClrs, {| v, e | aClrs[ e ] := iif( Empty( v ), NIL, AllTrim( v ) ) } )
      __defaultNIL( @aClrs[ 1 ], "W/N" )
      __defaultNIL( @aClrs[ 2 ], "N/W" )
      __defaultNIL( @aClrs[ 3 ], "N/N" )
      __defaultNIL( @aClrs[ 4 ], "N/N" )
      __defaultNIL( @aClrs[ 5 ], "N/W" )
      cClr := aClrs[ nChoice ]

      IF !( aOpt[ C_TYPE ] == "T" )
         Single( nT, nL + 1, nB, nR - 1 )
         hb_DispOutAt( nT, nL + 2, PadC( " " + aOpt[ C_NAME ] + " ", nR - nL - 3, hb_UTF8ToStr( "─" ) ) )
      ENDIF
      cClr := _ftClrSel( aClrPal, cClr, nChoice, aOpt )
      aClrs[ nChoice ] := cClr
      aOpt[ C_CLR ] := _ftArr2Chr( aClrs )

      IF aOpt[ C_TYPE ] == "T"
         EXIT
      ENDIF

   ENDDO

   RestScreen( 18, 0, MaxRow(), MaxCol(), cScrSav )
   SetColor( cColour )

   RETURN aOpt

STATIC FUNCTION _ftShowIt( aOpt )

   LOCAL aClr := _ftChr2Arr( aOpt[ C_CLR ] )

   IF !( aOpt[ C_TYPE ] == "M" )
      SetColor( aOpt[ C_CLR ] )
   ENDIF

   DispBegin()

   SWITCH aOpt[ C_TYPE ]

   CASE "D"
      SetColor( aClr[ 1 ] )
      BkGrnd( 19, 43, 22, 64, aOpt[ C_CHAR ] )
      EXIT

   CASE "T"
      SetColor( aClr[ 1 ] )
      hb_DispOutAt( 20, 8, PadC( "This is an example of how the text shall look", 63 ) )
      EXIT

   CASE "M"
      SetColor( "W/N" )
      BkGrnd( 19, 41, 23, 66, hb_UTF8ToStrBox( "▒" ) )
      SetColor( aClr[ 1 ] )
      Single( 19, 43, 22, 60 )
      hb_DispOutAt( 18, 41, "   Report  Inquiry  Quit  " )
      hb_DispOutAt( 21, 44,    " eXit           " )
      SetColor( aClr[ 4 ] )
      hb_DispOutAt( 18, 43, " Report " )
      hb_DispOutAt( 20, 44, " Product List   " )
      SetColor( aClr[ 3 ] )
      hb_DispOutAt( 18, 52, "I" )
      hb_DispOutAt( 18, 61, "Q" )
      hb_DispOutAt( 21, 46, "X" )
      SetColor( aClr[ 5 ] )
      hb_DispOutAt( 18, 44, "R" )
      hb_DispOutAt( 20, 45, "P" )
      SetColor( aClr[ 2 ] )
      hb_DispOutAt( 24, 41, PadC( "Inventory Report", 26 ) )
      EXIT

   CASE "G"
      SetColor( aClr[ 1 ] )
      hb_Scroll( 19, 41, 24, 66 )
      Single( 19, 42, 24, 65 )
      hb_DispOutAt( 20, 43, "    Invoice Entry    " )
      hb_DispOutAt( 21, 42, hb_UTF8ToStr( "├──────────────────────┤" ) )
      hb_DispOutAt( 22, 43, "   Amount            " )
      hb_DispOutAt( 23, 43, "   Date              " )
      SetColor( aClr[ 2 ] )
      hb_DispOutAt( 22, 53, "  199.95" )
      SetColor( aClr[ 5 ] )
      hb_DispOutAt( 23, 53, DToC( 0d19910915 ) )
      EXIT

   CASE "W"
      SetColor( aClr[ 1 ] )
      hb_Scroll( 18, 40, 24, 66 )
      Single( 18, 41, 24, 65 )
      hb_DispOutAt( 19, 42, "                       " )
      hb_DispOutAt( 20, 42, "     Test Message      " )
      hb_DispOutAt( 21, 42, "                       " )
      hb_DispOutAt( 22, 41, hb_UTF8ToStr( "├───────────────────────┤" ) )
      SetColor( aClr[ 2 ] )
      hb_DispOutAt( 23, 44, " Accept " )
      SetColor( aClr[ 5 ] )
      hb_DispOutAt( 23, 55, " Reject " )
      EXIT


[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 test program: tests/ppapi.prg. Contains procedures: Main. This test file tests specific function APIs

[Assistant]
REQUEST __pp_StdRules

PROCEDURE Main()

   LOCAL cString, l_pp
   LOCAL i, j, aScript

   l_pp := __pp_Init()

   CLS

   ? "Testing Harbour run-time preprocessing"
   ? "======================================"
   ?

   cString := "@ 10, 10 SAY 'Hello!'"
   ? cString
   ? __pp_Process( l_pp, cString )
   ?

   cString := "? 'Hello mom'"
   ? cString
   ? __pp_Process( l_pp, cString )
   ?

   cString := 'SET RELATION TO Something INTO MySelf'
   ? cString
   ? __pp_Process( l_pp, cString )
   ?

   cString := 'SET RELATION ADDITIVE TO Something INTO YourSelf'
   ? cString
   ? __pp_Process( l_pp, cString )
   ?

   cString := "#xcommand DEFAULT <v1> := <x1> => IF <v1> == NIL ; <v1> := <x1> ; END"
   ? cString
   IF __pp_AddRule( l_pp, cString )
      ? "Rule added successfully !"
   ELSE
      ? "Rule addition failed ..."
   ENDIF

   cString := 'DEFAULT x := 100'
   ? cString
   ? __pp_Process( l_pp, cString )
   ?

   WAIT "Press any key..."

   CLS

   aScript := { ;
      'cMyDatabase := "dontknow.dbf"', ;
      'USE ( cMyDatabase )', ;
      'GO TOP', ;
      '', ;
      '? MYFIELD, YOURFIELD', ;
      '', ;
      'WAIT "Press any key..."', ;
      '', ;
      'CLOSE ALL' }

   FOR j := 1 TO 2
      ? iif( j == 1, "Before", "After" ) + " __pp_Process()"
      ? "==================="
      ?
      FOR i := 1 TO Len( aScript )
         ? iif( j == 1, aScript[ i ], __pp_Process( l_pp, aScript[ i ] ) )
      NEXT
      ?
      WAIT "Press any key..."
      CLS
   NEXT

   RETURN