for review: add nested modules [5/5]

Fergus Henderson fjh at cs.mu.OZ.AU
Thu Feb 26 16:33:20 AEDT 1998


+	io__write_string("/"),
 	{ pred_info_arity(PredInfo, Arity) },
 	io__write_int(Arity),
-	io__write_string(":\n"),
+	io__write_string("':\n"),
 	prog_out__write_context(Context),
 	io__write_string("  warning: "),   
 	(
Index: compiler/vn_debug.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_debug.m,v
retrieving revision 1.29
diff -u -u -r1.29 vn_debug.m
--- vn_debug.m	1998/01/23 12:57:06	1.29
+++ vn_debug.m	1998/02/25 02:09:25
@@ -14,8 +14,8 @@
 
 :- interface.
 
-:- import_module atsort, vn_type, vn_table, livemap.
-:- import_module assoc_list, bool, list, io.
+:- import_module atsort, vn_type, vn_table, llds, livemap.
+:- import_module assoc_list, bool, list, std_util, io.
 
 :- pred vn_debug__tuple_msg(maybe(bool), list(instruction), vn_ctrl_tuple,
 	io__state, io__state).
@@ -95,8 +95,8 @@
 
 :- implementation.
 
-:- import_module llds, llds_out, globals, options, opt_debug.
-:- import_module string, int, std_util, map.
+:- import_module llds_out, globals, options, opt_debug.
+:- import_module string, int, map.
 
 vn_debug__tuple_msg(Intermediate, Instrs, Tuple) -->
 	vn_debug__tuple_msg_flag(Flag),
Index: compiler/vn_order.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_order.m,v
retrieving revision 1.45
diff -u -u -r1.45 vn_order.m
--- vn_order.m	1998/01/13 10:14:15	1.45
+++ vn_order.m	1998/02/25 02:07:04
@@ -15,7 +15,7 @@
 :- interface.
 
 :- import_module llds, vn_type, vn_table.
-:- import_module bool, list.
+:- import_module bool, list, std_util.
 
 :- type order_result	--->	success(vn_tables, list(vn_node))
 			;	failure(maybe(label)).
@@ -28,7 +28,7 @@
 
 :- implementation.
 
-:- import_module map, set, string, int, require, std_util, assoc_list.
+:- import_module map, set, string, int, require, assoc_list.
 
 :- import_module atsort, vn_util, vn_debug, opt_util.
 
Index: compiler/vn_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_util.m,v
retrieving revision 1.60
diff -u -u -r1.60 vn_util.m
--- vn_util.m	1998/01/13 10:14:21	1.60
+++ vn_util.m	1998/02/25 02:13:22
@@ -14,7 +14,7 @@
 
 :- interface.
 
-:- import_module list.
+:- import_module list, bool, std_util.
 :- import_module llds, vn_type, vn_table.
 
 %-----------------------------------------------------------------------------%
@@ -33,7 +33,7 @@
 
 :- implementation.
 
-:- import_module bool, int, float, string, set, map, require, std_util.
+:- import_module int, float, string, set, map, require.
 
 :- import_module opt_util.
 
cvs diff: Diffing compiler/notes
cvs diff: Diffing doc
Index: doc/reference_manual.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.86
diff -u -u -r1.86 reference_manual.texi
--- reference_manual.texi	1998/02/05 13:33:40	1.86
+++ reference_manual.texi	1998/02/25 23:56:48
@@ -344,7 +344,7 @@
 :- implementation
 :- import_module
 :- use_module
-:- external
+:- include_module
 :- end_module
 @end example
 
@@ -896,10 +896,8 @@
 Each discriminated union type definition introduces a distinct type.
 Mercury considers two discriminated union types that have the same bodies
 to be distinct types (name equivalence).
-Having two different types with the same name and arity in the program
-is an error.
-(We hope to relax this in the future, to allow types with the same name
-and arity in different modules.)
+Having two different definitions of a type with the same name and arity in
+the same module is an error.
 
 @item
 Equivalence types: these are type abbreviations.
@@ -945,8 +943,8 @@
 Constructors may be overloaded among different types:
 there may be any number of constructors with a given name and arity,
 so long as they all have different types.
-However, there must be only one constructor
-with a given name, arity, and result type.
+However, there must not be more than one constructor
+with the same name, arity, and result type in the same module.
 (There is no particularly good reason for this restriction;
 in the future we may allow several such functors
 as long as they have different argument types.)
@@ -969,6 +967,7 @@
 
 There must only be one predicate with a given name and arity in each module,
 and only one function with a given name and arity in each module.
+It is an error to declare the same predicate or function twice.
 
 The compiler infers the types of data-terms, and in particular the types
 of variables and overloaded constructors, functions, and predicates.
@@ -1163,6 +1162,10 @@
 :- mode create_request :: out(request).
 @end example
 
+There must not be more than one inst definition with the same name
+and arity in the same module.  Similarly, there must not be more
+than one mode definition with the same name and arity in the same module.
+
 A @dfn{predicate mode declaration}
 assigns a mode mapping to each argument of a predicate.
 A @dfn{function mode declaration}
@@ -2069,7 +2072,7 @@
 closures, and lambda expressions. 
 (To be pedantic, it would be more accurate to
 say that Mercury supports higher-order procedures: in Mercury, when you
-construct a higher-order predicate term, you only get one mode of
+construct a higher-order term, you only get one mode of
 a predicate or function; if you want multiple modes, you must pass multiple
 higher-order procedures.)
 
@@ -2437,32 +2440,55 @@
 @node Modules
 @chapter Modules
 
-The Mercury module system is simple and straightforward. 
-Each module must start with a @code{module} declaration,
-specifying the name of the module. 
-An @code{interface} declaration specifies
+ at menu
+* The module system::
+* An example module::
+* Sub-modules::
+ at end menu
+
+ at node The module system
+ at section The module system
+
+The Mercury module system is relatively simple and straightforward. 
+
+Each module must start with a @samp{:- module @var{ModuleName}}
+declaration, specifying the name of the module. 
+
+A @samp{:- interface.} declaration indicates
 the start of the module's interface section:
-this section contains declarations for the types, typeclasses, typeclass
-instances, data constructors, instantiation states, modes, functions and
-predicates exported by this module.
-Mercury provides support for abstract data types,
-since the definition of a type may be kept hidden,
-with only the type name being exported.  
-An @code{implementation} declaration specifies
+this section specifies the entities that are exported by this module.
+Mercury provides support for abstract data types, since the
+definition of a type may be kept hidden, with only the type
+name being exported.
+The interface section can contain declarations or definitions of types,
+definitions of typeclasses, typeclass instances, data constructors,
+instantiation states, and modes,
+and declarations for functions, predicates, and (sub-)modules.
+The interface section may not contain definitions for functions or
+predicates (i.e. clauses), or definitions of (sub-)modules. 
+
+A @samp{:- implementation.} declaration indicates
 the start of the module's implementation section. 
 Any entities declared in this section are local to the module
-and cannot be used by other modules.
-The implementation section must of course contain definitions
-for all abstract data types, functions and predicates exported by the module,
-as well for all local types, functions and predicates.
-The module may optionally end with an @code{end_module} declaration.
+(and its sub-modules) and cannot be used by other modules.
+The implementation section must contain definitions
+for all abstract data types, functions, predicates, and
+sub-modules exported by the module,
+as well for all local types, functions, predicates, and sub-modules.
+The implementation section can be omitted if it is empty.
+
+The module may optionally end with a @samp{:- end_module @var{ModuleName}}
+declaration; the name specified in the @samp{end_module} be the
+same as that in the corresponding @samp{module} declaration.
 
- at c XXX should we mention multipart interfaces and implementations?
+ at c should we mention multipart interfaces and implementations?
 @c ===> no
 
 If a module wishes to make use of entities exported by other modules,
 then it must explicitly import those modules using one or more 
- at code{import_module} or @code{use_module} declarations.
+ at samp{:- import_module @var{Modules}} or @samp{:- use_module @var{Modules}}
+declarations.  In both cases, @var{Modules} is a comma-separated list of
+(fully-qualified) module names.
 These declarations may occur either in the interface or the implementation 
 section.  If the imported entities are used in the interface section,
 then the corresponding @code{import_module} or @code{use_module}
@@ -2471,11 +2497,12 @@
 @code{import_module} or @code{use_module} declaration should be in 
 the implementation section.
 
-The names of predicates, functions, constructors, types, modes and insts
-can be explicitly module qualified using the @samp{:} operator,
-i.e. @samp{module:name}.  This is useful both for readability and
-for resolving name conflicts.  Uses of entities imported using 
- at code{use_module} declarations @emph{must} be explicitly module qualified.
+The names of predicates, functions, constructors, types, modes, insts,
+and (sub-)modules can be explicitly module qualified using the @samp{:}
+operator, e.g. @samp{module:name} or @samp{module:submodule:name}.
+This is useful both for readability and for resolving name conflicts.
+Uses of entities imported using @code{use_module} declarations
+ at emph{must} be explicitly module qualified.
 
 Currently we also support @samp{__} as an alternative module qualifier,
 so you can write @code{module__name} instead of @code{module:name}.
@@ -2489,7 +2516,7 @@
 inlining and higher-order specialization are the only optimizations that
 the Mercury compiler can perform across module boundaries.
 
-One module must export a predicate @samp{main}, which
+One module must export a predicate @samp{main/2}, which
 must be declared as either
 
 @example
@@ -2506,7 +2533,17 @@
 @noindent
 (or any declaration equivalent to one of the two above).
 
-For example, here is the definition of a simple module for managing queues:
+Mercury has a standard library which includes modules for
+lists, stacks, queues, priority queues, sets, bags (multi-sets),
+maps (dictionaries), random number generation, input/output
+and filename and directory handling. 
+See the Mercury Library Reference Manual for details.
+
+ at node An example module
+ at section An example module.
+
+For illustrative purposes, here is the definition of a
+simple module for managing queues:
 
 @example
 :- module queue.
@@ -2554,19 +2591,117 @@
 
 @end example
 
-Mercury has a standard library which includes modules for
-lists, stacks, queues, priority queues, sets, bags (multi-sets),
-maps (dictionaries), random number generation, input/output
-and filename and directory handling. 
-See the Mercury Library Reference Manual for details.
+ at node Sub-modules
+ at section Sub-modules
+
+As mentioned above, modules may contain sub-modules.
+There are two kinds of sub-modules, called nested sub-modules
+and separate sub-modules; the difference is that nested sub-modules
+are defined in the same source file as the containing module,
+whereas separate sub-modules are defined in separate source files.
+Implementations should support separate compilation of separate sub-modules.
 
-The Mercury standard library has a standard naming convention in which
-every entity exported by a module is prefixed by the module name and
-two underscores.  We have found this convention improves the
-readability and maintainability of our code, and so we recommend that
-you follow it in your code too.  (Eventually, these names will be converted
-to names of the form @code{module.name}; this will allow you to omit the
-prefix in places where it does not improve readability.)
+A module may not contain more than one sub-module with the same name.
+
+ at menu
+* Nested sub-modules::
+* Separate sub-modules::
+* Visibility rules::
+* Implementation bugs and limitations::
+ at end menu
+
+ at node Nested sub-modules
+ at subsection Nested sub-modules
+
+Nested sub-modules within an module are delimited by
+matching @samp{:- module} and @samp{:- end_module} declarations.
+(Note that @samp{:- end_module} for nested sub-modules 
+are mandatory, not optional, even if the nested sub-module
+is the last thing in the source file.
+Also note that the module name in a @samp{:- module} declaration
+need not be fully-qualified.)
+The sequence of items thus delimited is known as a nested sub-module
+declaration.
+
+The interface and implementation parts of a nested sub-module
+may be specified in two different sub-module declarations.
+If a nested sub-module declaration includes an interface section,
+then it is a declaration of that sub-module;
+if it includes an implementation section,
+then it is a definition of that sub-module;
+and if includes both, then it is both declaration and definition.
+
+It is an error to declare a sub-module twice, or to define it twice.
+It is an error to define a sub-module without declaring it.
+If a sub-module is declared but not explicitly defined,
+then there is an implicit definition with an empty implementation section
+for that sub-module (this will result in an error, if the interface
+section includes declarations but not definitions for any types,
+preds, modes, or (doubly) nested sub-modules).
+
+ at node Separate sub-modules
+ at subsection Separate sub-modules
+
+Separate sub-modules are declared using
+ at samp{:- include_module @var{Modules}} declarations.
+Each @samp{:- include_module} declaration specifies a comma-separated list
+of sub-modules.
+
+ at example
+:- include_module @var{Module1}, @var{Module2}, @dots{}, @var{ModuleN}.
+ at end example
+
+Each of the named sub-modules in a @samp{:- include_module} declaration
+must be defined in a separate source file.
+The mapping between module names and source file names is
+implementation-defined.  (The University of Melbourne Mercury
+implementation requires a module named @samp{foo:bar:baz} to be
+located in source file @file{foo.bar.baz.m}.)
+The separate source source must contain the definition of
+the sub-module, starting with a @samp{:- module} declaration
+which matches that in the @samp{:- include_module} declaration
+in the parent, and optionally ending in a @samp{:- end_module}
+declaration.  (Note: the module names in the @samp{:- module}
+and @samp{:- end_module} declaration need not be fully-qualified.)
+
+If a @samp{:- include_module} declaration occurs in the interface
+section of a module, then only the interfaces of the sub-modules
+are included in the parent module's interface; the implementations
+of the sub-modules are considered to be implicitly part of the
+parent module's implementation.
+
+Apart from that, the semantics of separate sub-modules are
+identical to those of nested sub-modules.
+
+ at node Visibility rules
+ at subsection Visibility rules
+
+Any declarations in the parent module, including those in the
+parent module's implementation section, are visible in the parent's
+sub-modules, including indirect sub-modules (i.e. sub-sub-modules, etc.).
+Similarly, declarations in the interfaces of any modules imported using a
+ at samp{:- import_module} or a @samp{:- use_module} in the parent module
+are visible in the parent's sub-modules, including indirect sub-modules.
+However, declarations in a child module are not visible in the parent
+module or in "sibling" modules (other children of the same parent)
+unless the child is explicitly imported using a @samp{:- import_module}
+or @samp{:- use_module} declaration.
+
+ at node Implementation bugs and limitations
+ at subsection Implementation bugs and limitations
+
+The current implementation of sub-modules is incomplete. 
+In particular:
+
+ at itemize @bullet
+ at item it supports only separate sub-modules, not nested sub-modules; 
+ at item module qualifiers must use the fully-qualified module name; 
+ at item the compiler doesn't check that the parent module is imported/used
+      before allowing import/use of its sub-modules;
+ at item it doesn't check that there is an include_module declaration in the
+	parent for each module claiming to be a child of that parent;
+ at item privacy of private sub-modules is not enforced
+ at end itemize
 
 @node Type classes
 @chapter Type classes
@@ -2624,7 +2759,10 @@
 :- typeclass a(T1, T2) where [@dots{}].
 @end example
 
-The only restriction is that the parameters be distinct variables.
+The parameters must be distinct variables.
+
+There must not be more than one typeclass declaration with the
+same name and arity in the same module.
 
 @node Instance declarations
 @section Instance declarations
@@ -2639,7 +2777,6 @@
 a polymorphic type whose arguments are all distinct type variables.  e.g. 
 @code{int}, @code{list(T)} and @code{map(K,V)} are allowed but
 @code{T}, @code{list(int)} and @code{map(T,T)} are not.
-
 A program may not contain more than one @code{instance} declaration for a
 particular type (or set of types, in the case of a multi-parameter
 typeclass).  These restrictions ensure that there are no overlapping instance
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.117
diff -u -u -r1.117 user_guide.texi
--- user_guide.texi	1998/02/09 10:24:08	1.117
+++ user_guide.texi	1998/02/17 14:35:39
@@ -128,10 +128,11 @@
 whose name should be the same as the filename without
 the @samp{.m} extension.
 
-Files ending in @file{.int}, @file{.int2} and @file{.int3} are interface files;
-these are generated automatically by the compiler,
-using the @samp{--make-interface} (or @samp{--make-int})
-and @samp{--make-short-interface} (or @samp{--make-short-int}) options.
+Files ending in @file{.int}, @file{.int0}, @file{.int2} and @file{.int3}
+are interface files; these are generated automatically by the compiler,
+using the @samp{--make-interface} (or @samp{--make-int}),
+ at samp{--make-private-interface} (or @samp{--make-priv-int}),
+ at samp{--make-short-interface} (or @samp{--make-short-int}) options.
 Files ending in @file{.opt} are
 interface files used in inter-module optimization,
 and are created using the @samp{--make-optimization-interface}
@@ -142,11 +143,12 @@
 (or @samp{--make-trans-opt-int}) option.
 
 Since the interface of a module changes less often than its implementation,
-the @file{.int}, @file{.int2}, @file{.int3}, @file{.opt}, and @file{.trans_opt}
-files will remain unchanged on many compilations.
+the @file{.int}, @file{.int0}, @file{.int2}, @file{.int3}, @file{.opt},
+and @file{.trans_opt} files will remain unchanged on many compilations.
 To avoid unnecessary recompilations of the clients of the module,
 the timestamps on the these files are updated only if their contents change.
- at file{.date}, @file{.date3}, @file{.optdate}, and @file{.trans_opt_date}
+ at file{.date}, @file{.date0}, @file{.date3}, @file{.optdate},
+and @file{.trans_opt_date}
 files associated with the module are used as date stamps;
 they are used when deciding whether the interface files need to be regenerated.
 
@@ -807,9 +809,10 @@
 @item @var{main-module}.realclean
 Removes all the automatically generated files.
 In addition to the files removed by @var{main-module}.clean, this
-removes the @samp{.date}, @samp{.int}, @samp{.int2}, @samp{.int3},
- at samp{.opt}, @samp{.optdate}, @samp{.date3},
- at samp{.trans_opt}, @samp{.trans_opt_date},
+removes the @samp{.int}, @samp{.int0}, @samp{.int2},
+ at samp{.int3}, @samp{.opt}, @samp{.trans_opt},
+ at samp{.date}, @samp{.date0}, @samp{.date3}, @samp{.optdate},
+ at samp{.trans_opt_date},
 @samp{.d}, and @samp{.dep} belonging to one of the modules of the program,
 and also the various possible executables for the program ---
 @samp{@var{main-module}},
@@ -1589,6 +1592,12 @@
 @itemx --make-short-interface
 Write the unqualified version of the short interface to
 @file{@var{module}.int3}.
+
+ at sp 1
+ at item --make-priv-int
+ at itemx --make-private-interface
+Write the module's private interface (used for compiling
+nested sub-modules) to @file{@var{module}.int0}.
 
 @sp 1
 @item --make-opt-int
cvs diff: Diffing extras
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/clpr
cvs diff: Diffing extras/clpr/clpr
cvs diff: Diffing extras/clpr/samples
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/Togl-1.2
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/references
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing library
Index: library/graph.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/graph.m,v
retrieving revision 1.18
diff -u -u -r1.18 graph.m
--- graph.m	1998/01/27 15:25:35	1.18
+++ graph.m	1998/02/19 05:56:18
@@ -18,7 +18,7 @@
 :- module graph.
 
 :- interface.
-:- import_module set, std_util.
+:- import_module list, set, std_util.
 
 	% graph(Node, Arc) represents a directed graph with information of
 	% type Node associated with each node, and information of type Arc
Index: library/lexer.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/lexer.m,v
retrieving revision 1.28
diff -u -u -r1.28 lexer.m
--- lexer.m	1998/01/13 09:47:14	1.28
+++ lexer.m	1998/02/19 05:52:20
@@ -17,7 +17,7 @@
 
 :- module lexer.
 :- interface.
-:- import_module io.
+:- import_module io, char.
 
 :- type	token
 	--->	name(string)
@@ -72,7 +72,7 @@
 %-----------------------------------------------------------------------------%
 
 :- implementation.
-:- import_module list, require, char, string, int.
+:- import_module list, require, string, int.
 
 lexer__token_to_string(name(Name), String) :-
 	string__append_list(["token '", Name, "'"], String).
Index: library/nc_builtin.nl
===================================================================
RCS file: /home/mercury1/repository/mercury/library/nc_builtin.nl,v
retrieving revision 1.18
diff -u -u -r1.18 nc_builtin.nl
--- nc_builtin.nl	1998/01/14 03:21:03	1.18
+++ nc_builtin.nl	1998/02/18 23:44:45
@@ -24,6 +24,8 @@
 % :- op(1199, fx, (export_adt)).
 % :- op(1199, fx, (export_op)).
 
+:- op(1199, fx, (include_module)).
+
 :- op(1199, fx, (import_module)).
 % :- op(1199, fx, (import_sym)).
 % :- op(1199, fx, (import_pred)).
@@ -62,6 +64,7 @@
 
 % In NU-Prolog, ':' has precedence 1175, whereas according to the
 % ISO Prolog modules standard it should have precedence 600.
+% Also in Mercury it is yfx whereas in ISO Prolog it is xfy.
 % Hence we need to override the original precedence for it.
 % Because ':' is both unary prefix and binary in NU-Prolog,
 % we can't simply set the precedence, since that would cause a
@@ -73,7 +76,7 @@
 % warning messages.
 
 :- $setOpField((:), []).
-:- op(600, xfy, (:)).
+:- op(600, yfx, (:)).
 
 % In ISO Prolog, `is' has precedence 700, but
 % in Mercury we want `is' to have a higher precedence, so that
@@ -103,6 +106,8 @@
 termExpansion((:- end_module(_)), (:- fail)).
 termExpansion((:- interface), (:- fail)).
 termExpansion((:- implementation), (:- fail)).
+
+termExpansion((:- include_module(_)), (:- fail)).
 
 termExpansion((:- import_module(_)), (:- fail)).
 % termExpansion((:- import_sym(_)), (:- fail)).
Index: library/ops.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/ops.m,v
retrieving revision 1.22
diff -u -u -r1.22 ops.m
--- ops.m	1998/01/23 12:33:25	1.22
+++ ops.m	1998/02/18 23:55:12
@@ -135,7 +135,7 @@
 ops__op_table("/", after, yfx, 400).		% standard ISO Prolog
 ops__op_table("//", after, yfx, 400).		% standard ISO Prolog
 ops__op_table("/\\", after, yfx, 500).		% standard ISO Prolog
-ops__op_table(":", after, xfy, 600).		% different precedence in ISO?
+ops__op_table(":", after, yfx, 600).		% `xfy' in ISO Prolog
 ops__op_table(":-", after, xfx, 1200).		% standard ISO Prolog
 ops__op_table(":-", before, fx, 1200).		% standard ISO Prolog
 ops__op_table("::", after, xfx, 1175).		% Mercury extension
@@ -182,6 +182,7 @@
 ops__op_table("import_adt", before, fx, 1199).	% Mercury extension (NYI)
 ops__op_table("import_cons", before, fx, 1199).	% Mercury extension (NYI)
 ops__op_table("import_module", before, fx, 1199). % Mercury extension
+ops__op_table("include_module", before, fx, 1199). % Mercury extension
 ops__op_table("import_op", before, fx, 1199).	% Mercury extension (NYI)
 ops__op_table("import_pred", before, fx, 1199).	% Mercury extension (NYI)
 ops__op_table("import_sym", before, fx, 1199).	% Mercury extension (NYI)
Index: library/sp_builtin.nl
===================================================================
RCS file: /home/mercury1/repository/mercury/library/sp_builtin.nl,v
retrieving revision 1.14
diff -u -u -r1.14 sp_builtin.nl
--- sp_builtin.nl	1997/12/09 04:02:30	1.14
+++ sp_builtin.nl	1998/02/18 23:47:57
@@ -27,6 +27,8 @@
 :- op(1199, fx, (export_adt)).
 :- op(1199, fx, (export_op)).
 
+:- op(1199, fx, (include_module)).
+
 :- op(1199, fx, (import_module)).
 :- op(1199, fx, (import_sym)).
 :- op(1199, fx, (import_pred)).
@@ -73,6 +75,12 @@
 
 :- op(701, xfx, (is)).
 
+% N.B. Sicstus has ':' already, but with the wrong precedence
+% (550 instead of the ISO Prolog predence of 600),
+% and as xfy instead of yfx (xfy is correct according to ISO Prolog,
+% but Mercury has it as yfx).
+:- op(600, yfx, (:)).
+
 :- op(400, yfx, (rem)).
 :- op(400, yfx, (div)).
 
@@ -91,6 +99,8 @@
 mercury_declaration(end_module(_)).
 mercury_declaration(interface).
 mercury_declaration(implementation).
+
+mercury_declaration(include_module(_)).
 
 mercury_declaration(import_module(_)).
 mercury_declaration(import_sym(_)).
Index: library/term.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/term.m,v
retrieving revision 1.79
diff -u -u -r1.79 term.m
--- term.m	1998/01/23 12:33:41	1.79
+++ term.m	1998/02/19 05:54:50
@@ -15,7 +15,7 @@
 
 :- module term.
 :- interface.
-:- import_module list, map.
+:- import_module list, map, std_util.
 
 %-----------------------------------------------------------------------------%
 
Index: library/term_io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/term_io.m,v
retrieving revision 1.52
diff -u -u -r1.52 term_io.m
--- term_io.m	1998/01/24 10:28:37	1.52
+++ term_io.m	1998/02/19 05:54:56
@@ -16,7 +16,7 @@
 
 :- module term_io.
 :- interface.
-:- import_module io, varset, term.
+:- import_module char, io, varset, term.
 
 % External interface: exported predicates
 
Index: library/varset.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/varset.m,v
retrieving revision 1.56
diff -u -u -r1.56 varset.m
--- varset.m	1998/01/08 08:11:32	1.56
+++ varset.m	1998/02/19 05:56:00
@@ -28,7 +28,7 @@
 
 :- module varset.
 :- interface.
-:- import_module term.
+:- import_module term, list, map, assoc_list.
 
 :- type varset.
 
cvs diff: Diffing lp_solve
cvs diff: Diffing lp_solve/lp_examples
cvs diff: Diffing profiler
Index: profiler/demangle.m
===================================================================
RCS file: /home/mercury1/repository/mercury/profiler/demangle.m,v
retrieving revision 1.4
diff -u -u -r1.4 demangle.m
--- demangle.m	1997/10/13 10:18:28	1.4
+++ demangle.m	1998/02/18 17:14:12
@@ -183,18 +183,6 @@
 	),
 
 	%
-	% Separate the module name from the type name for the compiler
-	% generated predicates.
-	%
-	( { Category0 \= ordinary } ->
-		remove_prefix("_"),
-		remove_maybe_module_prefix(MaybeModule),
-		{ MaybeModule \= yes("") }
-	;
-		remove_maybe_module_prefix(MaybeModule)
-	),
-
-	%
 	% Make sure special predicates with unused_args 
 	% are reported correctly.
 	%
@@ -206,6 +194,20 @@
 	),
 
 	%
+	% Separate the module name from the type name for the compiler
+	% generated predicates.
+	%
+	( { Category0 \= ordinary } ->
+		remove_prefix("_"),
+		remove_maybe_module_prefix(MaybeModule,
+			["IntroducedFrom__"]),
+		{ MaybeModule \= yes("") }
+	;
+		remove_maybe_module_prefix(MaybeModule,
+			["IntroducedFrom__"])
+	),
+
+	%
 	% Now we need to look at the pred name and see if it is an
 	% introduced lambda predicate.
 	%
@@ -220,7 +222,7 @@
 		;
 			{ fail }
 		),
-		remove_maybe_module_prefix(MPredName),
+		remove_maybe_pred_name(MPredName),
 		{ MPredName = yes(PredName) },
 		remove_int(Line),
 		remove_prefix("__"),
@@ -303,7 +305,9 @@
 :- mode demangle_data(in, out) is semidet.
 demangle_data -->
 	remove_prefix("mercury_data_"),
-	remove_maybe_module_prefix(MaybeModule0),
+	remove_maybe_module_prefix(MaybeModule0,
+		["base_type_info_", "base_type_layout_",
+		"base_type_functors_", "common_"]),
 	{ MaybeModule0 = yes("") ->
 		MaybeModule = no
 	;
@@ -470,18 +474,53 @@
 
 /*---------------------------------------------------------------------------*/
 
-:- pred remove_maybe_module_prefix(maybe(string), string, string).
-:- mode remove_maybe_module_prefix(out, in, out) is det.
-remove_maybe_module_prefix(MaybeModule, String0, String) :-
-	( string__sub_string_search(String0, "__", Index) ->
+:- pred remove_maybe_module_prefix(maybe(string), list(string), string, string).
+:- mode remove_maybe_module_prefix(out, in, in, out) is det.
+remove_maybe_module_prefix(MaybeModule, StringsToStopAt, String0, String) :-
+	(
+		list__member(StopString, StringsToStopAt),
+		string__prefix(String0, StopString)
+	->
+		MaybeModule = no,
+		String = String0
+	;
+		string__sub_string_search(String0, "__", Index)
+	->
 		string__left(String0, Index, Module),
 		string__length(String0, Len),
 		Index2 is Index + 2,
-		string__substring(String0, Index2, Len, String),
-		MaybeModule = yes(Module)
+		string__substring(String0, Index2, Len, String1),
+		(
+			remove_maybe_module_prefix(yes(SubModule),
+				StringsToStopAt, String1, String2)
+		->
+			string__append_list([Module, ":", SubModule],
+				QualifiedModule),
+			MaybeModule = yes(QualifiedModule),
+			String = String2
+		;
+			MaybeModule = yes(Module),
+			String = String1
+		)
 	;
 		String = String0,
 		MaybeModule = no
+	).
+
+:- pred remove_maybe_pred_name(maybe(string), string, string).
+:- mode remove_maybe_pred_name(out, in, out) is det.
+remove_maybe_pred_name(MaybePredName, String0, String) :-
+	(
+		string__sub_string_search(String0, "__", Index)
+	->
+		string__left(String0, Index, PredName),
+		string__length(String0, Len),
+		Index2 is Index + 2,
+		string__substring(String0, Index2, Len, String),
+		MaybePredName = yes(PredName)
+	;
+		String = String0,
+		MaybePredName = no
 	).
 
 :- pred maybe_remove_prefix(string, string, string).
cvs diff: Diffing runtime
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing scripts
Index: scripts/Mmake.rules
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/Mmake.rules,v
retrieving revision 1.49
diff -u -u -r1.49 Mmake.rules
--- Mmake.rules	1998/02/12 10:04:33	1.49
+++ Mmake.rules	1998/02/18 13:56:30
@@ -12,14 +12,14 @@
 
 # Beware that the order of suffixes is significant.
 .SUFFIXES: .m .nl .no .err \
-		.int .int2 .int3 .opt .trans_opt \
+		.int0 .int .int2 .int3 .opt .trans_opt \
 		.dep .depend .doit .ugly \
-		.date .date3 .optdate .trans_opt_date \
+		.date0 .date .date3 .optdate .trans_opt_date \
 		.c .nu .o .pic_o \
 		.i .s .pic_s \
 		.ql .pl
 
-.PRECIOUS: %.date %.date3 %.optdate %.trans_opt_date
+.PRECIOUS: %.date0 %.date %.date3 %.optdate %.trans_opt_date
 
 # All the builtin rules must use $@ as the target, so that they work
 # when $(VPATH) is set.
@@ -52,6 +52,9 @@
 	$(MC) $(MCFLAGS) --errorcheck-only $< > $@ 2>&1
 	@touch $@
 
+.m.date0:
+	$(MCPI) $(MCPIFLAGS) $<
+
 .m.date:
 	$(MCI) $(MCIFLAGS) $<
 
@@ -69,6 +72,9 @@
 # It is used to force GNU Make to recheck the timestamp
 # on the target file.  (It is a pity that GNU Make doesn't
 # have a way of handling these sorts of rules in a nicer manner.)
+
+.date0.int0:
+	@:
 
 .date.int:
 	@:
Index: scripts/Mmake.vars.in
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/Mmake.vars.in,v
retrieving revision 1.14
diff -u -u -r1.14 Mmake.vars.in
--- Mmake.vars.in	1998/01/29 13:41:23	1.14
+++ Mmake.vars.in	1998/02/18 13:57:16
@@ -1,5 +1,4 @@
 #-----------------------------------------------------------------------------#
-#-----------------------------------------------------------------------------#
 # Copyright (C) 1996-1998 The University of Melbourne.
 # This file may only be copied under the terms of the GNU General
 # Public License - see the file COPYING in the Mercury distribution.
@@ -32,11 +31,13 @@
 MCG		= $(MC) --compile-to-c
 MCD		= $(MC) --generate-dependencies
 MCI		= $(MC) --make-interface
+MCPI		= $(MC) --make-private-interface
 MCSI		= $(MC) --make-short-interface
 MCOI		= $(MC) --make-optimization-interface
 MCTOI		= $(MC) --make-transitive-optimization-interface
 MCFLAGS		= $(EXTRA_MCFLAGS)
 MCIFLAGS	= $(MCFLAGS)
+MCPIFLAGS	= $(MCFLAGS)
 MCSIFLAGS	= $(MCFLAGS)
 MCOIFLAGS	= $(MCFLAGS)
 MCTOIFLAGS	= $(MCFLAGS)
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/general
Index: tests/general/.cvsignore
===================================================================
RCS file: /home/mercury1/repository/tests/general/.cvsignore,v
retrieving revision 1.8
diff -u -u -r1.8 .cvsignore
--- .cvsignore	1997/08/11 08:04:06	1.8
+++ .cvsignore	1998/02/16 16:04:21
@@ -1,7 +1,7 @@
 *.c *.nux *.nux.save *.exp *.out *.res .allres
 arithmetic commit_bug disj_disj duplicate_label environment float_test
 interpreter nasty_nondet nondet_disj nondet_ite partition petdr1
-string__format_test string_test string_test_2 set_test univ
+string_format_test string_test string_test_2 set_test univ
 higher_order semidet_map parse_list
 det_complicated_unify commit_bug nondet_ite_2
 unreachable dnf hello_again nondetlive semidet_lambda liveness
Index: tests/general/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/general/Mmakefile,v
retrieving revision 1.6
diff -u -u -r1.6 Mmakefile
--- Mmakefile	1998/02/25 00:12:02	1.6
+++ Mmakefile	1998/02/25 07:57:49
@@ -53,7 +53,7 @@
 		prune_switch \
 		semidet_map \
 		set_test \
-		string__format_test \
+		string_format_test \
 		string_test \
 		string_test_2 \
 		univ \
cvs diff: tests/general/string__format_test.exp was removed, no comparison available
cvs diff: tests/general/string__format_test.m was removed, no comparison available
cvs diff: tests/general/string_format_test.exp is a new entry, no comparison available
cvs diff: tests/general/string_format_test.m is a new entry, no comparison available
cvs diff: Diffing tests/hard_coded
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.18
diff -u -u -r1.18 Mmakefile
--- Mmakefile	1998/02/19 03:17:13	1.18
+++ Mmakefile	1998/02/26 03:58:06
@@ -48,6 +48,8 @@
 	no_fully_strict \
 	no_inline \
 	nullary_ho_func \
+	parent \
+	parent2 \
 	pragma_c_code \
 	pragma_inline \
 	pragma_import \
cvs diff: tests/hard_coded/parent.child.m is a new entry, no comparison available
cvs diff: tests/hard_coded/parent.exp is a new entry, no comparison available
cvs diff: tests/hard_coded/parent.m is a new entry, no comparison available
cvs diff: tests/hard_coded/parent2.child.m is a new entry, no comparison available
cvs diff: tests/hard_coded/parent2.exp is a new entry, no comparison available
cvs diff: tests/hard_coded/parent2.m is a new entry, no comparison available
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
Index: tests/invalid/bigtest.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/bigtest.err_exp,v
retrieving revision 1.1
diff -u -u -r1.1 bigtest.err_exp
--- bigtest.err_exp	1996/11/04 07:14:34	1.1
+++ bigtest.err_exp	1998/02/25 05:29:01
@@ -1,4 +1,4 @@
-bigtest.m:001: Warning: module should start with a `:- module' declaration.
+bigtest.m:001: Warning: module should start with a `:- module' declaration: :- export_sym list / 1, append / 3, member.
 bigtest.m:006: Syntax error at token ':-': operator precedence error.
 bigtest.m:008: Error: unrecognized declaration: incorrect_declaration.
 bigtest.m:001: Warning: declaration not yet implemented.
Index: tests/invalid/errors.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/errors.err_exp,v
retrieving revision 1.3
diff -u -u -r1.3 errors.err_exp
--- errors.err_exp	1997/06/29 23:24:35	1.3
+++ errors.err_exp	1998/02/25 05:31:17
@@ -1,8 +1,8 @@
-errors.m:001: Warning: module should start with a `:- module' declaration.
+errors.m:010: Warning: module should start with a `:- module' declaration: :- pred pred_with_no_clauses_or_mode_declaration(int).
 errors.m:060: Error: free type parameter in RHS of type definition: f(_0).
 errors.m:061: Error: free type parameter in RHS of type definition: f(_0).
-errors.m:000: Warning: module `int' is imported using both
-errors.m:000:   `:- import_module' and `:- use_module' declarations.
+errors.m:001: Warning: module `int' is imported using both
+errors.m:001:   `:- import_module' and `:- use_module' declarations.
 errors.m:051: In definition of type `errors:du_type_which_references_undefined_type'/0:
 errors.m:051:   error: undefined type `undefined_type'/0.
 errors.m:053: In definition of type `errors:eqv_type_which_references_undefined_type'/0:
Index: tests/invalid/prog_io_erroneous.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/prog_io_erroneous.err_exp,v
retrieving revision 1.1
diff -u -u -r1.1 prog_io_erroneous.err_exp
--- prog_io_erroneous.err_exp	1996/11/04 07:15:12	1.1
+++ prog_io_erroneous.err_exp	1998/02/25 05:31:53
@@ -1,4 +1,4 @@
-prog_io_erroneous.m:001: Warning: incorrect module name in `:- module' declaration.
+prog_io_erroneous.m:001: Warning: incorrect module name in `:- module' declaration: :- module p.
 prog_io_erroneous.m:012: Error: no clauses for predicate `prog_io_erroneous:q/2'
 prog_io_erroneous.m:007: In clause for `p(in, out, out)':
 prog_io_erroneous.m:007:   in argument 1 of call to predicate `prog_io_erroneous:q/2':
Index: tests/invalid/typeclass_test_1.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/typeclass_test_1.err_exp,v
retrieving revision 1.2
diff -u -u -r1.2 typeclass_test_1.err_exp
--- typeclass_test_1.err_exp	1998/02/02 02:55:57	1.2
+++ typeclass_test_1.err_exp	1998/02/25 05:32:22
@@ -1,4 +1,4 @@
-typeclass_test_1.m:001: Warning: module should start with a `:- module' declaration.
+typeclass_test_1.m:001: Warning: module should start with a `:- module' declaration: :- interface.
 typeclass_test_1.m:014: Error: expected `pred(<Name> / <Arity>) is <InstanceName>': type_num is foo_type_num.
 typeclass_test_1.m:017: Syntax error at variable `_': operator or `.' expected.
 typeclass_test_1.m:007: In clause for predicate `typeclass_test_1:main/2':
Index: tests/invalid/typeclass_test_2.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/typeclass_test_2.err_exp,v
retrieving revision 1.2
diff -u -u -r1.2 typeclass_test_2.err_exp
--- typeclass_test_2.err_exp	1998/02/02 02:55:57	1.2
+++ typeclass_test_2.err_exp	1998/02/25 05:32:39
@@ -1,4 +1,4 @@
-typeclass_test_2.m:001: Warning: incorrect module name in `:- module' declaration.
+typeclass_test_2.m:001: Warning: incorrect module name in `:- module' declaration: :- module foo.
 typeclass_test_2.m:015: Error: expected `pred(<Name> / <Arity>) is <InstanceName>': type_num / 0 is foo_type_num.
 typeclass_test_2.m:018: Error: clause for function `typeclass_test_2:foo_type_num/1'
 typeclass_test_2.m:018:   without preceding `func' declaration.
Index: tests/invalid/types.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/types.err_exp,v
retrieving revision 1.2
diff -u -u -r1.2 types.err_exp
--- types.err_exp	1998/01/12 13:30:03	1.2
+++ types.err_exp	1998/02/25 05:33:22
@@ -1,4 +1,4 @@
-types.m:001: Warning: incorrect module name in `:- module' declaration.
+types.m:001: Warning: incorrect module name in `:- module' declaration: :- module t.
 types.m:003: Error: constructor `types:a/0' for type `types:t/0' multiply defined.
 types.m:003: Error: constructor `types:f/1' for type `types:t/0' multiply defined.
 types.m:017: Error: clause for predicate `types:r/0'
Index: tests/invalid/undef_type.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/undef_type.err_exp,v
retrieving revision 1.1
diff -u -u -r1.1 undef_type.err_exp
--- undef_type.err_exp	1996/11/04 07:15:18	1.1
+++ undef_type.err_exp	1998/02/25 05:33:07
@@ -1,4 +1,4 @@
-undef_type.m:001: Warning: incorrect module name in `:- module' declaration.
+undef_type.m:001: Warning: incorrect module name in `:- module' declaration: :- module test1.
 undef_type.m:003: In definition of type `undef_type:t1'/0:
 undef_type.m:003:   error: undefined type `undef1'/0.
 undef_type.m:010: In definition of predicate `undef_type:q'/1:
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
Index: tests/warnings/unused_args_test.exp
===================================================================
RCS file: /home/mercury1/repository/tests/warnings/unused_args_test.exp,v
retrieving revision 1.4
diff -u -u -r1.4 unused_args_test.exp
--- unused_args_test.exp	1997/01/20 03:33:42	1.4
+++ unused_args_test.exp	1998/02/16 06:46:35
@@ -1,4 +1,4 @@
-unused_args_test.m:009: In predicate `unused_args_test:recursive'/3:
+unused_args_test.m:009: In predicate `unused_args_test:recursive/3':
 unused_args_test.m:009:   warning: argument 1 is unused.
-unused_args_test.m:011: In predicate `unused_args_test:nonrecursive'/1:
+unused_args_test.m:011: In predicate `unused_args_test:nonrecursive/1':
 unused_args_test.m:011:   warning: argument 1 is unused.
Index: tests/warnings/unused_import.exp
===================================================================
RCS file: /home/mercury1/repository/tests/warnings/unused_import.exp,v
retrieving revision 1.3
diff -u -u -r1.3 unused_import.exp
--- unused_import.exp	1997/06/01 19:35:32	1.3
+++ unused_import.exp	1998/02/25 05:16:33
@@ -1,3 +1,4 @@
-unused_import.m:001: Warning: modules `float' and `list'
+unused_import.m:001: In module `unused_import':
+unused_import.m:001:   warning: modules `float' and `list'
 unused_import.m:001:   are imported in the interface, but are not
 unused_import.m:001:   used in the interface.
cvs diff: Diffing tools
cvs diff: Diffing trial
cvs diff: Diffing util
Index: util/mdemangle.c
===================================================================
RCS file: /home/mercury1/repository/mercury/util/mdemangle.c,v
retrieving revision 1.28
diff -u -u -r1.28 mdemangle.c
--- mdemangle.c	1997/11/23 07:47:20	1.28
+++ mdemangle.c	1998/02/25 05:55:56
@@ -28,6 +28,8 @@
 #include "mercury_std.h"
 
 static void demangle(char *name);
+static const char *strip_module_name(char **start_ptr, char *end,
+		const char *trailing_context[]);
 static bool check_for_suffix(char *start, char *position, const char *suffix,
 		int sizeof_suffix, int *mode_num2);
 static char *fix_mangled_ascii(char *str, char **end);
@@ -117,6 +119,15 @@
 	static const char base_type_functors[] = "base_type_functors_";
 	static const char common[] = "common";
 
+	static const char * trailing_context_1[] = { introduced, NULL };
+	static const char * trailing_context_2[] = {
+		base_type_layout,
+		base_type_info,
+		base_type_functors,
+		common,
+		NULL
+	};
+
 	char *start = name;
 	const char *module = "";	/* module name */
 	char *end = name + strlen(name);
@@ -281,14 +292,6 @@
 	*end = '\0';
 
 	/*
-	** Strip off the module name
-	*/
-	module = start;
-	if (!cut_at_double_underscore(&start, end)) {
-		module = "";
-	}
-
-	/*
 	** Make sure special predicates with unused_args 
 	** are reported correctly.
 	*/
@@ -299,6 +302,8 @@
 		}
 	}
 
+	module = strip_module_name(&start, end, trailing_context_1);
+
 	/*
 	** look for "IntroducedFrom"
 	*/
@@ -385,10 +390,8 @@
 	if (!strip_prefix(&start, mercury_data)) {
 		goto wrong_format;
 	}
-	module = start;
-	if (!cut_at_double_underscore(&start, end)) {
-		module = "";
-	}
+
+	module = strip_module_name(&start, end, trailing_context_2);
 
 	if (strip_prefix(&start, base_type_info)) {
 		data_category = INFO;
@@ -460,6 +463,69 @@
 	printf("%s", name);
 	return;
 } /* end demangle() */
+
+	/*
+	** Remove a module name prefix.
+	** Just keep munching up double-underscores until we
+	** get to something that matches the specified trailing context,
+	** at which point we stop, or until there are no double-underscores
+	** left.
+	*/
+static const char *
+strip_module_name(char **start_ptr, char *end, const char *trailing_context[])
+{
+	const char *module;		/* module name */
+	char *module_end;		/* end of the module name */
+	char *next_double_underscore;
+	char *start;
+
+	start = *start_ptr;
+
+	/*
+	** Strip off the module name
+	*/
+	module = start;
+	module_end = start;
+	while ((next_double_underscore = strstr(start, "__")) != NULL) {
+		int len, i;
+
+		/*
+		** Check for special cases
+		*/
+		bool stop = FALSE;
+		for (i = 0; trailing_context[i] != NULL; i++) {
+			if (strncmp(start,
+				trailing_context[i],
+				strlen(trailing_context[i])) == 0)
+			{
+				stop = TRUE;
+			}
+		}
+		if (stop) break;
+
+		len = next_double_underscore - start;
+		if (module != module_end) {
+			/*
+			** append a module qualifier, and
+			** shift the module name into the right place
+			*/
+			*module_end = ':';
+			module_end++;
+			memmove(module_end, start, len);
+		}
+		module_end += len;
+
+		start = next_double_underscore + 2;
+	}
+	if (module == module_end) {
+		module = "";
+	} else {
+		*module_end = '\0';
+	}
+
+	*start_ptr = start;
+	return module;
+}
 
 	/*
 	** Remove the prefix from a string, if it has 

-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list