1 # -*- coding: iso-8859-15 -*-
3 Ce module centralise les informations issues de la ligne de commande.
5 La ligne de commande est parsee avec l'aide du module python optparse.
6 Les options possibles sont : -c, -j, -p, -d, -i, -f comme definies ci-dessous.
8 Un exemple typique d'utilisation est :
9 >>> ./appli.py -c V7.3 -d 1 -j aa -i 11 iii -p ppp -i 22 ii -j bb -f ff
11 qui demande a l'application d'ouvrir trois jeux de commandes.
13 Le premier (aa) a un include (11,iii) et est la suite du fichier poursuite ppp
14 qui a lui meme un include (22,ii).
16 Le deuxieme bb est un jeu de commandes simple.
18 Le troisieme est decrit dans le fichier ff de type .ini
19 qui est parse par le module ConfigParser.
20 Chaque section du fichier decrit un jeu de commandes.
21 Un include est specifie par: numero logique=nom du fichier
22 Une poursuite est specifiee par: poursuite=reference a un jeu de commande
23 Cette reference correspond a un nom de section decrivant le jeu de commandes.
24 Le jeu de commandes maitre est donne par l'entree globale jdc dans la section jdc.
37 La session utilisera le catalogue V7.3 en mode debug.
42 from optparse import OptionValueError
44 from Tools import optparse
45 from Tools.optparse import OptionValueError
50 # Les valeurs decodees par optparse sont mises dans un objet dictionnaire-like.
51 # On l'utilise comme environnement de session.
54 # L'attribut "studies" de d_env est une liste dans laquelle on range les etudes de niveau global.
55 # Une étude est stockée dans un dictionnaire.
56 # La clé "comm" du dictionnaire donne le nom du fichier de commandes principal
57 # La clé (optionnelle) "pours" du dictionnaire donne les informations pour une poursuite
58 # La valeur associée à la clé est un dictionnaire qui contient les informations sur
59 # le nom du fichier de commandes de la poursuite (clé "comm"), une éventuelle poursuite
60 # (clé "pours") et les includes (clés entières associées à des noms de fichier).
64 # Les informations (dictionnaire) associées au fichier de commandes en cours de traitement
65 # sont stockées dans parser.values.current
66 # En general, il faut utiliser current et pas parser.values.studies car les informations
67 # sont stockées hiérarchiquement
70 def check_comm(option, opt_str, value, parser):
71 if not hasattr(parser.values,"studies"):
72 parser.values.studies=[]
74 if not os.path.isfile(value):
75 raise OptionValueError("le fichier de commandes %s n'existe pas" % value)
76 parser.values.comm.append(value)
77 d_study={"comm":value}
78 parser.values.current=d_study
79 parser.values.studies.append(d_study)
81 def check_poursuite(option, opt_str, value, parser):
82 if parser.values.comm is None:
83 raise OptionValueError("un fichier de commandes doit etre defini avant une poursuite %s" % value)
84 if not os.path.isfile(value):
85 raise OptionValueError("le fichier poursuite %s n'existe pas" % value)
86 #current : fichier de commandes en cours de traitement (dictionnaire des infos)
87 comm=parser.values.current
88 d_study={"comm":value}
90 parser.values.current=d_study
92 def check_include(option, opt_str, value, parser):
94 args=[int(parser.rargs[0]),parser.rargs[1]]
96 raise OptionValueError("include mal defini %s" % parser.rargs[0:2])
101 if parser.values.comm is None:
102 raise OptionValueError("un fichier de commandes doit etre defini avant un include %s" % args)
103 if not os.path.isfile(args[1]):
104 raise OptionValueError("le fichier include %s n'existe pas" % args[1])
106 comm=parser.values.current
107 comm[args[0]]=args[1]
110 def check_jdc(config,jdc,parser,fich):
112 Fonction : analyse une section de fichier .ini pour en extraire
113 les informations sur les fichiers poursuite et includes
114 définis dans cette section
116 parser : objet analyseur de la ligne de commande
117 fich : nom du fichier .ini en cours d'analyse
118 config : objet de la classe ConfigParser permettant de parser le fichier fich
119 jdc : nom de la section du fichier fich à analyser
123 for o in config.options(jdc):
125 p=config.get(jdc,"poursuite")
127 if not config.has_option(p,"comm"):
128 raise OptionValueError("jdc %s manque fichier comm dans section %s" % (fich,p))
129 comm=config.get(p,"comm")
130 if not os.path.isfile(comm):
131 raise OptionValueError("jdc %s, le fichier de commandes %s n'existe pas" % (fich,comm))
133 pours=check_jdc(config,p,parser,fich)
135 d_study["pours"]=pours
140 # si le parametre est un entier, il s'agit d'un include
141 inc=config.get(jdc,o)
144 if not os.path.isfile(inc):
145 raise OptionValueError("jdc %s fichier include %s, %s n'existe pas" % (fich,unit,inc))
150 def check_fich(option, opt_str, fich, parser):
152 Fonction : parse le fichier fich (format .ini)
154 option : option en cours de traitement
155 opt_str : chaine de caracteres utilisee par l'utilisateur
156 fich : nom du fichier .ini donné par l'utilisateur
157 parser : objet parseur des options de la ligne de commande
159 if not os.path.isfile(fich):
160 raise OptionValueError("le fichier jdc %s n'existe pas" % fich)
161 if parser.values.fich is None:
162 parser.values.fich=[]
163 parser.values.fich.append(fich)
164 if not hasattr(parser.values,"studies"):
165 parser.values.studies=[]
166 parser.values.comm=[]
167 config = ConfigParser.ConfigParser()
169 if not config.has_option("jdc","jdc"):
170 raise OptionValueError("jdc %s manque option jdc dans section jdc")
171 jdc=config.get("jdc","jdc")
173 if not config.has_option(jdc,"comm"):
174 raise OptionValueError("jdc %s manque fichier comm dans section %s" % (fich,jdc))
175 comm=config.get(jdc,"comm")
176 if not os.path.isfile(comm):
177 raise OptionValueError("jdc %s, le fichier de commandes %s n'existe pas" % (fich,comm))
178 parser.values.comm.append(comm)
180 d_study=check_jdc(config,jdc,parser,fich)
182 parser.values.studies.append(d_study)
184 def print_pours(d_pours,dec=''):
185 # Les fichiers includes d'abord
186 for k,v in d_pours.items():
187 if k in ("pours","comm"):continue
188 print dec+" include",k," :",v
190 if d_pours.has_key("pours"):
191 # Description de la poursuite
192 print dec+" fichier poursuite:",d_pours["pours"]["comm"]
193 print_pours(d_pours["pours"],dec=dec+"++")
197 if d_env.studies is None:return
198 for study in d_env.studies:
199 print "nom etude:",study["comm"]
200 print_pours(study,dec="++")
204 # creation du parser des options de la ligne de commande
205 parser=optparse.OptionParser(usage="usage: %prog [options]",version="%prog 1.8")
207 parser.add_option("-j","--jdc",dest="comm",type='string',
208 action="callback",callback=check_comm,
209 help="nom du fichier de commandes")
210 parser.add_option("-p","--poursuite", type="string",dest="pours",
211 action="callback", callback=check_poursuite,
212 help="nom du fichier poursuite")
213 parser.add_option("-i","--include",
214 action="callback", callback=check_include,
215 nargs=2, help="numero d'unite suivi du nom du fichier include")
217 parser.add_option("-f","--fich", type="string",dest="fich",
218 action="callback", callback=check_fich,
219 help="fichier decrivant une etude")
221 parser.add_option("-c","--cata", action="store", type="string",dest="cata",
222 help="version de catalogue a utiliser")
224 parser.add_option("-d","--debug", action="store", type="int",dest="debug",
225 help="niveau de debug")
230 parser=create_parser()
231 (options,args)=parser.parse_args(args[1:])
232 if not hasattr(options,"studies"):
236 del parser.values.current
241 if os.path.isfile(file):
242 options.comm.append(file)
243 options.studies.append({"comm":file})
245 parser.error("incorrect number of arguments")
252 def get_unit(d_study,appli):
254 Fonction : construit et retourne un dictionnaire contenant les informations
255 sur les fichiers poursuite et includes sous la forme adaptée
257 [None : nom_fichier, texte_source, unites_associees, # poursuite
258 numero_include : nom_fichier, texte_source, unites_associees, # include
260 d_study : dictionnaire de l'etude
261 appli : objet application EFICAS (permet d'acceder aux services comme get_source)
263 return get_dunit(d_study,appli)
265 def get_dunit(d_unit,appli):
267 if d_unit.has_key("pours"):
269 comm=d_unit["pours"]["comm"]
270 g=get_dunit(d_unit["pours"],appli)
271 text=appli.get_source(comm)
274 for k,v in d_unit.items():
275 if k in ("pours","comm"): continue
276 text=appli.get_source(v)