mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-14 17:41:33 +03:00
Merge branch 'do' of https://github.com/urbit/urbit into do
Conflicts: urb/zod/base/ape/bit/core.hook
This commit is contained in:
commit
a4a2f0c789
26
Makefile
26
Makefile
@ -354,7 +354,7 @@ LIBCOMMONMARK=outside/commonmark/build/src/libcmark.a
|
|||||||
|
|
||||||
LIBSCRYPT=outside/scrypt/scrypt.a
|
LIBSCRYPT=outside/scrypt/scrypt.a
|
||||||
|
|
||||||
all: vere
|
all: urbit
|
||||||
|
|
||||||
.MAKEFILE-VERSION: Makefile .make.conf
|
.MAKEFILE-VERSION: Makefile .make.conf
|
||||||
@echo "Makefile update."
|
@echo "Makefile update."
|
||||||
@ -363,7 +363,7 @@ all: vere
|
|||||||
.make.conf:
|
.make.conf:
|
||||||
@echo "# Set custom configuration here, please!" > ".make.conf"
|
@echo "# Set custom configuration here, please!" > ".make.conf"
|
||||||
|
|
||||||
vere: $(BIN)/vere
|
urbit: $(BIN)/urbit
|
||||||
meme: $(BIN)/meme
|
meme: $(BIN)/meme
|
||||||
|
|
||||||
$(LIBUV_MAKEFILE) $(LIBUV_MAKEFILE2):
|
$(LIBUV_MAKEFILE) $(LIBUV_MAKEFILE2):
|
||||||
@ -393,14 +393,14 @@ $(CRE2_OFILES): outside/cre2/src/src/cre2.cpp outside/cre2/src/src/cre2.h $(LIBR
|
|||||||
$(V_OFILES): i/v/vere.h
|
$(V_OFILES): i/v/vere.h
|
||||||
|
|
||||||
ifdef NO_SILENT_RULES
|
ifdef NO_SILENT_RULES
|
||||||
$(BIN)/vere: $(LIBCRE) $(LIBCOMMONMARK) $(VERE_OFILES) $(LIBUV) $(LIBRE2) $(LIBED25519) $(LIBANACHRONISM) $(LIBSCRYPT)
|
$(BIN)/urbit: $(LIBCRE) $(LIBCOMMONMARK) $(VERE_OFILES) $(LIBUV) $(LIBRE2) $(LIBED25519) $(LIBANACHRONISM) $(LIBSCRYPT)
|
||||||
mkdir -p $(BIN)
|
mkdir -p $(BIN)
|
||||||
$(CLD) $(CLDOSFLAGS) -o $(BIN)/vere $(VERE_OFILES) $(LIBUV) $(LIBCRE) $(LIBRE2) $(LIBED25519) $(LIBANACHRONISM) $(LIBS) $(LIBCOMMONMARK) $(LIBSCRYPT)
|
$(CLD) $(CLDOSFLAGS) -o $(BIN)/urbit $(VERE_OFILES) $(LIBUV) $(LIBCRE) $(LIBRE2) $(LIBED25519) $(LIBANACHRONISM) $(LIBS) $(LIBCOMMONMARK) $(LIBSCRYPT)
|
||||||
else
|
else
|
||||||
$(BIN)/vere: $(LIBCRE) $(LIBCOMMONMARK) $(VERE_OFILES) $(LIBUV) $(LIBRE2) $(LIBED25519) $(LIBANACHRONISM) $(LIBSCRYPT)
|
$(BIN)/urbit: $(LIBCRE) $(LIBCOMMONMARK) $(VERE_OFILES) $(LIBUV) $(LIBRE2) $(LIBED25519) $(LIBANACHRONISM) $(LIBSCRYPT)
|
||||||
@echo " CCLD $(BIN)/vere"
|
@echo " CCLD $(BIN)/urbit"
|
||||||
@mkdir -p $(BIN)
|
@mkdir -p $(BIN)
|
||||||
@$(CLD) $(CLDOSFLAGS) -o $(BIN)/vere $(VERE_OFILES) $(LIBUV) $(LIBCRE) $(LIBRE2) $(LIBED25519) $(LIBANACHRONISM) $(LIBS) $(LIBCOMMONMARK) $(LIBSCRYPT)
|
@$(CLD) $(CLDOSFLAGS) -o $(BIN)/urbit $(VERE_OFILES) $(LIBUV) $(LIBCRE) $(LIBRE2) $(LIBED25519) $(LIBANACHRONISM) $(LIBS) $(LIBCOMMONMARK) $(LIBSCRYPT)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(BIN)/meme: $(LIBCRE) $(LIBCOMMONMARK) $(MEME_OFILES) $(LIBUV) $(LIBRE2) $(LIBED25519) $(LIBANACHRONISM) $(LIBSCRYPT)
|
$(BIN)/meme: $(LIBCRE) $(LIBCOMMONMARK) $(MEME_OFILES) $(LIBUV) $(LIBRE2) $(LIBED25519) $(LIBANACHRONISM) $(LIBSCRYPT)
|
||||||
@ -416,24 +416,24 @@ etags:
|
|||||||
osxpackage:
|
osxpackage:
|
||||||
$(RM) -r inst
|
$(RM) -r inst
|
||||||
$(MAKE) distclean
|
$(MAKE) distclean
|
||||||
$(MAKE) $(BIN)/vere LIB=/usr/local/lib/urb STATIC=yes
|
$(MAKE) $(BIN)/urbit LIB=/usr/local/lib/urb STATIC=yes
|
||||||
mkdir -p inst/usr/local/lib/urb inst/usr/local/bin
|
mkdir -p inst/usr/local/lib/urb inst/usr/local/bin
|
||||||
cp $(BIN)/vere inst/usr/local/bin
|
cp $(BIN)/urbit inst/usr/local/bin
|
||||||
cp urb/urbit.pill inst/usr/local/lib/urb
|
cp urb/urbit.pill inst/usr/local/lib/urb
|
||||||
cp -R urb/zod inst/usr/local/lib/urb
|
cp -R urb/zod inst/usr/local/lib/urb
|
||||||
pkgbuild --root inst --identifier org.urbit.vere --version 0.2 vere.pkg
|
pkgbuild --root inst --identifier org.urbit.urbit --version 0.2 urbit.pkg
|
||||||
|
|
||||||
debbuild:
|
debbuild:
|
||||||
$(MAKE) $(BIN)/vere LIB=/usr/share/urb
|
$(MAKE) $(BIN)/urbit LIB=/usr/share/urb
|
||||||
|
|
||||||
debinstall:
|
debinstall:
|
||||||
mkdir -p $(DESTDIR)/usr/bin $(DESTDIR)/usr/share/urb
|
mkdir -p $(DESTDIR)/usr/bin $(DESTDIR)/usr/share/urb
|
||||||
install -m755 $(BIN)/vere $(DESTDIR)/usr/bin
|
install -m755 $(BIN)/urbit $(DESTDIR)/usr/bin
|
||||||
cp urb/urbit.pill $(DESTDIR)/usr/share/urb
|
cp urb/urbit.pill $(DESTDIR)/usr/share/urb
|
||||||
cp -R urb/zod $(DESTDIR)/usr/share/urb
|
cp -R urb/zod $(DESTDIR)/usr/share/urb
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) $(VERE_OFILES) $(BIN)/vere vere.pkg $(VERE_DFILES)
|
$(RM) $(VERE_OFILES) $(BIN)/urbit urbit.pkg $(VERE_DFILES)
|
||||||
|
|
||||||
distclean: clean $(LIBUV_MAKEFILE)
|
distclean: clean $(LIBUV_MAKEFILE)
|
||||||
$(MAKE) -C outside/libuv_0.11 distclean
|
$(MAKE) -C outside/libuv_0.11 distclean
|
||||||
|
135
demo/commands.txt
Normal file
135
demo/commands.txt
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
|
||||||
|
Commands
|
||||||
|
|
||||||
|
[from URL bar]
|
||||||
|
***TBD - Galen/Anton please fill in
|
||||||
|
|
||||||
|
[from unix]
|
||||||
|
For A, to build and boot:
|
||||||
|
git clone https://github.com/urbit/urbit
|
||||||
|
cd urbit
|
||||||
|
make
|
||||||
|
bin/urbit -T $A -c $A
|
||||||
|
|
||||||
|
For A, to kill and restart from checkpoint:
|
||||||
|
[in new terminal] killall -9 urbit
|
||||||
|
[in old terminal] urbit $A
|
||||||
|
|
||||||
|
For A, to kill, delete checkpoint, and rerun events:
|
||||||
|
[in new terminal] killall -9 urbit; rm -rf $A/.urb/chk
|
||||||
|
[in old terminal] urbit $A
|
||||||
|
|
||||||
|
For B, to edit /foo/bar/hoon:
|
||||||
|
*** Philip/anyone, add directions to install vim style
|
||||||
|
|
||||||
|
vim urbit/$B/$B/in/$DEMO/foo/bar.hoon
|
||||||
|
|
||||||
|
|
||||||
|
[from talk]
|
||||||
|
For A, to private-message B (who defaults to talking back):
|
||||||
|
|
||||||
|
;~B
|
||||||
|
|
||||||
|
To create a channel '%foobar':
|
||||||
|
|
||||||
|
;create channel %foobar 'channel description'
|
||||||
|
|
||||||
|
[from hood, #]
|
||||||
|
|
||||||
|
For A or B, to start tictactoe:
|
||||||
|
|
||||||
|
*demo/tictactoe
|
||||||
|
|
||||||
|
For A or B, to log in to X's tictactoe:
|
||||||
|
|
||||||
|
+~X/tictactoe
|
||||||
|
|
||||||
|
To log out:
|
||||||
|
|
||||||
|
-~X/tictactoe
|
||||||
|
|
||||||
|
[from dojo]
|
||||||
|
|
||||||
|
For B, to create a %demo desk for this project:
|
||||||
|
|
||||||
|
:+merge %demo ~B %home
|
||||||
|
|
||||||
|
For A, to sync and follow B's demo desk:
|
||||||
|
|
||||||
|
:+sync %demo ~B %demo
|
||||||
|
|
||||||
|
*** - put bitcoin instructions here
|
||||||
|
|
||||||
|
|
||||||
|
[files in script, clay and unix]
|
||||||
|
|
||||||
|
The tictactoe app, all three versions:
|
||||||
|
|
||||||
|
/=demo=/ape/tictactoe/core/hook
|
||||||
|
urbit/$X/$X/in/$DEMO/ape/tictactoe/core/hook
|
||||||
|
|
||||||
|
version 1 (centralized):
|
||||||
|
$DEMO/files/1-ape-tictactoe.hoon
|
||||||
|
|
||||||
|
version 2 (distributed):
|
||||||
|
$DEMO/files/2-ape-tictactoe.hoon
|
||||||
|
|
||||||
|
version 3 (webified)
|
||||||
|
$DEMO/files/3-ape-tictactoe.hoon
|
||||||
|
|
||||||
|
Helper files needed for version 2:
|
||||||
|
|
||||||
|
The %octo-game mark, for game update diffs:
|
||||||
|
|
||||||
|
/=demo=/mar/octo-game/door/hook
|
||||||
|
urbit/$X/$X/in/$DEMO/mar/octo-game/door.hook
|
||||||
|
$DEMO/files/mar-octo-game.hoon
|
||||||
|
|
||||||
|
Helper files needed for version 3:
|
||||||
|
|
||||||
|
The %octo-move mark, for moves from the web:
|
||||||
|
|
||||||
|
/=demo=/mar/octo-move/door/hook
|
||||||
|
urbit/$X/$X/in/$DEMO/mar/octo-move/door.hook
|
||||||
|
$DEMO/files/mar-octo-move.hoon
|
||||||
|
|
||||||
|
The HTML generator:
|
||||||
|
|
||||||
|
/=demo=/pub/octo/fab/hymn/hook
|
||||||
|
urbit/$X/$X/in/$DEMO/pub/octo/fab/hymn.hook
|
||||||
|
$DEMO/files/pub-octo-hymn.hoon
|
||||||
|
|
||||||
|
The CSS:
|
||||||
|
|
||||||
|
/=demo=/pub/octo/src/main/css
|
||||||
|
urbit/$X/$X/in/$DEMO/pub/octo/src/main.css
|
||||||
|
$DEMO/files/pub-octo-main.css
|
||||||
|
|
||||||
|
The JS:
|
||||||
|
|
||||||
|
/=demo=/pub/octo/src/main/js
|
||||||
|
urbit/$X/$X/in/$DEMO/pub/octo/src/main.js
|
||||||
|
$DEMO/files/pub-octo-main.js
|
||||||
|
|
||||||
|
[from tictactoe]
|
||||||
|
|
||||||
|
To move:
|
||||||
|
|
||||||
|
X/Y where X is row, Y is column.
|
||||||
|
|
||||||
|
To connect to a remote server (in versions 2 and 3),
|
||||||
|
specifying the side you will play:
|
||||||
|
|
||||||
|
~X x
|
||||||
|
~X o
|
||||||
|
|
||||||
|
To disconnect from a remote server (versions 2 and 3)
|
||||||
|
|
||||||
|
~ *** - not well tested
|
||||||
|
|
||||||
|
[scripts, to run from branch root directory]
|
||||||
|
|
||||||
|
$DEMO/install1.sh - copy in all version 1 (centralized) files
|
||||||
|
$DEMO/install2.sh - copy in all version 2 (distributed) files
|
||||||
|
$DEMO/install3.sh - copy in all version 3 (webby) files
|
||||||
|
|
123
demo/files/1-ape-tictactoe.hoon
Normal file
123
demo/files/1-ape-tictactoe.hoon
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
:: :: ::
|
||||||
|
:::: /hook/core/acto/ape :: :: dependencies
|
||||||
|
:: :: ::
|
||||||
|
/- *sole :: structure
|
||||||
|
/+ sole :: library
|
||||||
|
:: :: ::
|
||||||
|
:::: :: :: structures
|
||||||
|
!: :: ::
|
||||||
|
=> |% :: board logic
|
||||||
|
++ board ,@ :: one-player bitfield
|
||||||
|
++ point ,[x=@ y=@] :: coordinate
|
||||||
|
++ game ,[who=? box=board boo=board] :: game state
|
||||||
|
++ icon |=(? ?:(+< 'X' 'O')) :: display at
|
||||||
|
++ bo :: per board
|
||||||
|
|_ bud=board ::
|
||||||
|
++ get |=(point =(1 (cut 0 [(off +<) 1] bud))) :: get point
|
||||||
|
++ off |=(point (add x (mul 3 y))) :: bitfield address
|
||||||
|
++ set |=(point (con bud (bex (off +<)))) :: set point
|
||||||
|
++ win %- lien :_ |=(a=@ =(a (dis a bud))) :: test for win
|
||||||
|
(rip 4 0wl04h0.4A0Aw.4A00s.0e070) ::
|
||||||
|
-- ::
|
||||||
|
:: :: ::
|
||||||
|
:::: :: :: semantics
|
||||||
|
:: :: ::
|
||||||
|
++ go :: per game
|
||||||
|
|_ game ::
|
||||||
|
++ at |_ point :: per point
|
||||||
|
++ g +>+< :: game
|
||||||
|
++ k !|(x o) :: ok move
|
||||||
|
++ m ?.(k [| g] [& g:t:?:(who y p)]) :: move
|
||||||
|
++ o (~(get bo boo) +<) :: old at o
|
||||||
|
++ p .(boo (~(set bo boo) +<)) :: play at o
|
||||||
|
++ t .(who !who) :: take turn
|
||||||
|
++ v ?:(x (icon &) ?:(o (icon |) '.')) :: view
|
||||||
|
++ x (~(get bo box) +<) :: old at x
|
||||||
|
++ y .(box (~(set bo box) +<)) :: play at x
|
||||||
|
-- ::
|
||||||
|
++ res ?: ~(win bo box) `"{~[(icon &)]} wins" :: result
|
||||||
|
?: ~(win bo boo) `"{~[(icon |)]} wins" ::
|
||||||
|
?: =(511 (con boo box)) `"tie :-(" ~ ::
|
||||||
|
++ row |= y=@ :~ (add y '1') :: print row
|
||||||
|
' ' ~(v at y 0) ::
|
||||||
|
' ' ~(v at y 1) ::
|
||||||
|
' ' ~(v at y 2) ::
|
||||||
|
== ::
|
||||||
|
++ tab ~["+ 1 2 3" (row 0) (row 1) (row 2)] :: print table
|
||||||
|
-- ::
|
||||||
|
-- ::
|
||||||
|
:: :: ::
|
||||||
|
:::: :: :: server
|
||||||
|
:: :: ::
|
||||||
|
=> |% :: arvo structures
|
||||||
|
++ axle ,[%0 eye=face gam=game] :: agent state
|
||||||
|
++ card ,[%diff lime] :: update
|
||||||
|
++ face (pair (list ,@c) (map bone sole-share)) :: interface
|
||||||
|
++ lime ,[%sole-effect sole-effect] :: console update
|
||||||
|
++ move (pair bone card) :: cause and action
|
||||||
|
-- ::
|
||||||
|
=> |% :: parsers
|
||||||
|
++ colm (cook |=(a=@ (sub a '1')) (shim '1' '3')) :: row or column
|
||||||
|
++ come ;~(plug colm ;~(pfix fas colm)) :: coordinate
|
||||||
|
-- ::
|
||||||
|
|_ [hid=hide moz=(list move) axle] :: per agent
|
||||||
|
++ et ::
|
||||||
|
|_ [from say=sole-share] :: per console
|
||||||
|
++ abet +>(q.eye (~(put by q.eye) ost say)) :: continue
|
||||||
|
++ amok +>(q.eye (~(del by q.eye) ost)) :: discontinue
|
||||||
|
++ beep (emit %bel ~) :: bad user
|
||||||
|
++ delt |= cal=sole-change :: input line change
|
||||||
|
=^ cul say (remit:sole cal good) ::
|
||||||
|
?~ cul (park:abet(p.eye buf.say) | ~) ::
|
||||||
|
abet:beep:(emit det/u.cul) ::
|
||||||
|
++ emit |= fec=sole-effect ^+ +> :: send effect
|
||||||
|
+>(moz [[ost %diff %sole-effect fec] moz]) ::
|
||||||
|
++ emil |= fex=(list sole-effect) :: send effects
|
||||||
|
?~(fex +> $(fex t.fex, +> (emit i.fex))) ::
|
||||||
|
++ good |=((list ,@c) -:(rose (tufa +<) come)) :: valid input
|
||||||
|
++ kick |= point :: move command
|
||||||
|
=^ dud gam ~(m ~(at go gam) +<) ::
|
||||||
|
?. dud abet:beep =+ mus=~(res go gam) ::
|
||||||
|
(park:abet(gam ?^(mus *game gam)) %2 mus) ::
|
||||||
|
++ line =^ cal say (transmit:sole set/p.eye) :: update command
|
||||||
|
(emit %det cal) ::
|
||||||
|
++ make =+ dur=(rust (tufa p.eye) come) ::
|
||||||
|
?~ dur abet:beep ::
|
||||||
|
(kick:line(p.eye ~) +.dur) ::
|
||||||
|
++ mean |=((unit tape) ?~(+< +> (emit txt/+<+))) :: optional message
|
||||||
|
++ play |= lev=?(%0 %1 %2) :: update by level
|
||||||
|
?-(lev %0 +>, %1 line, %2 line:show:prom) ::
|
||||||
|
++ plow |= [lev=?(%0 %1 %2) mus=(unit tape)] :: complete print
|
||||||
|
abet:(mean:(play lev) mus) ::
|
||||||
|
++ prom %^ emit %pro %& :- %tictactoe :: update prompt
|
||||||
|
": {~[(icon who.gam)]} to move (row/col): " ::
|
||||||
|
++ rend (turn `wall`~(tab go gam) |=(tape txt/+<)) :: table print
|
||||||
|
++ show (emit %mor rend) :: update board
|
||||||
|
++ sole ~(. cs say) :: console library
|
||||||
|
++ work |= act=sole-action :: console input
|
||||||
|
?:(?=(%det -.act) (delt +.act) make) ::
|
||||||
|
-- ::
|
||||||
|
++ abet [(flop moz) .(moz ~)] :: resolve core
|
||||||
|
++ flet |=(from ~(. et +< (~(got by q.eye) ost))) :: in old client
|
||||||
|
++ fret |=(from ~(. et +< *sole-share)) :: in new client
|
||||||
|
++ pals %+ turn (pale hid (prix /sole)) |= sink :: per console
|
||||||
|
[[p=p.+< q=q.+<] r=(~(got by q.eye) p.+<)] ::
|
||||||
|
++ park |= [lev=?(%0 %1 %2) mus=(unit tape)] :: general update
|
||||||
|
=+ pals |- ^+ +>.^$ ?~ +< +>.^$ ::
|
||||||
|
$(+< t.+<, +>.^$ (~(plow et i.+<) lev mus)) ::
|
||||||
|
:: :: ::
|
||||||
|
:::: :: :: events
|
||||||
|
:: :: ::
|
||||||
|
++ peer-sole :: console subscribe
|
||||||
|
|= [from *] =< abet ::
|
||||||
|
(plow:(fret +<-) %2 ~) ::
|
||||||
|
++ poke-sole-action :: console input
|
||||||
|
|= [from act=sole-action] =< abet ::
|
||||||
|
(work:(flet +<-) act) ::
|
||||||
|
++ prep |= [from old=(unit ,[(list move) axle])] :: initialize
|
||||||
|
=< abet ?~ old +> =< (park %2 ~) ::
|
||||||
|
+>(+<+ u.old) ::
|
||||||
|
++ pull-sole :: disconnect console
|
||||||
|
|= [from *] =< abet ::
|
||||||
|
amok:(flet +<-) ::
|
||||||
|
--
|
174
demo/files/2-ape-tictactoe.hoon
Normal file
174
demo/files/2-ape-tictactoe.hoon
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
:: :: ::
|
||||||
|
:::: /hook/core/acto/ape :: :: dependencies
|
||||||
|
:: :: ::
|
||||||
|
/- *sole :: structures
|
||||||
|
/+ sole :: libraries
|
||||||
|
:: :: ::
|
||||||
|
:::: :: :: structures
|
||||||
|
!: :: ::
|
||||||
|
=> |% :: board logic
|
||||||
|
++ board ,@ :: one-player bitfield
|
||||||
|
++ point ,[x=@ y=@] :: coordinate
|
||||||
|
++ game ,[who=? box=board boo=board] :: game state
|
||||||
|
++ icon |=(? ?:(+< 'X' 'O')) :: display at
|
||||||
|
++ bo :: per board
|
||||||
|
|_ bud=board ::
|
||||||
|
++ get |=(point =(1 (cut 0 [(off +<) 1] bud))) :: get point
|
||||||
|
++ off |=(point (add x (mul 3 y))) :: bitfield address
|
||||||
|
++ set |=(point (con bud (bex (off +<)))) :: set point
|
||||||
|
++ win %- lien :_ |=(a=@ =(a (dis a bud))) :: test for win
|
||||||
|
(rip 4 0wl04h0.4A0Aw.4A00s.0e070) :: with bitmasks
|
||||||
|
-- ::
|
||||||
|
++ go :: per game
|
||||||
|
|_ game ::
|
||||||
|
++ at |_ point :: per point
|
||||||
|
++ g +>+< :: game
|
||||||
|
++ k !|(x o) :: ok move
|
||||||
|
++ m ?.(k [| g] [& g:t:?:(who y p)]) :: move
|
||||||
|
++ o (~(get bo boo) +<) :: old at o
|
||||||
|
++ p .(boo (~(set bo boo) +<)) :: play at o
|
||||||
|
++ t .(who !who) :: take turn
|
||||||
|
++ v ?:(x (icon &) ?:(o (icon |) '.')) :: view
|
||||||
|
++ x (~(get bo box) +<) :: old at x
|
||||||
|
++ y .(box (~(set bo box) +<)) :: play at x
|
||||||
|
-- ::
|
||||||
|
++ res ?: ~(win bo box) `"{~[(icon &)]} wins" :: result
|
||||||
|
?: ~(win bo boo) `"{~[(icon |)]} wins" ::
|
||||||
|
?: =(511 (con boo box)) `"tie :-(" ~ ::
|
||||||
|
++ row |= y=@ :~ (add y '1') :: print row
|
||||||
|
' ' ~(v at y 0) ::
|
||||||
|
' ' ~(v at y 1) ::
|
||||||
|
' ' ~(v at y 2) ::
|
||||||
|
== ::
|
||||||
|
++ tab ~["+ 1 2 3" (row 0) (row 1) (row 2)] :: print table
|
||||||
|
-- ::
|
||||||
|
-- ::
|
||||||
|
:: :: ::
|
||||||
|
:::: :: :: server
|
||||||
|
:: :: ::
|
||||||
|
=> |% :: arvo structures
|
||||||
|
++ axle ,[%1 eye=face but=tube gam=game] :: agent state
|
||||||
|
++ axon $?(axle [%0 eye=face gam=game]) :: historical state
|
||||||
|
++ card $% [%diff lime] :: update
|
||||||
|
[%quit ~] :: cancel
|
||||||
|
[%peer wire dock path] :: subscribe
|
||||||
|
[%pull wire dock ~]
|
||||||
|
== ::
|
||||||
|
++ face (pair (list ,@c) (map bone sole-share)) :: interface
|
||||||
|
++ lime $% [%sole-effect sole-effect] :: :sole update
|
||||||
|
[%octo-game game] :: :octo update
|
||||||
|
== ::
|
||||||
|
++ move (pair bone card) :: cause and action
|
||||||
|
++ mote (pair ship ,?) :: remote binding
|
||||||
|
++ tube (unit (pair ,? mote)) :: alive, remote
|
||||||
|
-- ::
|
||||||
|
=> |% :: parsers
|
||||||
|
++ colm (cook |=(a=@ (sub a '1')) (shim '1' '3')) :: row or column
|
||||||
|
++ come ;~(plug colm ;~(pfix fas colm)) :: coordinate
|
||||||
|
++ comb (pick come ;~(pfix sig (punt comp))) :: all command input
|
||||||
|
++ comp ;~(plug fed:ag ;~(pfix ace (flag %x %o))) :: login command
|
||||||
|
++ cope |=(? ?:(+< (stag %| (cold ~ sig)) comb)) :: with wait mode
|
||||||
|
-- ::
|
||||||
|
|_ [hid=hide moz=(list move) axle] :: per agent
|
||||||
|
++ et ::
|
||||||
|
|_ [from say=sole-share] :: per console client
|
||||||
|
++ abet +>(q.eye (~(put by q.eye) ost say)) :: continue
|
||||||
|
++ amok +>(q.eye (~(del by q.eye) ost)) :: discontinue
|
||||||
|
++ beep (emit %bel ~) :: bad user
|
||||||
|
++ cusp (cope wait) :: parsing rule
|
||||||
|
++ delt |= cal=sole-change :: input line change
|
||||||
|
=^ cul say (remit:sole cal good) ::
|
||||||
|
?~ cul (park:abet(p.eye buf.say) | ~) ::
|
||||||
|
abet:beep:(emit det/u.cul) ::
|
||||||
|
++ emit |= fec=sole-effect ^+ +> :: send effect
|
||||||
|
+>(moz [[ost %diff %sole-effect fec] moz]) ::
|
||||||
|
++ emil |= fex=(list sole-effect) :: send effects
|
||||||
|
?~(fex +> $(fex t.fex, +> (emit i.fex))) ::
|
||||||
|
++ good |=((list ,@c) -:(rose (tufa +<) cusp)) :: valid input
|
||||||
|
++ kick |= point :: move command
|
||||||
|
=^ dud gam ~(m ~(at go gam) +<) ::
|
||||||
|
?. dud abet:beep =+ mus=~(res go gam) ::
|
||||||
|
(park:abet(gam ?^(mus *game gam)) %2 mus) ::
|
||||||
|
++ line =^ cal say (transmit:sole set/p.eye) :: update command
|
||||||
|
(emit %det cal) ::
|
||||||
|
++ make =+ dur=(rust (tufa p.eye) comb) ::
|
||||||
|
?~ dur abet:beep ::
|
||||||
|
=. + line(p.eye ~) ::
|
||||||
|
?-(+<.dur & (kick +>.dur), | (plan +>.dur)) ::
|
||||||
|
++ mean |=((unit tape) ?~(+< +> (emit txt/+<+))) :: optional message
|
||||||
|
++ play |= lev=?(%0 %1 %2) :: update by level
|
||||||
|
?-(lev %0 +>, %1 line, %2 line:show:prom) ::
|
||||||
|
++ plow |= [lev=?(%0 %1 %2) mus=(unit tape)] :: complete print
|
||||||
|
abet:(mean:(play lev) mus) ::
|
||||||
|
++ prom %^ emit %pro %& :- %octo :: update prompt
|
||||||
|
?: wait "(their turn) " ::
|
||||||
|
": {~[(icon who.gam)]} to move (row/col): " ::
|
||||||
|
++ plan |= mut=(unit mote) :: peer command
|
||||||
|
?~ mut ?~(but abet:beep stop:abet) ::
|
||||||
|
?^(but abet:beep (link:abet u.mut)) ::
|
||||||
|
++ rend (turn `wall`~(tab go gam) |=(tape txt/+<)) :: table print
|
||||||
|
++ show (emit %mor rend) :: update board
|
||||||
|
++ sole ~(. cs say) :: console library
|
||||||
|
++ wait &(?=(^ but) !=(q.q.u.but who.gam)) :: waiting turn
|
||||||
|
++ work |= act=sole-action :: console input
|
||||||
|
?:(?=(%det -.act) (delt +.act) make) ::
|
||||||
|
-- ::
|
||||||
|
++ abet [(flop moz) .(moz ~)] :: resolve core
|
||||||
|
++ dump |=(mov=move %_(+> moz [mov moz])) :: send move
|
||||||
|
++ dish |=(cad=card (dump 0 cad)) :: forward move
|
||||||
|
++ flet |=(from ~(. et +< (~(got by q.eye) ost))) :: in old client
|
||||||
|
++ fret |=(from ~(. et +< *sole-share)) :: in new client
|
||||||
|
++ like |=(a=ship |*(* [/octo [a %tictactoe] +<])) :: to friend
|
||||||
|
++ link |= mot=mote %+ dish(but `[| mot]) %peer :: subscribe to friend
|
||||||
|
((like p.mot) /octo/net/[?:(q.mot %x %o)]) ::
|
||||||
|
++ pals %+ turn (pale hid (prix /sole)) |= sink :: per console
|
||||||
|
[[p=p.+< q=q.+<] r=(~(got by q.eye) p.+<)] ::
|
||||||
|
++ park |= [lev=?(%0 %1 %2) mus=(unit tape)] :: update all
|
||||||
|
=. +> ?:(=(%2 lev) push +>) ::
|
||||||
|
=+ pals ::
|
||||||
|
|- ^+ +>.^$ ?~ +< +>.^$ ::
|
||||||
|
$(+< t.+<, +>.^$ (~(plow et i.+<) lev mus)) ::
|
||||||
|
++ push =+ pey=(pale hid (prix /octo)) |- ^+ +> :: update friends
|
||||||
|
?~(pey +> $(pey t.pey, +> (sell p.i.pey))) ::
|
||||||
|
++ sell |=(ost=bone (dump ost %diff %octo-game gam)) :: update friend
|
||||||
|
++ stop (dish(but ~) pull/((like +>-.but) ~)) :: cancel subscribe
|
||||||
|
:: :::::::::::::::
|
||||||
|
:::: :: :: :: hooks
|
||||||
|
:: :::::::::::::::
|
||||||
|
++ diff-octo-game :: friend update
|
||||||
|
|= [then gam=game] =< abet ::
|
||||||
|
?. &(?=([~ %& *] but) =(src p.q.u.but)) +> ::
|
||||||
|
?: =(^gam gam) +> ::
|
||||||
|
(park(gam gam) %2 ~) ::
|
||||||
|
++ peer-octo-net :: urbit peer
|
||||||
|
|= [from pax=path] =< abet ::
|
||||||
|
=+ who==(%x -.pax) ::
|
||||||
|
?^ but (park %2 ~) ::
|
||||||
|
(park:(link src !who) %2 `"net from {<src>}") ::
|
||||||
|
++ peer-sole :: console subscribe
|
||||||
|
|= [from pax=path] =< abet ::
|
||||||
|
(plow:(fret +<-) %2 ~) ::
|
||||||
|
++ poke-sole-action :: console input
|
||||||
|
|= [from act=sole-action] =< abet ::
|
||||||
|
(work:(flet +<-) act) ::
|
||||||
|
++ prep |= [from old=(unit ,[(list move) axon])] :: initialize
|
||||||
|
=< abet ?~ old +> ::
|
||||||
|
=< (park %2 ~) ::
|
||||||
|
?- -.+>.old ::
|
||||||
|
%1 +>(+<+ u.old) ::
|
||||||
|
%0 +>(eye.+< eye.+>.old, gam.+< gam.+>.old)::
|
||||||
|
== ::
|
||||||
|
++ pull-octo ::
|
||||||
|
|= [from *] =< abet ::
|
||||||
|
(park(but ~) %2 `"dropped") ::
|
||||||
|
++ pull-sole :: disconnect console
|
||||||
|
|= [from *] =< abet ::
|
||||||
|
amok:(flet +<-) ::
|
||||||
|
++ quit-octo :: unlinked by friend
|
||||||
|
|=([then ~] abet:(park(but ~) %0 `"removed")) ::
|
||||||
|
++ reap-octo :: linked to friend
|
||||||
|
|= [then saw=(unit tang)] =< abet ::
|
||||||
|
?> ?=([~ %| *] but) ::
|
||||||
|
?^ saw (park:stop %0 `"fail to {<src>}") ::
|
||||||
|
(park(p.u.but %&) %0 `"link to {<src>}") ::
|
||||||
|
--
|
185
demo/files/3-ape-tictactoe.hoon
Normal file
185
demo/files/3-ape-tictactoe.hoon
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
:: :: ::
|
||||||
|
:::: /hook/core/acto/ape :: :: dependencies
|
||||||
|
:: :: ::
|
||||||
|
/- *sole :: structures
|
||||||
|
/+ sole :: libraries
|
||||||
|
:: :: ::
|
||||||
|
:::: :: :: structures
|
||||||
|
!: :: ::
|
||||||
|
=> |% :: board logic
|
||||||
|
++ board ,@ :: one-player bitfield
|
||||||
|
++ point ,[x=@ y=@] :: coordinate
|
||||||
|
++ game ,[who=? box=board boo=board] :: game state
|
||||||
|
++ icon |=(? ?:(+< 'X' 'O')) :: display at
|
||||||
|
++ bo :: per board
|
||||||
|
|_ bud=board ::
|
||||||
|
++ get |=(point =(1 (cut 0 [(off +<) 1] bud))) :: get point
|
||||||
|
++ off |=(point (add x (mul 3 y))) :: bitfield address
|
||||||
|
++ set |=(point (con bud (bex (off +<)))) :: set point
|
||||||
|
++ win %- lien :_ |=(a=@ =(a (dis a bud))) :: test for win
|
||||||
|
(rip 4 0wl04h0.4A0Aw.4A00s.0e070) :: with bitmasks
|
||||||
|
-- ::
|
||||||
|
++ go :: per game
|
||||||
|
|_ game ::
|
||||||
|
++ at |_ point :: per point
|
||||||
|
++ g +>+< :: game
|
||||||
|
++ k !|(x o) :: ok move
|
||||||
|
++ m ?.(k [| g] [& g:t:?:(who y p)]) :: move
|
||||||
|
++ o (~(get bo boo) +<) :: old at o
|
||||||
|
++ p .(boo (~(set bo boo) +<)) :: play at o
|
||||||
|
++ t .(who !who) :: take turn
|
||||||
|
++ v ?:(x (icon &) ?:(o (icon |) '.')) :: view
|
||||||
|
++ x (~(get bo box) +<) :: old at x
|
||||||
|
++ y .(box (~(set bo box) +<)) :: play at x
|
||||||
|
-- ::
|
||||||
|
++ res ?: ~(win bo box) `"{~[(icon &)]} wins" :: result
|
||||||
|
?: ~(win bo boo) `"{~[(icon |)]} wins" ::
|
||||||
|
?: =(511 (con boo box)) `"tie :-(" ~ ::
|
||||||
|
++ row |= y=@ :~ (add y '1') :: print row
|
||||||
|
' ' ~(v at y 0) ::
|
||||||
|
' ' ~(v at y 1) ::
|
||||||
|
' ' ~(v at y 2) ::
|
||||||
|
== ::
|
||||||
|
++ tab ~["+ 1 2 3" (row 0) (row 1) (row 2)] :: print table
|
||||||
|
-- ::
|
||||||
|
-- ::
|
||||||
|
:: :: ::
|
||||||
|
:::: :: :: server
|
||||||
|
:: :: ::
|
||||||
|
=> |% :: arvo structures
|
||||||
|
++ axle ,[%1 eye=face but=tube gam=game] :: agent state
|
||||||
|
++ axon $?(axle [%0 eye=face gam=game]) :: historical state
|
||||||
|
++ card $% [%diff lime] :: update
|
||||||
|
[%quit ~] :: cancel
|
||||||
|
[%peer wire dock path] :: subscribe
|
||||||
|
[%pull wire dock ~]
|
||||||
|
== ::
|
||||||
|
++ face (pair (list ,@c) (map bone sole-share)) :: interface
|
||||||
|
++ lime $% [%sole-effect sole-effect] :: :sole update
|
||||||
|
[%octo-game game] :: :octo update
|
||||||
|
== ::
|
||||||
|
++ move (pair bone card) :: cause and action
|
||||||
|
++ mote (pair ship ,?) :: remote binding
|
||||||
|
++ tube (unit (pair ,? mote)) :: alive, remote
|
||||||
|
-- ::
|
||||||
|
=> |% :: parsers
|
||||||
|
++ colm (cook |=(a=@ (sub a '1')) (shim '1' '3')) :: row or column
|
||||||
|
++ come ;~(plug colm ;~(pfix fas colm)) :: coordinate
|
||||||
|
++ comb (pick come ;~(pfix sig (punt comp))) :: all command input
|
||||||
|
++ comp ;~(plug fed:ag ;~(pfix ace (flag %x %o))) :: login command
|
||||||
|
++ cope |=(? ?:(+< (stag %| (cold ~ sig)) comb)) :: with wait mode
|
||||||
|
-- ::
|
||||||
|
|_ [hid=hide moz=(list move) axle] :: per agent
|
||||||
|
++ et ::
|
||||||
|
|_ [from say=sole-share] :: per console client
|
||||||
|
++ abet +>(q.eye (~(put by q.eye) ost say)) :: continue
|
||||||
|
++ amok +>(q.eye (~(del by q.eye) ost)) :: discontinue
|
||||||
|
++ beep (emit %bel ~) :: bad user
|
||||||
|
++ cusp (cope wait) :: parsing rule
|
||||||
|
++ delt |= cal=sole-change :: input line change
|
||||||
|
=^ cul say (remit:sole cal good) ::
|
||||||
|
?~ cul (park:abet(p.eye buf.say) | ~) ::
|
||||||
|
abet:beep:(emit det/u.cul) ::
|
||||||
|
++ emit |= fec=sole-effect ^+ +> :: send effect
|
||||||
|
+>(moz [[ost %diff %sole-effect fec] moz]) ::
|
||||||
|
++ emil |= fex=(list sole-effect) :: send effects
|
||||||
|
?~(fex +> $(fex t.fex, +> (emit i.fex))) ::
|
||||||
|
++ good |=((list ,@c) -:(rose (tufa +<) cusp)) :: valid input
|
||||||
|
++ kick |= point :: move command
|
||||||
|
=^ dud gam ~(m ~(at go gam) +<) ::
|
||||||
|
?. dud abet:beep =+ mus=~(res go gam) ::
|
||||||
|
(park:abet(gam ?^(mus *game gam)) %2 mus) ::
|
||||||
|
++ line =^ cal say (transmit:sole set/p.eye) :: update command
|
||||||
|
(emit %det cal) ::
|
||||||
|
++ make =+ dur=(rust (tufa p.eye) comb) ::
|
||||||
|
?~ dur abet:beep ::
|
||||||
|
=. + line(p.eye ~) ::
|
||||||
|
?-(+<.dur & (kick +>.dur), | (plan +>.dur)) ::
|
||||||
|
++ mean |=((unit tape) ?~(+< +> (emit txt/+<+))) :: optional message
|
||||||
|
++ play |= lev=?(%0 %1 %2) :: update by level
|
||||||
|
?-(lev %0 +>, %1 line, %2 line:show:prom) ::
|
||||||
|
++ plow |= [lev=?(%0 %1 %2) mus=(unit tape)] :: complete print
|
||||||
|
abet:(mean:(play lev) mus) ::
|
||||||
|
++ prom %^ emit %pro %& :- %octo :: update prompt
|
||||||
|
?: wait "(their turn) " ::
|
||||||
|
": {~[(icon who.gam)]} to move (row/col): " ::
|
||||||
|
++ plan |= mut=(unit mote) :: peer command
|
||||||
|
?~ mut ?~(but abet:beep stop:abet) ::
|
||||||
|
?^(but abet:beep (link:abet u.mut)) ::
|
||||||
|
++ rend (turn `wall`~(tab go gam) |=(tape txt/+<)) :: table print
|
||||||
|
++ show (emit %mor rend) :: update board
|
||||||
|
++ sole ~(. cs say) :: console library
|
||||||
|
++ wait &(?=(^ but) !=(q.q.u.but who.gam)) :: waiting turn
|
||||||
|
++ work |= act=sole-action :: console input
|
||||||
|
?:(?=(%det -.act) (delt +.act) make) ::
|
||||||
|
-- ::
|
||||||
|
++ abet [(flop moz) .(moz ~)] :: resolve core
|
||||||
|
++ dump |=(mov=move %_(+> moz [mov moz])) :: send move
|
||||||
|
++ dish |=(cad=card (dump 0 cad)) :: forward move
|
||||||
|
++ flet |=(from ~(. et +< (~(got by q.eye) ost))) :: in old client
|
||||||
|
++ fret |=(from ~(. et +< *sole-share)) :: in new client
|
||||||
|
++ like |=(a=ship |*(* [/octo [a %tictactoe] +<])) :: to friend
|
||||||
|
++ link |= mot=mote %+ dish(but `[| mot]) %peer :: subscribe to friend
|
||||||
|
((like p.mot) /octo/net/[?:(q.mot %x %o)]) ::
|
||||||
|
++ pals %+ turn (pale hid (prix /sole)) |= sink :: per console
|
||||||
|
[[p=p.+< q=q.+<] r=(~(got by q.eye) p.+<)] ::
|
||||||
|
++ park |= [lev=?(%0 %1 %2) mus=(unit tape)] :: update all
|
||||||
|
=. +> ?:(=(%2 lev) push +>) ::
|
||||||
|
=+ pals ::
|
||||||
|
|- ^+ +>.^$ ?~ +< +>.^$ ::
|
||||||
|
$(+< t.+<, +>.^$ (~(plow et i.+<) lev mus)) ::
|
||||||
|
++ push =+ pey=(pale hid (prix /octo)) |- ^+ +> :: update friends
|
||||||
|
?~(pey +> $(pey t.pey, +> (sell p.i.pey))) ::
|
||||||
|
++ sell |=(ost=bone (dump ost %diff %octo-game gam)) :: update friend
|
||||||
|
++ stop (dish(but ~) pull/((like +>-.but) ~)) :: cancel subscribe
|
||||||
|
:: :::::::::::::::
|
||||||
|
:::: :: :: :: hooks
|
||||||
|
:: :::::::::::::::
|
||||||
|
++ diff-octo-game :: friend update
|
||||||
|
|= [then gam=game] =< abet ::
|
||||||
|
?. &(?=([~ %& *] but) =(src p.q.u.but)) +> ::
|
||||||
|
?: =(^gam gam) +> ::
|
||||||
|
(park(gam gam) %2 ~) ::
|
||||||
|
++ peer-octo-net :: urbit peer
|
||||||
|
|= [from pax=path] =< abet ::
|
||||||
|
=+ who==(%x -.pax) ::
|
||||||
|
?^ but (park %2 ~) ::
|
||||||
|
(park:(link src !who) %2 `"net from {<src>}") ::
|
||||||
|
++ peer-octo-web :: web peer
|
||||||
|
|= [from pax=path] =< abet ::
|
||||||
|
~& [%peer-web +<] ::
|
||||||
|
?^ but (park %2 ~) ::
|
||||||
|
%+ park(but `[%& src !who.gam]) %2 ::
|
||||||
|
`"web from {<src>}" ::
|
||||||
|
++ peer-sole :: console subscribe
|
||||||
|
|= [from pax=path] =< abet ::
|
||||||
|
(plow:(fret +<-) %2 ~) ::
|
||||||
|
++ poke-sole-action :: console input
|
||||||
|
|= [from act=sole-action] =< abet ::
|
||||||
|
(work:(flet +<-) act) ::
|
||||||
|
++ poke-octo-move ::
|
||||||
|
|= [from wha=point] =< abet ::
|
||||||
|
=^ dud gam ~(m ~(at go gam) wha) ::
|
||||||
|
?> dud =+ mus=~(res go gam) ::
|
||||||
|
(park(gam ?^(mus *game gam)) %2 mus) ::
|
||||||
|
++ prep |= [from old=(unit ,[(list move) axon])] :: initialize
|
||||||
|
=< abet ?~ old +> ::
|
||||||
|
=< (park %2 ~) ::
|
||||||
|
?- -.+>.old ::
|
||||||
|
%1 +>(+<+ u.old) ::
|
||||||
|
%0 +>(eye.+< eye.+>.old, gam.+< gam.+>.old)::
|
||||||
|
== ::
|
||||||
|
++ pull-octo ::
|
||||||
|
|= [from *] =< abet ::
|
||||||
|
(park(but ~) %2 `"dropped") ::
|
||||||
|
++ pull-sole :: disconnect console
|
||||||
|
|= [from *] =< abet ::
|
||||||
|
amok:(flet +<-) ::
|
||||||
|
++ quit-octo :: unlinked by friend
|
||||||
|
|=([then ~] abet:(park(but ~) %0 `"removed")) ::
|
||||||
|
++ reap-octo :: linked to friend
|
||||||
|
|= [then saw=(unit tang)] =< abet ::
|
||||||
|
?> ?=([~ %| *] but) ::
|
||||||
|
?^ saw (park:stop %0 `"fail to {<src>}") ::
|
||||||
|
(park(p.u.but %&) %0 `"link to {<src>}") ::
|
||||||
|
--
|
26
demo/files/mar-octo-game.hoon
Normal file
26
demo/files/mar-octo-game.hoon
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
::
|
||||||
|
:::: /hook/door/octo-game/mar
|
||||||
|
::
|
||||||
|
/? 310
|
||||||
|
!:
|
||||||
|
|%
|
||||||
|
++ rip9
|
||||||
|
=+ b=0
|
||||||
|
|= a=@ ^- (list ,@A)
|
||||||
|
?: =(b 9) ~
|
||||||
|
[(cut 0 [b 1] a) $(b +(b))]
|
||||||
|
--
|
||||||
|
!:
|
||||||
|
|_ cod=[who=? box=@ boo=@] :: game state
|
||||||
|
::
|
||||||
|
++ grab :: convert from
|
||||||
|
|%
|
||||||
|
++ noun ,[who=? box=@ boo=@] :: clam from %noun
|
||||||
|
--
|
||||||
|
++ grow
|
||||||
|
|%
|
||||||
|
++ json ^- ^json
|
||||||
|
=> |=(bor=@ `^json`a/(turn (rip9 bor) |=(a=@A [%b =(1 a)])))
|
||||||
|
(jobe who/s/?:(who.cod %x %o) box/(. box.cod) boo/(. boo.cod) ~)
|
||||||
|
--
|
||||||
|
--
|
16
demo/files/mar-octo-move.hoon
Normal file
16
demo/files/mar-octo-move.hoon
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
::
|
||||||
|
:::: /hook/door/octo-move/mar
|
||||||
|
::
|
||||||
|
/? 314
|
||||||
|
!:
|
||||||
|
::::
|
||||||
|
::
|
||||||
|
=+ point=,[x=@ y=@]
|
||||||
|
|_ point
|
||||||
|
::
|
||||||
|
++ grab :: convert from
|
||||||
|
|%
|
||||||
|
++ json (corl need (at ni ni ~):jo) :: reparse from %json
|
||||||
|
++ noun point :: clam from %noun
|
||||||
|
--
|
||||||
|
--
|
32
demo/files/pub-octo-hymn.hoon
Normal file
32
demo/files/pub-octo-hymn.hoon
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
::
|
||||||
|
::
|
||||||
|
:::: /hook/hymn/fab/octo/pub/
|
||||||
|
::
|
||||||
|
^- manx
|
||||||
|
;html
|
||||||
|
;head
|
||||||
|
;meta(charset "utf-8");
|
||||||
|
;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.js");
|
||||||
|
;script(type "text/javascript", src "/~/at/base/lib/urb.js");
|
||||||
|
;link(type "text/css", rel "stylesheet", href "/home/lib/base.css");
|
||||||
|
;link(type "text/css", rel "stylesheet", href "/home/pub/octo/src/main.css");
|
||||||
|
;title: :octo
|
||||||
|
==
|
||||||
|
;body
|
||||||
|
;div#what
|
||||||
|
;div#ship
|
||||||
|
;div.sig: ~
|
||||||
|
;div.ship;
|
||||||
|
;div.as;
|
||||||
|
==
|
||||||
|
;div#vs: vs
|
||||||
|
;div#user
|
||||||
|
;div.sig: ~
|
||||||
|
;div.ship;
|
||||||
|
;div.as;
|
||||||
|
==
|
||||||
|
==
|
||||||
|
;div#bord;
|
||||||
|
;script(type "text/javascript", src "/home/pub/octo/src/main.js");
|
||||||
|
==
|
||||||
|
==
|
102
demo/files/pub-octo-main.css
Normal file
102
demo/files/pub-octo-main.css
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#what,
|
||||||
|
#bord {
|
||||||
|
width: 600px;
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#what {
|
||||||
|
height: 36px;
|
||||||
|
top: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bord {
|
||||||
|
height: 600px;
|
||||||
|
position: absolute;
|
||||||
|
top: 111px;
|
||||||
|
opacity: .6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.turn #bord {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#what {
|
||||||
|
font-family: "bau";
|
||||||
|
}
|
||||||
|
|
||||||
|
#what div {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#what .ship {
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.turn #what #ship,
|
||||||
|
#what #user {
|
||||||
|
border: 2px solid #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#what #ship,
|
||||||
|
.turn #what #user {
|
||||||
|
border: 2px solid red;
|
||||||
|
}
|
||||||
|
|
||||||
|
#what #ship,
|
||||||
|
#what #user {
|
||||||
|
padding: .6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#what .as {
|
||||||
|
width: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vs {
|
||||||
|
margin: 0 1rem;
|
||||||
|
padding: .3rem;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spac {
|
||||||
|
font-size: 100px;
|
||||||
|
line-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spac {
|
||||||
|
width: 198px;
|
||||||
|
height: 198px;
|
||||||
|
border: 1px solid #000;
|
||||||
|
text-align: center;
|
||||||
|
float: left;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spac[data-index="0-0"],
|
||||||
|
.spac[data-index="1-0"],
|
||||||
|
.spac[data-index="2-0"] {
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spac[data-index="0-0"],
|
||||||
|
.spac[data-index="0-1"],
|
||||||
|
.spac[data-index="0-2"] {
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spac[data-index="2-0"],
|
||||||
|
.spac[data-index="2-1"],
|
||||||
|
.spac[data-index="2-2"] {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spac[data-index="0-2"],
|
||||||
|
.spac[data-index="1-2"],
|
||||||
|
.spac[data-index="2-2"] {
|
||||||
|
border-right: 0;
|
||||||
|
}
|
62
demo/files/pub-octo-main.js
Normal file
62
demo/files/pub-octo-main.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
$(function() {
|
||||||
|
$bord = $('#bord')
|
||||||
|
$whom = $('#whom')
|
||||||
|
|
||||||
|
lett = ["x","o"]
|
||||||
|
symb = [" ","✕","◯"]
|
||||||
|
draw = function(state) {
|
||||||
|
space = function(_state,y,x) {
|
||||||
|
return "<div class='spac' data-index='"+y+"-"+x+
|
||||||
|
"'>"+symb[_state]+"</div>"
|
||||||
|
}
|
||||||
|
s = ""
|
||||||
|
x = 0
|
||||||
|
y = 0
|
||||||
|
for(i=0;i<9;i++) {
|
||||||
|
j = [0,3,6,1,4,7,2,5,8][i] // XX math
|
||||||
|
s += space((state.box[j] ? 1 : 0)+(state.boo[j] ? 2 : 0),y,x)
|
||||||
|
x++
|
||||||
|
if((i+1)%3 == 0) {
|
||||||
|
y++
|
||||||
|
x=0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$bord.html(s)
|
||||||
|
turn(state.who)
|
||||||
|
}
|
||||||
|
|
||||||
|
which = null
|
||||||
|
turn = function(who) {
|
||||||
|
$('body').toggleClass('turn',(who == which))
|
||||||
|
}
|
||||||
|
|
||||||
|
assign = function(who) {
|
||||||
|
which = who
|
||||||
|
turn(who)
|
||||||
|
$('#ship .as').text(symb[Number(!lett.indexOf(who))+1])
|
||||||
|
$('#user .as').text(symb[lett.indexOf(who)+1])
|
||||||
|
}
|
||||||
|
|
||||||
|
urb.appl = 'octo'
|
||||||
|
urb.bind('/octo/web', function(err,res) {
|
||||||
|
if(which == null) { assign(res.data.who) }
|
||||||
|
draw(res.data)
|
||||||
|
})
|
||||||
|
|
||||||
|
// draw({
|
||||||
|
// box:[false,false,false,false,false,false,false,false,false],
|
||||||
|
// boo:[false,false,false,false,false,false,false,false,false]
|
||||||
|
// })
|
||||||
|
|
||||||
|
$bord.on('click', function(e) {
|
||||||
|
if(!$('body').hasClass('turn')) { return false }
|
||||||
|
$t = $(e.target).closest('.spac')
|
||||||
|
data = $.map(
|
||||||
|
$t.attr('data-index').split('-'),
|
||||||
|
function(i) { return Number(i); })
|
||||||
|
urb.send({mark:'octo-move',data:data})
|
||||||
|
})
|
||||||
|
|
||||||
|
$('#ship .ship').text(window.urb.ship)
|
||||||
|
$('#user .ship').text(window.urb.user)
|
||||||
|
})
|
9
demo/install1.sh
Executable file
9
demo/install1.sh
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
X=$1
|
||||||
|
DEMO=demo
|
||||||
|
COLD=$DEMO/files
|
||||||
|
DESK=urbit/$X/$X/in/$DEMO
|
||||||
|
|
||||||
|
echo "cp -f $COLD/1-ape-tictactoe.hoon $DESK/ape/tictactoe/core/hook"
|
||||||
|
cp -f $COLD/1-ape-tictactoe.hoon $DESK/ape/tictactoe/core/hook
|
12
demo/install2.sh
Executable file
12
demo/install2.sh
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
X=$1
|
||||||
|
DEMO=demo
|
||||||
|
COLD=$DEMO/files
|
||||||
|
DESK=urbit/$X/$X/in/$DEMO
|
||||||
|
|
||||||
|
echo "cp -f $COLD/2-ape-tictactoe.hoon $DESK/ape/tictactoe/core/hook"
|
||||||
|
cp -f $COLD/1-ape-tictactoe.hoon $DESK/ape/tictactoe/core/hook
|
||||||
|
|
||||||
|
echo "cp -f $COLD/mar-octo-game.hoon $DESK/mar/octo-game/door.hook"
|
||||||
|
cp -f $COLD/mar-octo-game.hoon $DESK/mar/octo-game/door.hook
|
21
demo/install3.sh
Executable file
21
demo/install3.sh
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
X=$1
|
||||||
|
DEMO=demo
|
||||||
|
COLD=$DEMO/files
|
||||||
|
DESK=urbit/$X/$X/in/$DEMO
|
||||||
|
|
||||||
|
echo "cp -f $COLD/3-ape-tictactoe.hoon $DESK/ape/tictactoe/core/hook"
|
||||||
|
cp -f $COLD/3-ape-tictactoe.hoon $DESK/ape/tictactoe/core/hook
|
||||||
|
|
||||||
|
echo "cp -f $COLD/mar-octo-game.hoon $DESK/mar/octo-game/door.hook"
|
||||||
|
cp -f $COLD/mar-octo-game.hoon $DESK/mar/octo-game/door.hook
|
||||||
|
|
||||||
|
echo "cp -f $COLD/pub-octo-hymn.hoon $DESK/pub/octo/fab/hymn.hook"
|
||||||
|
cp -f $COLD/pub-octo-hymn.hoon $DESK/pub/octo/fab/hymn.hook
|
||||||
|
|
||||||
|
echo "cp -f $COLD/pub-octo-main.css $DESK/pub/octo/src/main.css"
|
||||||
|
cp -f $COLD/pub-octo-main.css $DESK/pub/octo/src/main.css
|
||||||
|
|
||||||
|
echo "cp -f $COLD/pub-octo-main.js $DESK/pub/octo/src/main.js"
|
||||||
|
cp -f $COLD/pub-octo-main.js $DESK/pub/octo/src/main.js
|
27
demo/script-1.txt
Normal file
27
demo/script-1.txt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
script:
|
||||||
|
~tasfyn-partyv and ~talsur-todres decide to build a tic-tac-toe game
|
||||||
|
|
||||||
|
tasfyn-partyv: would you like to play a game of thermonuclear war?
|
||||||
|
|
||||||
|
talsur-todres: no. how about some tic-tac-toe?
|
||||||
|
|
||||||
|
tasfyn-partyv: sure. but wait, do we have a server?
|
||||||
|
|
||||||
|
talsur-todres:
|
||||||
|
features of the game:
|
||||||
|
(0) we build one-computer two-player TTT
|
||||||
|
(1) we build console tic-tac-toe
|
||||||
|
(2) we install it over the network
|
||||||
|
|
||||||
|
+ 1 2 3
|
||||||
|
1 X X
|
||||||
|
2 O O
|
||||||
|
3 X O X
|
||||||
|
|
||||||
|
? 1/3
|
||||||
|
|
||||||
|
(3) we update it to change the characters
|
||||||
|
|
||||||
|
(4) maybe cheating with some pretyped assets, we make a web view
|
||||||
|
|
||||||
|
(5)
|
147
demo/script-2.txt
Normal file
147
demo/script-2.txt
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
A == ~tasfyn-partyv
|
||||||
|
B == ~talsur-todres
|
||||||
|
|
||||||
|
A and B, on unix terminals on different machines, clone and
|
||||||
|
build urbit from scratch, cutting over the build.
|
||||||
|
|
||||||
|
Each screen is divided into two logical columns. A's
|
||||||
|
screen is filled with two shells. B's screen has a shell
|
||||||
|
on the left and is empty on the right.
|
||||||
|
|
||||||
|
At the unix prompt, both run
|
||||||
|
|
||||||
|
urbit -c myship
|
||||||
|
|
||||||
|
type in an invisible ticket, and begin their ships. All
|
||||||
|
diagnostic messages are suppressed. Both users land
|
||||||
|
initially in :talk.
|
||||||
|
|
||||||
|
A: is this thing on?
|
||||||
|
|
||||||
|
B: who am i? why am i here?
|
||||||
|
|
||||||
|
A: would you like to play a game of global thermonuclear war?
|
||||||
|
|
||||||
|
B: wouldn't you prefer tic-tac-toe?
|
||||||
|
|
||||||
|
A: sure, but i'll have to write it. hang on...
|
||||||
|
|
||||||
|
A switches to :dojo and runs
|
||||||
|
|
||||||
|
:+merge %tic-tac-a ~tasfyn-partyv %home
|
||||||
|
|
||||||
|
In the other window, A runs vim and edits, occasionally
|
||||||
|
hitting :w to save the file:
|
||||||
|
|
||||||
|
demo/file1.txt -> A/in/base/ape/tictactoe/core.hook
|
||||||
|
|
||||||
|
After ++bo,
|
||||||
|
|
||||||
|
A: the board state is a bitfield
|
||||||
|
|
||||||
|
A: btw, you can watch me code at <URL>.
|
||||||
|
|
||||||
|
B opens a browser and points it at <URL>, showing the
|
||||||
|
tree with live update every time A saves.
|
||||||
|
|
||||||
|
After ++go:
|
||||||
|
|
||||||
|
A: game semantics are not that complex...
|
||||||
|
|
||||||
|
After ++move:
|
||||||
|
|
||||||
|
A: basic console io, kinda boilerplaty
|
||||||
|
|
||||||
|
After ++come:
|
||||||
|
|
||||||
|
A: if you can infer the type of the product
|
||||||
|
A: of a combinator parser, you are probably
|
||||||
|
A: a typed functional language even if you
|
||||||
|
A: leave category theory to the real math nerds...
|
||||||
|
|
||||||
|
After ++park:
|
||||||
|
|
||||||
|
A: a fairly vanilla console server. probably some
|
||||||
|
A: of this should be sucked out into a library -
|
||||||
|
A: you can never completely beat the boilerplate.
|
||||||
|
A: also note that this is a two-way console with
|
||||||
|
A: operational transformation that cancels syntax
|
||||||
|
A: errors as you type, just like how :talk violates
|
||||||
|
A: your human rights by lowercasing your capitals.
|
||||||
|
A: finally, while the style is perfectly readable
|
||||||
|
A: for a hoon programmer, we don't normally go in
|
||||||
|
A: for this kind of mildly contrived topiary.
|
||||||
|
|
||||||
|
After ++pull-sole:
|
||||||
|
|
||||||
|
A: those were the event hooks where arvo calls us,
|
||||||
|
A: expecting a new state and a list of actions.
|
||||||
|
A: anyway, this should work - let's try it.
|
||||||
|
A: do this:
|
||||||
|
|
||||||
|
:+sync %tic-tac-a ~tasfyn-partyv %tic-tac-a
|
||||||
|
:+start %tic-tac-a %tictactoe
|
||||||
|
|
||||||
|
B does this. it puts him straight into TTT.
|
||||||
|
|
||||||
|
A: now hang on, I'll join you.
|
||||||
|
|
||||||
|
A uses ^V to pop the hood and types +~B/
|
||||||
|
|
||||||
|
A: bear in mind, this is a very crude shared space.
|
||||||
|
A: your server is just exporting a console interface
|
||||||
|
A: which we both can access. so essentially i'm
|
||||||
|
A: ssh-ed into your game world.
|
||||||
|
|
||||||
|
They play a couple of moves.
|
||||||
|
|
||||||
|
A: it's important to note that your urbit is also
|
||||||
|
A: in a sense, a database. try this from unix:
|
||||||
|
|
||||||
|
killall -9 urbit
|
||||||
|
urbit myship
|
||||||
|
|
||||||
|
B does this, comes back and plays a move.
|
||||||
|
|
||||||
|
B: we don't seem to have lost any data.
|
||||||
|
A: we didn't even come close to losing data,
|
||||||
|
A: so let's come a little closer:
|
||||||
|
|
||||||
|
killall -9 vere
|
||||||
|
rm -rf $checkpoint
|
||||||
|
urbit myship
|
||||||
|
|
||||||
|
B does this, comes back and plays a move.
|
||||||
|
|
||||||
|
B: whoa, that was heavy.
|
||||||
|
A: yeah, your life flashed before your eyes. or at least,
|
||||||
|
A: your event history. this system of checkpoint
|
||||||
|
A: and transaction log is actually how normal dbs work,
|
||||||
|
A: though urbit is designed as a personal computer and
|
||||||
|
A: hardly up for a normal db workload.
|
||||||
|
|
||||||
|
B: it's a little odd that either of us could play X or O.
|
||||||
|
A: or even have an edit war in the command line.
|
||||||
|
|
||||||
|
They have an edit war in the command line.
|
||||||
|
|
||||||
|
B: it might be right for some things. not tictactoe.
|
||||||
|
A: then we'll have to change it! often when someone
|
||||||
|
A: installs your software, later you find out it's not
|
||||||
|
A: perfect and sometimes actually needs to be changed.
|
||||||
|
B: i've had that experience a number of times.
|
||||||
|
A: but it's always tricky to operate on a beating heart,
|
||||||
|
A: so let's try it in a small way first...
|
||||||
|
|
||||||
|
A edits the source file and changes X to Z, or
|
||||||
|
maybe to a Unicode symbol. When he saves, the
|
||||||
|
change propagates to both consoles and also the
|
||||||
|
tree view on B's screen, even to the prompt UI.
|
||||||
|
|
||||||
|
B: i've seen that sort of thing before.
|
||||||
|
A: really? in any case, let's do it for real. the next
|
||||||
|
A: version is a genuine distributed tictactoe with
|
||||||
|
A: its own peer-to-peer move protocol. surely this
|
||||||
|
A: is some fancy technology...
|
||||||
|
|
||||||
|
A edits the source file into
|
162
demo/script-3.txt
Normal file
162
demo/script-3.txt
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
For dialogue: start with dialogue ad-libbed by whoever is
|
||||||
|
doing the production. Later, copy it into a script and
|
||||||
|
edit that script.
|
||||||
|
|
||||||
|
For operation details, see commands.txt. Fill in the script
|
||||||
|
with literal operations *only once you have tested them
|
||||||
|
yourself*.
|
||||||
|
|
||||||
|
A: build and boot A
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
A: private-message B
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
B: create demo desk
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
B: vim in application version 1, just typing, very fast
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
A: sync A's demo desk to B
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
B: log in to A's tictactoe (intentionally reversed)
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
A: start tictactoe on A
|
||||||
|
|
||||||
|
A/B: play ONE full game of tictactoe, moves interleaved with
|
||||||
|
these subdemos:
|
||||||
|
|
||||||
|
B changes X to Z in the source, then changes it back
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
A or B enters an invalid move, beep sound is heard
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
A kills and restarts the vere process:
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
A kills the vere process, deletes the checkpoint, restarts:
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
A or B enters an invalid move, beep sound is heard:
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
A and B tussle humorously over weird shared command line
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
B edits version 1 into version 2, automagically upgrading A
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
B logs out of A's tictactoe
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
B starts local tictactoe
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
B connects local tictactoe to A's server
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
B edits in version 3 ape, with web support
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
A: watch editing of application
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
B edits in mar, pub (very fast)
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
A: logs in to game url
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
A: brings up web talk
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
B: creates a local channel to talk about TTT
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
A: subscribes from the web UI to B's channel
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
C, D, and E: join the channel and give humorous advice
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
A: loses the game
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
B: sends bitcoin payment to A
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
A: points browser at blockchain.info, shows real payment
|
||||||
|
|
||||||
|
...
|
||||||
|
""
|
||||||
|
|
||||||
|
close:
|
||||||
|
credit screen 1:
|
||||||
|
|
||||||
|
*everyone who has ever worked/for at Tlon, in alphabetical
|
||||||
|
order*,
|
||||||
|
|
||||||
|
credit screen 2:
|
||||||
|
|
||||||
|
*every non Tlon github uid that has contributed to our repository*
|
||||||
|
|
||||||
|
credit screen 3:
|
||||||
|
|
||||||
|
~, huge
|
||||||
|
|
@ -1121,6 +1121,7 @@
|
|||||||
# define c3__veer c3_s4('v','e','e','r')
|
# define c3__veer c3_s4('v','e','e','r')
|
||||||
# define c3__vega c3_s4('v','e','g','a')
|
# define c3__vega c3_s4('v','e','g','a')
|
||||||
# define c3__velt c3_s4('v','e','l','t')
|
# define c3__velt c3_s4('v','e','l','t')
|
||||||
|
# define c3__verb c3_s4('v','e','r','b')
|
||||||
# define c3__vern c3_s4('v','e','r','n')
|
# define c3__vern c3_s4('v','e','r','n')
|
||||||
# define c3__very c3_s4('v','e','r','y')
|
# define c3__very c3_s4('v','e','r','y')
|
||||||
# define c3__view c3_s4('v','i','e','w')
|
# define c3__view c3_s4('v','i','e','w')
|
||||||
|
8
i/n/a.h
8
i/n/a.h
@ -104,11 +104,9 @@
|
|||||||
/* u3a_road: contiguous allocation and execution context.
|
/* u3a_road: contiguous allocation and execution context.
|
||||||
*/
|
*/
|
||||||
typedef struct _u3a_road {
|
typedef struct _u3a_road {
|
||||||
struct _u3a_road* par_u; // parent road
|
u3p(struct _u3a_road) par_p; // parent road
|
||||||
|
u3p(struct _u3a_road) kid_p; // child road list
|
||||||
struct _u3a_road* kid_u; // child road list
|
u3p(struct _u3a_road) nex_p; // sibling road
|
||||||
struct _u3a_road* nex_u; // sibling road
|
|
||||||
struct _u3a_road* now_u; // current road pointer
|
|
||||||
|
|
||||||
u3p(c3_w) cap_p; // top of transient region
|
u3p(c3_w) cap_p; // top of transient region
|
||||||
u3p(c3_w) hat_p; // top of durable region
|
u3p(c3_w) hat_p; // top of durable region
|
||||||
|
3
i/n/o.h
3
i/n/o.h
@ -23,7 +23,8 @@
|
|||||||
u3o_check_corrupt = 0x4, // check: gc memory
|
u3o_check_corrupt = 0x4, // check: gc memory
|
||||||
u3o_check_fatal = 0x8, // check: unrecoverable
|
u3o_check_fatal = 0x8, // check: unrecoverable
|
||||||
u3o_verbose = 0x10, // be remarkably wordy
|
u3o_verbose = 0x10, // be remarkably wordy
|
||||||
u3o_dryrun = 0x20 // don't touch checkpoint
|
u3o_dryrun = 0x20, // don't touch checkpoint
|
||||||
|
u3o_quiet = 0x40 // disable ~&
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Globals.
|
/** Globals.
|
||||||
|
1
i/n/u.h
1
i/n/u.h
@ -104,5 +104,6 @@
|
|||||||
/* u3to(), u3of(): offset/pointer conversion.
|
/* u3to(), u3of(): offset/pointer conversion.
|
||||||
*/
|
*/
|
||||||
# define u3to(type, x) ((type *) u3a_into(x))
|
# define u3to(type, x) ((type *) u3a_into(x))
|
||||||
|
# define u3tn(type, x) (x == 0) ? (void *)0 : ((type *) u3a_into(x))
|
||||||
# define u3of(type, x) (u3a_outa((type *)x))
|
# define u3of(type, x) (u3a_outa((type *)x))
|
||||||
|
|
||||||
|
15
i/v/vere.h
15
i/v/vere.h
@ -521,6 +521,8 @@
|
|||||||
c3_c* imp_c; // -I, czar name
|
c3_c* imp_c; // -I, czar name
|
||||||
c3_c* nam_c; // -n, unix hostname
|
c3_c* nam_c; // -n, unix hostname
|
||||||
c3_c* raf_c; // -r, raft flotilla
|
c3_c* raf_c; // -r, raft flotilla
|
||||||
|
c3_c* who_c; // -T, begin with ticket
|
||||||
|
c3_c* tic_c; // -T, ticket value
|
||||||
c3_w kno_w; // -k, kernel version
|
c3_w kno_w; // -k, kernel version
|
||||||
c3_w fuz_w; // -f, fuzz testing
|
c3_w fuz_w; // -f, fuzz testing
|
||||||
c3_s por_s; // -p, ames port
|
c3_s por_s; // -p, ames port
|
||||||
@ -536,7 +538,8 @@
|
|||||||
c3_o pro; // -P, profile
|
c3_o pro; // -P, profile
|
||||||
c3_o veb; // -v, verbose (inverse of -q)
|
c3_o veb; // -v, verbose (inverse of -q)
|
||||||
c3_o nuu; // -c, new pier
|
c3_o nuu; // -c, new pier
|
||||||
c3_o vno; // -V
|
c3_o qui; // -q, quiet
|
||||||
|
c3_o vno; // -V, turn on +verb
|
||||||
c3_o mem; // -M, memory madness
|
c3_o mem; // -M, memory madness
|
||||||
} u3_opts;
|
} u3_opts;
|
||||||
|
|
||||||
@ -791,6 +794,16 @@
|
|||||||
void
|
void
|
||||||
u3_term_ef_boil();
|
u3_term_ef_boil();
|
||||||
|
|
||||||
|
/* u3_term_ef_ticket(): initial effects for new ticket.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
u3_term_ef_ticket(c3_c* who_c, c3_c* tic_c);
|
||||||
|
|
||||||
|
/* u3_term_ef_verb(): initial effects for verbose events.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
u3_term_ef_verb(void);
|
||||||
|
|
||||||
/* u3_term_ef_winc(): window change.
|
/* u3_term_ef_winc(): window change.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
4
n/a.c
4
n/a.c
@ -967,11 +967,11 @@ _me_copy_south(u3_noun dog)
|
|||||||
u3a_cell* new_u = (u3a_cell*)(void *)new_w;
|
u3a_cell* new_u = (u3a_cell*)(void *)new_w;
|
||||||
|
|
||||||
// printf("south: cell %p to %p\r\n", old_u, new_u);
|
// printf("south: cell %p to %p\r\n", old_u, new_u);
|
||||||
|
#if 0
|
||||||
if ( old_u->mug_w == 0x730e66cc ) {
|
if ( old_u->mug_w == 0x730e66cc ) {
|
||||||
fprintf(stderr, "BAD: take %p\r\n", new_u);
|
fprintf(stderr, "BAD: take %p\r\n", new_u);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
new_u->mug_w = old_u->mug_w;
|
new_u->mug_w = old_u->mug_w;
|
||||||
// new_u->mug_w = 0;
|
// new_u->mug_w = 0;
|
||||||
new_u->hed = _me_copy_south_in(old_u->hed);
|
new_u->hed = _me_copy_south_in(old_u->hed);
|
||||||
|
4
n/j.c
4
n/j.c
@ -209,8 +209,8 @@ u3j_find(u3_noun bat)
|
|||||||
return jaw;
|
return jaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( rod_u->par_u ) {
|
if ( rod_u->par_p ) {
|
||||||
rod_u = rod_u->par_u;
|
rod_u = u3to(u3_road, rod_u->par_p);
|
||||||
}
|
}
|
||||||
else return u3_none;
|
else return u3_none;
|
||||||
}
|
}
|
||||||
|
36
n/m.c
36
n/m.c
@ -144,7 +144,7 @@ _cm_signal_handle_term(int x)
|
|||||||
{
|
{
|
||||||
// Ignore if we are using base memory from work memory, very rare.
|
// Ignore if we are using base memory from work memory, very rare.
|
||||||
//
|
//
|
||||||
if ( (0 != u3H->rod_u.kid_u) && (&(u3H->rod_u) == u3R) ) {
|
if ( (0 != u3H->rod_u.kid_p) && (&(u3H->rod_u) == u3R) ) {
|
||||||
_cm_emergency("ignored", c3__term);
|
_cm_emergency("ignored", c3__term);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -179,7 +179,7 @@ _cm_signal_reset(void)
|
|||||||
u3R = &u3H->rod_u;
|
u3R = &u3H->rod_u;
|
||||||
u3R->cap_p = u3R->mat_p;
|
u3R->cap_p = u3R->mat_p;
|
||||||
u3R->ear_p = 0;
|
u3R->ear_p = 0;
|
||||||
u3R->kid_u = 0;
|
u3R->kid_p = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _cm_stack_recover(): recover stack trace, with lacunae.
|
/* _cm_stack_recover(): recover stack trace, with lacunae.
|
||||||
@ -271,13 +271,13 @@ _cm_signal_recover(c3_l sig_l, u3_noun arg)
|
|||||||
u3R = &(u3H->rod_u);
|
u3R = &(u3H->rod_u);
|
||||||
rod_u = u3R;
|
rod_u = u3R;
|
||||||
|
|
||||||
while ( rod_u->kid_u ) {
|
while ( rod_u->kid_p ) {
|
||||||
#if 0
|
#if 0
|
||||||
fprintf(stderr, "collecting %d frames\r\n",
|
fprintf(stderr, "collecting %d frames\r\n",
|
||||||
u3kb_lent(rod_u->kid_u->bug.tax));
|
u3kb_lent((u3to(u3_road, rod_u->kid_p)->bug.tax));
|
||||||
#endif
|
#endif
|
||||||
tax = u3kb_weld(_cm_stack_recover(rod_u->kid_u), tax);
|
tax = u3kb_weld(_cm_stack_recover(u3to(u3_road, rod_u->kid_p)), tax);
|
||||||
rod_u = rod_u->kid_u;
|
rod_u = u3to(u3_road, rod_u->kid_p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -709,9 +709,9 @@ u3m_leap(c3_w pad_w)
|
|||||||
/* Attach the new road to its parents.
|
/* Attach the new road to its parents.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
c3_assert(0 == u3R->kid_u);
|
c3_assert(0 == u3R->kid_p);
|
||||||
rod_u->par_u = u3R;
|
rod_u->par_p = u3of(u3_road, u3R);
|
||||||
u3R->kid_u = rod_u;
|
u3R->kid_p = u3of(u3_road, rod_u);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the new road.
|
/* Set up the new road.
|
||||||
@ -727,26 +727,26 @@ u3m_leap(c3_w pad_w)
|
|||||||
void
|
void
|
||||||
u3m_fall()
|
u3m_fall()
|
||||||
{
|
{
|
||||||
c3_assert(0 != u3R->par_u);
|
c3_assert(0 != u3R->par_p);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
fprintf(stderr, "fall: from %s %p, to %s %p (cap %p, was %p)\r\n",
|
fprintf(stderr, "fall: from %s %p, to %s %p (cap %p, was %p)\r\n",
|
||||||
_(u3a_is_north(u3R)) ? "north" : "south",
|
_(u3a_is_north(u3R)) ? "north" : "south",
|
||||||
u3R,
|
u3R,
|
||||||
_(u3a_is_north(u3R)) ? "north" : "south",
|
_(u3a_is_north(u3R)) ? "north" : "south",
|
||||||
u3R->par_u,
|
u3to(u3_road, u3R->par_p),
|
||||||
u3R->hat_w,
|
u3R->hat_w,
|
||||||
u3R->rut_w);
|
u3R->rut_w);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The new cap is the old hat - it's as simple as that.
|
/* The new cap is the old hat - it's as simple as that.
|
||||||
*/
|
*/
|
||||||
u3R->par_u->cap_p = u3R->hat_p;
|
u3to(u3_road, u3R->par_p)->cap_p = u3R->hat_p;
|
||||||
|
|
||||||
/* And, we're back home.
|
/* And, we're back home.
|
||||||
*/
|
*/
|
||||||
u3R = u3R->par_u;
|
u3R = u3to(u3_road, u3R->par_p);
|
||||||
u3R->kid_u = 0;
|
u3R->kid_p = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* u3m_hate(): new, integrated leap mechanism (enter).
|
/* u3m_hate(): new, integrated leap mechanism (enter).
|
||||||
@ -948,8 +948,8 @@ u3m_soft_run(u3_noun fly,
|
|||||||
/* Configure the new road.
|
/* Configure the new road.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
u3R->ski.flu = u3nc(fly, u3R->par_u->ski.flu);
|
u3R->ski.flu = u3nc(fly, u3to(u3_road, u3R->par_p)->ski.flu);
|
||||||
u3R->pro.don = u3R->par_u->pro.don;
|
u3R->pro.don = u3to(u3_road, u3R->par_p)->pro.don;
|
||||||
u3R->bug.tax = 0;
|
u3R->bug.tax = 0;
|
||||||
}
|
}
|
||||||
u3t_on(coy_o);
|
u3t_on(coy_o);
|
||||||
@ -1036,8 +1036,8 @@ u3m_soft_esc(u3_noun sam)
|
|||||||
/* Configure the new road.
|
/* Configure the new road.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
u3R->ski.flu = u3t(u3R->par_u->ski.flu);
|
u3R->ski.flu = u3t(u3to(u3_road, u3R->par_p)->ski.flu);
|
||||||
u3R->pro.don = u3R->par_u->pro.don;
|
u3R->pro.don = u3to(u3_road, u3R->par_p)->pro.don;
|
||||||
u3R->bug.tax = 0;
|
u3R->bug.tax = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
n/n.c
2
n/n.c
@ -46,9 +46,11 @@ _n_hint(u3_noun zep,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case c3__slog: {
|
case c3__slog: {
|
||||||
|
if ( !(u3C.wag_w & u3o_quiet) ) {
|
||||||
u3t_off(noc_o);
|
u3t_off(noc_o);
|
||||||
u3t_slog(hod);
|
u3t_slog(hod);
|
||||||
u3t_on(noc_o);
|
u3t_on(noc_o);
|
||||||
|
}
|
||||||
return _n_nock_on(bus, nex);
|
return _n_nock_on(bus, nex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
n/t.c
6
n/t.c
@ -113,8 +113,8 @@ _t_jet_label(u3a_road* rod_u, u3_noun bat)
|
|||||||
return u3h(u3t(u3t(u3h(cax))));
|
return u3h(u3t(u3t(u3h(cax))));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( rod_u->par_u ) {
|
if ( rod_u->par_p ) {
|
||||||
rod_u = rod_u->par_u;
|
rod_u = u3to(u3_road, rod_u->par_p);
|
||||||
}
|
}
|
||||||
else return u3_none;
|
else return u3_none;
|
||||||
}
|
}
|
||||||
@ -175,7 +175,7 @@ _t_samp_process(u3_road* rod_u)
|
|||||||
}
|
}
|
||||||
don = u3t(don);
|
don = u3t(don);
|
||||||
}
|
}
|
||||||
rod_u = rod_u->par_u;
|
rod_u = u3tn(u3_road, rod_u->par_p);
|
||||||
}
|
}
|
||||||
u3z(muf);
|
u3z(muf);
|
||||||
|
|
||||||
|
1
v/ames.c
1
v/ames.c
@ -67,6 +67,7 @@ _ames_czar(c3_y imp_y, c3_s* por_s)
|
|||||||
|
|
||||||
snprintf(dns_c, 64, "%s.urbit.org", nam_c + 1);
|
snprintf(dns_c, 64, "%s.urbit.org", nam_c + 1);
|
||||||
// uL(fprintf(uH, "czar %s, dns %s\n", nam_c, dns_c));
|
// uL(fprintf(uH, "czar %s, dns %s\n", nam_c, dns_c));
|
||||||
|
|
||||||
free(nam_c);
|
free(nam_c);
|
||||||
u3z(nam);
|
u3z(nam);
|
||||||
|
|
||||||
|
7
v/loop.c
7
v/loop.c
@ -691,9 +691,16 @@ u3_lo_lead(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( c3y == u3_Host.ops_u.nuu ) {
|
if ( c3y == u3_Host.ops_u.nuu ) {
|
||||||
|
if ( u3_Host.ops_u.who_c ) {
|
||||||
|
u3_term_ef_ticket(u3_Host.ops_u.who_c, u3_Host.ops_u.tic_c);
|
||||||
|
}
|
||||||
u3_term_ef_boil(1);
|
u3_term_ef_boil(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( c3y == u3_Host.ops_u.veb ) {
|
||||||
|
u3_term_ef_verb();
|
||||||
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
_lo_slow();
|
_lo_slow();
|
||||||
#endif
|
#endif
|
||||||
|
35
v/main.c
35
v/main.c
@ -40,6 +40,22 @@ _main_readw(const c3_c* str_c, c3_w max_w, c3_w* out_w)
|
|||||||
|
|
||||||
static c3_c hostbuf[2048]; // kill me
|
static c3_c hostbuf[2048]; // kill me
|
||||||
|
|
||||||
|
/* _main_presig(): prefix optional sig.
|
||||||
|
*/
|
||||||
|
c3_c*
|
||||||
|
_main_presig(c3_c* txt_c)
|
||||||
|
{
|
||||||
|
c3_c* new_c = malloc(2 + strlen(txt_c));
|
||||||
|
|
||||||
|
if ( '~' == *txt_c ) {
|
||||||
|
strcpy(new_c, txt_c);
|
||||||
|
} else {
|
||||||
|
new_c[0] = '~';
|
||||||
|
strcpy(new_c + 1, txt_c);
|
||||||
|
}
|
||||||
|
return new_c;
|
||||||
|
}
|
||||||
|
|
||||||
/* _main_getopt(): extract option map from command line.
|
/* _main_getopt(): extract option map from command line.
|
||||||
*/
|
*/
|
||||||
static u3_noun
|
static u3_noun
|
||||||
@ -57,12 +73,13 @@ _main_getopt(c3_i argc, c3_c** argv)
|
|||||||
u3_Host.ops_u.fak = c3n;
|
u3_Host.ops_u.fak = c3n;
|
||||||
u3_Host.ops_u.pro = c3n;
|
u3_Host.ops_u.pro = c3n;
|
||||||
u3_Host.ops_u.dry = c3n;
|
u3_Host.ops_u.dry = c3n;
|
||||||
u3_Host.ops_u.veb = c3y;
|
u3_Host.ops_u.veb = c3n;
|
||||||
|
u3_Host.ops_u.qui = c3n;
|
||||||
u3_Host.ops_u.nuu = c3n;
|
u3_Host.ops_u.nuu = c3n;
|
||||||
u3_Host.ops_u.mem = c3n;
|
u3_Host.ops_u.mem = c3n;
|
||||||
u3_Host.ops_u.kno_w = DefaultKernel;
|
u3_Host.ops_u.kno_w = DefaultKernel;
|
||||||
|
|
||||||
while ( (ch_i = getopt(argc, argv, "I:X:f:k:l:n:p:r:LabcdgqvFMPD")) != -1 ) {
|
while ( (ch_i = getopt(argc, argv, "I:T:X:f:k:l:n:p:r:LabcdgqvFMPD")) != -1 ) {
|
||||||
switch ( ch_i ) {
|
switch ( ch_i ) {
|
||||||
case 'M': {
|
case 'M': {
|
||||||
u3_Host.ops_u.mem = c3y;
|
u3_Host.ops_u.mem = c3y;
|
||||||
@ -72,6 +89,11 @@ _main_getopt(c3_i argc, c3_c** argv)
|
|||||||
u3_Host.ops_u.imp_c = strdup(optarg);
|
u3_Host.ops_u.imp_c = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'T': {
|
||||||
|
u3_Host.ops_u.who_c = _main_presig(optarg);
|
||||||
|
u3_Host.ops_u.tic_c = _main_presig(getpass("your ticket: ~"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'X': {
|
case 'X': {
|
||||||
if ( 0 != strcmp("wtf", optarg) ) {
|
if ( 0 != strcmp("wtf", optarg) ) {
|
||||||
return c3n;
|
return c3n;
|
||||||
@ -123,7 +145,7 @@ _main_getopt(c3_i argc, c3_c** argv)
|
|||||||
case 'g': { u3_Host.ops_u.gab = c3y; break; }
|
case 'g': { u3_Host.ops_u.gab = c3y; break; }
|
||||||
case 'P': { u3_Host.ops_u.pro = c3y; break; }
|
case 'P': { u3_Host.ops_u.pro = c3y; break; }
|
||||||
case 'D': { u3_Host.ops_u.dry = c3y; break; }
|
case 'D': { u3_Host.ops_u.dry = c3y; break; }
|
||||||
case 'q': { u3_Host.ops_u.veb = c3n; break; }
|
case 'q': { u3_Host.ops_u.qui = c3y; break; }
|
||||||
case 'v': { u3_Host.ops_u.veb = c3y; break; }
|
case 'v': { u3_Host.ops_u.veb = c3y; break; }
|
||||||
case '?': default: {
|
case '?': default: {
|
||||||
return c3n;
|
return c3n;
|
||||||
@ -330,6 +352,12 @@ main(c3_i argc,
|
|||||||
u3C.wag_w |= u3o_verbose;
|
u3C.wag_w |= u3o_verbose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set quiet flag.
|
||||||
|
*/
|
||||||
|
if ( _(u3_Host.ops_u.qui) ) {
|
||||||
|
u3C.wag_w |= u3o_quiet;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set dry-run flag.
|
/* Set dry-run flag.
|
||||||
*/
|
*/
|
||||||
if ( _(u3_Host.ops_u.dry) ) {
|
if ( _(u3_Host.ops_u.dry) ) {
|
||||||
@ -363,6 +391,7 @@ main(c3_i argc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// u3e_grab("main", u3_none);
|
// u3e_grab("main", u3_none);
|
||||||
|
//
|
||||||
u3_lo_loop();
|
u3_lo_loop();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
5
v/reck.c
5
v/reck.c
@ -365,8 +365,6 @@ u3_reck_kick(u3_noun ovo)
|
|||||||
if ( (c3n == _reck_kick_spec(u3k(u3h(ovo)), u3k(u3t(ovo)))) &&
|
if ( (c3n == _reck_kick_spec(u3k(u3h(ovo)), u3k(u3t(ovo)))) &&
|
||||||
(c3n == _reck_kick_norm(u3k(u3h(ovo)), u3k(u3t(ovo)))) )
|
(c3n == _reck_kick_norm(u3k(u3h(ovo)), u3k(u3t(ovo)))) )
|
||||||
{
|
{
|
||||||
u3_noun tox = u3do("spat", u3k(u3h(ovo)));
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if ( (c3__warn != u3h(u3t(ovo))) &&
|
if ( (c3__warn != u3h(u3t(ovo))) &&
|
||||||
(c3__text != u3h(u3t(ovo))) &&
|
(c3__text != u3h(u3t(ovo))) &&
|
||||||
@ -384,9 +382,11 @@ u3_reck_kick(u3_noun ovo)
|
|||||||
u3nc(c3__flog, u3k(u3t(ovo))));
|
u3nc(c3__flog, u3k(u3t(ovo))));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
u3_noun tox = u3do("spat", u3k(u3h(ovo)));
|
||||||
uL(fprintf(uH, "kick: lost %%%s on %s\n",
|
uL(fprintf(uH, "kick: lost %%%s on %s\n",
|
||||||
u3r_string(u3h(u3t(ovo))),
|
u3r_string(u3h(u3t(ovo))),
|
||||||
u3r_string(tox)));
|
u3r_string(tox)));
|
||||||
|
u3z(tox);
|
||||||
#if 0
|
#if 0
|
||||||
if ( c3__hear == u3h(u3t(ovo)) ) {
|
if ( c3__hear == u3h(u3t(ovo)) ) {
|
||||||
c3_assert(0);
|
c3_assert(0);
|
||||||
@ -394,7 +394,6 @@ u3_reck_kick(u3_noun ovo)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
u3z(tox);
|
|
||||||
}
|
}
|
||||||
u3z(ovo);
|
u3z(ovo);
|
||||||
}
|
}
|
||||||
|
4
v/sist.c
4
v/sist.c
@ -222,9 +222,13 @@ _sist_suck(u3_noun ovo, u3_noun gon)
|
|||||||
|
|
||||||
u3_lo_punt(2, u3kb_flop(u3k(u3t(gon))));
|
u3_lo_punt(2, u3kb_flop(u3k(u3t(gon))));
|
||||||
// u3_loom_exit();
|
// u3_loom_exit();
|
||||||
|
#if 1
|
||||||
u3_lo_exit();
|
u3_lo_exit();
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
|
#else
|
||||||
|
u3z(ovo); u3z(gon);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _sist_sing(): replay ovum from the past, time already set.
|
/* _sist_sing(): replay ovum from the past, time already set.
|
||||||
|
36
v/term.c
36
v/term.c
@ -1012,6 +1012,42 @@ u3_term_ef_boil(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* u3_term_ef_verb(): initial effects for verbose events
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
u3_term_ef_verb(void)
|
||||||
|
{
|
||||||
|
u3_noun pax = u3nq(u3_blip, c3__term, '1', u3_nul);
|
||||||
|
|
||||||
|
u3v_plan(pax, u3nc(c3__verb, u3_nul));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* u3_term_ef_ticket(): initial effects for new ticket.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
u3_term_ef_ticket(c3_c* who_c, c3_c* tic_c)
|
||||||
|
{
|
||||||
|
u3_noun pax = u3nq(u3_blip, c3__term, '1', u3_nul);
|
||||||
|
u3_noun who, tic;
|
||||||
|
u3_noun whu, tuc;
|
||||||
|
|
||||||
|
whu = u3dc("slaw", 'p', u3i_string(who_c));
|
||||||
|
if ( u3_nul == whu ) {
|
||||||
|
fprintf(stderr, "ticket: invalid planet '%s'\r\n", who_c);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
else { who = u3k(u3t(whu)); u3z(whu); }
|
||||||
|
|
||||||
|
tuc = u3dc("slaw", 'p', u3i_string(tic_c));
|
||||||
|
if ( u3_nul == tuc ) {
|
||||||
|
fprintf(stderr, "ticket: invalid secret '%s'\r\n", tic_c);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
else { tic = u3k(u3t(tuc)); u3z(tuc); }
|
||||||
|
|
||||||
|
u3v_plan(pax, u3nt(c3__tick, who, tic));
|
||||||
|
}
|
||||||
|
|
||||||
/* u3_term_ef_bake(): initial effects for new terminal.
|
/* u3_term_ef_bake(): initial effects for new terminal.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
331
v/unix.c
331
v/unix.c
@ -21,6 +21,9 @@
|
|||||||
#include "all.h"
|
#include "all.h"
|
||||||
#include "v/vere.h"
|
#include "v/vere.h"
|
||||||
|
|
||||||
|
/* undef this to turn off syncing out to unix */
|
||||||
|
#define ERGO_SYNC
|
||||||
|
|
||||||
/* _unix_ship_in(): c3_w[4] to ship.
|
/* _unix_ship_in(): c3_w[4] to ship.
|
||||||
*/
|
*/
|
||||||
static u3_noun
|
static u3_noun
|
||||||
@ -82,42 +85,6 @@ _unix_mkdir(c3_c* pax_c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _unix_mkpath(): mkdir -p, asserting
|
|
||||||
*
|
|
||||||
* adapted from
|
|
||||||
* http://niallohiggins.com/2009/01/08/mkpath-mkdir-p-alike-in-c-for-unix/
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
_unix_mkpath(const char *s)
|
|
||||||
{
|
|
||||||
char *q, *r = NULL, *path = NULL, *up = NULL;
|
|
||||||
|
|
||||||
if (strcmp(s, ".") == 0 || strcmp(s, "/") == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((path = strdup(s)) == NULL)
|
|
||||||
c3_assert(0);
|
|
||||||
|
|
||||||
if ((q = strdup(s)) == NULL)
|
|
||||||
c3_assert(0);
|
|
||||||
|
|
||||||
if ((r = dirname(q)) == NULL)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if ((up = strdup(r)) == NULL)
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
_unix_mkpath(up);
|
|
||||||
|
|
||||||
_unix_mkdir(path);
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (up != NULL)
|
|
||||||
free(up);
|
|
||||||
free(q);
|
|
||||||
free(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _unix_opendir(): opendir, recreating if nonexistent.
|
/* _unix_opendir(): opendir, recreating if nonexistent.
|
||||||
*/
|
*/
|
||||||
static DIR*
|
static DIR*
|
||||||
@ -137,17 +104,6 @@ _unix_opendir(c3_c* pax_c)
|
|||||||
return rid_u;
|
return rid_u;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _unix_unlink(): unlink, asserting.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
_unix_unlink(c3_c* pax_c)
|
|
||||||
{
|
|
||||||
if ( 0 != unlink(pax_c) && ENOENT != errno ) {
|
|
||||||
uL(fprintf(uH, "error unlinking %s: %s\n", pax_c, strerror(errno)));
|
|
||||||
c3_assert(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* u3_unix_acquire(): acquire a lockfile, killing anything that holds it.
|
/* u3_unix_acquire(): acquire a lockfile, killing anything that holds it.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@ -332,38 +288,6 @@ _unix_file_watch(u3_ufil* fil_u,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _unix_file_form(): form a filename path downward.
|
|
||||||
*/
|
|
||||||
static c3_c*
|
|
||||||
_unix_file_form(c3_c* pax_c,
|
|
||||||
u3_noun pre,
|
|
||||||
u3_noun ket,
|
|
||||||
u3_noun ext)
|
|
||||||
{
|
|
||||||
c3_c* pre_c = u3r_string(pre);
|
|
||||||
c3_c* ext_c = u3r_string(ext);
|
|
||||||
c3_w pax_w = strlen(pax_c);
|
|
||||||
c3_w pre_w = strlen(pre_c);
|
|
||||||
c3_w ext_w = strlen(ext_c);
|
|
||||||
c3_w ket_w = (c3y == ket) ? 1 : 0;
|
|
||||||
c3_c* pox_c = c3_malloc(pax_w + 1 + pre_w + 1 + ket_w + ext_w + 1);
|
|
||||||
|
|
||||||
strncpy(pox_c, pax_c, pax_w);
|
|
||||||
pox_c[pax_w] = '/';
|
|
||||||
strncpy(pox_c + pax_w + 1, pre_c, pre_w);
|
|
||||||
pox_c[pax_w + 1 + pre_w] = '.';
|
|
||||||
if ( c3y == ket ) {
|
|
||||||
pox_c[pax_w + 1 + pre_w + 1] = '^';
|
|
||||||
}
|
|
||||||
strncpy(pox_c + pax_w + 1 + pre_w + 1 + ket_w, ext_c, ext_w);
|
|
||||||
pox_c[pax_w + 1 + pre_w + 1 + ket_w + ext_w] = '\0';
|
|
||||||
|
|
||||||
free(pre_c); free(ext_c);
|
|
||||||
u3z(pre); u3z(ext);
|
|
||||||
|
|
||||||
return pox_c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _unix_dir_watch(): instantiate directory tracker.
|
/* _unix_dir_watch(): instantiate directory tracker.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
@ -402,35 +326,6 @@ _unix_dir_watch(u3_udir* dir_u, u3_udir* par_u, c3_c* pax_c, c3_c* pot_c)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _unix_dir_forge: instantiate directory tracker (and make directory).
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
_unix_dir_forge(u3_udir* dir_u, u3_udir* par_u, u3_noun tet)
|
|
||||||
{
|
|
||||||
c3_c* tet_c = u3r_string(tet);
|
|
||||||
c3_w pax_w = strlen(par_u->pax_c);
|
|
||||||
c3_w tet_w = strlen(tet_c);
|
|
||||||
c3_c* pax_c = c3_malloc(pax_w + 1 + tet_w + 1);
|
|
||||||
c3_c* pot_c = c3_malloc(pax_w + 1 + 1 + tet_w + 1);
|
|
||||||
|
|
||||||
strncpy(pax_c, par_u->pax_c, pax_w + 1);
|
|
||||||
pax_c[pax_w] = '/';
|
|
||||||
strncpy(pax_c + pax_w + 1, tet_c, tet_w + 1);
|
|
||||||
pax_c[pax_w + tet_w + 1] = '\0';
|
|
||||||
|
|
||||||
strncpy(pot_c, par_u->pot_c, pax_w + 1 + 1);
|
|
||||||
pot_c[pax_w + 1] = '/';
|
|
||||||
strncpy(pot_c + pax_w + 1 + 1, tet_c, tet_w + 1);
|
|
||||||
pot_c[pax_w + 1 + tet_w + 1] = '\0';
|
|
||||||
|
|
||||||
free(tet_c);
|
|
||||||
u3z(tet);
|
|
||||||
|
|
||||||
_unix_mkdir(pax_c);
|
|
||||||
_unix_mkdir(pot_c);
|
|
||||||
_unix_dir_watch(dir_u, par_u, pax_c, pot_c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _unix_file_done(): finish freeing file.
|
/* _unix_file_done(): finish freeing file.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
@ -741,42 +636,6 @@ _unix_load(u3_ufil* fil_u)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unix_save(): save a file.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
_unix_save(c3_c* pax_c, u3_atom oat)
|
|
||||||
{
|
|
||||||
c3_c* dir = strdup(pax_c);
|
|
||||||
_unix_mkpath(dirname(dir));
|
|
||||||
free(dir);
|
|
||||||
|
|
||||||
c3_i fid_i = open(pax_c, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
|
||||||
c3_w fln_w, rit_w, siz_w;
|
|
||||||
c3_y* oat_y;
|
|
||||||
|
|
||||||
if ( fid_i < 0 ) {
|
|
||||||
uL(fprintf(uH, "error opening %s: %s\n", pax_c, strerror(errno)));
|
|
||||||
u3m_bail(c3__fail);
|
|
||||||
}
|
|
||||||
|
|
||||||
siz_w = u3h(u3t(oat));
|
|
||||||
fln_w = u3r_met(3, u3t(u3t(oat)));
|
|
||||||
oat_y = c3_malloc(siz_w);
|
|
||||||
memset(oat_y, 0, siz_w);
|
|
||||||
|
|
||||||
u3r_bytes(0, fln_w, oat_y, u3t(u3t(oat)));
|
|
||||||
u3z(oat);
|
|
||||||
|
|
||||||
rit_w = write(fid_i, oat_y, siz_w);
|
|
||||||
if ( rit_w != siz_w ) {
|
|
||||||
uL(fprintf(uH, "error writing %s: %s\n", pax_c, strerror(errno)));
|
|
||||||
c3_assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fid_i);
|
|
||||||
free(oat_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _unix_file_load(): load a file by watcher.
|
/* _unix_file_load(): load a file by watcher.
|
||||||
*/
|
*/
|
||||||
static u3_weak
|
static u3_weak
|
||||||
@ -1201,6 +1060,134 @@ _unix_hot_lose(u3_uhot* hot_u)
|
|||||||
_unix_dir_free(&(hot_u->dir_u));
|
_unix_dir_free(&(hot_u->dir_u));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* _unix_home(): find home directory from identity.
|
||||||
|
*/
|
||||||
|
static u3_uhot*
|
||||||
|
_unix_home(u3_noun who)
|
||||||
|
{
|
||||||
|
u3_unix* unx_u = &u3_Host.unx_u;
|
||||||
|
u3_uhot* hot_u;
|
||||||
|
c3_w who_w[4];
|
||||||
|
|
||||||
|
_unix_ship_out(who, who_w);
|
||||||
|
for ( hot_u = unx_u->hot_u;
|
||||||
|
hot_u && !_(_unix_ship_sing(who_w, hot_u->who_w));
|
||||||
|
hot_u = hot_u->nex_u )
|
||||||
|
{
|
||||||
|
// uL(fprintf(uH, "uh: %p, %s\n", hot_u, hot_u->dir_u.pax_c));
|
||||||
|
}
|
||||||
|
return hot_u;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ERGO_SYNC
|
||||||
|
/* _unix_mkpath(): mkdir -p, asserting
|
||||||
|
*
|
||||||
|
* adapted from
|
||||||
|
* http://niallohiggins.com/2009/01/08/mkpath-mkdir-p-alike-in-c-for-unix/
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_unix_mkpath(const char *s)
|
||||||
|
{
|
||||||
|
char *q, *r = NULL, *path = NULL, *up = NULL;
|
||||||
|
|
||||||
|
if (strcmp(s, ".") == 0 || strcmp(s, "/") == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((path = strdup(s)) == NULL)
|
||||||
|
c3_assert(0);
|
||||||
|
|
||||||
|
if ((q = strdup(s)) == NULL)
|
||||||
|
c3_assert(0);
|
||||||
|
|
||||||
|
if ((r = dirname(q)) == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if ((up = strdup(r)) == NULL)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
_unix_mkpath(up);
|
||||||
|
|
||||||
|
_unix_mkdir(path);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (up != NULL)
|
||||||
|
free(up);
|
||||||
|
free(q);
|
||||||
|
free(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* _unix_dir_forge: instantiate directory tracker (and make directory).
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_unix_dir_forge(u3_udir* dir_u, u3_udir* par_u, u3_noun tet)
|
||||||
|
{
|
||||||
|
c3_c* tet_c = u3r_string(tet);
|
||||||
|
c3_w pax_w = strlen(par_u->pax_c);
|
||||||
|
c3_w tet_w = strlen(tet_c);
|
||||||
|
c3_c* pax_c = c3_malloc(pax_w + 1 + tet_w + 1);
|
||||||
|
c3_c* pot_c = c3_malloc(pax_w + 1 + 1 + tet_w + 1);
|
||||||
|
|
||||||
|
strncpy(pax_c, par_u->pax_c, pax_w + 1);
|
||||||
|
pax_c[pax_w] = '/';
|
||||||
|
strncpy(pax_c + pax_w + 1, tet_c, tet_w + 1);
|
||||||
|
pax_c[pax_w + tet_w + 1] = '\0';
|
||||||
|
|
||||||
|
strncpy(pot_c, par_u->pot_c, pax_w + 1 + 1);
|
||||||
|
pot_c[pax_w + 1] = '/';
|
||||||
|
strncpy(pot_c + pax_w + 1 + 1, tet_c, tet_w + 1);
|
||||||
|
pot_c[pax_w + 1 + tet_w + 1] = '\0';
|
||||||
|
|
||||||
|
free(tet_c);
|
||||||
|
u3z(tet);
|
||||||
|
|
||||||
|
_unix_mkdir(pax_c);
|
||||||
|
_unix_mkdir(pot_c);
|
||||||
|
_unix_dir_watch(dir_u, par_u, pax_c, pot_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* _unix_file_form(): form a filename path downward.
|
||||||
|
*/
|
||||||
|
static c3_c*
|
||||||
|
_unix_file_form(c3_c* pax_c,
|
||||||
|
u3_noun pre,
|
||||||
|
u3_noun ket,
|
||||||
|
u3_noun ext)
|
||||||
|
{
|
||||||
|
c3_c* pre_c = u3r_string(pre);
|
||||||
|
c3_c* ext_c = u3r_string(ext);
|
||||||
|
c3_w pax_w = strlen(pax_c);
|
||||||
|
c3_w pre_w = strlen(pre_c);
|
||||||
|
c3_w ext_w = strlen(ext_c);
|
||||||
|
c3_w ket_w = (c3y == ket) ? 1 : 0;
|
||||||
|
c3_c* pox_c = c3_malloc(pax_w + 1 + pre_w + 1 + ket_w + ext_w + 1);
|
||||||
|
|
||||||
|
strncpy(pox_c, pax_c, pax_w);
|
||||||
|
pox_c[pax_w] = '/';
|
||||||
|
strncpy(pox_c + pax_w + 1, pre_c, pre_w);
|
||||||
|
pox_c[pax_w + 1 + pre_w] = '.';
|
||||||
|
if ( c3y == ket ) {
|
||||||
|
pox_c[pax_w + 1 + pre_w + 1] = '^';
|
||||||
|
}
|
||||||
|
strncpy(pox_c + pax_w + 1 + pre_w + 1 + ket_w, ext_c, ext_w);
|
||||||
|
pox_c[pax_w + 1 + pre_w + 1 + ket_w + ext_w] = '\0';
|
||||||
|
|
||||||
|
free(pre_c); free(ext_c);
|
||||||
|
u3z(pre); u3z(ext);
|
||||||
|
|
||||||
|
return pox_c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* _unix_unlink(): unlink, asserting.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_unix_unlink(c3_c* pax_c)
|
||||||
|
{
|
||||||
|
if ( 0 != unlink(pax_c) && ENOENT != errno ) {
|
||||||
|
uL(fprintf(uH, "error unlinking %s: %s\n", pax_c, strerror(errno)));
|
||||||
|
c3_assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* _unix_pdir(): find directory reference from text.
|
/* _unix_pdir(): find directory reference from text.
|
||||||
*/
|
*/
|
||||||
static u3_udir**
|
static u3_udir**
|
||||||
@ -1221,34 +1208,41 @@ _unix_pdir(u3_udir* par_u, u3_noun tet)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _unix_home(): find home directory from identity.
|
/* unix_save(): save a file.
|
||||||
*/
|
*/
|
||||||
static u3_uhot*
|
static void
|
||||||
_unix_home(u3_noun who)
|
_unix_save(c3_c* pax_c, u3_atom oat)
|
||||||
{
|
{
|
||||||
u3_unix* unx_u = &u3_Host.unx_u;
|
c3_c* dir = strdup(pax_c);
|
||||||
u3_uhot* hot_u;
|
_unix_mkpath(dirname(dir));
|
||||||
c3_w who_w[4];
|
free(dir);
|
||||||
|
|
||||||
_unix_ship_out(who, who_w);
|
c3_i fid_i = open(pax_c, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||||
for ( hot_u = unx_u->hot_u;
|
c3_w fln_w, rit_w, siz_w;
|
||||||
hot_u && !_(_unix_ship_sing(who_w, hot_u->who_w));
|
c3_y* oat_y;
|
||||||
hot_u = hot_u->nex_u )
|
|
||||||
{
|
if ( fid_i < 0 ) {
|
||||||
// uL(fprintf(uH, "uh: %p, %s\n", hot_u, hot_u->dir_u.pax_c));
|
uL(fprintf(uH, "error opening %s: %s\n", pax_c, strerror(errno)));
|
||||||
|
u3m_bail(c3__fail);
|
||||||
}
|
}
|
||||||
return hot_u;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
siz_w = u3h(u3t(oat));
|
||||||
/* _unix_desk_sync_udon(): apply udon to existing value.
|
fln_w = u3r_met(3, u3t(u3t(oat)));
|
||||||
*/
|
oat_y = c3_malloc(siz_w);
|
||||||
static u3_noun
|
memset(oat_y, 0, siz_w);
|
||||||
_unix_desk_sync_udon(u3_noun don, u3_noun old)
|
|
||||||
{
|
u3r_bytes(0, fln_w, oat_y, u3t(u3t(oat)));
|
||||||
return u3dc("lump", don, old);
|
u3z(oat);
|
||||||
|
|
||||||
|
rit_w = write(fid_i, oat_y, siz_w);
|
||||||
|
if ( rit_w != siz_w ) {
|
||||||
|
uL(fprintf(uH, "error writing %s: %s\n", pax_c, strerror(errno)));
|
||||||
|
c3_assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fid_i);
|
||||||
|
free(oat_y);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* _unix_desk_sync_tofu(): sync out file install.
|
/* _unix_desk_sync_tofu(): sync out file install.
|
||||||
*/
|
*/
|
||||||
@ -1420,6 +1414,7 @@ _unix_desk_sync_list(u3_udir* dir_u, u3_noun can)
|
|||||||
|
|
||||||
u3z(can);
|
u3z(can);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* _unix_desk_sync_ergo(): sync desk changes to unix.
|
/* _unix_desk_sync_ergo(): sync desk changes to unix.
|
||||||
*/
|
*/
|
||||||
@ -1430,11 +1425,11 @@ _unix_desk_sync_ergo(u3_noun hox,
|
|||||||
u3_noun can,
|
u3_noun can,
|
||||||
u3_uhot* hot_u)
|
u3_uhot* hot_u)
|
||||||
{
|
{
|
||||||
#if 0
|
#ifndef ERGO_SYNC
|
||||||
u3z(hox); u3z(syd); u3z(lok); u3z(can);
|
u3z(hox); u3z(syd); u3z(lok); u3z(can);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
u3_udir** dir_u = _unix_pdir(&(hot_u->dir_u), syd);
|
u3_udir** dir_u = _unix_pdir(&(hot_u->dir_u), u3k(syd));
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
uL(fprintf(uH, "ergo %s %s %s\n", u3r_string(hox),
|
uL(fprintf(uH, "ergo %s %s %s\n", u3r_string(hox),
|
||||||
|
Loading…
Reference in New Issue
Block a user