[m-rev.] for review: move to support solver initialization

Zoltan Somogyi zs at cs.mu.OZ.AU
Tue Aug 9 16:25:27 AEST 2005


For review by anyone. I tested the code by hand. Automatic tests can't
be conveniently done until the compiler starts using this functionality.

Zoltan.

Make a step towards supporting the automatic running of compiler-provided
initialization functions at startup. The idea is that in each module that
defines a solver type which wants to keep the solver state in a global
variable, the compiler will generate a function to initialize this global
variable and put a line containing

	REQUIRED_INIT function_name

in the generated .c file. Mkinit will then see this and put a call to the named
function in the program's init_modules_required function, which (once this diff
is installed) will be called from the tail end of mercury_init.

util/mkinit.c:
	Until now, mkinit didn't open .c files unless given the -x option,
	because doing so was expensive: the list of .c (and .init) files was
	scanned five times, and opening and reading each file five times is
	excessive. This diff changes that. Each file is now opened and read
	(until a line containing only ENDINIT) just once, and the info found
	therein put into some new mkinit data structures. The five scans
	through the file list now scan through these data structures instead.
	This is now fast enough to leave -x on all the time: mkinit -x now
	takes 3-4 seconds in the compiler directory, and at most 0.15s
	in the other directories.

	Add a sixth scan through the data structures to generate calls to
	the functions named in REQUIRED_INIT lines; make bunches of these calls
	the body of the program's init_modules_required function.

runtime/mercury_array_macro.h:
	Fix indentation.

runtime/mercury_dlist.[ch]:
	Move the documentation of the exported functions from the .c file
	to the .h file.

runtime/mercury_std.h:
	Add a missing () around a macro argument.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_glut
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/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_array_macros.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_array_macros.h,v
retrieving revision 1.14
diff -u -b -r1.14 mercury_array_macros.h
--- runtime/mercury_array_macros.h	21 Jun 2005 03:12:02 -0000	1.14
+++ runtime/mercury_array_macros.h	9 Aug 2005 04:22:46 -0000
@@ -222,8 +222,7 @@
     do {                                                                \
         (element) = (next) - 1;                                         \
         while ((element) >= 0 && (COMPARE) > 0) {                       \
-            MR_assign_structure(items[element + 1],                     \
-                items[element]);                                        \
+            MR_assign_structure(items[element + 1], items[element]);    \
             (element) -= 1;                                             \
         }                                                               \
         (element) += 1;                                                 \
Index: runtime/mercury_dlist.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_dlist.c,v
retrieving revision 1.7
diff -u -b -r1.7 mercury_dlist.c
--- runtime/mercury_dlist.c	20 Jul 2004 04:41:21 -0000	1.7
+++ runtime/mercury_dlist.c	9 Aug 2005 04:15:30 -0000
@@ -13,10 +13,6 @@
 #include	"mercury_memory.h"
 #include	"mercury_dlist.h"
 
-/*
-**	Make an empty list.
-*/
-
 MR_Dlist *
 MR_dlist_makelist0(void)
 {
@@ -30,10 +26,6 @@
 	return list;
 }
 
-/*
-**	Make a list with the argument is its only element.
-*/
-
 MR_Dlist *
 MR_dlist_makelist(const void *data)
 {
@@ -45,10 +37,6 @@
 	return list;
 }
 
-/*
-**	Add some data to the head of a list.
-*/
-
 MR_Dlist *
 MR_dlist_addhead(MR_Dlist *list, const void *data)
 {
@@ -72,10 +60,6 @@
 	return list;
 }
 
-/*
-**	Add some data to the tail of a list.
-*/
-
 MR_Dlist *
 MR_dlist_addtail(MR_Dlist *list, const void *data)
 {
@@ -99,11 +83,6 @@
 	return list;
 }
 
-/*
-**	Destructively append list2 to list1. Since the header of
-**	list2 is not meaningful after the operation, it is freed.
-*/
-
 MR_Dlist *
 MR_dlist_addlist(MR_Dlist *list1, MR_Dlist *list2)
 {
@@ -142,12 +121,6 @@
 	return list1;
 }
 
-/*
-**	(Semi-) nondestructively append list2 to list1.
-**	The header of the first list is indeed altered,
-**	but only the data pointers of the second are used.
-*/
-
 MR_Dlist *
 MR_dlist_addndlist(MR_Dlist *list1, MR_Dlist *list2)
 {
@@ -168,10 +141,6 @@
 	return list1;
 }
 
-/*
-**	Insert into a list before a given position.
-*/
-
 void 
 MR_dlist_insert_before(MR_Dlist *list, MR_Dlist *where, const void *data)
 {
@@ -189,10 +158,6 @@
 	MR_dlist_prev(MR_dlist_next(item)) = item;
 }
 
-/*
-**	Insert into a list after a given position.
-*/
-
 void 
 MR_dlist_insert_after(MR_Dlist *list, MR_Dlist *where, const void *data)
 {
@@ -254,12 +219,6 @@
 
 	return;
 }
-
-/*
-**	Free a whole list, including the header and maybe the data
-**	pointed to by the list. Of course, if they were not allocated
-**	by MR_GC_malloc, then all Hell will break loose.
-*/
 
 void 
 MR_dlist_oldlist(MR_Dlist *list, void (* func)(const void *))
Index: runtime/mercury_dlist.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_dlist.h,v
retrieving revision 1.5
diff -u -b -r1.5 mercury_dlist.h
--- runtime/mercury_dlist.h	20 Jul 2004 04:41:21 -0000	1.5
+++ runtime/mercury_dlist.h	9 Aug 2005 04:19:07 -0000
@@ -28,6 +28,84 @@
 	MR_Dlist	*MR_dlist_next;
 };
 
+/*
+** Make an empty list.
+*/
+
+extern	MR_Dlist	*MR_dlist_makelist0(void);
+
+/*
+** Make a list with "data" as its only element.
+*/
+
+extern	MR_Dlist	*MR_dlist_makelist(const void *data);
+
+/*
+** Add "data" to the head of "list".
+*/
+
+extern	MR_Dlist	*MR_dlist_addhead(MR_Dlist *list, const void *data);
+
+/*
+** Add "data" to the tail of "list".
+*/
+
+extern	MR_Dlist	*MR_dlist_addtail(MR_Dlist *list, const void *data);
+
+/*
+** Destructively append list2 to list1. Since the header of list2 is not
+** meaningful after the operation, it is freed.
+*/
+
+extern	MR_Dlist	*MR_dlist_addlist(MR_Dlist *list1, MR_Dlist *list2);
+
+/*
+** (Semi-) nondestructively append list2 to list1. The header of list1 is
+** indeed altered, but only the data pointers of list2 are used.
+*/
+
+extern	MR_Dlist	*MR_dlist_addndlist(MR_Dlist *list1, MR_Dlist *list2);
+
+/*
+** Insert "data" into "list" before the element given by "where".
+*/
+
+extern	void		MR_dlist_insert_before(MR_Dlist *list, MR_Dlist *where,
+				const void *data);
+
+/*
+** Insert "data" into "list" after the element given by "where".
+*/
+
+extern	void		MR_dlist_insert_after(MR_Dlist *list, MR_Dlist *where,
+				const void *data);
+
+/*
+** Return the length of "list".
+*/
+
+extern	int		MR_dlist_maybe_null_length(const MR_Dlist *list);
+
+/*
+** Delete the node given by "item" from its linked list "list". Free this node,
+** and, if "func" is non-NULL, use it to free the data item in that node.
+*/
+
+extern	void		MR_dlist_delete(MR_Dlist *list, MR_Dlist *item,
+				void (* func)(const void *));
+
+/*
+** Free the whole list, including the header. If func is non-NULL, then use it
+** to free the data items pointed to by the list nodes.
+*/
+
+extern	void		MR_dlist_oldlist(MR_Dlist *list,
+				void (* func)(const void *));
+
+/*
+** Macros to make programming with this module easier.
+*/
+
 #define	MR_dlist_next(ptr)		(ptr)->MR_dlist_next
 #define	MR_dlist_prev(ptr)		(ptr)->MR_dlist_prev
 #define	MR_dlist_data(ptr)		(ptr)->MR_dlist_union.MR_dlist_data
@@ -65,20 +143,5 @@
 	)
 #define	MR_end_dlist(p, l)						\
 	((p) == (l) || (p) == NULL)
-
-extern	MR_Dlist	*MR_dlist_makelist0(void);
-extern	MR_Dlist	*MR_dlist_makelist(const void *);
-extern	MR_Dlist	*MR_dlist_addhead(MR_Dlist *, const void *);
-extern	MR_Dlist	*MR_dlist_addtail(MR_Dlist *, const void *);
-extern	MR_Dlist	*MR_dlist_addlist(MR_Dlist *, MR_Dlist *);
-extern	MR_Dlist	*MR_dlist_addndlist(MR_Dlist *, MR_Dlist *);
-extern	void		MR_dlist_insert_before(MR_Dlist *, MR_Dlist *,
-				const void *);
-extern	void		MR_dlist_insert_after(MR_Dlist *, MR_Dlist *,
-				const void *);
-extern	int		MR_dlist_maybe_null_length(const MR_Dlist *);
-extern	void		MR_dlist_delete(MR_Dlist *, MR_Dlist *,
-				void (*)(const void *));
-extern	void		MR_dlist_oldlist(MR_Dlist *, void (*)(const void *));
 
 #endif /* not MERCURY_DLIST_H */
Index: runtime/mercury_std.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_std.h,v
retrieving revision 1.29
diff -u -b -r1.29 mercury_std.h
--- runtime/mercury_std.h	24 Nov 2004 08:46:29 -0000	1.29
+++ runtime/mercury_std.h	9 Aug 2005 03:21:27 -0000
@@ -77,7 +77,7 @@
 #define	MR_isalnum(c)		isalnum((unsigned char) (c))
 #define	MR_isdigit(c)		isdigit((unsigned char) (c))
 #define	MR_isspace(c)		isspace((unsigned char) (c))
-#define	MR_isalnumunder(c)	(isalnum((unsigned char) (c)) || c == '_')
+#define	MR_isalnumunder(c)	(isalnum((unsigned char) (c)) || (c) == '_')
 
 #define MR_streq(s1, s2)	(strcmp(s1, s2) == 0)
 #define MR_strdiff(s1, s2)	(strcmp(s1, s2) != 0)
cvs diff: Diffing runtime/GETOPT
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/mercury_calls_fortran
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 samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
Index: util/mkinit.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/util/mkinit.c,v
retrieving revision 1.99
diff -u -b -r1.99 mkinit.c
--- util/mkinit.c	21 Jun 2005 01:38:19 -0000	1.99
+++ util/mkinit.c	9 Aug 2005 06:08:08 -0000
@@ -1,4 +1,3 @@
-/*---------------------------------------------------------------------------*/
 /*
 ** vim:sw=4 ts=4 expandtab
 */
@@ -24,6 +23,18 @@
 #include    "mercury_conf.h"
 #include    "mercury_std.h"
 #include    "getopt.h"
+#include    "mercury_array_macros.h"
+
+/*
+** mercury_array_macros.h uses the MR_NEW_ARRAY and MR_RESIZE_ARRAY macros.
+*/
+
+#define MR_NEW_ARRAY(type, num) \
+        ((type *) malloc((num) * sizeof(type)))
+
+#define MR_RESIZE_ARRAY(ptr, type, num) \
+        ((type *) realloc((ptr), (num) * sizeof(type)))
+
 
 #include    <stdio.h>
 #include    <stdlib.h>
@@ -66,7 +77,8 @@
     PURPOSE_TYPE_TABLE = 1,
     PURPOSE_DEBUGGER = 2,
     PURPOSE_COMPLEXITY = 3,
-    PURPOSE_PROC_STATIC = 4
+    PURPOSE_PROC_STATIC = 4,
+    PURPOSE_REQ_INIT = 5
 } Purpose;
 
 const char  *main_func_name[] =
@@ -75,7 +87,8 @@
     "init_modules_type_tables",
     "init_modules_debugger",
     "init_modules_complexity_procs",
-    "write_out_proc_statics"
+    "write_out_proc_statics",
+    "init_modules_required",
 };
 
 const char  *module_suffix[] =
@@ -84,7 +97,8 @@
     "init_type_tables",
     "init_debugger",
     "init_complexity_procs",
-    "write_out_proc_statics"
+    "write_out_proc_statics",
+    "",
 };
 
 const char  *init_suffix[] =
@@ -102,7 +116,8 @@
     NULL,
     if_need_to_init,
     if_need_term_size,
-    if_need_deep_prof
+    if_need_deep_prof,
+    NULL
 };
 
 const char  *main_func_guard[] =
@@ -111,7 +126,8 @@
     NULL,
     NULL,
     if_need_term_size,
-    if_need_deep_prof
+    if_need_deep_prof,
+    NULL,
 };
 
 const char  *main_func_body_guard[] =
@@ -120,6 +136,7 @@
     NULL,
     if_need_to_init,
     NULL,
+    NULL,
     NULL
 };
 
@@ -129,7 +146,8 @@
     "void",
     "void",
     "void",
-    "FILE *fp"
+    "FILE *fp",
+    "void"
 };
 
 const char  *main_func_arg_decl[] =
@@ -138,7 +156,8 @@
     "void",
     "void",
     "void",
-    "FILE *"
+    "FILE *",
+    "void"
 };
 
 const char  *main_func_arg[] =
@@ -147,7 +166,8 @@
     "",
     "",
     "",
-    "fp"
+    "fp",
+    ""
 };
 
 /* --- macros--- */
@@ -166,7 +186,50 @@
 
 static const char *MR_progname = NULL;
 
-    /* List of names of Aditi-RL code constants. */
+/*
+** List of names of the modules to call all the usual initialization
+** functions for: "init", "init_type_tables", "init_debugger" and (with
+** the right #defines) "init_complexity_procs" and "write_out_proc_statics".
+*/
+
+static const char   **std_modules = NULL;
+static int          std_module_max = 0;
+static int          std_module_next = 0;
+#define MR_INIT_STD_MODULE_SIZE     100
+
+/*
+** List of names of handwritten modules, for which we call a limited set
+** of initialization functions: "init", "init_type_tables" and (with
+** the right #defines) "write_out_proc_statics". We don't call
+** "init_debugger" functions since handwritten modules don't have module
+** layouts, and we don't generate "init_complexity_procs" since they have
+** no Mercury code to measure the complexity of.
+*/
+
+static const char   **special_modules = NULL;
+static int          special_module_max = 0;
+static int          special_module_next = 0;
+#define MR_INIT_SPECIAL_MODULE_SIZE     10
+
+/*
+** The concatenation of std_modules and special_modules; created with the
+** right size (std_module_next + special_module_next).
+*/
+
+static const char   **std_and_special_modules = NULL;
+
+/*
+** List of names of modules that have initialization functions that should
+** always be run. This is currently used to initialize the states of constraint
+** solvers. We call an "init_required" function for each such module.
+*/
+
+static const char   **req_modules = NULL;
+static int          req_module_max = 0;
+static int          req_module_next = 0;
+#define MR_INIT_REQ_MODULE_SIZE     10
+
+/* List of names of Aditi-RL code constants. */
 static String_List *rl_data = NULL;
 
 /* options and arguments, set by parse_options() */
@@ -445,22 +508,22 @@
 static  void    output_complexity_proc(const char *procname);
 static  void    output_complexity_experiment_table(const char *filename);
 static  void    output_headers(void);
-static  int     output_sub_init_functions(Purpose purpose);
+static  int     output_sub_init_functions(Purpose purpose,
+                    const char **func_names, int num_func_names);
 static  void    output_main_init_function(Purpose purpose, int num_bunches);
 static  void    output_aditi_load_function(void);
 static  void    output_main(void);
-static  void    process_file(const char *filename, int *num_bunches_ptr,
-                    int *num_calls_in_cur_bunch_ptr, Purpose purpose);
-static  void    process_c_file(const char *filename, int *num_bunches_ptr,
-                    int *num_calls_in_cur_bunch_ptr, Purpose purpose);
-static  void    process_init_file(const char *filename, int *num_bunches_ptr,
-                    int *num_calls_in_cur_bunch_ptr, Purpose purpose);
+static  void    process_file(const char *filename);
+static  void    process_c_file(const char *filename);
+static  void    process_init_file(const char *filename);
 static  void    output_init_function(const char *func_name,
                     int *num_bunches_ptr, int *num_calls_in_cur_bunch_ptr,
-                    Purpose purpose, MR_bool special_module);
+                    Purpose purpose);
 static  void    add_rl_data(char *data);
 static  int     get_line(FILE *file, char *line, int line_max);
 static  void    *checked_malloc(size_t size);
+static  char    *checked_strdup(const char *str);
+static  char    *checked_strdupcat(const char *str, const char *suffix);
 
 /*---------------------------------------------------------------------------*/
 
@@ -496,7 +559,9 @@
 int
 main(int argc, char **argv)
 {
+    int filenum;
     int num_bunches;
+    int i;
 
     MR_progname = argv[0];
 
@@ -511,21 +576,45 @@
         printf("#define MR_MAY_NEED_INITIALIZATION\n\n");
     }
 
-    num_bunches = output_sub_init_functions(PURPOSE_INIT);
+    for (filenum = 0; filenum < num_files; filenum++) {
+        process_file(files[filenum]);
+    }
+
+    std_and_special_modules = MR_NEW_ARRAY(const char *,
+        std_module_next + special_module_next);
+
+    for (i = 0; i < std_module_next; i++) {
+        std_and_special_modules[i] = std_modules[i];
+    }
+
+    for (i = 0; i < special_module_next; i++) {
+        std_and_special_modules[std_module_next + i] = special_modules[i];
+    }
+
+    num_bunches = output_sub_init_functions(PURPOSE_INIT,
+        std_and_special_modules, std_module_next + special_module_next);
     output_main_init_function(PURPOSE_INIT, num_bunches);
 
-    num_bunches = output_sub_init_functions(PURPOSE_TYPE_TABLE);
+    num_bunches = output_sub_init_functions(PURPOSE_TYPE_TABLE,
+        std_and_special_modules, std_module_next + special_module_next);
     output_main_init_function(PURPOSE_TYPE_TABLE, num_bunches);
 
-    num_bunches = output_sub_init_functions(PURPOSE_DEBUGGER);
+    num_bunches = output_sub_init_functions(PURPOSE_DEBUGGER,
+        std_modules, std_module_next);
     output_main_init_function(PURPOSE_DEBUGGER, num_bunches);
 
-    num_bunches = output_sub_init_functions(PURPOSE_COMPLEXITY);
+    num_bunches = output_sub_init_functions(PURPOSE_COMPLEXITY,
+        std_modules, std_module_next);
     output_main_init_function(PURPOSE_COMPLEXITY, num_bunches);
 
-    num_bunches = output_sub_init_functions(PURPOSE_PROC_STATIC);
+    num_bunches = output_sub_init_functions(PURPOSE_PROC_STATIC,
+        std_and_special_modules, std_module_next + special_module_next);
     output_main_init_function(PURPOSE_PROC_STATIC, num_bunches);
 
+    num_bunches = output_sub_init_functions(PURPOSE_REQ_INIT,
+        req_modules, req_module_next);
+    output_main_init_function(PURPOSE_REQ_INIT, num_bunches);
+
     if (aditi) {
         output_aditi_load_function();
     }
@@ -898,9 +987,10 @@
 }
 
 static int
-output_sub_init_functions(Purpose purpose)
+output_sub_init_functions(Purpose purpose, const char **func_names,
+    int num_func_names)
 {
-    int filenum;
+    int funcnum;
     int num_bunches;
     int num_calls_in_cur_bunch;
 
@@ -916,8 +1006,8 @@
 
     num_bunches = 0;
     num_calls_in_cur_bunch = 0;
-    for (filenum = 0; filenum < num_files; filenum++) {
-        process_file(files[filenum], &num_bunches,
+    for (funcnum = 0; funcnum < num_func_names; funcnum++) {
+        output_init_function(func_names[funcnum], &num_bunches,
             &num_calls_in_cur_bunch, purpose);
     }
 
@@ -1026,23 +1116,19 @@
 /*---------------------------------------------------------------------------*/
 
 static void
-process_file(const char *filename, int *num_bunches_ptr,
-    int *num_calls_in_cur_bunch_ptr, Purpose purpose)
+process_file(const char *filename)
 {
     int len;
 
     len = strlen(filename);
     if (len >= 2 && strcmp(filename + len - 2, ".c") == 0) {
         if (c_files_contain_extra_inits) {
-            process_init_file(filename, num_bunches_ptr,
-                num_calls_in_cur_bunch_ptr, purpose);
+            process_init_file(filename);
         } else {
-            process_c_file(filename, num_bunches_ptr,
-                num_calls_in_cur_bunch_ptr, purpose);
+            process_c_file(filename);
         }
     } else if (len >= 5 && strcmp(filename + len - 5, ".init") == 0) {
-        process_init_file(filename, num_bunches_ptr,
-            num_calls_in_cur_bunch_ptr, purpose);
+        process_init_file(filename);
     } else {
         fprintf(stderr,
             "%s: filename `%s' must end in `.c' or `.init'\n",
@@ -1052,8 +1138,7 @@
 }
 
 static void
-process_c_file(const char *filename, int *num_bunches_ptr,
-    int *num_calls_in_cur_bunch_ptr, Purpose purpose)
+process_c_file(const char *filename)
 {
     char    func_name[1000];
     char    *position;
@@ -1114,8 +1199,9 @@
     */
     strcat(func_name, "__");
 
-    output_init_function(func_name, num_bunches_ptr,
-        num_calls_in_cur_bunch_ptr, purpose, MR_FALSE);
+    MR_ensure_room_for_next(std_module, const char *, MR_INIT_STD_MODULE_SIZE);
+    std_modules[std_module_next] = checked_strdup(func_name);
+    std_module_next++;
 
     if (aditi) {
         char    *rl_data_name;
@@ -1133,13 +1219,14 @@
 }
 
 static void
-process_init_file(const char *filename, int *num_bunches_ptr,
-    int *num_calls_in_cur_bunch_ptr, Purpose purpose)
+process_init_file(const char *filename)
 {
     const char * const  init_str = "INIT ";
+    const char * const  reqinit_str = "REQUIRED_INIT ";
     const char * const  endinit_str = "ENDINIT ";
     const char * const  aditi_init_str = "ADITI_DATA ";
     const int           init_strlen = strlen(init_str);
+    const int           reqinit_strlen = strlen(reqinit_str);
     const int           endinit_strlen = strlen(endinit_str);
     const int           aditi_init_strlen = strlen(aditi_init_str);
     char                line[MAXLINE];
@@ -1161,7 +1248,7 @@
             int     j;
             MR_bool special;
 
-            for (j = init_strlen; MR_isalnum(line[j]) || line[j] == '_'; j++) {
+            for (j = init_strlen; MR_isalnumunder(line[j]); j++) {
                 /* VOID */
             }
             line[j] = '\0';
@@ -1170,22 +1257,37 @@
             func_name_len = strlen(func_name);
             if (MR_strneq(&func_name[func_name_len - 4], "init", 4)) {
                 func_name[func_name_len - 4] = '\0';
-                special = MR_FALSE;
+                MR_ensure_room_for_next(std_module, const char *,
+                    MR_INIT_STD_MODULE_SIZE);
+                std_modules[std_module_next] = checked_strdup(func_name);
+                std_module_next++;
             } else {
-                special = MR_TRUE;
+                MR_ensure_room_for_next(special_module, const char *,
+                    MR_INIT_SPECIAL_MODULE_SIZE);
+                special_modules[special_module_next] =
+                    checked_strdupcat(func_name, "_");
+                special_module_next++;
             }
+        } else if (strncmp(line, reqinit_str, reqinit_strlen) == 0) {
+            char    *func_name;
+            int     j;
 
-            output_init_function(func_name, num_bunches_ptr,
-                num_calls_in_cur_bunch_ptr, purpose, special);
+            for (j = reqinit_strlen; MR_isalnumunder(line[j]); j++) {
+                /* VOID */
+            }
+            line[j] = '\0';
+
+            func_name = line + reqinit_strlen;
+            MR_ensure_room_for_next(req_module, const char *,
+                MR_INIT_REQ_MODULE_SIZE);
+            req_modules[req_module_next] = checked_strdup(func_name);
+            req_module_next++;
         } else if (aditi &&
             strncmp(line, aditi_init_str, aditi_init_strlen) == 0)
         {
             int j;
 
-            for (j = aditi_init_strlen;
-                MR_isalnum(line[j]) || line[j] == '_';
-                j++)
-            {
+            for (j = aditi_init_strlen; MR_isalnumunder(line[j]); j++) {
                 /* VOID */
             }
             line[j] = '\0';
@@ -1216,30 +1318,8 @@
 
 static void
 output_init_function(const char *func_name, int *num_bunches_ptr,
-    int *num_calls_in_cur_bunch_ptr, Purpose purpose, MR_bool special_module)
+    int *num_calls_in_cur_bunch_ptr, Purpose purpose)
 {
-    if (purpose == PURPOSE_DEBUGGER) {
-        if (special_module) {
-            /*
-            ** This is a handwritten "module" which doesn't have
-            ** a module layout to register.
-            */
-
-            return;
-        }
-    }
-
-    if (purpose == PURPOSE_COMPLEXITY) {
-        if (special_module) {
-            /*
-            ** This is a handwritten "module" whose code
-            ** cannot participate in complexity experiments.
-            */
-
-            return;
-        }
-    }
-
     if (*num_calls_in_cur_bunch_ptr >= maxcalls) {
         printf("}\n\n");
 
@@ -1253,12 +1333,10 @@
 
     (*num_calls_in_cur_bunch_ptr)++;
 
-    printf("\t{ extern void %s%s%s(%s);\n",
-        func_name, special_module ? "_" : "", module_suffix[purpose],
-        main_func_arg_decl[purpose]);
-    printf("\t  %s%s%s(%s); }\n",
-        func_name, special_module ? "_" : "", module_suffix[purpose],
-        main_func_arg[purpose]);
+    printf("\t{ extern void %s%s(%s);\n",
+        func_name, module_suffix[purpose], main_func_arg_decl[purpose]);
+    printf("\t  %s%s(%s); }\n",
+        func_name, module_suffix[purpose], main_func_arg[purpose]);
 }
 
 /*---------------------------------------------------------------------------*/
@@ -1405,6 +1483,37 @@
         fprintf(stderr, "Out of memory\n");
         exit(EXIT_FAILURE);
     }
+    return mem;
+}
+
+static char *
+checked_strdup(const char *str)
+{
+    char    *mem;
+
+    mem = malloc(strlen(str) + 1);
+    if (mem == NULL) {
+        fprintf(stderr, "Out of memory\n");
+        exit(EXIT_FAILURE);
+    }
+
+    strcpy(mem, str);
+    return mem;
+}
+
+static char *
+checked_strdupcat(const char *str, const char *suffix)
+{
+    char    *mem;
+
+    mem = malloc(strlen(str) + strlen(suffix) + 1);
+    if (mem == NULL) {
+        fprintf(stderr, "Out of memory\n");
+        exit(EXIT_FAILURE);
+    }
+
+    strcpy(mem, str);
+    strcat(mem, suffix);
     return mem;
 }
 
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list