Since the code block was badly indented, it was not tested by `nitunit`.
Once the indentation was corrected, `nitunit` found that the test was failing.
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Pull-Request: #1342
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Jean Privat <jean@pryen.org>
module complete_simple_android is
app_namespace "org.nitlanguage.test_all"
- target_api_version 19
+ android_api_target 19
end
import test_bundle
# Test for the API level related annotations
module test_target_api is
- min_api_version(10)
- max_api_version(19)
+ android_api_min 10
+ android_api_max 19
end
import simple_android
--- /dev/null
+#!/usr/bin/env nit
+#
+# This file is part of NIT ( http://www.nitlanguage.org ).
+# This program is public domain
+
+# Task: Loops/Break
+#
+# SEE: http://rosettacode.org/wiki/Loops/Break
+module loops_break
+
+loop
+ var a = 20.rand
+ print a
+ if a == 10 then break
+ print 20.rand
+end
--- /dev/null
+#!/usr/bin/env nit
+#
+# This file is part of NIT ( http://www.nitlanguage.org ).
+# This program is public domain
+
+# Task: Loops/Continue
+#
+# SEE: http://rosettacode.org/wiki/Loops/Continue
+module loops_continue
+
+for i in [1..10] do
+ printn i
+ if i % 5 == 0 then
+ printn "\n"
+ continue
+ end
+ printn ", "
+end
--- /dev/null
+#!/usr/bin/env nit
+#
+# This file is part of NIT ( http://www.nitlanguage.org ).
+# This program is public domain
+
+# Task: Loops/Do-while
+#
+# SEE: http://rosettacode.org/wiki/Loops/Do-while
+module loops_do_while
+
+var val = 0
+loop
+ val += 1
+ print val
+ if val % 6 == 0 then break
+end
--- /dev/null
+#!/usr/bin/env nit
+#
+# This file is part of NIT ( http://www.nitlanguage.org ).
+# This program is public domain
+
+# Task: Loops/Downward for
+#
+# SEE: http://rosettacode.org/wiki/Loops/Downward_for
+module loops_downward_for
+
+for i in [0..10].reverse_iterator do
+ print i
+end
--- /dev/null
+#!/usr/bin/env nit
+#
+# This file is part of NIT ( http://www.nitlanguage.org ).
+# This program is public domain
+
+# Task: Loops/For
+#
+# SEE: http://rosettacode.org/wiki/Loops/For
+module loops_for
+
+for i in [1..5] do
+ for j in [1..i] do printn "*"
+ print ""
+end
--- /dev/null
+#!/usr/bin/env nit
+#
+# This file is part of NIT ( http://www.nitlanguage.org ).
+# This program is public domain
+
+# Task: Loops/Infinite
+#
+# SEE: http://rosettacode.org/wiki/Loops/Infinite
+module loops_infinite
+
+loop print "SPAM"
--- /dev/null
+#!/usr/bin/env nit
+#
+# This file is part of NIT ( http://www.nitlanguage.org ).
+# This program is public domain
+
+# Task: Loops/n + 1/2
+#
+# SEE: http://rosettacode.org/wiki/Loops/N_plus_one_half
+module loops_n_plus_one_half
+
+for i in [0..10] do
+ printn i
+ if i == 10 then break
+ printn ", "
+end
+print ""
+
+# Here the idiomatic version using `join`
+print([0..10].join(", "))
--- /dev/null
+#!/usr/bin/env nit
+#
+# This file is part of NIT ( http://www.nitlanguage.org ).
+# This program is public domain
+
+# Task: Loops/While
+#
+# SEE: http://rosettacode.org/wiki/Loops/While
+module loops_while
+
+var i = 2014
+while i > 0 do
+ print i
+ i /= 2
+end
--- /dev/null
+#!/usr/bin/env nit
+#
+# This file is part of NIT ( http://www.nitlanguage.org ).
+# This program is public domain
+
+# Task: Read entire file
+#
+# SEE: http://rosettacode.org/wiki/Read_entire_file
+module read_entire_file
+
+var filename = "/etc/issue"
+var content = filename.to_path.read_all
+print content
--- /dev/null
+#!/usr/bin/env nit
+#
+# This file is part of NIT ( http://www.nitlanguage.org ).
+# This program is public domain
+
+# Task: Tree traversal
+#
+# SEE: http://rosettacode.org/wiki/Tree_traversal
+module tree_traversal
+
+class Node
+ var value: Int
+ var left: nullable Node
+ var right: nullable Node
+
+ fun preorder
+ do
+ print value
+ var l = left
+ if l != null then l.preorder
+ var r = right
+ if r != null then r.preorder
+ end
+
+ fun inorder
+ do
+ var l = left
+ if l != null then l.inorder
+ print value
+ var r = right
+ if r != null then r.inorder
+ end
+
+ fun postorder
+ do
+ var l = left
+ if l != null then l.postorder
+ var r = right
+ if r != null then r.postorder
+ print value
+ end
+
+ fun levelorder
+ do
+ var q = new List[Node]
+ q.add self
+ while q.not_empty do
+ var n = q.shift
+ print n.value
+ var l = n.left
+ if l != null then q.push l
+ var r = n.right
+ if r != null then q.push r
+ end
+ end
+end
+
+var tree = new Node(1,
+ new Node(2,
+ new Node(4,
+ new Node(7)),
+ new Node(5)),
+ new Node(3,
+ new Node(6,
+ new Node(8),
+ new Node(9))))
+
+print "preorder:"
+tree.preorder
+print "inorder:"
+tree.inorder
+print "postorder:"
+tree.postorder
+print "levelorder:"
+tree.levelorder
private import log
private import data_store
-# Uses Android logs to print everything
-redef fun print(text) do log_write(priority_info, app.log_prefix.to_cstring, text.to_s.to_cstring)
-
redef class App
- redef fun log_error(msg) do log_write(priority_error, log_prefix.to_cstring, msg.to_cstring)
-
- redef fun log_warning(msg) do log_write(priority_warn, log_prefix.to_cstring, msg.to_cstring)
-
redef fun init_window
do
super
# Android compatibility module
#
-# Defines all Android related annoations including the `@android` annotations
-# used to tag `ldflags` annotations.
+# Defines all Android related annotations, including `ldflags@android`.
module aware is
new_annotation android
- new_annotation min_api_version
- new_annotation max_api_version
- new_annotation target_api_version
+ new_annotation android_api_min
+ new_annotation android_api_max
+ new_annotation android_api_target
new_annotation android_manifest
new_annotation android_manifest_application
new_annotation android_manifest_activity
# limitations under the License.
# Refines intent module to add API 11 services
-module intent_api11 is min_api_version(11)
+module intent_api11 is android_api_min 11
import intent
# limitations under the License.
# Refines intent module to add API 12 services
-module intent_api12 is min_api_version(12)
+module intent_api12 is android_api_min 12
import intent_api11
# limitations under the License.
# Refines intent module to add API 14 services
-module intent_api14 is min_api_version(14)
+module intent_api14 is android_api_min 14
import intent_api12
# limitations under the License.
# Refines intent module to add API 15 services
-module intent_api15 is min_api_version(15)
+module intent_api15 is android_api_min 15
import intent_api14
# limitations under the License.
# Refines intent module to add API 16 services
-module intent_api16 is min_api_version(16)
+module intent_api16 is android_api_min 16
import intent_api15
# limitations under the License.
# Refines intent module to add API 17 services
-module intent_api17 is min_api_version(17)
+module intent_api17 is android_api_min 17
import intent_api16
# limitations under the License.
# Refines intent module to add API 18 services
-module intent_api18 is min_api_version(18)
+module intent_api18 is android_api_min 18
import intent_api17
# limitations under the License.
# Refines intent module to add API 19 services
-module intent_api19 is min_api_version(19)
+module intent_api19 is android_api_min 19
import intent_api18
#include <android/log.h>
`}
+# Use Android logs to print
+redef fun print(object)
+do
+ log_write(priority_info, app.log_prefix.to_cstring, object.to_s.to_cstring)
+end
+
+# Use Android logs to print errors
+redef fun print_error(object)
+do
+ log_write(priority_error, app.log_prefix.to_cstring, object.to_s.to_cstring)
+end
+
+# Use Android logs to print warnings
+redef fun print_warning(object)
+do
+ log_write(priority_warn, app.log_prefix.to_cstring, object.to_s.to_cstring)
+end
+
+redef class App
+ # Prefix to all log messages
+ protected fun log_prefix: String do return "app.nit"
+end
+
# Default Android log priority
-fun priority_default: Int do return 1
+private fun priority_default: Int do return 1
# Verbose Android log priority
-fun priority_verbose: Int do return 2
+private fun priority_verbose: Int do return 2
# Debug Android log priority
-fun priority_debug: Int do return 3
+private fun priority_debug: Int do return 3
# Info Android log priority
-fun priority_info: Int do return 4
+private fun priority_info: Int do return 4
# Warn Android log priority
-fun priority_warn: Int do return 5
+private fun priority_warn: Int do return 5
# Error Android log priority
-fun priority_error: Int do return 6
+private fun priority_error: Int do return 6
# Fatal Android log priority
-fun priority_fatal: Int do return 7
+private fun priority_fatal: Int do return 7
# Silent Android log priority
-fun priority_silent: Int do return 8
+private fun priority_silent: Int do return 8
# Write `text` to Android log at priority `level` with tag `tag`
-fun log_write(level: Int, tag, text: NativeString) `{
+private fun log_write(level: Int, tag, text: NativeString) `{
__android_log_write(level, tag, text);
`}
# limitations under the License.
# Native Java classes for notifications
-module native_notification is min_api_version 11
+module native_notification is android_api_min 11
import android::assets_and_resources
# limitations under the License.
# Refines shared_preferences module to add API 11 services
-module shared_preferences_api11 is min_api_version(11)
+module shared_preferences_api11 is android_api_min 11
import shared_preferences
# limitations under the License.
# Native services from the `android.view` and `android.widget` namespaces
-module native_ui is min_api_version 14
+module native_ui is android_api_min 14
import nit_activity
# Main entry point of your application
fun run do end
- # Prefix to all log messages, used by `log_error`, `log_warning` and `log_info`.
- fun log_prefix: String do return "app.nit"
-
- # Helper function for logging errors
- fun log_error(msg: String) do sys.stderr.write "{log_prefix} error: {msg}\n"
-
- # Helper function for logging warnings
- fun log_warning(msg: String) do sys.stderr.write "{log_prefix} warn: {msg}\n"
-
# Main init method for graphical stuff
# Is called when display is ready so graphical assets
# can be loaded at this time.
fun window_closing do end
end
+# Print a warning
+fun print_warning(object: Object)
+do
+ sys.stderr.write object.to_s
+ sys.stderr.write "\n"
+end
+
+# The running `App`
fun app: App do return once new App
app.setup
app.run
#
# Basically just returns `self` encapsulated in a `FlatString`.
private class LeafSubstrings
- super IndexedIterator[Text]
+ super IndexedIterator[FlatText]
var leaf: Leaf
- var str: String is noinit
+ var str: FlatString is noinit
var avail = true
init do
var got_delimiter = false
loop
- var i = istream.read_char
- var c: Char
+ var c = istream.read_char
- if i < 0 then
+ if c == null then
if got_row then
row.add value.to_s
return row
return null
end
end
- c = i.ascii
if c == format.delimiter then
if got_delimiter and unescaped == 0 then
end
# Read all bytes until the delimiter.
loop
- i = istream.read_char
- assert not_eof: i >= 0 else
+ c = istream.read_char
+ assert not_eof: c != null else
sys.stderr.write "Unexpected end of file before the end of a delimited value.\n"
end
- c = i.ascii
if c == format.delimiter then break
value.add c
end
return res
end
- redef fun read_char: Int
+ redef fun read_char
do
assert not eof
return stream.read_char
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT. This software is
-# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE. You can modify it is you want, provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You are allowed to redistribute it and sell it, alone or is a part of
-# another product.
-
-# Additional services for streams.
-module io
-
-import push_back_reader
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT. This software is
-# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE. You can modify it is you want, provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You are allowed to redistribute it and sell it, alone or is a part of
-# another product.
-
-# Input stream that permits to push bytes back to the stream.
-module io::push_back_reader
-
-# Input stream that permits to push bytes back to the stream.
-class PushBackReader
- super Reader
-
- # Push the specified byte back to the stream.
- #
- # The specified byte is usually the last read byte that is not
- # “unread” already.
- fun unread_char(c: Char) is abstract
-
- # Push the specified string back to the stream.
- #
- # The specified string is usually the last read string that is not
- # “unread” already.
- fun unread(s: String) do
- for c in s.chars.reverse_iterator do unread_char(c)
- end
-end
-
-# Decorates an input stream to permit to push bytes back to the input stream.
-class PushBackDecorator
- super PushBackReader
-
- # The parent stream.
- var parent: Reader
-
- # The stack of the pushed-back bytes.
- #
- # Bytes are in the reverse order they will reappear in the stream.
- # `unread` pushes bytes after already pushed-back bytes.
- #
- # TODO: With optimized bulk array copy operations, a reversed stack (like in
- # OpenJDK) would be more efficient.
- private var buf: Sequence[Char] = new Array[Char]
-
- redef fun read_char: Int do
- if buf.length <= 0 then return parent.read_char
- return buf.pop.ascii
- end
-
- redef fun read(i: Int): String do
- if i <= 0 then return ""
- if buf.length <= 0 then return parent.read(i)
- var s = new FlatBuffer.with_capacity(i)
-
- loop
- s.chars.push(buf.pop)
- i -= 1
- if i <= 0 then
- return s.to_s
- else if buf.length <= 0 then
- s.append(parent.read(i))
- return s.to_s
- end
- end
- end
-
- redef fun read_all: String do
- if buf.length <= 0 then return parent.read_all
- var s = new FlatBuffer
-
- loop
- s.chars.push(buf.pop)
- if buf.length <= 0 then
- s.append(parent.read_all)
- return s.to_s
- end
- end
- end
-
- redef fun append_line_to(s: Buffer) do
- if buf.length > 0 then
- var c: Char
-
- loop
- c = buf.pop
- s.chars.push(c)
- if c == '\n' then return
- if buf.length <= 0 then break
- end
- end
- parent.append_line_to(s)
- end
-
- redef fun eof: Bool do return buf.length <= 0 and parent.eof
-
- redef fun close do
- buf.clear
- parent.close
- end
-
- redef fun unread_char(c: Char) do buf.push(c)
-
- redef fun unread(s: String) do
- for c in s.chars.reverse_iterator do buf.push(c)
- end
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT. This software is
-# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE. You can modify it is you want, provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You are allowed to redistribute it and sell it, alone or is a part of
-# another product.
-
-# Test suites for module `push_back_reader`
-module test_push_back_reader is test_suite
-
-import test_suite
-import io::push_back_reader
-
-class TestPushBackDecorator
- super TestSuite
-
- private fun sample: PushBackDecorator do
- return new PushBackDecorator(new StringReader("""
-abcd
-
-efg
-"""))
- end
-
- fun test_read_char do
- var subject = sample
-
- assert 'a' == subject.read_char.ascii
- end
-
- fun test_read_char_eof do
- var subject = new PushBackDecorator(new StringReader(""))
-
- assert -1 == subject.read_char
- end
-
- fun test_unread_read_char do
- var subject = sample
-
- subject.unread_char('z')
- assert 'z' == subject.read_char.ascii
- assert 'a' == subject.read_char.ascii
- end
-
- fun test_read_partial do
- var subject = sample
-
- assert "abcd" == subject.read(4)
- end
-
- fun test_read_too_much do
- var subject = sample
- var exp = """
-abcd
-
-efg
-"""
- assert exp == subject.read(100)
- end
-
- fun test_unread_read do
- var subject = sample
-
- subject.unread("a")
- assert "aab" == subject.read(3)
- end
-
- fun test_unread_read_mixed do
- var subject = sample
-
- subject.unread("a")
- assert "aab" == subject.read(3)
- end
-
- fun test_read_all do
- var subject = sample
- var exp = """
-abcd
-
-efg
-"""
- assert exp == subject.read_all
- end
-
- fun test_unread_read_all do
- var subject = sample
- var exp = """
-fooabcd
-
-efg
-"""
- subject.unread("foo")
- assert exp == subject.read_all
- end
-
- fun test_read_line do
- var subject = sample
-
- assert "abcd" == subject.read_line
- assert "" == subject.read_line
- end
-
- fun test_unread_read_line do
- var subject = sample
-
- subject.unread("a\nb")
- assert "a" == subject.read_line
- assert "babcd" == subject.read_line
- end
-
- fun test_eof do
- var subject = sample
-
- assert not subject.eof
- subject.read_all
- assert subject.eof
- end
-
- fun test_eof_empty do
- var subject = new PushBackDecorator(new StringReader(""))
-
- assert subject.eof
- end
-
- fun test_close do
- var subject = sample
-
- subject.close
- assert subject.eof
- end
-
- fun test_unread_close do
- var subject = sample
-
- subject.unread("foo")
- subject.close
- assert subject.eof
- end
-
- fun test_unread_char_order do
- var subject = sample
-
- subject.unread_char('z')
- subject.unread_char('y')
- assert "yzab" == subject.read(4)
- end
-
- fun test_unread_order do
- var subject = sample
-
- subject.unread("bar")
- subject.unread("foo")
- assert "foobarab" == subject.read(8)
- end
-end
# Open DB connection
db = new Sqlite3DB.open(db_path)
if not db.is_open then
- app.log_error "Data store unavaible, cannot load/save data. (at '{db_path}' with '{db.error or else "unknown"}')"
+ print_error "Data store unavaible, cannot load/save data. (at '{db_path}' with '{db.error or else "unknown"}')"
return null
end
do
var asset = try_loading_asset( id )
if asset == null then # error
- log_error( "asset <{id}> could not be loaded." )
+ print_error "asset <{id}> could not be loaded."
abort
else
return asset
if asset isa Image then
return asset
else
- log_error( "asset <{id}> is not an image." )
+ print_error "asset <{id}> is not an image."
abort
end
end
do
var path = "{assets_dir}/{id}"
if not path.file_exists then
- log_error( "asset <{id}> does not exists." )
+ print_error "asset <{id}> does not exists."
exit(1)
abort
else
locator.column_number += 1
end
- last_char = input.read_char
- if last_char < 0 then
+ var s = input.read_byte
+ if s == null then
+ last_char = -1
return
end
+ last_char = s
# XML 1.0 end-of-line handling
# Note: Regardless the XML version, any EOL defined by the
# recommandation MUST be reported as a single LINE FEED.
if was_cr and last_char == '\n'.ascii then
# EOL already reported. => Skip this byte.
- last_char = input.read_char
+ s = input.read_byte
+ if s == null then s = -1
+ last_char = s
end
was_cr = last_char == '\r'.ascii
if was_cr then
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Services for byte streams and arrays
+module bytes
+
+import kernel
+import collection::array
+intrude import string
+
+# A buffer containing Byte-manipulation facilities
+#
+# Uses Copy-On-Write when persisted
+#
+# TODO: Change the bound to Byte when available in stdlib and bootstrap
+class Bytes
+ super AbstractArray[Int]
+
+ # A NativeString being a char*, it can be used as underlying representation here.
+ private var items: NativeString
+
+ # Number of bytes in the array
+ redef var length: Int
+
+ # Capacity of the array
+ private var capacity: Int
+
+ # Has this buffer been persisted (to_s'd)?
+ #
+ # Used for Copy-On-Write
+ private var persisted = false
+
+ # var b = new Bytes.empty
+ # assert b.to_s == ""
+ init empty do
+ var ns = new NativeString(0)
+ init(ns, 0, 0)
+ end
+
+ init with_capacity(cap: Int) do
+ var ns = new NativeString(cap)
+ init(ns, 0, cap)
+ end
+
+ redef fun is_empty do return length != 0
+
+ # var b = new Bytes.empty
+ # b.add 101
+ # assert b[0] == 101
+ redef fun [](i: Int): Int do
+ assert i >= 0
+ assert i < length
+ return items[i].ascii
+ end
+
+ # var b = new Bytes.with_capacity(1)
+ # b[0] = 101
+ # assert b.to_s == "e"
+ redef fun []=(i: Int, v: Int) do
+ if persisted then regen
+ assert i >= 0
+ assert i <= length
+ if i == length then add(v)
+ items[i] = v.ascii
+ end
+
+ # var b = new Bytes.empty
+ # b.add 101
+ # assert b.to_s == "e"
+ redef fun add(c: Int) do
+ if persisted then regen
+ if length >= capacity then
+ enlarge(length)
+ end
+ items[length] = c.ascii
+ length += 1
+ end
+
+ # var b = new Bytes.empty
+ # b.append([104, 101, 108, 108, 111])
+ # assert b.to_s == "hello"
+ redef fun append(arr: Collection[Int]) do
+ if arr isa Bytes then
+ append_ns(arr.items, arr.length)
+ else
+ for i in arr do add i
+ end
+ end
+
+ redef fun clear do length = 0
+
+ # Regenerates the buffer, necessary when it was persisted
+ private fun regen do
+ var nns = new NativeString(capacity)
+ items.copy_to(nns, length, 0, 0)
+ persisted = false
+ end
+
+ # Appends the `ln` first bytes of `ns` to self
+ fun append_ns(ns: NativeString, ln: Int) do
+ if persisted then regen
+ var nlen = length + ln
+ if nlen > capacity then enlarge(nlen)
+ ns.copy_to(items, ln, 0, length)
+ length += ln
+ end
+
+ # Appends `ln` bytes from `ns` starting at index `from` to self
+ fun append_ns_from(ns: NativeString, ln, from: Int) do
+ if persisted then regen
+ var nlen = length + ln
+ if nlen > capacity then enlarge(nlen)
+ ns.copy_to(items, ln, from, length)
+ length += ln
+ end
+
+ redef fun enlarge(sz) do
+ if capacity >= sz then return
+ persisted = false
+ while capacity < sz do capacity = capacity * 2 + 2
+ var ns = new NativeString(capacity)
+ items.copy_to(ns, length, 0, 0)
+ items = ns
+ end
+
+ redef fun to_s do
+ persisted = true
+ return new FlatString.with_infos(items, length, 0, length -1)
+ end
+
+ redef fun iterator do return new BytesIterator.with_buffer(self)
+end
+
+private class BytesIterator
+ super IndexedIterator[Int]
+
+ var tgt: NativeString
+
+ redef var index: Int
+
+ var max: Int
+
+ init with_buffer(b: Bytes) do init(b.items, 0, b.length - 1)
+
+ redef fun is_ok do return index < max
+
+ redef fun next do index += 1
+
+ redef fun item do return tgt[index].ascii
+end
+
+redef class NativeString
+ fun to_bytes: Bytes do
+ var len = cstring_length
+ return new Bytes(self, len, len)
+ end
+end
redef fun iterator do return new IteratorRange[E](self)
+ # Gets an iterator starting at the end and going backwards
+ #
+ # var reviter = [1..4].reverse_iterator
+ # assert reviter.to_a == [4,3,2,1]
+ #
+ # reviter = [1..4[.reverse_iterator
+ # assert reviter.to_a == [3,2,1]
+ fun reverse_iterator: Iterator[E] do return new ReverseIteratorRange[E](self)
+
# assert [1..10].length == 10
# assert [1..10[.length == 9
# assert [1..1].length == 1
end
end
+# Iterator on ranges.
private class IteratorRange[E: Discrete]
- # Iterator on ranges.
super Iterator[E]
var range: Range[E]
redef var item is noinit
redef fun is_ok do return _item < _range.after
-
+
redef fun next do _item = _item.successor(1)
-
+
init
do
_item = _range.first
end
end
+# Reverse iterator on ranges.
+private class ReverseIteratorRange[E: Discrete]
+ super Iterator[E]
+ var range: Range[E]
+ redef var item is noinit
+
+ redef fun is_ok do return _item >= _range.first
+
+ redef fun next do _item = _item.predecessor(1)
+
+ init
+ do
+ _item = _range.last
+ end
+end
+
redef class Int
# Returns the range from 0 to `self-1`, is used to do:
#
redef fun read_char do return stream_in.read_char
+ redef fun read_byte do return stream_in.read_byte
+
redef fun eof do return stream_in.eof
redef fun pipeflags do return 2
sys.stdout.write("\n")
end
+# Print `object` on the error output (`stderr` or a log system)
+fun print_error(object: Object)
+do
+ sys.stderr.write object.to_s
+ sys.stderr.write "\n"
+end
+
# Read a character from the standard input (`stdin`).
fun getc: Char
do
- return sys.stdin.read_char.ascii
+ var c = sys.stdin.read_char
+ if c == null then return '\1'
+ return c
end
# Read a line from the standard input (`stdin`).
return new Concat(left, r + s)
end
end
+
+ redef fun copy_to_native(dest, n, src_offset, dest_offset) do
+ var remlen = n
+ var subs = new RopeSubstrings.from(self, src_offset)
+ var st = src_offset - subs.pos
+ var off = dest_offset
+ while n > 0 do
+ var it = subs.item
+ if n > it.length then
+ var cplen = it.length - st
+ it.items.copy_to(dest, cplen, st, off)
+ off += cplen
+ n -= cplen
+ else
+ it.items.copy_to(dest, n, st, off)
+ n = 0
+ end
+ subs.next
+ st = 0
+ end
+ end
end
# Mutable `Rope`, optimized for concatenation operations
# mutable native string (`ns`)
private var buf_size: Int is noinit
- redef fun substrings: Iterator[String] do return new RopeBufSubstringIterator(self)
+ redef fun substrings do return new RopeBufSubstringIterator(self)
# Builds an empty `RopeBuffer`
init do
end
private class RopeBufSubstringIterator
- super Iterator[String]
+ super Iterator[FlatText]
# Iterator on the substrings of the building string
- var iter: Iterator[String]
+ var iter: Iterator[FlatText]
# Makes a String out of the buffered part of the Ropebuffer
- var nsstr: String
+ var nsstr: FlatString
# Did we attain the buffered part ?
var nsstr_done = false
# Substrings of a Rope (i.e. Postfix iterator on leaves)
private class RopeSubstrings
- super IndexedIterator[String]
+ super IndexedIterator[FlatString]
# Visit Stack
var iter: RopeIterPiece is noinit
var max: Int is noinit
# Current leaf
- var str: String is noinit
+ var str: FlatString is noinit
init(root: RopeString) is old_style_init do
var r = new RopeIterPiece(root, true, false, null)
rnod = rnod.left
r = new RopeIterPiece(rnod, true, false, r)
else
- str = rnod
+ str = rnod.as(FlatString)
r.rdone = true
iter = r
break
r = new RopeIterPiece(rnod, true, false, r)
end
else
- str = rnod
+ str = rnod.as(FlatString)
r.rdone = true
iter = r
self.pos = pos - off
if not rnod isa Concat then
it.ldone = true
it.rdone = true
- str = rnod
+ str = rnod.as(FlatString)
iter = it.as(not null)
break
end
import numeric
import error
import re
+import bytes
# A `Stream` that can be read from
abstract class Reader
super Stream
- # Read a character. Return its ASCII value, -1 on EOF or timeout
- fun read_char: Int is abstract
+ # Reads a character. Returns `null` on EOF or timeout
+ fun read_char: nullable Char is abstract
+
+ # Reads a byte. Returns `null` on EOF or timeout
+ fun read_byte: nullable Int is abstract
# Read at most i bytes
fun read(i: Int): String
var s = new FlatBuffer.with_capacity(i)
while i > 0 and not eof do
var c = read_char
- if c >= 0 then
- s.add(c.ascii)
+ if c != null then
+ s.add(c)
i -= 1
end
end
var s = new FlatBuffer
while not eof do
var c = read_char
- if c >= 0 then s.add(c.ascii)
+ if c != null then s.add(c)
end
return s.to_s
end
if last_error != null then return
loop
var x = read_char
- if x == -1 then
+ if x == null then
if eof then return
else
- var c = x.ascii
- s.chars.push(c)
- if c == '\n' then return
+ s.chars.push(x)
+ if x == '\n' then return
end
end
end
do
var buf = new FlatBuffer
var c = read_nonwhitespace
- if c > 0 then
- buf.add(c.ascii)
+ if c != null then
+ buf.add(c)
while not eof do
c = read_char
- if c < 0 then break
- var a = c.ascii
- if a.is_whitespace then break
- buf.add(a)
+ if c == null then break
+ if c.is_whitespace then break
+ buf.add(c)
end
end
var res = buf.to_s
# Skip whitespace characters (if any) then return the following non-whitespace character.
#
# Returns the code point of the character.
- # Return -1 on end of file or error.
+ # Returns `null` on end of file or error.
#
# In fact, this method works like `read_char` except it skips whitespace.
#
# ~~~
# var w = new StringReader(" \nab\tc")
- # assert w.read_nonwhitespace == 'a'.ascii
- # assert w.read_nonwhitespace == 'b'.ascii
- # assert w.read_nonwhitespace == 'c'.ascii
- # assert w.read_nonwhitespace == -1
+ # assert w.read_nonwhitespace == 'a'
+ # assert w.read_nonwhitespace == 'b'
+ # assert w.read_nonwhitespace == 'c'
+ # assert w.read_nonwhitespace == null
# ~~~
#
# `Char::is_whitespace` determines what is a whitespace.
- fun read_nonwhitespace: Int
+ fun read_nonwhitespace: nullable Char
do
- var c = -1
+ var c: nullable Char = null
while not eof do
c = read_char
- if c < 0 or not c.ascii.is_whitespace then break
+ if c == null or not c.is_whitespace then break
end
return c
end
super Reader
redef fun read_char
do
- if last_error != null then return -1
+ if last_error != null then return null
if eof then
last_error = new IOError("Stream has reached eof")
- return -1
+ return null
end
- var c = _buffer.chars[_buffer_pos]
+ var c = _buffer[_buffer_pos]
_buffer_pos += 1
- return c.ascii
+ return c
+ end
+
+ redef fun read_byte
+ do
+ if last_error != null then return null
+ if eof then
+ last_error = new IOError("Stream has reached eof")
+ return null
+ end
+ var c = _buffer[_buffer_pos].ascii
+ _buffer_pos += 1
+ return c
+ end
+
+ # Peeks up to `n` bytes in the buffer, returns an empty string on EOF
+ #
+ # The operation does not consume the buffer
+ #
+ # ~~~nitish
+ # var x = new FileReader("File.txt")
+ # assert x.peek(5) == x.read(5)
+ # ~~~
+ fun peek(i: Int): String do
+ if eof then return ""
+ var b = new FlatBuffer.with_capacity(i)
+ while i > 0 and not eof do
+ b.add _buffer[_buffer_pos]
+ _buffer_pos += 1
+ i -= 1
+ end
+ var nbuflen = b.length + (_buffer.length - _buffer_pos)
+ var nbuf = new FlatBuffer.with_capacity(nbuflen)
+ nbuf.append(b)
+ while _buffer_pos < _buffer.length do
+ nbuf.add(_buffer[_buffer_pos])
+ _buffer_pos += 1
+ end
+ _buffer_pos = 0
+ _buffer = nbuf
+ return b.to_s
end
redef fun read(i)
loop
# First phase: look for a '\n'
var i = _buffer_pos
- while i < _buffer.length and _buffer.chars[i] != '\n' do i += 1
+ while i < _buffer.length and _buffer[i] != '\n' do i += 1
var eol
if i < _buffer.length then
- assert _buffer.chars[i] == '\n'
+ assert _buffer[i] == '\n'
i += 1
eol = true
else
# Copy from the buffer to the string
var j = _buffer_pos
while j < i do
- s.add(_buffer.chars[j])
+ s.add(_buffer[j])
j += 1
end
_buffer_pos = i
redef fun read_char do
if cursor < source.length then
- var c = source[cursor].ascii
+ var c = source[cursor]
cursor += 1
return c
else
- return -1
+ return null
+ end
+ end
+
+ redef fun read_byte do
+ if cursor < source.length then
+ var c = source[cursor]
+
+ cursor += 1
+ return c.ascii
+ else
+ return null
end
end
fun substring(from: Int, count: Int): SELFTYPE is abstract
# Iterates on the substrings of self if any
- fun substrings: Iterator[Text] is abstract
+ fun substrings: Iterator[FlatText] is abstract
# Is the current Text empty (== "")
#
return s.to_s
end
+ # Copies `n` bytes from `self` at `src_offset` into `dest` starting at `dest_offset`
+ #
+ # Basically a high-level synonym of NativeString::copy_to
+ #
+ # REQUIRE: `n` must be large enough to contain `len` bytes
+ #
+ # var ns = new NativeString(8)
+ # "Text is String".copy_to_native(ns, 8, 2, 0)
+ # assert ns.to_s_with_length(8) == "xt is St"
+ #
+ fun copy_to_native(dest: NativeString, n, src_offset, dest_offset: Int) do
+ var mypos = src_offset
+ var itspos = dest_offset
+ while n > 0 do
+ dest[itspos] = self.chars[mypos]
+ itspos += 1
+ mypos += 1
+ n -= 1
+ end
+ end
+
end
# All kinds of array-based text representations.
end
redef fun flatten do return self
+
+ redef fun copy_to_native(dest, n, src_offset, dest_offset) do
+ items.copy_to(dest, n, src_offset, dest_offset)
+ end
end
# Abstract class for the SequenceRead compatible
# assert "helloworld".insert_at(" ", 5) == "hello world"
fun insert_at(s: String, pos: Int): SELFTYPE is abstract
- redef fun substrings: Iterator[String] is abstract
+ redef fun substrings is abstract
# Returns a reversed version of self
#
private fun unpad_message do
var fin = false
while not fin do
- var fst_char = client.read_char
- var snd_char = client.read_char
+ var fst_byte = client.read_byte
+ var snd_byte = client.read_byte
+ if fst_byte == null or snd_byte == null then
+ last_error = new IOError("Error: bad frame")
+ client.close
+ return
+ end
# First byte in msg is formatted this way :
# |(fin - 1bit)|(RSV1 - 1bit)|(RSV2 - 1bit)|(RSV3 - 1bit)|(opcode - 4bits)
# fin = Flag indicating if current frame is the last one
# %x9 denotes a ping
# %xA denotes a pong
# %xB-F are reserved for further control frames
- var fin_flag = fst_char.bin_and(128)
+ var fin_flag = fst_byte.bin_and(128)
if fin_flag != 0 then fin = true
- var opcode = fst_char.bin_and(15)
+ var opcode = fst_byte.bin_and(15)
if opcode == 9 then
_buffer.add(138.ascii)
_buffer.add('\0')
# |(mask - 1bit)|(payload length - 7 bits)
# As specified, if the payload length is 126 or 127
# The next 16 or 64 bits contain an extended payload length
- var mask_flag = snd_char.bin_and(128)
- var len = snd_char.bin_and(127)
+ var mask_flag = snd_byte.bin_and(128)
+ var len = snd_byte.bin_and(127)
var payload_ext_len = 0
if len == 126 then
- payload_ext_len = client.read_char.lshift(8)
- payload_ext_len += client.read_char
+ var tmp = client.read(2)
+ if tmp.length != 2 then
+ last_error = new IOError("Error: received interrupted frame")
+ client.close
+ return
+ end
+ payload_ext_len = tmp[1].ascii + tmp[0].ascii.lshift(8)
else if len == 127 then
# 64 bits for length are not supported,
# only the last 32 will be interpreted as a Nit Integer
- for i in [0..4[ do client.read_char
- payload_ext_len = client.read_char.lshift(24)
- payload_ext_len += client.read_char.lshift(16)
- payload_ext_len += client.read_char.lshift(8)
- payload_ext_len += client.read_char
+ var tmp = client.read(8)
+ if tmp.length != 8 then
+ last_error = new IOError("Error: received interrupted frame")
+ client.close
+ return
+ end
+ for pos in [0 .. tmp.length[ do
+ var i = tmp[pos].ascii
+ payload_ext_len += i.lshift(8 * (7 - pos))
+ end
end
if mask_flag != 0 then
if payload_ext_len != 0 then
border-left: 2px solid #0d8921;
}
+
+.pull-right .dropdown-toggle {
+ padding: 0 5px;
+}
+
+/* Hide the "..." link */
+
+article .dropdown, article .dropdown {
+ visibility: hidden;
+}
+article:hover .dropdown, article:target .dropdown {
+ visibility: visible;
+}
+
/*
* Page parts
*/
margin-left: 30px;
}
-.source-link {
- display: none;
- float: right;
- margin-top: 10px;
-}
-
-.source-link a {
- color: #0d8921;
-}
-
-article:hover .source-link, article:target .source-link {
- display: block;
-}
-
/*
* Code Highlighting
*/
# Dot script of the graph.
var dot: Text
+
+ redef var is_empty = false
end
redef class MModulePage
redef fun build_inh_list(v, doc) do
var section = new ImportationListSection(mentity)
+ var group = new PanelGroup("List")
var imports = self.imports.to_a
v.name_sorter.sort(imports)
- section.add_child new HierarchyListArticle(mentity, "Imports", imports)
+ group.add_child new HierarchyListArticle(mentity, "Imports", imports)
var clients = self.clients.to_a
v.name_sorter.sort(clients)
- section.add_child new HierarchyListArticle(mentity, "Clients", clients)
+ group.add_child new HierarchyListArticle(mentity, "Clients", clients)
+ section.add_child group
section.parent = root.children.first
root.children.first.children.insert(section, 1)
end
redef class MClassPage
redef fun build_inh_list(v, doc) do
var section = new InheritanceListSection(mentity)
+ var group = new PanelGroup("List")
var parents = self.parents.to_a
v.name_sorter.sort(parents)
- section.add_child new HierarchyListArticle(mentity, "Parents", parents)
+ group.add_child new HierarchyListArticle(mentity, "Parents", parents)
var ancestors = self.ancestors.to_a
v.name_sorter.sort(ancestors)
- section.add_child new HierarchyListArticle(mentity, "Ancestors", ancestors)
+ group.add_child new HierarchyListArticle(mentity, "Ancestors", ancestors)
var children = self.children.to_a
v.name_sorter.sort(children)
- section.add_child new HierarchyListArticle(mentity, "Children", children)
+ group.add_child new HierarchyListArticle(mentity, "Children", children)
var descendants = self.descendants.to_a
v.name_sorter.sort(descendants)
- section.add_child new HierarchyListArticle(mentity, "Descendants", descendants)
+ group.add_child new HierarchyListArticle(mentity, "Descendants", descendants)
+ section.add_child group
section.parent = root.children.first
root.children.first.children.insert(section, 1)
end
# FIXME diff hack
class ImportationListSection
- super DocSection
+ super TabbedGroup
super MEntityComposite
end
# FIXME diff hack
class InheritanceListSection
- super DocSection
+ super TabbedGroup
super MEntityComposite
end
# TODO this should move to MEntity?
private fun build_mmodule_list(v: IntroRedefListPhase, doc: DocModel, mmodule: MModule) do
+ var section = new IntrosRedefsSection(mentity)
+ var group = new PanelGroup("List")
var intros = mmodule.intro_mclassdefs(v.ctx.min_visibility).to_a
doc.mainmodule.linearize_mclassdefs(intros)
- add_child new IntrosRedefsListArticle(mentity, "Introduces", intros)
+ group.add_child new IntrosRedefsListArticle(mentity, "Introduces", intros)
var redefs = mmodule.redef_mclassdefs(v.ctx.min_visibility).to_a
doc.mainmodule.linearize_mclassdefs(redefs)
- add_child new IntrosRedefsListArticle(mentity, "Redefines", redefs)
+ group.add_child new IntrosRedefsListArticle(mentity, "Redefines", redefs)
+ section.add_child group
+ add_child(section)
end
# TODO this should move to MEntity?
private fun build_mclassdef_list(v: IntroRedefListPhase, doc: DocModel, mclassdef: MClassDef) do
+ var section = new IntrosRedefsSection(mentity)
+ var group = new PanelGroup("List")
var intros = mclassdef.collect_intro_mpropdefs(v.ctx.min_visibility).to_a
# FIXME avoid diff changes
# v.ctx.mainmodule.linearize_mpropdefs(intros)
- add_child new IntrosRedefsListArticle(mentity, "Introduces", intros)
+ group.add_child new IntrosRedefsListArticle(mentity, "Introduces", intros)
var redefs = mclassdef.collect_redef_mpropdefs(v.ctx.min_visibility).to_a
# FIXME avoid diff changes
# v.ctx.mainmodule.linearize_mpropdefs(redefs)
- add_child new IntrosRedefsListArticle(mentity, "Redefines", redefs)
+ group.add_child new IntrosRedefsListArticle(mentity, "Redefines", redefs)
+ section.add_child group
+ add_child(section)
end
end
+# Section that contains the intros and redefs lists.
+class IntrosRedefsSection
+ super TabbedGroup
+ super MEntitySection
+end
+
# An article that displays a list of introduced / refined mentities.
#
# FIXME diff hack
end
end
+# A group of sections that can be displayed together in a tab.
+#
+# Display the first child and hide less relevant data in other panels.
+class TabbedGroup
+ super DocSection
+end
+
+# A group of sections that can be displayed together in a tab panel.
+class PanelGroup
+ super DocSection
+
+ # The title of this group.
+ var group_title: String
+end
+
# A DocComposite element about a MEntity.
class MEntityComposite
super DocComposite
# An article that displaus a list of definition belonging to a MEntity.
class DefinitionListArticle
+ super TabbedGroup
super MEntityArticle
end
end
end
+# A component that display tabbed data.
+class DocTabs
+ super BSComponent
+
+ # HTML id of this component.
+ var html_id: String
+
+ # Text displayed on the tabs dropdown button.
+ var drop_text: String
+
+ # Panels to display in this tab group.
+ var panels = new Array[DocTabPanel]
+
+ # Droplist containing links to panels.
+ #
+ # Can also be used to add external links.
+ var drop_list: DocTabsDrop is lazy do return new DocTabsDrop(html_id, drop_text)
+
+ # Adds a new `panel` to that tab.
+ #
+ # You should always use this instead of `panels.add` because it also set the
+ # `drop_list` entry.
+ fun add_panel(panel: DocTabPanel) do
+ drop_list.add_li panel.render_tab
+ panels.add panel
+ end
+
+ redef fun rendering do
+ if panels.is_empty then return
+ panels.first.is_active = true
+ add "<div role=\"tabpanel\">"
+ if drop_list.items.length > 1 then add drop_list
+ add " <div class=\"tab-content\">"
+ for panel in panels do
+ add panel
+ end
+ add " </div>"
+ add "</div>"
+ end
+end
+
+# A list of tab regrouped in a dropdown
+class DocTabsDrop
+ super UnorderedList
+
+ # HTML id used by the tabs group.
+ var html_id: String
+
+ # Title to display in the tab item.
+ var html_title: String
+
+ redef fun rendering do
+ add """<ul id="{{{html_id}}}-tabs" class="nav pull-right" role="tablist">"""
+ add """ <li role="presentation" class="dropdown pull-right">"""
+ add """ <a href="#" id="{{{html_id}}}-drop" class="dropdown-toggle"
+ data-toggle="dropdown" aria-controls="{{{html_id}}}-contents"
+ aria-expanded="false">"""
+ add html_title
+ add """ <span class="glyphicon glyphicon-menu-hamburger"></span>"""
+ add """ </a>"""
+ add """ <ul class="dropdown-menu" role="menu"
+ aria-labelledby="{{{html_id}}}-drop" id="{{{html_id}}}-contents">"""
+ for item in items do add item
+ add " </ul>"
+ add " </li>"
+ add "</ul>"
+ end
+end
+
+# A panel that goes in a DocTabs.
+class DocTabPanel
+ super BSComponent
+
+ # HTML id of this panel.
+ var html_id: String
+
+ # Title of this panel as displayed in the tab label.
+ var tab_title: String
+
+ # HTML content of this panel.
+ var html_content: Writable is writable
+
+ # Is this panel visible by default?
+ var is_active = false
+
+ redef fun rendering do
+ var active = ""
+ if is_active then active = "active in"
+ add "<div role=\"tabpanel\" class=\"tab-pane fade {active}\""
+ add " id=\"{html_id}\" aria-labelledby=\"{html_id}-tab\">"
+ add html_content
+ add "</div>"
+ end
+
+ private fun render_tab: DocTabItem do return new DocTabItem(tab_title, html_id)
+end
+
+# A ListItem that goes in a DocTabsDrop.
+private class DocTabItem
+ super ListItem
+
+ # Panel id to trigger when the link is clicked.
+ var target_id: String
+
+ redef fun rendering do
+ add "<li{render_css_classes}>"
+ add " <a role=\"tab\" data-toggle=\"tab\" aria-expanded=\"false\" tabindex=\"-1\""
+ add " id=\"{target_id}-tab\" href=\"#{target_id}\" aria-controls=\"{target_id}\">"
+ add text
+ add " </a>"
+ add "</li>"
+ end
+end
+
# A HTML tag attribute
# `<tag attr="value">`
#
end
lst.add_li new ListItem(content)
end
+
+ # ID used in HTML tab labels.
+ #
+ # We sanitize it for Boostrap JS panels that do not like ":" and "." in ids.
+ var html_tab_id: String is lazy do
+ var id = html_id.replace(":", "")
+ id = id.replace(".", "")
+ return "{id}-tab"
+ end
end
redef class DocSection
end
end
+redef class TabbedGroup
+ redef fun render_body do
+ var tabs = new DocTabs("{html_id}.tabs", "")
+ for child in children do
+ if child.is_hidden then continue
+ tabs.add_panel new DocTabPanel(child.html_tab_id, child.toc_title, child)
+ end
+ addn tabs
+ end
+end
+
+redef class PanelGroup
+ redef var html_id is lazy do return "group:{group_title.to_lower.to_snake_case}"
+ redef var html_title = null
+ redef var toc_title is lazy do return group_title
+ redef var is_toc_hidden = true
+end
+
redef class HomeArticle
redef var html_id = "article:home"
redef var html_title = "Overview"
# Link to source to display if any.
var html_source_link: nullable Writable is noinit, writable
- redef fun render_title do
+ redef fun render_body do
+ var tabs = new DocTabs("{html_id}.tabs", "")
+ var comment = mentity.html_comment
+ if comment != null then
+ tabs.add_panel new DocTabPanel("{html_tab_id}-comment", "Comment", comment)
+ end
+ for child in children do
+ if child.is_hidden then continue
+ tabs.add_panel new DocTabPanel(child.html_tab_id, child.toc_title, child)
+ end
var lnk = html_source_link
if lnk != null then
- add "<div class='source-link'>"
- add lnk
- addn "</div>"
+ tabs.drop_list.items.add new ListItem(lnk)
end
- super
- end
-
- redef fun render_body do
- var comment = mentity.html_comment
- if comment != null then addn comment
- super
+ addn tabs
end
end
# Link to source to display if any.
var html_source_link: nullable Writable is noinit, writable
- redef fun render_title do
- var lnk = html_source_link
- if lnk != null then
- add "<div class='source-link'>"
- add lnk
- addn "</div>"
- end
- super
- end
-
redef fun render_body do
+ var tabs = new DocTabs("{html_id}.tabs", "")
if not is_no_body then
var comment
if is_short_comment then
else
comment = mentity.html_comment
end
- if comment != null then addn comment
+ if comment != null then
+ tabs.add_panel new DocTabPanel("{html_tab_id}-comment", "Comment", comment)
+ end
end
- super
+ for child in children do
+ if child.is_hidden then continue
+ tabs.add_panel new DocTabPanel(child.html_tab_id, child.toc_title, child)
+ end
+ var lnk = html_source_link
+ if lnk != null then
+ tabs.drop_list.items.add new ListItem(lnk)
+ end
+ addn tabs
end
end
redef var html_id is lazy do return "article:{list_title}_{mentity.nitdoc_id}.hierarchy"
redef var html_title is lazy do return list_title
redef fun is_empty do return mentities.is_empty
- redef fun is_toc_hidden do return mentities.is_empty
+ redef var is_toc_hidden = true
redef fun render_body do
var lst = new UnorderedList
end
end
-redef class IntrosRedefsListArticle
+redef class IntrosRedefsSection
redef var html_id is lazy do return "article:{mentity.nitdoc_id}.intros_redefs"
+ redef var toc_title do return "Intros / Redefs"
+ redef var html_title = null
+ redef var html_subtitle = null
+ redef var is_toc_hidden = true
+end
+
+redef class IntrosRedefsListArticle
+ redef var html_id is lazy do return "article:{list_title}_{mentity.nitdoc_id}.intros_redefs"
redef var html_title is lazy do return list_title
redef fun is_hidden do return mentities.is_empty
redef var is_toc_hidden = true
init
do
- var annots = modelbuilder.collect_annotations_on_modules("min_api_version", mainmodule)
+ var annots = modelbuilder.collect_annotations_on_modules("android_api_min", mainmodule)
if not annots.is_empty then
var i = annots.pop.arg_as_int(modelbuilder)
if i == null then i = 0
end
end
- annots = modelbuilder.collect_annotations_on_modules("max_api_version", mainmodule)
+ annots = modelbuilder.collect_annotations_on_modules("android_api_max", mainmodule)
if not annots.is_empty then
var i = annots.pop.arg_as_int(modelbuilder)
if i == null then i = 0
end
end
- var annot = modelbuilder.lookup_annotation_on_modules("target_api_version", mainmodule)
+ var annot = modelbuilder.lookup_annotation_on_modules("android_api_target", mainmodule)
if annot != null then target_api = annot.arg_as_int(modelbuilder) or else 0
annots = modelbuilder.collect_annotations_on_modules("android_manifest", mainmodule)
var inw = false
while not stdin.eof do
var i = stdin.read_char
- if i >= 0 then
- var x = i.ascii
+ if i != null then
c = c + 1
- if x > ' ' then
+ if i > ' ' then
if not inw then
inw = true
w = w + 1
end
else
inw = false
- if x == '\n' then
+ if i == '\n' then
l = l + 1
end
end
converter
show_basedir
langannot
+loops_infinite
+read_entire_file
--- /dev/null
+16
+7
+15
+15
+18
+3
+6
+15
+5
+11
+9
+12
+7
+10
+19
+18
+12
+14
+2
+12
+0
+4
+2
+16
+3
+8
+2
+2
+19
+4
+10
--- /dev/null
+1, 2, 3, 4, 5
+6, 7, 8, 9, 10
--- /dev/null
+1
+2
+3
+4
+5
+6
--- /dev/null
+10
+9
+8
+7
+6
+5
+4
+3
+2
+1
+0
--- /dev/null
+*
+**
+***
+****
+*****
--- /dev/null
+0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
+0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
--- /dev/null
+2014
+1007
+503
+251
+125
+62
+31
+15
+7
+3
+1
--- /dev/null
+# Thi
+# Thi
+s file is pa
+s file is pa
+rt of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+var f = new FileReader.open("test_peek.nit")
+
+print f.peek(5)
+print f.read(5)
+
+print f.peek(12)
+print f.read(12)
+
+print f.read_all
+
+print f.peek(2)
+
+f.close
+
+
--- /dev/null
+preorder:
+1
+2
+4
+7
+5
+3
+6
+8
+9
+inorder:
+7
+4
+2
+5
+1
+8
+6
+9
+3
+postorder:
+7
+4
+5
+2
+8
+9
+6
+3
+1
+levelorder:
+1
+2
+3
+4
+5
+6
+7
+8
+9
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+var f = new FileReader.open("test_peek.nit")
+
+print f.peek(5)
+print f.read(5)
+
+print f.peek(12)
+print f.read(12)
+
+print f.read_all
+
+print f.peek(2)
+
+f.close