        "Parsarg" : un package tcl d'analyse d'arguments

 ## Historique
 ## Objectif, Possibilités et limitations
 ## Syntaxe et options
 ## Valeur par défaut des options
 ## Spécification d'option
 ## Clés d'option reconnues
 ## Valeur par défault de certaines clé d'option :
 ## Exemples complet
 ## Organisation du programme 
 ## Complément

## Historique
--------------

20/11/02 (diam) dans xtext_style__apply : 
    Ajout d'une option boolean -reset (vraie par défaut) pour effacer 
    les style à réappliquer 
    Utilisé dans le switch de dispatching 
        switch -exact -- $xtext_style($w,$sheet,$style,-type) {...}

23/11/01 (diam) rajout de la  possibilité de modifier les valeurs par défauts 
    des options -mode et -cache de la procédure Parsarg_fullSpec :
    Exemple :
        Parsarg_fullSpec -setDefault_mode "strict"
        Parsarg_fullSpec -setDefault_cache 1
    
29/10/01 (diam) diverses mises à jour :
    - amélioration du type flagenum pour supporter les alias

10/10/01 (diam) diverses mises à jour :
    - Fonctionnalité complètes
    - changement de la valeur "-keep-" en "parsargs:keep" ou "=" pour 
      décrire une valeur par défaut qui ne doit pas être appliquée
      (i.e. quand on concerve la valeur de la variable sans
      l'initialiser) 

30/09/10 (diam) fin de refonte. A peu pret complet au viveau des
        fonctionnalités 

30/09/01 (diam) amélioration de Parsarg_fullSpec, ou suspension
        (future suppression ?) de Parsarg_lightSpec qui ne se sustifie plus 
        que pour une raison d'efficacité (fonctionnalité englobée dans la 
        variante "simplifiée" de la spec.
        
        CETTE DOC N'EST PLUS A JOUR
            1 - PLUS DE NOTION DE MODE (-type flag à la place)
            2 - plus de Parsarg_LightSpec
            
16/09/01 (diam) suppression argument arglist (choix automatique
        de args ou argv suivant [info level]
        
22/08/00 (diam) intégration à stead et passage en version 0.2

ww/05/97  (diam) création et nommage de la version en 0.1

## Objectif, Possibilités et limitations
-----------------------------------------

Gérer relativement simplement un nombre suffisant de cas fréquents
d'extraction d'arguments optionnels de procédures ou de scripts (:-) 

- La ligne de commande analysée est soit argv (au niveau global) soit
  args (si appelé depuis une procédure, se qui est le cas général)
- les options à extraire (définis par une clé ou switch) peuvent être ou 
  non suivies par une valeurs (on parlera de "flag" pour une option
  sans valeur), 
- la méta option "--" est reconnue pour indiquer que ce qui suit n'est 
  plus une option. Apres détection elle est extraite de la lioste, sauf 
  si on a passé l'option "-partial"
- Les options exploitées sont retirées de la liste analysée (qui est 
  généralement argv ou args suivant le contexte d'appel) 
- plusieurs clés peuvent être associées à une même option.
- chaque option est décrite par une spécification d'option,
- il est possible d'effectuer une vérification de "type" sur la valeur 
  extraite d'une option, ou encore de déclencher une action...
- la syntaxe d'appel de la procédure d'extraction est réduite au minimum 
  pour les cas simples mais est ouverte ou extensible pour les cas peu
  fréquents. 
- la présence d'une option non explicitement déclarée gérère une erreur, 
  sauf si l'option "-partial" a été utilisée.
- les fonctionnalités de ce package sont extensibles sans casser la
  compatibilité avec les programmes clients existant (ce fut par exemple
  le cas lors de l'ajout du nouveau type "flagenum" qui n'est qu'une
  surcouche au possibilites préexistantes) 


Pour simplifier l'implémentation, les restrictions suivantes sont 
imposées (pour l'instant) :
  
- pas de gestion des clés collés à leur valeur (mais faisable)
  Exemple non supporté :  
     myscript -Pmyprinter
  
- Une seule valeur peut être associée à une clé : mais il est toujours
  possible de passer plusieurs valeurs sous forme d'une seule liste.
  Exemple : 
     myscript -coord  $x1 $y1 $x2 $y2  -debug -- $file 
  Doit etre remplacé par :
     myscript -coord "$x1 $y1 $x2 $y2" -debug -- $file
  

## Syntaxe et options
---------------------

Commande :

    Parsarg_fullSpec ?keyValues? clientArrayName specs
 
arguments :
 
    clientArrayName : nom du tableau des valeurs à positionner
    specs : liste des spécifications des options.
    
    (La liste à analyser (argv ou args) est déterminée automatiquement)
 
options :

  -c
  -cache  : suppose la spec figée pour la procédure applelante,
           et mémorise la "compilation" de celle-ci en cache
           Nom de ce tableau **global** en -cache :
                upvar #0 parsarg_cacheSpec_<parentName>_swa$arg

  -mode <mode> impose un des modes d'analyse suivants :
       partial : les options inconnues sont retransmises dans args
                 et la chaine "--" éventuelles également/
                 Ceci permet à la procédures appelante de retransmettre
                 les options qu'elle ne gère pas.
       normal : options inconnues retransmise, mais "--" est absorbée
                Cela permet par exemple d'accepter un argument 
                (e.g. un nom de fichier) commençant par un "-" sans
                avoir hurler pour cause d'option inconnue.
       strict : option inconnue entraine "error", et "--" absorbé
                Cette option permet de détecter facilement une erreur dans un
                nom d'option (par exemple -refresch au lieu de -refresh)
                mais nécessite d'utiliser systématiquement la méta-option
                "--" dés qu'on ne connais pas a priori la valeur du
                premier argument non optionnel. 
       fast : en plus de strict, le mode d'option "-flag" n'est pas
              supporté, et la chaine d'arret "--" n'est pas gèrer
              (i.e. la liste d'arguments doit être paire)
         
       Remarque : 
           L'analyse s'arrete des qu'une option inconnue est détectée.
           Il faut donc que les options devant être extraites soient
           passées **avant** les options destinées à être extraites
           plus tard. 
           En effet, il n'est pas possible de traiter toutes les
           options connues en retransmettant les autres car on ne peut
           pas savoir si une option inconnue (i.e. à retransmettre) est
           un flag, ou nécessite un ou plusieurs arguments
           supplémentaires ! 

## Valeur par défaut des options
--------------------------------

Le choix difficile pour choisir la valeur par défaut de l'option -mode
m'a conduit à rendre cette valeur par défaut parametrable par : 
    Parsarg_fullSpec -setDefault_mode "strict"
pour la mise au point d'une application, afin de dépister les erreur 
d'option
    Parsarg_fullSpec -setDefault_mode "normal"
   
Ainsi, la valeur par défaut des options suivantes est modifiables :

-mode :

    Parsarg_fullSpec -setDefault_mode "strict"
        pour la mise au point d'une application, afin de dépister les erreur 
        d'option
    Parsarg_fullSpec -setDefault_mode "normal"
        En mode d'exploitation normal de façon à permettre l'utisateur
        de passer un argument commansant par "-xxx" sans etre obliger
        de la faire précéder par "--" 

-cache
    Parsarg_fullSpec -setDefault_cache 0
        Pour etre sur de reprendre en compte les dernieres version de la
        spécification d'option (pendant les test)
    Parsarg_fullSpec -setDefault_cache 1
        Pour tester la différence d'efficacité avec et sans cache
    


## Spécification d'option
-------------------------

Une spécification d'options est une liste paire de la forme :


    {switch_1 descr_1  switch_2 destcr_2 ...}

L'élément "switch_i" est le nom de l'option décrite (débarassée de son 
tiret); et "descr_i" est un descripteur de l'option. 

Un descripteur d'option peut prendre une des deux formes suivantes :

1 - une **forme générale** dite "standard" correspondant à une liste paire 
    de la forme :
         {?-key1 value1?  ?-key2 value2? ...}
      ou -keyi sont des clés d'option. 

2 - une **forme simplifiée** défini par un singleton.
    Cet élément représente une abbreviation d'une forme standard de 
    descripteur d'option.
    Pour l'instant, seules les quatre abréviations suivantes sont 
    définies :
    
    - Le caractère "-" pour indiquer que ce descripteur
      est identique au descripteur de l'option suivante.
      C'est la forme abbrégée de :
         {-alias <otherSwitch>}
      
    - le mot "flag" indique une version simplifiée d'une option 
      spécifiée par :
         {-mode flag  -default 0  -value 1}
     
    - une chaine arbitraire <defaultValue> (autre que les abbréviations 
      précédentes).  
      Celle-ci sera considérée comme la valeur par défaut d'une option 
      de type string, dont les autres caractéristiques sont standards.
      Elle est donc équivalente à :
         {-type string -defaut <defaultValue>}
     
    - une chaine spéciale "parsargs:keep" ou "=" à la place de la valeur par 
      défaut indique que la variable ne **doit pas** etre initialisée
      (une valeur par défaut "parsargs:equalSign" est remplacée par le
      signe "=" en cas de besoin)
      
    Par ailleurs, si une desciption d'option est vide, elle est
    interprétée comme une singleton contenant une chaine nulle. Ceci
    permet d'affecter une valeur par défaut "" par la syntaxe 
          myOption {}
    au lieu du singleton qui serait nécessaire :
          myOption {{}}
    Ces deux notation sont acceptée et représente une valeur par
    défaut vide
    
########################################################################
## Clés d'option reconnues
--------------------------

  -nop <string> (NON IMPLEMENTE)
  
      Ignoré : sert à commenter l'option concernée.
  
  -label <label> 
  
     décrit sommairement la signification de l'option recherchée,
     Peut être utilisé pour retourner une aide en cas d'erreur
     (i.e. switch non autorisé, valeur incorrect, ..)
     
               
  -type <type>
  
      Spécifie une information sur le "type" de la valeur liée à 
      l'option. Ceci permet d'effectuer des vérification, et de lever 
      une erreur si le type n'est pas respecté.
      
      La valeur par défaut est -type string.
      
      Le type "flag" est spécial car il indique la manière dont l'option
      doit etre extraite plutot que de donnée une information sur la 
      valeur elle-meme
      
   Les types suivants sont reconnus :
   
      -type flag   : option seule, sans valeur associée
          La variable correspondante est affectée à 1
          si ce flag est présent.
          La clé d'option -value et -default permettent 
          de controler les valeurs on et off
          
          Exemple :
          
             colomodel  {
                -type flag 
                -default color 
                -value monochrome
             }
            
      -type string : une chaine arbitraire (non vérifiée).
           C'est le type par défaut.


       Les autres types caractérisent la valeur associée à la clé
       et sont (seront ?) utilisés pour la vérification de celle-ci
       en levant une erreur si elle est incorrecte.
       
      -type boolean
      -type integer
        et d'une manière générale, tous les type supportés directement par 
        la commande "string is xxx" de tcl. 
      
      
      types de confort :
      ----------------
      
      Les deux types suivants sont en fait des facilités destinées à simplifier
      l'écriture de spécifications d'option déja possibles avec les options
      standards :
         
       -type enum
       
        - donne explicitement la liste des valeurs autorisée pour la
          variable associée à cette option.
        - impose le premier élément de la liste comme valeur par défaut
          pour la variable (mais qui peut etre "parsargs:keep")
       
        
        Permet d'ecrire :
               
               color {
                    -type enum
                    -values {rouge vert bleu}
               }
        à la place de son equivalent :
               
               color {
                    -type string
                    -default "rouge"
                    -regexp {^rouge|vert|bleu$}
               }
        
        
       -type enumflag
       
         - comme pour le type enum, mais permet en plus de créer autant 
           de flag que de valeur de l'énumération
         - la valeur par défaut correspond au premier élément de 
           l'énumération.
       
         Permet d'écrire :
         
            parsarg_fullSpec opt {
                mode {
                    -type flagenum
                    -values {exact regexp glob}
                }
            }
              
         à la place de :

            parsarg_fullSpec opt {
                mode {
                    -type flagenum
                    -default "exact"
                    -regexp {^exact|regexp|glob$}
                }
                exact {
                    -type flag
                    -default =
                    -value "exact"
                    -variable opt(-mode) 
                }
                regexp {
                    -type flag
                    -default =
                    -value "regexp"
                    -variable opt(-mode) 
                }
                glob {
                    -type flag
                    -default =
                    -value "glob"
                    -variable opt(-mode) 
                }
            }   
       
       (pas mal hein :-)
       
       Le type flagenum permet également de simuler des flag à double sens
       par exemple pour surcharger une valeur par défaut fluctuante par
         -nocase  ou -case en ecrivant :
       
       Ceci permet d'appeler d'utiliser au choix un appel tel que :
            
            if {$caseVal} {
                myProc -case
            } else {
                myProc -nocase
            }
            
       ou bien 
            
            myProc -caseval $caseVal ...
              
       De plus, on suppose qu'un flag ne contient pas de caracteres spéciaux
       ni d'espaces. Par consequent, on peut introduire un petite sucrerie
       pour avoir à la fois les avantages de la notion d'alias : la spec 
       précédente peut désormais s'écrire :
       
            set opt(caseval) [calculTresCompliqué ...]
            Parsarg_fullSpec opt {
                caseval {
                    -type flageval 
                    -values { {case c}  {nocase nc} }
                    -default =
                }
            }
       
       
       Autres idées pour plus tard si nécessaire
       -----------------------------------------
       
       -type bbox : un quadruplet de coordonnées
       -type color : définition de couleur ("#0F0", "green", ...)
       -type geometry : une chaine accepté par un window manager
            (par exemple "100*200+0+0" ou "-0+100")
            
       -type file :      un fichier existant.
       -type directory : un répertoire existant.
       -type filenew :   un fichier ou répertoire inexistant.

       -type stuck : réserver pour le switchs collé, comme dans
           lpr -Pmypriter

       Dans tous les cas, un type arbitraire peut être défini, simplement
       en définissant la procédure de vérification correspondante.
       
       Exemple de création d'un nouveau type :
       
       On crée une procédure de vérification qui sera appelée 
       automatiquement. Celle-ci doit ou bien générer une erreur,
       ou bien retourner une valeur considérée comme correcte (NON TESTE).
       Ceci permet à cette procédure d'avoir une focntion de filtrage 
       en transformant (ou en corrigeant) la valeur avant affectation.

            proc Parsarg_verifRegexp_nonNulReel {regexp string} {
                if {![string is real $string] || ($string == 0) } {
                    error "incorrect argument $string: should be\
                            e non nul real"
                } else {
                    return $string
                }
            }
          
       On peut alors utiliser le nouveau "type" :
         {
           myswitch {-type nonNulReel  -default xxx  ...}
         }
  
  
  -regexp <pattern>
  
      patterne que la valeur passée doit satisfaire ; une erreur est 
      levée si elle n'est pas satisfaite.
      Cette clé d'option permet des vérifications simples sur
      la valeur de l'argument.
      
      exemples :
      
         Si la valeur doit être un nombre hexa de deux chiffres :
         
            -regexp {^[a-zA-Z0-9][a-zA-Z0-9]$}
            
        Pour  définir un type énuméré :
        
            -regexp {^rouge|vert|bleu$}    
        
        
  
  -verifCmd <procName>
    
       Implémentation faite,  mais non testée.
  
       Permet à l'utilisateur de passer n'importe que procédure de 
       filtrage. La procédure en question doit avopir la meme signature
       que pour un type personnalisé : voir -type userType 
       (Fait double emploi avec -type userType ??)
       
  
  -value <effectiveValue>
      
      N'est utilisée QUE dans le mode flag.
      
      Valeur à affecter à la variable si le flag est présent. Si
      cette clé d'option est absente, sa valeur par défaut est 1 
      C'est une abbréviation de l'option :
      
            -values {0 1}
      
      Exemple 1 :
      
      Définir une variable énumérée positionnée par trois switch.
      
      parsarg_fullSpec arga {
          color {
             -default vert
             -regexp {^rouge|vert|bleu$}
          } 
          rouge { -type flag  -variable arga(-color)  -value rouge }
          vert  { -type flag  -variable arga(-color)  -value vert  }
          bleu  { -type flag  -variable arga(-color)  -value bleu  }
      }
      
      Exemple 1 bis : 
      
      Cet exemple est abbrégeable par :
      
      parsarg_fullSpec arga {
          color { -type enumflag  -values {vert rouge bleu} }
      }
      
      (c'est pas beau ça ? :-)
      
      
      Exemple 2 :
      
      Définir le flag "-debug" comme une abbreviation du couple option-
      valeur "-debuglevel 2" :
      
          verboselevel {
            -defaut 0
            -type integer
          }
          debug {-type flag -variable arga(verboselevel) -value 2}
          
          
      Exemple 3 :
      
      Changer les valeurs "0" et "1" d'un flag en "right" et "left" :
      
          left {
             -variable SCROLLSIDE 
             -type     flag
             -default  right
             -value    left
          }
      
      Exemple 3 bis :
      Cet exemple pourra s'ecrire par :
      
           left { 
                -type  flag  
                -variable SCROLLSIDE 
                -values {right left }  
           }
      
  -values <value list> (PAS ENCORE IMPLEMENTEE)
  
      liste de valeurs utilisé pour les type flag, enum et enumflag.
      La premiere valeur est la valeur par défaut (rendant inutile
      l'utilisation de -default <defaultValue> dans ce cas précis)
      
  -default <defaultvalue>
  
      valeur par défaut de la variable liée à cette option.
      En cas d'absence de cette information, la variable correspondante
      reste inchangée si l'option n'a pas été trouvée dans la liste à
      analyser. 
      
      
  -variable <varName>
  
      Spécifie le nom de la variable liée à l'option. 
      Par défaut : la variable utilisée est l'élément de tableau dont le nom 
      est passé en parametre, et dont l'indice est le nom du switch **avec 
      le tiret**. 
      
      Exemple : 
      
      si on veut analyser la ligne de commande suivante :
      
         myappli -debug -pat "*.tcl"  filename ...
      
      On peut analyser ces arguments par :
      
         Parsarg_fullSpec opt {
            debug {-type flag  -default 0 -variable DEBUG}
            pat   {-default *}
         }
      
      Le résultat de cet appel :
      
      -debug est détecté dans la ligne de commande, donc la variable
         DEBUG est positionnée à 1 (car -value n'est pas précisée).
         En l'absence de l'option de clé -variable, la variable
         "opt(-debug)" aurait été utilisée.
         
      -pat est détectée, aucune variable n'est précisé dans la spec, donc 
         c'est la variable opt(-pat) qui est affecté (à "*.tcl").
         Si l'option "-pat" n'avait pas de valeur par défaut de précisée,
         la chaine vide "" aurait été utilisée.
        Si la valeur par défault avait été "=" ou  "parsargs:keep"
        ou ... (à définir), l'abscence de l'option "-pat *.tcl" 
        aurait laisser la variable inchangée. 
      
         
   -eval <script>  
   
      Ce script est évaluer **après** l'affectation de la variable
      dans le contexte appelant. 
      
      Exemples : 
      
      debug   {-type flag  -action {set verbose(level) 2}}
      edit    {
         -type flag  
         -action {
            exec $env(PRINTER) [info script]
            exit
         }
      }
      editBis {-type boolean  -action editThisScript}
      

      QUESTIONS :
      
      - Prévoir gestion de substitution pour la valeur déctectée
        (par %v par exemple => permet de supprimer -verifier ?)

      - EU UTILE ? On peut toujours l'exécuter apres :

        if $arga(edit) {
           exec $env(PRINTER) [info script]
           exit
        }
   

     
   -alias <OtherSwitch>
        
     Indique que l'option ayant cette spécification est synonyme  
     de l'option <OtherSwitch>.
     Toutes autres clés d'option sont ignorées.
     
     Cette clé d'option est généralement utilisée indirectement sous sa
     forme abrégée "-". Et dans ce cas, la spécification de
     <<OtherSwitch>> doit suivre immédiatement cette option.  
     
     Exemple, la spécification suivante indique que les options -v ou
     -verboselevel sont synonymes : 
     
        verboselevel {-cle1 val1  -cle2 val2 ... }
        ...
        v {-alias verboselevel}
        
     Elle est équivalente à :
     
        v -
        verboselevel {-cle1 val1  -cle2 val2 ... }

########################################################################
## Valeur par défault de certaines clé d'option
-----------------------------------------------

- Si la clé  "-type" d'une spécif d'option n'est pas précisée :
    - si on a utiliser la clé "-alias xxx" alors on déduit "-type alias" 
    - sinon si on a utilisé "-values {xxx yyy} alors on déduit le
      le type "-type flagenum" (on aurait pu choisir "-type enum"
    - sinon on déduit "-type string" (le fourre-tout) 



########################################################################
## Exemples complet
-------------------

Utilisation de specs complètes (Parsarg_fullSpec) :
-----------------------------------------------

    # On peut affecter une valeur par défaut qui ne sera pas touche 
    # à l'analyse :

    set opt(-coord) [$canvas bbox $item] ;# i.e. {0 0 100 150}
    
    Parsarg_fullSpec opt {
    
       b           -
       bg          -
       background  white
       
       f     -
       fast  flag
       
       p     -
       prefix {}
       
       reset {
           -type boolean
           -default 1
           -label "préférable à un flag si on veut propager cette option"
       }

       bbox    -
       c       -
       coord   =
       
       fg          -
       foreground  {
          -type color
          -default black
       }
       
       mode     {
          -default  glob
          -regexp  {^glob|regexp|exact$}
          -label   "type de pattern de recherche"
       }  
       
       regexp   { -type flag  -variable opt(-mode)  -value regexp }
       glob     { -type flag  -variable opt(-mode)  -value glob }
       exact    { -type flag  -variable opt(-mode)  -value exact }
       
       Mode    {
            -type flagenum
            -values {Glob Regexp Exact}
       }
       
       v  - 
       verboselevel {-default 0  -type integer}
    
       d  -
       debug    {
          -type flag
          -variable opt(-verboselevel)
          -value 2
       }
       
       edit   {
          -type flag  
          -eval {
              exec $::env(PRINTER) [info script]
              exit
          }
       }
    }


Explication :
-------------

On appelle la procédure d'analyse "Parsarg_fullSpec" pour la liste argv
(qui doit être connu dans le contexte courant).
On souhaite que les valeurs extraites soient rangées dans le 
tableau "opt".


Les premières spécifications d'options sont exprimées sous la forme 
abrégée car ce sont soit des listes de un seul élément, soit des éléments 
vides.

- Les trois premières spécifs d'option permettent d'extraire une couleur 
  de fond passée par :
     myscript -b blue  
  ou 
     myscript -bg blue  
  ou 
     myscript -background blue
     
  La variable utilisée sera par défaut opt(background), laquelle
  sera préinitialisée à la valeur "white". 

- L'option "-fast" ou son abréviation "-f" sont des flags (donc sans
  parametres associées). La variable "opt(flag)" sera initialisée à "0"
  puis éventuellement affectée à la valeur "1" si cette option est
  présente sur la ligne de commande. 

- L'option "-prefix" est également spécifiée sous la forme abrégée car 
  sa spécif est une liste vide, donc la variable sera initialisée à "" 


Les spécifications d'options suivantes sont exprimées sous la forme 
normale car ce sont des listes paires.

- L'option "-coord" est bien spécifiées par sa forme abrégée car 
  singleton. . La  valeur par défaut étant "=" (aurait pu etre
  "parsargs:keep") la variable "opt(coord)" ne sera pas réinitialisée : 
  la valeur affectée juste avant l'appel de la procédure
  "Parsarg_fullSpec" ne sera écrasée que si l'option "-coord" ou "-c"
  est passée. 

- La spécif de l'option -foreground donnée sous sa forme standard permet
  de passer l'information de type.
  Une procédure de vérification de nom Parsarg_VerifType_color sera 
  automatiquement appelée -- si elle existe -- avec la valeur de la 
  couleur passé.
  Une erreur sera levée si la chaine n'est pas une couleur (par exemple 
  "blue" ou #FF ne sont pas des couleurs correctes).


- l'option mode est supposée recevoir une des trois valeurs possibles 
  glob, regexp ou exact ; laquelle sera vérifiée grace à la chaine 
  régulière spécifiée.

- Les trois flags suivants sont des abréviations de l'option -type
  précédente : ils partagent, sans l'initialiser,  la même variable que
  l'option "-type" ci-dessus.

- l'option Mode illustre la manière de décrire les mémes options que
  mode, et les trois flag correspondant d'une manière tres dense et lisible
  grâce au type flagenum.

- le flag "-debug" (alias "-d") est un autre exemple d'abréviation
  pour l'option "-verboselevel" (alias "-v").

- le flag "-edit" permet -- s'il est présent -- de lancer l'édition du 
  script par celui qui l'exécute. Néammoins, la variable "opt(-edit)"
  aura préalablement été effectée à "1", ce qui est sans importance. 



Autre exemple
-------------

Attention avec l'utilisation des specs simplifiée :

Ce qui suit est incorrect, car la première spec est interpréter comme
une spec complete !

    Parsarg_fullSpec data   {
        text            "Enter a value:"   <=== ERREUR
        default         ""
    }

Il faut corriger en :

    Parsarg_fullSpec data   {
        text            {"Enter a value:"}    <=== CORRECT
        default         ""
    }

Exemple d'appel correct avec spec simplifiée :

    Parsarg_fullSpec opt {
        buttons      {{ok rescan cancel gointo home root}}
        prompt       {"Choose a file"}
        directory    .
        cancelvalue  ""
        fileprompt   "File:"
        title        {"File Selector"}
        parent       .
    }


Autre exemple : utilisation d'un flag inversé :
---------------

Le nom du flag (-noconfirm) correspond à un nom de variable de sens 
opposé :

    Parsarg_fullSpec app {
        nc              -
        noconfirm       {
            -type     flag 
            -variable app(-confirm) 
            -default  1 
            -value    0 
        }
        
    }



########################################################################
## Organisation du programme
----------------------------

# Principe : 
# 
# 1 - lecture des options locales à la procédure Parsarg_fullSpec
#   
# 2 - compilation (i.e. analyse) et mémorisation la la spécif brutte
#     en une spécif standard (i.e non abrégée) dans un tableau de la forme :
#             set swa-level(-type) string
#             set swa-level(-default) "0"
#             set swa-debug(-type) flag
#             
#     Cette compilation n'est faite qu'une seule fois si l'option -cache est
#     utilisée.
#     
#     Le prefixe "swa" est en fait un chaine de la forme :
#     
#         ::parsarg_cache_$parentProcName
#     
#     si l'option -cache était utilisée ou sinon :
#     
#         parsarg_cache_$parentProcName
#     
#     Ce préfix est également utilisé pour mémorisé la liste des clés
#     autorisées. 
#     
#     Par exemple si une procédure "myProc" fait appel à parsarg_compilSpec
#     pour extraire ses arguments, et si on souhaite mémoriser en cache 
#     la spécification compilée, on aura création de la liste :
# 
#         ::parsarg_cache_myProc = {-f1 -flag1 -k1 -key1 -key1 ...}
#   
#     et des tableaux de la forme :
# 
#         ::parsarg_cache_myProc-f1(-alias) = "-flag1"
#         ::parsarg_cache_myProc-flag1(-default) = "0"
#         ::parsarg_cache_myProc-flag1(-type) = "flag"
#         ::parsarg_cache_myProc-flag1(-value) = "1"
#         ::parsarg_cache_myProc-flag1(-variable) = "arga(-flag1)"
#         ::parsarg_cache_myProc-flag1(-verifcmd) = "Parsarg_veriftype_flag"
#        
#     
#         
# 3 - analyse de la ligne de commande (args ou argv) et positionnement 
#     du tableau d'option
# 
# 
# Pour debug : pour afficher les tableaux des spec d'option de "MyProc":
#     eval report -v [info vars ::parsarg_cache_MyProc-*]
# 


########################################################################
## Complément
-------------

Pour les cas critiques, voici un exemple d'analyse d'arguments
ne nécessitant aucune procédure (=> plus efficace) :

    # 1 - intialisation des options
    set opt(-dry)     0
    set opt(-backname) ""
    
    # 2 - analyse de la ligne de commande
    while {[llength $args]} {
        switch -exact -- [lindex $args 0] {
          -- {
                set args [lreplace $args 0 0]
                break
          }
          -dry {
                set opt(-dry) 1
                set args [lreplace $args 0 0]
                continue
          }
          -backname {
                set opt(-backname) [lindex $args 1]
                set args [lreplace $args 0 1]
                continue
          }
          default {
                puts stdout "unknow option [lindex $args 0]"
                exit 1
          }
          default { break  ;# no more options}
        }
    }
    
    # 3 - lecture des arguments obligatoires
    set tclCmd   [lindex $args 0]
    set fileName [lindex $args 1]


# ./


