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
51 # Les valeurs decodees par optparse sont mises dans un objet dictionnaire-like.
52 # On l'utilise comme environnement de session.
55 # L'attribut "studies" de d_env est une liste dans laquelle on range les etudes de niveau global.
56 # Une étude est stockée dans un dictionnaire.
57 # La clé "comm" du dictionnaire donne le nom du fichier de commandes principal
58 # La clé (optionnelle) "pours" du dictionnaire donne les informations pour une poursuite
59 # La valeur associée à la clé est un dictionnaire qui contient les informations sur
60 # le nom du fichier de commandes de la poursuite (clé "comm"), une éventuelle poursuite
61 # (clé "pours") et les includes (clés entières associées à des noms de fichier).
65 # Les informations (dictionnaire) associées au fichier de commandes en cours de traitement
66 # sont stockées dans parser.values.current
67 # En general, il faut utiliser current et pas parser.values.studies car les informations
68 # sont stockées hiérarchiquement
71 def check_comm(option, opt_str, value, parser):
72 if not hasattr(parser.values,"studies"):
73 parser.values.studies=[]
75 if not os.path.isfile(value):
76 raise OptionValueError("le fichier de commandes %s n'existe pas" % value)
77 parser.values.comm.append(value)
78 d_study={"comm":value}
79 parser.values.current=d_study
80 parser.values.studies.append(d_study)
82 def check_poursuite(option, opt_str, value, parser):
83 if parser.values.comm is None:
84 raise OptionValueError("un fichier de commandes doit etre defini avant une poursuite %s" % value)
85 if not os.path.isfile(value):
86 raise OptionValueError("le fichier poursuite %s n'existe pas" % value)
87 #current : fichier de commandes en cours de traitement (dictionnaire des infos)
88 comm=parser.values.current
89 d_study={"comm":value}
91 parser.values.current=d_study
93 def check_include(option, opt_str, value, parser):
95 args=[int(parser.rargs[0]),parser.rargs[1]]
97 raise OptionValueError("include mal defini %s" % parser.rargs[0:2])
102 if parser.values.comm is None:
103 raise OptionValueError("un fichier de commandes doit etre defini avant un include %s" % args)
104 if not os.path.isfile(args[1]):
105 raise OptionValueError("le fichier include %s n'existe pas" % args[1])
107 comm=parser.values.current
108 comm[args[0]]=args[1]
111 def check_jdc(config,jdc,parser,fich):
113 Fonction : analyse une section de fichier .ini pour en extraire
114 les informations sur les fichiers poursuite et includes
115 définis dans cette section
117 parser : objet analyseur de la ligne de commande
118 fich : nom du fichier .ini en cours d'analyse
119 config : objet de la classe ConfigParser permettant de parser le fichier fich
120 jdc : nom de la section du fichier fich à analyser
124 for o in config.options(jdc):
126 p=config.get(jdc,"poursuite")
128 if not config.has_option(p,"comm"):
129 raise OptionValueError("jdc %s manque fichier comm dans section %s" % (fich,p))
130 comm=config.get(p,"comm")
131 if not os.path.isfile(comm):
132 raise OptionValueError("jdc %s, le fichier de commandes %s n'existe pas" % (fich,comm))
134 pours=check_jdc(config,p,parser,fich)
136 d_study["pours"]=pours
141 # si le parametre est un entier, il s'agit d'un include
142 inc=config.get(jdc,o)
145 if not os.path.isfile(inc):
146 raise OptionValueError("jdc %s fichier include %s, %s n'existe pas" % (fich,unit,inc))
151 def check_fich(option, opt_str, fich, parser):
153 Fonction : parse le fichier fich (format .ini)
155 option : option en cours de traitement
156 opt_str : chaine de caracteres utilisee par l'utilisateur
157 fich : nom du fichier .ini donné par l'utilisateur
158 parser : objet parseur des options de la ligne de commande
160 if not os.path.isfile(fich):
161 raise OptionValueError("le fichier jdc %s n'existe pas" % fich)
162 if parser.values.fich is None:
163 parser.values.fich=[]
164 parser.values.fich.append(fich)
165 if not hasattr(parser.values,"studies"):
166 parser.values.studies=[]
167 parser.values.comm=[]
168 config = ConfigParser.ConfigParser()
170 if not config.has_option("jdc","jdc"):
171 raise OptionValueError("jdc %s manque option jdc dans section jdc")
172 jdc=config.get("jdc","jdc")
174 if not config.has_option(jdc,"comm"):
175 raise OptionValueError("jdc %s manque fichier comm dans section %s" % (fich,jdc))
176 comm=config.get(jdc,"comm")
177 if not os.path.isfile(comm):
178 raise OptionValueError("jdc %s, le fichier de commandes %s n'existe pas" % (fich,comm))
179 parser.values.comm.append(comm)
181 d_study=check_jdc(config,jdc,parser,fich)
183 parser.values.studies.append(d_study)
185 def print_pours(d_pours,dec=''):
186 # Les fichiers includes d'abord
187 for k,v in d_pours.items():
188 if k in ("pours","comm"):continue
189 print dec+" include",k," :",v
191 if d_pours.has_key("pours"):
192 # Description de la poursuite
193 print dec+" fichier poursuite:",d_pours["pours"]["comm"]
194 print_pours(d_pours["pours"],dec=dec+"++")
198 if d_env.studies is None:return
199 for study in d_env.studies:
200 print "nom etude:",study["comm"]
201 print_pours(study,dec="++")
205 # creation du parser des options de la ligne de commande
207 parser=optparse.OptionParser(usage="usage: %prog [options]",version="%prog 1.13")
209 parser.add_option("-j","--jdc",dest="comm",type='string',
210 action="callback",callback=check_comm,
211 help="nom du fichier de commandes")
213 parser.add_option("-p","--poursuite", type="string",dest="pours",
214 action="callback", callback=check_poursuite,
215 help="nom du fichier poursuite")
217 parser.add_option("-i","--include",
218 action="callback", callback=check_include,
219 nargs=2, help="numero d'unite suivi du nom du fichier include")
221 parser.add_option("-f","--fich", type="string",dest="fich",
222 action="callback", callback=check_fich,
223 help="fichier decrivant une etude")
225 parser.add_option("-c","--cata", action="store", type="string",dest="cata",
226 help="version de catalogue a utiliser")
228 parser.add_option("-k","--kode", action="store", type="string",dest="code",
229 help="nom du code a utiliser",default=prefs.code)
231 parser.add_option("-d","--debug", action="store", type="int",dest="debug",
232 help="niveau de debug")
237 parser=create_parser()
238 (options,args)=parser.parse_args(args[1:])
239 if not hasattr(options,"studies"):
243 del parser.values.current
248 if os.path.isfile(file):
249 options.comm.append(file)
250 options.studies.append({"comm":file})
251 elif len(args)==1 and re.search('.comm',file):
256 parser.error("incorrect number of arguments")
257 options.comm.append(file)
258 options.studies.append({"comm":file})
260 parser.error("incorrect number of arguments")
267 def get_unit(d_study,appli):
269 Fonction : construit et retourne un dictionnaire contenant les informations
270 sur les fichiers poursuite et includes sous la forme adaptée
273 [None : nom_fichier, texte_source, unites_associees, # poursuite
274 numero_include : nom_fichier, texte_source, unites_associees, # include
277 d_study : dictionnaire de l'etude
278 appli : objet application EFICAS (permet d'acceder aux services comme get_source)
280 return get_dunit(d_study,appli)
282 def get_dunit(d_unit,appli):
284 if d_unit.has_key("pours"):
286 comm=d_unit["pours"]["comm"]
287 g=get_dunit(d_unit["pours"],appli)
288 text=appli.get_source(comm)
291 for k,v in d_unit.items():
292 if k in ("pours","comm"): continue
293 text=appli.get_source(v)