Les programmes présentés ci-après ont été écrits pour WinX et Linux. Ils se distinguent par les fonctions d'accès aux fichiers. Sous VM et TSO ces derniers sont lus et écrits à l'aide de stems, toutes les applications se réduisent donc à des opérations sur ceux-ci.
Conversion d'un fichier texte Unix en DOS (caractères de fin de ligne). Le fichier d'origine est chargé en une seule fois dans une chaîne de caractères. Celle-ci est ensuite découpée suivant le caractère de fin de ligne Unix, ceux de DOS sont ajoutés automatiquement à l'écriture.
La conversion inverse est effectuée avec le séparateur '0D0A'x . En fait Linux lit très bien les fichiers DOS et effectue la conversion de lui-même.
On utilisera ce principe pour lire des sorties de tableur où les données sont séparées par des points-virgules, et en général les formats CSV (comma separated variable) .
Ce programme découpe un fichier texte en pages avec entête et pied.
Les lecture et écriture pourraient se faire en une seule boucle. Les séparer en travaillant en mémoire (dans une chaîne de caractères ou en stem ) présente les avantages :
- d'accès disque séparés, au moins un est continu et l'autre pratiquement ;
- de réutiliser éventuellement le fichier d'entrée ;
- d'adapter plus aisément un code développé pour les grands systèmes (lecture / écriture via des stems ).
Cette méthode sera systématique dans toutes les applications.
Sur ce modèle on ajoutera des instructions de formatage pour recadrer des champs (import / export de tableurs), d'enrichissement du texte ou de tout autre manipulation des données...
Un document d'inscription (ou autre sujet), sous forme de fichier ou courrier électronique, pourrait contenir le texte suivant :
Précisez votre identité NOM: (30 caractères max) PRENOM: (30 caractères max) Et votre adresse NUMERO: (8 caractères max) RUE: (50 caractères max) VILLE: (30 caractères max) CODE POSTAL: (5 caractères)
Plutôt que de saisir au clavier les données de chaque document, un utilitaire les extraira et préparera un fichier pour les importer dans l'application de gestion. Il n'y aura plus alors qu'à procéder aux vérifications et corrections. Dans l'exemple présenté les documents sont des courriers dans un dossier de boîte à lettres où chacun est en fichier séparé (d'autres logiciels de courrier stockent toutes les notes en un seul fichier, l'extraction sera adaptée en conséquence) ; les enregistrements erronés sont signalés :
Les documents formatés issus de certains logiciels de traitement de texte se prêtent très bien à une telle recherche, d'autres non. La fonction Pos() étant la plus efficace, chaque fichier est lu en mode binaire dans une chaîne de caractères. Il faut éviter les lettres accentuées dans les noms des champs recherchés car elles sont interprétées différement suivant le jeu de caractères.
Pour effacer de façon sûre des données il faut d'abord les écraser par un caractère quelconque puis supprimer le fichier, ce que fait l'utilitaire suivant.
! 0 1 2 3 4 5 6 7 8 9 A B C D E F ! 0123456789ABCDEF -----+----------------------------------+----------------- 0 ! 4749463839610003760087000013095C ! GIF89a..v.ç....\
Les lecture et conversion du fichier en entier ne sont satisfaisantes que pour de faibles volumes sinon elles s'avèrent désastreuses. La méthode choisie avec de bonnes performances consiste à ne lire dans le fichier que le bloc de 320 caractères (20 fois 16) de la page à afficher.
On utilise deux fonctions externes SysCls() (effacement écran) et SysGetKey() (saisie au clavier d'un caractère sans validation par la touche Entrée), ainsi le programme tel quel fonctionne aussi bien sous WinX que sous Linux. En leur absence :
Parse Source 1 env 2 . If env = 'W' Then "CLS" /* sous WinX */ Else "clear" /* sinon sous Linux */ /* et pour la saisie d'un caractère, avec validation par la touche Entrée : */ x = Charin()
Certains fichiers comportent la description des structure et contenu au début. Il suffit de décoder (ce n'est pas toujours facile) cet en-tête puis extraire les données, par exemple pour les fichiers ".DBF" (à l'origine fichiers du logiciel DBase d'Ashton Tate, devenus un standard de fait pour les SGBDs) :
Les 32 premiers octets donnent la date, la longueur d'un enregistrement, leur nombre... L'octet de poids faible étant en premier il faut inverser l'ordre de lecture des mots. Chaque champ composant un enregistrement est ensuite décrit dans 32 octets : on lit les n descriptions en une fois et on découpe à l'affichage. Et enfin les enregistrements de données suivent, toujours lus en une fois pour limiter les accès disque et séparés ensuite. Ils sont affichés à l'écran mais pourraient être écrits dans un fichier texte en sortie.
Vérification de la date saisie au clavier entre 1901 et 2099 : la routine boucle jusqu'à l'obtention d'une date correcte ou se termine sur une entrée vide. Le jour est vérifié dans 'BISSEXT' appelée en fonction. En supplément 'JOURS' indique le jour de la semaine js, calcule ses rangs ja dans l'année et jj depuis le 31/12/1900.
JJ est un numéro de jour, càd une date, pour une durée retrancher 1 jour. Par ex :
le 30 janvier 1901 est le jour no 30, en duréee 29 à 0h, 29.5 à midi.
Pour obtenir le jour julien à 0h ajouter 2 415 384.5 (le 31 décembre 1900) à jj.
Inversement la date est déterminée à partir du rang du jour, toujours entre 1901 et 2099, soit de 1 à 72 684. On calculera ainsi les intervalles entre deux dates.
Contrôle de données entrées au clavier.
Quelques fonctions usuelles, en l'absence de la bibliothèque externe de fonctions mathématiques.
Simple boucle de multiplication, la formule approchée de Sterling serait pire. Attention 10! = 3 628 800, au
dessus le résultat devient énorme !
Le code erreur fixé à -1000 conviendra à toutes les fonctions suivantes.
Calcul par itérations convergentes de Newton-Raphson. Le calcul du delta en fonction de la précision (Numeric Digits) évite une boucle sans fin.
Calcul à la sixième décimale près suivant le développement en série, l'angle est exprimé en radians. Pour le
cosinus prendre cos(x) = sin(x + π/2).
On trouvera sur le web les développements en série de toutes les fonctions trigonométriques directes et
inverses.
Calcul à la sixième décimale près du logarithme népérien de x = z + 1 suivant le développement limité de Ln(z+1) pour z < 1. Si l'entrée est inférieure à 0,1 on multiplie par a fois 10 , si supérieure à 2 on divise par a fois 10 ; on retranche ou ajoute ensuite autant de Ln(10). La série comportant des termes positifs et négatifs alternés le calcul est effectué en deux boucles.
Calcul avec la valeur absolue de x et division ensuite si x négatif. La boucle du développement relativement lourde est nécessaire pour les nombres élevés, elle peut être réduite suivant la précision désirée.
Un exemple d'utilisation des fonctions mathématiques externes d'Open Object Rexx, chargement de la bibliothèque et émulation de la fonction atan2 du langage C qui retourne directement l'angle de -π à +π, en radians ou ici en degrés.
D'habitude les commandes système sont composées dans le programme et exécutées immédiatement. Pour des cas complexes d'automatismes où l'enchaînement des ordres dépend de conditions diverses une meilleure méthode consiste à construire un fichier d'exécution qui sera soumis par le programme lui même ou séparément. Cette façon de procéder a deux avantages :
- le fichier de commandes n'est pas obligatoirement écrit en REXX mais dans n'importe quel langage reconnu par le système ou un sous système : un ".BAT" sous WinX, un "JCL" sous TSO, un ordre SQL, etc...
- la séparation des préparation et exécution facilite le contrôle du processus.
Pour illustrer les propos précédents, ci joint un programme de génération de fichiers HTML pour voir toutes les images d'un répertoire. L'utilisation de cadres en HTML requiert un fichier maître dans lequel ils sont définis et un autre contenant la liste des images.
La plupart des systèmes disposent d'un planificateur de tâches pour les déclencher en temps voulu. Mais absent (DOS seul), un tel utilitaire s'écrit en REXX :
Les commandes à exécuter sont chargées en stem dans la sous routine CMDES (mieux : les mettre en fichier) ; la dernière ligne obligatoire évite une boucle sans fin. Puis dans la boucle principale : la prochaine tâche à effectuer est recherchée et l'intervalle d'attente calculé dans DIFFER. La fonction RXSLEEP ne détectant pas les entrées clavier on utilise ici un programme compilé "WAITNSEE" d'attente avec interruption si une touche est pressée et renvoi de son code (voir Un peu de C). Une fois le temps écoulé la tâche est soumise et on recherche la suivante.
© G. Navarre, 2003 - 2006, màj 01/12/2019.