| The Gaudi Framework v32r1 (f65d50dc)

Public Member Functions | Public Attributes | Static Public Attributes | Private Member Functions | List of all members
GaudiKernel.ProcessJobOptions.JobOptsParser Class Reference
Collaboration diagram for GaudiKernel.ProcessJobOptions.JobOptsParser:
[legend]

## Public Member Functions
def | __init__ (self)
def | parse (self, file)

## Public Attributes
| units
| 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'\*/'))
string | statement_sep = ";"
| reference = re.compile(r'^@([\w.]*)$')

## Private Member Functions
def | _include (self, file, function)
def | _parse_units (self, file)
def | _eval_statement (self, statement)

## Detailed Description

Definition at line 165 of file ProcessJobOptions.py.

## Constructor & Destructor Documentation

## ◆ __init__()

def GaudiKernel.ProcessJobOptions.JobOptsParser.__init__ | ( |  | self | ) |

Definition at line 175 of file ProcessJobOptions.py.

175 def __init__(self):
176 # parser level states
177 self.units = {}
178 self.defines = {}
179 if sys.platform != 'win32':
180 self.defines["WIN32"] = True
181

## Member Function Documentation

## ◆ _eval_statement()

def GaudiKernel.ProcessJobOptions.JobOptsParser._eval_statement | ( |  | self,
|  |  | statement
| ) |  |
| private

Definition at line 332 of file ProcessJobOptions.py.

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

## ◆ _include()

def GaudiKernel.ProcessJobOptions.JobOptsParser._include | ( |  | self,
|  |  | file,
|  |  | function
| ) |  |
| private

Definition at line 182 of file ProcessJobOptions.py.

182 def _include(self, file, function):
183 file = _find_file(file)
184 if _to_be_included(file):
185 _log.info("--> Including file '%s'", file)
186 function(file)
187 _log.info("<-- End of file '%s'", file)
188
GaudiKernel.ProcessJobOptions._to_be_included
def _to_be_included(f)
Definition: ProcessJobOptions.py:157
GaudiKernel.ProcessJobOptions._find_file
def _find_file(f)
Definition: ProcessJobOptions.py:140

## ◆ _parse_units()

def GaudiKernel.ProcessJobOptions.JobOptsParser._parse_units | ( |  | self,
|  |  | file
| ) |  |
| private

Definition at line 320 of file ProcessJobOptions.py.

320 def _parse_units(self, file):
321 for line in open(file):
322 if '//' in line:
323 line = line[:line.index('//')]
324 line = line.strip()
325 if not line:
326 continue
327 nunit, value = line.split('=')
328 factor, unit = nunit.split()
329 value = eval(value) / eval(factor)
330 self.units[unit] = value
331

## ◆ parse()

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

Definition at line 189 of file ProcessJobOptions.py.

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

## Member Data Documentation

## ◆ comment

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

Definition at line 166 of file ProcessJobOptions.py.

## ◆ comment_in_string

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

Definition at line 169 of file ProcessJobOptions.py.

## ◆ comment_ml

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

Definition at line 171 of file ProcessJobOptions.py.

## ◆ defines

GaudiKernel.ProcessJobOptions.JobOptsParser.defines

Definition at line 178 of file ProcessJobOptions.py.

## ◆ directive

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

Definition at line 170 of file ProcessJobOptions.py.

## ◆ reference

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

Definition at line 173 of file ProcessJobOptions.py.

## ◆ statement_sep

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

Definition at line 172 of file ProcessJobOptions.py.

## ◆ units

GaudiKernel.ProcessJobOptions.JobOptsParser.units

Definition at line 177 of file ProcessJobOptions.py.

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

- GaudiKernel/python/GaudiKernel/ProcessJobOptions.py