Apprenez par l’exemple!                            Allez! Et ne discutez pas!

 

C’est ce que j’ai toujours fait, et ce que je consid�re toujours �tre la meilleure fa�on d’apprendre un nouveau langage de programmation. Prenez un programme d�j� existant et lisez-le. Vous y verrez tout ce qu’il y a � savoir sur la syntaxe, comment indiquer les commentaires, ainsi que plusieurs instructions.

Une fois ces connaissances acquises vous pouvez commencer � programmer vous-m�me, avec � vos c�t�s le "DCL Dictionary" ou alors la toujours pratique commande HELP.

Voici donc pour vous un petit exemple de programme. Il fait intentionellement usage de plusieurs "constructs", boucles, sous-routines et autres pour vous donner un aper�u de ce que vous pouvez faire avec DCL. Bien entendu, j'ai choisi d'utiliser des moyens plus compliqu�s que n�cessaires � certains endroits, histoire d'introduire quelques instructions DCL. Je crois qu'il est quand m�me facile d'identifier o� j'ai un peu trop forc�! L'usage des minuscules et majuscules dans le code est un choix personnel.

                             Boooooonsoir! Elle est partie!

 

 

$!------------------------------------------------------------------------------
$! SAMPLE.COM                                        Syltrem                  29-AVR-2001
$!------------------------------------------------------------------------------
$! Cette proc�dure donnera, pour le r�pertoire donn� en param�tre, le nombre
$! de blocks occup�s pour chaque groupe de fichiers d'un type donn�.
$! Le type est identifi� par l'extension (ex. PROGRAMME.EXE --> le type est EXE)
$! La liste est tri�e par ordre d�croissant du nombre de blocks.
$!------------------------------------------------------------------------------
$ Init:
$    On Control_Y Then Goto Error_Trap
$    On Error Then Goto Error_Trap
$
$    P_Directory = P1
$
$    Say := Write SYS$OUTPUT             ! SYS$OUTPUT = sortie par d�faut
$    Define TMP_File     SYS$SCRATCH:SAMPLE.TMP    ! Un fichier de travail
$
$    File_Types = ""    ! Contiendra une liste des types de fichiers rencontr�s
$!-------------------------------------------------------------------------------
$ Begin:
$ File_Loop:
$    File = f$search(P1 + "*.*;*")
$    If    File .eqs. ""    -     ! Plus de fichiers; fin de la liste
    Then    Goto Arrange_Data
$
$    File_Type = f$parse(File,,,"type") ! Extraire le type (.EXE, .DAT etc)
$    ! Si le type de ce fichier n'est pas d�j� dans notre liste, on l'ajoute
$    ! et on initialise une variable pour cumuler le nombre de blocks.
$    If    f$locate(File_Type, File_Types) .eq. f$length(File_Types) -
     Then    File_Types = File_Types + File_Type
$    File_Type = File_Type - "."            ! Enlever le point (.)
$    If    f$type(Num_Blocks_'File_Type) .eqs. "" -! Symbole n'existe pas
    Then    Num_Blocks_'File_Type = 0         ! initialiser cumulatif
$    Num_Blocks_'File_Type = Num_Blocks_'File_Type         -
            + f$file_attributes(File,"ALQ") ! ALlocation Quantity
$    Goto     File_Loop    ! Passer au fichier suivant
$
$!-------------------------------------------------------------------------------
$ Arrange_Data:
$    Cpt = 1
$    Open/Write TMP TMP_File     ! Ouvrir un fichier de travail
$ Arrange_Data_Loop:
$    File_Type = f$element(Cpt, ".", File_Types)
$    If    File_Type .eqs. "."             - ! Fin de la liste
    Then    Goto Arrange_Data_End
$
$    ! �crire dans le fichier le nombre de blocks en format 9(8) avec z�ros
$    ! non significatifs, suivi du type (Ex.: "00012345DAT")
$    Write TMP f$fao("!8ZL", Num_Blocks_'File_Type), File_Type
$    Cpt = Cpt + 1
$    Goto    Arrange_Data_Loop
$ Arrange_Data_End:
$    Close    TMP
$
$    Call     Sort_TMP_File 1 8 Zoned Descending
$
$!-------------------------------------------------------------------------------
$ Display_Results:
$    Open/Read TMP TMP_File
$
$    Total_Blocks = 0
$
$    Say "Type de fichier Nombre de blocks"
$    Say "--------------- ----------------"
$ Display_Results_Loop:
$    Read/End_of_File=Display_Results_End    TMP TMP_Rec
$    Num_Blocks = f$integer(f$extract(0, 8, TMP_Rec))
$    File_Type = f$extract(8, f$length(TMP_Rec) - 8, TMP_Rec)
$
$    Say f$fao("!15AS !15UL", File_Type, Num_Blocks)
$    Total_Blocks = Total_Blocks + Num_Blocks
$
$    Goto    Display_Results_Loop
$
$ Display_Results_End:
$    Close TMP
$    Say " ----------------"
$    Say f$fao("!15AS !15UL", "Total", Total_Blocks)
$    Goto End_Proc
$
$!-------------------------------------------------------------------------------
$ Sort_TMP_File: SubRoutine
$    Exit_Status = 1                         ! Succ�s
$    On Error Then Goto Sort_TMP_File_Err
$
$    P_Pos = P1
$    P_Size = P2
$    P_DataType = P3
$    P_Order = P4
$
$    ! On trie notre fichier de travail selon le nombre de blocks descendant.
$    Sort/NoStat     TMP_File TMP_File                 -
        /Key=(Position='P_Pos, Size='P_Size, 'P_DataType, 'P_Order)
$
$    Goto    Sort_TMP_File_End
$
$ Sort_TMP_File_Err:
$    Exit_Status = $STATUS
$    Say "%SAMPLE-E-SORTERR, error in sorting the temp file"
$
$ Sort_TMP_File_End:
$    Exit 'Exit_Status
$    EndSubroutine
$
$!-------------------------------------------------------------------------------
$ Control_Y:
$    Exit_Status = $STATUS
$    Say "%SAMPLE-F-CTRLY, user cancelled execution"
$    Goto End_Proc
$
$ Error_Trap:
$    Exit_Status = $STATUS
$
$ End_Proc:
$    Set NoOn
$    If        f$trn("TMP") .nes. ""                     -
      Then   Close TMP
$    If         f$search("TMP_File:") .nes. ""                 -
      Then   Delete/NoConf/NoLog TMP_File:;*
$    Exit 'Exit_Status

                                                                                                                      On peut m'aider un peu???
Voyons cela plus en d�tail...

$STATUS Ce symbole est mis � jour � l'ex�cution de chaque commande. Vous pouvez l'utiliser pour v�rifier le r�sultat (succ�s ou erreur) et pour signifier ce r�sultat � une proc�dure appelante. Voyez la fonction lexicale F$MESSAGE().
Sauvegardez sa valeur si vous comptez l'utiliser dans le futur car elle sera chang�e � la prochaine instruction que vous ferez ex�cuter.
Dans la m�me optique, le syst�me tient aussi � jour le symbole $SEVERITY.
ON CONTROL_Y Que faire si l'utilisateur d�cide de stopper l'ex�cution de la proc�dure. On pourrait aussi emp�cher un arr�t par l'utilisateur en employant SET NOCONTROL = Y.
P1..P8 Les param�tres P1 � P8 peuvent �tres donn�es � une proc�dures.
ON ERROR Que faire en cas d'erreur (on peut d�terminer la s�v�rit� des erreurs � contr�ler avec ON WARNING, ON SEVERE).
SYS$OUTPUT C'est la sortie par d�faut (�cran, ou fichier .LOG pour une ex�cution en lot (batch). C'est l� qu'on peut �crire les messages � l'intention de l'utilisateur.
Symbole de commande Un symbole de commande est un genre de raccourci pour une commande fr�quemment utilis�e.
DEFINE Assignation de nom logique
�tiquette: Commun�ment appel� label. Pour faire des branchements, mais j'ai l'habitude d'en mettre un peu partout pour d�limiter les actions et clarifier le code.
F$SEARCH() Fonction lexicale qui retourne les noms des fichiers demand�s, un par un. La fin de la liste est indiqu�e par une cha�ne vide.
F$PARSE Fonction lexicale permettant d'extraire les composantes (disque, r�pertoire, etc) d'une sp�cification de fichier.
F$LOCATE Fonction lexicale permettant de trouver la position d'une cha�ne de caract�res dans une autre. Si la valeur retourn�e �gale la longueur de la cha�ne de caract�res examin�e c'est qu'on n'a pas trouv�. Le premier caract�re est � la position z�ro.
Concat�nation et soustraction On peut concat�ner des cha�nes de caract�res en employant le + (addition). De m�me, on peut retirer des caract�res d'une cha�ne en employant le - (soustraction).
F$TYPE Fonction lexicale permettant de d�terminer si un symbole est d�fini et de quel type (caract�re ou num�rique) il est. Les symboles ne sont pas d�clar�s explicitement, mais dynamiquement la premi�re fois qu'on leur assigne une valeur.
GOTO Il n'y a pas de commande d'it�rations. L'utilisation judicieuse de GOTO ne nuit pas � la clart� du code mais est r�ellement n�cessaire.
OPEN On peut lire ou cr�er des fichiers avec DCL. M�me des fichiers index�s.
F$ELEMENT Fonction lexicale permettant d'extraire des �l�ments d'une liste d'items s�par�s par un caract�re quelconque.
F$FAO Fonction lexicale utilis�e pour formatter des donn�es. Ici, une valeur num�rique d'une longueur de 8 caract�res avec z�ros non-significatifs.
CALL Appel d'une sous-routine. Obtenez plus d'informations ici.
SUBROUTINE Utilisation tout � fait superflue ici pour lieu de d�monstration. Une sous-routine se comporte exactement comme une autre proc�dure appel�e avec @ et est r�gie par les m�mes r�gles (symboles locaux/globaux, etc). En passant, rien n'emp�che de mettre une instruction sur la m�me ligne qu'une �tiquette comme je l'ai fait ici.
F$EXTRACT Fonction lexicale utilis�e pour extraire des caract�res d'une cha�ne. Employ�e ici pour s�parer les 2 informations provenant du fichier TMP_File et lues dans le symbole TMP_Rec.
F$INTEGER Fonction lexicale qui converti des caract�res (de 0 � 9) en valeur num�rique.
SORT On trie notre fichier de travail.
EndSubroutine Marque la fin de la sous-routine. Pas une instruction ex�cutable en tant que telle mais d�limite le code. Tiendra lieu implicitement de la commande EXIT en son absence.
DELETE On fait notre petit m�nage. J'utilise toujoure /NOCONFIRM/NOLOG dans les proc�dures pour m'assurer que peut importe l'environnement de l'utilisateur aucun message ne sera affich� ( Ex. Si DEL*ETE:==DELETE/CONFIRM/LOG dans le
LOGIN.COM de l'utilisateur).
Apostrophe On peut substituer dans une commande la valeur d'un symbole. Apprenez tout � ce sujet ici.
F$FILE_ATTRIBUTES Fonction lexicale utilis�e pour obtenir de l'information sur un fichier. Ici, le nombre de blocks qu'il occupe.
EXIT Annonce la fin de la proc�dure. Optionnellement, on peut terminer avec succ�s ou en erreur en donnant la valeur de retour appropri�e.

                                                                                                Je m'en vais écrire ma 1ère procédure...