From 2cda6db1306ab00a4f61209691bdfe32871df867 Mon Sep 17 00:00:00 2001 From: Alex Shinn Date: Mon, 23 May 2011 03:31:24 -0700 Subject: [PATCH] More documentation. --- lib/chibi/net.scm | 16 ++++++++++++-- lib/chibi/net.stub | 24 ++++++++++++++++++-- lib/chibi/pathname.module | 2 +- lib/chibi/pathname.scm | 36 ++++++++++++++++++++++++++++-- lib/chibi/time.stub | 26 ++++++++++++++++++++++ lib/chibi/type-inference.scm | 15 ++++++++++--- lib/chibi/uri.scm | 43 ++++++++++++++++++++++++++++++++---- lib/chibi/weak.module | 2 ++ 8 files changed, 150 insertions(+), 14 deletions(-) diff --git a/lib/chibi/net.scm b/lib/chibi/net.scm index 4235c2e4..65998bde 100644 --- a/lib/chibi/net.scm +++ b/lib/chibi/net.scm @@ -1,7 +1,12 @@ -;; net.scm -- the high-level network interface -;; Copyright (c) 2010 Alex Shinn. All rights reserved. +;; Copyright (c) 2010-2011 Alex Shinn. All rights reserved. ;; BSD-style license: http://synthcode.com/license.txt +;;> Opens a client net connection to @var{host}, a string, +;;> on port @var{service}, which can be a string such as +;;> @scheme{"http"} or an integer. Returns a list of two +;;> values on success - an input port and output port - +;;> or @scheme{#f} on failure. + (define (open-net-io host service) (let lp ((addr (get-address-info host (if (integer? service) @@ -28,6 +33,13 @@ (list (open-input-file-descriptor sock) (open-output-file-descriptor sock))))))))) +;;> Convenience wrapper around @scheme{open-net-io}, opens +;;> the connection then calls @var{proc} with two arguments, +;;> the input port and the output port connected to the +;;> service, then closes the connection. Returns the result +;;> of @var{proc}. Raises an error if a connection can't +;;> be made. + (define (with-net-io host service proc) (let ((io (open-net-io host service))) (if (not (pair? io)) diff --git a/lib/chibi/net.stub b/lib/chibi/net.stub index f52209df..70109cf9 100644 --- a/lib/chibi/net.stub +++ b/lib/chibi/net.stub @@ -16,11 +16,31 @@ (size_t ai_addrlen address-info-address-length) ((link addrinfo) ai_next address-info-next)) +;;> The addrinfo struct accessors. +;;/ + +;;> Create and return a new addrinfo structure for the +;;> given host and service. + (define-c errno (get-address-info getaddrinfo) (string string (maybe-null addrinfo) (result free addrinfo))) +;;> Bind a name to a socket. + (define-c int bind (int sockaddr int)) + +;;> Listen on a socket. + (define-c int listen (int int)) -(define-c int socket (int int int)) -(define-c int connect (int sockaddr int)) + +;;> Accept a connection on a socket. + (define-c int accept (int sockaddr (pointer unsigned))) + +;;> Create an endpoint for communication. + +(define-c int socket (int int int)) + +;;> Initiate a connection on a socket. + +(define-c int connect (int sockaddr int)) diff --git a/lib/chibi/pathname.module b/lib/chibi/pathname.module index 1f4ffbf2..931167fc 100644 --- a/lib/chibi/pathname.module +++ b/lib/chibi/pathname.module @@ -1,6 +1,6 @@ (module (chibi pathname) - (export path-strip-directory path-directory path-extension-pos + (export path-strip-directory path-directory ;; path-extension-pos path-extension path-strip-extension path-replace-extension path-absolute? path-relative? path-normalize make-path) (import-immutable (scheme)) diff --git a/lib/chibi/pathname.scm b/lib/chibi/pathname.scm index de27ad61..ca5c66e2 100644 --- a/lib/chibi/pathname.scm +++ b/lib/chibi/pathname.scm @@ -1,7 +1,8 @@ -;; pathname.scm -- a general, non-host-specific path lib -;; Copyright (c) 2009 Alex Shinn. All rights reserved. +;; Copyright (c) 2009-2011 Alex Shinn. All rights reserved. ;; BSD-style license: http://synthcode.com/license.txt +;;> A general, non-host-specific pathname library. + (define (string-scan c str . o) (let ((limit (string-length str))) (let lp ((i (if (pair? o) (car o) 0))) @@ -38,6 +39,11 @@ ;; (let ((start (string-scan-right #\/ path (- end 1)))) ;; (substring path (if start (+ start 1) 0) (+ end 1))))))) +;;> Returns just the basename of @var{path}, with any directory +;;> removed. If @var{path} does not contain a directory separator, +;;> return the whole @var{path}. If @var{path} ends in a directory +;;> separator (i.e. path is a directory) return the empty string. + ;; GNU basename (define (path-strip-directory path) (if (string=? path "") @@ -50,6 +56,9 @@ path (substring path (+ slash 1) len))))))) +;;> Returns just the directory of @var{path}. +;;> If @var{path} is relative, return @scheme{"."}. + (define (path-directory path) (if (string=? path "") "." @@ -64,30 +73,50 @@ (define (path-extension-pos path) (string-scan-right #\. path)) +;;> Returns the rightmost extension of @var{path}, not including +;;> the @scheme{"."}. If there is no extension, returns @scheme{#f}. + (define (path-extension path) (let ((i (path-extension-pos path))) (and i (let ((start (+ i 1)) (end (string-length path))) (and (< start end) (substring path start end)))))) +;;> Returns @var{path} with the extension, if any, removed, +;;> along with the @scheme{"."}. + (define (path-strip-extension path) (let ((i (path-extension-pos path))) (if (and i (< (+ i 1) (string-length path))) (substring path 0 i) path))) +;;> Returns @var{path} with the extension, if any, replaced +;;> with @var{ext}. + (define (path-replace-extension path ext) (string-append (path-strip-extension path) "." ext)) +;;> Returns @scheme{#t} iff @var{path} is an absolute path. + (define (path-absolute? path) (and (not (string=? "" path)) (eqv? #\/ (string-ref path 0)))) +;;> Returns @scheme{#t} iff @var{path} is a relative path. + (define (path-relative? path) (not (path-absolute? path))) ;; This looks big and hairy, but it's mutation-free and guarantees: ;; (string=? s (path-normalize s)) <=> (eq? s (path-normalize s)) ;; i.e. fast and simple for already normalized paths. +;;> Returns a normalized version of path, with duplicate directory +;;> separators removed and "/./" and "x/../" references removed. +;;> Does not take symbolic links into account - this is meant to +;;> be abstract and applicable to paths on remote systems and in +;;> URIs. Returns @var{path} itself if @var{path} is already +;;> normalized. + (define (path-normalize path) (let* ((len (string-length path)) (len-1 (- len 1))) (define (collect i j res) @@ -155,6 +184,9 @@ path ((if (eqv? #\/ (string-ref path 0)) boundary inside) 0 1 '())))) +;;> Return a new string representing the path where each of @var{args} +;;> is a path component, separated with the directory separator. + (define (make-path . args) (define (x->string x) (cond ((string? x) x) diff --git a/lib/chibi/time.stub b/lib/chibi/time.stub index adde486e..88a192c9 100644 --- a/lib/chibi/time.stub +++ b/lib/chibi/time.stub @@ -14,33 +14,59 @@ (int tm_yday time-day-of-year) (int tm_isdst time-dst?)) +;;> Accessors for the @scheme{tm} struct. +;;/ + (define-c-struct timeval predicate: timeval? (time_t tv_sec timeval-seconds) (int tv_usec timeval-microseconds)) +;;> Accessors for the @scheme{timeval} struct. +;;/ + (define-c-struct timezone predicate: timezone? (int tz_minuteswest timezone-offset) (int tz_dsttime timezone-dst-time)) +;;> Accessors for the @scheme{timezone} struct. +;;/ + +;;> Returns the current time as an integer number +;;> of seconds since an arbitrary epoch. + (define-c time_t (current-seconds "time") ((value NULL))) +;;> Returns the current time as a list of a timeval struct +;;> and a timezone. + (define-c errno (get-time-of-day "gettimeofday") ((result timeval) (result timezone))) +;;> Set the current time from a timeval struct and +;;> and optional timezone. + (define-c errno (set-time-of-day! "settimeofday") (timeval (maybe-null default NULL timezone))) +;;> Convert an integer number of epoch seconds to a broken-down tm struct. + (define-c non-null-pointer (seconds->time "localtime_r") ((pointer time_t) (result tm))) +;;> Convert a tm struct to an integer number of seconds. + (define-c time_t (time->seconds "mktime") (tm)) +;;> Format a datetime string from an integer number of epoch seconds. + (define-c non-null-string (seconds->string "ctime_r") ((pointer time_t) (result (array char 64)))) +;;> Format a datetime string from a tm struct. + (define-c non-null-string (time->string "asctime_r") (tm (result (array char 64)))) diff --git a/lib/chibi/type-inference.scm b/lib/chibi/type-inference.scm index d7aaa444..70a07d8f 100755 --- a/lib/chibi/type-inference.scm +++ b/lib/chibi/type-inference.scm @@ -1,8 +1,8 @@ -;; type-inference.scm -- general type-inference for Scheme -;; -;; Copyright (c) 2010 Alex Shinn. All rights reserved. +;; Copyright (c) 2010-2011 Alex Shinn. All rights reserved. ;; BSD-style license: http://synthcode.com/license.txt +;;> General type-inference library. + (define (typed? x) (and (lambda? x) (lambda-return-type x))) @@ -226,6 +226,8 @@ (for-each type-analyze-expr ls) (for-each type-resolve-circularities ls)) +;;> Analyze the types of all bindings in the module @var{name}. + (define (type-analyze-module name) (let* ((mod (analyze-module name)) (ls (and (vector? mod) (module-ast mod)))) @@ -240,6 +242,9 @@ (type-analyze-module-body name ls)) ls)))) +;;> Return the type signature for a given source +;;> code expression. + (define (type-analyze sexp . o) (type-analyze-expr (apply analyze sexp o))) @@ -255,6 +260,10 @@ (define (lambda-type x) (cons 'lambda (cons (lambda-return-type x) (lambda-param-types x)))) +;;> Return the type signature for the procedure @var{x} as +;;> a list whose first element is the return type and whose +;;> remaining arguments are the parameter types. + (define (procedure-signature x) (cond ((opcode? x) diff --git a/lib/chibi/uri.scm b/lib/chibi/uri.scm index 41507961..5a048588 100644 --- a/lib/chibi/uri.scm +++ b/lib/chibi/uri.scm @@ -1,7 +1,8 @@ -;; uri.scm -- URI parsing library -;; Copyright (c) 2009 Alex Shinn. All rights reserved. +;; Copyright (c) 2009-2011 Alex Shinn. All rights reserved. ;; BSD-style license: http://synthcode.com/license.txt +;;> Library for parsing and constructing URI objects. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; URI representation @@ -16,7 +17,11 @@ (query uri-query) (fragment uri-fragment)) -;; (make-uri scheme [user host port path query fragment]) +;;> Accessors for the URI type. +;;/ + +;;> @subsubsubsection{@scheme{(make-uri scheme [user host port path query fragment])}} + (define (make-uri scheme . o) (let* ((user (if (pair? o) (car o) #f)) (o (if (pair? o) (cdr o) '())) @@ -81,7 +86,6 @@ (lp (+ i 1))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; functional updaters (uses as much shared state as possible) (define (uri-with-scheme u scheme) (%make-uri scheme (uri-user u) (uri-host u) (uri-port u) @@ -111,6 +115,10 @@ (%make-uri (uri-scheme u) (uri-user u) (uri-host u) (uri-port u) (uri-path u) (uri-query u) fragment)) +;;> Functional updaters - returns a new uri identical to @var{u} +;;> with only the specified field changed. +;;/ + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; parsing - without :// we just split into scheme & path @@ -181,9 +189,13 @@ (decode (substring str (+ pound 1) len))) )))))))))) +;;> Parses a string and returns a new URI object. + (define (string->uri str . o) (apply string->path-uri #f str o)) +;;> Convert a URI object to a string. + (define (uri->string uri . o) (define encode? (and (pair? o) (car o))) (define encode (if encode? uri-encode (lambda (x) x))) @@ -221,6 +233,12 @@ res (cons (substring str from to) res))) +;;> @subsubsubsection{@scheme{(uri-encode str [plus?])}} + +;;> Return the URI encoded version of the string @var{str}, +;;> using hex escapes as needed and replacing spaces with "+" +;;> iff the optional argument @var{plus?} is true. + (define (uri-encode str . o) (define (encode-1-space ch) (if (eqv? ch #\space) @@ -249,6 +267,12 @@ (lp next next (cons (encode-1 ch) (collect str from to res))))))))) +;;> @subsubsubsection{@scheme{(uri-decode str [plus?])}} + +;;> Decodes any URI hex escapes in the given string, and +;;> translates any pluses ("+") to space iff the optional +;;> argument @var{plus?} is true. + (define (uri-decode str . o) (let ((space-as-plus? (and (pair? o) (car o))) (start 0) @@ -277,6 +301,12 @@ (else (lp from next res)))))))) +;;> @subsubsubsection{@scheme{(uri-query->alist str [plus?])}} + +;;> Parses the query part of a URI as a delimited list of +;;> URI encoded @rawcode{VAR=VALUE} pairs, decodes them and +;;> returns the result as an alist. + (define (uri-query->alist str . o) (define (split-char? c) (if (eqv? c #\&) #t (eqv? c #\;))) (let ((len (string-length str)) @@ -292,6 +322,11 @@ (cons (uri-decode (substring str i j) plus?) #f)))) (lp (+ j 1) (cons cell res))))))) +;;> @subsubsubsection{@scheme{(uri-alist->query ls [plus?])}} + +;;> The reverse of the above, formats the alist as a URI +;;> query string. + (define (uri-alist->query ls . o) (define plus? (and (pair? o) (car o))) (define (encode key val res) diff --git a/lib/chibi/weak.module b/lib/chibi/weak.module index 4471790f..2d43627f 100644 --- a/lib/chibi/weak.module +++ b/lib/chibi/weak.module @@ -1,4 +1,6 @@ +;;> Library for weak data structures. + (module (chibi weak) (export make-ephemeron ephemeron? ephemeron-broken? ephemeron-key ephemeron-value