Compare commits

...
51 Commits
Author SHA1 Message Date
José Valim 17e8dbbf16 Release v1.2.4 2016-04-01 12:08:10 +02:00
José Valim be7e6565f1 Merge pull request #4453 from sasa1977/purge-erlang-modules-on-recompilation
purge erlang modules on recompilation

Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-03-30 18:57:43 +02:00
José Valim c0770bace0 Include archive.check inside deps.check 2016-03-30 16:04:55 +02:00
José Valim 788a3cf242 Merge branch 'jv-nerves' into v1.2 2016-03-30 15:09:30 +02:00
José Valim 598c33d246 Fold decomposition recursions at compile time 2016-03-29 16:55:22 +02:00
José Valim 2bfd924ca8 Do not reorder starting classes 2016-03-29 13:37:34 +02:00
José Valim 28f553aa63 Handle compositios with non-zero combining class 2016-03-29 13:20:51 +02:00
José Valim ae2da553e8 More optimizations and improvements to normalization 2016-03-29 12:55:40 +02:00
José Valim e96fd72841 Make decomposition recursive and consider exclusion list 2016-03-29 11:49:49 +02:00
José Valim 9d9417ec1b Use combining_classes from UnicodeData 2016-03-29 11:11:29 +02:00
José Valim 3006ace8f5 Rely only on UnicodeData for composition/decomposition
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-03-29 00:56:06 +02:00
José Valim b558b90253 Merge pull request #4409 from whatyouhide/version-build-metadata-fix
Allow dots in the metadata info in Version.parse/1

Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-03-22 19:40:48 +01:00
Aleksei Magusev a97fcf932c Add a note about line filter for a file with multiple test cases
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-03-22 19:40:34 +01:00
Wojtek Mach f438efbfca Remove reference to old Inspect.Opts.new
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-03-22 19:40:27 +01:00
José Valim d0dd0bd0e4 Clean up unicode range parsing
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-03-22 19:35:03 +01:00
José Valim 77b5fe0e9f Update Unicode to 8.0.0 (equivalent pending)
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-03-22 19:34:55 +01:00
José Valim dbc6127820 Avoid regular expressions
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-03-22 19:34:48 +01:00
Abel Muiño 2eb77e12f0 New definition of whitespace & breakable whitespace
All whitespace can be removed by `strip` but only breakable whitespace
can be used as a delimiter by `split`, with updated docs for String.split/1

Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-03-22 19:34:38 +01:00
José Valim ffb626602c Add tests for archive check 2016-03-19 19:02:41 +01:00
José Valim f571fb74c4 Ensure mix deps.compile --include-children recurs on root dep 2016-03-19 17:42:12 +01:00
José Valim 7c07476db7 Add :archives option to Mix.Project 2016-03-19 15:26:40 +01:00
José Valim e3be6dd0e9 Add deps.precompile hook and --include-children option 2016-03-19 14:24:17 +01:00
José Valim c076fdb030 Ensure Application.spec/2 returns nil for unknown applications
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-03-19 14:03:50 +01:00
Andrea Leopardi 173c57fed2 Fix a possible binary leak in Integer.parse/1
Integer.parse/1 followed this pattern:

    defp do_parse(<<char, rest :: binary>>, ...) do
      ...
      # instead of re-using the original binary, we do this
      {..., <<char, rest :: binary>>}
    end

This causes a new binary to be created instead of `rest` just being a
sub-binary.

Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-03-02 19:52:48 +01:00
José Valim 737ac62926 Release v1.2.3 2016-02-21 22:28:30 +01:00
José Valim 9dcc0e140b Support canonical URLs
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-02-21 21:42:01 +01:00
José Valim e4e5481ca1 Update CHANGELOG 2016-02-21 17:57:10 +01:00
José Valim c3df6806b3 Simplify padding rules
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-02-21 17:56:14 +01:00
Paulo Almeida 6dc523074d Add option to omit / ignore padding
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-02-21 17:56:08 +01:00
Daniel Perez 5746cbf1e3 Add doc about ignore: :whitespace to Base.decode64.
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-02-21 17:56:05 +01:00
Artur Cygan 51966e92a7 Update base.ex
Clean up doc

Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-02-21 17:56:01 +01:00
Daniel Perez 498057c51b Add option to ignore whitespace to base64 decoding. Close #4186.
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-02-21 17:55:02 +01:00
José Valim b3c26a8633 Improve helpers docs 2016-02-17 19:18:10 +01:00
José Valim 5e218e77bf Update CHANGELOG 2016-02-17 00:39:19 +01:00
José Valim 56fbf2a399 Add Mix.Project.deps_paths
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-02-17 00:34:59 +01:00
José Valim c3582f9617 Reject non fullfilled optional dependencies later on
Imagine this dependency tree:

    * parent
      * child
        * ecto
        * postgrex
      * ja_serializer
        * ecto

where postgrex is an optional dependency of Ecto.

Because optional dependencies were rejected later on,
ecto would have its postgrex dependency stripped and
later failed to top-sort. This commit changes it to
so optional dependencies are rejected only later on.

Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-02-17 00:34:52 +01:00
José Valim bd83a45215 Fix typespecs table
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-02-16 19:44:05 +01:00
José Valim 52dc944cfb Do not allow negative line numbers without generated annotation 2016-02-15 11:47:46 +01:00
José Valim 3d27c749e1 Remove outdated debug_info test 2016-02-01 09:45:23 +01:00
José Valim 75d679cdc8 Merge pull request #4247 from stephenmoloney/rstrip-bug
String.replace_trailing bug fix.
2016-02-01 09:22:05 +01:00
José Valim 2c9f28ecc3 Remove debug_info from unicode 2016-02-01 09:21:38 +01:00
José Valim 9decf4c78a Release v1.2.2 2016-01-31 10:17:08 +01:00
José Valim e2463a5589 Limit the list of attributes we consider reserved 2016-01-31 09:30:51 +01:00
José Valim a825f5a0c8 Force recompilation if dependency was recently fetched 2016-01-29 13:20:47 +01:00
José Valim 3c0d26cb74 Raise if trying to override reserved tag, closes #4236 2016-01-29 00:32:00 +01:00
José Valim f7a31ac804 Update CHANGELOG 2016-01-27 13:05:25 +01:00
José Valim 31aebcdc59 Automatically merge manager according to internal priority, closes #4230 2016-01-27 12:56:16 +01:00
José Valim afbac81918 Do not require all compilers available on manifest
Closes #4228

Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-01-27 10:11:38 +01:00
José Valim 0b78f86f08 Do not rely on compiled functions in Mix for autoload
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-01-25 10:00:55 +01:00
José Valim 7180b98f47 Support disabling autoload after compilation
Useful for delaying loading of modules that may depend
on NIFs until necessary.

Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-01-25 00:13:37 +01:00
José Valim 021cca436d Do not include debug_info in metadata String modules
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
2016-01-25 00:13:28 +01:00
52 changed files with 3749 additions and 4405 deletions
+45
View File
@@ -85,6 +85,51 @@ ask Mix to use Rebar 3 to compile it by passing the `manager: :rebar3` option.
Once configured, Mix will prompt you to install Rebar 3 if it is not yet
available.
## v1.2.4 (2016-04-01)
### 1. Enhancements
* [Mix] Add `:archives` configuration to `def project` that allows projects to list archive dependencies. `--no-archives-check` (as well as `--no-deps-check`) will disable the archive check. The `:archives` option is not checked for dependencies.
* [Mix] Add `deps.precompile` task as hook
* [Mix] Support `--include-children` in `mix deps.compile` option
* [String] Update version of the Unicode database to 8.0.0
### 2. Bug fixes
* [Application] Ensure `spec/2` returns nil for unknown applications
* [Integer] Fix a possible binary leak in `parse/1`
* [Mix] Purge Erlang modules on recompilation
* [String] Ensure `split/1` does not break on non-breakable whitespace
* [String] Ensure NFC and NFD normalization pass all of Unicode 8.0.0 tests
* [Version] Allow dots in build info for versions in `Version.parse/1`
## v1.2.3 (2016-02-21)
### 1. Enhancements
* [Base] Add `:ignore` and `:padding` option to encoding/decoding functions
* [Mix] Add `Mix.Projects.deps_paths` that returns the dependencies path as a map
### 2. Bug fixes
* [ExUnit] Do not provide negative line numbers without generated annotation (for compatibility with Erlang 19)
* [Mix] Reject non fullfilled optional dependencies later on in the convergence resolution for proper dependency sorting
* [String] Fix incomplete data trimming on both `String.replace_trailing` and `String.rstrip`
* [String] Attach debug_info back into Unicode modules for Dialyzer support
## v1.2.2 (2016-01-31)
### 1. Enhancements
* [Kernel] Support `@compile {:autoload, false}` to disable automatic loading after compilation
### 2. Bug fixes
* [ExUnit] Raise if trying to override reserved tag in `setup` blocks
* [Mix] Ensure retrieve compile manifests do fail if some compilers are not yet available
* [Mix] Automatically merge managers according to the mix > rebar3 > rebar > make order
* [Mix] Force recompilation if dependency was recently fetched
## v1.2.1 (2016-01-14)
### 1. Enhancements
+2 -1
View File
@@ -1,6 +1,7 @@
REBAR ?= "$(CURDIR)/rebar"
PREFIX ?= /usr/local
DOCS := v1.2
CANONICAL := stable
ELIXIRC := bin/elixirc --verbose --ignore-module-conflict
ERLC := erlc -I lib/elixir/include
ERL := erl -I lib/elixir/include -noshell -pa lib/elixir/ebin
@@ -128,7 +129,7 @@ clean_exbeam:
LOGO_PATH = $(shell test -f ../docs/logo.png && echo "--logo ../docs/logo.png")
SOURCE_REF = $(shell head="$$(git rev-parse HEAD)" tag="$$(git tag --points-at $$head | tail -1)" ; echo "$${tag:-$$head}\c")
COMPILE_DOCS = bin/elixir ../ex_doc/bin/ex_doc "$(1)" "$(VERSION)" "lib/$(2)/ebin" -m "$(3)" -u "https://github.com/elixir-lang/elixir" --source-ref "$(call SOURCE_REF)" $(call LOGO_PATH) -o doc/$(2) -p http://elixir-lang.org/docs.html $(4)
COMPILE_DOCS = bin/elixir ../ex_doc/bin/ex_doc "$(1)" "$(VERSION)" "lib/$(2)/ebin" -m "$(3)" -u "https://github.com/elixir-lang/elixir" --source-ref "v$(VERSION)" $(call LOGO_PATH) -o doc/$(2) -a http://elixir-lang.org/docs/$(CANONICAL)/$(2)/ -p http://elixir-lang.org/docs.html $(4)
docs: compile ../ex_doc/bin/ex_doc docs_elixir docs_eex docs_mix docs_iex docs_ex_unit docs_logger
+1 -1
View File
@@ -1 +1 @@
1.2.1
1.2.4
+7 -5
View File
@@ -133,14 +133,16 @@ defmodule Application do
@doc """
Returns the value for `key` in `app`'s specification.
See `spec/1` for the supporte keys. If the given
See `spec/1` for the supported keys. If the given
specification parameter does not exist, this function
will raise.
will raise. Returns `nil` if the application is not loaded.
"""
@spec spec(app, key) :: value
@spec spec(app, key) :: value | nil
def spec(app, key) when key in @application_keys do
{:ok, value} = :application.get_key(app, key)
value
case :application.get_key(app, key) do
{:ok, value} -> value
:undefined -> nil
end
end
@doc """
+244 -127
View File
@@ -138,6 +138,15 @@ defmodule Base do
defp from_mixed(char),
do: char
defp maybe_pad(subject, false, _, _),
do: subject
defp maybe_pad(subject, _, group_size, pad) do
case rem(byte_size(subject), group_size) do
0 -> subject
x -> subject <> String.duplicate(pad, group_size - x)
end
end
@doc """
Encodes a binary string into a base 16 encoded string.
@@ -225,29 +234,56 @@ defmodule Base do
@doc """
Encodes a binary string into a base 64 encoded string.
Accepts `padding: false` option which will omit padding from
the output string.
## Examples
iex> Base.encode64("foobar")
"Zm9vYmFy"
iex> Base.encode64("foob")
"Zm9vYg=="
iex> Base.encode64("foob", padding: false)
"Zm9vYg"
"""
@spec encode64(binary) :: binary
def encode64(data) when is_binary(data) do
do_encode64(data)
@spec encode64(binary, Keyword.t) :: binary
def encode64(data, opts \\ []) when is_binary(data) do
pad_flag = Keyword.get(opts, :padding, true)
do_encode64(data, pad_flag)
end
@doc """
Decodes a base 64 encoded string into a binary string.
Accepts `ignore: :whitespace` option which will ignore all the
whitespace characters in the input string.
Accepts `padding: false` option which will ignore padding from
the input string.
## Examples
iex> Base.decode64("Zm9vYmFy")
{:ok, "foobar"}
iex> Base.decode64("Zm9vYmFy\\n", ignore: :whitespace)
{:ok, "foobar"}
iex> Base.decode64("Zm9vYg==")
{:ok, "foob"}
iex> Base.decode64("Zm9vYg", padding: false)
{:ok, "foob"}
"""
@spec decode64(binary) :: {:ok, binary} | :error
def decode64(string) when is_binary(string) do
{:ok, decode64!(string)}
@spec decode64(binary, Keyword.t) :: {:ok, binary} | :error
def decode64(string, opts \\ []) when is_binary(string) do
{:ok, decode64!(string, opts)}
rescue
ArgumentError -> :error
end
@@ -255,7 +291,11 @@ defmodule Base do
@doc """
Decodes a base 64 encoded string into a binary string.
The following alphabet is used both for encoding and decoding:
Accepts `ignore: :whitespace` option which will ignore all the
whitespace characters in the input string.
Accepts `padding: false` option which will ignore padding from
the input string.
An `ArgumentError` exception is raised if the padding is incorrect or
a non-alphabet character is present in the string.
@@ -265,44 +305,72 @@ defmodule Base do
iex> Base.decode64!("Zm9vYmFy")
"foobar"
iex> Base.decode64!("Zm9vYmFy\\n", ignore: :whitespace)
"foobar"
iex> Base.decode64!("Zm9vYg==")
"foob"
iex> Base.decode64!("Zm9vYg", padding: false)
"foob"
"""
@spec decode64!(binary) :: binary
def decode64!(string) when is_binary(string) and rem(byte_size(string), 4) == 0 do
do_decode64(string)
end
def decode64!(string) when is_binary(string) do
raise ArgumentError, "incorrect padding"
@spec decode64!(binary, Keyword.t) :: binary
def decode64!(string, opts \\ []) when is_binary(string) do
pad_flag = Keyword.get(opts, :padding, true)
string |> filter_ignored(opts[:ignore]) |> do_decode64(pad_flag)
end
@doc """
Encodes a binary string into a base 64 encoded string with URL and filename
safe alphabet.
Accepts `padding: false` option which will omit padding from
the output string.
## Examples
iex> Base.url_encode64(<<255, 127, 254, 252>>)
"_3_-_A=="
iex> Base.url_encode64(<<255, 127, 254, 252>>, padding: false)
"_3_-_A"
"""
@spec url_encode64(binary) :: binary
def url_encode64(data) when is_binary(data) do
do_encode64url(data)
@spec url_encode64(binary, Keyword.t) :: binary
def url_encode64(data, opts \\ []) when is_binary(data) do
pad_flag = Keyword.get(opts, :padding, true)
do_encode64url(data, pad_flag)
end
@doc """
Decodes a base 64 encoded string with URL and filename safe alphabet
into a binary string.
Accepts `ignore: :whitespace` option which will ignore all the
whitespace characters in the input string.
Accepts `padding: false` option which will ignore padding from
the input string.
## Examples
iex> Base.url_decode64("_3_-_A==")
{:ok, <<255, 127, 254, 252>>}
iex> Base.url_decode64("_3_-_A==\\n", ignore: :whitespace)
{:ok, <<255, 127, 254, 252>>}
iex> Base.url_decode64("_3_-_A", padding: false)
{:ok, <<255, 127, 254, 252>>}
"""
@spec url_decode64(binary) :: {:ok, binary} | :error
def url_decode64(string) when is_binary(string) do
{:ok, url_decode64!(string)}
@spec url_decode64(binary, Keyword.t) :: {:ok, binary} | :error
def url_decode64(string, opts \\ []) when is_binary(string) do
{:ok, url_decode64!(string, opts)}
rescue
ArgumentError -> :error
end
@@ -311,6 +379,12 @@ defmodule Base do
Decodes a base 64 encoded string with URL and filename safe alphabet
into a binary string.
Accepts `ignore: :whitespace` option which will ignore all the
whitespace characters in the input string.
Accepts `padding: false` option which will ignore padding from
the input string.
An `ArgumentError` exception is raised if the padding is incorrect or
a non-alphabet character is present in the string.
@@ -319,14 +393,18 @@ defmodule Base do
iex> Base.url_decode64!("_3_-_A==")
<<255, 127, 254, 252>>
iex> Base.url_decode64!("_3_-_A==\\n", ignore: :whitespace)
<<255, 127, 254, 252>>
iex> Base.url_decode64!("_3_-_A", padding: false)
<<255, 127, 254, 252>>
"""
@spec url_decode64!(binary) :: binary
def url_decode64!(string) when is_binary(string) and rem(byte_size(string), 4) == 0 do
do_decode64url(string)
end
def url_decode64!(string) when is_binary(string) do
raise ArgumentError, "incorrect padding"
@spec url_decode64!(binary, Keyword.t) :: binary
def url_decode64!(string, opts \\ []) when is_binary(string) do
pad_flag = Keyword.get(opts, :padding, true)
string |> filter_ignored(opts[:ignore]) |> do_decode64url(pad_flag)
end
@doc """
@@ -335,6 +413,9 @@ defmodule Base do
Accepts an atom `:upper` (default) for encoding to upper case characters or
`:lower` for lower case characters.
Accepts `padding: false` option which will omit padding from
the output string.
## Examples
iex> Base.encode32("foobar")
@@ -343,12 +424,16 @@ defmodule Base do
iex> Base.encode32("foobar", case: :lower)
"mzxw6ytboi======"
iex> Base.encode32("foobar", padding: false)
"MZXW6YTBOI"
"""
@spec encode32(binary) :: binary
@spec encode32(binary, Keyword.t) :: binary
def encode32(data, opts \\ []) when is_binary(data) do
case = Keyword.get(opts, :case, :upper)
do_encode32(case, data)
pad_flag = Keyword.get(opts, :padding, true)
do_encode32(case, data, pad_flag)
end
@doc """
@@ -358,6 +443,9 @@ defmodule Base do
`:lower` for lower case characters. `:mixed` can be given for mixed case
characters.
Accepts `padding: false` option which will ignore padding from
the input string.
## Examples
iex> Base.decode32("MZXW6YTBOI======")
@@ -369,6 +457,9 @@ defmodule Base do
iex> Base.decode32("mzXW6ytBOi======", case: :mixed)
{:ok, "foobar"}
iex> Base.decode32("MZXW6YTBOI", padding: false)
{:ok, "foobar"}
"""
@spec decode32(binary) :: {:ok, binary} | :error
@spec decode32(binary, Keyword.t) :: {:ok, binary} | :error
@@ -385,6 +476,9 @@ defmodule Base do
`:lower` for lower case characters. `:mixed` can be given for mixed case
characters.
Accepts `padding: false` option which will ignore padding from
the input string.
An `ArgumentError` exception is raised if the padding is incorrect or
a non-alphabet character is present in the string.
@@ -399,18 +493,16 @@ defmodule Base do
iex> Base.decode32!("mzXW6ytBOi======", case: :mixed)
"foobar"
iex> Base.decode32!("MZXW6YTBOI", padding: false)
"foobar"
"""
@spec decode32!(binary) :: binary
@spec decode32!(binary, Keyword.t) :: binary
def decode32!(string, opts \\ [])
def decode32!(string, opts) when is_binary(string) and rem(byte_size(string), 8) == 0 do
def decode32!(string, opts \\ []) when is_binary(string) do
case = Keyword.get(opts, :case, :upper)
do_decode32(case, string)
end
def decode32!(string, _opts) when is_binary(string) do
raise ArgumentError, "incorrect padding"
pad_flag = Keyword.get(opts, :padding, true)
do_decode32(case, string, pad_flag)
end
@doc """
@@ -420,6 +512,9 @@ defmodule Base do
Accepts an atom `:upper` (default) for encoding to upper case characters or
`:lower` for lower case characters.
Accepts `padding: false` option which will omit padding from
the output string.
## Examples
iex> Base.hex_encode32("foobar")
@@ -428,12 +523,16 @@ defmodule Base do
iex> Base.hex_encode32("foobar", case: :lower)
"cpnmuoj1e8======"
iex> Base.hex_encode32("foobar", padding: false)
"CPNMUOJ1E8"
"""
@spec hex_encode32(binary) :: binary
@spec hex_encode32(binary, Keyword.t) :: binary
def hex_encode32(data, opts \\ []) when is_binary(data) do
case = Keyword.get(opts, :case, :upper)
do_hex_encode32(case, data)
pad_flag = Keyword.get(opts, :padding, true)
do_hex_encode32(case, data, pad_flag)
end
@doc """
@@ -444,6 +543,9 @@ defmodule Base do
`:lower` for lower case characters. `:mixed` can be given for mixed case
characters.
Accepts `padding: false` option which will ignore padding from
the input string.
## Examples
iex> Base.hex_decode32("CPNMUOJ1E8======")
@@ -455,6 +557,9 @@ defmodule Base do
iex> Base.hex_decode32("cpnMuOJ1E8======", case: :mixed)
{:ok, "foobar"}
iex> Base.hex_decode32("CPNMUOJ1E8", padding: false)
{:ok, "foobar"}
"""
@spec hex_decode32(binary) :: {:ok, binary} | :error
@spec hex_decode32(binary, Keyword.t) :: {:ok, binary} | :error
@@ -472,6 +577,9 @@ defmodule Base do
`:lower` for lower case characters. `:mixed` can be given for mixed case
characters.
Accepts `padding: false` option which will ignore padding from
the input string.
An `ArgumentError` exception is raised if the padding is incorrect or
a non-alphabet character is present in the string.
@@ -486,18 +594,21 @@ defmodule Base do
iex> Base.hex_decode32!("cpnMuOJ1E8======", case: :mixed)
"foobar"
iex> Base.hex_decode32!("CPNMUOJ1E8", padding: false)
"foobar"
"""
@spec hex_decode32!(binary) :: binary
@spec hex_decode32!(binary, Keyword.t) :: binary
def hex_decode32!(string, opts \\ [])
def hex_decode32!(string, opts) when is_binary(string) and rem(byte_size(string), 8) == 0 do
def hex_decode32!(string, opts \\ []) when is_binary(string) do
case = Keyword.get(opts, :case, :upper)
do_hex_decode32(case, string)
pad_flag = Keyword.get(opts, :padding, true)
do_hex_decode32(case, string, pad_flag)
end
def hex_decode32!(string, _opts) when is_binary(string) do
raise ArgumentError, "incorrect padding"
defp filter_ignored(string, nil), do: string
defp filter_ignored(string, :whitespace) do
for <<c::8 <- string>>, not c in '\s\t\r\n', into: <<>>, do: <<c::8>>
end
defp do_encode16(_, <<>>), do: <<>>
@@ -525,213 +636,219 @@ defmodule Base do
end
end
defp do_encode64(<<>>), do: <<>>
defp do_encode64(data) do
defp do_encode64(<<>>, _), do: <<>>
defp do_encode64(data, pad_flag) do
split = 3 * div(byte_size(data), 3)
<<main::size(split)-binary, rest::binary>> = data
main = for <<c::6 <- main>>, into: <<>>, do: <<enc64(c)::8>>
case rest do
tail = case rest do
<<c1::6, c2::6, c3::4>> ->
<<main::binary, enc64(c1)::8, enc64(c2)::8, enc64(bsl(c3, 2))::8, ?=>>
<<enc64(c1)::8, enc64(c2)::8, enc64(bsl(c3, 2))::8>>
<<c1::6, c2::2>> ->
<<main::binary, enc64(c1)::8, enc64(bsl(c2, 4))::8, ?=, ?=>>
<<enc64(c1)::8, enc64(bsl(c2, 4))::8>>
<<>> ->
main
<<>>
end
main <> maybe_pad(tail, pad_flag, 4, "=")
end
defp do_decode64(<<>>), do: <<>>
defp do_decode64(string) do
defp do_decode64(<<>>, _), do: <<>>
defp do_decode64(string, false) do
maybe_pad(string, true, 4, "=") |> do_decode64(true)
end
defp do_decode64(string, _pad_flag) when rem(byte_size(string), 4) == 0 do
split = byte_size(string) - 4
<<main::size(split)-binary, rest::binary>> = string
main = for <<c::8 <- main>>, into: <<>>, do: <<dec64(c)::6>>
case rest do
tail = case rest do
<<c1::8, c2::8, ?=, ?=>> ->
<<main::binary, dec64(c1)::6, bsr(dec64(c2), 4)::2>>
<<dec64(c1)::6, bsr(dec64(c2), 4)::2>>
<<c1::8, c2::8, c3::8, ?=>> ->
<<main::binary, dec64(c1)::6, dec64(c2)::6, bsr(dec64(c3), 2)::4>>
<<dec64(c1)::6, dec64(c2)::6, bsr(dec64(c3), 2)::4>>
<<c1::8, c2::8, c3::8, c4::8>> ->
<<main::binary, dec64(c1)::6, dec64(c2)::6, dec64(c3)::6, dec64(c4)::6>>
<<dec64(c1)::6, dec64(c2)::6, dec64(c3)::6, dec64(c4)::6>>
<<>> ->
main
<<>>
end
main <> tail
end
defp do_decode64(_, _) do
raise ArgumentError, "incorrect padding"
end
defp do_encode64url(<<>>), do: <<>>
defp do_encode64url(data) do
defp do_encode64url(<<>>, _), do: <<>>
defp do_encode64url(data, pad_flag) do
split = 3 * div(byte_size(data), 3)
<<main::size(split)-binary, rest::binary>> = data
main = for <<c::6 <- main>>, into: <<>>, do: <<enc64url(c)::8>>
case rest do
tail = case rest do
<<c1::6, c2::6, c3::4>> ->
<<main::binary, enc64url(c1)::8, enc64url(c2)::8, enc64url(bsl(c3, 2))::8, ?=>>
<<enc64url(c1)::8, enc64url(c2)::8, enc64url(bsl(c3, 2))::8>>
<<c1::6, c2::2>> ->
<<main::binary, enc64url(c1)::8, enc64url(bsl(c2, 4))::8, ?=, ?=>>
<<enc64url(c1)::8, enc64url(bsl(c2, 4))::8>>
<<>> ->
main
<<>>
end
main <> maybe_pad(tail, pad_flag, 4, "=")
end
defp do_decode64url(<<>>), do: <<>>
defp do_decode64url(string) do
defp do_decode64url(<<>>, _), do: <<>>
defp do_decode64url(string, false) do
maybe_pad(string, true, 4, "=") |> do_decode64url(true)
end
defp do_decode64url(string, _pad_flag) when rem(byte_size(string), 4) == 0 do
split = byte_size(string) - 4
<<main::size(split)-binary, rest::binary>> = string
main = for <<c::8 <- main>>, into: <<>>, do: <<dec64url(c)::6>>
case rest do
tail = case rest do
<<c1::8, c2::8, ?=, ?=>> ->
<<main::binary, dec64url(c1)::6, bsr(dec64url(c2), 4)::2>>
<<dec64url(c1)::6, bsr(dec64url(c2), 4)::2>>
<<c1::8, c2::8, c3::8, ?=>> ->
<<main::binary, dec64url(c1)::6, dec64url(c2)::6, bsr(dec64url(c3), 2)::4>>
<<dec64url(c1)::6, dec64url(c2)::6, bsr(dec64url(c3), 2)::4>>
<<c1::8, c2::8, c3::8, c4::8>> ->
<<main::binary, dec64url(c1)::6, dec64url(c2)::6, dec64url(c3)::6, dec64url(c4)::6>>
<<dec64url(c1)::6, dec64url(c2)::6, dec64url(c3)::6, dec64url(c4)::6>>
<<>> ->
main
<<>>
end
main <> tail
end
defp do_decode64url(_, _) do
raise ArgumentError, "incorrect padding"
end
defp do_encode32(_, <<>>), do: <<>>
defp do_encode32(_, <<>>, _), do: <<>>
for {case, fun} <- [upper: :to_upper, lower: :to_lower] do
defp do_encode32(unquote(case), data) do
defp do_encode32(unquote(case), data, pad_flag) do
split = 5 * div(byte_size(data), 5)
<<main::size(split)-binary, rest::binary>> = data
main = for <<c::5 <- main>>, into: <<>>, do: <<unquote(fun)(enc32(c))::8>>
case rest do
tail = case rest do
<<c1::5, c2::5, c3::5, c4::5, c5::5, c6::5, c7::2>> ->
<<main::binary,
unquote(fun)(enc32(c1))::8, unquote(fun)(enc32(c2))::8,
<<unquote(fun)(enc32(c1))::8, unquote(fun)(enc32(c2))::8,
unquote(fun)(enc32(c3))::8, unquote(fun)(enc32(c4))::8,
unquote(fun)(enc32(c5))::8, unquote(fun)(enc32(c6))::8,
unquote(fun)(enc32(bsl(c7, 3)))::8, ?=>>
unquote(fun)(enc32(bsl(c7, 3)))::8>>
<<c1::5, c2::5, c3::5, c4::5, c5::4>> ->
<<main::binary,
unquote(fun)(enc32(c1))::8, unquote(fun)(enc32(c2))::8,
<<unquote(fun)(enc32(c1))::8, unquote(fun)(enc32(c2))::8,
unquote(fun)(enc32(c3))::8, unquote(fun)(enc32(c4))::8,
unquote(fun)(enc32(bsl(c5, 1)))::8, ?=, ?=, ?=>>
unquote(fun)(enc32(bsl(c5, 1)))::8>>
<<c1::5, c2::5, c3::5, c4::1>> ->
<<main::binary,
unquote(fun)(enc32(c1))::8, unquote(fun)(enc32(c2))::8,
unquote(fun)(enc32(c3))::8, unquote(fun)(enc32(bsl(c4, 4)))::8,
?=, ?=, ?=, ?=>>
<<unquote(fun)(enc32(c1))::8, unquote(fun)(enc32(c2))::8,
unquote(fun)(enc32(c3))::8, unquote(fun)(enc32(bsl(c4, 4)))::8>>
<<c1::5, c2::3>> ->
<<main::binary,
unquote(fun)(enc32(c1))::8, unquote(fun)(enc32(bsl(c2, 2)))::8, ?=, ?=,
?=, ?=, ?=, ?=>>
<<unquote(fun)(enc32(c1))::8, unquote(fun)(enc32(bsl(c2, 2)))::8>>
<<>> ->
main
<<>>
end
main <> maybe_pad(tail, pad_flag, 8, "=")
end
end
defp do_decode32(_, <<>>), do: <<>>
defp do_decode32(_, <<>>, _), do: <<>>
defp do_decode32(case, string, false),
do: do_decode32(case, maybe_pad(string, true, 8, "="), true)
for {case, fun} <- [upper: :from_upper, lower: :from_lower, mixed: :from_mixed] do
defp do_decode32(unquote(case), string) do
defp do_decode32(unquote(case), string, _pad_flag) when rem(byte_size(string), 8) == 0 do
split = byte_size(string) - 8
<<main::size(split)-binary, rest::binary>> = string
main = for <<c::8 <- main>>, into: <<>>, do: <<dec32(unquote(fun)(c))::5>>
case rest do
tail = case rest do
<<c1::8, c2::8, ?=, ?=, ?=, ?=, ?=, ?=>> ->
<<main::binary, dec32(unquote(fun)(c1))::5,
bsr(dec32(unquote(fun)(c2)), 2)::3>>
<<dec32(unquote(fun)(c1))::5, bsr(dec32(unquote(fun)(c2)), 2)::3>>
<<c1::8, c2::8, c3::8, c4::8, ?=, ?=, ?=, ?=>> ->
<<main::binary,
dec32(unquote(fun)(c1))::5, dec32(unquote(fun)(c2))::5,
<<dec32(unquote(fun)(c1))::5, dec32(unquote(fun)(c2))::5,
dec32(unquote(fun)(c3))::5, bsr(dec32(unquote(fun)(c4)), 4)::1>>
<<c1::8, c2::8, c3::8, c4::8, c5::8, ?=, ?=, ?=>> ->
<<main::binary,
dec32(unquote(fun)(c1))::5, dec32(unquote(fun)(c2))::5,
<<dec32(unquote(fun)(c1))::5, dec32(unquote(fun)(c2))::5,
dec32(unquote(fun)(c3))::5, dec32(unquote(fun)(c4))::5,
bsr(dec32(unquote(fun)(c5)), 1)::4>>
<<c1::8, c2::8, c3::8, c4::8, c5::8, c6::8, c7::8, ?=>> ->
<<main::binary,
dec32(unquote(fun)(c1))::5, dec32(unquote(fun)(c2))::5,
<<dec32(unquote(fun)(c1))::5, dec32(unquote(fun)(c2))::5,
dec32(unquote(fun)(c3))::5, dec32(unquote(fun)(c4))::5,
dec32(unquote(fun)(c5))::5, dec32(unquote(fun)(c6))::5,
bsr(dec32(unquote(fun)(c7)), 3)::2>>
<<c1::8, c2::8, c3::8, c4::8, c5::8, c6::8, c7::8, c8::8>> ->
<<main::binary,
dec32(unquote(fun)(c1))::5, dec32(unquote(fun)(c2))::5,
<<dec32(unquote(fun)(c1))::5, dec32(unquote(fun)(c2))::5,
dec32(unquote(fun)(c3))::5, dec32(unquote(fun)(c4))::5,
dec32(unquote(fun)(c5))::5, dec32(unquote(fun)(c6))::5,
dec32(unquote(fun)(c7))::5, dec32(unquote(fun)(c8))::5>>
<<>> ->
main
<<>>
end
main <> tail
end
end
defp do_hex_encode32(_, <<>>), do: <<>>
defp do_decode32(_, _, _),
do: raise ArgumentError, "incorrect padding"
defp do_hex_encode32(_, <<>>, _), do: <<>>
for {case, fun} <- [upper: :to_upper, lower: :to_lower] do
defp do_hex_encode32(unquote(case), data) do
defp do_hex_encode32(unquote(case), data, pad_flag) do
split = 5 * div(byte_size(data), 5)
<<main::size(split)-binary, rest::binary>> = data
main = for <<c::5 <- main>>, into: <<>>, do: <<unquote(fun)(enc32hex(c))::8>>
case rest do
tail = case rest do
<<c1::5, c2::5, c3::5, c4::5, c5::5, c6::5, c7::2>> ->
<<main::binary,
unquote(fun)(enc32hex(c1))::8, unquote(fun)(enc32hex(c2))::8,
<<unquote(fun)(enc32hex(c1))::8, unquote(fun)(enc32hex(c2))::8,
unquote(fun)(enc32hex(c3))::8, unquote(fun)(enc32hex(c4))::8,
unquote(fun)(enc32hex(c5))::8, unquote(fun)(enc32hex(c6))::8,
unquote(fun)(enc32hex(bsl(c7, 3)))::8, ?=>>
unquote(fun)(enc32hex(bsl(c7, 3)))::8>>
<<c1::5, c2::5, c3::5, c4::5, c5::4>> ->
<<main::binary,
unquote(fun)(enc32hex(c1))::8, unquote(fun)(enc32hex(c2))::8,
<<unquote(fun)(enc32hex(c1))::8, unquote(fun)(enc32hex(c2))::8,
unquote(fun)(enc32hex(c3))::8, unquote(fun)(enc32hex(c4))::8,
unquote(fun)(enc32hex(bsl(c5, 1)))::8, ?=, ?=, ?=>>
unquote(fun)(enc32hex(bsl(c5, 1)))::8>>
<<c1::5, c2::5, c3::5, c4::1>> ->
<<main::binary,
unquote(fun)(enc32hex(c1))::8, unquote(fun)(enc32hex(c2))::8,
unquote(fun)(enc32hex(c3))::8, unquote(fun)(enc32hex(bsl(c4, 4)))::8,
?=, ?=, ?=, ?=>>
<<unquote(fun)(enc32hex(c1))::8, unquote(fun)(enc32hex(c2))::8,
unquote(fun)(enc32hex(c3))::8, unquote(fun)(enc32hex(bsl(c4, 4)))::8>>
<<c1::5, c2::3>> ->
<<main::binary,
unquote(fun)(enc32hex(c1))::8, unquote(fun)(enc32hex(bsl(c2, 2)))::8, ?=, ?=,
?=, ?=, ?=, ?=>>
<<unquote(fun)(enc32hex(c1))::8, unquote(fun)(enc32hex(bsl(c2, 2)))::8>>
<<>> ->
main
<<>>
end
main <> maybe_pad(tail, pad_flag, 8, "=")
end
end
defp do_hex_decode32(_, <<>>), do: <<>>
defp do_hex_decode32(_, <<>>, _), do: <<>>
defp do_hex_decode32(case, string, false),
do: do_hex_decode32(case, maybe_pad(string, true, 8, "="), true)
for {case, fun} <- [upper: :from_upper, lower: :from_lower, mixed: :from_mixed] do
defp do_hex_decode32(unquote(case), string) do
defp do_hex_decode32(unquote(case), string, _pad_flag) when rem(byte_size(string), 8) == 0 do
split = byte_size(string) - 8
<<main::size(split)-binary, rest::binary>> = string
main = for <<c::8 <- main>>, into: <<>>, do: <<dec32hex(unquote(fun)(c))::5>>
case rest do
tail = case rest do
<<c1::8, c2::8, ?=, ?=, ?=, ?=, ?=, ?=>> ->
<<main::binary, dec32hex(unquote(fun)(c1))::5,
bsr(dec32hex(unquote(fun)(c2)), 2)::3>>
<<dec32hex(unquote(fun)(c1))::5, bsr(dec32hex(unquote(fun)(c2)), 2)::3>>
<<c1::8, c2::8, c3::8, c4::8, ?=, ?=, ?=, ?=>> ->
<<main::binary,
dec32hex(unquote(fun)(c1))::5, dec32hex(unquote(fun)(c2))::5,
<<dec32hex(unquote(fun)(c1))::5, dec32hex(unquote(fun)(c2))::5,
dec32hex(unquote(fun)(c3))::5, bsr(dec32hex(unquote(fun)(c4)), 4)::1>>
<<c1::8, c2::8, c3::8, c4::8, c5::8, ?=, ?=, ?=>> ->
<<main::binary,
dec32hex(unquote(fun)(c1))::5, dec32hex(unquote(fun)(c2))::5,
<<dec32hex(unquote(fun)(c1))::5, dec32hex(unquote(fun)(c2))::5,
dec32hex(unquote(fun)(c3))::5, dec32hex(unquote(fun)(c4))::5,
bsr(dec32hex(unquote(fun)(c5)), 1)::4>>
<<c1::8, c2::8, c3::8, c4::8, c5::8, c6::8, c7::8, ?=>> ->
<<main::binary,
dec32hex(unquote(fun)(c1))::5, dec32hex(unquote(fun)(c2))::5,
<<dec32hex(unquote(fun)(c1))::5, dec32hex(unquote(fun)(c2))::5,
dec32hex(unquote(fun)(c3))::5, dec32hex(unquote(fun)(c4))::5,
dec32hex(unquote(fun)(c5))::5, dec32hex(unquote(fun)(c6))::5,
bsr(dec32hex(unquote(fun)(c7)), 3)::2>>
<<c1::8, c2::8, c3::8, c4::8, c5::8, c6::8, c7::8, c8::8>> ->
<<main::binary,
dec32hex(unquote(fun)(c1))::5, dec32hex(unquote(fun)(c2))::5,
<<dec32hex(unquote(fun)(c1))::5, dec32hex(unquote(fun)(c2))::5,
dec32hex(unquote(fun)(c3))::5, dec32hex(unquote(fun)(c4))::5,
dec32hex(unquote(fun)(c5))::5, dec32hex(unquote(fun)(c6))::5,
dec32hex(unquote(fun)(c7))::5, dec32hex(unquote(fun)(c8))::5>>
<<>> ->
main
<<>>
end
main <> tail
end
end
defp do_hex_decode32(_, _, _),
do: raise ArgumentError, "incorrect padding"
end
+1 -1
View File
@@ -48,7 +48,7 @@ defprotocol Inspect do
implementation directly. For example, to test Inspect.MapSet above,
you can invoke it as:
Inspect.MapSet.inspect(MapSet.new, Inspect.Opts.new)
Inspect.MapSet.inspect(MapSet.new, %Inspect.Opts{})
"""
+2 -2
View File
@@ -167,11 +167,11 @@ defmodule Integer do
defp do_parse(_, _), do: :error
defp do_parse(<<char, rest::binary>>, base, acc) do
defp do_parse(<<char, rest::binary>> = bin, base, acc) do
if valid_digit_in_base?(char, base) do
do_parse(rest, base, base * acc + parse_digit(char, base))
else
{acc, <<char, rest::binary>>}
{acc, bin}
end
end
+23 -18
View File
@@ -239,9 +239,11 @@ defmodule String do
def printable?(<<>>), do: true
def printable?(binary) when is_binary(binary), do: false
@doc """
@doc ~S"""
Divides a string into substrings at each Unicode whitespace
occurrence with leading and trailing whitespace ignored.
occurrence with leading and trailing whitespace ignored. Groups
of whitespace are treated as a single occurrence. Divisions do
not occur on non-breaking whitespace.
## Examples
@@ -254,9 +256,12 @@ defmodule String do
iex> String.split(" foo bar ")
["foo", "bar"]
iex> String.split("no\u00a0break")
["no\u00a0break"]
"""
@spec split(t) :: [t]
defdelegate split(binary), to: String.Unicode
defdelegate split(binary), to: String.Break
@doc ~S"""
Divides a string into substrings based on a pattern.
@@ -444,7 +449,7 @@ defmodule String do
end
defp do_split_at(string, position) do
{byte_size, rest} = String.Graphemes.split_at(string, position)
{byte_size, rest} = String.Unicode.split_at(string, position)
{binary_part(string, 0, byte_size), rest || ""}
end
@@ -499,7 +504,7 @@ defmodule String do
## Examples
iex> String.normalize("yêṩ", :nfd)
"yêṩ"
"yêṩ"
iex> String.normalize("leña", :nfc)
"leña"
@@ -524,7 +529,7 @@ defmodule String do
"""
@spec upcase(t) :: t
defdelegate upcase(binary), to: String.Unicode
defdelegate upcase(binary), to: String.Casing
@doc """
Converts all characters in the given string to lowercase.
@@ -542,7 +547,7 @@ defmodule String do
"""
@spec downcase(t) :: t
defdelegate downcase(binary), to: String.Unicode
defdelegate downcase(binary), to: String.Casing
@doc """
Converts the first character in the given string to
@@ -567,7 +572,7 @@ defmodule String do
"""
@spec capitalize(t) :: t
def capitalize(string) when is_binary(string) do
{char, rest} = String.Unicode.titlecase_once(string)
{char, rest} = String.Casing.titlecase_once(string)
char <> downcase(rest)
end
@@ -582,7 +587,7 @@ defmodule String do
"""
@spec rstrip(t) :: t
defdelegate rstrip(binary), to: String.Unicode
defdelegate rstrip(binary), to: String.Break
@doc """
Returns a string where all trailing `char`s have been removed.
@@ -661,7 +666,7 @@ defmodule String do
replace_trailing(string, match, replacement, prefix_size, suffix_size, "")
end
defp replace_trailing(string, match, replacement, prefix_size, suffix_size, acc) when prefix_size > 0 do
defp replace_trailing(string, match, replacement, prefix_size, suffix_size, acc) when prefix_size >= 0 do
case string do
<<prefix::size(prefix_size)-binary, suffix::size(suffix_size)-binary>> when suffix == match ->
replace_trailing(prefix, match, replacement, prefix_size - suffix_size, suffix_size, acc <> replacement)
@@ -754,7 +759,7 @@ defmodule String do
"abc "
"""
defdelegate lstrip(binary), to: String.Unicode
defdelegate lstrip(binary), to: String.Break
@doc """
Returns a string where all leading `char`s have been removed.
@@ -1179,7 +1184,7 @@ defmodule String do
"""
@spec graphemes(t) :: [grapheme]
defdelegate graphemes(string), to: String.Graphemes
defdelegate graphemes(string), to: String.Unicode
@compile {:inline, next_grapheme: 1, next_grapheme_size: 1}
@@ -1218,7 +1223,7 @@ defmodule String do
"""
@spec next_grapheme_size(t) :: {pos_integer, t} | nil
defdelegate next_grapheme_size(string), to: String.Graphemes
defdelegate next_grapheme_size(string), to: String.Unicode
@doc """
Returns the first grapheme from a utf8 string,
@@ -1278,7 +1283,7 @@ defmodule String do
"""
@spec length(t) :: non_neg_integer
defdelegate length(string), to: String.Graphemes
defdelegate length(string), to: String.Unicode
@doc """
Returns the grapheme at the `position` of the given utf8 `string`.
@@ -1317,7 +1322,7 @@ defmodule String do
end
defp do_at(string, position) do
case String.Graphemes.split_at(string, position) do
case String.Unicode.split_at(string, position) do
{_, nil} -> nil
{_, rest} -> first(rest)
end
@@ -1367,10 +1372,10 @@ defmodule String do
end
def slice(string, start, len) when start >= 0 and len >= 0 do
case String.Graphemes.split_at(string, start) do
case String.Unicode.split_at(string, start) do
{_, nil} -> ""
{start_bytes, rest} ->
{len_bytes, _} = String.Graphemes.split_at(rest, len)
{len_bytes, _} = String.Unicode.split_at(rest, len)
binary_part(string, start_bytes, len_bytes)
end
end
@@ -1438,7 +1443,7 @@ defmodule String do
def slice("", _.._), do: ""
def slice(string, first..-1) when first >= 0 do
case String.Graphemes.split_at(string, first) do
case String.Unicode.split_at(string, first) do
{_, nil} ->
""
{start_bytes, _} ->
+1 -1
View File
@@ -317,7 +317,7 @@ defmodule Version do
(?:\.(\d+))? # minor
(?:\.(\d+))? # patch
(?:\-([\d\w\.\-]+))? # pre
(?:\+([\d\w\-]+))? # build
(?:\+([\d\w\.\-]+))? # build
$/x
@spec parse_requirement(String.t) :: {:ok, Version.Requirement.t} | :error
+1 -1
View File
@@ -100,8 +100,8 @@ Built-in type | Defined as
`list()` | `[any()]`
`maybe_improper_list()` | `maybe_improper_list(any(), any())`
`nonempty_list()` | `nonempty_list(any())`
`iolist()` | `maybe_improper_list(byte() \| binary() \| iolist(), binary() \| [])`
`iodata()` | `iolist()` \| `binary()`
`iolist()` | `maybe_improper_list(byte()` \| `binary()` \| `iolist(), binary()` \| `[])`
`module()` | `atom()` \| `tuple()`
`arity()` | `0..255`
`mfa()` | `{atom(), atom(), arity()}`
+22 -13
View File
@@ -78,9 +78,8 @@ code_loading_compilation(Forms, Vars, #{line := Line} = E) ->
%% Pass {native, false} to speed up bootstrap
%% process when native is set to true
AllOpts = options(),
FinalOpts = AllOpts -- [native, warn_missing_spec],
inner_module(Form, FinalOpts, true, E, fun(_, Binary) ->
ErlOpts = options() -- [native, warn_missing_spec],
inner_module(Form, ErlOpts, [{bootstrap, true}], E, fun(_, Binary) ->
%% If we have labeled locals, anonymous functions
%% were created and therefore we cannot ditch the
%% module
@@ -169,22 +168,32 @@ allows_fast_compilation(_) -> false.
%% executes the callback in case of success. This automatically
%% handles errors and warnings. Used by this module and elixir_module.
module(Forms, Opts, E, Callback) ->
Final =
case (get_opt(debug_info) == true) orelse
lists:member(debug_info, Opts) of
true -> [debug_info] ++ options();
false -> options()
ErlOpts =
case proplists:get_value(debug_info, Opts) of
true -> [debug_info];
false -> [];
undefined ->
case get_opt(debug_info) of
true -> [debug_info];
false -> []
end
end,
inner_module(Forms, Final, false, E, Callback).
inner_module(Forms, ErlOpts ++ options(), Opts, E, Callback).
inner_module(Forms, Options, Bootstrap, #{file := File} = E, Callback) when
is_list(Forms), is_list(Options), is_boolean(Bootstrap), is_function(Callback) ->
inner_module(Forms, ErlOpts, ExOpts, #{file := File} = E, Callback) when
is_list(Forms), is_list(ErlOpts), is_list(ExOpts), is_function(Callback) ->
Source = elixir_utils:characters_to_list(File),
Autoload = proplists:get_value(autoload, ExOpts, true),
Bootstrap = proplists:get_value(bootstrap, ExOpts, false),
case compile:noenv_forms([no_auto_import()|Forms], [return, {source, Source}|Options]) of
case compile:noenv_forms([no_auto_import()|Forms], [return, {source, Source}|ErlOpts]) of
{ok, Module, Binary, Warnings} ->
format_warnings(Bootstrap, Warnings),
{module, Module} = code:load_binary(Module, beam_location(E), Binary),
{module, Module} =
case Autoload of
true -> code:load_binary(Module, beam_location(E), Binary);
false -> {module, Module}
end,
Callback(Module, Binary);
{error, Errors, Warnings} ->
format_warnings(Bootstrap, Warnings),
+1 -1
View File
@@ -331,7 +331,7 @@ spec_for_macro(Else) -> Else.
compile_opts(Module) ->
case ets:lookup(data_table(Module), compile) of
[{compile, Opts}] when is_list(Opts) -> Opts;
[{compile, Opts}] when is_list(Opts) -> lists:flatten(Opts);
[] -> []
end.
@@ -38,6 +38,7 @@ defmodule ApplicationTest do
test "application specification" do
assert is_list Application.spec(:elixir)
assert Application.spec(:unknown) == nil
assert Application.spec(:unknown, :description) == nil
assert Application.spec(:elixir, :description) == 'elixir'
assert_raise FunctionClauseError, fn -> Application.spec(:elixir, :unknown) end
+280
View File
@@ -93,6 +93,18 @@ defmodule BaseTest do
assert "MDEyMzQ1Njc4OSFAIzBeJiooKTs6PD4sLiBbXXt9" == encode64(<<"0123456789!@#0^&*();:<>,. []{}">>)
end
test "encode64 omit padding one pad" do
assert "SGVsbG8gV29ybGQ" == encode64("Hello World", padding: false)
end
test "encode64 omit padding two pads" do
assert "QWxhZGRpbjpvcGVuIHNlc2FtZQ" == encode64("Aladdin:open sesame", padding: false)
end
test "encode64 omit padding no pad" do
assert "QWxhZGRpbjpvcGVuIHNlc2Ft" == encode64("Aladdin:open sesam", padding: false)
end
test "decode64 empty" do
assert {:ok, ""} == decode64("")
end
@@ -135,6 +147,18 @@ defmodule BaseTest do
end
end
test "decode64 whitespace" do
assert :error == decode64("\nQWxhZGRp bjpvcGVu\sIHNlc2Ft\t")
assert {:ok, "Aladdin:open sesam"} == decode64("\nQWxhZGRp bjpvcGVu\sIHNlc2Ft\t", ignore: :whitespace)
end
test "decode64! whitespace" do
assert_raise ArgumentError, "non-alphabet digit found: \"\\n\" (byte 10)", fn ->
decode64!("\nQWxhZGRp bjpvcGVu\sIHNlc2Ft\t")
end
assert "Aladdin:open sesam" == decode64!("\nQWxhZGRp bjpvcGVu\sIHNlc2Ft\t", ignore: :whitespace)
end
test "decode64 incorrect padding" do
assert :error == decode64("SGVsbG8gV29ybGQ")
end
@@ -145,6 +169,38 @@ defmodule BaseTest do
end
end
test "decode64 ignore padding two pads" do
assert {:ok, "Aladdin:open sesame"} == decode64("QWxhZGRpbjpvcGVuIHNlc2FtZQ", padding: false)
end
test "decode64! ignore padding two pads" do
assert "Aladdin:open sesame" == decode64!("QWxhZGRpbjpvcGVuIHNlc2FtZQ", padding: false)
end
test "decode64 ignore padding one pad" do
assert {:ok, "Hello World"} == decode64("SGVsbG8gV29ybGQ", padding: false)
end
test "decode64! ignore padding one pad" do
assert "Hello World" == decode64!("SGVsbG8gV29ybGQ", padding: false)
end
test "decode64 ignore padding no pad" do
assert {:ok, "Aladdin:open sesam"} == decode64("QWxhZGRpbjpvcGVuIHNlc2Ft", padding: false)
end
test "decode64! ignore padding no pad" do
assert "Aladdin:open sesam" == decode64!("QWxhZGRpbjpvcGVuIHNlc2Ft", padding: false)
end
test "decode64 ignore padding incorrect padding" do
assert {:ok, "Hello World"} == decode64("SGVsbG8gV29ybGQ", padding: false)
end
test "decode64! ignore padding incorrect padding" do
assert "Hello World" == decode64!("SGVsbG8gV29ybGQ", padding: false)
end
test "url_encode64 empty" do
assert "" == url_encode64("")
end
@@ -162,6 +218,18 @@ defmodule BaseTest do
assert "MDEyMzQ1Njc4OSFAIzBeJiooKTs6PD4sLiBbXXt9" == url_encode64(<<"0123456789!@#0^&*();:<>,. []{}">>)
end
test "url_encode64 omit padding two pads" do
assert "QWxhZGRpbjpvcGVuIHNlc2FtZQ" == url_encode64("Aladdin:open sesame", padding: false)
end
test "url_encode64 omit padding one pad" do
assert "SGVsbG8gV29ybGQ" == url_encode64("Hello World", padding: false)
end
test "url_encode64 omit padding no pad" do
assert "QWxhZGRpbjpvcGVuIHNlc2Ft" == url_encode64("Aladdin:open sesam", padding: false)
end
test "url_encode64 no URL unsafe characters" do
refute "/3/+/A==" == url_encode64(<<255, 127, 254, 252>>)
assert "_3_-_A==" == url_encode64(<<255, 127, 254, 252>>)
@@ -199,6 +267,18 @@ defmodule BaseTest do
assert "Aladdin:open sesam" == url_decode64!("QWxhZGRpbjpvcGVuIHNlc2Ft")
end
test "url_decode64 whitespace" do
assert :error == url_decode64("\nQWxhZGRp bjpvcGVu\sIHNlc2Ft\t")
assert {:ok, "Aladdin:open sesam"} == url_decode64("\nQWxhZGRp bjpvcGVu\sIHNlc2Ft\t", ignore: :whitespace)
end
test "url_decode64! whitespace" do
assert_raise ArgumentError, "non-alphabet digit found: \"\\n\" (byte 10)", fn ->
url_decode64!("\nQWxhZGRp bjpvcGVu\sIHNlc2Ft\t")
end
assert "Aladdin:open sesam" == url_decode64!("\nQWxhZGRp bjpvcGVu\sIHNlc2Ft\t", ignore: :whitespace)
end
test "url_decode64 non-alphabet digit" do
assert :error == url_decode64("Zm9)")
end
@@ -219,6 +299,38 @@ defmodule BaseTest do
end
end
test "url_decode64 ignore padding two pads" do
assert {:ok, "Aladdin:open sesame"} == url_decode64("QWxhZGRpbjpvcGVuIHNlc2FtZQ", padding: false)
end
test "url_decode64! ignore padding two pads" do
assert "Aladdin:open sesame" == url_decode64!("QWxhZGRpbjpvcGVuIHNlc2FtZQ", padding: false)
end
test "url_decode64 ignore padding one pad" do
assert {:ok, "Hello World"} == url_decode64("SGVsbG8gV29ybGQ", padding: false)
end
test "url_decode64! ignore padding one pad" do
assert "Hello World" == url_decode64!("SGVsbG8gV29ybGQ", padding: false)
end
test "url_decode64 ignore padding no pad" do
assert {:ok, "Aladdin:open sesam"} == url_decode64("QWxhZGRpbjpvcGVuIHNlc2Ft", padding: false)
end
test "url_decode64! ignore padding no pad" do
assert "Aladdin:open sesam" == url_decode64!("QWxhZGRpbjpvcGVuIHNlc2Ft", padding: false)
end
test "url_decode64 ignore padding incorrect padding" do
assert {:ok, "Hello World"} == url_decode64("SGVsbG8gV29ybGQ", padding: false)
end
test "url_decode64! ignore padding incorrect padding" do
assert "Hello World" == url_decode64!("SGVsbG8gV29ybGQ", padding: false)
end
test "encode32 empty" do
assert "" == encode32("")
end
@@ -244,6 +356,26 @@ defmodule BaseTest do
assert "MZXW6YTB" == encode32("fooba")
end
test "encode32 omit padding one pad" do
assert "MZXW6YQ" == encode32("foob", padding: false)
end
test "encode32 omit padding three pads" do
assert "MZXW6" == encode32("foo", padding: false)
end
test "encode32 omit padding four pads" do
assert "MZXQ" == encode32("fo", padding: false)
end
test "encode32 omit padding six pads" do
assert "MZXW6YTBOI" == encode32("foobar", padding: false)
end
test "encode32 omit padding no pads" do
assert "MZXW6YTB" == encode32("fooba", padding: false)
end
test "encode32 lowercase" do
assert "mzxw6ytb" == encode32("fooba", case: :lower)
end
@@ -342,6 +474,70 @@ defmodule BaseTest do
end
end
test "decode32 ignore padding one pad" do
assert {:ok, "foob"} == decode32("MZXW6YQ", padding: false)
end
test "decode32! ignore padding one pad" do
assert "foob" == decode32!("MZXW6YQ", padding: false)
end
test "decode32 ignore padding three pads" do
assert {:ok, "foo"} == decode32("MZXW6", padding: false)
end
test "decode32! ignore padding three pads" do
assert "foo" == decode32!("MZXW6", padding: false)
end
test "decode32 ignore padding four pads" do
assert {:ok, "fo"} == decode32("MZXQ", padding: false)
end
test "decode32! ignore padding four pads" do
assert "fo" == decode32!("MZXQ", padding: false)
end
test "decode32 ignore padding lowercase" do
assert {:ok, "fo"} == decode32("mzxq", case: :lower, padding: false)
end
test "decode32! ignore padding lowercase" do
assert "fo" == decode32!("mzxq", case: :lower, padding: false)
end
test "decode32 ignore padding mixed case" do
assert {:ok, "fo"} == decode32("mZXq", case: :mixed, padding: false)
end
test "decode32! ignore padding mixed case" do
assert "fo" == decode32!("mZXq", case: :mixed, padding: false)
end
test "decode32 ignore padding six pads" do
assert {:ok, "foobar"} == decode32("MZXW6YTBOI", padding: false)
end
test "decode32! ignore padding six pads" do
assert "foobar" == decode32!("MZXW6YTBOI", padding: false)
end
test "decode32 ignore padding no pads" do
assert {:ok, "fooba"} == decode32("MZXW6YTB", padding: false)
end
test "decode32! ignore padding no pads" do
assert "fooba" == decode32!("MZXW6YTB", padding: false)
end
test "decode32 ignore padding incorrect padding" do
assert {:ok, "foob"} == decode32("MZXW6YQ", padding: false)
end
test "decode32! ignore padding incorrect padding" do
"foob" = decode32!("MZXW6YQ", padding: false)
end
test "hex_encode32 empty" do
assert "" == hex_encode32("")
end
@@ -367,6 +563,26 @@ defmodule BaseTest do
assert "CPNMUOJ1" == hex_encode32("fooba")
end
test "hex_encode32 omit padding one pad" do
assert "CPNMUOG" == hex_encode32("foob", padding: false)
end
test "hex_encode32 omit padding three pads" do
assert "CPNMU" == hex_encode32("foo", padding: false)
end
test "hex_encode32 omit padding four pads" do
assert "CPNG" == hex_encode32("fo", padding: false)
end
test "hex_encode32 omit padding six pads" do
assert "CPNMUOJ1E8" == hex_encode32("foobar", padding: false)
end
test "hex_encode32 omit padding no pads" do
assert "CPNMUOJ1" == hex_encode32("fooba", padding: false)
end
test "hex_encode32 lowercase" do
assert "cpnmuoj1" == hex_encode32("fooba", case: :lower)
end
@@ -470,4 +686,68 @@ defmodule BaseTest do
decode16!("012" <> <<0>>)
end
end
test "hex_decode32 ignore padding one pad" do
assert {:ok, "foob"} == hex_decode32("CPNMUOG", padding: false)
end
test "hex_decode32! ignore padding one pad" do
assert "foob" == hex_decode32!("CPNMUOG", padding: false)
end
test "hex_decode32 ignore padding three pads" do
assert {:ok, "foo"} == hex_decode32("CPNMU", padding: false)
end
test "hex_decode32! ignore padding three pads" do
assert "foo" == hex_decode32!("CPNMU", padding: false)
end
test "hex_decode32 ignore padding four pads" do
assert {:ok, "fo"} == hex_decode32("CPNG", padding: false)
end
test "hex_decode32! ignore padding four pads" do
assert "fo" == hex_decode32!("CPNG", padding: false)
end
test "hex_decode32 ignore padding six pads" do
assert {:ok, "foobar"} == hex_decode32("CPNMUOJ1E8", padding: false)
end
test "hex_decode32! ignore padding six pads" do
assert "foobar" == hex_decode32!("CPNMUOJ1E8", padding: false)
end
test "hex_decode32 ignore padding no pads" do
assert {:ok, "fooba"} == hex_decode32("CPNMUOJ1", padding: false)
end
test "hex_decode32! ignore padding no pads" do
assert "fooba" == hex_decode32!("CPNMUOJ1", padding: false)
end
test "hex_decode32 ignore padding incorrect padding" do
assert {:ok, "foob"} == hex_decode32("CPNMUOG", padding: false)
end
test "hex_decode32! ignore padding incorrect padding" do
"foob" = hex_decode32!("CPNMUOG", padding: false)
end
test "hex_decode32 ignoring padding lowercase" do
assert {:ok, "fo"} == hex_decode32("cpng", case: :lower, padding: false)
end
test "hex_decode32! ignore padding lowercase" do
assert "fo" == hex_decode32!("cpng", case: :lower, padding: false)
end
test "hex_decode32 ignore padding mixed case" do
assert {:ok, "fo"} == hex_decode32("cPNg====", case: :mixed, padding: false)
end
test "hex_decode32! ignore padding mixed case" do
assert "fo" == hex_decode32!("cPNg", case: :mixed, padding: false)
end
end
+7
View File
@@ -144,6 +144,13 @@ defmodule ModuleTest do
assert [3, 2, 1] = @other_attribute
end
test "@compile autoload attribute" do
defmodule NoAutoload do
@compile {:autoload, false}
end
refute :code.is_loaded(NoAutoload)
end
## Naming
test "concat" do
+63 -4
View File
@@ -33,8 +33,12 @@ defmodule StringTest do
assert String.split("foo bar ") == ["foo", "bar"]
assert String.split(" foo bar ") == ["foo", "bar"]
assert String.split("foo\t\n\v\f\r\sbar\n") == ["foo", "bar"]
assert String.split("foo" <> <<31>> <> "bar") == ["foo", "bar"]
assert String.split("foo" <> <<194, 133>> <> "bar") == ["foo", "bar"]
# information separators are not considered whitespace
assert String.split("foo\u001Fbar") == ["foo\u001Fbar"]
# no-break space is excluded
assert String.split("foo\00A0bar") == ["foo\00A0bar"]
assert String.split("foo\u202Fbar") == ["foo\u202Fbar"]
assert String.split("a,b,c", ",") == ["a", "b", "c"]
assert String.split("a,b", ".") == ["a,b"]
@@ -160,6 +164,17 @@ defmodule StringTest do
assert String.capitalize("fin") == "Fin"
end
test "replace_trailing" do
assert String.replace_trailing(" abc aa", "a", "") == " abc "
assert String.replace_trailing(" abc __", "_", "") == " abc "
assert String.replace_trailing(" aaaaaaaaa", "a", "") == " "
assert String.replace_trailing("aaaaaaaaaa", "a", "") == ""
assert String.replace_trailing("]]]]]]]]]]", "]", "") == ""
assert String.replace_trailing(" cat 猫猫", "猫", "") == " cat "
assert String.replace_trailing("test", "t", "") == "tes"
assert String.replace_trailing("t", "t", "") == ""
end
test "rstrip" do
assert String.rstrip("") == ""
assert String.rstrip("1\n") == "1"
@@ -168,11 +183,17 @@ defmodule StringTest do
assert String.rstrip(" abc a") == " abc a"
assert String.rstrip("a abc a\n\n") == "a abc a"
assert String.rstrip("a abc a\t\n\v\f\r\s") == "a abc a"
assert String.rstrip("a abc a " <> <<31>>) == "a abc a"
assert String.rstrip("a abc a" <> <<194, 133>>) == "a abc a"
assert String.rstrip(" abc aa", ?a) == " abc "
assert String.rstrip(" abc __", ?_) == " abc "
assert String.rstrip(" aaaaaaaaa", ?a) == " "
assert String.rstrip("aaaaaaaaaa", ?a) == ""
assert String.rstrip("]]]]]]]]]]", ?]) == ""
assert String.rstrip(" cat 猫猫", ?猫) == " cat "
# information separators are not whitespace
assert String.rstrip("a abc a \u001F") == "a abc a \u001F"
# no-break space
assert String.rstrip("a abc a \u00A0") == "a abc a"
end
test "lstrip" do
@@ -181,10 +202,13 @@ defmodule StringTest do
assert String.lstrip("a abc a") == "a abc a"
assert String.lstrip("\n\na abc a") == "a abc a"
assert String.lstrip("\t\n\v\f\r\sa abc a") == "a abc a"
assert String.lstrip(<<31>> <> " a abc a") == "a abc a"
assert String.lstrip(<<194, 133>> <> "a abc a") == "a abc a"
assert String.lstrip("__ abc _", ?_) == " abc _"
assert String.lstrip("猫猫 cat ", ?猫) == " cat "
# information separators are not whitespace
assert String.lstrip("\u001F a abc a") == <<31>> <> " a abc a"
# no-break space
assert String.lstrip("\u00A0 a abc a") == "a abc a"
end
test "strip" do
@@ -194,6 +218,10 @@ defmodule StringTest do
assert String.strip("a abc a\t\n\v\f\r\s") == "a abc a"
assert String.strip("___ abc ___", ?_) == " abc "
assert String.strip("猫猫猫 cat 猫猫猫", ?猫) == " cat "
# no-break space
assert String.strip("\u00A0a abc a\u00A0") == "a abc a"
# whitespace defined as a range
assert String.strip("\u2008a abc a\u2005") == "a abc a"
end
test "rjust" do
@@ -285,12 +313,43 @@ defmodule StringTest do
end
test "normalize" do
assert String.normalize("ḇravô", :nfd) == "ḇravô"
assert String.normalize("ŝ", :nfd) == "ŝ"
assert String.normalize("ḇravô", :nfd) == "ḇravô"
assert String.normalize("ṩierra", :nfd) == "ṩierra"
assert String.normalize("뢴", :nfd) == "뢴"
assert String.normalize("êchǭ", :nfc) == "êchǭ"
assert String.normalize("거̄", :nfc) == "거̄"
assert String.normalize("뢴", :nfc) == "뢴"
## Cases from NormalizationTest.txt
# 05B8 05B9 05B1 0591 05C3 05B0 05AC 059F
# 05B1 05B8 05B9 0591 05C3 05B0 05AC 059F
# HEBREW POINT QAMATS, HEBREW POINT HOLAM, HEBREW POINT HATAF SEGOL,
# HEBREW ACCENT ETNAHTA, HEBREW PUNCTUATION SOF PASUQ, HEBREW POINT SHEVA,
# HEBREW ACCENT ILUY, HEBREW ACCENT QARNEY PARA
assert String.normalize("ֱָֹ֑׃ְ֬֟", :nfc) == "ֱָֹ֑׃ְ֬֟"
# 095D (exclusion list)
# 0922 093C
# DEVANAGARI LETTER RHA
assert String.normalize("ढ़", :nfc) == "ढ़"
# 0061 0315 0300 05AE 0340 0062
# 00E0 05AE 0300 0315 0062
# LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT,
# HEBREW ACCENT ZINOR, COMBINING GRAVE TONE MARK, LATIN SMALL LETTER B
assert String.normalize("à֮̀̕b", :nfc) == "à֮̀̕b"
# 0344
# 0308 0301
# COMBINING GREEK DIALYTIKA TONOS
assert String.normalize("\u0344", :nfc) == "\u0308\u0301"
# 115B9 0334 115AF
# 115B9 0334 115AF
# SIDDHAM VOWEL SIGN AI, COMBINING TILDE OVERLAY, SIDDHAM VOWEL SIGN AA
assert String.normalize("𑖹̴𑖯", :nfc) == "𑖹̴𑖯"
end
test "graphemes" do
+1
View File
@@ -60,6 +60,7 @@ defmodule VersionTest do
test "parse" do
assert {:ok, %V{major: 1, minor: 2, patch: 3}} = V.parse("1.2.3")
assert {:ok, %V{major: 1, minor: 4, patch: 5}} = V.parse("1.4.5+ignore")
assert {:ok, %V{major: 0, minor: 0, patch: 1}} = V.parse("0.0.1+sha.0702245")
assert {:ok, %V{major: 1, minor: 4, patch: 5, pre: ["6-g3318bd5"]}} = V.parse("1.4.5-6-g3318bd5")
assert {:ok, %V{major: 1, minor: 4, patch: 5, pre: [6, 7, "eight"]}} = V.parse("1.4.5-6.7.eight")
assert {:ok, %V{major: 1, minor: 4, patch: 5, pre: ["6-g3318bd5"]}} = V.parse("1.4.5-6-g3318bd5+ignore")
-745
View File
@@ -1,745 +0,0 @@
0300;230;
0301;230;
0302;230;
0303;230;
0304;230;
0305;230;
0306;230;
0307;230;
0308;230;
0309;230;
030A;230;
030B;230;
030C;230;
030D;230;
030E;230;
030F;230;
0310;230;
0311;230;
0312;230;
0313;230;
0314;230;
0315;232;
0316;220;
0317;220;
0318;220;
0319;220;
031A;232;
031B;216;
031C;220;
031D;220;
031E;220;
031F;220;
0320;220;
0321;202;
0322;202;
0323;220;
0324;220;
0325;220;
0326;220;
0327;202;
0328;202;
0329;220;
032A;220;
032B;220;
032C;220;
032D;220;
032E;220;
032F;220;
0330;220;
0331;220;
0332;220;
0333;220;
0334;1;
0335;1;
0336;1;
0337;1;
0338;1;
0339;220;
033A;220;
033B;220;
033C;220;
033D;230;
033E;230;
033F;230;
0340;230;
0341;230;
0342;230;
0343;230;
0344;230;
0345;240;
0346;230;
0347;220;
0348;220;
0349;220;
034A;230;
034B;230;
034C;230;
034D;220;
034E;220;
0350;230;
0351;230;
0352;230;
0353;220;
0354;220;
0355;220;
0356;220;
0357;230;
0358;232;
0359;220;
035A;220;
035B;230;
035C;233;
035D;234;
035E;234;
035F;233;
0360;234;
0361;234;
0362;233;
0363;230;
0364;230;
0365;230;
0366;230;
0367;230;
0368;230;
0369;230;
036A;230;
036B;230;
036C;230;
036D;230;
036E;230;
036F;230;
0483;230;
0484;230;
0485;230;
0486;230;
0487;230;
0591;220;
0592;230;
0593;230;
0594;230;
0595;230;
0596;220;
0597;230;
0598;230;
0599;230;
059A;222;
059B;220;
059C;230;
059D;230;
059E;230;
059F;230;
05A0;230;
05A1;230;
05A2;220;
05A3;220;
05A4;220;
05A5;220;
05A6;220;
05A7;220;
05A8;230;
05A9;230;
05AA;220;
05AB;230;
05AC;230;
05AD;222;
05AE;228;
05AF;230;
05B0;10;
05B1;11;
05B2;12;
05B3;13;
05B4;14;
05B5;15;
05B6;16;
05B7;17;
05B8;18;
05B9;19;
05BA;19;
05BB;20;
05BC;21;
05BD;22;
05BF;23;
05C1;24;
05C2;25;
05C4;230;
05C5;220;
05C7;18;
0610;230;
0611;230;
0612;230;
0613;230;
0614;230;
0615;230;
0616;230;
0617;230;
0618;30;
0619;31;
061A;32;
064B;27;
064C;28;
064D;29;
064E;30;
064F;31;
0650;32;
0651;33;
0652;34;
0653;230;
0654;230;
0655;220;
0656;220;
0657;230;
0658;230;
0659;230;
065A;230;
065B;230;
065C;220;
065D;230;
065E;230;
065F;220;
0670;35;
06D6;230;
06D7;230;
06D8;230;
06D9;230;
06DA;230;
06DB;230;
06DC;230;
06DF;230;
06E0;230;
06E1;230;
06E2;230;
06E3;220;
06E4;230;
06E7;230;
06E8;230;
06EA;220;
06EB;230;
06EC;230;
06ED;220;
0711;36;
0730;230;
0731;220;
0732;230;
0733;230;
0734;220;
0735;230;
0736;230;
0737;220;
0738;220;
0739;220;
073A;230;
073B;220;
073C;220;
073D;230;
073E;220;
073F;230;
0740;230;
0741;230;
0742;220;
0743;230;
0744;220;
0745;230;
0746;220;
0747;230;
0748;220;
0749;230;
074A;230;
07EB;230;
07EC;230;
07ED;230;
07EE;230;
07EF;230;
07F0;230;
07F1;230;
07F2;220;
07F3;230;
0816;230;
0817;230;
0818;230;
0819;230;
081B;230;
081C;230;
081D;230;
081E;230;
081F;230;
0820;230;
0821;230;
0822;230;
0823;230;
0825;230;
0826;230;
0827;230;
0829;230;
082A;230;
082B;230;
082C;230;
082D;230;
0859;220;
085A;220;
085B;220;
08E4;230;
08E5;230;
08E6;220;
08E7;230;
08E8;230;
08E9;220;
08EA;230;
08EB;230;
08EC;230;
08ED;220;
08EE;220;
08EF;220;
08F0;27;
08F1;28;
08F2;29;
08F3;230;
08F4;230;
08F5;230;
08F6;220;
08F7;230;
08F8;230;
08F9;220;
08FA;220;
08FB;230;
08FC;230;
08FD;230;
08FE;230;
08FF;230;
093C;7;
094D;9;
0951;230;
0952;220;
0953;230;
0954;230;
09BC;7;
09CD;9;
0A3C;7;
0A4D;9;
0ABC;7;
0ACD;9;
0B3C;7;
0B4D;9;
0BCD;9;
0C4D;9;
0C55;84;
0C56;91;
0CBC;7;
0CCD;9;
0D4D;9;
0DCA;9;
0E38;103;
0E39;103;
0E3A;9;
0E48;107;
0E49;107;
0E4A;107;
0E4B;107;
0EB8;118;
0EB9;118;
0EC8;122;
0EC9;122;
0ECA;122;
0ECB;122;
0F18;220;
0F19;220;
0F35;220;
0F37;220;
0F39;216;
0F71;129;
0F72;130;
0F74;132;
0F7A;130;
0F7B;130;
0F7C;130;
0F7D;130;
0F80;130;
0F82;230;
0F83;230;
0F84;9;
0F86;230;
0F87;230;
0FC6;220;
1037;7;
1039;9;
103A;9;
108D;220;
135D;230;
135E;230;
135F;230;
1714;9;
1734;9;
17D2;9;
17DD;230;
18A9;228;
1939;222;
193A;230;
193B;220;
1A17;230;
1A18;220;
1A60;9;
1A75;230;
1A76;230;
1A77;230;
1A78;230;
1A79;230;
1A7A;230;
1A7B;230;
1A7C;230;
1A7F;220;
1AB0;230;
1AB1;230;
1AB2;230;
1AB3;230;
1AB4;230;
1AB5;220;
1AB6;220;
1AB7;220;
1AB8;220;
1AB9;220;
1ABA;220;
1ABB;230;
1ABC;230;
1ABD;220;
1B34;7;
1B44;9;
1B6B;230;
1B6C;220;
1B6D;230;
1B6E;230;
1B6F;230;
1B70;230;
1B71;230;
1B72;230;
1B73;230;
1BAA;9;
1BAB;9;
1BE6;7;
1BF2;9;
1BF3;9;
1C37;7;
1CD0;230;
1CD1;230;
1CD2;230;
1CD4;1;
1CD5;220;
1CD6;220;
1CD7;220;
1CD8;220;
1CD9;220;
1CDA;230;
1CDB;230;
1CDC;220;
1CDD;220;
1CDE;220;
1CDF;220;
1CE0;230;
1CE2;1;
1CE3;1;
1CE4;1;
1CE5;1;
1CE6;1;
1CE7;1;
1CE8;1;
1CED;220;
1CF4;230;
1CF8;230;
1CF9;230;
1DC0;230;
1DC1;230;
1DC2;220;
1DC3;230;
1DC4;230;
1DC5;230;
1DC6;230;
1DC7;230;
1DC8;230;
1DC9;230;
1DCA;220;
1DCB;230;
1DCC;230;
1DCD;234;
1DCE;214;
1DCF;220;
1DD0;202;
1DD1;230;
1DD2;230;
1DD3;230;
1DD4;230;
1DD5;230;
1DD6;230;
1DD7;230;
1DD8;230;
1DD9;230;
1DDA;230;
1DDB;230;
1DDC;230;
1DDD;230;
1DDE;230;
1DDF;230;
1DE0;230;
1DE1;230;
1DE2;230;
1DE3;230;
1DE4;230;
1DE5;230;
1DE6;230;
1DE7;230;
1DE8;230;
1DE9;230;
1DEA;230;
1DEB;230;
1DEC;230;
1DED;230;
1DEE;230;
1DEF;230;
1DF0;230;
1DF1;230;
1DF2;230;
1DF3;230;
1DF4;230;
1DF5;230;
1DFC;233;
1DFD;220;
1DFE;230;
1DFF;220;
20D0;230;
20D1;230;
20D2;1;
20D3;1;
20D4;230;
20D5;230;
20D6;230;
20D7;230;
20D8;1;
20D9;1;
20DA;1;
20DB;230;
20DC;230;
20E1;230;
20E5;1;
20E6;1;
20E7;230;
20E8;220;
20E9;230;
20EA;1;
20EB;1;
20EC;220;
20ED;220;
20EE;220;
20EF;220;
20F0;230;
2CEF;230;
2CF0;230;
2CF1;230;
2D7F;9;
2DE0;230;
2DE1;230;
2DE2;230;
2DE3;230;
2DE4;230;
2DE5;230;
2DE6;230;
2DE7;230;
2DE8;230;
2DE9;230;
2DEA;230;
2DEB;230;
2DEC;230;
2DED;230;
2DEE;230;
2DEF;230;
2DF0;230;
2DF1;230;
2DF2;230;
2DF3;230;
2DF4;230;
2DF5;230;
2DF6;230;
2DF7;230;
2DF8;230;
2DF9;230;
2DFA;230;
2DFB;230;
2DFC;230;
2DFD;230;
2DFE;230;
2DFF;230;
302A;218;
302B;228;
302C;232;
302D;222;
302E;224;
302F;224;
3099;8;
309A;8;
A66F;230;
A674;230;
A675;230;
A676;230;
A677;230;
A678;230;
A679;230;
A67A;230;
A67B;230;
A67C;230;
A67D;230;
A69F;230;
A6F0;230;
A6F1;230;
A806;9;
A8C4;9;
A8E0;230;
A8E1;230;
A8E2;230;
A8E3;230;
A8E4;230;
A8E5;230;
A8E6;230;
A8E7;230;
A8E8;230;
A8E9;230;
A8EA;230;
A8EB;230;
A8EC;230;
A8ED;230;
A8EE;230;
A8EF;230;
A8F0;230;
A8F1;230;
A92B;220;
A92C;220;
A92D;220;
A953;9;
A9B3;7;
A9C0;9;
AAB0;230;
AAB2;230;
AAB3;230;
AAB4;220;
AAB7;230;
AAB8;230;
AABE;230;
AABF;230;
AAC1;230;
AAF6;9;
ABED;9;
FB1E;26;
FE20;230;
FE21;230;
FE22;230;
FE23;230;
FE24;230;
FE25;230;
FE26;230;
FE27;220;
FE28;220;
FE29;220;
FE2A;220;
FE2B;220;
FE2C;220;
FE2D;220;
101FD;220;
102E0;220;
10376;230;
10377;230;
10378;230;
10379;230;
1037A;230;
10A0D;220;
10A0F;230;
10A38;230;
10A39;1;
10A3A;220;
10A3F;9;
10AE5;230;
10AE6;220;
11046;9;
1107F;9;
110B9;9;
110BA;7;
11100;230;
11101;230;
11102;230;
11133;9;
11134;9;
11173;7;
111C0;9;
11235;9;
11236;7;
112E9;7;
112EA;9;
1133C;7;
1134D;9;
11366;230;
11367;230;
11368;230;
11369;230;
1136A;230;
1136B;230;
1136C;230;
11370;230;
11371;230;
11372;230;
11373;230;
11374;230;
114C2;9;
114C3;7;
115BF;9;
115C0;7;
1163F;9;
116B6;9;
116B7;7;
16AF0;1;
16AF1;1;
16AF2;1;
16AF3;1;
16AF4;1;
16B30;230;
16B31;230;
16B32;230;
16B33;230;
16B34;230;
16B35;230;
16B36;230;
1BC9E;1;
1D165;216;
1D166;216;
1D167;1;
1D168;1;
1D169;1;
1D16D;226;
1D16E;216;
1D16F;216;
1D170;216;
1D171;216;
1D172;216;
1D17B;220;
1D17C;220;
1D17D;220;
1D17E;220;
1D17F;220;
1D180;220;
1D181;220;
1D182;220;
1D185;230;
1D186;230;
1D187;230;
1D188;230;
1D189;230;
1D18A;220;
1D18B;220;
1D1AA;230;
1D1AB;230;
1D1AC;230;
1D1AD;230;
1D242;230;
1D243;230;
1D244;230;
1E8D0;220;
1E8D1;220;
1E8D2;220;
1E8D3;220;
1E8D4;220;
1E8D5;220;
1E8D6;220;
-940
View File
@@ -1,940 +0,0 @@
0041;0300;00C0;
0041;0301;00C1;
0041;0302;00C2;
0041;0303;00C3;
0041;0308;00C4;
0041;030A;00C5;
0043;0327;00C7;
0045;0300;00C8;
0045;0301;00C9;
0045;0302;00CA;
0045;0308;00CB;
0049;0300;00CC;
0049;0301;00CD;
0049;0302;00CE;
0049;0308;00CF;
004E;0303;00D1;
004F;0300;00D2;
004F;0301;00D3;
004F;0302;00D4;
004F;0303;00D5;
004F;0308;00D6;
0055;0300;00D9;
0055;0301;00DA;
0055;0302;00DB;
0055;0308;00DC;
0059;0301;00DD;
0061;0300;00E0;
0061;0301;00E1;
0061;0302;00E2;
0061;0303;00E3;
0061;0308;00E4;
0061;030A;00E5;
0063;0327;00E7;
0065;0300;00E8;
0065;0301;00E9;
0065;0302;00EA;
0065;0308;00EB;
0069;0300;00EC;
0069;0301;00ED;
0069;0302;00EE;
0069;0308;00EF;
006E;0303;00F1;
006F;0300;00F2;
006F;0301;00F3;
006F;0302;00F4;
006F;0303;00F5;
006F;0308;00F6;
0075;0300;00F9;
0075;0301;00FA;
0075;0302;00FB;
0075;0308;00FC;
0079;0301;00FD;
0079;0308;00FF;
0041;0304;0100;
0061;0304;0101;
0041;0306;0102;
0061;0306;0103;
0041;0328;0104;
0061;0328;0105;
0043;0301;0106;
0063;0301;0107;
0043;0302;0108;
0063;0302;0109;
0043;0307;010A;
0063;0307;010B;
0043;030C;010C;
0063;030C;010D;
0044;030C;010E;
0064;030C;010F;
0045;0304;0112;
0065;0304;0113;
0045;0306;0114;
0065;0306;0115;
0045;0307;0116;
0065;0307;0117;
0045;0328;0118;
0065;0328;0119;
0045;030C;011A;
0065;030C;011B;
0047;0302;011C;
0067;0302;011D;
0047;0306;011E;
0067;0306;011F;
0047;0307;0120;
0067;0307;0121;
0047;0327;0122;
0067;0327;0123;
0048;0302;0124;
0068;0302;0125;
0049;0303;0128;
0069;0303;0129;
0049;0304;012A;
0069;0304;012B;
0049;0306;012C;
0069;0306;012D;
0049;0328;012E;
0069;0328;012F;
0049;0307;0130;
004A;0302;0134;
006A;0302;0135;
004B;0327;0136;
006B;0327;0137;
004C;0301;0139;
006C;0301;013A;
004C;0327;013B;
006C;0327;013C;
004C;030C;013D;
006C;030C;013E;
004E;0301;0143;
006E;0301;0144;
004E;0327;0145;
006E;0327;0146;
004E;030C;0147;
006E;030C;0148;
004F;0304;014C;
006F;0304;014D;
004F;0306;014E;
006F;0306;014F;
004F;030B;0150;
006F;030B;0151;
0052;0301;0154;
0072;0301;0155;
0052;0327;0156;
0072;0327;0157;
0052;030C;0158;
0072;030C;0159;
0053;0301;015A;
0073;0301;015B;
0053;0302;015C;
0073;0302;015D;
0053;0327;015E;
0073;0327;015F;
0053;030C;0160;
0073;030C;0161;
0054;0327;0162;
0074;0327;0163;
0054;030C;0164;
0074;030C;0165;
0055;0303;0168;
0075;0303;0169;
0055;0304;016A;
0075;0304;016B;
0055;0306;016C;
0075;0306;016D;
0055;030A;016E;
0075;030A;016F;
0055;030B;0170;
0075;030B;0171;
0055;0328;0172;
0075;0328;0173;
0057;0302;0174;
0077;0302;0175;
0059;0302;0176;
0079;0302;0177;
0059;0308;0178;
005A;0301;0179;
007A;0301;017A;
005A;0307;017B;
007A;0307;017C;
005A;030C;017D;
007A;030C;017E;
004F;031B;01A0;
006F;031B;01A1;
0055;031B;01AF;
0075;031B;01B0;
0041;030C;01CD;
0061;030C;01CE;
0049;030C;01CF;
0069;030C;01D0;
004F;030C;01D1;
006F;030C;01D2;
0055;030C;01D3;
0075;030C;01D4;
00DC;0304;01D5;
00FC;0304;01D6;
00DC;0301;01D7;
00FC;0301;01D8;
00DC;030C;01D9;
00FC;030C;01DA;
00DC;0300;01DB;
00FC;0300;01DC;
00C4;0304;01DE;
00E4;0304;01DF;
0226;0304;01E0;
0227;0304;01E1;
00C6;0304;01E2;
00E6;0304;01E3;
0047;030C;01E6;
0067;030C;01E7;
004B;030C;01E8;
006B;030C;01E9;
004F;0328;01EA;
006F;0328;01EB;
01EA;0304;01EC;
01EB;0304;01ED;
01B7;030C;01EE;
0292;030C;01EF;
006A;030C;01F0;
0047;0301;01F4;
0067;0301;01F5;
004E;0300;01F8;
006E;0300;01F9;
00C5;0301;01FA;
00E5;0301;01FB;
00C6;0301;01FC;
00E6;0301;01FD;
00D8;0301;01FE;
00F8;0301;01FF;
0041;030F;0200;
0061;030F;0201;
0041;0311;0202;
0061;0311;0203;
0045;030F;0204;
0065;030F;0205;
0045;0311;0206;
0065;0311;0207;
0049;030F;0208;
0069;030F;0209;
0049;0311;020A;
0069;0311;020B;
004F;030F;020C;
006F;030F;020D;
004F;0311;020E;
006F;0311;020F;
0052;030F;0210;
0072;030F;0211;
0052;0311;0212;
0072;0311;0213;
0055;030F;0214;
0075;030F;0215;
0055;0311;0216;
0075;0311;0217;
0053;0326;0218;
0073;0326;0219;
0054;0326;021A;
0074;0326;021B;
0048;030C;021E;
0068;030C;021F;
0041;0307;0226;
0061;0307;0227;
0045;0327;0228;
0065;0327;0229;
00D6;0304;022A;
00F6;0304;022B;
00D5;0304;022C;
00F5;0304;022D;
004F;0307;022E;
006F;0307;022F;
022E;0304;0230;
022F;0304;0231;
0059;0304;0232;
0079;0304;0233;
00A8;0301;0385;
0391;0301;0386;
0395;0301;0388;
0397;0301;0389;
0399;0301;038A;
039F;0301;038C;
03A5;0301;038E;
03A9;0301;038F;
03CA;0301;0390;
0399;0308;03AA;
03A5;0308;03AB;
03B1;0301;03AC;
03B5;0301;03AD;
03B7;0301;03AE;
03B9;0301;03AF;
03CB;0301;03B0;
03B9;0308;03CA;
03C5;0308;03CB;
03BF;0301;03CC;
03C5;0301;03CD;
03C9;0301;03CE;
03D2;0301;03D3;
03D2;0308;03D4;
0415;0300;0400;
0415;0308;0401;
0413;0301;0403;
0406;0308;0407;
041A;0301;040C;
0418;0300;040D;
0423;0306;040E;
0418;0306;0419;
0438;0306;0439;
0435;0300;0450;
0435;0308;0451;
0433;0301;0453;
0456;0308;0457;
043A;0301;045C;
0438;0300;045D;
0443;0306;045E;
0474;030F;0476;
0475;030F;0477;
0416;0306;04C1;
0436;0306;04C2;
0410;0306;04D0;
0430;0306;04D1;
0410;0308;04D2;
0430;0308;04D3;
0415;0306;04D6;
0435;0306;04D7;
04D8;0308;04DA;
04D9;0308;04DB;
0416;0308;04DC;
0436;0308;04DD;
0417;0308;04DE;
0437;0308;04DF;
0418;0304;04E2;
0438;0304;04E3;
0418;0308;04E4;
0438;0308;04E5;
041E;0308;04E6;
043E;0308;04E7;
04E8;0308;04EA;
04E9;0308;04EB;
042D;0308;04EC;
044D;0308;04ED;
0423;0304;04EE;
0443;0304;04EF;
0423;0308;04F0;
0443;0308;04F1;
0423;030B;04F2;
0443;030B;04F3;
0427;0308;04F4;
0447;0308;04F5;
042B;0308;04F8;
044B;0308;04F9;
0627;0653;0622;
0627;0654;0623;
0648;0654;0624;
0627;0655;0625;
064A;0654;0626;
06D5;0654;06C0;
06C1;0654;06C2;
06D2;0654;06D3;
0928;093C;0929;
0930;093C;0931;
0933;093C;0934;
09C7;09BE;09CB;
09C7;09D7;09CC;
0B47;0B56;0B48;
0B47;0B3E;0B4B;
0B47;0B57;0B4C;
0B92;0BD7;0B94;
0BC6;0BBE;0BCA;
0BC7;0BBE;0BCB;
0BC6;0BD7;0BCC;
0C46;0C56;0C48;
0CBF;0CD5;0CC0;
0CC6;0CD5;0CC7;
0CC6;0CD6;0CC8;
0CC6;0CC2;0CCA;
0CCA;0CD5;0CCB;
0D46;0D3E;0D4A;
0D47;0D3E;0D4B;
0D46;0D57;0D4C;
0DD9;0DCA;0DDA;
0DD9;0DCF;0DDC;
0DDC;0DCA;0DDD;
0DD9;0DDF;0DDE;
1025;102E;1026;
1B05;1B35;1B06;
1B07;1B35;1B08;
1B09;1B35;1B0A;
1B0B;1B35;1B0C;
1B0D;1B35;1B0E;
1B11;1B35;1B12;
1B3A;1B35;1B3B;
1B3C;1B35;1B3D;
1B3E;1B35;1B40;
1B3F;1B35;1B41;
1B42;1B35;1B43;
0041;0325;1E00;
0061;0325;1E01;
0042;0307;1E02;
0062;0307;1E03;
0042;0323;1E04;
0062;0323;1E05;
0042;0331;1E06;
0062;0331;1E07;
00C7;0301;1E08;
00E7;0301;1E09;
0044;0307;1E0A;
0064;0307;1E0B;
0044;0323;1E0C;
0064;0323;1E0D;
0044;0331;1E0E;
0064;0331;1E0F;
0044;0327;1E10;
0064;0327;1E11;
0044;032D;1E12;
0064;032D;1E13;
0112;0300;1E14;
0113;0300;1E15;
0112;0301;1E16;
0113;0301;1E17;
0045;032D;1E18;
0065;032D;1E19;
0045;0330;1E1A;
0065;0330;1E1B;
0228;0306;1E1C;
0229;0306;1E1D;
0046;0307;1E1E;
0066;0307;1E1F;
0047;0304;1E20;
0067;0304;1E21;
0048;0307;1E22;
0068;0307;1E23;
0048;0323;1E24;
0068;0323;1E25;
0048;0308;1E26;
0068;0308;1E27;
0048;0327;1E28;
0068;0327;1E29;
0048;032E;1E2A;
0068;032E;1E2B;
0049;0330;1E2C;
0069;0330;1E2D;
00CF;0301;1E2E;
00EF;0301;1E2F;
004B;0301;1E30;
006B;0301;1E31;
004B;0323;1E32;
006B;0323;1E33;
004B;0331;1E34;
006B;0331;1E35;
004C;0323;1E36;
006C;0323;1E37;
1E36;0304;1E38;
1E37;0304;1E39;
004C;0331;1E3A;
006C;0331;1E3B;
004C;032D;1E3C;
006C;032D;1E3D;
004D;0301;1E3E;
006D;0301;1E3F;
004D;0307;1E40;
006D;0307;1E41;
004D;0323;1E42;
006D;0323;1E43;
004E;0307;1E44;
006E;0307;1E45;
004E;0323;1E46;
006E;0323;1E47;
004E;0331;1E48;
006E;0331;1E49;
004E;032D;1E4A;
006E;032D;1E4B;
00D5;0301;1E4C;
00F5;0301;1E4D;
00D5;0308;1E4E;
00F5;0308;1E4F;
014C;0300;1E50;
014D;0300;1E51;
014C;0301;1E52;
014D;0301;1E53;
0050;0301;1E54;
0070;0301;1E55;
0050;0307;1E56;
0070;0307;1E57;
0052;0307;1E58;
0072;0307;1E59;
0052;0323;1E5A;
0072;0323;1E5B;
1E5A;0304;1E5C;
1E5B;0304;1E5D;
0052;0331;1E5E;
0072;0331;1E5F;
0053;0307;1E60;
0073;0307;1E61;
0053;0323;1E62;
0073;0323;1E63;
015A;0307;1E64;
015B;0307;1E65;
0160;0307;1E66;
0161;0307;1E67;
1E62;0307;1E68;
1E63;0307;1E69;
0054;0307;1E6A;
0074;0307;1E6B;
0054;0323;1E6C;
0074;0323;1E6D;
0054;0331;1E6E;
0074;0331;1E6F;
0054;032D;1E70;
0074;032D;1E71;
0055;0324;1E72;
0075;0324;1E73;
0055;0330;1E74;
0075;0330;1E75;
0055;032D;1E76;
0075;032D;1E77;
0168;0301;1E78;
0169;0301;1E79;
016A;0308;1E7A;
016B;0308;1E7B;
0056;0303;1E7C;
0076;0303;1E7D;
0056;0323;1E7E;
0076;0323;1E7F;
0057;0300;1E80;
0077;0300;1E81;
0057;0301;1E82;
0077;0301;1E83;
0057;0308;1E84;
0077;0308;1E85;
0057;0307;1E86;
0077;0307;1E87;
0057;0323;1E88;
0077;0323;1E89;
0058;0307;1E8A;
0078;0307;1E8B;
0058;0308;1E8C;
0078;0308;1E8D;
0059;0307;1E8E;
0079;0307;1E8F;
005A;0302;1E90;
007A;0302;1E91;
005A;0323;1E92;
007A;0323;1E93;
005A;0331;1E94;
007A;0331;1E95;
0068;0331;1E96;
0074;0308;1E97;
0077;030A;1E98;
0079;030A;1E99;
017F;0307;1E9B;
0041;0323;1EA0;
0061;0323;1EA1;
0041;0309;1EA2;
0061;0309;1EA3;
00C2;0301;1EA4;
00E2;0301;1EA5;
00C2;0300;1EA6;
00E2;0300;1EA7;
00C2;0309;1EA8;
00E2;0309;1EA9;
00C2;0303;1EAA;
00E2;0303;1EAB;
1EA0;0302;1EAC;
1EA1;0302;1EAD;
0102;0301;1EAE;
0103;0301;1EAF;
0102;0300;1EB0;
0103;0300;1EB1;
0102;0309;1EB2;
0103;0309;1EB3;
0102;0303;1EB4;
0103;0303;1EB5;
1EA0;0306;1EB6;
1EA1;0306;1EB7;
0045;0323;1EB8;
0065;0323;1EB9;
0045;0309;1EBA;
0065;0309;1EBB;
0045;0303;1EBC;
0065;0303;1EBD;
00CA;0301;1EBE;
00EA;0301;1EBF;
00CA;0300;1EC0;
00EA;0300;1EC1;
00CA;0309;1EC2;
00EA;0309;1EC3;
00CA;0303;1EC4;
00EA;0303;1EC5;
1EB8;0302;1EC6;
1EB9;0302;1EC7;
0049;0309;1EC8;
0069;0309;1EC9;
0049;0323;1ECA;
0069;0323;1ECB;
004F;0323;1ECC;
006F;0323;1ECD;
004F;0309;1ECE;
006F;0309;1ECF;
00D4;0301;1ED0;
00F4;0301;1ED1;
00D4;0300;1ED2;
00F4;0300;1ED3;
00D4;0309;1ED4;
00F4;0309;1ED5;
00D4;0303;1ED6;
00F4;0303;1ED7;
1ECC;0302;1ED8;
1ECD;0302;1ED9;
01A0;0301;1EDA;
01A1;0301;1EDB;
01A0;0300;1EDC;
01A1;0300;1EDD;
01A0;0309;1EDE;
01A1;0309;1EDF;
01A0;0303;1EE0;
01A1;0303;1EE1;
01A0;0323;1EE2;
01A1;0323;1EE3;
0055;0323;1EE4;
0075;0323;1EE5;
0055;0309;1EE6;
0075;0309;1EE7;
01AF;0301;1EE8;
01B0;0301;1EE9;
01AF;0300;1EEA;
01B0;0300;1EEB;
01AF;0309;1EEC;
01B0;0309;1EED;
01AF;0303;1EEE;
01B0;0303;1EEF;
01AF;0323;1EF0;
01B0;0323;1EF1;
0059;0300;1EF2;
0079;0300;1EF3;
0059;0323;1EF4;
0079;0323;1EF5;
0059;0309;1EF6;
0079;0309;1EF7;
0059;0303;1EF8;
0079;0303;1EF9;
03B1;0313;1F00;
03B1;0314;1F01;
1F00;0300;1F02;
1F01;0300;1F03;
1F00;0301;1F04;
1F01;0301;1F05;
1F00;0342;1F06;
1F01;0342;1F07;
0391;0313;1F08;
0391;0314;1F09;
1F08;0300;1F0A;
1F09;0300;1F0B;
1F08;0301;1F0C;
1F09;0301;1F0D;
1F08;0342;1F0E;
1F09;0342;1F0F;
03B5;0313;1F10;
03B5;0314;1F11;
1F10;0300;1F12;
1F11;0300;1F13;
1F10;0301;1F14;
1F11;0301;1F15;
0395;0313;1F18;
0395;0314;1F19;
1F18;0300;1F1A;
1F19;0300;1F1B;
1F18;0301;1F1C;
1F19;0301;1F1D;
03B7;0313;1F20;
03B7;0314;1F21;
1F20;0300;1F22;
1F21;0300;1F23;
1F20;0301;1F24;
1F21;0301;1F25;
1F20;0342;1F26;
1F21;0342;1F27;
0397;0313;1F28;
0397;0314;1F29;
1F28;0300;1F2A;
1F29;0300;1F2B;
1F28;0301;1F2C;
1F29;0301;1F2D;
1F28;0342;1F2E;
1F29;0342;1F2F;
03B9;0313;1F30;
03B9;0314;1F31;
1F30;0300;1F32;
1F31;0300;1F33;
1F30;0301;1F34;
1F31;0301;1F35;
1F30;0342;1F36;
1F31;0342;1F37;
0399;0313;1F38;
0399;0314;1F39;
1F38;0300;1F3A;
1F39;0300;1F3B;
1F38;0301;1F3C;
1F39;0301;1F3D;
1F38;0342;1F3E;
1F39;0342;1F3F;
03BF;0313;1F40;
03BF;0314;1F41;
1F40;0300;1F42;
1F41;0300;1F43;
1F40;0301;1F44;
1F41;0301;1F45;
039F;0313;1F48;
039F;0314;1F49;
1F48;0300;1F4A;
1F49;0300;1F4B;
1F48;0301;1F4C;
1F49;0301;1F4D;
03C5;0313;1F50;
03C5;0314;1F51;
1F50;0300;1F52;
1F51;0300;1F53;
1F50;0301;1F54;
1F51;0301;1F55;
1F50;0342;1F56;
1F51;0342;1F57;
03A5;0314;1F59;
1F59;0300;1F5B;
1F59;0301;1F5D;
1F59;0342;1F5F;
03C9;0313;1F60;
03C9;0314;1F61;
1F60;0300;1F62;
1F61;0300;1F63;
1F60;0301;1F64;
1F61;0301;1F65;
1F60;0342;1F66;
1F61;0342;1F67;
03A9;0313;1F68;
03A9;0314;1F69;
1F68;0300;1F6A;
1F69;0300;1F6B;
1F68;0301;1F6C;
1F69;0301;1F6D;
1F68;0342;1F6E;
1F69;0342;1F6F;
03B1;0300;1F70;
03B5;0300;1F72;
03B7;0300;1F74;
03B9;0300;1F76;
03BF;0300;1F78;
03C5;0300;1F7A;
03C9;0300;1F7C;
1F00;0345;1F80;
1F01;0345;1F81;
1F02;0345;1F82;
1F03;0345;1F83;
1F04;0345;1F84;
1F05;0345;1F85;
1F06;0345;1F86;
1F07;0345;1F87;
1F08;0345;1F88;
1F09;0345;1F89;
1F0A;0345;1F8A;
1F0B;0345;1F8B;
1F0C;0345;1F8C;
1F0D;0345;1F8D;
1F0E;0345;1F8E;
1F0F;0345;1F8F;
1F20;0345;1F90;
1F21;0345;1F91;
1F22;0345;1F92;
1F23;0345;1F93;
1F24;0345;1F94;
1F25;0345;1F95;
1F26;0345;1F96;
1F27;0345;1F97;
1F28;0345;1F98;
1F29;0345;1F99;
1F2A;0345;1F9A;
1F2B;0345;1F9B;
1F2C;0345;1F9C;
1F2D;0345;1F9D;
1F2E;0345;1F9E;
1F2F;0345;1F9F;
1F60;0345;1FA0;
1F61;0345;1FA1;
1F62;0345;1FA2;
1F63;0345;1FA3;
1F64;0345;1FA4;
1F65;0345;1FA5;
1F66;0345;1FA6;
1F67;0345;1FA7;
1F68;0345;1FA8;
1F69;0345;1FA9;
1F6A;0345;1FAA;
1F6B;0345;1FAB;
1F6C;0345;1FAC;
1F6D;0345;1FAD;
1F6E;0345;1FAE;
1F6F;0345;1FAF;
03B1;0306;1FB0;
03B1;0304;1FB1;
1F70;0345;1FB2;
03B1;0345;1FB3;
03AC;0345;1FB4;
03B1;0342;1FB6;
1FB6;0345;1FB7;
0391;0306;1FB8;
0391;0304;1FB9;
0391;0300;1FBA;
0391;0345;1FBC;
00A8;0342;1FC1;
1F74;0345;1FC2;
03B7;0345;1FC3;
03AE;0345;1FC4;
03B7;0342;1FC6;
1FC6;0345;1FC7;
0395;0300;1FC8;
0397;0300;1FCA;
0397;0345;1FCC;
1FBF;0300;1FCD;
1FBF;0301;1FCE;
1FBF;0342;1FCF;
03B9;0306;1FD0;
03B9;0304;1FD1;
03CA;0300;1FD2;
03B9;0342;1FD6;
03CA;0342;1FD7;
0399;0306;1FD8;
0399;0304;1FD9;
0399;0300;1FDA;
1FFE;0300;1FDD;
1FFE;0301;1FDE;
1FFE;0342;1FDF;
03C5;0306;1FE0;
03C5;0304;1FE1;
03CB;0300;1FE2;
03C1;0313;1FE4;
03C1;0314;1FE5;
03C5;0342;1FE6;
03CB;0342;1FE7;
03A5;0306;1FE8;
03A5;0304;1FE9;
03A5;0300;1FEA;
03A1;0314;1FEC;
00A8;0300;1FED;
1F7C;0345;1FF2;
03C9;0345;1FF3;
03CE;0345;1FF4;
03C9;0342;1FF6;
1FF6;0345;1FF7;
039F;0300;1FF8;
03A9;0300;1FFA;
03A9;0345;1FFC;
2190;0338;219A;
2192;0338;219B;
2194;0338;21AE;
21D0;0338;21CD;
21D4;0338;21CE;
21D2;0338;21CF;
2203;0338;2204;
2208;0338;2209;
220B;0338;220C;
2223;0338;2224;
2225;0338;2226;
223C;0338;2241;
2243;0338;2244;
2245;0338;2247;
2248;0338;2249;
003D;0338;2260;
2261;0338;2262;
224D;0338;226D;
003C;0338;226E;
003E;0338;226F;
2264;0338;2270;
2265;0338;2271;
2272;0338;2274;
2273;0338;2275;
2276;0338;2278;
2277;0338;2279;
227A;0338;2280;
227B;0338;2281;
2282;0338;2284;
2283;0338;2285;
2286;0338;2288;
2287;0338;2289;
22A2;0338;22AC;
22A8;0338;22AD;
22A9;0338;22AE;
22AB;0338;22AF;
227C;0338;22E0;
227D;0338;22E1;
2291;0338;22E2;
2292;0338;22E3;
22B2;0338;22EA;
22B3;0338;22EB;
22B4;0338;22EC;
22B5;0338;22ED;
304B;3099;304C;
304D;3099;304E;
304F;3099;3050;
3051;3099;3052;
3053;3099;3054;
3055;3099;3056;
3057;3099;3058;
3059;3099;305A;
305B;3099;305C;
305D;3099;305E;
305F;3099;3060;
3061;3099;3062;
3064;3099;3065;
3066;3099;3067;
3068;3099;3069;
306F;3099;3070;
306F;309A;3071;
3072;3099;3073;
3072;309A;3074;
3075;3099;3076;
3075;309A;3077;
3078;3099;3079;
3078;309A;307A;
307B;3099;307C;
307B;309A;307D;
3046;3099;3094;
309D;3099;309E;
30AB;3099;30AC;
30AD;3099;30AE;
30AF;3099;30B0;
30B1;3099;30B2;
30B3;3099;30B4;
30B5;3099;30B6;
30B7;3099;30B8;
30B9;3099;30BA;
30BB;3099;30BC;
30BD;3099;30BE;
30BF;3099;30C0;
30C1;3099;30C2;
30C4;3099;30C5;
30C6;3099;30C7;
30C8;3099;30C9;
30CF;3099;30D0;
30CF;309A;30D1;
30D2;3099;30D3;
30D2;309A;30D4;
30D5;3099;30D6;
30D5;309A;30D7;
30D8;3099;30D9;
30D8;309A;30DA;
30DB;3099;30DC;
30DB;309A;30DD;
30A6;3099;30F4;
30EF;3099;30F7;
30F0;3099;30F8;
30F1;3099;30F9;
30F2;3099;30FA;
30FD;3099;30FE;
11099;110BA;1109A;
1109B;110BA;1109C;
110A5;110BA;110AB;
11131;11127;1112E;
11132;11127;1112F;
11347;1133E;1134B;
11347;11357;1134C;
114B9;114BA;114BB;
114B9;114B0;114BC;
114B9;114BD;114BE;
115B8;115AF;115BA;
115B9;115AF;115BB;
@@ -0,0 +1,206 @@
# CompositionExclusions-8.0.0.txt
# Date: 2015-02-19, 00:30:00 GMT [KW, LI]
#
# This file lists the characters for the Composition Exclusion Table
# defined in UAX #15, Unicode Normalization Forms.
#
# This file is a normative contributory data file in the
# Unicode Character Database.
#
# Copyright (c) 1991-2015 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
#
# For more information, see
# http://www.unicode.org/unicode/reports/tr15/#Primary_Exclusion_List_Table
#
# For a full derivation of composition exclusions, see the derived property
# Full_Composition_Exclusion in DerivedNormalizationProps.txt
#
# ================================================
# (1) Script Specifics
#
# This list of characters cannot be derived from the UnicodeData.txt file.
# ================================================
0958 # DEVANAGARI LETTER QA
0959 # DEVANAGARI LETTER KHHA
095A # DEVANAGARI LETTER GHHA
095B # DEVANAGARI LETTER ZA
095C # DEVANAGARI LETTER DDDHA
095D # DEVANAGARI LETTER RHA
095E # DEVANAGARI LETTER FA
095F # DEVANAGARI LETTER YYA
09DC # BENGALI LETTER RRA
09DD # BENGALI LETTER RHA
09DF # BENGALI LETTER YYA
0A33 # GURMUKHI LETTER LLA
0A36 # GURMUKHI LETTER SHA
0A59 # GURMUKHI LETTER KHHA
0A5A # GURMUKHI LETTER GHHA
0A5B # GURMUKHI LETTER ZA
0A5E # GURMUKHI LETTER FA
0B5C # ORIYA LETTER RRA
0B5D # ORIYA LETTER RHA
0F43 # TIBETAN LETTER GHA
0F4D # TIBETAN LETTER DDHA
0F52 # TIBETAN LETTER DHA
0F57 # TIBETAN LETTER BHA
0F5C # TIBETAN LETTER DZHA
0F69 # TIBETAN LETTER KSSA
0F76 # TIBETAN VOWEL SIGN VOCALIC R
0F78 # TIBETAN VOWEL SIGN VOCALIC L
0F93 # TIBETAN SUBJOINED LETTER GHA
0F9D # TIBETAN SUBJOINED LETTER DDHA
0FA2 # TIBETAN SUBJOINED LETTER DHA
0FA7 # TIBETAN SUBJOINED LETTER BHA
0FAC # TIBETAN SUBJOINED LETTER DZHA
0FB9 # TIBETAN SUBJOINED LETTER KSSA
FB1D # HEBREW LETTER YOD WITH HIRIQ
FB1F # HEBREW LIGATURE YIDDISH YOD YOD PATAH
FB2A # HEBREW LETTER SHIN WITH SHIN DOT
FB2B # HEBREW LETTER SHIN WITH SIN DOT
FB2C # HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT
FB2D # HEBREW LETTER SHIN WITH DAGESH AND SIN DOT
FB2E # HEBREW LETTER ALEF WITH PATAH
FB2F # HEBREW LETTER ALEF WITH QAMATS
FB30 # HEBREW LETTER ALEF WITH MAPIQ
FB31 # HEBREW LETTER BET WITH DAGESH
FB32 # HEBREW LETTER GIMEL WITH DAGESH
FB33 # HEBREW LETTER DALET WITH DAGESH
FB34 # HEBREW LETTER HE WITH MAPIQ
FB35 # HEBREW LETTER VAV WITH DAGESH
FB36 # HEBREW LETTER ZAYIN WITH DAGESH
FB38 # HEBREW LETTER TET WITH DAGESH
FB39 # HEBREW LETTER YOD WITH DAGESH
FB3A # HEBREW LETTER FINAL KAF WITH DAGESH
FB3B # HEBREW LETTER KAF WITH DAGESH
FB3C # HEBREW LETTER LAMED WITH DAGESH
FB3E # HEBREW LETTER MEM WITH DAGESH
FB40 # HEBREW LETTER NUN WITH DAGESH
FB41 # HEBREW LETTER SAMEKH WITH DAGESH
FB43 # HEBREW LETTER FINAL PE WITH DAGESH
FB44 # HEBREW LETTER PE WITH DAGESH
FB46 # HEBREW LETTER TSADI WITH DAGESH
FB47 # HEBREW LETTER QOF WITH DAGESH
FB48 # HEBREW LETTER RESH WITH DAGESH
FB49 # HEBREW LETTER SHIN WITH DAGESH
FB4A # HEBREW LETTER TAV WITH DAGESH
FB4B # HEBREW LETTER VAV WITH HOLAM
FB4C # HEBREW LETTER BET WITH RAFE
FB4D # HEBREW LETTER KAF WITH RAFE
FB4E # HEBREW LETTER PE WITH RAFE
# Total code points: 67
# ================================================
# (2) Post Composition Version precomposed characters
#
# These characters cannot be derived solely from the UnicodeData.txt file
# in this version of Unicode.
#
# Note that characters added to the standard after the
# Composition Version and which have canonical decomposition mappings
# are not automatically added to this list of Post Composition
# Version precomposed characters.
# ================================================
2ADC # FORKING
1D15E # MUSICAL SYMBOL HALF NOTE
1D15F # MUSICAL SYMBOL QUARTER NOTE
1D160 # MUSICAL SYMBOL EIGHTH NOTE
1D161 # MUSICAL SYMBOL SIXTEENTH NOTE
1D162 # MUSICAL SYMBOL THIRTY-SECOND NOTE
1D163 # MUSICAL SYMBOL SIXTY-FOURTH NOTE
1D164 # MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE
1D1BB # MUSICAL SYMBOL MINIMA
1D1BC # MUSICAL SYMBOL MINIMA BLACK
1D1BD # MUSICAL SYMBOL SEMIMINIMA WHITE
1D1BE # MUSICAL SYMBOL SEMIMINIMA BLACK
1D1BF # MUSICAL SYMBOL FUSA WHITE
1D1C0 # MUSICAL SYMBOL FUSA BLACK
# Total code points: 14
# ================================================
# (3) Singleton Decompositions
#
# These characters can be derived from the UnicodeData.txt file
# by including all canonically decomposable characters whose
# canonical decomposition consists of a single character.
#
# These characters are simply quoted here for reference.
# See also Full_Composition_Exclusion in DerivedNormalizationProps.txt
# ================================================
# 0340..0341 [2] COMBINING GRAVE TONE MARK..COMBINING ACUTE TONE MARK
# 0343 COMBINING GREEK KORONIS
# 0374 GREEK NUMERAL SIGN
# 037E GREEK QUESTION MARK
# 0387 GREEK ANO TELEIA
# 1F71 GREEK SMALL LETTER ALPHA WITH OXIA
# 1F73 GREEK SMALL LETTER EPSILON WITH OXIA
# 1F75 GREEK SMALL LETTER ETA WITH OXIA
# 1F77 GREEK SMALL LETTER IOTA WITH OXIA
# 1F79 GREEK SMALL LETTER OMICRON WITH OXIA
# 1F7B GREEK SMALL LETTER UPSILON WITH OXIA
# 1F7D GREEK SMALL LETTER OMEGA WITH OXIA
# 1FBB GREEK CAPITAL LETTER ALPHA WITH OXIA
# 1FBE GREEK PROSGEGRAMMENI
# 1FC9 GREEK CAPITAL LETTER EPSILON WITH OXIA
# 1FCB GREEK CAPITAL LETTER ETA WITH OXIA
# 1FD3 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
# 1FDB GREEK CAPITAL LETTER IOTA WITH OXIA
# 1FE3 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
# 1FEB GREEK CAPITAL LETTER UPSILON WITH OXIA
# 1FEE..1FEF [2] GREEK DIALYTIKA AND OXIA..GREEK VARIA
# 1FF9 GREEK CAPITAL LETTER OMICRON WITH OXIA
# 1FFB GREEK CAPITAL LETTER OMEGA WITH OXIA
# 1FFD GREEK OXIA
# 2000..2001 [2] EN QUAD..EM QUAD
# 2126 OHM SIGN
# 212A..212B [2] KELVIN SIGN..ANGSTROM SIGN
# 2329 LEFT-POINTING ANGLE BRACKET
# 232A RIGHT-POINTING ANGLE BRACKET
# F900..FA0D [270] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA0D
# FA10 CJK COMPATIBILITY IDEOGRAPH-FA10
# FA12 CJK COMPATIBILITY IDEOGRAPH-FA12
# FA15..FA1E [10] CJK COMPATIBILITY IDEOGRAPH-FA15..CJK COMPATIBILITY IDEOGRAPH-FA1E
# FA20 CJK COMPATIBILITY IDEOGRAPH-FA20
# FA22 CJK COMPATIBILITY IDEOGRAPH-FA22
# FA25..FA26 [2] CJK COMPATIBILITY IDEOGRAPH-FA25..CJK COMPATIBILITY IDEOGRAPH-FA26
# FA2A..FA6D [68] CJK COMPATIBILITY IDEOGRAPH-FA2A..CJK COMPATIBILITY IDEOGRAPH-FA6D
# FA70..FAD9 [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9
# 2F800..2FA1D [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
# Total code points: 1035
# ================================================
# (4) Non-Starter Decompositions
#
# These characters can be derived from the UnicodeData.txt file
# by including each expanding canonical decomposition
# (i.e., those which canonically decompose to a sequence
# of characters instead of a single character), such that:
#
# A. The character is not a Starter.
#
# OR (inclusive)
#
# B. The character's canonical decomposition begins
# with a character that is not a Starter.
#
# Note that a "Starter" is any character with a zero combining class.
#
# These characters are simply quoted here for reference.
# See also Full_Composition_Exclusion in DerivedNormalizationProps.txt
# ================================================
# 0344 COMBINING GREEK DIALYTIKA TONOS
# 0F73 TIBETAN VOWEL SIGN II
# 0F75 TIBETAN VOWEL SIGN UU
# 0F81 TIBETAN VOWEL SIGN REVERSED II
# Total code points: 4
# EOF
File diff suppressed because it is too large Load Diff
+17 -6
View File
@@ -55,7 +55,7 @@ E01F0..E0FFF ; Control # Cn [3600] <reserved-E01F0>..<reserved-E0FFF>
0825..0827 ; Extend # Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U
0829..082D ; Extend # Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA
0859..085B ; Extend # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK
08E4..0902 ; Extend # Mn [31] ARABIC CURLY FATHA..DEVANAGARI SIGN ANUSVARA
08E3..0902 ; Extend # Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA
093A ; Extend # Mn DEVANAGARI VOWEL SIGN OE
093C ; Extend # Mn DEVANAGARI SIGN NUKTA
0941..0948 ; Extend # Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI
@@ -216,7 +216,7 @@ E01F0..E0FFF ; Control # Cn [3600] <reserved-E01F0>..<reserved-E0FFF>
A66F ; Extend # Mn COMBINING CYRILLIC VZMET
A670..A672 ; Extend # Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN
A674..A67D ; Extend # Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK
A69F ; Extend # Mn COMBINING CYRILLIC LETTER IOTIFIED E
A69E..A69F ; Extend # Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E
A6F0..A6F1 ; Extend # Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS
A802 ; Extend # Mn SYLOTI NAGRI SIGN DVISVARA
A806 ; Extend # Mn SYLOTI NAGRI SIGN HASANTA
@@ -249,7 +249,7 @@ ABE8 ; Extend # Mn MEETEI MAYEK VOWEL SIGN UNAP
ABED ; Extend # Mn MEETEI MAYEK APUN IYEK
FB1E ; Extend # Mn HEBREW POINT JUDEO-SPANISH VARIKA
FE00..FE0F ; Extend # Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16
FE20..FE2D ; Extend # Mn [14] COMBINING LIGATURE LEFT HALF..COMBINING CONJOINING MACRON BELOW
FE20..FE2F ; Extend # Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF
FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
101FD ; Extend # Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE
102E0 ; Extend # Mn COPTIC EPACT THOUSANDS MARK
@@ -271,12 +271,13 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT
11173 ; Extend # Mn MAHAJANI SIGN NUKTA
11180..11181 ; Extend # Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA
111B6..111BE ; Extend # Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O
111CA..111CC ; Extend # Mn [3] SHARADA SIGN NUKTA..SHARADA EXTRA SHORT VOWEL MARK
1122F..11231 ; Extend # Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI
11234 ; Extend # Mn KHOJKI SIGN ANUSVARA
11236..11237 ; Extend # Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA
112DF ; Extend # Mn KHUDAWADI SIGN ANUSVARA
112E3..112EA ; Extend # Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA
11301 ; Extend # Mn GRANTHA SIGN CANDRABINDU
11300..11301 ; Extend # Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU
1133C ; Extend # Mn GRANTHA SIGN NUKTA
1133E ; Extend # Mc GRANTHA VOWEL SIGN AA
11340 ; Extend # Mn GRANTHA VOWEL SIGN II
@@ -293,6 +294,7 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT
115B2..115B5 ; Extend # Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR
115BC..115BD ; Extend # Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA
115BF..115C0 ; Extend # Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA
115DC..115DD ; Extend # Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU
11633..1163A ; Extend # Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI
1163D ; Extend # Mn MODI SIGN ANUSVARA
1163F..11640 ; Extend # Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA
@@ -300,6 +302,9 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT
116AD ; Extend # Mn TAKRI VOWEL SIGN AA
116B0..116B5 ; Extend # Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU
116B7 ; Extend # Mn TAKRI SIGN NUKTA
1171D..1171F ; Extend # Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA
11722..11725 ; Extend # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU
11727..1172B ; Extend # Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER
16AF0..16AF4 ; Extend # Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE
16B30..16B36 ; Extend # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM
16F8F..16F92 ; Extend # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW
@@ -311,6 +316,12 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT
1D185..1D18B ; Extend # Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE
1D1AA..1D1AD ; Extend # Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO
1D242..1D244 ; Extend # Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME
1DA00..1DA36 ; Extend # Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN
1DA3B..1DA6C ; Extend # Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT
1DA75 ; Extend # Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS
1DA84 ; Extend # Mn SIGNWRITING LOCATION HEAD NECK
1DA9B..1DA9F ; Extend # Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6
1DAA1..1DAAF ; Extend # Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16
1E8D0..1E8D6 ; Extend # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS
E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
1F1E6..1F1FF ; Regional_Indicator # So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z
@@ -368,8 +379,6 @@ E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
1929..192B ; SpacingMark # Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA
1930..1931 ; SpacingMark # Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA
1933..1938 ; SpacingMark # Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA
19B5..19B7 ; SpacingMark # Mc [3] NEW TAI LUE VOWEL SIGN E..NEW TAI LUE VOWEL SIGN O
19BA ; SpacingMark # Mc NEW TAI LUE VOWEL SIGN AY
1A19..1A1A ; SpacingMark # Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O
1A55 ; SpacingMark # Mc TAI THAM CONSONANT SIGN MEDIAL RA
1A57 ; SpacingMark # Mc TAI THAM CONSONANT SIGN LA TANG LAI
@@ -443,6 +452,8 @@ ABEC ; SpacingMark # Mc MEETEI MAYEK LUM IYEK
116AC ; SpacingMark # Mc TAKRI SIGN VISARGA
116AE..116AF ; SpacingMark # Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II
116B6 ; SpacingMark # Mc TAKRI SIGN VIRAMA
11720..11721 ; SpacingMark # Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA
11726 ; SpacingMark # Mc AHOM VOWEL SIGN E
16F51..16F7E ; SpacingMark # Mc [46] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN NG
1D166 ; SpacingMark # Mc MUSICAL SYMBOL COMBINING SPRECHGESANG STEM
1D16D ; SpacingMark # Mc MUSICAL SYMBOL COMBINING AUGMENTATION DOT
File diff suppressed because it is too large Load Diff
+11
View File
@@ -0,0 +1,11 @@
0009..000D ; White_Space # Cc [5] <control-0009>..<control-000D>
0020 ; White_Space # Zs SPACE
0085 ; White_Space # Cc <control-0085>
00A0 ; White_Space # Zs NO-BREAK SPACE
1680 ; White_Space # Zs OGHAM SPACE MARK
2000..200A ; White_Space # Zs [11] EN QUAD..HAIR SPACE
2028 ; White_Space # Zl LINE SEPARATOR
2029 ; White_Space # Zp PARAGRAPH SEPARATOR
202F ; White_Space # Zs NARROW NO-BREAK SPACE
205F ; White_Space # Zs MEDIUM MATHEMATICAL SPACE
3000 ; White_Space # Zs IDEOGRAPHIC SPACE
+327 -274
View File
@@ -1,231 +1,25 @@
to_binary = fn
"" ->
nil
codepoints ->
codepoints = :binary.split(codepoints, " ", [:global])
Enum.reduce codepoints, "", fn(codepoint, acc) ->
acc <> <<String.to_integer(codepoint, 16)::utf8>>
end
end
defmodule String.Unicode do
@moduledoc false
def version, do: {7, 0, 0}
data_path = Path.join(__DIR__, "UnicodeData.txt")
{codes, whitespace} = Enum.reduce File.stream!(data_path), {[], []}, fn(line, {cacc, wacc}) ->
[codepoint, _name, _category,
_class, bidi, _decomposition,
_numeric_1, _numeric_2, _numeric_3,
_bidi_mirror, _unicode_1, _iso,
upper, lower, title] = :binary.split(line, ";", [:global])
title = :binary.part(title, 0, byte_size(title) - 1)
cond do
upper != "" or lower != "" or title != "" ->
{[{to_binary.(codepoint),
to_binary.(upper),
to_binary.(lower),
to_binary.(title)} | cacc],
wacc}
bidi in ["B", "S", "WS"] ->
{cacc, [to_binary.(codepoint) | wacc]}
true ->
{cacc, wacc}
end
end
special_path = Path.join(__DIR__, "SpecialCasing.txt")
codes = Enum.reduce File.stream!(special_path), codes, fn(line, acc) ->
[codepoint, lower, title, upper, _] = :binary.split(line, "; ", [:global])
key = to_binary.(codepoint)
:lists.keystore(key, 1, acc, {key,
to_binary.(upper),
to_binary.(lower),
to_binary.(title)})
end
# Downcase
def downcase(string), do: downcase(string, "")
for {codepoint, _upper, lower, _title} <- codes, lower && lower != codepoint do
defp downcase(unquote(codepoint) <> rest, acc) do
downcase(rest, acc <> unquote(lower))
end
end
defp downcase(<<char, rest::binary>>, acc) do
downcase(rest, <<acc::binary, char>>)
end
defp downcase("", acc), do: acc
# Upcase
def upcase(string), do: upcase(string, "")
for {codepoint, upper, _lower, _title} <- codes, upper && upper != codepoint do
defp upcase(unquote(codepoint) <> rest, acc) do
upcase(rest, acc <> unquote(upper))
end
end
defp upcase(<<char, rest::binary>>, acc) do
upcase(rest, <<acc::binary, char>>)
end
defp upcase("", acc), do: acc
# Titlecase once
def titlecase_once(""), do: {"", ""}
for {codepoint, _upper, _lower, title} <- codes, title && title != codepoint do
def titlecase_once(unquote(codepoint) <> rest) do
{unquote(title), rest}
end
end
def titlecase_once(<<char, rest::binary>>) do
{<<char>>, rest}
end
# Strip
def lstrip(string)
def lstrip(""), do: ""
for codepoint <- whitespace do
def lstrip(unquote(codepoint) <> rest) do
lstrip(rest)
end
end
def lstrip(string) when is_binary(string), do: string
@whitespace_max_size 3
for codepoint <- whitespace do
# We need to increment @whitespace_max_size as well
# as the small table (_s) if we add a new entry here.
case byte_size(codepoint) do
3 ->
defp do_rstrip_l(unquote(codepoint)), do: -3
2 ->
defp do_rstrip_l(<<_, unquote(codepoint)>>), do: -2
defp do_rstrip_s(unquote(codepoint)), do: <<>>
1 ->
defp do_rstrip_l(<<unquote(codepoint), unquote(codepoint), unquote(codepoint)>>), do: -3
defp do_rstrip_l(<<_, unquote(codepoint), unquote(codepoint)>>), do: -2
defp do_rstrip_l(<<_, _, unquote(codepoint)>>), do: -1
defp do_rstrip_s(<<x, unquote(codepoint)>>), do: do_rstrip_s(<<x>>)
defp do_rstrip_s(unquote(codepoint)), do: <<>>
end
end
defp do_rstrip_l(_), do: 0
defp do_rstrip_s(o), do: o
def rstrip(string) when is_binary(string) do
rstrip(string, byte_size(string))
end
defp rstrip(string, size) when size < @whitespace_max_size do
do_rstrip_s(string)
end
defp rstrip(string, size) do
trail = binary_part(string, size, -@whitespace_max_size)
case do_rstrip_l(trail) do
0 -> string
x -> rstrip(binary_part(string, 0, size + x), size + x)
end
end
# Split
def split(""), do: []
def split(string) when is_binary(string) do
:lists.reverse do_split(string, "", [])
end
for codepoint <- whitespace do
defp do_split(unquote(codepoint) <> rest, buffer, acc) do
do_split(rest, "", add_buffer_to_acc(buffer, acc))
end
end
defp do_split(<<char, rest::binary>>, buffer, acc) do
do_split(rest, <<buffer::binary, char>>, acc)
end
defp do_split(<<>>, buffer, acc) do
add_buffer_to_acc(buffer, acc)
end
@compile {:inline, add_buffer_to_acc: 2}
defp add_buffer_to_acc("", acc), do: acc
defp add_buffer_to_acc(buffer, acc), do: [buffer|acc]
# Codepoints
def next_codepoint(<<cp::utf8, rest::binary>>) do
{<<cp::utf8>>, rest}
end
def next_codepoint(<<cp, rest::binary>>) do
{<<cp>>, rest}
end
def next_codepoint(<<>>) do
nil
end
def codepoints(binary) when is_binary(binary) do
do_codepoints(next_codepoint(binary))
end
defp do_codepoints({c, rest}) do
[c|do_codepoints(next_codepoint(rest))]
end
defp do_codepoints(nil) do
[]
end
end
defmodule String.Graphemes do
@moduledoc false
def version, do: {8, 0, 0}
cluster_path = Path.join(__DIR__, "GraphemeBreakProperty.txt")
regex = ~r/(?:^([0-9A-F]+)(?:\.\.([0-9A-F]+))?)\s+;\s(\w+)/m
to_range = fn
first, "" ->
[<<String.to_integer(first, 16)::utf8>>]
first, last ->
range = String.to_integer(first, 16)..String.to_integer(last, 16)
Enum.map(range, fn(int) -> <<int::utf8>> end)
end
cluster = Enum.reduce File.stream!(cluster_path), %{}, fn(line, dict) ->
cluster = Enum.reduce File.stream!(cluster_path), %{}, fn line, dict ->
[_full, first, last, class] = Regex.run(regex, line)
# Skip surrogates
if first == "D800" and last == "DFFF" do
dict
else
list = to_range.(first, last)
Map.update(dict, class, list, &(&1 ++ list))
end
codepoints =
case {first, last} do
{"D800", "DFFF"} ->
[]
{first, ""} ->
[<<String.to_integer(first, 16)::utf8>>]
{first, last} ->
range = String.to_integer(first, 16)..String.to_integer(last, 16)
Enum.map(range, fn int -> <<int::utf8>> end)
end
Map.update(dict, class, codepoints, &(&1 ++ codepoints))
end
# There is no codepoint marked as Prepend by Unicode 6.3.0
@@ -371,7 +165,7 @@ defmodule String.Graphemes do
# {size, rest}
# end
## Tight-loop implementations
# Graphemes
def graphemes(binary) when is_binary(binary) do
do_graphemes(next_grapheme_size(binary), binary)
@@ -385,6 +179,8 @@ defmodule String.Graphemes do
[]
end
# Length
def length(string) do
do_length(next_grapheme_size(string), 0)
end
@@ -395,6 +191,8 @@ defmodule String.Graphemes do
defp do_length(nil, acc), do: acc
# Split at
def split_at(string, pos) do
do_split_at(string, 0, pos, 0)
end
@@ -409,34 +207,272 @@ defmodule String.Graphemes do
defp do_split_at(string, acc, desired_pos, desired_pos) do
{acc, string}
end
# Codepoints
def next_codepoint(<<cp::utf8, rest::binary>>) do
{<<cp::utf8>>, rest}
end
def next_codepoint(<<cp, rest::binary>>) do
{<<cp>>, rest}
end
def next_codepoint(<<>>) do
nil
end
def codepoints(binary) when is_binary(binary) do
do_codepoints(next_codepoint(binary))
end
defp do_codepoints({c, rest}) do
[c|do_codepoints(next_codepoint(rest))]
end
defp do_codepoints(nil) do
[]
end
end
to_binary = fn
"" ->
nil
codepoints ->
codepoints
|> :binary.split(" ", [:global])
|> Enum.map(&<<String.to_integer(&1, 16)::utf8>>)
|> IO.iodata_to_binary
end
data_path = Path.join(__DIR__, "UnicodeData.txt")
{codes, non_breakable, decompositions, combining_classes} =
Enum.reduce File.stream!(data_path), {[], [], %{}, %{}}, fn line, {cacc, wacc, dacc, kacc} ->
[codepoint, _name, _category,
class, _bidi, decomposition,
_numeric_1, _numeric_2, _numeric_3,
_bidi_mirror, _unicode_1, _iso,
upper, lower, title] = :binary.split(line, ";", [:global])
title = :binary.part(title, 0, byte_size(title) - 1)
cacc =
if upper != "" or lower != "" or title != "" do
[{to_binary.(codepoint), to_binary.(upper), to_binary.(lower), to_binary.(title)} | cacc]
else
cacc
end
wacc =
case decomposition do
"<noBreak>" <> _ -> [to_binary.(codepoint)|wacc]
_ -> wacc
end
dacc =
case decomposition do
<<h, _::binary>> when h != ?< -> # Decomposition
decomposition =
decomposition
|> :binary.split(" ", [:global])
|> Enum.map(&String.to_integer(&1, 16))
Map.put(dacc, String.to_integer(codepoint, 16), decomposition)
_ ->
dacc
end
kacc =
case Integer.parse(class) do
{0, ""} -> kacc
{n, ""} -> Map.put(kacc, String.to_integer(codepoint, 16), n)
end
{cacc, wacc, dacc, kacc}
end
defmodule String.Casing do
@moduledoc false
special_path = Path.join(__DIR__, "SpecialCasing.txt")
codes = Enum.reduce File.stream!(special_path), codes, fn line, acc ->
[codepoint, lower, title, upper, _] = :binary.split(line, "; ", [:global])
key = to_binary.(codepoint)
:lists.keystore(key, 1, acc, {key,
to_binary.(upper),
to_binary.(lower),
to_binary.(title)})
end
# Downcase
def downcase(string), do: downcase(string, "")
for {codepoint, _upper, lower, _title} <- codes, lower && lower != codepoint do
defp downcase(unquote(codepoint) <> rest, acc) do
downcase(rest, acc <> unquote(lower))
end
end
defp downcase(<<char, rest::binary>>, acc) do
downcase(rest, <<acc::binary, char>>)
end
defp downcase("", acc), do: acc
# Upcase
def upcase(string), do: upcase(string, "")
for {codepoint, upper, _lower, _title} <- codes, upper && upper != codepoint do
defp upcase(unquote(codepoint) <> rest, acc) do
upcase(rest, acc <> unquote(upper))
end
end
defp upcase(<<char, rest::binary>>, acc) do
upcase(rest, <<acc::binary, char>>)
end
defp upcase("", acc), do: acc
# Titlecase once
def titlecase_once(""), do: {"", ""}
for {codepoint, _upper, _lower, title} <- codes, title && title != codepoint do
def titlecase_once(unquote(codepoint) <> rest) do
{unquote(title), rest}
end
end
def titlecase_once(<<char, rest::binary>>) do
{<<char>>, rest}
end
end
defmodule String.Break do
@moduledoc false
@whitespace_max_size 3
# WhiteSpace.txt is extracted from Unicode's PropList.txt (just the White_Space property)
prop_path = Path.join(__DIR__, "WhiteSpace.txt")
whitespace = Enum.reduce File.stream!(prop_path), [], fn line, acc ->
case line |> :binary.split(";") |> hd do
<<first::4-bytes, "..", last::4-bytes, _::binary>> ->
first = String.to_integer(first, 16)
last = String.to_integer(last, 16)
Enum.map(first..last, fn int -> <<int::utf8>> end) ++ acc
<<single::4-bytes, _::binary>> ->
[<<String.to_integer(single, 16)::utf8>> | acc]
end
end
# lstrip
def lstrip(""), do: ""
for codepoint <- whitespace do
def lstrip(unquote(codepoint) <> rest) do
lstrip(rest)
end
end
def lstrip(string) when is_binary(string), do: string
# rstrip
for codepoint <- whitespace do
# We need to increment @whitespace_max_size as well
# as the small table (_s) if we add a new entry here.
case byte_size(codepoint) do
3 ->
defp do_rstrip_l(unquote(codepoint)), do: -3
2 ->
defp do_rstrip_l(<<_, unquote(codepoint)>>), do: -2
defp do_rstrip_s(unquote(codepoint)), do: <<>>
1 ->
defp do_rstrip_l(<<unquote(codepoint), unquote(codepoint), unquote(codepoint)>>), do: -3
defp do_rstrip_l(<<_, unquote(codepoint), unquote(codepoint)>>), do: -2
defp do_rstrip_l(<<_, _, unquote(codepoint)>>), do: -1
defp do_rstrip_s(<<x, unquote(codepoint)>>), do: do_rstrip_s(<<x>>)
defp do_rstrip_s(unquote(codepoint)), do: <<>>
end
end
defp do_rstrip_l(_), do: 0
defp do_rstrip_s(o), do: o
def rstrip(string) when is_binary(string) do
rstrip(string, byte_size(string))
end
defp rstrip(string, size) when size < @whitespace_max_size do
do_rstrip_s(string)
end
defp rstrip(string, size) do
trail = binary_part(string, size, -@whitespace_max_size)
case do_rstrip_l(trail) do
0 -> string
x -> rstrip(binary_part(string, 0, size + x), size + x)
end
end
# Split
def split(""), do: []
def split(string) when is_binary(string) do
:lists.reverse do_split(string, "", [])
end
for codepoint <- whitespace -- non_breakable do
defp do_split(unquote(codepoint) <> rest, buffer, acc) do
do_split(rest, "", add_buffer_to_acc(buffer, acc))
end
end
defp do_split(<<char, rest::binary>>, buffer, acc) do
do_split(rest, <<buffer::binary, char>>, acc)
end
defp do_split(<<>>, buffer, acc) do
add_buffer_to_acc(buffer, acc)
end
@compile {:inline, add_buffer_to_acc: 2}
defp add_buffer_to_acc("", acc), do: acc
defp add_buffer_to_acc(buffer, acc), do: [buffer|acc]
# Decompose
def decompose(entries, map) do
for entry <- entries do
case map do
%{^entry => match} -> decompose(match, map)
%{} -> <<entry::utf8>>
end
end
end
end
defmodule String.Normalizer do
@moduledoc false
decomposition_path = Path.join(__DIR__, "Decomposition.txt")
exclusions_path = Path.join(__DIR__, "CompositionExclusions.txt")
decompositions = Enum.reduce File.stream!(decomposition_path), [], fn(line, acc) ->
[key, first, second, third, fourth, _] = :binary.split(line, ";", [:global])
decomposition = to_binary.(first) <> (to_binary.(second) || "") <>
(to_binary.(third) || "") <>
(to_binary.(fourth) || "")
[{to_binary.(key), decomposition} | acc]
end
composition_path = Path.join(__DIR__, "Composition.txt")
compositions = Enum.reduce File.stream!(composition_path), [], fn(line, acc) ->
[first, second, composition, _] = :binary.split(line, ";", [:global])
key = to_binary.(first) <> to_binary.(second)
[{key, to_binary.(composition)} | acc]
end
combining_class_path = Path.join(__DIR__, "CombiningClasses.txt")
combining_classes = Enum.reduce File.stream!(combining_class_path), [], fn(line, acc) ->
[codepoint, class, _] = :binary.split(line, ";", [:global])
[{String.to_integer(codepoint, 16), class} | acc]
compositions = Enum.reduce File.stream!(exclusions_path), decompositions, fn
<<h, _::binary>> = line, acc when h in ?0..?9 or h in ?A..?F ->
[codepoint, _] = :binary.split(line, " ")
Map.delete(acc, String.to_integer(codepoint, 16))
_, acc ->
acc
end
# Normalize
@@ -465,18 +501,12 @@ defmodule String.Normalizer do
normalize_nfd(rest, acc <> binary)
end
for {binary, decomposition} <- decompositions do
defp normalize_nfd(unquote(binary) <> rest, acc) do
normalize_nfd(rest, acc <> unquote(decomposition))
end
end
defp normalize_nfd(binary, acc) do
{n, rest} = String.Graphemes.next_grapheme_size(binary)
{n, rest} = String.Unicode.next_grapheme_size(binary)
part = :binary.part(binary, 0, n)
case n do
1 -> normalize_nfd(rest, acc <> part)
_ -> normalize_nfd(rest, acc <> canonical_order(part))
1 -> normalize_nfc(rest, acc <> part)
_ -> normalize_nfd(rest, acc <> canonical_order(part, []))
end
end
@@ -487,7 +517,7 @@ defmodule String.Normalizer do
end
defp normalize_nfc(binary, acc) do
{n, rest} = String.Graphemes.next_grapheme_size(binary)
{n, rest} = String.Unicode.next_grapheme_size(binary)
part = :binary.part(binary, 0, n)
case n do
1 -> normalize_nfc(rest, acc <> part)
@@ -495,11 +525,33 @@ defmodule String.Normalizer do
end
end
defp canonical_order(binary) do
binary
|> :unicode.characters_to_list()
|> Enum.sort_by(&combining_class/1)
|> :unicode.characters_to_binary()
for {cp, decomposition} <- decompositions do
decomposition =
decomposition
|> String.Break.decompose(decompositions)
|> IO.iodata_to_binary()
defp canonical_order(unquote(<<cp::utf8>>) <> rest, acc) do
canonical_order(unquote(decomposition) <> rest, acc)
end
end
defp canonical_order(<<h::utf8, t::binary>>, acc) do
case combining_class(h) do
0 -> canonical_order(acc) <> canonical_order(t, [{h, 0}])
n -> canonical_order(t, [{h, n}|acc])
end
end
defp canonical_order(<<>>, acc) do
canonical_order(acc)
end
defp canonical_order([{x, _}]) do
<<x::utf8>>
end
defp canonical_order(acc) do
:lists.keysort(2, Enum.reverse(acc))
|> Enum.map(&<<elem(&1, 0)::utf8>>)
|> IO.iodata_to_binary
end
for {codepoint, class} <- combining_classes do
@@ -508,8 +560,6 @@ defmodule String.Normalizer do
defp combining_class(_), do: 0
defp compose(<<_::utf8>> = binary), do: binary
defp compose(<<lead::utf8, vowel::utf8, rest::binary>>) when lead in 0x1100..0x1112 and vowel in 0x1161..0x1175 do
codepoint = 0xAC00 + ((lead - 0x1100) * 588) + ((vowel - 0x1161) * 28)
case rest do
@@ -520,29 +570,32 @@ defmodule String.Normalizer do
end
end
for {binary, composition} <- compositions do
defp compose(unquote(binary)), do: unquote(composition)
defp compose(binary) do
compose_one(binary) || (
<<cp::utf8, rest::binary>> = binary
compose_many(rest, <<cp::utf8>>, "", combining_class(cp) - 1)
)
end
defp compose(<<cp::utf8, rest::binary>>) do
compose(rest, <<cp::utf8>>, "", combining_class(cp) - 1)
end
defp compose_many("", base, accents, _), do: base <> accents
defp compose("", base, accents, _), do: base <> accents
defp compose(<<cp::utf8, rest::binary>>, base, accents, last_class) do
defp compose_many(<<cp::utf8, rest::binary>>, base, accents, last_class) do
part_class = combining_class(cp)
combined = <<base::binary, cp::utf8>>
if last_class < part_class and composable?(combined) do
compose(rest, compose(combined), accents, last_class)
if composed = (last_class < part_class && compose_one(combined)) do
compose_many(rest, composed, accents, last_class)
else
compose(rest, base, <<accents::binary, cp::utf8>>, part_class)
compose_many(rest, base, <<accents::binary, cp::utf8>>, part_class)
end
end
for {binary, _} <- compositions do
defp composable?(unquote(binary)), do: true
# Compositions:
# 1. We must exclude compositions with a single codepoint
# 2. We must exclude compositions that do not start with 0 combining class
for {cp, [fst, snd]} <- compositions,
Map.get(combining_classes, fst, 0) == 0 do
defp compose_one(unquote(<<fst::utf8, snd::utf8>>)), do: unquote(<<cp::utf8>>)
end
defp composable?(_), do: false
defp compose_one(_), do: nil
end
+12 -8
View File
@@ -103,12 +103,13 @@ defmodule ExUnit.Assertions do
# to avoid silly warnings though.
return =
no_warning(quote do
if right do
right
else
raise ExUnit.AssertionError,
expr: expr,
message: "Expected truthy, got #{inspect right}"
case right do
x when x in [nil, false] ->
raise ExUnit.AssertionError,
expr: expr,
message: "Expected truthy, got #{inspect right}"
_ ->
:ok
end
end)
@@ -416,8 +417,11 @@ defmodule ExUnit.Assertions do
|> elem(1)
end
defp no_warning({name, meta, args}) do
{name, [line: -1] ++ meta, args}
defp no_warning({name, meta, [expr, [do: clauses]]}) do
clauses = Enum.map clauses, fn {:->, meta, args} ->
{:->, [generated: true] ++ Keyword.put(meta, :line, -1), args}
end
{name, meta, [expr, [do: clauses]]}
end
@doc """
+16 -5
View File
@@ -146,6 +146,8 @@ defmodule ExUnit.Callbacks do
## Helpers
@reserved ~w(case test line file)a
@doc false
def __merge__(_mod, context, :ok) do
{:ok, context}
@@ -163,12 +165,16 @@ defmodule ExUnit.Callbacks do
raise_merge_failed!(mod, data)
end
defp context_merge(_mod, context, %{} = data) do
Map.merge(context, data)
defp context_merge(mod, context, %{} = data) do
Map.merge(context, data, fn
_, v, v -> v
k, _, v when k in @reserved -> raise_merge_reserved!(mod, k, v)
_, _, v -> v
end)
end
defp context_merge(_mod, context, data) when is_list(data) do
Enum.into(data, context)
defp context_merge(mod, context, data) when is_list(data) do
context_merge(mod, context, Map.new(data))
end
defp context_merge(mod, _context, data) do
@@ -177,7 +183,12 @@ defmodule ExUnit.Callbacks do
defp raise_merge_failed!(mod, data) do
raise "expected ExUnit callback in #{inspect mod} to return :ok " <>
" or {:ok, keyword | map}, got #{inspect data} instead"
"or {:ok, keyword | map}, got #{inspect data} instead"
end
defp raise_merge_reserved!(mod, key, value) do
raise "expected ExUnit callback in #{inspect mod} is trying to set " <>
"reserved field #{inspect key} to #{inspect value}"
end
defp escape(contents) do
+19 -17
View File
@@ -114,10 +114,11 @@ defmodule ExUnit.Case do
The following tags are set automatically by ExUnit and are
therefore reserved:
* `:case` - the test case module
* `:test` - the test name
* `:line` - the line on which the test was defined
* `:file` - the file on which the test was defined
* `:case` - the test case module
* `:test` - the test name
* `:line` - the line on which the test was defined
* `:file` - the file on which the test was defined
* `:async` - if the test case is in async mode
The following tags customize how tests behaves:
@@ -174,7 +175,7 @@ defmodule ExUnit.Case do
This default can be overriden by `@tag capture_log: false` or `@moduletag capture_log: false`.
Since `setup_all` blocks don't belong to a specific test, log messages generated in them (or
Since `setup_all` blocks don't belong to a specific test, log messages generated in them (or
between tests) are never captured. If you want to suppress these messages as well, remove the
console backend globally:
@@ -193,20 +194,16 @@ defmodule ExUnit.Case do
end
quote do
async = !!unquote(async)
unless Module.get_attribute(__MODULE__, :ex_unit_tests) do
Enum.each [:ex_unit_tests, :tag, :moduletag],
&Module.register_attribute(__MODULE__, &1, accumulate: true)
if unquote(async) do
@moduletag async: true
ExUnit.Server.add_async_case(__MODULE__)
else
@moduletag async: false
ExUnit.Server.add_sync_case(__MODULE__)
end
@moduletag async: async
@before_compile ExUnit.Case
@ex_unit_test_names %{}
@ex_unit_async async
use ExUnit.Callbacks
end
@@ -254,7 +251,7 @@ defmodule ExUnit.Case do
quote bind_quoted: binding do
test = :"test #{message}"
ExUnit.Case.__on_definition__(__ENV__, test)
ExUnit.Case.__on_definition__(__ENV__, test, [])
def unquote(test)(unquote(var)), do: unquote(contents)
end
end
@@ -284,6 +281,12 @@ defmodule ExUnit.Case do
@doc false
defmacro __before_compile__(_) do
quote do
if @ex_unit_async do
ExUnit.Server.add_async_case(__MODULE__)
else
ExUnit.Server.add_sync_case(__MODULE__)
end
def __ex_unit__(:case) do
%ExUnit.TestCase{name: __MODULE__, tests: @ex_unit_tests}
end
@@ -291,8 +294,7 @@ defmodule ExUnit.Case do
end
@doc false
def __on_definition__(env, name, tags \\ []) do
mod = env.module
def __on_definition__(%{module: mod, file: file, line: line}, name, tags) do
moduletag = Module.get_attribute(mod, :moduletag)
unless moduletag do
@@ -304,7 +306,7 @@ defmodule ExUnit.Case do
(tags ++ Module.get_attribute(mod, :tag) ++ moduletag)
|> normalize_tags
|> validate_tags
|> Map.merge(%{line: env.line, file: env.file})
|> Map.merge(%{line: line, file: file})
test = %ExUnit.Test{name: name, case: mod, tags: tags}
test_names = Module.get_attribute(mod, :ex_unit_test_names)
+53 -4
View File
@@ -152,7 +152,7 @@ defmodule ExUnitTest do
refute output =~ "[debug] four"
end
test "it supports multi errors" do
test "supports multi errors" do
capture_io :stderr, fn ->
defmodule MultiTest do
use ExUnit.Case
@@ -187,7 +187,7 @@ defmodule ExUnitTest do
assert output =~ "Failure #2"
end
test "it registers only the first test with any given name" do
test "registers only the first test with any given name" do
capture_io :stderr, fn ->
defmodule TestWithSameNames do
use ExUnit.Case
@@ -207,7 +207,7 @@ defmodule ExUnitTest do
end) =~ "1 test, 0 failure"
end
test "it produces error on not implemented tests" do
test "produces error on not implemented tests" do
defmodule TestNotImplemented do
use ExUnit.Case
@@ -227,7 +227,7 @@ defmodule ExUnitTest do
assert output =~ "1 test, 1 failure"
end
test "it skips tagged test with skip" do
test "skips tagged test with skip" do
defmodule TestSkipped do
use ExUnit.Case
@@ -250,6 +250,55 @@ defmodule ExUnitTest do
assert output =~ "2 tests, 0 failures, 2 skipped"
end
test "raises on reserved tag in module" do
assert_raise RuntimeError, "cannot set tag :file because it is reserved by ExUnit", fn ->
defmodule ReservedTag do
use ExUnit.Case
setup do
{:ok, file: :foo}
end
@tag file: "oops"
test "sample", do: :ok
end
end
end
test "raises on reserved tag in setup" do
defmodule ReservedSetupTag do
use ExUnit.Case
setup do
{:ok, file: :foo}
end
test "sample", do: :ok
end
output = capture_io(fn ->
assert ExUnit.run == %{failures: 1, skipped: 0, total: 1}
end)
assert output =~ "trying to set reserved field :file"
end
test "does not raise on reserved tag in setup_all (lower priority)" do
defmodule ReservedSetupAllTag do
use ExUnit.Case
setup_all do
{:ok, file: :foo}
end
test "sample", do: :ok
end
capture_io(fn ->
assert ExUnit.run == %{failures: 0, skipped: 0, total: 1}
end)
end
defp run_with_filter(filters, {async, sync, load_us}) do
opts = Keyword.merge(ExUnit.configuration, filters)
output = capture_io fn ->
+1 -2
View File
@@ -27,9 +27,9 @@ defmodule IEx.Helpers do
* `cd/1` - changes the current directory
* `clear/0` - clears the screen
* `flush/0` - flushes all messages sent to the shell
* `i/1` - prints information about the given data type
* `h/0` - prints this help message
* `h/1` - prints help for the given module, function or macro
* `i/1` - prints information about the given data type
* `import_file/1` - evaluates the given file in the shell's context
* `l/1` - loads the given module's beam code
* `ls/0` - lists the contents of the current directory
@@ -42,7 +42,6 @@ defmodule IEx.Helpers do
* `t/1` — prints type information
* `v/0` — retrieves the last value from the history
* `v/1` — retrieves the nth value from the history
* `import_file/1` — evaluates the given file in the shell's context
Help for all of those functions can be consulted directly from
the command line using the `h` helper itself. Try:
+7 -10
View File
@@ -137,29 +137,26 @@ defmodule Mix.Compilers.Elixir do
|> List.delete(module)
|> Enum.reject(&match?("elixir_" <> _, Atom.to_string(&1)))
attributes = module.__info__(:attributes)
kind = detect_kind(attributes)
kind = detect_kind(module)
source = Path.relative_to(source, cwd)
files = get_external_resources(attributes, cwd)
files = get_external_resources(module, cwd)
tuple = {beam, module, kind, source, compile, runtime, files, binary}
Agent.cast pid, &:lists.keystore(beam, 1, &1, tuple)
end
defp detect_kind(attributes) do
defp detect_kind(module) do
cond do
impl = attributes[:impl] ->
impl = Module.get_attribute(module, :impl) ->
{:impl, impl[:protocol]}
attributes[:protocol] ->
Module.get_attribute(module, :protocol) ->
:protocol
true ->
:module
end
end
defp get_external_resources(attributes, cwd) do
for {:external_resource, values} <- attributes,
file <- values,
defp get_external_resources(module, cwd) do
for file <- Module.get_attribute(module, :external_resource),
File.regular?(file),
relative = Path.relative_to(file, cwd),
Path.type(relative) == :relative,
+30 -3
View File
@@ -100,9 +100,12 @@ defmodule Mix.Dep do
# Ensure all apps are atoms
apps = to_app_names(given)
# We need to keep the order of deps, loaded/1 properly orders them
deps = Enum.filter(all_deps, &(&1.app in apps))
deps =
if opts[:include_children] do
get_deps_with_children(all_deps, apps)
else
get_deps(all_deps, apps)
end
Enum.each apps, fn(app) ->
unless Enum.any?(all_deps, &(&1.app == app)) do
@@ -113,6 +116,30 @@ defmodule Mix.Dep do
deps
end
defp get_deps(all_deps, apps) do
Enum.filter(all_deps, &(&1.app in apps))
end
defp get_deps_with_children(all_deps, apps) do
deps = get_children(all_deps, apps)
apps = deps |> Enum.map(& &1.app) |> Enum.uniq
get_deps(all_deps, apps)
end
defp get_children(_all_deps, []), do: []
defp get_children(all_deps, apps) do
# Current deps
deps = get_deps(all_deps, apps)
# Children apps
apps = for %{deps: children} <- deps,
%{app: app} <- children,
do: app
# Current deps + children deps
deps ++ get_children(all_deps, apps)
end
@doc """
Runs the given `fun` inside the given dependency project by
changing the current working directory and loading the given
+37 -25
View File
@@ -92,15 +92,18 @@ defmodule Mix.Dep.Converger do
# In case no lock was given, we will use the local lock
# which is potentially stale. So remote.deps/2 needs to always
# check if the data it finds in the lock is actually valid.
all(main, apps, callback, rest, lock, env, fn dep ->
if cached = deps[dep.app] do
{:loaded, cached}
else
{:unloaded, dep, remote.deps(dep, lock)}
end
end)
{deps, rest, lock} =
all(main, apps, callback, rest, lock, env, fn dep ->
if cached = deps[dep.app] do
{:loaded, cached}
else
{:unloaded, dep, remote.deps(dep, lock)}
end
end)
{reject_non_fullfilled_optional(deps), rest, lock}
else
{deps, rest, lock}
{reject_non_fullfilled_optional(deps), rest, lock}
end
end
@@ -173,12 +176,12 @@ defmodule Mix.Dep.Converger do
Mix.Dep.Loader.load(dep, children)
end
dep = %{dep | deps: reject_non_fullfilled_optional(dep.deps, current_breadths)}
{acc, rest, lock} =
all(t, [dep|acc], upper_breadths, current_breadths, callback, rest, lock, env, cache)
new_breadths = Enum.map(dep.deps, &(&1.app)) ++ current_breadths
all(dep.deps, acc, current_breadths, new_breadths, callback, rest, lock, env, cache)
deps = reject_non_fullfilled_optional(dep.deps, current_breadths)
new_breadths = Enum.map(deps, &(&1.app)) ++ current_breadths
all(deps, acc, current_breadths, new_breadths, callback, rest, lock, env, cache)
end
end
@@ -213,7 +216,8 @@ defmodule Mix.Dep.Converger do
in_upper? && other_opts[:override] ->
{other |> with_matching_only(dep, in_upper?), true}
converge?(other, dep) ->
{other |> with_matching_only(dep, in_upper?) |> with_matching_req(dep) |> merge_manager(dep), true}
{other |> with_matching_only(dep, in_upper?)
|> with_matching_req(dep) |> merge_manager(dep, in_upper?), true}
true ->
tag = if in_upper?, do: :overridden, else: :diverged
{%{other | status: {tag, dep}}, true}
@@ -276,32 +280,40 @@ defmodule Mix.Dep.Converger do
end
end
defp converge?(%Mix.Dep{scm: scm1, manager: manager1, opts: opts1},
%Mix.Dep{scm: scm2, manager: manager2, opts: opts2}) do
scm1 == scm2 and
manager_equal?(manager1, manager2) and
opts_equal?(opts1, opts2) and
scm1.equal?(opts1, opts2)
defp converge?(%Mix.Dep{scm: scm1, opts: opts1}, %Mix.Dep{scm: scm2, opts: opts2}) do
scm1 == scm2 and opts_equal?(opts1, opts2) and scm1.equal?(opts1, opts2)
end
defp manager_equal?(manager, manager), do: true
defp manager_equal?(_, nil), do: true
defp manager_equal?(nil, _), do: true
defp manager_equal?(_, _), do: false
defp opts_equal?(opts1, opts2) do
keys = ~w(app env compile)a
Enum.all?(keys, &(Keyword.fetch(opts1, &1) == Keyword.fetch(opts2, &1)))
end
defp reject_non_fullfilled_optional(deps) do
apps = Enum.map(deps, & &1.app)
for dep <- deps do
update_in dep.deps, &reject_non_fullfilled_optional(&1, apps)
end
end
defp reject_non_fullfilled_optional(children, upper_breadths) do
Enum.reject children, fn %Mix.Dep{app: app, opts: opts} ->
opts[:optional] && not(app in upper_breadths)
end
end
defp merge_manager(other, dep) do
%{other | manager: other.manager || dep.manager}
defp merge_manager(%{manager: other_manager} = other, %{manager: manager}, in_upper?) do
%{other | manager: sort_manager(other_manager, manager, in_upper?)}
end
@managers [:mix, :rebar3, :rebar, :make]
defp sort_manager(other_manager, manager, true) do
other_manager || manager
end
defp sort_manager(other_manager, manager, false) do
priority = @managers -- (@managers -- (List.wrap(other_manager) ++ List.wrap(manager)))
List.first(priority) || other_manager || manager
end
defp with_matching_req(%Mix.Dep{} = other, %Mix.Dep{} = dep) do
+1 -3
View File
@@ -96,9 +96,7 @@ defmodule Mix.Dep.Fetcher do
# it for compilation too, this is our best to try to solve the
# maximum we can at each deps.get and deps.update.
if Enum.all?(all_deps, &available?/1) do
deps = (with_depending(deps, all_deps) ++
Enum.filter(all_deps, fn dep -> not ok?(dep) end))
|> Enum.uniq(&(&1.app))
deps = Enum.uniq_by(with_depending(deps, all_deps), &(&1.app))
end
# Merge the new lock on top of the old to guarantee we don't
+16
View File
@@ -236,6 +236,22 @@ defmodule Mix.Project do
Path.expand config[:deps_path]
end
@doc """
Returns the full path of all dependencies as a map.
## Examples
Mix.Project.deps_paths
#=> %{foo: "deps/foo", bar: "custom/path/dep"}
"""
@spec deps_paths() :: %{atom => Path.t}
def deps_paths do
Enum.reduce Mix.Dep.loaded(env: Mix.env), %{}, fn
%{app: app, opts: opts}, acc -> Map.put acc, app, opts[:dest]
end
end
@doc """
Returns the build path for this project.
+1
View File
@@ -21,6 +21,7 @@ defmodule Mix.Tasks.App.Start do
* `--permanent` - start the application as permanent
* `--no-compile` - do not compile even if files require compilation
* `--no-protocols` - do not load consolidated protocols
* `--no-archives-check` - do not check archives
* `--no-deps-check` - do not check dependencies
* `--no-elixir-version-check` - do not check Elixir version
* `--no-start` - do not start applications after compilation
+55
View File
@@ -0,0 +1,55 @@
defmodule Mix.Tasks.Archive.Check do
use Mix.Task
@moduledoc """
Checks all archives are available.
Mix projects can specify required archives using
the `:archives` option:
archives: [{:foo, "~> 1.0.0"}]
This task guarantees this option is respected.
"""
def run(_) do
archives = Mix.Project.config[:archives] || []
Enum.each archives, fn tuple ->
{archive, req} = parse_archive(tuple)
_ = Application.load(archive)
vsn = Application.spec(archive, :vsn)
cond do
is_nil(vsn) ->
Mix.raise "Archive \"#{archive}\" could not be found. " <>
"Please make sure the archive is installed locally."
not Version.match?(List.to_string(vsn), req) ->
Mix.raise "Archive \"#{archive}-#{vsn}\" does not match requirement #{req}. " <>
"Please update your archive version accordingly."
true ->
:ok
end
end
end
defp parse_archive({archive, req}) when is_atom(archive) and is_binary(req) do
case Version.parse_requirement(req) do
{:ok, req} ->
{archive, req}
:error ->
Mix.raise "Invalid requirement #{req} for archive \"#{archive}\""
end
end
defp parse_archive(other) do
Mix.raise """
Expected archive to be in the format:
{app :: atom, requirement :: binary}
got:
#{inspect other}
"""
end
end
+6
View File
@@ -80,6 +80,12 @@ defmodule Mix.Tasks.Compile.Erlang do
Mix.Compilers.Erlang.compile(manifest(), tuples, fn
input, _output ->
# We're purging the module because a previous compiler (e.g. Phoenix)
# might have already loaded the previous version of it.
module = Path.basename(input, ".erl") |> String.to_atom
:code.purge(module)
:code.delete(module)
file = to_erl_file(Path.rootname(input, ".erl"))
:compile.file(file, erlc_options)
end)
+6 -5
View File
@@ -41,9 +41,10 @@ defmodule Mix.Tasks.Compile do
## Command line options
* `--list` - list all enabled compilers
* `--no-deps-check` - skip checking of dependencies
* `--force` - force compilation
* `--list` - list all enabled compilers
* `--no-archives-check` - skip checking of archives
* `--no-deps-check` - skip checking of dependencies
* `--force` - force compilation
"""
@spec run(OptionParser.argv) :: :ok | :noop
@@ -127,8 +128,8 @@ defmodule Mix.Tasks.Compile do
"""
def manifests do
Enum.flat_map(compilers(), fn(compiler) ->
module = Mix.Task.get!("compile.#{compiler}")
if function_exported?(module, :manifests, 0) do
module = Mix.Task.get("compile.#{compiler}")
if module && function_exported?(module, :manifests, 0) do
module.manifests
else
[]
+5
View File
@@ -14,10 +14,15 @@ defmodule Mix.Tasks.Deps.Check do
## Command line options
* `--no-compile` - do not compile dependencies
* `--no-archives-check` - do not check archives
"""
@spec run(OptionParser.argv) :: :ok
def run(args) do
unless "--no-archives-check" in args do
Mix.Task.run "archive.check", args
end
all = Enum.map(loaded(env: Mix.env), &check_lock/1)
_ = prune_deps(all)
+25 -8
View File
@@ -6,8 +6,8 @@ defmodule Mix.Tasks.Deps.Compile do
@moduledoc """
Compiles dependencies.
By default, compile all dependencies. A list of dependencies can
be given to force the compilation of specific dependencies.
By default, compile all dependencies. A list of dependencies
can be given to force the compilation of specific dependencies.
This task attempts to detect if the project contains one of
the following files and act accordingly:
@@ -22,23 +22,35 @@ defmodule Mix.Tasks.Deps.Compile do
{:some_dependency, "0.1.0", compile: "command to compile"}
If a list of dependencies is given, Mix will attempt to compile
them as is. For example, if project `a` depends on `b`, calling
`mix deps.compile a` will compile `a` even if `b` is out of
date. This is to allow parts of the dependency tree to be
recompiled without propagating those changes upstream. To ensure
`b` is included in the compilation step, pass `--include-children`.
"""
import Mix.Dep, only: [loaded: 1, available?: 1, loaded_by_name: 2,
format_dep: 1, make?: 1, mix?: 1, rebar?: 1]
format_dep: 1, make?: 1, mix?: 1]
@switches [include_children: :boolean]
@spec run(OptionParser.argv) :: :ok
def run(args) do
unless "--no-archives-check" in args do
Mix.Task.run "archive.check", args
end
Mix.Project.get!
case OptionParser.parse(args) do
case OptionParser.parse(args, switches: @switches) do
{_, [], _} ->
# Because this command is invoked explicitly with
# Because this command may be invoked explicitly with
# deps.compile, we simply try to compile any available
# dependency.
compile(Enum.filter(loaded(env: Mix.env), &available?/1))
{_, tail, _} ->
compile(loaded_by_name(tail, env: Mix.env))
{opts, tail, _} ->
compile(loaded_by_name(tail, [env: Mix.env] ++ opts))
end
end
@@ -47,7 +59,7 @@ defmodule Mix.Tasks.Deps.Compile do
shell = Mix.shell
config = Mix.Project.deps_config
Mix.Task.run "deps.loadpaths"
Mix.Task.run "deps.precompile"
compiled =
Enum.map(deps, fn %Mix.Dep{app: app, status: status, opts: opts, scm: scm} = dep ->
@@ -100,6 +112,11 @@ defmodule Mix.Tasks.Deps.Compile do
"but you are running on v#{System.version}"
end
# Force recompilation on compile status
if dep.status == :compile do
Mix.Dep.Lock.touch_manifest
end
try do
res = Mix.Task.run("compile", ["--no-deps", "--no-elixir-version-check"])
:ok in List.wrap(res)
+6 -1
View File
@@ -9,10 +9,15 @@ defmodule Mix.Tasks.Deps.Get do
## Command line options
* `--only` - only fetch dependencies for given environment
* `--only` - only fetch dependencies for given environment
* `--no-archives-check` - do not check archives before fetching deps
"""
@spec run(OptionParser.argv) :: :ok
def run(args) do
unless "--no-archives-check" in args do
Mix.Task.run "archive.check", args
end
Mix.Project.get!
{opts, _, _} = OptionParser.parse(args, switches: [only: :string])
+19
View File
@@ -0,0 +1,19 @@
defmodule Mix.Tasks.Deps.Precompile do
use Mix.Task
@moduledoc """
Extension point for precompiling dependencies.
This is a task that can be aliased by projects
that need to execute certain tasks to before
compiling dependencies:
aliases: ["deps.precompile": ["nerves.precompile", "deps.precompile"]]
By default, this task has a single responsibility
of loading all dependencies paths.
"""
def run(_) do
Mix.Task.run "deps.loadpaths"
end
end
+5 -1
View File
@@ -13,11 +13,15 @@ defmodule Mix.Tasks.Deps.Update do
## Command line options
* `--all` - update all dependencies
* `--all` - update all dependencies
* `--only` - only fetch dependencies for given environment
* `--no-archives-check` - do not check archives before fetching deps
"""
@spec run(OptionParser.argv) :: [atom]
def run(args) do
unless "--no-archives-check" in args do
Mix.Task.run "archive.check", args
end
Mix.Project.get!
{opts, rest, _} = OptionParser.parse(args, switches: [all: :boolean, only: :string])
+2 -1
View File
@@ -6,7 +6,8 @@ defmodule Mix.Tasks.Loadpaths do
## Command line options
* `--no-deps-check` - do not check dependencies
* `--no-archives-check` - do not check archive
* `--no-deps-check` - do not check dependencies (also implies --no-archives-check)
* `--no-elixir-version-check` - do not check Elixir version
"""
+5
View File
@@ -100,6 +100,11 @@ defmodule Mix.Tasks.Test do
mix test --only line:12 test/some/particular/file_test.exs
Note that line filter takes the closest test on or before the given line number.
In the case a single file contains more than one test module (test case),
line filter applies to every test case before the given line number, thus more
than one test might be taken for the run.
## Configuration
* `:test_paths` - list of paths containing test files, defaults to
+27 -1
View File
@@ -53,6 +53,17 @@ defmodule Mix.DepTest do
end
end
test "extracts all dependencies paths from the given project" do
Mix.Project.push DepsApp
in_fixture "deps_status", fn ->
paths = Mix.Project.deps_paths
assert map_size(paths) == 6
assert paths[:ok] =~ "deps/ok"
assert paths[:uncloned] =~ "deps/uncloned"
end
end
test "fails on invalid dependencies" do
assert_wrong_dependency [{:ok}]
assert_wrong_dependency [{:ok, nil}]
@@ -144,7 +155,22 @@ defmodule Mix.DepTest do
end
end
test "nested deps convergence with optional dependencies" do
test "nested deps with convergence and managers" do
Process.put(:custom_deps_git_repo_opts, [manager: :make])
deps = [{:deps_repo, "0.1.0", path: "custom/deps_repo", manager: :rebar},
{:git_repo, "0.2.0", git: MixTest.Case.fixture_path("git_repo")}]
with_deps deps, fn ->
in_fixture "deps_status", fn ->
[dep1, dep2] = Mix.Dep.loaded([])
assert dep1.manager == nil
assert dep2.manager == :rebar
end
end
end
test "nested deps with convergence and optional dependencies" do
deps = [{:deps_repo, "0.1.0", path: "custom/deps_repo"},
{:git_repo, "0.2.0", git: MixTest.Case.fixture_path("git_repo")}]
+33
View File
@@ -132,6 +132,39 @@ defmodule Mix.Tasks.ArchiveTest do
end
end
test "archive check" do
# Install the archive
in_fixture "archive", fn() ->
Mix.Tasks.Archive.Build.run ["--no-elixir-version-check"]
send self, {:mix_shell_input, :yes?, true}
Mix.Tasks.Archive.Install.run []
end
assert_raise Mix.Error, ~r/Expected archive to be in the format/, fn ->
archive_check [:archive]
end
assert_raise Mix.Error, ~r/Archive "archive" could not be found/, fn ->
archive_check [{:archive, ">= 1.0.0"}]
end
# Load the archive
Mix.Local.append_archives
assert_raise Mix.Error, ~r/Archive \"archive-0.1.0\" does not match requirement >= 1.0.0/, fn ->
archive_check [{:archive, ">= 1.0.0"}]
end
archive_check [{:archive, ">= 0.0.0"}]
end
defp archive_check(archives) do
Mix.Project.pop
Mix.ProjectStack.post_config archives: archives
Mix.Project.push MixTest.Case.Sample
Mix.Tasks.Archive.Check.run([])
end
defp sha512(file) do
Base.encode16 :crypto.hash(:sha512, File.read!(file)), case: :lower
end
@@ -59,4 +59,25 @@ defmodule Mix.Tasks.Compile.ErlangTest do
refute File.regular?("_build/dev/lib/sample/ebin/b.beam")
end
end
test "compilation purges the module" do
in_fixture "compile_erlang", fn ->
# Create the first version of the module.
defmodule :purge_test do
def version, do: :v1
end
assert :v1 == :purge_test.version
# Create the second version of the module (this time as Erlang source).
File.write! "src/purge_test.erl", """
-module(purge_test).
-compile(export_all).
version() -> v2.
"""
assert Mix.Tasks.Compile.Erlang.run([]) == :ok
# If the module was not purged on recompilation, this would fail.
assert :v2 == :purge_test.version
end
end
end
+6
View File
@@ -26,6 +26,12 @@ defmodule Mix.Tasks.CompileTest do
assert_received {:mix_shell, :info, ["\nEnabled compilers: elixir, app, custom, protocols"]}
end
test "compile does not require all compilers available on manifest" do
Mix.Project.push CustomCompilers
assert Mix.Tasks.Compile.manifests |> Enum.map(&Path.basename/1) ==
[".compile.elixir"]
end
test "compile a project with mixfile" do
in_fixture "no_mixfile", fn ->
assert Mix.Tasks.Compile.run([]) == :ok
+17 -3
View File
@@ -133,6 +133,23 @@ defmodule Mix.Tasks.DepsGitTest do
purge [GitRepo, GitRepo.Mixfile]
end
test "compiles many levels deep dependencies" do
Mix.Project.push DepsOnGitApp
in_fixture "no_mixfile", fn ->
Mix.Tasks.Deps.Get.run []
refute File.exists?("_build/dev/lib/deps_on_git_repo")
refute File.exists?("_build/dev/lib/git_repo")
# Compile the parent with children
Mix.Tasks.Deps.Compile.run ["deps_on_git_repo", "--include-children"]
assert File.exists?("_build/dev/lib/deps_on_git_repo")
assert File.exists?("_build/dev/lib/git_repo")
end
after
purge [GitRepo, GitRepo.Mixfile]
end
test "recompiles the project when a dep is fetched" do
Mix.Project.push GitApp
@@ -146,9 +163,6 @@ defmodule Mix.Tasks.DepsGitTest do
assert_received {:mix_shell, :info, ["Compiled lib/a.ex"]}
# Clear up to prepare for the update
File.rm("_build/dev/lib/git_repo/ebin/Elixir.GitRepo.beam")
File.rm("_build/dev/lib/git_repo/.compile.elixir")
File.rm("deps/git_repo/.fetch")
Mix.Task.clear
Mix.shell.flush
purge [A, B, C, GitRepo]
+1 -1
View File
@@ -1,6 +1,6 @@
{application, elixir,
[{description, "elixir"},
{vsn, "1.2.1"},
{vsn, "1.2.4"},
{modules, [
elixir
]},