The Gaudi Framework  v41r0 (bdbe7744)
Loading...
Searching...
No Matches
GaudiKernel.ProcessJobOptions.JobOptsParser Class Reference

Public Member Functions

 __init__ (self)
 parse (self, file)

Public Attributes

dict units = {}
dict defines = {}

Static Public Attributes

 comment = re.compile(r"(//.*)$")
 comment_in_string = re.compile(r'(["\']).*//.*\1')
 directive = re.compile(r"^\s*#\s*([\w!]+)\s*(.*)\s*$")
tuple comment_ml = (re.compile(r"/\*"), re.compile(r"\*/"))
str statement_sep = ";"
 reference = re.compile(r"^@([\w.]*)$")

Protected Member Functions

 _include (self, file, function)
 _parse_units (self, file)
 _eval_statement (self, statement)

Protected Attributes

 _parse_units

Detailed Description

Definition at line 174 of file ProcessJobOptions.py.

Constructor & Destructor Documentation

◆ __init__()

GaudiKernel.ProcessJobOptions.JobOptsParser.__init__ ( self)

Definition at line 184 of file ProcessJobOptions.py.

184 def __init__(self):
185 # parser level states
186 self.units = {}
187 self.defines = {}
188

Member Function Documentation

◆ _eval_statement()

GaudiKernel.ProcessJobOptions.JobOptsParser._eval_statement ( self,
statement )
protected

Definition at line 341 of file ProcessJobOptions.py.

341 def _eval_statement(self, statement):
342 from GaudiKernel.Proxy.Configurable import (
343 Configurable,
344 ConfigurableGeneric,
345 PropertyReference,
346 )
347
348 # statement = statement.replace("\n","").strip()
349 _log.info("%s%s", statement, self.statement_sep)
350
351 property, value = statement.split("=", 1)
352
353 inc = None
354 if property[-1] in ["+", "-"]:
355 inc = property[-1]
356 property = property[:-1]
357
358 property = property.strip()
359 value = value.strip()
360
361 # find the configurable to apply the property to
362 # parent_cfg = None
363 # while '.' in property:
364 # component, property = property.split('.',1)
365 # if parent_cfg:
366 # if hasattr(parent_cfg,component):
367 # cfg = getattr(parent_cfg,component)
368 # else:
369 # cfg = ConfigurableGeneric(component)
370 # setattr(parent_cfg,component,cfg)
371 # else:
372 # cfg = ConfigurableGeneric(component)
373 # parent_cfg = cfg
374
375 # remove spaces around dots
376 property = ".".join([w.strip() for w in property.split(".")])
377 component, property = property.rsplit(".", 1)
378 if component in Configurable.allConfigurables:
379 cfg = Configurable.allConfigurables[component]
380 else:
381 cfg = ConfigurableGeneric(component)
382
383 # value = os.path.expandvars(value)
384 value = value.replace("true", "True").replace("false", "False")
385 if value[0] == "{":
386 # Try to guess if the values looks like a dictionary
387 if ":" in value and not (
388 value[: value.index(":")].count('"') % 2
389 or value[: value.index(":")].count("'") % 2
390 ):
391 # for dictionaries, keep the surrounding {}
392 value = "{" + value[1:-1].replace("{", "[").replace("}", "]") + "}"
393 else: # otherwise replace all {} with []
394 value = value.replace("{", "[").replace("}", "]")
395
396 # We must escape '\' because eval tends to interpret them
397 value = value.replace("\\", "\\\\")
398 # Restore special cases ('\n', '\t' and '\"') (see GAUDI-1001)
399 value = (
400 value.replace(r"\\n", r"\n").replace(r"\\t", r"\t").replace(r'\\"', r"\"")
401 )
402 # replace r'\n' and r'\t' that are outside double quoted strings
403 value = '"'.join(
404 [
405 (v if i % 2 else re.sub(r"\\[nt]", " ", v))
406 for i, v in enumerate(value.split('"'))
407 ]
408 )
409
410 # interprete the @ operator
411 m = self.reference.match(value)
412 if m:
413 # this allows late binding of references
414 value = PropertyReference(m.group(1))
415 else:
416 value = eval(value, self.units)
417
418 # if type(value) is str : value = os.path.expandvars(value)
419 # elif type(value) is list : value = [ type(item) is str and os.path.expandvars(item) or item for item in value ]
420
421 if property not in cfg.__slots__ and not hasattr(cfg, property):
422 # check if the case of the property is wrong (old options are case insensitive)
423 lprop = property.lower()
424 for p in cfg.__slots__:
425 if lprop == p.lower():
426 _log.warning(
427 "property '%s' was requested for %s, but the correct spelling is '%s'",
428 property,
429 cfg.name(),
430 p,
431 )
432 property = p
433 break
434
435 # consider the += and -=
436 if inc == "+":
437 if hasattr(cfg, property):
438 prop = getattr(cfg, property)
439 if isinstance(prop, dict):
440 for k in value:
441 prop[k] = value[k]
442 else:
443 prop += value
444 else:
445 setattr(cfg, property, value)
446 elif inc == "-":
447 if hasattr(cfg, property):
448 prop = getattr(cfg, property)
449 if isinstance(prop, dict):
450 for k in value:
451 if k in prop:
452 del prop[k]
453 else:
454 _log.warning(
455 "key '%s' not in %s.%s", k, cfg.name(), property
456 )
457 else:
458 for k in value:
459 if k in prop:
460 prop.remove(k)
461 else:
462 _log.warning(
463 "value '%s' not in %s.%s", k, cfg.name(), property
464 )
465 else:
466 setattr(cfg, property, value)
467
468

◆ _include()

GaudiKernel.ProcessJobOptions.JobOptsParser._include ( self,
file,
function )
protected

Definition at line 189 of file ProcessJobOptions.py.

189 def _include(self, file, function):
190 file = _find_file(file)
191 if _to_be_included(file):
192 _log.info("--> Including file '%s'", file)
193 function(file)
194 _log.info("<-- End of file '%s'", file)
195

◆ _parse_units()

GaudiKernel.ProcessJobOptions.JobOptsParser._parse_units ( self,
file )
protected

Definition at line 329 of file ProcessJobOptions.py.

329 def _parse_units(self, file):
330 for line in open(file):
331 if "//" in line:
332 line = line[: line.index("//")]
333 line = line.strip()
334 if not line:
335 continue
336 nunit, value = line.split("=")
337 factor, unit = nunit.split()
338 value = eval(value) / eval(factor)
339 self.units[unit] = value
340

◆ parse()

GaudiKernel.ProcessJobOptions.JobOptsParser.parse ( self,
file )

Definition at line 196 of file ProcessJobOptions.py.

196 def parse(self, file):
197 # states for the "translation unit"
198 statement = ""
199
200 ifdef_level = 0
201 ifdef_skipping = False
202 ifdef_skipping_level = 0
203
204 in_string = False
205
206 f = open(_find_file(file))
207 l = f.readline()
208 if l.startswith("#!"):
209 # Skip the first line if it starts with "#!".
210 # It allows to use options files as scripts.
211 l = f.readline()
212
213 while l:
214 l = (
215 l.rstrip() + "\n"
216 ) # normalize EOL chars (to avoid problems with DOS new-line on Unix)
217
218 # single line comment
219 m = self.comment.search(l)
220 if m:
221 # check if the '//' is part of a string
222 m2 = self.comment_in_string.search(l)
223 # the '//' is part of a string if we find the quotes around it
224 # and they are not part of the comment itself
225 if not (m2 and m2.start() < m.start()):
226 # if it is not the case, we can remove the comment from the
227 # statement
228 l = l[: m.start()] + l[m.end() :]
229 # process directives
230 m = self.directive.search(l)
231 if m:
232 directive_name = m.group(1)
233 directive_arg = m.group(2).strip()
234 if directive_name == "include":
235 included_file = directive_arg.strip("'\"")
236 importOptions(included_file)
237 elif directive_name == "units":
238 units_file = directive_arg.strip("'\"")
239 self._include(units_file, self._parse_units)
240 elif directive_name in ["ifdef", "ifndef"]:
241 ifdef_skipping_level = ifdef_level
242 ifdef_level += 1
243 if directive_arg in self.defines:
244 ifdef_skipping = directive_name == "ifndef"
245 else:
246 ifdef_skipping = directive_name == "ifdef"
247 elif directive_name == "else":
248 ifdef_skipping = not ifdef_skipping
249 elif directive_name == "endif":
250 ifdef_level -= 1
251 if ifdef_skipping and ifdef_skipping_level == ifdef_level:
252 ifdef_skipping = False
253 elif directive_name == "pragma":
254 if not directive_arg:
255 l = f.readline()
256 continue
257 pragma = directive_arg.split()
258 if pragma[0] == "print":
259 if len(pragma) > 1:
260 if pragma[1].upper() in ["ON", "TRUE", "1"]:
261 PrintOn()
262 else:
263 PrintOff()
264 else:
265 _log.warning("unknown directive '%s'", directive_name)
266 l = f.readline()
267 continue
268
269 if ifdef_skipping:
270 l = f.readline()
271 continue
272
273 # multi-line comment
274 m = self.comment_ml[0].search(l)
275 if m:
276 l, l1 = l[: m.start()], l[m.end() :]
277 m = self.comment_ml[1].search(l1)
278 while not m:
279 l1 = f.readline()
280 if not l1:
281 break # EOF
282 m = self.comment_ml[1].search(l1)
283 if not l1 and not m:
284 raise ParserError(
285 "End Of File reached before end of multi-line comment"
286 )
287 l += l1[m.end() :]
288
289 # if we are in a multiline string, we add to the statement
290 # everything until the next '"'
291 if in_string:
292 string_end = l.find('"')
293 if string_end >= 0:
294 statement += l[: string_end + 1]
295 l = l[string_end + 1 :]
296 in_string = False # the string ends here
297 else:
298 statement += l
299 l = ""
300 else: # check if we have a string
301 string_start = l.find('"')
302 if string_start >= 0:
303 string_end = l.find('"', string_start + 1)
304 if string_end >= 0:
305 # the string is opened and closed
306 statement += l[: string_end + 1]
307 l = l[string_end + 1 :]
308 else:
309 # the string is only opened
310 statement += l
311 in_string = True
312 l = f.readline()
313 continue
314
315 if self.statement_sep in l:
316 i = l.index(self.statement_sep)
317 statement += l[:i]
318 self._eval_statement(statement.strip().replace("\n", "\\n"))
319 statement = l[i + 1 :]
320 # it may happen (bug #37479) that the rest of the statement
321 # contains a comment.
322 if statement.lstrip().startswith("//"):
323 statement = ""
324 else:
325 statement += l
326
327 l = f.readline()
328
StatusCode parse(DataObjID &dest, std::string_view src)
Definition DataObjID.cpp:58

Member Data Documentation

◆ _parse_units

GaudiKernel.ProcessJobOptions.JobOptsParser._parse_units
protected

Definition at line 239 of file ProcessJobOptions.py.

◆ comment

GaudiKernel.ProcessJobOptions.JobOptsParser.comment = re.compile(r"(//.*)$")
static

Definition at line 175 of file ProcessJobOptions.py.

◆ comment_in_string

GaudiKernel.ProcessJobOptions.JobOptsParser.comment_in_string = re.compile(r'(["\']).*//.*\1')
static

Definition at line 178 of file ProcessJobOptions.py.

◆ comment_ml

tuple GaudiKernel.ProcessJobOptions.JobOptsParser.comment_ml = (re.compile(r"/\*"), re.compile(r"\*/"))
static

Definition at line 180 of file ProcessJobOptions.py.

◆ defines

dict GaudiKernel.ProcessJobOptions.JobOptsParser.defines = {}

Definition at line 187 of file ProcessJobOptions.py.

◆ directive

GaudiKernel.ProcessJobOptions.JobOptsParser.directive = re.compile(r"^\s*#\s*([\w!]+)\s*(.*)\s*$")
static

Definition at line 179 of file ProcessJobOptions.py.

◆ reference

GaudiKernel.ProcessJobOptions.JobOptsParser.reference = re.compile(r"^@([\w.]*)$")
static

Definition at line 182 of file ProcessJobOptions.py.

◆ statement_sep

GaudiKernel.ProcessJobOptions.JobOptsParser.statement_sep = ";"
static

Definition at line 181 of file ProcessJobOptions.py.

◆ units

dict GaudiKernel.ProcessJobOptions.JobOptsParser.units = {}

Definition at line 186 of file ProcessJobOptions.py.


The documentation for this class was generated from the following file: