aboutsummaryrefslogtreecommitdiff
path: root/test_reload.icl
diff options
context:
space:
mode:
Diffstat (limited to 'test_reload.icl')
-rw-r--r--test_reload.icl69
1 files changed, 69 insertions, 0 deletions
diff --git a/test_reload.icl b/test_reload.icl
new file mode 100644
index 0000000..052c4c9
--- /dev/null
+++ b/test_reload.icl
@@ -0,0 +1,69 @@
+module test_reload
+
+import StdBool
+import StdClass
+import StdFile
+import StdFunc
+import StdInt
+import StdString
+import Data.Either
+import Data.Maybe
+import Inotify
+
+/** test_reload
+ *
+ * This module will watch the directory it is in. Whenever the attributes of
+ * its own binaries change, it will exit. Hence, putting it in a loop:
+ *
+ * while :; do ./test_reload; done
+ *
+ * will give a program that automatically reloads itself when its binary has
+ * changed.
+ *
+ * Test it by running `make run_test_reload`, then editing `changeme` below and
+ * running `make test_reload` to recompile.
+ */
+
+my_name :== "test_reload"
+my_dir :== "."
+changeme :== 42
+verbose :== False
+
+:: Void = Void
+
+Start w
+# (io,w) = stdio w
+# io = io <<< changeme <<< "\n"
+# (ok,w) = fclose io w
+# (Just inot) = inotify_init Void
+# (Right watch,inot) = inotify_add_watch reload IN_ALL_EVENTS my_dir inot
+# (inot,w) = inotify_loop_forever inot w
+= inotify_close inot
+where
+ reload :: !INEvent (Maybe String) Void !*World -> *(Void, *World)
+ reload ev mbName _ w
+ # w = echo (\f -> f <<< "event: " <<< ev <<< "; " <<< mbName) w
+ | isNothing mbName = (Void, w)
+ # (Just name) = mbName
+ | ev bitand IN_ATTRIB <> 0 && name == my_name
+ # w = echo (\f -> f <<< "reloading...") w
+ # w = exit 127 w
+ = (Void, w)
+ = (Void, w)
+
+ echo :: (*File -> *File) *World -> *World
+ echo f w
+ # (io,w) = stdio w
+ # io = if verbose (flip (<<<) "\n" o f) id io
+ # (ok,w) = fclose io w
+ = w
+
+ exit :: !Int !*World -> *World
+ exit c w = code {
+ ccall exit "I:V:A"
+ }
+
+instance <<< (Maybe x) | <<< x
+where
+ (<<<) f Nothing = f
+ (<<<) f (Just x) = f <<< x