Loading ...
Sorry, an error occurred while loading the content.

Re: [Cheetahtemplate-discuss] Does Cheetah count line numbers its written?

Expand Messages
  • Nate Reid
    In code generation, I have a source file which has a combination of C++ and custom code/directives which is interpreted and converted into C++ code. When
    Message 1 of 6 , Mar 25, 2011
    • 0 Attachment
      In code generation, I have a source file which has a combination of C++ and custom 'code/directives' which is interpreted and converted into C++ code.  When debugging a generated file, #line directives are used to signal to the debugger where the source of the of lines originates.
      E.g.

      // mycustom.file (adding line numbers for clarity in the explanation.  They aren't in the original files)
      1: HEADER
      2: content name = test
      3: content type = string
      4: content default = "hello world"
      5: END
      6:
      7: CUSTOM
      8: #include <string>
      9: #include <vector>
      10: END

      // Output from cheetah template below.  Generated 'this_file.cpp'
      1: #line 8 "mycustom.file"
      2: #include <string>
      3: #include <vector>
      4: #line 5 "this_file.cpp"
      5: std::string contentTest = "hello world"
      6: etc...

      So the cheetah template is creating this_file.cpp, and needs to use the information from the mycustom.file to insert the corret #line directives into the file and then (more importantly) insert the #line directive of the file being generated at the correct line.
      So, in the above example, a cheetah template like this would be used

      // cheetah template
      #def lineDirective()
      \#line $LINE "this_file.cpp"
      #end def
      ##
      #for $custom in $customs
      ## first $custom is  -> #line 8 "mycustom.file"
      $custom
      #end for
      $lineDirective() ## should output: #line 5 "this_file.cpp"
      $type $var = $default
      ...


      So, the $LINE variable needs to be updated to be the actual line number of the current generated file that the cheetah template is producing, so it needs to handle loops, conditionals, etc.  Basically, a run-time count of the lines written, so it can't be known at compile time.

      I hope that helps clear up what I was trying to do.

      Thanks!
      -Nate
       


      Date: Wed, 23 Mar 2011 23:22:49 -0400
      Subject: Re: [Cheetahtemplate-discuss] Does Cheetah count line numbers its written?
      From: abbeyj@...
      To: gnatty7@...
      CC: cheetahtemplate-discuss@...

      Hi Nate,

      I guess I'm not quite clear on what you're trying to do.  If you don't want the line number from the original template then what line number do you want?  Could you provide some small theoretical example of your desired input and what you'd expect it to produce?

      --
      James Abbatiello


      On Fri, Mar 11, 2011 at 9:29 PM, Nate Reid <gnatty7@...> wrote:
      Hi James,
      In my work, I am using the command line cheetah compiler (e.g. cheetah script) so I had to hack a version of the command-line CheetahWrapper by monkey patching in a version that lets me specify a compilerClass to the Template.compile command.  My changes are specifying the compilerClass in the compille command below.

      #!/bin/env python
      import Cheetah.CheetahWrapper
      from Cheetah.CheetahWrapper import CheetahWrapper
      from cheetah_compilers import LineNumberCompiler
      import os
      import shutil
      moduleNameRE = Cheetah.CheetahWrapper.moduleNameRE

      class MyCheetahWrapper(CheetahWrapper):
          def __init__(self, *args, **kwargs):
              super(MyCheetahWrapper, self).__init__(*args, **kwargs)

          def _compileOrFillBundle(self, b):
              C, D, W = self.chatter, self.debug, self.warn
              TemplateClass = self._getTemplateClass()
              compilerSettings = self._getCompilerSettings()
              src = b.src
              dst = b.dst
              base = b.base
              basename = b.basename
              dstDir = os.path.dirname(dst)
              what = self.isCompile and "Compiling" or "Filling"
              C("%s %s -> %s^", what, src, dst) # No trailing newline.
              if os.path.exists(dst) and not self.opts.nobackup:
                  bak = b.bak
                  C(" (backup %s)", bak) # On same line as previous message.
              else:
                  bak = None
                  C("")
              if self.isCompile:
                  if not moduleNameRE.match(basename):
                      tup = basename, src
                      raise Error("""\
      %s: base name %s contains invalid characters.  It must
      be named according to the same rules as Python modules.""" % tup)
                  pysrc = TemplateClass.compile(file=src, returnAClass=False,
                                                moduleName=basename,
                                                className=basename,
                                                commandlineopts=self.opts,
                                                compilerSettings=compilerSettings,
                                                compilerClass=LineNumberCompiler)
                  output = pysrc
              else:
                  #output = str(TemplateClass(file=src, searchList=self.searchList))
                  tclass = TemplateClass.compile(file=src, compilerSettings=compilerSettings, compilerClass=LineNumberCompiler)
                  output = str(tclass(searchList=self.searchList))

              if bak:
                  shutil.copyfile(dst, bak)
              if dstDir and not os.path.exists(dstDir):
                  if self.isCompile:
                      mkdirsWithPyInitFiles(dstDir)
                  else:
                      os.makedirs(dstDir)
              if self.opts.stdout:
                  sys.stdout.write(output)
              else:
                  f = open(dst, 'w')
                  f.write(output)
                  f.close()

      if __name__ == '__main__':
          MyCheetahWrapper().main()


      Where LineNumberCompiler is the MyCompiler class you created in the original e-mail.
      The problem is that when the templates are compiled, it seems to hardcode the $LINE variable directly into the source code, so when I actually fill the templates,
      the $LINE variable no longer corresponds to the actual line in the source code.  It also doesn't allow me to use a #def to define a function that lets me spit out the #line $LINE "filename.cpp" directive.  E.g. it just replaces $LINE with the line number that it was first defined, rather than the dynamic one.

      Is there another way that Cheetah can actually count the lines it's written while filling the template?

      Thanks!
      -Nate


      From: gnatty7@...
      To: abbeyj@...
      Date: Wed, 9 Mar 2011 11:23:04 -0800
      Subject: Re: [Cheetahtemplate-discuss] Does Cheetah count line numbers its written?

      Thanks James, I'll give this a try and thanks for taking the time to write this up.
      Cheers
      -Nate


      Date: Wed, 9 Mar 2011 01:03:20 -0500
      Subject: Re: [Cheetahtemplate-discuss] Does Cheetah count line numbers its written?
      From: abbeyj@...
      To: gnatty7@...
      CC: cheetahtemplate-discuss@...

      This is a bit ugly but it may work for you:

      #!/usr/bin/env python
      import Cheetah.Compiler
      import Cheetah.Template

      class MyAutoMethodCompiler(Cheetah.Compiler.AutoMethodCompiler):
          def addPlaceholder(self, expr, filterArgs, rawPlaceholder,
                             cacheTokenParts, lineCol,
                             silentMode=False):
              if rawPlaceholder == u'$LINE':
                  self.addFilteredChunk(repr(unicode(lineCol[0])),
                                        filterArgs,
                                        rawPlaceholder,
                                        lineCol=lineCol)
              else:
                  super(MyAutoMethodCompiler, self).addPlaceholder(
                      expr, filterArgs, rawPlaceholder,
                      cacheTokenParts, lineCol,
                      silentMode=silentMode)


      class MyAutoClassCompiler(Cheetah.Compiler.AutoClassCompiler):
          methodCompilerClass = MyAutoMethodCompiler


      class MyCompiler(Cheetah.Compiler.Compiler):
          classCompilerClass = MyAutoClassCompiler


      tclass = Cheetah.Template.Template.compile('''\
      This is line $LINE
      Hello, $name!
      And this is line $LINE''', compilerClass=MyCompiler)
      print tclass(searchList=[{"name": "Nate"}])


      --
      James Abbatiello


      On Tue, Mar 8, 2011 at 1:45 PM, Nate Reid <gnatty7@...> wrote:
      I'm writing a source generator using Cheetah templates for C++ and would like to add #line directives into the generated source.  Without delving deep into the Cheetah source code, I was wondering if anyone on the list knew if Cheetah keeps track of how many lines are written so I can easily query the current line number in the template and use that in the template output itself for inserting #line directives into the generated source code.
      Thanks!
      -Nate

      ------------------------------------------------------------------------------
      What You Don't Know About Data Connectivity CAN Hurt You
      This paper provides an overview of data connectivity, details
      its effect on application quality, and explores various alternative
      solutions. http://p.sf.net/sfu/progress-d2d
      _______________________________________________
      Cheetahtemplate-discuss mailing list
      Cheetahtemplate-discuss@...
      https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss



      ------------------------------------------------------------------------------ Colocation vs. Managed Hosting A question and answer guide to determining the best fit for your organization - today and in the future. http://p.sf.net/sfu/internap-sfd2d
      _______________________________________________ Cheetahtemplate-discuss mailing list Cheetahtemplate-discuss@... https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss

      ------------------------------------------------------------------------------
      Colocation vs. Managed Hosting
      A question and answer guide to determining the best fit
      for your organization - today and in the future.
      http://p.sf.net/sfu/internap-sfd2d
      _______________________________________________
      Cheetahtemplate-discuss mailing list
      Cheetahtemplate-discuss@...
      https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss


    Your message has been successfully submitted and would be delivered to recipients shortly.