IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

How to check a PLI variable is numeric or not


IBM Mainframe Forums -> PL/I & Assembler
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
ponnu116
Warnings : 1

New User


Joined: 12 Sep 2007
Posts: 21
Location: chennai

PostPosted: Thu Apr 17, 2008 12:00 pm
Reply with quote

We are facing a data exception error in a PL/1 program, when a non numeric value is being checked for zeros in an IF statement. We are facing this issue when the program is compiled in Enterprise PL/i and not in earlier compilers. It will be greatful, if someone can help me with how to resolve this issue and let us know how to check a variable's type in PLI so that we can check whether it is numeric or not before the IF Condition.
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Thu Apr 17, 2008 4:45 pm
Reply with quote

What is the format of the numeric field? Display-Numeric or Packed-Decimal?

Regards,

Bill
Back to top
View user's profile Send private message
ponnu116
Warnings : 1

New User


Joined: 12 Sep 2007
Posts: 21
Location: chennai

PostPosted: Thu Apr 17, 2008 4:59 pm
Reply with quote

it is a packed decimal.can we verify whether it is numeric or not
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Fri Apr 18, 2008 8:49 pm
Reply with quote

My PL/I is rather rusty (haven't touched it over 20 years) and the only one I remember is for Display Numeric, using the IF VERIFY.

Perhaps someone else has the answer?

Regards,

Bill
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Sat Apr 19, 2008 10:19 pm
Reply with quote

OK, I found this page below, whose contents (perhaps) looks like what you need icon_cool.gif

www.users.bigpond.com/robin_v/validate.htm

Regards,

Bill
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Tue Apr 22, 2008 10:50 pm
Reply with quote

Below is an Assembler sub-program which can be called from PL/I to validate decimal-data. It uses the "TEST PACK" instruction, which is a somewhat fairly new instruction. However, you need to contact your System's folks and verify that you have "THE EXTENDED-TRANSLATION FACILITY 2" installed. Example syntax (from COBOL) is given in the source, so you'll just have to access it via the proper PL/I syntax.

Code:

***********************************************************************   
*---------------------------------------------------------------------*   
*                                                                     *   
*        THE EXTENDED-TRANSLATION FACILITY 2 MUST BE INSTALLED IN     *   
*        ORDER FOR THE 'TP' (TEST PACK) INSTRUCTION TO WORK.          *   
*                                                                     *   
*        EXAMPLE 'CALL' FROM COBOL:                                   *   
*                                                                     *   
*        03  WS-PARM-LGTH          PIC  9(04)      BINARY.            *   
*        03  WS-PARM-DATA          PIC  X(16).                        *   
*        03  WS-TESTPKD            PIC  X(08)      VALUE 'TESTPKD'.   *   
*        03  WS-DECIMAL-X          PIC  X(05).                        *   
*                                                                     *   
*        MOVE X'123456789C'            TO WS-DECIMAL-X.               *   
*        MOVE WS-DECIMAL-X             TO WS-PARM-DATA.               *   
*        MOVE LENGTH OF WS-DECIMAL-X   TO WS-PARM-LGTH.               *   
*                                                                     *   
*        CALL WS-TESTPKD               USING WS-PARM-LGTH,            *   
*                                            WS-PARM-DATA.            *   
*                                                                     *   
*        UPON RETURN, THE 'RETURN-CODE' SPECIAL-REGISTER (R15) WILL   *   
*        EQUAL ZERO (VALID PACKED-DECIMAL DATA), 08 (INVALID DATA) OR *   
*        16 (INVALID DATA LENGTH).                                    *   
*                                                                     *   
*        AFTER ISSUING THE OBLIGATORY 'BCTR,0', AN 'SLL,4' IS ISSUED  *   
*        AGAINST R7. THIS IS NECESSARY FOR THE 'EX' TO 'OR' THE       *   
*        ADJUSTED-LGTH INTO BITS 8-15 OF THE 'TP' INSTRUCTION.        *   
*                                                                     *   
*        SO FOR EXAMPLE, IF THE ADJUSTED R7 = X'00000005', IT WILL    *   
*        CONTAIN X'00000050' AFTER THE SHIFT.                         *   
*                                                                     *   
*---------------------------------------------------------------------*   
***********************************************************************   
TESTPKD  CSECT                                                           
         USING *,R3                    INFORM ASSEMBLER                   
         SAVE  (14,12)                 SAVE REGISTERS                     
         LA    R3,0(,R15)              R3 IS BASE-REGISTER               
         L     R7,0(,R1)               POINT TO HWORD-LGTH               
         LH    R7,0(,R7)               LOAD AS HWORD                     
         LA    R15,16                  SET RETURN-CODE                   
         CHI   R7,1                    ZERO OR NEGATIVE LGTH?             
         BL    RTN2CLLR                YES, RETURN TO CALLER             
         CHI   R7,16                   EXCEEDS MAXIMUM-LGTH?             
         BH    RTN2CLLR                YES, RETURN TO CALLER             
         BCTR  R7,0                    REDUCE BY ONE                     
         SLL   R7,4                    SHIFT-LEFT 4-BITS FOR 'EX'         
         L     R9,4(,R1)               POINT TO DATA-PARM                 
         LA    R9,0(,R9)               CLEAR TOP-BIT                     
         LA    R15,8                   SET RETURN-CODE                   
         EX    R7,VALIDATE             VALID DECIMAL-DATA?               
         BNZ   RTN2CLLR                NO, RETURN TO CALLER               
         SLR   R15,R15                 ALL IS WELL                       
RTN2CLLR EQU   *                                                         
*                                                                         
         RETURN (14,12),RC=(15)        RETURN TO THE CALLER               
*                                                                         
VALIDATE TP    0(00,R9)                EXECUTED 'TP' (LGTH IN R7)         
*                                                                         
         LTORG ,                       LITERAL-ORG                       
*                                                                         
TESTPKD  AMODE 31                                                         
TESTPKD  RMODE ANY                                                       
*                                                                         
         YREGS                         REGISTER-EQUATE MACRO             
*                                                                         
         END   ,                       END 'TESTPKD'                     

HTH....

Regards,

Bill
Back to top
View user's profile Send private message
soundarr

New User


Joined: 17 Jan 2008
Posts: 25
Location: Chennai

PostPosted: Tue May 06, 2008 8:13 pm
Reply with quote

Hi ponnu,

You can use UNSPEC BUILTIN function for this. Let me know if you need more info on this and if my reply isnt too late..;-)

Regards,
Soundarr
Back to top
View user's profile Send private message
k_vikram07

New User


Joined: 23 Nov 2005
Posts: 35

PostPosted: Sat May 24, 2008 10:05 am
Reply with quote

HI

Use HEX function to get the hex char of the field and then use VERIFY to verify if all the hex digits are acceptable.

regards
Vik[/code]
Back to top
View user's profile Send private message
letmeknow

New User


Joined: 10 Dec 2005
Posts: 5
Location: chennai

PostPosted: Tue Jun 03, 2008 1:19 pm
Reply with quote

Srini,

As vikram said you can use VERIFY to verify whether the variable is numeric or not.

DCL A DEC FIXED(5,0) INIT(0);
DCL B PIC'99999' INIT('');
DCL C BIN FIXED(15) INIT(0);

A=1234;
B=A;
C = VERIFY(B,'0123456789');

C will be 0, since it is numeric.

Ex: A = 123A;

C will be 4. --> gives the position of the non numeric.

------
If A is decimal value, define appropriate pic variable, in verify string add . (decimal point).


Regards,

Krishna
Back to top
View user's profile Send private message
LeonDirect

New User


Joined: 13 Jan 2022
Posts: 5
Location: South Africa

PostPosted: Fri Jan 28, 2022 2:12 pm
Reply with quote

Functions / algorithms using Verify to check for a valid numeric field (DEC / PIC / CHAR from CICS screen containing a PIC or DEC) can be dicey (e.g. if a text amount field contains two decimal points your verify test will pass it).

The best way to properly verify that a field is valid, is to let PL/1 do it for you!

This way, the answer you get from the test is 100% aligned with what will happen when you use that field.

I have variations on this function for PIC fields, CHAR fields (supposedly containing integer numbers or amounts with decimals) etc. , but you will see the principle is the same:

Code:
 /********************************************************************/
 /*          A M O U N T   V A L I D                                 */
 /*                                                                  */
 /* TEST CHAR(14) FIELD FROM SCREEN FOR BEING A VALID DECIMAL(13,2)  */
 /********************************************************************/
 AMOUNT_VALID: PROC(AMOUNT) RETURNS(BIT);                               
 DCL AMOUNT CHAR(14);                                                   
 PROCESS:                                                               
 DO;                                                                   
                                                                       
  DCL VALID BIT INIT ('1'B);                                           
  DCL TEMP_AMOUNT FIXED DECIMAL(13,2) INIT(0);                         
                                                                       
  IF AMOUNT = '' THEN LEAVE PROCESS;                                   
                                                                       
  ON CONVERSION BEGIN;                                                 
  VALID = '0'B;                                                         
  GOTO CONT1;                                                           
  END;                                                                 
                                                                       
  TEMP_AMOUNT = AMOUNT;                                                 
                                                                       
  CONT1: REVERT CONVERSION;                                             
                                                                       
 END PROCESS;                                                           
                                                                       
 RETURN(VALID);                                                         
                                                                       
 END AMOUNT_VALID;     



What happens here is that you are using PL/1's ON ERROR functionality to trap the specific kind of error you are worried about (which is an exact prediction of whether you will get e.g. ONCODE 612 "for real"). Then you revert (switch off that error trapping again), so that whatever error trapping was in effect before this call, is reset to exactly what it was before this call.

In effect:
Set specific error handling trap locally
Do the actual operation you fear may cause a data exception (but in an isolated test case in my function example)
See if the real error handler trapped it, or let it pass
set your "validate" function's return value
revert the error handling back to whatever was in effect.

You could do this in line where you actually use the field and hit the exception , but I prefer an isolated self contained function, so that the main code remains easily readable & focused.


The error handler is quite interesting. It has "scope" just like variables, and it stacks.


Hope this helps!
Back to top
View user's profile Send private message
LeonDirect

New User


Joined: 13 Jan 2022
Posts: 5
Location: South Africa

PostPosted: Fri Jan 28, 2022 2:23 pm
Reply with quote

Back to top
View user's profile Send private message
Garry Carroll

Senior Member


Joined: 08 May 2006
Posts: 1205
Location: Dublin, Ireland

PostPosted: Fri Jan 28, 2022 9:58 pm
Reply with quote

Unlikely that the OP is waiting 14 years for an answer....

Garry.
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> PL/I & Assembler

 


Similar Topics
Topic Forum Replies
No new posts REXX/CMS How to place command console... CLIST & REXX 4
No new posts CA7 count with DATE variable CA Products 0
No new posts Using Multiple IFTHEN and WHEN condit... SYNCSORT 12
No new posts Check if CICS is online in JCL CICS 10
No new posts Issues Converting From ZD to Signed N... DFSORT/ICETOOL 4
Search our Forums:

Back to Top