blob: 2744df01bd926219d8da52c8f89290504e29f3c0 [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
43#ifndef SEP
44#define SEP '/'
45#endif
46
Guido van Rossum3f5da241990-12-20 15:06:42 +000047static object *modules;
48
49/* Initialization */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000050
51void
52initimport()
53{
Guido van Rossum3f5da241990-12-20 15:06:42 +000054 if ((modules = newdictobject()) == NULL)
55 fatal("no mem for dictionary of modules");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000056}
57
58object *
Guido van Rossum3f5da241990-12-20 15:06:42 +000059get_modules()
60{
61 return modules;
62}
63
64object *
65add_module(name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066 char *name;
67{
68 object *m;
Guido van Rossum3f5da241990-12-20 15:06:42 +000069 if ((m = dictlookup(modules, name)) != NULL && is_moduleobject(m))
70 return m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000071 m = newmoduleobject(name);
72 if (m == NULL)
73 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000074 if (dictinsert(modules, name, m) != 0) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075 DECREF(m);
76 return NULL;
77 }
Guido van Rossum3f5da241990-12-20 15:06:42 +000078 DECREF(m); /* Yes, it still exists, in modules! */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079 return m;
80}
81
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082static FILE *
Guido van Rossum3f5da241990-12-20 15:06:42 +000083open_module(name, suffix, namebuf)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000084 char *name;
85 char *suffix;
Guido van Rossum3f5da241990-12-20 15:06:42 +000086 char *namebuf; /* XXX No buffer overflow checks! */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087{
88 object *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000089 FILE *fp;
90
91 path = sysget("path");
92 if (path == NULL || !is_listobject(path)) {
93 strcpy(namebuf, name);
94 strcat(namebuf, suffix);
95 fp = fopen(namebuf, "r");
96 }
97 else {
98 int npath = getlistsize(path);
99 int i;
100 fp = NULL;
101 for (i = 0; i < npath; i++) {
102 object *v = getlistitem(path, i);
103 int len;
104 if (!is_stringobject(v))
105 continue;
106 strcpy(namebuf, getstringvalue(v));
107 len = getstringsize(v);
108 if (len > 0 && namebuf[len-1] != SEP)
109 namebuf[len++] = SEP;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000110 strcpy(namebuf+len, name);
111 strcat(namebuf, suffix);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000112 fp = fopen(namebuf, "r");
113 if (fp != NULL)
114 break;
115 }
116 }
117 return fp;
118}
119
120static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000121get_module(m, name, m_ret)
122 /*module*/object *m;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000123 char *name;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000124 object **m_ret;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125{
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000126 object *d;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000127 FILE *fp;
128 node *n;
129 int err;
130 char namebuf[256];
131
132 fp = open_module(name, ".py", namebuf);
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000133 if (fp == NULL) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000134 if (m == NULL)
135 err_setstr(NameError, name);
136 else
137 err_setstr(RuntimeError, "no module source file");
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000138 return NULL;
139 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000140 err = parse_file(fp, namebuf, file_input, &n);
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000141 fclose(fp);
142 if (err != E_DONE) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000143 err_input(err);
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000144 return NULL;
145 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000146 if (m == NULL) {
147 m = add_module(name);
148 if (m == NULL) {
149 freetree(n);
150 return NULL;
151 }
152 *m_ret = m;
153 }
154 d = getmoduledict(m);
155 return run_node(n, namebuf, d, d);
156}
157
158static object *
159load_module(name)
160 char *name;
161{
162 object *m, *v;
163 v = get_module((object *)NULL, name, &m);
164 if (v == NULL)
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000165 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000166 DECREF(v);
167 return m;
168}
169
170object *
171import_module(name)
172 char *name;
173{
174 object *m;
Guido van Rossum7f133ed1991-02-19 12:23:57 +0000175 if ((m = dictlookup(modules, name)) == NULL) {
176 if (init_builtin(name)) {
177 if ((m = dictlookup(modules, name)) == NULL)
178 err_setstr(SystemError, "builtin module missing");
179 }
180 else {
181 m = load_module(name);
182 }
183 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000184 return m;
185}
186
187object *
188reload_module(m)
189 object *m;
190{
191 if (m == NULL || !is_moduleobject(m)) {
192 err_setstr(TypeError, "reload() argument must be module");
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000193 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000194 }
195 /* XXX Ought to check for builtin modules -- can't reload these... */
196 return get_module(m, getmodulename(m), (object **)NULL);
197}
198
199static void
200cleardict(d)
201 object *d;
202{
203 int i;
204 for (i = getdictsize(d); --i >= 0; ) {
205 char *k;
206 k = getdictkey(d, i);
207 if (k != NULL)
208 (void) dictremove(d, k);
209 }
210}
211
212void
213doneimport()
214{
215 if (modules != NULL) {
216 int i;
217 /* Explicitly erase all modules; this is the safest way
218 to get rid of at least *some* circular dependencies */
219 for (i = getdictsize(modules); --i >= 0; ) {
220 char *k;
221 k = getdictkey(modules, i);
222 if (k != NULL) {
223 object *m;
224 m = dictlookup(modules, k);
225 if (m != NULL && is_moduleobject(m)) {
226 object *d;
227 d = getmoduledict(m);
228 if (d != NULL && is_dictobject(d)) {
229 cleardict(d);
230 }
231 }
232 }
233 }
234 cleardict(modules);
235 }
236 DECREF(modules);
Guido van Rossum8d15b5d1990-10-26 14:58:58 +0000237}
Guido van Rossum7f133ed1991-02-19 12:23:57 +0000238
239
240/* Initialize built-in modules when first imported */
241
242extern struct {
243 char *name;
244 void (*initfunc)();
245} inittab[];
246
247static int
248init_builtin(name)
249 char *name;
250{
251 int i;
252 for (i = 0; inittab[i].name != NULL; i++) {
253 if (strcmp(name, inittab[i].name) == 0) {
254 (*inittab[i].initfunc)();
255 return 1;
256 }
257 }
258 return 0;
259}