[m-rev.] for review: library grade set filters

Julien Fischer juliensf at csse.unimelb.edu.au
Mon Nov 5 17:30:28 AEDT 2007


Estimated hours taken: 4
Branches: main

Add support for filtering the set of library grades to be installed
from the command line.  This is useful, for example, if you wish to
install a library in all the trailing grades that are installed with
a particular system.  (The new options are only useful with `--make',
as the library grade set is handled externally of the compiler with Mmake.)

This change also adds some sanity checking of the library grade set
immediately after the invocation of the compiler.  Previously this
was only done at point when a library was being built in a particular
grade.  (The sanity checking is not complete, since it is not currently
possible to check whether a grade is valid or not without modifying
the option table -- something this change cannot do.)

compiler/options.m:
 	Add two new options, `--libgrades-omit-component' and
 	`--libgrades-include-component', that allow the set of library
 	grades to be installed to be filtered by component from the
 	command line.

compiler/handle_options.m:
 	Add code to post-process the library grade set and apply any
 	grade filters to that set.

 	Break some overlong lines.

 	Unrelated change: fix an XXX regarding the Erlang backend.

doc/user_guide/texi:
 	Document the new options.

 	Fix a typo: s/segement/segment/.

Julien

Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.310
diff -u -r1.310 handle_options.m
--- compiler/handle_options.m	24 Oct 2007 09:21:15 -0000	1.310
+++ compiler/handle_options.m	5 Nov 2007 06:16:27 -0000
@@ -217,8 +217,7 @@
          Target = target_c,     % dummy
          add_error("Invalid target option " ++
  % XXX When the x86_64 backend is documented modify the line below.
-% XXX When the erlang backend is documented modify the line below.
-            "(must be `c', `asm', `il', or `java')", !Errors)
+            "(must be `c', `asm', `il', `java', or `erlang')", !Errors)
      ),
      map.lookup(!.OptionTable, gc, GC_Method0),
      (
@@ -1816,8 +1815,10 @@
          globals.lookup_bool_option(!.Globals, use_subdirs, UseSubdirs),
          (
              ( UseGradeSubdirs = yes ->
-                ToMihsSubdir = (func(Dir) = ToGradeSubdir(Dir)/"Mercury"/"mihs"),
-                ToHrlsSubdir = (func(Dir) = ToGradeSubdir(Dir)/"Mercury"/"hrls")
+                ToMihsSubdir =
+                    (func(Dir) = ToGradeSubdir(Dir)/"Mercury"/"mihs"),
+                ToHrlsSubdir =
+                    (func(Dir) = ToGradeSubdir(Dir)/"Mercury"/"hrls")
              ; UseSubdirs = yes ->
                  ToMihsSubdir = (func(Dir) = Dir/"Mercury"/"mihs"),
                  ToHrlsSubdir = (func(Dir) = Dir/"Mercury"/"hrls")
@@ -1945,6 +1946,7 @@
          ;
              HighLevel = yes
          ),
+        postprocess_options_libgrades(!Globals, !Errors),
          globals.io_set_globals(!.Globals, !IO)
      ).

@@ -2139,6 +2141,132 @@
      options_help(!IO).

  %-----------------------------------------------------------------------------%
+%
+% Code for postprocessing the library grade set
+%
+
+    % Apply some sanity checks to the library grade set and then apply any
+    % library grade filters to that set.
+    %
+    % XXX we could do better with the sanity checks, currently we only
+    % check that all the grade components are valid and that there are
+    % no duplicate grade components.
+    %
+:- pred postprocess_options_libgrades(globals::in, globals::out,
+    list(string)::in, list(string)::out) is det.
+
+postprocess_options_libgrades(!Globals, !Errors) :-
+    globals.lookup_accumulating_option(!.Globals, libgrades_include_components,
+        IncludeComponentStrs),
+    globals.lookup_accumulating_option(!.Globals, libgrades_omit_components,
+        OmitComponentStrs),
+    list.foldl2(string_to_grade_component("--libgrades-include-component"),
+        IncludeComponentStrs, [], IncludeComponents, !Errors),
+    list.foldl2(string_to_grade_component("--libgrades-omit-component"),
+        OmitComponentStrs, [], OmitComponents, !Errors),
+    some [!LibGrades] (
+        globals.lookup_accumulating_option(!.Globals, libgrades, !:LibGrades),
+        %
+        % NOTE: the two calls to foldl2 here will preserve the original
+        %       relative ordering of the library grades.
+        %
+        list.foldl2(filter_grade(must_contain, IncludeComponents),
+            !.LibGrades, [], !:LibGrades, !Errors),
+        list.foldl2(filter_grade(must_not_contain, OmitComponents),
+            !.LibGrades, [], !:LibGrades, !Errors),
+        globals.set_option(libgrades, accumulating(!.LibGrades), !Globals)
+    ).
+
+    % string_to_grade_component(OptionStr, Comp, !Comps, !Errors):
+    %
+    % If `Comp' is a string that represents a valid grade component
+    % then add it to !Comps.  If it is not then emit an error message.
+    % `OptionStr' should be the name of the command line option for
+    % which the error is to be reported.
+    %
+:- pred string_to_grade_component(string::in, string::in,
+    list(string)::in, list(string)::out,
+    list(string)::in, list(string)::out) is det.
+
+string_to_grade_component(OptionStr, Comp, !Comps, !Errors) :-
+    ( grade_component_table(Comp, _, _, _, _) ->
+        !:Comps = [Comp | !.Comps]
+    ;
+        add_error("`" ++ OptionStr ++ "' unknown grade component:  "
+            ++ Comp, !Errors)
+    ).
+
+    % filter_grade(FilterPred, Components, GradeString, !Grades, !Errors):
+    % 
+    % Convert `GradeString' into a list of grade component strings, and
+    % then check whether the given grade should be filtered from the
+    % library grade set by applying the closure `FilterPred(Components)',
+    % to that list.  The grade removed from the library grade set if
+    % the application fails.
+    %
+    % Emits an error if `GradeString' cannot be converted into a list
+    % of grade component strings.
+    %
+:- pred filter_grade(pred(list(string), list(string))
+    ::in(pred(in, in) is semidet), list(string)::in,
+    string::in, list(string)::in, list(string)::out,
+    list(string)::in, list(string)::out) is det.
+
+filter_grade(FilterPred, CondComponents, GradeString, !Grades, !Errors) :-
+    grade_string_to_comp_strings(GradeString, MaybeGrade, !Errors),
+    (
+        MaybeGrade = yes(GradeComponents),
+        ( FilterPred(CondComponents, GradeComponents) ->
+            !:Grades = [GradeString | !.Grades]
+        ;
+            true
+        )
+    ;
+        MaybeGrade = no
+    ).
+
+:- pred must_contain(list(string)::in, list(string)::in) is semidet.
+
+must_contain(IncludeComponents, GradeComponents) :-
+    all [Component] ( list.member(Component, IncludeComponents) =>
+        list.member(Component, GradeComponents)
+    ).
+
+:- pred must_not_contain(list(string)::in, list(string)::in) is semidet.
+
+must_not_contain(OmitComponents, GradeComponents) :-
+    all [Component] (list.member(Component, OmitComponents) =>
+        not list.member(Component, GradeComponents)
+    ).
+
+    % Convert a grade string into a list of component strings.
+    % Emit an invalid grade error if the conversion fails.
+    %
+:- pred grade_string_to_comp_strings(string::in,
+    maybe(list(string))::out, list(string)::in, list(string)::out)
+    is det.
+
+grade_string_to_comp_strings(GradeString, MaybeGrade, !Errors) :-
+    ( 
+        split_grade_string(GradeString, ComponentStrs),
+        StrToComp = (pred(Str::in, Str::out) is semidet :-
+            grade_component_table(Str, _, _, _, _)
+        ),
+        list.map(StrToComp, ComponentStrs, Components0)
+    ->
+        list.sort_and_remove_dups(Components0, Components),
+        ( list.length(Components0) > list.length(Components) ->
+            add_error("invalid library grade: " ++ GradeString, !Errors),
+            MaybeGrade = no
+        ;
+            MaybeGrade = yes(Components)
+        )
+    ;
+        add_error("invalid library grade: " ++ GradeString, !Errors),
+        MaybeGrade = no
+    ).
+
+%-----------------------------------------------------------------------------%

      % IMPORTANT: any changes here may require similar changes to
      %   runtime/mercury_grade.h
@@ -2162,6 +2290,7 @@
      % corresponding change there. The only place where the ordering
      % actually matters is for constructing the pathname for the
      % grade of the library, etc for linking (and installation).
+    %
  :- type grade_component
      --->    comp_gcc_ext        % gcc extensions etc. -- see
                                  % grade_component_table
Index: compiler/options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.598
diff -u -r1.598 options.m
--- compiler/options.m	31 Oct 2007 03:58:28 -0000	1.598
+++ compiler/options.m	5 Nov 2007 06:16:27 -0000
@@ -826,6 +826,8 @@
      ;       install_command
      ;       install_command_dir_option
      ;       libgrades
+    ;       libgrades_include_components
+    ;       libgrades_omit_components
      ;       lib_linkages
      ;       flags_file
      ;       options_files
@@ -1618,6 +1620,8 @@
      install_command                     -   string("cp"),
      install_command_dir_option          -   string("-r"),
      libgrades                           -   accumulating([]),
+    libgrades_include_components        -   accumulating([]),
+    libgrades_omit_components           -   accumulating([]),
      lib_linkages                        -   accumulating([]),
      flags_file                          -   file_special,
      options_files                       -   accumulating(["Mercury.options"]),
@@ -2446,6 +2450,10 @@
  long_option("use-symlinks",         use_symlinks).
  long_option("library-grade",        libgrades).
  long_option("libgrade",             libgrades).
+long_option("libgrades-include-component", libgrades_include_components).
+long_option("libgrades-include",    libgrades_include_components).
+long_option("libgrades-omit-component",    libgrades_omit_components).
+long_option("libgrades-omit",       libgrades_omit_components).
  long_option("library-linkage",      lib_linkages).
  long_option("lib-linkage",          lib_linkages).
  long_option("flags",                flags_file).
@@ -4989,6 +4997,18 @@
          "--no-libgrade",
          "\tClear the list of compilation grades in which a library",
          "\tto be installed should be built.",
+        "--libgrades-include-component <component>",
+        "--libgrades-include <component>",
+        "\tFilter the list of compilation grades in which a library to",
+        "\tbe installed should be built so that it only contains grades",
+        "\tthat include the specified grade component.",
+        "\t(This option does not work with Mmake, only `--make'.)",
+        "--libgrades-omit-component <component>",
+        "--libgrades-omit <component>",
+        "\tFilter the list of compilation grades in which a library to",
+        "\tbe installed should be built so that it does not contain any",
+        "\tgrades that include the specified grade component.",
+        "\t(This option does not work with Mmake, only `--make'.)",
          "--lib-linkage {shared|static}",
          "\tSpecify whether libraries should be installed for shared",
          "\tor static linking.  This option can be specified multiple",
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.549
diff -u -r1.549 user_guide.texi
--- doc/user_guide.texi	25 Oct 2007 06:53:44 -0000	1.549
+++ doc/user_guide.texi	5 Nov 2007 06:16:27 -0000
@@ -7170,7 +7170,7 @@
  @samp{spf} (the default is to use double-precision floats)

  @item Whether to allocate a new stack segment when the limit on the old one
-is reached: @samp{stseg} (the default is not to allocate a new stack segement)
+is reached: @samp{stseg} (the default is not to allocate a new stack segment)

  @item What debugging features to enable:
  @samp{debug} and @samp{decldebug} (the default is no debugging features).
@@ -8731,6 +8731,26 @@
  building and installing the default set of grades.

  @sp 1
+ at item --libgrades-include-component @var{component}
+ at itemx --libgrades-include @var{component}
+ at findex --libgrade-include-component
+ at findex --libgrades-include
+Filter the list of compilation grades in which a library to be
+installed should be built so that it only contains grades
+that include the specified grade component.
+(This option does not work with Mmake, only @samp{--make}.)
+
+ at sp 1
+ at item --libgrades-omit-component @var{component}
+ at itemx --libgrade-omit @var{component}
+ at findex --libgrades-omit-component
+ at findex --libgrade-omit
+Filter the list of compilation grades in which a library to be
+installed should be built so that it does not contain any grades
+that include the specified grade component.
+(This option does not work with Mmake, only @samp{--make}.)
+
+ at sp 1
  @item --lib-linkage @{shared,static@}
  @findex --lib-linkage
  Specify whether libraries should be installed for shared

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list