                          P D S U T I L


      La routine linkabile PDSUTIL serve per eseguire via Batch alcune
manipolazioni sui membri di librerie partitioned, rendendole disponibili 
a qualunque programma chiamante, Cobol o Assembler.

      Questa routine si puo' richiamare con una CALL da un qualunque
programma Cobol o Assembler specificando i seguenti parametri:

      in cobol:

          CALL 'PDSUTIL' USING FUNZ DDNAME MEMBRO AREALEN AREAOUT RC

      dove:

          FUNZ       PIC     X(6).
          DDNAME     PIC     X(8).
          MEMBRO     PIC     X(8).
          AREALEN    PIC    S9(7)   COMP.
          AREAOUT    PIC     X(nnn).
          RC         PIC    S9(7)   COMP.

      in assembler:

          CALL  PDSUTIL,(FUNZ,DDNAME,MEMBRO,AREALEN,AREAOUT,RC),VL

      dove:

          FUNZ       DS   CL6
          DDNAME     DS   CL8
          MEMBRO     DS   CL8
          AREALEN    DS   F
          AREAOUT    DS   CLnnn
          RC         DS   F

      Le variabili passate hanno il seguente significato:
FUNZ    : e' l'azione da intraprendere, che vedremo poi
DDNAME  : e' il nome logico della libreria da elaborare; a differenza del
          programma PDSBATCH, la ddname non e' fissa ma e' impostabile
          dal programma chiamante
MEMBRO  : e' il nome del membro da elaborare; anche questo parametro e'
          sempre obbligatorio, tranne che per la funzione 'DIR', in cui
          si puo' mettere a blank
AREALEN : e' la lunghezza del parametro successivo 'AREA' espressa come
          fullword binaria; e' una variabile che e' obbligatorio
          specificare sempre e che e' in input/output
AREAOUT : e' l'area di passaggio dati tra il programma chiamante e la
          routine; nella funzione WRITE va riempita con il record da
          scrivere in output, in tutti gli altri casi contiene i dati
          restituiti dalla routine al programma chiamante
RC      : E' il return code restituito dalla routine, espresso come
          fullword binaria; e' uguale a 0 se e' tutto OK.

      I comandi che si possono dare alla routine (nella variabile FUNZ)
sono i seguenti:

DIR      restituisce un record di directory in 'AREA'; chiamando piu'
         volte la funzione 'DIR' senza cambiare la libreria puntata
         (ossia la DDNAME) vengono restituiti ad uno ad uno tutti i
         nomi e le caratteristiche dei membri della libreria, finche'
         non viene raggiunta una condizione di End Of File (ossia RC
         diverso da zero).
         Se il parametro MEMBRO viene lasciato vuoto (ossia pieno di
         blank), viene restituita la directory completa; se MEMBRO
         specifica un nome preciso, il primo record di directory che
         viene restituito e' quello con nome uguale a quello specificato
         o immediatamente seguente, nel caso che il membro specificato
         non esista. Se infine viene specificato un nome parziale,
         seguito da un asterisco (*), vengono restituiti solo i membri
         che iniziano per il nome parziale; non si puo' specificare
         l'asterisco all'inizio o a meta' di un nome. La selezione che
         conta, e' quella che viene impostata la prima volta che viene
         chiamata la funzione 'DIR' per una determinata libreria.
         Se la libreria non contiene programmi eseguibili ed e' gestita
         dall'ISPF (ossia se la User Data Area della directory e' lunga
         30), in AREA vengono restituite le seguenti informazioni:

          AREAOUT.
             NOMEMEM         PIC   X(8).
             UAREALEN        PIC   9(2).
             ALIAS           PIC      X.
             SIZEMEM         PIC   9(6).
             INIT            PIC   9(6).
             MOD             PIC   9(6).
             CREATED.
                 GG-CREA     PIC   99.
                 FILLER      PIC    X.
                 MM-CREA     PIC   99.
                 FILLER      PIC    X.
                 AA-CREA     PIC   99.
             CHANGED-DATE.
                 GG-CHANGE   PIC   99.
                 FILLER      PIC    X.
                 MM-CHANGE   PIC   99.
                 FILLER      PIC    X.
                 AA-CHANGE   PIC   99.
             CHANGED-TIME.
                 HH-CHANGE   PIC   99.
                 FILLER      PIC    X.
                 MM-CHANGE   PIC   99.
             USERID          PIC   X(8).
             VV              PIC   99.
             MM              PIC   99.

         Il significato delle variabili e' lo stesso di quello specificato
         per il programma PDSBATCH.
         Nel caso che la User Data Area della directory non sia lunga 30,
         in AREA viene restituito:

          AREA.
             NOMEMEM         PIC   X(8).
             UAREALEN        PIC   9(2).
             ALIAS           PIC      X.
             UAREA           PIC  X(nn).

         in cui UAREA e' la User Area non decodificata, con una lunghezza
         (UAREALEN) che al massimo puo' essere 62 bytes.

QUERY    verifica l'esistenza di un membro e ne restituisce le carat-
         teristiche, con tracciato uguale al record restituito da DIR
READ     legge un record del membro specificato; chiamando piu' volte
         la routine e lasciando invariati DDNAME e MEMBRO, vengono
         restituiti uno ad uno tutte le righe del membro, fino a che
         non si arriva alla condizione di End Of File, ossia finche'
         la variabile RC non e' diversa da zero.
WRITE    scrive un record nel membro specificato prendendolo da 'AREA',
         con lunghezza record specificata in AREALEN; chiamando piu' volte
         la routine e lasciando invariati DDNAME e MEMBRO, vengono
         scritti sequenzialmente i record sullo stesso membro.
DELETE   cancella il membro specificato dalla libreria puntata da DDNAME
RENAME   rinomina il membro specificato col nuovo nome in 'area',
         sempre nella libreria puntata da DDNAME
CLOSE    chiude il membro con ddname specificata

      Come si e' notato, non esiste funzione di 'OPEN'; questo perche'
la apertura del file e' sempre implicita nel comando: viene fatta
tutte le volte che viene dato un comando per la prima volta con un
determinato DDNAME e MEMBRO. Se lo stesso comando viene in seguito
dato con stesso ddname e nome membro, la funzione ritorna ad essere
fatta sul membro precedentemente aperto, almeno per le funzioni DIR,
READ e WRITE. Se lo stesso comando viene invece dato con un ddname
o nome membro diverso, la routine:
- chiude automaticamente il membro precedente
- riapre automaticamente la nuova libreria o il nuovo membro
In questo caso, quindi, anche la CLOSE viene fatta implicitamente.
Inoltre, per le funzioni QUERY, RENAME e DELETE, la libreria viene
sempre aperta e chiusa prima del ritorno al programma chiamante.
In sostanza e' necessario usare la funzione 'CLOSE' soltanto prima di
finire il programma chiamante, per ognuna delle funzioni DIR, READ e
WRITE per le quali non si e' avuto un End Of File (quindi, come minimo,
bisognera' dare la CLOSE relativamente al comando WRITE prima di terminare
il programma chiamante).

      E' possibile usare la routine contemporaneamente per ognuna delle
funzioni disponibili, ossia per esempio, mentre si sta facendo una READ
di un membro, e' possibile chiamare la stessa routine per fare la WRITE
di un altro membro, ma non e' possibile chiamarla per fare la READ di un
membro diverso senza evitare che la routine chiuda la lettura del membro
in corso.
      Se si ha necessita' di leggere o scrivere contemporaneamente ad
esempio due membri alla volta si puo' usare questo accorgimento:
- copiare l'eseguibile della routine rinominandolo ad esempio 'PDSUTIL1'
- tutte le volte che nel programma chiamante si vuole accedere al secondo
  membro contemporaneamente, si fara la CALL a PDSUTIL1 invece che a
  PDSUTIL
Le limitazioni di contemporaneita' della routine dipendono dal fatto che
vi e' un solo blocco di controllo file (un solo DCB) per ognuna delle
funzioni; duplicando la routine in pratica vengono duplicati anche i
blocchi di controllo, permettendo l'apertura contemporanea di piu' files.

Non si puo' usare questa routine in un programma CICS.


      Esempi.


       IDENTIFICATION DIVISION.
       PROGRAM-ID. PROVA1.
       AUTHOR. PIERO.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SPECIAL-NAMES.
           DECIMAL-POINT  IS  COMMA.
      ****************************************************************
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       77  FUNZ       PIC     X(6).
       77  DDNAME     PIC     X(8).
       77  MEMBRO     PIC     X(8).
       77  LEN        PIC    S9(7)   COMP VALUE +80.
       77  AREAOUT    PIC     X(80).
       77  RC         PIC    S9(7)   COMP.
      ****************************************************************
      * ESEMPIO DI SCRITTURA IN SYSOUT DI UN MEMBRO DI LIBRERIA      *
      ****************************************************************
       PROCEDURE DIVISION.
       INIZIO.
           MOVE 'READ'     TO FUNZ.
           MOVE 'LIBDD'    TO DDNAME.
           MOVE 'MIOMEM  ' TO MEMBRO.
       LOOP.
           MOVE +80        TO LEN.
           CALL 'PDSUTIL' USING FUNZ DDNAME MEMBRO LEN AREAOUT RC.
           IF RC NOT = 0 THEN GO TO FINE.
           DISPLAY AREAOUT.
           GO TO LOOP.
       FINE.
           DISPLAY 'RC = ' RC.
           STOP RUN.


       Il prossimo esempio stampa la Directory di una libreria.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
      *----------------------------------------------------------------
       77  FUNZ       PIC     X(6).
       77  DDNAME     PIC     X(8).
       77  MEMBRO     PIC     X(8).
       77  LEN        PIC    S9(7)   COMP VALUE +80.
       77  RC         PIC    S9(7)   COMP.
       01  AREAOUT.
           05 NOMEMEM         PIC   X(8).
           05 UAREALEN        PIC   9(2).
           05 ALIAS           PIC      X.
           05 SIZE            PIC   9(6).
           05 INIT            PIC   9(6).
           05 MOD             PIC   9(6).
           05 CREATED.
              10  GG-CREA     PIC   99.
              10  FILLER      PIC    X.
              10  MM-CREA     PIC   99.
              10  FILLER      PIC    X.
              10  AA-CREA     PIC   99.
           05 CHANGED-DATE.
              10  GG-CHANGE   PIC   99.
              10  FILLER      PIC    X.
              10  MM-CHANGE   PIC   99.
              10  FILLER      PIC    X.
              10  AA-CHANGE   PIC   99.
           05 CHANGED-TIME.
              10  HH-CHANGE   PIC   99
              10  FILLER      PIC    X.
              10  MM-CHANGE   PIC   99
           05 USERID          PIC   X(8).
           05 VV              PIC   XX.
           05 MM              PIC   XX.
      ****************************************************************
       PROCEDURE DIVISION.
       INIZIO.
           MOVE 'DIR'      TO FUNZ.
           MOVE 'MIADD'    TO DDNAME.
           MOVE '        ' TO MEMBRO.
      *    MOVE 'val*    ' TO MEMBRO. <-- esempio di selezione
       LOOP.
           MOVE +80        TO LEN.
           MOVE '        ' TO AREAOUT.
           CALL 'PDSUTIL' USING FUNZ DDNAME MEMBRO LEN AREAOUT RC.
           IF RC NOT = 0 THEN GO TO FINE.
           DISPLAY AREAOUT.
           GO TO LOOP.
      * ---------------------------------------------------------------
       FINE.
           DISPLAY 'RC = ' RC.
           STOP RUN.
      ********************************************************** END *


      Il prossimo esempio copia un membro di libreria in un'altro membro.

       WORKING-STORAGE SECTION.
       77  FUNZ1      PIC     X(6).
       77  DDNAME1    PIC     X(8).
       77  MEMBRO1    PIC     X(8).
       77  LEN        PIC    S9(7)   COMP VALUE +80.
       77  AREAOUT    PIC     X(80).
       77  RC         PIC    S9(7)   COMP.
       77  FUNZ2      PIC     X(6).
       77  DDNAME2    PIC     X(8).
       77  MEMBRO2    PIC     X(8).
      ****************************************************************
      * ESEMPIO DI COPIA DI UN MEMBRO DI LIBRERIA                    *
      ****************************************************************
       PROCEDURE DIVISION.
       INIZIO.
           MOVE 'READ'     TO FUNZ1.
           MOVE 'MIADD'    TO DDNAME1.
           MOVE 'INPUTMEM' TO MEMBRO1.
           MOVE 'WRITE'    TO FUNZ2.
           MOVE 'MIADD'    TO DDNAME2.
           MOVE 'OUTMEM  ' TO MEMBRO2.
       LOOP.
           MOVE +80        TO LEN.
           CALL 'PDSUTIL' USING FUNZ1 DDNAME1 MEMBRO1 LEN AREAOUT RC.
           IF RC NOT = 0 THEN GO TO FINE.
           DISPLAY AREAOUT.
           CALL 'PDSUTIL' USING FUNZ2 DDNAME2 MEMBRO2 LEN AREAOUT RC.
           GO TO LOOP.
      * ---------------------------------------------------------------
       FINE.
           DISPLAY 'RC = ' RC.
           MOVE 'CLOSE'    TO FUNZ2.
           CALL 'PDSUTIL' USING FUNZ2 DDNAME2 MEMBRO2 LEN AREAOUT RC.
           STOP RUN.


