commit f604ac1430b756e6489e03d04d967aff7e110017
parent 07844d71887f047c789d68e131e4c8bff8561f64
Author: Andres Navarro <canavarro82@gmail.com>
Date: Mon, 5 Dec 2011 21:36:50 -0300
Added file tracking to require to avoid reloading the same file twice (at least with the same name)
Diffstat:
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/src/Makefile b/src/Makefile
@@ -214,7 +214,7 @@ kgpairs_lists.o: kgpairs_lists.c kstate.h klimits.h klisp.h kobject.h \
kgports.o: kgports.c kstate.h klimits.h klisp.h kobject.h klispconf.h \
ktoken.h kmem.h kport.h kstring.h kbytevector.h kenvironment.h \
kapplicative.h koperative.h kcontinuation.h kpair.h kgc.h kerror.h \
- ksymbol.h kread.h kwrite.h kghelpers.h ktable.h kgports.h
+ ksymbol.h kread.h kwrite.h kghelpers.h ktable.h kgports.h ktable.h
kgpromises.o: kgpromises.c kstate.h klimits.h klisp.h kobject.h \
klispconf.h ktoken.h kmem.h kpromise.h kpair.h kgc.h kapplicative.h \
koperative.h kcontinuation.h kerror.h kghelpers.h kenvironment.h \
diff --git a/src/kgports.c b/src/kgports.c
@@ -14,6 +14,7 @@
#include "kobject.h"
#include "kport.h"
#include "kstring.h"
+#include "ktable.h"
#include "kbytevector.h"
#include "kenvironment.h"
#include "kapplicative.h"
@@ -876,6 +877,21 @@ void require(klisp_State *K)
klispE_throw_simple(K, "Empty name");
return;
}
+ /* search for the named file in the table of already
+ required files.
+ N.B. this will be fooled if the same file is accessed
+ through different names */
+ TValue saved_name = kstring_immutablep(name)? name :
+ kstring_new_bs_imm(K, kstring_buf(name), kstring_size(name));
+
+ const TValue *node = klispH_getstr(tv2table(K->require_table),
+ tv2str(saved_name));
+ if (node != &kfree) {
+ /* was required already, nothing to be done */
+ kapply_cc(K, KINERT);
+ }
+
+ krooted_tvs_push(K, saved_name);
TValue filename = K->empty_string;
krooted_vars_push(K, &filename);
filename = find_file(K, name, K->require_path);
@@ -885,6 +901,16 @@ void require(klisp_State *K)
return;
}
+ /* the file was found, save it in the table */
+ /* MAYBE the name should be saved in the table only if no error
+ occured... but that could lead to loops if the file is
+ required recursively. A third option would be to record the
+ sate of the require in the table, so we could have: error, required,
+ requiring, etc */
+ *(klispH_setstr(K, tv2table(K->require_table), tv2str(saved_name))) =
+ KTRUE;
+ krooted_tvs_pop(K); /* saved_name no longer necessary */
+
/* the reads must be guarded to close the file if there is some error
this continuation also will return inert after the evaluation of the
last expression is done */