blob: 67cd31e6ddc1642bb549c2eb18452becbe1f3f69 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* Module definition and import implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000029#include "node.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000030#include "token.h"
31#include "graminit.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032#include "import.h"
33#include "errcode.h"
34#include "sysmodule.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000035#include "pythonrun.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036
Guido van Rossum3f5da241990-12-20 15:06:42 +000037/* Define pathname separator used in file names */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000038
39#ifdef THINK_C
40#define SEP ':'
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041#endif
42
Guido van Rossum175a9ea1991-05-05 20:07:59 +000043#ifdef MSDOS
44#define SEP '\\'
45#endif
46
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000047#ifndef SEP
48#define SEP '/'
49#endif
50
Guido van Rossum3f5da241990-12-20 15:06:42 +000051static object *modules;
52
Guido van Rossum66f1fa81991-04-03 19:03:52 +000053/* Forward */
54static int init_builtin PROTO((char *));
55
Guido van Rossum3f5da241990-12-20 15:06:42 +000056/* Initialization */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057
58void
59initimport()
60{
Guido van Rossum3f5da241990-12-20 15:06:42 +000061 if ((modules = newdictobject()) == NULL)
62 fatal("no mem for dictionary of modules");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000063}
64
65object *
Guido van Rossum3f5da241990-12-20 15:06:42 +000066get_modules()
67{
68 return modules;
69}
70
71object *
72add_module(name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073 char *name;
74{
75 object *m;
Guido van Rossum3f5da241990-12-20 15:06:42 +000076 if ((m = dictlookup(modules, name)) != NULL && is_moduleobject(m))
77 return m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000078 m = newmoduleobject(name);
79 if (m == NULL)
80 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000081 if (dictinsert(modules, name, m) != 0) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082 DECREF(m);
83 return NULL;
84 }
Guido van Rossum3f5da241990-12-20 15:06:42 +000085 DECREF(m); /* Yes, it still exists, in modules! */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000086 return m;
87}
88
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000089static FILE *
Guido van Rossum3f5da241990-12-20 15:06:42 +000090open_module(name, suffix, namebuf)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091 char *name;
92 char *suffix;
Guido van Rossum3f5da241990-12-20 15:06:42 +000093 char *namebuf; /* XXX No buffer overflow checks! */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000094{
95 object *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000096 FILE *fp;
97
98 path = sysget("path");
99 if (path == NULL || !is_listobject(path)) {
100 strcpy(namebuf, name);
101 strcat(namebuf, suffix);
102 fp = fopen(namebuf, "r");
103 }
104 else {
105 int npath = getlistsize(path);
106 int i;
107 fp = NULL;
108 for (i = 0; i < npath; i++) {
109 object *v = getlistitem(path, i);
110 int len;
111 if (!is_stringobject(v))
112 continue;
113 strcpy(namebuf, getstringvalue(v));
114 len = getstringsize(v);
115 if (len > 0 && namebuf[len-1] != SEP)
116 namebuf[len++] = SEP;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000117 strcpy(namebuf+len, name);
118 strcat(namebuf, suffix);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000119 fp = fopen(namebuf, "r");
120 if (fp != NULL)
121 break;
122 }
123 }
124 return fp;
125}
126
127static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000128get_module(m, name, m_ret)
129 /*module*/object *m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130 char *name;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000131 object **m_ret;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000132{
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000133 object *d;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000134 FILE *fp;
135 node *n;
136 int err;
137 char namebuf[256];
138
139 fp = open_module(name, ".py", namebuf);
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000140 if (fp == NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000141 if (m == NULL)
142 err_setstr(NameError, name);
143 else
144 err_setstr(RuntimeError, "no module source file");
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000145 return NULL;
146 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000147 err = parse_file(fp, namebuf, file_input, &n);
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000148 fclose(fp);
149 if (err != E_DONE) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000150 err_input(err);
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000151 return NULL;
152 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000153 if (m == NULL) {
154 m = add_module(name);
155 if (m == NULL) {
156 freetree(n);
157 return NULL;
158 }
159 *m_ret = m;
160 }
161 d = getmoduledict(m);
162 return run_node(n, namebuf, d, d);
163}
164
165static object *
166load_module(name)
167 char *name;
168{
169 object *m, *v;
170 v = get_module((object *)NULL, name, &m);
171 if (v == NULL)
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000172 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000173 DECREF(v);
174 return m;
175}
176
177object *
178import_module(name)
179 char *name;
180{
181 object *m;
Guido van Rossum7f133ed1991-02-19 12:23:57 +0000182 if ((m = dictlookup(modules, name)) == NULL) {
183 if (init_builtin(name)) {
184 if ((m = dictlookup(modules, name)) == NULL)
185 err_setstr(SystemError, "builtin module missing");
186 }
187 else {
188 m = load_module(name);
189 }
190 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000191 return m;
192}
193
194object *
195reload_module(m)
196 object *m;
197{
198 if (m == NULL || !is_moduleobject(m)) {
199 err_setstr(TypeError, "reload() argument must be module");
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000200 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000201 }
202 /* XXX Ought to check for builtin modules -- can't reload these... */
203 return get_module(m, getmodulename(m), (object **)NULL);
204}
205
206static void
207cleardict(d)
208 object *d;
209{
210 int i;
211 for (i = getdictsize(d); --i >= 0; ) {
212 char *k;
213 k = getdictkey(d, i);
214 if (k != NULL)
215 (void) dictremove(d, k);
216 }
217}
218
219void
220doneimport()
221{
222 if (modules != NULL) {
223 int i;
224 /* Explicitly erase all modules; this is the safest way
225 to get rid of at least *some* circular dependencies */
226 for (i = getdictsize(modules); --i >= 0; ) {
227 char *k;
228 k = getdictkey(modules, i);
229 if (k != NULL) {
230 object *m;
231 m = dictlookup(modules, k);
232 if (m != NULL && is_moduleobject(m)) {
233 object *d;
234 d = getmoduledict(m);
235 if (d != NULL && is_dictobject(d)) {
236 cleardict(d);
237 }
238 }
239 }
240 }
241 cleardict(modules);
242 }
243 DECREF(modules);
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000244}
Guido van Rossum7f133ed1991-02-19 12:23:57 +0000245
246
247/* Initialize built-in modules when first imported */
248
249extern struct {
250 char *name;
251 void (*initfunc)();
252} inittab[];
253
254static int
255init_builtin(name)
256 char *name;
257{
258 int i;
259 for (i = 0; inittab[i].name != NULL; i++) {
260 if (strcmp(name, inittab[i].name) == 0) {
261 (*inittab[i].initfunc)();
262 return 1;
263 }
264 }
265 return 0;
266}