[Helper] Symbols Parser for Dialog implementation

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 15/03/2012 at 14:16, xxxxxxxx wrote:

It is annoying to hardcode all symbols from the res/c4d_symbols.h file directly into the Python plugin file. This is a little helper I wrote to make things easier. You just give it a file or filename and it extracts all symbols it can find. This way you don't need to write pesky definitions (that might even change!) at the top of your source.

You are allowed to copy, use and modify the code but please don't expose it as your own written peace of code.

Here's an example of how to use the class:

  
import os  
import c4d  
  
dirname = os.path.dirname(__file__)  
respath = os.path.join(dirname, 'res', 'c4d_symbols.h')  
  
# Create a SymbolsContainer and parse the c4d_symbols.h directly  
res     = SymbolsContainer(filename = respath)  
  
class Dialog(c4d.gui.GeDialog) :  
  
  def CreateLayout(self) :  
      # NOTE: ID_DIALOG is a symbol from c4d_symbols.h  
      return self.LoadDialogResource(res.ID_DIALOG)  
  
  def Command(self, id, msg) :  
      # NOTE: Again, SOME_DIALOG_GADGET is a symbol from c4d_symbols.h  
      if id == res.SOME_DIALOG_GADGET:  
          doStuff()  
      return True

_<_h2_>_Source _<_h2_>_/h2>

import re  
  
class SymbolsContainer(object) :  
  """ This class implements parsing a ``c4d_symbols.h`` file and inserting the  
      data into a dictionary to access these value. Direct access is  
      implemented via ``__getattr__``. The parsing is implemented using a  
      single regular expression and is therefore not checking wether the  
      parsed file is actually a valid C header file. """  
  
  # The regular expression used to match the enumeration in a  
  # ``c4d_symbols.h`` file.  
  enum_match = re.compile('\s*(\w* )\s*(,\s*|=\s*(\d* )\s*,)\n')  
  
  def __init__(self, **ontoParse) :  
      self.values = dict()  
      if ontoParse:  
          self.parse(**ontoParse)  
  
  def __getattr__(self, name) :  
      return self.values[name]  
  
  def parse(self, file = None, filename = None, storage = None) :  
      """ Use this method to parse a file given by its ``filename`` or a  
          file-like object. The values are inserted into the calling  
          container, unless ``storage`` is given which will then be used to  
          store the parsed data.  
          """  
  
      if file and filename:  
          raise ValueError("Either `file` or `filename` must be set, both given.")  
      elif file:  
          pass  
      elif filename:  
          file = open(filename)  
      else:  
          raise ValueError("Either `file` or `filename` must be set, none given.")  
  
      last_value = 0  
      storage    = storage if hasattr(storage, "__setitem__") else self.values  
  
      for line in file:  
          match  = self.enum_match.match(line)  
          if not match: continue  
  
          groups = match.groups()  
          ename  = groups[0]  
          if groups[2]: last_value = int(groups[2])  
  
          storage[ename] = last_value  
          last_value    += 1  
  
      if filename:  
          file.close()  
  
      return True

-Niklas