C++ have a preprocessor. You can add Freemarker as a second preprocessor. For example:
<#function oh>
<#return 'Oh!'>
</#function>
int main(){
std::cout << "I am in line: __LINE__. ${oh()}" << std::endl;
return 0;
}
The code is UTF8 and linefeed is CRLF (windows).
The output will be:
I am in line: 2. Oh!
(But its line 5)
I use this code to transform the ftl into cpp:
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
// ...
@Override
public String load(final HttpServletRequest req) {
String code = iftl.load(req);
Configuration cfg = new Configuration();
cfg.setDefaultEncoding("UTF-8");
cfg.setLocale(Locale.US);
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
try {
Template template = new Template("x", new StringReader(code), cfg);
StringWriter sw = new StringWriter();
template.process(new LinkedHashMap<>(), sw);
sw.close();
return sw.toString();
} catch (IOException | TemplateException e) {
LOG.log(Level.SEVERE, "Could not parse freemaker-preprocessor.", e);
}
return code;
}
My problem: Line 2 is not correct! Line 5 is correct.
I need a function like this:
/** Takes a result-line-number and returns the source-line-number
*/
public int dest2src(int resultLineNumber, Template template) {
// what to write here?
}
// dest2src(2, template)) = 5
The issue comes from white-space stripping, which removes lines that contain only directives. You can disable it like this:
config.setWhitespaceStripping(false);
Then all line breaks will be preserved, so line numbers before and after processing will stay the same.