<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions tagged cl-format</title>
<link>https://ask.clojure.org/index.php/tag/cl-format</link>
<description></description>
<item>
<title>problem with Null exception in cl-format</title>
<link>https://ask.clojure.org/index.php/13162/problem-with-null-exception-in-cl-format</link>
<description>&lt;p&gt;If the format string ends in ~@, there is code in cl-format to detect this&lt;br&gt;
and issue a format-error.  However, that error detection is wrong, and a null exception&lt;br&gt;
happens rather than the format-error being reported.&lt;/p&gt;
&lt;p&gt;To reproduce this, simply evaluate the following.&lt;/p&gt;
&lt;p&gt;clojure.pprint&amp;gt; (cl-format false &quot;~@&quot;)&lt;br&gt;
Execution error (NullPointerException) at nrepl.middleware.interruptible-eval/evaluate$fn$fn (interruptible_eval.clj:87).&lt;/p&gt;
&lt;p&gt;I have a fix for this which I'd like to contribute.&lt;/p&gt;
&lt;p&gt;Here is the new version of the code &lt;code&gt;compile-directive&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn- compile-directive [s offset]
  (let [[raw-params [rest offset]] (extract-params s offset)
        [_ [rest offset flags]] (extract-flags rest offset)
        directive (first rest)
        ;; previous version was missing (if directive ...) here thus (format-error ...) never reached
        def (if directive (get directive-table (Character/toUpperCase ^Character directive)))
        params (if def (map-params def (map translate-param raw-params) flags offset))]
    (if (not directive)
      (format-error &quot;Format string ended in the middle of a directive&quot; offset))
    (if (not def)
      (format-error (str &quot;Directive \&quot;&quot; directive &quot;\&quot; is undefined&quot;) offset))
    [(struct compiled-directive ((:generator-fn def) params offset) def params offset)
     (let [remainder (subs rest 1) 
           offset (inc offset)
           trim? (and (= \newline (:directive def))
                      (not (:colon params)))
           trim-count (if trim? (prefix-count remainder [\space \tab]) 0)
           remainder (subs remainder trim-count)
           offset (+ offset trim-count)]
       [remainder offset])]))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The old version&lt;/p&gt;
</description>
<category>Printing</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13162/problem-with-null-exception-in-cl-format</guid>
<pubDate>Wed, 16 Aug 2023 14:36:19 +0000</pubDate>
</item>
<item>
<title>Potential issue in ~:[ directive in cl-format.</title>
<link>https://ask.clojure.org/index.php/12513/potential-issue-in-directive-in-cl-format</link>
<description>&lt;p&gt;I am using the cl-format function from the clojure.pprint library. I am using the ~:[ directive as follows:&lt;/p&gt;
&lt;p&gt;(cl-format nil &quot;~:[~;~a~]&quot; arg)&lt;/p&gt;
&lt;p&gt;When arg is nil, I get the expected empty string as a return value. However, when arg is non-nil, liike 1, I get an error: &quot;Not enough arguments for format definition.&quot; When I pass a second arg to the cl-format function:&lt;/p&gt;
&lt;p&gt;(cl-format nil &quot;~:[~;~a~]&quot; 1 2)&lt;/p&gt;
&lt;p&gt;it prints 2, so it's acting as if it is absorbing the first argument to check for its non-nil character and then passing the second to the internal format directive.&lt;/p&gt;
&lt;p&gt;From my reading of both the CL Hyperspec, and the gigamonkies format reference, the ~:[ should not absorb the argument but pass it on to the internal spec for printing. Is this an error in the implementation of cl-format or am I misinterpreting the spec?&lt;/p&gt;
&lt;p&gt;I've looked at the source and it sure looks like the navigator argument to execute-sub-format on line 862 of &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/clojure/blob/master/src/clj/clojure/pprint/cl_format.clj&quot;&gt;https://github.com/clojure/clojure/blob/master/src/clj/clojure/pprint/cl_format.clj&lt;/a&gt; should be arg-navigator instead.&lt;/p&gt;
</description>
<category>Printing</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12513/potential-issue-in-directive-in-cl-format</guid>
<pubDate>Thu, 29 Dec 2022 14:30:48 +0000</pubDate>
</item>
<item>
<title>Is this a bug in cl-format</title>
<link>https://ask.clojure.org/index.php/10897/is-this-a-bug-in-cl-format</link>
<description>&lt;p&gt;The following call to cl-format results in a Java level null pointer exception.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(cl-format false &quot;
~@&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course that code sample is pretty meaningless. The real example which lead to this minimum test case was the following.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(cl-format false &quot;~&amp;amp;~
                            item=~A~@
                            transitions=~A~@
                            lhs=~A~@
                            rhs=~A~@&quot;
                      1
                      2
                      3
                      4
                      )
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As near as I can tell the problem seems to be in dealing with the final &lt;code&gt;~@&lt;/code&gt; where the clojure code seems to (I'm guessing)  destructure the &lt;code&gt;nil&lt;/code&gt; return value of &lt;code&gt;extract-params&lt;/code&gt;&lt;br&gt;
in the function &lt;code&gt;compile-directive&lt;/code&gt; in cl_format.clj.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn- compile-directive [s offset]
  (let [[raw-params [rest offset]] (extract-params s offset)
        [_ [rest offset flags]] (extract-flags rest offset)
        directive (first rest)
        def (get directive-table (Character/toUpperCase ^Character directive))
        params (if def (map-params def (map translate-param raw-params) flags offset))]
    (if (not directive)
      (format-error &quot;Format string ended in the middle of a directive&quot; offset))
    (if (not def)
      (format-error (str &quot;Directive \&quot;&quot; directive &quot;\&quot; is undefined&quot;) offset))
    [(struct compiled-directive ((:generator-fn def) params offset) def params offset)
     (let [remainder (subs rest 1) 
           offset (inc offset)
           trim? (and (= \newline (:directive def))
                      (not (:colon params)))
           trim-count (if trim? (prefix-count remainder [\space \tab]) 0)
           remainder (subs remainder trim-count)
           offset (+ offset trim-count)]
       [remainder offset])]))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is the stack trace I see.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. Unhandled java.lang.NullPointerException
   (No message)

             cl_format.clj: 1717  clojure.pprint/compile-directive
             cl_format.clj: 1861  clojure.pprint/compile-format/fn
                  AFn.java:  154  clojure.lang.AFn/applyToHelper
                  AFn.java:  144  clojure.lang.AFn/applyTo
                  core.clj:  665  clojure.core/apply
             utilities.clj:   37  clojure.pprint/consume
             cl_format.clj: 1845  clojure.pprint/compile-format
             cl_format.clj: 1845  clojure.pprint/compile-format
             cl_format.clj:   62  clojure.pprint/cl-format
             cl_format.clj:   27  clojure.pprint/cl-format
               RestFn.java:  521  clojure.lang.RestFn/invoke
                      REPL: 1391  clojure-rte.rte-core/eval24978
                      REPL: 1391  clojure-rte.rte-core/eval24978
             Compiler.java: 7176  clojure.lang.Compiler/eval
             Compiler.java: 7131  clojure.lang.Compiler/eval
                  core.clj: 3214  clojure.core/eval
                  core.clj: 3210  clojure.core/eval
    interruptible_eval.clj:   87  nrepl.middleware.interruptible-eval/evaluate/fn/fn
                  AFn.java:  152  clojure.lang.AFn/applyToHelper
                  AFn.java:  144  clojure.lang.AFn/applyTo
                  core.clj:  665  clojure.core/apply
                  core.clj: 1973  clojure.core/with-bindings*
                  core.clj: 1973  clojure.core/with-bindings*
               RestFn.java:  425  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   87  nrepl.middleware.interruptible-eval/evaluate/fn
                  main.clj:  414  clojure.main/repl/read-eval-print/fn
                  main.clj:  414  clojure.main/repl/read-eval-print
                  main.clj:  435  clojure.main/repl/fn
                  main.clj:  435  clojure.main/repl
                  main.clj:  345  clojure.main/repl
               RestFn.java: 1523  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   84  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:   56  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:  152  nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
                  AFn.java:   22  clojure.lang.AFn/run
               session.clj:  202  nrepl.middleware.session/session-exec/main-loop/fn
               session.clj:  201  nrepl.middleware.session/session-exec/main-loop
                  AFn.java:   22  clojure.lang.AFn/run
               Thread.java:  834  java.lang.Thread/run
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>IO</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10897/is-this-a-bug-in-cl-format</guid>
<pubDate>Wed, 04 Aug 2021 13:44:47 +0000</pubDate>
</item>
</channel>
</rss>