• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Converting CASE in CL

    November 14, 2012 Bob Cozzi

    When I write CL, I long for some of the ease-of-use features IBM added over the last 10 years to RPG IV. Simple things like %XLATE or %SCAN or %EDITC would be nice.

    For example, a client of mine had a CL program that required several parameters, one of which was a user ID. However, the non-IBM i platform on which that information was entered did not automatically convert lowercase letters to all uppercase. When the program would try to verify the user profile, it would almost always fail.

    Initially my client wanted to use one of the legacy APIs such as QDCXLATE or QTBXLATE. But these APIs were created for tape conversions and were never intended to be used for data conversion on an on-going basis. Their tables are not maintained, and may not always produce the results one would expect.

    RPG IV has its %XLATE built-in function, which is a poor man’s ToLower or ToUpper function. But there is also an IBM i API that uses CCSID-safe conversion routines to perform case conversions. That API is QlgConvertCase.

    I’ve been using this API for years, but this was the first time I had needed to leverage it in CL. I had previously created an RPG IV prototype for this API. I reproduce it here so that we have a common foundation for this API, rather than using the QSYSINC version of the prototype, which is in C.

    D QlgCvtCase      PR                  extProc('QlgConvertCase')
    D  ctrlBlock                          Const LikeDS(FRCB_T)
    D  inString                  65535A   Const Options(*VARSIZE)
    D  OutString                 65535A   Options(*VARSIZE)
    D  nLength                      10I 0 Const
    D  apiError                           LikeDS(QUSEC_T) OPTIONS(*VARSIZE)
    

    The parameters are pretty standard except for the first one–the so called Control Block. This is a data structure named FRCB. I’ve created a template for it named FRCB_T in my own tool kit. I reproduce it here for completeness:

    D FRCB_T          DS                  QUALIFIED
    D  reqType                      10I 0 Inz(1)
    D  CCSID                        10I 0 Inz(0) 
        // 0=ToUpper; 1=ToLower; 
    D  ToLower                      10I 0 Inz(0)
    D  Reserved                     10A   Inz(*ALLX'00')
    

    The FRCB data structure controls how the QlgConvertCase API behaves. If the REQTYPE subfield equals 1, the API does a CCSID-save upper/lower case conversion. That conversion is based on the value of the TOLOWER subfield. If TOLOWER = 1, the data is converted to all lower case. If it equals 0, it is converted to all uppercase.

    We need to convert the data structure to CL in order to call the API. In V5R4, CL gained limited data structure support and other features that make it easier to define data structures. To define the FRCB data structure in CL, first declare the data structure itself (&FRCB in our example). Each subfield needs to specify STG(*DEFINED) and DEFVAR(&FRCB xx), where xx is the position within &FRCB where the subfield is located.

    Here’s how my version turned out:

     FRCB:        /* FRCB Structure in CL  */
                 DCL        VAR(&FRCB) TYPE(*CHAR) LEN(22)
                 DCL        VAR(&FRCB_REQ) TYPE(*INT) STG(*DEFINED) +
                              LEN(4) DEFVAR(&FRCB)
                 DCL        VAR(&FRCB_CCSID) TYPE(*INT) STG(*DEFINED) +
                              LEN(4) DEFVAR(&FRCB 5)
                 DCL        VAR(&FRCB_Lower) TYPE(*INT) STG(*DEFINED) +
                              LEN(4) DEFVAR(&FRCB 9)
                 DCL        VAR(&FRCB_RES) TYPE(*CHAR) STG(*DEFINED) +
                              LEN(10) DEFVAR(&FRCB 13)
    

    Interestingly, when you use the STG(*DEFINED) feature, you cannot use the VALUE keyword on the subfields. Therefore, you cannot initialize data structure subfields in CL. Instead you have to use CHGVAR.

    The QlgConvertCase API comes in two versions, a subprocedure and a program. The program object is the form I’ll use in CL since CL plays nicer with program calls. The program version of the API is named QLGCNVCS. It has identical parameters to its subprocedure counterpart; therefore the FRCB data structure is going to be put to good use.

    As with all good APIs, the numeric parameters are 4 byte integers. These equate to TYPE(*INT) LEN(4) in CL and 10i0 in RPG IV. For the most part, the entire data structure should be initialized to all X’00’. Since CL does not offer any kind of function to do that, we are forced to hard code it on the VALUE keyword as shown in the example below.

    Two subfields in the FRCB data structure must be initialized to values other than X’00’. The REQ subfield is always set to 1. This means a CCSID lower- to uppercase or upper- to lowercase conversion is being performed. That’s what we’re doing. The LOWER subfield is set to 1 to indicate lowercase conversion or 0 to indicate uppercase conversion. In my example, I convert to uppercase so it is set to 0.

    Here’s the full example:

     CVTCASE:    PGM        /* Example Convert Case in CL by Bob Cozzi  */
                 DCL        VAR(&FRCB) TYPE(*CHAR) LEN(22)
                 DCL        VAR(&FRCB_REQ) TYPE(*INT) STG(*DEFINED) +
                              LEN(4) DEFVAR(&FRCB)
                 DCL        VAR(&FRCB_CCSID) TYPE(*INT) STG(*DEFINED) +
                              LEN(4) DEFVAR(&FRCB 5)
                 DCL        VAR(&FRCB_Lower) TYPE(*INT) STG(*DEFINED) +
                              LEN(4) DEFVAR(&FRCB 9)
                 DCL        VAR(&FRCB_RES) TYPE(*CHAR) STG(*DEFINED) +
                              LEN(10) DEFVAR(&FRCB 13)
    
                 DCL        VAR(&NAME) TYPE(*CHAR) LEN(50) +
                              VALUE('Cozzi test for itJungle.com article')
                 DCL        VAR(&OUTPUT) TYPE(*CHAR) LEN(50)
                 DCL        VAR(&LEN) TYPE(*INT) LEN(4) VALUE(50)
                 DCL        VAR(&QUSEC) TYPE(*CHAR) LEN(16) +
                              VALUE(X'0000000000000000')
    
                 MONMSG     MSGID(CPF0000)
                 CHGVAR     VAR(&FRCB_REQ) VALUE(1)
                 CHGVAR     VAR(&FRCB_CCSID) VALUE(0)
                 CHGVAR     VAR(&FRCB_LOWER) VALUE(0)
                 CHGVAR     VAR(&FRCB_RES) VALUE(X'00000000000000000000')
     CONVERT:    CALL       PGM(QLGCNVCS) PARM(&FRCB &NAME &OUTPUT &LEN +
                              &QUSEC)
                 SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA('Name =' +
                              *BCAT &NAME) MSGTYPE(*COMP)
                 SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA('Upper=' +
                              *BCAT &OUTPUT) MSGTYPE(*COMP)
     ENDPGM:     ENDPGM
    

    This CL program converts the text in the CL variable &NAME to all uppercase and stores the converted text in the &OUTPUT variable. The program then writes this information to the job log for you to review.

    I originally tried to retrieve the job’s CCSID and use it, but since my system still has 65535 for its CCSID instead of 37 or 0, it didn’t work with this API. Using 0 means it will take the job’s CCSID anyway, so why bother trying to be explicit?

    One thing I’ve learned from my years of writing programmer tools is that if you put in a little effort up front, you end up with a fairly simple, yet powerful tool that can be easily reused. There’s an old saying “The cheap person pays twice.” If I modify that a bit for our situation, I could say “the lazy programmer codes twice.”

    Bob Cozzi is author of The Modern RPG IV Language book, and has been working with RPG since the 1970s. Bob’s latest project is COZTOOLS a library of features that add to RPG IV’s built-in functions. Send your questions or comments for Bob to Ted Holt via the IT Jungle Contact page.



                         Post this story to del.icio.us
                   Post this story to Digg
        Post this story to Slashdot

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags:

    Sponsored by
    Maxava

    Migrate IBM i with Confidence

    Tired of costly and risky migrations? Maxava Migrate Live minimizes disruption with seamless transitions. Upgrading to Power10 or cloud hosted system, Maxava has you covered!

    Learn More

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Sponsored Links

    HiT Software:  Download FREE paper "Change Data Capture for Business Intelligence and Analytics"
    looksoftware:  Achieving the impossible with RPG Open Access. Live webcast Dec 4 & 5.
    ITJ Bookstore:  Bookstore BLOWOUT!! Up to 50% off all titles! Everything must go! Shop NOW

    IT Jungle Store Top Book Picks

    Bookstore Blowout! Up to 50% off all titles!

    The iSeries Express Web Implementer's Guide: Save 50%, Sale Price $29.50
    The iSeries Pocket Database Guide: Save 50%, Sale Price $29.50
    Easy Steps to Internet Programming for the System i: Save 50%, Sale Price $24.97
    The iSeries Pocket WebFacing Primer: Save 50%, Sale Price $19.50
    Migrating to WebSphere Express for iSeries: Save 50%, Sale Price $24.50
    Getting Started with WebSphere Express for iSeries: Save 50%, Sale Price $24.50
    The All-Everything Operating System: Save 50%, Sale Price $17.50
    The Best Joomla! Tutorial Ever!: Save 50%, Sale Price $9.98

    IBM Deals On PowerSC Security Wares, And IBM i Hooks In LANSA Launches LongRange University

    Leave a Reply Cancel reply

Volume 12, Number 27 -- November 14, 2012
THIS ISSUE SPONSORED BY:

ProData Computer Services
WorksRight Software
PowerTech

Table of Contents

  • Converting CASE in CL
  • Use SQL To Update A Sequence Number
  • Admin Alert: A Checklist For Performing IBM i Planned Maintenance

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • Meet The Next Gen Of IBMers Helping To Build IBM i
  • Looks Like IBM Is Building A Linux-Like PASE For IBM i After All
  • Will Independent IBM i Clouds Survive PowerVS?
  • Now, IBM Is Jacking Up Hardware Maintenance Prices
  • IBM i PTF Guide, Volume 27, Number 24
  • Big Blue Raises IBM i License Transfer Fees, Other Prices
  • Keep The IBM i Youth Movement Going With More Training, Better Tools
  • Remain Begins Migrating DevOps Tools To VS Code
  • IBM Readies LTO-10 Tape Drives And Libraries
  • IBM i PTF Guide, Volume 27, Number 23

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2025 IT Jungle