From 5aa69516bb9e0b60a1e371b64c42c5c5ca3b34c4 Mon Sep 17 00:00:00 2001 From: steve Date: Tue, 28 May 2002 20:40:37 +0000 Subject: [PATCH] ivl indexes the search path for libraries, and supports case insensitive module-to-file lookup. --- compiler.h | 30 ++------ driver/cflexor.lex | 6 +- driver/cfparse.y | 14 +++- driver/globals.h | 7 +- driver/main.c | 11 ++- load_module.cc | 180 +++++++++++++++++++++++++++++++++++---------- main.cc | 32 +++++--- 7 files changed, 202 insertions(+), 78 deletions(-) diff --git a/compiler.h b/compiler.h index 2cfdf3d99..c1e4364d1 100644 --- a/compiler.h +++ b/compiler.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: compiler.h,v 1.11 2002/05/28 00:50:39 steve Exp $" +#ident "$Id: compiler.h,v 1.12 2002/05/28 20:40:37 steve Exp $" #endif # include @@ -75,9 +75,9 @@ extern bool warn_timescale; /* This is true if verbose output is requested. */ extern bool verbose_flag; -/* This is an ordered list of libraries to search. */ -extern listlibrary_dirs; +/* This is an ordered list of library suffixxes to search. */ extern listlibrary_suff; +extern int build_library_index(const char*path, bool key_case_sensitive); /* This is the generation of Verilog that the compiler is asked to support. */ @@ -95,6 +95,10 @@ extern char*ivlpp_string; /* * $Log: compiler.h,v $ + * Revision 1.12 2002/05/28 20:40:37 steve + * ivl indexes the search path for libraries, and + * supports case insensitive module-to-file lookup. + * * Revision 1.11 2002/05/28 00:50:39 steve * Add the ivl -C flag for bulk configuration * from the driver, and use that to run library @@ -111,25 +115,5 @@ extern char*ivlpp_string; * * Revision 1.7 2001/11/16 05:07:19 steve * Add support for +libext+ in command files. - * - * Revision 1.6 2001/10/20 23:02:40 steve - * Add automatic module libraries. - * - * Revision 1.5 2000/10/31 17:49:02 steve - * Support time variables. - * - * Revision 1.4 2000/08/20 04:13:56 steve - * Add ivl_target support for logic gates, and - * make the interface more accessible. - * - * Revision 1.3 2000/03/17 21:50:25 steve - * Switch to control warnings. - * - * Revision 1.2 2000/02/23 02:56:54 steve - * Macintosh compilers do not support ident. - * - * Revision 1.1 1999/06/06 20:42:48 steve - * Make compiler width a compile time constant. - * */ #endif diff --git a/driver/cflexor.lex b/driver/cflexor.lex index b2d88103b..ef43cbec4 100644 --- a/driver/cflexor.lex +++ b/driver/cflexor.lex @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: cflexor.lex,v 1.5 2001/12/08 04:13:07 steve Exp $" +#ident "$Id: cflexor.lex,v 1.6 2002/05/28 20:40:37 steve Exp $" #endif # include "cfparse.h" @@ -70,6 +70,10 @@ static int comment_enter; "+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; } +"+libdir+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR; } + +"+libdir-nocase+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR_NOCASE; } + "+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; } diff --git a/driver/cfparse.y b/driver/cfparse.y index a6bcbfc2b..ceed944df 100644 --- a/driver/cfparse.y +++ b/driver/cfparse.y @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: cfparse.y,v 1.6 2002/01/02 02:39:34 steve Exp $" +#ident "$Id: cfparse.y,v 1.7 2002/05/28 20:40:37 steve Exp $" #endif @@ -58,7 +58,7 @@ static void translate_file_name(char*text) }; %token TOK_Da TOK_Dv TOK_Dy -%token TOK_DEFINE TOK_INCDIR TOK_LIBEXT +%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT %token TOK_PLUSARG TOK_PLUSWORD TOK_STRING %% @@ -107,6 +107,16 @@ item free($2); } + | TOK_LIBDIR TOK_PLUSARG + { process_library_switch($2); + free($2); + } + + | TOK_LIBDIR_NOCASE TOK_PLUSARG + { process_library_nocase_switch($2); + free($2); + } + | TOK_DEFINE TOK_PLUSARG { process_define($2); free($2); diff --git a/driver/globals.h b/driver/globals.h index 75f6261c9..91cfe8716 100644 --- a/driver/globals.h +++ b/driver/globals.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: globals.h,v 1.13 2002/05/28 00:50:40 steve Exp $" +#ident "$Id: globals.h,v 1.14 2002/05/28 20:40:37 steve Exp $" #endif # include @@ -65,6 +65,7 @@ extern void process_file_name(const char*name); /* Add the name to the list of library directories. */ extern void process_library_switch(const char*name); +extern void process_library_nocase_switch(const char*name); extern void process_library2_switch(const char*name); /* Add a new include file search directory */ @@ -88,6 +89,10 @@ extern int build_string(char*out, size_t olen, const char*pattern); /* * $Log: globals.h,v $ + * Revision 1.14 2002/05/28 20:40:37 steve + * ivl indexes the search path for libraries, and + * supports case insensitive module-to-file lookup. + * * Revision 1.13 2002/05/28 00:50:40 steve * Add the ivl -C flag for bulk configuration * from the driver, and use that to run library diff --git a/driver/main.c b/driver/main.c index 9f9382fa7..b7b3a0884 100644 --- a/driver/main.c +++ b/driver/main.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ident "$Id: main.c,v 1.40 2002/05/28 02:25:03 steve Exp $" +#ident "$Id: main.c,v 1.41 2002/05/28 20:40:37 steve Exp $" # include "config.h" @@ -305,6 +305,11 @@ void process_library_switch(const char *name) fprintf(iconfig_file, "-y:%s\n", name); } +void process_library_nocase_switch(const char *name) +{ + fprintf(iconfig_file, "-yl:%s\n", name); +} + void process_library2_switch(const char *name) { fprintf(iconfig_file, "-Y:%s\n", name); @@ -716,6 +721,10 @@ int main(int argc, char **argv) /* * $Log: main.c,v $ + * Revision 1.41 2002/05/28 20:40:37 steve + * ivl indexes the search path for libraries, and + * supports case insensitive module-to-file lookup. + * * Revision 1.40 2002/05/28 02:25:03 steve * Pass library paths through -Cfile instead of command line. * diff --git a/load_module.cc b/load_module.cc index c37471a2a..86e44d0da 100644 --- a/load_module.cc +++ b/load_module.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: load_module.cc,v 1.6 2002/05/28 00:50:39 steve Exp $" +#ident "$Id: load_module.cc,v 1.7 2002/05/28 20:40:37 steve Exp $" #endif # include "config.h" @@ -25,65 +25,165 @@ # include "parse_api.h" # include "compiler.h" # include +# include +# include +# include +# include +# include +/* + * The module library items are maps of key names to file name within + * the directory. + */ +struct module_library { + char*dir; + bool key_case_sensitive; + mapname_map; + struct module_library*next; +}; + +static struct module_library*library_list = 0; +static struct module_library*library_last = 0; + const char dir_character = '/'; extern FILE *depend_file; +/* + * Use the type name as a key, and search the module library for a + * file name that has that key. + */ bool load_module(const char*type) { char path[4096]; + char*ltype = strdup(type); - for (list::iterator cur = library_dirs.begin() - ; cur != library_dirs.end() - ; cur ++ ) { - for (list::iterator suf = library_suff.begin() - ; suf != library_suff.end() - ; suf ++ ) { + for (char*tmp = ltype ; *tmp ; tmp += 1) + *tmp = tolower(*tmp); - sprintf(path, "%s%c%s%s", *cur, dir_character, type, *suf); + for (struct module_library*lcur = library_list + ; lcur != 0 ; lcur = lcur->next) { + + const char*key = lcur->key_case_sensitive? type : ltype; + map::const_iterator cur; + cur = lcur->name_map.find(key); + if (cur == lcur->name_map.end()) + continue; + + sprintf(path, "%s%c%s", lcur->dir, dir_character, (*cur).second); + + if(depend_file) { + fprintf(depend_file, "%s\n", path); + } + + if (ivlpp_string) { + char*cmdline = (char*)malloc(strlen(ivlpp_string) + + strlen(path) + 2); + strcpy(cmdline, ivlpp_string); + strcat(cmdline, " "); + strcat(cmdline, path); + FILE*file = popen(cmdline, "r"); + + if (verbose_flag) + cerr << "Executing: " << cmdline << endl; + + pform_parse(path, file); + fclose(file); + free(cmdline); + + } else { + if (verbose_flag) + cerr << "Loading library file " + << path << "." << endl; FILE*file = fopen(path, "r"); - if (file == 0) - continue; - if(depend_file) { - fprintf(depend_file, "%s\n", path); - } - - if (ivlpp_string) { - fclose(file); - char*cmdline = (char*)malloc(strlen(ivlpp_string) + - strlen(path) + 2); - strcpy(cmdline, ivlpp_string); - strcat(cmdline, " "); - strcat(cmdline, path); - file = popen(cmdline, "r"); - - if (verbose_flag) - cerr << "Executing: " << cmdline << endl; - - pform_parse(path, file); - fclose(file); - - } else { - if (verbose_flag) - cerr << "Loading library file " - << path << "." << endl; - - pform_parse(path, file); - - fclose(file); - } - - return true; + assert(file); + pform_parse(path, file); + fclose(file); } + + return true; } + return false; } +/* + * This function takes the name of a library directory that the caller + * passed, and builds a name index for it. + */ +int build_library_index(const char*path, bool key_case_sensitive) +{ + DIR*dir = opendir(path); + if (dir == 0) + return -1; + + if (verbose_flag) { + cerr << "Indexing library: " << path << endl; + } + + struct module_library*mlp = new struct module_library; + mlp->dir = strdup(path); + mlp->key_case_sensitive = key_case_sensitive; + + while (struct dirent*de = readdir(dir)) { + unsigned namsiz = strlen(de->d_name); + char*key = 0; + + for (list::iterator suf = library_suff.begin() + ; suf != library_suff.end() + ; suf ++ ) { + const char*sufptr = *suf; + unsigned sufsiz = strlen(sufptr); + + if (sufsiz >= namsiz) + continue; + + if (strcmp(de->d_name + (namsiz-sufsiz), sufptr) != 0) + continue; + + key = new char[namsiz-sufsiz+1]; + strncpy(key, de->d_name, namsiz-sufsiz); + key[namsiz-sufsiz] = 0; + break; + } + + if (key == 0) + continue; + + /* If the key is not to be case sensitive, then change + it to lowercase. */ + if (! key_case_sensitive) + for (char*tmp = key ; *tmp ; tmp += 1) + *tmp = tolower(*tmp); + + mlp->name_map[key] = strdup(de->d_name); + delete[]key; + } + + closedir(dir); + + if (library_last) { + assert(library_list); + library_last->next = mlp; + mlp->next = 0; + library_last = mlp; + } else { + library_list = mlp; + library_last = mlp; + mlp->next = 0; + } + + return 0; +} + /* * $Log: load_module.cc,v $ + * Revision 1.7 2002/05/28 20:40:37 steve + * ivl indexes the search path for libraries, and + * supports case insensitive module-to-file lookup. + * * Revision 1.6 2002/05/28 00:50:39 steve * Add the ivl -C flag for bulk configuration * from the driver, and use that to run library diff --git a/main.cc b/main.cc index 465d7e5ae..9ada6a887 100644 --- a/main.cc +++ b/main.cc @@ -19,7 +19,7 @@ const char COPYRIGHT[] = * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: main.cc,v 1.57 2002/05/28 02:25:03 steve Exp $" +#ident "$Id: main.cc,v 1.58 2002/05/28 20:40:37 steve Exp $" #endif # include "config.h" @@ -80,7 +80,6 @@ generation_t generation_flag = GN_DEFAULT; map flags; -list library_dirs; list library_suff; char*ivlpp_string = 0; @@ -99,6 +98,15 @@ bool error_implicit = false; */ bool verbose_flag = false; +/* + * In library searches, Windows file names are never case sensitive. + */ +#if defined(__MINGW32__) +const bool CASE_SENSITIVE = false; +#else +const bool CASE_SENSITIVE = true; +#endif + /* * Read the contents of a config file. This file is a temporary * configuration file made by the compiler driver to carry the bulky @@ -138,7 +146,10 @@ static void read_iconfig_file(const char*ipath) ivlpp_string = strdup(cp); } else if (strcmp(buf, "-y") == 0) { - library_dirs.push_back(strdup(cp)); + build_library_index(cp, CASE_SENSITIVE); + + } else if (strcmp(buf, "-yl") == 0) { + build_library_index(cp, false); } else if (strcmp(buf, "-Y") == 0) { library_suff.push_back(strdup(cp)); @@ -255,6 +266,8 @@ int main(int argc, char*argv[]) struct tms cycles[5]; + library_suff.push_back(".v"); + flags["VPI_MODULE_LIST"] = "system"; flags["-o"] = "a.out"; min_typ_max_flag = TYP; @@ -341,7 +354,7 @@ int main(int argc, char*argv[]) warn_en = optarg; break; case 'y': - library_dirs.push_back(optarg); + build_library_index(optarg, CASE_SENSITIVE); break; case 'Y': library_suff.push_back(optarg); @@ -358,6 +371,7 @@ int main(int argc, char*argv[]) cout << "Icarus Verilog version " << VERSION << endl << "usage: ivl \n" "options:\n" +"\t-C Config file from driver.\n" "\t-F Apply netlist function .\n" "\t-h Print usage information, and exit.\n" "\t-m Load vpi module .\n" @@ -400,12 +414,6 @@ int main(int argc, char*argv[]) } - /* If there were no -Y flags, then create a minimal library - suffix search list. */ - if (library_suff.empty()) { - library_suff.push_back(".v"); - } - /* Scan the warnings enable string for warning flags. */ for (const char*cp = warn_en ; *cp ; cp += 1) switch (*cp) { case 'i': @@ -583,6 +591,10 @@ int main(int argc, char*argv[]) /* * $Log: main.cc,v $ + * Revision 1.58 2002/05/28 20:40:37 steve + * ivl indexes the search path for libraries, and + * supports case insensitive module-to-file lookup. + * * Revision 1.57 2002/05/28 02:25:03 steve * Pass library paths through -Cfile instead of command line. *