[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: GetSecret, _HIDE, _VALUE. Harbour contribution module 'hbct' (CA-Tools compatibility library): contrib/hbct/getsecrt.prg. Provides functions: GetSecret, _HIDE, _VALUE. Contains procedures: _SECRET. This file provides legacy compatibility functions

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

FUNCTION GetSecret( cVar, nRow, nCol, lSay, xPrompt )

   LOCAL nCursorRow := Row()
   LOCAL nCursorCol := Col()
   LOCAL GetList := {}
   LOCAL _cGetSecret := cVar
   LOCAL lHide := .T.

   hb_default( @nRow, nCursorRow )
   hb_default( @nCol, nCursorCol )
   hb_default( @lSay, .F. )

   SetPos( nRow, nCol )
   IF xPrompt != NIL
      DevOut( xPrompt )
      nRow := Row()
      nCol := Col() + 1
   ENDIF

   SetPos( nRow, nCol )
   AAdd( GetList, _GET_( _CGETSECRET, "_CGETSECRET",,, ) )
   ATail( GetList ):reader := {| oGet, oGetList | _SECRET( @_cGetSecret, @lHide, ;
      oGet, oGetList ) }
   ATail( GetList ):block := {| xNew | _VALUE( @_cGetSecret, lHide, xNew ) }
   READ

   IF lSay
      SetPos( nRow, nCol )
      DevOut( _HIDE( _cGetSecret ) )
   ENDIF

   SetPos( nCursorRow, nCursorCol )

   RETURN _cGetSecret

STATIC FUNCTION _HIDE( cVar )

   RETURN PadR( Replicate( "*", Len( RTrim( cVar ) ) ), Len( cVar ) )

STATIC FUNCTION _VALUE(  cVar, lHide, xNew )

   IF lHide
      RETURN _HIDE( cVar )
   ELSEIF xNew != NIL
      cVar := PadR( xNew, Len( cVar ) )
   ENDIF

   RETURN cVar

STATIC PROCEDURE _SECRET(  _cGetSecret,  lHide, oGet, oGetList )

   LOCAL nKey, nLen, bKeyBlock
   LOCAL cKey

   IF oGetList == NIL
      oGetList := __GetListActive()
   ENDIF

   IF GetPreValidate( oGet )

      nLen := Len( _cGetSecret )
      oGet:SetFocus()

      DO WHILE oGet:exitState == GE_NOEXIT
         IF oGet:typeOut
            oGet:exitState := GE_ENTER
         ENDIF

         DO WHILE oGet:exitState == GE_NOEXIT
            SetCursor( iif( ReadStats( 17  ) == SC_NONE, SC_NORMAL, ReadStats( 17  ) ) )
            nKey := Inkey( 0 )
            SetCursor( SC_NONE )
            IF ( bKeyBlock := SetKey( nKey ) ) != NIL
               lHide := .F.
               Eval( bKeyBlock, ;
                  ReadStats( 10  ), ;
                  ReadStats( 11  ), ;
                  oGetList:ReadVar() )
               lHide := .T.
               LOOP
            ELSEIF nKey == K_BS
               IF oGet:pos > 1
                  _cGetSecret := Padr( Left( _cGetSecret, oGet:pos - 2 ) + ;
                                       Substr( _cGetSecret, oGet:pos ), nLen )
               ENDIF
            ELSEIF nKey == K_DEL
               _cGetSecret := Padr( Left( _cGetSecret, oGet:pos - 1 ) + ;
                                    Substr( _cGetSecret, oGet:pos + 1 ), nLen )
            ELSEIF ! ( cKey := hb_keyChar( nKey ) ) == ""
               IF Set( _SET_INSERT )
                  _cGetSecret := Stuff( Left( _cGetSecret, nLen - 1 ), ;
                                        oGet:pos, 0, cKey )
               ELSE
                  _cGetSecret := Stuff( _cGetSecret, oGet:pos, 1, cKey )
               ENDIF
               nKey := hb_keyCode( "*" )
            ENDIF
            GetApplyKey( oGet, nKey )
         ENDDO

         IF ! GetPostValidate( oGet )
            oGet:exitState := GE_NOEXIT
         ENDIF
      ENDDO
      oGet:KillFocus()
   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 a Harbour program with procedures: Main, Main_LAST, TEST_BEGIN. Harbour utility program: utils/hbtest/hbtest.prg. Provides functions: TEST_DBFAvail. Contains 4 procedures. This file is part of the test framework

[Assistant]
#include "rt_main.ch"

#include "error.ch"
#include "fileio.ch"

#include "rt_vars.ch"

#define TEST_RESULT_COL1_WIDTH  1
#define TEST_RESULT_COL2_WIDTH  20
#define TEST_RESULT_COL3_WIDTH  40
#define TEST_RESULT_COL4_WIDTH  85
#define TEST_RESULT_COL5_WIDTH  85

STATIC s_nPass
STATIC s_nFail
STATIC s_nFhnd
STATIC s_nCount
STATIC s_lShowAll
STATIC s_lNoAltResult
STATIC s_lShortcut
STATIC s_aSkipList
STATIC s_nStartTime
STATIC s_nEndTime
STATIC s_lDBFAvail := .F.

#ifdef __HARBOUR__
   REQUEST HB_LANG_EN

   ANNOUNCE HB_GTSYS
   REQUEST HB_GT_CGI_DEFAULT

   #define COPYRIGHT_YEAR  "2025"
#else
   #define COPYRIGHT_YEAR  "present"

   #xtranslate hb_eol() => ( Chr( 13 ) + Chr( 10 ) )
#endif

PROCEDURE Main( cPar1, cPar2, cPar3 )

   OutStd( ;
      "Harbour Compatibility and Regression Test Suite" + hb_eol() + ;
      "Copyright (c) 1999-" + COPYRIGHT_YEAR + ", " + ;
      "Viktor Szakats" + hb_eol() )

   IF cPar1 == NIL
      cPar1 := ""
   ENDIF
   IF cPar2 == NIL
      cPar2 := ""
   ENDIF
   IF cPar3 == NIL
      cPar3 := ""
   ENDIF

   IF "/?" $ Lower( cPar1 ) .OR. ;
      "/h" $ Lower( cPar1 ) .OR. ;
      "-?" $ Lower( cPar1 ) .OR. ;
      "-h" $ Lower( cPar1 ) .OR. ;
      "-help" $ Lower( cPar1 ) .OR. ;
      "--help" $ Lower( cPar1 )

      OutStd( hb_eol() + ;
              "Syntax:  hbtest [options]" + hb_eol() + ;
              hb_eol() + ;
              "Options:  -h, -?        Display this help." + hb_eol() + ;
              "          -all          Display all tests, not only the failures." + hb_eol() + ;
              "          -noalt        Ignore alternative results." + hb_eol() + ;
              "          -skip:<list>  Skip the listed test numbers." + hb_eol() )
      RETURN
   ENDIF

   TEST_BEGIN( cPar1 + " " + cPar2 + " " + cPar3 )

   Main_HVM()
   Main_HVMA()
   Main_MATH()
   Main_DATE()
   Main_STR()
   Main_STRA()
   Main_TRANS()
   Comp_Str()
   Exact_Str()
   New_STRINGS()
#ifdef __HARBOUR__
#ifndef __PLATFORM__VXWORKS
   Long_STRINGS()
#endif
#endif
#ifdef __XPP__
   Long_STRINGS()
#endif
   Main_ARRAY()
   Main_FILE()
   Main_MISC()
#ifdef __HARBOUR__
   Main_OPOVERL()
   Main_CLASS()
   Main_MT()
#endif
   Main_LAST()

   TEST_END()

   RETURN

STATIC PROCEDURE Main_LAST()

   HBTEST MemVarBlock( "mcString" )           IS "{||...}"
#ifndef __XPP__
   HBTEST __MRestore()                        IS "E 1 BASE 2007 Argument error (__MRESTORE) OS:0 #:0 "
#endif
   HBTEST MemVarBlock( "mcString" )           IS "{||...}"
#ifndef __XPP__
   HBTEST __MSave()                           IS "E 1 BASE 2008 Argument error (__MSAVE) OS:0 #:0 "
   HBTEST __MRestore( "$NOTHERE.MEM", .F. )   IS "E 21 BASE 2005 Open error <$NOTHERE.MEM> OS:2 #:1 F:DR"
#endif
   HBTEST MemVarBlock( "mcString" )           IS NIL
#ifndef __XPP__
   HBTEST __MSave( BADFNAME(), "*", .T. )     IS "E 20 BASE 2006 Create error <" + BADFNAME() + "> OS:2 #:1 F:DR"
#endif

   RETURN

STATIC PROCEDURE TEST_BEGIN( cParam )

   LOCAL bOldError

   s_nStartTime := Seconds()

#ifdef __HARBOUR__
   hb_cdpSelect( "EN" )
   hb_langSelect( "en" )
#endif
   Set( _SET_DATEFORMAT, "yyyy-mm-dd" )
   Set( _SET_EXACT, .F. )

   FErase( "NOT_HERE.$$$" )

   s_lShowAll := ;
      "/all" $ Lower( cParam ) .OR. ;
      "-all" $ Lower( cParam )

   s_lNoAltResult := ;
      "/noalt" $ Lower( cParam ) .OR. ;
      "-noalt" $ Lower( cParam )

   s_aSkipList := ListToNArray( CMDLGetValue( Lower( cParam ), "/skip:", "" ) )
   IF Empty( s_aSkipList )
      s_aSkipList := ListToNArray( CMDLGetValue( Lower( cParam ), "-skip:", "" ) )
   ENDIF

   s_lShortcut := .T.
   IF .T. .OR. Eval( {|| s_lShortcut := .F. } )

   ENDIF

   s_nFhnd := 1

   s_nCount := 0
   s_nPass := 0
   s_nFail := 0

   OutMsg( s_nFhnd, ;
      Replicate( "-", 75 ) + hb_eol() + ;
      "      Version: " + Version() + hb_eol() )
#ifdef __HARBOUR__
   OutMsg( s_nFhnd, ;
      "     Compiler: " + hb_Compiler() + hb_eol() )
#endif
   OutMsg( s_nFhnd, ;
      "           OS: " + OS() + hb_eol() +;
      "   Date, Time: " + DToC( Date() ) + " " + Time() + hb_eol() +;
      "Shortcut opt.: " + iif( s_lShortcut, "On", "Off" ) + hb_eol() +;
      "     Switches: " + cParam + hb_eol() +;
      Replicate( "=", 75 ) + hb_eol() )

   OutMsg( s_nFhnd, ;
      PadR( "R", TEST_RESULT_COL1_WIDTH ) + " " +;
      PadR( "No.  Line", TEST_RESULT_COL2_WIDTH ) + " " +;
      PadR( "TestCall()", TEST_RESULT_COL3_WIDTH ) + " -> " +;
      PadR( "Result", TEST_RESULT_COL4_WIDTH ) + " | " +;
            "Expected" + hb_eol() +;
      Replicate( "-", 75 ) + hb_eol() )

   PUBLIC mcLongerNameThen10Chars := "Long String Name!"
   PUBLIC mcString  := scString
   PUBLIC mcStringE := scStringE
   PUBLIC mcStringZ := scStringZ
   PUBLIC mcStringW := scStringW
   PUBLIC mnIntZ    := snIntZ
   PUBLIC mnDoubleZ := snDoubleZ
   PUBLIC mnIntP    := snIntP
   PUBLIC mnLongP   := snLongP
   PUBLIC mnDoubleP := snDoubleP
   PUBLIC mnIntN    := snIntN
   PUBLIC mnLongN   := snLongN
   PUBLIC mnDoubleN := snDoubleN
   PUBLIC mnDoubleI := snDoubleI
   PUBLIC mdDate    := sdDate
   PUBLIC mdDateE   := sdDateE
   PUBLIC mlFalse   := slFalse
   PUBLIC mlTrue    := slTrue
   PUBLIC moObject  := ErrorNew()
   PUBLIC muNIL     := suNIL
   PUBLIC mbBlock   := sbBlock
   PUBLIC mbBlockC  := sbBlockC
   PUBLIC maArray   := { 9898 }

#ifndef __XPP__

#endif

   bOldError := ErrorBlock( {| oError | Break( oError ) } )
   BEGIN SEQUENCE
      dbCreate( "_hbtmp_.dbf", { ;
         { "TYPE_C"   , "C", 15, 0 }, ;
         { "TYPE_C_E" , "C", 15, 0 }, ;
         { "TYPE_D"   , "D",  8, 0 }, ;
         { "TYPE_D_E" , "D",  8, 0 }, ;
         { "TYPE_M"   , "M", 10, 0 }, ;
         { "TYPE_M_E" , "M", 10, 0 }, ;
         { "TYPE_N_I" , "N", 11, 0 }, ;
         { "TYPE_N_IE", "N", 11, 0 }, ;
         { "TYPE_N_D" , "N", 11, 3 }, ;
         { "TYPE_N_DE", "N", 11, 3 }, ;
         { "TYPE_L"   , "L",  1, 0 }, ;
         { "TYPE_L_E" , "L",  1, 0 } } )

      USE ( "_hbtmp_.dbf" ) NEW ALIAS w_TEST EXCLUSIVE

      dbAppend()

      w_TEST->TYPE_C    := "<FieldValue>"
      w_TEST->TYPE_C_E  := ""
      w_TEST->TYPE_D    := sdDate
      w_TEST->TYPE_D_E  := sdDateE
      w_TEST->TYPE_M    := "<MemoValue>"
      w_TEST->TYPE_M_E  := ""
      w_TEST->TYPE_N_I  := 100
      w_TEST->TYPE_N_IE := 0
      w_TEST->TYPE_N_D  := 101.127
      w_TEST->TYPE_N_DE := 0
      w_TEST->TYPE_L    := .T.
      w_TEST->TYPE_L_E  := .F.

      s_lDBFAvail := .T.
   END SEQUENCE
   ErrorBlock( bOldError )

   IF ! s_lDBFAvail
      OutMsg( s_nFhnd, "WARNING: Test .dbf could not be created. Related tests will be skipped." + hb_eol() )
   ENDIF

   RETURN

FUNCTION TEST_DBFAvail()
   RETURN s_lDBFAvail

PROCEDURE TEST_CALL( cBlock, bBlock, xResultExpected, xResultAlter )

   LOCAL xResult
   LOCAL oError
   LOCAL bOldError
   LOCAL lPPError
   LOCAL lRTE
   LOCAL lFailed
   LOCAL lSkipped

   s_nCount++

   IF ValType( cBlock ) == "C"
      lPPError := .F.
   ELSE
      cBlock := "!! Preprocessor error !!"
      lPPError := .T.
   ENDIF

   lSkipped := AScan( s_aSkipList, s_nCount ) > 0

   IF lSkipped

      lFailed := .F.
      xResult := "!! Skipped !!"

   ELSE

      bOldError := ErrorBlock( {| oError | Break( oError ) } )

      BEGIN SEQUENCE
         xResult := Eval( bBlock )
         lRTE := .F.
      RECOVER USING oError
         xResult := ErrorMessage( oError )
         lRTE := .T.
      END SEQUENCE

      ErrorBlock( bOldError )

      lFailed := ResultCompare( lRTE, xResult, xResultExpected )
      IF lFailed .AND. ! s_lNoAltResult .AND. PCount() >= 4
         lFailed := ResultCompare( lRTE, xResult, xResultAlter )
      ENDIF
   ENDIF

   IF s_lShowAll .OR. lFailed .OR. lSkipped .OR. lPPError

      IF lFailed
         OutMsg( s_nFhnd, ;
            PadR( iif( lFailed, "!", iif( lSkipped, "S", " " ) ), TEST_RESULT_COL1_WIDTH ) + " " + ;


[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/mt/mttest01.prg. This test file tests specific function APIs

[Assistant]
#ifdef __XHARBOUR__
   #xtranslate hb_threadStart( <x,...> ) => StartThread( <x> )
   #xtranslate hb_threadJoin( <x,...> ) => JoinThread( <x> )
#endif

static s_var
proc main()
   local xResult
   ? Version()
   ? "join:", hb_threadJoin( hb_threadStart( @thFunc() ), @xResult )
   ? "result:", xResult
   ? "static var type:", valtype( s_var )
   ? eval( s_var )
   ? eval( s_var )
return

func thFunc()
   local i := 12345.678
   s_var := {|| i++ }
return replicate( "Hello World!!! ", 3 )


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

[Assistant]
#include "box.ch"

FUNCTION ft_XBox( ;
      cJustType, ;
      cRetWait, ;
      cBorType, ;
      cBorColor, ;
      cBoxColor, ;
      nStartRow, ;
      nStartCol, ;
      cLine1, cLine2, cLine3, cLine4, cLine5, cLine6, cLine7, cLine8 )

   LOCAL nLLen := 0
   LOCAL nLCol
   LOCAL nRCol
   LOCAL nTRow
   LOCAL nBRow
   LOCAL nLoop
   LOCAL nSayRow
   LOCAL nSayCol
   LOCAL nNumRows
   LOCAL aLines_[ 8 ]

   hb_default( @cJustType, "" )
   hb_default( @cRetWait, "" )
   hb_default( @cBorType, "" )
   hb_default( @cBorColor, "N/W" )
   hb_default( @cBoxColor, "W/N" )
   hb_default( @nStartRow, 99 )
   hb_default( @nStartCol, 99 )

   cJustType := Upper( cJustType )
   cRetWait  := Upper( cRetWait )
   cBorType  := Upper( cBorType )

   nNumRows := Min( PCount() - 7, 8 )

   aLines_[ 1 ] := iif( HB_ISSTRING( cLine1 ), AllTrim( Left( cLine1, 74 ) ), "" )
   aLines_[ 2 ] := iif( HB_ISSTRING( cLine2 ), AllTrim( Left( cLine2, 74 ) ), "" )
   aLines_[ 3 ] := iif( HB_ISSTRING( cLine3 ), AllTrim( Left( cLine3, 74 ) ), "" )
   aLines_[ 4 ] := iif( HB_ISSTRING( cLine4 ), AllTrim( Left( cLine4, 74 ) ), "" )
   aLines_[ 5 ] := iif( HB_ISSTRING( cLine5 ), AllTrim( Left( cLine5, 74 ) ), "" )
   aLines_[ 6 ] := iif( HB_ISSTRING( cLine6 ), AllTrim( Left( cLine6, 74 ) ), "" )
   aLines_[ 7 ] := iif( HB_ISSTRING( cLine7 ), AllTrim( Left( cLine7, 74 ) ), "" )
   aLines_[ 8 ] := iif( HB_ISSTRING( cLine8 ), AllTrim( Left( cLine8, 74 ) ), "" )
   ASize( aLines_, Min( nNumRows, 8 ) )

   nLoop := 1
   AEval( aLines_, {|| nLLen := Max( nLLen, Len( aLines_[ nLoop ] ) ), nLoop++ } )

   nLCol := iif( nStartCol == 99, Int( ( 76 - nLLen ) / 2 ), Min( nStartCol, 74 - nLLen ) )
   nRCol := nLCol + nLLen + 3
   nTRow := iif( nStartRow == 99, Int( ( 24 - nNumRows ) / 2 ), Min( nStartRow, 22 - nNumRows ) )
   nBRow := nTRow + nNumRows + 1

   hb_Scroll( nTRow, nLCol, nBRow, nRCol )

   SetColor( cBorColor )
   IF Left( cBorType, 1 ) == "D"
      hb_DispBox( nTRow, nLCol, nBRow, nRCol, HB_B_DOUBLE_UNI )
   ELSE
      hb_DispBox( nTRow, nLCol, nBRow, nRCol, HB_B_SINGLE_UNI )
   ENDIF

   hb_Shadow( nTRow, nLCol, nBRow, nRCol )

   SetColor( cBoxColor )
   nLoop := 1
   AEval( aLines_, {| cSayStr | ;
      nSayRow := nTRow + nLoop, ;
      nSayCol := iif( Left( cJustType, 1 ) == "L", ;
      nLCol + 2, ;
      nLCol + 2 + ( nLLen - Int( Len( aLines_[ nLoop ] ) ) ) / 2 ), ;
      nLoop++, ;
      hb_DispOutAt( nSayRow, nSayCol, cSayStr );
      } )

   IF Left( cRetWait, 1 ) == "W"
      Inkey( 0 )
   ENDIF

   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] Implement these Harbour functions: Harbour test program: tests/memvar.prg. Provides 6 functions including: Scope, Scope3, Scope5, Scope7, UseVar. Contains 18 procedures. This test file exercises basic Harbour language features

[Assistant]
#ifndef __HARBOUR__
#include "clipper.ch"
#endif

MEMVAR memvar
MEMVAR memvar1
MEMVAR memvar2
MEMVAR memvar3
MEMVAR memvar4
MEMVAR mempublic
MEMVAR memprivate
MEMVAR memparam
MEMVAR memfunc
MEMVAR public1
MEMVAR public2
MEMVAR public3
MEMVAR publCB
MEMVAR private1
MEMVAR private2
MEMVAR private3
MEMVAR privVar
MEMVAR para1
MEMVAR para2
MEMVAR para3
MEMVAR parameter1again
MEMVAR param1
MEMVAR param2
MEMVAR initmem

PROCEDURE Main()

   LOCAL main := 0

   HB_SYMBOL_UNUSED( main )

   Test1()
   WAIT "press any key..."
   Test2()
   WAIT "press any key..."
   Test3()
   WAIT "press any key..."
   Test4()
   WAIT "press any key..."
   Test5()
   WAIT "press any key..."
   Test6()
   WAIT "press any key..."
   Test7( "value1", 2, .T. )
   WAIT "press any key..."
   Test8()
   WAIT "press any key..."
   Test9()

   RETURN

PROCEDURE Test1()

   PUBL memvar1

   ? "==Test 1==PUBLIC -> PRIVATE -> PUBLIC"
   ? memvar1
   memvar1 := "main"
   ? "in MAIN : ", memvar1
   Scope( memvar1 )
   ? "back in MAIN : ", memvar1
   ?

   RETURN

FUNCTION Scope( value )

   PRIVA memvar1 := "scope"

   Scope2()
   ? "in SCOPE : ", memvar1

   RETURN value

PROCEDURE Scope2()

   PUBLIC memvar1

   ? "in SCOPE2 : ", memvar1

   RETURN

PROCEDURE Test2()

   PUBLIC memvar2

   ? "==Test 2==PUBLIC -> PUBLIC -> PUBLIC"
   ? memvar2
   memvar2 := "main"
   ? "in MAIN : ", memvar2
   Scope3( memvar2 )
   ? "back in MAIN : ", memvar2
   ?

   RETURN

FUNCTION Scope3( value )

   PUBLIC memvar2 := "scope"

   Scope4()
   ? "in SCOPE : ", memvar2

   RETURN value

PROCEDURE Scope4()

   PUBLIC memvar2

   ? "in SCOPE2 : ", memvar2

   RETURN

PROCEDURE Test3()

   PUBLIC memvar3

   ? "==Test 3==PUBLIC -> PRIVATE -> PUBLIC:="
   ? memvar3
   memvar3 := "main"
   ? "in MAIN : ", memvar3
   Scope5( memvar3 )
   ? "back in MAIN : ", memvar3
   ?

   RETURN

FUNCTION Scope5( value )

   PRIVATE memvar3 := "scope"

   Scope6()
   ? "in SCOPE : ", memvar3

   RETURN value

PROCEDURE Scope6()

   PUBLIC memvar3 := "scope2"

   ? "in SCOPE2 : ", memvar3

   RETURN

PROCEDURE Test4()

   PUBLIC memvar4

   ? "==Test 4==PUBLIC -> PUBLIC -> PUBLIC:="
   ? memvar4
   memvar4 := "main"
   ? "in MAIN : ", memvar4
   Scope7( memvar4 )
   ? "back in MAIN : ", memvar4
   ?

   RETURN

FUNCTION Scope7( value )

   PUBLIC memvar4 := "scope"

   Scope8()
   ? "in SCOPE : ", memvar4

   RETURN value

PROCEDURE Scope8()

   PUBLIC memvar4 := "scope2"

   ? "in SCOPE2 : ", memvar4

   RETURN

PROCEDURE TEST5()

   PUBLIC mempublic, public3 := 3

   PRIVATE memprivate
   PARAMETERS memparam

   ? "==Test for memvars passed by reference and __PUBLIC/__PRIVATE "
   ? "   uninitialized PUBLIC : ", mempublic

   ? "initialized PUBLIC : ", public3
   ? "  uninitialized PRIVATE : ", memprivate
   ? "uninitialized PARAMETER : ", memparam

   mempublic := "PUBLIC"
   ? "   PUBLIC with new value : ", mempublic
   memprivate := "PRIVATE"
   ? "  PRIVATE with new value : ", memprivate
   memparam := "PARAMETER"
   ? "PARAMETER with new value : ", memparam

   ? "   PUBLIC after passing by reference : ", UseVar( @mempublic )
   ? "  PRIVATE after passing by reference : ", UseVar( @memprivate )
   ? "PARAMETER after passing by reference : ", UseVar( @memparam )

#ifdef __HARBOUR__
   ? "PUBLIC created by __PUBLIC function : ", public1
#endif
   ?

   RETURN

FUNCTION UseVar( value )

   UseRef( @value )

#ifdef __HARBOUR__
   __mvPublic( "public1" )

   __mvPrivate( { "private1", "private2", "private3" } )
   ? "undeclared PUBLIC created by __PUBLIC function : ", public1
   ? "undeclared PRIVATE created by __PRIVATE function : ", private1
   ? "undeclared PRIVATE created by __PRIVATE function : ", private2
   ? "undeclared PRIVATE created by __PRIVATE function : ", private3

   public1 := "public created by __PUBLIC"
#endif
   ?

   RETURN value

PROCEDURE UseRef( reference )

   reference += " variable"

   RETURN

PROCEDURE Test6()

   PUBLIC publCB
   PRIVATE privVar := " (PRIVATE in MAIN) "

   ? "== Test for detached PRIVATE variables"
   DetachMemvar( "detached memvar" )
   ? Eval( publCB, "in Main: " )

   RETURN

PROCEDURE DetachMemvar( cValue )

   PRIVATE privVar := " (PRIVATE in DetachMemvar) "

   publCB := {| x | x + privVar + cValue }
   ? Eval( publCB, "in DetachMemvar: " )

   RETURN

PROCEDURE Test7( )

   PARAMETERS para1, para2, para3
   PARAM parameter1again

   ? "Parameter 1 : ", para1
   ? "Parameter 2 : ", para2
   ? "Parameter 3 : ", para3
   ? "Parameter 4 : ", parameter1again

   RETURN

PROCEDURE Test8()

   PRIVATE private1 := "PRIVATE1"

   ? "In Test8 before UsePriv"
   ? "Private1 : ", private1
   UsePriv( private1 )
   ? "In Test8 after UsePriv"
   ? "Private1 : ", private1

   WAIT "press any key..."

   ? "In Test8 before UsePriv with reference"
   ? "Private1 : ", private1
   UsePriv( @private1 )
   ? "In Test8 after UsePriv with reference"
   ? "Private1 : ", private1

   RETURN

PROCEDURE UsePriv()

   PARAMETERS param1

   ? "In UsePriv before UseParam"
   ? "Private1 : ", private1
   ? "Param1   : ", param1
   UseParam()
   ? "In UsePriv after UseParam"
   ? "Private1 : ", private1
   ? "Param1   : ", param1

   RETURN

PROCEDURE UseParam()

   PARAMETERS param2

   ? "In UseParam before assignment"
   ? "Private1 : ", private1
   ? "Param1   : ", param1
   ? "Param2   : ", param2
   param2 := "PARAM2"
   param1 := "new value"
   ? "In UseParam after assignment"
   ? "Private1 : ", private1
   ? "Param1   : ", param1
   ? "Param2   : ", param2

   RETURN

PROCEDURE Test9()

   PUBLIC MEMVAR
   PUBLIC memfunc

   memvar := 19

   ? "Variable with the name of module (memvar) : ", memvar

   memfunc := 33
   ? "Variable with the name of function : ", memfunc
   ? "Return value from a function : ", memfunc( 9 )

   RETURN

STATIC FUNCTION memfunc( memfunc )

   RETURN memfunc
   ? "Tests for PARAMETERS, PRIVATE nad PUBLIC variables"
   ?
   ? "in INIT function - Passed parameter : ", memvar
   ? "in INIT function - Passed parameter with different name : ", initmem
   ?

   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 OOP classes for the functionality described: Harbour contribution module 'xhb' (Extended Harbour functions): contrib/xhb/hblog.prg. Defines classes: HB_Logger, HB_LogChannel, HB_LogConsole, HB_LogFile. Provides functions: hb_BldLogMsg, hb_LogDateStamp. Contains 7 procedures. This file provides legacy compatibility functions

[Assistant]
#include "hbclass.ch"
#include "hblog.ch"
#include "fileio.ch"

STATIC s_StdLogMutex := hb_mutexCreate()
STATIC s_StdLogger

PROCEDURE hb_InitStandardLog( ... )

   LOCAL PARAM

   s_StdLogger := HB_Logger():New()

   FOR EACH PARAM in hb_AParams()
#ifdef HB_THREAD_SUPPORT
      hb_mutexLock( s_StdLogMutex )
#endif

      s_StdLogger:AddChannel( Param )

#ifdef HB_THREAD_SUPPORT
      hb_mutexUnlock( s_StdLogMutex )
#endif
   NEXT

#ifdef HB_THREAD_SUPPORT
   hb_mutexLock( s_StdLogMutex )
#endif

   s_StdLogger:SetStyle( HB_LOG_ST_DATE + HB_LOG_ST_ISODATE + HB_LOG_ST_TIME + HB_LOG_ST_LEVEL )

#ifdef HB_THREAD_SUPPORT
   hb_mutexUnlock( s_StdLogMutex )
#endif

   RETURN

PROCEDURE hb_OpenStandardLog()

   s_StdLogger:Open()

   RETURN

PROCEDURE hb_StandardLogAdd( oChannel )

   IF s_StdLogger != NIL
#ifdef HB_THREAD_SUPPORT
      hb_mutexLock( s_StdLogMutex )
#endif

      s_StdLogger:AddChannel( oChannel )

#ifdef HB_THREAD_SUPPORT
      hb_mutexUnlock( s_StdLogMutex )
#endif
   ENDIF

   RETURN

PROCEDURE hb_CloseStandardLog()

   IF s_StdLogger != NIL
#ifdef HB_THREAD_SUPPORT
      hb_mutexLock( s_StdLogMutex )
#endif

      s_StdLogger:Close()

#ifdef HB_THREAD_SUPPORT
      hb_mutexUnlock( s_StdLogMutex )
#endif
   ENDIF

   RETURN

PROCEDURE hb_SetStandardLogStyle( nStyle )

   IF s_StdLogger != NIL
#ifdef HB_THREAD_SUPPORT
      hb_mutexLock( s_StdLogMutex )
#endif

      s_StdLogger:SetStyle( nStyle )

#ifdef HB_THREAD_SUPPORT
      hb_mutexUnlock( s_StdLogMutex )
#endif
   ENDIF

   RETURN

PROCEDURE hb_StandardLogName( cName )

#ifdef HB_THREAD_SUPPORT

   hb_mutexLock( s_StdLogMutex )
#endif

   s_StdLogger:cProgName := cName

#ifdef HB_THREAD_SUPPORT
   hb_mutexUnlock( s_StdLogMutex )
#endif

   RETURN

PROCEDURE hb_StandardLog( cMsg, nPrio )

   IF s_StdLogger != NIL
#ifdef HB_THREAD_SUPPORT
      hb_mutexLock( s_StdLogMutex )
#endif

      s_StdLogger:Log( cMsg, nPrio )

#ifdef HB_THREAD_SUPPORT
      hb_mutexUnlock( s_StdLogMutex )
#endif
   ENDIF

   RETURN

FUNCTION hb_BldLogMsg( ... )

   LOCAL xVar
   LOCAL cMsg := ""

   FOR EACH xVar IN hb_AParams()
      IF HB_ISNUMERIC( xVar )
         cMsg += AllTrim( hb_CStr( xVar ) )
      ELSEIF ! HB_ISSTRING( xVar )
         cMsg += hb_CStr( xVar )
      ELSE
         cMsg += xVar
      ENDIF

      IF xVar:__enumIndex() < PCount()
         cMsg += " "
      ENDIF
   NEXT

   RETURN cMsg

FUNCTION hb_LogDateStamp()

   LOCAL dToday := Date()

   RETURN  Str( Year( dToday ), 4 ) + "-" + PadL( Month( dToday ), 2, "0" ) + "-" + PadL( Day( dToday ), 2, "0" )

CREATE CLASS HB_Logger

   VAR cProgName
   VAR aLogToChannel                   INIT  {}
   VAR nStyle                          INIT  -1
   VAR nDefaultPriority                INIT  HB_LOG_INFO

   METHOD New()
   METHOD AddChannel( oChannel )       INLINE AAdd( ::aLogToChannel, oChannel )

   METHOD SetStyle( nStyle )           INLINE ::nStyle := nStyle

   METHOD Open()
   METHOD close()

   METHOD Log( cMessage, nPriority )

ENDCLASS

METHOD New() CLASS HB_Logger

   LOCAL nCount

   FOR nCount := 1 TO PCount()
      ::AddChannel( hb_PValue( nCount ) )
   NEXT

   RETURN Self

METHOD PROCEDURE Open() CLASS HB_Logger

   LOCAL oChannel

   IF ::cProgName == NIL
      hb_FNameSplit( hb_argv( 0 ), , @::cProgName )
   ENDIF

   FOR EACH oChannel IN ::aLogToChannel
      oChannel:Open( ::cProgName )
   NEXT

   RETURN

METHOD PROCEDURE close() CLASS HB_Logger

   LOCAL oChannel

   IF ::cProgName == NIL
      hb_FNameSplit( hb_argv( 0 ), , @::cProgName )
   ENDIF

   FOR EACH oChannel IN ::aLogToChannel
      oChannel:Close( ::cProgName )
   NEXT

   RETURN

METHOD PROCEDURE Log( cMessage, nPriority ) CLASS HB_Logger

   LOCAL oChannel

   IF nPriority == NIL
      nPriority := ::nDefaultPriority
   ENDIF

   FOR EACH oChannel IN ::aLogToChannel

      oChannel:Log( ::nStyle, cMessage, ::cProgName, nPriority )
   NEXT

   RETURN

CREATE CLASS HB_LogChannel

   VAR lOpened                   INIT .F.

   METHOD New( nLevel )          CONSTRUCTOR
   METHOD Open( cName )          VIRTUAL
   METHOD close( cName )         VIRTUAL

   METHOD Log( nStyle, cMessage, cName, nPriority )
   METHOD SetActive( lAct )      INLINE   ::lActive := lAct

   METHOD Format( nStyle, cMessage, cName, nPriority )

   PROTECTED:
   METHOD Send( nStyle, cMessage, cName, nPriority )    VIRTUAL

   HIDDEN:
   VAR nLevel
   VAR lActive                  INIT .T.

ENDCLASS

METHOD New( nLevel ) CLASS HB_LogChannel

   IF nLevel == NIL

      nLevel := HB_LOG_ALL
   ENDIF

   ::nLevel := nLevel

   RETURN Self

METHOD PROCEDURE Log( nStyle, cMessage, cName, nPriority ) CLASS HB_LogChannel

   IF nPriority <= ::nLevel .AND. ::lActive
      ::Send( nStyle, cMessage, cName, nPriority )
   ENDIF

   RETURN

METHOD Format( nStyle, cMessage, cName, nPriority ) CLASS HB_LogChannel

   LOCAL cPrefix := ""

   IF hb_bitAnd( nStyle, HB_LOG_ST_DATE ) > 0
      IF hb_bitAnd( nStyle, HB_LOG_ST_ISODATE ) > 0
         cPrefix += hb_LogDateStamp()
      ELSE
         cPrefix += DToC( Date() )
      ENDIF
      cPrefix += " "
   ENDIF

   IF hb_bitAnd( nStyle, HB_LOG_ST_NAME ) > 0
      cPrefix += cName + " "
   ENDIF

   IF hb_bitAnd( nStyle, HB_LOG_ST_TIME ) > 0
      cPrefix += Time() + " "
   ENDIF

   IF hb_bitAnd( nStyle, HB_LOG_ST_LEVEL ) > 0
      SWITCH nPriority
      CASE HB_LOG_CRITICAL
         cPrefix += "CRITICAL: "
         EXIT

      CASE HB_LOG_ERROR
         cPrefix += "ERROR: "
         EXIT

      CASE HB_LOG_WARNING
         cPrefix += "WARNING: "
         EXIT

      CASE HB_LOG_INFO
         cPrefix += "INFO: "
         EXIT

      CASE HB_LOG_DEBUG
         cPrefix += "DEBUG: "
         EXIT

      OTHERWISE
         cPrefix += "DEBUG" + hb_ntos( nPriority - HB_LOG_DEBUG ) +  ": "
      ENDSWITCH
   ENDIF

   RETURN cPrefix + cMessage

CREATE CLASS HB_LogConsole FROM HB_LogChannel

   METHOD New( nLevel )
   METHOD Open( cName )
   METHOD close( cName )
   METHOD Out( ... )

   METHOD LogOnVt( ldo )      INLINE ::lRealConsole := ldo

   PROTECTED:
   METHOD Send( nStyle, cMessage, cName, nPriority )
   VAR lRealConsole    INIT .T.

ENDCLASS

METHOD New( nLevel ) CLASS HB_LogConsole

   ::Super:New( nLevel )

   RETURN Self

METHOD Open( cName ) CLASS HB_LogConsole

   IF ::lOpened
      RETURN .F.
   ENDIF

   ::Out( hb_LogDateStamp(), Time(), "--", cName, "start --" )
   ::lOpened := .T.

   RETURN .T.

METHOD close( cName ) CLASS HB_LogConsole

   IF ! ::lOpened
      RETURN .F.
   ENDIF

   ::Out( hb_LogDateStamp(), Time(), "--", cName, "end --" )
   ::lOpened := .F.

   RETURN .T.

METHOD PROCEDURE Send( nStyle, cMessage, cName, nPriority ) CLASS HB_LogConsole

   ::Out( ::Format( nStyle, cMessage, cName, nPriority ) )

   RETURN

METHOD PROCEDURE Out( ... ) CLASS HB_LogConsole

   LOCAL cMsg := "", xPar
   LOCAL nLen := Len( hb_AParams() )

   FOR EACH xPar IN hb_AParams()
      cMsg += hb_CStr( xPar )
      IF xPar:__EnumIndex() < nLen
         cMsg += " "
      ENDIF
   NEXT
   IF ::lRealConsole
      OutStd( cMsg, hb_eol() )
   ELSE
      QOut( cMsg )
   ENDIF

   RETURN

CREATE CLASS HB_LogFile FROM HB_LogChannel

   VAR cFileName
   VAR nFileHandle
   VAR nFileLimit         INIT -1
   VAR nBackup            INIT 5

   METHOD New( nLevel, cFilename, nMaxSize, nBackup )
   METHOD Open( cProgName )
   METHOD close( cProgName )

   PROTECTED:
   METHOD Send( nStyle, cMessage, cProgName, nPriority )

ENDCLASS

METHOD New( nLevel, cFilename, nMaxSize, nBackup ) CLASS HB_LogFile

   ::Super:New( nLevel )
   ::cFileName := cFileName

   IF nMaxSize != NIL
      ::nFileLimit := nMaxSize
   ENDIF

   IF nBackup != NIL
      ::nBackup := nBackup
   ENDIF

   RETURN Self

METHOD Open( cProgName ) CLASS HB_LogFile

   IF ::lOpened
      RETURN .F.
   ENDIF

   IF hb_FileExists( ::cFileName )
      ::nFileHandle := FOpen( ::cFileName, FO_READWRITE )
      IF ::nFileHandle != F_ERROR
         FSeek( ::nFileHandle, 0, FS_END )
      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]
Here is a Harbour (xBase/Clipper) implementation:

Harbour test program: tests/pipes.prg. This test file tests specific function APIs

[Assistant]
#xcommand ? [<cmd,...>]   => msg( <cmd> )
request HB_GT_CGI_DEFAULT
static s_lChild := .F.

proc main( xChild )
   local hProcess, hStdIn, hStdOut
   local n, nTimeout, nWrLim, nSent, nRead
   local cToSend, cBuffer, cProg
   local cSrvData, cCliData, cRead, cError

   s_lChild := !Empty( xChild )

   nTimeout := 1000

#if defined( __PLATFORM__UNIX )
   n := 10000
   nWrLim := 100000
#else
   n := 1000
   nWrLim := 10000

#endif
   cToSend := "ABCDEFGHIJKLMNOP"
   cSrvData := repl( left( cToSend, 16 - len( hb_eol() ) ) + hb_eol(), n )
   cCliData := lower( cSrvData  )
   cBuffer := space( 10000000 )

   if s_lChild
      ? "process started"
      if xChild == "STDOUT"
         ? "this is OUTPUT only test"
         outStd( "Child is happy to send this data :-)" + hb_eol() )
         outStd( "Bye Bye" + hb_eol() )
         errorLevel( 123 )
         return
      endif
      ? "waiting..."
      hb_idleSleep( 2.0 )

      ? "reading..."
      cRead := ""
      nRead := 0
      while .t.
         n := hb_PRead( 0, @cBuffer,, nTimeout )
         if n == -1
            ? "error during reading:", FError()
            exit
         else
            cRead += left( cBuffer, n )
            nRead += n
            ? "bytes read:", n, ", total:", nRead, ", error:", FError()
         endif
      enddo
      ? "READ DONE =>", iif( cRead == cSrvData, "OK", "ERR" )
      ? "writing..."
      cToSend := cCliData
      nSent := 0
      while len( cToSend ) > 0
         n := hb_PWrite( 1, cToSend, nWrLim, nTimeout )
         if n == -1
            ? "error during writing:", FError()
            exit
         else
            nSent += n
            ? "bytes sent:", n, ", total:", nSent, ", error:", FError()
            if n > 0
               cToSend := substr( cToSend, n + 1 )
            endif
            if nWrLim != NIL
               hb_idleSleep( 0.1 )
            endif
         endif
      enddo
   else
      cProg := hb_argv( 0 ) + " x"

      ? repl( "=", 40 )

      ? "process started"
      ? "opening child process:", cProg
      hProcess = hb_processOpen( cProg, @hStdIn, @hStdOut )
      if hProcess == -1
         ? "Cannot create child process..."
      else
         ? "child started, PID =", hProcess, ", stdin =", hStdIn, ", stdout =", hStdOut
         ? "writing..."
         cToSend := cSrvData
         nSent := 0
         while len( cToSend ) > 0
            n := hb_PWrite( hStdIn, cToSend,, nTimeout )
            if n == -1
               ? "error during writing:", FError()
               exit
            else
               nSent += n
               ? "bytes sent:", n, ", total:", nSent, ", error:", FError()
               if n > 0
                  cToSend := substr( cToSend, n + 1 )
               endif
            endif
         enddo
         FClose( hStdIn )
         ? "WRITE DONE"
         ? "reading..."
         cRead := ""
         nRead := 0
         while .t.
            n := hb_PRead( hStdOut, @cBuffer,, nTimeout )
            if n == -1
               ? "error during reading:", FError()
               exit
            else
               cRead += left( cBuffer, n )
               nRead += n
               ? "bytes read:", n, ", total:", nRead, ", error:", FError()
            endif
         enddo
         ? "READ DONE =>", iif( cRead == cCliData, "OK", "ERR" )
         FClose( hStdOut )
         ? "process result:", hb_processValue( hProcess )
      endif

      ? repl( "=", 40 )

      ? "running child process:", cProg
      ? "result:", hb_processRun( cProg, cSrvData, @cRead )
      ? "READ DONE =>", iif( cRead == cCliData, "OK", "ERR" )

      ? repl( "=", 40 )

      ? "running child process with error redirection:", cProg
      n := hb_processRun( cProg, cSrvData, @cRead, @cError )
      OutErr( cError )
      ? "result:", n
      ? "READ DONE =>", iif( cRead == cCliData, "OK", "ERR" )

      ? repl( "=", 40 )

      ? "running child process with mixed redirection:", cProg
      n := hb_processRun( cProg, cSrvData, @cRead, @cRead )

      cBuffer := cRead
      cRead := cError := ""
      for each cBuffer in hb_ATokens( cBuffer, .T. )
         if " CHILD: " $ cBuffer
            cError += cBuffer + hb_eol()
         elseif ! cBuffer == "" .or. ! cBuffer:__enumIsLast()
            cRead += cBuffer + hb_eol()
         endif
      next
      OutErr( cError )
      ? "result:", n
      ? "READ DONE =>", iif( cRead == cCliData, "OK", "ERR" )

      ? repl( "=", 40 )

      cProg := hb_argv( 0 ) + " STDOUT"
      ? "running child process only with stdout redirected:", cProg
      ? "result:", hb_processRun( cProg,, @cRead )
      ? "STDOUT =>"
      ? cRead

      ? repl( "=", 40 )

      ? "running child process with stdout and stderr redirected:", cProg
      ? "result:", hb_processRun( cProg,, @cRead, @cError )
      ? "STDOUT =>"
      ? cRead
      ? "STDERR =>"
      ? cError

      ? repl( "=", 40 )
   endif
return

static proc msg( ... )
   local param, cPar, cMsg

   cMsg := hb_tsToStr( hb_dateTime() ) + " " + iif( s_lChild, "CHILD: ", "PARENT:" )
   for each param in { ... }
      cPar := hb_CStr( param )
      cMsg += iif( cPar = ",", "", " " ) + LTrim( cPar )
   next
   OutErr( cMsg + hb_eol() )
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 'hbmxml' (XML generation library): contrib/hbmxml/hbmxml.ch. Defines 10 constants including: HBMXML_CH_, MXML_TAB, MXML_NO_CALLBACK, MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK. Defines communication constants

[Assistant]
#ifndef HBMXML_CH_
#define HBMXML_CH_

#define MXML_TAB                8

#define MXML_NO_CALLBACK        0
#define MXML_INTEGER_CALLBACK   1
#define MXML_OPAQUE_CALLBACK    2
#define MXML_REAL_CALLBACK      3
#define MXML_TEXT_CALLBACK      4
#define MXML_IGNORE_CALLBACK    5

#define MXML_NO_PARENT          0

#define MXML_IGNORE             -1

#define MXML_ELEMENT            0
#define MXML_INTEGER            1
#define MXML_OPAQUE             2
#define MXML_REAL               3
#define MXML_TEXT               4
#define MXML_CUSTOM             5

#define MXML_DESCEND            1
#define MXML_NO_DESCEND         0
#define MXML_DESCEND_FIRST      -1

#define MXML_WS_BEFORE_OPEN     0
#define MXML_WS_AFTER_OPEN      1
#define MXML_WS_BEFORE_CLOSE    2
#define MXML_WS_AFTER_CLOSE     3

#define MXML_ADD_BEFORE         0
#define MXML_ADD_AFTER          1
#define MXML_ADD_TO_PARENT      NIL

#define MXML_SAX_CDATA          1
#define MXML_SAX_COMMENT        2
#define MXML_SAX_DATA           3
#define MXML_SAX_DIRECTIVE      4
#define MXML_SAX_ELEMENT_CLOSE  5
#define MXML_SAX_ELEMENT_OPEN   6

#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. Harbour contribution module 'hbwin' (Windows API wrapper functions): contrib/hbwin/tests/registry.prg. Contains procedures: Main. This file provides platform-specific functionality

[Assistant]
#require "hbwin"

#define KEY_WOW64_64KEY 0x0100
#define KEY_WOW64_32KEY 0x0200

PROCEDURE Main()

   LOCAL tmp

   ? win_regWrite( "HKCU\_TEST\mydword", 0x11223344, WIN_REG_DWORD )
   ? hb_NumToHex( win_regRead( "HKCU\_TEST\mydword" ) )

   ? win_regWrite( "HKCU\_TEST\myqword", 0x1122334455667788, WIN_REG_QWORD )
   ? hb_NumToHex( win_regRead( "HKCU\_TEST\myqword" ) )

   Inkey( 0 )

   ? win_regDelete( "HKCU\_TEST\teszt" )
   ? win_regDelete( "HKCU\_TEST\" )

   ? ">" + win_GetCommandLineParam() + "<"
   ? ">" + wapi_GetCommandLine() + "<"

   ? ">" + hb_ValToStr( win_regGet( WIN_HKEY_CURRENT_USER, "Control Panel\Desktop", "Wallpaper" ) ) + "<"

   ? ">" + hb_ValToStr( win_regRead( "HKCU\Environment\PATH" ) ) + "<"
   ? ">" + hb_ValToStr( tmp := win_regRead( "HKCU\Control Panel\Desktop\Wallpaper" ) ) + "<"
   ? ">" + hb_ValToStr( win_regRead( "" ) ) + "<"

   ? win_regWrite( "HKCU\Control Panel\Desktop\Wallpaper", "harbour.bmp" )
   ? win_regRead( "HKCU\Control Panel\Desktop\Wallpaper" )

   Inkey( 0 )

   ? win_regWrite( "HKCU\Control Panel\Desktop\Wallpaper", tmp )

   ? win_regRead( "HKLM\SOFTWARE\7-Zip\Path" )
   IF hb_osIs64bit()
      ? win_regRead( "HKLM\SOFTWARE\7-Zip\Path",, KEY_WOW64_32KEY )
      ? win_regRead( "HKLM\SOFTWARE\7-Zip\Path",, KEY_WOW64_64KEY )
   ENDIF

   RETURN


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

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

Harbour contribution module 'hbformat' (Text formatting utilities): contrib/hbformat/utils/hbformat.prg. Provides functions: HBRawVersion. Contains 5 procedures. This file provides graphics and image processing capabilities

[Assistant]
#require "hbformat"

#include "directry.ch"
#include "hbver.ch"

ANNOUNCE HB_GTSYS
REQUEST HB_GT_CGI_DEFAULT

#define I_( x )                 hb_UTF8ToStr( hb_i18n_gettext( x ) )

PROCEDURE Main( ... )

   LOCAL oRef, aParams, cFileName, cInitDir, cParam, lRecursive := .F.

   aParams := hb_AParams()

   IF Empty( aParams ) .OR. Left( cFileName := ATail( aParams ), 1 ) $ "@-"
      About()
      RETURN
   ENDIF

   FOR EACH cParam IN aParams
      IF hb_LeftEq( cParam, "-" )
         IF SubStr( cParam, Len( "-" ) + 1 ) == "r"
            lRecursive := .T.
            cParam := "#"
            EXIT
         ENDIF
      ENDIF
   NEXT

   oRef := HBFormatCode():New( aParams, hb_FNameMerge( hb_DirBase(), "hbformat.ini" ) )
   IF oRef:nErr > 0
      OutStd( hb_StrFormat( iif( oRef:nLineErr == 0, ;
         I_( "Initialization error %1$d in parameter: %2$s" ), ;
         I_( "Initialization error %1$d on line %3$d: %2$s" ) ), oRef:nErr, oRef:cLineErr, oRef:nLineErr ) + hb_eol() )
   ENDIF

   oRef:bCallBack := {| a, i | FCallBack( a, i ) }

   IF "*" $ cFileName .OR. ;
      "?" $ cFileName

      IF SubStr( hb_FNameExt( cFileName ), 2, 1 ) < "a"
         OutErr( I_( "Wrong mask" ) + hb_eol() )
      ELSE
         cInitDir := hb_FNameDir( cFileName )
         IF HB_ISNULL( cInitDir )
            cInitDir := "." + hb_ps()
         ENDIF
         DirEval( cInitDir, hb_FNameNameExt( cFileName ), lRecursive, {| name | Reformat( oRef, name ) } )
      ENDIF
   ELSE
      Reformat( oRef, cFileName )
   ENDIF

   RETURN

STATIC PROCEDURE FCallBack( aFile, nItem )

   IF nItem % Int( Len( aFile ) / 40 ) == 1
      OutStd( "." )
   ENDIF

   RETURN

STATIC PROCEDURE Reformat( oRef, cFileName )

   LOCAL aFile

   IF ! Empty( aFile := oRef:File2Array( cFileName ) )
      OutStd( hb_StrFormat( I_( "Reformatting %1$s (%2$d lines)" ), cFileName, Len( aFile ) ) + hb_eol() )
      OutStd( "<" )
      IF oRef:Reformat( aFile )
         oRef:Array2File( cFileName, aFile )
         OutStd( ">" + hb_eol() )
      ELSE
         OutErr( hb_StrFormat( I_( "Error %1$d on line %2$d: %3$s" ), oRef:nErr, oRef:nLineErr, oRef:cLineErr ) + hb_eol() )
      ENDIF
   ELSE
      OutErr( hb_StrFormat( I_( "'%1$s' is not found..." ), cFileName ) + hb_eol() )
   ENDIF

   RETURN

STATIC PROCEDURE DirEval( cInitDir, cMask, lRecur, bCode )

   LOCAL file

   cInitDir := hb_DirSepAdd( cInitDir )
   cMask := iif( cMask == NIL, hb_osFileMask(), cMask )

   FOR EACH file IN hb_vfDirectory( cInitDir + cMask, "HSD" )
      IF "D" $ file[ F_ATTR ]
         IF ! "." == file[ F_NAME ] .AND. ;
            ! ".." == file[ F_NAME ] .AND. lRecur
            DirEval( cInitDir + file[ F_NAME ], cMask, lRecur, bCode )
         ENDIF
      ELSE
         IF bCode != NIL
            Eval( bCode, cInitDir + file[ F_NAME ] )
         ENDIF
      ENDIF
   NEXT

   RETURN

STATIC PROCEDURE About()

   OutStd( ;
      "Harbour Source Formatter " + HBRawVersion() + hb_eol() + ;
      "Copyright (c) 2010-" + ;
         "2025" + ", " + ;
         hb_Version( HB_VERSION_URL_BASE ) + hb_eol() + ;
      "Copyright (c) 2009, Alexander S.Kresin" + hb_eol() + ;
      hb_eol() )

   OutStd( ;
      I_( "Syntax:  hbformat [options] [@config] <file[s]>" ) + hb_eol() + ;
      hb_eol() )

   RETURN

STATIC FUNCTION HBRawVersion()
   RETURN StrTran( Version(), "Harbour " )


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

[User] Create Harbour preprocessor definitions: Harbour contribution module 'hbpgsql' (PostgreSQL database client library): contrib/hbpgsql/tpostgre.prg. Defines classes: TPQServer. This file handles database operations

[Assistant]
#include "hbclass.ch"
#include "postgres.ch"

#define _STRU_FIELDNAME     1
#define _STRU_FIELDTYPE     2
#define _STRU_FIELDLEN      3
#define _STRU_FIELDDEC      4
#define _STRU_TABLE         5
#define _STRU_TABLECOL      6

CREATE CLASS TPQServer

   VAR pDb
   VAR lTrans
   VAR lAllCols  INIT .T.
   VAR lNull     INIT .F.
   VAR Schema    INIT "public"
   VAR lError    INIT .F.
   VAR cError    INIT ""
   VAR lTrace    INIT .F.
   VAR pTrace

   METHOD New( cHost, cDatabase, cUser, cPass, nPort, cSchema, hCustom )
   METHOD Destroy()
   METHOD Close()              INLINE ::Destroy()

   METHOD StartTransaction()
   METHOD TransactionStatus()  INLINE PQtransactionStatus( ::pDb )
   METHOD Commit()
   METHOD Rollback()

   METHOD Query( cQuery, lNull )
   METHOD Execute( cQuery )    INLINE ::Query( cQuery )
   METHOD SetSchema( cSchema )

   METHOD NetErr()             INLINE ::lError
   METHOD ErrorMsg()           INLINE ::cError

   METHOD TableExists( cTable )
   METHOD ListTables()
   METHOD TableStruct( cTable )
   METHOD CreateTable( cTable, aStruct )
   METHOD DeleteTable( cTable  )
   METHOD TraceOn( cFile )
   METHOD TraceOff()
   METHOD SetVerbosity( num )  INLINE PQsetErrorVerbosity( ::pDb, iif( num >= 0 .AND. num <= 2, num, 1 )  )
   METHOD SetNull( lValue )

ENDCLASS

METHOD New( cHost, cDatabase, cUser, cPass, nPort, cSchema, hCustom ) CLASS TPQserver

   LOCAL res
   LOCAL item

   LOCAL cConnect := ;
      iif( HB_ISSTRING( cDatabase ), " dbname = " + EscapeParam( cDatabase ), "" ) + ;
      iif( HB_ISSTRING( cHost ), " host = " + EscapeParam( cHost ), "" ) + ;
      iif( HB_ISSTRING( cUser ), " user = " + EscapeParam( cUser ), "" ) + ;
      iif( HB_ISSTRING( cPass ), " password = " + EscapeParam( cPass ), "" ) + ;
      iif( HB_ISNUMERIC( nPort ), " port = " + hb_ntos( nPort ), "" )

   IF HB_ISHASH( hCustom )
      FOR EACH item IN hCustom
         cConnect += " " + item:__enumKey() + " = " + EscapeParam( item )
      NEXT
   ENDIF

   ::pDB := PQconnectdb( cConnect )

   IF PQstatus( ::pDb ) != CONNECTION_OK
      ::lError := .T.
      ::cError := PQerrorMessage( ::pDb )
   ELSE
      IF HB_ISSTRING( cSchema )
         ::SetSchema( cSchema )
      ELSE
         res := PQexec( ::pDB, "SELECT current_schema()" )
         IF PQresultStatus( res ) == PGRES_TUPLES_OK
            ::Schema := PQgetvalue( res, 1, 1 )
         ENDIF
      ENDIF
   ENDIF

   RETURN Self

METHOD PROCEDURE Destroy() CLASS TPQserver

   ::TraceOff()
   ::pDb := NIL

   RETURN

METHOD SetSchema( cSchema ) CLASS TPQserver

   LOCAL res
   LOCAL result

   IF PQstatus( ::pDb ) == CONNECTION_OK
      ::Schema := cSchema
      res := PQexec( ::pDB, "SET search_path TO " + cSchema )
      result := ( PQresultStatus( res ) == PGRES_COMMAND_OK )
   ELSE
      result := .F.
   ENDIF

   RETURN result

METHOD StartTransaction() CLASS TPQserver

   LOCAL res := PQexec( ::pDB, "BEGIN" )

   IF ::lError := ( PQresultStatus( res ) != PGRES_COMMAND_OK )
      ::cError := PQresultErrorMessage( res )
   ELSE
      ::cError := ""
   ENDIF

   RETURN ::lError

METHOD Commit() CLASS TPQserver

   LOCAL res := PQexec( ::pDB, "COMMIT" )

   IF ::lError := ( PQresultStatus( res ) != PGRES_COMMAND_OK )
      ::cError := PQresultErrorMessage( res )
   ELSE
      ::cError := ""
   ENDIF

   RETURN ::lError

METHOD Rollback() CLASS TPQserver

   LOCAL res := PQexec( ::pDB, "ROLLBACK" )

   IF ::lError := ( PQresultStatus( res ) != PGRES_COMMAND_OK )
      ::cError := PQresultErrorMessage( res )
   ELSE
      ::cError := ""
   ENDIF

   RETURN ::lError

METHOD Query( cQuery, lNull ) CLASS TPQserver

   IF ! HB_ISLOGICAL( lNull )
      lNull := ::lNull
   ENDIF

   RETURN TPQQuery():New( ::pDB, cQuery, ::lAllCols, ::Schema,, lNull )

METHOD TableExists( cTable ) CLASS TPQserver

   LOCAL result

   LOCAL res := PQexec( ::pDB, ;
      "SELECT table_name" + ;
      "  FROM information_schema.tables" + ;
      " WHERE table_type = 'BASE TABLE' AND table_schema = " + DataToSql( ::Schema ) + " AND table_name = " + DataToSql( Lower( cTable ) ) )

   IF ::lError := ( PQresultStatus( res ) != PGRES_TUPLES_OK )
      ::cError := PQresultErrorMessage( res )
      result := .F.
   ELSE
      ::cError := ""
      result := ( PQlastrec( res ) != 0 )
   ENDIF

   RETURN result

METHOD ListTables() CLASS TPQserver

   LOCAL result := {}
   LOCAL i

   LOCAL res := PQexec( ::pDB, ;
      "SELECT table_name" + ;
      "  FROM information_schema.tables" + ;
      " WHERE table_schema = " + DataToSql( ::Schema ) + " AND table_type = 'BASE TABLE'" )

   IF ::lError := ( PQresultStatus( res ) != PGRES_TUPLES_OK )
      ::cError := PQresultErrorMessage( res )
   ELSE
      FOR i := 1 TO PQlastrec( res )
         AAdd( result, PQgetvalue( res, i, 1 ) )
      NEXT
      ::cError := ""
   ENDIF

   RETURN result

METHOD TableStruct( cTable ) CLASS TPQserver

   LOCAL result := {}
   LOCAL i
   LOCAL cField
   LOCAL cType
   LOCAL nSize
   LOCAL nDec

   LOCAL res := PQexec( ::pDB, ;
      "SELECT column_name, data_type, character_maximum_length, numeric_precision, numeric_scale" + ;
      "  FROM information_schema.columns" + ;
      " WHERE table_schema = " + DataToSql( ::Schema ) + " AND table_name = " + DataToSql( Lower( cTable ) ) + ;
      " ORDER BY ordinal_position" )

   IF ::lError := ( PQresultStatus( res ) != PGRES_TUPLES_OK )
      ::cError := PQresultErrorMessage( res )
   ELSE
      ::cError := ""

      FOR i := 1 TO PQlastrec( res )

         cField := PQgetvalue( res, i, 1 )
         cType  := PQgetvalue( res, i, 2 )
         nSize  := PQgetvalue( res, i, 4 )
         nDec   := PQgetvalue( res, i, 5 )

         DO CASE
         CASE "char" $ cType
            cType := "C"
            nSize := Val( PQgetvalue( res, i, 3 ) )
            nDec  := 0

         CASE "text" $ cType
            cType := "M"
            nSize := 10
            nDec := 0

         CASE "boolean" $ cType
            cType := "L"
            nSize := 1
            nDec  := 0

         CASE "smallint" $ cType
            cType := "N"
            nSize := 5
            nDec  := 0

         CASE "integer" $ cType .OR. "serial" $ cType
            cType := "N"
            nSize := 9
            nDec  := 0

         CASE "bigint" $ cType .OR. "bigserial" $ cType
            cType := "N"
            nSize := 19
            nDec  := 0

         CASE "decimal" $ cType .OR. "numeric" $ cType
            cType := "N"
            nDec  := Val( nDec )

            nSize := Val( nSize ) + iif( nDec > 0, 1, 0 )

            IF nDec > 100
               nDec := 5
            ENDIF

            IF nSize > 100
               nSize := 15
            ENDIF

         CASE "real" $ cType .OR. "float4" $ cType
            cType := "N"
            nSize := 15
            nDec  :=  4

         CASE "double precision" $ cType .OR. "float8" $ cType
            cType := "N"
            nSize := 19
            nDec  := 9

         CASE "money" $ cType
            cType := "N"
            nSize := 9
            nDec  := 2

         CASE "timestamp" $ cType
            cType := "C"
            nSize := 20
            nDec  := 0

         CASE "date" $ cType
            cType := "D"
            nSize := 8
            nDec  := 0

         CASE "time" $ cType
            cType := "C"
            nSize := 10
            nDec  := 0

         CASE "name" $ cType
            cType := "C"
            nSize := 64
            nDec  := 0

         CASE "oid" $ cType
            cType := "N"
            nSize := 19
            nDec  := 0

         OTHERWISE

            cType := "U"
            nSize := 0
            nDec  := -1

         ENDCASE

         IF ! cType == "U"
            AAdd( result, { cField, cType, nSize, nDec } )
         ENDIF
      NEXT
   ENDIF

   RETURN result

METHOD CreateTable( cTable, aStruct ) CLASS TPQserver

   LOCAL res
   LOCAL fld


[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 extra library: extras/httpsrv/modules/cookie.prg. Provides functions: HRBMAIN. This file implements server functionality

[Assistant]
MEMVAR _REQUEST

FUNCTION HRBMAIN()

   LOCAL cHtml := ""
   LOCAL cCookie := uhttpd_GetField( "mycookie" )
   LOCAL cAction := uhttpd_GetField( "action" )
   LOCAL oCookie

   hb_default( @cCookie, "" )
   hb_default( @cAction, "" )

#pragma __cstream | cHtml += %s
<!DOCTYPE html PUBLIC "-
<html xmlns="http:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Harbour uHTTPD Server cookie example</title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />

Simple uHTTPD server cookie example

<form name=test action="/cgi-bin/cookie.hrb" method="post">
    Type something: <input type="text" name="mycookie" value="<%COOKIE_VALUE%>">
    <input type="submit">
    <input type="hidden" name="action" value="gotoinfo">
</form>
Pressing button you will redirect to /info page. Look at COOKIE values.

You will see a "mycookie" variable name.

Return to Main Page

#pragma __endtext

   IF Empty( cAction )

      oCookie := uhttpd_CookieNew( "localhost", "/", 1, 0 )

      oCookie:DeleteCookie( "mycookie" )

      cHtml := StrTran( cHtml, "<%COOKIE_VALUE%>", cCookie )
   ELSEIF cAction == "gotoinfo"

      oCookie := uhttpd_CookieNew( "localhost", "/", 1, 0 )
      oCookie:SetCookie( "mycookie", cCookie )
      uhttpd_SetHeader( "Location", "/info" )

      RETURN NIL
   ENDIF

   RETURN cHtml


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

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

Harbour test program: tests/round.prg. Contains procedures: Main. This test file tests specific function APIs

[Assistant]
PROCEDURE Main()

   LOCAL n, value := -5

   FOR n := 1 TO 100
      ? ;
         value, ;
         Round( value, 3 ),;
         Round( value, 2 ),;
         Round( value, 1 ),;
         Round( value, 0 )
      value += 0.001
   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] Implement this Harbour module: Header file for contribution module 'hbxpp' (xBase++ compatibility functions): contrib/hbxpp/hbxpp.ch. Defines constants: B_THIN, B_FAT, HB_B_THIN_UNI, HB_B_FAT_UNI. Declares 2 preprocessor commands. Declares 5 preprocessor translations. Defines Harbour internal constants and macros

[Assistant]
#ifdef __XPP__

#else
#ifdef __HARBOUR__

#include "hbclass.ch"

#if ! defined( XPP_OP_OVERLOAD_OFF )
   #pragma -ks+
   REQUEST xpp_op_Overload
#endif

#xtranslate IsPrinter( [<x>] )     => hb_IsPrinter( <x> )
#xtranslate DispOutAt( <x,...> )   => hb_DispOutAt( <x> )
#xtranslate AAdd( <a>, <v>, <p> )  => hb_AIns( <a>, <v>, <p>, .T. )

#xtranslate TBColumn()             => xpp_TBColumn()
#xtranslate TBrowse()              => xpp_TBrowse()
#xtranslate Get()                  => xpp_Get()

#define B_THIN          ( Chr( 219 ) + Chr( 223 ) + Chr( 219 ) + Chr( 219 ) + ;
                          Chr( 219 ) + Chr( 220 ) + Chr( 219 ) + Chr( 219 ) )

#define B_FAT           ( Chr( 219 ) + Chr( 219 ) + Chr( 219 ) + Chr( 219 ) + ;
                          Chr( 219 ) + Chr( 219 ) + Chr( 219 ) + Chr( 219 ) )

#define HB_B_THIN_UNI   hb_UTF8ToStrBox( "█▀███▄██" )
#define HB_B_FAT_UNI    hb_UTF8ToStrBox( "████████" )

#xcommand TEXT INTO <v> [<wrp:WRAP>] [<trm:TRIMMED>] => ;
            #pragma __text | <v> += iif( <.trm.>, LTrim( %s ), %s ) +;
                                    iif( <.wrp.>, hb_eol(), "" ); <v> := ""
#xcommand TEXT INTO <v> WRAP [<EOL>] [<trm:TRIMMED>] => ;
            #pragma __text | <v> += iif( <.trm.>, LTrim( %s ), %s ) +;
                                    iif( <.EOL.>, <EOL>, hb_eol() ); <v> := ""

#endif
#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: TODBCField, TODBC. Harbour contribution module 'hbodbc' (ODBC database connectivity): contrib/hbodbc/todbc.prg. Defines classes: TODBCField, TODBC. This file handles database operations

[Assistant]
#include "hbclass.ch"
#include "sql.ch"

CREATE CLASS TODBCField

   VAR FieldID      INIT -1
   VAR FieldName    INIT ""
   VAR DataType     INIT -1
   VAR DataSize     INIT -1
   VAR DataDecs     INIT -1
   VAR AllowNull    INIT .F.
   VAR Value        INIT NIL

   METHOD New()

ENDCLASS

METHOD New() CLASS TODBCField
   RETURN Self

CREATE CLASS TODBC

   VAR hEnv
   VAR hDbc
   VAR hStmt
   VAR cODBCStr
   VAR cODBCRes
   VAR cSQL
   VAR Active       INIT .F.
   VAR Fields       INIT {}
   VAR nEof         INIT 0
   VAR lBof         INIT .F.
   VAR nRetCode
   VAR nRecCount    INIT 0
   VAR nRecNo       INIT 0
   VAR lCacheRS
   VAR aRecordSet   INIT {}

   VAR lAutoCommit AS LOGICAL INIT .T.

   METHOD New( cODBCStr, cUserName, cPassword, lCache )
   METHOD Destroy()

   METHOD SetSQL( cSQL )
   METHOD Open()
   METHOD ExecSQL()
   METHOD Close()

   METHOD LoadData( nPos )
   METHOD ClearData() INLINE AEval( ::Fields, {| oField | oField:Value := NIL } )
   METHOD FieldByName( cField )

   METHOD Fetch( nFetchType, nOffSet )

   METHOD Next()
   METHOD Prior()
   METHOD First()
   METHOD Last()
   METHOD MoveBy( nSteps )
   METHOD GoTo( nRecNo )
   METHOD Skip()
   METHOD Eof()
   METHOD Bof()
   METHOD RecNo()
   METHOD RecCount()
   METHOD LastRec()

   METHOD SQLErrorMessage()

   METHOD SetCnnOptions( nType, uBuffer )
   METHOD GetCnnOptions( nType )
   METHOD Commit()
   METHOD RollBack()
   METHOD SetStmtOptions( nType, uBuffer )
   METHOD GetStmtOptions( nType )
   METHOD SetAutoCommit( lEnable )

ENDCLASS

METHOD SQLErrorMessage() CLASS TODBC

   LOCAL cErrorClass, nType, cErrorMsg

   SQLError( ::hEnv, ::hDbc, ::hStmt, @cErrorClass, @nType, @cErrorMsg )

   RETURN "Error " + cErrorClass + " - " + cErrorMsg

METHOD New( cODBCStr, cUserName, cPassword, lCache ) CLASS TODBC

   LOCAL nRet

   hb_default( @lCache, .T. )

   ::cODBCStr := cODBCStr
   ::lCacheRS := lCache

   IF ( nRet := SQLAllocEnv( @::hEnv ) ) != SQL_SUCCESS
      ::nRetCode := nRet
      RETURN NIL
   ENDIF

   SQLAllocConnect( ::hEnv, @::hDbc )

   IF HB_ISSTRING( cUserName )

      hb_default( @cPassword, "" )

      IF ! ( ( nRet := SQLConnect( ::hDbc, cODBCStr, cUserName, cPassword ) ) == SQL_SUCCESS .OR. nRet == SQL_SUCCESS_WITH_INFO )

      ENDIF
   ELSE
      SQLDriverConnect( ::hDbc, ::cODBCStr, @::cODBCRes )
   ENDIF

   RETURN Self

METHOD SetAutoCommit( lEnable ) CLASS TODBC

   LOCAL lOld := ::lAutoCommit

   hb_default( @lEnable, .T. )

   IF lEnable != lOld
      ::SetCnnOptions( SQL_AUTOCOMMIT, iif( lEnable, SQL_AUTOCOMMIT_ON, SQL_AUTOCOMMIT_OFF ) )
      ::lAutoCommit := lEnable
   ENDIF

   RETURN lOld

METHOD Destroy() CLASS TODBC

   SQLDisconnect( ::hDbc )

   ::hDbc := NIL
   ::hEnv := NIL

   RETURN NIL

METHOD GetCnnOptions( nType ) CLASS TODBC

   LOCAL cBuffer := Space( 256 )

   ::nRetCode := SQLGetConnectAttr( ::hDbc, nType, @cBuffer )

   RETURN cBuffer

METHOD SetCnnOptions( nType, uBuffer ) CLASS TODBC

   RETURN ::nRetCode := SQLSetConnectAttr( ::hDbc, nType, uBuffer )

METHOD Commit() CLASS TODBC

   RETURN ::nRetCode := SQLCommit( ::hEnv, ::hDbc )

METHOD RollBack() CLASS TODBC

   RETURN ::nRetCode := SQLRollback( ::hEnv, ::hDbc )

METHOD GetStmtOptions( nType ) CLASS TODBC

   LOCAL cBuffer := Space( 256 )

   ::nRetCode := SQLGetStmtAttr( ::hStmt, nType, @cBuffer )

   RETURN cBuffer

METHOD SetStmtOptions( nType, uBuffer ) CLASS TODBC

   RETURN ::nRetCode := SQLSetStmtAttr( ::hStmt, nType, uBuffer )

METHOD SetSQL( cSQL ) CLASS TODBC

   IF ::Active
      ::Close()
   ENDIF

   ::cSQL := cSQL

   RETURN NIL

METHOD Open() CLASS TODBC

   LOCAL nRet
   LOCAL nCols
   LOCAL nRows
   LOCAL i
   LOCAL cColName
   LOCAL nNameLen
   LOCAL nDataType
   LOCAL nColSize
   LOCAL nDecimals
   LOCAL nNul
   LOCAL nResult
   LOCAL aCurRow
   LOCAL oField

   DO WHILE .T.

      IF ::Active

         nRet := -1
         EXIT
      ENDIF

      IF Empty( ::cSQL )

         nRet := -1
         EXIT
      ENDIF

      SQLAllocStmt( ::hDbc, @::hStmt )
      IF ( nRet := SQLExecDirect( ::hStmt, ::cSQL ) ) != SQL_SUCCESS
         EXIT
      ENDIF

      SQLNumResultCols( ::hStmt, @nCols )

      nResult := SQLRowCount( ::hStmt, @nRows )
      IF nResult  == SQL_SUCCESS
         ::nRecCount := nRows
      ENDIF

      ::Fields := Array( nCols )

      FOR i := 1 TO nCols

         SQLDescribeCol( ::hStmt, i, @cColName, 255, @nNameLen, @nDataType, ;
            @nColSize, @nDecimals, @nNul )

         ::Fields[ i ] := oField := TODBCField():New()
         oField:FieldID   := i
         oField:FieldName := cColName
         oField:DataSize  := nColsize
         oField:DataType  := nDataType
         oField:DataDecs  := nDecimals
         oField:AllowNull := ( nNul != 0 )

      NEXT

      IF ::lCacheRS
         ::aRecordSet := {}
         DO WHILE ::Fetch( SQL_FETCH_NEXT, 1 ) == SQL_SUCCESS

            aCurRow := Array( nCols )
            FOR i := 1 TO nCols
               aCurRow[ i ] := ::Fields[ i ]:value
            NEXT
            AAdd( ::aRecordSet, aCurRow )
         ENDDO

         ::nRecCount := Len( ::aRecordSet )
      ELSE
         IF ::First() == SQL_SUCCESS
            ::nRecCount := 1
         ELSE
            ::nRecCount := 0
         ENDIF
      ENDIF

      ::nRecNo := 1
      ::Active := .T.

      EXIT

   ENDDO

   RETURN nRet == SQL_SUCCESS

METHOD ExecSQL() CLASS TODBC

   LOCAL nRet

   IF Empty( ::cSQL )
      nRet := SQL_ERROR
   ELSE

      SQLAllocStmt( ::hDbc, @::hStmt )
      nRet := SQLExecDirect( ::hStmt, ::cSQL )

      ::Close()
   ENDIF

   RETURN nRet

METHOD Close() CLASS TODBC

   ::hStmt := NIL
   ::Active := .F.

   IF ::lCacheRS
      ::aRecordSet := {}
   ENDIF
   ::nRecCount := 0
   ::nRecNo    := 0
   ::lBof      := .T.

   RETURN NIL

METHOD FieldByName( cField ) CLASS TODBC

   LOCAL nRet
   LOCAL xRet := NIL

   IF HB_ISSTRING( cField )
      nRet := AScan( ::Fields, {| x | Upper( x:FieldName ) == Upper( cField ) } )

      IF nRet != 0
         xRet := ::Fields[ nRet ]
      ELSE

      ENDIF
   ENDIF

   RETURN xRet

METHOD Fetch( nFetchType, nOffset ) CLASS TODBC

   LOCAL nResult
   LOCAL nPos := NIL

   ::ClearData()

   IF ::lCacheRS .AND. ::Active

      SWITCH nFetchType
      CASE SQL_FETCH_NEXT

         IF ::nRecNo == ::nRecCount
            nResult := SQL_NO_DATA_FOUND
         ELSE
            nResult := SQL_SUCCESS
            nPos := ::nRecNo + 1
         ENDIF
         EXIT

      CASE SQL_FETCH_PRIOR
         IF ::nRecNo == 1
            nResult := SQL_NO_DATA_FOUND
         ELSE
            nResult := SQL_SUCCESS
            nPos := ::nRecNo - 1
         ENDIF
         EXIT

      CASE SQL_FETCH_FIRST
         nResult := SQL_SUCCESS
         nPos := 1
         EXIT

      CASE SQL_FETCH_LAST
         nResult := SQL_SUCCESS
         nPos := ::nRecCount
         EXIT

      CASE SQL_FETCH_RELATIVE
         IF ( ::nRecNo + nOffset ) > ::nRecCount .OR. ( ::nRecNo + nOffset ) < 1
            nResult := SQL_ERROR
         ELSE
            nResult := SQL_SUCCESS
            nPos := ::nRecNo + nOffset
         ENDIF
         EXIT

      CASE SQL_FETCH_ABSOLUTE
         IF nOffset > ::nRecCount .OR. nOffset < 1
            nResult := SQL_ERROR
         ELSE
            nResult := SQL_SUCCESS
            nPos := nOffset
         ENDIF
         EXIT

      OTHERWISE
         nResult := SQL_ERROR
      ENDSWITCH

   ELSE
      nResult := SQLFetchScroll( ::hStmt, nFetchType, nOffSet )
   ENDIF

   IF nResult == SQL_SUCCESS .OR. nResult == SQL_SUCCESS_WITH_INFO
      nResult := SQL_SUCCESS

      ::LoadData( nPos )
      ::lBof := .F.
   ELSE

   ENDIF

   RETURN nResult

METHOD Next() CLASS TODBC


[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 test program: tests/mouse.prg. Provides functions: MUPDATE, MINRECT. Contains 4 procedures. This test file tests specific function APIs

[Assistant]
#include "inkey.ch"

PROCEDURE Main()

   LOCAL nR := 5, nC := 38

   SET CURSOR OFF
   CLS
   IF ! MPresent()
      ? " No mouse present !"
      QUIT
   ENDIF

   @ 0, 0 TO MaxRow(), MaxCol() DOUBLE
   @ MaxRow() - 2,  0 TO MaxRow(), 18 DOUBLE
   @ MaxRow() - 1,  2 SAY "Y:"
   @ MaxRow() - 1, 10 SAY "X:"

   @ nR,  2 SAY "Mouse Type    :"

   @ nR, 18 SAY "Mouse System"

   @ MaxRow() - 2, 68 TO MaxRow(), MaxCol() DOUBLE
   @ MaxRow() - 1, 70 SAY "Exit"

   @ 10,  2 SAY " -- Checkings --"
   @ 11,  2 SAY "Window Boundaries :"
   @ 12,  2 SAY "Press/Release But.:"
   @ 13,  2 SAY "Double Click Left :"
   @ 14,  2 SAY "Double Click Right:"

   TEST1()

   TEST2( nR, nC )

   SetPos( MaxRow(), 0 )

   SET CURSOR ON
   ?

   RETURN

STATIC FUNCTION MUPDATE()

   @ MaxRow() - 1,  4 SAY MRow() PICTURE "9999"
   @ MaxRow() - 1, 12 SAY MCol() PICTURE "9999"

   RETURN 0

STATIC FUNCTION MINRECT( nTop, nLeft, nBott, nRight )

   LOCAL lInside := .F.

   IF MRow() >= nTop .AND. MRow() <= nBott
      IF MCol() >= nLeft .AND. MCol() <= nRight
         lInside := .T.
      ENDIF
   ENDIF

   RETURN lInside

STATIC PROCEDURE TEST1()

   LOCAL nKey

   @ MaxRow() - 3, 25 SAY "Move the cursor until the UPPER side "
   MUPDATE()

   DO WHILE ( nKey := Inkey( 0, INKEY_ALL ) ) != K_TAB
      MUPDATE()
      IF nKey == K_MOUSEMOVE
         IF MRow() < 1
            EXIT
         ENDIF
         CHECKEXIT()
      ENDIF
   ENDDO

   @ MaxRow() - 3, 25 SAY "Move the cursor until the BOTTOM side  "

   DO WHILE ( nKey := Inkey( 0, INKEY_ALL ) ) != K_TAB
      MUPDATE()
      IF nKey == K_MOUSEMOVE
         IF MRow() > MaxRow() - 1
            EXIT
         ENDIF
         CHECKEXIT()
      ENDIF
   ENDDO

   @ MaxRow() - 3, 25 SAY "Move the cursor until the LEFT side  "

   DO WHILE ( nKey := Inkey( 0, INKEY_ALL ) ) != K_TAB
      MUPDATE()
      IF nKey == K_MOUSEMOVE
         IF MCol() < 1
            EXIT
         ENDIF
         CHECKEXIT()
      ENDIF
   ENDDO

   @ MaxRow() - 3, 25 SAY "Move the cursor until the RIGHT side "

   DO WHILE ( nKey := Inkey( 0, INKEY_ALL ) ) != K_TAB
      MUPDATE()
      IF nKey == K_MOUSEMOVE
         IF MCol() > MaxCol() - 1
            EXIT
         ENDIF
         CHECKEXIT()
      ENDIF
   ENDDO

   @ MaxRow() - 3, 20 SAY Space( 50 )
   @ 11, 22 SAY "Pass"

   RETURN

STATIC PROCEDURE TEST2( nR, nC )

   LOCAL cSkip := "", nKey, nPress := 0

   @ nR +  0, nC SAY "+---------|---------+"
   @ nR +  1, nC SAY "| +===+ +===+ +===+ |"
   @ nR +  2, nC SAY "| |   | |   | |   | |"
   @ nR +  3, nC SAY "| |   | |   | |   | |"
   @ nR +  4, nC SAY "| +===+ +===+ +===+ |"
   @ nR +  5, nC SAY "|                   |"
   @ nR +  6, nC SAY "|  Up    Up    Up   |"
   @ nR +  7, nC SAY "|                   |"
   @ nR +  8, nC SAY "|                   |"
   @ nR +  9, nC SAY "|           Harbour |"
   @ nR + 10, nC SAY "|            mouse  |"
   @ nR + 11, nC SAY "+-------------------+"

   Set( _SET_EVENTMASK, INKEY_ALL )

   IF ! Empty( cSkip )
      IF Upper( cSkip ) == "BREAK"
         SetCancel( .T. )
      ELSE
         SetCancel( .F. )
      ENDIF
   ENDIF

   MUPDATE()

   WHILE ( nKey := Inkey( 0, INKEY_ALL ) ) != K_TAB

      DO CASE
      CASE nKey == K_MOUSEMOVE

         IF MINRECT( 19, 40, 22, 60 )
            MHide()
         ELSE
            MShow()
         ENDIF
         CHECKEXIT()
         MUPDATE()

      CASE nKey == K_LBUTTONDOWN

         @ nR + 2, nC + 3 SAY "XXX"
         @ nR + 3, nC + 3 SAY "XXX"
         @ nR + 6, nC + 3 SAY "Down"
         nPress ++

      CASE nKey == K_LBUTTONUP

         @ nR + 2, nC + 3 SAY "   "
         @ nR + 3, nC + 3 SAY "   "
         @ nR + 6, nC + 3 SAY "Up  "

      CASE nKey == K_MBUTTONDOWN

         @ nR + 2, nC + 10 SAY "XXX"
         @ nR + 3, nC + 10 SAY "XXX"
         @ nR + 6, nC + 10 SAY "Down"
         nPress ++

      CASE nKey == K_MBUTTONUP

         @ nR + 6, nC + 10 SAY "Up  "

      CASE nKey == K_RBUTTONDOWN

         @ nR + 2, nC + 15 SAY "XXX"
         @ nR + 3, nC + 15 SAY "XXX"
         @ nR + 6, nC + 15 SAY "Down"
         nPress ++

      CASE nKey == K_RBUTTONUP

         @ nR + 2, nC + 15 SAY "   "
         @ nR + 3, nC + 15 SAY "   "
         @ nR + 6, nC + 15 SAY "Up  "

      CASE nKey == K_LDBLCLK

         @ 13, 22 SAY "Pass"

      CASE nKey == K_RDBLCLK

         @ 14, 22 SAY "Pass"

      OTHERWISE
         @ MaxRow(), 20 SAY "A keyboard key was pressed:"
         @ MaxRow(), 48 SAY nKey
#ifdef __HARBOUR__
         @ MaxRow(), 58 SAY hb_keyChar( nKey )
#else
         @ MaxRow(), 58 SAY iif( nKey >= 32 .AND. nKey <= 255, Chr( nKey ), "" )
#endif
      ENDCASE

      IF nPress > 6
         EXIT
      ENDIF

   ENDDO

   @ MaxRow() - 3, 20 SAY Space( 50 )
   @ 12, 22 SAY "Pass"

   SET CURSOR ON

   @ 20, 1 SAY "MOUSE TEST FINISH!"
   ?

   RETURN

STATIC PROCEDURE CHECKEXIT()

   IF ! MINRECT( MaxRow() - 2, MaxCol() - 11, MaxRow(), MaxCol() )
      RETURN
   ENDIF
   SET CURSOR ON
   CLS
   ? "MOUSE TEST FINISH!"
   ?
   QUIT


[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 header file: include/blob.ch. Defines constants: HB_BLOB_CH_. Declares 5 preprocessor translations. Defines Harbour internal constants and macros

[Assistant]
#ifndef HB_BLOB_CH_
#define HB_BLOB_CH_

#ifndef HB_DBINFO_CH_
   #include "dbinfo.ch"
#endif

#xtranslate BLOBRootLock()          => dbInfo( DBI_BLOB_ROOT_LOCK )
#xtranslate BLOBRootUnlock()        => dbInfo( DBI_BLOB_ROOT_UNLOCK )
#xtranslate BLOBRootGet()           => dbInfo( DBI_BLOB_ROOT_GET )
#xtranslate BLOBRootPut( <xBlob> )  => dbInfo( DBI_BLOB_ROOT_PUT, <xBlob> )
#xtranslate BLOBRootDelete()        => BLOBRootPut( "" )

#xtranslate BLOBDirectExport( <nPointer>, <cTargetFile> [, <kMode>] )   => ;
            dbInfo( DBI_BLOB_DIRECT_EXPORT, { <nPointer>, <cTargetFile>, ;
                    iif( <.kMode.>, <kMode>, BLOB_EXPORT_OVERWRITE ) } )
#xtranslate BLOBDirectGet( <nPointer> [, <nStart> [, <nCount> ]] )      => ;
            dbInfo( DBI_BLOB_DIRECT_GET, { <nPointer>, <nStart>, <nCount> } )
#xtranslate BLOBDirectImport( <nOldPointer>, <cSourceFile> )            => ;
            dbInfo( DBI_BLOB_DIRECT_IMPORT, { <nOldPointer>, <cSourceFile> } )
#xtranslate BLOBDirectPut( [<nOldPointer>], <xBlob> )                   => ;
            dbInfo( DBI_BLOB_DIRECT_PUT, { <nOldPointer>, <xBlob> } )
#xtranslate BLOBGet( <nFieldNo> [, <nStart> [, <nCount>]] )             => ;
            dbFieldInfo( DBS_BLOB_GET, <nFieldNo>, { <nStart>, <nCount> } )
#xtranslate BLOBExport( <nFieldNo>, <cTargetFile>, <nMode> )            => ;
            dbFileGet( <nFieldNo>, <cTargetFile>, <nMode> )
#xtranslate BLOBImport( <nFieldNo>, <cSourceFile> )                     => ;
            dbFilePut( <nFieldNo>, <cSourceFile> )

#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]
Here is a Harbour (xBase/Clipper) implementation:

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

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

PROCEDURE Main()

   ctinit()

   ? "Begin test of ValPos()"
   ?

   ? '  ValPos( "1234x56789" ) == 9     ? --> ' + Str( ValPos( "1234x56789" ) )
   ? '  ValPos( "1234x56789", 1 ) == 1  ? --> ' + Str( ValPos( "1234x56789", 1 ) )
   ? '  ValPos( "1234x56789", 11 ) == 0 ? --> ' + Str( ValPos( "1234x56789", 11 ) )
   ? '  ValPos( "1234x56789", 5 ) == 0  ? --> ' + Str( ValPos( "1234x56789", 5 ) )

   ?
   ? "End test of ValPos()"
   ?

   ctexit()

   RETURN


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

[User] Write a Harbour program with procedures: Main. Harbour contribution module 'hbhttpd' (Multithreaded HTTP/HTTPS server framework): contrib/hbhttpd/tests/eshop.prg. Provides 6 functions including: proc_login, proc_logout, proc_main, proc_shopping, proc_cart. Contains procedures: Main. This file provides network protocol implementations

[Assistant]
#require "hbssl"
#require "hbhttpd"

REQUEST __HBEXTERN__HBSSL__

REQUEST DBFCDX

MEMVAR server, get, post, cookie, session

PROCEDURE Main()

   LOCAL oServer

   LOCAL oLogAccess
   LOCAL oLogError

   LOCAL nPort

   IF hb_argCheck( "help" )
      ? "Usage: app [options]"
      ? "Options:"
      ? "
      ? "
      RETURN
   ENDIF

   IF hb_argCheck( "stop" )
      hb_MemoWrit( ".uhttpd.stop", "" )
      RETURN
   ELSE
      FErase( ".uhttpd.stop" )
   ENDIF

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

   rddSetDefault( "DBFCDX" )

   IF ! hb_dbExists( "users.dbf" )
      hb_dbDrop( "users.cdx" )
      dbCreate( "users", { { "USER", "C", 16, 0 }, { "PASSWORD", "C", 16, 0 }, { "NAME", "C", 50, 0 } }, , .T., "user" )
      dbAppend()
      FIELD->USER := "demo"
      FIELD->PASSWORD := "demo"
      FIELD->NAME := "Demo"
      ordCreate( "users", "user", "USER" )
      dbCloseArea()
   ELSEIF ! hb_dbExists( "users.cdx" )
      dbUseArea( .T., , "users", , .F., .F. )
      ordCreate( "users", "user", "USER" )
      dbCloseArea()
   ENDIF

   IF ! hb_dbExists( "carts.dbf" )
      hb_dbDrop( "carts.cdx" )
      dbCreate( "carts", { { "USER", "C", 16, 0 }, { "CODE", "C", 16, 0 }, { "AMOUNT", "N", 6, 0 }, { "TOTAL", "N", 9, 2 } }, , .T., "cart" )
      ordCreate( "carts", "user", "USER+CODE" )
      dbCloseArea()
   ELSEIF ! hb_dbExists( "carts.cdx" )
      dbUseArea( .T., , "carts", , .F., .F. )
      ordCreate( "carts", "user", "USER+CODE" )
      dbCloseArea()
   ENDIF

   IF ! hb_dbExists( "items.dbf" )
      hb_dbDrop( "items.cdx" )
      dbCreate( "items", { { "CODE", "C", 16, 0 }, { "TITLE", "C", 80, 0 }, { "PRICE", "N", 9, 2 } }, , .T., "items" )
      ordCreate( "items", "code", "CODE" )
      dbCloseArea()
   ELSEIF ! hb_dbExists( "item.cdx" )
      dbUseArea( .T., , "items", , .F., .F. )
      ordCreate( "items", "code", "CODE" )
      dbCloseArea()
   ENDIF

   oLogAccess := UHttpdLog():New( "eshop_access.log" )

   IF ! oLogAccess:Add( "" )
      oLogAccess:Close()
      ? "Access log file open error " + hb_ntos( FError() )
      RETURN
   ENDIF

   oLogError := UHttpdLog():New( "eshop_error.log" )

   IF ! oLogError:Add( "" )
      oLogError:Close()
      oLogAccess:Close()
      ? "Error log file open error " + hb_ntos( FError() )
      RETURN
   ENDIF

   ? "Listening on port:", nPort := 8002

   oServer := UHttpdNew()

   IF ! oServer:Run( { ;
         "FirewallFilter"      => "", ;
         "LogAccess"           => {| m | oLogAccess:Add( m + hb_eol() ) }, ;
         "LogError"            => {| m | oLogError:Add( m + hb_eol() ) }, ;
         "Trace"               => {| ... | QOut( ... ) }, ;
         "Port"                => nPort, ;
         "Idle"                => {| o | iif( hb_FileExists( ".uhttpd.stop" ), ( FErase( ".uhttpd.stop" ), o:Stop() ), NIL ) }, ;
         "PrivateKeyFilename"  => "private.key", ;
         "CertificateFilename" => "certificate.crt", ;
         "SSL"                 => .T., ;
         "Mount"          => { ;
         "/hello"            => {|| UWrite( "Hello!" ) }, ;
         "/info"             => {|| UProcInfo() }, ;
         "/files/*"          => {| x | QOut( hb_DirBase() + "/files/" + X ), UProcFiles( hb_DirBase() + "/files/" + X, .F. ) }, ;
         "/app/login"        => @proc_login(), ;
         "/app/logout"       => @proc_logout(), ;
         "/app/account"      => @proc_account(), ;
         "/app/account/edit" => @proc_account_edit(), ;
         "/app/register"     => @proc_register(), ;
         "/app/main"         => @proc_main(), ;
         "/app/shopping"     => @proc_shopping(), ;
         "/app/cart"         => @proc_cart(), ;
         "/"                 => {|| URedirect( "/app/login" ) } } } )
      oLogError:Close()
      oLogAccess:Close()
      ? "Server error:", oServer:cError
      ErrorLevel( 1 )
      RETURN
   ENDIF

   oLogError:Close()
   oLogAccess:Close()

   RETURN

STATIC FUNCTION proc_login()

   LOCAL cUser

   IF server[ "REQUEST_METHOD" ] == "POST"
      dbUseArea( .T., , "users", "users", .T., .T. )
      ordSetFocus( "user" )
      cUser := PadR( hb_HGetDef( post, "user", "" ), 16 )
      USessionStart()
      IF ! Empty( cUser ) .AND. dbSeek( cUser, .F. ) .AND. ! Deleted() .AND. ;
            PadR( hb_HGetDef( post, "password", "" ), 16 ) == FIELD->PASSWORD
         session[ "user" ] := cUser
         URedirect( "main" )
      ELSE
         URedirect( "login?err" )
         USessionDestroy()
      ENDIF
      dbCloseArea()
   ELSE
      IF hb_HHasKey( get, "err" )
         RETURN { "errtext" => "Invalid user name or password!" }
      ENDIF
      RETURN { => }
   ENDIF

   RETURN NIL

STATIC FUNCTION proc_logout()

   USessionStart()
   USessionDestroy()

   RETURN { => }

STATIC FUNCTION proc_main()

   USessionStart()
   IF ! hb_HHasKey( session, "user" )
      URedirect( "/app/login" )
      RETURN NIL
   ENDIF

   RETURN { => }

STATIC FUNCTION proc_shopping()

   LOCAL oW, nT, cCode

   USessionStart()
   IF ! hb_HHasKey( session, "user" )
      URedirect( "/app/login" )
      RETURN NIL
   ENDIF

   dbUseArea( .T., , "carts", "carts", .T., .F. )
   ordSetFocus( "user" )
   dbUseArea( .T., , "items", "items", .T., .T. )
   ordSetFocus( "code" )

   IF hb_HHasKey( get, "add" )
      cCode := PadR( get[ "add" ], 16 )
      IF items->( dbSeek( cCode ) ) .AND. carts->( FLock() )
         IF ! carts->( dbSeek( session[ "user" ] + cCode ) )
            carts->( dbAppend() )
            carts->USER := session[ "user" ]
            carts->CODE := cCode
         ENDIF
         carts->AMOUNT += 1
         carts->TOTAL += items->PRICE
         carts->( dbUnlock() )
      ENDIF
      URedirect( "shopping" )
      RETURN NIL
   ENDIF

   dbSelectArea( "carts" )
   ordScope( 0, session[ "user" ] )
   ordScope( 1, session[ "user" ] )
   nT := 0
   carts->( dbEval( {|| nT += FIELD->TOTAL } ) )
   dbSelectArea( "items" )
   oW := UWBrowseNew( "br_item" )
   oW:AddColumn( 101, "Item No.",    "CODE" )
   oW:AddColumn( 102, "Title",       "TITLE" )
   oW:AddColumn( 103, "Price",       "PRICE" )
   oW:AddColumn( 104, "",            {|| ULink( "Add to cart", "?add=" + RTrim( FIELD->CODE ) ) }, .T. )
   oW:nPageSize := 10
   IF hb_HHasKey( get, "_pos" )
      oW:nPos := Val( get[ "_pos" ] )
   ENDIF

   RETURN { "browse" => oW:Output(), "cartsum" => nT }

STATIC FUNCTION proc_cart()

   LOCAL oW, nT, cCode

   USessionStart()
   IF ! hb_HHasKey( session, "user" )
      URedirect( "/app/login" )
      RETURN NIL
   ENDIF

   dbUseArea( .T., , "items", "items", .T., .T. )
   ordSetFocus( "code" )
   dbUseArea( .T., , "carts", "carts", .T., .F. )
   ordSetFocus( "user" )

   IF hb_HHasKey( get, "del" )
      cCode := PadR( get[ "del" ], 16 )
      IF items->( dbSeek( cCode ) ) .AND. carts->( FLock() )
         IF carts->( dbSeek( session[ "user" ] + cCode ) )
            carts->( dbDelete() )
            carts->USER := ""
            carts->CODE := cCode
         ENDIF
         carts->( dbUnlock() )
      ENDIF
      URedirect( "cart" )
      RETURN NIL
   ENDIF

   ordScope( 0, session[ "user" ] )
   ordScope( 1, session[ "user" ] )
   nT := 0
   carts->( dbEval( {|| nT += FIELD->TOTAL } ) )

   oW := UWBrowseNew( "br_cart" )
   oW:AddColumn( 101, "Item No.",    "CODE" )
   oW:AddColumn( 102, "Title",       {|| items->( dbSeek( carts->CODE, .F. ), FIELD->TITLE ) } )
   oW:AddColumn( 103, "Amount",      "AMOUNT" )
   oW:AddColumn( 104, "Total",       "TOTAL" )
   oW:AddColumn( 104, "",            {|| ULink( "Delete", "?del=" + RTrim( FIELD->CODE ) ) }, .T. )
   oW:nPageSize := 10
   IF hb_HHasKey( get, "_pos" )
      oW:nPos := Val( get[ "_pos" ] )
   ENDIF

   RETURN { "browse" => oW:Output(), "cartsum" => nT }

STATIC FUNCTION proc_account()

   USessionStart()
   IF ! hb_HHasKey( session, "user" )
      URedirect( "/app/login" )
      RETURN NIL
   ENDIF
   dbUseArea( .T., , "users", "users", .T., .F. )
   ordSetFocus( "user" )
   dbSeek( session[ "user" ], .F. )


[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 'hbct' (CA-Tools compatibility library): contrib/hbct/tests/charnlst.prg. Contains procedures: Main. This file provides legacy compatibility functions

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

PROCEDURE Main()

   ctinit()

   ? "Begin test of CharNoList()"
   ?

   ? "Simple tests:"

   ? '  CharNoList( CharNoList( "Hello World !" ) ) == " !HWdelor" ? -> "' + CharNoList( CharNoList( "Hello World !" ) ) + '"'
   ? '  CharNoList( CharNoList( NIL ) ) == "" ? -> "' + CharNoList( CharNoList( NIL ) ) + '"'

   ? "End test of CharNoList()"
   ?

   ctexit()

   RETURN


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

[User] Write Harbour functions: xBrowse1, DbSkipBlock, TBNext. Harbour contribution module 'gtwvw' (): contrib/gtwvw/tests/prog0.prg. Provides 11 functions including: xBrowse1, DbSkipBlock, TBNext, TBPrev, VouBlockField. Contains procedures: Main, xGet1. This file provides platform-specific functionality

[Assistant]
#require "gtwvw"

#include "inkey.ch"
#include "setcurs.ch"

STATIC s_zwin := {}
STATIC s_cStdColor := "N/W,N/GR*,,,N/W*"

PROCEDURE Main()

   LOCAL i, j

#if defined( __HBSCRIPT__HBSHELL ) .AND. defined( __PLATFORM__WINDOWS )
   hbshell_gtSelect( "GTWVW" )
#endif

   SET SCOREBOARD OFF
   SetColor( s_cStdColor )
   SetCursor( SC_NONE )
   CLS
   @ 0, 0 SAY PadC( "This is the Main Window", MaxCol() + 1 )

   DispBegin()
   FOR i := 1 TO MaxRow() - 1
      FOR j := 0 TO MaxCol()
         hb_DispOutAtBox( i, j, hb_UTF8ToStrBox( "▒" ) )
      NEXT
   NEXT
   DispEnd()

   lboxmessage( "Welcome to our test program." + hb_eol() + ;
      "This program will show typical GET and BROWSE dialogs " + ;
      "with brief help on the bottom of the screen." )
   xGet1()
   xBrowse1()
   lboxmessage( "That's all folks" )

   SetCursor( SC_NORMAL )

   RETURN

PROCEDURE xGet1()

   LOCAL cName := PadR( "Name", 20 )
   LOCAL cAddr := PadR( "Address", 25 )
   LOCAL cPhone := PadR( "Phone", 15 )
   LOCAL cFax  := PadR( "Fax", 15 )
   LOCAL lDone := .F.
   LOCAL getlist := {}
   LOCAL oldCurs := SetCursor( SC_NORMAL )

   znewwindow( hb_UTF8ToStrBox( "┌─┐│┘─└│" ), 10, 20, 22, 59, "Some Window" )

   DO WHILE ! lDone
      @ 12, 22 SAY "Name    : " GET cName  PICT "@!K" WHEN lMessage( "Please enter your name" )
      @ 14, 22 SAY "Address : " GET cAddr  PICT "@!K" WHEN lMessage( "Please enter your address" )
      @ 16, 22 SAY "Phone   : " GET cPhone PICT "@K"  WHEN lMessage( "Please enter your phone number" )
      @ 18, 22 SAY "Fax     : " GET cFax   PICT "@K"  WHEN lMessage( "Please enter your fax number" )
      READ

      lMessage( "" )
      lDone := lyesno( "Done?" )
   ENDDO

   zrevwindow()

   SetCursor( oldCurs )

   RETURN

FUNCTION xBrowse1()

   LOCAL nKey, bBlock, oBrowse, i
   LOCAL lEnd    := .F.
   LOCAL info_
   LOCAL nTop    :=  6
   LOCAL nLeft   :=  3
   LOCAL nBottom := MaxRow() - 2
   LOCAL nRight  := MaxCol() - 3
   LOCAL nCursor := SetCursor( SC_NONE )

   USE "..\..\..\tests\test" NEW
   IF NetErr()
      RETURN NIL
   ENDIF
   info_ := dbStruct()

   SetColor( "N/W*,N/GR*,,,N/W* " )
   oBrowse := TBrowseNew( nTop + 1, nLeft + 1, nBottom - 1, nRight - 1 )

   oBrowse:ColSep        := hb_UTF8ToStrBox( "│" )
   oBrowse:HeadSep       := hb_UTF8ToStrBox( "─" )
   oBrowse:GoTopBlock    := {|| dbGoTop() }
   oBrowse:GoBottomBlock := {|| dbGoBottom() }
   oBrowse:SkipBlock     := {| nSkip | dbSkipBlock( nSkip, oBrowse ) }

   FOR i := 1 TO Len( info_ )
      bBlock := VouBlockField( i )
      oBrowse:AddColumn( TBColumnNew( info_[ i, 1 ], bBlock ) )
   NEXT

   oBrowse:configure()

   znewwindow( hb_UTF8ToStrBox( "┌─┐│┘─└│" ), nTop, nLeft, nBottom, nRight, "test.dbf" )

   WHILE ! lEnd
      oBrowse:ForceStable()

      lMessage( "Record #" + hb_ntos( RecNo() ) )

      nKey := Inkey( 0 )

      DO CASE
      CASE nKey == K_ESC .OR. nKey == K_ENTER
         lEnd := lYesNo( "Done?" )
      CASE nKey == K_DOWN
         oBrowse:Down()
      CASE nKey == K_UP
         oBrowse:Up()
      CASE nKey == K_LEFT
         oBrowse:Left()
      CASE nKey == K_RIGHT
         oBrowse:Right()
      CASE nKey == K_PGDN
         oBrowse:pageDown()
      CASE nKey == K_PGUP
         oBrowse:pageUp()
      CASE nKey == K_CTRL_PGUP
         oBrowse:goTop()
      CASE nKey == K_CTRL_PGDN
         oBrowse:goBottom()
      CASE nKey == K_HOME
         oBrowse:home()
      CASE nKey == K_END
         oBrowse:end()
      CASE nKey == K_CTRL_LEFT
         oBrowse:panLeft()
      CASE nKey == K_CTRL_RIGHT
         oBrowse:panRight()
      CASE nKey == K_CTRL_HOME
         oBrowse:panHome()
      CASE nKey == K_CTRL_END
         oBrowse:panEnd()
      ENDCASE
   ENDDO

   lMessage( "" )

   zrevwindow()

   SetCursor( nCursor )

   dbCloseArea()

   RETURN NIL

STATIC FUNCTION DbSkipBlock( n, oTbr )

   LOCAL nSkipped := 0

   HB_SYMBOL_UNUSED( oTbr )

   IF n == 0
      dbSkip( 0 )
   ELSEIF n > 0
      DO WHILE nSkipped != n .AND. TBNext( oTbr )
         nSkipped++
      ENDDO
   ELSE
      DO WHILE nSkipped != n .AND. TBPrev( oTbr )
         nSkipped--
      ENDDO
   ENDIF

   RETURN  nSkipped

STATIC FUNCTION TBNext( oTbr )

   LOCAL nSaveRecNum := RecNo()
   LOCAL lMoved := .T.

   HB_SYMBOL_UNUSED( oTbr )

   IF Eof()
      lMoved := .F.
   ELSE
      dbSkip( 1 )
      IF Eof()
         lMoved := .F.
         dbGoto( nSaveRecNum )
      ENDIF
   ENDIF

   RETURN lMoved

STATIC FUNCTION TBPrev( oTbr )

   LOCAL nSaveRecNum := RecNo()
   LOCAL lMoved := .T.

   HB_SYMBOL_UNUSED( oTbr )

   dbSkip( -1 )
   IF Bof()
      dbGoto( nSaveRecNum )
      lMoved := .F.
   ENDIF

   RETURN lMoved

STATIC FUNCTION VouBlockField( i )

   RETURN  {|| FieldGet( i ) }

FUNCTION lMessage( cMsg )

   LOCAL cOldColor := SetColor( s_cStdColor )

   @ MaxRow(), 0 SAY PadC( cMsg, MaxCol() + 1 )
   SetColor( cOldColor )

   RETURN .T.

FUNCTION lYesNo( cMsg )

   LOCAL nTopLine, ;
      nLeft := 5, ;
      nBotLine := MaxRow() - 2, ;
      nRight := MaxCol() - 5
   LOCAL nChoice, nWidth
   LOCAL oldCurs := SetCursor( SC_NONE )
   LOCAL oldColor := SetColor( s_cStdColor )

   hb_default( @cMsg, "Please Confirm" )

   cmsg := " " + AllTrim( cmsg ) + " "
   nWidth := Max( Len( cmsg ), Len( "Yes" ) )
   nTopLine := nBotLine - 2 - 1

   nLeft := Max( nLeft, ( ( nRight + nLeft )
   znewwindow( hb_UTF8ToStrBox( "┌─┐│┘─└│" ), nTopLine, nLeft, nBotLine, nRight, cMsg )

   @ nTopLine + 1, nLeft + 1 PROMPT PadR( "Yes", nWidth )
   @ nTopLine + 2, nLeft + 1 PROMPT PadR( "No", nWidth )
   MENU TO nChoice

   zrevwindow()

   SetCursor( oldCurs )
   SetColor( oldColor )

   RETURN nChoice == 1

FUNCTION lBoxMessage( cMsg, cTitle )

   LOCAL nTopLine, ;
      nLeft := 5, ;
      nBotLine := MaxRow() - 2, ;
      nRight := MaxCol() - 5
   LOCAL nwidth, nmaxwidth, i, nNumLines, cAline
   LOCAL oldCurs := SetCursor( SC_NONE )
   LOCAL oldColor := SetColor( s_cStdColor )

   hb_default( @cTitle, "Info" )

   cmsg := AllTrim( cmsg )
   nNumLines := MLCount( cmsg, ( nright - nleft ) - 1 )
   nWidth := iif( nNumLines < 2, Len( cmsg ), nRight - nLeft - 1 )
   nTopLine := nBotLine - nNumLines - 1
   IF nTopLine < 0
      nNumLines += nTopLine
      nTopLine := 0
   ENDIF

   nMaxWidth := 0
   FOR i := 1 TO nNumLines
      nMaxWidth := Max( nMaxWidth, Len( RTrim( MemoLine( cmsg, nwidth, i ) ) ) )
   NEXT

   nLeft := Max( nLeft, Int( ( ( nRight + nLeft ) / 2 ) - ( nMaxWidth / 2 ) - 1 ) )
   nRight := nLeft + nMaxWidth + 1

   znewwindow( hb_UTF8ToStrBox( "┌─┐│┘─└│" ), nTopLine, nLeft, nBotLine, nRight, cTitle )
   DispBegin()
   FOR i := 1 TO nNumLines
      cAline := MemoLine( cMsg, nWidth, i )
      hb_DispOutAt( nTopLine + i, nLeft + 1, PadC( AllTrim( cAline ), nMaxWidth ) )
   NEXT
   DispEnd()

   Inkey( 0 )

   zrevwindow()

   SetCursor( oldCurs )
   SetColor( oldColor )

   RETURN .T.

FUNCTION ZNEWWINDOW( wtype, r1, c1, r2, c2, ctitle, ccolor )

   LOCAL i := Len( s_zwin )
   LOCAL cScreen := SaveScreen( r1, c1, r2, c2 )
   LOCAL cOldColor := SetColor()
   LOCAL nrow := Row(), ncol := Col()

   hb_default( @ctitle, "" )
   hb_default( @ccolor, s_cStdColor )
   SetColor( ccolor )

   AAdd( s_zwin, { i + 1, r1, c1, r2, c2, cScreen, ctitle, nrow, ncol, coldcolor } )

   SetColor( ccolor )

   hb_Scroll( r1, c1, r2, c2 )

   hb_DispBox( r1, c1, r2, c2, wtype )
   IF ! Empty( ctitle )
      cTitle := " " + AllTrim( ctitle ) + " "
      hb_DispOutAt( r1, nCeiling( ( c2 + c1 - Len( cTitle ) ) / 2 ), cTitle )
   ENDIF

   SetColor( cOldColor )

   RETURN i + 1

FUNCTION ZREVWINDOW()

   LOCAL i := Len( s_zwin )

   IF i == 0

      RETURN NIL
   ENDIF

   RestScreen( s_zwin[ i ][ 2 ], s_zwin[ i ][ 3 ], s_zwin[ i ][ 4 ], s_zwin[ i ][ 5 ], s_zwin[ i ][ 6 ] )
   SetPos( s_zwin[ i ][ 8 ], s_zwin[ i ][ 9 ] )
   SetColor( s_zwin[ i ][ 10 ] )

   hb_ADel( s_zwin, i, .T. )

   RETURN NIL

FUNCTION nCeiling( nNumber )

   LOCAL nTemp


[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/inline_c.prg. Provides functions: EndDumpTest. Contains procedures: Main. This test file tests specific function APIs

[Assistant]
PROCEDURE Main()

   ? C_FUNC()

   ? EndDumpTest()

   RETURN

#pragma begindump

#include "hbapi.h"

HB_FUNC( C_FUNC )
{
   hb_retc( "returned from C_FUNC()\n" );
}

#pragma enddump

FUNCTION EndDumpTest()
   RETURN "End Dump Test"


[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 header file: include/dbinfo.ch. Defines 10 constants including: HB_DBINFO_CH_, RDDI_ISDBF, RDDI_CANPUTREC, RDDI_DELIMITER, RDDI_SEPARATOR. Defines Harbour internal constants and macros

[Assistant]
#ifndef HB_DBINFO_CH_
#define HB_DBINFO_CH_

#define RDDI_ISDBF                1
#define RDDI_CANPUTREC            2
#define RDDI_DELIMITER            3
#define RDDI_SEPARATOR            4

#define RDDI_TABLEEXT             5
#define RDDI_MEMOEXT              6
#define RDDI_ORDBAGEXT            7
#define RDDI_ORDEREXT             8
#define RDDI_ORDSTRUCTEXT         9

#define RDDI_LOCAL               10
#define RDDI_REMOTE              11
#define RDDI_CONNECTION          12
#define RDDI_TABLETYPE           13
#define RDDI_MEMOTYPE            14
#define RDDI_LARGEFILE           15
#define RDDI_LOCKSCHEME          16
#define RDDI_RECORDMAP           17
#define RDDI_ENCRYPTION          18
#define RDDI_TRIGGER             19
#define RDDI_AUTOLOCK            20

#define RDDI_STRUCTORD           21
#define RDDI_STRICTREAD          22
#define RDDI_STRICTSTRUCT        23
#define RDDI_OPTIMIZE            24
#define RDDI_FORCEOPT            25
#define RDDI_AUTOOPEN            26
#define RDDI_AUTOORDER           27
#define RDDI_AUTOSHARE           28
#define RDDI_MULTITAG            29
#define RDDI_SORTRECNO           30
#define RDDI_MULTIKEY            31

#define RDDI_MEMOBLOCKSIZE       32
#define RDDI_MEMOVERSION         33
#define RDDI_MEMOGCTYPE          34
#define RDDI_MEMOREADLOCK        35
#define RDDI_MEMOREUSE           36
#define RDDI_BLOB_SUPPORT        37

#define RDDI_PENDINGTRIGGER      40
#define RDDI_PENDINGPASSWORD     41
#define RDDI_PASSWORD            42
#define RDDI_LOCKRETRY           43
#define RDDI_DIRTYREAD           44
#define RDDI_INDEXPAGESIZE       45
#define RDDI_DECIMALS            46
#define RDDI_SETHEADER           47

#define RDDI_CONNECT             61
#define RDDI_DISCONNECT          62
#define RDDI_EXECUTE             63
#define RDDI_ERROR               64
#define RDDI_ERRORNO             65
#define RDDI_INSERTID            66
#define RDDI_AFFECTEDROWS        67
#define RDDI_QUERY               68

#define DBOI_CONDITION            1
#define DBOI_EXPRESSION           2
#define DBOI_POSITION             3
#define DBOI_RECNO                4
#define DBOI_NAME                 5
#define DBOI_NUMBER               6
#define DBOI_BAGNAME              7
#define DBOI_BAGEXT               8
#define DBOI_INDEXEXT            DBOI_BAGEXT
#define DBOI_INDEXNAME           DBOI_BAGNAME
#define DBOI_ORDERCOUNT           9
#define DBOI_FILEHANDLE          10
#define DBOI_ISCOND              11
#define DBOI_ISDESC              12
#define DBOI_UNIQUE              13

#define DBOI_FULLPATH            20
#define DBOI_KEYTYPE             24
#define DBOI_KEYSIZE             25
#define DBOI_KEYCOUNT            26
#define DBOI_SETCODEBLOCK        27
#define DBOI_KEYDEC              28
#define DBOI_HPLOCKING           29
#define DBOI_LOCKOFFSET          35

#define DBOI_KEYADD              36
#define DBOI_KEYDELETE           37
#define DBOI_KEYVAL              38
#define DBOI_SCOPETOP            39
#define DBOI_SCOPEBOTTOM         40
#define DBOI_SCOPETOPCLEAR       41
#define DBOI_SCOPEBOTTOMCLEAR    42
#define DBOI_CUSTOM              45
#define DBOI_SKIPUNIQUE          46

#define DBOI_KEYSINCLUDED        50

#define DBOI_KEYGOTO             DBOI_POSITION
#define DBOI_KEYGOTORAW          DBOI_KEYNORAW
#define DBOI_KEYNO               DBOI_POSITION
#define DBOI_KEYNORAW            51
#define DBOI_KEYCOUNTRAW         52

#define DBOI_OPTLEVEL            53

#define DBOI_STRICTREAD          60
#define DBOI_OPTIMIZE            61
#define DBOI_AUTOOPEN            62
#define DBOI_AUTOORDER           63
#define DBOI_AUTOSHARE           64

#define DBOI_SKIPEVAL           100
#define DBOI_SKIPEVALBACK       101
#define DBOI_SKIPREGEX          102
#define DBOI_SKIPREGEXBACK      103
#define DBOI_SKIPWILD           104
#define DBOI_SKIPWILDBACK       105
#define DBOI_SCOPEEVAL          106
#define DBOI_FINDREC            107
#define DBOI_FINDRECCONT        108
#define DBOI_SCOPESET           109
#define DBOI_SCOPECLEAR         110

#define DBOI_BAGCOUNT           111
#define DBOI_BAGNUMBER          112
#define DBOI_BAGORDER           113

#define DBOI_ISMULTITAG         114
#define DBOI_ISSORTRECNO        115
#define DBOI_LARGEFILE          116
#define DBOI_TEMPLATE           117
#define DBOI_MULTIKEY           118
#define DBOI_CHGONLY            119
#define DBOI_PARTIAL            120
#define DBOI_SHARED             121
#define DBOI_ISREADONLY         122
#define DBOI_READLOCK           123
#define DBOI_WRITELOCK          124
#define DBOI_UPDATECOUNTER      125

#define DBOI_EVALSTEP           126
#define DBOI_ISREINDEX          127
#define DBOI_I_BAGNAME          128
#define DBOI_I_TAGNAME          129

#define DBOI_RELKEYPOS          130
#define DBOI_USECURRENT         131
#define DBOI_INDEXTYPE          132
#define DBOI_RESETPOS           133
#define DBOI_INDEXPAGESIZE      134

#define DBOI_OPTIMIZED_NONE       0
#define DBOI_OPTIMIZED_PART       1
#define DBOI_OPTIMIZED_FULL       2

#define DBOI_TYPE_UNDEF          -1
#define DBOI_TYPE_NONE            0
#define DBOI_TYPE_NONCOMPACT      1
#define DBOI_TYPE_COMPACT         2
#define DBOI_TYPE_COMPOUND        3

#define DBRMI_FUNCTION            1
#define DBRMI_PARAM               2
#define DBRMI_LOVAL               3
#define DBRMI_HIVAL               4
#define DBRMI_RESULT              5
#define DBRMI_SIZE                5

#define DBRI_DELETED              1
#define DBRI_LOCKED               2
#define DBRI_RECSIZE              3
#define DBRI_RECNO                4
#define DBRI_UPDATED              5
#define DBRI_ENCRYPTED            6
#define DBRI_RAWRECORD            7
#define DBRI_RAWMEMOS             8
#define DBRI_RAWDATA              9

#define DBI_ISDBF                 1
#define DBI_CANPUTREC             2
#define DBI_GETHEADERSIZE         3
#define DBI_LASTUPDATE            4
#define DBI_GETDELIMITER          5
#define DBI_SETDELIMITER          6
#define DBI_GETRECSIZE            7
#define DBI_GETLOCKARRAY          8
#define DBI_TABLEEXT              9
#define DBI_FULLPATH             10

#define DBI_ISFLOCK              20
#define DBI_CHILDCOUNT           22
#define DBI_FILEHANDLE           23
#define DBI_BOF                  26
#define DBI_EOF                  27
#define DBI_DBFILTER             28
#define DBI_FOUND                29
#define DBI_FCOUNT               30
#define DBI_LOCKCOUNT            31
#define DBI_VALIDBUFFER          32
#define DBI_ALIAS                33
#define DBI_GETSCOPE             34
#define DBI_LOCKOFFSET           35
#define DBI_SHARED               36
#define DBI_MEMOEXT              37
#define DBI_MEMOHANDLE           38
#define DBI_MEMOBLOCKSIZE        39

#define DBI_DB_VERSION          101
#define DBI_RDD_VERSION         102

#define DBI_LOCKSCHEME          128
#define DBI_ISREADONLY          129
#define DBI_ROLLBACK            130
#define DBI_PASSWORD            131
#define DBI_ISENCRYPTED         132
#define DBI_MEMOTYPE            133
#define DBI_SEPARATOR           134
#define DBI_MEMOVERSION         135
#define DBI_TABLETYPE           136
#define DBI_SCOPEDRELATION      137
#define DBI_TRIGGER             138
#define DBI_OPENINFO            139
#define DBI_ENCRYPT             140
#define DBI_DECRYPT             141
#define DBI_MEMOPACK            142
#define DBI_DIRTYREAD           143
#define DBI_POSITIONED          144
#define DBI_ISTEMPORARY         145
#define DBI_LOCKTEST            146
#define DBI_CODEPAGE            147
#define DBI_TRANSREC            148
#define DBI_SETHEADER           149