コード例 #1
0
        /// <summary>
        /// Write o relative to self to out
        /// </summary>
        /// <remarks>
        /// John Snyders fixes here for formatString.  Basically, any time
        /// you are about to write a value, check formatting.
        /// </remarks>
        protected internal virtual int Write(StringTemplate self, object o, IStringTemplateWriter output)
        {
            if (o == null)
            {
                if (nullValue == null)
                {
                    return 0;
                }
                // continue with null option if specified
                o = nullValue;
            }
            int n = 0;
            try
            {
                if (o is StringTemplate)
                {
                    StringTemplate stToWrite = (StringTemplate) o;
                    // failsafe: perhaps enclosing instance not set
                    // Or, it could be set to another context!  This occurs
                    // when you store a template instance as an attribute of more
                    // than one template (like both a header file and C file when
                    // generating C code).  It must execute within the context of
                    // the enclosing template.
                    stToWrite.EnclosingInstance = self;
                    // if self is found up the enclosing instance chain, then
                    // infinite recursion
                    if (StringTemplate.IsInLintMode && StringTemplate.IsRecursiveEnclosingInstance(stToWrite))
                    {
                        // throw exception since sometimes eval keeps going
                        // even after I ignore this write of o.
                        throw new SystemException("infinite recursion to " + stToWrite.GetTemplateDeclaratorString() + " referenced in " + stToWrite.EnclosingInstance.GetTemplateDeclaratorString() + "; stack trace:\n" + stToWrite.GetEnclosingInstanceStackTrace());
                    }
                    else
                    {
                        // if we have a wrap string, then inform writer it
                        // might need to wrap
                        if (wrapString != null)
                        {
                            n = output.WriteWrapSeparator(wrapString);
                        }
                    // check if formatting needs to be applied to the stToWrite
                    if ( formatString != null ) {
                        IAttributeRenderer renderer = self.GetAttributeRenderer(typeof(string));
                        if ( renderer != null )
                        {
                            // you pay a penalty for applying format option to a template
                            // because the template must be written to a temp StringWriter so it can
                            // be formatted before being written to the real output.
                            StringWriter buf = new StringWriter();
                            IStringTemplateWriter sw = self.Group.CreateInstanceOfTemplateWriter(buf);
                            stToWrite.Write(sw);
                            n = output.Write(renderer.ToString(buf.ToString(), formatString));
                            return n;
                        }
                    }
                        n = stToWrite.Write(output);
                    }
                    return n;
                }
                // normalize anything iteratable to iterator
                o = ConvertAnythingIteratableToIterator(o);
                if (o is IEnumerator)
                {
                    IEnumerator iter = (IEnumerator)o;
                    bool seenPrevValue = false;
                    while (iter.MoveNext())
                    {
                        object iterValue = iter.Current;
                        if (iterValue == null)
                        {
                            iterValue = nullValue;
                        }
                        if (iterValue != null)
                        {
                            if (seenPrevValue /*prevIterValue!=null*/ && (separatorString != null))
                            {
                                n += output.WriteSeparator(separatorString);
                            }
                            seenPrevValue = true;
                            int nw = Write(self, iterValue, output);
                            n += nw;
                        }
                    }
                }
                else
                {
                    IAttributeRenderer renderer = self.GetAttributeRenderer(o.GetType());
                    string v = null;
                    if (renderer != null)
                    {
                        if (formatString != null)
                        {
                            v = renderer.ToString(o, formatString);
                        }
                        else
                        {
                            v = renderer.ToString(o);
                        }
                    }
                    else
                    {
                        v = o.ToString();
                    }

                    if (wrapString != null)
                    {
                        n = output.Write(v, wrapString);
                    }
                    else
                    {
                        n = output.Write(v);
                    }
                    return n;
                }
            }
            catch (IOException io)
            {
                self.Error("problem writing object: " + o, io);
            }
            return n;
        }
コード例 #2
0
ファイル: ASTExpr.cs プロジェクト: bszafko/antlrcs
        protected virtual int WriteIterableValue(StringTemplate self, Iterator iter, IStringTemplateWriter @out)
        {
            int n = 0;
            bool seenAValue = false;
            while (iter.hasNext())
            {
                object iterValue = iter.next() ?? _nullValue;

                if (iterValue != null)
                {
                    // if no separator or separator but iterValue isn't a single IF condition template
                    if (_separatorString == null)
                    {
                        // if no separator, don't waste time writing to temp buffer
                        int nw = Write(self, iterValue, @out);
                        if (nw != Missing)
                            n += nw;

                        continue;
                    }

                    /* if value to emit is a template, only buffer its
                     * value if it's nullable (can eval to missing).
                     * Only a sequence of IF can eval to missing.
                     */
                    StringTemplate st = iterValue as StringTemplate;
                    if (st != null)
                    {
                        int nchunks = st.Chunks != null ? st.Chunks.Count : 0;
                        bool nullable = true;
                        for (int i = 0; i < nchunks; i++)
                        {
                            Expr a = st.Chunks[i];
                            if (!(a is ConditionalExpr))
                                nullable = false;
                        }

                        // if not all IF, not nullable, spit out w/o buffering
                        if (!nullable)
                        {
                            if (seenAValue && _separatorString != null)
                            {
                                n += @out.WriteSeparator(_separatorString);
                            }

                            int nw = Write(self, iterValue, @out);
                            n += nw;
                            seenAValue = true;
                            continue;
                        }
                    }
                    else if (!(iterValue is Iterator))
                    {
                        // if not possible to be missing, don't waste time
                        // writing to temp buffer; might need separator though
                        if (seenAValue && _separatorString != null)
                        {
                            n += @out.WriteSeparator(_separatorString);
                        }

                        int nw = Write(self, iterValue, @out);
                        seenAValue = true;
                        n += nw;
                        continue;
                    }

                    /* if separator exists, write iterated value to a
                     * tmp buffer in case we don't need a separator.
                     * Can't generate separator then test next expr value
                     * as we can't undo separator emit.
                     * Write to dummy buffer to if it is MISSING
                     * but eval/write value again to real out so
                     * we get proper autowrap etc...
                     * Ack: you pay a penalty now for a separator
                     * Later, i can optimze to check if one chunk and
                     * it's a conditional
                     */
                    StringWriter buf = new StringWriter();
                    IStringTemplateWriter sw = self.Group.GetStringTemplateWriter(buf);
                    int tmpsize = Write(self, iterValue, sw);

                    if (tmpsize != Missing)
                    {
                        if (seenAValue && _separatorString != null)
                        {
                            n += @out.WriteSeparator(_separatorString);
                        }

                        // do it to real output stream now
                        int nw = Write(self, iterValue, @out);
                        n += nw;
                        seenAValue = true;
                    }
                }
            }

            return n;
        }