1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2010 Jean Privat <jean@pryen.org>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # Helps to generate complex strings.
18 # Can be used to simplify complex file generation where text addition is not only done at the end
19 package compiling_writer
21 # A writer is used to store a sequence of strings and sub-writers
23 # Add a new string at the end of the writer
24 fun add
(s
: String): Writer
28 var c2
= new WriterStrings(s
)
38 # Add each string of the array but separate them
39 fun add_all
(a
: Array[String], separator
: String): Writer
44 if first
then first
= false else add
(separator
)
50 var _first_sub_writer
: nullable WriterNode = null
51 var _last_sub_writer
: nullable WriterNode = null
53 # Last string added. Implies that _last_sub_writer isa WriterStrings
54 var _last_string
: nullable WriterStrings = null
56 # Insert an other Writer at the end of the writer
57 fun append
(c
: Writer): Writer
60 internal_append
(new WriterCoreNode(c
))
61 _last_string
= null # next add will create a new WriterStrings after c
65 # Insert a writer as a sub-one
66 private fun internal_append
(c
: WriterNode)
68 if _first_sub_writer
== null then _first_sub_writer
= c
69 var l
= _last_sub_writer
70 if l
!= null then l
._next_writer
= c
74 # Create a sub-writer that can be used as a new string insertion point
82 var _is_writing
: Bool = false
84 # Write all strings (including nested ones) to a stream
85 fun write_to_stream
(s
: OStream)
87 assert not _is_writing
89 var cur
= _first_sub_writer
91 cur
.internal_write_to_stream
(s
)
92 cur
= cur
._next_writer
97 # Return true if the string writer is frozen
98 readable var _is_frozen
: Bool = false
100 # Disable further writer modification: nor add or append are allowed
103 if is_frozen
then return
110 # Simple linked list of Writers contents
111 private abstract class WriterNode
112 # The next writer in the list
113 var _next_writer
: nullable WriterNode = null
115 # Write all strings (including nested ones) to a stream
116 fun internal_write_to_stream
(s
: OStream) is abstract
119 # A writer node that contains a full writer
120 private class WriterCoreNode
124 redef fun internal_write_to_stream
(s
) do _writer
.write_to_stream
(s
)
126 init(w
: Writer) do _writer
= w
129 # A simple writer node that contains only strings
130 private class WriterStrings
136 var _next
: nullable WriterStrings = null
143 redef fun internal_write_to_stream
(s
)
145 var cur
: nullable WriterStrings = self