X-Git-Url: https://jxself.org/git/?p=8sync.git;a=blobdiff_plain;f=demos%2Firc.scm;h=a5e9ba4426fb6e9f1e5c5a0b0b8d558584a3f561;hp=84b5528dbfc2e3111b4c2cf5a058c253fc05d7fe;hb=9c8d37765bca38ffe643434ca154999f8e602a6a;hpb=1827de0c8d77d5a238b68ded544c4fcc5085fd8d diff --git a/demos/irc.scm b/demos/irc.scm index 84b5528..a5e9ba4 100755 --- a/demos/irc.scm +++ b/demos/irc.scm @@ -65,7 +65,7 @@ (display (irc-line dest)))) (define* (handle-login socket username - #:optional + #:key (hostname "*") (servername "*") (realname username) @@ -78,11 +78,57 @@ (irc-format socket "JOIN ~a" channel)) channels)) -(define (handle-line socket line) - (display line) - (newline)) - -(define (make-simple-irc-handler handle-line) +(define (startswith-colon? str) + (and (> (string-length str) 0) + (eq? (string-ref str 0) + #\:))) + +(define (parse-line line) + (define (parse-params pre-params) + ;; This is stupid and imperative but I can't wrap my brain around + ;; the right way to do it in a functional way :\ + (let ((param-list '()) + (currently-building '())) + (for-each + (lambda (param-item) + (cond + ((startswith-colon? param-item) + (if (not (eq? currently-building '())) + (set! param-list + (cons + (reverse currently-building) + param-list))) + (set! currently-building (list param-item))) + (else + (set! currently-building (cons param-item currently-building))))) + pre-params) + ;; We're still building something, so tack that on there + (if (not (eq? currently-building '())) + (set! param-list + (cons (reverse currently-building) param-list))) + ;; return the reverse of the param list + (reverse param-list))) + + (match (string-split line #\space) + (((? startswith-colon? prefix) + command + pre-params ...) + (list prefix command + (parse-params2 pre-params))) + ((command pre-params ...) + (list #f command (parse-params2 pre-params))))) + + +(define (handle-line socket line my-username) + (match (string-split line #\space) + (("PING" rest ...) + (irc-display "PONG" socket) + (display "PONG'ed back ;)\n")) + (_ + (display line) + (newline)))) + +(define (make-simple-irc-handler handle-line username) (let ((buffer '())) (define (reset-buffer) (set! buffer '())) @@ -95,7 +141,8 @@ ((#\newline #\return (? char? line-chars) ...) (%sync (%run (handle-line socket - (list->string (reverse line-chars))))) + (list->string (reverse line-chars)) + username))) ;; reset buffer (set! buffer '())) (_ #f)))) @@ -104,7 +151,10 @@ (define* (queue-and-start-irc-agenda! agenda socket #:key (username "syncbot") (inet-port default-irc-port) - (handler (make-simple-irc-handler handle-line)) + (handler (make-simple-irc-handler + (lambda args + (apply handle-line args)) + username)) (channels '())) (dynamic-wind (lambda () #f) @@ -130,6 +180,7 @@ ,(lambda (s) (if (string->number s) #t #f)))) (username (single-char #\u) (required? #t) (value #t)) + (channels (value #t)) (listen))) (define (main args) @@ -138,13 +189,17 @@ (port (or (option-ref options 'port #f) default-irc-port)) (username (option-ref options 'username #f)) - (listen (option-ref options 'listen #f))) + (listen (option-ref options 'listen #f)) + (channels (option-ref options 'channels "")) + (agenda (make-agenda))) (display `((server ,hostname) (port ,port) (username ,username) - (listen ,listen))) + (listen ,listen) (channels-split ,(string-split channels #\space)))) (newline) + (if listen + (spawn-and-queue-repl-server! agenda)) (queue-and-start-irc-agenda! - (make-agenda) + agenda (irc-socket-setup hostname port) #:inet-port port #:username username - #:handler (make-simple-irc-handler handle-line)))) + #:channels (string-split channels #\space))))