summaryrefslogtreecommitdiff
path: root/ipl/packs/loadfuncpp/loadfuncpp.icn
diff options
context:
space:
mode:
Diffstat (limited to 'ipl/packs/loadfuncpp/loadfuncpp.icn')
-rw-r--r--ipl/packs/loadfuncpp/loadfuncpp.icn241
1 files changed, 241 insertions, 0 deletions
diff --git a/ipl/packs/loadfuncpp/loadfuncpp.icn b/ipl/packs/loadfuncpp/loadfuncpp.icn
new file mode 100644
index 0000000..318ee99
--- /dev/null
+++ b/ipl/packs/loadfuncpp/loadfuncpp.icn
@@ -0,0 +1,241 @@
+
+procedure loadfuncpp(fname, entry, arity)
+#the first call loads the glue library, and loads and assigns the external loadfuncpp
+ local iload, fpath, oldloadfunc, real_loadfunc
+ real_loadfunc := _loadfuncpp_proc("loadfunc")
+ iload := _loadfuncpp_iload()
+ oldloadfunc := loadfunc #catch22: loadfunc cannot correctly return loadfuncpp
+ real_loadfunc(iload, "loadfuncpp") #implicitly assigns loadfuncpp to loadfunc on load
+ loadfuncpp := loadfunc #replace this loadfuncpp with the one loaded
+ loadfunc := oldloadfunc #put the old loadfunc back
+ self(iload) #initialize self from iload.so; calls loadfuncpp
+ bindself(iload) #initialize bindself from iload.so; calls loadfuncpp
+ loadfuncpp(_loadfuncpp_iloadgpx(), "iconx_graphics", 0) #calling Icon
+ return loadfuncpp(fname, entry, arity) #call the new loadfuncpp just loaded
+end
+
+procedure self()
+ static getbinding
+ initial {
+ getbinding := loadfuncpp(_loadfuncpp_iload(), "getbinding", 0) |
+ stop("loadfuncpp: support function 'getbinding' not found in iload.so")
+ fail
+ }
+ return getbinding() #must be called from self()
+end
+
+procedure bindself(proc, rec)
+ bindself := loadfuncpp(_loadfuncpp_iload(), "bindself", 2) |
+ stop("loadfuncpp: support functon 'bindself' not found in iload.so")
+ return bindself(proc, rec)
+end
+
+invocable "_loadfuncpp_pathfind", "_loadfuncpp_reduce", "_loadfuncpp_create",
+ "_loadfuncpp_activate", "_loadfuncpp_kcollections", "_loadfuncpp_kfeatures",
+ "_loadfuncpp_kregions", "_loadfuncpp_kstorage", "_loadfuncpp_function",
+ "_loadfuncpp_bang", "_loadfuncpp_apply", "_loadfuncpp_any", "_loadfuncpp_many",
+ "_loadfuncpp_upto", "_loadfuncpp_find", "_loadfuncpp_match", "_loadfuncpp_bal",
+ "_loadfuncpp_move", "_loadfuncpp_tab", "_loadfuncpp_proc", "_loadfuncpp_key",
+ "_loadfuncpp_iload", "_loadfuncpp_iloadgpx"
+
+procedure _loadfuncpp_iload()
+ local getenv, fpath
+ static iload
+ initial {
+ getenv := _loadfuncpp_proc("getenv")
+ iload := _loadfuncpp_pathfind("iload.so", fpath:= getenv("FPATH")) |
+ stop("Cannot find iload.so on FPATH where \nFPATH=", fpath)
+ }
+ return iload
+end
+
+procedure _loadfuncpp_iloadgpx()
+ local getenv, fpath, libname
+ static iloadgpx
+ initial {
+ if \Event then libname := "iloadgpx.so" else libname := "iloadnogpx.so"
+ getenv := _loadfuncpp_proc("getenv")
+ iloadgpx := _loadfuncpp_pathfind(libname, fpath:= getenv("FPATH")) |
+ stop("Cannot find ", libname, " on FPATH where \nFPATH=", fpath)
+ }
+ return iloadgpx
+end
+
+procedure _loadfuncpp_pathfind(fname, path, psep)
+ local f, dir, fullname
+ static close, open, tab, upto, trim, many, pos
+ initial {
+ close := _loadfuncpp_proc("close")
+ open := _loadfuncpp_proc("open")
+ tab := _loadfuncpp_proc("tab")
+ upto := _loadfuncpp_proc("upto")
+ trim := _loadfuncpp_proc("trim")
+ many := _loadfuncpp_proc("many")
+ pos := _loadfuncpp_proc("pos")
+ }
+ /psep := ' :' #good for cygwin, unix variants (including OS X)
+ fname ? {
+ if ="/" & close(open(fname)) then
+ return fname #full absolute path works
+ while tab(upto('/') + 1)
+ fname := tab(0) #get final component of path
+ }
+ /path := ""
+ path := ". " || path
+ path ? while not pos(0) do {
+ dir := tab(upto(psep) | 0)
+ fullname := trim(dir, '/') || "/" || fname
+ if close(open(fullname)) then
+ return fullname
+ tab(many(psep))
+ }
+ return #must return
+end
+
+procedure _loadfuncpp_reduce(nullary, binary, g, arg)
+ local result
+ result := nullary
+ every binary(result, g!arg)
+ return result
+end
+
+procedure _loadfuncpp_create(g, arg)
+ return create g!arg
+end
+
+procedure _loadfuncpp_activate(coexp, val)
+ return val@coexp | &null
+end
+
+procedure _loadfuncpp_kcollections()
+ local ls
+ ls := []
+ every put(ls, &collections)
+ return ls
+end
+
+procedure _loadfuncpp_kfeatures()
+ local ls
+ ls := []
+ every put(ls, &features)
+ return ls
+end
+
+procedure _loadfuncpp_kregions()
+ local ls
+ ls := []
+ every put(ls, &regions)
+ return ls
+end
+
+procedure _loadfuncpp_kstorage()
+ local ls
+ ls := []
+ every put(ls, &storage)
+ return ls
+end
+
+procedure _loadfuncpp_function()
+ local ls
+ static function
+ initial function := _loadfuncpp_proc("function")
+ ls := []
+ every put(ls, function())
+ return ls
+end
+
+procedure _loadfuncpp_key(t)
+ local ls
+ static key
+ initial key := _loadfuncpp_proc("key")
+ ls := []
+ every put(ls, key(t))
+ return ls
+end
+
+procedure _loadfuncpp_bang(nullary, binary, x)
+ local result
+ result := nullary
+ if type(x)=="table"
+ then every binary(result, key(x))
+ else every binary(result, !x)
+ return result
+end
+
+procedure _loadfuncpp_any(c,s,i1,i2)
+ static any
+ initial any := _loadfuncpp_proc("any")
+ return any(c,s,i1,i2) | &null
+end
+
+procedure _loadfuncpp_many(c,s,i1,i2)
+ static many
+ initial many := _loadfuncpp_proc("many")
+ return many(c,s,i1,i2) | &null
+end
+
+procedure _loadfuncpp_upto(c,s,i1,i2)
+ static upto
+ initial upto := _loadfuncpp_proc("upto")
+ return upto(c,s,i1,i2) | &null
+end
+
+procedure _loadfuncpp_find(s1,s2,i1,i2)
+ static find
+ initial find := _loadfuncpp_proc("find")
+ return find(s1,s2,i1,i2) | &null
+end
+
+procedure _loadfuncpp_match(s1,s2,i1,i2)
+ static match
+ initial match := _loadfuncpp_proc("match")
+ return match(s1,s2,i1,i2) | &null
+end
+
+procedure _loadfuncpp_bal(c1,c2,c3,s,i1,i2)
+ static bal
+ initial bal := _loadfuncpp_proc("bal")
+ return bal(c1,c2,c3,s,i1,i2) | &null
+end
+
+procedure _loadfuncpp_move(i)
+ static move
+ initial move := _loadfuncpp_proc("move")
+ return move(i) | &null
+end
+
+procedure _loadfuncpp_tab(i)
+ static tab
+ initial tab := _loadfuncpp_proc("tab")
+ return tab(i) | &null
+end
+
+procedure _loadfuncpp_apply(f, arg)
+ return f!arg | &null
+end
+
+#use to find built-in functions so they can be nobbled
+#prior to the first call of loadfuncpp without affecting us
+#this is a defensive measure to protect a reasonable programmer
+#NOT an attempt to be secure against all ways to subvert loadfuncpp
+procedure _loadfuncpp_proc(function)
+ static Proc
+ local errmsg
+ initial {
+ #called when procedure loadfuncpp is first called to load the real loadfuncpp
+ errmsg := "loadfuncpp: built-in function 'proc' not found"
+ Proc := proc("proc",0) | stop(errmsg)
+ image(Proc)=="function proc" | stop(errmsg)
+ args(Proc)=2 | stop(errmsg)
+ Proc("proc",0)===Proc | stop(errmsg) #good enough, not perfect
+ }
+ return Proc(function,0) | &null
+end
+
+
+
+
+
+
+
+