aboutsummaryrefslogtreecommitdiff
path: root/test_reload.icl
blob: 6b71c8fe53aa1899f401ba88045020f31828f237 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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.
 * You can also use `touch test_reload`.
 */

my_name  :== "test_reload"
my_dir   :== "."
changeme :== 42
verbose  :== False

:: Void = Void

Start w
# (io,w)             = stdio w
# io = io          <<< changeme <<< " (edit changeme and recompile)\n"
# (ok,w)             = fclose io w
# (Just inot)        = inotify_init Void
# (Right watch,inot) = inotify_add_watch reload IN_ATTRIB 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
		| inotify_is_event IN_ATTRIB ev && 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