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

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

Harbour utility program: utils/hbtest/rt_hvm.prg. Contains procedures: Main_HVM. This file is part of the test framework

[Assistant]
#include "rt_main.ch"

#include "rt_vars.ch"

PROCEDURE Main_HVM()

   HBTEST ValType(  scString  )           IS "C"
   HBTEST ValType(  scStringE )           IS "C"
   HBTEST ValType(  scStringZ )           IS "C"
   HBTEST ValType(  snIntZ    )           IS "N"
   HBTEST ValType(  snDoubleZ )           IS "N"
   HBTEST ValType(  snIntP    )           IS "N"
   HBTEST ValType(  snLongP   )           IS "N"
   HBTEST ValType(  snDoubleP )           IS "N"
   HBTEST ValType(  snIntN    )           IS "N"
   HBTEST ValType(  snLongN   )           IS "N"
   HBTEST ValType(  snDoubleN )           IS "N"
   HBTEST ValType(  snDoubleI )           IS "N"
   HBTEST ValType(  sdDateE   )           IS "D"
   HBTEST ValType(  slFalse   )           IS "L"
   HBTEST ValType(  slTrue    )           IS "L"
   HBTEST ValType(  soObject  )           IS "O"
   HBTEST ValType(  suNIL     )           IS "U"
   HBTEST ValType(  sbBlock   )           IS "B"
   HBTEST ValType(  saArray   )           IS "A"
   HBTEST ValType( { 1, 2, 3 } )          IS "A"
   IF TEST_DBFAvail()
   HBTEST ValType( w_TEST->TYPE_C )       IS "C"
   HBTEST ValType( w_TEST->TYPE_D )       IS "D"
   HBTEST ValType( w_TEST->TYPE_M )       IS "M"
   HBTEST ValType( w_TEST->TYPE_N_I )     IS "N"
   HBTEST ValType( w_TEST->TYPE_N_D )     IS "N"
   HBTEST ValType( w_TEST->TYPE_L )       IS "L"
   ENDIF
#ifdef __HARBOUR__
   HBTEST ValType( @scString  )           IS "C"
   HBTEST ValType( @scStringE )           IS "C"
   HBTEST ValType( @scStringZ )           IS "C"
   HBTEST ValType( @snIntZ    )           IS "N"
   HBTEST ValType( @snDoubleZ )           IS "N"
   HBTEST ValType( @snIntP    )           IS "N"
   HBTEST ValType( @snLongP   )           IS "N"
   HBTEST ValType( @snDoubleP )           IS "N"
   HBTEST ValType( @snIntN    )           IS "N"
   HBTEST ValType( @snLongN   )           IS "N"
   HBTEST ValType( @snDoubleN )           IS "N"
   HBTEST ValType( @snDoubleI )           IS "N"
   HBTEST ValType( @sdDateE   )           IS "D"
   HBTEST ValType( @slFalse   )           IS "L"
   HBTEST ValType( @slTrue    )           IS "L"
   HBTEST ValType( @soObject  )           IS "O"
   HBTEST ValType( @suNIL     )           IS "U"
   HBTEST ValType( @sbBlock   )           IS "B"
   HBTEST ValType( @saArray   )           IS "A"
#endif
   HBTEST ValType(  mcString  )           IS "C"
   HBTEST ValType(  mcStringE )           IS "C"
   HBTEST ValType(  mcStringZ )           IS "C"
   HBTEST ValType(  mnIntZ    )           IS "N"
   HBTEST ValType(  mnDoubleZ )           IS "N"
   HBTEST ValType(  mnIntP    )           IS "N"
   HBTEST ValType(  mnLongP   )           IS "N"
   HBTEST ValType(  mnDoubleP )           IS "N"
   HBTEST ValType(  mnIntN    )           IS "N"
   HBTEST ValType(  mnLongN   )           IS "N"
   HBTEST ValType(  mnDoubleN )           IS "N"
   HBTEST ValType(  mnDoubleI )           IS "N"
   HBTEST ValType(  mdDateE   )           IS "D"
   HBTEST ValType(  mlFalse   )           IS "L"
   HBTEST ValType(  mlTrue    )           IS "L"
   HBTEST ValType(  moObject  )           IS "O"
   HBTEST ValType(  muNIL     )           IS "U"
   HBTEST ValType(  mbBlock   )           IS "B"
   HBTEST ValType(  maArray   )           IS "A"
#ifdef __HARBOUR__
   HBTEST ValType( @mcString  )           IS "C"
   HBTEST ValType( @mcStringE )           IS "C"
   HBTEST ValType( @mcStringZ )           IS "C"
   HBTEST ValType( @mnIntZ    )           IS "N"
   HBTEST ValType( @mnDoubleZ )           IS "N"
   HBTEST ValType( @mnIntP    )           IS "N"
   HBTEST ValType( @mnLongP   )           IS "N"
   HBTEST ValType( @mnDoubleP )           IS "N"
   HBTEST ValType( @mnIntN    )           IS "N"
   HBTEST ValType( @mnLongN   )           IS "N"
   HBTEST ValType( @mnDoubleN )           IS "N"
   HBTEST ValType( @mnDoubleI )           IS "N"
   HBTEST ValType( @mdDateE   )           IS "D"
   HBTEST ValType( @mlFalse   )           IS "L"
   HBTEST ValType( @mlTrue    )           IS "L"
   HBTEST ValType( @moObject  )           IS "O"
   HBTEST ValType( @muNIL     )           IS "U"
   HBTEST ValType( @mbBlock   )           IS "B"
   HBTEST ValType( @maArray   )           IS "A"
#endif

#ifndef __XPP__
   HBTEST Type( NIL )                     IS "E 1 BASE 1121 Argument error (TYPE) OS:0 #:0 A:1:U:NIL F:S"
   HBTEST Type( 100 )                     IS "E 1 BASE 1121 Argument error (TYPE) OS:0 #:0 A:1:N:100 F:S"
   HBTEST Type( {} )                      IS "E 1 BASE 1121 Argument error (TYPE) OS:0 #:0 A:1:A:{.[0].} F:S"
#endif
   IF TEST_DBFAvail()
   HBTEST Type( "w_TEST->TYPE_C" )        IS "C"
   HBTEST Type( "w_TEST->TYPE_D" )        IS "D"
   HBTEST Type( "w_TEST->TYPE_M" )        IS "M"
   HBTEST Type( "w_TEST->TYPE_N_I" )      IS "N"
   HBTEST Type( "w_TEST->TYPE_N_D" )      IS "N"
   HBTEST Type( "w_TEST->TYPE_L" )        IS "L"
   ENDIF
   HBTEST Type( "mxNotHere"  )            IS "U"
   HBTEST Type( "mcString"  )             IS "C"
   HBTEST Type( "mcStringE" )             IS "C"
   HBTEST Type( "mcStringZ" )             IS "C"
   HBTEST Type( "mnIntZ"    )             IS "N"
   HBTEST Type( "mnDoubleZ" )             IS "N"
   HBTEST Type( "mnIntP"    )             IS "N"
   HBTEST Type( "mnLongP"   )             IS "N"
   HBTEST Type( "mnDoubleP" )             IS "N"
   HBTEST Type( "mnIntN"    )             IS "N"
   HBTEST Type( "mnLongN"   )             IS "N"
   HBTEST Type( "mnDoubleN" )             IS "N"
   HBTEST Type( "mnDoubleI" )             IS "N"
   HBTEST Type( "mdDateE"   )             IS "D"
   HBTEST Type( "mlFalse"   )             IS "L"
   HBTEST Type( "mlTrue"    )             IS "L"
   HBTEST Type( "moObject"  )             IS "O"
   HBTEST Type( "muNIL"     )             IS "U"
   HBTEST Type( "mbBlock"   )             IS "B"
   HBTEST Type( "maArray"   )             IS "A"

#ifndef __HARBOUR__
#ifndef __XPP__
   HBTEST NIL:className()                 IS "NIL"
#endif
#endif
#ifndef __XPP__
   HBTEST "":className()                  IS "CHARACTER"
   HBTEST 0:className()                   IS "NUMERIC"
   HBTEST hb_SToD( "" ):className()       IS "DATE"
   HBTEST .F.:className()                 IS "LOGICAL"
   HBTEST {|| NIL }:className()           IS "BLOCK"
   HBTEST {}:className()                  IS "ARRAY"
#endif
   HBTEST ErrorNew():className()          IS "ERROR"
   HBTEST ErrorNew():className            IS "ERROR"

#ifndef __HARBOUR__
#ifndef __XPP__
   HBTEST NIL:classH()                    IS 0
#endif
#endif
#ifndef __XPP__
   HBTEST "":classH()                     IS 0
   HBTEST 0:classH()                      IS 0
   HBTEST hb_SToD( "" ):classH()          IS 0
   HBTEST .F.:classH()                    IS 0
   HBTEST {|| NIL }:classH()              IS 0
   HBTEST {}:classH()                     IS 0
#endif
   HBTEST ErrorNew():classH() > 0         IS .T.
   HBTEST ErrorNew():classH > 0           IS .T.

#ifndef __HARBOUR__
#ifndef __XPP__
   HBTEST suNIL:className()               IS "NIL"
#endif
#endif
#ifndef __XPP__
   HBTEST scString:className()            IS "CHARACTER"
   HBTEST snIntP:className()              IS "NUMERIC"
   HBTEST sdDateE:className()             IS "DATE"
   HBTEST slFalse:className()             IS "LOGICAL"
   HBTEST sbBlock:className()             IS "BLOCK"
   HBTEST saArray:className()             IS "ARRAY"
#endif
   HBTEST soObject:className()            IS "ERROR"
   HBTEST soObject:className              IS "ERROR"

#ifndef __HARBOUR__
#ifndef __XPP__
   HBTEST suNIL:classH()                  IS 0
#endif
#endif
#ifndef __XPP__
   HBTEST scString:classH()               IS 0
   HBTEST snIntP:classH()                 IS 0
   HBTEST sdDateE:classH()                IS 0
   HBTEST slFalse:classH()                IS 0
   HBTEST sbBlock:classH()                IS 0
   HBTEST saArray:classH()                IS 0
#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] Create Harbour preprocessor definitions: Harbour contribution module 'hbpgsql' (PostgreSQL database client library): contrib/hbpgsql/tests/cache.prg. Provides 9 functions including: SQLApplyUpdates, SQLFetch, SQLOpen, SQLConnect, SQLCurrentServer. Contains 6 procedures. This file handles database operations

[Assistant]
#require "hbpgsql"

#define DB_ALIAS            1
#define DB_QUERY            2
#define DB_ROW              3
#define DB_FETCH            4

THREAD STATIC t_oServer
THREAD STATIC t_aTableTemp := {}

PROCEDURE Main( cHost, cDatabase, cUser, cPass )

   LOCAL i

   IF SQLConnect( cHost, hb_defaultValue( cDatabase, "postgres" ), cUser, cPass )

      QuickQuery( "DROP TABLE test" )

      SQLQuery( "CREATE TABLE test (" + ;
         "  codigo integer primary key," + ;
         "  descri char(50)," + ;
         "  email varchar(50) )" )

      SQLOpen( "nomes", "SELECT * FROM test" )

      FOR i := 1 TO 50
         dbAppend()
         nomes->codigo := i
         nomes->descri := "test " + hb_ntos( i )
      NEXT

      SQLApplyUpdates()

      SQLOpen( "nomes", SQLPrepare( "SELECT * FROM test WHERE codigo >= :1 ORDER BY codigo", 1 ) )

      DO WHILE ! Eof()
         ? RecNo(), nomes->Codigo, nomes->descri, nomes->email

         IF RecNo() == 10
            dbDelete()
         ENDIF

         IF RecNo() == 20
            nomes->email := "teste"
         ENDIF

         SQLFetch()
      ENDDO

      SQLApplyUpdates()
   ENDIF

   SQLGarbageCollector()

   RETURN

FUNCTION SQLApplyUpdates()

   LOCAL cAlias := Upper( Alias() )
   LOCAL i, x
   LOCAL oQuery
   LOCAL oRow
   LOCAL lUpdate
   LOCAL lError := .F.
   LOCAL cError

   IF ( i := AScan( t_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } ) ) > 0

      oQuery := t_aTableTemp[ i ][ DB_QUERY ]

      FOR i := 1 TO LastRec()

         dbGoto( i )

         IF i > oQuery:LastRec()

            IF ! Deleted()

               oRow := oQuery:GetBlankRow()

               FOR x := 1 TO FCount()
                  IF oRow:FieldPos( FieldName( x ) ) != 0
                     oRow:FieldPut( FieldName( x ), FieldGet( x ) )
                  ENDIF
               NEXT

               oQuery:Append( oRow )
               cError := oQuery:ErrorMsg()
               lError := oQuery:NetErr()
            ENDIF
         ELSE
            oRow := oQuery:GetRow( i )

            IF Deleted()
               oQuery:Delete( oRow )
               cError := oQuery:ErrorMsg()
               lError := oQuery:NetErr()
            ELSE

               lUpdate := .F.
               FOR x := 1 TO FCount()
                  IF oRow:FieldPos( FieldName( x ) ) != 0 .AND. ;
                     ! FieldGet( x ) == oRow:FieldGet( FieldName( x ) )
                     oRow:FieldPut( FieldName( x ), FieldGet( x ) )
                     lUpdate := .T.
                  ENDIF
               NEXT

               IF lUpdate
                  oQuery:Update( oRow )
                  cError := oQuery:ErrorMsg()
                  lError := oQuery:NetErr()
               ENDIF
            ENDIF
         ENDIF

         IF lError
            EXIT
         ENDIF
      NEXT
   ENDIF

   IF lError
      ? cError
   ENDIF

   RETURN ! lError

PROCEDURE SQLCloseTemp( cAlias )

   LOCAL x

   IF Select( cAlias ) != 0
      ( cAlias )->( dbCloseArea() )
   ENDIF

   IF ( x := AScan( t_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } ) ) > 0
      hb_ADel( t_aTableTemp, x, .F.  )
   ENDIF

   RETURN

PROCEDURE SQLGarbageCollector()

   LOCAL item
   LOCAL oQuery

   dbCloseAll()

   FOR EACH item IN t_aTableTemp
      IF ( oQuery := item[ DB_QUERY ] ) != NIL
         oQuery:Destroy()
      ENDIF
   NEXT

   ASize( t_aTableTemp, 0 )

   RETURN

FUNCTION SQLFetch( lFetchAll )

   LOCAL oQuery
   LOCAL oRow
   LOCAL cAlias := Upper( Alias() )
   LOCAL i, x, y
   LOCAL nPos
   LOCAL lEof := .F.

   hb_default( @lFetchAll, .F. )

   IF ( i := AScan( t_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } ) ) > 0

      oQuery := t_aTableTemp[ i ][ DB_QUERY ]
      nPos   := t_aTableTemp[ i ][ DB_ROW ] + 1

      IF lFetchAll
         t_aTableTemp[ i ][ DB_FETCH ] := .T.
      ENDIF

      IF oQuery:LastRec() >= nPos

         y := nPos

         DO WHILE nPos <= iif( lFetchAll, oQuery:LastRec(), y )
            oRow := oQuery:GetRow( nPos )
            dbAppend()

            FOR x := 1 TO oRow:FCount()
               FieldPut( FieldPos( oRow:FieldName( x ) ), oRow:FieldGet( x ) )
            NEXT

            t_aTableTemp[ i ][ DB_ROW ] := nPos
            nPos++
         ENDDO

      ELSE

         dbSkip()
      ENDIF

      lEof := nPos > oQuery:LastRec()
   ENDIF

   RETURN lEof

PROCEDURE SQLFetchAll()

   SQLFetch( .T. )
   dbGoTop()

   RETURN

FUNCTION SQLOpen( cAlias, cQuery, xFetch, cOrder )

   LOCAL x
   LOCAL oServer
   LOCAL oQuery
   LOCAL lFetch

   oServer := SQLCurrentServer()
   cAlias := Upper( cAlias )

   IF ( x := AScan( t_aTableTemp, {| aVal | aVal[ DB_ALIAS ] == cAlias } ) ) > 0
      oQuery := t_aTableTemp[ x ][ DB_QUERY ]
      oQuery:Destroy()
   ENDIF

   IF cQuery == NIL
      cQuery := "SELECT * FROM " + cAlias
      IF ! Empty( cOrder )
         cQuery += " ORDER BY " + cOrder
      ENDIF
   ENDIF

   oQuery := oServer:Query( cQuery )

   IF oQuery:NetErr()
      ? oQuery:ErrorMsg()
      RETURN .F.
   ENDIF

   IF Select( cAlias ) == 0
      hb_dbCreateTemp( cAlias, oQuery:Struct() )
   ELSE
      dbSelectArea( cAlias )
      hb_dbZap()
   ENDIF

   IF xFetch != NIL
      lFetch := xFetch
   ELSE
      lFetch := .F.
   ENDIF

   IF x == 0
      AAdd( t_aTableTemp, { ;
         cAlias, ;
         oQuery, ;
         0, ;
         lFetch } )
   ELSE

      t_aTableTemp[ x ][ DB_QUERY ] := oQuery
      t_aTableTemp[ x ][ DB_ROW ]   := 0
      t_aTableTemp[ x ][ DB_FETCH ] := lFetch

   ENDIF

   SQLFetch( lFetch )

   IF lFetch
      dbGoTop()
   ENDIF

   RETURN .T.

FUNCTION SQLConnect( cHost, cDatabase, cUser, cPassword, cSchema )

   LOCAL lRetval := .T.

   t_oServer := TPQServer():New( cHost, cDatabase, cUser, cPassword, 5432, cSchema )
   IF t_oServer:NetErr()
      ? t_oServer:ErrorMsg()
      lRetval := .F.
   ENDIF
   t_oServer:lAllCols := .F.

   RETURN lRetval

PROCEDURE SQLDestroy()

   IF t_oServer != NIL
      t_oServer:Destroy()
   ENDIF

   RETURN

FUNCTION SQLCurrentServer
   RETURN t_oServer

FUNCTION SQLQuery( cQuery )

   LOCAL oQuery := t_oServer:Query( cQuery )

   IF oQuery:NetErr()
      ? cQuery + ":" + oQuery:ErrorMsg()
   ENDIF

   RETURN oQuery

FUNCTION SQLExecQuery( cQuery )

   LOCAL oQuery := t_oServer:Query( cQuery )

   IF oQuery:NetErr()
      ? "Cannot execute", cQuery + ":" + oQuery:ErrorMsg()
      RETURN .F.
   ENDIF

   oQuery:Destroy()

   RETURN .T.

FUNCTION SQLPrepare( cQuery, ... )

   LOCAL i, x

   IF PCount() >= 2

      DO WHILE Space( 2 ) $ cQuery
         cQuery := StrTran( cQuery, Space( 2 ), Space( 1 ) )
      ENDDO

      FOR i := 1 TO PCount() - 1
         IF ( x := At( ":" + hb_ntos( i ), cQuery ) ) > 0
            cQuery := Stuff( cQuery, x, 0, "{" )
            cQuery := Stuff( cQuery, x + Len( hb_ntos( i ) ) + 2, 0, "}" )
         ENDIF
      NEXT

      FOR i := 2 TO PCount()
         x := hb_PValue( i )

         DO CASE
         CASE x != NIL .AND. Empty( x )
            x := "null"

         CASE HB_ISNUMERIC( x )
            x := hb_ntos( x )

         CASE HB_ISDATE( x )
            x := "'" + hb_DToC( x, "yyyy-mm-dd" ) + "'"

         CASE HB_ISLOGICAL( x )
            x := iif( x, "'t'", "'f'" )

         CASE HB_ISSTRING( x )
            x := SToQ( RTrim( x ) )

         OTHERWISE
            x := "null"
         ENDCASE

         cQuery := StrTran( cQuery, "{:" + hb_ntos( i - 1 ) + "}", x )
      NEXT
   ENDIF

   RETURN hb_StrReplace( cQuery, { ;
      "=="    => "="   , ;
      "!="    => "<>"  , ;
      ".and." => "and" , ;
      ".or."  => "or"  , ;
      ".not." => "not" } )

FUNCTION SQLSequence( Sequence_name )
   RETURN Val( QuickQuery( "SELECT nextval(" + SToQ( sequence_name ) + ")" ) )

PROCEDURE SQLStartTrans()

   IF PQtransactionStatus( t_oServer:pDB ) != PQTRANS_INTRANS
      t_oServer:StartTransaction()
   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:

Header file for contribution module 'xhb' (Extended Harbour functions): contrib/xhb/hbcomprs.ch. Defines 10 constants including: HB_COMPRESS_CH, HB_Z_OK, HB_Z_STREAM_END, HB_Z_NEED_DICT, HB_Z_ERRNO. Defines error handling constants and codes

[Assistant]
#ifndef HB_COMPRESS_CH
#define HB_COMPRESS_CH

#include "hbzlib.ch"

#define HB_Z_OK                   HB_ZLIB_RES_OK
#define HB_Z_STREAM_END           HB_ZLIB_RES_STREAM_END
#define HB_Z_NEED_DICT            HB_ZLIB_RES_NEED_DICT
#define HB_Z_ERRNO                HB_ZLIB_RES_ERRNO
#define HB_Z_STREAM_ERROR         HB_ZLIB_RES_STREAM_ERROR
#define HB_Z_DATA_ERROR           HB_ZLIB_RES_DATA_ERROR
#define HB_Z_MEM_ERROR            HB_ZLIB_RES_MEM_ERROR
#define HB_Z_BUF_ERROR            HB_ZLIB_RES_BUF_ERROR
#define HB_Z_VERSION_ERROR        HB_ZLIB_RES_VERSION_ERROR

#define HB_Z_NO_COMPRESSION       HB_ZLIB_COMPRESSION_NONE
#define HB_Z_BEST_SPEED           HB_ZLIB_COMPRESSION_SPEED
#define HB_Z_BEST_COMPRESSION     HB_ZLIB_COMPRESSION_SIZE
#define HB_Z_DEFAULT_COMPRESSION  HB_ZLIB_COMPRESSION_DEFAULT

#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] Create Harbour preprocessor definitions: Harbour contribution module 'hbxdiff' (File difference/patching): contrib/hbxdiff/tests/test.prg. Contains procedures: Main. This file provides utility functions

[Assistant]
#require "hbxdiff"

#define _SIZE 62

PROCEDURE Main()

   LOCAL pMMF
   LOCAL cFileCtx
   LOCAL nSize

   pMMF := xdl_init_mmfile( XDLT_STD_BLKSIZE, XDL_MMF_ATOMIC )
   ? xdl_mmfile_size( pMMF )
   ? xdl_mmfile_iscompact( pMMF )

   cFileCtx := hb_MemoRead( __FILE__ )

   ? xdl_write_mmfile( pMMF, cFileCtx ), Len( cFileCtx )
   ? xdl_mmfile_size( pMMF )

   ? xdl_read_mmfile( pMMF, NIL, _SIZE, @nSize )
   ? nSize

   xdl_seek_mmfile( pMMF, 0 )

   ? xdl_read_mmfile( pMMF, NIL, _SIZE, @nSize )
   ? nSize

   ? xdl_read_mmfile( pMMF, NIL, _SIZE, @nSize )
   ? nSize

   xdl_seek_mmfile( pMMF, _SIZE )

   ? xdl_read_mmfile( pMMF, NIL, _SIZE, @nSize )
   ? nSize

   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 header file: include/hbdebug.ch. Defines 10 constants including: HB_DEBUGGER_CH_, HB_DBG_MODULENAME, HB_DBG_LOCALNAME, HB_DBG_STATICNAME, HB_DBG_ENDPROC. Defines color and display constants

[Assistant]
#ifndef HB_DEBUGGER_CH_
#define HB_DEBUGGER_CH_

#define HB_DBG_MODULENAME     1
#define HB_DBG_LOCALNAME      2
#define HB_DBG_STATICNAME     3
#define HB_DBG_ENDPROC        4
#define HB_DBG_SHOWLINE       5
#define HB_DBG_GETENTRY       6
#define HB_DBG_ACTIVATE       7
#define HB_DBG_VMQUIT         8

#define HB_DBG_CS_MODULE      1
#define HB_DBG_CS_FUNCTION    2
#define HB_DBG_CS_LINE        3
#define HB_DBG_CS_LEVEL       4
#define HB_DBG_CS_LOCALS      5
#define HB_DBG_CS_STATICS     6
#define HB_DBG_CS_LEN         6

#define HB_DBG_MOD_NAME       1
#define HB_DBG_MOD_STATICS    2
#define HB_DBG_MOD_GLOBALS    3
#define HB_DBG_MOD_EXTGLOBALS 4
#define HB_DBG_MOD_LEN        4

#define HB_DBG_VAR_NAME          1
#define HB_DBG_VAR_INDEX         2
#define HB_DBG_VAR_TYPE          3
#define HB_DBG_VAR_FRAME         4
#define HB_DBG_VAR_LEN           4

#define HB_DBG_WP_EXPR           1
#define HB_DBG_WP_ISTRACE        2
#define HB_DBG_WP_VALID          3
#define HB_DBG_WP_RESULT         4
#define HB_DBG_WP_LEN            4

#define HB_DBG_BP_LINE           1
#define HB_DBG_BP_MODULE         2
#define HB_DBG_BP_FUNC           3
#define HB_DBG_BP_LEN            3

#define HB_DBG_SET_POS           1
#define HB_DBG_SET_NAME          2
#define HB_DBG_SET_VALUE         3
#define HB_DBG_SET_LEN           3

#endif


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

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

Harbour contribution module 'gtwvg' (): contrib/gtwvg/htmlview.prg. Defines classes: WvgHTMLViewer. This file provides platform-specific functionality

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

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

#define evBeforeNavigate                          100
#define evNavigateComplete                        101
#define evStatusTextChange                        102
#define evDownloadComplete                        104
#define evCommandStateChange                      105
#define evDownloadBegin                           106
#define evProgressChange                          108
#define evTitleChange                             113

#define evPropertyChange                          112
#define evBeforeNavigate2                         250
#define evNavigateComplete2                       252
#define evDocumentComplete                        259
#define evNavigateError                           271

CREATE CLASS WvgHTMLViewer INHERIT WvgActiveXControl

   METHOD new( oParent, oOwner, aPos, aSize, aPresParams, lVisible )
   METHOD create( oParent, oOwner, aPos, aSize, aPresParams, lVisible )

   METHOD xBeforeNavigate( cURL, Flags, TFName, PData, Headers )
   METHOD xStatusTextChange( cText )
   METHOD xNavigateComplete( cURL )
   METHOD xProgressChange( nProgress, nProgMax )
   METHOD xTitleChange( cTitle )
   METHOD xDocumentComplete( cURI )
   METHOD setHTML( cHTML )

   METHOD back()                                INLINE ::goBack()
   METHOD forward()                             INLINE ::goForward()
   METHOD home()                                INLINE ::goHome()
   METHOD search()                              INLINE ::goSearch()
   METHOD isBusy()                              INLINE ::busy()

   VAR    sl_beforeNavigate                     PROTECTED
   ACCESS beforeNavigate                        INLINE ::sl_beforeNavigate
   ASSIGN beforeNavigate( bBlock )              INLINE ::sl_beforeNavigate := bBlock

   VAR    sl_navigateComplete                   PROTECTED
   ACCESS navigateComplete                      INLINE ::sl_navigateComplete
   ASSIGN navigateComplete( bBlock )            INLINE ::sl_navigateComplete := bBlock

   VAR    sl_statusTextChange                   PROTECTED
   ACCESS statusTextChange                      INLINE ::sl_statusTextChange
   ASSIGN statusTextChange( bBlock )            INLINE ::sl_statusTextChange := bBlock

   VAR    sl_progressChange                     PROTECTED
   ACCESS progressChange                        INLINE ::sl_progressChange
   ASSIGN progressChange( bBlock )              INLINE ::sl_progressChange := bBlock

   VAR    sl_titleChange                        PROTECTED
   ACCESS titleChange                           INLINE ::sl_titleChange
   ASSIGN titleChange( bBlock )                 INLINE ::sl_titleChange := bBlock

   VAR    sl_documentComplete                   PROTECTED
   ACCESS documentComplete                      INLINE ::sl_documentComplete
   ASSIGN documentComplete( bBlock )            INLINE ::sl_documentComplete := bBlock

   VAR    CLSID                                 PROTECTED INIT "Shell.Explorer"

ENDCLASS

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

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

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

   RETURN Self

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

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

   ::mapEvent( evBeforeNavigate,   {| cURL, Flags, TFName, PData, Headers | ;
      ::xBeforeNavigate( cURL, Flags, TFName, PData, Headers ) } )

   ::mapEvent( evStatusTextChange, {| cText| ::xStatusTextChange( cText ) } )

   ::mapEvent( evNavigateComplete, {| cURL | ::xNavigateComplete( cURL ) } )

   ::mapEvent( evProgressChange, {| nProgress, nProgMax | ::xProgressChange( nProgress, nProgMax ) } )

   ::mapEvent( evTitleChange, {| cTitle | ::xTitleChange( cTitle ) } )

   ::mapEvent( evDocumentComplete, {| cURI | ::xDocumentComplete( cURI ) } )

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

   RETURN Self

METHOD WvgHTMLViewer:xBeforeNavigate( cURL, Flags, TFName, PData, Headers )

   HB_SYMBOL_UNUSED( Flags   )
   HB_SYMBOL_UNUSED( TFName  )
   HB_SYMBOL_UNUSED( PData   )
   HB_SYMBOL_UNUSED( Headers )

   IF PCount() >= 1 .AND. HB_ISBLOCK( ::sl_beforeNavigate )
      Eval( ::sl_beforeNavigate, cURL, , Self )
      RETURN NIL
   ENDIF

   RETURN Self

METHOD WvgHTMLViewer:xStatusTextChange( cText )

   IF HB_ISBLOCK( ::sl_statusTextChange )
      Eval( ::sl_statusTextChange, cText, , Self )
   ENDIF

   RETURN Self

METHOD WvgHTMLViewer:xNavigateComplete( cURL )

   IF HB_ISBLOCK( ::sl_navigateComplete )
      Eval( ::sl_navigateComplete, cURL, , Self )
   ENDIF

   RETURN Self

METHOD WvgHTMLViewer:xProgressChange( nProgress, nProgMax )

   IF HB_ISBLOCK( ::sl_progressChange )
      Eval( ::sl_progressChange, nProgress, nProgMax, Self )
   ENDIF

   RETURN Self

METHOD WvgHTMLViewer:xTitleChange( cTitle )

   IF HB_ISBLOCK( ::sl_titleChange )
      Eval( ::sl_titleChange, cTitle, , Self )
   ENDIF

   RETURN Self

METHOD WvgHTMLViewer:xDocumentComplete( cURI )

   IF HB_ISBLOCK( ::sl_documentComplete )
      Eval( ::sl_documentComplete, cURI, , Self )
   ENDIF

   RETURN Self

METHOD WvgHTMLViewer:setHTML( cHTML )

   ::document:innerHTML := cHTML
   ::refresh()

   RETURN Self


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

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

Harbour contribution module 'xhb' (Extended Harbour functions): contrib/xhb/tests/compress.prg. Contains procedures: Main. This file provides legacy compatibility functions

[Assistant]
#require "xhb"

#include "hbcomprs.ch"

PROCEDURE Main()

   LOCAL cText := "A  text  to  be  compressed             "
   LOCAL cComp
   LOCAL cDecomp
   LOCAL nError, nBufLen

   CLS
   @ 1, 15 SAY "X H A R B O U R - ZLIB based compression test"

   @ 2, 5 SAY "TEST 1: using on-the-fly Buffer creation"

   nBufLen := hb_CompressBufLen( Len( cText ) )

   cComp := hb_Compress( cText )
   cDecomp := hb_Uncompress( nBuflen, cComp )

   @ 3, 7 SAY "Uncompressed: (" + hb_ntos( Len( cText ) ) + ")" + cText + "<<"
   @ 4, 7 SAY "Compressed (" + hb_ntos( Len( cComp ) ) + ")" + hb_StrToHex( cComp ) + "<<"
   @ 5, 7 SAY "Decompressed: (" + hb_ntos( Len( cDecomp ) ) + ")" + cDecomp + "<<"

   @ 7, 5 SAY "TEST 2: using preallocated buffers"

   cComp := Space( nBufLen )

   cDecomp := Space( Int( nBufLen
   @ 8, 7 SAY "Uncompressed: (" + hb_ntos( Len( cText ) ) + ")" + cText + "<<"
   @ 9, 7 SAY "Compressed (" + hb_ntos( nBuflen ) + ")" + hb_StrToHex( cComp ) + "<<"

   @ 10, 7 SAY "Decompressed: (" + hb_ntos( Len( cDecomp ) ) + ")" + cDecomp + "<<"

   @ 12, 5 SAY "TEST 3: Generating an error"

   nBufLen := hb_CompressBufLen( Len( cText ) )
   cComp := Space( nBufLen )
   cDecomp := Space( Len( cText ) )

   nBuflen := 3
   nError := hb_Compress( cText, Len( cText ), @cComp, @nBuflen )

   IF nError != HB_Z_OK
      @ 13, 7 SAY "Error generated (" + hb_ntos( Len( cComp ) ) + ")" + ;
         hb_CompressErrorDesc( nError )
   ELSE
      @ 13, 7 SAY "NO Error generated (" + hb_ntos( Len( cComp ) ) + ")" + ;
         hb_CompressErrorDesc( nError )
   ENDIF

   @ 22, 25 SAY "Press a key to terminate"

   Inkey( 0 )

   RETURN


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

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

Harbour contribution module 'hbmisc' (Miscellaneous utility functions): contrib/hbmisc/numtxthu.prg. Provides functions: NumToTxtHU, NumToTxtRaw. This file provides utility functions

[Assistant]
FUNCTION NumToTxtHU( nValue )

   LOCAL aTort := { "tized", "század", "ezred", "tízezred", "százezred", "milliomod", "milliárdod" }
   LOCAL cRetVal
   LOCAL tmp, tmp1, tmp2

   IF nValue < 0
      nValue := -nValue
      cRetVal := "mínusz "
   ELSE
      cRetVal := ""
   ENDIF

   IF Int( nValue ) == 0
      cRetVal += "nulla"
   ENDIF

   cRetVal += NumToTxtRaw( tmp := Int( nValue ) )

   IF ( tmp := ( nValue - tmp ) ) > 0 .AND. tmp < 1

      tmp1 := Len( tmp2 := SubStr( Str( tmp, 8, 6 ), 3 ) )

      DO WHILE SubStr( tmp2, tmp1, 1 ) == "0" .AND. tmp1 > 0
         tmp1--
      ENDDO

      cRetVal += " egész " + NumToTxtRaw( tmp * ( 10 ^ tmp1 ) ) + iif( tmp1 >= 1 .AND. tmp1 <= Len( aTort ), " " + aTort[ tmp1 ], "" )
   ENDIF

   RETURN hb_UTF8ToStr( cRetVal )

STATIC FUNCTION NumToTxtRaw( nValue )

   LOCAL aEgesz  := { "", "ezer" , "millió", "milliárd", "billió" , "trillió", "kvadrillió", "kvintillió" }
   LOCAL aEgyes  := { "", "egy"  , "kettő" , "három"   , "négy"   , "öt"     , "hat"       , "hét"       , "nyolc"     , "kilenc" }
   LOCAL aTizes1 := { "", "tíz"  , "húsz"  , "harminc" , "negyven", "ötven"  , "hatvan"    , "hetven"    , "nyolcvan"  , "kilencven" }
   LOCAL aTizes2 := { "", "tizen", "huszon", "harminc" , "negyven", "ötven"  , "hatvan"    , "hetven"    , "nyolcvan"  , "kilencven" }

   LOCAL aDigit
   LOCAL nLen
   LOCAL cValue
   LOCAL tmp

   cValue := hb_ntos( nValue )
   cValue := PadL( cValue, ( Int( Max( Len( cValue ) - 1, 0 ) / 3 ) + 1 ) * 3, "0" )

   aDigit := Array( nLen := Len( cValue ) )
   FOR tmp := 1 TO nLen
      aDigit[ tmp ] := Val( SubStr( cValue, tmp, 1 ) )
   NEXT

   cValue := ""
   FOR tmp := 1 TO nLen - 2 STEP 3

      IF aDigit[ tmp     ] != 0 .OR. ;
         aDigit[ tmp + 1 ] != 0 .OR. ;
         aDigit[ tmp + 2 ] != 0

         cValue += ;
            iif( Empty( cValue ), "", "-" ) + ;
            iif( aDigit[ tmp ] != 0, aEgyes[ aDigit[ tmp ] + 1 ] + "száz", "" ) + ;
            iif( aDigit[ tmp + 2 ] == 0, aTizes1[ aDigit[ tmp + 1 ] + 1 ], aTizes2[ aDigit[ tmp + 1 ] + 1 ] ) + ;
            aEgyes[ aDigit[ tmp + 2 ] + 1 ] + ;
            aEgesz[ ( Int( ( nLen - tmp ) / 3 ) ) + 1 ]
      ENDIF
   NEXT

   RETURN cValue


[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 'hbziparc' (ZIP archive handling): contrib/hbziparc/tests/zipa.prg. Contains procedures: Main. This file provides utility functions

[Assistant]
#require "hbziparc"

PROCEDURE Main( cZip, ... )

   LOCAL a, b, c

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

   ? hb_ZipFile( cZip, hb_AParams() )

   a := hb_GetFilesInZip( cZip, .T. )

   FOR EACH b IN a
      ?
      FOR EACH c IN b
         ?? c, ""
      NEXT
   NEXT

   RETURN


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

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

[Assistant]
PROCEDURE Main()

   LOCAL dDate
   LOCAL A

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

   dDate := 0d20051112
   ? "Should be '2005-11-12' :", dDate

   dDate := 0d18341112
   ? "Should be '1834-11-12' :", dDate

   dDate := 0d20040229 + 1
   ? "Should be '2004-03-01' :", dDate

   dDate := 0d20040229 - 1
   ? "Should be '2004-02-28' :", dDate

   ? "Should be '4' :", 0d20040229 - 0d20040225
   ? "Should be '0' :", 0d20040229 - 0d20040229

   dDate := 0d20000229
   ? "Should be '2000-02-29' :", dDate

   a := "0d20040229+1"
   ? "Should be '2004-03-01' :", &a

   a := "Date() - 0d20051112"
   ? "Number of days from 2005-11-12:", &a

   RETURN


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

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

Harbour contribution module 'rddmisc' (): contrib/rddmisc/dbtcdx.prg. Provides functions: DBTCDX_GETFUNCTABLE. Contains procedures: DBTCDX_INIT. This file handles database operations

[Assistant]
#include "dbinfo.ch"
#include "hbusrrdd.ch"
#include "rddsys.ch"

REQUEST DBFCDX
REQUEST DBFFPT

ANNOUNCE DBTCDX

FUNCTION DBTCDX_GETFUNCTABLE( pFuncCount, pFuncTable, pSuperTable, nRddID, pSuperRddID )
   RETURN USRRDD_GETFUNCTABLE( pFuncCount, pFuncTable, pSuperTable, nRddID, ;
      "DBFCDX", {}, pSuperRddID )

INIT PROCEDURE DBTCDX_INIT()

   rddRegister( "DBTCDX", RDT_FULL )
   rddInfo( RDDI_MEMOTYPE, DB_MEMO_DBT, "DBTCDX" )

   RETURN


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

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

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

[Assistant]
FUNCTION ft_EscCode( cInput )

   LOCAL cOutput  := ""
   LOCAL cCurrent
   LOCAL nPointer := 1
   LOCAL nLen     := Len( cInput )

   DO WHILE nPointer <= nLen

      cCurrent := SubStr( cInput, nPointer, 1 )

      DO CASE

      CASE cCurrent == "\" .AND. ;
            IsDigit( SubStr( cInput, nPointer + 1, 1 ) ) .AND. ;
            IsDigit( SubStr( cInput, nPointer + 2, 1 ) ) .AND. ;
            IsDigit( SubStr( cInput, nPointer + 3, 1 ) )
         cOutput  += Chr( Val( SubStr( cInput, nPointer + 1, 3 ) ) )
         nPointer += 4

      CASE cCurrent == "\" .AND. ;
            SubStr( cInput, nPointer + 1, 1 ) == "\"
         cOutput += "\"
         nPointer += 2

      OTHERWISE
         cOutput += cCurrent
         nPointer++

      ENDCASE
   ENDDO

   RETURN cOutput


[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/charor.prg. Contains procedures: Main. This file provides legacy compatibility functions

[Assistant]
#ifdef __HARBOUR__
#require "hbct"
#else
#define hb_BChar( n ) Chr( n )
#endif

PROCEDURE Main()

   ctinit()

   ? "Begin test of CharOr()"
   ?

   ? "Simple tests:"

   ? '  CharOr( "012345678", hb_BChar( 1 ) ) == "113355779" ? --> "' + CharOr( "012345678", hb_BChar( 1 ) ) + '"'
   ? '  CharOr( "012345678", hb_BChar( 1 ) + hb_BChar( 3 ) ) == "133357779" ? --> "' + CharOr( "012345678", hb_BChar( 1 ) + hb_BChar( 3 ) ) + '"'

   ? "End test of CharOr()"
   ?

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

[Assistant]
PROCEDURE Main( cParam )

   LOCAL n, limit := 10

   CLS

   IF ! Empty( cParam )
      limit := Val( cParam )
   ENDIF
   ? Seconds()
   FOR n := 1 TO limit
      IF Empty( cParam )
         ? "Pause:"
         Inkey( 0 )
      ENDIF
      ? Seconds()
   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]
Write the following Harbour (xBase/Clipper) code:

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

[Assistant]
PROCEDURE Main()

   LOCAL a, b, c

   a := { {, } }

   a[ 1, 2 ] := [Hello]

   c := { 1 }

   b := a[ c[ 1 ] ][ Val( [ 2 ] ) ]

   ? b

   RETURN


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

[User] Implement this Harbour module: Harbour contribution module 'hbwin' (Windows API wrapper functions): contrib/hbwin/wce_sim.prg. Defines classes: wce_Sim. This file provides platform-specific functionality

[Assistant]
#include "hbclass.ch"

#include "hbsim.ch"

CREATE CLASS wce_Sim

   VAR lInitialized INIT .F.
   VAR hSim
   VAR nLastError INIT SIM_E_OK

   METHOD New()
   METHOD End()

   METHOD lInitialize()
   METHOD lDeInitialize()

   METHOD lNumberOfPhoneBookEntries( nType, nTotal, nUsed )
   METHOD aGetAllPhoneBookEntries( nType )
   METHOD lGetSimPhoneEntry( nPos, nType, aEntry )
   METHOD lSetSimPhoneEntry( nPos, nType, cNumber, cName, nPlan, nAddrType )
   METHOD lDelSimPhoneEntry( nPos, nType )

ENDCLASS

METHOD New() CLASS wce_Sim
   RETURN Self

METHOD lInitialize() CLASS wce_Sim

   LOCAL nResult := wce_SimInitialize( @::hSim )

   ::lInitialized := ( nResult == SIM_E_OK )
   ::nLastError   := nResult

   RETURN ::lInitialized

METHOD lDeInitialize() CLASS wce_Sim

   LOCAL nResult

   IF ! ::lInitialized
      ::nLastError := SIM_E_HB_NOTINITIALIZED
      RETURN .F.
   ENDIF

   nResult := wce_SimDeInitialize( ::hSim )

   ::lInitialized := !( nResult == SIM_E_OK )
   ::nLastError   := nResult

   RETURN nResult == SIM_E_OK

METHOD lNumberOfPhoneBookEntries( nType,  nTotal,  nUsed ) CLASS wce_Sim

   LOCAL nResult

   IF ! ::lInitialized
      ::nLastError := SIM_E_HB_NOTINITIALIZED
      RETURN .F.
   ENDIF

   hb_default( @nType, SIM_PBSTORAGE_SIM )

   nResult       := wce_SimPhonebookStatus( ::hSim, nType, @nTotal, @nUsed )
   ::nLastError  := nResult

   RETURN nResult == SIM_E_OK

METHOD aGetAllPhoneBookEntries( nType ) CLASS wce_Sim

   LOCAL nResult
   LOCAL nTotal
   LOCAL nUsed
   LOCAL aEntry
   LOCAL aEntries
   LOCAL nPos

   IF ! ::lInitialized
      ::nLastError := SIM_E_HB_NOTINITIALIZED
      RETURN .F.
   ENDIF

   hb_default( @nType, SIM_PBSTORAGE_SIM )
   hb_default( @aEntries, {} )

   IF ! ::lNumberOfPhoneBookEntries( nType, @nTotal, @nUsed )
      RETURN {}
   ENDIF

   FOR nPos := 1 TO nUsed
      aEntry := {}
      nResult := wce_SimReadPhonebookEntry( ::hSim, nType, nPos, @aEntry )
      IF nResult != SIM_E_OK
         ::nLastError := nResult
         EXIT
      ELSE
         AAdd( aEntries, aEntry )
      ENDIF
   NEXT

   ::nLastError := nResult

   RETURN aEntries

METHOD lGetSimPhoneEntry( nPos, nType,  aEntry ) CLASS wce_Sim

   LOCAL nResult
   LOCAL a

   IF ! ::lInitialized
      ::nLastError := SIM_E_HB_NOTINITIALIZED
      RETURN .F.
   ENDIF

   hb_default( @nType, SIM_PBSTORAGE_SIM )

   nResult := wce_SimReadPhonebookEntry( ::hSim, nType, nPos, @a )

   aEntry := { a }
   ::nLastError := nResult

   RETURN nResult == SIM_E_OK

METHOD lSetSimPhoneEntry( nPos, nType, cNumber, cName, nPlan, nAddrType ) CLASS wce_Sim

   LOCAL nResult

   IF ! ::lInitialized
      ::nLastError := SIM_E_HB_NOTINITIALIZED
      RETURN .F.
   ENDIF

   hb_default( @nPos, SIM_PBINDEX_FIRSTAVAILABLE )
   hb_default( @nType, SIM_PBSTORAGE_SIM )

   nResult := wce_SimWritePhonebookEntry( ::hSim, nType, nPos, cNumber, cName, nPlan, nAddrType )
   ::nLastError := nResult

   RETURN nResult == SIM_E_OK

METHOD lDelSimPhoneEntry( nPos, nType ) CLASS wce_Sim

   LOCAL nResult

   IF ! ::lInitialized
      ::nLastError := SIM_E_HB_NOTINITIALIZED
      RETURN .F.
   ENDIF

   hb_default( @nType, SIM_PBSTORAGE_SIM )

   nResult := wce_SimDeletePhonebookEntry( ::hSim, nType, nPos )
   ::nLastError := nResult

   RETURN nResult == SIM_E_OK

METHOD End() CLASS wce_Sim

   IF ::lInitialized
      ::lDeInitialize()
   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 this Harbour module: Harbour test program: tests/altd.prg. Contains procedures: Main. This test file tests specific function APIs

[Assistant]
PROCEDURE Main()

   CLS

   AltD( 1 )

   Alert( "debugger enabled",, "GR+/B" )

   AltD()

   Alert( "debugger invoked",, "GR+" )

   Alert( "finished",, "GR+/B,W+/R" )

   RETURN


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

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

[Assistant]
#include "fileio.ch"

#define ERR_WRONG_PARAMETERS  -1
#define ERR_NO_ERROR          0
#define ERR_DRIVE_NOT_READY   1
#define ERR_UNFORMATTED       2
#define ERR_WRITE_PROTECTED   3

FUNCTION ft_FlopTst( nDriveNum )

   LOCAL cFileName
   LOCAL fhnd

   IF HB_ISNUMERIC( nDriveNum )
      cFileName := Chr( Asc( "A" ) + nDriveNum ) + hb_osDriveSeparator()
   ELSEIF HB_ISSTRING( nDriveNum )
      cFileName := nDriveNum
   ELSE
      RETURN ERR_WRONG_PARAMETERS
   ENDIF

   cFileName := hb_DirSepAdd( cFileName ) + "nf$rwtst.tmp"

   IF hb_FileExists( cFileName )
      IF ( fhnd := FOpen( cFileName, FO_DENYNONE + FO_READWRITE ) ) == F_ERROR
         RETURN ERR_WRITE_PROTECTED
      ENDIF
      FClose( fhnd )
   ELSE
      IF ( fhnd := hb_FCreate( cFileName, FC_NORMAL, FO_DENYNONE + FO_READWRITE ) ) == F_ERROR
         RETURN ERR_WRITE_PROTECTED
      ENDIF
      FClose( fhnd )

      FErase( cFileName )
   ENDIF

   RETURN ERR_NO_ERROR


[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 'hbnf' (NanForum Toolkit - legacy Clipper compatibility functions): contrib/hbnf/tests/aeminlen.prg. Contains procedures: Main. This file provides legacy compatibility functions

[Assistant]
#require "hbnf"

PROCEDURE Main()

   LOCAL var0, myarray1 := Directory()

   CLS
   ? "TEST TO DEMONSTRATE EXAMPLES OF FT_AEMINLEN"
   ?
   ? "myarray1 := Directory()"
   ?
   AEval( myarray1, {| v | QOut( PadR( v[ 1 ], 12 ), v[ 2 ], v[ 3 ], v[ 4 ], v[ 5 ] ) } )
   var0 := ft_AEMinLen( myarray1 )
   ? PadR( "ft_AEMinLen( myarray1 ) ->", 30 )
   ?? var0
   ?
   var0 := ft_AEMinLen( myarray1, 2 )
   ? PadR( "ft_AEMinLen( myarray1, 2 ) ->", 30 )
   ?? var0
   ?
   ?
   var0 := ft_AEMinLen( myarray1[ 2 ] )
   ? PadR( "ft_AEMinLen( myarray1[ 2 ] ) ->", 30 )
   ?? var0
   ?
   ?
   var0 := ft_AEMinLen( myarray1, 3 )
   ? PadR( "ft_AEMinLen( myarray1, 3 ) ->", 30 )
   ?? var0
   ?

   RETURN


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

[User] Implement this Harbour module: Harbour test program: tests/box2.prg. Contains procedures: Main. This test file tests specific function APIs

[Assistant]
#include "box.ch"

PROCEDURE Main()

   LOCAL max_row, max_col, boxColor := "W+/B,N/BG", lineColor := "W+/R, N/BG"

   CLS
   max_row := MaxRow()
   max_col := MaxCol()

   DispBox( -10, -10, 10, 10, HB_B_SINGLE_UNI + "X", boxColor )
   DispBox( -10, max_col - 10, 10, max_col + 10, HB_B_SINGLE_UNI + "X", boxColor )
   DispBox( max_row - 10, - 10, max_row + 10, 10, HB_B_SINGLE_UNI + "X", boxColor )
   DispBox( max_row - 10, max_col - 10, max_row + 10, max_col + 10, HB_B_SINGLE_UNI + "X", boxColor )

   DispBox( -15, -15, 15, 15, 1, boxColor )
   DispBox( -15, max_col - 15, 15, max_col + 15, 1, boxColor )
   DispBox( max_row - 15, - 15, max_row + 15, 15, 1, boxColor )
   DispBox( max_row - 15, max_col - 15, max_row + 15, max_col + 15, 1, boxColor )

   DispBox( 20, 20, 25, 60, 2, boxColor )
   DispBox( -10, -10, -1, -1, 2, boxColor )
   DispBox( max_row + 1, max_col + 1, max_row + 10, max_col + 10, 2, boxColor )

   DispBox( 1, -10, 1, 10, HB_B_SINGLE_UNI, lineColor )
   DispBox( 2, -10, 2, max_col + 10, HB_B_DOUBLE_UNI, lineColor )
   DispBox( 3, max_col - 10, 3, max_col + 10, HB_B_SINGLE_UNI, lineColor )

   DispBox( -10, 1, 10, 1, HB_B_SINGLE_UNI, lineColor )
   DispBox( -10, 2, max_row + 10, 2, HB_B_DOUBLE_UNI, lineColor )
   DispBox( max_row - 10, 3, max_row + 10, 3, HB_B_SINGLE_UNI, lineColor )

   Inkey( 5 )

   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:

Header file for contribution module 'xhb' (Extended Harbour functions): contrib/xhb/hbcommon.ch. Defines constants: HB_HBCOMMON_CH_, HB_FILE_VER(, HB_FILE_VER(. Defines Harbour internal constants and macros

[Assistant]
#ifndef HB_HBCOMMON_CH_
#define HB_HBCOMMON_CH_

#include "hbsetup.ch"

#ifdef HB_FILE_VER_STATIC
   #define HB_FILE_VER( id ) STATIC s_hb_file_ver := id
#else
   #define HB_FILE_VER( id )
#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]
Here is a Harbour (xBase/Clipper) implementation:

Harbour header file: include/error.ch. Defines 10 constants including: _ERROR_CH, ES_WHOCARES, ES_WARNING, ES_ERROR, ES_CATASTROPHIC. Defines error handling constants and codes

[Assistant]
#ifndef _ERROR_CH
#define _ERROR_CH

#define ES_WHOCARES     0
#define ES_WARNING      1
#define ES_ERROR        2
#define ES_CATASTROPHIC 3

#define EG_ARG          1
#define EG_BOUND        2
#define EG_STROVERFLOW  3
#define EG_NUMOVERFLOW  4
#define EG_ZERODIV      5
#define EG_NUMERR       6
#define EG_SYNTAX       7
#define EG_COMPLEXITY   8

#define EG_MEM          11
#define EG_NOFUNC       12
#define EG_NOMETHOD     13
#define EG_NOVAR        14
#define EG_NOALIAS      15
#define EG_NOVARMETHOD  16
#define EG_BADALIAS     17
#define EG_DUPALIAS     18

#define EG_CREATE       20
#define EG_OPEN         21
#define EG_CLOSE        22
#define EG_READ         23
#define EG_WRITE        24
#define EG_PRINT        25

#define EG_UNSUPPORTED  30
#define EG_LIMIT        31
#define EG_CORRUPTION   32
#define EG_DATATYPE     33
#define EG_DATAWIDTH    34
#define EG_NOTABLE      35
#define EG_NOORDER      36
#define EG_SHARED       37
#define EG_UNLOCKED     38
#define EG_READONLY     39

#define EG_APPENDLOCK   40
#define EG_LOCK         41

#define EG_DESTRUCTOR   45
#define EG_ARRACCESS    46
#define EG_ARRASSIGN    47
#define EG_ARRDIMENSION 48
#define EG_NOTARRAY     49
#define EG_CONDITION    50

#define HB_EI_ERRUNRECOV        9000
#define HB_EI_ERRRECFAILURE     9001
#define HB_EI_ERRNOBLOCK        9002
#define HB_EI_ERRTOOMANY        9003
#define HB_EI_RDDINVALID        9004
#define HB_EI_CLSINVMETHOD      9005
#define HB_EI_XGRABALLOC        9006
#define HB_EI_XREALLOCNULL      9007
#define HB_EI_XREALLOCINV       9008
#define HB_EI_XREALLOC          9009
#define HB_EI_XFREEINV          9010
#define HB_EI_XFREENULL         9011
#define HB_EI_VMBADSTARTUP      9012
#define HB_EI_VMNOSTARTUP       9013
#define HB_EI_VMBADOPCODE       9014
#define HB_EI_VMNOTSYMBOL       9015
#define HB_EI_VMINVSYMBOL       9016
#define HB_EI_VMNOTCBLOCK       9017
#define HB_EI_VMPOPINVITEM      9018
#define HB_EI_STACKUFLOW        9019
#define HB_EI_ITEMBADCOPY       9020
#define HB_EI_MVBADSYMBOL       9021
#define HB_EI_XMEMOVERFLOW      9022
#define HB_EI_XGRABNULLSIZE     9023
#define HB_EI_XREALLOCNULLSIZE  9024
#define HB_EI_XALLOCNULLSIZE    9025

#define HB_EI_COMPBADOPCODE     9100
#define HB_EI_COMPBADOPSIZE     9101

#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 these Harbour functions: Harbour Runtime Library file: src/rtl/cdpdet.prg. Provides 6 functions including: hb_cdpTerm, hb_cdpOS, __CPWinToCPStd, __UnixParseLangCP, __CPStdToHb. This file provides utility functions

[Assistant]
#include "hbextcdp.ch"

FUNCTION hb_cdpTerm()

   LOCAL cCP
   LOCAL cLang

#if defined( __PLATFORM__WINDOWS )
   LOCAL tmp
   cCP := __CPWinToCPStd( iif( ( tmp := __wapi_GetConsoleOutputCP() ) == 0, __wapi_GetOEMCP(), tmp ) )
   cLang := hb_UserLang()
#elif defined( __PLATFORM__UNIX )
   LOCAL tmp
   cCP := __UnixParseLangCP( iif( Empty( tmp := GetEnv( "LANG" ) ), ;
                                  GetEnv( "LC_CTYPE" ), tmp ), @cLang )
#elif defined( __PLATFORM__DOS )

   cCP := cLang := NIL
#elif defined( __PLATFORM__OS2 )

   cCP := cLang := NIL
#endif

   RETURN __CPStdToHb( cCP, cLang )

FUNCTION hb_cdpOS()

   LOCAL cCP
   LOCAL cLang

#if defined( __PLATFORM__WINDOWS )
   cCP := __CPWinToCPStd( __wapi_GetACP() )
   cLang := hb_UserLang()
#elif defined( __PLATFORM__UNIX )
   LOCAL tmp
   cCP := __UnixParseLangCP( iif( Empty( tmp := GetEnv( "LANG" ) ), ;
                                  GetEnv( "LC_CTYPE" ), tmp ), @cLang )
#elif defined( __PLATFORM__DOS )

   cCP := cLang := NIL
#elif defined( __PLATFORM__OS2 )

   cCP := cLang := NIL
#endif

   RETURN __CPStdToHb( cCP, cLang )

#if defined( __PLATFORM__WINDOWS )
STATIC FUNCTION __CPWinToCPStd( nCPWin )

   SWITCH nCPWin
   CASE 65001 ; RETURN "utf8"
   CASE 1200  ; RETURN "utf16"
   CASE 437
   CASE 737
   CASE 775
   CASE 850
   CASE 852
   CASE 855
   CASE 856
   CASE 857
   CASE 858
   CASE 860
   CASE 861
   CASE 862
   CASE 863
   CASE 864
   CASE 865
   CASE 866
   CASE 869
   CASE 874
   CASE 1250
   CASE 1251
   CASE 1252
   CASE 1253
   CASE 1254
   CASE 1255
   CASE 1256
   CASE 1257
   CASE 1258  ; RETURN "cp" + hb_ntos( nCPWin )
   CASE 28591
   CASE 28592
   CASE 28593
   CASE 28594
   CASE 28595
   CASE 28596
   CASE 28597
   CASE 28598
   CASE 28599
   CASE 28603
   CASE 28605 ; RETURN "iso8859-" + hb_ntos( nCPWin - 28590 )
   CASE 20866 ; RETURN "koi-8"
   CASE 21866 ; RETURN "koi-8u"
   CASE 936   ; RETURN "GBK"
   CASE 950   ; RETURN "CP950"
   ENDSWITCH

   RETURN NIL

#elif defined( __PLATFORM__UNIX )

STATIC FUNCTION __UnixParseLangCP( cString,  cLang )

   LOCAL tmp
   LOCAL cCP

   IF ( tmp := At( ".", cString ) ) > 0
      cLang := Left( cString, tmp - 1 )
      cCP := SubStr( cString, tmp + 1 )
      IF ( tmp := At( "@", cString ) ) > 0
         cCP := Left( cString, tmp - 1 )
      ENDIF
   ELSE
      cLang := cString
      cCP := "UTF-8"
   ENDIF

   cCP := hb_StrReplace( Lower( cCP ), { "_" => "", "-" => "", "ibm" => "cp", "windows" => "cp" } )
   IF hb_LeftEq( cCP, "iso8859" )
      cCP := Stuff( cCP, Len( "iso8859" ) + 1, 0, "-" )
   ENDIF

   SWITCH cCP
   CASE "utf8"
   CASE "cp437"
   CASE "cp737"
   CASE "cp775"
   CASE "cp850"
   CASE "cp852"
   CASE "cp855"
   CASE "cp856"
   CASE "cp857"
   CASE "cp858"
   CASE "cp860"
   CASE "cp861"
   CASE "cp862"
   CASE "cp863"
   CASE "cp864"
   CASE "cp865"
   CASE "cp866"
   CASE "cp869"
   CASE "cp874"
   CASE "cp1250"
   CASE "cp1251"
   CASE "cp1252"
   CASE "cp1253"
   CASE "cp1254"
   CASE "cp1255"
   CASE "cp1256"
   CASE "cp1257"
   CASE "cp1258"
   CASE "iso8859-1"
   CASE "iso8859-2"
   CASE "iso8859-3"
   CASE "iso8859-4"
   CASE "iso8859-5"
   CASE "iso8859-6"
   CASE "iso8859-7"
   CASE "iso8859-8"
   CASE "iso8859-9"
   CASE "iso8859-13"
   CASE "iso8859-15" ; RETURN cCP
   CASE "koi8r"      ; RETURN "koi-8"
   CASE "koi8u"      ; RETURN "koi-8u"
   CASE "gbk"        ; RETURN "GBK"
   CASE "big5"       ; RETURN "BIG5"
   ENDSWITCH

   RETURN NIL

#endif

STATIC FUNCTION __CPStdToHb( cCPStd, cCtryStd )

   LOCAL cCtryHb
   LOCAL cdp
   LOCAL aCP

   IF cCPStd != NIL
      SWITCH cCPStd := Lower( cCPStd )
      CASE "utf8"
         RETURN "UTF8"
      CASE "utf16"
         RETURN "UTF16LE"
      OTHERWISE
         aCP := hb_cdpList()
         cCtryHb := __LangStdToCPCtryHb( cCtryStd )
         FOR EACH cdp IN aCP
            IF hb_LeftEq( cdp, cCtryHb ) .AND. cCPStd == hb_cdpUniID( cdp )
               RETURN cdp
            ENDIF
         NEXT
         FOR EACH cdp IN aCP
            IF cCPStd == hb_cdpUniID( cdp )
               RETURN hb_cdpUniID( cdp )
            ENDIF
         NEXT
      ENDSWITCH
   ENDIF

   RETURN NIL

STATIC FUNCTION __LangStdToCPCtryHb( cCtryStd )

   SWITCH Lower( cCtryStd )
   CASE "bg-bg"
   CASE "bg"         ; RETURN "BG"
   CASE "cs-cz"
   CASE "cs"         ; RETURN "CS"
   CASE "da-dk"
   CASE "da"         ; RETURN "DK"
   CASE "de-at"
   CASE "de-ch"
   CASE "de-de"
   CASE "de-li"
   CASE "de-lu"
   CASE "de"         ; RETURN "DE"
   CASE "el-gr"
   CASE "el"         ; RETURN "EL"
   CASE "en-au"
   CASE "en-bz"
   CASE "en-ca"
   CASE "en-cb"
   CASE "en-gb"
   CASE "en-ie"
   CASE "en-jm"
   CASE "en-nz"
   CASE "en-ph"
   CASE "en-tt"
   CASE "en-us"
   CASE "en-za"
   CASE "en-zw"
   CASE "en"         ; RETURN "EN"
   CASE "es-419"
   CASE "es-ar"
   CASE "es-bo"
   CASE "es-cl"
   CASE "es-co"
   CASE "es-cr"
   CASE "es-do"
   CASE "es-ec"
   CASE "es-es"
   CASE "es-gt"
   CASE "es-hn"
   CASE "es-mx"
   CASE "es-ni"
   CASE "es-pa"
   CASE "es-pe"
   CASE "es-pr"
   CASE "es-py"
   CASE "es-sv"
   CASE "es-uy"
   CASE "es-ve"
   CASE "es"         ; RETURN "ES"
   CASE "fi-fi"
   CASE "fi"         ; RETURN "FI"
   CASE "fr-be"
   CASE "fr-ca"
   CASE "fr-ch"
   CASE "fr-fr"
   CASE "fr-lu"
   CASE "fr-mc"
   CASE "fr"         ; RETURN "FR"
   CASE "he-il"
   CASE "he"         ; RETURN "HE"
   CASE "hr-hr"
   CASE "hr"         ; RETURN "HR"
   CASE "hu-hu"
   CASE "hu"         ; RETURN "HU"
   CASE "is-is"
   CASE "is"         ; RETURN "IS"
   CASE "it-ch"
   CASE "it-it"
   CASE "it"         ; RETURN "IT"
   CASE "lt-lt"
   CASE "lt"         ; RETURN "LT"
   CASE "nl-be"
   CASE "nl-nl"
   CASE "nl"         ; RETURN "NL"
   CASE "no"         ; RETURN "NO"
   CASE "pl-pl"
   CASE "pl"         ; RETURN "PL"
   CASE "pt-br"
   CASE "pt-pt"
   CASE "pt"         ; RETURN "PT"
   CASE "ro-ro"
   CASE "ro"         ; RETURN "RO"
   CASE "ru-ru"
   CASE "ru"         ; RETURN "RU"
   CASE "sk-sk"
   CASE "sk"         ; RETURN "SK"
   CASE "sl-si"
   CASE "sl"         ; RETURN "SL"
   CASE "sr-sp-cyrl"
   CASE "sr-sp-latn" ; RETURN "SR"
   CASE "sv-fi"
   CASE "sv-se"
   CASE "sv"         ; RETURN "SV"
   CASE "tr-tr"
   CASE "tr"         ; RETURN "TR"
   CASE "uk-ua"
   CASE "uk"         ; RETURN "UA"
   ENDSWITCH

   RETURN Left( hb_cdpSelect(), 2 )


[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/varparam.prg. Contains 14 procedures. This test file tests specific function APIs

[Assistant]
MEMVAR m_iLoop

PROCEDURE Main()

   LOCAL l1 := 11, l2 := 22, l3 := 33, l4 := 44, l5 := 55, l6 := 66
   PRIVATE m_iLoop

   ? "passed 0:  "; TEST_0_0()
   ? "passed 1:  "; TEST_0_0( 1 )
   ? "passed 2:  "; TEST_0_0( 1, 2 )
   ? "passed 3:  "; TEST_0_0( 1, 2, 3 )

   ? "---------------------------------------"
   ? "passed 0:  "; TEST_0_0v()
   ? "passed 1:  "; TEST_0_0v( 1 )
   ? "passed 2:  "; TEST_0_0v( 1, 2 )
   ? "passed 3:  "; TEST_0_0v( 1, 2, 3 )

   ? "---------------------------------------"
   ? "passed 0:  "; TEST_1_0()
   ? "passed 1:  "; TEST_1_0( 1 )
   ? "passed 2:  "; TEST_1_0( 1, 2 )
   ? "passed 3:  "; TEST_1_0( 1, 2, 3 )

   ? "---------------------------------------"
   ? "passed 0:  "; TEST_1_0v()
   ? "passed 1:  "; TEST_1_0v( 1 )
   ? "passed 2:  "; TEST_1_0v( 1, 2 )
   ? "passed 3:  "; TEST_1_0v( 1, 2, 3 )

   ? "---------------------------------------"
   ? "passed 0:  "; TEST_1_1()
   ? "passed 1:  "; TEST_1_1( 1 )
   ? "passed 2:  "; TEST_1_1( 1, 2 )
   ? "passed 3:  "; TEST_1_1( 1, 2, 3 )

   ? "---------------------------------------"
   ? "passed 0:  "; TEST_1_1v()
   ? "passed 1:  "; TEST_1_1v( 1 )
   ? "passed 2:  "; TEST_1_1v( 1, 2 )
   ? "passed 3:  "; TEST_1_1v( 1, 2, 3 )

   ? "---------------------------------------"
   ? "passed 0:  "; TEST_1_3()
   ? "passed 1:  "; TEST_1_3( 1 )
   ? "passed 2:  "; TEST_1_3( 1, 2 )
   ? "passed 3:  "; TEST_1_3( 1, 2, 3 )
   ? "passed 4:  "; TEST_1_3( 1, 2, 3, 4 )
   ? "passed 5:  "; TEST_1_3( 1, 2, 3, 4, 5 )
   ? "passed 6:  "; TEST_1_3( 1, 2, 3, 4, 5, 6 )

   ? "---------------------------------------"
   ? "passed 0:  "; TEST_1_3v()
   ? "passed 1:  "; TEST_1_3v( 1 )
   ? "passed 2:  "; TEST_1_3v( 1, 2 )
   ? "passed 3:  "; TEST_1_3v( 1, 2, 3 )
   ? "passed 4:  "; TEST_1_3v( 1, 2, 3, 4 )
   ? "passed 5:  "; TEST_1_3v( 1, 2, 3, 4, 5 )
   ? "passed 6:  "; TEST_1_3v( 1, 2, 3, 4, 5, 6 )

   ? "---------------------------------------"
   ? "passed 0:  "; TEST_3_0()
   ? "passed 1:  "; TEST_3_0( 1 )
   ? "passed 2:  "; TEST_3_0( 1, 2 )
   ? "passed 3:  "; TEST_3_0( 1, 2, 3 )
   ? "passed 4:  "; TEST_3_0( 1, 2, 3, 4 )
   ? "passed 5:  "; TEST_3_0( 1, 2, 3, 4, 5 )
   ? "passed 6:  "; TEST_3_0( 1, 2, 3, 4, 5, 6 )

   ? "---------------------------------------"
   ? "passed 0:  "; TEST_3_0v()
   ? "passed 1:  "; TEST_3_0v( 1 )
   ? "passed 2:  "; TEST_3_0v( 1, 2 )
   ? "passed 3:  "; TEST_3_0v( 1, 2, 3 )
   ? "passed 4:  "; TEST_3_0v( 1, 2, 3, 4 )
   ? "passed 5:  "; TEST_3_0v( 1, 2, 3, 4, 5 )
   ? "passed 6:  "; TEST_3_0v( 1, 2, 3, 4, 5, 6 )

   ? "---------------------------------------"
   ? "passed 0:  "; TEST_3_3()
   ? "passed 1:  "; TEST_3_3( 1 )
   ? "passed 2:  "; TEST_3_3( 1, 2 )
   ? "passed 3:  "; TEST_3_3( 1, 2, 3 )
   ? "passed 4:  "; TEST_3_3( 1, 2, 3, 4 )
   ? "passed 5:  "; TEST_3_3( 1, 2, 3, 4, 5 )
   ? "passed 6:  "; TEST_3_3( 1, 2, 3, 4, 5, 6 )

   ? "---------------------------------------"
   ? "passed 0:  "; TEST_3_3v()
   ? "passed 1:  "; TEST_3_3v( 1 )
   ? "passed 2:  "; TEST_3_3v( 1, 2 )
   ? "passed 3:  "; TEST_3_3v( 1, 2, 3 )
   ? "passed 4:  "; TEST_3_3v( 1, 2, 3, 4 )
   ? "passed 5:  "; TEST_3_3v( 1, 2, 3, 4, 5 )
   ? "passed 6:  "; TEST_3_3v( 1, 2, 3, 4, 5, 6 )

   ? "---------------------------------------"
   ? "Passed 6 by ref:  "; TEST_0_0( @l1, @l2, @l3, @l4, @l5, @l6 )
   ? "Passed 6 by ref:  "; TEST_0_0v( @l1, @l2, @l3, @l4, @l5, @l6 )

   ? "---------------------------------------"
   ? "Passed 6 by ref:  "; TEST_1_0( @l1, @l2, @l3, @l4, @l5, @l6 )
   ? "Passed 6 by ref:  "; TEST_1_0v( @l1, @l2, @l3, @l4, @l5, @l6 )

   ? "---------------------------------------"
   ? "Passed 6 by ref:  "; TEST_1_1( @l1, @l2, @l3, @l4, @l5, @l6 )
   ? "Passed 6 by ref:  "; TEST_1_1v( @l1, @l2, @l3, @l4, @l5, @l6 )

   ? "---------------------------------------"
   ? "Passed 6 by ref:  "; TEST_1_3( @l1, @l2, @l3, @l4, @l5, @l6 )
   ? "Passed 6 by ref:  "; TEST_1_3v( @l1, @l2, @l3, @l4, @l5, @l6 )

   ? "---------------------------------------"
   ? "Passed 6 by ref:  "; TEST_3_0( @l1, @l2, @l3, @l4, @l5, @l6 )
   ? "Passed 6 by ref:  "; TEST_3_0v( @l1, @l2, @l3, @l4, @l5, @l6 )

   ? "---------------------------------------"
   ? "Passed 6 by ref:  "; TEST_3_3( @l1, @l2, @l3, @l4, @l5, @l6 )
   ? "Passed 6 by ref:  "; TEST_3_3v( @l1, @l2, @l3, @l4, @l5, @l6 )

   RETURN

PROCEDURE TEST_0_0v( ... )

   ?? ProcName( 0 ), " received: ", PCount()
   FOR m_iLoop := 1 TO PCount()
      ? m_iLoop, "=", hb_PValue( m_iLoop )
   NEXT

   Inkey( 0 )

   RETURN

PROCEDURE TEST_0_0()

   ?? ProcName( 0 ), " received: ", PCount()
   FOR m_iLoop := 1 TO PCount()
      ? m_iLoop, "=", hb_PValue( m_iLoop )
   NEXT

   Inkey( 0 )

   RETURN

PROCEDURE TEST_1_0v( ... )

   LOCAL i := "i"

   ?? ProcName( 0 ), " received: ", PCount()
   ? "i=", i
   FOR i := 1 TO PCount()
      ? i, "=", hb_PValue( i )
   NEXT

   Inkey( 0 )

   RETURN

PROCEDURE TEST_1_0()

   LOCAL i := "i"

   ?? ProcName( 0 ), " received: ", PCount()
   ? "i=", i
   FOR i := 1 TO PCount()
      ? i, "=", hb_PValue( i )
   NEXT

   Inkey( 0 )

   RETURN

PROCEDURE TEST_1_3v( a, b, c, ... )

   LOCAL i := "i"

   ?? ProcName( 0 ), " received: ", PCount()
   ? "i=", i
   ? "a=", a
   ? "b=", b
   ? "c=", c
   FOR i := 1 TO PCount()
      ? i, "=", hb_PValue( i )
   NEXT

   FOR EACH i IN hb_AParams()
      ? i:__enumindex, "-", i
   NEXT

   Inkey( 0 )

   RETURN

PROCEDURE TEST_1_3( a, b, c )

   LOCAL i := "i"

   ?? ProcName( 0 ), " received: ", PCount()
   ? "i=", i
   ? "a=", a
   ? "b=", b
   ? "c=", c
   FOR i := 1 TO PCount()
      ? i, "=", hb_PValue( i )
   NEXT

   FOR EACH i IN hb_AParams()
      ? i:__enumindex, "-", i
   NEXT

   Inkey( 0 )

   RETURN

PROCEDURE TEST_1_1( a )

   LOCAL i := "i"

   ?? ProcName( 0 ), " received: ", PCount()
   ? "i=", i
   ? "a=", a
   FOR i := 1 TO PCount()
      ? i, "=", hb_PValue( i )
   NEXT

   Inkey( 0 )

   RETURN

PROCEDURE TEST_1_1v( a, ... )

   LOCAL i := "i"

   ?? ProcName( 0 ), " received: ", PCount()
   ? "i=", i
   ? "a=", a
   FOR i := 1 TO PCount()
      ? i, "=", hb_PValue( i )
   NEXT

   Inkey( 0 )

   RETURN

PROCEDURE TEST_3_3v( a, b, c, ... )

   LOCAL x := "x", y := "y", z := "z"

   ?? ProcName( 0 ), " received: ", PCount()
   ? "x=", x
   ? "y=", y
   ? "z=", z
   ? "a=", a
   ? "b=", b
   ? "c=", c
   FOR m_iLoop := 1 TO PCount()
      ? m_iLoop, "=", hb_PValue( m_iLoop )
   NEXT

   test_ref( @a, @b, @c, @x, @y, @z )

   Inkey( 0 )

   RETURN

PROCEDURE TEST_3_3( a, b, c )

   LOCAL x := "x", y := "y", z := "z"

   ?? ProcName( 0 ), " received: ", PCount()
   ? "x=", x
   ? "y=", y
   ? "z=", z
   ? "a=", a
   ? "b=", b
   ? "c=", c
   FOR m_iLoop := 1 TO PCount()
      ? m_iLoop, "=", hb_PValue( m_iLoop )
   NEXT

   test_ref( @a, @b, @c, @x, @y, @z )

   Inkey( 0 )

   RETURN

PROCEDURE TEST_3_0()

   LOCAL x := "x", y := "y", z := "z"

   ?? ProcName( 0 ), " received: ", PCount()
   ? "x=", x
   ? "y=", y
   ? "z=", z
   FOR m_iLoop := 1 TO PCount()
      ? m_iLoop, "=", hb_PValue( m_iLoop )
   NEXT

   Inkey( 0 )

   RETURN

PROCEDURE TEST_3_0v( ... )

   LOCAL x := "x", y := "y", z := "z"

   ?? ProcName( 0 ), " received: ", PCount()
   ? "x=", x
   ? "y=", y
   ? "z=", z
   FOR m_iLoop := 1 TO PCount()
      ? m_iLoop, "=", hb_PValue( m_iLoop )
   NEXT

   Inkey( 0 )

   RETURN

PROCEDURE TEST_REF( a, ... )

   LOCAL b

   ? "@@@"
   ? ProcName( 0 ), " received: ", PCount()
   ? "a= ", a
   ? "b= ", b
   FOR EACH b IN hb_AParams( 0 )
      ? b:__enumindex, "-", b
   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] Generate Harbour code for: Harbour Runtime Library file: src/rtl/objfunc.prg. Provides 16 functions including: __objHasData, __objHasMethod, __objGetMsgList, __objGetMethodList, __objGetValueList. This file provides utility functions

[Assistant]
#include "error.ch"
#include "hboo.ch"

FUNCTION __objHasData( oObject, cSymbol )

   IF ! HB_ISOBJECT( oObject ) .OR. ! HB_ISSTRING( cSymbol )
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ENDIF

   RETURN ;
      __objHasMsg( oObject, cSymbol ) .AND. ;
      __objHasMsg( oObject, "_" + cSymbol )

FUNCTION __objHasMethod( oObject, cSymbol )

   IF ! HB_ISOBJECT( oObject ) .OR. ! HB_ISSTRING( cSymbol )
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ENDIF

   RETURN ;
      __objHasMsg( oObject, cSymbol ) .AND. ;
      ! __objHasMsg( oObject, "_" + cSymbol )

FUNCTION __objGetMsgList( oObject, lDataMethod, nClassType )

   LOCAL aInfo
   LOCAL aData
   LOCAL cName
   LOCAL nFirst

   IF ! HB_ISOBJECT( oObject )
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ENDIF

   hb_default( @lDataMethod, .T. )

   aInfo := oObject:ClassSel( hb_defaultValue( nClasstype, HB_MSGLISTALL ) )
   aData := {}
   nFirst := AScan( aInfo, {| n | hb_LeftEq( n, "_" ) } )

   FOR EACH cName IN aInfo

      IF ! hb_LeftEq( cName, "_" )

         IF ( AScan( aInfo, {| tmp | tmp == ( "_" + cName ) }, nFirst ) > 0 ) == lDataMethod
            AAdd( aData, cName )
         ENDIF
      ENDIF
   NEXT

   RETURN aData

FUNCTION __objGetMethodList( oObject )

   IF ! HB_ISOBJECT( oObject )
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ENDIF

   RETURN __objGetMsgList( oObject, .F. )

FUNCTION __objGetValueList( oObject, aExcept )

   LOCAL aData
   LOCAL cSymbol

   IF ! HB_ISOBJECT( oObject )
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ENDIF

   hb_default( @aExcept, {} )

   aData := {}
   FOR EACH cSymbol IN __objGetMsgList( oObject )
      IF hb_AScan( aExcept, cSymbol,,, .T. ) == 0
         AAdd( aData, { cSymbol, __objSendMsg( oObject, cSymbol ) } )
      ENDIF
   NEXT

   RETURN aData

FUNCTION __objSetValueList( oObject, aData )

   IF HB_ISOBJECT( oObject )
      AEval( aData, {| aItem | __objSendMsg( oObject, "_" + aItem[ HB_OO_DATA_SYMBOL ], aItem[ HB_OO_DATA_VALUE ] ) } )
   ELSE
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ENDIF

   RETURN oObject

FUNCTION __objAddMethod( oObject, cSymbol, nFuncPtr )

   IF ! HB_ISOBJECT( oObject ) .OR. ! HB_ISSTRING( cSymbol ) .OR. ! HB_ISSYMBOL( nFuncPtr )
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ELSEIF ! __objHasMsg( oObject, cSymbol )
      __clsAddMsg( oObject:ClassH, cSymbol, nFuncPtr, HB_OO_MSG_METHOD, , 1 )
   ENDIF

   RETURN oObject

FUNCTION __objAddInline( oObject, cSymbol, bInline )

   IF ! HB_ISOBJECT( oObject ) .OR. ! HB_ISSTRING( cSymbol )
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ELSEIF ! __objHasMsg( oObject, cSymbol )
      __clsAddMsg( oObject:ClassH, cSymbol, bInline, HB_OO_MSG_INLINE, , 1 )
   ENDIF

   RETURN oObject

FUNCTION __objAddData( oObject, cSymbol )

   LOCAL nSeq, hClass

   IF ! HB_ISOBJECT( oObject ) .OR. ! HB_ISSTRING( cSymbol )
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ELSEIF ! __objHasMsg( oObject, cSymbol ) .AND. ! __objHasMsg( oObject, "_" + cSymbol )
      hClass := oObject:ClassH
      nSeq   := __cls_IncData( hClass )
      __clsAddMsg( hClass,       cSymbol, nSeq, HB_OO_MSG_ACCESS, , 1 )
      __clsAddMsg( hClass, "_" + cSymbol, nSeq, HB_OO_MSG_ASSIGN, , 1 )
   ENDIF

   RETURN oObject

FUNCTION __objModMethod( oObject, cSymbol, nFuncPtr )

   IF ! HB_ISOBJECT( oObject ) .OR. ! HB_ISSTRING( cSymbol ) .OR. ! HB_ISSYMBOL( nFuncPtr )
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ELSEIF __objHasMethod( oObject, cSymbol )
      __clsModMsg( oObject:ClassH, cSymbol, nFuncPtr )
   ENDIF

   RETURN oObject

FUNCTION __objModInline( oObject, cSymbol, bInline )

   IF ! HB_ISOBJECT( oObject ) .OR. ! HB_ISSTRING( cSymbol ) .OR. ! HB_ISBLOCK( bInline )
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ELSEIF __objHasMethod( oObject, cSymbol )
      __clsModMsg( oObject:ClassH, cSymbol, bInline )
   ENDIF

   RETURN oObject

FUNCTION __objDelMethod( oObject, cSymbol )

   IF ! HB_ISOBJECT( oObject ) .OR. ! HB_ISSTRING( cSymbol )
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ELSEIF __objHasMethod( oObject, cSymbol )
      __clsDelMsg( oObject:ClassH, cSymbol )
   ENDIF

   RETURN oObject

FUNCTION __objDelInline( oObject, cSymbol )
   RETURN __objDelMethod( oObject, cSymbol )

FUNCTION __objDelData( oObject, cSymbol )

   IF ! HB_ISOBJECT( oObject ) .OR. ! HB_ISSTRING( cSymbol )
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ELSEIF __objHasData( oObject, cSymbol )
      __clsDelMsg( oObject:ClassH, cSymbol )
      __clsDelMsg( oObject:ClassH, "_" + cSymbol )
      __cls_DecData( oObject:ClassH )
   ENDIF

   RETURN oObject

FUNCTION __objDerivedFrom( oObject, xSuper )

   LOCAL cClassName

   IF ! HB_ISOBJECT( oObject )
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ENDIF

   DO CASE
   CASE HB_ISOBJECT( xSuper )
      cClassName := xSuper:ClassName()
   CASE HB_ISSTRING( xSuper )
      cClassName := hb_asciiUpper( xSuper )
   OTHERWISE
      __errRT_BASE( EG_ARG, 3101, , ProcName( 0 ) )
   ENDCASE

   RETURN __clsParent( oObject:ClassH, cClassName )

FUNCTION __objGetProperties( oObject, lAllExported )

   LOCAL msg
   LOCAL aMsgList := __clsGetProperties( oObject:classH, lAllExported )

   FOR EACH msg IN aMsgList
      msg := { msg, __objSendMsg( oObject, msg ) }
   NEXT

   RETURN aMsgList


[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 Runtime Library file: src/debug/dbghelp.prg. Provides functions: GetTopics, help_en. Contains 4 procedures. This file provides utility functions

[Assistant]
#pragma -b-

#include "box.ch"
#include "inkey.ch"

PROCEDURE __dbgHelp( cTopic )

   LOCAL cColor := iif( __dbg():lMonoDisplay, "N/W, W/N, W+/W, W+/N", "N/W, N/BG, R/W, R/BG" )
   LOCAL oBrw
   LOCAL nTopic
   LOCAL aTopics := GetTopics()

   LOCAL oDlg := HBDbWindow():New( 2, 2, MaxRow() - 2, MaxCol() - 2, "Help", cColor )

   oBrw := HBDbBrowser():New( oDlg:nTop + 1, oDlg:nLeft + 1, oDlg:nBottom - 1, oDlg:nLeft + 12 )
   oBrw:Cargo := 1
   oBrw:AddColumn( HBDbColumnNew( "", {|| aTopics[ oBrw:Cargo ][ 1 ] }, 12 ) )
   oBrw:ColorSpec := StrTran( __dbg():ClrModal(), ", R/W" )
   oBrw:SkipBlock := {| nSkip, nOld | nOld := oBrw:Cargo, oBrw:Cargo += nSkip, ;
      oBrw:Cargo := Min( Max( oBrw:Cargo, 1 ), Len( aTopics ) ), ;
      oBrw:Cargo - nOld }
   oBrw:GoTopBlock := {|| oBrw:Cargo := 1 }
   oBrw:GoBottomBlock := {|| oBrw:Cargo := Len( aTopics ) }

   IF HB_ISSTRING( cTopic ) .AND. ;
      ( nTopic := AScan( aTopics, {| x | hb_LeftEqI( x[ 1 ], cTopic ) } ) ) > 1
      oBrw:nFirstVisible := nTopic
   ENDIF

   oDlg:bPainted := {|| PaintWindow( oDlg, oBrw, aTopics ) }
   oDlg:bKeyPressed := {| nKey | ProcessKey( nKey, oDlg, oBrw, aTopics, oDlg:cColor ) }

   oDlg:ShowModal()

   RETURN

STATIC PROCEDURE PaintWindow( oDlg, oBrw, aTopics )

   hb_DispBox( oDlg:nTop + 1, oDlg:nLeft + 13, oDlg:nBottom - 1, oDlg:nLeft + 13, HB_B_SINGLE_UNI, oDlg:cColor )
   hb_DispOutAtBox( oDlg:nTop, oDlg:nLeft + 13, hb_UTF8ToStrBox( "┬" ), oDlg:cColor )
   hb_DispOutAtBox( oDlg:nBottom, oDlg:nLeft + 13, hb_UTF8ToStrBox( "┴" ), oDlg:cColor )

   oBrw:ForceStable()
   ShowTopic( oDlg, aTopics, oBrw:Cargo, 0 )

   RETURN

STATIC PROCEDURE ProcessKey( nKey, oDlg, oBrw, aTopics )

   LOCAL n
   LOCAL nSkip

   SWITCH nKey
   CASE K_UP

      IF oBrw:Cargo > 1
         oBrw:Up()
         oBrw:ForceStable()
         ShowTopic( oDlg, aTopics, oBrw:Cargo, 0 )
      ENDIF
      EXIT

   CASE K_DOWN

      IF oBrw:Cargo < Len( aTopics )
         oBrw:Down()
         oBrw:ForceStable()
         ShowTopic( oDlg, aTopics, oBrw:Cargo, 0 )
      ENDIF
      EXIT

   CASE K_HOME

      IF oBrw:Cargo > 1
         oBrw:GoTop()
         oBrw:ForceStable()
         ShowTopic( oDlg, aTopics, oBrw:Cargo, 0 )
      ENDIF
      EXIT

   CASE K_END

      IF oBrw:Cargo < Len( aTopics )
         oBrw:GoBottom()
         oBrw:ForceStable()
         ShowTopic( oDlg, aTopics, oBrw:Cargo, 0 )
      ENDIF
      EXIT

   CASE K_PGUP
   CASE K_CTRL_B

      ShowTopic( oDlg, aTopics, oBrw:Cargo, -1 )
      EXIT

   CASE K_PGDN
   CASE K_SPACE

      ShowTopic( oDlg, aTopics, oBrw:Cargo, 1 )
      EXIT

   CASE K_LBUTTONDOWN

      IF ( nSkip := MRow() - oDlg:nTop - oBrw:RowPos ) != 0
         IF nSkip > 0
            FOR n := 1 TO nSkip
               oBrw:Down()
               oBrw:Stabilize()
            NEXT
         ELSE
            FOR n := 1 TO nSkip + 2 STEP -1
               oBrw:Up()
               oBrw:Stabilize()
            NEXT
         ENDIF
         oBrw:ForceStable()
         ShowTopic( oDlg, aTopics, oBrw:Cargo, 0 )
      ENDIF
      EXIT

   ENDSWITCH

   RETURN

STATIC PROCEDURE ShowTopic( oDlg, aTopics, nTopic, nPageOp )

   LOCAL oDebug := __dbg()
   LOCAL nRows  := oDlg:nBottom - oDlg:nTop - 1
   LOCAL nPages
   LOCAL nRowsToPaint
   LOCAL n

   IF nTopic > Len( aTopics )
      nTopic := 1
   ENDIF

   nPages := Int( ( Len( aTopics[ nTopic ][ 2 ] ) + nRows - 1 ) / nRows )

   IF nPages <= 1
      IF nPageOp == -1 .OR. nPageOp == 1
         RETURN
      ENDIF
      oDebug:nHelpPage := 1
   ELSE
      SWITCH nPageOp
      CASE 0

         oDebug:nHelpPage := 1
         EXIT

      CASE 1

         IF oDebug:nHelpPage < nPages
            oDebug:nHelpPage++
         ELSE
            RETURN
         ENDIF
         EXIT

      CASE -1

         IF oDebug:nHelpPage > 1
            oDebug:nHelpPage--
         ELSE
            RETURN
         ENDIF
         EXIT

      ENDSWITCH
   ENDIF

   hb_Scroll( oDlg:nTop + 1, oDlg:nLeft + 14, oDlg:nBottom - 1, oDlg:nRight - 1,,, oDlg:cColor )

   nRowsToPaint := Min( nRows, Len( aTopics[ nTopic ][ 2 ] ) - ( ( oDebug:nHelpPage - 1 )
   hb_DispOutAt( oDlg:nBottom, oDlg:nRight - 16, " Page " + Str( oDebug:nHelpPage, 1 ) + " of " + Str( nPages, 1 ) + " ", oDlg:cColor )

   RETURN

STATIC FUNCTION GetTopics()

   LOCAL aTopics := {}
   LOCAL cLine

   FOR EACH cLine IN hb_ATokens( help_en(), .T. )
      IF hb_LeftEq( cLine, "--" )
         AAdd( aTopics, { PadR( SubStr( cLine, Len( "--" ) + 1 ), 12 ), {} } )
      ELSEIF ! Empty( aTopics ) .AND. ;
         ( ! Empty( cLine ) .OR. ! cLine:__enumIsLast() )
         AAdd( ATail( aTopics )[ 2 ], cLine )
      ENDIF
   NEXT

   RETURN aTopics

STATIC FUNCTION help_en()
   #pragma __streaminclude "en.txt" | RETURN %s


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

[User] Implement this Harbour module: Harbour contribution module 'xhb' (Extended Harbour functions): contrib/xhb/dirrec.prg. Provides functions: DirectoryRecurse. This file provides legacy compatibility functions

[Assistant]
#include "directry.ch"

FUNCTION DirectoryRecurse( cPath, cAttr )

   LOCAL aResult
   LOCAL cFilePath, cExt, cMask

   hb_FNameSplit( cPath, @cFilePath, @cMask, @cExt )
   cMask += cExt
   hb_default( @cAttr, "" )

   aResult := hb_DirScan( cFilePath, cMask, ;
      StrTran( Upper( cAttr ), "D" ) )

   AEval( aResult, {| x | x[ F_NAME ] := cFilePath + x[ F_NAME ] } )

   RETURN aResult


[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 'hbwin' (Windows API wrapper functions): contrib/hbwin/tests/prn1.prg. Contains procedures: Main, PrnTest, PrintBitmap. This file provides platform-specific functionality

[Assistant]
#require "hbwin"

PROCEDURE Main( cPar1 )

   LOCAL nPrn := 1
   LOCAL cBMPFile := Space( 40 )
   LOCAL GetList := {}

   LOCAL aPrn := win_printerList()

   IF Empty( aPrn )
      Alert( "No printers installed - Cannot continue" )
   ELSE
      DO WHILE nPrn != 0
         CLS
         @ 0, 0 SAY "win_Prn() Class test program. Choose a printer to test"
         @ 1, 0 SAY "Bitmap file name:" GET cBMPFile PICT "@K"
         READ
         @ 2, 0 TO MaxRow(), MaxCol()
         nPrn := AChoice( 3, 1, MaxRow() - 1, MaxCol() - 1, aPrn, .T.,, nPrn )
         IF nPrn != 0
            PrnTest( aPrn[ nPrn ], cBMPFile, iif( HB_ISSTRING( cPar1 ) .AND. Lower( cPar1 ) == "ask", .T., NIL ) )
         ENDIF
      ENDDO
   ENDIF

   RETURN

STATIC PROCEDURE PrnTest( cPrinter, cBMPFile, lAsk )

   LOCAL oPrinter := win_Prn():New( cPrinter )
   LOCAL aFonts
   LOCAL x
   LOCAL nColFixed
   LOCAL nColTTF
   LOCAL nColCharSet

   oPrinter:Landscape := .F.
   oPrinter:FormType  := WIN_DMPAPER_A4
   oPrinter:Copies    := 1
   IF HB_ISLOGICAL( lAsk )
      oPrinter:AskProperties := lAsk
   ENDIF

   IF ! oPrinter:Create()
      Alert( "Cannot Create Printer" )
   ELSE
      IF ! oPrinter:startDoc( "win_Prn(Doc name in Printer Properties)" )
         Alert( "StartDoc() failed" )
      ELSE
         oPrinter:SetPen( WIN_PS_SOLID, 1, HB_WIN_RGB_RED )
         oPrinter:Bold( WIN_FW_EXTRABOLD )
         oPrinter:TextOut( oPrinter:PrinterName + ": MaxRow() = " + hb_ntos( oPrinter:MaxRow() ) + "   MaxCol() = " + hb_ntos( oPrinter:MaxCol() ) )
         oPrinter:Bold( WIN_FW_DONTCARE )
         oPrinter:NewLine()
         oPrinter:TextOut( "   Partial list of available fonts that are available for OEM_" )
         oPrinter:NewLine()
         oPrinter:UnderLine( .T. )
         oPrinter:Italic( .T. )

         nColFixed   := 40
         oPrinter:TextOut( "FontName" )
         oPrinter:SetPos( nColFixed )
         oPrinter:TextOut( "Fixed?" )
         oPrinter:SetPos( nColTTF )
         oPrinter:TextOut( "TrueType?" )
         oPrinter:SetPos( nColCharset )
         oPrinter:TextOut( "CharSet#", .T. )
         oPrinter:NewLine()
         oPrinter:Italic( .F. )
         oPrinter:UnderLine( .F. )
         aFonts := oPrinter:GetFonts()
         oPrinter:NewLine()
         FOR x := 1 TO Len( aFonts ) STEP 2
            oPrinter:CharSet( aFonts[ x, 4 ] )
            IF oPrinter:SetFont( aFonts[ x, 1 ] )
               IF oPrinter:FontName == aFonts[ x, 1 ]
                  oPrinter:TextOut( aFonts[ x, 1 ] )
                  oPrinter:SetPos( nColFixed )
                  oPrinter:TextOut( iif( aFonts[ x, 2 ], "Yes", "No" ) )
                  oPrinter:SetPos( nColTTF )
                  oPrinter:TextOut( iif( aFonts[ x, 3 ], "Yes", "No" ) )
                  oPrinter:SetPos( nColCharSet )
                  oPrinter:TextOut( hb_ntos( aFonts[ x, 4 ] ) )
                  oPrinter:SetPos( oPrinter:LeftMargin, oPrinter:PosY + ( oPrinter:CharHeight
         oPrinter:SetFont( "Lucida Console", 8, { 3, -50 } )
         oPrinter:CharSet( 0 )
         oPrinter:Bold( WIN_FW_EXTRABOLD )
         oPrinter:NewLine()
         oPrinter:TextOut( "This is on line" + hb_ntos( oPrinter:PRow() ) + ", Printed bold, " )
         oPrinter:TextOut( " finishing at Column: " )
         oPrinter:TextOut( hb_ntos( oPrinter:PCol() ) )
         oPrinter:SetPRC( oPrinter:PRow() + 3, 0 )
         oPrinter:Bold( WIN_FW_DONTCARE )
         oPrinter:TextOut( "Notice: UNDERLINE only prints correctly if there is a blank line after", .T. )
         oPrinter:TextOut( "        it. This is because of :LineHeight and the next line", .T. )
         oPrinter:TextOut( "        printing over top of the underline. To avoid this happening", .T. )
         oPrinter:TextOut( "        you can to alter :LineHeight or use a smaller font, or use :SetBkMode( WIN_TRANSPARENT )" )
         oPrinter:NewLine()
         oPrinter:NewLine()
         oPrinter:SetFont( "Lucida Console", 18, 0 )
         oPrinter:SetColor( HB_WIN_RGB_GREEN )
         oPrinter:TextOut( "Finally some larger print" )
         oPrinter:Box(   0, oPrinter:PosY + 100, 100, oPrinter:PosY + 200 )
         oPrinter:Arc( 200, oPrinter:PosY + 100, 300, oPrinter:PosY + 200 )
         oPrinter:Ellipse( 400, oPrinter:PosY + 100, 500, oPrinter:PosY + 200 )
         oPrinter:FillRect( 600, oPrinter:PosY + 100, 700, oPrinter:PosY + 200, HB_WIN_RGB_RED )

         PrintBitmap( oPrinter, cBMPFile )

         oPrinter:EndDoc()
      ENDIF
      oPrinter:Destroy()
   ENDIF

   RETURN

STATIC PROCEDURE PrintBitmap( oPrn, cBitFile )

   LOCAL oBMP

   IF ! Empty( cBitFile )
      IF hb_FileExists( cBitFile )
         oBMP := win_BMP():New()
         IF oBmp:loadFile( cBitFile )

            oBmp:Draw( oPrn, { 200, 200, 2000, 1500 } )
         ENDIF
         oBMP:Destroy()
      ELSE
         Alert( hb_StrFormat( "%1$s not found ", cBitFile ) )
      ENDIF
   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 test program: tests/ifelse.prg. Contains procedures: Main, TestValue. This test file exercises basic Harbour language features

[Assistant]
PROCEDURE Main()

   LOCAL i

   ? "Testing Harbour IF ELSEIF ELSE ENDIF"
   FOR i := 1 TO 5
      TestValue( i )
   NEXT

   RETURN

PROCEDURE TestValue( x )

   IF x == 1
      ? "x is 1"

   ELSEIF x == 2
      ? "x is 2"

   ELSEIF x == 3
      ? "x is 3"

   ELSEIF x == 4
      ? "x is 4"

   ELSE
      ? "x is not 1 or 2 or 3 or 4"
   ENDIF

   ? "Ok!"

   RETURN


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

[User] Implement this Harbour module: Harbour contribution module 'hbnf' (NanForum Toolkit - legacy Clipper compatibility functions): contrib/hbnf/linked.prg. Provides functions: ft_Linked. This file provides legacy compatibility functions

[Assistant]
FUNCTION ft_Linked( cFuncs )

   LOCAL aFuncArray := {}, nSpace, nComma, nFEnd, lRetVal := .F.

   IF At( "(", cFuncs ) == 0

      Alert( "Warning: Expected function(s) in ft_Linked(), but none were found" )
   ELSE
      DO WHILE ( nFEnd := At( "(", cFuncs ) ) > 0

         AAdd( aFuncArray, Left( cFuncs, nFEnd ) + ")" )

         cFuncs := SubStr( cFuncs, nFEnd + 1 )
         nSpace := At( " ", cFuncs )
         nComma := At( ",", cFuncs )
         DO WHILE ( nComma > 0 .AND. nComma < nFEnd ) .OR. ;
               ( nSpace > 0 .AND. nSpace < nFEnd )

            IF nComma > 0
               cFuncs := SubStr( cFuncs, nComma + 1 )
            ELSEIF nSpace > 0
               cFuncs := SubStr( cFuncs, nSpace + 1 )
            ENDIF
            nSpace := At( " ", cFuncs )
            nComma := At( ",", cFuncs )
         ENDDO
      ENDDO

      lRetVal := AScan( aFuncArray, {| element | Type( element ) == "U" } ) == 0
   ENDIF

   RETURN lRetVal


[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 extra library: extras/httpsrv/uhttpd.prg. Contains procedures: Main. This file implements server functionality

[Assistant]
#require "hbnf"
#require "hbwin"
#require "hbgd"

#define FIXED_THREADS

#include "fileio.ch"
#include "inkey.ch"
#include "error.ch"
#include "hbmemory.ch"
#include "hbgtinfo.ch"

REQUEST __HB_EXTERN__

#include "hbsocket.ch"

#if defined( HBMK_HAS_HBGD )

REQUEST GDChart
REQUEST GDImage
REQUEST gdImageChar
   #define APP_GD_SUPPORT "_GD"
   #stdout "Lib GD support enabled"
#else
   #define APP_GD_SUPPORT ""
   #stdout "Lib GD support disabled"
#endif

#ifdef FIXED_THREADS
   #define APP_DT_SUPPORT "_FIXED_THREADS"
   #stdout "Fixed # of threads"
#else
   #define APP_DT_SUPPORT ""
   #stdout "Dynamic # of threads"
#endif

#define APP_NAME      "uhttpd"
#define APP_VER_NUM   "0.4.4"
#define APP_VERSION   APP_VER_NUM + APP_GD_SUPPORT + APP_DT_SUPPORT

#define START_RUNNING_THREADS   6
#define MAX_RUNNING_THREADS    20

#define START_SERVICE_THREADS   0
#define MAX_SERVICE_THREADS     3

#define LISTEN_PORT             8082

#define FILE_STOP               ".uhttpd.stop"
#define FILE_ACCESS_LOG         "logs" + hb_ps() + "access.log"
#define FILE_ERROR_LOG          "logs" + hb_ps() + "error.log"
#define DIRECTORYINDEX_ARRAY    { "index.html", "index.htm" }

#define PAGE_STATUS_REFRESH   5
#define THREAD_MAX_WAIT     ( 30 )
#define CGI_MAX_EXEC_TIME     30

#define HRB_ACTIVATE_CACHE   .F.

#define CR_LF    ( Chr( 13 ) + Chr( 10 ) )

#define THREAD_GT hb_gtVersion()

STATIC s_lQuitRequest := .F.

STATIC s_hmtxQueue, s_hmtxServiceThreads, s_hmtxRunningThreads, s_hmtxLog, s_hmtxConsole, s_hmtxBusy
STATIC s_hmtxHRB

STATIC s_hfileLogAccess, s_hfileLogError, s_cApplicationRoot, s_cDocumentRoot, s_lIndexes, s_lConsole, s_nPort
STATIC s_cSessionPath
STATIC s_nThreads, s_nStartThreads, s_nMaxThreads
STATIC s_nServiceThreads, s_nStartServiceThreads, s_nMaxServiceThreads
STATIC s_nConnections, s_nMaxConnections, s_nTotConnections
STATIC s_nServiceConnections, s_nMaxServiceConnections, s_nTotServiceConnections
STATIC s_aRunningThreads := {}
STATIC s_aServiceThreads := {}
STATIC s_hHRBModules     := { => }
STATIC s_aDirectoryIndex

STATIC s_hActions := { ;
   ;
   ;
   "cgi-script"      => @Handler_CgiScript(), ;
   "hrb-script"      => @Handler_HrbScript(), ;
   ;
   "server-status"   => @Handler_ServerStatus() }

STATIC s_hHandlers := { ;
   "hrb"            => "hrb-script", ;
   "exe"            => "cgi-script", ;
   "/serverstatus"  => "server-status" }

STATIC s_hScriptAliases    := { => }
STATIC s_hAliases          := { => }

THREAD STATIC t_cResult, t_nStatusCode,  t_cErrorMsg, t_oSession

MEMVAR _SERVER, _GET, _POST, _COOKIE, _SESSION, _REQUEST, _HTTP_REQUEST, _HTTP_RESPONSE, m_cPost

ANNOUNCE ERRORSYS

PROCEDURE Main( ... )

   LOCAL nPort, hListen, hSocket, aRemote, cI, xVal
   LOCAL aThreads, nStartThreads, nMaxThreads, nStartServiceThreads
   LOCAL i, cPar, lStop
   LOCAL cGT, cApplicationRoot, cDocumentRoot, lIndexes, cConfig
   LOCAL lConsole, lScriptAliasMixedCase, aDirectoryIndex
   LOCAL nProgress := 0
   LOCAL hDefault, cLogAccess, cLogError, cSessionPath
   LOCAL cCmdPort, cCmdApplicationRoot, cCmdDocumentRoot, lCmdIndexes, nCmdStartThreads, nCmdMaxThreads
   LOCAL nConsoleRows, nConsoleCols
   LOCAL nCmdConsoleRows, nCmdConsoleCols

#if defined( __HBSCRIPT__HBSHELL )
   #if defined( __PLATFORM__WINDOWS )
      hbshell_gtSelect( "GTWVT" )
   #endif
#endif

   IF ! hb_mtvm()
      ? "I need multhread support. Please, recompile me!"
      WAIT
      ErrorLevel( 2 )
      RETURN
   ENDIF

   SysSettings()

   ErrorBlock( {| oError | uhttpd_DefError( oError ) } )

   lStop                := .F.
   cConfig              := hb_DirBase() + APP_NAME + ".ini"
   lConsole             := .T.
   nStartServiceThreads := START_SERVICE_THREADS

   cGT := hb_gtVersion()
   IF cGT == "NUL"
      lConsole := .F.
   ENDIF

   i := 1
   DO WHILE i <= PCount()

      cPar := hb_PValue( i++ )

      DO CASE
      CASE cPar == "--port"             .OR. cPar == "-p"
         cCmdPort    := hb_PValue( i++ )

      CASE cPar == "--approot"          .OR. cPar == "-a"
         cCmdApplicationRoot := hb_PValue( i++ )

      CASE cPar == "--docroot"          .OR. cPar == "-d"
         cCmdDocumentRoot := hb_PValue( i++ )

      CASE cPar == "--indexes"          .OR. cPar == "-i"
         lCmdIndexes := .T.

      CASE cPar == "--stop"             .OR. cPar == "-s"
         lStop    := .T.

      CASE cPar == "--config"           .OR. cPar == "-c"
         cConfig     := hb_PValue( i++ )

      CASE cPar == "--start-threads"    .OR. cPar == "-ts"
         nCmdStartThreads := Val( hb_PValue( i++ ) )

      CASE cPar == "--max-threads"      .OR. cPar == "-tm"
         nCmdMaxThreads := Val( hb_PValue( i++ ) )

      CASE cPar == "--console-rows"     .OR. cPar == "-cr"
         nCmdConsoleRows := Val( hb_PValue( i++ ) )

      CASE cPar == "--console-cols"     .OR. cPar == "-cc"
         nCmdConsoleCols := Val( hb_PValue( i++ ) )

      CASE cPar == "--help"             .OR. Lower( cPar ) == "-h" .OR. cPar == "-?"
         Help()
         RETURN

      OTHERWISE
         Help()
         RETURN
      ENDCASE
   ENDDO

   IF lStop
      hb_MemoWrit( FILE_STOP, "" )
      RETURN
   ELSE
      FErase( FILE_STOP )
   ENDIF

   hDefault := ParseIni( cConfig )

   nPort                 := hDefault[ "MAIN" ][ "PORT" ]
   cApplicationRoot      := hDefault[ "MAIN" ][ "APPLICATION_ROOT" ]
   cDocumentRoot         := hDefault[ "MAIN" ][ "DOCUMENT_ROOT" ]
   lIndexes              := hDefault[ "MAIN" ][ "SHOW_INDEXES" ]
   lScriptAliasMixedCase := hDefault[ "MAIN" ][ "SCRIPTALIASMIXEDCASE" ]
   cSessionPath          := hDefault[ "MAIN" ][ "SESSIONPATH" ]
   aDirectoryIndex       := hDefault[ "MAIN" ][ "DIRECTORYINDEX" ]
   nConsoleRows          := hDefault[ "MAIN" ][ "CONSOLE-ROWS" ]
   nConsoleCols          := hDefault[ "MAIN" ][ "CONSOLE-COLS" ]

   cLogAccess            := hDefault[ "LOGFILES" ][ "ACCESS" ]
   cLogError             := hDefault[ "LOGFILES" ][ "ERROR" ]

   nStartThreads         := hDefault[ "THREADS" ][ "START_NUM" ]
   nMaxThreads           := hDefault[ "THREADS" ][ "MAX_NUM" ]

   FOR EACH xVal IN hDefault[ "SCRIPTALIASES" ]
      IF HB_ISSTRING( xVal )
         s_hScriptAliases[ iif( lScriptAliasMixedCase, xVal:__enumKey(), Upper( xVal:__enumKey() ) ) ] := xVal
      ENDIF
   NEXT

   FOR EACH xVal IN hDefault[ "ALIASES" ]
      IF HB_ISSTRING( xVal )
         s_hAliases[ xVal:__enumKey() ] := xVal
      ENDIF
   NEXT

   IF cCmdPort != NIL
      nPort := Val( cCmdPort )
   ENDIF

   IF cCmdApplicationRoot != NIL
      cApplicationRoot := cCmdApplicationRoot
   ENDIF

   IF cCmdDocumentRoot != NIL
      cDocumentRoot := cCmdDocumentRoot
   ENDIF

   IF lCmdIndexes != NIL
      lIndexes := lCmdIndexes
   ENDIF

   IF nCmdStartThreads != NIL
      nStartThreads := nCmdStartThreads
   ENDIF

   IF nCmdMaxThreads != NIL
      nMaxThreads := nCmdMaxThreads
   ENDIF

   IF nCmdConsoleRows != NIL
      nConsoleRows := nCmdConsoleRows
   ENDIF

   IF nCmdConsoleCols != NIL
      nConsoleCols := nCmdConsoleCols
   ENDIF

   cDocumentRoot         := StrTran( cDocumentRoot, "$(APP_DIR)", cApplicationRoot )
   cSessionPath          := StrTran( cSessionPath, "$(APP_DIR)", cApplicationRoot )
   cLogAccess            := StrTran( cLogAccess, "$(APP_DIR)", cApplicationRoot )
   cLogError             := StrTran( cLogError, "$(APP_DIR)", cApplicationRoot )

   IF nPort <= 0 .OR. nPort > 65535
      ? "Invalid port number:", nPort
      WAIT
      ErrorLevel( 1 )
      RETURN
   ENDIF

   IF HB_ISSTRING( cApplicationRoot )
      IF Empty( cApplicationRoot )
         cApplicationRoot := "." + hb_ps()
      ENDIF
      cI := cApplicationRoot
      IF hb_DirExists( cI )
         IF Right( cI, 1 ) == "/" .AND. Len( cI ) > 2 .AND. !( SubStr( cI, Len( cI ) - 2, 1 ) == ":" )
            s_cApplicationRoot := Left( cI, Len( cI ) - 1 )
         ELSE


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

[User] Define Harbour macros and constants: Harbour contribution module 'hbnetio' (Network I/O operations): contrib/hbnetio/tests/netiot03.prg. Provides functions: reg_stream, reg_charstream, rpc_timer, rpc_charstream. Contains procedures: Main, createdb, testdb. This file provides network protocol implementations

[Assistant]
#require "hbnetio"

#define DBSERVER  "127.0.0.1"
#define DBPORT    2941
#define DBPASSWD  "topsecret"
#define DBDIR     "data"
#define DBFILE    "_tst_"

#define DBNAME    "net:" + DBSERVER + ":" + hb_ntos( DBPORT ) + ":" + ;
      DBPASSWD + ":" + DBDIR + "/" + DBFILE

REQUEST DBFCDX

REQUEST hb_DirExists
REQUEST hb_DirCreate
REQUEST hb_DateTime

PROCEDURE Main()

   LOCAL pSockSrv, lExists, nStream1, nStream2, nSec, xData

   SET EXCLUSIVE OFF
   rddSetDefault( "DBFCDX" )

   pSockSrv := netio_MTServer( DBPORT,,,  .T., DBPASSWD )
   IF Empty( pSockSrv )
      ? "Cannot start NETIO server !!!"
      WAIT "Press any key to exit..."
      QUIT
   ENDIF

   ? "NETIO server activated."
   hb_idleSleep( 0.1 )
   WAIT

   ?
   ? "netio_Connect():", netio_Connect( DBSERVER, DBPORT, , DBPASSWD )
   ?

   netio_ProcExec( "QOut", "PROCEXEC", "P2", "P3", "P4" )
   netio_FuncExec( "QOut", "FUNCEXEC", "P2", "P3", "P4" )
   ? "SERVER TIME:", netio_FuncExec( "hb_dateTime" )
   ?
   WAIT

   nStream1 := netio_OpenItemStream( "reg_stream" )
   ? "NETIO_OPENITEMSTREAM:", nStream1
   nStream2 := netio_OpenDataStream( "reg_charstream" )
   ? "NETIO_OPENDATASTREAM:", nStream2

   hb_idleSleep( 3 )
   ? "NETIO_GETDATA 1:", hb_ValToExp( netio_GetData( nStream1 ) )
   ? "NETIO_GETDATA 2:", hb_ValToExp( netio_GetData( nStream2 ) )
   nSec := Seconds() + 3
   WHILE Seconds() < nSec
      xData := netio_GetData( nStream1 )
      IF ! Empty( xData )
         ? hb_ValToExp( xData )
      ENDIF
      xData := netio_GetData( nStream2 )
      IF ! Empty( xData )
         ?? "", hb_ValToExp( xData )
      ENDIF
   ENDDO
   WAIT
   ? "NETIO_GETDATA 1:", hb_ValToExp( netio_GetData( nStream1 ) )
   ? "NETIO_GETDATA 2:", hb_ValToExp( netio_GetData( nStream2 ) )
   WAIT

   lExists := netio_FuncExec( "hb_DirExists", "./data" )
   ? "Directory './data'", iif( lExists, "exists", "not exists" )
   IF ! lExists
      ? "Creating directory './data' ->", ;
         iif( netio_FuncExec( "hb_DirCreate", "./data" ) == -1, "error", "OK" )
   ENDIF

   createdb( DBNAME )
   testdb( DBNAME )
   WAIT

   ?
   ? "table exists:", dbExists( DBNAME )
   WAIT

   ?
   ? "delete table with indexes:", dbDrop( DBNAME )
   ? "table exists:", dbExists( DBNAME )
   WAIT

   ? "NETIO_GETDATA 1:", hb_ValToExp( netio_GetData( nStream1 ) )
   ? "NETIO_GETDATA 2:", hb_ValToExp( netio_GetData( nStream2 ) )
   ? "netio_Disconnect():", netio_Disconnect( DBSERVER, DBPORT )
   ? "NETIO_CLOSESTREAM 1:", netio_CloseStream( nStream1 )
   ? "NETIO_CLOSESTREAM 2:", netio_CloseStream( nStream2 )
   hb_idleSleep( 2 )
   ?
   ? "stopping the server..."
   netio_ServerStop( pSockSrv, .T. )

   RETURN

PROCEDURE createdb( cName )

   LOCAL n

   dbCreate( cName, { ;
      { "F1", "C", 20, 0 }, ;
      { "F2", "M",  4, 0 }, ;
      { "F3", "N", 10, 2 }, ;
      { "F4", "T",  8, 0 } } )
   ? "create neterr:", NetErr(), hb_osError()
   USE ( cName )
   ? "use neterr:", NetErr(), hb_osError()
   WHILE LastRec() < 100
      dbAppend()
      n := RecNo() - 1
      field->F1 := Chr( n % 26 + Asc( "A" ) ) + " " + Time()
      field->F2 := field->F1
      field->F3 := n / 100
      field->F4 := hb_DateTime()
   ENDDO
   INDEX ON field->F1 TAG T1
   INDEX ON field->F3 TAG T3
   INDEX ON field->F4 TAG T4
   CLOSE
   ?

   RETURN

PROCEDURE testdb( cName )

   LOCAL i, j

   USE ( cName )
   ? "used:", Used()
   ? "nterr:", NetErr()
   ? "alias:", Alias()
   ? "lastrec:", LastRec()
   ? "ordCount:", ordCount()
   FOR i := 1 TO ordCount()
      ordSetFocus( i )
      ? i, "name:", ordName(), "key:", ordKey(), "keycount:", ordKeyCount()
   NEXT
   ordSetFocus( 1 )
   dbGoTop()
   WHILE ! Eof()
      IF ! field->F1 == field->F2
         ? "error at record:", RecNo()
         ? "  ! '" + field->F1 + "' == '" + field->F2 + "'"
      ENDIF
      dbSkip()
   ENDDO
   WAIT
   i := Row()
   j := Col()
   dbGoTop()
   Browse()
   SetPos( i, j )
   CLOSE

   RETURN

FUNCTION reg_stream( pConnSock, nStream )

   ? ProcName(), nStream
   hb_threadDetach( hb_threadStart( @rpc_timer(), pConnSock, nStream ) )

   RETURN nStream

FUNCTION reg_charstream( pConnSock, nStream )

   ? ProcName(), nStream
   hb_threadDetach( hb_threadStart( @rpc_charstream(), pConnSock, nStream ) )

   RETURN nStream

STATIC FUNCTION rpc_timer( pConnSock, nStream )

   WHILE .T.
      IF ! netio_SrvSendItem( pConnSock, nStream, Time() )
         ? "CLOSED STREAM:", nStream
         EXIT
      ENDIF
      hb_idleSleep( 1 )
   ENDDO

   RETURN NIL

STATIC FUNCTION rpc_charstream( pConnSock, nStream )

   LOCAL n := 0

   WHILE .T.
      IF ! netio_SrvSendData( pConnSock, nStream, Chr( Asc( "A" ) + n ) )
         ? "CLOSED STREAM:", nStream
         EXIT
      ENDIF
      n := Int( ( n + 1 ) % 26 )
      hb_idleSleep( 0.1 )
   ENDDO

   RETURN NIL