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
CC: cheetahtemplate-discuss@...
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
|