You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by "Andrew Cook (Jira)" <ji...@apache.org> on 2020/12/18 00:26:00 UTC

[jira] [Created] (FREEMARKER-169) Various inconsistencies around c builtin

Andrew Cook created FREEMARKER-169:
--------------------------------------

             Summary: Various inconsistencies around c builtin
                 Key: FREEMARKER-169
                 URL: https://issues.apache.org/jira/browse/FREEMARKER-169
             Project: Apache Freemarker
          Issue Type: Bug
    Affects Versions: 2.3.29
         Environment: OS: Ubuntu 20.04.1 LTS (virtual machine)
Hardware: 32GB; 6 core processor (virtual machine)
Java Version: 1.8.0_172
            Reporter: Andrew Cook


While trying to build a custom template number formatter, I've encountered various inconsistencies around the C builtin, C NumberFormat, and related documentation.

I'll explain the problems below.
h2. c built-in Behavior

My use case requires XML compatible NaN/INF representations, and rather than write the string format representation logic myself, I wanted to leverage the logic used for the c built-in, since the [c-builtin documentation|https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_c] states that "[i]f the {{incompatible_improvements}} FreeMarker configuration setting is set to 2.3.24 or higher (also if it's set to 2.3.20 or higher and you are outside a string literal), this built-in will return {{"INF"}}, {{"-INF"}} and {{"NaN"}} for positive/negative infinity and IEEE floating point Not-a-Number, respectively."

In my project, we have {{incompatible_improvements}} version set to 2.3.29:
{code:java}
cfg = new Configuration(Configuration.VERSION_2_3_29);
{code}
So the expected behavior for the c-builtin is that INF, -INF, and NaN are represented as such, and it does, with val=Double.POSITIVE_INFINITY in the root context:
{code:java}
<MyDocument>
  <myField>${val?c}</myField>
</MyDocument>{code}
Yields:
{code:java}
<MyDocument>
  <myField>INF</myField>
</MyDocument>{code}
Great, just what I want.
h2. CNumberFormat Behavior Mismatch

To access this behavior for my custom template number format, I tried to use [Environment::getCNumberFormat|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/Environment.java#L1473] since it's documentation says that it "[r]eturns the NumberFormat used for the c built-in." Again, that should be great, since the c built-in has exactly the behavior I want.

Went I implemented this and made a test, however, this code:

 
{code:java}
environment.getCNumberFormat().format(Double.POSITIVE_INFINITY);
{code}
Returned "∞". Not if you look at [the code|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/Environment.java#L1477] because under the hood, this ended up returning [a DecimalFormat object|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/Environment.java#L104], contra was is suggested by the various documentation, including, for the c built-in: "[e]arlier it has returned what {{java.text.DecimalFormat}} did with US locale, none of which is understood by any (common) computer language." It seems like it actually still just returns DecimalFormat in some cases.

 
h2. string.computer Behavior Mismatch

Further inconsistency comes in with the string.computer builtin. The [string builtin for numbers documentation|https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_string_for_number] states that "[t]here are four predefined number formats: {{computer}}, {{currency}}, {{number}}, and {{percent}}. The exact meaning of these is locale (nationality) specific, and is controlled by the Java platform installation, not by FreeMarker, except for {{computer}}, which uses the same formatting as [the {{c}} built-in|https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_c]."

So the expected behavior of the following should be the same as my use of the c built-in above:

 
{code:java}
<MyDocument>
 <myField>${val?string.computer}</myField>
</MyDocument>
{code}
But it's not:

 

 
{code:java}
<MyDocument>
 <myField>∞</myField>
</MyDocument>
{code}
The cause for this is the same as the cause of the other inconsistency, since it seems that the computer number format for the string builtin for numbers [just uses Environment::getCNumberFormat|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/JavaTemplateNumberFormatFactory.java#L58], which as I've already mentioned has the same problem.
h2. Conclusion

Either documentation in multiple places is wrong and should be updated or the implementation for all this is wrong because the formatting logic isn't shared (as, indeed, it isn't, since [the c built-in works totally differently|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java#L94]).

Please either update the documentation or the implementation to resolve these inconsistencies. It was quite confusing for me and took a good bit of digging to figure out what was going on.

Let me know if you need any other information

 

 



--
This message was sent by Atlassian Jira
(v8.3.4#803005)