Skip to content

Commit

Permalink
iverilog: Allow tool path to have spaces in it
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
larsclausen committed Dec 27, 2024
1 parent 66216de commit 0794189
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 17 deletions.
69 changes: 59 additions & 10 deletions driver/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,23 +321,72 @@ static const char*my_tempfile(const char*str, FILE**fout)
return pathbuf;
}

#ifdef __MINGW32__
/* system() on Windows is a bit special. It removes quotes at the begining and
* the end. Even if the quoted part is just part of the command.
* E.g. `"cmd" "arg"` would be executed as `cmd" "arg`. This prevents us from
* properly handling paths with spaces in it.
*/
static int run_cmd(const char *cmd)
{
char *cmd2;
size_t len;
int rc;

len = strlen(cmd) + 13;
cmd2 = malloc(len);
rc = snprintf(cmd2, len, "cmd /S /C \"%s\"", cmd);
if (rc < 0)
return rc;

if (verbose_flag)
fprintf(stderr, "Executing: %s", cmd2);

STARTUPINFO si;
PROCESS_INFORMATION pi;

memset(&si, 0x00, sizeof(si));
si.cb = sizeof(si);
memset(&pi, 0x00, sizeof(pi));

if (!CreateProcess(NULL, cmd2, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
fprintf(stderr, "CreateProcess failed (%lu).\n", GetLastError());
return -1;
}

WaitForSingleObject(pi.hProcess, INFINITE);

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

free(cmd2);

return 0;
}
#else
static int run_cmd(const char *cmd)
{
return system(cmd);
}
#endif

static int t_version_only(void)
{
int rc;
remove(source_path);
free(source_path);

fflush(0);
snprintf(tmp, sizeof tmp, "%s%civlpp -V", ivlpp_dir, sep);
rc = system(tmp);
snprintf(tmp, sizeof tmp, "\"%s%civlpp\" -V", ivlpp_dir, sep);
rc = run_cmd(tmp);
if (rc != 0) {
fprintf(stderr, "Unable to get version from \"%s\"\n", tmp);
}

fflush(0);
snprintf(tmp, sizeof tmp, "%s%civl -V -C\"%s\" -C\"%s\"", base, sep,
snprintf(tmp, sizeof tmp, "\"%s%civl\" -V -C\"%s\" -C\"%s\"", base, sep,
iconfig_path, iconfig_common_path);
rc = system(tmp);
rc = run_cmd(tmp);
if (rc != 0) {
fprintf(stderr, "Unable to get version from \"%s\"\n", tmp);
}
Expand All @@ -356,7 +405,7 @@ static int t_version_only(void)

static void build_preprocess_command(int e_flag)
{
snprintf(tmp, sizeof tmp, "%s%civlpp%s%s%s -F\"%s\" -f\"%s\" -p\"%s\"%s",
snprintf(tmp, sizeof tmp, "\"%s%civlpp\"%s%s%s -F\"%s\" -f\"%s\" -p\"%s\"%s",
ivlpp_dir, sep,
verbose_flag ? " -v" : "",
e_flag ? "" : " -L",
Expand Down Expand Up @@ -388,7 +437,7 @@ static int t_preprocess_only(void)
if (verbose_flag)
printf("preprocess: %s\n", cmd);

rc = system(cmd);
rc = run_cmd(cmd);
remove(source_path);
free(source_path);

Expand Down Expand Up @@ -442,7 +491,7 @@ static int t_compile(void)
#endif

/* Build the ivl command. */
snprintf(tmp, sizeof tmp, "%s%civl", base, sep);
snprintf(tmp, sizeof tmp, "\"%s%civl\"", base, sep);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp);
Expand Down Expand Up @@ -489,7 +538,7 @@ static int t_compile(void)
printf("translate: %s\n", cmd);


rc = system(cmd);
rc = run_cmd(cmd);
if ( ! getenv("IVERILOG_ICONFIG")) {
remove(source_path);
free(source_path);
Expand Down Expand Up @@ -1420,7 +1469,7 @@ int main(int argc, char **argv)

if (vhdlpp_work == 0)
vhdlpp_work = "ivl_vhdl_work";
fprintf(defines_file, "vhdlpp:%s%cvhdlpp\n", vhdlpp_dir, sep);
fprintf(defines_file, "vhdlpp:\"%s%cvhdlpp\"\n", vhdlpp_dir, sep);
fprintf(defines_file, "vhdlpp-work:%s\n", vhdlpp_work);
for (unsigned idx = 0 ; idx < vhdlpp_libdir_cnt ; idx += 1)
fprintf(defines_file, "vhdlpp-libdir:%s\n", vhdlpp_libdir[idx]);
Expand Down Expand Up @@ -1483,7 +1532,7 @@ int main(int argc, char **argv)
/* Write the preprocessor command needed to preprocess a
single file. This may be used to preprocess library
files. */
fprintf(iconfig_file, "ivlpp:%s%civlpp %s -L -F\"%s\" -P\"%s\"\n",
fprintf(iconfig_file, "ivlpp:\"%s%civlpp\" %s -L -F\"%s\" -P\"%s\"\n",
ivlpp_dir, sep,
strchr(warning_flags, 'r') ? "-Wredef-all" :
strchr(warning_flags, 'R') ? "-Wredef-chg" : "",
Expand Down
6 changes: 5 additions & 1 deletion ivlpp/lexor.lex
Original file line number Diff line number Diff line change
Expand Up @@ -2114,7 +2114,7 @@ static void open_input_file(struct include_stack_t*isp)
return;
}

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

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

char*cmd = malloc(cmdlen);
#ifdef __MINGW32__
snprintf(cmd, cmdlen, "cmd /S /C \"%s -w\"%s\"%s %s\"", vhdlpp_path, vhdlpp_work, libs, isp->path);
#else
snprintf(cmd, cmdlen, "%s -w\"%s\"%s %s", vhdlpp_path, vhdlpp_work, libs, isp->path);
#endif

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

Expand Down
13 changes: 7 additions & 6 deletions pform.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3410,12 +3410,13 @@ int pform_parse(const char*path)
if (strcmp(path, "-") == 0) {
vl_input = stdin;
} else if (ivlpp_string) {
char*cmdline = (char*)malloc(strlen(ivlpp_string) +
strlen(path) + 4);
strcpy(cmdline, ivlpp_string);
strcat(cmdline, " \"");
strcat(cmdline, path);
strcat(cmdline, "\"");
size_t cmdlen = strlen(ivlpp_string) + strlen(path) + 16;
char*cmdline = (char*)malloc(cmdlen);
#ifdef __MINGW32__
snprintf(cmdline, cmdlen, "cmd /S /C \"%s \"%s\"\"", ivlpp_string, path);
#else
snprintf(cmdline, cmdlen, "%s \"%s\"", ivlpp_string, path);
#endif

if (verbose_flag)
cerr << "Executing: " << cmdline << endl<< flush;
Expand Down

0 comments on commit 0794189

Please sign in to comment.