]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' of git://factorcode.org/git/factor
authorDaniel Ehrenberg <ehrenbed@carleton.edu>
Tue, 18 Mar 2008 21:02:48 +0000 (17:02 -0400)
committerDaniel Ehrenberg <ehrenbed@carleton.edu>
Tue, 18 Mar 2008 21:02:48 +0000 (17:02 -0400)
130 files changed:
core/alien/alien-docs.factor
core/alien/alien.factor
core/alien/c-types/c-types.factor
core/bootstrap/stage1.factor
core/continuations/continuations-docs.factor
core/debugger/debugger.factor
core/definitions/definitions-tests.factor
core/generic/generic-docs.factor
core/generic/generic.factor
core/generic/math/math.factor
core/generic/standard/standard.factor
core/io/files/files-tests.factor
core/io/files/files.factor
core/io/io.factor
core/kernel/kernel-docs.factor
core/optimizer/specializers/specializers.factor
core/parser/parser.factor
core/slots/slots.factor
core/syntax/syntax.factor
core/threads/threads-tests.factor
core/threads/threads.factor
core/tuples/tuples-docs.factor
core/words/words.factor
extra/assocs/lib/lib.factor
extra/bootstrap/tools/tools.factor
extra/builder/benchmark/benchmark.factor
extra/builder/builder.factor
extra/cairo-demo/cairo-demo.factor
extra/cairo/authors.txt
extra/cairo/cairo.factor [deleted file]
extra/cairo/ffi/ffi.factor [new file with mode: 0644]
extra/cairo/lib/lib.factor [new file with mode: 0644]
extra/cairo/png/png.factor [new file with mode: 0644]
extra/combinators/cleave/cleave.factor
extra/db/db-tests.factor [new file with mode: 0755]
extra/db/db.factor
extra/db/postgresql/lib/lib.factor
extra/db/postgresql/postgresql.factor
extra/db/sqlite/ffi/ffi.factor
extra/db/sqlite/lib/lib.factor
extra/db/sqlite/sqlite.factor
extra/db/tuples/tuples-tests.factor
extra/db/tuples/tuples.factor
extra/db/types/types.factor
extra/delegate/delegate.factor
extra/destructors/destructors.factor
extra/hello-world/deploy.factor
extra/help/help-tests.factor [new file with mode: 0644]
extra/help/help.factor
extra/http/client/client-tests.factor
extra/http/http-tests.factor
extra/http/http.factor
extra/http/server/actions/actions-tests.factor
extra/http/server/actions/actions.factor
extra/http/server/auth/auth.factor
extra/http/server/auth/login/edit-profile.fhtml [new file with mode: 0755]
extra/http/server/auth/login/login.factor
extra/http/server/auth/login/recover-3.fhtml
extra/http/server/auth/login/register.fhtml
extra/http/server/auth/providers/assoc/assoc-tests.factor
extra/http/server/auth/providers/assoc/assoc.factor
extra/http/server/auth/providers/db/db-tests.factor
extra/http/server/auth/providers/db/db.factor
extra/http/server/auth/providers/null/null.factor
extra/http/server/auth/providers/providers.factor
extra/http/server/callbacks/callbacks.factor
extra/http/server/components/components-tests.factor
extra/http/server/components/components.factor
extra/http/server/server.factor
extra/http/server/sessions/sessions-tests.factor
extra/http/server/sessions/sessions.factor
extra/http/server/sessions/storage/assoc/assoc.factor [new file with mode: 0755]
extra/http/server/sessions/storage/db/db-tests.factor [new file with mode: 0755]
extra/http/server/sessions/storage/db/db.factor [new file with mode: 0755]
extra/http/server/sessions/storage/storage.factor [new file with mode: 0755]
extra/http/server/validators/validators-tests.factor
extra/http/server/validators/validators.factor
extra/io/unix/launcher/launcher-tests.factor [changed mode: 0644->0755]
extra/io/unix/unix.factor
extra/io/windows/files/files.factor
extra/io/windows/nt/nt.factor
extra/io/windows/windows.factor
extra/ldap/libldap/libldap.factor
extra/locals/locals-tests.factor
extra/locals/locals.factor
extra/logging/logging.factor
extra/logging/server/server.factor
extra/memoize/memoize.factor
extra/multiline/multiline.factor
extra/namespaces/lib/lib-tests.factor [new file with mode: 0755]
extra/namespaces/lib/lib.factor [changed mode: 0644->0755]
extra/opengl/gl/gl-docs.factor [new file with mode: 0644]
extra/opengl/opengl-docs.factor
extra/opengl/opengl.factor
extra/openssl/libcrypto/libcrypto.factor
extra/openssl/libssl/libssl.factor [changed mode: 0644->0755]
extra/openssl/openssl-tests.factor
extra/pdf/authors.txt [deleted file]
extra/pdf/libhpdf/libhpdf.factor [deleted file]
extra/pdf/pdf-tests.factor [deleted file]
extra/pdf/pdf.factor [deleted file]
extra/pdf/readme.txt [deleted file]
extra/promises/promises.factor
extra/reports/noise/noise.factor [new file with mode: 0755]
extra/reports/optimizer/optimizer.factor [new file with mode: 0755]
extra/sequences/lib/lib-tests.factor
extra/sequences/lib/lib.factor
extra/serialize/serialize-tests.factor
extra/serialize/serialize.factor
extra/sudoku/deploy.factor
extra/symbols/symbols-tests.factor [changed mode: 0644->0755]
extra/symbols/symbols.factor [changed mode: 0644->0755]
extra/tools/deploy/backend/backend.factor
extra/tools/deploy/deploy-tests.factor
extra/tools/deploy/shaker/shaker.factor
extra/tools/walker/debug/debug.factor
extra/tools/walker/walker.factor
extra/ui/freetype/freetype.factor
extra/ui/tools/walker/walker.factor
extra/ui/windows/windows.factor
extra/unicode/data/data.factor
extra/windows/user32/user32.factor
misc/factor.el
unmaintained/pdf/authors.txt [new file with mode: 0644]
unmaintained/pdf/libhpdf/libhpdf.factor [new file with mode: 0644]
unmaintained/pdf/pdf-tests.factor [new file with mode: 0755]
unmaintained/pdf/pdf.factor [new file with mode: 0644]
unmaintained/pdf/readme.txt [new file with mode: 0644]
vm/code_gc.c
vm/data_gc.h

index 475cf72d28b3a0709c785fc08681f347ffd7ac46..95b29ee50b2ba1596618bfba18c508ae61d9e5b3 100755 (executable)
@@ -65,8 +65,7 @@ HELP: dlclose ( dll -- )
 
 HELP: load-library
 { $values { "name" "a string" } { "dll" "a DLL handle" } }
-{ $description "Loads a library by logical name and outputs a handle which may be passed to " { $link dlsym } " or " { $link dlclose } ". If the library is already loaded, returns the existing handle." }
-{ $errors "Throws an error if the library could not be found, or if loading fails for some other reason." } ;
+{ $description "Loads a library by logical name and outputs a handle which may be passed to " { $link dlsym } " or " { $link dlclose } ". If the library is already loaded, returns the existing handle." } ;
 
 HELP: add-library
 { $values { "name" "a string" } { "path" "a string" } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } }
index 0369d55fb3b059fff31c95d746844c9beced221d..bce2e16d734a60cb197a1ae03ea4956dbcb6e420 100755 (executable)
@@ -57,7 +57,7 @@ TUPLE: library path abi dll ;
     over dup [ dlopen ] when \ library construct-boa ;
 
 : load-library ( name -- dll )
-    library library-dll ;
+    library dup [ library-dll ] when ;
 
 : add-library ( name path abi -- )
     <library> swap libraries get set-at ;
index c3f5c64b29d2e5ffc09633ba012ae1bf3fe2d880..f1d8abdc1ebbbea9033126a4a40ff1df6330eeb5 100755 (executable)
@@ -262,8 +262,8 @@ M: long-long-type box-return ( type -- )
         r> add*
     ] when ;
 
-: malloc-file-contents ( path -- alien )
-    binary file-contents malloc-byte-array ;
+: malloc-file-contents ( path -- alien len )
+    binary file-contents dup malloc-byte-array swap length ;
 
 [
     [ alien-cell ]
index 0e038d0a10d8ea3e67534faea5ad39ee9b8e3d00..74b4d03cbb62a250f7bacf28e097edab76068afd 100755 (executable)
@@ -47,6 +47,7 @@ vocabs.loader system debugger continuations ;
                 "listener" vocab
                 [ restarts. vocab-main execute ]
                 [ die ] if*
+                1 exit
             ] recover
         ] [
             "Cannot find " write write "." print
index 81063031f9a4e7e7c13eaea0c65ce7ea58c45488..7209b7ec4d6f555c3a6dc74e3ff5fbd87a6b41ab 100755 (executable)
@@ -29,7 +29,9 @@ $nl
 { $subsection ignore-errors }
 "Unhandled errors are reported in the listener and can be debugged using various tools. See " { $link "debugger" } "."
 { $subsection "errors-restartable" }
-{ $subsection "errors-post-mortem" } ;
+{ $subsection "errors-post-mortem" }
+"When Factor encouters a critical error, it calls the following word:"
+{ $subsection die } ;
 
 ARTICLE: "continuations.private" "Continuation implementation details"
 "A continuation is simply a tuple holding the contents of the five stacks:"
index 40bcbe78b1bb06402f2f63e8c6a58a8c7cc39977..ad2fa149549eeeb84469418ca39cb7e42b9c14a2 100755 (executable)
@@ -214,7 +214,7 @@ M: check-closed summary
     drop "Attempt to perform I/O on closed stream" ;
 
 M: check-method summary
-    drop "Invalid parameters for define-method" ;
+    drop "Invalid parameters for create-method" ;
 
 M: check-tuple summary
     drop "Invalid class for define-constructor" ;
index 4e8fb255ddead832ca0391cecc0b909e4b4d2774..ebbce4d7e2cdea49655344b940e57e18179734fe 100755 (executable)
@@ -1,10 +1,10 @@
 IN: definitions.tests
 USING: tools.test generic kernel definitions sequences
-compiler.units ;
+compiler.units words ;
 
 TUPLE: combination-1 ;
 
-M: combination-1 perform-combination 2drop { } [ ] each [ ] ;
+M: combination-1 perform-combination 2drop [ ] ;
 
 M: combination-1 make-default-method 2drop [ "No method" throw ] ;
 
@@ -13,7 +13,7 @@ SYMBOL: generic-1
 [
     generic-1 T{ combination-1 } define-generic
 
-    [ ] object \ generic-1 define-method
+    object \ generic-1 create-method [ ] define
 ] with-compilation-unit
 
 [ ] [
index 9b799d9143668c09ba1b44a93b2026ae57aa4e1a..62b85dde3a36b7dc3c9a0f2edb95efb5cebdb8b8 100755 (executable)
@@ -34,7 +34,7 @@ $nl
 { $subsection define-generic }
 { $subsection define-simple-generic }
 "Methods can be added to existing generic words:"
-{ $subsection define-method }
+{ $subsection create-method }
 "Method definitions can be looked up:"
 { $subsection method }
 { $subsection methods }
@@ -123,7 +123,7 @@ HELP: method
 { $values { "class" class } { "generic" generic } { "method/f" "a " { $link method-body } " or " { $link f } } }
 { $description "Looks up a method definition." } ;
 
-{ method define-method POSTPONE: M: } related-words
+{ method create-method POSTPONE: M: } related-words
 
 HELP: <method>
 { $values { "quot" quotation } { "class" class } { "generic" generic } { "method" "a new method definition" } }
@@ -140,16 +140,17 @@ HELP: order
 HELP: check-method
 { $values { "class" class } { "generic" generic } }
 { $description "Asserts that " { $snippet "class" } " is a class word and " { $snippet "generic" } " is a generic word, throwing a " { $link check-method } " error if the assertion fails." }
-{ $error-description "Thrown if " { $link POSTPONE: M: } " or " { $link define-method } " is given an invalid class or generic word." } ;
+{ $error-description "Thrown if " { $link POSTPONE: M: } " or " { $link create-method } " is given an invalid class or generic word." } ;
 
 HELP: with-methods
 { $values { "word" generic } { "quot" "a quotation with stack effect " { $snippet "( methods -- )" } } }
 { $description "Applies a quotation to the generic word's methods hashtable, and regenerates the generic word's definition when the quotation returns." }
 $low-level-note ;
 
-HELP: define-method
-{ $values { "quot" quotation } { "class" class } { "generic" generic } }
-{ $description "Defines a method. This is the runtime equivalent of " { $link POSTPONE: M: } "." } ;
+HELP: create-method
+{ $values { "class" class } { "generic" generic } { "method" method-body } }
+{ $description "Creates a method or returns an existing one. This is the runtime equivalent of " { $link POSTPONE: M: } "." }
+{ $notes "To define a method, pass the output value to " { $link define } "." } ;
 
 HELP: implementors
 { $values { "class" class } { "seq" "a sequence of generic words" } }
index 3c83b87d49982eba8980cab48d000ec2f5a658d1..ad31831e9481b512a40b6b23bcd4c5738049234b 100755 (executable)
@@ -17,10 +17,6 @@ M: object perform-combination
     #! the method will throw an error. We don't want that.
     nip [ "Invalid method combination" throw ] curry [ ] like ;
 
-GENERIC: method-prologue ( class combination -- quot )
-
-M: object method-prologue 2drop [ ] ;
-
 GENERIC: make-default-method ( generic combination -- method )
 
 PREDICATE: word generic "combination" word-prop >boolean ;
@@ -50,55 +46,49 @@ TUPLE: check-method class generic ;
 : check-method ( class generic -- class generic )
     over class? over generic? and [
         \ check-method construct-boa throw
-    ] unless ;
+    ] unless ; inline
 
-: with-methods ( word quot -- )
+: with-methods ( generic quot -- )
     swap [ "methods" word-prop swap call ] keep make-generic ;
     inline
 
 : method-word-name ( class word -- string )
     word-name "/" rot word-name 3append ;
 
-: make-method-def ( quot class generic -- quot )
-    "combination" word-prop method-prologue swap append ;
-
-PREDICATE: word method-body "method-def" word-prop >boolean ;
+PREDICATE: word method-body
+    "method-generic" word-prop >boolean ;
 
 M: method-body stack-effect
     "method-generic" word-prop stack-effect ;
 
-: method-word-props ( quot class generic -- assoc )
+: method-word-props ( class generic -- assoc )
     [
         "method-generic" set
         "method-class" set
-        "method-def" set
     ] H{ } make-assoc ;
 
-: <method> ( quot class generic -- method )
+: <method> ( class generic -- method )
     check-method
-    [ make-method-def ] 3keep
     [ method-word-props ] 2keep
     method-word-name f <word>
-    tuck set-word-props
-    dup rot define ;
-
-: redefine-method ( quot class generic -- )
-    [ method swap "method-def" set-word-prop ] 3keep
-    [ make-method-def ] 2keep
-    method swap define ;
-
-: define-method ( quot class generic -- )
-    >r bootstrap-word r>
-    2dup method [
-        redefine-method
+    [ set-word-props ] keep ;
+
+: reveal-method ( method class generic -- )
+    [ set-at ] with-methods ;
+
+: create-method ( class generic -- method )
+    2dup method dup [
+        2nip
     ] [
-        [ <method> ] 2keep
-        [ set-at ] with-methods
+        drop [ <method> dup ] 2keep reveal-method
     ] if ;
 
+: <default-method> ( generic combination -- method )
+    object bootstrap-word pick <method>
+    [ -rot make-default-method define ] keep ;
+
 : define-default-method ( generic combination -- )
-    dupd make-default-method object bootstrap-word pick <method>
-    "default-method" set-word-prop ;
+    dupd <default-method> "default-method" set-word-prop ;
 
 ! Definition protocol
 M: method-spec where
@@ -108,11 +98,10 @@ M: method-spec set-where
     first2 method set-where ;
 
 M: method-spec definer
-    drop \ M: \ ; ;
+    first2 method definer ;
 
 M: method-spec definition
-    first2 method dup
-    [ "method-def" word-prop ] when ;
+    first2 method definition ;
 
 : forget-method ( class generic -- )
     check-method
@@ -125,9 +114,6 @@ M: method-spec forget*
 M: method-body definer
     drop \ M: \ ; ;
 
-M: method-body definition
-    "method-def" word-prop ;
-
 M: method-body forget*
     dup "method-class" word-prop
     swap "method-generic" word-prop
index 27b0ddb7a2bc0933bc38f7a765f7630bf38938fe..9fd5481a3971d6ec7c95881dde4408c919fa99e1 100755 (executable)
@@ -43,7 +43,7 @@ TUPLE: no-math-method left right generic ;
 
 : applicable-method ( generic class -- quot )
     over method
-    [ word-def ]
+    [ 1quotation ]
     [ default-math-method ] ?if ;
 
 : object-method ( generic -- quot )
index 313f487c994adc94696e383e3689f8b83ad18d84..c634e02e75bbad2f134f28dd8cee8c41c30e0431 100755 (executable)
@@ -8,10 +8,6 @@ IN: generic.standard
 
 TUPLE: standard-combination # ;
 
-M: standard-combination method-prologue
-    standard-combination-# object
-    <array> swap add* [ declare ] curry ;
-
 C: <standard-combination> standard-combination
 
 SYMBOL: (dispatch#)
index e2eeef6528e4e258c3706de5f3d15303877e8a6d..e347e3e3d6bccf182ed857c35fda28c016647aaa 100755 (executable)
@@ -1,6 +1,10 @@
 IN: io.files.tests
 USING: tools.test io.files io threads kernel continuations io.encodings.ascii ;
 
+[ ] [ "blahblah" temp-file dup exists? [ delete-directory ] [ drop ] if ] unit-test
+[ ] [ "blahblah" temp-file make-directory ] unit-test
+[ t ] [ "blahblah" temp-file directory? ] unit-test
+
 [ "passwd" ] [ "/etc/passwd" file-name ] unit-test
 [ "awk" ] [ "/usr/libexec/awk/" file-name ] unit-test
 [ "awk" ] [ "/usr/libexec/awk///" file-name ] unit-test
@@ -123,3 +127,7 @@ USING: tools.test io.files io threads kernel continuations io.encodings.ascii ;
 [ ] [ "copy-tree-test" temp-file delete-tree ] unit-test
 
 [ t ] [ cwd "misc" resource-path [ ] with-directory cwd = ] unit-test
+
+[ ] [ "append-test" temp-file dup exists? [ delete-file ] [ drop ] if ] unit-test
+
+[ ] [ "append-test" ascii <file-appender> dispose ] unit-test
index 3ab489739b04a44e93b31d53a3a1815ad33ac082..a6320a750723dbc9fa18599f8946ccc4928caf1e 100755 (executable)
@@ -86,15 +86,11 @@ SYMBOL: +unknown+
 : stat ( path -- directory? permissions length modified )
     normalize-pathname (stat) ;
 
-! : file-length ( path -- n ) stat drop 2nip ;
-
 : file-modified ( path -- n ) stat >r 3drop r> ;
 
-! : file-permissions ( path -- perm ) stat 2drop nip ;
-
 : exists? ( path -- ? ) file-modified >boolean ;
 
-: directory? ( path -- ? ) stat 3drop ;
+: directory? ( path -- ? ) file-info file-info-type +directory+ = ;
 
 ! Current working directory
 HOOK: cd io-backend ( path -- )
@@ -220,10 +216,7 @@ M: pathname <=> [ pathname-string ] compare ;
     >r <file-reader> r> with-stream ; inline
 
 : file-contents ( path encoding -- str )
-    dupd [ file-info file-info-size read ] with-file-reader ;
-
-! : file-contents ( path encoding -- str )
-!     dupd [ file-length read ] with-file-reader ;
+    <file-reader> contents ;
 
 : with-file-writer ( path encoding quot -- )
     >r <file-writer> r> with-stream ; inline
index 2d927d088afb69a754529f08af742a93224e4508..ef9eae790286118ace704db838437566f2cc4594 100755 (executable)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2003, 2007 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: hashtables generic kernel math namespaces sequences strings
-    continuations assocs io.styles sbufs ;
+USING: hashtables generic kernel math namespaces sequences
+continuations assocs io.styles ;
 IN: io
 
 GENERIC: stream-readln ( stream -- str )
@@ -88,4 +88,6 @@ SYMBOL: stderr
     [ [ readln dup ] [ ] [ drop ] unfold ] with-stream ;
 
 : contents ( stream -- str )
-    2048 <sbuf> [ stream-copy ] keep >string ;
+    [
+        [ 65536 read dup ] [ ] [ drop ] unfold concat f like
+    ] with-stream  ;
index 8e107975bb589a854663d3be5a82753eaf702419..0babb14fa75ce99edb886bea2dce410c77ba4e7c 100755 (executable)
@@ -429,7 +429,14 @@ $nl
 { $code "[ X ] [ Y ] ?if" "dup [ nip X ] [ drop Y ] if" } } ;
 
 HELP: die
-{ $description "Starts the front-end processor (FEP), which is a low-level debugger which can inspect memory addresses and the like. The FEP is also entered when a critical error occurs." } ;
+{ $description "Starts the front-end processor (FEP), which is a low-level debugger which can inspect memory addresses and the like. The FEP is also entered when a critical error occurs." }
+{ $notes
+    "The term FEP originates from the Lisp machines of old. According to the Jargon File,"
+    $nl
+    { $strong "fepped out" } " /fept owt/ " { $emphasis "adj." }  " The Symbolics 3600 LISP Machine has a Front-End Processor called a `FEP' (compare sense 2 of box). When the main processor gets wedged, the FEP takes control of the keyboard and screen. Such a machine is said to have `fepped out' or `dropped into the fep'." 
+    $nl
+    { $url "http://www.jargon.net/jargonfile/f/feppedout.html" }
+} ;
 
 HELP: (clone) ( obj -- newobj )
 { $values { "obj" object } { "newobj" "a shallow copy" } }
index 10a9fda3eae0212a673f17b67d15548ecc910c63..5153d84c7faaa0ffd12871d7af40708ce6334a79 100755 (executable)
@@ -24,20 +24,40 @@ IN: optimizer.specializers
         \ dispatch ,\r
     ] [ ] make ;\r
 \r
-: specializer-methods ( quot word -- default alist )\r
+: specializer-cases ( quot word -- default alist )\r
     dup [ array? ] all? [ 1array ] unless [\r
         [ make-specializer ] keep\r
         [ declare ] curry pick append\r
     ] { } map>assoc ;\r
 \r
+: method-declaration ( method -- quot )\r
+    dup "method-generic" word-prop dispatch# object <array>\r
+    swap "method-class" word-prop add* ;\r
+\r
+: specialize-method ( quot method -- quot' )\r
+    method-declaration [ declare ] curry swap append ;\r
+\r
+: specialize-quot ( quot specializer -- quot' )\r
+    dup { number } = [\r
+        drop tag-specializer\r
+    ] [\r
+        specializer-cases alist>quot\r
+    ] if ;\r
+\r
+: standard-method? ( method -- ? )\r
+    dup method-body? [\r
+        "method-generic" word-prop standard-generic?\r
+    ] [ drop f ] if ;\r
+\r
 : specialized-def ( word -- quot )\r
-    dup word-def swap "specializer" word-prop [\r
-        dup { number } = [\r
-            drop tag-specializer\r
-        ] [\r
-            specializer-methods alist>quot\r
-        ] if\r
-    ] when* ;\r
+    dup word-def swap {\r
+        { [ dup standard-method? ] [ specialize-method ] }\r
+        {\r
+            [ dup "specializer" word-prop ]\r
+            [ "specializer" word-prop specialize-quot ]\r
+        }\r
+        { [ t ] [ drop ] }\r
+    } cond ;\r
 \r
 : specialized-length ( specializer -- n )\r
     dup [ array? ] all? [ first ] when length ;\r
index 50f8f582d352ab32cf753b78cf5439754276d36b..cf31c16662bca14c8c3c8991d099ff72deef8dcc 100755 (executable)
@@ -215,9 +215,6 @@ SYMBOL: in
 : set-in ( name -- )
     check-vocab-string dup in set create-vocab (use+) ;
 
-: create-in ( string -- word )
-    in get create dup set-word dup save-location ;
-
 TUPLE: unexpected want got ;
 
 : unexpected ( want got -- * )
@@ -238,8 +235,15 @@ PREDICATE: unexpected unexpected-eof
 : parse-tokens ( end -- seq )
     100 <vector> swap (parse-tokens) >array ;
 
+: create-in ( string -- word )
+    in get create dup set-word dup save-location ;
+
 : CREATE ( -- word ) scan create-in ;
 
+: CREATE-GENERIC ( -- word ) CREATE dup reset-word ;
+
+: CREATE-WORD ( -- word ) CREATE dup reset-generic ;
+
 : create-class-in ( word -- word )
     in get create
     dup save-class-location
@@ -284,6 +288,12 @@ M: no-word summary
         ] ?if
     ] when ;
 
+: create-method-in ( class generic -- method )
+    create-method f set-word dup save-location ;
+
+: CREATE-METHOD ( -- method )
+    scan-word bootstrap-word scan-word create-method-in ;
+
 TUPLE: staging-violation word ;
 
 : staging-violation ( word -- * )
@@ -355,7 +365,9 @@ TUPLE: bad-number ;
 : parse-definition ( -- quot )
     \ ; parse-until >quotation ;
 
-: (:) CREATE dup reset-generic parse-definition ;
+: (:) CREATE-WORD parse-definition ;
+
+: (M:) CREATE-METHOD parse-definition ;
 
 GENERIC: expected>string ( obj -- str )
 
index 92d22247bdb0386104b8e5deb6debd781eb21c24..7e9046573f5018d26907b24a323fa7f61e55e87f 100755 (executable)
@@ -10,7 +10,8 @@ TUPLE: slot-spec type name offset reader writer ;
 C: <slot-spec> slot-spec
 
 : define-typecheck ( class generic quot -- )
-    over define-simple-generic -rot define-method ;
+    over define-simple-generic
+    >r create-method r> define ;
 
 : define-slot-word ( class slot word quot -- )
     rot >fixnum add* define-typecheck ;
index 79a5553228b53687d2b1f3c563493d1f8bc79bf1..d9870b08daddd7739d9ee6c6de799fd79c18126b 100755 (executable)
@@ -97,7 +97,7 @@ IN: bootstrap.syntax
     "parsing" [ word t "parsing" set-word-prop ] define-syntax
 
     "SYMBOL:" [
-        CREATE dup reset-generic define-symbol
+        CREATE-WORD define-symbol
     ] define-syntax
 
     "DEFER:" [
@@ -111,31 +111,26 @@ IN: bootstrap.syntax
     ] define-syntax
 
     "GENERIC:" [
-        CREATE dup reset-word
-        define-simple-generic
+        CREATE-GENERIC define-simple-generic
     ] define-syntax
 
     "GENERIC#" [
-        CREATE dup reset-word
+        CREATE-GENERIC
         scan-word <standard-combination> define-generic
     ] define-syntax
 
     "MATH:" [
-        CREATE dup reset-word
+        CREATE-GENERIC
         T{ math-combination } define-generic
     ] define-syntax
 
     "HOOK:" [
-        CREATE dup reset-word scan-word
+        CREATE-GENERIC scan-word
         <hook-combination> define-generic
     ] define-syntax
 
     "M:" [
-        f set-word
-        location >r
-        scan-word bootstrap-word scan-word
-        [ parse-definition -rot define-method ] 2keep
-        2array r> remember-definition
+        (M:) define
     ] define-syntax
 
     "UNION:" [
@@ -163,7 +158,7 @@ IN: bootstrap.syntax
     ] define-syntax
 
     "C:" [
-        CREATE dup reset-generic
+        CREATE-WORD
         scan-word dup check-tuple
         [ construct-boa ] curry define-inline
     ] define-syntax
index c2e627e7bf9abc164865564960a1afdc5bfef494..d746404cba4b751de0e4b1d5eac5622b655b6c3f 100755 (executable)
@@ -14,3 +14,5 @@ yield
 [ 3 ] [
     [ 3 swap resume-with ] "Test suspend" suspend
 ] unit-test
+
+[ f ] [ f get-global ] unit-test
index b4fd6eee60de359b893a62b7d7fc9338578b7f3f..d7d7988893e06df8bc443488014fc8334eba7cf1 100755 (executable)
@@ -32,8 +32,6 @@ mailbox variables sleep-entry ;
 
 : threads 41 getenv ;
 
-threads global [ H{ } assoc-like ] change-at
-
 : thread ( id -- thread ) threads at ;
 
 : thread-registered? ( thread -- ? )
index c03b9784eecf8dbe72e778d326d2be140b287405..3af7d27d861c9dbe9d8f72bb96c5c713d4d320da 100755 (executable)
@@ -12,6 +12,22 @@ ARTICLE: "tuple-constructors" "Constructors and slots"
 $nl
 "A shortcut for defining BOA constructors:"
 { $subsection POSTPONE: C: }
+"Examples of constructors:"
+{ $code
+    "TUPLE: color red green blue alpha ;"
+    ""
+    "C: <rgba> rgba"
+    ": <rgba> color construct-boa ; ! identical to above"
+    ""
+    ": <rgb>"
+    "    { set-color-red set-color-green set-color-blue }"
+    "    color construct ;"
+    ": <rgb> f <rgba> ; ! identical to above"
+    ""
+    ": <color> construct-empty ;"
+    ": <color> { } color construct ; ! identical to above"
+    ": <color> f f f f <rgba> ; ! identical to above"
+}
 "After construction, slots are read and written using various automatically-defined words with names of the form " { $snippet { $emphasis "class-slot" } } " and " { $snippet "set-" { $emphasis "class-slot" } } "." ;
 
 ARTICLE: "tuple-delegation" "Delegation"
@@ -48,8 +64,8 @@ ARTICLE: "tuples" "Tuples"
 "Tuples are user-defined classes composed of named slots. A parsing word defines tuple classes:"
 { $subsection POSTPONE: TUPLE: }
 "An example:"
-{ $code "TUPLE: person name address phone ;" }
-"This defines a class word named " { $snippet "person" } ", along with a predicate " { $snippet "person?" } ", and the following reader/writer words:"
+{ $code "TUPLE: person name address phone ;" "C: <person> person" }
+"This defines a class word named " { $snippet "person" } ", a predicate " { $snippet "person?" } ", a constructor named " { $snippet "<person>" } ", and the following reader/writer words:"
 { $table
     { "Reader" "Writer" }
     { { $snippet "person-name" }    { $snippet "set-person-name" }    }
index ce69c1ff2eb4c3d133ee6d809b3f270339be4192..73b877fdbbf2b4e1d8cfb6c559b8e592a1dc8075 100755 (executable)
@@ -68,7 +68,7 @@ SYMBOL: bootstrapping?
 : crossref? ( word -- ? )
     {
         { [ dup "forgotten" word-prop ] [ f ] }
-        { [ dup "method-def" word-prop ] [ t ] }
+        { [ dup "method-generic" word-prop ] [ t ] }
         { [ dup word-vocabulary ] [ t ] }
         { [ t ] [ f ] }
     } cond nip ;
index 88095759e67c67ebc93e957ac83d6830ad6a2d26..2500940373ada62a6a99919374f0b2fbb6ea31ee 100755 (executable)
@@ -1,4 +1,5 @@
-USING: assocs kernel vectors sequences namespaces ;
+USING: arrays assocs kernel vectors sequences namespaces
+random math.parser ;
 IN: assocs.lib
 
 : >set ( seq -- hash )
@@ -35,3 +36,13 @@ IN: assocs.lib
     [ with each ] curry assoc-each ; inline
 
 : insert ( value variable -- ) namespace insert-at ;
+
+: 2seq>assoc ( keys values exemplar -- assoc )
+    >r 2array flip r> assoc-like ;
+
+: generate-key ( assoc -- str )
+    >r random-256 >hex r>
+    2dup key? [ nip generate-key ] [ drop ] if ;
+
+: set-at-unique ( value assoc -- key )
+    dup generate-key [ swap set-at ] keep ;
index 0bf7a032ee176765e17c1e45870b4cc4be15191f..670bca490349f6e194d699a653b04b1f1d1fc475 100755 (executable)
@@ -13,5 +13,6 @@ USING: vocabs.loader sequences ;
     "tools.threads"
     "tools.vocabs"
     "tools.vocabs.browser"
+    "tools.vocabs.monitor"
     "editors"
 } [ require ] each
index 444e5b6ea703f93c28e1f7e6196ed6aebf1f4d02..2f38462976c5c4a1cfc3cf8a77a736afdc19f955 100644 (file)
@@ -4,10 +4,12 @@ USING: kernel continuations arrays assocs sequences sorting math
 
 IN: builder.benchmark
 
-: passing-benchmarks ( table -- table )
-  [ second first2 number? swap number? and ] subset ;
+: passing-benchmarks ( table -- table )
+  [ second first2 number? swap number? and ] subset ;
 
-: simplify-table ( table -- table ) [ first2 second 2array ] map ;
+: passing-benchmarks ( table -- table ) [ second number? ] subset ;
+
+! : simplify-table ( table -- table ) [ first2 second 2array ] map ;
 
 : benchmark-difference ( old-table benchmark-result -- result-diff )
   first2 >r
@@ -17,7 +19,7 @@ IN: builder.benchmark
   2array ;
 
 : compare-tables ( old new -- table )
-  [ passing-benchmarks simplify-table ] 2apply
+  [ passing-benchmarks ] 2apply
   [ benchmark-difference ] with map ;
 
 : benchmark-deltas ( -- table )
index 52150b07a8692157d2b73de49b72d619110fc730..7d95ce24092575b485608cff1635d680e6eaa04f 100644 (file)
@@ -134,7 +134,9 @@ SYMBOL: build-status
       "Did not pass load-everything: " print "load-everything-vocabs" cat
       
       "Did not pass test-all: "        print "test-all-vocabs"        cat
-      "test-all-vocabs" eval-file test-failures.
+                                             "test-failures"          cat
+      
+!       "test-failures" eval-file test-failures.
       
       "help-lint results:"             print "help-lint"              cat
 
index 316479d53cdd7c857ff48e153de603a8fbafe3ad..29fb99a3016b7b1241e2941405f7dcfe6588ce0b 100644 (file)
@@ -6,7 +6,7 @@
 !  http://cairographics.org/samples/text/
 
 
-USING: cairo math math.constants byte-arrays kernel ui ui.render
+USING: cairo.ffi math math.constants byte-arrays kernel ui ui.render
            ui.gadgets opengl.gl ;
 
 IN: cairo-demo
@@ -23,13 +23,15 @@ IN: cairo-demo
 TUPLE: cairo-gadget image-array cairo-t ;
 
 M: cairo-gadget draw-gadget* ( gadget -- )
-   0 0 glRasterPos2i
-   1.0 -1.0 glPixelZoom
-   >r 384 256 GL_RGBA GL_UNSIGNED_BYTE r>
-   cairo-gadget-image-array glDrawPixels ;
+    0 0 glRasterPos2i
+    1.0 -1.0 glPixelZoom
+    >r 384 256 GL_RGBA GL_UNSIGNED_BYTE r>
+    cairo-gadget-image-array glDrawPixels ;
 
 : create-surface ( gadget -- cairo_surface_t )
-  make-image-array dup >r swap set-cairo-gadget-image-array r> convert-array-to-surface ;
+    make-image-array
+    [ swap set-cairo-gadget-image-array ] keep
+    convert-array-to-surface ;
 
 : init-cairo ( gadget -- cairo_t )
    create-surface cairo_create ;
@@ -56,7 +58,7 @@ M: cairo-gadget pref-dim* drop { 384 256 0 } ;
   cairo_fill ;
 
 M: cairo-gadget graft* ( gadget -- )
-   dup dup init-cairo swap set-cairo-gadget-cairo-t draw-hello-world ;
+  dup dup init-cairo swap set-cairo-gadget-cairo-t draw-hello-world ;
 
 M: cairo-gadget ungraft* ( gadget -- )
    cairo-gadget-cairo-t cairo_destroy ;
index 4a2736dd934b5c2e533ca263d87e80cf0f7c9aa3..68d35d192b42a2515c48045af4ab6a419eb0ca2e 100644 (file)
@@ -1 +1,2 @@
 Sampo Vuori
+Doug Coleman
diff --git a/extra/cairo/cairo.factor b/extra/cairo/cairo.factor
deleted file mode 100644 (file)
index 0d3e0c2..0000000
+++ /dev/null
@@ -1,459 +0,0 @@
-! Bindings for Cairo library
-!  Copyright (c) 2007 Sampo Vuori
-!    License: http://factorcode.org/license.txt
-
-! Unimplemented:
-!  - most of the font stuff
-!  - most of the matrix stuff
-!  - most of the query functions
-
-
-USING: alien alien.syntax combinators system ;
-
-IN: cairo
-
-<< "cairo" {
-        { [ win32? ] [ "cairo.dll" ] }
-        ! { [ macosx? ] [ "libcairo.dylib" ] }
-        { [ macosx? ] [ "/opt/local/lib/libcairo.dylib" ] }
-        { [ unix? ] [ "libcairo.so.2" ] }
-  } cond "cdecl" add-library >>
-
-LIBRARY: cairo
-
-TYPEDEF: int cairo_status_t
-C-ENUM:
-    CAIRO_STATUS_SUCCESS
-    CAIRO_STATUS_NO_MEMORY
-    CAIRO_STATUS_INVALID_RESTORE
-    CAIRO_STATUS_INVALID_POP_GROUP
-    CAIRO_STATUS_NO_CURRENT_POINT
-    CAIRO_STATUS_INVALID_MATRIX
-    CAIRO_STATUS_INVALID_STATUS
-    CAIRO_STATUS_NULL_POINTER
-    CAIRO_STATUS_INVALID_STRING
-    CAIRO_STATUS_INVALID_PATH_DATA
-    CAIRO_STATUS_READ_ERROR
-    CAIRO_STATUS_WRITE_ERROR
-    CAIRO_STATUS_SURFACE_FINISHED
-    CAIRO_STATUS_SURFACE_TYPE_MISMATCH
-    CAIRO_STATUS_PATTERN_TYPE_MISMATCH
-    CAIRO_STATUS_INVALID_CONTENT
-    CAIRO_STATUS_INVALID_FORMAT
-    CAIRO_STATUS_INVALID_VISUAL
-    CAIRO_STATUS_FILE_NOT_FOUND
-    CAIRO_STATUS_INVALID_DASH
-    CAIRO_STATUS_INVALID_DSC_COMMENT
-    CAIRO_STATUS_INVALID_INDEX
-    CAIRO_STATUS_CLIP_NOT_REPRESENTABLE
-;
-
-TYPEDEF: int cairo_content_t
-: CAIRO_CONTENT_COLOR HEX: 1000 ;
-: CAIRO_CONTENT_ALPHA HEX: 2000 ;
-: CAIRO_CONTENT_COLOR_ALPHA HEX: 3000 ;
-
-TYPEDEF: int cairo_operator_t
-C-ENUM:
-    CAIRO_OPERATOR_CLEAR
-    CAIRO_OPERATOR_SOURCE
-    CAIRO_OPERATOR_OVER
-    CAIRO_OPERATOR_IN
-    CAIRO_OPERATOR_OUT
-    CAIRO_OPERATOR_ATOP
-    CAIRO_OPERATOR_DEST
-    CAIRO_OPERATOR_DEST_OVER
-    CAIRO_OPERATOR_DEST_IN
-    CAIRO_OPERATOR_DEST_OUT
-    CAIRO_OPERATOR_DEST_ATOP
-    CAIRO_OPERATOR_XOR
-    CAIRO_OPERATOR_ADD
-    CAIRO_OPERATOR_SATURATE
-;
-
-TYPEDEF: int cairo_line_cap_t
-C-ENUM:
-    CAIRO_LINE_CAP_BUTT
-    CAIRO_LINE_CAP_ROUND
-    CAIRO_LINE_CAP_SQUARE
-;
-
-TYPEDEF: int cair_line_join_t
-C-ENUM:
-    CAIRO_LINE_JOIN_MITER
-    CAIRO_LINE_JOIN_ROUND
-    CAIRO_LINE_JOIN_BEVEL
-;
-
-TYPEDEF: int cairo_fill_rule_t
-C-ENUM:
-    CAIRO_FILL_RULE_WINDING
-    CAIRO_FILL_RULE_EVEN_ODD
-;
-
-TYPEDEF: int cairo_font_slant_t
-C-ENUM:
-    CAIRO_FONT_SLANT_NORMAL
-    CAIRO_FONT_SLANT_ITALIC
-    CAIRO_FONT_SLANT_OBLIQUE
-;
-
-TYPEDEF: int cairo_font_weight_t
-C-ENUM:
-    CAIRO_FONT_WEIGHT_NORMAL
-    CAIRO_FONT_WEIGHT_BOLD
-;
-
-C-STRUCT: cairo_font_t
-    { "int" "refcount" }
-    { "uint" "scale" } ;
-
-C-STRUCT: cairo_rectangle_t
-    { "short" "x" }
-    { "short" "y" }
-    { "ushort" "width" }
-    { "ushort" "height" } ;
-
-C-STRUCT: cairo_clip_rec_t
-    { "cairo_rectangle_t" "rect" }
-    { "void*" "region" }
-    { "void*" "surface" } ;
-
-C-STRUCT: cairo_matrix_t
-    { "void*" "m" } ;
-
-C-STRUCT: cairo_gstate_t
-    { "uint" "operator" }
-    { "double" "tolerance" }
-    { "double" "line_width" }
-    { "uint" "line_cap" }
-    { "uint" "line_join" }
-    { "double" "miter_limit" }
-    { "uint" "fill_rule" }
-    { "void*" "dash" }
-    { "int" "num_dashes" }
-    { "double" "dash_offset" }
-    { "char*" "font_family " }
-    { "uint" "font_slant" }
-    { "uint" "font_weight" }
-    { "void*" "font" }
-    { "void*" "surface" }
-    { "void*" "pattern " }
-    { "double" "alpha" }
-    { "cairo_clip_rec_t" "clip" }
-    { "double" "pixels_per_inch" }
-    { "cairo_matrix_t" "font_matrix" }
-    { "cairo_matrix_t" "ctm" }
-    { "cairo_matrix_t" "ctm_inverse" }
-    { "void*" "path" }
-    { "void*" "pen_regular" }
-    { "void*" "next" } ;
-
-C-STRUCT: cairo_t
-    { "uint" "ref_count" }
-    { "cairo_gstate_t*" "gstate" }
-    { "uint" "status ! cairo_status_t" } ;
-
-C-STRUCT: cairo_matrix_t
-        { "double" "xx" }
-        { "double" "yx" }
-        { "double" "xy" }
-        { "double" "yy" }
-        { "double" "x0" }
-        { "double" "y0" } ;
-
-TYPEDEF: int cairo_format_t
-C-ENUM:
-    CAIRO_FORMAT_ARGB32
-    CAIRO_FORMAT_RGB24
-    CAIRO_FORMAT_A8
-    CAIRO_FORMAT_A1
-;
-
-TYPEDEF: int cairo_antialias_t
-C-ENUM:
-    CAIRO_ANTIALIAS_DEFAULT
-    CAIRO_ANTIALIAS_NONE
-    CAIRO_ANTIALIAS_GRAY
-    CAIRO_ANTIALIAS_SUBPIXEL
-;
-
-TYPEDEF: int cairo_subpixel_order_t
-C-ENUM:
-    CAIRO_SUBPIXEL_ORDER_DEFAULT
-    CAIRO_SUBPIXEL_ORDER_RGB
-    CAIRO_SUBPIXEL_ORDER_BGR
-    CAIRO_SUBPIXEL_ORDER_VRGB
-    CAIRO_SUBPIXEL_ORDER_VBGR
-;
-
-TYPEDEF: int cairo_hint_style_t
-C-ENUM:
-    CAIRO_HINT_STYLE_DEFAULT
-    CAIRO_HINT_STYLE_NONE
-    CAIRO_HINT_STYLE_SLIGHT
-    CAIRO_HINT_STYLE_MEDIUM
-    CAIRO_HINT_STYLE_FULL
-;
-
-TYPEDEF: int cairo_hint_metrics_t
-C-ENUM:
-    CAIRO_HINT_METRICS_DEFAULT
-    CAIRO_HINT_METRICS_OFF
-    CAIRO_HINT_METRICS_ON
-;
-
-: cairo_create ( cairo_surface_t -- cairo_t )
-    "cairo_t*" "cairo" "cairo_create" [ "void*" ] alien-invoke ;
-
-: cairo_reference ( cairo_t -- cairo_t )
-        "cairo_t*" "cairo" "cairo_reference" [ "cairo_t*" ] alien-invoke ;
-
-: cairo_destroy ( cairo_t -- )
-    "void" "cairo" "cairo_destroy" [ "cairo_t*" ] alien-invoke ;
-
-: cairo_save ( cairo_t -- )
-        "void" "cairo" "cairo_save" [ "cairo_t*" ] alien-invoke ;
-
-: cairo_restore ( cairo_t -- )
-        "void" "cairo" "cairo_restore" [ "cairo_t*" ] alien-invoke ;
-
-: cairo_set_operator ( cairo_t cairo_operator_t -- )
-    "void" "cairo" "cairo_set_operator" [ "cairo_t*" "int" ] alien-invoke ;
-
-: cairo_set_source ( cairo_t cairo_pattern_t -- )
-    "void" "cairo" "cairo_set_source" [ "cairo_t*" "void*" ] alien-invoke ;
-
-: cairo_set_source_rgb ( cairo_t red green blue -- )
-    "void" "cairo" "cairo_set_source_rgb" [ "cairo_t*" "double" "double" "double" ] alien-invoke ;
-
-: cairo_set_source_rgba ( cairo_t red green blue alpha -- )
-    "void" "cairo" "cairo_set_source_rgb" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ;
-
-: cairo_set_source_surface ( cairo_t cairo_surface_t x y -- )
-    "void" "cairo" "cairo_set_source_surface" [ "cairo_t*" "void*" "double" "double" ] alien-invoke ;
-
-: cairo_set_tolerance ( cairo_t tolerance -- )
-    "void" "cairo" "cairo_set_tolerance" [ "cairo_t*" "double" ] alien-invoke ;
-
-: cairo_image_surface_create_for_data ( data format width height stride -- cairo_surface_t )
-    "void*" "cairo" "cairo_image_surface_create_for_data" [ "void*" "uint" "int" "int" "int" ] alien-invoke ;
-    
-
-: cairo_set_antialias ( cairo_t cairo_antialias_t -- )
-    "void" "cairo" "cairo_set_antialias" [ "cairo_t*" "int" ] alien-invoke ;
-
-: cairo_set_fill_rule ( cairo_t cairo_fill_rule_t -- )
-    "void" "cairo" "cairo_set_fill_rule" [ "cairo_t*" "int" ] alien-invoke ;
-
-: cairo_set_line_width ( cairo_t width -- )
-    "void" "cairo" "cairo_set_line_width" [ "cairo_t*" "double" ] alien-invoke ;
-
-: cairo_set_line_cap ( cairo_t cairo_line_cap_t -- )
-    "void" "cairo" "cairo_set_line_cap" [ "cairo_t*" "int" ] alien-invoke ;
-
-: cairo_set_line_join ( cairo_t cairo_line_join_t -- )
-    "void" "cairo" "cairo_set_line_join" [ "cairo_t*" "int" ] alien-invoke ;
-
-: cairo_set_dash ( cairo_t dashes num_dashes offset -- )
-    "void" "cairo" "cairo_set_dash" [ "cairo_t*" "double" "int" "double" ] alien-invoke ;
-
-: cairo_set_miter_limit ( cairo_t limit -- )
-    "void" "cairo" "cairo_set_miter_limit" [ "cairo_t*" "double" ] alien-invoke ;
-
-: cairo_translate ( cairo_t x y -- )
-    "void" "cairo" "cairo_translate" [ "cairo_t*" "double" "double" ] alien-invoke ;
-
-: cairo_scale ( cairo_t sx sy -- )
-    "void" "cairo" "cairo_scale" [ "cairo_t*" "double" "double" ] alien-invoke ;
-
-: cairo_rotate ( cairo_t angle -- )
-    "void" "cairo" "cairo_rotate" [ "cairo_t*" "double" ] alien-invoke ;
-
-: cairo_transform ( cairo_t cairo_matrix_t -- )
-        "void" "cairo" "cairo_transform" [ "cairo_t*" "cairo_matrix_t*" ] alien-invoke ;
-
-: cairo_set_matrix ( cairo_t cairo_matrix_t -- )
-        "void" "cairo" "cairo_set_matrix" [ "cairo_t*" "cairo_matrix_t*" ] alien-invoke ;
-
-: cairo_identity_matrix ( cairo_t -- )
-        "void" "cairo" "cairo_identity_matrix" [ "cairo_t*" ] alien-invoke ;
-
-! cairo path creating functions
-
-: cairo_new_path ( cairo_t -- )
-    "void" "cairo" "cairo_new_path" [ "cairo_t*" ] alien-invoke ;
-
-: cairo_move_to ( cairo_t x y -- )
-    "void" "cairo" "cairo_move_to" [ "cairo_t*" "double" "double" ] alien-invoke ;
-
-: cairo_new_sub_path ( cairo_t -- )
-    "void" "cairo" "cairo_new_sub_path" [ "cairo_t*" ] alien-invoke ;
-    
-: cairo_line_to ( cairo_t x y -- )
-    "void" "cairo" "cairo_line_to" [ "cairo_t*" "double" "double" ] alien-invoke ;
-
-: cairo_curve_to ( cairo_t x1 y1 x2 y2 x3 y3 -- )
-    "void" "cairo" "cairo_curve_to" [ "cairo_t*" "double" "double" "double" "double" "double" "double" ] alien-invoke ;
-
-: cairo_arc ( cairo_t xc yc radius angle1 angle2 -- )
-    "void" "cairo" "cairo_arc" [ "cairo_t*" "double" "double" "double" "double" "double" ] alien-invoke ;
-
-: cairo_arc_negative ( cairo_t xc yc radius angle1 angle2 -- )
-    "void" "cairo" "cairo_arc_negative" [ "cairo_t*" "double" "double" "double" "double" "double" ] alien-invoke ;
-    
-: cairo_rel_move_to ( cairo_t dx dy -- )
-    "void" "cairo" "cairo_rel_move_to" [ "cairo_t*" "double" "double" ] alien-invoke ;
-    
-: cairo_rel_line_to ( cairo_t dx dy -- )
-    "void" "cairo" "cairo_rel_line_to" [ "cairo_t*" "double" "double" ] alien-invoke ;
-
-: cairo_rel_curve_to ( cairo_t dx1 dy1 dx2 dy2 dx3 dy3 -- )
-    "void" "cairo" "cairo_rel_curve_to" [ "cairo_t*" "double" "double" "double" "double" "double" "double" ] alien-invoke ;
-
-: cairo_rectangle ( cairo_t x y width height -- )
-    "void" "cairo" "cairo_rectangle" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ;
-
-: cairo_close_path ( cairo_t -- )
-    "void" "cairo" "cairo_close_path" [ "cairo_t*" ] alien-invoke ;
-
-! Surface manipulation
-
-: cairo_surface_create_similar ( cairo_surface_t cairo_content_t width height -- cairo_surface_t )
-    "cairo_surface_t*" "cairo" "cairo_surface_create_similar" [ "cairo_surface_t*" "uint" "int" "int" ] alien-invoke ;
-
-: cairo_surface_reference ( cairo_surface_t -- cairo_surface_t )
-    "cairo_surface_t*" "cairo" "cairo_surface_reference" [ "cairo_surface_t*" ] alien-invoke ;
-
-: cairo_surface_finish ( cairo_surface_t -- )
-    "void" "cairo" "cairo_surface_finish" [ "cairo_surface_t*" ] alien-invoke ;
-
-: cairo_surface_destroy ( cairo_surface_t -- )
-    "void" "cairo" "cairo_surface_destroy" [ "cairo_surface_t*" ] alien-invoke ;
-
-: cairo_surface_get_reference_count ( cairo_surface_t -- count )
-    "uint" "cairo" "cairo_surface_get_reference_count" [ "cairo_surface_t*" ] alien-invoke ;
-
-: cairo_surface_status ( cairo_surface_t -- cairo_status_t )
-    "uint" "cairo" "cairo_surface_status" [ "cairo_surface_t*" ] alien-invoke ;
-
-: cairo_surface_flush ( cairo_surface_t -- )
-    "void" "cairo" "cairo_surface_flush" [ "cairo_surface_t*" ] alien-invoke ;
-
-! painting functions
-: cairo_paint ( cairo_t -- )
-    "void" "cairo" "cairo_paint" [ "cairo_t*" ] alien-invoke ;
-
-: cairo_paint_with_alpha ( cairo_t alpha -- )
-    "void" "cairo" "cairo_paint_with_alpha" [ "cairo_t*" "double" ] alien-invoke ;
-
-: cairo_mask ( cairo_t cairo_pattern_t -- )
-    "void" "cairo" "cairo_mask" [ "cairo_t*" "void*" ] alien-invoke ;
-
-: cairo_mask_surface ( cairo_t cairo_pattern_t surface-x surface-y -- )
-    "void" "cairo" "cairo_mask_surface" [ "cairo_t*" "void*" "double" "double" ] alien-invoke ;
-
-: cairo_stroke ( cairo_t -- )
-    "void" "cairo" "cairo_stroke" [ "cairo_t*" ] alien-invoke ;
-
-: cairo_stroke_preserve ( cairo_t -- )
-    "void" "cairo" "cairo_stroke_preserve" [ "cairo_t*" ] alien-invoke ;
-
-: cairo_fill ( cairo_t -- )
-    "void" "cairo" "cairo_fill" [ "cairo_t*" ] alien-invoke ;
-
-: cairo_fill_preserve ( cairo_t -- )
-    "void" "cairo" "cairo_fill_preserve" [ "cairo_t*" ] alien-invoke ;
-
-: cairo_copy_page ( cairo_t -- )
-    "void" "cairo" "cairo_copy_page" [ "cairo_t*" ] alien-invoke ;
-
-: cairo_show_page ( cairo_t -- )
-    "void" "cairo" "cairo_show_page" [ "cairo_t*" ] alien-invoke ;
-
-! insideness testing
-: cairo_in_stroke ( cairo_t x y -- t/f )
-    "int" "cairo" "cairo_in_stroke" [ "cairo_t*" "double" "double" ] alien-invoke ;
-
-: cairo_in_fill ( cairo_t x y -- t/f )
-    "int" "cairo" "cairo_in_fill" [ "cairo_t*" "double" "double" ] alien-invoke ;
-
-! rectangular extents
-: cairo_stroke_extents ( cairo_t x1 y1 x2 y2 -- )
-    "void" "cairo" "cairo_stroke_extents" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ;
-
-: cairo_fill_extents ( cairo_t x1 y1 x2 y2 -- )
-    "void" "cairo" "cairo_fill_extents" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ;
-
-! clipping
-: cairo_reset_clip ( cairo_t -- )
-    "void" "cairo" "cairo_reset_clip" [ "cairo_t*" ] alien-invoke ;
-
-: cairo_clip ( cairo_t -- )
-    "void" "cairo" "cairo_clip" [ "cairo_t*" ] alien-invoke ;
-
-: cairo_clip_preserve ( cairo_t -- )
-    "void" "cairo" "cairo_clip_preserve" [ "cairo_t*" ] alien-invoke ;
-
-
-: cairo_pattern_create_linear ( x0 y0 x1 y1 -- cairo_pattern_t )
-    "void*" "cairo" "cairo_pattern_create_linear" [ "double" "double" "double" "double" ] alien-invoke ;
-
-: cairo_pattern_create_radial ( cx0 cy0 radius0 cx1 cy1 radius1 -- cairo_pattern_t )
-    "void*" "cairo" "cairo_pattern_create_radial" [ "double" "double" "double" "double" "double" "double" ] alien-invoke ;
-
-: cairo_pattern_add_color_stop_rgba ( pattern offset red green blue alpha -- status )
-    "uint" "cairo" "cairo_pattern_add_color_stop_rgba" [ "void*" "double" "double" "double" "double" "double" ] alien-invoke ;
-
-: cairo_show_text ( cairo_t msg_utf8 -- )
-    "void" "cairo" "cairo_show_text" [ "cairo_t*" "char*" ] alien-invoke ;
-
-: cairo_text_path ( cairo_t msg_utf8 -- )
-    "void" "cairo" "cairo_text_path" [ "cairo_t*" "char*" ] alien-invoke ;
-
-: cairo_select_font_face ( cairo_t family font_slant font_weight -- )
-    "void" "cairo" "cairo_select_font_face" [ "cairo_t*" "char*" "uint" "uint" ] alien-invoke ;
-
-: cairo_set_font_size ( cairo_t scale -- )
-    "void" "cairo" "cairo_set_font_size" [ "cairo_t*" "double" ] alien-invoke ;
-
-: cairo_set_font_matrix ( cairo_t cairo_matrix_t -- )
-        "void" "cairo" "cairo_set_font_matrix" [ "cairo_t*" "cairo_matrix_t*" ] alien-invoke ;
-
-: cairo_get_font_matrix ( cairo_t cairo_matrix_t -- )
-        "void" "cairo" "cairo_get_font_matrix" [ "cairo_t*" "cairo_matrix_t*" ] alien-invoke ;
-
-FUNCTION: uchar* cairo_image_surface_get_data ( cairo_surface_t* surface ) ;
-FUNCTION: cairo_format_t cairo_image_surface_get_format ( cairo_surface_t* surface ) ;
-FUNCTION: int cairo_image_surface_get_width ( cairo_surface_t* surface ) ;
-FUNCTION: int cairo_image_surface_get_height ( cairo_surface_t* surface ) ;
-FUNCTION: int cairo_image_surface_get_stride ( cairo_surface_t* surface ) ;
-
-! Cairo pdf
-
-: cairo_pdf_surface_create ( filename width height -- surface )
-  "void*" "cairo" "cairo_pdf_surface_create" [ "char*" "double" "double" ] alien-invoke ;
-
-! Missing:
-
-! cairo_public cairo_surface_t *
-! cairo_pdf_surface_create_for_stream (cairo_write_func_t write_func,
-!                                      void              *closure,
-!                                      double             width_in_points,
-!                                      double             height_in_points);
-
-: cairo_pdf_surface_set_size ( surface width height -- )
-  "void" "cairo" "cairo_pdf_surface_set_size" [ "void*" "double" "double" ] alien-invoke ;
-
-! Cairo png
-
-TYPEDEF: void* cairo_write_func_t
-TYPEDEF: void* cairo_read_func_t
-
-FUNCTION: cairo_surface_t* cairo_image_surface_create_from_png ( char* filename ) ;
-
-FUNCTION: cairo_surface_t* cairo_image_surface_create_from_png_stream ( cairo_read_func_t read_func, void* closure ) ;
-
-FUNCTION: cairo_status_t cairo_surface_write_to_png ( cairo_surface_t* surface, char* filename ) ;
-
-FUNCTION: cairo_status_t cairo_surface_write_to_png_stream ( cairo_surface_t* surface, cairo_write_func_t write_func, void* closure ) ;
diff --git a/extra/cairo/ffi/ffi.factor b/extra/cairo/ffi/ffi.factor
new file mode 100644 (file)
index 0000000..d7aa90c
--- /dev/null
@@ -0,0 +1,459 @@
+! Bindings for Cairo library
+!  Copyright (c) 2007 Sampo Vuori
+!    License: http://factorcode.org/license.txt
+
+! Unimplemented:
+!  - most of the font stuff
+!  - most of the matrix stuff
+!  - most of the query functions
+
+
+USING: alien alien.syntax combinators system ;
+
+IN: cairo.ffi
+
+<< "cairo" {
+        { [ win32? ] [ "cairo.dll" ] }
+        ! { [ macosx? ] [ "libcairo.dylib" ] }
+        { [ macosx? ] [ "/opt/local/lib/libcairo.dylib" ] }
+        { [ unix? ] [ "libcairo.so.2" ] }
+  } cond "cdecl" add-library >>
+
+LIBRARY: cairo
+
+TYPEDEF: int cairo_status_t
+C-ENUM:
+    CAIRO_STATUS_SUCCESS
+    CAIRO_STATUS_NO_MEMORY
+    CAIRO_STATUS_INVALID_RESTORE
+    CAIRO_STATUS_INVALID_POP_GROUP
+    CAIRO_STATUS_NO_CURRENT_POINT
+    CAIRO_STATUS_INVALID_MATRIX
+    CAIRO_STATUS_INVALID_STATUS
+    CAIRO_STATUS_NULL_POINTER
+    CAIRO_STATUS_INVALID_STRING
+    CAIRO_STATUS_INVALID_PATH_DATA
+    CAIRO_STATUS_READ_ERROR
+    CAIRO_STATUS_WRITE_ERROR
+    CAIRO_STATUS_SURFACE_FINISHED
+    CAIRO_STATUS_SURFACE_TYPE_MISMATCH
+    CAIRO_STATUS_PATTERN_TYPE_MISMATCH
+    CAIRO_STATUS_INVALID_CONTENT
+    CAIRO_STATUS_INVALID_FORMAT
+    CAIRO_STATUS_INVALID_VISUAL
+    CAIRO_STATUS_FILE_NOT_FOUND
+    CAIRO_STATUS_INVALID_DASH
+    CAIRO_STATUS_INVALID_DSC_COMMENT
+    CAIRO_STATUS_INVALID_INDEX
+    CAIRO_STATUS_CLIP_NOT_REPRESENTABLE
+;
+
+TYPEDEF: int cairo_content_t
+: CAIRO_CONTENT_COLOR HEX: 1000 ;
+: CAIRO_CONTENT_ALPHA HEX: 2000 ;
+: CAIRO_CONTENT_COLOR_ALPHA HEX: 3000 ;
+
+TYPEDEF: int cairo_operator_t
+C-ENUM:
+    CAIRO_OPERATOR_CLEAR
+    CAIRO_OPERATOR_SOURCE
+    CAIRO_OPERATOR_OVER
+    CAIRO_OPERATOR_IN
+    CAIRO_OPERATOR_OUT
+    CAIRO_OPERATOR_ATOP
+    CAIRO_OPERATOR_DEST
+    CAIRO_OPERATOR_DEST_OVER
+    CAIRO_OPERATOR_DEST_IN
+    CAIRO_OPERATOR_DEST_OUT
+    CAIRO_OPERATOR_DEST_ATOP
+    CAIRO_OPERATOR_XOR
+    CAIRO_OPERATOR_ADD
+    CAIRO_OPERATOR_SATURATE
+;
+
+TYPEDEF: int cairo_line_cap_t
+C-ENUM:
+    CAIRO_LINE_CAP_BUTT
+    CAIRO_LINE_CAP_ROUND
+    CAIRO_LINE_CAP_SQUARE
+;
+
+TYPEDEF: int cair_line_join_t
+C-ENUM:
+    CAIRO_LINE_JOIN_MITER
+    CAIRO_LINE_JOIN_ROUND
+    CAIRO_LINE_JOIN_BEVEL
+;
+
+TYPEDEF: int cairo_fill_rule_t
+C-ENUM:
+    CAIRO_FILL_RULE_WINDING
+    CAIRO_FILL_RULE_EVEN_ODD
+;
+
+TYPEDEF: int cairo_font_slant_t
+C-ENUM:
+    CAIRO_FONT_SLANT_NORMAL
+    CAIRO_FONT_SLANT_ITALIC
+    CAIRO_FONT_SLANT_OBLIQUE
+;
+
+TYPEDEF: int cairo_font_weight_t
+C-ENUM:
+    CAIRO_FONT_WEIGHT_NORMAL
+    CAIRO_FONT_WEIGHT_BOLD
+;
+
+C-STRUCT: cairo_font_t
+    { "int" "refcount" }
+    { "uint" "scale" } ;
+
+C-STRUCT: cairo_rectangle_t
+    { "short" "x" }
+    { "short" "y" }
+    { "ushort" "width" }
+    { "ushort" "height" } ;
+
+C-STRUCT: cairo_clip_rec_t
+    { "cairo_rectangle_t" "rect" }
+    { "void*" "region" }
+    { "void*" "surface" } ;
+
+C-STRUCT: cairo_matrix_t
+    { "void*" "m" } ;
+
+C-STRUCT: cairo_gstate_t
+    { "uint" "operator" }
+    { "double" "tolerance" }
+    { "double" "line_width" }
+    { "uint" "line_cap" }
+    { "uint" "line_join" }
+    { "double" "miter_limit" }
+    { "uint" "fill_rule" }
+    { "void*" "dash" }
+    { "int" "num_dashes" }
+    { "double" "dash_offset" }
+    { "char*" "font_family " }
+    { "uint" "font_slant" }
+    { "uint" "font_weight" }
+    { "void*" "font" }
+    { "void*" "surface" }
+    { "void*" "pattern " }
+    { "double" "alpha" }
+    { "cairo_clip_rec_t" "clip" }
+    { "double" "pixels_per_inch" }
+    { "cairo_matrix_t" "font_matrix" }
+    { "cairo_matrix_t" "ctm" }
+    { "cairo_matrix_t" "ctm_inverse" }
+    { "void*" "path" }
+    { "void*" "pen_regular" }
+    { "void*" "next" } ;
+
+C-STRUCT: cairo_t
+    { "uint" "ref_count" }
+    { "cairo_gstate_t*" "gstate" }
+    { "uint" "status ! cairo_status_t" } ;
+
+C-STRUCT: cairo_matrix_t
+        { "double" "xx" }
+        { "double" "yx" }
+        { "double" "xy" }
+        { "double" "yy" }
+        { "double" "x0" }
+        { "double" "y0" } ;
+
+TYPEDEF: int cairo_format_t
+C-ENUM:
+    CAIRO_FORMAT_ARGB32
+    CAIRO_FORMAT_RGB24
+    CAIRO_FORMAT_A8
+    CAIRO_FORMAT_A1
+;
+
+TYPEDEF: int cairo_antialias_t
+C-ENUM:
+    CAIRO_ANTIALIAS_DEFAULT
+    CAIRO_ANTIALIAS_NONE
+    CAIRO_ANTIALIAS_GRAY
+    CAIRO_ANTIALIAS_SUBPIXEL
+;
+
+TYPEDEF: int cairo_subpixel_order_t
+C-ENUM:
+    CAIRO_SUBPIXEL_ORDER_DEFAULT
+    CAIRO_SUBPIXEL_ORDER_RGB
+    CAIRO_SUBPIXEL_ORDER_BGR
+    CAIRO_SUBPIXEL_ORDER_VRGB
+    CAIRO_SUBPIXEL_ORDER_VBGR
+;
+
+TYPEDEF: int cairo_hint_style_t
+C-ENUM:
+    CAIRO_HINT_STYLE_DEFAULT
+    CAIRO_HINT_STYLE_NONE
+    CAIRO_HINT_STYLE_SLIGHT
+    CAIRO_HINT_STYLE_MEDIUM
+    CAIRO_HINT_STYLE_FULL
+;
+
+TYPEDEF: int cairo_hint_metrics_t
+C-ENUM:
+    CAIRO_HINT_METRICS_DEFAULT
+    CAIRO_HINT_METRICS_OFF
+    CAIRO_HINT_METRICS_ON
+;
+
+: cairo_create ( cairo_surface_t -- cairo_t )
+    "cairo_t*" "cairo" "cairo_create" [ "void*" ] alien-invoke ;
+
+: cairo_reference ( cairo_t -- cairo_t )
+        "cairo_t*" "cairo" "cairo_reference" [ "cairo_t*" ] alien-invoke ;
+
+: cairo_destroy ( cairo_t -- )
+    "void" "cairo" "cairo_destroy" [ "cairo_t*" ] alien-invoke ;
+
+: cairo_save ( cairo_t -- )
+        "void" "cairo" "cairo_save" [ "cairo_t*" ] alien-invoke ;
+
+: cairo_restore ( cairo_t -- )
+        "void" "cairo" "cairo_restore" [ "cairo_t*" ] alien-invoke ;
+
+: cairo_set_operator ( cairo_t cairo_operator_t -- )
+    "void" "cairo" "cairo_set_operator" [ "cairo_t*" "int" ] alien-invoke ;
+
+: cairo_set_source ( cairo_t cairo_pattern_t -- )
+    "void" "cairo" "cairo_set_source" [ "cairo_t*" "void*" ] alien-invoke ;
+
+: cairo_set_source_rgb ( cairo_t red green blue -- )
+    "void" "cairo" "cairo_set_source_rgb" [ "cairo_t*" "double" "double" "double" ] alien-invoke ;
+
+: cairo_set_source_rgba ( cairo_t red green blue alpha -- )
+    "void" "cairo" "cairo_set_source_rgb" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ;
+
+: cairo_set_source_surface ( cairo_t cairo_surface_t x y -- )
+    "void" "cairo" "cairo_set_source_surface" [ "cairo_t*" "void*" "double" "double" ] alien-invoke ;
+
+: cairo_set_tolerance ( cairo_t tolerance -- )
+    "void" "cairo" "cairo_set_tolerance" [ "cairo_t*" "double" ] alien-invoke ;
+
+: cairo_image_surface_create_for_data ( data format width height stride -- cairo_surface_t )
+    "void*" "cairo" "cairo_image_surface_create_for_data" [ "void*" "uint" "int" "int" "int" ] alien-invoke ;
+    
+
+: cairo_set_antialias ( cairo_t cairo_antialias_t -- )
+    "void" "cairo" "cairo_set_antialias" [ "cairo_t*" "int" ] alien-invoke ;
+
+: cairo_set_fill_rule ( cairo_t cairo_fill_rule_t -- )
+    "void" "cairo" "cairo_set_fill_rule" [ "cairo_t*" "int" ] alien-invoke ;
+
+: cairo_set_line_width ( cairo_t width -- )
+    "void" "cairo" "cairo_set_line_width" [ "cairo_t*" "double" ] alien-invoke ;
+
+: cairo_set_line_cap ( cairo_t cairo_line_cap_t -- )
+    "void" "cairo" "cairo_set_line_cap" [ "cairo_t*" "int" ] alien-invoke ;
+
+: cairo_set_line_join ( cairo_t cairo_line_join_t -- )
+    "void" "cairo" "cairo_set_line_join" [ "cairo_t*" "int" ] alien-invoke ;
+
+: cairo_set_dash ( cairo_t dashes num_dashes offset -- )
+    "void" "cairo" "cairo_set_dash" [ "cairo_t*" "double" "int" "double" ] alien-invoke ;
+
+: cairo_set_miter_limit ( cairo_t limit -- )
+    "void" "cairo" "cairo_set_miter_limit" [ "cairo_t*" "double" ] alien-invoke ;
+
+: cairo_translate ( cairo_t x y -- )
+    "void" "cairo" "cairo_translate" [ "cairo_t*" "double" "double" ] alien-invoke ;
+
+: cairo_scale ( cairo_t sx sy -- )
+    "void" "cairo" "cairo_scale" [ "cairo_t*" "double" "double" ] alien-invoke ;
+
+: cairo_rotate ( cairo_t angle -- )
+    "void" "cairo" "cairo_rotate" [ "cairo_t*" "double" ] alien-invoke ;
+
+: cairo_transform ( cairo_t cairo_matrix_t -- )
+        "void" "cairo" "cairo_transform" [ "cairo_t*" "cairo_matrix_t*" ] alien-invoke ;
+
+: cairo_set_matrix ( cairo_t cairo_matrix_t -- )
+        "void" "cairo" "cairo_set_matrix" [ "cairo_t*" "cairo_matrix_t*" ] alien-invoke ;
+
+: cairo_identity_matrix ( cairo_t -- )
+        "void" "cairo" "cairo_identity_matrix" [ "cairo_t*" ] alien-invoke ;
+
+! cairo path creating functions
+
+: cairo_new_path ( cairo_t -- )
+    "void" "cairo" "cairo_new_path" [ "cairo_t*" ] alien-invoke ;
+
+: cairo_move_to ( cairo_t x y -- )
+    "void" "cairo" "cairo_move_to" [ "cairo_t*" "double" "double" ] alien-invoke ;
+
+: cairo_new_sub_path ( cairo_t -- )
+    "void" "cairo" "cairo_new_sub_path" [ "cairo_t*" ] alien-invoke ;
+    
+: cairo_line_to ( cairo_t x y -- )
+    "void" "cairo" "cairo_line_to" [ "cairo_t*" "double" "double" ] alien-invoke ;
+
+: cairo_curve_to ( cairo_t x1 y1 x2 y2 x3 y3 -- )
+    "void" "cairo" "cairo_curve_to" [ "cairo_t*" "double" "double" "double" "double" "double" "double" ] alien-invoke ;
+
+: cairo_arc ( cairo_t xc yc radius angle1 angle2 -- )
+    "void" "cairo" "cairo_arc" [ "cairo_t*" "double" "double" "double" "double" "double" ] alien-invoke ;
+
+: cairo_arc_negative ( cairo_t xc yc radius angle1 angle2 -- )
+    "void" "cairo" "cairo_arc_negative" [ "cairo_t*" "double" "double" "double" "double" "double" ] alien-invoke ;
+    
+: cairo_rel_move_to ( cairo_t dx dy -- )
+    "void" "cairo" "cairo_rel_move_to" [ "cairo_t*" "double" "double" ] alien-invoke ;
+    
+: cairo_rel_line_to ( cairo_t dx dy -- )
+    "void" "cairo" "cairo_rel_line_to" [ "cairo_t*" "double" "double" ] alien-invoke ;
+
+: cairo_rel_curve_to ( cairo_t dx1 dy1 dx2 dy2 dx3 dy3 -- )
+    "void" "cairo" "cairo_rel_curve_to" [ "cairo_t*" "double" "double" "double" "double" "double" "double" ] alien-invoke ;
+
+: cairo_rectangle ( cairo_t x y width height -- )
+    "void" "cairo" "cairo_rectangle" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ;
+
+: cairo_close_path ( cairo_t -- )
+    "void" "cairo" "cairo_close_path" [ "cairo_t*" ] alien-invoke ;
+
+! Surface manipulation
+
+: cairo_surface_create_similar ( cairo_surface_t cairo_content_t width height -- cairo_surface_t )
+    "cairo_surface_t*" "cairo" "cairo_surface_create_similar" [ "cairo_surface_t*" "uint" "int" "int" ] alien-invoke ;
+
+: cairo_surface_reference ( cairo_surface_t -- cairo_surface_t )
+    "cairo_surface_t*" "cairo" "cairo_surface_reference" [ "cairo_surface_t*" ] alien-invoke ;
+
+: cairo_surface_finish ( cairo_surface_t -- )
+    "void" "cairo" "cairo_surface_finish" [ "cairo_surface_t*" ] alien-invoke ;
+
+: cairo_surface_destroy ( cairo_surface_t -- )
+    "void" "cairo" "cairo_surface_destroy" [ "cairo_surface_t*" ] alien-invoke ;
+
+: cairo_surface_get_reference_count ( cairo_surface_t -- count )
+    "uint" "cairo" "cairo_surface_get_reference_count" [ "cairo_surface_t*" ] alien-invoke ;
+
+: cairo_surface_status ( cairo_surface_t -- cairo_status_t )
+    "uint" "cairo" "cairo_surface_status" [ "cairo_surface_t*" ] alien-invoke ;
+
+: cairo_surface_flush ( cairo_surface_t -- )
+    "void" "cairo" "cairo_surface_flush" [ "cairo_surface_t*" ] alien-invoke ;
+
+! painting functions
+: cairo_paint ( cairo_t -- )
+    "void" "cairo" "cairo_paint" [ "cairo_t*" ] alien-invoke ;
+
+: cairo_paint_with_alpha ( cairo_t alpha -- )
+    "void" "cairo" "cairo_paint_with_alpha" [ "cairo_t*" "double" ] alien-invoke ;
+
+: cairo_mask ( cairo_t cairo_pattern_t -- )
+    "void" "cairo" "cairo_mask" [ "cairo_t*" "void*" ] alien-invoke ;
+
+: cairo_mask_surface ( cairo_t cairo_pattern_t surface-x surface-y -- )
+    "void" "cairo" "cairo_mask_surface" [ "cairo_t*" "void*" "double" "double" ] alien-invoke ;
+
+: cairo_stroke ( cairo_t -- )
+    "void" "cairo" "cairo_stroke" [ "cairo_t*" ] alien-invoke ;
+
+: cairo_stroke_preserve ( cairo_t -- )
+    "void" "cairo" "cairo_stroke_preserve" [ "cairo_t*" ] alien-invoke ;
+
+: cairo_fill ( cairo_t -- )
+    "void" "cairo" "cairo_fill" [ "cairo_t*" ] alien-invoke ;
+
+: cairo_fill_preserve ( cairo_t -- )
+    "void" "cairo" "cairo_fill_preserve" [ "cairo_t*" ] alien-invoke ;
+
+: cairo_copy_page ( cairo_t -- )
+    "void" "cairo" "cairo_copy_page" [ "cairo_t*" ] alien-invoke ;
+
+: cairo_show_page ( cairo_t -- )
+    "void" "cairo" "cairo_show_page" [ "cairo_t*" ] alien-invoke ;
+
+! insideness testing
+: cairo_in_stroke ( cairo_t x y -- t/f )
+    "int" "cairo" "cairo_in_stroke" [ "cairo_t*" "double" "double" ] alien-invoke ;
+
+: cairo_in_fill ( cairo_t x y -- t/f )
+    "int" "cairo" "cairo_in_fill" [ "cairo_t*" "double" "double" ] alien-invoke ;
+
+! rectangular extents
+: cairo_stroke_extents ( cairo_t x1 y1 x2 y2 -- )
+    "void" "cairo" "cairo_stroke_extents" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ;
+
+: cairo_fill_extents ( cairo_t x1 y1 x2 y2 -- )
+    "void" "cairo" "cairo_fill_extents" [ "cairo_t*" "double" "double" "double" "double" ] alien-invoke ;
+
+! clipping
+: cairo_reset_clip ( cairo_t -- )
+    "void" "cairo" "cairo_reset_clip" [ "cairo_t*" ] alien-invoke ;
+
+: cairo_clip ( cairo_t -- )
+    "void" "cairo" "cairo_clip" [ "cairo_t*" ] alien-invoke ;
+
+: cairo_clip_preserve ( cairo_t -- )
+    "void" "cairo" "cairo_clip_preserve" [ "cairo_t*" ] alien-invoke ;
+
+
+: cairo_pattern_create_linear ( x0 y0 x1 y1 -- cairo_pattern_t )
+    "void*" "cairo" "cairo_pattern_create_linear" [ "double" "double" "double" "double" ] alien-invoke ;
+
+: cairo_pattern_create_radial ( cx0 cy0 radius0 cx1 cy1 radius1 -- cairo_pattern_t )
+    "void*" "cairo" "cairo_pattern_create_radial" [ "double" "double" "double" "double" "double" "double" ] alien-invoke ;
+
+: cairo_pattern_add_color_stop_rgba ( pattern offset red green blue alpha -- status )
+    "uint" "cairo" "cairo_pattern_add_color_stop_rgba" [ "void*" "double" "double" "double" "double" "double" ] alien-invoke ;
+
+: cairo_show_text ( cairo_t msg_utf8 -- )
+    "void" "cairo" "cairo_show_text" [ "cairo_t*" "char*" ] alien-invoke ;
+
+: cairo_text_path ( cairo_t msg_utf8 -- )
+    "void" "cairo" "cairo_text_path" [ "cairo_t*" "char*" ] alien-invoke ;
+
+: cairo_select_font_face ( cairo_t family font_slant font_weight -- )
+    "void" "cairo" "cairo_select_font_face" [ "cairo_t*" "char*" "uint" "uint" ] alien-invoke ;
+
+: cairo_set_font_size ( cairo_t scale -- )
+    "void" "cairo" "cairo_set_font_size" [ "cairo_t*" "double" ] alien-invoke ;
+
+: cairo_set_font_matrix ( cairo_t cairo_matrix_t -- )
+        "void" "cairo" "cairo_set_font_matrix" [ "cairo_t*" "cairo_matrix_t*" ] alien-invoke ;
+
+: cairo_get_font_matrix ( cairo_t cairo_matrix_t -- )
+        "void" "cairo" "cairo_get_font_matrix" [ "cairo_t*" "cairo_matrix_t*" ] alien-invoke ;
+
+FUNCTION: uchar* cairo_image_surface_get_data ( cairo_surface_t* surface ) ;
+FUNCTION: cairo_format_t cairo_image_surface_get_format ( cairo_surface_t* surface ) ;
+FUNCTION: int cairo_image_surface_get_width ( cairo_surface_t* surface ) ;
+FUNCTION: int cairo_image_surface_get_height ( cairo_surface_t* surface ) ;
+FUNCTION: int cairo_image_surface_get_stride ( cairo_surface_t* surface ) ;
+
+! Cairo pdf
+
+: cairo_pdf_surface_create ( filename width height -- surface )
+  "void*" "cairo" "cairo_pdf_surface_create" [ "char*" "double" "double" ] alien-invoke ;
+
+! Missing:
+
+! cairo_public cairo_surface_t *
+! cairo_pdf_surface_create_for_stream (cairo_write_func_t write_func,
+!                                      void              *closure,
+!                                      double             width_in_points,
+!                                      double             height_in_points);
+
+: cairo_pdf_surface_set_size ( surface width height -- )
+  "void" "cairo" "cairo_pdf_surface_set_size" [ "void*" "double" "double" ] alien-invoke ;
+
+! Cairo png
+
+TYPEDEF: void* cairo_write_func_t
+TYPEDEF: void* cairo_read_func_t
+
+FUNCTION: cairo_surface_t* cairo_image_surface_create_from_png ( char* filename ) ;
+
+FUNCTION: cairo_surface_t* cairo_image_surface_create_from_png_stream ( cairo_read_func_t read_func, void* closure ) ;
+
+FUNCTION: cairo_status_t cairo_surface_write_to_png ( cairo_surface_t* surface, char* filename ) ;
+
+FUNCTION: cairo_status_t cairo_surface_write_to_png_stream ( cairo_surface_t* surface, cairo_write_func_t write_func, void* closure ) ;
diff --git a/extra/cairo/lib/lib.factor b/extra/cairo/lib/lib.factor
new file mode 100644 (file)
index 0000000..9e226ee
--- /dev/null
@@ -0,0 +1,40 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.c-types cairo.ffi continuations destructors
+kernel libc locals math combinators.cleave shuffle new-slots
+accessors ;
+IN: cairo.lib
+
+TUPLE: cairo-t alien ;
+C: <cairo-t> cairo-t
+M: cairo-t dispose ( alien -- ) alien>> cairo_destroy ;
+: cairo-t-destroy-always ( alien -- ) <cairo-t> add-always-destructor ;
+: cairo-t-destroy-later ( alien -- ) <cairo-t> add-error-destructor ;
+    
+TUPLE: cairo-surface-t alien ;
+C: <cairo-surface-t> cairo-surface-t
+M: cairo-surface-t dispose ( alien -- ) alien>> cairo_surface_destroy ;
+
+: cairo-surface-t-destroy-always ( alien -- )
+    <cairo-surface-t> add-always-destructor ;
+
+: cairo-surface-t-destroy-later ( alien -- )
+    <cairo-surface-t> add-error-destructor ;
+
+: cairo-surface>array ( surface -- cairo-t byte-array )
+    [
+        dup
+        [ drop CAIRO_FORMAT_ARGB32 ]
+        [ cairo_image_surface_get_width ]
+        [ cairo_image_surface_get_height ] tri
+        over 4 *
+        2dup * [
+            malloc dup free-always [
+                5 -nrot cairo_image_surface_create_for_data
+                dup cairo-surface-t-destroy-always
+                cairo_create dup cairo-t-destroy-later
+                [ swap 0 0 cairo_set_source_surface ] keep
+                dup cairo_paint
+            ] keep
+        ] keep memory>byte-array
+    ] with-destructors ;
diff --git a/extra/cairo/png/png.factor b/extra/cairo/png/png.factor
new file mode 100644 (file)
index 0000000..b9da140
--- /dev/null
@@ -0,0 +1,45 @@
+! Copyright (C) 2008 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays combinators.cleave kernel new-slots
+accessors math ui.gadgets ui.render opengl.gl byte-arrays
+namespaces opengl cairo.ffi cairo.lib ;
+IN: cairo.png
+
+TUPLE: png surface width height cairo-t array ;
+TUPLE: png-gadget png ;
+
+: <png> ( path -- png )
+    cairo_image_surface_create_from_png
+    dup [ cairo_image_surface_get_width ]
+    [ cairo_image_surface_get_height ] [ ] tri
+    cairo-surface>array png construct-boa ;
+
+: write-png ( png path -- )
+    >r png-surface r>
+    cairo_surface_write_to_png
+    zero? [ "write png failed" throw ] unless ;
+
+: <png-gadget> ( path -- gadget )
+    png-gadget construct-gadget swap
+    <png> >>png ;
+
+M: png-gadget pref-dim* ( gadget -- )
+    png>>
+    [ width>> ] [ height>> ] bi 2array ;
+
+M: png-gadget draw-gadget* ( gadget -- )
+    origin get [
+        0 0 glRasterPos2i
+        1.0 -1.0 glPixelZoom
+        png>>
+        [ width>> ]
+        [ height>> GL_RGBA GL_UNSIGNED_BYTE ]
+        [ array>> ] tri
+        glDrawPixels
+    ] with-translation ;
+
+M: png-gadget graft* ( gadget -- )
+    drop ;
+
+M: png-gadget ungraft* ( gadget -- )
+    png>> surface>> cairo_destroy ;
index fd66536c127f2691579120eb30118c8bdb4772a8..049c8bf2a94245db39e587569c6992cef494ad6e 100644 (file)
@@ -70,3 +70,29 @@ MACRO: spread ( seq -- )
   swap
     [ [ r> ] swap append ] map concat
   append ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! Cleave into array
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+USING: words quotations fry arrays.lib ;
+
+: >quot ( obj -- quot ) dup word? [ 1quotation ] when ;
+
+: >quots ( seq -- seq ) [ >quot ] map ;
+
+MACRO: <arr> ( seq -- )
+  [ >quots ] [ length ] bi
+ '[ , cleave , narray ] ;
+
+MACRO: <2arr> ( seq -- )
+  [ >quots ] [ length ] bi
+ '[ , 2cleave , narray ] ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! Spread into array
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+MACRO: <arr*> ( seq -- )
+  [ >quots ] [ length ] bi
+ '[ , spread , narray ] ;
diff --git a/extra/db/db-tests.factor b/extra/db/db-tests.factor
new file mode 100755 (executable)
index 0000000..9c32f9e
--- /dev/null
@@ -0,0 +1,5 @@
+IN: db.tests\r
+USING: tools.test db kernel ;\r
+\r
+{ 1 0 } [ [ drop ] query-each ] must-infer-as\r
+{ 1 1 } [ [ ] query-map ] must-infer-as\r
index 309847209f6c4b87999652b36ff0d8fe73a48f1c..ac46be4422eef06f9fd56cc19999f9136e2adc73 100755 (executable)
@@ -33,6 +33,19 @@ HOOK: db-close db ( handle -- )
 TUPLE: statement handle sql in-params out-params bind-params bound? ;
 TUPLE: simple-statement ;
 TUPLE: prepared-statement ;
+TUPLE: nonthrowable-statement ;
+: make-nonthrowable ( obj -- obj' )
+    dup sequence? [
+        [ make-nonthrowable ] map
+    ] [
+        nonthrowable-statement construct-delegate
+    ] if ;
+
+MIXIN: throwable-statement
+INSTANCE: statement throwable-statement
+INSTANCE: simple-statement throwable-statement
+INSTANCE: prepared-statement throwable-statement
+
 TUPLE: result-set sql in-params out-params handle n max ;
 : <statement> ( sql in out -- statement )
     { (>>sql) (>>in-params) (>>out-params) } statement construct ;
@@ -50,13 +63,22 @@ GENERIC# row-column-typed 1 ( result-set column -- sql )
 GENERIC: advance-row ( result-set -- )
 GENERIC: more-rows? ( result-set -- ? )
 
-: execute-statement ( statement -- )
+GENERIC: execute-statement ( statement -- )
+
+M: throwable-statement execute-statement ( statement -- )
     dup sequence? [
         [ execute-statement ] each
     ] [
         query-results dispose
     ] if ;
 
+M: nonthrowable-statement execute-statement ( statement -- )
+    dup sequence? [
+        [ execute-statement ] each
+    ] [
+        [ query-results dispose ] [ 2drop ] recover
+    ] if ;
+
 : bind-statement ( obj statement -- )
     swap >>bind-params
     [ bind-statement* ] keep
index b48c87f0cad9b00ae8079ed092d339867bdefe84..928b51dc59fe2489161f8e83e265eb500d30dd0e 100755 (executable)
@@ -73,7 +73,7 @@ IN: db.postgresql.lib
         sql-spec-type {
             { FACTOR-BLOB [
                 dup [
-                    binary [ serialize ] with-byte-writer
+                    object>bytes
                     malloc-byte-array/length ] [ 0 ] if ] }
             { BLOB [
                 dup [ malloc-byte-array/length ] [ 0 ] if ] }
@@ -164,7 +164,7 @@ M: postgresql-malloc-destructor dispose ( obj -- )
         { BLOB [ pq-get-blob ] }
         { FACTOR-BLOB [
             pq-get-blob
-            dup [ binary [ deserialize ] with-byte-reader ] when ] }
+            dup [ bytes>object ] when ] }
         [ no-sql-type ]
     } case ;
     ! PQgetlength PQgetisnull
index 26b6cbe75c49e631bce7be4cb70acba874a28c4f..8a6f8632ec134ee5e3cae9283183258b490359fb 100755 (executable)
@@ -10,6 +10,7 @@ IN: db.postgresql
 
 TUPLE: postgresql-db host port pgopts pgtty db user pass ;
 TUPLE: postgresql-statement ;
+INSTANCE: postgresql-statement throwable-statement
 TUPLE: postgresql-result-set ;
 : <postgresql-statement> ( statement in out -- postgresql-statement )
     <statement>
@@ -119,8 +120,8 @@ M: postgresql-db bind% ( spec -- )
 
 : postgresql-make ( class quot -- )
     >r sql-props r>
-    [ postgresql-counter off ] swap compose
-    { "" { } { } } nmake <postgresql-statement> ;
+    [ postgresql-counter off call ] { "" { } { } } nmake
+    <postgresql-statement> ; inline
 
 : create-table-sql ( class -- statement )
     [
@@ -194,7 +195,7 @@ M: postgresql-db <insert-native-statement> ( class -- statement )
         ");" 0%
     ] postgresql-make ;
 
-M: postgresql-db <insert-assigned-statement> ( class -- statement )
+M: postgresql-db <insert-nonnative-statement> ( class -- statement )
     [
         "insert into " 0% 0%
         "(" 0%
index 63bce0a8c3520250cc0b316c6ae506b6ad833b07..1d356b15921a4f6f0ca8daeb592156d1326b858e 100755 (executable)
@@ -127,6 +127,6 @@ FUNCTION: char* sqlite3_column_decltype ( sqlite3_stmt* pStmt, int col ) ;
 FUNCTION: int sqlite3_column_int ( sqlite3_stmt* pStmt, int col ) ;
 FUNCTION: sqlite3_int64 sqlite3_column_int64 ( sqlite3_stmt* pStmt, int col ) ;
 FUNCTION: double sqlite3_column_double ( sqlite3_stmt* pStmt, int col ) ;
-FUNCTION: int sqlite3_column_name ( sqlite3_stmt* pStmt, int col ) ;
+FUNCTION: char* sqlite3_column_name ( sqlite3_stmt* pStmt, int col ) ;
 FUNCTION: char* sqlite3_column_text ( sqlite3_stmt* pStmt, int col ) ;
 FUNCTION: int sqlite3_column_type ( sqlite3_stmt* pStmt, int col ) ;
index dbada854fbff974632a76cce672e971cb5554f1b..f81d7de4b820a2ee358e189055c919cff1909821 100755 (executable)
@@ -94,7 +94,7 @@ IN: db.sqlite.lib
         { TIMESTAMP [ sqlite-bind-text-by-name ] }
         { BLOB [ sqlite-bind-blob-by-name ] }
         { FACTOR-BLOB [
-            binary [ serialize ] with-byte-writer
+            object>bytes
             sqlite-bind-blob-by-name
         ] }
         { +native-id+ [ sqlite-bind-int-by-name ] }
@@ -102,17 +102,12 @@ IN: db.sqlite.lib
         [ no-sql-type ]
     } case ;
 
-: sqlite-finalize ( handle -- )
-    sqlite3_finalize sqlite-check-result ;
-
-: sqlite-reset ( handle -- )
-    sqlite3_reset sqlite-check-result ;
-
-: sqlite-#columns ( query -- int )
-    sqlite3_column_count ;
-
-: sqlite-column ( handle index -- string )
-    sqlite3_column_text ;
+: sqlite-finalize ( handle -- ) sqlite3_finalize sqlite-check-result ;
+: sqlite-reset ( handle -- ) sqlite3_reset sqlite-check-result ;
+: sqlite-#columns ( query -- int ) sqlite3_column_count ;
+: sqlite-column ( handle index -- string ) sqlite3_column_text ;
+: sqlite-column-name ( handle index -- string ) sqlite3_column_name ;
+: sqlite-column-type ( handle index -- string ) sqlite3_column_type ;
 
 : sqlite-column-blob ( handle index -- byte-array/f )
     [ sqlite3_column_bytes ] 2keep
@@ -126,6 +121,7 @@ IN: db.sqlite.lib
     dup array? [ first ] when
     {
         { +native-id+ [ sqlite3_column_int64 ] }
+        { +random-id+ [ sqlite3_column_int64 ] }
         { INTEGER [ sqlite3_column_int ] }
         { BIG-INTEGER [ sqlite3_column_int64 ] }
         { DOUBLE [ sqlite3_column_double ] }
@@ -138,7 +134,7 @@ IN: db.sqlite.lib
         { BLOB [ sqlite-column-blob ] }
         { FACTOR-BLOB [
             sqlite-column-blob
-            dup [ binary [ deserialize ] with-byte-reader ] when
+            dup [ bytes>object ] when
         ] }
         ! { NULL [ 2drop f ] }
         [ no-sql-type ]
@@ -147,7 +143,7 @@ IN: db.sqlite.lib
 : sqlite-row ( handle -- seq )
     dup sqlite-#columns [ sqlite-column ] with map ;
 
-: sqlite-step-has-more-rows? ( step-result -- bool )
+: sqlite-step-has-more-rows? ( prepared -- bool )
     dup SQLITE_ROW =  [
         drop t
     ] [
index b72d7886052ab05386257ffd5e91c6f8aa52df6a..bca904279b48129e85303272c7a48ee4cb010825 100755 (executable)
@@ -6,6 +6,7 @@ prettyprint sequences strings tuples alien.c-types
 continuations db.sqlite.lib db.sqlite.ffi db.tuples
 words combinators.lib db.types combinators
 combinators.cleave io namespaces.lib ;
+USE: tools.walker
 IN: db.sqlite
 
 TUPLE: sqlite-db path ;
@@ -17,15 +18,12 @@ M: sqlite-db db-open ( db -- )
     dup sqlite-db-path sqlite-open <db>
     swap set-delegate ;
 
-M: sqlite-db db-close ( handle -- )
-    sqlite-close ;
-
+M: sqlite-db db-close ( handle -- ) sqlite-close ;
 M: sqlite-db dispose ( db -- ) dispose-db ;
-
-: with-sqlite ( path quot -- )
-    sqlite-db swap with-db ; inline
+: with-sqlite ( path quot -- ) sqlite-db swap with-db ; inline
 
 TUPLE: sqlite-statement ;
+INSTANCE: sqlite-statement throwable-statement
 
 TUPLE: sqlite-result-set has-more? ;
 
@@ -38,12 +36,20 @@ M: sqlite-db <prepared-statement> ( str in out -- obj )
         set-statement-in-params
         set-statement-out-params
     } statement construct
-    db get db-handle over statement-sql sqlite-prepare
-    over set-statement-handle
     sqlite-statement construct-delegate ;
 
+: sqlite-maybe-prepare ( statement -- statement )
+    dup statement-handle [
+        [
+            delegate
+            db get db-handle over statement-sql sqlite-prepare
+            swap set-statement-handle
+        ] keep
+    ] unless ;
+
 M: sqlite-statement dispose ( statement -- )
-    statement-handle sqlite-finalize ;
+    statement-handle
+    [ [ sqlite3_reset drop ] keep sqlite-finalize ] when* ;
 
 M: sqlite-result-set dispose ( result-set -- )
     f swap set-result-set-handle ;
@@ -52,9 +58,11 @@ M: sqlite-result-set dispose ( result-set -- )
     swap [ first3 sqlite-bind-type ] with each ;
 
 : reset-statement ( statement -- )
+    sqlite-maybe-prepare
     statement-handle sqlite-reset ;
 
 M: sqlite-statement bind-statement* ( statement -- )
+    sqlite-maybe-prepare
     dup statement-bound? [ dup reset-statement ] when
     [ statement-bind-params ] [ statement-handle ] bi
     sqlite-bind ;
@@ -95,21 +103,17 @@ M: sqlite-result-set more-rows? ( result-set -- ? )
     sqlite-result-set-has-more? ;
 
 M: sqlite-statement query-results ( query -- result-set )
+    sqlite-maybe-prepare
     dup statement-handle sqlite-result-set <result-set>
     dup advance-row ;
 
-M: sqlite-db begin-transaction ( -- )
-    "BEGIN" sql-command ;
-
-M: sqlite-db commit-transaction ( -- )
-    "COMMIT" sql-command ;
-
-M: sqlite-db rollback-transaction ( -- )
-    "ROLLBACK" sql-command ;
+M: sqlite-db begin-transaction ( -- ) "BEGIN" sql-command ;
+M: sqlite-db commit-transaction ( -- ) "COMMIT" sql-command ;
+M: sqlite-db rollback-transaction ( -- ) "ROLLBACK" sql-command ;
 
 : sqlite-make ( class quot -- )
     >r sql-props r>
-    { "" { } { } } nmake <simple-statement> ;
+    { "" { } { } } nmake <simple-statement> ; inline
 
 M: sqlite-db create-sql-statement ( class -- statement )
     [
@@ -123,9 +127,7 @@ M: sqlite-db create-sql-statement ( class -- statement )
     ] sqlite-make ;
 
 M: sqlite-db drop-sql-statement ( class -- statement )
-    [
-        "drop table " 0% 0% ";" 0% drop
-    ] sqlite-make ;
+    [ "drop table " 0% 0% ";" 0% drop ] sqlite-make ;
 
 M: sqlite-db <insert-native-statement> ( tuple -- statement )
     [
@@ -138,7 +140,7 @@ M: sqlite-db <insert-native-statement> ( tuple -- statement )
         ");" 0%
     ] sqlite-make ;
 
-M: sqlite-db <insert-assigned-statement> ( tuple -- statement )
+M: sqlite-db <insert-nonnative-statement> ( tuple -- statement )
     <insert-native-statement> ;
 
 : where-primary-key% ( specs -- )
@@ -188,6 +190,8 @@ M: sqlite-db modifier-table ( -- hashtable )
     H{
         { +native-id+ "primary key" }
         { +assigned-id+ "primary key" }
+        { +random-id+ "primary key" }
+        ! { +nonnative-id+ "primary key" }
         { +autoincrement+ "autoincrement" }
         { +unique+ "unique" }
         { +default+ "default" }
@@ -195,10 +199,9 @@ M: sqlite-db modifier-table ( -- hashtable )
         { +not-null+ "not null" }
     } ;
 
-M: sqlite-db compound-modifier ( str obj -- newstr )
-    compound-type ;
+M: sqlite-db compound-modifier ( str obj -- str' ) compound-type ;
 
-M: sqlite-db compound-type ( str seq -- newstr )
+M: sqlite-db compound-type ( str seq -- str' )
     over {
         { "default" [ first number>string join-space ] }
         [ 2drop ] !  "no sqlite compound data type" 3array throw ]
@@ -207,6 +210,7 @@ M: sqlite-db compound-type ( str seq -- newstr )
 M: sqlite-db type-table ( -- assoc )
     H{
         { +native-id+ "integer primary key" }
+        { +random-id+ "integer primary key" }
         { INTEGER "integer" }
         { TEXT "text" }
         { VARCHAR "text" }
@@ -219,5 +223,4 @@ M: sqlite-db type-table ( -- assoc )
         { FACTOR-BLOB "blob" }
     } ;
 
-M: sqlite-db create-type-table
-    type-table ;
+M: sqlite-db create-type-table ( symbol -- str ) type-table ;
index 4c47066d35a0eb47058c89e59b079ee059f3c581..6b61981119d1c9f56ceb4304fd526da52c80ee21 100755 (executable)
@@ -9,7 +9,7 @@ IN: db.tuples.tests
 TUPLE: person the-id the-name the-number the-real
 ts date time blob factor-blob ;
 
-: <person> ( name age real ts date time blob -- person )
+: <person> ( name age real ts date time blob factor-blob -- person )
     {
         set-person-the-name
         set-person-the-number
@@ -190,11 +190,11 @@ TUPLE: annotation n paste-id summary author mode contents ;
 : test-postgresql ( -- )
 >r { "localhost" "postgres" "foob" "factor-test" } postgresql-db r> with-db ;
 
-[ native-person-schema test-tuples ] test-sqlite
-[ assigned-person-schema test-tuples ] test-sqlite
-
-! [ native-person-schema test-tuples ] test-postgresql
-! [ assigned-person-schema test-tuples ] test-postgresql
+: test-repeated-insert
+    [ ] [ person ensure-table ] unit-test
+    
+    [ ] [ person1 get insert-tuple ] unit-test
+    [ person1 get insert-tuple ] must-fail ;
 
 TUPLE: serialize-me id data ;
 
@@ -239,3 +239,34 @@ TUPLE: exam id name score ;
     ;
 
 ! [ test-ranges ] test-sqlite
+
+TUPLE: secret n message ;
+C: <secret> secret
+
+: test-random-id
+    secret "SECRET"
+    {
+        { "n" "ID" +random-id+ }
+        { "message" "MESSAGE" TEXT }
+    } define-persistent
+
+    [ ] [ secret ensure-table ] unit-test
+    [ ] [ f "kilroy was here" <secret> insert-tuple ] unit-test
+    [ ] [ T{ secret } select-tuples ] unit-test
+    ;
+
+
+
+! [ test-random-id ] test-sqlite
+ [ native-person-schema test-tuples ] test-sqlite
+ [ assigned-person-schema test-tuples ] test-sqlite
+! [ assigned-person-schema test-repeated-insert ] test-sqlite
+! [ native-person-schema test-tuples ] test-postgresql
+! [ assigned-person-schema test-tuples ] test-postgresql
+! [ assigned-person-schema test-repeated-insert ] test-postgresql
+
+! \ insert-tuple must-infer
+! \ update-tuple must-infer
+! \ delete-tuple must-infer
+! \ select-tuple must-infer
+! \ define-persistent must-infer
index 82147a2efa5a1b0ad18a790102bb6fb8a8a43acd..0f69b0fafb823d2e69159a0ec60e23b1f373f1be 100755 (executable)
@@ -28,7 +28,7 @@ HOOK: create-sql-statement db ( class -- obj )
 HOOK: drop-sql-statement db ( class -- obj )
 
 HOOK: <insert-native-statement> db ( class -- obj )
-HOOK: <insert-assigned-statement> db ( class -- obj )
+HOOK: <insert-nonnative-statement> db ( class -- obj )
 
 HOOK: <update-tuple-statement> db ( class -- obj )
 HOOK: <update-tuples-statement> db ( class -- obj )
@@ -36,7 +36,7 @@ HOOK: <update-tuples-statement> db ( class -- obj )
 HOOK: <delete-tuple-statement> db ( class -- obj )
 HOOK: <delete-tuples-statement> db ( class -- obj )
 
-HOOK: <select-by-slots-statement> db ( tuple -- tuple )
+HOOK: <select-by-slots-statement> db ( tuple class -- tuple )
 
 HOOK: insert-tuple* db ( tuple statement -- )
 
@@ -75,21 +75,25 @@ HOOK: insert-tuple* db ( tuple statement -- )
     drop-sql-statement [ execute-statement ] with-disposals ;
 
 : ensure-table ( class -- )
-    [ dup drop-table ] ignore-errors create-table ;
+    [
+        drop-sql-statement make-nonthrowable
+        [ execute-statement ] with-disposals
+    ] [ create-table ] bi ;
 
 : insert-native ( tuple -- )
     dup class
     db get db-insert-statements [ <insert-native-statement> ] cache
     [ bind-tuple ] 2keep insert-tuple* ;
 
-: insert-assigned ( tuple -- )
+: insert-nonnative ( tuple -- )
+! TODO logic here for unique ids
     dup class
-    db get db-insert-statements [ <insert-assigned-statement> ] cache
+    db get db-insert-statements [ <insert-nonnative-statement> ] cache
     [ bind-tuple ] keep execute-statement ;
 
 : insert-tuple ( tuple -- )
-    dup class db-columns find-primary-key assigned-id? [
-        insert-assigned
+    dup class db-columns find-primary-key nonnative-id? [
+        insert-nonnative
     ] [
         insert-native
     ] if ;
index 7014aaa943b62bee421eccce59f33515633c796b..a0414f334d9f84e0fb2e2f1d06ebe561175324fe 100755 (executable)
@@ -3,7 +3,8 @@
 USING: arrays assocs db kernel math math.parser
 sequences continuations sequences.deep sequences.lib
 words namespaces tools.walker slots slots.private classes
-mirrors tuples combinators calendar.format symbols ;
+mirrors tuples combinators calendar.format symbols
+singleton ;
 IN: db.types
 
 HOOK: modifier-table db ( -- hash )
@@ -14,22 +15,30 @@ HOOK: compound-type db ( str n -- hash )
 
 TUPLE: sql-spec class slot-name column-name type modifiers primary-key ;
 
-SYMBOLS: +native-id+ +assigned-id+ +autoincrement+
-+serial+ +unique+ +default+ +null+ +not-null+
-+foreign-id+ +has-many+ ;
+SINGLETON: +native-id+
+SINGLETON: +assigned-id+
+SINGLETON: +random-id+
+UNION: +primary-key+ +native-id+ +assigned-id+ +random-id+ ;
+UNION: +nonnative-id+ +random-id+ +assigned-id+ ;
 
-: (primary-key?) ( obj -- ? )
-    { +native-id+ +assigned-id+ } member? ;
+SYMBOLS: +autoincrement+ +serial+ +unique+ +default+ +null+ +not-null+
++foreign-id+ +has-many+ ;
 
 : primary-key? ( spec -- ? )
-    sql-spec-primary-key (primary-key?) ;
+    sql-spec-primary-key +primary-key+? ;
+
+: native-id? ( spec -- ? )
+    sql-spec-primary-key +native-id+? ;
+
+: nonnative-id? ( spec -- ? )
+    sql-spec-primary-key +nonnative-id+? ;
 
 : normalize-spec ( spec -- )
-    dup sql-spec-type dup (primary-key?) [
+    dup sql-spec-type dup +primary-key+? [
         swap set-sql-spec-primary-key
     ] [
         drop dup sql-spec-modifiers [
-            (primary-key?)
+            +primary-key+?
         ] deep-find
         [ swap set-sql-spec-primary-key ] [ drop ] if*
     ] if ;
@@ -37,12 +46,6 @@ SYMBOLS: +native-id+ +assigned-id+ +autoincrement+
 : find-primary-key ( specs -- obj )
     [ sql-spec-primary-key ] find nip ;
 
-: native-id? ( spec -- ? )
-    sql-spec-primary-key +native-id+ = ;
-
-: assigned-id? ( spec -- ? )
-    sql-spec-primary-key +assigned-id+ = ;
-
 : relation? ( spec -- ? ) [ +has-many+ = ] deep-find ;
 
 SYMBOLS: INTEGER BIG-INTEGER DOUBLE REAL BOOLEAN TEXT VARCHAR
@@ -69,7 +72,7 @@ TUPLE: no-sql-modifier ;
     dup number? [ number>string ] when ;
 
 : maybe-remove-id ( specs -- obj )
-    [ native-id? not ] subset ;
+    [ +native-id+? not ] subset ;
 
 : remove-relations ( specs -- newcolumns )
     [ relation? not ] subset ;
index 654d096b26bd55a72bcdc94485f013daad79170b..67b8a39320e86ad0e331cc6776af38f4901cf404 100755 (executable)
@@ -7,7 +7,7 @@ IN: delegate
     swap { } like "protocol-words" set-word-prop ;
 
 : PROTOCOL:
-    CREATE dup reset-generic dup define-symbol
+    CREATE-WORD dup define-symbol
     parse-definition swap define-protocol ; parsing
 
 PREDICATE: word protocol "protocol-words" word-prop ;
@@ -27,11 +27,11 @@ M: tuple-class group-words
     swap [ slot-spec-writer ] map append ;
 
 : define-consult-method ( word class quot -- )
-    pick add spin define-method ;
+    pick add >r swap create-method r> define ;
 
 : define-consult ( class group quot -- )
-    >r group-words r>
-    swapd [ define-consult-method ] 2curry each ;
+    >r group-words swap r>
+    [ define-consult-method ] 2curry each ;
 
 : CONSULT:
     scan-word scan-word parse-definition swapd define-consult ; parsing
@@ -39,7 +39,7 @@ M: tuple-class group-words
 : define-mimic ( group mimicker mimicked -- )
     >r >r group-words r> r> [
         pick "methods" word-prop at dup
-        [ "method-def" word-prop spin define-method ]
+        [ >r swap create-method r> word-def define ]
         [ 3drop ] if
     ] 2curry each ; 
 
index b2561c74395af64d16c2392b2c43da1ea36cdf10..1b98d2ee0d88561ff39026402643622d8258c4ef 100755 (executable)
@@ -26,11 +26,14 @@ M: destructor dispose
 : add-always-destructor ( obj -- )
     <destructor> always-destructors get push ;
 
+: dispose-each ( seq -- )
+    <reversed> [ dispose ] each ;
+
 : do-always-destructors ( -- )
-    always-destructors get [ dispose ] each ;
+    always-destructors get dispose-each ;
 
 : do-error-destructors ( -- )
-    error-destructors get [ dispose ] each ;
+    error-destructors get dispose-each ;
 
 : with-destructors ( quot -- )
     [
index 45d19cb891c752fb1ba024dc511fd364264be78f..2341aabc9ddf302ff44eb74f7b1c7d92f8365835 100755 (executable)
@@ -1,14 +1,14 @@
 USING: tools.deploy.config ;
 H{
-    { deploy-io 2 }
-    { deploy-math? f }
-    { deploy-threads? f }
-    { deploy-compiler? f }
-    { deploy-word-props? f }
-    { deploy-word-defs? f }
     { deploy-name "Hello world (console)" }
-    { deploy-reflection 2 }
+    { deploy-threads? f }
     { deploy-c-types? f }
+    { deploy-compiler? f }
     { deploy-ui? f }
+    { deploy-math? f }
+    { deploy-reflection 1 }
+    { deploy-word-defs? f }
+    { deploy-io 2 }
+    { deploy-word-props? f }
     { "stop-after-last-window?" t }
 }
diff --git a/extra/help/help-tests.factor b/extra/help/help-tests.factor
new file mode 100644 (file)
index 0000000..e38f2fc
--- /dev/null
@@ -0,0 +1,5 @@
+IN: help.tests
+USING: tools.test help kernel ;
+
+[ 3 throw ] must-fail
+[ ] [ :help ] unit-test
index 85f5a35a5c74ae9866cdc1312065c2d0e601cad1..34e90b2ccff33bdd772c6469e9c33f9e266e1bd0 100755 (executable)
@@ -136,7 +136,7 @@ M: word set-article-parent swap "help-parent" set-word-prop ;
     ":edit - jump to source location (parse errors only)" print
 
     ":get  ( var -- value ) accesses variables at time of the error" print
-    ":vars - list all variables at error time";
+    ":vars - list all variables at error time" print ;
 
 : :help ( -- )
     error get delegates [ error-help ] map [ ] subset
index 661f63ab599f8fa4d470fc6369f9532d2c20bb1a..0f684f782af39a08cca1770eba11c4b9e8568f9d 100755 (executable)
@@ -18,6 +18,7 @@ tuple-syntax namespaces ;
         port: 80
         version: "1.1"
         cookies: V{ }
+        header: H{ }
     }
 ] [
     [
index 66182b10ae7dbfff7c55a7b95236141b51c21820..2e7370bc395b14200c9fafbf675411a94322cb9a 100755 (executable)
@@ -5,8 +5,8 @@ IN: http.tests
 [ "hello%20world" ] [ "hello world" url-encode ] unit-test
 [ "hello world" ] [ "hello%20world" url-decode ] unit-test
 [ "~hello world" ] [ "%7ehello+world" url-decode ] unit-test
-[ "" ] [ "%XX%XX%XX" url-decode ] unit-test
-[ "" ] [ "%XX%XX%X" url-decode ] unit-test
+[ f ] [ "%XX%XX%XX" url-decode ] unit-test
+[ f ] [ "%XX%XX%X" url-decode ] unit-test
 
 [ "hello world"   ] [ "hello+world"    url-decode ] unit-test
 [ "hello world"   ] [ "hello%20world"  url-decode ] unit-test
index 4dd433f85dbd18a8aed57edd7810485b8c62d112..421a40963907d4c043a3151218c126dbbeec9b22 100755 (executable)
@@ -180,6 +180,7 @@ cookies ;
     request construct-empty
         "1.1" >>version
         http-port >>port
+        H{ } clone >>header
         H{ } clone >>query
         V{ } clone >>cookies ;
 
index 45f7ff385deedf0fd79ed82dfe1c4b7b04f2d731..c604b8a4270becea3ff5a9f53db82a3a1f4303bf 100755 (executable)
@@ -1,11 +1,16 @@
 IN: http.server.actions.tests
-USING: http.server.actions tools.test math math.parser
-multiline namespaces http io.streams.string http.server
-sequences accessors ;
+USING: http.server.actions http.server.validators
+tools.test math math.parser multiline namespaces http
+io.streams.string http.server sequences accessors ;
+
+[
+    "a" [ v-number ] { { "a" "123" } } validate-param
+    [ 123 ] [ "a" get ] unit-test
+] with-scope
 
 <action>
     [ "a" get "b" get + ] >>display
-    { { "a" [ string>number ] } { "b" [ string>number ] } } >>get-params
+    { { "a" [ v-number ] } { "b" [ v-number ] } } >>get-params
 "action-1" set
 
 STRING: action-request-test-1
@@ -23,7 +28,7 @@ blah
 
 <action>
     [ +path+ get "xxx" get "X" <repetition> concat append ] >>submit
-    { { +path+ [ ] } { "xxx" [ string>number ] } } >>post-params
+    { { +path+ [ ] } { "xxx" [ v-number ] } } >>post-params
 "action-2" set
 
 STRING: action-request-test-2
index 72c2d2df8ed24b1a884ecfdfb6832cb29c81062f..52567ed35290cfe0c699929c35fff33b5048cf3b 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: accessors new-slots sequences kernel assocs combinators\r
 http.server http.server.validators http hashtables namespaces\r
-combinators.cleave fry continuations ;\r
+combinators.cleave fry continuations locals ;\r
 IN: http.server.actions\r
 \r
 SYMBOL: +path+\r
@@ -17,17 +17,13 @@ TUPLE: action init display submit get-params post-params ;
         [ <400> ] >>display\r
         [ <400> ] >>submit ;\r
 \r
-: with-validator ( string quot -- result error? )\r
-    '[ , @ f ] [\r
-        dup validation-error? [ t ] [ rethrow ] if\r
-    ] recover ; inline\r
-\r
-: validate-param ( name validator assoc -- error? )\r
-    swap pick\r
-    >r >r at r> with-validator swap r> set ;\r
+:: validate-param ( name validator assoc -- )\r
+    name assoc at validator with-validator name set ; inline\r
 \r
 : action-params ( validators -- error? )\r
-    [ params get validate-param ] { } assoc>map [ ] contains? ;\r
+    validation-failed? off\r
+    params get '[ , validate-param ] assoc-each\r
+    validation-failed? get ;\r
 \r
 : handle-get ( -- response )\r
     action get get-params>> action-params [ <400> ] [\r
@@ -42,10 +38,13 @@ TUPLE: action init display submit get-params post-params ;
     action get display>> call exit-with ;\r
 \r
 M: action call-responder ( path action -- response )\r
-    [ +path+ associate request-params union params set ]\r
-    [ action set ] bi*\r
-    request get method>> {\r
-        { "GET" [ handle-get ] }\r
-        { "HEAD" [ handle-get ] }\r
-        { "POST" [ handle-post ] }\r
-    } case ;\r
+    '[\r
+        , ,\r
+        [ +path+ associate request-params union params set ]\r
+        [ action set ] bi*\r
+        request get method>> {\r
+            { "GET" [ handle-get ] }\r
+            { "HEAD" [ handle-get ] }\r
+            { "POST" [ handle-post ] }\r
+        } case\r
+    ] with-exit-continuation ;\r
index 1b1534b85ea4f01e4e4d1cb0d8156ce6b4af0fd0..69a3c76c2bf7325d0c1e2cd0e70c2b1c64fa1379 100755 (executable)
@@ -1,9 +1,26 @@
 ! Copyright (c) 2008 Slava Pestov\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: http.server.sessions accessors\r
-http.server.auth.providers ;\r
+http.server.auth.providers assocs namespaces kernel ;\r
 IN: http.server.auth\r
 \r
 SYMBOL: logged-in-user\r
+SYMBOL: user-profile-changed?\r
+\r
+GENERIC: init-user-profile ( responder -- )\r
+\r
+M: object init-user-profile drop ;\r
 \r
 : uid ( -- string ) logged-in-user sget username>> ;\r
+\r
+: profile ( -- assoc ) logged-in-user sget profile>> ;\r
+\r
+: uget ( key -- value )\r
+    profile at ;\r
+\r
+: uset ( value key -- )\r
+    profile set-at user-profile-changed? on ;\r
+\r
+: uchange ( quot key -- )\r
+    profile swap change-at\r
+    user-profile-changed? on ; inline\r
diff --git a/extra/http/server/auth/login/edit-profile.fhtml b/extra/http/server/auth/login/edit-profile.fhtml
new file mode 100755 (executable)
index 0000000..7d94ca1
--- /dev/null
@@ -0,0 +1,77 @@
+<% USING: http.server.components http.server.auth.login\r
+http.server namespaces kernel combinators ; %>\r
+<html>\r
+<body>\r
+<h1>Edit profile</h1>\r
+\r
+<form method="POST" action="edit-profile">\r
+<% hidden-form-field %>\r
+\r
+<table>\r
+\r
+<tr>\r
+<td>User name:</td>\r
+<td><% "username" component render-view %></td>\r
+</tr>\r
+\r
+<tr>\r
+<td>Real name:</td>\r
+<td><% "realname" component render-edit %></td>\r
+</tr>\r
+\r
+<tr>\r
+<td></td>\r
+<td>Specifying a real name is optional.</td>\r
+</tr>\r
+\r
+<tr>\r
+<td>Current password:</td>\r
+<td><% "password" component render-edit %></td>\r
+</tr>\r
+\r
+<tr>\r
+<td></td>\r
+<td>If you don't want to change your current password, leave this field blank.</td>\r
+</tr>\r
+\r
+<tr>\r
+<td>New password:</td>\r
+<td><% "new-password" component render-edit %></td>\r
+</tr>\r
+\r
+<tr>\r
+<td>Verify:</td>\r
+<td><% "verify-password" component render-edit %></td>\r
+</tr>\r
+\r
+<tr>\r
+<td></td>\r
+<td>If you are changing your password, enter it twice to ensure it is correct.</td>\r
+</tr>\r
+\r
+<tr>\r
+<td>E-mail:</td>\r
+<td><% "email" component render-edit %></td>\r
+</tr>\r
+\r
+<tr>\r
+<td></td>\r
+<td>Specifying an e-mail address is optional. It enables the "recover password" feature.</td>\r
+</tr>\r
+\r
+</table>\r
+\r
+<p><input type="submit" value="Update" />\r
+\r
+<% {\r
+    { [ login-failed? get ] [ "invalid password" render-error ] }\r
+    { [ password-mismatch? get ] [ "passwords do not match" render-error ] }\r
+    { [ t ] [ ] }\r
+} cond %>\r
+\r
+</p>\r
+\r
+</form>\r
+\r
+</body>\r
+</html>\r
index 9b2648158dc47e76e3f9313894ec43879f1c72ec..275fb0ff63236a6e610c40dcb1568a9de1df8ee6 100755 (executable)
@@ -7,15 +7,30 @@ http.server.actions http.server.components http.server.sessions
 http.server.templating.fhtml http.server.validators\r
 http.server.auth http sequences io.files namespaces hashtables\r
 fry io.sockets combinators.cleave arrays threads locals\r
-qualified ;\r
+qualified continuations destructors ;\r
 IN: http.server.auth.login\r
 QUALIFIED: smtp\r
 \r
-TUPLE: login users ;\r
-\r
 SYMBOL: post-login-url\r
 SYMBOL: login-failed?\r
 \r
+TUPLE: login users ;\r
+\r
+: users login get users>> ;\r
+\r
+! Destructor\r
+TUPLE: user-saver user ;\r
+\r
+C: <user-saver> user-saver\r
+\r
+M: user-saver dispose\r
+    user-profile-changed? get [\r
+        user>> users update-user\r
+    ] [ drop ] if ;\r
+\r
+: save-user-after ( user -- )\r
+    <user-saver> add-always-destructor ;\r
+\r
 ! ! ! Login\r
 \r
 : <login-form>\r
@@ -49,7 +64,7 @@ SYMBOL: login-failed?
                 form validate-form\r
 \r
                 "password" value "username" value\r
-                login get users>> check-login [\r
+                users check-login [\r
                     successful-login\r
                 ] [\r
                     login-failed? on\r
@@ -67,7 +82,7 @@ SYMBOL: login-failed?
             t >>required\r
             add-field\r
         "realname" <string> add-field\r
-        "password" <password>\r
+        "new-password" <password>\r
             t >>required\r
             add-field\r
         "verify-password" <password>\r
@@ -80,7 +95,7 @@ SYMBOL: password-mismatch?
 SYMBOL: user-exists?\r
 \r
 : same-password-twice ( -- )\r
-    "password" value "verify-password" value = [ \r
+    "new-password" value "verify-password" value = [ \r
         password-mismatch? on\r
         validation-failed\r
     ] unless ;\r
@@ -102,19 +117,76 @@ SYMBOL: user-exists?
 \r
                 same-password-twice\r
 \r
-                <user> values get [\r
-                    "username" get >>username\r
-                    "realname" get >>realname\r
-                    "password" get >>password\r
-                    "email" get >>email\r
-                ] bind\r
+                <user>\r
+                    "username" value >>username\r
+                    "realname" value >>realname\r
+                    "new-password" value >>password\r
+                    "email" value >>email\r
 \r
-                login get users>> new-user [\r
+                users new-user [\r
                     user-exists? on\r
                     validation-failed\r
                 ] unless*\r
 \r
                 successful-login\r
+\r
+                login get responder>> init-user-profile\r
+            ] >>submit\r
+    ] ;\r
+\r
+! ! ! Editing user profile\r
+\r
+: <edit-profile-form> ( -- form )\r
+    "edit-profile" <form>\r
+        "resource:extra/http/server/auth/login/edit-profile.fhtml" >>edit-template\r
+        "username" <username> add-field\r
+        "realname" <string> add-field\r
+        "password" <password> add-field\r
+        "new-password" <password> add-field\r
+        "verify-password" <password> add-field\r
+        "email" <email> add-field ;\r
+\r
+SYMBOL: previous-page\r
+\r
+:: <edit-profile-action> ( -- action )\r
+    [let | form [ <edit-profile-form> ] |\r
+        <action>\r
+            [\r
+                blank-values\r
+                logged-in-user sget\r
+                dup username>> "username" set-value\r
+                dup realname>> "realname" set-value\r
+                dup email>> "email" set-value\r
+            ] >>init\r
+\r
+            [\r
+                "text/html" <content>\r
+                [ form edit-form ] >>body\r
+            ] >>display\r
+\r
+            [\r
+                blank-values\r
+                uid "username" set-value\r
+\r
+                form validate-form\r
+\r
+                logged-in-user sget\r
+\r
+                "password" value empty? [\r
+                    same-password-twice\r
+\r
+                    "password" value uid users check-login\r
+                    [ login-failed? on validation-failed ] unless\r
+\r
+                    "new-password" value set-password\r
+                ] unless\r
+\r
+                "realname" value >>realname\r
+                "email" value >>email\r
+\r
+                user-profile-changed? on\r
+\r
+                previous-page sget f <permanent-redirect>\r
             ] >>submit\r
     ] ;\r
 \r
@@ -186,7 +258,7 @@ SYMBOL: lost-password-from
                 form validate-form\r
 \r
                 "email" value "username" value\r
-                login get users>> issue-ticket [\r
+                users issue-ticket [\r
                     send-password-email\r
                 ] when*\r
 \r
@@ -200,7 +272,7 @@ SYMBOL: lost-password-from
         "username" <username> <hidden>\r
             t >>required\r
             add-field\r
-        "password" <password>\r
+        "new-password" <password>\r
             t >>required\r
             add-field\r
         "verify-password" <password>\r
@@ -239,9 +311,9 @@ SYMBOL: lost-password-from
 \r
                 "ticket" value\r
                 "username" value\r
-                login get users>> claim-ticket [\r
-                    "password" value >>password\r
-                    login get users>> update-user\r
+                users claim-ticket [\r
+                    "new-password" value >>password\r
+                    users update-user\r
 \r
                     "resource:extra/http/server/auth/login/recover-4.fhtml"\r
                     serve-template\r
@@ -265,13 +337,19 @@ TUPLE: protected responder ;
 \r
 C: <protected> protected\r
 \r
+: show-login-page ( -- response )\r
+    request get request-url post-login-url sset\r
+    "login" f <permanent-redirect> ;\r
+\r
 M: protected call-responder ( path responder -- response )\r
-    logged-in-user sget [ responder>> call-responder ] [\r
+    logged-in-user sget [\r
+        dup save-user-after\r
+        request get request-url previous-page sset\r
+        responder>> call-responder\r
+    ] [\r
         2drop\r
-        request get method>> { "GET" "HEAD" } member? [\r
-            request get request-url post-login-url sset\r
-            "login" f <permanent-redirect>\r
-        ] [ <400> ] if\r
+        request get method>> { "GET" "HEAD" } member?\r
+        [ show-login-page ] [ <400> ] if\r
     ] if ;\r
 \r
 M: login call-responder ( path responder -- response )\r
@@ -283,10 +361,13 @@ M: login call-responder ( path responder -- response )
         swap <protected> >>default\r
         <login-action> "login" add-responder\r
         <logout-action> "logout" add-responder\r
-        no >>users ;\r
+        no-users >>users ;\r
 \r
 ! ! ! Configuration\r
 \r
+: allow-edit-profile ( login -- login )\r
+    <edit-profile-action> <protected> "edit-profile" add-responder ;\r
+\r
 : allow-registration ( login -- login )\r
     <register-action> "register" add-responder ;\r
 \r
@@ -294,6 +375,9 @@ M: login call-responder ( path responder -- response )
     <recover-action-1> "recover-password" add-responder\r
     <recover-action-3> "new-password" add-responder ;\r
 \r
+: allow-edit-profile? ( -- ? )\r
+    login get responders>> "edit-profile" swap key? ;\r
+\r
 : allow-registration? ( -- ? )\r
     login get responders>> "register" swap key? ;\r
 \r
index edd32fffe8f6926a99af02f5ff636c1c8853a587..ca4823baab53a06713eab0db5ab1ba01c2560e89 100755 (executable)
@@ -17,7 +17,7 @@ namespaces kernel combinators ; %>
 \r
 <tr>\r
 <td>Password:</td>\r
-<td><% "password" component render-edit %></td>\r
+<td><% "new-password" component render-edit %></td>\r
 </tr>\r
 \r
 <tr>\r
index 99d1547d03938d8416cc11ed8f28c3ca12da14f6..9106497defafc34875314a3877d4b9e6d9358fd5 100755 (executable)
@@ -26,7 +26,7 @@ http.server namespaces kernel combinators ; %>
 \r
 <tr>\r
 <td>Password:</td>\r
-<td><% "password" component render-edit %></td>\r
+<td><% "new-password" component render-edit %></td>\r
 </tr>\r
 \r
 <tr>\r
index 12c799816d3cee1d817830b39c0cc88134f8bfdb..f99e4d3d2ec329ee8850f0c12bffac0d284e11ef 100755 (executable)
@@ -3,7 +3,7 @@ USING: http.server.auth.providers
 http.server.auth.providers.assoc tools.test\r
 namespaces accessors kernel ;\r
 \r
-<in-memory> "provider" set\r
+<users-in-memory> "provider" set\r
 \r
 [ t ] [\r
     <user>\r
@@ -22,11 +22,11 @@ namespaces accessors kernel ;
 \r
 [ f ] [ "fdasf" "slava" "provider" get check-login >boolean ] unit-test\r
 \r
-[ t ] [ "foobar" "slava" "provider" get check-login >boolean ] unit-test\r
+[ ] [ "foobar" "slava" "provider" get check-login "user" set ] unit-test\r
 \r
-[ f ] [ "xx" "blah" "provider" get set-password ] unit-test\r
+[ t ] [ "user" get >boolean ] unit-test\r
 \r
-[ t ] [ "fdasf" "slava" "provider" get set-password ] unit-test\r
+[ ] [ "user" get "fdasf" set-password drop ] unit-test\r
 \r
 [ t ] [ "fdasf" "slava" "provider" get check-login >boolean ] unit-test\r
 \r
index 8433e54fda68ad54b790d5003883c829428594c6..e8ab908406ba3b283a57fa499c48b74c417969d1 100755 (executable)
@@ -4,16 +4,16 @@ IN: http.server.auth.providers.assoc
 USING: new-slots accessors assocs kernel\r
 http.server.auth.providers ;\r
 \r
-TUPLE: in-memory assoc ;\r
+TUPLE: users-in-memory assoc ;\r
 \r
-: <in-memory> ( -- provider )\r
-    H{ } clone in-memory construct-boa ;\r
+: <users-in-memory> ( -- provider )\r
+    H{ } clone users-in-memory construct-boa ;\r
 \r
-M: in-memory get-user ( username provider -- user/f )\r
+M: users-in-memory get-user ( username provider -- user/f )\r
     assoc>> at ;\r
 \r
-M: in-memory update-user ( user provider -- ) 2drop ;\r
+M: users-in-memory update-user ( user provider -- ) 2drop ;\r
 \r
-M: in-memory new-user ( user provider -- user/f )\r
+M: users-in-memory new-user ( user provider -- user/f )\r
     >r dup username>> r> assoc>>\r
     2dup key? [ 3drop f ] [ pick >r set-at r> ] if ;\r
index 247359aea4556339345a4f7c4843f43d02d2b494..340e1bb35d1a0bb0f0c7bb36a2eeb8c158ac0781 100755 (executable)
@@ -4,35 +4,36 @@ http.server.auth.providers.db tools.test
 namespaces db db.sqlite db.tuples continuations\r
 io.files accessors kernel ;\r
 \r
-from-db "provider" set\r
+users-in-db "provider" set\r
 \r
 "auth-test.db" temp-file sqlite-db [\r
 \r
-    [ user drop-table ] ignore-errors\r
-    [ user create-table ] ignore-errors\r
+    init-users-table\r
 \r
     [ t ] [\r
         <user>\r
-        "slava" >>username\r
-        "foobar" >>password\r
-        "slava@factorcode.org" >>email\r
-        "provider" get new-user\r
-        username>> "slava" =\r
+            "slava" >>username\r
+            "foobar" >>password\r
+            "slava@factorcode.org" >>email\r
+            "provider" get new-user\r
+            username>> "slava" =\r
     ] unit-test\r
 \r
     [ f ] [\r
         <user>\r
-        "slava" >>username\r
+            "slava" >>username\r
         "provider" get new-user\r
     ] unit-test\r
 \r
     [ f ] [ "fdasf" "slava" "provider" get check-login >boolean ] unit-test\r
 \r
-    [ t ] [ "foobar" "slava" "provider" get check-login >boolean ] unit-test\r
+    [ ] [ "foobar" "slava" "provider" get check-login "user" set ] unit-test\r
+\r
+    [ t ] [ "user" get >boolean ] unit-test\r
 \r
-    [ f ] [ "xx" "blah" "provider" get set-password ] unit-test\r
+    [ ] [ "user" get "fdasf" set-password drop ] unit-test\r
 \r
-    [ t ] [ "fdasf" "slava" "provider" get set-password ] unit-test\r
+    [ ] [ "user" get "provider" get update-user ] unit-test\r
 \r
     [ t ] [ "fdasf" "slava" "provider" get check-login >boolean ] unit-test\r
 \r
index c9e1328052c496fed13324018b4fd909ce72b541..aec64d3384cf238b62ddfc1161107f17fdaaac9d 100755 (executable)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: db db.tuples db.types new-slots accessors\r
-http.server.auth.providers kernel continuations ;\r
+http.server.auth.providers kernel continuations\r
+singleton ;\r
 IN: http.server.auth.providers.db\r
 \r
 user "USERS"\r
@@ -16,20 +17,18 @@ user "USERS"
 \r
 : init-users-table user ensure-table ;\r
 \r
-TUPLE: from-db ;\r
-\r
-: from-db T{ from-db } ;\r
+SINGLETON: users-in-db\r
 \r
 : find-user ( username -- user )\r
     <user>\r
         swap >>username\r
     select-tuple ;\r
 \r
-M: from-db get-user\r
+M: users-in-db get-user\r
     drop\r
     find-user ;\r
 \r
-M: from-db new-user\r
+M: users-in-db new-user\r
     drop\r
     [\r
         dup username>> find-user [\r
@@ -39,5 +38,5 @@ M: from-db new-user
         ] if\r
     ] with-transaction ;\r
 \r
-M: from-db update-user\r
+M: users-in-db update-user\r
     drop update-tuple ;\r
index 7b8bfc627ce377821c6d403f9caca3ff855f06e4..30f6dbd06e0bd7744a80a691cdec2e7b8083f126 100755 (executable)
@@ -3,14 +3,12 @@
 USING: http.server.auth.providers kernel ;\r
 IN: http.server.auth.providers.null\r
 \r
-! Named "no" because we can say  no >>users\r
+TUPLE: no-users ;\r
 \r
-TUPLE: no ;\r
+: no-users T{ no-users } ;\r
 \r
-: no T{ no } ;\r
+M: no-users get-user 2drop f ;\r
 \r
-M: no get-user 2drop f ;\r
+M: no-users new-user 2drop f ;\r
 \r
-M: no new-user 2drop f ;\r
-\r
-M: no update-user 2drop ;\r
+M: no-users update-user 2drop ;\r
index 0aa27f870d2bf8259d1c32b3dd9508f8817a4af2..d51679016e1ee6b0c05bc2cd82bb0abf8e13b18e 100755 (executable)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.\r
 ! See http://factorcode.org/license.txt for BSD license.\r
 USING: kernel new-slots accessors random math.parser locals\r
-sequences math ;\r
+sequences math crypto.sha2 ;\r
 IN: http.server.auth.providers\r
 \r
 TUPLE: user username realname password email ticket profile ;\r
@@ -17,14 +17,7 @@ GENERIC: new-user ( user provider -- user/f )
 : check-login ( password username provider -- user/f )\r
     get-user dup [ [ password>> = ] keep and ] [ 2drop f ] if ;\r
 \r
-:: set-password ( password username provider -- ? )\r
-    [let | user [ username provider get-user ] |\r
-        user [\r
-            user\r
-                password >>password\r
-            provider update-user t\r
-        ] [ f ] if\r
-    ] ;\r
+: set-password ( user password -- user ) >>password ;\r
 \r
 ! Password recovery support\r
 \r
index ac03e0efc824209ebde7a38d04734074c87b421f..eb264279cbf0acb8b24762cad3825d40acd938f9 100755 (executable)
@@ -4,7 +4,7 @@
 USING: html http http.server io kernel math namespaces\r
 continuations calendar sequences assocs new-slots hashtables\r
 accessors arrays alarms quotations combinators\r
-combinators.cleave fry ;\r
+combinators.cleave fry assocs.lib ;\r
 IN: http.server.callbacks\r
 \r
 SYMBOL: responder\r
@@ -98,11 +98,18 @@ SYMBOL: current-show
     cont-id query-param swap callbacks>> at ;\r
 \r
 M: callback-responder call-responder ( path responder -- response )\r
-    [ callback-responder set ]\r
-    [ request get resuming-callback ] bi\r
+    '[\r
+        , ,\r
 \r
-    [ invoke-callback ]\r
-    [ callback-responder get responder>> call-responder ] ?if ;\r
+        [ callback-responder set ]\r
+        [ request get resuming-callback ] bi\r
+\r
+        [\r
+            invoke-callback\r
+        ] [\r
+            callback-responder get responder>> call-responder\r
+        ] ?if\r
+    ] with-exit-continuation ;\r
 \r
 : show-page ( quot -- )\r
     >r redirect-to-here store-current-show r>\r
index 2a507e6416a52bf2a5b9559322047dd0bbd5c83d..09d31202c5152d6a6e8b6e052b5178ef956c5864 100755 (executable)
@@ -86,3 +86,24 @@ TUPLE: test-tuple text number more-text ;
 \r
     [ t ] [ "number" value validation-error? ] unit-test\r
 ] with-scope\r
+\r
+[\r
+    [ ] [\r
+        "n" <number>\r
+            0 >>min-value\r
+            10 >>max-value\r
+        "n" set\r
+    ] unit-test\r
+\r
+    [ "123" ] [\r
+        "123" "n" get validate value>>\r
+    ] unit-test\r
+    \r
+    [ ] [ "n" get t >>integer drop ] unit-test\r
+\r
+    [ 3 ] [\r
+        "3" "n" get validate\r
+    ] unit-test\r
+] with-scope\r
+\r
+[ t ] [ "wake up sheeple" dup "n" <text> validate = ] unit-test\r
index bb0fc4b3dd1eddb3542ea064cadf648cf435ec4a..02c992651a2dc3fa43fa6111dd48215de798a157 100755 (executable)
@@ -7,8 +7,6 @@ http.server.actions splitting mirrors hashtables
 combinators.cleave fry continuations math ;
 IN: http.server.components
 
-SYMBOL: validation-failed?
-
 SYMBOL: components
 
 TUPLE: component id required default ;
@@ -30,16 +28,13 @@ SYMBOL: values
 
 : validate ( value component -- result )
     '[
-        , ,
+        ,
         over empty? [
             [ default>> [ v-default ] when* ]
             [ required>> [ v-required ] when ]
             bi
         ] [ validate* ] if
-    ] [
-        dup validation-error?
-        [ validation-failed? on ] [ rethrow ] if
-    ] recover ;
+    ] with-validator ;
 
 : render-view ( component -- )
     [ id>> value ] [ render-view* ] bi ;
@@ -192,15 +187,16 @@ M: password render-error*
     render-edit* render-error ;
 
 ! Number fields
-TUPLE: number min-value max-value ;
+TUPLE: number min-value max-value integer ;
 
 : <number> ( id -- component ) number <component> ;
 
 M: number validate*
     [ v-number ] [
+        [ integer>> [ v-integer ] when ]
         [ min-value>> [ v-min-value ] when* ]
         [ max-value>> [ v-max-value ] when* ]
-        bi
+        tri
     ] bi* ;
 
 M: number render-view*
@@ -215,7 +211,12 @@ M: number render-error*
 ! Text areas
 TUPLE: text ;
 
-: <text> ( id -- component ) <string> text construct-delegate ;
+: <text> ( id -- component ) text <component> ;
+
+M: text validate* drop ;
+
+M: text render-view*
+    drop write ;
 
 : render-textarea
     <textarea
index 60bb5d921d91f76164d9ab628b139f202edca00b..7448752c608abd04b770a8293124c2cf59e89605 100755 (executable)
@@ -108,10 +108,6 @@ TUPLE: dispatcher default responders ;
 : <dispatcher> ( -- dispatcher )
     404-responder get H{ } clone dispatcher construct-boa ;
 
-: set-main ( dispatcher name -- dispatcher )
-    '[ , f <permanent-redirect> ] <trivial-responder>
-    >>default ;
-
 : split-path ( path -- rest first )
     [ CHAR: / = ] left-trim "/" split1 swap ;
 
@@ -124,28 +120,36 @@ TUPLE: dispatcher default responders ;
 
 M: dispatcher call-responder ( path dispatcher -- response )
     over [
-        2dup find-responder call-responder [
-            2nip
-        ] [
-            default>> [
-                call-responder
-            ] [
-                drop f
-            ] if*
-        ] if*
+        find-responder call-responder
     ] [
         2drop redirect-with-/
     ] if ;
 
+: <webapp> ( class -- dispatcher )
+    <dispatcher> swap construct-delegate ; inline
+
+TUPLE: vhost-dispatcher default responders ;
+
+: <vhost-dispatcher> ( -- dispatcher )
+    404-responder get H{ } clone vhost-dispatcher construct-boa ;
+
+: find-vhost ( dispatcher -- responder )
+    request get host>> over responders>> at*
+    [ nip ] [ drop default>> ] if ;
+
+M: vhost-dispatcher call-responder ( path dispatcher -- response )
+    find-vhost call-responder ;
+
+: set-main ( dispatcher name -- dispatcher )
+    '[ , f <permanent-redirect> ] <trivial-responder>
+    >>default ;
+
 : add-responder ( dispatcher responder path -- dispatcher )
     pick responders>> set-at ;
 
 : add-main-responder ( dispatcher responder path -- dispatcher )
     [ add-responder ] keep set-main ;
 
-: <webapp> ( class -- dispatcher )
-    <dispatcher> swap construct-delegate ; inline
-
 SYMBOL: main-responder
 
 main-responder global
@@ -181,21 +185,20 @@ SYMBOL: exit-continuation
 
 : exit-with exit-continuation get continue-with ;
 
+: with-exit-continuation ( quot -- )
+    '[ exit-continuation set @ ] callcc1 exit-continuation off ;
+
 : do-request ( request -- response )
-    '[
-        exit-continuation set ,
-        [
-            [ log-request ]
-            [ request set ]
-            [ path>> main-responder get call-responder ] tri
-            [ <404> ] unless*
-        ] [
-            [ \ do-request log-error ]
-            [ <500> ]
-            bi
-        ] recover
-    ] callcc1
-    exit-continuation off ;
+    [
+        [ log-request ]
+        [ request set ]
+        [ path>> main-responder get call-responder ] tri
+        [ <404> ] unless*
+    ] [
+        [ \ do-request log-error ]
+        [ <500> ]
+        bi
+    ] recover ;
 
 : default-timeout 1 minutes stdio get set-timeout ;
 
@@ -219,11 +222,3 @@ SYMBOL: exit-continuation
 : httpd-main ( -- ) 8888 httpd ;
 
 MAIN: httpd-main
-
-! Utility
-: generate-key ( assoc -- str )
-    >r random-256 >hex r>
-    2dup key? [ nip generate-key ] [ drop ] if ;
-
-: set-at-unique ( value assoc -- key )
-    dup generate-key [ swap set-at ] keep ;
index 5530b04611a22fae73f259d08f032f673f5a74ab..26e6927d7cb616aa3df7ada078fddd97723caf3a 100755 (executable)
@@ -1,6 +1,8 @@
 IN: http.server.sessions.tests\r
-USING: tools.test http.server.sessions math namespaces\r
-kernel accessors ;\r
+USING: tools.test http http.server.sessions\r
+http.server.sessions.storage http.server.sessions.storage.assoc\r
+http.server.actions http.server math namespaces kernel accessors\r
+prettyprint io.streams.string splitting destructors sequences ;\r
 \r
 [ H{ } ] [ H{ } add-session-id ] unit-test\r
 \r
@@ -12,7 +14,16 @@ C: <foo> foo
 \r
 M: foo init-session* drop 0 "x" sset ;\r
 \r
-f <session> "123" >>id [\r
+M: foo call-responder\r
+    2drop\r
+    "x" [ 1+ ] schange\r
+    "text/html" <content> [ "x" sget pprint ] >>body ;\r
+\r
+[\r
+    "123" session-id set\r
+    H{ } clone session set\r
+    session-changed? off\r
+\r
     [ H{ { "factorsessid" "123" } } ] [ H{ } add-session-id ] unit-test\r
 \r
     [ ] [ 3 "x" sset ] unit-test\r
@@ -22,22 +33,113 @@ f <session> "123" >>id [
     [ ] [ "x" [ 1- ] schange ] unit-test\r
     \r
     [ 4 ] [ "x" sget sq ] unit-test\r
-] with-session\r
+\r
+    [ t ] [ session-changed? get ] unit-test\r
+] with-scope\r
 \r
 [ t ] [ f <url-sessions> url-sessions? ] unit-test\r
 [ t ] [ f <cookie-sessions> cookie-sessions? ] unit-test\r
 \r
 [ ] [\r
     <foo> <url-sessions>\r
+        <sessions-in-memory> >>sessions\r
     "manager" set\r
 ] unit-test\r
 \r
 [ { 5 0 } ] [\r
     [\r
-        "manager" get new-session\r
-        dup "manager" get get-session [ 5 "a" sset ] with-session\r
-        dup "manager" get get-session [ "a" sget , ] with-session\r
-        dup "manager" get get-session [ "x" sget , ] with-session\r
-        "manager" get get-session delete-session\r
+        "manager" get begin-session drop\r
+        dup "manager" get sessions>> get-session [ 5 "a" sset ] with-session\r
+        dup "manager" get sessions>> get-session [ "a" sget , ] with-session\r
+        dup "manager" get sessions>> get-session [ "x" sget , ] with-session\r
+        "manager" get sessions>> get-session\r
+        "manager" get sessions>> delete-session\r
     ] { } make\r
 ] unit-test\r
+\r
+[ ] [\r
+    <request>\r
+        "GET" >>method\r
+    request set\r
+    "/etc" "manager" get call-responder\r
+    response set\r
+] unit-test\r
+\r
+[ 307 ] [ response get code>> ] unit-test\r
+\r
+[ ] [ response get "location" header "=" split1 nip "id" set ] unit-test\r
+\r
+: url-responder-mock-test\r
+    [\r
+        <request>\r
+            "GET" >>method\r
+            "id" get session-id-key set-query-param\r
+            "/" >>path\r
+        request set\r
+        "/" "manager" get call-responder\r
+        [ write-response-body drop ] with-string-writer\r
+    ] with-destructors ;\r
+\r
+[ "1" ] [ url-responder-mock-test ] unit-test\r
+[ "2" ] [ url-responder-mock-test ] unit-test\r
+[ "3" ] [ url-responder-mock-test ] unit-test\r
+[ "4" ] [ url-responder-mock-test ] unit-test\r
+\r
+[ ] [\r
+    <foo> <cookie-sessions>\r
+        <sessions-in-memory> >>sessions\r
+    "manager" set\r
+] unit-test\r
+\r
+[\r
+    <request>\r
+    "GET" >>method\r
+    "/" >>path\r
+    request set\r
+    "/etc" "manager" get call-responder response set\r
+    [ "1" ] [ [ response get write-response-body drop ] with-string-writer ] unit-test\r
+    response get\r
+] with-destructors\r
+response set\r
+\r
+[ ] [ response get cookies>> "cookies" set ] unit-test\r
+\r
+: cookie-responder-mock-test\r
+    [\r
+        <request>\r
+            "GET" >>method\r
+            "cookies" get >>cookies\r
+            "/" >>path\r
+        request set\r
+        "/" "manager" get call-responder\r
+        [ write-response-body drop ] with-string-writer\r
+    ] with-destructors ;\r
+\r
+[ "2" ] [ cookie-responder-mock-test ] unit-test\r
+[ "3" ] [ cookie-responder-mock-test ] unit-test\r
+[ "4" ] [ cookie-responder-mock-test ] unit-test\r
+\r
+: <exiting-action>\r
+    <action>\r
+        [\r
+            "text/plain" <content> exit-with\r
+        ] >>display ;\r
+\r
+[\r
+    [ ] [\r
+        <request>\r
+            "GET" >>method\r
+            "id" get session-id-key set-query-param\r
+            "/" >>path\r
+        request set\r
+\r
+        [\r
+            "/" <exiting-action> <cookie-sessions>\r
+            call-responder\r
+        ] with-destructors response set\r
+    ] unit-test\r
+\r
+    [ "text/plain" ] [ response get "content-type" header ] unit-test\r
+\r
+    [ f ] [ response get cookies>> empty? ] unit-test\r
+] with-scope\r
index 260c80914ebad49c522f696e2757a66b121cc1bc..f45f10d25fc8f5b9465edd8c2487d13e57f24f7b 100755 (executable)
@@ -1,9 +1,10 @@
 ! Copyright (C) 2008 Doug Coleman, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs calendar kernel math.parser namespaces random
-boxes alarms new-slots accessors http http.server
+new-slots accessors http http.server
+http.server.sessions.storage http.server.sessions.storage.assoc
 quotations hashtables sequences fry combinators.cleave
-html.elements ;
+html.elements symbols continuations destructors ;
 IN: http.server.sessions
 
 ! ! ! ! ! !
@@ -12,61 +13,56 @@ IN: http.server.sessions
 
 GENERIC: init-session* ( responder -- )
 
-M: dispatcher init-session* drop ;
+M: object init-session* drop ;
 
 TUPLE: session-manager responder sessions ;
 
 : <session-manager> ( responder class -- responder' )
-    >r H{ } clone session-manager construct-boa r>
-    construct-delegate ; inline
+    >r <sessions-in-memory> session-manager construct-boa
+    r> construct-delegate ; inline
 
-TUPLE: session manager id namespace alarm ;
+SYMBOLS: session session-id session-changed? ;
 
-: <session> ( manager -- session )
-    f H{ } clone <box> \ session construct-boa ;
+: sget ( key -- value )
+    session get at ;
 
-: timeout ( -- dt ) 20 minutes ;
+: sset ( value key -- )
+    session get set-at
+    session-changed? on ;
 
-: cancel-timeout ( session -- )
-    alarm>> [ cancel-alarm ] if-box? ;
+: schange ( key quot -- )
+    session get swap change-at
+    session-changed? on ; inline
 
-: delete-session ( session -- )
-    [ cancel-timeout ]
-    [ dup manager>> sessions>> delete-at ]
-    bi ;
+: sessions session-manager get sessions>> ;
 
-: touch-session ( session -- session )
-    [ cancel-timeout ]
-    [ [ '[ , delete-session ] timeout later ] keep alarm>> >box ]
-    [ ]
-    tri ;
+: managed-responder session-manager get responder>> ;
 
-: session ( -- assoc ) \ session get namespace>> ;
+: init-session ( managed -- session )
+    H{ } clone [ session [ init-session* ] with-variable ] keep ;
 
-: sget ( key -- value ) session at ;
+: begin-session ( responder -- id session )
+    [ responder>> init-session ] [ sessions>> ] bi
+    [ new-session ] [ drop ] 2bi ;
 
-: sset ( value key -- ) session set-at ;
+! Destructor
+TUPLE: session-saver id session ;
 
-: schange ( key quot -- ) session swap change-at ; inline
+C: <session-saver> session-saver
 
-: init-session ( session -- session )
-    dup dup \ session [
-        manager>> responder>> init-session*
-    ] with-variable ;
+M: session-saver dispose
+    session-changed? get [
+        [ session>> ] [ id>> ] bi
+        sessions update-session
+    ] [ drop ] if ;
 
-: new-session ( responder -- id )
-    [ <session> init-session touch-session ]
-    [ [ sessions>> set-at-unique ] [ drop swap >>id ] 2bi ]
-    bi id>> ;
+: save-session-after ( id session -- )
+    <session-saver> add-always-destructor ;
 
-: get-session ( id responder -- session/f )
-    sessions>> at* [ touch-session ] when ;
-
-: call-responder/session ( path responder session -- response )
-    \ session set responder>> call-responder ;
-
-: sessions ( -- manager/f )
-    \ session get dup [ manager>> ] when ;
+: call-responder/session ( path responder id session -- response )
+    [ save-session-after ]
+    [ [ session-id set ] [ session set ] bi* ] 2bi
+    [ session-manager set ] [ responder>> call-responder ] bi ;
 
 TUPLE: null-sessions ;
 
@@ -74,56 +70,64 @@ TUPLE: null-sessions ;
     null-sessions <session-manager> ;
 
 M: null-sessions call-responder ( path responder -- response )
-    dup <session> call-responder/session ;
+    H{ } clone f call-responder/session ;
 
 TUPLE: url-sessions ;
 
 : <url-sessions> ( responder -- responder' )
     url-sessions <session-manager> ;
 
-: sess-id "factorsessid" ;
+: session-id-key "factorsessid" ;
 
-: current-session ( responder -- session )
-    >r request-params sess-id swap at r> get-session ;
+: current-url-session ( responder -- id/f session/f )
+    [ request-params session-id-key swap at ] [ sessions>> ] bi*
+    [ drop ] [ get-session ] 2bi ;
 
 : add-session-id ( query -- query' )
-    \ session get [ id>> sess-id associate union ] when* ;
+    session-id get [ session-id-key associate union ] when* ;
 
 : session-form-field ( -- )
     <input
-    "hidden" =type
-    sess-id =id
-    sess-id =name
-    \ session get id>> =value
+        "hidden" =type
+        session-id-key =id
+        session-id-key =name
+        session-id get =value
     input/> ;
 
+: new-url-session ( responder -- response )
+    [ f ] [ begin-session drop session-id-key associate ] bi*
+    <temporary-redirect> ;
+
 M: url-sessions call-responder ( path responder -- response )
     [ add-session-id ] link-hook set
     [ session-form-field ] form-hook set
-    dup current-session [
+    dup current-url-session dup [
         call-responder/session
     ] [
-        nip
-        f swap new-session sess-id associate <temporary-redirect>
-    ] if* ;
+        2drop nip new-url-session
+    ] if ;
 
 TUPLE: cookie-sessions ;
 
 : <cookie-sessions> ( responder -- responder' )
     cookie-sessions <session-manager> ;
 
-: get-session-cookie ( responder -- cookie )
-    request get sess-id get-cookie
-    [ value>> swap get-session ] [ drop f ] if* ;
+: current-cookie-session ( responder -- id namespace/f )
+    request get session-id-key get-cookie dup
+    [ value>> dup rot sessions>> get-session ] [ 2drop f f ] if ;
 
 : <session-cookie> ( id -- cookie )
-    sess-id <cookie> ;
+    session-id-key <cookie> ;
+
+: call-responder/new-session ( path responder -- response )
+    dup begin-session
+    [ call-responder/session ]
+    [ drop <session-cookie> ] 2bi
+    put-cookie ;
 
 M: cookie-sessions call-responder ( path responder -- response )
-    dup get-session-cookie [
+    dup current-cookie-session dup [
         call-responder/session
     ] [
-        dup new-session
-        [ over get-session call-responder/session ] keep
-        <session-cookie> put-cookie
-    ] if* ;
+        2drop call-responder/new-session
+    ] if ;
diff --git a/extra/http/server/sessions/storage/assoc/assoc.factor b/extra/http/server/sessions/storage/assoc/assoc.factor
new file mode 100755 (executable)
index 0000000..1339e3c
--- /dev/null
@@ -0,0 +1,38 @@
+! Copyright (C) 2008 Slava Pestov.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: assocs assocs.lib new-slots accessors\r
+http.server.sessions.storage combinators.cleave alarms kernel\r
+fry http.server ;\r
+IN: http.server.sessions.storage.assoc\r
+\r
+TUPLE: sessions-in-memory sessions alarms ;\r
+\r
+: <sessions-in-memory> ( -- storage )\r
+    H{ } clone H{ } clone sessions-in-memory construct-boa ;\r
+\r
+: cancel-session-timeout ( id storage -- )\r
+    alarms>> at [ cancel-alarm ] when* ;\r
+\r
+: touch-session ( id storage -- )\r
+    [ cancel-session-timeout ]\r
+    [ '[ , , delete-session ] timeout later ]\r
+    [ alarms>> set-at ]\r
+    2tri ;\r
+\r
+M: sessions-in-memory get-session ( id storage -- namespace )\r
+    [ sessions>> at ] [ touch-session ] 2bi ;\r
+\r
+M: sessions-in-memory update-session ( namespace id storage -- )\r
+    [ sessions>> set-at ]\r
+    [ touch-session ]\r
+    2bi ;\r
+\r
+M: sessions-in-memory delete-session ( id storage -- )\r
+    [ sessions>> delete-at ]\r
+    [ cancel-session-timeout ]\r
+    2bi ;\r
+\r
+M: sessions-in-memory new-session ( namespace storage -- id )\r
+    [ sessions>> set-at-unique ]\r
+    [ [ touch-session ] [ drop ] 2bi ]\r
+    bi ;\r
diff --git a/extra/http/server/sessions/storage/db/db-tests.factor b/extra/http/server/sessions/storage/db/db-tests.factor
new file mode 100755 (executable)
index 0000000..4e6ae8a
--- /dev/null
@@ -0,0 +1,24 @@
+IN: http.server.sessions.storage.db\r
+USING: http.server.sessions.storage\r
+http.server.sessions.storage.db namespaces io.files\r
+db.sqlite db accessors math tools.test kernel assocs\r
+sequences ;\r
+\r
+sessions-in-db "storage" set\r
+\r
+"auth-test.db" temp-file sqlite-db [\r
+    [ ] [ init-sessions-table ] unit-test\r
+\r
+    [ f ] [ H{ } "storage" get new-session empty? ] unit-test\r
+\r
+    H{ } "storage" get new-session "id" set\r
+\r
+    "id" get "storage" get get-session "session" set\r
+    "a" "b" "session" get set-at\r
+\r
+    "session" get "id" get "storage" get update-session\r
+\r
+    [ H{ { "b" "a" } } ] [\r
+        "id" get "storage" get get-session\r
+    ] unit-test\r
+] with-db\r
diff --git a/extra/http/server/sessions/storage/db/db.factor b/extra/http/server/sessions/storage/db/db.factor
new file mode 100755 (executable)
index 0000000..07cd22b
--- /dev/null
@@ -0,0 +1,46 @@
+! Copyright (C) 2008 Slava Pestov.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: assocs new-slots accessors http.server.sessions.storage\r
+alarms kernel http.server db.tuples db.types singleton\r
+combinators.cleave math.parser ;\r
+IN: http.server.sessions.storage.db\r
+\r
+SINGLETON: sessions-in-db\r
+\r
+TUPLE: session id namespace ;\r
+\r
+session "SESSIONS"\r
+{\r
+    { "id" "ID" INTEGER +native-id+ }\r
+    { "namespace" "NAMESPACE" FACTOR-BLOB }\r
+} define-persistent\r
+\r
+: init-sessions-table session ensure-table ;\r
+\r
+: <session> ( id -- session )\r
+    session construct-empty\r
+        swap dup [ string>number ] when >>id ;\r
+\r
+M: sessions-in-db get-session ( id storage -- namespace/f )\r
+    drop\r
+    dup [\r
+        <session>\r
+        select-tuple dup [ namespace>> ] when\r
+    ] when ;\r
+\r
+M: sessions-in-db update-session ( namespace id storage -- )\r
+    drop\r
+    <session>\r
+        swap >>namespace\r
+    update-tuple ;\r
+\r
+M: sessions-in-db delete-session ( id storage -- )\r
+    drop\r
+    <session>\r
+    delete-tuple ;\r
+\r
+M: sessions-in-db new-session ( namespace storage -- id )\r
+    drop\r
+    f <session>\r
+        swap >>namespace\r
+    [ insert-tuple ] [ id>> number>string ] bi ;\r
diff --git a/extra/http/server/sessions/storage/storage.factor b/extra/http/server/sessions/storage/storage.factor
new file mode 100755 (executable)
index 0000000..df96c81
--- /dev/null
@@ -0,0 +1,14 @@
+! Copyright (C) 2008 Slava Pestov.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: calendar ;\r
+IN: http.server.sessions.storage\r
+\r
+: timeout 20 minutes ;\r
+\r
+GENERIC: get-session ( id storage -- namespace )\r
+\r
+GENERIC: update-session ( namespace id storage -- )\r
+\r
+GENERIC: delete-session ( id storage -- )\r
+\r
+GENERIC: new-session ( namespace storage -- id )\r
index 3ef2b6c8631c2e3018db01b6421a35745302f4b0..82827ac450f74b97c774bfde6d68ca1988227acc 100755 (executable)
@@ -2,7 +2,8 @@ IN: http.server.validators.tests
 USING: kernel sequences tools.test http.server.validators
 accessors ;
 
-[ "foo" v-number ] [ validation-error? ] must-fail-with
+[ "foo" v-number ] must-fail
+[ 123 ] [ "123" v-number ] unit-test
 
 [ "slava@factorcode.org" ] [
     "slava@factorcode.org" v-email
@@ -13,10 +14,10 @@ accessors ;
 ] unit-test
 
 [ "slava@factorcode.o" v-email ]
-[ reason>> "invalid e-mail" = ] must-fail-with
+[ "invalid e-mail" = ] must-fail-with
 
 [ "sla@@factorcode.o" v-email ]
-[ reason>> "invalid e-mail" = ] must-fail-with
+[ "invalid e-mail" = ] must-fail-with
 
 [ "slava@factorcodeorg" v-email ]
-[ reason>> "invalid e-mail" = ] must-fail-with
+[ "invalid e-mail" = ] must-fail-with
index 7eb5163d33da5322e6fb1e5d996aa5dd706ce182..539a58d19f52d13b6785bcc08e581784d6059045 100755 (executable)
@@ -5,21 +5,26 @@ math.parser assocs new-slots regexp fry unicode.categories
 combinators.cleave sequences ;
 IN: http.server.validators
 
+SYMBOL: validation-failed?
+
 TUPLE: validation-error value reason ;
 
-: validation-error ( value reason -- * )
-    \ validation-error construct-boa throw ;
+C: <validation-error> validation-error
+
+: with-validator ( value quot -- result )
+    [ validation-failed? on <validation-error> ] recover ;
+    inline
 
 : v-default ( str def -- str )
     over empty? spin ? ;
 
 : v-required ( str -- str )
-    dup empty? [ "required" validation-error ] when ;
+    dup empty? [ "required" throw ] when ;
 
 : v-min-length ( str n -- str )
     over length over < [
         [ "must be at least " % # " characters" % ] "" make
-        validation-error
+        throw
     ] [
         drop
     ] if ;
@@ -27,35 +32,34 @@ TUPLE: validation-error value reason ;
 : v-max-length ( str n -- str )
     over length over > [
         [ "must be no more than " % # " characters" % ] "" make
-        validation-error
+        throw
     ] [
         drop
     ] if ;
 
 : v-number ( str -- n )
-    dup string>number [ ] [
-        "must be a number" validation-error
-    ] ?if ;
+    dup string>number [ ] [ "must be a number" throw ] ?if ;
+
+: v-integer ( n -- n )
+    dup integer? [ "must be an integer" throw ] unless ;
 
 : v-min-value ( x n -- x )
     2dup < [
-        [ "must be at least " % # ] "" make
-        validation-error
+        [ "must be at least " % # ] "" make throw
     ] [
         drop
     ] if ;
 
 : v-max-value ( x n -- x )
     2dup > [
-        [ "must be no more than " % # ] "" make
-        validation-error
+        [ "must be no more than " % # ] "" make throw
     ] [
         drop
     ] if ;
 
 : v-regexp ( str what regexp -- str )
     >r over r> matches?
-    [ drop ] [ "invalid " swap append validation-error ] if ;
+    [ drop ] [ "invalid " swap append throw ] if ;
 
 : v-email ( str -- str )
     #! From http://www.regular-expressions.info/email.html
@@ -64,12 +68,12 @@ TUPLE: validation-error value reason ;
     v-regexp ;
 
 : v-captcha ( str -- str )
-    dup empty? [ "must remain blank" validation-error ] unless ;
+    dup empty? [ "must remain blank" throw ] unless ;
 
 : v-one-line ( str -- str )
     dup "\r\n" seq-intersect empty?
-    [ "must be a single line" validation-error ] unless ;
+    [ "must be a single line" throw ] unless ;
 
 : v-one-word ( str -- str )
     dup [ alpha? ] all?
-    [ "must be a single word" validation-error ] unless ;
+    [ "must be a single word" throw ] unless ;
old mode 100644 (file)
new mode 100755 (executable)
index 5370817..9e19245
@@ -34,7 +34,7 @@ accessors kernel sequences ;
     ascii <process-stream> contents
 ] unit-test
 
-[ "" ] [
+[ f ] [
     <process>
         "cat"
         "launcher-test-1" temp-file
@@ -55,7 +55,7 @@ accessors kernel sequences ;
     try-process
 ] unit-test
 
-[ "" ] [
+[ f ] [
     "cat"
     "launcher-test-1" temp-file
     2array
index 01e29866ebdaeb768a07083ce7c11d5a7a94c9e2..1f0492a0602c05e5d07c7dc606f4eff9532df304 100755 (executable)
@@ -3,5 +3,3 @@ io.unix.launcher io.unix.mmap io.backend
 combinators namespaces system vocabs.loader sequences ;
 
 "io.unix." os append require
-
-"tools.vocabs.monitor" require
index 2180ff79017b9ad82779fa84c9dd8283b7b06b71..35aaf456a39b6bbe87e37c1403fcbc2d1948332a 100755 (executable)
@@ -7,7 +7,7 @@ sequences namespaces words symbols ;
 IN: io.windows.files
 
 SYMBOLS: +read-only+ +hidden+ +system+
-+directory+ +archive+ +device+ +normal+ +temporary+
++archive+ +device+ +normal+ +temporary+
 +sparse-file+ +reparse-point+ +compressed+ +offline+
 +not-content-indexed+ +encrypted+ ;
 
index 319acc35f8b1c77c029eb7f41831bce67243c014..1baec5658f1d0747e219a6efd46735a6b5721b0d 100755 (executable)
@@ -13,5 +13,3 @@ USE: io.windows.files
 USE: io.backend
 
 T{ windows-nt-io } set-io-backend
-
-"tools.vocabs.monitor" require
index f6a9dd451fe326444ba1e4ee6b76c7fb472475a5..dac55664a4a63c6cfdfb363947323bfe49d7b4b3 100755 (executable)
@@ -76,11 +76,8 @@ M: win32-file close-handle ( handle -- )
     ] when drop ;
 
 : open-append ( path -- handle length )
-    dup file-info file-info-size dup [
-        >r (open-append) r> 2dup set-file-pointer
-    ] [
-        drop open-write
-    ] if ;
+    [ dup file-info file-info-size ] [ drop 0 ] recover
+    >r (open-append) r> 2dup set-file-pointer ;
 
 TUPLE: FileArgs
     hFile lpBuffer nNumberOfBytesToRead lpNumberOfBytesRet lpOverlapped ;
index ae613bd461009fab3b25a29a0d6c96af8bbc102f..6db68840712a579f7a7f5d94978f7410288e44c6 100755 (executable)
@@ -10,9 +10,9 @@ USING: alien alien.syntax combinators kernel system ;
 IN: ldap.libldap
 
 << "libldap" {
-    { [ win32? ] [ "libldap.dll" "stdcall" ] }
+    { [ win32? ]  [ "libldap.dll" "stdcall" ] }
     { [ macosx? ] [ "libldap.dylib" "cdecl" ] }
-    { [ unix? ] [ "$LD_LIBRARY_PATH/libldap.so" "cdecl" ] }
+    { [ unix? ]   [ "libldap.so" "cdecl" ] }
 } cond add-library >>
  
 : LDAP_VERSION1     1 ; inline
index b4f1b0a61edddb37e86eb2a7308dd590ecbe53fc..bd1e62f22a581852244b6e93ffc8408f4f20dd34 100755 (executable)
@@ -1,5 +1,6 @@
 USING: locals math sequences tools.test hashtables words kernel
-namespaces arrays strings prettyprint ;
+namespaces arrays strings prettyprint io.streams.string parser
+;
 IN: locals.tests
 
 :: foo ( a b -- a a ) a a ;
@@ -178,3 +179,19 @@ M:: string lambda-generic ( a b -- c ) a b lambda-generic-2 ;
 [ "[| a! | ]" ] [
     [| a! | ] unparse
 ] unit-test
+
+DEFER: xyzzy
+
+[ ] [
+    "IN: locals.tests USE: math GENERIC: xyzzy M: integer xyzzy ;"
+    <string-reader> "lambda-generic-test" parse-stream drop
+] unit-test
+
+[ 10 ] [ 10 xyzzy ] unit-test
+
+[ ] [
+    "IN: locals.tests USE: math USE: locals GENERIC: xyzzy M:: integer xyzzy ( n -- ) 5 ;"
+    <string-reader> "lambda-generic-test" parse-stream drop
+] unit-test
+
+[ 5 ] [ 10 xyzzy ] unit-test
index 9819e65e37438337b7f97ac7b90bfcddc7a5d387..a8f5e139e723a5e0709f224251e0ab9e56ff3227 100755 (executable)
@@ -249,13 +249,14 @@ M: wlet local-rewrite*
     word [ over "declared-effect" set-word-prop ] when*
     effect-in make-locals ;
 
-: ((::)) ( word -- word quot )
+: parse-locals-definition ( word -- word quot )
     scan "(" assert= parse-locals \ ; (parse-lambda) <lambda>
     2dup "lambda" set-word-prop
     lambda-rewrite first ;
 
-: (::) ( -- word quot )
-    CREATE dup reset-generic ((::)) ;
+: (::) CREATE-WORD parse-locals-definition ;
+
+: (M::) CREATE-METHOD parse-locals-definition ;
 
 PRIVATE>
 
@@ -275,18 +276,7 @@ MACRO: with-locals ( form -- quot ) lambda-rewrite ;
 
 : :: (::) define ; parsing
 
-! This will be cleaned up when method tuples and method words
-! are unified
-: create-method ( class generic -- method )
-    2dup method dup
-    [ 2nip ]
-    [ drop 2dup [ ] -rot define-method create-method ] if ;
-
-: CREATE-METHOD ( -- class generic body )
-    scan-word bootstrap-word scan-word 2dup
-    create-method f set-word dup save-location ;
-
-: M:: CREATE-METHOD ((::)) nip -rot define-method ; parsing
+: M:: (M::) define ; parsing
 
 : MACRO:: (::) define-macro ; parsing
 
index 5846515dca15d5cf07d2a57491414216b60d48af..42545500a553d1cce769fd688a94bd7078887826 100755 (executable)
@@ -127,8 +127,7 @@ PRIVATE>
 \r
 : LOG:\r
     #! Syntax: name level\r
-    CREATE\r
-    dup reset-generic\r
+    CREATE-WORD\r
     dup scan-word\r
     [ >r >r 1array stack>message r> r> log-message ] 2curry\r
     define ; parsing\r
index d181ab8a169574b4a1af26395cc72b1452569587..372216c45e3d9d4d90eeec9af6f527930cab7294 100755 (executable)
@@ -3,8 +3,8 @@
 USING: namespaces kernel io calendar sequences io.files\r
 io.sockets continuations prettyprint assocs math.parser\r
 words debugger math combinators concurrency.messaging\r
-threads arrays init math.ranges strings calendar.format
-io.encodings.ascii ;\r
+threads arrays init math.ranges strings calendar.format\r
+io.encodings.utf8 ;\r
 IN: logging.server\r
 \r
 : log-root ( -- string )\r
@@ -21,7 +21,7 @@ SYMBOL: log-files
 : open-log-stream ( service -- stream )\r
     log-path\r
     dup make-directories\r
-    1 log# ascii <file-appender> ;\r
+    1 log# utf8 <file-appender> ;\r
 \r
 : log-stream ( service -- stream )\r
     log-files get [ open-log-stream ] cache ;\r
index 3b0b8fd29f2e0e6617861bf3413bc0209a66a772..ab915ae7d5d7d2555deade4ba3e35e8f3cbd4128 100755 (executable)
@@ -40,7 +40,7 @@ IN: memoize
     over make-memoizer define ;
 
 : MEMO:
-    CREATE dup reset-generic parse-definition define-memoized ; parsing
+    CREATE-WORD parse-definition define-memoized ; parsing
 
 PREDICATE: word memoized "memoize" word-prop ;
 
index 5baa205d15714e415525148964f79d6c5f78e76e..079f4842747ba95740c75c39383aaa5440bde1f8 100755 (executable)
@@ -18,7 +18,7 @@ IN: multiline
     lexer get next-line ;
 
 : STRING:
-    CREATE dup reset-generic
+    CREATE-WORD
     parse-here 1quotation define-inline ; parsing
 
 : (parse-multiline-string) ( start-index end-text -- end-index )
diff --git a/extra/namespaces/lib/lib-tests.factor b/extra/namespaces/lib/lib-tests.factor
new file mode 100755 (executable)
index 0000000..20769e1
--- /dev/null
@@ -0,0 +1,6 @@
+IN: namespaces.lib.tests\r
+USING: namespaces.lib tools.test ;\r
+\r
+[ ] [ [ ] { } nmake ] unit-test\r
+\r
+[ { 1 } { 2 } ] [ [ 1 0, 2 1, ] { { } { } } nmake ] unit-test\r
old mode 100644 (file)
new mode 100755 (executable)
index 76ba0ac..47b6b33
@@ -2,7 +2,7 @@
 ! USING: kernel quotations namespaces sequences assocs.lib ;
 
 USING: kernel namespaces namespaces.private quotations sequences
-       assocs.lib math.parser math sequences.lib ;
+       assocs.lib math.parser math sequences.lib locals ;
 
 IN: namespaces.lib
 
@@ -42,11 +42,19 @@ SYMBOL: building-seq
 : 4% 4 n% ;
 : 4# 4 n# ;
 
-: nmake ( quot exemplars -- seqs )
-    dup length dup zero? [ 1+ ] when
-    [
+MACRO:: nmake ( quot exemplars -- )
+    [let | n [ exemplars length ] |
         [
-            [ drop 1024 swap new-resizable ] 2map
-            [ building-seq set call ] keep
-        ] 2keep >r [ like ] 2map r> firstn 
-    ] with-scope ;
+            [
+                exemplars
+                [ 0 swap new-resizable ] map
+                building-seq set
+
+                quot call
+
+                building-seq get
+                exemplars [ like ] 2map
+                n firstn
+            ] with-scope
+        ]
+    ] ;
diff --git a/extra/opengl/gl/gl-docs.factor b/extra/opengl/gl/gl-docs.factor
new file mode 100644 (file)
index 0000000..f244b4d
--- /dev/null
@@ -0,0 +1,85 @@
+
+USING: help.syntax help.markup ;
+
+IN: opengl.gl
+
+ARTICLE: "opengl-low-level" "OpenGL Library (low level)"
+  { $subsection "opengl-specifying-vertices" }
+  { $subsection "opengl-geometric-primitives" }
+  { $subsection "opengl-modeling-transformations" } ;
+
+ARTICLE: "opengl-specifying-vertices" "Specifying Vertices"
+
+  { $subsection glVertex2d }
+  { $subsection glVertex2f }
+  { $subsection glVertex2i }
+  { $subsection glVertex2s }
+  { $subsection glVertex3d }
+  { $subsection glVertex3f }
+  { $subsection glVertex3i }
+  { $subsection glVertex3s }
+  { $subsection glVertex4d }
+  { $subsection glVertex4f }
+  { $subsection glVertex4i }
+  { $subsection glVertex4s }
+  { $subsection glVertex2dv }
+  { $subsection glVertex2fv }
+  { $subsection glVertex2iv }
+  { $subsection glVertex2sv }
+  { $subsection glVertex3dv }
+  { $subsection glVertex3fv }
+  { $subsection glVertex3iv }
+  { $subsection glVertex3sv }
+  { $subsection glVertex4dv }
+  { $subsection glVertex4fv }
+  { $subsection glVertex4iv }
+  { $subsection glVertex4sv } ;
+
+ARTICLE: "opengl-geometric-primitives" "OpenGL Geometric Primitives"
+
+  { $table
+      { { $link GL_POINTS         } "individual points" }
+      { { $link GL_LINES          } { "pairs of vertices interpreted as "
+                                      "individual line segments" } }
+      { { $link GL_LINE_STRIP     } "series of connected line segments" }
+      { { $link GL_LINE_LOOP      } { "same as above, with a segment added "
+                                      "between last and first vertices" } }
+      { { $link GL_TRIANGLES      }
+        "triples of vertices interpreted as triangles" }
+      { { $link GL_TRIANGLE_STRIP } "linked strip of triangles" }
+      { { $link GL_TRIANGLE_FAN   } "linked fan of triangles" }
+      { { $link GL_QUADS          }
+        "quadruples of vertices interpreted as four-sided polygons" }
+      { { $link GL_QUAD_STRIP     } "linked strip of quadrilaterals" }
+      { { $link GL_POLYGON        } "boundary of a simple, convex polygon" } }
+
+;
+
+HELP: glBegin
+  { $values { "mode"
+              { "One of the " { $link "opengl-geometric-primitives" } } } } ;
+
+HELP: glPolygonMode
+  { $values { "face" { "One of the following:"
+                       { $list { $link GL_FRONT }
+                               { $link GL_BACK }
+                               { $link GL_FRONT_AND_BACK } } } }
+            { "mode" { "One of the following:"
+                       { $list
+                         { $link GL_POINT }
+                         { $link GL_LINE }
+                         { $link GL_FILL } } } } } ;
+
+ARTICLE: "opengl-modeling-transformations" "Modeling Transformations"
+  { $subsection glTranslatef }
+  { $subsection glTranslated }
+  { $subsection glRotatef }
+  { $subsection glRotated }
+  { $subsection glScalef }
+  { $subsection glScaled } ;
+
+
+{ glTranslatef glTranslated glRotatef glRotated glScalef glScaled }
+related-words
+
+
index 97120237ecf88ff4547fd20fca35de63989e20cd..5b1ee0d565ed43c9ce9e39de50eee1ddbe959ce6 100644 (file)
@@ -10,7 +10,11 @@ HELP: gl-error
 { $description "If the most recent OpenGL call resulted in an error, print the error to the " { $link stdio } " stream." } ;
 
 HELP: do-state
-{ $values { "what" integer } { "quot" quotation } }
+  {
+    $values
+      { "mode" { "One of the " { $link "opengl-geometric-primitives" } } }
+      { "quot" quotation }
+  }
 { $description "Wraps a quotation in " { $link glBegin } "/" { $link glEnd } " calls." } ;
 
 HELP: do-enabled
index 5afb6ef0702a1f46a93850640a95b084ad0906fd..08e3cb204b35a193e95681150f7d3213610a760e 100755 (executable)
@@ -25,7 +25,7 @@ IN: opengl
         "GL error: " over gluErrorString append throw
     ] unless drop ;
 
-: do-state ( what quot -- )
+: do-state ( mode quot -- )
     swap glBegin call glEnd ; inline
 
 : do-enabled ( what quot -- )
index 8378a1195617d1740ca7364d21a277d37c016fcb..d06afdc5ea808031aade8927b19d419b5e62f69b 100755 (executable)
@@ -9,11 +9,13 @@ USING: alien alien.syntax combinators kernel system ;
 
 IN: openssl.libcrypto
 
+<<
 "libcrypto" {
-    { [ win32? ] [ "libeay32.dll" "stdcall" ] }
+    { [ win32? ]  [ "libeay32.dll" "cdecl" ] }
     { [ macosx? ] [ "libcrypto.dylib" "cdecl" ] }
-    { [ unix? ] [ "$LD_LIBRARY_PATH/libcrypto.so" "cdecl" ] }
+    { [ unix? ]   [ "libcrypto.so" "cdecl" ] }
 } cond add-library
+>>
 
 C-STRUCT: bio-method
     { "int" "type" }
old mode 100644 (file)
new mode 100755 (executable)
index 8d1b3b5..11dcee3
@@ -10,9 +10,9 @@ USING: alien alien.syntax combinators kernel system ;
 IN: openssl.libssl
 
 << "libssl" {
-    { [ win32? ] [ "ssleay32.dll" "stdcall" ] }
+    { [ win32? ]  [ "ssleay32.dll" "cdecl" ] }
     { [ macosx? ] [ "libssl.dylib" "cdecl" ] }
-    { [ unix? ] [ "$LD_LIBRARY_PATH/libssl.so" "cdecl" ] }
+    { [ unix? ]   [ "libssl.so" "cdecl" ] }
 } cond add-library >>
 
 : X509_FILETYPE_PEM       1 ; inline
index c40bc5628b24a3444769e70922772e34b59eb435..2d0f5bb5d0da62e6dff3fa3ad702529ca0f52a4d 100755 (executable)
@@ -21,55 +21,55 @@ namespaces math math.parser openssl prettyprint sequences tools.test ;
 ! Initialize context
 ! =========================================================
 
-init load-error-strings
+[ ] [ init load-error-strings ] unit-test
 
-ssl-v23 new-ctx
+[ ] [ ssl-v23 new-ctx ] unit-test
 
-get-ctx "/extra/openssl/test/server.pem" resource-path use-cert-chain
+[ ] [ get-ctx "/extra/openssl/test/server.pem" resource-path use-cert-chain ] unit-test
 
 ! TODO: debug 'Memory protection fault at address 6c'
 ! get-ctx 1024 "char" malloc-array 1024 0 f password-cb set-default-passwd
 
-get-ctx "password" string>char-alien set-default-passwd-userdata
+[ ] [ get-ctx "password" string>char-alien set-default-passwd-userdata ] unit-test
 
 ! Enter PEM pass phrase: password
-get-ctx "/extra/openssl/test/server.pem" resource-path
-SSL_FILETYPE_PEM use-private-key
+[ ] [ get-ctx "/extra/openssl/test/server.pem" resource-path
+SSL_FILETYPE_PEM use-private-key ] unit-test
 
-get-ctx "/extra/openssl/test/root.pem" resource-path f
-verify-load-locations
+[ ] [ get-ctx "/extra/openssl/test/root.pem" resource-path f
+verify-load-locations ] unit-test
 
-get-ctx 1 set-verify-depth
+[ ] [ get-ctx 1 set-verify-depth ] unit-test
 
 ! =========================================================
 ! Load Diffie-Hellman parameters
 ! =========================================================
 
-"/extra/openssl/test/dh1024.pem" resource-path "r" bio-new-file
+[ ] [ "/extra/openssl/test/dh1024.pem" resource-path "r" bio-new-file ] unit-test
 
-get-bio f f f read-pem-dh-params
+[ ] [ get-bio f f f read-pem-dh-params ] unit-test
 
-get-bio bio-free
+[ ] [ get-bio bio-free ] unit-test
 
 ! TODO: debug SSL_CTX_set_tmp_dh 'No such symbol'
-! get-ctx get-dh set-tmp-dh-callback
+[ ] [ get-ctx get-dh set-tmp-dh-callback ] unit-test
 
 ! Workaround (this function should never be called directly)
-get-ctx SSL_CTRL_SET_TMP_DH 0 get-dh set-ctx-ctrl
+! [ ] [ get-ctx SSL_CTRL_SET_TMP_DH 0 get-dh set-ctx-ctrl ] unit-test
 
 ! =========================================================
 ! Generate ephemeral RSA key
 ! =========================================================
 
-512 RSA_F4 f f generate-rsa-key
+[ ] [ 512 RSA_F4 f f generate-rsa-key ] unit-test
 
 ! TODO: debug SSL_CTX_set_tmp_rsa 'No such symbol'
 ! get-ctx get-rsa set-tmp-rsa-callback
 
 ! Workaround (this function should never be called directly)
-get-ctx SSL_CTRL_SET_TMP_RSA 0 get-rsa set-ctx-ctrl
+[ ] [ get-ctx SSL_CTRL_SET_TMP_RSA 0 get-rsa set-ctx-ctrl ] unit-test
 
-get-rsa free-rsa
+[ ] [ get-rsa free-rsa ] unit-test
 
 ! =========================================================
 ! Listen and accept on socket
@@ -129,11 +129,11 @@ get-rsa free-rsa
 ! Dump errors to file
 ! =========================================================
 
-"/extra/openssl/test/errors.txt" resource-path "w" bio-new-file
+[ ] [ "/extra/openssl/test/errors.txt" resource-path "w" bio-new-file ] unit-test
 
 [ 6 ] [ get-bio "Hello\n" bio-print ] unit-test
 
-get-bio bio-free
+[ ] [ get-bio bio-free ] unit-test
 
 ! =========================================================
 ! Clean-up
diff --git a/extra/pdf/authors.txt b/extra/pdf/authors.txt
deleted file mode 100644 (file)
index 7c29e7c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Elie Chaftari
diff --git a/extra/pdf/libhpdf/libhpdf.factor b/extra/pdf/libhpdf/libhpdf.factor
deleted file mode 100644 (file)
index a40b7cd..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-! Copyright (C) 2007 Elie CHAFTARI
-! See http://factorcode.org/license.txt for BSD license.
-!
-! Tested with libharu2 2.0.8 on Mac OS X 10.4.9 PowerPC
-!
-! export LD_LIBRARY_PATH=/opt/local/lib
-
-USING: alien alien.syntax combinators system ;
-
-IN: pdf.libhpdf
-
-<< "libhpdf" {
-    { [ win32? ] [ "libhpdf.dll" "stdcall" ] }
-    { [ macosx? ] [ "libhpdf.dylib" "cdecl" ] }
-    { [ unix? ] [ "$LD_LIBRARY_PATH/libhpdf.so" "cdecl" ] }
-} cond add-library >>
-
-! compression mode
-: HPDF_COMP_NONE      HEX: 00 ; inline ! No contents are compressed
-: HPDF_COMP_TEXT      HEX: 01 ; inline ! Compress contents stream of page
-: HPDF_COMP_IMAGE     HEX: 02 ; inline ! Compress streams of image objects
-: HPDF_COMP_METADATA  HEX: 04 ; inline ! Compress other data (fonts, cmaps...)
-: HPDF_COMP_ALL       HEX: 0F ; inline ! All stream data are compressed
-: HPDF_COMP_MASK      HEX: FF ; inline
-
-! page mode
-C-ENUM:
-    HPDF_PAGE_MODE_USE_NONE
-    HPDF_PAGE_MODE_USE_OUTLINE
-    HPDF_PAGE_MODE_USE_THUMBS
-    HPDF_PAGE_MODE_FULL_SCREEN
-    HPDF_PAGE_MODE_EOF
-;
-
-: error-code ( -- seq ) {
-     { HEX: 1001  "HPDF_ARRAY_COUNT_ERR\nInternal error. The consistency of the data was lost." }
-     { HEX: 1002  "HPDF_ARRAY_ITEM_NOT_FOUND\nInternal error. The consistency of the data was lost." }
-     { HEX: 1003  "HPDF_ARRAY_ITEM_UNEXPECTED_TYPE\nInternal error. The consistency of the data was lost." }
-     { HEX: 1004  "HPDF_BINARY_LENGTH_ERR\nThe length of the data exceeds HPDF_LIMIT_MAX_STRING_LEN." }
-     { HEX: 1005  "HPDF_CANNOT_GET_PALLET\nCannot get a pallet data from PNG image." }
-     { HEX: 1007  "HPDF_DICT_COUNT_ERR\nThe count of elements of a dictionary exceeds HPDF_LIMIT_MAX_DICT_ELEMENT" }
-     { HEX: 1008  "HPDF_DICT_ITEM_NOT_FOUND\nInternal error. The consistency of the data was lost." }
-     { HEX: 1009  "HPDF_DICT_ITEM_UNEXPECTED_TYPE\nInternal error. The consistency of the data was lost." }  
-     { HEX: 100A  "HPDF_DICT_STREAM_LENGTH_NOT_FOUND\nInternal error. The consistency of the data was lost." }  
-     { HEX: 100B  "HPDF_DOC_ENCRYPTDICT_NOT_FOUND\nHPDF_SetPermission() OR HPDF_SetEncryptMode() was called before a password is set." }
-     { HEX: 100C  "HPDF_DOC_INVALID_OBJECT\nInternal error. The consistency of the data was lost." }
-     { HEX: 100E  "HPDF_DUPLICATE_REGISTRATION\nTried to register a font that has been registered." }
-     { HEX: 100F  "HPDF_EXCEED_JWW_CODE_NUM_LIMIT\nCannot register a character to the japanese word wrap characters list." }
-     { HEX: 1011  "HPDF_ENCRYPT_INVALID_PASSWORD\nTried to set the owner password to NULL. owner password and user password is the same." }
-     { HEX: 1013  "HPDF_ERR_UNKNOWN_CLASS\nInternal error. The consistency of the data was lost." }
-     { HEX: 1014  "HPDF_EXCEED_GSTATE_LIMIT\nThe depth of the stack exceeded HPDF_LIMIT_MAX_GSTATE." }
-     { HEX: 1015  "HPDF_FAILED_TO_ALLOC_MEM\nMemory allocation failed." }
-     { HEX: 1016  "HPDF_FILE_IO_ERROR\nFile processing failed. (A detailed code is set.)" }
-     { HEX: 1017  "HPDF_FILE_OPEN_ERROR\nCannot open a file. (A detailed code is set.)" }
-     { HEX: 1019  "HPDF_FONT_EXISTS\nTried to load a font that has already been registered." }
-     { HEX: 101A  "HPDF_FONT_INVALID_WIDTHS_TABLE\nThe format of a font-file is invalid . Internal error. The consistency of the data was lost." }
-     { HEX: 101B  "HPDF_INVALID_AFM_HEADER\nCannot recognize a header of an afm file." }
-     { HEX: 101C  "HPDF_INVALID_ANNOTATION\nThe specified annotation handle is invalid." }
-     { HEX: 101E  "HPDF_INVALID_BIT_PER_COMPONENT\nBit-per-component of a image which was set as mask-image is invalid." }
-     { HEX: 101F  "HPDF_INVALID_CHAR_MATRICS_DATA\nCannot recognize char-matrics-data  of an afm file." }
-     { HEX: 1020  "HPDF_INVALID_COLOR_SPACE\n1. The color_space parameter of HPDF_LoadRawImage is invalid.\n2. Color-space of a image which was set as mask-image is invalid.\n3. The function which is invalid in the present color-space was invoked." }
-     { HEX: 1021  "HPDF_INVALID_COMPRESSION_MODE\nInvalid value was set when invoking HPDF_SetCommpressionMode()." }
-     { HEX: 1022  "HPDF_INVALID_DATE_TIME\nAn invalid date-time value was set." }
-     { HEX: 1023  "HPDF_INVALID_DESTINATION\nAn invalid destination handle was set." }
-     { HEX: 1025  "HPDF_INVALID_DOCUMENT\nAn invalid document handle is set." }
-     { HEX: 1026  "HPDF_INVALID_DOCUMENT_STATE\nThe function which is invalid in the present state was invoked." }
-     { HEX: 1027  "HPDF_INVALID_ENCODER\nAn invalid encoder handle was set." }
-     { HEX: 1028  "HPDF_INVALID_ENCODER_TYPE\nA combination between font and encoder is wrong." }
-     { HEX: 102B  "HPDF_INVALID_ENCODING_NAME\nAn Invalid encoding name is specified." }
-     { HEX: 102C  "HPDF_INVALID_ENCRYPT_KEY_LEN\nThe lengh of the key of encryption is invalid." }
-     { HEX: 102D  "HPDF_INVALID_FONTDEF_DATA\n1. An invalid font handle was set.\n2. Unsupported font format." }
-     { HEX: 102E  "HPDF_INVALID_FONTDEF_TYPE\nInternal error. The consistency of the data was lost." }
-     { HEX: 102F  "HPDF_INVALID_FONT_NAME\nA font which has the specified name is not found." }
-     { HEX: 1030  "HPDF_INVALID_IMAGE\nUnsupported image format." }
-     { HEX: 1031  "HPDF_INVALID_JPEG_DATA\nUnsupported image format." }
-     { HEX: 1032  "HPDF_INVALID_N_DATA\nCannot read a postscript-name from an afm file." }
-     { HEX: 1033  "HPDF_INVALID_OBJECT\n1. An invalid object is set.\n2. Internal error. The consistency of the data was lost." }
-     { HEX: 1034  "HPDF_INVALID_OBJ_ID\nInternal error. The consistency of the data was lost." }
-     { HEX: 1035  "HPDF_INVALID_OPERATION\nInvoked HPDF_Image_SetColorMask() against the image-object which was set a mask-image." }
-     { HEX: 1036  "HPDF_INVALID_OUTLINE\nAn invalid outline-handle was specified." }
-     { HEX: 1037  "HPDF_INVALID_PAGE\nAn invalid page-handle was specified." }
-     { HEX: 1038  "HPDF_INVALID_PAGES\nAn invalid pages-handle was specified. (internal error)" }
-     { HEX: 1039  "HPDF_INVALID_PARAMETER\nAn invalid value is set." }
-     { HEX: 103B  "HPDF_INVALID_PNG_IMAGE\nInvalid PNG image format." }
-     { HEX: 103C  "HPDF_INVALID_STREAM\nInternal error. The consistency of the data was lost." }
-     { HEX: 103D  "HPDF_MISSING_FILE_NAME_ENTRY\nInternal error. The \"_FILE_NAME\" entry for delayed loading is missing." }
-     { HEX: 103F  "HPDF_INVALID_TTC_FILE\nInvalid .TTC file format." }
-     { HEX: 1040  "HPDF_INVALID_TTC_INDEX\nThe index parameter was exceed the number of included fonts" }
-     { HEX: 1041  "HPDF_INVALID_WX_DATA\nCannot read a width-data from an afm file." }
-     { HEX: 1042  "HPDF_ITEM_NOT_FOUND\nInternal error. The consistency of the data was lost." }
-     { HEX: 1043  "HPDF_LIBPNG_ERROR\nAn error has returned from PNGLIB while loading an image." }
-     { HEX: 1044  "HPDF_NAME_INVALID_VALUE\nInternal error. The consistency of the data was lost." }
-     { HEX: 1045  "HPDF_NAME_OUT_OF_RANGE\nInternal error. The consistency of the data was lost." }
-     { HEX: 1049  "HPDF_PAGES_MISSING_KIDS_ENTRY\nInternal error. The consistency of the data was lost." }
-     { HEX: 104A  "HPDF_PAGE_CANNOT_FIND_OBJECT\nInternal error. The consistency of the data was lost." }
-     { HEX: 104B  "HPDF_PAGE_CANNOT_GET_ROOT_PAGES\nInternal error. The consistency of the data was lost." }
-     { HEX: 104C  "HPDF_PAGE_CANNOT_RESTORE_GSTATE\nThere are no graphics-states to be restored." }
-     { HEX: 104D  "HPDF_PAGE_CANNOT_SET_PARENT\nInternal error. The consistency of the data was lost." }
-     { HEX: 104E  "HPDF_PAGE_FONT_NOT_FOUND\nThe current font is not set." }
-     { HEX: 104F  "HPDF_PAGE_INVALID_FONT\nAn invalid font-handle was specified." }
-     { HEX: 1050  "HPDF_PAGE_INVALID_FONT_SIZE\nAn invalid font-size was set." }
-     { HEX: 1051  "HPDF_PAGE_INVALID_GMODE\nSee Graphics mode." }
-     { HEX: 1052  "HPDF_PAGE_INVALID_INDEX\nInternal error. The consistency of the data was lost." }
-     { HEX: 1053  "HPDF_PAGE_INVALID_ROTATE_VALUE\nThe specified value is not a multiple of 90." }
-     { HEX: 1054  "HPDF_PAGE_INVALID_SIZE\nAn invalid page-size was set." }
-     { HEX: 1055  "HPDF_PAGE_INVALID_XOBJECT\nAn invalid image-handle was set." }
-     { HEX: 1056  "HPDF_PAGE_OUT_OF_RANGE\nThe specified value is out of range." }
-     { HEX: 1057  "HPDF_REAL_OUT_OF_RANGE\nThe specified value is out of range." }
-     { HEX: 1058  "HPDF_STREAM_EOF\nUnexpected EOF marker was detected." }
-     { HEX: 1059  "HPDF_STREAM_READLN_CONTINUE\nInternal error. The consistency of the data was lost." }
-     { HEX: 105B  "HPDF_STRING_OUT_OF_RANGE\nThe length of the specified text is too long." }
-     { HEX: 105C  "HPDF_THIS_FUNC_WAS_SKIPPED\nThe execution of a function was skipped because of other errors." }
-     { HEX: 105D  "HPDF_TTF_CANNOT_EMBEDDING_FONT\nThis font cannot be embedded. (restricted by license.)" }
-     { HEX: 105E  "HPDF_TTF_INVALID_CMAP\nUnsupported ttf format. (cannot find unicode cmap.)" }
-     { HEX: 105F  "HPDF_TTF_INVALID_FOMAT\nUnsupported ttf format." }
-     { HEX: 1060  "HPDF_TTF_MISSING_TABLE\nUnsupported ttf format. (cannot find a necessary table.)" }
-     { HEX: 1061  "HPDF_UNSUPPORTED_FONT_TYPE\nInternal error. The consistency of the data was lost." }
-     { HEX: 1062  "HPDF_UNSUPPORTED_FUNC\n1. The library is not configured to use PNGLIB.\n2. Internal error. The consistency of the data was lost." }
-     { HEX: 1063  "HPDF_UNSUPPORTED_JPEG_FORMAT\nUnsupported Jpeg format." }
-     { HEX: 1064  "HPDF_UNSUPPORTED_TYPE1_FONT\nFailed to parse .PFB file." }
-     { HEX: 1065  "HPDF_XREF_COUNT_ERR\nInternal error. The consistency of the data was lost." }
-     { HEX: 1066  "HPDF_ZLIB_ERROR\nAn error has occurred while executing a function of Zlib." }
-     { HEX: 1067  "HPDF_INVALID_PAGE_INDEX\nAn error returned from Zlib." }
-     { HEX: 1068  "HPDF_INVALID_URI\nAn invalid URI was set." }
-     { HEX: 1069  "HPDF_PAGELAYOUT_OUT_OF_RANGE\nAn invalid page-layout was set." }
-     { HEX: 1070  "HPDF_PAGEMODE_OUT_OF_RANGE\nAn invalid page-mode was set." }
-     { HEX: 1071  "HPDF_PAGENUM_STYLE_OUT_OF_RANGE\nAn invalid page-num-style was set." }
-     { HEX: 1072  "HPDF_ANNOT_INVALID_ICON\nAn invalid icon was set." }
-     { HEX: 1073  "HPDF_ANNOT_INVALID_BORDER_STYLE\nAn invalid border-style was set." }
-     { HEX: 1074  "HPDF_PAGE_INVALID_DIRECTION\nAn invalid page-direction was set." }
-     { HEX: 1075  "HPDF_INVALID_FONT\nAn invalid font-handle was specified." }
-} ;
-
-LIBRARY: libhpdf
-
-! ===============================================
-! hpdf.h
-! ===============================================
-
-FUNCTION: void* HPDF_New ( void* user_error_fn, void* user_data ) ;
-
-FUNCTION: void* HPDF_Free ( void* pdf ) ;
-
-FUNCTION: ulong HPDF_SetCompressionMode ( void* pdf, uint mode ) ;
-
-FUNCTION: ulong HPDF_SetPageMode ( void* pdf, uint mode ) ;
-
-FUNCTION: void* HPDF_AddPage ( void* pdf ) ;
-
-FUNCTION: ulong HPDF_SaveToFile ( void* pdf, char* file_name ) ;
-
-FUNCTION: float HPDF_Page_GetHeight ( void* page ) ;
-
-FUNCTION: float HPDF_Page_GetWidth ( void* page ) ;
-
-FUNCTION: ulong HPDF_Page_SetLineWidth ( void* page, float line_width ) ;
-
-FUNCTION: ulong HPDF_Page_Rectangle ( void* page, float x, float y,
-                                      float width, float height ) ;
-
-FUNCTION: ulong HPDF_Page_Stroke ( void* page ) ;
-
-FUNCTION: void* HPDF_GetFont ( void* pdf, char* font_name,
-                               char* encoding_name ) ;
-
-FUNCTION: ulong HPDF_Page_SetFontAndSize ( void* page, void* font,
-                                           float size ) ;
-
-FUNCTION: float HPDF_Page_TextWidth ( void* page, char* text ) ;
-
-FUNCTION: ulong HPDF_Page_BeginText ( void* page ) ;
-
-FUNCTION: ulong HPDF_Page_TextOut ( void* page, float xpos, float ypos,
-                                    char* text ) ;
-
-FUNCTION: ulong HPDF_Page_EndText ( void*  page ) ;
-
-FUNCTION: ulong HPDF_Page_MoveTextPos ( void* page, float x, float y ) ;
-
-FUNCTION: ulong HPDF_Page_ShowText ( void* page, char* text ) ;
diff --git a/extra/pdf/pdf-tests.factor b/extra/pdf/pdf-tests.factor
deleted file mode 100755 (executable)
index 290773a..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-USING: io.files kernel math namespaces pdf pdf.libhpdf prettyprint sequences ;
-IN: pdf.tests
-
-SYMBOL: font
-
-SYMBOL: width
-SYMBOL: height
-SYMBOL: twidth
-
-: font-list ( -- seq ) {
-    "Courier"
-    "Courier-Bold"
-    "Courier-Oblique"
-    "Courier-BoldOblique"
-    "Helvetica"
-    "Helvetica-Bold"
-    "Helvetica-Oblique"
-    "Helvetica-BoldOblique"
-    "Times-Roman"
-    "Times-Bold"
-    "Times-Italic"
-    "Times-BoldItalic"
-    "Symbol"
-    "ZapfDingbats"
-} ;
-
-[
-    ! HPDF_COMP_ALL set-compression-mode
-
-    ! HPDF_PAGE_MODE_USE_OUTLINE set-page-mode
-
-    ! Add a new page object
-    add-page
-
-    get-page-height height set
-
-    get-page-width width set
-
-    ! Print the lines of the page
-    1 set-page-line-width
-
-    50 50 width get 100 - height get 110 - page-rectangle
-
-    page-stroke
-
-    ! Print the title of the page (with positioning center)
-    "Helvetica" f get-font font set
-
-    font get 24 set-page-font-and-size
-
-    "Font Demo" page-text-width twidth set
-
-    [
-        width get twidth get - 2 / height get 50 - "Font Demo" page-text-out
-
-    ] with-text
-
-    ! Print subtitle
-    [
-        font get 16 set-page-font-and-size
-
-        60 height get 80 - "<Standard Type1 font samples>" page-text-out
-
-    ] with-text
-
-    ! Print font list
-    [
-        60 height get 105 - page-move-text-pos
-
-        SYMBOL: fontname
-
-        font-list [
-
-            fontname set
-
-            fontname get f get-font font set
-
-            ! print a label of text
-            font get 9 set-page-font-and-size
-
-            fontname get page-show-text
-
-            0 -18 page-move-text-pos
-
-            ! print a sample text
-            font get 20 set-page-font-and-size
-
-            "abcdefgABCDEFG12345!#$%&+-@?" page-show-text
-
-            0 -20 page-move-text-pos
-
-        ] each
-
-    ] with-text
-
-    "font_test.pdf" temp-file save-to-file
-
-] with-pdf
diff --git a/extra/pdf/pdf.factor b/extra/pdf/pdf.factor
deleted file mode 100644 (file)
index 98c94e5..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-! Copyright (C) 2007 Elie CHAFTARI
-! See http://factorcode.org/license.txt for BSD license.
-!
-! Tested with libharu2 2.0.8 on Mac OS X 10.4.9 PowerPC
-
-USING: assocs continuations hashtables kernel math namespaces pdf.libhpdf ;
-
-IN: pdf
-
-SYMBOL: pdf
-SYMBOL: page
-
-! =========================================================
-! Error handling routines
-! =========================================================
-
-: check-status ( status -- )
-    dup zero? [ 
-        drop
-    ] [
-        error-code >hashtable at throw   
-    ] if ;
-
-! =========================================================
-! Document handling routines
-! =========================================================
-
-: new-pdf ( error-handler user-data -- )
-    HPDF_New pdf set ;
-
-: free-pdf ( -- )
-    pdf get HPDF_Free drop ;
-
-: with-pdf ( quot -- )
-    [ f f new-pdf [ free-pdf ] [ ] cleanup ] with-scope ; inline
-
-: set-compression-mode ( mode -- )
-    pdf get swap HPDF_SetCompressionMode check-status ;
-
-: set-page-mode ( mode -- )
-    pdf get swap HPDF_SetPageMode check-status ;
-
-: add-page ( -- )
-    pdf get HPDF_AddPage page set ;
-
-: save-to-file ( filename -- )
-    pdf get swap HPDF_SaveToFile check-status ;
-
-: get-font ( fontname encoding -- font )
-    pdf get -rot HPDF_GetFont ;
-
-! =========================================================
-! Page Handling routines
-! =========================================================
-
-: get-page-height ( -- height )
-    page get HPDF_Page_GetHeight ;
-
-: get-page-width ( -- width )
-    page get HPDF_Page_GetWidth ;
-
-: page-text-width ( text -- width )
-    page get swap HPDF_Page_TextWidth ;
-
-! =========================================================
-! Graphics routines
-! =========================================================
-
-: set-page-line-width ( linewidth -- )
-    page get swap HPDF_Page_SetLineWidth check-status ;
-
-: page-rectangle ( x y width height -- )
-    >r >r >r >r page get r> r> r> r> HPDF_Page_Rectangle check-status ;
-
-: page-stroke ( -- )
-    page get HPDF_Page_Stroke check-status ;
-
-: set-page-font-and-size ( font size -- )
-    page get -rot HPDF_Page_SetFontAndSize check-status ;
-
-: page-begin-text ( -- )
-    page get HPDF_Page_BeginText check-status ;
-
-: page-text-out ( xpos ypos text -- )
-    page get -roll HPDF_Page_TextOut check-status ;
-
-: page-end-text ( -- )
-    page get HPDF_Page_EndText check-status ;
-
-: with-text ( -- )
-    [ page-begin-text [ page-end-text ] [ ] cleanup ] with-scope ; inline
-
-: page-move-text-pos ( x y -- )
-    page get -rot HPDF_Page_MoveTextPos check-status ;
-
-: page-show-text ( text -- )
-    page get swap HPDF_Page_ShowText check-status ;
diff --git a/extra/pdf/readme.txt b/extra/pdf/readme.txt
deleted file mode 100644 (file)
index fd52944..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-To build libharu as a shared dylib on Mac OS X, modify the Makefile after calling ./configure --shared\r\rHere are the relevant sections and the lines to be changed:\r\r...\rCC=cc\rPREFIX=/usr/local\r\rLIBNAME=libhpdf.a\rSONAME=libhpdf.dylib\rSOVER1=.1\rSOVER2=.0.0\rLIBTARGET=libhpdf.dylib\rCFLAGS=-Iinclude -fPIC -fno-common -c\r...\r$(SONAME): $(OBJS)\r$(CC) -dynamiclib -o $(SONAME)$(SOVER1)$(SOVER2) $(OBJS) $(LDFLAGS) -Wl\rln -sf $(SONAME)$(SOVER1)$(SOVER2) $(SONAME)$(SOVER1)\rln -sf $(SONAME)$(SOVER1) $(SONAME)
-
-Now you can build and install:
-
-make clean
-make
-make install
-
-Test PDF files from pdf-tests.factor are generated in the test folder.
\ No newline at end of file
index 3724b929f02f7dd98902c09a9d33d51be2cfa4be..469f6a91ed68890866cf614d325d54984440d73e 100755 (executable)
@@ -40,6 +40,6 @@ TUPLE: promise quot forced? value ;
   ] [ ] make ;
 
 : LAZY:
-  CREATE dup reset-generic
+  CREATE-WORD
   dup parse-definition
   make-lazy-quot define ; parsing
diff --git a/extra/reports/noise/noise.factor b/extra/reports/noise/noise.factor
new file mode 100755 (executable)
index 0000000..f4b10a7
--- /dev/null
@@ -0,0 +1,174 @@
+USING: assocs math kernel shuffle combinators.lib\r
+words quotations arrays combinators sequences math.vectors\r
+io.styles combinators.cleave prettyprint vocabs sorting io\r
+generic locals.private math.statistics ;\r
+IN: reports.noise\r
+\r
+: badness ( word -- n )\r
+    H{\r
+        { -nrot 5 }\r
+        { -roll 4 }\r
+        { -rot 3 }\r
+        { 2apply 1 }\r
+        { 2curry 1 }\r
+        { 2drop 1 }\r
+        { 2dup 1 }\r
+        { 2keep 1 }\r
+        { 2nip 2 }\r
+        { 2over 4 }\r
+        { 2slip 2 }\r
+        { 2swap 3 }\r
+        { 2with 2 }\r
+        { 2with* 3 }\r
+        { 3apply 1/2 }\r
+        { 3curry 2 }\r
+        { 3drop 1 }\r
+        { 3dup 2 }\r
+        { 3keep 3 }\r
+        { 3nip 4 }\r
+        { 3slip 3 }\r
+        { 3with 3 }\r
+        { 3with* 4 }\r
+        { 4drop 2 }\r
+        { 4dup 3 }\r
+        { 4slip 4 }\r
+        { compose 1/2 }\r
+        { curry 1/3 }\r
+        { dip 1 }\r
+        { dipd 2 }\r
+        { drop 1/3 }\r
+        { dup 1/3 }\r
+        { if 1/3 }\r
+        { when 1/4 }\r
+        { unless 1/4 }\r
+        { when* 1/3 }\r
+        { unless* 1/3 }\r
+        { ?if 1/2 }\r
+        { cond 1/2 }\r
+        { case 1/2 }\r
+        { keep 1 }\r
+        { napply 2 }\r
+        { ncurry 3 }\r
+        { ndip 5 }\r
+        { ndrop 2 }\r
+        { ndup 3 }\r
+        { nip 2 }\r
+        { nipd 3 }\r
+        { nkeep 5 }\r
+        { npick 6 }\r
+        { nrev 5 }\r
+        { nrot 5 }\r
+        { nslip 5 }\r
+        { ntuck 6 }\r
+        { nwith 4 }\r
+        { over 2 }\r
+        { pick 4 }\r
+        { roll 4 }\r
+        { rot 3 }\r
+        { slip 1 }\r
+        { spin 3 }\r
+        { swap 1 }\r
+        { swapd 3 }\r
+        { tuck 2 }\r
+        { tuckd 4 }\r
+        { with 1/2 }\r
+        { with* 2 }\r
+        { r> 1 }\r
+        { >r 1 }\r
+\r
+        { bi 1/2 }\r
+        { tri 1 }\r
+        { bi* 1/2 }\r
+        { tri* 1 }\r
+\r
+        { cleave 2 }\r
+        { spread 2 }\r
+    } at 0 or ;\r
+\r
+: vsum { 0 0 } [ v+ ] reduce ;\r
+\r
+GENERIC: noise ( obj -- pair )\r
+\r
+M: word noise badness 1 2array ;\r
+\r
+M: wrapper noise wrapped noise ;\r
+\r
+M: let noise let-body noise ;\r
+\r
+M: wlet noise wlet-body noise ;\r
+\r
+M: lambda noise lambda-body noise ;\r
+\r
+M: object noise drop { 0 0 } ;\r
+\r
+M: quotation noise [ noise ] map vsum { 1/4 1/2 } v+ ;\r
+\r
+M: array noise [ noise ] map vsum ;\r
+\r
+: noise-factor / 100 * >integer ;\r
+\r
+: quot-noise-factor ( quot -- n )\r
+    #! For very short words, noise doesn't count so much\r
+    #! (so dup foo swap bar isn't penalized as badly).\r
+    noise first2 {\r
+        { [ over 4 <= ] [ >r drop 0 r> ] }\r
+        { [ over 15 >= ] [ >r 2 * r> ] }\r
+        { [ t ] [ ] }\r
+    } cond\r
+    {\r
+        ! short words are easier to read\r
+        { [ dup 10 <= ] [ >r 2 / r> ] }\r
+        { [ dup 5 <= ] [ >r 3 / r> ] }\r
+        ! long words are penalized even more\r
+        { [ dup 25 >= ] [ >r 2 * r> 20 max ] }\r
+        { [ dup 20 >= ] [ >r 5/3 * r> ] }\r
+        { [ dup 15 >= ] [ >r 3/2 * r> ] }\r
+        { [ t ] [ ] }\r
+    } cond noise-factor ;\r
+\r
+GENERIC: word-noise-factor ( word -- factor )\r
+\r
+M: word word-noise-factor\r
+    word-def quot-noise-factor ;\r
+\r
+M: lambda-word word-noise-factor\r
+    "lambda" word-prop quot-noise-factor ;\r
+\r
+: flatten-generics ( words -- words' )\r
+    [\r
+        dup generic? [ methods values ] [ 1array ] if\r
+    ] map concat ;\r
+\r
+: noisy-words ( -- alist )\r
+    all-words flatten-generics\r
+    [ dup word-noise-factor ] { } map>assoc\r
+    sort-values reverse ;\r
+\r
+: noise. ( alist -- )\r
+    standard-table-style [\r
+        [\r
+            [ [ pprint-cell ] [ pprint-cell ] bi* ] with-row\r
+        ] assoc-each\r
+    ] tabular-output ;\r
+\r
+: vocab-noise-factor ( vocab -- factor )\r
+    words flatten-generics\r
+    [ word-noise-factor dup 20 < [ drop 0 ] when ] map\r
+    dup empty? [ drop 0 ] [\r
+        [ [ sum ] [ length 5 max ] bi /i ]\r
+        [ supremum ]\r
+        bi +\r
+    ] if ;\r
+\r
+: noisy-vocabs ( -- alist )\r
+    vocabs [ dup vocab-noise-factor ] { } map>assoc\r
+    sort-values reverse ;\r
+\r
+: noise-report ( -- )\r
+    "NOISY WORDS:" print\r
+    noisy-words 80 head noise.\r
+    nl\r
+    "NOISY VOCABS:" print\r
+    noisy-vocabs 80 head noise. ;\r
+\r
+MAIN: noise-report\r
diff --git a/extra/reports/optimizer/optimizer.factor b/extra/reports/optimizer/optimizer.factor
new file mode 100755 (executable)
index 0000000..42e72de
--- /dev/null
@@ -0,0 +1,33 @@
+USING: assocs words sequences arrays compiler tools.time\r
+io.styles io prettyprint vocabs kernel sorting generator\r
+optimizer math combinators.cleave ;\r
+IN: report.optimizer\r
+\r
+: count-optimization-passes ( nodes n -- n )\r
+    >r optimize-1\r
+    [ r> 1+ count-optimization-passes ] [ drop r> ] if ;\r
+\r
+: results\r
+    [ [ second ] swap compose compare ] curry sort 20 tail*\r
+    print\r
+    standard-table-style\r
+    [\r
+        [ [ [ pprint-cell ] each ] with-row ] each\r
+    ] tabular-output ; inline\r
+\r
+: optimizer-measurements ( -- alist )\r
+    all-words [ compiled? ] subset\r
+    [\r
+        dup [\r
+            word-dataflow nip 1 count-optimization-passes\r
+        ] benchmark nip 2array\r
+    ] { } map>assoc ;\r
+\r
+: optimizer-measurements. ( alist -- )\r
+    [ [ first ] "Worst number of optimizer passes:" results ]\r
+    [ [ second ] "Worst compile times:" results ] bi ;\r
+\r
+: optimizer-report ( -- )\r
+    optimizer-measurements optimizer-measurements. ;\r
+\r
+MAIN: optimizer-report\r
index b19c2f39c9ee15e18e6b9344cd9c772766af11e4..6e6a92438215c045755955944975be6433c2bab9 100755 (executable)
@@ -79,3 +79,6 @@ IN: sequences.lib.tests
 [ { 910 911 912 } ] [ 10 900 3 [ + + ] map-with2 ] unit-test
 
 [ 1 2 3 4 ] [ { 1 2 3 4 } 4 firstn ] unit-test
+
+[ ] [ { } 0 firstn ] unit-test
+[ "a" ] [ { "a" } 1 firstn ] unit-test
index 050de0ae1c41671cbe053b6ca04d4f1ff7cf0e0f..a6b6b7314833b2df9c8df62c9fd86b7e111aa890 100755 (executable)
@@ -3,7 +3,8 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: combinators.lib kernel sequences math namespaces assocs 
 random sequences.private shuffle math.functions mirrors
-arrays math.parser math.private sorting strings ascii macros ;
+arrays math.parser math.private sorting strings ascii macros
+assocs.lib quotations ;
 IN: sequences.lib
 
 : each-withn ( seq quot n -- ) nwith each ; inline
@@ -19,8 +20,9 @@ IN: sequences.lib
 : map-with2 ( obj obj list quot -- newseq ) 2 map-withn ; inline
 
 MACRO: firstn ( n -- )
-    [ [ swap nth ] curry
-    [ keep ] curry ] map concat [ drop ] compose ;
+    [ [ swap nth ] curry [ keep ] curry ] map
+    concat >quotation
+    [ drop ] compose ;
 
 : prepare-index ( seq quot -- seq n quot )
     >r dup length r> ; inline
@@ -192,7 +194,7 @@ USE: continuations
 : ?tail* ( seq n -- seq/f ) (tail) ?subseq ;
 
 : accumulator ( quot -- quot vec )
-    V{ } clone [ [ push ] curry compose ] keep ;
+    V{ } clone [ [ push ] curry compose ] keep ; inline
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -220,3 +222,6 @@ PRIVATE>
 
 : nths ( indices seq -- seq' )
     [ swap nth ] with map ;
+
+: replace ( str oldseq newseq -- str' )
+    H{ } 2seq>assoc substitute ;
index 18314959245a5f6fbbdbf422cb66713162de55b3..c5734b2ae8fb2aac12f5b41670b2d57850573604 100755 (executable)
@@ -4,7 +4,7 @@
 USING: tools.test kernel serialize io io.streams.byte-array math
 alien arrays byte-arrays sequences math prettyprint parser
 classes math.constants io.encodings.binary random
-combinators.lib ;
+combinators.lib assocs ;
 IN: serialize.tests
 
 : test-serialize-cell
@@ -56,19 +56,23 @@ C: <serialize-test> serialize-test
     } ;
 
 : check-serialize-1 ( obj -- ? )
+    "=====" print
     dup class .
+    dup .
     dup
-    binary [ serialize ] with-byte-writer
-    binary [ deserialize ] with-byte-reader = ;
+    object>bytes
+    bytes>object
+    dup . = ;
 
 : check-serialize-2 ( obj -- ? )
     dup number? over wrapper? or [
         drop t ! we don't care if numbers aren't interned
     ] [
+        "=====" print
         dup class .
-        dup 2array
-        binary [ serialize ] with-byte-writer
-        binary [ deserialize ] with-byte-reader
+        dup 2array dup .
+        object>bytes
+        bytes>object dup .
         first2 eq?
     ] if ;
 
@@ -79,3 +83,17 @@ C: <serialize-test> serialize-test
 [ t ] [ pi check-serialize-1 ] unit-test
 [ serialize ] must-infer
 [ deserialize ] must-infer
+
+[ t ] [
+    V{ } dup dup push
+    object>bytes
+    bytes>object
+    dup first eq?
+] unit-test
+
+[ t ] [
+    H{ } dup dup dup set-at
+    object>bytes
+    bytes>object
+    dup keys first eq?
+] unit-test
index f573499695d17f73e6d26179f8cfa39e1a0e38fc..36d5e40b774211023ef46e8d5c6150493457ad81 100755 (executable)
@@ -6,13 +6,14 @@
 !
 ! See http://factorcode.org/license.txt for BSD license.
 !
-IN: serialize
 USING: namespaces sequences kernel math io math.functions
-io.binary strings classes words sbufs tuples arrays
-vectors byte-arrays bit-arrays quotations hashtables
-assocs help.syntax help.markup float-arrays splitting
-io.encodings.string io.encodings.utf8 combinators new-slots
-accessors ;
+io.binary strings classes words sbufs tuples arrays vectors
+byte-arrays bit-arrays quotations hashtables assocs help.syntax
+help.markup float-arrays splitting io.streams.byte-array
+io.encodings.string io.encodings.utf8 io.encodings.binary
+combinators combinators.cleave new-slots accessors locals
+prettyprint compiler.units sequences.private tuples.private ;
+IN: serialize
 
 ! Variable holding a assoc of objects already serialized
 SYMBOL: serialized
@@ -69,7 +70,8 @@ GENERIC: (serialize) ( obj -- )
 
 : serialize-shared ( obj quot -- )
     >r dup object-id
-    [ CHAR: o write1 serialize-cell drop ] r> if* ; inline
+    [ CHAR: o write1 serialize-cell drop ]
+    r> if* ; inline
 
 M: f (serialize) ( obj -- )
     drop CHAR: n write1 ;
@@ -96,75 +98,93 @@ M: ratio (serialize) ( obj -- )
     dup numerator (serialize)
     denominator (serialize) ;
 
-: serialize-string ( obj code -- )
-    write1
-    dup utf8 encode dup length serialize-cell write
-    add-object ;
-
-M: string (serialize) ( obj -- )
-    [ CHAR: s serialize-string ] serialize-shared ;
-
-: serialize-elements ( seq -- )
-    [ (serialize) ] each CHAR: . write1 ;
+: serialize-seq ( obj code -- )
+    [
+        write1
+        [ add-object ]
+        [ length serialize-cell ]
+        [ [ (serialize) ] each ] tri
+    ] curry serialize-shared ;
 
 M: tuple (serialize) ( obj -- )
     [
         CHAR: T write1
-        dup tuple>array serialize-elements
-        add-object
+        [ class (serialize) ]
+        [ add-object ]
+        [ tuple>array 1 tail (serialize) ]
+        tri
     ] serialize-shared ;
 
-: serialize-seq ( seq code -- )
-    [
-        write1
-        dup serialize-elements
-        add-object
-    ] curry serialize-shared ;
-
 M: array (serialize) ( obj -- )
     CHAR: a serialize-seq ;
 
-M: byte-array (serialize) ( obj -- )
+M: quotation (serialize) ( obj -- )
     [
-        CHAR: A write1
-        dup dup length serialize-cell write
-        add-object
+        CHAR: q write1 [ >array (serialize) ] [ add-object ] bi
     ] serialize-shared ;
 
-M: bit-array (serialize) ( obj -- )
+M: hashtable (serialize) ( obj -- )
     [
-        CHAR: b write1
-        dup length serialize-cell
-        dup [ 1 0 ? ] B{ } map-as write
-        add-object
+        CHAR: h write1
+        [ add-object ] [ >alist (serialize) ] bi
     ] serialize-shared ;
 
-M: quotation (serialize) ( obj -- )
-    CHAR: q serialize-seq ;
+M: bit-array (serialize) ( obj -- )
+    CHAR: b serialize-seq ;
+
+M: byte-array (serialize) ( obj -- )
+    [
+        CHAR: A write1
+        [ add-object ]
+        [ length serialize-cell ]
+        [ write ] tri
+    ] serialize-shared ;
 
 M: float-array (serialize) ( obj -- )
     [
         CHAR: f write1
-        dup length serialize-cell
-        dup [ double>bits 8 >be write ] each
-        add-object
+        [ add-object ]
+        [ length serialize-cell ]
+        [ [ double>bits 8 >be write ] each ]
+        tri
     ] serialize-shared ;
 
-M: hashtable (serialize) ( obj -- )
+M: string (serialize) ( obj -- )
     [
-        CHAR: h write1
-        dup >alist (serialize)
-        add-object
+        CHAR: s write1
+        [ add-object ]
+        [
+            utf8 encode
+            [ length serialize-cell ]
+            [ write ] bi
+        ] bi
     ] serialize-shared ;
 
-M: word (serialize) ( obj -- )
+: serialize-true ( word -- )
+    drop CHAR: t write1 ;
+
+: serialize-gensym ( word -- )
     [
-        CHAR: w write1
-        dup word-name (serialize)
-        dup word-vocabulary (serialize)
-        add-object
+        CHAR: G write1
+        [ add-object ]
+        [ word-def (serialize) ]
+        [ word-props (serialize) ]
+        tri
     ] serialize-shared ;
 
+: serialize-word ( word -- )
+    CHAR: w write1
+    [ word-name (serialize) ]
+    [ word-vocabulary (serialize) ]
+    bi ;
+
+M: word (serialize) ( obj -- )
+    {
+        { [ dup t eq? ] [ serialize-true ] }
+        { [ dup word-vocabulary not ] [ serialize-gensym ] }
+        { [ t ] [ serialize-word ] }
+    } cond ;
+
 M: wrapper (serialize) ( obj -- )
     CHAR: W write1
     wrapped (serialize) ;
@@ -179,6 +199,9 @@ SYMBOL: deserialized
 : deserialize-false ( -- f )
     f ;
 
+: deserialize-true ( -- f )
+    t ;
+
 : deserialize-positive-integer ( -- number )
     deserialize-cell ;
 
@@ -204,53 +227,63 @@ SYMBOL: deserialized
     (deserialize-string) dup intern-object ;
 
 : deserialize-word ( -- word )
-    (deserialize) dup (deserialize) lookup
-    [ dup intern-object ] [ "Unknown word" throw ] ?if ;
+    (deserialize) (deserialize) 2dup lookup
+    dup [ 2nip ] [
+        "Unknown word: " -rot
+        2array unparse append throw
+    ] if ;
+
+: deserialize-gensym ( -- word )
+    gensym
+    dup intern-object
+    dup (deserialize) define
+    dup (deserialize) swap set-word-props ;
 
 : deserialize-wrapper ( -- wrapper )
     (deserialize) <wrapper> ;
 
-SYMBOL: +stop+
-
-: (deserialize-seq) ( -- seq )
-    [ (deserialize) dup +stop+ get eq? not ] [ ] [ drop ] unfold ;
-
-: deserialize-seq ( seq -- array )
-    >r (deserialize-seq) r> like dup intern-object ;
+:: (deserialize-seq) ( exemplar quot -- seq )
+    deserialize-cell exemplar new
+    [ intern-object ]
+    [ dup [ drop quot call ] change-each ] bi ; inline
 
 : deserialize-array ( -- array )
-    { } deserialize-seq ;
+    { } [ (deserialize) ] (deserialize-seq) ;
 
 : deserialize-quotation ( -- array )
-    [ ] deserialize-seq ;
-
-: (deserialize-byte-array) ( -- byte-array )
-    deserialize-cell read B{ } like ;
+    (deserialize) >quotation dup intern-object ;
 
 : deserialize-byte-array ( -- byte-array )
-    (deserialize-byte-array) dup intern-object ;
+    B{ } [ read1 ] (deserialize-seq) ;
 
 : deserialize-bit-array ( -- bit-array )
-    (deserialize-byte-array) [ 0 > ] ?{ } map-as
-    dup intern-object ;
+    ?{ } [ (deserialize) ] (deserialize-seq) ;
 
 : deserialize-float-array ( -- float-array )
-    deserialize-cell
-    8 * read 8 <groups> [ be> bits>double ] F{ } map-as
-    dup intern-object ;
+    F{ } [ 8 read be> bits>double ] (deserialize-seq) ;
 
 : deserialize-hashtable ( -- hashtable )
-    (deserialize) >hashtable dup intern-object ;
+    H{ } clone
+    [ intern-object ]
+    [ (deserialize) update ]
+    [ ] tri ;
+
+: copy-seq-to-tuple ( seq tuple -- )
+    >r dup length [ 1+ ] map r> [ set-array-nth ] curry 2each ;
 
 : deserialize-tuple ( -- array )
-    (deserialize-seq) >tuple dup intern-object ;
+    #! Ugly because we have to intern the tuple before reading
+    #! slots
+    (deserialize) construct-empty
+    [ intern-object ]
+    [
+        [ (deserialize) ]
+        [ [ copy-seq-to-tuple ] keep ] bi*
+    ] bi ;
 
 : deserialize-unknown ( -- object )
     deserialize-cell deserialized get nth ;
 
-: deserialize-stop ( -- object )
-    +stop+ get ;
-
 : deserialize* ( -- object ? )
     read1 [
         {
@@ -265,14 +298,15 @@ SYMBOL: +stop+
             { CHAR: h [ deserialize-hashtable ] }
             { CHAR: m [ deserialize-negative-integer ] }
             { CHAR: n [ deserialize-false ] }
+            { CHAR: t [ deserialize-true ] }
             { CHAR: o [ deserialize-unknown ] }
             { CHAR: p [ deserialize-positive-integer ] }
             { CHAR: q [ deserialize-quotation ] }
             { CHAR: r [ deserialize-ratio ] }
             { CHAR: s [ deserialize-string ] }
             { CHAR: w [ deserialize-word ] }
+            { CHAR: G [ deserialize-word ] }
             { CHAR: z [ deserialize-zero ] }
-            { CHAR: . [ deserialize-stop ] }
         } case t
     ] [
         f f
@@ -282,14 +316,16 @@ SYMBOL: +stop+
     deserialize* [ "End of stream" throw ] unless ;
 
 : deserialize ( -- obj )
-    [
-        V{ } clone deserialized set
-        gensym +stop+ set
-        (deserialize)
-    ] with-scope ;
+    ! [
+    V{ } clone deserialized
+    [ (deserialize) ] with-variable ;
+    ! ] with-compilation-unit ;
 
 : serialize ( obj -- )
-    [
-        H{ } clone serialized set
-        (serialize)
-    ] with-scope ;
\ No newline at end of file
+    H{ } clone serialized [ (serialize) ] with-variable ;
+
+: bytes>object ( bytes -- obj )
+    binary [ deserialize ] with-byte-reader ;
+
+: object>bytes ( obj -- bytes )
+    binary [ serialize ] with-byte-writer ;
\ No newline at end of file
index de60bed20bf8e8cca929ee31177934e450d99c65..11a06f46bc685bd9e1c0a020f2668f892d4a436f 100755 (executable)
@@ -1,13 +1,14 @@
 USING: tools.deploy.config ;
 H{
-    { deploy-reflection 2 }
-    { deploy-word-props? f }
+    { deploy-name "Sudoku" }
+    { deploy-threads? f }
+    { deploy-c-types? f }
     { deploy-compiler? t }
+    { deploy-ui? f }
     { deploy-math? f }
-    { deploy-c-types? f }
+    { deploy-reflection 1 }
+    { deploy-word-defs? f }
     { deploy-io 2 }
-    { deploy-ui? f }
-    { deploy-name "Sudoku" }
+    { deploy-word-props? f }
     { "stop-after-last-window?" t }
-    { deploy-word-defs? f }
 }
old mode 100644 (file)
new mode 100755 (executable)
index 84a6150..0eacbbf
@@ -1,7 +1,15 @@
-USING: kernel symbols tools.test ;
+USING: kernel symbols tools.test parser generic words ;
 IN: symbols.tests
 
 [ ] [ SYMBOLS: a b c ; ] unit-test
 [ a ] [ a ] unit-test
 [ b ] [ b ] unit-test
 [ c ] [ c ] unit-test
+
+DEFER: blah
+
+[ ] [ "IN: symbols.tests GENERIC: blah" eval ] unit-test
+[ ] [ "IN: symbols.tests USE: symbols SYMBOLS: blah ;" eval ] unit-test
+
+[ f ] [ \ blah generic? ] unit-test
+[ t ] [ \ blah symbol? ] unit-test
old mode 100644 (file)
new mode 100755 (executable)
index 8e074f4..f6254f1
@@ -1,8 +1,9 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: parser sequences words ;
+USING: parser sequences words kernel ;
 IN: symbols
 
 : SYMBOLS:
-    ";" parse-tokens [ create-in define-symbol ] each ;
+    ";" parse-tokens
+    [ create-in dup reset-generic define-symbol ] each ;
     parsing
index 15dc32115e8715c137d7ec9db4b788bce218f6b2..60dc11257f138696e0d7de0af96b995ea264bf4e 100755 (executable)
@@ -65,8 +65,12 @@ IN: tools.deploy.backend
 : run-factor ( vm flags -- )
     swap add* dup . run-with-output ; inline
 
-: make-staging-image ( vm config -- )
-    staging-command-line run-factor ;
+: make-staging-image ( config -- )
+    vm swap staging-command-line run-factor ;
+
+: ?make-staging-image ( config -- )
+    dup [ staging-image-name ] bind exists?
+    [ drop ] [ make-staging-image ] if ;
 
 : deploy-command-line ( image vocab config -- flags )
     [
@@ -85,9 +89,7 @@ IN: tools.deploy.backend
 
 : make-deploy-image ( vm image vocab config -- )
     make-boot-image
-    dup staging-image-name exists? [
-        >r pick r> tuck make-staging-image
-    ] unless
+    dup ?make-staging-image
     deploy-command-line run-factor ;
 
 SYMBOL: deploy-implementation
index a6e126ea9e1bc3baf7e66a8154be130a2323d75c..6d3385d0a4d63cb23f5c38dfcea508aa06bc2a0e 100755 (executable)
@@ -1,44 +1,47 @@
 IN: tools.deploy.tests\r
 USING: tools.test system io.files kernel tools.deploy.config\r
-tools.deploy.backend math sequences io.launcher ;\r
+tools.deploy.backend math sequences io.launcher arrays ;\r
 \r
-: shake-and-bake\r
+: shake-and-bake ( vocab -- )\r
     "." resource-path [\r
-        vm\r
+        >r vm\r
         "test.image" temp-file\r
-        rot dup deploy-config make-deploy-image\r
+        r> dup deploy-config make-deploy-image\r
     ] with-directory ;\r
 \r
+: small-enough? ( n -- ? )\r
+    >r "test.image" temp-file file-info file-info-size r> <= ;\r
+\r
 [ ] [ "hello-world" shake-and-bake ] unit-test\r
 \r
 [ t ] [\r
-    "hello.image" temp-file file-info file-info-size 500000 <=\r
+    500000 small-enough?\r
 ] unit-test\r
 \r
 [ ] [ "sudoku" shake-and-bake ] unit-test\r
 \r
 [ t ] [\r
-    "hello.image" temp-file file-info file-info-size 1500000 <=\r
+    1500000 small-enough?\r
 ] unit-test\r
 \r
 [ ] [ "hello-ui" shake-and-bake ] unit-test\r
 \r
 [ t ] [\r
-    "hello.image" temp-file file-info file-info-size 2000000 <=\r
+    2000000 small-enough?\r
 ] unit-test\r
 \r
 [ ] [ "bunny" shake-and-bake ] unit-test\r
 \r
 [ t ] [\r
-    "hello.image" temp-file file-info file-info-size 3000000 <=\r
+    3000000 small-enough?\r
 ] unit-test\r
 \r
 [ ] [\r
     "tools.deploy.test.1" shake-and-bake\r
-    vm "-i=" "test.image" temp-file append try-process\r
+    vm "-i=" "test.image" temp-file append 2array try-process\r
 ] unit-test\r
 \r
 [ ] [\r
     "tools.deploy.test.2" shake-and-bake\r
-    vm "-i=" "test.image" temp-file append try-process\r
+    vm "-i=" "test.image" temp-file append 2array try-process\r
 ] unit-test\r
index bddf3d76c97a0106c9259a7e7b48a60a0071450b..44fb15ac7ef57bbff8834a06a55caae7df338152 100755 (executable)
@@ -13,7 +13,6 @@ QUALIFIED: definitions
 QUALIFIED: init
 QUALIFIED: inspector
 QUALIFIED: io.backend
-QUALIFIED: io.nonblocking
 QUALIFIED: io.thread
 QUALIFIED: layouts
 QUALIFIED: libc.private
@@ -133,7 +132,10 @@ IN: tools.deploy.shaker
 
         strip-io? [ io.backend:io-backend , ] when
 
-        { io.backend:io-backend io.nonblocking:default-buffer-size }
+        [
+            io.backend:io-backend ,
+            "default-buffer-size" "io.nonblocking" lookup ,
+        ] { } make
         { "alarms" "io" "tools" } strip-vocab-globals %
 
         strip-dictionary? [
@@ -192,7 +194,7 @@ IN: tools.deploy.shaker
         global swap
         '[ drop , member? not ] assoc-subset
         [ drop string? not ] assoc-subset ! strip CLI args
-        dup keys .
+        dup keys unparse show
         21 setenv
     ] [ drop ] if ;
 
index c8c0ff28a65dde2d1a59d492958efd8412a3095f..1fded308b47707c7f973b9e6e899f335b9573e42 100755 (executable)
@@ -2,17 +2,19 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: concurrency.promises models tools.walker kernel
 sequences concurrency.messaging locals continuations
-threads namespaces namespaces.private ;
+threads namespaces namespaces.private assocs ;
 IN: tools.walker.debug
 
 :: test-walker ( quot -- data )
-    [let | p [ <promise> ]
-           s [ f <model> ]
-           c [ f <model> ] |
+    [let | p [ <promise> ] |
         [
             H{ } clone >n
-            [ s c start-walker-thread p fulfill ] new-walker-hook set
-            [ drop ] show-walker-hook set
+
+            [
+                p promise-fulfilled?
+                [ drop ] [ p fulfill ] if
+                2drop
+            ] show-walker-hook set
 
             break
 
@@ -23,9 +25,7 @@ IN: tools.walker.debug
         p ?promise
         send-synchronous drop
 
-        detach
         p ?promise
-        send-synchronous drop
-
-        c model-value continuation-data
+        thread-variables walker-continuation swap at
+        model-value continuation-data
     ] ;
index e86cee0c47c167d98f0b9e2d3cf581dc11e842e6..610d3db0a3dc8fa950f525c6b21d7e982d25f755 100755 (executable)
@@ -3,33 +3,51 @@
 USING: threads kernel namespaces continuations combinators
 sequences math namespaces.private continuations.private
 concurrency.messaging quotations kernel.private words
-sequences.private assocs models ;
+sequences.private assocs models combinators.cleave ;
 IN: tools.walker
 
-SYMBOL: new-walker-hook ! ( -- )
-SYMBOL: show-walker-hook ! ( thread -- )
+SYMBOL: show-walker-hook ! ( status continuation thread -- )
 
-! Thread local
+! Thread local in thread being walked
 SYMBOL: walker-thread
+
+! Thread local in walker thread
 SYMBOL: walking-thread
+SYMBOL: walker-status
+SYMBOL: walker-continuation
+SYMBOL: walker-history
+
+DEFER: start-walker-thread
 
-: get-walker-thread ( -- thread )
+: get-walker-thread ( -- status continuation thread )
     walker-thread tget [
-        dup show-walker-hook get call
+        [ thread-variables walker-status swap at ]
+        [ thread-variables walker-continuation swap at ]
+        [ ] tri
     ] [
-        new-walker-hook get call
-        walker-thread tget
+        f <model>
+        f <model>
+        2dup start-walker-thread
     ] if* ;
 
-: break ( -- )
-    continuation callstack over set-continuation-call
+USING: io.streams.c prettyprint ;
+
+: show-walker ( -- thread )
+    get-walker-thread
+    [ show-walker-hook get call ] keep ;
 
-    get-walker-thread send-synchronous {
+: after-break ( object -- )
+    {
         { [ dup continuation? ] [ (continue) ] }
         { [ dup quotation? ] [ call ] }
         { [ dup not ] [ "Single stepping abandoned" throw ] }
     } cond ;
 
+: break ( -- )
+    continuation callstack over set-continuation-call
+    show-walker send-synchronous
+    after-break ;
+
 \ break t "break?" set-word-prop
 
 : walk ( quot -- quot' )
@@ -71,15 +89,9 @@ SYMBOL: detach
 SYMBOL: abandon
 SYMBOL: call-in
 
-! Thread locals
-SYMBOL: walker-status
-SYMBOL: walker-continuation
-SYMBOL: walker-history
-
 SYMBOL: +running+
 SYMBOL: +suspended+
 SYMBOL: +stopped+
-SYMBOL: +detached+
 
 : change-frame ( continuation quot -- continuation' )
     #! Applies quot to innermost call frame of the
@@ -145,34 +157,20 @@ SYMBOL: +detached+
 : set-status ( symbol -- )
     walker-status tget set-model ;
 
-: unassociate-thread ( -- )
-    walker-thread walking-thread tget thread-variables delete-at
-    [ ] walking-thread tget set-thread-exit-handler ;
-
-: detach-msg ( -- )
-    +detached+ set-status
-    unassociate-thread ;
-
 : keep-running ( -- )
     +running+ set-status ;
 
 : walker-stopped ( -- )
     +stopped+ set-status
-    [ status +stopped+ eq? ] [
-        [
-            {
-                { detach [ detach-msg ] }
-                [ drop ]
-            } case f
-        ] handle-synchronous
-    ] [ ] while ;
+    [ status +stopped+ eq? ]
+    [ [ drop f ] handle-synchronous ]
+    [ ] while ;
 
 : step-into-all-loop ( -- )
     +running+ set-status
     [ status +running+ eq? ] [
         [
             {
-                { detach [ detach-msg f ] }
                 { step [ f ] }
                 { step-out [ f ] }
                 { step-into [ f ] }
@@ -201,10 +199,6 @@ SYMBOL: +detached+
             {
                 ! These are sent by the walker tool. We reply
                 ! and keep cycling.
-                { detach [ detach-msg ] }
-                ! These change the state of the thread being
-                ! interpreted, so we modify the continuation and
-                ! output f.
                 { step [ step-msg keep-running ] }
                 { step-out [ step-out-msg keep-running ] }
                 { step-into [ step-into-msg keep-running ] }
@@ -221,10 +215,9 @@ SYMBOL: +detached+
 
 : walker-loop ( -- )
     +running+ set-status
-    [ status +detached+ eq? not ] [
+    [ status +stopped+ eq? not ] [
         [
             {
-                { detach [ detach-msg f ] }
                 ! ignore these commands while the thread is
                 ! running
                 { step [ f ] }
index 8dca72c29e2ece43eba41d5d150d3b164f9f7244..e9527e6f9a7dfe8e4fc94990f95a3b02b6151f00 100755 (executable)
@@ -73,10 +73,7 @@ M: freetype-renderer free-fonts ( world -- )
     ] keep *void* ;
 
 : open-face ( font style -- face )
-    ttf-name ttf-path
-    dup malloc-file-contents
-    swap file-info file-info-size
-    (open-face) ;
+    ttf-name ttf-path malloc-file-contents (open-face) ;
 
 SYMBOL: dpi
 
index bc038cd2443172267cbcdc11338dfdc9bf9ccea0..a9fe38a14c558307eb274c0243429d94150ffdbc 100755 (executable)
@@ -4,14 +4,18 @@ USING: kernel concurrency.messaging inspector ui.tools.listener
 ui.tools.traceback ui.gadgets.buttons ui.gadgets.status-bar
 ui.gadgets.tracks ui.commands ui.gadgets models
 ui.tools.workspace ui.gestures ui.gadgets.labels ui threads
-namespaces tools.walker assocs ;
+namespaces tools.walker assocs combinators combinators.cleave ;
 IN: ui.tools.walker
 
-TUPLE: walker-gadget status continuation thread traceback ;
+TUPLE: walker-gadget
+status continuation thread
+traceback
+closing? ;
 
 : walker-command ( walker msg -- )
-    over walker-gadget-thread thread-registered?
-    [ swap walker-gadget-thread send-synchronous drop ]
+    swap
+    dup walker-gadget-thread thread-registered?
+    [ walker-gadget-thread send-synchronous drop ]
     [ 2drop ] if ;
 
 : com-step ( walker -- ) step walker-command ;
@@ -27,7 +31,9 @@ TUPLE: walker-gadget status continuation thread traceback ;
 : com-abandon ( walker -- ) abandon walker-command ;
 
 M: walker-gadget ungraft*
-    dup delegate ungraft* detach walker-command ;
+    [ t swap set-walker-gadget-closing? ]
+    [ com-continue ]
+    [ delegate ungraft* ] tri ;
 
 M: walker-gadget focusable-child*
     walker-gadget-traceback ;
@@ -41,7 +47,6 @@ M: walker-gadget focusable-child*
             { +stopped+ "Stopped" }
             { +suspended+ "Suspended" }
             { +running+ "Running" }
-            { +detached+ "Detached" }
         } at %
         ")" %
         drop
@@ -51,7 +56,7 @@ M: walker-gadget focusable-child*
     [ walker-state-string ] curry <filter> <label-control> ;
 
 : <walker-gadget> ( status continuation thread -- gadget )
-    over <traceback-gadget> walker-gadget construct-boa [
+    over <traceback-gadget> walker-gadget construct-boa [
         toolbar,
         g walker-gadget-status self <thread-status> f track,
         g walker-gadget-traceback 1 track,
@@ -72,16 +77,20 @@ walker-gadget "toolbar" f {
     { T{ key-down f f "F1" } walker-help }
 } define-command-map
 
-: walker-window ( -- )
-    f <model> f <model> 2dup start-walker-thread
-    [ <walker-gadget> ] keep thread-name open-status-window ;
+: walker-for-thread? ( thread gadget -- ? )
+    {
+        { [ dup walker-gadget? not ] [ 2drop f ] }
+        { [ dup walker-gadget-closing? ] [ 2drop f ] }
+        { [ t ] [ walker-gadget-thread eq? ] }
+    } cond ;
 
-[ [ walker-window ] with-ui ] new-walker-hook set-global
+: find-walker-window ( thread -- world/f )
+    [ swap walker-for-thread? ] curry find-window ;
+
+: walker-window ( status continuation thread -- )
+    [ <walker-gadget> ] [ thread-name ] bi open-status-window ;
 
 [
-    [
-        >r dup walker-gadget?
-        [ walker-gadget-thread r> eq? ]
-        [ r> 2drop f ] if
-    ] curry find-window raise-window
+    dup find-walker-window dup
+    [ raise-window 3drop ] [ drop [ walker-window ] with-ui ] if
 ] show-walker-hook set-global
index 8eb5fe59aae119c27e73012245d0e8dd6e84f505..0c9c23cf76f46e67d616158f15c7671c3a6c0178 100755 (executable)
@@ -376,6 +376,22 @@ SYMBOL: trace-messages?
 
 : peek-message? ( msg -- ? ) f 0 0 PM_REMOVE PeekMessage zero? ;
 
+! ! ! !
+: set-world-dim ( dim world -- )
+    swap >r world-handle win-hWnd HWND_TOP 20 20 r> first2 0
+    SetWindowPos drop ;
+USE: random
+USE: arrays
+
+: twiddle
+    100 500 random +
+    100 500 random +
+    2array
+    "x" get-global find-world
+    set-world-dim
+    yield ;
+! ! ! !
+
 : event-loop ( msg -- )
     {
         { [ windows get empty? ] [ drop ] }
@@ -436,17 +452,16 @@ SYMBOL: trace-messages?
 
 : init-win32-ui ( -- )
     V{ } clone nc-buttons set-global
-    "MSG" <c-object> msg-obj set-global
+    "MSG" malloc-object msg-obj set-global
     "Factor-window" malloc-u16-string class-name-ptr set-global
     register-wndclassex drop
     GetDoubleClickTime double-click-timeout set-global ;
 
 : cleanup-win32-ui ( -- )
-    class-name-ptr get-global [
-        dup f UnregisterClass drop
-        free
-    ] when*
-    f class-name-ptr set-global ;
+    class-name-ptr get-global [ dup f UnregisterClass drop free ] when*
+    msg-obj get-global [ free ] when*
+    f class-name-ptr set-global
+    f msg-obj set-global ;
 
 : setup-pixel-format ( hdc -- )
     16 make-pfd [ ChoosePixelFormat dup win32-error=0/f ] 2keep
index 11be803893abfbd72001ecdad928f464e7d8417e..d8e1e8937a9220b7aa60bedf3ac62f511d2414d7 100755 (executable)
@@ -5,7 +5,7 @@ IN: unicode.data
 
 <<
 : VALUE:
-    CREATE dup reset-generic { f } clone [ first ] curry define ; parsing
+    CREATE-WORD { f } clone [ first ] curry define ; parsing
 
 : set-value ( value word -- )
     word-def first set-first ;
index 39879bf91d090d735d611576a07b3c0858f11f60..e3e8a23ca7dc91a0f7d38ee5ad0ad7c99b397c67 100755 (executable)
@@ -1283,7 +1283,13 @@ FUNCTION: void SetLastErrorEx ( DWORD dwErrCode, DWORD dwType ) ;
 ! FUNCTION: SetWindowLongA
 ! FUNCTION: SetWindowLongW
 ! FUNCTION: SetWindowPlacement
-! FUNCTION: SetWindowPos
+FUNCTION: BOOL SetWindowPos ( HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags ) ;
+
+: HWND_BOTTOM ALIEN: 1 ;
+: HWND_NOTOPMOST ALIEN: -2 ;
+: HWND_TOP ALIEN: 0 ;
+: HWND_TOPMOST ALIEN: -1 ;
+
 ! FUNCTION: SetWindowRgn
 ! FUNCTION: SetWindowsHookA
 ! FUNCTION: SetWindowsHookExA
index 7225ef91fde379f20f04f6a5053b4529079a1a1e..7513c3640d136434699a69edc2e4e13d4c083a97 100644 (file)
@@ -83,7 +83,9 @@
     (" !.*$" . font-lock-comment-face)
     ("( .* )" . font-lock-comment-face)
     "MAIN:"
-    "IN:" "USING:" "TUPLE:" "^C:" "^M:" "USE:" "REQUIRE:" "PROVIDE:"
+    "IN:" "USING:" "TUPLE:" "^C:" "^M:"
+    "METHOD:"
+    "USE:" "REQUIRE:" "PROVIDE:"
     "REQUIRES:"
     "GENERIC:" "GENERIC#" "SYMBOL:" "PREDICATE:" "VAR:" "VARS:"
     "C-STRUCT:"
       (insert str)
       (comint-send-input))))
 
+(defun factor-send-definition ()
+  (interactive)
+  (factor-send-region (search-backward ":")
+                      (search-forward  ";")))
+
 (defun factor-see ()
   (interactive)
   (comint-send-string "*factor*" "\\ ")
 
 (define-key factor-mode-map "\C-c\C-f" 'factor-run-file)
 (define-key factor-mode-map "\C-c\C-r" 'factor-send-region)
+(define-key factor-mode-map "\C-c\C-d" 'factor-send-definition)
 (define-key factor-mode-map "\C-c\C-s" 'factor-see)
 (define-key factor-mode-map "\C-ce"    'factor-edit)
 (define-key factor-mode-map "\C-c\C-h" 'factor-help)
 
 (defun factor-refresh-all ()
   (interactive)
-  (comint-send-string "*factor*" "refresh-all\n"))
\ No newline at end of file
+  (comint-send-string "*factor*" "refresh-all\n"))
+
+
diff --git a/unmaintained/pdf/authors.txt b/unmaintained/pdf/authors.txt
new file mode 100644 (file)
index 0000000..7c29e7c
--- /dev/null
@@ -0,0 +1 @@
+Elie Chaftari
diff --git a/unmaintained/pdf/libhpdf/libhpdf.factor b/unmaintained/pdf/libhpdf/libhpdf.factor
new file mode 100644 (file)
index 0000000..a40b7cd
--- /dev/null
@@ -0,0 +1,180 @@
+! Copyright (C) 2007 Elie CHAFTARI
+! See http://factorcode.org/license.txt for BSD license.
+!
+! Tested with libharu2 2.0.8 on Mac OS X 10.4.9 PowerPC
+!
+! export LD_LIBRARY_PATH=/opt/local/lib
+
+USING: alien alien.syntax combinators system ;
+
+IN: pdf.libhpdf
+
+<< "libhpdf" {
+    { [ win32? ] [ "libhpdf.dll" "stdcall" ] }
+    { [ macosx? ] [ "libhpdf.dylib" "cdecl" ] }
+    { [ unix? ] [ "$LD_LIBRARY_PATH/libhpdf.so" "cdecl" ] }
+} cond add-library >>
+
+! compression mode
+: HPDF_COMP_NONE      HEX: 00 ; inline ! No contents are compressed
+: HPDF_COMP_TEXT      HEX: 01 ; inline ! Compress contents stream of page
+: HPDF_COMP_IMAGE     HEX: 02 ; inline ! Compress streams of image objects
+: HPDF_COMP_METADATA  HEX: 04 ; inline ! Compress other data (fonts, cmaps...)
+: HPDF_COMP_ALL       HEX: 0F ; inline ! All stream data are compressed
+: HPDF_COMP_MASK      HEX: FF ; inline
+
+! page mode
+C-ENUM:
+    HPDF_PAGE_MODE_USE_NONE
+    HPDF_PAGE_MODE_USE_OUTLINE
+    HPDF_PAGE_MODE_USE_THUMBS
+    HPDF_PAGE_MODE_FULL_SCREEN
+    HPDF_PAGE_MODE_EOF
+;
+
+: error-code ( -- seq ) {
+     { HEX: 1001  "HPDF_ARRAY_COUNT_ERR\nInternal error. The consistency of the data was lost." }
+     { HEX: 1002  "HPDF_ARRAY_ITEM_NOT_FOUND\nInternal error. The consistency of the data was lost." }
+     { HEX: 1003  "HPDF_ARRAY_ITEM_UNEXPECTED_TYPE\nInternal error. The consistency of the data was lost." }
+     { HEX: 1004  "HPDF_BINARY_LENGTH_ERR\nThe length of the data exceeds HPDF_LIMIT_MAX_STRING_LEN." }
+     { HEX: 1005  "HPDF_CANNOT_GET_PALLET\nCannot get a pallet data from PNG image." }
+     { HEX: 1007  "HPDF_DICT_COUNT_ERR\nThe count of elements of a dictionary exceeds HPDF_LIMIT_MAX_DICT_ELEMENT" }
+     { HEX: 1008  "HPDF_DICT_ITEM_NOT_FOUND\nInternal error. The consistency of the data was lost." }
+     { HEX: 1009  "HPDF_DICT_ITEM_UNEXPECTED_TYPE\nInternal error. The consistency of the data was lost." }  
+     { HEX: 100A  "HPDF_DICT_STREAM_LENGTH_NOT_FOUND\nInternal error. The consistency of the data was lost." }  
+     { HEX: 100B  "HPDF_DOC_ENCRYPTDICT_NOT_FOUND\nHPDF_SetPermission() OR HPDF_SetEncryptMode() was called before a password is set." }
+     { HEX: 100C  "HPDF_DOC_INVALID_OBJECT\nInternal error. The consistency of the data was lost." }
+     { HEX: 100E  "HPDF_DUPLICATE_REGISTRATION\nTried to register a font that has been registered." }
+     { HEX: 100F  "HPDF_EXCEED_JWW_CODE_NUM_LIMIT\nCannot register a character to the japanese word wrap characters list." }
+     { HEX: 1011  "HPDF_ENCRYPT_INVALID_PASSWORD\nTried to set the owner password to NULL. owner password and user password is the same." }
+     { HEX: 1013  "HPDF_ERR_UNKNOWN_CLASS\nInternal error. The consistency of the data was lost." }
+     { HEX: 1014  "HPDF_EXCEED_GSTATE_LIMIT\nThe depth of the stack exceeded HPDF_LIMIT_MAX_GSTATE." }
+     { HEX: 1015  "HPDF_FAILED_TO_ALLOC_MEM\nMemory allocation failed." }
+     { HEX: 1016  "HPDF_FILE_IO_ERROR\nFile processing failed. (A detailed code is set.)" }
+     { HEX: 1017  "HPDF_FILE_OPEN_ERROR\nCannot open a file. (A detailed code is set.)" }
+     { HEX: 1019  "HPDF_FONT_EXISTS\nTried to load a font that has already been registered." }
+     { HEX: 101A  "HPDF_FONT_INVALID_WIDTHS_TABLE\nThe format of a font-file is invalid . Internal error. The consistency of the data was lost." }
+     { HEX: 101B  "HPDF_INVALID_AFM_HEADER\nCannot recognize a header of an afm file." }
+     { HEX: 101C  "HPDF_INVALID_ANNOTATION\nThe specified annotation handle is invalid." }
+     { HEX: 101E  "HPDF_INVALID_BIT_PER_COMPONENT\nBit-per-component of a image which was set as mask-image is invalid." }
+     { HEX: 101F  "HPDF_INVALID_CHAR_MATRICS_DATA\nCannot recognize char-matrics-data  of an afm file." }
+     { HEX: 1020  "HPDF_INVALID_COLOR_SPACE\n1. The color_space parameter of HPDF_LoadRawImage is invalid.\n2. Color-space of a image which was set as mask-image is invalid.\n3. The function which is invalid in the present color-space was invoked." }
+     { HEX: 1021  "HPDF_INVALID_COMPRESSION_MODE\nInvalid value was set when invoking HPDF_SetCommpressionMode()." }
+     { HEX: 1022  "HPDF_INVALID_DATE_TIME\nAn invalid date-time value was set." }
+     { HEX: 1023  "HPDF_INVALID_DESTINATION\nAn invalid destination handle was set." }
+     { HEX: 1025  "HPDF_INVALID_DOCUMENT\nAn invalid document handle is set." }
+     { HEX: 1026  "HPDF_INVALID_DOCUMENT_STATE\nThe function which is invalid in the present state was invoked." }
+     { HEX: 1027  "HPDF_INVALID_ENCODER\nAn invalid encoder handle was set." }
+     { HEX: 1028  "HPDF_INVALID_ENCODER_TYPE\nA combination between font and encoder is wrong." }
+     { HEX: 102B  "HPDF_INVALID_ENCODING_NAME\nAn Invalid encoding name is specified." }
+     { HEX: 102C  "HPDF_INVALID_ENCRYPT_KEY_LEN\nThe lengh of the key of encryption is invalid." }
+     { HEX: 102D  "HPDF_INVALID_FONTDEF_DATA\n1. An invalid font handle was set.\n2. Unsupported font format." }
+     { HEX: 102E  "HPDF_INVALID_FONTDEF_TYPE\nInternal error. The consistency of the data was lost." }
+     { HEX: 102F  "HPDF_INVALID_FONT_NAME\nA font which has the specified name is not found." }
+     { HEX: 1030  "HPDF_INVALID_IMAGE\nUnsupported image format." }
+     { HEX: 1031  "HPDF_INVALID_JPEG_DATA\nUnsupported image format." }
+     { HEX: 1032  "HPDF_INVALID_N_DATA\nCannot read a postscript-name from an afm file." }
+     { HEX: 1033  "HPDF_INVALID_OBJECT\n1. An invalid object is set.\n2. Internal error. The consistency of the data was lost." }
+     { HEX: 1034  "HPDF_INVALID_OBJ_ID\nInternal error. The consistency of the data was lost." }
+     { HEX: 1035  "HPDF_INVALID_OPERATION\nInvoked HPDF_Image_SetColorMask() against the image-object which was set a mask-image." }
+     { HEX: 1036  "HPDF_INVALID_OUTLINE\nAn invalid outline-handle was specified." }
+     { HEX: 1037  "HPDF_INVALID_PAGE\nAn invalid page-handle was specified." }
+     { HEX: 1038  "HPDF_INVALID_PAGES\nAn invalid pages-handle was specified. (internal error)" }
+     { HEX: 1039  "HPDF_INVALID_PARAMETER\nAn invalid value is set." }
+     { HEX: 103B  "HPDF_INVALID_PNG_IMAGE\nInvalid PNG image format." }
+     { HEX: 103C  "HPDF_INVALID_STREAM\nInternal error. The consistency of the data was lost." }
+     { HEX: 103D  "HPDF_MISSING_FILE_NAME_ENTRY\nInternal error. The \"_FILE_NAME\" entry for delayed loading is missing." }
+     { HEX: 103F  "HPDF_INVALID_TTC_FILE\nInvalid .TTC file format." }
+     { HEX: 1040  "HPDF_INVALID_TTC_INDEX\nThe index parameter was exceed the number of included fonts" }
+     { HEX: 1041  "HPDF_INVALID_WX_DATA\nCannot read a width-data from an afm file." }
+     { HEX: 1042  "HPDF_ITEM_NOT_FOUND\nInternal error. The consistency of the data was lost." }
+     { HEX: 1043  "HPDF_LIBPNG_ERROR\nAn error has returned from PNGLIB while loading an image." }
+     { HEX: 1044  "HPDF_NAME_INVALID_VALUE\nInternal error. The consistency of the data was lost." }
+     { HEX: 1045  "HPDF_NAME_OUT_OF_RANGE\nInternal error. The consistency of the data was lost." }
+     { HEX: 1049  "HPDF_PAGES_MISSING_KIDS_ENTRY\nInternal error. The consistency of the data was lost." }
+     { HEX: 104A  "HPDF_PAGE_CANNOT_FIND_OBJECT\nInternal error. The consistency of the data was lost." }
+     { HEX: 104B  "HPDF_PAGE_CANNOT_GET_ROOT_PAGES\nInternal error. The consistency of the data was lost." }
+     { HEX: 104C  "HPDF_PAGE_CANNOT_RESTORE_GSTATE\nThere are no graphics-states to be restored." }
+     { HEX: 104D  "HPDF_PAGE_CANNOT_SET_PARENT\nInternal error. The consistency of the data was lost." }
+     { HEX: 104E  "HPDF_PAGE_FONT_NOT_FOUND\nThe current font is not set." }
+     { HEX: 104F  "HPDF_PAGE_INVALID_FONT\nAn invalid font-handle was specified." }
+     { HEX: 1050  "HPDF_PAGE_INVALID_FONT_SIZE\nAn invalid font-size was set." }
+     { HEX: 1051  "HPDF_PAGE_INVALID_GMODE\nSee Graphics mode." }
+     { HEX: 1052  "HPDF_PAGE_INVALID_INDEX\nInternal error. The consistency of the data was lost." }
+     { HEX: 1053  "HPDF_PAGE_INVALID_ROTATE_VALUE\nThe specified value is not a multiple of 90." }
+     { HEX: 1054  "HPDF_PAGE_INVALID_SIZE\nAn invalid page-size was set." }
+     { HEX: 1055  "HPDF_PAGE_INVALID_XOBJECT\nAn invalid image-handle was set." }
+     { HEX: 1056  "HPDF_PAGE_OUT_OF_RANGE\nThe specified value is out of range." }
+     { HEX: 1057  "HPDF_REAL_OUT_OF_RANGE\nThe specified value is out of range." }
+     { HEX: 1058  "HPDF_STREAM_EOF\nUnexpected EOF marker was detected." }
+     { HEX: 1059  "HPDF_STREAM_READLN_CONTINUE\nInternal error. The consistency of the data was lost." }
+     { HEX: 105B  "HPDF_STRING_OUT_OF_RANGE\nThe length of the specified text is too long." }
+     { HEX: 105C  "HPDF_THIS_FUNC_WAS_SKIPPED\nThe execution of a function was skipped because of other errors." }
+     { HEX: 105D  "HPDF_TTF_CANNOT_EMBEDDING_FONT\nThis font cannot be embedded. (restricted by license.)" }
+     { HEX: 105E  "HPDF_TTF_INVALID_CMAP\nUnsupported ttf format. (cannot find unicode cmap.)" }
+     { HEX: 105F  "HPDF_TTF_INVALID_FOMAT\nUnsupported ttf format." }
+     { HEX: 1060  "HPDF_TTF_MISSING_TABLE\nUnsupported ttf format. (cannot find a necessary table.)" }
+     { HEX: 1061  "HPDF_UNSUPPORTED_FONT_TYPE\nInternal error. The consistency of the data was lost." }
+     { HEX: 1062  "HPDF_UNSUPPORTED_FUNC\n1. The library is not configured to use PNGLIB.\n2. Internal error. The consistency of the data was lost." }
+     { HEX: 1063  "HPDF_UNSUPPORTED_JPEG_FORMAT\nUnsupported Jpeg format." }
+     { HEX: 1064  "HPDF_UNSUPPORTED_TYPE1_FONT\nFailed to parse .PFB file." }
+     { HEX: 1065  "HPDF_XREF_COUNT_ERR\nInternal error. The consistency of the data was lost." }
+     { HEX: 1066  "HPDF_ZLIB_ERROR\nAn error has occurred while executing a function of Zlib." }
+     { HEX: 1067  "HPDF_INVALID_PAGE_INDEX\nAn error returned from Zlib." }
+     { HEX: 1068  "HPDF_INVALID_URI\nAn invalid URI was set." }
+     { HEX: 1069  "HPDF_PAGELAYOUT_OUT_OF_RANGE\nAn invalid page-layout was set." }
+     { HEX: 1070  "HPDF_PAGEMODE_OUT_OF_RANGE\nAn invalid page-mode was set." }
+     { HEX: 1071  "HPDF_PAGENUM_STYLE_OUT_OF_RANGE\nAn invalid page-num-style was set." }
+     { HEX: 1072  "HPDF_ANNOT_INVALID_ICON\nAn invalid icon was set." }
+     { HEX: 1073  "HPDF_ANNOT_INVALID_BORDER_STYLE\nAn invalid border-style was set." }
+     { HEX: 1074  "HPDF_PAGE_INVALID_DIRECTION\nAn invalid page-direction was set." }
+     { HEX: 1075  "HPDF_INVALID_FONT\nAn invalid font-handle was specified." }
+} ;
+
+LIBRARY: libhpdf
+
+! ===============================================
+! hpdf.h
+! ===============================================
+
+FUNCTION: void* HPDF_New ( void* user_error_fn, void* user_data ) ;
+
+FUNCTION: void* HPDF_Free ( void* pdf ) ;
+
+FUNCTION: ulong HPDF_SetCompressionMode ( void* pdf, uint mode ) ;
+
+FUNCTION: ulong HPDF_SetPageMode ( void* pdf, uint mode ) ;
+
+FUNCTION: void* HPDF_AddPage ( void* pdf ) ;
+
+FUNCTION: ulong HPDF_SaveToFile ( void* pdf, char* file_name ) ;
+
+FUNCTION: float HPDF_Page_GetHeight ( void* page ) ;
+
+FUNCTION: float HPDF_Page_GetWidth ( void* page ) ;
+
+FUNCTION: ulong HPDF_Page_SetLineWidth ( void* page, float line_width ) ;
+
+FUNCTION: ulong HPDF_Page_Rectangle ( void* page, float x, float y,
+                                      float width, float height ) ;
+
+FUNCTION: ulong HPDF_Page_Stroke ( void* page ) ;
+
+FUNCTION: void* HPDF_GetFont ( void* pdf, char* font_name,
+                               char* encoding_name ) ;
+
+FUNCTION: ulong HPDF_Page_SetFontAndSize ( void* page, void* font,
+                                           float size ) ;
+
+FUNCTION: float HPDF_Page_TextWidth ( void* page, char* text ) ;
+
+FUNCTION: ulong HPDF_Page_BeginText ( void* page ) ;
+
+FUNCTION: ulong HPDF_Page_TextOut ( void* page, float xpos, float ypos,
+                                    char* text ) ;
+
+FUNCTION: ulong HPDF_Page_EndText ( void*  page ) ;
+
+FUNCTION: ulong HPDF_Page_MoveTextPos ( void* page, float x, float y ) ;
+
+FUNCTION: ulong HPDF_Page_ShowText ( void* page, char* text ) ;
diff --git a/unmaintained/pdf/pdf-tests.factor b/unmaintained/pdf/pdf-tests.factor
new file mode 100755 (executable)
index 0000000..290773a
--- /dev/null
@@ -0,0 +1,98 @@
+USING: io.files kernel math namespaces pdf pdf.libhpdf prettyprint sequences ;
+IN: pdf.tests
+
+SYMBOL: font
+
+SYMBOL: width
+SYMBOL: height
+SYMBOL: twidth
+
+: font-list ( -- seq ) {
+    "Courier"
+    "Courier-Bold"
+    "Courier-Oblique"
+    "Courier-BoldOblique"
+    "Helvetica"
+    "Helvetica-Bold"
+    "Helvetica-Oblique"
+    "Helvetica-BoldOblique"
+    "Times-Roman"
+    "Times-Bold"
+    "Times-Italic"
+    "Times-BoldItalic"
+    "Symbol"
+    "ZapfDingbats"
+} ;
+
+[
+    ! HPDF_COMP_ALL set-compression-mode
+
+    ! HPDF_PAGE_MODE_USE_OUTLINE set-page-mode
+
+    ! Add a new page object
+    add-page
+
+    get-page-height height set
+
+    get-page-width width set
+
+    ! Print the lines of the page
+    1 set-page-line-width
+
+    50 50 width get 100 - height get 110 - page-rectangle
+
+    page-stroke
+
+    ! Print the title of the page (with positioning center)
+    "Helvetica" f get-font font set
+
+    font get 24 set-page-font-and-size
+
+    "Font Demo" page-text-width twidth set
+
+    [
+        width get twidth get - 2 / height get 50 - "Font Demo" page-text-out
+
+    ] with-text
+
+    ! Print subtitle
+    [
+        font get 16 set-page-font-and-size
+
+        60 height get 80 - "<Standard Type1 font samples>" page-text-out
+
+    ] with-text
+
+    ! Print font list
+    [
+        60 height get 105 - page-move-text-pos
+
+        SYMBOL: fontname
+
+        font-list [
+
+            fontname set
+
+            fontname get f get-font font set
+
+            ! print a label of text
+            font get 9 set-page-font-and-size
+
+            fontname get page-show-text
+
+            0 -18 page-move-text-pos
+
+            ! print a sample text
+            font get 20 set-page-font-and-size
+
+            "abcdefgABCDEFG12345!#$%&+-@?" page-show-text
+
+            0 -20 page-move-text-pos
+
+        ] each
+
+    ] with-text
+
+    "font_test.pdf" temp-file save-to-file
+
+] with-pdf
diff --git a/unmaintained/pdf/pdf.factor b/unmaintained/pdf/pdf.factor
new file mode 100644 (file)
index 0000000..98c94e5
--- /dev/null
@@ -0,0 +1,97 @@
+! Copyright (C) 2007 Elie CHAFTARI
+! See http://factorcode.org/license.txt for BSD license.
+!
+! Tested with libharu2 2.0.8 on Mac OS X 10.4.9 PowerPC
+
+USING: assocs continuations hashtables kernel math namespaces pdf.libhpdf ;
+
+IN: pdf
+
+SYMBOL: pdf
+SYMBOL: page
+
+! =========================================================
+! Error handling routines
+! =========================================================
+
+: check-status ( status -- )
+    dup zero? [ 
+        drop
+    ] [
+        error-code >hashtable at throw   
+    ] if ;
+
+! =========================================================
+! Document handling routines
+! =========================================================
+
+: new-pdf ( error-handler user-data -- )
+    HPDF_New pdf set ;
+
+: free-pdf ( -- )
+    pdf get HPDF_Free drop ;
+
+: with-pdf ( quot -- )
+    [ f f new-pdf [ free-pdf ] [ ] cleanup ] with-scope ; inline
+
+: set-compression-mode ( mode -- )
+    pdf get swap HPDF_SetCompressionMode check-status ;
+
+: set-page-mode ( mode -- )
+    pdf get swap HPDF_SetPageMode check-status ;
+
+: add-page ( -- )
+    pdf get HPDF_AddPage page set ;
+
+: save-to-file ( filename -- )
+    pdf get swap HPDF_SaveToFile check-status ;
+
+: get-font ( fontname encoding -- font )
+    pdf get -rot HPDF_GetFont ;
+
+! =========================================================
+! Page Handling routines
+! =========================================================
+
+: get-page-height ( -- height )
+    page get HPDF_Page_GetHeight ;
+
+: get-page-width ( -- width )
+    page get HPDF_Page_GetWidth ;
+
+: page-text-width ( text -- width )
+    page get swap HPDF_Page_TextWidth ;
+
+! =========================================================
+! Graphics routines
+! =========================================================
+
+: set-page-line-width ( linewidth -- )
+    page get swap HPDF_Page_SetLineWidth check-status ;
+
+: page-rectangle ( x y width height -- )
+    >r >r >r >r page get r> r> r> r> HPDF_Page_Rectangle check-status ;
+
+: page-stroke ( -- )
+    page get HPDF_Page_Stroke check-status ;
+
+: set-page-font-and-size ( font size -- )
+    page get -rot HPDF_Page_SetFontAndSize check-status ;
+
+: page-begin-text ( -- )
+    page get HPDF_Page_BeginText check-status ;
+
+: page-text-out ( xpos ypos text -- )
+    page get -roll HPDF_Page_TextOut check-status ;
+
+: page-end-text ( -- )
+    page get HPDF_Page_EndText check-status ;
+
+: with-text ( -- )
+    [ page-begin-text [ page-end-text ] [ ] cleanup ] with-scope ; inline
+
+: page-move-text-pos ( x y -- )
+    page get -rot HPDF_Page_MoveTextPos check-status ;
+
+: page-show-text ( text -- )
+    page get swap HPDF_Page_ShowText check-status ;
diff --git a/unmaintained/pdf/readme.txt b/unmaintained/pdf/readme.txt
new file mode 100644 (file)
index 0000000..fd52944
--- /dev/null
@@ -0,0 +1,9 @@
+To build libharu as a shared dylib on Mac OS X, modify the Makefile after calling ./configure --shared\r\rHere are the relevant sections and the lines to be changed:\r\r...\rCC=cc\rPREFIX=/usr/local\r\rLIBNAME=libhpdf.a\rSONAME=libhpdf.dylib\rSOVER1=.1\rSOVER2=.0.0\rLIBTARGET=libhpdf.dylib\rCFLAGS=-Iinclude -fPIC -fno-common -c\r...\r$(SONAME): $(OBJS)\r$(CC) -dynamiclib -o $(SONAME)$(SOVER1)$(SOVER2) $(OBJS) $(LDFLAGS) -Wl\rln -sf $(SONAME)$(SOVER1)$(SOVER2) $(SONAME)$(SOVER1)\rln -sf $(SONAME)$(SOVER1) $(SONAME)
+
+Now you can build and install:
+
+make clean
+make
+make install
+
+Test PDF files from pdf-tests.factor are generated in the test folder.
\ No newline at end of file
index 5c51fe7e8b160463545ca5c70695350f467077ed..5b0d2ebabba6875af7d4929b06a4b5effc126b7c 100755 (executable)
@@ -375,6 +375,8 @@ void forward_object_xts(void)
                        F_WORD *word = untag_object(obj);
 
                        word->code = forward_xt(word->code);
+                       if(word->profiling)
+                               word->profiling = forward_xt(word->profiling);
                }
                else if(type_of(obj) == QUOTATION_TYPE)
                {
index d9c3d8eb1c4c3d6f3482613bc395a1bc369d4759..8f93ce79a1e4b63a445be022bb795bb22df7a467 100755 (executable)
@@ -263,13 +263,18 @@ DEFPUSHPOP(root_,extra_roots)
 #define REGISTER_UNTAGGED(obj) root_push(obj ? tag_object(obj) : 0)
 #define UNREGISTER_UNTAGGED(obj) obj = untag_object(root_pop())
 
+INLINE bool in_data_heap_p(CELL ptr)
+{
+       return (ptr >= data_heap->segment->start
+               && ptr <= data_heap->segment->end);
+}
+
 /* We ignore strings which point outside the data heap, but we might be given
 a char* which points inside the data heap, in which case it is a root, for
 example if we call unbox_char_string() the result is placed in a byte array */
 INLINE bool root_push_alien(const void *ptr)
 {
-       if((CELL)ptr > data_heap->segment->start
-               && (CELL)ptr < data_heap->segment->end)
+       if(in_data_heap_p((CELL)ptr))
        {
                F_BYTE_ARRAY *objptr = ((F_BYTE_ARRAY *)ptr) - 1;
                if(objptr->header == tag_header(BYTE_ARRAY_TYPE))