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

 ## Historique
 ## Objectif, Possibilits et limitations
 ## Syntaxe et options
 ## Valeur par dfaut des options
 ## Spcification d'option
 ## Cls d'option reconnues
 ## Valeur par dfault de certaines cl d'option :
 ## Exemples complet
 ## Organisation du programme 
 ## Complment

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

20/11/02 (diam) dans xtext_style__apply : 
    Ajout d'une option boolean -reset (vraie par dfaut) pour effacer 
    les style  rappliquer 
    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 dfauts 
    des options -mode et -cache de la procdure Parsarg_fullSpec :
    Exemple :
        Parsarg_fullSpec -setDefault_mode "strict"
        Parsarg_fullSpec -setDefault_cache 1
    
29/10/01 (diam) diverses mises  jour :
    - amlioration du type flagenum pour supporter les alias

10/10/01 (diam) diverses mises  jour :
    - Fonctionnalit compltes
    - changement de la valeur "-keep-" en "parsargs:keep" ou "=" pour 
      dcrire une valeur par dfaut qui ne doit pas tre applique
      (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
        fonctionnalits 

30/09/01 (diam) amlioration de Parsarg_fullSpec, ou suspension
        (future suppression ?) de Parsarg_lightSpec qui ne se sustifie plus 
        que pour une raison d'efficacit (fonctionnalit englobe dans la 
        variante "simplifie" 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) intgration  stead et passage en version 0.2

ww/05/97  (diam) cration et nommage de la version en 0.1

## Objectif, Possibilits et limitations
-----------------------------------------

Grer relativement simplement un nombre suffisant de cas frquents
d'extraction d'arguments optionnels de procdures ou de scripts (:-) 

- La ligne de commande analyse est soit argv (au niveau global) soit
  args (si appel depuis une procdure, se qui est le cas gnral)
- les options  extraire (dfinis par une cl ou switch) peuvent tre ou 
  non suivies par une valeurs (on parlera de "flag" pour une option
  sans valeur), 
- la mta option "--" est reconnue pour indiquer que ce qui suit n'est 
  plus une option. Apres dtection elle est extraite de la lioste, sauf 
  si on a pass l'option "-partial"
- Les options exploites sont retires de la liste analyse (qui est 
  gnralement argv ou args suivant le contexte d'appel) 
- plusieurs cls peuvent tre associes  une mme option.
- chaque option est dcrite par une spcification d'option,
- il est possible d'effectuer une vrification de "type" sur la valeur 
  extraite d'une option, ou encore de dclencher une action...
- la syntaxe d'appel de la procdure d'extraction est rduite au minimum 
  pour les cas simples mais est ouverte ou extensible pour les cas peu
  frquents. 
- la prsence d'une option non explicitement dclare grre une erreur, 
  sauf si l'option "-partial" a t utilise.
- les fonctionnalits 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 prexistantes) 


Pour simplifier l'implmentation, les restrictions suivantes sont 
imposes (pour l'instant) :
  
- pas de gestion des cls colls  leur valeur (mais faisable)
  Exemple non support :  
     myscript -Pmyprinter
  
- Une seule valeur peut tre associe  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 spcifications des options.
    
    (La liste  analyser (argv ou args) est dtermine automatiquement)
 
options :

  -c
  -cache  : suppose la spec fige pour la procdure applelante,
           et mmorise 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 procdures appelante de retransmettre
                 les options qu'elle ne gre pas.
       normal : options inconnues retransmise, mais "--" est absorbe
                Cela permet par exemple d'accepter un argument 
                (e.g. un nom de fichier) commenant par un "-" sans
                avoir hurler pour cause d'option inconnue.
       strict : option inconnue entraine "error", et "--" absorb
                Cette option permet de dtecter facilement une erreur dans un
                nom d'option (par exemple -refresch au lieu de -refresh)
                mais ncessite d'utiliser systmatiquement la mta-option
                "--" ds 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 grer
              (i.e. la liste d'arguments doit tre paire)
         
       Remarque : 
           L'analyse s'arrete des qu'une option inconnue est dtecte.
           Il faut donc que les options devant tre extraites soient
           passes **avant** les options destines  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 ncessite un ou plusieurs arguments
           supplmentaires ! 

## Valeur par dfaut des options
--------------------------------

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

-mode :

    Parsarg_fullSpec -setDefault_mode "strict"
        pour la mise au point d'une application, afin de dpister les erreur 
        d'option
    Parsarg_fullSpec -setDefault_mode "normal"
        En mode d'exploitation normal de faon  permettre l'utisateur
        de passer un argument commansant par "-xxx" sans etre obliger
        de la faire prcder par "--" 

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


## Spcification d'option
-------------------------

Une spcification d'options est une liste paire de la forme :


    {switch_1 descr_1  switch_2 destcr_2 ...}

L'lment "switch_i" est le nom de l'option dcrite (dbarasse 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 gnrale** dite "standard" correspondant  une liste paire 
    de la forme :
         {?-key1 value1?  ?-key2 value2? ...}
      ou -keyi sont des cls d'option. 

2 - une **forme simplifie** dfini par un singleton.
    Cet lment reprsente une abbreviation d'une forme standard de 
    descripteur d'option.
    Pour l'instant, seules les quatre abrviations suivantes sont 
    dfinies :
    
    - Le caractre "-" pour indiquer que ce descripteur
      est identique au descripteur de l'option suivante.
      C'est la forme abbrge de :
         {-alias <otherSwitch>}
      
    - le mot "flag" indique une version simplifie d'une option 
      spcifie par :
         {-mode flag  -default 0  -value 1}
     
    - une chaine arbitraire <defaultValue> (autre que les abbrviations 
      prcdentes).  
      Celle-ci sera considre comme la valeur par dfaut d'une option 
      de type string, dont les autres caractristiques sont standards.
      Elle est donc quivalente  :
         {-type string -defaut <defaultValue>}
     
    - une chaine spciale "parsargs:keep" ou "="  la place de la valeur par 
      dfaut indique que la variable ne **doit pas** etre initialise
      (une valeur par dfaut "parsargs:equalSign" est remplace par le
      signe "=" en cas de besoin)
      
    Par ailleurs, si une desciption d'option est vide, elle est
    interprte comme une singleton contenant une chaine nulle. Ceci
    permet d'affecter une valeur par dfaut "" par la syntaxe 
          myOption {}
    au lieu du singleton qui serait ncessaire :
          myOption {{}}
    Ces deux notation sont accepte et reprsente une valeur par
    dfaut vide
    
########################################################################
## Cls d'option reconnues
--------------------------

  -nop <string> (NON IMPLEMENTE)
  
      Ignor : sert  commenter l'option concerne.
  
  -label <label> 
  
     dcrit sommairement la signification de l'option recherche,
     Peut tre utilis pour retourner une aide en cas d'erreur
     (i.e. switch non autoris, valeur incorrect, ..)
     
               
  -type <type>
  
      Spcifie une information sur le "type" de la valeur lie  
      l'option. Ceci permet d'effectuer des vrification, et de lever 
      une erreur si le type n'est pas respect.
      
      La valeur par dfaut est -type string.
      
      Le type "flag" est spcial car il indique la manire dont l'option
      doit etre extraite plutot que de donne une information sur la 
      valeur elle-meme
      
   Les types suivants sont reconnus :
   
      -type flag   : option seule, sans valeur associe
          La variable correspondante est affecte  1
          si ce flag est prsent.
          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 vrifie).
           C'est le type par dfaut.


       Les autres types caractrisent la valeur associe  la cl
       et sont (seront ?) utiliss pour la vrification de celle-ci
       en levant une erreur si elle est incorrecte.
       
      -type boolean
      -type integer
        et d'une manire gnrale, tous les type supports directement par 
        la commande "string is xxx" de tcl. 
      
      
      types de confort :
      ----------------
      
      Les deux types suivants sont en fait des facilits destines  simplifier
      l'criture de spcifications d'option dja possibles avec les options
      standards :
         
       -type enum
       
        - donne explicitement la liste des valeurs autorise pour la
          variable associe  cette option.
        - impose le premier lment de la liste comme valeur par dfaut
          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 crer autant 
           de flag que de valeur de l'numration
         - la valeur par dfaut correspond au premier lment de 
           l'numration.
       
         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 dfaut 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 spciaux
       ni d'espaces. Par consequent, on peut introduire un petite sucrerie
       pour avoir  la fois les avantages de la notion d'alias : la spec 
       prcdente peut dsormais s'crire :
       
            set opt(caseval) [calculTresCompliqu ...]
            Parsarg_fullSpec opt {
                caseval {
                    -type flageval 
                    -values { {case c}  {nocase nc} }
                    -default =
                }
            }
       
       
       Autres ides pour plus tard si ncessaire
       -----------------------------------------
       
       -type bbox : un quadruplet de coordonnes
       -type color : dfinition 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 rpertoire existant.
       -type filenew :   un fichier ou rpertoire inexistant.

       -type stuck : rserver pour le switchs coll, comme dans
           lpr -Pmypriter

       Dans tous les cas, un type arbitraire peut tre dfini, simplement
       en dfinissant la procdure de vrification correspondante.
       
       Exemple de cration d'un nouveau type :
       
       On cre une procdure de vrification qui sera appele 
       automatiquement. Celle-ci doit ou bien gnrer une erreur,
       ou bien retourner une valeur considre comme correcte (NON TESTE).
       Ceci permet  cette procdure 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 passe doit satisfaire ; une erreur est 
      leve si elle n'est pas satisfaite.
      Cette cl d'option permet des vrifications 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  dfinir un type numr :
        
            -regexp {^rouge|vert|bleu$}    
        
        
  
  -verifCmd <procName>
    
       Implmentation faite,  mais non teste.
  
       Permet  l'utilisateur de passer n'importe que procdure de 
       filtrage. La procdure 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 utilise QUE dans le mode flag.
      
      Valeur  affecter  la variable si le flag est prsent. Si
      cette cl d'option est absente, sa valeur par dfaut est 1 
      C'est une abbrviation de l'option :
      
            -values {0 1}
      
      Exemple 1 :
      
      Dfinir une variable numre positionne 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 abbrgeable par :
      
      parsarg_fullSpec arga {
          color { -type enumflag  -values {vert rouge bleu} }
      }
      
      (c'est pas beau a ? :-)
      
      
      Exemple 2 :
      
      Dfinir 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 dfaut (rendant inutile
      l'utilisation de -default <defaultValue> dans ce cas prcis)
      
  -default <defaultvalue>
  
      valeur par dfaut de la variable lie  cette option.
      En cas d'absence de cette information, la variable correspondante
      reste inchange si l'option n'a pas t trouve dans la liste 
      analyser. 
      
      
  -variable <varName>
  
      Spcifie le nom de la variable lie  l'option. 
      Par dfaut : la variable utilise est l'lment 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 rsultat de cet appel :
      
      -debug est dtect dans la ligne de commande, donc la variable
         DEBUG est positionne  1 (car -value n'est pas prcise).
         En l'absence de l'option de cl -variable, la variable
         "opt(-debug)" aurait t utilise.
         
      -pat est dtecte, aucune variable n'est prcis dans la spec, donc 
         c'est la variable opt(-pat) qui est affect ( "*.tcl").
         Si l'option "-pat" n'avait pas de valeur par dfaut de prcise,
         la chaine vide "" aurait t utilise.
        Si la valeur par dfault avait t "=" ou  "parsargs:keep"
        ou ... ( dfinir), l'abscence de l'option "-pat *.tcl" 
        aurait laisser la variable inchange. 
      
         
   -eval <script>  
   
      Ce script est valuer **aprs** 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 :
      
      - Prvoir gestion de substitution pour la valeur dctecte
        (par %v par exemple => permet de supprimer -verifier ?)

      - EU UTILE ? On peut toujours l'excuter apres :

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

     
   -alias <OtherSwitch>
        
     Indique que l'option ayant cette spcification est synonyme  
     de l'option <OtherSwitch>.
     Toutes autres cls d'option sont ignores.
     
     Cette cl d'option est gnralement utilise indirectement sous sa
     forme abrge "-". Et dans ce cas, la spcification de
     <<OtherSwitch>> doit suivre immdiatement cette option.  
     
     Exemple, la spcification 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 dfault de certaines cl d'option
-----------------------------------------------

- Si la cl  "-type" d'une spcif d'option n'est pas prcise :
    - si on a utiliser la cl "-alias xxx" alors on dduit "-type alias" 
    - sinon si on a utilis "-values {xxx yyy} alors on dduit le
      le type "-type flagenum" (on aurait pu choisir "-type enum"
    - sinon on dduit "-type string" (le fourre-tout) 



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

Utilisation de specs compltes (Parsarg_fullSpec) :
-----------------------------------------------

    # On peut affecter une valeur par dfaut 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 "prfrable  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 procdure d'analyse "Parsarg_fullSpec" pour la liste argv
(qui doit tre connu dans le contexte courant).
On souhaite que les valeurs extraites soient ranges dans le 
tableau "opt".


Les premires spcifications d'options sont exprimes sous la forme 
abrge car ce sont soit des listes de un seul lment, soit des lments 
vides.

- Les trois premires spcifs d'option permettent d'extraire une couleur 
  de fond passe par :
     myscript -b blue  
  ou 
     myscript -bg blue  
  ou 
     myscript -background blue
     
  La variable utilise sera par dfaut opt(background), laquelle
  sera prinitialise  la valeur "white". 

- L'option "-fast" ou son abrviation "-f" sont des flags (donc sans
  parametres associes). La variable "opt(flag)" sera initialise  "0"
  puis ventuellement affecte  la valeur "1" si cette option est
  prsente sur la ligne de commande. 

- L'option "-prefix" est galement spcifie sous la forme abrge car 
  sa spcif est une liste vide, donc la variable sera initialise  "" 


Les spcifications d'options suivantes sont exprimes sous la forme 
normale car ce sont des listes paires.

- L'option "-coord" est bien spcifies par sa forme abrge car 
  singleton. . La  valeur par dfaut tant "=" (aurait pu etre
  "parsargs:keep") la variable "opt(coord)" ne sera pas rinitialise : 
  la valeur affecte juste avant l'appel de la procdure
  "Parsarg_fullSpec" ne sera crase que si l'option "-coord" ou "-c"
  est passe. 

- La spcif de l'option -foreground donne sous sa forme standard permet
  de passer l'information de type.
  Une procdure de vrification de nom Parsarg_VerifType_color sera 
  automatiquement appele -- si elle existe -- avec la valeur de la 
  couleur pass.
  Une erreur sera leve si la chaine n'est pas une couleur (par exemple 
  "blue" ou #FF ne sont pas des couleurs correctes).


- l'option mode est suppose recevoir une des trois valeurs possibles 
  glob, regexp ou exact ; laquelle sera vrifie grace  la chaine 
  rgulire spcifie.

- Les trois flags suivants sont des abrviations de l'option -type
  prcdente : ils partagent, sans l'initialiser,  la mme variable que
  l'option "-type" ci-dessus.

- l'option Mode illustre la manire de dcrire les mmes options que
  mode, et les trois flag correspondant d'une manire tres dense et lisible
  grce au type flagenum.

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

- le flag "-edit" permet -- s'il est prsent -- de lancer l'dition du 
  script par celui qui l'excute. Nammoins, la variable "opt(-edit)"
  aura pralablement t effecte  "1", ce qui est sans importance. 



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

Attention avec l'utilisation des specs simplifie :

Ce qui suit est incorrect, car la premire spec est interprter 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 simplifie :

    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 procdure Parsarg_fullSpec
#   
# 2 - compilation (i.e. analyse) et mmorisation la la spcif brutte
#     en une spcif standard (i.e non abrge) 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
#     utilise.
#     
#     Le prefixe "swa" est en fait un chaine de la forme :
#     
#         ::parsarg_cache_$parentProcName
#     
#     si l'option -cache tait utilise ou sinon :
#     
#         parsarg_cache_$parentProcName
#     
#     Ce prfix est galement utilis pour mmoris la liste des cls
#     autorises. 
#     
#     Par exemple si une procdure "myProc" fait appel  parsarg_compilSpec
#     pour extraire ses arguments, et si on souhaite mmoriser en cache 
#     la spcification compile, on aura cration 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-*]
# 


########################################################################
## Complment
-------------

Pour les cas critiques, voici un exemple d'analyse d'arguments
ne ncessitant aucune procdure (=> 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]


# ./


