[m-rev.] for review: improve usage and version messages in the slice directory
Julien Fischer
jfischer at opturion.com
Sun Oct 1 16:24:22 AEDT 2023
On Sun, 1 Oct 2023, Zoltan Somogyi wrote:
> That diff of mtc_diff.m is hard to read, because it resynchronized on an "if"
> that plays different roles in the before and after versions.
> Can you please resend it with -b --patience?
Attached.
Julien.
-------------- next part --------------
diff --git a/slice/mcov.m b/slice/mcov.m
index aab3ebd..a74db7e 100644
--- a/slice/mcov.m
+++ b/slice/mcov.m
@@ -140,7 +140,8 @@ do_coverage_testing(OptionTable, Args, !IO) :-
)
;
Args = [],
- short_usage(StdOutStream, !IO)
+ short_usage(StdErrStream, !IO),
+ io.set_exit_status(1, !IO)
).
:- func kind_warning = string.
@@ -439,7 +440,7 @@ write_path_port_for_user(OutStream, port_and_path(Port, Path), !IO) :-
display_version(OutStream, !IO) :-
Version = library.mercury_version,
io.format(OutStream,
- "Mercury Coverage Testing Tool, version %s",
+ "Mercury coverage testing tool, version %s",
[s(Version)], !IO),
Package = library.package_version,
( if Package = "" then
@@ -462,13 +463,18 @@ short_usage(OutStream, !IO) :-
long_usage(OutStream, !IO) :-
io.write_string(OutStream,
- "Name: mcov - Mercury Coverage Testing Tool\n", !IO),
+ "Name: mcov - Mercury coverage testing tool\n", !IO),
write_copyright_notice(OutStream, !IO),
io.write_string(OutStream, "Usage: mcov [<options>] <arguments>\n", !IO),
- io.write_string(OutStream, "Arguments:\n", !IO),
- io.write_string(OutStream,
- "\tArguments are assumed to Mercury trace count files.\n", !IO),
- io.write_string(OutStream, "Options:\n", !IO),
+ io.write_string(OutStream, "\nDescription:\n", !IO),
+ io.write_prefixed_lines(OutStream, "\t", [
+ "`mcov' outputs a test coverage report."
+ ], !IO),
+ io.write_string(OutStream, "\nArguments:\n", !IO),
+ io.write_prefixed_lines(OutStream, "\t", [
+ "Arguments are assumed to Mercury trace count files."
+ ], !IO),
+ io.write_string(OutStream, "\nOptions:\n", !IO),
io.write_prefixed_lines(OutStream, "\t", [
"-?, -h, --help",
"\tPrint help about using mcov (on the standard output) and exit",
@@ -476,7 +482,7 @@ long_usage(OutStream, !IO) :-
"--version",
"\tPrint version information.",
"-v, --verbose",
- "\tPrint the name of each trace count file as it is added to the union",
+ "\tPrint the name of each trace count file as it is added to the union.",
"-d, --detailed",
"\tPrint a report for each label that has not been executed, even",
"\tif some other code has been executed in the same procedure.",
diff --git a/slice/mdice.m b/slice/mdice.m
index f664ca8..484d6c3 100644
--- a/slice/mdice.m
+++ b/slice/mdice.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 expandtab
%---------------------------------------------------------------------------%
% Copyright (C) 2005-2006, 2012 The University of Melbourne.
+% Copyright (C) 2015-2016, 2019-2020, 2022-2023 The Mercury team.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -29,7 +30,9 @@
:- import_module mdbcomp.slice_and_dice.
:- import_module mdbcomp.shared_utilities.
+:- import_module bool.
:- import_module getopt.
+:- import_module library.
:- import_module maybe.
:- import_module list.
:- import_module string.
@@ -44,12 +47,33 @@ main(!IO) :-
getopt.process_options(OptionOps, Args0, Args, GetoptResult),
(
GetoptResult = ok(OptionTable),
- (
- Args = [],
- usage(StdOutStream, !IO)
+ ( if lookup_bool_option(OptionTable, help, yes) then
+ long_usage(StdOutStream, !IO)
+ else if lookup_bool_option(OptionTable, version, yes) then
+ display_version(StdOutStream, !IO)
+ else
+ main_2(StdOutStream, OptionTable, Args, !IO)
+ )
;
- Args = [_],
- usage(StdOutStream, !IO)
+ GetoptResult = error(GetoptError),
+ GetoptErrorMsg = option_error_to_string(GetoptError),
+ io.stderr_stream(StdErrStream, !IO),
+ io.format(StdErrStream, "%s\n", [s(GetoptErrorMsg)], !IO),
+ io.set_exit_status(1, !IO)
+ ).
+
+:- pred main_2(io.text_output_stream::in, option_table::in, list(string)::in,
+ io::di, io::uo) is det.
+
+main_2(StdOutStream, OptionTable, Args, !IO) :-
+ (
+ ( Args = []
+ ; Args = [_]
+ ; Args = [_, _, _ | _]
+ ),
+ io.stderr_stream(StdErrStream, !IO),
+ short_usage(StdErrStream, !IO),
+ io.set_exit_status(1, !IO)
;
Args = [PassFileName, FailFileName],
lookup_string_option(OptionTable, sort, SortStr),
@@ -83,28 +107,86 @@ main(!IO) :-
io.nl(StdOutStream, !IO),
io.set_exit_status(1, !IO)
)
- ;
- Args = [_, _, _ | _],
- usage(StdOutStream, !IO)
- )
- ;
- GetoptResult = error(GetoptError),
- GetoptErrorMsg = option_error_to_string(GetoptError),
- io.format(StdOutStream, "%s\n", [s(GetoptErrorMsg)], !IO)
).
-:- pred usage(io.text_output_stream::in, io::di, io::uo) is det.
+%---------------------------------------------------------------------------%
-usage(OutStream, !IO) :-
+:- pred display_version(io.text_output_stream::in, io::di, io::uo) is det.
+
+display_version(OutStream, !IO) :-
+ Version = library.mercury_version,
+ io.format(OutStream, "Mercury dice tool, version %s",
+ [s(Version)], !IO),
+ Package = library.package_version,
+ ( if Package = "" then
+ io.nl(OutStream, !IO)
+ else
+ io.format(OutStream, " (%s)\n", [s(Package)], !IO)
+ ),
+ write_copyright_notice(OutStream, !IO).
+
+:- pred short_usage(io.text_output_stream::in, io::di, io::uo) is det.
+
+short_usage(OutStream, !IO) :-
+ io.write_strings(OutStream, [
+ "Usage: mdice [<options>] <passfile> <failfile>\n",
+ "Use `mdice --help' for more information.\n"
+ ], !IO).
+
+:- pred long_usage(io.text_output_stream::in, io::di, io::uo) is det.
+
+long_usage(OutStream, !IO) :-
+ io.write_string(OutStream, "Name: mdice - Mercury dice tool\n", !IO),
+ write_copyright_notice(OutStream, !IO),
+ io.write_string(OutStream, "\nUsage: mdice [<options>] <passfile> <failfile>\n", !IO),
+ io.write_string(OutStream, "\nDescription:\n", !IO),
+ io.write_prefixed_lines(OutStream, "\t", [
+ "`mdice' creates a comparison between passing and failing runs of a",
+ "program."
+ ], !IO),
+ io.write_string(OutStream, "\nArguments:\n", !IO),
io.write_string(OutStream,
- "Usage: mdice [-s sortspec] [-m module] [-l N] [-n N] [-p N] [-f N] "
- ++ "passfile failfile\n",
- !IO).
+ "\tArguments are assumed to Mercury trace count files.\n", !IO),
+ io.write_string(OutStream, "\nOptions:\n", !IO),
+ io.write_prefixed_lines(OutStream, "\t", [
+ "-?, -h, --help",
+ "\tPrint help about using mdice (on the standard output) and exit",
+ "\twithout doing any further processing.",
+ "--version",
+ "\tPrint version information.",
+ "-s <sortspec>, --sort <sortspec>",
+ "\tSpecify how the output should be sorted.",
+ "\t(See the Mercury User's Guide for details.)",
+ "-l <N>, --limit <N>",
+ "\tLimit the output to at most N lines.",
+ "-m <module>, --module <module>",
+ "\tRestrict the output to the given module and its submodules (if any).",
+ "-n <N>, --max-column-name <N>",
+ "\tThe maximum width of the column containing predicate names.",
+ "\tA value of zero means there is no maximum width.",
+ "-p <N>, --max-path-column <N>",
+ "\tThe maximum width of the column containing ports and goal paths.",
+ "\tA value of zero means there is no maximum width.",
+ "-f <N>, --max-file-column <N>",
+ "\tThe maximum width of the column containing file names and line numbers.",
+ "\tA value of zero means there is no maximum width."
+ ], !IO).
+
+:- pred write_copyright_notice(io.text_output_stream::in, io::di, io::uo)
+ is det.
+
+write_copyright_notice(OutStream, !IO) :-
+ io.write_strings(OutStream, [
+ "Copyright (C) 2005-2006, 2012 The University of Melbourne\n",
+ "Copyright (C) 2015-2016, 2019-2020, 2022-2023 The Mercury team\n"
+ ], !IO).
%---------------------------------------------------------------------------%
:- type option
- ---> sort
+ ---> help
+ ; version
+ ; sort
; max_row
; max_pred_column
; max_path_column
@@ -115,6 +197,8 @@ usage(OutStream, !IO) :-
:- pred short_option(character::in, option::out) is semidet.
+short_option('?', help).
+short_option('h', help).
short_option('s', sort).
short_option('l', max_row).
short_option('n', max_pred_column).
@@ -124,6 +208,8 @@ short_option('m', modulename).
:- pred long_option(string::in, option::out) is semidet.
+long_option("help", help).
+long_option("version", version).
long_option("sort", sort).
long_option("limit", max_row).
long_option("max-name-column", max_pred_column).
@@ -133,6 +219,8 @@ long_option("module", modulename).
:- pred option_default(option::out, option_data::out) is multi.
+option_default(help, bool(no)).
+option_default(version, bool(no)).
option_default(sort, string("S")).
option_default(max_row, int(100)).
option_default(max_pred_column, int(35)).
diff --git a/slice/mslice.m b/slice/mslice.m
index 72cf225..1ebe2da 100644
--- a/slice/mslice.m
+++ b/slice/mslice.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 expandtab
%---------------------------------------------------------------------------%
% Copyright (C) 2005-2006, 2012 The University of Melbourne.
+% Copyright (C) 2015-2016, 2019-2020, 2022-2023 The Mercury team.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -11,7 +12,6 @@
%---------------------------------------------------------------------------%
:- module mslice.
-
:- interface.
:- import_module io.
@@ -27,11 +27,15 @@
:- import_module mdbcomp.slice_and_dice.
:- import_module mdbcomp.shared_utilities.
+:- import_module bool.
:- import_module getopt.
+:- import_module library.
:- import_module list.
:- import_module maybe.
:- import_module string.
+%---------------------------------------------------------------------------%
+
main(!IO) :-
io.stdout_stream(StdOutStream, !IO),
unlimit_stack(!IO),
@@ -40,9 +44,31 @@ main(!IO) :-
getopt.process_options(OptionOps, Args0, Args, GetoptResult),
(
GetoptResult = ok(OptionTable),
+ ( if lookup_bool_option(OptionTable, help, yes) then
+ long_usage(StdOutStream, !IO)
+ else if lookup_bool_option(OptionTable, version, yes) then
+ display_version(StdOutStream, !IO)
+ else
+ main_2(StdOutStream, OptionTable, Args, !IO)
+ )
+ ;
+ GetoptResult = error(GetoptError),
+ GetoptErrorMsg = option_error_to_string(GetoptError),
+ io.format(StdOutStream, "%s\n", [s(GetoptErrorMsg)], !IO),
+ io.set_exit_status(1, !IO)
+ ).
+
+:- pred main_2(io.text_output_stream::in, option_table::in, list(string)::in,
+ io::di, io::uo) is det.
+
+main_2(StdOutStream, OptionTable, Args, !IO) :-
(
- Args = [],
- usage(StdOutStream, !IO)
+ ( Args = []
+ ; Args = [_, _ | _]
+ ),
+ io.stderr_stream(StdErrStream, !IO),
+ short_usage(StdErrStream, !IO),
+ io.set_exit_status(1, !IO)
;
Args = [FileName],
lookup_string_option(OptionTable, sort, SortStr),
@@ -76,28 +102,86 @@ main(!IO) :-
io.nl(StdOutStream, !IO),
io.set_exit_status(1, !IO)
)
- ;
- Args = [_, _ | _],
- usage(StdOutStream, !IO)
- )
- ;
- GetoptResult = error(GetoptError),
- GetoptErrorMsg = option_error_to_string(GetoptError),
- io.format(StdOutStream, "%s\n", [s(GetoptErrorMsg)], !IO)
).
-:- pred usage(io.text_output_stream::in, io::di, io::uo) is det.
+%---------------------------------------------------------------------------%
-usage(OutStream, !IO) :-
- io.write_string(OutStream,
- "Usage: mslice [-s sortspec] [-m module] [-l N] [-n N] [-p N] [-f N] "
- ++ "filename\n",
- !IO).
+:- pred display_version(io.text_output_stream::in, io::di, io::uo) is det.
+
+display_version(OutStream, !IO) :-
+ Version = library.mercury_version,
+ io.format(OutStream, "Mercury slice tool, version %s",
+ [s(Version)], !IO),
+ Package = library.package_version,
+ ( if Package = "" then
+ io.nl(OutStream, !IO)
+ else
+ io.format(OutStream, " (%s)\n", [s(Package)], !IO)
+ ),
+ write_copyright_notice(OutStream, !IO).
+
+:- pred short_usage(io.text_output_stream::in, io::di, io::uo) is det.
+
+short_usage(OutStream, !IO) :-
+ io.write_strings(OutStream, [
+ "Usage: mslice [<options>] <file>\n",
+ "Use `mslice --help' for more information.\n"
+ ], !IO).
+
+:- pred long_usage(io.text_output_stream::in, io::di, io::uo) is det.
+
+long_usage(OutStream, !IO) :-
+ io.write_string(OutStream, "Name: mslice - Mercury slice tool\n", !IO),
+ write_copyright_notice(OutStream, !IO),
+ io.write_string(OutStream, "\nUsage: mslice [<options>] <file>\n", !IO),
+ io.write_string(OutStream, "\nDescription:\n", !IO),
+ io.write_prefixed_lines(OutStream, "\t", [
+ "`mslice' is a tool that outputs views of program slices."
+ ], !IO),
+ io.write_string(OutStream, "\nArguments:\n", !IO),
+ io.write_prefixed_lines(OutStream, "\t", [
+ "The argument is assumed to be a Mercury trace count file."
+ ], !IO),
+ io.write_string(OutStream, "\nOptions:\n", !IO),
+ io.write_prefixed_lines(OutStream, "\t", [
+ "-?, -h, --help",
+ "\tPrint help about using mslice (on the standard output) and exit",
+ "\twithout doing any further processing.",
+ "--version",
+ "\tPrint version information.",
+ "-s <sortspec>, --sort <sortspec>",
+ "\tSpecify how the output should be sorted.",
+ "\t(See the Mercury User's Guide for details.)",
+ "-l <N>, --limit <N>",
+ "\tLimit the output to at most N lines.",
+ "-m <module>, --module <module>",
+ "\tRestrict the output to the given module and its submodules (if any).",
+ "-n <N>, --max-name-column <N>",
+ "\tThe maximum width of the column containing predicate names.",
+ "\tA value of zero means there is no maximum width.",
+ "-p <N>, --max-path-column <N>",
+ "\tThe maximum width of the column containing ports and goal paths.",
+ "\tA value of zero means there is no maximum width.",
+ "-f <N>, --max-file-column <N>",
+ "\tThe maximum width of the column containing file names and line numbers.",
+ "\tA value of zero means there is no maximum width."
+ ], !IO).
+
+:- pred write_copyright_notice(io.text_output_stream::in, io::di, io::uo)
+ is det.
+
+write_copyright_notice(OutStream, !IO) :-
+ io.write_strings(OutStream, [
+ "Copyright (C) 2005-2006, 2012 The University of Melbourne\n",
+ "Copyright (C) 2015-2016, 2019-2020, 2022-2023 The Mercury team\n"
+ ], !IO).
%---------------------------------------------------------------------------%
:- type option
- ---> sort
+ ---> help
+ ; version
+ ; sort
; max_row
; max_pred_column
; max_path_column
@@ -108,6 +192,8 @@ usage(OutStream, !IO) :-
:- pred short_option(character::in, option::out) is semidet.
+short_option('?', help).
+short_option('h', help).
short_option('s', sort).
short_option('l', max_row).
short_option('n', max_pred_column).
@@ -117,6 +203,8 @@ short_option('m', modulename).
:- pred long_option(string::in, option::out) is semidet.
+long_option("help", help).
+long_option("version", version).
long_option("sort", sort).
long_option("limit", max_row).
long_option("max-name-column", max_pred_column).
@@ -126,6 +214,8 @@ long_option("module", modulename).
:- pred option_default(option::out, option_data::out) is multi.
+option_default(help, bool(no)).
+option_default(version, bool(no)).
option_default(sort, string("C")).
option_default(max_row, int(100)).
option_default(max_pred_column, int(35)).
diff --git a/slice/mtc_diff.m b/slice/mtc_diff.m
index 71d2d27..9c55fb3 100644
--- a/slice/mtc_diff.m
+++ b/slice/mtc_diff.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 expandtab
%---------------------------------------------------------------------------%
% Copyright (C) 2006, 2012 The University of Melbourne.
+% Copyright (C) 2015-2017, 2019-2023 The Mercury team.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -29,7 +30,9 @@
:- import_module mdbcomp.shared_utilities.
:- import_module mdbcomp.trace_counts.
+:- import_module bool.
:- import_module getopt.
+:- import_module library.
:- import_module list.
:- import_module map.
:- import_module string.
@@ -45,6 +48,24 @@ main(!IO) :-
getopt.process_options(OptionOps, Args0, Args, GetoptResult),
(
GetoptResult = ok(OptionTable),
+ ( if lookup_bool_option(OptionTable, help, yes) then
+ long_usage(StdOutStream, !IO)
+ else if lookup_bool_option(OptionTable, version, yes) then
+ display_version(StdOutStream, !IO)
+ else
+ main_2(StdErrStream, OptionTable, Args, !IO)
+ )
+ ;
+ GetoptResult = error(GetoptError),
+ GetoptErrorMsg = option_error_to_string(GetoptError),
+ io.format(StdErrStream, "%s\n", [s(GetoptErrorMsg)], !IO),
+ io.set_exit_status(1, !IO)
+ ).
+
+:- pred main_2(io.text_output_stream::in, option_table::in,
+ list(string)::in, io::di, io::uo) is det.
+
+main_2(StdErrStream, OptionTable, Args, !IO) :-
lookup_string_option(OptionTable, output_filename, OutputFile),
( if
Args = [Arg1, Arg2],
@@ -77,49 +98,111 @@ main(!IO) :-
WriteResult = ok
;
WriteResult = error(WriteErrorMsg),
- io.write_string(StdErrStream, "Error writing to " ++
- "file `" ++ OutputFile ++ "'" ++ ": " ++
- string(WriteErrorMsg), !IO),
- io.nl(StdErrStream, !IO)
+ io.format(StdErrStream,
+ "Error writing to file`%s': %s\n",
+ [s(OutputFile), s(io.error_message(WriteErrorMsg))],
+ !IO),
+ io.set_exit_status(1, !IO)
)
else
% The error message has already been printed above.
true
)
else
- usage(StdOutStream, !IO)
- )
- ;
- GetoptResult = error(GetoptError),
- GetoptErrorMsg = option_error_to_string(GetoptError),
- io.format(StdOutStream, "%s\n", [s(GetoptErrorMsg)], !IO)
+ short_usage(StdErrStream, !IO),
+ io.set_exit_status(1, !IO)
).
-:- pred usage(io.text_output_stream::in, io::di, io::uo) is det.
+%---------------------------------------------------------------------------%
-usage(OutStream, !IO) :-
- io.write_string(OutStream,
- "Usage: mtc_diff -o outputfile tracecountfile1 tracecountfile2\n",
- !IO).
+:- pred display_version(io.text_output_stream::in, io::di, io::uo) is det.
+
+display_version(OutStream, !IO) :-
+ Version = library.mercury_version,
+ io.format(OutStream, "Mercury trace count diff, version %s",
+ [s(Version)], !IO),
+ Package = library.package_version,
+ ( if Package = "" then
+ io.nl(OutStream, !IO)
+ else
+ io.format(OutStream, " (%s)\n", [s(Package)], !IO)
+ ),
+ write_copyright_notice(OutStream, !IO).
+
+:- pred short_usage(io.text_output_stream::in, io::di, io::uo) is det.
+
+short_usage(OutStream, !IO) :-
+ io.progname_base("mtc_diff", ProgName, !IO),
+ io.format(OutStream,
+ "Usage: %s [<options>] <tracecountfile1> <tracecountfile2>]\n",
+ [s(ProgName)], !IO),
+ io.format(OutStream, "Use `%s --help' for more information.\n",
+ [s(ProgName)], !IO).
+
+:- pred long_usage(io.text_output_stream::in, io::di, io::uo) is det.
+
+long_usage(OutStream, !IO) :-
+ io.progname_base("mtc_diff", ProgName, !IO),
+ io.write_string(OutStream, "Name: mtc_diff - Mercury trace count diff\n", !IO),
+ write_copyright_notice(OutStream, !IO),
+ io.write_strings(OutStream, [
+ "Usage: ", ProgName, " [<options>] <tracecountfile1> <tracecountfile2>\n",
+ "\n",
+ "Description:\n"
+ ], !IO),
+ io.write_prefixed_lines(OutStream, "\t", [
+ "`mtc_diff' combines multiple trace count files into a single trace",
+ "count file."
+ ], !IO),
+ io.write_string(OutStream, "\nArguments:\n", !IO),
+ io.write_prefixed_lines(OutStream, "\t", [
+ "<files> is the trace count files that are to be combined."
+ ], !IO),
+ io.write_string(OutStream, "\nOptions:\n", !IO),
+ io.write_prefixed_lines(OutStream, "\t", [
+ "-?, -h, --help",
+ "\tPrint this usage message.",
+ "--version",
+ "\tPrint version information.",
+ "-o <file>, --out <file>",
+ "\tWrite the diff of the input trace counts to the specified file."
+ ], !IO).
+
+:- pred write_copyright_notice(io.text_output_stream::in, io::di, io::uo)
+ is det.
+
+write_copyright_notice(OutStream, !IO) :-
+ io.write_strings(OutStream, [
+ "Copyright (C) 2006-2012 The University of Melbourne\n",
+ "Copyright (C) 2013-2023 The Mercury team\n"
+ ], !IO).
%---------------------------------------------------------------------------%
:- type option
- ---> output_filename.
+ ---> help
+ ; version
+ ; output_filename.
:- type option_table == option_table(option).
:- pred short_option(character::in, option::out) is semidet.
+short_option('?', help).
+short_option('h', help).
short_option('o', output_filename).
:- pred long_option(string::in, option::out) is semidet.
+long_option("help", help).
+long_option("version", version).
long_option("out", output_filename).
:- pred option_default(option::out, option_data::out) is multi.
:- pragma no_determinism_warning(pred(option_default/2)).
+option_default(help, bool(no)).
+option_default(version, bool(no)).
option_default(output_filename, string("")).
%---------------------------------------------------------------------------%
diff --git a/slice/mtc_union.m b/slice/mtc_union.m
index 4b3c184..85bb6f1 100644
--- a/slice/mtc_union.m
+++ b/slice/mtc_union.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 expandtab
%---------------------------------------------------------------------------%
% Copyright (C) 2005-2006, 2012 The University of Melbourne.
+% Copyright (C) 2015-2016, 2019-2023 The Mercury team.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -31,6 +32,7 @@
:- import_module bool.
:- import_module getopt.
+:- import_module library.
:- import_module list.
:- import_module map.
:- import_module maybe.
@@ -48,6 +50,24 @@ main(!IO) :-
getopt.process_options(OptionOps, Args0, Args, GetoptResult),
(
GetoptResult = ok(OptionTable),
+ ( if lookup_bool_option(OptionTable, help, yes) then
+ long_usage(StdOutStream, !IO)
+ else if lookup_bool_option(OptionTable, version, yes) then
+ display_version(StdOutStream, !IO)
+ else
+ main_2(StdOutStream, StdErrStream, OptionTable, Args, !IO)
+ )
+ ;
+ GetoptResult = error(GetoptError),
+ GetoptErrorMsg = option_error_to_string(GetoptError),
+ io.format(StdErrStream, "%s\n", [s(GetoptErrorMsg)], !IO),
+ io.set_exit_status(1, !IO)
+ ).
+
+:- pred main_2(io.text_output_stream::in, io.text_output_stream::in,
+ option_table::in, list(string)::in, io::di, io::uo) is det.
+
+main_2(StdOutStream, StdErrStream, OptionTable, Args, !IO) :-
lookup_string_option(OptionTable, output_filename, OutputFile),
( if
Args = [_ | _],
@@ -76,51 +96,111 @@ main(!IO) :-
WriteResult = ok
;
WriteResult = error(WriteErrorMsg),
- io.write_string(StdErrStream,
- "Error writing to file `" ++ OutputFile ++ "'" ++
- ": " ++ string(WriteErrorMsg), !IO),
- io.nl(StdErrStream, !IO)
+ io.format(StdErrStream,
+ "Error writing to file `%s': %s\n",
+ [s(OutputFile), s(io.error_message(WriteErrorMsg))],
+ !IO),
+ io.set_exit_status(1, !IO)
)
)
else
- usage(StdOutStream, !IO)
- )
- ;
- GetoptResult = error(GetoptError),
- GetoptErrorMsg = option_error_to_string(GetoptError),
- io.format(StdOutStream, "%s\n", [s(GetoptErrorMsg)], !IO)
+ short_usage(StdErrStream, !IO),
+ io.set_exit_status(1, !IO)
).
-:- pred usage(io.text_output_stream::in, io::di, io::uo) is det.
+%---------------------------------------------------------------------------%
-usage(OutStream, !IO) :-
+:- pred display_version(io.text_output_stream::in, io::di, io::uo) is det.
+
+display_version(OutStream, !IO) :-
+ Version = library.mercury_version,
+ io.format(OutStream, "Mercury trace count union, version %s",
+ [s(Version)], !IO),
+ Package = library.package_version,
+ ( if Package = "" then
+ io.nl(OutStream, !IO)
+ else
+ io.format(OutStream, " (%s)\n", [s(Package)], !IO)
+ ),
+ write_copyright_notice(OutStream, !IO).
+
+:- pred short_usage(io.text_output_stream::in, io::di, io::uo) is det.
+
+short_usage(OutStream, !IO) :-
+ io.progname_base("mtc_union", ProgName, !IO),
+ io.format(OutStream, "Usage: %s [<options>] [<files>]\n",
+ [s(ProgName)], !IO),
+ io.format(OutStream, "Use `%s --help' for more information.\n",
+ [s(ProgName)], !IO).
+
+:- pred long_usage(io.text_output_stream::in, io::di, io::uo) is det.
+
+long_usage(OutStream, !IO) :-
+ io.progname_base("mtc_union", ProgName, !IO),
+ io.write_string(OutStream, "Name: mtc_union - Mercury trace count union\n", !IO),
+ write_copyright_notice(OutStream, !IO),
+ io.write_strings(OutStream, [
+ "Usage: ", ProgName, " [<options>] [<files>]\n",
+ "\n",
+ "Description:\n"
+ ], !IO),
+ io.write_prefixed_lines(OutStream, "\t", [
+ "`mtc_union' combines multiple trace count files into a single trace",
+ "count file."
+ ], !IO),
+ io.write_string(OutStream, "\nArguments:\n", !IO),
+ io.write_prefixed_lines(OutStream, "\t", [
+ "<files> is the trace count files that are to be combined."
+ ], !IO),
+ io.write_string(OutStream, "\nOptions:\n", !IO),
+ io.write_prefixed_lines(OutStream, "\t", [
+ "-?, -h, --help",
+ "\tPrint this usage message.",
+ "--version",
+ "\tPrint version information.",
+ "-v, --verbose",
+ "\tPrint the name of each trace count file as it is added to the union",
+ "-o <file>, --out <file>",
+ "\tWrite the union of the input trace counts to the specified file."
+ ], !IO).
+
+:- pred write_copyright_notice(io.text_output_stream::in, io::di, io::uo)
+ is det.
+
+write_copyright_notice(OutStream, !IO) :-
io.write_strings(OutStream, [
- "Usage: mtc_union [-v] -o output_file file1 file2 ...\n",
- "The -v or --verbose option causes each trace count file name\n",
- "to be printed as it is added to the union.\n",
- "file1, file2, etc should be trace count files.\n"],
- !IO).
+ "Copyright (C) 2005-2012 The University of Melbourne\n",
+ "Copyright (C) 2013-2023 The Mercury team\n"
+ ], !IO).
%---------------------------------------------------------------------------%
:- type option
- ---> output_filename
+ ---> help
+ ; version
+ ; output_filename
; verbose.
:- type option_table == option_table(option).
:- pred short_option(character::in, option::out) is semidet.
+short_option('?', help).
+short_option('h', help).
short_option('o', output_filename).
short_option('v', verbose).
:- pred long_option(string::in, option::out) is semidet.
+long_option("help", help).
+long_option("version", version).
long_option("out", output_filename).
long_option("verbose", verbose).
:- pred option_default(option::out, option_data::out) is multi.
+option_default(help, bool(no)).
+option_default(version, bool(no)).
option_default(output_filename, string("")).
option_default(verbose, bool(no)).
More information about the reviews
mailing list