Skip to content

Commit a1ac28d

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 a1ac28d

File tree

3 files changed

+76
-17
lines changed

3 files changed

+76
-17
lines changed

driver/main.c

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -321,23 +321,77 @@ 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+
DWORD exit_code;
333+
char *cmd2;
334+
size_t len;
335+
int rc;
336+
337+
len = strlen(cmd) + 13;
338+
cmd2 = malloc(len);
339+
rc = snprintf(cmd2, len, "cmd /S /C \"%s\"", cmd);
340+
if (rc < 0) {
341+
free(cmd2);
342+
return rc;
343+
}
344+
345+
if (verbose_flag)
346+
fprintf(stderr, "Executing: %s", cmd2);
347+
348+
STARTUPINFO si;
349+
PROCESS_INFORMATION pi;
350+
351+
memset(&si, 0x00, sizeof(si));
352+
si.cb = sizeof(si);
353+
memset(&pi, 0x00, sizeof(pi));
354+
355+
if (!CreateProcess(NULL, cmd2, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
356+
fprintf(stderr, "CreateProcess failed (%lu).\n", GetLastError());
357+
free(cmd2);
358+
return -1;
359+
}
360+
361+
WaitForSingleObject(pi.hProcess, INFINITE);
362+
GetExitCodeProcess(pi.hProcess, &exit_code);
363+
364+
CloseHandle(pi.hProcess);
365+
CloseHandle(pi.hThread);
366+
367+
free(cmd2);
368+
369+
return exit_code;
370+
}
371+
#else
372+
static int run_cmd(const char *cmd)
373+
{
374+
return system(cmd);
375+
}
376+
#endif
377+
324378
static int t_version_only(void)
325379
{
326380
int rc;
327381
remove(source_path);
328382
free(source_path);
329383

330384
fflush(0);
331-
snprintf(tmp, sizeof tmp, "%s%civlpp -V", ivlpp_dir, sep);
332-
rc = system(tmp);
385+
snprintf(tmp, sizeof tmp, "\"%s%civlpp\" -V", ivlpp_dir, sep);
386+
rc = run_cmd(tmp);
333387
if (rc != 0) {
334388
fprintf(stderr, "Unable to get version from \"%s\"\n", tmp);
335389
}
336390

337391
fflush(0);
338-
snprintf(tmp, sizeof tmp, "%s%civl -V -C\"%s\" -C\"%s\"", base, sep,
392+
snprintf(tmp, sizeof tmp, "\"%s%civl\" -V -C\"%s\" -C\"%s\"", base, sep,
339393
iconfig_path, iconfig_common_path);
340-
rc = system(tmp);
394+
rc = run_cmd(tmp);
341395
if (rc != 0) {
342396
fprintf(stderr, "Unable to get version from \"%s\"\n", tmp);
343397
}
@@ -356,7 +410,7 @@ static int t_version_only(void)
356410

357411
static void build_preprocess_command(int e_flag)
358412
{
359-
snprintf(tmp, sizeof tmp, "%s%civlpp%s%s%s -F\"%s\" -f\"%s\" -p\"%s\"%s",
413+
snprintf(tmp, sizeof tmp, "\"%s%civlpp\"%s%s%s -F\"%s\" -f\"%s\" -p\"%s\"%s",
360414
ivlpp_dir, sep,
361415
verbose_flag ? " -v" : "",
362416
e_flag ? "" : " -L",
@@ -388,7 +442,7 @@ static int t_preprocess_only(void)
388442
if (verbose_flag)
389443
printf("preprocess: %s\n", cmd);
390444

391-
rc = system(cmd);
445+
rc = run_cmd(cmd);
392446
remove(source_path);
393447
free(source_path);
394448

@@ -442,7 +496,7 @@ static int t_compile(void)
442496
#endif
443497

444498
/* Build the ivl command. */
445-
snprintf(tmp, sizeof tmp, "%s%civl", base, sep);
499+
snprintf(tmp, sizeof tmp, "\"%s%civl\"", base, sep);
446500
rc = strlen(tmp);
447501
cmd = realloc(cmd, ncmd+rc+1);
448502
strcpy(cmd+ncmd, tmp);
@@ -489,7 +543,7 @@ static int t_compile(void)
489543
printf("translate: %s\n", cmd);
490544

491545

492-
rc = system(cmd);
546+
rc = run_cmd(cmd);
493547
if ( ! getenv("IVERILOG_ICONFIG")) {
494548
remove(source_path);
495549
free(source_path);
@@ -1420,7 +1474,7 @@ int main(int argc, char **argv)
14201474

14211475
if (vhdlpp_work == 0)
14221476
vhdlpp_work = "ivl_vhdl_work";
1423-
fprintf(defines_file, "vhdlpp:%s%cvhdlpp\n", vhdlpp_dir, sep);
1477+
fprintf(defines_file, "vhdlpp:\"%s%cvhdlpp\"\n", vhdlpp_dir, sep);
14241478
fprintf(defines_file, "vhdlpp-work:%s\n", vhdlpp_work);
14251479
for (unsigned idx = 0 ; idx < vhdlpp_libdir_cnt ; idx += 1)
14261480
fprintf(defines_file, "vhdlpp-libdir:%s\n", vhdlpp_libdir[idx]);
@@ -1483,7 +1537,7 @@ int main(int argc, char **argv)
14831537
/* Write the preprocessor command needed to preprocess a
14841538
single file. This may be used to preprocess library
14851539
files. */
1486-
fprintf(iconfig_file, "ivlpp:%s%civlpp %s -L -F\"%s\" -P\"%s\"\n",
1540+
fprintf(iconfig_file, "ivlpp:\"%s%civlpp\" %s -L -F\"%s\" -P\"%s\"\n",
14871541
ivlpp_dir, sep,
14881542
strchr(warning_flags, 'r') ? "-Wredef-all" :
14891543
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)