[cig-commits] r6615 - cs/pythia/trunk/pyre/inventory/cfg

leif at geodynamics.org leif at geodynamics.org
Thu Apr 19 19:43:26 PDT 2007


Author: leif
Date: 2007-04-19 19:43:26 -0700 (Thu, 19 Apr 2007)
New Revision: 6615

Modified:
   cs/pythia/trunk/pyre/inventory/cfg/CodecConfig.py
   cs/pythia/trunk/pyre/inventory/cfg/Parser.py
Log:
Added the ${td} and ${basename} macros for .cfg files.

~~~ ${td} ~~~

The ${td} macro expands to the directory pathname of the .cfg file
("td" == "this directory").  Within a .cfg file, ${td} allows one to
reference other files relative to the .cfg file itself:


    # PyLith
    [pylith3d]
    bcInputFile = ${td}/splittest.bc


    # CitcomS
    [CitcomS.solver.mesher]
    # Read uneven mesh point coordinates from 'coor.dat'.
    coor = on
    coor_file = ${td}/coor.dat


This allows examples to work from anywhere, regardless of the current
working directory:

    citcoms Cookbook4/cookbook4.cfg

The output files will appear in the working directory as always, but
"${td}/coor.dat" expands to "Cookbook4/coor.dat", so that the input
file "coor.dat" is found alongside "cookbook4.cfg".

This works for all .cfg files; not merely those named on the command
line.  So, within ~/.pyre/pylith3d/pylith3d.cfg, ${td} expands to
"$HOME/.pyre/pylith3d".

~~~ ${basename} ~~~

The ${basename} macro expands to the basename of the .cfg file -- the
pathname stripped of the directory component and the '.cfg' extension
(e.g., "cookbook4").  With input files, it would commonly be used in
conjuction with ${td}, but with output files, it should probably be
used alone:

    # splittest.cfg
    [pylith3d]
    asciiOutputFile = ${basename}.ascii
    bcInputFile = ${td}/${basename}.bc

The advantage of this is that it allows an entire set of input/output
files to be toggled simply by copying or renaming the .cfg file:

    cp splittest.cfg mysplittest.cfg
    pylith3dapp.py mysplittest.cfg

Now PyLith would read "mysplittest.bc" and write "mysplittest.ascii",
simply by virtue of the new .cfg filename.

The ${basename} macro is perhaps a little goofy.  The goal is to
capture most of spirit of PyLith's ad-hoc ${fileRoot} macro, but in a
way that can implemented cleanly and simply within the Pyre framework.


Modified: cs/pythia/trunk/pyre/inventory/cfg/CodecConfig.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/cfg/CodecConfig.py	2007-04-20 00:50:43 UTC (rev 6614)
+++ cs/pythia/trunk/pyre/inventory/cfg/CodecConfig.py	2007-04-20 02:43:26 UTC (rev 6615)
@@ -14,6 +14,7 @@
 from pyre.inventory.odb.Registry import Registry
 from pyre.odb.fs.CodecODB import CodecODB
 from Parser import Parser
+from os.path import split, splitext
 
 
 class CodecConfig(CodecODB):
@@ -28,7 +29,11 @@
 
     def _decode(self, shelf):
         root = Registry("root")
-        parser = Parser(root)
+        td, fn = split(shelf.name)
+        if not td: td = "."
+        basename = splitext(fn)[0]
+        macros = { 'td': td, 'basename': basename }
+        parser = Parser(root, macros=macros)
         parser.read(shelf.name)
         shelf['inventory'] = root
         shelf._frozen = True

Modified: cs/pythia/trunk/pyre/inventory/cfg/Parser.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/cfg/Parser.py	2007-04-20 00:50:43 UTC (rev 6614)
+++ cs/pythia/trunk/pyre/inventory/cfg/Parser.py	2007-04-20 02:43:26 UTC (rev 6615)
@@ -13,6 +13,7 @@
 
 from ConfigParser import SafeConfigParser
 import pyre.parsing.locators as locators
+from pyre.util import expandMacros
 
 
 class Parser(SafeConfigParser):
@@ -45,9 +46,10 @@
 
     class Section(dict):
 
-        def __init__(self, sectname, node, fp):
+        def __init__(self, sectname, node, macros, fp):
             dict.__init__(self)
             self.node = node
+            self.macros = macros
             self.fp = fp
         
         def __setitem__(self, trait, value):
@@ -56,14 +58,16 @@
             key = path[-1]
             path = path[:-1]
             node = _getNode(self.node, path)
+            value = expandMacros(value, self.macros)
             node.setProperty(key, value, locator)
             dict.__setitem__(self, key, value)
 
     class SectionDict(dict):
 
-        def __init__(self, root):
+        def __init__(self, root, macros):
             dict.__init__(self)
             self.root = root
+            self.macros = macros
             self.fp = Parser.FileProxy()
         
         def __contains__(self, sectname):
@@ -71,16 +75,18 @@
             # dictionaries; instead, create our own.
             if not dict.__contains__(self, sectname):
                 node = _getNode(self.root, sectname.split('.'))
-                cursect = Parser.Section(sectname, node, self.fp)
+                cursect = Parser.Section(sectname, node, self.macros, self.fp)
                 self[sectname] = cursect
             return True
         
         def __setitem__(self, key, value):
             dict.__setitem__(self, key, value)
 
-    def __init__(self, root, defaults=None):
+    def __init__(self, root, defaults=None, macros=None):
         SafeConfigParser.__init__(self, defaults)
-        self._sections = Parser.SectionDict(root)
+        if macros is None:
+            macros = dict()
+        self._sections = Parser.SectionDict(root, macros)
 
     def _read(self, fp, fpname):
         self._sections.fp.fp = fp



More information about the cig-commits mailing list