issue100:programmer_en_cobol
Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
issue100:programmer_en_cobol [2015/08/30 14:50] – créée auntiee | issue100:programmer_en_cobol [2015/09/01 17:25] (Version actuelle) – andre_domenech | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | **Programming in COBOL | ||
+ | |||
Ubuntu users are a modern people. We use tablets and smartphones that didn't exist ten years back. We wait impatiently for each succeeding version of Ubuntu to be more revolutionary than the last version, a mere six months back. Is this not progress? Is this not what the fast-paced twenty-first century is all about? | Ubuntu users are a modern people. We use tablets and smartphones that didn't exist ten years back. We wait impatiently for each succeeding version of Ubuntu to be more revolutionary than the last version, a mere six months back. Is this not progress? Is this not what the fast-paced twenty-first century is all about? | ||
- | Writing about a programming language such as COBOL may come out as a bit odd. After all, the Common Business-Oriented Language was born in the year 1959, sometime during those Dark Ages when programming did not mean running a JavaScript in a Web browser, and computing was not all about connecting | + | Writing about a programming language such as COBOL may come out as a bit odd. After all, the Common Business-Oriented Language was born in the year 1959, sometime during those Dark Ages when programming did not mean running a JavaScript in a Web browser, and computing was not all about conning |
- | Just before year 2000 and the infamous "y2k bug" that was supposed to bite us all in the nose (but never quite did – because we were prepared for it!) it came to the attention of many IT department heads that a sizable portion of computer programs in use had been originally written in COBOL. This was true mainly in the finance industry. Having been passed from one generation of hardware to another, and recompiled several times in the process, the programs handled most core processes and were well placed to last longer than the human programmers that had created them in the first place – and who were at that time heading towards retirement, if not already there. A scarcity of programmers of the younger generations able to comprehend, let alone maintain, code written in COBOL, seemed to be on the cards. Fifteen years on, this still seems to be a bit of a concern even in year 2015, at least according to some. However, a large part of the programs must have needed to be re-written at some point if only to adapt to the needs of e-banking and e-business, and writing newer programs from scratch in COBOL is less often seen these days. | + | ====== Programmer en COBOL ====== |
- | However, the COBOL language still seems to have been maintained, with even an object-oriented version being announced in 2002, and a more advanced standard published in 2014. IBM seems to be a major player in the field, although it also gives active support to other offerings (such as Java) for programming mainframes. On the GNU/Linux side, OpenCOBOL (http://www.opencobol.org/ | + | Nous, les utilisateurs d' |
- | It was mainly from a standpoint of historical interest that I installed this compiler, and managed to get an Euclidian Algorithm program up and running quite easily, with procedure calls and even some invocation of routines written in the C language by the side. | + | Il peut donc sembler assez bizarre d' |
- | Installation | ||
- | Installation is the usual procedure on *buntu systems, since OpenCOBOL is available directly | + | **Just before year 2000 and the infamous " |
- | aptitude install open-cobol | + | However, the COBOL language still seems to have been maintained, with even an object-oriented version being announced in 2002 and a more advanced standard published in 2014. IBM seems to be a major player on the field, although it also gives active support to other offerings (such as Java) for programming mainframes. On the GNU/Linux side, OpenCOBOL (http:// |
- | When this is installed, | + | It was mainly from a standpoint of historical interest that I installed |
- | cobc --version | + | Juste avant l' |
- | cobc (OpenCOBOL) 1.1.0 | + | Cela étant dit, le langage COBOL paraît avoir toujours été maintenu, avec même la parution d'une version orientée objets en 2002 et un standard plus avancé publié en 2014. IBM sembla être toujours un participant important, bien qu'il apporte aussi son appui actif à d' |
- | Copyright (C) 2001-2009 Keisuke Nishida / Roger While | + | J'ai installé ce compilateur surtout pour son intérêt historique et suis arrivé à construire assez facilement un programme de Division Euclidienne, |
- | Built Nov 02 2013 00:16:01 | ||
- | Packaged Feb 06 2009 10:30:55 CET | ||
- | As can be seen from the dates quoted, development of this compiler is not going along at the supersonic speeds seen in some open-source projects. However, this suits quite well the COBOL mindset that goes more for " | + | **Installation |
- | The compiler documentation gives us some insight into which COBOL dialects are supported. The ground-breaking 2002 version | + | Installation |
- | -std=< | + | ===== Installation ===== |
- | cobol2002 | + | Son installation suit la procédure habituelle sur des systèmes *buntu, puisque OpenCOBOL est disponible directement depuis les dépôts. Utilisez simplement votre gestionnaire de logiciels préféré pour installer le paquet open-cobol : |
+ | |||
+ | # aptitude install open-cobol | ||
- | Compiling "Hello, world!" | + | **When this is installed, we can directly fire up the COBOL compiler in a terminal and investigate which version we are using:** |
- | A very basic program in traditional, old-style, fixed-format, | + | Une fois installé, nous pouvons exécuter le compilateur COBOL directement dans un terminal, et découvrir quelle version nous avons installée : |
- | IDENTIFICATION DIVISION. | + | $ cobc --version |
+ | cobc (OpenCOBOL) 1.1.0 | ||
+ | Copyright (C) 2001-2009 Keisuke Nishida / Roger While | ||
+ | Built Nov 02 2013 00:16:01 | ||
+ | Packaged Feb 06 2009 10:30:55 CET | ||
- | PROGRAM-ID. HELLO-WORLD. | + | **As can be seen from the dates quoted, development of this compiler is not going along at the supersonic speeds seen in some open-source projects. However, this suits quite well the COBOL mindset that goes more for " |
- | PROCEDURE DIVISION. | + | The compiler documentation gives us some insight into which COBOL dialects are supported. The ground-breaking 2002 version is there, though the 2014 update is not (yet) there:** |
- | DISPLAY | + | Les dates nous montrent que le développement de ce compilateur n'avance pas aux vitesses supersoniques que l'on voit chez certains projets de code Open Source. Mais cela concorde assez bien avec la mentalité de COBOL qui préfère cheminer doucement selon le principe de « qui va piano va sano » plutôt que de chercher à obtenir des résultats immédiats. |
- | STOP RUN. | + | La documentation du compilateur nous informe sur les dialectes de COBOL qui sont pris en charge. La version séminale de 2002 y est, mais non (ou pas encore) celle de la mise à jour de 2014 : |
- | Note that this syntax - originally thought out for punched cards - is all about spacing. The first six characters on each line (columns 1 to 6) are reserved to identify each program line with a number – though nowadays numbers are no longer mandatory. Column 7 is an indicator area that can be used to mark a line as a commentary by inserting an asterisk " | + | |
+ | cobol2002 | ||
+ | cobol85 | ||
+ | ibm IBM Compatible | ||
+ | mvs MVS Compatible | ||
+ | bs2000 | ||
+ | mf Micro Focus Compatible | ||
+ | default | ||
- | Fire up your favorite text editing program, and type or paste in this text. Save the file as " | ||
- | Once saved, let us compile our first program. We will need to use option | + | **Compiling "Hello, world!" |
- | cobc hello.cob | + | A very basic program in traditional, |
- | Here we have our source code, and the executable program, which can then be executed: | + | ===== Compiler « Hello, world! » ===== |
- | ls | + | Voici un exemple de programme très basique, dans un COBOL traditionnel à format d' |
- | hello hello.cob | + | |
+ | | ||
+ | | ||
+ | | ||
+ | STOP RUN. | ||
- | ./hello | + | **Note that this syntax -originally thought out for punched cards- is all about spacing. The first six characters on each line (columns 1 to 6) are reserved to identify each program line with a number – though nowadays numbers are no longer mandatory. Column 7 is an indicator area that can be used to mark a line as a commentary by inserting an asterisk " |
- | Hello, world | + | Fire up your favorite text editing program, and type or paste in this text. Save the file as " |
- | It is noteworthy that, since I was doing this on a 64-bit version of Linux Mint, what the compiler | + | Once saved, let us compile our first program. We will need to use option "-x" to request |
- | ldd hello | + | Notez que cette syntaxe - conçue originalement pour les cartes perforées - est basée sur le compte de caractères. Les premiers six caractères de chaque ligne (les colonnes 1 à 6) sont réservés pour la numérotation de chaque ligne du programme, bien que les numéros de ligne ne soient plus obligatoires aujourd' |
- | [...] | + | Lancez votre éditeur de textes préféré et tapez ou collez-y ce texte. Enregistrez le fichier comme « hello.cob » ou « hello.cbl »" |
- | /lib64/ld-linux-x86-64.so.2 (0x00007f277d149000) | + | Une fois le fichier créé, compilons notre premier programme. Nous indiquerons l' |
+ | $ cobc hello.cob -x | ||
- | Free-form | + | **Here we have our source code, and the executable program, which can then be executed:** |
- | The programing world has gone forward a tad since the original specification for COBOL was published. Among other things, writing programs in ALL CAPITAL LETTERS is no longer considered the only true way of getting things done, and modern script-kiddies would have difficulties abiding with the very strict column syntax of earlier versions. This is why later COBOL dialects have progressively reduced the constraints on formal program presentation, | + | Nous avons ainsi le fichier code source, et le programme exécutable qui peut alors être exécuté : |
- | program-id. HelloWorld. | + | $ ls |
+ | hello hello.cob | ||
+ | $ ./hello | ||
+ | Hello, world | ||
- | procedure division. | + | **It is noteworthy that, since I was doing this on a 64-bit version of Linux Mint, what the compiler produced is in fact a 64-bit executable file! I wonder what the original creators of the language would have thought of that: |
- | display "Hello, world" | + | Il est intéressant de noter que, puisque je faisais cette compilation sous une version 64-bits de Linux Mint, le compilateur vient en fait de produire un fichier exécutable en code 64-bits ! Je me demande ce que les concepteurs originels du langage en auraient pensé : |
- | stop run. | + | $ ldd hello |
+ | [...] | ||
+ | / | ||
- | end program HelloWorld. | + | **Free-form and procedures |
- | From the compiler' | + | The programing world has gone forward a tad since the original specification for COBOL was published. Among other things, writing programs in ALL CAPITAL LETTERS |
- | cobc hello.cob -x -free | + | ===== La forme libre et les procédures ===== |
- | Let us now complicate things. We are now going to split the program up into two parts: | + | Le monde de la programmation |
- | program-id. HelloWorld. | + | |
+ | |||
+ | procedure division. | ||
+ | |||
+ | display " | ||
+ | stop run. | ||
+ | |||
+ | end program | ||
- | data division. | + | **From the compiler' |
+ | ** | ||
- | working-storage section. | + | Du point de vue du compilateur, |
- | 01 Greeting PIC X(15) value " | + | $ cobc hello.cob -x -free |
- | + | ||
+ | **Let us now complicate things. We are now going to split the program up into two parts: a main procedure that will be invoked on program execution, and a sub-program (procedure) that actually does the dirty work when required by the main procedure. To go a step further, we will declare a variable and initialize it with the text to be displayed. The main program goes as follows:** | ||
- | procedure division. | + | Compliquons maintenant un peu les choses. Nous allons séparer le programme en deux parties : une procédure principale qui sera invoquée au moment de la mise en route du programme et une sous-procédure qui fera les basses besognes dès son invocation depuis la principale. Pour aller encore plus loin, nous allons déclarer une variable et l' |
- | call " | + | program-id. HelloWorld. |
+ | |||
+ | data division. | ||
+ | working-storage section. | ||
+ | 01 Greeting PIC X(15) value " | ||
+ | |||
+ | procedure division. | ||
+ | |||
+ | call " | ||
+ | stop run. | ||
+ | |||
+ | end program HelloWorld. | ||
- | stop run. | + | **A new data division has appeared before the procedure division. This contains a working-storage section, which is where local variables are declared using the PIC syntax. Variables may be immediately initialized using the value keyword. |
+ | Now, for the procedure TestSub. This must be written in a new program-id section, that may be inserted within the same file as the main program. For example:** | ||
- | end program HelloWorld. | + | Une nouvelle Data division est apparue devant la Procedure division. Elle contient une section Working-storage, |
- | A new data division has appeared before the procedure division. This contains a working-storage section, which is where local variables are declared using the PIC syntax. Variables may be immediately initialized using the value keyword. | + | Ecrivons maintenant la procédure TestSub. Elle doit être déclarée dans une nouvelle section program-id, mais qui peut se trouver dans le même fichier que le programme principal. Par exemple : |
- | Now, for the procedure | + | program-id. |
+ | |||
+ | data division. | ||
+ | linkage section. | ||
+ | 01 Grt PIC X(15). | ||
+ | |||
+ | procedure division using Grt. | ||
+ | |||
+ | display "This is TestSub" | ||
+ | display "Grt = " Grt. | ||
+ | exit program. | ||
+ | |||
+ | end program TestSub. | ||
+ | |||
+ | **In this case, procedure TestSub will be invoked by the main program | ||
- | program-id. TestSub. | + | For clarity, the parameter name is " |
- | data division. | + | Dans ce cas, TestSub sera invoqué par le programme principal à l'aide d'un paramètre, le texte à afficher. Nous avons aussi inséré une Data division |
- | linkage section. | + | Pour être plus clairs, nous avons donné à ce paramètre le nom « Grt » dans le sous-programme, |
- | 01 Grt PIC X(15). | ||
- | |||
- | | ||
- | |||
- | procedure division using Grt. | ||
- | |||
- | display "This is TestSub" | ||
- | |||
- | display "Grt = " Grt. | ||
- | |||
- | exit program. | ||
- | |||
- | | ||
- | |||
- | end program TestSub. | ||
- | |||
- | In this case, procedure TestSub will be invoked by the main program using one parameter, the text to be displayed. We have also inserted a data division within the sub-program, | ||
- | |||
- | For clarity, the parameter name is " | ||
+ | ** | ||
Let's calculate a GCD | Let's calculate a GCD | ||
- | To illustrate parameter passing when using a procedure, let us use Euclid' | + | To illustrate parameter passing when using a procedure, let us use Euclid' |
- | program-id. GCD. | + | ===== Calculons le PGCD de deux nombres ===== |
- | data division. | + | Pour illustrer le passage de paramètres vers et depuis une procédure, utilisons l' |
- | | + | program-id. GCD. |
+ | |||
+ | data division. | ||
+ | working-storage section. | ||
+ | 01 A PIC 9(15) value 245. | ||
+ | 01 B PIC 9(15) value 135. | ||
+ | 01 G PIC 9(15). | ||
+ | |||
+ | procedure division. | ||
+ | |||
+ | call " | ||
+ | display "GCD of " A " and " B " is " G. | ||
+ | stop run. | ||
+ | |||
+ | end program GCD. | ||
- | 01 A PIC 9(15) value 245. | + | **Inside the EuclidianAlgorithm procedure, we will begin by making a copy of the two numbers |
- | 01 B PIC 9(15) value 135. | + | Dans la procédure EuclidianAlgorithm, |
- | | + | program-id. EuclidianAlgorithm. |
+ | |||
+ | data division. | ||
+ | working-storage section. | ||
+ | 01 A PIC 9(15). | ||
+ | 01 B PIC 9(15). | ||
+ | 01 Q PIC 9(15). | ||
+ | 01 R PIC 9(15). | ||
+ | |||
+ | linkage section. | ||
+ | 01 IN_A PIC 9(15). | ||
+ | 01 IN_B PIC 9(15). | ||
+ | 01 IN_G PIC 9(15). | ||
+ | |||
+ | procedure division using IN_A, IN_B, IN_G. | ||
+ | |||
+ | Main. | ||
+ | move IN_A to A. | ||
+ | move IN_B to B. | ||
+ | perform Loop with test after until R = 0. | ||
+ | move A to IN_G. | ||
+ | |||
+ | Loop. | ||
+ | divide A by B giving Q remainder R. | ||
+ | move B to A. | ||
+ | move R to B. | ||
+ | end program EuclidianAlgorithm. | ||
- | | + | **Once the file is compiled, we can execute the binary program:** |
- | procedure division. | + | Une fois le fichier compilé, nous pouvons exécuter le programme: |
- | call " | + | $ cobc gcd.cob -x -free |
+ | $ ./gcd | ||
+ | GCD of 000000000000245 and 000000000000135 is 000000000000005 | ||
- | display "GCD of " A " and " B " is " G. | + | **Calling C code from COBOL |
- | stop run. | + | When generating the result above, I was not entirely satisfied with presentation on screen. All those leading zeros seem rather gauche, to say the least. I would have much preferred a C-style printf function to format output, which unfortunately does not seem to be readily available in COBOL. |
- | end program | + | In the interest of tinkering a bit, instead of writing an equivalent procedure in pure COBOL, let us do so in C and invoke it from the COBOL main program. |
- | Inside the EuclidianAlgorithm procedure, we will begin by making a copy of the two numbers | + | prettyNumber takes one of the numbers |
- | program-id. EuclidianAlgorithm. | + | Print is defined as an external function, and so is accessible from outside the C object file. It simply takes the three parameters A, B and G from the COBOL side, and writes them out using prettyNumber.** |
- | data division. | + | ===== Faire appel à un code en C depuis COBOL ===== |
- | working-storage section. | + | En préparant le programme précédent, |
- | 01 A PIC 9(15). | + | Dans l' |
- | 01 B PIC 9(15). | + | - prettyNumber prend un nombre entier envoyé depuis le COBOL, le transforme et l' |
- | 01 Q PIC 9(15). | + | - Print est déclarée comme une fonction externe, et sera donc accessible depuis l' |
- | 01 R PIC 9(15). | + | #define TRUE (1 == 1) |
+ | #define FALSE !TRUE | ||
+ | |||
+ | void prettyNumber (char *p) { | ||
+ | |||
+ | int i, leading_zeros = TRUE; | ||
+ | |||
+ | for (i = 0; i < 15; i++) | ||
+ | if ((p[i] != ' | ||
+ | leading_zeros = FALSE; | ||
+ | printf (" | ||
+ | } | ||
+ | if (leading_zeros) | ||
+ | printf(" | ||
+ | } | ||
+ | |||
+ | extern int Print (char *a, char *b, char *g) { | ||
+ | |||
+ | printf ("GCD of "); | ||
+ | prettyNumber(a); | ||
+ | printf (" and "); | ||
+ | prettyNumber(b); | ||
+ | printf (" is "); | ||
+ | prettyNumber(g); | ||
+ | printf(" | ||
+ | |||
+ | return(0); | ||
+ | } | ||
- | linkage section. | + | **Inside the existing COBOL code, just one line needs to be changed in the main program. We replace** |
- | 01 IN_A PIC 9(15). | + | Du côté du programme COBOL existant, il faut changer une seule ligne. Remplaçons |
- | 01 IN_B PIC 9(15). | + | display "GCD of " A " and " B " is " G. |
+ | |||
+ | **with** | ||
- | 01 IN_G PIC 9(15). | + | par |
- | | + | call " |
- | procedure division using IN_A, IN_B, IN_G. | + | **No further modifications need to be made to the code. However, compilation will be a tad more tricky, since we need to compile the C library first, and then give it to the COBOL compiler to link with the COBOL code and produce an executable file. So:** |
- | Main. | + | Nul besoin de faire de plus longues modifications au programme. Mais la compilation sera plus complexe, puisque nous devrons commencer par compiler la bibliothèque en C d' |
- | move IN_A to A. | + | $ cc print.c -o print.o -c |
+ | $ cobc gcd-c.cob print.o -x -free | ||
- | move IN_B to B. | + | **The " |
- | perform Loop with test after until R = 0. | + | Le drapeau « -c » indique au compilateur C de s' |
- | move A to IN_G. | + | $ ./gcd-c |
- | + | GCD of 245 and 135 is 5 | |
- | + | ||
- | + | **Conclusions | |
- | Loop. | + | |
- | + | ||
- | divide A by B giving Q remainder R. | + | |
- | + | ||
- | move B to A. | + | |
- | + | ||
- | move R to B. | + | |
- | + | ||
- | end program EuclidianAlgorithm. | + | |
- | + | ||
- | Once the file is compiled, we can execute the binary program: | + | |
- | + | ||
- | cobc gcd.cob -x -free | + | |
- | + | ||
- | ./gcd | + | |
- | + | ||
- | GCD of 000000000000245 | + | |
- | + | ||
- | Calling C code from COBOL | + | |
- | + | ||
- | When generating the result above, I was not entirely satisfied with the presentation on screen. All those leading zeros seem rather gauche, to say the least. I would have much preferred a C-style printf function to format output, which unfortunately does not seem to be readily available in COBOL. | + | |
- | + | ||
- | In the interest of tinkering a bit, instead of writing an equivalent procedure in pure COBOL, let us do so in C and invoke it from the COBOL main program. The C wrapper was built around two functions: | + | |
- | + | ||
- | • prettyNumber takes one of the numbers sent from the COBOL side of things, parses and prints it on-screen. As the numbers are each formatted as an array of 15 characters, a simple for loop is used to traverse the array, combined with the flag leading_zeros to indicate if we are still passing through leading zeros (TRUE) or have come into the main body of the number (FALSE). | + | |
- | + | ||
- | • Print is defined as an external function, and so is accessible from outside the C object file. It simply takes the three parameters A, B and G from the COBOL side, and writes them out using prettyNumber. | + | |
- | + | ||
- | Inside the existing COBOL code, just one line needs to be changed in the main program. We replace | + | |
- | + | ||
- | display "GCD of " A " and " B " is " G. | + | |
- | with | + | As stated at the beginning, the aims of this short piece were mostly to go back in time and see how the efforts of a dedicated group of programmers have made a rather ancient (in computer terms) programming language com back to life on a modern GNU/Linux distribution. Neither the hardware (laptop versus 1950's mainframe) nor the operating system (UNIX-like versus proprietary OS) have much to do with what the original COBOL designers were contending with – but this stuff works, and can give us a taste of how things were in the "good old days" of computation.** |
- | call " | + | **Although the language itself has seen some evolution since conception, general syntax and conception are visible those of another age. This is not to say that modern trends such as object-oriented design or web service implementation could not be handled through COBOL. On the contrary, if sufficient interest were to be found to implement the necessary intermediate libraries I see no reason why COBOL -and, specifically, |
- | No further modifications need to be made to the code. However, compilation will be a tad more tricky, since we need to compile | + | On the other hand, handling communication with databases has always been one of the strengths of the COBOL environment; |
- | cc print.c -o print.o -c | + | ===== Conclusions ===== |
- | cobc gcd-c.cob print.o | + | Comme il a été dit au début, l' |
- | The "-c" flag tells the C compiler to halt once the object code is produced, before linking. The object file may then simply be added to the COBOL compiler's input file list. Execution is then performed in the usual way, producing much nicer visual results: | + | Bien que le langage lui-même ait vu quelques évolutions depuis sa conception initiale, sa syntaxe en général et sa philosophie sont visiblement celles d'un autre âge. Cela n' |
- | ./gcd-c | + | En revanche, la connexion à des bases de données a toujours été un des points forts du COBOL, qui a été conçu surtout dans cet objectif. Donc, si (ou quand) des gens intéressés peuvent arriver à connecter COBOL avec des systèmes de gestion de bases de données tels que PostgreSQL ou MariaBD (une partie du travail a déjà été accomplie avec Oracle), ou, mieux encore, un système générique de connexion avec SQL, ce projet pourrait trouver sa place dans le monde moderne, au moins pour ce qui est de la programmation de dorsales de bases de données. |
- | GCD of 245 and 135 is 5 | ||
- | Conclusions | ||
- | As stated | + | **Author biography: Alan teaches computer science at Escola Andorrana de Batxillerat (high-school). He has previously given GNU/Linux courses |
- | Although the language itself has seen some evolution since conception, general syntax and conception are visible to those of another age. This is not to say that modern trends such as object-oriented design or web service implementation could not be handled through COBOL. On the contrary, if sufficient interest were to be found to implement the necessary intermediate libraries, I see no reason why COBOL - and, specifically, | + | Biographie de l' |
- | On the other hand, handling communication with databases has always been one of the strengths of the COBOL environment; |
issue100/programmer_en_cobol.1440939043.txt.gz · Dernière modification : 2015/08/30 14:50 de auntiee