Add the ability to dump array words
[iverilog.git] / load_module.cc
blob3f282fc84723dc207cb53245043a3ec6870194f8
1 /*
2 * Copyright (c) 2001 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #ifdef HAVE_CVS_IDENT
20 #ident "$Id: load_module.cc,v 1.13 2005/03/22 15:53:48 steve Exp $"
21 #endif
23 # include "config.h"
24 # include "util.h"
25 # include "parse_api.h"
26 # include "compiler.h"
27 # include <iostream>
28 # include <map>
29 # include <string>
30 # include <sys/types.h>
31 # include <dirent.h>
32 # include <ctype.h>
33 # include <assert.h>
36 * The module library items are maps of key names to file name within
37 * the directory.
39 struct module_library {
40 char*dir;
41 bool key_case_sensitive;
42 map<string,const char*>name_map;
43 struct module_library*next;
46 static struct module_library*library_list = 0;
47 static struct module_library*library_last = 0;
49 const char dir_character = '/';
50 extern FILE *depend_file;
53 * Use the type name as a key, and search the module library for a
54 * file name that has that key.
56 bool load_module(const char*type)
58 char path[4096];
59 char*ltype = strdup(type);
61 for (char*tmp = ltype ; *tmp ; tmp += 1)
62 *tmp = tolower(*tmp);
64 for (struct module_library*lcur = library_list
65 ; lcur != 0 ; lcur = lcur->next) {
67 const char*key = lcur->key_case_sensitive? type : ltype;
68 map<string,const char*>::const_iterator cur;
69 cur = lcur->name_map.find(key);
70 if (cur == lcur->name_map.end())
71 continue;
73 sprintf(path, "%s%c%s", lcur->dir, dir_character, (*cur).second);
75 if(depend_file) {
76 fprintf(depend_file, "%s\n", path);
79 if (ivlpp_string) {
80 char*cmdline = (char*)malloc(strlen(ivlpp_string) +
81 strlen(path) + 2);
82 strcpy(cmdline, ivlpp_string);
83 strcat(cmdline, " ");
84 strcat(cmdline, path);
85 FILE*file = popen(cmdline, "r");
87 if (verbose_flag)
88 cerr << "Executing: " << cmdline << endl;
90 pform_parse(path, file);
91 pclose(file);
92 free(cmdline);
94 } else {
95 if (verbose_flag)
96 cerr << "Loading library file "
97 << path << "." << endl;
99 FILE*file = fopen(path, "r");
100 assert(file);
101 pform_parse(path, file);
102 fclose(file);
105 return true;
109 return false;
113 * This function takes the name of a library directory that the caller
114 * passed, and builds a name index for it.
116 int build_library_index(const char*path, bool key_case_sensitive)
118 DIR*dir = opendir(path);
119 if (dir == 0)
120 return -1;
122 if (verbose_flag) {
123 cerr << "Indexing library: " << path << endl;
126 struct module_library*mlp = new struct module_library;
127 mlp->dir = strdup(path);
128 mlp->key_case_sensitive = key_case_sensitive;
130 /* Scan the director for files. check each file name to see if
131 it has one of the configured suffixes. If it does, then use
132 the root of the name as the key and index the file name. */
133 while (struct dirent*de = readdir(dir)) {
134 unsigned namsiz = strlen(de->d_name);
135 char*key = 0;
137 for (list<const char*>::iterator suf = library_suff.begin()
138 ; suf != library_suff.end()
139 ; suf ++ ) {
140 const char*sufptr = *suf;
141 unsigned sufsiz = strlen(sufptr);
143 if (sufsiz >= namsiz)
144 continue;
146 /* If the directory is case insensitive, then so
147 is the suffix. */
148 if (key_case_sensitive) {
149 if (strcmp(de->d_name + (namsiz-sufsiz),
150 sufptr) != 0)
151 continue;
152 } else {
153 if (strcasecmp(de->d_name + (namsiz-sufsiz),
154 sufptr) != 0)
155 continue;
158 key = new char[namsiz-sufsiz+1];
159 strncpy(key, de->d_name, namsiz-sufsiz);
160 key[namsiz-sufsiz] = 0;
162 break;
165 if (key == 0)
166 continue;
168 /* If the key is not to be case sensitive, then change
169 it to lowercase. */
170 if (! key_case_sensitive)
171 for (char*tmp = key ; *tmp ; tmp += 1)
172 *tmp = tolower(*tmp);
174 mlp->name_map[key] = strdup(de->d_name);
175 delete[]key;
178 closedir(dir);
180 if (library_last) {
181 assert(library_list);
182 library_last->next = mlp;
183 mlp->next = 0;
184 library_last = mlp;
185 } else {
186 library_list = mlp;
187 library_last = mlp;
188 mlp->next = 0;
191 return 0;
195 * $Log: load_module.cc,v $
196 * Revision 1.13 2005/03/22 15:53:48 steve
197 * popen must be matched by pclose.
199 * Revision 1.12 2003/06/05 04:31:09 steve
200 * INclude missing assert.h in load_module.
202 * Revision 1.11 2002/08/12 01:34:59 steve
203 * conditional ident string using autoconfig.
205 * Revision 1.10 2002/08/03 22:30:00 steve
206 * Fix suffix parsing of library index.
208 * Revision 1.9 2002/07/10 04:34:18 steve
209 * Library dir case insensitivity includes the suffix.
211 * Revision 1.8 2002/06/06 18:57:18 steve
212 * Use standard name for iostream.
214 * Revision 1.7 2002/05/28 20:40:37 steve
215 * ivl indexes the search path for libraries, and
216 * supports case insensitive module-to-file lookup.
218 * Revision 1.6 2002/05/28 00:50:39 steve
219 * Add the ivl -C flag for bulk configuration
220 * from the driver, and use that to run library
221 * modules through the preprocessor.
223 * Revision 1.5 2002/04/04 05:26:13 steve
224 * Add dependency generation.
226 * Revision 1.4 2001/11/20 23:36:34 steve
227 * Close library files after parsing.
229 * Revision 1.3 2001/11/16 05:07:19 steve
230 * Add support for +libext+ in command files.
232 * Revision 1.2 2001/10/22 02:05:21 steve
233 * Handle activating tasks in another root.
235 * Revision 1.1 2001/10/20 23:02:40 steve
236 * Add automatic module libraries.