aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2015-03-12 16:13:40 +0100
committerLoïc Hoguin <[email protected]>2015-03-12 16:13:40 +0100
commit6f9b4bbc415db026f080b10a3d3d4400801882b1 (patch)
tree760275a03de406a1b05c60282dd562f53adcb594 /src
parenta8db5d9f7a21f36d4582dd083001757513e5990e (diff)
downloadcowlib-6f9b4bbc415db026f080b10a3d3d4400801882b1.tar.gz
cowlib-6f9b4bbc415db026f080b10a3d3d4400801882b1.tar.bz2
cowlib-6f9b4bbc415db026f080b10a3d3d4400801882b1.zip
Maintenance
* Update copyright years. * Update erlang.mk. * Fix triq testing.
Diffstat (limited to 'src')
-rw-r--r--src/cow_cookie.erl2
-rw-r--r--src/cow_date.erl6
-rw-r--r--src/cow_http.erl6
-rw-r--r--src/cow_http_hd.erl66
-rw-r--r--src/cow_http_te.erl7
-rw-r--r--src/cow_mimetypes.erl2
-rw-r--r--src/cow_multipart.erl12
-rw-r--r--src/cow_qs.erl10
-rw-r--r--src/cow_spdy.erl2
-rw-r--r--src/cowlib.app.src2
10 files changed, 10 insertions, 105 deletions
diff --git a/src/cow_cookie.erl b/src/cow_cookie.erl
index 02df65e..150efeb 100644
--- a/src/cow_cookie.erl
+++ b/src/cow_cookie.erl
@@ -1,4 +1,4 @@
-%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]>
+%% Copyright (c) 2013-2015, Loïc Hoguin <[email protected]>
%%
%% Permission to use, copy, modify, and/or distribute this software for any
%% purpose with or without fee is hereby granted, provided that the above
diff --git a/src/cow_date.erl b/src/cow_date.erl
index 1e54090..b805aec 100644
--- a/src/cow_date.erl
+++ b/src/cow_date.erl
@@ -1,4 +1,4 @@
-%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]>
+%% Copyright (c) 2013-2015, Loïc Hoguin <[email protected]>
%%
%% Permission to use, copy, modify, and/or distribute this software for any
%% purpose with or without fee is hereby granted, provided that the above
@@ -182,9 +182,7 @@ http_date_test_() ->
{<<"Sun Nov 6 08:49:37 1994">>, {{1994, 11, 6}, {8, 49, 37}}}
],
[{V, fun() -> R = http_date(V) end} || {V, R} <- Tests].
--endif.
--ifdef(PERF).
horse_http_date_fixdate() ->
horse:repeat(200000,
http_date(<<"Sun, 06 Nov 1994 08:49:37 GMT">>)
@@ -221,9 +219,7 @@ rfc2109_test_() ->
{<<"Sun, 01-Jan-2012 00:00:00 GMT">>, {{2012, 1, 1}, { 0, 0, 0}}}
],
[{R, fun() -> R = rfc2109(D) end} || {R, D} <- Tests].
--endif.
--ifdef(PERF).
horse_rfc2019_20130101_000000() ->
horse:repeat(100000,
rfc2109({{2013, 1, 1}, {0, 0, 0}})
diff --git a/src/cow_http.erl b/src/cow_http.erl
index 60f3faa..8f2ae92 100644
--- a/src/cow_http.erl
+++ b/src/cow_http.erl
@@ -1,4 +1,4 @@
-%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]>
+%% Copyright (c) 2013-2015, Loïc Hoguin <[email protected]>
%%
%% Permission to use, copy, modify, and/or distribute this software for any
%% purpose with or without fee is hereby granted, provided that the above
@@ -82,9 +82,7 @@ parse_status_line_error_test_() ->
],
[{V, fun() -> {'EXIT', _} = (catch parse_status_line(V)) end}
|| V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_status_line_200() ->
horse:repeat(200000,
parse_status_line(<<"HTTP/1.1 200 OK\r\n">>)
@@ -184,9 +182,7 @@ parse_headers_error_test_() ->
],
[{V, fun() -> {'EXIT', _} = (catch parse_headers(V)) end}
|| V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_headers() ->
horse:repeat(50000,
parse_headers(<<"Server: Erlang/R17\r\n"
diff --git a/src/cow_http_hd.erl b/src/cow_http_hd.erl
index b54ade6..e47d80d 100644
--- a/src/cow_http_hd.erl
+++ b/src/cow_http_hd.erl
@@ -1,4 +1,4 @@
-%% Copyright (c) 2014, Loïc Hoguin <[email protected]>
+%% Copyright (c) 2014-2015, Loïc Hoguin <[email protected]>
%%
%% Permission to use, copy, modify, and/or distribute this software for any
%% purpose with or without fee is hereby granted, provided that the above
@@ -386,9 +386,7 @@ parse_accept_error_test_() ->
<<"audio/basic;t=\"zero \\", 0, " woo\"">>
],
[{V, fun() -> {'EXIT', _} = (catch parse_accept(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_accept() ->
horse:repeat(20000,
parse_accept(<<"text/*;q=0.3, text/html;q=0.7, text/html;level=1, "
@@ -480,9 +478,7 @@ parse_accept_charset_error_test_() ->
<<>>
],
[{V, fun() -> {'EXIT', _} = (catch parse_accept_charset(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_accept_charset() ->
horse:repeat(20000,
parse_accept_charset(<<"iso-8859-5, unicode-1-1;q=0.8">>)
@@ -538,9 +534,7 @@ parse_accept_encoding_test_() ->
]}
],
[{V, fun() -> R = parse_accept_encoding(V) end} || {V, R} <- Tests].
--endif.
--ifdef(PERF).
horse_parse_accept_encoding() ->
horse:repeat(20000,
parse_accept_encoding(<<"gzip;q=1.0, identity; q=0.5, *;q=0">>)
@@ -657,9 +651,7 @@ parse_accept_language_error_test_() ->
<<"419-en-us">>
],
[{V, fun() -> {'EXIT', _} = (catch parse_accept_language(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_accept_language() ->
horse:repeat(20000,
parse_accept_language(<<"da, en-gb;q=0.8, en;q=0.7">>)
@@ -688,9 +680,7 @@ parse_accept_ranges_error_test_() ->
<<>>
],
[{V, fun() -> {'EXIT', _} = (catch parse_accept_ranges(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_accept_ranges_none() ->
horse:repeat(200000,
parse_accept_ranges(<<"none">>)
@@ -764,9 +754,7 @@ parse_allow_test_() ->
{<<"GET, HEAD, PUT">>, [<<"GET">>, <<"HEAD">>, <<"PUT">>]}
],
[{V, fun() -> R = parse_allow(V) end} || {V, R} <- Tests].
--endif.
--ifdef(PERF).
horse_parse_allow() ->
horse:repeat(200000,
parse_allow(<<"GET, HEAD, PUT">>)
@@ -863,9 +851,7 @@ parse_authorization_test_() ->
{<<"opaque">>, <<"5ccc069c403ebaf9f0171e9517f40e41">>}]}}
],
[{V, fun() -> R = parse_authorization(V) end} || {V, R} <- Tests].
--endif.
--ifdef(PERF).
horse_parse_authorization_basic() ->
horse:repeat(20000,
parse_authorization(<<"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==">>)
@@ -1014,9 +1000,7 @@ parse_cache_control_error_test_() ->
<<>>
],
[{V, fun() -> {'EXIT', _} = (catch parse_cache_control(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_cache_control_no_cache() ->
horse:repeat(200000,
parse_cache_control(<<"no-cache">>)
@@ -1078,9 +1062,7 @@ parse_connection_error_test_() ->
<<>>
],
[{V, fun() -> {'EXIT', _} = (catch parse_connection(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_connection_close() ->
horse:repeat(200000,
parse_connection(<<"close">>)
@@ -1115,9 +1097,7 @@ parse_content_encoding_error_test_() ->
<<>>
],
[{V, fun() -> {'EXIT', _} = (catch parse_content_encoding(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_content_encoding() ->
horse:repeat(200000,
parse_content_encoding(<<"gzip">>)
@@ -1403,9 +1383,7 @@ parse_content_language_error_test_() ->
<<>>
],
[{V, fun() -> {'EXIT', _} = (catch parse_content_language(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_content_language() ->
horse:repeat(100000,
parse_content_language(<<"fr, en-US, es-419, az-Arab, x-pig-latin, man-Nkoo-GN">>)
@@ -1449,9 +1427,7 @@ parse_content_length_error_test_() ->
<<"4.17">>
],
[{V, fun() -> {'EXIT', _} = (catch parse_content_length(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_content_length_zero() ->
horse:repeat(100000,
parse_content_length(<<"0">>)
@@ -1551,9 +1527,7 @@ parse_content_range_error_test_() ->
<<>>
],
[{V, fun() -> {'EXIT', _} = (catch parse_content_range(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_content_range_bytes() ->
horse:repeat(200000,
parse_content_range(<<"bytes 21010-47021/47022">>)
@@ -1666,9 +1640,7 @@ parse_content_type_test_() ->
]}}
],
[{V, fun() -> R = parse_content_type(V) end} || {V, R} <- Tests].
--endif.
--ifdef(PERF).
horse_parse_content_type() ->
horse:repeat(200000,
parse_content_type(<<"text/html;charset=utf-8">>)
@@ -1739,9 +1711,7 @@ parse_etag_error_test_() ->
<<"W/">>
],
[{V, fun() -> {'EXIT', _} = (catch parse_etag(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_etag() ->
horse:repeat(200000,
parse_etag(<<"W/\"xyzzy\"">>)
@@ -1789,9 +1759,7 @@ parse_expect_error_test_() ->
<<"Cookies">>
],
[{V, fun() -> {'EXIT', _} = (catch parse_expect(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_expect() ->
horse:repeat(200000,
parse_expect(<<"100-continue">>)
@@ -1821,9 +1789,7 @@ parse_expires_test_() ->
{<<"Thu, 01 Dec 1994 16:00:00 GMT">>, {{1994, 12, 1}, {16, 0, 0}}}
],
[{V, fun() -> R = parse_expires(V) end} || {V, R} <- Tests].
--endif.
--ifdef(PERF).
horse_parse_expires_0() ->
horse:repeat(200000,
parse_expires(<<"0">>)
@@ -1897,9 +1863,7 @@ parse_host_test_() ->
{<<"[::ffff:192.0.2.1]">>, {<<"[::ffff:192.0.2.1]">>, undefined}}
],
[{V, fun() -> R = parse_host(V) end} || {V, R} <- Tests].
--endif.
--ifdef(PERF).
horse_parse_host_blue_example_org() ->
horse:repeat(200000,
parse_host(<<"blue.example.org:8080">>)
@@ -1966,9 +1930,7 @@ parse_if_match_error_test_() ->
<<>>
],
[{V, fun() -> {'EXIT', _} = (catch parse_if_match(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_if_match() ->
horse:repeat(200000,
parse_if_match(<<"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\"">>)
@@ -2015,9 +1977,7 @@ parse_if_none_match_error_test_() ->
<<>>
],
[{V, fun() -> {'EXIT', _} = (catch parse_if_none_match(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_if_none_match() ->
horse:repeat(200000,
parse_if_none_match(<<"W/\"xyzzy\", W/\"r2d2xxxx\", W/\"c3piozzzz\"">>)
@@ -2048,9 +2008,7 @@ parse_if_range_error_test_() ->
<<>>
],
[{V, fun() -> {'EXIT', _} = (catch parse_if_range(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_if_range_etag() ->
horse:repeat(200000,
parse_if_range(<<"\"xyzzy\"">>)
@@ -2255,9 +2213,7 @@ parse_range_error_test_() ->
<<>>
],
[{V, fun() -> {'EXIT', _} = (catch parse_range(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_range_first_last() ->
horse:repeat(200000,
parse_range(<<"bytes=500-999">>)
@@ -2307,9 +2263,7 @@ parse_retry_after_error_test_() ->
<<>>
],
[{V, fun() -> {'EXIT', _} = (catch parse_retry_after(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_retry_after_date() ->
horse:repeat(200000,
parse_retry_after(<<"Fri, 31 Dec 1999 23:59:59 GMT">>)
@@ -2417,9 +2371,7 @@ parse_sec_websocket_extensions_error_test_() ->
],
[{V, fun() -> {'EXIT', _} = (catch parse_sec_websocket_extensions(V)) end}
|| V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_sec_websocket_extensions() ->
horse:repeat(200000,
parse_sec_websocket_extensions(<<"mux; max-channels=4; flow-control, deflate-stream">>)
@@ -2456,9 +2408,7 @@ parse_sec_websocket_protocol_req_error_test_() ->
],
[{V, fun() -> {'EXIT', _} = (catch parse_sec_websocket_protocol_req(V)) end}
|| V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_sec_websocket_protocol_req() ->
horse:repeat(200000,
parse_sec_websocket_protocol_req(<<"chat, superchat">>)
@@ -2494,9 +2444,7 @@ parse_sec_websocket_protocol_resp_error_test_() ->
],
[{V, fun() -> {'EXIT', _} = (catch parse_sec_websocket_protocol_resp(V)) end}
|| V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_sec_websocket_protocol_resp() ->
horse:repeat(200000,
parse_sec_websocket_protocol_resp(<<"chat">>)
@@ -2533,9 +2481,7 @@ parse_sec_websocket_version_req_error_test_() ->
],
[{V, fun() -> {'EXIT', _} = (catch parse_sec_websocket_version_req(V)) end}
|| V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_sec_websocket_version_req_13() ->
horse:repeat(200000,
parse_sec_websocket_version_req(<<"13">>)
@@ -2591,9 +2537,7 @@ parse_sec_websocket_version_resp_error_test_() ->
],
[{V, fun() -> {'EXIT', _} = (catch parse_sec_websocket_version_resp(V)) end}
|| V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_sec_websocket_version_resp() ->
horse:repeat(200000,
parse_sec_websocket_version_resp(<<"13, 8, 7">>)
@@ -2691,9 +2635,7 @@ parse_te_test_() ->
{<<"trailers, deflate;q=0.5">>, {trailers, [{<<"deflate">>, 500}]}}
],
[{V, fun() -> R = parse_te(V) end} || {V, R} <- Tests].
--endif.
--ifdef(PERF).
horse_parse_te() ->
horse:repeat(200000,
parse_te(<<"trailers, deflate;q=0.5">>)
@@ -2718,9 +2660,7 @@ parse_trailer_error_test_() ->
<<>>
],
[{V, fun() -> {'EXIT', _} = (catch parse_trailer(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_trailer() ->
horse:repeat(200000,
parse_trailer(<<"Date, Content-MD5">>)
@@ -2769,9 +2709,7 @@ parse_transfer_encoding_error_test_() ->
],
[{V, fun() -> {'EXIT', _} = (catch parse_transfer_encoding(V)) end}
|| V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_transfer_encoding_chunked() ->
horse:repeat(200000,
parse_transfer_encoding(<<"chunked">>)
@@ -3018,9 +2956,7 @@ parse_www_authenticate_error_test_() ->
<<>>
],
[{V, fun() -> {'EXIT', _} = (catch parse_www_authenticate(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_www_authenticate() ->
horse:repeat(200000,
parse_www_authenticate(<<"Newauth realm=\"apps\", type=1, title=\"Login to \\\"apps\\\"\", Basic realm=\"simple\"">>)
diff --git a/src/cow_http_te.erl b/src/cow_http_te.erl
index 5ab71f4..1e7b43f 100644
--- a/src/cow_http_te.erl
+++ b/src/cow_http_te.erl
@@ -34,7 +34,7 @@
| {done, Data::binary(), TotalLen::non_neg_integer(), Rest::binary()}.
-export_type([decode_ret/0]).
--ifdef(EXTRA).
+-ifdef(TEST).
dripfeed(<< C, Rest/bits >>, Acc, State, F) ->
case F(<< Acc/binary, C >>, State) of
more ->
@@ -92,11 +92,8 @@ stream_identity_parts_test() ->
{done, << 0:7992 >>, 2999, <<>>}
= stream_identity(<< 0:7992 >>, S2),
ok.
--endif.
--ifdef(PERF).
%% Using the same data as the chunked one for comparison.
-
horse_stream_identity() ->
horse:repeat(10000,
stream_identity(<<
@@ -296,9 +293,7 @@ stream_chunked_error_test_() ->
[{lists:flatten(io_lib:format("value ~p state ~p", [V, S])),
fun() -> {'EXIT', _} = (catch stream_chunked(V, S)) end}
|| {V, S} <- Tests].
--endif.
--ifdef(PERF).
horse_stream_chunked() ->
horse:repeat(10000,
stream_chunked(<<
diff --git a/src/cow_mimetypes.erl b/src/cow_mimetypes.erl
index 69284e1..58585b9 100644
--- a/src/cow_mimetypes.erl
+++ b/src/cow_mimetypes.erl
@@ -1,4 +1,4 @@
-%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]>
+%% Copyright (c) 2013-2015, Loïc Hoguin <[email protected]>
%%
%% Permission to use, copy, modify, and/or distribute this software for any
%% purpose with or without fee is hereby granted, provided that the above
diff --git a/src/cow_multipart.erl b/src/cow_multipart.erl
index c53cdb4..d37a7e1 100644
--- a/src/cow_multipart.erl
+++ b/src/cow_multipart.erl
@@ -1,4 +1,4 @@
-%% Copyright (c) 2014, Loïc Hoguin <[email protected]>
+%% Copyright (c) 2014-2015, Loïc Hoguin <[email protected]>
%%
%% Permission to use, copy, modify, and/or distribute this software for any
%% purpose with or without fee is hereby granted, provided that the above
@@ -362,9 +362,7 @@ parse_partial_test() ->
{ok, <<"boundary">>, <<"\r\n--">>}
= parse_body(<<"boundary\r\n--">>, <<"boundary">>),
ok.
--endif.
--ifdef(PERF).
perf_parse_multipart(Stream, Boundary) ->
case parse_headers(Stream, Boundary) of
{ok, _, Rest} ->
@@ -461,9 +459,7 @@ identity_test() ->
{done, Body2, M6} = parse_body(M5, B),
{done, Epilogue} = parse_headers(M6, B),
ok.
--endif.
--ifdef(PERF).
perf_build_multipart() ->
B = boundary(),
[
@@ -575,9 +571,7 @@ parse_content_disposition_test_() ->
{<<"file">>, [{<<"filename">>, <<"file2.gif">>}]}}
],
[{V, fun() -> R = parse_content_disposition(V) end} || {V, R} <- Tests].
--endif.
--ifdef(PERF).
horse_parse_content_disposition_attachment() ->
horse:repeat(100000,
parse_content_disposition(<<"attachment; filename=genome.jpeg;"
@@ -617,9 +611,7 @@ parse_content_transfer_encoding_test_() ->
],
[{V, fun() -> R = parse_content_transfer_encoding(V) end}
|| {V, R} <- Tests].
--endif.
--ifdef(PERF).
horse_parse_content_transfer_encoding() ->
horse:repeat(100000,
parse_content_transfer_encoding(<<"QUOTED-PRINTABLE">>)
@@ -680,9 +672,7 @@ parse_content_type_test_() ->
],
[{V, fun() -> R = parse_content_type(V) end}
|| {V, R} <- Tests].
--endif.
--ifdef(PERF).
horse_parse_content_type_zero() ->
horse:repeat(100000,
parse_content_type(<<"text/plain">>)
diff --git a/src/cow_qs.erl b/src/cow_qs.erl
index 413562b..33d385b 100644
--- a/src/cow_qs.erl
+++ b/src/cow_qs.erl
@@ -1,4 +1,4 @@
-%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]>
+%% Copyright (c) 2013-2015, Loïc Hoguin <[email protected]>
%%
%% Permission to use, copy, modify, and/or distribute this software for any
%% purpose with or without fee is hereby granted, provided that the above
@@ -126,9 +126,7 @@ parse_qs_identity_test_() ->
"b-sid=521732&ortb-xt=IAB3&ortb-ugc=">>
],
[{V, fun() -> V = qs(parse_qs(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_parse_qs_shorter() ->
horse:repeat(20000,
parse_qs(<<"hl=en&q=erlang%20cowboy">>)
@@ -310,9 +308,7 @@ qs_identity_test_() ->
[{lists:flatten(io_lib:format("~p", [V])), fun() ->
V = parse_qs(qs(V))
end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_qs_shorter() ->
horse:repeat(20000, qs(?QS_SHORTER)).
@@ -395,9 +391,7 @@ urldecode_identity_test_() ->
"%BE%8B%E3%80%9C">>
],
[{V, fun() -> V = urlencode(urldecode(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_urldecode() ->
horse:repeat(100000,
urldecode(<<"nothingnothingnothingnothing">>)
@@ -544,9 +538,7 @@ urlencode_identity_test_() ->
129,153,227,130,139,230,151,139,229,190,139,227,128,156>>
],
[{V, fun() -> V = urldecode(urlencode(V)) end} || V <- Tests].
--endif.
--ifdef(PERF).
horse_urlencode() ->
horse:repeat(100000,
urlencode(<<"nothingnothingnothingnothing">>)
diff --git a/src/cow_spdy.erl b/src/cow_spdy.erl
index 59c1ba4..ac7f0fc 100644
--- a/src/cow_spdy.erl
+++ b/src/cow_spdy.erl
@@ -1,4 +1,4 @@
-%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]>
+%% Copyright (c) 2013-2015, Loïc Hoguin <[email protected]>
%%
%% Permission to use, copy, modify, and/or distribute this software for any
%% purpose with or without fee is hereby granted, provided that the above
diff --git a/src/cowlib.app.src b/src/cowlib.app.src
index 2172075..5d358c2 100644
--- a/src/cowlib.app.src
+++ b/src/cowlib.app.src
@@ -1,4 +1,4 @@
-%% Copyright (c) 2013-2014, Loïc Hoguin <[email protected]>
+%% Copyright (c) 2013-2015, Loïc Hoguin <[email protected]>
%%
%% Permission to use, copy, modify, and/or distribute this software for any
%% purpose with or without fee is hereby granted, provided that the above