Refactor vpi module path code.

Also restore the original behaviour of the '-M -' option, although it's
probably not needed now we add the default path last.
This commit is contained in:
Martin Whitaker 2018-10-29 20:33:52 +00:00
parent dd33da0d5b
commit 6887c31d8c
3 changed files with 97 additions and 91 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2015 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2018 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -303,14 +303,9 @@ int main(int argc, char*argv[])
break;
case 'M':
if (strcmp(optarg,"-") == 0) {
vpip_module_path_cnt = 0;
vpip_module_path[0] = 0;
vpip_clear_module_paths();
} else {
if (vpip_module_path_cnt >= VPIP_MODULE_PATH_MAX) {
fprintf(stderr, "Too many paths specified\n");
return -1;
}
vpip_module_path[vpip_module_path_cnt++] = optarg;
vpip_add_module_path(optarg);
}
break;
case 'm':
@ -336,82 +331,7 @@ int main(int argc, char*argv[])
flag_errors += 1;
}
if (char *var = ::getenv("IVERILOG_VPI_MODULE_PATH")) {
char *ptr = var;
char *end = var+strlen(var);
int len = 0;
while (ptr <= end) {
if (*ptr == 0 || *ptr == ':' || *ptr == ';') {
if (len > 0) {
if (vpip_module_path_cnt >= VPIP_MODULE_PATH_MAX) {
fprintf(stderr, "Too many paths specified\n");
return -1;
}
vpip_module_path[vpip_module_path_cnt++] = strndup(var, len);
}
len = 0;
var = ptr+1;
} else {
len++;
}
ptr++;
}
}
#ifdef __MINGW32__
/* Calculate the module path from the path to the command.
This is necessary because of the installation process on
Windows. Mostly, it is those darn drive letters, but oh
well. We know the command path is formed like this:
D:\iverilog\bin\iverilog.exe
The IVL_ROOT in a Windows installation is the path:
D:\iverilog\lib\ivl$(suffix)
so we chop the file name and the last directory by
turning the last two \ characters to null. Then we append
the lib\ivl$(suffix) to finish. */
char *s;
char basepath[4096], tmp[4096];
GetModuleFileName(NULL, tmp, sizeof tmp);
/* Convert to a short name to remove any embedded spaces. */
GetShortPathName(tmp, basepath, sizeof basepath);
s = strrchr(basepath, '\\');
if (s) *s = 0;
else {
fprintf(stderr, "%s: Missing first \\ in exe path!\n", argv[0]);
exit(1);
}
s = strrchr(basepath, '\\');
if (s) *s = 0;
else {
fprintf(stderr, "%s: Missing second \\ in exe path!\n", argv[0]);
exit(1);
}
strcat(s, "\\lib\\ivl" IVL_SUFFIX);
if (vpip_module_path_cnt >= VPIP_MODULE_PATH_MAX) {
fprintf(stderr, "Too many paths specified\n");
return -1;
}
vpip_module_path[vpip_module_path_cnt++] = strdup(basepath);
#else
#ifdef MODULE_DIR1
if (vpip_module_path_cnt >= VPIP_MODULE_PATH_MAX) {
fprintf(stderr, "Too many paths specified\n");
return -1;
}
vpip_module_path[vpip_module_path_cnt++] = MODULE_DIR1;
#endif
#endif
#ifdef MODULE_DIR2
if (vpip_module_path_cnt >= VPIP_MODULE_PATH_MAX) {
fprintf(stderr, "Too many paths specified\n");
return -1;
}
vpip_module_path[vpip_module_path_cnt++] = MODULE_DIR2;
#endif
vpip_add_env_and_default_module_paths();
if (flag_errors)
return flag_errors;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2018 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -32,10 +32,96 @@ static unsigned dll_list_cnt = 0;
typedef void (*vlog_startup_routines_t)(void);
# define VPIP_MODULE_PATH_MAX 64
const char* vpip_module_path[VPIP_MODULE_PATH_MAX] = {0};
static const char* vpip_module_path[VPIP_MODULE_PATH_MAX] = {0};
unsigned vpip_module_path_cnt = 0;
static unsigned vpip_module_path_cnt = 0;
static bool disable_default_paths = false;
void vpip_clear_module_paths()
{
vpip_module_path_cnt = 0;
vpip_module_path[0] = 0;
disable_default_paths = true;
}
void vpip_add_module_path(const char*path)
{
if (vpip_module_path_cnt >= VPIP_MODULE_PATH_MAX) {
fprintf(stderr, "Too many module paths specified\n");
exit(1);
}
vpip_module_path[vpip_module_path_cnt++] = path;
}
void vpip_add_env_and_default_module_paths()
{
if (disable_default_paths)
return;
if (char *var = ::getenv("IVERILOG_VPI_MODULE_PATH")) {
char *ptr = var;
char *end = var+strlen(var);
int len = 0;
while (ptr <= end) {
if (*ptr == 0 || *ptr == ':' || *ptr == ';') {
if (len > 0) {
vpip_add_module_path(strndup(var, len));
}
len = 0;
var = ptr+1;
} else {
len++;
}
ptr++;
}
}
#ifdef __MINGW32__
/* Calculate the module path from the path to the command.
This is necessary because of the installation process on
Windows. Mostly, it is those darn drive letters, but oh
well. We know the command path is formed like this:
D:\iverilog\bin\iverilog.exe
The IVL_ROOT in a Windows installation is the path:
D:\iverilog\lib\ivl$(suffix)
so we chop the file name and the last directory by
turning the last two \ characters to null. Then we append
the lib\ivl$(suffix) to finish. */
char *s;
char basepath[4096], tmp[4096];
GetModuleFileName(NULL, tmp, sizeof tmp);
/* Convert to a short name to remove any embedded spaces. */
GetShortPathName(tmp, basepath, sizeof basepath);
s = strrchr(basepath, '\\');
if (s) *s = 0;
else {
fprintf(stderr, "%s: Missing first \\ in exe path!\n", argv[0]);
exit(1);
}
s = strrchr(basepath, '\\');
if (s) *s = 0;
else {
fprintf(stderr, "%s: Missing second \\ in exe path!\n", argv[0]);
exit(1);
}
strcat(s, "\\lib\\ivl" IVL_SUFFIX);
vpip_add_module_path(strdup(basepath));
#else
#ifdef MODULE_DIR1
vpip_add_module_path(MODULE_DIR1);
#endif
#endif
#ifdef MODULE_DIR2
vpip_add_module_path(MODULE_DIR2);
#endif
}
void load_module_delete(void)
{

View File

@ -1,7 +1,7 @@
#ifndef IVL_vpi_priv_H
#define IVL_vpi_priv_H
/*
* Copyright (c) 2001-2017 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2018 Stephen Williams (steve@icarus.com)
* Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch)
*
* This source code is free software; you can redistribute it
@ -873,9 +873,9 @@ vpiHandle vpip_make_vthr_APV(char*label, unsigned index, unsigned bit, unsigned
*/
extern void vpip_load_module(const char*name);
# define VPIP_MODULE_PATH_MAX 64
extern const char* vpip_module_path[VPIP_MODULE_PATH_MAX];
extern unsigned vpip_module_path_cnt;
extern void vpip_clear_module_paths();
extern void vpip_add_module_path(const char *path);
extern void vpip_add_env_and_default_module_paths();
/*
* The vpip_build_vpi_call function creates a __vpiSysTaskCall object