[m-rev.] diff: add -f option to mkinit to avoid command line overflows
Peter Ross
pro at missioncriticalit.com
Fri Jun 15 10:34:23 AEST 2007
Hi,
===================================================================
Estimated hours taken: 4
Branches: main
Windows has a limit on the command line length. Allow mkinit
to be passed a list of files to be processed in a file via
-f to avoid this limit.
compiler/compile_target_code.m:
Use the -f option to avoid overflowing the windows
command line.
util/mkinit.c:
Add code to handle the -f option.
Index: compiler/compile_target_code.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/compile_target_code.m,v
retrieving revision 1.111
diff -u -r1.111 compile_target_code.m
--- compiler/compile_target_code.m 14 Jun 2007 00:18:26 -0000 1.111
+++ compiler/compile_target_code.m 14 Jun 2007 07:22:39 -0000
@@ -995,12 +995,33 @@
InitFileRes = ok(InitFileStream),
list.map_foldl(module_name_to_file_name_ext(TargetExt, no),
AllModules, AllTargetFilesList, !IO),
- join_quoted_string_list(AllTargetFilesList, "", "", " ",
+ join_quoted_string_list(AllTargetFilesList, "", "\n", "",
TargetFileNames),
- MkInitCmd = string.append_list([MkInit, " -k ", TargetFileNames]),
- invoke_system_command(InitFileStream, cmd_verbose, MkInitCmd, MkInitOK,
- !IO),
+ io.make_temp(TmpFile, !IO),
+ io.open_output(TmpFile, OpenResult, !IO),
+ (
+ OpenResult = ok(TmpStream),
+ io.write_string(TmpStream, TargetFileNames, !IO),
+ io.close_output(TmpStream, !IO),
+
+ MkInitCmd = string.append_list([MkInit, " -k -f ", TmpFile]),
+ invoke_system_command(InitFileStream, cmd_verbose,
+ MkInitCmd, MkInitOK0, !IO),
+
+ io.remove_file(TmpFile, RemoveResult, !IO),
+ (
+ RemoveResult = ok,
+ MkInitOK = MkInitOK0
+ ;
+ RemoveResult = error(_),
+ MkInitOK = no
+ )
+ ;
+ OpenResult = error(_),
+ MkInitOK = no
+ ),
+
(
MkInitOK = yes,
Index: util/mkinit.c
===================================================================
RCS file: /home/mercury1/repository/mercury/util/mkinit.c,v
retrieving revision 1.116
diff -u -r1.116 mkinit.c
--- util/mkinit.c 8 Jun 2007 00:47:15 -0000 1.116
+++ util/mkinit.c 14 Jun 2007 07:22:40 -0000
@@ -59,7 +59,11 @@
#endif
/* --- adjustable limits --- */
-#define MAXCALLS 40 /* maximum number of calls per function */
+#define MAXCALLS 40 /* maximum number of calls per function */
+
+#define MAXFILENAME 4096 /* maximimum file name length */
+#define NUMFILES 128 /* intial size of files array */
+#define FACTOR 2 /* factor to increase files array by */
/* --- used to collect a list of strings --- */
@@ -277,7 +281,8 @@
static const char *grade = "";
static int maxcalls = MAXCALLS;
static int num_files;
-static char **files;
+static int size_of_files;
+static char **files = NULL;
static MR_bool output_main_func = MR_TRUE;
static MR_bool need_initialization_code = MR_FALSE;
static MR_bool need_tracing = MR_FALSE;
@@ -528,6 +533,7 @@
/* --- function prototypes --- */
static void parse_options(int argc, char *argv[]);
+static void process_file_list_file(char *filename);
static void usage(void);
static void output_complexity_proc(const char *procname);
static void output_complexity_experiment_table(const char *filename);
@@ -721,12 +727,13 @@
int c;
int i;
String_List *tmp_slist;
+ int seen_f_option = 0;
/*
** The set of options for mkinit and mkinit_erl should be
** kept in sync, even if they may not necessarily make sense.
*/
- while ((c = getopt(argc, argv, "A:c:g:iI:lm:o:r:tw:xX:ks")) != EOF) {
+ while ((c = getopt(argc, argv, "A:c:f:g:iI:lm:o:r:tw:xX:ks")) != EOF) {
switch (c) {
case 'A':
/*
@@ -751,6 +758,11 @@
break;
+ case 'f':
+ process_file_list_file(optarg);
+ seen_f_option = 1;
+ break;
+
case 'g':
grade = optarg;
break;
@@ -825,12 +837,66 @@
}
}
- num_files = argc - optind;
+ if (seen_f_option) {
+ /*
+ ** -f could be made compatible if we copied the filenames
+ ** from argv into files.
+ **
+ */
+ if ((argc - optind) > 0) {
+ fprintf(stderr,
+ "%s: -f incompatible with filenames on the command line\n",
+ MR_progname);
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ num_files = argc - optind;
+ files = argv + optind;
+ }
+
if (num_files <= 0) {
usage();
}
+}
+
+static void
+process_file_list_file(char *filename)
+{
+ FILE *fp;
+ char *line;
- files = argv + optind;
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+ fprintf(stderr, "%s: error opening file `%s': %s\n",
+ MR_progname, filename, strerror(errno));
+ num_errors++;
+ return;
+ }
+ /* intialize the files structure, if required */
+ if (files == NULL) {
+ num_files = 0;
+ size_of_files = NUMFILES;
+ files = (char **) checked_malloc(sizeof(char *) * NUMFILES);
+ }
+
+ while ((line = read_line(filename, fp, MAXFILENAME)) != NULL) {
+ /* Ignore blank lines */
+ if (line[0] != '\0') {
+ if (num_files >= size_of_files) {
+ size_of_files *= FACTOR;
+ files = (char **)
+ realloc(files, size_of_files * sizeof(char *));
+
+ if (files == NULL) {
+ fprintf(stderr, "%s: unable to realloc\n", MR_progname);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ files[num_files] = line;
+ num_files++;
+ }
+ }
}
static void
@@ -839,6 +905,7 @@
fputs("Usage: mkinit [options] files...\n", stderr);
fputs("Options:\n", stderr);
fputs(" -c maxcalls:\tset the max size of an init function\n", stderr);
+ fputs(" -f filename:\tprocess the files one per line in filename\n", stderr);
fputs(" -g grade:\tset the grade of the executable\n", stderr);
fputs(" -i:\t\tenable initialization code\n", stderr);
fputs(" -l:\t\tdo not output main function\n", stderr);
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list