Obligement - L'Amiga au maximum

Jeudi 18 avril 2024 - 22:43  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in english


Réseaux sociaux

Suivez-nous sur X




Liste des jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z,
ALL


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : Amiga E - programmer ARexx
(Article écrit par Yann Armand et Pierre Girard et extrait d'Amiga News - février 1996)


Il y a de grandes chances pour que vous connaissiez tous ARexx. Pour ceux qui ne se souviennent pas, voici un petit rappel. ARexx est un langage de programmation simple à utiliser et qui permet de communiquer avec les programmes prévus à cet effet.

Il permet notamment d'ajouter des fonctions personnelles aux logiciels par le biais de scripts (des sortes de macro-commandes en plus puissant). En théorie, l'Amiga était déjà capable de faire communiquer les tâches entre elles par l'intermédiaire des ports de message Exec. Cependant, il n'y avait pas de standard de communication. Et ARexx est arrivé ! Mais quel est l'intérêt de programmer ARexx ?

C'est simple : prenez un petit script ARexx qui ouvre une fenêtre de requête sous GoldEd. Ça va vite, même si le programme est interprété. Mais si vous voulez, par exemple, chercher un mot spécifique dans un dictionnaire avec une énorme boucle WHILE, vous pouvez aller prendre un café en attendant.

Eh oui, le problème d'ARexx, c'est la vitesse. En utilisation normale, celle-ci est tout à fait convenable. Mais notre optique à nous est de ne pas être ralenti par l'interpréteur.

Nous vous livrons donc ce mois-ci la méthode pour qu'un petit programme (le nôtre) puisse communiquer avec un logiciel quelconque, tout en ne connaissant que les commandes que ce logiciel met à la disposition d'ARexx et en se substituant à l'interpréteur (RexxMast).

Les ports de messages

Pour programmer ARexx, il faut au minimum avoir quelques notions sur les ports de messages. Ils servent à recevoir des messages, à intercepter des événements. C'est ainsi qu'une fenêtre possède un port de message qui intercepte les événements Intuition lorsque ceux-ci surviennent (déplacement...). La gestion d'un port peut paraître ardue à première vue, mais quelques commandes de la bibliothèque Exec se chargent de tout contrôler.

Les commandes de gestion des ports

La première chose à faire est de déterminer si notre port existe déjà grâce à la fonction FindPort('nom').

Attention : cette commande doit toujours être encadrée du couple Forbid()-Permit() coupant le multitâche. Le port n'existant pas, il faut le créer grâce à la fonction CreateMsgPort() qui nous renvoie une structure MsgPort. Il faut ensuite appeler la fonction AddPort() afin d'ajouter le nouveau port à la liste des ports publics (pour que les autres tâches puissent y avoir accès). Dans l'ordre inverse, il nous faudra sortir le port de la liste des ports publics (RemPort) puis l'effacer (DeleteMsgPort) avant la sortie du programme.

Les messages ARexx

Les tâches communiquent par ARexx en s'envoyant des objets de type rexxmsg. Ceux-ci contiennent un objet node exec standard, le type d'action ARexx demandé, le nom de la commande sous forme d'une chaîne de caractères, deux champs results (chaînes) et l'adresse du port de message pour la réponse.

Envoi du message ARexx

En cadeau ce mois-ci, voici une superbe procédure qui va vous permettre d'envoyer des commandes ARexx à vos programmes préférés. La commande se déclare comme suit :

PROC sendrexxcmd(hostname,replyport: PTR TO mp, command, flags, result)

. hostname, est le nom du port Arexx appelé.
. replyport, l'adresse du port sur lequel doit se faire la réponse.
. command, est la chaîne de caractères décrivant la commande.
. retour, est l'adresse de la chaîne de caractères dans laquelle sera stocké le résultat.

Il nous faut créer un objet rexxmsg. Une fois remplis ces champs, nous l'expédions à la tâche-cible (hostname), qui nous répondra sur notre port de message(replyport).

Bon allez, on explique

On commence par allouer l'objet rexxmsg. Cela se fait presque tout seul grâce à CreateRexxMsg auquel nous donnons comme arguments notre port de message ainsi que son nom.

On crée ensuite la chaîne d'arguments (CreateArgstring). Et là, tout le monde se demande pourquoi on fait un CopyMem alors qu'il suffirait d'écrire :

rxmsg.args={rexx_command}

On atteint ici une des limites de l'Amiga E. En effet, rxmsg.args est déclaré dans le module "rexx/storage" comme une substructure. C'est donc, pour le compilateur, le label d'une substructure dont il ne connaît pas le contenu. Il pourrait faire ainsi des erreurs de typage pour toute instruction d'affectation. Par contre, nous, nous savons que c'est un tableau de 16 pointeurs sur des chaînes de caractères. Nous posons donc dans la première case du tableau (le premier argument) l'adresse de la chaîne d'arguments que nous venons de créer. Nous continuons en définissant le type d'action ARexx. C'est une commande (RXCOMM) avec d'éventuels flags (drapeaux), le plus souvent utilisé étant RXFF_RESULT qui demande un résultat sous forme d'une chaîne de caractères.

Comme nous sommes des fanatiques du Shell, nous définissons stdin et stdout avec Input() et Output() ce qui permettra à notre programme d'utiliser des pipes, vous savez "dir | more".

Et là, on envoie le message ! Attention, quand on fait ce genre de chose, il faut s'assurer que les ports ne vont pas changer pendant l'opération (Forbid-Permit). Ensuite, on cherche l'adresse du port grâce à son nom (FindPort()) et on envoie avec PutMsg(...).

Enfin, on attend une réponse (WaitPort, GetMsg). La tâche-cible nous a renvoyé notre message dans lequel elle a rempli les deux champs result :
  • result1 pour la réussite de l'action (0), sinon un code de retour standard ARexx.
  • result2 pour la chaîne de résultat, si elle a été demandée.
Notez dans vos cahiers pour le mois prochain que vous avez à modifier la procédure pour qu'elle traite le cas où rxmsg.result1 est différent de 0, c'est-à-dire quand il y a une erreur. Il nous suffit pour finir de recopier result2 dans la chaîne servant au retour (StrCopy), de nettoyer le message (ClearRexxMsg) et de désallouer la mémoire (DeleteRexxMsg).

Voili, voilou, c'est fini. Si vous ne possédez pas CygnusEd (commercial), vous pouvez utiliser GoldEd avec par exemple :

sendrexxcmd('GOLDED.1',replyport,'QUERY FILE', RXFF_RESULT,nom).

Le mois prochain, nous verrons peut-être une application de cette routine. Tchao.

MODULE 'exec/ports','exec/nodes','exec/lists'
MODULE 'rexxsyslib','rexx/rxslib','rexx/storage','rexx/errors'
MODULE 'dos/dos'

/************************* main ***********************/
PROC main() HANDLE
DEF replyport:PTR TO mp
DEF node:PTR TO ln
DEF nom[64]:STRING
    IF (rexxsysbase:=OpenLibrary('rexxsyslib.library',0))=NIL THEN Raise(0)
->Creation du port public
    Forbid()
    IF FindPort('Rexx_Comp')=0
        IF replyport:=CreateMsgPort()
            node:=replyport.ln
            node.name:='Rexx_Comp'
            node.pri:=0
            AddPort(replyport)
        ENDIF
    ELSE
        Raise()
    ENDIF
    Permit()
->Recherche du port 'rexx_ced'
    Forbid()
    IF FindPort('rexx_ced') THEN WriteF('Port "rexx_ced" Trouvé') 
        ELSE WriteF('Port "rexx_ced" introuvable')
    Permit()
->Envoi de commande a cygnus
    sendrexxcmd('rexx_ced',replyport,'STATUS 21',RXFF_RESULT,nom)
    WriteF('Le fichier ouvert sous cygnus est   ',nom)
->Fermeture des MsgPorts et des Libraries
    RemPort(replyport)
    DeleteMsgPort(replyport)
    CloseLibrary(rexxsysbase)
EXCEPT
        WriteF('error')
ENDPROC
/****************** sendrexxcmd **********************/
PROC sendrexxcmd(hostname,replyport:PTR TO mp,command,flags,retour)
DEF rxmsg:PTR TO rexxmsg
DEF replymsg:PTR TO rexxmsg
DEF rexx_command:LONG
DEF hostport:PTR TO mp
DEF node:PTR TO ln
-> Creation du message AREXX
        node:=replyport.ln
        IF (rxmsg:=CreateRexxMsg(replyport,NIL,node.name))=NIL THEN Raise(0)
        IF rexx_command:=CreateArgstring(command,EstrLen(command))
            CopyMem({rexx_command},rxmsg.args,4)
            rxmsg.action:=RXCOMM OR flags
            rxmsg.stdin:=Input()
            rxmsg.stdout:=Output()
-> Envoi du message
                Forbid()
                hostport:=FindPort(hostname)
                IF hostport THEN PutMsg(hostport,rxmsg)
                Permit()
-> Recuperation du resultat
                WaitPort(replyport)
                replymsg:=GetMsg(replyport)
        ELSE
                WriteF('Problème d''envoi de commande Arexx')
        ENDIF
        StrCopy(retour,replymsg.result2,ALL)
        ClearRexxMsg(rxmsg,16)
        DeleteRexxMsg(rxmsg)
ENDPROC


[Retour en haut] / [Retour aux articles] [Article précédent] / [Article suivant]