mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-17 06:47:17 +00:00
Allow the user to conveniently use Mercury libraries installed in
Estimated hours taken: 70 Allow the user to conveniently use Mercury libraries installed in non-standard places, by specifying the variables `EXTRA_LIBRARIES' and `EXTRA_LIB_DIRS' in their Mmakefile. doc/user_guide.texi: Documented the new `EXTRA_LIBRARIES' and `EXTRA_LIB_DIRS' Mmake variables. scripts/Mmake.vars.in: Added/changed definitions appropriately to support the new variables. This included adding a `GRADESTRING' variable which holds the canonical name of the grade being used, taking into account all the grade flags. scripts/c2init.in: Added a new option to `c2init': -I/--init-file-directory <directory> adds the directory to the list of directories to search for `.init' files. util/mkinit.c: Added a new option `-I' to add a directory to the list of directories to search for `.init' files.
This commit is contained in:
@@ -530,6 +530,18 @@ specified in @code{GRADEFLAGS} and @code{C2INITARGS}, respectively.)
|
|||||||
Extra files to be processed by c2init. These variables should not be
|
Extra files to be processed by c2init. These variables should not be
|
||||||
used for specifying flags to c2init (that's what @code{C2INITFLAGS} is for)
|
used for specifying flags to c2init (that's what @code{C2INITFLAGS} is for)
|
||||||
since they are also used to derive extra dependency information.
|
since they are also used to derive extra dependency information.
|
||||||
|
|
||||||
|
@item EXTRA_LIBRARIES
|
||||||
|
A list of extra Mercury libraries to link into any programs or libraries
|
||||||
|
that you are building.
|
||||||
|
Libraries should be specified using their base name; that is, without any
|
||||||
|
@samp{lib} prefix or extension.
|
||||||
|
For example the library including the files @file{libfoo.a} and
|
||||||
|
@file{foo.init} would be referred to as just @samp{foo}.
|
||||||
|
|
||||||
|
@item EXTRA_LIB_DIRS
|
||||||
|
A list of extra Mercury library directory hierarchies to search when
|
||||||
|
looking for extra libraries.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
Other variables also exist - see
|
Other variables also exist - see
|
||||||
@@ -582,6 +594,7 @@ and, on many platforms, it supports shared object libraries.
|
|||||||
* Building libraries::
|
* Building libraries::
|
||||||
* Installing libraries::
|
* Installing libraries::
|
||||||
* Using libraries::
|
* Using libraries::
|
||||||
|
* Supporting multiple grades and architectures::
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node Writing libraries
|
@node Writing libraries
|
||||||
@@ -779,6 +792,45 @@ for each Mercury library being used are all put in a single directory,
|
|||||||
which is probably the simplest way of organizing things, but the
|
which is probably the simplest way of organizing things, but the
|
||||||
Mercury implementation does not require that.
|
Mercury implementation does not require that.
|
||||||
|
|
||||||
|
@node Supporting multiple grades and architectures
|
||||||
|
@section Supporting multiple grades and architectures
|
||||||
|
|
||||||
|
In order to better support using and installing libraries in multiple
|
||||||
|
grades, @samp{mmake} now has some support for alternative library directory
|
||||||
|
hierarchies.
|
||||||
|
These have the same structure as the @file{@var{prefix}/lib/mercury} tree,
|
||||||
|
including the different subdirectories for different grades and different
|
||||||
|
machine architectures.
|
||||||
|
|
||||||
|
Automatically installing a library and all its associated files to such a
|
||||||
|
tree is not yet supported, but until it is the user can use the same
|
||||||
|
techniques used for building and installing the core Mercury libraries.
|
||||||
|
|
||||||
|
Once a library is installed in such a hierarchy, using it is easy.
|
||||||
|
Suppose the user wishes to use the library @samp{mypackage} (installed
|
||||||
|
in the tree rooted at @samp{/some/directory/mypackage}) and the library
|
||||||
|
@samp{myotherlib} (installed in the tree rooted at
|
||||||
|
@samp{/some/directory/myotherlib}).
|
||||||
|
The user need only set the following Mmake variables:
|
||||||
|
|
||||||
|
@example
|
||||||
|
EXTRA_LIB_DIRS = /some/directory/mypackage /some/directory/myotherlib
|
||||||
|
EXTRA_LIBRARIES = mypackage myotherlib
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Mmake will then ensure that the appropriate directories are searched for
|
||||||
|
the relevant interface files, module initialisation files, compiled
|
||||||
|
libraries, etc.
|
||||||
|
|
||||||
|
One can specify extra libraries to be used on a program-by-program
|
||||||
|
basis. For instance, if the program @samp{foo} also uses the library
|
||||||
|
@samp{mylib4foo}, but the other programs governed by the Mmakefile don't,
|
||||||
|
then one can declare:
|
||||||
|
|
||||||
|
@example
|
||||||
|
EXTRA_LIBRARIES-foo = mylib4foo
|
||||||
|
@end example
|
||||||
|
|
||||||
@node Debugging
|
@node Debugging
|
||||||
@chapter Debugging
|
@chapter Debugging
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,31 @@
|
|||||||
# Ensure that commands use /bin/sh not the user's shell
|
# Ensure that commands use /bin/sh not the user's shell
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
|
ALL_EXTRA_LIBRARIES = $(TARGET_EXTRA_LIBRARIES) $(EXTRA_LIBRARIES)
|
||||||
|
EXTRA_LIB_DIRS =
|
||||||
|
EXTRA_LIBRARIES =
|
||||||
|
|
||||||
|
EXTRA_INT_DIRS = $(patsubst %,%/ints,$(EXTRA_LIB_DIRS))
|
||||||
|
MERCURY_EXTRA_INT_DIRS = $(EXTRA_INT_DIRS)
|
||||||
|
EXTRA_C_LIB_DIRS = \
|
||||||
|
$(patsubst %,%/lib/$(GRADESTRING)/@FULLARCH@,$(EXTRA_LIB_DIRS)) \
|
||||||
|
$(patsubst %,%/lib/@FULLARCH@,$(EXTRA_LIB_DIRS))
|
||||||
|
EXTRA_C_INCL_DIRS = $(patsubst %,%/inc,$(EXTRA_LIB_DIRS))
|
||||||
|
EXTRA_INIT_DIRS = $(patsubst %,%/modules,$(EXTRA_LIB_DIRS))
|
||||||
|
MERCURY_EXTRA_INIT_DIRS = $(EXTRA_INIT_DIRS)
|
||||||
|
|
||||||
# Set the directory search path.
|
# Set the directory search path.
|
||||||
# (See the GNU Make manual for documentation about VPATH and GPATH.)
|
# (See the GNU Make manual for documentation about VPATH and GPATH.)
|
||||||
MMAKE_VPATH = $(MERCURY_INT_DIR)
|
# We need to substitute all spaces with colons for the VPATH to work.
|
||||||
|
# Getting a space to be recognised as the first argument of the subst
|
||||||
|
# function is problematic; hence the `$(nullstring)' hack.
|
||||||
|
# XXX Note that directory names with spaces in them (e.g. under Windows)
|
||||||
|
# will cause problems for the VPATH settings below, as well as every
|
||||||
|
# occurrence of $(patsubst ...), since GNU Make does not respect quotes.
|
||||||
|
nullstring =
|
||||||
|
MMAKE_VPATH = $(subst $(nullstring) ,:,$(strip \
|
||||||
|
$(MERCURY_EXTRA_INT_DIRS) $(MERCURY_INT_DIR)\
|
||||||
|
$(MERCURY_EXTRA_INIT_DIRS)))
|
||||||
VPATH = $(MMAKE_VPATH) # do not remove the `:' from this comment!!!
|
VPATH = $(MMAKE_VPATH) # do not remove the `:' from this comment!!!
|
||||||
# the above comment works around a misfeature of
|
# the above comment works around a misfeature of
|
||||||
# autoconf which causes it to delete assignments to
|
# autoconf which causes it to delete assignments to
|
||||||
@@ -23,15 +45,17 @@ GPATH = $(VPATH)
|
|||||||
|
|
||||||
DEFAULT_GRADE = $(MERCURY_DEFAULT_GRADE)
|
DEFAULT_GRADE = $(MERCURY_DEFAULT_GRADE)
|
||||||
GRADE = $(DEFAULT_GRADE)
|
GRADE = $(DEFAULT_GRADE)
|
||||||
|
GRADESTRING = $(shell $(MCOGS) $(ALL_GRADEFLAGS))
|
||||||
|
|
||||||
ALL_GRADEFLAGS = $(GRADEFLAGS) $(EXTRA_GRADEFLAGS) $(TARGET_GRADEFLAGS)
|
ALL_GRADEFLAGS = $(GRADEFLAGS) $(EXTRA_GRADEFLAGS) $(TARGET_GRADEFLAGS)
|
||||||
GRADEFLAGS = --grade $(GRADE)
|
GRADEFLAGS = --grade $(GRADE)
|
||||||
EXTRA_GRADEFLAGS =
|
EXTRA_GRADEFLAGS =
|
||||||
|
|
||||||
MC = mmc
|
MC = mmc
|
||||||
ALL_MCFLAGS = $(MCFLAGS) $(EXTRA_MCFLAGS) $(TARGET_MCFLAGS)
|
ALL_MCFLAGS = $(MCFLAGS) $(EXTRA_MCFLAGS) $(TARGET_MCFLAGS) $(LIB_MCFLAGS)
|
||||||
MCFLAGS =
|
MCFLAGS =
|
||||||
EXTRA_MCFLAGS =
|
EXTRA_MCFLAGS =
|
||||||
|
LIB_MCFLAGS = $(patsubst %,-I %,$(EXTRA_INT_DIRS))
|
||||||
|
|
||||||
MCS = $(MC) --split-c-files --compile-only
|
MCS = $(MC) --split-c-files --compile-only
|
||||||
MCG = $(MC) --compile-to-c
|
MCG = $(MC) --compile-to-c
|
||||||
@@ -41,15 +65,24 @@ MCPI = $(MC) --make-private-interface
|
|||||||
MCSI = $(MC) --make-short-interface
|
MCSI = $(MC) --make-short-interface
|
||||||
MCOI = $(MC) --make-optimization-interface
|
MCOI = $(MC) --make-optimization-interface
|
||||||
MCTOI = $(MC) --make-transitive-optimization-interface
|
MCTOI = $(MC) --make-transitive-optimization-interface
|
||||||
|
MCOGS = $(MC) --output-grade-string
|
||||||
|
|
||||||
ALL_MCIFLAGS = $(MCIFLAGS) $(EXTRA_MCIFLAGS) $(TARGET_MCFLAGS)
|
ALL_MCIFLAGS = $(MCIFLAGS) $(EXTRA_MCIFLAGS) $(TARGET_MCFLAGS) \
|
||||||
ALL_MCPIFLAGS = $(MCPIFLAGS) $(EXTRA_MCPIFLAGS) $(TARGET_MCFLAGS)
|
$(LIB_MCFLAGS)
|
||||||
ALL_MCSIFLAGS = $(MCSIFLAGS) $(EXTRA_MCSIFLAGS) $(TARGET_MCFLAGS)
|
ALL_MCPIFLAGS = $(MCPIFLAGS) $(EXTRA_MCPIFLAGS) $(TARGET_MCFLAGS) \
|
||||||
ALL_MCOIFLAGS = $(MCOIFLAGS) $(EXTRA_MCOIFLAGS) $(TARGET_MCFLAGS)
|
$(LIB_MCFLAGS)
|
||||||
ALL_MCTOIFLAGS = $(MCTOIFLAGS) $(EXTRA_MCTOIFLAGS) $(TARGET_MCFLAGS)
|
ALL_MCSIFLAGS = $(MCSIFLAGS) $(EXTRA_MCSIFLAGS) $(TARGET_MCFLAGS) \
|
||||||
ALL_MCDFLAGS = $(MCDFLAGS) $(EXTRA_MCDFLAGS) $(TARGET_MCFLAGS)
|
$(LIB_MCFLAGS)
|
||||||
ALL_MCGFLAGS = $(MCGFLAGS) $(EXTRA_MCGFLAGS) $(TARGET_MCFLAGS)
|
ALL_MCOIFLAGS = $(MCOIFLAGS) $(EXTRA_MCOIFLAGS) $(TARGET_MCFLAGS) \
|
||||||
ALL_MCSFLAGS = $(MCSFLAGS) $(EXTRA_MCSFLAGS) $(TARGET_MCFLAGS)
|
$(LIB_MCFLAGS)
|
||||||
|
ALL_MCTOIFLAGS = $(MCTOIFLAGS) $(EXTRA_MCTOIFLAGS) $(TARGET_MCFLAGS) \
|
||||||
|
$(LIB_MCFLAGS)
|
||||||
|
ALL_MCDFLAGS = $(MCDFLAGS) $(EXTRA_MCDFLAGS) $(TARGET_MCFLAGS) \
|
||||||
|
$(LIB_MCFLAGS)
|
||||||
|
ALL_MCGFLAGS = $(MCGFLAGS) $(EXTRA_MCGFLAGS) $(TARGET_MCFLAGS) \
|
||||||
|
$(LIB_MCFLAGS)
|
||||||
|
ALL_MCSFLAGS = $(MCSFLAGS) $(EXTRA_MCSFLAGS) $(TARGET_MCFLAGS) \
|
||||||
|
$(LIB_MCFLAGS)
|
||||||
|
|
||||||
MCIFLAGS = $(MCFLAGS)
|
MCIFLAGS = $(MCFLAGS)
|
||||||
MCPIFLAGS = $(MCFLAGS)
|
MCPIFLAGS = $(MCFLAGS)
|
||||||
@@ -74,13 +107,17 @@ EXTRA_MCSFLAGS = $(EXTRA_MCFLAGS)
|
|||||||
# the options which should be passed to them.
|
# the options which should be passed to them.
|
||||||
#
|
#
|
||||||
C2INIT = c2init
|
C2INIT = c2init
|
||||||
ALL_C2INITFLAGS = $(C2INITFLAGS) $(EXTRA_C2INITFLAGS) $(TARGET_C2INITFLAGS)
|
ALL_C2INITFLAGS = $(C2INITFLAGS) $(EXTRA_C2INITFLAGS) $(TARGET_C2INITFLAGS) \
|
||||||
|
$(LIB_C2INITFLAGS)
|
||||||
C2INITFLAGS =
|
C2INITFLAGS =
|
||||||
EXTRA_C2INITFLAGS =
|
EXTRA_C2INITFLAGS =
|
||||||
|
LIB_C2INITFLAGS = $(patsubst %,--init-file-directory %,$(EXTRA_INIT_DIRS))
|
||||||
|
|
||||||
ALL_C2INITARGS = $(C2INITARGS) $(EXTRA_C2INITARGS) $(TARGET_C2INITARGS)
|
ALL_C2INITARGS = $(C2INITARGS) $(EXTRA_C2INITARGS) $(TARGET_C2INITARGS) \
|
||||||
|
$(LIB_C2INITARGS)
|
||||||
C2INITARGS =
|
C2INITARGS =
|
||||||
EXTRA_C2INITARGS =
|
EXTRA_C2INITARGS =
|
||||||
|
LIB_C2INITARGS = $(patsubst %,%.init,$(ALL_EXTRA_LIBRARIES))
|
||||||
|
|
||||||
MGNUC = mgnuc
|
MGNUC = mgnuc
|
||||||
ALL_MGNUCFLAGS = $(MGNUCFLAGS) $(EXTRA_MGNUCFLAGS) $(TARGET_MGNUCFLAGS) \
|
ALL_MGNUCFLAGS = $(MGNUCFLAGS) $(EXTRA_MGNUCFLAGS) $(TARGET_MGNUCFLAGS) \
|
||||||
@@ -93,13 +130,15 @@ CFLAGS =
|
|||||||
EXTRA_CFLAGS =
|
EXTRA_CFLAGS =
|
||||||
|
|
||||||
ML = ml
|
ML = ml
|
||||||
ALL_MLFLAGS = $(MLFLAGS) $(EXTRA_MLFLAGS) $(TARGET_MLFLAGS)
|
ALL_MLFLAGS = $(MLFLAGS) $(EXTRA_MLFLAGS) $(TARGET_MLFLAGS) $(LIB_MLFLAGS)
|
||||||
MLFLAGS = $(EXTRA_MLFLAGS)
|
MLFLAGS = $(EXTRA_MLFLAGS)
|
||||||
EXTRA_MLFLAGS =
|
EXTRA_MLFLAGS =
|
||||||
|
LIB_MLFLAGS = $(patsubst %,-R%,$(EXTRA_C_LIB_DIRS)) \
|
||||||
|
$(patsubst %,-L%,$(EXTRA_C_LIB_DIRS))
|
||||||
|
|
||||||
MLOBJS =
|
MLOBJS =
|
||||||
MLPICOBJS = $(MLOBJS:.o=.$(EXT_FOR_PIC_OBJECTS))
|
MLPICOBJS = $(MLOBJS:.o=.$(EXT_FOR_PIC_OBJECTS))
|
||||||
ALL_MLLIBS = $(MLLIBS) $(EXTRA_MLLIBS) $(TARGET_MLLIBS)
|
ALL_MLLIBS = $(MLLIBS) $(EXTRA_MLLIBS) $(TARGET_MLLIBS) $(LIB_MLLIBS)
|
||||||
# XXX ALL_MLLIBS_DEP should contain a list of the file names of the
|
# XXX ALL_MLLIBS_DEP should contain a list of the file names of the
|
||||||
# libraries specified in ALL_MLLIBS, but I can't see how to know whether
|
# libraries specified in ALL_MLLIBS, but I can't see how to know whether
|
||||||
# they should be `.a' or `.so' libraries, so for now we leave it empty.
|
# they should be `.a' or `.so' libraries, so for now we leave it empty.
|
||||||
@@ -107,6 +146,7 @@ ALL_MLLIBS = $(MLLIBS) $(EXTRA_MLLIBS) $(TARGET_MLLIBS)
|
|||||||
ALL_MLLIBS_DEP =
|
ALL_MLLIBS_DEP =
|
||||||
MLLIBS =
|
MLLIBS =
|
||||||
EXTRA_MLLIBS =
|
EXTRA_MLLIBS =
|
||||||
|
LIB_MLLIBS = $(patsubst %,-l%,$(ALL_EXTRA_LIBRARIES))
|
||||||
|
|
||||||
MNC = mnc
|
MNC = mnc
|
||||||
ALL_MNCFLAGS = $(MNCFLAGS) $(EXTRA_MNCFLAGS) $(TARGET_MNCFLAGS)
|
ALL_MNCFLAGS = $(MNCFLAGS) $(EXTRA_MNCFLAGS) $(TARGET_MNCFLAGS)
|
||||||
@@ -256,6 +296,15 @@ TARGET_RANLIBFLAGS = \
|
|||||||
maybe-target-RANLIBFLAGS- = $(RANLIBFLAGS-$@)
|
maybe-target-RANLIBFLAGS- = $(RANLIBFLAGS-$@)
|
||||||
maybe-target-RANLIBFLAGS-undefined =
|
maybe-target-RANLIBFLAGS-undefined =
|
||||||
|
|
||||||
|
# Note we strip any trailing `_init.c' from `$@' so we get the appropriate
|
||||||
|
# "base" name, regardless of whether this variable ends up being used as
|
||||||
|
# an argument of a `c2init' rule or an `ml' rule.
|
||||||
|
TARGET_EXTRA_LIBRARIES = \
|
||||||
|
$(maybe-target-EXTRA_LIBRARIES-$(findstring undefined,\
|
||||||
|
$(origin EXTRA_LIBRARIES-$(patsubst %_init.c,%,$@))))
|
||||||
|
maybe-target-EXTRA_LIBRARIES- = $(EXTRA_LIBRARIES-$(patsubst %_init.c,%,$@))
|
||||||
|
maybe-target-EXTRA_LIBRARIES-undefined =
|
||||||
|
|
||||||
# Support for compiling Mercury programs with Prolog will probably be
|
# Support for compiling Mercury programs with Prolog will probably be
|
||||||
# dropped one of these days, so it's probably not worth bothering with these.
|
# dropped one of these days, so it's probably not worth bothering with these.
|
||||||
TARGET_MNCFLAGS =
|
TARGET_MNCFLAGS =
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ Options:
|
|||||||
(declared in \"init.h\") that can be called from C code.
|
(declared in \"init.h\") that can be called from C code.
|
||||||
(A more fine-grained interface is also available;
|
(A more fine-grained interface is also available;
|
||||||
see \"init.h\" for details.)
|
see \"init.h\" for details.)
|
||||||
|
-I <directory>, --init-file-directory <directory>
|
||||||
|
Include <directory> in the list of directories searched to
|
||||||
|
locate \`.init' files.
|
||||||
-w <label>, --entry-point <label>
|
-w <label>, --entry-point <label>
|
||||||
Set entry point to <label>.
|
Set entry point to <label>.
|
||||||
(Default value is \`mercury__main_2_0'.)
|
(Default value is \`mercury__main_2_0'.)
|
||||||
@@ -88,6 +91,7 @@ trace_opt=""
|
|||||||
library_opt=""
|
library_opt=""
|
||||||
extra_inits_opt=""
|
extra_inits_opt=""
|
||||||
aditi_opt=""
|
aditi_opt=""
|
||||||
|
extra_init_dirs=""
|
||||||
|
|
||||||
# include the file `init_grade_options.sh-subr'
|
# include the file `init_grade_options.sh-subr'
|
||||||
@INIT_GRADE_OPTIONS@
|
@INIT_GRADE_OPTIONS@
|
||||||
@@ -113,6 +117,9 @@ while true; do
|
|||||||
-l-|--no-library)
|
-l-|--no-library)
|
||||||
library_opt="";;
|
library_opt="";;
|
||||||
|
|
||||||
|
-I|--init-file-directory)
|
||||||
|
extra_init_dirs="$extra_init_dirs -I $2"; shift;;
|
||||||
|
|
||||||
-w|--entry-point)
|
-w|--entry-point)
|
||||||
defentry="$2"; shift;;
|
defentry="$2"; shift;;
|
||||||
|
|
||||||
@@ -176,10 +183,10 @@ esac
|
|||||||
case $# in
|
case $# in
|
||||||
0) exec $MKINIT $aditi_opt -c"$maxcalls" $init_opt $trace_opt \
|
0) exec $MKINIT $aditi_opt -c"$maxcalls" $init_opt $trace_opt \
|
||||||
$library_opt -w"$defentry" $extra_inits_opt \
|
$library_opt -w"$defentry" $extra_inits_opt \
|
||||||
$MERCURY_MOD_LIB_MODS
|
$extra_init_dirs $EXTRA_INIT_FILES $MERCURY_MOD_LIB_MODS
|
||||||
;;
|
;;
|
||||||
*) exec $MKINIT $aditi_opt -c"$maxcalls" $init_opt $trace_opt \
|
*) exec $MKINIT $aditi_opt -c"$maxcalls" $init_opt $trace_opt \
|
||||||
$library_opt -w"$defentry" $extra_inits_opt "$@" \
|
$library_opt -w"$defentry" $extra_inits_opt \
|
||||||
$MERCURY_MOD_LIB_MODS
|
$extra_init_dirs "$@" $EXTRA_INIT_FILES $MERCURY_MOD_LIB_MODS
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
113
util/mkinit.c
113
util/mkinit.c
@@ -23,6 +23,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
#include "mercury_conf.h"
|
#include "mercury_conf.h"
|
||||||
#include "mercury_std.h"
|
#include "mercury_std.h"
|
||||||
@@ -32,7 +34,7 @@
|
|||||||
#define MAXLINE 256 /* maximum number of characters per line */
|
#define MAXLINE 256 /* maximum number of characters per line */
|
||||||
/* (characters after this limit are ignored) */
|
/* (characters after this limit are ignored) */
|
||||||
|
|
||||||
/* --- used to collect Aditi data constant names --- */
|
/* --- used to collect a list of strings, e.g. Aditi data constant names --- */
|
||||||
|
|
||||||
typedef struct String_List_struct {
|
typedef struct String_List_struct {
|
||||||
char *data;
|
char *data;
|
||||||
@@ -57,6 +59,12 @@ static bool need_tracing = FALSE;
|
|||||||
static int num_modules = 0;
|
static int num_modules = 0;
|
||||||
static int num_errors = 0;
|
static int num_errors = 0;
|
||||||
|
|
||||||
|
/* List of directories to search for init files */
|
||||||
|
static String_List *init_file_dirs = NULL;
|
||||||
|
|
||||||
|
/* Pointer to tail of the init_file_dirs list */
|
||||||
|
static String_List **init_file_dirs_tail = &init_file_dirs;
|
||||||
|
|
||||||
/* List of names of Aditi-RL code constants. */
|
/* List of names of Aditi-RL code constants. */
|
||||||
static String_List *rl_data = NULL;
|
static String_List *rl_data = NULL;
|
||||||
|
|
||||||
@@ -229,6 +237,9 @@ static const char if_need_to_init[] =
|
|||||||
/* --- function prototypes --- */
|
/* --- function prototypes --- */
|
||||||
static void parse_options(int argc, char *argv[]);
|
static void parse_options(int argc, char *argv[]);
|
||||||
static void usage(void);
|
static void usage(void);
|
||||||
|
static void do_path_search(void);
|
||||||
|
static char *find_init_file(const char *basename);
|
||||||
|
static bool file_exists(const char *filename);
|
||||||
static void output_headers(void);
|
static void output_headers(void);
|
||||||
static void output_sub_init_functions(void);
|
static void output_sub_init_functions(void);
|
||||||
static void output_main_init_function(void);
|
static void output_main_init_function(void);
|
||||||
@@ -279,6 +290,8 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
parse_options(argc, argv);
|
parse_options(argc, argv);
|
||||||
|
|
||||||
|
do_path_search();
|
||||||
|
|
||||||
output_headers();
|
output_headers();
|
||||||
output_sub_init_functions();
|
output_sub_init_functions();
|
||||||
output_main_init_function();
|
output_main_init_function();
|
||||||
@@ -305,7 +318,8 @@ static void
|
|||||||
parse_options(int argc, char *argv[])
|
parse_options(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
while ((c = getopt(argc, argv, "ac:iltw:x")) != EOF) {
|
String_List *tmp_slist;
|
||||||
|
while ((c = getopt(argc, argv, "ac:iI:ltw:x")) != EOF) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'a':
|
case 'a':
|
||||||
aditi = TRUE;
|
aditi = TRUE;
|
||||||
@@ -320,6 +334,21 @@ parse_options(int argc, char *argv[])
|
|||||||
need_initialization_code = TRUE;
|
need_initialization_code = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'I':
|
||||||
|
/*
|
||||||
|
** Add the directory name to the end of the
|
||||||
|
** search path for `.init' files.
|
||||||
|
*/
|
||||||
|
tmp_slist = (String_List *)
|
||||||
|
checked_malloc(sizeof(String_List));
|
||||||
|
tmp_slist->next = NULL;
|
||||||
|
tmp_slist->data = (char *)
|
||||||
|
checked_malloc(strlen(optarg) + 1);
|
||||||
|
strcpy(tmp_slist->data, optarg);
|
||||||
|
*init_file_dirs_tail = tmp_slist;
|
||||||
|
init_file_dirs_tail = &tmp_slist->next;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
output_main_func = FALSE;
|
output_main_func = FALSE;
|
||||||
break;
|
break;
|
||||||
@@ -355,6 +384,86 @@ usage(void)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Scan the list of files for ones not found in the current
|
||||||
|
** directory, and replace them with their full path equivalent
|
||||||
|
** if they are found in the list of search directories.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
do_path_search(void)
|
||||||
|
{
|
||||||
|
int filenum;
|
||||||
|
char *init_file;
|
||||||
|
|
||||||
|
for (filenum = 0; filenum < num_files; filenum++) {
|
||||||
|
init_file = find_init_file(files[filenum]);
|
||||||
|
if (init_file != NULL)
|
||||||
|
files[filenum] = init_file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Search the init file directory list to locate the file.
|
||||||
|
** If the file is in the current directory or is not in any of the
|
||||||
|
** search directories, then return NULL. Otherwise return the full
|
||||||
|
** path name to the file.
|
||||||
|
** It is the caller's responsibility to free the returned buffer
|
||||||
|
** holding the full path name when it is no longer needed.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
find_init_file(const char *basename)
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
char *dirname;
|
||||||
|
String_List *dir_ptr;
|
||||||
|
int dirlen;
|
||||||
|
int baselen;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (file_exists(basename)) {
|
||||||
|
/* File is in current directory, so no search required */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
baselen = strlen(basename);
|
||||||
|
|
||||||
|
for (dir_ptr = init_file_dirs; dir_ptr != NULL;
|
||||||
|
dir_ptr = dir_ptr->next)
|
||||||
|
{
|
||||||
|
dirname = dir_ptr->data;
|
||||||
|
dirlen = strlen(dirname);
|
||||||
|
len = dirlen + 1 + baselen;
|
||||||
|
|
||||||
|
filename = (char *) checked_malloc(len + 1);
|
||||||
|
strcpy(filename, dirname);
|
||||||
|
filename[dirlen] = '/';
|
||||||
|
strcpy(filename + dirlen + 1, basename);
|
||||||
|
|
||||||
|
if (file_exists(filename))
|
||||||
|
return filename;
|
||||||
|
|
||||||
|
free(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Did not find file */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Check whether a file exists.
|
||||||
|
** At some point in the future it may be worth making this
|
||||||
|
** implementation more portable.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
file_exists(const char *filename)
|
||||||
|
{
|
||||||
|
struct stat buf;
|
||||||
|
|
||||||
|
return (stat(filename, &buf) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
Reference in New Issue
Block a user