Skip to content

Commit 0794189

Browse files
committed
iverilog: Allow tool path to have spaces in it
When invoking the various subcommands make sure the path to the executable is quoted. This allows it to contain spaces. Signed-off-by: Lars-Peter Clausen <[email protected]>
1 parent 66216de commit 0794189

File tree

3 files changed

+71
-17
lines changed

3 files changed

+71
-17
lines changed

driver/main.c

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -321,23 +321,72 @@ static const char*my_tempfile(const char*str, FILE**fout)
321321
return pathbuf;
322322
}
323323

324+
#ifdef __MINGW32__
325+
/* system() on Windows is a bit special. It removes quotes at the begining and
326+
* the end. Even if the quoted part is just part of the command.
327+
* E.g. `"cmd" "arg"` would be executed as `cmd" "arg`. This prevents us from
328+
* properly handling paths with spaces in it.
329+
*/
330+
static int run_cmd(const char *cmd)
331+
{
332+
char *cmd2;
333+
size_t len;
334+
int rc;
335+
336+
len = strlen(cmd) + 13;
337+
cmd2 = malloc(len);
338+
rc = snprintf(cmd2, len, "cmd /S /C \"%s\"", cmd);
339+
if (rc < 0)
340+
return rc;
341+
342+
if (verbose_flag)
343+
fprintf(stderr, "Executing: %s", cmd2);
344+
345+
STARTUPINFO si;
346+
PROCESS_INFORMATION pi;
347+
348+
memset(&si, 0x00, sizeof(si));
349+
si.cb = sizeof(si);
350+
memset(&pi, 0x00, sizeof(pi));
351+
352+
if (!CreateProcess(NULL, cmd2, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
353+
fprintf(stderr, "CreateProcess failed (%lu).\n", GetLastError());
354+
return -1;
355+
}
356+
357+
WaitForSingleObject(pi.hProcess, INFINITE);
358+
359+
CloseHandle(pi.hProcess);
360+
CloseHandle(pi.hThread);
361+
362+
free(cmd2);
363+
364+
return 0;
365+
}
366+
#else
367+
static int run_cmd(const char *cmd)
368+
{
369+
return system(cmd);
370+
}
371+
#endif
372+
324373
static int t_version_only(void)
325374
{
326375
int rc;
327376
remove(source_path);
328377
free(source_path);
329378

330379
fflush(0);
331-
snprintf(tmp, sizeof tmp, "%s%civlpp -V", ivlpp_dir, sep);
332-
rc = system(tmp);
380+
snprintf(tmp, sizeof tmp, "\"%s%civlpp\" -V", ivlpp_dir, sep);
381+
rc = run_cmd(tmp);
333382
if (rc != 0) {
334383
fprintf(stderr, "Unable to get version from \"%s\"\n", tmp);
335384
}
336385

337386
fflush(0);
338-
snprintf(tmp, sizeof tmp, "%s%civl -V -C\"%s\" -C\"%s\"", base, sep,
387+
snprintf(tmp, sizeof tmp, "\"%s%civl\" -V -C\"%s\" -C\"%s\"", base, sep,
339388
iconfig_path, iconfig_common_path);
340-
rc = system(tmp);
389+
rc = run_cmd(tmp);
341390
if (rc != 0) {
342391
fprintf(stderr, "Unable to get version from \"%s\"\n", tmp);
343392
}
@@ -356,7 +405,7 @@ static int t_version_only(void)
356405

357406
static void build_preprocess_command(int e_flag)
358407
{
359-
snprintf(tmp, sizeof tmp, "%s%civlpp%s%s%s -F\"%s\" -f\"%s\" -p\"%s\"%s",
408+
snprintf(tmp, sizeof tmp, "\"%s%civlpp\"%s%s%s -F\"%s\" -f\"%s\" -p\"%s\"%s",
360409
ivlpp_dir, sep,
361410
verbose_flag ? " -v" : "",
362411
e_flag ? "" : " -L",
@@ -388,7 +437,7 @@ static int t_preprocess_only(void)
388437
if (verbose_flag)
389438
printf("preprocess: %s\n", cmd);
390439

391-
rc = system(cmd);
440+
rc = run_cmd(cmd);
392441
remove(source_path);
393442
free(source_path);
394443

@@ -442,7 +491,7 @@ static int t_compile(void)
442491
#endif
443492

444493
/* Build the ivl command. */
445-
snprintf(tmp, sizeof tmp, "%s%civl", base, sep);
494+
snprintf(tmp, sizeof tmp, "\"%s%civl\"", base, sep);
446495
rc = strlen(tmp);
447496
cmd = realloc(cmd, ncmd+rc+1);
448497
strcpy(cmd+ncmd, tmp);
@@ -489,7 +538,7 @@ static int t_compile(void)
489538
printf("translate: %s\n", cmd);
490539

491540

492-
rc = system(cmd);
541+
rc = run_cmd(cmd);
493542
if ( ! getenv("IVERILOG_ICONFIG")) {
494543
remove(source_path);
495544
free(source_path);
@@ -1420,7 +1469,7 @@ int main(int argc, char **argv)
14201469

14211470
if (vhdlpp_work == 0)
14221471
vhdlpp_work = "ivl_vhdl_work";
1423-
fprintf(defines_file, "vhdlpp:%s%cvhdlpp\n", vhdlpp_dir, sep);
1472+
fprintf(defines_file, "vhdlpp:\"%s%cvhdlpp\"\n", vhdlpp_dir, sep);
14241473
fprintf(defines_file, "vhdlpp-work:%s\n", vhdlpp_work);
14251474
for (unsigned idx = 0 ; idx < vhdlpp_libdir_cnt ; idx += 1)
14261475
fprintf(defines_file, "vhdlpp-libdir:%s\n", vhdlpp_libdir[idx]);
@@ -1483,7 +1532,7 @@ int main(int argc, char **argv)
14831532
/* Write the preprocessor command needed to preprocess a
14841533
single file. This may be used to preprocess library
14851534
files. */
1486-
fprintf(iconfig_file, "ivlpp:%s%civlpp %s -L -F\"%s\" -P\"%s\"\n",
1535+
fprintf(iconfig_file, "ivlpp:\"%s%civlpp\" %s -L -F\"%s\" -P\"%s\"\n",
14871536
ivlpp_dir, sep,
14881537
strchr(warning_flags, 'r') ? "-Wredef-all" :
14891538
strchr(warning_flags, 'R') ? "-Wredef-chg" : "",

ivlpp/lexor.lex

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2114,7 +2114,7 @@ static void open_input_file(struct include_stack_t*isp)
21142114
return;
21152115
}
21162116

2117-
size_t cmdlen = strlen(vhdlpp_path);
2117+
size_t cmdlen = strlen(vhdlpp_path) + 12;
21182118
cmdlen += strlen(isp->path);
21192119
cmdlen += 8+strlen(vhdlpp_work);
21202120

@@ -2130,7 +2130,11 @@ static void open_input_file(struct include_stack_t*isp)
21302130
cmdlen += liblen;
21312131

21322132
char*cmd = malloc(cmdlen);
2133+
#ifdef __MINGW32__
2134+
snprintf(cmd, cmdlen, "cmd /S /C \"%s -w\"%s\"%s %s\"", vhdlpp_path, vhdlpp_work, libs, isp->path);
2135+
#else
21332136
snprintf(cmd, cmdlen, "%s -w\"%s\"%s %s", vhdlpp_path, vhdlpp_work, libs, isp->path);
2137+
#endif
21342138

21352139
if (verbose_flag) fprintf(stderr, "Invoke vhdlpp: %s\n", cmd);
21362140

pform.cc

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3410,12 +3410,13 @@ int pform_parse(const char*path)
34103410
if (strcmp(path, "-") == 0) {
34113411
vl_input = stdin;
34123412
} else if (ivlpp_string) {
3413-
char*cmdline = (char*)malloc(strlen(ivlpp_string) +
3414-
strlen(path) + 4);
3415-
strcpy(cmdline, ivlpp_string);
3416-
strcat(cmdline, " \"");
3417-
strcat(cmdline, path);
3418-
strcat(cmdline, "\"");
3413+
size_t cmdlen = strlen(ivlpp_string) + strlen(path) + 16;
3414+
char*cmdline = (char*)malloc(cmdlen);
3415+
#ifdef __MINGW32__
3416+
snprintf(cmdline, cmdlen, "cmd /S /C \"%s \"%s\"\"", ivlpp_string, path);
3417+
#else
3418+
snprintf(cmdline, cmdlen, "%s \"%s\"", ivlpp_string, path);
3419+
#endif
34193420

34203421
if (verbose_flag)
34213422
cerr << "Executing: " << cmdline << endl<< flush;

0 commit comments

Comments
 (0)