home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
prog
/
c
/
parse.lha
/
parse.doc
< prev
next >
Wrap
Text File
|
1992-08-11
|
10KB
|
204 lines
parse()
version 1.00
par Jean-Pierre Rivière
(English reader : please see file parse.edoc)
RESUME : parcoureur ("parser") de ligne de commande facile
d'emploi et suivant totalement les conventions
du systeme V pour le passage des options.
copyright (c) 1992 par Jean-Pierre Rivière.
Librement redistribuable et gratuit ("freeware").
Toute utilisation dans tout programme libre et gratuite
pour peu que la source dudit programme, si elle est
distribuée, inclut le présent paquetage logiciel ou
à défaut indique ses références et le moyen de se le
procurer.
Toute utilisation de ce paquetage se fait aux seuls
risques et périls de l'utilisateur, l'auteur déclinant
par avance toute responsabilité.
Ça suffit comme ça, place à la suite !
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Veille au respect scrupuleux des conventions Unix System V v4
Utilise pour cela une chaîne de formatage où toutes les options
sont indiquées dans un ordre quelconque mais avec un espace
derrière chaque option sans argument et un point-virgule derrière
chaque option avec un argument.
Si tout s'est bien passé, la valeur de retour est positive ou nulle,
égale au nombre d'options reconnues dans la ligne de commande.
Sinon elle est négative pour indiquer une erreur de syntaxe ou bien
que l'allocation dynamique de mémoire faite par la fonction n'a pas pû
être réalisée. Dans chacun de ces cas, il n'y a rien corespondant à la
description de ce qui a été éventuellement vu, et en conséquence il ne
faut pas essayer de le voir !
Si tout s'est bien passé, il faut désallouer manuellement la mémoire
allouée par la fonction parse() en appelant la fonction parse_cleanup().
Rappelons que toutes les options doivent précéder les éventuels
arguments, que leur ordre n'a aucune importance mais qu'elles ne doivent
pas être répétées, même si cela ne se fait pas de façon contradictoire.
parse() et parse_cleanup() sont deux fonctions que j'ai écrites sous
la forme d'un "module" C afin de faciliter la tâche du programmeur
quand il s'agit de gérer les multiples options que la ligne de commande
de son dernier utilitaire peut gérer. Mon but était puissance et ergo-
nomie et je peux dire qu'il est atteint.
Puissance car le respect strict des normes Open Software Foundation
est intégral. Puissance car simple à mettre en oeuvre et à faire évo-
luer. Le tout est donc ergonomique à la fois pour le programmeur et
pour l'utilisateur (uniformisation des interfaces sous shell rendue plus
facile donc plus répandue).
L'outil principal qui sert à ces deux fonctions est une bête chaîne
de caractères qui est une suite d'option et de type d'option : avec ou
sans argument.
Par exemple si votre programme s'emploie ainsi :
truc [-h] [-i] [-f <fichier>] [-o <dest>] [-v] [-R] <mode> [<type>]
alors le traitement automatique des options est réalisé grâce à la
chaine C suivante :
"h i f;o;v R "
ou encore, car l'ordre des options y est sans importance :
"R f;h i o;v "
Les caractères en position impaire sont les lettres des options. Un
point-virgule après une lettre indique que l'option prend un argument,
un espace qu'elle n'en prend pas. Attention, le caractère après la lettre
d'option est strictement obligatoire.
Attention aussi au fait que les options tiennent compte des majuscules
et des minuscules, et que normalement vous n'avez le droit qu'à des
lettres (ce dernier point n'est pas vérifiée mais c'est au programmeur
de décider ce qu'il fait en la matière).
En respect des conventions sus-citées, les lignes de commandes ci-
dessous sont acceptées (et correctement traitées ;-) (sous réserve bien
sûr que truc trouve que le nombre de ses arguments lui convienne) :
truc -i -hR -f merci mon gars
truc de_rien camarade
truc -o hara -hRi -f raime sapeur Camembert
truc -h - ---> ici - signifie entrée standard et n'est pas une option
truc -h -o brien -- -i --> -- indique la fin des options et donc
-i est le premier argument
truc -hi -o -i dabord --> l'argument d'une option à argument est
entièrement libre. -i est ici l'argument
de l'option o.
Mais les suivantes ne le sont pas :
truc -hRo hara kiri ---> les options à arguments doivent être isolées
truc -hRi -hv virus ---> pas de répétition d'option
truc -ohara sant ---> pas d'argument collé à l'option
truc -h - -i trema ---> le - est considéré comme une option vide
Ceci est peut-être hors-norme (je n'ai plus
celles-ci sous les yeux) mais j'ai trouvé
que si - est suivi d'un groupe commençant
par -, alors le premier - résultait sans
aucun doute d'une erreur de frappe (c'est
en tous cas vrai pour - --). Ne pas faire
cette hypothèse simplifierait le codage.
J'attends vos réactions...
Allez, voici une grammaire formelle de la chaîne de desciption :
descripteur ::= descripteur | option
option ::= (lettre type)
lettre ::= { a...z A...Z }
type ::= ( <espace> ; )
Et pour exploiter tout ça ? Voyez le code source. En définissant TEST
sur la ligne de compilation, vous aurez un exécutable qui vous montrera
que je ne vous mentais pas. Comme le codage de la fonction main() le
montre, l'idée est de faire :
if (parse(...) < 0) {
/* traitement des erreurs de syntaxe */
exit(1);
}
/* traitement des erreurs de logique propre au programme */
...
/* fin du programme */
parse_cleanup();
exit(0);
Pour plus de facilité, j'ai défini une structure regroupant les
données et permettant de déterminer précisément les erreurs éventuelles.
Je vous laisse voir le code, il est inutile que je le recopie, je
pense. Faites bien attention cependant aux remarques qui suivent :
- un appel à parse_cleanup() sans appel précédent à parse() est
illégal et retourne un code d'erreur. Sans danger cependant.
- un appel à parse_cleanup() suite à un appel précédent à parse() qui
a echoué est illégal car parse() à déjà tout nettoyé, et un code
d'erreur est renvoyé. Sans danger cependant.
- deux appels consécutifs à la même fonction parse() ou parse_cleanup()
sont interdits et le second appel renvoit un code d'erreur. Sans
danger cependant.
- l'appel à parse_cleanup() sert à libérer la mémoire allouée par
parse() dans le cas où celui-ci a réussi. N'oublier pas de
l'appeler, même si par exemple les options mises ne respectent pas
la logique de votre programme. Regardez le main() donné en exemple.
Pour utiliser ces deux fonctions, il est nécessaire qu'elles soient
compilées à part et de faire l'édition de lien avec le fichier objet
résultant, afin de garantir les procédés de vérification de séquence
d'appel indiqués précédemment.
J'ai défine plusieurs drapeaux pour la compilation du module parse.o :
NO_PARSE_ERR_MESS : s'il est défini, les messages d'erreur n'existent
pas. Vous n'aurez que les codes d'erreurs.
ENGLISH : s'il est défini et s'il y a des messages d'erreurs, ceux-ci
seront en anglais.
ERR_MESS_WITHOUT_LETTER : s'il est défini et qu'il y a des messages
d'erreurs, ceux-ci seront de simples chaînes de caractères à
imprimer directement. Par défault, ils comportent un %s pour
mettre à la bonne place l'option fautive et doivent donc être
utilisées avec une fonction du type printf.
Quand vous éditerez votre source, le seul drapeau à définir éven-
tuellement (et avant d'inclure parse.h) est NO_PARSE_ERR_MESS.
parse() et parse_cleanup() ne sont pas domaine public (car je ne veux
pas qu'un croquant m'en dépossède) mais sont librement redistribuables
et freeware. Leur emploi est encouragé chaque fois qu'une syntaxe de
type Unix est souhaitée (moi je n'ai jamais pu supporter getopt() car
il ne supporte pas bien les changement de syntaxe (ou alors je ne sais
pas m'en servir, mais de toute façon mon système est à la fois plus
simple, plus intuitif et plus performant.)). Il n'est pas autorisé de
le diffuser sans cette documentation ou pour un tarif excédant le prix
du support, la référence étant les disquettes AmigaLibDisk distribuées
par Fred Fish.
Allez, bonne programmation en C. Si c'est en autre chose, vous avez
toute latitude pour le faire. Envoyez moi alors votre traduction, ce
serait sympa de votre part. :^)
Mon adresse :
Jean-Pierre Rivière
13, rue Maison Dieu
75014 PARIS
FRANCE