Clipper On Line • Ver Tópico - Usando -e3 -es2
Página 1 de 2

Usando -e3 -es2

MensagemEnviado: 28 Mai 2019 21:22
por JoséQuintas
Esta é a getsys do outro post.
Aproveitar pra mostrar como ajustar os erros da compilação -w3 -es2 (chamo de tolerância zero), e vantagens.

/***
*
*  Getsys.prg
*
*  Standard Clipper 5.2 GET/READ Subsystem
*
*  Copyright (c) 1991-1993, Computer Associates International, Inc.
*  All rights reserved.
*
*  This version adds the following public functions:
*
*    ReadKill( [<lKill>] )       --> lKill
*    ReadUpdated( [<lUpdated>] ) --> lUpdated
*    ReadFormat( [<bFormat>] )   --> bFormat | NIL
*
*  NOTE: compile with /m /n /w
*
*/

#include "Inkey.ch"
#include "Getexit.ch"

STATIC snMRow, snMCol
STATIC  nMRow,  nMCol

/***
*  Nation Message Constants
*  These constants are used with the NationMsg(<msg>) function.
*  The <msg> parameter can range from 1-12 and returns the national
*  version of the system message.
*/
#define _GET_INSERT_ON   7    // "Ins"
#define _GET_INSERT_OFF   8    // "   "
#define _GET_INVD_DATE   9    // "Invalid Date"
#define _GET_RANGE_FROM   10    // "Range: "
#define _GET_RANGE_TO   11    // " - "

#define K_UNDO          K_CTRL_U

//
// State variables for active READ
//
STATIC sbFormat
STATIC slUpdated := .F.
STATIC slKillRead
STATIC slBumpTop
STATIC slBumpBot
STATIC snLastExitState
STATIC snLastPos
STATIC soActiveGet
STATIC scReadProcName
STATIC snReadProcLine

//
// Format of array used to preserve state variables
//
#define GSV_KILLREAD     1
#define GSV_BUMPTOP        2
#define GSV_BUMPBOT        3
#define GSV_LASTEXIT     4
#define GSV_LASTPOS        5
#define GSV_ACTIVEGET     6
#define GSV_READVAR        7
#define GSV_READPROCNAME   8
#define GSV_READPROCLINE   9

#define GSV_COUNT        9

/***
*
*  ReadModal()
*
*  Standard modal READ on an array of GETs
*
*/
FUNCTION ReadModal( GetList, nPos )
LOCAL oGet
LOCAL aSavGetSysVars
PUBLIC nKey2 := SPACE(0)

PRIVATE GetMsg := {},PosMsg:=nPos
FOR nI := 1 TO LEN(GetList)
   IF VALTYPE(GetList[nI])<>"O"
    AADD(GetMsg ,GetList[nI,2])
    GetList[nI] := GetList[nI,1]
   ELSE
    AADD(GetMsg ,)
   ENDIF
NEXT

   IF ( VALTYPE( sbFormat ) == "B" )
    EVAL( sbFormat )
   ENDIF

   IF ( EMPTY( GetList ) )

    // S'87 compatibility
    SETPOS( MAXROW() - 1, 0 )
    RETURN (.F.)             // NOTE

   ENDIF

   // Preserve state variables
   aSavGetSysVars := ClearGetSysVars()

   // Set these for use in SET KEYs
   scReadProcName := PROCNAME( 1 )
   snReadProcLine := PROCLINE( 1 )

   // Set initial GET to be read
   IF !( VALTYPE( nPos ) == "N" .AND. nPos > 0 )
    nPos := Settle( Getlist, 0 )
    PosMsg:=nPos
   ENDIF

   WHILE !( nPos == 0 )

    // Get next GET from list and post it as the active GET
    PostActiveGet( oGet := GetList[ nPos ] )

    // Read the GET
    IF ( VALTYPE( oGet:reader ) == "B" )
       EVAL( oGet:reader, oGet )    // Use custom reader block
    ELSE
       GetReader( oGet )         // Use standard reader
    ENDIF

    // Move to next GET based on exit condition
    nPos := Settle( GetList, nPos )
    PosMsg:=nPos

   ENDDO

   // Restore state variables
   RestoreGetSysVars( aSavGetSysVars )

   // S'87 compatibility
   SETPOS( MAXROW() - 1, 0 )

   RETURN ( slUpdated )

/***
*
*  GetReader()
*
*  Standard modal read of a single GET
*
*/
PROCEDURE GetReader( oGet )
LOCAL nTempo, nTemp, nCursor1, nCursor2, lRestaura := .F.
PRIVATE cGetMsg, nLINAJU1, nLINAJU2, nCOLAJU1, nCOLAJU2
   // Read the GET if the WHEN condition is satisfied

   IF ( GetPreValidate( oGet ) )

    // Activate the GET for reading
    oGet:setFocus()

    WHILE ( oGet:exitState == GE_NOEXIT )

       // Check for initial typeout (no editable positions)
       IF ( oGet:typeOut )
        oGet:exitState := GE_ENTER
       ENDIF

       // Apply keystrokes until exit
       IF ( oGet:type == "N" )
        oGet:pos    := oGet:decPos()-1
        oGet:display()
       ENDIF
       SETPOS(oGet:row,oGet:col)
       WHILE ( oGet:exitState == GE_NOEXIT )
        IF ( oGet:type == "N" ) .AND. (oGet:pos < oGet:decPos )
         oGet:pos     := oGet:decPos()-1
         oGet:display()
        ENDIF
        IF nTempo <> 0
         GetApplyKey( oGet, INKEY(0)) // minkey( 0, @snMrow, @snMCol ) )
        ELSE
         SET CURSOR ON
         oGet:display()
        ENDIF
       ENDDO

       // Disallow exit if the VALID condition is not satisfied
       IF ( !GetPostValidate( oGet ) )
        oGet:exitState := GE_NOEXIT
       ENDIF
    ENDDO

    // De-activate the GET
    oGet:killFocus()

   ENDIF
   IF lRestaura
   ENDIF

   RETURN

/***
*
*  GetApplyKey()
*
*  Apply a single INKEY() keystroke to a GET
*
*  NOTE: GET must have focus.
*
*/
PROCEDURE GetApplyKey( oGet, nKey )

   LOCAL cKey
   LOCAL bKeyBlock
   LOCAL nTemp
   LOCAL lTmp, lDec, lDec0

   // Check for SET KEY first
   IF !( ( bKeyBlock := setkey( nKey ) ) == NIL )
    GetDoSetKey( bKeyBlock, oGet )
    RETURN                   // NOTE
   ENDIF

   DO CASE
// CASE ( nKey == 45 ) .AND. SUBSTR(oGet:buffer,oGet:decPos()-1,1) == "0"
//       oGet:buffer := SUBSTR(oGet:buffer,1,oGet:decPos()-2)+"-"+SUBSTR(oGet:buffer,oGet:decPos()-1)
//       oGet:display()
   CASE ( nKey == K_UP )
    oGet:exitState := GE_UP

   CASE ( nKey == K_SH_TAB )
    oGet:exitState := GE_UP

   CASE ( nKey == K_DOWN )
    oGet:exitState := GE_DOWN

   CASE ( nKey == K_TAB )
    oGet:exitState := GE_DOWN

   CASE ( nKey == K_ENTER )
    oGet:changed := .T.
    oGet:exitState := GE_ENTER
    nKey2 := SPACE(0)

   CASE ( nKey == K_ESC )
    IF ( SET( _SET_ESCAPE ) )
       oGet:undo()
       oGet:exitState := GE_ESCAPE

    ENDIF

   CASE ( nKey == K_PGUP )
    oGet:exitState := GE_WRITE

   CASE ( nKey == K_PGDN )
    oGet:exitState := GE_WRITE

   CASE ( nKey == K_CTRL_HOME )
    oGet:exitState := GE_TOP

#ifdef CTRL_END_SPECIAL

   // Both ^W and ^End go to the last GET
   CASE ( nKey == K_CTRL_END )
    oGet:exitState := GE_BOTTOM

#else

   // Both ^W and ^End terminate the READ (the default)
   CASE ( nKey == K_CTRL_W )
    oGet:exitState := GE_WRITE

#endif

   CASE ( nKey == K_INS )
    SET( _SET_INSERT, !SET( _SET_INSERT ) )
    ShowScoreboard()

   CASE ( nKey == K_UNDO )
    oGet:undo()

   CASE ( nKey == K_HOME )
    oGet:home()

   CASE ( nKey == K_END )
    oGet:end()

   CASE ( nKey == K_RIGHT )
    oGet:right()
    nKey2 := SPACE(0)

   CASE ( nKey == K_LEFT )
    oGet:left()
    nKey2 := SPACE(0)

   CASE ( nKey == K_CTRL_RIGHT )
    oGet:wordRight()
    nKey2 := SPACE(0)

   CASE ( nKey == K_CTRL_LEFT )
    oGet:wordLeft()
    nKey2 := SPACE(0)

   CASE ( nKey == K_BS ) .OR. ((nKey == K_DEL) .AND. (oGet:type =="N"))
    IF ( oGet:type == "N" ) .AND. (oGet:pos < oGet:decPos )
       IF AT(".",oGet:buffer) <> 0 .OR. AT(",",oGet:buffer) <> 0
        oGet:pos    := oGet:decPos()-1
        nTemp := oGet:unTransform()
        nTemp := (nTemp-INT(nTemp)) + INT(nTemp / 10)
       ELSE
        oGet:pos    := oGet:decPos()-1
        oGet:delete()
        nTemp := oGet:unTransform()
       ENDIF
       oGet:buffer := Transform(nTemp,oGet:picture)
       oGet:pos    := oGet:decPos()-1
       oGet:display()
    ELSE
       IF (oGet:type="N").AND.(oGet:pos=oGet:decPos+1).AND.(nKey<>K_DEL)
         oGet:pos := oGet:decPos()-1
         KEYBOARD CHR( K_BS )
       ELSE
         IF ( nKey == K_DEL )
          oGet:delete()
         ELSE
          oGet:backSpace()
         ENDIF
         oGet:display()
      ENDIF
    ENDIF
   CASE ( nKey == K_DEL )
    oGet:delete()

   CASE ( nKey == K_CTRL_T )
    oGet:delWordRight()

   CASE ( nKey == K_CTRL_Y )
    IF oGet:type == "N"
       nTmp := oGet:pos
       oGet:pos    := 01
       oGet:delEnd()
       oGet:pos    := nTmp
       oGet:display()
    ELSE
       oGet:delEnd()
    ENDIF

   CASE ( nKey == K_CTRL_BS )
    oGet:delWordLeft()

   OTHERWISE
    lIns  := .T.

    IF ( nKey >= 32 .AND. nKey <= 255 )

       IF ! EMPTY(nKey2) .AND.  oGet:type == "C"
         lIns := Acentos(oGet, nKey2, @nKey)
         nKey2 := SPACE(0)
       ENDIF

       cKey := CHR( nKey )

       IF ( oGet:type == "N" .AND. ( cKey == "." .OR. cKey == "," ) )
        lTmp := AT("-",oGet:buffer) <> 0
        IF oGet:Clear
         oGet:buffer := Transform(0,oGet:picture)
        ENDIF
        oGet:toDecPos()
        IF lTmp .AND. AT("-",oGet:buffer) == 0
         oGet:buffer := SUBSTR(oGet:buffer,1,oGet:decPos()-2)+"-"+SUBSTR(oGet:buffer,oGet:decPos()-1)
         oGet:buffer := SUBSTR(oGet:buffer,2)
        ENDIF
        oGet:display()
       ELSEIF ( oGet:type == "N" ) .AND. (oGet:pos < oGet:decPos ) .AND. ;
       ((nKey >= ASC('0') .AND. nKey <= ASC('9')) .OR. UPPER(CHR(nKey))="C";
                  .OR.  nKey == ASC('+')  .OR.  nKey == ASC('-'))
        nTemp := oGet:unTransform()
        IF UPPER(cKey) == "C" .OR. oGet:clear
         oGet:clear := .F.
         nTemp = 0
         oGet:buffer := Transform(nTemp,oGet:picture)
         oGet:display()
        ENDIF
        lDec := AT(".",Transform(0,oGet:picture))
        IF(lDec==0,lDec := AT(",",Transform(0,oGet:picture)),lDec)
        lDec0 := IF(lDec<>0,IF(LEN(oGet:buffer) > (lDec+1),.T.,.F.),.T.)
        lDec  := IF(lDec<>0,.T.,.F.)
        IF(oGet:picture==NIL,lDec0:=.T.,)
       
        IF LEN((oGet:buffer)) >= (LEN(ALLTRIM(oGet:buffer))+1)
         IF oGet:type == "N" .AND. cKey == "-"
            nKey2 := ASC("-")
         ELSE
            lTmp  := AT("-",oGet:buffer) <> 0
            nTemp := (nTemp-INT(nTemp)) + INT(nTemp * 10)
            oGet:buffer := Transform(nTemp,oGet:picture)
            IF nTemp = 0 .AND. lTmp
             IF LEN(oGet:buffer) < oGet:decPos() .and. 1 = 2
                oGet:buffer := SUBSTR(oGet:buffer,1,oGet:decPos()-3)+"-"+SUBSTR(oGet:buffer,oGet:decPos()-2)
                oGet:buffer := SUBSTR(oGet:buffer,2)
             ELSE
                oGet:buffer := SUBSTR(oGet:buffer,1,oGet:decPos()-IF(lDec0,2,3))+"-"+SUBSTR(oGet:buffer,oGet:decPos()-IF(lDec0,1,2))
                oGet:buffer := SUBSTR(oGet:buffer,2)
             ENDIF
            ENDIF                                                                //2   1
            oGet:pos   := oGet:decPos() -IF(oGet:picture<>NIL .AND. lDec, IF(lTmp .AND. LEN(oGet:buffer) < oGet:decPos(),2,1),0)
            oGet:overstrike( cKey )                                                    //2   1
            oGet:pos   := oGet:decPos() -IF(oGet:picture<>NIL .AND. lDec, IF(lTmp .AND. LEN(oGet:buffer) < oGet:decPos(),2,1),0)
         ENDIF
         IF VALTYPE(nKey2) == "N" .AND. cKey == "-"
            lTmp  := AT("-",oGet:buffer) == 0
            nTemp := oGet:unTransform()
            nTemp *= (-1)
            oGet:buffer := Transform(nTemp,oGet:picture)
            IF nTemp = 0 .AND. lTmp
             IF LEN(oGet:buffer) < oGet:decPos() .and. 1 = 2
                oGet:buffer := SUBSTR(oGet:buffer,1,oGet:decPos()-3)+"-"+SUBSTR(oGet:buffer,oGet:decPos()-2)
                oGet:buffer := SUBSTR(oGet:buffer,2)
             ELSE
                oGet:buffer := SUBSTR(oGet:buffer,1,oGet:decPos()-IF(lDec0,2,3))+"-"+SUBSTR(oGet:buffer,oGet:decPos()-IF(lDec0,1,2))
                oGet:buffer := SUBSTR(oGet:buffer,2)
             ENDIF
            ENDIF
         ENDIF
         IF VALTYPE(nKey2) == "N"
            nKey2 := SPACE(0)
         ENDIF
         oGet:display()
         IF LEN(SUBSTR(oGet:buffer,1,oGet:decpos-1))==LEN(ALLTRIM(SUBSTR(oGet:buffer,1,oGet:decpos-1))) .AND. (!SET(_SET_CONFIRM))
            oGet:exitstate:=GE_ENTER
         ENDIF
        ELSEIF LEN(SUBSTR(oGet:buffer,1,oGet:decpos-1)) == 1 .AND. (oGet:pos < oGet:decPos )
         oGet:overstrike(cKey)
         oGet:pos := oGet:decPos()
         oGet:display()
         IF LEN(SUBSTR(oGet:buffer,1,oGet:decpos-1))==1 .AND. (!SET(_SET_CONFIRM))
            oGet:exitstate:=GE_ENTER
         ENDIF
        ELSE
         IF ( !SET( _SET_CONFIRM ) )
            oGet:exitState := GE_ENTER
         ELSE
            ?? CHR(7)
         ENDIF

        ENDIF
        IF oGet:type == "N" .AND. cKey == "-"
         nKey2 := nKey
        ENDIF
       ELSE

        IF ( SET( _SET_INSERT ) ) .AND. lIns
         oGet:insert( cKey )
        ELSE
         oGet:overstrike( cKey )
        ENDIF
        IF ( oGet:type == "C")
         IF EMPTY(nKey2) .AND. (nKey=126 .OR. nKey=39 .OR. nKey=96 .OR. nKey=34 .OR. nKey=94 .OR. nKey=46)
            nKey2 := nKey
            oGet:left()
         ELSE
            nKey2 := SPACE(0)
         ENDIF
        ENDIF

        IF ( oGet:typeOut )
         IF ( SET( _SET_BELL ) )
            ?? CHR(7)
         ENDIF

         IF ( !SET( _SET_CONFIRM ) )
            oGet:exitState := GE_ENTER
         ENDIF
        ENDIF

       ENDIF

    ENDIF

   ENDCASE
   oGet:changed := .T.

   RETURN

/***
*
*  GetPreValidate()
*
*  Test entry condition (WHEN clause) for a GET
*
*/
FUNCTION GetPreValidate( oGet )

   LOCAL lSavUpdated
   LOCAL lWhen := .T.

   IF !( oGet:preBlock == NIL )

    lSavUpdated := slUpdated

    lWhen := EVAL( oGet:preBlock, oGet )

    oGet:display()

    ShowScoreBoard()
    slUpdated := lSavUpdated

   ENDIF

   IF ( slKillRead )

    lWhen := .F.
    oGet:exitState := GE_ESCAPE      // Provokes ReadModal() exit

   ELSEIF ( !lWhen )

    oGet:exitState := GE_WHEN      // Indicates failure

   ELSE

    oGet:exitState := GE_NOEXIT      // Prepares for editing

   END

   RETURN ( lWhen )

/***
*
*  GetPostValidate()
*
*  Test exit condition (VALID clause) for a GET
*
*  NOTE: Bad dates are rejected in such a way as to preserve edit buffer
*
*/
FUNCTION GetPostValidate( oGet )

   LOCAL lSavUpdated
   LOCAL lValid := .T.

   IF ( oGet:exitState == GE_ESCAPE )
    RETURN ( .T. )             // NOTE
   ENDIF

   IF ( oGet:badDate() )
    oGet:home()
    DateMsg()
    ShowScoreboard()
    RETURN ( .F. )             // NOTE
   ENDIF

   // If editing occurred, assign the new value to the variable
   IF ( oGet:changed )
    oGet:assign()
    slUpdated := .T.
   ENDIF

   // Reform edit buffer, set cursor to home position, redisplay
   oGet:reset()

   // Check VALID condition if specified
   IF !( oGet:postBlock == NIL )

    lSavUpdated := slUpdated

    // S'87 compatibility
    SETPOS( oGet:row, oGet:col + LEN( oGet:buffer ) )

    lValid := EVAL( oGet:postBlock, oGet )

    // Reset S'87 compatibility cursor position
    SETPOS( oGet:row, oGet:col )

    ShowScoreBoard()
    oGet:updateBuffer()

    slUpdated := lSavUpdated

    IF ( slKillRead )
       oGet:exitState := GE_ESCAPE     // Provokes ReadModal() exit
       lValid := .T.

    ENDIF
   ENDIF

   RETURN ( lValid )

/***
*
*  GetDoSetKey()
*
*  Process SET KEY during editing
*
*/
PROCEDURE GetDoSetKey( keyBlock, oGet )

   LOCAL lSavUpdated

   // If editing has occurred, assign variable
   IF ( oGet:changed )
    oGet:assign()
    slUpdated := .T.
   ENDIF

   lSavUpdated := slUpdated

   EVAL( keyBlock, scReadProcName, snReadProcLine, ReadVar() )

   ShowScoreboard()
   oGet:updateBuffer()

   slUpdated := lSavUpdated

   IF ( slKillRead )
    oGet:exitState := GE_ESCAPE       // provokes ReadModal() exit
   ENDIF

   RETURN

/***
*         READ services
*/

/***
*
*  Settle()
*
*  Returns new position in array of Get objects, based on:
*    - current position
*    - exitState of Get object at current position
*
*  NOTES: return value of 0 indicates termination of READ
*      exitState of old Get is transferred to new Get
*
*/
STATIC FUNCTION Settle( GetList, nPos )

   LOCAL nExitState

   IF ( nPos == 0 )
    nExitState := GE_DOWN
   ELSE
    nExitState := GetList[ nPos ]:exitState
   ENDIF

   IF ( nExitState == GE_ESCAPE .or. nExitState == GE_WRITE )
    RETURN ( 0 )            // NOTE
   ENDIF

   IF !( nExitState == GE_WHEN )
    // Reset state info
    snLastPos := nPos
    slBumpTop := .F.
    slBumpBot := .F.
   ELSE
    // Re-use last exitState, do not disturb state info
    nExitState := snLastExitState
   ENDIF

   //
   // Move
   //
   DO CASE
   CASE ( nExitState == GE_UP )
    nPos--

   CASE ( nExitState == GE_DOWN )
    nPos++

   CASE ( nExitState == GE_TOP )
    nPos     := 1
    slBumpTop  := .T.
    nExitState := GE_DOWN

   CASE ( nExitState == GE_BOTTOM )
    nPos     := LEN( GetList )
    slBumpBot  := .T.
    nExitState := GE_UP

   CASE ( nExitState == GE_ENTER )
    nPos++

   ENDCASE

   //
   // Bounce
   //
   IF ( nPos == 0 )                 // Bumped top
    IF ( !ReadExit() .and. !slBumpBot )
       slBumpTop   := .T.
       nPos      := snLastPos
       nExitState := GE_DOWN
    ENDIF

   ELSEIF ( nPos == len( GetList ) + 1 )  // Bumped bottom
    IF ( !ReadExit() .and. !( nExitState == GE_ENTER ) .and. !slBumpTop )
       slBumpBot   := .T.
       nPos      := snLastPos
       nExitState := GE_UP
    ELSE
       nPos := 0
    ENDIF
   ENDIF

   // Record exit state
   snLastExitState := nExitState

   IF !( nPos == 0 )
    GetList[ nPos ]:exitState := nExitState
   ENDIF

   RETURN ( nPos )

/***
*
*  PostActiveGet()
*
*  Post active GET for ReadVar(), GetActive()
*
*/
STATIC PROCEDURE PostActiveGet( oGet )

   GetActive( oGet )
   ReadVar( GetReadVar( oGet ) )

   ShowScoreBoard()

   RETURN

/***
*
*  ClearGetSysVars()
*
*  Save and clear READ state variables. Return array of saved values
*
*  NOTE: 'Updated' status is cleared but not saved (S'87 compatibility)
*/
STATIC FUNCTION ClearGetSysVars()

   LOCAL aSavSysVars[ GSV_COUNT ]

   // Save current sys vars
   aSavSysVars[ GSV_KILLREAD ]   := slKillRead
   aSavSysVars[ GSV_BUMPTOP ]      := slBumpTop
   aSavSysVars[ GSV_BUMPBOT ]      := slBumpBot
   aSavSysVars[ GSV_LASTEXIT ]   := snLastExitState
   aSavSysVars[ GSV_LASTPOS ]      := snLastPos
   aSavSysVars[ GSV_ACTIVEGET ]   := GetActive( NIL )
   aSavSysVars[ GSV_READVAR ]      := ReadVar( "" )
   aSavSysVars[ GSV_READPROCNAME ] := scReadProcName
   aSavSysVars[ GSV_READPROCLINE ] := snReadProcLine

   // Re-init old ones
   slKillRead       := .F.
   slBumpTop       := .F.
   slBumpBot       := .F.
   snLastExitState := 0
   snLastPos       := 0
   scReadProcName  := ""
   snReadProcLine  := 0
   slUpdated       := .F.

   RETURN ( aSavSysVars )

/***
*
*  RestoreGetSysVars()
*
*  Restore READ state variables from array of saved values
*
*  NOTE: 'Updated' status is not restored (S'87 compatibility)
*
*/
STATIC PROCEDURE RestoreGetSysVars( aSavSysVars )

   slKillRead       := aSavSysVars[ GSV_KILLREAD ]
   slBumpTop       := aSavSysVars[ GSV_BUMPTOP ]
   slBumpBot       := aSavSysVars[ GSV_BUMPBOT ]
   snLastExitState := aSavSysVars[ GSV_LASTEXIT ]
   snLastPos       := aSavSysVars[ GSV_LASTPOS ]

   GetActive( aSavSysVars[ GSV_ACTIVEGET ] )

   ReadVar( aSavSysVars[ GSV_READVAR ] )

   scReadProcName  := aSavSysVars[ GSV_READPROCNAME ]
   snReadProcLine  := aSavSysVars[ GSV_READPROCLINE ]

   RETURN

/***
*
*  GetReadVar()
*
*  Set READVAR() value from a GET
*
*/
STATIC FUNCTION GetReadVar( oGet )

   LOCAL cName := UPPER( oGet:name )
   LOCAL i

   // The following code includes subscripts in the name returned by
   // this FUNCTIONtion, if the get variable is an array element
   //
   // Subscripts are retrieved from the oGet:subscript instance variable
   //
   // NOTE: Incompatible with Summer 87
   //
   IF !( oGet:subscript == NIL )
    FOR i := 1 TO LEN( oGet:subscript )
       cName += "[" + LTRIM( STR( oGet:subscript[i] ) ) + "]"
    NEXT
   END

   RETURN ( cName )

/***
*         System Services
*/

/***
*
*  __SetFormat()
*
*  SET FORMAT service
*
*/
PROCEDURE __SetFormat( b )
   sbFormat := IF( VALTYPE( b ) == "B", b, NIL )
   RETURN

/***
*
*  __KillRead()
*
*  CLEAR GETS service
*
*/
PROCEDURE __KillRead()
   slKillRead := .T.
   RETURN

/***
*
*  GetActive()
*
*  Retrieves currently active GET object
*/
FUNCTION GetActive( g )

   LOCAL oldActive := soActiveGet

   IF ( PCOUNT() > 0 )
    soActiveGet := g
   ENDIF

   RETURN ( oldActive )

/***
*
*  Updated()
*
*/
FUNCTION Updated()
   RETURN slUpdated

/***
*
*  ReadExit()
*
*/
FUNCTION ReadExit( lNew )
   RETURN ( SET( _SET_EXIT, lNew ) )

/***
*
*  ReadInsert()
*
*/
FUNCTION ReadInsert( lNew )
   RETURN ( SET( _SET_INSERT, lNew ) )

/***
*         Wacky Compatibility Services
*/

// Display coordinates for SCOREBOARD
#define SCORE_ROW      0
#define SCORE_COL      60

/***
*
*  ShowScoreboard()
*
*/
STATIC PROCEDURE ShowScoreboard()

   LOCAL nRow
   LOCAL nCol

   IF ( SET( _SET_SCOREBOARD ) )
    nRow := ROW()
    nCol := COL()

    SETPOS( SCORE_ROW, SCORE_COL )
    DISPOUT( IF( SET( _SET_INSERT ), NationMsg(_GET_INSERT_ON),;
                     NationMsg(_GET_INSERT_OFF)) )
    SETPOS( nRow, nCol )
   ENDIF

   RETURN

/***
*
*  DateMsg()
*
*/
STATIC PROCEDURE DateMsg()

   LOCAL nRow
   LOCAL nCol

   IF ( SET( _SET_SCOREBOARD ) )

    nRow := ROW()
    nCol := COL()

    SETPOS( SCORE_ROW, SCORE_COL )
    DISPOUT( NationMsg(_GET_INVD_DATE) )
    SETPOS( nRow, nCol )

    WHILE ( NEXTKEY() == 0 )
    END

    SETPOS( SCORE_ROW, SCORE_COL )
    DISPOUT( SPACE( LEN( NationMsg(_GET_INVD_DATE) ) ) )
    SETPOS( nRow, nCol )

   ENDIF

   RETURN

/***
*
*  RangeCheck()
*
*  NOTE: Unused second param for 5.00 compatibility.
*
*/
FUNCTION RangeCheck( oGet, junk, lo, hi )

   LOCAL cMsg, nRow, nCol
   LOCAL xValue

   IF ( !oGet:changed )
    RETURN ( .T. )      // NOTE
   ENDIF

   xValue := oGet:varGet()

   IF ( xValue >= lo .and. xValue <= hi )
    RETURN ( .T. )      // NOTE
   ENDIF

   IF ( SET(_SET_SCOREBOARD) )

    cMsg := NationMsg(_GET_RANGE_FROM) + LTRIM( TRANSFORM( lo, "" ) ) + ;
          NationMsg(_GET_RANGE_TO) + LTRIM( TRANSFORM( hi, "" ) )

    IF ( LEN( cMsg ) > MAXCOL() )
       cMsg := SUBSTR( cMsg, 1, MAXCOL() )
    ENDIF

    nRow := ROW()
    nCol := COL()

    SETPOS( SCORE_ROW, MIN( 60, MAXCOL() - LEN( cMsg ) ) )
    DISPOUT( cMsg )
    SETPOS( nRow, nCol )

    WHILE ( NEXTKEY() == 0 )
    END

    SETPOS( SCORE_ROW, MIN( 60, MAXCOL() - LEN( cMsg ) ) )
    DISPOUT( SPACE( LEN( cMsg ) ) )
    SETPOS( nRow, nCol )

   ENDIF

   RETURN ( .F. )

/***
*
*  ReadKill()
*
*/
FUNCTION ReadKill( lKill )

   LOCAL lSavKill := slKillRead

   IF ( PCOUNT() > 0 )
    slKillRead := lKill
   ENDIF

   RETURN ( lSavKill )

/***
*
*  ReadUpdated()
*
*/
FUNCTION ReadUpdated( lUpdated )

   LOCAL lSavUpdated := slUpdated

   IF ( PCOUNT() > 0 )
    slUpdated := lUpdated
   ENDIF

   RETURN ( lSavUpdated )

/***
*
*  ReadFormat()
*
*/
FUNCTION ReadFormat( b )

   LOCAL bSavFormat := sbFormat

   IF ( PCOUNT() > 0 )
    sbFormat := b
   ENDIF

   RETURN ( bSavFormat )

**********************************************************************
FUNCTION Mensagem1(nLinh,cTexto,cCor)
LOCAL nCol,nLargJan
    nLargJan := LEN(cTexto)
IF nLargJan < 10
    nLargJan := 10
ENDIF
nCol := (80 -nLargJan)/2
  @ nLinh,nCol CLEAR TO nLinh,nCol + nLargJan
  @ nLinh,nCol SAY cTexto COLOR cCor
RETURN NIL
**********************************************************************

// "Ž„ …†ƒ€‡‚ˆ‰Š¡‹Œ“¢™”•£š–¦§"

FUNCTION Acentos(oGet,nKey2,nKey)
LOCAL lIns := .F.
nKey2 := CHR(nKey2)
nKey3 := nKey
nKey  := CHR(nKey )
IF nKey2 == "~"
   IF   nKey=="A" ; nKey:="Ž"
   ELSEIF nKey=="O" ; nKey:="™"
   ELSEIF nKey=="a" ; nKey:="„"
   ELSEIF nKey=="o" ; nKey:="”"
   ELSE  ; lIns := .T. ; ENDIF
ELSEIF nKey2 == "'"
   IF   nKey=="A" ; nKey:=""
   ELSEIF nKey=="E" ; nKey:=""
   ELSEIF nKey=="a" ; nKey:=" "
   ELSEIF nKey=="e" ; nKey:="‚"
   ELSEIF nKey=="i" ; nKey:="¡"
   ELSEIF nKey=="o" ; nKey:="¢"
   ELSEIF nKey=="u" ; nKey:="£"
   ELSEIF nKey=="C" ; nKey:="€"
   ELSEIF nKey=="c" ; nKey:="‡"
   ELSE  ; lIns := .T. ; ENDIF
ELSEIF nKey2 == "`"
   IF   nKey=="a" ; nKey:="…"
   ELSEIF nKey=="e" ; nKey:="Š"
   ELSEIF nKey=="i" ; nKey:=""
   ELSEIF nKey=="o" ; nKey:="•"
   ELSE  ; lIns := .T. ; ENDIF
ELSEIF nKey2 == "^"
   IF   nKey=="a" ; nKey:="ƒ"
   ELSEIF nKey=="e" ; nKey:="ˆ"
   ELSEIF nKey=="i" ; nKey:="Œ"
   ELSEIF nKey=="o" ; nKey:="“"
   ELSEIF nKey=="u" ; nKey:="–"
   ELSE  ; lIns := .T. ; ENDIF
ELSEIF nKey2 == "."
   IF   nKey=="a" ; nKey:="¦"
   ELSEIF nKey=="o" ; nKey:="§"
   ELSE  ; lIns := .T. ; ENDIF
ENDIF
nKey2 := ASC(nKey2)
nKey  := ASC(nKey )
IF nKey3 == nKey
   oGet:right()
ENDIF
RETURN (lIns)

***************************************************************************

FUNCTION _INKEY(nTempo,lTrava)
LOCAL nKey := 0 , nTime := SECONDS()
lTrava:=IF(lTrava==NIL,.F.,.T.)
IF lTrava .AND. nTempo <> NIL .AND. nTempo <> 0
   WHILE IF (nTempo > 0, (SECONDS() - nTime) < nTempo, .T.)
   ENDDO
   nKey := LASTKEY()
ELSE
   nKey :=  INKEY(0) // Minkey(nTempo, @nMRow, @nMCol, .T.)
ENDIF
RETURN (nKey)

***************************************************************************

FUNCTION AJUDADECAMPOATIVA( oGet )
LOCAL nROW := ROW(), nCOL := COL(), nCURSOR := SETCURSOR(), cCOR := SETCOLOR()
LOCAL GetMensg := GetMsg[PosMsg], nCALCULO, nPOSOGET
LOCAL nPOS1 := AT("|",GetMensg), nPOS2, cVAR[3], nTAMAJU
IF nPOS1 # 0
   cVAR[1] := SUBSTR(GetMensg,1,nPOS1-1)
   GetMensg := SUBSTR(GetMensg,nPOS1+1,LEN(GetMensg))
ELSE
   cVAR[1] := GetMensg
   GetMensg := SPACE(0)
ENDIF
nPOS2 := AT("|",GetMensg)
IF nPOS2 # 0
   cVAR[2] := SUBSTR(GetMensg,1,nPOS2-1)
   GetMensg := SUBSTR(GetMensg,nPOS2+1,LEN(GetMensg))
   cVAR[3] := GetMensg
ELSEIF nPOS2 == 0 .AND. !EMPTY(GetMensg)
   cVAR[2] := GetMensg
ENDIF
IF cVAR[3] # NIL
   nCALCULO := 4
ELSEIF cVAR[3] == NIL .AND. cVAR[2] # NIL
   nCALCULO := 3
ELSE
   nCALCULO := 2
ENDIF
nTAMAJU := LenLargura( cVAR )
nPOSOGET := oGet:col + 4
IF nPOSOGET+4+nTAMAJU > 79
   DO WHIL .T.
    nPOSOGET--
    IF nPOSOGET+4+nTAMAJU <= 79
       EXIT
    ENDIF
   ENDDO
ENDIF
nCOLAJU1 := nPOSOGET
nCOLAJU2 := nPOSOGET+nTAMAJU
IF oGet:row+1+nCALCULO > 24
   nLINAJU1 := oGet:row-1-nCALCULO
   nLINAJU2 := oGet:row-1
ELSE
   nLINAJU1 := oGet:row+1
   nLINAJU2 := oGet:row+1+nCALCULO
ENDIF
cGetMsg := SAVESCREEN(nLINAJU1,nCOLAJU1-2,nLINAJU2+1,nCOLAJU2+3)
@ nLINAJU1,nCOLAJU1 TO nLINAJU2,nCOLAJU2+3
@ nLINAJU1+1,nCOLAJU1+1 SAY " "+PAD( cVAR[1], nTAMAJU)+" "
IF cVAR[2] # NIL
   @ nLINAJU1+2,nCOLAJU1+1 SAY " "+PAD( cVAR[2], nTAMAJU)+" "
ENDIF
IF cVAR[3] # NIL
   @ nLINAJU1+3,nCOLAJU1+1 SAY " "+PAD( cVAR[3], nTAMAJU)+" "
ENDIF
SETPOS(nROW,nCOL)
SETCOLOR(cCOR)
SETCURSOR(nCURSOR)
RETURN NIL
***************************************************************************
STATIC FUNCTION LenLargura( aMenu2 )
LOCAL nLargura, i
nLargura := aMenu2[1]
FOR i = 1 TO LEN(aMenu2)
   IF aMenu2[i] # NIL
    IF LEN(nLargura) < LEN(aMenu2[i])
       nLargura := aMenu2[i]
    ENDIF
   ENDIF
NEXT
RETURN LEN(nLargura)
***************************************************************************
FUNCTION _ROUND(nValor,nDecimals)
Hb_Default( @nDecimals,2)
RETURN (ROUND(val(str(nValor)),nDecimals))

***************************************************************************

FUNCTION GetPassword(oGet)
LOCAL nKey,nChar,cKey
LOCAL nTempo, nTemp, nCursor1, nCursor2, lRestaura := .F.
PRIVATE cGetMsg, nLINAJU1, nLINAJU2, nCOLAJU1, nCOLAJU2
IF (GetPreValidate(oGet))

    // Activate the GET for reading
    oGet:setFocus()
    IF GetMsg[PosMsg] <> NIL
    ENDIF

   oGet:SetFocus()
   oGet:cargo := ""
   Do While(oGet:exitState == GE_NOEXIT)
    IF (oGet:typeOut)
       oGet:exitState := GE_ENTER
    ENDIF
    Do While (oGet:exitState == GE_NOEXIT)
       nKey := INKEY(0)
       IF nKey >= 32 .AND. nKey <= 255
        oGet:cargo += Chr(nKey)
        GetApplyKey(oGet,Asc("þ"))
       ELSEIF nKey == K_BS
        oGet:cargo := Substr(oGet:cargo,1,Len(oGet:cargo)-1)
        GetApplyKey(oGet,nKey)
       ELSEIF nKey == K_ENTER
        GetApplyKey(oGet,nKey)
       ELSEIF nKey == K_ESC
        GetApplyKey(oGet,nKey)
       ENDIF
    ENDDO
    IF (!GetPostValidate(oGet))
       oGet:exitState := GE_NOEXIT
    ENDIF
   ENDDO
   oGet:KillFocus()
   IF lRestaura
   ENDIF
ENDIF
IF oGet:exitState != GE_ESCAPE
   oGet:varPut(oGet:cargo)
ENDIF
RETURN

********************************************************************************
* Atualiza um get especifico
FUNCTION Atualiza_Gets( cGetName, uValue )
Local oGet, nPos
If ( nPos:= Ascan( GetList, { |e| Upper(e:name)==Upper(cGetName) } ) ) > 0
   oGet := GetList[nPos]
   If PCount()>1
      oGet:Varput( uValue )
   EndIf
   oGet:Display()
EndIf
Return( nPos>0 )

********************************************************************************
* Atulizar na tela todos os gets da getlist
Function AtGets()
AEval( GetList, {|oGet| oGet:UpdateBuffers() })
AEval( GetList, {|oGet| oGet:Display() })
Return Nil



Só lembrando:
Compilação -w3 -es2 não é novidade, existia no Clipper.
No Harbour aumentaram a checagem ainda mais.

Usando -e3 -es2

MensagemEnviado: 28 Mai 2019 21:25
por JoséQuintas
Primeira compilação

getsys.prg:83: warning W0002 Ambiguous reference, assuming memvar 'NKEY2'
getsys.prg:85: warning W0002 Ambiguous reference, assuming memvar 'POSMSG'
getsys.prg:85: warning W0002 Ambiguous reference, assuming memvar 'GETMSG'
getsys.prg:86: warning W0001 Ambiguous reference 'NI'
getsys.prg:87: warning W0001 Ambiguous reference 'NI'
getsys.prg:88: warning W0001 Ambiguous reference 'GETMSG'
getsys.prg:88: warning W0001 Ambiguous reference 'NI'
getsys.prg:89: warning W0001 Ambiguous reference 'NI'
getsys.prg:89: warning W0001 Ambiguous reference 'NI'
getsys.prg:91: warning W0001 Ambiguous reference 'GETMSG'
getsys.prg:93: warning W0001 Ambiguous reference 'NI'
getsys.prg:93: warning W0001 Ambiguous reference 'NI'
getsys.prg:117: warning W0001 Ambiguous reference 'POSMSG'
getsys.prg:134: warning W0001 Ambiguous reference 'POSMSG'
getsys.prg:218: warning W0003 Variable 'NTEMP' declared but not used in function '157:GETREADER'
getsys.prg:218: warning W0003 Variable 'NCURSOR1' declared but not used in function '157:GETREADER'
getsys.prg:218: warning W0003 Variable 'NCURSOR2' declared but not used in function '157:GETREADER'
getsys.prg:218: warning W0033 Variable 'NTEMPO' is never assigned in function '157:GETREADER'
getsys.prg:250: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:299: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:303: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:307: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:311: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:348: warning W0001 Ambiguous reference 'NTMP'
getsys.prg:351: warning W0001 Ambiguous reference 'NTMP'
getsys.prg:362: warning W0001 Ambiguous reference 'LINS'
getsys.prg:366: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:367: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:367: warning W0001 Ambiguous reference 'LINS'
getsys.prg:368: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:402: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:420: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:435: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:436: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:458: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:462: warning W0001 Ambiguous reference 'LINS'
getsys.prg:468: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:469: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:472: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:1055: warning W0003 Variable 'JUNK' declared but not used in function '1006:RANGECHECK'
getsys.prg:1118: warning W0001 Ambiguous reference 'NKEY3'
getsys.prg:1157: warning W0001 Ambiguous reference 'NKEY3'
getsys.prg:1179: warning W0032 Variable 'NKEY' is assigned but not used in function '1165:_INKEY'
getsys.prg:1181: warning W0002 Ambiguous reference, assuming memvar 'GETMSG'
getsys.prg:1181: warning W0001 Ambiguous reference 'POSMSG'
getsys.prg:1215: warning W0001 Ambiguous reference 'NCOLAJU1'
getsys.prg:1216: warning W0001 Ambiguous reference 'NCOLAJU2'
getsys.prg:1218: warning W0001 Ambiguous reference 'NLINAJU1'
getsys.prg:1219: warning W0001 Ambiguous reference 'NLINAJU2'
getsys.prg:1221: warning W0001 Ambiguous reference 'NLINAJU1'
getsys.prg:1222: warning W0001 Ambiguous reference 'NLINAJU2'
getsys.prg:1224: warning W0001 Ambiguous reference 'NLINAJU1'
getsys.prg:1224: warning W0001 Ambiguous reference 'NCOLAJU1'
getsys.prg:1224: warning W0001 Ambiguous reference 'NLINAJU2'
getsys.prg:1224: warning W0001 Ambiguous reference 'NCOLAJU2'
getsys.prg:1224: warning W0001 Ambiguous reference 'CGETMSG'
getsys.prg:1225: warning W0001 Ambiguous reference 'NLINAJU1'
getsys.prg:1225: warning W0001 Ambiguous reference 'NCOLAJU1'
getsys.prg:1225: warning W0001 Ambiguous reference 'NLINAJU2'
getsys.prg:1225: warning W0001 Ambiguous reference 'NCOLAJU2'
getsys.prg:1226: warning W0001 Ambiguous reference 'NLINAJU1'
getsys.prg:1226: warning W0001 Ambiguous reference 'NCOLAJU1'
getsys.prg:1228: warning W0001 Ambiguous reference 'NLINAJU1'
getsys.prg:1228: warning W0001 Ambiguous reference 'NCOLAJU1'
getsys.prg:1231: warning W0001 Ambiguous reference 'NLINAJU1'
getsys.prg:1231: warning W0001 Ambiguous reference 'NCOLAJU1'
getsys.prg:1264: warning W0002 Ambiguous reference, assuming memvar 'GETMSG'
getsys.prg:1264: warning W0001 Ambiguous reference 'POSMSG'
getsys.prg:1298: warning W0005 RETURN statement with no return value in function
getsys.prg:1305: warning W0003 Variable 'NCHAR' declared but not used in function '1257:GETPASSWORD'
getsys.prg:1305: warning W0003 Variable 'CKEY' declared but not used in function '1257:GETPASSWORD'
getsys.prg:1305: warning W0003 Variable 'NTEMPO' declared but not used in function '1258:GETPASSWORD'
getsys.prg:1305: warning W0003 Variable 'NTEMP' declared but not used in function '1258:GETPASSWORD'
getsys.prg:1305: warning W0003 Variable 'NCURSOR1' declared but not used in function '1258:GETPASSWORD'
getsys.prg:1305: warning W0003 Variable 'NCURSOR2' declared but not used in function '1258:GETPASSWORD'
getsys.prg:1307: warning W0001 Ambiguous reference 'GETLIST'
getsys.prg:1308: warning W0002 Ambiguous reference, assuming memvar 'GETLIST'
getsys.prg:1319: warning W0001 Ambiguous reference 'GETLIST'
getsys.prg:1320: warning W0001 Ambiguous reference 'GETLIST'

Usando -e3 -es2

MensagemEnviado: 28 Mai 2019 21:32
por JoséQuintas
Bom... o normal seria seguir a sequência, mas tem umas encrencas aí que já vi antes, então vou fazer fora dessa ordem.

nI costuma ser um contador em FOR/NEXT,
nlinaju1, nlinaju2, ncolaju1, ncolaju2, pelo nome devem ser linhas/colunas pra calcular ajuste,

E tem estas:
getsys.prg:218: warning W0003 Variable 'NTEMP' declared but not used in function '157:GETREADER'
getsys.prg:218: warning W0003 Variable 'NCURSOR1' declared but not used in function '157:GETREADER'
getsys.prg:218: warning W0003 Variable 'NCURSOR2' declared but not used in function '157:GETREADER'

declarada e não usada.... então é apagar do fonte, definiu a variável e não usou pra nada, não faz falta.
E isso é porque declarou local, se é local, só vale praquela função... se não usou na função não faz falta.

Usando -e3 -es2

MensagemEnviado: 28 Mai 2019 21:45
por JoséQuintas
Pra ficar mais legal ainda....
Usar o GIT.

git1.png


git2.png


git3.png
git3.png (11.53 KiB) Visualizado 1691 vezes


git4.png


Chamar o git, escolher pasta, criar controle, depois selecionar os arquivos existentes, e salvar o commit.
Isso vai criar uma pasta .GIT dentro dessa temp\bug.
Essa pasta vai ser a única diferença entre usar o git ou não: a pasta temp\bug\.git

Agora é alterar no fonte o que já mencionei.

Usando -e3 -es2

MensagemEnviado: 28 Mai 2019 21:51
por JoséQuintas
Usando o git pra mostrar o que foi alterado.
Tinha mais variáveis sem uso.
O git mostra em -vermelho o que foi removido/alterado, e em +verde o que foi acrescentado/resultado

Salvar isso como primeiro "commit". é colocar descrição e clicar no botão commit.

git6.png

Usando -e3 -es2

MensagemEnviado: 28 Mai 2019 21:58
por JoséQuintas
esqueci da ntmp, mas tudo bem, o Harbour não esqueceu.... rs

[quote]
getsys.prg:83: warning W0002 Ambiguous reference, assuming memvar 'NKEY2'
getsys.prg:85: warning W0002 Ambiguous reference, assuming memvar 'POSMSG'
getsys.prg:85: warning W0002 Ambiguous reference, assuming memvar 'GETMSG'
getsys.prg:88: warning W0001 Ambiguous reference 'GETMSG'
getsys.prg:91: warning W0001 Ambiguous reference 'GETMSG'
getsys.prg:117: warning W0001 Ambiguous reference 'POSMSG'
getsys.prg:134: warning W0001 Ambiguous reference 'POSMSG'
getsys.prg:218: warning W0033 Variable 'NTEMPO' is never assigned in function '157:GETREADER'
getsys.prg:250: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:299: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:303: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:307: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:311: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:348: warning W0001 Ambiguous reference 'NTMP'
getsys.prg:351: warning W0001 Ambiguous reference 'NTMP'
getsys.prg:362: warning W0001 Ambiguous reference 'LINS'
getsys.prg:366: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:367: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:367: warning W0001 Ambiguous reference 'LINS'
getsys.prg:368: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:402: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:420: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:435: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:436: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:458: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:462: warning W0001 Ambiguous reference 'LINS'
getsys.prg:468: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:469: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:472: warning W0001 Ambiguous reference 'NKEY2'
getsys.prg:1055: warning W0003 Variable 'JUNK' declared but not used in function '1006:RANGECHECK'
getsys.prg:1118: warning W0001 Ambiguous reference 'NKEY3'
getsys.prg:1157: warning W0001 Ambiguous reference 'NKEY3'
getsys.prg:1179: warning W0032 Variable 'NKEY' is assigned but not used in function '1165:_INKEY'
getsys.prg:1181: warning W0002 Ambiguous reference, assuming memvar 'GETMSG'
getsys.prg:1181: warning W0001 Ambiguous reference 'POSMSG'
getsys.prg:1225: warning W0001 Ambiguous reference 'CGETMSG'
getsys.prg:1265: warning W0002 Ambiguous reference, assuming memvar 'GETMSG'
getsys.prg:1265: warning W0001 Ambiguous reference 'POSMSG'
getsys.prg:1299: warning W0005 RETURN statement with no return value in function
getsys.prg:1308: warning W0001 Ambiguous reference 'GETLIST'
getsys.prg:1309: warning W0002 Ambiguous reference, assuming memvar 'GETLIST'
getsys.prg:1320: warning W0001 Ambiguous reference 'GETLIST'
getsys.prg:1321: warning W0001 Ambiguous reference 'GETLIST'
/quote]

RETURN statement with no return value in function
isso é porque função retorna alguma coisa, nem que seja RETURN NIL, é só colocar no NIL lá.

As 4 últimas são um perigo GetList, mas são duas funções que NÃO são usadas.
Normalmente declaramos LOCAL GetList := {}, então essas rotinas nem funcionariam, porque não enxergariam a GetList.
Agora... se o resto do aplicativo usa GetList como PRIVATE... aí a coisa complica.
Mas provavelmente é coisa que foi criada e não é mais usada, apagar daí mesmo.
Já de onde veio essa getsys, talvez seja interessante pesquisar nos fontes, pra ver se não usa em lugar nenhum, antes de apagar.

Usando -e3 -es2

MensagemEnviado: 28 Mai 2019 22:01
por JoséQuintas
Variable 'NTEMPO' is never assigned in function '157:GETREADER'


esta já mencionei no outro post.

LOCAL nTempo
...
IF nTempo <> 0


Não serve pra nada porque não tem conteúdo, não tem alteração do conteúdo, e só usa nessa linha.
É remover a variável e o IF/ENDIF, mas SEM remover o conteúdo, porque esse IF SEMPRE é verdadeiro.
O Harbour não dá erro nessa linha durante a execução, por isso acabou ficando aí sem perceber.

Usando -e3 -es2

MensagemEnviado: 28 Mai 2019 22:08
por JoséQuintas
valornaousado.png


Essa não é grave.
Apenas está reclamando que nKey := 0, atribuir zero não serve pra nada, porque sempre vai atribuir outra coisa no lugar.
Deixando LOCAL nKey dá no mesmo, está apenas inútil colocar := 0

a mensagem de erro é: variável nKey é atribuído valor, mas o valor não é usado na função.

Por isso eu chamo de tolerância zero, não aceita deixar nada inútil no fonte, e não deixa prosseguir enquanto não for corrigido.

Usando -e3 -es2

MensagemEnviado: 28 Mai 2019 22:13
por JoséQuintas
E sempre dá pra conferir no git o que foi alterado, e salvar a posição final - se quiser.

git7.png


O GIT NÃO fica rodando, NÃO fica vigiando o que é feito.
QUANDO você carrega o git, ele analisa, e mostra o que está diferente entre a situação salva e a situação atual.
Então não causa nenhum problema na máquina, vai ser executado somente quando você executar.
E vai salvar somente o que você pedir pra salvar.

Usando -e3 -es2

MensagemEnviado: 28 Mai 2019 22:16
por JoséQuintas
Vamos recapitular o que foi feito?
É só no git escolher repositor, view all branch history (ver todo histórico)

revisao.png


Como salvei cada mudança separada, dá pra ver aí cada conjunto de mudanças.
Tudo isso fica dentro da pasta .GIT, que o Windows esconde por causa de começar com ".", e se quiser deixar de usar o git, é só apagar essa pasta temp\bug\.git.

NÃO confundir GIT com GITHUB.
GIT é o programa que faz todo esse controle.
GITHUB é o site, que agora é da Microsoft, que permite salvar tudo isso nas nuvens

Usando -e3 -es2

MensagemEnviado: 28 Mai 2019 22:28
por JoséQuintas
Agora vém a parte mais complicada

PUBLIC nKey2 := SPACE(0)
PRIVATE GetMsg := {},PosMsg:=nPos


Porque complicada? porque é PUBLIC e PRIVATE?
Não exatamente, porque agora só analisando o uso disso pra ver o que fazer.

nKey2 como PUBLIC... é um nome muito comum, quase certo de usar em outras partes do fonte.
GetMsg e PosMsg como PRIVATE... pelo menos PRIVATE vale daí pra baixo, mesmo se a variável já existir, ao contrário do PUBLIC.
A declaração PRIVATE também evita problemas, mas não é tão bom quanto LOCAL.
PRIVATE isola o que existia antes, mas não isola o que vém depois, essa é a diferença.
Tudo que for chamado, ainda vai enxergar essa variável.

Usando -e3 -es2

MensagemEnviado: 28 Mai 2019 22:39
por JoséQuintas
Ainda no assunto anterior:

o PRIVATE:
o módulo que chamou a getsys pode ter variável com mesmo nome que não tem problema.
Mas.....
VALID, WHEN etc. vai chamar rotinas que podem ter variáveis com mesmo nome.
Esse é o perigo.
Dá problema? Tudo depende das outras variáveis, se foram declaradas ou não.

GETSYS vai ser extremamente usada, em tudo que é rotina, podem existir GETS pendentes durante tudo que é rotina.
Então... a chance de usar nome de variável que já existe.... é grande.

Convém compilar usando -w3 -es2 rotinas assim, pra evitar problemas que não se sabe de onde vém, e geralmente tem a ver com variáveis repetidas, que só mesmo usando o Harbour pra conferir tudo.

Agora sim, é olhar pra que servem as variáveis PUBLIC/PRIVATE, se por acaso não daria pra substituir por LOCAL.
Ou STATIC, que fica visível só nesse fonte !!! Igual outras variáveis originais da GETSYS.

Usando -e3 -es2

MensagemEnviado: 28 Mai 2019 22:58
por JoséQuintas
Uia.... pra não ter que analisar muito.... STATIC

getsys.png


agora só sobrou isto

getsys.prg:347: warning W0001 Ambiguous reference 'NTMP'
getsys.prg:350: warning W0001 Ambiguous reference 'NTMP'
getsys.prg:361: warning W0001 Ambiguous reference 'LINS'
getsys.prg:366: warning W0001 Ambiguous reference 'LINS'
getsys.prg:461: warning W0001 Ambiguous reference 'LINS'
getsys.prg:1054: warning W0003 Variable 'JUNK' declared but not used in function '1005:RANGECHECK'
getsys.prg:1178: warning W0032 Variable 'NKEY' is assigned but not used in function '1164:_INKEY'
getsys.prg:1224: warning W0001 Ambiguous reference 'CGETMSG'

Usando -e3 -es2

MensagemEnviado: 29 Mai 2019 09:06
por JoséQuintas
Continuando....
Os erros restantes são variável não declarada, e variável que não é usada.
No anterior já chama a atenção a variável cGetMsg porque aparece uma única vez, sinal de que deve ser inútil. Se fosse útil apareceria mais de uma vez - criação e uso.
Então, primeiro os básicos: lIns pensei que era algo relacionado com linha, mas é relacionado a Insert.
Pode ser interessante alterar esse nome de variável, assim da próxima vez ficaria claro que é Insert.

getsys.png


Deixei de propósito pro final.

getsys.prg:1054: warning W0003 Variable 'JUNK' declared but not used in function '1005:RANGECHECK'

variável não usada. só que faz parte dos parâmetros recebidos. Não dá pra simplesmente eliminar.

getsys.prg:1178: warning W0032 Variable 'NKEY' is assigned but not used in function '1164:_INKEY'

nKey com valor atribuído, mas o valor não usado. Já alteramos um assim. Era var := 0

getsys.prg:1224: warning W0001 Ambiguous reference 'CGETMSG'

Variável não declarada, mas aparece uma só vez. Deveria aparecer duas: criação e uso. Uma vez só... provavelmente é lixo, ou nome errado - lembro de acertar uma variável chamada GetMsg

Tem essa parte interessante:
A compilação mostra possíveis erros.
Não se trata apenas de eliminar a mensagem de erro, mas de confirmar o porquê do erro.
Este último caso pode ser nome errado.

Usando -e3 -es2

MensagemEnviado: 29 Mai 2019 12:53
por JoséQuintas
GetMsg é array, cGetMsg não.
Dois lugares: cria, coloca conteúdo... e só... não usa pra nada.

getsys.png


Convém destacar:
O -w3 -es2 acaba chamando a atenção de cada coisa.
Isso não seria possível apenas olhando o fonte, só mesmo -w3 -es2.

Restam duas.
Fazendo passo a passo, dá pra fazer outras tarefas enquanto acerta.
Caso precise urgente da rotina, sempre continua a opção de compilar usando -w0 -es0, e continuar depois.

getsys.prg:1054: warning W0003 Variable 'JUNK' declared but not used in function '1005:RANGECHECK'
getsys.prg:1178: warning W0032 Variable 'NKEY' is assigned but not used in function '1164:_INKEY'

Usando -e3 -es2

MensagemEnviado: 29 Mai 2019 12:58
por JoséQuintas
getsys.png


Pronto.
Poderia usar o HB_SYMBOL_UNUSED, ou HB_UNUSED_SYMBOL, mas sempre me confundo.
IF .F. resolve, porque faz uso da variável e não faz nada.
Porque não retirei? Teria que analisar isso, talvez até comparar a GETSYS com a original pra ver se isso existe....
Assim resolve.

Usando -e3 -es2

MensagemEnviado: 29 Mai 2019 12:59
por JoséQuintas
A getsys após correções.

/***
*
*  Getsys.prg
*
*  Standard Clipper 5.2 GET/READ Subsystem
*
*  Copyright (c) 1991-1993, Computer Associates International, Inc.
*  All rights reserved.
*
*  This version adds the following public functions:
*
*    ReadKill( [<lKill>] )       --> lKill
*    ReadUpdated( [<lUpdated>] ) --> lUpdated
*    ReadFormat( [<bFormat>] )   --> bFormat | NIL
*
*  NOTE: compile with /m /n /w
*
*/

#include "Inkey.ch"
#include "Getexit.ch"

STATIC snMRow, snMCol
STATIC  nMRow,  nMCol

/***
*  Nation Message Constants
*  These constants are used with the NationMsg(<msg>) function.
*  The <msg> parameter can range from 1-12 and returns the national
*  version of the system message.
*/
#define _GET_INSERT_ON   7    // "Ins"
#define _GET_INSERT_OFF   8    // "   "
#define _GET_INVD_DATE   9    // "Invalid Date"
#define _GET_RANGE_FROM   10    // "Range: "
#define _GET_RANGE_TO   11    // " - "

#define K_UNDO          K_CTRL_U

//
// State variables for active READ
//
STATIC sbFormat
STATIC slUpdated := .F.
STATIC slKillRead
STATIC slBumpTop
STATIC slBumpBot
STATIC snLastExitState
STATIC snLastPos
STATIC soActiveGet
STATIC scReadProcName
STATIC snReadProcLine
STATIC nKey2
STATIC GetMsg
STATIC PosMsg

//
// Format of array used to preserve state variables
//
#define GSV_KILLREAD     1
#define GSV_BUMPTOP        2
#define GSV_BUMPBOT        3
#define GSV_LASTEXIT     4
#define GSV_LASTPOS        5
#define GSV_ACTIVEGET     6
#define GSV_READVAR        7
#define GSV_READPROCNAME   8
#define GSV_READPROCLINE   9

#define GSV_COUNT        9

/***
*
*  ReadModal()
*
*  Standard modal READ on an array of GETs
*
*/
FUNCTION ReadModal( GetList, nPos )
LOCAL oGet, nI
LOCAL aSavGetSysVars

GetMsg := {}
PosMsg := nPos
nKey2  := SPACE(0)

FOR nI := 1 TO LEN(GetList)
   IF VALTYPE(GetList[nI])<>"O"
    AADD(GetMsg ,GetList[nI,2])
    GetList[nI] := GetList[nI,1]
   ELSE
    AADD(GetMsg ,)
   ENDIF
NEXT

   IF ( VALTYPE( sbFormat ) == "B" )
    EVAL( sbFormat )
   ENDIF

   IF ( EMPTY( GetList ) )

    // S'87 compatibility
    SETPOS( MAXROW() - 1, 0 )
    RETURN (.F.)             // NOTE

   ENDIF

   // Preserve state variables
   aSavGetSysVars := ClearGetSysVars()

   // Set these for use in SET KEYs
   scReadProcName := PROCNAME( 1 )
   snReadProcLine := PROCLINE( 1 )

   // Set initial GET to be read
   IF !( VALTYPE( nPos ) == "N" .AND. nPos > 0 )
    nPos := Settle( Getlist, 0 )
    PosMsg:=nPos
   ENDIF

   WHILE !( nPos == 0 )

    // Get next GET from list and post it as the active GET
    PostActiveGet( oGet := GetList[ nPos ] )

    // Read the GET
    IF ( VALTYPE( oGet:reader ) == "B" )
       EVAL( oGet:reader, oGet )    // Use custom reader block
    ELSE
       GetReader( oGet )         // Use standard reader
    ENDIF

    // Move to next GET based on exit condition
    nPos := Settle( GetList, nPos )
    PosMsg:=nPos

   ENDDO

   // Restore state variables
   RestoreGetSysVars( aSavGetSysVars )

   // S'87 compatibility
   SETPOS( MAXROW() - 1, 0 )

   RETURN ( slUpdated )

/***
*
*  GetReader()
*
*  Standard modal read of a single GET
*
*/
PROCEDURE GetReader( oGet )
LOCAL lRestaura := .F.
PRIVATE cGetMsg, nLINAJU1, nLINAJU2, nCOLAJU1, nCOLAJU2
   // Read the GET if the WHEN condition is satisfied

   IF ( GetPreValidate( oGet ) )

    // Activate the GET for reading
    oGet:setFocus()

    WHILE ( oGet:exitState == GE_NOEXIT )

       // Check for initial typeout (no editable positions)
       IF ( oGet:typeOut )
        oGet:exitState := GE_ENTER
       ENDIF

       // Apply keystrokes until exit
       IF ( oGet:type == "N" )
        oGet:pos    := oGet:decPos()-1
        oGet:display()
       ENDIF
       SETPOS(oGet:row,oGet:col)
       WHILE ( oGet:exitState == GE_NOEXIT )
        IF ( oGet:type == "N" ) .AND. (oGet:pos < oGet:decPos )
         oGet:pos     := oGet:decPos()-1
         oGet:display()
        ENDIF
         GetApplyKey( oGet, INKEY(0)) // minkey( 0, @snMrow, @snMCol ) )
       ENDDO

       // Disallow exit if the VALID condition is not satisfied
       IF ( !GetPostValidate( oGet ) )
        oGet:exitState := GE_NOEXIT
       ENDIF
    ENDDO

    // De-activate the GET
    oGet:killFocus()

   ENDIF
   IF lRestaura
   ENDIF

   RETURN

/***
*
*  GetApplyKey()
*
*  Apply a single INKEY() keystroke to a GET
*
*  NOTE: GET must have focus.
*
*/
PROCEDURE GetApplyKey( oGet, nKey )

   LOCAL cKey, nTmp, lIns
   LOCAL bKeyBlock
   LOCAL nTemp
   LOCAL lTmp, lDec, lDec0

   // Check for SET KEY first
   IF !( ( bKeyBlock := setkey( nKey ) ) == NIL )
    GetDoSetKey( bKeyBlock, oGet )
    RETURN                   // NOTE
   ENDIF

   DO CASE
// CASE ( nKey == 45 ) .AND. SUBSTR(oGet:buffer,oGet:decPos()-1,1) == "0"
//       oGet:buffer := SUBSTR(oGet:buffer,1,oGet:decPos()-2)+"-"+SUBSTR(oGet:buffer,oGet:decPos()-1)
//       oGet:display()
   CASE ( nKey == K_UP )
    oGet:exitState := GE_UP

   CASE ( nKey == K_SH_TAB )
    oGet:exitState := GE_UP

   CASE ( nKey == K_DOWN )
    oGet:exitState := GE_DOWN

   CASE ( nKey == K_TAB )
    oGet:exitState := GE_DOWN

   CASE ( nKey == K_ENTER )
    oGet:changed := .T.
    oGet:exitState := GE_ENTER
    nKey2 := SPACE(0)

   CASE ( nKey == K_ESC )
    IF ( SET( _SET_ESCAPE ) )
       oGet:undo()
       oGet:exitState := GE_ESCAPE

    ENDIF

   CASE ( nKey == K_PGUP )
    oGet:exitState := GE_WRITE

   CASE ( nKey == K_PGDN )
    oGet:exitState := GE_WRITE

   CASE ( nKey == K_CTRL_HOME )
    oGet:exitState := GE_TOP

#ifdef CTRL_END_SPECIAL

   // Both ^W and ^End go to the last GET
   CASE ( nKey == K_CTRL_END )
    oGet:exitState := GE_BOTTOM

#else

   // Both ^W and ^End terminate the READ (the default)
   CASE ( nKey == K_CTRL_W )
    oGet:exitState := GE_WRITE

#endif

   CASE ( nKey == K_INS )
    SET( _SET_INSERT, !SET( _SET_INSERT ) )
    ShowScoreboard()

   CASE ( nKey == K_UNDO )
    oGet:undo()

   CASE ( nKey == K_HOME )
    oGet:home()

   CASE ( nKey == K_END )
    oGet:end()

   CASE ( nKey == K_RIGHT )
    oGet:right()
    nKey2 := SPACE(0)

   CASE ( nKey == K_LEFT )
    oGet:left()
    nKey2 := SPACE(0)

   CASE ( nKey == K_CTRL_RIGHT )
    oGet:wordRight()
    nKey2 := SPACE(0)

   CASE ( nKey == K_CTRL_LEFT )
    oGet:wordLeft()
    nKey2 := SPACE(0)

   CASE ( nKey == K_BS ) .OR. ((nKey == K_DEL) .AND. (oGet:type =="N"))
    IF ( oGet:type == "N" ) .AND. (oGet:pos < oGet:decPos )
       IF AT(".",oGet:buffer) <> 0 .OR. AT(",",oGet:buffer) <> 0
        oGet:pos    := oGet:decPos()-1
        nTemp := oGet:unTransform()
        nTemp := (nTemp-INT(nTemp)) + INT(nTemp / 10)
       ELSE
        oGet:pos    := oGet:decPos()-1
        oGet:delete()
        nTemp := oGet:unTransform()
       ENDIF
       oGet:buffer := Transform(nTemp,oGet:picture)
       oGet:pos    := oGet:decPos()-1
       oGet:display()
    ELSE
       IF (oGet:type="N").AND.(oGet:pos=oGet:decPos+1).AND.(nKey<>K_DEL)
         oGet:pos := oGet:decPos()-1
         KEYBOARD CHR( K_BS )
       ELSE
         IF ( nKey == K_DEL )
          oGet:delete()
         ELSE
          oGet:backSpace()
         ENDIF
         oGet:display()
      ENDIF
    ENDIF
   CASE ( nKey == K_DEL )
    oGet:delete()

   CASE ( nKey == K_CTRL_T )
    oGet:delWordRight()

   CASE ( nKey == K_CTRL_Y )
    IF oGet:type == "N"
       nTmp := oGet:pos
       oGet:pos    := 01
       oGet:delEnd()
       oGet:pos    := nTmp
       oGet:display()
    ELSE
       oGet:delEnd()
    ENDIF

   CASE ( nKey == K_CTRL_BS )
    oGet:delWordLeft()

   OTHERWISE
    lIns  := .T.

    IF ( nKey >= 32 .AND. nKey <= 255 )

       IF ! EMPTY(nKey2) .AND.  oGet:type == "C"
         lIns := Acentos(oGet, nKey2, @nKey)
         nKey2 := SPACE(0)
       ENDIF

       cKey := CHR( nKey )

       IF ( oGet:type == "N" .AND. ( cKey == "." .OR. cKey == "," ) )
        lTmp := AT("-",oGet:buffer) <> 0
        IF oGet:Clear
         oGet:buffer := Transform(0,oGet:picture)
        ENDIF
        oGet:toDecPos()
        IF lTmp .AND. AT("-",oGet:buffer) == 0
         oGet:buffer := SUBSTR(oGet:buffer,1,oGet:decPos()-2)+"-"+SUBSTR(oGet:buffer,oGet:decPos()-1)
         oGet:buffer := SUBSTR(oGet:buffer,2)
        ENDIF
        oGet:display()
       ELSEIF ( oGet:type == "N" ) .AND. (oGet:pos < oGet:decPos ) .AND. ;
       ((nKey >= ASC('0') .AND. nKey <= ASC('9')) .OR. UPPER(CHR(nKey))="C";
                  .OR.  nKey == ASC('+')  .OR.  nKey == ASC('-'))
        nTemp := oGet:unTransform()
        IF UPPER(cKey) == "C" .OR. oGet:clear
         oGet:clear := .F.
         nTemp = 0
         oGet:buffer := Transform(nTemp,oGet:picture)
         oGet:display()
        ENDIF
        lDec := AT(".",Transform(0,oGet:picture))
        IF(lDec==0,lDec := AT(",",Transform(0,oGet:picture)),lDec)
        lDec0 := IF(lDec<>0,IF(LEN(oGet:buffer) > (lDec+1),.T.,.F.),.T.)
        lDec  := IF(lDec<>0,.T.,.F.)
        IF(oGet:picture==NIL,lDec0:=.T.,)

        IF LEN((oGet:buffer)) >= (LEN(ALLTRIM(oGet:buffer))+1)
         IF oGet:type == "N" .AND. cKey == "-"
            nKey2 := ASC("-")
         ELSE
            lTmp  := AT("-",oGet:buffer) <> 0
            nTemp := (nTemp-INT(nTemp)) + INT(nTemp * 10)
            oGet:buffer := Transform(nTemp,oGet:picture)
            IF nTemp = 0 .AND. lTmp
             IF LEN(oGet:buffer) < oGet:decPos() .and. 1 = 2
                oGet:buffer := SUBSTR(oGet:buffer,1,oGet:decPos()-3)+"-"+SUBSTR(oGet:buffer,oGet:decPos()-2)
                oGet:buffer := SUBSTR(oGet:buffer,2)
             ELSE
                oGet:buffer := SUBSTR(oGet:buffer,1,oGet:decPos()-IF(lDec0,2,3))+"-"+SUBSTR(oGet:buffer,oGet:decPos()-IF(lDec0,1,2))
                oGet:buffer := SUBSTR(oGet:buffer,2)
             ENDIF
            ENDIF                                                                //2   1
            oGet:pos   := oGet:decPos() -IF(oGet:picture<>NIL .AND. lDec, IF(lTmp .AND. LEN(oGet:buffer) < oGet:decPos(),2,1),0)
            oGet:overstrike( cKey )                                                    //2   1
            oGet:pos   := oGet:decPos() -IF(oGet:picture<>NIL .AND. lDec, IF(lTmp .AND. LEN(oGet:buffer) < oGet:decPos(),2,1),0)
         ENDIF
         IF VALTYPE(nKey2) == "N" .AND. cKey == "-"
            lTmp  := AT("-",oGet:buffer) == 0
            nTemp := oGet:unTransform()
            nTemp *= (-1)
            oGet:buffer := Transform(nTemp,oGet:picture)
            IF nTemp = 0 .AND. lTmp
             IF LEN(oGet:buffer) < oGet:decPos() .and. 1 = 2
                oGet:buffer := SUBSTR(oGet:buffer,1,oGet:decPos()-3)+"-"+SUBSTR(oGet:buffer,oGet:decPos()-2)
                oGet:buffer := SUBSTR(oGet:buffer,2)
             ELSE
                oGet:buffer := SUBSTR(oGet:buffer,1,oGet:decPos()-IF(lDec0,2,3))+"-"+SUBSTR(oGet:buffer,oGet:decPos()-IF(lDec0,1,2))
                oGet:buffer := SUBSTR(oGet:buffer,2)
             ENDIF
            ENDIF
         ENDIF
         IF VALTYPE(nKey2) == "N"
            nKey2 := SPACE(0)
         ENDIF
         oGet:display()
         IF LEN(SUBSTR(oGet:buffer,1,oGet:decpos-1))==LEN(ALLTRIM(SUBSTR(oGet:buffer,1,oGet:decpos-1))) .AND. (!SET(_SET_CONFIRM))
            oGet:exitstate:=GE_ENTER
         ENDIF
        ELSEIF LEN(SUBSTR(oGet:buffer,1,oGet:decpos-1)) == 1 .AND. (oGet:pos < oGet:decPos )
         oGet:overstrike(cKey)
         oGet:pos := oGet:decPos()
         oGet:display()
         IF LEN(SUBSTR(oGet:buffer,1,oGet:decpos-1))==1 .AND. (!SET(_SET_CONFIRM))
            oGet:exitstate:=GE_ENTER
         ENDIF
        ELSE
         IF ( !SET( _SET_CONFIRM ) )
            oGet:exitState := GE_ENTER
         ELSE
            ?? CHR(7)
         ENDIF

        ENDIF
        IF oGet:type == "N" .AND. cKey == "-"
         nKey2 := nKey
        ENDIF
       ELSE

        IF ( SET( _SET_INSERT ) ) .AND. lIns
         oGet:insert( cKey )
        ELSE
         oGet:overstrike( cKey )
        ENDIF
        IF ( oGet:type == "C")
         IF EMPTY(nKey2) .AND. (nKey=126 .OR. nKey=39 .OR. nKey=96 .OR. nKey=34 .OR. nKey=94 .OR. nKey=46)
            nKey2 := nKey
            oGet:left()
         ELSE
            nKey2 := SPACE(0)
         ENDIF
        ENDIF

        IF ( oGet:typeOut )
         IF ( SET( _SET_BELL ) )
            ?? CHR(7)
         ENDIF

         IF ( !SET( _SET_CONFIRM ) )
            oGet:exitState := GE_ENTER
         ENDIF
        ENDIF

       ENDIF

    ENDIF

   ENDCASE
   oGet:changed := .T.

   RETURN

/***
*
*  GetPreValidate()
*
*  Test entry condition (WHEN clause) for a GET
*
*/
FUNCTION GetPreValidate( oGet )

   LOCAL lSavUpdated
   LOCAL lWhen := .T.

   IF !( oGet:preBlock == NIL )

    lSavUpdated := slUpdated

    lWhen := EVAL( oGet:preBlock, oGet )

    oGet:display()

    ShowScoreBoard()
    slUpdated := lSavUpdated

   ENDIF

   IF ( slKillRead )

    lWhen := .F.
    oGet:exitState := GE_ESCAPE      // Provokes ReadModal() exit

   ELSEIF ( !lWhen )

    oGet:exitState := GE_WHEN      // Indicates failure

   ELSE

    oGet:exitState := GE_NOEXIT      // Prepares for editing

   END

   RETURN ( lWhen )

/***
*
*  GetPostValidate()
*
*  Test exit condition (VALID clause) for a GET
*
*  NOTE: Bad dates are rejected in such a way as to preserve edit buffer
*
*/
FUNCTION GetPostValidate( oGet )

   LOCAL lSavUpdated
   LOCAL lValid := .T.

   IF ( oGet:exitState == GE_ESCAPE )
    RETURN ( .T. )             // NOTE
   ENDIF

   IF ( oGet:badDate() )
    oGet:home()
    DateMsg()
    ShowScoreboard()
    RETURN ( .F. )             // NOTE
   ENDIF

   // If editing occurred, assign the new value to the variable
   IF ( oGet:changed )
    oGet:assign()
    slUpdated := .T.
   ENDIF

   // Reform edit buffer, set cursor to home position, redisplay
   oGet:reset()

   // Check VALID condition if specified
   IF !( oGet:postBlock == NIL )

    lSavUpdated := slUpdated

    // S'87 compatibility
    SETPOS( oGet:row, oGet:col + LEN( oGet:buffer ) )

    lValid := EVAL( oGet:postBlock, oGet )

    // Reset S'87 compatibility cursor position
    SETPOS( oGet:row, oGet:col )

    ShowScoreBoard()
    oGet:updateBuffer()

    slUpdated := lSavUpdated

    IF ( slKillRead )
       oGet:exitState := GE_ESCAPE     // Provokes ReadModal() exit
       lValid := .T.

    ENDIF
   ENDIF

   RETURN ( lValid )

/***
*
*  GetDoSetKey()
*
*  Process SET KEY during editing
*
*/
PROCEDURE GetDoSetKey( keyBlock, oGet )

   LOCAL lSavUpdated

   // If editing has occurred, assign variable
   IF ( oGet:changed )
    oGet:assign()
    slUpdated := .T.
   ENDIF

   lSavUpdated := slUpdated

   EVAL( keyBlock, scReadProcName, snReadProcLine, ReadVar() )

   ShowScoreboard()
   oGet:updateBuffer()

   slUpdated := lSavUpdated

   IF ( slKillRead )
    oGet:exitState := GE_ESCAPE       // provokes ReadModal() exit
   ENDIF

   RETURN

/***
*         READ services
*/

/***
*
*  Settle()
*
*  Returns new position in array of Get objects, based on:
*    - current position
*    - exitState of Get object at current position
*
*  NOTES: return value of 0 indicates termination of READ
*      exitState of old Get is transferred to new Get
*
*/
STATIC FUNCTION Settle( GetList, nPos )

   LOCAL nExitState

   IF ( nPos == 0 )
    nExitState := GE_DOWN
   ELSE
    nExitState := GetList[ nPos ]:exitState
   ENDIF

   IF ( nExitState == GE_ESCAPE .or. nExitState == GE_WRITE )
    RETURN ( 0 )            // NOTE
   ENDIF

   IF !( nExitState == GE_WHEN )
    // Reset state info
    snLastPos := nPos
    slBumpTop := .F.
    slBumpBot := .F.
   ELSE
    // Re-use last exitState, do not disturb state info
    nExitState := snLastExitState
   ENDIF

   //
   // Move
   //
   DO CASE
   CASE ( nExitState == GE_UP )
    nPos--

   CASE ( nExitState == GE_DOWN )
    nPos++

   CASE ( nExitState == GE_TOP )
    nPos     := 1
    slBumpTop  := .T.
    nExitState := GE_DOWN

   CASE ( nExitState == GE_BOTTOM )
    nPos     := LEN( GetList )
    slBumpBot  := .T.
    nExitState := GE_UP

   CASE ( nExitState == GE_ENTER )
    nPos++

   ENDCASE

   //
   // Bounce
   //
   IF ( nPos == 0 )                 // Bumped top
    IF ( !ReadExit() .and. !slBumpBot )
       slBumpTop   := .T.
       nPos      := snLastPos
       nExitState := GE_DOWN
    ENDIF

   ELSEIF ( nPos == len( GetList ) + 1 )  // Bumped bottom
    IF ( !ReadExit() .and. !( nExitState == GE_ENTER ) .and. !slBumpTop )
       slBumpBot   := .T.
       nPos      := snLastPos
       nExitState := GE_UP
    ELSE
       nPos := 0
    ENDIF
   ENDIF

   // Record exit state
   snLastExitState := nExitState

   IF !( nPos == 0 )
    GetList[ nPos ]:exitState := nExitState
   ENDIF

   RETURN ( nPos )

/***
*
*  PostActiveGet()
*
*  Post active GET for ReadVar(), GetActive()
*
*/
STATIC PROCEDURE PostActiveGet( oGet )

   GetActive( oGet )
   ReadVar( GetReadVar( oGet ) )

   ShowScoreBoard()

   RETURN

/***
*
*  ClearGetSysVars()
*
*  Save and clear READ state variables. Return array of saved values
*
*  NOTE: 'Updated' status is cleared but not saved (S'87 compatibility)
*/
STATIC FUNCTION ClearGetSysVars()

   LOCAL aSavSysVars[ GSV_COUNT ]

   // Save current sys vars
   aSavSysVars[ GSV_KILLREAD ]   := slKillRead
   aSavSysVars[ GSV_BUMPTOP ]      := slBumpTop
   aSavSysVars[ GSV_BUMPBOT ]      := slBumpBot
   aSavSysVars[ GSV_LASTEXIT ]   := snLastExitState
   aSavSysVars[ GSV_LASTPOS ]      := snLastPos
   aSavSysVars[ GSV_ACTIVEGET ]   := GetActive( NIL )
   aSavSysVars[ GSV_READVAR ]      := ReadVar( "" )
   aSavSysVars[ GSV_READPROCNAME ] := scReadProcName
   aSavSysVars[ GSV_READPROCLINE ] := snReadProcLine

   // Re-init old ones
   slKillRead       := .F.
   slBumpTop       := .F.
   slBumpBot       := .F.
   snLastExitState := 0
   snLastPos       := 0
   scReadProcName  := ""
   snReadProcLine  := 0
   slUpdated       := .F.

   RETURN ( aSavSysVars )

/***
*
*  RestoreGetSysVars()
*
*  Restore READ state variables from array of saved values
*
*  NOTE: 'Updated' status is not restored (S'87 compatibility)
*
*/
STATIC PROCEDURE RestoreGetSysVars( aSavSysVars )

   slKillRead       := aSavSysVars[ GSV_KILLREAD ]
   slBumpTop       := aSavSysVars[ GSV_BUMPTOP ]
   slBumpBot       := aSavSysVars[ GSV_BUMPBOT ]
   snLastExitState := aSavSysVars[ GSV_LASTEXIT ]
   snLastPos       := aSavSysVars[ GSV_LASTPOS ]

   GetActive( aSavSysVars[ GSV_ACTIVEGET ] )

   ReadVar( aSavSysVars[ GSV_READVAR ] )

   scReadProcName  := aSavSysVars[ GSV_READPROCNAME ]
   snReadProcLine  := aSavSysVars[ GSV_READPROCLINE ]

   RETURN

/***
*
*  GetReadVar()
*
*  Set READVAR() value from a GET
*
*/
STATIC FUNCTION GetReadVar( oGet )

   LOCAL cName := UPPER( oGet:name )
   LOCAL i

   // The following code includes subscripts in the name returned by
   // this FUNCTIONtion, if the get variable is an array element
   //
   // Subscripts are retrieved from the oGet:subscript instance variable
   //
   // NOTE: Incompatible with Summer 87
   //
   IF !( oGet:subscript == NIL )
    FOR i := 1 TO LEN( oGet:subscript )
       cName += "[" + LTRIM( STR( oGet:subscript[i] ) ) + "]"
    NEXT
   END

   RETURN ( cName )

/***
*         System Services
*/

/***
*
*  __SetFormat()
*
*  SET FORMAT service
*
*/
PROCEDURE __SetFormat( b )
   sbFormat := IF( VALTYPE( b ) == "B", b, NIL )
   RETURN

/***
*
*  __KillRead()
*
*  CLEAR GETS service
*
*/
PROCEDURE __KillRead()
   slKillRead := .T.
   RETURN

/***
*
*  GetActive()
*
*  Retrieves currently active GET object
*/
FUNCTION GetActive( g )

   LOCAL oldActive := soActiveGet

   IF ( PCOUNT() > 0 )
    soActiveGet := g
   ENDIF

   RETURN ( oldActive )

/***
*
*  Updated()
*
*/
FUNCTION Updated()
   RETURN slUpdated

/***
*
*  ReadExit()
*
*/
FUNCTION ReadExit( lNew )
   RETURN ( SET( _SET_EXIT, lNew ) )

/***
*
*  ReadInsert()
*
*/
FUNCTION ReadInsert( lNew )
   RETURN ( SET( _SET_INSERT, lNew ) )

/***
*         Wacky Compatibility Services
*/

// Display coordinates for SCOREBOARD
#define SCORE_ROW      0
#define SCORE_COL      60

/***
*
*  ShowScoreboard()
*
*/
STATIC PROCEDURE ShowScoreboard()

   LOCAL nRow
   LOCAL nCol

   IF ( SET( _SET_SCOREBOARD ) )
    nRow := ROW()
    nCol := COL()

    SETPOS( SCORE_ROW, SCORE_COL )
    DISPOUT( IF( SET( _SET_INSERT ), NationMsg(_GET_INSERT_ON),;
                     NationMsg(_GET_INSERT_OFF)) )
    SETPOS( nRow, nCol )
   ENDIF

   RETURN

/***
*
*  DateMsg()
*
*/
STATIC PROCEDURE DateMsg()

   LOCAL nRow
   LOCAL nCol

   IF ( SET( _SET_SCOREBOARD ) )

    nRow := ROW()
    nCol := COL()

    SETPOS( SCORE_ROW, SCORE_COL )
    DISPOUT( NationMsg(_GET_INVD_DATE) )
    SETPOS( nRow, nCol )

    WHILE ( NEXTKEY() == 0 )
    END

    SETPOS( SCORE_ROW, SCORE_COL )
    DISPOUT( SPACE( LEN( NationMsg(_GET_INVD_DATE) ) ) )
    SETPOS( nRow, nCol )

   ENDIF

   RETURN

/***
*
*  RangeCheck()
*
*  NOTE: Unused second param for 5.00 compatibility.
*
*/
FUNCTION RangeCheck( oGet, junk, lo, hi )

   LOCAL cMsg, nRow, nCol
   LOCAL xValue

   IF .F.
      ? Junk
   ENDIF

   IF ( !oGet:changed )
    RETURN ( .T. )      // NOTE
   ENDIF

   xValue := oGet:varGet()

   IF ( xValue >= lo .and. xValue <= hi )
    RETURN ( .T. )      // NOTE
   ENDIF

   IF ( SET(_SET_SCOREBOARD) )

    cMsg := NationMsg(_GET_RANGE_FROM) + LTRIM( TRANSFORM( lo, "" ) ) + ;
          NationMsg(_GET_RANGE_TO) + LTRIM( TRANSFORM( hi, "" ) )

    IF ( LEN( cMsg ) > MAXCOL() )
       cMsg := SUBSTR( cMsg, 1, MAXCOL() )
    ENDIF

    nRow := ROW()
    nCol := COL()

    SETPOS( SCORE_ROW, MIN( 60, MAXCOL() - LEN( cMsg ) ) )
    DISPOUT( cMsg )
    SETPOS( nRow, nCol )

    WHILE ( NEXTKEY() == 0 )
    END

    SETPOS( SCORE_ROW, MIN( 60, MAXCOL() - LEN( cMsg ) ) )
    DISPOUT( SPACE( LEN( cMsg ) ) )
    SETPOS( nRow, nCol )

   ENDIF

   RETURN ( .F. )

/***
*
*  ReadKill()
*
*/
FUNCTION ReadKill( lKill )

   LOCAL lSavKill := slKillRead

   IF ( PCOUNT() > 0 )
    slKillRead := lKill
   ENDIF

   RETURN ( lSavKill )

/***
*
*  ReadUpdated()
*
*/
FUNCTION ReadUpdated( lUpdated )

   LOCAL lSavUpdated := slUpdated

   IF ( PCOUNT() > 0 )
    slUpdated := lUpdated
   ENDIF

   RETURN ( lSavUpdated )

/***
*
*  ReadFormat()
*
*/
FUNCTION ReadFormat( b )

   LOCAL bSavFormat := sbFormat

   IF ( PCOUNT() > 0 )
    sbFormat := b
   ENDIF

   RETURN ( bSavFormat )

**********************************************************************
FUNCTION Mensagem1(nLinh,cTexto,cCor)
LOCAL nCol,nLargJan
    nLargJan := LEN(cTexto)
IF nLargJan < 10
    nLargJan := 10
ENDIF
nCol := (80 -nLargJan)/2
  @ nLinh,nCol CLEAR TO nLinh,nCol + nLargJan
  @ nLinh,nCol SAY cTexto COLOR cCor
RETURN NIL
**********************************************************************

// "Ž„ …†ƒ€‡‚ˆ‰Š¡‹Œ“¢™”•£š–¦§"

FUNCTION Acentos(oGet,nKey2,nKey)
LOCAL lIns := .F., nKey3
nKey2 := CHR(nKey2)
nKey3 := nKey
nKey  := CHR(nKey )
IF nKey2 == "~"
   IF   nKey=="A" ; nKey:="Ž"
   ELSEIF nKey=="O" ; nKey:="™"
   ELSEIF nKey=="a" ; nKey:="„"
   ELSEIF nKey=="o" ; nKey:="”"
   ELSE  ; lIns := .T. ; ENDIF
ELSEIF nKey2 == "'"
   IF   nKey=="A" ; nKey:=""
   ELSEIF nKey=="E" ; nKey:=""
   ELSEIF nKey=="a" ; nKey:=" "
   ELSEIF nKey=="e" ; nKey:="‚"
   ELSEIF nKey=="i" ; nKey:="¡"
   ELSEIF nKey=="o" ; nKey:="¢"
   ELSEIF nKey=="u" ; nKey:="£"
   ELSEIF nKey=="C" ; nKey:="€"
   ELSEIF nKey=="c" ; nKey:="‡"
   ELSE  ; lIns := .T. ; ENDIF
ELSEIF nKey2 == "`"
   IF   nKey=="a" ; nKey:="…"
   ELSEIF nKey=="e" ; nKey:="Š"
   ELSEIF nKey=="i" ; nKey:=""
   ELSEIF nKey=="o" ; nKey:="•"
   ELSE  ; lIns := .T. ; ENDIF
ELSEIF nKey2 == "^"
   IF   nKey=="a" ; nKey:="ƒ"
   ELSEIF nKey=="e" ; nKey:="ˆ"
   ELSEIF nKey=="i" ; nKey:="Œ"
   ELSEIF nKey=="o" ; nKey:="“"
   ELSEIF nKey=="u" ; nKey:="–"
   ELSE  ; lIns := .T. ; ENDIF
ELSEIF nKey2 == "."
   IF   nKey=="a" ; nKey:="¦"
   ELSEIF nKey=="o" ; nKey:="§"
   ELSE  ; lIns := .T. ; ENDIF
ENDIF
nKey2 := ASC(nKey2)
nKey  := ASC(nKey )
IF nKey3 == nKey
   oGet:right()
ENDIF
RETURN lIns

***************************************************************************

FUNCTION _INKEY(nTempo,lTrava)
LOCAL nKey, nTime := SECONDS()
lTrava:=IF(lTrava==NIL,.F.,.T.)
IF lTrava .AND. nTempo <> NIL .AND. nTempo <> 0
   WHILE IF (nTempo > 0, (SECONDS() - nTime) < nTempo, .T.)
   ENDDO
   nKey := LASTKEY()
ELSE
   nKey :=  INKEY(0) // Minkey(nTempo, @nMRow, @nMCol, .T.)
ENDIF
RETURN (nKey)

***************************************************************************

FUNCTION AJUDADECAMPOATIVA( oGet )
LOCAL nROW := ROW(), nCOL := COL(), nCURSOR := SETCURSOR(), cCOR := SETCOLOR()
LOCAL GetMensg := GetMsg[PosMsg], nCALCULO, nPOSOGET
LOCAL nPOS1 := AT("|",GetMensg), nPOS2, cVAR[3], nTAMAJU
LOCAL nColAju1, nColAju2, nLinAju1, nLinAju2
IF nPOS1 # 0
   cVAR[1] := SUBSTR(GetMensg,1,nPOS1-1)
   GetMensg := SUBSTR(GetMensg,nPOS1+1,LEN(GetMensg))
ELSE
   cVAR[1] := GetMensg
   GetMensg := SPACE(0)
ENDIF
nPOS2 := AT("|",GetMensg)
IF nPOS2 # 0
   cVAR[2] := SUBSTR(GetMensg,1,nPOS2-1)
   GetMensg := SUBSTR(GetMensg,nPOS2+1,LEN(GetMensg))
   cVAR[3] := GetMensg
ELSEIF nPOS2 == 0 .AND. !EMPTY(GetMensg)
   cVAR[2] := GetMensg
ENDIF
IF cVAR[3] # NIL
   nCALCULO := 4
ELSEIF cVAR[3] == NIL .AND. cVAR[2] # NIL
   nCALCULO := 3
ELSE
   nCALCULO := 2
ENDIF
nTAMAJU := LenLargura( cVAR )
nPOSOGET := oGet:col + 4
IF nPOSOGET+4+nTAMAJU > 79
   DO WHIL .T.
    nPOSOGET--
    IF nPOSOGET+4+nTAMAJU <= 79
       EXIT
    ENDIF
   ENDDO
ENDIF
nCOLAJU1 := nPOSOGET
nCOLAJU2 := nPOSOGET+nTAMAJU
IF oGet:row+1+nCALCULO > 24
   nLINAJU1 := oGet:row-1-nCALCULO
   nLINAJU2 := oGet:row-1
ELSE
   nLINAJU1 := oGet:row+1
   nLINAJU2 := oGet:row+1+nCALCULO
ENDIF
//cGetMsg := SAVESCREEN(nLINAJU1,nCOLAJU1-2,nLINAJU2+1,nCOLAJU2+3)
@ nLINAJU1,nCOLAJU1 TO nLINAJU2,nCOLAJU2+3
@ nLINAJU1+1,nCOLAJU1+1 SAY " "+PAD( cVAR[1], nTAMAJU)+" "
IF cVAR[2] # NIL
   @ nLINAJU1+2,nCOLAJU1+1 SAY " "+PAD( cVAR[2], nTAMAJU)+" "
ENDIF
IF cVAR[3] # NIL
   @ nLINAJU1+3,nCOLAJU1+1 SAY " "+PAD( cVAR[3], nTAMAJU)+" "
ENDIF
SETPOS(nROW,nCOL)
SETCOLOR(cCOR)
SETCURSOR(nCURSOR)
RETURN NIL
***************************************************************************
STATIC FUNCTION LenLargura( aMenu2 )
LOCAL nLargura, i
nLargura := aMenu2[1]
FOR i = 1 TO LEN(aMenu2)
   IF aMenu2[i] # NIL
    IF LEN(nLargura) < LEN(aMenu2[i])
       nLargura := aMenu2[i]
    ENDIF
   ENDIF
NEXT
RETURN LEN(nLargura)
***************************************************************************
FUNCTION _ROUND(nValor,nDecimals)
Hb_Default( @nDecimals,2)
RETURN (ROUND(val(str(nValor)),nDecimals))

***************************************************************************

FUNCTION GetPassword(oGet)
LOCAL nKey
LOCAL lRestaura := .F.
PRIVATE nLINAJU1, nLINAJU2, nCOLAJU1, nCOLAJU2
IF (GetPreValidate(oGet))

    // Activate the GET for reading
    oGet:setFocus()
    IF GetMsg[PosMsg] <> NIL
    ENDIF

   oGet:SetFocus()
   oGet:cargo := ""
   Do While(oGet:exitState == GE_NOEXIT)
    IF (oGet:typeOut)
       oGet:exitState := GE_ENTER
    ENDIF
    Do While (oGet:exitState == GE_NOEXIT)
       nKey := INKEY(0)
       IF nKey >= 32 .AND. nKey <= 255
        oGet:cargo += Chr(nKey)
        GetApplyKey(oGet,Asc("þ"))
       ELSEIF nKey == K_BS
        oGet:cargo := Substr(oGet:cargo,1,Len(oGet:cargo)-1)
        GetApplyKey(oGet,nKey)
       ELSEIF nKey == K_ENTER
        GetApplyKey(oGet,nKey)
       ELSEIF nKey == K_ESC
        GetApplyKey(oGet,nKey)
       ENDIF
    ENDDO
    IF (!GetPostValidate(oGet))
       oGet:exitState := GE_NOEXIT
    ENDIF
   ENDDO
   oGet:KillFocus()
   IF lRestaura
   ENDIF
ENDIF
IF oGet:exitState != GE_ESCAPE
   oGet:varPut(oGet:cargo)
ENDIF
RETURN NIL


Mas, porque parar aqui... usar meu formatador de fonte.

Usando -e3 -es2

MensagemEnviado: 29 Mai 2019 13:05
por JoséQuintas
Pronto.
Precisei alterar alguns DO WHILE(
O formatador NÃO considerou que era DO WHILE
E também ELSE ; xxxxx; ENDIF
O formatador também se perdeu nisso.
Rotina final

/***
*  Getsys.prg
*  Standard Clipper 5.2 GET/READ Subsystem
*  Copyright (c) 1991-1993, Computer Associates International, Inc.
*  All rights reserved.
*  This version adds the following public functions:
*    ReadKill( [<lKill>] )       --> lKill
*    ReadUpdated( [<lUpdated>] ) --> lUpdated
*    ReadFormat( [<bFormat>] )   --> bFormat | NIL
*  NOTE: compile with /m /n /w
*/

#include "Inkey.ch"
#include "Getexit.ch"

STATIC snMRow, snMCol
STATIC  nMRow,  nMCol

/***
*  Nation Message Constants
*  These constants are used with the NationMsg(<msg>) function.
*  The <msg> parameter can range from 1-12 and returns the national
*  version of the system message.
*/
#define _GET_INSERT_ON   7    // "Ins"
#define _GET_INSERT_OFF   8    // "   "
#define _GET_INVD_DATE   9    // "Invalid Date"
#define _GET_RANGE_FROM   10    // "Range: "
#define _GET_RANGE_TO   11    // " - "

#define K_UNDO          K_CTRL_U

// State variables for active READ
STATIC sbFormat
STATIC slUpdated := .F.
STATIC slKillRead
STATIC slBumpTop
STATIC slBumpBot
STATIC snLastExitState
STATIC snLastPos
STATIC soActiveGet
STATIC scReadProcName
STATIC snReadProcLine
STATIC nKey2
STATIC GetMsg
STATIC PosMsg

// Format of array used to preserve state variables
#define GSV_KILLREAD     1
#define GSV_BUMPTOP        2
#define GSV_BUMPBOT        3
#define GSV_LASTEXIT     4
#define GSV_LASTPOS        5
#define GSV_ACTIVEGET     6
#define GSV_READVAR        7
#define GSV_READPROCNAME   8
#define GSV_READPROCLINE   9

#define GSV_COUNT        9

/***
*  ReadModal()
*  Standard modal READ on an array of GETs
*/

FUNCTION ReadModal( GetList, nPos )

   LOCAL oGet, nI
   LOCAL aSavGetSysVars

   GetMsg := {}
   PosMsg := nPos
   nKey2  := Space(0)

   FOR nI := 1 TO Len(GetList)
      IF VALTYPE(GetList[nI])<>"O"
         AAdd(GetMsg ,GetList[nI,2])
         GetList[nI] := GetList[nI,1]
      ELSE
         AAdd(GetMsg ,)
      ENDIF
   NEXT

   IF ( VALTYPE( sbFormat ) == "B" )
      EVAL( sbFormat )
   ENDIF

   IF ( Empty( GetList ) )

      // S'87 compatibility
      SETPOS( MAXROW() - 1, 0 )
      RETURN (.F.)             // NOTE

   ENDIF

   // Preserve state variables
   aSavGetSysVars := ClearGetSysVars()

   // Set these for use in SET KEYs
   scReadProcName := PROCNAME( 1 )
   snReadProcLine := PROCLINE( 1 )

   // Set initial GET to be read
   IF !( VALTYPE( nPos ) == "N" .AND. nPos > 0 )
      nPos := Settle( Getlist, 0 )
      PosMsg:=nPos
   ENDIF

   DO WHILE !( nPos == 0 )

      // GET next GET from list and post it as the active GET
      PostActiveGet( oGet := GetList[ nPos ] )

      // Read the GET
      IF ( VALTYPE( oGet:reader ) == "B" )
         EVAL( oGet:reader, oGet )    // Use custom reader block
      ELSE
         GetReader( oGet )         // Use standard reader
      ENDIF

      // Move to next GET based on exit condition
      nPos := Settle( GetList, nPos )
      PosMsg:=nPos

   ENDDO

   // Restore state variables
   RestoreGetSysVars( aSavGetSysVars )

   // S'87 compatibility
   SETPOS( MAXROW() - 1, 0 )

   RETURN ( slUpdated )

   /***
   *  GetReader()
   *  Standard modal read of a single GET
   */

PROCEDURE GetReader( oGet )

   LOCAL lRestaura := .F.
   PRIVATE cGetMsg, nLINAJU1, nLINAJU2, nCOLAJU1, nCOLAJU2

   // Read the GET IF the WHEN condition is satisfied

   IF ( GetPreValidate( oGet ) )

      // Activate the GET for reading
      oGet:setFocus()

      DO WHILE ( oGet:exitState == GE_NOEXIT )

         // Check for initial typeout (no editable positions)
         IF ( oGet:typeOut )
            oGet:exitState := GE_ENTER
         ENDIF

         // Apply keystrokes until exit
         IF ( oGet:type == "N" )
            oGet:pos    := oGet:decPos()-1
            oGet:display()
         ENDIF
         SETPOS(oGet:row,oGet:col)
         DO WHILE ( oGet:exitState == GE_NOEXIT )
            IF ( oGet:type == "N" ) .AND. (oGet:pos < oGet:decPos )
               oGet:pos     := oGet:decPos()-1
               oGet:display()
            ENDIF
            GetApplyKey( oGet, Inkey(0)) // minkey( 0, @snMrow, @snMCol ) )
         ENDDO

         // Disallow exit IF the VALID condition is not satisfied
         IF ( !GetPostValidate( oGet ) )
            oGet:exitState := GE_NOEXIT
         ENDIF
      ENDDO

      // De-activate the GET
      oGet:killFocus()

   ENDIF
   IF lRestaura
   ENDIF

   RETURN

   /***
   *  GetApplyKey()
   *  Apply a single Inkey() keystroke to a GET
   *  NOTE: GET must have focus.
   */

PROCEDURE GetApplyKey( oGet, nKey )

   LOCAL cKey, nTmp, lIns
   LOCAL bKeyBlock
   LOCAL nTemp
   LOCAL lTmp, lDec, lDec0

   // Check for SET KEY first
   IF !( ( bKeyBlock := setkey( nKey ) ) == NIL )
      GetDoSetKey( bKeyBlock, oGet )
      RETURN                   // NOTE
   ENDIF

   DO CASE
      // CASE ( nKey == 45 ) .AND. Substr(oGet:buffer,oGet:decPos()-1,1) == "0"
      //       oGet:buffer := Substr(oGet:buffer,1,oGet:decPos()-2)+"-"+Substr(oGet:buffer,oGet:decPos()-1)
      //       oGet:display()
   CASE ( nKey == K_UP )
      oGet:exitState := GE_UP

   CASE ( nKey == K_SH_TAB )
      oGet:exitState := GE_UP

   CASE ( nKey == K_DOWN )
      oGet:exitState := GE_DOWN

   CASE ( nKey == K_TAB )
      oGet:exitState := GE_DOWN

   CASE ( nKey == K_ENTER )
      oGet:changed := .T.
      oGet:exitState := GE_ENTER
      nKey2 := Space(0)

   CASE ( nKey == K_ESC )
      IF ( SET( _SET_ESCAPE ) )
         oGet:undo()
         oGet:exitState := GE_ESCAPE

      ENDIF

   CASE ( nKey == K_PGUP )
      oGet:exitState := GE_WRITE

   CASE ( nKey == K_PGDN )
      oGet:exitState := GE_WRITE

   CASE ( nKey == K_CTRL_HOME )
      oGet:exitState := GE_TOP

#ifdef CTRL_END_SPECIAL

      // Both ^W and ^End go to the last GET
   CASE ( nKey == K_CTRL_END )
      oGet:exitState := GE_BOTTOM

#else

      // Both ^W and ^End terminate the READ (the default)
   CASE ( nKey == K_CTRL_W )
      oGet:exitState := GE_WRITE

#endif

   CASE ( nKey == K_INS )
      SET( _SET_INSERT, !SET( _SET_INSERT ) )
      ShowScoreboard()

   CASE ( nKey == K_UNDO )
      oGet:undo()

   CASE ( nKey == K_HOME )
      oGet:home()

   CASE ( nKey == K_END )
      oGet:end()

   CASE ( nKey == K_RIGHT )
      oGet:right()
      nKey2 := Space(0)

   CASE ( nKey == K_LEFT )
      oGet:left()
      nKey2 := Space(0)

   CASE ( nKey == K_CTRL_RIGHT )
      oGet:wordRight()
      nKey2 := Space(0)

   CASE ( nKey == K_CTRL_LEFT )
      oGet:wordLeft()
      nKey2 := Space(0)

   CASE ( nKey == K_BS ) .OR. ((nKey == K_DEL) .AND. (oGet:type =="N"))
      IF ( oGet:type == "N" ) .AND. (oGet:pos < oGet:decPos )
         IF AT(".",oGet:buffer) <> 0 .OR. AT(",",oGet:buffer) <> 0
            oGet:pos    := oGet:decPos()-1
            nTemp := oGet:unTransform()
            nTemp := (nTemp-INT(nTemp)) + Int(nTemp / 10)
         ELSE
            oGet:pos    := oGet:decPos()-1
            oGet:delete()
            nTemp := oGet:unTransform()
         ENDIF
         oGet:buffer := Transform(nTemp,oGet:picture)
         oGet:pos    := oGet:decPos()-1
         oGet:display()
      ELSE
         IF (oGet:type="N").AND.(oGet:pos=oGet:decPos+1).AND.(nKey<>K_DEL)
            oGet:pos := oGet:decPos()-1
            KEYBOARD Chr( K_BS )
         ELSE
            IF ( nKey == K_DEL )
               oGet:delete()
            ELSE
               oGet:backSpace()
            ENDIF
            oGet:display()
         ENDIF
      ENDIF
   CASE ( nKey == K_DEL )
      oGet:delete()

   CASE ( nKey == K_CTRL_T )
      oGet:delWordRight()

   CASE ( nKey == K_CTRL_Y )
      IF oGet:type == "N"
         nTmp := oGet:pos
         oGet:pos    := 01
         oGet:delEnd()
         oGet:pos    := nTmp
         oGet:display()
      ELSE
         oGet:delEnd()
      ENDIF

   CASE ( nKey == K_CTRL_BS )
      oGet:delWordLeft()

   OTHERWISE
      lIns  := .T.

      IF ( nKey >= 32 .AND. nKey <= 255 )

         IF ! Empty(nKey2) .AND.  oGet:type == "C"
            lIns := Acentos(oGet, nKey2, @nKey)
            nKey2 := Space(0)
         ENDIF

         cKey := Chr( nKey )

         IF ( oGet:type == "N" .AND. ( cKey == "." .OR. cKey == "," ) )
            lTmp := AT("-",oGet:buffer) <> 0
            IF oGet:Clear
               oGet:buffer := Transform(0,oGet:picture)
            ENDIF
            oGet:toDecPos()
            IF lTmp .AND. AT("-",oGet:buffer) == 0
               oGet:buffer := Substr(oGet:buffer,1,oGet:decPos()-2)+"-"+Substr(oGet:buffer,oGet:decPos()-1)
               oGet:buffer := Substr(oGet:buffer,2)
            ENDIF
            oGet:display()
         ELSEIF ( oGet:type == "N" ) .AND. (oGet:pos < oGet:decPos ) .AND. ;
               ((nKey >= Asc('0') .AND. nKey <= Asc('9')) .OR. Upper(CHR(nKey))="C" ;
               .OR.  nKey == Asc('+')  .OR.  nKey == Asc('-'))
            nTemp := oGet:unTransform()
            IF Upper(cKey) == "C" .OR. oGet:clear
               oGet:clear := .F.
               nTemp = 0
               oGet:buffer := Transform(nTemp,oGet:picture)
               oGet:display()
            ENDIF
            lDec := AT(".",Transform(0,oGet:picture))
            IF(lDec==0,lDec := AT(",",Transform(0,oGet:picture)),lDec)
            lDec0 := IF(lDec<>0,IF(Len(oGet:buffer) > (lDec+1),.T.,.F.),.T.)
            lDec  := IF(lDec<>0,.T.,.F.)
            IF(oGet:picture==NIL,lDec0:=.T.,)

            IF Len((oGet:buffer)) >= (Len(AllTrim(oGet:buffer))+1)
               IF oGet:type == "N" .AND. cKey == "-"
                  nKey2 := Asc("-")
               ELSE
                  lTmp  := AT("-",oGet:buffer) <> 0
                  nTemp := (nTemp-INT(nTemp)) + Int(nTemp * 10)
                  oGet:buffer := Transform(nTemp,oGet:picture)
                  IF nTemp = 0 .AND. lTmp
                     IF Len(oGet:buffer) < oGet:decPos() .AND. 1 = 2
                        oGet:buffer := Substr(oGet:buffer,1,oGet:decPos()-3)+"-"+Substr(oGet:buffer,oGet:decPos()-2)
                        oGet:buffer := Substr(oGet:buffer,2)
                     ELSE
                        oGet:buffer := Substr(oGet:buffer,1,oGet:decPos()-IF(lDec0,2,3))+"-"+Substr(oGet:buffer,oGet:decPos()-IF(lDec0,1,2))
                        oGet:buffer := Substr(oGet:buffer,2)
                     ENDIF
                  ENDIF                                                                //2   1
                  oGet:pos   := oGet:decPos() -IF(oGet:picture<>NIL .AND. lDec, IF(lTmp .AND. Len(oGet:buffer) < oGet:decPos(),2,1),0)
                  oGet:overstrike( cKey )                                                    //2   1
                  oGet:pos   := oGet:decPos() -IF(oGet:picture<>NIL .AND. lDec, IF(lTmp .AND. Len(oGet:buffer) < oGet:decPos(),2,1),0)
               ENDIF
               IF VALTYPE(nKey2) == "N" .AND. cKey == "-"
                  lTmp  := AT("-",oGet:buffer) == 0
                  nTemp := oGet:unTransform()
                  nTemp *= (-1)
                  oGet:buffer := Transform(nTemp,oGet:picture)
                  IF nTemp = 0 .AND. lTmp
                     IF Len(oGet:buffer) < oGet:decPos() .AND. 1 = 2
                        oGet:buffer := Substr(oGet:buffer,1,oGet:decPos()-3)+"-"+Substr(oGet:buffer,oGet:decPos()-2)
                        oGet:buffer := Substr(oGet:buffer,2)
                     ELSE
                        oGet:buffer := Substr(oGet:buffer,1,oGet:decPos()-IF(lDec0,2,3))+"-"+Substr(oGet:buffer,oGet:decPos()-IF(lDec0,1,2))
                        oGet:buffer := Substr(oGet:buffer,2)
                     ENDIF
                  ENDIF
               ENDIF
               IF VALTYPE(nKey2) == "N"
                  nKey2 := Space(0)
               ENDIF
               oGet:display()
               IF Len(Substr(oGet:buffer,1,oGet:decpos-1))==LEN(AllTrim(Substr(oGet:buffer,1,oGet:decpos-1))) .AND. (!SET(_SET_CONFIRM))
                  oGet:exitstate:=GE_ENTER
               ENDIF
            ELSEIF Len(Substr(oGet:buffer,1,oGet:decpos-1)) == 1 .AND. (oGet:pos < oGet:decPos )
               oGet:overstrike(cKey)
               oGet:pos := oGet:decPos()
               oGet:display()
               IF Len(Substr(oGet:buffer,1,oGet:decpos-1))==1 .AND. (!SET(_SET_CONFIRM))
                  oGet:exitstate:=GE_ENTER
               ENDIF
            ELSE
               IF ( !SET( _SET_CONFIRM ) )
                  oGet:exitState := GE_ENTER
               ELSE
                  ?? Chr(7)
               ENDIF

            ENDIF
            IF oGet:type == "N" .AND. cKey == "-"
               nKey2 := nKey
            ENDIF
         ELSE

            IF ( SET( _SET_INSERT ) ) .AND. lIns
               oGet:insert( cKey )
            ELSE
               oGet:overstrike( cKey )
            ENDIF
            IF ( oGet:type == "C")
               IF Empty(nKey2) .AND. (nKey=126 .OR. nKey=39 .OR. nKey=96 .OR. nKey=34 .OR. nKey=94 .OR. nKey=46)
                  nKey2 := nKey
                  oGet:left()
               ELSE
                  nKey2 := Space(0)
               ENDIF
            ENDIF

            IF ( oGet:typeOut )
               IF ( SET( _SET_BELL ) )
                  ?? Chr(7)
               ENDIF

               IF ( !SET( _SET_CONFIRM ) )
                  oGet:exitState := GE_ENTER
               ENDIF
            ENDIF

         ENDIF

      ENDIF

   ENDCASE
   oGet:changed := .T.

   RETURN

   /***
   *  GetPreValidate()
   *  Test entry condition (WHEN clause) for a GET
   */

FUNCTION GetPreValidate( oGet )

   LOCAL lSavUpdated
   LOCAL lWhen := .T.

   IF !( oGet:preBlock == NIL )

      lSavUpdated := slUpdated

      lWhen := EVAL( oGet:preBlock, oGet )

      oGet:display()

      ShowScoreBoard()
      slUpdated := lSavUpdated

   ENDIF

   IF ( slKillRead )

      lWhen := .F.
      oGet:exitState := GE_ESCAPE      // Provokes ReadModal() exit

   ELSEIF ( !lWhen )

      oGet:exitState := GE_WHEN      // Indicates failure

   ELSE

      oGet:exitState := GE_NOEXIT      // Prepares for editing

   ENDIF

   RETURN ( lWhen )

   /***
   *  GetPostValidate()
   *  Test exit condition (VALID clause) for a GET
   *  NOTE: Bad dates are rejected in such a way as to preserve edit buffer
   */

FUNCTION GetPostValidate( oGet )

   LOCAL lSavUpdated
   LOCAL lValid := .T.

   IF ( oGet:exitState == GE_ESCAPE )
      RETURN ( .T. )             // NOTE
   ENDIF

   IF ( oGet:badDate() )
      oGet:home()
      DateMsg()
      ShowScoreboard()
      RETURN ( .F. )             // NOTE
   ENDIF

   // IF editing occurred, assign the new value to the variable
   IF ( oGet:changed )
      oGet:assign()
      slUpdated := .T.
   ENDIF

   // Reform edit buffer, set cursor to home position, redisplay
   oGet:reset()

   // Check VALID condition IF specified
   IF !( oGet:postBlock == NIL )

      lSavUpdated := slUpdated

      // S'87 compatibility
      SETPOS( oGet:row, oGet:col + Len( oGet:buffer ) )

      lValid := EVAL( oGet:postBlock, oGet )

      // Reset S'87 compatibility cursor position
      SETPOS( oGet:row, oGet:col )

      ShowScoreBoard()
      oGet:updateBuffer()

      slUpdated := lSavUpdated

      IF ( slKillRead )
         oGet:exitState := GE_ESCAPE     // Provokes ReadModal() exit
         lValid := .T.

      ENDIF
   ENDIF

   RETURN ( lValid )

   /***
   *  GetDoSetKey()
   *  Process SET KEY during editing
   */

PROCEDURE GetDoSetKey( keyBlock, oGet )

   LOCAL lSavUpdated

   // IF editing has occurred, assign variable
   IF ( oGet:changed )
      oGet:assign()
      slUpdated := .T.
   ENDIF

   lSavUpdated := slUpdated

   EVAL( keyBlock, scReadProcName, snReadProcLine, ReadVar() )

   ShowScoreboard()
   oGet:updateBuffer()

   slUpdated := lSavUpdated

   IF ( slKillRead )
      oGet:exitState := GE_ESCAPE       // provokes ReadModal() exit
   ENDIF

   RETURN

   /***
   *         READ services
   */

   /***
   *  Settle()
   *  Returns new position in array of GET objects, based on:
   *    - current position
   *    - exitState of GET object at current position
   *  NOTES: return value of 0 indicates termination of READ
   *      exitState of old GET is transferred to new Get
   */

STATIC FUNCTION Settle( GetList, nPos )

   LOCAL nExitState

   IF ( nPos == 0 )
      nExitState := GE_DOWN
   ELSE
      nExitState := GetList[ nPos ]:exitState
   ENDIF

   IF ( nExitState == GE_ESCAPE .OR. nExitState == GE_WRITE )
      RETURN ( 0 )            // NOTE
   ENDIF

   IF !( nExitState == GE_WHEN )
      // Reset state info
      snLastPos := nPos
      slBumpTop := .F.
      slBumpBot := .F.
   ELSE
      // Re-use last exitState, do not disturb state info
      nExitState := snLastExitState
   ENDIF

   // Move
   DO CASE
   CASE ( nExitState == GE_UP )
      nPos--

   CASE ( nExitState == GE_DOWN )
      nPos++

   CASE ( nExitState == GE_TOP )
      nPos     := 1
      slBumpTop  := .T.
      nExitState := GE_DOWN

   CASE ( nExitState == GE_BOTTOM )
      nPos     := Len( GetList )
      slBumpBot  := .T.
      nExitState := GE_UP

   CASE ( nExitState == GE_ENTER )
      nPos++

   ENDCASE

   // Bounce
   IF ( nPos == 0 )                 // Bumped top
      IF ( !ReadExit() .AND. !slBumpBot )
         slBumpTop   := .T.
         nPos      := snLastPos
         nExitState := GE_DOWN
      ENDIF

   ELSEIF ( nPos == Len( GetList ) + 1 )  // Bumped bottom
      IF ( !ReadExit() .AND. !( nExitState == GE_ENTER ) .AND. !slBumpTop )
         slBumpBot   := .T.
         nPos      := snLastPos
         nExitState := GE_UP
      ELSE
         nPos := 0
      ENDIF
   ENDIF

   // Record exit state
   snLastExitState := nExitState

   IF !( nPos == 0 )
      GetList[ nPos ]:exitState := nExitState
   ENDIF

   RETURN ( nPos )

   /***
   *  PostActiveGet()
   *  Post active GET for ReadVar(), GetActive()
   */

STATIC PROCEDURE PostActiveGet( oGet )

   GetActive( oGet )
   ReadVar( GetReadVar( oGet ) )

   ShowScoreBoard()

   RETURN

   /***
   *  ClearGetSysVars()
   *  Save and clear READ state variables. Return array of saved values
   *  NOTE: 'Updated' status is cleared but not saved (S'87 compatibility)
   */

STATIC FUNCTION ClearGetSysVars()

   LOCAL aSavSysVars[ GSV_COUNT ]

   // Save current sys vars
   aSavSysVars[ GSV_KILLREAD ]   := slKillRead
   aSavSysVars[ GSV_BUMPTOP ]      := slBumpTop
   aSavSysVars[ GSV_BUMPBOT ]      := slBumpBot
   aSavSysVars[ GSV_LASTEXIT ]   := snLastExitState
   aSavSysVars[ GSV_LASTPOS ]      := snLastPos
   aSavSysVars[ GSV_ACTIVEGET ]   := GetActive( NIL )
   aSavSysVars[ GSV_READVAR ]      := ReadVar( "" )
   aSavSysVars[ GSV_READPROCNAME ] := scReadProcName
   aSavSysVars[ GSV_READPROCLINE ] := snReadProcLine

   // Re-init old ones
   slKillRead       := .F.
   slBumpTop       := .F.
   slBumpBot       := .F.
   snLastExitState := 0
   snLastPos       := 0
   scReadProcName  := ""
   snReadProcLine  := 0
   slUpdated       := .F.

   RETURN ( aSavSysVars )

   /***
   *  RestoreGetSysVars()
   *  Restore READ state variables from array of saved values
   *  NOTE: 'Updated' status is not restored (S'87 compatibility)
   */

STATIC PROCEDURE RestoreGetSysVars( aSavSysVars )

   slKillRead       := aSavSysVars[ GSV_KILLREAD ]
   slBumpTop       := aSavSysVars[ GSV_BUMPTOP ]
   slBumpBot       := aSavSysVars[ GSV_BUMPBOT ]
   snLastExitState := aSavSysVars[ GSV_LASTEXIT ]
   snLastPos       := aSavSysVars[ GSV_LASTPOS ]

   GetActive( aSavSysVars[ GSV_ACTIVEGET ] )

   ReadVar( aSavSysVars[ GSV_READVAR ] )

   scReadProcName  := aSavSysVars[ GSV_READPROCNAME ]
   snReadProcLine  := aSavSysVars[ GSV_READPROCLINE ]

   RETURN

   /***
   *  GetReadVar()
   *  Set READVAR() value from a GET
   */

STATIC FUNCTION GetReadVar( oGet )

   LOCAL cName := Upper( oGet:name )
   LOCAL i

   // The following code includes subscripts in the name returned by
   // this FUNCTIONtion, IF the GET variable is an array element
   // Subscripts are retrieved from the oGet:subscript instance variable
   // NOTE: Incompatible with Summer 87
   IF !( oGet:subscript == NIL )
      FOR i := 1 TO Len( oGet:subscript )
         cName += "[" + LTRIM( Str( oGet:subscript[i] ) ) + "]"
      NEXT
   END

   RETURN ( cName )

   /***
   *         System Services
   */

   /***
   *  __SetFormat()
   *  SET FORMAT service
   */

PROCEDURE __SetFormat( b )

   sbFormat := IF( VALTYPE( b ) == "B", b, NIL )

   RETURN

   /***
   *  __KillRead()
   *  CLEAR GETS service
   */

PROCEDURE __KillRead()

   slKillRead := .T.

   RETURN

   /***
   *  GetActive()
   *  Retrieves currently active GET object
   */

FUNCTION GetActive( g )

   LOCAL oldActive := soActiveGet

   IF ( PCOUNT() > 0 )
      soActiveGet := g
   ENDIF

   RETURN ( oldActive )

   /***
   *  Updated()
   */

FUNCTION Updated()

   RETURN slUpdated

   /***
   *  ReadExit()
   */

FUNCTION ReadExit( lNew )

   RETURN ( SET( _SET_EXIT, lNew ) )

   /***
   *  ReadInsert()
   */

FUNCTION ReadInsert( lNew )

   RETURN ( SET( _SET_INSERT, lNew ) )

   /***
   *         Wacky Compatibility Services
   */

   // Display coordinates for SCOREBOARD
#define SCORE_ROW      0
#define SCORE_COL      60

   /***
   *  ShowScoreboard()
   */

STATIC PROCEDURE ShowScoreboard()

   LOCAL nRow
   LOCAL nCol

   IF ( SET( _SET_SCOREBOARD ) )
      nRow := Row()
      nCol := Col()

      SETPOS( SCORE_ROW, SCORE_COL )
      DISPOUT( IF( SET( _SET_INSERT ), NationMsg(_GET_INSERT_ON), ;
         NationMsg(_GET_INSERT_OFF)) )
      SETPOS( nRow, nCol )
   ENDIF

   RETURN

   /***
   *  DateMsg()
   */

STATIC PROCEDURE DateMsg()

   LOCAL nRow
   LOCAL nCol

   IF ( SET( _SET_SCOREBOARD ) )

      nRow := Row()
      nCol := Col()

      SETPOS( SCORE_ROW, SCORE_COL )
      DISPOUT( NationMsg(_GET_INVD_DATE) )
      SETPOS( nRow, nCol )

      WHILE ( NEXTKEY() == 0 )
      END

      SETPOS( SCORE_ROW, SCORE_COL )
      DISPOUT( Space( Len( NationMsg(_GET_INVD_DATE) ) ) )
      SETPOS( nRow, nCol )

   ENDIF

   RETURN

   /***
   *  RangeCheck()
   *  NOTE: Unused second param for 5.00 compatibility.
   */

FUNCTION RangeCheck( oGet, junk, lo, hi )

   LOCAL cMsg, nRow, nCol
   LOCAL xValue

   IF .F.
      ? Junk
   ENDIF

   IF ( !oGet:changed )
      RETURN ( .T. )      // NOTE
   ENDIF

   xValue := oGet:varGet()

   IF ( xValue >= lo .AND. xValue <= hi )
      RETURN ( .T. )      // NOTE
   ENDIF

   IF ( SET(_SET_SCOREBOARD) )

      cMsg := NationMsg(_GET_RANGE_FROM) + LTRIM( Transform( lo, "" ) ) + ;
         NationMsg(_GET_RANGE_TO) + LTRIM( Transform( hi, "" ) )

      IF ( Len( cMsg ) > MAXCOL() )
         cMsg := Substr( cMsg, 1, MAXCOL() )
      ENDIF

      nRow := Row()
      nCol := Col()

      SETPOS( SCORE_ROW, MIN( 60, MAXCOL() - Len( cMsg ) ) )
      DISPOUT( cMsg )
      SETPOS( nRow, nCol )

      WHILE ( NEXTKEY() == 0 )
      END

      SETPOS( SCORE_ROW, MIN( 60, MAXCOL() - Len( cMsg ) ) )
      DISPOUT( Space( Len( cMsg ) ) )
      SETPOS( nRow, nCol )

   ENDIF

   RETURN ( .F. )

   /***
   *  ReadKill()
   */

FUNCTION ReadKill( lKill )

   LOCAL lSavKill := slKillRead

   IF ( PCOUNT() > 0 )
      slKillRead := lKill
   ENDIF

   RETURN ( lSavKill )

   /***
   *  ReadUpdated()
   */

FUNCTION ReadUpdated( lUpdated )

   LOCAL lSavUpdated := slUpdated

   IF ( PCOUNT() > 0 )
      slUpdated := lUpdated
   ENDIF

   RETURN ( lSavUpdated )

   /***
   *  ReadFormat()
   */

FUNCTION ReadFormat( b )

   LOCAL bSavFormat := sbFormat

   IF ( PCOUNT() > 0 )
      sbFormat := b
   ENDIF

   RETURN ( bSavFormat )

FUNCTION Mensagem1(nLinh,cTexto,cCor)

   LOCAL nCol,nLargJan

   nLargJan := Len(cTexto)
   IF nLargJan < 10
      nLargJan := 10
   ENDIF
   nCol := (80 -nLargJan)/2
   @ nLinh,nCol CLEAR TO nLinh,nCol + nLargJan
   @ nLinh,nCol SAY cTexto COLOR cCor

   RETURN NIL

   // "Ž„ …†ƒ€‡‚ˆ‰Š¡‹Œ“¢™”•£š–¦§"

FUNCTION Acentos(oGet,nKey2,nKey)

   LOCAL lIns := .F., nKey3

   nKey2 := Chr(nKey2)
   nKey3 := nKey
   nKey  := Chr(nKey )
   IF nKey2 == "~"
      IF   nKey=="A" ; nKey:="Ž"
      ELSEIF nKey=="O" ; nKey:="™"
      ELSEIF nKey=="a" ; nKey:="„"
      ELSEIF nKey=="o" ; nKey:="”"
      ELSE  ; lIns := .T.
      ENDIF
   ELSEIF nKey2 == "'"
      IF   nKey=="A" ; nKey:=""
      ELSEIF nKey=="E" ; nKey:=""
      ELSEIF nKey=="a" ; nKey:=" "
      ELSEIF nKey=="e" ; nKey:="‚"
      ELSEIF nKey=="i" ; nKey:="¡"
      ELSEIF nKey=="o" ; nKey:="¢"
      ELSEIF nKey=="u" ; nKey:="£"
      ELSEIF nKey=="C" ; nKey:="€"
      ELSEIF nKey=="c" ; nKey:="‡"
      ELSE  ; lIns := .T.
      ENDIF
   ELSEIF nKey2 == "`"
      IF   nKey=="a" ; nKey:="…"
      ELSEIF nKey=="e" ; nKey:="Š"
      ELSEIF nKey=="i" ; nKey:=""
      ELSEIF nKey=="o" ; nKey:="•"
      ELSE  ; lIns := .T.
      ENDIF
   ELSEIF nKey2 == "^"
      IF   nKey=="a" ; nKey:="ƒ"
      ELSEIF nKey=="e" ; nKey:="ˆ"
      ELSEIF nKey=="i" ; nKey:="Œ"
      ELSEIF nKey=="o" ; nKey:="“"
      ELSEIF nKey=="u" ; nKey:="–"
      ELSE  ; lIns := .T.
      ENDIF
   ELSEIF nKey2 == "."
      IF   nKey=="a" ; nKey:="¦"
      ELSEIF nKey=="o" ; nKey:="§"
      ELSE  ; lIns := .T.
      ENDIF
   ENDIF
   nKey2 := Asc(nKey2)
   nKey  := Asc(nKey )
   IF nKey3 == nKey
      oGet:right()
   ENDIF

   RETURN lIns

FUNCTION _INKEY(nTempo,lTrava)

   LOCAL nKey, nTime := SECONDS()

   lTrava:=IF(lTrava==NIL,.F.,.T.)
   IF lTrava .AND. nTempo <> NIL .AND. nTempo <> 0
      WHILE IF (nTempo > 0, (SECONDS() - nTime) < nTempo, .T.)
      ENDDO
      nKey := LastKey()
   ELSE
      nKey :=  Inkey(0) // Minkey(nTempo, @nMRow, @nMCol, .T.)
   ENDIF

   RETURN (nKey)

FUNCTION AJUDADECAMPOATIVA( oGet )

   LOCAL nROW := Row(), nCOL := Col(), nCURSOR := SetCursor(), cCOR := SetColor()
   LOCAL GetMensg := GetMsg[PosMsg], nCALCULO, nPOSOGET
   LOCAL nPOS1 := AT("|",GetMensg), nPOS2, cVAR[3], nTAMAJU
   LOCAL nColAju1, nColAju2, nLinAju1, nLinAju2

   IF nPOS1 # 0
      cVAR[1] := Substr(GetMensg,1,nPOS1-1)
      GetMensg := Substr(GetMensg,nPOS1+1,Len(GetMensg))
   ELSE
      cVAR[1] := GetMensg
      GetMensg := Space(0)
   ENDIF
   nPOS2 := AT("|",GetMensg)
   IF nPOS2 # 0
      cVAR[2] := Substr(GetMensg,1,nPOS2-1)
      GetMensg := Substr(GetMensg,nPOS2+1,Len(GetMensg))
      cVAR[3] := GetMensg
   ELSEIF nPOS2 == 0 .AND. !Empty(GetMensg)
      cVAR[2] := GetMensg
   ENDIF
   IF cVAR[3] # NIL
      nCALCULO := 4
   ELSEIF cVAR[3] == NIL .AND. cVAR[2] # NIL
      nCALCULO := 3
   ELSE
      nCALCULO := 2
   ENDIF
   nTAMAJU := LenLargura( cVAR )
   nPOSOGET := oGet:col + 4
   IF nPOSOGET+4+nTAMAJU > 79
      DO WHILE .T.
         nPOSOGET--
         IF nPOSOGET+4+nTAMAJU <= 79
            EXIT
         ENDIF
      ENDDO
   ENDIF
   nCOLAJU1 := nPOSOGET
   nCOLAJU2 := nPOSOGET+nTAMAJU
   IF oGet:row+1+nCALCULO > 24
      nLINAJU1 := oGet:row-1-nCALCULO
      nLINAJU2 := oGet:row-1
   ELSE
      nLINAJU1 := oGet:row+1
      nLINAJU2 := oGet:row+1+nCALCULO
   ENDIF
   //cGetMsg := SaveScreen(nLINAJU1,nCOLAJU1-2,nLINAJU2+1,nCOLAJU2+3)
   @ nLINAJU1,nCOLAJU1 TO nLINAJU2,nCOLAJU2+3
   @ nLINAJU1+1,nCOLAJU1+1 SAY " "+PAD( cVAR[1], nTAMAJU)+" "
   IF cVAR[2] # NIL
      @ nLINAJU1+2,nCOLAJU1+1 SAY " "+PAD( cVAR[2], nTAMAJU)+" "
   ENDIF
   IF cVAR[3] # NIL
      @ nLINAJU1+3,nCOLAJU1+1 SAY " "+PAD( cVAR[3], nTAMAJU)+" "
   ENDIF
   SETPOS(nROW,nCOL)
   SetColor(cCOR)
   SetCursor(nCURSOR)

   RETURN NIL

STATIC FUNCTION LenLargura( aMenu2 )

   LOCAL nLargura, i

   nLargura := aMenu2[1]
   FOR i = 1 TO Len(aMenu2)
      IF aMenu2[i] # NIL
         IF Len(nLargura) < Len(aMenu2[i])
            nLargura := aMenu2[i]
         ENDIF
      ENDIF
   NEXT

   RETURN Len(nLargura)

FUNCTION _ROUND(nValor,nDecimals)

   Hb_Default( @nDecimals,2)

   RETURN (Round(Val(Str(nValor)),nDecimals))

FUNCTION GetPassword(oGet)

   LOCAL nKey
   LOCAL lRestaura := .F.
   PRIVATE nLINAJU1, nLINAJU2, nCOLAJU1, nCOLAJU2

   IF (GetPreValidate(oGet))

      // Activate the GET for reading
      oGet:setFocus()
      IF GetMsg[PosMsg] <> NIL
      ENDIF

      oGet:SetFocus()
      oGet:cargo := ""
      DO WHILE oGet:exitState == GE_NOEXIT
         IF (oGet:typeOut)
            oGet:exitState := GE_ENTER
         ENDIF
         DO WHILE oGet:exitState == GE_NOEXIT
            nKey := Inkey(0)
            IF nKey >= 32 .AND. nKey <= 255
               oGet:cargo += Chr(nKey)
               GetApplyKey(oGet,Asc("þ"))
            ELSEIF nKey == K_BS
               oGet:cargo := Substr(oGet:cargo,1,Len(oGet:cargo)-1)
               GetApplyKey(oGet,nKey)
            ELSEIF nKey == K_ENTER
               GetApplyKey(oGet,nKey)
            ELSEIF nKey == K_ESC
               GetApplyKey(oGet,nKey)
            ENDIF
         ENDDO
         IF (!GetPostValidate(oGet))
            oGet:exitState := GE_NOEXIT
         ENDIF
      ENDDO
      oGet:KillFocus()
      IF lRestaura
      ENDIF
   ENDIF
   IF oGet:exitState != GE_ESCAPE
      oGet:varPut(oGet:cargo)
   ENDIF

   RETURN NIL

Usando -e3 -es2

MensagemEnviado: 29 Mai 2019 13:11
por JoséQuintas
E lembram do git?
Pois é... fui salvando...
Agora dá pra ver o histórico de cada conjunto, inclusive o que foi mexido em cada conjunto.

getsys.png

Usando -e3 -es2

MensagemEnviado: 29 Mai 2019 13:18
por JoséQuintas
E tem outra: posso cancelar alguma das alterações. - revert commit
cancelar, cancelar o cancelamento....
E até isso fica registrado pelo git.

getsys.png


Aquilo de fazer backup, voltar backup se deu problema, pegar backup de dias atrás....
Tudo simplificado.
Como pelo git enxerga o que mexeu, pode até corrigir a alteração mal feita, ao invés de cancelar.
Mas pode cancelar também, sem precisar pegar backup - o próprio git já é um backup

Agora imagine tudo isso com bakcup nas nuvens....
aí é criar conta no bitbucket que é grátis pra uso pessoal, ou pagar no GitHub.

E o Harbour, ao baixar usando git, é assim também.
Temos toda história, com CADA alteração que é feita, desde os primeiros arquivos.
Anos e anos de trabalho, controlados pelo git, e com o backup centralizado nas nuvens, que é de onde baixamos tudo.

Então... coisas legais aqui:
- Compilar usando -w3 -es2
- Usar o GIT pra controlar versão
- usando o mesmo programa git, salvar nas nuvens, e ter um super-backup além do controle de versão

Usando -e3 -es2

MensagemEnviado: 29 Mai 2019 14:08
por JoséQuintas
Complemento:

Se temos controle das variáveis (-w3 -es2), de qualquer alteração (git), backup (git), podemos reverter (git), etc. etc. etc....

Poderíamos até melhorar todo fonte, afinal, tá tudo sob controle, não tem perigo de mexer.
No pior dos casos.... se estragar tudo... é acionar o git e pedir pra "reverter commit".

Entenderam?
É como ter funcionários/ajudantes conferindo o que fazemos.
Podemos fazer manutenção tranquilamente - e isto representa 90% de nossas tarefas.
Se 90% de nosso trabalho fica melhor e mais tranquilo.... NÓS também ficamos melhores e mais tranquilos !!!!

Essa getsys:
Como o Rubens disse, foram anos e anos juntando pedaços e ajustando recursos.
Eu fiz melhor que ele? NÃO. Foi o Harbour que mostrou aonde ajustar.
Uma compilação -w3 -es2 resolveu anos de pipino.

Outra coisa que comento aqui:
dá uma geral nos fontes antes de quebrar a cabeça com LIB gráfica
Isso teria resolvido um problema que o Rubens teve no passado com LIB gráfica, teria reduzido o tempo perdido.
Então... revisar fontes NÃO é perder tempo, é ganhar tempo.
Na correria do dia a dia, a gente não percebe isso....

Fonte do Rubens dando problema...
Eu apenas compilei usando -w3 -es2, mais nada.
Nem sequer tentei entender o fonte, não analisei, não melhorei, não conferi, nada.
O Harbour mostrou aonde ajustar, e eu ajustei.

Fiz o que qualquer um poderia fazer: olhar o que o Harbour estava reclamando, e resolver pra ele não reclamar.
A única diferença é que comecei a fazer isso há mais tempo, então estou "mais craque".

Usando -e3 -es2

MensagemEnviado: 02 Jun 2019 21:41
por JoséQuintas
Faltou chamar a atenção numa coisa muito importante:

Parece que em console, essa getsys nunca causou problema, só apareceu ao misturar HMG com GTWVG.

Em GUI, e em multithread, não há ordem de execução de rotinas como em console, o usuário pode fazer a ordem que quiser, clicando em qualquer lugar.
Com muitas rotinas sendo executadas a qualquer momento, a chance de problemas com variáveis "fora de controle" aumenta.
Isso pode explicar muitos problemas que alguns tem ao testar libs gráficas.

NÃO precisa parar de usar variável PUBLIC e PRIVATE, mas elas precisam de muito mais atenção, pra não ficarem "fora de controle".

Usando -e3 -es2

MensagemEnviado: 11 Jun 2019 23:51
por JoséQuintas
Acabei de pegar um erro no meu aplicativo.
Ainda uso variável PRIVATE em relatórios.... com isso, o -w3 -es2 não avisa tudo.

w3es2.png


Error BASE/1068 Argument error: array access
Called from LJPFORPAG(39)
Called from DO(0)
Called from DOPRG(116)
Called from (b)RUNMODULE(85)


Usando variável local, e compilando com -w3 -es2, teriam aparecido dois erros - que são um só

mostraria essa linha 24 como inútil, porque a 25 anula o conteúdo
e... mostraria que a variável nOpcTipo não foi inicializada

É um erro só, porque errei no nome da variável nessa linha 24.

Ainda não encontrei uma forma melhor de refazer o fonte dos relatórios.....

Isso se refere às diversas opções do relatório, que além de ter o menu de seleção, ainda pode aparecer no título do relatório, por isso variável PRIVATE.

relatorio.png

Usando -e3 -es2

MensagemEnviado: 12 Jun 2019 00:05
por JoséQuintas
debug.png


Aproveitando pra mostrar três coisas:

1. O debug do Harbour, igual do Clipper, pra acompanhar o fonte em questão, do relatório
Dá pra ver até o ícone do aplicativo na janela de debug

2. Multithread
Estou fazendo debug no relatório...
Como é multithread, o debug "parou" o relatório, e não o menu, que pode até chamar outros módulos, porque somente uma thread está sendo controlada pelo debug, e não o aplicativo inteiro.
Acaba tendo um efeito parecido com GUI e multijanelas, cada janela é totalmente independente.

3. Acaba parecendo um ambiente com IDE, no lado esquerdo é o programmers notepad.
Acho que nenhuma IDE do Harbour deixa alterar durante a execução, só mesmo a do VB6 fazia isso, então... fica igual IDE.

Nota: o que me refiro a alterar durante a execução, é alterar e continuar a execução, sem interromper ou recompilar. É que a IDE do VB6 interpreta linha a linha, então, se alterar a linha já continua executando a linha alterada.