[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/rddtest/ntxcl52.prg. Provides functions: test_main. This test file tests specific function APIs

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

FUNCTION test_main()

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


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

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

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

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

CREATE CLASS TIPMail

   VAR hHeaders

   VAR aReceived INIT {}

   METHOD New( cBody, xEncoder )    CONSTRUCTOR
   METHOD SetBody( cBody )
   METHOD GetBody()
   METHOD GetRawBody()              INLINE ::cBody
   METHOD SetEncoder( xEncoder )

   METHOD FromString( cMail, cBoundary, nPos )
   METHOD HeadersToString()
   METHOD ToString()

   METHOD GetFieldPart( cPart )
   METHOD GetFieldOption( cPart, cOption )
   METHOD SetFieldPart( cPart, cValue )
   METHOD SetFieldOption( cPart, cOption, cValue )
   METHOD SetCharset( cCharset ) INLINE ::cCharset := hb_defaultValue( cCharset, "UTF-8" )

   METHOD GetContentType() INLINE ::GetFieldPart( "Content-Type" )
   METHOD GetCharEncoding() INLINE ::GetFieldOption( "Content-Type", "encoding" )

   METHOD Attach( oSubPart )
   METHOD NextAttachment()
   METHOD CountAttachments()  INLINE Len( ::aAttachments )
   METHOD GetAttachment()
   METHOD ResetAttachment()   INLINE ::nAttachPos := 1

   METHOD MakeBoundary()

   METHOD isMultiPart()
   METHOD getMultiParts( aParts )

   METHOD setHeader( cSubject, cFrom, xTo, xCC )
   METHOD attachFile( cFileName )
   METHOD detachFile( cPath )
   METHOD getFileName()

   HIDDEN:

   VAR cBody
   VAR lBodyEncoded INIT .F.
   VAR oEncoder
   VAR aAttachments
   VAR nAttachPos   INIT 1
   VAR cCharset

ENDCLASS

METHOD New( cBody, xEncoder ) CLASS TIPMail

   ::hHeaders := { => }
   hb_HCaseMatch( ::hHeaders, .F. )
   ::aAttachments := {}

   ::setEncoder( xEncoder )
   ::setBody( cBody )
   ::SetCharset()

   RETURN Self

METHOD SetEncoder( xEncoder ) CLASS TIPMail

   ::oEncoder := iif( HB_ISSTRING( xEncoder ), tip_GetEncoder( xEncoder ), xEncoder )

   IF HB_ISOBJECT( ::oEncoder )
      ::hHeaders[ "Content-Transfer-Encoding" ] := ::oEncoder:cName
      RETURN .T.
   ENDIF

   RETURN .F.

METHOD SetBody( cBody ) CLASS TIPMail

   IF HB_ISOBJECT( ::oEncoder )
      ::cBody := ::oEncoder:Encode( cBody )
      ::hHeaders[ "Content-Transfer-Encoding" ] := ::oEncoder:cName
      ::lBodyEncoded := .T.
   ELSEIF HB_ISSTRING( cBody ) .OR. cBody == NIL
      ::cBody := cBody
   ENDIF

   RETURN .T.

METHOD GetBody() CLASS TIPMail
   RETURN iif( HB_ISOBJECT( ::oEncoder ), ::oEncoder:Decode( ::cBody ), ::cBody )

METHOD GetFieldPart( cPart ) CLASS TIPMail

   LOCAL nPos
   LOCAL cEnc

   IF hb_HGetRef( ::hHeaders, cPart, @cEnc )
      IF ( nPos := At( ";", cEnc ) ) > 0
         cEnc := Left( cEnc, nPos - 1 )
      ENDIF
      RETURN cEnc
   ENDIF

   RETURN ""

METHOD GetFieldOption( cPart, cOption ) CLASS TIPMail

   LOCAL aMatch
   LOCAL cEnc

   IF hb_HGetRef( ::hHeaders, cPart, @cEnc ) .AND. ;
      ! Empty( aMatch := hb_regex( ";\s*" + cOption + "\s*=\s*([^;]*)", cEnc, .F.  ) )
      RETURN aMatch[ 2 ]
   ENDIF

   RETURN ""

METHOD SetFieldPart( cPart, cValue ) CLASS TIPMail

   LOCAL nPos
   LOCAL cEnc

   IF HB_ISSTRING( cValue ) .AND. ! Empty( cValue )
      IF hb_HGetRef( ::hHeaders, cPart, @cEnc ) .AND. ;
         ( nPos := At( ";", cEnc ) ) > 0
         ::hHeaders[ cPart ] := cValue + SubStr( cEnc, nPos )
      ELSE
         ::hHeaders[ cPart ] := cValue
      ENDIF
   ENDIF

   RETURN .T.

METHOD SetFieldOption( cPart, cOption, cValue ) CLASS TIPMail

   LOCAL aMatch

   IF HB_ISSTRING( cPart ) .AND. cPart $ ::hHeaders .AND. ;
      HB_ISSTRING( cOption ) .AND. ! Empty( cOption )

      aMatch := hb_regex( "(.*?;\s*)" + cOption + "\s*=[^;]*(.*)?", ::hHeaders[ cPart ], .F. )

      IF Empty( aMatch )
         ::hHeaders[ cPart ] += "; " + cOption + "=" + '"' + cValue + '"'
      ELSE
         ::hHeaders[ cPart ] := aMatch[ 2 ] + cOption + "=" + '"' + cValue + '"' + aMatch[ 3 ]
      ENDIF

      RETURN .T.
   ENDIF

   RETURN .F.

METHOD Attach( oSubPart ) CLASS TIPMail

   IF HB_ISOBJECT( oSubPart ) .AND. oSubPart:ClassName() == "TIPMAIL"

      IF ! ::isMultiPart()
         ::hHeaders[ "Content-Type" ] := "multipart/mixed"
      ENDIF

      AAdd( ::aAttachments, oSubPart )
      RETURN .T.
   ENDIF

   RETURN .F.

METHOD NextAttachment() CLASS TIPMail

   IF ::nAttachPos > Len( ::aAttachments )
      RETURN NIL
   ENDIF

   RETURN ::aAttachments[ ::nAttachPos++ ]

METHOD GetAttachment() CLASS TIPMail

   IF ::nAttachPos > Len( ::aAttachments )
      RETURN NIL
   ENDIF

   RETURN ::aAttachments[ ::nAttachPos ]

METHOD HeadersToString() CLASS TIPMail

   LOCAL cRet := ""
   LOCAL cElem, i

   FOR EACH cElem IN { "Return-Path", "Delivered-To" }
      IF cElem $ ::hHeaders
         cRet += cElem + ": " + ::hHeaders[ cElem ] + e"\r\n"
      ENDIF
   NEXT

   FOR EACH cElem IN ::aReceived
      cRet += "Received: " + cElem + e"\r\n"
   NEXT

   FOR EACH cElem IN { "Date", "From", "To", "Subject" }
      IF cElem $ ::hHeaders
         cRet += cElem + ": " + ::hHeaders[ cElem ] + e"\r\n"
      ENDIF
   NEXT

   IF ! Empty( ::aAttachments )
      cRet += "Mime-Version: " + ::hHeaders[ "Mime-Version" ] + e"\r\n"
   ENDIF

   FOR EACH i IN ::hHeaders
      SWITCH Lower( cElem := i:__enumKey() )
      CASE "return-path"
      CASE "delivered-to"
      CASE "date"
      CASE "from"
      CASE "to"
      CASE "subject"
      CASE "mime-version"
         EXIT
      OTHERWISE
         cRet += cElem + ": " + i + e"\r\n"
      ENDSWITCH
   NEXT

   RETURN cRet

METHOD ToString() CLASS TIPMail

   LOCAL cBoundary, i
   LOCAL cRet

   IF ! Empty( ::aAttachments )
      ::hHeaders[ "Mime-Version" ] := "1.0"

      IF ! ::isMultiPart()
         ::hHeaders[ "Content-Type" ] := "multipart/mixed"
      ENDIF

      cBoundary := ::GetFieldOption( "Content-Type", "Boundary" )
      IF Empty( cBoundary )
         cBoundary := ::MakeBoundary()
         IF ! ::SetFieldOption( "Content-Type", "Boundary", cBoundary )
            ::hHeaders[ "Content-Type" ] := "multipart/mixed; boundary=" + '"' + cBoundary + '"'
         ENDIF
      ENDIF
   ENDIF

   cRet := ::HeadersToString() + e"\r\n"

   IF ::cBody != NIL .AND. ! ::cBody == ""
      IF Empty( ::aAttachments )
         cRet += ::cBody + iif( ::lBodyEncoded, "", e"\r\n" )
      ELSE

         cRet += ;
            "--" + cBoundary + e"\r\n" + ;
            "Content-Disposition: inline" + e"\r\n" + ;
            "Content-Type: text/plain; charset=" + ::cCharset + "; format=flowed" + e"\r\n" + ;
            "Content-Transfer-Encoding: 7bit" + e"\r\n" + ;
            e"\r\n" + ;
            ::cBody + ;
            e"\r\n"
      ENDIF
   ENDIF

   IF ! Empty( ::aAttachments )

      FOR EACH i IN ::aAttachments
         cRet += "--" + cBoundary + e"\r\n" + i:ToString() + e"\r\n"
      NEXT
      cRet += "--" + cBoundary + "--" + e"\r\n"
   ENDIF

   RETURN cRet

METHOD FromString( cMail, cBoundary, nPos ) CLASS TIPMail

   LOCAL oSubSection, cSubBoundary
   LOCAL nLinePos, nSplitPos, nBodyPos
   LOCAL cValue, cLastField

   IF ! HB_ISSTRING( cMail )
      RETURN 0
   ENDIF

   IF Len( ::aAttachments ) > 0
      ::aAttachments := {}
   ENDIF

   IF Len( ::hHeaders ) > 0
      ::hHeaders := { => }
      hb_HCaseMatch( ::hHeaders, .F. )
   ENDIF

   IF Len( ::aReceived ) > 0
      ::aReceived := {}
   ENDIF

   hb_default( @nPos, 1 )

   DO WHILE ( nLinePos := hb_At( e"\r\n", cMail, nPos ) ) > nPos

      IF ( SubStr( cMail, nPos, 1 ) == " " .OR. SubStr( cMail, nPos, 1 ) == e"\t" ) .AND. ;
         cLastField != NIL

         cValue := LTrim( SubStr( cMail, nPos, nLinePos - nPos ) )
         IF Lower( cLastField ) == "received"
            ::aReceived[ Len( ::aReceived ) ] += " " + cValue
         ELSE
            ::hHeaders[ cLastField ] += " " + cValue
         ENDIF
      ELSE
         nSplitPos := hb_At( ":", cMail, nPos )
         cLastField := SubStr( cMail, nPos, nSplitPos - nPos )
         cValue := LTrim( SubStr( cMail, nSplitPos + 1, nLinePos - nSplitPos - 1 ) )
         IF Lower( cLastField ) == "received"
            AAdd( ::aReceived, cValue )
         ELSE
            ::hHeaders[ cLastField ] := cValue
         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 test program: tests/rddtest/cdxcl52.prg. Provides functions: test_main. This test file tests specific function APIs

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

FUNCTION test_main()

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


[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 Runtime Library file: src/rtl/tgetlist.prg. Defines classes: HBGetList. This file implements object-oriented classes using Harbour's class system

[Assistant]
#include "hbclass.ch"

#include "button.ch"
#include "getexit.ch"
#include "inkey.ch"
#include "setcurs.ch"
#include "tbrowse.ch"

#define SCORE_ROW       0
#define SCORE_COL       60

#define _GET_INSERT_ON  7
#define _GET_INSERT_OFF 8
#define _GET_INVD_DATE  9

#define K_UNDO          K_CTRL_U

#define MSGFLAG         1
#define MSGROW          2
#define MSGLEFT         3
#define MSGRIGHT        4
#define MSGCOLOR        5

CREATE CLASS HBGetList

   EXPORTED:

   VAR HasFocus        AS LOGICAL   INIT .F.

#ifdef HB_COMPAT_C53
   METHOD ReadModal( nPos, oMenu, nMsgRow, nMsgLeft, nMsgRight, cMsgColor )
#else
   METHOD ReadModal()
#endif
   METHOD Settle( nPos, lInit )
   METHOD Reader( oMenu, aMsg )
   METHOD GetApplyKey( nKey, oGet, oMenu, aMsg )
   METHOD GetPreValidate( oGet, aMsg )
   METHOD GetPostValidate( oGet, aMsg )
   METHOD GetDoSetKey( bKeyBlock, oGet )
   METHOD PostActiveGet()
   METHOD GetReadVar()
   METHOD SetFormat( bFormat )
   METHOD KillRead( lKill )
   METHOD GetActive( oGet )
   METHOD DateMsg()
   METHOD ShowScoreBoard()
   METHOD ReadUpdated( lUpdated )
   METHOD ReadVar( cNewVarName )
   METHOD SetFocus()
   METHOD Updated()
   METHOD Get()

#ifdef HB_COMPAT_C53
   METHOD GUIReader( oGet, oMenu, aMsg )
   METHOD GUIApplyKey( oGet, oGUI, nKey, oMenu, aMsg )
   METHOD GUIPreValidate( oGet, oGUI, aMsg )
   METHOD GUIPostValidate( oGet, oGUI, aMsg )
   METHOD TBApplyKey( oGet, oTB, nKey, oMenu, aMsg )
   METHOD TBReader( oGet, oMenu, aMsg )
   METHOD Accelerator( nKey, aMsg )
   METHOD hitTest( nMRow, nMCol, aMsg )
#endif
   METHOD ReadStats( nElement, xNewValue )
   METHOD ShowGetMsg( oGet, aMsg )
   METHOD EraseGetMsg( aMsg )

   METHOD Init( GetList )

   PROTECTED:

   VAR oGet
   VAR aGetList

   VAR lUpdated        AS LOGICAL   INIT .F.
   VAR bFormat
   VAR lKillRead       AS LOGICAL   INIT .F.
   VAR lBumpTop        AS LOGICAL   INIT .F.
   VAR lBumpBot        AS LOGICAL   INIT .F.
   VAR nLastExitState               INIT 0
   VAR nLastPos        AS NUMERIC   INIT 0
   VAR oActiveGet
   VAR xReadVar
   VAR cVarName
   VAR cReadProcName   AS CHARACTER INIT ""
   VAR nReadProcLine                INIT 0
   VAR nNextGet                     INIT 0
   VAR nHitCode        AS NUMERIC   INIT 0
   VAR nPos            AS NUMERIC   INIT 1
   VAR cMsgSaveS
   VAR nMenuID
   VAR nSaveCursor

ENDCLASS

#ifdef HB_COMPAT_C53
METHOD ReadModal( nPos, oMenu, nMsgRow, nMsgLeft, nMsgRight, cMsgColor ) CLASS HBGetList
#else
METHOD ReadModal() CLASS HBGetList
#endif

#ifdef HB_COMPAT_C53
   LOCAL lMsgFlag
   LOCAL aMsg
#endif

#ifdef HB_COMPAT_C53
   ::nSaveCursor   := SetCursor( SC_NONE )
#endif
   ::cReadProcName := ProcName( 2 )
   ::nReadProcLine := ProcLine( 2 )

#ifdef HB_COMPAT_C53
   ::nPos := ::Settle( hb_defaultValue( nPos, 0 ), .T. )

   IF ( lMsgFlag := HB_ISNUMERIC( nMsgRow ) .AND. ;
                    HB_ISNUMERIC( nMsgLeft ) .AND. ;
                    HB_ISNUMERIC( nMsgRight ) )

      IF ! HB_ISSTRING( cMsgColor )
         cMsgColor := GetClrPair( SetColor(), 1 )
      ENDIF

      Scroll( nMsgRow, nMsgLeft, nMsgRow, nMsgRight )

      ::cMsgSaveS := SaveScreen( nMsgRow, nMsgLeft, nMsgRow, nMsgRight )
   ENDIF

   ::nNextGet := 0
   ::nHitCode := 0
   ::nMenuID := 0

   aMsg := { lMsgFlag, nMsgRow, nMsgLeft, nMsgRight, cMsgColor, , , , , }
#else
   ::nPos := ::Settle( 0 )
#endif

   DO WHILE ::nPos != 0

      ::oGet := ::aGetList[ ::nPos ]
      ::PostActiveGet()

#ifdef HB_COMPAT_C53
      IF HB_ISEVALITEM( ::oGet:reader )
         Eval( ::oGet:reader, ::oGet, Self, oMenu, aMsg )
      ELSE
         ::Reader( oMenu, aMsg )
      ENDIF
#else
      IF HB_ISEVALITEM( ::oGet:reader )
         Eval( ::oGet:reader, ::oGet )
      ELSE
         ::Reader()
      ENDIF
#endif

      ::nPos := ::Settle( ::nPos )

   ENDDO

#ifdef HB_COMPAT_C53
   IF lMsgFlag
      RestScreen( nMsgRow, nMsgLeft, nMsgRow, nMsgRight, ::cMsgSaveS )
   ENDIF

   SetCursor( ::nSaveCursor )
#endif

   RETURN Self

METHOD Updated() CLASS HBGetList
   RETURN ::lUpdated

METHOD Get() CLASS HBGetList
   RETURN ::oGet

METHOD SetFocus() CLASS HBGetList

   __GetListSetActive( Self )
   __GetListLast( Self )
   ::aGetList[ ::nPos ]:setFocus()

   RETURN Self

METHOD Reader( oMenu, aMsg ) CLASS HBGetList

   LOCAL oGet := ::oGet
   LOCAL nRow
   LOCAL nCol
#ifdef HB_COMPAT_C53
   LOCAL nOldCursor
   LOCAL nKey
#endif

#ifdef HB_COMPAT_C53
   IF ::nLastExitState == GE_SHORTCUT .OR.;
      ::nLastExitState == GE_MOUSEHIT .OR.;
      ::GetPreValidate( oGet, aMsg )
#else
   IF ::GetPreValidate( oGet, aMsg )
#endif

      ::ShowGetMsg( oGet, aMsg )

      ::nHitCode := 0
      ::nLastExitState := 0
      oGet:setFocus()

      DO WHILE oGet:exitState == GE_NOEXIT .AND. ! ::lKillRead
         IF oGet:typeOut
            oGet:exitState := GE_ENTER
         ENDIF

         DO WHILE oGet:exitState == GE_NOEXIT .AND. ! ::lKillRead
#ifdef HB_COMPAT_C53
            SetCursor( iif( ::nSaveCursor == SC_NONE, SC_NORMAL, ::nSaveCursor ) )
            nKey := Inkey( 0 )
            SetCursor( SC_NONE )
            ::GetApplyKey( nKey, oGet, oMenu, aMsg )
#else
            ::GetApplyKey( Inkey( 0 ), oGet, oMenu, aMsg )
#endif
            nRow := Row()
            nCol := Col()
            ::ShowGetMsg( oGet, aMsg )
            SetPos( nRow, nCol )
         ENDDO

#ifdef HB_COMPAT_C53
         IF ! ::nLastExitState == GE_SHORTCUT .AND. ;
            ! ::nLastExitState == GE_MOUSEHIT .AND. ;
            ! ::GetPostValidate( oGet, aMsg )
#else
         IF ! ::GetPostValidate( oGet, aMsg )
#endif
            oGet:exitState := GE_NOEXIT
         ENDIF
      ENDDO

#ifdef HB_COMPAT_C53
      nRow := Row()
      nCol := Col()
      nOldCursor := SetCursor()
#endif
      oGet:killFocus()
#ifdef HB_COMPAT_C53
      SetCursor( nOldCursor )
      SetPos( nRow, nCol )
#endif

      ::EraseGetMsg( aMsg )
   ENDIF

   RETURN Self

METHOD GetApplyKey( nKey, oGet, oMenu, aMsg ) CLASS HBGetList

   LOCAL cKey
   LOCAL bKeyBlock

#ifdef HB_COMPAT_C53
   LOCAL nMRow
   LOCAL nMCol
   LOCAL nButton
   LOCAL nHotItem
#endif

   hb_default( @oGet, ::oGet )

   IF ( bKeyBlock := SetKey( nKey ) ) != NIL
      IF ::GetDoSetKey( bKeyBlock, oGet )
         RETURN Self
      ENDIF
   ENDIF

#ifdef HB_COMPAT_C53
   IF ::aGetList != NIL .AND. ( nHotItem := ::Accelerator( nKey, aMsg ) ) != 0

      oGet:exitState := GE_SHORTCUT
      ::nNextGet := nHotItem
      ::nLastExitState := GE_SHORTCUT
   ELSEIF ! HB_ISOBJECT( oMenu )
   ELSEIF ( nHotItem := oMenu:getAccel( nKey ) ) != 0
      ::nMenuID := MenuModal( oMenu, nHotItem, aMsg[ MSGROW ], aMsg[ MSGLEFT ], aMsg[ MSGRIGHT ], aMsg[ MSGCOLOR ] )
      nKey := 0
   ELSEIF IsShortcut( oMenu, nKey )
      nKey := 0
   ENDIF
#else
   HB_SYMBOL_UNUSED( oMenu )
   HB_SYMBOL_UNUSED( aMsg )
#endif

   SWITCH nKey
   CASE K_UP
      oGet:exitState := GE_UP
      EXIT

   CASE K_SH_TAB
      oGet:exitState := GE_UP
      EXIT

   CASE K_DOWN
      oGet:exitState := GE_DOWN
      EXIT

   CASE K_TAB
      oGet:exitState := GE_DOWN
      EXIT

   CASE K_ENTER
      oGet:exitState := GE_ENTER
      EXIT

   CASE K_ESC
      IF Set( _SET_ESCAPE )
         oGet:undo()
         oGet:exitState := GE_ESCAPE
      ENDIF
      EXIT

   CASE K_PGUP
      oGet:exitState := GE_WRITE
      EXIT

   CASE K_PGDN
      oGet:exitState := GE_WRITE
      EXIT

   CASE K_CTRL_HOME
      oGet:exitState := GE_TOP
      EXIT

#ifdef CTRL_END_SPECIAL
   CASE K_CTRL_END
      oGet:exitState := GE_BOTTOM
      EXIT
#else
   CASE K_CTRL_W
      oGet:exitState := GE_WRITE
      EXIT
#endif

#ifdef HB_COMPAT_C53
   CASE K_LBUTTONDOWN
   CASE K_LDBLCLK

      nMRow := MRow()
      nMCol := MCol()

      IF ! HB_ISOBJECT( oMenu )
         nButton := 0
      ELSEIF ! oMenu:ClassName() == "TOPBARMENU"
         nButton := 0
      ELSEIF ( nButton := oMenu:hitTest( nMRow, nMCol ) ) != 0


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

[User] Implement this Harbour module: Harbour Runtime Library file: src/rtl/adir.prg. Provides functions: ADir. This file provides file I/O operations

[Assistant]
#include "directry.ch"

FUNCTION ADir( cFileMask, aName, aSize, aDate, aTime, aAttr )

   LOCAL aDir
   LOCAL nDirLen
   LOCAL nDirPos

   LOCAL nNameLen, nSizeLen, nDateLen, nTimeLen, nAttrLen

   LOCAL aFileInfo

   LOCAL cDir
   LOCAL cName
   LOCAL cExt

   IF ! HB_ISSTRING( cFileMask )
      RETURN 0
   ENDIF

   hb_FNameSplit( cFileMask, @cDir, @cName, @cExt )

   IF Empty( cDir )
      cFileMask := hb_FNameMerge( __DefPath(), cName, cExt )
   ENDIF

   IF HB_ISARRAY( aName )
      nNameLen := Len( aName )
   ENDIF
   IF HB_ISARRAY( aSize )
      nSizeLen := Len( aSize )
   ENDIF
   IF HB_ISARRAY( aDate )
      nDateLen := Len( aDate )
   ENDIF
   IF HB_ISARRAY( aTime )
      nTimeLen := Len( aTime )
   ENDIF
   IF HB_ISARRAY( aAttr )
      nAttrLen := Len( aAttr )
   ENDIF

   aDir := Directory( cFileMask, iif( HB_ISARRAY( aAttr ), "HSD", ) )
   nDirLen := Len( aDir )

   FOR nDirPos := 1 TO nDirLen

      aFileInfo := aDir[ nDirPos ]

      IF nNameLen != NIL .AND. nNameLen >= nDirPos
         aName[ nDirPos ] := aFileInfo[ F_NAME ]
      ENDIF
      IF nSizeLen != NIL .AND. nSizeLen >= nDirPos
         aSize[ nDirPos ] := aFileInfo[ F_SIZE ]
      ENDIF
      IF nDateLen != NIL .AND. nDateLen >= nDirPos
         aDate[ nDirPos ] := aFileInfo[ F_DATE ]
      ENDIF
      IF nTimeLen != NIL .AND. nTimeLen >= nDirPos
         aTime[ nDirPos ] := aFileInfo[ F_TIME ]
      ENDIF
      IF nAttrLen != NIL .AND. nAttrLen >= nDirPos
         aAttr[ nDirPos ] := aFileInfo[ F_ATTR ]
      ENDIF

   NEXT

   RETURN nDirLen


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

[User] Implement this Harbour module: Header file for contribution module 'xhb' (Extended Harbour functions): contrib/xhb/cstruct.ch. Defines constants: __HBCSTRUCT_CH_, __PACK. Declares 5 preprocessor commands. Declares 5 preprocessor translations. Defines color and display constants

[Assistant]
#include "hbctypes.ch"

#ifndef __HBCSTRUCT_CH_
   #define __HBCSTRUCT_CH_

   #ifdef _SET_CH
      #xtranslate __ClsSetModule( <x> ) => Empty( <x> )
      #xcommand C STRUCTURE <!stru!> [ALIGN <align> ] => ;
               INIT PROCEDURE __INIT_<stru>; ;
                  __ActiveStructure( #<stru>, <align> ) ; ;
               #xtranslate IS <stru> \[ \<x: :=, INIT> { \<initlist,...> } ] => := hb_CStructure( #<stru> ):Init( {\<initlist>} ); ;
               #xtranslate IS <stru> FROM \<pointer> => := hb_CStructure( #<stru> ):Buffer( \<pointer> )

      #xcommand MEMBER <elem> IS <type> => hb_Member( #<elem>, <type> )

      #xcommand MEMBER <elem> := hb_CStructure( <literalstru> ):Init( {} ) => ;
               hb_Member( #<elem>, hb_CStructureId( <literalstru>, .T. ) )

      #xcommand MEMBER <!elem!> IS <type> ( <nlen> ) => hb_Member( #<elem>, hb_CTypeArrayId( <type>, <nlen> ) )

      #xcommand MEMBER <!elem!> AS <!stru!> => ;
               hb_Member( #<elem>, hb_CStructureId( #<stru>, .F. ) )

      #xcommand END C STRUCTURE [<!stru!>] => ; ;
                  __ClsSetModule( __ActiveStructure() ); ;
               RETURN

      #xcommand IMPORT C STRUCTURE <!stru!> => ;
               #xtranslate IS <stru> \[ \<x: :=, INIT> { \<initlist,...> } ] => := hb_CStructure( #<stru> ):Init( {\<initlist>} ); ;
               #xtranslate IS <stru> FROM \<pointer> => := hb_CStructure( #<stru> ):Buffer( \<pointer> )

      #define __PACK 8

      #xcommand typedef struct [<!tag!>] { [[struct] <elem>] } <!stru!> [, <*synon*>] => ;
                INIT PROCEDURE __INIT_<stru>; ;
                   hb_CStructureCSyntax( #<stru>, {[#<elem>,]}, <(tag)>, <"synon">, __PACK ); ;
                   __ClsSetModule( __ActiveStructure() ); ;
                RETURN; ;
                #xtranslate IS <stru> \[ \<x: :=, INIT> { \<initlist,...> } ] => := hb_CStructure( #<stru> ):Init( {\<initlist>} ); ;
                #xtranslate IS <stru> FROM \<pointer> => := hb_CStructure( #<stru> ):Buffer( \<pointer> )

      #xcommand pragma pack( <pack> ) => #undef __PACK; #define __PACK <pack>
      #xcommand pragma pack() => #undef __PACK; #define __PACK 8

      #xtranslate ( struct <stru> ) [<buffer>] => hb_CStructure( #<stru> ):Buffer( <buffer> )
      #xtranslate ( struct <stru>* ) <pointer> => hb_CStructure( #<stru> ):Pointer( <pointer> )
   #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 contribution module 'hbwin' (Windows API wrapper functions): contrib/hbwin/tests/prngdi.prg. Contains procedures: Main. This file provides platform-specific functionality

[Assistant]
#require "hbwin"

#include "simpleio.ch"

PROCEDURE Main()

   LOCAL cPrinterName := "Microsoft XPS Document Writer"

   LOCAL hDC
   LOCAL pDEVMODE
   LOCAL hRECT
   LOCAL aRECT
   LOCAL hOBJECT

   pDEVMODE := __wapi_DEVMODE_New( cPrinterName )
   __wapi_DEVMODE_Set( pDEVMODE, { "dmPaperSize" => WIN_DMPAPER_A3 } )
   ? hDC := wapi_CreateDC( NIL, cPrinterName, NIL, pDEVMODE )

   ? wapi_StartDoc( hDC, { "lpszDocName" => "test job" }  )
   ? wapi_StartPage( hDC )
   ? hOBJECT := wapi_CreateFont( ,,,,,,,,,,,,, "Arial" )
   ? wapi_SelectObject( hDC, hOBJECT )

   ? "in ARR"
   aRECT := { 100, 150, 450, 250 }
   ? wapi_DrawText( hDC, "0TEST", aRECT )

   ? "inout ARR"
   aRECT := { 100, 150, 450, 250 }
   ? wapi_DrawText( hDC, "1TEST", aRECT, WIN_DT_CALCRECT )
   ? aRECT[ 1 ], aRECT[ 2 ], aRECT[ 3 ], aRECT[ 4 ]

   ? "out HASH"
   hRECT := { => }
   ? wapi_DrawText( hDC, "2TEST", hRECT, WIN_DT_CALCRECT )
   ? hRECT[ "left" ], hRECT[ "top" ], hRECT[ "bottom" ], hRECT[ "right" ]

   ? "inout HASH"
   hRECT := { => }
   hRECT[ "left" ] := 300
   hRECT[ "top" ] := 350
   ? wapi_DrawText( hDC, "3TEST", hRECT, WIN_DT_CALCRECT )
   ? hRECT[ "left" ], hRECT[ "top" ], hRECT[ "bottom" ], hRECT[ "right" ]

   ? "in HASH"
   hRECT := { => }
   hRECT[ "left" ] := 300
   hRECT[ "top" ] := 350
   hRECT[ "right" ] := 650
   hRECT[ "bottom" ] := 450
   ? wapi_DrawText( hDC, "4TEST", hRECT )

   ? wapi_EndPage( hDC )
   ? wapi_EndDoc( hDC )

   hDC := NIL
   hOBJECT := NIL

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

[Assistant]
PROCEDURE Main()

   LOCAL obj := ErrorNew()

   MEMVAR m_send1
   MEMVAR m_send2

   PRIVATE m_send1 := "_description"
   PRIVATE m_send2 := "_tries"

   obj:tries := 1
   obj:&m_send1 := "test"

   obj:tries += 1
   obj:tries++
   ++obj:tries

   WITH OBJECT obj
      :tries += 1
      :tries++
      ++:tries

      :&m_send2 += 1
      :&m_send2++
      ++:&m_send2
      ++:&( m_send2 )

      :&( m_send2 ) := :&( SubStr( m_send2, 2 ) ) + 1

      :&m_send1 += " description"
      :&( m_send1 ) += " of "
   ENDWITH

   obj:&( "_" + SubStr( m_send1, 2 ) ) += "Error object"
   ? m_send1, "=", obj:&( SubStr( m_send1, 2 ) )
   ? m_send2, "=", obj:tries

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

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

PROCEDURE Main()

   TestIt( hb_osFileMask() )
   TestIt( hb_ps() )
   TestIt( ".." + hb_ps() )
   TestIt( ".." + hb_ps() + hb_osFileMask() )

   RETURN

STATIC FUNCTION TestIt( cSpec )

   LOCAL a
   LOCAL a1
   LOCAL a2
   LOCAL a3
   LOCAL a4
   LOCAL a5

   a := ADir( cSpec, , , , , {} )

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

   a1 := Array( a )
   a2 := Array( a )
   a3 := Array( iif( a >= 1, a - 1, a ) )
   a4 := Array( a )
   a5 := Array( a + 1 )

   OutStd( "--------------------------------------------------------" )
   OutStd( hb_eol() )

   ADir( cSpec, a1, a2, a3, a4, a5 )

   AEval( a1, {| tmp | OutStd( tmp ), OutStd( hb_eol() ) } )
   AEval( a2, {| tmp | OutStd( tmp ), OutStd( hb_eol() ) } )
   AEval( a3, {| tmp | OutStd( tmp ), OutStd( hb_eol() ) } )
   AEval( a4, {| tmp | OutStd( tmp ), OutStd( hb_eol() ) } )
   AEval( a5, {| tmp | OutStd( tmp ), OutStd( hb_eol() ) } )

   ADir( cSpec, 10, "A", NIL, NIL, NIL )

   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] Define Harbour macros and constants: Header file for contribution module 'xhb' (Extended Harbour functions): contrib/xhb/classex.ch. Declares 5 preprocessor commands. Declares 5 preprocessor translations. Defines communication constants

[Assistant]
#xcommand PROPERTY <x>  [TYPE <type>] [AS <astype>] [INDEX <i>] READ <rf> WRITE <wf> [DEFAULT <d>];
                        [<scope: EXPORTED, EXPORT, VISIBLE, PUBLIC, PROTECTED, HIDDEN, PRIVATE, READONLY, RO, PUBLISHED >] ;
           =>  ;
           DATA T_<x>    AS STRING INIT <(type)> PROTECTED  ;;
           #xtranslate __FNAME(<x>) => F<x> ;;
           DATA __FNAME(<x>)     [AS <astype>] PROTECTED [INIT <d>] ;;
           ACCESS <x>    INLINE ::<rf>( [ <i> ] )           ;;
           ASSIGN <x>(v) INLINE ::<wf>( [ <i>, ] v)

#xcommand PROPERTY <x>  [AS <astype>] [INDEX <i>] READ <rf> WRITE <wf> [DEFAULT <d>];
                        [<scope: EXPORTED, EXPORT, VISIBLE, PUBLIC, PROTECTED, HIDDEN, PRIVATE, READONLY, RO, PUBLISHED >] ;
           =>  ;
           #xtranslate __FNAME(<x>) => F<x> ;;
           DATA __FNAME(<x>)     [AS <astype>] PROTECTED [INIT <d>] ;;
           ACCESS <x>    INLINE ::<rf>( [ <i> ] )          ;;
           ASSIGN <x>(v) INLINE ::<wf>( [ <i>, ] v)

#xcommand PROPERTY <x>  [TYPE <type>] [AS <astype>] [INDEX <i>] WRITE <wf> [DEFAULT <d>];
                        [<scope: EXPORTED, EXPORT, VISIBLE, PUBLIC, PROTECTED, HIDDEN, PRIVATE, READONLY, RO, PUBLISHED >] ;
           =>  ;
           DATA T_<x>    AS STRING INIT <(type)> PROTECTED   ;;
           #xtranslate __FNAME(<x>) => F<x> ;;
           DATA __FNAME(<x>)     [AS <astype>] PROTECTED [INIT <d>] ;;
           ASSIGN <x>(v) INLINE ::<wf>( [ <i>, ] v)

#xcommand PROPERTY <x>  [AS <astype>] [INDEX <i>] WRITE <wf> [DEFAULT <d>];
                        [<scope: EXPORTED, EXPORT, VISIBLE, PUBLIC, PROTECTED, HIDDEN, PRIVATE, READONLY, RO, PUBLISHED >] ;
           =>  ;
           #xtranslate __FNAME(<x>) => F<x> ;;
           DATA __FNAME(<x>)     [AS <astype>] PROTECTED [INIT <d>] ;;
           ASSIGN <x>(v) INLINE ::<wf>( [ <i>, ] v)

#xcommand PROPERTY <x>  [TYPE <type>] [AS <astype>] [INDEX <i>] READ <rf> [DEFAULT <d>];
                        [<scope: EXPORTED, EXPORT, VISIBLE, PUBLIC, PROTECTED, HIDDEN, PRIVATE, READONLY, RO, PUBLISHED >] ;
           =>  ;
           DATA T_<x>    AS STRING INIT <(type)> PROTECTED   ;;
           #xtranslate __FNAME(<x>) => F<x> ;;
           DATA __FNAME(<x>)     [AS <astype>] PROTECTED [INIT <d>] ;;
           ACCESS <x>    INLINE ::<rf>( [ <i> ] )

#xcommand PROPERTY <x>  [AS <astype>] [INDEX <i>] READ <rf> [DEFAULT <d>];
                        [<scope: EXPORTED, EXPORT, VISIBLE, PUBLIC, PROTECTED, HIDDEN, PRIVATE, READONLY, RO, PUBLISHED >] ;
           =>  ;
           #xtranslate __FNAME(<x>) => F<x> ;;
           DATA __FNAME(<x>)     [AS <astype>] PROTECTED [INIT <d>] ;;
           ACCESS <x>    INLINE ::<rf>( [ <i> ] )

#xcommand PROPERTY <x>  [TYPE <type>] [AS <astype>] [DEFAULT <d>];
                        [<scope: EXPORTED, EXPORT, VISIBLE, PUBLIC, PROTECTED, HIDDEN, PRIVATE, READONLY, RO, PUBLISHED >] ;
           =>  ;
           DATA T_<x>    AS STRING INIT <(type)> PROTECTED   ;;
           #xtranslate __FNAME(<x>) => F<x> ;;
           DATA __FNAME(<x>)     [AS <astype>] EXPORTED  [INIT <d>]

#xcommand PROPERTY <x>  [AS <astype>] [DEFAULT <d>];
                        [<scope: EXPORTED, EXPORT, VISIBLE, PUBLIC, PROTECTED, HIDDEN, PRIVATE, READONLY, RO, PUBLISHED >] ;
           =>  ;
           #xtranslate __FNAME(<x>) => F<x> ;;
           DATA __FNAME(<x>)     [AS <astype>] EXPORTED  [INIT <d>]

#xtranslate __FNAME(<x>) => F<x>


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

[Assistant]
PROCEDURE Main()

   ? "From Main()"

   SecondOne()

   ? "From Main() again"

   RETURN

STATIC FUNCTION SecondOne()

   ? "From Second()"

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

Harbour test program: tests/gfx.prg. Provides functions: PutFrame. Contains procedures: Main. This test file tests specific function APIs

[Assistant]
#include "hbgtinfo.ch"
#include "hbgfx.ch"

PROCEDURE Main()

   LOCAL nFontHeight, nFontWidth
   LOCAL nTop, nLeft, nHeight, nWidth, nColor, nSec := Seconds()
   LOCAL cWelcome

#if defined( __HBSCRIPT__HBSHELL )
#  if defined( __PLATFORM__WINDOWS )
      hbshell_gtSelect( "GTWVT" )
#  elif defined( __PLATFORM__UNIX )
      hbshell_gtSelect( "GTXWC" )
#  endif
#endif

   IF ! hb_gtInfo( HB_GTI_ISGRAPHIC )
      ? "You are using a non graphics capable gt:"
      ? "GT" + hb_gtVersion()
      QUIT
   ENDIF

   IF hb_gtInfo( HB_GTI_DESKTOPWIDTH ) > 1000
      hb_gtInfo( HB_GTI_FONTWIDTH, 12 )
      hb_gtInfo( HB_GTI_FONTSIZE, 24 )
   ENDIF

   nFontHeight := hb_gtInfo( HB_GTI_FONTSIZE )
   nFontWidth := hb_gtInfo( HB_GTI_FONTWIDTH )

   cWelcome := "Welcome to the World of Harbour multiplatform Graphics!" + " (GT" + hb_gtVersion() + ")"

   SetColor( "n/w" )
   @ 0, 0 SAY Space( MaxCol() + 1 )
   @ 1, 0 SAY PadC( cWelcome, MaxCol() + 1 )
   @ 2, 0 SAY Space( MaxCol() + 1 )

   hb_gtInfo( HB_GTI_WINTITLE, "Cross-GT, multiplatform graphics demo" )

   PutFrame( ;
      nFontHeight / 2, ;
      MaxCol() / 2
         hb_gfxText( nTop, nLeft, "Hello", nColor, nHeight )
         EXIT
      ENDSWITCH
      IF Seconds() - nSec > 3
         hb_gfxFloodFill( 0, 0, nColor )
         nSec := Seconds()
      ENDIF
   ENDDO

   RETURN

FUNCTION PutFrame( nTop, nLeft, nBottom, nRight, nColor1, nColor2 )

   hb_gfxRect( nTop, nLeft, nBottom, nRight, nColor1 )
   hb_gfxRect( nTop + 1, nLeft + 1, nBottom - 1, nRight - 1, nColor2 )
   hb_gfxLine( nTop + 1, nLeft + 1, nTop + 1, nRight - 1, nColor2 )
   hb_gfxLine( nTop + 2, nLeft + 1, nBottom - 1, nLeft + 1, nColor2 )

   RETURN NIL


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

[User] Implement these Harbour functions: Harbour source file: src/rdd/dbdelim.prg. Provides functions: __dbDelim. This file implements core Record Driver Driver functionality

[Assistant]
REQUEST Delim

FUNCTION __dbDelim( lExport, cFile, cDelimArg, aFields, bFor, bWhile, nNext, nRecord, lRest, cCodePage )

#ifdef HB_CLP_STRICT

   LOCAL nSrcArea
   LOCAL nDstArea
   LOCAL aStruct
   LOCAL cRDD := "DELIM"

   IF lExport
      nSrcArea := Select()
   ELSE
      nDstArea := Select()
   ENDIF

   IF Empty( aStruct := __dbStructFilter( dbStruct(), aFields ) )
      RETURN .F.
   ENDIF

   IF lExport
      dbCreate( cFile, aStruct, cRDD, .T., "", cDelimArg )
      nDstArea := Select()
      IF nDstArea == nSrcArea
         nDstArea := NIL
      ENDIF
      dbSelectArea( nSrcArea )
   ELSE
      IF ! __dbOpenSDF( cFile, aStruct, cRDD, .T., "", cDelimArg )
         RETURN .F.
      ENDIF
      nSrcArea := Select()
   ENDIF

   IF nDstArea != NIL
      __dbTrans( nDstArea, aStruct, bFor, bWhile, nNext, nRecord, lRest )
   ENDIF

   IF lExport
      IF nDstArea != NIL
         dbSelectArea( nDstArea )
         dbCloseArea()
      ENDIF
      dbSelectArea( nSrcArea )
   ELSE
      dbSelectArea( nSrcArea )
      dbCloseArea()
      dbSelectArea( nDstArea )
   ENDIF

   RETURN .T.

#else

   RETURN iif( lExport, ;
      __dbCopy( cFile, aFields, bFor, bWhile, nNext, nRecord, lRest, "DELIM",, cCodePage, cDelimArg ), ;
      __dbApp( cFile, aFields, bFor, bWhile, nNext, nRecord, lRest, "DELIM",, cCodePage, cDelimArg ) )

#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] Define Harbour macros and constants: Harbour contribution module 'gtwvg' (): contrib/gtwvg/tests/demowvg.prg. Contains 6 procedures. This file provides platform-specific functionality

[Assistant]
#require "gtwvg"

#include "inkey.ch"
#include "hbgtinfo.ch"
#include "hbver.ch"
#include "wvgparts.ch"

REQUEST DBFCDX
REQUEST DBFNTX

#define IMAGE_VOUCH                hb_DirBase() + "vouch1.bmp"
#define IMAGE_BROWSE               hb_DirBase() + "v_browse.ico"
#define IMAGE_VR                   hb_DirBase() + "vr_1.ico"
#define IMAGE_NOTES                hb_DirBase() + "v_notes.ico"
#define IMAGE_TOOLS                hb_DirBase() + "v_tools.ico"
#define IMAGE_HELP                 hb_DirBase() + "v_notes.ico"

#define OBJ_TYPE_BUTTON            1

#ifndef __SQL__
   ANNOUNCE Hb_NoStartUpWindow
#endif

MEMVAR cCdxExp, First, Last, City

THREAD STATIC t_wvtScreen := {}

#ifdef __XCC__
STATIC s_paint_ := { { "", {} } }
#endif

EXIT PROCEDURE CleanHandles()

   LOCAL obj

   FOR EACH obj IN SetFonts()
      wvg_DeleteObject( obj )
      obj := NIL
   NEXT
   FOR EACH obj IN SetIcons()
      wvg_DeleteObject( obj )
      obj := NIL
   NEXT

   RETURN

PROCEDURE Main()

   LOCAL aLastPaint, clr, scr, pGT
   LOCAL hPopup
   LOCAL dDate     := hb_SToD()
   LOCAL cName     := PadR( "Pritpal Bedi", 35 )
   LOCAL cAdd1     := PadR( "60, New Professor Colony", 35 )
   LOCAL cAdd2     := PadR( "Ludhiana, INDIA", 35 )
   LOCAL cAdd3     := PadR( hb_Version( HB_VERSION_URL_BASE ), 35 )
   LOCAL nSlry     := 20000
   LOCAL aBlocks   := {}
   LOCAL nColGet   := 8
   LOCAL GetList   := {}
   LOCAL nTop      := 4
   LOCAL nLft      := 4
   LOCAL nBtm      := 20
   LOCAL nRgt      := 75
   LOCAL cLabel    := "Harbour simulated GUI."
   LOCAL aObjects  := WvtSetObjects( {} )
   LOCAL oLastMenu
   LOCAL oError := ErrorBlock( {| o | MyError( o ) } )

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

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

   Set( _SET_EVENTMASK, INKEY_ALL + HB_INKEY_GTEVENT )

   wvt_SetGUI( .T. )
   WvtSetKeys( .T. )
   Popups( 1 )
   wvt_SetMouseMove( .T. )
   wvt_SetFont( "Courier New", 18, 0, 0 )

   CLS
   wvt_ShowWindow( SW_RESTORE )

   oLastMenu := BuildMainMenu()
   oLastMenu:disableItem( 11 )
   oLastMenu:checkItem( 1 )
   oLastMenu:insItem( 11, { "I am inserted later !", ;
      {|| wvg_MessageBox( , "Hi " + iif( oLastMenu:isItemChecked( 1 ), "Yes", "No" ) + ;
      iif( oLastMenu:isItemEnabled( 12 ), " Yes", " No" ) ) } } )

   oLastMenu:setItem( 14, { "This is Set Against Prev Menu", {|| wvg_MessageBox( , "Hi" ) } } )

   SetMode( MaxRow() + 1, MaxCol() + 1 )

   SetKey( K_F12        , {|| hb_gtInfo( HB_GTI_ACTIVATESELECTCOPY ) } )
   SetKey( K_CTRL_V     , {|| __Keyboard( hb_gtInfo( HB_GTI_CLIPBOARDDATA ) ) } )
   SetKey( K_RBUTTONDOWN, {|| __Keyboard( hb_gtInfo( HB_GTI_CLIPBOARDDATA ) ) } )

   hPopup := wvt_SetPopupMenu()

   pGT := SetGT( 1, hb_gtSelect() )

   wvt_SetMousePos( 2, 40 )

   AAdd( aBlocks, {|| wvt_SetIcon( GetResource( "vr_1.ico" ) ) } )
   AAdd( aBlocks, {|| Wvt_SetTitle( "Vouch" ) } )
   AAdd( aBlocks, {|| wvt_DrawLabel( 1, 40, cLabel, 6,, RGB( 255, 255, 255 ), RGB( 198, 198, 198 ), "Arial", 26, , , , , .T., .T. ) } )
   AAdd( aBlocks, {|| wvt_DrawBoxRaised( nTop, nLft, nBtm, nRgt ) } )
   AAdd( aBlocks, {|| wvt_DrawBoxRecessed( 7, 61, 13, 70 ) } )
   AAdd( aBlocks, {|| wvt_DrawBoxGroup( 15, 59, 18, 72 ) } )
   AAdd( aBlocks, {|| wvt_DrawBoxGroup( 5, 6, 19, 44 ) } )
   AAdd( aBlocks, {|| wvt_DrawImage( 8, 62, 12, 69, IMAGE_VOUCH, , .T. ) } )
   AAdd( aBlocks, {|| wvt_DrawBoxRecessed( 7, 48, 13, 55 ) } )
   AAdd( aBlocks, {|| wvt_DrawLine( MaxRow() - 2, 0, MaxRow() - 2, MaxCol(), WVT_LINE_HORZ, WVT_LINE_RECESSED, WVT_LINE_BOTTOM ) } )
   AAdd( aBlocks, {|| wvt_DrawLine( MaxRow() - 1, 41, MaxRow(), 41, WVT_LINE_VERT, WVT_LINE_RECESSED, WVT_LINE_CENTER ) } )
   AAdd( aBlocks, {|| AEval( GetList, {| oGet | wvt_DrawBoxGet( oGet:Row, oGet:Col, Len( Transform( oGet:VarGet(), oGet:Picture ) ) ) } ) } )

   AAdd( aBlocks, {|| wvt_Mouse( -1000001 ) } )

   aLastPaint := WvtSetBlocks( aBlocks )

   BuildButtons()

   scr := SaveScreen( 0, 0, MaxRow(), MaxCol() )
   clr := SetColor( "N/W" )
   CLS
   SetColor( "N/W,N/GR*,,,N/W*" )

   @  6, nColGet SAY "< Date >"
   @  9, nColGet SAY "<" + PadC( "Name", 33 ) + ">"
   @ 12, nColGet SAY "<" + PadC( "Address", 33 ) + ">"
   @ 16, 61      SAY "< Salary >"

   dDate := hb_SToD( "20040401" )

   @  7, nColGet GET dDate WHEN DispStatusMsg( "Date must be valid" ) VALID ClearStatusMsg()
   @ 10, nColGet GET cName WHEN DispStatusMsg( "Must be one of the list!" ) VALID VouChoice() < 7 .AND. ClearStatusMsg()
   @ 13, nColGet GET cAdd1
   @ 15, nColGet GET cAdd2
   @ 17, nColGet GET cAdd3
   @ 17, 61      GET nSlry PICTURE "@Z 9999999.99"

   WvgSetAppWindow():refresh()

   READ

   WvtSetBlocks( aLastPaint )
   WvtSetObjects( aObjects )
   SetColor( clr )
   RestScreen( 0, 0, MaxRow(), MaxCol(), scr )
   WvtSetKeys( .F. )
   wvt_SetPopupMenu( hPopup )

   Popups( 1, .T. )
   SetGT( 1, pGT )

   ErrorBlock( oError )

   RETURN

STATIC PROCEDURE WvtConsoleGets( nMode )

   hb_default( @nMode, 0 )

   IF hb_mtvm()
      hb_threadStart( {| oCrt | hb_gtReload( "WVT" ), ;
         oCrt := hb_gtSelect(), ;
         iif( nMode == 0, WvtNextGetsConsole(), OnlineMap() ), ;
         oCrt := NIL } )
   ENDIF

   RETURN

PROCEDURE WvtNextGetsConsole()

   LOCAL dDate   := hb_SToD()
   LOCAL cName   := Space( 35 )
   LOCAL cAdd1   := Space( 35 )
   LOCAL cAdd2   := Space( 35 )
   LOCAL cAdd3   := Space( 35 )
   LOCAL nSlry   := 0
   LOCAL nColGet := 8
   LOCAL GetList := {}

   SetMode( 20, 51 )
   SetColor( "N/W,N/GR*,,,N/W*" )
   CLS
   hb_gtInfo( HB_GTI_WINTITLE, "WVT Console in WVG Application" )

   @ MaxRow(), 0 SAY PadC( "GTWVT in GTWVG Console Gets", MaxCol() + 1 ) COLOR "W+/B*"

   @  2, nColGet SAY "< Date >"
   @  5, nColGet SAY "<" + PadC( "Name", 33 ) + ">"
   @  8, nColGet SAY "<" + PadC( "Address", 33 ) + ">"
   @ 15, nColGet SAY "< Salary >"

   @  3, nColGet GET dDate
   @  6, nColGet GET cName
   @  9, nColGet GET cAdd1
   @ 11, nColGet GET cAdd2
   @ 13, nColGet GET cAdd3
   @ 16, nColGet GET nSlry PICTURE "@Z 9999999.99"

   READ

   RETURN

PROCEDURE WvtNextGets()

   IF hb_mtvm()
      hb_threadStart( {|| hb_gtReload( "WVG" ), wvt_SetFont( "Terminal", 20 ), ;
         hb_clear(), wvt_ShowWindow( SW_RESTORE ), WvtNextGets_X() } )
   ELSE
      WvtNextGets_X()
   ENDIF

   RETURN

PROCEDURE WvtNextGets_X()

   LOCAL aLastPaint, clr
   LOCAL dDate      := hb_SToD()
   LOCAL cName      := Space( 35 )
   LOCAL cAdd1      := Space( 35 )
   LOCAL cAdd2      := Space( 35 )
   LOCAL cAdd3      := Space( 35 )
   LOCAL nSlry      := 0
   LOCAL aBlocks    := {}
   LOCAL nColGet    := 8
   LOCAL GetList    := {}
   LOCAL aPalette   := Wvt_GetPalette()
   LOCAL aNewPalette := AClone( aPalette )
   LOCAL aObjects   := WvtSetObjects( {} )
   LOCAL nRow       := Row()
   LOCAL nCol       := Col()
   LOCAL scr        := SaveScreen( 0, 0, MaxRow(), MaxCol() )
   LOCAL wvtScr     := wvt_SaveScreen( 0, 0, MaxRow(), MaxCol() )

   STATIC s_nPalletMultiplier := 0

   aNewPalette[ 8 ] := aNewPalette[ 8 ] + ( 100000
   AAdd( aBlocks, {|| Wvt_SetTitle( "Wvt Gets 2nd Window with Different Palette" ) } )
   AAdd( aBlocks, {|| wvt_DrawLine( MaxRow() - 1, 0, MaxRow() - 1, MaxCol() ) } )
   AAdd( aBlocks, {|| wvt_SetBrush( 0, RGB( 32, 255, 100 ) )    } )
   AAdd( aBlocks, {|| wvt_DrawEllipse( 6, 50, 10, 58 )           } )
   AAdd( aBlocks, {|| wvt_SetBrush( 2, RGB( 255, 255, 100 ), 1 ) } )
   AAdd( aBlocks, {|| wvt_DrawRectangle( 11, 50, 13, 58 )     } )
   AAdd( aBlocks, {|| wvt_DrawBoxGroupRaised( 5, 6, 19, 72 )  } )
   AAdd( aBlocks, {|| AEval( GetList, {| oGet | wvt_DrawBoxGet( oGet:Row, oGet:Col, Len( Transform( oGet:VarGet(), oGet:Picture ) ) ) } ) } )

   AAdd( aBlocks, {|| wvt_DrawButton( 21,  6, 22,  9, "New", "vouch1.bmp" )                             } )
   AAdd( aBlocks, {|| wvt_DrawButton( 21, 11, 22, 14, "Browse", "vouch1.bmp", 1, RGB( 255, 255, 255 ) )      } )


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

[Assistant]
#ifndef __HARBOUR__
#define hb_ntos( n ) LTrim( Str( n ) )
#endif

#include "inkey.ch"

PROCEDURE Main()

   MEMVAR m_testvar

   LOCAL testvar

#ifdef _SET_EVENTMASK
   Set( _SET_EVENTMASK, INKEY_ALL )
   MSetCursor( .T. )
#endif

   SET KEY K_F8 TO RECURSE()

   CLS

   @  1, 10 PROMPT "Menu Item 1" MESSAGE "Menu Message 1"
   __AtPrompt( 2, 10, "Menu Item 2", "Menu Message 2", "R+/GR, GR+/N" )
   @  3, 10 PROMPT "Menu Item 3" MESSAGE "Menu Message 3"
   @  4, 10 PROMPT "Menu Item 4" MESSAGE "Menu Message 4"

   @  6, 10 SAY "Testing with LOCAL parameter"
   @  7, 10 SAY "Press F8 to recurse into MENU TO"

   MENU TO testvar

   @  9, 10 SAY "Your Choice = " + hb_ntos( testvar )

   Inkey( 0 )

   SET KEY K_F8 TO RECURSE()

   CLS

   @  1, 10 PROMPT "Menu Item 1" MESSAGE "Menu Message 1"
   @  2, 10 PROMPT "Menu Item 2" MESSAGE "Menu Message 2"
   @  3, 10 PROMPT "Menu Item 3" MESSAGE "Menu Message 3"
   @  4, 10 PROMPT "Menu Item 4" MESSAGE "Menu Message 4"

   @  6, 10 SAY "Testing with MEMVAR parameter"
   @  7, 10 SAY "Press F8 to recurse into MENU TO"

   MENU TO m_testvar

   @  9, 10 SAY "Your Choice = " + hb_ntos( m_testvar )

   RETURN

PROCEDURE RECURSE()

   LOCAL testvar

   SET KEY K_F8 TO

   @  6, 10 SAY Space( Len( "Press F8 to recurse into MENU TO" ) )

   @  1, 50 PROMPT "Menu Item 1" MESSAGE "Menu Message 1"
   @  2, 50 PROMPT "Menu Item 2" MESSAGE "Menu Message 2"
   @  3, 50 PROMPT "Menu Item 3" MESSAGE "Menu Message 3"
   @  4, 50 PROMPT "Menu Item 4" MESSAGE "Menu Message 4"

   MENU TO testvar

   @  7, 10 SAY "Press F8 to recurse into MENU TO"

   @  9, 50 SAY "Your Choice = " + hb_ntos( testvar )

   SET KEY K_F8 TO RECURSE()

   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/tests/serial1.prg. Contains procedures: Main. This file provides platform-specific functionality

[Assistant]
#require "hbwin"

PROCEDURE Main( cPortName )

   LOCAL oWinPort := win_com():Init( cPortName, WIN_CBR_9600, WIN_NOPARITY, 8, WIN_ONESTOPBIT )
   LOCAL cString := "ATE0" + Chr( 13 ) + "ATI3" + Chr( 13 )
   LOCAL nResult

   IF ! oWinPort:Open()
      ? "Open() failed"
   ELSE
      ? "Open() succeeded"
      ?
      IF oWinPort:SetDTR( .T. )
         ? "SetDTR( .T. ) succeeded"
      ELSE
         ? "SetDTR( .T. ) failed :", oWinPort:ErrorText()
      ENDIF
      IF ( nResult := oWinPort:Write( cString ) ) == Len( cString )
         ? "Write() succeeded"
      ELSE
         ? "Write() failed, returned ", nResult, " expected ", Len( cString )
      ENDIF
      ? "Scan something... we'll not read it but purge it, press enter"
      Inkey( 0 )
      ? "Read() ", oWinPort:Read( @cString, 32 ), Len( cString ), cString
      ? oWinPort:ErrorText()
      ? "Close", oWinPort:Close()
   ENDIF

   RETURN


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

[User] Implement these Harbour functions: Harbour source file: src/rdd/dbupdat.prg. Provides functions: __dbUpdate. This file implements core Record Driver Driver functionality

[Assistant]
FUNCTION __dbUpdate( cAlias, bKey, lRandom, bAssign )

   LOCAL nOldArea := Select()
   LOCAL xKey

   LOCAL oError
   LOCAL lError := .F.

   __defaultNIL( @lRandom, .F. )

   dbGoTop()

   BEGIN SEQUENCE

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

         xKey := Eval( bKey )

         dbSelectArea( nOldArea )
         IF lRandom
            IF dbSeek( xKey )
               Eval( bAssign )
            ENDIF
         ELSE
            DO WHILE Eval( bKey ) < xKey .AND. ! Eof()
               dbSkip()
            ENDDO

            IF Eval( bKey ) == xKey .AND. ! Eof()
               Eval( bAssign )
            ENDIF
         ENDIF

         dbSelectArea( cAlias )
         dbSkip()
      ENDDO

   RECOVER USING oError
      lError := .T.
   END SEQUENCE

   dbSelectArea( nOldArea )

   IF lError
      Break( oError )
   ENDIF

   RETURN .T.


[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 'hbmysql' (MySQL database client library): contrib/hbmysql/tsqlbrw.prg. Defines classes: TBColumnSQL, TBrowseSQL. Provides functions: Skipper. This file handles database operations

[Assistant]
#include "hbclass.ch"

#include "inkey.ch"
#include "dbstruct.ch"

#include "mysql.ch"

CREATE CLASS TBColumnSQL FROM TBColumn

   VAR   oBrw

   VAR   nFieldNum

   MESSAGE  Block METHOD Block()

   METHOD   New( cHeading, bBlock, oBrw )

ENDCLASS

METHOD New( cHeading, bBlock, oBrw ) CLASS TBColumnSQL

   ::super:New( cHeading, bBlock )
   ::oBrw := oBrw

   RETURN Self

METHOD Block() CLASS TBColumnSQL

   LOCAL xValue := ::oBrw:oCurRow:FieldGet( ::nFieldNum )
   LOCAL xType := ::oBrw:oCurRow:FieldType( ::nFieldNum )

   DO CASE
   CASE xType == "N"
      xValue := "'" + Str( xValue, ::oBrw:oCurRow:FieldLen( ::nFieldNum ), ::oBrw:oCurRow:FieldDec( ::nFieldNum ) ) + "'"

   CASE xType == "D"
      xValue :=  "'" + DToC( xValue ) + "'"

   CASE xType == "L"
      xValue := iif( xValue, ".T.", ".F." )

   CASE xType == "C"

      xValue := '"' + StrTran( xValue, '"', e"\" + '\"' + \"" ) + '"'

   CASE xType == "M"
      xValue := "' <MEMO> '"

   OTHERWISE
      xValue := "'" + xValue + "'"
   ENDCASE

   RETURN hb_macroBlock( xValue )

CREATE CLASS TBrowseSQL FROM TBrowse

   VAR      oCurRow
   VAR      oQuery

   METHOD   New( nTop, nLeft, nBottom, nRight, oServer, oQuery, cTable )

   METHOD   EditField()

   METHOD   BrowseTable( lCanEdit, aExitKeys )

   METHOD   KeyboardHook( nKey )

ENDCLASS

METHOD New( nTop, nLeft, nBottom, nRight, oServer, oQuery, cTable ) CLASS TBrowseSQL

   LOCAL i, oCol

   HB_SYMBOL_UNUSED( oServer )
   HB_SYMBOL_UNUSED( cTable )

   ::super:New( nTop, nLeft, nBottom, nRight )

   ::oQuery := oQuery

   ::oCurRow := ::oQuery:GetRow( 1 )

   ::SkipBlock := {| n | ::oCurRow := Skipper( @n, ::oQuery ), n }
   ::GoBottomBlock := {|| ::oCurRow := ::oQuery:GetRow( ::oQuery:LastRec() ), 1 }
   ::GoTopBlock := {|| ::oCurRow := ::oQuery:GetRow( 1 ), 1 }

   FOR i := 1 TO ::oQuery:FCount()

      oCol := TBColumnSQL():New( ::oCurRow:FieldName( i ),, Self )

      IF !( ::oCurRow:FieldType( i ) == "M" )
         oCol:Width := Max( ::oCurRow:FieldLen( i ), Len( oCol:Heading ) )
      ELSE
         oCol:Width := 10
      ENDIF

      oCol:nFieldNum := i

      DO CASE
      CASE ::oCurRow:FieldType( i ) == "N"
         oCol:picture := Replicate( "9", oCol:Width )

      CASE ::oCurRow:FieldType( i ) $ "CM"
         oCol:picture := Replicate( "!", oCol:Width )
      ENDCASE

      ::AddColumn( oCol )
   NEXT

   RETURN Self

STATIC FUNCTION Skipper( nSkip, oQuery )

   LOCAL i := 0

   DO CASE
   CASE nSkip == 0 .OR. oQuery:LastRec() == 0
      oQuery:Skip( 0 )

   CASE nSkip > 0
      DO WHILE i < nSkip

         IF oQuery:recno() == oQuery:lastrec()
            EXIT
         ENDIF
         oQuery:Skip( 1 )
         i++

      ENDDO

   CASE nSkip < 0
      DO WHILE i > nSkip

         IF oQuery:recno() == 1
            EXIT
         ENDIF

         oQuery:Skip( -1 )
         i--

      ENDDO
   ENDCASE

   nSkip := i

   RETURN oQuery:GetRow( oQuery:RecNo() )

METHOD EditField() CLASS TBrowseSQL

   LOCAL oCol
   LOCAL aGetList
   LOCAL nKey
   LOCAL cMemoBuff, cMemo

   oCol := ::getColumn( ::colPos )

   IF ::oCurRow:FieldType( oCol:nFieldNum ) == "M"

      cMemoBuff := SaveScreen( 10, 10, 22, 69 )

      hb_Scroll( 10, 10, 22, 69, 0 )
      hb_DispBox( 10, 10, 22, 69 )

      cMemo := MemoEdit( ::oCurRow:FieldGet( oCol:nFieldNum ), 11, 11, 21, 68, .T. )

      IF LastKey() == K_CTRL_END
         ::oCurRow:FieldPut( oCol:nFieldNum, cMemo )

         IF ! ::oQuery:Update( ::oCurRow )
            Alert( Left( ::oQuery:Error(), 60 ) )
         ENDIF
      ENDIF

      RestScreen( 10, 10, 22, 69, cMemoBuff )

   ELSE

      aGetList := { GetNew( Row(), Col(),;
                            {| xValue | iif( xValue == NIL, Eval( oCol:Block ), ::oCurRow:FieldPut( oCol:nFieldNum, xValue ) ) },;
                            oCol:heading,;
                            oCol:picture,;
                            ::colorSpec ) }

      ReadModal( aGetList )

      IF ! ::oQuery:Update( ::oCurRow )
         Alert( Left( ::oQuery:Error(), 60 ) )
      ENDIF

   endif

   IF ! ::oQuery:Refresh()
      Alert( ::oQuery:Error() )
   ENDIF

   ::RefreshAll()

   nKey := LastKey()
   IF nKey == K_UP   .OR. nKey == K_DOWN .OR. ;
      nKey == K_PGUP .OR. nKey == K_PGDN

      hb_keyIns( nKey )

   ENDIF

   RETURN Self

METHOD BrowseTable( lCanEdit, aExitKeys ) CLASS TBrowseSQL

   LOCAL nKey
   LOCAL lKeepGoing := .T.

   IF ! HB_ISNUMERIC( nKey )
      nKey := NIL
   ENDIF
   hb_default( @lCanEdit, .F. )
   hb_default( @aExitKeys, { K_ESC } )

   DO WHILE lKeepGoing

      DO WHILE .T.
         nKey := Inkey()
         IF ::Stabilize() .AND. nKey != 0
            EXIT
         ENDIF
      ENDDO

      IF nKey == 0
         nKey := Inkey( 0 )
      ENDIF

      IF AScan( aExitKeys, nKey ) > 0
         lKeepGoing := .F.
         LOOP
      ENDIF

      DO CASE
      CASE nKey == K_DOWN
         ::down()

      CASE nKey == K_PGDN
         ::pageDown()

      CASE nKey == K_CTRL_PGDN
         ::goBottom()

      CASE nKey == K_UP
         ::up()

      CASE nKey == K_PGUP
         ::pageUp()

      CASE nKey == K_CTRL_PGUP
         ::goTop()

      CASE nKey == K_RIGHT
         ::right()

      CASE nKey == K_LEFT
         ::left()

      CASE nKey == K_HOME
         ::home()

      CASE nKey == K_END
         ::end()

      CASE nKey == K_CTRL_LEFT
         ::panLeft()

      CASE nKey == K_CTRL_RIGHT
         ::panRight()

      CASE nKey == K_CTRL_HOME
         ::panHome()

      CASE nKey == K_CTRL_END
         ::panEnd()

      CASE nKey == K_ENTER .AND. lCanEdit
         ::EditField()

      OTHERWISE
         ::KeyboardHook( nKey )
      ENDCASE
   ENDDO

   RETURN Self

METHOD KeyboardHook( nKey ) CLASS TBrowseSQL

   HB_SYMBOL_UNUSED( nKey )

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

[Assistant]
#require "hbwin"

PROCEDURE Main()

   LOCAL oPC, nTime, cDefaultPrinter, cFilename, oPrinter, nEvent := 0

   IF Empty( oPC := win_oleCreateObject( "PDFCreator.clsPDFCreator" ) )
      ? "Unable to create PDFCreator COM object"
      RETURN
   ENDIF

   cFilename := hb_ProgName()

   oPC:__hSink := __axRegisterHandler( oPC:__hObj, {| X | nEvent := X } )

   oPC:cStart( "/NoProcessingAtStartup" )
   oPC:_cOption( "UseAutosave", 1 )
   oPC:_cOption( "UseAutosaveDirectory", 1 )
   oPC:_cOption( "AutosaveDirectory", Left( cFileName, RAt( hb_ps(), cFilename ) - 1 ) )
   oPC:_cOption( "AutosaveFilename", "pdfcreat.pdf" )
   oPC:_cOption( "AutosaveFormat", 0 )

   cDefaultPrinter := oPC:cDefaultPrinter
   oPC:cDefaultPrinter := "PDFCreator"
   oPC:cClearCache()

#if 1
   oPrinter := win_Prn():New( "PDFCreator" )
   oPrinter:Create()
   oPrinter:startDoc( "Harbour print job via PDFCreator" )
   oPrinter:NewLine()
   oPrinter:NewLine()
   oPrinter:TextOut( "Hello, PDFCreator! This is Harbour :)" )
   oPrinter:EndDoc()
   oPrinter:Destroy()
#else
   oPrinter := NIL
   ? "Do some printing to PDFCreator printer and press any key..."
   Inkey( 0 )
#endif

   oPC:cPrinterStop := .F.

   nTime := hb_MilliSeconds()
   DO WHILE nEvent == 0 .AND. hb_MilliSeconds() - nTime < 10000
      hb_idleSleep( 0.5 )

      oPC:cOption( "UseAutosave" )
   ENDDO

   IF nEvent == 0
      ? "Print timeout"
   ELSEIF nEvent == 1
      ? "Printed successfully"
   ELSEIF nEvent == 2
      ? "Error:", oPC:cError():Description
   ELSE
      ? "Unknown event"
   ENDIF

   oPC:cDefaultPrinter := cDefaultPrinter
   oPC:cClose()
   oPC := NIL

   RETURN


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

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

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

[Assistant]
#ifdef __HARBOUR__
#require "hbct"
#else
#define hb_ntos( n ) LTrim( Str( n ) )
#endif

#include "ct.ch"

PROCEDURE Main()

   LOCAL cRet, olderr

   ctinit()

   ? "Begin test of CSetArgErr()"
   ?

   ?
   ? "Local error handler: "

   olderr := ErrorBlock( {| oerr | myerrhandler( oerr ) } )

   ?
   ? "Standard behaviour"
   ? "  Call to AddAscii( 5789676, 1, 2, .T. ):"
   cRet := AddAscii( 5789676, 1, 2, .T. )
   ? "  return value was", cRet
   ?
   ? "  Call to CharAdd( 'AA', .F. ):"
   cRet := CharAdd( "AA", .F. )
   ? "  return value was", cRet, "<Press any key>"
   ?
   Inkey( 0 )

   ?
   ? "CT_ARGERR_WHOCARES behaviour"
   CSetArgErr( CT_ARGERR_WHOCARES )
   ? "  Call to AddAscii( 5789676, 1, 2, .T. ):"
   cRet := AddAscii( 5789676, 1, 2, .T. )
   ? "  return value was", cRet
   ?
   ? "  Call to CharAdd( 'AA', .F. ):"
   cRet := CharAdd( "AA", .F. )
   ? "  return value was", cRet, "<Press any key>"
   ?
   Inkey( 0 )

   ?
   ? "CT_ARGERR_WARNING behaviour"
   CSetArgErr( CT_ARGERR_WARNING )
   ? "  Call to AddAscii( 5789676, 1, 2, .T. ):"
   cRet := AddAscii( 5789676, 1, 2, .T. )
   ? "  return value was", cRet
   ?
   ? "  Call to CharAdd( 'AA', .F. ):"
   cRet := CharAdd( "AA", .F. )
   ? "  return value was", cRet, "<Press any key>"
   ?
   Inkey( 0 )

   ?
   ? "CT_ARGERR_ERROR behaviour"
   CSetArgErr( CT_ARGERR_ERROR )
   ? "  Call to AddAscii( 5789676, 1, 2, .T. ):"
   cRet := AddAscii( 5789676, 1, 2, .T. )
   ? "  return value was", cRet
   ?
   ? "  Call to CharAdd( 'AA', .F. ):"
   cRet := CharAdd( "AA", .F. )
   ? "  return value was", cRet, "<Press any key>"
   ?
   Inkey( 0 )

   ?
   ? "CT_ARGERR_CATASTROPHIC behaviour"
   CSetArgErr( CT_ARGERR_CATASTROPHIC )
   ? "  Call to AddAscii( 5789676, 1, 2, .T. ):"
   cRet := AddAscii( 5789676, 1, 2, .T. )
   ? "  return value was", cRet
   ?
   ? "  Call to CharAdd( 'AA', .F. ):"
   cRet := CharAdd( "AA", .F. )
   ? "  return value was", cRet, "<Press any key>"
   ?
   Inkey( 0 )

   ?
   ? "Standard error handler: "
   ErrorBlock( olderr )

   ?
   ? "Standard behaviour"
   ? "  Call to CharAdd( 'AA', .F. ):"
   cRet := CharAdd( "AA", .F. )
   ? "  return value was", cRet, "<Press any key>"
   ?
   Inkey( 0 )

   ?
   ? "CT_ARGERR_WHOCARES behaviour"
   CSetArgErr( CT_ARGERR_WHOCARES )
   ? "  Call to CharAdd( 'AA', .F. ):"
   cRet := CharAdd( "AA", .F. )
   ? "  return value was", cRet, "<Press any key>"
   ?
   Inkey( 0 )

   ?
   ? "CT_ARGERR_WARNING behaviour"
   CSetArgErr( CT_ARGERR_WARNING )
   ? "  Call to CharAdd( 'AA', .F. ):"
   cRet := CharAdd( "AA", .F. )
   ? "  return value was", cRet, "<Press any key>"
   ?
   Inkey( 0 )

   ?
   ? "CT_ARGERR_ERROR behaviour"
   CSetArgErr( CT_ARGERR_ERROR )
   ? "  Call to CharAdd( 'AA', .F. ):"
   cRet := CharAdd( "AA", .F. )
   ? "  return value was", cRet, "<Press any key>"
   ?
   Inkey( 0 )

   ?
   ? "CT_ARGERR_CATASTROPHIC behaviour"
   CSetArgErr( CT_ARGERR_CATASTROPHIC )
   ? "  Call to CharAdd( 'AA', .F. ):"
   cRet := CharAdd( "AA", .F. )
   ? "  return value was", cRet, "<Press any key>"
   ?
   Inkey( 0 )

   ? "End test of CSetArgErr()"

   ctexit()

   RETURN

FUNCTION myerrhandler( oerr )

   LOCAL ni, nDigit

   LOCAL cInput

   ? "    Error handler called:"
   ? "      err:severity.....:", oerr:severity
   ? "      err:subSystem....:", oerr:subSystem
   ? "      err:operation....:", oerr:operation
   ? "      Len(err:args)....:", Len( oerr:args )
   FOR ni := 1 TO Len( oerr:args )
      ? "          err:args[" + hb_ntos( ni ) + "]..:", oerr:args[ ni ]
   NEXT
   ? "      err:genCode......:", oerr:genCode
   ? "      err:subCode......:", oerr:subCode
   ? "      err:osCode.......:", oerr:osCode
   ? "      err:filename.....:", oerr:filename
   ? "      err:tries........:", oerr:tries
   ? "      err:cargo........:", oerr:cargo
   ? "      err:canDefault...:", oerr:canDefault
   ? "      err:canRetry.....:", oerr:canRetry
   ? "      err:canSubstitute:", oerr:canSubstitute
   ?

   IF oerr:canSubstitute

      ? "    Error handler can substitute return value, so please"
      ACCEPT "    type in return value <Return for default>: " TO cInput

      IF Empty( cInput )
         ? "    You have chosen the default return value. Ok, this should "
         ? "    be now problem, since the last digit of err:subCode indicates"
         ? "    the type of the return value:"
         ? "      0 is NIL,    1 is String,    2 is Integer,"
         ? "      3 is Float,  4 is Boolean,   5 is Date"
         ? "      6 is Block,  7 is Array,    8 is Object"
         ? "      9 is unknown"
         nDigit := Int( oerr:subCode % 10 )
         ? "    Here it's a " + hb_ntos( nDigit ) + ", so I return a "
         DO CASE
         CASE nDigit == 0
            ?? "NIL."
            cInput  := NIL

         CASE nDigit == 1
            ?? "String."
            cInput := ""

         CASE nDigit == 2
            ?? "Integer."
            cInput := 0

         CASE nDigit == 3
            ?? "Float."
            cInput := 0.0

         CASE nDigit == 4
            ?? "Boolean."
            cInput := .F.

         CASE nDigit == 5
            ?? "Date."
            cInput := CToD( "" )

         CASE nDigit == 6
            ?? "Block."
            cInput := {|| NIL }

         CASE nDigit == 7
            ?? "Array."
            cInput := {}

         CASE nDigit == 8
            ?? "Object."
            cInput := GetNew()

         CASE nDigit == 9
            ?? "<don't know, NIL would be best."
            cInput := NIL

         ENDCASE

      ENDIF

      RETURN cInput

   ENDIF

   IF oerr:canDefault
      ? "    Subsystem can set the default value itself, so this error"
      ? "    is only informative."
   ENDIF

   RETURN .F.


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

[User] Create Harbour OOP classes for the functionality described: Harbour Runtime Library file: src/rtl/tbrowse.prg. Defines classes: TBrowse. Provides functions: TBrowseNew. This file implements object-oriented classes using Harbour's class system

[Assistant]
#include "hbclass.ch"

#include "button.ch"
#include "color.ch"
#include "error.ch"
#include "inkey.ch"
#include "setcurs.ch"
#include "tbrowse.ch"

#define _TBCI_COLOBJECT       1
#define _TBCI_COLWIDTH        2
#define _TBCI_COLPOS          3
#define _TBCI_CELLWIDTH       4
#define _TBCI_CELLPOS         5
#define _TBCI_COLSEP          6
#define _TBCI_SEPWIDTH        7
#define _TBCI_HEADING         8
#define _TBCI_FOOTING         9
#define _TBCI_HEADSEP        10
#define _TBCI_FOOTSEP        11
#define _TBCI_DEFCOLOR       12
#define _TBCI_FROZENSPACE    13
#define _TBCI_LASTSPACE      14
#define _TBCI_SIZE           14

#define _TBC_SETKEY_KEY       1
#define _TBC_SETKEY_BLOCK     2

#define _TBC_CLR_STANDARD     1
#define _TBC_CLR_SELECTED     2
#define _TBC_CLR_HEADING      3
#define _TBC_CLR_FOOTING      4
#define _TBC_CLR_MAX          4

#define _TBR_CONF_COLORS      1
#define _TBR_CONF_COLUMNS     2
#define _TBR_CONF_ALL         3

#define _TBR_CHR_LINEDELIMITER ";"

#define _TBR_COORD( n )       Int( n )

CREATE CLASS TBrowse

   VAR cargo      AS USUAL          EXPORTED

   PROTECTED:

   VAR n_Top      AS NUMERIC INIT 0
   VAR n_Left     AS NUMERIC INIT 0
   VAR n_Bottom   AS NUMERIC INIT 0
   VAR n_Right    AS NUMERIC INIT 0

   VAR columns    AS ARRAY INIT {}

   VAR cHeadSep   AS CHARACTER INIT ""
   VAR cColSep    AS CHARACTER INIT " "
   VAR cFootSep   AS CHARACTER INIT ""

   VAR cColorSpec AS CHARACTER

   VAR bSkipBlock     AS BLOCK INIT {|| NIL }
   VAR bGoTopBlock    AS BLOCK INIT {|| NIL }
   VAR bGoBottomBlock AS BLOCK INIT {|| NIL }

   VAR dummy                   INIT ""

#ifdef HB_COMPAT_C53
   VAR cBorder    AS CHARACTER
   VAR cMessage
   VAR keys       AS ARRAY
   VAR styles     AS ARRAY
#endif

   EXPORTED:

#ifdef HB_COMPAT_C53
#ifdef HB_BRW_STATICMOUSE
   VAR mRowPos    AS INTEGER INIT 0
   VAR mColPos    AS INTEGER INIT 0
#else
   METHOD mRowPos SETGET
   METHOD mColPos SETGET
#endif

   METHOD setStyle( nStyle, lNewValue )
   METHOD setKey( nKey, bBlock )
   METHOD applyKey( nKey )
   METHOD hitTest( mRow, mCol )
   METHOD nRow SETGET
   METHOD nCol SETGET
   METHOD border( cBorder ) SETGET
   METHOD message( cMessage ) SETGET
#endif

   METHOD nTop( nTop ) SETGET
   METHOD nLeft( nLeft ) SETGET
   METHOD nBottom( nBottom ) SETGET
   METHOD nRight( nRight ) SETGET

   METHOD headSep( cHeadSep ) SETGET
   METHOD colSep( cColSep ) SETGET
   METHOD footSep( cFootSep ) SETGET
   METHOD skipBlock( bSkipBlock ) SETGET
   METHOD goTopBlock( bBlock ) SETGET
   METHOD goBottomBlock( bBlock ) SETGET

   METHOD colorSpec( cColorSpec ) SETGET

   ACCESS rowPos    METHOD getRowPos
   ASSIGN rowPos    METHOD setRowPos

   ACCESS colPos    METHOD getColPos
   ASSIGN colPos    METHOD setColPos

   ACCESS freeze    METHOD getFrozen
   ASSIGN freeze    METHOD freeze

   ACCESS hitTop    METHOD getTopFlag
   ASSIGN hitTop    METHOD setTopFlag

   ACCESS hitBottom METHOD getBottomFlag
   ASSIGN hitBottom METHOD setBottomFlag

   ACCESS autoLite  METHOD getAutoLite
   ASSIGN autoLite  METHOD setAutoLite

   ACCESS stable    METHOD getStableFlag
   ASSIGN stable    METHOD setStableFlag

   METHOD addColumn( oCol )
   METHOD delColumn( nColumn )
   METHOD insColumn( nColumn, oCol )
   METHOD setColumn( nColumn, oCol )
   METHOD getColumn( nColumn )

   METHOD rowCount()
   METHOD colCount()

   METHOD colWidth( nColumn )

   METHOD leftVisible()
   METHOD rightVisible()

   METHOD hilite()
   METHOD deHilite()
   METHOD refreshAll()
   METHOD refreshCurrent()
   METHOD forceStable()
   METHOD invalidate()

   METHOD up()
   METHOD down()
   METHOD left()
   METHOD right()
   METHOD pageUp()
   METHOD pageDown()
   METHOD home()
   METHOD end()

   METHOD goTop()
   METHOD goBottom()

   METHOD panLeft()
   METHOD panRight()
   METHOD panHome()
   METHOD panEnd()

   METHOD stabilize()
   METHOD colorRect( aRect, aColors )

   METHOD configure( nMode )

   METHOD init( nTop, nLeft, nBottom, nRight )

   PROTECTED:

   VAR nRowPos       AS INTEGER INIT 1
   VAR nColPos       AS INTEGER INIT 1
   VAR nLeftVisible  AS INTEGER INIT 0
   VAR nRightVisible AS INTEGER INIT 0
   VAR n_Row         AS INTEGER INIT 0
   VAR n_Col         AS INTEGER INIT 0
   VAR nHeadHeight   AS INTEGER INIT 0
   VAR nFootHeight   AS INTEGER INIT 0
   VAR nFrozen       AS INTEGER INIT 0
   VAR nBufferPos    AS INTEGER INIT 1
   VAR nMoveOffset   AS INTEGER INIT 0
   VAR nLastRow      AS INTEGER INIT 0
   VAR nLastScroll   AS INTEGER INIT 0
   VAR nConfigure    AS INTEGER INIT _TBR_CONF_ALL
   VAR nLastPos      AS INTEGER INIT 0
   VAR lHitTop       AS LOGICAL INIT .F.
   VAR lHitBottom    AS LOGICAL INIT .F.
   VAR lHiLited      AS LOGICAL INIT .F.
   VAR lAutoLite     AS LOGICAL INIT .T.
   VAR lStable       AS LOGICAL INIT .F.
   VAR lInvalid      AS LOGICAL INIT .T.
   VAR lRefresh      AS LOGICAL INIT .F.
   VAR lFrames       AS LOGICAL INIT .F.
   VAR lHeadSep      AS LOGICAL INIT .F.
   VAR lFootSep      AS LOGICAL INIT .F.
   VAR aColData      AS ARRAY   INIT {}
   VAR aColors       AS ARRAY   INIT {}
   VAR aDispStatus   AS ARRAY   INIT {}
   VAR aCellStatus   AS ARRAY   INIT {}
   VAR aCellValues   AS ARRAY   INIT {}
   VAR aCellColors   AS ARRAY   INIT {}

   METHOD doConfigure()
   METHOD setUnstable()
   METHOD setPosition()
   METHOD readRecord( nRow )

   METHOD setVisible()
   METHOD setCursorPos()
   METHOD scrollBuffer( nRows )
   METHOD colorValue( nColorIndex )
   METHOD cellValue( nRow, nCol )
   METHOD cellColor( nRow, nCol )
   METHOD dispFrames()
   METHOD dispRow( nRow )

#ifndef HB_BRW_STATICMOUSE
   FRIEND FUNCTION _mBrwPos
#endif

ENDCLASS

FUNCTION TBrowseNew( nTop, nLeft, nBottom, nRight )
   RETURN TBrowse():new( nTop, nLeft, nBottom, nRight )


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

[Assistant]
PROCEDURE hb_HashAddMember( aName, cType, uInit, oObj )

   LOCAL cName

   IF !( cType == NIL )

      SWITCH Upper( Left( cType, 1 ) )
      CASE "S"

         IF uInit == NIL
            uInit := ""
         ENDIF

         EXIT

      CASE "N"

         IF uInit == NIL
            uInit := 0
         ENDIF

         EXIT

      CASE "L"

         IF uInit == NIL
            uInit := .F.
         ENDIF

         EXIT

      CASE "D"

         IF uInit == NIL
            uInit := hb_SToD()
         ENDIF

         EXIT

      CASE "C"

         IF uInit == NIL
            uInit := {|| NIL }
         ENDIF

         EXIT

      CASE "A"

         IF uInit == NIL
            uInit := {}
         ENDIF

         EXIT

      CASE "O"
         EXIT

      ENDSWITCH
   ENDIF

   FOR EACH cName IN aName
      oObj[ cName ] := uInit
   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 header file: include/hblang.ch. Defines 9 constants including: HB_LANG_CH_, HB_LANG_ITEM_BASE_ID, HB_LANG_ITEM_BASE_MONTH, HB_LANG_ITEM_BASE_DAY, HB_LANG_ITEM_BASE_NATMSG. Defines Harbour internal constants and macros

[Assistant]
#ifndef HB_LANG_CH_
#define HB_LANG_CH_

#define HB_LANG_ITEM_BASE_ID            0
#define HB_LANG_ITEM_BASE_MONTH         6
#define HB_LANG_ITEM_BASE_DAY           18
#define HB_LANG_ITEM_BASE_NATMSG        25
#define HB_LANG_ITEM_BASE_ERRDESC       38
#define HB_LANG_ITEM_BASE_ERRINTR       89
#define HB_LANG_ITEM_BASE_TEXT          115
#define HB_LANG_ITEM_MAX_               118

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

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

PROCEDURE Main()

   ctinit()

   ? "Begin test of CharMix()"
   ?

   ? "Simple tests:"
   ? '  CharMix( "ABC", "123" )  == "A1B2C3"     ? --> "' + CharMix( "ABC", "123" )  + '"'
   ? '  CharMix( "ABCDE", "12" ) == "A1B2C1D2E1" ? --> "' + CharMix( "ABCDE", "12" ) + '"'
   ? '  CharMix( "AB", "12345" ) == "A1B2"       ? --> "' + CharMix( "AB", "12345" ) + '"'
   ? '  CharMix( "HELLO", " " )  == "H E L L O " ? --> "' + CharMix( "HELLO", " " )  + '"'
   ? '  CharMix( "HELLO", "" )   == "HELLO"      ? --> "' + CharMix( "HELLO", "" )   + '"'
   ?

   ? "End test of CharMix()"
   ?

   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 the following Harbour (xBase/Clipper) code:

Harbour contribution module 'hbtip' (Internet protocol utilities (FTP, HTTP, SMTP, POP3)): contrib/hbtip/encoder.prg. Defines classes: TIPEncoder. Provides functions: tip_GetEncoder. This file provides network protocol implementations

[Assistant]
#include "hbclass.ch"

#include "fileio.ch"

CREATE CLASS TIPEncoder

   VAR cName

   METHOD New( cMode )
   METHOD Encode( cData )
   METHOD Decode( cData )

ENDCLASS

#define MODE_PASSTHROUGH  "as-is"

METHOD New( cMode ) CLASS TIPEncoder

   ::cName := Lower( hb_defaultValue( cMode, MODE_PASSTHROUGH ) )

   RETURN Self

METHOD Encode( cData ) CLASS TIPEncoder
   RETURN iif( ::cName == MODE_PASSTHROUGH, cData, tip_GetEncoder( ::cName ):Encode( cData ) )

METHOD Decode( cData ) CLASS TIPEncoder
   RETURN iif( ::cName == MODE_PASSTHROUGH, cData, tip_GetEncoder( ::cName ):Decode( cData ) )

FUNCTION tip_GetEncoder( cMode )

   SWITCH Lower( hb_defaultValue( cMode, MODE_PASSTHROUGH ) )
   CASE "base64"           ; RETURN TIPEncoderBase64():New()
   CASE "quoted-printable" ; RETURN TIPEncoderQP():New()
   CASE "url"
   CASE "urlencoded"       ; RETURN TIPEncoderUrl():New()
   ENDSWITCH

   RETURN TIPEncoder():New()


[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 'hbpgsql' (PostgreSQL database client library): contrib/hbpgsql/tests/dbf2pg.prg. Contains procedures: Main, Help. This file handles database operations

[Assistant]
#require "hbpgsql"

#include "fileio.ch"
#include "inkey.ch"

#include "hbextcdp.ch"

PROCEDURE Main()

   LOCAL cHostName
   LOCAL cUser
   LOCAL cPassword
   LOCAL cDatabase := "postgres", cTable, cFile
   LOCAL i
   LOCAL lCreateTable := .F.
   LOCAL oServer, oTable, oRecord
   LOCAL cField
   LOCAL cTypeDB
   LOCAL cTypePG
   LOCAL cValue
   LOCAL nCommit := 100
   LOCAL hFile
   LOCAL nCount := 0
   LOCAL nRecno := 0
   LOCAL lTruncate := .F.
   LOCAL lUseTrans := .F.
   LOCAL cPath := "public"

   Set( _SET_DATEFORMAT, "yyyy-mm-dd" )
   Set( _SET_DELETED, .T. )

   FOR i := 1 TO PCount()

      SWITCH hb_PValue( i )
      CASE "-h" ; cHostName := hb_PValue( ++i ) ; EXIT
      CASE "-d" ; cDatabase := hb_PValue( ++i ) ; EXIT
      CASE "-t" ; cTable := AllTrim( hb_PValue( ++i ) ) ; EXIT
      CASE "-f" ; cFile := hb_PValue( ++i ) ; EXIT
      CASE "-u" ; cUser := hb_PValue( ++i ) ; EXIT
      CASE "-p" ; cPassword := hb_PValue( ++i ) ; EXIT
      CASE "-c" ; lCreateTable := .T. ; EXIT
      CASE "-x" ; lTruncate := .T. ; EXIT
      CASE "-s" ; lUseTrans := .T. ; EXIT
      CASE "-m" ; nCommit := Val( hb_PValue( ++i ) ) ; EXIT
      CASE "-r" ; nRecno := Val( hb_PValue( ++i ) ) ; EXIT
      CASE "-e" ; cPath := hb_PValue( ++i ) ; EXIT
      CASE "-cp" ; Set( _SET_DBCODEPAGE, hb_PValue( ++i ) ) ; EXIT
      OTHERWISE
         help()
         RETURN
      ENDSWITCH
   NEXT

   IF Empty( cTable ) .OR. cFile == ""
      help()
      RETURN
   ENDIF

   IF ( hFile := hb_vfOpen( cTable + ".log", FO_CREAT + FO_TRUNC + FO_WRITE ) ) == NIL
      ? "Cannot create log file"
      RETURN
   ENDIF

   USE ( cFile ) SHARED READONLY

   oServer := TPQServer():New( cHostName, cDatabase, cUser, cPassword, , cPath )
   IF oServer:NetErr()
      ? oServer:ErrorMsg()
      RETURN
   ENDIF

   oServer:lallCols := .F.

   IF lCreateTable
      IF oServer:TableExists( cTable )
         oServer:DeleteTable( cTable )
         IF oServer:NetErr()
            ? oServer:ErrorMsg()
            hb_vfWrite( hFile, "Error: " + oServer:ErrorMsg() + hb_eol() )
            hb_vfClose( hFile )
            RETURN
         ENDIF
      ENDIF

      oServer:CreateTable( cTable, dbStruct() )
      IF oServer:NetErr()
         ? oServer:ErrorMsg()
         hb_vfWrite( hFile, "Error: " + oServer:ErrorMsg() + hb_eol() )
         hb_vfClose( hFile )
         RETURN
      ENDIF
   ENDIF

   IF lTruncate
      oServer:Execute( "truncate table " + cTable )
      IF oServer:NetErr()
         ? oServer:ErrorMsg()
         hb_vfWrite( hFile, "Error: " + oServer:ErrorMsg() + hb_eol() )
         hb_vfClose( hFile )
         RETURN
      ENDIF
   ENDIF

   oTable := oServer:Query( "SELECT * FROM " + cTable + " LIMIT 1" )
   IF oTable:NetErr()
      ? oTable:ErrorMsg()
      hb_vfWrite( hFile, "Error: " + oTable:ErrorMsg() + hb_eol() )
      hb_vfClose( hFile )
      RETURN
   ENDIF

   IF lUseTrans
      oServer:StartTransaction()
   ENDIF

   hb_vfWrite( hFile, "Start: " + Time() + hb_eol() )

   ? "Start:", Time()
   ?

   IF nRecno != 0
      dbGoto( nRecno )
   ENDIF

   DO WHILE ! Eof() .AND. hb_keyStd( Inkey() ) != K_ESC .AND. ( nRecno == 0 .OR. nRecno == RecNo() )
      oRecord := oTable:GetBlankRow()

      FOR i := 1 TO oTable:FCount()
         cField := Lower( oTable:FieldName( i ) )
         cTypeDB := Left( hb_FieldType( FieldPos( cField ) ), 1 )
         cTypePG := oRecord:FieldType( i )
         cValue := FieldGet( FieldPos( cField ) )

         IF cValue != NIL
            IF cTypePG != cTypeDB
               DO CASE
               CASE cTypePG == "C" .AND. cTypeDB $ "NIYF8BZ24" ; cValue := hb_ntos( cValue )
               CASE cTypePG == "C" .AND. cTypeDB == "D" ; cValue := DToC( cValue )
               CASE cTypePG == "C" .AND. cTypeDB $ "T@" ; cValue := hb_TToC( cValue )
               CASE cTypePG == "C" .AND. cTypeDB == "L" ; cValue := iif( cValue, "S", "N" )
               CASE cTypePG == "N" .AND. cTypeDB $ "CQ" ; cValue := Val( cValue )
               CASE cTypePG == "N" .AND. cTypeDB == "D" ; cValue := Val( DToS( cValue ) )
               CASE cTypePG == "N" .AND. cTypeDB == "L" ; cValue := iif( cValue, 1, 0 )
               CASE cTypePG == "D" .AND. cTypeDB $ "CQ" ; cValue := CToD( cValue )
               CASE cTypePG == "D" .AND. cTypeDB $ "NIYF8BZ24" ; cValue := hb_SToD( hb_ntos( cValue ) )
               CASE cTypePG == "L" .AND. cTypeDB $ "NIYF8BZ24" ; cValue := ! Empty( cValue )
               CASE cTypePG == "L" .AND. cTypeDB $ "CQ" ; cValue := AllTrim( cValue ) $ "YySs1"
               ENDCASE
            ENDIF

            IF cValue != NIL
               IF oRecord:FieldType( i ) == "C" .OR. oRecord:FieldType( i ) == "M"
                  oRecord:FieldPut( i, hb_StrToUTF8( cValue ) )
               ELSE
                  oRecord:FieldPut( i, cValue )
               ENDIF
            ENDIF
         ENDIF
      NEXT

      oTable:Append( oRecord )

      IF oTable:NetErr()
         ?
         ? "Error Record:", RecNo(), Left( oTable:ErrorMsg(), 70 )
         ?
         hb_vfWrite( hFile, "Error at record: " + hb_ntos( RecNo() ) + " Description: " + oTable:ErrorMsg() + hb_eol() )
      ELSE
         nCount++
      ENDIF

      dbSkip()

      IF nCount % nCommit == 0
         DevPos( Row(), 1 )
         DevOut( "imported recs:", hb_ntos( nCount ) )

         IF lUseTrans
            oServer:commit()
            oServer:StartTransaction()
         ENDIF
      ENDIF
   ENDDO

   IF nCount % nCommit != 0 .AND. lUseTrans
      oServer:commit()
   ENDIF

   hb_vfWrite( hFile, "End: " + Time() + ", records in dbf: " + hb_ntos( RecNo() ) + ", imported recs: " + hb_ntos( nCount ) + hb_eol() )

   ? "End:", Time()

   hb_vfClose( hFile )

   dbCloseAll()

   oTable:Destroy()
   oServer:Destroy()

   RETURN

STATIC PROCEDURE Help()

   ? "dbf2pg - dbf file to PostgreSQL table conversion utility"
   ? "-h hostname"
   ? "-u user"
   ? "-p password"
   ? "-d name of database to use (default: postgres)"
   ? "-t name of table to add records to (required)"
   ? "-c delete existing table and create a new one"
   ? "-f name of .dbf file to import (required)"
   ? "-x truncate table before append records"
   ? "-s use transaction"
   ? "-m commit interval"
   ? "-r insert only record number"
   ? "-e search path"
   ?

   RETURN


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

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

Harbour contribution module 'hbtip' (Internet protocol utilities (FTP, HTTP, SMTP, POP3)): contrib/hbtip/tests/ftp_ul.prg. Contains procedures: Main. This file provides network protocol implementations

[Assistant]
#require "hbtip"

#include "directry.ch"

PROCEDURE Main( cURL, cMask )

   LOCAL lRetVal := .T.

   LOCAL aFiles, aFile
   LOCAL oFTP, oURL

   IF ! Empty( aFiles := hb_vfDirectory( hb_defaultValue( cMask, hb_osFileMask() ) ) )

      hb_default( @cURL, "ftp:

      oURL := TUrl():New( cURL )

      oFTP := TIPClientFTP():New( oURL, .T. )
      oFTP:nConnTimeout := 20000
      oFTP:bUsePasv := .T.

      IF oFTP:Open( cURL )
         FOR EACH aFile IN aFiles
            ? "Filename:", aFile[ F_NAME ]
            IF ! oFtp:UploadFile( aFile[ F_NAME ] )
               lRetVal := .F.
               EXIT
            ENDIF
         NEXT
         oFTP:Close()
      ELSE
         ? "Could not connect to FTP server", oURL:cServer
         IF oFTP:SocketCon == NIL
            ? "Connection not initialized"
         ELSEIF hb_inetErrorCode( oFTP:SocketCon ) == 0
            ? "Server response:", oFTP:cReply
         ELSE
            ? "Error in connection:", hb_inetErrorDesc( oFTP:SocketCon )
         ENDIF
         lRetVal := .F.
      ENDIF
   ENDIF

   ErrorLevel( iif( lRetVal, 0, 1 ) )

   RETURN