Menu

#1244 GCSORT support of DFSORT parameters SYMBOLS

contrib
accepted
GCSORT (13)
5 - default
4 days ago
2026-08-20
No

@sf-mensch
@ddeclerck

I don't know if a bug or an enhancement.
Since I could find no GCSORT documentation excluding SYMBOLS I guess it is a bug.
SYMBOLS is not a feature of ICETOOLS - support lies within DFSORT proper.
zOS example of DFSORT using the SYMBOLS facility
~~~
//ASORTE15 JOB 'WINZOS-SORT',CLASS=A,MSGCLASS=A
//STEP01 EXEC PGM=IEFBR14
//SYSUT1 DD DSN=TESTDATA.WINZOS.SORTED.DATA,DISP=(MOD,DELETE,DELETE)
/
//STEP02 EXEC PGM=SORT
//SORTIN DD DSN=TESTDATA.ASCII.DATA,DISP=SHR
// DD DSN=TESTDATA.UNSORT.ASCII.DATA2,DISP=SHR
// DD DSN=TESTDATA.UNSORTED.ASCII.DATA,DISP=SHR
//
DD DSN=TESTDATA.ASCII.DATA,DISP=SHR
//SORTOUT DD DSN=TESTDATA.WINZOS.SORTED.DATA,DISP=(NEW,CATLG,DELETE),
// DCB=(LRECL=400,RECFM=FB,BLKSIZE=0)
//SYSOUT DD SYSOUT=
//SYMNAMES DD *
ORDERNUM,1,6,CH
/

//SORTCNTL DD *
OPTION MODS E15=(TESTAE15)
SORT FIELDS=(ORDERNUM,A)
OMIT COND=(3,1,CH,EQ,C'1')
/*
//

 ** WINZOS JOB LOG Copyright 2010-2026 Metamorphous Company LLC **

 JOB: ASORTE15  JOB NUMBER: 0036  DATE: 08/19/26  TIME: 21:39:47

1 //ASORTE15 JOB 'WINZOS-SORT',CLASS=A,MSGCLASS=A
2 //STEP01 EXEC PGM=IEFBR14
3 //SYSUT1 DD DSN=TESTDATA.WINZOS.SORTED.DATA,DISP=(MOD,DELETE,DELETE)
4 /
5 //STEP02 EXEC PGM=SORT
6 //SORTIN DD DSN=TESTDATA.ASCII.DATA,DISP=SHR
7 // DD DSN=TESTDATA.UNSORT.ASCII.DATA2,DISP=SHR
8 // DD DSN=TESTDATA.UNSORTED.ASCII.DATA,DISP=SHR
9 *** DD DSN=TESTDATA.ASCII.DATA,DISP=SHR
10 //SORTOUT DD DSN=TESTDATA.WINZOS.SORTED.DATA,DISP=(NEW,CATLG,DELETE),
11 // DCB=(LRECL=400,RECFM=FB,BLKSIZE=0)
12 //SYSOUT DD SYSOUT=

13 //SYMNAMES DD *
16 //SORTCNTL DD *
22 *** OMIT COND=(3,1,CH,EQ,C'1')
23 //

* JOB STATISTICS
21:39:47 STEP01 - STEP STARTED
TESTDATA.WINZOS.SORTED.DATA DELETED
21:39:47 STEP01 - STEP WAS EXECUTED RETURN-CODE=0000
21:39:47 STEP02 - STEP STARTED
+++ SYMBOLS
+++ ORDERNUM,1,6,CH
+++ END
+++
+++ OPTION MODS E15=(TESTAE15)
+++
SORT FIELDS=(1,6,CH,D)
+++ SORT FIELDS=(ORDERNUM,A)
+++ OMIT COND=(3,1,CH,EQ,C'1')
+++
+++ ERROR : SYNTAX ERROR, UNEXPECTED STRING, EXPECTING
+++ ERROR NEAR ELEMENT : SYMBOLS
+++ ABEND STEP ABEND SORT FAILED RETURN-CODE = 16
21:39:47 STEP02 - STEP ABENDED RETURN-CODE=0016
21:39:48 ASORTE15 (0036) ENDED WITH AN ABEND - RETURN-CODE 0016 - JOB ENDED

2 public AI(s) took a left turn halucination infering that this syntax would implement SYMBOLS support within GCSORT - AI lied :-)
SYMBOLS
ORDERNUM,1,6,CH
END
USE C:\WINZOS\DATA\SORTIN03.DAT RECORD F,00400 ORG SQ
USE C:\WINZOS\DATA\SORTIN02.DAT RECORD F,00400 ORG SQ
USE C:\WINZOS\DATA\SORTIN01.DAT RECORD F,00400 ORG SQ
GIVE C:\WINZOS\ZOSICF\S2121558.DAT RECORD F,00400 ORG SQ
OPTION MODS E15=(TESTAE15)
SORT FIELDS=(ORDERNUM,A)
OMIT COND=(3,1,CH,EQ,C'1')
~~~

GCSORT has no support to parse, or process DFSORT SYMBOLS.
It only understands numbers, lengths, data types and order (like "1,6,CH,A" in my JCL sort)

The onus of storing the SYMBOLS and then parsing and substituting the the SYMBOL tokens with numbers, lengths, data types should be that of GCSORT

I could do the substitution in WINZOS but then GCSORT users that do not use WINZOS would not have support for SYMBOLS

Agreed ?

Discussion

  • Sauro Menna

    Sauro Menna - 2026-08-21

    Hi,
    I've analyzed the issue regarding SYMBOLS.
    Indeed, the SORT function must handle the SYMBOLS.

    For GCSort, I thought I'd organize the handling this way:
    1) Define an environment variable named: SYMNAMES
    2) Assign the name of a file containing the symbolic variable information to this variable

    Example: SYMNAMES=..\files\symnames.txt

    The file ..\files\symnames.txt will contain:
    <variable name="">,value(s)</variable>

    An example of the file format is as follows:
    ID,1,8,ZD
    Name,9,15,CH
    If the first character is a ‘*’, the line indicates a comment.

    During startup, if GCSort finds the SYMNAMES environment variable defined, it retrieves the file name.
    If the file exists and its format conforms to the expected structure, it loads a table of symbols that
    GCSort will use to replace variables with the values extracted from the file.
    The substitution will occur on all lines sent to GCSort, before actual execution.

    I’ll need a few days to implement the solution.
    I’ll send an update as soon as I finish development and testing.
    Okay?
    Best regards.

    Sauro

     
    • Simon Sobisch

      Simon Sobisch - 2026-08-21

      Sounds like a good plan - but I suggest to use libcob's file resolution instead of building that manually (this way DD_SYMNAMES and SYMNAMES env vars work, as well as using COB_FILE_PATH). The easiest way is possible calling into cob_open for input - and either read_next through the file (then it exists somewhere following gc rules) or don't do the symnames setup.

       

      Last edit: Simon Sobisch 2026-08-21
      • Sauro Menna

        Sauro Menna - 2026-08-23

        Okay,
        thanks for the suggestion.
        The feature will be implemented using libcob.
        The question is which file type to use (Line Sequential or Sequential).
        If Line Sequential is used, we might run into the problem previously identified in the GCSort Take file, namely a NULL character in the file.
        For now, I’ll use Line Sequential, so I’ll need to generate the SYMNAMES files with that structure (without NULL characters).

         
        • Ralph Linkletter

          Are you planning to use the takefile for specifying the SYMBOLS ?

          SYMBOLS
          ORDERNUM,1,6,CH
          USE C:\WINZOS\DATA\SORTIN03.DAT RECORD F,00400   ORG SQ
          USE C:\WINZOS\DATA\SORTIN02.DAT RECORD F,00400   ORG SQ
          USE C:\WINZOS\DATA\SORTIN01.DAT RECORD F,00400   ORG SQ
          GIVE C:\WINZOS\ZOSICF\S2121566.DAT RECORD F,00400   ORG SQ
           OPTION MODS E15=(TESTAE15)
           SORT FIELDS=(ORDERNUM,A)
           OMIT COND=(3,1,CH,EQ,C'1')
          

          That actually seems as if would fit in easily - would it not ?
          Are there other operands that precede the USE clause(s) ?

          Please advise

           
          • Sauro Menna

            Sauro Menna - 7 days ago

            Hi,
            The implementation in GCSort will be the same as in DFSORT, that is, using an external file, as in JCL.
            In accordance with the DFSORT standard, an environment variable named DD_SYMNAMES, dd_SYMNAMES, or SYMNAMES must be created, specifying the physical file.
            According to IBM and Microfocus documentation, the dataset or file assigned to DD SYMNAMES must have a fixed-length record format (RECFM=F or RECFM=FB) and a record length of 80 bytes (LRECL=80).
            I will adopt this definition in GCSort.
            Example:

            //SYMNAMES DD *
            ID_DIP,1,5,CH
            LAST_NAME,6,15,CH
            SALARY,21,4,BI
            

            or with the SKIP parameter

            //SYMNAMES DD *
            ID_DIP,1,5,CH       * Starts at column 1. The next free byte is 6.
            ,*,SKIP,50          * Skips 50 bytes. The pointer moves to column 56.
            LAST NAME,*,15,CH     * Starts automatically at 56. The next free byte is 71.
            ,*,SKIP,10          * Skips 10 bytes. The pointer moves to column 81.
            SALARY,*,4,BI    * Starts automatically at 81.
            

            The Microfocus Sort utility allows you to specify symbols in the TAKE file, but they must be enclosed within a block.
            Example:

            * -------------------------------- ------------------
            * Section 1: Symbol Dictionary Definition
            * --------------------------------------------------
            SYMNAMES
            ID_DIP,1,5,CH       * Column 1 for 5 bytes
            ,*,SKIP,50          * SKIP 50 bytes (columns 6–55)
            LAST_NAME,*,15,CH     * Column 56 for 15 bytes
            ,*,SKIP,10          * SKIP 10 bytes (columns 71–80)
            SALARY,*,4,BI    * Column 81 for 4 bytes (binary)
            SALARY_THRESHOLD,+50000
            END                 * Ends the SYMNAMES block
            * --------------------------------------------------
            * Section 2: Data Processing Commands (Logic)
            * --------------------------------------------------
            INCLUDE COND=(SALARY,GT,SALARY_THRESHOLD)
            SORT FIELDS=(LAST_NAME,A)
            

            I think the idea of including the symbol definitions in the TAKE file is a good one.
            I’ll implement this using both an environment variable with an external file and within the TAKE file itself.

            Thank you.
            Sauro

             
            👍
            1

            Last edit: Simon Sobisch 7 days ago
            • Ralph Linkletter

              I understand the SYMBOLS integration.

              Hey while you are in the source code can you add a counter to the audit file.
              Records omitted or included.
              This is what I produced from my DFSORT emulation.

              Thank you for the feedback !

              Bruce

                    +++  DFSORT Processed  RECORDS IN=:          262
                    +++  DFSORT Processed  RECORDS OUT=:           74
                    +++  DFSORT Processed OMIT/INCLUDE=:          188      <=========*
              
                    ** WINZOS JOB LOG Copyright 2010-2025 Metamorphous Company LLC **
              
                    JOB: AY2SORT   JOB NUMBER: 0409  DATE: 08/24/26  TIME: 11:50:37
                  1 //AY2SORT JOB 'WINZOS-SORT',CLASS=A,MSGCLASS=A
                  2 //STEP01 EXEC PGM=IEFBR14
                  3 //SYSUT1 DD DSN=TESTDATA.WINZOS.SORTED.DATA,DISP=(MOD,DELETE,DELETE)
                  4 /*
                  5 //STEP02 EXEC PGM=SORT
                  6 //SORTIN  DD DSN=TESTDATA.UNSORTED.ASCII.DATA,DISP=SHR
                  7 ***       DD DSN=TESTDATA.UNSORT.ASCII.DATA2,DISP=SHR
                  8 ***       DD DSN=TESTDATA.ASCII.DATA,DISP=SHR
                  9 //SORTOUT DD DSN=TESTDATA.WINZOS.SORTED.DATA,DISP=(NEW,CATLG,DELETE),
                 10 //        DCB=(LRECL=400,RECFM=FB,BLKSIZE=0)
                 11 //SYSOUT  DD  SYSOUT=*
                 12 //SYSIN    DD *
                 17 *** INCLUDE COND=(3,1,CH,EQ,C'1')
                 18 *** SORT FIELDS=(1,6,Y2C,A)
                 19 *** SORT FIELDS=(393,4,Y2P,A)
                 20 *** SORT FIELDS=(393,4,BI,A)
                 21 *** SORT FIELDS=(1,6,CH,D,7,12,CH,A)
                 22 //
              
              ****   JOB STATISTICS   ****
                    11:50:37 STEP01            - STEP STARTED
                    TESTDATA.WINZOS.SORTED.DATA DELETED
                    11:50:37 STEP01            - STEP WAS EXECUTED RETURN-CODE=0000
                    11:50:37 STEP02            - STEP STARTED
                    +++  DFSORT Processed  RECORDS  IN=:          262
                    +++  DFSORT Processed  RECORDS OUT=:           74
              *+++  DFSORT Processed OMIT/INCLUDE=:          188*
                    TESTDATA.UNSORTED.ASCII.DATA                             KEPT
                    TESTDATA.WINZOS.SORTED.DATA CATALOGED
                    C:\WINZOS\ZOSICF\04090200.003 SYSOUT
                    &&TEMP.SY020004.409     DELETED
                    11:50:37 STEP02            - STEP WAS EXECUTED RETURN-CODE=0000
                    11:50:37 AY2SORT  (0409)   - JOB ENDED
              
               
              👍
              1

              Last edit: Simon Sobisch 6 days ago
  • Simon Sobisch

    Simon Sobisch - 2026-08-21
    • labels: --> GCSORT
    • status: open --> accepted
     
  • Ralph Linkletter

    I would think that the implementation would follow SYSIN
    From a zOS perspective there is a SYSIN DD and a SYMNAMES DD

    ~~~
    //STEP02 EXEC PGM=SORT
    //SORTIN DD DSN=TESTDATA.UNSORTED.ASCII.DATA,DISP=SHR
    // DD DSN=TESTDATA.UNSORT.ASCII.DATA2,DISP=SHR
    // DD DSN=TESTDATA.ASCII.DATA,DISP=SHR
    //SORTOUT DD DSN=TESTDATA.WINZOS.SORTED.DATA,DISP=(NEW,CATLG,DELETE),
    // DCB=(LRECL=400,RECFM=FB,BLKSIZE=0)
    //SYSOUT DD SYSOUT=*
    //SYSIN DD DSN=TSUBLUH.SORTCNTL.PDSIN,DISP=SHR

    //STEP02 EXEC PGM=SORT
    //SORTIN DD DSN=TESTDATA.ASCII.DATA,DISP=SHR
    // DD DSN=TESTDATA.UNSORT.ASCII.DATA2,DISP=SHR
    // DD DSN=TESTDATA.UNSORTED.ASCII.DATA,DISP=SHR
    // DD DSN=TESTDATA.ASCII.DATA,DISP=SHR
    //SORTOUT DD DSN=TESTDATA.WINZOS.SORTED.DATA,DISP=(NEW,CATLG,DELETE),
    // DCB=(LRECL=400,RECFM=FB,BLKSIZE=0)
    //SORTCNTL DD *
    OPTION MODS E15=(TESTAE15)
    SORT FIELDS=(1,6,CH,A)
    OMIT COND=(3,1,CH,EQ,C'1')
    /

    The SYSIN DD dataset name is a defacto zOS best practice
    As opposed to SYSIN DD *

    The SYMNAMES parameters should parallel the SYSIN paradigm

    However SYMNAMES is implemented I have the need to extract it from JCL and feed GCSORT - Akin to SYSIN

     

    Last edit: Ralph Linkletter 2026-08-21
  • Sauro Menna

    Sauro Menna - 4 days ago

    Hi,
    I've released a new version of GCSort, ver. 1.05.00, with a number of updates.
    Here are the details:

    - Added support for reading the TAKE file using libcob.
    - SYMNAMES symbol integration
          [1] SYMNAMES with definitions in an external file using libcob
          [2] SYMNAMES definitions in the TAKE file
    - A new counter has been added to the print statistics for OMIT/INCLUDE records
    - Updated the configuration files: gctestsetup.cfg and gctestcmd.cfg for test cases related to SYMNAMES
    

    Best regards.
    Sauro

     
    • Ralph Linkletter

      Can you document how it was implemented on your side please.
      SYMORG or SYMNAMES ?
      If in the TAKEFILE what syntax is required in supporting symbols
      The new record counter is impleneted with ?
      Please advise,

      Thanks
      Bruce

       
      • Sauro Menna

        Sauro Menna - 4 days ago

        Hi,
        Attached are two examples of how to use SYMNAME.
        1) SYMNAMES within the TAKE file. In this case, the contents of the SYMNAMES definition are enclosed between the SYMNAMES (start) and END (end) lines. The definition of the SYMNAMES and SYMORG environment variables must be omitted.
        Within the TAKE file, before defining the SORT instructions, you can insert symbols enclosed between two lines that define the start and end of the SYMNAMES definition.
        Start: SYMNAMES
        End: END

        2) SYMNAMES defined in an external file. In this case, you must set the SYMNAMES environment variable to the pathname of the definition file. SYMORG is required only for SYMORG=SQ, and the record length is fixed at 80 characters.
        The requirements for the definition are identical to those for the TAKE file.

        The definition of the SYMNAMES fields is as follows:
        SYMNAMES format:

        [1] <var name>,value
        [2] <var name>,pos,len,type
        [3] <var name>,*,len,type
        [4] SKIP,value
        

        In the SYMNAMES file, you can assign a descriptive name to record positions, constants, or keywords.
        The asterisk (*) indicates “continue from where the previous field ended.”

        I have included some additional details in the document located in gcsort/doc (GCSORT_Manual.pdf).

        The new record counter dedicated to OMIT/INCLUDE is displayed only if the SORT commands contain the OMIT or INCLUDE construct and the counter takes on a value greater than zero.
        Example:
        ==============================================================

         Total Records Number..............:       786
         Total Records Write Sort..........:         0
         Total Records Write Output........:       222
         Total Records Omit/Include........:       564
        

        ==============================================================

         
        • Sauro Menna

          Sauro Menna - 4 days ago

          first example

           
  • Sauro Menna

    Sauro Menna - 4 days ago

    Hi,
    Attached is a ZIP file with two examples in Windows environment.
    readme.txt contains the details.

    1) Example - SYMNAMES definition in the take file
    gcsort TAKE take_symb.prm
    2) Example - SYMNAMES definition in an external file
    set SYMNAMES=fsymb.txt
    gcsort TAKE take_symb_file.prm

    Sauro

     

Log in to post a comment.