Mercurial > cpython-lru_cache-weakref
annotate Python/import.c @ 116:0a02ca9dcd6e legacy-trunk
Initial revision
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Mon, 21 Jan 1991 14:27:52 +0000 |
| parents | a6934380c6e7 |
| children | bf5a8539d8ba |
| rev | line source |
|---|---|
| 6 | 1 /* Module definition and import implementation */ |
| 2 | |
| 86 | 3 #include "allobjects.h" |
| 6 | 4 |
| 5 #include "node.h" | |
| 6 #include "token.h" | |
| 7 #include "graminit.h" | |
| 8 #include "import.h" | |
| 9 #include "errcode.h" | |
| 10 #include "sysmodule.h" | |
| 86 | 11 #include "pythonrun.h" |
| 6 | 12 |
| 86 | 13 /* Define pathname separator used in file names */ |
| 6 | 14 |
| 15 #ifdef THINK_C | |
| 16 #define SEP ':' | |
| 17 #endif | |
| 18 | |
| 19 #ifndef SEP | |
| 20 #define SEP '/' | |
| 21 #endif | |
| 22 | |
| 86 | 23 static object *modules; |
| 24 | |
| 25 /* Initialization */ | |
| 6 | 26 |
| 27 void | |
| 28 initimport() | |
| 29 { | |
| 86 | 30 if ((modules = newdictobject()) == NULL) |
| 31 fatal("no mem for dictionary of modules"); | |
| 6 | 32 } |
| 33 | |
| 34 object * | |
| 86 | 35 get_modules() |
| 6 | 36 { |
| 86 | 37 return modules; |
| 6 | 38 } |
| 39 | |
| 86 | 40 object * |
| 41 add_module(name) | |
|
40
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
42 char *name; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
43 { |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
44 object *m; |
| 86 | 45 if ((m = dictlookup(modules, name)) != NULL && is_moduleobject(m)) |
| 46 return m; | |
| 47 m = newmoduleobject(name); | |
| 48 if (m == NULL) | |
| 6 | 49 return NULL; |
| 86 | 50 if (dictinsert(modules, name, m) != 0) { |
| 51 DECREF(m); | |
| 52 return NULL; | |
| 6 | 53 } |
| 86 | 54 DECREF(m); /* Yes, it still exists, in modules! */ |
| 55 return m; | |
| 6 | 56 } |
| 57 | |
| 58 static FILE * | |
| 86 | 59 open_module(name, suffix, namebuf) |
| 6 | 60 char *name; |
| 61 char *suffix; | |
| 86 | 62 char *namebuf; /* XXX No buffer overflow checks! */ |
| 6 | 63 { |
| 64 object *path; | |
| 65 FILE *fp; | |
| 66 | |
| 67 path = sysget("path"); | |
| 68 if (path == NULL || !is_listobject(path)) { | |
| 69 strcpy(namebuf, name); | |
| 70 strcat(namebuf, suffix); | |
| 71 fp = fopen(namebuf, "r"); | |
| 72 } | |
| 73 else { | |
| 74 int npath = getlistsize(path); | |
| 75 int i; | |
| 76 fp = NULL; | |
| 77 for (i = 0; i < npath; i++) { | |
| 78 object *v = getlistitem(path, i); | |
| 79 int len; | |
| 80 if (!is_stringobject(v)) | |
| 81 continue; | |
| 82 strcpy(namebuf, getstringvalue(v)); | |
| 83 len = getstringsize(v); | |
| 84 if (len > 0 && namebuf[len-1] != SEP) | |
| 85 namebuf[len++] = SEP; | |
| 86 | 86 strcpy(namebuf+len, name); |
| 87 strcat(namebuf, suffix); | |
| 6 | 88 fp = fopen(namebuf, "r"); |
| 89 if (fp != NULL) | |
| 90 break; | |
| 91 } | |
| 92 } | |
| 93 return fp; | |
| 94 } | |
| 95 | |
| 96 static object * | |
| 86 | 97 get_module(m, name, m_ret) |
| 98 /*module*/object *m; | |
| 6 | 99 char *name; |
| 86 | 100 object **m_ret; |
| 6 | 101 { |
| 86 | 102 object *d; |
| 6 | 103 FILE *fp; |
|
40
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
104 node *n; |
| 6 | 105 int err; |
| 86 | 106 char namebuf[256]; |
| 6 | 107 |
| 86 | 108 fp = open_module(name, ".py", namebuf); |
| 109 if (fp == NULL) { | |
| 110 if (m == NULL) | |
| 111 err_setstr(NameError, name); | |
| 112 else | |
| 113 err_setstr(RuntimeError, "no module source file"); | |
| 6 | 114 return NULL; |
| 115 } | |
| 86 | 116 err = parse_file(fp, namebuf, file_input, &n); |
| 6 | 117 fclose(fp); |
| 118 if (err != E_DONE) { | |
| 86 | 119 err_input(err); |
| 6 | 120 return NULL; |
| 121 } | |
| 86 | 122 if (m == NULL) { |
| 123 m = add_module(name); | |
| 124 if (m == NULL) { | |
| 125 freetree(n); | |
| 126 return NULL; | |
| 127 } | |
| 128 *m_ret = m; | |
| 129 } | |
| 130 d = getmoduledict(m); | |
| 131 return run_node(n, namebuf, d, d); | |
| 132 } | |
| 133 | |
| 134 static object * | |
| 135 load_module(name) | |
| 136 char *name; | |
| 137 { | |
| 138 object *m, *v; | |
| 139 v = get_module((object *)NULL, name, &m); | |
| 140 if (v == NULL) | |
| 6 | 141 return NULL; |
| 86 | 142 DECREF(v); |
| 6 | 143 return m; |
| 144 } | |
| 145 | |
| 146 object * | |
| 86 | 147 import_module(name) |
| 6 | 148 char *name; |
| 149 { | |
| 150 object *m; | |
| 86 | 151 if ((m = dictlookup(modules, name)) == NULL) |
| 152 m = load_module(name); | |
| 6 | 153 return m; |
| 154 } | |
|
40
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
155 |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
156 object * |
| 86 | 157 reload_module(m) |
|
40
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
158 object *m; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
159 { |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
160 if (m == NULL || !is_moduleobject(m)) { |
| 86 | 161 err_setstr(TypeError, "reload() argument must be module"); |
|
40
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
162 return NULL; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
163 } |
| 86 | 164 /* XXX Ought to check for builtin modules -- can't reload these... */ |
| 165 return get_module(m, getmodulename(m), (object **)NULL); | |
| 166 } | |
| 167 | |
| 168 static void | |
| 169 cleardict(d) | |
| 170 object *d; | |
| 171 { | |
| 172 int i; | |
| 173 for (i = getdictsize(d); --i >= 0; ) { | |
| 174 char *k; | |
| 175 k = getdictkey(d, i); | |
| 176 if (k != NULL) | |
| 177 (void) dictremove(d, k); | |
|
40
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
178 } |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
179 } |
| 86 | 180 |
| 181 void | |
| 182 doneimport() | |
| 183 { | |
| 184 if (modules != NULL) { | |
| 185 int i; | |
| 186 /* Explicitly erase all modules; this is the safest way | |
| 187 to get rid of at least *some* circular dependencies */ | |
| 188 for (i = getdictsize(modules); --i >= 0; ) { | |
| 189 char *k; | |
| 190 k = getdictkey(modules, i); | |
| 191 if (k != NULL) { | |
| 192 object *m; | |
| 193 m = dictlookup(modules, k); | |
| 194 if (m != NULL && is_moduleobject(m)) { | |
| 195 object *d; | |
| 196 d = getmoduledict(m); | |
| 197 if (d != NULL && is_dictobject(d)) { | |
| 198 cleardict(d); | |
| 199 } | |
| 200 } | |
| 201 } | |
| 202 } | |
| 203 cleardict(modules); | |
| 204 } | |
| 205 DECREF(modules); | |
| 206 } |
