Il COBOL - Jurassic News

Transcript

Il COBOL - Jurassic News
Tullio Nicolussi
Il COBOL
J urassic B ook s
Jurassic Book - Tullio Nicolussi - Il COBOL
Title: Il COBOL
Author: Tullio Nicolussi
Acquisitions Editor: Bes Delsec
Technical Editor: Tullio Nicolussi
Production Editor:Bes Delsec
Production Manager: Tullio Nicolussi
Book Designer: Anna
Cover Designer: Anna
Copyright © 2008 by Jurassic News
Published in Italy
First edition 2009
ISBN: na
This publication may be reproduced, stored in a retrieval system or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, scanning or otherwise, only in integral form.
Distribution on-line from http://www.jurassicnews.com
Limit of Liability/Disclaimer of Warranty: The publisher and the author make no representations or warranties with respect to the accuracy or completeness of the contents of this work and specifically disclaim
all warranties, including without limitation warranties of fitness for a particular purpose.
For general information on our other products and services or to obtain technical support, please contact
our Customer Care Department at [email protected]
Library of Congress Cataloging-in-Publication Data
Nicolussi, Tullio.
Il COBOL / Tullio Nicolussi. - 1st ed.
ISBN na
1. Computer programming 2. Computer language 3. Computer manual.
TRADEMARKS: Jurassic News, is not associated with any product or vendor mentioned in this book.
10 9 8 7 6 5 4 3 2 1 0
2
Jurassic Book - Tullio Nicolussi - Il COBOL
Sommario
Introduzione
.........................................................................................................................4
Overview
.........................................................................................................................6
Il primo programma
.......................................................................................................................10
Il Bubble Sort in COBOL
.......................................................................................................................12
Le Variabili Strutturate
.......................................................................................................................19
La Gestione dei File
.......................................................................................................................26
La Gestione del Video
.......................................................................................................................32
Conclusione
.......................................................................................................................37
3
Jurassic Book - Tullio Nicolussi - Il COBOL
COBOL
Introduzione
R
ileggendo la prima stesura di questo articolo
ho visto (con orrore) che
avevo scritto le solite cose che
si dicono quando si spolvera un
vecchio software e in particolare
un linguaggio di programmazione
che non gode più dei favori degli
sviluppatori, cioè qualcosa come:
-“che questo è un peccato, che in
realtà il linguaggio non ha nulla da
invidiare ai più moderni idiomi, che
ancora viene usato con profitto,...”
e via di questo passo fra un rammarico e un sospiro.
Il bello è che per il COBOL tutto
questo corrisponde alla verità!
Ma perché allora quando se ne
sussurra il nome gli studenti sghignazzano, i guro della programmazione si fanno due volte il segno della croce (che vuol dire che
invocano il dio C++) e i colleghi più
giovani scuotono il capo e mentre si allontanano si coglie chiara
la frase “...pronto per la pensione...”?
Ehi, un po’ di rispetto, che diamine!
Per essere onesti non si deve negare che qualche acciacco ahinoi
il linguaggio per eccellenza della
programmazione gestionale non
riesce a nasconderlo. Qualche
iniezione di “Gerovital” in forma di
query SQL è valsa a migliorarne
taluni aspetti nascondendo le artri4
ti reumatoidi dei file indexed. Parimenti le stampelle della programmazione per eventi sono valse a
traghettare l’idioma nelle acque
assai agitate della programmazione Windows. Per finire la clonazione sotto forma di linguaggi
embedded nei sistemi ERP (vedi
ad esempio SAP), hanno arginato
il fuggi fuggi generale dei cervelli
programmatoidi che rischiava di
lasciare milioni di righe di codice
prive di qualsiasi possibilità di manutenzione.
Eppure ancora oggi dove l’idea di
classe regna indiscussa, il COBOL
rimane una buona scelta in molte
circostanze. Questa considerazione è valida per la quasi totalità dei
linguaggi di programmazione che
sono stati inventati nella storia
dell’informatica (parecchie centinaia se contiamo anche i dialetti).
Dipende tutto dalle circostanze in
cui si opera, dai sistemi di cui si dispone e dalle prestazioni dei tool
di sviluppo dei quali possiamo avvalerci.
La fortuna di un linguaggio è
determinata da una serie di circostanze contingenti che dipendono
molto anche dalle mode, oltre che
naturalmente dallo scopo con il
quale esso viene progettato. L’Assembly ad esempio nasce con i
microprocessori e rimane l’indiscusso re della programmazione a
basso livello. Non è stato inventato
niente di meglio perché è perfetto
Jurassic Book - Tullio Nicolussi - Il COBOL
così com’è.
I problemi di concorrenza si pongono quando più linguaggi si sovrappongono per funzionalità specifiche
dell’ambiente in cui operano. Ad
esempio VBSCRIPT piuttosto che
PHP, Python piuttosto che Ruby,
etc, nella programmazione Web.
Il COBOL ha rappresentato per
un paio di decenni la soluzione
indiscussa nell’ambito della programmazione gestionale e rimane
tutt’ora uno strumento molto usato
in questo ambito. Fino a pochi anni
fa si calcolava esistessero molte più
righe di COBOL al mondo di quante
ne potesse vantare il C. Non sono a
conoscenza del rapporto esistente
in questo momento ma credo che
sebbene il C possa vantare la palma del vincitore in questa gara, il
COBOL non sia molto distante dal
podio.
5
Jurassic Book - Tullio Nicolussi - Il COBOL
COBOL - Overview
L
’insegnamento del linguaggio COBOL è stato
per anni appannaggio della scuola secondaria a indirizzo
tecnico. Qualunque istituto pretendesse di sfornare programmatori doveva tenerne conto ed approntare per esso specifici corsi.
Le banche e la finanza in genere
hanno assorbito moltissima forza
lavoro dedicata al settore dell’elaborazione dei dati e se andavi a
lavorare lì non avevi speranza: era
COBOL a pranzo e cena!
Appena possibile le scuole si
sono liberare da questo fardello,
perché? A mio giudizio le cause
sono diverse ma fra le principali
non mancano le seguenti:
- una pretesa di modernità, visto
che ad un certo punto, come detto
prima, se parlavi di COBOL venivi
deriso;
- la mancanza di insegnanti preparati unita ad una certa difficoltà,
peraltro obiettiva, di insegnare la
programmazione usando questo
linguaggio;
- la diffusione del Personal Computer e la conseguente diffusione
di linguaggi più semplici, anche e
meno potenti, come ad esempio il
Basic.
Delle tre a mio giudizio l’ultima è
quella chiave: se trovi il Basic nella macchina finirai per usare solo
quello!
Che dire della difficoltà di apprendimento della quale il linguaggio è
stato accusato? Il problema nasce
6
tutto dalla sua prolissità. Infatti il
COBOL nasce con intenti molto ambiziosi come la cross-compilation ad esempio; è possibile
sviluppare su un sistema e trasferire su un’altra macchina, purché supportata. Il contesto dove
viene messo a punto è quello dei
sistemi mainframe e mini dipartimentali e soprattutto per i primi la
cross-compilation è essenziale.
La pesantezza della sintassi viene, diciamo così, aggravata dalla
ricchezza delle estensioni. Una
istruzione può essere usata in forma semplice ma può essere estremamente strutturata per svolgere
molteplici compiti, essenzialmente
di tipo ripetitivo.
Facciamo un esempio per capire
meglio questo punto. Prendiamo
l’istruzione di addizione che si può
scrivere con l seguente sintassi:
ADD A TO B.
che tradotto sarebbe somma il
contenuto della variabile A con il
contenuto della variabile B e metti
il risultato in B.
Qualcosa come: B = B + A
Per incrementare un contatore di
una unità si userebbe:
ADD 1 TO INDICE
Fino a qui nulla di particolarmente
sconvolgente, la sintassi è leggermente diversa rispetto ai linguaggi
correnti che per la maggior parte
Jurassic Book - Tullio Nicolussi - Il COBOL
utilizzano una notazione “tipo formula”, che fra l’altro è possibile utilizzare anche in COBOL scrivendo
l’istruzione precedente come:
ADD 123,67 TO R1
ROUNDED R2 R3.
Ancora, è anche possibile che
COMPUTE IND = IND + 1.
non si voglia “sporcare” il valore
dell’operando ottenendo un comE se dobbiamo sommare una se- portamento più classico che preverie di numeri?
de lo store del risultato in una variabile a parte. Per fare ciò si usa una
ADD N1 N2 N3 TO RIS.
variante dell’istruzione ADD:
Che, come avrete certo capito significa:
RIS = RIS + N1 + N2 + N3
Ma le possibilità non si esauriscono qui. Consideriamo lo statement
seguente:
ADD A1 A2 A3 TO B1 B2 B3 B4.
Questa sintassi è meno intuibile e
significa: somma i valori A1, A2 e
A3 poi aggiungi questo risultato alle
variabile B1, B2, B3 e B4.
Ovviamente è sempre possibile
espandere l’istruzione in più statement ottendeno ad esempio:
ADD A1 A2 A3 TO R.
ADD R TO B1.
ADD R TO B2.
ADD R TO B3.
ADD R TO B4.
Qualcuno degli operandi che accoglieranno il risultato possono
essere arrotondati aggiungendo la
specifica opzione ROUNDED dopo
i nome, come in:
ADD IMPORTO IVA
GIVING IMPORTO-IVATO.
Si capisce che la sintassi del linguaggio è molto articolata e questo mette sicuramente in difficoltà
chi cerchi di utilizzarlo leggendo
un manuale. L’istruzione MOVE è
l’esempio più eclatante, se vogliamo, ad onta della sua semplicità
(serve per caricare i valori nelle variabili), infatti essa è ricchissima di
varianti, al punto che le pagine dei
manuali ad essa dedicata scoraggiano il malcapitato che volesse
imparare il linguaggio da autodidatta basandosi solo sulla documentazione tecnica.
L’istruzione MOVE carica i valori
nelle variabili, come in:
MOVE 1 TO INDICE.
MOVE N1 TO R2.
Niente di più semplice, apparentemente. Però qualsiasi manuale
COBOL che ne riporta la descrizione e sintassi completa occuperà
pagine e pagine!
Un’altro aspetto del linguaggio
può essere chiamato in causa per
7
Jurassic Book - Tullio Nicolussi - Il COBOL
giustificarne la difficoltà di apprendimento, ed è la sintassi rigida detta in gergo informatico “a campi”.
Significa che ogni elemento del linguaggio deve stare in certe zone
definite della riga. Retaggio derivato dall’uso delle schede perforate
come la lunghezza di 72 caratteri
massima e la necessità di distinguere fisicamente gli elementi di
un programma.
Per creare un programmatore
COBOL professionista una azienda deve essere disposta ad investire almeno tre anni di formazione/
affiancamento e questo oggigiorno
viene considerato un costo, piuttosto che un investimento.
C’è da dire un’ultima cosa sull’uso
del linguaggio, che è la seguente:
pochi, se non addirittura pochissimi, programmatori utilizzano la
ricchezza sintattica del linguaggio.
Nel tempo si è creato in tutte le
aziende una sorta di “lessico famigliare”, per dirla alla Gizburg, che
prevede l’utilizzo di costrutti il più
elementare possibile, anche per
una ragione di manutenzione del
software stesso. Le nuove generazioni di programmatori e i tempi
di consegna sempre più stringenti
non lasciano speranze di procedere altrimenti. Forse esiste un
assioma che implica la longevità
di un linguaggio di programmazione direttamente correlata con
la ricchezza sintattica. Succede
che all’inizio esce una versione
spartana e minimale, poi a furia
di aggiungere features si finisce
per snatuare l’idea originale e si
8
rende la curva di apprendimento
sempre più ripida e lunga. Autorevoli esempi li troviamo nel Perl, nel
PHP e nel Basic.
Dovuta alla ricchezza della sintassi deriva la difficoltà nel costruire un compilatore, aumentata dal
fatto che il linguaggio possiede obbligatoriamente embedded capacità di gestione per i file indicizzati
(che come vedremo nel prosieguo
di questa serie è la vera forza del
COBOL). I compilatori professionali sono costosi e inizialmente indisponibili sulle piattaforme micro,
con la lodevole eccezione dei sistemi che supportano il CP/M.
La diffusione del personal computer in ambito professionistico
ha cambiato molto le cose. In fondo una rete di PC vale quanto un
mainframe (non sempre, ma è un
discorso che ci porterebbe lontano).
Per quanto accennato sopra il
COBOL si è fatta una cattiva fama
e gli ambienti, diciamo così, progressisti non hanno esitato a vituperarne l’utilizzo. Se questo è stato un bene o il contrario non sta a
me decidere. Da un lato si è persa
una professionalitè elevata, dall’altro i nuovi idiomi, più facili all’approccio, hanno permesso a molte
persone l’avvicinarsi alla programmazione. Ci sono dei pro e dei
contro, come in tutte le cose.
Dopo questa lunga ma doverosa
panoramica sulla filosofia del linguaggio COBOL veniamo a parlare di cose pratiche. Prima di tutto
Jurassic Book - Tullio Nicolussi - Il COBOL
bisogna procurarsi un compilatore se si vuole seguire con profitto
il corso che proponiamo. -”Bravo!
E dove ne trovo uno?”. Tranquilli,
è più semplice di quanto si creda.
Rivolgendosi all’Open Source è
possibile recuperare un buon compilatore che gira con GCC (che erroneamente viene considerato un
compilatore di codice C, in realtà è
uno dei cross compiler più flessibili
che ci sono in giro).
Se decidete di seguire questa strada il prodotto si chiama OpenCobol
e si possono scaricare i sorgenti da
questo link:
http://www.opencobol.org/modules/mydownloads/
Scelte alternative possono essere
le versioni datate che qualche utente a volte svende (anche se teoricamente non sarebbe legalmente
ineccepibile) su eBay. La Microsoft
ha commercializzato per un certo
tempo un compilatore per Windows
chiamato Microsoft COBOL. Altra
ditta specializzata è la MicroFocus
che costruisce compilatori per tutte
le piattaforme ed ha anche una versione educational molto bella chiamata “Personal COBOL” che viene
venduta in libreria (non in Italia). Si
veda la prova software in questo fascicolo. Un compilatore molto diffuso all’epoca delle reti Novell era un
certo “MBP COBOL”, prodotto da
una ditta tedesca (la MBP, appunto), il cui acronimo non chiedetemi
per cosa sta :-).
Una fonte alternativa ma molto
valida è fornita dal retro computing
(se no che ci staremmo a fare?). E’
possibile che se il vostro retro com-
puter preferito supporta il CP/M,
troviate in giro le immagini di un
compilatore. magari non sarà una
scheggia, ma che importa?
Ad esempio per Apple IIe sotto
CP/M la Microsoft (sì, sempre lei)
ha commercializzato un compilatore chiamato COBOL-80, elemento
di una serie di prodotti il cui esponente più famoso è il BASIC-80.
Su SurgeForce.org si possono reperire vari progetti che hanno a che
fare con l’argomento. Uno di questi
propone un compilatore minimale
per Windows, chiamato Tiny Cobol.
Lo abbiamo scaricato e provato
trovandolo per la verità non troppo
esaltante...
Ancora, all’indirizzo:
http://www.netcobol.com/products/windows/netcobol.html
si trova un prodotto commerciale
chiamato NETCobol, adatto all’ambiente .NET che sfrutta la IDE di
Visual Studio. Ne esiste anche una
versione “Student”, se volete provarci... Insomma non ci sono scuse
del tipo “non trovo un compilatore
in giro” :-)
9
Jurassic Book - Tullio Nicolussi - Il COBOL
Il primo programma
Abbiamo scritto il classico proseconda
dell’ambien- gramma “hello World” e come si
te operativo che avete vede l’idea della prolissità colpisce
scelto dovete comincia- abbastanza. Rispetto ad un Basic
re a scrivere il sorgente dei pro- che con una semplice istruzione:
grammi. Alcuni tools prevedono 10 PRINT “HELLO WORLD”
un input guidato, ad esempio con
i tab impostati per muoversi fra le avrebbe fornito lo stesso risultato,
varie zone nelle quali è divisa la in COBOL sono state necessarie
riga. Vi ricordo che i primi sei ca- molte più righe. L’utilità dell’orgatarreri della riga sono riservati alle nizzazione del sorgente con mollabel. Il settimo carattere contie- te parti dichiarative sarà molto più
ne un eventuale controllo di riga: chiara nel prosieguo del corso che
il simbolo “-” per la continuazione abbiamo per ora solo introdotto.
dalla riga precedente, “*” per una C’è da dire comunque, a consoriga di commento (da qui il verbo lazione di chi si è spaventato da
“asteriscare” che usano i “veri” subito, che i programmatori si limiprogrammatori), “/” per ordinare il tano fare un copia incolla da un
salto pagina alla stampante sulla template. Oserei dire che moltisquale andiamo a ottenere il listing simi di essi nemmeno sarebbero
del sorgente. Dall’ottavo carattere capaci di scrivere da zero l’intera
inizia la “ZONA A” e al 12 carattere parte dichiarativa: semplicemente
non la possono ricordare, dopo
la “ZONA B”.
anni che non se ne preoccupano!
A
Il primo programma è visibile nel
riquadro “Listato 1” che ora andiamo ad eseminare in dettaglio.
0-----78---2-------2---------3---------4---------AAAABBBBBBBBBBBBBBBBBBBB... IDENTIFICATION DIVISION.
PROGRAM-ID HELLOWORLD.
ENVIRONMENTAL DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
DECIMAL POINT IS COMMA.
DATA DIVISION.
PROCEDURE DIVISION.
MAIN SECTION.
INIZIO.
DISPLAY “HELLO WORLD”.
10
Esaminando il primo sorgente
evidenziamo gli aspetti essenziali
del linguaggio.
Prima di tutto il token
di chiusura di uno statement è il punto e ogni
riga, come si diceva,
deve concludersi entro 72 caratteri, punto
compreso. La regola
dei compilatori è ignorare tutto ciò che eccede il 72-simo carattere.
Il sorgente è diviso in
DIVISION che ne indi-
Jurassic Book - Tullio Nicolussi - Il COBOL
viduano le quattro parti principali.
L’IDENTIFICATION
DIVISION
come dice il nome è deputata a
contenere delle meta-istruzioni che
servono all’identificazione del programma. Una di queste informazioni è il nome del programma stesso
la cui composizione segue le regole dell’ambiente operativo. Non
necessariamente il PROGRAM-ID
corrisponde al nome del binario
compilato sul file system, esso è
un nome interno al quale fare riferimento ad esempio se il sorgente
fosse in una libreria di funzioni.
La ENVIRONMENT DIVISION
specifica l’ambiente dove il programma viene sviluppato rispetto
alla sua destinazione finale. Ricordate che il COBOL è crossplatform? In ambiente Personal
Computer queste specifiche hanno
ormai poco senso e anzi i compilatori sono stati di fatto alleggeriti della capacità di compilare per diversa
piattaforma. Rimane quindi sostanzialmente una divisione figurativa
che serve al più per specificare alcune particolarità che si intendono
usare, come ad esempio l’utilizzo
della virgola come separatore dei
decimali.
Infine la PROCEDURE DIVISION
ospita il codice che viene organizzato in sezioni. Tradizionalmente
si nomina la prima sezione “MAIN
SECTION”, anche se il nome “MAIN”
non è obbligatorio (potrebbe essere chiamata INIZIO o qualsiasi altra
cosa piaccia). Poi abbiamo inserito
anche la parola “INIZIO” che funge
da label. Si usa, ma anche questo
non è obbligatorio.
Per completare la disamina del
primo sorgente diciamo che l’istruzione DISPLAY stampa a video una
costante letterale (è il nostro caso)
o il valore di una variabile.
Il programma viene eseguito dalla
prima sezione che si incontra fino al
termine della stessa o fino alla conclusione del sorgente. Esiste una
specifica istruzione STOP PROGRAM o semplicemente STOP che
conclude l’elaborazione.
Tradizionalmente i sorgenti vengono scritti in maiuscolo in omaggio ai
vecchi terminali dei mainframe anni
‘60. I compilatori oggigiorno accettano anche il minuscolo che negli
ultimi anni è diventata una pratica
seguita da moltissimi programmatori, specialmente se appartenenti
alle nuove generazioni, abituati ai
linguaggi correnti. Il Cobol rimane
però unsensitive, come il Basic:
non distingue fra maiuscole e minuscole.
La DATA DIVISION non è altro che
la parte di sorgente dove si dichiarano le variabili. In COBOL variabili
e costanti devono essere dichiarate tutte in questa divisione dove
trovano posto anche altre strutture
informative come ad esempio i file Pur esistendo qualche approccio
sequenziali o con chiave, le specifi- alla pratica dell’interpretazione, il
che di ordinamento, etc...
COBOL nasce come linguaggio
11
Jurassic Book - Tullio Nicolussi - Il COBOL
compilato. La rigida organizzazione dei sorgenti è a supporto della creazione del codice binario. Il
COBOL si presenta quindi praticamente sempre con la classica
configurazione di sviluppo editorcompilazione-esecuzione.
L’ambiente di eccellenza per
l’esecuzione di programmi COBOL
è l’interfaccia a caratteri, proprio
per la forma spartana dell’I/O tipica del linguaggio. Come abbiamo
detto nell’introduzione non mancano comunque implementazioni “a
finestre” realizzate con opportune
estensioni del linguaggio stesso
che dimostra una certa dose di
adattabilità grazie soprattutto alle
estensioni “ad-hoc” che le aziende
produttrici vi inseriscono “a forza”
per dare al loro prodotto una parvenza di modernità. Già dalla nascita comunque è stata prevista
una sorta di gestione “a form” del
video. Una specifica SECTION,
esattamente la SCREEN SECTION, è deputata alla descrizione
dell’interfaccia.
Il bubble sort in COBOL
Un esempio più articolato è riportato per intero nei box delle pagine
seguenti. Si tratta di una implementazione dell’algoritmo classico
di bubble sort. Penso sia noto a
tutti il meccanismo di questo semplice algoritmo di ordinamento: si
tratta di spostare degli elementi in
un vettore effettuando dei ripetuti
scambi con gli elementi adiacenti
fino ad ottenere un vettore ordinato. Maggiori approfondimenti si
possono trovare sul fascicolo numero 1 di Jurassic News.
Commentiamo ora le righe che
incontriamo nel sorgente per introdurre le novità rispetto a quanto
visto finora.
Nella
WORKING-STORAGE
SECTION abbiamo dichiarato due
costanti (in realtà non esiste una
dichiarazione speciale per variabili
immodificabili, il fatto che siano costanti lo decidiamo noi).
01
MAX
COMP-1 VALUE 3.
01
LIMITE COMP-1
VALUE 10000.
Il tipo COMP-1 è il classico Integer che occupa una o più coppie
di byte a seconda dell’implementazione del compilatore. Sono variabili numeriche senza una definizione di formato.
A cominciare dalla variabile VETTORE abbiamo il primo esempio di
variabile strutturata. VETTORE è il
nome della nostra variabile dichiarata a livello 01 che contiene un
sotto-livello, individuato dal livello
12
Jurassic Book - Tullio Nicolussi - Il COBOL
05 che ne rappresenta il contenuto 01 VETTORE.
10 ELEMENTO
strutturato.
01
VETTORE.
05 EL-VETTORE COMP-1
OCCURS 10000.
EL-VETTORE è vettore di 10.000
elementi di tipo COMP-1.
Quando in una istruzione ci si riferisce alla variabile VETTORE si sta
parlando dell’intera struttura; quando ci si riferisce a EL-VETTORE
si sta parlando di una componente che andrà individuata tramite il
classico meccanismo degli indici:
COMP-1
OCCURS 1000.
Un altro esempio di variabile strutturata è quella che contiene un orario:
01
ORA.
05
05
05
05
ORA-HH
ORA-MM
ORA-SS
ORA-CC
COMP-1.
COMP-1.
COMP-1.
COMP-1.
In questo caso quattro variabili
semplici di tipo COMP-1 sono raggruppate al solo fine di chiarezza,
ma verranno elaborate singolarmente.
MOVE 12 TO EL-VETTORE(34)
In questo specifico caso, cioè nella necessità di dichiarare vettori o
matrici la strutturazione è obbligatoria. Infatti lo standard prevede
che una variabile di livello 01 non
possa essere indicizzata. C’è un
motivo pratico per questo: il livello
01 indica al compilatore anche la
classe di storage della variabile,
cioè i livelli 01 sono immagazzinati
a partire dall’indirizzo intero di memoria, cosa che non succede per i
sotto-livelli.
Se avessimo ad esempio un ambiente a 64 bit, quindi con word di
quattro byte e il tipo COMP-1 fosse
un intero da due byte, allora ogni dichiarazione di COMP-1 a livello 01
occuperebbe comunque una word,
sprecando due byte di memoria.
Una dichiarazione
Nella dichiarazione della variabile
TOT-SECONDI troviamo un’altra
forma di dichiarazione di variabile
numerica.
01 TOT-SECONDI PIC 9(12)V9(2) VALUE ZERO.
PIC 9(12)V9(2) significa 12 cifre
intere seguite da due decimali.
Passiamo ora alla desamina del
codice premettendo che esso è
stato strutturato in maniera molto
spinta (tipo Pascal per intenderci)
cercando di introdurre i concetti di
esecuzione dei singoli pezzi come
fossero parti staccate (procedure o
funzioni).
INIZIO.
* --- loop iterazioni
PERFORM ESEGUI
THRU ESEGUI-EXIT
MAX TIMES.
* --- calcolo della media
01 VETTORE COMP-1 OCCURS 1000
COMPUTE MEDIA =
TOT-SECONDI / MAX.
* --- display dei risultati.
occuperebbe 4000 byte di memoDISPLAY
ria, contro i 2000 occupati dalla di“TOTALE SECONDI IMPIEGATI: “ TOT-SECONDI.
chiarazione:
DISPLAY
13
Jurassic Book - Tullio Nicolussi - Il COBOL
IDENTIFICATION DIVISION.
01
PROGRAM-ID. BUBBLE.
***********************************
* Titolo : Bubble Sort
***********************************
DATE-WRITTEN.
DATE-COMPILED.
DIC/97.
GEN/98.
***********************************
ENVIRONMENT DIVISION.
***********************************
CONFIGURATION SECTION.
*---------------------------------SOURCE-COMPUTER. PENTIUM-PC166.
OBJECT-COMPUTER. PENTIUM-PC166.
SPECIAL-NAMES.
DECIMAL-POINT IS COMMA.
* --- calcolo della media
COMPUTE MEDIA = TOT-SECONDI / MAX. * --- display dei risultati.
DISPLAY “TOTALE SECONDI IMPIEGATI:
“ TOT-SECONDI.
DISPLAY “MEDIA PER VETTORE
“ MEDIA
ESEGUI.
PERFORM CARICA-VETTORE
THRU CARICA-VETTORE-EXIT.
* --- esecuzione sort
VETTORE.
05 EL-VETTORE COMP-1
OCCURS 10000.
01
I COMP-1.
01
SCAMBI
COMP-1.
01
TOT-ITERAZIONI PIC 9(12).
01
J
COMP-1.
01
TOT-SCAMBI PIC 9(12).
01
TEMP
COMP-1.
01
01
ORA.
ORA-HH
ORA-MM
ORA-SS
ORA-CC
COMP-1.
COMP-1.
COMP-1.
COMP-1.
05
05
05
05
ORA-I.
ORA-I-HH
ORA-I-MM
ORA-I-SS
ORA-I-CC
COMP-1.
COMP-1.
COMP-1.
COMP-1.
05
05
05
05
ORA-F.
ORA-F-HH
ORA-F-MM
ORA-F-SS
ORA-F-CC
COMP-1.
COMP-1.
COMP-1.
COMP-1.
CALL “GTIME” USING ORA-I.
display “ora iniziale: “
ORA-I-HH
“:”
ORA-I-MM
“:”
ORA-I-SS
“:”
ORA-I-CC.
MOVE 1 TO SCAMBI.
PERFORM LOOP-SCAMBIO
THRU LOOP-SCAMBIO-EXIT
UNTIL SCAMBI IS EQUAL ZERO.
CALL “GTIME” USING ORA-F.
display “ora finale : “
ORA-F-HH
“:”
ORA-F-MM
“:”
ORA-F-SS
“:”
ORA-F-CC.
MOVE ZERO TO DIFF-SECONDI.
PERFORM CALCOLA-SECONDI
THRU CALCOLA-SECONDI-EXIT.
01
TOT-SECONDI PIC 9(12)V9(2) VALUE ZERO.
01
MEDIA
PIC 9(5)V9(2)
VALUE ZERO.
01
01
01
DIFF-SECONDI
PIC 9(12).
SECONDI-INIZIALI
SECONDI-FINALI
14
COMPUTE TOT-SECONDI =
TOT-SECONDI +
(DIFF-SECONDI / 100).
DISPLAY “TOTALE SECONDI :
“ TOT-SECONDI.
PIC 9(12).
PIC 9(12).
* ---- Variabili per il generatore
di numeri casuali
01
MODULO
COMP-1 VALUE 36456.
01
MOLTIPLICATORE COMP-1.
01
INCREMENTO
COMP-1.
:
USCITA.
STOP RUN.
01
05
05
05
05
COMP-1.
/****************************************
PROCEDURE DIVISION.
****************************************
MAIN SECTION.
****************************************
INIZIO.
****************************************
* --- loop iterazioni
PERFORM ESEGUI THRU ESEGUI-EXIT
MAX TIMES.
/**********************************
DATA DIVISION.
***********************************
WORKING-STORAGE SECTION.
***********************************
* ---- costanti
01
MAX COMP-1 VALUE 3.
01
LIMITE COMP-1 VALUE 10000.
* --- variabili
01
SEME
ESEGUI-EXIT.
EXIT.
LOOP-SCAMBIO.
MOVE ZERO TO SCAMBI.
PERFORM CONFRONTA
THRU CONFRONTA-EXIT
Jurassic Book - Tullio Nicolussi - Il COBOL
VARYING I FROM 1 BY 1
UNTIL I = LIMITE.
LOOP-SCAMBIO-EXIT.
EXIT.
CONFRONTA.
IF EL-VETTORE( I + 1 )
IS < EL-VETTORE( I )
MOVE EL-VETTORE( I + 1 )
TO TEMP
MOVE EL-VETTORE( I )
TO EL-VETTORE( I + 1 )
MOVE TEMP TO EL-VETTORE( I )
MOVE 1
TO SCAMBI.
CONFRONTA-EXIT.
EXIT.
CARICA-VETTORE.
CALL “GTIME” USING ORA.
COMPUTE MOLTIPLICATORE =
ORA-SS * ORA-MM.
COMPUTE SEME =
ORA-CC * ORA-SS.
COMPUTE INCREMENTO =
ORA-CC * ORA-MM.
PERFORM NUMERO-RANDOM
THRU NUMERO-RANDOM-EXIT
VARYING I FROM 1 BY 1
UNTIL I > LIMITE.
CARICA-VETTORE-EXIT.
EXIT.
NUMERO-RANDOM.
MOVE SEME TO EL-VETTORE(I).
COMPUTE SEME =
(MOLTIPLICATORE * SEME +
INCREMENTO).
COMPUTE SEME =
MODULO - (SEME / MODULO) * SEME.
IF SEME < 0
COMPUTE SEME = -SEME.
NUMERO-RANDOM-EXIT.
EXIT.
CALCOLA-SECONDI.
* --- calcola il numero di secondi
occorsi fra i due orari.
COMPUTE SECONDI-INIZIALI =
ORA-I-HH * 3600 +
ORA-I-MM * 60 +
ORA-I-SS.
COMPUTE SECONDI-INIZIALI =
SECONDI-INIZIALI * 100 +
ORA-I-CC.
COMPUTE SECONDI-FINALI =
ORA-F-HH * 3600 +
ORA-F-MM * 60 +
ORA-F-SS.
COMPUTE SECONDI-FINALI =
SECONDI-FINALI
* 100 +
ORA-F-CC.
COMPUTE DIFF-SECONDI =
SECONDI-FINALI SECONDI-INIZIALI.
CALCOLA-SECONDI-EXIT.
EXIT.
15
Jurassic Book - Tullio Nicolussi - Il COBOL
“MEDIA PER VETTORE: “ MEDIA.
USCITA.
STOP RUN.
C’è una iterazione iniziale che
richiama la sezione ESEGUI. La
sintassi
PERFORM ESEGUI THRU ESEGUIEXIT
MAX TIMES.
scambio.
Le istruzioni di iterazione innescate dall’istruzione PERFORM
vengono eseguite continuamente
fino a che non si verifica la condizione descritta nell’UNTIL.
Si noti la sintassi usata per controllare la condizione di uscita. Si
sarebbe potuto anche scrivere:
UNTIL SCAMBI = 0
Concedendo un certo vantaggio
ai programmatori “moderni”, ma
perché dovremmo? La sintassi
usata qui è molto più chiara per
chi è avvezzo a leggere i sorgenti
COBOL, infatti se ci pensate asso-
Significa: esegui un numero di iterazioni pari al valore contenuto in
MAX (che abbiamo dichiarato nella Working al valore 10.000) delle
istruzioni comprese nella sezione
INIZIO per finire con quelle nella
sezione ESEGUI-EXIT.
Fatta questa iterazione c’e’ un
calcolo dei secondi medi impiega- miglia molto di più ad una sintassi
ti, la stampa a video dei risultati e letterale. E’ dimostrato inoltre che
molti errori di codifica nei programl’uscita dal programma.
mi derivano dalla scrittura di conLa sezione ESEGUI, che abbia- dizioni al contorno errate dovute
mo visto viene iterata 10.000 volte, ad una errata interpretazione delle
per avere un risultato medio atten- specifiche o all’impiego di operatori
dibile, prevede i seguenti passag- di confronto simbolici che richiedono un quid di attenzione maggiore
gi:
caricamento del vettore con nu- a chi codifica.
meri pseudo-casuali, la rilevazione
del tempo iniziale, il sort del vettore, la rilevazione del tempo impiegato.
L’algoritmo di ordinamento vero
e proprio è costituito dai seguenti
statement:
MOVE 1 TO SCAMBI.
PERFORM LOOP-SCAMBIO
THRU LOOP-SCAMBIO-EXIT
UNTIL SCAMBI IS EQUAL ZERO.
Se vi è chiaro come procede il
bubble sort, semplicemente si continua a fare scambi di elementi fino
a che una “spazzolatura” finale del
vettore non da luogo a nessuno
16
Il caricamento dei dati nel vettore
avviene nella form CARICA-VETTORE chiamata dallo statement:
PERFORM CARICA-VETTORE
THRU CARICA-VETTORE-EXIT.
Essa contiene un loop che interessa uno ad uno gli elementi del
vettore e vi inserisce un numero
pseudo-casuale.
L’istruzione che effettua il loop di
caricamento è la seguente:
PERFORM NUMERO-RANDOM THRU
NUMERO-RANDOM-EXIT
VARYING I FROM
1 BY 1
UNTIL I > LIMITE.
Jurassic Book - Tullio Nicolussi - Il COBOL
Questa sintassi prevede l’incremento automatico di un indice
rappresentato dalla variabile I che
viene incrementato partendo dal
valore 1 fino a superare il limite
previsto, che è la dimensione del
vettore stesso.
Implicitamente abbiamo introdotto un ulteriore concetto: le variabili
indicizzate hanno indice che inizia
da 1.
altri linguaggi.
Una particolarità che vale la pena
spiegare è l’utilizzo dello statement
MOVE 1
TO SCAMBI
All’interno della form di confronto.
Un valore diverso da zero della variabile SCAMBI serve per ordinare
un ulteriore loop sugli elementi del
vettore. Infatti l’algoritmo si basa
proprio sull’iterazione dei confronti
elemento per elemento del vettore
fino a che un’ultima iterazione non
Il cuore dell’algoritmo di bubble effettua alcuno scambio, segno che
sort è contenuto nella form CON- il vettore è ordinato.
FRONTA:
Non sarebbe stato meglio increCONFRONTA.
mentare il valore di SCAMBI con
IF EL-VETTORE( I + 1 )
una istruzione del tipo:
IS < EL-VETTORE( I )
MOVE EL-VETTORE( I + 1 ) •
ADD 1 TO SCAMBI
TO TEMP
MOVE EL-VETTORE( I )
TO EL-VETTORE( I + 1 )
In effetti se servisse anche tracMOVE TEMP
ciare quanti scambi vengono fatti in
TO EL-VETTORE( I )
MOVE 1 TO SCAMBI.
ogni iterazione, allora l’istruzione di
CONFRONTA-EXIT.
EXIT.
Qui si vede come l’indicizzazione
delle variabili avviene indicando
l’elemento con indice fra parentesi,
eventualmente calcolando il valore
stesso dell’indice.
Gli operatori di confronto in COBOL sono quelli classici: =, <, >,
>=, <=, <>. Esiste tuttavia una forma “letterale” di questi operatori:
incremento sarebbe stata necessaria. In caso contrario è inutile una
istruzione matematica, che consuma certo più tempo, rispetto ad una
istruzione di assegnazione.
•
= IS EQUAL
•
> IS GREATHER THAN
•
< IS LESS THAN
•
>= IS GREATHER OR EQUAL,
IS NOT LESS
•
<= IS LESS OR EQUAL, IS
NOT GREATHER
•
<> IS NOT EQUAL
La forma “prolissa” della sintassi
è poco usata attualmente, dato che
le nuove generazioni di programmatori sono ormai abituate alle
forme “matematiche” più simili agli
17
Jurassic Book - Tullio Nicolussi - Il COBOL
legato alla strutturazione del dato
è la possibilità di ridefinire la memoria indirizzata da una variabile
in modo che questa sia usabile
con due o più nomi.
Ad esempio:
Variabili strutturate
L
’uso di variabili strutturate, come matrici e vettori,
è incoraggiata in COBOL.
C’è chi addirittura struttura tutto,
perfino i semplici contatori interi.
01 CODICE.
Qualcosa come:
02 COD-FIS 01
CONTATORE.
10 CONT PIC COMP-1.
La multidimensionalità si ottiene
inserendo una dichiarazione strutturata in un’altra. Ecco un esempio:
01 MATRICE.
10 RIGA-MATRICE OCCURS 100.
20 EL-MATRICE PIC 9(5)
OCCURS 100.
02
PIC X(16).
PARTITA-IVA
REDEFINES COD-FIS.
05 P-IVA PIC 9(12).
05 FILLER X(4).
Incontriamo per la prima volta una
parola chiave molto usata nella
definizione delle variabili strutturate del COBOL: “FILLER”. Questa
viene utilizzata come riempitivo.
Nel nostro esempio, dato che la
ridefinizione di un’area di memoria deve essere coerente, cioè utilizzare tutto lo spazio, riempiamo
con un nome simbolico FILLER
quella parte di dato che nel caso
stessimo trattando una partita IVA
non ci interessa.
E’ chiaro che COD-FIS e PARTITA-IVA condividono lo stesso spazio di memoria, è lo stesso meccanismo implementato con le union
nel linguaggio C.
Nel listato numero 2 riportiamo un
esempio di definizione di un record
anagrafico che contiene un po’ tutte le cose viste finora nella definizione dei tipi di dato in COBOL.
Qui abbiamo dichiarato una matrice di dimensione 100 per 100 i cui
elementi sono dei valori numerici
di cinListato 1
que ci/****************************************
fre.
PROCEDURE DIVISION.
Ecco
****************************************
MAIN SECTION.
un loop
****************************************
INIZIO.
che ca****************************************
rica gli
PERFORM SCAN-RIGHE
THRU SCAN-RIGHE-EXIT
elemen
VARYING RIGA FROM 1 BY 1
ti della
UNTIL RIGA <= 10.
matrice
USCITA.
STOP RUN.
c o m e
fosse
SCAN-RIGA.
una ta
PERFORM SCAN-COL
01 REC-ANAG.
THRU SCAN-COL-EXIT
vola pi
VARYING COLONNA FROM 1 BY 1
UNTIL COLONNA <= 10.
tagorica è la definizione del livello base,
SCAN-RIGHE-EXIT.
( l i s t a t o appunto 01, che identifica l’inizio
EXIT.
1).
di un dato strutturato.
SCAN-COL.
COMPUTE EL-MATRICE(RIGA, COLONNA) =
RIGA * COLONNA.
18
SCAN-COL-EXIT.
EXIT.
05
Un’alt r o
aspetto
TIPO-RECORD PIC XX.
è un tipo di secondo livello di formato due caratteri alfanumerici.
Jurassic Book - Tullio Nicolussi - Il COBOL
MATRICOLA è un dato strutturato formato da due sotto-livelli che
nell’esempio sono identificato dal
numero di livello 10. Ci si potrà riferire a questo dato indicando il
singolo sotto-livello o il dato intero
MATRICOLA. Ad esempio:
Purtroppo il COBOL non prevede
un meccanismo di dereferenziazione del dato, come succede nei
linguaggi di programmazione più
moderni. Ad esempio nel C si usa il
punto come separatore e indicatore
di riferimento per il cosidetto “Spazio di validità” del dato.
In C si scriverebbe qualcosa
come:
MOVE ‘12345A’ TO MATRICOLA.
MOVE ‘12345’ TO NUMERO.
MOVE ‘A’
TO CONTROLLO.
REC-ANAG.ASSUNZIONE.DATA-ASSUNZIONE.ANNO = 1975.
05
10
10
MATRICOLA.
NUMERO
CONTROLLO
PIC 9(5).
PIC X.
Dato che il COBOL non dispone di
questo meccanismo è fortemente
consigliato differenziare i nomi dei
campi in maniera nativa, cioè chiamandoli diversamente.
Quando questo non è possibile
si ricorre alla clausula “OF” come
nell’esempio seguente:
I due campi GENERALITA e NOMINATIVO sono ridefiniti, cioè
identificano la stessa locazione di
memoria per una lunghezza di 50
caratteri alfanumerici. Mentre GENERALITA è stato sotto specificato in due sottocampi NOME e COGNOME, il campo NOMINATIVO,
che possiamo pensare come un MOVE 1975 TO ANNO OF DATA-NASCITA.
Listato 2
alias del campo GENERALITA, è
Sembra
definito come unico.
compli01 REC-ANAG.
05
TIPO-RECORD PIC XX.
cato ma
05
MATRICOLA.
Seguono tre livelli chiamati rispetti
10
NUMERO
PIC 9(5).
non lo è
10
CONTROLLO
PIC X.
vamente NASCITA, ASSUNZIONE
affatto,
05
GENERALITA.
10 NOME
PIC X(25).
e DIMISSIONI. Tutti e tre contengoanche
10 COGNOME
PIC X(25).
no una data definita con sottocampi
05
NOMINATIVO
consi
REDEFINES GENERALITA.
che hanno lo stesso nome: ANNO,
10
FILLER
PIC X(50).
derando
05
SESSO
PIC X.
MESE e GIORNO.
05
NASCITA.
che
la
10
DATA-NASCITA.
sintassi
15 ANNO
PIC 9999.
15
MESE
PIC 99.
10
DATA-NASCITA.
mantie
15 GIORNO
PIC 99.
15 ANNO
PIC 9999.
10
LUOGO-DI-NASCITA.
15 MESE
PIC 99.
ne una
15 CITTA
PIC X(25).
15 GIORNO
PIC 99.
15
CAP
PIC Z(5).
ottima
15 PROVINCIA
PIC XX.
10
DATA-ASSUNZIONE.
15
NAZIONE
PIC X(25).
leggibili15 ANNO
PIC 9999.
05
ASSUNZIONE.
15 MESE
PIC 99.
tà.
10
DATA-ASSUNZIONE.
15 ANNO PIC 99.
15 ANNO
PIC 9999.
Nel
re
15
MESE
PIC 99.
10
DATA-DIMISSIONI.
15 ANNO PIC 99.
15 ANNO
PIC 9999.
cord che
05
DIMISSIONI.
15 MESE
PIC 99.
10
DATA-DIMISSIONI.
15 ANNO PIC 99.
abbia
15 ANNO
PIC 9999.
15 MESE
PIC 99.
mo esa15 ANNO PIC 99.
Come si fa a riferirsi ad un particominato
lare anno, mese o giorno?
c o m e
19
Jurassic Book - Tullio Nicolussi - Il COBOL
esempio è presente una dichiarazione di USAGE PIC Z. Il tipo Z è
un numerico che mantiene gli zeri
non significativi. Serve nei casi in
cui, come in questo, il valore numerico sia in realtà un alfabetico di
sole cifre. Possiamo assegnare al
campo il valore 00103 e la stampa ci mostrerebbe anche i due zeri
“leading”, cioè davanti.
Per chiudere il discorso sulla
rappresentazione dei dati e cioè
sull’uso della specifica USAGE,
che a volte viene omessa facciamo
questo altri esempi significativi:
USAGE IS PIC 9(5)V99.
E’ in valore numerico con segno
con cinque cifre intere e due cifre
decimali.
USAGE IS PIC AAAXX999.
E’ un campo misto lungo otto
caratteri dei quali i primi tre sono
alfabetici (solo lettere), seguono
due caratteri alfanumerici (lettere
e numeri) e infine tre caratteri numerici.
Infine
USAGE IS PIC A(5)9(3)X(2).
PIC 999.999.999.
indica che vogliamo una rappresentazione con numeri di separazione per le migliaia.
PIC 999-.
indica che il dato è rappresentato con il segno alla fine (trailing),
un uso molto comune nelle liste di
cifre dei bilanci e il simbolo sarà
un meno se il dato è negativo, uno
spazio altrimenti.
PIC 999+.
indica che vogliamo il segno in
coda al numero ma questa volta il
segno esisterà sia per i valori positivi che per quelli negativi.
C’è un’altra forma possibile per la
rappresentazione dei valori positivi e negativi, anche se non molto
usata in Italia, ed è quella di indicare due lettere “CR” che starebbe
per “credito” e “DB” per debito.
PIC 999CR.
PIC 999DB.
La stampa di “CR” e “DB” avviene solo se il dato è negativo e non
come si potrebbe pensare DB se
negativo e CR se positivo.
PIC 999Z.
sta ad indicare che vogliamo
stampare la cifra zero a fronte di
un valore nullo.
E’ un valore che contiene cinque
caratteri alfabetici, seguiti da tre cifre ed infine due ulteriori caratteri
alfanumerici.
Nell’assegnazione dei valori sono
La clausula PICTURES, abbre- consentite delle abbreviazioni e
viata in PIC, serve anche per defi- l’uso di due costanti figurative per
nire una rappresentazione del dato lo spazio (blank) e per lo zero.
su video al momento dell’output o
VALUE IS ZERO.
della stampa.
VALUE IS ZEROES.
VALUE IS SPACE.
20
Jurassic Book - Tullio Nicolussi - Il COBOL
VALUE IS ALL SPACE.
COPY (che è l’equivalete dell’include presente in molti altri linguaggi).
La COPY permette di includere nel
sorgente un file esterno che deve
essere ovviamente ben formato.
L’uso prevalente è quello dell’inclusione di strutture dati che sono
comuni in un progetto e che più comodo condividere fra i sorgenti. Ad
esempio la descrizione di un record
da scrivere in una tabella.
La sintassi è molto semplice, la
parola COPY va inserita all’inizio
della zona B, seguita dal nome del
file da includere.
Nei moderni compilatori l’assegnazione di una stringa vuota ad una
variabile alfanumerica già la riempie di spazi (si dice in gergo che la
“filla”, dalla parola chiave FILLER),
ma i programmatori COBOL amano abbastanza queste forme che
possiamo considerare prolisse ed
obsolete ma di facile lettura.
Ecco, una delle cose affascinanti del COBOL è che i sorgenti si
possono leggere. Attenzione, non
“interpretare”, dico proprio leggere
nel senso letterale del termine. Gli
COPY ‘SCRNSELE.SKL’.
statement, se ben scritti, vanno a
comporre dei veri paragrafi in ingle- Una variante molto comoda perse che hanno un senso compiuto. mette di sostituire un pattern duAd esempio:
rante la copia. Ad esempio sostituire tutte le occorrenze di una
PERFORM CALCOLA
THRU CALCOLA-EXIT
sottostringa, operazione utilissima
VARYING INDEX FROM 1 BY 1
UNTIL INDEX IS
perché abbiamo visto che la defe
GREATER THAN MAX.
renziazione dei nomi deve essere
esplicitata. Facciamo un esempio.
è certamente più leggibile di un
Supponiamo di dover realizzare un
C:
programma che legge i recod di un
file e li scrive in un altro file, elabofor(i=1; i<=max; i++){
...
randoli ma lasciando invariata la
};
struttura del record stesso.
Il C ha dalla sua la compattezza, Se la descrizione del primo record
questo è certo, il COBOL invece è qualcosa del tipo:
assicura che fra venti anni chi legge 01 TR01.
02 TR01-CHIAVE.
il sorgente capirà benissimo cosa 02 TR01-VALORE.
diavolo il programma combina! Si La descrizione del secondo record
può dire la stessa cosa del C o di sarà ad esempio:
Java? Ne dubito molto...
01 TR02.
02 TR02-CHIAVE.
02 TR02-VALORE.
Il precompilatore.
I compilatori COBOL dispongono
Se abbiamo registrato la descriziodi un pre-compilatore che viene
ne della variabile strutturata TR01
usato quasi esclusivamente per la
su un file esterno, all’interno del norisoluzione della pseudo istruzione
21
Jurassic Book - Tullio Nicolussi - Il COBOL
stro sorgente possiamo scrivere:
COPY ‘TR01.TRC’.
COPY ‘TR01.TRC’
REPLACING ‘TR01’ BY ‘TR02’.
e sarà come avessimo definito le
due variabili nel sorgente in maniera esplicita.
cide con il loro ordine.
L’accesso ai file byte-stream o testo avviene per riga (se è un testo)
o per lettura a blocchi di lungezza
fissa.
L’uso dei file va dichiarato in due
divisioni diverse: nella ENVIRONMENT DIVISION e precisamenL’uso dei file.
te nella sezione INPUT-OUTPUT
Veniamo ora a parlare dell’argo- SECTION si dichiara una specie
mento clou che riguarda il COBOL: di puntatore al file stabilendo le
la gestione dei dati su file.
sue caratteristiche e la modalità di
Il linguaggio nasce con l’inten- accesso.
to di fornire in maniera integrata Ad esempio:
gli strumenti adatti al trattamento
delle registrazioni commerciali. E’ environment division.
configuration section.
stato il primo linguaggio (e forse source-computer. mds-800.
object-computer. mds-800.
anche l’ultimo) che nelle specifi- special-names.
console is crt.
che del compilatore richiede una input-output
section.
file-control.
gestione interna dei file indicizzaselect stock-file
assign to “stock.it”
ti, cioè gestibili come le classiche organization indexed
(ora) tabelle dei database.
access dynamic
record key stock-code.
I file gestibili sono di due tipi: file
senza indici (classico file di testo o
La sezione input-output section
file sequenziale binario) e file indicontiene una sotto-sezione chiacizzati. In questa ultima categoria
mata file-control nella quale si ditroviamo due tipi di organizzazioni:
chiarano tutti i file che si useranno
gestione sequenziale delle infornel programma. La dichiarazione
mazioni e gestione a chiave. La
avviene per mezzo della parola
gestione a chiave è un concetto
“select” seguita dal nome con il
moderno che significa in pratica
quale si identifica il file nel sorgenche i record presenti sono accessite e si “assegna” ad un file effettivo
bili in maniera dinamica attraverso
la cui sintassi dipende dalla piattal’uso di chiavi di ricerca (che per il
forma e dal compilatore.
COBOL coincidono con uno o più
campi della tabella).
organization indexed
access dynamic
L’accesso sequenziale alle inforrecord key stock-code.
mazioni significa invece che i record presenti nella registrazione Con la dichiarazione sopra risono numerati e vi si accede attra- portata diciamo al sistema che il
verso la chiave numerica che coin- nostro file è di tipo indexed, cioè
22
Jurassic Book - Tullio Nicolussi - Il COBOL
con chiave, vi accederemo in maniera dinamica attraverso la chiave
(i file indexed potrebbero essere
acceduti anche sequenzialmente).
Infine abbiamo anche informato il
compilatore che la chiave è un certo campo del record.
La dichiarazione di record, proprio
perché dichiarata nella DATA DIVISION può usarsi tranquillamente come area di lavoro. L’idea è la
seguente: si apre in Input/Output
il file, si valorizzano i campi della
struttura record e infine si scrivono
nel file.
La struttura del record si andrà a
procedure division.
dichiarare nella DATA DIVISION sr1.
display space.
in una speciale sezione chiamata
open i-o stock-file.
move ‘0001’ to stock-code.
FILE SECTION:
move ‘Computer’
data
file
fd
01
02
02
02
division.
section.
stock-file
record is stock-item.
stock-item.
stock-code
pic x(4).
product-desc pic x(24).
unit-size
pic 9(4).
“fd” è la parola chiave “file description”, stiamo descrivendo il file, dichiarato nella precedente sezione
con nome “stock-file”, appunto.
Diciamo al sistema che il record si
trova in una struttura il cui livello 01
si chiama “stock-item”.
Sotto si trova la descrizione di questo dato strutturato che è in pratica
il record della tabella. Si noti che il
campo “stock-code” del record è il
campo che sarà usato come chiave
di accesso per i record.
Attenzione: la dichiarazione senza
ulteriori specificazioni implica che
la chiave è univoca. Un eventuale
errore potrà essere gestito da programma, attraverso un meccanismo che assomiglia alle eccezioni.
In COBOL non esiste il concetto
di “campo contatore”, deve essere
gestito “a mano”, cioè è il programmatore che deve preoccuparsi di
assegnare ad ogni record una chiave diversa.
to product-desc.
move 25 to unit-size.
write stock-item
invalid key
go to errore
close stock-file.
stop run.
errore.
display ‘Chiave non valida’.
stop run.
Il frammento di codice sopra riportato effettua il lavoro che ci eravamo prefissi. Lo statement WRITE
che scrive il record nel file contiene
la gestione dell’errore. Una scrittura in file a chiave può fallire per duplicazione della chiave. Se questo
succede viene invocata il blocco di
gestione dell’errore, che nell’esempio specifico si limita a stamtare a
video un messaggio prima di terminare.
Per quanto riguarda la gestione
del file, come si vede dal codice c’è
l’azione di apertura che può essere
di tre tipi “input”, “output” e “i-o” per
stabilire rispettivamente che useremo il file come solo input, come
output o in maniera dinamica con
operazioni di leggi/scrivi a piacere.
Ovviamente si può sempre aprire
un file indexed in i-o per qualunque
23
Jurassic Book - Tullio Nicolussi - Il COBOL
job intendiamo portare a termine. Si rente.
intuisce però che la gestione della Forse vi sarà capitato di vedere,
modalità i-o sarà più pesante per il probabilmente in qualche film, le
sistema. Oggigiorno è abbastanza torri di lettura di nastri dei mainfuori uso la pratica di ottimizzare il frame con i nastri che ginvece di
codice, dato che CPU e canali di girare sempre in uno stesso verso,
i-o sono diventati enormemente come ci sia aspetterebbe, vanno
più performanti rispetto al passato, avanti ed indietro in una sorta di
tuttavia bisogna anche considera- balletto. Bene, questi movimenti
re che negli ambienti transazionali sono dati proprio dalle istruzioni di
dove si opera con il COBOL ci si lettura avanti e indietro comandate
potrebbe trovare difronte a file con dal sorgente COBOL.
milioni di record e risparmiare due Di riflesso anche l’istruzione di
millisecondi a record equivalgono chiusura CLOSE ha clausole anaad una mezzoretta in meno di ela- loghe ad esempio per riavvolgere
o meno il nastro a fine lettura.
borazione!
Il linguaggio COBOL conserva nel Un’altra “strana” caratteristica del
suo DNA dei geni che appartengo- COBOL è la lettura a blocchi dei
no ad un lontano passato, come dati.
ad esempio la gestione dei nastri Vediamo un esempio:
magnetici. Osservate questa for- ...
input-output section.
ma dell’istruzione OPEN:
file-control.
OPEN INPUT magazzino
REVERSED
Stiamo dicendo al sistema che ci
interessa aprire in input un flusso
di dati posizionando il cursore in
fono al flusso e leggendo all’indietro. Questo ha un senso per i file
sequenziali e in particolare ai dati
conservati su un nastro magnetico, periferica usatissima nelle sale
macchine dove prosperano i mainframe.
Un’altra clausola utile nei flussi su
nastro è espliccitata nell’istruzione
seguente:
OPEN INPUT magazzino
WITH NO REWIND
Che evita il riavvolgomento del
nastro e quindi la lettura del flusso
dati partendo dalla posizione cor24
select stock-file
assign to “stock.it”
organization sequential
access mode is sequential.
...
data division.
file section.
fd stock-file
label record is standard
block contain 5 records
data record is stock.
01
02
stock.
product-desc pic x(20).
working-storage section.
01 deposito.
02 dep-01 pic x(20).
02 dep-02 pic x(20).
02 dep-03 pic x(20).
02 dep-04 pic x(20).
02 dep-05 pic x(20).
procedure division.
...
read stock INTO deposito
at end go to fine-input.
L’uso dell’input blocchi rende più
efficiente la fase di lettura, come
chiunque abbia avuto a che fare
con massicce dosi di dati da leg-
Jurassic Book - Tullio Nicolussi - Il COBOL
gere saprà certamente.
A proposito di movimento a blocchi di dati incontriamo un’altra particolarità del linguaggio che è stata
conservata successivamente da
pochissimi idiomi della programmazione moderna. Stiamo parlando
della specifica CORRESPONDING
che si può usare tutte le volte che si
dovrebbero fare operazioni uguali
su dati che “si assomigliano”.
L’uso più facile da capire è all’interno dell’istruzione MOVE. Quante
volte vi sarà capitato di dover spostare selettivamente dei dati da un
record all’altro e di dover predisporre n istruzioni diverse.
Vediamo un esempio pratico. Dichiariamo due record che contengano campi con lo stesso nome:
to cognome of rec-02.
Come dovrebbe apparire chiaro
da questo esempio, lo svolgimento
dell’istruzione si basa sulla corrispondenza dei nomi nelle due strutture. Invece il campo “cod-fis” non
è stato copiato in “c-fis” del secondo record, anche se tipo, lunghezza e posizione, suggeriscono che si
tratta di due campi omologhi.
La clausola CORRESPONDING
funziona anche con istruzioni matematiche. Ad esempio:
ADD CORRESPONDING
X TO Y.
prende dalla struttura X i campi
numerici e li somma ai corrispondenti campi nella struttura Y.
01 rec-01.
02 nome pic x(20).
02 cognome pic x(25).
02 cod-fis pic x(16).
01 rec-02.
02 nome pic x(20).
02 cognome pic x(25).
02 c-fis pic x(16).
Supponiamo ora di aver caricato i
dati nella struttura rec-01, ad esempio da una lettura da file.
L’istruzione:
move corresponding
rec-01 to rec-02.
copia i due campi “nome” e “cognome” del record numero 1 nel record numero 2. Corrisponde quindi
a scrivere due istruzioni di MOVE:
move nome of rec-01
to nome of rec-02.
move cognome of rec-01
25
Jurassic Book - Tullio Nicolussi - Il COBOL
La gestione dei file
to, basti ricordare che il Wirth vi ha
dedicato un intero volume “Sorting
l fatto che il COBOL nasca con & Searching”.
l’intenzione di manipolare i file La supponenza è un pessimo diorganizzati in file (sequenzia- fetto, soprattutto per un programli o a indice, come abbiamo avuto matore, che dovrebbe secondo il
modo di spiegare), spiega l’atten- sottoscritto, conservare sempre
zione dei progettisti del linguaggio una buona dose di umiltà davanti
verso quelle procedure ricorrenti al codice. Fatto sta, per farla breche riguardano la manipolazione ve, che dopo un mese di lavoro
dei dati nelle strutture organizzate non ne era ancora uscito, anche
perché fui proprio io a fare le pulci
quali appunto i file a disco.
Una delle pratiche giornaliere che al suo codice e a scoprire i ripesi incontra nella gestione dei dati tuti bug e cali di prestazioni. Queè sicuramente quella dell’ordina- sta vicenda insegnò molto al mio
mento. Ecco allora che il COBOL collega, ma anche al sottoscritto.
I
ha implementato le procedure di
sort in maniera nativa, cioè senza ricorrere a librerie esterne o,
peggio, ad implementazioni di algoritmi che hanno due essenziali
sfortune: di solito riescono male e
in ogni caso impiegano tempo ed
energie per essere messi a punto.
Questo anche per dire che le prestazioni delle routine di sort implementate nei compilatori COBOL
sono molto efficenti ed è difficile
fare meglio...
Vediamo quali sono le linee guida per l’implementazione di un
ordinamento all’interno del codice
A questo proposito voglio raccon- COBOL.
tare le vicende di un collega (si Prima di tutto va rilevato che la
parla di oltre quindici anni fà) che procedura funziona grosso modo
si ostinò a voler fare da solo per- nella seguente maniera: si apre il
ché, secondo lui, sarebbe riuscito file da ordinare (file di input), ogni
ad avere maggiori prestazioni ri- record letto viene dato in pasto ad
spetto a quelle fornite dal compi- una routine di sort che può esselatore. Difronte ai miei consigli di re personalizzata, infine al termine
ripensarci fece spallucce e, errore della lettura dei record si fa il promadornale, non volle nemmeno cesso inverso e attraverso un loop
seguire la mia indicazione di con- di chiamate al sort si ottengono i
sultare almeno la letteratura in me- record ordinati da scrivere su un
rito, per farsi suggerire un algorit- file di output (se si vuole).
mo consolidato da implementare. Il primo passo consiste nel diC’è da dire in proposito che il sor- chiarare un file di appoggio che
ting è probabilmente la più studia- sarà usato dal SORT come area
ta procedura algoritmica in assolu- di lavoro. E’ impensabile infatti che
26
Jurassic Book - Tullio Nicolussi - Il COBOL
tutto possa svolgersi in memoria, qualunque sia la dimensione
e il numero di record da elaborare (riga 000042)Il nome del file di
sort non è significativo (al termine
dell’operazione viene comunque
cancellato); è sufficente che punti
ad un nome di file valido per il file
system (e che ci siano i necessari
privilegi di scrittura, ovviamente!).
Nella DATA DIVISION (riga
000015) troviamo la definizione
del file di input e del file di sort,
che nella maggior parte dei casi
avranno la stessa struttura del record (ma non è obbligatorio).
Queste parti dichiarative (file di
input e file di sort) sono sufficienti
per procedere con l’effettiva operazione di ordinamento che andrà
specificata all’interno della PROCEDURE DIVISION, come nelle
righe di esempio che seguono la
riga 000068 del listato 1.
Questo è un primo esempio che
non manipola i record, si limita a
restituire un file ordinato. La parola chiave SORT da inizio al procedimento che prende in input il file
da ordinare e restituisce lo stesso
file ordinato secondo le chiavi specificate come parametri del SORT.
Ovviamente è possibile un ordinamento discendente specificando la
clausola “DESCENDING KEY” invece di “ASCENDING KEY”.
...
000005 Environment Division.
000006 Configuration Section.
000007 Source-Computer. IBM-PC.
000008 Object-Computer. IBM-PC.
000009 Input-Output Section.
000010 File-Control.
000011
Select Dealer-Text Assign To “Dealer.TXT”
000012
Organization Line Sequential
000013 Access Sequential.
000014
Select Sort-Work Assign To “work.txt”.
...
000015 Data Division.
000016 File Section.
000017 Fd Dealer-Text.
000018 01 Dealer-Record.
000019 03 Dealer-Number Pic X(8).
000020
03 Dealer-Name.
000021 05 Last-Name Pic X(25).
000022 05 First-Name Pic X(15).
000042 Sd Sort-Work.
000043 01 Sort-Record.
000044 03 Dealer-Number Pic X(8).
000045 03 Dealer-Name.
000046 05 Last-Name Pic X(25).
000047 05 First-Name Pic X(15).
...
000067 Working-Storage Section.
000068 Procedure Division.
000070 Sort Sort-Work Ascending Key
Last-Name Of Sort-Record
000071 First-Name Of Sort-Record
000072 Middle-Name Of Sort-Record
000073 Using Dealer-Text
000074 Giving Dealer-Text
000075 000076 Display “Sort Complete”
Stop Run.
In quest’altro esempio che mostriamo si ottiene un file indicizzato
partendo da un file sequenziale. La
procedura potrebbe essere eseguita in modo più tradizionale, ma
vogliamo mostrare come il SORT
può essere usato anche in maniera
“non ortodossa” per fare un trasferimento di record fra due file.
Dichiariamo nella sezione FILECONTROL della INPUT-OUTPUT
Quello mostrato è il caso più sem- SECTION il file index che sarà il riplice in assoluto; non c’è bisogno sultato finale del lavoro (Listato 2,
di aprire e chiudere file, ci pensa il righe da 000014 a 000018).
SORT a compiere queste operazio- Nella DATA DIVISION descriviani.
mo l’FD e il record del file con chia27
Jurassic Book - Tullio Nicolussi - Il COBOL
ve (righe da 000020 a 000027).
L’istruzione che effettua il sort non
è dissimile da quella vista precedentemente per il file sequenziale:
Un file a chiave “Dealer-File”
sarà restiruito ordinato in un file
sequenziale “Address-File” passando attraverso un ordinamento
che fa uso di un file di appoggio
“Sort-Work”.
Il caso più generale e anche più
interessante si presenta qualora
si debbano ordinare i record ma- Abbiamo aggiunto la parte “DEnipolando in qualche modo i dati o CLARATIVES” per la gestione devolendo avere pieno controllo su gli errori sui file.
Lo statement SORT specifica che
cosa si intende per “odinamento”.
In questo caso è necessario im- l’ordinamento sarà fatto sui campi
plementare una procedura di IN- “nomi” del record di sort. Si noti
PUT che sarà responsabile del che rispetto agli esempi precedenti
passaggio del record da elaborare non viene specificato il file di input
ma al suo posto una “procedura
alla routine di SORT.
di input” che sarà usata dal SORT
Per procedere a piccoli passi moper la lettura dei dati da ordinare.
striamo l’esempio del listato 3 che
consiste nell’elaborare un odina- Il nome di questa procedura non
mento ottenendo un file sequen- è significativo, l’importante è che
ziale ordinato, partendo questa essa sia dichiarata nella PROCEvolta da un file a chiave e utilizzan- DURE DIVISION (riga 000083 e
seguenti del listato).
do una INPUT PROCEDURE.
...
000014 Select Dealer-File
Assign To “Dealer.Dat”
000015 Organization Is Indexed
000016 Record Key Dealer-Number
Of Dealer-Record
000017
Alternate Key Dealer-Name
Of Dealer-Record
000018 Access Is Sequential.
...
000020 Data Division.
000021 File Section.
000022 Fd Dealer-File.
000023 01 Dealer-Record.
000024 03 Dealer-Number Pic X(8).
000025 03 Dealer-Name.
000026 05 Last-Name Pic X(25).
000027 05 First-Name Pic X(15).
...
000067 Working-Storage Section.
000068 Procedure Division.
000070 Sort Sort-Work
Ascending Key Dealer-Number
Of Sort-Record
000072 Using Dealer-Text
000074 Giving Dealer-File
000075 Display “Sort Complete”
000076 Stop Run.
La procedura SORT-IN apre il
file di Input ed effettua un loop di
lettura di tutti i record spostando i
dati letti nel record di SORT.
Il fatto che la SORT-IN contenga l’istruzione di apertura del file
di input dovrebbe suggerire che
essa non viene eseguita n-volte
in loop, ma solamente all’inizio.
Questo è un errore molto comune fra i principianti, cioè il ritenere
che ci siano esecuzioni multiple
della routine e quindi inserire in
essa contatori o altro da elaborare. Seguire l’esecuzione in debug
è molto istruttivo in questo come
in altri casi.
In effetti seguire l’esecuzione in
28
Jurassic Book - Tullio Nicolussi - Il COBOL
...
000002
000003
000005
000006
000007
000008
000009
000010
000011
000012
000013
000014
000015
000016
000017
000018
000019
000020
000021
000022
000023
000024
000025
000026
000027
000028
000030
000031
000032
000033
000034
000048
000049
000050
000051
000052
000053
000054
000055
000056
000057
000058
000059
000060
000061
000062
000063
000064
000065
000066
000067
000068
000069
000070
000071
000072
000073
000074
Identification Division.
Program-Id. SORT03.
Environment Division.
Configuration Section.
Source-Computer. IBM-PC.
Object-Computer. IBM-PC.
Input-Output Section.
File-Control.
Select Dealer-File Assign To “Dealer.Dat”
Organization Indexed
Record Key Dealer-Number Of Dealer-Record
Alternate Record Key Dealer-Name Of Dealer-Record
Access Sequential
File Status Dealer-Status.
Select Address-File Assign To “Address.Txt”
Organization Line Sequential
Access Sequential.
Select Sort-Work Assign To Dealer-Sort-Work.
Data Division.
File Section.
Fd Dealer-File.
01 Dealer-Record.
03 Dealer-Number
Pic X(8).
03 Dealer-Name.
05 Last-Name
Pic X(25).
05 First-Name Pic X(15).
03 Address-Line-1
Pic X(50).
03 Address-Line-2
Pic X(50).
03 City
Pic X(40).
03 State-Or-Country
Pic X(20).
03 Postal-Code
Pic X(15).
Sd Sort-Work.
01 Sort-Record.
03 Dealer-Name.
05 Last-Name
Pic X(25).
05 First-Name Pic X(15).
05 Middle-Name Pic X(10).
03 Address-Line-1
Pic X(50).
03 Address-Line-2
Pic X(50).
03 City
Pic X(40).
03 State-Or-Country
Pic X(20).
03 Postal-Code
Pic X(15).
Fd Address-File.
01 Address-Record
Pic X(225).
Working-Storage Section.
01 Done-Flag
Pic X Value Spaces.
88 All-Done
Value “Y”.
01 Dealer-Status Pic XX Value “00”.
Procedure Division.
Declaratives.
Dealer-File-Error Section.
Use After Standard Error Procedure On Dealer-File.
Dealer-Error.
Display “Unhandled error on Dealer File “ Dealer-Status
Set All-Done To True
.
End Declaratives.
SORT03-Start.
29
Jurassic Book - Tullio Nicolussi - Il COBOL
...
000074 SORT03-Start.
000075
Sort Sort-Work Ascending Key Last-Name Of Sort-Record
000076
First-Name Of Sort-Record
000077
Middle-Name Of Sort-Record
000078
Input Procedure Sort-In
000079
Giving Address-File
000080
Display “Sort Complete”
000081
Stop Run
000082
.
000083 Sort-In.
000084
Open Input Dealer-File
000085
Perform Until All-Done
000086
Read Dealer-File
000087
At End Set All-Done To True
000088
Not At End
000089
If State-Or-Country Of Dealer-Record = “CA”
000090
Move Corresponding Dealer-Record To Sort-Record
000091
Release Sort-Record
000092
End-If
000093
End-Read
000094
End-Perform
000095
Close Dealer-File
000096
.
debug del proprio codice è un consiglio che do sempre ai miei allievi:
serve ad acquisire una consapevolezza di come vengono interpretate le sequenze di istruzioni che abbiamo impostato nel codice. E’ più
un aspetto psicologico che pratico
e mi sono fatta la convinzione che
serva a far capire come la macchina sia una estensione delle nostre
capacità mentali e non un oggetto
staccato dalle nostre percezioni.
Un punto chiave della routine
SORT-IN è l’istruzione “RELEASE” che invia il record da elaborare al sort. Qui si capisce come
sia possibile pre-elaborare i dati
di input prima di decidere se passarli al sort oppure eventualmente
scartarli del tutto.
E’ anche possibile elaborare i record al termine del sort; in questo
caso si costruisce una routine di
30
OUTPUT.
Nel listato 4 abbiamo modificato
lo statement SORT inserendo la
routine personalizzata di output
SORT-OUTPUT.
L’esempio non usa un SORT-IN,
ma potrebbe farlo. Le due routines
SORT-IN e SORT-OUT possono
tranquillamente convivere.
Lo statement chiave è RETURN:
Return Sort-Work Into DealerRecord
Esso riceve dal SORT un record
alla volta secondo l’ordinamento
stabilito ed è quindi l’occasione per
procedere ad una elaborazione
dei record ordinati, non necessariamente con una scrittura su file.
Jurassic Book - Tullio Nicolussi - Il COBOL
...
000072 SORT04-Start.
000073
Sort Sort-Work Ascending Key Dealer-Number Of Sort-Record
000074
Using Dealer-Text
000075
Output Procedure Sort-Out
000076
Display “Sort Complete with “ Record-Count “ Records.”
000077
Stop Run
000078
.
000079 Sort-Out.
000080
Open Output Dealer-File
000081
Perform Until All-Done
000082
Return Sort-Work Into Dealer-Record
000083
At End Set All-Done To True
000084
Not At End
000085
Add 1 To Record-Count
000086
Move Zeros To Last-Sold-Amount
000087
Last-Sold-Date
000088
Sold-To-Date
000089
Commission-To-Date
000090
Write Dealer-Record
000091
End-Return
000092
End-Perform
000093
Close Dealer-File
000094
.
31
Jurassic Book - Tullio Nicolussi - Il COBOL
La gestione del video
U
na delle cose che non si
è potuto standardizzare nel linguaggio e che
di fatto ha impedito al COBOL di
diventare una vera applicazione
cross-platform è la gestione del
video.
La nascita del linguaggio risale
all’epoca in cui il batch la faceva
da padrone e l’input dell’utente veniva limitato di proposito, proprio
per la difficoltà e il costo di questo tipo di elaborazione. Quindi ad
esempio era uso prendere i parametri dall’esterno prima del lancio
dell’eseguibile vero e proprio; non
per nulla i sistemi IBM usano linguaggi di shell molto articolati e
potenti (capaci ad esempio di creare file a chiave).
Questo sotto-standard ha teorizzato l’esistenza di una sezione chiamata SCREEN SECTION
nella quale si descrive il video, o
meglio i campi di input-output che
si vogliono rappresentare in esso.
A questo punto una unica istruzione DISPLAY stampa a video l’intera immagine della sezione e un
ACCEPT FROM attiverà il dialogo
user-oriented.
Chiaro che l’avvento di sistemi
graphics-enabled e dei PC in particolare ha complicato la vita dei
produttori che infatti hanno scelto
ognuno per conto proprio delegando la user interface a librerie
proprietarie più o meno complete.
Torniamo alla nostra “quasi standard” SCREEN SECTION per definirne le caratteristiche.
La SCREEN SECTION viene inserita all’interno della DATA DIVIIl verbo ACCEPT sembrava l’uni- SION subito dopo la WORKINGca possibilità di implementare il STORAGE SECTION. Ecco un
classico dialogo utente, se pur con esempio nel listato 1.
le limitazioni che potete immaginaIl listato 1 mostra in realtà solo la
re. Anche il più recente BASIC si
parte di definizione generale della
è scontrato con questa difficoltà e
sezione. Si intuisce che i parameinfatti le varie istruzioni di INPUT,
tri specificano alcune caratteristiINKEY, etc... sono proprietarie di
che come la pulizia del video priogni sistema.
ma dell’emissione (Blank Screen),
Da questo scenario si sono di- il colore di sfondo e quello dei castaccati i compilatori eseguibili su ratteri, etc...
UNIX, grazie ad un accordo extraI colori sono standardizzati seansi fra i produttori e naturalmente
condo la tabella seguente:
grazie al fatto che UNIX viene naBlack
0
tivo con una sua gestione video a
Blue
1
finestre (le classiche librerie CurGreen
2
ses, oltre alla standardizzazione
Cyan
3
dei caratteri di controllo sul termiRed
4
nale).
32
Jurassic Book - Tullio Nicolussi - Il COBOL
Magenta
Brown
White
5
6
7
000020 Screen Section.
000021 01 My-Main-Screen
000022 Blank Screen, Auto, Required,
000023 Foreground-Color is 7,
000024
Background-Color is 1.
Mentre la seguente tabella riporta il significato degli attributi
generali:
Blank Screen
Foreground-Color
Background-Color
Sign
Usage
Auto
Full
Secure
Required
Listato 1
Pulisce lo schermo prima dell’emissione
Imposta il colore dei caratteri
Inposta il colore di sfondo
definizione di come saranno mostrati i campi
numerici con segno
Impostazione globale dei campi numerici per
l’intero screen
Il cursore si sposta sul prossimo campo quando
si è riempito quello precedente
Tutti i campi del livello devono essere riempiti
I caratteri digitati non sono mostrati (stile password)
I campi sono obbligatori
Nel listato 2 sono state aggiunte due definizioni di campi alla section.
Oltre alle “label”, cioè alle scritte fisse, i campi di input sono in questo
caso due: PREZZO e DESCRIZIONE. I campi devono essere descritti
nella Working-Storage Section in maniera opportuna.
Nel listato 3 un esempio completo di utilizzo della Screen Section.
Listato 2
000020 Screen Section.
000021 01 My-Main-Screen
000022 Blank Screen, Auto, Required,
000023 Foreground-Color is 7,
000024
Background-Color is 1.
000025
03 Line 01 Column 27 Value “Name and Address Entry”
000026
Underline.
000027
03 Line 3 Column 5 Value “Last Name “ Highlight Bell.
000019 03 Line 3 Column 16 Pic $$,$$$.99 From Prezzo.
000020
03 Line 5 Column 5 Value “Item Description” Highlight.
000021
03 Line 5 Column 22 Pic x(10) From Descrizione.
33
Jurassic Book - Tullio Nicolussi - Il COBOL
000002 Identification Division.
000003 Program-Id. Lezione05.
000004
000005
000006
000007
Environment Division.
Configuration Section.
Source-Computer. IBM-PC.
Object-Computer. IBM-PC.
000008 Data Division.
000009 Working-Storage Section.
000010 01 Prezzo
Pic 9(5)v99 Value 12.99.
000011 01 Descrizione
Pic X(10) Value “Gold Coins”.
000012 Screen Section.
000013 01 Main-Screen
000014 Blank Screen, Auto, Required,
000015 Foreground-Color is 7,
000016
Background-Color is 1.
000017
03 Line 1 Column 35 Value “Item Entry”.
000018
03 Line 3 Column 5 Value “Item Value “ Highlight Bell.
000019 03 Line 3 Column 16 Pic $$,$$$.99 From Prezzo.
000020
03 Line 5 Column 5 Value “Item Description” Highlight.
000021
03 Line 5 Column 22 Pic x(10) From Descrizione.
000025 Procedure Division.
000026 Lezione05-Start.
000027
Display Main-Screen.
000028
Stop Run.
Listato 3
esterne attraverso la parola chiaDiverso, come dicevamo, il caso ve “CALL”, hanno potuto dotare i
dei compilatori per PC che sono loro prodotti di una gestione video
apparsi dopo il 1980. Per qualche “decente”.
ragione le ditte leader nel settore Nella pratica in dotazione al commainframe (ad esempio la IBM o pilatore era dato un “disegnatore
la Microfocus per Unix), non pen- di maschere video”. La schermasarono subito al trasporto dei loro ta così costruita viene salvata in
compilatori nell’ambiente personal qualche formato in una libreria di
che si stava profilando. Questo a maschere o anche come file sinpermesso la comparsa di altri at- golo, aperta e inizializzata al motori che si sono presto specializza- mento dell’utilizzo ed infine chiusa
ti (la Microsoft è stata fra questi,
anche se nella “seconda ondata”).
Questi si sono inventati di sana
pianta una gestione del video più
confacente all’ambiente interattivo
di una macchina personale, anche
per adeguare la loro offerta con altri compilatori meglio dotati in questo senso (basta pensare al Turbo Pascal, tanto per menzionarne
uno).
Sfruttando le chiamate a librerie
34
e rilasciata. I campi definiti a livello
di disegno corrispondono ad altrettante aree video della WorkingStorage (più raramente della Screen Section).
Vediamo un frammento di codice
(listato 4) che esplica quanto detto. Il sorgente è “castrato” per mostrare solo le parti che interessano
la gestione della maschera video.
Sono dichiarate due strutture: la
Jurassic Book - Tullio Nicolussi - Il COBOL
1
1
/*****************************************************************
DATA DIVISION.
******************************************************************
WORKING-STORAGE SECTION.
*****************************************************************
01
FILETAB.
02
FILETAB-NFILE
<COMP5> VALUE 5.
02
MASKLIB-FCB.
03
MASKLIB-DDNAME
PIC X(10) VALUE ‘MASKLIB’.
03
MASKLIB-DSNAME
PIC X(72) VALUE SPACES.
03
MASKLIB-HANDLE
PIC X(4) VALUE LOW-VALUES.
03
MASKLIB-STATUS
<COMP5>
VALUE ZERO.
01
02
02
03
03
03
03
02
03
03
03
03
03
02
03
03
04
04
04
04
04
03
04
05
06
06
03
04
MASK-1.
M1-NOME-MASK
PIC X(8) VALUE ‘UT0115M1’.
M1-WTRD.
M1-CURSORE
PIC 9(4).
M1-ULT-CAMPO
PIC 9(4).
M1-RET-CODE
PIC 9.
M1-FUNCT-KEY
PIC 99.
M1-INIZ
REDEFINES M1-WTRD.
M1-RIG
<COMP5>.
M1-COL
<COMP5>.
M1-COLORE
<COMP5>.
M1-MODO
<COMP5>.
FILLER
PIC 9(3).
M1-DATI.
M1-OPCODE
PIC X(3).
M1-TESTATA.
M1-MODALITA
PIC X(10).
M1-COLLEZ-NAME
PIC X(10).
M1-CODICE
PIC X(8).
M1-DESCRIZIONE
PIC X(40).
M1-MODE
PIC X(3).
M1-TABELLA.
FILLER
OCCURS 20.
M1-RIGA-SEL.
M1-RS-FIRSTCHAR
PIC X.
FILLER
PIC X(79).
M1-TAB-RED
REDEFINES M1-TABELLA.
M1-TAB-CHAR
OCCURS 1600 PIC X.
/****************************************************************
PROCEDURE DIVISION.
* --------------------------------------------------------------MAIN SECTION.
INIZIO.
CALL ‘SCRNOPEN’ USING MASKLIB-DSNAME RET-CODE.
CALL ‘SCRNINIT’ USING MASK-1.
CALL ‘SCRNWTRD’ USING MASK-1.
PERFORM ELABORA THRU ELABORA-EXIT.
CALL ‘SCRNCLOSE’.
USCITA.
STOP RUN.
ELABORA.
......
ELABORA-EXIT.
EXIT.
Listatop 4
35
Jurassic Book - Tullio Nicolussi - Il COBOL
Lo splash screen del tool
SMSED, lo screen editor
in dotazione al Visual Cobol della MBP.
prima è la libreria delle maschere
dove è stata preparata quella che
andremo ad usare nel codice; la
seconda struttura è la parte dati
della maschera stessa, generata
dal programma di disegno video e
importata nel sorgente.
breria.
La chiamata SCRNWTRD apre
il dialogo, nel senso che emette
la maschera a video ed aspetta
l’input. Il dialogo viene interrotto
dall’uso di un tasto funzione che
andrà poi testato nel successivo
loop di elaborazione.
Nella PROCEDURE DIVISION si
inizia aprendo la librerie e inizializ- Al termine del programma si chiuzando il video. Sono le due CALL de il video e... “si va a casa” con la
iniziali a routines predisposte nelle SCRNCLOSE.
librerie del compilatore.
Come si vede una modalità abE’ facile intuire che la funzio- bastanza agevole nell’utilizzo, tanne SCRNOPEN sta per “screen to efficace da essersi poi imposta
Open” e la SCRNINIT effettua le come normale dotazione dei comoperazioni di inizializzazione della pilatori su PC.
maschera video il cui nome MASKPer la cronaca questo esempio è
1 è stato inserito nella struttura di
stato tratto da un compilatore chiadescrizione della maschera stesmato Visual Cobol della tedesca
sa, esattamente nel campo M1MBP.
NOME-MASK che è valorizzato a
“UT0115M1” (il nome con il quale
è stata salvata la maschera nella li36
Jurassic Book - Tullio Nicolussi - Il COBOL
Due fasi della creazione
di una maschera video.
Sotto la scelta del nome
e della libreria, sopra
l’editor full screen.
Siamo quindi giunti alla conclusione di questa stringata ma completa
presentazione di uno dei più diffusi linguaggi di programmazione del
passato. Riprendendo il discorso iniziale mi piace ribadire la validità tuttora presente di un idioma che ha saputo superare più di una moda
e, seppure con notevole sforzo, adattarsi ai nuovi paradigmi della programmazione visuale, per eventi ed infine ad oggetti.
Tullio Nicolussi
37