Menu

CBL_ACCEPT_NUMERIC ==> calculator style accept of any numeric (except float or edited) field

2023-10-28
2024-03-22
1 2 3 4 > >> (Page 1 of 4)
  • Chuck Haatvedt

    Chuck Haatvedt - 2023-10-28

    I have created a CBL_ACCEPT_NUMERIC function which can be used to accept BINARY / COMP or PACKED DECIMAL / COMP-3 /COMP-6 or DISPLAY-NUMERIC field. This function will only function if the program is already in extended display mode.

    Please, if this routine is useful to you, respond here with any feedback. It may be possible to implement this into the upcoming 3.3 release if the feedback indicates you would like to see it implemented as a CBL routine in the compiler. Simon will make the decision. Since the timeframe for Release 3.3 is pretty short, if you would like to see this implemented, respond here..

    Consider this as a "alpha" release with the intent to gauge its usefulness to the community of GNUCOBOL programmers. The Delete key is used to emulate the CE (clear entry) button on a calculator. The Enter key is used to accept the value.

    compile command on Windows...
    cobc -x binsize.cbl accept_numeric.c -lpdcurses

    compile command on Linux
    cobc -x binsize.cbl accept_numeric.c -A '-DUSENC -DFLSH' -lncurses

    Note on Linux the beep is usually not available so we flash the screen instead to indicate an error. You could leave off the -DFLSH if the beep is audible on your Linux environment.

    I will attach 2 program files and 2 links to the demo videos on my Dropbox, the 2 MP4 files are short videos showing the execution of the sample program on Windows and Linux

    binsize.cbl is a short test program which calls the CBL_ACCEPT_NUMERIC function. It passes a numeric field followed by the line and column where the accept field will be positioned on the screen. The attributes of the numeric field are obtained from the LIBCOB-4.DLL runtime.

    accept_numeric.c is the source code for the new CBL_ACCEPT_NUMERIC function.

    link to Linux demo of binsize execution
    https://www.dropbox.com/scl/fi/3jhvlir5enkp0p0vwepso/cob_accept_numeric_linux.mp4?rlkey=tpge8jj7rx85u3j83d6rdxpb9&dl=0

    link to Windows demo of binsize execution
    https://www.dropbox.com/scl/fi/9uia36efm4oxohrng8f9p/cob_accept_numeric_windows.mp4?rlkey=ji8qgy0o5iibq5qc8ho8bhktm&dl=0

    Chuck Haatvedt

     

    Last edit: Chuck Haatvedt 2023-10-28
  • Simon Sobisch

    Simon Sobisch - 2023-10-28

    That's quite nice. For others watching the video - they may wonder how the actual definitions look like - I'd suggest to provide those in the output for the accept, for each one, something like
    DISPLAY 'ENTER BINARY VALUE USAGE BINARY-CHAR SIGNED' before accepting the numeric in the free space via the CBL routine.

    I find it important to provide a way to also "edit" values:
    * pre-fill the data showing the current value not showing leading zero or trailing zero after the decimal point) and position at its end, possibly depending on a flag (that's for mimic ACCEPT .. WITH [NO] UPDATE
    * make it calculator-mode editable (I guess something like: backspace removes one digit to the left, delete removes the content [no positioning or "overwrite"])

    For the samples: please add the edge-case "v99" (only after the decimal point) and the case of an alphanumeric field XXXX, which will be handled as 9999).
    For the edge-case: it likely is a good idea to use FUNCTION NUMVAL for numeric DISPLAY and alphanumeric/numeric-edited fields and the "update" mode (so " 2 " in a 9(06) or X(06) would display as 2).

     
  • Chuck Haatvedt

    Chuck Haatvedt - 2023-10-28

    Simon, you are correct about editing the value as it is entered. This would involve a hybrid functionality, calculator code until an editing key is pressed then allow positional editing.

    Certainly there are a number of "edge case" conditions that are missing from my very primitive sample program.

    I was in a rush to get this out to the community to allow people to test it so that we could incorporate possible improvements / bug fixes in time for it to be included in the upcoming Release 3.3

    Also this CBL function could be modified in later contributions if we added it in the contribution area as source code. So there are a number of things to consider...

    functionality pure calculator mode vs hybrid calculator mode with editing capability
    implementation first release as source code in contribution area
    second incorporate as a CBL function in the compiler
    third modify the ACCEPT verb in COBOL to allow for numeric field input

    For initial release, I personally like the first implementation option for initial release and then progress to the second. It would allow for somewhat easier initial releases in the contribution area without any changes to the compiler. After it has had an opportunity to be more widely tested and proven, then it could be incorporated as a CBL function in the compiler itself quite easily.

    I'm curious as to the feedback from people as they test this in their environments.

    Chuck Haatvedt

     
  • Chuck Haatvedt

    Chuck Haatvedt - 2023-10-30

    This is a work in progress and will probably involve a multiple step process. The first step is like an alpha release which implements various suggestions based on feedback. This will be done as a callable CBL function in a stand alone source code file. I am working on adding a simple update and backspace to delete the right most character in the field. At some point I am considering to add a hybrid editing functionality where the use of the HOME, END, LEFT-ARROW, RIGHT-ARROW, INSERT keys would switch to a more traditional editing mode. There is still some analysis of this idea as to how to switch between editing modes.

    The second step would be to take the CBL function and integrate with the GNUCOBOL compiler as a new CBL function.

    The third and most difficult phase would be to integrate this into the COBOL ACCEPT statement syntax. I would need to check with Simon to see how that may be done if it is even possible.

    For now the first phase is pretty straight forward in that it does not involve any changes to the compiler. The second phase would be a minor change to the compiler.

    I will probably add this to the contribution area instead of the discussion area so that it exists at a fixed location.

           Have fun, and please provide feedback.
    
      Chuck Haatvedt
    
     
    • Eugenio Di Lorenzo

      Hi Chuck,
      First of all I would like to congratulate you on the work already done.
      I did some tests with the attached program.
      I bring you some of my first considerations.

      1. Display of the field on the screen. The field should be visible in its size to the user, for example using reverse or with a "prompt character" such as the underscore. At the programmer's choice. It could be a parameter of the CALL CBL_ACCEPT_NUMERIC (just as it is a parameter of the ACCEPT: ... PROMPT CHARACTER IS '_'

      2. First view of the field. At the beginning it is good that at least one zero is always displayed to the user. Or at least let it be a parameter of the CBL_ACCEPT_NUMERIC CALL.
        If the field allows decimals then 0.0 should be displayed (or 0.0 if DECIMAL-POINT IS COMMA is active). When the user types the period . (or the comma if DECIMAL-POINT IS COMMA is active) then the program moves the cursor to the decimal part.

      3. Cursor. Now the cursor is not displayed (on my PC). It is best that it is displayed in the position where the digit you are going to type will appear. Therefore if you type the entire part of digits, the cursor must remain stationary in the rightmost position of the field. If you type the decimal part, then the cursor must move one position to the right each time you type a digit.
        This could also be driven by a parameter of the CALL CBL_ACCEPT_NUMERIC (do you want to see the cursor or not?)

      4. Minus sign. if you type the minus sign - it now appears correctly on the screen. If you type the - sign again a second time then the minus sign should disappear from the screen.

      5. Position of the minus sign The minus sign should be able to appear to the left of the number. In a floating position. Could a parameter of the CALL CBL_ACCEPT_NUMERIC be driven (minus sign to the right or to the left?)

      6. If DECIMAL-POINT IS COMMA is active in the calling program, then when entering decimals the program must accept the comma, and not the point. Could it be a parameter of the CBL_ACCEPT_NUMERIC CALL: Activate DECIMAL-POINT IS COMMA?

      7. The BACKSPACE should delete the last digit entered.

      8. If you type ESC you must exit ACCEPT_NUMERIC

       
      • Chuck Haatvedt

        Chuck Haatvedt - 2023-11-03

        Eugenio,

        Currently the allowable input characters must match the allowable characters in the receiving field. For example the PIC SV99 COMP-3. Would require the first position to be a decimal point followed by 2 numeric digits. The sign is always formatted as separate trailing. Also the sign is ONLY allowed if the receiving field is signed. The only valid values for the sign are "-" and "+" if no sign is entered then the receiving field will have a positive value. So unless there is a strong consensus then I would be inclined to leave that behavior as it is.

        I''m working on the following.

        • implement BACKSPACE to remove the right most character
        • implement ESC to exit without changing the receiving field. I'm inclined to reset the display of the input to blanks when doing this.
        • implement an "update" function where it displays the value in the receiving field when starting the input. this would require using the backspace key to delete characters before adding them to the right side position.
        • implementing to show a fixed position cursor at the position of the right most digit to be entered.

        I've had some discussions about adding a hybrid editing mode where the initial mode would be calculator mode of entering characters from the right.

        if a HOME, END, LEFT or RIGHT ARROW was entered then align the field and switch to allow a more conventional data entry mode allowing the cursor to move horizontally with the bounds of the field. This would require some thought as to how this would be implemented, but it may be a possibility after the above changes are completed.

        I will review the feedback and use that to help determine the future direction.

          Chuck Haatvedt
        
         
        • Chuck Haatvedt

          Chuck Haatvedt - 2023-11-06

          Hello,

          I have another update to the programs. I've implemented the above mentioned changes. I did keep the sign as trailing rather than a leading, floating sign as it is simpler and also that makes the logic to move to any other numeric format much simpler.

          One issue that remains is when leading zeros are entered, I tried to convert leading zeros before a decimal point to spaces but i have a slight bug to work out as they are not converted until the leading zero reaches the left most position of the input field.

          My original intent was to keep this function as simple as I could. However that has become more of a challenge as new functionality is added. This is the reason for keeping the sign as trailing in a fixed location, as it greatly simplifies the code.

          So while this code appears to be functional at least in my limited testing, the code does need to be cleaned up and documented such that a person looking at the code could understand what it is doing. So still a work in progress...

          cursor implemented
          backspace implemented
          update implemented (this requires an additional parm on the CALL)
          removal of leading zeros / partially implemented

          have fun and keep the feedback coming.

          Chuck Haatvedt
          
           
          • Eugenio Di Lorenzo

            I'm trying to test the new version , it compiles ok with:

            cobc -x binsize.cob accept_numeric.c -lpdcures

            but when executing binsize I get the screenshot error message

             
            • Simon Sobisch

              Simon Sobisch - 2023-11-06

              you also need the new binsize - which has 4 parameters

               
            • Chuck Haatvedt

              Chuck Haatvedt - 2023-11-06

              As Simon indicated, you need the new version of BINSIZE.CBL, it appears that you were using BINSIZE.COB.

              Let me know if you still encounter an error when using the BINSIZE.CBL from above
              which I included.

               
              • Chuck Haatvedt

                Chuck Haatvedt - 2023-11-07

                Here is modified version of accept_numeric.c with changes to allow only a single leading "0" until another character is entered, then the leading zero will be removed if the next character is a valid numeric digit.

                Other than the hybrid editing behavior, this should be pretty close to being ready for use.

                      Chuck Haatvedt
                
                 

                Last edit: Chuck Haatvedt 2023-11-07
              • Eugenio Di Lorenzo

                ok thx. solved.

                 
  • Simon Sobisch

    Simon Sobisch - 2023-10-30

    moved to contribution area

     
  • Eugenio Di Lorenzo

    I would say that the implemented solution is already at an excellent level !
    I would like to point out that when managing a field with decimal digits, the cursor is positioned on the decimal part of the last digit on the right.
    This way you can't type anything. the present digits (zeros) must be deleted before.
    instead it should be placed on the first digit of the integers.
    see the following example.

    Example

    ...

    01 MYNUM PIC S9(5)V(9(3) value zero.
    ...
    DISPLAY "Type a number : " AT xxxxx
    ACCEPT MYNUM AT xxxxxxxxx
    ...
    

    The system displays on the screen

    Type a number : _______0.0__

    The field on the screen has 6 characters to the left of the dot (5 digits plus the sign) and three to the right of the dot.
    The cursor is positioned on the zero to the left of the point.

    The user types 5 and the system displays

    Type a number : _____5.0__

    The user types 7 and the system displays

    Type a number: ____57.0__

    The user types 4 and the system displays

    Type a number: ___574.0__

    The user types a dot and the system displays

    Type a number: ___574.0__

    Where the cursor is positioned on the zero to the right of the point.

    The user types 3 and the system displays

    Type a number: ___574.3__

    The user types 8 and the system displays

    Type a number: ___574.38_

    The user types - and the system displays

    Type a number : __-574.38_

    The user types "Enter" and the ACCEPT is executed...

     
  • Chuck Haatvedt

    Chuck Haatvedt - 2023-11-07

    Hello Eugenio,

    The design was modeled after the Windows Calculator where all input is from the right most position. I think that it does that pretty well.

    I need to add some logic to only accept numeric display, packed decimal and binary fields. So floating point, edited numeric and alphanumeric would cause an error condition and control would immediately be returned to the caller.

    I'm thinking of adding this to the compiler as a new CBL routine after the code has been tested by more users. My ability to test the code in Linux environments is very limited, so I'm hoping to hear from more people who have tested this in Linux.

        Chuck Haatvedt
    
     
    • Eugenio Di Lorenzo

      Sorry but there's something I don't understand.
      please try running the following program.
      it displays what you see in the screenshot.
      Here the user should type his number but he cannot type anything, the program does not accept anything.
      The user must clear everything (zeroes) to be able to type a number.
      I don't think it's acceptable.
      where am I wrong?

             >>SOURCE FREE
      IDENTIFICATION DIVISION.
      PROGRAM-ID. ACCNUM.
      
      DATA DIVISION.
      WORKING-STORAGE SECTION.
      78 CBL_ACCEPT VALUE 'CBL_ACCEPT_NUMERIC'.
      01 ANSWR      PIC X    VALUE 'Y'.
      01 LN-1       PIC 9(4) VALUE  0.
      01 PKD-1      PIC S9(04)V999 COMP-3 value 0.
      01 NUMD       PIC -----.999 VALUE ZERO.
      
      PROCEDURE DIVISION.
        ADD 4 TO LN-1.
        DISPLAY 'ENTER PIC S9(4)V999 COMP-3 ............:' AT LINE LN-1 COL 2.
        CALL CBL_ACCEPT USING BY REFERENCE PKD-1 BY VALUE LN-1 BY VALUE 42 BY REFERENCE ANSWR.
        ADD 1 TO LN-1.
        move PKD-1 TO NUMD.
        DISPLAY NUMD LINE LN-1 COL 2.
        GOBACK.
      
       
      • Eugenio Di Lorenzo

        I would like to add a couple of considerations.

        when you need to accept a field from the screen, this field should always be zoned alphanumeric or zoned (display) numeric.
        I don't think it is necessary to manage the screen ACCEPT of a COMP or COMP-3 or BINARY etc etc field.
        Just an ACCEPT of a numeric field in "display" format is enough.
        Any complexities related to accepting a COMP-3 or COMP-5 etc field could be avoided.
        I don't know if microfocus or acucobol cobol compilers manage the accept of COMP-3 or COMP-5 fields etc directly for example in the screen section.

        From a functional point of view I believe that it would be appropriate to adopt the same ACCEPT behavior of a numeric field as the other microfocus compilers, acucobol rm/cobol etc and not that of the Windows calculator.

         

        Last edit: Eugenio Di Lorenzo 2023-11-07
        • Chuck Haatvedt

          Chuck Haatvedt - 2023-11-07

          Eugenio,

          the complexity of handling COMP-3 or COMP-6 is trivial, it's just a simple function call to convert to numeric display with sign trailing... so that is not worth removing.

          the COMP / COMP-4 / COMP-5 / BINARY field are also using the same technique so again trivial...

          The only challenge for the binary fields is getting the maximum digits and values when -fnotrunc compiler option is used or for BINARY fields. Again this is already done so there is no reason to remove it. Also this was specifically asked for.

          Initally I undertook this task with the idea to keep it as simple and minimal to accomplish the objective of providing a "calculator like" method to input a numeric field.

          My intent was not to emulate the behavior of other COBOL compilers as I don't have access to any of them. My only experience has been on ENTERPRISE COBOL on an IBM mainframe which in my professional career I never used the ACCEPT verb.

          That is not to imply that emulating the behavior of othe COBOL compilers would not be a worthwhile effort. Perhaps the code I created could be used as a starting point to do that. I'm guessing that this may not be standardized across all of the COBOL compilers so the effort may be significant. Also since this is a contribution and not part of the GNUCOBOL compiler itself, it would need to be incorporated into the compiler. If that was the goal to emulate the other compilers, that is a much larger task. I've looked briefly at the SCREENIO.C code which is part of LIBCOB, it is very complicated. I thought about doing this in LIBCOB, but the effort would be significant and something beyond my current level of C knowledge and more importantly my knowledge of the COBC and LIBCOB architectures. Also I know that there is a desire to move on from version 3.x to migrate to version 4 which involves a lot of work for Simon. So I wanted to keep this out of the compiler itself and go the route of implementing this as an external contribution / function. With this route, I can do most of the work myself without have to use to much of Simon's time. As it is, Simon has been very generous with his time to help me.

          Respectfully,
          Chuck Haatvedt

          if there is a desire to emulate the other COBOL compilers, perhaps that is worthy of a separate discussion.

           
  • Vincent (Bryan) Coen

    I have just tried to run this routine but it fails with :
    [vince@applewood testing-1]$ oe
    libcob: slcdsmnt.cbl:762: error: module 'CBL_ACCEPT_NUMERIC' not found

    Using a script to do all this ---
    In my system being tested oe is an executable compiled as cobc -x oe ...
    This program is a menu element that in turns calls all processes as modules compiled as cobc -m

    I complied the module under test as :

    cobc -m slcdsmnt.cbl -Wlinkage -d -g -ftraceall -fdump=ALL accept_numeric.c -A '-DUSENC -DFLSH' -lncurses

    All the other modules compiled as :
    cobc -m $i -Wlinkage -d -g -ftraceall -fdump=ALL -T $i

    program oe is compiled as :

    cobc -x oe.cbl -T oe.prn -Wlinkage -d -g -ftraceall

    I am guessing that it could be possibly 3reasons for this failure

    1. Need to build oe with the routine and not the module OR
    2. oe and compiler code cannot find it as the name within the C code does not have an External flag set .
    3. Source file name not the same as the entry point in the C code.

    Sorry it has beeen many years since I programmed in C - and I do mean many :(

     
    • Simon Sobisch

      Simon Sobisch - 2023-11-07

      to make that work you can do one of the following:
      * either change that single compile to cobc -m slcdsmnt.cbl -Wlinkage -d -g -ftraceall -fdump=ALL accept_numeric.c -A '-DUSENC -DFLSH' -lncurses -k CBL_ACCEPT_NUMERIC
      * change the code to use CALL STATIC 'CBL_ACCEPT_NUMERIC (which is the same, but in the code)
      * leave all link-time "unused" entry points in by using -Q '-Wl,no-as-needed'
      * generate the test prog separately cobc -m -g accept_numeric.c -A '-DUSENC -DFLSH' -lncurses and use COB_PRE_LOAD=accept_numeric oe to run

       
    • Chuck Haatvedt

      Chuck Haatvedt - 2023-11-07

      Vince,

      Sorry about the issues your are encountering, hopefully Simon's suggestions below will at least allow you to do some testing.

      If all goes well, our next step is to incorporate this directly in the GNUCOBOL compiler as that should make it much easier to use.

            Chuck Haatvedt
      
       
  • Vincent (Bryan) Coen

    I have linked it to the oe executable and it is now found BUT found other issues :

    1. Using input field as pic 99.99. does not work but changing to 99v99 does but in both case where field is set to zeros I have to use DEL key to clear content before entering data (2.25) I forgot if I tried to use DEL key first with 99.99 field so need to retry it ...... No have to use DEL key first as well so both 99.99 and 99v99 works but need to clear content first with DEL key.
    2. I thought the 4th param was for field Update mode, if not what is needed.
    3. Again as on 2., If in update mode they field should be displayed forst beore accepting data - ?
    4. and again using 99v99 comp-3 also need to do the same i.e., use DEL first

    Thats it so far.

    .

     
    • Chuck Haatvedt

      Chuck Haatvedt - 2023-11-07

      Hello Vince,

      you are correct in that the function does NOT work with edited fields so PIC 99.99. will not work.

      the fourth parameter is checked for a value of 'Y' or 'y' to detemine if in update mode.

      if the field has a value of 0.00 with 2 allowable positions to the right of the decimal point in update mode it would require the DEL key to erase the entire field or the BACKSPACE to remove the right most characters one at a time....

      for example if the value displayed is 0.00 and you wanted to change to 0.01 you could use the BACKSPACE key to remove the right most character and then enter a "1" followed by the ENTER key to accomplish this.

      another option would be to set the update variable (4th parm) to be a value other than Y or y. This would cause the field to be displayed as blank.

      ===============>> another thing I'm working on is to export the function name as "ACCEPT_NUMERIC" so that it could be compiled and used as a shared object without needing a COB_PRE_LOAD environment variable.

      in your cobol program you would just do a CALL "ACCEPT_NUMERIC" USING ....

      so that would make implementation easier.

      i'll post here when I have these changes made and tested in my environments.

      Thanks for your feedback, hopefully the above changes will make the process of using this better...

            Chuck Haatvedt
      
       
      • Vincent (Bryan) Coen

        Looks like the routine is no good for Update mode but OK for create /
        enter etc.

        I will have to have a think about it all but as it is now 01:00 I think
        time for  a bit of TV to wind down.

        Oh, the changed script for building it in the module that calls it fails
        as not found so did the same by doing it in the main executable (cobc
        -x) which does find it.

        On 07/11/2023 21:18, Chuck H. wrote:

        Hello Vince,

        you are correct in that the function does NOT work with edited fields
        so PIC 99.99. will not work.

        the fourth parameter is checked for a value of 'Y' or 'y' to detemine
        if in update mode.

        if the field has a value of 0.00 with 2 allowable positions to the
        right of the decimal point in update mode it would require the DEL key
        to erase the entire field or the BACKSPACE to remove the right most
        characters one at a time....

        for example if the value displayed is 0.00 and you wanted to change to
        0.01 you could use the BACKSPACE key to remove the right most
        character and then enter a "1" followed by the ENTER key to accomplish
        this.

        another option would be to set the update variable (4th parm) to be a
        value other than Y or y. This would cause the field to be displayed as
        blank.

        ===============>> another thing I'm working on is to export the
        function name as "ACCEPT_NUMERIC" so that it could be compiled and
        used as a shared object without needing a COB_PRE_LOAD environment
        variable.

        in your cobol program you would just do a CALL "ACCEPT_NUMERIC" USING ....

        so that would make implementation easier.

        i'll post here when I have these changes made and tested in my
        environments.

         
        • Chuck Haatvedt

          Chuck Haatvedt - 2023-11-08

          Vince,

          I think that you are correct in that for an update, the calculator mode of input is not very useful. I have been thinking of using more of the classical editing mode when doing an update. So that may come in the not too distant future. I have used this type of editing in another program I've worked on without the numeric check so it would not be inventing something from scratch.

          One of the challenges I've encountered is that some terminals, think Windows vs Linux, return different values for the same key stroke. Another aspect of this I've been thinking about is how to implement the classical edit functionality. Should I try to use switches and have both sets of logic in the same internal function or should I create a separate internal function and use the update indicator variable to determine which one gets executed.

          Logically it may make more sense to have separate functions in that some keys would have different actions depending on whether in calculator mode or the classical edit mode. For a field with a decimal point, the insert / overwrite logic would be different based on whether to the left or right of the decimal point. Also the decimal point would be non-modifiable. So there are some unique considerations for editing numeric data with a decimal point.

          I would appreciate people's ideas on how the classical edit functionality should be implemented when a field has a decimal point. I've also been considering whether it should be possible to switch from calculator mode to the classical mode which entering a new value. If so what would trigger that switch, perhaps using an ARROW KEY / HOME / END / INSERT would cause the behavior to switch. For myself personally I think that this would be desirable. However most of my career has been dealing with performance not user interfaces, so I'm a bit out of my comfort zone.

          Now that I have the calculator mode working fairly well, I'll probably wait a few days before studying how to implement the classical edit mode. Also I need to clean up the code to make it production ready before any attempt at adding the classical edit mode functionality.

          Chuck Haatvedt

           
1 2 3 4 > >> (Page 1 of 4)

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.