IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Cobol Discussion :

Un exercice complet


Sujet :

Cobol

  1. #1
    Membre à l'essai Avatar de Obelix84
    Homme Profil pro
    Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)
    Inscrit en
    octobre 2019
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)

    Informations forums :
    Inscription : octobre 2019
    Messages : 15
    Points : 20
    Points
    20
    Par défaut Un exercice complet
    Bonjour les cobolistes,

    ceci est mon premier message sur ce forum. J'ai pratiqué le cobol entre 1968 et 1998 sur mainframe (MVS/IBM et GCOS7/Bull) ainsi que sur micro (WIN 3.1 sous DOS 6.22). Pendant ces 30 ans, j'ai eu diverses casquettes, développeur, Ingénieur système et d'exploitation, analyste, responsable de projets en utilisant essentiellement Cobol, assembleur, Clist et Rexx. Je suis parti à la retraite en 2004 cela fait donc 15 ans que j'ai perdu tout contact avec le monde du travail. On peut dire que depuis 21 ans je n'ai plus fait de COBOL, ni même pratiqué un autre langage, à l'exception très récente de macros sous Word en VsBasic.

    De lire ce forum m'a donné l'envie de refaire un peu de Cobol. Je disposais à l'époque d'un compilateur Microfocus (V4.0) installé sur ce qu'on peut appeler maintenant un très ancien portable. Sur cet engin qui fonctionne toujours est installé un DOS 6.22 et un Windows 3.1 et ce COBOL cadeau à l'époque d'une société pour laquelle j'avais travaillé. J'ai tout gardé, disquettes d'install, documentations et la licence. Comme il n'était pas question de réutiliser ce portable, j'ai cherché comment installer cette ancienne version du Cobol sur une machine récente. Après quelques tentatives non convainquantes avec VirtualBox j'ai opté pour DosBox. Comme j'ai réussi à télécharger une version gratuite de SPFPC (4.07), je dispose d'un environnement complet : Compilateur et éditeur performant sous DOS avec la possibilité d'édition directe avec mon Windows 10.

    Pour me refaire la main j'ai feuilleté le forum et trouvé cette discussion:
    https://www.developpez.net/forums/d2...ichier-sortie/
    où il était décrit un exercice qui m'a semblé suffisamment complet et intéressant pour être réalisé.
    J'ai réveillé mes souvenirs, retrouvé quelques reflexes de codage ainsi que le plaisir d'utiliser SPF (même sur PC c'est super!). J'ai donc écrit et testé le programme que j'ai appelé EXO. Pour ne pas polluer le thread de Elosam782, je vous le soumet ici.

    Je me suis attaché à faire une réalisation comme si j'étais dans un contexte de production réelle en tenant compte des divers problèmes, gestion des I/O et données mal contrôlées qui font planter les programmes... (vieux réflexes d'exploitant)

    Le résultat est opérationnel. Dites-moi ce que vous pensez de mon code et si mes techniques vieilles de 30 ans sont encore d'actualité et ce qu'il me faudrait améliorer pour être crédible de nos jours comme développeur. J'ai tout mis dans un pack Zippé qui comprend une doc d'information, les programmes Cobol ainsi que les fichiers entrées et sorties utilisés pendant les tests.

    Merci d'avance.

    EXO.zip

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Ingénieur d'Etude Mainframe/AS400
    Inscrit en
    novembre 2012
    Messages
    1 620
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur d'Etude Mainframe/AS400
    Secteur : Finance

    Informations forums :
    Inscription : novembre 2012
    Messages : 1 620
    Points : 10 076
    Points
    10 076
    Par défaut
    Bonjour, ton code est bien indenté et clair. Pour ma part, je remplacerais juste le GOTO (à proscrire même si dans ton cas il n'est pas réellement gênant) RETOUR par un PERFORM RETOUR. Et dans ce paragraphe, j'utiliserais un GOBACK à la place du top run (c'est ce qui m'a toujours été conseillé). C'est sympathique de voir quelqu'un retourner vers COBOL après toutes ces années ! Tu pourras peut-être apporter ton expérience à cette partie du forum.

  3. #3
    Membre à l'essai Avatar de Obelix84
    Homme Profil pro
    Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)
    Inscrit en
    octobre 2019
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)

    Informations forums :
    Inscription : octobre 2019
    Messages : 15
    Points : 20
    Points
    20
    Par défaut
    Merci pour cette réponse.

    Concernant les GO TO RETOUR, ce serait plutôt GO TO SANS-RETOUR...! Ce sont les seuls GO TO que je me suis permis pour bien marquer qu'il y aura une sortie définitive du programme. PERFORM est moins définitif puisqu'il peut y avoir un retour à l'appelant.

    Concernant GOBACK à la place de STOP RUN. Pourquoi pas! L'utilisation du STOP RUN découle d'une longue et ancienne habitude.
    J'utilise GOBACK dans le cas des SP externes appelés par CALL.
    Maintenant j'ai lu quelque part dans la doc de Microfocus que le STOP était obsolete (déjà à l'époque entre 1985 et 1988 puisque la brochure référence les normes du cobol85 et ne va au-delà de 1988). IL faut donc bien sûr éviter de l'utiliser.

    OK je prend note.

    Pour la participation au forum, j'y compte bien!

  4. #4
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    6 940
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 6 940
    Points : 21 866
    Points
    21 866
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    Quelques remarques de mémoire car je n'ai plus de compilateur COBOL sous la main depuis longtemps déjà

    Procédure division :
    - les sections dans la procédure division n'ont plus de raison d'être. Elles existent toujours pour compatibilité déscendante uniquement.
    Attention toutefois : si vous faites un perform d'une section, alors tous les paragraphes de cette section seront exécutés avant retour.
    Pour info, les sections servaient autrefois, quand la mémoire RAM était très limitée et très chère, à segmenter les portions de code à monter en mémoire.

    - déclaratives : je ne suis pas partisan d'une gestion uniforme des exceptions (idem pour les "handle conditions" en cobol-cics). Je préfère nettement, même si c'est un peu plus long à coder, un test du file-status après chaque ordre (OPEN, CLOSE, READ, WRITE...) avec un message d'erreur numéroté (de façon unique bien sur) et un peu de texte de diagnostic avant appel de la routine d'abend.

    - appel de modules par CALL. Autrefois, si le nom du module était entre quotes (simples et non pas doubles, mais peut-être que sur COBOL Microfocus il en va autrement), alors il s'agissait d'un appel statique.
    Pour un appel dynamique, il fallait alimenter une variable et faire un CALL à cette variable. À vérifier dans votre contexte.


    Data division :
    - point de détail qui avait autrefois son importance et que je rappelle pour les puristes : une variable déclarée en niveau "01" s'aligne sur une frontière de 16 octets. Donc, pour du PIC X(1) on gâche 15 octets... C'est ballot. C'est pourquoi, pour les différents indicateurs de travail, file-status et autres données courtes, je préférais déclarer un filler de niveau "01" dans lesquels je rangeais dans des sous-niveaux les variables de travail.

    - quand une variable de niveau X est décomposée en sous-parties, j'avais pour habitude de conserver un radical commun pour faciliter les recherches.
    ainsi, par exemple, plutôt que de déclarer
    05 DATE-NAISSANCE-LU REDEFINES Z2-LU.
    009700        10 JJ-LU            PIC 9(02).
    009800        10 MM-LU            PIC 9(02).
    009900        10 AA-LU            PIC 9(04).
    je préfère
    05 DATE-NAISSANCE-LU REDEFINES Z2-LU.
    009700        10 DATE-NAISSANCE-LU-JJ            PIC 9(02).
    009800        10 DATE-NAISSANCE-LU-MM            PIC 9(02).
    009900        10 DATE-NAISSANCE-LU-AA            PIC 9(04).
    ainsi la recherche de DATE-NAISSANCE-LU me permet de retrouver tout le code concerné en une seule fois plutôt que de faire 4 recherches

    - vous avez eu la sagesse de ne pas nommer votre index "I" ou "J" comme on le voit trop souvent ce qui rend les recherches pénibles dans le code.

  5. #5
    Membre expert
    Homme Profil pro
    Ingénieur Exploitation Mainframe
    Inscrit en
    octobre 2005
    Messages
    1 441
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur Exploitation Mainframe
    Secteur : Finance

    Informations forums :
    Inscription : octobre 2005
    Messages : 1 441
    Points : 3 164
    Points
    3 164
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    Bonjour, ...
    Toujours les même "lubies" d'escartefigue concernant le COBOL. Certaines ressortent de l'opinion, et donc discutables, d'autres sont carrément fausses ...

    Par exemple ;

    Pour un appel dynamique, il fallait alimenter une variable et faire un CALL à cette variable. À vérifier dans votre contexte.
    Sur z/OS, c'est faux depuis bien longtemps.
    Le caractère statique ou dynamique d'un appel de sous programme par CALL litteral dépend de l'option DYNAM / NODYNAM du compilateur.

  6. #6
    Membre à l'essai Avatar de Obelix84
    Homme Profil pro
    Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)
    Inscrit en
    octobre 2019
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)

    Informations forums :
    Inscription : octobre 2019
    Messages : 15
    Points : 20
    Points
    20
    Par défaut
    Merci d'avoir pris la peine de répondre.

    Citation Envoyé par escartefigue Voir le message
    Procédure division :
    - les sections dans la procédure division n'ont plus de raison d'être. Elles existent toujours pour compatibilité déscendante uniquement.
    Attention toutefois : si vous faites un perform d'une section, alors tous les paragraphes de cette section seront exécutés avant retour.
    Pour info, les sections servaient autrefois, quand la mémoire RAM était très limitée et très chère, à segmenter les portions de code à monter en mémoire.
    Effectivement les sections en PROCEDURE DIVISION ne sont plus très utiles. Cette habitude de mettre une section pour les déclaratives vient de loin et j'avoue ne pas m'y être replongé plus avant. Je pensais même que les sections pour les déclaratives était une structure imposée. Comme tout a bien fonctionné pendant mes tests je ne me suis pas cassé la tête là-dessus. Je vais essayer quelques tests pour supprimer ces sections.

    Citation Envoyé par escartefigue Voir le message
    - déclaratives : je ne suis pas partisan d'une gestion uniforme des exceptions (idem pour les "handle conditions" en cobol-cics). Je préfère nettement, même si c'est un peu plus long à coder, un test du file-status après chaque ordre (OPEN, CLOSE, READ, WRITE...) avec un message d'erreur numéroté (de façon unique bien sur) et un peu de texte de diagnostic avant appel de la routine d'abend.
    Pour les DECLARATIVES et la gestion des exceptions, ne pas centraliser est une question de feeling. Mais dans un contexte de production, c'est très pratique et cela permet une normalisation des situations d'exception. Personnellement je préfère ce choix.

    Citation Envoyé par escartefigue Voir le message
    - appel de modules par CALL. Autrefois, si le nom du module était entre quotes (simples et non pas doubles, mais peut-être que sur COBOL Microfocus il en va autrement), alors il s'agissait d'un appel statique.
    Pour un appel dynamique, il fallait alimenter une variable et faire un CALL à cette variable. À vérifier dans votre contexte.
    Effectivement un appel dynamique est toujours réalisé avec une variable. Dans l'autre cas cela dépend d'options de compilation et de link. Mon choix est de faire un call dynamique systématiquement. Je vais donc utiliser des variables pour ne pas me poser de questions

    Citation Envoyé par escartefigue Voir le message
    Data division :
    - point de détail qui avait autrefois son importance et que je rappelle pour les puristes : une variable déclarée en niveau "01" s'aligne sur une frontière de 16 octets. Donc, pour du PIC X(1) on gâche 15 octets... C'est ballot. C'est pourquoi, pour les différents indicateurs de travail, file-status et autres données courtes, je préférais déclarer un filler de niveau "01" dans lesquels je rangeais dans des sous-niveaux les variables de travail.
    C'était justement pour cette particularité qu'à l'époque j'utilisais les niveau 01. En cas de DUMP c'était nettement plus pratique pour s'y retrouver (du moins dans mon souvenir). Vu les tailles de mémoire ça n'a plus d'importance.

    Citation Envoyé par escartefigue Voir le message
    - quand une variable de niveau X est décomposée en sous-parties, j'avais pour habitude de conserver un radical commun pour faciliter les recherches.
    ainsi, par exemple, plutôt que de déclarer
    05 DATE-NAISSANCE-LU REDEFINES Z2-LU.
    009700        10 JJ-LU            PIC 9(02).
    009800        10 MM-LU            PIC 9(02).
    009900        10 AA-LU            PIC 9(04).
    je préfère
    05 DATE-NAISSANCE-LU REDEFINES Z2-LU.
    009700        10 DATE-NAISSANCE-LU-JJ            PIC 9(02).
    009800        10 DATE-NAISSANCE-LU-MM            PIC 9(02).
    009900        10 DATE-NAISSANCE-LU-AA            PIC 9(04).
    ainsi la recherche de DATE-NAISSANCE-LU me permet de retrouver tout le code concerné en une seule fois plutôt que de faire 4 recherches
    Bien sûr c'est pratique pour s'y retrouver, mais la contrepartie c'est la longueur des noms et le temps de codage qui en résulte. En ce qui me concerne je fais en sorte que les noms soient suffisament clairs pour savoir de quoi on parle quand on code sans avoir à se référer en permanence aux déclarations et cela me suffit.

    Citation Envoyé par escartefigue Voir le message
    - vous avez eu la sagesse de ne pas nommer votre index "I" ou "J" comme on le voit trop souvent ce qui rend les recherches pénibles dans le code.
    Pour être très honnête j'avais lu des interventions d'Escartefigue... et trouvé la remarque judicieuse. Avant j'utilisais comme tout le monde "I", "j", et autres "X" et "Y"...

  7. #7
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    6 940
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 6 940
    Points : 21 866
    Points
    21 866
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Obelix84 Voir le message
    Bien sûr c'est pratique pour s'y retrouver, mais la contrepartie c'est la longueur des noms et le temps de codage qui en résulte. En ce qui me concerne je fais en sorte que les noms soient suffisament clairs pour savoir de quoi on parle quand on code sans avoir à se référer en permanence aux déclarations et cela me suffit.
    C'est que j'ai repris votre code et comme, tout comme vous, je n'aime guère les noms à rallonge, j'aurais tout simplement choisi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    01  DDN-LU.
        02 DDN-LU-JJ PIC XX.
        02 DDN-LU-MM PIC XX.
        02 DDN-LU-AA PIX XX.

  8. #8
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    6 940
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 6 940
    Points : 21 866
    Points
    21 866
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Obelix84 Voir le message
    C'était justement pour cette particularité qu'à l'époque j'utilisais les niveau 01. En cas de DUMP c'était nettement plus pratique pour s'y retrouver (du moins dans mon souvenir). Vu les tailles de mémoire ça n'a plus d'importance.
    J'ai connu cette époque où les dumps n'étaient pas formatés, quelle galère d'y retrouver ses petits dans les adresses hexa, en particulier dans les dumps sous DL1 ou il fallait appliquer un déplacement de l'adresse du verbe.
    Mais tous ceux qui avaient un peu d'expérience, utilisaient à l'époque des balises dans la working pour s'y retrouver comme par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    01   FILLER   PIC X(28) VALUE '*** DEB WSS PROG001 ***'.
    Ces quelques balises facilitaient la recherche dans le dump mais prenaient un peu de place mémoire, place qu'on récupérait largement grâce aux astuces liées à l'usage de types appropriés de données, de niveau "01" uniquement quand nécessaire et aussi de niveau "77" qui à l'origine utilisaient de la mémoire contiguë non alignée sur 16 octets. Ce n'est plus vrai de nos jours : les niveaux "77" ont exactement le même comportement que les niveaux "01" de ce point de vue même si on ne peut toujours pas les découper en niveaux inférieurs contrairement aux niveaux "01".

    Citation Envoyé par Obelix84 Voir le message
    Pour être très honnête j'avais lu des interventions d'Escartefigue... et trouvé la remarque judicieuse. Avant j'utilisais comme tout le monde "I", "j", et autres "X" et "Y"...
    Heureux d'avoir pu rendre service

  9. #9
    Membre à l'essai Avatar de Obelix84
    Homme Profil pro
    Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)
    Inscrit en
    octobre 2019
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)

    Informations forums :
    Inscription : octobre 2019
    Messages : 15
    Points : 20
    Points
    20
    Par défaut Précision sur les DECLARATIVES
    Après consultation de la brochure (COBOL85) sur le sujet et si j'interprète bien l'anglais, la PROCEDURE DIVISION se compose de déclaratives et de procédures.
    Les déclaratives doivent être groupées au début de PROCEDURE DIVISION entre:
    DECLARATIVES.
    END DECLARATIVES.

    USE AFTER STANDARD ERROR... pour intercepter les erreurs I/O implique l'obligation pour USE d'être la première "instruction" (en fait c'est une information fournie au compilateur) d'une section dans les DECLARATIVES. Dans cette même section viennent ensuite les paragraphes de procédures utilisées pour traiter l'erreur.

    Les procédures commencent immédiatement après END DECLARATIVES et se terminent soit à la fin physique des lignes de programme, soit à la rencontre de END PROGRAM.

    D'utiliser USE implique donc l'emploi des sections. Je ne changerai donc pas mon code

Discussions similaires

  1. recherche exercices sqlalchemy complets
    Par buffalo974 dans le forum Bibliothèques tierces
    Réponses: 0
    Dernier message: 27/10/2016, 10h49
  2. exercice ou tp complet
    Par LeBadaking dans le forum C++/CLI
    Réponses: 0
    Dernier message: 14/11/2012, 16h53
  3. exercices C complets
    Par LeBadaking dans le forum C
    Réponses: 7
    Dernier message: 24/10/2012, 18h49
  4. [XL-2007] Exercice complet sous VBA
    Par nanou60350 dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 05/12/2010, 21h50
  5. Pouvez vous m'aider a resoudres ces 3 exercices
    Par algorithmique dans le forum Algorithmes et structures de données
    Réponses: 11
    Dernier message: 09/08/2002, 17h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo