aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2010-03-17 09:05:43 +0000
committerErlang/OTP <[email protected]>2010-03-17 09:05:43 +0000
commit4b8723ee1e17264d15cc89e26e2293605280f319 (patch)
tree8aa0abe065490667057eaafe10aac2919cc95458 /erts
parente2c29e24e0635ed729896f16c1d32fc2437371cf (diff)
parentd09c73a475ecc29b2715b92fe39bd234b3283e84 (diff)
downloadotp-4b8723ee1e17264d15cc89e26e2293605280f319.tar.gz
otp-4b8723ee1e17264d15cc89e26e2293605280f319.tar.bz2
otp-4b8723ee1e17264d15cc89e26e2293605280f319.zip
Merge branch 'hawk/escript-add-create-and-extract' into dev
* hawk/escript-add-create-and-extract: Add type info for record fields Remove the undocumented function escript:foldl/3 Make reltool independent of the function escript:foldl/3 Add functions to create and extract escripts Add function zip:foldl/3 to iterate over zip archives OTP-8521 hawk/escript-add-create-and-extract Added function zip:foldl/3 to iterate over zip archives. Added functions to create and extract escripts. See escript:create/2 and escript:extract/2. The undocumented function escript:foldl/3 has been removed. The same functionality can be achieved with the more flexible functions escript:extract/2 and zip:foldl/3. Record fields has been annotated with type info. Source files as been adapted to fit within 80 chars and trailing whitespace hasd been removed.
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/escript.xml217
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin50808 -> 50816 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin23800 -> 23808 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin44488 -> 44500 bytes
-rw-r--r--erts/preloaded/ebin/otp_ring0.beambin1436 -> 1448 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin29480 -> 29496 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin57308 -> 57320 bytes
-rw-r--r--erts/preloaded/ebin/prim_zip.beambin21756 -> 22600 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin10612 -> 10620 bytes
-rw-r--r--erts/preloaded/src/prim_zip.erl89
10 files changed, 255 insertions, 51 deletions
diff --git a/erts/doc/src/escript.xml b/erts/doc/src/escript.xml
index a89449df23..44c9a5ac68 100644
--- a/erts/doc/src/escript.xml
+++ b/erts/doc/src/escript.xml
@@ -31,7 +31,7 @@
<com>escript</com>
<comsummary>Erlang scripting support</comsummary>
<description>
- <p><c><![CDATA[escript]]></c> provides support for running short Erlang programs
+ <p><c>escript</c> provides support for running short Erlang programs
without having to compile them first and an easy way to retrieve the
command line arguments.</p>
</description>
@@ -41,10 +41,10 @@
<name>escript escript-flags script-name script-arg1 script-arg2...</name>
<fsummary>Run a script written in Erlang</fsummary>
<desc>
- <p><c><![CDATA[escript]]></c> runs a script written in Erlang.</p>
+ <p><c>escript</c> runs a script written in Erlang.</p>
<p>Here follows an example.</p>
<pre>
-$ <input>cat factorial</input>
+$ <input>cat factorial</input>
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp enable -sname factorial -mnesia debug verbose
@@ -59,11 +59,11 @@ main([String]) ->
end;
main(_) ->
usage().
-
+
usage() ->
io:format("usage: factorial integer\n"),
halt(1).
-
+
fac(0) -> 1;
fac(N) -> N * fac(N-1).
$ <input>factorial 5</input>
@@ -74,9 +74,8 @@ $ <input>factorial five</input>
usage: factorial integer </pre>
<p>The header of the Erlang script in the example differs from
a normal Erlang module. The first line is intended to be the
- interpreter line, which invokes
- <c><![CDATA[escript]]></c>. However if you invoke the
- <c><![CDATA[escript]]></c> like this</p>
+ interpreter line, which invokes <c>escript</c>. However if you
+ invoke the <c>escript</c> like this</p>
<pre>
$ <input>escript factorial 5</input> </pre>
<p>the contents of the first line does not matter, but it
@@ -93,13 +92,13 @@ $ <input>escript factorial 5</input> </pre>
%%! -smp enable -sname factorial -mnesia debug verbose</pre>
<p>Such an argument line must start with <c>%%!</c> and the
rest of the line will interpreted as arguments to the emulator.</p>
- <p>If you know the location of the <c><![CDATA[escript]]></c> executable, the first
- line can directly give the path to <c><![CDATA[escript]]></c>. For instance:</p>
+ <p>If you know the location of the <c>escript</c> executable, the first
+ line can directly give the path to <c>escript</c>. For instance:</p>
<pre>
#!/usr/local/bin/escript </pre>
<p>As any other kind of scripts, Erlang scripts will not work on
Unix platforms if the execution bit for the script file is not set.
- (Use <c><![CDATA[chmod +x script-name]]></c> to turn on the execution bit.)
+ (Use <c>chmod +x script-name</c> to turn on the execution bit.)
</p>
<p>The rest of the Erlang script file may either contain
@@ -108,33 +107,33 @@ $ <input>escript factorial 5</input> </pre>
<p>An Erlang script file must always contain the function
<em>main/1</em>. When the script is run, the
- <c><![CDATA[main/1]]></c> function will be called with a list
+ <c>main/1</c> function will be called with a list
of strings representing the arguments given to the script (not
changed or interpreted in any way).</p>
- <p>If the <c><![CDATA[main/1]]></c> function in the script returns successfully,
+ <p>If the <c>main/1</c> function in the script returns successfully,
the exit status for the script will be 0. If an exception is generated
during execution, a short message will be printed and the script terminated
with exit status 127.</p>
- <p>To return your own non-zero exit code, call <c><![CDATA[halt(ExitCode)]]></c>;
+ <p>To return your own non-zero exit code, call <c>halt(ExitCode)</c>;
for instance:</p>
<pre>
halt(1).</pre>
- <p>Call <c><![CDATA[escript:script_name/0]]></c> from your to
- script to retrieve the pathname of the script (the pathname
- is usually, but not always, absolute).</p>
+ <p>Call <seealso marker="#script_name_0">escript:script_name()</seealso>
+ from your to script to retrieve the pathname of the script
+ (the pathname is usually, but not always, absolute).</p>
<p>If the file contains source code (as in the example above),
it will be processed by the preprocessor <c>epp</c>. This
means that you for example may use pre-defined macros (such as
- <c><![CDATA[?MODULE]]></c>) as well as include directives like
- the <c><![CDATA[-include_lib]]></c> directive. For instance, use</p>
+ <c>?MODULE</c>) as well as include directives like
+ the <c>-include_lib</c> directive. For instance, use</p>
<pre>
--include_lib("kernel/include/file.hrl"). </pre>
+-include_lib("kernel/include/file.hrl").</pre>
<p>to include the record definitions for the records used by the
- <c><![CDATA[file:read_link_info/1]]></c> function.</p>
+ <c>file:read_link_info/1</c> function.</p>
<p>The script will be checked for syntactic and semantic
correctness before being run. If there are warnings (such as
@@ -144,7 +143,7 @@ halt(1).</pre>
127.</p>
<p>Both the module declaration and the export declaration of
- the <c><![CDATA[main/1]]></c> function are optional.</p>
+ the <c>main/1</c> function are optional.</p>
<p>By default, the script will be interpreted. You can force
it to be compiled by including the following line somewhere
@@ -198,6 +197,180 @@ factorial 5 = 120
</pre>
</desc>
</func>
+ <func>
+ <name>escript:create(FileOrBin, Sections) -> ok | {ok, binary()} | {error, term()}</name>
+ <fsummary>Create an escript</fsummary>
+ <type>
+ <v>FileOrBin = filename() | 'binary'</v>
+ <v>Sections = [Header] Body | Body</v>
+ <v>Header = shebang | {shebang, Shebang}
+ | comment | {comment, Comment}
+ | {emu_args, EmuArgs}</v>
+ <v>Shebang = string() | 'default' | 'undefined'</v>
+ <v>Comment = string() | 'default' | 'undefined'</v>
+ <v>EmuArgs = string() | 'undefined'</v>
+ <v>Body = {source, SourceCode}
+ | {beam, BeamCode}
+ | {archive, ZipArchive}</v>
+ <v>SourceCode = BeamCode = ZipArchive = binary()</v>
+ </type>
+ <desc>
+ <p>The <marker id="create_2"></marker> <c>create/2</c>
+ function creates an escript from a list of sections. The
+ sections can be given in any order. An escript begins with an
+ optional <c>Header</c> followed by a mandatory <c>Body</c>. If
+ the header is present, it does always begin with a
+ <c>shebang</c>, possibly followed by a <c>comment</c> and
+ <c>emu_args</c>. The <c>shebang</c> defaults to
+ <c>"/usr/bin/env escript"</c>. The comment defaults to
+ <c>"This is an -*- erlang -*- file"</c>. The created escript
+ can either be returned as a binary or written to file.</p>
+
+ <p>As an example of how the function can be used, we create an
+ interpreted escript which uses emu_args to set some emulator
+ flag. In this case it happens to disable the smp_support. We
+ do also extract the different sections from the newly created
+ script:</p>
+ <pre>
+&gt; <input>Source = "%% Demo\nmain(_Args) ->\n io:format(erlang:system_info(smp_support)).\n".</input>
+"%% Demo\nmain(_Args) ->\n io:format(erlang:system_info(smp_support)).\n"
+&gt; <input>io:format("~s\n", [Source]).</input>
+%% Demo
+main(_Args) ->
+ io:format(erlang:system_info(smp_support)).
+
+ok
+&gt; <input>{ok, Bin} = escript:create(binary, [shebang, comment, {emu_args, "-smp disable"},
+ {source, list_to_binary(Source)}]).</input>
+{ok,&lt;&lt;"#!/usr/bin/env escript\n%% This is an -*- erlang -*- file\n%%!-smp disabl"...&gt;&gt;}
+&gt; <input>file:write_file("demo.escript", Bin).</input>
+ok
+&gt; <input>os:cmd("escript demo.escript").</input>
+"false"
+&gt; <input>escript:extract("demo.escript", []).</input>
+{ok,[{shebang,default}, {comment,default}, {emu_args,"-smp disable"},
+ {source,&lt;&lt;"%% Demo\nmain(_Args) ->\n io:format(erlang:system_info(smp_su"...&gt;&gt;}]}
+ </pre>
+
+ <p>An escript without header can be created like this:</p>
+<pre>
+&gt; <input>file:write_file("demo.erl",
+ ["%% demo.erl\n-module(demo).\n-export([main/1]).\n\n", Source]).</input>
+ok
+&gt; <input>{ok, _, BeamCode} = compile:file("demo.erl", [binary, debug_info]).</input>
+{ok,demo,
+ &lt;&lt;70,79,82,49,0,0,2,208,66,69,65,77,65,116,111,109,0,0,0,
+ 79,0,0,0,9,4,100,...&gt;&gt;}
+&gt; <input>escript:create("demo.beam", [{beam, BeamCode}]).</input>
+ok
+&gt; <input>escript:extract("demo.beam", []).</input>
+{ok,[{shebang,undefined}, {comment,undefined}, {emu_args,undefined},
+ {beam,&lt;&lt;70,79,82,49,0,0,3,68,66,69,65,77,65,116,
+ 111,109,0,0,0,83,0,0,0,9,...&gt;&gt;}]}
+&gt; <input>os:cmd("escript demo.beam").</input>
+"true"
+</pre>
+ <p>Here we create an archive script containing both Erlang
+ code as well as beam code. Then we iterate over all files in
+ the archive and collect their contents and some info about
+ them.
+ </p>
+<pre>
+&gt; <input>{ok, SourceCode} = file:read_file("demo.erl").</input>
+{ok,&lt;&lt;"%% demo.erl\n-module(demo).\n-export([main/1]).\n\n%% Demo\nmain(_Arg"...&gt;&gt;}
+&gt; <input>escript:create("demo.escript",
+ [shebang,
+ {archive, [{"demo.erl", SourceCode},
+ {"demo.beam", BeamCode}], []}]).</input>
+ok
+&gt; <input>{ok, [{shebang,default}, {comment,undefined}, {emu_args,undefined},
+ {archive, ArchiveBin}]} = escript:extract("demo.escript", []).</input>
+{ok,[{shebang,default}, {comment,undefined}, {emu_args,undefined},
+ {{archive,&lt;&lt;80,75,3,4,20,0,0,0,8,0,118,7,98,60,105,
+ 152,61,93,107,0,0,0,118,0,...&gt;&gt;}]}
+&gt; <input>file:write_file("demo.zip", ArchiveBin).</input>
+ok
+&gt; <input>zip:foldl(fun(N, I, B, A) -> [{N, I(), B()} | A] end, [], "demo.zip").</input>
+{ok,[{"demo.beam",
+ {file_info,748,regular,read_write,
+ {{2010,3,2},{0,59,22}},
+ {{2010,3,2},{0,59,22}},
+ {{2010,3,2},{0,59,22}},
+ 54,1,0,0,0,0,0},
+ &lt;&lt;70,79,82,49,0,0,2,228,66,69,65,77,65,116,111,109,0,0,0,
+ 83,0,0,...&gt;&gt;},
+ {"demo.erl",
+ {file_info,118,regular,read_write,
+ {{2010,3,2},{0,59,22}},
+ {{2010,3,2},{0,59,22}},
+ {{2010,3,2},{0,59,22}},
+ 54,1,0,0,0,0,0},
+ &lt;&lt;"%% demo.erl\n-module(demo).\n-export([main/1]).\n\n%% Demo\nmain(_Arg"...&gt;&gt;}]}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>escript:extract(File, Options) -> {ok, Sections} | {error, term()}</name>
+ <fsummary>Parses an escript and extracts its sections</fsummary>
+ <type>
+ <v>File = filename()</v>
+ <v>Options = [] | [compile_source]</v>
+ <v>Sections = Headers Body</v>
+ <v>Headers = {shebang, Shebang}
+ {comment, Comment}
+ {emu_args, EmuArgs}</v>
+ <v>Shebang = string() | 'default' | 'undefined'</v>
+ <v>Comment = string() | 'default' | 'undefined'</v>
+ <v>EmuArgs = string() | 'undefined'</v>
+ <v>Body = {source, SourceCode}
+ | {source, BeamCode}
+ | {beam, BeamCode}
+ | {archive, ZipArchive}</v>
+ <v>SourceCode = BeamCode = ZipArchive = binary()</v>
+ </type>
+ <desc>
+ <p>The <marker id="extract_2"></marker> <c>extract/2</c>
+ function parses an escript and extracts its sections. This is
+ the reverse of <c>create/2</c>.</p>
+
+ <p>All sections are returned even if they do not exist in the
+ escript. If a particular section happens to have the same
+ value as the default value, the extracted value is set to the
+ atom <c>default</c>. If a section is missing, the extracted
+ value is set to the atom <c>undefined</c>. </p>
+
+ <p>The <c>compile_source</c> option only affects the result if
+ the escript contains <c>source</c> code. In that case the
+ Erlang code is automatically compiled and <c>{source,
+ BeamCode}</c> is returned instead of <c>{source,
+ SourceCode}</c>.</p>
+
+ <pre>
+&gt; <input>escript:create("demo.escript",
+ [shebang, {archive, [{"demo.erl", SourceCode},
+ {"demo.beam", BeamCode}], []}]).</input>
+ok
+&gt; <input>{ok, [{shebang,default}, {comment,undefined}, {emu_args,undefined},
+ {archive, ArchiveBin}]} =
+ escript:extract("demo.escript", []).</input>
+{ok,[{{archive,&lt;&lt;80,75,3,4,20,0,0,0,8,0,118,7,98,60,105,
+ 152,61,93,107,0,0,0,118,0,...&gt;&gt;}
+ {emu_args,undefined}]}
+ </pre>
+ </desc>
+ </func>
+ <func>
+ <name>escript:script_name() -> File</name>
+ <fsummary>Returns the name of an escript</fsummary>
+ <type>
+ <v>File = filename()</v>
+ </type>
+ <desc>
+ <p>The <marker id="script_name_0"></marker>
+ <c>script_name/0</c> function returns the name of the escript
+ being executed. If the function is invoked outside the context
+ of an escript, the behavior is undefined.</p>
+ </desc>
+ </func>
</funcs>
<section>
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index 304ac41dce..afd8a90b3f 100644
--- a/erts/preloaded/ebin/erl_prim_loader.beam
+++ b/erts/preloaded/ebin/erl_prim_loader.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam
index 21e5525b2f..4ec84948d8 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index 8ccc553c13..c3e746f3ee 100644
--- a/erts/preloaded/ebin/init.beam
+++ b/erts/preloaded/ebin/init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/otp_ring0.beam b/erts/preloaded/ebin/otp_ring0.beam
index 8ae73ea9a7..4b2d8bb2de 100644
--- a/erts/preloaded/ebin/otp_ring0.beam
+++ b/erts/preloaded/ebin/otp_ring0.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam
index 3acda843fd..2916baaa77 100644
--- a/erts/preloaded/ebin/prim_file.beam
+++ b/erts/preloaded/ebin/prim_file.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index 9457b6d360..46912e2bea 100644
--- a/erts/preloaded/ebin/prim_inet.beam
+++ b/erts/preloaded/ebin/prim_inet.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_zip.beam b/erts/preloaded/ebin/prim_zip.beam
index 6837cb4661..ccf8aff6f6 100644
--- a/erts/preloaded/ebin/prim_zip.beam
+++ b/erts/preloaded/ebin/prim_zip.beam
Binary files differ
diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam
index 4e4f85d312..ccd597ba68 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/preloaded/src/prim_zip.erl b/erts/preloaded/src/prim_zip.erl
index 3f5a5b9721..6a9856fdad 100644
--- a/erts/preloaded/src/prim_zip.erl
+++ b/erts/preloaded/src/prim_zip.erl
@@ -65,34 +65,55 @@ filter_fun() ->
open(F) ->
open(filter_fun(), undefined, F).
-open(FilterFun, FilterAcc, F) ->
- case ?CATCH do_open(FilterFun, FilterAcc, F) of
- {ok, PrimZip, Acc} ->
- {ok, PrimZip, Acc};
- Error ->
- {error, Error}
- end.
+open(FilterFun, FilterAcc, F) when is_function(FilterFun, 2) ->
+ try
+ do_open(FilterFun, FilterAcc, F)
+ catch
+ throw:{filter_fun_throw, Reason} ->
+ throw(Reason);
+ throw:InternalReason ->
+ {error, InternalReason};
+ Class:Reason ->
+ erlang:error(erlang:raise(Class, Reason, erlang:get_stacktrace()))
+ end;
+open(_, _, _) ->
+ {error, einval}.
do_open(FilterFun, FilterAcc, F) ->
Input = get_zip_input(F),
In0 = Input({open, F, [read, binary, raw]}, []),
Z = zlib:open(),
PrimZip = #primzip{files = [], zlib = Z, in = In0, input = Input},
- {PrimZip2, FilterAcc2} = get_central_dir(PrimZip, FilterFun, FilterAcc),
- {ok, PrimZip2, FilterAcc2}.
+ try
+ {PrimZip2, FilterAcc2} = get_central_dir(PrimZip, FilterFun, FilterAcc),
+ {ok, PrimZip2, FilterAcc2}
+ catch
+ Class:Reason ->
+ close(PrimZip),
+ erlang:error(erlang:raise(Class, Reason, erlang:get_stacktrace()))
+ end.
%% iterate over all files in a zip archive
-foldl(FilterFun, FilterAcc, #primzip{files = Files} = PrimZip) ->
- case ?CATCH do_foldl(FilterFun, FilterAcc, Files, [], PrimZip, PrimZip) of
- {ok, FilterAcc2, PrimZip2} -> {ok, PrimZip2, FilterAcc2};
- Error -> {error, Error}
+foldl(FilterFun, FilterAcc, #primzip{files = Files} = PrimZip)
+ when is_function(FilterFun, 2) ->
+ try
+ {ok, FilterAcc2, PrimZip2} =
+ do_foldl(FilterFun, FilterAcc, Files, [], PrimZip, PrimZip),
+ {ok, PrimZip2, FilterAcc2}
+ catch
+ throw:{filter_fun_throw, Reason} ->
+ throw(Reason);
+ throw:InternalReason ->
+ {error, InternalReason};
+ Class:Reason ->
+ erlang:error(erlang:raise(Class, Reason, erlang:get_stacktrace()))
end;
foldl(_, _, _) ->
{error, einval}.
do_foldl(FilterFun, FilterAcc, [PF | Tail], Acc0, PrimZip, PrimZipOrig) ->
#primzip_file{name = F, get_info = GetInfo, get_bin = GetBin} = PF,
- case FilterFun({F, GetInfo, GetBin}, FilterAcc) of
+ try FilterFun({F, GetInfo, GetBin}, FilterAcc) of
{Continue, Include, FilterAcc2} ->
Acc1 = include_acc(Include, PF, Acc0),
case Continue of
@@ -103,6 +124,9 @@ do_foldl(FilterFun, FilterAcc, [PF | Tail], Acc0, PrimZip, PrimZipOrig) ->
end;
FilterRes ->
throw({illegal_filter, FilterRes})
+ catch
+ throw:Reason ->
+ throw({filter_fun_throw, Reason})
end;
do_foldl(_FilterFun, FilterAcc, [], Acc, PrimZip, _PrimZipOrig) ->
{ok, FilterAcc, PrimZip#primzip{files = reverse(Acc)}}.
@@ -121,12 +145,14 @@ include_acc(Include, PF, Acc) ->
List when is_list(List) ->
%% Add new entries
Fun = fun(I, A) -> include_acc(I, PF, A) end,
- lists_foldl(Fun, Acc, List)
+ lists_foldl(Fun, Acc, List);
+ Bad ->
+ throw({illegal_filter, Bad})
end.
lists_foldl(F, Accu, [Hd|Tail]) ->
lists_foldl(F, F(Hd, Accu), Tail);
-lists_foldl(F, Accu, []) when is_function(F, 2) ->
+lists_foldl(F, Accu, []) when is_function(F, 2) ->
Accu.
%% close a zip archive
@@ -139,7 +165,9 @@ close(_) ->
get_zip_input({F, B}) when is_binary(B), is_list(F) ->
fun binary_io/2;
get_zip_input(F) when is_list(F) ->
- fun prim_file_io/2.
+ fun prim_file_io/2;
+get_zip_input(_) ->
+ throw(einval).
%% get a file from the archive
get_z_file(F, Offset, ChunkSize, #primzip{zlib = Z, in = In0, input = Input}) ->
@@ -218,15 +246,15 @@ get_cd_loop(N, BCD, Acc0, PrimZip, FileName, Offset, CFH, EndOffset, FilterFun,
GetInfo = fun() -> cd_file_header_to_file_info(FileName, CFH, <<>>) end,
GetBin = fun() -> get_z_file(FileName, Offset, Size, PrimZip) end,
PF = #primzip_file{name = FileName, get_info = GetInfo, get_bin = GetBin},
- case FilterFun({FileName, GetInfo, GetBin}, FilterAcc) of
+ try FilterFun({FileName, GetInfo, GetBin}, FilterAcc) of
{Continue, Include, FilterAcc2} ->
Acc1 =
case Include of
- false ->
+ false ->
Acc0;
true ->
[PF | Acc0];
- {true, Nick} ->
+ {true, Nick} ->
[PF#primzip_file{name = Nick} | Acc0];
{true, Nick, GI, GB} ->
PF2 = #primzip_file{name = Nick, get_info = GI, get_bin = GB},
@@ -247,13 +275,16 @@ get_cd_loop(N, BCD, Acc0, PrimZip, FileName, Offset, CFH, EndOffset, FilterFun,
end;
FilterRes ->
throw({illegal_filter, FilterRes})
+ catch
+ throw:Reason ->
+ throw({filter_fun_throw, Reason})
end.
get_file_header(BCD) ->
BCFH =
case BCD of
<<?CENTRAL_FILE_MAGIC:32/little,
- B:(?CENTRAL_FILE_HEADER_SZ-4)/binary,
+ B:(?CENTRAL_FILE_HEADER_SZ-4)/binary,
_/binary>> ->
B;
_ ->
@@ -266,11 +297,11 @@ get_file_header(BCD) ->
ToGet = FileNameLen + ExtraLen + CommentLen,
{B2, BCDRest} =
case BCD of
- <<_:?CENTRAL_FILE_HEADER_SZ/binary,
+ <<_:?CENTRAL_FILE_HEADER_SZ/binary,
G:ToGet/binary,
- Rest/binary>> ->
+ Rest/binary>> ->
{G, Rest};
- _ ->
+ _ ->
throw(bad_central_directory)
end,
FileName = get_filename_from_b2(B2, FileNameLen, ExtraLen, CommentLen),
@@ -319,9 +350,9 @@ prim_file_io({file_info, F}, _) ->
end;
prim_file_io({open, FN, Opts}, _) ->
case ?CATCH prim_file:open(FN, Opts++[binary]) of
- {ok, H} ->
+ {ok, H} ->
H;
- {error, E} ->
+ {error, E} ->
throw(E)
end;
prim_file_io({read, N}, H) ->
@@ -476,7 +507,7 @@ cd_file_header_to_file_info(FileName,
%% FI; % not yet supported, and not widely used
add_extra_info(FI, _) ->
FI.
-%%
+%%
%% unix_extra_field_and_var_from_bin(<<TSize:16/little,
%% ATime:32/little,
%% MTime:32/little,
@@ -500,7 +531,7 @@ dos_date_time_to_datetime(DosDate, DosTime) ->
<<Hour:5, Min:6, Sec:5>> = <<DosTime:16>>,
<<YearFrom1980:7, Month:4, Day:5>> = <<DosDate:16>>,
{{YearFrom1980+1980, Month, Day},
- {Hour, Min, Sec}}.
+ {Hour, Min, Sec}}.
cd_file_header_from_bin(<<VersionMadeBy:16/little,
VersionNeeded:16/little,
@@ -622,7 +653,7 @@ reverse(X) ->
reverse([H|T], Y) ->
reverse(T, [H|Y]);
-reverse([], X) ->
+reverse([], X) ->
X.
last([E|Es]) -> last(E, Es).