From 2b05f90c7bd5ecc9edb8159c9775e5154c82d7a7 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sat, 13 Feb 2010 12:52:32 -0800
Subject: [PATCH 001/250] io.directories: add "directory-tree-files" and
 "with-directory-tree-files" words

---
 basis/io/directories/directories-docs.factor  |  8 ++++++++
 basis/io/directories/directories-tests.factor | 12 ++++++++++++
 basis/io/directories/directories.factor       | 17 ++++++++++++++---
 3 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/basis/io/directories/directories-docs.factor b/basis/io/directories/directories-docs.factor
index 4af5ee4592..a9dcea8a8f 100644
--- a/basis/io/directories/directories-docs.factor
+++ b/basis/io/directories/directories-docs.factor
@@ -46,10 +46,18 @@ HELP: directory-files
 { $values { "path" "a pathname string" } { "seq" "a sequence of filenames" } }
 { $description "Outputs the contents of a directory named by " { $snippet "path" } "." } ;
 
+HELP: directory-tree-files
+{ $values { "path" "a pathname string" } { "seq" "a sequence of filenames" } }
+{ $description "Outputs a sequence of all non-directory files inside the directory named by " { $snippet "path" } " and its subdirectories." } ;
+
 HELP: with-directory-files
 { $values { "path" "a pathname string" } { "quot" quotation } }
 { $description "Calls the quotation with the directory file names on the stack and with the directory set as the " { $link current-directory } ".  Restores the current directory after the quotation is called." } ;
 
+HELP: with-directory-tree-files
+{ $values { "path" "a pathname string" } { "quot" quotation } }
+{ $description "Calls the quotation with the recursive directory file names on the stack and with the directory set as the " { $link current-directory } ".  Restores the current directory after the quotation is called." } ;
+
 HELP: with-directory-entries
 { $values { "path" "a pathname string" } { "quot" quotation } }
 { $description "Calls the quotation with the directory entries on the stack and with the directory set as the " { $link current-directory } ".  Restores the current directory after the quotation is called." } ;
diff --git a/basis/io/directories/directories-tests.factor b/basis/io/directories/directories-tests.factor
index b703421b45..92e35557e2 100644
--- a/basis/io/directories/directories-tests.factor
+++ b/basis/io/directories/directories-tests.factor
@@ -22,6 +22,18 @@ IN: io.directories.tests
     ] with-directory-files
 ] unit-test
 
+[ { "classes/tuple/tuple.factor" } ] [
+    "resource:core" [
+        "." directory-tree-files [ "classes/tuple/tuple.factor" = ] filter
+    ] with-directory
+] unit-test
+
+[ { "classes/tuple/tuple.factor" } ] [
+    "resource:core" [
+        [ "classes/tuple/tuple.factor" = ] filter
+    ] with-directory-tree-files
+] unit-test
+
 [ ] [ "blahblah" temp-file dup exists? [ delete-directory ] [ drop ] if ] unit-test
 [ ] [ "blahblah" temp-file make-directory ] unit-test
 [ t ] [ "blahblah" temp-file file-info directory? ] unit-test
diff --git a/basis/io/directories/directories.factor b/basis/io/directories/directories.factor
index 0524398304..3158f6ca41 100644
--- a/basis/io/directories/directories.factor
+++ b/basis/io/directories/directories.factor
@@ -1,8 +1,8 @@
 ! Copyright (C) 2004, 2008 Slava Pestov, Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors combinators destructors io io.backend
-io.encodings.binary io.files io.pathnames kernel namespaces
-sequences system vocabs.loader fry ;
+USING: accessors arrays combinators destructors io io.backend
+io.encodings.binary io.files io.files.types io.pathnames
+kernel namespaces sequences system vocabs.loader fry ;
 IN: io.directories
 
 : set-current-directory ( path -- )
@@ -41,12 +41,23 @@ HOOK: (directory-entries) os ( path -- seq )
 : directory-files ( path -- seq )
     directory-entries [ name>> ] map ;
 
+: directory-tree-files ( path -- seq )
+    dup directory-entries
+    [
+        dup type>> +directory+ =
+        [ name>> [ append-path directory-tree-files ] [ [ prepend-path ] curry map ] bi ]
+        [ nip name>> 1array ] if
+    ] with map concat ;
+
 : with-directory-entries ( path quot -- )
     '[ "" directory-entries @ ] with-directory ; inline
 
 : with-directory-files ( path quot -- )
     '[ "" directory-files @ ] with-directory ; inline
 
+: with-directory-tree-files ( path quot -- )
+    '[ "" directory-tree-files @ ] with-directory ; inline
+
 ! Touching files
 HOOK: touch-file io-backend ( path -- )
 

From 72de727d0ec5319c28a00a24a2db245f354e0ae4 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sat, 13 Feb 2010 13:35:04 -0800
Subject: [PATCH 002/250] globs: * and ? should not match path-separator

---
 basis/globs/globs-tests.factor |  7 ++++++-
 basis/globs/globs.factor       | 11 +++++++----
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/basis/globs/globs-tests.factor b/basis/globs/globs-tests.factor
index bdc0623d54..eceb6bab7b 100644
--- a/basis/globs/globs-tests.factor
+++ b/basis/globs/globs-tests.factor
@@ -1,4 +1,4 @@
-USING: tools.test globs ;
+USING: tools.test globs io.pathnames ;
 IN: globs.tests
 
 [ f ] [ "abd" "fdf" glob-matches? ] unit-test
@@ -17,3 +17,8 @@ IN: globs.tests
 [ f ] [ "foo." "*.{xml,txt}" glob-matches? ] unit-test
 [ t ] [ "foo." "*.{,xml,txt}" glob-matches? ] unit-test
 [ t ] [ "foo.{" "*.{" glob-matches? ] unit-test
+
+[ f ] [ "foo" "bar" append-path "*" glob-matches? ] unit-test
+[ t ] [ "foo" "bar" append-path "*" "*" append-path glob-matches? ] unit-test
+[ f ] [ "foo" "bar" append-path "foo?bar" glob-matches? ] unit-test
+[ t ] [ "foo" "bar" append-path "fo?" "bar" append-path glob-matches? ] unit-test
diff --git a/basis/globs/globs.factor b/basis/globs/globs.factor
index cac7fd9a2f..47c8fca528 100644
--- a/basis/globs/globs.factor
+++ b/basis/globs/globs.factor
@@ -1,9 +1,12 @@
 ! Copyright (C) 2007, 2009 Slava Pestov, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: sequences kernel regexp.combinators strings unicode.case
-peg.ebnf regexp arrays ;
+USING: sequences io.pathnames kernel regexp.combinators
+strings unicode.case peg.ebnf regexp arrays ;
 IN: globs
 
+: not-path-separator ( -- sep )
+    "[^" path-separator "]" 3append <regexp> ; foldable
+
 EBNF: <glob>
 
 Character = "\\" .:c => [[ c 1string <literal> ]]
@@ -24,8 +27,8 @@ CharClass = "^"?:n Ranges:e => [[ e <or> n [ <not> ] when ]]
 AlternationBody = Concatenation:c "," AlternationBody:a => [[ a c prefix ]]
                 | Concatenation => [[ 1array ]]
 
-Element = "*" => [[ R/ .*/ ]]
-        | "?" => [[ R/ ./ ]]
+Element = "*" => [[ not-path-separator <zero-or-more> ]]
+        | "?" => [[ not-path-separator ]]
         | "[" CharClass:c "]" => [[ c ]]
         | "{" AlternationBody:b "}" => [[ b <or> ]]
         | Character

From 1632fa64482c09be434bd1d086782b8e7d4f7a02 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sat, 13 Feb 2010 13:57:58 -0800
Subject: [PATCH 003/250] io.directories: directory-tree-files should include
 the directories too, not just their contents

---
 basis/io/directories/directories-docs.factor  | 2 +-
 basis/io/directories/directories-tests.factor | 6 ++++++
 basis/io/directories/directories.factor       | 7 +++++--
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/basis/io/directories/directories-docs.factor b/basis/io/directories/directories-docs.factor
index a9dcea8a8f..804a2f4a8d 100644
--- a/basis/io/directories/directories-docs.factor
+++ b/basis/io/directories/directories-docs.factor
@@ -48,7 +48,7 @@ HELP: directory-files
 
 HELP: directory-tree-files
 { $values { "path" "a pathname string" } { "seq" "a sequence of filenames" } }
-{ $description "Outputs a sequence of all non-directory files inside the directory named by " { $snippet "path" } " and its subdirectories." } ;
+{ $description "Outputs a sequence of all files and subdirectories inside the directory named by " { $snippet "path" } " or recursively inside its subdirectories." } ;
 
 HELP: with-directory-files
 { $values { "path" "a pathname string" } { "quot" quotation } }
diff --git a/basis/io/directories/directories-tests.factor b/basis/io/directories/directories-tests.factor
index 92e35557e2..742a927b4b 100644
--- a/basis/io/directories/directories-tests.factor
+++ b/basis/io/directories/directories-tests.factor
@@ -28,6 +28,12 @@ IN: io.directories.tests
     ] with-directory
 ] unit-test
 
+[ { "classes/tuple" } ] [
+    "resource:core" [
+        "." directory-tree-files [ "classes/tuple" = ] filter
+    ] with-directory
+] unit-test
+
 [ { "classes/tuple/tuple.factor" } ] [
     "resource:core" [
         [ "classes/tuple/tuple.factor" = ] filter
diff --git a/basis/io/directories/directories.factor b/basis/io/directories/directories.factor
index 3158f6ca41..d12adc5f41 100644
--- a/basis/io/directories/directories.factor
+++ b/basis/io/directories/directories.factor
@@ -45,8 +45,11 @@ HOOK: (directory-entries) os ( path -- seq )
     dup directory-entries
     [
         dup type>> +directory+ =
-        [ name>> [ append-path directory-tree-files ] [ [ prepend-path ] curry map ] bi ]
-        [ nip name>> 1array ] if
+        [ name>>
+            [ append-path directory-tree-files ]
+            [ [ prepend-path ] curry map ]
+            [ prefix ] tri
+        ] [ nip name>> 1array ] if
     ] with map concat ;
 
 : with-directory-entries ( path quot -- )

From c0aee1908229c9fe7bda8aaaa46b09abe57fcb11 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sat, 13 Feb 2010 14:15:27 -0800
Subject: [PATCH 004/250] vocabs.metadata: add "vocab-resources" word to read
 list of deployable resource files from a "resources.txt" file in the vocab
 directory. add "vocabs.metadata.resources" subvocab that expands globs and
 directory names in resources.txt entries

---
 basis/vocabs/metadata/metadata-docs.factor    | 13 ++++++++++
 basis/vocabs/metadata/metadata.factor         | 11 +++++++-
 .../metadata/resources/resources-docs.factor  | 26 +++++++++++++++++++
 .../metadata/resources/resources-tests.factor | 19 ++++++++++++++
 .../metadata/resources/resources.factor       | 24 +++++++++++++++++
 .../vocabs/metadata/resources/test/1/1.factor |  6 +++++
 basis/vocabs/metadata/resources/test/1/bar    |  0
 basis/vocabs/metadata/resources/test/1/bas    |  0
 basis/vocabs/metadata/resources/test/1/foo    |  0
 .../metadata/resources/test/1/resources.txt   |  3 +++
 .../vocabs/metadata/resources/test/2/2.factor |  6 +++++
 .../vocabs/metadata/resources/test/2/bar.wtf  |  0
 .../vocabs/metadata/resources/test/2/bas.ftw  |  0
 .../vocabs/metadata/resources/test/2/foo.wtf  |  0
 .../test/2/no-resources-here/zim.wtf          |  0
 .../metadata/resources/test/2/resources.txt   |  1 +
 .../vocabs/metadata/resources/test/3/3.factor |  6 +++++
 .../resources/test/3/resource-dir/bar         |  0
 .../resources/test/3/resource-dir/bas/zang    |  0
 .../resources/test/3/resource-dir/bas/zim     |  0
 .../resources/test/3/resource-dir/foo         |  0
 .../metadata/resources/test/3/resources.txt   |  1 +
 22 files changed, 115 insertions(+), 1 deletion(-)
 create mode 100644 basis/vocabs/metadata/resources/resources-docs.factor
 create mode 100644 basis/vocabs/metadata/resources/resources-tests.factor
 create mode 100644 basis/vocabs/metadata/resources/resources.factor
 create mode 100644 basis/vocabs/metadata/resources/test/1/1.factor
 create mode 100644 basis/vocabs/metadata/resources/test/1/bar
 create mode 100644 basis/vocabs/metadata/resources/test/1/bas
 create mode 100644 basis/vocabs/metadata/resources/test/1/foo
 create mode 100644 basis/vocabs/metadata/resources/test/1/resources.txt
 create mode 100644 basis/vocabs/metadata/resources/test/2/2.factor
 create mode 100644 basis/vocabs/metadata/resources/test/2/bar.wtf
 create mode 100644 basis/vocabs/metadata/resources/test/2/bas.ftw
 create mode 100644 basis/vocabs/metadata/resources/test/2/foo.wtf
 create mode 100644 basis/vocabs/metadata/resources/test/2/no-resources-here/zim.wtf
 create mode 100644 basis/vocabs/metadata/resources/test/2/resources.txt
 create mode 100644 basis/vocabs/metadata/resources/test/3/3.factor
 create mode 100644 basis/vocabs/metadata/resources/test/3/resource-dir/bar
 create mode 100644 basis/vocabs/metadata/resources/test/3/resource-dir/bas/zang
 create mode 100644 basis/vocabs/metadata/resources/test/3/resource-dir/bas/zim
 create mode 100644 basis/vocabs/metadata/resources/test/3/resource-dir/foo
 create mode 100644 basis/vocabs/metadata/resources/test/3/resources.txt

diff --git a/basis/vocabs/metadata/metadata-docs.factor b/basis/vocabs/metadata/metadata-docs.factor
index 66041e249c..95c8083e0f 100644
--- a/basis/vocabs/metadata/metadata-docs.factor
+++ b/basis/vocabs/metadata/metadata-docs.factor
@@ -18,6 +18,11 @@ ARTICLE: "vocabs.metadata" "Vocabulary metadata"
     set-vocab-tags
     add-vocab-tags
 }
+"Vocabulary resources:"
+{ $subsections
+    vocab-resources
+    set-vocab-resources
+}
 "Getting and setting arbitrary vocabulary metadata:"
 { $subsections
     vocab-file-contents
@@ -50,3 +55,11 @@ HELP: set-vocab-tags
 { $values { "tags" "a sequence of strings" } { "vocab" "a vocabulary specifier" } }
 { $description "Stores a list of short tags classifying the vocabulary to the " { $snippet "tags.txt" } " file in the vocabulary's directory." } ;
 
+HELP: vocab-resources
+{ $values { "vocab" "a vocabulary specifier" } { "patterns" "a sequence of glob patterns" } }
+{ $description "Outputs a list of glob patterns matching files that will be deployed with an application that includes " { $snippet "vocab" } ", as specified by the " { $snippet "resources.txt" } " file in the vocabulary's directory. Outputs an empty array if the file doesn't exist." }
+{ $notes "The " { $vocab-link "vocabs.metadata.resources" } " vocabulary contains words that will expand the glob patterns and directory names in " { $snippet "patterns" } " and return all the matching files." } ;
+
+HELP: set-vocab-resources
+{ $values { "patterns" "a sequence of glob patterns" } { "vocab" "a vocabulary specifier" } }
+{ $description "Stores a list of glob patterns matching files that will be deployed with an application that includes " { $snippet "vocab" } " to the " { $snippet "resources.txt" } " file in the vocabulary's directory." } ;
diff --git a/basis/vocabs/metadata/metadata.factor b/basis/vocabs/metadata/metadata.factor
index 85a503c7f0..43c7641577 100644
--- a/basis/vocabs/metadata/metadata.factor
+++ b/basis/vocabs/metadata/metadata.factor
@@ -19,6 +19,15 @@ MEMO: vocab-file-contents ( vocab name -- seq )
         3append throw
     ] ?if ;
 
+: vocab-resources-path ( vocab -- string )
+    vocab-dir "resources.txt" append-path ;
+
+: vocab-resources ( vocab -- patterns )
+    dup vocab-resources-path vocab-file-contents harvest ;
+
+: set-vocab-resources ( patterns vocab -- )
+    dup vocab-resources-path set-vocab-file-contents ;
+
 : vocab-summary-path ( vocab -- string )
     vocab-dir "summary.txt" append-path ;
 
@@ -67,4 +76,4 @@ M: vocab-link summary vocab-summary ;
     dup vocab-authors-path set-vocab-file-contents ;
 
 : unportable? ( vocab -- ? )
-    vocab-tags "unportable" swap member? ;
\ No newline at end of file
+    vocab-tags "unportable" swap member? ;
diff --git a/basis/vocabs/metadata/resources/resources-docs.factor b/basis/vocabs/metadata/resources/resources-docs.factor
new file mode 100644
index 0000000000..b4289ff388
--- /dev/null
+++ b/basis/vocabs/metadata/resources/resources-docs.factor
@@ -0,0 +1,26 @@
+! (c)2010 Joe Groff bsd license
+USING: help.markup help.syntax kernel ;
+IN: vocabs.metadata.resources
+
+HELP: expand-vocab-resource-files
+{ $values
+    { "vocab" "a vocabulary specifier" } { "resource-glob-strings" "a sequence of glob patterns" }
+    { "filenames" "a sequence of filenames" }
+}
+{ $description "Matches all the glob patterns in " { $snippet "resource-glob-strings" } " to the set of files inside " { $snippet "vocab" } "'s directory and outputs a sequence containing the individual files and directories that match. Any matching directories will also have their contents recursively included in the output. The paths in the output will be relative to " { $snippet "vocab" } "'s directory." } ;
+
+HELP: vocab-resource-files
+{ $values
+    { "vocab" "a vocabulary specifier" }
+    { "filenames" "a sequence of filenames" }
+}
+{ $description "Outputs a sequence containing the individual resource files and directories that match the patterns specified in " { $snippet "vocab" } "'s " { $snippet "resources.txt" } " file. Any matching directories will also have their contents recursively included in the output. The paths in the output will be relative to " { $snippet "vocab" } "'s directory." } ;
+
+ARTICLE: "vocabs.metadata.resources" "vocabs.metadata.resources"
+"The " { $vocab-link "vocabs.metadata.resources" } " vocabulary contains words to retrieve the full list of files that match the patterns specified in a vocabulary's " { $snippet "resources.txt" } " file."
+{ $subsections
+    vocab-resource-files
+    expand-vocab-resource-files
+} ;
+
+ABOUT: "vocabs.metadata.resources"
diff --git a/basis/vocabs/metadata/resources/resources-tests.factor b/basis/vocabs/metadata/resources/resources-tests.factor
new file mode 100644
index 0000000000..36fd13125e
--- /dev/null
+++ b/basis/vocabs/metadata/resources/resources-tests.factor
@@ -0,0 +1,19 @@
+! (c)2010 Joe Groff bsd license
+USING: sorting tools.test vocabs.metadata.resources ;
+IN: vocabs.metadata.resources.tests
+
+[ { "bar" "bas" "foo" } ]
+[ "vocabs.metadata.resources.test.1" vocab-resource-files natural-sort ] unit-test
+
+[ { "bar.wtf" "foo.wtf" } ]
+[ "vocabs.metadata.resources.test.2" vocab-resource-files natural-sort ] unit-test
+
+[ {
+    "resource-dir"
+    "resource-dir/bar"
+    "resource-dir/bas"
+    "resource-dir/bas/zang"
+    "resource-dir/bas/zim"
+    "resource-dir/buh"
+    "resource-dir/foo"
+} ] [ "vocabs.metadata.resources.test.3" vocab-resource-files natural-sort ] unit-test
diff --git a/basis/vocabs/metadata/resources/resources.factor b/basis/vocabs/metadata/resources/resources.factor
new file mode 100644
index 0000000000..1da15f6b9e
--- /dev/null
+++ b/basis/vocabs/metadata/resources/resources.factor
@@ -0,0 +1,24 @@
+! (c)2010 Joe Groff bsd license
+USING: arrays fry globs io.directories io.files.info
+io.pathnames kernel regexp sequences vocabs.loader
+vocabs.metadata ;
+IN: vocabs.metadata.resources
+
+<PRIVATE
+: (expand-vocab-resource) ( resource-path -- filenames )
+    dup file-info directory?
+    [ dup '[ _ directory-tree-files [ append-path ] with map ] [ prefix ] bi ]
+    [ 1array ] if ;
+
+: filter-resources ( vocab-files resource-globs -- resource-files ) 
+    '[ _ [ matches? ] with any? ] filter ;
+PRIVATE>
+
+: expand-vocab-resource-files ( vocab resource-glob-strings -- filenames )
+    [ [ find-vocab-root ] [ vocab-dir ] bi append-path ] dip [ <glob> ] map '[
+        _ filter-resources
+        [ (expand-vocab-resource) ] map concat
+    ] with-directory-tree-files ;
+
+: vocab-resource-files ( vocab -- filenames )
+    dup vocab-resources expand-vocab-resource-files ;
diff --git a/basis/vocabs/metadata/resources/test/1/1.factor b/basis/vocabs/metadata/resources/test/1/1.factor
new file mode 100644
index 0000000000..dddc0ddd58
--- /dev/null
+++ b/basis/vocabs/metadata/resources/test/1/1.factor
@@ -0,0 +1,6 @@
+USING: io kernel ;
+IN: vocabs.metadata.resources.test.1
+
+: main ( -- ) "Resources test 1" print ;
+
+MAIN: main
diff --git a/basis/vocabs/metadata/resources/test/1/bar b/basis/vocabs/metadata/resources/test/1/bar
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/basis/vocabs/metadata/resources/test/1/bas b/basis/vocabs/metadata/resources/test/1/bas
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/basis/vocabs/metadata/resources/test/1/foo b/basis/vocabs/metadata/resources/test/1/foo
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/basis/vocabs/metadata/resources/test/1/resources.txt b/basis/vocabs/metadata/resources/test/1/resources.txt
new file mode 100644
index 0000000000..ce0f4c956c
--- /dev/null
+++ b/basis/vocabs/metadata/resources/test/1/resources.txt
@@ -0,0 +1,3 @@
+foo
+bar
+bas
diff --git a/basis/vocabs/metadata/resources/test/2/2.factor b/basis/vocabs/metadata/resources/test/2/2.factor
new file mode 100644
index 0000000000..82a5a11d18
--- /dev/null
+++ b/basis/vocabs/metadata/resources/test/2/2.factor
@@ -0,0 +1,6 @@
+USING: io kernel ;
+IN: vocabs.metadata.resources.test.2
+
+: main ( -- ) "Resources test 2" print ;
+
+MAIN: main
diff --git a/basis/vocabs/metadata/resources/test/2/bar.wtf b/basis/vocabs/metadata/resources/test/2/bar.wtf
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/basis/vocabs/metadata/resources/test/2/bas.ftw b/basis/vocabs/metadata/resources/test/2/bas.ftw
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/basis/vocabs/metadata/resources/test/2/foo.wtf b/basis/vocabs/metadata/resources/test/2/foo.wtf
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/basis/vocabs/metadata/resources/test/2/no-resources-here/zim.wtf b/basis/vocabs/metadata/resources/test/2/no-resources-here/zim.wtf
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/basis/vocabs/metadata/resources/test/2/resources.txt b/basis/vocabs/metadata/resources/test/2/resources.txt
new file mode 100644
index 0000000000..8dfd81c911
--- /dev/null
+++ b/basis/vocabs/metadata/resources/test/2/resources.txt
@@ -0,0 +1 @@
+*.wtf
diff --git a/basis/vocabs/metadata/resources/test/3/3.factor b/basis/vocabs/metadata/resources/test/3/3.factor
new file mode 100644
index 0000000000..a81fd707c5
--- /dev/null
+++ b/basis/vocabs/metadata/resources/test/3/3.factor
@@ -0,0 +1,6 @@
+USING: io kernel ;
+IN: vocabs.metadata.resources.test.3
+
+: main ( -- ) "Resources test 3" print ;
+
+MAIN: main
diff --git a/basis/vocabs/metadata/resources/test/3/resource-dir/bar b/basis/vocabs/metadata/resources/test/3/resource-dir/bar
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/basis/vocabs/metadata/resources/test/3/resource-dir/bas/zang b/basis/vocabs/metadata/resources/test/3/resource-dir/bas/zang
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/basis/vocabs/metadata/resources/test/3/resource-dir/bas/zim b/basis/vocabs/metadata/resources/test/3/resource-dir/bas/zim
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/basis/vocabs/metadata/resources/test/3/resource-dir/foo b/basis/vocabs/metadata/resources/test/3/resource-dir/foo
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/basis/vocabs/metadata/resources/test/3/resources.txt b/basis/vocabs/metadata/resources/test/3/resources.txt
new file mode 100644
index 0000000000..c27d538826
--- /dev/null
+++ b/basis/vocabs/metadata/resources/test/3/resources.txt
@@ -0,0 +1 @@
+resource-dir

From 8a4fb8cbcec5d28430e89ab7c6302366d21c81a5 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sat, 13 Feb 2010 18:06:48 -0800
Subject: [PATCH 005/250] gpu.textures: add symbolic constants for LATC
 compression

---
 extra/gpu/textures/textures-docs.factor | 6 +++++-
 extra/gpu/textures/textures.factor      | 1 +
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/extra/gpu/textures/textures-docs.factor b/extra/gpu/textures/textures-docs.factor
index ffac0bc29b..09906d623a 100644
--- a/extra/gpu/textures/textures-docs.factor
+++ b/extra/gpu/textures/textures-docs.factor
@@ -335,12 +335,16 @@ HELP: compressed-texture-format
 { { $link DXT1-RGBA } }
 { { $link DXT3 } }
 { { $link DXT5 } }
+{ { $link LATC1 } }
+{ { $link LATC1-SIGNED } }
+{ { $link LATC2 } }
+{ { $link LATC2-SIGNED } }
 { { $link RGTC1 } }
 { { $link RGTC1-SIGNED } }
 { { $link RGTC2 } }
 { { $link RGTC2-SIGNED } }
 } }
-{ $notes "The " { $snippet "DXT1" } " formats require either the " { $snippet "GL_EXT_texture_compression_s3tc" } " or " { $snippet "GL_EXT_texture_compression_dxt1" } " extension. The other " { $snippet "DXT" } " formats require the " { $snippet "GL_EXT_texture_compression_s3tc" } " extension. The " { $snippet "RGTC" } " formats require OpenGL 3.0 or later or the " { $snippet "GL_EXT_texture_compression_rgtc" } " extension." } ;
+{ $notes "The " { $snippet "DXT1" } " formats require either the " { $snippet "GL_EXT_texture_compression_s3tc" } " or " { $snippet "GL_EXT_texture_compression_dxt1" } " extension. The other " { $snippet "DXT" } " formats require the " { $snippet "GL_EXT_texture_compression_s3tc" } " extension. The " { $snippet "LATC" } " formats require the " { $snippet "GL_EXT_texture_compression_latc" } " extension. The " { $snippet "RGTC" } " formats require OpenGL 3.0 or later or the " { $snippet "GL_EXT_texture_compression_rgtc" } " extension." } ;
 
 HELP: compressed-texture-data
 { $class-description { $snippet "compressed-texture-data" } " tuples are used to feed compressed texture data to " { $link allocate-compressed-texture } " and " { $link update-compressed-texture } "."
diff --git a/extra/gpu/textures/textures.factor b/extra/gpu/textures/textures.factor
index e1afc20f88..132e4303e7 100644
--- a/extra/gpu/textures/textures.factor
+++ b/extra/gpu/textures/textures.factor
@@ -51,6 +51,7 @@ UNION: ?float-array float-array POSTPONE: f ;
 
 VARIANT: compressed-texture-format
     DXT1-RGB DXT1-RGBA DXT3 DXT5
+    LATC1 LATC1-SIGNED LATC2 LATC2-SIGNED
     RGTC1 RGTC1-SIGNED RGTC2 RGTC2-SIGNED ;
 
 TUPLE: compressed-texture-data

From 072dd3b0d077b104e829709880f97976394bbd31 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 14 Feb 2010 09:59:36 -0800
Subject: [PATCH 006/250] vocabs.metadata.resources: don't try to expand
 resource patterns for vocabs without a resources.txt

---
 basis/vocabs/metadata/resources/resources.factor | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/basis/vocabs/metadata/resources/resources.factor b/basis/vocabs/metadata/resources/resources.factor
index 1da15f6b9e..e37bdc273f 100644
--- a/basis/vocabs/metadata/resources/resources.factor
+++ b/basis/vocabs/metadata/resources/resources.factor
@@ -21,4 +21,5 @@ PRIVATE>
     ] with-directory-tree-files ;
 
 : vocab-resource-files ( vocab -- filenames )
-    dup vocab-resources expand-vocab-resource-files ;
+    dup vocab-resources
+    [ drop f ] [ expand-vocab-resource-files ] if-empty ;

From 9c77d7bde8d4dbd4dc3950895efd0b106c18df72 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 14 Feb 2010 11:29:37 -0800
Subject: [PATCH 007/250] have tools.deploy.shaker write a manifest of loaded
 vocabs to a file. have tools.deploy.backend read in this manifest. have
 tools.deploy.macosx copy resources for the manifest vocabs to the deployed
 bundle

---
 basis/tools/deploy/backend/backend.factor     | 23 ++++++------
 basis/tools/deploy/macosx/macosx.factor       |  2 +-
 basis/tools/deploy/shaker/shaker.factor       | 35 +++++++++++--------
 .../metadata/resources/resources.factor       | 22 +++++++++++-
 4 files changed, 53 insertions(+), 29 deletions(-)

diff --git a/basis/tools/deploy/backend/backend.factor b/basis/tools/deploy/backend/backend.factor
index fe8049e9e3..9d6b8d4c08 100644
--- a/basis/tools/deploy/backend/backend.factor
+++ b/basis/tools/deploy/backend/backend.factor
@@ -7,21 +7,15 @@ summary layouts vocabs.loader prettyprint.config prettyprint debugger
 io.streams.c io.files io.files.temp io.pathnames io.directories
 io.directories.hierarchy io.backend quotations io.launcher
 tools.deploy.config tools.deploy.config.editor bootstrap.image
-io.encodings.utf8 destructors accessors hashtables ;
+io.encodings.utf8 destructors accessors hashtables
+vocabs.metadata.resources ;
 IN: tools.deploy.backend
 
 : copy-vm ( executable bundle-name -- vm )
     prepend-path vm over copy-file ;
 
-CONSTANT: theme-path "basis/ui/gadgets/theme/"
-
-: copy-theme ( name dir -- )
-    deploy-ui? get [
-        append-path
-        theme-path append-path
-        [ make-directories ]
-        [ theme-path "resource:" prepend swap copy-tree ] bi
-    ] [ 2drop ] if ;
+: copy-resources ( manifest name dir -- )
+    append-path swap [ copy-vocab-resources ] with each ;
 
 : image-name ( vocab bundle-name -- str )
     prepend-path ".image" append ;
@@ -89,7 +83,7 @@ DEFER: ?make-staging-image
     [ "deploy-config-" prepend temp-file ] bi
     [ utf8 set-file-contents ] keep ;
 
-: deploy-command-line ( image vocab config -- flags )
+: deploy-command-line ( image vocab manifest-file config -- flags )
     [
         bootstrap-profile ?make-staging-image
 
@@ -97,6 +91,7 @@ DEFER: ?make-staging-image
             "-i=" bootstrap-profile staging-image-name append ,
             "-resource-path=" "" resource-path append ,
             "-run=tools.deploy.shaker" ,
+            "-vocab-manifest-out=" prepend ,
             [ "-deploy-vocab=" prepend , ]
             [ make-deploy-config "-deploy-config=" prepend , ] bi
             "-output-image=" prepend ,
@@ -104,8 +99,10 @@ DEFER: ?make-staging-image
         ] { } make
     ] bind ;
 
-: make-deploy-image ( vm image vocab config -- )
+: make-deploy-image ( vm image vocab config -- manifest )
     make-boot-image
-    deploy-command-line run-factor ;
+    over "vocab-manifest-" prepend temp-file
+    [ swap deploy-command-line run-factor ]
+    [ utf8 file-lines ] bi ;
 
 HOOK: deploy* os ( vocab -- )
diff --git a/basis/tools/deploy/macosx/macosx.factor b/basis/tools/deploy/macosx/macosx.factor
index f753e38fb2..bec3e78cbd 100644
--- a/basis/tools/deploy/macosx/macosx.factor
+++ b/basis/tools/deploy/macosx/macosx.factor
@@ -46,7 +46,6 @@ IN: tools.deploy.macosx
             [ copy-dll ]
             [ copy-nib ]
             [ "Contents/Resources" append-path make-directories ]
-            [ "Contents/Resources" copy-theme ]
         } cleave
     ]
     [ create-app-plist ]
@@ -72,6 +71,7 @@ M: macosx deploy* ( vocab -- )
             [ bundle-name create-app-dir ] keep
             [ bundle-name deploy.app-image ] keep
             namespace make-deploy-image
+            bundle-name "Contents/Resources" copy-resources
             bundle-name show-in-finder
         ] bind
     ] with-directory ;
diff --git a/basis/tools/deploy/shaker/shaker.factor b/basis/tools/deploy/shaker/shaker.factor
index 5897712a02..e020980233 100755
--- a/basis/tools/deploy/shaker/shaker.factor
+++ b/basis/tools/deploy/shaker/shaker.factor
@@ -1,11 +1,11 @@
 ! Copyright (C) 2007, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays accessors io.backend io.streams.c init fry
-namespaces math make assocs kernel parser parser.notes lexer
-strings.parser vocabs sequences sequences.deep sequences.private
-words memory kernel.private continuations io vocabs.loader
-system strings sets vectors quotations byte-arrays sorting
-compiler.units definitions generic generic.standard
+USING: arrays accessors io.backend io.encodings.utf8 io.files
+io.streams.c init fry namespaces math make assocs kernel parser
+parser.notes lexer strings.parser vocabs sequences sequences.deep
+sequences.private words memory kernel.private continuations io
+vocabs.loader system strings sets vectors quotations byte-arrays
+sorting compiler.units definitions generic generic.standard
 generic.single tools.deploy.config combinators classes
 classes.builtin slots.private grouping command-line ;
 QUALIFIED: bootstrap.stage2
@@ -465,7 +465,8 @@ SYMBOL: deploy-vocab
 
 : startup-stripper ( -- )
     t "quiet" set-global
-    f output-stream set-global ;
+    f output-stream set-global
+    V{ "resource:" } clone vocab-roots set-global ;
 
 : next-method* ( method -- quot )
     [ "method-class" word-prop ]
@@ -501,7 +502,12 @@ SYMBOL: deploy-vocab
     "Clearing megamorphic caches" show
     [ clear-megamorphic-cache ] each ;
 
-: strip ( -- )
+: write-vocab-manifest ( vocab-manifest-out -- )
+    "Writing vocabulary manifest to " write dup print flush
+    vocabs swap utf8 set-file-lines ;
+
+: strip ( vocab-manifest-out -- )
+    [ write-vocab-manifest ] when*
     startup-stripper
     strip-libc
     strip-destructors
@@ -535,7 +541,7 @@ SYMBOL: deploy-vocab
         1 exit
     ] recover ; inline
 
-: (deploy) ( final-image vocab config -- )
+: (deploy) ( final-image vocab-manifest-out vocab config -- )
     #! Does the actual work of a deployment in the slave
     #! stage2 image
     [
@@ -548,11 +554,11 @@ SYMBOL: deploy-vocab
                     "ui.debugger" require
                 ] when
             ] unless
-            deploy-vocab set
-            deploy-vocab get require
-            deploy-vocab get vocab-main [
-                "Vocabulary has no MAIN: word." print flush 1 exit
-            ] unless
+            [ deploy-vocab set ] [ require ] [
+                vocab-main [
+                    "Vocabulary has no MAIN: word." print flush 1 exit
+                ] unless
+            ] tri
             strip
             "Saving final image" show
             save-image-and-exit
@@ -561,6 +567,7 @@ SYMBOL: deploy-vocab
 
 : do-deploy ( -- )
     "output-image" get
+    "vocab-manifest-out" get
     "deploy-vocab" get
     "Deploying " write dup write "..." print
     "deploy-config" get parse-file first
diff --git a/basis/vocabs/metadata/resources/resources.factor b/basis/vocabs/metadata/resources/resources.factor
index e37bdc273f..62036be408 100644
--- a/basis/vocabs/metadata/resources/resources.factor
+++ b/basis/vocabs/metadata/resources/resources.factor
@@ -5,6 +5,7 @@ vocabs.metadata ;
 IN: vocabs.metadata.resources
 
 <PRIVATE
+
 : (expand-vocab-resource) ( resource-path -- filenames )
     dup file-info directory?
     [ dup '[ _ directory-tree-files [ append-path ] with map ] [ prefix ] bi ]
@@ -12,10 +13,20 @@ IN: vocabs.metadata.resources
 
 : filter-resources ( vocab-files resource-globs -- resource-files ) 
     '[ _ [ matches? ] with any? ] filter ;
+
+: copy-vocab-resource ( to from file -- )
+    [ append-path ] curry bi@
+    dup file-info directory?
+    [ drop make-directories ]
+    [ swap [ parent-directory make-directories ] [ copy-file ] bi ] if ;
+    
 PRIVATE>
 
+: vocab-dir-in-root ( vocab -- dir )
+    [ find-vocab-root ] [ vocab-dir ] bi append-path ;
+
 : expand-vocab-resource-files ( vocab resource-glob-strings -- filenames )
-    [ [ find-vocab-root ] [ vocab-dir ] bi append-path ] dip [ <glob> ] map '[
+    [ vocab-dir-in-root ] dip [ <glob> ] map '[
         _ filter-resources
         [ (expand-vocab-resource) ] map concat
     ] with-directory-tree-files ;
@@ -23,3 +34,12 @@ PRIVATE>
 : vocab-resource-files ( vocab -- filenames )
     dup vocab-resources
     [ drop f ] [ expand-vocab-resource-files ] if-empty ;
+
+: copy-vocab-resources ( dir vocab -- )
+    dup vocab-resource-files 
+    [ 2drop ] [
+        [ [ vocab-dir append-path P ] [ vocab-dir-in-root P ] bi ] dip
+        [ 2drop make-directories ]
+        [ [ copy-vocab-resource ] with with each ] 3bi
+    ] if-empty ;
+

From 5f0855c5c25c59a59d67a4335df47f311f6dbe93 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 14 Feb 2010 11:49:33 -0800
Subject: [PATCH 008/250] globs: add "glob-parent-directory" word that returns
 the deepest level of a path without glob symbols

---
 basis/globs/globs-tests.factor | 18 +++++++++++++++++-
 basis/globs/globs.factor       |  7 +++++++
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/basis/globs/globs-tests.factor b/basis/globs/globs-tests.factor
index eceb6bab7b..c9903b1633 100644
--- a/basis/globs/globs-tests.factor
+++ b/basis/globs/globs-tests.factor
@@ -1,4 +1,4 @@
-USING: tools.test globs io.pathnames ;
+USING: arrays tools.test globs io.pathnames sequences ;
 IN: globs.tests
 
 [ f ] [ "abd" "fdf" glob-matches? ] unit-test
@@ -22,3 +22,19 @@ IN: globs.tests
 [ t ] [ "foo" "bar" append-path "*" "*" append-path glob-matches? ] unit-test
 [ f ] [ "foo" "bar" append-path "foo?bar" glob-matches? ] unit-test
 [ t ] [ "foo" "bar" append-path "fo?" "bar" append-path glob-matches? ] unit-test
+
+[ f ] [ "foo" glob-pattern? ] unit-test
+[ t ] [ "fo?" glob-pattern? ] unit-test
+[ t ] [ "fo*" glob-pattern? ] unit-test
+[ t ] [ "fo[mno]" glob-pattern? ] unit-test
+[ t ] [ "fo\\*" glob-pattern? ] unit-test
+[ t ] [ "fo{o,bro}" glob-pattern? ] unit-test
+
+"foo" "bar" append-path 1array
+[ { "foo" "bar" "ba?" } path-separator join glob-parent-directory ] unit-test
+
+[ "foo" ] 
+[ { "foo" "b?r" "bas" } path-separator join glob-parent-directory ] unit-test
+
+[ "" ] 
+[ { "f*" "bar" "bas" } path-separator join glob-parent-directory ] unit-test
diff --git a/basis/globs/globs.factor b/basis/globs/globs.factor
index 47c8fca528..72b686c3b1 100644
--- a/basis/globs/globs.factor
+++ b/basis/globs/globs.factor
@@ -43,3 +43,10 @@ Main = Concatenation End
 
 : glob-matches? ( input glob -- ? )
     [ >case-fold ] bi@ <glob> matches? ;
+
+: glob-pattern? ( string -- ? )
+    [ "\\*?[{" member? ] any? ;
+
+: glob-parent-directory ( glob -- parent-directory )
+    path-components dup [ glob-pattern? ] find drop head
+    path-separator join ;

From 281ddf5b27a0f00141f1c0b8499e4f885cca71c1 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 14 Feb 2010 12:08:13 -0800
Subject: [PATCH 009/250] remove debug output from vocab.metadata.resources

---
 basis/vocabs/metadata/resources/resources.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/vocabs/metadata/resources/resources.factor b/basis/vocabs/metadata/resources/resources.factor
index 62036be408..d8f9bdcffd 100644
--- a/basis/vocabs/metadata/resources/resources.factor
+++ b/basis/vocabs/metadata/resources/resources.factor
@@ -38,7 +38,7 @@ PRIVATE>
 : copy-vocab-resources ( dir vocab -- )
     dup vocab-resource-files 
     [ 2drop ] [
-        [ [ vocab-dir append-path P ] [ vocab-dir-in-root P ] bi ] dip
+        [ [ vocab-dir append-path ] [ vocab-dir-in-root ] bi ] dip
         [ 2drop make-directories ]
         [ [ copy-vocab-resource ] with with each ] 3bi
     ] if-empty ;

From eb875e1e7845831045ef60be208ef7b6205e7558 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 14 Feb 2010 12:42:03 -0800
Subject: [PATCH 010/250] create a real "ui.gadgets.theme" vocab, move
 theme-image word into it, and add theme images to resources.txt

---
 basis/ui/gadgets/buttons/buttons.factor             | 6 +++---
 basis/ui/gadgets/corners/corners.factor             | 4 ++--
 basis/ui/gadgets/search-tables/search-tables.factor | 4 ++--
 basis/ui/gadgets/sliders/sliders.factor             | 2 +-
 basis/ui/gadgets/tabbed/tabbed.factor               | 5 +++--
 basis/ui/gadgets/theme/authors.txt                  | 1 +
 basis/ui/gadgets/theme/resources.txt                | 1 +
 basis/ui/gadgets/theme/theme.factor                 | 6 ++++++
 basis/ui/pens/image/image.factor                    | 2 --
 9 files changed, 19 insertions(+), 12 deletions(-)
 create mode 100644 basis/ui/gadgets/theme/resources.txt
 create mode 100644 basis/ui/gadgets/theme/theme.factor

diff --git a/basis/ui/gadgets/buttons/buttons.factor b/basis/ui/gadgets/buttons/buttons.factor
index 061fd8d364..d0d25a0630 100644
--- a/basis/ui/gadgets/buttons/buttons.factor
+++ b/basis/ui/gadgets/buttons/buttons.factor
@@ -5,9 +5,9 @@ colors.constants combinators combinators.short-circuit
 combinators.smart fry kernel locals math math.rectangles
 math.vectors models namespaces opengl opengl.gl quotations
 sequences strings ui.commands ui.gadgets ui.gadgets.borders
-ui.gadgets.labels ui.gadgets.packs ui.gadgets.tracks
-ui.gadgets.worlds ui.gestures ui.pens ui.pens.image
-ui.pens.solid ui.pens.tile ;
+ui.gadgets.labels ui.gadgets.packs ui.gadgets.theme
+ui.gadgets.tracks ui.gadgets.worlds ui.gestures ui.pens
+ui.pens.image ui.pens.solid ui.pens.tile ;
 FROM: models => change-model ;
 IN: ui.gadgets.buttons
 
diff --git a/basis/ui/gadgets/corners/corners.factor b/basis/ui/gadgets/corners/corners.factor
index 7f558fca19..31b7d5db2e 100644
--- a/basis/ui/gadgets/corners/corners.factor
+++ b/basis/ui/gadgets/corners/corners.factor
@@ -1,7 +1,7 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel sequences namespaces ui.gadgets.frames
-ui.pens.image ui.gadgets.icons ui.gadgets.grids ;
+ui.pens.image ui.gadgets.icons ui.gadgets.grids ui.gadgets.theme ;
 IN: ui.gadgets.corners
 
 CONSTANT: @center { 1 1 }
@@ -40,4 +40,4 @@ SYMBOL: name
 
 : make-corners ( class name quot -- corners )
     [ [ [ 3 3 ] dip new-frame { 1 1 } >>filled-cell ] dip name ] dip
-    with-variable ; inline
\ No newline at end of file
+    with-variable ; inline
diff --git a/basis/ui/gadgets/search-tables/search-tables.factor b/basis/ui/gadgets/search-tables/search-tables.factor
index dd2232df60..1da137270a 100644
--- a/basis/ui/gadgets/search-tables/search-tables.factor
+++ b/basis/ui/gadgets/search-tables/search-tables.factor
@@ -3,7 +3,7 @@
 USING: accessors kernel delegate fry sequences models
 combinators.short-circuit models.search models.delay calendar locals
 ui.gestures ui.pens ui.pens.image ui.gadgets.editors ui.gadgets.labels
-ui.gadgets.scrollers ui.gadgets.tables ui.gadgets.tracks
+ui.gadgets.scrollers ui.gadgets.tables ui.gadgets.theme ui.gadgets.tracks
 ui.gadgets.borders ui.gadgets.buttons ui.baseline-alignment ui.gadgets ;
 IN: ui.gadgets.search-tables
 
@@ -78,4 +78,4 @@ CONSULT: table-protocol search-table table>> ;
 M: search-table model-changed
     nip field>> clear-search-field ;
 
-M: search-table focusable-child* field>> ;
\ No newline at end of file
+M: search-table focusable-child* field>> ;
diff --git a/basis/ui/gadgets/sliders/sliders.factor b/basis/ui/gadgets/sliders/sliders.factor
index b98a0d152e..6851ff4be7 100644
--- a/basis/ui/gadgets/sliders/sliders.factor
+++ b/basis/ui/gadgets/sliders/sliders.factor
@@ -4,7 +4,7 @@ USING: accessors arrays assocs kernel math namespaces sequences
 vectors models models.range math.vectors math.functions quotations
 colors colors.constants math.rectangles fry combinators ui.gestures
 ui.pens ui.gadgets ui.gadgets.buttons ui.gadgets.tracks math.order
-ui.gadgets.icons ui.pens.tile ui.pens.image ;
+ui.gadgets.icons ui.gadgets.theme ui.pens.tile ui.pens.image ;
 IN: ui.gadgets.sliders
 
 TUPLE: slider < track elevator thumb saved line ;
diff --git a/basis/ui/gadgets/tabbed/tabbed.factor b/basis/ui/gadgets/tabbed/tabbed.factor
index 23881103a9..77ddb90270 100644
--- a/basis/ui/gadgets/tabbed/tabbed.factor
+++ b/basis/ui/gadgets/tabbed/tabbed.factor
@@ -2,8 +2,9 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: ui.pens ui.gadgets.tracks ui.gadgets.buttons
 ui.gadgets.buttons.private ui.gadgets.books ui.gadgets.packs
-ui.gadgets.borders ui.gadgets.icons ui.gadgets ui.pens.image
-sequences models accessors kernel colors colors.constants ;
+ui.gadgets.borders ui.gadgets.icons ui.gadgets ui.gadgets.theme
+ui.pens.image sequences models accessors kernel colors
+colors.constants ;
 IN: ui.gadgets.tabbed
 
 TUPLE: tabbed-gadget < track tabs book ;
diff --git a/basis/ui/gadgets/theme/authors.txt b/basis/ui/gadgets/theme/authors.txt
index 1901f27a24..580f882c8d 100644
--- a/basis/ui/gadgets/theme/authors.txt
+++ b/basis/ui/gadgets/theme/authors.txt
@@ -1 +1,2 @@
 Slava Pestov
+Joe Groff
diff --git a/basis/ui/gadgets/theme/resources.txt b/basis/ui/gadgets/theme/resources.txt
new file mode 100644
index 0000000000..72238b4d93
--- /dev/null
+++ b/basis/ui/gadgets/theme/resources.txt
@@ -0,0 +1 @@
+*.tiff
diff --git a/basis/ui/gadgets/theme/theme.factor b/basis/ui/gadgets/theme/theme.factor
new file mode 100644
index 0000000000..ab10999021
--- /dev/null
+++ b/basis/ui/gadgets/theme/theme.factor
@@ -0,0 +1,6 @@
+! (c)2009, 2010 Slava Pestov, Joe Groff bsd license
+USING: io.pathnames sequences ui.images ;
+IN: ui.gadgets.theme
+
+: theme-image ( name -- image-name )
+    "vocab:ui/gadgets/theme/" prepend-path ".tiff" append <image-name> ;
diff --git a/basis/ui/pens/image/image.factor b/basis/ui/pens/image/image.factor
index da253f8b0c..be37e6e129 100644
--- a/basis/ui/pens/image/image.factor
+++ b/basis/ui/pens/image/image.factor
@@ -18,5 +18,3 @@ M: image-pen draw-interior
 
 M: image-pen pen-pref-dim nip image>> image-dim ;
 
-: theme-image ( name -- image-name )
-    "vocab:ui/gadgets/theme/" prepend-path ".tiff" append <image-name> ;
\ No newline at end of file

From ad63314a9e3da465762ae72b93824dc5df342e70 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 14 Feb 2010 13:58:24 -0800
Subject: [PATCH 011/250] audio.chunked-file: inline "check-chunk" so heap-size
 call can be folded away and audio can be deployed

---
 extra/audio/chunked-file/chunked-file.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/extra/audio/chunked-file/chunked-file.factor b/extra/audio/chunked-file/chunked-file.factor
index a450790ec6..f5844a60d0 100644
--- a/extra/audio/chunked-file/chunked-file.factor
+++ b/extra/audio/chunked-file/chunked-file.factor
@@ -24,5 +24,5 @@ ERROR: invalid-audio-file ;
     } case ;
 
 : check-chunk ( chunk id class -- ? )
-    heap-size [ id= ] [ [ length ] dip >= ] bi-curry* bi and ;
+    heap-size [ id= ] [ [ length ] dip >= ] bi-curry* bi and ; inline
 

From 06f4a218159a4e08a0ef73180bba149cf51f41f3 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 14 Feb 2010 14:01:07 -0800
Subject: [PATCH 012/250] gpu.demos.raytrace: add deploy config and
 resources.txt

---
 extra/gpu/demos/raytrace/deploy.factor | 14 ++++++++++++++
 extra/gpu/demos/raytrace/resources.txt |  4 ++++
 2 files changed, 18 insertions(+)
 create mode 100644 extra/gpu/demos/raytrace/deploy.factor
 create mode 100644 extra/gpu/demos/raytrace/resources.txt

diff --git a/extra/gpu/demos/raytrace/deploy.factor b/extra/gpu/demos/raytrace/deploy.factor
new file mode 100644
index 0000000000..b01a64ccbc
--- /dev/null
+++ b/extra/gpu/demos/raytrace/deploy.factor
@@ -0,0 +1,14 @@
+USING: tools.deploy.config ;
+H{
+    { deploy-name "Raytrace" }
+    { deploy-ui? t }
+    { deploy-c-types? f }
+    { deploy-unicode? f }
+    { "stop-after-last-window?" t }
+    { deploy-io 2 }
+    { deploy-reflection 2 }
+    { deploy-word-props? f }
+    { deploy-math? t }
+    { deploy-threads? t }
+    { deploy-word-defs? f }
+}
diff --git a/extra/gpu/demos/raytrace/resources.txt b/extra/gpu/demos/raytrace/resources.txt
new file mode 100644
index 0000000000..24d3bb9b79
--- /dev/null
+++ b/extra/gpu/demos/raytrace/resources.txt
@@ -0,0 +1,4 @@
+green-ball.aiff
+mirror-ball.aiff
+red-ball.aiff
+yellow-ball.aiff

From f02fb684cdc3b4d1e74da44fcaf21ede47014e3a Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 14 Feb 2010 14:03:19 -0800
Subject: [PATCH 013/250] add resources.txt for gpu.demos.bunny

---
 extra/gpu/demos/bunny/deploy.factor | 20 ++++++++++----------
 extra/gpu/demos/bunny/resources.txt |  1 +
 2 files changed, 11 insertions(+), 10 deletions(-)
 create mode 100644 extra/gpu/demos/bunny/resources.txt

diff --git a/extra/gpu/demos/bunny/deploy.factor b/extra/gpu/demos/bunny/deploy.factor
index fe80da122e..1289caadb6 100644
--- a/extra/gpu/demos/bunny/deploy.factor
+++ b/extra/gpu/demos/bunny/deploy.factor
@@ -1,14 +1,14 @@
 USING: tools.deploy.config ;
 H{
-    { deploy-name "gpu.demos.bunny" }
-    { deploy-word-defs? f }
-    { deploy-io 3 }
-    { "stop-after-last-window?" t }
-    { deploy-math? t }
-    { deploy-word-props? f }
-    { deploy-threads? t }
-    { deploy-c-types? f }
-    { deploy-reflection 2 }
-    { deploy-unicode? f }
+    { deploy-name "Bunny" }
     { deploy-ui? t }
+    { deploy-c-types? f }
+    { deploy-unicode? f }
+    { "stop-after-last-window?" t }
+    { deploy-io 3 }
+    { deploy-reflection 2 }
+    { deploy-word-props? f }
+    { deploy-math? t }
+    { deploy-threads? t }
+    { deploy-word-defs? f }
 }
diff --git a/extra/gpu/demos/bunny/resources.txt b/extra/gpu/demos/bunny/resources.txt
new file mode 100644
index 0000000000..7aa9238e48
--- /dev/null
+++ b/extra/gpu/demos/bunny/resources.txt
@@ -0,0 +1 @@
+loading.tiff

From a6bbb6dca6583c353ea4797934245b4c76742b9c Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 14 Feb 2010 23:10:05 -0800
Subject: [PATCH 014/250] update unix, windows, and test deploy backends

---
 basis/tools/deploy/test/test.factor       |  2 +-
 basis/tools/deploy/unix/unix.factor       |  4 ++--
 basis/tools/deploy/windows/windows.factor | 14 ++++++--------
 3 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/basis/tools/deploy/test/test.factor b/basis/tools/deploy/test/test.factor
index d8414baba7..bc458dde36 100644
--- a/basis/tools/deploy/test/test.factor
+++ b/basis/tools/deploy/test/test.factor
@@ -7,7 +7,7 @@ IN: tools.deploy.test
     [ "test.image" temp-file delete-file ] ignore-errors
     "resource:" [
         [ vm "test.image" temp-file ] dip
-        dup deploy-config make-deploy-image
+        dup deploy-config make-deploy-image drop
     ] with-directory ;
 
 ERROR: image-too-big actual-size max-size ;
diff --git a/basis/tools/deploy/unix/unix.factor b/basis/tools/deploy/unix/unix.factor
index f88cf06ef7..2646f2d5a4 100644
--- a/basis/tools/deploy/unix/unix.factor
+++ b/basis/tools/deploy/unix/unix.factor
@@ -7,7 +7,6 @@ tools.deploy.config.editor assocs hashtables prettyprint ;
 IN: tools.deploy.unix
 
 : create-app-dir ( vocab bundle-name -- vm )
-    dup "" copy-theme
     copy-vm
     dup OCT: 755 set-file-permissions ;
 
@@ -20,6 +19,7 @@ M: unix deploy* ( vocab -- )
             [ bundle-name create-app-dir ] keep
             [ bundle-name image-name ] keep
             namespace make-deploy-image
+            bundle-name "" copy-resources
             bundle-name normalize-path [ "Binary deployed to " % % "." % ] "" make print
         ] bind
-    ] with-directory ;
\ No newline at end of file
+    ] with-directory ;
diff --git a/basis/tools/deploy/windows/windows.factor b/basis/tools/deploy/windows/windows.factor
index f21f4ac363..4dad875128 100644
--- a/basis/tools/deploy/windows/windows.factor
+++ b/basis/tools/deploy/windows/windows.factor
@@ -16,20 +16,18 @@ IN: tools.deploy.windows
 
 : create-exe-dir ( vocab bundle-name -- vm )
     dup copy-dll
-    deploy-ui? get [
-        [ "" copy-theme ] [ ".exe" copy-vm ] bi
-    ] [ ".com" copy-vm ] if ;
+    deploy-ui? get ".exe" ".com" ? copy-vm ;
 
 M: winnt deploy*
     "resource:" [
         dup deploy-config [
             deploy-name get
-            [
+            {
                 [ create-exe-dir ]
                 [ image-name ]
-                [ drop ]
-                2tri namespace make-deploy-image
-            ]
-            [ nip open-in-explorer ] 2bi
+                [ drop namespace make-deploy-image ]
+                [ nip "" copy-resources ]
+                [ nip open-in-explorer ]
+            } 2cleave 
         ] bind
     ] with-directory ;

From 642d48cd0592ab20046c7b07061b43dd2ce47208 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 14 Feb 2010 23:27:48 -0800
Subject: [PATCH 015/250] gpu.demos.bunny: use images.tiff so that it's present
 in deployed bundle

---
 extra/gpu/demos/bunny/bunny.factor | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/extra/gpu/demos/bunny/bunny.factor b/extra/gpu/demos/bunny/bunny.factor
index 987d3d1507..bee94d302a 100644
--- a/extra/gpu/demos/bunny/bunny.factor
+++ b/extra/gpu/demos/bunny/bunny.factor
@@ -3,8 +3,8 @@ USING: accessors alien.c-types arrays classes.struct combinators
 combinators.short-circuit game.loop game.worlds gpu gpu.buffers
 gpu.util.wasd gpu.framebuffers gpu.render gpu.shaders gpu.state
 gpu.textures gpu.util grouping http.client images images.loader
-io io.encodings.ascii io.files io.files.temp kernel locals math
-math.matrices math.vectors.simd math.parser math.vectors
+images.tiff io io.encodings.ascii io.files io.files.temp kernel
+locals math math.matrices math.vectors.simd math.parser math.vectors
 method-chains namespaces sequences splitting threads ui ui.gadgets
 ui.gadgets.worlds ui.pixel-formats specialized-arrays
 specialized-vectors literals ;

From 3bdc84a07ab33fd6bccabbf5304a8d98703aa5fb Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Sun, 14 Feb 2010 23:41:44 -0800
Subject: [PATCH 016/250] Fix D3D9 constants that I punted on calculating
 initially.

---
 .../directx/d3d9types/d3d9types.factor        | 26 +++++++------------
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/basis/windows/directx/d3d9types/d3d9types.factor b/basis/windows/directx/d3d9types/d3d9types.factor
index 9f4358f658..dc02849553 100644
--- a/basis/windows/directx/d3d9types/d3d9types.factor
+++ b/basis/windows/directx/d3d9types/d3d9types.factor
@@ -900,12 +900,6 @@ CONSTANT: D3DMULTISAMPLE_14_SAMPLES      14
 CONSTANT: D3DMULTISAMPLE_15_SAMPLES      15
 CONSTANT: D3DMULTISAMPLE_16_SAMPLES      16
 CONSTANT: D3DMULTISAMPLE_FORCE_DWORD     HEX: 7fffffff
-
-:: MAKEFOURCC ( ch0 ch1 ch2 ch3 -- n )
-    ch3 HEX: ff bitand 24 shift
-    ch2 HEX: ff bitand 16 shift
-    ch1 HEX: ff bitand  8 shift
-    ch0 HEX: ff bitand bitor bitor bitor ; inline
                                                                   
 TYPEDEF: int D3DFORMAT
 CONSTANT: D3DFMT_UNKNOWN              0
@@ -937,15 +931,15 @@ CONSTANT: D3DFMT_X8L8V8U8             62
 CONSTANT: D3DFMT_Q8W8V8U8             63
 CONSTANT: D3DFMT_V16U16               64
 CONSTANT: D3DFMT_A2W10V10U10          67
-#! : D3DFMT_UYVY                 ( -- n ) 'U' 'Y' 'V' 'Y' MAKEFOURCC
-#! D3DFMT_R8G8_B8G8            = MAKEFOURCC('R', 'G', 'B', 'G'),
-#! D3DFMT_YUY2                 = MAKEFOURCC('Y', 'U', 'Y', '2'),
-#! D3DFMT_G8R8_G8B8            = MAKEFOURCC('G', 'R', 'G', 'B'),
-#! D3DFMT_DXT1                 = MAKEFOURCC('D', 'X', 'T', '1'),
-#! D3DFMT_DXT2                 = MAKEFOURCC('D', 'X', 'T', '2'),
-#! D3DFMT_DXT3                 = MAKEFOURCC('D', 'X', 'T', '3'),
-#! D3DFMT_DXT4                 = MAKEFOURCC('D', 'X', 'T', '4'),
-#! D3DFMT_DXT5                 = MAKEFOURCC('D', 'X', 'T', '5'),
+CONSTANT: D3DFMT_UYVY                 HEX: 55595659
+CONSTANT: D3DFMT_R8G8_B8G8            HEX: 52474247
+CONSTANT: D3DFMT_YUY2                 HEX: 59555932
+CONSTANT: D3DFMT_G8R8_G8B8            HEX: 47524742
+CONSTANT: D3DFMT_DXT1                 HEX: 44585431
+CONSTANT: D3DFMT_DXT2                 HEX: 44585432
+CONSTANT: D3DFMT_DXT3                 HEX: 44585433
+CONSTANT: D3DFMT_DXT4                 HEX: 44585434
+CONSTANT: D3DFMT_DXT5                 HEX: 44585435
 CONSTANT: D3DFMT_D16_LOCKABLE         70
 CONSTANT: D3DFMT_D32                  71
 CONSTANT: D3DFMT_D15S1                73
@@ -962,7 +956,7 @@ CONSTANT: D3DFMT_VERTEXDATA           100
 CONSTANT: D3DFMT_INDEX16              101
 CONSTANT: D3DFMT_INDEX32              102
 CONSTANT: D3DFMT_Q16W16V16U16         110
-#! D3DFMT_MULTI2_ARGB8         = MAKEFOURCC('M', 'E', 'T', '1'),
+CONSTANT: D3DFMT_MULTI2_ARGB8         HEX: 4d455431
 CONSTANT: D3DFMT_R16F                 111
 CONSTANT: D3DFMT_G16R16F              112
 CONSTANT: D3DFMT_A16B16G16R16F        113

From 45c85d1851544225c5ffc8b9134b2a4e7e8406d0 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 14 Feb 2010 23:55:38 -0800
Subject: [PATCH 017/250] update vocabs and deploy docs to mention
 resources.txt

---
 basis/tools/deploy/deploy-docs.factor | 4 ++++
 core/vocabs/loader/loader-docs.factor | 9 +++++----
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/basis/tools/deploy/deploy-docs.factor b/basis/tools/deploy/deploy-docs.factor
index 948db1c833..2cbb2869de 100644
--- a/basis/tools/deploy/deploy-docs.factor
+++ b/basis/tools/deploy/deploy-docs.factor
@@ -7,8 +7,12 @@ ARTICLE: "prepare-deploy" "Preparing to deploy an application"
 { $subsections
     "deploy-config"
     "deploy-flags"
+    "deploy-resources"
 } ;
 
+ARTICLE: "deploy-resources" "Deployed resource files"
+"To include additional files in your deployed application, specify their names in a vocabulary's " { $snippet "resources.txt" } " file. The " { $snippet "resources.txt" } " file contains one glob pattern per line. These patterns are expanded relative to the vocabulary directory; files outside of the vocabulary directory cannot be referenced. If a file inside the vocabulary directory matches any of these patterns, it will be included in deployed applications that reference the vocabulary. If a subdirectory matches, its contents will be included recursively." ;
+
 ARTICLE: "tools.deploy.usage" "Deploy tool usage"
 "Once the necessary deployment flags have been set, the application can be deployed:"
 { $subsections deploy }
diff --git a/core/vocabs/loader/loader-docs.factor b/core/vocabs/loader/loader-docs.factor
index 7d00cbe2ad..7db3cdd5c2 100644
--- a/core/vocabs/loader/loader-docs.factor
+++ b/core/vocabs/loader/loader-docs.factor
@@ -45,11 +45,12 @@ $nl
     { { $snippet "foo/bar/bar-docs.factor" } " - documentation, see " { $link "writing-help" } }
     { { $snippet "foo/bar/bar-tests.factor" } " - unit tests, see " { $link "tools.test" } }
 }
-"Finally, optional three text files may contain meta-data:"
+"Finally, four optional text files may contain metadata:"
 { $list
-    { { $snippet "foo/bar/authors.txt" } " - a series of lines, with one author name per line. These are listed under " { $link "vocab-authors" } }
-    { { $snippet "foo/bar/summary.txt" } " - a one-line description" }
-    { { $snippet "foo/bar/tags.txt" } " - a whitespace-separated list of tags which classify the vocabulary. Consult " { $link "vocab-tags" } " for a list of existing tags you can re-use" }
+    { { $snippet "foo/bar/authors.txt" } " - a series of lines, with one author name per line. These are listed under " { $link "vocab-authors" } "." }
+    { { $snippet "foo/bar/resources.txt" } " - a series of lines with one file glob pattern per line. Files inside the vocabulary directory whose names match any of these glob patterns will be included with the compiled application as " { $link "deploy-resources" } "." }
+    { { $snippet "foo/bar/summary.txt" } " - a one-line description." }
+    { { $snippet "foo/bar/tags.txt" } " - a whitespace-separated list of tags which classify the vocabulary. Consult " { $link "vocab-tags" } " for a list of existing tags you can reuse." }
 }
 "The " { $link POSTPONE: USE: } " and " { $link POSTPONE: USING: } " words load vocabularies which have not been loaded yet, as needed."
 $nl

From f9d6ba0339815322cf1e42065841b5a2acedfde1 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 15 Feb 2010 10:56:23 -0800
Subject: [PATCH 018/250] tools.deploy.macosx: copy "icon.icns" from deployed
 vocab to app bundle as app icon

---
 basis/tools/deploy/macosx/macosx.factor | 34 ++++++++++++++++---------
 basis/vocabs/metadata/metadata.factor   |  6 +++++
 2 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/basis/tools/deploy/macosx/macosx.factor b/basis/tools/deploy/macosx/macosx.factor
index bec3e78cbd..8bd3749093 100644
--- a/basis/tools/deploy/macosx/macosx.factor
+++ b/basis/tools/deploy/macosx/macosx.factor
@@ -6,7 +6,7 @@ sequences system tools.deploy.backend tools.deploy.config
 tools.deploy.config.editor assocs hashtables prettyprint
 io.backend.unix cocoa io.encodings.utf8 io.backend
 cocoa.application cocoa.classes cocoa.plists
-combinators ;
+combinators vocabs.metadata vocabs.loader ;
 IN: tools.deploy.macosx
 
 : bundle-dir ( -- dir )
@@ -16,7 +16,7 @@ IN: tools.deploy.macosx
     [ bundle-dir prepend-path swap ] keep
     "Contents" prepend-path append-path copy-tree ;
 
-: app-plist ( executable bundle-name -- assoc )
+: app-plist ( icon? executable bundle-name -- assoc )
     [
         "6.0" "CFBundleInfoDictionaryVersion" set
         "APPL" "CFBundlePackageType" set
@@ -25,9 +25,11 @@ IN: tools.deploy.macosx
 
         [ "CFBundleExecutable" set ]
         [ "org.factor." prepend "CFBundleIdentifier" set ] bi
+
+        [ "Icon.icns" "CFBundleIconFile" set ] when
     ] H{ } make-assoc ;
 
-: create-app-plist ( executable bundle-name -- )
+: create-app-plist ( icon? executable bundle-name -- )
     [ app-plist ] keep
     "Contents/Info.plist" append-path
     write-plist ;
@@ -40,16 +42,24 @@ IN: tools.deploy.macosx
         "Resources/English.lproj/MiniFactor.nib" copy-bundle-dir
     ] [ drop ] if ;
 
+: copy-icns ( vocab bundle-name -- icon? )
+    swap dup vocab-mac-icon-path vocab-append-path dup exists?
+    [ swap "Contents/Resources/Icon.icns" append-path copy-file t ]
+    [ 2drop f ] if ;
+
 : create-app-dir ( vocab bundle-name -- vm )
-    [
-        nip {
-            [ copy-dll ]
-            [ copy-nib ]
-            [ "Contents/Resources" append-path make-directories ]
-        } cleave
-    ]
-    [ create-app-plist ]
-    [ "Contents/MacOS/" append-path copy-vm ] 2tri
+    {
+        [
+            nip {
+                [ copy-dll ]
+                [ copy-nib ]
+                [ "Contents/Resources" append-path make-directories ]
+            } cleave
+        ]
+        [ copy-icns ]
+        [ create-app-plist ]
+        [ "Contents/MacOS/" append-path copy-vm ]
+    } 2cleave
     dup OCT: 755 set-file-permissions ;
 
 : deploy.app-image ( vocab bundle-name -- str )
diff --git a/basis/vocabs/metadata/metadata.factor b/basis/vocabs/metadata/metadata.factor
index 43c7641577..04a0ea7546 100644
--- a/basis/vocabs/metadata/metadata.factor
+++ b/basis/vocabs/metadata/metadata.factor
@@ -19,6 +19,12 @@ MEMO: vocab-file-contents ( vocab name -- seq )
         3append throw
     ] ?if ;
 
+: vocab-windows-icon-path ( vocab -- string )
+    vocab-dir "icon.ico" append-path ;
+
+: vocab-mac-icon-path ( vocab -- string )
+    vocab-dir "icon.icns" append-path ;
+
 : vocab-resources-path ( vocab -- string )
     vocab-dir "resources.txt" append-path ;
 

From bfa5f5ad9b2037c8dc012212bf207754cd16920b Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 15 Feb 2010 10:58:26 -0800
Subject: [PATCH 019/250] icon for gpu.demos.bunny

---
 extra/gpu/demos/bunny/icon.icns | Bin 0 -> 30278 bytes
 extra/gpu/demos/bunny/icon.ico  | Bin 0 -> 9854 bytes
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 extra/gpu/demos/bunny/icon.icns
 create mode 100644 extra/gpu/demos/bunny/icon.ico

diff --git a/extra/gpu/demos/bunny/icon.icns b/extra/gpu/demos/bunny/icon.icns
new file mode 100644
index 0000000000000000000000000000000000000000..ef7ed0af6ff9a8871d8203be227168da6be3b9d1
GIT binary patch
literal 30278
zcmeHv2Y6i9b>^M-ruWxofI%Bz(5JjMz*K;p5PL;$RHaC<ONtY3tjr7=yF{u*QsOv{
z*Rd>Fl4I@0-pK7s9Iu_tw=SPzYi-AIV#TtP*m04Y3iiKm0E(bUkN}y_-)1%XBw*&9
zcF#TM+;jf9(7sy_-A%}Et>1T#t`XANN${Gz?CblpCGv||o8)!a98Qscb=K}7HkXSK
zcj$##me_sdqq9yzgkWQfgV-hViCGIVTg?o4Zq`N2QXr`5e!}|sKcBS`k0=Rtf+r@z
z6$18XuEI?0LM8dwtetoR!9Y-?4}D+@288G;)lZ1kUkL>!A{7H{5bvLx^%J`Y(xzyq
z9I)VdfIK^E^3&&1*bQ2qID>(JC{#DA5wDrB4!>0W)GR{;sT5$82q+ksTMYOl5!Q)*
zr-iUiuTUZVDISPYAz%@kyEPV?%!G*b(p1153`(5KLLiH)kUlW$@=8)5AO-bo)&p@C
z;*Qk^rD;kR5d2P-5C_MT_d%RnECj4lbtaRq0-@Dn4$ILR>3E<Jw2M9mR_7JTdqL-g
zTC3Ea%j7inqqBAg5u&PEACOLf(iRBXh#7=WP{X~&fK7_$GTBZGEQI6v3RzW^W>GpB
za0KgHDh=A|$FMcT7c77nQZqRb#BLBvRUMj|j@D4oPAS;X6tEH2T}d9DWi8l4N-u*x
zUt>6$c!N@1Dyej4^*S*S49<WjP#vju81_6w?QxXAlE_0v94tOUJi&k%PIYR@Y%UfO
zPg0I%z0z!OoS$WVu&NlagC$E@uy=yN6A<gtDLt9Wr=uaLIv#L9iXH@?FZcj<!ev<J
zkSaTKV2lyRvvh?XSnL+-I@2A=j!aj&R-(%i1F=<VkPtgxeHJEKETw=$3T3ic80lf3
z!$%I7;Fc=YTxUmTDw~hih$jLrsWO^f)s7Xo1LX89BeGbUQ*4BtnRJ)mOry+ZnFt^@
z)m*yJX-?&HVFBwCs+1MoVLLH%zEiWT0Go;dMv8YA^5*O+p7JqHvosO#NWo}6lj`hD
zWwNaSaXR2dm`Z_qtt*2xaEbhhS&M))5XFMv2~~wcl@%d7%lkcqAbhQ6X)=JgYt3iV
zsZ?h=r$r=j0^v~zxWqtJV`B&@=@7*d(kv+XTvp;P_!*ApCw(R-TOwwgi<ig;A&3>G
z0)9zqPUkXdSd+~wwaA15L`?*Iq8P07BSl?e6~wqK1!A#!cu_*`n1V)lh=LU49p(aI
z%}xjTlUbG{TyQ!dh}9{$3KCQKyb`Xh5CZ|wli*~43kG>4g%ycLY!HSArvm<<B-M3x
zsF5&-AU3<)$QRawfSU>M*on@Z;i`1LtE;0e*#JK~f&t!RGuu1@EIo^4uWVNfX%}`i
z*~&w**^NwMgRB#=!%0%GE}F^b;HXR%GV-mb5T=4aGd_3@dsvS!DyH43R63hh!W=T)
zO8$VBGc)ptmn5;Or9Fv_&t$T>T(=THcAF&;{EuL7YqOJ?i8Px^g!v+}5+3jcPt$rL
z2I~{4EL3K5-D+?OM#6Is1_-S@i1?{YA?=_6(9z~07V`KkBM`?qB)(MDp3db8SyPuX
z6<|bBdLUo{Yh`t)7%+?V`79I`)Am$nM@sX7lV-P@c+Mke#p-Y(lh5b6!%$L`&R}Z;
z!P-VSozK+LB2}HsO=SyEY=dIWYcQKd2jPR~krkp;)ug4{DvjzX1;EZrjao9_-3^KD
z*eR(NvS%Q`Mq@>H5u0JP^HJCp2+^=8N~htPrta>pQr^_9Blat_u3~OF>wx>xsZ1+M
z{9~w*PT~}?HAE_i6HrGG&eU8}N7q!I>8eKnGC{4o2xWFKrn1clLh$i!V&f4=aAW}H
z1}p08n-U4REfKB=2&m00K1R}8@Hp5>MRms^$}CnV^Z5dV5iH%52^Qcpzr>r(KB=Oz
zG9-kXn>$k=x1`jzh=^t2q%s7twbf$H48$}bWtoPoA;d<PlHrN@ahyJamDmCedQQv3
zNjbVTK7?4ly#_Wy1Qjy_d)m6PN)m#)YN;ThF;AC91!Yte{>O1liEf0QGf*8(bmS4E
z5H*!C=d)USbwRRFF+n7cU2N*gL3}PZ30Wxw6(dHwO7O24vU2SO1fV%6@osC8I2>MI
zO_Q3+bmbr^+m#UEXhy1l7;7-yMU5@wCa_EDG^Et#OR&gFrBo8+j*a+mdbu5zBC%V&
zwR)a16f$PyKnVHAO0C^+28-B+45qsU6^yA&Ul7vaCFK3HD7&1*Lkdzo)U2nlEb6+D
zcpL(PYF8m|G6Fr9D?vuHI1?~wU6WXiC6mr3tmMgAzbJZ8*;%L5pyu-VbQM_blH8rc
zn_RAl6;K(~Gl;WPeyYrwt0CmWvtAMueNHP%fhQExt09{aBVCl9fUlHex@GJP6Uuc>
z8#%#r*vT_ET7rVlQ6MHKKLZ<U>5dl-jv_efk@%3(U4$xAHdiw2tfy^=orKUk5LbW(
zA@pR6hGEEJ@MWtgpVSV%ncM`nDxLL_=V#609K94wA|49(*Gm1_6+=&8N_I`=C&8PA
z3=0ZRD?ww#c!{6-t~QI6lwg}Bo6YB{D18U$r$A2~3Jn=wnVdTju!^->4&Ex|t#Dg+
zvKAR)(z~V&@n!N{BO!k_%X(1=PQX$rOr=}8x|3~{I1Cx7v3n*z4Y#qGq=OQ2AUqv#
zb<ki$b;vdch0}Bkx+oddpRc1{p$9c3bVN}@GRa6)NIVM%wqKCeX$KWcY!>Nkz*1db
zUl|b32biktTXJe?Q^0`YewZPO597bh-6yb8xGIxP+UQfsY<mjzqND3LKBwBz;9xIV
ziMWCv21BCzB-Tn9&?=CRz%01Yc+zS-!Mf5oSD(fM8yXAB(%gM&jwK(aPnZC4JdMxm
zFMOU=&E}_PStqLfQvs7yb0$Aw=+2@o{V*i4tQZ6b%Ft;%p~}(qc|J`06j$&ga}Or5
zf#^e6aIn->&jd_z_i1Rx$6ecr86TU86#RXhoaf-UmTs!Wl1*(o;I}+U8!qRw7e2OT
za<?7}lgNjt3SaOsdPF~fr>zE)HNE!m;cj9#p7Oy*Xo<t2dyYoJ8KkW(n;t!~f5c1X
z2p&SM5v$_KM63pT!-O)%GHj{7yARy4FZ&i1Qy<M1x=kxJ5Ftz^X+}>%o;|bj(Bb{J
z-+7yNPT=`~IhZJ)3)QsJtDr3+w@Nu@wsY{<fqi%GKN=-}N{ttc#kQ`X!m7>~IZ8#E
z^7xM{o!NEl;QoCFjvU(zY7;R(2!bqvA7ubB2pgu5Wu9z$-EDUtzH9%%V`I19W}}2G
zA`786MTJtrD1M#F`O>NU;L&4;4jedgXt=ZYXsuxZM|%nk4Ow~`bymP!9mm5&j)&Nh
zeRm%@eCW`z;qG**|DF{vf<ZK$#=#wGZP2=m%A63vLQfR1Wby~@J$mTy(PM{q(_Y}_
zW7`cD7up`16zc3QS94RB2BU<=?rDRk>#oBG4j$|4S)I<JyT9Yu7Q-`U5$VZFLbQ7V
z`DsQ)4k4FWu`Z8np2#_}so_KWj}4;4qB5k{96Y+sU?XlEwJ5l4*(o@Do(<`WJe<hc
zGWorC?ccv5Qv%P<V@JD<&9z84T+k#{YN)l@6DTZH6{B|Nj?>*uZ$7f`Kz}-iEwp5B
zJ91BRIU?Nja6uQ*i6-S#j>%M^#F~Xxh@hJ6>CwY?9_UTev)GbZbLi0FiYJXs5x~ai
z-N+v>bv25mKuI#Spv0B!yW{ZQ{e5YwD!uFI;Zd3_eyj-xsgy)LJ%Pwji;`UoR0L~f
z%{b`|8#f#|c*ouzTEeZ_-0g?&$s38u;53E!`t(HhB;q93T2)oorlipM=d;wUlR0}f
zcgN8Kx8J!M#oLnFa_rz;zNcrMI1z&tt!hlkL#J_WP0;f%lR^0?A4X+vKHYcsp}TI|
zza|66rPd!hc(5A<1YNYbse_jH=`6_|H#(6*W-5Co$ESPlK74TBZ3ow7a@o%HhY^P;
zURDe7cc#+mLgo~uO`#y5(@z&O6WP;<sjj<@9z3}B_WdjH@wOw!j@%r2ma1^XlVzsk
zXfCpwxAt^q(!~^k6jL@+f~SN`X7uhu2k*LdUvE0oHFWQhBX>0#$Cs-`GgwO*e>Mwe
zWHYIrGf%wt_qXZEjzXs?l`esQCMTqG!}lIObl~<qhc_kDWA`38c1s-&1P7^0>Phsn
zDX221lIynMr!PD5=wt7l=-GZ#Ck8UZ_{nT#F4LKUU)ItrI=FXi@4=00hmIXRv|XYn
zq7VaRp|b`HPpvuf_#bUW*R2oy@q7RH;p4x5U$#SuD|C59xV$3O(LK5&mEL^#?!$)<
z-g)z_hYlY&cI@aaG3%etn#87w&U`A>v2E%-Cm-3IN_QPD7Vp^E)16CoZ{Lz`O?0Hv
zI3d%z-nsR69)EnZw(juJ!v_!CdF$;5jvPIDXgucyZo!fUJu`vfsw3I8X>B^)o$sX0
zdOFj2;1l2Y`!gF7F|9L|%<mh0&*%QRxNY6g0Z7=l_x8O9jvN?Y-^!Cu&RY2fOof;%
zGL|$Zi!64#DYfg)zCZlV7k;NF8IA6k_|^|ze(~UrJ7D_$JNMqPcmJV-y-J7+kk8Co
zNu;T{BX4Ac2#=-L^=w$X{<fX#wr<-uymk2Y+ixx0;<)v;JMOq;rxvOtpPx0kqlGN#
zx<6M;J5w9)d;fi#603W*>@M~?cHFdXmEK+#j*%}wY$zCtq!8l_LUtlwN&A9qs&ifM
z%9|fw**`WsuzTmmwQHj-jpQq{-o`wp>pTijCY3_JRm=%lHKRurrE~osZ5`;{b<5s6
z_S`|fHA_fwcH#nH^aZ?s9sg4N=ofQ87h*}DTln_EyLoWQVY685{xY~kY&Oj9oB=M`
zftp}EbPF{#7GmMBNfU@&OuBwiXm16e;WBU~tH(!s>E~uW#DOWVQQ^@*di=B>A{Jjk
zKof<B=t(`2z%_NWxC?}F`61gxJVl-rAke^4Jfa|kn_|s=`kdlQjGf~OJj;a~Aa)T}
z5CxtKhFh!9FtT>Pgvp#GUcbM{Gp!+z;C%L!1S`i0g3pQJ*=+UtD6r%rULR(0E}U$e
z1D3p%{ItOGpehoU&gLJOWgH%Vfwu@zMW#5Gh1kO(fu9nrqR8`JI*YRypD`z6By#h-
zz*Q)UDuL2!VS|nJ75piI@l!I!O;IIK`6yLHRg|_es^n{EYN;0Z6M_>W{lF$LlVN^<
zckG}PxMq;X%w=ErgyyE^mN3ts6dYo8-5l{_bcwE_z(8z4G5JA@UGQ*$XlqNn3FbmJ
zCsfz?F_GH^z)Fk-kd<KLT2w{Wf*?oR<>a|gysaswM5`d($qN-#680RnJVcuT3s2>@
zXpr9o1|Tv{cs-PewYDj0bAUT3n0X=GCSajpIX}zzh_f`u!8FnCkuz9$e<%@eYm2FJ
zV-R}GTvei#r;R=UC6+j_^@4+!;#jkaX4t@!oI-(j`$I7~+7^{{ImFZT@IrGZ(wkVk
z<SZC1W`9vI@qr1&<g!vI(^}xYaGunv#G<h{gjIqIJKCsr0FWehKj0*E{#KqxByzQS
zK{3l3kV$A{Sssfu^J1%-D8$SORjtPIoLsQ2L$8DjU1dng0U{^goYa8yb@&WUC*k>$
z;NgWvRgTAEaam~)xKo0ord^LyTm68OoC0zCy&jj-$?+u)=;H-2iSUzxm**Q)C6S27
z5^A)TuGGZ~!El|3t+4t5Bw2v~xm_$Nni-4DUbGf0lf=xr9Ay}Zc&DJA56g;74N$b!
zPysT0Jcj`erdt491vv*>AXdb;+w1dB^ERIs|9GtCB4KP4JYpQgJ0tkHinyjI5EECm
z*6NUiNVbW*8&X(%kyz|*FUJd~cp3(kvG&%QkQe#K*eGVic!={jJ`Xg)d5U3(uE!#=
z8tO-pr>L#j?)Jlh1gSK^dpN0~O_mdioM;dGkt`;=fxxo169Na@Lyd|CF$qQ0^rYT!
zQm`TQoYa8x*r%G9subly!XhVHLS8K6575n6iC3h~<G5gbBq{@)PzoxWY!i^-@PZ54
z9~MkpXi6b+DZ$2?LOugFg5~0A>M$fsb6k-ThibA-oP<ih+XIdK127tq&9|tNP)iUZ
zOncZ>0D1tN(d>VKR+?Z0wjx#Z)(OFi4MsKM&mxQ&sWL$Gs9Kv=3bGa39F4W2@I3~L
z9muhB)Z&V&76n0-tm2B0<?(?RzDLB1p}JN$B7~47l?8Q1vB78X?wkbCOx)6Wqz}gj
z!|h5$f`2VOsOG@#=flyMo=oamvJq8<4`~JUxMGI@@S~c;df-t0M_`-~DDpOt_<VjJ
zIL&+*Y$eT<jKXxOT`z*s2E~c6fg+g!UlGp<>J_eNY-xek0)g`t{DeO(m}2^r#^}{F
z(Zsf7Y0hpLBPFmTGmjI%3Bjm!1<or-)m7n^=9WlvHBJSvAQuH5psCN#9~UeTD<-J8
zWHX+b`CwGjiV$eVI%L!yiYFnv9UM@f09O?b#}j%1E467_qAgO(QIGO|jx(gOp$e|D
zpp|s9rX_3m34y6m4QWN0!SwhzN-)Zt*<aPJMm3t|GYY5bTBHJo33O8+ML^D4_=v8w
z#^xmHAu5Th(<fBA$7~DwLBMlFv=@le#s?xTuvyn3%%dvNNCmZp_xl7y2TC#@)>Y_G
zsW2v)5T_uj5u#=kCZRM?T!{@zUVDi+EN)LlZA)C%5r%GA(Odj9IJr4Ntf=T(31W)6
zDcL>^_lC47l|eL@6y%8_&4Wumzum?biOuW`wraYf7O5{4(OcwAeq%eWk)%dTTtPKy
zT0v*EWIYFYlA=u_!ihQoh8TQ44>P&k^t2Fbqj4+}Wk?Yq3$+dz1#e01$)aYa)m@#y
zE{3@ofoV@d)HK8>%@$xyfLf`mSQ}r3Xx9>gcald+fw?tV(g;l}%1kQ2D#>~g>!LO&
z73G0H==Y#J+1yg36+zEU@D@~%8l9?x+5%j{0GkGHP(@HvURI9U<}fFx4ef!=#rX|B
zE~IKy6I7N|1|foVb2Z6naM9yJsVa9UArVE<!66tXc*b9&7v^+<M+q7{5%5fdhm~ay
z?XNlF@N)%9F2oR>6WWBz=*`@5nkzH&((5SFWcCs#t&>HxAY4e%)hR?MtEoX`0~^;h
zy=)9CCp@4=3cI-yA_;lJg`(=TW>K|dlpcMisD1*HiwXl+&cK*Fh*J|i=~#}hQYSTw
zo{U8T+zG@=U9zB=bmZA2Wr*6r0Gn~Jlqkof;EEw8P)sx>EOMu@4GH}u)=*SfHAH;^
zcMy+&+Tmyfl@hDL*92!FHv+i?E2N}M%w|y9h*v<BuvFC4NCN6P-Ir6KfVWgYpwFT*
z+RU_iLi58$G19b2>>Q0gCQ6T8v&33>{=))^O&dFk&(Uibz>^IhGdQCs^+_;T%1y;b
z&@Z@%`zh2G#5VE_YoS{JjR`cJK$8giNBTINr1^sq1Gz{hh1Ia-c<w^m`xFFMV?9%N
zMtK=v>Hw&Ks28X$l|^kDv1zOn-PMO@3;3F_z&|CB_(^Ch8pZ&aHIOJ9G7W}eKTklK
z@l00c&?q<d9?x2m+DSYsP(FP%g`^lW@t61~(L&W@H%>sP4QZO_9`KqCObQ(k{i^9n
z>@NtYQahe2J4Zt#_#tc&ap8n6;5oxJB&W2AGJ%{K9#$zn1p=Qz@F2=I&z++YM5#)e
zgNoTY(zn3{wBZ8T{Q}z6U~{yksgmw>K*2s2;DMrQOZ1El?COm#q-JUw)k4zL(M|)S
zE_s{=9Hq7^9Ye$YyLxxHJ_PjJuz`m_v)E#sLZkwb(4IUCPdJst#<9V^-u{s=@RbX+
zXK0{xOlc&D-vX+B8bV!)vTk&+zi(h<G;h%2fT9J7QYcs!37*DLTT7!FW*1eDB4>Av
z4-NDWjc?t(-Au71Gkj&@5UD80NN37n<{QCLKn`-$^V-I-v7y0%k)h48^}|8KB7`<h
zW7_6&6)Iwo(GwDMMp2vLZjm}NyQP18WO!(JY;#gc+%&GjJS$Be@X-S=&`{Hk-C>d~
z92gU2MmHF>!9AnH!=qy(>ydUlMpuH5L3dw5!7=lJcoOSC<)`M>A^gkA^nu~Qp|PG^
zC(5s)^o~)~4At6;5Sv1{`x}!*)C@)mpkOe36=Hh=ezqqz5A~02Kr2L}FEun$)<x_S
zs32xeXi$+HFj1v!tdu}G2cL`D*gMca(19WjMtR-Xh*pNDyr@tmSjpium_+4aRYN1T
zwQwN}SB&%x_Q>??wkW$s#_Pa|A;(4=3@k4k*HO7~kf^AzsO5;@B3wFYg!q=>zJc{h
z!AOVn@X(O(BuzdK)yYPasxqyXD5qYBQi=W_VNkE1fg-EYJKWpfQ|6S{jgD+Yc0#Fx
zp3G)G3YVQxy;>U>&>f0Gs5Ppor@?5G^P_{icjs`n*i=Q`Jv^p>6HOIvSYR7DzPhBG
zMhvPA!C<JNEs;>*uoGb96}4}4aA$8yrAKUHC88M+m&1k$TBvVpY}F=|lQ`aK1yYGp
zoa4C(fw`kUO?$*det2k5F5_BkEg%6E<R?`Vwo0B+Cg7ry%FFrj;i0}ALs<pAcz$Gb
zcmqA{EW{H{6lC<UI07y4cmlnCAwlrL4AxPEZTi6I&`|Hr{ti4@jX>MN8{n3uzCD(Z
zWi-xUbg8S?=40sFApjqpQU#O-s2kYcw;oN&rkh7cdPAu5_$I!p6?_TEHznc)#S!l+
z-hb}Y+O}x45Hls@Y2`S0)y+4L3=i(yGQ1)tZ`(66wnf6x!;wH+TRX-nXjPPWG`B`B
zD!v`3&Yb(Lu6128Ooj9bT}Xw3u}Mv2`o~9y2X}AUJ=B%iG&VZ4!cPxfcO=>lT{R$%
zr*A)del6V9zV+dA51;tmQ^%BObELVvtcrLvxpRF&UNM5a9PHh?V|aLQd~9@UJ^6DC
zHnq`GEFVuq*S-7beJ59={krYmdxv}SNj1^2Zgspi5;csJVeguQXV0!~&%)nB1HC(T
z4UUYC4sD7#0hgFbb*r2x#?y&dG^(%4%1Tm?p^wLm61(}C7hfuMH8ixw5>ah@$FWcT
z<GpJ$n+CDXeY<z|4vq|N>a21C)iU$dvVsj@<hXoXX^L+c-TdG;KYJkCS|48juCIUh
zJ72za)$Sn_u)f{9di#e4*VcO+E(6f235R3oFKH7sqeYNF@wlArT9M85uS>65Gq!!j
zO*?mP-?nZ0_MN+SZClac@fxUB6Iwk~(t_&6NF*m#9ewo3iU__*TwPq_Sdr3|hAKe_
z8OW9=DAgvA|7IG~NaqSoS2a1F+t|^6Hrcaj!@4yqQ%NmcOQ9`Gqb8$AEU1heL)sDa
z>WG2rP*e%Gc0amq-P*OiyLN8Z{{yfsugl?Ziw3rZ5`b>sYh0Z2l`l>Ka;j@^5NG+~
zl*j9$@C&{e!uZi1^AodBMK4a#n+pa=g^N%H!QMnK#yE|OQ$XSbd~ZQpAs>aefN!Ou
zP-4YXif^Hwup(v)3RD2MaE6-_Z4$0c3FT{3^f6!U1S!w@fPMkps&B9J;tH3`xHg50
zS{O0fYC(W&GpJ%f4Frr!ZaZssl`l=1ybxmH>yuFmZ2?%RsGb(wB5q6gJkI$mQxk$k
zjH;S}Ygwh{S`nqxg^Lax){8N?%D62hP(c8-k`)H1<*#XPrv0Q7x5j)ZaaNAPT7=M2
z+N3L5%mB6AVskWFBjDsKh*rQzfO#;wn25cE5vN60)I|BBlt++I0NUpOt(pkERK<z7
zC^bjgsH5BAumW7HkoXGBs!DSi&*FuedI&CGlVU6$kq%F7m^hM^Ag5Ejz*oufc3HcC
zXVn2Pq=q~M>DCF5w}M=20l5#i*Wl)AB@qSK0W|BhV6Tr=z~LaLSe8>Pp}he;p3<Ha
zZpVcn7gwdoKzVefDF|f4!BxqzAeeXq%W`=nFiA4XG?;KT3db|7bc0I4@T?{=$WuoG
z$x1~72%Ug&Gs=OzB|$X#itfg}C}Nus+!&iQ3SnqEnkxgw!i9n+1kl{AC>xG8I&v0N
zvywDGEXD?~$Y9iwuBgP?9ER22k*uL^0EWe26H64r>d-N9rVI#+ar%IDup+jyDC3Zv
z$FGtqg4?(b#Q=H4;1H@RgzS~@sBi8rl-n;N!Xj`f9s2Z(z^iZt#zVx_{4FSl3j!uN
zm*4Gn(cypo4wP4%5zO@fIOy1{>TL#e1(a0``axE{{N%MeonD_vp(xzy2nmk2?mRJ^
zLz+PsSAhnEim>Z?8-=YX{D~`6oZD)#I~{fxumMrLA2}0}6VY%rt_#fFbYeUX@i@Xb
z&<IDX5TIgsiAQ3!*xQ0=;W1!~;(4TIAktpI$)~A_$c0Nzrl6gIEcnt5zJ>!RQU$0A
zppW>Fz}6(_nC?)O_8MGTGp;o;#OXuRiJrNkF@}1KDN|#U?E?P+v|b?`z$RMW&8pm1
z!%<`k%M;HEnDND$7FokV5744r{GecJ(I+v~W4D^h_m@}*6@fxQGPMPBd$R2bbX-iJ
zGDvZj8hsk$7e#*L*!;aEuUUK$kx)_H0uHUCntufTDdSB#!j$4g1r2=x#eL*h`N9$_
zqJlnzG!iJ<)F?fI<<~95m{8A;gUKSxG2@aFi#7^$fS7`h;@5CTGFbvXQO1?f!BGts
zS&5j5k0N4Dn_oI9O!I#znBvK4-Bg3Q7624b07_`q8Vm%9-bO-nO;Dr|m*Q%w!>!G&
zkro3#dKfhjWm-;70Zo~MjAC@opaM*)G=Brh;uq*$B@TBV5|r2?w?}}!J}6j#5ruSv
zy^IiPbIh#969<KeP_k@dT}+Sa9T*0t0W|@lj8qET{S+8Vs%^0u=q`goVVsN8=ra|y
z9TELFI-4qFD-MlNbE}MR?tsost7ct|HdamwCJC8nr!y!7(wUb@$_5_Pl$?P5jG{Fy
zyl3S0hQg?KNerE4s7SWX$zXs5P2wb;2ZAVmhVUuTQ4;9?!dpfTv$raS$sSd!2oGV(
zF-5R5M5X;T)6r1Ieju-)lClWdxMPHgd;X4*J=hSFA)=^|3RFdG7^W&JuncNZ%*RA$
z8Z1@O+UWHnq^A#a2<sGTDbl7?0^w~lhA}!iU_7fVV?8H~rRl&J<}Mbwak0qau4s;h
z=oG-$mT?P!7iD;99_Kj;OU*cR=B^e6>D3~NP_vkEu%88;rRJ3|WzAze1z-@gnrc8x
zo}=H_iGtHSrvp>?JOdm=r;o;t0-7T$nkfah`JM-a<pB6>iep$dU=$jA6x>Np0E98b
zB6R6BA{Pn{%ZF6hT>>$qYeDcOKz9;!tfG3$WYP%~wop`q8;eLPR_};~PEvtW5J>fE
zVT$TNAQA>pYBiN-NnQl#OzX!{Q<yltH^gu*OrdO?4zEdsTN%VbmP{MNFRNG6MFS-9
zfUFGR#B0kC4j1W|F^CvA)3~+EBhD)?U^g0M9H*x1KuU~r5_q|R+%Smb<6uRzmndHs
zvhq*U#HR8n1HK@62A7B&B1Kl3lP54%TQH^JyrqB*Ttz>RBu^rIscUeiP^8A;Gd>T`
zf1bpK(R)HR@oA9PBu{}HVzhR8O^9(i#g71+Ib*~xi@h@N7Ym0^88I<Wj8+FXgwTRK
zNB82iLCokBk6~PH@maytYJ6xxv$57dV(dQg8H7PY2c@;B^2%YKfx%coJpZv()pqTv
zq4$DN`Hjyb2Dw$qj*fOx#DyU)>9Gr73sg`<N7+6)u#H{^qE8<#V=VF3=1>`9DHF*z
z?HTGD&@T`%xNk_Im1r4SnMA};+{UhUj*JfW_V?m05Nwbh6ii}EA!(t>saG1X$|SOZ
zf?ZBk-n3_UU|?vx$-osn_+EiJzXVZbTtx$@05p~k`ii=Ke0XqRXl&0agP6l1X$mS6
z1}z03YC(Hk1Kge4ee=lB;K-isy}NN2h#{PKj%E+S9SNwT)-Zfi$0Ro1r^x!Iaf*vz
z>;x)OO{v{DwOI<J;3$x#Gv)A~(0It*I<RMKbYygVOHz?H-qHy(OirAZmOunwy<zb{
zty?HiX`BRLQIbQqjDdc9w1>{jyY{T5ELQQ1fZI_WNmx!{!7_XjMo5=gMu$hnZ_1~D
zXQ*o5o;Ai|{pdv)t|^Iv2rkrvleDVn-~ku`lx%Q(BbtGNW>M0^<AxUEpx>2>5e<=P
zU|s|~K(dhtbi<Q<LxV#dN(mh6_KbHLo9Y*5uyPdA(`5}5GN;s5W#!nw@J3|<LAPt{
z=7>RT0RqGZ!-?b>N_-p$4Mp(F<l9CEhHj#=)y&AqXy8dC5bKsEfvy43RnHiRJl<iP
zs7KMC!WyhVDEbFC81}3m8{0|~#*d9dlNg5^&S)OJoqk2b36dCUiy|f{)@oC_#)kX)
zaUTc*wBC`Mb?^Z-bz&9*u~36y{WKsVJyKCo6=|1cRX>OL)cVGNz@))tkyimlFu)Lt
zPm&_-&F%OWgw}CHN)k~@)Cb_-4Tz`RgBi?@RyjX1GMqy01Cca0B;fK%(BmK|0`NJD
zEzj>69U0s`k_B#($OF#UMj>L{8w8jDnA<qZ&|>2lP^PdfgvcP`ufKP&6XkWy*!bAa
zz_XCexLV_K0VD+S?Q7O{C5(o*02!w+yeiv($_?!v=)w8B`IfP<;RaMm{1Hb(G!8uz
zs!2{1RENBxbnd}3>+r>N!H{*Fj=fuM866q!1(Fw6w%;-~zN?0!?xY6DN&&2>D$)E}
zAaEXS*O~ht{O#_Z74$1Ouv6nJl(?*Ea&BPH=;(0Yj=tgU>}FsV>&v%!T0mHoE76!|
z_ul`|TKpADbo-+ZK62{5Gxw<RwwCq;^#F#ej$J*nvT~Hl=-;^;){O5N-_>f|<Y}0c
zLrT2ockeEoUIVz|j(5FlWJ6a{S2}yvYYi<BP>nCMqVctd?tfrSdu|l?%TWLB-r=#a
z@sS-Uvj*k?0IeveG5f@lYjTRxk&I()6w$fmqks2}<7--*qrg9sdv@LP$?v{vZEo`r
z3>fI|?H?W;-rm(L8aH|B(3$Hv$1Ff0uq{(+6CmI%5B>dL9$O_hH*R|OOD})ttGBP|
z9T^1<+t=4WI5NB;e&HrhxB&or0ox?v3w9;fy)wUYZ1buO8*kmUc1vIH?!qp|?%jQT
zyLuAFO&+Ve2`Z962GRQ{4te$6PyAL-d$wy$X@g_^ihMTFT3ZtV;sG3uA|8{v+30c%
zzyn(m&uvN#KA76Lee0&1*01QwwM8i4;c7(fz_6vO3jhyX=9vRLHuVlI7x1_zeef<q
zR^sc%cV6#!;2jUV<AHZP@c*X=7^~F^Sm8JIau1w+;DO&;h2iQq^J@MZTxI?Biv?UT
zx~><~(6B5o`kwzey-WMU_vKC3qn|tTuU~%ma!zy8O<ywZ^1kt@aSZayeYv0e)$HsW
z2La10`Q<tOQ^SDS@4s(b-7<Y(8v6y6@po-Y)=r42>nmmbv#-7Uk+J1j;Q32K#OuGa
z90$1H2j9)TzW>ZvWEs1-;)iAa&jajQ`fK<1=hfrqD=*A!Zv@`BlovB;#PICwPj@VZ
zZJw6<!bSRLu?;Uw53iy3Zm;#lKR+knjfa;LK&JD*USI&~!M}g&ljnz`*J?uNH|F@?
z{L5u*9w9?>?pt8R8~^gT^INK~rKXq<UI?IX003M1tK*dgnlHS0<J*6BSM${^;6HJJ
z<43!euAPwTuU!yu=`TP0`2OarB$a99k1ue&aRyf~mi+Q848RN0j9-5A@%{MUVl48q
zKKkZc9A5&oz2ukkuip}Incsf+>HF|E2UmQ_Ke&kJwbfUoyYd6;f4fM+<$nF?C-z@4
z4lKtPa7<rW%@v<8k1h~#xi>TpE+2{Yf46}CFBb9Cl?*UFut3D+-~8|sw*@XEz%=x;
z1@x}~%3kWrG`&E?mEOGk2R&~OM9Z0l<ZtX=s&>#Hy(oegid*pR&9D5fd})4#o?AdN
zJ6pPx;u`GPw9to_NWAFntN&y0k_2ljw=ZweJaG9iS=0*cdvEby<+pF2U9q57T{~a<
z=lMR_yRyZx#A7J>PxIVY|M}~$o?3xBqIj_Zwg2d!{qho)U;W^fm)`f=Ta+65_f*&T
zYJ2$-A&b8K^;b`?6s&=+qaXUx4}Nv|$och8Uis3e&TOd$ym~FK+Lsnp__l|?dhw6%
z`{38E8Z@te<?On^wbTRQ^KVmewGS?B8LmM8qrX0}^6G5_Zm<4_z25lo-weIIY%JUr
zcIxumc!P}k*@qggk`P<IdxKP6Ud%6FkQX<g>c3x}@rHf+Eqze~EQkK>hN-%|pl>LP
z8c=!eLJxU){_FnqQ;~%+cgeeszrAh^iwk(|vkjN1T=3Su?;jWEzwW26eGq?ia^;uz
zz&Ed3#o_{9Ke1>nbnp7?;{4bB^ySQzmyajRnrDA<-8vQ%@W!Wc19Op=srkOoedp5i
zbTNTTefGv(izXp%C^hxG=c&*B;|~ltW2w@wf&T0GpR8QvW#J;Lcl?(Jp7^V;|NAd*
z_^I&g{a10ooN;EWuPL+V(8FK6>KT6xi@uoTE8(jwf5Bsq_U=!9^QYH%)L*RTiod`9
z%+lIpd;O|g3r~OftqJ#vlCSZ>k2fw@;kCT622%UZf989yU89D@$zFQ~x3HG{GC7-f
z{?V(8OTNaZFQu2Pz09!b3Mk1n>YXS1*|}?MiZ3;@=h}yqd0m(N`StvzlCSOkO*csY
zFF$&<cJ%W0+^F@>{(M;=6}dtCk3D&D@nh)n%V+PtVYTp=gO^va=%?2EFB?tE`S6WT
z;~Mo+U$(Q$QFVEqSJp07J0TTMU0&95KK=EhORoXymzSgI3OrwFT&e?1V>fa_`SI;b
zI|lK0b?0wnGxFwhm%vC@bw}`pE4XrbAAf)KRW&XoP;cyX@aEa2MWAW?2DhXyUcD2&
z*a5aDZshi3&wje-G<dOU<M)aye?_sp0C+w7HXVz7u=++ep@zk07E^cWGt<oSR=Eh*
z_b!K~U#fThJ^QgmBrWgJKZWOoU&BxH$CsyM5w4f@YtTDSV)=_jBrWgJtK;*+ui>Zp
z#_NCc+%@Q(Ct<Jl4b?Jy@aaX-ka^AJpXN_3L%~&8zP2bFv`|0$>8l7^#^YDkFVwNv
zJLdUiD7XsC>xUQ9xbT_j(Hk>;E->l+*M>zHmh8V_&G%a-eCFD}pds;#zvO*O#C84l
z#U<!>edfAUU6%Q;me7JQzx~E#Wn9mP&o5#9MElP5sJblg6HDoVoquwJ8=%?O_ASh@
z#ow8>+{pf)`r~`y#Wh~?)c?`TI&t|QKCl$`<DS^Q8`}Z@YyBk)yxQBw8#)2JKC^`C
zXP9Pr<VM!uuP&|srxvLHu>8%wl=J0vS9AB<pIi5T@lr9%egC6dmKJ<vV=QaGy<CM0
z`Tp&$CG<WQIl_Eqp`2yDTi)ua9c>@K{wnyB542shq$U2^eE)Sq@xS;;$5M`+x0&Y{
z{=~BD(3{`>U!O1HFK4gs<=y!FGQT5xX<Kb@d4adkVn=MS`1z&w18@B7rIF<%-9ptD
z-UZ(C_3ys?i))_BfBv`c-&b=3)#E%8<N3XZ&wcIHpTGL*&)@vs|NQG05f`uh;wL|N
z<%=JC{)JC}?r;9jKYabAZ@%&`|NPzm{h@mYa?*80-Gyae`io8P+qHei=*(bMuxand
zUih!4?(J73htuu%3-#epsI~$Bhc~}vsYlJFTCV!u@T|#fW=#L#s;+9wI|TpfJn)+i
gs^7H!|8yI=v<1E6{-ycr9qM;H@Qw%mpYXu{1;S|b>Hq)$

literal 0
HcmV?d00001

diff --git a/extra/gpu/demos/bunny/icon.ico b/extra/gpu/demos/bunny/icon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..0fd376bc5134def5ad574135895ea9f1608d5b66
GIT binary patch
literal 9854
zcmeI0TWlOx8ONu#V|y>Nvv=?Mw!2>M#n)V%=4L0c<HUC2ByCEZ6iTa#Mol1GM1j%*
z5h;j*`T#-#K?+DglsBXbfyx6R6}%uGka#IVREP?Rsz|7)gaXaZ?&1IcX3lzcvre3l
zNC;)4lQVPX%$eVJJ>Rim+=G9cHW~OoYn&+>M$#~hG8%@AN6|R0f3bjJu<4&t%DCI^
z>fo*q+&LdWtliVp+IauJs&lf<&dzqQ;kr$8^4iPI`<0cIb~g7}+j--B+lsN$F7F$S
z@9TB$R1b#ssi~<Aw|jk8zB^_w>XiEPa_9O>lbKBMV6iy*sbX>L`H}ME#d3M#nNn%u
zD}g}r66U{<Ob(ozpIiFCf%)Z+rNX&$xxR^WySB}LVQO;c)1|@EaisZ4>O`-5C*&Zz
zUO$)1W%9Z52Z!?`FAn8OS8~~+8X4KB3d3V6ozAGi!C^HtG@|amZ$*9liKo=Qy$fn`
zbV@z?@G14&m%gk{pZbv6JF~17_dlR!cOOzSI~U%*ck}emvOU=y`Wx)=YtWVV+09&g
z*)zSlv-w={jZ$GuWith}Z*EDQJn;zFM{B!w&Q{+0&|~(};?e5F_>}$F`_5F(zW>Aa
zXnC^Qm(JFvw(O{#e*A3p$xnQ`IyZaJp5C=sJ$mF}b#U>7wEgqPuFURUzBILQdQS7*
z4jHh9*fteQJ(7p6!K$Ep8+x~=w(P9#-Lp_l^$gYyE#0r4dh)zFa`?C!AKj$<?GY+b
z(LSZ(cr7znsPR6T7*wOMSAM8mo0(pyEgyP!b@9Nv?77(^3is;Z(g`)U`_Qu<8S1vz
zW9#iTJNlhHiS!k+7Yk!o-CkwE*58*CnaDI!-YEBE=Ka{%CRHqs%X7$p`^~Ccnoz^e
zI(WaJcF!!SBg^kmb9)X~hlfY5Zr!>Y_YXma!%vg*{Q2{@<VRqZe9kreUESY~MdB)v
zNLBj#GLV5xW7I2nCgmPBQA4@1j13M9sovf}l^M(<7E1D5-htmyo?>xAA;#-+9oT<N
z!3Ju4Y)TCbWJQLhh2w8;-#$ONUR^iO^XNVw3Yc$%t*A0h)3&Uza0v%^C<kmJT;=kl
z@P<Mb=PJ&%tcdD^ESyhyb(4F@kjoX-_HDCjX<<c8jBkZ)M(CfF1;}$?{@7QWxz>BH
z`OPlh6Jao*+2L?hg~Jg=J~EZ4N9xn%r%rS5335AgqjF7IXcPL5!%Z7N7To9aW#OjZ
z@7TT%J~gaznL=e6v9PfJfy?XV_0FU3=zGfyy%YgA^jHx&z%P0Yg^@1@MBkKy{z0B>
zW?1B-oKACOpgi<3&LO*Q)c5GfCh?!cjDx+0)!69f%H~Zw)c(2qUiPwRrW^HmM`8xO
z88$<&@Y~>r{>2V;u0SBD;_;-gP`6~GziYo)mBFzYWs`XE@KcTg>^A}#W~LV<b{7|p
z+xw7@_Uu}^a3j`M&%OMipxMY@*DLiKg|5Sh)d9&VWTQVj{^RPOzK40H8IqW$jN)@m
zGB77)GI@3H*4?$`gAXDfpHy47OrLJWccU>6e+c})ZP34$U)ZSIkcvj*DwXO}@mR7Y
zKVv2qOF-A75;x-ikfBs^W14;iAH=>;ou50Zrgtt>!Lj#7tgW8oy}JL0{DGe~`@h#O
zygp7H(;f}aT^VVUNTe|aBo~n%P2{2f<x1EWr`5)ZZLfo4uod5W#<UI0&dyJU!6g3g
zvNZ5{?Eycz=9%k1)IV)QU)M1#x_9+2@r-AM!njSjdQ<(E*2B5h9Pmrs&}|rdtbkc{
zeF(kl*A2agyIDq;pSJ1g=@s8^;MZ{g-;q3A7_a7$0|MOv*?%?1TAXW*YyG2-!-t$0
z2qOn+KDVb|P`BKtD5KLnGJ5#a>3-3D-Cvs6VVf#*aerU-ulR0}Z1~k{>$O;0jpMy~
z-C_FtKP0ymcJ~06$?@qJa%himJN|FA^q~;sWWA&FXG0F+{>N4vzseqd_I=F+j(RNW
zvGw%i*Rq@4{%^Ycb^Vi_ycy(l`Y!SYYL_A8n55Wa)z6q?EtO2B9pB+zr}fTW*rlGT
za-91#zPpc%`ujKH#XLD%alYFcWDaz8evvT@CgG>AFqaIXKI1o~j$mF#V{MvF^}8}S
z{zN&Q`T@0G1H0yT;+C=`6Y1}2UUKQ{=H6xI*}J8GxpEAlKN;xq|62I1NLA{%U`VBU
z`s($JFyY%|r!0BY2~N&+>LBv>p>EZ_<IMN4508rOQLp|B-`he~{5qPM^*x?l!;CT7
zAcnTByQA~jNF;tanMl1(y>Z`<SkanA8=wwlPrh8P;N(JKrw*MulzhxJCiXSPGyRA6
zb=`BG+gQIAhR1Eno`@wcy6pAZT{G)mv!ie8Fgj*JfzU^zk@$r~JoS@gviEnr>4AT;
zhUEIJX{08|7HZ)T;#c^QTOb3O=tHa@MX$mGor0Zpbbo(V;v*7?sbJ7t<!|5~L)|fE
zmykR0-M@ip*yV4jdouI6-!Rg?j;<esOv~;`_9E_b5`R)dihoYn;IBZADr$ln8H61&
zP!1=DIyFr)nUXkQ-L{(7SL<j;&KUMpIY)|(9Gz=_8?R(>=5I6FKI^jA^B(VY)9mPb
z0-e5JIq@j*RbyPj29-p-$3~v0!f&A4nCLhJ-({{5X4CDtchz%fL<Ir?sm-W&%D{6Z
z>p0d$tWRkp#>FZ(^*&mIj;`i&C1nQ9m%-&*iyzPGaU9&xb-`u7iaf&ol>EXP3<i}S
zEYx)m@*VRv&wyTj*N1A@3vd>b_hs**ymDqltgxo%Ugh`uC8v^|^(B0~hE|0f@b@u$
z7&$i@j{gRHDVP14xb%((4PzW<!N0q;fSjk83z;7{hVw1<zKr;iJ}WU73O}A>ZY^wv
zE8;`AclTPJ3n+`MqvL}2)C=sudZt2N9kbjk2K#d=7LHTzQlp`7>GLkXJPWpWK4>BC
zobN_!{1&fy7UbUym;>18%dExeN0g28(46xlxI(@lTHrP4;vF}yk`;EOOz!!NK8Jhi
zgXb<X)0W7)Z{nRFf%g=e_L-J?Cwl|`hORSVXI-+_ShF)Xie8Y%xIS$ldn=etHZxR3
zeSkPmE5?Ga+xH7!XXgt3?w1M}9rMA??q|$y-!H8IY#6j?AM~hKgOJ&8+IaTIXgK;~
z%ZxndGLL93m+iXj-Z`P}?$1PM=a5z9S%Nw*f}6VGS=QCF_%mdv!l!NSJKO^h->+eF
ze!P{PQKRldjjAlLV_pq9K@C}ku6zH4`J-N5ea&^yTIL!(NB4T3<qv+HjL7vi<DPb<
z&Y2_VC$7&{S*Ou9^!-$__bq>y|7%zy<5^GkZH#qt%x4(=@TEV~ci=NN{Lf|%N~QYi
ze?P!nU7PUTdOp!>Ua!~lQOCTHjHmeb37g!ksUS}kjlRuRgZ`*P?zeB5LF-$1ccWh0
zWvJ_n>*}>p<2}!uit|?m`j<0EB9Z<)-@RRbZ;zVRO9Q=G=0@AYE&Hf^+l0@W)?b4D
z;5VAM$=T9RF)q2m?C|ZfOzR!ySMJ~Z8&o))*h79jN9*BMdaMzTS+Q3mVcD1d&3rA)
zsKv}c@b`Y7|HZBiT_3@`f_Hs>8*NQ{<C)k4eLG_J=O)(UehwSIim|B6U$>ce?VGta
z+x<tO+ZyYrH2zM29R82)4V@Re+S`}$on-S`<Uw1L+dCig#0JQVpJNO$o|5sN@98<~
zT}RJv?(x14w!Q4eqiqJP?_f;oRPS7Jpskx*zsq-cZFZR@$na(eHo({n$MiEj_g4B1
zV6}pwKcMD)1?xTJT?6;G#Oz&z*Z7I85C_x#_O8SFxgOW|x6)$`h+w4AO#MEtuj|)(
z-p%w_b6x&+Gix@_#W!x+KbqIL-o3m2nzhXJ-d*b%_2RDkU+00fzHxVa^{n#$rVIGa
M-QQge+_DD#1F#5OHUIzs

literal 0
HcmV?d00001


From 4a5e9ecdf46c481a6eb095eb3558ed60e9f144e0 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 15 Feb 2010 11:26:26 -0800
Subject: [PATCH 020/250] windows.kernel32: bindings for BeginUpdateResource,
 UpdateResource, EndUpdateResource

---
 basis/windows/kernel32/kernel32.factor | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/basis/windows/kernel32/kernel32.factor b/basis/windows/kernel32/kernel32.factor
index 80f50ef2b0..1e9a387646 100644
--- a/basis/windows/kernel32/kernel32.factor
+++ b/basis/windows/kernel32/kernel32.factor
@@ -826,7 +826,8 @@ FUNCTION: BOOL AllocConsole ( ) ;
 ! FUNCTION: BaseUpdateAppcompatCache
 ! FUNCTION: Beep
 ! FUNCTION: BeginUpdateResourceA
-! FUNCTION: BeginUpdateResourceW
+FUNCTION: HANDLE BeginUpdateResource ( LPCTSTR pFileName, BOOL bDeleteExistingResources ) ;
+ALIAS: BeginUpdateResource BeginUpdateResourceW
 ! FUNCTION: BindIoCompletionCallback
 ! FUNCTION: BuildCommDCBA
 ! FUNCTION: BuildCommDCBAndTimeoutsA
@@ -1013,7 +1014,8 @@ CONSTANT: DUPLICATE_SAME_ACCESS 2
 ! FUNCTION: EncodePointer
 ! FUNCTION: EncodeSystemPointer
 ! FUNCTION: EndUpdateResourceA
-! FUNCTION: EndUpdateResourceW
+FUNCTION: BOOL EndUpdateResourceW ( HANDLE hUpdate, BOOL fDiscard ) ;
+ALIAS: EndUpdateResource EndUpdateResourceW
 ! FUNCTION: EnterCriticalSection
 ! FUNCTION: EnumCalendarInfoA
 ! FUNCTION: EnumCalendarInfoExA
@@ -1831,7 +1833,8 @@ FUNCTION: BOOL UnmapViewOfFile ( LPCVOID lpBaseAddress ) ;
 ! FUNCTION: UnregisterWait
 ! FUNCTION: UnregisterWaitEx
 ! FUNCTION: UpdateResourceA
-! FUNCTION: UpdateResourceW
+FUNCTION: BOOL UpdateResourceW ( HANDLE hUpdate, LPCTSTR lpType, LPCTSTR lpName, WORD wLanguage, LPVOID lpData, DWORD cbData ) ;
+ALIAS: UpdateResource UpdateResourceW
 ! FUNCTION: UTRegister
 ! FUNCTION: UTUnRegister
 ! FUNCTION: ValidateLCType

From c3e60fc9c3fa8abedd12e9f63c8e67e989ed030f Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 15 Feb 2010 11:26:56 -0800
Subject: [PATCH 021/250] vm: change id of windows app icon resource to more
 standard "APPICON"

---
 vm/factor.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/vm/factor.rs b/vm/factor.rs
index 47f899fef6..a36ef297f1 100644
--- a/vm/factor.rs
+++ b/vm/factor.rs
@@ -1,2 +1,2 @@
-fraptor ICON "misc/icons/Factor.ico"
+APPICON ICON "misc/icons/Factor.ico"
 

From f1d60827389004d4ce60e5d8dbc600dd7f977e96 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 15 Feb 2010 11:43:30 -0800
Subject: [PATCH 022/250] windows.kernel32: add MAKEINTRESOURCE, standard
 resource types

---
 basis/windows/kernel32/kernel32.factor | 28 ++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/basis/windows/kernel32/kernel32.factor b/basis/windows/kernel32/kernel32.factor
index 1e9a387646..576fac3a06 100644
--- a/basis/windows/kernel32/kernel32.factor
+++ b/basis/windows/kernel32/kernel32.factor
@@ -1,7 +1,7 @@
 ! Copyright (C) 2005, 2006 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.c-types alien.syntax kernel windows.types
-multiline classes.struct ;
+math multiline classes.struct ;
 IN: windows.kernel32
 
 CONSTANT: MAX_PATH 260
@@ -787,6 +787,30 @@ CONSTANT: STATUS_CONTROL_C_EXIT             HEX: C000013A
 CONSTANT: STATUS_FLOAT_MULTIPLE_FAULTS      HEX: C00002B4
 CONSTANT: STATUS_FLOAT_MULTIPLE_TRAPS       HEX: C00002B5
 
+! Resource IDs
+: MAKEINTRESOURCE ( int -- resource ) HEX: ffff bitand <alien> ; inline
+
+: RT_CURSOR       ( -- id )  1 MAKEINTRESOURCE ; inline
+: RT_BITMAP       ( -- id )  2 MAKEINTRESOURCE ; inline
+: RT_ICON         ( -- id )  3 MAKEINTRESOURCE ; inline
+: RT_MENU         ( -- id )  4 MAKEINTRESOURCE ; inline
+: RT_DIALOG       ( -- id )  5 MAKEINTRESOURCE ; inline
+: RT_STRING       ( -- id )  6 MAKEINTRESOURCE ; inline
+: RT_FONTDIR      ( -- id )  7 MAKEINTRESOURCE ; inline
+: RT_FONT         ( -- id )  8 MAKEINTRESOURCE ; inline
+: RT_ACCELERATOR  ( -- id )  9 MAKEINTRESOURCE ; inline
+: RT_RCDATA       ( -- id ) 10 MAKEINTRESOURCE ; inline
+: RT_MESSAGETABLE ( -- id ) 11 MAKEINTRESOURCE ; inline
+: RT_GROUP_CURSOR ( -- id ) 12 MAKEINTRESOURCE ; inline
+: RT_GROUP_ICON   ( -- id ) 14 MAKEINTRESOURCE ; inline
+: RT_VERSION      ( -- id ) 16 MAKEINTRESOURCE ; inline
+: RT_DLGINCLUDE   ( -- id ) 17 MAKEINTRESOURCE ; inline
+: RT_PLUGPLAY     ( -- id ) 19 MAKEINTRESOURCE ; inline
+: RT_VXD          ( -- id ) 20 MAKEINTRESOURCE ; inline
+: RT_ANICURSOR    ( -- id ) 21 MAKEINTRESOURCE ; inline
+: RT_ANIICON      ( -- id ) 22 MAKEINTRESOURCE ; inline
+: RT_MANIFEST     ( -- id ) 24 MAKEINTRESOURCE ; inline
+
 LIBRARY: kernel32
 ! FUNCTION: _hread
 ! FUNCTION: _hwrite
@@ -826,7 +850,7 @@ FUNCTION: BOOL AllocConsole ( ) ;
 ! FUNCTION: BaseUpdateAppcompatCache
 ! FUNCTION: Beep
 ! FUNCTION: BeginUpdateResourceA
-FUNCTION: HANDLE BeginUpdateResource ( LPCTSTR pFileName, BOOL bDeleteExistingResources ) ;
+FUNCTION: HANDLE BeginUpdateResourceW ( LPCTSTR pFileName, BOOL bDeleteExistingResources ) ;
 ALIAS: BeginUpdateResource BeginUpdateResourceW
 ! FUNCTION: BindIoCompletionCallback
 ! FUNCTION: BuildCommDCBA

From b1160f6b36aac54d743d5a7cd76906aa74804132 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 15 Feb 2010 11:49:03 -0800
Subject: [PATCH 023/250] tools.deploy.windows: embed icon.ico from deployed
 vocab dir into deployed exe

---
 basis/tools/deploy/windows/windows.factor | 24 ++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/basis/tools/deploy/windows/windows.factor b/basis/tools/deploy/windows/windows.factor
index 4dad875128..9df13a9cdd 100644
--- a/basis/tools/deploy/windows/windows.factor
+++ b/basis/tools/deploy/windows/windows.factor
@@ -1,11 +1,15 @@
 ! Copyright (C) 2007, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: io io.files io.pathnames io.directories io.encodings.ascii kernel namespaces
+USING: io io.encodings.binary io.files io.pathnames io.directories
+io.encodings.ascii kernel namespaces
 sequences locals system splitting tools.deploy.backend
 tools.deploy.config tools.deploy.config.editor assocs hashtables
-prettyprint combinators windows.shell32 windows.user32 ;
+prettyprint combinators windows.kernel32 windows.shell32 windows.user32
+alien.c-types vocabs.metadata vocabs.loader ;
 IN: tools.deploy.windows
 
+CONSTANT: app-icon-resource-id "APPICON"
+
 : copy-dll ( bundle-name -- )
     "resource:factor.dll" swap copy-file-into ;
 
@@ -18,12 +22,26 @@ IN: tools.deploy.windows
     dup copy-dll
     deploy-ui? get ".exe" ".com" ? copy-vm ;
 
+:: (embed-ico) ( vm ico-bytes -- )
+    vm 0 BeginUpdateResource :> hUpdate
+    hUpdate [
+        hUpdate RT_ICON app-icon-resource-id 0 ico-bytes dup byte-length
+        UpdateResource drop
+        hUpdate 0 EndUpdateResource drop
+    ] when ;
+
+: embed-ico ( vm vocab -- )
+    dup vocab-windows-icon-path vocab-append-path dup exists?
+    [ binary file-contents (embed-ico) ]
+    [ 2drop ] if ;
+
 M: winnt deploy*
     "resource:" [
         dup deploy-config [
             deploy-name get
             {
-                [ create-exe-dir ]
+                [ create-exe-dir dup ]
+                [ drop embed-ico ]
                 [ image-name ]
                 [ drop namespace make-deploy-image ]
                 [ nip "" copy-resources ]

From 4ebfd1ef3a84e9788a85d4b4386c2b6b0fb83305 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 15 Feb 2010 14:04:11 -0800
Subject: [PATCH 024/250] you have to parse the .ico file yourself and update
 individual RT_ICON and RT_GROUP_ICON resources. lame

---
 basis/tools/deploy/windows/ico/ico.factor | 72 +++++++++++++++++++++++
 basis/tools/deploy/windows/windows.factor | 12 +---
 2 files changed, 74 insertions(+), 10 deletions(-)
 create mode 100755 basis/tools/deploy/windows/ico/ico.factor
 mode change 100644 => 100755 basis/tools/deploy/windows/windows.factor

diff --git a/basis/tools/deploy/windows/ico/ico.factor b/basis/tools/deploy/windows/ico/ico.factor
new file mode 100755
index 0000000000..8ea7af348d
--- /dev/null
+++ b/basis/tools/deploy/windows/ico/ico.factor
@@ -0,0 +1,72 @@
+USING: accessors alien alien.c-types arrays classes.struct combinators
+io.backend kernel locals math sequences specialized-arrays
+tools.deploy.windows windows.kernel32 windows.types ;
+IN: tools.deploy.windows.ico
+
+<PRIVATE
+
+STRUCT: ico-header
+    { Reserved WORD }
+    { Type WORD }
+    { ImageCount WORD } ;
+
+STRUCT: ico-directory-entry
+    { Width        BYTE  }
+    { Height       BYTE  }
+    { Colors       BYTE  }
+    { Reserved     BYTE  }
+    { Planes       WORD  }
+    { BitsPerPixel WORD  }
+    { ImageSize    DWORD }
+    { ImageOffset  DWORD } ;
+SPECIALIZED-ARRAY: ico-directory-entry
+
+STRUCT: group-directory-entry
+    { Width        BYTE  }
+    { Height       BYTE  }
+    { Colors       BYTE  }
+    { Reserved     BYTE  }
+    { Planes       WORD  }
+    { BitsPerPixel WORD  }
+    { ImageSize    DWORD }
+    { ImageResourceID WORD } ;
+
+: ico>group-directory-entry ( ico i -- group )
+    [ {
+        [ Width>> ] [ Height>> ] [ Colors>> ] [ Reserved>> ]
+        [ Planes>> ] [ BitsPerPixel>> ] [ ImageSize>> ]
+    } cleave ] [ 1 + ] bi* group-directory-entry <struct-boa> >c-ptr ; inline
+
+: ico-icon ( directory-entry bytes -- subbytes )
+    [ [ ImageOffset>> dup ] [ ImageSize>> + ] bi ] dip subseq ; inline
+
+:: ico-group-and-icons ( bytes -- group-bytes icon-bytes )
+    bytes ico-header memory>struct :> header
+
+    ico-header heap-size bytes <displaced-alien> 
+    header ImageCount>> <direct-ico-directory-entry-array> :> directory
+
+    directory dup length iota [ ico>group-directory-entry ] { } 2map-as
+        :> group-directory
+    directory [ bytes ico-icon ] { } map-as :> icon-bytes
+
+    header clone >c-ptr group-directory concat append
+    icon-bytes ; inline
+
+PRIVATE>
+
+:: embed-icon-resource ( exe ico-bytes id -- )
+    exe normalize-path 1 BeginUpdateResource :> hUpdate
+    hUpdate [
+        ico-bytes ico-group-and-icons :> ( group icons )
+        hUpdate RT_GROUP_ICON id 0 group dup byte-length
+        UpdateResource drop
+
+        icons [| icon i |
+            hUpdate RT_ICON i 1 + MAKEINTRESOURCE 0 icon dup byte-length
+            UpdateResource drop
+        ] each-index
+
+        hUpdate 0 EndUpdateResource drop
+    ] when ;
+
diff --git a/basis/tools/deploy/windows/windows.factor b/basis/tools/deploy/windows/windows.factor
old mode 100644
new mode 100755
index 9df13a9cdd..9f0b22847b
--- a/basis/tools/deploy/windows/windows.factor
+++ b/basis/tools/deploy/windows/windows.factor
@@ -5,7 +5,7 @@ io.encodings.ascii kernel namespaces
 sequences locals system splitting tools.deploy.backend
 tools.deploy.config tools.deploy.config.editor assocs hashtables
 prettyprint combinators windows.kernel32 windows.shell32 windows.user32
-alien.c-types vocabs.metadata vocabs.loader ;
+alien.c-types vocabs.metadata vocabs.loader tools.deploy.windows.ico ;
 IN: tools.deploy.windows
 
 CONSTANT: app-icon-resource-id "APPICON"
@@ -22,17 +22,9 @@ CONSTANT: app-icon-resource-id "APPICON"
     dup copy-dll
     deploy-ui? get ".exe" ".com" ? copy-vm ;
 
-:: (embed-ico) ( vm ico-bytes -- )
-    vm 0 BeginUpdateResource :> hUpdate
-    hUpdate [
-        hUpdate RT_ICON app-icon-resource-id 0 ico-bytes dup byte-length
-        UpdateResource drop
-        hUpdate 0 EndUpdateResource drop
-    ] when ;
-
 : embed-ico ( vm vocab -- )
     dup vocab-windows-icon-path vocab-append-path dup exists?
-    [ binary file-contents (embed-ico) ]
+    [ binary file-contents app-icon-resource-id embed-icon-resource ]
     [ 2drop ] if ;
 
 M: winnt deploy*

From bd2b72ad08348337e4d04f830f7d09c2abea1f21 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 15 Feb 2010 14:18:26 -0800
Subject: [PATCH 025/250] update vocabs and tools.deploy docs to mention icon
 files

---
 basis/tools/deploy/deploy-docs.factor | 4 +++-
 core/vocabs/loader/loader-docs.factor | 2 ++
 2 files changed, 5 insertions(+), 1 deletion(-)
 mode change 100644 => 100755 basis/tools/deploy/deploy-docs.factor
 mode change 100644 => 100755 core/vocabs/loader/loader-docs.factor

diff --git a/basis/tools/deploy/deploy-docs.factor b/basis/tools/deploy/deploy-docs.factor
old mode 100644
new mode 100755
index 2cbb2869de..a552bd04fb
--- a/basis/tools/deploy/deploy-docs.factor
+++ b/basis/tools/deploy/deploy-docs.factor
@@ -11,7 +11,9 @@ ARTICLE: "prepare-deploy" "Preparing to deploy an application"
 } ;
 
 ARTICLE: "deploy-resources" "Deployed resource files"
-"To include additional files in your deployed application, specify their names in a vocabulary's " { $snippet "resources.txt" } " file. The " { $snippet "resources.txt" } " file contains one glob pattern per line. These patterns are expanded relative to the vocabulary directory; files outside of the vocabulary directory cannot be referenced. If a file inside the vocabulary directory matches any of these patterns, it will be included in deployed applications that reference the vocabulary. If a subdirectory matches, its contents will be included recursively." ;
+"To include additional files in your deployed application, specify their names in a vocabulary's " { $snippet "resources.txt" } " file. The " { $snippet "resources.txt" } " file contains one glob pattern per line. These patterns are expanded relative to the vocabulary directory; files outside of the vocabulary directory cannot be referenced. If a file inside the vocabulary directory matches any of these patterns, it will be included in deployed applications that reference the vocabulary. If a subdirectory matches, its contents will be included recursively."
+$nl
+"If the deployed vocabulary includes an icon file for the current platform (" { $snippet "icon.ico" } " on Windows, or " { $snippet "icon.icns" } " on MacOS X), it will be embedded in the deployed application as its GUI icon." ;
 
 ARTICLE: "tools.deploy.usage" "Deploy tool usage"
 "Once the necessary deployment flags have been set, the application can be deployed:"
diff --git a/core/vocabs/loader/loader-docs.factor b/core/vocabs/loader/loader-docs.factor
old mode 100644
new mode 100755
index 7db3cdd5c2..ce4a319a42
--- a/core/vocabs/loader/loader-docs.factor
+++ b/core/vocabs/loader/loader-docs.factor
@@ -52,6 +52,8 @@ $nl
     { { $snippet "foo/bar/summary.txt" } " - a one-line description." }
     { { $snippet "foo/bar/tags.txt" } " - a whitespace-separated list of tags which classify the vocabulary. Consult " { $link "vocab-tags" } " for a list of existing tags you can reuse." }
 }
+"An icon file representing the vocabulary can also be provided. A file named " { $snippet "icon.ico" } " will be used as the application icon when the application is deployed on Windows. A file named " { $snippet "icon.icns" } " will be used when the application is deployed on MacOS X."
+$nl
 "The " { $link POSTPONE: USE: } " and " { $link POSTPONE: USING: } " words load vocabularies which have not been loaded yet, as needed."
 $nl
 "Vocabularies can also be loaded at run time, without altering the vocabulary search path. This is done by calling a word which loads a vocabulary if it is not in the image, doing nothing if it is:"

From f37fcf7eb73f004fdcef8f35dd6248748855200f Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 15 Feb 2010 14:29:36 -0800
Subject: [PATCH 026/250] add icons for gpu.demos.raytrace

---
 extra/gpu/demos/raytrace/icon.icns | Bin 0 -> 44630 bytes
 extra/gpu/demos/raytrace/icon.ico  | Bin 0 -> 9854 bytes
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 extra/gpu/demos/raytrace/icon.icns
 create mode 100644 extra/gpu/demos/raytrace/icon.ico

diff --git a/extra/gpu/demos/raytrace/icon.icns b/extra/gpu/demos/raytrace/icon.icns
new file mode 100644
index 0000000000000000000000000000000000000000..38288036baa024af238df95e765878622f7e625e
GIT binary patch
literal 44630
zcmbrm2bdI9+BV!h)3G|o>aMD;>aNadx+l+&1q2ZjuBaF>V-^Dv<y3c1B<CPeT@cU(
z1SP2;x+D{>sB79))YaFt>aH8~d$+#(^uVsZ@9uY9|Mjag&P><2pLo(!_c=FTcgH;%
z&95%L`QF9`jpmLK8vJuWHEV`kc*#xI-*oMmvEQi9QRD7hu>ZFw)&Ks-U*0~k@qzK0
z&sE*nTNc0ew;r|jn<wua@(0yA_PVtn{rJP*{{F*%|Mx%sK~&>E{_)@cQ2+YUJs+#q
z%R1lu?(46={qy&K`P<+BUi!iG_rL$``|tnu)yAtnQ0+smd-UWdAAkD!mw)``+duvJ
z&!z9pfBy5IzWw8uUw-@2<lm|GbMJZf-FM#q;Nwp|{rrnBzxs;&QTxp|<d3GWzWm~|
zPe1<T-3Q)N9XH;+@3q(7`0cyze{k~SPyX=fr{pv8x#hFZKK;WdAAk74d+#16@2Jrs
z_dI#{@Jq)}y!qRA-h2P|AAET7<4-^R<l~P|p8W8`58i+8owrWBeoT2=jZN6_%>EY+
zzxc}W-<){!Ej;@1cmMt4cc1+Jz4zXI_nqIq^~P_GzjSQhoo}hG3G;V6wfEWQe|`Aa
zORpS%?Kdah`BqV#-@W(Nn{S*r@tfnXzI5#H^9MKHd|YLRTzSbkLmIEzvSs^Id!E^U
z@P$K%j~;vRl{e|*fBx<9S6_YQl^2g4J@mrCXZGx_yrkCOe))NANx`bqI65EMxMkap
zr}jMk?EVAKzwqlr$A0_m|M@?Ee)pB5M-Lx9^y?Q69(eZY-A_KT{*EK6Zv42xDPKjC
z8n@=b^&2-ow(W^0ckSN$^fPGq!m-zW^Wv|cKX~xKf&I@u^YotGPd%}9^M=k}BX*Y$
zj5`#KqW5dW^1@{gu6uanrpJD@ZTpTVpW3y1&z`+|m8YG1_wL!Vd-tv<cWmGK*rrF;
zExhxfT6^mSId550(t9<-XU$r$bmgjb4{g}EY0G23+PZD~6HkyG+9#h>cG#ZSzHQsD
z9^3rrhKJU!Ts-N3YPs<&S*OwH_4sB`^d1c}q0}*J-lC-|9$d5Tp+`1se00-hvZeBv
zW6PG!n;zY`;o<dbA6&j@-psq6QEP4=8762&^co$3zCKOz?kS|wJ!k&HCCkx#?Yi|3
zJ^aWcog3_rJp9o5b!%6xT)uSSobCti-G`=QV?<M<*P*diht>qv4!Y}}DG!u7x@XS?
zz|v(aR<3+-)tWWswaztbR;_w)<%(rX7cH1OtFtuaj=ie+sye$yZ-ClRTBB1mLA_pc
z&ds;qbN_Tws&w|wnlo?yf`yBgELpa6xw6c)eEHI)OBO9!Fn{ix-p&e{e$QRIRm-Gd
z0gXmytb&xN8j8kmKmVGWZku@T<Y^C3n6BPgv**m6J8xcPzH{EZxpQXE>h0<%lLw~U
zd)sZ~Db;ji&Okk9tXg3x>p2~~$X{^T_#1Ayed0ZnCQq9&la$Jpj?T`mu1dGFtE;o4
zQZA7Prca)9_w6^_IAy2GkTC*WcnYLOr!!Ra0iA|B`=ZOPzV4=5Zolj9dnZkvGHu2K
zGYL@?v{me6<^waPO}YQRyYIa9rtw!!+Mycm9_ZHSsS-6t1KdGT%6e848h*|%F1_OF
z>u#KI>+N^kb@x5@PMUQ8<SA3i)7(?0OrCuIr2Fofc<1f6PPl&jWg|!5zFoE7R<J=6
zKvcB>5YcH3Kn-Z3gU%d%!9|x|an&`~-Eh;*x88R99e3U}apK)~EBBDQT@&xR^N!nZ
zyJf<S*Nwm8(u)SThupPQHD8}JYJi0Qh`v^5G(sU7X9KH|S_Tgvb?%t4mt1zm)#I<d
z{)QVTOt|HiTW>Aj=DqdSTW+~|!i_gvcg@vTj2nBw=r)a~b<*Ri<?0xtp-5CUqSsM0
zz!9Ba<14fd96DmuxffhG_L6azUvbsd<FC2)y6edG<Ocus*I#$twbzWl`pPTDU2@Tw
zb4LxY*J#{LleVa~Yh(th0Ypy$l~aHfILw<Ww)7tiz|rTPKjs%>FTP~lWtUxk#TDf%
z{a0LZ`Q_s-y=3e~W6nQk)QB?%q%=m2yLi_o)p3n%)|jerr}5Akj0CuTjVqC=Yi#X5
z_>AErMxA}mx#wLl=E7fGbP*X#E)I+xd(lO|xNyw*=bkg_tTTrWYHyUF6Cm%{sMcN=
zXEel!enoB8_gPy4B&*lQlc`*NQ)|D0gU=Xt=7_UKjXHbuIp>~RJ}+?Yx#x^Nd(^0r
zXAT=Os9$S+#!pRz!T0`BHBU&pG)AKdK*Xr4LMrf|MprWWHIY;@na&j(np@ik3>rM-
zjG@EMJafc|^2p$b5oZn`Hgw3~f&JTB8tT#sn;y|LYS{i$9!Ae8`ZVS~NMKfzL}OHt
zy40B(KBXjW>1@6psIBe&`VSa1sB3Uw(7*xx+gn>2>+_jZDpHMr$)MqfO<S+pW()}G
zj1-V62}EMh>h+|GSfjBg%1I`b&gKgB^^Hx<Eu^*7rnClHni}hib-6SQNCh=iIg?S(
zgvU%=s~UPoi$F6IqrMMO0U`lliS`bSoa#)PQ|U}DS65dk7R&XfVzE${%R#SF(iXSs
zD3-x!(zui3*Qh3PWx@q(%_hVIUqFIl=p4qfL8}SOPAVyquFYi9X$82oDS-x#iZvNE
zfyUbu)uicO^zhyT2eyx$ubOYG59sNq|3WKO(G(;6t2e|_>j4pGfKFvOkXcOVjH#+R
z=fT~_-#hs+`AGZLujXLX7%Eu}0D+N;QEM_$14~u&kS}IE515)1PqPRptjP>xJjsj5
ztcRaD^6H7VG0UDj`N1oiUe!AB;<R5+jiV|7%7Aak4%h}KFgClGTAMVcqUe8c2{8s}
zkbvKG>)OY6?LYj|Yp=iY*4uBtdE)5Y9@TbRt3Z+Z)B;Y8fhwk8h^!dR2K-`i*qB&q
zb<&VZxHa&CV&tf5W+ZBC#QaTLcRh3P@QL?MVCp?~XdmfPo#hcppT<-*lbT93q@ZP3
zTE_2Ir&;ez0Z@mhOa{fsn*m25jlsf=>wo#!_Fd1u|LMEGe&PB3`<{BZOSN9tB-kL2
z>PQ1%Hkhr|u4^(?07(F8v%^4t>cONAfi%IVA;49en04;x(5}_%Hf;XY-b2ss+V#}V
zZJXE4?ofS|p((%SwAoZwo829>qQjaxj5cbv*~S=*jM<+~Edwk~kdje?7FAqoKEoHT
znYU>9n)MI=a^t4Wn>IeOc1ce~b&;!@C8r*mQiahy%ywd{;Uq(ajt$V*Vm4dwSB5cr
z;;AJ`T{`a6=oO=`3QbHd>RPi&<BJcQ)J13X<txd9`V~tT_Rb(>_;y$}07v!t0{8&e
zTRrtw1Js6waF32*AeJz-CWo9}nAE4zl2ykLV+~9qMiJjnd)p~Cjhiw<>FDmAJqMFy
zcX`I`(@Lt7T-hE)c2)JKHdqy#(dtPv)cai!qL_3>xW=q7Ix`bYrROHCsdUVTfxgc-
zh|p;v2$$I%%$|AOo%h^7W%`VnGiOYndf%N_-Ct4zGtO)XxeS1$BGABQwc2b}9}id5
z;!lu7%r%fwW@^oLK0#7lNs`jVd}ci&uBAB@sY;=lL**GYzG(knTyy<|TW-7K&O7h8
z?Uoy_zF=xebzD0z8?;c>t6wIIVl~*TerI2jo6!m3H~6K(Ko=`3B~l$}Ln<!1A*W>2
zz;DD9t_Hp8H{j^pV#C=Nj=l8qtFF5G>Z`82?Ber>5k+Onqx;2K+8?RSH728_WYyU{
z_?4J2R+tr2Euw<(bir$8n>$eE^nRxm9jszB(A)=nwcneAeR*rNbGcz>ojK~9^UuHF
zg7eQidqn?1H)4%@>yXB<?^O5!ZiGELo5O6Vil|VZRi$XmJ&eX&F~OA#(}fSUMi?UW
zg}$0$OdvVntTs$ZgNF<mJg8rD;$lTLld%Kp1UD3f4SE_DvyA|sfqED|%_ZtAcz!Xk
zyNtCA@{iz2zN$S{+h}CvmQhWaTmd6=A(xg@bKsiNS^YD-M~@K!4_l~<7@N&PpC<rQ
zsG8_h_)%kC#B?LLRa6iC8&#No8U0ejh=F0b6s?sb!qp|Lo`$w3gATODSZS`Mj;BK^
zepdigHtVWGW68LX(U_``c(4j<KLx7ygzAQjkRxTehC5%QsK&Jy4{DAFY$o^$y5JkI
zh)H8C!R!(c%f|UIy9a;m)7I=bt)9*+<ochT4=ZwQBy|2lBwg?DL5<OXohAeRGtsc%
zJH<mBO6D@gLPW<n7l6IS8W;#iAVjdlQ;ojP!>8NN8XT78Fdw^ib6K@a9z3{S4%jdt
z(b!a#gPJ8EB6k6(HJWK`W-+sk)EW4sY6YTYw(326s%`kFC?C#_DRrpkYlieMMgk6_
zi7B7bi)vSf=b&9D8X~v|FqE5vQKOpAG(1$nl9{1sEkj3+x_(k;r)pnu!Qg%cIp8*!
zO?|3SD5_QkZlgIv0eXxW4>91G=hK-DDN51k_cAiZ2e=_aZ|hO5vqlVUFUo=HsKAhF
zU{9lIj2$o%9p7Yr2ty@J4OmDWMgh^e{X(i~(6Eb1w`!U+cu0FO7WBgFT2mDVA%j*>
zOF=xls!;$;r7w_u5RA!WWrbApz+s~w1jfyS2DcYtoR5JN=BF5yDn>V&V+=ymYEDrd
ztPFawofR`JgNB{i)2*6+F?evlVuJVEs<8k@H6S#js3{tVUym+yD)tn?1_ZOg9SCPz
z2Ms@CS{L1A3>?&6p9--qM5o5YFf`k#a}lSmzMunx4jv_ZfB-Sn8G3I}&bJL3HsoeN
z%*D#Gy)h#NJP-?a&<9UNdKMI@oNlL>8Kce5#R{#1h7P$5lkVKXg9o-Z=H#FcNmrqH
zLVbZL_a|wx7V$W3SPjEK3&!YXL&;*>pfd&o#5Q-(;DP;`@(F=;W5(;CVPF75v!jeo
zRl}G~Yx;)!lDP&UsF*E`FAz>Qv=2JtjFEGZU-z~R8qlw$kdgvE8*-?#526f+PK+DK
z`ZY#aO<Oaj4ztzZ_H)r(bHBl73?06>Q?*WQ9XPOmOMOP>{B8rn#dP%nRH!MlVEk%0
zk9JZtH+3P1K2}T=n)_o-J$ydePir19pkHfaJ|VI`JAC)A2r$qE<Dq#K4I)y+)NQsI
zU4Bl^)YHAgkfCVqxW9Q2R^m;Cw9Nax5P~FNm~JRfm>#JAV4v;XW+!7d+NkJ!Q`>;S
zLk6FL#?C2Cklo%=pG&}ax4s&EW)>PNXpD}q5}m0RDiO1t@%ec<U2LH{j6r8C=~T5-
z8c2UzduwAM6BSsWldd<AJj@*EtRN5?W;yNJa0fNXVe<F`QZkQS59WhGg8|^3T;IQc
zzkY4a_4#Ck^LuTW3@8NjpAXFmq%Jdd(_a;{)8O(2La}VIxqSfI4;VxhxUZ=6bGEfK
z7PE0F=%elX00^@TA;51-=)i|u1VjmrH#(^ebm!G?02x%%kAl>YLL2F4ZEtOAs7uAf
z0EMALDT9Fv&7eGD2s6x!(LeBqve^qqI(;k`N#^RCF}n>IJa9liB!XvEb4z=_e(hAD
zTq+t0_&nC?;KU%e39|_KV>U0uU#cjC@tUYUTsV;{VBdzl(7^ufLkQfmxS^@7UweC7
zYcqfnGJw2J3@qrsRiMQf;;M6Q#T-CNVV&oJS>br5(Ad(}zyH8N{RcLk*QM$fH8-@j
zk#<LGOLIeAHd)2N%CFiz2@E65Jo8*S#30i#gAudOX!F7@Al1=bUw>@N`VVM08&H~I
zbuF!=-PJ~SX~2q#LBH371v3<)YW0|V5u;u@z5_`yV_)I)`B)*608|s81`OywU|?I}
z%5Ie#k!!-<udTfm=2fvIp7nWMSaH*wF_jQI4b}j)$Q*MCXk~N2WP^o)Dq4M0OIttc
ztO4yU`CGeHaeS(wxea(w4S0oYDjpW#Fb_6Jw8v4%4y2Qo!I(m-fE{Me$hcuCFGW+?
zy85Q(wzhu#(TA}It()Gh3b!U38(Ld{+1iJhODANJD(SJC5k5_|cg<&N0AB`tx7lT6
zoX{{RL}IC2p`p2@t)28YA{AO&S{mj+$*x49p|P#4g=z^k8;bc%G8z_wexKLvU=UlR
z#2j<4X^z=X7d%#=Rn<$T^95Mk+Sac0GqeM**ne!d8d+M*G&CUCt*uqFn;MFB*;FDb
z2>}3loK`x~5@s!e;Wrx%X1mMl^96V@5{J3i(8GhIziGe#q-|Ss=ImZIIy_!zY-$7=
zM8Rh4p9|RY#$_N<v)vA>868n!=Hjbtj?vwa%i~2%I584SV*lNM-8ZyEWbkiWYg2uE
zLa&+}AITM)urY6IYj0_(;zCoHPJuZJ3}hQ7*0p91%L&Hr1g4J-@De~X`MUbXM)a?K
zrFIh(Yi_E~$2xk|TyH#`D>OH^G__E70u}zG+x-kY5D|GOOf`04Ly1XiF@~}%HbZu&
z+v7#Z1Dqhqae(KG4ajlmj9lv9AAJ`1g;Xo)Rm}^FF<PN$ZE7LS!B%(~pY>G~GU-H2
z4u|+43qKQ&nM$#t3mT2R=mfQPo6}7^iK-1;NQy)gsca4ohsV(|k@Bc`^dHdL-qcjA
zlgG?fZNHGRSp>MXxvizWrB!JOG{g1On0z*!qM}5Bqq2P7l1JlKTxGk)p}6pqM}!bR
zwT6m`Cs9%<Ku!y~8v53Ne*H+BxgQdk4j_?xW~=tDP%@h>6dKSOTiRROl{T)mPgZ>)
zpF^c25syY7jpu>^*01<_yo#^R&q4q%h>#FVq%zrj9m*^XO-*erE&ckV%Rmfue`{lN
zeIc29WVY(uoR>1$LiI63y}6~i(!w`4HB>FiXS1nfA|8_?VMz=LJVXUM0{F&32FwUY
z<Y+vRMC~PCwWX<%wD{Vg>j3m^d}~Kl2S|1K@cDC9{<1(KlP}aY*4H;THp73d7%maR
zW=L%$4UQsQn9pX?kO<47GKr9INz#VHB;t~zu~;0Hp$sg7q+)#oY2s*@s~G+Jx1kGQ
zK5ecq7W28JIBTxzS|x;&sXF8%QU=M4eo|^N<Nr+%hmJ^!=0Y)FmxIJinxr(zjs!_+
zQz??sWJ%5lzfm!bq$$)&Qx5$DQfM~d7YJ@F77%Z#mCRE;BLZ?fmCF_zijB?aQ;qOp
zD`^Y1(%#kFgn=B1h~id#0bYiQxg5zFbGd9bm&K2HZC#!eQpE-++6Y&)Ak;9Xtsl*D
zn1^~D@~fq#o)+3->}~VaOgAe=<LQ3|t*P3ig^pm5*+x4VkQ$mA;H7$f5t55VQmDbk
zixf$H4#s2LfG7-Wt<4zjFlItrD`qeB_x5(QY%12*V<-`m>*uRQ(i8~8K%^_uz5%l*
z%x^*KK56YRwyn7tZf$8qk84Eckj7ew!2h)LXH64nR$8KHgbst$=nr8q5!u+>Ood@|
zDPZbN$^NSss?9S3Vpyg%%tF2ZxTaP*6wzTF=FxAhNMu+Ekr<QVXncsDO3m6P2=O2?
z@Ex555T`yd?Mkb*xtTOso12k`#kzDV%EwkLR2w%p2gBi5I+aGGF=(NeKxx|j;LfTa
zsbv@f+aL-i1Gl-QyH(RhT0^jeg5xnNr-iPDnp^s{VH7|H=1ESUOeG}$)r(cD!lREQ
zQYm!xTwW<^8c2)KM3t_>!Ql{r@f)i-Y90PcT5H<cQ4h`0VUk7#{(_J;_>1a-0RW>8
zx)l73&Y4D63G?ywOVpOL*l;)!PbN}%q*cC%k);KzBTQh_qN)^XR@IX<Pw)d3jP*f|
z&L7njpi#jm)W395gudH^94ergT9?Pjh6x~W^-|ToJS2oe;dm^T$RG*xq(O`HY6vto
zR=YCX1@j=Z&nk!^Ew$)2ZKNfKc>$iIE`$GQzQS>kMh6?@BOTQ0^67X~mL<M{EK>v5
zvlw;4Q5hpyI+LlZZz!TuHX!gyqlcywMov1=0|xeB4kImkm;#TH7B~I~OE9k?GISVf
z#28cWLP}wr&gOF&I(CLcuC!duZmtVTAv%~v<C!dmvI53e3><V=f&*z=>cFa5?MgF5
zAkA8oRtH2O@c0ZJ6q$-K%-@JMw3E<L1>uRy5iukN$E;LqW&{K!<i&uAo|}W;a&&~L
zN1TdHq{T}kh1rp+3ANFk=s=@1W%>++&)TaZsH-5cp@2~YHl$N2Ov@1{&letgP?g8|
zM3EX2mZ`&1_{yUrW0a#A4$ZJCA+07l_#y)^RyS!{m9{jHfr_9*IM#Pf7%%!HU>?L^
ziqSuc`7<O6rBy1sc>oI;VmJ~(R4@f4Q|PKNg5;SxI>OPRxv7cN>tIk*qtZ}nRT_8*
zfEpN05kTY;it}&}9eFWbDiIxZ5i0YB6>%;sh9na4NMRY{J-|`a&sX0RG!#jl4rVme
zD@APsCV5R$xn9$#pyOj~BSj_eN8swR=``G)s!muDI7SQ%S*J#(VHqk>o$(FGNq8m&
z#gS4_iu$KPX*A&ns&i9AxuAh-qBQgI7mT~mfsWf*3`=ym62|08p}Fis>($!Z`4HwQ
zcl9q)I0l_De_^IdXGxtNgFI#{Qm?5ac~aL=(AMFHn!5UWQsnBgS-3ZcHDD|jrOO7a
z3V<zgk@XL&?kju}6%?lVgAb@PNZgp9E=i@+BvXsvU>;F&nqsM5TgWL{LnaH~W-}yZ
zL>8ywu_%1YVBQW($OwTi;nmT3Y?z9WBvA=j!%?8du}r}Hog%b|ikC9ktdh~@3Q8R?
zNv518NegD<L=tFN1ca4{30)Ej3EYg0s_FaywL2t=MAFi44164gk}y9-617<3U@p~V
zk*VoYrUqlJlBvli6C_Sz#&`_oN}{AhG!hBvD5SDUHH`^K)VU#1iD<(j3EAKTI{5<?
zLr|)ct|V&Wi44J<txsT;5RH<UHX0_P2I~Yfycj}w1g^A2HC^Zn^+A;)=Bk$XNXFwt
zHb!AK)Qoq;G;x@ofHpGL7}RB25msu#il_@m1hMqEs=G`Sum}+~QYlgc>xpQjGN>OF
z$kaxo9WsL$QV+q^ayep@@L2@E0VE;|+>KjR9T9j5zZ=3bx=utYi#0Hwgvw$q1~|0Q
z&_6->63oVPHBwk2q8=!L2E5EQ-&J7Y2;f4Z9@RhmQhl-vyE`IUIou`IQh!!N2L8ii
zayZaNcA(BP*k4U71YVJ9salnY0Vx4j;3ustb&6U^>VS15VvzAcC_H8t!Vuwr0mKSE
zp#o%tI2^9fU?I>tOg1vr81_OTc!kT|xJT99+Q<piebA#8>5R{yS|=K4!Y~oPQpeUn
z2?&EVyf{env}!(At_p)&Do_R%YNQ_gAa`KlhY^%6Gb7Zwq9D{=zF*akZ-;gfBEwT1
zBDCri%T)~{_AsFFEKRHsmpcD>l^N3}^K`U=X$l2bB5*w9zz$gt`|yh*T2N4>Z3I4c
zj^>bRAJ-;BYIVS%fC^-hhyn+8iRLi$z*0CfXw)%PH=-#c(ilR;NSBN}EW;@#8YoPX
z>7mC}-SAwDKB23^m1Rx18@?bBoggL}N1ad&*#WsI1ee5;R0D~nur+c@T`>}^AM}pO
zXqsE{aS@XhO+8ppmd#RCy?DN<@uX@HS_(-iBXo)eDa|#6S~X9plvCuZOAKfoP?ySr
zQxt2yVCoakzw)Q={`C2C2YbeZ!70+WpFeHi*MIN&LHGBMmz+&mMZVPZcmML2Z@&A}
z_uv2ZujFsWzy9_6zy0v-fni`31uuW`o6kP|{Hw43_|13UmHuS<?z?Zk{`yZJlNPXw
zG|A52fB61~AAR!Ke|`SNS6`LBHh=Zi7oUIj$)|rjcokShjaTk|`;9l>e*bqLegtL_
z7(?3s`Y-aC36!9dX!YhOu!_#TX#2}AzWN)ydVKHw-~Il>56MaLkp+CA-~aCYci(>V
zt;3gsRiwFi>+=T>9eersZ(avo=<Rpkd;h}^fA{|TlrHr4TW`Mp+RHB=xgD$`aml{D
z&mR2skz+5t46@McZ@&NK_kaHKcfWn}%{Sh7{Wq_@`qHsOhjtEpOHI_>yJOpvyQ?&z
zBgbBR>E+iy|KZ0UfB5pv*N(sX^2;yv@r0gTHvqIE4a;%S<k-y{9^1Ba*WRa}eeNJQ
zLPw5&uKeiy>Nm%Z9zAjd?<1dk_UT<acV7%z(Wn^DN8>pxX)Eg<+OXwU+jc&+d+$Cl
zgr0lhH=lq1{a0@sc^)L8=k`DQ^uFCs?b!OOWpzi?CMU<oGkMHE_4Re*RxDff&@VS`
zd3@^=Rff>seb2t|;!D5Y|IE`*@7uR`H{Mh3*!KA5Up_MB*D7AO^WjvXP_FkE8)wc1
zw`k2nkDQ_iJ+WiwP7s8iaz6Rw&Ye4UJh2rdp^cBMTQ&ErgQ|g#hZ5Kp5=<T5x{+O7
za~3RJ{^08MlpeHc^OnaRf1LbEyLGGbE8F9bZP~JE<1Zgxzk21;rR@h)y`K%Ii}hu^
zWOv>0fP&YM3zjTf@!;wzGw7FOLuI35!-ii{deE9xE0-;rH+Mq#8C4exg|kJaP%0|*
zzGCy8lctl79*}|-p(!XqtJkbs*SX%lZp~_tf|gTGP*3H)Vf$3$<pbmlT`!PA8B?gg
zFy!{TCQW^y`c`r-$UsY$E?u^K#ftJu=ZY1}moHnoWZ{B&b9%c<4@}MMRckWgXc;Xl
z#USSO(Kp_5*S(Xcg9Fsr)k7&j^XAWAxL}d8&;<_Bg8B32&6(ZX(^(?ZC*OPiZdHGt
z5W>o*RHqa=ivGg6S6zSe9TV@ne=2QX?(FLB>Fu30t1{a;YgTVhcUNawnK^yxq=~m&
zKmIATc9fLF3}3D*L1%y6d6!&y?M=7bao0Wf-9Kg8bZ~x@QmG97kh5GaDd7D~pE~)z
zd+xmDx~s0*sp@ZO3S{!w4_45)gvMuGc*zyxuLo!7&WZQjH|hQ<Q>RUzK4V7t0W!lr
zecIG1_fNX_?mKS-+vn`M9coP~5mL~$6KzS+pBsAin6cxo7=PUj6K=Wnc5r*{x#!;d
zCQT~e@18X2zWeUI=kB}k8g#-9*IYSnNKms~#qb@*qL=`n3jl#)dcd$z=Uq5<+~rq+
z(R1U3n{S~MA-p_Q?jm=(Kn}X~mYZ+7;kxlxjvIU704XSKRcpmyJWqh2<h$W@wwP=h
zICSLb^Dn&Ul5tmDc{Nx(H{5X3O%o=RZ}v`@aMMlT1YJA+sw>7_eBpVcTJsV+7L%+T
zjOQ|RL8Ih*>-@z`T}%HV!$*!j?}7_2y7*F%fvyA_Xgs-wT<gE)n(^cDe)WpW#$9~T
zh3AhRF|<CH5AhdnQS~i>7#5ZaKuXYqEu@omP3;4RfUZLsKp^W}e90x3jvH6L%s+12
zrI%hj_M!_fJpbIYM-Cs{FP+Qgd49|$)e!YZvsf9Hsvuo;-a<B>%r~^O4;(yn_=vN>
z&pGe>3&xZ#B)?ED^p3gU{BuX2J#xgbAp=?);#hm-1fhMSsta>5)D$vhV3grfAJ!U~
zLIcW4l;<;i#E6k+f#@^3d`@8W=(9(iHFCt6!_F8ypsl%(j#n4PJTLuHH8gv~zNKC{
zTh3LGj@m+uBwV!k*@)c^EvOGUW7x3a!^>y7hJ)L41||1kSzn(|q1dKig~&$4hgIV^
zHb}PuSbCMSm0Tz44TW;Tft5Ag6VR<+KNJ-QmIt{8qI696e^~sZc$$djvINVl8a67d
z#~LW&OJRwqr8t#r2NbHQ%f>4SD{4#_?C8pw?!#LxboYW?3Tio-l#<ZKposwszZjcn
zUyCG9x?>cF0H!nBiC}B%qTLB_5olqD)RhZZ=EITcWI0h2%RmET8oQiK$XCP$LDS+7
zfghw$HOgq;ozv9KOK6h-tfh~UWOqUvg+!`ms)iM!l&*9C*kQR$qQ7Ros*AHetUgZz
zbi<CCd|m8eh{AH6wjwD{G8J=0qpCV>q{!1Emmmu4997SWo^T?epe;#PGQG(4+B_2M
zAu6!iR7u&f?&a8oFi1oR4oyoTEeBGLQ3wZFtf3*egvK42o~!{|iejCZT$j+qPHC$o
z%?VF1$NE_m*9fl&H9XheqZ(zw6Qzw6G*;4`u$ne*5G~QQiCPpz5h9=_orx6BM!kNN
z|AL$t3-LVRw5+B}H4H-85i4g>)xDhVMjGfbyxGmpwFzxJt5lmS35%QOX?c<j<S$Mt
z!J2^I+oc-M;#^`p7O%E8VC#W(J+$aSA2SrgpsV<ktEvu2ms3j8L3awgJL2;K$j?b!
ziLLQ_xeir#o#gjo&98|o2@{-@l0unwY*b3=E_8Wg!Gof_*`HdOs72pPR{%v4=6GCo
ziM-q6@e*IjUyGu9sDfqm0M5-TF>M@BHK{mV5e+=6oGQbuHMx{c0V%{2OD;+1QZaW5
zP^IePJ|0W>{SgmArMKkOp@QukTUHIXMSbqR{R1^nn*>;GsP6V`N2-JFuyPV(0iMYo
zNi9N#igqKHEv3py_zK03xZsvpr_<%?aM!w=wh<-OsA-klUhD&um@bYj6V{crLhkZR
zH{fb>tl3hcyqG{DH4mCceRzH2?1O_b*bhbBY}8?QI69oQ4!dP!Ni_*^-W8-f93{pe
z0|dI!5{iRL$=;McozD5qmI|W>2L^@Fo`f!$jQXr4MjK97k|jhInEGhU?~VnDt;1ex
zvzmVac7&7=99a1iU}_Vx5~>x2#%v|olfv%I(N*QT_{Dg#Bc)5mLT+n?(XyFxAD$93
zMPor{AZoW*I;^!8#(XX~9KNLNchU7VRa2XY08$8NLCWb))!G@x(ghXq;(_Iqpq}$N
zL2~L~H1-l8NnDAMs6ONjX8h((1kPv%-NKCYcf08(2}+vb=Lq^>NQ{&cz32f|$X*Z-
z@QT+ADvLIfs#JlLs3GiN<8jKEz&j-RR$uQ>Fl2-Rg40ho9<qY1pN1zPtq|(~SWPNv
zU%_ZBos3pUQEf`lhR6n&N60$$dho~eTKoCne>6A9KBrHn+Y(?vrKli;v2%`hCVG+@
zJK|_r3pZiIt5h+}bO+*b3rU}@11#BL$c)SC<3R@(!RAAY-9%IqBZ!U??@pAH+Jqgi
z-z<yp)x~JtNhMx^9t<!d5E~4~%@r_!8{ioO8NhR_ohPSZI%1`GZ=xodaxX*cZl>0q
zjAKVjq7XtNM%nKUNNJa@g!c6WvA@eNNL~l8^tCTVJJB8kX3Dn|&3l*{TMV+5zSfSg
z?6Z4ONYYUfsP#<r7vmUzj`ulu?0V^jNQrjEI^t#Yn?MEa=isXs7}0pS4?~IA!m`)t
z4@Z+0&`9kq9ja+S2CpFP0c^RjdnF+4^u#*j+N6k-u*|A{X>CZO65^mltk@2DoxWfu
zn>xeGcdATxRulqWhnH^Is_o0sSumj{5w&)rF?cD^qSl7e5d|n=!)9<fe1hOUuSd09
z-<+32FbNx9sf5;wT#n8~!a94HvSmJ_wLu#NQkAe-lAI17>y?TijTm`85#oGyH{E)n
zVHpiOqP=M7e~8h#;B2KTiNVI%;qnE&Qe6jVBAG;-=UfhFb;l-^(X1qQ!r|Jugl6s-
zq+_c`Bok+M`r>jZcN-c7li0uo-8N3ahPjNrc1iAzmSY;ndZyMFquccowxA}j-5ZR@
zv(lAasznouMr4k4+Po4(5vhV=Kw0jIYUBR(j5ZjpM9PrDh?0{w5)#t+U8-4#MzDWo
zU3P~OLfJ+^tFA~zu0(5Ml4Tvb11u^-l0g)Co6{#?qb;_9GU5wIMNDmeyFI8tnj&?C
zyRqx7iN-u@8I4VebU+qC0Rrv{vLTeNir|Z|Y#h}?f6!@nivmHrlGGLMg>5xa$+`wU
zlsoX62YYbAZu79H)M4|i=~QiaBg}>c&g-_@f+5sSX~XXD9MoGpXcdT5pdk_M7#qAc
zyUT~#o1BRvO{~|3cogS&=xKF@NVR1dEqfz1vS?YwXssgR4}m0Pg-EBD<HV?lQ4BI~
z@C8vo68x;wZey!$OJZ4?gYapi-c?Mk2law7nkpfK=s{C9fGHypi_*4NaOr3`ByfI@
z%Vy_GkXsTf()@5uBy4|>(ekGnI)qTr?r?k22_o@uqT2LEyuS~jL>KUT99DM)3x|@}
z0kPT$zmm~9VJON2At%-%cBG3>Kv6uL7EoAGomY7vG$aW^zyqCqDDw$rlpDHXur}gb
z&eU4@FiH|77~=@JtWI|zAPOiCi7Cm~sk*OZVXg$VL#)SPv$J@`R|Y^uoQ+)9IF~V6
zPZ%x;DS|WPvDuyAu}Gn46xAge&0Uv!F*f7fYJkQG@&f`v`%0)&oFi$ROVAlHWp#u~
zf-B^)(kO9U1SQx|)GJcyH{fMYC=v>BA=c}Id>bn$d`0L8^@v?)znIZ-QYBOo+-Plg
zdht432yxM1I-HFm(E0_k04I`=SqOl(;kH|CY?<#6x<YeMViKJT8LeL`p}7x>F}Ky`
zaARpDpw7c5WN#{f9P{5D3h*%rMM8n&S*H&WRu5isDtwpF8|tc}U}*58KG`Aofx<hi
zHm3`83xN-Z19H-z6Kq{7>*WHdU`48xN57ACyB&6`0~uK6yM+az8d37jVQMUXu@mO`
zgn->@cep&P5DH6NC?-0^qMrqd2FeBED1C;6K#;{7WRKHkwfnJ<tMIdg*`XSVb7F*b
za4@ON`vs2;0m18d8c->k2zpWlzhCH91AZY84a9jF`2v3hSr67HR+}rxD?nO|KByN^
z7<XDb@b=puLUbw!AZxeTpq1avV(lu0SypaJaISC^c)qY#O8Md(UNa!ic&|T*T(es2
zo(k8&FBNnMpwC6@I+r&fAkQj1yvYZs@-8<90=z2@23cON%S7E6oC6?h__(Y)&aqJ*
z6*mNrV_Bcu2~4ZQ$MF@ehhHFQLr6MpNa*Ax0Pq+VEpWZt=ViHI1S=TSw~_MxU_+b(
zS0muyBhGBf6N?1#R*w^5H3$XBNI-f5d?&X7#!EcUx}lZB>GrX{AP3EYEC>c(fsd!_
z5`Im$Dmna)tkWqbebq|2ByqgogNNNNr^5<+*je04zJm*6ba8^042FW&;|s9pzY)Aj
z%*Ij)Fp~0F-rcK4!k$nzW<izN!$(mL4DcZyTm~8q2i42&VK;Mn03qv$jkCL<6wji{
z%lla$hZk%i6!GJMpbc0yf6x`maCS!`lZ2B=$cy&`a0Kh|x|}YcS*#AXKllh24|wUX
zHajv5%n4TViM*GMr<0)Txm;eS$L_IO4gOv=<PAEk{z6=~czkJ;Ryo8hh<=E~^Lf2a
z;sEd3VgonA7g)hLd5#N!^wI|m_j!oV!})k@iPF5A1s5uw5P}|;gV?lg?05u?I~ZhQ
zLIa=hyIf)rOdN@Z8gUNzeZ)hY#Ku5pbZR&FD1kYgC5SHUqs$D8#j4oDZkOAGF#+R+
z<i<)nQi%9nY`Bnb73)1Qr{MI?R=K2*bUJMQ##ket^9%4S4B+vvzz2y>@AtW|%rDs$
zt75BlIP5Ossdc+OZUssz*0kN`z-R_3-T*j2$hwd>=@C+_TP!98hu4)8!7RyyL;l2U
zRh;aU!gkIWWW+q*Am{MHBo&iFte+DRQolg_T3^*Fz1?9)H!5LqY_(b{2x|=jL7YjK
z3)~>=tvE`Y2m}RBmh<GYtSeSbr>t&AAj3B$GD3XeY&AAlbR_wV+r}C_7KAGRXS-QJ
zmcjK4iWr3OpN}QJk(g%O=razd!-1Yd18&D}4vcaxr`rYV5y+rF5cCQDP(bpAd3QGK
ziquEEF1a<F^qag^F^QBKK35$&Qp3d(S$`qmNIAHeCmo_^XCzQ^;wjFH!3$h3^b{XP
zBtPr%U|2$z@ghR-p3CRM1`WI#*5H8`K@cLG7?gQ7;ZE_cM8X>=<h@RgZLM>~ZDzc4
z3UV{%s&{mlnUE`=NHxal8pFkgSU%1M-EJ<PNq9VogeMSp2Lx}#Bf4d;j{|K7JT0H!
z8w~n<JnQ0uA&v`!+vNurD}YG>(_h>Jnc09hlXrW=$-K)HO+=eyqnoh{_5wH>x3y{<
zMmA<oX6%WqO$wTQKD&f4hMc}cmUSfJ?nuZT@drcb%VA96n2y{|Rt&mDKZoHdz<DuB
z2~q&r73O#u3CG1;;X2ltD!MJvrm&y2TMLb>%<C}=T{d4Gc)wN882lzivYA+i!6`W8
z##A)!wfizf!Nq4KhaAVu?T%v|5ENk!M^_HsAO<?x4+&2M(5)~v#$lZ+9df56yOi<y
zKx*^)g7u9KqnH!2MI@L}Ts&XBmE_GHY_p6OmcgpcmTJz*S<d2+v$>GnlgM!{IqTxn
z9yaX@$U#oRG7H9lcf|=9M=&dfWI>QIf1!>idtwQDr0C`95>98TO*T6ln*-<(X1+db
z6U~~Ig=*_WhsSFW-FhME@HgiZ@kYsH14k<tcUuE>NslX*c6)M?Gn#b@DNOlXK#F3a
zD!{5jfKH<VeikCUFU7g=Oei07`Eqd|E6YeSUd%N54Ys<B829T;+(Px{%>{>K_oaQF
zx?CjLP_Ws(E{CJ8HRG^)b4AJNN!A4&u^j7*r(Jw1?33a`Fcin6h}jP-8v%<WE*|wt
z*@!)!^4sG%yQkPB+02pFqRVK_H^q#GknD~|8JlCVI$<I!2q@Tz(Oll;it$E+w;`7b
zgrQe5F1grzF=!9u;?7_p>G9-JK6f~cOiU!>$bJ#k4<VlQvvR@fMsj#_O(~Z>9&@@9
z?OB__o@>h5?QXl?m+(7nwk7I~gWVDzjK%E1yr4JPc-9_nYK@wV?)sKG595>zaksxN
z%R7U)h}RL%OI|LS4P!t~rE*~}-Vd`*As_d<8*;qeo%Wk;LVbJO?F>b+f#%srBIngx
z@D|YTSgPJwa=XGdf5M}8gczfNYs_ajpWyX+gf!M4DE|6vc3(d3aEo<0yDON2+OBlI
zK7t86)>Mpo<zzi;^~yz$jZL>?-O09k9<1<WV`IRicV+5CgWfN(l3lY*z5WV@_2UQy
z&cAv5j5$^;#^`~l=El6w#JFOOjgmdun3FvAR6|nmhKo)0UdDyUWtuq)LQ;%#?p%9g
z$}6-rMO}<Fj*}_Ad}G0jV_3;d!lJhXEJ2@pxq971k0HS5>{h+OnoNiy2*M&PV~dTA
zA*U;l1j*LP=V-9xeBQ-aTyjzf1%mVyVmwz!GiHl3$=XaNSIUXAQc|%o>yQf>x8BIa
zb19brxK7c%QoYuTQ*L^l&1KNDpcc5yHir*$d5p#Ung(S!=3!j%3~M(tTrnOFI#Zx(
z#Tko*Ni^q^F%bt)TLV^qtiCDklnRZFS+Ch>4RIcaN5o_(vU-!ivJa}`U8s@hjT~pU
z$avLm!BM?%L!mB$lU0mATVDt{l3;)}Mtt#NOMB75VC9i+0ISPo!HF)py_gbwDSVy{
z*yQ>;kv13d`Hb73H;3eqS?8C6tMH!As&m+N_6YV=LNqNYMoGx$iWxV~+z1gXh`dfA
z9k+ud>f~Zxr;~AlyXCCM#OdZlw+)n3dk)qTqYr9>?HWU+4(>7r!;)R+5ZE>9P_M-p
zbm+0M3Bmb6%H=eR2}$-jQsBMCyr5h%kvQvuRU&29<h`hN+3j%@k6Vh2fw6g{h+_0R
zQ9WX<o@6GOaN-Q5CmiwUEFR}N^#Z@m6877`Zwcsi@D@0NajzaH!Q6?ud|ff=W<f1%
zD5k>R7zoUbX(J9f8q9?zP}!1RA(03FjWs&LxqK#{#-b$|wG+L`jdi@<V3O`#uYw!x
zlKCKbB5obdtnsw!>M_7zhRftqoXr-D<w0=4DLV!$QL!8}@_q-1z-*&ZXHRn+2sxQF
zXVL4;tOv**Il?nGlXLFFs^?5=AR^j5qHM<*cSA4+4oZ+1?RvdOwBY=x(PU?1EIr_+
zXVRdv)Yd2HVYaY=$>d_Zi!oSYnN-MuGn{$`%VDev*Z|5}rn`TsW{25PUN)FqEQ3Og
z9z$p>Az5q~1QP;|Q__R4T!Jq4Ek?1Z)YTLsIE(7B*gRglkse0IfMBO5vGpz@nIlLU
zK=@6!Z&b4*eUi-L=s6ScxLgh|=6ajOmp~;snF_n1QiQU<GN~kI_Xid1AABH5B$7EF
zK#_P3frF_!GfOEEE*$gr%3kx`n^fm$4=a1{ksa&;NkC-?Wj0$#iP{hlCyJw#{h3TV
zEBdHEk76@^2|-V*S405>?OfP2g+&{6vg|WY+@dDWu{a_=0NU`@JsfuHs|RmsjWZhd
zm<<+`(4vVXtH+_es9r#YnsQz+?F(`gszoFR2WEiG!Fy&d=4bADTy<XLGzC0R-iD9E
z5!Qrr?jF6_C3sErxHVj2u?IXBi@9X9gre2Wk3}B@1x0d4B)`Sr6y>l7&Sm&0t83h<
zIwm`GR;y93V>nroWWk0r>IOTHzN9CJs9qO9Jtjo3Ukjo?QvrINQw9kj<U=wUbe5n6
zML3%zyUf<@DmOl%(b@erBTl~2BB|euJsc<lQqW<>*?fb}6Co&%)ye_AzKk>G=CBlS
znswAGMvveyn7p#+v}$&!o{0@Qon4Xwfsn_Iy`<TLT|H_=k%-7TEk-9QkV;qwg<U!Y
zS|AY|PN<A*(HUI=cs@Rdo8z3jRL>9>Oam{9HA8j8+#^N+1fqm2yX<a%AVjL<2P-ne
zVsm*pNp@5nX>`K(5y@lF*;&^fRZ3YfX~1p?X$W=oW=|-B;9vxSOuZf_0cx>D<p|cZ
zlo1k+_~9$Y9m0>{fJJ8x1VAPUSWS8xhYD;6-HW1_9F$Sy(CZZgt%N$OOb$1Q%Yxa#
zN_bG_tvbD%bAwo-fg7Btchv@MdL$;SHu`a}l%SAXgTfS;X_O}-`0ZGbLjw+|wt)Y6
zmBX^z9ROh?%DGHPR~ur3$6R&>$C!1f5z9Ua3oW<Z3`mspB^DxWY!F-%x5bMZ4C@bx
z9+MrV71)Bxs1bu`AQ1G^Ed<WNS9E4CPoroHaGGPPN8<?a9t)geU|bMOi^Wi`7M<Ut
zKyRW$(cR{E=#aI(z;V@p?!!583SDO~S#b^v3@5n;ou;I-=}i{9o0FnZmxJZ4C-4%(
zgT=nfVpMcNgVBQem@kAnCN|MHd4VniP3^4oj_TB47L{4I!@^+nFgk)VUQ)=S%mw|}
z$a3;Yl@SUB!NFq}>2j5wdY_Ip@l|R{jV9X)77j<5DTY{cA(@CsBx;bQh$#B#Z8swa
zB|@l`8bH#D2pLdQbl6!$P*v`Z)xtrckJTE=50mFcYr;WLP;dnRM_|8#5-X8)=oM1?
z@6?)ehamB2vAmlSc)}X?J^Za7Ps^kVs)6Vuk|f05QMH-@M5v`NS5RjIOr=`I)P`E#
zR`o%;T*ZEyR%8uWQe_hn)bRij((=i-RBavhJ9wv1EixLz$pM#M+CLdCqduq;1YQJx
z#G<iEsWCSUMlkzc>yeN#oE~<=jl(nH3W_B<l$$vACDj!ZlOszT-u~prlM(t34^Jz2
z31|$-xwiJaELKoD($RWF`iN?9`rFB#lYcAyXu8->-`L@Cg)8v}0kt(Oa5_*j(glM7
zw(x7!tzp~l-~TPhEr0#%-~RUFF`P^A6IL4tD8UX$=-@~YzYtb4@Sy6q<;VT%+aG`U
z{!ickrTX+l?Dp^`Phm-*GpOab&LF{~HQ10HPy>$Wq}PA=;oEO1Ux+^b<F{e@vJN|8
ze~FzJD6x7!9`u3$BJk-+Z~gG?S6_eA_b{IR@p060@H8G*{EJxP*H;gK^xLNjqXu02
z#$Uhw{LAX&Rq((3^~bC5rVYDy55XCSioeWOaNa>rkD|CddsQwveABmIRBtVU2*{us
z{q2VwcE&E^R?w*8)1ZOY?=SlZ&VZm0;1qYO(wWg|pM3erANpEWo6@#Fd=kLIgudD%
z?viI7j&T^=wEhzY!6Q6m;4@#JJc%}+eU3|#zW(|fD)75M{kY3Qx8P_+T#9>vM{yfm
zw9XT}b*JhbTR-mYKm7i~)2;fNk#CLP{kWUK*>*cYi9m5Jz*!Lk-NM_QV04JG-0_F^
z-$Sd9KKYai`{K*f;(mOXv0z-#+R?D&obN(4#i2*t!Nr5i;b!y8KYIIJdL_h1pHy3Z
z{ssBc@)cF}#|dUEP0^ItOOAO?R6^_q9Iemy_(9?D1k+D`^yb^|yhpEW`skBCz{1Zy
zCtqm4{E~cS{&6BbCy2IaT(Zw|D7am~Xth|9Uzfe-J+6BB)Q<OFr;V!@K2=+PimRct
zUqH6*hwV7JOc<@jLaZg*JiB6})e#HBBtH0bMgY8xKryxb-Pdpp)H|ScRmGn|0EFp_
zFaEk669<ljGm1sA&cnHLg0@&&HlKX!qp5*&H>qqWzV)qFs&`kMMxe(3;SU6KGvnvq
zy+CIk%pM9;vdpmp1+7iSYrlBo#D~+^=8Y<jfIarci?0HJs_^dnREG~wp8N<H1Q_No
zKEo1(-k1T53Ny=6X6)5BjD|%Yz47|-_b2;7*Wer6<r7D7oz-h6fbw=#kKccA3Woqk
z`<Ibe>CoFyaKN-=o`<7%ID}`!a^c{6Ctg4P>N^(%!PXGQxvzfX5O7{S{`zSk_~aB4
z`G|a?{hpMtZXia*G>@KD#jPTAmh1n?8z){n{_-oY_Txd<5HI7}j=XT_$g!89&?z9O
z^d3yBLMbO}Kl<XRtpcEmu?L6Fp_rn#l21;&{@SZAAA5D190glLyd^4aJ#_HUk)tpE
z69=ZjMSV!*1M*?b$!}V_F}2RdjU^RKX-D3E{k7w-ynO8N>%<AlMo81*nsF4jaUBND
z4n{$ls#&K{$ou5?<OA(D3+C%9hFN<1Eq_4kS6_bd=;1>zkMREw_C_%2Zh!8X1JAwC
zce57-qo%$2)?06rceL-mOWq^z>wf?H4?oR5tQUPp-vSc7^6T*PhqqyZ`=5jkkqdcO
z9@w}4IouR><mfS22*5t|C?X)qyLxKpH%lMZ2XFi6_$jnQ&mTB;i@T5HK@UNlB6*;k
z;Te5k_de+NJd8aBSXJ@F8{|#xTW=9S>XG1oc#m7J59Hr^{Z&v6j~zX7=!Js^_8-W4
zDfJ^j=Lk$jm=wVM5apn_Y0vJxPeaM)51j&qnx{|!OWrcQ4OhPRZ4Yl=s}I>8d*{_x
zUWUy_4ug}p|LH@M-9Mp(C|pgDGD4(5l5NcX9lQ4IdwTx?uo({>KKAO1FTM;1P-r-n
zoFH$Q;Mcc5c%wPSuF;FuW$(T6auxRwa1T7QZ||NA%8;koA|zNFsM1A3X9Ya-ckOtR
zG9IbUhu=7~^_AoBZ67vyO-sSeZ=i>KHb0bd=vM2+2`4G?u_IJvIO6HOyPvz;_P;44
z(shz^;O=ct?4)Wxv;V-+qgV2V!md}29fRtxKy`AQyk<p0oOtu(Md6rHqcg0~3(O7g
zAqA*Epg35U&+OZ?YxhP01rp3X3T7%DrX9*Fae-Ijn7niA_8m`F1sr~&Kr}Y}fD=cK
z9<7Ri3<4R3*Is-3KrS9qG|Tj;dgNX{PAQ;3hhN|rX#eDnXU=xWv^e`yu8H%us5|=T
zmd9bhle_oqedb`Bg8ewZ=h)#RrzDV<$ty-g;N8Vik}qkrdcz`p*noH7)82${`t&~l
z7U<qRyLLXYn>a)kv)jMOCr*%0Y(t*d^w`$zRS}0Llr#pNeBkh*Lx;(cT51J(k-Thp
z<&}4D5|eycQ-j6hJV-G463OsT+;vB7IQU$j2w1Uw`=+o5gcRbaoF=3=g*a!w?eRx9
z_X*jvS1M^3-5JLZK93|ibQp59M~^DU3@^U;_BALjci=X*x%#lthqoe$xV-vh;P(kY
z{y@SL+a7=NY}?Q1DNZTD`4&D34(sF8j%OC?OB%C&;nC-iOwYgY0y(6mQpi!mi^m2<
z5;0>ZL=b%ks2VjWR+kcjc;l;72DJi0c0IWhLbmL@-V%_1N?LJ(wBk-a^6&<j@;GkO
zdwO<R!wfpQfByjpf+X^S_Rt~au<^*TLv1)p<LK2?bc#kRgOtY0?faka!{4_DH}>s(
z0$28J-r9*8{!d6OPAuQ-jT_dVmaunLNn;cC9C#Y3yZ=B{3VB|6!FcG%^X(A8FV<)*
z9SI?xSpUK^Rn7P8!exMfetgTO&C5A2<+W5VL!q1&H|4Z2zjzea`BAzqh{D^VNY=Xb
z2lnjU2MJXX<T-MXJa0U75cr8Wvq%Gi3M5G7!_+ZV%}?QP+^{k3_&MbzMkz1M1sm6{
zf4EP?<2xT3HDu<#XQ~$#?mH!f98jJ!9em*cm5|~VYP1X(F}!s9A>3vN&pf#k5rzS{
zoA8m1O}3xVVPc@e1nd*nuU-qv@y16f<9Nq2`=8#qW9O5*`mRKzBFHmjzy831gU_@?
z2}mmL1sZKA1p(m;o~KtOQd0BwZ6GLbdUV6X4{bTu@>8meOsO({`_wfnAp<r%TJ;mX
zIB^Gr;L=81yh!$H_w6GPQ@j6#^TMTs#y(G@^{2WLLiqgsz=!(Vq5or510GtpX|(lc
zY?>%#(|GKYSFc#LhRWDLWjyxy)@^-4s;2BFkV5w9o__ksm0~%eam}F;x^Zl!Ve77{
z{@WgZ{4w0axZ#n9)~$JT6!UY!jZ6tQUi;*g%U7;i1B!Lu?Tu7O^$N%;!<+0PRVg(u
z+#LpGG9{RMG&PKr>PbXm#Vt=hvHg?{RT=BouHG<;`6(kOP8m5K+s!MNE?==~_1bk0
z!H}xAKmw<x;HF7<Y$th=%BeXpSFV6)mcVAatN|-1m`L^}q*!s&j%{13o~qs``Ovzx
zt5-fUiuo6FC*H^0F`vC^F_nXxBu~kqE~}bTm4rJjckWc4)a}~438%&rmQ+IK0}kv<
z(M4t_gjn&>?QqwY>b;fVm{Tz;R_86J7(TH+hL3sl%7u`!l3GLWtAsf;GL+R0w{0Wa
zwNE^u>>xX9_6!e$e+4pLC|2CCwR#;U?!$b9-fX#g)r#dSWb0`T5GehW1H=@T%%{*R
zR<1sE7v=`)t139q$yV*QZOV4?M9tIJOY0J$@LAh8Z=w#_P}Ow}lwG#Gn{}M#2uXb$
zA*<L6GW+5s%c#mf!F_ZS*{s<@9wPu&w$<)h6pOC~=;$XNrCI{As^`k(%a*K|grf8*
z4pF?1L*%mEyI^h~>I&peA1r)Pb;hR6xB-+rraZ2LKl;lQ^{Q?E!~_kWf-YJ)+Wb$N
zQQ|bs$UJ&6z0GqGuJc43`}BpAtH|&(fzHYn-D8jKx>lsH_dX6isiG8g#d2KPxnNm_
z`6m%6b()A|iOm5kfBu3+i~H^gT}>T<=uu><^hWZi0_fVUOH#4b36P(<9;K+KV3#df
zylBDVDU|AUim4Pi%~Y~E@1BFZL*d{)l~+<9SFy=MwG^CeARCoOYd1Y{v9ucRd>U3G
zt4_m0-GvM0E*oX~7nuoL^HXFdrgeUI&#XB(h)`8}IkJNKW6fH!u68{%Cl8ZHlnuI#
zTNbBcs}fT9tc`%JdI2XDpzr*-^DC_7Cw!;mKlx5J`^4V9V+v3k9-+R5;#G9Gg{&tJ
zl^)hT^2pY)VTydmBY=f>tGG~j&g><lOg|+=B~KBef_}THc}_=HH@yXwx@0kRH`Sbi
zLw5q@6`<E{T#$^dOoU_k1#19&8X1?Z&YDy5TYk!zO8$#6WwTz}+tG>B5mm1&Jgqv8
zXi$8znygXQD(h-CT_&we1jAz<qPWx*3+XMcvuE`z9AW+$p(^<kLKVZ$?7;P{0LS5t
z`KNVXx{PYSf~+K~l-0_b+I4H%BFhtzcx=XMiu_OL-tIZKJM2HBTqS=>xia;iRVsG?
z9_Kpd(2&A6a6I+=GP0aNKzUW|!!u*CWvKp)Sk;Hzr*&^nS5Jw<8?2v_vXVa`Wua((
zUXMcWjP35}nMKc@oW_R$vXnqTc}4BYhpq}QO~|p-%;k#~QioLUrlqG#W*5!QpL4d7
zKjUm!oi}yOtlmjWy)$d}X#uc+EGCdpUZz{VV)bxoNkR@^yb7mXC^jy>1$alt?6c^r
zjGuA3l0WBkS=|#lXDa^`a9RR<L>7`o%Hr}8-O?3H&Im6`MCHag3+K}N0%!HYE%a{O
zStHHh%>116mHZ#1FUECa=gfaffDKg<a1)tN7AOnLi}Z^ZFI#*@cma;dCZ;Tc>d>8f
zrn945?j3>GRsWF}7CFTWGrO;?%$U(917U`vsz-R>t2tz@GQYAwzi{D_g+s#gaMMNf
z+C`@X^j+>-=^Snbx8{E`$CCexImTGes?3~TwdB+d!QIptGK<Vs=9D2uw`l(GNNhHh
zam}Kt36Ri%`-7FvnHiJy6s-&|w@%Z_GXI-aW@QRfO4DEqH3nijI;lCZhx975DiEZf
zzv%KrINp;;MAFwR=tdL}1}bBw(mjDUQHIz5<el;Vj(29{uPjZUHhl(}saL9^NJlM|
zrF1JjUA=}`i|!v1i^Mw;DLFD|%A7tSkfO|-Sys-p<5HM^!%GYOJ6;-NZJ$({Mvpd;
znKcka%C!~PMLJ7e9o?kI*ga?N#52;UZbuD~aIEcy?j8b8YpE&<H&osfL3I8tYYlV2
zzhSLejQ)|+XHK08i8CNkt0<(TEti#w($U*#n>B0d73bhCfwL~Tv(i(+C-`_~XvXxJ
z9TOYuxRK}Iv)SVRfz8I4A{R|nrcHq~m^VYg@h^J*tG80q+0#op^xZgerod&988fC&
zpINzgsK<aT_zw)X^nYZynVHDh6P0O`shp~y%FL3|TPiE1nPf(EI-;nQZXE10TK^xk
zx6FU0z1htsw*U3;*<{=`O+}FD%8Z3Gl^NRU)5)~x)M+zIQ!g#pOq9#@AGvU`{}&g|
zVzfukylLvpY06~nlqm{aHg~!*O_`dQGHs?Z`Kor_f>GrE8$FKu89mNwHrZoCubeb}
z=Cmo3?<bQ>Q)W*sPf1UmF>}VmU$pa9GxPtSE{DsO4Ax-bjLYwuJOjt`CQmNk-#OV&
z@8?Euo%Vm*yZ)G}syKf6&5PfX3W}98VIXOf@aGJDjLa2C3bHj7!&xm8tSlyqBI#N-
zEq^d`*xaz$m`S3wM9nPCV7fMZ1|c9S#z0%(2(%FByr1XX_s+fdoO{o?&oS;FaPB$Z
z^Z9(vdH2UT=YH;c`KuSri2+|h7GPc?rg6^!D<Z}{XEyv9`~yagPe{&Owl+8alZ`=z
z@8#t#$(R`%0iJmp0*lx==!$})g20!s0do=Xw1D@rrh%`e247S?FD5oNE;1ZE#5BYL
zA0Hnt9dJn&8@7Q}S0AwS95lq8bij?{4kumYqu``_(v40!UpgmU=&+Mc<fKa&cG8hL
z=@N#7lP>g;cG88YchdPjGETZ=22MKggwSfG3mCT2>1w6((Q2g&bG6bH`S=Z6>4vRz
z<W{<|!&bVXZ>3u|W6f$onCmZS-#h|=TW>OWr@>b{7Bzz3q@~4&&RjK_OqVM5<fcS;
zP$OumFe2;Vm3w`Iwr!yI_UWSO;Ag*d+5%tw{+^xN{=dIzSE5ez3FX~(R?+|Ff^Z!a
zc;_^VSdpE+Z@~|Iao!&Ls0U$mPBx_Srr$l_%qiOM$lxl#`(qIsW~cono&w(J#ZZc~
z>L>FPVEj|eh25(P;~>C$)YR1MeUeAMNJs%=e!sZPg3@z!9d|@5(mOZf843tZDLmTP
z*(-n4J89X&ir;s}w(72jRNQ7MZEOy~@D<1J_B%C=Y`2g>2Ta&lbDxaOHR@8RRsm64
zZ@9t|=iHmAjXyZ=8Zj3(aE&JZ1=Uzkip)|C{A2b%pkTs>{;Ym{nf?bJk}9`e?MNhW
z$A45r62UFt2VK={(LYE4(q@0^r-t6xOv@t~UlB<!U}>i$9DPAe46T57v>*4V%!V0s
z0ya?JXHYgwy46S{U?XdKa34%27m&}MesHjr_&%_T$!YKMA=Jl_^+3AIe9i?*UB<<+
zBmxq&+-&8Al^c`=L|l}|&{PT><qDhU0Zjx7m3y<y^d2GOQ(l;pIK~U3<xO>iJOy4y
zaT6Ghk9%$3ukHVIch#0I9_6fHD#@hAfu<sHY=rSUIF!7UCSIyB99IEJRpsH2Eol6G
z@H2PF_7+;EPkMtV<ex}3r(-It3z?&rFhwQ=t9;zv0nf9%<rA_G4tA#7_&pC3*I^pC
z!?t8<<aOOwP<w8ir2{;_Qi$VKTsz6apVY;RKmoVWIz!*B5XP;z;R$p5C$bxEQz|{{
zW9DB=S&Ln`Wr@naiX9*wQk&)QPrOT4i(T{w=H3_b*#Xia9kkqm{ZG@?VisK%Y-#?p
zr0a>yh%G?f1-3C*4qIF@w3~aUSQ-!hd`?z_T~yzx+<9<aB&3ENG9l7td(+MTC+q+5
ze}jy>gp58y)$GDdqmd3MV24YJ)czd8e~7deySRTdA;0%2cDTey`H+9CJMO&)Apg^C
z#H!f^ehK-X>0k#-jC2ytycY6VaFLf%3on1m<s<o&UV|5aWqcUqQ5zw@TiTECXUi+)
zQ`!{aI04+k-wgRz@M)nu>UGHPmeEfO<WJ+f=!NfxI(YuayJPBk4n7u(cE`;BsN?V#
z#@xnt5!c+qkl*7Mu1t9FO^{zWh7aMIn~m^q<I02ue=rx}cf$q1I_<V;NYsD)eGy%K
z599aD1Kar^6B+)2PN<X$<CdR;eEfp&J~ti-;2yCpW~$x?z-6&d)vr!MC$H?CqV5-j
zUA%}Sa2Gi78ztg6Wj9%ueV_;f3#SLU*b>NWOX+$E?st6_9naQqAm0_|(Zvs22YfAG
zg=y*QF5NE(^O-Wpf?bD0KPbdozd?v~$rn;vQ%htuGc3H}c;Y6K;B|o^haA*85iQ(F
zm8-<A>>BRVx2VwP0pLp5VyDy;J?0@*m~-E*Lx*+99@k5som~(Nn$3=ihshSmhDjwU
zd&(6VWCJb)U|5kX&I7T|1cVEh^g1FdUu)qi9H%HR@~T!2nfiN0RQR1){7%9%3Lm~z
z&>~*P;BQ3!FG0wY=|K%eZH}j1_>PCU#Tr;7t9B$o0;SYeNfgxucjhUPqUBpu^GH-|
zr)a%d$a=ODvX<Fs>qyd>EZ4-UCy-EzV~p1&x{^M-Vx$<FZ11VF^h~%KeIKfP8_}?x
z#X)duAz5>AQ7>wrmX}-HH8^mRyzpJx9!=d^E;HI95g;U;$9<+`dG||HzIuQv^IzFO
z#^xL~aAFpUqdpzJq173iV88kmvA0w`zaWf$x0Zkr33*VNrs|~&Ns$4IEAcPdBBYMw
zt<R=O0;w;E-F%tkWcd3;wyMh=fiU0c>rejWXeB1`u(>Q}JOPmU5RY*$7gqd^xi|H9
qRDbdI>=5<H6g3Ue^H*-)f8;WF;oW4qV*079WK-6hD3w=v!23Vfb?I*a

literal 0
HcmV?d00001

diff --git a/extra/gpu/demos/raytrace/icon.ico b/extra/gpu/demos/raytrace/icon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..806fe33ad086c8e43e7b3b2a5a34abf76196ed23
GIT binary patch
literal 9854
zcmeI1d7Kp0wa2e8(_OtxZ_|5MS6B7EOn1*d3=BF7D!9jhOB6oF7(fj%aU&`!iON${
zT+padLr~ntD7de2Uvb5Ki7U7OKJ=N-Lo?me=lxDqH;%Z(7~gyU1V6{ReXHu+@A;i`
zPj%M_u@(MnZx{H#D(0kx@CzZbFieR9U_9UW*J=}jt?`eD#CJ8^(=_^8x4X+J%gJs0
z{`lc8SL`x}LtSOHDr?;C*v4>J-53nUHiSaj%i*wghb(K0R5i7)Eay_AeXvj1n9*}T
z^ceof!nSJoZEY>|Mk2|@KA-lo!x1B|SEEoUPSI$bVzD@>sxd}9WVNc)(xQ^nso^@6
z?PJW}+T0vJ(CHj-H+<IP*t|w#{$D+^--Zt%+Qxgmi4|ZRW>%+DB_R|r#j4S$RtW^u
zs>c%>aXMo)Nm6RaNe%NO(7)pM$142U=Ti}50`Y3(a;bl{*-}Ra0z24v4b}+ugXE&_
zOJ^?@cXr$DsdM~(wW=s_^7&N)U)63`n7O7X8nJ<o=b?8DvBij4Wm!dDG%#zVX<7~O
zRUHnc5{ala&Q&0wk=w1U_WANt8#)aR4sO=0G560LN9)kuK5l}?lX!`10W}TIcm;Zo
zSgZ;KgU}M(JdZiDSQIeFm{T`Z)$~||h(g>b#>PEdbI4oG=~SwSV+47?{TgD;EfRwC
z8Un-jilNS~`zV)t_78;;pEoxv)Y_^JLu1qe*RrDP%=&U2@%k2vifg#;xi%7HwZ+NQ
z%=#t}OOhgTf_;Edqj)^7=Y`{8f02kbY_lnPF2do|&3o)|fU90l|5Oa4buSisey%79
zuqkA>$A($oa75KLx7k#kD;`gyE;5KGjrlBPG6hN`^5D$ja}MY7h$qLoB8D8sS?Hc5
zhck(Bit7gZJEq5iI7V7pqE+k@_$WL)bLOF~MhxG*mIeonoXK+kPh{v7iNuKao!P8l
zEfowY)K3QSFmI01={B$ysMXU3_A+=&WV02)Q^L7+aFoGW#<e9}SH$@uWwRyt%)@sc
z*W^(*X~dtvbqV-YYFKYL6yjRV-ZOXZxn?7V>0|#<{Wt2(V%e_OZjW#BdZX~EVV}jx
z<4Gb9Y2>|t7~06;Xw%s;nGVENrev}cEL~vfz_<&H-QerQ{axs#UHUmbABl7z{tkTZ
zKs+U!E5T<G{&To5kGf02w^l=Ms<_<>$GNn@&9%`OZ+R5Lh%b{ly2WnKtd=C1`}S}!
znAA0jMhnojfVIldnVH*lCQa+cnq8F3^+MxrF!bss%e}a^k5cJA#MuYtUa<Dyo?cR7
zJvi5maSv*+6R~#T-m;!Ej>X}~;`;Om`T+Vb_DiT|7W3lYH|7B6^qyNNbf3mOB@l=Y
zyWMHzlWVs~g+eDdJFreC#=X#`n^LJ>=xcB)N+0sl2d;5go0-Rf*BEQsIK(s#=f|Ob
zjBzYx#HFfye-F-g!&fJKc0!vX?k{4!Y=wI;a`KTguyfpq;j4Aj=(Uq4Pwj}slAm$C
zXj*<Go#y<u>ouV$hQ@(F57y}0%*`Ck#jMQF>^#TDbIi+Qo>vs(I-ZNi`}NO>M8AFw
z$HzJ2{P_Ky$Z;p?zldI(8wL~hN82U!9Psn)OLf%voJ_VaL)|0(9G*!<y;fNl_8AWM
zfQR*Ec0+5f3B!6Y#|91MZjvKiq@eDja+f|1hxy3*_SCQE`@V=rRr@#RhVvGQ^y>B4
z+S-Bj+DGE?Jf0h=&$HPbx{MgU+K(nq+&v!(Wj;0fTzN!QJE04&*{kcv+`J~|o9owL
z#s0*8jE2h;2^A?EERf%qhkiNo`f}t8WGR3i6$<7l94g?tA}Ns)?rDd0Lho+)<{C6&
z(X@W}@7Hs~x#KwU`5xq;z2b1>5L4F$^&EWV`$aC-GoSY;dff=uN(_vwH`fH`UzVXA
z;*oXU5_r)w{TVWQlO#ME3G@o#jF51IaSWlq2g&IOQZtUi$#Xd8#xoc_ShOa{=|lew
z;Mou=A*K$nHnbXt+8+;&e$>!-%=e-Gd#c>8GMUnv9e3O_#4${t{>46+K7D9xB+~w1
zBvOXP-4$J9J-<esvrdt4JITQ|XpsQ}c%3rY905u@TWNyZO*?rUw3oMqX8P^)Q@@R7
z1#C1sV5Og7d;n}epPlw-ZK3TvE^2pqDD3nbak*n;^QI__=Rp)}a9%mjygy>G@z8HP
zxch6G)`Ps3vHpa;>p9r`T=saT=Fz`C<vtC~M;iN$HRpcK++JUb1fIhJ%$+VbSR6Xz
z5g`j58<yz!h(squEOer7QvJxEd2HB%`uX34E%eKvm1ZEO$%rTB@WC(ggS<pgYjPNC
zVr`?AI2Yp)Q-4*){&70{&ad-t-p7H!q<xH<>BaZRarnNAdVvnCdB}(7J-$;~z|GpR
zuDm{THh4~qSU2-7z?kQMTQ?q`A{)ln&BwjJ!{>#t-{IT|i0#ObmG<#ED2H5fojH*Y
zImpj&&IR|Z3Fxl_6|N`j?}vq0pljdg`F{Vz6O3NhUs0mGZ@`Ya^s(ls=N{yH4!C(O
z=3=G><4JWk=J}7hojU4xree{V_wh<J(IL?|*p4oV4i0ckRyrBRK2DY;<k3RYyiRgK
zE8)R&E6`@_3x)UfKvmNQ5YPDcWO-)9$bqp3QmJj0a;?EC+;1YGGP#gTf&IsIay<N=
z1pmz5;APfRqZV2OI~{gL-Oj|3Z85l)#4L0OII}i0wVKTowU{Xe3rS`Qz^1iIbQ-Qb
zwH}9|fkeLw+NhxCLc#uS12gyA3FxB}IT!!!a_v|i&0j8Wf2S;?#=tM5ueG8#F#8N&
z3pA4I`dG1!MPHA3nei+zo(($(b}sX>ftl?h)dGzrY6YhT<~(A^S`BNA%_cMLkG$~x
z?349ah*(&Y<56opZjWBOdXGX~tLoO+&m6;)!O{Gs(vA<v@&vB6D)&XM!F_!W@Jf1)
zS?kfvydE>22m3wj0ygk6^Mx2M)hsj*``QJ~(_qfQQZOE~@t9-Dz`}^{IOLaoupXSZ
z)1p>ApS)k%oL=nfB&pGE@K2<;Hi#H@+kP~ExjY5@1Ek8`Rqo~6dfa*~v)-%)`)x3v
zU*~1kKfo@5T?+eS{dhUp&s8KU+0CTXbsx<>I)*~Mu6A`xdhDzP>%wcDff&w)pCdwc
zJVQd{54P1bbpZQ#JM`AwCy(ZjC#K$_Dig^YDpgutAv!u_qs8Fnn&!F~&3tj4b19C0
z0_!r^Ww6UNNw=Z6L<jmL;@V)o2JhD$S^p$r<oGzh?CV1K<y>%XjoOrG*H$<7b8;k(
zeH@QZ!an%Xz-WF&nQ~z&z6}XquCha`2ka6wx9VE3uZGTC7rX|uE{9zS)~jGw$1ONo
zXhl*&{YZMPbIo&&d>!}bIj$`y>TF)f@YBd6ugSV`JsuObk;M}ok?~y1q_+QCclX|H
zqxn;*-HuKt2T6Dn)j5F{)U*V4tDaM?59YpX6f^S<B`kC;?9Z_4l57&)n&P^bNI-ku
zqs++~kG9e5JkG<cxPG=@qU+#`b>X!*x14K^gX^f*6R5PHHx>(1UY|aFu8;W}-<$h;
z_ueI$8l*9({bR${8sB%3Y9+1_u8rj|)_Eu)>Acs2cLnSQFyC0WTT&9;j4}5_8}w`g
zKXY?!XjX|-SOVilER8sr-v<5}=tJz2b>X$HfN`!b1;-_-nRfSjDk9KJrTnh9F}tC^
z{;p`NJ$E`ZrY0wS81*L5b4*p%oAbz8u&?XD%^EW|Gv5Sb-dka})$N|Nab0hVL^66x
z4*X%Og=|(UiMmNR1~8XGEF6cfKdxi_ng3?^S_$8rhejOBG%M=WMEm*OHGyYqI=;<1
zi=}vNFgQ4^5eFX&<(+QQ!g)Gf7M103zQ=;Pmgsu0Uju)vEweKB?XWw+dl&5Px;>ON
zV%5NvgayH=bK7hr*f<7@VQ!AWCQ%y3b;k8}D4rF6fiGT%bIQ5k`n(dgdUagT%pkra
zDdTHFyaNy-g5LvaJO{cKHe$$Remut>?!@zBYz;l6#`m$GW$@7*wbKmMuIqhI+Dvz6
zB)S)NAM63x{jgOzgI~tJm7(ueb>=42(pIKs8Y4;6gczDR4vb~f7|Kawz|Z@IpY0N{
z2CNP1#Bp#g{+zJVHQ=8X#&>UJfIODYn#t7pxey)rZHwO>k%3(}hQ7#LSwttSJyv$p
z%EZ{}5bnDJe*S=?knOnFLB|zb^hnkMX0yK5!&vW8*dtjpJ(Dxj3gjvV?Hyn=Su8Zh
zWTG+nZrv1#P!rz6HEVdE1rr!M!(mFg9F#E$a+^*1K6@N~I0u~5JM>&wP^(tDQWLaw
z7~jQ$yMTWmvbW3t`;5O!(%yJ)G4&#RkJEqGi^498X5gLA4GB?QnY8ITaGmV0Apf$1
zw%IyD50zW!@l+E%2EA8dy(hu_1nl{|S<geS19fAP$YJBSqtu+vP;(~xB{Si(fO%8+
zo)V7GOs|<9%QQg?3q4rREAOY<VRxol&`ZQfAT+*a@f=B>mJ{*Y=p^#E7Y@5zC*ilv
zuP(xm8J*v?(-E-_wflqRi1)6PrONlSKaOD@{9MrCrl<1~Jqhlo!TStsb=_VlnCX=^
zn_kDlWFtS`e~N6*;O7{&u(9~;$#5Jw+BK=s!#Nvr*rex|^U5`OciKkxq)oM>qSzyW
z!zkpr81JI4!S8^TfA{&W#qXIR*peS}{cO%bbf;g>S5&$$EvkP>+iG0jkHg<;X#5;B
zdM0PmnOW}_U@sL+^fK&4*qRdZokFgnF`c~yj7?i`ZyARV=S4b4v(qZpFwxVn$FLsn
zg@-cE+Kov;eUWXeB6t<azDFsUdWF)Nckv$c4ZO>__iAw0-}Nrge-rb&-}cD3J8uNX
zW7(~SAIe(6Z`8@N;AQR?p*1tV3VRLqSN&+F4~l|T6!3c&Jj`ile$+_wR}A^U+*p_u
z=1ilGQaQRf8-hQ9dX%uXwfbaM(EJ#FFUO|s*PFd<wi0{%30Z#q&4~QgW3uwbJXL*5
zYV;pH2laREqUYfF+(iDpRk$C%hM$7J=UDGLcZ2zjHWR&7w>8Bkdbenz85!))RF=Zv
z;u<&Q@?>f&lBrZCbGd`e?VX147;~afqyXwnq_Z?7m7r(y7UWl|y^s?lE7Cp+M7KV<
z!8m>TVoO`w^MOL)MN?xAdVlF%#9;lMyD03o?HQW(*(=avb>1?p*Ee*29rh-e--f*d
z-Zijyi)Q+$B<QI&7de?5%&u}fnR@!jGGTx$TMv?T+eu`dv^`lT*Nw-R<8$`@31sW)
zCXsKW6<Kd>O`E7Zp2PcqSl99|IE~+oUwo!9Te3IK4K?~vY{#9KCY8Ux-6ptJhF>d~
zYpnM>#b#Oyd%t9&4|Frr-^zmSDBu}WER$#a1hQ{8nXFTHCflxiko`x~$Ubc^YMGAS
zx7WU8-}@)VaoXPcISJRuQ>Ky_7_41bQt8b?6CIK&UoX0zY-Xm$yIJNHVhDeS`?BT@
z?#7Y##O4?xJ8XAlO8Jm$``x0bzFjm|*FtmVURP?S4Y2iPi9Q4W)mU2$PNMLxyOSNP
zj{Rnm<A9%$<Dl8(oP7v65B>!?51DHikLMgp&Y#aA`%e#|;C?e|V$bPxR9`opDJL%$
z3k=2vdxPz}9`$|Q$U|ng%;mY{{cB4$+K4*&u+%)fu4Jx$1on+(Si6NPn7^eLy=2e5
zC<JB~*j&FnoZLsuBlo=H$aC!R<T>s{@*Kawu=zM1cLI5SGoRc?&LihxhgVt;`31G?
zw$I82qYz(xPuMv3U61$H|DGWR?`=9Ooj>M@g8$>sI+|%yyP!|XO(Xx+-dz2p-8xb&
zirN$X;6HE{wH|&H`HltKZ%?Myg^S3$Xfb)uIGcQnmyqx5^9(y{33<;vhrFksMc##{
z<Jway9GidkuTNmMu35A6+WD@W-*(-CQ94AjlhU_j<LA9r@ND?J1MRCzP_+x~0P(Ev
z^o&fLdss!BvZ$t>aTc{Mxq$o^UP^&WmQi5oati$E3d5FNNrB6*!WeUxUPk_l{#f(j
zTJNcgNj~V9J()!e4SnOg{%>RbrgL~_GzMNb`|ME$;<sfIN4?k<y8nZcYvZOa{J9PN
zcKNIWNnCI-X_qV;30^Top`jHNy8b2#-*791ZoY#8x8FnITkfLpO}A6{#@i^o@)inS
zyRs7G>y}*fYO#2*{`c(0cY<%?`M&e|z8>}doqNIjRA=tSa@$^S$He^G2F6_zy71D9
z8*I^=@2E!Zet@F)Jwn0zAEoxU-=`^?DwKNVO$tA>ilPrcLGpc%j708wU_`&}{AGtQ
z*AK1z*Tp)-e{ZVqjV;gTPWk;j1<cVWo+V|~>fzWkFV&*Yze@S{Hqf|FKcgh#P+ok!
z7JL4+in99Un)>=Xq}+PX)eS#lf$?3S@%exAh(0w&-{Tz1sCU}grPrPqd-4U+)_qLc
zn)Rfu-B69KU0;o?SzpyY_|Izm!;O^qcoW4pd`jx7=dLOErrVkG|3dq3(_{2|dFAY@
zchR1D`O(Dt8!1&IO5?^1jE~7pHHxqM<dyj9H}slepa0+N%%F21{}|}s3#STUPOp4$
wa%%OP$0grde`#Xfr%MxWuRlqB>D@i#ONKm~@A(({4Qk-u|NgDO_g3J4007NtQUCw|

literal 0
HcmV?d00001


From f01487eb8351fba796ca65a821df8ad89eeb3415 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Tue, 16 Feb 2010 23:52:38 +1300
Subject: [PATCH 027/250] A few documentation fixes

---
 basis/math/vectors/simd/simd-docs.factor      | 24 ++++++++++++++++---
 basis/stack-checker/errors/errors-docs.factor |  6 ++---
 core/combinators/combinators-docs.factor      |  6 ++---
 core/sequences/sequences-docs.factor          |  4 +---
 4 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/basis/math/vectors/simd/simd-docs.factor b/basis/math/vectors/simd/simd-docs.factor
index 540838bdd5..bcc05564fc 100644
--- a/basis/math/vectors/simd/simd-docs.factor
+++ b/basis/math/vectors/simd/simd-docs.factor
@@ -8,7 +8,7 @@ ARTICLE: "math.vectors.simd.intro" "Introduction to SIMD support"
 $nl
 "SIMD support in the processor takes the form of instruction sets which operate on vector registers. By operating on multiple scalar values at the same time, code which operates on points, colors, and other vector data can be sped up."
 $nl
-"In Factor, SIMD support is exposed in the form of special-purpose SIMD " { $link "sequence-protocol" } " implementations. These are fixed-length, homogeneous sequences. They are referred to as vectors, but should not be confused with Factor's " { $link "vectors" } ", which can hold any type of object and can be resized.)."
+"In Factor, SIMD support is exposed in the form of special-purpose SIMD " { $link "sequence-protocol" } " implementations. These are fixed-length, homogeneous sequences. They are referred to as vectors, but should not be confused with Factor's " { $link "vectors" } ", which can hold any type of object and can be resized."
 $nl
 "The words in the " { $vocab-link "math.vectors" } " vocabulary, which can be used with any sequence of numbers, are special-cased by the compiler. If the compiler can prove that only SIMD vectors are used, it expands " { $link "math-vectors" } " into " { $link "math.vectors.simd.intrinsics" } ". While in the general case, SIMD intrinsics operate on heap-allocated SIMD vectors, that too can be optimized since in many cases the compiler unbox SIMD vectors, storing them directly in registers."
 $nl
@@ -36,7 +36,7 @@ $nl
 ARTICLE: "math.vectors.simd.types" "SIMD vector types"
 "Each SIMD vector type is named " { $snippet "scalar-count" } ", where " { $snippet "scalar" } " is a scalar C type and " { $snippet "count" } " is a vector dimension."
 $nl
-"The following vector types are available:"
+"The following 128-bit vector types are defined in the " { $vocab-link "math.vectors.simd" } " vocabulary:"
 { $code
     "char-16"
     "uchar-16"
@@ -48,6 +48,19 @@ $nl
     "ulonglong-2"
     "float-4"
     "double-2"
+}
+"Double-width 256-bit vector types are defined in the " { $vocab-link "math.vectors.simd.cords" } " vocabulary:"
+{ $code
+    "char-32"
+    "uchar-32"
+    "short-16"
+    "ushort-16"
+    "int-8"
+    "uint-8"
+    "longlong-4"
+    "ulonglong-4"
+    "float-8"
+    "double-4"
 } ;
 
 ARTICLE: "math.vectors.simd.words" "SIMD vector words"
@@ -142,7 +155,12 @@ M\\ actor advance optimized."""
 """USE: compiler.tree.debugger
 
 M\\ actor advance test-mr mr.""" }
-"An example of a high-performance algorithm that uses SIMD primitives can be found in the " { $vocab-link "benchmark.nbody-simd" } " vocabulary." ;
+"Example of a high-performance algorithms that use SIMD primitives can be found in the following vocabularies:"
+{ $list
+    { $vocab-link "benchmark.nbody-simd" }
+    { $vocab-link "benchmark.raytracer-simd" }
+    { $vocab-link "random.sfmt" }
+} ;
 
 ARTICLE: "math.vectors.simd.intrinsics" "Low-level SIMD primitives"
 "The words in the " { $vocab-link "math.vectors.simd.intrinsics" } " vocabulary are used to implement SIMD support. These words have three disadvantages compared to the higher-level " { $link "math-vectors" } " words:"
diff --git a/basis/stack-checker/errors/errors-docs.factor b/basis/stack-checker/errors/errors-docs.factor
index 4b432e733f..9aa7ed0d14 100644
--- a/basis/stack-checker/errors/errors-docs.factor
+++ b/basis/stack-checker/errors/errors-docs.factor
@@ -134,10 +134,10 @@ HELP: inconsistent-recursive-call-error
 } ;
 
 ARTICLE: "inference-errors" "Stack checker errors"
-"These " { $link "inference" } " failure conditions are reported in one of two ways:"
+"Stack effect checking failure conditions are reported in one of two ways:"
 { $list
-    { { $link "tools.inference" } " throws them as errors" }
-    { "The " { $link "compiler" } " reports them via " { $link "tools.errors" } }
+    { { $link "tools.inference" } " report them when fed quotations interactively" }
+    { "The " { $link "compiler" } " reports them while compiling words, via the " { $link "tools.errors" } " mechanism" }
 }
 "Errors thrown when insufficient information is available to calculate the stack effect of a call to a combinator or macro (see " { $link "inference-combinators" } "):"
 { $subsections
diff --git a/core/combinators/combinators-docs.factor b/core/combinators/combinators-docs.factor
index 02114496f4..31183a629e 100644
--- a/core/combinators/combinators-docs.factor
+++ b/core/combinators/combinators-docs.factor
@@ -176,15 +176,15 @@ ARTICLE: "conditionals" "Conditional combinators"
 { $subsections "conditionals-boolean-equivalence" }
 { $see-also "booleans" "bitwise-arithmetic" both? either? } ;
 
-ARTICLE: "dataflow-combinators" "Data flow combinators"
-"Data flow combinators express common dataflow patterns such as performing a operation while preserving its inputs, applying multiple operations to a single value, applying a set of operations to a set of values, or applying a single operation to multiple values."
+ARTICLE: "dataflow-combinators" "Dataflow combinators"
+"Dataflow combinators express common dataflow patterns such as performing a operation while preserving its inputs, applying multiple operations to a single value, applying a set of operations to a set of values, or applying a single operation to multiple values."
 { $subsections
     "dip-keep-combinators"
     "cleave-combinators"
     "spread-combinators"
     "apply-combinators"
 }
-"More intricate data flow can be constructed by composing " { $link "curried-dataflow" } "." ;
+"More intricate dataflow can be constructed by composing " { $link "curried-dataflow" } "." ;
 
 ARTICLE: "combinators-quot" "Quotation construction utilities"
 "Some words for creating quotations which can be useful for implementing method combinations and compiler transforms:"
diff --git a/core/sequences/sequences-docs.factor b/core/sequences/sequences-docs.factor
index 819b5b2115..02dadb323c 100644
--- a/core/sequences/sequences-docs.factor
+++ b/core/sequences/sequences-docs.factor
@@ -1416,9 +1416,7 @@ $nl
 ARTICLE: "sequences-integers" "Counted loops"
 "A virtual sequence is defined for iterating over integers from zero."
 { $subsection iota }
-"For example, calling " { $link iota } " on the integer 3 produces a sequence containing the elements 0, 1, and 2. This is very useful for performing counted loops."
-$nl
-"This means the " { $link each } " combinator, given an integer, simply calls a quotation that number of times, pushing a counter on each iteration that ranges from 0 up to that integer:"
+"For example, calling " { $link iota } " on the integer 3 produces a sequence containing the elements 0, 1, and 2. This is very useful for performing counted loops using words such as " { $link each } ":"
 { $example "3 iota [ . ] each" "0\n1\n2" }
 "A common idiom is to iterate over a sequence, while also maintaining a loop counter. This can be done using " { $link each-index } ", " { $link map-index } " and " { $link reduce-index } "."
 $nl

From bd0ca0e2aa61db6c1d966e2e7979f23136dd3627 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Wed, 17 Feb 2010 00:12:55 +1300
Subject: [PATCH 028/250] Clean up some tags

---
 basis/cocoa/tags.txt              | 1 +
 basis/images/tags.txt             | 2 +-
 basis/windows/com/tags.txt        | 1 +
 core/alien/tags.txt               | 1 +
 extra/annotations/tags.txt        | 3 +--
 extra/gpu/demos/bunny/tags.txt    | 1 +
 extra/gpu/demos/raytrace/tags.txt | 1 +
 extra/svg/tags.txt                | 1 -
 extra/terrain/tags.txt            | 1 +
 extra/trees/splay/tags.txt        | 1 -
 extra/trees/tags.txt              | 1 -
 extra/tty-server/tags.txt         | 2 +-
 extra/webapps/fjsc/tags.txt       | 3 ++-
 13 files changed, 11 insertions(+), 8 deletions(-)
 create mode 100644 extra/gpu/demos/bunny/tags.txt
 create mode 100644 extra/gpu/demos/raytrace/tags.txt
 create mode 100644 extra/terrain/tags.txt

diff --git a/basis/cocoa/tags.txt b/basis/cocoa/tags.txt
index 2320bdd648..86dd9eeb91 100644
--- a/basis/cocoa/tags.txt
+++ b/basis/cocoa/tags.txt
@@ -1,2 +1,3 @@
 unportable
 bindings
+ffi
diff --git a/basis/images/tags.txt b/basis/images/tags.txt
index 04b54a06f4..9347bd326b 100644
--- a/basis/images/tags.txt
+++ b/basis/images/tags.txt
@@ -1 +1 @@
-bitmap graphics
+graphics
diff --git a/basis/windows/com/tags.txt b/basis/windows/com/tags.txt
index 2320bdd648..86dd9eeb91 100755
--- a/basis/windows/com/tags.txt
+++ b/basis/windows/com/tags.txt
@@ -1,2 +1,3 @@
 unportable
 bindings
+ffi
diff --git a/core/alien/tags.txt b/core/alien/tags.txt
index 86a7c8e637..7ea420feed 100644
--- a/core/alien/tags.txt
+++ b/core/alien/tags.txt
@@ -1 +1,2 @@
 compiler
+ffi
diff --git a/extra/annotations/tags.txt b/extra/annotations/tags.txt
index 278296de5e..ef1aab0d0e 100644
--- a/extra/annotations/tags.txt
+++ b/extra/annotations/tags.txt
@@ -1,2 +1 @@
-comments
-annotation
+tools
diff --git a/extra/gpu/demos/bunny/tags.txt b/extra/gpu/demos/bunny/tags.txt
new file mode 100644
index 0000000000..cb5fc203e1
--- /dev/null
+++ b/extra/gpu/demos/bunny/tags.txt
@@ -0,0 +1 @@
+demos
diff --git a/extra/gpu/demos/raytrace/tags.txt b/extra/gpu/demos/raytrace/tags.txt
new file mode 100644
index 0000000000..cb5fc203e1
--- /dev/null
+++ b/extra/gpu/demos/raytrace/tags.txt
@@ -0,0 +1 @@
+demos
diff --git a/extra/svg/tags.txt b/extra/svg/tags.txt
index 0cf061a252..65e8f3eddb 100644
--- a/extra/svg/tags.txt
+++ b/extra/svg/tags.txt
@@ -1,3 +1,2 @@
 xml
 graphics
-svg
diff --git a/extra/terrain/tags.txt b/extra/terrain/tags.txt
new file mode 100644
index 0000000000..cb5fc203e1
--- /dev/null
+++ b/extra/terrain/tags.txt
@@ -0,0 +1 @@
+demos
diff --git a/extra/trees/splay/tags.txt b/extra/trees/splay/tags.txt
index fb6cea7147..42d711b32b 100644
--- a/extra/trees/splay/tags.txt
+++ b/extra/trees/splay/tags.txt
@@ -1,2 +1 @@
 collections
-trees
diff --git a/extra/trees/tags.txt b/extra/trees/tags.txt
index fb6cea7147..42d711b32b 100644
--- a/extra/trees/tags.txt
+++ b/extra/trees/tags.txt
@@ -1,2 +1 @@
 collections
-trees
diff --git a/extra/tty-server/tags.txt b/extra/tty-server/tags.txt
index 587fb228f3..8dfb43b578 100644
--- a/extra/tty-server/tags.txt
+++ b/extra/tty-server/tags.txt
@@ -1,4 +1,4 @@
 tools
 applications
 demos
-networking
+network
diff --git a/extra/webapps/fjsc/tags.txt b/extra/webapps/fjsc/tags.txt
index 1b93c9eb4d..14d6b62728 100644
--- a/extra/webapps/fjsc/tags.txt
+++ b/extra/webapps/fjsc/tags.txt
@@ -1 +1,2 @@
-webapp
+web
+examples

From 59bd725c378f4bff12affd8177deb9dddbe4c685 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Wed, 17 Feb 2010 00:13:08 +1300
Subject: [PATCH 029/250] websites.concatenative: fix mason web app invocation

---
 extra/websites/concatenative/concatenative.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/extra/websites/concatenative/concatenative.factor b/extra/websites/concatenative/concatenative.factor
index fd4fb7515f..92a4942fe6 100644
--- a/extra/websites/concatenative/concatenative.factor
+++ b/extra/websites/concatenative/concatenative.factor
@@ -98,7 +98,7 @@ SYMBOL: dh-file
         <login-config> <factor-boilerplate> test-db <alloy> "concatenative.org" add-responder
         <pastebin> <login-config> <factor-boilerplate> test-db <alloy> "paste.factorcode.org" add-responder
         <planet> <login-config> <factor-boilerplate> test-db <alloy> "planet.factorcode.org" add-responder
-        <mason-app> <login-config> "builds.factorcode.org" add-responder
+        <mason-app> <login-config> test-db <alloy> "builds.factorcode.org" add-responder
         home "docs" append-path <help-webapp> "docs.factorcode.org" add-responder
         home "cgi" append-path <gitweb> "gitweb.factorcode.org" add-responder
     main-responder set-global ;

From d8c452270596bad65be18dc58295a1635379ca05 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Tue, 16 Feb 2010 03:14:30 -0800
Subject: [PATCH 030/250] Fix docs typo

---
 basis/command-line/command-line-docs.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/command-line/command-line-docs.factor b/basis/command-line/command-line-docs.factor
index 11ee46c227..9a69614766 100644
--- a/basis/command-line/command-line-docs.factor
+++ b/basis/command-line/command-line-docs.factor
@@ -91,7 +91,7 @@ ARTICLE: "standard-cli-args" "Command line switches for general usage"
 } ;
 
 ARTICLE: "factor-boot-rc" "Bootstrap initialization file"
-"The botstrap initialization file is named " { $snippet "factor-boot-rc" } " on Windows and " { $snippet ".factor-boot-rc" } " on Unix. This file can contain " { $link require } " calls for vocabularies you use frequently, and other such long-running tasks that you do not want to perform every time Factor starts."
+"The bootstrap initialization file is named " { $snippet "factor-boot-rc" } " on Windows and " { $snippet ".factor-boot-rc" } " on Unix. This file can contain " { $link require } " calls for vocabularies you use frequently, and other such long-running tasks that you do not want to perform every time Factor starts."
 $nl
 "A word to run this file from an existing Factor session:"
 { $subsections run-bootstrap-init }

From 4c1cd406c909b967caa61ca31a92f966b64654b1 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Wed, 17 Feb 2010 00:16:08 +1300
Subject: [PATCH 031/250] Bump version number to 0.93

---
 Factor.app/Contents/Info.plist | 4 +++-
 GNUmakefile                    | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/Factor.app/Contents/Info.plist b/Factor.app/Contents/Info.plist
index c87520d0fd..1c07f95643 100644
--- a/Factor.app/Contents/Info.plist
+++ b/Factor.app/Contents/Info.plist
@@ -31,8 +31,10 @@
 	<string>Factor</string>
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
+	<key>CFBundleVersion</key>
+	<string>0.93</string>
 	<key>NSHumanReadableCopyright</key>
-	<string>Copyright © 2003-2009, Slava Pestov and friends</string>
+	<string>Copyright © 2003-2010 Factor developers</string>
 	<key>NSServices</key>
 	<array>
 		<dict>
diff --git a/GNUmakefile b/GNUmakefile
index c4796de63b..eac1c696df 100755
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -4,7 +4,7 @@ ifdef CONFIG
 	AR = ar
 	LD = ld
 
-	VERSION = 0.92
+	VERSION = 0.93
 
 	BUNDLE = Factor.app
 	LIBPATH = -L/usr/X11R6/lib

From c8192adf7113c996adb546c4e8a3fe8619b0ba08 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Tue, 16 Feb 2010 03:25:03 -0800
Subject: [PATCH 032/250] Fix some doc typos, metadata

---
 basis/db/tuples/tuples-docs.factor   | 2 +-
 core/classes/tuple/tuple-docs.factor | 2 +-
 extra/chipmunk/summary.txt           | 2 +-
 extra/chipmunk/tags.txt              | 1 +
 4 files changed, 4 insertions(+), 3 deletions(-)
 create mode 100644 extra/chipmunk/tags.txt

diff --git a/basis/db/tuples/tuples-docs.factor b/basis/db/tuples/tuples-docs.factor
index 01d65484f3..ebf86371a7 100644
--- a/basis/db/tuples/tuples-docs.factor
+++ b/basis/db/tuples/tuples-docs.factor
@@ -267,7 +267,7 @@ T{ book
 { $list
     "Make a new tuple to represent your data"
     { "Map the Factor types to the database types with " { $link define-persistent } }
-    { "Make a custom database combinator (see" { $link "db-custom-database-combinators" } ") to open your database and run a " { $link quotation } }
+    { "Make a custom database combinator (see " { $link "db-custom-database-combinators" } ") to open your database and run a " { $link quotation } }
     { "Create a table with " { $link create-table } ", " { $link ensure-table } ", or " { $link recreate-table } }
     { "Start making and storing objects with " { $link insert-tuple } ", " { $link update-tuple } ", " { $link delete-tuples } ", and " { $link select-tuples } }
 } ;
diff --git a/core/classes/tuple/tuple-docs.factor b/core/classes/tuple/tuple-docs.factor
index 2b3e80da1d..0fd7907492 100644
--- a/core/classes/tuple/tuple-docs.factor
+++ b/core/classes/tuple/tuple-docs.factor
@@ -440,4 +440,4 @@ HELP: boa
 { $values { "..." "slot values" } { "class" tuple-class } { "tuple" tuple } }
 { $description "Creates a new instance of " { $snippet "class" } " and fill in the slots from the stack, with the top-most stack element being stored in the right-most slot." }
 { $notes "The name " { $snippet "boa" } " is shorthand for “by order of arguments”, and “BOA constructor” is a pun on “boa constrictor”." }
-{ $errors "Throws an error if the slot values do not match class declarations on slots (see" { $link "tuple-declarations" } ")." } ;
+{ $errors "Throws an error if the slot values do not match class declarations on slots (see " { $link "tuple-declarations" } ")." } ;
diff --git a/extra/chipmunk/summary.txt b/extra/chipmunk/summary.txt
index ebc56a79ed..2859b353f2 100644
--- a/extra/chipmunk/summary.txt
+++ b/extra/chipmunk/summary.txt
@@ -1 +1 @@
-FFI bindings to the Chipmunk 2D physics library.
+Chipmunk 2D physics library binding
diff --git a/extra/chipmunk/tags.txt b/extra/chipmunk/tags.txt
new file mode 100644
index 0000000000..bb863cf9a0
--- /dev/null
+++ b/extra/chipmunk/tags.txt
@@ -0,0 +1 @@
+bindings

From 941c09d73a1f5d571a6a39255e03e0b896302c83 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Tue, 16 Feb 2010 03:26:36 -0800
Subject: [PATCH 033/250] Splines: catmull-rom, bezier curve, cubic hermite,
 kochanek-bartels

---
 extra/math/splines/authors.txt            |  1 +
 extra/math/splines/splines-docs.factor    | 44 ++++++++++++
 extra/math/splines/splines.factor         | 84 +++++++++++++++++++++++
 extra/math/splines/summary.txt            |  1 +
 extra/math/splines/testing/authors.txt    |  1 +
 extra/math/splines/testing/testing.factor | 49 +++++++++++++
 extra/math/splines/viewer/authors.txt     |  1 +
 extra/math/splines/viewer/viewer.factor   | 49 +++++++++++++
 8 files changed, 230 insertions(+)
 create mode 100644 extra/math/splines/authors.txt
 create mode 100644 extra/math/splines/splines-docs.factor
 create mode 100644 extra/math/splines/splines.factor
 create mode 100644 extra/math/splines/summary.txt
 create mode 100644 extra/math/splines/testing/authors.txt
 create mode 100644 extra/math/splines/testing/testing.factor
 create mode 100644 extra/math/splines/viewer/authors.txt
 create mode 100644 extra/math/splines/viewer/viewer.factor

diff --git a/extra/math/splines/authors.txt b/extra/math/splines/authors.txt
new file mode 100644
index 0000000000..6f03a12101
--- /dev/null
+++ b/extra/math/splines/authors.txt
@@ -0,0 +1 @@
+Erik Charlebois
diff --git a/extra/math/splines/splines-docs.factor b/extra/math/splines/splines-docs.factor
new file mode 100644
index 0000000000..62ff1418cd
--- /dev/null
+++ b/extra/math/splines/splines-docs.factor
@@ -0,0 +1,44 @@
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax math ;
+IN: math.splines
+
+HELP: <bezier-curve>
+{ $values
+    { "control-points" "sequence of control points same dimension" }
+    { "polynomials" "sequence of polynomials for each dimension" }
+}
+{ $description "Creates bezier curve polynomials for the given control points." } ;
+
+HELP: <catmull-rom-spline>
+{ $values
+    { "points" "points on the spline" } { "m0" "initial tangent vector" } { "mn" "final tangent vector" }
+    { "polynomials-sequence" "sequence of sequences of polynomials" }
+}
+{ $description "Creates a sequence of cubic hermite curves (each a sequence of polynomials) passing through the given points and generating tangents for C1 continuity." } ;
+
+HELP: <cubic-hermite-curve>
+{ $values
+    { "p0" "start point" } { "m0" "start tangent" } { "p1" "end point" } { "m1" "end tangent" }
+    { "polynomials" "sequence of polynomials" }
+}
+{ $description "Creates a sequence of polynomials (one per dimension) for the curve passing through " { $emphasis "p0" } " and " { $emphasis "p1" } "." } ;
+
+HELP: <cubic-hermite-spline>
+{ $values
+    { "point-tangent-pairs" "sequence of point and tangent pairs" }
+    { "polynomials-sequence" "sequence of sequences of polynomials" }
+}
+{ $description "Creates a sequence of cubic hermite curves (each a sequence of polynomials) passing through the given points with the given tangents." } ;
+
+HELP: <kochanek-bartels-curve>
+{ $values
+    { "points" "points on the spline" } { "m0" "start tangent" } { "mn" "end tangent" } { "tension" number } { "bias" number } { "continuity" number }
+    { "polynomials-sequence" "sequence of sequence of polynomials" }
+}
+{ $description "Creates a sequence of cubic hermite curves (each a sequence of polynomials) passing through the given points, generating tangents with the given tuning parameters." } ;
+
+ARTICLE: "math.splines" "Common parametric curves."
+"The curve creating functions create sequences of polynomials, one for each degree of the input points. The spline creating functions create sequences of these curve polynomial sequences. The " { $vocab-link "math.splines.viewer" } " vocabulary provides a gadget to evaluate the generated polynomials and view the results.";
+
+ABOUT: "math.splines"
diff --git a/extra/math/splines/splines.factor b/extra/math/splines/splines.factor
new file mode 100644
index 0000000000..dc22224416
--- /dev/null
+++ b/extra/math/splines/splines.factor
@@ -0,0 +1,84 @@
+! Copyright (C) 2010 Erik Charlebois
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators kernel locals math math.combinatorics
+math.polynomials opengl.gl sequences ui.gadgets ui.gadgets.panes
+ui.render arrays grouping math.vectors assocs
+ui.gestures ;
+IN: math.splines
+
+<PRIVATE
+:: bernstein-polynomial-ith ( n i -- p )
+    n i nCk { 0 1 } i p^ { 1 -1 } n i - p^ p* n*p ;
+
+:: hermite-polynomial ( p0 m0 p1 m1 -- poly )
+    p0
+    m0 
+    -3 p0 * -2 m0 * + 3 p1 * + m1 neg +
+    2 p0 * m0 + -2 p1 * + m1 +
+    4array ;
+
+:: kochanek-bartels-coefficients ( tension bias continuity -- s1 d1 s2 d2 )
+    1 tension -
+    [
+        1 bias +
+        [ 1 continuity + * * 2 / ]
+        [ 1 continuity - * * 2 / ] 2bi
+    ]
+    [
+        1 bias -
+        [ 1 continuity - * * 2 / ]
+        [ 1 continuity + * * 2 / ] 2bi
+    ] bi ;
+
+:: kochanek-bartels-tangents ( points m0 mn c1 c2 -- tangents )
+    points 3 clump [
+        first3 :> ( pi-1 pi pi+1 )
+        pi pi-1 v- c1 v*n
+        pi+1 pi v- c2 v*n v+
+    ] map
+    m0 prefix
+    mn suffix ;
+PRIVATE>
+
+:: <bezier-curve> ( control-points -- polynomials )
+    control-points
+    [ length 1 - ]
+    [ first length [ { 0 } ] replicate ]
+    bi :> ( n acc )
+
+    control-points [| pt i |
+        n i bernstein-polynomial-ith :> poly
+        pt [| v j |
+            j acc [ v poly n*p p+ ] change-nth
+        ] each-index
+    ] each-index
+    acc ;
+    
+:: <cubic-hermite-curve> ( p0 m0 p1 m1 -- polynomials )
+    p0 length iota [
+        {
+            [ p0 nth ] [ m0 nth ]
+            [ p1 nth ] [ m1 nth ]
+        } cleave
+        hermite-polynomial
+    ] map ;
+
+<PRIVATE
+: (cubic-hermite-spline) ( point-in-out-triplets -- polynomials-sequence )
+    2 clump [
+        first2 [ first2 ] [ [ first ] [ third ] bi ] bi* <cubic-hermite-curve>
+    ] map ;
+PRIVATE>
+
+: <cubic-hermite-spline> ( point-tangent-pairs -- polynomials-sequence )
+    2 clump [ first2 [ first2 ] bi@ <cubic-hermite-curve> ] map ;
+
+:: <kochanek-bartels-curve> ( points m0 mn tension bias continuity -- polynomials-sequence )
+    tension bias continuity kochanek-bartels-coefficients :> ( s1 d1 s2 d2 )
+    points m0 mn
+    [ s1 s2 kochanek-bartels-tangents ]
+    [ d1 d2 kochanek-bartels-tangents ] 3bi :> ( in out )
+    points in out [ 3array ] 3map (cubic-hermite-spline) ;
+
+: <catmull-rom-spline> ( points m0 mn -- polynomials-sequence )
+    0 0 0 <kochanek-bartels-curve> ;
diff --git a/extra/math/splines/summary.txt b/extra/math/splines/summary.txt
new file mode 100644
index 0000000000..229b05edc9
--- /dev/null
+++ b/extra/math/splines/summary.txt
@@ -0,0 +1 @@
+Common parametric curves
diff --git a/extra/math/splines/testing/authors.txt b/extra/math/splines/testing/authors.txt
new file mode 100644
index 0000000000..67cf648cf5
--- /dev/null
+++ b/extra/math/splines/testing/authors.txt
@@ -0,0 +1 @@
+Erik Charlebois
\ No newline at end of file
diff --git a/extra/math/splines/testing/testing.factor b/extra/math/splines/testing/testing.factor
new file mode 100644
index 0000000000..bbb5cd6a6a
--- /dev/null
+++ b/extra/math/splines/testing/testing.factor
@@ -0,0 +1,49 @@
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: locals math.splines math.splines.viewer arrays ;
+IN: math.splines.testing
+
+: test1 ( -- )
+    {
+        { { 0 0 } { 0 200 } }
+        { { 100 50 } { 0 -200 } }
+        { { 300 300 } { 500 200 } }
+        { { 400 400 } { 300 0 } }
+    } <cubic-hermite-spline> { 50 100 } 4 spline. ;
+
+: test2 ( -- )
+    {
+        { 50 50 }
+        { 100 100 }
+        { 300 200 }
+        { 350 0 }
+        { 400 400 }
+    } { 0 100 } { 100 0 } <catmull-rom-spline> { 100 50 } 50 spline. ;
+
+:: test3 ( x y z -- )
+    {
+        { 100 50 }
+        { 200 350 }
+        { 300 50 }
+    } { 0 100 } { 0 -100 } x y z <kochanek-bartels-curve> { 50 50 } 1000 spline. ;
+
+: test4 ( -- )
+    {
+        { 0 5 }
+        { 0.5 3 }
+        { 10 10 }
+        { 12 4 }
+        { 15 5 }
+    } <bezier-curve> 1array { 100 100 } 100 spline. ;
+
+: test-splines ( -- )
+    test1 test2
+    1 0 0 test3
+    -1 0 0 test3
+    0 1 0 test3
+    0 -1 0 test3
+    0 0 1 test3
+    0 0 -1 test3
+    test4 ;
+    
+
diff --git a/extra/math/splines/viewer/authors.txt b/extra/math/splines/viewer/authors.txt
new file mode 100644
index 0000000000..67cf648cf5
--- /dev/null
+++ b/extra/math/splines/viewer/authors.txt
@@ -0,0 +1 @@
+Erik Charlebois
\ No newline at end of file
diff --git a/extra/math/splines/viewer/viewer.factor b/extra/math/splines/viewer/viewer.factor
new file mode 100644
index 0000000000..f1ec1a2445
--- /dev/null
+++ b/extra/math/splines/viewer/viewer.factor
@@ -0,0 +1,49 @@
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel locals math math.order math.polynomials
+math.splines opengl.gl sequences ui.gadgets ui.gadgets.panes ui.render
+arrays ;
+IN: math.splines.viewer
+
+<PRIVATE
+: eval-polynomials ( polynomials-seq n -- xy-sequence )
+    [
+        [ 1 + iota ] keep [
+            /f swap [ polyval ] with map
+        ] curry with map
+    ] curry map concat ;
+PRIVATE>
+
+TUPLE: spline-gadget < gadget polynomials steps spline-dim ;
+
+M: spline-gadget pref-dim* spline-dim>> ;
+
+M:: spline-gadget draw-gadget* ( gadget -- )
+    0 0 0 glColor3f
+
+    gadget [ polynomials>> ] [ steps>> ] bi eval-polynomials :> pts
+
+    pts [ first ] [ max ] map-reduce  :> x-max
+    pts [ first ] [ min ] map-reduce  :> x-min
+    pts [ second ] [ max ] map-reduce :> y-max
+    pts [ second ] [ min ] map-reduce :> y-min
+
+    pts [
+        [ first x-min - x-max x-min - / gadget spline-dim>> first * ]
+        [ second y-min - y-max y-min - / gadget spline-dim>> second * ] bi 2array
+    ] map :> pts
+    
+    GL_LINE_STRIP glBegin
+    pts [
+        first2 neg gadget spline-dim>> second + glVertex2f
+    ] each
+    glEnd ;
+
+:: <spline-gadget> ( polynomials dim steps -- gadget )
+    spline-gadget new
+    dim >>spline-dim
+    polynomials >>polynomials 
+    steps >>steps ;
+
+: spline. ( curve dim steps -- )
+    <spline-gadget> gadget. ; 

From 55cf38163f1b9cc3ce5368b90f96a9041240398a Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Wed, 17 Feb 2010 00:32:53 +1300
Subject: [PATCH 034/250] inverse: remove unnecessary dependency on debugger

---
 basis/inverse/inverse.factor | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/basis/inverse/inverse.factor b/basis/inverse/inverse.factor
index d112e4e6eb..3485b3efa7 100644
--- a/basis/inverse/inverse.factor
+++ b/basis/inverse/inverse.factor
@@ -1,10 +1,10 @@
 ! Copyright (C) 2007, 2009 Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel locals words summary slots quotations
-sequences assocs math arrays stack-checker effects
-continuations debugger classes.tuple namespaces make vectors
-bit-arrays byte-arrays strings sbufs math.functions macros
-sequences.private combinators mirrors splitting combinators.smart
+sequences assocs math arrays stack-checker effects continuations
+classes.tuple namespaces make vectors bit-arrays byte-arrays
+strings sbufs math.functions macros sequences.private
+combinators mirrors splitting combinators.smart
 combinators.short-circuit fry words.symbol generalizations
 classes ;
 IN: inverse

From 177e741ea073b0c4982f5317224284ba7394f94d Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Wed, 17 Feb 2010 00:33:08 +1300
Subject: [PATCH 035/250] tools.deploy: add deploy tests for gpu.demos.raytrace
 and gpu.demos.bunny

---
 basis/tools/deploy/deploy-tests.factor | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/basis/tools/deploy/deploy-tests.factor b/basis/tools/deploy/deploy-tests.factor
index 987b4aa8a1..8e25afdcfe 100644
--- a/basis/tools/deploy/deploy-tests.factor
+++ b/basis/tools/deploy/deploy-tests.factor
@@ -24,8 +24,12 @@ IN: tools.deploy.tests
 
 [ ] [ "terrain" shake-and-bake 1700000 small-enough? ] unit-test
 
+[ ] [ "gpu.demos.raytrace" shake-and-bake 2500000 small-enough? ] unit-test
+
 [ ] [ "bunny" shake-and-bake 2500000 small-enough? ] unit-test
 
+[ ] [ "gpu.demos.bunny" shake-and-bake 3500000 small-enough? ] unit-test
+
 os macosx? [
     [ ] [ "webkit-demo" shake-and-bake 500000 small-enough? ] unit-test
 ] when

From 5557353f97a67b5791d149f0b20d7584e0023857 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Wed, 17 Feb 2010 01:52:09 +1300
Subject: [PATCH 036/250] tools.deploy.windows.ico: add unportable tag so that
 load-all doesn't load Win32 bindings on non-Windows platforms

---
 basis/tools/deploy/windows/ico/tags.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 basis/tools/deploy/windows/ico/tags.txt

diff --git a/basis/tools/deploy/windows/ico/tags.txt b/basis/tools/deploy/windows/ico/tags.txt
new file mode 100644
index 0000000000..6bf68304bb
--- /dev/null
+++ b/basis/tools/deploy/windows/ico/tags.txt
@@ -0,0 +1 @@
+unportable

From 4b41d8e83e93807439749ae9c8d6c42755cd2217 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Wed, 17 Feb 2010 01:52:16 +1300
Subject: [PATCH 037/250] vocabs.metadata.resources: fix help lint

---
 basis/vocabs/metadata/resources/resources-docs.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/vocabs/metadata/resources/resources-docs.factor b/basis/vocabs/metadata/resources/resources-docs.factor
index b4289ff388..a20775e937 100644
--- a/basis/vocabs/metadata/resources/resources-docs.factor
+++ b/basis/vocabs/metadata/resources/resources-docs.factor
@@ -16,7 +16,7 @@ HELP: vocab-resource-files
 }
 { $description "Outputs a sequence containing the individual resource files and directories that match the patterns specified in " { $snippet "vocab" } "'s " { $snippet "resources.txt" } " file. Any matching directories will also have their contents recursively included in the output. The paths in the output will be relative to " { $snippet "vocab" } "'s directory." } ;
 
-ARTICLE: "vocabs.metadata.resources" "vocabs.metadata.resources"
+ARTICLE: "vocabs.metadata.resources" "Vocabulary resource metadata"
 "The " { $vocab-link "vocabs.metadata.resources" } " vocabulary contains words to retrieve the full list of files that match the patterns specified in a vocabulary's " { $snippet "resources.txt" } " file."
 { $subsections
     vocab-resource-files

From 25b93af7df84bf81dfc851d690a95247759cb85a Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 10:29:18 -0800
Subject: [PATCH 038/250] git doesn't track empty directories. remove that from
 the vocab.metadata.resources tests

---
 basis/vocabs/metadata/resources/resources-tests.factor | 1 -
 1 file changed, 1 deletion(-)

diff --git a/basis/vocabs/metadata/resources/resources-tests.factor b/basis/vocabs/metadata/resources/resources-tests.factor
index 36fd13125e..5c50406a26 100644
--- a/basis/vocabs/metadata/resources/resources-tests.factor
+++ b/basis/vocabs/metadata/resources/resources-tests.factor
@@ -14,6 +14,5 @@ IN: vocabs.metadata.resources.tests
     "resource-dir/bas"
     "resource-dir/bas/zang"
     "resource-dir/bas/zim"
-    "resource-dir/buh"
     "resource-dir/foo"
 } ] [ "vocabs.metadata.resources.test.3" vocab-resource-files natural-sort ] unit-test

From bf7371c32ecdf18bfc75f84e7ff39cd698ce7fad Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 10:30:20 -0800
Subject: [PATCH 039/250] reduce reflection level on gpu.demos.bunny deployment
 to hopefully get it back below the tools.deploy test limit size

---
 extra/gpu/demos/bunny/deploy.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/extra/gpu/demos/bunny/deploy.factor b/extra/gpu/demos/bunny/deploy.factor
index 1289caadb6..048d710a41 100644
--- a/extra/gpu/demos/bunny/deploy.factor
+++ b/extra/gpu/demos/bunny/deploy.factor
@@ -6,7 +6,7 @@ H{
     { deploy-unicode? f }
     { "stop-after-last-window?" t }
     { deploy-io 3 }
-    { deploy-reflection 2 }
+    { deploy-reflection 1 }
     { deploy-word-props? f }
     { deploy-math? t }
     { deploy-threads? t }

From fcbeb3467d39f0bedf022046121a95141ae9ff92 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Tue, 16 Feb 2010 10:33:19 -0800
Subject: [PATCH 040/250] Line endings

---
 basis/tools/deploy/deploy-tests.factor | 250 ++++++++++++-------------
 1 file changed, 125 insertions(+), 125 deletions(-)

diff --git a/basis/tools/deploy/deploy-tests.factor b/basis/tools/deploy/deploy-tests.factor
index 987b4aa8a1..f76ad7a557 100644
--- a/basis/tools/deploy/deploy-tests.factor
+++ b/basis/tools/deploy/deploy-tests.factor
@@ -1,125 +1,125 @@
-USING: tools.test system io io.encodings.ascii io.pathnames
-io.files io.files.info io.files.temp kernel tools.deploy.config
-tools.deploy.config.editor tools.deploy.backend math sequences
-io.launcher arrays namespaces continuations layouts accessors
-urls math.parser io.directories tools.deploy.test ;
-IN: tools.deploy.tests
-
-[ ] [ "hello-world" shake-and-bake 500000 small-enough? ] unit-test
-
-[ ] [ "sudoku" shake-and-bake 800000 small-enough? ] unit-test
-
-[ ] [ "hello-ui" shake-and-bake 1300000 small-enough? ] unit-test
-
-[ "staging.math-threads-compiler-ui.image" ] [
-    "hello-ui" deploy-config
-    [ bootstrap-profile staging-image-name file-name ] bind
-] unit-test
-
-[ ] [ "maze" shake-and-bake 1200000 small-enough? ] unit-test
-
-[ ] [ "tetris" shake-and-bake 1500000 small-enough? ] unit-test
-
-[ ] [ "spheres" shake-and-bake 1500000 small-enough? ] unit-test
-
-[ ] [ "terrain" shake-and-bake 1700000 small-enough? ] unit-test
-
-[ ] [ "bunny" shake-and-bake 2500000 small-enough? ] unit-test
-
-os macosx? [
-    [ ] [ "webkit-demo" shake-and-bake 500000 small-enough? ] unit-test
-] when
-
-[ ] [ "benchmark.regex-dna" shake-and-bake 900000 small-enough? ] unit-test
-
-{
-    "tools.deploy.test.1"
-    "tools.deploy.test.2"
-    "tools.deploy.test.3"
-    "tools.deploy.test.4"
-} [
-    [ ] swap [
-        shake-and-bake
-        run-temp-image
-    ] curry unit-test
-] each
-
-USING: http.client http.server http.server.dispatchers
-http.server.responses http.server.static io.servers.connection ;
-
-SINGLETON: quit-responder
-
-M: quit-responder call-responder*
-    2drop stop-this-server "Goodbye" "text/html" <content> ;
-
-: add-quot-responder ( responder -- responder )
-    quit-responder "quit" add-responder ;
-
-: test-httpd ( responder -- )
-    [
-        main-responder set
-        <http-server>
-            0 >>insecure
-            f >>secure
-        dup start-server*
-        sockets>> first addr>> port>>
-        dup number>string "resource:temp/port-number" ascii set-file-contents
-    ] with-scope
-    "port" set ;
-
-[ ] [
-    <dispatcher>
-        add-quot-responder
-        "vocab:http/test" <static> >>default
-
-    test-httpd
-] unit-test
-
-[ ] [
-    "tools.deploy.test.5" shake-and-bake
-    run-temp-image
-] unit-test
-
-: add-port ( url -- url' )
-    >url clone "port" get >>port ;
-
-[ ] [ "http://localhost/quit" add-port http-get 2drop ] unit-test
-
-{
-    "tools.deploy.test.6"
-    "tools.deploy.test.7"
-    "tools.deploy.test.9"
-    "tools.deploy.test.10"
-    "tools.deploy.test.11"
-    "tools.deploy.test.12"
-} [
-    [ ] swap [
-        shake-and-bake
-        run-temp-image
-    ] curry unit-test
-] each
-
-os windows? os macosx? or [
-    [ ] [ "tools.deploy.test.8" shake-and-bake run-temp-image ] unit-test
-] when
-
-os macosx? [
-    [ ] [ "tools.deploy.test.14" shake-and-bake run-temp-image ] unit-test
-] when
-
-[ { "a" "b" "c" } ] [
-    "tools.deploy.test.15" shake-and-bake deploy-test-command
-    { "a" "b" "c" } append
-    ascii [ lines ] with-process-reader
-    rest
-] unit-test
-
-[ ] [ "tools.deploy.test.16" shake-and-bake run-temp-image ] unit-test
-
-[ ] [ "tools.deploy.test.17" shake-and-bake run-temp-image ] unit-test
-
-[ t ] [
-    "tools.deploy.test.18" shake-and-bake
-    deploy-test-command ascii [ readln ] with-process-reader
-    "test.image" temp-file =
-] unit-test
+USING: tools.test system io io.encodings.ascii io.pathnames
+io.files io.files.info io.files.temp kernel tools.deploy.config
+tools.deploy.config.editor tools.deploy.backend math sequences
+io.launcher arrays namespaces continuations layouts accessors
+urls math.parser io.directories tools.deploy.test ;
+IN: tools.deploy.tests
+
+[ ] [ "hello-world" shake-and-bake 500000 small-enough? ] unit-test
+
+[ ] [ "sudoku" shake-and-bake 800000 small-enough? ] unit-test
+
+[ ] [ "hello-ui" shake-and-bake 1300000 small-enough? ] unit-test
+
+[ "staging.math-threads-compiler-ui.image" ] [
+    "hello-ui" deploy-config
+    [ bootstrap-profile staging-image-name file-name ] bind
+] unit-test
+
+[ ] [ "maze" shake-and-bake 1200000 small-enough? ] unit-test
+
+[ ] [ "tetris" shake-and-bake 1500000 small-enough? ] unit-test
+
+[ ] [ "spheres" shake-and-bake 1500000 small-enough? ] unit-test
+
+[ ] [ "terrain" shake-and-bake 1700000 small-enough? ] unit-test
+
+[ ] [ "bunny" shake-and-bake 2500000 small-enough? ] unit-test
+
+os macosx? [
+    [ ] [ "webkit-demo" shake-and-bake 500000 small-enough? ] unit-test
+] when
+
+[ ] [ "benchmark.regex-dna" shake-and-bake 900000 small-enough? ] unit-test
+
+{
+    "tools.deploy.test.1"
+    "tools.deploy.test.2"
+    "tools.deploy.test.3"
+    "tools.deploy.test.4"
+} [
+    [ ] swap [
+        shake-and-bake
+        run-temp-image
+    ] curry unit-test
+] each
+
+USING: http.client http.server http.server.dispatchers
+http.server.responses http.server.static io.servers.connection ;
+
+SINGLETON: quit-responder
+
+M: quit-responder call-responder*
+    2drop stop-this-server "Goodbye" "text/html" <content> ;
+
+: add-quot-responder ( responder -- responder )
+    quit-responder "quit" add-responder ;
+
+: test-httpd ( responder -- )
+    [
+        main-responder set
+        <http-server>
+            0 >>insecure
+            f >>secure
+        dup start-server*
+        sockets>> first addr>> port>>
+        dup number>string "resource:temp/port-number" ascii set-file-contents
+    ] with-scope
+    "port" set ;
+
+[ ] [
+    <dispatcher>
+        add-quot-responder
+        "vocab:http/test" <static> >>default
+
+    test-httpd
+] unit-test
+
+[ ] [
+    "tools.deploy.test.5" shake-and-bake
+    run-temp-image
+] unit-test
+
+: add-port ( url -- url' )
+    >url clone "port" get >>port ;
+
+[ ] [ "http://localhost/quit" add-port http-get 2drop ] unit-test
+
+{
+    "tools.deploy.test.6"
+    "tools.deploy.test.7"
+    "tools.deploy.test.9"
+    "tools.deploy.test.10"
+    "tools.deploy.test.11"
+    "tools.deploy.test.12"
+} [
+    [ ] swap [
+        shake-and-bake
+        run-temp-image
+    ] curry unit-test
+] each
+
+os windows? os macosx? or [
+    [ ] [ "tools.deploy.test.8" shake-and-bake run-temp-image ] unit-test
+] when
+
+os macosx? [
+    [ ] [ "tools.deploy.test.14" shake-and-bake run-temp-image ] unit-test
+] when
+
+[ { "a" "b" "c" } ] [
+    "tools.deploy.test.15" shake-and-bake deploy-test-command
+    { "a" "b" "c" } append
+    ascii [ lines ] with-process-reader
+    rest
+] unit-test
+
+[ ] [ "tools.deploy.test.16" shake-and-bake run-temp-image ] unit-test
+
+[ ] [ "tools.deploy.test.17" shake-and-bake run-temp-image ] unit-test
+
+[ t ] [
+    "tools.deploy.test.18" shake-and-bake
+    deploy-test-command ascii [ readln ] with-process-reader
+    "test.image" temp-file =
+] unit-test

From 9af0f8d426262e6ff9c46d9b770199c031332973 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 10:33:21 -0800
Subject: [PATCH 041/250] fix globs tests

---
 basis/globs/globs.factor | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/basis/globs/globs.factor b/basis/globs/globs.factor
index 72b686c3b1..9cd6a73891 100644
--- a/basis/globs/globs.factor
+++ b/basis/globs/globs.factor
@@ -1,11 +1,11 @@
 ! Copyright (C) 2007, 2009 Slava Pestov, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: sequences io.pathnames kernel regexp.combinators
-strings unicode.case peg.ebnf regexp arrays ;
+strings splitting system unicode.case peg.ebnf regexp arrays ;
 IN: globs
 
 : not-path-separator ( -- sep )
-    "[^" path-separator "]" 3append <regexp> ; foldable
+    os windows? R! [^/\\]! R! [^/]! ? ; foldable
 
 EBNF: <glob>
 
@@ -48,5 +48,5 @@ Main = Concatenation End
     [ "\\*?[{" member? ] any? ;
 
 : glob-parent-directory ( glob -- parent-directory )
-    path-components dup [ glob-pattern? ] find drop head
+    path-separator split harvest dup [ glob-pattern? ] find drop head
     path-separator join ;

From 42089b6586f51485e2f446385c471b00278c245e Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 13:32:14 -0800
Subject: [PATCH 042/250] alien.libraries: add a "deploy-library" word that
 marks a library to have its dll deployed with applications that use it. add
 support to tools.deploy to find and copy deployed libraries into target
 bundle

---
 basis/alien/libraries/libraries-docs.factor   | 11 +++++++-
 basis/alien/libraries/libraries.factor        | 24 ++++++++++++++++--
 basis/tools/deploy/backend/backend.factor     | 25 ++++++++++++++++---
 basis/tools/deploy/libraries/libraries.factor | 11 ++++++++
 basis/tools/deploy/libraries/tags.txt         |  1 +
 basis/tools/deploy/libraries/unix/tags.txt    |  1 +
 basis/tools/deploy/libraries/unix/unix.factor | 16 ++++++++++++
 .../deploy/libraries/windows/windows.factor   | 16 ++++++++++++
 basis/tools/deploy/macosx/macosx.factor       |  4 ++-
 basis/tools/deploy/shaker/shaker.factor       | 22 ++++++++++++++--
 basis/tools/deploy/unix/unix.factor           |  2 +-
 basis/tools/deploy/windows/windows.factor     |  2 +-
 basis/windows/kernel32/kernel32.factor        |  7 ++++--
 13 files changed, 129 insertions(+), 13 deletions(-)
 create mode 100644 basis/tools/deploy/libraries/libraries.factor
 create mode 100644 basis/tools/deploy/libraries/tags.txt
 create mode 100644 basis/tools/deploy/libraries/unix/tags.txt
 create mode 100644 basis/tools/deploy/libraries/unix/unix.factor
 create mode 100644 basis/tools/deploy/libraries/windows/windows.factor

diff --git a/basis/alien/libraries/libraries-docs.factor b/basis/alien/libraries/libraries-docs.factor
index 245565d9ed..59142733b9 100644
--- a/basis/alien/libraries/libraries-docs.factor
+++ b/basis/alien/libraries/libraries-docs.factor
@@ -60,6 +60,10 @@ $nl
 }
 "Note the parse time evaluation with " { $link POSTPONE: << } "." } ;
 
+HELP: deploy-library
+{ $values { "name" string } }
+{ $description "Specifies that the logical library named " { $snippet "name" } " should be included during " { $link "tools.deploy" } ". " { $snippet "name" } " must be the name of a library previously loaded with " { $link add-library } "." } ;
+
 HELP: remove-library
 { $values { "name" string } }
 { $description "Unloads a library and removes it from the internal list of libraries. The " { $snippet "name" } " parameter should be a name that was previously passed to " { $link add-library } ". If no library with that name exists, this word does nothing." } ;
@@ -72,4 +76,9 @@ ARTICLE: "loading-libs" "Loading native libraries"
 }
 "Once a library has been defined, you can try loading it to see if the path name is correct:"
 { $subsections load-library }
-"If the compiler cannot load a library, or cannot resolve a symbol in a library, a linkage error is reported using the compiler error mechanism (see " { $link "compiler-errors" } "). Once you install the right library, reload the source file containing the " { $link add-library } " form to force the compiler to try loading the library again." ;
+"If the compiler cannot load a library, or cannot resolve a symbol in a library, a linkage error is reported using the compiler error mechanism (see " { $link "compiler-errors" } "). Once you install the right library, reload the source file containing the " { $link add-library } " form to force the compiler to try loading the library again."
+$nl
+"Libraries that do not come standard with the operating system need to be included with deployed applications that use them. A word is provided to instruct " { $link "tools.deploy" } " that a library must be so deployed:"
+{ $subsections
+    deploy-library
+} ;
diff --git a/basis/alien/libraries/libraries.factor b/basis/alien/libraries/libraries.factor
index 0d255b8d07..6f80900da0 100644
--- a/basis/alien/libraries/libraries.factor
+++ b/basis/alien/libraries/libraries.factor
@@ -1,7 +1,7 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors alien alien.strings assocs io.backend
-kernel namespaces destructors ;
+kernel namespaces destructors sequences system io.pathnames ;
 IN: alien.libraries
 
 : dlopen ( path -- dll ) native-string>alien (dlopen) ;
@@ -9,11 +9,15 @@ IN: alien.libraries
 : dlsym ( name dll -- alien ) [ string>symbol ] dip (dlsym) ;
 
 SYMBOL: libraries
+SYMBOL: deploy-libraries
 
 libraries [ H{ } clone ] initialize
+deploy-libraries [ V{ } clone ] initialize
 
 TUPLE: library path abi dll ;
 
+ERROR: no-library name ;
+
 : library ( name -- library ) libraries get at ;
 
 : <library> ( path abi -- library )
@@ -31,4 +35,20 @@ M: library dispose dll>> [ dispose ] when* ;
 
 : add-library ( name path abi -- )
     [ 2drop remove-library ]
-    [ <library> swap libraries get set-at ] 3bi ;
\ No newline at end of file
+    [ <library> swap libraries get set-at ] 3bi ;
+
+: deploy-library ( name -- )
+    dup libraries get key?
+    [ deploy-libraries get 2dup member? [ 2drop ] [ push ] if ]
+    [ no-library ] if ;
+
+<PRIVATE
+HOOK: >deployed-library-path os ( path -- path' )
+
+M: windows >deployed-library-path
+    file-name ;
+M: unix >deployed-library-path
+    file-name "$ORIGIN" prepend-path ;
+M: macosx >deployed-library-path
+    file-name "@executable_path/../Frameworks" prepend-path ;
+PRIVATE>
diff --git a/basis/tools/deploy/backend/backend.factor b/basis/tools/deploy/backend/backend.factor
index 9d6b8d4c08..4a4037d754 100644
--- a/basis/tools/deploy/backend/backend.factor
+++ b/basis/tools/deploy/backend/backend.factor
@@ -8,14 +8,27 @@ io.streams.c io.files io.files.temp io.pathnames io.directories
 io.directories.hierarchy io.backend quotations io.launcher
 tools.deploy.config tools.deploy.config.editor bootstrap.image
 io.encodings.utf8 destructors accessors hashtables
-vocabs.metadata.resources ;
+tools.deploy.libraries vocabs.metadata.resources ;
 IN: tools.deploy.backend
 
 : copy-vm ( executable bundle-name -- vm )
     prepend-path vm over copy-file ;
 
+TUPLE: vocab-manifest vocabs libraries ;
+
 : copy-resources ( manifest name dir -- )
-    append-path swap [ copy-vocab-resources ] with each ;
+    append-path swap vocabs>> [ copy-vocab-resources ] with each ;
+
+ERROR: cant-deploy-library-file library ;
+<PRIVATE
+: copy-library ( dir library -- )
+    dup find-library-file
+    [ nip swap over file-name append-path copy-file ]
+    [ cant-deploy-library-file ] if* ;
+PRIVATE>
+
+: copy-libraries ( manifest name dir -- )
+    append-path swap libraries>> [ copy-library ] with each ;
 
 : image-name ( vocab bundle-name -- str )
     prepend-path ".image" append ;
@@ -99,10 +112,16 @@ DEFER: ?make-staging-image
         ] { } make
     ] bind ;
 
+: parse-vocab-manifest-file ( path -- vocab-manifest )
+    utf8 file-lines
+    dup first "VOCABS:" =
+    [ "LIBRARIES:" split1 vocab-manifest boa ]
+    [ "invalid vocab manifest!" throw ] if ;
+
 : make-deploy-image ( vm image vocab config -- manifest )
     make-boot-image
     over "vocab-manifest-" prepend temp-file
     [ swap deploy-command-line run-factor ]
-    [ utf8 file-lines ] bi ;
+    [ parse-vocab-manifest-file ] bi ;
 
 HOOK: deploy* os ( vocab -- )
diff --git a/basis/tools/deploy/libraries/libraries.factor b/basis/tools/deploy/libraries/libraries.factor
new file mode 100644
index 0000000000..36fe3037de
--- /dev/null
+++ b/basis/tools/deploy/libraries/libraries.factor
@@ -0,0 +1,11 @@
+! (c)2010 Joe Groff bsd license
+USING: alien.libraries io.pathnames io.pathnames.private kernel
+system vocabs.loader ;
+IN: tools.deploy.libraries
+
+HOOK: find-library-file os ( file -- path )
+
+os windows?
+"tools.deploy.libraries.windows"
+"tools.deploy.libraries.unix" ? require
+
diff --git a/basis/tools/deploy/libraries/tags.txt b/basis/tools/deploy/libraries/tags.txt
new file mode 100644
index 0000000000..6bf68304bb
--- /dev/null
+++ b/basis/tools/deploy/libraries/tags.txt
@@ -0,0 +1 @@
+unportable
diff --git a/basis/tools/deploy/libraries/unix/tags.txt b/basis/tools/deploy/libraries/unix/tags.txt
new file mode 100644
index 0000000000..6bf68304bb
--- /dev/null
+++ b/basis/tools/deploy/libraries/unix/tags.txt
@@ -0,0 +1 @@
+unportable
diff --git a/basis/tools/deploy/libraries/unix/unix.factor b/basis/tools/deploy/libraries/unix/unix.factor
new file mode 100644
index 0000000000..6c3dbb4d91
--- /dev/null
+++ b/basis/tools/deploy/libraries/unix/unix.factor
@@ -0,0 +1,16 @@
+! (c)2010 Joe Groff bsd license
+USING: io.files io.pathnames io.pathnames.private kernel
+sequences system tools.deploy.libraries ;
+IN: tools.deploy.libraries.unix
+
+! stupid hack. better ways to find the library name would be open the library,
+! note a symbol address found in the library, then call dladdr (or use
+: ?exists ( path -- path/f )
+    dup exists? [ drop f ] unless ; inline
+
+M: unix find-library-file
+    dup absolute-path? [ ?exists ] [
+        { "/lib" "/usr/lib" "/usr/local/lib" }
+        [ prepend-path ?exists ] with map-find drop
+    ] if ;
+
diff --git a/basis/tools/deploy/libraries/windows/windows.factor b/basis/tools/deploy/libraries/windows/windows.factor
new file mode 100644
index 0000000000..4698754f07
--- /dev/null
+++ b/basis/tools/deploy/libraries/windows/windows.factor
@@ -0,0 +1,16 @@
+! (c)2010 Joe Groff bsd license
+USING: alien.strings byte-arrays io.encodings.utf16n kernel
+specialized-arrays system tools.deploy.libraries windows.kernel32
+windows.types ;
+FROM: alien.c-types => ushort ;
+SPECIALIZED-ARRAY: ushort
+IN: tools.deploy.libraries.windows
+
+M: windows find-library-file
+    f DONT_RESOLVE_DLL_REFERENCES LoadLibraryEx [
+        [
+            32768 (ushort-array) [ 32768 GetModuleFileName drop ] keep
+            utf16n alien>string
+        ] [ FreeLibrary drop ] bi
+    ] [ f ] if* ;
+
diff --git a/basis/tools/deploy/macosx/macosx.factor b/basis/tools/deploy/macosx/macosx.factor
index 8bd3749093..c02642ba1d 100644
--- a/basis/tools/deploy/macosx/macosx.factor
+++ b/basis/tools/deploy/macosx/macosx.factor
@@ -81,7 +81,9 @@ M: macosx deploy* ( vocab -- )
             [ bundle-name create-app-dir ] keep
             [ bundle-name deploy.app-image ] keep
             namespace make-deploy-image
-            bundle-name "Contents/Resources" copy-resources
+            bundle-name
+            [ "Contents/Resources" copy-resources ]
+            [ "Contents/Frameworks" copy-libraries ] 2bi
             bundle-name show-in-finder
         ] bind
     ] with-directory ;
diff --git a/basis/tools/deploy/shaker/shaker.factor b/basis/tools/deploy/shaker/shaker.factor
index d8a653c021..5630275aa1 100755
--- a/basis/tools/deploy/shaker/shaker.factor
+++ b/basis/tools/deploy/shaker/shaker.factor
@@ -1,6 +1,6 @@
 ! Copyright (C) 2007, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays accessors io.backend io.encodings.utf8 io.files
+USING: arrays alien.libraries accessors io.backend io.encodings.utf8 io.files
 io.streams.c init fry namespaces math make assocs kernel parser
 parser.notes lexer strings.parser vocabs sequences sequences.deep
 sequences.private words memory kernel.private continuations io
@@ -19,6 +19,7 @@ QUALIFIED: layouts
 QUALIFIED: source-files
 QUALIFIED: source-files.errors
 QUALIFIED: vocabs
+FROM: alien.libraries.private => >deployed-library-path ;
 IN: tools.deploy.shaker
 
 ! This file is some hairy shit.
@@ -505,11 +506,28 @@ SYMBOL: deploy-vocab
 
 : write-vocab-manifest ( vocab-manifest-out -- )
     "Writing vocabulary manifest to " write dup print flush
-    vocabs swap utf8 set-file-lines ;
+    vocabs "VOCABS:" prefix
+    deploy-libraries get [ libraries get path>> ] map "LIBRARIES:" prefix append
+    swap utf8 set-file-lines ;
+
+: prepare-deploy-libraries ( -- )
+    "Preparing deployed libraries" print flush
+    deploy-libraries get [
+        libraries get [
+            [ path>> >deployed-library-path ] [ abi>> ] bi <library>
+        ] change-at
+    ] each
+    
+    [
+        "deploy-libraries" "alien.libraries" lookup forget
+        "deploy-library" "alien.libraries" lookup forget
+        ">deployed-library-path" "alien.libraries.private" lookup forget
+    ] with-compilation-unit ;
 
 : strip ( vocab-manifest-out -- )
     [ write-vocab-manifest ] when*
     startup-stripper
+    prepare-deploy-libraries
     strip-libc
     strip-destructors
     strip-call
diff --git a/basis/tools/deploy/unix/unix.factor b/basis/tools/deploy/unix/unix.factor
index 2646f2d5a4..1b6b8596e2 100644
--- a/basis/tools/deploy/unix/unix.factor
+++ b/basis/tools/deploy/unix/unix.factor
@@ -19,7 +19,7 @@ M: unix deploy* ( vocab -- )
             [ bundle-name create-app-dir ] keep
             [ bundle-name image-name ] keep
             namespace make-deploy-image
-            bundle-name "" copy-resources
+            bundle-name "" [ copy-resources ] [ copy-libraries ] 3bi
             bundle-name normalize-path [ "Binary deployed to " % % "." % ] "" make print
         ] bind
     ] with-directory ;
diff --git a/basis/tools/deploy/windows/windows.factor b/basis/tools/deploy/windows/windows.factor
index 9f0b22847b..1dd60583fa 100755
--- a/basis/tools/deploy/windows/windows.factor
+++ b/basis/tools/deploy/windows/windows.factor
@@ -36,7 +36,7 @@ M: winnt deploy*
                 [ drop embed-ico ]
                 [ image-name ]
                 [ drop namespace make-deploy-image ]
-                [ nip "" copy-resources ]
+                [ nip "" [ copy-resources ] [ copy-libraries ] 3bi ]
                 [ nip open-in-explorer ]
             } 2cleave 
         ] bind
diff --git a/basis/windows/kernel32/kernel32.factor b/basis/windows/kernel32/kernel32.factor
index 576fac3a06..db0005e219 100644
--- a/basis/windows/kernel32/kernel32.factor
+++ b/basis/windows/kernel32/kernel32.factor
@@ -90,6 +90,8 @@ CONSTANT: FILE_ACTION_MODIFIED 3
 CONSTANT: FILE_ACTION_RENAMED_OLD_NAME 4
 CONSTANT: FILE_ACTION_RENAMED_NEW_NAME 5
 
+CONSTANT: DONT_RESOLVE_DLL_REFERENCES 1
+
 STRUCT: FILE_NOTIFY_INFORMATION
     { NextEntryOffset DWORD }
     { Action DWORD }
@@ -1167,7 +1169,7 @@ FUNCTION: BOOL FreeConsole ( ) ;
 ! FUNCTION: FreeEnvironmentStringsA
 FUNCTION: BOOL FreeEnvironmentStringsW ( LPTCH lpszEnvironmentBlock ) ;
 ALIAS: FreeEnvironmentStrings FreeEnvironmentStringsW
-! FUNCTION: FreeLibrary
+FUNCTION: BOOL FreeLibrary ( HMODULE hModule ) ;
 ! FUNCTION: FreeLibraryAndExitThread
 ! FUNCTION: FreeResource
 ! FUNCTION: FreeUserPhysicalPages
@@ -1314,7 +1316,8 @@ FUNCTION: DWORD GetLogicalDrives ( ) ;
 ! FUNCTION: GetLongPathNameW
 ! FUNCTION: GetMailslotInfo
 ! FUNCTION: GetModuleFileNameA
-! FUNCTION: GetModuleFileNameW
+FUNCTION: DWORD GetModuleFileNameW ( HMODULE hModule, LPTSTR lpFilename, DWORD nSize ) ;
+ALIAS: GetModuleFileName GetModuleFileNameW
 FUNCTION: HMODULE GetModuleHandleW ( LPCWSTR lpModuleName ) ;
 ALIAS: GetModuleHandle GetModuleHandleW
 ! FUNCTION: GetModuleHandleExA

From 08a20f94788e7f7ceb7006dead57401dcfe5aaa5 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 13:38:29 -0800
Subject: [PATCH 043/250] math.blas.config: add deploy-blas? variable

---
 basis/math/blas/config/config-docs.factor | 9 +++++++--
 basis/math/blas/config/config.factor      | 4 +++-
 basis/math/blas/ffi/ffi.factor            | 3 +++
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/basis/math/blas/config/config-docs.factor b/basis/math/blas/config/config-docs.factor
index 5c6cef83b8..826f26c646 100644
--- a/basis/math/blas/config/config-docs.factor
+++ b/basis/math/blas/config/config-docs.factor
@@ -6,20 +6,25 @@ ARTICLE: "math.blas.config" "Configuring the BLAS interface"
 { $subsections
     blas-library
     blas-fortran-abi
+    deploy-blas?
 }
 "The interface attempts to set default values based on the ones encountered on the Factor project's build machines. If these settings don't work with your system's BLAS, or you wish to use a commercial BLAS, you may change the global values of those variables in your " { $link "factor-rc" } ". For example, to use AMD's ACML library on Windows with " { $snippet "math.blas" } ", your " { $snippet "factor-rc" } " would look like this:"
 { $code """
 USING: math.blas.config namespaces ;
 "X:\\path\\to\\acml.dll" blas-library set-global
 intel-windows-abi blas-fortran-abi set-global
+t deploy-blas? set-global
 """ }
 "To take effect, the " { $snippet "blas-library" } " and " { $snippet "blas-fortran-abi" } " variables must be set before any other " { $snippet "math.blas" } " vocabularies are loaded."
 ;
 
 HELP: blas-library
-{ $description "The name of the shared library containing the BLAS interface to load. The value of this variable must be a valid shared library name that can be passed to " { $link add-fortran-library } ". To take effect, this variable must be set before any other " { $snippet "math.blas" } " vocabularies are loaded. See " { $link "math.blas.config" } " for details and examples." } ;
+{ $var-description "The name of the shared library containing the BLAS interface to load. The value of this variable must be a valid shared library name that can be passed to " { $link add-fortran-library } ". To take effect, this variable must be set before any other " { $snippet "math.blas" } " vocabularies are loaded. See " { $link "math.blas.config" } " for details and examples." } ;
 
 HELP: blas-fortran-abi
-{ $description "The Fortran ABI used by the BLAS interface specified in the " { $link blas-library } " variable. The value of " { $snippet "blas-fortran-abi" } " must be one of the " { $link "alien.fortran-abis" } " that can be passed to " { $link add-fortran-library } ". To take effect, this variable must be set before any other " { $snippet "math.blas" } " vocabularies are loaded. See " { $link "math.blas.config" } " for details and examples." } ;
+{ $var-description "The Fortran ABI used by the BLAS interface specified in the " { $link blas-library } " variable. The value of " { $snippet "blas-fortran-abi" } " must be one of the " { $link "alien.fortran-abis" } " that can be passed to " { $link add-fortran-library } ". To take effect, this variable must be set before any other " { $snippet "math.blas" } " vocabularies are loaded. See " { $link "math.blas.config" } " for details and examples." } ;
+
+HELP: deploy-blas?
+{ $var-description "If set to a true value, the BLAS library will be configured to deploy with applications that use it. To take effect, this variable must be set before any other " { $snippet "math.blas" } " vocabularies are loaded. See " { $link "math.blas.config" } " for details and examples." } ;
 
 ABOUT: "math.blas.config"
diff --git a/basis/math/blas/config/config.factor b/basis/math/blas/config/config.factor
index bce6e663af..76524d80ee 100644
--- a/basis/math/blas/config/config.factor
+++ b/basis/math/blas/config/config.factor
@@ -1,7 +1,7 @@
 USING: alien.fortran combinators kernel namespaces system ;
 IN: math.blas.config
 
-SYMBOLS: blas-library blas-fortran-abi ;
+SYMBOLS: blas-library blas-fortran-abi deploy-blas? ;
 
 blas-library [
     {
@@ -21,3 +21,5 @@ blas-fortran-abi [
         [ f2c-abi ]
     } cond
 ] initialize
+
+deploy-blas? [ os macosx? not ] initialize
diff --git a/basis/math/blas/ffi/ffi.factor b/basis/math/blas/ffi/ffi.factor
index b7748f500f..5cc6a18b6d 100644
--- a/basis/math/blas/ffi/ffi.factor
+++ b/basis/math/blas/ffi/ffi.factor
@@ -1,9 +1,12 @@
 USING: alien.fortran kernel math.blas.config namespaces ;
+FROM: alien.libraries => deploy-library ;
 IN: math.blas.ffi
 
 <<
 "blas" blas-library blas-fortran-abi [ get ] bi@
 add-fortran-library
+
+deploy-blas? get [ "blas" deploy-library ] when
 >>
 
 LIBRARY: blas

From b208c30fd3bb9f8dc73559acf4d831bbcd65a7c8 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 13:41:35 -0800
Subject: [PATCH 044/250] tools.deploy.shaker: prune library manifest

---
 basis/tools/deploy/shaker/shaker.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/tools/deploy/shaker/shaker.factor b/basis/tools/deploy/shaker/shaker.factor
index 5630275aa1..4a9882c2e6 100755
--- a/basis/tools/deploy/shaker/shaker.factor
+++ b/basis/tools/deploy/shaker/shaker.factor
@@ -507,7 +507,7 @@ SYMBOL: deploy-vocab
 : write-vocab-manifest ( vocab-manifest-out -- )
     "Writing vocabulary manifest to " write dup print flush
     vocabs "VOCABS:" prefix
-    deploy-libraries get [ libraries get path>> ] map "LIBRARIES:" prefix append
+    deploy-libraries get [ libraries get path>> ] map prune "LIBRARIES:" prefix append
     swap utf8 set-file-lines ;
 
 : prepare-deploy-libraries ( -- )

From 2f17248094ba2693b38ca9b70bdafaf8077c65c7 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 13:42:01 -0800
Subject: [PATCH 045/250] deploy openal and alut libraries except on OS X

---
 extra/openal/openal.factor | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/extra/openal/openal.factor b/extra/openal/openal.factor
index 85b150ce09..d3c2b0a5cc 100644
--- a/extra/openal/openal.factor
+++ b/extra/openal/openal.factor
@@ -24,6 +24,8 @@ IN: openal
         { [ os unix?  ]  [ "libopenal.so" ] }
     } cond "cdecl" add-library >>
 
+<< os macosx? [ "openal" deploy-library "alut" deploy-library ] unless >>
+
 LIBRARY: openal
 
 TYPEDEF: char ALboolean 

From b64f694e7ebe3f2e87c26fe79b74f2a6dab191c0 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 14:23:51 -0800
Subject: [PATCH 046/250] tools.deploy.shaker typos

---
 basis/tools/deploy/shaker/shaker.factor | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/basis/tools/deploy/shaker/shaker.factor b/basis/tools/deploy/shaker/shaker.factor
index 4a9882c2e6..54058f1b0d 100755
--- a/basis/tools/deploy/shaker/shaker.factor
+++ b/basis/tools/deploy/shaker/shaker.factor
@@ -507,11 +507,11 @@ SYMBOL: deploy-vocab
 : write-vocab-manifest ( vocab-manifest-out -- )
     "Writing vocabulary manifest to " write dup print flush
     vocabs "VOCABS:" prefix
-    deploy-libraries get [ libraries get path>> ] map prune "LIBRARIES:" prefix append
+    deploy-libraries get [ libraries get at path>> ] map prune "LIBRARIES:" prefix append
     swap utf8 set-file-lines ;
 
 : prepare-deploy-libraries ( -- )
-    "Preparing deployed libraries" print flush
+    "Preparing deployed libraries" show
     deploy-libraries get [
         libraries get [
             [ path>> >deployed-library-path ] [ abi>> ] bi <library>

From dcac051a4d467ca0f60923e731875b099cdccd25 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 14:24:04 -0800
Subject: [PATCH 047/250] deploy ogg and vorbis libraries

---
 extra/ogg/ogg.factor           | 2 ++
 extra/ogg/vorbis/vorbis.factor | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/extra/ogg/ogg.factor b/extra/ogg/ogg.factor
index 24227167c9..d7abece8bc 100644
--- a/extra/ogg/ogg.factor
+++ b/extra/ogg/ogg.factor
@@ -19,6 +19,8 @@ IN: ogg
     { [ os macosx? ] [ "libogg.0.dylib" ] }
     { [ os unix? ]   [ "libogg.so" ] }
 } cond "cdecl" add-library
+
+"ogg" deploy-library
 >>
 
 LIBRARY: ogg
diff --git a/extra/ogg/vorbis/vorbis.factor b/extra/ogg/vorbis/vorbis.factor
index 8cf79fecaf..d5905dac9e 100644
--- a/extra/ogg/vorbis/vorbis.factor
+++ b/extra/ogg/vorbis/vorbis.factor
@@ -20,6 +20,8 @@ IN: ogg.vorbis
     { [ os macosx? ] [ "libvorbis.0.dylib" ] }
     { [ os unix? ]   [ "libvorbis.so" ] }
 } cond "cdecl" add-library 
+
+"vorbis" deploy-library
 >>
 
 LIBRARY: vorbis

From 38f98afe6f8787b634a84e53d86567291ddd1239 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 14:24:29 -0800
Subject: [PATCH 048/250] search resource: for unix libraries too

---
 basis/tools/deploy/libraries/unix/unix.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/tools/deploy/libraries/unix/unix.factor b/basis/tools/deploy/libraries/unix/unix.factor
index 6c3dbb4d91..db3e9fa134 100644
--- a/basis/tools/deploy/libraries/unix/unix.factor
+++ b/basis/tools/deploy/libraries/unix/unix.factor
@@ -10,7 +10,7 @@ IN: tools.deploy.libraries.unix
 
 M: unix find-library-file
     dup absolute-path? [ ?exists ] [
-        { "/lib" "/usr/lib" "/usr/local/lib" }
+        { "/lib" "/usr/lib" "/usr/local/lib" "/opt/local/lib" "resource:" }
         [ prepend-path ?exists ] with map-find drop
     ] if ;
 

From 10bc247ed4681b936bdefd4eac35ba54d3c38fc8 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 14:33:57 -0800
Subject: [PATCH 049/250] typo in tools.deploy.backend

---
 basis/tools/deploy/backend/backend.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/tools/deploy/backend/backend.factor b/basis/tools/deploy/backend/backend.factor
index 4a4037d754..fe63071998 100644
--- a/basis/tools/deploy/backend/backend.factor
+++ b/basis/tools/deploy/backend/backend.factor
@@ -115,7 +115,7 @@ DEFER: ?make-staging-image
 : parse-vocab-manifest-file ( path -- vocab-manifest )
     utf8 file-lines
     dup first "VOCABS:" =
-    [ "LIBRARIES:" split1 vocab-manifest boa ]
+    [ { "LIBRARIES:" } split1 vocab-manifest boa ]
     [ "invalid vocab manifest!" throw ] if ;
 
 : make-deploy-image ( vm image vocab config -- manifest )

From 4a182cfbade49380fcd18fd47707bc4d4f8d6044 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 18:40:40 -0800
Subject: [PATCH 050/250] fix append-path and vocab-dir to use path-separator

---
 core/io/pathnames/pathnames.factor | 2 +-
 core/vocabs/loader/loader.factor   | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/core/io/pathnames/pathnames.factor b/core/io/pathnames/pathnames.factor
index b307128efb..5a9c647973 100644
--- a/core/io/pathnames/pathnames.factor
+++ b/core/io/pathnames/pathnames.factor
@@ -103,7 +103,7 @@ PRIVATE>
         ] }
         [
             [ trim-tail-separators ]
-            [ trim-head-separators ] bi* "/" glue
+            [ trim-head-separators ] bi* path-separator glue
         ]
     } cond ;
 
diff --git a/core/vocabs/loader/loader.factor b/core/vocabs/loader/loader.factor
index 2c0f67641d..0f2e3f7178 100644
--- a/core/vocabs/loader/loader.factor
+++ b/core/vocabs/loader/loader.factor
@@ -35,7 +35,9 @@ M: string vocab-path ( string -- path/f )
 PRIVATE>
 
 : vocab-dir ( vocab -- dir )
-    vocab-name { { CHAR: . CHAR: / } } substitute ;
+    vocab-name
+    os windows? { { CHAR: . CHAR: \\ } } { { CHAR: . CHAR: / } } ?
+    substitute ;
 
 : vocab-dir+ ( vocab str/f -- path )
     [ vocab-name "." split ] dip

From f59f28d78861dc7aa861f3333eecf7e31075dcfa Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 19:01:44 -0800
Subject: [PATCH 051/250] io.pathnames: make absolute-path? public

---
 core/io/pathnames/pathnames.factor | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/io/pathnames/pathnames.factor b/core/io/pathnames/pathnames.factor
index 5a9c647973..2be66ef186 100644
--- a/core/io/pathnames/pathnames.factor
+++ b/core/io/pathnames/pathnames.factor
@@ -76,6 +76,8 @@ ERROR: no-parent-directory path ;
         [ f ]
     } cond ;
 
+PRIVATE>
+
 : absolute-path? ( path -- ? )
     {
         { [ dup empty? ] [ f ] }
@@ -85,8 +87,6 @@ ERROR: no-parent-directory path ;
         [ f ]
     } cond nip ;
 
-PRIVATE>
-
 : append-path ( path1 path2 -- path )
     {
         { [ over empty? ] [ append-path-empty ] }

From 6ac33f6dea2bbb8f274d14cfa9ff141a4a7cd229 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 19:28:51 -0800
Subject: [PATCH 052/250] make io.pathnames tests path-separator-neutral

---
 core/io/pathnames/pathnames-tests.factor | 35 +++++++++++++-----------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/core/io/pathnames/pathnames-tests.factor b/core/io/pathnames/pathnames-tests.factor
index f23a1ac1f4..38cfe330fb 100644
--- a/core/io/pathnames/pathnames-tests.factor
+++ b/core/io/pathnames/pathnames-tests.factor
@@ -1,6 +1,6 @@
 USING: io.pathnames io.files.temp io.directories
 continuations math io.files.private kernel
-namespaces tools.test io.pathnames.private ;
+namespaces sequences tools.test io.pathnames.private ;
 IN: io.pathnames.tests
 
 [ "passwd" ] [ "/etc/passwd" file-name ] unit-test
@@ -11,20 +11,23 @@ IN: io.pathnames.tests
 [ "freetype6.dll" ] [ "resource:freetype6.dll" file-name ] unit-test
 [ "freetype6.dll" ] [ "resource:/freetype6.dll" file-name ] unit-test
 
-[ "/usr/lib" ] [ "/usr" "lib" append-path ] unit-test
-[ "/usr/lib" ] [ "/usr/" "lib" append-path ] unit-test
-[ "/usr/lib" ] [ "/usr" "./lib" append-path ] unit-test
-[ "/usr/lib/" ] [ "/usr" "./lib/" append-path ] unit-test
-[ "/lib" ] [ "/usr" "../lib" append-path ] unit-test
-[ "/lib/" ] [ "/usr" "../lib/" append-path ] unit-test
+: >test-path ( path -- path' )
+    [ dup path-separator? [ drop CHAR: / ] when ] map ;
+
+[ "/usr/lib" ] [ "/usr" "lib" append-path >test-path ] unit-test
+[ "/usr/lib" ] [ "/usr/" "lib" append-path >test-path ] unit-test
+[ "/usr/lib" ] [ "/usr" "./lib" append-path >test-path ] unit-test
+[ "/usr/lib/" ] [ "/usr" "./lib/" append-path >test-path ] unit-test
+[ "/lib" ] [ "/usr" "../lib" append-path >test-path ] unit-test
+[ "/lib/" ] [ "/usr" "../lib/" append-path >test-path ] unit-test
 
 [ "" ] [ "" "." append-path ] unit-test
 [ "" ".." append-path ] must-fail
 
-[ "/" ] [ "/" "./." append-path ] unit-test
-[ "/" ] [ "/" "././" append-path ] unit-test
-[ "/a/b/lib" ] [ "/a/b/c/d/e/f/" "../../../../lib" append-path ] unit-test
-[ "/a/b/lib/" ] [ "/a/b/c/d/e/f/" "../../../../lib/" append-path ] unit-test
+[ "/" ] [ "/" "./." append-path >test-path ] unit-test
+[ "/" ] [ "/" "././" append-path >test-path ] unit-test
+[ "/a/b/lib" ] [ "/a/b/c/d/e/f/" "../../../../lib" append-path >test-path ] unit-test
+[ "/a/b/lib/" ] [ "/a/b/c/d/e/f/" "../../../../lib/" append-path >test-path ] unit-test
 
 [ "" "../lib/" append-path ] must-fail
 [ "lib" ] [ "" "lib" append-path ] unit-test
@@ -45,10 +48,10 @@ IN: io.pathnames.tests
 [ "" parent-directory ] must-fail
 [ "." ] [ "boot.x86.64.image" parent-directory ] unit-test
 
-[ "bar/foo" ] [ "bar/baz" "..///foo" append-path ] unit-test
-[ "bar/baz/foo" ] [ "bar/baz" ".///foo" append-path ] unit-test
-[ "bar/foo" ] [ "bar/baz" "./..//foo" append-path ] unit-test
-[ "bar/foo" ] [ "bar/baz" "./../././././././///foo" append-path ] unit-test
+[ "bar/foo" ] [ "bar/baz" "..///foo" append-path >test-path ] unit-test
+[ "bar/baz/foo" ] [ "bar/baz" ".///foo" append-path >test-path ] unit-test
+[ "bar/foo" ] [ "bar/baz" "./..//foo" append-path >test-path ] unit-test
+[ "bar/foo" ] [ "bar/baz" "./../././././././///foo" append-path >test-path ] unit-test
 
 [ t ] [ "resource:core" absolute-path? ] unit-test
 [ f ] [ "" absolute-path? ] unit-test
@@ -61,7 +64,7 @@ IN: io.pathnames.tests
     "." current-directory set
     ".." "resource-path" set
     [ "../core/bootstrap/stage2.factor" ]
-    [ "resource:core/bootstrap/stage2.factor" absolute-path ]
+    [ "resource:core/bootstrap/stage2.factor" absolute-path >test-path ]
     unit-test
 ] with-scope
 

From 27cfeec43a5e4e23a1c329e8459b474c0f9cd1a3 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 19:29:42 -0800
Subject: [PATCH 053/250] vocabs.loader: make vocab-dir+ use path-separator too

---
 core/vocabs/loader/loader.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/vocabs/loader/loader.factor b/core/vocabs/loader/loader.factor
index 0f2e3f7178..390cfceb95 100644
--- a/core/vocabs/loader/loader.factor
+++ b/core/vocabs/loader/loader.factor
@@ -42,7 +42,7 @@ PRIVATE>
 : vocab-dir+ ( vocab str/f -- path )
     [ vocab-name "." split ] dip
     [ [ dup last ] dip append suffix ] when*
-    "/" join ;
+    path-separator join ;
 
 : find-vocab-root ( vocab -- path/f )
     vocab-name dup root-cache get at

From a9c13e03017da324a8130729256e31f9395ad657 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 22:19:56 -0800
Subject: [PATCH 054/250] fix last globs test on windows

---
 basis/globs/globs-tests.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 mode change 100644 => 100755 basis/globs/globs-tests.factor

diff --git a/basis/globs/globs-tests.factor b/basis/globs/globs-tests.factor
old mode 100644
new mode 100755
index c9903b1633..b2432754b1
--- a/basis/globs/globs-tests.factor
+++ b/basis/globs/globs-tests.factor
@@ -30,7 +30,7 @@ IN: globs.tests
 [ t ] [ "fo\\*" glob-pattern? ] unit-test
 [ t ] [ "fo{o,bro}" glob-pattern? ] unit-test
 
-"foo" "bar" append-path 1array
+{ "foo" "bar" } path-separator join 1array
 [ { "foo" "bar" "ba?" } path-separator join glob-parent-directory ] unit-test
 
 [ "foo" ] 

From a64d6e27ecc0a1b3673277aedbdc3a981a9f91a2 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 16 Feb 2010 22:31:21 -0800
Subject: [PATCH 055/250] move alut stuff to openal.alut so alut only gets
 deployed if we use it

---
 extra/morse/morse.factor                      |   2 +-
 extra/openal/alut/alut.factor                 | 103 ++++++++++++++++++
 extra/openal/{ => alut}/backend/authors.txt   |   0
 .../openal/{ => alut}/backend/backend.factor  |   2 +-
 extra/openal/{ => alut}/macosx/authors.txt    |   0
 extra/openal/{ => alut}/macosx/macosx.factor  |   4 +-
 extra/openal/{ => alut}/macosx/tags.txt       |   0
 extra/openal/{ => alut}/other/authors.txt     |   0
 extra/openal/{ => alut}/other/other.factor    |   4 +-
 extra/openal/example/example.factor           |   2 +-
 extra/openal/openal.factor                    |  95 +---------------
 extra/space-invaders/space-invaders.factor    |   1 +
 extra/synth/example/example.factor            |   2 +-
 extra/synth/synth.factor                      |   2 +-
 14 files changed, 115 insertions(+), 102 deletions(-)
 mode change 100644 => 100755 extra/morse/morse.factor
 create mode 100755 extra/openal/alut/alut.factor
 rename extra/openal/{ => alut}/backend/authors.txt (100%)
 rename extra/openal/{ => alut}/backend/backend.factor (79%)
 mode change 100644 => 100755
 rename extra/openal/{ => alut}/macosx/authors.txt (100%)
 rename extra/openal/{ => alut}/macosx/macosx.factor (84%)
 mode change 100644 => 100755
 rename extra/openal/{ => alut}/macosx/tags.txt (100%)
 rename extra/openal/{ => alut}/other/authors.txt (100%)
 rename extra/openal/{ => alut}/other/other.factor (89%)
 mode change 100644 => 100755
 mode change 100644 => 100755 extra/openal/example/example.factor
 mode change 100644 => 100755 extra/openal/openal.factor
 mode change 100644 => 100755 extra/space-invaders/space-invaders.factor
 mode change 100644 => 100755 extra/synth/example/example.factor
 mode change 100644 => 100755 extra/synth/synth.factor

diff --git a/extra/morse/morse.factor b/extra/morse/morse.factor
old mode 100644
new mode 100755
index cbe3c0f2fa..c6f1601955
--- a/extra/morse/morse.factor
+++ b/extra/morse/morse.factor
@@ -1,6 +1,6 @@
 ! Copyright (C) 2007, 2008, 2009 Alex Chapman, 2009 Diego Martinelli
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors ascii assocs biassocs combinators hashtables kernel lists literals math namespaces make multiline openal parser sequences splitting strings synth synth.buffers ;
+USING: accessors ascii assocs biassocs combinators hashtables kernel lists literals math namespaces make multiline openal openal.alut parser sequences splitting strings synth synth.buffers ;
 IN: morse
 
 ERROR: no-morse-ch ch ;
diff --git a/extra/openal/alut/alut.factor b/extra/openal/alut/alut.factor
new file mode 100755
index 0000000000..d1b8d2600d
--- /dev/null
+++ b/extra/openal/alut/alut.factor
@@ -0,0 +1,103 @@
+! Copyright (C) 2007 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel accessors arrays alien system combinators
+alien.syntax namespaces alien.c-types sequences vocabs.loader
+shuffle openal openal.alut.backend alien.libraries generalizations
+specialized-arrays alien.destructors ;
+FROM: alien.c-types => float short ;
+SPECIALIZED-ARRAY: uint
+IN: openal.alut
+
+<< "alut" {
+        { [ os windows? ]  [ "alut.dll" ] }
+        { [ os macosx? ] [
+            "/System/Library/Frameworks/OpenAL.framework/OpenAL"
+        ] }
+        { [ os unix?  ]  [ "libalut.so" ] }
+    } cond "cdecl" add-library >>
+
+<< os macosx? [ "alut" deploy-library ] unless >>
+
+LIBRARY: alut
+
+CONSTANT: ALUT_API_MAJOR_VERSION 1
+CONSTANT: ALUT_API_MINOR_VERSION 1
+CONSTANT: ALUT_ERROR_NO_ERROR 0
+CONSTANT: ALUT_ERROR_OUT_OF_MEMORY HEX: 200
+CONSTANT: ALUT_ERROR_INVALID_ENUM HEX: 201
+CONSTANT: ALUT_ERROR_INVALID_VALUE HEX: 202
+CONSTANT: ALUT_ERROR_INVALID_OPERATION HEX: 203
+CONSTANT: ALUT_ERROR_NO_CURRENT_CONTEXT HEX: 204
+CONSTANT: ALUT_ERROR_AL_ERROR_ON_ENTRY HEX: 205
+CONSTANT: ALUT_ERROR_ALC_ERROR_ON_ENTRY HEX: 206
+CONSTANT: ALUT_ERROR_OPEN_DEVICE HEX: 207
+CONSTANT: ALUT_ERROR_CLOSE_DEVICE HEX: 208
+CONSTANT: ALUT_ERROR_CREATE_CONTEXT HEX: 209
+CONSTANT: ALUT_ERROR_MAKE_CONTEXT_CURRENT HEX: 20A
+CONSTANT: ALUT_ERROR_DESTRY_CONTEXT HEX: 20B
+CONSTANT: ALUT_ERROR_GEN_BUFFERS HEX: 20C
+CONSTANT: ALUT_ERROR_BUFFER_DATA HEX: 20D
+CONSTANT: ALUT_ERROR_IO_ERROR HEX: 20E
+CONSTANT: ALUT_ERROR_UNSUPPORTED_FILE_TYPE HEX: 20F
+CONSTANT: ALUT_ERROR_UNSUPPORTED_FILE_SUBTYPE HEX: 210
+CONSTANT: ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA HEX: 211
+CONSTANT: ALUT_WAVEFORM_SINE HEX: 100
+CONSTANT: ALUT_WAVEFORM_SQUARE HEX: 101
+CONSTANT: ALUT_WAVEFORM_SAWTOOTH HEX: 102
+CONSTANT: ALUT_WAVEFORM_WHITENOISE HEX: 103
+CONSTANT: ALUT_WAVEFORM_IMPULSE HEX: 104
+CONSTANT: ALUT_LOADER_BUFFER HEX: 300
+CONSTANT: ALUT_LOADER_MEMORY HEX: 301
+
+FUNCTION: ALboolean alutInit ( int* argcp, char** argv ) ;
+FUNCTION: ALboolean alutInitWithoutContext ( int* argcp, char** argv ) ;
+FUNCTION: ALboolean alutExit ( ) ;
+FUNCTION: ALenum alutGetError ( ) ;
+FUNCTION: char* alutGetErrorString ( ALenum error ) ;
+FUNCTION: ALuint alutCreateBufferFromFile ( char* fileName ) ;
+FUNCTION: ALuint alutCreateBufferFromFileImage ( void* data, ALsizei length ) ;
+FUNCTION: ALuint alutCreateBufferHelloWorld ( ) ;
+FUNCTION: ALuint alutCreateBufferWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration ) ;
+FUNCTION: void* alutLoadMemoryFromFile ( char* fileName, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
+FUNCTION: void* alutLoadMemoryFromFileImage ( void* data, ALsizei length, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
+FUNCTION: void* alutLoadMemoryHelloWorld ( ALenum* format, ALsizei* size, ALfloat* frequency ) ;
+FUNCTION: void* alutLoadMemoryWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration, ALenum* format, ALsizei* size, ALfloat* freq ) ;
+FUNCTION: char* alutGetMIMETypes ( ALenum loader ) ;
+FUNCTION: ALint alutGetMajorVersion ( ) ;
+FUNCTION: ALint alutGetMinorVersion ( ) ;
+FUNCTION: ALboolean alutSleep ( ALfloat duration ) ;
+
+FUNCTION: void alutUnloadWAV ( ALenum format, void* data, ALsizei size, ALsizei frequency ) ;
+
+SYMBOL: init
+
+: init-openal ( -- )
+    init get-global expired? [
+        f f alutInit 0 = [ "Could not initialize OpenAL" throw ] when
+        1337 <alien> init set-global
+    ] when ;
+
+: exit-openal ( -- )
+    init get-global expired? [
+        alutExit 0 = [ "Could not close OpenAL" throw ] when
+        f init set-global
+    ] unless ;
+
+: create-buffer-from-file ( filename -- buffer )
+    alutCreateBufferFromFile dup AL_NONE = [
+        "create-buffer-from-file failed" throw
+    ] when ;
+
+os macosx? "openal.alut.macosx" "openal.alut.other" ? require
+
+: create-buffer-from-wav ( filename -- buffer )
+    gen-buffer dup rot load-wav-file
+    [ alBufferData ] 4 nkeep alutUnloadWAV ;
+
+: check-error ( -- )
+    alGetError dup ALUT_ERROR_NO_ERROR = [
+        drop
+    ] [
+        alGetString throw
+    ] if ;
+
diff --git a/extra/openal/backend/authors.txt b/extra/openal/alut/backend/authors.txt
similarity index 100%
rename from extra/openal/backend/authors.txt
rename to extra/openal/alut/backend/authors.txt
diff --git a/extra/openal/backend/backend.factor b/extra/openal/alut/backend/backend.factor
old mode 100644
new mode 100755
similarity index 79%
rename from extra/openal/backend/backend.factor
rename to extra/openal/alut/backend/backend.factor
index 41069dcddf..fc50d3d15e
--- a/extra/openal/backend/backend.factor
+++ b/extra/openal/alut/backend/backend.factor
@@ -1,4 +1,4 @@
 USING: namespaces system ;
-IN: openal.backend
+IN: openal.alut.backend
 
 HOOK: load-wav-file os ( filename -- format data size frequency )
diff --git a/extra/openal/macosx/authors.txt b/extra/openal/alut/macosx/authors.txt
similarity index 100%
rename from extra/openal/macosx/authors.txt
rename to extra/openal/alut/macosx/authors.txt
diff --git a/extra/openal/macosx/macosx.factor b/extra/openal/alut/macosx/macosx.factor
old mode 100644
new mode 100755
similarity index 84%
rename from extra/openal/macosx/macosx.factor
rename to extra/openal/alut/macosx/macosx.factor
index f0a6b928e9..3c0a4672cb
--- a/extra/openal/macosx/macosx.factor
+++ b/extra/openal/alut/macosx/macosx.factor
@@ -1,8 +1,8 @@
 ! Copyright (C) 2007 Chris Double.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien.c-types kernel alien alien.syntax shuffle
-openal openal.backend namespaces system generalizations ;
-IN: openal.macosx
+openal openal.alut.backend namespaces system generalizations ;
+IN: openal.alut.macosx
 
 LIBRARY: alut
 
diff --git a/extra/openal/macosx/tags.txt b/extra/openal/alut/macosx/tags.txt
similarity index 100%
rename from extra/openal/macosx/tags.txt
rename to extra/openal/alut/macosx/tags.txt
diff --git a/extra/openal/other/authors.txt b/extra/openal/alut/other/authors.txt
similarity index 100%
rename from extra/openal/other/authors.txt
rename to extra/openal/alut/other/authors.txt
diff --git a/extra/openal/other/other.factor b/extra/openal/alut/other/other.factor
old mode 100644
new mode 100755
similarity index 89%
rename from extra/openal/other/other.factor
rename to extra/openal/alut/other/other.factor
index ada8d6b1fb..b19579286b
--- a/extra/openal/other/other.factor
+++ b/extra/openal/alut/other/other.factor
@@ -1,8 +1,8 @@
 ! Copyright (C) 2007 Chris Double.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien.c-types alien.syntax combinators generalizations
-kernel openal openal.backend ;
-IN: openal.other
+kernel openal openal.alut.backend ;
+IN: openal.alut.other
 
 LIBRARY: alut
 
diff --git a/extra/openal/example/example.factor b/extra/openal/example/example.factor
old mode 100644
new mode 100755
index 4d979a8fa7..7789ee6e0a
--- a/extra/openal/example/example.factor
+++ b/extra/openal/example/example.factor
@@ -1,6 +1,6 @@
 ! Copyright (C) 2007 Chris Double.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: calendar kernel openal sequences threads ;
+USING: calendar kernel openal openal.alut sequences threads ;
 IN: openal.example
 
 : play-hello ( -- )
diff --git a/extra/openal/openal.factor b/extra/openal/openal.factor
old mode 100644
new mode 100755
index d3c2b0a5cc..bbe61f9dc3
--- a/extra/openal/openal.factor
+++ b/extra/openal/openal.factor
@@ -2,20 +2,12 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors arrays alien system combinators
 alien.syntax namespaces alien.c-types sequences vocabs.loader
-shuffle openal.backend alien.libraries generalizations
+shuffle alien.libraries generalizations
 specialized-arrays alien.destructors ;
 FROM: alien.c-types => float short ;
 SPECIALIZED-ARRAY: uint
 IN: openal
 
-<< "alut" {
-        { [ os windows? ]  [ "alut.dll" ] }
-        { [ os macosx? ] [
-            "/System/Library/Frameworks/OpenAL.framework/OpenAL"
-        ] }
-        { [ os unix?  ]  [ "libalut.so" ] }
-    } cond "cdecl" add-library >>
-
 << "openal" {
         { [ os windows? ]  [ "OpenAL32.dll" ] }
         { [ os macosx? ] [
@@ -24,7 +16,7 @@ IN: openal
         { [ os unix?  ]  [ "libopenal.so" ] }
     } cond "cdecl" add-library >>
 
-<< os macosx? [ "openal" deploy-library "alut" deploy-library ] unless >>
+<< os macosx? [ "openal" deploy-library ] unless >>
 
 LIBRARY: openal
 
@@ -254,71 +246,6 @@ FUNCTION: void alcCaptureSamples ( ALCdevice* device, void* buf, ALCsizei samps
 DESTRUCTOR: alcCloseDevice*
 DESTRUCTOR: alcDestroyContext
 
-LIBRARY: alut
-
-CONSTANT: ALUT_API_MAJOR_VERSION 1
-CONSTANT: ALUT_API_MINOR_VERSION 1
-CONSTANT: ALUT_ERROR_NO_ERROR 0
-CONSTANT: ALUT_ERROR_OUT_OF_MEMORY HEX: 200
-CONSTANT: ALUT_ERROR_INVALID_ENUM HEX: 201
-CONSTANT: ALUT_ERROR_INVALID_VALUE HEX: 202
-CONSTANT: ALUT_ERROR_INVALID_OPERATION HEX: 203
-CONSTANT: ALUT_ERROR_NO_CURRENT_CONTEXT HEX: 204
-CONSTANT: ALUT_ERROR_AL_ERROR_ON_ENTRY HEX: 205
-CONSTANT: ALUT_ERROR_ALC_ERROR_ON_ENTRY HEX: 206
-CONSTANT: ALUT_ERROR_OPEN_DEVICE HEX: 207
-CONSTANT: ALUT_ERROR_CLOSE_DEVICE HEX: 208
-CONSTANT: ALUT_ERROR_CREATE_CONTEXT HEX: 209
-CONSTANT: ALUT_ERROR_MAKE_CONTEXT_CURRENT HEX: 20A
-CONSTANT: ALUT_ERROR_DESTRY_CONTEXT HEX: 20B
-CONSTANT: ALUT_ERROR_GEN_BUFFERS HEX: 20C
-CONSTANT: ALUT_ERROR_BUFFER_DATA HEX: 20D
-CONSTANT: ALUT_ERROR_IO_ERROR HEX: 20E
-CONSTANT: ALUT_ERROR_UNSUPPORTED_FILE_TYPE HEX: 20F
-CONSTANT: ALUT_ERROR_UNSUPPORTED_FILE_SUBTYPE HEX: 210
-CONSTANT: ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA HEX: 211
-CONSTANT: ALUT_WAVEFORM_SINE HEX: 100
-CONSTANT: ALUT_WAVEFORM_SQUARE HEX: 101
-CONSTANT: ALUT_WAVEFORM_SAWTOOTH HEX: 102
-CONSTANT: ALUT_WAVEFORM_WHITENOISE HEX: 103
-CONSTANT: ALUT_WAVEFORM_IMPULSE HEX: 104
-CONSTANT: ALUT_LOADER_BUFFER HEX: 300
-CONSTANT: ALUT_LOADER_MEMORY HEX: 301
-
-FUNCTION: ALboolean alutInit ( int* argcp, char** argv ) ;
-FUNCTION: ALboolean alutInitWithoutContext ( int* argcp, char** argv ) ;
-FUNCTION: ALboolean alutExit ( ) ;
-FUNCTION: ALenum alutGetError ( ) ;
-FUNCTION: char* alutGetErrorString ( ALenum error ) ;
-FUNCTION: ALuint alutCreateBufferFromFile ( char* fileName ) ;
-FUNCTION: ALuint alutCreateBufferFromFileImage ( void* data, ALsizei length ) ;
-FUNCTION: ALuint alutCreateBufferHelloWorld ( ) ;
-FUNCTION: ALuint alutCreateBufferWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration ) ;
-FUNCTION: void* alutLoadMemoryFromFile ( char* fileName, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
-FUNCTION: void* alutLoadMemoryFromFileImage ( void* data, ALsizei length, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
-FUNCTION: void* alutLoadMemoryHelloWorld ( ALenum* format, ALsizei* size, ALfloat* frequency ) ;
-FUNCTION: void* alutLoadMemoryWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration, ALenum* format, ALsizei* size, ALfloat* freq ) ;
-FUNCTION: char* alutGetMIMETypes ( ALenum loader ) ;
-FUNCTION: ALint alutGetMajorVersion ( ) ;
-FUNCTION: ALint alutGetMinorVersion ( ) ;
-FUNCTION: ALboolean alutSleep ( ALfloat duration ) ;
-
-FUNCTION: void alutUnloadWAV ( ALenum format, void* data, ALsizei size, ALsizei frequency ) ;
-
-SYMBOL: init
-
-: init-openal ( -- )
-    init get-global expired? [
-        f f alutInit 0 = [ "Could not initialize OpenAL" throw ] when
-        1337 <alien> init set-global
-    ] when ;
-
-: exit-openal ( -- )
-    init get-global expired? [
-        alutExit 0 = [ "Could not close OpenAL" throw ] when
-        f init set-global
-    ] unless ;
-
 : gen-sources ( size -- seq )
     dup <uint-array> [ alGenSources ] keep ;
 
@@ -327,17 +254,6 @@ SYMBOL: init
 
 : gen-buffer ( -- buffer ) 1 gen-buffers first ;
 
-: create-buffer-from-file ( filename -- buffer )
-    alutCreateBufferFromFile dup AL_NONE = [
-        "create-buffer-from-file failed" throw
-    ] when ;
-
-os macosx? "openal.macosx" "openal.other" ? require
-
-: create-buffer-from-wav ( filename -- buffer )
-    gen-buffer dup rot load-wav-file
-    [ alBufferData ] 4 nkeep alutUnloadWAV ;
-
 : queue-buffers ( source buffers -- )
     [ length ] [ >uint-array ] bi alSourceQueueBuffers ;
 
@@ -360,12 +276,5 @@ os macosx? "openal.macosx" "openal.other" ? require
 
 : source-stop ( source -- ) alSourceStop ;
 
-: check-error ( -- )
-    alGetError dup ALUT_ERROR_NO_ERROR = [
-        drop
-    ] [
-        alGetString throw
-    ] if ;
-
 : source-playing? ( source -- bool )
     AL_SOURCE_STATE get-source-param AL_PLAYING = ;
diff --git a/extra/space-invaders/space-invaders.factor b/extra/space-invaders/space-invaders.factor
old mode 100644
new mode 100755
index 17e277fb6a..01bf621769
--- a/extra/space-invaders/space-invaders.factor
+++ b/extra/space-invaders/space-invaders.factor
@@ -18,6 +18,7 @@ USING:
     math
     math.order
     openal
+    openal.alut
     opengl.gl
     sequences
     ui
diff --git a/extra/synth/example/example.factor b/extra/synth/example/example.factor
old mode 100644
new mode 100755
index 747cfb9c86..e09d903afb
--- a/extra/synth/example/example.factor
+++ b/extra/synth/example/example.factor
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Alex Chapman
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays kernel namespaces make openal sequences
+USING: accessors arrays kernel namespaces make openal openal.alut sequences
 synth synth.buffers ;
 IN: synth.example
 
diff --git a/extra/synth/synth.factor b/extra/synth/synth.factor
old mode 100644
new mode 100755
index def610d356..90645e3562
--- a/extra/synth/synth.factor
+++ b/extra/synth/synth.factor
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Alex Chapman
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel locals math math.constants math.functions memoize openal synth.buffers sequences sequences.modified sequences.repeating ;
+USING: accessors kernel locals math math.constants math.functions memoize openal openal.alut synth.buffers sequences sequences.modified sequences.repeating ;
 IN: synth
 
 MEMO: single-sine-wave ( samples/wave -- seq )

From 7b22818192aec8638039f42a89e64f976eab7ac9 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Tue, 16 Feb 2010 22:37:31 -0800
Subject: [PATCH 056/250] Remove game.input dependency from chipmunk.demo so it
 works on linux

---
 extra/chipmunk/demo/demo.factor | 42 +++++++++++++++------------------
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/extra/chipmunk/demo/demo.factor b/extra/chipmunk/demo/demo.factor
index 031ed576b6..06f3c32dbe 100644
--- a/extra/chipmunk/demo/demo.factor
+++ b/extra/chipmunk/demo/demo.factor
@@ -1,9 +1,8 @@
 ! Copyright (C) 2010 Erik Charlebois
 ! See http:// factorcode.org/license.txt for BSD license.
-USING: accessors chipmunk classes.struct game.loop game.worlds gpu
-gpu.util.wasd kernel literals locals math method-chains opengl.gl
-random sequences specialized-arrays
-specialized-arrays.instances.alien.c-types.void* ui.gadgets.worlds
+USING: accessors chipmunk classes.struct game.worlds kernel locals
+math method-chains opengl.gl random sequences specialized-arrays
+specialized-arrays.instances.alien.c-types.void* ui ui.gadgets.worlds
 ui.pixel-formats ;
 IN: chipmunk.demo
 
@@ -56,7 +55,7 @@ CONSTANT: image-bitmap B{
     cpCircleShapeAlloc body 0.95 0 0 cpv cpCircleShapeInit cpCircleShape memory>struct
     [ shape>> 0 >>e ] [ shape>> 0 >>u ] bi drop ;
 
-TUPLE: chipmunk-world < wasd-world
+TUPLE: chipmunk-world < game-world
     space ;
 
 AFTER: chipmunk-world tick-game-world
@@ -97,8 +96,6 @@ M:: chipmunk-world draw-world* ( world -- )
 
 M:: chipmunk-world begin-game-world ( world -- )
     cpInitChipmunk
-    init-gpu
-    world { -0.2 0.13 0.1 } 1.1 0.2 set-wasd-view drop
 
     cpSpaceAlloc cpSpaceInit cpSpace memory>struct :> space
 
@@ -132,20 +129,19 @@ M: chipmunk-world end-game-world
     [ cpSpaceFreeChildren ]
     [ cpSpaceFree ] bi ;
 
-M: chipmunk-world wasd-movement-speed drop 1/160. ;
-M: chipmunk-world wasd-near-plane drop 1/32. ;
-M: chipmunk-world wasd-far-plane drop 256.0 ;
+: chipmunk-demo ( -- )
+    [
+        f
+        T{ game-attributes
+           { world-class chipmunk-world }
+           { title "Chipmunk Physics Demo" }
+           { pixel-format-attributes
+             { windowed double-buffered }
+           }
+           { pref-dim { 640 480 } }
+           { tick-interval-micros 16666 }
+        }
+        clone
+        open-window
+    ] with-ui ;
 
-GAME: chipmunk-demo {
-        { world-class chipmunk-world }
-        { title "Chipmunk Physics Demo" }
-        { pixel-format-attributes {
-            windowed
-            double-buffered
-            T{ depth-bits { value 24 } }
-        } }
-        { grab-input? t }
-        { use-game-input? t }
-        { pref-dim { 640 480 } }
-        { tick-interval-micros $[ 60 fps ] }
-    } ;

From da7cd4186ab0a9e70709fdaa5514d5c4d647b24a Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 01:18:48 +1300
Subject: [PATCH 057/250] help.markup: make $example render slightly nicer

---
 basis/help/markup/markup.factor         | 4 ++--
 basis/help/stylesheet/stylesheet.factor | 7 +++++--
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/basis/help/markup/markup.factor b/basis/help/markup/markup.factor
index 75e6538243..f951f30b2f 100644
--- a/basis/help/markup/markup.factor
+++ b/basis/help/markup/markup.factor
@@ -129,8 +129,8 @@ ALIAS: $slot $snippet
     "Examples" $heading print-element ;
 
 : $example ( element -- )
-    1 cut* swap "\n" join dup <input> [
-        input-style get format nl print-element
+    1 cut* [ "\n" join ] bi@ over <input> [
+        [ print ] [ output-style get format ] bi*
     ] ($code) ;
 
 : $unchecked-example ( element -- )
diff --git a/basis/help/stylesheet/stylesheet.factor b/basis/help/stylesheet/stylesheet.factor
index 8a119823cc..d5b783fef8 100644
--- a/basis/help/stylesheet/stylesheet.factor
+++ b/basis/help/stylesheet/stylesheet.factor
@@ -80,8 +80,11 @@ H{
     { wrap-margin f }
 } code-style set-global
 
-SYMBOL: input-style
-H{ { font-style bold } } input-style set-global
+SYMBOL: output-style
+H{
+    { font-style bold }
+    { foreground COLOR: dark-red }
+} output-style set-global
 
 SYMBOL: url-style
 H{

From 36cff8ed6e8ff8900ac2bf99d70db97033ea55f0 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 01:19:26 +1300
Subject: [PATCH 058/250] combinators: better wrong-values error

---
 core/combinators/combinators.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/combinators/combinators.factor b/core/combinators/combinators.factor
index 95b62fc3f3..9016d540d7 100644
--- a/core/combinators/combinators.factor
+++ b/core/combinators/combinators.factor
@@ -17,7 +17,7 @@ M: object throw
 
 PRIVATE>
 
-ERROR: wrong-values quot effect ;
+ERROR: wrong-values quot call-site ;
 
 ! We can't USE: effects here so we forward reference slots instead
 SLOT: in

From 63928191e719c041624300c37e9e855c550a2b46 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 01:19:39 +1300
Subject: [PATCH 059/250] Minor documentation fixes

---
 basis/listener/listener-docs.factor | 28 ++++++++++++++++++++--------
 core/generic/generic-docs.factor    |  8 +++++++-
 2 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/basis/listener/listener-docs.factor b/basis/listener/listener-docs.factor
index 77bec12c1a..a35f43e848 100644
--- a/basis/listener/listener-docs.factor
+++ b/basis/listener/listener-docs.factor
@@ -1,8 +1,8 @@
-USING: help.markup help.syntax kernel io system prettyprint continuations quotations ;
+USING: help.markup help.syntax kernel io system prettyprint continuations quotations vocabs.loader vocabs.refresh parser ;
 IN: listener
 
 ARTICLE: "listener-watch" "Watching variables in the listener"
-"The listener prints the concepts of the data and retain stacks after every expression. It can also print values of dynamic variables which are added to a watch list:"
+"The listener prints values of dynamic variables which are added to a watch list:"
 { $subsections visible-vars }
 "To add or remove a single variable:"
 { $subsections
@@ -14,7 +14,7 @@ ARTICLE: "listener-watch" "Watching variables in the listener"
     show-vars
     hide-vars
 }
-"Hiding all visible variables:"
+"Clearing the watch list:"
 { $subsections hide-all-vars } ;
 
 HELP: only-use-vocabs
@@ -46,21 +46,33 @@ HELP: hide-all-vars
 { $description "Removes all variables from the watch list." } ;
 
 ARTICLE: "listener" "The listener"
-"The listener evaluates Factor expressions read from a stream. The listener is the primary interface to the Factor runtime. Typically, you write Factor code in a text editor, then load it using the listener and test it."
+"The listener evaluates Factor expressions read from the input stream. Typically, you write Factor code in a text editor, load it from the listener by calling " { $link require } ", " { $link refresh-all } " or " { $link run-file } ", and then test it from interactively."
 $nl
 "The classical first program can be run in the listener:"
 { $example "\"Hello, world\" print" "Hello, world" }
+"New words can also be defined in the listener:"
+{ $example
+    "USE: math.functions"
+    ": twice ( word -- ) [ execute ] [ execute ] bi ; inline"
+    "81 \\ sqrt twice ."
+    "3"
+}
 "Multi-line expressions are supported:"
 { $example "{ 1 2 3 } [\n    .\n] each" "1\n2\n3" }
-"The listener knows when to expect more input by looking at the height of the stack. Parsing words such as " { $link POSTPONE: { } " leave elements on the parser stack, and corresponding words such as " { $link POSTPONE: } } " pop them."
+"The listener will display the current contents of the datastack after every line of input."
 $nl
-"The listener will display the current contents of the datastack after every expression is evaluated. The listener can additionally watch dynamic variables:"
+"The listener can watch dynamic variables:"
 { $subsections "listener-watch" }
-"To start a nested listener:"
+"Nested listeners can be useful for testing code in other dynamic scopes. For example, when doing database maintanance using the " { $vocab-link "db.tuples" } " vocabulary, it can be useful to start a listener with a database connection:"
+{ $code
+    "USING: db db.sqlite listener ;"
+    "\"data.db\" <sqlite-db> [ listener ] with-db"
+}
+"Starting a nested listener:"
 { $subsections listener }
 "To exit a listener, invoke the " { $link return } " word."
 $nl
-"Multi-line quotations can be read independently of the rest of the listener:"
+"The listener's mechanism for reading multi-line expressions from the input stream can be called from user code:"
 { $subsections read-quot } ;
 
 ABOUT: "listener"
diff --git a/core/generic/generic-docs.factor b/core/generic/generic-docs.factor
index 3a9314fb56..8d4f1f61a5 100644
--- a/core/generic/generic-docs.factor
+++ b/core/generic/generic-docs.factor
@@ -166,7 +166,13 @@ HELP: create-method
 HELP: (call-next-method)
 { $values { "method" method } }
 { $description "Low-level word implementing " { $link POSTPONE: call-next-method } "." }
-{ $notes "In most cases, " { $link POSTPONE: call-next-method } " should be used instead." } ;
+{ $notes
+    "The " { $link POSTPONE: call-next-method } " word parses into this word. The following are equivalent:"
+    { $code
+        "M: class generic call-next-method ;"
+        "M: class generic M\\ class generic (call-next-method) ;"
+    }
+} ;
 
 HELP: no-next-method
 { $error-description "Thrown by " { $link POSTPONE: call-next-method } " if the current method is already the least specific method." }

From 41433da61bb490011d62acff99cdc34711cf44c5 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 01:57:22 +1300
Subject: [PATCH 060/250] core: minor cleanups

---
 core/arrays/arrays.factor           | 14 +++-----------
 core/combinators/combinators.factor |  4 ++++
 2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/core/arrays/arrays.factor b/core/arrays/arrays.factor
index fa4d4b2f69..62a0774444 100644
--- a/core/arrays/arrays.factor
+++ b/core/arrays/arrays.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2005, 2008 Slava Pestov.
+! Copyright (C) 2005, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel kernel.private math math.private
 sequences sequences.private ;
@@ -9,24 +9,16 @@ M: array length length>> ; inline
 M: array nth-unsafe [ >fixnum ] dip array-nth ; inline
 M: array set-nth-unsafe [ >fixnum ] dip set-array-nth ; inline
 M: array resize resize-array ; inline
-
-: >array ( seq -- array ) { } clone-like ;
-
+M: array equal? over array? [ sequence= ] [ 2drop f ] if ;
 M: object new-sequence drop 0 <array> ; inline
-
 M: f new-sequence drop [ f ] [ 0 <array> ] if-zero ; inline
 
-M: array equal?
-    over array? [ sequence= ] [ 2drop f ] if ;
-
 INSTANCE: array sequence
 
+: >array ( seq -- array ) { } clone-like ;
 : 1array ( x -- array ) 1 swap <array> ; inline
-
 : 2array ( x y -- array ) { } 2sequence ; inline
-
 : 3array ( x y z -- array ) { } 3sequence ; inline
-
 : 4array ( w x y z -- array ) { } 4sequence ; inline
 
 PREDICATE: pair < array length 2 number= ;
diff --git a/core/combinators/combinators.factor b/core/combinators/combinators.factor
index 9016d540d7..7b9481825b 100644
--- a/core/combinators/combinators.factor
+++ b/core/combinators/combinators.factor
@@ -5,6 +5,10 @@ kernel kernel.private math assocs quotations vectors
 hashtables sorting words sets math.order make ;
 IN: combinators
 
+! Most of these combinators have compile-time expansions in
+! the optimizing compiler. See stack-checker.transforms and
+! compiler.tree.propagation.call-effect
+
 <PRIVATE
 
 : call-effect-unsafe ( quot effect -- ) drop call ;

From 01824d41be4f631118fdc4c94de180cdfc21ac6c Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 02:19:57 +1300
Subject: [PATCH 061/250] Add support for final tuple classes which cannot be
 subclassed: TUPLE: foo ... ; final

---
 basis/classes/struct/struct-tests.factor | 25 +++++++++++++++++-----
 basis/classes/struct/struct.factor       |  4 +---
 basis/debugger/debugger.factor           |  2 +-
 basis/functors/functors.factor           |  3 +++
 basis/typed/typed-tests.factor           |  8 +++++++
 core/bootstrap/syntax.factor             |  1 +
 core/classes/parser/parser.factor        |  3 ++-
 core/classes/tuple/tuple-tests.factor    | 27 ++++++++++++++++++++++++
 core/classes/tuple/tuple.factor          | 12 +++++++++--
 core/syntax/syntax.factor                |  4 ++++
 10 files changed, 77 insertions(+), 12 deletions(-)

diff --git a/basis/classes/struct/struct-tests.factor b/basis/classes/struct/struct-tests.factor
index 2c0db93522..cb7e4ee2b0 100644
--- a/basis/classes/struct/struct-tests.factor
+++ b/basis/classes/struct/struct-tests.factor
@@ -1,11 +1,11 @@
 ! (c)Joe Groff bsd license
 USING: accessors alien alien.c-types alien.data ascii
-assocs byte-arrays classes.struct classes.tuple.private
+assocs byte-arrays classes.struct classes.tuple.private classes.tuple
 combinators compiler.tree.debugger compiler.units destructors
 io.encodings.utf8 io.pathnames io.streams.string kernel libc
 literals math mirrors namespaces prettyprint
 prettyprint.config see sequences specialized-arrays system
-tools.test parser lexer eval layouts ;
+tools.test parser lexer eval layouts generic.single classes ;
 FROM: math => float ;
 QUALIFIED-WITH: alien.c-types c
 SPECIALIZED-ARRAY: char
@@ -338,13 +338,28 @@ STRUCT: struct-that's-a-word { x int } ;
 [
     "USE: classes.struct IN: classes.struct.tests TUPLE: not-a-struct ; S{ not-a-struct }"
     eval( -- value )
-] must-fail
+] [ error>> no-method? ] must-fail-with
 
 ! Subclassing a struct class should not be allowed
 [
-    "USE: classes.struct IN: classes.struct.tests STRUCT: a-struct { x int } ; TUPLE: not-a-struct < a-struct ;"
+    "USING: alien.c-types classes.struct ; IN: classes.struct.tests STRUCT: a-struct { x int } ; TUPLE: not-a-struct < a-struct ;"
     eval( -- )
-] must-fail
+] [ error>> bad-superclass? ] must-fail-with
+
+! Changing a superclass into a struct should reset the subclass
+TUPLE: will-become-struct ;
+
+TUPLE: a-subclass < will-become-struct ;
+
+[ f ] [ will-become-struct struct-class? ] unit-test
+
+[ will-become-struct ] [ a-subclass superclass ] unit-test
+
+[ ] [ "IN: classes.struct.tests USING: classes.struct alien.c-types ; STRUCT: will-become-struct { x int } ;" eval( -- ) ] unit-test
+
+[ t ] [ will-become-struct struct-class? ] unit-test
+
+[ tuple ] [ a-subclass superclass ] unit-test
 
 ! Remove c-type when struct class is forgotten
 [ ] [
diff --git a/basis/classes/struct/struct.factor b/basis/classes/struct/struct.factor
index fae39cd229..a5711de609 100644
--- a/basis/classes/struct/struct.factor
+++ b/basis/classes/struct/struct.factor
@@ -32,8 +32,6 @@ TUPLE: struct-bit-slot-spec < struct-slot-spec
 PREDICATE: struct-class < tuple-class
     superclass \ struct eq? ;
 
-M: struct-class valid-superclass? drop f ;
-
 SLOT: fields
 
 : struct-slots ( struct-class -- slots )
@@ -273,7 +271,7 @@ M: struct binary-zero? >c-ptr [ 0 = ] all? ;
     [ type>> c-type drop ] each ;
 
 : redefine-struct-tuple-class ( class -- )
-    [ dup class? [ forget-class ] [ drop ] if ] [ struct f define-tuple-class ] bi ;
+    [ struct f define-tuple-class ] [ make-final ] bi ;
 
 :: (define-struct-class) ( class slots offsets-quot -- )
     slots empty? [ struct-must-have-slots ] when
diff --git a/basis/debugger/debugger.factor b/basis/debugger/debugger.factor
index 815304b21f..b6497c52a9 100644
--- a/basis/debugger/debugger.factor
+++ b/basis/debugger/debugger.factor
@@ -194,7 +194,7 @@ M: not-a-tuple summary
     drop "Not a tuple" ;
 
 M: bad-superclass summary
-    drop "Tuple classes can only inherit from other tuple classes" ;
+    drop "Tuple classes can only inherit from non-final tuple classes" ;
 
 M: no-initial-value summary
     drop "Initial value must be provided for slots specialized to this class" ;
diff --git a/basis/functors/functors.factor b/basis/functors/functors.factor
index ac2e52f68e..6678613002 100644
--- a/basis/functors/functors.factor
+++ b/basis/functors/functors.factor
@@ -63,6 +63,9 @@ FUNCTOR-SYNTAX: TUPLE:
     } case
     \ define-tuple-class suffix! ;
 
+FUNCTOR-SYNTAX: final
+    [ word make-final ] append! ;
+
 FUNCTOR-SYNTAX: SINGLETON:
     scan-param suffix!
     \ define-singleton-class suffix! ;
diff --git a/basis/typed/typed-tests.factor b/basis/typed/typed-tests.factor
index f7b853cff7..f1e151b985 100644
--- a/basis/typed/typed-tests.factor
+++ b/basis/typed/typed-tests.factor
@@ -97,3 +97,11 @@ TYPED: no-outputs-unboxable-input ( x: unboxable3 -- )
     buh set ;
 
 [ T{ unboxable3 } ] [ T{ unboxable3 } no-outputs-unboxable-input buh get ] unit-test
+
+! Reported by littledan
+TUPLE: superclass x ;
+TUPLE: subclass < superclass y ;
+
+TYPED: unbox-fail ( superclass: a -- ? ) subclass? ;
+
+[ t ] [ subclass new unbox-fail ] unit-test
diff --git a/core/bootstrap/syntax.factor b/core/bootstrap/syntax.factor
index bb159f04df..1870f4ac1b 100644
--- a/core/bootstrap/syntax.factor
+++ b/core/bootstrap/syntax.factor
@@ -49,6 +49,7 @@ IN: bootstrap.syntax
         "SYMBOLS:"
         "CONSTANT:"
         "TUPLE:"
+        "final"
         "SLOT:"
         "T{"
         "UNION:"
diff --git a/core/classes/parser/parser.factor b/core/classes/parser/parser.factor
index 8233d8cff3..41ce32105d 100644
--- a/core/classes/parser/parser.factor
+++ b/core/classes/parser/parser.factor
@@ -8,8 +8,9 @@ IN: classes.parser
 
 : create-class-in ( string -- word )
     current-vocab create
+    dup set-word
     dup save-class-location
-    dup create-predicate-word dup set-word save-location ;
+    dup create-predicate-word save-location ;
 
 : CREATE-CLASS ( -- word )
     scan create-class-in ;
diff --git a/core/classes/tuple/tuple-tests.factor b/core/classes/tuple/tuple-tests.factor
index 36d402c61d..6711c5705e 100644
--- a/core/classes/tuple/tuple-tests.factor
+++ b/core/classes/tuple/tuple-tests.factor
@@ -770,3 +770,30 @@ TUPLE: tuple-predicate-redefine-test ;
 [ ] [ "IN: classes.tuple.tests TUPLE: tuple-predicate-redefine-test ;" eval( -- ) ] unit-test
 
 [ t ] [ \ tuple-predicate-redefine-test? predicate? ] unit-test
+
+! Final classes
+TUPLE: final-superclass ;
+TUPLE: final-subclass < final-superclass ;
+
+[ final-superclass ] [ final-subclass superclass ] unit-test
+
+! Making the superclass final should change the superclass of the subclass
+[ ] [ "IN: classes.tuple.tests TUPLE: final-superclass ; final" eval( -- ) ] unit-test
+
+[ tuple ] [ final-subclass superclass ] unit-test
+
+[ t ] [ \ final-subclass valid-superclass? ] unit-test
+
+! Subclassing a final class should fail
+[ "IN: classes.tuple.tests TUPLE: final-subclass < final-superclass ;" eval( -- ) ]
+[ error>> bad-superclass? ] must-fail-with
+
+! Making a final class non-final should work
+[ ] [ "IN: classes.tuple.tests TUPLE: final-superclass ;" eval( -- ) ] unit-test
+
+[ ] [ "IN: classes.tuple.tests TUPLE: final-subclass < final-superclass ; final" eval( -- ) ] unit-test
+
+! Changing a superclass should not change the final status of a subclass
+[ ] [ "IN: classes.tuple.tests TUPLE: final-superclass x ;" eval( -- ) ] unit-test
+
+[ f ] [ \ final-subclass valid-superclass? ] unit-test
diff --git a/core/classes/tuple/tuple.factor b/core/classes/tuple/tuple.factor
index 363c2879e9..c7a3afdd6d 100644
--- a/core/classes/tuple/tuple.factor
+++ b/core/classes/tuple/tuple.factor
@@ -240,7 +240,7 @@ M: tuple-class update-class
 
 GENERIC: valid-superclass? ( class -- ? )
 
-M: tuple-class valid-superclass? drop t ;
+M: tuple-class valid-superclass? "final" word-prop not ;
 
 M: builtin-class valid-superclass? tuple eq? ;
 
@@ -266,8 +266,16 @@ PRIVATE>
 : define-tuple-class ( class superclass slots -- )
     over check-superclass
     over prepare-slots
+    pick f "final" set-word-prop
     (define-tuple-class) ;
 
+GENERIC: make-final ( class -- )
+
+M: tuple-class make-final
+    [ dup class-usage keys ?metaclass-changed ]
+    [ t "final" set-word-prop ]
+    bi ;
+
 M: word (define-tuple-class)
     define-new-tuple-class ;
 
@@ -301,7 +309,7 @@ M: tuple-class reset-class
         ] with each
     ] [
         [ call-next-method ]
-        [ { "layout" "slots" "boa-check" "prototype" } reset-props ]
+        [ { "layout" "slots" "boa-check" "prototype" "final" } reset-props ]
         bi
     ] bi ;
 
diff --git a/core/syntax/syntax.factor b/core/syntax/syntax.factor
index cf2c49fff9..0b5b32e289 100644
--- a/core/syntax/syntax.factor
+++ b/core/syntax/syntax.factor
@@ -204,6 +204,10 @@ IN: bootstrap.syntax
         parse-tuple-definition define-tuple-class
     ] define-core-syntax
 
+    "final" [
+        word make-final
+    ] define-core-syntax
+
     "SLOT:" [
         scan define-protocol-slot
     ] define-core-syntax

From 60296be9641543c403098cf7f1b2cd5d9dbaa84a Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 02:39:12 +1300
Subject: [PATCH 062/250] typed: only unbox final classes. Fixes bug reported
 by littledan

---
 .../dependencies/dependencies.factor          | 12 +++++-
 basis/typed/typed-tests.factor                | 37 ++++++++++++++-----
 basis/typed/typed.factor                      | 12 ++++--
 core/classes/tuple/tuple.factor               | 27 +++++++++-----
 4 files changed, 64 insertions(+), 24 deletions(-)

diff --git a/basis/stack-checker/dependencies/dependencies.factor b/basis/stack-checker/dependencies/dependencies.factor
index d995354a52..df68fa8961 100644
--- a/basis/stack-checker/dependencies/dependencies.factor
+++ b/basis/stack-checker/dependencies/dependencies.factor
@@ -1,7 +1,8 @@
 ! Copyright (C) 2009, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs accessors classes.algebra fry generic kernel math
-namespaces sequences words sets combinators.short-circuit ;
+namespaces sequences words sets combinators.short-circuit
+classes.tuple ;
 FROM: classes.tuple.private => tuple-layout ;
 IN: stack-checker.dependencies
 
@@ -122,6 +123,15 @@ TUPLE: depends-on-flushable word ;
 M: depends-on-flushable satisfied?
     word>> flushable? ;
 
+TUPLE: depends-on-final class ;
+
+: depends-on-final ( word -- )
+    [ depends-on-conditionally ]
+    [ \ depends-on-final add-conditional-dependency ] bi ;
+
+M: depends-on-final satisfied?
+    class>> final-class? ;
+
 : init-dependencies ( -- )
     H{ } clone dependencies set
     H{ } clone generic-dependencies set
diff --git a/basis/typed/typed-tests.factor b/basis/typed/typed-tests.factor
index f1e151b985..7f984ccaf2 100644
--- a/basis/typed/typed-tests.factor
+++ b/basis/typed/typed-tests.factor
@@ -14,8 +14,8 @@ TYPED: fix+ ( a: fixnum b: fixnum -- c: fixnum )
 most-positive-fixnum neg 1 - 1quotation
 [ most-positive-fixnum 1 fix+ ] unit-test
 
-TUPLE: tweedle-dee ;
-TUPLE: tweedle-dum ;
+TUPLE: tweedle-dee ; final
+TUPLE: tweedle-dum ; final
 
 TYPED: dee ( x: tweedle-dee -- y )
     drop \ tweedle-dee ;
@@ -39,11 +39,11 @@ TYPED:: f+locals ( a: float b: float -- c: float )
 
 TUPLE: unboxable
     { x fixnum read-only }
-    { y fixnum read-only } ;
+    { y fixnum read-only } ; final
 
 TUPLE: unboxable2
     { u unboxable read-only }
-    { xy fixnum read-only } ;
+    { xy fixnum read-only } ; final
 
 TYPED: unboxy ( in: unboxable -- out: unboxable2 )
     dup [ x>> ] [ y>> ] bi - unboxable2 boa ;
@@ -63,7 +63,7 @@ IN: typed.tests
 TUPLE: unboxable
     { x fixnum read-only }
     { y fixnum read-only }
-    { z float read-only } ;
+    { z float read-only } ; final
 """ eval( -- )
 
 """
@@ -79,13 +79,15 @@ TYPED: no-inputs ( -- out: integer )
 [ 1 ] [ no-inputs ] unit-test
 
 TUPLE: unboxable3
-    { x read-only } ;
+    { x read-only } ; final
 
 TYPED: no-inputs-unboxable-output ( -- out: unboxable3 )
     T{ unboxable3 } ;
 
 [ T{ unboxable3 } ] [ no-inputs-unboxable-output ] unit-test
 
+[ f ] [ no-inputs-unboxable-output no-inputs-unboxable-output eq? ] unit-test
+
 SYMBOL: buh
 
 TYPED: no-outputs ( x: integer -- )
@@ -98,10 +100,25 @@ TYPED: no-outputs-unboxable-input ( x: unboxable3 -- )
 
 [ T{ unboxable3 } ] [ T{ unboxable3 } no-outputs-unboxable-input buh get ] unit-test
 
-! Reported by littledan
-TUPLE: superclass x ;
-TUPLE: subclass < superclass y ;
+[ f ] [
+    T{ unboxable3 } no-outputs-unboxable-input buh get
+    T{ unboxable3 } no-outputs-unboxable-input buh get
+    eq?
+] unit-test
 
-TYPED: unbox-fail ( superclass: a -- ? ) subclass? ;
+! Reported by littledan
+TUPLE: superclass { x read-only } ;
+TUPLE: subclass < superclass { y read-only } ; final
+
+TYPED: unbox-fail ( a: superclass -- ? ) subclass? ;
 
 [ t ] [ subclass new unbox-fail ] unit-test
+
+! If a final class becomes non-final, typed words need to be recompiled
+TYPED: recompile-fail ( a: subclass -- ? ) buh get eq? ;
+
+[ f ] [ subclass new [ buh set ] [ recompile-fail ] bi ] unit-test
+
+[ ] [ "IN: typed.tests TUPLE: subclass < superclass { y read-only } ;" eval( -- ) ] unit-test
+
+[ t ] [ subclass new [ buh set ] [ recompile-fail ] bi ] unit-test
diff --git a/basis/typed/typed.factor b/basis/typed/typed.factor
index e71196e3ee..8a85ca1afb 100644
--- a/basis/typed/typed.factor
+++ b/basis/typed/typed.factor
@@ -20,6 +20,7 @@ PREDICATE: typed-word < word "typed-word" word-prop ;
     {
         [ all-slots empty? not ]
         [ immutable-tuple-class? ]
+        [ final-class? ]
     } 1&& ;
 
 ! typed inputs
@@ -30,9 +31,14 @@ PREDICATE: typed-word < word "typed-word" word-prop ;
 : input-mismatch-quot ( word types -- quot )
     [ input-mismatch-error ] 2curry ;
 
+: depends-on-unboxing ( class -- )
+    [ dup tuple-layout depends-on-tuple-layout ]
+    [ depends-on-final ]
+    bi ;
+
 : (unboxer) ( type -- quot )
     dup unboxable-tuple-class? [
-        dup dup tuple-layout depends-on-tuple-layout
+        dup depends-on-unboxing
         all-slots [
             [ name>> reader-word 1quotation ]
             [ class>> (unboxer) ] bi compose
@@ -52,7 +58,7 @@ PREDICATE: typed-word < word "typed-word" word-prop ;
 : (unboxed-types) ( type -- types )
     dup unboxable-tuple-class?
     [
-        dup dup tuple-layout depends-on-tuple-layout
+        dup depends-on-unboxing
         all-slots [ class>> (unboxed-types) ] map concat
     ]
     [ 1array ] if ;
@@ -81,7 +87,7 @@ DEFER: make-boxer
 : boxer ( type -- quot )
     dup unboxable-tuple-class?
     [
-        dup dup tuple-layout depends-on-tuple-layout
+        dup depends-on-unboxing
         [ all-slots [ class>> ] map make-boxer ]
         [ [ boa ] curry ]
         bi compose
diff --git a/core/classes/tuple/tuple.factor b/core/classes/tuple/tuple.factor
index c7a3afdd6d..b590826511 100644
--- a/core/classes/tuple/tuple.factor
+++ b/core/classes/tuple/tuple.factor
@@ -93,6 +93,14 @@ ERROR: bad-superclass class ;
         ] [ 2drop f ] if
     ] [ 2drop f ] if ; inline
 
+GENERIC: final-class? ( class -- ? )
+
+M: tuple-class final-class? "final" word-prop ;
+
+M: builtin-class final-class? tuple eq? not ;
+
+M: class final-class? drop t ;
+
 <PRIVATE
 
 : tuple-predicate-quot/1 ( class -- quot )
@@ -238,16 +246,8 @@ M: tuple-class update-class
     [ [ "slots" word-prop ] dip = ]
     bi-curry* bi and ;
 
-GENERIC: valid-superclass? ( class -- ? )
-
-M: tuple-class valid-superclass? "final" word-prop not ;
-
-M: builtin-class valid-superclass? tuple eq? ;
-
-M: class valid-superclass? drop f ;
-
 : check-superclass ( superclass -- )
-    dup valid-superclass? [ bad-superclass ] unless drop ;
+    dup final-class? [ bad-superclass ] when drop ;
 
 GENERIC# (define-tuple-class) 2 ( class superclass slots -- )
 
@@ -261,12 +261,19 @@ GENERIC# (define-tuple-class) 2 ( class superclass slots -- )
         read-only suffix
     ] map ;
 
+: reset-final ( class -- )
+    dup final-class? [
+        [ f "final" set-word-prop ]
+        [ changed-conditionally ]
+        bi
+    ] [ drop ] if ;
+
 PRIVATE>
 
 : define-tuple-class ( class superclass slots -- )
     over check-superclass
     over prepare-slots
-    pick f "final" set-word-prop
+    pick reset-final
     (define-tuple-class) ;
 
 GENERIC: make-final ( class -- )

From ff172f4132b3938e3aa83df3d5da0b973fd9e096 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 02:39:40 +1300
Subject: [PATCH 063/250] Make specialized arrays and SIMD types final so that
 typed can unbox them

---
 basis/math/vectors/simd/simd.factor                | 2 +-
 basis/sequences/cords/cords.factor                 | 6 +++---
 basis/specialized-arrays/specialized-arrays.factor | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/basis/math/vectors/simd/simd.factor b/basis/math/vectors/simd/simd.factor
index acf13599c1..a60026317d 100644
--- a/basis/math/vectors/simd/simd.factor
+++ b/basis/math/vectors/simd/simd.factor
@@ -251,7 +251,7 @@ BOA-EFFECT [ N "n" <array> { "v" } <effect> ]
 
 WHERE
 
-TUPLE: A < simd-128 ;
+TUPLE: A < simd-128 ; final
 
 M: A new-underlying    drop \ A boa ; inline
 M: A simd-rep          drop A-rep ; inline
diff --git a/basis/sequences/cords/cords.factor b/basis/sequences/cords/cords.factor
index fca005fa6e..4a2d267a12 100644
--- a/basis/sequences/cords/cords.factor
+++ b/basis/sequences/cords/cords.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov, Joe Groff.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs sequences sorting binary-search fry math
 math.order arrays classes combinators kernel functors math.functions
@@ -8,7 +8,7 @@ IN: sequences.cords
 MIXIN: cord
 
 TUPLE: generic-cord
-    { head read-only } { tail read-only } ;
+    { head read-only } { tail read-only } ; final
 INSTANCE: generic-cord cord
 
 M: cord length
@@ -34,7 +34,7 @@ T-cord DEFINES-CLASS ${C}
 WHERE
 
 TUPLE: T-cord
-    { head T read-only } { tail T read-only } ;
+    { head T read-only } { tail T read-only } ; final
 INSTANCE: T-cord cord
 
 M: T cord-append
diff --git a/basis/specialized-arrays/specialized-arrays.factor b/basis/specialized-arrays/specialized-arrays.factor
index eda793ff22..d3db93e788 100644
--- a/basis/specialized-arrays/specialized-arrays.factor
+++ b/basis/specialized-arrays/specialized-arrays.factor
@@ -47,7 +47,7 @@ WHERE
 
 TUPLE: A
 { underlying c-ptr read-only }
-{ length array-capacity read-only } ;
+{ length array-capacity read-only } ; final
 
 : <direct-A> ( alien len -- specialized-array ) A boa ; inline
 

From c4c14c7cebeac1adc48d00ead76fad8bcac299b9 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 03:00:43 +1300
Subject: [PATCH 064/250] classes.tuple: fix screwup

---
 core/classes/tuple/tuple.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/classes/tuple/tuple.factor b/core/classes/tuple/tuple.factor
index b590826511..64c34d221a 100644
--- a/core/classes/tuple/tuple.factor
+++ b/core/classes/tuple/tuple.factor
@@ -273,7 +273,6 @@ PRIVATE>
 : define-tuple-class ( class superclass slots -- )
     over check-superclass
     over prepare-slots
-    pick reset-final
     (define-tuple-class) ;
 
 GENERIC: make-final ( class -- )
@@ -287,6 +286,7 @@ M: word (define-tuple-class)
     define-new-tuple-class ;
 
 M: tuple-class (define-tuple-class)
+    pick reset-final
     3dup tuple-class-unchanged?
     [ 2drop ?define-symbol ] [ redefine-tuple-class ] if ;
 

From 9df8a3adbd5362ec6d8674a29440f984a5c48537 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 03:01:26 +1300
Subject: [PATCH 065/250] see: show final declaration on tuples

---
 basis/prettyprint/prettyprint-tests.factor | 12 ++++++++++++
 basis/see/see.factor                       | 21 ++++++++++++++-------
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/basis/prettyprint/prettyprint-tests.factor b/basis/prettyprint/prettyprint-tests.factor
index 8ba6e94a49..ec0e20a393 100644
--- a/basis/prettyprint/prettyprint-tests.factor
+++ b/basis/prettyprint/prettyprint-tests.factor
@@ -362,3 +362,15 @@ TUPLE: tuple-with-initial-declared-slot { x integer initial: 123 } ;
 ] [
     [ \ tuple-with-initial-declared-slot see ] with-string-writer "\n" split
 ] unit-test
+
+TUPLE: final-tuple ; final
+
+[
+    {
+        "IN: prettyprint.tests"
+        "TUPLE: final-tuple ; final"
+        ""
+    }
+] [
+    [ \ final-tuple see ] with-string-writer "\n" split
+] unit-test
diff --git a/basis/see/see.factor b/basis/see/see.factor
index 0d2388114a..326e051219 100644
--- a/basis/see/see.factor
+++ b/basis/see/see.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2009 Slava Pestov.
+! Copyright (C) 2009, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays assocs classes classes.builtin
 classes.intersection classes.mixin classes.predicate classes.singleton
@@ -182,14 +182,21 @@ M: array pprint-slot-name
     dup length 1 = [ first ] when
     pprint-slot-name ;
 
+: tuple-declarations. ( class -- )
+    \ final declaration. ;
+
+: superclass. ( class -- )
+    superclass dup tuple eq? [ drop ] [ "<" text pprint-word ] if ;
+
 M: tuple-class see-class*
     <colon \ TUPLE: pprint-word
-    dup pprint-word
-    dup superclass tuple eq? [
-        "<" text dup superclass pprint-word
-    ] unless
-    <block "slots" word-prop [ pprint-slot ] each block>
-    pprint-; block> ;
+    {
+        [ pprint-word ]
+        [ superclass. ]
+        [ <block "slots" word-prop [ pprint-slot ] each block> pprint-; ]
+        [ tuple-declarations. ]
+    } cleave
+    block> ;
 
 M: word see-class* drop ;
 

From d2ae4ff4bada2584fbde4a486f5da1712e2d99ae Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 03:36:43 +1300
Subject: [PATCH 066/250] listener: fix docs

---
 basis/listener/listener-docs.factor | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/basis/listener/listener-docs.factor b/basis/listener/listener-docs.factor
index a35f43e848..bb20fe62ae 100644
--- a/basis/listener/listener-docs.factor
+++ b/basis/listener/listener-docs.factor
@@ -1,4 +1,5 @@
-USING: help.markup help.syntax kernel io system prettyprint continuations quotations vocabs.loader vocabs.refresh parser ;
+USING: help.markup help.syntax kernel io system prettyprint
+continuations quotations vocabs.loader parser ;
 IN: listener
 
 ARTICLE: "listener-watch" "Watching variables in the listener"
@@ -46,7 +47,7 @@ HELP: hide-all-vars
 { $description "Removes all variables from the watch list." } ;
 
 ARTICLE: "listener" "The listener"
-"The listener evaluates Factor expressions read from the input stream. Typically, you write Factor code in a text editor, load it from the listener by calling " { $link require } ", " { $link refresh-all } " or " { $link run-file } ", and then test it from interactively."
+"The listener evaluates Factor expressions read from the input stream. Typically, you write Factor code in a text editor, load it from the listener by calling " { $link require } ", " { $link reload } " or " { $link run-file } ", and then test it from interactively."
 $nl
 "The classical first program can be run in the listener:"
 { $example "\"Hello, world\" print" "Hello, world" }

From 4b76e2a61dc933ea39d4431d076bb9f47e94f883 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 03:56:41 +1300
Subject: [PATCH 067/250] functors: make 'final' declarations work in functors

---
 basis/functors/backend/backend.factor | 10 ++++--
 basis/functors/functors-tests.factor  | 47 +++++++++++++++++++++++++--
 basis/functors/functors.factor        |  2 +-
 3 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/basis/functors/backend/backend.factor b/basis/functors/backend/backend.factor
index dd3d891f7b..331864417e 100644
--- a/basis/functors/backend/backend.factor
+++ b/basis/functors/backend/backend.factor
@@ -1,6 +1,6 @@
 USING: accessors arrays assocs generic.standard kernel
 lexer locals.types namespaces parser quotations vocabs.parser
-words ;
+words classes.tuple ;
 IN: functors.backend
 
 DEFER: functor-words
@@ -27,7 +27,11 @@ SYNTAX: FUNCTOR-SYNTAX:
 
 : define* ( word def -- ) over set-word define ;
 
-: define-declared* ( word def effect -- ) pick set-word define-declared ;
+: define-declared* ( word def effect -- )
+    pick set-word define-declared ;
 
-: define-simple-generic* ( word effect -- ) over set-word define-simple-generic ;
+: define-simple-generic* ( word effect -- )
+    over set-word define-simple-generic ;
 
+: define-tuple-class* ( class superclass slots -- )
+    pick set-word define-tuple-class ;
diff --git a/basis/functors/functors-tests.factor b/basis/functors/functors-tests.factor
index 544c2ed1e4..c756d1b83d 100644
--- a/basis/functors/functors-tests.factor
+++ b/basis/functors/functors-tests.factor
@@ -1,5 +1,5 @@
-USING: classes.struct functors tools.test math words kernel
-multiline parser io.streams.string generic ;
+USING: classes.struct classes.tuple functors tools.test math
+words kernel multiline parser io.streams.string generic ;
 QUALIFIED-WITH: alien.c-types c
 IN: functors.tests
 
@@ -36,7 +36,7 @@ WW DEFINES ${W}${W}
 
 WHERE
 
-: WW ( a -- b ) \ W twice ; inline
+: WW ( a -- b ) \ W twice ;
 
 ;FUNCTOR
 
@@ -211,3 +211,44 @@ STRUCT: T-class
     }
 ] [ a-struct struct-slots ] unit-test
 
+<<
+
+FUNCTOR: define-an-inline-word ( W -- )
+
+W DEFINES ${W}
+W-W DEFINES ${W}-${W}
+
+WHERE
+
+: W ( -- ) ; inline
+: W-W ( -- ) W W ;
+
+;FUNCTOR
+
+"an-inline-word" define-an-inline-word
+
+>>
+
+[ t ] [ \ an-inline-word inline? ] unit-test
+[ f ] [ \ an-inline-word-an-inline-word inline? ] unit-test
+
+<<
+
+FUNCTOR: define-a-final-class ( T W -- )
+
+T DEFINES-CLASS ${T}
+W DEFINES ${W}
+
+WHERE
+
+TUPLE: T ; final
+
+: W ( -- ) ;
+
+;FUNCTOR
+
+"a-final-tuple" "a-word" define-a-final-class
+
+>>
+
+[ t ] [ a-final-tuple final-class? ] unit-test
diff --git a/basis/functors/functors.factor b/basis/functors/functors.factor
index 6678613002..1895c6e0f4 100644
--- a/basis/functors/functors.factor
+++ b/basis/functors/functors.factor
@@ -61,7 +61,7 @@ FUNCTOR-SYNTAX: TUPLE:
             make suffix!
         ]
     } case
-    \ define-tuple-class suffix! ;
+    \ define-tuple-class* suffix! ;
 
 FUNCTOR-SYNTAX: final
     [ word make-final ] append! ;

From 049b87bda9b71f5e29d6aa804285e7b31ec9f5bd Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 03:57:02 +1300
Subject: [PATCH 068/250] tuple-arrays: require that base type be final

---
 basis/tuple-arrays/tuple-arrays-docs.factor   | 12 ++++++----
 basis/tuple-arrays/tuple-arrays-tests.factor  | 22 ++++++++++++++-----
 basis/tuple-arrays/tuple-arrays.factor        | 15 +++++++++++--
 .../tuple-arrays/tuple-arrays.factor          |  4 ++--
 4 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/basis/tuple-arrays/tuple-arrays-docs.factor b/basis/tuple-arrays/tuple-arrays-docs.factor
index 5e70e15aa7..72a5ae4df3 100644
--- a/basis/tuple-arrays/tuple-arrays-docs.factor
+++ b/basis/tuple-arrays/tuple-arrays-docs.factor
@@ -3,20 +3,24 @@ USING: help.markup help.syntax sequences ;
 
 HELP: TUPLE-ARRAY:
 { $syntax "TUPLE-ARRAY: class" }
+{ $values { "class" "a final tuple class" } }
 { $description "Generates a new data type in the current vocabulary named " { $snippet { $emphasis "class" } "-array" } " for holding instances of " { $snippet "class" } ", which must be a tuple class word. Together with the class itself, this also generates words named " { $snippet "<" { $emphasis "class" } "-array>" } " and " { $snippet ">" { $emphasis "class" } "-array" } ", for creating new instances of this tuple array type." } ;
 
 ARTICLE: "tuple-arrays" "Tuple arrays"
-"The " { $vocab-link "tuple-arrays" } " vocabulary implements space-efficient unboxed tuple arrays. Whereas an ordinary array of tuples would consist of pointers to heap-allocated objects, a tuple array stores its elements inline. Calling " { $link nth } " copies an element into a new tuple, and calling " { $link set-nth } " copies an existing tuple's slots into an array."
+"The " { $vocab-link "tuple-arrays" } " vocabulary implements space-efficient unboxed tuple arrays. Whereas an ordinary array of tuples would consist of references to heap-allocated objects, a tuple array stores its elements as values."
 $nl
-"Since value semantics differ from reference semantics, it is best to use tuple arrays with tuples where all slots are declared " { $link read-only } "."
+"Calling " { $link nth } " copies an element into a new tuple, and calling " { $link set-nth } " copies an existing tuple's slots into an array."
+$nl
+"Since value semantics are incompatible with inheritance, the base type of a tuple array must be declared " { $link POSTPONE: final } ". A best practice that is not enforced is to have all slots in the tuple declared " { $link read-only } "."
+$nl
+"Tuple arrays do not get updated if tuples are redefined to add or remove slots, so caution should be exercised when doing interactive development on code that uses tuple arrays."
 $nl
-"Tuple arrays should not be used with inheritance; storing an instance of a subclass in a tuple array will slice off the subclass slots, and getting the same value out again will yield an instance of the superclass. Also, tuple arrays do not get updated if tuples are redefined to add or remove slots, so caution should be exercised when doing interactive development on code that uses tuple arrays."
 { $subsections POSTPONE: TUPLE-ARRAY: }
 "An example:"
 { $example
   "USE: tuple-arrays"
   "IN: scratchpad"
-  "TUPLE: point x y ;"
+  "TUPLE: point x y ; final"
   "TUPLE-ARRAY: point"
   "{ T{ point f 1 2 } T{ point f 1 3 } T{ point f 2 3 } } >point-array first short."
   "T{ point f 1 2 }"
diff --git a/basis/tuple-arrays/tuple-arrays-tests.factor b/basis/tuple-arrays/tuple-arrays-tests.factor
index 2eeae20aa1..0fbf0eeaa0 100644
--- a/basis/tuple-arrays/tuple-arrays-tests.factor
+++ b/basis/tuple-arrays/tuple-arrays-tests.factor
@@ -1,9 +1,9 @@
 USING: tuple-arrays sequences tools.test namespaces kernel
-math accessors ;
+math accessors classes.tuple eval ;
 IN: tuple-arrays.tests
 
 SYMBOL: mat
-TUPLE: foo bar ;
+TUPLE: foo bar ; final
 C: <foo> foo
 TUPLE-ARRAY: foo
 
@@ -18,15 +18,27 @@ TUPLE-ARRAY: foo
 [ T{ foo } ] [ mat get first ] unit-test
 [ T{ foo f 1 } ] [ T{ foo f 1 } 0 mat get [ set-nth ] keep first ] unit-test
 
-TUPLE: baz { bing integer } bong ;
+TUPLE: baz { bing integer } bong ; final
 TUPLE-ARRAY: baz
 
 [ 0 ] [ 1 <baz-array> first bing>> ] unit-test
 [ f ] [ 1 <baz-array> first bong>> ] unit-test
 
-TUPLE: broken x ;
+TUPLE: broken x ; final
 : broken ( -- ) ;
 
 TUPLE-ARRAY: broken
 
-[ 100 ] [ 100 <broken-array> length ] unit-test
\ No newline at end of file
+[ 100 ] [ 100 <broken-array> length ] unit-test
+
+! Can't define a tuple array for a non-tuple class
+[ "IN: tuple-arrays.tests USING: tuple-arrays words ; TUPLE-ARRAY: word" eval( -- ) ]
+[ error>> not-a-tuple? ]
+must-fail-with
+
+! Can't define a tuple array for a non-final class
+TUPLE: non-final x ;
+
+[ "IN: tuple-arrays.tests USE: tuple-arrays TUPLE-ARRAY: non-final" eval( -- ) ]
+[ error>> not-final? ]
+must-fail-with
\ No newline at end of file
diff --git a/basis/tuple-arrays/tuple-arrays.factor b/basis/tuple-arrays/tuple-arrays.factor
index aea51f7820..1a3091c1e2 100644
--- a/basis/tuple-arrays/tuple-arrays.factor
+++ b/basis/tuple-arrays/tuple-arrays.factor
@@ -1,11 +1,13 @@
-! Copyright (C) 2009 Slava Pestov.
+! Copyright (C) 2009, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays combinators.smart fry functors kernel
 kernel.private macros sequences combinators sequences.private
-stack-checker parser math classes.tuple.private ;
+stack-checker parser math classes.tuple classes.tuple.private ;
 FROM: inverse => undo ;
 IN: tuple-arrays
 
+ERROR: not-final class ;
+
 <PRIVATE
 
 MACRO: boa-unsafe ( class -- quot ) tuple-layout '[ _ <tuple-boa> ] ;
@@ -29,6 +31,13 @@ MACRO: write-tuple ( class -- quot )
     [ tuple-arity iota <reversed> [ '[ [ _ ] dip set-nth-unsafe ] ] map '[ _ cleave ] ]
     bi '[ _ dip @ ] ;
 
+: check-final ( class -- )
+    {
+        { [ dup tuple-class? not ] [ not-a-tuple ] }
+        { [ dup final-class? not ] [ not-final ] }
+        [ drop ]
+    } cond ;
+
 PRIVATE>
 
 FUNCTOR: define-tuple-array ( CLASS -- )
@@ -43,6 +52,8 @@ CLASS-array? IS ${CLASS-array}?
 
 WHERE
 
+CLASS check-final
+
 TUPLE: CLASS-array
 { seq array read-only }
 { n array-capacity read-only }
diff --git a/extra/benchmark/tuple-arrays/tuple-arrays.factor b/extra/benchmark/tuple-arrays/tuple-arrays.factor
index 701db77135..80c31553c1 100644
--- a/extra/benchmark/tuple-arrays/tuple-arrays.factor
+++ b/extra/benchmark/tuple-arrays/tuple-arrays.factor
@@ -1,10 +1,10 @@
-! Copyright (C) 2009 Slava Pestov.
+! Copyright (C) 2009, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math math.functions tuple-arrays accessors fry sequences
 prettyprint ;
 IN: benchmark.tuple-arrays
 
-TUPLE: point { x float } { y float } { z float } ;
+TUPLE: point { x float } { y float } { z float } ; final
 
 TUPLE-ARRAY: point
 

From bf72c890603b00757f0ea8334888908b52af9e34 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 03:57:10 +1300
Subject: [PATCH 069/250] tools.deploy.backend: clean up

---
 basis/tools/deploy/backend/backend.factor | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/basis/tools/deploy/backend/backend.factor b/basis/tools/deploy/backend/backend.factor
index fe63071998..9f25808c9e 100644
--- a/basis/tools/deploy/backend/backend.factor
+++ b/basis/tools/deploy/backend/backend.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2007, 2009 Slava Pestov.
+! Copyright (C) 2007, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: namespaces make continuations.private kernel.private init
 assocs kernel vocabs words sequences memory io system arrays
@@ -19,13 +19,12 @@ TUPLE: vocab-manifest vocabs libraries ;
 : copy-resources ( manifest name dir -- )
     append-path swap vocabs>> [ copy-vocab-resources ] with each ;
 
-ERROR: cant-deploy-library-file library ;
-<PRIVATE
+ERROR: can't-deploy-library-file library ;
+
 : copy-library ( dir library -- )
     dup find-library-file
-    [ nip swap over file-name append-path copy-file ]
-    [ cant-deploy-library-file ] if* ;
-PRIVATE>
+    [ swap over file-name append-path copy-file ]
+    [ can't-deploy-library-file ] ?if ;
 
 : copy-libraries ( manifest name dir -- )
     append-path swap libraries>> [ copy-library ] with each ;

From 9debed1c75490b451c7268a7a3043b3e184a6fee Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 04:13:21 +1300
Subject: [PATCH 070/250] typed: update documentation

---
 basis/typed/typed-docs.factor | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/basis/typed/typed-docs.factor b/basis/typed/typed-docs.factor
index 0b6838379c..c6f80a48bc 100644
--- a/basis/typed/typed-docs.factor
+++ b/basis/typed/typed-docs.factor
@@ -58,10 +58,18 @@ HELP: output-mismatch-error
 
 ARTICLE: "typed" "Strongly-typed word definitions"
 "The Factor compiler supports advanced compiler optimizations that take advantage of the type information it can glean from source code. The " { $vocab-link "typed" } " vocabulary provides syntax that allows words to provide checked type information about their inputs and outputs and improve the performance of compiled code."
+$nl
+"Parameters and return values of typed words where the type is declared to be a " { $link POSTPONE: final } " tuple class with all slots " { $link read-only } " are passed by value."
 { $subsections
     POSTPONE: TYPED:
     POSTPONE: TYPED::
+}
+"Defining typed words at run time:"
+{ $subsections
     define-typed
+}
+"Errors:"
+{ $subsections
     input-mismatch-error
     output-mismatch-error
 } ;

From c5259f2e2c54fb44642d322b7fc6bb5836bc99b0 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 04:13:34 +1300
Subject: [PATCH 071/250] classes.tuple: document final class declaration

---
 core/classes/tuple/tuple-docs.factor | 5 +++++
 core/syntax/syntax-docs.factor       | 4 ++++
 2 files changed, 9 insertions(+)

diff --git a/core/classes/tuple/tuple-docs.factor b/core/classes/tuple/tuple-docs.factor
index 2b3e80da1d..7f6078e321 100644
--- a/core/classes/tuple/tuple-docs.factor
+++ b/core/classes/tuple/tuple-docs.factor
@@ -191,6 +191,8 @@ $nl
     "tuple-inheritance-example"
     "tuple-inheritance-anti-example"
 } 
+"Declaring a tuple class final prohibits other classes from subclassing it:"
+{ $subsections POSTPONE: final }
 { $see-also "call-next-method" "parametrized-constructors" "unions" "mixins" } ;
 
 ARTICLE: "tuple-introspection" "Tuple introspection"
@@ -441,3 +443,6 @@ HELP: boa
 { $description "Creates a new instance of " { $snippet "class" } " and fill in the slots from the stack, with the top-most stack element being stored in the right-most slot." }
 { $notes "The name " { $snippet "boa" } " is shorthand for “by order of arguments”, and “BOA constructor” is a pun on “boa constrictor”." }
 { $errors "Throws an error if the slot values do not match class declarations on slots (see" { $link "tuple-declarations" } ")." } ;
+
+HELP: bad-superclass
+{ $error-description "Thrown if an attempt is made to subclass a class that is not a tuple class, or a tuple class declared " { $link POSTPONE: final } "." } ;
diff --git a/core/syntax/syntax-docs.factor b/core/syntax/syntax-docs.factor
index 8ad6084188..4a1af4c578 100644
--- a/core/syntax/syntax-docs.factor
+++ b/core/syntax/syntax-docs.factor
@@ -792,6 +792,10 @@ $nl
     { $code "TUPLE: person" "{ age integer initial: 0 }" "{ department string initial: \"Marketing\" }" "manager ;" }
 } ;
 
+HELP: final
+{ $syntax "TUPLE: ... ; final" }
+{ $description "Declares the most recently defined word as a final tuple class which cannot be subclassed. Attempting to subclass a final class raises a " { $link bad-superclass } " error." } ;
+
 HELP: initial:
 { $syntax "TUPLE: ... { slot initial: value } ... ;" }
 { $values { "slot" "a slot name" } { "value" "any literal" } }

From 31ccfa2e5d8633c7e09aa26754bc3a197daf4860 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 04:58:30 +1300
Subject: [PATCH 072/250] Fix unit test failures

---
 core/classes/tuple/tuple-tests.factor | 4 ++--
 core/parser/parser-tests.factor       | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/core/classes/tuple/tuple-tests.factor b/core/classes/tuple/tuple-tests.factor
index 6711c5705e..276c6b407c 100644
--- a/core/classes/tuple/tuple-tests.factor
+++ b/core/classes/tuple/tuple-tests.factor
@@ -782,7 +782,7 @@ TUPLE: final-subclass < final-superclass ;
 
 [ tuple ] [ final-subclass superclass ] unit-test
 
-[ t ] [ \ final-subclass valid-superclass? ] unit-test
+[ f ] [ \ final-subclass final-class? ] unit-test
 
 ! Subclassing a final class should fail
 [ "IN: classes.tuple.tests TUPLE: final-subclass < final-superclass ;" eval( -- ) ]
@@ -796,4 +796,4 @@ TUPLE: final-subclass < final-superclass ;
 ! Changing a superclass should not change the final status of a subclass
 [ ] [ "IN: classes.tuple.tests TUPLE: final-superclass x ;" eval( -- ) ] unit-test
 
-[ f ] [ \ final-subclass valid-superclass? ] unit-test
+[ t ] [ \ final-subclass final-class? ] unit-test
diff --git a/core/parser/parser-tests.factor b/core/parser/parser-tests.factor
index f30eb68684..266a65b957 100644
--- a/core/parser/parser-tests.factor
+++ b/core/parser/parser-tests.factor
@@ -339,7 +339,7 @@ IN: parser.tests
 ] unit-test
 
 [ t ] [
-    "foo?" "parser.tests" lookup word eq?
+    "foo" "parser.tests" lookup word eq?
 ] unit-test
 
 [ ] [

From 9da061de5eb4d6d45a60a34eef4ca6814f13234c Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 07:02:22 +1300
Subject: [PATCH 073/250] listener: fix help lint

---
 basis/listener/listener-docs.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/listener/listener-docs.factor b/basis/listener/listener-docs.factor
index bb20fe62ae..bb014fef62 100644
--- a/basis/listener/listener-docs.factor
+++ b/basis/listener/listener-docs.factor
@@ -56,7 +56,7 @@ $nl
     "USE: math.functions"
     ": twice ( word -- ) [ execute ] [ execute ] bi ; inline"
     "81 \\ sqrt twice ."
-    "3"
+    "3.0"
 }
 "Multi-line expressions are supported:"
 { $example "{ 1 2 3 } [\n    .\n] each" "1\n2\n3" }

From 31d97a8ff7cddd6c0a23ca284d5c9c4c5f32112e Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Wed, 17 Feb 2010 11:26:32 -0800
Subject: [PATCH 074/250] fall back to manual gl vertex attribute management
 when GL_APPLE_vertex_array_object is not present, so gpu can support vanilla
 GL 2.0

---
 extra/gpu/gpu.factor             |  4 +-
 extra/gpu/render/render.factor   |  5 +-
 extra/gpu/shaders/shaders.factor | 80 ++++++++++++++++++++++++++------
 extra/gpu/state/state.factor     |  4 --
 4 files changed, 71 insertions(+), 22 deletions(-)
 mode change 100644 => 100755 extra/gpu/gpu.factor
 mode change 100644 => 100755 extra/gpu/render/render.factor
 mode change 100644 => 100755 extra/gpu/shaders/shaders.factor
 mode change 100644 => 100755 extra/gpu/state/state.factor

diff --git a/extra/gpu/gpu.factor b/extra/gpu/gpu.factor
old mode 100644
new mode 100755
index 6a61e2ec4f..1d02b3f07a
--- a/extra/gpu/gpu.factor
+++ b/extra/gpu/gpu.factor
@@ -9,10 +9,12 @@ TUPLE: gpu-object < identity-tuple handle ;
 VARIANT: gpu-api
     opengl-2 opengl-3 ;
 
+SYMBOL: has-vertex-array-objects?
+
 : set-gpu-api ( -- )
     "2.0" require-gl-version
     "3.0" { { "GL_ARB_vertex_array_object" "GL_APPLE_vertex_array_object" } }
-    require-gl-version-or-extensions
+    has-gl-version-or-extensions? has-vertex-array-objects? set-global
     "3.0" has-gl-version? opengl-3 opengl-2 ? gpu-api set-global ;
 
 HOOK: init-gpu-api gpu-api ( -- )
diff --git a/extra/gpu/render/render.factor b/extra/gpu/render/render.factor
old mode 100644
new mode 100755
index 1d4813ab54..2b7d75a3ae
--- a/extra/gpu/render/render.factor
+++ b/extra/gpu/render/render.factor
@@ -520,9 +520,6 @@ SYNTAX: UNIFORM-TUPLE:
 
 <PRIVATE 
 
-: bind-vertex-array ( vertex-array -- )
-    handle>> glBindVertexArray ;
-
 : bind-unnamed-output-attachments ( framebuffer attachments -- )
     [ gl-attachment ] with map
     dup length 1 =
@@ -567,7 +564,7 @@ UNION: transform-feedback-output buffer buffer-range POSTPONE: f ;
 
 TUPLE: render-set
     { primitive-mode primitive-mode read-only }
-    { vertex-array vertex-array read-only }
+    { vertex-array vertex-array initial: T{ vertex-array-collection } read-only }
     { uniforms uniform-tuple read-only }
     { indexes vertex-indexes initial: T{ index-range } read-only } 
     { instances ?integer initial: f read-only }
diff --git a/extra/gpu/shaders/shaders.factor b/extra/gpu/shaders/shaders.factor
old mode 100644
new mode 100755
index 0401584f7c..025acba896
--- a/extra/gpu/shaders/shaders.factor
+++ b/extra/gpu/shaders/shaders.factor
@@ -2,9 +2,9 @@
 USING: accessors alien alien.c-types alien.data alien.strings
 arrays assocs byte-arrays classes.mixin classes.parser
 classes.singleton classes.struct combinators combinators.short-circuit
-definitions destructors fry generic.parser gpu gpu.buffers hashtables
-images io.encodings.ascii io.files io.pathnames kernel lexer
-literals locals math math.parser memoize multiline namespaces
+definitions destructors fry generic.parser gpu gpu.buffers gpu.private
+gpu.state hashtables images io.encodings.ascii io.files io.pathnames
+kernel lexer literals locals math math.parser memoize multiline namespaces
 opengl opengl.gl opengl.shaders parser quotations sequences
 specialized-arrays splitting strings tr ui.gadgets.worlds
 variants vectors vocabs vocabs.loader vocabs.parser words
@@ -319,11 +319,18 @@ SYNTAX: VERTEX-FORMAT:
 SYNTAX: VERTEX-STRUCT:
     CREATE-CLASS scan-word define-vertex-struct ;
 
-TUPLE: vertex-array < gpu-object
+TUPLE: vertex-array-object < gpu-object
     { program-instance program-instance read-only }
     { vertex-buffers sequence read-only } ;
 
-M: vertex-array dispose
+TUPLE: vertex-array-collection
+    { vertex-formats sequence read-only }
+    { program-instance program-instance read-only } ;
+
+UNION: vertex-array
+    vertex-array-object vertex-array-collection ;
+
+M: vertex-array-object dispose
     [ [ delete-vertex-array ] when* f ] change-handle drop ;
 
 : ?>buffer-ptr ( buffer/ptr -- buffer-ptr )
@@ -331,26 +338,73 @@ M: vertex-array dispose
 : ?>buffer ( buffer/ptr -- buffer )
     dup buffer? [ buffer>> ] unless ; inline
 
-:: <multi-vertex-array> ( vertex-formats program-instance -- vertex-array )
+<PRIVATE
+
+: normalize-vertex-formats ( vertex-formats -- vertex-formats' )
+    [ first2 [ ?>buffer-ptr ] dip 2array ] map ; inline
+
+: (bind-vertex-array) ( vertex-formats program-instance -- )
+    '[ _ swap first2 bind-vertex-format ] each ; inline
+
+: (reset-vertex-array) ( -- )
+    GL_MAX_VERTEX_ATTRIBS get-gl-int iota [ glDisableVertexAttribArray ] each ; inline
+
+:: <multi-vertex-array-object> ( vertex-formats program-instance -- vertex-array )
     gen-vertex-array :> handle
     handle glBindVertexArray
 
-    vertex-formats [ program-instance swap first2 [ ?>buffer-ptr ] dip bind-vertex-format ] each
-    handle program-instance vertex-formats [ first ?>buffer ] map
-    vertex-array boa window-resource ; inline
+    vertex-formats normalize-vertex-formats program-instance (bind-vertex-array)
 
-:: <vertex-array*> ( vertex-buffer program-instance format -- vertex-array )
+    handle program-instance vertex-formats [ first ?>buffer ] map
+    vertex-array-object boa window-resource ; inline
+
+: <multi-vertex-array-collection> ( vertex-formats program-instance -- vertex-array )
+    [ normalize-vertex-formats ] dip vertex-array-collection boa ; inline
+
+:: <vertex-array-object> ( vertex-buffer program-instance format -- vertex-array )
     gen-vertex-array :> handle
     handle glBindVertexArray
     program-instance vertex-buffer ?>buffer-ptr format bind-vertex-format
     handle program-instance vertex-buffer ?>buffer 1array
-    vertex-array boa window-resource ; inline
+    vertex-array-object boa window-resource ; inline
+
+: <vertex-array-collection> ( vertex-buffer program-instance format -- vertex-array )
+    swap [ [ ?>buffer-ptr ] dip 2array 1array ] dip <multi-vertex-array-collection> ; inline
+
+PRIVATE>
+
+GENERIC: bind-vertex-array ( vertex-array -- )
+
+M: vertex-array-object bind-vertex-array
+    handle>> glBindVertexArray ; inline
+
+M: vertex-array-collection bind-vertex-array
+    (reset-vertex-array)
+    [ vertex-formats>> ] [ program-instance>> ] bi (bind-vertex-array) ; inline
+
+: <multi-vertex-array> ( vertex-formats program-instance -- vertex-array )
+    has-vertex-array-objects? get
+    [ <multi-vertex-array-object> ]
+    [ <multi-vertex-array-collection> ] if ; inline
+    
+: <vertex-array*> ( vertex-buffer program-instance format -- vertex-array )
+    has-vertex-array-objects? get
+    [ <vertex-array-object> ]
+    [ <vertex-array-collection> ] if ; inline
 
 : <vertex-array> ( vertex-buffer program-instance -- vertex-array )
     dup program>> vertex-formats>> first <vertex-array*> ; inline
 
-TYPED: vertex-array-buffer ( vertex-array: vertex-array -- vertex-buffer: buffer )
-    vertex-buffers>> first ;
+GENERIC: vertex-array-buffers ( vertex-array -- buffers )
+
+M: vertex-array-object vertex-array-buffers
+    vertex-buffers>> ; inline
+
+M: vertex-array-collection vertex-array-buffers
+    vertex-formats>> [ first buffer>> ] map ; inline
+
+: vertex-array-buffer ( vertex-array: vertex-array -- vertex-buffer: buffer )
+    vertex-array-buffers first ; inline
 
 TUPLE: compile-shader-error shader log ;
 TUPLE: link-program-error program log ;
diff --git a/extra/gpu/state/state.factor b/extra/gpu/state/state.factor
old mode 100644
new mode 100755
index 3064ed4b82..db76774038
--- a/extra/gpu/state/state.factor
+++ b/extra/gpu/state/state.factor
@@ -415,8 +415,6 @@ M: mask-state set-gpu-state*
     [ [ set-gpu-state* ] each ]
     [ set-gpu-state* ] if ; inline
 
-<PRIVATE
-
 : get-gl-bool ( enum -- value )
     0 <uchar> [ glGetBooleanv ] keep *uchar c-bool> ;
 : get-gl-int ( enum -- value )
@@ -437,8 +435,6 @@ M: mask-state set-gpu-state*
 : gl-enabled? ( enum -- ? )
     glIsEnabled c-bool> ;
 
-PRIVATE>
-
 TYPED: get-viewport-state ( -- viewport-state: viewport-state )
     GL_VIEWPORT get-gl-rect <viewport-state> ;
 

From 33bbd05507e57b212ced8856d40423a344b07281 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 18 Feb 2010 08:38:45 +1300
Subject: [PATCH 075/250] io.pathnames: fix doc typo

---
 core/io/pathnames/pathnames-docs.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/io/pathnames/pathnames-docs.factor b/core/io/pathnames/pathnames-docs.factor
index 8dacef6f8c..cc637b59c3 100644
--- a/core/io/pathnames/pathnames-docs.factor
+++ b/core/io/pathnames/pathnames-docs.factor
@@ -92,7 +92,7 @@ HELP: normalize-path
 { $values { "path" "a pathname string" } { "path'" "a new pathname string" } }
 { $description "Prepends the " { $link current-directory } " to the pathname, resolves a " { $snippet "resource:" } " or " { $snippet "vocab:" } " prefix, if present (see " { $link "io.pathnames.special" } "). Also converts the path into a UNC path on Windows." }
 { $notes "High-level words, such as " { $link <file-reader> } " and " { $link delete-file } " call this word for you. It only needs to be called directly when passing pathnames to C functions or external processes. This is because Factor does not use the operating system's notion of a current directory, and instead maintains its own dynamically-scoped " { $link current-directory } " variable." }
-{ $notes "On Windows NT platforms, this word does prepends the Unicode path prefix." }
+{ $notes "On Windows NT platforms, this word prepends the Unicode path prefix." }
 { $examples
   "For example, if you create a file named " { $snippet "data.txt" } " in the current directory, and wish to pass it to a process, you must normalize it:"
   { $code

From 236b2e6dc5fe8c594570af4110a943fc5a5b277d Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Wed, 17 Feb 2010 12:50:32 -0800
Subject: [PATCH 076/250] =?UTF-8?q?update=20gpu=20docs=E2=80=94VAOs=20no?=
 =?UTF-8?q?=20longer=20required?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 extra/gpu/gpu-docs.factor             |  2 +-
 extra/gpu/shaders/shaders-docs.factor | 16 +++++++++++++---
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/extra/gpu/gpu-docs.factor b/extra/gpu/gpu-docs.factor
index 3c0c24e97e..103e0c60a1 100644
--- a/extra/gpu/gpu-docs.factor
+++ b/extra/gpu/gpu-docs.factor
@@ -42,6 +42,6 @@ ARTICLE: "gpu-summary" "GPU-accelerated rendering"
     "gpu.shaders"
     "gpu.render"
 }
-"The library is built on top of the OpenGL API, but it aims to be complete enough that raw OpenGL calls are never needed. OpenGL 2.0 with the vertex array object extension (" { $snippet "GL_APPLE_vertex_array_object" } " or " { $snippet "GL_ARB_vertex_array_object" } ") is required. Some features require later OpenGL versions or additional extensions; these requirements are documented alongside individual words. To make full use of the library, an OpenGL 3.1 or later implementation is recommended." ;
+"The library is built on top of the OpenGL API, but it aims to be complete enough that raw OpenGL calls are never needed. OpenGL 2.0 is required. Some features require later OpenGL versions or additional extensions; these requirements are documented alongside individual words. To make full use of the library, an OpenGL 3.1 or later implementation is recommended." ;
 
 ABOUT: "gpu-summary"
diff --git a/extra/gpu/shaders/shaders-docs.factor b/extra/gpu/shaders/shaders-docs.factor
index dd16224529..96a8561e9f 100644
--- a/extra/gpu/shaders/shaders-docs.factor
+++ b/extra/gpu/shaders/shaders-docs.factor
@@ -167,14 +167,23 @@ HELP: vertex-shader
 { $class-description "This " { $link shader-kind } " indicates that a " { $link shader } " is a vertex shader." } ;
 
 HELP: vertex-array
-{ $class-description "A " { $snippet "vertex-array" } " object associates a shader " { $link program-instance } " with vertex attribute data from one or more " { $link buffer } "s. The format of the binary data inside these buffers is described using " { $link vertex-format } "s. " { $snippet "vertex-array" } "s are constructed using the " { $link <multi-vertex-array> } " or " { $link <vertex-array*> } " words." } ;
+{ $class-description "A " { $snippet "vertex-array" } " object associates a shader " { $link program-instance } " with vertex attribute data from one or more " { $link buffer } "s. The format of the binary data inside these buffers is described using " { $link vertex-format } "s. " { $snippet "vertex-array" } "s are constructed using the " { $link <multi-vertex-array> } " or " { $link <vertex-array*> } " words. The actual type of a vertex-array object is opaque, but the " { $link vertex-array-buffers } " word can be used to query a vertex array object for its component buffers." } ;
+
+HELP: vertex-array-buffers
+{ $values
+    { "vertex-array" vertex-array }
+    { "vertex-buffer" buffer }
+}
+{ $description "Returns a sequence containing all of the " { $link buffer } " objects that make up " { $snippet "vertex-array" } "." } ;
 
 HELP: vertex-array-buffer
 { $values
     { "vertex-array" vertex-array }
     { "vertex-buffer" buffer }
 }
-{ $description "Returns the first " { $link buffer } " object comprised in " { $snippet "vertex-array" } "." } ;
+{ $description "Returns the first " { $link buffer } " object that makes up " { $snippet "vertex-array" } "." } ;
+
+{ vertex-array-buffer vertex-array-buffers } related-words
 
 HELP: vertex-attribute
 { $class-description "This tuple type is passed to " { $link define-vertex-format } " to define a new " { $link vertex-format } " type." } ;
@@ -204,7 +213,8 @@ ARTICLE: "gpu.shaders" "Shader objects"
 { $subsections
     vertex-array
     <multi-vertex-array>
-    vertex-array
+    <vertex-array*>
+    <vertex-array>
     POSTPONE: VERTEX-FORMAT:
 } ;
 

From f26460450e5ea4de9cf7cf7217d540b856e09ea1 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Wed, 17 Feb 2010 16:05:59 -0800
Subject: [PATCH 077/250] Revert "vocabs.loader: make vocab-dir+ use
 path-separator too"

This reverts commit 2dcc7206292cde1ba52b12620a12848f58223a1b.
---
 core/vocabs/loader/loader.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/vocabs/loader/loader.factor b/core/vocabs/loader/loader.factor
index 390cfceb95..0f2e3f7178 100644
--- a/core/vocabs/loader/loader.factor
+++ b/core/vocabs/loader/loader.factor
@@ -42,7 +42,7 @@ PRIVATE>
 : vocab-dir+ ( vocab str/f -- path )
     [ vocab-name "." split ] dip
     [ [ dup last ] dip append suffix ] when*
-    path-separator join ;
+    "/" join ;
 
 : find-vocab-root ( vocab -- path/f )
     vocab-name dup root-cache get at

From 1250a0fcfd2a23edb3504ad81cfa83285d6677f7 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Wed, 17 Feb 2010 16:06:13 -0800
Subject: [PATCH 078/250] Revert "make io.pathnames tests
 path-separator-neutral"

This reverts commit f344c0062966a8c7ff9a9c8e57d06316941f8c12.
---
 core/io/pathnames/pathnames-tests.factor | 35 +++++++++++-------------
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/core/io/pathnames/pathnames-tests.factor b/core/io/pathnames/pathnames-tests.factor
index 38cfe330fb..f23a1ac1f4 100644
--- a/core/io/pathnames/pathnames-tests.factor
+++ b/core/io/pathnames/pathnames-tests.factor
@@ -1,6 +1,6 @@
 USING: io.pathnames io.files.temp io.directories
 continuations math io.files.private kernel
-namespaces sequences tools.test io.pathnames.private ;
+namespaces tools.test io.pathnames.private ;
 IN: io.pathnames.tests
 
 [ "passwd" ] [ "/etc/passwd" file-name ] unit-test
@@ -11,23 +11,20 @@ IN: io.pathnames.tests
 [ "freetype6.dll" ] [ "resource:freetype6.dll" file-name ] unit-test
 [ "freetype6.dll" ] [ "resource:/freetype6.dll" file-name ] unit-test
 
-: >test-path ( path -- path' )
-    [ dup path-separator? [ drop CHAR: / ] when ] map ;
-
-[ "/usr/lib" ] [ "/usr" "lib" append-path >test-path ] unit-test
-[ "/usr/lib" ] [ "/usr/" "lib" append-path >test-path ] unit-test
-[ "/usr/lib" ] [ "/usr" "./lib" append-path >test-path ] unit-test
-[ "/usr/lib/" ] [ "/usr" "./lib/" append-path >test-path ] unit-test
-[ "/lib" ] [ "/usr" "../lib" append-path >test-path ] unit-test
-[ "/lib/" ] [ "/usr" "../lib/" append-path >test-path ] unit-test
+[ "/usr/lib" ] [ "/usr" "lib" append-path ] unit-test
+[ "/usr/lib" ] [ "/usr/" "lib" append-path ] unit-test
+[ "/usr/lib" ] [ "/usr" "./lib" append-path ] unit-test
+[ "/usr/lib/" ] [ "/usr" "./lib/" append-path ] unit-test
+[ "/lib" ] [ "/usr" "../lib" append-path ] unit-test
+[ "/lib/" ] [ "/usr" "../lib/" append-path ] unit-test
 
 [ "" ] [ "" "." append-path ] unit-test
 [ "" ".." append-path ] must-fail
 
-[ "/" ] [ "/" "./." append-path >test-path ] unit-test
-[ "/" ] [ "/" "././" append-path >test-path ] unit-test
-[ "/a/b/lib" ] [ "/a/b/c/d/e/f/" "../../../../lib" append-path >test-path ] unit-test
-[ "/a/b/lib/" ] [ "/a/b/c/d/e/f/" "../../../../lib/" append-path >test-path ] unit-test
+[ "/" ] [ "/" "./." append-path ] unit-test
+[ "/" ] [ "/" "././" append-path ] unit-test
+[ "/a/b/lib" ] [ "/a/b/c/d/e/f/" "../../../../lib" append-path ] unit-test
+[ "/a/b/lib/" ] [ "/a/b/c/d/e/f/" "../../../../lib/" append-path ] unit-test
 
 [ "" "../lib/" append-path ] must-fail
 [ "lib" ] [ "" "lib" append-path ] unit-test
@@ -48,10 +45,10 @@ IN: io.pathnames.tests
 [ "" parent-directory ] must-fail
 [ "." ] [ "boot.x86.64.image" parent-directory ] unit-test
 
-[ "bar/foo" ] [ "bar/baz" "..///foo" append-path >test-path ] unit-test
-[ "bar/baz/foo" ] [ "bar/baz" ".///foo" append-path >test-path ] unit-test
-[ "bar/foo" ] [ "bar/baz" "./..//foo" append-path >test-path ] unit-test
-[ "bar/foo" ] [ "bar/baz" "./../././././././///foo" append-path >test-path ] unit-test
+[ "bar/foo" ] [ "bar/baz" "..///foo" append-path ] unit-test
+[ "bar/baz/foo" ] [ "bar/baz" ".///foo" append-path ] unit-test
+[ "bar/foo" ] [ "bar/baz" "./..//foo" append-path ] unit-test
+[ "bar/foo" ] [ "bar/baz" "./../././././././///foo" append-path ] unit-test
 
 [ t ] [ "resource:core" absolute-path? ] unit-test
 [ f ] [ "" absolute-path? ] unit-test
@@ -64,7 +61,7 @@ IN: io.pathnames.tests
     "." current-directory set
     ".." "resource-path" set
     [ "../core/bootstrap/stage2.factor" ]
-    [ "resource:core/bootstrap/stage2.factor" absolute-path >test-path ]
+    [ "resource:core/bootstrap/stage2.factor" absolute-path ]
     unit-test
 ] with-scope
 

From 97654b67c1109b3f130b773b0af05396ec7c1a99 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Wed, 17 Feb 2010 16:06:30 -0800
Subject: [PATCH 079/250] Revert "io.pathnames: make absolute-path? public"

This reverts commit 48756c9fca10a3a89ab8bb4b55c4fa711e524f74.
---
 core/io/pathnames/pathnames.factor | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/io/pathnames/pathnames.factor b/core/io/pathnames/pathnames.factor
index 2be66ef186..5a9c647973 100644
--- a/core/io/pathnames/pathnames.factor
+++ b/core/io/pathnames/pathnames.factor
@@ -76,8 +76,6 @@ ERROR: no-parent-directory path ;
         [ f ]
     } cond ;
 
-PRIVATE>
-
 : absolute-path? ( path -- ? )
     {
         { [ dup empty? ] [ f ] }
@@ -87,6 +85,8 @@ PRIVATE>
         [ f ]
     } cond nip ;
 
+PRIVATE>
+
 : append-path ( path1 path2 -- path )
     {
         { [ over empty? ] [ append-path-empty ] }

From e70fcf159d9f8d48c8e575324aeec8da66c98486 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Wed, 17 Feb 2010 16:06:45 -0800
Subject: [PATCH 080/250] Revert "fix append-path and vocab-dir to use
 path-separator"

This reverts commit 0f3026b8712816d29143ff49dea807acbf03e0e0.
---
 core/io/pathnames/pathnames.factor | 2 +-
 core/vocabs/loader/loader.factor   | 4 +---
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/core/io/pathnames/pathnames.factor b/core/io/pathnames/pathnames.factor
index 5a9c647973..b307128efb 100644
--- a/core/io/pathnames/pathnames.factor
+++ b/core/io/pathnames/pathnames.factor
@@ -103,7 +103,7 @@ PRIVATE>
         ] }
         [
             [ trim-tail-separators ]
-            [ trim-head-separators ] bi* path-separator glue
+            [ trim-head-separators ] bi* "/" glue
         ]
     } cond ;
 
diff --git a/core/vocabs/loader/loader.factor b/core/vocabs/loader/loader.factor
index 0f2e3f7178..2c0f67641d 100644
--- a/core/vocabs/loader/loader.factor
+++ b/core/vocabs/loader/loader.factor
@@ -35,9 +35,7 @@ M: string vocab-path ( string -- path/f )
 PRIVATE>
 
 : vocab-dir ( vocab -- dir )
-    vocab-name
-    os windows? { { CHAR: . CHAR: \\ } } { { CHAR: . CHAR: / } } ?
-    substitute ;
+    vocab-name { { CHAR: . CHAR: / } } substitute ;
 
 : vocab-dir+ ( vocab str/f -- path )
     [ vocab-name "." split ] dip

From 02d868dabe29f4a22fd8c29c504f3c7d0bccb3ea Mon Sep 17 00:00:00 2001
From: Aaron Schaefer <aaron@elasticdog.com>
Date: Wed, 17 Feb 2010 22:25:53 -0600
Subject: [PATCH 081/250] Solution to Project Euler problem 206

---
 extra/project-euler/206/206-tests.factor |  4 +++
 extra/project-euler/206/206.factor       | 46 ++++++++++++++++++++++++
 2 files changed, 50 insertions(+)
 create mode 100644 extra/project-euler/206/206-tests.factor
 create mode 100644 extra/project-euler/206/206.factor

diff --git a/extra/project-euler/206/206-tests.factor b/extra/project-euler/206/206-tests.factor
new file mode 100644
index 0000000000..132adfb05e
--- /dev/null
+++ b/extra/project-euler/206/206-tests.factor
@@ -0,0 +1,4 @@
+USING: project-euler.206 tools.test ;
+IN: project-euler.206.tests
+
+[ 1389019170 ] [ euler206 ] unit-test
diff --git a/extra/project-euler/206/206.factor b/extra/project-euler/206/206.factor
new file mode 100644
index 0000000000..06946d4db7
--- /dev/null
+++ b/extra/project-euler/206/206.factor
@@ -0,0 +1,46 @@
+! Copyright (c) 2010 Aaron Schaefer. All rights reserved.
+! The contents of this file are licensed under the Simplified BSD License
+! A copy of the license is available at http://factorcode.org/license.txt
+USING: grouping kernel math math.ranges project-euler.common sequences ;
+IN: project-euler.206
+
+! http://projecteuler.net/index.php?section=problems&id=206
+
+! DESCRIPTION
+! -----------
+
+! Find the unique positive integer whose square has the form
+! 1_2_3_4_5_6_7_8_9_0, where each “_” is a single digit.
+
+
+! SOLUTION
+! --------
+
+! Through mathematical analysis, we know that the number must end in 00, and
+! the only way to get the last digits to be 900, is for our answer to end in
+! 30 or 70.
+
+<PRIVATE
+
+! 1020304050607080900 sqrt, rounded up to the nearest 30 ending
+CONSTANT: lo 1010101030
+
+! 1929394959697989900 sqrt, rounded down to the nearest 70 ending
+CONSTANT: hi 1389026570
+
+: form-fitting? ( n -- ? )
+    number>digits 2 group [ first ] map
+    { 1 2 3 4 5 6 7 8 9 0 } = ;
+
+: candidates ( -- seq )
+    lo lo 40 + [ hi 100 <range> ] bi@ append ;
+
+PRIVATE>
+
+: euler206 ( -- answer )
+    candidates [ sq form-fitting? ] find-last nip ;
+
+! [ euler206 ] 100 ave-time
+! 321 ms ave run time - 8.33 SD (100 trials)
+
+SOLUTION: euler206

From 488e5ead26d7757671ba8f748c80f1d7ce11706f Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Fri, 19 Feb 2010 04:11:48 +1300
Subject: [PATCH 082/250] tools.deploy.libraries.windows: add unportable tag to
 avoid loading windows.kernel32 on non-windows platforms

---
 basis/tools/deploy/libraries/windows/tags.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 basis/tools/deploy/libraries/windows/tags.txt

diff --git a/basis/tools/deploy/libraries/windows/tags.txt b/basis/tools/deploy/libraries/windows/tags.txt
new file mode 100644
index 0000000000..6bf68304bb
--- /dev/null
+++ b/basis/tools/deploy/libraries/windows/tags.txt
@@ -0,0 +1 @@
+unportable

From 2a517d31dffff7e0b6ef9056f6edf6b033ce81bd Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Fri, 19 Feb 2010 04:11:57 +1300
Subject: [PATCH 083/250] help.stylesheet: tweak color

---
 basis/help/stylesheet/stylesheet.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/help/stylesheet/stylesheet.factor b/basis/help/stylesheet/stylesheet.factor
index d5b783fef8..254b65e5ac 100644
--- a/basis/help/stylesheet/stylesheet.factor
+++ b/basis/help/stylesheet/stylesheet.factor
@@ -83,7 +83,7 @@ H{
 SYMBOL: output-style
 H{
     { font-style bold }
-    { foreground COLOR: dark-red }
+    { foreground COLOR: DarkOrange4 }
 } output-style set-global
 
 SYMBOL: url-style

From d3d7392fa9424383d71e7af0dce8d9f5853fa174 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Thu, 18 Feb 2010 12:52:33 -0800
Subject: [PATCH 084/250] Implement input grabbing for x11; add do-nothing
 game.input backend for linux. The game and gpu demos now run correctly.

---
 basis/game/input/input.factor       |  2 +-
 basis/game/input/linux/authors.txt  |  1 +
 basis/game/input/linux/linux.factor | 49 +++++++++++++++++++++++++++++
 basis/game/input/linux/summary.txt  |  1 +
 basis/game/input/linux/tags.txt     |  1 +
 basis/ui/backend/x11/x11.factor     | 33 +++++++++++++------
 basis/x11/xlib/xlib.factor          | 14 +++++++++
 7 files changed, 91 insertions(+), 10 deletions(-)
 create mode 100644 basis/game/input/linux/authors.txt
 create mode 100644 basis/game/input/linux/linux.factor
 create mode 100644 basis/game/input/linux/summary.txt
 create mode 100644 basis/game/input/linux/tags.txt

diff --git a/basis/game/input/input.factor b/basis/game/input/input.factor
index a2afbe92a3..7543a05c60 100644
--- a/basis/game/input/input.factor
+++ b/basis/game/input/input.factor
@@ -93,5 +93,5 @@ M: mouse-state clone
 {
     { [ os windows? ] [ "game.input.xinput" require ] }
     { [ os macosx? ] [ "game.input.iokit" require ] }
-    { [ t ] [ ] }
+    { [ os linux? ] [ "game.input.linux" require ] }
 } cond
diff --git a/basis/game/input/linux/authors.txt b/basis/game/input/linux/authors.txt
new file mode 100644
index 0000000000..67cf648cf5
--- /dev/null
+++ b/basis/game/input/linux/authors.txt
@@ -0,0 +1 @@
+Erik Charlebois
\ No newline at end of file
diff --git a/basis/game/input/linux/linux.factor b/basis/game/input/linux/linux.factor
new file mode 100644
index 0000000000..465cefa84b
--- /dev/null
+++ b/basis/game/input/linux/linux.factor
@@ -0,0 +1,49 @@
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel game.input namespaces classes windows.com.syntax
+bit-arrays
+vectors ;
+IN: game.input.linux
+
+SINGLETON: linux-game-input-backend
+
+linux-game-input-backend game-input-backend set-global
+
+M: linux-game-input-backend (open-game-input)
+    ;
+
+M: linux-game-input-backend (close-game-input)
+    ;
+
+M: linux-game-input-backend (reset-game-input)
+    ;
+
+M: linux-game-input-backend get-controllers
+    { } ;
+
+M: linux-game-input-backend product-string
+    drop "" ;
+     
+M: linux-game-input-backend product-id
+    drop GUID: {00000000-0000-0000-0000-000000000000} ;
+     
+M: linux-game-input-backend instance-id
+    drop GUID: {00000000-0000-0000-0000-000000000000} ;
+     
+M: linux-game-input-backend read-controller
+    drop controller-state new ;
+     
+M: linux-game-input-backend calibrate-controller
+    drop ;
+     
+M: linux-game-input-backend vibrate-controller
+    3drop ;
+     
+M: linux-game-input-backend read-keyboard
+    256 <bit-array> keyboard-state boa ;
+     
+M: linux-game-input-backend read-mouse
+    0 0 0 0 2 <vector> mouse-state boa ;
+     
+M: linux-game-input-backend reset-mouse
+    ;
diff --git a/basis/game/input/linux/summary.txt b/basis/game/input/linux/summary.txt
new file mode 100644
index 0000000000..5c88274722
--- /dev/null
+++ b/basis/game/input/linux/summary.txt
@@ -0,0 +1 @@
+Linux backend for game input.
diff --git a/basis/game/input/linux/tags.txt b/basis/game/input/linux/tags.txt
new file mode 100644
index 0000000000..84d4140a70
--- /dev/null
+++ b/basis/game/input/linux/tags.txt
@@ -0,0 +1 @@
+games
diff --git a/basis/ui/backend/x11/x11.factor b/basis/ui/backend/x11/x11.factor
index 4c977f17a4..673dd8e9c3 100644
--- a/basis/ui/backend/x11/x11.factor
+++ b/basis/ui/backend/x11/x11.factor
@@ -1,14 +1,13 @@
 ! Copyright (C) 2005, 2009 Eduardo Cavazos and Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien.c-types arrays ascii assocs colors
-classes.struct combinators io.encodings.ascii
-io.encodings.string io.encodings.utf8 kernel literals math
-namespaces sequences strings ui ui.backend ui.clipboards
-ui.event-loop ui.gadgets ui.gadgets.private ui.gadgets.worlds
-ui.gestures ui.pixel-formats ui.pixel-formats.private
-ui.private x11 x11.clipboard x11.constants x11.events x11.glx
-x11.io x11.windows x11.xim x11.xlib environment command-line
-combinators.short-circuit ;
+USING: accessors alien.c-types ascii assocs classes.struct combinators
+combinators.short-circuit command-line environment io.encodings.ascii
+io.encodings.string io.encodings.utf8 kernel literals locals math
+namespaces sequences specialized-arrays.instances.alien.c-types.uchar
+strings ui ui.backend ui.clipboards ui.event-loop ui.gadgets
+ui.gadgets.private ui.gadgets.worlds ui.gestures ui.pixel-formats
+ui.pixel-formats.private ui.private x11 x11.clipboard x11.constants
+x11.events x11.glx x11.io x11.windows x11.xim x11.xlib ;
 IN: ui.backend.x11
 
 SINGLETON: x11-ui-backend
@@ -328,6 +327,22 @@ M: x11-ui-backend (with-ui) ( quot -- )
 M: x11-ui-backend beep ( -- )
     dpy get 100 XBell drop ;
 
+: black ( -- xcolor ) 0 0 0 0 0 0 XColor <struct-boa> ; inline
+
+M:: x11-ui-backend (grab-input) ( handle -- )
+    handle window>>                                                  :> wnd
+    dpy get                                                          :> dpy
+    dpy wnd uchar-array{ 0 0 0 0 0 0 0 0 } 8 8 XCreateBitmapFromData :> pixmap
+    dpy pixmap dup black dup 0 0 XCreatePixmapCursor                 :> cursor
+
+    dpy wnd 1 NoEventMask GrabModeAsync dup wnd cursor CurrentTime XGrabPointer drop
+
+    dpy cursor XFreeCursor drop
+    dpy pixmap XFreePixmap drop ;
+
+M: x11-ui-backend (ungrab-input)
+    drop dpy get CurrentTime XUngrabPointer drop ;
+
 x11-ui-backend ui-backend set-global
 
 [ "DISPLAY" os-env "ui.tools" "listener" ? ]
diff --git a/basis/x11/xlib/xlib.factor b/basis/x11/xlib/xlib.factor
index a6097c9dad..7235aaf679 100644
--- a/basis/x11/xlib/xlib.factor
+++ b/basis/x11/xlib/xlib.factor
@@ -284,6 +284,11 @@ X-FUNCTION: int XConvertSelection ( Display* display, Atom selection, Atom targe
 X-FUNCTION: Pixmap XCreatePixmap ( Display* display, Drawable d, uint width, uint height, uint depth ) ;
 X-FUNCTION: int XFreePixmap ( Display* display, Pixmap pixmap ) ;
 
+! 5.2 - Creating, Recoloring, and Freeing Cursors
+
+C-TYPE: XColor
+X-FUNCTION: Cursor XCreatePixmapCursor ( Display* display, Pixmap source, Pixmap mask, XColor* foreground_color, XColor* background_color, uint x, uint y ) ;
+X-FUNCTION: int XFreeCursor ( Display* display, Cursor cursor ) ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 ! 6 - Color Management Functions
@@ -1096,6 +1101,7 @@ X-FUNCTION: int XGrabPointer (
 X-FUNCTION: Status XUngrabPointer ( Display* display, Time time ) ;
 X-FUNCTION: Status XChangeActivePointerGrab ( Display* display, uint event_mask, Cursor cursor, Time time ) ;
 X-FUNCTION: Status XGrabKey ( Display* display, int keycode, uint modifiers, Window grab_window, Bool owner_events, int pointer_mode, int keyboard_mode ) ;
+X-FUNCTION: int XGrabKeyboard ( Display* display, Window grab_window, Bool owner_events, int pointer_mode, int keyboard_mode, Time time ) ;
 X-FUNCTION: Status XSetInputFocus ( Display* display, Window focus, int revert_to, Time time ) ;
 
 X-FUNCTION: Status XGetInputFocus ( Display* display,
@@ -1210,6 +1216,14 @@ STRUCT: XVisualInfo
         { colormap_size int }
         { bits_per_rgb int } ;
 
+! 16.9 Manipulating Bitmaps
+X-FUNCTION: Pixmap XCreateBitmapFromData (
+    Display* display,
+    Drawable d,
+    char* data,
+    uint width,
+    uint height ) ;
+
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 ! Appendix D - Compatibility Functions
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

From 5d80153d53671a6691feb1c72abffa38c902d940 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Thu, 18 Feb 2010 12:53:15 -0800
Subject: [PATCH 085/250] Bindings to libusb

---
 extra/libusb/authors.txt   |   1 +
 extra/libusb/libusb.factor | 422 +++++++++++++++++++++++++++++++++++++
 extra/libusb/summary.txt   |   1 +
 extra/libusb/tags.txt      |   1 +
 4 files changed, 425 insertions(+)
 create mode 100644 extra/libusb/authors.txt
 create mode 100644 extra/libusb/libusb.factor
 create mode 100644 extra/libusb/summary.txt
 create mode 100644 extra/libusb/tags.txt

diff --git a/extra/libusb/authors.txt b/extra/libusb/authors.txt
new file mode 100644
index 0000000000..67cf648cf5
--- /dev/null
+++ b/extra/libusb/authors.txt
@@ -0,0 +1 @@
+Erik Charlebois
\ No newline at end of file
diff --git a/extra/libusb/libusb.factor b/extra/libusb/libusb.factor
new file mode 100644
index 0000000000..d521015d6f
--- /dev/null
+++ b/extra/libusb/libusb.factor
@@ -0,0 +1,422 @@
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien alien.c-types alien.libraries
+alien.syntax classes.struct combinators endian io.binary
+kernel locals math sequences specialized-arrays
+system unix.time unix.types ;
+FROM: alien.c-types => short ;
+IN: libusb
+
+<< "libusb" {
+        { [ os windows? ] [ "libusb-1.0.dll" ] }
+        { [ os macosx? ] [ "libusb-1.0.dylib"  ] }
+        { [ os unix?  ] [ "libusb-1.0.so" ] }
+    } cond "cdecl" add-library >>
+LIBRARY: libusb
+
+: libusb_cpu_to_le16 ( x -- y )
+    2 >native-endian le> ; inline
+
+ALIAS: libusb_le16_to_cpu libusb_cpu_to_le16
+
+CONSTANT: LIBUSB_CLASS_PER_INTERFACE 0
+CONSTANT: LIBUSB_CLASS_AUDIO         1
+CONSTANT: LIBUSB_CLASS_COMM          2
+CONSTANT: LIBUSB_CLASS_HID           3
+CONSTANT: LIBUSB_CLASS_PRINTER       7
+CONSTANT: LIBUSB_CLASS_PTP           6
+CONSTANT: LIBUSB_CLASS_MASS_STORAGE  8
+CONSTANT: LIBUSB_CLASS_HUB           9
+CONSTANT: LIBUSB_CLASS_DATA          10
+CONSTANT: LIBUSB_CLASS_VENDOR_SPEC HEX: ff
+TYPEDEF: int libusb_class_code
+
+CONSTANT: LIBUSB_DT_DEVICE    HEX: 01
+CONSTANT: LIBUSB_DT_CONFIG    HEX: 02
+CONSTANT: LIBUSB_DT_STRING    HEX: 03
+CONSTANT: LIBUSB_DT_INTERFACE HEX: 04
+CONSTANT: LIBUSB_DT_ENDPOINT  HEX: 05
+CONSTANT: LIBUSB_DT_HID       HEX: 21
+CONSTANT: LIBUSB_DT_REPORT    HEX: 22
+CONSTANT: LIBUSB_DT_PHYSICAL  HEX: 23
+CONSTANT: LIBUSB_DT_HUB       HEX: 29
+TYPEDEF: int libusb_descriptor_type
+
+CONSTANT: LIBUSB_DT_DEVICE_SIZE           18
+CONSTANT: LIBUSB_DT_CONFIG_SIZE           9
+CONSTANT: LIBUSB_DT_INTERFACE_SIZE        9
+CONSTANT: LIBUSB_DT_ENDPOINT_SIZE         7
+CONSTANT: LIBUSB_DT_ENDPOINT_AUDIO_SIZE   9
+CONSTANT: LIBUSB_DT_HUB_NONVAR_SIZE       7
+
+CONSTANT: LIBUSB_ENDPOINT_ADDRESS_MASK    HEX: 0f
+CONSTANT: LIBUSB_ENDPOINT_DIR_MASK        HEX: 80
+
+CONSTANT: LIBUSB_ENDPOINT_IN  HEX: 80
+CONSTANT: LIBUSB_ENDPOINT_OUT HEX: 00
+TYPEDEF: int libusb_endpoint_direction
+
+CONSTANT: LIBUSB_TRANSFER_TYPE_MASK HEX: 03
+
+CONSTANT: LIBUSB_TRANSFER_TYPE_CONTROL     0
+CONSTANT: LIBUSB_TRANSFER_TYPE_ISOCHRONOUS 1
+CONSTANT: LIBUSB_TRANSFER_TYPE_BULK        2
+CONSTANT: LIBUSB_TRANSFER_TYPE_INTERRUPT   3
+TYPEDEF: int libusb_transfer_type
+
+CONSTANT: LIBUSB_REQUEST_GET_STATUS        HEX: 00
+CONSTANT: LIBUSB_REQUEST_CLEAR_FEATURE     HEX: 01
+CONSTANT: LIBUSB_REQUEST_SET_FEATURE       HEX: 03
+CONSTANT: LIBUSB_REQUEST_SET_ADDRESS       HEX: 05
+CONSTANT: LIBUSB_REQUEST_GET_DESCRIPTOR    HEX: 06
+CONSTANT: LIBUSB_REQUEST_SET_DESCRIPTOR    HEX: 07
+CONSTANT: LIBUSB_REQUEST_GET_CONFIGURATION HEX: 08
+CONSTANT: LIBUSB_REQUEST_SET_CONFIGURATION HEX: 09
+CONSTANT: LIBUSB_REQUEST_GET_INTERFACE     HEX: 0A
+CONSTANT: LIBUSB_REQUEST_SET_INTERFACE     HEX: 0B
+CONSTANT: LIBUSB_REQUEST_SYNCH_FRAME       HEX: 0C
+TYPEDEF: int libusb_standard_request
+
+CONSTANT: LIBUSB_REQUEST_TYPE_STANDARD HEX: 00
+CONSTANT: LIBUSB_REQUEST_TYPE_CLASS    HEX: 20
+CONSTANT: LIBUSB_REQUEST_TYPE_VENDOR   HEX: 40
+CONSTANT: LIBUSB_REQUEST_TYPE_RESERVED HEX: 60
+
+CONSTANT: LIBUSB_RECIPIENT_DEVICE    HEX: 00
+CONSTANT: LIBUSB_RECIPIENT_INTERFACE HEX: 01
+CONSTANT: LIBUSB_RECIPIENT_ENDPOINT  HEX: 02
+CONSTANT: LIBUSB_RECIPIENT_OTHER     HEX: 03
+TYPEDEF: int libusb_request_recipient
+
+CONSTANT: LIBUSB_ISO_SYNC_TYPE_MASK HEX: 0C
+
+CONSTANT: LIBUSB_ISO_SYNC_TYPE_NONE     0
+CONSTANT: LIBUSB_ISO_SYNC_TYPE_ASYNC    1
+CONSTANT: LIBUSB_ISO_SYNC_TYPE_ADAPTIVE 2
+CONSTANT: LIBUSB_ISO_SYNC_TYPE_SYNC     3
+TYPEDEF: int libusb_iso_sync_type
+
+CONSTANT: LIBUSB_ISO_USAGE_TYPE_MASK HEX: 30
+
+CONSTANT: LIBUSB_ISO_USAGE_TYPE_DATA     0
+CONSTANT: LIBUSB_ISO_USAGE_TYPE_FEEDBACK 1
+CONSTANT: LIBUSB_ISO_USAGE_TYPE_IMPLICIT 2
+TYPEDEF: int libusb_iso_usage_type
+
+STRUCT: libusb_device_descriptor
+    { bLength             uint8_t  }
+    { bDescriptorType     uint8_t  }
+    { bcdUSB              uint16_t }
+    { bDeviceClass        uint8_t  }
+    { bDeviceSubClass     uint8_t  }
+    { bDeviceProtocol     uint8_t  }
+    { bMaxPacketSize0     uint8_t  }
+    { idVendor            uint16_t }
+    { idProduct           uint16_t }
+    { bcdDevice           uint16_t }
+    { iManufacturer       uint8_t  }
+    { iProduct            uint8_t  }
+    { iSerialNumber       uint8_t  }
+    { bNumConfigurations  uint8_t  } ;
+
+STRUCT: libusb_endpoint_descriptor
+    { bLength           uint8_t  }
+    { bDescriptorType   uint8_t  }
+    { bEndpointAddress  uint8_t  }
+    { bmAttributes      uint8_t  }
+    { wMaxPacketSize    uint16_t }
+    { bInterval         uint8_t  }
+    { bRefresh          uint8_t  }
+    { bSynchAddress     uint8_t  }
+    { extra             uchar*   }
+    { extra_length      int      } ;
+
+STRUCT: libusb_interface_descriptor
+    { bLength             uint8_t                     }
+    { bDescriptorType     uint8_t                     }
+    { bInterfaceNumber    uint8_t                     }
+    { bAlternateSetting   uint8_t                     }
+    { bNumEndpoints       uint8_t                     }
+    { bInterfaceClass     uint8_t                     }
+    { bInterfaceSubClass  uint8_t                     }
+    { bInterfaceProtocol  uint8_t                     }
+    { iInterface          uint8_t                     }
+    { endpoint            libusb_endpoint_descriptor* }
+    { extra               uchar*                      }
+    { extra_length        int                         } ;
+
+STRUCT: libusb_interface
+    { altsetting     libusb_interface_descriptor* }
+    { num_altsetting int                          } ;
+
+STRUCT: libusb_config_descriptor
+    { bLength              uint8_t           }
+    { bDescriptorType      uint8_t           }
+    { wTotalLength         uint16_t          }
+    { bNumInterfaces       uint8_t           }
+    { bConfigurationValue  uint8_t           }
+    { iConfiguration       uint8_t           }
+    { bmAttributes         uint8_t           }
+    { MaxPower             uint8_t           }
+    { interface            libusb_interface* }
+    { extra                uchar*            }
+    { extra_length         int               } ;
+
+STRUCT: libusb_control_setup
+    { bmRequestType  uint8_t  }
+    { bRequest       uint8_t  }
+    { wValue         uint16_t }
+    { wIndex         uint16_t }
+    { wLength        uint16_t } ;
+
+: LIBUSB_CONTROL_SETUP_SIZE ( -- x ) libusb_control_setup heap-size ; inline
+
+C-TYPE: libusb_context
+C-TYPE: libusb_device
+C-TYPE: libusb_device_handle
+
+CONSTANT: LIBUSB_SUCCESS             0
+CONSTANT: LIBUSB_ERROR_IO            -1
+CONSTANT: LIBUSB_ERROR_INVALID_PARAM -2
+CONSTANT: LIBUSB_ERROR_ACCESS        -3
+CONSTANT: LIBUSB_ERROR_NO_DEVICE     -4
+CONSTANT: LIBUSB_ERROR_NOT_FOUND     -5
+CONSTANT: LIBUSB_ERROR_BUSY          -6
+CONSTANT: LIBUSB_ERROR_TIMEOUT       -7
+CONSTANT: LIBUSB_ERROR_OVERFLOW      -8
+CONSTANT: LIBUSB_ERROR_PIPE          -9
+CONSTANT: LIBUSB_ERROR_INTERRUPTED   -10
+CONSTANT: LIBUSB_ERROR_NO_MEM        -11
+CONSTANT: LIBUSB_ERROR_NOT_SUPPORTED -12
+CONSTANT: LIBUSB_ERROR_OTHER         -99
+TYPEDEF: int libusb_error
+
+C-ENUM:
+    LIBUSB_TRANSFER_COMPLETED
+    LIBUSB_TRANSFER_ERROR
+    LIBUSB_TRANSFER_TIMED_OUT
+    LIBUSB_TRANSFER_CANCELLED
+    LIBUSB_TRANSFER_STALL
+    LIBUSB_TRANSFER_NO_DEVICE
+    LIBUSB_TRANSFER_OVERFLOW ;
+TYPEDEF: int libusb_transfer_status
+
+CONSTANT: LIBUSB_TRANSFER_SHORT_NOT_OK  1
+CONSTANT: LIBUSB_TRANSFER_FREE_BUFFER   2
+CONSTANT: LIBUSB_TRANSFER_FREE_TRANSFER 4
+TYPEDEF: int libusb_transfer_flags
+
+STRUCT: libusb_iso_packet_descriptor
+    { length        uint                   }
+    { actual_length uint                   }
+    { status        libusb_transfer_status } ;
+SPECIALIZED-ARRAY: libusb_iso_packet_descriptor
+
+C-TYPE: libusb_transfer
+
+CALLBACK: void libusb_transfer_cb_fn ( libusb_transfer* transfer ) ;
+
+STRUCT: libusb_transfer
+    { dev_handle      libusb_device_handle*           }
+    { flags           uint8_t                         }
+    { endpoint        uchar                           }
+    { type            uchar                           }
+    { timeout         uint                            }
+    { status          libusb_transfer_status          }
+    { length          int                             }
+    { actual_length   int                             }
+    { callback        libusb_transfer_cb_fn           }
+    { user_data       void*                           }
+    { buffer          uchar*                          }
+    { num_iso_packets int                             }
+    { iso_packet_desc libusb_iso_packet_descriptor[0] } ;
+
+FUNCTION: int libusb_init ( libusb_context** ctx ) ;
+FUNCTION: void libusb_exit ( libusb_context* ctx ) ;
+FUNCTION: void libusb_set_debug ( libusb_context* ctx, int level ) ;
+
+FUNCTION: ssize_t libusb_get_device_list ( libusb_context* ctx, libusb_device*** list ) ;
+FUNCTION: void libusb_free_device_list ( libusb_device** list, int unref_devices ) ;
+FUNCTION: libusb_device* libusb_ref_device ( libusb_device* dev ) ;
+FUNCTION: void libusb_unref_device ( libusb_device* dev ) ;
+
+FUNCTION: int libusb_get_configuration ( libusb_device_handle* dev, int* config ) ;
+FUNCTION: int libusb_get_device_descriptor ( libusb_device* dev, libusb_device_descriptor* desc ) ;
+FUNCTION: int libusb_get_active_config_descriptor ( libusb_device* dev, libusb_config_descriptor** config ) ;
+FUNCTION: int libusb_get_config_descriptor ( libusb_device* dev, uint8_t config_index, libusb_config_descriptor** config ) ;
+FUNCTION: int libusb_get_config_descriptor_by_value ( libusb_device* dev, uint8_t bConfigurationValue, libusb_config_descriptor** config ) ;
+FUNCTION: void libusb_free_config_descriptor ( libusb_config_descriptor* config ) ;
+FUNCTION: uint8_t libusb_get_bus_number ( libusb_device* dev ) ;
+FUNCTION: uint8_t libusb_get_device_address ( libusb_device* dev ) ;
+FUNCTION: int libusb_get_max_packet_size ( libusb_device* dev, uchar endpoint ) ;
+
+FUNCTION: int libusb_open ( libusb_device* dev, libusb_device_handle** handle ) ;
+FUNCTION: void libusb_close ( libusb_device_handle* dev_handle ) ;
+FUNCTION: libusb_device* libusb_get_device ( libusb_device_handle* dev_handle ) ;
+
+FUNCTION: int libusb_set_configuration ( libusb_device_handle* dev, int configuration ) ;
+FUNCTION: int libusb_claim_interface ( libusb_device_handle* dev, int iface ) ;
+FUNCTION: int libusb_release_interface ( libusb_device_handle* dev, int iface ) ;
+
+FUNCTION: libusb_device_handle* libusb_open_device_with_vid_pid ( libusb_context* ctx, uint16_t vendor_id, uint16_t product_id ) ;
+
+FUNCTION: int libusb_set_interface_alt_setting ( libusb_device_handle* dev, int interface_number, int alternate_setting ) ;
+FUNCTION: int libusb_clear_halt ( libusb_device_handle* dev, uchar endpoint ) ;
+FUNCTION: int libusb_reset_device ( libusb_device_handle* dev ) ;
+
+FUNCTION: int libusb_kernel_driver_active ( libusb_device_handle* dev, int interface ) ;
+FUNCTION: int libusb_detach_kernel_driver ( libusb_device_handle* dev, int interface ) ;
+FUNCTION: int libusb_attach_kernel_driver ( libusb_device_handle* dev, int interface ) ;
+
+: libusb_control_transfer_get_data ( transfer -- data )
+    buffer>> LIBUSB_CONTROL_SETUP_SIZE swap <displaced-alien> ; inline
+
+: libusb_control_transfer_get_setup ( transfer -- setup )
+    buffer>> libusb_control_setup memory>struct ; inline
+
+:: libusb_fill_control_setup ( buffer bmRequestType bRequest wValue wIndex wLength -- )
+    buffer libusb_control_setup memory>struct
+    bmRequestType              >>bmRequestType
+    bRequest                   >>bRequest
+    wValue libusb_cpu_to_le16  >>wValue
+    wIndex libusb_cpu_to_le16  >>wIndex
+    wLength libusb_cpu_to_le16 >>wLength drop ; inline
+
+FUNCTION: libusb_transfer* libusb_alloc_transfer ( int iso_packets ) ;
+FUNCTION: int libusb_submit_transfer ( libusb_transfer* transfer ) ;
+FUNCTION: int libusb_cancel_transfer ( libusb_transfer* transfer ) ;
+FUNCTION: void libusb_free_transfer ( libusb_transfer* transfer ) ;
+
+:: libusb_fill_control_transfer ( transfer dev_handle buffer callback user_data timeout -- )
+    transfer
+    dev_handle                   >>dev_handle
+    0                            >>endpoint
+    LIBUSB_TRANSFER_TYPE_CONTROL >>type
+    timeout                      >>timeout
+    buffer                       >>buffer
+    user_data                    >>user_data
+    callback                     >>callback
+    
+    buffer [
+        libusb_control_setup memory>struct wLength>> LIBUSB_CONTROL_SETUP_SIZE +
+    ] [ 0 ] if* >>length drop ; inline
+
+:: libusb_fill_bulk_transfer ( transfer dev_handle endpoint buffer length callback user_data timeout -- )
+    transfer
+    dev_handle                >>dev_handle
+    endpoint                  >>endpoint
+    LIBUSB_TRANSFER_TYPE_BULK >>type
+    timeout                   >>timeout
+    buffer                    >>buffer
+    length                    >>length
+    user_data                 >>user_data
+    callback                  >>callback
+    drop ; inline
+
+:: libusb_fill_interrupt_transfer ( transfer dev_handle endpoint buffer length callback user_data timeout -- )
+    transfer
+    dev_handle                     >>dev_handle
+    endpoint                       >>endpoint
+    LIBUSB_TRANSFER_TYPE_INTERRUPT >>type
+    timeout                        >>timeout
+    buffer                         >>buffer
+    length                         >>length
+    user_data                      >>user_data
+    callback                       >>callback
+    drop ; inline
+
+:: libusb_fill_iso_transfer ( transfer dev_handle endpoint buffer length num_iso_packets callback user_data timeout -- )
+    transfer
+    dev_handle                       >>dev_handle
+    endpoint                         >>endpoint
+    LIBUSB_TRANSFER_TYPE_ISOCHRONOUS >>type
+    timeout                          >>timeout
+    buffer                           >>buffer
+    length                           >>length
+    num_iso_packets                  >>num_iso_packets
+    user_data                        >>user_data
+    callback                         >>callback
+    drop ; inline
+
+: libusb_set_iso_packet_lengths ( transfer length -- )
+    [ [ iso_packet_desc>> >c-ptr ]
+      [ num_iso_packets>> ] bi
+      <direct-libusb_iso_packet_descriptor-array>
+    ] dip [ >>length drop ] curry each ; inline
+    
+:: libusb_get_iso_packet_buffer ( transfer packet -- data )
+    packet transfer num_iso_packets>> >=
+    [ f ]
+    [
+        transfer
+        [ iso_packet_desc>> >c-ptr ] 
+        [ num_iso_packets>> ] bi
+        <direct-libusb_iso_packet_descriptor-array> 0
+        [ length>> + ] reduce
+        transfer buffer>> <displaced-alien>
+    ] if ;
+
+:: libusb_get_iso_packet_buffer_simple ( transfer packet -- data )
+    packet transfer num_iso_packets>> >=
+    [ f ]
+    [
+        0 transfer
+        [ iso_packet_desc>> >c-ptr ] 
+        [ num_iso_packets>> ] bi
+        <direct-libusb_iso_packet_descriptor-array> nth
+        length>> packet *
+        transfer buffer>> <displaced-alien>
+    ] if ;
+
+FUNCTION: int libusb_control_transfer ( libusb_device_handle* dev_handle,
+    uint8_t request_type, uint8_t request, uint16_t value, uint16_t index,
+    uchar* data, uint16_t length, uint timeout ) ;
+
+FUNCTION: int libusb_bulk_transfer ( libusb_device_handle* dev_handle,
+    uchar endpoint, uchar* data, int length,
+    int* actual_length, uint timeout ) ;
+
+FUNCTION: int libusb_interrupt_transfer ( libusb_device_handle* dev_handle,
+    uchar endpoint, uchar* data, int length,
+    int* actual_length, int timeout ) ;
+
+:: libusb_get_descriptor ( dev desc_type desc_index data length -- int )
+    dev LIBUSB_ENDPOINT_IN LIBUSB_REQUEST_GET_DESCRIPTOR
+    desc_type 8 shift desc_index bitor 0 data
+    length 1000 libusb_control_transfer ; inline
+
+:: libusb_get_string_descriptor ( dev desc_index langid data length -- int )
+    dev LIBUSB_ENDPOINT_IN LIBUSB_REQUEST_GET_DESCRIPTOR
+    LIBUSB_DT_STRING 8 shift desc_index bitor
+    langid data length 1000 libusb_control_transfer ; inline
+
+FUNCTION: int libusb_get_string_descriptor_ascii ( libusb_device_handle* dev,
+                                                   uint8_t               index,
+                                                   uchar*                data,
+                                                   int                   length ) ;
+
+FUNCTION: int libusb_try_lock_events ( libusb_context* ctx ) ;
+FUNCTION: void libusb_lock_events ( libusb_context* ctx ) ;
+FUNCTION: void libusb_unlock_events ( libusb_context* ctx ) ;
+FUNCTION: int libusb_event_handling_ok ( libusb_context* ctx ) ;
+FUNCTION: int libusb_event_handler_active ( libusb_context* ctx ) ;
+FUNCTION: void libusb_lock_event_waiters ( libusb_context* ctx ) ;
+FUNCTION: void libusb_unlock_event_waiters ( libusb_context* ctx ) ;
+FUNCTION: int libusb_wait_for_event ( libusb_context* ctx, timeval* tv ) ;
+FUNCTION: int libusb_handle_events_timeout ( libusb_context* ctx, timeval* tv ) ;
+FUNCTION: int libusb_handle_events ( libusb_context* ctx ) ;
+FUNCTION: int libusb_handle_events_locked ( libusb_context* ctx, timeval* tv ) ;
+FUNCTION: int libusb_get_next_timeout ( libusb_context* ctx, timeval* tv ) ;
+
+STRUCT: libusb_pollfd
+    { fd     int   }
+    { events short } ;
+
+CALLBACK: void libusb_pollfd_added_cb ( int fd, short events, void* user_data ) ;
+CALLBACK: void libusb_pollfd_removed_cb ( int fd, void* user_data ) ;
+
+FUNCTION: libusb_pollfd** libusb_get_pollfds ( libusb_context* ctx ) ;
+FUNCTION: void libusb_set_pollfd_notifiers ( libusb_context*          ctx,
+                                             libusb_pollfd_added_cb   added_cb,
+                                             libusb_pollfd_removed_cb removed_cb,
+                                             void*                    user_data ) ;
diff --git a/extra/libusb/summary.txt b/extra/libusb/summary.txt
new file mode 100644
index 0000000000..fc00ac5307
--- /dev/null
+++ b/extra/libusb/summary.txt
@@ -0,0 +1 @@
+Bindings to libusb
diff --git a/extra/libusb/tags.txt b/extra/libusb/tags.txt
new file mode 100644
index 0000000000..bb863cf9a0
--- /dev/null
+++ b/extra/libusb/tags.txt
@@ -0,0 +1 @@
+bindings

From 220dd88a2ca6d2b7cac84d54773cb055cf253411 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Fri, 19 Feb 2010 12:31:52 +1300
Subject: [PATCH 086/250] Update documentation for new help lint check

---
 basis/calendar/calendar-docs.factor           |  6 +--
 basis/calendar/calendar.factor                |  6 +--
 basis/compression/lzw/lzw-docs.factor         |  2 -
 basis/db/tuples/tuples-docs.factor            |  2 +-
 basis/db/tuples/tuples.factor                 |  2 +-
 basis/dlists/dlists-docs.factor               |  2 +-
 basis/dlists/dlists.factor                    |  2 +-
 .../normalization/normalization-docs.factor   |  4 +-
 .../images/normalization/normalization.factor |  6 +--
 basis/lists/lazy/lazy-docs.factor             |  2 +-
 basis/math/bitwise/bitwise-docs.factor        | 30 +++++++--------
 basis/math/bitwise/bitwise.factor             | 38 ++++++++-----------
 .../combinatorics/combinatorics-docs.factor   |  8 ++--
 basis/math/combinatorics/combinatorics.factor |  8 ++--
 .../math/polynomials/polynomials-docs.factor  |  6 +--
 basis/math/polynomials/polynomials.factor     |  6 +--
 .../math/quaternions/quaternions-docs.factor  |  2 +-
 basis/math/quaternions/quaternions.factor     |  6 +--
 basis/math/statistics/statistics-docs.factor  |  2 -
 basis/opengl/shaders/shaders-docs.factor      |  2 +-
 basis/random/random-docs.factor               |  2 +-
 basis/random/random.factor                    |  2 +-
 basis/roman/roman-docs.factor                 | 10 ++---
 basis/roman/roman.factor                      | 17 +++++----
 basis/sequences/deep/deep-docs.factor         |  2 +-
 basis/ui/gadgets/worlds/worlds-docs.factor    |  2 +-
 basis/xml-rpc/xml-rpc-docs.factor             |  2 +-
 basis/xml-rpc/xml-rpc.factor                  |  2 +-
 basis/xml/traversal/traversal-docs.factor     |  2 +-
 basis/xml/traversal/traversal.factor          |  2 +-
 core/kernel/kernel-docs.factor                |  2 +-
 core/parser/parser-docs.factor                |  2 +-
 core/sequences/sequences-docs.factor          | 23 ++++++-----
 core/sequences/sequences.factor               |  6 +--
 extra/game/models/collada/collada-docs.factor |  4 +-
 extra/game/models/collada/collada.factor      |  2 +-
 extra/game/models/obj/obj-docs.factor         |  2 +-
 extra/gpu/shaders/shaders-docs.factor         |  2 +-
 extra/math/transforms/fft/fft-docs.factor     |  2 +-
 extra/math/transforms/fft/fft.factor          | 12 +++---
 extra/math/transforms/haar/haar-docs.factor   |  4 +-
 extra/math/transforms/haar/haar.factor        |  6 +--
 extra/memory/piles/piles-docs.factor          |  1 -
 extra/mongodb/driver/driver-docs.factor       |  5 ---
 extra/spider/spider-docs.factor               |  1 -
 45 files changed, 120 insertions(+), 139 deletions(-)

diff --git a/basis/calendar/calendar-docs.factor b/basis/calendar/calendar-docs.factor
index 616c4d2c2c..6ce8b1d5fd 100644
--- a/basis/calendar/calendar-docs.factor
+++ b/basis/calendar/calendar-docs.factor
@@ -309,7 +309,7 @@ HELP: time-
 } ;
 
 HELP: convert-timezone
-{ $values { "timestamp" timestamp } { "duration" duration } { "timestamp" timestamp } }
+{ $values { "timestamp" timestamp } { "duration" duration } { "timestamp'" timestamp } }
 { $description "Converts the " { $snippet "timestamp" } "'s " { $snippet "gmt-offset" } " to the GMT offset represented by the " { $snippet "duration" } "." }
 { $examples
     { $example "USING: accessors calendar prettyprint ;"
@@ -319,7 +319,7 @@ HELP: convert-timezone
 } ;
 
 HELP: >local-time
-{ $values { "timestamp" timestamp } { "timestamp" timestamp } }
+{ $values { "timestamp" timestamp } { "timestamp'" timestamp } }
 { $description "Converts the " { $snippet "timestamp" } " to the timezone of your computer." }
 { $examples
     { $example "USING: accessors calendar kernel prettyprint ;"
@@ -329,7 +329,7 @@ HELP: >local-time
 } ;
 
 HELP: >gmt
-{ $values { "timestamp" timestamp } { "timestamp" timestamp } }
+{ $values { "timestamp" timestamp } { "timestamp'" timestamp } }
 { $description "Converts the " { $snippet "timestamp" } " to the GMT timezone." }
 { $examples
     { $example "USING: accessors calendar kernel prettyprint ;"
diff --git a/basis/calendar/calendar.factor b/basis/calendar/calendar.factor
index 3940af4856..1a64ceb646 100644
--- a/basis/calendar/calendar.factor
+++ b/basis/calendar/calendar.factor
@@ -316,15 +316,15 @@ M: duration <=> [ duration>years ] compare ;
 
 GENERIC: time- ( time1 time2 -- time3 )
 
-: convert-timezone ( timestamp duration -- timestamp )
+: convert-timezone ( timestamp duration -- timestamp' )
     over gmt-offset>> over = [ drop ] [
         [ over gmt-offset>> time- time+ ] keep >>gmt-offset
     ] if ;
 
-: >local-time ( timestamp -- timestamp )
+: >local-time ( timestamp -- timestamp' )
     gmt-offset-duration convert-timezone ;
 
-: >gmt ( timestamp -- timestamp )
+: >gmt ( timestamp -- timestamp' )
     instant convert-timezone ;
 
 M: timestamp <=> ( ts1 ts2 -- n )
diff --git a/basis/compression/lzw/lzw-docs.factor b/basis/compression/lzw/lzw-docs.factor
index 28dc36902b..55c54bc9f7 100644
--- a/basis/compression/lzw/lzw-docs.factor
+++ b/basis/compression/lzw/lzw-docs.factor
@@ -20,7 +20,6 @@ HELP: tiff-lzw-uncompress
 
 HELP: lzw-read
 { $values
-    { "lzw" lzw }
     { "lzw" lzw } { "n" integer }
 }
 { $description "Read the next LZW code." } ;
@@ -48,7 +47,6 @@ HELP: code-space-full?
 HELP: reset-lzw-uncompress
 { $values
     { "lzw" lzw }
-    { "lzw" lzw }
 }
 { $description "Reset the LZW uncompressor state (either at initialization time or immediately after receiving a Clear Code). " } ;
 
diff --git a/basis/db/tuples/tuples-docs.factor b/basis/db/tuples/tuples-docs.factor
index 01d65484f3..2c5db1c90d 100644
--- a/basis/db/tuples/tuples-docs.factor
+++ b/basis/db/tuples/tuples-docs.factor
@@ -51,7 +51,7 @@ HELP: <insert-user-assigned-statement>
 HELP: <select-by-slots-statement>
 { $values
      { "tuple" tuple } { "class" class }
-     { "tuple" tuple } }
+     { "statement" tuple } }
 { $description "A database-specific hook for generating the SQL for a select statement." } ;
 
 HELP: <update-tuple-statement>
diff --git a/basis/db/tuples/tuples.factor b/basis/db/tuples/tuples.factor
index 388c9ba47e..d193b5921e 100644
--- a/basis/db/tuples/tuples.factor
+++ b/basis/db/tuples/tuples.factor
@@ -14,7 +14,7 @@ HOOK: <insert-db-assigned-statement> db-connection ( class -- object )
 HOOK: <insert-user-assigned-statement> db-connection ( class -- object )
 HOOK: <update-tuple-statement> db-connection ( class -- object )
 HOOK: <delete-tuples-statement> db-connection ( tuple class -- object )
-HOOK: <select-by-slots-statement> db-connection ( tuple class -- tuple )
+HOOK: <select-by-slots-statement> db-connection ( tuple class -- statement )
 HOOK: <count-statement> db-connection ( query -- statement )
 HOOK: query>statement db-connection ( query -- statement )
 HOOK: insert-tuple-set-key db-connection ( tuple statement -- )
diff --git a/basis/dlists/dlists-docs.factor b/basis/dlists/dlists-docs.factor
index 716c20d6f6..5036441f60 100644
--- a/basis/dlists/dlists-docs.factor
+++ b/basis/dlists/dlists-docs.factor
@@ -48,7 +48,7 @@ HELP: dlist-find
 } ;
 
 HELP: dlist-filter
-{ $values { "dlist" { $link dlist } } { "quot" quotation } { "dlist" { $link dlist } } }
+{ $values { "dlist" { $link dlist } } { "quot" quotation } { "dlist'" { $link dlist } } }
 { $description "Applies the quotation to each element of the " { $link dlist } " in turn, removing the corresponding nodes if the quotation returns " { $link f } "." }
 { $side-effects { "dlist" } } ;
 
diff --git a/basis/dlists/dlists.factor b/basis/dlists/dlists.factor
index 668ba23054..317ed81e3e 100644
--- a/basis/dlists/dlists.factor
+++ b/basis/dlists/dlists.factor
@@ -157,7 +157,7 @@ M: dlist clear-deque ( dlist -- )
 
 : 1dlist ( obj -- dlist ) <dlist> [ push-front ] keep ;
 
-: dlist-filter ( dlist quot -- dlist )
+: dlist-filter ( dlist quot -- dlist' )
     over [ '[ dup obj>> @ [ drop ] [ _ delete-node ] if ] dlist-each-node ] keep ; inline
 
 M: dlist clone
diff --git a/basis/images/normalization/normalization-docs.factor b/basis/images/normalization/normalization-docs.factor
index 8ed4b659ed..39e2fee769 100644
--- a/basis/images/normalization/normalization-docs.factor
+++ b/basis/images/normalization/normalization-docs.factor
@@ -6,14 +6,14 @@ IN: images.normalization
 HELP: normalize-image
 { $values
     { "image" image }
-    { "image" image }
+    { "image'" image }
 }
 { $description "Converts the image to RGBA with ubyte-components. If the image is upside-down, it will be flipped right side up such that the 1st byte in the bitmap slot's byte array corresponds to the first color component of the pixel in the upper-left corner of the image." } ;
 
 HELP: reorder-components
 { $values
     { "image" image } { "component-order" component-order }
-    { "image" image }
+    { "image'" image }
 }
 { $description "Convert the bitmap in " { $snippet "image" } " such that the pixel sample layout corresponds to " { $snippet "component-order" } ". If the destination layout cannot find a corresponding value from the source layout, the value " { $snippet "255" } " will be substituted for that byte." }
 { $warning "The image's " { $snippet "component-type" } " will be changed to " { $snippet "ubyte-components" } " if it is not already in that format."
diff --git a/basis/images/normalization/normalization.factor b/basis/images/normalization/normalization.factor
index 2bd7e6883f..6eaca01e15 100644
--- a/basis/images/normalization/normalization.factor
+++ b/basis/images/normalization/normalization.factor
@@ -55,7 +55,7 @@ M: ushort-components normalize-component-type*
 M: ubyte-components normalize-component-type*
     drop ;
 
-: normalize-scan-line-order ( image -- image )
+: normalize-scan-line-order ( image -- image' )
     dup upside-down?>> [
         dup dim>> first 4 * '[
             _ <groups> reverse concat
@@ -71,14 +71,14 @@ M: ubyte-components normalize-component-type*
 
 PRIVATE>
 
-: reorder-components ( image component-order -- image )
+: reorder-components ( image component-order -- image' )
     [
         dup component-type>> '[ _ normalize-component-type* ] change-bitmap
         dup component-order>>
     ] dip
     validate-request [ (reorder-components) ] keep >>component-order ;
 
-: normalize-image ( image -- image )
+: normalize-image ( image -- image' )
     [ >byte-array ] change-bitmap
     RGBA reorder-components
     normalize-scan-line-order ;
diff --git a/basis/lists/lazy/lazy-docs.factor b/basis/lists/lazy/lazy-docs.factor
index 3b23e1186e..201764bd95 100644
--- a/basis/lists/lazy/lazy-docs.factor
+++ b/basis/lists/lazy/lazy-docs.factor
@@ -144,7 +144,7 @@ HELP: lcomp
 { $description "Get the cartesian product of the lists in " { $snippet "list" } " and call " { $snippet "quot" } " call with each element from the cartesian product on the stack, the result of which is returned in the final " { $snippet "list" } "." } ;
 
 HELP: lcomp*
-{ $values { "list" "a list of lists" } { "guards" "a sequence of quotations with stack effect ( seq -- bool )" } { "quot" { $quotation "( seq -- X )" } } { "list" "the resulting list" } { "result" "a list" } }
+{ $values { "list" "a list of lists" } { "guards" "a sequence of quotations with stack effect ( seq -- bool )" } { "quot" { $quotation "( seq -- X )" } } { "result" "a list" } }
 { $description "Get the cartesian product of the lists in " { $snippet "list" } ", filter it by applying each guard quotation to it and call " { $snippet "quot" } " call with each element from the remaining cartesian product items on the stack, the result of which is returned in the final " { $snippet "list" } "." }
 { $examples
   { $code "{ 1 2 3 } >list { 4 5 6 } >list 2list { [ first odd? ] } [ first2 + ] lcomp*" }
diff --git a/basis/math/bitwise/bitwise-docs.factor b/basis/math/bitwise/bitwise-docs.factor
index 5dce9646f4..bbc72d99e4 100644
--- a/basis/math/bitwise/bitwise-docs.factor
+++ b/basis/math/bitwise/bitwise-docs.factor
@@ -88,10 +88,10 @@ HELP: bit-count
 
 HELP: bitroll-32
 { $values
-     { "n" integer } { "s" integer }
-     { "n'" integer }
+     { "m" integer } { "s" integer }
+     { "n" integer }
 }     
-{ $description "Rolls the number " { $snippet "n" } " by " { $snippet "s" } " bits to the left, wrapping around after 32 bits." }
+{ $description "Rolls the number " { $snippet "m" } " by " { $snippet "s" } " bits to the left, wrapping around after 32 bits." }
 { $examples 
     { $example "USING: math.bitwise prettyprint ;"
                "HEX: 1 10 bitroll-32 .h"
@@ -105,10 +105,10 @@ HELP: bitroll-32
 
 HELP: bitroll-64
 { $values
-     { "n" integer } { "s" "a shift integer" }
-     { "n'" integer }
+     { "m" integer } { "s" "a shift integer" }
+     { "n" integer }
 }
-{ $description "Rolls the number " { $snippet "n" } " by " { $snippet "s" } " bits to the left, wrapping around after 64 bits." }
+{ $description "Rolls the number " { $snippet "m" } " by " { $snippet "s" } " bits to the left, wrapping around after 64 bits." }
 { $examples 
     { $example "USING: math.bitwise prettyprint ;"
                "HEX: 1 10 bitroll-64 .h"
@@ -226,10 +226,10 @@ HELP: odd-parity?
 
 HELP: on-bits
 { $values
-     { "n" integer }
      { "m" integer }
+     { "n" integer }
 }
-{ $description "Returns an integer with " { $snippet "n" } " bits set." }
+{ $description "Returns an integer with " { $snippet "m" } " bits set." }
 { $examples
     { $example "USING: math.bitwise kernel prettyprint ;"
         "6 on-bits .h"
@@ -274,7 +274,7 @@ HELP: set-bit
 
 HELP: shift-mod
 { $values
-     { "n" integer } { "s" integer } { "w" integer }
+     { "m" integer } { "s" integer } { "w" integer }
      { "n" integer }
 }
 { $description "Calls " { $link shift } " on " { $snippet "n" } " and " { $snippet "s" } ", wrapping the result to " { $snippet "w" } " bits." } ;
@@ -307,8 +307,8 @@ HELP: unmask?
 
 HELP: w*
 { $values
-     { "int" integer } { "int" integer }
-     { "int" integer }
+     { "x" integer } { "y" integer }
+     { "z" integer }
 }
 { $description "Multiplies two integers and wraps the result to 32 bits." }
 { $examples
@@ -320,8 +320,8 @@ HELP: w*
 
 HELP: w+
 { $values
-     { "int" integer } { "int" integer }
-     { "int" integer }
+     { "x" integer } { "y" integer }
+     { "z" integer }
 }
 { $description "Adds two integers and wraps the result to 32 bits." }
 { $examples
@@ -333,8 +333,8 @@ HELP: w+
 
 HELP: w-
 { $values
-     { "int" integer } { "int" integer }
-     { "int" integer }
+     { "x" integer } { "y" integer }
+     { "z" integer }
 }
 { $description "Subtracts two integers and wraps the result to 32 bits." }
 { $examples
diff --git a/basis/math/bitwise/bitwise.factor b/basis/math/bitwise/bitwise.factor
index 6b301fa97b..e508b49a19 100644
--- a/basis/math/bitwise/bitwise.factor
+++ b/basis/math/bitwise/bitwise.factor
@@ -17,29 +17,32 @@ IN: math.bitwise
 : wrap ( m n -- m' ) 1 - bitand ; inline
 : bits ( m n -- m' ) 2^ wrap ; inline
 : mask-bit ( m n -- m' ) 2^ mask ; inline
-: on-bits ( n -- m ) 2^ 1 - ; inline
+: on-bits ( m -- n ) 2^ 1 - ; inline
 : toggle-bit ( m n -- m' ) 2^ bitxor ; inline
-
-: shift-mod ( n s w -- n )
-    [ shift ] dip 2^ wrap ; inline
+: >signed ( x n -- y ) 2dup neg 1 + shift 1 = [ 2^ - ] [ drop ] if ;
+: >odd ( m -- n ) 0 set-bit ; foldable
+: >even ( m -- n ) 0 clear-bit ; foldable
+: next-even ( m -- n ) >even 2 + ; foldable
+: next-odd ( m -- n ) dup even? [ 1 + ] [ 2 + ] if ; foldable
+: shift-mod ( m s w -- n ) [ shift ] dip 2^ wrap ; inline
 
 : bitroll ( x s w -- y )
     [ wrap ] keep
     [ shift-mod ] [ [ - ] keep shift-mod ] 3bi bitor ; inline
 
-: bitroll-32 ( n s -- n' ) 32 bitroll ; inline
+: bitroll-32 ( m s -- n ) 32 bitroll ; inline
 
-: bitroll-64 ( n s -- n' ) 64 bitroll ; inline
+: bitroll-64 ( m s -- n ) 64 bitroll ; inline
 
 ! 32-bit arithmetic
-: w+ ( int int -- int ) + 32 bits ; inline
-: w- ( int int -- int ) - 32 bits ; inline
-: w* ( int int -- int ) * 32 bits ; inline
+: w+ ( x y -- z ) + 32 bits ; inline
+: w- ( x y -- z ) - 32 bits ; inline
+: w* ( x y -- z ) * 32 bits ; inline
 
 ! 64-bit arithmetic
-: W+ ( int int -- int ) + 64 bits ; inline
-: W- ( int int -- int ) - 64 bits ; inline
-: W* ( int int -- int ) * 64 bits ; inline
+: W+ ( x y -- z ) + 64 bits ; inline
+: W- ( x y -- z ) - 64 bits ; inline
+: W* ( x y -- z ) * 64 bits ; inline
 
 ! flags
 MACRO: flags ( values -- )
@@ -117,17 +120,6 @@ M: object bit-count
     [ >c-ptr ] [ byte-length ] bi <direct-uchar-array>
     byte-array-bit-count ;
 
-: >signed ( x n -- y )
-    2dup neg 1 + shift 1 = [ 2^ - ] [ drop ] if ;
-
-: >odd ( n -- int ) 0 set-bit ; foldable
-
-: >even ( n -- int ) 0 clear-bit ; foldable
-
-: next-even ( m -- n ) >even 2 + ; foldable
-
-: next-odd ( m -- n ) dup even? [ 1 + ] [ 2 + ] if ; foldable
-
 : even-parity? ( obj -- ? ) bit-count even? ;
 
 : odd-parity? ( obj -- ? ) bit-count odd? ;
diff --git a/basis/math/combinatorics/combinatorics-docs.factor b/basis/math/combinatorics/combinatorics-docs.factor
index ec3cd6ee76..0a2a0d4011 100644
--- a/basis/math/combinatorics/combinatorics-docs.factor
+++ b/basis/math/combinatorics/combinatorics-docs.factor
@@ -26,7 +26,7 @@ HELP: nCk
 } ;
 
 HELP: permutation
-{ $values { "n" "a non-negative integer" } { "seq" sequence } { "seq" sequence } }
+{ $values { "n" "a non-negative integer" } { "seq" sequence } { "seq'" sequence } }
 { $description "Outputs the " { $snippet "nth" } " lexicographical permutation of " { $snippet "seq" } "." }
 { $notes "Permutations are 0-based and a bounds error will be thrown if " { $snippet "n" } " is larger than " { $snippet "seq length factorial 1 -" } "." }
 { $examples
@@ -37,7 +37,7 @@ HELP: permutation
 } ;
 
 HELP: all-permutations
-{ $values { "seq" sequence } { "seq" sequence } }
+{ $values { "seq" sequence } { "seq'" sequence } }
 { $description "Outputs a sequence containing all permutations of " { $snippet "seq" } " in lexicographical order." }
 { $examples
     { $example "USING: math.combinatorics prettyprint ;"
@@ -60,7 +60,7 @@ HELP: inverse-permutation
 } ;
 
 HELP: combination
-{ $values { "m" "a non-negative integer" } { "seq" sequence } { "k" "a non-negative integer" } { "seq" sequence } }
+{ $values { "m" "a non-negative integer" } { "seq" sequence } { "k" "a non-negative integer" } { "seq'" sequence } }
 { $description "Outputs the " { $snippet "mth" } " lexicographical combination of " { $snippet "seq" } " choosing " { $snippet "k" } " elements." }
 { $notes "Combinations are 0-based and a bounds error will be thrown if " { $snippet "m" } " is larger than " { $snippet "seq length k nCk" } "." }
 { $examples
@@ -71,7 +71,7 @@ HELP: combination
 } ;
 
 HELP: all-combinations
-{ $values { "seq" sequence } { "k" "a non-negative integer" } { "seq" sequence } }
+{ $values { "seq" sequence } { "k" "a non-negative integer" } { "seq'" sequence } }
 { $description "Outputs a sequence containing all combinations of " { $snippet "seq" } " choosing " { $snippet "k" } " elements, in lexicographical order." }
 { $examples
     { $example "USING: math.combinatorics prettyprint ;"
diff --git a/basis/math/combinatorics/combinatorics.factor b/basis/math/combinatorics/combinatorics.factor
index 7c68aede09..5a9f627015 100644
--- a/basis/math/combinatorics/combinatorics.factor
+++ b/basis/math/combinatorics/combinatorics.factor
@@ -42,10 +42,10 @@ PRIVATE>
 
 PRIVATE>
 
-: permutation ( n seq -- seq )
+: permutation ( n seq -- seq' )
     [ permutation-indices ] keep nths ;
 
-: all-permutations ( seq -- seq )
+: all-permutations ( seq -- seq' )
     [ length factorial iota ] keep
     '[ _ permutation ] map ;
 
@@ -118,10 +118,10 @@ PRIVATE>
 : map>assoc-combinations ( seq k quot exemplar -- )
     [ combinations-quot ] dip map>assoc ; inline
 
-: combination ( m seq k -- seq )
+: combination ( m seq k -- seq' )
     <combo> apply-combination ;
 
-: all-combinations ( seq k -- seq )
+: all-combinations ( seq k -- seq' )
     [ ] combinations-quot map ;
 
 : reduce-combinations ( seq k identity quot -- result )
diff --git a/basis/math/polynomials/polynomials-docs.factor b/basis/math/polynomials/polynomials-docs.factor
index 9c16bf8a7e..3b8885cc88 100644
--- a/basis/math/polynomials/polynomials-docs.factor
+++ b/basis/math/polynomials/polynomials-docs.factor
@@ -36,12 +36,12 @@ HELP: p=
 { $examples { $example "USING: math.polynomials prettyprint ;" "{ 0 1 } { 0 1 0 } p= ." "t" } } ;
 
 HELP: ptrim
-{ $values { "p" "a polynomial" } { "p" "a polynomial" } }
+{ $values { "p" "a polynomial" } { "q" "a polynomial" } }
 { $description "Trims excess zeros from a polynomial." }
 { $examples { $example "USING: math.polynomials prettyprint ;" "{ 0 1 0 0 } ptrim ." "{ 0 1 }" } } ;
 
 HELP: 2ptrim
-{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "p" "a polynomial" } { "q" "a polynomial" } }
+{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "p'" "a polynomial" } { "q'" "a polynomial" } }
 { $description "Trims excess zeros from two polynomials." }
 { $examples { $example "USING: kernel math.polynomials prettyprint ;" "{ 0 1 0 0 } { 1 0 0 } 2ptrim [ . ] bi@" "{ 0 1 }\n{ 1 }" } } ;
 
@@ -61,7 +61,7 @@ HELP: n*p
 { $examples { $example "USING: math.polynomials prettyprint ;" "4 { 3 0 1 } n*p ." "{ 12 0 4 }" } } ;
 
 HELP: pextend-conv
-{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "p" "a polynomial" } { "q" "a polynomial" } }
+{ $values { "p" "a polynomial" } { "q" "a polynomial" } { "p'" "a polynomial" } { "q'" "a polynomial" } }
 { $description "Convulution, extending to " { $snippet "p_m + q_n - 1" } "." }
 { $examples { $example "USING: kernel math.polynomials prettyprint ;" "{ 1 0 1 } { 0 1 } pextend-conv [ . ] bi@" "V{ 1 0 1 0 }\nV{ 0 1 0 0 }" } } ;
 
diff --git a/basis/math/polynomials/polynomials.factor b/basis/math/polynomials/polynomials.factor
index b994410283..31152016ea 100644
--- a/basis/math/polynomials/polynomials.factor
+++ b/basis/math/polynomials/polynomials.factor
@@ -20,15 +20,15 @@ PRIVATE>
 
 : p= ( p q -- ? ) pextend = ;
 
-: ptrim ( p -- p )
+: ptrim ( p -- q )
     dup length 1 = [ [ zero? ] trim-tail ] unless ;
 
-: 2ptrim ( p q -- p q ) [ ptrim ] bi@ ;
+: 2ptrim ( p q -- p' q' ) [ ptrim ] bi@ ;
 : p+ ( p q -- r ) pextend v+ ;
 : p- ( p q -- r ) pextend v- ;
 : n*p ( n p -- n*p ) n*v ;
 
-: pextend-conv ( p q -- p q )
+: pextend-conv ( p q -- p' q' )
     2dup [ length ] bi@ + 1 - 2pad-tail [ >vector ] bi@ ;
 
 : p* ( p q -- r )
diff --git a/basis/math/quaternions/quaternions-docs.factor b/basis/math/quaternions/quaternions-docs.factor
index 1a381c6287..d3bead7dea 100644
--- a/basis/math/quaternions/quaternions-docs.factor
+++ b/basis/math/quaternions/quaternions-docs.factor
@@ -30,7 +30,7 @@ HELP: q/
 { $examples { $example "USING: math.quaternions prettyprint ;" "{ 0 0 0 1 } { 0 0 1 0 } q/ ." "{ 0 1 0 0 }" } } ;
 
 HELP: q*n
-{ $values { "q" "a quaternion" } { "n" real } { "q" "a quaternion" } }
+{ $values { "q" "a quaternion" } { "n" real } { "r" "a quaternion" } }
 { $description "Multiplies each element of " { $snippet "q" } " by real value " { $snippet "n" } "." }
 { $notes "To multiply a quaternion with a complex value, use " { $link c>q } " " { $link q* } "." } ;
 
diff --git a/basis/math/quaternions/quaternions.factor b/basis/math/quaternions/quaternions.factor
index e659cf5f61..4173507e6c 100644
--- a/basis/math/quaternions/quaternions.factor
+++ b/basis/math/quaternions/quaternions.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2005, 2007 Slava Pestov.
+! Copyright (C) 2005, 2010 Joe Groff, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays combinators kernel locals math math.functions
 math.libm math.order math.vectors sequences ;
@@ -35,10 +35,10 @@ M: object qconjugate ( u -- u' )
 : q/ ( u v -- u/v )
     qrecip q* ; inline
 
-: n*q ( q n -- q )
+: n*q ( q n -- r )
     v*n ; inline
 
-: q*n ( q n -- q )
+: q*n ( q n -- r )
     v*n ; inline
 
 : n>q ( n -- q )
diff --git a/basis/math/statistics/statistics-docs.factor b/basis/math/statistics/statistics-docs.factor
index 6fa7d79f77..f7d108dddb 100644
--- a/basis/math/statistics/statistics-docs.factor
+++ b/basis/math/statistics/statistics-docs.factor
@@ -87,7 +87,6 @@ HELP: histogram
 HELP: histogram!
 { $values
     { "hashtable" hashtable } { "seq" sequence }
-    { "hashtable" hashtable }
 }
 { $examples 
     { $example "! Count the number of times the elements of two sequences appear."
@@ -128,7 +127,6 @@ HELP: sequence>assoc
 HELP: sequence>assoc!
 { $values
     { "assoc" assoc } { "seq" sequence } { "quot" quotation }
-    { "assoc" assoc }
 }
 { $examples 
     { $example "! Iterate over a sequence and add the counts to an existing assoc"
diff --git a/basis/opengl/shaders/shaders-docs.factor b/basis/opengl/shaders/shaders-docs.factor
index 1a10071ddf..c3e4d045ef 100644
--- a/basis/opengl/shaders/shaders-docs.factor
+++ b/basis/opengl/shaders/shaders-docs.factor
@@ -52,7 +52,7 @@ HELP: delete-gl-shader
 { $description "Deletes the shader object, invalidating it and releasing any resources allocated for it by the OpenGL implementation." } ;
 
 HELP: gl-shader-info-log
-{ $values { "shader" "A " { $link gl-shader } " object" } { "shader" "a new " { $link gl-shader } } { "log" string } }
+{ $values { "shader" "A " { $link gl-shader } " object" } { "log" string } }
 { $description "Retrieves the info log for " { $snippet "shader" } ", including any errors or warnings generated in compiling the shader object." } ;
 
 HELP: gl-program
diff --git a/basis/random/random-docs.factor b/basis/random/random-docs.factor
index 175c34ad9d..20d5dc0214 100644
--- a/basis/random/random-docs.factor
+++ b/basis/random/random-docs.factor
@@ -75,7 +75,7 @@ HELP: with-system-random
 HELP: randomize
 { $values
      { "seq" sequence }
-     { "seq" sequence }
+     { "randomized" sequence }
 }
 { $description "Randomizes a sequence in-place with the Fisher-Yates algorithm and returns the sequence." } ;
 
diff --git a/basis/random/random.factor b/basis/random/random.factor
index eeaa1f8f2c..ba5d9c7ca3 100644
--- a/basis/random/random.factor
+++ b/basis/random/random.factor
@@ -67,7 +67,7 @@ M: sequence random
     [ [ random ] [ 1 - ] bi [ pick exchange ] keep ]
     while drop ;
 
-: randomize ( seq -- seq ) 
+: randomize ( seq -- randomized )
     dup length randomize-n-last ;
 
 ERROR: too-many-samples seq n ;
diff --git a/basis/roman/roman-docs.factor b/basis/roman/roman-docs.factor
index c81ed0ae42..c9c3db71b5 100644
--- a/basis/roman/roman-docs.factor
+++ b/basis/roman/roman-docs.factor
@@ -39,7 +39,7 @@ HELP: roman>
 { >roman >ROMAN roman> } related-words
 
 HELP: roman+
-{ $values { "x" string } { "x" string } { "x" string } }
+{ $values { "x" string } { "y" string } { "z" string } }
 { $description "Adds two Roman numerals." }
 { $examples 
     { $example "USING: io roman ;"
@@ -49,7 +49,7 @@ HELP: roman+
 } ;
 
 HELP: roman-
-{ $values { "x" string } { "x" string } { "x" string } }
+{ $values { "x" string } { "y" string } { "z" string } }
 { $description "Subtracts two Roman numerals." }
 { $examples 
     { $example "USING: io roman ;"
@@ -61,7 +61,7 @@ HELP: roman-
 { roman+ roman- } related-words
 
 HELP: roman*
-{ $values { "x" string } { "x" string } { "x" string } }
+{ $values { "x" string } { "y" string } { "z" string } }
 { $description "Multiplies two Roman numerals." }
 { $examples 
     { $example "USING: io roman ;"
@@ -71,7 +71,7 @@ HELP: roman*
 } ;
 
 HELP: roman/i
-{ $values { "x" string } { "x" string } { "x" string } }
+{ $values { "x" string } { "y" string } { "z" string } }
 { $description "Computes the integer division of two Roman numerals." }
 { $examples 
     { $example "USING: io roman ;"
@@ -81,7 +81,7 @@ HELP: roman/i
 } ;
 
 HELP: roman/mod
-{ $values { "x" string } { "x" string } { "x" string } { "x" string } }
+{ $values { "x" string } { "y" string } { "z" string } { "w" string } }
 { $description "Computes the quotient and remainder of two Roman numerals." }
 { $examples 
     { $example "USING: kernel io roman ;"
diff --git a/basis/roman/roman.factor b/basis/roman/roman.factor
index a783e7973c..588166829a 100644
--- a/basis/roman/roman.factor
+++ b/basis/roman/roman.factor
@@ -2,8 +2,9 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays assocs effects fry generalizations
 grouping kernel lexer macros math math.order math.vectors
-namespaces parser quotations sequences sequences.private
-splitting.monotonic stack-checker strings unicode.case words ;
+namespaces parser effects.parser quotations sequences
+sequences.private splitting.monotonic stack-checker strings
+unicode.case words ;
 IN: roman
 
 <PRIVATE
@@ -58,14 +59,14 @@ PRIVATE>
 SYNTAX: ROMAN-OP:
     scan-word [ name>> "roman" prepend create-in ] keep
     1quotation '[ _ binary-roman-op ]
-    dup infer define-declared ;
+    complete-effect define-declared ;
 
 >>
 
-ROMAN-OP: +
-ROMAN-OP: -
-ROMAN-OP: *
-ROMAN-OP: /i
-ROMAN-OP: /mod
+ROMAN-OP: + ( x y -- z )
+ROMAN-OP: - ( x y -- z )
+ROMAN-OP: * ( x y -- z )
+ROMAN-OP: /i ( x y -- z )
+ROMAN-OP: /mod ( x y -- z w )
 
 SYNTAX: ROMAN: scan roman> suffix! ;
diff --git a/basis/sequences/deep/deep-docs.factor b/basis/sequences/deep/deep-docs.factor
index e8b9ddea6d..6f479e48b6 100644
--- a/basis/sequences/deep/deep-docs.factor
+++ b/basis/sequences/deep/deep-docs.factor
@@ -31,7 +31,7 @@ HELP: flatten
 { $description "Creates a sequence of all of the leaf nodes (non-sequence nodes, but including strings and numbers) in the object." } ;
 
 HELP: deep-map!
-{ $values { "obj" object } { "quot" { $quotation "( elt -- newelt )" } } { "obj" object } }
+{ $values { "obj" object } { "quot" { $quotation "( elt -- newelt )" } } }
 { $description "Modifies each sub-node of an object in place, in preorder, and returns that object." }
 { $see-also map! } ;
 
diff --git a/basis/ui/gadgets/worlds/worlds-docs.factor b/basis/ui/gadgets/worlds/worlds-docs.factor
index 83d042db43..0d7e40a789 100644
--- a/basis/ui/gadgets/worlds/worlds-docs.factor
+++ b/basis/ui/gadgets/worlds/worlds-docs.factor
@@ -33,7 +33,7 @@ HELP: set-gl-context
 { $description "Selects an OpenGL context to be the implicit destination for subsequent GL rendering calls. This word is called automatically by the UI before drawing a " { $link world } "." } ;
 
 HELP: window-resource
-{ $values { "resource" disposable } { "resource" disposable } }
+{ $values { "resource" disposable } }
 { $description "Marks " { $snippet "resource" } " to be destroyed with " { $link dispose } " when the window with the currently active OpenGL context (set by " { $link set-gl-context } ") is closed. " { $snippet "resource" } " is left unmodified at the top of the stack." } ;
 
 HELP: flush-gl-context
diff --git a/basis/xml-rpc/xml-rpc-docs.factor b/basis/xml-rpc/xml-rpc-docs.factor
index 113fc00407..aeb29c5d07 100644
--- a/basis/xml-rpc/xml-rpc-docs.factor
+++ b/basis/xml-rpc/xml-rpc-docs.factor
@@ -49,7 +49,7 @@ HELP: rpc-fault
 
 HELP: post-rpc
 { $values { "rpc" "an XML-RPC input tuple" } { "url" "a URL" }
-    { "rpc" "an XML-RPC output tuple" } }
+    { "rpc'" "an XML-RPC output tuple" } }
 { $description "posts an XML-RPC document to the specified URL, receives the response and parses it as XML-RPC, returning the tuple" } ;
 
 ARTICLE: { "xml-rpc" "intro" } "XML-RPC"
diff --git a/basis/xml-rpc/xml-rpc.factor b/basis/xml-rpc/xml-rpc.factor
index 370c778787..4c6570c4de 100644
--- a/basis/xml-rpc/xml-rpc.factor
+++ b/basis/xml-rpc/xml-rpc.factor
@@ -186,7 +186,7 @@ TAG: array xml>item
 
 PRIVATE>
 
-: post-rpc ( rpc url -- rpc )
+: post-rpc ( rpc url -- rpc' )
     ! This needs to do something in the event of an error
     rpc-post-request http-request nip string>xml receive-rpc ;
 
diff --git a/basis/xml/traversal/traversal-docs.factor b/basis/xml/traversal/traversal-docs.factor
index bb7ce7ce31..d8032d99fc 100644
--- a/basis/xml/traversal/traversal-docs.factor
+++ b/basis/xml/traversal/traversal-docs.factor
@@ -58,7 +58,7 @@ HELP: children-tags
 { $see-also first-child-tag } ;
 
 HELP: first-child-tag
-{ $values { "tag" "an XML tag or document" } { "tag" tag } }
+{ $values { "tag" "an XML tag or document" } { "child" tag } }
 { $description "Returns the first child of the given tag that is a tag." }
 { $see-also children-tags } ;
 
diff --git a/basis/xml/traversal/traversal.factor b/basis/xml/traversal/traversal.factor
index b337ea1472..46a5896814 100644
--- a/basis/xml/traversal/traversal.factor
+++ b/basis/xml/traversal/traversal.factor
@@ -18,7 +18,7 @@ IN: xml.traversal
 : children-tags ( tag -- sequence )
     children>> [ tag? ] filter ;
 
-: first-child-tag ( tag -- tag )
+: first-child-tag ( tag -- child )
     children>> [ tag? ] find nip ;
 
 : tag-named? ( name elem -- ? )
diff --git a/core/kernel/kernel-docs.factor b/core/kernel/kernel-docs.factor
index c92ef7d599..8b9650fc31 100644
--- a/core/kernel/kernel-docs.factor
+++ b/core/kernel/kernel-docs.factor
@@ -708,7 +708,7 @@ HELP: 3curry
 { $notes "This operation is efficient and does not copy the quotation." } ;
 
 HELP: with
-{ $values { "param" object } { "obj" object } { "quot" { $quotation "( param elt -- ... )" } } { "obj" object } { "curry" curry } }
+{ $values { "param" object } { "obj" object } { "quot" { $quotation "( param elt -- ... )" } } { "curry" curry } }
 { $description "Partial application on the left. The following two lines are equivalent:"
     { $code "swap [ swap A ] curry B" }
     { $code "[ A ] with B" }
diff --git a/core/parser/parser-docs.factor b/core/parser/parser-docs.factor
index 3062f55a42..b024d1d968 100644
--- a/core/parser/parser-docs.factor
+++ b/core/parser/parser-docs.factor
@@ -177,7 +177,7 @@ HELP: parse-lines
 { $errors "Throws a " { $link lexer-error } " if the input is malformed." } ;
 
 HELP: parse-base
-{ $values { "parsed" integer } { "base" "an integer between 2 and 36" } { "parsed" integer } }
+{ $values { "parsed" integer } { "base" "an integer between 2 and 36" } }
 { $description "Reads an integer in a specific numerical base from the parser input." }
 $parsing-note ;
 
diff --git a/core/sequences/sequences-docs.factor b/core/sequences/sequences-docs.factor
index 02dadb323c..38eadc745d 100644
--- a/core/sequences/sequences-docs.factor
+++ b/core/sequences/sequences-docs.factor
@@ -296,7 +296,7 @@ $nl
 } ;
 
 HELP: accumulate!
-{ $values { "seq" sequence } { "identity" object } { "quot" { $quotation "( prev elt -- next )" } } { "final" "the final result" } { "seq" sequence } }
+{ $values { "seq" sequence } { "identity" object } { "quot" { $quotation "( prev elt -- next )" } } { "final" "the final result" } }
 { $description "Combines successive elements of the sequence using a binary operation, and outputs the original sequence of intermediate results, together with the final result."
 $nl
 "The first element of the new sequence is " { $snippet "identity" } ". Then, on the first iteration, the two inputs to the quotation are " { $snippet "identity" } ", and the first element of the old sequence. On successive iterations, the first input is the result of the previous iteration, and the second input is the corresponding element of the old sequence."
@@ -344,7 +344,7 @@ HELP: change-nth
 { $side-effects "seq" } ;
 
 HELP: map!
-{ $values { "seq" "a mutable sequence" } { "quot" { $quotation "( old -- new )" } } { "seq" "a mutable sequence" } }
+{ $values { "seq" "a mutable sequence" } { "quot" { $quotation "( old -- new )" } } }
 { $description "Applies the quotation to each element yielding a new element, storing the new elements back in the original sequence. Returns the original sequence." }
 { $errors "Throws an error if the sequence is immutable, or the sequence cannot hold elements of the type output by " { $snippet "quot" } "." }
 { $side-effects "seq" } ;
@@ -442,7 +442,7 @@ HELP: filter-as
 { $description "Applies the quotation to each element in turn, and outputs a new sequence of the same type as " { $snippet "exemplar" } " containing the elements of the original sequence for which the quotation output a true value." } ;
 
 HELP: filter!
-{ $values { "seq" "a resizable mutable sequence" } { "quot" { $quotation "( elt -- ? )" } } { "seq" "a resizable mutable sequence" } }
+{ $values { "seq" "a resizable mutable sequence" } { "quot" { $quotation "( elt -- ? )" } } }
 { $description "Applies the quotation to each element in turn, and removes elements for which the quotation outputs a false value." }
 { $side-effects "seq" } ;
 
@@ -503,19 +503,19 @@ HELP: move
 { $side-effects "seq" } ;
 
 HELP: remove!
-{ $values { "elt" object } { "seq" "a resizable mutable sequence" } { "elt" object } }
+{ $values { "elt" object } { "seq" "a resizable mutable sequence" } }
 { $description "Removes all elements equal to " { $snippet "elt" } " from " { $snippet "seq" } " and returns " { $snippet "seq" } "." }
 { $notes "This word uses equality comparison (" { $link = } ")." }
 { $side-effects "seq" } ;
 
 HELP: remove-eq!
-{ $values { "elt" object } { "seq" "a resizable mutable sequence" } { "seq" "a resizable mutable sequence" } }
+{ $values { "elt" object } { "seq" "a resizable mutable sequence" } }
 { $description "Outputs a new sequence containing all elements of the input sequence except the given element." }
 { $notes "This word uses identity comparison (" { $link eq? } ")." }
 { $side-effects "seq" } ;
 
 HELP: remove-nth!
-{ $values { "n" "a non-negative integer" } { "seq" "a resizable mutable sequence" } { "seq" "a resizable mutable sequence" } }
+{ $values { "n" "a non-negative integer" } { "seq" "a resizable mutable sequence" } }
 { $description "Removes the " { $snippet "n" } "th element from the sequence, shifting all other elements down and reducing its length by one." }
 { $side-effects "seq" } ;
 
@@ -540,7 +540,7 @@ HELP: suffix
 } ;
 
 HELP: suffix!
-{ $values { "seq" sequence } { "elt" object } { "seq" sequence } }
+{ $values { "seq" sequence } { "elt" object } }
 { $description "Modifiers a sequence in-place by adding " { $snippet "elt" } " to the end of " { $snippet "seq" } ". Outputs " { $snippet "seq" } "." }
 { $errors "Throws an error if the type of " { $snippet "elt" } " is not permitted in sequences of the same class as " { $snippet "seq" } "." }
 { $examples
@@ -548,7 +548,7 @@ HELP: suffix!
 } ;
 
 HELP: append!
-{ $values { "seq1" sequence } { "seq2" sequence } { "seq1" sequence } }
+{ $values { "seq1" sequence } { "seq2" sequence } }
 { $description "Modifiers " { $snippet "seq1" } " in-place by adding the elements from " { $snippet "seq2" } " to the end and outputs " { $snippet "seq1" } "." }
 { $examples
     { $example "USING: prettyprint sequences ;" "V{ 1 2 3 } { 4 5 6 } append! ." "V{ 1 2 3 4 5 6 }" }
@@ -996,7 +996,7 @@ HELP: count
 HELP: selector
 { $values
      { "quot" "a predicate quotation" }
-     { "quot" quotation } { "accum" vector } }
+     { "selector" quotation } { "accum" vector } }
 { $description "Creates a new vector to accumulate the values which return true for a predicate.  Returns a new quotation which accepts an object to be tested and stored in the collector if the test yields true. The collector is left on the stack for convenience." }
 { $example "! Find all the even numbers:" "USING: prettyprint sequences math kernel ;"
            "10 iota [ even? ] selector [ each ] dip ."
@@ -1202,7 +1202,7 @@ HELP: 2map-reduce
 HELP: 2selector
 { $values
      { "quot" quotation }
-     { "quot" quotation } { "accum1" vector } { "accum2" vector } }
+     { "selector" quotation } { "accum1" vector } { "accum2" vector } }
 { $description "Creates two new vectors to accumultate values based on a predicate. The first vector accumulates values for which the predicate yields true; the second for false." } ;
 
 HELP: 2reverse-each
@@ -1323,8 +1323,7 @@ HELP: sequence-hashcode-step
 
 HELP: short
 { $values
-     { "seq" sequence } { "n" integer }
-     { "seq" sequence } { "n'" integer } }
+     { "seq" sequence } { "n" integer } { "n'" integer } }
 { $description "Returns the input sequence and its length or " { $snippet "n" } ", whichever is less." }
 { $examples { $example "USING: sequences kernel prettyprint ;"
     "\"abcd\" 3 short [ . ] bi@"
diff --git a/core/sequences/sequences.factor b/core/sequences/sequences.factor
index 23ab4b5d84..2eafe2ceb8 100644
--- a/core/sequences/sequences.factor
+++ b/core/sequences/sequences.factor
@@ -486,10 +486,10 @@ PRIVATE>
 : push-if ( elt quot accum -- )
     [ keep ] dip rot [ push ] [ 2drop ] if ; inline
 
-: selector-for ( quot exemplar -- quot accum )
+: selector-for ( quot exemplar -- selector accum )
     [ length ] keep new-resizable [ [ push-if ] 2curry ] keep ; inline
 
-: selector ( quot -- quot accum )
+: selector ( quot -- selector accum )
     V{ } selector-for ; inline
 
 : filter-as ( seq quot exemplar -- subseq )
@@ -501,7 +501,7 @@ PRIVATE>
 : push-either ( elt quot accum1 accum2 -- )
     [ keep swap ] 2dip ? push ; inline
 
-: 2selector ( quot -- quot accum1 accum2 )
+: 2selector ( quot -- selector accum1 accum2 )
     V{ } clone V{ } clone [ [ push-either ] 3curry ] 2keep ; inline
 
 : partition ( seq quot -- trueseq falseseq )
diff --git a/extra/game/models/collada/collada-docs.factor b/extra/game/models/collada/collada-docs.factor
index 5be2e19790..b8dad530a4 100644
--- a/extra/game/models/collada/collada-docs.factor
+++ b/extra/game/models/collada/collada-docs.factor
@@ -33,7 +33,7 @@ HELP: y-up { $class-description "Right-handed 3D coordinate system where Y is up
 HELP: z-up { $class-description "Right-handed 3D coordinate system where Z is up." } ;
 
 HELP: >y-up-axis!
-{ $values { "seq" sequence } { "from-axis" rh-up } { "seq" sequence } }
+{ $values { "seq" sequence } { "from-axis" rh-up } }
 { $description "Destructively swizzles the first three elements of the input sequence to a right-handed 3D coordinate system where Y is up and returns the modified sequence." } ;
 
 HELP: source>seq
@@ -53,7 +53,7 @@ HELP: mesh>vertices
 { $description "Convert the mesh tag's vertices element to a pair for further lookup in " { $link collect-sources } ". " } ;
 
 HELP: collect-sources
-{ $values { "sources" hashtable } { "vertices" pair } { "inputs" tag sequence } { "sources" sequence } }
+{ $values { "sources" hashtable } { "vertices" pair } { "inputs" tag sequence } { "seq" sequence } }
 { $description "Look up the sources for these " { $emphasis "input" } " elements and return a sequence of " { $link source } " tuples." } ;
 
 HELP: group-indices
diff --git a/extra/game/models/collada/collada.factor b/extra/game/models/collada/collada.factor
index ef1c55049b..bb7c73c2c7 100644
--- a/extra/game/models/collada/collada.factor
+++ b/extra/game/models/collada/collada.factor
@@ -94,7 +94,7 @@ M: z-up >y-up-axis!
       ] x*
     ] bi 2array ;
 
-:: collect-sources ( sources vertices inputs -- sources )
+:: collect-sources ( sources vertices inputs -- seq )
     inputs
     [| input |
         input "source" x@ rest vertices first =
diff --git a/extra/game/models/obj/obj-docs.factor b/extra/game/models/obj/obj-docs.factor
index ceb61dbb17..a41ca13b8e 100644
--- a/extra/game/models/obj/obj-docs.factor
+++ b/extra/game/models/obj/obj-docs.factor
@@ -58,7 +58,7 @@ HELP: face>aos
 { $description "Convert a face line to a sequence of vertex attributes." } ;
 
 HELP: push*
-{ $values { "elt" "an object" } { "seq" sequence } { "seq" sequence } }
+{ $values { "elt" "an object" } { "seq" sequence } }
 { $description "Push the value onto the sequence, keeping the sequence on the stack." } ;
 
 HELP: push-current-model
diff --git a/extra/gpu/shaders/shaders-docs.factor b/extra/gpu/shaders/shaders-docs.factor
index 96a8561e9f..54822c2fbb 100644
--- a/extra/gpu/shaders/shaders-docs.factor
+++ b/extra/gpu/shaders/shaders-docs.factor
@@ -172,7 +172,7 @@ HELP: vertex-array
 HELP: vertex-array-buffers
 { $values
     { "vertex-array" vertex-array }
-    { "vertex-buffer" buffer }
+    { "buffers" sequence }
 }
 { $description "Returns a sequence containing all of the " { $link buffer } " objects that make up " { $snippet "vertex-array" } "." } ;
 
diff --git a/extra/math/transforms/fft/fft-docs.factor b/extra/math/transforms/fft/fft-docs.factor
index 430058b362..93d72f39a4 100644
--- a/extra/math/transforms/fft/fft-docs.factor
+++ b/extra/math/transforms/fft/fft-docs.factor
@@ -2,6 +2,6 @@ USING: help.markup help.syntax sequences ;
 IN: math.transforms.fft
 
 HELP: fft
-{ $values { "seq" sequence } { "seq" sequence } }
+{ $values { "seq" sequence } { "seq'" sequence } }
 { $description "Fast Fourier transform function." } ;
 
diff --git a/extra/math/transforms/fft/fft.factor b/extra/math/transforms/fft/fft.factor
index 0688c00468..440243a968 100644
--- a/extra/math/transforms/fft/fft.factor
+++ b/extra/math/transforms/fft/fft.factor
@@ -13,26 +13,26 @@ IN: math.transforms.fft
 : omega ( n -- n' )
     recip -2 pi i* * * exp ;
 
-: twiddle ( seq -- seq )
+: twiddle ( seq -- seq' )
     dup length [ omega ] [ n^v ] bi v* ;
 
 PRIVATE>
 
 DEFER: fft
 
-: two ( seq -- seq )
+: two ( seq -- seq' )
     fft 2 v/n dup append ;
 
 <PRIVATE
 
-: even ( seq -- seq ) 2 group 0 <column> ;
-: odd ( seq -- seq ) 2 group 1 <column> ;
+: even ( seq -- seq' ) 2 group 0 <column> ;
+: odd ( seq -- seq' ) 2 group 1 <column> ;
 
-: (fft) ( seq -- seq )
+: (fft) ( seq -- seq' )
     [ odd two twiddle ] [ even two ] bi v+ ;
 
 PRIVATE>
 
-: fft ( seq -- seq )
+: fft ( seq -- seq' )
     dup length 1 = [ (fft) ] unless ;
 
diff --git a/extra/math/transforms/haar/haar-docs.factor b/extra/math/transforms/haar/haar-docs.factor
index 218a63a480..a9a4fd111f 100644
--- a/extra/math/transforms/haar/haar-docs.factor
+++ b/extra/math/transforms/haar/haar-docs.factor
@@ -2,13 +2,13 @@ USING: help.markup help.syntax sequences ;
 IN: math.transforms.haar
 
 HELP: haar
-{ $values { "seq" sequence } { "seq" sequence } }
+{ $values { "seq" sequence } { "seq'" sequence } }
 { $description "Haar wavelet transform function." }
 { $notes "The sequence length should be a power of two." }
 { $examples { $example "USING: math.transforms.haar prettyprint ;" "{ 7 1 6 6 3 -5 4 2 } haar ." "{ 3 2 -1 -2 3 0 4 1 }" } } ;
 
 HELP: rev-haar
-{ $values { "seq" sequence } { "seq" sequence } }
+{ $values { "seq" sequence } { "seq'" sequence } }
 { $description "Reverse Haar wavelet transform function." }
 { $notes "The sequence length should be a power of two." }
 { $examples { $example "USING: math.transforms.haar prettyprint ;" "{ 3 2 -1 -2 3 0 4 1 } rev-haar ." "{ 7 1 6 6 3 -5 4 2 }" } } ;
diff --git a/extra/math/transforms/haar/haar.factor b/extra/math/transforms/haar/haar.factor
index c0359b8e7b..e9b430a802 100644
--- a/extra/math/transforms/haar/haar.factor
+++ b/extra/math/transforms/haar/haar.factor
@@ -8,7 +8,7 @@ IN: math.transforms.haar
 
 <PRIVATE
 
-: averages ( seq -- seq )
+: averages ( seq -- seq' )
     [ mean ] map ;
 
 : differences ( seq averages -- differences )
@@ -22,9 +22,9 @@ IN: math.transforms.haar
 
 PRIVATE>
 
-: haar ( seq -- seq )
+: haar ( seq -- seq' )
     dup length 1 <= [ haar-step haar prepend ] unless ;
 
-: rev-haar ( seq -- seq )
+: rev-haar ( seq -- seq' )
     dup length 2 > [ halves swap rev-haar prepend ] when rev-haar-step ;
 
diff --git a/extra/memory/piles/piles-docs.factor b/extra/memory/piles/piles-docs.factor
index 20568f2226..94a3e7736f 100644
--- a/extra/memory/piles/piles-docs.factor
+++ b/extra/memory/piles/piles-docs.factor
@@ -21,7 +21,6 @@ HELP: pile
 HELP: pile-align
 { $values
     { "pile" pile } { "align" "a power of two" }
-    { "pile" pile }
 }
 { $description "Adjusts a " { $link pile } "'s internal state so that the next call to " { $link pile-alloc } " will return a pointer aligned to " { $snippet "align" } " bytes relative to the pile's initial offset." } ;
 
diff --git a/extra/mongodb/driver/driver-docs.factor b/extra/mongodb/driver/driver-docs.factor
index 532dfe1dce..95acd523b3 100644
--- a/extra/mongodb/driver/driver-docs.factor
+++ b/extra/mongodb/driver/driver-docs.factor
@@ -49,7 +49,6 @@ HELP: <update>
 HELP: >upsert
 { $values
   { "mdb-update-msg" "a mdb-update-msg" }
-  { "mdb-update-msg" "mdb-update-msg with the upsert indicator set to t" }
 }
 { $description "Marks a mdb-update-msg as upsert operation"
   "(inserts object identified by the update selector if it doesn't exist in the collection)" } ;
@@ -162,7 +161,6 @@ HELP: hint
 { $values
   { "mdb-query-msg" "a query" }
   { "index-hint" "a hint to an index" }
-  { "mdb-query-msg" "modified query object" }
 }
 { $description "Annotates the query with a hint to an index. "
   "For detailed information see: " { $url "http://www.mongodb.org/display/DOCS/Optimizing+Mongo+Performance#OptimizingMongoPerformance-Hint" } }
@@ -183,7 +181,6 @@ HELP: limit
 { $values
   { "mdb-query-msg" "a query" }
   { "limit#" "number of objects that should be returned at most" }
-  { "mdb-query-msg" "modified query object" }
 }
 { $description "Limits the number of returned objects to limit#" }
 { $examples
@@ -243,7 +240,6 @@ HELP: skip
 { $values
   { "mdb-query-msg" "a query message" }
   { "skip#" "number of objects to skip" }
-  { "mdb-query-msg" "annotated query message" }
 }
 { $description "annotates a query message with a number of objects to skip when returning the results" } ;
 
@@ -251,7 +247,6 @@ HELP: sort
 { $values
   { "mdb-query-msg" "a query message" }
   { "sort-quot" "a quotation with sort specifiers" }
-  { "mdb-query-msg" "annotated query message" }
 }
 { $description "annotates the query message for sort specifiers" } ;
 
diff --git a/extra/spider/spider-docs.factor b/extra/spider/spider-docs.factor
index 83d93268b5..a39515379a 100644
--- a/extra/spider/spider-docs.factor
+++ b/extra/spider/spider-docs.factor
@@ -12,7 +12,6 @@ HELP: <spider>
 
 HELP: run-spider
 { $values
-     { "spider" spider }
      { "spider" spider } }
 { $description "Runs a spider until completion. See the " { $subsection "spider-tutorial" } " for a complete description of the tuple slots that affect how thet spider works." } ;
 

From c3de89c808ea483fc2d88e10596ccdf4d6a3eba3 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Fri, 19 Feb 2010 12:32:03 +1300
Subject: [PATCH 087/250] help.lint.checks: you can't have duplicate names in
 $values anymore

---
 basis/help/lint/checks/checks.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/help/lint/checks/checks.factor b/basis/help/lint/checks/checks.factor
index 340f9b16d3..632cdb46e2 100644
--- a/basis/help/lint/checks/checks.factor
+++ b/basis/help/lint/checks/checks.factor
@@ -33,7 +33,7 @@ SYMBOL: vocab-articles
 
 : extract-values ( element -- seq )
     \ $values swap elements dup empty? [
-        first rest [ first ] map prune
+        first rest [ first ] map
     ] unless ;
 
 : effect-values ( word -- seq )

From 3f53d189fe6789eb7a647f2a59e239e4b41c1de8 Mon Sep 17 00:00:00 2001
From: Aaron Schaefer <aaron@elasticdog.com>
Date: Thu, 18 Feb 2010 20:46:18 -0600
Subject: [PATCH 088/250] update project-euler common files

---
 extra/project-euler/common/common.factor |  4 ++--
 extra/project-euler/project-euler.factor | 27 ++++++++++++------------
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/extra/project-euler/common/common.factor b/extra/project-euler/common/common.factor
index a84f4fa48b..6995adcd6a 100644
--- a/extra/project-euler/common/common.factor
+++ b/extra/project-euler/common/common.factor
@@ -1,4 +1,4 @@
-! Copyright (c) 2007-2009 Aaron Schaefer.
+! Copyright (c) 2007-2010 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays kernel lists make math math.functions math.matrices
     math.primes.miller-rabin math.order math.parser math.primes.factors
@@ -19,7 +19,7 @@ IN: project-euler.common
 ! mediant - #71, #73
 ! nth-prime - #7, #69
 ! nth-triangle - #12, #42
-! number>digits - #16, #20, #30, #34, #35, #38, #43, #52, #55, #56, #92
+! number>digits - #16, #20, #30, #34, #35, #38, #43, #52, #55, #56, #92, #206
 ! palindrome? - #4, #36, #55
 ! pandigital? - #32, #38
 ! pentagonal? - #44, #45
diff --git a/extra/project-euler/project-euler.factor b/extra/project-euler/project-euler.factor
index 66f4296827..ce58e7009a 100644
--- a/extra/project-euler/project-euler.factor
+++ b/extra/project-euler/project-euler.factor
@@ -1,4 +1,4 @@
-! Copyright (c) 2007-2009 Aaron Schaefer, Samuel Tardieu.
+! Copyright (c) 2007-2010 Aaron Schaefer, Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: definitions io io.files io.pathnames kernel math math.parser
     prettyprint project-euler.ave-time sequences vocabs vocabs.loader
@@ -14,18 +14,19 @@ USING: definitions io io.files io.pathnames kernel math math.parser
     project-euler.037 project-euler.038 project-euler.039 project-euler.040
     project-euler.041 project-euler.042 project-euler.043 project-euler.044
     project-euler.045 project-euler.046 project-euler.047 project-euler.048
-    project-euler.049 project-euler.051 project-euler.052 project-euler.053
-    project-euler.054 project-euler.055 project-euler.056 project-euler.057
-    project-euler.058 project-euler.059 project-euler.062 project-euler.063
-    project-euler.065 project-euler.067 project-euler.069 project-euler.071
-    project-euler.072 project-euler.073 project-euler.074 project-euler.075
-    project-euler.076 project-euler.079 project-euler.081 project-euler.085
-    project-euler.092 project-euler.097 project-euler.099 project-euler.100
-    project-euler.102 project-euler.112 project-euler.116 project-euler.117
-    project-euler.124 project-euler.134 project-euler.148 project-euler.150
-    project-euler.151 project-euler.164 project-euler.169 project-euler.173
-    project-euler.175 project-euler.186 project-euler.188 project-euler.190
-    project-euler.203 project-euler.215 ;
+    project-euler.049 project-euler.050 project-euler.051 project-euler.052
+    project-euler.053 project-euler.054 project-euler.055 project-euler.056
+    project-euler.057 project-euler.058 project-euler.059 project-euler.062
+    project-euler.063 project-euler.065 project-euler.067 project-euler.069
+    project-euler.071 project-euler.072 project-euler.073 project-euler.074
+    project-euler.075 project-euler.076 project-euler.079 project-euler.081
+    project-euler.085 project-euler.089 project-euler.092 project-euler.097
+    project-euler.099 project-euler.100 project-euler.102 project-euler.112
+    project-euler.116 project-euler.117 project-euler.124 project-euler.134
+    project-euler.148 project-euler.150 project-euler.151 project-euler.164
+    project-euler.169 project-euler.173 project-euler.175 project-euler.186
+    project-euler.188 project-euler.190 project-euler.203 project-euler.206
+    project-euler.215 project-euler.255 ;
 IN: project-euler
 
 <PRIVATE

From 170f2b5eca702c863e38a4251b3997acef976ef7 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Fri, 19 Feb 2010 18:24:23 +1300
Subject: [PATCH 089/250] game.input: fix load error on *BSD, remove dependency
 on windows.com from game.input.linux

---
 basis/game/input/input.factor       | 1 +
 basis/game/input/linux/linux.factor | 8 +++-----
 basis/game/input/linux/tags.txt     | 1 +
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/basis/game/input/input.factor b/basis/game/input/input.factor
index 7543a05c60..8a269cd51a 100644
--- a/basis/game/input/input.factor
+++ b/basis/game/input/input.factor
@@ -94,4 +94,5 @@ M: mouse-state clone
     { [ os windows? ] [ "game.input.xinput" require ] }
     { [ os macosx? ] [ "game.input.iokit" require ] }
     { [ os linux? ] [ "game.input.linux" require ] }
+    [ ]
 } cond
diff --git a/basis/game/input/linux/linux.factor b/basis/game/input/linux/linux.factor
index 465cefa84b..0d451e96f0 100644
--- a/basis/game/input/linux/linux.factor
+++ b/basis/game/input/linux/linux.factor
@@ -1,8 +1,6 @@
 ! Copyright (C) 2010 Erik Charlebois.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel game.input namespaces classes windows.com.syntax
-bit-arrays
-vectors ;
+USING: kernel game.input namespaces classes bit-arrays vectors ;
 IN: game.input.linux
 
 SINGLETON: linux-game-input-backend
@@ -25,10 +23,10 @@ M: linux-game-input-backend product-string
     drop "" ;
      
 M: linux-game-input-backend product-id
-    drop GUID: {00000000-0000-0000-0000-000000000000} ;
+    drop f ;
      
 M: linux-game-input-backend instance-id
-    drop GUID: {00000000-0000-0000-0000-000000000000} ;
+    drop f ;
      
 M: linux-game-input-backend read-controller
     drop controller-state new ;
diff --git a/basis/game/input/linux/tags.txt b/basis/game/input/linux/tags.txt
index 84d4140a70..82506ff250 100644
--- a/basis/game/input/linux/tags.txt
+++ b/basis/game/input/linux/tags.txt
@@ -1 +1,2 @@
+unportable
 games

From 48fe9029af23b64d8ba4df68c6e849704a847737 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Fri, 19 Feb 2010 18:24:36 +1300
Subject: [PATCH 090/250] libusb: add unportable tag since it depends on the
 unix vocab

---
 extra/libusb/tags.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/extra/libusb/tags.txt b/extra/libusb/tags.txt
index bb863cf9a0..bf2a35f15b 100644
--- a/extra/libusb/tags.txt
+++ b/extra/libusb/tags.txt
@@ -1 +1,2 @@
 bindings
+unportable

From 7692bd1715db1a8cd5e12452f97bf7465ea73de0 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Fri, 19 Feb 2010 21:45:43 +1300
Subject: [PATCH 091/250] concurrency.mailboxes: mailboxes should not be
 disposable, since futures and promises use them in a transient fashion,
 causing leaks

---
 .../mailboxes/mailboxes-tests.factor          | 35 -------------------
 basis/concurrency/mailboxes/mailboxes.factor  | 20 +++++------
 2 files changed, 9 insertions(+), 46 deletions(-)

diff --git a/basis/concurrency/mailboxes/mailboxes-tests.factor b/basis/concurrency/mailboxes/mailboxes-tests.factor
index 56d579d6c7..3435a01455 100644
--- a/basis/concurrency/mailboxes/mailboxes-tests.factor
+++ b/basis/concurrency/mailboxes/mailboxes-tests.factor
@@ -42,40 +42,6 @@ IN: concurrency.mailboxes.tests
     mailbox-get
 ] unit-test
 
-<mailbox> "m" set
-
-1 <count-down> "c" set
-1 <count-down> "d" set
-
-[
-    "c" get await
-    [ "m" get mailbox-get drop ]
-    [ drop "d" get count-down ] recover
-] "Mailbox close test" spawn drop
-
-[ ] [ "c" get count-down ] unit-test
-[ ] [ "m" get dispose ] unit-test
-[ ] [ "d" get 5 seconds await-timeout ] unit-test
-
-[ ] [ "m" get dispose ] unit-test
-
-<mailbox> "m" set
-
-1 <count-down> "c" set
-1 <count-down> "d" set
-
-[
-    "c" get await
-    "m" get wait-for-close
-    "d" get count-down
-] "Mailbox close test" spawn drop
-
-[ ] [ "c" get count-down ] unit-test
-[ ] [ "m" get dispose ] unit-test
-[ ] [ "d" get 5 seconds await-timeout ] unit-test
-
-[ ] [ "m" get dispose ] unit-test
-
 [ { "foo" "bar" } ] [
     <mailbox>
     "foo" over mailbox-put
@@ -86,4 +52,3 @@ IN: concurrency.mailboxes.tests
 [
     <mailbox> 1 seconds mailbox-get-timeout
 ] [ wait-timeout? ] must-fail-with
-    
diff --git a/basis/concurrency/mailboxes/mailboxes.factor b/basis/concurrency/mailboxes/mailboxes.factor
index 7834a2a3e1..06da3b34a6 100644
--- a/basis/concurrency/mailboxes/mailboxes.factor
+++ b/basis/concurrency/mailboxes/mailboxes.factor
@@ -1,17 +1,17 @@
-! Copyright (C) 2005, 2008 Chris Double, Slava Pestov.
+! Copyright (C) 2005, 2010 Chris Double, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: dlists deques threads sequences continuations
-destructors namespaces math quotations words kernel
-arrays assocs init system concurrency.conditions accessors
-debugger debugger.threads locals fry ;
+USING: dlists deques threads sequences continuations namespaces
+math quotations words kernel arrays assocs init system
+concurrency.conditions accessors debugger debugger.threads
+locals fry ;
 IN: concurrency.mailboxes
 
-TUPLE: mailbox < disposable threads data ;
-
-M: mailbox dispose* threads>> notify-all ;
+TUPLE: mailbox threads data ;
 
 : <mailbox> ( -- mailbox )
-    mailbox new-disposable <dlist> >>threads <dlist> >>data ;
+    mailbox new
+        <dlist> >>threads
+        <dlist> >>data ;
 
 : mailbox-empty? ( mailbox -- bool )
     data>> deque-empty? ;
@@ -24,14 +24,12 @@ M: mailbox dispose* threads>> notify-all ;
     [ threads>> ] dip "mailbox" wait ;
 
 :: block-unless-pred ( mailbox timeout pred: ( message -- ? ) -- )
-    mailbox check-disposed
     mailbox data>> pred dlist-any? [
         mailbox timeout wait-for-mailbox
         mailbox timeout pred block-unless-pred
     ] unless ; inline recursive
 
 : block-if-empty ( mailbox timeout -- mailbox )
-    over check-disposed
     over mailbox-empty? [
         2dup wait-for-mailbox block-if-empty
     ] [

From be8a0f777998a459a31a3fe606c9cd8723f66c33 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Fri, 19 Feb 2010 21:45:50 +1300
Subject: [PATCH 092/250] concurrency.promises: fix formatting

---
 basis/concurrency/promises/promises.factor | 1 +
 1 file changed, 1 insertion(+)

diff --git a/basis/concurrency/promises/promises.factor b/basis/concurrency/promises/promises.factor
index 2ff338c4e3..3381bcc00b 100644
--- a/basis/concurrency/promises/promises.factor
+++ b/basis/concurrency/promises/promises.factor
@@ -12,6 +12,7 @@ TUPLE: promise mailbox ;
     mailbox>> mailbox-empty? not ;
 
 ERROR: promise-already-fulfilled promise ;
+
 : fulfill ( value promise -- )
     dup promise-fulfilled? [ 
         promise-already-fulfilled

From a615700af1f6d969b394ba8ea6a451025df2a7c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= <blei42@gmail.com>
Date: Tue, 20 Oct 2009 13:55:29 +0200
Subject: [PATCH 093/250] ui.tools.listener docs: typo

---
 basis/ui/tools/listener/listener-docs.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/ui/tools/listener/listener-docs.factor b/basis/ui/tools/listener/listener-docs.factor
index b762e036e6..966ac37d30 100644
--- a/basis/ui/tools/listener/listener-docs.factor
+++ b/basis/ui/tools/listener/listener-docs.factor
@@ -9,7 +9,7 @@ HELP: interactor
 $nl
 "Interactors are created by calling " { $link <interactor> } "."
 $nl
-"Interactors implement the " { $link stream-readln } ", " { $link stream-read } " and " { $link read-quot } " generic words." } ;
+"Interactors implement the " { $link stream-readln } ", " { $link stream-read } " and " { $link stream-read-quot } " generic words." } ;
 
 ARTICLE: "ui-listener" "UI listener"
 "The graphical listener adds input history and word and vocabulary completion. See " { $link "listener" } " for general information on the listener."

From db663548f9cd4615c31efa81b1b109a12ca2cfba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= <blei42@gmail.com>
Date: Wed, 21 Oct 2009 19:48:49 +0200
Subject: [PATCH 094/250] math: typo in rem docs

---
 core/math/math-docs.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/math/math-docs.factor b/core/math/math-docs.factor
index 1e107124a2..6357c8bd98 100644
--- a/core/math/math-docs.factor
+++ b/core/math/math-docs.factor
@@ -212,7 +212,7 @@ HELP: recip
 HELP: rem
 { $values { "x" rational } { "y" rational } { "z" rational } }
 { $description
-    "Computes the remainder of dividing " { $snippet "x" } " by " { $snippet "y" } ", with the remainder always positive."
+    "Computes the remainder of dividing " { $snippet "x" } " by " { $snippet "y" } ", with the remainder always positive or zero."
     { $list 
         "Given fixnums, always yields a fixnum."
         "Given bignums, always yields a bignum."

From caf978588bf9521cde6a1d6d518c5954cb4d150e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= <blei42@gmail.com>
Date: Thu, 18 Feb 2010 18:18:26 +0100
Subject: [PATCH 095/250] sequences: clarify some stack effect and examlpes in
 docs

---
 core/sequences/sequences-docs.factor | 30 ++++++++++++++--------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/core/sequences/sequences-docs.factor b/core/sequences/sequences-docs.factor
index 38eadc745d..dc26933af4 100644
--- a/core/sequences/sequences-docs.factor
+++ b/core/sequences/sequences-docs.factor
@@ -269,7 +269,7 @@ HELP: reduce
 
 HELP: reduce-index
 { $values
-     { "seq" sequence } { "identity" object } { "quot" quotation } }
+     { "seq" sequence } { "identity" object } { "quot" { $quotation "( prev elt index -- result )" } } }
 { $description "Combines successive elements of the sequence and their indices binary operations, and outputs the final result. On the first iteration, the three inputs to the quotation are " { $snippet "identity" } ", the first element of the sequence, and its index, 0. On successive iterations, the first input is the result of the previous iteration, the second input is the corresponding element of the sequence, and the third is its index." }
 { $examples { $example "USING: sequences prettyprint math ;"
     "{ 10 50 90 } 0 [ + + ] reduce-index ."
@@ -321,20 +321,20 @@ HELP: map-as
 
 HELP: each-index
 { $values
-     { "seq" sequence } { "quot" quotation } }
+     { "seq" sequence } { "quot" { $quotation "( elt index -- )" } } }
 { $description "Calls the quotation with the element of the sequence and its index on the stack, with the index on the top of the stack." }
-{ $examples { $example "USING: sequences prettyprint math ;"
-"{ 10 20 30 } [ + . ] each-index"
-"10\n21\n32"
+{ $examples { $example "USING: arrays sequences prettyprint ;"
+"{ 10 20 30 } [ 2array . ] each-index"
+"{ 10 0 }\n{ 20 1 }\n{ 30 2 }"
 } } ;
 
 HELP: map-index
 { $values
-  { "seq" sequence } { "quot" quotation } { "newseq" sequence } }
+  { "seq" sequence } { "quot" { $quotation "( elt index -- result )" } } { "newseq" sequence } }
 { $description "Calls the quotation with the element of the sequence and its index on the stack, with the index on the top of the stack. Collects the outputs of the quotation and outputs them in a sequence of the same type as the input sequence." }
-{ $examples { $example "USING: sequences prettyprint math ;"
-"{ 10 20 30 } [ + ] map-index ."
-"{ 10 21 32 }"
+{ $examples { $example "USING: arrays sequences prettyprint ;"
+"{ 10 20 30 } [ 2array ] map-index ."
+"{ { 10 0 } { 20 1 } { 30 2 } }"
 } } ;
 
 HELP: change-nth
@@ -995,8 +995,8 @@ HELP: count
 
 HELP: selector
 { $values
-     { "quot" "a predicate quotation" }
-     { "selector" quotation } { "accum" vector } }
+     { "quot" { $quotation "( elt -- ? )" } }
+     { "selector" { $quotation "( elt -- )" } } { "accum" vector } }
 { $description "Creates a new vector to accumulate the values which return true for a predicate.  Returns a new quotation which accepts an object to be tested and stored in the collector if the test yields true. The collector is left on the stack for convenience." }
 { $example "! Find all the even numbers:" "USING: prettyprint sequences math kernel ;"
            "10 iota [ even? ] selector [ each ] dip ."
@@ -1152,7 +1152,7 @@ HELP: replicate
 
 HELP: replicate-as
 { $values
-     { "len" integer } { "quot" quotation } { "exemplar" sequence }
+     { "len" integer } { "quot" { $quotation "( -- elt )" } } { "exemplar" sequence }
      { "newseq" sequence } }
  { $description "Calls the quotation " { $snippet "len" } " times, collecting results into a new sequence of the same type as the exemplar sequence." }
 { $examples 
@@ -1190,7 +1190,7 @@ HELP: virtual@
 
 HELP: 2map-reduce
 { $values
-     { "seq1" sequence } { "seq2" sequence } { "map-quot" quotation } { "reduce-quot" quotation }
+     { "seq1" sequence } { "seq2" sequence } { "map-quot" { $quotation "( elt1 elt2 -- intermediate )" } } { "reduce-quot" { $quotation "( prev intermediate -- result )" } }
      { "result" object } }
  { $description "Calls " { $snippet "map-quot" } " on each pair of elements from " { $snippet "seq1" } " and " { $snippet "seq2" } " and combines the results using " { $snippet "reduce-quot" } " in the same manner as " { $link reduce } ", except that there is no identity element, and the sequence must have a length of at least 1." }
 { $errors "Throws an error if the sequence is empty." }
@@ -1236,7 +1236,7 @@ HELP: collector
 
 HELP: binary-reduce
 { $values
-     { "seq" sequence } { "start" integer } { "quot" quotation }
+     { "seq" sequence } { "start" integer } { "quot" { $quotation "( elt1 elt2 -- newelt )" } }
      { "value" object } }
 { $description "Like " { $link reduce } ", but splits the sequence in half recursively until each sequence is small enough, and calls the quotation on these smaller sequences. If the quotation computes values that depend on the size of their input, such as bignum arithmetic, then this algorithm can be more efficient than using " { $link reduce } "." }
 { $examples "Computing factorial:"
@@ -1247,7 +1247,7 @@ HELP: binary-reduce
 
 HELP: follow
 { $values
-     { "obj" object } { "quot" quotation }
+     { "obj" object } { "quot" { $quotation "( prev -- result/f )" } }
      { "seq" sequence } }
 { $description "Outputs a sequence containing the input object and all of the objects generated by successively feeding the result of the quotation called on the input object to the quotation recursuively. Objects yielded by the quotation are added to the output sequence until the quotation yields " { $link f } ", at which point the recursion terminates." }
 { $examples "Get random numbers until zero is reached:"

From eb8344a5a5494276e5f7d5f16372d87364e6bdd9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= <blei42@gmail.com>
Date: Thu, 18 Feb 2010 18:43:13 +0100
Subject: [PATCH 096/250] assocs: doc fixes

---
 core/assocs/assocs-docs.factor | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/core/assocs/assocs-docs.factor b/core/assocs/assocs-docs.factor
index 0d5a884832..8f93c5a9d1 100644
--- a/core/assocs/assocs-docs.factor
+++ b/core/assocs/assocs-docs.factor
@@ -221,7 +221,7 @@ HELP: assoc-size
 
 HELP: assoc-like
 { $values { "assoc" assoc } { "exemplar" assoc } { "newassoc" "a new assoc" } }
-{ $contract "Creates a new assoc having the same entries as  "{ $snippet "assoc" } " and the same type as " { $snippet "exemplar" } "." } ;
+{ $contract "Creates a new assoc having the same entries as " { $snippet "assoc" } " and the same type as " { $snippet "exemplar" } "." } ;
 
 HELP: assoc-empty?
 { $values { "assoc" assoc } { "?" "a boolean" } }
@@ -383,7 +383,7 @@ HELP: cache
 { $side-effects "assoc" } ;
 
 HELP: 2cache
-{ $values { "key1" "a key" } { "key2" "a key" } { "assoc" assoc } { "quot" { $quotation "( key -- value )" } } { "value" "a previously-retained or freshly-computed value" } }
+{ $values { "key1" "a key" } { "key2" "a key" } { "assoc" assoc } { "quot" { $quotation "( key1 key2 -- value )" } } { "value" "a previously-retained or freshly-computed value" } }
 { $description "If a single key composed of the input keys is present in the assoc, outputs the associated value, otherwise calls the quotation to produce a value and stores the keys/value pair into the assoc. Returns the value stored in the assoc. Returns a value either looked up or newly stored in the assoc." }
 { $side-effects "assoc" } ;
 
@@ -432,7 +432,7 @@ HELP: assoc-combine
 
 HELP: assoc-map-as
 { $values
-     { "assoc" assoc } { "quot" quotation } { "exemplar" assoc }
+     { "assoc" assoc } { "quot" { $quotation "( key value -- newkey newvalue )" } } { "exemplar" assoc }
      { "newassoc" assoc } }
 { $description "Applies the quotation to each entry in the input assoc and collects the results in a new assoc of the stame type as the exemplar." }
 { $examples { $example "USING: prettyprint assocs hashtables math ;" " H{ { 1 2 } { 3 4 } } [ sq ] { } assoc-map-as ." "{ { 1 4 } { 3 16 } }" } } ;

From aec0243f8331f69f2c71804e312b58baca56252a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= <blei42@gmail.com>
Date: Thu, 18 Feb 2010 18:47:02 +0100
Subject: [PATCH 097/250] infix: part about integers as sequences doesn't apply
 anymore

---
 extra/infix/infix-docs.factor | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/extra/infix/infix-docs.factor b/extra/infix/infix-docs.factor
index 9c42bf256b..3885fcc613 100644
--- a/extra/infix/infix-docs.factor
+++ b/extra/infix/infix-docs.factor
@@ -65,14 +65,6 @@ $nl
     "[let { 1 2 3 4 } :> myarr [infix myarr[4/2]*3 infix] ] ."
     "9"
 }
-"Please note: in Factor " { $emphasis "fixnums are sequences too." } " If you are not careful with sequence accesses you may introduce subtle bugs:"
-{ $example
-    "USING: arrays infix locals ;"
-    ":: add-2nd-elements ( x y -- res )"
-    "    [infix x[1] + y[1] infix] ;"
-    "{ 1 2 3 } { 0 1 2 3 } add-2nd-elements ."
-    "3"
-}
 ;
 
 ABOUT: "infix"

From a343f8a31ccf418e39e0a5c5e18a9dfe51034efa Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sat, 20 Feb 2010 00:23:24 +1300
Subject: [PATCH 098/250] io.monitors: if a monitor is disposed while other
 threads are waiting on it, an error will be thrown from next-change, instead
 of those threads hanging forever. This makes monitors consistent with streams
 and other native resources that behave in a similar manner

---
 basis/io/monitors/linux/linux.factor         |  4 +++-
 basis/io/monitors/macosx/macosx.factor       |  5 ++--
 basis/io/monitors/monitors-tests.factor      | 21 ++++++++++++++++-
 basis/io/monitors/monitors.factor            | 24 ++++++++++++++++----
 basis/io/monitors/recursive/recursive.factor |  2 +-
 basis/io/monitors/windows/nt/nt.factor       |  2 +-
 6 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/basis/io/monitors/linux/linux.factor b/basis/io/monitors/linux/linux.factor
index 7653eaa84c..eacc920303 100644
--- a/basis/io/monitors/linux/linux.factor
+++ b/basis/io/monitors/linux/linux.factor
@@ -59,7 +59,9 @@ M: linux-monitor dispose* ( monitor -- )
             [ inotify>> handle>> handle-fd ] [ wd>> ] bi
             inotify_rm_watch io-error
         ] if
-    ] bi ;
+    ]
+    [ call-next-method ]
+    tri ;
 
 : ignore-flags? ( mask -- ? )
     {
diff --git a/basis/io/monitors/macosx/macosx.factor b/basis/io/monitors/macosx/macosx.factor
index e71fb2eca2..dbbbe7c7e3 100644
--- a/basis/io/monitors/macosx/macosx.factor
+++ b/basis/io/monitors/macosx/macosx.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: io.backend io.monitors
 core-foundation.fsevents continuations kernel sequences
@@ -16,6 +16,7 @@ M:: macosx (monitor) ( path recursive? mailbox -- monitor )
     dup [ enqueue-notifications ] curry
     path 1array 0 0 <event-stream> >>handle ;
 
-M: macosx-monitor dispose* handle>> dispose ;
+M: macosx-monitor dispose*
+    [ handle>> dispose ] [ call-next-method ] bi ;
 
 macosx set-io-backend
diff --git a/basis/io/monitors/monitors-tests.factor b/basis/io/monitors/monitors-tests.factor
index 576ac7ca30..ac17c4a39f 100644
--- a/basis/io/monitors/monitors-tests.factor
+++ b/basis/io/monitors/monitors-tests.factor
@@ -3,7 +3,7 @@ USING: io.monitors tools.test io.files system sequences
 continuations namespaces concurrency.count-downs kernel io
 threads calendar prettyprint destructors io.timeouts
 io.files.temp io.directories io.directories.hierarchy
-io.pathnames accessors ;
+io.pathnames accessors concurrency.promises ;
 
 os { winnt linux macosx } member? [
     [
@@ -110,4 +110,23 @@ os { winnt linux macosx } member? [
         [ [ t ] [ "m" get next-change drop ] while ] must-fail
         [ ] [ "m" get dispose ] unit-test
     ] with-monitors
+
+    ! Disposing a monitor should throw an error in any threads
+    ! waiting on notifications
+    [
+        [ ] [
+            <promise> "p" set
+            "monitor-test" temp-file t <monitor> "m" set
+            10 seconds "m" get set-timeout
+        ] unit-test
+
+        [
+            [ "m" get next-change ] [ ] recover
+            "p" get fulfill
+        ] in-thread
+
+        [ ] [ 1 seconds sleep ] unit-test
+        [ ] [ "m" get dispose ] unit-test
+        [ t ] [ "p" get 10 seconds ?promise-timeout already-disposed? ] unit-test
+    ] with-monitors
 ] when
diff --git a/basis/io/monitors/monitors.factor b/basis/io/monitors/monitors.factor
index cb2f552a32..731798c424 100644
--- a/basis/io/monitors/monitors.factor
+++ b/basis/io/monitors/monitors.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2008, 2009 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: io.backend kernel continuations destructors namespaces
 sequences assocs hashtables sorting arrays threads boxes
@@ -26,6 +26,15 @@ M: monitor timeout timeout>> ;
 
 M: monitor set-timeout (>>timeout) ;
 
+<PRIVATE
+
+SYMBOL: monitor-disposed
+
+PRIVATE>
+
+M: monitor dispose*
+    [ monitor-disposed ] dip queue>> mailbox-put ;
+
 : new-monitor ( path mailbox class -- monitor )
     new-disposable
         swap >>queue
@@ -34,8 +43,11 @@ M: monitor set-timeout (>>timeout) ;
 TUPLE: file-change path changed monitor ;
 
 : queue-change ( path changes monitor -- )
-    3dup and and
-    [ [ file-change boa ] keep queue>> mailbox-put ] [ 3drop ] if ;
+    3dup and and [
+        [ check-disposed ] keep
+        [ file-change boa ] keep
+        queue>> mailbox-put
+    ] [ 3drop ] if ;
 
 HOOK: (monitor) io-backend ( path recursive? mailbox -- monitor )
 
@@ -43,7 +55,11 @@ HOOK: (monitor) io-backend ( path recursive? mailbox -- monitor )
     <mailbox> (monitor) ;
 
 : next-change ( monitor -- change )
-    [ queue>> ] [ timeout ] bi mailbox-get-timeout ;
+    [ check-disposed ]
+    [
+        [ ] [ queue>> ] [ timeout ] tri mailbox-get-timeout
+        dup monitor-disposed eq? [ drop already-disposed ] [ nip ] if
+    ] bi ;
 
 SYMBOL: +add-file+
 SYMBOL: +remove-file+
diff --git a/basis/io/monitors/recursive/recursive.factor b/basis/io/monitors/recursive/recursive.factor
index 33477abdb6..83c088e882 100644
--- a/basis/io/monitors/recursive/recursive.factor
+++ b/basis/io/monitors/recursive/recursive.factor
@@ -41,7 +41,7 @@ DEFER: add-child-monitor
 
 M: recursive-monitor dispose*
     [ "stop" swap thread>> send-synchronous drop ]
-    [ queue>> dispose ]
+    [ call-next-method ]
     bi ;
 
 : stop-pump ( -- )
diff --git a/basis/io/monitors/windows/nt/nt.factor b/basis/io/monitors/windows/nt/nt.factor
index 9cd8bc4df8..4d061cbb1a 100644
--- a/basis/io/monitors/windows/nt/nt.factor
+++ b/basis/io/monitors/windows/nt/nt.factor
@@ -100,4 +100,4 @@ M:: winnt (monitor) ( path recursive? mailbox -- monitor )
     ] with-destructors ;
 
 M: win32-monitor dispose
-    port>> dispose ;
+    [ port>> dispose ] [ call-next-method ] bi ;

From 5336d6f287fcbd59d59ca075ef29d67c1b0b84da Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@factorcode.org>
Date: Fri, 19 Feb 2010 07:36:12 -0500
Subject: [PATCH 099/250] io.monitors.recursive: fix hang introduced by recent
 io.monitors change

---
 basis/io/monitors/recursive/recursive.factor | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/basis/io/monitors/recursive/recursive.factor b/basis/io/monitors/recursive/recursive.factor
index 83c088e882..b573e2fa2b 100644
--- a/basis/io/monitors/recursive/recursive.factor
+++ b/basis/io/monitors/recursive/recursive.factor
@@ -39,17 +39,19 @@ DEFER: add-child-monitor
 : remove-child-monitor ( monitor -- )
     monitor tget children>> delete-at* [ dispose ] [ drop ] if ;
 
+SYMBOL: +stop+
+
 M: recursive-monitor dispose*
-    [ "stop" swap thread>> send-synchronous drop ]
-    [ call-next-method ]
-    bi ;
+    [ [ +stop+ ] dip thread>> send ] [ call-next-method ] bi ;
 
 : stop-pump ( -- )
     monitor tget children>> values dispose-each ;
 
 : pump-step ( msg -- )
-    [ [ monitor>> path>> ] [ path>> ] bi append-path ] [ changed>> ] bi
-    monitor tget queue-change ;
+    monitor tget disposed>> [ drop ] [
+        [ [ monitor>> path>> ] [ path>> ] bi append-path ] [ changed>> ] bi
+        monitor tget queue-change
+    ] if ;
 
 : child-added ( path monitor -- )
     path>> prepend-path add-child-monitor ;
@@ -69,8 +71,8 @@ M: recursive-monitor dispose*
     ] with with each ;
 
 : pump-loop ( -- )
-    receive dup synchronous? [
-        [ stop-pump t ] dip reply-synchronous
+    receive dup +stop+ eq? [
+        drop stop-pump
     ] [
         [ '[ _ update-hierarchy ] ignore-errors ] [ pump-step ] bi
         pump-loop

From 6501480a0e7eb83511aa1d70194eb3a756e8689f Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sat, 20 Feb 2010 12:01:47 +1300
Subject: [PATCH 100/250] Fix two problems with recompilation: predicate
 constant folding was recording unsatisfied dependencies in some cases, and
 literal tuple instances of forgotten classes would cause problems for method
 inlining

---
 basis/compiler/crossref/crossref-tests.factor |  9 ++++++
 basis/compiler/tests/redefine22.factor        | 11 +++++++
 basis/compiler/tests/redefine23.factor        | 13 ++++++++
 basis/compiler/tree/cleanup/cleanup.factor    | 13 +++++---
 .../tree/propagation/info/info.factor         | 21 ++++++++----
 .../tree/propagation/propagation-tests.factor |  6 ++--
 .../tree/propagation/simple/simple.factor     |  9 ++----
 .../dependencies/dependencies.factor          | 32 +++++++++----------
 core/classes/algebra/algebra.factor           |  9 ++++++
 9 files changed, 87 insertions(+), 36 deletions(-)
 create mode 100644 basis/compiler/crossref/crossref-tests.factor
 create mode 100644 basis/compiler/tests/redefine22.factor
 create mode 100644 basis/compiler/tests/redefine23.factor

diff --git a/basis/compiler/crossref/crossref-tests.factor b/basis/compiler/crossref/crossref-tests.factor
new file mode 100644
index 0000000000..9cd475b2de
--- /dev/null
+++ b/basis/compiler/crossref/crossref-tests.factor
@@ -0,0 +1,9 @@
+USING: compiler.crossref fry kernel sequences tools.test vocabs words ;
+IN: compiler.crossref.tests
+
+! Dependencies of all words should always be satisfied unless we're
+! in the middle of recompiling something
+[ { } ] [
+    all-words dup [ subwords ] map concat append
+    H{ } clone '[ _ dependencies-satisfied? not ] filter
+] unit-test
diff --git a/basis/compiler/tests/redefine22.factor b/basis/compiler/tests/redefine22.factor
new file mode 100644
index 0000000000..5837d68c73
--- /dev/null
+++ b/basis/compiler/tests/redefine22.factor
@@ -0,0 +1,11 @@
+IN: compiler.tests.redefine22
+USING: kernel sequences compiler.units vocabs tools.test definitions ;
+
+TUPLE: ttt ;
+INSTANCE: ttt sequence
+M: ttt new-sequence 2drop ttt new ;
+
+: www-1 ( a -- b ) T{ ttt } new-sequence ;
+
+! This used to break with a compiler error in the above word
+[ ] [ [ \ ttt forget ] with-compilation-unit ] unit-test
diff --git a/basis/compiler/tests/redefine23.factor b/basis/compiler/tests/redefine23.factor
new file mode 100644
index 0000000000..e6061937b6
--- /dev/null
+++ b/basis/compiler/tests/redefine23.factor
@@ -0,0 +1,13 @@
+IN: compiler.tests.redefine23
+USING: classes.struct specialized-arrays alien.c-types sequences
+compiler.units vocabs tools.test ;
+
+STRUCT: my-struct { x int } ;
+SPECIALIZED-ARRAY: my-struct
+: my-word ( a -- b ) iota [ my-struct <struct-boa> ] my-struct-array{ } map-as ;
+
+[ ] [
+    [
+        "specialized-arrays.instances.compiler.tests.redefine23" forget-vocab
+    ] with-compilation-unit
+] unit-test
diff --git a/basis/compiler/tree/cleanup/cleanup.factor b/basis/compiler/tree/cleanup/cleanup.factor
index b19c99c360..b69f053898 100644
--- a/basis/compiler/tree/cleanup/cleanup.factor
+++ b/basis/compiler/tree/cleanup/cleanup.factor
@@ -51,11 +51,16 @@ GENERIC: cleanup* ( node -- node/nodes )
     [ in-d>> #drop ]
     bi prefix ;
 
-: record-predicate-folding ( #call -- )
-    [ node-input-infos first class>> ]
+: >predicate-folding< ( #call -- value-info class result )
+    [ node-input-infos first ]
     [ word>> "predicating" word-prop ]
-    [ node-output-infos first literal>> ] tri
-    [ depends-on-class<= ] [ depends-on-classes-disjoint ] if ;
+    [ node-output-infos first literal>> ] tri ;
+
+: record-predicate-folding ( #call -- )
+    >predicate-folding< pick literal?>>
+    [ [ literal>> ] 2dip depends-on-instance-predicate ]
+    [ [ class>> ] 2dip depends-on-class-predicate ]
+    if ;
 
 : record-folding ( #call -- )
     dup word>> predicate?
diff --git a/basis/compiler/tree/propagation/info/info.factor b/basis/compiler/tree/propagation/info/info.factor
index 28ffb96f8f..7f5b9f6fcd 100644
--- a/basis/compiler/tree/propagation/info/info.factor
+++ b/basis/compiler/tree/propagation/info/info.factor
@@ -1,10 +1,11 @@
-! Copyright (C) 2008, 2009 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs classes classes.algebra classes.tuple
-classes.tuple.private kernel accessors math math.intervals namespaces
-sequences sequences.private words combinators memoize
-combinators.short-circuit byte-arrays strings arrays layouts
-cpu.architecture compiler.tree.propagation.copy ;
+classes.tuple.private classes.singleton kernel accessors math
+math.intervals namespaces sequences sequences.private words
+combinators memoize combinators.short-circuit byte-arrays
+strings arrays layouts cpu.architecture
+compiler.tree.propagation.copy ;
 IN: compiler.tree.propagation.info
 
 : false-class? ( class -- ? ) \ f class<= ;
@@ -65,9 +66,17 @@ DEFER: <literal-info>
 
 UNION: fixed-length array byte-array string ;
 
+: literal-class ( obj -- class )
+    #! Handle forgotten tuples and singleton classes properly
+    dup singleton-class? [
+        class dup class? [
+            drop tuple
+        ] unless
+    ] unless ;
+
 : init-literal-info ( info -- info )
     empty-interval >>interval
-    dup literal>> class >>class
+    dup literal>> literal-class >>class
     dup literal>> {
         { [ dup real? ] [ [a,a] >>interval ] }
         { [ dup tuple? ] [ tuple-slot-infos >>slots ] }
diff --git a/basis/compiler/tree/propagation/propagation-tests.factor b/basis/compiler/tree/propagation/propagation-tests.factor
index e2bfe58788..444a424766 100644
--- a/basis/compiler/tree/propagation/propagation-tests.factor
+++ b/basis/compiler/tree/propagation/propagation-tests.factor
@@ -648,7 +648,7 @@ M: array iterate first t ; inline
     ] final-info drop
 ] unit-test
 
-[ V{ word } ] [
+[ V{ t } ] [
     [ { hashtable } declare hashtable instance? ] final-classes
 ] unit-test
 
@@ -660,7 +660,7 @@ M: array iterate first t ; inline
     [ { assoc } declare hashtable instance? ] final-classes
 ] unit-test
 
-[ V{ word } ] [
+[ V{ t } ] [
     [ { string } declare string? ] final-classes
 ] unit-test
 
@@ -774,7 +774,7 @@ MIXIN: empty-mixin
     [ { fixnum } declare log2 ] final-classes
 ] unit-test
 
-[ V{ word } ] [
+[ V{ t } ] [
     [ { fixnum } declare log2 0 >= ] final-classes
 ] unit-test
 
diff --git a/basis/compiler/tree/propagation/simple/simple.factor b/basis/compiler/tree/propagation/simple/simple.factor
index ccfd6ffabd..ed417ef9d7 100644
--- a/basis/compiler/tree/propagation/simple/simple.factor
+++ b/basis/compiler/tree/propagation/simple/simple.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2008, 2009 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: fry accessors kernel sequences sequences.private assocs
 words namespaces classes.algebra combinators
@@ -93,11 +93,8 @@ M: #declare propagate-before
     recover ;
 
 : predicate-output-infos/class ( info class -- info )
-    [ class>> ] dip {
-        { [ 2dup class<= ] [ t <literal-info> ] }
-        { [ 2dup classes-intersect? not ] [ f <literal-info> ] }
-        [ object-info ]
-    } cond 2nip ;
+    [ class>> ] dip compare-classes
+    dup +incomparable+ eq? [ drop object-info ] [ <literal-info> ] if ;
 
 : predicate-output-infos ( info class -- info )
     over literal?>>
diff --git a/basis/stack-checker/dependencies/dependencies.factor b/basis/stack-checker/dependencies/dependencies.factor
index df68fa8961..5469000e84 100644
--- a/basis/stack-checker/dependencies/dependencies.factor
+++ b/basis/stack-checker/dependencies/dependencies.factor
@@ -1,8 +1,8 @@
 ! Copyright (C) 2009, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: assocs accessors classes.algebra fry generic kernel math
-namespaces sequences words sets combinators.short-circuit
-classes.tuple ;
+USING: assocs accessors classes classes.algebra fry generic
+kernel math namespaces sequences words sets
+combinators.short-circuit classes.tuple ;
 FROM: classes.tuple.private => tuple-layout ;
 IN: stack-checker.dependencies
 
@@ -57,28 +57,26 @@ GENERIC: satisfied? ( dependency -- ? )
     boa conditional-dependencies get
     dup [ conjoin ] [ 2drop ] if ; inline
 
-TUPLE: depends-on-class<= class1 class2 ;
+TUPLE: depends-on-class-predicate class1 class2 result ;
 
-: depends-on-class<= ( class1 class2 -- )
-    \ depends-on-class<= add-conditional-dependency ;
+: depends-on-class-predicate ( class1 class2 result -- )
+    \ depends-on-class-predicate add-conditional-dependency ;
 
-M: depends-on-class<= satisfied?
+M: depends-on-class-predicate satisfied?
     {
-        [ class1>> classoid? ]
-        [ class2>> classoid? ]
-        [ [ class1>> ] [ class2>> ] bi class<= ]
+        [ [ class1>> classoid? ] [ class2>> classoid? ] bi and ]
+        [ [ [ class1>> ] [ class2>> ] bi compare-classes ] [ result>> ] bi eq? ]
     } 1&& ;
 
-TUPLE: depends-on-classes-disjoint class1 class2 ;
+TUPLE: depends-on-instance-predicate object class result ;
 
-: depends-on-classes-disjoint ( class1 class2 -- )
-    \ depends-on-classes-disjoint add-conditional-dependency ;
+: depends-on-instance-predicate ( object class result -- )
+    \ depends-on-instance-predicate add-conditional-dependency ;
 
-M: depends-on-classes-disjoint satisfied?
+M: depends-on-instance-predicate satisfied?
     {
-        [ class1>> classoid? ]
-        [ class2>> classoid? ]
-        [ [ class1>> ] [ class2>> ] bi classes-intersect? not ]
+        [ class>> classoid? ]
+        [ [ [ object>> ] [ class>> ] bi instance? ] [ result>> ] bi eq? ]
     } 1&& ;
 
 TUPLE: depends-on-next-method class generic next-method ;
diff --git a/core/classes/algebra/algebra.factor b/core/classes/algebra/algebra.factor
index 69289600e4..f9aaf3eaa5 100644
--- a/core/classes/algebra/algebra.factor
+++ b/core/classes/algebra/algebra.factor
@@ -234,3 +234,12 @@ ERROR: topological-sort-failed ;
 
 : flatten-class ( class -- assoc )
     [ (flatten-class) ] H{ } make-assoc ;
+
+SYMBOL: +incomparable+
+
+: compare-classes ( class1 class2 -- ? )
+    {
+        { [ 2dup class<= ] [ t ] }
+        { [ 2dup classes-intersect? not ] [ f ] }
+        [ +incomparable+ ]
+    } cond 2nip ;

From 08a80e5ba22ac457da60c526c1c06f73a83b123d Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sat, 20 Feb 2010 12:05:12 +1300
Subject: [PATCH 101/250] specialized-arrays: generate slightly more efficient
 byte-array>T-array words

---
 .../specialized-arrays/specialized-arrays.factor  | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/basis/specialized-arrays/specialized-arrays.factor b/basis/specialized-arrays/specialized-arrays.factor
index d3db93e788..e2840b89dd 100644
--- a/basis/specialized-arrays/specialized-arrays.factor
+++ b/basis/specialized-arrays/specialized-arrays.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2008, 2009 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors alien alien.c-types alien.data alien.parser
 assocs byte-arrays classes compiler.units functors kernel lexer
@@ -19,6 +19,11 @@ ERROR: bad-byte-array-length byte-array type ;
 M: bad-byte-array-length summary
     drop "Byte array length doesn't divide type width" ;
 
+ERROR: not-a-byte-array alien ;
+
+M: not-a-byte-array summary
+    drop "Not a byte array" ;
+
 : (underlying) ( n c-type -- array )
     heap-size * (byte-array) ; inline
 
@@ -61,9 +66,11 @@ TUPLE: A
     [ \ T heap-size calloc ] keep <direct-A> ; inline
 
 : byte-array>A ( byte-array -- specialized-array )
-    >c-ptr dup length \ T heap-size /mod 0 =
-    [ drop \ T bad-byte-array-length ] unless
-    <direct-A> ; inline
+    >c-ptr dup byte-array? [
+        dup length \ T heap-size /mod 0 =
+        [ <direct-A> ]
+        [ drop \ T bad-byte-array-length ] if
+    ] [ not-a-byte-array ] if ; inline
 
 M: A clone [ underlying>> clone ] [ length>> ] bi <direct-A> ; inline
 

From 9cd164f3acc03d783278abf6e9af7ff30032b678 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sat, 20 Feb 2010 12:05:52 +1300
Subject: [PATCH 102/250] tools.crossref: don't include generic words in usage
 lists, since the results are useless and arbitrary -- they depend on the
 contents of megamorphic caches

---
 basis/tools/crossref/crossref.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/tools/crossref/crossref.factor b/basis/tools/crossref/crossref.factor
index 3bdf2f83ae..50034822b2 100644
--- a/basis/tools/crossref/crossref.factor
+++ b/basis/tools/crossref/crossref.factor
@@ -71,7 +71,7 @@ M: word crossref-def
 
 : defs-to-crossref ( -- seq )
     [
-        all-words
+        all-words [ generic? not ] filter
         all-articles [ >link ] map
         source-files get keys [ <pathname> ] map
     ] append-outputs ;

From c5a62b14e786781fde0b860b08fb16d21a6c507c Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sat, 20 Feb 2010 12:08:14 +1300
Subject: [PATCH 103/250] stack-checker.dependencies: fix load error

---
 basis/stack-checker/dependencies/dependencies.factor | 1 +
 1 file changed, 1 insertion(+)

diff --git a/basis/stack-checker/dependencies/dependencies.factor b/basis/stack-checker/dependencies/dependencies.factor
index 5469000e84..ece943acac 100644
--- a/basis/stack-checker/dependencies/dependencies.factor
+++ b/basis/stack-checker/dependencies/dependencies.factor
@@ -4,6 +4,7 @@ USING: assocs accessors classes classes.algebra fry generic
 kernel math namespaces sequences words sets
 combinators.short-circuit classes.tuple ;
 FROM: classes.tuple.private => tuple-layout ;
+FROM: assocs => change-at ;
 IN: stack-checker.dependencies
 
 ! Words that the current quotation depends on

From 66bb912641871b5d64681c2b9b1e94cd8a5e5074 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sat, 20 Feb 2010 12:18:16 +1300
Subject: [PATCH 104/250] prettyprint.config: set some output limits by
 default. Use the new without-limits combinator to get the old behavior

---
 basis/prettyprint/config/config-docs.factor   | 10 ++++++-
 basis/prettyprint/config/config.factor        | 30 ++++++++++++++++---
 basis/prettyprint/prettyprint-docs.factor     |  9 ++----
 basis/prettyprint/prettyprint.factor          |  8 +----
 .../tools/deploy/config/editor/editor.factor  |  9 +++---
 5 files changed, 44 insertions(+), 22 deletions(-)

diff --git a/basis/prettyprint/config/config-docs.factor b/basis/prettyprint/config/config-docs.factor
index ccc63c61cb..7cd4b31c8b 100644
--- a/basis/prettyprint/config/config-docs.factor
+++ b/basis/prettyprint/config/config-docs.factor
@@ -1,5 +1,5 @@
 USING: help.markup help.syntax io kernel
-prettyprint.sections words ;
+prettyprint.sections words quotations ;
 IN: prettyprint.config
 
 ABOUT: "prettyprint-variables"
@@ -31,3 +31,11 @@ HELP: boa-tuples?
 
 HELP: c-object-pointers?
 { $var-description "Toggles whether C objects such as structs and direct arrays only print their underlying address. If this flag isn't set, C objects will attempt to print their contents. If a C object points to invalid memory, it will display only its address regardless." } ;
+
+HELP: with-short-limits
+{ $values { "quot" quotation } }
+{ $description "Calls a quotation in a new dynamic scope with prettyprinter limits set to produce a single line of output." } ;
+
+HELP: without-limits
+{ $values { "quot" quotation } }
+{ $description "Calls a quotation in a new dynamic scope with prettyprinter limits set to produce unlimited output." } ;
diff --git a/basis/prettyprint/config/config.factor b/basis/prettyprint/config/config.factor
index dd61e3e23d..a8848f9061 100644
--- a/basis/prettyprint/config/config.factor
+++ b/basis/prettyprint/config/config.factor
@@ -1,8 +1,6 @@
-! Copyright (C) 2003, 2008 Slava Pestov.
+! Copyright (C) 2003, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays generic assocs io kernel math
-namespaces sequences strings vectors words
-continuations ;
+USING: kernel namespaces ;
 IN: prettyprint.config
 
 ! Configuration
@@ -18,4 +16,28 @@ SYMBOL: c-object-pointers?
 
 4 tab-size set-global
 64 margin set-global
+15 nesting-limit set-global
+100 length-limit set-global
 10 number-base set-global
+string-limit? on
+
+: with-short-limits ( quot -- )
+    [
+        1 line-limit set
+        15 length-limit set
+        2 nesting-limit set
+        string-limit? on
+        boa-tuples? on
+        c-object-pointers? on
+        call
+    ] with-scope ; inline
+
+: without-limits ( quot -- )
+    [
+        nesting-limit off
+        length-limit off
+        line-limit off
+        string-limit? off
+        c-object-pointers? off
+        call
+    ] with-scope ; inline
diff --git a/basis/prettyprint/prettyprint-docs.factor b/basis/prettyprint/prettyprint-docs.factor
index bd2c4bd924..33e1857260 100644
--- a/basis/prettyprint/prettyprint-docs.factor
+++ b/basis/prettyprint/prettyprint-docs.factor
@@ -38,12 +38,9 @@ ARTICLE: "prettyprint-variables" "Prettyprint control variables"
     boa-tuples?
     c-object-pointers?
 }
-"Note that the " { $link short. } " and " { $link pprint-short } " variables override some of these variables."
-{
-    $warning "Treat the global variables as essentially being constants. Only ever rebind them in a nested scope."
-    $nl
-    "Some of the globals are safe to change, like the tab size and wrap margin. However setting limits globally could break code which uses the prettyprinter as a serialization mechanism."
-} ;
+"The default limits are meant to strike a balance between readability, and not producing too much output when large structures are given. There are two combinators that override the defaults:"
+{ $subsections with-short-limits without-limits }
+"That the " { $link short. } " and " { $link pprint-short } " words wrap calls to " { $link . } " and " { $link pprint } " in " { $link with-short-limits } ". Code that uses the prettyprinter for serialization should use " { $link without-limits } " to avoid producing unreadable output." ;
 
 ARTICLE: "prettyprint-limitations" "Prettyprinter limitations"
 "When using the prettyprinter as a serialization mechanism, keep the following points in mind:"
diff --git a/basis/prettyprint/prettyprint.factor b/basis/prettyprint/prettyprint.factor
index 7b1538b1dc..23cf956a1d 100644
--- a/basis/prettyprint/prettyprint.factor
+++ b/basis/prettyprint/prettyprint.factor
@@ -26,13 +26,7 @@ IN: prettyprint
 : unparse-use ( obj -- str ) [ pprint-use ] with-string-writer ;
 
 : pprint-short ( obj -- )
-    H{
-       { line-limit 1 }
-       { length-limit 15 }
-       { nesting-limit 2 }
-       { string-limit? t }
-       { boa-tuples? t }
-    } clone [ pprint ] bind ;
+    [ pprint ] with-short-limits ;
 
 : unparse-short ( obj -- str )
     [ pprint-short ] with-string-writer ;
diff --git a/basis/tools/deploy/config/editor/editor.factor b/basis/tools/deploy/config/editor/editor.factor
index 78d86a4707..e10d20e8b3 100644
--- a/basis/tools/deploy/config/editor/editor.factor
+++ b/basis/tools/deploy/config/editor/editor.factor
@@ -1,7 +1,8 @@
-! Copyright (C) 2008 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: assocs io.pathnames kernel parser prettyprint sequences
-splitting tools.deploy.config vocabs.loader vocabs.metadata ;
+USING: assocs io.pathnames kernel parser prettyprint
+prettyprint.config sequences splitting tools.deploy.config
+vocabs.loader vocabs.metadata ;
 IN: tools.deploy.config.editor
 
 : deploy-config-path ( vocab -- string )
@@ -13,7 +14,7 @@ IN: tools.deploy.config.editor
     parse-fresh [ first assoc-union ] unless-empty ;
 
 : set-deploy-config ( assoc vocab -- )
-    [ unparse-use string-lines ] dip
+    [ [ unparse-use ] without-limits string-lines ] dip
     dup deploy-config-path set-vocab-file-contents ;
 
 : set-deploy-flag ( value key vocab -- )

From 51922a2fb96efa9797bc47a6d654742dd3b8dd2c Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sat, 20 Feb 2010 12:18:29 +1300
Subject: [PATCH 105/250] make: documentation tweak

---
 core/make/make-docs.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/make/make-docs.factor b/core/make/make-docs.factor
index 5e4e04c270..2cbf82ae33 100644
--- a/core/make/make-docs.factor
+++ b/core/make/make-docs.factor
@@ -63,7 +63,7 @@ HELP: building
 
 HELP: make
 { $values { "quot" quotation } { "exemplar" sequence } { "seq" "a new sequence" } }
-{ $description "Calls the quotation in a new " { $emphasis "dynamic scope" } ". The quotation and any words it calls can execute the " { $link , } " and " { $link % } " words to accumulate elements. When the quotation returns, all accumulated elements are collected into a sequence with the same type as " { $snippet "exemplar" } "." }
+{ $description "Calls the quotation in a new dynamic scope with the " { $link building } " variable bound to a new resizable mutable sequence. The quotation and any words it calls can execute the " { $link , } " and " { $link % } " words to accumulate elements. When the quotation returns, all accumulated elements are collected into a sequence with the same type as " { $snippet "exemplar" } "." }
 { $examples { $example "USING: make prettyprint ;" "[ 1 , 2 , 3 , ] { } make ." "{ 1 2 3 }" } } ;
 
 HELP: ,

From daed64d8b4f8510e4080cf8abf74630da7e69ff6 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sat, 20 Feb 2010 12:24:25 +1300
Subject: [PATCH 106/250] ui.gadgets.worlds: support S+DELETE as an alternative
 shortcut for cut-action

---
 basis/ui/gadgets/editors/editors.factor | 1 -
 basis/ui/gadgets/worlds/worlds.factor   | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/ui/gadgets/editors/editors.factor b/basis/ui/gadgets/editors/editors.factor
index f42fdf4616..da60d66aff 100644
--- a/basis/ui/gadgets/editors/editors.factor
+++ b/basis/ui/gadgets/editors/editors.factor
@@ -365,7 +365,6 @@ editor "editing" f {
     { undo-action com-undo }
     { redo-action com-redo }
     { T{ key-down f f "DELETE" } delete-next-character }
-    { T{ key-down f { S+ } "DELETE" } delete-next-character }
     { T{ key-down f f "BACKSPACE" } delete-previous-character }
     { T{ key-down f { S+ } "BACKSPACE" } delete-previous-character }
     { T{ key-down f { C+ } "DELETE" } delete-previous-word }
diff --git a/basis/ui/gadgets/worlds/worlds.factor b/basis/ui/gadgets/worlds/worlds.factor
index 7e54b823e8..526fc77c57 100644
--- a/basis/ui/gadgets/worlds/worlds.factor
+++ b/basis/ui/gadgets/worlds/worlds.factor
@@ -230,6 +230,7 @@ action-gestures [
     bi*
 ] H{ } assoc-map-as
 H{
+    { T{ key-down f { S+ } "DELETE" } [ \ cut-action send-action ] }
     { T{ button-down f { C+ } 1 } [ drop T{ button-down f f 3 } button-gesture ] }
     { T{ button-down f { A+ } 1 } [ drop T{ button-down f f 2 } button-gesture ] }
     { T{ button-down f { M+ } 1 } [ drop T{ button-down f f 2 } button-gesture ] }

From 95bfc8a240bbe08d1190e3f3535d335ae421e109 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sat, 20 Feb 2010 13:25:26 +1300
Subject: [PATCH 107/250] vocabs.metadata: replace unportable tag with a
 platforms.txt file for more fine-grained control. Rename unportable tag to
 untested for remaining cases

---
 basis/bootstrap/compiler/timing/tags.txt      |  2 +-
 basis/calendar/unix/platforms.txt             |  1 +
 basis/calendar/unix/tags.txt                  |  1 -
 basis/calendar/windows/platforms.txt          |  1 +
 basis/calendar/windows/tags.txt               |  1 -
 basis/cocoa/application/platforms.txt         |  1 +
 basis/cocoa/application/tags.txt              |  1 -
 basis/cocoa/callbacks/platforms.txt           |  1 +
 basis/cocoa/callbacks/tags.txt                |  1 -
 basis/cocoa/dialogs/platforms.txt             |  1 +
 basis/cocoa/dialogs/tags.txt                  |  1 -
 basis/cocoa/enumeration/platforms.txt         |  1 +
 basis/cocoa/enumeration/tags.txt              |  1 -
 basis/cocoa/messages/platforms.txt            |  1 +
 basis/cocoa/messages/tags.txt                 |  1 -
 basis/cocoa/nibs/platforms.txt                |  1 +
 basis/cocoa/nibs/tags.txt                     |  1 -
 basis/cocoa/pasteboard/platforms.txt          |  1 +
 basis/cocoa/pasteboard/tags.txt               |  1 -
 basis/cocoa/platforms.txt                     |  1 +
 basis/cocoa/plists/platforms.txt              |  1 +
 basis/cocoa/plists/tags.txt                   |  1 -
 basis/cocoa/runtime/platforms.txt             |  1 +
 basis/cocoa/runtime/tags.txt                  |  1 -
 basis/cocoa/subclassing/platforms.txt         |  1 +
 basis/cocoa/subclassing/tags.txt              |  1 -
 basis/cocoa/tags.txt                          |  1 -
 basis/cocoa/types/platforms.txt               |  1 +
 basis/cocoa/types/tags.txt                    |  1 -
 basis/cocoa/views/platforms.txt               |  1 +
 basis/cocoa/views/tags.txt                    |  1 -
 basis/cocoa/windows/platforms.txt             |  1 +
 basis/cocoa/windows/tags.txt                  |  1 -
 basis/core-foundation/arrays/platforms.txt    |  1 +
 basis/core-foundation/arrays/tags.txt         |  1 -
 .../attributed-strings/platforms.txt          |  1 +
 .../attributed-strings/tags.txt               |  1 -
 basis/core-foundation/bundles/platforms.txt   |  1 +
 basis/core-foundation/bundles/tags.txt        |  1 -
 basis/core-foundation/data/platforms.txt      |  1 +
 basis/core-foundation/data/tags.txt           |  1 -
 .../dictionaries/platforms.txt                |  1 +
 basis/core-foundation/dictionaries/tags.txt   |  1 -
 .../file-descriptors/platforms.txt            |  1 +
 .../core-foundation/file-descriptors/tags.txt |  1 -
 basis/core-foundation/fsevents/platforms.txt  |  1 +
 basis/core-foundation/fsevents/tags.txt       |  1 -
 basis/core-foundation/numbers/platforms.txt   |  1 +
 basis/core-foundation/numbers/tags.txt        |  1 -
 basis/core-foundation/platforms.txt           |  1 +
 basis/core-foundation/run-loop/platforms.txt  |  1 +
 basis/core-foundation/run-loop/tags.txt       |  1 -
 basis/core-foundation/strings/platforms.txt   |  1 +
 basis/core-foundation/strings/tags.txt        |  1 -
 basis/core-foundation/tags.txt                |  1 -
 basis/core-foundation/timers/platforms.txt    |  1 +
 basis/core-foundation/timers/tags.txt         |  1 -
 basis/core-foundation/urls/platforms.txt      |  1 +
 basis/core-foundation/urls/tags.txt           |  1 -
 basis/core-foundation/utilities/platforms.txt |  1 +
 basis/core-foundation/utilities/tags.txt      |  1 -
 basis/core-graphics/platforms.txt             |  1 +
 basis/core-graphics/tags.txt                  |  1 -
 basis/core-text/fonts/platforms.txt           |  1 +
 basis/core-text/fonts/tags.txt                |  1 -
 basis/core-text/platforms.txt                 |  1 +
 basis/core-text/tags.txt                      |  1 -
 basis/cpu/ppc/assembler/backend/tags.txt      |  1 -
 basis/cpu/ppc/linux/tags.txt                  |  2 +-
 basis/cpu/ppc/macosx/tags.txt                 |  2 +-
 basis/cpu/ppc/tags.txt                        |  2 +-
 basis/cpu/x86/32/tags.txt                     |  2 +-
 basis/cpu/x86/64/tags.txt                     |  2 +-
 basis/cpu/x86/64/unix/tags.txt                |  2 +-
 basis/cpu/x86/64/winnt/tags.txt               |  2 +-
 basis/cpu/x86/assembler/syntax/tags.txt       |  1 -
 basis/cpu/x86/features/tags.txt               |  2 +-
 basis/cpu/x86/tags.txt                        |  2 +-
 basis/debugger/windows/platforms.txt          |  1 +
 basis/debugger/windows/tags.txt               |  1 -
 basis/editors/editpadlite/tags.txt            |  2 +-
 basis/editors/editpadpro/tags.txt             |  2 +-
 basis/editors/editplus/tags.txt               |  2 +-
 basis/editors/emacs/tags.txt                  |  2 +-
 basis/editors/emacs/windows/tags.txt          |  2 +-
 basis/editors/emeditor/tags.txt               |  2 +-
 basis/editors/etexteditor/tags.txt            |  2 +-
 basis/editors/gedit/tags.txt                  |  2 +-
 basis/editors/gvim/tags.txt                   |  2 +-
 basis/editors/gvim/unix/tags.txt              |  2 +-
 basis/editors/gvim/windows/tags.txt           |  2 +-
 basis/editors/jedit/tags.txt                  |  2 +-
 basis/editors/macvim/tags.txt                 |  2 +-
 basis/editors/notepad/tags.txt                |  2 +-
 basis/editors/notepad2/tags.txt               |  2 +-
 basis/editors/notepadpp/tags.txt              |  2 +-
 basis/editors/scite/tags.txt                  |  2 +-
 basis/editors/ted-notepad/tags.txt            |  2 +-
 basis/editors/textedit/tags.txt               |  2 +-
 basis/editors/textmate/tags.txt               |  2 +-
 basis/editors/textpad/tags.txt                |  2 +-
 basis/editors/textwrangler/tags.txt           |  2 +-
 basis/editors/ultraedit/tags.txt              |  2 +-
 basis/editors/vim/generate-syntax/tags.txt    |  2 +-
 basis/editors/vim/tags.txt                    |  2 +-
 basis/editors/wordpad/tags.txt                |  2 +-
 basis/environment/unix/macosx/platforms.txt   |  1 +
 basis/environment/unix/macosx/tags.txt        |  1 -
 basis/environment/unix/platforms.txt          |  1 +
 basis/environment/unix/tags.txt               |  1 -
 basis/environment/winnt/platforms.txt         |  1 +
 basis/environment/winnt/tags.txt              |  1 -
 basis/game/input/dinput/platforms.txt         |  1 +
 basis/game/input/dinput/tags.txt              |  1 -
 basis/game/input/iokit/platforms.txt          |  1 +
 basis/game/input/iokit/tags.txt               |  1 -
 basis/game/input/linux/platforms.txt          |  1 +
 basis/game/input/linux/tags.txt               |  1 -
 basis/game/input/xinput/platforms.txt         |  1 +
 basis/game/input/xinput/tags.txt              |  1 -
 basis/io/backend/unix/bsd/platforms.txt       |  1 +
 basis/io/backend/unix/bsd/tags.txt            |  1 -
 basis/io/backend/unix/freebsd/platforms.txt   |  1 +
 basis/io/backend/unix/freebsd/tags.txt        |  1 -
 basis/io/backend/unix/linux/platforms.txt     |  1 +
 basis/io/backend/unix/linux/tags.txt          |  1 -
 basis/io/backend/unix/macosx/platforms.txt    |  1 +
 basis/io/backend/unix/macosx/tags.txt         |  1 -
 .../unix/multiplexers/epoll/platforms.txt     |  1 +
 .../backend/unix/multiplexers/epoll/tags.txt  |  1 -
 .../unix/multiplexers/kqueue/platforms.txt    |  1 +
 .../backend/unix/multiplexers/kqueue/tags.txt |  1 -
 .../backend/unix/multiplexers/platforms.txt   |  1 +
 .../unix/multiplexers/run-loop/platforms.txt  |  1 +
 .../unix/multiplexers/run-loop/tags.txt       |  1 -
 .../unix/multiplexers/select/platforms.txt    |  1 +
 .../backend/unix/multiplexers/select/tags.txt |  1 -
 basis/io/backend/unix/multiplexers/tags.txt   |  1 -
 basis/io/backend/unix/netbsd/platforms.txt    |  1 +
 basis/io/backend/unix/netbsd/tags.txt         |  1 -
 basis/io/backend/unix/openbsd/platforms.txt   |  1 +
 basis/io/backend/unix/openbsd/tags.txt        |  1 -
 basis/io/backend/unix/platforms.txt           |  1 +
 basis/io/backend/unix/tags.txt                |  1 -
 basis/io/backend/windows/nt/platforms.txt     |  1 +
 .../windows/nt/privileges/platforms.txt       |  1 +
 .../io/backend/windows/nt/privileges/tags.txt |  1 -
 basis/io/backend/windows/nt/tags.txt          |  1 -
 basis/io/backend/windows/platforms.txt        |  1 +
 .../backend/windows/privileges/platforms.txt  |  1 +
 basis/io/backend/windows/privileges/tags.txt  |  1 -
 basis/io/backend/windows/tags.txt             |  1 -
 .../directories/search/windows/platforms.txt  |  1 +
 basis/io/directories/search/windows/tags.txt  |  1 -
 basis/io/directories/unix/linux/platforms.txt |  1 +
 basis/io/directories/unix/linux/tags.txt      |  1 -
 basis/io/directories/unix/platforms.txt       |  1 +
 basis/io/directories/unix/tags.txt            |  1 -
 basis/io/directories/windows/platforms.txt    |  1 +
 basis/io/directories/windows/tags.txt         |  1 -
 basis/io/files/info/unix/bsd/platforms.txt    |  1 +
 basis/io/files/info/unix/bsd/tags.txt         |  1 -
 .../io/files/info/unix/freebsd/platforms.txt  |  1 +
 basis/io/files/info/unix/freebsd/tags.txt     |  1 -
 basis/io/files/info/unix/linux/platforms.txt  |  1 +
 basis/io/files/info/unix/linux/tags.txt       |  1 -
 basis/io/files/info/unix/macosx/platforms.txt |  1 +
 basis/io/files/info/unix/macosx/tags.txt      |  1 -
 basis/io/files/info/unix/netbsd/platforms.txt |  1 +
 basis/io/files/info/unix/netbsd/tags.txt      |  1 -
 .../io/files/info/unix/openbsd/platforms.txt  |  1 +
 basis/io/files/info/unix/openbsd/tags.txt     |  1 -
 basis/io/files/info/unix/platforms.txt        |  1 +
 basis/io/files/info/unix/tags.txt             |  1 -
 basis/io/files/info/windows/platforms.txt     |  1 +
 basis/io/files/info/windows/tags.txt          |  1 -
 basis/io/files/links/unix/platforms.txt       |  1 +
 basis/io/files/links/unix/tags.txt            |  1 -
 basis/io/files/unique/unix/platforms.txt      |  1 +
 basis/io/files/unique/unix/tags.txt           |  1 -
 basis/io/files/unique/windows/platforms.txt   |  1 +
 basis/io/files/unique/windows/tags.txt        |  1 -
 basis/io/files/unix/platforms.txt             |  1 +
 basis/io/files/unix/tags.txt                  |  1 -
 basis/io/files/windows/nt/platforms.txt       |  1 +
 basis/io/files/windows/nt/tags.txt            |  1 -
 basis/io/files/windows/platforms.txt          |  1 +
 basis/io/files/windows/tags.txt               |  1 -
 basis/io/launcher/unix/parser/platforms.txt   |  1 +
 basis/io/launcher/unix/parser/tags.txt        |  1 -
 basis/io/launcher/unix/platforms.txt          |  1 +
 basis/io/launcher/unix/tags.txt               |  1 -
 basis/io/launcher/windows/nt/platforms.txt    |  1 +
 basis/io/launcher/windows/nt/tags.txt         |  1 -
 basis/io/launcher/windows/platforms.txt       |  1 +
 basis/io/launcher/windows/tags.txt            |  1 -
 basis/io/mmap/unix/platforms.txt              |  1 +
 basis/io/mmap/unix/tags.txt                   |  1 -
 basis/io/mmap/windows/platforms.txt           |  1 +
 basis/io/mmap/windows/tags.txt                |  1 -
 basis/io/monitors/linux/platforms.txt         |  1 +
 basis/io/monitors/linux/tags.txt              |  1 -
 basis/io/monitors/macosx/platforms.txt        |  1 +
 basis/io/monitors/macosx/tags.txt             |  1 -
 basis/io/monitors/windows/nt/platforms.txt    |  1 +
 basis/io/monitors/windows/nt/tags.txt         |  1 -
 basis/io/pipes/unix/platforms.txt             |  1 +
 basis/io/pipes/unix/tags.txt                  |  1 -
 basis/io/pipes/windows/nt/platforms.txt       |  1 +
 basis/io/pipes/windows/nt/tags.txt            |  1 -
 basis/io/sockets/secure/unix/platforms.txt    |  1 +
 basis/io/sockets/secure/unix/tags.txt         |  1 -
 basis/io/sockets/unix/platforms.txt           |  1 +
 basis/io/sockets/unix/tags.txt                |  1 -
 basis/io/sockets/windows/nt/platforms.txt     |  1 +
 basis/io/sockets/windows/nt/tags.txt          |  1 -
 basis/io/sockets/windows/platforms.txt        |  1 +
 basis/io/sockets/windows/tags.txt             |  1 -
 basis/iokit/hid/platforms.txt                 |  1 +
 basis/iokit/hid/tags.txt                      |  1 -
 basis/iokit/platforms.txt                     |  1 +
 basis/iokit/tags.txt                          |  1 -
 basis/math/floats/env/ppc/tags.txt            |  2 +-
 basis/math/floats/env/x86/32/tags.txt         |  2 +-
 basis/math/floats/env/x86/64/tags.txt         |  2 +-
 basis/math/floats/env/x86/tags.txt            |  2 +-
 basis/opengl/gl/macosx/platforms.txt          |  1 +
 basis/opengl/gl/macosx/tags.txt               |  1 -
 basis/opengl/gl/unix/platforms.txt            |  1 +
 basis/opengl/gl/unix/tags.txt                 |  1 -
 basis/opengl/gl/windows/platforms.txt         |  1 +
 basis/opengl/gl/windows/tags.txt              |  1 -
 basis/random/unix/platforms.txt               |  1 +
 basis/random/unix/tags.txt                    |  1 -
 basis/random/windows/platforms.txt            |  1 +
 basis/random/windows/tags.txt                 |  1 -
 basis/system-info/linux/platforms.txt         |  1 +
 basis/system-info/linux/tags.txt              |  1 -
 basis/system-info/macosx/platforms.txt        |  1 +
 basis/system-info/macosx/tags.txt             |  1 -
 basis/system-info/windows/ce/platforms.txt    |  1 +
 basis/system-info/windows/ce/tags.txt         |  1 -
 basis/system-info/windows/nt/platforms.txt    |  1 +
 basis/system-info/windows/nt/tags.txt         |  1 -
 basis/system-info/windows/platforms.txt       |  1 +
 basis/system-info/windows/tags.txt            |  1 -
 basis/tools/cocoa/platforms.txt               |  1 +
 basis/tools/cocoa/tags.txt                    |  1 -
 basis/tools/deploy/libraries/tags.txt         |  1 -
 .../tools/deploy/libraries/unix/platforms.txt |  1 +
 basis/tools/deploy/libraries/unix/tags.txt    |  1 -
 .../deploy/libraries/windows/platforms.txt    |  1 +
 basis/tools/deploy/libraries/windows/tags.txt |  1 -
 basis/tools/deploy/macosx/platforms.txt       |  1 +
 basis/tools/deploy/macosx/tags.txt            |  1 -
 basis/tools/deploy/test/14/platforms.txt      |  1 +
 basis/tools/deploy/test/14/tags.txt           |  1 -
 basis/tools/deploy/unix/platforms.txt         |  1 +
 basis/tools/deploy/unix/tags.txt              |  1 -
 basis/tools/deploy/windows/ico/platforms.txt  |  1 +
 basis/tools/deploy/windows/ico/tags.txt       |  1 -
 basis/tools/deploy/windows/platforms.txt      |  1 +
 basis/tools/deploy/windows/tags.txt           |  1 -
 basis/tools/disassembler/gdb/tags.txt         |  2 +-
 basis/tools/disassembler/udis/tags.txt        |  2 +-
 basis/tools/files/tags.txt                    |  1 -
 basis/tools/files/unix/platforms.txt          |  1 +
 basis/tools/files/unix/tags.txt               |  1 -
 basis/tools/files/windows/platforms.txt       |  1 +
 basis/tools/files/windows/tags.txt            |  1 -
 basis/tools/scaffold/scaffold.factor          | 14 ++---
 basis/tools/scaffold/windows/platforms.txt    |  1 +
 basis/tools/scaffold/windows/tags.txt         |  1 -
 basis/ui/backend/cocoa/platforms.txt          |  1 +
 basis/ui/backend/cocoa/tags.txt               |  1 -
 basis/ui/backend/cocoa/tools/platforms.txt    |  1 +
 basis/ui/backend/cocoa/tools/tags.txt         |  1 -
 basis/ui/backend/cocoa/views/platforms.txt    |  1 +
 basis/ui/backend/cocoa/views/tags.txt         |  1 -
 basis/ui/backend/windows/platforms.txt        |  1 +
 basis/ui/backend/windows/tags.txt             |  1 -
 basis/ui/backend/x11/tags.txt                 |  2 +-
 basis/ui/text/core-text/platforms.txt         |  1 +
 basis/ui/text/core-text/tags.txt              |  1 -
 basis/ui/text/pango/tags.txt                  |  2 +-
 basis/ui/text/uniscribe/platforms.txt         |  1 +
 basis/ui/text/uniscribe/tags.txt              |  1 -
 basis/unix/debugger/platforms.txt             |  1 +
 basis/unix/debugger/tags.txt                  |  1 -
 basis/unix/ffi/bsd/freebsd/platforms.txt      |  1 +
 basis/unix/ffi/bsd/freebsd/tags.txt           |  1 -
 basis/unix/ffi/bsd/macosx/platforms.txt       |  1 +
 basis/unix/ffi/bsd/macosx/tags.txt            |  1 -
 basis/unix/ffi/bsd/netbsd/platforms.txt       |  1 +
 basis/unix/ffi/bsd/netbsd/tags.txt            |  1 -
 basis/unix/ffi/bsd/openbsd/platforms.txt      |  1 +
 basis/unix/ffi/bsd/openbsd/tags.txt           |  1 -
 basis/unix/ffi/bsd/platforms.txt              |  1 +
 basis/unix/ffi/bsd/tags.txt                   |  1 -
 basis/unix/ffi/linux/platforms.txt            |  1 +
 basis/unix/ffi/linux/tags.txt                 |  1 -
 basis/unix/ffi/platforms.txt                  |  1 +
 basis/unix/ffi/solaris/platforms.txt          |  1 +
 basis/unix/ffi/solaris/tags.txt               |  1 -
 basis/unix/ffi/tags.txt                       |  1 -
 basis/unix/getfsstat/freebsd/platforms.txt    |  1 +
 basis/unix/getfsstat/freebsd/tags.txt         |  1 -
 basis/unix/getfsstat/macosx/platforms.txt     |  1 +
 basis/unix/getfsstat/macosx/tags.txt          |  1 -
 basis/unix/getfsstat/netbsd/platforms.txt     |  1 +
 basis/unix/getfsstat/netbsd/tags.txt          |  1 -
 basis/unix/getfsstat/openbsd/platforms.txt    |  1 +
 basis/unix/getfsstat/openbsd/tags.txt         |  1 -
 basis/unix/groups/platforms.txt               |  1 +
 basis/unix/groups/tags.txt                    |  1 -
 basis/unix/kqueue/freebsd/platforms.txt       |  1 +
 basis/unix/kqueue/freebsd/tags.txt            |  1 -
 basis/unix/kqueue/macosx/platforms.txt        |  1 +
 basis/unix/kqueue/macosx/tags.txt             |  1 -
 basis/unix/kqueue/netbsd/platforms.txt        |  1 +
 basis/unix/kqueue/netbsd/tags.txt             |  1 -
 basis/unix/kqueue/openbsd/platforms.txt       |  1 +
 basis/unix/kqueue/openbsd/tags.txt            |  1 -
 basis/unix/kqueue/platforms.txt               |  1 +
 basis/unix/kqueue/tags.txt                    |  1 -
 basis/unix/linux/epoll/platforms.txt          |  1 +
 basis/unix/linux/epoll/tags.txt               |  1 -
 basis/unix/linux/inotify/platforms.txt        |  1 +
 basis/unix/linux/inotify/tags.txt             |  1 -
 basis/unix/linux/platforms.txt                |  1 +
 basis/unix/linux/tags.txt                     |  1 -
 basis/unix/platforms.txt                      |  1 +
 basis/unix/process/platforms.txt              |  1 +
 basis/unix/process/tags.txt                   |  1 -
 basis/unix/stat/freebsd/platforms.txt         |  1 +
 basis/unix/stat/freebsd/tags.txt              |  1 -
 basis/unix/stat/linux/32/tags.txt             |  2 +-
 basis/unix/stat/linux/64/tags.txt             |  2 +-
 basis/unix/stat/linux/platforms.txt           |  1 +
 basis/unix/stat/linux/tags.txt                |  1 -
 basis/unix/stat/macosx/platforms.txt          |  1 +
 basis/unix/stat/macosx/tags.txt               |  1 -
 basis/unix/stat/netbsd/32/tags.txt            |  2 +-
 basis/unix/stat/netbsd/64/tags.txt            |  2 +-
 basis/unix/stat/netbsd/platforms.txt          |  1 +
 basis/unix/stat/netbsd/tags.txt               |  1 -
 basis/unix/stat/openbsd/platforms.txt         |  1 +
 basis/unix/stat/openbsd/tags.txt              |  1 -
 basis/unix/stat/platforms.txt                 |  1 +
 basis/unix/stat/tags.txt                      |  1 -
 basis/unix/statfs/freebsd/platforms.txt       |  1 +
 basis/unix/statfs/freebsd/tags.txt            |  1 -
 basis/unix/statfs/linux/platforms.txt         |  1 +
 basis/unix/statfs/linux/tags.txt              |  1 -
 basis/unix/statfs/macosx/platforms.txt        |  1 +
 basis/unix/statfs/macosx/tags.txt             |  1 -
 basis/unix/statfs/openbsd/platforms.txt       |  1 +
 basis/unix/statfs/openbsd/tags.txt            |  1 -
 basis/unix/statvfs/freebsd/platforms.txt      |  1 +
 basis/unix/statvfs/freebsd/tags.txt           |  1 -
 basis/unix/statvfs/linux/platforms.txt        |  1 +
 basis/unix/statvfs/linux/tags.txt             |  1 -
 basis/unix/statvfs/macosx/platforms.txt       |  1 +
 basis/unix/statvfs/macosx/tags.txt            |  1 -
 basis/unix/statvfs/netbsd/platforms.txt       |  1 +
 basis/unix/statvfs/netbsd/tags.txt            |  1 -
 basis/unix/statvfs/openbsd/platforms.txt      |  1 +
 basis/unix/statvfs/openbsd/tags.txt           |  1 -
 basis/unix/statvfs/platforms.txt              |  1 +
 basis/unix/statvfs/tags.txt                   |  1 -
 basis/unix/tags.txt                           |  1 -
 basis/unix/time/platforms.txt                 |  1 +
 basis/unix/time/tags.txt                      |  1 -
 basis/unix/types/freebsd/platforms.txt        |  1 +
 basis/unix/types/freebsd/tags.txt             |  1 -
 basis/unix/types/linux/platforms.txt          |  1 +
 basis/unix/types/linux/tags.txt               |  1 -
 basis/unix/types/macosx/platforms.txt         |  1 +
 basis/unix/types/macosx/tags.txt              |  1 -
 basis/unix/types/netbsd/32/tags.txt           |  2 +-
 basis/unix/types/netbsd/64/tags.txt           |  2 +-
 basis/unix/types/netbsd/platforms.txt         |  1 +
 basis/unix/types/netbsd/tags.txt              |  1 -
 basis/unix/types/openbsd/platforms.txt        |  1 +
 basis/unix/types/openbsd/tags.txt             |  1 -
 basis/unix/types/platforms.txt                |  1 +
 basis/unix/types/tags.txt                     |  1 -
 basis/unix/users/bsd/platforms.txt            |  1 +
 basis/unix/users/bsd/tags.txt                 |  1 -
 basis/unix/users/platforms.txt                |  1 +
 basis/unix/users/tags.txt                     |  1 -
 basis/unix/utilities/platforms.txt            |  1 +
 basis/unix/utilities/tags.txt                 |  1 -
 basis/unix/utmpx/macosx/platforms.txt         |  1 +
 basis/unix/utmpx/macosx/tags.txt              |  1 -
 basis/unix/utmpx/netbsd/platforms.txt         |  1 +
 basis/unix/utmpx/netbsd/tags.txt              |  1 -
 basis/unix/utmpx/platforms.txt                |  1 +
 basis/unix/utmpx/tags.txt                     |  1 -
 basis/vocabs/metadata/authors.txt             |  3 +-
 basis/vocabs/metadata/metadata.factor         | 55 +++++++++++++++----
 basis/windows/advapi32/platforms.txt          |  1 +
 basis/windows/advapi32/tags.txt               |  1 -
 basis/windows/ce/platforms.txt                |  1 +
 basis/windows/ce/tags.txt                     |  1 -
 basis/windows/com/platforms.txt               |  1 +
 basis/windows/com/prettyprint/platforms.txt   |  1 +
 basis/windows/com/prettyprint/tags.txt        |  1 -
 basis/windows/com/syntax/platforms.txt        |  1 +
 basis/windows/com/syntax/tags.txt             |  1 -
 basis/windows/com/tags.txt                    |  1 -
 basis/windows/com/wrapper/platforms.txt       |  1 +
 basis/windows/com/wrapper/tags.txt            |  1 -
 basis/windows/directx/audiodefs/platforms.txt |  1 +
 basis/windows/directx/audiodefs/tags.txt      |  1 -
 basis/windows/directx/d2d1/platforms.txt      |  1 +
 basis/windows/directx/d2d1/tags.txt           |  1 -
 .../directx/d2dbasetypes/platforms.txt        |  1 +
 basis/windows/directx/d2dbasetypes/tags.txt   |  1 -
 basis/windows/directx/d2derr/platforms.txt    |  1 +
 basis/windows/directx/d2derr/tags.txt         |  1 -
 basis/windows/directx/d3d10/platforms.txt     |  1 +
 basis/windows/directx/d3d10/tags.txt          |  1 -
 basis/windows/directx/d3d10_1/platforms.txt   |  1 +
 basis/windows/directx/d3d10_1/tags.txt        |  1 -
 .../directx/d3d10_1shader/platforms.txt       |  1 +
 basis/windows/directx/d3d10_1shader/tags.txt  |  1 -
 .../windows/directx/d3d10effect/platforms.txt |  1 +
 basis/windows/directx/d3d10effect/tags.txt    |  1 -
 basis/windows/directx/d3d10misc/platforms.txt |  1 +
 basis/windows/directx/d3d10misc/tags.txt      |  1 -
 .../windows/directx/d3d10shader/platforms.txt |  1 +
 basis/windows/directx/d3d10shader/tags.txt    |  1 -
 basis/windows/directx/d3d11/platforms.txt     |  1 +
 basis/windows/directx/d3d11/tags.txt          |  1 -
 .../windows/directx/d3d11shader/platforms.txt |  1 +
 basis/windows/directx/d3d11shader/tags.txt    |  1 -
 basis/windows/directx/d3d9/platforms.txt      |  1 +
 basis/windows/directx/d3d9/tags.txt           |  1 -
 basis/windows/directx/d3d9caps/platforms.txt  |  1 +
 basis/windows/directx/d3d9caps/tags.txt       |  1 -
 basis/windows/directx/d3d9types/platforms.txt |  1 +
 basis/windows/directx/d3d9types/tags.txt      |  1 -
 basis/windows/directx/d3dcommon/platforms.txt |  1 +
 basis/windows/directx/d3dcommon/tags.txt      |  1 -
 .../windows/directx/d3dcompiler/platforms.txt |  1 +
 basis/windows/directx/d3dcompiler/tags.txt    |  1 -
 basis/windows/directx/d3dcsx/platforms.txt    |  1 +
 basis/windows/directx/d3dcsx/tags.txt         |  1 -
 basis/windows/directx/d3dx10/platforms.txt    |  1 +
 basis/windows/directx/d3dx10/tags.txt         |  1 -
 .../windows/directx/d3dx10async/platforms.txt |  1 +
 basis/windows/directx/d3dx10async/tags.txt    |  1 -
 .../windows/directx/d3dx10core/platforms.txt  |  1 +
 basis/windows/directx/d3dx10core/tags.txt     |  1 -
 .../windows/directx/d3dx10math/platforms.txt  |  1 +
 basis/windows/directx/d3dx10math/tags.txt     |  1 -
 .../windows/directx/d3dx10mesh/platforms.txt  |  1 +
 basis/windows/directx/d3dx10mesh/tags.txt     |  1 -
 basis/windows/directx/d3dx10tex/platforms.txt |  1 +
 basis/windows/directx/d3dx10tex/tags.txt      |  1 -
 basis/windows/directx/d3dx11/platforms.txt    |  1 +
 basis/windows/directx/d3dx11/tags.txt         |  1 -
 .../windows/directx/d3dx11async/platforms.txt |  1 +
 basis/windows/directx/d3dx11async/tags.txt    |  1 -
 .../windows/directx/d3dx11core/platforms.txt  |  1 +
 basis/windows/directx/d3dx11core/tags.txt     |  1 -
 basis/windows/directx/d3dx11tex/platforms.txt |  1 +
 basis/windows/directx/d3dx11tex/tags.txt      |  1 -
 basis/windows/directx/d3dx9/platforms.txt     |  1 +
 basis/windows/directx/d3dx9/tags.txt          |  1 -
 basis/windows/directx/d3dx9anim/platforms.txt |  1 +
 basis/windows/directx/d3dx9anim/tags.txt      |  1 -
 basis/windows/directx/d3dx9core/platforms.txt |  1 +
 basis/windows/directx/d3dx9core/tags.txt      |  1 -
 .../windows/directx/d3dx9effect/platforms.txt |  1 +
 basis/windows/directx/d3dx9effect/tags.txt    |  1 -
 basis/windows/directx/d3dx9math/platforms.txt |  1 +
 basis/windows/directx/d3dx9math/tags.txt      |  1 -
 basis/windows/directx/d3dx9mesh/platforms.txt |  1 +
 basis/windows/directx/d3dx9mesh/tags.txt      |  1 -
 .../windows/directx/d3dx9shader/platforms.txt |  1 +
 basis/windows/directx/d3dx9shader/tags.txt    |  1 -
 .../windows/directx/d3dx9shape/platforms.txt  |  1 +
 basis/windows/directx/d3dx9shape/tags.txt     |  1 -
 basis/windows/directx/d3dx9tex/platforms.txt  |  1 +
 basis/windows/directx/d3dx9tex/tags.txt       |  1 -
 basis/windows/directx/d3dx9xof/platforms.txt  |  1 +
 basis/windows/directx/d3dx9xof/tags.txt       |  1 -
 basis/windows/directx/dcommon/platforms.txt   |  1 +
 basis/windows/directx/dcommon/tags.txt        |  1 -
 .../directx/dinput/constants/platforms.txt    |  1 +
 .../windows/directx/dinput/constants/tags.txt |  1 -
 basis/windows/directx/dinput/platforms.txt    |  1 +
 basis/windows/directx/dinput/tags.txt         |  1 -
 basis/windows/directx/dwrite/platforms.txt    |  1 +
 basis/windows/directx/dwrite/tags.txt         |  1 -
 basis/windows/directx/dxfile/platforms.txt    |  1 +
 basis/windows/directx/dxfile/tags.txt         |  1 -
 basis/windows/directx/dxgi/platforms.txt      |  1 +
 basis/windows/directx/dxgi/tags.txt           |  1 -
 .../windows/directx/dxgiformat/platforms.txt  |  1 +
 basis/windows/directx/dxgiformat/tags.txt     |  1 -
 basis/windows/directx/dxgitype/platforms.txt  |  1 +
 basis/windows/directx/dxgitype/tags.txt       |  1 -
 basis/windows/directx/x3daudio/platforms.txt  |  1 +
 basis/windows/directx/x3daudio/tags.txt       |  1 -
 basis/windows/directx/xact3/platforms.txt     |  1 +
 basis/windows/directx/xact3/tags.txt          |  1 -
 basis/windows/directx/xapo/platforms.txt      |  1 +
 basis/windows/directx/xapo/tags.txt           |  1 -
 basis/windows/directx/xapofx/platforms.txt    |  1 +
 basis/windows/directx/xapofx/tags.txt         |  1 -
 basis/windows/directx/xaudio2/platforms.txt   |  1 +
 basis/windows/directx/xaudio2/tags.txt        |  1 -
 basis/windows/directx/xaudio2fx/platforms.txt |  1 +
 basis/windows/directx/xaudio2fx/tags.txt      |  1 -
 basis/windows/directx/xinput/platforms.txt    |  1 +
 basis/windows/directx/xinput/tags.txt         |  1 -
 basis/windows/dragdrop-listener/platforms.txt |  1 +
 basis/windows/dragdrop-listener/tags.txt      |  1 -
 basis/windows/dwmapi/platforms.txt            |  1 +
 basis/windows/dwmapi/tags.txt                 |  1 -
 basis/windows/errors/platforms.txt            |  1 +
 basis/windows/errors/tags.txt                 |  1 -
 basis/windows/fonts/platforms.txt             |  1 +
 basis/windows/fonts/tags.txt                  |  1 -
 basis/windows/gdi32/platforms.txt             |  1 +
 basis/windows/gdi32/tags.txt                  |  1 -
 basis/windows/kernel32/platforms.txt          |  1 +
 basis/windows/kernel32/tags.txt               |  1 -
 basis/windows/messages/platforms.txt          |  1 +
 basis/windows/messages/tags.txt               |  1 -
 basis/windows/nt/platforms.txt                |  1 +
 basis/windows/nt/tags.txt                     |  1 -
 basis/windows/offscreen/platforms.txt         |  1 +
 basis/windows/offscreen/tags.txt              |  1 -
 basis/windows/ole32/platforms.txt             |  1 +
 basis/windows/ole32/tags.txt                  |  1 -
 basis/windows/opengl32/platforms.txt          |  1 +
 basis/windows/opengl32/tags.txt               |  1 -
 basis/windows/platforms.txt                   |  1 +
 basis/windows/psapi/platforms.txt             |  1 +
 basis/windows/psapi/tags.txt                  |  1 -
 basis/windows/shell32/platforms.txt           |  1 +
 basis/windows/shell32/tags.txt                |  1 -
 basis/windows/tags.txt                        |  1 -
 basis/windows/time/platforms.txt              |  1 +
 basis/windows/time/tags.txt                   |  1 -
 basis/windows/types/platforms.txt             |  1 +
 basis/windows/types/tags.txt                  |  1 -
 basis/windows/uniscribe/platforms.txt         |  1 +
 basis/windows/uniscribe/tags.txt              |  1 -
 basis/windows/user32/platforms.txt            |  1 +
 basis/windows/user32/tags.txt                 |  1 -
 basis/windows/usp10/platforms.txt             |  1 +
 basis/windows/usp10/tags.txt                  |  1 -
 basis/windows/winsock/platforms.txt           |  1 +
 basis/windows/winsock/tags.txt                |  1 -
 basis/x11/io/unix/platforms.txt               |  1 +
 basis/x11/io/unix/tags.txt                    |  1 -
 basis/x11/windows/platforms.txt               |  1 +
 basis/x11/windows/tags.txt                    |  1 -
 core/vocabs/loader/loader.factor              | 11 +++-
 core/vocabs/loader/test/a/a.factor            |  2 +-
 core/vocabs/loader/test/a/tags.txt            |  2 +-
 core/vocabs/loader/test/b/tags.txt            |  2 +-
 core/vocabs/loader/test/c/tags.txt            |  2 +-
 core/vocabs/loader/test/d/tags.txt            |  2 +-
 core/vocabs/loader/test/e/tags.txt            |  2 +-
 core/vocabs/loader/test/f/tags.txt            |  2 +-
 core/vocabs/loader/test/g/tags.txt            |  2 +-
 core/vocabs/loader/test/h/tags.txt            |  2 +-
 core/vocabs/loader/test/i/tags.txt            |  2 +-
 core/vocabs/loader/test/j/tags.txt            |  2 +-
 core/vocabs/loader/test/k/tags.txt            |  2 +-
 core/vocabs/loader/test/l/tags.txt            |  2 +-
 extra/couchdb/tags.txt                        |  2 +-
 extra/curses/ffi/platforms.txt                |  1 +
 extra/curses/ffi/tags.txt                     |  1 -
 extra/curses/platforms.txt                    |  1 +
 extra/curses/tags.txt                         |  1 -
 extra/ecdsa/tags.txt                          |  2 +-
 extra/io/serial/tags.txt                      |  1 -
 extra/io/serial/unix/bsd/platforms.txt        |  1 +
 extra/io/serial/unix/bsd/tags.txt             |  1 -
 extra/io/serial/unix/linux/platforms.txt      |  1 +
 extra/io/serial/unix/linux/tags.txt           |  1 -
 extra/io/serial/unix/platforms.txt            |  1 +
 extra/io/serial/unix/tags.txt                 |  1 -
 .../io/serial/unix/termios/bsd/platforms.txt  |  1 +
 extra/io/serial/unix/termios/bsd/tags.txt     |  1 -
 .../serial/unix/termios/linux/platforms.txt   |  1 +
 extra/io/serial/unix/termios/linux/tags.txt   |  1 -
 extra/io/serial/unix/termios/platforms.txt    |  1 +
 extra/io/serial/unix/termios/tags.txt         |  1 -
 extra/io/serial/windows/platforms.txt         |  1 +
 extra/io/serial/windows/tags.txt              |  1 -
 extra/libusb/platforms.txt                    |  1 +
 extra/libusb/tags.txt                         |  1 -
 extra/llvm/core/tags.txt                      |  2 +-
 extra/llvm/engine/tags.txt                    |  2 +-
 extra/llvm/invoker/tags.txt                   |  2 +-
 extra/llvm/jit/tags.txt                       |  2 +-
 extra/llvm/reader/tags.txt                    |  2 +-
 extra/llvm/tags.txt                           |  2 +-
 extra/llvm/types/tags.txt                     |  2 +-
 extra/llvm/wrappers/tags.txt                  |  2 +-
 extra/merger/platforms.txt                    |  1 +
 extra/merger/tags.txt                         |  2 -
 extra/openal/alut/macosx/platforms.txt        |  1 +
 extra/openal/alut/macosx/tags.txt             |  1 -
 extra/qtkit/platforms.txt                     |  1 +
 extra/qtkit/tags.txt                          |  1 -
 extra/webkit-demo/platforms.txt               |  1 +
 extra/webkit-demo/tags.txt                    |  1 -
 616 files changed, 400 insertions(+), 369 deletions(-)
 create mode 100644 basis/calendar/unix/platforms.txt
 delete mode 100644 basis/calendar/unix/tags.txt
 create mode 100644 basis/calendar/windows/platforms.txt
 delete mode 100755 basis/calendar/windows/tags.txt
 create mode 100644 basis/cocoa/application/platforms.txt
 delete mode 100644 basis/cocoa/application/tags.txt
 create mode 100644 basis/cocoa/callbacks/platforms.txt
 delete mode 100644 basis/cocoa/callbacks/tags.txt
 create mode 100644 basis/cocoa/dialogs/platforms.txt
 delete mode 100644 basis/cocoa/dialogs/tags.txt
 create mode 100644 basis/cocoa/enumeration/platforms.txt
 delete mode 100644 basis/cocoa/enumeration/tags.txt
 create mode 100644 basis/cocoa/messages/platforms.txt
 delete mode 100644 basis/cocoa/messages/tags.txt
 create mode 100644 basis/cocoa/nibs/platforms.txt
 delete mode 100644 basis/cocoa/nibs/tags.txt
 create mode 100644 basis/cocoa/pasteboard/platforms.txt
 delete mode 100644 basis/cocoa/pasteboard/tags.txt
 create mode 100644 basis/cocoa/platforms.txt
 create mode 100644 basis/cocoa/plists/platforms.txt
 delete mode 100644 basis/cocoa/plists/tags.txt
 create mode 100644 basis/cocoa/runtime/platforms.txt
 delete mode 100644 basis/cocoa/runtime/tags.txt
 create mode 100644 basis/cocoa/subclassing/platforms.txt
 delete mode 100644 basis/cocoa/subclassing/tags.txt
 create mode 100644 basis/cocoa/types/platforms.txt
 delete mode 100644 basis/cocoa/types/tags.txt
 create mode 100644 basis/cocoa/views/platforms.txt
 delete mode 100644 basis/cocoa/views/tags.txt
 create mode 100644 basis/cocoa/windows/platforms.txt
 delete mode 100644 basis/cocoa/windows/tags.txt
 create mode 100644 basis/core-foundation/arrays/platforms.txt
 create mode 100644 basis/core-foundation/attributed-strings/platforms.txt
 create mode 100644 basis/core-foundation/bundles/platforms.txt
 create mode 100644 basis/core-foundation/data/platforms.txt
 create mode 100644 basis/core-foundation/dictionaries/platforms.txt
 create mode 100644 basis/core-foundation/file-descriptors/platforms.txt
 create mode 100644 basis/core-foundation/fsevents/platforms.txt
 delete mode 100644 basis/core-foundation/fsevents/tags.txt
 create mode 100644 basis/core-foundation/numbers/platforms.txt
 delete mode 100644 basis/core-foundation/numbers/tags.txt
 create mode 100644 basis/core-foundation/platforms.txt
 create mode 100644 basis/core-foundation/run-loop/platforms.txt
 delete mode 100644 basis/core-foundation/run-loop/tags.txt
 create mode 100644 basis/core-foundation/strings/platforms.txt
 create mode 100644 basis/core-foundation/timers/platforms.txt
 create mode 100644 basis/core-foundation/urls/platforms.txt
 create mode 100644 basis/core-foundation/utilities/platforms.txt
 delete mode 100644 basis/core-foundation/utilities/tags.txt
 create mode 100644 basis/core-graphics/platforms.txt
 create mode 100644 basis/core-text/fonts/platforms.txt
 create mode 100644 basis/core-text/platforms.txt
 delete mode 100644 basis/cpu/ppc/assembler/backend/tags.txt
 delete mode 100644 basis/cpu/x86/assembler/syntax/tags.txt
 create mode 100644 basis/debugger/windows/platforms.txt
 delete mode 100644 basis/debugger/windows/tags.txt
 create mode 100644 basis/environment/unix/macosx/platforms.txt
 delete mode 100644 basis/environment/unix/macosx/tags.txt
 create mode 100644 basis/environment/unix/platforms.txt
 delete mode 100644 basis/environment/unix/tags.txt
 create mode 100644 basis/environment/winnt/platforms.txt
 delete mode 100644 basis/environment/winnt/tags.txt
 create mode 100644 basis/game/input/dinput/platforms.txt
 create mode 100644 basis/game/input/iokit/platforms.txt
 create mode 100644 basis/game/input/linux/platforms.txt
 create mode 100644 basis/game/input/xinput/platforms.txt
 create mode 100644 basis/io/backend/unix/bsd/platforms.txt
 delete mode 100644 basis/io/backend/unix/bsd/tags.txt
 create mode 100644 basis/io/backend/unix/freebsd/platforms.txt
 delete mode 100644 basis/io/backend/unix/freebsd/tags.txt
 create mode 100644 basis/io/backend/unix/linux/platforms.txt
 delete mode 100644 basis/io/backend/unix/linux/tags.txt
 create mode 100644 basis/io/backend/unix/macosx/platforms.txt
 delete mode 100644 basis/io/backend/unix/macosx/tags.txt
 create mode 100644 basis/io/backend/unix/multiplexers/epoll/platforms.txt
 delete mode 100644 basis/io/backend/unix/multiplexers/epoll/tags.txt
 create mode 100644 basis/io/backend/unix/multiplexers/kqueue/platforms.txt
 delete mode 100644 basis/io/backend/unix/multiplexers/kqueue/tags.txt
 create mode 100644 basis/io/backend/unix/multiplexers/platforms.txt
 create mode 100644 basis/io/backend/unix/multiplexers/run-loop/platforms.txt
 delete mode 100644 basis/io/backend/unix/multiplexers/run-loop/tags.txt
 create mode 100644 basis/io/backend/unix/multiplexers/select/platforms.txt
 delete mode 100644 basis/io/backend/unix/multiplexers/select/tags.txt
 delete mode 100755 basis/io/backend/unix/multiplexers/tags.txt
 create mode 100644 basis/io/backend/unix/netbsd/platforms.txt
 delete mode 100644 basis/io/backend/unix/netbsd/tags.txt
 create mode 100644 basis/io/backend/unix/openbsd/platforms.txt
 delete mode 100644 basis/io/backend/unix/openbsd/tags.txt
 create mode 100644 basis/io/backend/unix/platforms.txt
 delete mode 100644 basis/io/backend/unix/tags.txt
 create mode 100644 basis/io/backend/windows/nt/platforms.txt
 create mode 100644 basis/io/backend/windows/nt/privileges/platforms.txt
 delete mode 100644 basis/io/backend/windows/nt/privileges/tags.txt
 delete mode 100644 basis/io/backend/windows/nt/tags.txt
 create mode 100644 basis/io/backend/windows/platforms.txt
 create mode 100644 basis/io/backend/windows/privileges/platforms.txt
 delete mode 100644 basis/io/backend/windows/privileges/tags.txt
 delete mode 100755 basis/io/backend/windows/tags.txt
 create mode 100644 basis/io/directories/search/windows/platforms.txt
 delete mode 100644 basis/io/directories/search/windows/tags.txt
 create mode 100644 basis/io/directories/unix/linux/platforms.txt
 delete mode 100644 basis/io/directories/unix/linux/tags.txt
 create mode 100644 basis/io/directories/unix/platforms.txt
 delete mode 100644 basis/io/directories/unix/tags.txt
 create mode 100644 basis/io/directories/windows/platforms.txt
 delete mode 100644 basis/io/directories/windows/tags.txt
 create mode 100644 basis/io/files/info/unix/bsd/platforms.txt
 delete mode 100644 basis/io/files/info/unix/bsd/tags.txt
 create mode 100644 basis/io/files/info/unix/freebsd/platforms.txt
 delete mode 100644 basis/io/files/info/unix/freebsd/tags.txt
 create mode 100644 basis/io/files/info/unix/linux/platforms.txt
 delete mode 100644 basis/io/files/info/unix/linux/tags.txt
 create mode 100644 basis/io/files/info/unix/macosx/platforms.txt
 delete mode 100644 basis/io/files/info/unix/macosx/tags.txt
 create mode 100644 basis/io/files/info/unix/netbsd/platforms.txt
 delete mode 100644 basis/io/files/info/unix/netbsd/tags.txt
 create mode 100644 basis/io/files/info/unix/openbsd/platforms.txt
 delete mode 100644 basis/io/files/info/unix/openbsd/tags.txt
 create mode 100644 basis/io/files/info/unix/platforms.txt
 delete mode 100644 basis/io/files/info/unix/tags.txt
 create mode 100644 basis/io/files/info/windows/platforms.txt
 delete mode 100644 basis/io/files/info/windows/tags.txt
 create mode 100644 basis/io/files/links/unix/platforms.txt
 delete mode 100644 basis/io/files/links/unix/tags.txt
 create mode 100644 basis/io/files/unique/unix/platforms.txt
 delete mode 100644 basis/io/files/unique/unix/tags.txt
 create mode 100644 basis/io/files/unique/windows/platforms.txt
 delete mode 100644 basis/io/files/unique/windows/tags.txt
 create mode 100644 basis/io/files/unix/platforms.txt
 delete mode 100644 basis/io/files/unix/tags.txt
 create mode 100644 basis/io/files/windows/nt/platforms.txt
 delete mode 100644 basis/io/files/windows/nt/tags.txt
 create mode 100644 basis/io/files/windows/platforms.txt
 delete mode 100644 basis/io/files/windows/tags.txt
 create mode 100644 basis/io/launcher/unix/parser/platforms.txt
 delete mode 100644 basis/io/launcher/unix/parser/tags.txt
 create mode 100644 basis/io/launcher/unix/platforms.txt
 delete mode 100644 basis/io/launcher/unix/tags.txt
 create mode 100644 basis/io/launcher/windows/nt/platforms.txt
 delete mode 100644 basis/io/launcher/windows/nt/tags.txt
 create mode 100644 basis/io/launcher/windows/platforms.txt
 delete mode 100644 basis/io/launcher/windows/tags.txt
 create mode 100644 basis/io/mmap/unix/platforms.txt
 delete mode 100644 basis/io/mmap/unix/tags.txt
 create mode 100644 basis/io/mmap/windows/platforms.txt
 delete mode 100644 basis/io/mmap/windows/tags.txt
 create mode 100644 basis/io/monitors/linux/platforms.txt
 delete mode 100644 basis/io/monitors/linux/tags.txt
 create mode 100644 basis/io/monitors/macosx/platforms.txt
 delete mode 100644 basis/io/monitors/macosx/tags.txt
 create mode 100644 basis/io/monitors/windows/nt/platforms.txt
 delete mode 100644 basis/io/monitors/windows/nt/tags.txt
 create mode 100644 basis/io/pipes/unix/platforms.txt
 delete mode 100644 basis/io/pipes/unix/tags.txt
 create mode 100644 basis/io/pipes/windows/nt/platforms.txt
 delete mode 100644 basis/io/pipes/windows/nt/tags.txt
 create mode 100644 basis/io/sockets/secure/unix/platforms.txt
 delete mode 100644 basis/io/sockets/secure/unix/tags.txt
 create mode 100644 basis/io/sockets/unix/platforms.txt
 delete mode 100644 basis/io/sockets/unix/tags.txt
 create mode 100644 basis/io/sockets/windows/nt/platforms.txt
 delete mode 100644 basis/io/sockets/windows/nt/tags.txt
 create mode 100644 basis/io/sockets/windows/platforms.txt
 delete mode 100644 basis/io/sockets/windows/tags.txt
 create mode 100644 basis/iokit/hid/platforms.txt
 create mode 100644 basis/iokit/platforms.txt
 create mode 100644 basis/opengl/gl/macosx/platforms.txt
 delete mode 100644 basis/opengl/gl/macosx/tags.txt
 create mode 100644 basis/opengl/gl/unix/platforms.txt
 delete mode 100644 basis/opengl/gl/unix/tags.txt
 create mode 100644 basis/opengl/gl/windows/platforms.txt
 delete mode 100755 basis/opengl/gl/windows/tags.txt
 create mode 100644 basis/random/unix/platforms.txt
 delete mode 100644 basis/random/unix/tags.txt
 create mode 100644 basis/random/windows/platforms.txt
 delete mode 100755 basis/random/windows/tags.txt
 create mode 100644 basis/system-info/linux/platforms.txt
 delete mode 100644 basis/system-info/linux/tags.txt
 create mode 100644 basis/system-info/macosx/platforms.txt
 delete mode 100644 basis/system-info/macosx/tags.txt
 create mode 100644 basis/system-info/windows/ce/platforms.txt
 delete mode 100644 basis/system-info/windows/ce/tags.txt
 create mode 100644 basis/system-info/windows/nt/platforms.txt
 delete mode 100644 basis/system-info/windows/nt/tags.txt
 create mode 100644 basis/system-info/windows/platforms.txt
 delete mode 100755 basis/system-info/windows/tags.txt
 create mode 100644 basis/tools/cocoa/platforms.txt
 delete mode 100644 basis/tools/cocoa/tags.txt
 delete mode 100644 basis/tools/deploy/libraries/tags.txt
 create mode 100644 basis/tools/deploy/libraries/unix/platforms.txt
 delete mode 100644 basis/tools/deploy/libraries/unix/tags.txt
 create mode 100644 basis/tools/deploy/libraries/windows/platforms.txt
 delete mode 100644 basis/tools/deploy/libraries/windows/tags.txt
 create mode 100644 basis/tools/deploy/macosx/platforms.txt
 create mode 100644 basis/tools/deploy/test/14/platforms.txt
 delete mode 100644 basis/tools/deploy/test/14/tags.txt
 create mode 100644 basis/tools/deploy/unix/platforms.txt
 create mode 100644 basis/tools/deploy/windows/ico/platforms.txt
 delete mode 100644 basis/tools/deploy/windows/ico/tags.txt
 create mode 100644 basis/tools/deploy/windows/platforms.txt
 delete mode 100644 basis/tools/files/tags.txt
 create mode 100644 basis/tools/files/unix/platforms.txt
 delete mode 100644 basis/tools/files/unix/tags.txt
 create mode 100644 basis/tools/files/windows/platforms.txt
 delete mode 100644 basis/tools/files/windows/tags.txt
 create mode 100644 basis/tools/scaffold/windows/platforms.txt
 delete mode 100644 basis/tools/scaffold/windows/tags.txt
 create mode 100644 basis/ui/backend/cocoa/platforms.txt
 delete mode 100644 basis/ui/backend/cocoa/tags.txt
 create mode 100644 basis/ui/backend/cocoa/tools/platforms.txt
 delete mode 100644 basis/ui/backend/cocoa/tools/tags.txt
 create mode 100644 basis/ui/backend/cocoa/views/platforms.txt
 delete mode 100644 basis/ui/backend/cocoa/views/tags.txt
 create mode 100644 basis/ui/backend/windows/platforms.txt
 delete mode 100644 basis/ui/backend/windows/tags.txt
 create mode 100644 basis/ui/text/core-text/platforms.txt
 delete mode 100644 basis/ui/text/core-text/tags.txt
 create mode 100644 basis/ui/text/uniscribe/platforms.txt
 delete mode 100755 basis/ui/text/uniscribe/tags.txt
 create mode 100644 basis/unix/debugger/platforms.txt
 delete mode 100644 basis/unix/debugger/tags.txt
 create mode 100644 basis/unix/ffi/bsd/freebsd/platforms.txt
 delete mode 100644 basis/unix/ffi/bsd/freebsd/tags.txt
 create mode 100644 basis/unix/ffi/bsd/macosx/platforms.txt
 delete mode 100644 basis/unix/ffi/bsd/macosx/tags.txt
 create mode 100644 basis/unix/ffi/bsd/netbsd/platforms.txt
 delete mode 100644 basis/unix/ffi/bsd/netbsd/tags.txt
 create mode 100644 basis/unix/ffi/bsd/openbsd/platforms.txt
 delete mode 100644 basis/unix/ffi/bsd/openbsd/tags.txt
 create mode 100644 basis/unix/ffi/bsd/platforms.txt
 delete mode 100644 basis/unix/ffi/bsd/tags.txt
 create mode 100644 basis/unix/ffi/linux/platforms.txt
 delete mode 100644 basis/unix/ffi/linux/tags.txt
 create mode 100644 basis/unix/ffi/platforms.txt
 create mode 100644 basis/unix/ffi/solaris/platforms.txt
 delete mode 100644 basis/unix/ffi/solaris/tags.txt
 delete mode 100644 basis/unix/ffi/tags.txt
 create mode 100644 basis/unix/getfsstat/freebsd/platforms.txt
 delete mode 100644 basis/unix/getfsstat/freebsd/tags.txt
 create mode 100644 basis/unix/getfsstat/macosx/platforms.txt
 delete mode 100644 basis/unix/getfsstat/macosx/tags.txt
 create mode 100644 basis/unix/getfsstat/netbsd/platforms.txt
 delete mode 100644 basis/unix/getfsstat/netbsd/tags.txt
 create mode 100644 basis/unix/getfsstat/openbsd/platforms.txt
 delete mode 100644 basis/unix/getfsstat/openbsd/tags.txt
 create mode 100644 basis/unix/groups/platforms.txt
 delete mode 100644 basis/unix/groups/tags.txt
 create mode 100644 basis/unix/kqueue/freebsd/platforms.txt
 delete mode 100644 basis/unix/kqueue/freebsd/tags.txt
 create mode 100644 basis/unix/kqueue/macosx/platforms.txt
 delete mode 100644 basis/unix/kqueue/macosx/tags.txt
 create mode 100644 basis/unix/kqueue/netbsd/platforms.txt
 delete mode 100644 basis/unix/kqueue/netbsd/tags.txt
 create mode 100644 basis/unix/kqueue/openbsd/platforms.txt
 delete mode 100644 basis/unix/kqueue/openbsd/tags.txt
 create mode 100644 basis/unix/kqueue/platforms.txt
 delete mode 100644 basis/unix/kqueue/tags.txt
 create mode 100644 basis/unix/linux/epoll/platforms.txt
 delete mode 100644 basis/unix/linux/epoll/tags.txt
 create mode 100644 basis/unix/linux/inotify/platforms.txt
 delete mode 100644 basis/unix/linux/inotify/tags.txt
 create mode 100644 basis/unix/linux/platforms.txt
 delete mode 100644 basis/unix/linux/tags.txt
 create mode 100644 basis/unix/platforms.txt
 create mode 100644 basis/unix/process/platforms.txt
 delete mode 100644 basis/unix/process/tags.txt
 create mode 100644 basis/unix/stat/freebsd/platforms.txt
 delete mode 100644 basis/unix/stat/freebsd/tags.txt
 create mode 100644 basis/unix/stat/linux/platforms.txt
 delete mode 100644 basis/unix/stat/linux/tags.txt
 create mode 100644 basis/unix/stat/macosx/platforms.txt
 delete mode 100644 basis/unix/stat/macosx/tags.txt
 create mode 100644 basis/unix/stat/netbsd/platforms.txt
 delete mode 100644 basis/unix/stat/netbsd/tags.txt
 create mode 100644 basis/unix/stat/openbsd/platforms.txt
 delete mode 100644 basis/unix/stat/openbsd/tags.txt
 create mode 100644 basis/unix/stat/platforms.txt
 delete mode 100644 basis/unix/stat/tags.txt
 create mode 100644 basis/unix/statfs/freebsd/platforms.txt
 delete mode 100644 basis/unix/statfs/freebsd/tags.txt
 create mode 100644 basis/unix/statfs/linux/platforms.txt
 delete mode 100644 basis/unix/statfs/linux/tags.txt
 create mode 100644 basis/unix/statfs/macosx/platforms.txt
 delete mode 100644 basis/unix/statfs/macosx/tags.txt
 create mode 100644 basis/unix/statfs/openbsd/platforms.txt
 delete mode 100644 basis/unix/statfs/openbsd/tags.txt
 create mode 100644 basis/unix/statvfs/freebsd/platforms.txt
 delete mode 100644 basis/unix/statvfs/freebsd/tags.txt
 create mode 100644 basis/unix/statvfs/linux/platforms.txt
 delete mode 100644 basis/unix/statvfs/linux/tags.txt
 create mode 100644 basis/unix/statvfs/macosx/platforms.txt
 delete mode 100644 basis/unix/statvfs/macosx/tags.txt
 create mode 100644 basis/unix/statvfs/netbsd/platforms.txt
 delete mode 100644 basis/unix/statvfs/netbsd/tags.txt
 create mode 100644 basis/unix/statvfs/openbsd/platforms.txt
 delete mode 100644 basis/unix/statvfs/openbsd/tags.txt
 create mode 100644 basis/unix/statvfs/platforms.txt
 delete mode 100644 basis/unix/statvfs/tags.txt
 create mode 100644 basis/unix/time/platforms.txt
 delete mode 100644 basis/unix/time/tags.txt
 create mode 100644 basis/unix/types/freebsd/platforms.txt
 delete mode 100644 basis/unix/types/freebsd/tags.txt
 create mode 100644 basis/unix/types/linux/platforms.txt
 delete mode 100644 basis/unix/types/linux/tags.txt
 create mode 100644 basis/unix/types/macosx/platforms.txt
 delete mode 100644 basis/unix/types/macosx/tags.txt
 create mode 100644 basis/unix/types/netbsd/platforms.txt
 delete mode 100644 basis/unix/types/netbsd/tags.txt
 create mode 100644 basis/unix/types/openbsd/platforms.txt
 delete mode 100644 basis/unix/types/openbsd/tags.txt
 create mode 100644 basis/unix/types/platforms.txt
 delete mode 100644 basis/unix/types/tags.txt
 create mode 100644 basis/unix/users/bsd/platforms.txt
 delete mode 100644 basis/unix/users/bsd/tags.txt
 create mode 100644 basis/unix/users/platforms.txt
 delete mode 100644 basis/unix/users/tags.txt
 create mode 100644 basis/unix/utilities/platforms.txt
 delete mode 100644 basis/unix/utilities/tags.txt
 create mode 100644 basis/unix/utmpx/macosx/platforms.txt
 delete mode 100644 basis/unix/utmpx/macosx/tags.txt
 create mode 100644 basis/unix/utmpx/netbsd/platforms.txt
 delete mode 100644 basis/unix/utmpx/netbsd/tags.txt
 create mode 100644 basis/unix/utmpx/platforms.txt
 delete mode 100644 basis/unix/utmpx/tags.txt
 create mode 100644 basis/windows/advapi32/platforms.txt
 delete mode 100644 basis/windows/advapi32/tags.txt
 create mode 100644 basis/windows/ce/platforms.txt
 delete mode 100644 basis/windows/ce/tags.txt
 create mode 100644 basis/windows/com/platforms.txt
 create mode 100644 basis/windows/com/prettyprint/platforms.txt
 delete mode 100644 basis/windows/com/prettyprint/tags.txt
 create mode 100644 basis/windows/com/syntax/platforms.txt
 create mode 100644 basis/windows/com/wrapper/platforms.txt
 create mode 100644 basis/windows/directx/audiodefs/platforms.txt
 create mode 100644 basis/windows/directx/d2d1/platforms.txt
 create mode 100644 basis/windows/directx/d2dbasetypes/platforms.txt
 create mode 100644 basis/windows/directx/d2derr/platforms.txt
 create mode 100644 basis/windows/directx/d3d10/platforms.txt
 create mode 100644 basis/windows/directx/d3d10_1/platforms.txt
 create mode 100644 basis/windows/directx/d3d10_1shader/platforms.txt
 create mode 100644 basis/windows/directx/d3d10effect/platforms.txt
 create mode 100644 basis/windows/directx/d3d10misc/platforms.txt
 create mode 100644 basis/windows/directx/d3d10shader/platforms.txt
 create mode 100644 basis/windows/directx/d3d11/platforms.txt
 create mode 100644 basis/windows/directx/d3d11shader/platforms.txt
 create mode 100644 basis/windows/directx/d3d9/platforms.txt
 create mode 100644 basis/windows/directx/d3d9caps/platforms.txt
 create mode 100644 basis/windows/directx/d3d9types/platforms.txt
 create mode 100644 basis/windows/directx/d3dcommon/platforms.txt
 create mode 100644 basis/windows/directx/d3dcompiler/platforms.txt
 create mode 100644 basis/windows/directx/d3dcsx/platforms.txt
 create mode 100644 basis/windows/directx/d3dx10/platforms.txt
 create mode 100644 basis/windows/directx/d3dx10async/platforms.txt
 create mode 100644 basis/windows/directx/d3dx10core/platforms.txt
 create mode 100644 basis/windows/directx/d3dx10math/platforms.txt
 create mode 100644 basis/windows/directx/d3dx10mesh/platforms.txt
 create mode 100644 basis/windows/directx/d3dx10tex/platforms.txt
 create mode 100644 basis/windows/directx/d3dx11/platforms.txt
 create mode 100644 basis/windows/directx/d3dx11async/platforms.txt
 create mode 100644 basis/windows/directx/d3dx11core/platforms.txt
 create mode 100644 basis/windows/directx/d3dx11tex/platforms.txt
 create mode 100644 basis/windows/directx/d3dx9/platforms.txt
 create mode 100644 basis/windows/directx/d3dx9anim/platforms.txt
 create mode 100644 basis/windows/directx/d3dx9core/platforms.txt
 create mode 100644 basis/windows/directx/d3dx9effect/platforms.txt
 create mode 100644 basis/windows/directx/d3dx9math/platforms.txt
 create mode 100644 basis/windows/directx/d3dx9mesh/platforms.txt
 create mode 100644 basis/windows/directx/d3dx9shader/platforms.txt
 create mode 100644 basis/windows/directx/d3dx9shape/platforms.txt
 create mode 100644 basis/windows/directx/d3dx9tex/platforms.txt
 create mode 100644 basis/windows/directx/d3dx9xof/platforms.txt
 create mode 100644 basis/windows/directx/dcommon/platforms.txt
 create mode 100644 basis/windows/directx/dinput/constants/platforms.txt
 delete mode 100644 basis/windows/directx/dinput/constants/tags.txt
 create mode 100644 basis/windows/directx/dinput/platforms.txt
 create mode 100644 basis/windows/directx/dwrite/platforms.txt
 create mode 100644 basis/windows/directx/dxfile/platforms.txt
 create mode 100644 basis/windows/directx/dxgi/platforms.txt
 create mode 100644 basis/windows/directx/dxgiformat/platforms.txt
 create mode 100644 basis/windows/directx/dxgitype/platforms.txt
 create mode 100644 basis/windows/directx/x3daudio/platforms.txt
 create mode 100644 basis/windows/directx/xact3/platforms.txt
 create mode 100644 basis/windows/directx/xapo/platforms.txt
 create mode 100644 basis/windows/directx/xapofx/platforms.txt
 create mode 100644 basis/windows/directx/xaudio2/platforms.txt
 create mode 100644 basis/windows/directx/xaudio2fx/platforms.txt
 create mode 100644 basis/windows/directx/xinput/platforms.txt
 create mode 100644 basis/windows/dragdrop-listener/platforms.txt
 delete mode 100644 basis/windows/dragdrop-listener/tags.txt
 create mode 100644 basis/windows/dwmapi/platforms.txt
 create mode 100644 basis/windows/errors/platforms.txt
 delete mode 100644 basis/windows/errors/tags.txt
 create mode 100644 basis/windows/fonts/platforms.txt
 delete mode 100644 basis/windows/fonts/tags.txt
 create mode 100644 basis/windows/gdi32/platforms.txt
 create mode 100644 basis/windows/kernel32/platforms.txt
 delete mode 100644 basis/windows/kernel32/tags.txt
 create mode 100644 basis/windows/messages/platforms.txt
 delete mode 100644 basis/windows/messages/tags.txt
 create mode 100644 basis/windows/nt/platforms.txt
 delete mode 100644 basis/windows/nt/tags.txt
 create mode 100644 basis/windows/offscreen/platforms.txt
 delete mode 100755 basis/windows/offscreen/tags.txt
 create mode 100644 basis/windows/ole32/platforms.txt
 delete mode 100644 basis/windows/ole32/tags.txt
 create mode 100644 basis/windows/opengl32/platforms.txt
 delete mode 100644 basis/windows/opengl32/tags.txt
 create mode 100644 basis/windows/platforms.txt
 create mode 100644 basis/windows/psapi/platforms.txt
 create mode 100644 basis/windows/shell32/platforms.txt
 delete mode 100644 basis/windows/shell32/tags.txt
 create mode 100644 basis/windows/time/platforms.txt
 delete mode 100644 basis/windows/time/tags.txt
 create mode 100644 basis/windows/types/platforms.txt
 delete mode 100644 basis/windows/types/tags.txt
 create mode 100644 basis/windows/uniscribe/platforms.txt
 delete mode 100755 basis/windows/uniscribe/tags.txt
 create mode 100644 basis/windows/user32/platforms.txt
 delete mode 100644 basis/windows/user32/tags.txt
 create mode 100644 basis/windows/usp10/platforms.txt
 create mode 100644 basis/windows/winsock/platforms.txt
 delete mode 100644 basis/windows/winsock/tags.txt
 create mode 100644 basis/x11/io/unix/platforms.txt
 delete mode 100644 basis/x11/io/unix/tags.txt
 create mode 100644 basis/x11/windows/platforms.txt
 delete mode 100644 basis/x11/windows/tags.txt
 create mode 100644 extra/curses/ffi/platforms.txt
 delete mode 100644 extra/curses/ffi/tags.txt
 create mode 100644 extra/curses/platforms.txt
 delete mode 100644 extra/curses/tags.txt
 delete mode 100644 extra/io/serial/tags.txt
 create mode 100644 extra/io/serial/unix/bsd/platforms.txt
 delete mode 100644 extra/io/serial/unix/bsd/tags.txt
 create mode 100644 extra/io/serial/unix/linux/platforms.txt
 delete mode 100644 extra/io/serial/unix/linux/tags.txt
 create mode 100644 extra/io/serial/unix/platforms.txt
 delete mode 100644 extra/io/serial/unix/tags.txt
 create mode 100644 extra/io/serial/unix/termios/bsd/platforms.txt
 delete mode 100644 extra/io/serial/unix/termios/bsd/tags.txt
 create mode 100644 extra/io/serial/unix/termios/linux/platforms.txt
 delete mode 100644 extra/io/serial/unix/termios/linux/tags.txt
 create mode 100644 extra/io/serial/unix/termios/platforms.txt
 delete mode 100644 extra/io/serial/unix/termios/tags.txt
 create mode 100644 extra/io/serial/windows/platforms.txt
 delete mode 100644 extra/io/serial/windows/tags.txt
 create mode 100644 extra/libusb/platforms.txt
 create mode 100644 extra/merger/platforms.txt
 delete mode 100644 extra/merger/tags.txt
 create mode 100644 extra/openal/alut/macosx/platforms.txt
 delete mode 100644 extra/openal/alut/macosx/tags.txt
 create mode 100644 extra/qtkit/platforms.txt
 delete mode 100644 extra/qtkit/tags.txt
 create mode 100644 extra/webkit-demo/platforms.txt
 delete mode 100644 extra/webkit-demo/tags.txt

diff --git a/basis/bootstrap/compiler/timing/tags.txt b/basis/bootstrap/compiler/timing/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/bootstrap/compiler/timing/tags.txt
+++ b/basis/bootstrap/compiler/timing/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/calendar/unix/platforms.txt b/basis/calendar/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/calendar/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/calendar/unix/tags.txt b/basis/calendar/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/calendar/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/calendar/windows/platforms.txt b/basis/calendar/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/calendar/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/calendar/windows/tags.txt b/basis/calendar/windows/tags.txt
deleted file mode 100755
index 6bf68304bb..0000000000
--- a/basis/calendar/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cocoa/application/platforms.txt b/basis/cocoa/application/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/cocoa/application/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/cocoa/application/tags.txt b/basis/cocoa/application/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cocoa/application/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cocoa/callbacks/platforms.txt b/basis/cocoa/callbacks/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/cocoa/callbacks/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/cocoa/callbacks/tags.txt b/basis/cocoa/callbacks/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cocoa/callbacks/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cocoa/dialogs/platforms.txt b/basis/cocoa/dialogs/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/cocoa/dialogs/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/cocoa/dialogs/tags.txt b/basis/cocoa/dialogs/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cocoa/dialogs/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cocoa/enumeration/platforms.txt b/basis/cocoa/enumeration/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/cocoa/enumeration/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/cocoa/enumeration/tags.txt b/basis/cocoa/enumeration/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cocoa/enumeration/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cocoa/messages/platforms.txt b/basis/cocoa/messages/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/cocoa/messages/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/cocoa/messages/tags.txt b/basis/cocoa/messages/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cocoa/messages/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cocoa/nibs/platforms.txt b/basis/cocoa/nibs/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/cocoa/nibs/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/cocoa/nibs/tags.txt b/basis/cocoa/nibs/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cocoa/nibs/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cocoa/pasteboard/platforms.txt b/basis/cocoa/pasteboard/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/cocoa/pasteboard/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/cocoa/pasteboard/tags.txt b/basis/cocoa/pasteboard/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cocoa/pasteboard/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cocoa/platforms.txt b/basis/cocoa/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/cocoa/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/cocoa/plists/platforms.txt b/basis/cocoa/plists/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/cocoa/plists/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/cocoa/plists/tags.txt b/basis/cocoa/plists/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cocoa/plists/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cocoa/runtime/platforms.txt b/basis/cocoa/runtime/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/cocoa/runtime/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/cocoa/runtime/tags.txt b/basis/cocoa/runtime/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cocoa/runtime/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cocoa/subclassing/platforms.txt b/basis/cocoa/subclassing/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/cocoa/subclassing/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/cocoa/subclassing/tags.txt b/basis/cocoa/subclassing/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cocoa/subclassing/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cocoa/tags.txt b/basis/cocoa/tags.txt
index 86dd9eeb91..40fc52b29b 100644
--- a/basis/cocoa/tags.txt
+++ b/basis/cocoa/tags.txt
@@ -1,3 +1,2 @@
-unportable
 bindings
 ffi
diff --git a/basis/cocoa/types/platforms.txt b/basis/cocoa/types/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/cocoa/types/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/cocoa/types/tags.txt b/basis/cocoa/types/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cocoa/types/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cocoa/views/platforms.txt b/basis/cocoa/views/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/cocoa/views/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/cocoa/views/tags.txt b/basis/cocoa/views/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cocoa/views/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cocoa/windows/platforms.txt b/basis/cocoa/windows/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/cocoa/windows/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/cocoa/windows/tags.txt b/basis/cocoa/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cocoa/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/core-foundation/arrays/platforms.txt b/basis/core-foundation/arrays/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-foundation/arrays/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-foundation/arrays/tags.txt b/basis/core-foundation/arrays/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/core-foundation/arrays/tags.txt
+++ b/basis/core-foundation/arrays/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/core-foundation/attributed-strings/platforms.txt b/basis/core-foundation/attributed-strings/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-foundation/attributed-strings/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-foundation/attributed-strings/tags.txt b/basis/core-foundation/attributed-strings/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/core-foundation/attributed-strings/tags.txt
+++ b/basis/core-foundation/attributed-strings/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/core-foundation/bundles/platforms.txt b/basis/core-foundation/bundles/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-foundation/bundles/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-foundation/bundles/tags.txt b/basis/core-foundation/bundles/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/core-foundation/bundles/tags.txt
+++ b/basis/core-foundation/bundles/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/core-foundation/data/platforms.txt b/basis/core-foundation/data/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-foundation/data/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-foundation/data/tags.txt b/basis/core-foundation/data/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/core-foundation/data/tags.txt
+++ b/basis/core-foundation/data/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/core-foundation/dictionaries/platforms.txt b/basis/core-foundation/dictionaries/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-foundation/dictionaries/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-foundation/dictionaries/tags.txt b/basis/core-foundation/dictionaries/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/core-foundation/dictionaries/tags.txt
+++ b/basis/core-foundation/dictionaries/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/core-foundation/file-descriptors/platforms.txt b/basis/core-foundation/file-descriptors/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-foundation/file-descriptors/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-foundation/file-descriptors/tags.txt b/basis/core-foundation/file-descriptors/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/core-foundation/file-descriptors/tags.txt
+++ b/basis/core-foundation/file-descriptors/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/core-foundation/fsevents/platforms.txt b/basis/core-foundation/fsevents/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-foundation/fsevents/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-foundation/fsevents/tags.txt b/basis/core-foundation/fsevents/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/core-foundation/fsevents/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/core-foundation/numbers/platforms.txt b/basis/core-foundation/numbers/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-foundation/numbers/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-foundation/numbers/tags.txt b/basis/core-foundation/numbers/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/core-foundation/numbers/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/core-foundation/platforms.txt b/basis/core-foundation/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-foundation/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-foundation/run-loop/platforms.txt b/basis/core-foundation/run-loop/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-foundation/run-loop/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-foundation/run-loop/tags.txt b/basis/core-foundation/run-loop/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/core-foundation/run-loop/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/core-foundation/strings/platforms.txt b/basis/core-foundation/strings/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-foundation/strings/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-foundation/strings/tags.txt b/basis/core-foundation/strings/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/core-foundation/strings/tags.txt
+++ b/basis/core-foundation/strings/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/core-foundation/tags.txt b/basis/core-foundation/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/core-foundation/tags.txt
+++ b/basis/core-foundation/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/core-foundation/timers/platforms.txt b/basis/core-foundation/timers/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-foundation/timers/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-foundation/timers/tags.txt b/basis/core-foundation/timers/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/core-foundation/timers/tags.txt
+++ b/basis/core-foundation/timers/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/core-foundation/urls/platforms.txt b/basis/core-foundation/urls/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-foundation/urls/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-foundation/urls/tags.txt b/basis/core-foundation/urls/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/core-foundation/urls/tags.txt
+++ b/basis/core-foundation/urls/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/core-foundation/utilities/platforms.txt b/basis/core-foundation/utilities/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-foundation/utilities/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-foundation/utilities/tags.txt b/basis/core-foundation/utilities/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/core-foundation/utilities/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/core-graphics/platforms.txt b/basis/core-graphics/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-graphics/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-graphics/tags.txt b/basis/core-graphics/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/core-graphics/tags.txt
+++ b/basis/core-graphics/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/core-text/fonts/platforms.txt b/basis/core-text/fonts/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-text/fonts/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-text/fonts/tags.txt b/basis/core-text/fonts/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/core-text/fonts/tags.txt
+++ b/basis/core-text/fonts/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/core-text/platforms.txt b/basis/core-text/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/core-text/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/core-text/tags.txt b/basis/core-text/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/core-text/tags.txt
+++ b/basis/core-text/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/cpu/ppc/assembler/backend/tags.txt b/basis/cpu/ppc/assembler/backend/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cpu/ppc/assembler/backend/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cpu/ppc/linux/tags.txt b/basis/cpu/ppc/linux/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/cpu/ppc/linux/tags.txt
+++ b/basis/cpu/ppc/linux/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/cpu/ppc/macosx/tags.txt b/basis/cpu/ppc/macosx/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/cpu/ppc/macosx/tags.txt
+++ b/basis/cpu/ppc/macosx/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/cpu/ppc/tags.txt b/basis/cpu/ppc/tags.txt
index 8e66660f70..6c8f59c757 100644
--- a/basis/cpu/ppc/tags.txt
+++ b/basis/cpu/ppc/tags.txt
@@ -1,2 +1,2 @@
-unportable
 compiler
+untested
diff --git a/basis/cpu/x86/32/tags.txt b/basis/cpu/x86/32/tags.txt
index 8e66660f70..50dfc5156e 100644
--- a/basis/cpu/x86/32/tags.txt
+++ b/basis/cpu/x86/32/tags.txt
@@ -1,2 +1,2 @@
-unportable
+untested
 compiler
diff --git a/basis/cpu/x86/64/tags.txt b/basis/cpu/x86/64/tags.txt
index 8e66660f70..50dfc5156e 100644
--- a/basis/cpu/x86/64/tags.txt
+++ b/basis/cpu/x86/64/tags.txt
@@ -1,2 +1,2 @@
-unportable
+untested
 compiler
diff --git a/basis/cpu/x86/64/unix/tags.txt b/basis/cpu/x86/64/unix/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/cpu/x86/64/unix/tags.txt
+++ b/basis/cpu/x86/64/unix/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/cpu/x86/64/winnt/tags.txt b/basis/cpu/x86/64/winnt/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/cpu/x86/64/winnt/tags.txt
+++ b/basis/cpu/x86/64/winnt/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/cpu/x86/assembler/syntax/tags.txt b/basis/cpu/x86/assembler/syntax/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/cpu/x86/assembler/syntax/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/cpu/x86/features/tags.txt b/basis/cpu/x86/features/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/cpu/x86/features/tags.txt
+++ b/basis/cpu/x86/features/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/cpu/x86/tags.txt b/basis/cpu/x86/tags.txt
index 8e66660f70..50dfc5156e 100644
--- a/basis/cpu/x86/tags.txt
+++ b/basis/cpu/x86/tags.txt
@@ -1,2 +1,2 @@
-unportable
+untested
 compiler
diff --git a/basis/debugger/windows/platforms.txt b/basis/debugger/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/debugger/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/debugger/windows/tags.txt b/basis/debugger/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/debugger/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/editors/editpadlite/tags.txt b/basis/editors/editpadlite/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/editpadlite/tags.txt
+++ b/basis/editors/editpadlite/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/editpadpro/tags.txt b/basis/editors/editpadpro/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/editpadpro/tags.txt
+++ b/basis/editors/editpadpro/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/editplus/tags.txt b/basis/editors/editplus/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/editplus/tags.txt
+++ b/basis/editors/editplus/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/emacs/tags.txt b/basis/editors/emacs/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/emacs/tags.txt
+++ b/basis/editors/emacs/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/emacs/windows/tags.txt b/basis/editors/emacs/windows/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/emacs/windows/tags.txt
+++ b/basis/editors/emacs/windows/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/emeditor/tags.txt b/basis/editors/emeditor/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/emeditor/tags.txt
+++ b/basis/editors/emeditor/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/etexteditor/tags.txt b/basis/editors/etexteditor/tags.txt
index 6bf68304bb..5d77766703 100755
--- a/basis/editors/etexteditor/tags.txt
+++ b/basis/editors/etexteditor/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/gedit/tags.txt b/basis/editors/gedit/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/gedit/tags.txt
+++ b/basis/editors/gedit/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/gvim/tags.txt b/basis/editors/gvim/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/gvim/tags.txt
+++ b/basis/editors/gvim/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/gvim/unix/tags.txt b/basis/editors/gvim/unix/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/gvim/unix/tags.txt
+++ b/basis/editors/gvim/unix/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/gvim/windows/tags.txt b/basis/editors/gvim/windows/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/gvim/windows/tags.txt
+++ b/basis/editors/gvim/windows/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/jedit/tags.txt b/basis/editors/jedit/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/jedit/tags.txt
+++ b/basis/editors/jedit/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/macvim/tags.txt b/basis/editors/macvim/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/macvim/tags.txt
+++ b/basis/editors/macvim/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/notepad/tags.txt b/basis/editors/notepad/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/notepad/tags.txt
+++ b/basis/editors/notepad/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/notepad2/tags.txt b/basis/editors/notepad2/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/notepad2/tags.txt
+++ b/basis/editors/notepad2/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/notepadpp/tags.txt b/basis/editors/notepadpp/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/notepadpp/tags.txt
+++ b/basis/editors/notepadpp/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/scite/tags.txt b/basis/editors/scite/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/scite/tags.txt
+++ b/basis/editors/scite/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/ted-notepad/tags.txt b/basis/editors/ted-notepad/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/ted-notepad/tags.txt
+++ b/basis/editors/ted-notepad/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/textedit/tags.txt b/basis/editors/textedit/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/textedit/tags.txt
+++ b/basis/editors/textedit/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/textmate/tags.txt b/basis/editors/textmate/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/textmate/tags.txt
+++ b/basis/editors/textmate/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/textpad/tags.txt b/basis/editors/textpad/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/textpad/tags.txt
+++ b/basis/editors/textpad/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/textwrangler/tags.txt b/basis/editors/textwrangler/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/textwrangler/tags.txt
+++ b/basis/editors/textwrangler/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/ultraedit/tags.txt b/basis/editors/ultraedit/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/ultraedit/tags.txt
+++ b/basis/editors/ultraedit/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/vim/generate-syntax/tags.txt b/basis/editors/vim/generate-syntax/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/vim/generate-syntax/tags.txt
+++ b/basis/editors/vim/generate-syntax/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/vim/tags.txt b/basis/editors/vim/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/vim/tags.txt
+++ b/basis/editors/vim/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/editors/wordpad/tags.txt b/basis/editors/wordpad/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/editors/wordpad/tags.txt
+++ b/basis/editors/wordpad/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/environment/unix/macosx/platforms.txt b/basis/environment/unix/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/environment/unix/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/environment/unix/macosx/tags.txt b/basis/environment/unix/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/environment/unix/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/environment/unix/platforms.txt b/basis/environment/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/environment/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/environment/unix/tags.txt b/basis/environment/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/environment/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/environment/winnt/platforms.txt b/basis/environment/winnt/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/environment/winnt/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/environment/winnt/tags.txt b/basis/environment/winnt/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/environment/winnt/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/game/input/dinput/platforms.txt b/basis/game/input/dinput/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/game/input/dinput/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/game/input/dinput/tags.txt b/basis/game/input/dinput/tags.txt
index 82506ff250..84d4140a70 100755
--- a/basis/game/input/dinput/tags.txt
+++ b/basis/game/input/dinput/tags.txt
@@ -1,2 +1 @@
-unportable
 games
diff --git a/basis/game/input/iokit/platforms.txt b/basis/game/input/iokit/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/game/input/iokit/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/game/input/iokit/tags.txt b/basis/game/input/iokit/tags.txt
index 82506ff250..84d4140a70 100755
--- a/basis/game/input/iokit/tags.txt
+++ b/basis/game/input/iokit/tags.txt
@@ -1,2 +1 @@
-unportable
 games
diff --git a/basis/game/input/linux/platforms.txt b/basis/game/input/linux/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/game/input/linux/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/game/input/linux/tags.txt b/basis/game/input/linux/tags.txt
index 82506ff250..84d4140a70 100644
--- a/basis/game/input/linux/tags.txt
+++ b/basis/game/input/linux/tags.txt
@@ -1,2 +1 @@
-unportable
 games
diff --git a/basis/game/input/xinput/platforms.txt b/basis/game/input/xinput/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/game/input/xinput/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/game/input/xinput/tags.txt b/basis/game/input/xinput/tags.txt
index 82506ff250..84d4140a70 100644
--- a/basis/game/input/xinput/tags.txt
+++ b/basis/game/input/xinput/tags.txt
@@ -1,2 +1 @@
-unportable
 games
diff --git a/basis/io/backend/unix/bsd/platforms.txt b/basis/io/backend/unix/bsd/platforms.txt
new file mode 100644
index 0000000000..df796f15d4
--- /dev/null
+++ b/basis/io/backend/unix/bsd/platforms.txt
@@ -0,0 +1 @@
+bsd
diff --git a/basis/io/backend/unix/bsd/tags.txt b/basis/io/backend/unix/bsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/backend/unix/bsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/unix/freebsd/platforms.txt b/basis/io/backend/unix/freebsd/platforms.txt
new file mode 100644
index 0000000000..edfe86017d
--- /dev/null
+++ b/basis/io/backend/unix/freebsd/platforms.txt
@@ -0,0 +1 @@
+freebsd
diff --git a/basis/io/backend/unix/freebsd/tags.txt b/basis/io/backend/unix/freebsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/backend/unix/freebsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/unix/linux/platforms.txt b/basis/io/backend/unix/linux/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/io/backend/unix/linux/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/io/backend/unix/linux/tags.txt b/basis/io/backend/unix/linux/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/backend/unix/linux/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/unix/macosx/platforms.txt b/basis/io/backend/unix/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/io/backend/unix/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/io/backend/unix/macosx/tags.txt b/basis/io/backend/unix/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/backend/unix/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/unix/multiplexers/epoll/platforms.txt b/basis/io/backend/unix/multiplexers/epoll/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/io/backend/unix/multiplexers/epoll/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/io/backend/unix/multiplexers/epoll/tags.txt b/basis/io/backend/unix/multiplexers/epoll/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/backend/unix/multiplexers/epoll/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/unix/multiplexers/kqueue/platforms.txt b/basis/io/backend/unix/multiplexers/kqueue/platforms.txt
new file mode 100644
index 0000000000..df796f15d4
--- /dev/null
+++ b/basis/io/backend/unix/multiplexers/kqueue/platforms.txt
@@ -0,0 +1 @@
+bsd
diff --git a/basis/io/backend/unix/multiplexers/kqueue/tags.txt b/basis/io/backend/unix/multiplexers/kqueue/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/backend/unix/multiplexers/kqueue/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/unix/multiplexers/platforms.txt b/basis/io/backend/unix/multiplexers/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/io/backend/unix/multiplexers/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/io/backend/unix/multiplexers/run-loop/platforms.txt b/basis/io/backend/unix/multiplexers/run-loop/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/io/backend/unix/multiplexers/run-loop/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/io/backend/unix/multiplexers/run-loop/tags.txt b/basis/io/backend/unix/multiplexers/run-loop/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/backend/unix/multiplexers/run-loop/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/unix/multiplexers/select/platforms.txt b/basis/io/backend/unix/multiplexers/select/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/io/backend/unix/multiplexers/select/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/io/backend/unix/multiplexers/select/tags.txt b/basis/io/backend/unix/multiplexers/select/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/backend/unix/multiplexers/select/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/unix/multiplexers/tags.txt b/basis/io/backend/unix/multiplexers/tags.txt
deleted file mode 100755
index 6abe115b12..0000000000
--- a/basis/io/backend/unix/multiplexers/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/unix/netbsd/platforms.txt b/basis/io/backend/unix/netbsd/platforms.txt
new file mode 100644
index 0000000000..dccfe71042
--- /dev/null
+++ b/basis/io/backend/unix/netbsd/platforms.txt
@@ -0,0 +1 @@
+netbsd
diff --git a/basis/io/backend/unix/netbsd/tags.txt b/basis/io/backend/unix/netbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/backend/unix/netbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/unix/openbsd/platforms.txt b/basis/io/backend/unix/openbsd/platforms.txt
new file mode 100644
index 0000000000..389b028aca
--- /dev/null
+++ b/basis/io/backend/unix/openbsd/platforms.txt
@@ -0,0 +1 @@
+openbsd
diff --git a/basis/io/backend/unix/openbsd/tags.txt b/basis/io/backend/unix/openbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/backend/unix/openbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/unix/platforms.txt b/basis/io/backend/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/io/backend/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/io/backend/unix/tags.txt b/basis/io/backend/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/backend/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/windows/nt/platforms.txt b/basis/io/backend/windows/nt/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/io/backend/windows/nt/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/io/backend/windows/nt/privileges/platforms.txt b/basis/io/backend/windows/nt/privileges/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/io/backend/windows/nt/privileges/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/io/backend/windows/nt/privileges/tags.txt b/basis/io/backend/windows/nt/privileges/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/backend/windows/nt/privileges/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/windows/nt/tags.txt b/basis/io/backend/windows/nt/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/backend/windows/nt/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/windows/platforms.txt b/basis/io/backend/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/io/backend/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/io/backend/windows/privileges/platforms.txt b/basis/io/backend/windows/privileges/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/io/backend/windows/privileges/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/io/backend/windows/privileges/tags.txt b/basis/io/backend/windows/privileges/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/backend/windows/privileges/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/backend/windows/tags.txt b/basis/io/backend/windows/tags.txt
deleted file mode 100755
index 6bf68304bb..0000000000
--- a/basis/io/backend/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/directories/search/windows/platforms.txt b/basis/io/directories/search/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/io/directories/search/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/io/directories/search/windows/tags.txt b/basis/io/directories/search/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/directories/search/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/directories/unix/linux/platforms.txt b/basis/io/directories/unix/linux/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/io/directories/unix/linux/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/io/directories/unix/linux/tags.txt b/basis/io/directories/unix/linux/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/directories/unix/linux/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/directories/unix/platforms.txt b/basis/io/directories/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/io/directories/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/io/directories/unix/tags.txt b/basis/io/directories/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/directories/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/directories/windows/platforms.txt b/basis/io/directories/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/io/directories/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/io/directories/windows/tags.txt b/basis/io/directories/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/directories/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/info/unix/bsd/platforms.txt b/basis/io/files/info/unix/bsd/platforms.txt
new file mode 100644
index 0000000000..df796f15d4
--- /dev/null
+++ b/basis/io/files/info/unix/bsd/platforms.txt
@@ -0,0 +1 @@
+bsd
diff --git a/basis/io/files/info/unix/bsd/tags.txt b/basis/io/files/info/unix/bsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/files/info/unix/bsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/info/unix/freebsd/platforms.txt b/basis/io/files/info/unix/freebsd/platforms.txt
new file mode 100644
index 0000000000..edfe86017d
--- /dev/null
+++ b/basis/io/files/info/unix/freebsd/platforms.txt
@@ -0,0 +1 @@
+freebsd
diff --git a/basis/io/files/info/unix/freebsd/tags.txt b/basis/io/files/info/unix/freebsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/files/info/unix/freebsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/info/unix/linux/platforms.txt b/basis/io/files/info/unix/linux/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/io/files/info/unix/linux/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/io/files/info/unix/linux/tags.txt b/basis/io/files/info/unix/linux/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/files/info/unix/linux/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/info/unix/macosx/platforms.txt b/basis/io/files/info/unix/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/io/files/info/unix/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/io/files/info/unix/macosx/tags.txt b/basis/io/files/info/unix/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/files/info/unix/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/info/unix/netbsd/platforms.txt b/basis/io/files/info/unix/netbsd/platforms.txt
new file mode 100644
index 0000000000..dccfe71042
--- /dev/null
+++ b/basis/io/files/info/unix/netbsd/platforms.txt
@@ -0,0 +1 @@
+netbsd
diff --git a/basis/io/files/info/unix/netbsd/tags.txt b/basis/io/files/info/unix/netbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/files/info/unix/netbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/info/unix/openbsd/platforms.txt b/basis/io/files/info/unix/openbsd/platforms.txt
new file mode 100644
index 0000000000..389b028aca
--- /dev/null
+++ b/basis/io/files/info/unix/openbsd/platforms.txt
@@ -0,0 +1 @@
+openbsd
diff --git a/basis/io/files/info/unix/openbsd/tags.txt b/basis/io/files/info/unix/openbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/files/info/unix/openbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/info/unix/platforms.txt b/basis/io/files/info/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/io/files/info/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/io/files/info/unix/tags.txt b/basis/io/files/info/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/files/info/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/info/windows/platforms.txt b/basis/io/files/info/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/io/files/info/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/io/files/info/windows/tags.txt b/basis/io/files/info/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/files/info/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/links/unix/platforms.txt b/basis/io/files/links/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/io/files/links/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/io/files/links/unix/tags.txt b/basis/io/files/links/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/files/links/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/unique/unix/platforms.txt b/basis/io/files/unique/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/io/files/unique/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/io/files/unique/unix/tags.txt b/basis/io/files/unique/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/files/unique/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/unique/windows/platforms.txt b/basis/io/files/unique/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/io/files/unique/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/io/files/unique/windows/tags.txt b/basis/io/files/unique/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/files/unique/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/unix/platforms.txt b/basis/io/files/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/io/files/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/io/files/unix/tags.txt b/basis/io/files/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/files/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/windows/nt/platforms.txt b/basis/io/files/windows/nt/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/io/files/windows/nt/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/io/files/windows/nt/tags.txt b/basis/io/files/windows/nt/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/files/windows/nt/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/files/windows/platforms.txt b/basis/io/files/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/io/files/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/io/files/windows/tags.txt b/basis/io/files/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/files/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/launcher/unix/parser/platforms.txt b/basis/io/launcher/unix/parser/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/io/launcher/unix/parser/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/io/launcher/unix/parser/tags.txt b/basis/io/launcher/unix/parser/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/launcher/unix/parser/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/launcher/unix/platforms.txt b/basis/io/launcher/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/io/launcher/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/io/launcher/unix/tags.txt b/basis/io/launcher/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/launcher/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/launcher/windows/nt/platforms.txt b/basis/io/launcher/windows/nt/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/io/launcher/windows/nt/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/io/launcher/windows/nt/tags.txt b/basis/io/launcher/windows/nt/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/launcher/windows/nt/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/launcher/windows/platforms.txt b/basis/io/launcher/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/io/launcher/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/io/launcher/windows/tags.txt b/basis/io/launcher/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/launcher/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/mmap/unix/platforms.txt b/basis/io/mmap/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/io/mmap/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/io/mmap/unix/tags.txt b/basis/io/mmap/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/mmap/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/mmap/windows/platforms.txt b/basis/io/mmap/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/io/mmap/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/io/mmap/windows/tags.txt b/basis/io/mmap/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/mmap/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/monitors/linux/platforms.txt b/basis/io/monitors/linux/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/io/monitors/linux/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/io/monitors/linux/tags.txt b/basis/io/monitors/linux/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/monitors/linux/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/monitors/macosx/platforms.txt b/basis/io/monitors/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/io/monitors/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/io/monitors/macosx/tags.txt b/basis/io/monitors/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/monitors/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/monitors/windows/nt/platforms.txt b/basis/io/monitors/windows/nt/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/io/monitors/windows/nt/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/io/monitors/windows/nt/tags.txt b/basis/io/monitors/windows/nt/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/monitors/windows/nt/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/pipes/unix/platforms.txt b/basis/io/pipes/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/io/pipes/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/io/pipes/unix/tags.txt b/basis/io/pipes/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/pipes/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/pipes/windows/nt/platforms.txt b/basis/io/pipes/windows/nt/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/io/pipes/windows/nt/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/io/pipes/windows/nt/tags.txt b/basis/io/pipes/windows/nt/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/pipes/windows/nt/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/sockets/secure/unix/platforms.txt b/basis/io/sockets/secure/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/io/sockets/secure/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/io/sockets/secure/unix/tags.txt b/basis/io/sockets/secure/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/sockets/secure/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/sockets/unix/platforms.txt b/basis/io/sockets/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/io/sockets/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/io/sockets/unix/tags.txt b/basis/io/sockets/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/sockets/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/sockets/windows/nt/platforms.txt b/basis/io/sockets/windows/nt/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/io/sockets/windows/nt/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/io/sockets/windows/nt/tags.txt b/basis/io/sockets/windows/nt/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/sockets/windows/nt/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/io/sockets/windows/platforms.txt b/basis/io/sockets/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/io/sockets/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/io/sockets/windows/tags.txt b/basis/io/sockets/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/io/sockets/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/iokit/hid/platforms.txt b/basis/iokit/hid/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/iokit/hid/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/iokit/hid/tags.txt b/basis/iokit/hid/tags.txt
index bf2a35f15b..bb863cf9a0 100755
--- a/basis/iokit/hid/tags.txt
+++ b/basis/iokit/hid/tags.txt
@@ -1,2 +1 @@
 bindings
-unportable
diff --git a/basis/iokit/platforms.txt b/basis/iokit/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/iokit/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/iokit/tags.txt b/basis/iokit/tags.txt
index bf2a35f15b..bb863cf9a0 100755
--- a/basis/iokit/tags.txt
+++ b/basis/iokit/tags.txt
@@ -1,2 +1 @@
 bindings
-unportable
diff --git a/basis/math/floats/env/ppc/tags.txt b/basis/math/floats/env/ppc/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/math/floats/env/ppc/tags.txt
+++ b/basis/math/floats/env/ppc/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/math/floats/env/x86/32/tags.txt b/basis/math/floats/env/x86/32/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/math/floats/env/x86/32/tags.txt
+++ b/basis/math/floats/env/x86/32/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/math/floats/env/x86/64/tags.txt b/basis/math/floats/env/x86/64/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/math/floats/env/x86/64/tags.txt
+++ b/basis/math/floats/env/x86/64/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/math/floats/env/x86/tags.txt b/basis/math/floats/env/x86/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/math/floats/env/x86/tags.txt
+++ b/basis/math/floats/env/x86/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/opengl/gl/macosx/platforms.txt b/basis/opengl/gl/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/opengl/gl/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/opengl/gl/macosx/tags.txt b/basis/opengl/gl/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/opengl/gl/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/opengl/gl/unix/platforms.txt b/basis/opengl/gl/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/opengl/gl/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/opengl/gl/unix/tags.txt b/basis/opengl/gl/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/opengl/gl/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/opengl/gl/windows/platforms.txt b/basis/opengl/gl/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/opengl/gl/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/opengl/gl/windows/tags.txt b/basis/opengl/gl/windows/tags.txt
deleted file mode 100755
index 6bf68304bb..0000000000
--- a/basis/opengl/gl/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/random/unix/platforms.txt b/basis/random/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/random/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/random/unix/tags.txt b/basis/random/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/random/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/random/windows/platforms.txt b/basis/random/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/random/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/random/windows/tags.txt b/basis/random/windows/tags.txt
deleted file mode 100755
index 6bf68304bb..0000000000
--- a/basis/random/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/system-info/linux/platforms.txt b/basis/system-info/linux/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/system-info/linux/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/system-info/linux/tags.txt b/basis/system-info/linux/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/system-info/linux/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/system-info/macosx/platforms.txt b/basis/system-info/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/system-info/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/system-info/macosx/tags.txt b/basis/system-info/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/system-info/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/system-info/windows/ce/platforms.txt b/basis/system-info/windows/ce/platforms.txt
new file mode 100644
index 0000000000..cd0d980f6f
--- /dev/null
+++ b/basis/system-info/windows/ce/platforms.txt
@@ -0,0 +1 @@
+wince
diff --git a/basis/system-info/windows/ce/tags.txt b/basis/system-info/windows/ce/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/system-info/windows/ce/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/system-info/windows/nt/platforms.txt b/basis/system-info/windows/nt/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/system-info/windows/nt/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/system-info/windows/nt/tags.txt b/basis/system-info/windows/nt/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/system-info/windows/nt/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/system-info/windows/platforms.txt b/basis/system-info/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/system-info/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/system-info/windows/tags.txt b/basis/system-info/windows/tags.txt
deleted file mode 100755
index 6bf68304bb..0000000000
--- a/basis/system-info/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/tools/cocoa/platforms.txt b/basis/tools/cocoa/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/tools/cocoa/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/tools/cocoa/tags.txt b/basis/tools/cocoa/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/tools/cocoa/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/tools/deploy/libraries/tags.txt b/basis/tools/deploy/libraries/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/tools/deploy/libraries/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/tools/deploy/libraries/unix/platforms.txt b/basis/tools/deploy/libraries/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/tools/deploy/libraries/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/tools/deploy/libraries/unix/tags.txt b/basis/tools/deploy/libraries/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/tools/deploy/libraries/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/tools/deploy/libraries/windows/platforms.txt b/basis/tools/deploy/libraries/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/tools/deploy/libraries/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/tools/deploy/libraries/windows/tags.txt b/basis/tools/deploy/libraries/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/tools/deploy/libraries/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/tools/deploy/macosx/platforms.txt b/basis/tools/deploy/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/tools/deploy/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/tools/deploy/macosx/tags.txt b/basis/tools/deploy/macosx/tags.txt
index 660d511420..ef1aab0d0e 100644
--- a/basis/tools/deploy/macosx/tags.txt
+++ b/basis/tools/deploy/macosx/tags.txt
@@ -1,2 +1 @@
-unportable
 tools
diff --git a/basis/tools/deploy/test/14/platforms.txt b/basis/tools/deploy/test/14/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/tools/deploy/test/14/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/tools/deploy/test/14/tags.txt b/basis/tools/deploy/test/14/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/tools/deploy/test/14/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/tools/deploy/unix/platforms.txt b/basis/tools/deploy/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/tools/deploy/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/tools/deploy/unix/tags.txt b/basis/tools/deploy/unix/tags.txt
index 660d511420..ef1aab0d0e 100644
--- a/basis/tools/deploy/unix/tags.txt
+++ b/basis/tools/deploy/unix/tags.txt
@@ -1,2 +1 @@
-unportable
 tools
diff --git a/basis/tools/deploy/windows/ico/platforms.txt b/basis/tools/deploy/windows/ico/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/tools/deploy/windows/ico/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/tools/deploy/windows/ico/tags.txt b/basis/tools/deploy/windows/ico/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/tools/deploy/windows/ico/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/tools/deploy/windows/platforms.txt b/basis/tools/deploy/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/tools/deploy/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/tools/deploy/windows/tags.txt b/basis/tools/deploy/windows/tags.txt
index 660d511420..ef1aab0d0e 100755
--- a/basis/tools/deploy/windows/tags.txt
+++ b/basis/tools/deploy/windows/tags.txt
@@ -1,2 +1 @@
-unportable
 tools
diff --git a/basis/tools/disassembler/gdb/tags.txt b/basis/tools/disassembler/gdb/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/tools/disassembler/gdb/tags.txt
+++ b/basis/tools/disassembler/gdb/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/tools/disassembler/udis/tags.txt b/basis/tools/disassembler/udis/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/tools/disassembler/udis/tags.txt
+++ b/basis/tools/disassembler/udis/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/tools/files/tags.txt b/basis/tools/files/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/tools/files/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/tools/files/unix/platforms.txt b/basis/tools/files/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/tools/files/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/tools/files/unix/tags.txt b/basis/tools/files/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/tools/files/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/tools/files/windows/platforms.txt b/basis/tools/files/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/tools/files/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/tools/files/windows/tags.txt b/basis/tools/files/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/tools/files/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/tools/scaffold/scaffold.factor b/basis/tools/scaffold/scaffold.factor
index 936d388b01..a8565fccf9 100644
--- a/basis/tools/scaffold/scaffold.factor
+++ b/basis/tools/scaffold/scaffold.factor
@@ -2,11 +2,11 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: assocs io.files io.pathnames io.directories
 io.encodings.utf8 hashtables kernel namespaces sequences
-vocabs.loader io combinators calendar accessors math.parser
-io.streams.string ui.tools.operations quotations strings arrays
-prettyprint words vocabs sorting sets classes math alien urls
-splitting ascii combinators.short-circuit alarms words.symbol
-system summary ;
+vocabs.loader vocabs.metadata io combinators calendar accessors
+math.parser io.streams.string ui.tools.operations quotations
+strings arrays prettyprint words vocabs sorting sets classes
+math alien urls splitting ascii combinators.short-circuit alarms
+words.symbol system summary ;
 IN: tools.scaffold
 
 SYMBOL: developer-name
@@ -15,7 +15,6 @@ SYMBOL: using
 ERROR: not-a-vocab-root string ;
 ERROR: vocab-name-contains-separator path ;
 ERROR: vocab-name-contains-dot path ;
-ERROR: no-vocab vocab ;
 ERROR: bad-developer-name name ;
 
 M: bad-developer-name summary
@@ -40,9 +39,6 @@ M: bad-developer-name summary
 : check-root ( string -- string )
     dup vocab-root? [ not-a-vocab-root ] unless ;
 
-: check-vocab ( vocab -- vocab )
-    dup find-vocab-root [ no-vocab ] unless ;
-
 : check-vocab-root/vocab ( vocab-root string -- vocab-root string )
     [ check-root ] [ check-vocab-name ] bi* ;
 
diff --git a/basis/tools/scaffold/windows/platforms.txt b/basis/tools/scaffold/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/tools/scaffold/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/tools/scaffold/windows/tags.txt b/basis/tools/scaffold/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/tools/scaffold/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/ui/backend/cocoa/platforms.txt b/basis/ui/backend/cocoa/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/ui/backend/cocoa/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/ui/backend/cocoa/tags.txt b/basis/ui/backend/cocoa/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/ui/backend/cocoa/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/ui/backend/cocoa/tools/platforms.txt b/basis/ui/backend/cocoa/tools/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/ui/backend/cocoa/tools/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/ui/backend/cocoa/tools/tags.txt b/basis/ui/backend/cocoa/tools/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/ui/backend/cocoa/tools/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/ui/backend/cocoa/views/platforms.txt b/basis/ui/backend/cocoa/views/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/ui/backend/cocoa/views/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/ui/backend/cocoa/views/tags.txt b/basis/ui/backend/cocoa/views/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/ui/backend/cocoa/views/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/ui/backend/windows/platforms.txt b/basis/ui/backend/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/ui/backend/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/ui/backend/windows/tags.txt b/basis/ui/backend/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/ui/backend/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/ui/backend/x11/tags.txt b/basis/ui/backend/x11/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/ui/backend/x11/tags.txt
+++ b/basis/ui/backend/x11/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/ui/text/core-text/platforms.txt b/basis/ui/text/core-text/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/ui/text/core-text/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/ui/text/core-text/tags.txt b/basis/ui/text/core-text/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/ui/text/core-text/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/ui/text/pango/tags.txt b/basis/ui/text/pango/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/ui/text/pango/tags.txt
+++ b/basis/ui/text/pango/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/ui/text/uniscribe/platforms.txt b/basis/ui/text/uniscribe/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/ui/text/uniscribe/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/ui/text/uniscribe/tags.txt b/basis/ui/text/uniscribe/tags.txt
deleted file mode 100755
index 6abe115b12..0000000000
--- a/basis/ui/text/uniscribe/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/debugger/platforms.txt b/basis/unix/debugger/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/unix/debugger/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/unix/debugger/tags.txt b/basis/unix/debugger/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/debugger/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/ffi/bsd/freebsd/platforms.txt b/basis/unix/ffi/bsd/freebsd/platforms.txt
new file mode 100644
index 0000000000..edfe86017d
--- /dev/null
+++ b/basis/unix/ffi/bsd/freebsd/platforms.txt
@@ -0,0 +1 @@
+freebsd
diff --git a/basis/unix/ffi/bsd/freebsd/tags.txt b/basis/unix/ffi/bsd/freebsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/ffi/bsd/freebsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/ffi/bsd/macosx/platforms.txt b/basis/unix/ffi/bsd/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/unix/ffi/bsd/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/unix/ffi/bsd/macosx/tags.txt b/basis/unix/ffi/bsd/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/ffi/bsd/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/ffi/bsd/netbsd/platforms.txt b/basis/unix/ffi/bsd/netbsd/platforms.txt
new file mode 100644
index 0000000000..dccfe71042
--- /dev/null
+++ b/basis/unix/ffi/bsd/netbsd/platforms.txt
@@ -0,0 +1 @@
+netbsd
diff --git a/basis/unix/ffi/bsd/netbsd/tags.txt b/basis/unix/ffi/bsd/netbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/ffi/bsd/netbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/ffi/bsd/openbsd/platforms.txt b/basis/unix/ffi/bsd/openbsd/platforms.txt
new file mode 100644
index 0000000000..389b028aca
--- /dev/null
+++ b/basis/unix/ffi/bsd/openbsd/platforms.txt
@@ -0,0 +1 @@
+openbsd
diff --git a/basis/unix/ffi/bsd/openbsd/tags.txt b/basis/unix/ffi/bsd/openbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/ffi/bsd/openbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/ffi/bsd/platforms.txt b/basis/unix/ffi/bsd/platforms.txt
new file mode 100644
index 0000000000..df796f15d4
--- /dev/null
+++ b/basis/unix/ffi/bsd/platforms.txt
@@ -0,0 +1 @@
+bsd
diff --git a/basis/unix/ffi/bsd/tags.txt b/basis/unix/ffi/bsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/ffi/bsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/ffi/linux/platforms.txt b/basis/unix/ffi/linux/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/unix/ffi/linux/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/unix/ffi/linux/tags.txt b/basis/unix/ffi/linux/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/ffi/linux/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/ffi/platforms.txt b/basis/unix/ffi/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/unix/ffi/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/unix/ffi/solaris/platforms.txt b/basis/unix/ffi/solaris/platforms.txt
new file mode 100644
index 0000000000..613a93b535
--- /dev/null
+++ b/basis/unix/ffi/solaris/platforms.txt
@@ -0,0 +1 @@
+solaris
diff --git a/basis/unix/ffi/solaris/tags.txt b/basis/unix/ffi/solaris/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/ffi/solaris/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/ffi/tags.txt b/basis/unix/ffi/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/ffi/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/getfsstat/freebsd/platforms.txt b/basis/unix/getfsstat/freebsd/platforms.txt
new file mode 100644
index 0000000000..edfe86017d
--- /dev/null
+++ b/basis/unix/getfsstat/freebsd/platforms.txt
@@ -0,0 +1 @@
+freebsd
diff --git a/basis/unix/getfsstat/freebsd/tags.txt b/basis/unix/getfsstat/freebsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/getfsstat/freebsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/getfsstat/macosx/platforms.txt b/basis/unix/getfsstat/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/unix/getfsstat/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/unix/getfsstat/macosx/tags.txt b/basis/unix/getfsstat/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/getfsstat/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/getfsstat/netbsd/platforms.txt b/basis/unix/getfsstat/netbsd/platforms.txt
new file mode 100644
index 0000000000..dccfe71042
--- /dev/null
+++ b/basis/unix/getfsstat/netbsd/platforms.txt
@@ -0,0 +1 @@
+netbsd
diff --git a/basis/unix/getfsstat/netbsd/tags.txt b/basis/unix/getfsstat/netbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/getfsstat/netbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/getfsstat/openbsd/platforms.txt b/basis/unix/getfsstat/openbsd/platforms.txt
new file mode 100644
index 0000000000..389b028aca
--- /dev/null
+++ b/basis/unix/getfsstat/openbsd/platforms.txt
@@ -0,0 +1 @@
+openbsd
diff --git a/basis/unix/getfsstat/openbsd/tags.txt b/basis/unix/getfsstat/openbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/getfsstat/openbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/groups/platforms.txt b/basis/unix/groups/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/unix/groups/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/unix/groups/tags.txt b/basis/unix/groups/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/groups/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/kqueue/freebsd/platforms.txt b/basis/unix/kqueue/freebsd/platforms.txt
new file mode 100644
index 0000000000..edfe86017d
--- /dev/null
+++ b/basis/unix/kqueue/freebsd/platforms.txt
@@ -0,0 +1 @@
+freebsd
diff --git a/basis/unix/kqueue/freebsd/tags.txt b/basis/unix/kqueue/freebsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/kqueue/freebsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/kqueue/macosx/platforms.txt b/basis/unix/kqueue/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/unix/kqueue/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/unix/kqueue/macosx/tags.txt b/basis/unix/kqueue/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/kqueue/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/kqueue/netbsd/platforms.txt b/basis/unix/kqueue/netbsd/platforms.txt
new file mode 100644
index 0000000000..dccfe71042
--- /dev/null
+++ b/basis/unix/kqueue/netbsd/platforms.txt
@@ -0,0 +1 @@
+netbsd
diff --git a/basis/unix/kqueue/netbsd/tags.txt b/basis/unix/kqueue/netbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/kqueue/netbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/kqueue/openbsd/platforms.txt b/basis/unix/kqueue/openbsd/platforms.txt
new file mode 100644
index 0000000000..389b028aca
--- /dev/null
+++ b/basis/unix/kqueue/openbsd/platforms.txt
@@ -0,0 +1 @@
+openbsd
diff --git a/basis/unix/kqueue/openbsd/tags.txt b/basis/unix/kqueue/openbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/kqueue/openbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/kqueue/platforms.txt b/basis/unix/kqueue/platforms.txt
new file mode 100644
index 0000000000..df796f15d4
--- /dev/null
+++ b/basis/unix/kqueue/platforms.txt
@@ -0,0 +1 @@
+bsd
diff --git a/basis/unix/kqueue/tags.txt b/basis/unix/kqueue/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/kqueue/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/linux/epoll/platforms.txt b/basis/unix/linux/epoll/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/unix/linux/epoll/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/unix/linux/epoll/tags.txt b/basis/unix/linux/epoll/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/linux/epoll/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/linux/inotify/platforms.txt b/basis/unix/linux/inotify/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/unix/linux/inotify/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/unix/linux/inotify/tags.txt b/basis/unix/linux/inotify/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/linux/inotify/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/linux/platforms.txt b/basis/unix/linux/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/unix/linux/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/unix/linux/tags.txt b/basis/unix/linux/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/linux/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/platforms.txt b/basis/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/unix/process/platforms.txt b/basis/unix/process/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/unix/process/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/unix/process/tags.txt b/basis/unix/process/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/process/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/stat/freebsd/platforms.txt b/basis/unix/stat/freebsd/platforms.txt
new file mode 100644
index 0000000000..edfe86017d
--- /dev/null
+++ b/basis/unix/stat/freebsd/platforms.txt
@@ -0,0 +1 @@
+freebsd
diff --git a/basis/unix/stat/freebsd/tags.txt b/basis/unix/stat/freebsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/stat/freebsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/stat/linux/32/tags.txt b/basis/unix/stat/linux/32/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/unix/stat/linux/32/tags.txt
+++ b/basis/unix/stat/linux/32/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/unix/stat/linux/64/tags.txt b/basis/unix/stat/linux/64/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/unix/stat/linux/64/tags.txt
+++ b/basis/unix/stat/linux/64/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/unix/stat/linux/platforms.txt b/basis/unix/stat/linux/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/unix/stat/linux/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/unix/stat/linux/tags.txt b/basis/unix/stat/linux/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/stat/linux/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/stat/macosx/platforms.txt b/basis/unix/stat/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/unix/stat/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/unix/stat/macosx/tags.txt b/basis/unix/stat/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/stat/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/stat/netbsd/32/tags.txt b/basis/unix/stat/netbsd/32/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/unix/stat/netbsd/32/tags.txt
+++ b/basis/unix/stat/netbsd/32/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/unix/stat/netbsd/64/tags.txt b/basis/unix/stat/netbsd/64/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/unix/stat/netbsd/64/tags.txt
+++ b/basis/unix/stat/netbsd/64/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/unix/stat/netbsd/platforms.txt b/basis/unix/stat/netbsd/platforms.txt
new file mode 100644
index 0000000000..dccfe71042
--- /dev/null
+++ b/basis/unix/stat/netbsd/platforms.txt
@@ -0,0 +1 @@
+netbsd
diff --git a/basis/unix/stat/netbsd/tags.txt b/basis/unix/stat/netbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/stat/netbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/stat/openbsd/platforms.txt b/basis/unix/stat/openbsd/platforms.txt
new file mode 100644
index 0000000000..389b028aca
--- /dev/null
+++ b/basis/unix/stat/openbsd/platforms.txt
@@ -0,0 +1 @@
+openbsd
diff --git a/basis/unix/stat/openbsd/tags.txt b/basis/unix/stat/openbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/stat/openbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/stat/platforms.txt b/basis/unix/stat/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/unix/stat/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/unix/stat/tags.txt b/basis/unix/stat/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/stat/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statfs/freebsd/platforms.txt b/basis/unix/statfs/freebsd/platforms.txt
new file mode 100644
index 0000000000..edfe86017d
--- /dev/null
+++ b/basis/unix/statfs/freebsd/platforms.txt
@@ -0,0 +1 @@
+freebsd
diff --git a/basis/unix/statfs/freebsd/tags.txt b/basis/unix/statfs/freebsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/statfs/freebsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statfs/linux/platforms.txt b/basis/unix/statfs/linux/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/unix/statfs/linux/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/unix/statfs/linux/tags.txt b/basis/unix/statfs/linux/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/statfs/linux/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statfs/macosx/platforms.txt b/basis/unix/statfs/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/unix/statfs/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/unix/statfs/macosx/tags.txt b/basis/unix/statfs/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/statfs/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statfs/openbsd/platforms.txt b/basis/unix/statfs/openbsd/platforms.txt
new file mode 100644
index 0000000000..389b028aca
--- /dev/null
+++ b/basis/unix/statfs/openbsd/platforms.txt
@@ -0,0 +1 @@
+openbsd
diff --git a/basis/unix/statfs/openbsd/tags.txt b/basis/unix/statfs/openbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/statfs/openbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statvfs/freebsd/platforms.txt b/basis/unix/statvfs/freebsd/platforms.txt
new file mode 100644
index 0000000000..edfe86017d
--- /dev/null
+++ b/basis/unix/statvfs/freebsd/platforms.txt
@@ -0,0 +1 @@
+freebsd
diff --git a/basis/unix/statvfs/freebsd/tags.txt b/basis/unix/statvfs/freebsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/statvfs/freebsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statvfs/linux/platforms.txt b/basis/unix/statvfs/linux/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/unix/statvfs/linux/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/unix/statvfs/linux/tags.txt b/basis/unix/statvfs/linux/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/statvfs/linux/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statvfs/macosx/platforms.txt b/basis/unix/statvfs/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/unix/statvfs/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/unix/statvfs/macosx/tags.txt b/basis/unix/statvfs/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/statvfs/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statvfs/netbsd/platforms.txt b/basis/unix/statvfs/netbsd/platforms.txt
new file mode 100644
index 0000000000..dccfe71042
--- /dev/null
+++ b/basis/unix/statvfs/netbsd/platforms.txt
@@ -0,0 +1 @@
+netbsd
diff --git a/basis/unix/statvfs/netbsd/tags.txt b/basis/unix/statvfs/netbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/statvfs/netbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statvfs/openbsd/platforms.txt b/basis/unix/statvfs/openbsd/platforms.txt
new file mode 100644
index 0000000000..389b028aca
--- /dev/null
+++ b/basis/unix/statvfs/openbsd/platforms.txt
@@ -0,0 +1 @@
+openbsd
diff --git a/basis/unix/statvfs/openbsd/tags.txt b/basis/unix/statvfs/openbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/statvfs/openbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/statvfs/platforms.txt b/basis/unix/statvfs/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/unix/statvfs/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/unix/statvfs/tags.txt b/basis/unix/statvfs/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/statvfs/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/tags.txt b/basis/unix/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/unix/tags.txt
+++ b/basis/unix/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/unix/time/platforms.txt b/basis/unix/time/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/unix/time/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/unix/time/tags.txt b/basis/unix/time/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/time/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/types/freebsd/platforms.txt b/basis/unix/types/freebsd/platforms.txt
new file mode 100644
index 0000000000..edfe86017d
--- /dev/null
+++ b/basis/unix/types/freebsd/platforms.txt
@@ -0,0 +1 @@
+freebsd
diff --git a/basis/unix/types/freebsd/tags.txt b/basis/unix/types/freebsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/types/freebsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/types/linux/platforms.txt b/basis/unix/types/linux/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/basis/unix/types/linux/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/basis/unix/types/linux/tags.txt b/basis/unix/types/linux/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/types/linux/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/types/macosx/platforms.txt b/basis/unix/types/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/unix/types/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/unix/types/macosx/tags.txt b/basis/unix/types/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/types/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/types/netbsd/32/tags.txt b/basis/unix/types/netbsd/32/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/unix/types/netbsd/32/tags.txt
+++ b/basis/unix/types/netbsd/32/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/unix/types/netbsd/64/tags.txt b/basis/unix/types/netbsd/64/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/basis/unix/types/netbsd/64/tags.txt
+++ b/basis/unix/types/netbsd/64/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/basis/unix/types/netbsd/platforms.txt b/basis/unix/types/netbsd/platforms.txt
new file mode 100644
index 0000000000..dccfe71042
--- /dev/null
+++ b/basis/unix/types/netbsd/platforms.txt
@@ -0,0 +1 @@
+netbsd
diff --git a/basis/unix/types/netbsd/tags.txt b/basis/unix/types/netbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/types/netbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/types/openbsd/platforms.txt b/basis/unix/types/openbsd/platforms.txt
new file mode 100644
index 0000000000..389b028aca
--- /dev/null
+++ b/basis/unix/types/openbsd/platforms.txt
@@ -0,0 +1 @@
+openbsd
diff --git a/basis/unix/types/openbsd/tags.txt b/basis/unix/types/openbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/types/openbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/types/platforms.txt b/basis/unix/types/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/unix/types/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/unix/types/tags.txt b/basis/unix/types/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/types/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/users/bsd/platforms.txt b/basis/unix/users/bsd/platforms.txt
new file mode 100644
index 0000000000..df796f15d4
--- /dev/null
+++ b/basis/unix/users/bsd/platforms.txt
@@ -0,0 +1 @@
+bsd
diff --git a/basis/unix/users/bsd/tags.txt b/basis/unix/users/bsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/users/bsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/users/platforms.txt b/basis/unix/users/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/unix/users/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/unix/users/tags.txt b/basis/unix/users/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/users/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/utilities/platforms.txt b/basis/unix/utilities/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/unix/utilities/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/unix/utilities/tags.txt b/basis/unix/utilities/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/utilities/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/utmpx/macosx/platforms.txt b/basis/unix/utmpx/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/basis/unix/utmpx/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/basis/unix/utmpx/macosx/tags.txt b/basis/unix/utmpx/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/utmpx/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/utmpx/netbsd/platforms.txt b/basis/unix/utmpx/netbsd/platforms.txt
new file mode 100644
index 0000000000..dccfe71042
--- /dev/null
+++ b/basis/unix/utmpx/netbsd/platforms.txt
@@ -0,0 +1 @@
+netbsd
diff --git a/basis/unix/utmpx/netbsd/tags.txt b/basis/unix/utmpx/netbsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/utmpx/netbsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/unix/utmpx/platforms.txt b/basis/unix/utmpx/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/unix/utmpx/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/unix/utmpx/tags.txt b/basis/unix/utmpx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/unix/utmpx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/vocabs/metadata/authors.txt b/basis/vocabs/metadata/authors.txt
index d4f5d6b3ae..1ad6ff84f7 100644
--- a/basis/vocabs/metadata/authors.txt
+++ b/basis/vocabs/metadata/authors.txt
@@ -1 +1,2 @@
-Slava Pestov
\ No newline at end of file
+Slava Pestov
+Joe Groff
\ No newline at end of file
diff --git a/basis/vocabs/metadata/metadata.factor b/basis/vocabs/metadata/metadata.factor
index 04a0ea7546..10e4eac2a2 100644
--- a/basis/vocabs/metadata/metadata.factor
+++ b/basis/vocabs/metadata/metadata.factor
@@ -1,23 +1,26 @@
-! Copyright (C) 2009 Slava Pestov.
+! Copyright (C) 2009, 2010 Slava Pestov, Joe Groff.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays assocs io.encodings.utf8 io.files
-io.pathnames kernel make math.parser memoize sequences sets
-sorting summary vocabs vocabs.loader ;
+USING: accessors arrays assocs io.directories io.encodings.utf8
+io.files io.pathnames kernel make math.parser memoize sequences
+sets sorting summary vocabs vocabs.loader words system
+classes.algebra combinators.short-circuit fry continuations
+namespaces ;
 IN: vocabs.metadata
 
+: check-vocab ( vocab -- vocab )
+    dup find-vocab-root [ no-vocab ] unless ;
+
 MEMO: vocab-file-contents ( vocab name -- seq )
     vocab-append-path dup
     [ dup exists? [ utf8 file-lines ] [ drop f ] if ] when ;
 
+: ?delete-file ( pathname -- ) '[ _ delete-file ] ignore-errors ;
+
 : set-vocab-file-contents ( seq vocab name -- )
     dupd vocab-append-path [
-        utf8 set-file-lines
+        swap [ ?delete-file ] [ swap utf8 set-file-lines ] if-empty
         \ vocab-file-contents reset-memoized
-    ] [
-        "The " swap vocab-name
-        " vocabulary was not loaded from the file system"
-        3append throw
-    ] ?if ;
+    ] [ vocab-name no-vocab ] ?if ;
 
 : vocab-windows-icon-path ( vocab -- string )
     vocab-dir "icon.ico" append-path ;
@@ -72,6 +75,9 @@ M: vocab-link summary vocab-summary ;
 : add-vocab-tags ( tags vocab -- )
     [ vocab-tags append prune ] keep set-vocab-tags ;
 
+: remove-vocab-tags ( tags vocab -- )
+    [ vocab-tags swap diff ] keep set-vocab-tags ;
+
 : vocab-authors-path ( vocab -- string )
     vocab-dir "authors.txt" append-path ;
 
@@ -81,5 +87,32 @@ M: vocab-link summary vocab-summary ;
 : set-vocab-authors ( authors vocab -- )
     dup vocab-authors-path set-vocab-file-contents ;
 
+: vocab-platforms-path ( vocab -- string )
+    vocab-dir "platforms.txt" append-path ;
+
+ERROR: bad-platform name ;
+
+: vocab-platforms ( vocab -- platforms )
+    dup vocab-platforms-path vocab-file-contents
+    [ dup "system" lookup [ ] [ bad-platform ] ?if ] map ;
+
+: set-vocab-platforms ( platforms vocab -- )
+    [ [ name>> ] map ] dip
+    dup vocab-platforms-path set-vocab-file-contents ;
+
+: supported-platform? ( vocab -- ? )
+    vocab-platforms [ t ] [ [ os swap class<= ] any? ] if-empty ;
+
 : unportable? ( vocab -- ? )
-    vocab-tags "unportable" swap member? ;
+    {
+        [ vocab-tags "untested" swap member? ]
+        [ supported-platform? not ]
+    } 1|| ;
+
+ERROR: unsupported-platform vocab ;
+
+M: unsupported-platform summary
+    drop "Current operating system not supported by this vocabulary" ;
+
+[ dup supported-platform? [ drop ] [ vocab-name unsupported-platform ] if ]
+check-vocab-hook set-global
diff --git a/basis/windows/advapi32/platforms.txt b/basis/windows/advapi32/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/advapi32/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/advapi32/tags.txt b/basis/windows/advapi32/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/advapi32/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/ce/platforms.txt b/basis/windows/ce/platforms.txt
new file mode 100644
index 0000000000..cd0d980f6f
--- /dev/null
+++ b/basis/windows/ce/platforms.txt
@@ -0,0 +1 @@
+wince
diff --git a/basis/windows/ce/tags.txt b/basis/windows/ce/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/ce/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/com/platforms.txt b/basis/windows/com/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/com/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/com/prettyprint/platforms.txt b/basis/windows/com/prettyprint/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/com/prettyprint/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/com/prettyprint/tags.txt b/basis/windows/com/prettyprint/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/com/prettyprint/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/com/syntax/platforms.txt b/basis/windows/com/syntax/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/com/syntax/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/com/syntax/tags.txt b/basis/windows/com/syntax/tags.txt
index 2320bdd648..bb863cf9a0 100755
--- a/basis/windows/com/syntax/tags.txt
+++ b/basis/windows/com/syntax/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/com/tags.txt b/basis/windows/com/tags.txt
index 86dd9eeb91..40fc52b29b 100755
--- a/basis/windows/com/tags.txt
+++ b/basis/windows/com/tags.txt
@@ -1,3 +1,2 @@
-unportable
 bindings
 ffi
diff --git a/basis/windows/com/wrapper/platforms.txt b/basis/windows/com/wrapper/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/com/wrapper/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/com/wrapper/tags.txt b/basis/windows/com/wrapper/tags.txt
index 2320bdd648..bb863cf9a0 100755
--- a/basis/windows/com/wrapper/tags.txt
+++ b/basis/windows/com/wrapper/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/audiodefs/platforms.txt b/basis/windows/directx/audiodefs/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/audiodefs/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/audiodefs/tags.txt b/basis/windows/directx/audiodefs/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/audiodefs/tags.txt
+++ b/basis/windows/directx/audiodefs/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d2d1/platforms.txt b/basis/windows/directx/d2d1/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d2d1/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d2d1/tags.txt b/basis/windows/directx/d2d1/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d2d1/tags.txt
+++ b/basis/windows/directx/d2d1/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d2dbasetypes/platforms.txt b/basis/windows/directx/d2dbasetypes/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d2dbasetypes/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d2dbasetypes/tags.txt b/basis/windows/directx/d2dbasetypes/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d2dbasetypes/tags.txt
+++ b/basis/windows/directx/d2dbasetypes/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d2derr/platforms.txt b/basis/windows/directx/d2derr/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d2derr/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d2derr/tags.txt b/basis/windows/directx/d2derr/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d2derr/tags.txt
+++ b/basis/windows/directx/d2derr/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3d10/platforms.txt b/basis/windows/directx/d3d10/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3d10/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3d10/tags.txt b/basis/windows/directx/d3d10/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3d10/tags.txt
+++ b/basis/windows/directx/d3d10/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3d10_1/platforms.txt b/basis/windows/directx/d3d10_1/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3d10_1/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3d10_1/tags.txt b/basis/windows/directx/d3d10_1/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3d10_1/tags.txt
+++ b/basis/windows/directx/d3d10_1/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3d10_1shader/platforms.txt b/basis/windows/directx/d3d10_1shader/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3d10_1shader/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3d10_1shader/tags.txt b/basis/windows/directx/d3d10_1shader/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3d10_1shader/tags.txt
+++ b/basis/windows/directx/d3d10_1shader/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3d10effect/platforms.txt b/basis/windows/directx/d3d10effect/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3d10effect/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3d10effect/tags.txt b/basis/windows/directx/d3d10effect/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3d10effect/tags.txt
+++ b/basis/windows/directx/d3d10effect/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3d10misc/platforms.txt b/basis/windows/directx/d3d10misc/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3d10misc/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3d10misc/tags.txt b/basis/windows/directx/d3d10misc/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3d10misc/tags.txt
+++ b/basis/windows/directx/d3d10misc/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3d10shader/platforms.txt b/basis/windows/directx/d3d10shader/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3d10shader/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3d10shader/tags.txt b/basis/windows/directx/d3d10shader/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3d10shader/tags.txt
+++ b/basis/windows/directx/d3d10shader/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3d11/platforms.txt b/basis/windows/directx/d3d11/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3d11/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3d11/tags.txt b/basis/windows/directx/d3d11/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3d11/tags.txt
+++ b/basis/windows/directx/d3d11/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3d11shader/platforms.txt b/basis/windows/directx/d3d11shader/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3d11shader/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3d11shader/tags.txt b/basis/windows/directx/d3d11shader/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3d11shader/tags.txt
+++ b/basis/windows/directx/d3d11shader/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3d9/platforms.txt b/basis/windows/directx/d3d9/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3d9/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3d9/tags.txt b/basis/windows/directx/d3d9/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3d9/tags.txt
+++ b/basis/windows/directx/d3d9/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3d9caps/platforms.txt b/basis/windows/directx/d3d9caps/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3d9caps/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3d9caps/tags.txt b/basis/windows/directx/d3d9caps/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3d9caps/tags.txt
+++ b/basis/windows/directx/d3d9caps/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3d9types/platforms.txt b/basis/windows/directx/d3d9types/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3d9types/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3d9types/tags.txt b/basis/windows/directx/d3d9types/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3d9types/tags.txt
+++ b/basis/windows/directx/d3d9types/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dcommon/platforms.txt b/basis/windows/directx/d3dcommon/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dcommon/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dcommon/tags.txt b/basis/windows/directx/d3dcommon/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dcommon/tags.txt
+++ b/basis/windows/directx/d3dcommon/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dcompiler/platforms.txt b/basis/windows/directx/d3dcompiler/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dcompiler/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dcompiler/tags.txt b/basis/windows/directx/d3dcompiler/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dcompiler/tags.txt
+++ b/basis/windows/directx/d3dcompiler/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dcsx/platforms.txt b/basis/windows/directx/d3dcsx/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dcsx/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dcsx/tags.txt b/basis/windows/directx/d3dcsx/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dcsx/tags.txt
+++ b/basis/windows/directx/d3dcsx/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx10/platforms.txt b/basis/windows/directx/d3dx10/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx10/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx10/tags.txt b/basis/windows/directx/d3dx10/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx10/tags.txt
+++ b/basis/windows/directx/d3dx10/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx10async/platforms.txt b/basis/windows/directx/d3dx10async/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx10async/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx10async/tags.txt b/basis/windows/directx/d3dx10async/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx10async/tags.txt
+++ b/basis/windows/directx/d3dx10async/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx10core/platforms.txt b/basis/windows/directx/d3dx10core/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx10core/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx10core/tags.txt b/basis/windows/directx/d3dx10core/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx10core/tags.txt
+++ b/basis/windows/directx/d3dx10core/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx10math/platforms.txt b/basis/windows/directx/d3dx10math/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx10math/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx10math/tags.txt b/basis/windows/directx/d3dx10math/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx10math/tags.txt
+++ b/basis/windows/directx/d3dx10math/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx10mesh/platforms.txt b/basis/windows/directx/d3dx10mesh/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx10mesh/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx10mesh/tags.txt b/basis/windows/directx/d3dx10mesh/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx10mesh/tags.txt
+++ b/basis/windows/directx/d3dx10mesh/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx10tex/platforms.txt b/basis/windows/directx/d3dx10tex/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx10tex/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx10tex/tags.txt b/basis/windows/directx/d3dx10tex/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx10tex/tags.txt
+++ b/basis/windows/directx/d3dx10tex/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx11/platforms.txt b/basis/windows/directx/d3dx11/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx11/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx11/tags.txt b/basis/windows/directx/d3dx11/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx11/tags.txt
+++ b/basis/windows/directx/d3dx11/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx11async/platforms.txt b/basis/windows/directx/d3dx11async/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx11async/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx11async/tags.txt b/basis/windows/directx/d3dx11async/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx11async/tags.txt
+++ b/basis/windows/directx/d3dx11async/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx11core/platforms.txt b/basis/windows/directx/d3dx11core/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx11core/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx11core/tags.txt b/basis/windows/directx/d3dx11core/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx11core/tags.txt
+++ b/basis/windows/directx/d3dx11core/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx11tex/platforms.txt b/basis/windows/directx/d3dx11tex/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx11tex/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx11tex/tags.txt b/basis/windows/directx/d3dx11tex/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx11tex/tags.txt
+++ b/basis/windows/directx/d3dx11tex/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx9/platforms.txt b/basis/windows/directx/d3dx9/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx9/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx9/tags.txt b/basis/windows/directx/d3dx9/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx9/tags.txt
+++ b/basis/windows/directx/d3dx9/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx9anim/platforms.txt b/basis/windows/directx/d3dx9anim/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx9anim/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx9anim/tags.txt b/basis/windows/directx/d3dx9anim/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx9anim/tags.txt
+++ b/basis/windows/directx/d3dx9anim/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx9core/platforms.txt b/basis/windows/directx/d3dx9core/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx9core/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx9core/tags.txt b/basis/windows/directx/d3dx9core/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx9core/tags.txt
+++ b/basis/windows/directx/d3dx9core/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx9effect/platforms.txt b/basis/windows/directx/d3dx9effect/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx9effect/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx9effect/tags.txt b/basis/windows/directx/d3dx9effect/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx9effect/tags.txt
+++ b/basis/windows/directx/d3dx9effect/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx9math/platforms.txt b/basis/windows/directx/d3dx9math/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx9math/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx9math/tags.txt b/basis/windows/directx/d3dx9math/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx9math/tags.txt
+++ b/basis/windows/directx/d3dx9math/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx9mesh/platforms.txt b/basis/windows/directx/d3dx9mesh/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx9mesh/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx9mesh/tags.txt b/basis/windows/directx/d3dx9mesh/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx9mesh/tags.txt
+++ b/basis/windows/directx/d3dx9mesh/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx9shader/platforms.txt b/basis/windows/directx/d3dx9shader/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx9shader/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx9shader/tags.txt b/basis/windows/directx/d3dx9shader/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx9shader/tags.txt
+++ b/basis/windows/directx/d3dx9shader/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx9shape/platforms.txt b/basis/windows/directx/d3dx9shape/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx9shape/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx9shape/tags.txt b/basis/windows/directx/d3dx9shape/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx9shape/tags.txt
+++ b/basis/windows/directx/d3dx9shape/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx9tex/platforms.txt b/basis/windows/directx/d3dx9tex/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx9tex/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx9tex/tags.txt b/basis/windows/directx/d3dx9tex/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx9tex/tags.txt
+++ b/basis/windows/directx/d3dx9tex/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/d3dx9xof/platforms.txt b/basis/windows/directx/d3dx9xof/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/d3dx9xof/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/d3dx9xof/tags.txt b/basis/windows/directx/d3dx9xof/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/d3dx9xof/tags.txt
+++ b/basis/windows/directx/d3dx9xof/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/dcommon/platforms.txt b/basis/windows/directx/dcommon/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/dcommon/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/dcommon/tags.txt b/basis/windows/directx/dcommon/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/dcommon/tags.txt
+++ b/basis/windows/directx/dcommon/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/dinput/constants/platforms.txt b/basis/windows/directx/dinput/constants/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/dinput/constants/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/dinput/constants/tags.txt b/basis/windows/directx/dinput/constants/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/directx/dinput/constants/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/directx/dinput/platforms.txt b/basis/windows/directx/dinput/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/dinput/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/dinput/tags.txt b/basis/windows/directx/dinput/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/dinput/tags.txt
+++ b/basis/windows/directx/dinput/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/dwrite/platforms.txt b/basis/windows/directx/dwrite/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/dwrite/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/dwrite/tags.txt b/basis/windows/directx/dwrite/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/dwrite/tags.txt
+++ b/basis/windows/directx/dwrite/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/dxfile/platforms.txt b/basis/windows/directx/dxfile/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/dxfile/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/dxfile/tags.txt b/basis/windows/directx/dxfile/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/dxfile/tags.txt
+++ b/basis/windows/directx/dxfile/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/dxgi/platforms.txt b/basis/windows/directx/dxgi/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/dxgi/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/dxgi/tags.txt b/basis/windows/directx/dxgi/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/dxgi/tags.txt
+++ b/basis/windows/directx/dxgi/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/dxgiformat/platforms.txt b/basis/windows/directx/dxgiformat/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/dxgiformat/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/dxgiformat/tags.txt b/basis/windows/directx/dxgiformat/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/dxgiformat/tags.txt
+++ b/basis/windows/directx/dxgiformat/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/dxgitype/platforms.txt b/basis/windows/directx/dxgitype/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/dxgitype/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/dxgitype/tags.txt b/basis/windows/directx/dxgitype/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/dxgitype/tags.txt
+++ b/basis/windows/directx/dxgitype/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/x3daudio/platforms.txt b/basis/windows/directx/x3daudio/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/x3daudio/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/x3daudio/tags.txt b/basis/windows/directx/x3daudio/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/x3daudio/tags.txt
+++ b/basis/windows/directx/x3daudio/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/xact3/platforms.txt b/basis/windows/directx/xact3/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/xact3/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/xact3/tags.txt b/basis/windows/directx/xact3/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/xact3/tags.txt
+++ b/basis/windows/directx/xact3/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/xapo/platforms.txt b/basis/windows/directx/xapo/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/xapo/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/xapo/tags.txt b/basis/windows/directx/xapo/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/xapo/tags.txt
+++ b/basis/windows/directx/xapo/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/xapofx/platforms.txt b/basis/windows/directx/xapofx/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/xapofx/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/xapofx/tags.txt b/basis/windows/directx/xapofx/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/xapofx/tags.txt
+++ b/basis/windows/directx/xapofx/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/xaudio2/platforms.txt b/basis/windows/directx/xaudio2/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/xaudio2/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/xaudio2/tags.txt b/basis/windows/directx/xaudio2/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/xaudio2/tags.txt
+++ b/basis/windows/directx/xaudio2/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/xaudio2fx/platforms.txt b/basis/windows/directx/xaudio2fx/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/xaudio2fx/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/xaudio2fx/tags.txt b/basis/windows/directx/xaudio2fx/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/xaudio2fx/tags.txt
+++ b/basis/windows/directx/xaudio2fx/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/directx/xinput/platforms.txt b/basis/windows/directx/xinput/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/directx/xinput/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/directx/xinput/tags.txt b/basis/windows/directx/xinput/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/directx/xinput/tags.txt
+++ b/basis/windows/directx/xinput/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/dragdrop-listener/platforms.txt b/basis/windows/dragdrop-listener/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/dragdrop-listener/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/dragdrop-listener/tags.txt b/basis/windows/dragdrop-listener/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/dragdrop-listener/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/dwmapi/platforms.txt b/basis/windows/dwmapi/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/dwmapi/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/dwmapi/tags.txt b/basis/windows/dwmapi/tags.txt
index 43bc035447..8e1a55995e 100755
--- a/basis/windows/dwmapi/tags.txt
+++ b/basis/windows/dwmapi/tags.txt
@@ -1,2 +1 @@
 windows
-unportable
diff --git a/basis/windows/errors/platforms.txt b/basis/windows/errors/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/errors/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/errors/tags.txt b/basis/windows/errors/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/errors/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/fonts/platforms.txt b/basis/windows/fonts/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/fonts/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/fonts/tags.txt b/basis/windows/fonts/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/fonts/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/gdi32/platforms.txt b/basis/windows/gdi32/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/gdi32/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/gdi32/tags.txt b/basis/windows/gdi32/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/gdi32/tags.txt
+++ b/basis/windows/gdi32/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/kernel32/platforms.txt b/basis/windows/kernel32/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/kernel32/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/kernel32/tags.txt b/basis/windows/kernel32/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/kernel32/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/messages/platforms.txt b/basis/windows/messages/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/messages/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/messages/tags.txt b/basis/windows/messages/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/messages/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/nt/platforms.txt b/basis/windows/nt/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/nt/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/nt/tags.txt b/basis/windows/nt/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/nt/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/offscreen/platforms.txt b/basis/windows/offscreen/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/offscreen/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/offscreen/tags.txt b/basis/windows/offscreen/tags.txt
deleted file mode 100755
index 6abe115b12..0000000000
--- a/basis/windows/offscreen/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/ole32/platforms.txt b/basis/windows/ole32/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/ole32/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/ole32/tags.txt b/basis/windows/ole32/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/ole32/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/opengl32/platforms.txt b/basis/windows/opengl32/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/opengl32/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/opengl32/tags.txt b/basis/windows/opengl32/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/opengl32/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/platforms.txt b/basis/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/psapi/platforms.txt b/basis/windows/psapi/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/psapi/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/psapi/tags.txt b/basis/windows/psapi/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/psapi/tags.txt
+++ b/basis/windows/psapi/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/shell32/platforms.txt b/basis/windows/shell32/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/shell32/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/shell32/tags.txt b/basis/windows/shell32/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/shell32/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/tags.txt b/basis/windows/tags.txt
index 2320bdd648..bb863cf9a0 100755
--- a/basis/windows/tags.txt
+++ b/basis/windows/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/time/platforms.txt b/basis/windows/time/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/time/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/time/tags.txt b/basis/windows/time/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/time/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/types/platforms.txt b/basis/windows/types/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/types/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/types/tags.txt b/basis/windows/types/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/types/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/uniscribe/platforms.txt b/basis/windows/uniscribe/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/uniscribe/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/uniscribe/tags.txt b/basis/windows/uniscribe/tags.txt
deleted file mode 100755
index 6abe115b12..0000000000
--- a/basis/windows/uniscribe/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/user32/platforms.txt b/basis/windows/user32/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/user32/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/user32/tags.txt b/basis/windows/user32/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/user32/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/windows/usp10/platforms.txt b/basis/windows/usp10/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/usp10/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/usp10/tags.txt b/basis/windows/usp10/tags.txt
index 2320bdd648..bb863cf9a0 100644
--- a/basis/windows/usp10/tags.txt
+++ b/basis/windows/usp10/tags.txt
@@ -1,2 +1 @@
-unportable
 bindings
diff --git a/basis/windows/winsock/platforms.txt b/basis/windows/winsock/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/basis/windows/winsock/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/basis/windows/winsock/tags.txt b/basis/windows/winsock/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/windows/winsock/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/x11/io/unix/platforms.txt b/basis/x11/io/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/x11/io/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/x11/io/unix/tags.txt b/basis/x11/io/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/x11/io/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/basis/x11/windows/platforms.txt b/basis/x11/windows/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/basis/x11/windows/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/basis/x11/windows/tags.txt b/basis/x11/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/basis/x11/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/core/vocabs/loader/loader.factor b/core/vocabs/loader/loader.factor
index 2c0f67641d..67d7d7677d 100644
--- a/core/vocabs/loader/loader.factor
+++ b/core/vocabs/loader/loader.factor
@@ -99,6 +99,11 @@ PRIVATE>
 
 SYMBOL: blacklist
 
+! Defined by vocabs.metadata
+SYMBOL: check-vocab-hook
+
+check-vocab-hook [ [ drop ] ] initialize
+
 <PRIVATE
 
 : add-to-blacklist ( error vocab -- )
@@ -115,10 +120,12 @@ M: vocab (load-vocab)
     ] [ [ swap add-to-blacklist ] keep rethrow ] recover ;
 
 M: vocab-link (load-vocab)
-    vocab-name create-vocab (load-vocab) ;
+    vocab-name (load-vocab) ;
 
 M: string (load-vocab)
-    create-vocab (load-vocab) ;
+    [ check-vocab-hook get call( vocab -- ) ]
+    [ create-vocab (load-vocab) ]
+    bi ;
 
 PRIVATE>
 
diff --git a/core/vocabs/loader/test/a/a.factor b/core/vocabs/loader/test/a/a.factor
index 03a2f8a091..18ed045936 100644
--- a/core/vocabs/loader/test/a/a.factor
+++ b/core/vocabs/loader/test/a/a.factor
@@ -3,7 +3,7 @@ IN: vocabs.loader.test.a
 
 << global [ "count-me" inc ] bind >>
 
-: v-l-t-a-hello 4 ;
+: v-l-t-a-hello ( -- a ) 4 ;
 
 : byebye v-l-t-a-hello ;
 
diff --git a/core/vocabs/loader/test/a/tags.txt b/core/vocabs/loader/test/a/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/core/vocabs/loader/test/a/tags.txt
+++ b/core/vocabs/loader/test/a/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/core/vocabs/loader/test/b/tags.txt b/core/vocabs/loader/test/b/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/core/vocabs/loader/test/b/tags.txt
+++ b/core/vocabs/loader/test/b/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/core/vocabs/loader/test/c/tags.txt b/core/vocabs/loader/test/c/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/core/vocabs/loader/test/c/tags.txt
+++ b/core/vocabs/loader/test/c/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/core/vocabs/loader/test/d/tags.txt b/core/vocabs/loader/test/d/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/core/vocabs/loader/test/d/tags.txt
+++ b/core/vocabs/loader/test/d/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/core/vocabs/loader/test/e/tags.txt b/core/vocabs/loader/test/e/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/core/vocabs/loader/test/e/tags.txt
+++ b/core/vocabs/loader/test/e/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/core/vocabs/loader/test/f/tags.txt b/core/vocabs/loader/test/f/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/core/vocabs/loader/test/f/tags.txt
+++ b/core/vocabs/loader/test/f/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/core/vocabs/loader/test/g/tags.txt b/core/vocabs/loader/test/g/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/core/vocabs/loader/test/g/tags.txt
+++ b/core/vocabs/loader/test/g/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/core/vocabs/loader/test/h/tags.txt b/core/vocabs/loader/test/h/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/core/vocabs/loader/test/h/tags.txt
+++ b/core/vocabs/loader/test/h/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/core/vocabs/loader/test/i/tags.txt b/core/vocabs/loader/test/i/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/core/vocabs/loader/test/i/tags.txt
+++ b/core/vocabs/loader/test/i/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/core/vocabs/loader/test/j/tags.txt b/core/vocabs/loader/test/j/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/core/vocabs/loader/test/j/tags.txt
+++ b/core/vocabs/loader/test/j/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/core/vocabs/loader/test/k/tags.txt b/core/vocabs/loader/test/k/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/core/vocabs/loader/test/k/tags.txt
+++ b/core/vocabs/loader/test/k/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/core/vocabs/loader/test/l/tags.txt b/core/vocabs/loader/test/l/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/core/vocabs/loader/test/l/tags.txt
+++ b/core/vocabs/loader/test/l/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/extra/couchdb/tags.txt b/extra/couchdb/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/extra/couchdb/tags.txt
+++ b/extra/couchdb/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/extra/curses/ffi/platforms.txt b/extra/curses/ffi/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/extra/curses/ffi/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/extra/curses/ffi/tags.txt b/extra/curses/ffi/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/extra/curses/ffi/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/extra/curses/platforms.txt b/extra/curses/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/extra/curses/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/extra/curses/tags.txt b/extra/curses/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/extra/curses/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/extra/ecdsa/tags.txt b/extra/ecdsa/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/extra/ecdsa/tags.txt
+++ b/extra/ecdsa/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/extra/io/serial/tags.txt b/extra/io/serial/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/extra/io/serial/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/extra/io/serial/unix/bsd/platforms.txt b/extra/io/serial/unix/bsd/platforms.txt
new file mode 100644
index 0000000000..df796f15d4
--- /dev/null
+++ b/extra/io/serial/unix/bsd/platforms.txt
@@ -0,0 +1 @@
+bsd
diff --git a/extra/io/serial/unix/bsd/tags.txt b/extra/io/serial/unix/bsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/extra/io/serial/unix/bsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/extra/io/serial/unix/linux/platforms.txt b/extra/io/serial/unix/linux/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/extra/io/serial/unix/linux/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/extra/io/serial/unix/linux/tags.txt b/extra/io/serial/unix/linux/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/extra/io/serial/unix/linux/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/extra/io/serial/unix/platforms.txt b/extra/io/serial/unix/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/extra/io/serial/unix/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/extra/io/serial/unix/tags.txt b/extra/io/serial/unix/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/extra/io/serial/unix/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/extra/io/serial/unix/termios/bsd/platforms.txt b/extra/io/serial/unix/termios/bsd/platforms.txt
new file mode 100644
index 0000000000..df796f15d4
--- /dev/null
+++ b/extra/io/serial/unix/termios/bsd/platforms.txt
@@ -0,0 +1 @@
+bsd
diff --git a/extra/io/serial/unix/termios/bsd/tags.txt b/extra/io/serial/unix/termios/bsd/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/extra/io/serial/unix/termios/bsd/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/extra/io/serial/unix/termios/linux/platforms.txt b/extra/io/serial/unix/termios/linux/platforms.txt
new file mode 100644
index 0000000000..a08e1f35eb
--- /dev/null
+++ b/extra/io/serial/unix/termios/linux/platforms.txt
@@ -0,0 +1 @@
+linux
diff --git a/extra/io/serial/unix/termios/linux/tags.txt b/extra/io/serial/unix/termios/linux/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/extra/io/serial/unix/termios/linux/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/extra/io/serial/unix/termios/platforms.txt b/extra/io/serial/unix/termios/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/extra/io/serial/unix/termios/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/extra/io/serial/unix/termios/tags.txt b/extra/io/serial/unix/termios/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/extra/io/serial/unix/termios/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/extra/io/serial/windows/platforms.txt b/extra/io/serial/windows/platforms.txt
new file mode 100644
index 0000000000..8e1a55995e
--- /dev/null
+++ b/extra/io/serial/windows/platforms.txt
@@ -0,0 +1 @@
+windows
diff --git a/extra/io/serial/windows/tags.txt b/extra/io/serial/windows/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/extra/io/serial/windows/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/extra/libusb/platforms.txt b/extra/libusb/platforms.txt
new file mode 100644
index 0000000000..509143d863
--- /dev/null
+++ b/extra/libusb/platforms.txt
@@ -0,0 +1 @@
+unix
diff --git a/extra/libusb/tags.txt b/extra/libusb/tags.txt
index bf2a35f15b..bb863cf9a0 100644
--- a/extra/libusb/tags.txt
+++ b/extra/libusb/tags.txt
@@ -1,2 +1 @@
 bindings
-unportable
diff --git a/extra/llvm/core/tags.txt b/extra/llvm/core/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/extra/llvm/core/tags.txt
+++ b/extra/llvm/core/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/extra/llvm/engine/tags.txt b/extra/llvm/engine/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/extra/llvm/engine/tags.txt
+++ b/extra/llvm/engine/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/extra/llvm/invoker/tags.txt b/extra/llvm/invoker/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/extra/llvm/invoker/tags.txt
+++ b/extra/llvm/invoker/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/extra/llvm/jit/tags.txt b/extra/llvm/jit/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/extra/llvm/jit/tags.txt
+++ b/extra/llvm/jit/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/extra/llvm/reader/tags.txt b/extra/llvm/reader/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/extra/llvm/reader/tags.txt
+++ b/extra/llvm/reader/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/extra/llvm/tags.txt b/extra/llvm/tags.txt
index bf2a35f15b..a9d28becd8 100644
--- a/extra/llvm/tags.txt
+++ b/extra/llvm/tags.txt
@@ -1,2 +1,2 @@
 bindings
-unportable
+untested
diff --git a/extra/llvm/types/tags.txt b/extra/llvm/types/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/extra/llvm/types/tags.txt
+++ b/extra/llvm/types/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/extra/llvm/wrappers/tags.txt b/extra/llvm/wrappers/tags.txt
index 6bf68304bb..5d77766703 100644
--- a/extra/llvm/wrappers/tags.txt
+++ b/extra/llvm/wrappers/tags.txt
@@ -1 +1 @@
-unportable
+untested
diff --git a/extra/merger/platforms.txt b/extra/merger/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/extra/merger/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/extra/merger/tags.txt b/extra/merger/tags.txt
deleted file mode 100644
index c80b8b4fe1..0000000000
--- a/extra/merger/tags.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-unportable
-
diff --git a/extra/openal/alut/macosx/platforms.txt b/extra/openal/alut/macosx/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/extra/openal/alut/macosx/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/extra/openal/alut/macosx/tags.txt b/extra/openal/alut/macosx/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/extra/openal/alut/macosx/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/extra/qtkit/platforms.txt b/extra/qtkit/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/extra/qtkit/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/extra/qtkit/tags.txt b/extra/qtkit/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/extra/qtkit/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable
diff --git a/extra/webkit-demo/platforms.txt b/extra/webkit-demo/platforms.txt
new file mode 100644
index 0000000000..6e806f449e
--- /dev/null
+++ b/extra/webkit-demo/platforms.txt
@@ -0,0 +1 @@
+macosx
diff --git a/extra/webkit-demo/tags.txt b/extra/webkit-demo/tags.txt
deleted file mode 100644
index 6bf68304bb..0000000000
--- a/extra/webkit-demo/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-unportable

From c3f4bcb616140027d10326794ce5eb3aa4235785 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sat, 20 Feb 2010 13:31:09 +1300
Subject: [PATCH 108/250] Fix load errors exposed by platforms.txt change

---
 basis/cocoa/callbacks/callbacks.factor                  | 4 ++--
 basis/io/backend/unix/multiplexers/select/select.factor | 7 ++++---
 basis/unix/utmpx/macosx/macosx.factor                   | 2 +-
 basis/unix/utmpx/utmpx.factor                           | 6 ++++--
 extra/io/serial/unix/unix.factor                        | 4 ++--
 extra/qtkit/qtkit.factor                                | 5 +++--
 6 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/basis/cocoa/callbacks/callbacks.factor b/basis/cocoa/callbacks/callbacks.factor
index e1ec43f1dc..87b5f628a9 100644
--- a/basis/cocoa/callbacks/callbacks.factor
+++ b/basis/cocoa/callbacks/callbacks.factor
@@ -1,7 +1,7 @@
 ! Copyright (C) 2005, 2006 Kevin Reid.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: assocs kernel namespaces cocoa cocoa.classes
-cocoa.subclassing debugger ;
+USING: alien.c-types assocs kernel namespaces cocoa
+cocoa.classes cocoa.runtime cocoa.subclassing debugger ;
 IN: cocoa.callbacks
 
 SYMBOL: callbacks
diff --git a/basis/io/backend/unix/multiplexers/select/select.factor b/basis/io/backend/unix/multiplexers/select/select.factor
index f2d1a3a3b7..5a3dab4dcc 100644
--- a/basis/io/backend/unix/multiplexers/select/select.factor
+++ b/basis/io/backend/unix/multiplexers/select/select.factor
@@ -1,8 +1,9 @@
 ! Copyright (C) 2004, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types kernel bit-arrays sequences assocs unix
-math namespaces accessors math.order locals unix.time fry
-io.ports io.backend.unix io.backend.unix.multiplexers ;
+USING: alien.c-types kernel bit-arrays sequences assocs math
+namespaces accessors math.order locals fry io.ports
+io.backend.unix io.backend.unix.multiplexers unix unix.ffi
+unix.time ;
 IN: io.backend.unix.multiplexers.select
 
 TUPLE: select-mx < mx read-fdset write-fdset ;
diff --git a/basis/unix/utmpx/macosx/macosx.factor b/basis/unix/utmpx/macosx/macosx.factor
index 92a0d9e3a4..faae29ffa4 100644
--- a/basis/unix/utmpx/macosx/macosx.factor
+++ b/basis/unix/utmpx/macosx/macosx.factor
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.syntax unix.bsd.macosx ;
+USING: alien.syntax unix.ffi.bsd.macosx ;
 IN: unix.utmpx.macosx
 
 ! empty
diff --git a/basis/unix/utmpx/utmpx.factor b/basis/unix/utmpx/utmpx.factor
index 6083776fc6..78556ab225 100644
--- a/basis/unix/utmpx/utmpx.factor
+++ b/basis/unix/utmpx/utmpx.factor
@@ -2,8 +2,8 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien.c-types alien.data alien.syntax combinators
 continuations io.encodings.string io.encodings.utf8 kernel
-sequences strings unix calendar system accessors unix.time
-calendar.unix vocabs.loader classes.struct ;
+sequences strings calendar system accessors unix unix.time
+unix.ffi calendar.unix vocabs.loader classes.struct ;
 IN: unix.utmpx
 
 CONSTANT: EMPTY 0
@@ -19,6 +19,8 @@ CONSTANT: ACCOUNTING 9
 CONSTANT: SIGNATURE 10
 CONSTANT: SHUTDOWN_TIME 11
 
+C-TYPE: utmpx
+
 FUNCTION: void setutxent ( ) ;
 FUNCTION: void endutxent ( ) ;
 FUNCTION: utmpx* getutxent ( ) ;
diff --git a/extra/io/serial/unix/unix.factor b/extra/io/serial/unix/unix.factor
index 8ee115ca45..6c0de55ec8 100644
--- a/extra/io/serial/unix/unix.factor
+++ b/extra/io/serial/unix/unix.factor
@@ -2,8 +2,8 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors alien.c-types alien.syntax alien.data 
 classes.struct combinators io.ports io.streams.duplex
-system kernel math math.bitwise vocabs.loader unix io.serial
-io.serial.unix.termios io.backend.unix ;
+system kernel math math.bitwise vocabs.loader io.serial
+io.serial.unix.termios io.backend.unix unix unix.ffi ;
 IN: io.serial.unix
 
 << {
diff --git a/extra/qtkit/qtkit.factor b/extra/qtkit/qtkit.factor
index b573cd51ab..919e0d2d29 100644
--- a/extra/qtkit/qtkit.factor
+++ b/extra/qtkit/qtkit.factor
@@ -1,5 +1,6 @@
-USING: classes.struct cocoa cocoa.application cocoa.classes
-cocoa.enumeration cocoa.plists core-foundation.strings kernel ;
+USING: alien.c-types classes.struct cocoa cocoa.application
+cocoa.classes cocoa.enumeration cocoa.plists core-foundation
+core-foundation.strings kernel ;
 IN: qtkit
 
 STRUCT: QTTime

From 1915b7e955787ea49a62f8dbe6acc7d7e241dcd5 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sat, 20 Feb 2010 13:31:51 +1300
Subject: [PATCH 109/250] vocabs.loader.test.a: fix

---
 core/vocabs/loader/test/a/a.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/vocabs/loader/test/a/a.factor b/core/vocabs/loader/test/a/a.factor
index 18ed045936..b1fa5aaed8 100644
--- a/core/vocabs/loader/test/a/a.factor
+++ b/core/vocabs/loader/test/a/a.factor
@@ -5,6 +5,6 @@ IN: vocabs.loader.test.a
 
 : v-l-t-a-hello ( -- a ) 4 ;
 
-: byebye v-l-t-a-hello ;
+: byebye ( -- a ) v-l-t-a-hello ;
 
 [ this is an error

From 6e516789d5c8f9072347c846fd1e8ea8cbd75924 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sat, 20 Feb 2010 13:41:33 +1300
Subject: [PATCH 110/250] continuations: add a throw-continue word for
 resumable errors, and change vocabs.metadata to throw a resumable error if
 the current platform is not supported

---
 basis/vocabs/metadata/metadata.factor        | 17 +++++++++++------
 core/compiler/units/units.factor             |  3 +--
 core/continuations/continuations-docs.factor | 12 ++++++++++--
 core/continuations/continuations.factor      |  3 +++
 4 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/basis/vocabs/metadata/metadata.factor b/basis/vocabs/metadata/metadata.factor
index 10e4eac2a2..09ca012fcc 100644
--- a/basis/vocabs/metadata/metadata.factor
+++ b/basis/vocabs/metadata/metadata.factor
@@ -100,19 +100,24 @@ ERROR: bad-platform name ;
     [ [ name>> ] map ] dip
     dup vocab-platforms-path set-vocab-file-contents ;
 
-: supported-platform? ( vocab -- ? )
-    vocab-platforms [ t ] [ [ os swap class<= ] any? ] if-empty ;
+: supported-platform? ( platforms -- ? )
+    [ t ] [ [ os swap class<= ] any? ] if-empty ;
 
 : unportable? ( vocab -- ? )
     {
         [ vocab-tags "untested" swap member? ]
-        [ supported-platform? not ]
+        [ vocab-platforms supported-platform? not ]
     } 1|| ;
 
-ERROR: unsupported-platform vocab ;
+TUPLE: unsupported-platform vocab requires ;
+
+: unsupported-platform ( vocab requires -- )
+    \ unsupported-platform boa throw-continue ;
 
 M: unsupported-platform summary
     drop "Current operating system not supported by this vocabulary" ;
 
-[ dup supported-platform? [ drop ] [ vocab-name unsupported-platform ] if ]
-check-vocab-hook set-global
+[
+    dup vocab-platforms dup supported-platform?
+    [ 2drop ] [ [ vocab-name ] dip unsupported-platform ] if
+] check-vocab-hook set-global
diff --git a/core/compiler/units/units.factor b/core/compiler/units/units.factor
index 9582ebadb6..b024ed2c65 100644
--- a/core/compiler/units/units.factor
+++ b/core/compiler/units/units.factor
@@ -12,8 +12,7 @@ SYMBOL: new-definitions
 TUPLE: redefine-error def ;
 
 : redefine-error ( definition -- )
-    \ redefine-error boa
-    { { "Continue" t } } throw-restarts drop ;
+    \ redefine-error boa throw-continue ;
 
 <PRIVATE
 
diff --git a/core/continuations/continuations-docs.factor b/core/continuations/continuations-docs.factor
index 84da26a082..766a78c483 100644
--- a/core/continuations/continuations-docs.factor
+++ b/core/continuations/continuations-docs.factor
@@ -9,9 +9,13 @@ ARTICLE: "errors-restartable" "Restartable errors"
     throw-restarts
     rethrow-restarts
 }
+"A utility word using the above:"
+{ $subsections
+    throw-continue
+}
 "The list of restarts from the most recently-thrown error is stored in a global variable:"
 { $subsections restarts }
-"To invoke restarts, see " { $link "debugger" } "." ;
+"To invoke restarts, use " { $link "debugger" } "." ;
 
 ARTICLE: "errors-post-mortem" "Post-mortem error inspection"
 "The most recently thrown error, together with the continuation at that point, are stored in a pair of global variables:"
@@ -213,7 +217,11 @@ HELP: rethrow-restarts
 { $values { "error" object } { "restarts" "a sequence of " { $snippet "{ string object }" } " pairs" } { "restart" object } }
 { $description "Throws a restartable error using " { $link rethrow } ". Otherwise, this word is identical to " { $link throw-restarts } "." } ;
 
-{ throw rethrow throw-restarts rethrow-restarts } related-words
+{ throw rethrow throw-restarts rethrow-restarts throw-continue } related-words
+
+HELP: throw-continue
+{ $values { "error" object } }
+{ $description "Throws a resumable error. If the user elects to continue execution, this word returns normally." } ;
 
 HELP: compute-restarts
 { $values { "error" object } { "seq" "a sequence" } }
diff --git a/core/continuations/continuations.factor b/core/continuations/continuations.factor
index d63acae883..332354e302 100644
--- a/core/continuations/continuations.factor
+++ b/core/continuations/continuations.factor
@@ -149,6 +149,9 @@ C: <condition> condition ( error restarts cc -- condition )
 : rethrow-restarts ( error restarts -- restart )
     [ <condition> rethrow ] callcc1 2nip ;
 
+: throw-continue ( error -- )
+    { { "Continue" t } } throw-restarts drop ;
+
 TUPLE: restart name obj continuation ;
 
 C: <restart> restart

From 0f1aa770a193867e6f286f2b44b2f028c54c0f9e Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Sat, 20 Feb 2010 00:22:01 -0800
Subject: [PATCH 111/250] Merge up

---
 extra/openal/alut/alut.factor       | 206 ++++++++++++++--------------
 extra/openal/example/example.factor |  66 ++++-----
 2 files changed, 136 insertions(+), 136 deletions(-)

diff --git a/extra/openal/alut/alut.factor b/extra/openal/alut/alut.factor
index d1b8d2600d..9e37d9886c 100755
--- a/extra/openal/alut/alut.factor
+++ b/extra/openal/alut/alut.factor
@@ -1,103 +1,103 @@
-! Copyright (C) 2007 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-USING: kernel accessors arrays alien system combinators
-alien.syntax namespaces alien.c-types sequences vocabs.loader
-shuffle openal openal.alut.backend alien.libraries generalizations
-specialized-arrays alien.destructors ;
-FROM: alien.c-types => float short ;
-SPECIALIZED-ARRAY: uint
-IN: openal.alut
-
-<< "alut" {
-        { [ os windows? ]  [ "alut.dll" ] }
-        { [ os macosx? ] [
-            "/System/Library/Frameworks/OpenAL.framework/OpenAL"
-        ] }
-        { [ os unix?  ]  [ "libalut.so" ] }
-    } cond "cdecl" add-library >>
-
-<< os macosx? [ "alut" deploy-library ] unless >>
-
-LIBRARY: alut
-
-CONSTANT: ALUT_API_MAJOR_VERSION 1
-CONSTANT: ALUT_API_MINOR_VERSION 1
-CONSTANT: ALUT_ERROR_NO_ERROR 0
-CONSTANT: ALUT_ERROR_OUT_OF_MEMORY HEX: 200
-CONSTANT: ALUT_ERROR_INVALID_ENUM HEX: 201
-CONSTANT: ALUT_ERROR_INVALID_VALUE HEX: 202
-CONSTANT: ALUT_ERROR_INVALID_OPERATION HEX: 203
-CONSTANT: ALUT_ERROR_NO_CURRENT_CONTEXT HEX: 204
-CONSTANT: ALUT_ERROR_AL_ERROR_ON_ENTRY HEX: 205
-CONSTANT: ALUT_ERROR_ALC_ERROR_ON_ENTRY HEX: 206
-CONSTANT: ALUT_ERROR_OPEN_DEVICE HEX: 207
-CONSTANT: ALUT_ERROR_CLOSE_DEVICE HEX: 208
-CONSTANT: ALUT_ERROR_CREATE_CONTEXT HEX: 209
-CONSTANT: ALUT_ERROR_MAKE_CONTEXT_CURRENT HEX: 20A
-CONSTANT: ALUT_ERROR_DESTRY_CONTEXT HEX: 20B
-CONSTANT: ALUT_ERROR_GEN_BUFFERS HEX: 20C
-CONSTANT: ALUT_ERROR_BUFFER_DATA HEX: 20D
-CONSTANT: ALUT_ERROR_IO_ERROR HEX: 20E
-CONSTANT: ALUT_ERROR_UNSUPPORTED_FILE_TYPE HEX: 20F
-CONSTANT: ALUT_ERROR_UNSUPPORTED_FILE_SUBTYPE HEX: 210
-CONSTANT: ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA HEX: 211
-CONSTANT: ALUT_WAVEFORM_SINE HEX: 100
-CONSTANT: ALUT_WAVEFORM_SQUARE HEX: 101
-CONSTANT: ALUT_WAVEFORM_SAWTOOTH HEX: 102
-CONSTANT: ALUT_WAVEFORM_WHITENOISE HEX: 103
-CONSTANT: ALUT_WAVEFORM_IMPULSE HEX: 104
-CONSTANT: ALUT_LOADER_BUFFER HEX: 300
-CONSTANT: ALUT_LOADER_MEMORY HEX: 301
-
-FUNCTION: ALboolean alutInit ( int* argcp, char** argv ) ;
-FUNCTION: ALboolean alutInitWithoutContext ( int* argcp, char** argv ) ;
-FUNCTION: ALboolean alutExit ( ) ;
-FUNCTION: ALenum alutGetError ( ) ;
-FUNCTION: char* alutGetErrorString ( ALenum error ) ;
-FUNCTION: ALuint alutCreateBufferFromFile ( char* fileName ) ;
-FUNCTION: ALuint alutCreateBufferFromFileImage ( void* data, ALsizei length ) ;
-FUNCTION: ALuint alutCreateBufferHelloWorld ( ) ;
-FUNCTION: ALuint alutCreateBufferWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration ) ;
-FUNCTION: void* alutLoadMemoryFromFile ( char* fileName, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
-FUNCTION: void* alutLoadMemoryFromFileImage ( void* data, ALsizei length, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
-FUNCTION: void* alutLoadMemoryHelloWorld ( ALenum* format, ALsizei* size, ALfloat* frequency ) ;
-FUNCTION: void* alutLoadMemoryWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration, ALenum* format, ALsizei* size, ALfloat* freq ) ;
-FUNCTION: char* alutGetMIMETypes ( ALenum loader ) ;
-FUNCTION: ALint alutGetMajorVersion ( ) ;
-FUNCTION: ALint alutGetMinorVersion ( ) ;
-FUNCTION: ALboolean alutSleep ( ALfloat duration ) ;
-
-FUNCTION: void alutUnloadWAV ( ALenum format, void* data, ALsizei size, ALsizei frequency ) ;
-
-SYMBOL: init
-
-: init-openal ( -- )
-    init get-global expired? [
-        f f alutInit 0 = [ "Could not initialize OpenAL" throw ] when
-        1337 <alien> init set-global
-    ] when ;
-
-: exit-openal ( -- )
-    init get-global expired? [
-        alutExit 0 = [ "Could not close OpenAL" throw ] when
-        f init set-global
-    ] unless ;
-
-: create-buffer-from-file ( filename -- buffer )
-    alutCreateBufferFromFile dup AL_NONE = [
-        "create-buffer-from-file failed" throw
-    ] when ;
-
-os macosx? "openal.alut.macosx" "openal.alut.other" ? require
-
-: create-buffer-from-wav ( filename -- buffer )
-    gen-buffer dup rot load-wav-file
-    [ alBufferData ] 4 nkeep alutUnloadWAV ;
-
-: check-error ( -- )
-    alGetError dup ALUT_ERROR_NO_ERROR = [
-        drop
-    ] [
-        alGetString throw
-    ] if ;
-
+! Copyright (C) 2007 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel accessors arrays alien system combinators
+alien.syntax namespaces alien.c-types sequences vocabs.loader
+shuffle openal openal.alut.backend alien.libraries generalizations
+specialized-arrays alien.destructors ;
+FROM: alien.c-types => float short ;
+SPECIALIZED-ARRAY: uint
+IN: openal.alut
+
+<< "alut" {
+        { [ os windows? ]  [ "alut.dll" ] }
+        { [ os macosx? ] [
+            "/System/Library/Frameworks/OpenAL.framework/OpenAL"
+        ] }
+        { [ os unix?  ]  [ "libalut.so" ] }
+    } cond "cdecl" add-library >>
+
+<< os macosx? [ "alut" deploy-library ] unless >>
+
+LIBRARY: alut
+
+CONSTANT: ALUT_API_MAJOR_VERSION 1
+CONSTANT: ALUT_API_MINOR_VERSION 1
+CONSTANT: ALUT_ERROR_NO_ERROR 0
+CONSTANT: ALUT_ERROR_OUT_OF_MEMORY HEX: 200
+CONSTANT: ALUT_ERROR_INVALID_ENUM HEX: 201
+CONSTANT: ALUT_ERROR_INVALID_VALUE HEX: 202
+CONSTANT: ALUT_ERROR_INVALID_OPERATION HEX: 203
+CONSTANT: ALUT_ERROR_NO_CURRENT_CONTEXT HEX: 204
+CONSTANT: ALUT_ERROR_AL_ERROR_ON_ENTRY HEX: 205
+CONSTANT: ALUT_ERROR_ALC_ERROR_ON_ENTRY HEX: 206
+CONSTANT: ALUT_ERROR_OPEN_DEVICE HEX: 207
+CONSTANT: ALUT_ERROR_CLOSE_DEVICE HEX: 208
+CONSTANT: ALUT_ERROR_CREATE_CONTEXT HEX: 209
+CONSTANT: ALUT_ERROR_MAKE_CONTEXT_CURRENT HEX: 20A
+CONSTANT: ALUT_ERROR_DESTRY_CONTEXT HEX: 20B
+CONSTANT: ALUT_ERROR_GEN_BUFFERS HEX: 20C
+CONSTANT: ALUT_ERROR_BUFFER_DATA HEX: 20D
+CONSTANT: ALUT_ERROR_IO_ERROR HEX: 20E
+CONSTANT: ALUT_ERROR_UNSUPPORTED_FILE_TYPE HEX: 20F
+CONSTANT: ALUT_ERROR_UNSUPPORTED_FILE_SUBTYPE HEX: 210
+CONSTANT: ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA HEX: 211
+CONSTANT: ALUT_WAVEFORM_SINE HEX: 100
+CONSTANT: ALUT_WAVEFORM_SQUARE HEX: 101
+CONSTANT: ALUT_WAVEFORM_SAWTOOTH HEX: 102
+CONSTANT: ALUT_WAVEFORM_WHITENOISE HEX: 103
+CONSTANT: ALUT_WAVEFORM_IMPULSE HEX: 104
+CONSTANT: ALUT_LOADER_BUFFER HEX: 300
+CONSTANT: ALUT_LOADER_MEMORY HEX: 301
+
+FUNCTION: ALboolean alutInit ( int* argcp, char** argv ) ;
+FUNCTION: ALboolean alutInitWithoutContext ( int* argcp, char** argv ) ;
+FUNCTION: ALboolean alutExit ( ) ;
+FUNCTION: ALenum alutGetError ( ) ;
+FUNCTION: char* alutGetErrorString ( ALenum error ) ;
+FUNCTION: ALuint alutCreateBufferFromFile ( char* fileName ) ;
+FUNCTION: ALuint alutCreateBufferFromFileImage ( void* data, ALsizei length ) ;
+FUNCTION: ALuint alutCreateBufferHelloWorld ( ) ;
+FUNCTION: ALuint alutCreateBufferWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration ) ;
+FUNCTION: void* alutLoadMemoryFromFile ( char* fileName, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
+FUNCTION: void* alutLoadMemoryFromFileImage ( void* data, ALsizei length, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
+FUNCTION: void* alutLoadMemoryHelloWorld ( ALenum* format, ALsizei* size, ALfloat* frequency ) ;
+FUNCTION: void* alutLoadMemoryWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration, ALenum* format, ALsizei* size, ALfloat* freq ) ;
+FUNCTION: char* alutGetMIMETypes ( ALenum loader ) ;
+FUNCTION: ALint alutGetMajorVersion ( ) ;
+FUNCTION: ALint alutGetMinorVersion ( ) ;
+FUNCTION: ALboolean alutSleep ( ALfloat duration ) ;
+
+FUNCTION: void alutUnloadWAV ( ALenum format, void* data, ALsizei size, ALsizei frequency ) ;
+
+SYMBOL: init
+
+: init-openal ( -- )
+    init get-global expired? [
+        f f alutInit 0 = [ "Could not initialize OpenAL" throw ] when
+        1337 <alien> init set-global
+    ] when ;
+
+: exit-openal ( -- )
+    init get-global expired? [
+        alutExit 0 = [ "Could not close OpenAL" throw ] when
+        f init set-global
+    ] unless ;
+
+: create-buffer-from-file ( filename -- buffer )
+    alutCreateBufferFromFile dup AL_NONE = [
+        "create-buffer-from-file failed" throw
+    ] when ;
+
+os macosx? "openal.alut.macosx" "openal.alut.other" ? require
+
+: create-buffer-from-wav ( filename -- buffer )
+    gen-buffer dup rot load-wav-file
+    [ alBufferData ] 4 nkeep alutUnloadWAV ;
+
+: check-error ( -- )
+    alGetError dup ALUT_ERROR_NO_ERROR = [
+        drop
+    ] [
+        alGetString throw
+    ] if ;
+
diff --git a/extra/openal/example/example.factor b/extra/openal/example/example.factor
index 7789ee6e0a..54ce402957 100755
--- a/extra/openal/example/example.factor
+++ b/extra/openal/example/example.factor
@@ -1,33 +1,33 @@
-! Copyright (C) 2007 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-USING: calendar kernel openal openal.alut sequences threads ;
-IN: openal.example
-
-: play-hello ( -- )
-    init-openal
-    1 gen-sources
-    first dup AL_BUFFER  alutCreateBufferHelloWorld set-source-param
-    source-play
-    1000 milliseconds sleep ;
-  
-: (play-file) ( source -- )
-    100 milliseconds sleep
-    dup source-playing? [ (play-file) ] [ drop ] if ;
-
-: play-file ( filename -- )
-    init-openal
-    create-buffer-from-file 
-    1 gen-sources
-    first dup [ AL_BUFFER rot set-source-param ] dip
-    dup source-play
-    check-error
-    (play-file) ;
-
-: play-wav ( filename -- )
-    init-openal
-    create-buffer-from-wav 
-    1 gen-sources
-    first dup [ AL_BUFFER rot set-source-param ] dip
-    dup source-play
-    check-error
-    (play-file) ;
+! Copyright (C) 2007 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: calendar kernel openal openal.alut sequences threads ;
+IN: openal.example
+
+: play-hello ( -- )
+    init-openal
+    1 gen-sources
+    first dup AL_BUFFER  alutCreateBufferHelloWorld set-source-param
+    source-play
+    1000 milliseconds sleep ;
+  
+: (play-file) ( source -- )
+    100 milliseconds sleep
+    dup source-playing? [ (play-file) ] [ drop ] if ;
+
+: play-file ( filename -- )
+    init-openal
+    create-buffer-from-file 
+    1 gen-sources
+    first dup [ AL_BUFFER rot set-source-param ] dip
+    dup source-play
+    check-error
+    (play-file) ;
+
+: play-wav ( filename -- )
+    init-openal
+    create-buffer-from-wav 
+    1 gen-sources
+    first dup [ AL_BUFFER rot set-source-param ] dip
+    dup source-play
+    check-error
+    (play-file) ;

From 30b586ef5fd035bc5d681cf7a0e14a952a3407b9 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Sat, 20 Feb 2010 00:24:37 -0800
Subject: [PATCH 112/250] Merge up

---
 .../mailboxes/mailboxes-tests.factor          | 108 +++++-----
 basis/concurrency/mailboxes/mailboxes.factor  | 188 +++++++++---------
 basis/concurrency/promises/promises.factor    |  54 ++---
 3 files changed, 175 insertions(+), 175 deletions(-)

diff --git a/basis/concurrency/mailboxes/mailboxes-tests.factor b/basis/concurrency/mailboxes/mailboxes-tests.factor
index 3435a01455..87a4c3cdba 100644
--- a/basis/concurrency/mailboxes/mailboxes-tests.factor
+++ b/basis/concurrency/mailboxes/mailboxes-tests.factor
@@ -1,54 +1,54 @@
-USING: concurrency.mailboxes concurrency.count-downs concurrency.conditions
-vectors sequences threads tools.test math kernel strings namespaces
-continuations calendar destructors ;
-IN: concurrency.mailboxes.tests
-
-{ 1 1 } [ [ integer? ] mailbox-get? ] must-infer-as
-
-[ V{ 1 2 3 } ] [
-    0 <vector>
-    <mailbox>
-    [ mailbox-get swap push ] in-thread
-    [ mailbox-get swap push ] in-thread
-    [ mailbox-get swap push ] in-thread
-    1 over mailbox-put
-    2 over mailbox-put
-    3 swap mailbox-put
-] unit-test
-
-[ V{ 1 2 3 } ] [
-    0 <vector>
-    <mailbox>
-    [ [ integer? ] mailbox-get? swap push ] in-thread
-    [ [ integer? ] mailbox-get? swap push ] in-thread
-    [ [ integer? ] mailbox-get? swap push ] in-thread
-    1 over mailbox-put
-    2 over mailbox-put
-    3 swap mailbox-put
-] unit-test
-
-[ V{ 1 "junk" 3 "junk2" } [ 456 ] ] [
-    0 <vector>
-    <mailbox>
-    [ [ integer? ] mailbox-get? swap push ] in-thread
-    [ [ integer? ] mailbox-get? swap push ] in-thread
-    [ [ string? ] mailbox-get? swap push ] in-thread
-    [ [ string? ] mailbox-get? swap push ] in-thread
-    1 over mailbox-put
-    "junk" over mailbox-put
-    [ 456 ] over mailbox-put
-    3 over mailbox-put
-    "junk2" over mailbox-put
-    mailbox-get
-] unit-test
-
-[ { "foo" "bar" } ] [
-    <mailbox>
-    "foo" over mailbox-put
-    "bar" over mailbox-put
-    mailbox-get-all
-] unit-test
-
-[
-    <mailbox> 1 seconds mailbox-get-timeout
-] [ wait-timeout? ] must-fail-with
+USING: concurrency.mailboxes concurrency.count-downs concurrency.conditions
+vectors sequences threads tools.test math kernel strings namespaces
+continuations calendar destructors ;
+IN: concurrency.mailboxes.tests
+
+{ 1 1 } [ [ integer? ] mailbox-get? ] must-infer-as
+
+[ V{ 1 2 3 } ] [
+    0 <vector>
+    <mailbox>
+    [ mailbox-get swap push ] in-thread
+    [ mailbox-get swap push ] in-thread
+    [ mailbox-get swap push ] in-thread
+    1 over mailbox-put
+    2 over mailbox-put
+    3 swap mailbox-put
+] unit-test
+
+[ V{ 1 2 3 } ] [
+    0 <vector>
+    <mailbox>
+    [ [ integer? ] mailbox-get? swap push ] in-thread
+    [ [ integer? ] mailbox-get? swap push ] in-thread
+    [ [ integer? ] mailbox-get? swap push ] in-thread
+    1 over mailbox-put
+    2 over mailbox-put
+    3 swap mailbox-put
+] unit-test
+
+[ V{ 1 "junk" 3 "junk2" } [ 456 ] ] [
+    0 <vector>
+    <mailbox>
+    [ [ integer? ] mailbox-get? swap push ] in-thread
+    [ [ integer? ] mailbox-get? swap push ] in-thread
+    [ [ string? ] mailbox-get? swap push ] in-thread
+    [ [ string? ] mailbox-get? swap push ] in-thread
+    1 over mailbox-put
+    "junk" over mailbox-put
+    [ 456 ] over mailbox-put
+    3 over mailbox-put
+    "junk2" over mailbox-put
+    mailbox-get
+] unit-test
+
+[ { "foo" "bar" } ] [
+    <mailbox>
+    "foo" over mailbox-put
+    "bar" over mailbox-put
+    mailbox-get-all
+] unit-test
+
+[
+    <mailbox> 1 seconds mailbox-get-timeout
+] [ wait-timeout? ] must-fail-with
diff --git a/basis/concurrency/mailboxes/mailboxes.factor b/basis/concurrency/mailboxes/mailboxes.factor
index 06da3b34a6..221a5a1fa3 100644
--- a/basis/concurrency/mailboxes/mailboxes.factor
+++ b/basis/concurrency/mailboxes/mailboxes.factor
@@ -1,94 +1,94 @@
-! Copyright (C) 2005, 2010 Chris Double, Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: dlists deques threads sequences continuations namespaces
-math quotations words kernel arrays assocs init system
-concurrency.conditions accessors debugger debugger.threads
-locals fry ;
-IN: concurrency.mailboxes
-
-TUPLE: mailbox threads data ;
-
-: <mailbox> ( -- mailbox )
-    mailbox new
-        <dlist> >>threads
-        <dlist> >>data ;
-
-: mailbox-empty? ( mailbox -- bool )
-    data>> deque-empty? ;
-
-: mailbox-put ( obj mailbox -- )
-    [ data>> push-front ]
-    [ threads>> notify-all ] bi yield ;
-
-: wait-for-mailbox ( mailbox timeout -- )
-    [ threads>> ] dip "mailbox" wait ;
-
-:: block-unless-pred ( mailbox timeout pred: ( message -- ? ) -- )
-    mailbox data>> pred dlist-any? [
-        mailbox timeout wait-for-mailbox
-        mailbox timeout pred block-unless-pred
-    ] unless ; inline recursive
-
-: block-if-empty ( mailbox timeout -- mailbox )
-    over mailbox-empty? [
-        2dup wait-for-mailbox block-if-empty
-    ] [
-        drop
-    ] if ;
-
-: mailbox-peek ( mailbox -- obj )
-    data>> peek-back ;
-
-: mailbox-get-timeout ( mailbox timeout -- obj )
-    block-if-empty data>> pop-back ;
-
-: mailbox-get ( mailbox -- obj )
-    f mailbox-get-timeout ;
-
-: mailbox-get-all-timeout ( mailbox timeout -- array )
-    block-if-empty
-    [ dup mailbox-empty? not ]
-    [ dup data>> pop-back ]
-    produce nip ;
-
-: mailbox-get-all ( mailbox -- array )
-    f mailbox-get-all-timeout ;
-
-: while-mailbox-empty ( mailbox quot -- )
-    [ '[ _ mailbox-empty? ] ] dip while ; inline
-
-: mailbox-get-timeout? ( mailbox timeout pred -- obj )
-    [ block-unless-pred ]
-    [ [ drop data>> ] dip delete-node-if ]
-    3bi ; inline
-
-: mailbox-get? ( mailbox pred -- obj )
-    f swap mailbox-get-timeout? ; inline
-
-: wait-for-close-timeout ( mailbox timeout -- )
-    over disposed>>
-    [ 2drop ] [ 2dup wait-for-mailbox wait-for-close-timeout ] if ;
-
-: wait-for-close ( mailbox -- )
-    f wait-for-close-timeout ;
-
-TUPLE: linked-error error thread ;
-
-M: linked-error error.
-    [ thread>> error-in-thread. ] [ error>> error. ] bi ;
-
-C: <linked-error> linked-error
-
-: ?linked ( message -- message )
-    dup linked-error? [ rethrow ] when ;
-
-TUPLE: linked-thread < thread supervisor ;
-
-M: linked-thread error-in-thread
-    [ <linked-error> ] [ supervisor>> ] bi mailbox-put ;
-
-: <linked-thread> ( quot name mailbox -- thread' )
-    [ linked-thread new-thread ] dip >>supervisor ;
-
-: spawn-linked-to ( quot name mailbox -- thread )
-    <linked-thread> [ (spawn) ] keep ;
+! Copyright (C) 2005, 2010 Chris Double, Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: dlists deques threads sequences continuations namespaces
+math quotations words kernel arrays assocs init system
+concurrency.conditions accessors debugger debugger.threads
+locals fry ;
+IN: concurrency.mailboxes
+
+TUPLE: mailbox threads data ;
+
+: <mailbox> ( -- mailbox )
+    mailbox new
+        <dlist> >>threads
+        <dlist> >>data ;
+
+: mailbox-empty? ( mailbox -- bool )
+    data>> deque-empty? ;
+
+: mailbox-put ( obj mailbox -- )
+    [ data>> push-front ]
+    [ threads>> notify-all ] bi yield ;
+
+: wait-for-mailbox ( mailbox timeout -- )
+    [ threads>> ] dip "mailbox" wait ;
+
+:: block-unless-pred ( mailbox timeout pred: ( message -- ? ) -- )
+    mailbox data>> pred dlist-any? [
+        mailbox timeout wait-for-mailbox
+        mailbox timeout pred block-unless-pred
+    ] unless ; inline recursive
+
+: block-if-empty ( mailbox timeout -- mailbox )
+    over mailbox-empty? [
+        2dup wait-for-mailbox block-if-empty
+    ] [
+        drop
+    ] if ;
+
+: mailbox-peek ( mailbox -- obj )
+    data>> peek-back ;
+
+: mailbox-get-timeout ( mailbox timeout -- obj )
+    block-if-empty data>> pop-back ;
+
+: mailbox-get ( mailbox -- obj )
+    f mailbox-get-timeout ;
+
+: mailbox-get-all-timeout ( mailbox timeout -- array )
+    block-if-empty
+    [ dup mailbox-empty? not ]
+    [ dup data>> pop-back ]
+    produce nip ;
+
+: mailbox-get-all ( mailbox -- array )
+    f mailbox-get-all-timeout ;
+
+: while-mailbox-empty ( mailbox quot -- )
+    [ '[ _ mailbox-empty? ] ] dip while ; inline
+
+: mailbox-get-timeout? ( mailbox timeout pred -- obj )
+    [ block-unless-pred ]
+    [ [ drop data>> ] dip delete-node-if ]
+    3bi ; inline
+
+: mailbox-get? ( mailbox pred -- obj )
+    f swap mailbox-get-timeout? ; inline
+
+: wait-for-close-timeout ( mailbox timeout -- )
+    over disposed>>
+    [ 2drop ] [ 2dup wait-for-mailbox wait-for-close-timeout ] if ;
+
+: wait-for-close ( mailbox -- )
+    f wait-for-close-timeout ;
+
+TUPLE: linked-error error thread ;
+
+M: linked-error error.
+    [ thread>> error-in-thread. ] [ error>> error. ] bi ;
+
+C: <linked-error> linked-error
+
+: ?linked ( message -- message )
+    dup linked-error? [ rethrow ] when ;
+
+TUPLE: linked-thread < thread supervisor ;
+
+M: linked-thread error-in-thread
+    [ <linked-error> ] [ supervisor>> ] bi mailbox-put ;
+
+: <linked-thread> ( quot name mailbox -- thread' )
+    [ linked-thread new-thread ] dip >>supervisor ;
+
+: spawn-linked-to ( quot name mailbox -- thread )
+    <linked-thread> [ (spawn) ] keep ;
diff --git a/basis/concurrency/promises/promises.factor b/basis/concurrency/promises/promises.factor
index 3381bcc00b..4d6439cf30 100644
--- a/basis/concurrency/promises/promises.factor
+++ b/basis/concurrency/promises/promises.factor
@@ -1,27 +1,27 @@
-! Copyright (C) 2005, 2008 Chris Double, Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors concurrency.mailboxes kernel continuations ;
-IN: concurrency.promises
-
-TUPLE: promise mailbox ;
-
-: <promise> ( -- promise )
-    <mailbox> promise boa ;
-
-: promise-fulfilled? ( promise -- ? )
-    mailbox>> mailbox-empty? not ;
-
-ERROR: promise-already-fulfilled promise ;
-
-: fulfill ( value promise -- )
-    dup promise-fulfilled? [ 
-        promise-already-fulfilled
-    ] [
-        mailbox>> mailbox-put
-    ] if ;
-
-: ?promise-timeout ( promise timeout -- result )
-    [ mailbox>> ] dip block-if-empty mailbox-peek ;
-
-: ?promise ( promise -- result )
-    f ?promise-timeout ;
+! Copyright (C) 2005, 2008 Chris Double, Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors concurrency.mailboxes kernel continuations ;
+IN: concurrency.promises
+
+TUPLE: promise mailbox ;
+
+: <promise> ( -- promise )
+    <mailbox> promise boa ;
+
+: promise-fulfilled? ( promise -- ? )
+    mailbox>> mailbox-empty? not ;
+
+ERROR: promise-already-fulfilled promise ;
+
+: fulfill ( value promise -- )
+    dup promise-fulfilled? [ 
+        promise-already-fulfilled
+    ] [
+        mailbox>> mailbox-put
+    ] if ;
+
+: ?promise-timeout ( promise timeout -- result )
+    [ mailbox>> ] dip block-if-empty mailbox-peek ;
+
+: ?promise ( promise -- result )
+    f ?promise-timeout ;

From b25e945c746e357b54107fa6212184555dd83f94 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Sat, 20 Feb 2010 03:02:56 -0800
Subject: [PATCH 113/250] The return values in the stack effects of FUNCTION:
 words were c-types rather than strings. This was causing scaffold-help to
 fail on vocabularies with FUNCTION:.

---
 basis/alien/parser/parser.factor | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor
index 0cf495fd25..d706446799 100644
--- a/basis/alien/parser/parser.factor
+++ b/basis/alien/parser/parser.factor
@@ -72,10 +72,10 @@ IN: alien.parser
 : function-quot ( return library function types -- quot )
     '[ _ _ _ _ alien-invoke ] ;
 
-:: make-function ( return! library function! parameters -- word quot effect )
-    return function normalize-c-arg function! return!
+:: make-function ( return library function parameters -- word quot effect )
+    return function normalize-c-arg :> ( return-c-type function )
     function create-in dup reset-generic
-    return library function
+    return-c-type library function
     parameters return parse-arglist [ function-quot ] dip ;
 
 : parse-arg-tokens ( -- tokens )

From d0f4239d58ba61b8ca74bd094bbb2bcd698cec7c Mon Sep 17 00:00:00 2001
From: Aaron Schaefer <aaron@elasticdog.com>
Date: Sat, 20 Feb 2010 09:15:05 -0600
Subject: [PATCH 114/250] Solution to Project Euler problem 70

---
 extra/project-euler/049/049.factor       | 14 +----
 extra/project-euler/070/070-tests.factor |  4 ++
 extra/project-euler/070/070.factor       | 67 ++++++++++++++++++++++++
 extra/project-euler/common/common.factor | 24 ++++++---
 4 files changed, 91 insertions(+), 18 deletions(-)
 create mode 100644 extra/project-euler/070/070-tests.factor
 create mode 100644 extra/project-euler/070/070.factor

diff --git a/extra/project-euler/049/049.factor b/extra/project-euler/049/049.factor
index 8b6f635ee4..08244ea023 100644
--- a/extra/project-euler/049/049.factor
+++ b/extra/project-euler/049/049.factor
@@ -1,7 +1,7 @@
 ! Copyright (c) 2009 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays byte-arrays fry hints kernel math math.combinatorics
-    math.functions math.parser math.primes project-euler.common sequences sets ;
+USING: arrays byte-arrays fry kernel math math.combinatorics math.functions
+    math.parser math.primes project-euler.common sequences sets ;
 IN: project-euler.049
 
 ! http://projecteuler.net/index.php?section=problems&id=49
@@ -25,16 +25,6 @@ IN: project-euler.049
 
 <PRIVATE
 
-: count-digits ( n -- byte-array )
-    10 <byte-array> [
-        '[ 10 /mod _ [ 1 + ] change-nth dup 0 > ] loop drop
-    ] keep ;
-
-HINTS: count-digits fixnum ;
-
-: permutations? ( n m -- ? )
-    [ count-digits ] bi@ = ;
-
 : collect-permutations ( seq -- seq )
     [ V{ } clone ] [ dup ] bi* [
         dupd '[ _ permutations? ] filter
diff --git a/extra/project-euler/070/070-tests.factor b/extra/project-euler/070/070-tests.factor
new file mode 100644
index 0000000000..d402b16902
--- /dev/null
+++ b/extra/project-euler/070/070-tests.factor
@@ -0,0 +1,4 @@
+USING: project-euler.070 tools.test ;
+IN: project-euler.070.tests
+
+[ 8319823 ] [ euler070 ] unit-test
diff --git a/extra/project-euler/070/070.factor b/extra/project-euler/070/070.factor
new file mode 100644
index 0000000000..eed179851e
--- /dev/null
+++ b/extra/project-euler/070/070.factor
@@ -0,0 +1,67 @@
+! Copyright (c) 2010 Aaron Schaefer. All rights reserved.
+! The contents of this file are licensed under the Simplified BSD License
+! A copy of the license is available at http://factorcode.org/license.txt
+USING: arrays assocs combinators.short-circuit kernel math math.combinatorics
+    math.functions math.primes math.ranges project-euler.common sequences ;
+IN: project-euler.070
+
+! http://projecteuler.net/index.php?section=problems&id=70
+
+! DESCRIPTION
+! -----------
+
+! Euler's Totient function, φ(n) [sometimes called the phi function], is used
+! to determine the number of positive numbers less than or equal to n which are
+! relatively prime to n. For example, as 1, 2, 4, 5, 7, and 8, are all less
+! than nine and relatively prime to nine, φ(9)=6. The number 1 is considered to
+! be relatively prime to every positive number, so φ(1)=1.
+
+! Interestingly, φ(87109)=79180, and it can be seen that 87109 is a permutation
+! of 79180.
+
+! Find the value of n, 1 < n < 10^(7), for which φ(n) is a permutation of n and
+! the ratio n/φ(n) produces a minimum.
+
+
+! SOLUTION
+! --------
+
+! For n/φ(n) to be minimised, φ(n) must be as close to n as possible; that is,
+! we want to maximise φ(n). The minimal solution for n/φ(n) would be if n was
+! prime giving n/(n-1) but since n-1 never is a permutation of n it cannot be
+! prime.
+
+! The next best thing would be if n only consisted of 2 prime factors close to
+! (in this case) sqrt(10000000). Hence n = p1*p2 and we only need to search
+! through a list of known prime pairs. In addition:
+
+!     φ(p1*p2) = p1*p2*(1-1/p1)(1-1/p2) = (p1-1)(p2-1)
+
+! ...so we can compute φ(n) more efficiently.
+
+<PRIVATE
+
+! NOTE: ±1000 is an arbitrary range
+: likely-prime-factors ( -- seq )
+    7 10^ sqrt >integer 1000 [ - ] [ + ] 2bi primes-between ; inline
+
+: n-and-phi ( seq -- seq' )
+    #! ( seq  = { p1, p2 } -- seq' = { n, φ(n) } )
+    [ product ] [ [ 1 - ] map product ] bi 2array ;
+
+: fit-requirements? ( seq -- ? )
+    first2 { [ drop 7 10^ < ] [ permutations? ] } 2&& ;
+
+: minimum-ratio ( seq -- n )
+    [ [ first2 / ] map [ infimum ] keep index ] keep nth first ;
+
+PRIVATE>
+
+: euler070 ( -- answer )
+   likely-prime-factors 2 all-combinations [ n-and-phi ] map
+   [ fit-requirements? ] filter minimum-ratio ;
+
+! [ euler070 ] 100 ave-time
+! 379 ms ave run time - 1.15 SD (100 trials)
+
+SOLUTION: euler070
diff --git a/extra/project-euler/common/common.factor b/extra/project-euler/common/common.factor
index 6995adcd6a..1f29ca0af5 100644
--- a/extra/project-euler/common/common.factor
+++ b/extra/project-euler/common/common.factor
@@ -1,10 +1,11 @@
 ! Copyright (c) 2007-2010 Aaron Schaefer.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays kernel lists make math math.functions math.matrices
-    math.primes.miller-rabin math.order math.parser math.primes.factors
-    math.primes.lists math.ranges math.ratios namespaces parser prettyprint
-    quotations sequences sorting strings unicode.case vocabs vocabs.parser
-    words ;
+! The contents of this file are licensed under the Simplified BSD License
+! A copy of the license is available at http://factorcode.org/license.txt
+USING: accessors arrays byte-arrays fry hints kernel lists make math
+    math.functions math.matrices math.order math.parser math.primes.factors
+    math.primes.lists math.primes.miller-rabin math.ranges math.ratios
+    namespaces parser prettyprint quotations sequences sorting strings
+    unicode.case vocabs vocabs.parser words ;
 IN: project-euler.common
 
 ! A collection of words used by more than one Project Euler solution
@@ -25,6 +26,7 @@ IN: project-euler.common
 ! pentagonal? - #44, #45
 ! penultimate - #69, #71
 ! propagate-all - #18, #67
+! permutations? - #49, #70
 ! sum-proper-divisors - #21
 ! tau* - #12
 ! [uad]-transform - #39, #75
@@ -38,6 +40,13 @@ IN: project-euler.common
 
 <PRIVATE
 
+: count-digits ( n -- byte-array )
+    10 <byte-array> [
+        '[ 10 /mod _ [ 1 + ] change-nth dup 0 > ] loop drop
+    ] keep ;
+
+HINTS: count-digits fixnum ;
+
 : max-children ( seq -- seq )
     [ dup length 1 - iota [ nth-pair max , ] with each ] { } make ;
 
@@ -107,6 +116,9 @@ PRIVATE>
     reverse [ first dup ] [ rest ] bi
     [ propagate dup ] map nip reverse swap suffix ;
 
+: permutations? ( n m -- ? )
+    [ count-digits ] bi@ = ;
+
 : sum-divisors ( n -- sum )
     dup 4 < [ { 0 1 3 4 } nth ] [ (sum-divisors) ] if ;
 

From 6cc9348dfab6f03628caaaf990e37ddefcc362b4 Mon Sep 17 00:00:00 2001
From: Aaron Schaefer <aaron@elasticdog.com>
Date: Sat, 20 Feb 2010 09:16:53 -0600
Subject: [PATCH 115/250] Add PE problem 70 to common project file

---
 extra/project-euler/project-euler.factor | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/extra/project-euler/project-euler.factor b/extra/project-euler/project-euler.factor
index ce58e7009a..4131f41b1f 100644
--- a/extra/project-euler/project-euler.factor
+++ b/extra/project-euler/project-euler.factor
@@ -18,15 +18,15 @@ USING: definitions io io.files io.pathnames kernel math math.parser
     project-euler.053 project-euler.054 project-euler.055 project-euler.056
     project-euler.057 project-euler.058 project-euler.059 project-euler.062
     project-euler.063 project-euler.065 project-euler.067 project-euler.069
-    project-euler.071 project-euler.072 project-euler.073 project-euler.074
-    project-euler.075 project-euler.076 project-euler.079 project-euler.081
-    project-euler.085 project-euler.089 project-euler.092 project-euler.097
-    project-euler.099 project-euler.100 project-euler.102 project-euler.112
-    project-euler.116 project-euler.117 project-euler.124 project-euler.134
-    project-euler.148 project-euler.150 project-euler.151 project-euler.164
-    project-euler.169 project-euler.173 project-euler.175 project-euler.186
-    project-euler.188 project-euler.190 project-euler.203 project-euler.206
-    project-euler.215 project-euler.255 ;
+    project-euler.070 project-euler.071 project-euler.072 project-euler.073
+    project-euler.074 project-euler.075 project-euler.076 project-euler.079
+    project-euler.081 project-euler.085 project-euler.089 project-euler.092
+    project-euler.097 project-euler.099 project-euler.100 project-euler.102
+    project-euler.112 project-euler.116 project-euler.117 project-euler.124
+    project-euler.134 project-euler.148 project-euler.150 project-euler.151
+    project-euler.164 project-euler.169 project-euler.173 project-euler.175
+    project-euler.186 project-euler.188 project-euler.190 project-euler.203
+    project-euler.206 project-euler.215 project-euler.255 ;
 IN: project-euler
 
 <PRIVATE

From 5ea289eacd66f32a2dba91e1013095f81aa4e215 Mon Sep 17 00:00:00 2001
From: Aaron Schaefer <aaron@elasticdog.com>
Date: Sat, 20 Feb 2010 11:20:21 -0600
Subject: [PATCH 116/250] clean up PE solution 255

---
 extra/project-euler/255/255.factor       | 102 +++++++++++++----------
 extra/project-euler/common/common.factor |   3 +
 2 files changed, 61 insertions(+), 44 deletions(-)

diff --git a/extra/project-euler/255/255.factor b/extra/project-euler/255/255.factor
index 57a5c5fec7..40bcce4b90 100644
--- a/extra/project-euler/255/255.factor
+++ b/extra/project-euler/255/255.factor
@@ -1,49 +1,64 @@
-! Copyright (C) 2009 Jon Harper.
+! Copyright (c) 2009 Jon Harper.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: project-euler.common math kernel sequences math.functions math.ranges prettyprint io threads math.parser locals arrays namespaces ;
+USING: arrays io kernel locals math math.functions math.parser math.ranges
+    namespaces prettyprint project-euler.common sequences threads ;
 IN: project-euler.255
 
 ! http://projecteuler.net/index.php?section=problems&id=255
 
 ! DESCRIPTION
 ! -----------
-! We define the rounded-square-root of a positive integer n as the square root of n rounded to the nearest integer.
-! 
-! The following procedure (essentially Heron's method adapted to integer arithmetic) finds the rounded-square-root of n:
-! 
-! Let d be the number of digits of the number n.
-! If d is odd, set x_(0) = 2×10^((d-1)⁄2).
-! If d is even, set x_(0) = 7×10^((d-2)⁄2).
-! Repeat:
-! 
-! until x_(k+1) = x_(k).
-! 
+
+! We define the rounded-square-root of a positive integer n as the square root
+! of n rounded to the nearest integer.
+
+! The following procedure (essentially Heron's method adapted to integer
+! arithmetic) finds the rounded-square-root of n:
+
+!     Let d be the number of digits of the number n.
+!     If d is odd, set x_(0) = 2×10^((d-1)⁄2).
+!     If d is even, set x_(0) = 7×10^((d-2)⁄2).
+
+!     Repeat: [see URL for figure ]
+
+!     until x_(k+1) = x_(k).
+
 ! As an example, let us find the rounded-square-root of n = 4321.
 ! n has 4 digits, so x_(0) = 7×10^((4-2)⁄2) = 70.
-! 
-! Since x_(2) = x_(1), we stop here.
-! So, after just two iterations, we have found that the rounded-square-root of 4321 is 66 (the actual square root is 65.7343137…).
-! 
-! The number of iterations required when using this method is surprisingly low.
-! For example, we can find the rounded-square-root of a 5-digit integer (10,000 ≤ n ≤ 99,999) with an average of 3.2102888889 iterations (the average value was rounded to 10 decimal places).
-! 
-! Using the procedure described above, what is the average number of iterations required to find the rounded-square-root of a 14-digit number (10^(13) ≤ n < 10^(14))?
-! Give your answer rounded to 10 decimal places.
-! 
-! Note: The symbols ⌊x⌋ and ⌈x⌉ represent the floor function and ceiling function respectively.
-! 
-<PRIVATE
 
-: round-to-10-decimals ( a -- b ) 1.0e10 * round 1.0e10 / ;
+!     [ see URL for figure ]
+
+! Since x_(2) = x_(1), we stop here.
+
+! So, after just two iterations, we have found that the rounded-square-root of
+! 4321 is 66 (the actual square root is 65.7343137…).
+
+! The number of iterations required when using this method is surprisingly low.
+! For example, we can find the rounded-square-root of a 5-digit integer
+! (10,000 ≤ n ≤ 99,999) with an average of 3.2102888889 iterations (the average
+! value was rounded to 10 decimal places).
+
+! Using the procedure described above, what is the average number of iterations
+! required to find the rounded-square-root of a 14-digit number
+! (10^(13) ≤ n < 10^(14))? Give your answer rounded to 10 decimal places.
+
+! Note: The symbols ⌊x⌋ and ⌈x⌉ represent the floor function and ceiling
+! function respectively.
+
+! SOLUTION
+! --------
+
+<PRIVATE
 
 ! same as produce, but outputs the sum instead of the sequence of results
 : produce-sum ( id pred quot -- sum )
     [ 0 ] 2dip [ [ dip swap ] curry ] [ [ dip + ] curry ] bi* while ; inline
 
 : x0 ( i -- x0 )
-    number-length dup even? 
+    number-length dup even?
     [ 2 - 2 / 10 swap ^ 7 * ]
     [ 1 - 2 / 10 swap ^ 2 * ] if ;
+
 : ⌈a/b⌉  ( a b -- ⌈a/b⌉ )
     [ 1 - + ] keep /i ;
 
@@ -56,38 +71,37 @@ IN: project-euler.255
 DEFER: iteration#
 ! Gives the number of iterations when xk+1 has the same value for all a<=i<=n
 :: (iteration#) ( i xi a b -- # )
-    a xi xk+1 dup xi = 
-        [ drop i b a - 1 + * ] 
-        [ i 1 + swap a b iteration# ] if ;
+    a xi xk+1 dup xi =
+    [ drop i b a - 1 + * ]
+    [ i 1 + swap a b iteration# ] if ;
 
 ! Gives the number of iterations in the general case by breaking into intervals
 ! in which xk+1 is the same.
 :: iteration# ( i xi a b -- # )
-    a 
-    a xi next-multiple 
-    [ dup b < ] 
-    [ 
+    a
+    a xi next-multiple
+    [ dup b < ]
+    [
         ! set up the values for the next iteration
         [ nip [ 1 + ] [ xi + ] bi ] 2keep
         ! set up the arguments for (iteration#)
-        [ i xi ] 2dip (iteration#) 
-    ] produce-sum 
+        [ i xi ] 2dip (iteration#)
+    ] produce-sum
     ! deal with the last numbers
     [ drop b [ i xi ] 2dip (iteration#) ] dip
     + ;
 
-: 10^ ( a -- 10^a ) 10 swap ^ ; inline
-
-: (euler255) ( a b -- answer ) 
+: (euler255) ( a b -- answer )
     [ 10^ ] bi@ 1 -
     [ [ drop x0 1 swap ] 2keep iteration# ] 2keep
     swap - 1 + /f ;
 
-
 PRIVATE>
 
-: euler255 ( -- answer ) 
-    13 14 (euler255) round-to-10-decimals ;
+: euler255 ( -- answer )
+    13 14 (euler255) 10 nth-place ;
+
+! [ euler255 ] gc time
+! Running time: 37.468911341 seconds
 
 SOLUTION: euler255
-
diff --git a/extra/project-euler/common/common.factor b/extra/project-euler/common/common.factor
index 1f29ca0af5..48520ef565 100644
--- a/extra/project-euler/common/common.factor
+++ b/extra/project-euler/common/common.factor
@@ -92,6 +92,9 @@ PRIVATE>
         [ [ 10 * ] [ 1 + ] bi* ] while 2nip
     ] if-zero ;
 
+: nth-place ( x n -- y )
+    10^ [ * round >integer ] keep /f ;
+
 : nth-prime ( n -- n )
     1 - lprimes lnth ;
 

From 83d6f7fc6f746a0d7289eda78e5224133f8e6696 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sat, 20 Feb 2010 09:45:42 -0800
Subject: [PATCH 117/250] if you're going to support shift-del, you should also
 support shift-ins and ctrl-ins

---
 basis/ui/gadgets/worlds/worlds.factor | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/basis/ui/gadgets/worlds/worlds.factor b/basis/ui/gadgets/worlds/worlds.factor
index 526fc77c57..eea2933b04 100644
--- a/basis/ui/gadgets/worlds/worlds.factor
+++ b/basis/ui/gadgets/worlds/worlds.factor
@@ -231,6 +231,8 @@ action-gestures [
 ] H{ } assoc-map-as
 H{
     { T{ key-down f { S+ } "DELETE" } [ \ cut-action send-action ] }
+    { T{ key-down f { S+ } "INSERT" } [ \ paste-action send-action ] }
+    { T{ key-down f { C+ } "INSERT" } [ \ copy-action send-action ] }
     { T{ button-down f { C+ } 1 } [ drop T{ button-down f f 3 } button-gesture ] }
     { T{ button-down f { A+ } 1 } [ drop T{ button-down f f 2 } button-gesture ] }
     { T{ button-down f { M+ } 1 } [ drop T{ button-down f f 2 } button-gesture ] }

From d6731085183bef23d926f6b70ddc8fb504a08945 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sat, 20 Feb 2010 10:10:02 -0800
Subject: [PATCH 118/250] game.input: add a convenient "buttons-delta" word to
 convert two key/button state samples into pressed/released values

---
 basis/game/input/input-docs.factor  | 33 +++++++++++++++++++++++++++--
 basis/game/input/input-tests.factor | 11 ++++++++++
 basis/game/input/input.factor       | 15 +++++++++++++
 3 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/basis/game/input/input-docs.factor b/basis/game/input/input-docs.factor
index 29b74ff570..1ea5dcc650 100644
--- a/basis/game/input/input-docs.factor
+++ b/basis/game/input/input-docs.factor
@@ -32,6 +32,12 @@ ARTICLE: "game-input" "Game controller input"
     controller-state
     keyboard-state
     mouse-state
+}
+"Convenience functions are provided to convert a pair of key or button state sequences into a sequence of " { $link pressed } "/" { $link released } " deltas:"
+{ $subsections
+    button-delta
+    buttons-delta
+    buttons-delta-as
 } ;
 
 HELP: open-game-input
@@ -136,7 +142,7 @@ HELP: controller-state
     { "A value of " { $link f } " in any slot (besides the elements of " { $snippet "buttons" } ") indicates that the corresponding element is not present on the device." } } } ;
 
 HELP: keyboard-state
-{ $class-description "The " { $link read-keyboard } " word returns objects of this class. The " { $snippet "keys" } " slot of a " { $snippet "keyboard-state" } " object contains a " { $link sequence } " of 256 members representing the state of the keys on the keyboard. Each element is a boolean value indicating whether the corresponding key is pressed. The sequence is indexed by scancode as defined under usage page 7 of the USB HID standard. Named scancode constants are provided in the " { $vocab-link "game.input.scancodes" } " vocabulary." }
+{ $class-description "The " { $link read-keyboard } " word returns objects of this class. The " { $snippet "keys" } " slot of a " { $snippet "keyboard-state" } " object contains a " { $link sequence } " of 256 members representing the state of the keys on the keyboard. Each element is a boolean value indicating whether the corresponding key is pressed. The sequence is indexed by scancode as defined by the USB HID standard. Named scancode constants are provided in the " { $vocab-link "game.input.scancodes" } " vocabulary." }
 { $warning "The scancodes used to index " { $snippet "keyboard-state" } " objects correspond to physical key positions on the keyboard--they are unaffected by keymaps, modifier keys, or other operating environment postprocessing. The face value of the constants in " { $vocab-link "game.input.scancodes" } " do not necessarily correspond to what the user expects the key to type. Because of this, " { $link read-keyboard } " should not be used for text entry purposes. The Factor UI's standard gesture mechanism should be used in cases where the logical meaning of keypresses is needed; see " { $link "keyboard-gestures" } "." } ;
 
 HELP: mouse-state
@@ -151,7 +157,30 @@ HELP: mouse-state
 "Mouse movement is recorded relative to when the game input interface was opened with " { $link open-game-input } " or the mouse state is reset with " { $link reset-mouse } "."
 } ;
 
-
 { keyboard-state read-keyboard } related-words
 
+HELP: button-delta
+{ $values { "old?" boolean } { "new?" boolean } { "delta" { $link pressed } ", " { $link released } ", or " { $link POSTPONE: f } } }
+{ $description "Outputs a symbol representing the change in a key or button's state given a \"before\" and \"after\" sample of its state. Outputs " { $link pressed } " if " { $snippet "old?" } " is false and " { $snippet "new?" } " is true, " { $link released } " if " { $snippet "old?" } " is true and " { $snippet "new?" } " is false, or " { $link POSTPONE: f } " if the two inputs have the same boolean value." } ;
+
+HELP: buttons-delta
+{ $values { "old-buttons" sequence } { "new-buttons" sequence } { "delta" "an array of " { $link pressed } ", " { $link released } ", or " { $link POSTPONE: f } } }
+{ $description "Outputs an array of symbols representing the change in a set of keys or buttons' states given \"before\" and \"after\" samples of their state. For each corresponding pair of values in the two input sequences, outputs " { $link pressed } " if " { $snippet "old-buttons" } " contains a false and " { $snippet "new-buttons" } " a true value, " { $link released } " if " { $snippet "old-buttons" } " contains true and " { $snippet "new-buttons" } " false, or " { $link POSTPONE: f } " if the two elements have the same boolean value."
+$nl
+"This word can be used with two samples of a " { $link keyboard-state } "'s " { $snippet "keys" } " slot or of a " { $link mouse-state } "'s or " { $link controller-state } "'s " { $snippet "buttons" } " slot to convert the button states into pressed/released values. Remember to " { $link clone } " state objects to record snapshots of their state." } ;
+
+HELP: buttons-delta-as
+{ $values { "old-buttons" sequence } { "new-buttons" sequence } { "exemplar" sequence } { "delta" "a sequence of " { $link pressed } ", " { $link released } ", or " { $link POSTPONE: f } } }
+{ $description "Like " { $link buttons-delta } ", but returns a sequence matching the type of the " { $snippet "exemplar" } "." } ;
+
+{ button-delta buttons-delta buttons-delta-as } related-words
+
+HELP: pressed
+{ $class-description "This symbol is returned by " { $link button-delta } " or " { $link buttons-delta } " to represent a button or key being pressed between two samples of its state." } ;
+
+HELP: released
+{ $class-description "This symbol is returned by " { $link button-delta } " or " { $link buttons-delta } " to represent a button or key being released between two samples of its state." } ;
+
+{ pressed released } related-words
+
 ABOUT: "game-input"
diff --git a/basis/game/input/input-tests.factor b/basis/game/input/input-tests.factor
index bd993bf811..923815328e 100644
--- a/basis/game/input/input-tests.factor
+++ b/basis/game/input/input-tests.factor
@@ -7,3 +7,14 @@ os { [ windows? ] [ macosx? ] } 1|| [
     [ ] [ 1 seconds sleep ] unit-test
     [ ] [ close-game-input ] unit-test
 ] when
+
+[ f        ] [ t t button-delta ] unit-test
+[ pressed  ] [ f t button-delta ] unit-test
+[ released ] [ t f button-delta ] unit-test
+
+[ f        ] [ 0.5 1.0 button-delta ] unit-test
+[ pressed  ] [ f   0.7 button-delta ] unit-test
+[ released ] [ 0.2 f   button-delta ] unit-test
+
+[  { pressed f f released } ] [ { f t f t } { t t f f }      buttons-delta    ] unit-test
+[ V{ pressed f f released } ] [ { f t f t } { t t f f } V{ } buttons-delta-as ] unit-test
diff --git a/basis/game/input/input.factor b/basis/game/input/input.factor
index 8a269cd51a..f27e1f36d1 100644
--- a/basis/game/input/input.factor
+++ b/basis/game/input/input.factor
@@ -90,6 +90,21 @@ TUPLE: mouse-state dx dy scroll-dx scroll-dy buttons ;
 M: mouse-state clone
     call-next-method dup buttons>> clone >>buttons ;
 
+SYMBOLS: pressed released ;
+
+: button-delta ( old? new? -- delta )
+    {
+        { [ 2dup xor not ] [ 2drop f ] }
+        { [ dup  not     ] [ 2drop released ] }
+        { [ over not     ] [ 2drop pressed ] }
+    } cond ; inline
+
+: buttons-delta-as ( old-buttons new-buttons exemplar -- delta )
+    [ button-delta ] swap 2map-as ; inline
+
+: buttons-delta ( old-buttons new-buttons -- delta )
+    { } buttons-delta-as ; inline
+
 {
     { [ os windows? ] [ "game.input.xinput" require ] }
     { [ os macosx? ] [ "game.input.iokit" require ] }

From 271afe3fde888c6ff0c7e79810fde7c02362b231 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sat, 20 Feb 2010 10:47:03 -0800
Subject: [PATCH 119/250] game.loop: separate delegate into tick-delegate and
 draw-delegate

---
 extra/game/loop/loop-docs.factor | 34 ++++++++++++++++++++++++--------
 extra/game/loop/loop.factor      | 12 +++++++----
 2 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/extra/game/loop/loop-docs.factor b/extra/game/loop/loop-docs.factor
index cd8660e465..e4946d160c 100644
--- a/extra/game/loop/loop-docs.factor
+++ b/extra/game/loop/loop-docs.factor
@@ -11,7 +11,20 @@ HELP: <game-loop>
     { "tick-interval-micros" integer } { "delegate" "a " { $link "game.loop-delegates" } }
     { "loop" game-loop }
 }
-{ $description "Constructs a new stopped " { $link game-loop } " object. When started, the game loop will call the " { $link tick* } " method on the " { $snippet "delegate" } " every " { $snippet "tick-interval-micros" } " microseconds, and " { $link draw* } " on the delegate as frequently as possible. The " { $link start-loop } " and " { $link stop-loop } " words start and stop the game loop." } ;
+{ $description "Constructs a new stopped " { $link game-loop } " object. When started, the game loop will call the " { $link tick* } " method on the " { $snippet "delegate" } " every " { $snippet "tick-interval-micros" } " microseconds, and " { $link draw* } " on the same delegate object as frequently as possible. The " { $link start-loop } " and " { $link stop-loop } " words start and stop the game loop."
+$nl
+"To initialize the game loop with separate tick and draw delegates, use " { $link <game-loop*> } "." } ;
+
+HELP: <game-loop*>
+{ $values
+    { "tick-interval-micros" integer } { "tick-delegate" "a " { $link "game.loop-delegates" } } { "draw-delegate" "a " { $link "game.loop-delegates" } }
+    { "loop" game-loop }
+}
+{ $description "Constructs a new stopped " { $link game-loop } " object. When started, the game loop will call the " { $link tick* } " method on the " { $snippet "tick-delegate" } " every " { $snippet "tick-interval-micros" } " microseconds, and " { $link draw* } " on the " { $snippet "draw-delegate" } " as frequently as possible. The " { $link start-loop } " and " { $link stop-loop } " words start and stop the game loop."
+$nl
+"The " { $link <game-loop> } " word provides a shorthand for initializing a game loop that uses the same object for the " { $snippet "tick-delegate" } " and " { $snippet "draw-delegate" } "." } ;
+
+{ <game-loop> <game-loop*> } related-words
 
 HELP: benchmark-frames-per-second
 { $values
@@ -25,7 +38,7 @@ HELP: benchmark-ticks-per-second
     { "loop" game-loop }
     { "n" float }
 }
-{ $description "Returns the average number of times per second the game loop has called " { $link tick* } " on its delegate since the game loop was started with " { $link start-loop } " or since the benchmark counters have been reset with " { $link reset-loop-benchmark } "." } ;
+{ $description "Returns the average number of times per second the game loop has called " { $link tick* } " on its tick delegate since the game loop was started with " { $link start-loop } " or since the benchmark counters have been reset with " { $link reset-loop-benchmark } "." } ;
 
 { reset-loop-benchmark benchmark-frames-per-second benchmark-ticks-per-second } related-words
 
@@ -33,10 +46,12 @@ HELP: draw*
 { $values
     { "tick-slice" float } { "delegate" "a " { $link "game.loop-delegates" } }
 }
-{ $description "This generic word is called by a " { $link game-loop } " on its " { $snippet "delegate" } " object in a tight loop while the game loop is running. The " { $snippet "tick-slice" } " value represents what fraction of the game loop's " { $snippet "tick-interval-micros" } " time period has passed since " { $link tick* } " was most recently called on the delegate." } ;
+{ $description "This generic word is called by a " { $link game-loop } " on its " { $snippet "draw-delegate" } " object in a tight loop while the game loop is running. The " { $snippet "tick-slice" } " value represents what fraction of the game loop's " { $snippet "tick-interval-micros" } " time period has passed since " { $link tick* } " was most recently called on the " { $snippet "tick-delegate" } "." } ;
 
 HELP: game-loop
-{ $class-description "Objects of the " { $snippet "game-loop" } " class manage game loops. See " { $link "game.loop" } " for an overview of the game loop library. To construct a game loop, use " { $link <game-loop> } ". To start and stop a game loop, use the " { $link start-loop } " and " { $link stop-loop } " words." } ;
+{ $class-description "Objects of the " { $snippet "game-loop" } " class manage game loops. See " { $link "game.loop" } " for an overview of the game loop library. To construct a game loop, use " { $link <game-loop> } ". To start and stop a game loop, use the " { $link start-loop } " and " { $link stop-loop } " words."
+$nl
+"The " { $snippet "tick-delegate" } " and " { $snippet "draw-delegate" } " slots of a game loop object determine where the loop sends its " { $link tick* } " and " { $link draw* } " events. These slots can be changed while the game loop is running." } ;
 
 HELP: game-loop-error
 { $values
@@ -68,23 +83,26 @@ HELP: tick*
 { $values
     { "delegate" "a " { $link "game.loop-delegates" } }
 }
-{ $description "This generic word is called by a " { $link game-loop } " on its " { $snippet "delegate" } " object at regular intervals while the game loop is running. The game loop's " { $snippet "tick-interval-micros" } " attribute determines the number of microseconds between invocations of " { $snippet "tick*" } "." } ;
+{ $description "This generic word is called by a " { $link game-loop } " on its " { $snippet "tick-delegate" } " object at regular intervals while the game loop is running. The game loop's " { $snippet "tick-interval-micros" } " attribute determines the number of microseconds between invocations of " { $snippet "tick*" } "." } ;
 
 { draw* tick* } related-words
 
 ARTICLE: "game.loop-delegates" "Game loop delegate"
-"A " { $link game-loop } " object requires a " { $snippet "delegate" } " that implements the logic that controls the game. A game loop delegate can be any object that provides two methods for the following generic words:"
+"A " { $link game-loop } " object requires a " { $snippet "tick-delegate" } " and " { $snippet "draw-delegate" } " that together implement the logic that controls the game. Both delegates can also be the same object. A game loop delegate can be any object that provides two methods for the following generic words:"
 { $subsections
     tick*
     draw*
 }
-{ $snippet "tick*" } " will be called at a regular interval determined by the game loop's " { $snippet "tick-interval-micros" } " attribute. " { $snippet "draw*" } " will be invoked in a tight loop, updating as frequently as possible." ;
+{ $snippet "tick*" } " will be called at a regular interval determined by the game loop's " { $snippet "tick-interval-micros" } " attribute on the tick delegate. " { $snippet "draw*" } " will be invoked on the draw delegate in a tight loop, updating as frequently as possible."
+$nl
+"It is possible to change the " { $snippet "tick-delegate" } " and " { $snippet "draw-delegate" } " slots of a game loop while it is running, for example, to use different delegates to control a game while it's in the menu, paused, or running the main game." ;
 
 ARTICLE: "game.loop" "Game loops"
-"The " { $vocab-link "game.loop" } " vocabulary contains the implementation of a game loop. The game loop supports decoupled rendering and game logic timers; given a delegate object with methods on the " { $link tick* } " and " { $link draw* } " methods, the game loop will invoke the " { $snippet "tick*" } " method at regular intervals while invoking the " { $snippet "draw*" } " method as frequently as possible. Game loop objects must first be constructed:"
+"The " { $vocab-link "game.loop" } " vocabulary contains the implementation of a game loop. The game loop supports decoupled rendering and game logic timers; given a \"tick delegate\" object with a method on the " { $link tick* } " generic and a \"draw delegate\" with a " { $link draw* } " method, the game loop will invoke the " { $snippet "tick*" } " method on the former at regular intervals while invoking the " { $snippet "draw*" } " method on the latter as frequently as possible. Game loop objects must first be constructed:"
 { $subsections
     "game.loop-delegates"
     <game-loop>
+    <game-loop*>
 }
 "Once constructed, the game loop can be started and stopped:"
 { $subsections
diff --git a/extra/game/loop/loop.factor b/extra/game/loop/loop.factor
index afe011cb7b..9e46535b4e 100644
--- a/extra/game/loop/loop.factor
+++ b/extra/game/loop/loop.factor
@@ -6,7 +6,8 @@ IN: game.loop
 
 TUPLE: game-loop
     { tick-interval-micros integer read-only }
-    delegate
+    tick-delegate
+    draw-delegate
     { last-tick integer }
     thread 
     { running? boolean }
@@ -46,10 +47,10 @@ TUPLE: game-loop-error game-loop error ;
 
 : redraw ( loop -- )
     [ 1 + ] change-frame-number
-    [ tick-slice ] [ delegate>> ] bi draw* ;
+    [ tick-slice ] [ draw-delegate>> ] bi draw* ;
 
 : tick ( loop -- )
-    delegate>> tick* ;
+    tick-delegate>> tick* ;
 
 : increment-tick ( loop -- )
     [ 1 + ] change-tick-number
@@ -101,10 +102,13 @@ PRIVATE>
     f >>thread
     drop ;
 
-: <game-loop> ( tick-interval-micros delegate -- loop )
+: <game-loop*> ( tick-interval-micros tick-delegate draw-delegate -- loop )
     system-micros f f 0 0 system-micros 0 0
     game-loop boa ;
 
+: <game-loop> ( tick-interval-micros delegate -- loop )
+    dup <game-loop*> ; inline
+
 M: game-loop dispose
     stop-loop ;
 

From 41afc11ccab73524a12b83704e7cb51210802d87 Mon Sep 17 00:00:00 2001
From: Aaron Schaefer <aaron@elasticdog.com>
Date: Sat, 20 Feb 2010 13:15:46 -0600
Subject: [PATCH 120/250] minor poker vocab cleanup

---
 extra/poker/poker-tests.factor | 3 +--
 extra/poker/poker.factor       | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/extra/poker/poker-tests.factor b/extra/poker/poker-tests.factor
index fc10a13659..18f596c0e0 100644
--- a/extra/poker/poker-tests.factor
+++ b/extra/poker/poker-tests.factor
@@ -1,5 +1,4 @@
-USING: accessors kernel math math.order poker poker.private
-tools.test ;
+USING: accessors kernel math math.order poker poker.private tools.test ;
 IN: poker.tests
 
 [ 134236965 ] [ "KD" >ckf ] unit-test
diff --git a/extra/poker/poker.factor b/extra/poker/poker.factor
index 59f50509e4..b33b8e5710 100644
--- a/extra/poker/poker.factor
+++ b/extra/poker/poker.factor
@@ -1,5 +1,4 @@
-! Copyright (c) 2009 Aaron Schaefer. All rights reserved.
-! Copyright (c) 2009 Doug Coleman.
+! Copyright (c) 2009 Aaron Schaefer, Doug Coleman. All rights reserved.
 ! The contents of this file are licensed under the Simplified BSD License
 ! A copy of the license is available at http://factorcode.org/license.txt
 USING: accessors arrays ascii assocs binary-search combinators

From e26393394d89f7d29784f36defea18a4282f3654 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sun, 21 Feb 2010 16:21:54 +1300
Subject: [PATCH 121/250] tools.crossref: fix method cross-referencing

---
 basis/tools/crossref/crossref.factor | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/basis/tools/crossref/crossref.factor b/basis/tools/crossref/crossref.factor
index 50034822b2..30ec4b2b65 100644
--- a/basis/tools/crossref/crossref.factor
+++ b/basis/tools/crossref/crossref.factor
@@ -61,18 +61,17 @@ M: pathname uses string>> source-file top-level-form>> [ uses ] [ { } ] if* ;
 ! To make UI browser happy
 M: vocab uses drop f ;
 
-GENERIC: crossref-def ( defspec -- )
-
-M: object crossref-def
+: crossref-def ( defspec -- )
     dup uses crossref get add-vertex ;
 
-M: word crossref-def
-    [ call-next-method ] [ subwords [ crossref-def ] each ] bi ;
-
 : defs-to-crossref ( -- seq )
     [
-        all-words [ generic? not ] filter
+        all-words
+        [ [ generic? not ] filter ]
+        [ [ subwords ] map concat ] bi
+
         all-articles [ >link ] map
+
         source-files get keys [ <pathname> ] map
     ] append-outputs ;
 

From f78e5c74308a84d77e994c9b5c9c918b8a78ab1e Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sun, 21 Feb 2010 16:47:55 +1300
Subject: [PATCH 122/250] ui.text.pango: add a platforms.txt

---
 basis/ui/text/pango/platforms.txt | 4 ++++
 basis/ui/text/pango/tags.txt      | 1 -
 2 files changed, 4 insertions(+), 1 deletion(-)
 create mode 100644 basis/ui/text/pango/platforms.txt
 delete mode 100644 basis/ui/text/pango/tags.txt

diff --git a/basis/ui/text/pango/platforms.txt b/basis/ui/text/pango/platforms.txt
new file mode 100644
index 0000000000..b60912bb4a
--- /dev/null
+++ b/basis/ui/text/pango/platforms.txt
@@ -0,0 +1,4 @@
+linux
+freebsd
+netbsd
+openbsd
diff --git a/basis/ui/text/pango/tags.txt b/basis/ui/text/pango/tags.txt
deleted file mode 100644
index 5d77766703..0000000000
--- a/basis/ui/text/pango/tags.txt
+++ /dev/null
@@ -1 +0,0 @@
-untested

From eab105590be0f1c7b59ae260198eec88e8219796 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sun, 21 Feb 2010 17:00:48 +1300
Subject: [PATCH 123/250] Rename io.launcher.unix.parser to simple-tokenizer
 since ftp.server uses it

---
 basis/ftp/server/server.factor                | 21 ++++++------
 .../launcher/unix/parser/parser-tests.factor  | 33 -------------------
 basis/io/launcher/unix/parser/platforms.txt   |  1 -
 basis/io/launcher/unix/unix.factor            | 11 +++----
 basis/simple-tokenizer/authors.txt            |  1 +
 .../simple-tokenizer-docs.factor              | 13 ++++++++
 .../simple-tokenizer-tests.factor             | 33 +++++++++++++++++++
 .../simple-tokenizer.factor}                  | 10 ++----
 basis/simple-tokenizer/tags.txt               |  1 +
 9 files changed, 66 insertions(+), 58 deletions(-)
 delete mode 100644 basis/io/launcher/unix/parser/parser-tests.factor
 delete mode 100644 basis/io/launcher/unix/parser/platforms.txt
 create mode 100644 basis/simple-tokenizer/authors.txt
 create mode 100644 basis/simple-tokenizer/simple-tokenizer-docs.factor
 create mode 100644 basis/simple-tokenizer/simple-tokenizer-tests.factor
 rename basis/{io/launcher/unix/parser/parser.factor => simple-tokenizer/simple-tokenizer.factor} (62%)
 create mode 100644 basis/simple-tokenizer/tags.txt

diff --git a/basis/ftp/server/server.factor b/basis/ftp/server/server.factor
index 1077aebf07..f1bc8adef9 100644
--- a/basis/ftp/server/server.factor
+++ b/basis/ftp/server/server.factor
@@ -1,15 +1,14 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors assocs byte-arrays calendar classes
-combinators combinators.short-circuit concurrency.promises
-continuations destructors ftp io io.backend io.directories
-io.encodings io.encodings.binary
-tools.files io.encodings.utf8 io.files io.files.info
-io.pathnames io.launcher.unix.parser io.servers.connection
-io.sockets io.streams.duplex io.streams.string io.timeouts
-kernel make math math.bitwise math.parser namespaces sequences
-splitting threads unicode.case logging calendar.format
-strings io.files.links io.files.types io.encodings.8-bit.latin1 ;
+USING: accessors assocs byte-arrays calendar classes combinators
+combinators.short-circuit concurrency.promises continuations
+destructors ftp io io.backend io.directories io.encodings
+io.encodings.binary tools.files io.encodings.utf8 io.files
+io.files.info io.pathnames io.servers.connection io.sockets
+io.streams.duplex io.streams.string io.timeouts kernel make math
+math.bitwise math.parser namespaces sequences splitting threads
+unicode.case logging calendar.format strings io.files.links
+io.files.types io.encodings.8-bit.latin1 simple-tokenizer ;
 IN: ftp.server
 
 SYMBOL: server
@@ -24,7 +23,7 @@ TUPLE: ftp-command raw tokenized ;
     dup \ <ftp-command> DEBUG log-message
     ftp-command new
         over >>raw
-        swap tokenize-command >>tokenized ;
+        swap tokenize >>tokenized ;
 
 TUPLE: ftp-get path ;
 : <ftp-get> ( path -- obj )
diff --git a/basis/io/launcher/unix/parser/parser-tests.factor b/basis/io/launcher/unix/parser/parser-tests.factor
deleted file mode 100644
index 90504ccac2..0000000000
--- a/basis/io/launcher/unix/parser/parser-tests.factor
+++ /dev/null
@@ -1,33 +0,0 @@
-IN: io.launcher.unix.parser.tests
-USING: io.launcher.unix.parser tools.test ;
-
-[ "" tokenize-command ] must-fail
-[ "   " tokenize-command ] must-fail
-[ V{ "a" } ] [ "a" tokenize-command ] unit-test
-[ V{ "abc" } ] [ "abc" tokenize-command ] unit-test
-[ V{ "abc" } ] [ "abc   " tokenize-command ] unit-test
-[ V{ "abc" } ] [ "   abc" tokenize-command ] unit-test
-[ V{ "abc" "def" } ] [ "abc def" tokenize-command ] unit-test
-[ V{ "abc def" } ] [ "abc\\ def" tokenize-command ] unit-test
-[ V{ "abc\\" "def" } ] [ "abc\\\\ def" tokenize-command ] unit-test
-[ V{ "abc\\ def" } ] [ "\"abc\\\\ def\"" tokenize-command ] unit-test
-[ V{ "abc\\ def" } ] [ "  \"abc\\\\ def\"" tokenize-command ] unit-test
-[ V{ "abc\\ def" "hey" } ] [ "\"abc\\\\ def\" hey" tokenize-command ] unit-test
-[ V{ "abc def" "hey" } ] [ "\"abc def\" \"hey\"" tokenize-command ] unit-test
-[ "\"abc def\" \"hey" tokenize-command ] must-fail
-[ "\"abc def" tokenize-command ] must-fail
-[ V{ "abc def" "h\"ey" } ] [ "\"abc def\" \"h\\\"ey\"  " tokenize-command ] unit-test
-
-[
-    V{
-        "Hello world.app/Contents/MacOS/hello-ui"
-        "-i=boot.macosx-ppc.image"
-        "-include= math compiler ui"
-        "-deploy-vocab=hello-ui"
-        "-output-image=Hello world.app/Contents/Resources/hello-ui.image"
-        "-no-stack-traces"
-        "-no-user-init"
-    }
-] [
-    "\"Hello world.app/Contents/MacOS/hello-ui\" -i=boot.macosx-ppc.image \"-include= math compiler ui\" -deploy-vocab=hello-ui \"-output-image=Hello world.app/Contents/Resources/hello-ui.image\" -no-stack-traces -no-user-init" tokenize-command
-] unit-test
diff --git a/basis/io/launcher/unix/parser/platforms.txt b/basis/io/launcher/unix/parser/platforms.txt
deleted file mode 100644
index 509143d863..0000000000
--- a/basis/io/launcher/unix/parser/platforms.txt
+++ /dev/null
@@ -1 +0,0 @@
-unix
diff --git a/basis/io/launcher/unix/unix.factor b/basis/io/launcher/unix/unix.factor
index d8b55d3d17..aaaccd4719 100644
--- a/basis/io/launcher/unix/unix.factor
+++ b/basis/io/launcher/unix/unix.factor
@@ -1,15 +1,14 @@
-! Copyright (C) 2007, 2008 Slava Pestov.
+! Copyright (C) 2007, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors alien.c-types arrays assocs combinators
 continuations environment io io.backend io.backend.unix
-io.files io.files.private io.files.unix io.launcher
-io.launcher.unix.parser io.pathnames io.ports kernel math
-namespaces sequences strings system threads unix
-unix.process unix.ffi ;
+io.files io.files.private io.files.unix io.launcher io.pathnames
+io.ports kernel math namespaces sequences strings system threads
+unix unix.process unix.ffi simple-tokenizer ;
 IN: io.launcher.unix
 
 : get-arguments ( process -- seq )
-    command>> dup string? [ tokenize-command ] when ;
+    command>> dup string? [ tokenize ] when ;
 
 : assoc>env ( assoc -- env )
     [ "=" glue ] { } assoc>map ;
diff --git a/basis/simple-tokenizer/authors.txt b/basis/simple-tokenizer/authors.txt
new file mode 100644
index 0000000000..1901f27a24
--- /dev/null
+++ b/basis/simple-tokenizer/authors.txt
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/basis/simple-tokenizer/simple-tokenizer-docs.factor b/basis/simple-tokenizer/simple-tokenizer-docs.factor
new file mode 100644
index 0000000000..57e14f09ba
--- /dev/null
+++ b/basis/simple-tokenizer/simple-tokenizer-docs.factor
@@ -0,0 +1,13 @@
+USING: help.markup help.syntax strings ;
+IN: simple-tokenizer
+
+HELP: tokenize
+{ $values { "input" string } { "ast" "a sequence of strings" } }
+{ $description
+    "Tokenize a string. Supported syntax:"
+    { $list
+        { { $snippet "foo bar baz" } " - simple tokens" }
+        { { $snippet "foo\\ bar" } " - token with an escaped space"}
+        { { $snippet "\"foo bar\"" } " - quoted token" }
+    }
+} ;
diff --git a/basis/simple-tokenizer/simple-tokenizer-tests.factor b/basis/simple-tokenizer/simple-tokenizer-tests.factor
new file mode 100644
index 0000000000..3b44f03650
--- /dev/null
+++ b/basis/simple-tokenizer/simple-tokenizer-tests.factor
@@ -0,0 +1,33 @@
+IN: simple-tokenizer.tests
+USING: simple-tokenizer tools.test ;
+
+[ "" tokenize ] must-fail
+[ "   " tokenize ] must-fail
+[ V{ "a" } ] [ "a" tokenize ] unit-test
+[ V{ "abc" } ] [ "abc" tokenize ] unit-test
+[ V{ "abc" } ] [ "abc   " tokenize ] unit-test
+[ V{ "abc" } ] [ "   abc" tokenize ] unit-test
+[ V{ "abc" "def" } ] [ "abc def" tokenize ] unit-test
+[ V{ "abc def" } ] [ "abc\\ def" tokenize ] unit-test
+[ V{ "abc\\" "def" } ] [ "abc\\\\ def" tokenize ] unit-test
+[ V{ "abc\\ def" } ] [ "\"abc\\\\ def\"" tokenize ] unit-test
+[ V{ "abc\\ def" } ] [ "  \"abc\\\\ def\"" tokenize ] unit-test
+[ V{ "abc\\ def" "hey" } ] [ "\"abc\\\\ def\" hey" tokenize ] unit-test
+[ V{ "abc def" "hey" } ] [ "\"abc def\" \"hey\"" tokenize ] unit-test
+[ "\"abc def\" \"hey" tokenize ] must-fail
+[ "\"abc def" tokenize ] must-fail
+[ V{ "abc def" "h\"ey" } ] [ "\"abc def\" \"h\\\"ey\"  " tokenize ] unit-test
+
+[
+    V{
+        "Hello world.app/Contents/MacOS/hello-ui"
+        "-i=boot.macosx-ppc.image"
+        "-include= math compiler ui"
+        "-deploy-vocab=hello-ui"
+        "-output-image=Hello world.app/Contents/Resources/hello-ui.image"
+        "-no-stack-traces"
+        "-no-user-init"
+    }
+] [
+    "\"Hello world.app/Contents/MacOS/hello-ui\" -i=boot.macosx-ppc.image \"-include= math compiler ui\" -deploy-vocab=hello-ui \"-output-image=Hello world.app/Contents/Resources/hello-ui.image\" -no-stack-traces -no-user-init" tokenize
+] unit-test
diff --git a/basis/io/launcher/unix/parser/parser.factor b/basis/simple-tokenizer/simple-tokenizer.factor
similarity index 62%
rename from basis/io/launcher/unix/parser/parser.factor
rename to basis/simple-tokenizer/simple-tokenizer.factor
index bcc5f965e9..f6698a65f0 100644
--- a/basis/io/launcher/unix/parser/parser.factor
+++ b/basis/simple-tokenizer/simple-tokenizer.factor
@@ -1,13 +1,9 @@
-! Copyright (C) 2008 Slava Pestov
+! Copyright (C) 2008, 2010 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: peg peg.ebnf arrays sequences strings kernel ;
-IN: io.launcher.unix.parser
+IN: simple-tokenizer
 
-! Our command line parser. Supported syntax:
-! foo bar baz -- simple tokens
-! foo\ bar -- escaping the space
-! "foo bar" -- quotation
-EBNF: tokenize-command
+EBNF: tokenize
 space = " "
 escaped-char = "\" .:ch => [[ ch ]]
 quoted = '"' (escaped-char | [^"])*:a '"' => [[ a ]]
diff --git a/basis/simple-tokenizer/tags.txt b/basis/simple-tokenizer/tags.txt
new file mode 100644
index 0000000000..8e27be7d61
--- /dev/null
+++ b/basis/simple-tokenizer/tags.txt
@@ -0,0 +1 @@
+text

From 5700d94e2bb649c2027cac16bdd40e959d64716e Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sun, 21 Feb 2010 17:40:05 +1300
Subject: [PATCH 124/250] unix.utilities: remove platforms.txt since its
 portable

---
 basis/unix/utilities/platforms.txt | 1 -
 1 file changed, 1 deletion(-)
 delete mode 100644 basis/unix/utilities/platforms.txt

diff --git a/basis/unix/utilities/platforms.txt b/basis/unix/utilities/platforms.txt
deleted file mode 100644
index 509143d863..0000000000
--- a/basis/unix/utilities/platforms.txt
+++ /dev/null
@@ -1 +0,0 @@
-unix

From 6367c8ec85e1ad2417fa60530371ea3c7557bc45 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sun, 21 Feb 2010 17:40:19 +1300
Subject: [PATCH 125/250] native-thread-test: clean up

---
 core/alien/strings/strings.factor             | 17 ++++++-----
 .../native-thread-test.factor                 | 28 +++++++++----------
 2 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/core/alien/strings/strings.factor b/core/alien/strings/strings.factor
index 15e0370ba0..0ad4f6c85a 100644
--- a/core/alien/strings/strings.factor
+++ b/core/alien/strings/strings.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2008, 2009 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays sequences kernel kernel.private accessors math
 alien.accessors byte-arrays io io.encodings io.encodings.utf8
@@ -37,17 +37,16 @@ M: string string>alien
 
 M: tuple string>alien drop underlying>> ;
 
-HOOK: alien>native-string os ( alien -- string )
+HOOK: native-string-encoding os ( -- encoding ) foldable
 
-M: windows alien>native-string utf16n alien>string ;
+M: unix native-string-encoding utf8 ;
+M: windows native-string-encoding utf16n ;
 
-M: unix alien>native-string utf8 alien>string ;
+: alien>native-string ( alien -- string )
+    native-string-encoding alien>string ; inline
 
-HOOK: native-string>alien os ( string -- alien )
-
-M: windows native-string>alien utf16n string>alien ;
-
-M: unix native-string>alien utf8 string>alien ;
+: native-string>alien ( string -- alien )
+    native-string-encoding string>alien ; inline
 
 : dll-path ( dll -- string )
     path>> alien>native-string ;
diff --git a/extra/native-thread-test/native-thread-test.factor b/extra/native-thread-test/native-thread-test.factor
index 508e590d01..4d0df1f454 100644
--- a/extra/native-thread-test/native-thread-test.factor
+++ b/extra/native-thread-test/native-thread-test.factor
@@ -1,26 +1,24 @@
-USING: alien.c-types alien.syntax io io.encodings.utf16n
-io.encodings.utf8 io.files kernel namespaces sequences system threads
+! Copyright (C) 2009 Phil Dawes.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.c-types alien.strings alien.syntax io
+io.encodings.utf8 io.files kernel sequences system threads
 unix.utilities ;
 IN: native-thread-test
 
 FUNCTION: void* start_standalone_factor_in_new_thread ( int argc, char** argv ) ;
 
-HOOK: native-string-encoding os ( -- encoding )
-M: windows native-string-encoding utf16n ;
-M: unix native-string-encoding utf8 ;
-
 : start-vm-in-os-thread ( args -- threadhandle )
-    \ vm get-global prefix 
+    vm prefix
     [ length ] [ native-string-encoding strings>alien ] bi 
-     start_standalone_factor_in_new_thread ;
+    start_standalone_factor_in_new_thread ;
 
 : start-tetris-in-os-thread ( -- )
-     { "-run=tetris" } start-vm-in-os-thread drop ;
+    { "-run=tetris" } start-vm-in-os-thread drop ;
 
-: start-testthread-in-os-thread ( -- )
-     { "-run=native-thread-test" } start-vm-in-os-thread drop ;
- 
-: testthread ( -- )
-     "/tmp/hello" utf8 [ "hello!\n" write ] with-file-appender 5000000 sleep ;
+: start-test-thread-in-os-thread ( -- )
+    { "-run=native-thread-test" } start-vm-in-os-thread drop ;
 
-MAIN: testthread
+: test-thread ( -- )
+    "/tmp/hello" utf8 [ "hello!\n" write ] with-file-appender 5000000 sleep ;
+
+MAIN: test-thread

From 0161f4e8d2ba2968bc02cfec560bdfff04a029c8 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sun, 21 Feb 2010 17:42:40 +1300
Subject: [PATCH 126/250] io.serial.windows: fix load error

---
 extra/io/serial/windows/windows.factor | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/extra/io/serial/windows/windows.factor b/extra/io/serial/windows/windows.factor
index 645e4939de..4ea3d5e9e4 100644
--- a/extra/io/serial/windows/windows.factor
+++ b/extra/io/serial/windows/windows.factor
@@ -1,9 +1,8 @@
 ! Copyright (C) 2009 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: io.files.windows io.streams.duplex kernel math
-math.bitwise windows.kernel32 accessors alien.c-types
-windows io.files.windows fry locals continuations
-classes.struct ;
+math.bitwise windows windows.kernel32 windows.errors accessors
+alien.c-types fry locals continuations classes.struct ;
 IN: io.serial.windows
 
 : <serial-stream> ( path encoding -- duplex )

From 0e8f3670a3f64d07f5c0e7371ddd978341639797 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sun, 21 Feb 2010 17:46:25 +1300
Subject: [PATCH 127/250] Move windows.dragdrop-listener to unmaintained

---
 .../dragdrop-listener/dragdrop-listener.factor                    | 0
 {basis/windows => unmaintained}/dragdrop-listener/platforms.txt   | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename {basis/windows => unmaintained}/dragdrop-listener/dragdrop-listener.factor (100%)
 rename {basis/windows => unmaintained}/dragdrop-listener/platforms.txt (100%)

diff --git a/basis/windows/dragdrop-listener/dragdrop-listener.factor b/unmaintained/dragdrop-listener/dragdrop-listener.factor
similarity index 100%
rename from basis/windows/dragdrop-listener/dragdrop-listener.factor
rename to unmaintained/dragdrop-listener/dragdrop-listener.factor
diff --git a/basis/windows/dragdrop-listener/platforms.txt b/unmaintained/dragdrop-listener/platforms.txt
similarity index 100%
rename from basis/windows/dragdrop-listener/platforms.txt
rename to unmaintained/dragdrop-listener/platforms.txt

From 536ae3c64856a95f18eb96f62adca63a3b022caa Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Sat, 20 Feb 2010 21:15:47 -0800
Subject: [PATCH 128/250] Unit test checking the stack effects from FUNCTION:.

---
 basis/alien/parser/parser-tests.factor | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/basis/alien/parser/parser-tests.factor b/basis/alien/parser/parser-tests.factor
index e405f49995..2fec2d9a4c 100644
--- a/basis/alien/parser/parser-tests.factor
+++ b/basis/alien/parser/parser-tests.factor
@@ -1,7 +1,7 @@
 ! (c)2009 Joe Groff bsd license
 USING: accessors alien.c-types alien.parser alien.syntax
-tools.test vocabs.parser parser eval vocabs.parser debugger
-continuations ;
+tools.test vocabs.parser parser eval debugger kernel
+continuations words ;
 IN: alien.parser.tests
 
 TYPEDEF: char char2
@@ -34,6 +34,11 @@ CONSTANT: eleven 11
 
 ] with-file-vocabs
 
+FUNCTION: void* alien-parser-effect-test ( int *arg1 float arg2 ) ;
+[ (( arg1 arg2 -- void* )) ] [
+    \ alien-parser-effect-test "declared-effect" word-prop
+] unit-test
+
 ! Reported by mnestic
 TYPEDEF: int alien-parser-test-int ! reasonably unique name...
 

From 22ce5eb45cfd9b51886931d6ad33cd73361212f2 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sat, 20 Feb 2010 21:58:09 -0800
Subject: [PATCH 129/250] adjust wording in game.loop docs

---
 extra/game/loop/loop-docs.factor | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/extra/game/loop/loop-docs.factor b/extra/game/loop/loop-docs.factor
index e4946d160c..b48f01cd82 100644
--- a/extra/game/loop/loop-docs.factor
+++ b/extra/game/loop/loop-docs.factor
@@ -109,13 +109,13 @@ ARTICLE: "game.loop" "Game loops"
     start-loop
     stop-loop
 }
-"The game loop maintains performance counters for measuring drawing frames and ticks per second:"
+"The game loop maintains performance counters:"
 { $subsections
     reset-loop-benchmark
     benchmark-frames-per-second
     benchmark-ticks-per-second
 }
-"The game loop manages errors that occur in the delegate's methods during the course of the game loop:"
+"The game loop catches errors that occur in the delegate's methods during the course of the game loop:"
 { $subsections
     game-loop-error
 }

From 570a2d0b37099ee7c207a8e85176a9781584d481 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sun, 21 Feb 2010 20:19:11 +1300
Subject: [PATCH 130/250] unix.utmpx: fix load errors

---
 basis/unix/utmpx/netbsd/netbsd.factor | 30 +++++++++++++--------------
 basis/unix/utmpx/platforms.txt        |  3 ++-
 2 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/basis/unix/utmpx/netbsd/netbsd.factor b/basis/unix/utmpx/netbsd/netbsd.factor
index 40fce746b1..93092a7cbf 100644
--- a/basis/unix/utmpx/netbsd/netbsd.factor
+++ b/basis/unix/utmpx/netbsd/netbsd.factor
@@ -1,22 +1,20 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.syntax unix.utmpx unix.bsd.netbsd accessors
-unix.utmpx system kernel unix combinators ;
+USING: alien.syntax unix unix.utmpx unix.ffi.bsd.netbsd accessors
+system kernel combinators ;
 IN: unix.utmpx.netbsd
 
-TUPLE: netbsd-utmpx-record < utmpx-record termination exit
-sockaddr ;
-    
+TUPLE: netbsd-utmpx-record < utmpx-record
+termination exit sockaddr ;
+
 M: netbsd new-utmpx-record ( -- utmpx-record )
-    netbsd-utmpx-record new ; 
-    
+    netbsd-utmpx-record new ;
+
 M: netbsd utmpx>utmpx-record ( utmpx -- record )
-    [ new-utmpx-record ] keep
-    {
-        [
-            utmpx-ut_exit
-            [ exit_struct-e_termination >>termination ]
-            [ exit_struct-e_exit >>exit ] bi
-        ]
-        [ utmpx-ut_ss >>sockaddr ]
-    } cleave ;
+    [ new-utmpx-record ] dip
+    [
+        ut_exit>>
+        [ e_termination>> >>termination ]
+        [ e_exit>> >>exit ] bi
+    ]
+    [ ut_ss>> >>sockaddr ] bi ;
diff --git a/basis/unix/utmpx/platforms.txt b/basis/unix/utmpx/platforms.txt
index 509143d863..abe56c1458 100644
--- a/basis/unix/utmpx/platforms.txt
+++ b/basis/unix/utmpx/platforms.txt
@@ -1 +1,2 @@
-unix
+macosx
+netbsd

From 2f70ebd4d02dab0c06835f071b0045b39d624cc2 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sun, 21 Feb 2010 20:38:09 +1300
Subject: [PATCH 131/250] vocabs: document platforms.txt

---
 basis/tools/deploy/deploy-docs.factor      |  2 +-
 basis/vocabs/metadata/metadata-docs.factor | 31 +++++++++++++++++++---
 core/vocabs/loader/loader-docs.factor      | 20 +++++---------
 3 files changed, 34 insertions(+), 19 deletions(-)

diff --git a/basis/tools/deploy/deploy-docs.factor b/basis/tools/deploy/deploy-docs.factor
index a552bd04fb..976fc25357 100755
--- a/basis/tools/deploy/deploy-docs.factor
+++ b/basis/tools/deploy/deploy-docs.factor
@@ -13,7 +13,7 @@ ARTICLE: "prepare-deploy" "Preparing to deploy an application"
 ARTICLE: "deploy-resources" "Deployed resource files"
 "To include additional files in your deployed application, specify their names in a vocabulary's " { $snippet "resources.txt" } " file. The " { $snippet "resources.txt" } " file contains one glob pattern per line. These patterns are expanded relative to the vocabulary directory; files outside of the vocabulary directory cannot be referenced. If a file inside the vocabulary directory matches any of these patterns, it will be included in deployed applications that reference the vocabulary. If a subdirectory matches, its contents will be included recursively."
 $nl
-"If the deployed vocabulary includes an icon file for the current platform (" { $snippet "icon.ico" } " on Windows, or " { $snippet "icon.icns" } " on MacOS X), it will be embedded in the deployed application as its GUI icon." ;
+"If the deployed vocabulary includes an icon file for the current platform, it will be embedded in the deployed application as its GUI icon. See " { $link "vocabs.icons" } "." ;
 
 ARTICLE: "tools.deploy.usage" "Deploy tool usage"
 "Once the necessary deployment flags have been set, the application can be deployed:"
diff --git a/basis/vocabs/metadata/metadata-docs.factor b/basis/vocabs/metadata/metadata-docs.factor
index 95c8083e0f..c3dce45c09 100644
--- a/basis/vocabs/metadata/metadata-docs.factor
+++ b/basis/vocabs/metadata/metadata-docs.factor
@@ -2,23 +2,36 @@ USING: help.markup help.syntax strings ;
 IN: vocabs.metadata
 
 ARTICLE: "vocabs.metadata" "Vocabulary metadata"
-"Vocabulary summaries:"
+"Vocabulary directories can contain text files with metadata:"
+{ $list
+    { { $snippet "authors.txt" } " - a series of lines, with one author name per line. These are listed under " { $link "vocab-authors" } "." }
+    { { $snippet "platforms.txt" } " - a series of lines, with one operating system name per line." }
+    { { $snippet "resources.txt" } " - a series of lines, with one file glob pattern per line. Files inside the vocabulary directory whose names match any of these glob patterns will be included with the compiled application as " { $link "deploy-resources" } "." }
+    { { $snippet "summary.txt" } " - a one-line description." }
+    { { $snippet "tags.txt" } " - a series of lines, with one tag per line. Tags help classify the vocabulary. Consult " { $link "vocab-tags" } " for a list of existing tags you can reuse." }
+}
+"Words for reading and writing " { $snippet "summary.txt" } ":"
 { $subsections
     vocab-summary
     set-vocab-summary
 }
-"Vocabulary authors:"
+"Words for reading and writing " { $snippet "authors.txt" } ":"
 { $subsections
     vocab-authors
     set-vocab-authors
 }
-"Vocabulary tags:"
+"Words for reading and writing " { $snippet "tags.txt" } ":"
 { $subsections
     vocab-tags
     set-vocab-tags
     add-vocab-tags
 }
-"Vocabulary resources:"
+"Words for reading and writing " { $snippet "platforms.txt" } ":"
+{ $subsections
+    vocab-platforms
+    set-vocab-platforms
+}
+"Words for reading and writing " { $snippet "resources.txt" } ":"
 { $subsections
     vocab-resources
     set-vocab-resources
@@ -55,6 +68,16 @@ HELP: set-vocab-tags
 { $values { "tags" "a sequence of strings" } { "vocab" "a vocabulary specifier" } }
 { $description "Stores a list of short tags classifying the vocabulary to the " { $snippet "tags.txt" } " file in the vocabulary's directory." } ;
 
+HELP: vocab-platforms
+{ $values { "vocab" "a vocabulary specifier" } { "platforms" "a sequence of operating system symbols" } }
+{ $description "Outputs a list of operating systems supported by " { $snippet "vocab" } ", as specified by the " { $snippet "platforms.txt" } " file in the vocabulary's directory. Outputs an empty array if the file doesn't exist." }
+{ $notes "Operating system symbols are defined in the " { $vocab-link "system" } " vocabulary." } ;
+
+HELP: set-vocab-platforms
+{ $values { "platforms" "a sequence of operating system symbols" } { "vocab" "a vocabulary specifier" } }
+{ $description "Stores a list of operating systems supported by " { $snippet "vocab" } " to the " { $snippet "platforms.txt" } " file in the vocabulary's directory." }
+{ $notes "Operating system symbols are defined in the " { $vocab-link "system" } " vocabulary." } ;
+
 HELP: vocab-resources
 { $values { "vocab" "a vocabulary specifier" } { "patterns" "a sequence of glob patterns" } }
 { $description "Outputs a list of glob patterns matching files that will be deployed with an application that includes " { $snippet "vocab" } ", as specified by the " { $snippet "resources.txt" } " file in the vocabulary's directory. Outputs an empty array if the file doesn't exist." }
diff --git a/core/vocabs/loader/loader-docs.factor b/core/vocabs/loader/loader-docs.factor
index ce4a319a42..08ab729b6d 100755
--- a/core/vocabs/loader/loader-docs.factor
+++ b/core/vocabs/loader/loader-docs.factor
@@ -27,10 +27,11 @@ ARTICLE: "vocabs.roots" "Vocabulary roots"
 "You can store your own vocabularies in the " { $snippet "work" } " directory."
 { $subsections "add-vocab-roots" } ;
 
+ARTICLE: "vocabs.icons" "Vocabulary icons"
+"An icon file representing the vocabulary can be provided for use by " { $link "tools.deploy" } ". A file named " { $snippet "icon.ico" } " will be used as the application icon when the application is deployed on Windows. A file named " { $snippet "icon.icns" } " will be used when the application is deployed on MacOS X." ;
+
 ARTICLE: "vocabs.loader" "Vocabulary loader"
-"The vocabulary loader combines the vocabulary system with " { $link "parser" } " in order to implement automatic loading of vocabulary source files. The vocabulary loader is implemented in the " { $vocab-link "vocabs.loader" } " vocabulary."
-$nl
-"When an attempt is made to use a vocabulary that has not been loaded into the image, the vocabulary loader is asked to locate the vocabulary's source files, and load them."
+"The " { $link POSTPONE: USE: } " and " { $link POSTPONE: USING: } " words load vocabularies using the vocabulary loader. The vocabulary loader is implemented in the " { $vocab-link "vocabs.loader" } " vocabulary."
 $nl
 "The vocabulary loader searches for vocabularies in a set of directories known as vocabulary roots."
 { $subsections "vocabs.roots" }
@@ -45,17 +46,8 @@ $nl
     { { $snippet "foo/bar/bar-docs.factor" } " - documentation, see " { $link "writing-help" } }
     { { $snippet "foo/bar/bar-tests.factor" } " - unit tests, see " { $link "tools.test" } }
 }
-"Finally, four optional text files may contain metadata:"
-{ $list
-    { { $snippet "foo/bar/authors.txt" } " - a series of lines, with one author name per line. These are listed under " { $link "vocab-authors" } "." }
-    { { $snippet "foo/bar/resources.txt" } " - a series of lines with one file glob pattern per line. Files inside the vocabulary directory whose names match any of these glob patterns will be included with the compiled application as " { $link "deploy-resources" } "." }
-    { { $snippet "foo/bar/summary.txt" } " - a one-line description." }
-    { { $snippet "foo/bar/tags.txt" } " - a whitespace-separated list of tags which classify the vocabulary. Consult " { $link "vocab-tags" } " for a list of existing tags you can reuse." }
-}
-"An icon file representing the vocabulary can also be provided. A file named " { $snippet "icon.ico" } " will be used as the application icon when the application is deployed on Windows. A file named " { $snippet "icon.icns" } " will be used when the application is deployed on MacOS X."
-$nl
-"The " { $link POSTPONE: USE: } " and " { $link POSTPONE: USING: } " words load vocabularies which have not been loaded yet, as needed."
-$nl
+"Optional text files may contain metadata."
+{ $subsections "vocabs.metadata" "vocabs.icons" }
 "Vocabularies can also be loaded at run time, without altering the vocabulary search path. This is done by calling a word which loads a vocabulary if it is not in the image, doing nothing if it is:"
 { $subsections require }
 "The above word will only ever load a vocabulary once in a given session. There is another word which unconditionally loads vocabulary from disk, regardless of whether or not is has already been loaded:"

From 0da6f780888e85ab01b706ade6b98dc9e8093735 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Sun, 21 Feb 2010 22:27:32 +1300
Subject: [PATCH 132/250] cocoa.messages: if a class cannot be found, IMPORT:
 no longer fails at parse time. Instead, there will be a runtime error when
 the class word is executed

---
 basis/cocoa/messages/messages.factor | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/basis/cocoa/messages/messages.factor b/basis/cocoa/messages/messages.factor
index 02e6335c54..eab301add7 100644
--- a/basis/cocoa/messages/messages.factor
+++ b/basis/cocoa/messages/messages.factor
@@ -76,13 +76,13 @@ MACRO: (send) ( selector super? -- quot )
 : super-send ( receiver args... selector -- return... ) t (send) ; inline
 
 ! Runtime introspection
-SYMBOL: class-startup-hooks
+SYMBOL: class-init-hooks
 
-class-startup-hooks [ H{ } clone ] initialize
+class-init-hooks [ H{ } clone ] initialize
 
 : (objc-class) ( name word -- class )
     2dup execute dup [ 2nip ] [
-        drop over class-startup-hooks get at [ call( -- ) ] when*
+        drop over class-init-hooks get at [ call( -- ) ] when*
         2dup execute dup [ 2nip ] [
             2drop "No such class: " prepend throw
         ] if
@@ -229,7 +229,7 @@ ERROR: no-objc-type name ;
 : class-exists? ( string -- class ) objc_getClass >boolean ;
 
 : define-objc-class-word ( quot name -- )
-    [ class-startup-hooks get set-at ]
+    [ class-init-hooks get set-at ]
     [
         [ "cocoa.classes" create ] [ '[ _ objc-class ] ] bi
         (( -- class )) define-declared
@@ -237,8 +237,10 @@ ERROR: no-objc-type name ;
 
 : import-objc-class ( name quot -- )
     over define-objc-class-word
-    [ objc-class register-objc-methods ]
-    [ objc-meta-class register-objc-methods ] bi ;
+    dup objc_getClass [
+        [ objc-class register-objc-methods ]
+        [ objc-meta-class register-objc-methods ] bi
+    ] [ drop ] if ;
 
 : root-class ( class -- root )
     dup class_getSuperclass [ root-class ] [ ] ?if ;

From bb3665f37e7a7f9a101ff88c7820ec5d37d8c8cb Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Sun, 21 Feb 2010 03:27:16 -0800
Subject: [PATCH 133/250] FUEL: Flip the default behavior of visit-other-file
 so that it does not try to create -docs or -tests files if they do not exist
 by default. This is the more common case when spelunking in code and in
 general you want to scaffold those files anyway.

---
 misc/fuel/factor-mode.el | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/misc/fuel/factor-mode.el b/misc/fuel/factor-mode.el
index bef6e4c774..c26abab997 100644
--- a/misc/fuel/factor-mode.el
+++ b/misc/fuel/factor-mode.el
@@ -245,11 +245,11 @@ code in the buffer."
 (defsubst factor-mode--in-tests (&optional file)
   (factor-mode--code-file "tests"))
 
-(defun factor-mode-visit-other-file (&optional skip)
+(defun factor-mode-visit-other-file (&optional create)
   "Cycle between code, tests and docs factor files.
-With prefix, non-existing files will be skipped."
+With prefix, non-existing files will be created."
   (interactive "P")
-  (let ((file (factor-mode--cycle-next (buffer-file-name) skip)))
+  (let ((file (factor-mode--cycle-next (buffer-file-name) (not create))))
     (unless file (error "No other file found"))
     (find-file file)
     (unless (file-exists-p file)

From ffddca36b74ea54be2f52b8ada2b0e17802a3582 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Sun, 21 Feb 2010 03:34:08 -0800
Subject: [PATCH 134/250] Add scaffolding words for tags, summary and authors
 and hook these up to FUEL. Modified fuel-scaffold-vocab to prompt the user
 for tags, summary and whether to create help and test files immediately.

---
 basis/tools/scaffold/scaffold-docs.factor | 26 ++++++-
 basis/tools/scaffold/scaffold.factor      | 27 +++++--
 basis/vocabs/files/files-docs.factor      |  8 +++
 basis/vocabs/files/files.factor           |  6 +-
 extra/fuel/fuel.factor                    | 19 ++++-
 misc/fuel/fuel-scaffold.el                | 88 ++++++++++++++++++++++-
 6 files changed, 159 insertions(+), 15 deletions(-)

diff --git a/basis/tools/scaffold/scaffold-docs.factor b/basis/tools/scaffold/scaffold-docs.factor
index f4200f8cb2..4476f5ec9f 100644
--- a/basis/tools/scaffold/scaffold-docs.factor
+++ b/basis/tools/scaffold/scaffold-docs.factor
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.syntax kernel strings words vocabs ;
+USING: help.markup help.syntax kernel strings words vocabs sequences ;
 IN: tools.scaffold
 
 HELP: developer-name
@@ -23,6 +23,30 @@ HELP: scaffold-undocumented
 
 { scaffold-help scaffold-undocumented } related-words
 
+HELP: scaffold-authors
+{ $values
+    { "vocab" "a vocabulary specifier" }
+}
+{ $description "Creates an authors.txt file using the value in " { $link developer-name } ". This word only works if no authors.txt file yet exists." } ;
+
+HELP: scaffold-summary
+{ $values
+    { "vocab" "a vocabulary specifier" } { "summary" string }
+}
+{ $description "Creates a summary.txt file with the given summary. This word only works if no summary.txt file yet exists." } ;
+
+HELP: scaffold-tags
+{ $values
+    { "vocab" "a vocabulary specifier" } { "tags" string }
+}
+{ $description "Creates a tags.txt file with the given tags. This word only works if no tags.txt file yet exists." } ;
+
+HELP: scaffold-tests
+{ $values
+    { "vocab" "a vocabulary specifier" }
+}
+{ $description "Takes an existing vocabulary and creates an empty tests file help for each word. This word only works if no tests file yet exists." } ;
+
 HELP: scaffold-vocab
 { $values
      { "vocab-root" "a vocabulary root string" } { "string" string } }
diff --git a/basis/tools/scaffold/scaffold.factor b/basis/tools/scaffold/scaffold.factor
index 936d388b01..151d98a134 100644
--- a/basis/tools/scaffold/scaffold.factor
+++ b/basis/tools/scaffold/scaffold.factor
@@ -63,6 +63,9 @@ M: bad-developer-name summary
 : vocab-root/vocab/suffix>path ( vocab-root vocab suffix -- path )
     [ vocab-root/vocab>path dup file-name append-path ] dip append ;
 
+: vocab/file>path ( vocab file -- path )
+    [ vocab>path ] dip append-path ;
+
 : vocab/suffix>path ( vocab suffix -- path )
     [ vocab>path dup file-name append-path ] dip append ;
 
@@ -104,16 +107,17 @@ M: bad-developer-name summary
         2drop
     ] if ;
 
-: scaffold-authors ( vocab-root vocab -- )
-    developer-name get [
-        "authors.txt" vocab-root/vocab/file>path scaffolding? [
-            developer-name get swap utf8 set-file-contents
+: scaffold-metadata ( vocab file contents -- )
+    [ ensure-vocab-exists ] 2dip
+    [
+        [ vocab/file>path ] dip swap scaffolding? [
+            utf8 set-file-contents
         ] [
-            drop
+            2drop
         ] if
     ] [
         2drop
-    ] if ;
+    ] if* ;
 
 : lookup-type ( string -- object/string ? )
     "new" ?head drop [ { [ CHAR: ' = ] [ digit? ] } 1|| ] trim-tail
@@ -258,12 +262,21 @@ PRIVATE>
 : scaffold-undocumented ( string -- )
     [ interesting-words. ] [ link-vocab ] bi ;
 
+: scaffold-authors ( vocab -- )
+    "authors.txt" developer-name get scaffold-metadata ;
+
+: scaffold-tags ( vocab tags -- )
+    [ "tags.txt" ] dip scaffold-metadata ;
+
+: scaffold-summary ( vocab summary -- )
+    [ "summary.txt" ] dip scaffold-metadata ;
+
 : scaffold-vocab ( vocab-root string -- )
     {
         [ scaffold-directory ]
         [ scaffold-main ]
-        [ scaffold-authors ]
         [ nip require ]
+        [ nip scaffold-authors ]
     } 2cleave ;
 
 : scaffold-core ( string -- ) "resource:core" swap scaffold-vocab ;
diff --git a/basis/vocabs/files/files-docs.factor b/basis/vocabs/files/files-docs.factor
index e2c6a5f373..61a2e68707 100644
--- a/basis/vocabs/files/files-docs.factor
+++ b/basis/vocabs/files/files-docs.factor
@@ -1,6 +1,14 @@
 USING: help.markup help.syntax strings ;
 IN: vocabs.files
 
+HELP: vocab-tests-file
+{ $values { "vocab" "a vocabulary specifier" } { "path" "pathname string to test file" } }
+{ $description "Outputs a pathname where the unit test file is located." } ;
+
+HELP: vocab-tests-dir
+{ $values { "vocab" "a vocabulary specifier" } { "paths" "a sequence of pathname strings" } }
+{ $description "Outputs a sequence of pathnames for the tests in the test directory." } ;
+
 HELP: vocab-files
 { $values { "vocab" "a vocabulary specifier" } { "seq" "a sequence of pathname strings" } }
 { $description "Outputs a sequence of files comprising this vocabulary, or " { $link f } " if the vocabulary does not have a directory on disk." } ;
diff --git a/basis/vocabs/files/files.factor b/basis/vocabs/files/files.factor
index c1d7dcfd59..1c3e3731bd 100644
--- a/basis/vocabs/files/files.factor
+++ b/basis/vocabs/files/files.factor
@@ -4,8 +4,6 @@ USING: io.directories io.files io.pathnames kernel make
 sequences vocabs.loader ;
 IN: vocabs.files
 
-<PRIVATE
-
 : vocab-tests-file ( vocab -- path )
     dup "-tests.factor" vocab-dir+ vocab-append-path dup
     [ dup exists? [ drop f ] unless ] [ drop f ] if ;
@@ -18,8 +16,6 @@ IN: vocabs.files
         ] [ drop f ] if
     ] [ drop f ] if ;
 
-PRIVATE>
-
 : vocab-tests ( vocab -- tests )
     [
         [ vocab-tests-file [ , ] when* ]
@@ -31,4 +27,4 @@ PRIVATE>
         [ vocab-source-path [ , ] when* ]
         [ vocab-docs-path [ , ] when* ]
         [ vocab-tests % ] tri
-    ] { } make ;
\ No newline at end of file
+    ] { } make ;
diff --git a/extra/fuel/fuel.factor b/extra/fuel/fuel.factor
index d64ef41f8c..2934d5d43c 100644
--- a/extra/fuel/fuel.factor
+++ b/extra/fuel/fuel.factor
@@ -3,7 +3,8 @@
 
 USING: accessors assocs compiler.units continuations fuel.eval fuel.help
 fuel.remote fuel.xref help.topics io.pathnames kernel namespaces parser
-sequences tools.scaffold vocabs.loader vocabs.parser words ;
+sequences tools.scaffold vocabs.loader vocabs.parser words vocabs.files
+vocabs.metadata ;
 
 IN: fuel
 
@@ -145,6 +146,22 @@ PRIVATE>
     [ fuel-scaffold-name dup require dup scaffold-help ] with-scope
     vocab-docs-path absolute-path fuel-eval-set-result ;
 
+: fuel-scaffold-tests ( name devname -- )
+    [ fuel-scaffold-name dup require dup scaffold-tests ] with-scope
+    vocab-tests-file absolute-path fuel-eval-set-result ;
+
+: fuel-scaffold-authors ( name devname -- )
+    [ fuel-scaffold-name dup require dup scaffold-authors ] with-scope
+    [ vocab-authors-path ] keep swap vocab-append-path absolute-path fuel-eval-set-result ;
+
+: fuel-scaffold-tags ( name tags -- )
+    [ scaffold-tags ]
+    [ drop [ vocab-tags-path ] keep swap vocab-append-path absolute-path fuel-eval-set-result ] 2bi ;
+
+: fuel-scaffold-summary ( name summary -- )
+    [ scaffold-summary ]
+    [ drop [ vocab-summary-path ] keep swap vocab-append-path absolute-path fuel-eval-set-result ] 2bi ;
+
 : fuel-scaffold-get-root ( name -- ) find-vocab-root fuel-eval-set-result ;
 
 ! Remote connection
diff --git a/misc/fuel/fuel-scaffold.el b/misc/fuel/fuel-scaffold.el
index 9b7d9861c7..9e8e56475d 100644
--- a/misc/fuel/fuel-scaffold.el
+++ b/misc/fuel/fuel-scaffold.el
@@ -79,6 +79,25 @@ IN: %s
                       "fuel")))
     (fuel-eval--send/wait cmd)))
 
+(defsubst fuel-scaffold--create-tests (vocab)
+  (let ((cmd `(:fuel* (,vocab ,fuel-scaffold-developer-name fuel-scaffold-tests)
+                      "fuel")))
+    (fuel-eval--send/wait cmd)))
+
+(defsubst fuel-scaffold--create-authors (vocab)
+  (let ((cmd `(:fuel* (,vocab ,fuel-scaffold-developer-name fuel-scaffold-authors) "fuel")))
+    (fuel-eval--send/wait cmd)))
+
+(defsubst fuel-scaffold--create-tags (vocab tags)
+  (let ((cmd `(:fuel* (,vocab ,tags fuel-scaffold-tags) "fuel")))
+    (fuel-eval--send/wait cmd)))
+
+(defsubst fuel-scaffold--create-summary (vocab summary)
+  (let ((cmd `(:fuel* (,vocab ,summary fuel-scaffold-summary) "fuel")))
+    (fuel-eval--send/wait cmd)))
+
+(defsubst fuel-scaffold--creaet-
+
 (defun fuel-scaffold--help (parent)
   (when (and parent (fuel-scaffold--check-auto fuel-scaffold-help-autoinsert-p))
     (let* ((ret (fuel-scaffold--create-docs (fuel-scaffold--vocab parent)))
@@ -102,7 +121,8 @@ IN: %s
 
 (defun fuel-scaffold-vocab (&optional other-window name-hint root-hint)
   "Creates a directory in the given root for a new vocabulary and
-adds source, tests and authors.txt files.
+adds source and authors.txt files. Prompts the user for optional summary,
+tags, help, and test file creation.
 
 You can configure `fuel-scaffold-developer-name' (set by default to
 `user-full-name') for the name to be inserted in the generated files."
@@ -111,12 +131,24 @@ You can configure `fuel-scaffold-developer-name' (set by default to
          (root (completing-read "Vocab root: "
                                 (fuel-scaffold--vocab-roots)
                                 nil t (or root-hint "resource:")))
+         (summary (read-string "Vocab summary (empty for none): "))
+         (tags (read-string "Vocab tags (empty for none): "))
+         (help (y-or-n-p "Scaffold help? "))
+         (tests (y-or-n-p "Scaffold tests? "))
          (cmd `(:fuel* ((,root ,name ,fuel-scaffold-developer-name)
                         (fuel-scaffold-vocab)) "fuel"))
          (ret (fuel-eval--send/wait cmd))
          (file (fuel-eval--retort-result ret)))
     (unless file
       (error "Error creating vocab (%s)" (car (fuel-eval--retort-error ret))))
+    (when (not (equal "" summary))
+      (fuel-scaffold--create-summary name summary))
+    (when (not (equal "" tags))
+      (fuel-scaffold--create-tags name tags))
+    (when help
+         (fuel-scaffold--create-docs name))
+    (when tests
+         (fuel-scaffold--create-tests name))
     (if other-window (find-file-other-window file) (find-file file))
     (goto-char (point-max))
     name))
@@ -137,6 +169,60 @@ You can configure `fuel-scaffold-developer-name' (set by default to
           (error "Error creating help file" (car (fuel-eval--retort-error ret))))
         (find-file file)))
 
+(defun fuel-scaffold-tests (&optional arg)
+  "Creates, if it does not already exist, a tests file for the current vocabulary.
+
+With prefix argument, ask for the vocabulary name.
+You can configure `fuel-scaffold-developer-name' (set by default to
+`user-full-name') for the name to be inserted in the generated file."
+  (interactive "P")
+  (let* ((vocab (or (and (not arg) (fuel-syntax--current-vocab))
+                    (fuel-completion--read-vocab nil)))
+         (ret (fuel-scaffold--create-tests vocab))
+         (file (fuel-eval--retort-result ret)))
+        (unless file
+          (error "Error creating tests file" (car (fuel-eval--retort-error ret))))
+        (find-file file)))
+
+(defun fuel-scaffold-authors (&optional arg)
+  "Creates, if it does not already exist, an authors file for the current vocabulary.
+
+With prefix argument, ask for the vocabulary name.
+You can configure `fuel-scaffold-developer-name' (set by default to
+`user-full-name') for the name to be inserted in the generated file."
+  (interactive "P")
+  (let* ((vocab (or (and (not arg) (fuel-syntax--current-vocab))
+                    (fuel-completion--read-vocab nil)))
+         (ret (fuel-scaffold--create-authors vocab))
+         (file (fuel-eval--retort-result ret)))
+        (unless file
+          (error "Error creating authors file" (car (fuel-eval--retort-error ret))))
+        (find-file file)))
+
+(defun fuel-scaffold-tags (&optional arg)
+  "Creates, if it does not already exist, a tags file for the current vocabulary."
+  (interactive "P")
+  (let* ((vocab (or (and (not arg) (fuel-syntax--current-vocab))
+                    (fuel-completion--read-vocab nil)))
+         (tags (read-string "Tags: "))
+         (ret (fuel-scaffold--create-tags vocab tags))
+         (file (fuel-eval--retort-result ret)))
+        (unless file
+          (error "Error creating tags file" (car (fuel-eval--retort-error ret))))
+        (find-file file)))
+
+(defun fuel-scaffold-summary (&optional arg)
+  "Creates, if it does not already exist, a summary file for the current vocabulary."
+  (interactive "P")
+  (let* ((vocab (or (and (not arg ) (fuel-syntax--current-vocab))
+                    (fuel-completion--read-vocab nil)))
+         (summary (read-string "Summary: "))
+         (ret (fuel-scaffold--create-summary vocab summary))
+         (file (fuel-eval--retort-result ret)))
+        (unless file
+          (error "Error creating summary file" (car (fuel-eval--retort-error ret))))
+        (find-file file)))
+
 
 (provide 'fuel-scaffold)
 ;;; fuel-scaffold.el ends here

From a452966af9724f83260204ea4cc1abab6aa810b0 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Sun, 21 Feb 2010 03:35:15 -0800
Subject: [PATCH 135/250] FUEL: Add prefix key behavior to fuel-test-vocab so
 that it is similar to other FUEL interactive functions.

---
 misc/fuel/fuel-listener.el | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/misc/fuel/fuel-listener.el b/misc/fuel/fuel-listener.el
index d5fec4bf5f..485d97e81f 100644
--- a/misc/fuel/fuel-listener.el
+++ b/misc/fuel/fuel-listener.el
@@ -192,12 +192,15 @@ With prefix, you're teletransported to the listener's buffer."
     (comint-send-string nil "\"Refreshing loaded vocabs...\" write nl flush")
     (comint-send-string nil " refresh-all \"Done!\" write nl flush\n")))
 
-(defun fuel-test-vocab (vocab)
-  "Run the unit tests for the specified vocabulary."
-  (interactive (list (fuel-completion--read-vocab nil (fuel-syntax--current-vocab))))
-  (comint-send-string (fuel-listener--process)
-                      (concat "\"" vocab "\" reload nl flush\n"
-                              "\"" vocab "\" test nl flush\n")))
+(defun fuel-test-vocab (&optional arg)
+  "Run the unit tests for the current vocabulary. With prefix argument, ask for
+the vocabulary name."
+  (interactive "P")
+  (let* ((vocab (or (and (not arg) (fuel-syntax--current-vocab))
+                    (fuel-completion--read-vocab nil))))
+    (comint-send-string (fuel-listener--process)
+                        (concat "\"" vocab "\" reload nl flush\n"
+                                "\"" vocab "\" test nl flush\n"))))
 
 
 ;;; Completion support

From 9b8fd8d160adb77ea560aa31f1aa2ac1b33aa5e6 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Sun, 21 Feb 2010 04:39:44 -0800
Subject: [PATCH 136/250] Fix parse error in elisp file

---
 misc/fuel/fuel-scaffold.el | 2 --
 1 file changed, 2 deletions(-)

diff --git a/misc/fuel/fuel-scaffold.el b/misc/fuel/fuel-scaffold.el
index 9e8e56475d..dc2a09713d 100644
--- a/misc/fuel/fuel-scaffold.el
+++ b/misc/fuel/fuel-scaffold.el
@@ -96,8 +96,6 @@ IN: %s
   (let ((cmd `(:fuel* (,vocab ,summary fuel-scaffold-summary) "fuel")))
     (fuel-eval--send/wait cmd)))
 
-(defsubst fuel-scaffold--creaet-
-
 (defun fuel-scaffold--help (parent)
   (when (and parent (fuel-scaffold--check-auto fuel-scaffold-help-autoinsert-p))
     (let* ((ret (fuel-scaffold--create-docs (fuel-scaffold--vocab parent)))

From 62e97c138ab5a792ab027b154c0a82c7b9bc7241 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 10:28:42 -0800
Subject: [PATCH 137/250] ditch string c-types

---
 basis/alien/c-types/c-types-docs.factor       |  5 +---
 basis/alien/c-types/c-types.factor            | 26 -------------------
 basis/alien/complex/complex-tests.factor      |  4 +--
 basis/alien/complex/complex.factor            |  4 ++-
 basis/alien/complex/functor/functor.factor    |  4 ++-
 basis/classes/struct/struct-tests.factor      |  7 -----
 basis/classes/struct/struct.factor            |  3 ---
 .../specialized-arrays.factor                 |  5 +---
 8 files changed, 10 insertions(+), 48 deletions(-)

diff --git a/basis/alien/c-types/c-types-docs.factor b/basis/alien/c-types/c-types-docs.factor
index b221051efc..215ca1b0ef 100644
--- a/basis/alien/c-types/c-types-docs.factor
+++ b/basis/alien/c-types/c-types-docs.factor
@@ -32,13 +32,10 @@ HELP: no-c-type
 { $description "Throws a " { $link no-c-type } " error." }
 { $error-description "Thrown by " { $link c-type } " if a given string does not name a C type. When thrown during compile time, indicates a typo in an " { $link alien-invoke } " or " { $link alien-callback } " form." } ;
 
-HELP: c-types
-{ $var-description "Global variable holding a hashtable mapping C type names to C types. Use the " { $link c-type } " word to look up C types." } ;
-
 HELP: c-type
 { $values { "name" "a C type" } { "c-type" c-type } }
 { $description "Looks up a C type by name." }
-{ $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
+{ $errors "Throws a " { $link no-c-type } " error if the type does not exist, or the word is not a C type." } ;
 
 HELP: c-getter
 { $values { "name" "a C type" } { "quot" { $quotation "( c-ptr n -- obj )" } } }
diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor
index e2f15f5de8..a929cba954 100644
--- a/basis/alien/c-types/c-types.factor
+++ b/basis/alien/c-types/c-types.factor
@@ -43,12 +43,6 @@ stack-align? ;
 : <c-type> ( -- c-type )
     \ c-type new ; inline
 
-SYMBOL: c-types
-
-global [
-    c-types [ H{ } assoc-like ] change
-] bind
-
 ERROR: no-c-type name ;
 
 PREDICATE: c-type-word < word
@@ -70,14 +64,6 @@ M: word resolve-pointer-type
     dup "pointer-c-type" word-prop
     [ ] [ drop void* ] ?if ;
 
-M: string resolve-pointer-type
-    dup "*" append dup c-types get at
-    [ nip ] [
-        drop
-        c-types get at dup c-type-name?
-        [ resolve-pointer-type ] [ drop void* ] if
-    ] if ;
-
 M: array resolve-pointer-type
     first resolve-pointer-type ;
 
@@ -93,15 +79,6 @@ M: array resolve-pointer-type
 
 PRIVATE>
 
-M: string c-type ( name -- c-type )
-    CHAR: ] over member? [
-        parse-array-type prefix
-    ] [
-        dup c-types get at [ ] [
-            "*" ?tail [ resolve-pointer-type ] [ no-c-type ] if
-        ] ?if resolve-typedef
-    ] if ;
-
 M: word c-type
     dup "c-type" word-prop resolve-typedef
     [ ] [ no-c-type ] ?if ;
@@ -268,12 +245,9 @@ GENERIC: typedef ( old new -- )
 PREDICATE: typedef-word < c-type-word
     "c-type" word-prop c-type-name? ;
 
-M: string typedef ( old new -- ) c-types get set-at ;
-
 M: word typedef ( old new -- )
     {
         [ nip define-symbol ]
-        [ name>> typedef ]
         [ swap "c-type" set-word-prop ]
         [
             swap dup c-type-name? [
diff --git a/basis/alien/complex/complex-tests.factor b/basis/alien/complex/complex-tests.factor
index 87f0c98b47..63d73ef029 100644
--- a/basis/alien/complex/complex-tests.factor
+++ b/basis/alien/complex/complex-tests.factor
@@ -16,6 +16,6 @@ STRUCT: complex-holder
 
 [ C{ 1.0 2.0 } ] [ "h" get z>> ] unit-test
 
-[ complex ] [ "complex-float" c-type-boxed-class ] unit-test
+[ complex ] [ complex-float c-type-boxed-class ] unit-test
 
-[ complex ] [ "complex-double" c-type-boxed-class ] unit-test
+[ complex ] [ complex-double c-type-boxed-class ] unit-test
diff --git a/basis/alien/complex/complex.factor b/basis/alien/complex/complex.factor
index 65c4095e25..fbf28071d0 100644
--- a/basis/alien/complex/complex.factor
+++ b/basis/alien/complex/complex.factor
@@ -6,8 +6,10 @@ IN: alien.complex
 
 <<
 { "float" "double" } [ dup "complex-" prepend define-complex-type ] each
+>>
 
+<<
 ! This overrides the fact that small structures are never returned
 ! in registers on NetBSD, Linux and Solaris running on 32-bit x86.
-"complex-float" c-type t >>return-in-registers? drop
+\ complex-float c-type t >>return-in-registers? drop
 >>
diff --git a/basis/alien/complex/functor/functor.factor b/basis/alien/complex/functor/functor.factor
index cb46f2d67a..90fb5174c1 100644
--- a/basis/alien/complex/functor/functor.factor
+++ b/basis/alien/complex/functor/functor.factor
@@ -7,6 +7,8 @@ IN: alien.complex.functor
 
 FUNCTOR: define-complex-type ( N T -- )
 
+N-type IS ${N}
+
 T-class DEFINES-CLASS ${T}
 
 <T> DEFINES <${T}>
@@ -14,7 +16,7 @@ T-class DEFINES-CLASS ${T}
 
 WHERE
 
-STRUCT: T-class { real N } { imaginary N } ;
+STRUCT: T-class { real N-type } { imaginary N-type } ;
 
 : <T> ( z -- alien )
     >rect T-class <struct-boa> >c-ptr ;
diff --git a/basis/classes/struct/struct-tests.factor b/basis/classes/struct/struct-tests.factor
index cb7e4ee2b0..44a2be5a70 100644
--- a/basis/classes/struct/struct-tests.factor
+++ b/basis/classes/struct/struct-tests.factor
@@ -361,13 +361,6 @@ TUPLE: a-subclass < will-become-struct ;
 
 [ tuple ] [ a-subclass superclass ] unit-test
 
-! Remove c-type when struct class is forgotten
-[ ] [
-    "USE: classes.struct IN: classes.struct.tests TUPLE: a-struct ;" eval( -- )
-] unit-test
-
-[ f ] [ "a-struct" c-types get key? ] unit-test
-
 STRUCT: bit-field-test
     { a uint bits: 12 }
     { b int bits: 2 }
diff --git a/basis/classes/struct/struct.factor b/basis/classes/struct/struct.factor
index a5711de609..4e7a565a5a 100644
--- a/basis/classes/struct/struct.factor
+++ b/basis/classes/struct/struct.factor
@@ -296,9 +296,6 @@ PRIVATE>
 : define-union-struct-class ( class slots -- )
     [ compute-union-offsets ] (define-struct-class) ;
 
-M: struct-class reset-class
-    [ call-next-method ] [ name>> c-types get delete-at ] bi ;
-
 ERROR: invalid-struct-slot token ;
 
 : struct-slot-class ( c-type -- class' )
diff --git a/basis/specialized-arrays/specialized-arrays.factor b/basis/specialized-arrays/specialized-arrays.factor
index e2840b89dd..fe2a93844c 100644
--- a/basis/specialized-arrays/specialized-arrays.factor
+++ b/basis/specialized-arrays/specialized-arrays.factor
@@ -116,10 +116,7 @@ M: A v*high [ * \ T heap-size neg shift ] 2map ; inline
 
 ;FUNCTOR
 
-GENERIC: (underlying-type) ( c-type -- c-type' )
-
-M: string (underlying-type) c-types get at ;
-M: word (underlying-type) "c-type" word-prop ;
+: (underlying-type) ( word -- c-type ) "c-type" word-prop ; inline
 
 : underlying-type ( c-type -- c-type' )
     dup (underlying-type) {

From 1a0fda2a5b06f49653db969e0cba985d50b389a0 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 11:10:52 -0800
Subject: [PATCH 138/250] remove references to c-types hash from deploy tool

---
 basis/tools/deploy/config/config-docs.factor | 4 ++--
 basis/tools/deploy/shaker/shaker.factor      | 4 ----
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/basis/tools/deploy/config/config-docs.factor b/basis/tools/deploy/config/config-docs.factor
index 1df76856ba..740abb0feb 100644
--- a/basis/tools/deploy/config/config-docs.factor
+++ b/basis/tools/deploy/config/config-docs.factor
@@ -36,7 +36,7 @@ $nl
 "Off by default. During normal execution, the word definition quotation of a word compiled with the optimizing compiler is not used, so disabling this flag can save space. However, some libraries introspect word definitions dynamically (for example, " { $vocab-link "inverse" } ") and so programs using these libraries must retain word definition quotations." } ;
 
 HELP: deploy-c-types?
-{ $description "Deploy flag. If set, the deploy tool retains the " { $link c-types } " table, otherwise this table is stripped out, saving space."
+{ $description "Deploy flag. If set, the deploy tool retains word properties containing metadata for C types and struct classes; otherwise, these properties are stripped out, saving space."
 $nl
 "Off by default."
 $nl
@@ -49,7 +49,7 @@ $nl
     { $link malloc-object }
     { $link malloc-array }
 }
-"If your program looks up C types dynamically or from words which do not have a stack effect, you must enable this flag, because in these situations the C type lookup is not folded away and the global table must be consulted at runtime." } ;
+"If your program looks up C types dynamically or from words which do not have a stack effect, you must enable this flag, because in these situations the C type lookup code is not folded away and the word properties must be consulted at runtime." } ;
 
 HELP: deploy-math?
 { $description "Deploy flag. If set, the deployed image will contain support for " { $link ratio } " and " { $link complex } " types."
diff --git a/basis/tools/deploy/shaker/shaker.factor b/basis/tools/deploy/shaker/shaker.factor
index 54058f1b0d..09219a8e5e 100755
--- a/basis/tools/deploy/shaker/shaker.factor
+++ b/basis/tools/deploy/shaker/shaker.factor
@@ -378,10 +378,6 @@ IN: tools.deploy.shaker
             ] when
         ] when
 
-        deploy-c-types? get [
-            "c-types" "alien.c-types" lookup ,
-        ] unless
-
         "windows-messages" "windows.messages" lookup [ , ] when*
     ] { } make ;
 

From 347003eb64fd65744c494ac7d5e460d740db6ab8 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 11:17:25 -0800
Subject: [PATCH 139/250] core-foundation.fsevents: use CALLBACK: type to
 define master-event-source-callback

---
 basis/core-foundation/fsevents/fsevents.factor | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/basis/core-foundation/fsevents/fsevents.factor b/basis/core-foundation/fsevents/fsevents.factor
index 37dbcd1e4f..ef1a3ff7f1 100644
--- a/basis/core-foundation/fsevents/fsevents.factor
+++ b/basis/core-foundation/fsevents/fsevents.factor
@@ -36,7 +36,6 @@ STRUCT: FSEventStreamContext
     { release void* }
     { copyDescription void* } ;
 
-! callback(
 CALLBACK: void FSEventStreamCallback ( FSEventStreamRef streamRef, void* clientCallBackInfo, size_t numEvents, void* eventPaths, FSEventStreamEventFlags* eventFlags, FSEventStreamEventId* eventIds ) ;
 
 CONSTANT: FSEventStreamEventIdSinceNow HEX: FFFFFFFFFFFFFFFF
@@ -173,16 +172,7 @@ SYMBOL: event-stream-callbacks
     info event-stream-callbacks get at [ drop ] or call( changes -- ) ;
 
 : master-event-source-callback ( -- alien )
-    "void"
-    {
-        "FSEventStreamRef"
-        "void*"                     ! info
-        "size_t"                    ! numEvents
-        "void*"                     ! eventPaths
-        "FSEventStreamEventFlags*"
-        "FSEventStreamEventId*"
-    }
-    "cdecl" [ (master-event-source-callback) ] alien-callback ;
+    [ (master-event-source-callback) ] FSEventStreamCallback ;
 
 TUPLE: event-stream < disposable info handle ;
 

From a2c9563bb7a1306160f18b98dfa85713c97e9696 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 11:36:59 -0800
Subject: [PATCH 140/250] opengl.gl.extensions: scan return type of
 GL-FUNCTION: as c-type

---
 basis/opengl/gl/extensions/extensions.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/opengl/gl/extensions/extensions.factor b/basis/opengl/gl/extensions/extensions.factor
index 540fba40f0..17813b8c82 100644
--- a/basis/opengl/gl/extensions/extensions.factor
+++ b/basis/opengl/gl/extensions/extensions.factor
@@ -49,7 +49,7 @@ reset-gl-function-number-counter
 
 SYNTAX: GL-FUNCTION:
     gl-function-calling-convention
-    scan
+    scan-c-type
     scan dup
     scan drop "}" parse-tokens swap prefix
     gl-function-number

From f07ec8bc1b554d092877e67505ef6a5a3694977b Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 11:56:35 -0800
Subject: [PATCH 141/250] windows.com.syntax: parse return c-type of
 COM-INTERFACE: functions

---
 basis/windows/com/syntax/syntax.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/windows/com/syntax/syntax.factor b/basis/windows/com/syntax/syntax.factor
index fc7d986cbc..5e08454d5a 100644
--- a/basis/windows/com/syntax/syntax.factor
+++ b/basis/windows/com/syntax/syntax.factor
@@ -38,7 +38,7 @@ ERROR: no-com-interface interface ;
 
 : (parse-com-function) ( tokens -- definition )
     [ second ]
-    [ first ]
+    [ first parse-c-type ]
     [
         3 tail [ CHAR: , swap remove ] map
         2 group [ first2 normalize-c-arg 2array ] map

From 9b0530dc9772aa314c19a62ec83c295732cd28c6 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 13:01:29 -0800
Subject: [PATCH 142/250] remove string c-types from classes.struct tests

---
 basis/classes/struct/struct-tests.factor | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/basis/classes/struct/struct-tests.factor b/basis/classes/struct/struct-tests.factor
index 44a2be5a70..cddca71188 100644
--- a/basis/classes/struct/struct-tests.factor
+++ b/basis/classes/struct/struct-tests.factor
@@ -219,7 +219,7 @@ UNION-STRUCT: struct-test-float-and-bits
         { type bool }
         { class object }
     }
-} ] [ "struct-test-foo" c-type fields>> ] unit-test
+} ] [ struct-test-foo c-type fields>> ] unit-test
 
 [ {
     T{ struct-slot-spec
@@ -236,7 +236,7 @@ UNION-STRUCT: struct-test-float-and-bits
         { class integer }
         { initial 0 }
     }
-} ] [ "struct-test-float-and-bits" c-type fields>> ] unit-test
+} ] [ struct-test-float-and-bits c-type fields>> ] unit-test
 
 STRUCT: struct-test-equality-1
     { x int } ;

From 1b508b9c376ea04577232b50d17d4a9af0545716 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Mon, 22 Feb 2010 13:10:20 +1300
Subject: [PATCH 143/250] cocoa.messages: fix

---
 basis/cocoa/messages/messages.factor | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/basis/cocoa/messages/messages.factor b/basis/cocoa/messages/messages.factor
index eab301add7..76b77721ff 100644
--- a/basis/cocoa/messages/messages.factor
+++ b/basis/cocoa/messages/messages.factor
@@ -236,10 +236,11 @@ ERROR: no-objc-type name ;
     ] bi ;
 
 : import-objc-class ( name quot -- )
-    over define-objc-class-word
+    2dup swap define-objc-class-word
+    over objc_getClass [ drop ] [ call( -- ) ] if
     dup objc_getClass [
-        [ objc-class register-objc-methods ]
-        [ objc-meta-class register-objc-methods ] bi
+        [ objc_getClass register-objc-methods ]
+        [ objc_getMetaClass register-objc-methods ] bi
     ] [ drop ] if ;
 
 : root-class ( class -- root )

From 2ab1be755cfa1e20516d945934af7d799a85dfac Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Mon, 22 Feb 2010 13:16:34 +1300
Subject: [PATCH 144/250] vocabs.loader: tweak platform checking logic

---
 core/vocabs/loader/loader.factor | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/core/vocabs/loader/loader.factor b/core/vocabs/loader/loader.factor
index 67d7d7677d..c8cf77b795 100644
--- a/core/vocabs/loader/loader.factor
+++ b/core/vocabs/loader/loader.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2007, 2009 Eduardo Cavazos, Slava Pestov.
+! Copyright (C) 2007, 2010 Eduardo Cavazos, Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: namespaces make sequences io io.files io.pathnames kernel
 assocs words vocabs definitions parser continuations hashtables
@@ -57,9 +57,15 @@ PRIVATE>
 
 SYMBOL: load-help?
 
+! Defined by vocabs.metadata
+SYMBOL: check-vocab-hook
+
+check-vocab-hook [ [ drop ] ] initialize
+
 <PRIVATE
 
 : load-source ( vocab -- )
+    dup check-vocab-hook get call( vocab -- )
     [
         +parsing+ >>source-loaded?
         dup vocab-source-path [ parse-file ] [ [ ] ] if*
@@ -99,11 +105,6 @@ PRIVATE>
 
 SYMBOL: blacklist
 
-! Defined by vocabs.metadata
-SYMBOL: check-vocab-hook
-
-check-vocab-hook [ [ drop ] ] initialize
-
 <PRIVATE
 
 : add-to-blacklist ( error vocab -- )
@@ -122,10 +123,7 @@ M: vocab (load-vocab)
 M: vocab-link (load-vocab)
     vocab-name (load-vocab) ;
 
-M: string (load-vocab)
-    [ check-vocab-hook get call( vocab -- ) ]
-    [ create-vocab (load-vocab) ]
-    bi ;
+M: string (load-vocab) create-vocab (load-vocab) ;
 
 PRIVATE>
 

From 5fe49b13bfbeba4628f72b3c40ef9ddf26f85000 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Mon, 22 Feb 2010 13:16:46 +1300
Subject: [PATCH 145/250] windows.com.prettyprint: remove circular dependency
 on windows.com

---
 basis/windows/com/prettyprint/prettyprint.factor | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/basis/windows/com/prettyprint/prettyprint.factor b/basis/windows/com/prettyprint/prettyprint.factor
index c75f43f560..ef79a58600 100644
--- a/basis/windows/com/prettyprint/prettyprint.factor
+++ b/basis/windows/com/prettyprint/prettyprint.factor
@@ -1,7 +1,7 @@
 ! Copyright (C) 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: windows.com windows.kernel32 windows.ole32
-prettyprint.custom prettyprint.sections sequences ;
+USING: windows.kernel32 windows.ole32 prettyprint.custom
+prettyprint.sections sequences ;
 IN: windows.com.prettyprint
 
 M: GUID pprint* guid>string "GUID: " prepend text ;

From f9d6191c4bc2399d3f66a121351959db23bb4ee1 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Mon, 22 Feb 2010 13:18:45 +1300
Subject: [PATCH 146/250] cpu.ppc: fix string c-type usage

---
 basis/cpu/ppc/ppc.factor | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/basis/cpu/ppc/ppc.factor b/basis/cpu/ppc/ppc.factor
index 22eb2543b4..6d84aad8d5 100644
--- a/basis/cpu/ppc/ppc.factor
+++ b/basis/cpu/ppc/ppc.factor
@@ -2,8 +2,9 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs sequences kernel combinators make math
 math.order math.ranges system namespaces locals layouts words
-alien alien.accessors alien.c-types alien.data literals cpu.architecture
-cpu.ppc.assembler cpu.ppc.assembler.backend compiler.cfg.registers
+alien alien.accessors alien.c-types alien.complex alien.data
+literals cpu.architecture cpu.ppc.assembler
+cpu.ppc.assembler.backend compiler.cfg.registers
 compiler.cfg.instructions compiler.cfg.comparisons
 compiler.codegen.fixup compiler.cfg.intrinsics
 compiler.cfg.stack-frame compiler.cfg.build-stack-frame
@@ -780,4 +781,4 @@ USE: vocabs.loader
     { [ os linux? ] [ "cpu.ppc.linux" require ] }
 } cond
 
-"complex-double" c-type t >>return-in-registers? drop
+complex-double c-type t >>return-in-registers? drop

From 5955ba06df0505ae5a7f4335170f982e8645355b Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 16:27:36 -0800
Subject: [PATCH 147/250] use a "pointer" wrapper tuple to indicate pointer
 types instead of the current slipshod approach

---
 basis/alien/arrays/arrays.factor              |  5 +-
 basis/alien/c-types/c-types-tests.factor      | 33 ++++---
 basis/alien/c-types/c-types.factor            | 97 +++++++++++--------
 basis/alien/fortran/fortran.factor            |  4 +-
 basis/alien/parser/parser-tests.factor        | 18 ++--
 basis/alien/parser/parser.factor              |  5 +-
 basis/alien/prettyprint/prettyprint.factor    |  3 +
 basis/alien/syntax/syntax.factor              |  3 +
 basis/classes/struct/struct-tests.factor      | 57 +++++++++++
 basis/compiler/codegen/codegen.factor         |  2 +-
 .../specialized-arrays.factor                 | 14 ++-
 basis/windows/types/types.factor              |  6 +-
 extra/alien/data/map/map.factor               |  4 +-
 13 files changed, 159 insertions(+), 92 deletions(-)

diff --git a/basis/alien/arrays/arrays.factor b/basis/alien/arrays/arrays.factor
index 7eed1a0664..cf6e8640f0 100644
--- a/basis/alien/arrays/arrays.factor
+++ b/basis/alien/arrays/arrays.factor
@@ -99,8 +99,5 @@ M: string-type c-type-getter
 M: string-type c-type-setter
     drop [ set-alien-cell ] ;
 
-{ char* utf8 } char* typedef
-char* uchar* typedef
+TYPEDEF: { char* utf8 } char*
 
-char char* "pointer-c-type" set-word-prop
-uchar uchar* "pointer-c-type" set-word-prop
diff --git a/basis/alien/c-types/c-types-tests.factor b/basis/alien/c-types/c-types-tests.factor
index faee8955e9..5f903c9a34 100644
--- a/basis/alien/c-types/c-types-tests.factor
+++ b/basis/alien/c-types/c-types-tests.factor
@@ -16,41 +16,46 @@ UNION-STRUCT: foo
     { a int }
     { b int } ;
 
-[ f ] [ char  resolve-pointer-type c-type void* c-type eq? ] unit-test
-[ t ] [ char* resolve-pointer-type c-type void* c-type eq? ] unit-test
+[ t ] [ pointer: void c-type void* c-type eq? ] unit-test
+[ t ] [ pointer: int  c-type void* c-type eq? ] unit-test
+[ t ] [ pointer: int* c-type void* c-type eq? ] unit-test
+[ f ] [ pointer: foo  c-type void* c-type eq? ] unit-test
+[ t ] [ pointer: foo* c-type void* c-type eq? ] unit-test
+
+[ t ] [ pointer: char c-type c-string c-type eq? ] unit-test
+
+[ t ] [ pointer: foo c-type-boxer-quot foo c-type-boxer-quot = ] unit-test
 
 [ t ] [ foo heap-size int heap-size = ] unit-test
 
 TYPEDEF: int MyInt
 
-[ t ] [ int   c-type MyInt                      c-type eq? ] unit-test
-[ t ] [ void* c-type MyInt resolve-pointer-type c-type eq? ] unit-test
-
-TYPEDEF: char MyChar
-
-[ t ] [ char  c-type MyChar                      c-type eq? ] unit-test
-[ f ] [ void* c-type MyChar resolve-pointer-type c-type eq? ] unit-test
-[ t ] [ char* c-type MyChar resolve-pointer-type c-type eq? ] unit-test
+[ t ] [ int   c-type          MyInt c-type eq? ] unit-test
+[ t ] [ void* c-type pointer: MyInt c-type eq? ] unit-test
 
 [ 32 ] [ { int 8 } heap-size ] unit-test
 
 TYPEDEF: char* MyString
 
-[ t ] [ char* c-type MyString                      c-type eq? ] unit-test
-[ t ] [ void* c-type MyString resolve-pointer-type c-type eq? ] unit-test
+[ t ] [ c-string c-type MyString          c-type eq? ] unit-test
+[ t ] [ void*    c-type pointer: MyString c-type eq? ] unit-test
 
 TYPEDEF: int* MyIntArray
 
 [ t ] [ void* c-type MyIntArray c-type eq? ] unit-test
 
-TYPEDEF: uchar* MyLPBYTE
+TYPEDEF: c-string MyLPBYTE
 
-[ t ] [ { char* utf8 } c-type MyLPBYTE c-type = ] unit-test
+[ t ] [ { c-string utf8 } c-type MyLPBYTE c-type = ] unit-test
 
 [
     0 B{ 1 2 3 4 } <displaced-alien> <void*>
 ] must-fail
 
+C-TYPE: MyOpaqueType
+
+[ f ] [ pointer: MyOpaqueType c-type void* c-type eq? ] unit-test
+
 os windows? cpu x86.64? and [
     [ -2147467259 ] [ 2147500037 <long> *long ] unit-test
 ] when
diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor
index a929cba954..4a7fd840ef 100644
--- a/basis/alien/c-types/c-types.factor
+++ b/basis/alien/c-types/c-types.factor
@@ -17,7 +17,7 @@ SYMBOLS:
     long ulong
     longlong ulonglong
     float double
-    void* bool
+    bool void*
     void ;
 
 DEFER: <int>
@@ -48,28 +48,18 @@ ERROR: no-c-type name ;
 PREDICATE: c-type-word < word
     "c-type" word-prop ;
 
-UNION: c-type-name string c-type-word ;
-
 ! C type protocol
 GENERIC: c-type ( name -- c-type ) foldable
 
-GENERIC: resolve-pointer-type ( name -- c-type )
-
-<< \ void \ void* "pointer-c-type" set-word-prop >>
-
 : void? ( c-type -- ? )
-    { void "void" } member? ;
+    void = ; inline
 
-M: word resolve-pointer-type
-    dup "pointer-c-type" word-prop
-    [ ] [ drop void* ] ?if ;
-
-M: array resolve-pointer-type
-    first resolve-pointer-type ;
+TUPLE: pointer { to initial: void read-only } ;
+C: <pointer> pointer
 
 : resolve-typedef ( name -- c-type )
     dup void? [ no-c-type ] when
-    dup c-type-name? [ c-type ] when ;
+    dup c-type-word? [ c-type ] when ;
 
 <PRIVATE
 
@@ -87,7 +77,7 @@ GENERIC: c-struct? ( c-type -- ? )
 
 M: object c-struct? drop f ;
 
-M: c-type-name c-struct? dup void? [ drop f ] [ c-type c-struct? ] if ;
+M: c-type-word c-struct? dup void? [ drop f ] [ c-type c-struct? ] if ;
 
 ! These words being foldable means that words need to be
 ! recompiled if a C type is redefined. Even so, folding the
@@ -96,65 +86,65 @@ GENERIC: c-type-class ( name -- class )
 
 M: abstract-c-type c-type-class class>> ;
 
-M: c-type-name c-type-class c-type c-type-class ;
+M: c-type-word c-type-class c-type c-type-class ;
 
 GENERIC: c-type-boxed-class ( name -- class )
 
 M: abstract-c-type c-type-boxed-class boxed-class>> ;
 
-M: c-type-name c-type-boxed-class c-type c-type-boxed-class ;
+M: c-type-word c-type-boxed-class c-type c-type-boxed-class ;
 
 GENERIC: c-type-boxer ( name -- boxer )
 
 M: c-type c-type-boxer boxer>> ;
 
-M: c-type-name c-type-boxer c-type c-type-boxer ;
+M: c-type-word c-type-boxer c-type c-type-boxer ;
 
 GENERIC: c-type-boxer-quot ( name -- quot )
 
 M: abstract-c-type c-type-boxer-quot boxer-quot>> ;
 
-M: c-type-name c-type-boxer-quot c-type c-type-boxer-quot ;
+M: c-type-word c-type-boxer-quot c-type c-type-boxer-quot ;
 
 GENERIC: c-type-unboxer ( name -- boxer )
 
 M: c-type c-type-unboxer unboxer>> ;
 
-M: c-type-name c-type-unboxer c-type c-type-unboxer ;
+M: c-type-word c-type-unboxer c-type c-type-unboxer ;
 
 GENERIC: c-type-unboxer-quot ( name -- quot )
 
 M: abstract-c-type c-type-unboxer-quot unboxer-quot>> ;
 
-M: c-type-name c-type-unboxer-quot c-type c-type-unboxer-quot ;
+M: c-type-word c-type-unboxer-quot c-type c-type-unboxer-quot ;
 
 GENERIC: c-type-rep ( name -- rep )
 
 M: c-type c-type-rep rep>> ;
 
-M: c-type-name c-type-rep c-type c-type-rep ;
+M: c-type-word c-type-rep c-type c-type-rep ;
 
 GENERIC: c-type-getter ( name -- quot )
 
 M: c-type c-type-getter getter>> ;
 
-M: c-type-name c-type-getter c-type c-type-getter ;
+M: c-type-word c-type-getter c-type c-type-getter ;
 
 GENERIC: c-type-setter ( name -- quot )
 
 M: c-type c-type-setter setter>> ;
 
-M: c-type-name c-type-setter c-type c-type-setter ;
+M: c-type-word c-type-setter c-type c-type-setter ;
 
 GENERIC: c-type-align ( name -- n )
 
 M: abstract-c-type c-type-align align>> ;
 
-M: c-type-name c-type-align c-type c-type-align ;
+M: c-type-word c-type-align c-type c-type-align ;
 
 GENERIC: c-type-align-first ( name -- n )
 
-M: c-type-name c-type-align-first c-type c-type-align-first ;
+M: c-type-word c-type-align-first c-type c-type-align-first ;
 
 M: abstract-c-type c-type-align-first align-first>> ;
 
@@ -162,7 +152,7 @@ GENERIC: c-type-stack-align? ( name -- ? )
 
 M: c-type c-type-stack-align? stack-align?>> ;
 
-M: c-type-name c-type-stack-align? c-type c-type-stack-align? ;
+M: c-type-word c-type-stack-align? c-type c-type-stack-align? ;
 
 : c-type-box ( n c-type -- )
     [ c-type-rep ] [ c-type-boxer [ "No boxer" throw ] unless* ] bi
@@ -176,37 +166,37 @@ GENERIC: box-parameter ( n c-type -- )
 
 M: c-type box-parameter c-type-box ;
 
-M: c-type-name box-parameter c-type box-parameter ;
+M: c-type-word box-parameter c-type box-parameter ;
 
 GENERIC: box-return ( c-type -- )
 
 M: c-type box-return f swap c-type-box ;
 
-M: c-type-name box-return c-type box-return ;
+M: c-type-word box-return c-type box-return ;
 
 GENERIC: unbox-parameter ( n c-type -- )
 
 M: c-type unbox-parameter c-type-unbox ;
 
-M: c-type-name unbox-parameter c-type unbox-parameter ;
+M: c-type-word unbox-parameter c-type unbox-parameter ;
 
 GENERIC: unbox-return ( c-type -- )
 
 M: c-type unbox-return f swap c-type-unbox ;
 
-M: c-type-name unbox-return c-type unbox-return ;
+M: c-type-word unbox-return c-type unbox-return ;
 
 : little-endian? ( -- ? ) 1 <int> *char 1 = ; foldable
 
 GENERIC: heap-size ( name -- size )
 
-M: c-type-name heap-size c-type heap-size ;
+M: c-type-word heap-size c-type heap-size ;
 
 M: abstract-c-type heap-size size>> ;
 
 GENERIC: stack-size ( name -- size )
 
-M: c-type-name stack-size c-type stack-size ;
+M: c-type-word stack-size c-type stack-size ;
 
 M: c-type stack-size size>> cell align ;
 
@@ -243,20 +233,19 @@ MIXIN: value-type
 GENERIC: typedef ( old new -- )
 
 PREDICATE: typedef-word < c-type-word
-    "c-type" word-prop c-type-name? ;
+    "c-type" word-prop c-type-word? ;
 
 M: word typedef ( old new -- )
     {
         [ nip define-symbol ]
         [ swap "c-type" set-word-prop ]
-        [
-            swap dup c-type-name? [
-                resolve-pointer-type
-                "pointer-c-type" set-word-prop
-            ] [ 2drop ] if
-        ]
     } 2cleave ;
 
+M: pointer typedef ( old new -- )
+    to>> dup c-type-word?
+    [ ]
+    [ 2drop ] if ;
+
 TUPLE: long-long-type < c-type ;
 
 : <long-long-type> ( -- c-type )
@@ -302,7 +291,31 @@ CONSTANT: primitive-types
 
 SYMBOLS:
     ptrdiff_t intptr_t uintptr_t size_t
-    char* uchar* ;
+    char* ;
+
+<PRIVATE
+
+: (pointer-c-type) ( void* type -- void*' )
+    [ clone ] dip c-type-boxer-quot >>boxer-quot ;
+
+: string-pointer-type? ( type -- ? )
+    dup pointer? [ drop f ]
+    [ resolve-typedef { char uchar } member? ] if ;
+
+: primitive-pointer-type? ( type -- ? )
+    dup pointer? [ drop t ] [
+        resolve-typedef [ void? ] [ primitive-types member? ] bi or
+    ] if ;
+
+PRIVATE>
+
+M: pointer c-type
+    [ \ void* c-type ] dip
+    to>> {
+        { [ dup string-pointer-type? ] [ drop \ char* c-type ] }
+        { [ dup primitive-pointer-type? ] [ drop ] }
+        [ (pointer-c-type) ]
+    } cond ;
 
 : 8-byte-alignment ( c-type -- c-type )
     {
diff --git a/basis/alien/fortran/fortran.factor b/basis/alien/fortran/fortran.factor
index 65e927f85a..9255c66c9f 100644
--- a/basis/alien/fortran/fortran.factor
+++ b/basis/alien/fortran/fortran.factor
@@ -392,13 +392,13 @@ PRIVATE>
 
 : fortran-arg-type>c-type ( fortran-type -- c-type added-args )
     parse-fortran-type
-    [ (fortran-type>c-type) resolve-pointer-type ]
+    [ (fortran-type>c-type) <pointer> ]
     [ added-c-args ] bi ;
 : fortran-ret-type>c-type ( fortran-type -- c-type added-args )
     parse-fortran-type dup returns-by-value?
     [ (fortran-ret-type>c-type) { } ] [
         c:void swap 
-        [ added-c-args ] [ (fortran-type>c-type) resolve-pointer-type ] bi prefix
+        [ added-c-args ] [ (fortran-type>c-type) <pointer> ] bi prefix
     ] if ;
 
 : fortran-arg-types>c-types ( fortran-types -- c-types )
diff --git a/basis/alien/parser/parser-tests.factor b/basis/alien/parser/parser-tests.factor
index e405f49995..b7f7b10628 100644
--- a/basis/alien/parser/parser-tests.factor
+++ b/basis/alien/parser/parser-tests.factor
@@ -18,20 +18,16 @@ CONSTANT: eleven 11
     [ { int 5 } ] [ "int[5]" parse-c-type ] unit-test
     [ { int 5 10 11 } ] [ "int[5][10][11]" parse-c-type ] unit-test
     [ { int 5 10 eleven } ] [ "int[5][10][eleven]" parse-c-type ] unit-test
-    [ void* ] [ "int*" parse-c-type ] unit-test
-    [ void* ] [ "int**" parse-c-type ] unit-test
-    [ void* ] [ "int***" parse-c-type ] unit-test
-    [ void* ] [ "int****" parse-c-type ] unit-test
-    [ char* ] [ "char*" parse-c-type ] unit-test
-    [ void* ] [ "char**" parse-c-type ] unit-test
-    [ void* ] [ "char***" parse-c-type ] unit-test
-    [ void* ] [ "char****" parse-c-type ] unit-test
+    [ pointer: void ] [ "void*" parse-c-type ] unit-test
+    [ pointer: int ] [ "int*" parse-c-type ] unit-test
+    [ pointer: int* ] [ "int**" parse-c-type ] unit-test
+    [ pointer: int** ] [ "int***" parse-c-type ] unit-test
+    [ pointer: int*** ] [ "int****" parse-c-type ] unit-test
+    [ pointer: char ] [ "char*" parse-c-type ] unit-test
     [ char2 ] [ "char2" parse-c-type ] unit-test
-    [ char* ] [ "char2*" parse-c-type ] unit-test
+    [ pointer: char2 ] [ "char2*" parse-c-type ] unit-test
 
-    [ "not-c-type" parse-c-type ] [ no-c-type? ] must-fail-with
     [ "not-word" parse-c-type ] [ error>> no-word-error? ] must-fail-with
-
 ] with-file-vocabs
 
 ! Reported by mnestic
diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor
index 0cf495fd25..09ee88c173 100644
--- a/basis/alien/parser/parser.factor
+++ b/basis/alien/parser/parser.factor
@@ -19,13 +19,12 @@ IN: alien.parser
         { [ dup "void" =         ] [ drop void ] }
         { [ CHAR: ] over member? ] [ parse-array-type parse-c-type-name prefix ] }
         { [ dup search           ] [ parse-c-type-name ] }
-        { [ "**" ?tail           ] [ drop void* ] }
-        { [ "*" ?tail            ] [ parse-c-type-name resolve-pointer-type ] }
+        { [ "*" ?tail            ] [ (parse-c-type) <pointer> ] }
         [ dup search [ ] [ no-word ] ?if ]
     } cond ;
 
 : valid-c-type? ( c-type -- ? )
-    { [ array? ] [ c-type-name? ] [ void? ] } 1|| ;
+    { [ array? ] [ c-type-word? ] [ pointer? ] [ void? ] } 1|| ;
 
 : parse-c-type ( string -- type )
     (parse-c-type) dup valid-c-type? [ no-c-type ] unless ;
diff --git a/basis/alien/prettyprint/prettyprint.factor b/basis/alien/prettyprint/prettyprint.factor
index ded8f692cd..6bfbf313a1 100644
--- a/basis/alien/prettyprint/prettyprint.factor
+++ b/basis/alien/prettyprint/prettyprint.factor
@@ -21,10 +21,13 @@ M: c-type-word declarations. drop ;
 
 GENERIC: pprint-c-type ( c-type -- )
 M: word pprint-c-type pprint-word ;
+M: pointer pprint-c-type to>> pprint-c-type "*" text ;
 M: wrapper pprint-c-type wrapped>> pprint-word ;
 M: string pprint-c-type text ;
 M: array pprint-c-type pprint* ;
 
+M: pointer pprint* \ pointer: pprint-word to>> pprint-c-type ;
+
 M: typedef-word definer drop \ TYPEDEF: f ;
 
 M: typedef-word synopsis*
diff --git a/basis/alien/syntax/syntax.factor b/basis/alien/syntax/syntax.factor
index 295bcff089..9eb8ca6287 100644
--- a/basis/alien/syntax/syntax.factor
+++ b/basis/alien/syntax/syntax.factor
@@ -47,3 +47,6 @@ SYNTAX: &:
     [ nip ] [ global-quot ] 2bi (( -- value )) define-declared ;
 
 SYNTAX: C-GLOBAL: scan-c-type CREATE-WORD define-global ;
+
+SYNTAX: pointer:
+    scan-c-type <pointer> suffix! ;
diff --git a/basis/classes/struct/struct-tests.factor b/basis/classes/struct/struct-tests.factor
index cddca71188..0316b1fae0 100644
--- a/basis/classes/struct/struct-tests.factor
+++ b/basis/classes/struct/struct-tests.factor
@@ -374,6 +374,63 @@ STRUCT: bit-field-test
 [ 1 ] [ bit-field-test <struct> 257 >>c c>> ] unit-test
 [ 3 ] [ bit-field-test heap-size ] unit-test
 
+STRUCT: referent
+    { y int } ;
+STRUCT: referrer
+    { x referent* } ;
+
+[ 57 ] [
+    [
+        referrer <struct>
+            referent malloc-struct &free
+                57 >>y
+            >>x
+        x>> y>>
+    ] with-destructors
+] unit-test
+
+STRUCT: self-referent
+    { x self-referent* }
+    { y int } ;
+
+[ 75 ] [
+    [
+        self-referent <struct>
+            self-referent malloc-struct &free
+                75 >>y
+            >>x
+        x>> y>>
+    ] with-destructors
+] unit-test
+
+C-TYPE: forward-referent
+STRUCT: backward-referent
+    { x forward-referent* }
+    { y int } ;
+STRUCT: forward-referent
+    { x backward-referent* }
+    { y int } ;
+
+[ 41 ] [
+    [
+        forward-referent <struct>
+            backward-referent malloc-struct &free
+                41 >>y
+            >>x
+        x>> y>>
+    ] with-destructors
+] unit-test
+
+[ 14 ] [
+    [
+        backward-referent <struct>
+            forward-referent malloc-struct &free
+                14 >>y
+            >>x
+        x>> y>>
+    ] with-destructors
+] unit-test
+
 cpu ppc? [
     STRUCT: ppc-align-test-1
         { x longlong }
diff --git a/basis/compiler/codegen/codegen.factor b/basis/compiler/codegen/codegen.factor
index 963ed0ab28..d6e58f7ac1 100755
--- a/basis/compiler/codegen/codegen.factor
+++ b/basis/compiler/codegen/codegen.factor
@@ -325,7 +325,7 @@ GENERIC: flatten-value-type ( type -- types )
 M: object flatten-value-type 1array ;
 M: struct-c-type flatten-value-type (flatten-int-type) ;
 M: long-long-type flatten-value-type (flatten-int-type) ;
-M: c-type-name flatten-value-type c-type flatten-value-type ;
+M: c-type-word flatten-value-type c-type flatten-value-type ;
 
 : flatten-value-types ( params -- params )
     #! Convert value type structs to consecutive void*s.
diff --git a/basis/specialized-arrays/specialized-arrays.factor b/basis/specialized-arrays/specialized-arrays.factor
index fe2a93844c..67689998ab 100644
--- a/basis/specialized-arrays/specialized-arrays.factor
+++ b/basis/specialized-arrays/specialized-arrays.factor
@@ -116,12 +116,10 @@ M: A v*high [ * \ T heap-size neg shift ] 2map ; inline
 
 ;FUNCTOR
 
-: (underlying-type) ( word -- c-type ) "c-type" word-prop ; inline
-
 : underlying-type ( c-type -- c-type' )
-    dup (underlying-type) {
+    dup "c-type" word-prop {
         { [ dup not ] [ drop no-c-type ] }
-        { [ dup c-type-name? ] [ nip underlying-type ] }
+        { [ dup c-type-word? ] [ nip underlying-type ] }
         [ drop ]
     } cond ;
 
@@ -140,21 +138,21 @@ PRIVATE>
     [ specialized-array-vocab ] [ '[ _ define-array ] ] bi
     generate-vocab ;
 
-M: c-type-name require-c-array define-array-vocab drop ;
+M: c-type-word require-c-array define-array-vocab drop ;
 
 ERROR: specialized-array-vocab-not-loaded c-type ;
 
-M: c-type-name c-array-constructor
+M: c-type-word c-array-constructor
     underlying-type
     dup [ name>> "<" "-array>" surround ] [ specialized-array-vocab ] bi lookup
     [ ] [ specialized-array-vocab-not-loaded ] ?if ; foldable
 
-M: c-type-name c-(array)-constructor
+M: c-type-word c-(array)-constructor
     underlying-type
     dup [ name>> "(" "-array)" surround ] [ specialized-array-vocab ] bi lookup
     [ ] [ specialized-array-vocab-not-loaded ] ?if ; foldable
 
-M: c-type-name c-direct-array-constructor
+M: c-type-word c-direct-array-constructor
     underlying-type
     dup [ name>> "<direct-" "-array>" surround ] [ specialized-array-vocab ] bi lookup
     [ ] [ specialized-array-vocab-not-loaded ] ?if ; foldable
diff --git a/basis/windows/types/types.factor b/basis/windows/types/types.factor
index 9e322d9cde..4f527513fc 100644
--- a/basis/windows/types/types.factor
+++ b/basis/windows/types/types.factor
@@ -11,11 +11,7 @@ TYPEDEF: uchar               UCHAR
 TYPEDEF: uchar               BYTE
 
 TYPEDEF: ushort              wchar_t
-SYMBOL: wchar_t*
-<<
-{ char* utf16n } \ wchar_t* typedef
-\ wchar_t \ wchar_t* "pointer-c-type" set-word-prop
->>
+TYPEDEF: { char* utf16n }    wchar_t*
 
 TYPEDEF: wchar_t             WCHAR
 
diff --git a/extra/alien/data/map/map.factor b/extra/alien/data/map/map.factor
index 6c93e8f4b6..06997bce56 100644
--- a/extra/alien/data/map/map.factor
+++ b/extra/alien/data/map/map.factor
@@ -54,7 +54,7 @@ INSTANCE: data-map-param immutable-sequence
     nip '[ _ <sliced-groups> ] ;
 
 : [>param] ( type -- quot )
-    c-type-count over c-type-name?
+    c-type-count over c-type-word?
     [ [>c-type-param] ] [ [>object-param] ] if ; 
 
 MACRO: >param ( in -- quot: ( array -- param ) )
@@ -74,7 +74,7 @@ MACRO: >param ( in -- quot: ( array -- param ) )
     "Factor sequences as data-map outputs not supported" throw ;
 
 : [alloc-param] ( type -- quot )
-    c-type-count over c-type-name?
+    c-type-count over c-type-word?
     [ [alloc-c-type-param] ] [ [alloc-object-param] ] if ; 
 
 MACRO: alloc-param ( out -- quot: ( len -- param ) )

From 52a8c3ebc9cec2943ad1dc02a69d6d66cc62e56f Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Sun, 21 Feb 2010 16:42:31 -0800
Subject: [PATCH 148/250] FUEL: Add UNION-STRUCT: to syntax highlighting.

---
 misc/fuel/fuel-syntax.el | 912 +++++++++++++++++++--------------------
 1 file changed, 456 insertions(+), 456 deletions(-)

diff --git a/misc/fuel/fuel-syntax.el b/misc/fuel/fuel-syntax.el
index 1b060e5dd1..7de627f8f5 100644
--- a/misc/fuel/fuel-syntax.el
+++ b/misc/fuel/fuel-syntax.el
@@ -1,456 +1,456 @@
-;;; fuel-syntax.el --- auxiliar definitions for factor code navigation.
-
-;; Copyright (C) 2008, 2009  Jose Antonio Ortega Ruiz
-;; See http://factorcode.org/license.txt for BSD license.
-
-;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
-;; Keywords: languages
-
-;;; Commentary:
-
-;; Auxiliar constants and functions to parse factor code.
-
-;;; Code:
-
-(require 'thingatpt)
-
-
-;;; Thing-at-point support for factor symbols:
-
-(defun fuel-syntax--beginning-of-symbol ()
-  "Move point to the beginning of the current symbol."
-  (skip-syntax-backward "w_()"))
-
-(defsubst fuel-syntax--beginning-of-symbol-pos ()
-  (save-excursion (fuel-syntax--beginning-of-symbol) (point)))
-
-(defun fuel-syntax--end-of-symbol ()
-  "Move point to the end of the current symbol."
-  (skip-syntax-forward "w_()"))
-
-(defsubst fuel-syntax--end-of-symbol-pos ()
-  (save-excursion (fuel-syntax--end-of-symbol) (point)))
-
-(put 'factor-symbol 'end-op 'fuel-syntax--end-of-symbol)
-(put 'factor-symbol 'beginning-op 'fuel-syntax--beginning-of-symbol)
-
-(defsubst fuel-syntax-symbol-at-point ()
-  (let ((s (substring-no-properties (thing-at-point 'factor-symbol))))
-    (and (> (length s) 0) s)))
-
-
-
-;;; Regexps galore:
-
-(defconst fuel-syntax--parsing-words
-  '(":" "::" ";" "&:" "<<" "<PRIVATE" ">>"
-    "ABOUT:" "ALIAS:" "ALIEN:" "ARTICLE:"
-    "B" "BIN:"
-    "C:" "CALLBACK:" "C-ENUM:" "C-STRUCT:" "C-TYPE:" "C-UNION:" "CHAR:" "CONSTANT:" "call-next-method"
-    "DEFER:"
-    "EBNF:" ";EBNF" "ERROR:" "EXCLUDE:"
-    "f" "FORGET:" "FROM:" "FUNCTION:"
-    "GAME:" "GENERIC#" "GENERIC:"
-    "GLSL-SHADER:" "GLSL-PROGRAM:"
-    "HELP:" "HEX:" "HOOK:"
-    "IN:" "initial:" "INSTANCE:" "INTERSECTION:"
-    "LIBRARY:"
-    "M:" "M::" "MACRO:" "MACRO::" "MAIN:" "MATH:"
-    "MEMO:" "MEMO:" "METHOD:" "MIXIN:"
-    "OCT:"
-    "POSTPONE:" "PREDICATE:" "PRIMITIVE:" "PRIVATE>" "PROVIDE:"
-    "QUALIFIED-WITH:" "QUALIFIED:"
-    "read-only" "RENAME:" "REQUIRE:"  "REQUIRES:"
-    "SINGLETON:" "SINGLETONS:" "SLOT:" "SPECIALIZED-ARRAY:" "SPECIALIZED-ARRAYS:" "STRING:" "STRUCT:" "SYMBOL:" "SYMBOLS:" "SYNTAX:"
-    "TUPLE:" "t" "t?" "TYPEDEF:" "TYPED:" "TYPED::"
-    "UNIFORM-TUPLE:" "UNION:" "USE:" "USING:"
-    "VARS:" "VERTEX-FORMAT:"))
-
-(defconst fuel-syntax--parsing-words-regex
-  (regexp-opt fuel-syntax--parsing-words 'words))
-
-(defconst fuel-syntax--bracers
-  '("B" "BV" "C" "CS" "H" "T" "V" "W"))
-
-(defconst fuel-syntax--brace-words-regex
-  (format "%s{" (regexp-opt fuel-syntax--bracers t)))
-
-(defconst fuel-syntax--declaration-words
-  '("flushable" "foldable" "inline" "parsing" "recursive" "delimiter"))
-
-(defconst fuel-syntax--declaration-words-regex
-  (regexp-opt fuel-syntax--declaration-words 'words))
-
-(defsubst fuel-syntax--second-word-regex (prefixes)
-  (format "%s +\\([^ \r\n]+\\)" (regexp-opt prefixes t)))
-
-(defconst fuel-syntax--method-definition-regex
-  "^M::? +\\([^ ]+\\) +\\([^ ]+\\)")
-
-(defconst fuel-syntax--integer-regex
-  "\\_<-?[0-9]+\\_>")
-
-(defconst fuel-syntax--raw-float-regex
-  "[0-9]*\\.[0-9]*\\([eE][+-]?[0-9]+\\)?")
-
-(defconst fuel-syntax--float-regex
-  (format "\\_<-?%s\\_>" fuel-syntax--raw-float-regex))
-
-(defconst fuel-syntax--number-regex
-  (format "\\([0-9]+\\|%s\\)" fuel-syntax--raw-float-regex))
-
-(defconst fuel-syntax--ratio-regex
-  (format "\\_<[+-]?%s/-?%s\\_>"
-          fuel-syntax--number-regex
-          fuel-syntax--number-regex))
-
-(defconst fuel-syntax--bad-string-regex
-  "\\_<\"[^>]\\([^\"\n]\\|\\\\\"\\)*\n")
-
-(defconst fuel-syntax--word-definition-regex
-  (format "\\_<\\(%s\\)?: +\\_<\\(\\w+\\)\\_>"
-          (regexp-opt
-           '(":" "GENERIC" "DEFER" "HOOK" "MAIN" "MATH" "POSTPONE"
-             "SYMBOL" "SYNTAX" "TYPED" "RENAME"))))
-
-(defconst fuel-syntax--alias-definition-regex
-  "^ALIAS: +\\(\\_<.+?\\_>\\) +\\(\\_<.+?\\_>\\)")
-
-(defconst fuel-syntax--vocab-ref-regexp
-  (fuel-syntax--second-word-regex
-   '("IN:" "USE:" "FROM:" "EXCLUDE:" "QUALIFIED:" "QUALIFIED-WITH:")))
-
-(defconst fuel-syntax--int-constant-def-regex
-  (fuel-syntax--second-word-regex '("ALIEN:" "CHAR:" "BIN:" "HEX:" "OCT:")))
-
-(defconst fuel-syntax--type-definition-regex
-  (fuel-syntax--second-word-regex
-   '("C-STRUCT:" "C-UNION:" "MIXIN:" "TUPLE:" "SINGLETON:" "SPECIALIZED-ARRAY:" "STRUCT:" "UNION:")))
-
-(defconst fuel-syntax--tuple-decl-regex
-  "^TUPLE: +\\([^ \n]+\\) +< +\\([^ \n]+\\)\\_>")
-
-(defconst fuel-syntax--constructor-regex "<[^ >]+>")
-
-(defconst fuel-syntax--getter-regex "\\(^\\|\\_<\\)[^ ]+?>>\\_>")
-(defconst fuel-syntax--setter-regex "\\_<>>.+?\\_>")
-
-(defconst fuel-syntax--symbol-definition-regex
-  (fuel-syntax--second-word-regex '("&:" "SYMBOL:" "VAR:")))
-
-(defconst fuel-syntax--stack-effect-regex
-  "\\( ( [^\n]* )\\)\\|\\( (( [^\n]* ))\\)")
-
-(defconst fuel-syntax--using-lines-regex "^USING: +\\([^;]+\\);")
-
-(defconst fuel-syntax--use-line-regex "^USE: +\\(.*\\)$")
-
-(defconst fuel-syntax--current-vocab-regex "^IN: +\\([^ \r\n\f]+\\)")
-
-(defconst fuel-syntax--sub-vocab-regex "^<\\([^ \n]+\\) *$")
-
-(defconst fuel-syntax--alien-function-regex
-  "\\_<FUNCTION: \\(\\w+\\) \\(\\w+\\)")
-
-(defconst fuel-syntax--alien-callback-regex
-  "\\_<CALLBACK: \\(\\w+\\) \\(\\w+\\)")
-
-(defconst fuel-syntax--indent-def-starts '("" ":"
-                                           "C-ENUM" "C-STRUCT" "C-UNION"
-                                           "FROM" "FUNCTION:"
-                                           "INTERSECTION:"
-                                           "M" "M:" "MACRO" "MACRO:"
-                                           "MEMO" "MEMO:" "METHOD"
-                                           "SYNTAX"
-                                           "PREDICATE" "PRIMITIVE"
-                                           "STRUCT" "TAG" "TUPLE"
-                                           "TYPED" "TYPED:"
-                                           "UNIFORM-TUPLE"
-                                           "UNION-STRUCT" "UNION"
-                                           "VERTEX-FORMAT"))
-
-(defconst fuel-syntax--no-indent-def-starts '("ARTICLE"
-                                              "HELP"
-                                              "SINGLETONS"
-                                              "SPECIALIZED-ARRAYS"
-                                              "SYMBOLS"
-                                              "VARS"))
-
-(defconst fuel-syntax--indent-def-start-regex
-  (format "^\\(%s:\\)\\( \\|\n\\)" (regexp-opt fuel-syntax--indent-def-starts)))
-
-(defconst fuel-syntax--definition-start-regex
-  (format "^\\(%s:\\) " (regexp-opt (append fuel-syntax--no-indent-def-starts
-                                            fuel-syntax--indent-def-starts))))
-
-(defconst fuel-syntax--definition-end-regex
-  (format "\\(\\(^\\| +\\);\\( *%s\\)*\\($\\| +\\)\\)"
-          fuel-syntax--declaration-words-regex))
-
-(defconst fuel-syntax--single-liner-regex
-  (regexp-opt '("ABOUT:"
-                "ALIAS:"
-                "CONSTANT:" "C:" "C-TYPE:"
-                "DEFER:"
-                "FORGET:"
-                "GAME:" "GENERIC:" "GENERIC#" "GLSL-PROGRAM:" 
-                "HEX:" "HOOK:"
-                "IN:" "INSTANCE:"
-                "LIBRARY:"
-                "MAIN:" "MATH:" "MIXIN:"
-                "OCT:"
-                "POSTPONE:" "PRIVATE>" "<PRIVATE"
-                "QUALIFIED-WITH:" "QUALIFIED:"
-                "RENAME:"
-                "SINGLETON:" "SLOT:" "SPECIALIZED-ARRAY:" "SYMBOL:"
-                "TYPEDEF:"
-                "USE:"
-                "VAR:")))
-
-(defconst fuel-syntax--begin-of-def-regex
-  (format "^USING: \\|\\(%s\\)\\|\\(^%s .*\\)"
-          fuel-syntax--definition-start-regex
-          fuel-syntax--single-liner-regex))
-
-(defconst fuel-syntax--end-of-def-line-regex
-  (format "^.*%s" fuel-syntax--definition-end-regex))
-
-(defconst fuel-syntax--end-of-def-regex
-  (format "\\(%s\\)\\|\\(^%s .*\\)"
-          fuel-syntax--end-of-def-line-regex
-          fuel-syntax--single-liner-regex))
-
-(defconst fuel-syntax--word-signature-regex
-  (format ":[^ ]* \\([^ ]+\\)\\(%s\\)*" fuel-syntax--stack-effect-regex))
-
-(defconst fuel-syntax--defun-signature-regex
-  (format "\\(%s\\|%s\\)"
-          fuel-syntax--word-signature-regex
-          "M[^:]*: [^ ]+ [^ ]+"))
-
-(defconst fuel-syntax--constructor-decl-regex
-  "\\_<C: +\\(\\w+\\) +\\(\\w+\\)\\( .*\\)?$")
-
-(defconst fuel-syntax--typedef-regex
-  "\\_<TYPEDEF: +\\(\\w+\\) +\\(\\w+\\)\\( .*\\)?$")
-
-(defconst fuel-syntax--rename-regex
-  "\\_<RENAME: +\\(\\w+\\) +\\(\\w+\\) +=> +\\(\\w+\\)\\( .*\\)?$")
-
-
-;;; Factor syntax table
-
-(setq fuel-syntax--syntax-table
-  (let ((table (make-syntax-table)))
-    ;; Default is word constituent
-    (dotimes (i 256)
-      (modify-syntax-entry i "w" table))
-    ;; Whitespace (TAB is not whitespace)
-    (modify-syntax-entry ?\f " " table)
-    (modify-syntax-entry ?\r " " table)
-    (modify-syntax-entry ?\  " " table)
-    (modify-syntax-entry ?\n " " table)
-    table))
-
-(defconst fuel-syntax--syntactic-keywords
-  `(;; Strings and chars
-    ("\\_<<\\(\"\\)\\_>" (1 "<b"))
-    ("\\_<\\(\"\\)>\\_>" (1 ">b"))
-    ("\\( \\|^\\)\\(DLL\\|P\\|SBUF\\)?\\(\"\\)\\(\\([^\n\r\f\"\\]\\|\\\\.\\)*\\)\\(\"\\)"
-     (3 "\"") (6 "\""))
-    ("CHAR: \\(\"\\) [^\\\"]*?\\(\"\\)\\([^\\\"]\\|\\\\.\\)*?\\(\"\\)"
-     (1 "w") (2 "<b") (4 ">b"))
-    ("\\(CHAR:\\|\\\\\\) \\(\\w\\|!\\)\\( \\|$\\)" (2 "w"))
-    ;; Comments
-    ("\\_<\\(#?!\\) .*\\(\n\\|$\\)" (1 "<") (2 ">"))
-    ("\\_<\\(#?!\\)\\(\n\\|$\\)" (1 "<") (2 ">"))
-    ;; postpone
-    ("\\_<POSTPONE:\\( \\).*\\(\n\\)" (1 "<b") (2 ">b"))
-    ;; Multiline constructs
-    ("\\_<\\(E\\)BNF:\\( \\|\n\\)" (1 "<b"))
-    ("\\_<;EBN\\(F\\)\\_>" (1 ">b"))
-    ("\\_<\\(U\\)SING: \\(;\\)" (1 "<b") (2 ">b"))
-    ("\\_<USING:\\( \\)" (1 "<b"))
-    ("\\_<\\(C\\)-ENUM: \\(;\\)" (1 "<b") (2 ">b"))
-    ("\\_<C-ENUM:\\( \\|\n\\)" (1 "<b"))
-    ("\\_<TUPLE: +\\w+? +< +\\w+? *\\( \\|\n\\)\\([^;]\\|$\\)" (1 "<b"))
-    ("\\_<TUPLE: +\\w+? *\\( \\|\n\\)\\([^;<\n]\\|\\_>\\)" (1 "<b"))
-    ("\\_<\\(SYMBOLS\\|VARS\\|SPECIALIZED-ARRAYS\\|SINGLETONS\\): *?\\( \\|\n\\)\\([^;\n]\\|\\_>\\)"
-     (2 "<b"))
-    ("\\(\n\\| \\);\\_>" (1 ">b"))
-    ;; Let and lambda:
-    ("\\_<\\(!(\\) .* \\()\\)" (1 "<") (2 ">"))
-    ("\\(\\[\\)\\(let\\|let\\*\\)\\( \\|$\\)" (1 "(]"))
-    ("\\(\\[\\)\\(|\\) +[^|]* \\(|\\)" (1 "(]") (2 "(|") (3 ")|"))
-    (" \\(|\\) " (1 "(|"))
-    (" \\(|\\)$" (1 ")"))
-    ;; Opening brace words:
-    ("\\_<\\w*\\({\\)\\_>" (1 "(}"))
-    ("\\_<\\(}\\)\\_>" (1 "){"))
-    ;; Parenthesis:
-    ("\\_<\\((\\)\\_>" (1 "()"))
-    ("\\_<\\w*\\((\\)\\_>" (1 "()"))
-    ("\\_<\\()\\)\\_>" (1 ")("))
-    ("\\_<(\\((\\)\\_>" (1 "()"))
-    ("\\_<\\()\\))\\_>" (1 ")("))
-    ;; Quotations:
-    ("\\_<'\\(\\[\\)\\_>" (1 "(]"))      ; fried
-    ("\\_<$\\(\\[\\)\\_>" (1 "(]"))      ; parse-time
-    ("\\_<\\(\\[\\)\\_>" (1 "(]"))
-    ("\\_<\\(\\]\\)\\_>" (1 ")["))))
-
-
-;;; Source code analysis:
-
-(defsubst fuel-syntax--brackets-depth ()
-  (nth 0 (syntax-ppss)))
-
-(defsubst fuel-syntax--brackets-start ()
-  (nth 1 (syntax-ppss)))
-
-(defun fuel-syntax--brackets-end ()
-  (save-excursion
-    (goto-char (fuel-syntax--brackets-start))
-    (condition-case nil
-        (progn (forward-sexp)
-               (1- (point)))
-      (error -1))))
-
-(defsubst fuel-syntax--indentation-at (pos)
-  (save-excursion (goto-char pos) (current-indentation)))
-
-(defsubst fuel-syntax--increased-indentation (&optional i)
-  (+ (or i (current-indentation)) factor-indent-width))
-(defsubst fuel-syntax--decreased-indentation (&optional i)
-  (- (or i (current-indentation)) factor-indent-width))
-
-(defsubst fuel-syntax--at-begin-of-def ()
-  (looking-at fuel-syntax--begin-of-def-regex))
-
-(defsubst fuel-syntax--at-begin-of-indent-def ()
-  (looking-at fuel-syntax--indent-def-start-regex))
-
-(defsubst fuel-syntax--at-end-of-def ()
-  (looking-at fuel-syntax--end-of-def-regex))
-
-(defsubst fuel-syntax--looking-at-emptiness ()
-  (looking-at "^[ ]*$\\|$"))
-
-(defsubst fuel-syntax--is-last-char (pos)
-  (save-excursion
-    (goto-char (1+ pos))
-    (looking-at-p "[ ]*$")))
-
-(defsubst fuel-syntax--line-offset (pos)
-  (- pos (save-excursion
-           (goto-char pos)
-           (beginning-of-line)
-           (point))))
-
-(defun fuel-syntax--previous-non-blank ()
-  (forward-line -1)
-  (while (and (not (bobp)) (fuel-syntax--looking-at-emptiness))
-    (forward-line -1)))
-
-(defun fuel-syntax--beginning-of-block-pos ()
-  (save-excursion
-    (if (> (fuel-syntax--brackets-depth) 0)
-        (fuel-syntax--brackets-start)
-      (fuel-syntax--beginning-of-defun)
-      (point))))
-
-(defun fuel-syntax--at-setter-line ()
-  (save-excursion
-    (beginning-of-line)
-    (when (re-search-forward fuel-syntax--setter-regex
-                             (line-end-position)
-                             t)
-      (let* ((to (match-beginning 0))
-             (from (fuel-syntax--beginning-of-block-pos)))
-        (goto-char from)
-        (let ((depth (fuel-syntax--brackets-depth)))
-          (and (or (re-search-forward fuel-syntax--constructor-regex to t)
-                   (re-search-forward fuel-syntax--setter-regex to t))
-               (= depth (fuel-syntax--brackets-depth))))))))
-
-(defun fuel-syntax--at-constructor-line ()
-  (save-excursion
-    (beginning-of-line)
-    (re-search-forward fuel-syntax--constructor-regex (line-end-position) t)))
-
-(defsubst fuel-syntax--at-using ()
-  (looking-at fuel-syntax--using-lines-regex))
-
-(defun fuel-syntax--in-using ()
-  (let ((p (point)))
-    (save-excursion
-      (and (re-search-backward "^USING: " nil t)
-           (re-search-forward " ;" nil t)
-           (< p (match-end 0))))))
-
-(defsubst fuel-syntax--beginning-of-defun (&optional times)
-  (re-search-backward fuel-syntax--begin-of-def-regex nil t times))
-
-(defsubst fuel-syntax--end-of-defun ()
-  (re-search-forward fuel-syntax--end-of-def-regex nil t))
-
-(defsubst fuel-syntax--end-of-defun-pos ()
-  (save-excursion
-    (re-search-forward fuel-syntax--end-of-def-regex nil t)
-    (point)))
-
-(defun fuel-syntax--beginning-of-body ()
-  (let ((p (point)))
-    (and (fuel-syntax--beginning-of-defun)
-         (re-search-forward fuel-syntax--defun-signature-regex p t)
-         (not (re-search-forward fuel-syntax--end-of-def-regex p t)))))
-
-(defun fuel-syntax--beginning-of-sexp ()
-  (if (> (fuel-syntax--brackets-depth) 0)
-      (goto-char (fuel-syntax--brackets-start))
-    (fuel-syntax--beginning-of-body)))
-
-(defsubst fuel-syntax--beginning-of-sexp-pos ()
-  (save-excursion (fuel-syntax--beginning-of-sexp) (point)))
-
-
-;;; USING/IN:
-
-(make-variable-buffer-local
- (defvar fuel-syntax--current-vocab-function 'fuel-syntax--find-in))
-
-(defsubst fuel-syntax--current-vocab ()
-  (funcall fuel-syntax--current-vocab-function))
-
-(defun fuel-syntax--find-in ()
-  (save-excursion
-    (when (re-search-backward fuel-syntax--current-vocab-regex nil t)
-      (match-string-no-properties 1))))
-
-(make-variable-buffer-local
- (defvar fuel-syntax--usings-function 'fuel-syntax--find-usings))
-
-(defsubst fuel-syntax--usings ()
-  (funcall fuel-syntax--usings-function))
-
-(defun fuel-syntax--file-has-private ()
-  (save-excursion
-    (goto-char (point-min))
-    (and (re-search-forward "\\_<<PRIVATE\\_>" nil t)
-         (re-search-forward "\\_<PRIVATE>\\_>" nil t))))
-
-(defun fuel-syntax--find-usings (&optional no-private)
-  (save-excursion
-    (let ((usings))
-      (goto-char (point-max))
-      (while (re-search-backward fuel-syntax--using-lines-regex nil t)
-        (dolist (u (split-string (match-string-no-properties 1) nil t))
-          (push u usings)))
-      (when (and (not no-private) (fuel-syntax--file-has-private))
-        (goto-char (point-max))
-        (push (concat (fuel-syntax--find-in) ".private") usings))
-      usings)))
-
-
-(provide 'fuel-syntax)
-;;; fuel-syntax.el ends here
+;;; fuel-syntax.el --- auxiliar definitions for factor code navigation.
+
+;; Copyright (C) 2008, 2009  Jose Antonio Ortega Ruiz
+;; See http://factorcode.org/license.txt for BSD license.
+
+;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
+;; Keywords: languages
+
+;;; Commentary:
+
+;; Auxiliar constants and functions to parse factor code.
+
+;;; Code:
+
+(require 'thingatpt)
+
+
+;;; Thing-at-point support for factor symbols:
+
+(defun fuel-syntax--beginning-of-symbol ()
+  "Move point to the beginning of the current symbol."
+  (skip-syntax-backward "w_()"))
+
+(defsubst fuel-syntax--beginning-of-symbol-pos ()
+  (save-excursion (fuel-syntax--beginning-of-symbol) (point)))
+
+(defun fuel-syntax--end-of-symbol ()
+  "Move point to the end of the current symbol."
+  (skip-syntax-forward "w_()"))
+
+(defsubst fuel-syntax--end-of-symbol-pos ()
+  (save-excursion (fuel-syntax--end-of-symbol) (point)))
+
+(put 'factor-symbol 'end-op 'fuel-syntax--end-of-symbol)
+(put 'factor-symbol 'beginning-op 'fuel-syntax--beginning-of-symbol)
+
+(defsubst fuel-syntax-symbol-at-point ()
+  (let ((s (substring-no-properties (thing-at-point 'factor-symbol))))
+    (and (> (length s) 0) s)))
+
+
+
+;;; Regexps galore:
+
+(defconst fuel-syntax--parsing-words
+  '(":" "::" ";" "&:" "<<" "<PRIVATE" ">>"
+    "ABOUT:" "ALIAS:" "ALIEN:" "ARTICLE:"
+    "B" "BIN:"
+    "C:" "CALLBACK:" "C-ENUM:" "C-STRUCT:" "C-TYPE:" "C-UNION:" "CHAR:" "CONSTANT:" "call-next-method"
+    "DEFER:"
+    "EBNF:" ";EBNF" "ERROR:" "EXCLUDE:"
+    "f" "FORGET:" "FROM:" "FUNCTION:"
+    "GAME:" "GENERIC#" "GENERIC:"
+    "GLSL-SHADER:" "GLSL-PROGRAM:"
+    "HELP:" "HEX:" "HOOK:"
+    "IN:" "initial:" "INSTANCE:" "INTERSECTION:"
+    "LIBRARY:"
+    "M:" "M::" "MACRO:" "MACRO::" "MAIN:" "MATH:"
+    "MEMO:" "MEMO:" "METHOD:" "MIXIN:"
+    "OCT:"
+    "POSTPONE:" "PREDICATE:" "PRIMITIVE:" "PRIVATE>" "PROVIDE:"
+    "QUALIFIED-WITH:" "QUALIFIED:"
+    "read-only" "RENAME:" "REQUIRE:"  "REQUIRES:"
+    "SINGLETON:" "SINGLETONS:" "SLOT:" "SPECIALIZED-ARRAY:" "SPECIALIZED-ARRAYS:" "STRING:" "STRUCT:" "SYMBOL:" "SYMBOLS:" "SYNTAX:"
+    "TUPLE:" "t" "t?" "TYPEDEF:" "TYPED:" "TYPED::"
+    "UNIFORM-TUPLE:" "UNION:" "UNION-STRUCT:" "USE:" "USING:"
+    "VARS:" "VERTEX-FORMAT:"))
+
+(defconst fuel-syntax--parsing-words-regex
+  (regexp-opt fuel-syntax--parsing-words 'words))
+
+(defconst fuel-syntax--bracers
+  '("B" "BV" "C" "CS" "H" "T" "V" "W"))
+
+(defconst fuel-syntax--brace-words-regex
+  (format "%s{" (regexp-opt fuel-syntax--bracers t)))
+
+(defconst fuel-syntax--declaration-words
+  '("flushable" "foldable" "inline" "parsing" "recursive" "delimiter"))
+
+(defconst fuel-syntax--declaration-words-regex
+  (regexp-opt fuel-syntax--declaration-words 'words))
+
+(defsubst fuel-syntax--second-word-regex (prefixes)
+  (format "%s +\\([^ \r\n]+\\)" (regexp-opt prefixes t)))
+
+(defconst fuel-syntax--method-definition-regex
+  "^M::? +\\([^ ]+\\) +\\([^ ]+\\)")
+
+(defconst fuel-syntax--integer-regex
+  "\\_<-?[0-9]+\\_>")
+
+(defconst fuel-syntax--raw-float-regex
+  "[0-9]*\\.[0-9]*\\([eE][+-]?[0-9]+\\)?")
+
+(defconst fuel-syntax--float-regex
+  (format "\\_<-?%s\\_>" fuel-syntax--raw-float-regex))
+
+(defconst fuel-syntax--number-regex
+  (format "\\([0-9]+\\|%s\\)" fuel-syntax--raw-float-regex))
+
+(defconst fuel-syntax--ratio-regex
+  (format "\\_<[+-]?%s/-?%s\\_>"
+          fuel-syntax--number-regex
+          fuel-syntax--number-regex))
+
+(defconst fuel-syntax--bad-string-regex
+  "\\_<\"[^>]\\([^\"\n]\\|\\\\\"\\)*\n")
+
+(defconst fuel-syntax--word-definition-regex
+  (format "\\_<\\(%s\\)?: +\\_<\\(\\w+\\)\\_>"
+          (regexp-opt
+           '(":" "GENERIC" "DEFER" "HOOK" "MAIN" "MATH" "POSTPONE"
+             "SYMBOL" "SYNTAX" "TYPED" "RENAME"))))
+
+(defconst fuel-syntax--alias-definition-regex
+  "^ALIAS: +\\(\\_<.+?\\_>\\) +\\(\\_<.+?\\_>\\)")
+
+(defconst fuel-syntax--vocab-ref-regexp
+  (fuel-syntax--second-word-regex
+   '("IN:" "USE:" "FROM:" "EXCLUDE:" "QUALIFIED:" "QUALIFIED-WITH:")))
+
+(defconst fuel-syntax--int-constant-def-regex
+  (fuel-syntax--second-word-regex '("ALIEN:" "CHAR:" "BIN:" "HEX:" "OCT:")))
+
+(defconst fuel-syntax--type-definition-regex
+  (fuel-syntax--second-word-regex
+   '("C-STRUCT:" "C-UNION:" "MIXIN:" "TUPLE:" "SINGLETON:" "SPECIALIZED-ARRAY:" "STRUCT:" "UNION:" "UNION-STRUCT:")))
+
+(defconst fuel-syntax--tuple-decl-regex
+  "^TUPLE: +\\([^ \n]+\\) +< +\\([^ \n]+\\)\\_>")
+
+(defconst fuel-syntax--constructor-regex "<[^ >]+>")
+
+(defconst fuel-syntax--getter-regex "\\(^\\|\\_<\\)[^ ]+?>>\\_>")
+(defconst fuel-syntax--setter-regex "\\_<>>.+?\\_>")
+
+(defconst fuel-syntax--symbol-definition-regex
+  (fuel-syntax--second-word-regex '("&:" "SYMBOL:" "VAR:")))
+
+(defconst fuel-syntax--stack-effect-regex
+  "\\( ( [^\n]* )\\)\\|\\( (( [^\n]* ))\\)")
+
+(defconst fuel-syntax--using-lines-regex "^USING: +\\([^;]+\\);")
+
+(defconst fuel-syntax--use-line-regex "^USE: +\\(.*\\)$")
+
+(defconst fuel-syntax--current-vocab-regex "^IN: +\\([^ \r\n\f]+\\)")
+
+(defconst fuel-syntax--sub-vocab-regex "^<\\([^ \n]+\\) *$")
+
+(defconst fuel-syntax--alien-function-regex
+  "\\_<FUNCTION: \\(\\w+\\) \\(\\w+\\)")
+
+(defconst fuel-syntax--alien-callback-regex
+  "\\_<CALLBACK: \\(\\w+\\) \\(\\w+\\)")
+
+(defconst fuel-syntax--indent-def-starts '("" ":"
+                                           "C-ENUM" "C-STRUCT" "C-UNION"
+                                           "FROM" "FUNCTION:"
+                                           "INTERSECTION:"
+                                           "M" "M:" "MACRO" "MACRO:"
+                                           "MEMO" "MEMO:" "METHOD"
+                                           "SYNTAX"
+                                           "PREDICATE" "PRIMITIVE"
+                                           "STRUCT" "TAG" "TUPLE"
+                                           "TYPED" "TYPED:"
+                                           "UNIFORM-TUPLE"
+                                           "UNION-STRUCT" "UNION"
+                                           "VERTEX-FORMAT"))
+
+(defconst fuel-syntax--no-indent-def-starts '("ARTICLE"
+                                              "HELP"
+                                              "SINGLETONS"
+                                              "SPECIALIZED-ARRAYS"
+                                              "SYMBOLS"
+                                              "VARS"))
+
+(defconst fuel-syntax--indent-def-start-regex
+  (format "^\\(%s:\\)\\( \\|\n\\)" (regexp-opt fuel-syntax--indent-def-starts)))
+
+(defconst fuel-syntax--definition-start-regex
+  (format "^\\(%s:\\) " (regexp-opt (append fuel-syntax--no-indent-def-starts
+                                            fuel-syntax--indent-def-starts))))
+
+(defconst fuel-syntax--definition-end-regex
+  (format "\\(\\(^\\| +\\);\\( *%s\\)*\\($\\| +\\)\\)"
+          fuel-syntax--declaration-words-regex))
+
+(defconst fuel-syntax--single-liner-regex
+  (regexp-opt '("ABOUT:"
+                "ALIAS:"
+                "CONSTANT:" "C:" "C-TYPE:"
+                "DEFER:"
+                "FORGET:"
+                "GAME:" "GENERIC:" "GENERIC#" "GLSL-PROGRAM:" 
+                "HEX:" "HOOK:"
+                "IN:" "INSTANCE:"
+                "LIBRARY:"
+                "MAIN:" "MATH:" "MIXIN:"
+                "OCT:"
+                "POSTPONE:" "PRIVATE>" "<PRIVATE"
+                "QUALIFIED-WITH:" "QUALIFIED:"
+                "RENAME:"
+                "SINGLETON:" "SLOT:" "SPECIALIZED-ARRAY:" "SYMBOL:"
+                "TYPEDEF:"
+                "USE:"
+                "VAR:")))
+
+(defconst fuel-syntax--begin-of-def-regex
+  (format "^USING: \\|\\(%s\\)\\|\\(^%s .*\\)"
+          fuel-syntax--definition-start-regex
+          fuel-syntax--single-liner-regex))
+
+(defconst fuel-syntax--end-of-def-line-regex
+  (format "^.*%s" fuel-syntax--definition-end-regex))
+
+(defconst fuel-syntax--end-of-def-regex
+  (format "\\(%s\\)\\|\\(^%s .*\\)"
+          fuel-syntax--end-of-def-line-regex
+          fuel-syntax--single-liner-regex))
+
+(defconst fuel-syntax--word-signature-regex
+  (format ":[^ ]* \\([^ ]+\\)\\(%s\\)*" fuel-syntax--stack-effect-regex))
+
+(defconst fuel-syntax--defun-signature-regex
+  (format "\\(%s\\|%s\\)"
+          fuel-syntax--word-signature-regex
+          "M[^:]*: [^ ]+ [^ ]+"))
+
+(defconst fuel-syntax--constructor-decl-regex
+  "\\_<C: +\\(\\w+\\) +\\(\\w+\\)\\( .*\\)?$")
+
+(defconst fuel-syntax--typedef-regex
+  "\\_<TYPEDEF: +\\(\\w+\\) +\\(\\w+\\)\\( .*\\)?$")
+
+(defconst fuel-syntax--rename-regex
+  "\\_<RENAME: +\\(\\w+\\) +\\(\\w+\\) +=> +\\(\\w+\\)\\( .*\\)?$")
+
+
+;;; Factor syntax table
+
+(setq fuel-syntax--syntax-table
+  (let ((table (make-syntax-table)))
+    ;; Default is word constituent
+    (dotimes (i 256)
+      (modify-syntax-entry i "w" table))
+    ;; Whitespace (TAB is not whitespace)
+    (modify-syntax-entry ?\f " " table)
+    (modify-syntax-entry ?\r " " table)
+    (modify-syntax-entry ?\  " " table)
+    (modify-syntax-entry ?\n " " table)
+    table))
+
+(defconst fuel-syntax--syntactic-keywords
+  `(;; Strings and chars
+    ("\\_<<\\(\"\\)\\_>" (1 "<b"))
+    ("\\_<\\(\"\\)>\\_>" (1 ">b"))
+    ("\\( \\|^\\)\\(DLL\\|P\\|SBUF\\)?\\(\"\\)\\(\\([^\n\r\f\"\\]\\|\\\\.\\)*\\)\\(\"\\)"
+     (3 "\"") (6 "\""))
+    ("CHAR: \\(\"\\) [^\\\"]*?\\(\"\\)\\([^\\\"]\\|\\\\.\\)*?\\(\"\\)"
+     (1 "w") (2 "<b") (4 ">b"))
+    ("\\(CHAR:\\|\\\\\\) \\(\\w\\|!\\)\\( \\|$\\)" (2 "w"))
+    ;; Comments
+    ("\\_<\\(#?!\\) .*\\(\n\\|$\\)" (1 "<") (2 ">"))
+    ("\\_<\\(#?!\\)\\(\n\\|$\\)" (1 "<") (2 ">"))
+    ;; postpone
+    ("\\_<POSTPONE:\\( \\).*\\(\n\\)" (1 "<b") (2 ">b"))
+    ;; Multiline constructs
+    ("\\_<\\(E\\)BNF:\\( \\|\n\\)" (1 "<b"))
+    ("\\_<;EBN\\(F\\)\\_>" (1 ">b"))
+    ("\\_<\\(U\\)SING: \\(;\\)" (1 "<b") (2 ">b"))
+    ("\\_<USING:\\( \\)" (1 "<b"))
+    ("\\_<\\(C\\)-ENUM: \\(;\\)" (1 "<b") (2 ">b"))
+    ("\\_<C-ENUM:\\( \\|\n\\)" (1 "<b"))
+    ("\\_<TUPLE: +\\w+? +< +\\w+? *\\( \\|\n\\)\\([^;]\\|$\\)" (1 "<b"))
+    ("\\_<TUPLE: +\\w+? *\\( \\|\n\\)\\([^;<\n]\\|\\_>\\)" (1 "<b"))
+    ("\\_<\\(SYMBOLS\\|VARS\\|SPECIALIZED-ARRAYS\\|SINGLETONS\\): *?\\( \\|\n\\)\\([^;\n]\\|\\_>\\)"
+     (2 "<b"))
+    ("\\(\n\\| \\);\\_>" (1 ">b"))
+    ;; Let and lambda:
+    ("\\_<\\(!(\\) .* \\()\\)" (1 "<") (2 ">"))
+    ("\\(\\[\\)\\(let\\|let\\*\\)\\( \\|$\\)" (1 "(]"))
+    ("\\(\\[\\)\\(|\\) +[^|]* \\(|\\)" (1 "(]") (2 "(|") (3 ")|"))
+    (" \\(|\\) " (1 "(|"))
+    (" \\(|\\)$" (1 ")"))
+    ;; Opening brace words:
+    ("\\_<\\w*\\({\\)\\_>" (1 "(}"))
+    ("\\_<\\(}\\)\\_>" (1 "){"))
+    ;; Parenthesis:
+    ("\\_<\\((\\)\\_>" (1 "()"))
+    ("\\_<\\w*\\((\\)\\_>" (1 "()"))
+    ("\\_<\\()\\)\\_>" (1 ")("))
+    ("\\_<(\\((\\)\\_>" (1 "()"))
+    ("\\_<\\()\\))\\_>" (1 ")("))
+    ;; Quotations:
+    ("\\_<'\\(\\[\\)\\_>" (1 "(]"))      ; fried
+    ("\\_<$\\(\\[\\)\\_>" (1 "(]"))      ; parse-time
+    ("\\_<\\(\\[\\)\\_>" (1 "(]"))
+    ("\\_<\\(\\]\\)\\_>" (1 ")["))))
+
+
+;;; Source code analysis:
+
+(defsubst fuel-syntax--brackets-depth ()
+  (nth 0 (syntax-ppss)))
+
+(defsubst fuel-syntax--brackets-start ()
+  (nth 1 (syntax-ppss)))
+
+(defun fuel-syntax--brackets-end ()
+  (save-excursion
+    (goto-char (fuel-syntax--brackets-start))
+    (condition-case nil
+        (progn (forward-sexp)
+               (1- (point)))
+      (error -1))))
+
+(defsubst fuel-syntax--indentation-at (pos)
+  (save-excursion (goto-char pos) (current-indentation)))
+
+(defsubst fuel-syntax--increased-indentation (&optional i)
+  (+ (or i (current-indentation)) factor-indent-width))
+(defsubst fuel-syntax--decreased-indentation (&optional i)
+  (- (or i (current-indentation)) factor-indent-width))
+
+(defsubst fuel-syntax--at-begin-of-def ()
+  (looking-at fuel-syntax--begin-of-def-regex))
+
+(defsubst fuel-syntax--at-begin-of-indent-def ()
+  (looking-at fuel-syntax--indent-def-start-regex))
+
+(defsubst fuel-syntax--at-end-of-def ()
+  (looking-at fuel-syntax--end-of-def-regex))
+
+(defsubst fuel-syntax--looking-at-emptiness ()
+  (looking-at "^[ ]*$\\|$"))
+
+(defsubst fuel-syntax--is-last-char (pos)
+  (save-excursion
+    (goto-char (1+ pos))
+    (looking-at-p "[ ]*$")))
+
+(defsubst fuel-syntax--line-offset (pos)
+  (- pos (save-excursion
+           (goto-char pos)
+           (beginning-of-line)
+           (point))))
+
+(defun fuel-syntax--previous-non-blank ()
+  (forward-line -1)
+  (while (and (not (bobp)) (fuel-syntax--looking-at-emptiness))
+    (forward-line -1)))
+
+(defun fuel-syntax--beginning-of-block-pos ()
+  (save-excursion
+    (if (> (fuel-syntax--brackets-depth) 0)
+        (fuel-syntax--brackets-start)
+      (fuel-syntax--beginning-of-defun)
+      (point))))
+
+(defun fuel-syntax--at-setter-line ()
+  (save-excursion
+    (beginning-of-line)
+    (when (re-search-forward fuel-syntax--setter-regex
+                             (line-end-position)
+                             t)
+      (let* ((to (match-beginning 0))
+             (from (fuel-syntax--beginning-of-block-pos)))
+        (goto-char from)
+        (let ((depth (fuel-syntax--brackets-depth)))
+          (and (or (re-search-forward fuel-syntax--constructor-regex to t)
+                   (re-search-forward fuel-syntax--setter-regex to t))
+               (= depth (fuel-syntax--brackets-depth))))))))
+
+(defun fuel-syntax--at-constructor-line ()
+  (save-excursion
+    (beginning-of-line)
+    (re-search-forward fuel-syntax--constructor-regex (line-end-position) t)))
+
+(defsubst fuel-syntax--at-using ()
+  (looking-at fuel-syntax--using-lines-regex))
+
+(defun fuel-syntax--in-using ()
+  (let ((p (point)))
+    (save-excursion
+      (and (re-search-backward "^USING: " nil t)
+           (re-search-forward " ;" nil t)
+           (< p (match-end 0))))))
+
+(defsubst fuel-syntax--beginning-of-defun (&optional times)
+  (re-search-backward fuel-syntax--begin-of-def-regex nil t times))
+
+(defsubst fuel-syntax--end-of-defun ()
+  (re-search-forward fuel-syntax--end-of-def-regex nil t))
+
+(defsubst fuel-syntax--end-of-defun-pos ()
+  (save-excursion
+    (re-search-forward fuel-syntax--end-of-def-regex nil t)
+    (point)))
+
+(defun fuel-syntax--beginning-of-body ()
+  (let ((p (point)))
+    (and (fuel-syntax--beginning-of-defun)
+         (re-search-forward fuel-syntax--defun-signature-regex p t)
+         (not (re-search-forward fuel-syntax--end-of-def-regex p t)))))
+
+(defun fuel-syntax--beginning-of-sexp ()
+  (if (> (fuel-syntax--brackets-depth) 0)
+      (goto-char (fuel-syntax--brackets-start))
+    (fuel-syntax--beginning-of-body)))
+
+(defsubst fuel-syntax--beginning-of-sexp-pos ()
+  (save-excursion (fuel-syntax--beginning-of-sexp) (point)))
+
+
+;;; USING/IN:
+
+(make-variable-buffer-local
+ (defvar fuel-syntax--current-vocab-function 'fuel-syntax--find-in))
+
+(defsubst fuel-syntax--current-vocab ()
+  (funcall fuel-syntax--current-vocab-function))
+
+(defun fuel-syntax--find-in ()
+  (save-excursion
+    (when (re-search-backward fuel-syntax--current-vocab-regex nil t)
+      (match-string-no-properties 1))))
+
+(make-variable-buffer-local
+ (defvar fuel-syntax--usings-function 'fuel-syntax--find-usings))
+
+(defsubst fuel-syntax--usings ()
+  (funcall fuel-syntax--usings-function))
+
+(defun fuel-syntax--file-has-private ()
+  (save-excursion
+    (goto-char (point-min))
+    (and (re-search-forward "\\_<<PRIVATE\\_>" nil t)
+         (re-search-forward "\\_<PRIVATE>\\_>" nil t))))
+
+(defun fuel-syntax--find-usings (&optional no-private)
+  (save-excursion
+    (let ((usings))
+      (goto-char (point-max))
+      (while (re-search-backward fuel-syntax--using-lines-regex nil t)
+        (dolist (u (split-string (match-string-no-properties 1) nil t))
+          (push u usings)))
+      (when (and (not no-private) (fuel-syntax--file-has-private))
+        (goto-char (point-max))
+        (push (concat (fuel-syntax--find-in) ".private") usings))
+      usings)))
+
+
+(provide 'fuel-syntax)
+;;; fuel-syntax.el ends here

From a56d0a760283d928017ab9b20ca4873de9ff92a7 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Sun, 21 Feb 2010 16:43:09 -0800
Subject: [PATCH 149/250] Bindings to the HID portion of the Windows DDK.

---
 basis/windows/ddk/hid/authors.txt |   1 +
 basis/windows/ddk/hid/hid.factor  | 805 ++++++++++++++++++++++++++++++
 2 files changed, 806 insertions(+)
 create mode 100644 basis/windows/ddk/hid/authors.txt
 create mode 100644 basis/windows/ddk/hid/hid.factor

diff --git a/basis/windows/ddk/hid/authors.txt b/basis/windows/ddk/hid/authors.txt
new file mode 100644
index 0000000000..67cf648cf5
--- /dev/null
+++ b/basis/windows/ddk/hid/authors.txt
@@ -0,0 +1 @@
+Erik Charlebois
\ No newline at end of file
diff --git a/basis/windows/ddk/hid/hid.factor b/basis/windows/ddk/hid/hid.factor
new file mode 100644
index 0000000000..9c8a55ee7c
--- /dev/null
+++ b/basis/windows/ddk/hid/hid.factor
@@ -0,0 +1,805 @@
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.c-types alien.libraries alien.syntax classes.struct
+kernel math windows.types windows.ole32 ;
+IN: windows.ddk.hid
+
+<< "hid" "hid.dll" "stdcall" add-library >>
+LIBRARY: hid
+
+TYPEDEF: LONG   NTSTATUS
+TYPEDEF: USHORT USAGE
+TYPEDEF: USAGE* PUSAGE
+
+CONSTANT: HID_USAGE_PAGE_UNDEFINED      HEX: 00
+CONSTANT: HID_USAGE_PAGE_GENERIC        HEX: 01
+CONSTANT: HID_USAGE_PAGE_SIMULATION     HEX: 02
+CONSTANT: HID_USAGE_PAGE_VR             HEX: 03
+CONSTANT: HID_USAGE_PAGE_SPORT          HEX: 04
+CONSTANT: HID_USAGE_PAGE_GAME           HEX: 05
+CONSTANT: HID_USAGE_PAGE_KEYBOARD       HEX: 07
+CONSTANT: HID_USAGE_PAGE_LED            HEX: 08
+CONSTANT: HID_USAGE_PAGE_BUTTON         HEX: 09
+CONSTANT: HID_USAGE_PAGE_ORDINAL        HEX: 0A
+CONSTANT: HID_USAGE_PAGE_TELEPHONY      HEX: 0B
+CONSTANT: HID_USAGE_PAGE_CONSUMER       HEX: 0C
+CONSTANT: HID_USAGE_PAGE_DIGITIZER      HEX: 0D
+CONSTANT: HID_USAGE_PAGE_UNICODE        HEX: 10
+CONSTANT: HID_USAGE_PAGE_ALPHANUMERIC   HEX: 14
+
+CONSTANT: HID_USAGE_PAGE_MICROSOFT_BLUETOOTH_HANDSFREE  HEX: FFF3
+
+CONSTANT: HID_USAGE_GENERIC_POINTER      HEX: 01
+CONSTANT: HID_USAGE_GENERIC_MOUSE        HEX: 02
+CONSTANT: HID_USAGE_GENERIC_JOYSTICK     HEX: 04
+CONSTANT: HID_USAGE_GENERIC_GAMEPAD      HEX: 05
+CONSTANT: HID_USAGE_GENERIC_KEYBOARD     HEX: 06
+CONSTANT: HID_USAGE_GENERIC_KEYPAD       HEX: 07
+CONSTANT: HID_USAGE_GENERIC_SYSTEM_CTL   HEX: 80
+
+CONSTANT: HID_USAGE_GENERIC_X                        HEX: 30
+CONSTANT: HID_USAGE_GENERIC_Y                        HEX: 31
+CONSTANT: HID_USAGE_GENERIC_Z                        HEX: 32
+CONSTANT: HID_USAGE_GENERIC_RX                       HEX: 33
+CONSTANT: HID_USAGE_GENERIC_RY                       HEX: 34
+CONSTANT: HID_USAGE_GENERIC_RZ                       HEX: 35
+CONSTANT: HID_USAGE_GENERIC_SLIDER                   HEX: 36
+CONSTANT: HID_USAGE_GENERIC_DIAL                     HEX: 37
+CONSTANT: HID_USAGE_GENERIC_WHEEL                    HEX: 38
+CONSTANT: HID_USAGE_GENERIC_HATSWITCH                HEX: 39
+CONSTANT: HID_USAGE_GENERIC_COUNTED_BUFFER           HEX: 3A
+CONSTANT: HID_USAGE_GENERIC_BYTE_COUNT               HEX: 3B
+CONSTANT: HID_USAGE_GENERIC_MOTION_WAKEUP            HEX: 3C
+CONSTANT: HID_USAGE_GENERIC_VX                       HEX: 40
+CONSTANT: HID_USAGE_GENERIC_VY                       HEX: 41
+CONSTANT: HID_USAGE_GENERIC_VZ                       HEX: 42
+CONSTANT: HID_USAGE_GENERIC_VBRX                     HEX: 43
+CONSTANT: HID_USAGE_GENERIC_VBRY                     HEX: 44
+CONSTANT: HID_USAGE_GENERIC_VBRZ                     HEX: 45
+CONSTANT: HID_USAGE_GENERIC_VNO                      HEX: 46
+CONSTANT: HID_USAGE_GENERIC_SYSCTL_POWER             HEX: 81
+CONSTANT: HID_USAGE_GENERIC_SYSCTL_SLEEP             HEX: 82
+CONSTANT: HID_USAGE_GENERIC_SYSCTL_WAKE              HEX: 83
+CONSTANT: HID_USAGE_GENERIC_SYSCTL_CONTEXT_MENU      HEX: 84
+CONSTANT: HID_USAGE_GENERIC_SYSCTL_MAIN_MENU         HEX: 85
+CONSTANT: HID_USAGE_GENERIC_SYSCTL_APP_MENU          HEX: 86
+CONSTANT: HID_USAGE_GENERIC_SYSCTL_HELP_MENU         HEX: 87
+CONSTANT: HID_USAGE_GENERIC_SYSCTL_MENU_EXIT         HEX: 88
+CONSTANT: HID_USAGE_GENERIC_SYSCTL_MENU_SELECT       HEX: 89
+CONSTANT: HID_USAGE_GENERIC_SYSCTL_MENU_RIGHT        HEX: 8A
+CONSTANT: HID_USAGE_GENERIC_SYSCTL_MENU_LEFT         HEX: 8B
+CONSTANT: HID_USAGE_GENERIC_SYSCTL_MENU_UP           HEX: 8C
+CONSTANT: HID_USAGE_GENERIC_SYSCTL_MENU_DOWN         HEX: 8D
+
+CONSTANT: HID_USAGE_SIMULATION_RUDDER                HEX: BA
+CONSTANT: HID_USAGE_SIMULATION_THROTTLE              HEX: BB
+
+CONSTANT: HID_USAGE_KEYBOARD_NOEVENT     HEX: 00
+CONSTANT: HID_USAGE_KEYBOARD_ROLLOVER    HEX: 01
+CONSTANT: HID_USAGE_KEYBOARD_POSTFAIL    HEX: 02
+CONSTANT: HID_USAGE_KEYBOARD_UNDEFINED   HEX: 03
+
+CONSTANT: HID_USAGE_KEYBOARD_aA          HEX: 04
+CONSTANT: HID_USAGE_KEYBOARD_zZ          HEX: 1D
+CONSTANT: HID_USAGE_KEYBOARD_ONE         HEX: 1E
+CONSTANT: HID_USAGE_KEYBOARD_ZERO        HEX: 27
+CONSTANT: HID_USAGE_KEYBOARD_LCTRL       HEX: E0
+CONSTANT: HID_USAGE_KEYBOARD_LSHFT       HEX: E1
+CONSTANT: HID_USAGE_KEYBOARD_LALT        HEX: E2
+CONSTANT: HID_USAGE_KEYBOARD_LGUI        HEX: E3
+CONSTANT: HID_USAGE_KEYBOARD_RCTRL       HEX: E4
+CONSTANT: HID_USAGE_KEYBOARD_RSHFT       HEX: E5
+CONSTANT: HID_USAGE_KEYBOARD_RALT        HEX: E6
+CONSTANT: HID_USAGE_KEYBOARD_RGUI        HEX: E7
+CONSTANT: HID_USAGE_KEYBOARD_SCROLL_LOCK HEX: 47
+CONSTANT: HID_USAGE_KEYBOARD_NUM_LOCK    HEX: 53
+CONSTANT: HID_USAGE_KEYBOARD_CAPS_LOCK   HEX: 39
+CONSTANT: HID_USAGE_KEYBOARD_F1          HEX: 3A
+CONSTANT: HID_USAGE_KEYBOARD_F12         HEX: 45
+CONSTANT: HID_USAGE_KEYBOARD_RETURN      HEX: 28
+CONSTANT: HID_USAGE_KEYBOARD_ESCAPE      HEX: 29
+CONSTANT: HID_USAGE_KEYBOARD_DELETE      HEX: 2A
+CONSTANT: HID_USAGE_KEYBOARD_PRINT_SCREEN HEX: 46
+
+CONSTANT: HID_USAGE_LED_NUM_LOCK               HEX: 01
+CONSTANT: HID_USAGE_LED_CAPS_LOCK              HEX: 02
+CONSTANT: HID_USAGE_LED_SCROLL_LOCK            HEX: 03
+CONSTANT: HID_USAGE_LED_COMPOSE                HEX: 04
+CONSTANT: HID_USAGE_LED_KANA                   HEX: 05
+CONSTANT: HID_USAGE_LED_POWER                  HEX: 06
+CONSTANT: HID_USAGE_LED_SHIFT                  HEX: 07
+CONSTANT: HID_USAGE_LED_DO_NOT_DISTURB         HEX: 08
+CONSTANT: HID_USAGE_LED_MUTE                   HEX: 09
+CONSTANT: HID_USAGE_LED_TONE_ENABLE            HEX: 0A
+CONSTANT: HID_USAGE_LED_HIGH_CUT_FILTER        HEX: 0B
+CONSTANT: HID_USAGE_LED_LOW_CUT_FILTER         HEX: 0C
+CONSTANT: HID_USAGE_LED_EQUALIZER_ENABLE       HEX: 0D
+CONSTANT: HID_USAGE_LED_SOUND_FIELD_ON         HEX: 0E
+CONSTANT: HID_USAGE_LED_SURROUND_FIELD_ON      HEX: 0F
+CONSTANT: HID_USAGE_LED_REPEAT                 HEX: 10
+CONSTANT: HID_USAGE_LED_STEREO                 HEX: 11
+CONSTANT: HID_USAGE_LED_SAMPLING_RATE_DETECT   HEX: 12
+CONSTANT: HID_USAGE_LED_SPINNING               HEX: 13
+CONSTANT: HID_USAGE_LED_CAV                    HEX: 14
+CONSTANT: HID_USAGE_LED_CLV                    HEX: 15
+CONSTANT: HID_USAGE_LED_RECORDING_FORMAT_DET   HEX: 16
+CONSTANT: HID_USAGE_LED_OFF_HOOK               HEX: 17
+CONSTANT: HID_USAGE_LED_RING                   HEX: 18
+CONSTANT: HID_USAGE_LED_MESSAGE_WAITING        HEX: 19
+CONSTANT: HID_USAGE_LED_DATA_MODE              HEX: 1A
+CONSTANT: HID_USAGE_LED_BATTERY_OPERATION      HEX: 1B
+CONSTANT: HID_USAGE_LED_BATTERY_OK             HEX: 1C
+CONSTANT: HID_USAGE_LED_BATTERY_LOW            HEX: 1D
+CONSTANT: HID_USAGE_LED_SPEAKER                HEX: 1E
+CONSTANT: HID_USAGE_LED_HEAD_SET               HEX: 1F
+CONSTANT: HID_USAGE_LED_HOLD                   HEX: 20
+CONSTANT: HID_USAGE_LED_MICROPHONE             HEX: 21
+CONSTANT: HID_USAGE_LED_COVERAGE               HEX: 22
+CONSTANT: HID_USAGE_LED_NIGHT_MODE             HEX: 23
+CONSTANT: HID_USAGE_LED_SEND_CALLS             HEX: 24
+CONSTANT: HID_USAGE_LED_CALL_PICKUP            HEX: 25
+CONSTANT: HID_USAGE_LED_CONFERENCE             HEX: 26
+CONSTANT: HID_USAGE_LED_STAND_BY               HEX: 27
+CONSTANT: HID_USAGE_LED_CAMERA_ON              HEX: 28
+CONSTANT: HID_USAGE_LED_CAMERA_OFF             HEX: 29
+CONSTANT: HID_USAGE_LED_ON_LINE                HEX: 2A
+CONSTANT: HID_USAGE_LED_OFF_LINE               HEX: 2B
+CONSTANT: HID_USAGE_LED_BUSY                   HEX: 2C
+CONSTANT: HID_USAGE_LED_READY                  HEX: 2D
+CONSTANT: HID_USAGE_LED_PAPER_OUT              HEX: 2E
+CONSTANT: HID_USAGE_LED_PAPER_JAM              HEX: 2F
+CONSTANT: HID_USAGE_LED_REMOTE                 HEX: 30
+CONSTANT: HID_USAGE_LED_FORWARD                HEX: 31
+CONSTANT: HID_USAGE_LED_REVERSE                HEX: 32
+CONSTANT: HID_USAGE_LED_STOP                   HEX: 33
+CONSTANT: HID_USAGE_LED_REWIND                 HEX: 34
+CONSTANT: HID_USAGE_LED_FAST_FORWARD           HEX: 35
+CONSTANT: HID_USAGE_LED_PLAY                   HEX: 36
+CONSTANT: HID_USAGE_LED_PAUSE                  HEX: 37
+CONSTANT: HID_USAGE_LED_RECORD                 HEX: 38
+CONSTANT: HID_USAGE_LED_ERROR                  HEX: 39
+CONSTANT: HID_USAGE_LED_SELECTED_INDICATOR     HEX: 3A
+CONSTANT: HID_USAGE_LED_IN_USE_INDICATOR       HEX: 3B
+CONSTANT: HID_USAGE_LED_MULTI_MODE_INDICATOR   HEX: 3C
+CONSTANT: HID_USAGE_LED_INDICATOR_ON           HEX: 3D
+CONSTANT: HID_USAGE_LED_INDICATOR_FLASH        HEX: 3E
+CONSTANT: HID_USAGE_LED_INDICATOR_SLOW_BLINK   HEX: 3F
+CONSTANT: HID_USAGE_LED_INDICATOR_FAST_BLINK   HEX: 40
+CONSTANT: HID_USAGE_LED_INDICATOR_OFF          HEX: 41
+CONSTANT: HID_USAGE_LED_FLASH_ON_TIME          HEX: 42
+CONSTANT: HID_USAGE_LED_SLOW_BLINK_ON_TIME     HEX: 43
+CONSTANT: HID_USAGE_LED_SLOW_BLINK_OFF_TIME    HEX: 44
+CONSTANT: HID_USAGE_LED_FAST_BLINK_ON_TIME     HEX: 45
+CONSTANT: HID_USAGE_LED_FAST_BLINK_OFF_TIME    HEX: 46
+CONSTANT: HID_USAGE_LED_INDICATOR_COLOR        HEX: 47
+CONSTANT: HID_USAGE_LED_RED                    HEX: 48
+CONSTANT: HID_USAGE_LED_GREEN                  HEX: 49
+CONSTANT: HID_USAGE_LED_AMBER                  HEX: 4A
+CONSTANT: HID_USAGE_LED_GENERIC_INDICATOR      HEX: 4B
+
+CONSTANT: HID_USAGE_TELEPHONY_PHONE                  HEX: 01
+CONSTANT: HID_USAGE_TELEPHONY_ANSWERING_MACHINE      HEX: 02
+CONSTANT: HID_USAGE_TELEPHONY_MESSAGE_CONTROLS       HEX: 03
+CONSTANT: HID_USAGE_TELEPHONY_HANDSET                HEX: 04
+CONSTANT: HID_USAGE_TELEPHONY_HEADSET                HEX: 05
+CONSTANT: HID_USAGE_TELEPHONY_KEYPAD                 HEX: 06
+CONSTANT: HID_USAGE_TELEPHONY_PROGRAMMABLE_BUTTON    HEX: 07
+CONSTANT: HID_USAGE_TELEPHONY_REDIAL                 HEX: 24
+CONSTANT: HID_USAGE_TELEPHONY_TRANSFER               HEX: 25
+CONSTANT: HID_USAGE_TELEPHONY_DROP                   HEX: 26
+CONSTANT: HID_USAGE_TELEPHONY_LINE                   HEX: 2A
+CONSTANT: HID_USAGE_TELEPHONY_RING_ENABLE            HEX: 2D
+CONSTANT: HID_USAGE_TELEPHONY_SEND                   HEX: 31
+CONSTANT: HID_USAGE_TELEPHONY_KEYPAD_0               HEX: B0
+CONSTANT: HID_USAGE_TELEPHONY_KEYPAD_D               HEX: BF
+CONSTANT: HID_USAGE_TELEPHONY_HOST_AVAILABLE         HEX: F1
+
+CONSTANT: HID_USAGE_MS_BTH_HF_DIALNUMBER             HEX: 21
+CONSTANT: HID_USAGE_MS_BTH_HF_DIALMEMORY             HEX: 22
+
+CONSTANT: HID_USAGE_CONSUMERCTRL          HEX: 01
+CONSTANT: HID_USAGE_DIGITIZER_PEN         HEX: 02
+CONSTANT: HID_USAGE_DIGITIZER_IN_RANGE    HEX: 32
+CONSTANT: HID_USAGE_DIGITIZER_TIP_SWITCH  HEX: 42
+CONSTANT: HID_USAGE_DIGITIZER_BARREL_SWITCH HEX: 44
+
+CONSTANT: HIDP_LINK_COLLECTION_ROOT        -1
+CONSTANT: HIDP_LINK_COLLECTION_UNSPECIFIED 0
+
+C-ENUM:
+    HidP_Input
+    HidP_Output
+    HidP_Feature ;
+TYPEDEF: int HIDP_REPORT_TYPE
+
+STRUCT: USAGE_AND_PAGE
+    { Usage     USAGE }
+    { UsagePage USAGE } ;
+TYPEDEF: USAGE_AND_PAGE* PUSAGE_AND_PAGE
+
+: HidP_IsSameUsageAndPage ( u1 u2 -- ? ) = ; inline
+
+STRUCT: HIDP_BUTTONS_CAPS_range
+    { UsageMin        USAGE  }
+    { UsageMax        USAGE  }
+    { StringMin       USHORT }
+    { StringMax       USHORT }
+    { DesignatorMin   USHORT }
+    { DesignatorMax   USHORT }
+    { DataIndexMin    USHORT }
+    { DataIndexMax    USHORT } ;
+
+STRUCT: HIDP_BUTTONS_CAPS_not_range
+    { Usage           USAGE  }
+    { Reserved1       USAGE  }
+    { StringIndex     USHORT }
+    { Reserved2       USHORT }
+    { DesignatorIndex USHORT }
+    { Reserved3       USHORT }
+    { DataIndex       USHORT }
+    { Reserved4       USHORT } ;
+
+UNION-STRUCT: HIDP_BUTTONS_CAPS_union
+    { Range    HIDP_BUTTONS_CAPS_range     }
+    { NotRange HIDP_BUTTONS_CAPS_not_range } ;
+
+STRUCT: HIDP_BUTTON_CAPS
+    { UsagePage          USAGE                   }
+    { ReportID           UCHAR                   }
+    { IsAlias            BOOLEAN                 }
+    { BitField           USHORT                  }
+    { LinkCollection     USHORT                  }
+    { LinkUsage          USAGE                   }
+    { LinkUsagePage      USAGE                   }
+    { IsRange            BOOLEAN                 }
+    { IsStringRange      BOOLEAN                 }
+    { IsDesignatorRange  BOOLEAN                 }
+    { IsAbsolute         BOOLEAN                 }
+    { Reserved           ULONG[10]               }
+    { Union              HIDP_BUTTONS_CAPS_union } ;
+TYPEDEF: HIDP_BUTTON_CAPS* PHIDP_BUTTON_CAPS
+
+STRUCT: HIDP_VALUE_CAPS_range
+    { UsageMin        USAGE  }
+    { UsageMax        USAGE  }
+    { StringMin       USHORT }
+    { StringMax       USHORT }
+    { DesignatorMin   USHORT }
+    { DesignatorMax   USHORT }
+    { DataIndexMin    USHORT }
+    { DataIndexMax    USHORT } ;
+
+STRUCT: HIDP_VALUE_CAPS_not_range
+    { Usage             USAGE  }
+    { Reserved1         USAGE  }
+    { StringIndex       USHORT }
+    { Reserved2         USHORT }
+    { DesignatorIndex   USHORT }
+    { Reserved3         USHORT }
+    { DataIndex         USHORT }
+    { Reserved4         USHORT } ;
+
+UNION-STRUCT: HIDP_VALUE_CAPS_union
+    { Range    HIDP_VALUE_CAPS_range     }
+    { NotRange HIDP_VALUE_CAPS_not_range } ;
+
+STRUCT: HIDP_VALUE_CAPS
+    { UsagePage          USAGE                  }
+    { ReportID           UCHAR                  }
+    { IsAlias            BOOLEAN                }
+    { BitField           USHORT                 }
+    { LinkCollection     USHORT                 }
+    { LinkUsage          USAGE                  }
+    { LinkUsagePage      USAGE                  }
+    { IsRange            BOOLEAN                }
+    { IsStringRange      BOOLEAN                }
+    { IsDesignatorRange  BOOLEAN                }
+    { IsAbsolute         BOOLEAN                }
+    { HasNull            BOOLEAN                }
+    { Reserved           UCHAR                  }
+    { BitSize            USHORT                 }
+    { ReportCount        USHORT                 }
+    { Reserved2          USHORT[5]              }
+    { UnitsExp           ULONG                  }
+    { Units              ULONG                  }
+    { LogicalMin         LONG                   }
+    { LogicalMax         LONG                   }
+    { PhysicalMin        LONG                   }
+    { PhysicalMax        LONG                   }
+    { Union              HIDP_VALUE_CAPS_union  } ;
+TYPEDEF: HIDP_VALUE_CAPS* PHIDP_VALUE_CAPS
+
+STRUCT: HIDP_LINK_COLLECTION_NODE
+    { LinkUsage                        USAGE  }
+    { LinkUsagePage                    USAGE  }
+    { Parent                           USHORT }
+    { NumberOfChildren                 USHORT }
+    { NextSibling                      USHORT }
+    { FirstChild                       USHORT }
+    { CollectionTypeIsAliasBitfield    ULONG  }
+    { UserContext                      PVOID  } ;
+TYPEDEF: HIDP_LINK_COLLECTION_NODE* PHIDP_LINK_COLLECTION_NODE
+
+TYPEDEF: PUCHAR PHIDP_REPORT_DESCRIPTOR
+C-TYPE: HIDP_PREPARSED_DATA
+TYPEDEF: HIDP_PREPARSED_DATA* PHIDP_PREPARSED_DATA
+
+STRUCT: HIDP_CAPS
+    { Usage                       USAGE      }
+    { UsagePage                   USAGE      }
+    { InputReportByteLength       USHORT     }
+    { OutputReportByteLength      USHORT     }
+    { FeatureReportByteLength     USHORT     }
+    { Reserved                    USHORT[17] }
+    { NumberLinkCollectionNodes   USHORT     }
+    { NumberInputButtonCaps       USHORT     }
+    { NumberInputValueCaps        USHORT     }
+    { NumberInputDataIndices      USHORT     }
+    { NumberOutputButtonCaps      USHORT     }
+    { NumberOutputValueCaps       USHORT     }
+    { NumberOutputDataIndices     USHORT     }
+    { NumberFeatureButtonCaps     USHORT     }
+    { NumberFeatureValueCaps      USHORT     }
+    { NumberFeatureDataIndices    USHORT     } ;
+TYPEDEF: HIDP_CAPS* PHIDP_CAPS
+
+STRUCT: HIDP_DATA
+    { DataIndex  USHORT }
+    { Reserved   USHORT }
+    { RawValue   ULONG  } ;
+TYPEDEF: HIDP_DATA* PHIDP_DATA
+
+STRUCT: HIDP_UNKNOWN_TOKEN
+    { Token     UCHAR    }
+    { Reserved  UCHAR[3] }
+    { BitField  ULONG    } ;
+TYPEDEF: HIDP_UNKNOWN_TOKEN* PHIDP_UNKNOWN_TOKEN
+
+STRUCT: HIDP_EXTENDED_ATTRIBUTES
+    { NumGlobalUnknowns   UCHAR               }
+    { Reserved            UCHAR[3]            }
+    { GlobalUnknowns      PHIDP_UNKNOWN_TOKEN }
+    { Data                ULONG[1]            } ;
+TYPEDEF: HIDP_EXTENDED_ATTRIBUTES* PHIDP_EXTENDED_ATTRIBUTES
+
+FUNCTION: NTSTATUS
+HidP_GetCaps (
+   PHIDP_PREPARSED_DATA      PreparsedData,
+   PHIDP_CAPS                Capabilities
+   ) ;
+
+FUNCTION: NTSTATUS
+HidP_GetLinkCollectionNodes (
+   PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
+   PULONG                     LinkCollectionNodesLength,
+   PHIDP_PREPARSED_DATA       PreparsedData
+   ) ;
+
+FUNCTION: NTSTATUS
+HidP_GetSpecificButtonCaps (
+   HIDP_REPORT_TYPE     ReportType,
+   USAGE                UsagePage,
+   USHORT               LinkCollection,
+   USAGE                Usage,
+   PHIDP_BUTTON_CAPS    ButtonCaps,
+   PUSHORT              ButtonCapsLength,
+   PHIDP_PREPARSED_DATA PreparsedData
+   ) ;
+
+FUNCTION: NTSTATUS
+HidP_GetButtonCaps (
+   HIDP_REPORT_TYPE     ReportType,
+   PHIDP_BUTTON_CAPS    ButtonCaps,
+   PUSHORT              ButtonCapsLength,
+   PHIDP_PREPARSED_DATA PreparsedData
+) ;
+
+FUNCTION: NTSTATUS
+HidP_GetSpecificValueCaps (
+   HIDP_REPORT_TYPE     ReportType,
+   USAGE                UsagePage,
+   USHORT               LinkCollection,
+   USAGE                Usage,
+   PHIDP_VALUE_CAPS     ValueCaps,
+   PUSHORT              ValueCapsLength,
+   PHIDP_PREPARSED_DATA PreparsedData
+   ) ;
+
+FUNCTION: NTSTATUS
+HidP_GetValueCaps (
+   HIDP_REPORT_TYPE     ReportType,
+   PHIDP_VALUE_CAPS     ValueCaps,
+   PUSHORT              ValueCapsLength,
+   PHIDP_PREPARSED_DATA PreparsedData
+) ;
+
+FUNCTION: NTSTATUS
+HidP_GetExtendedAttributes (
+    HIDP_REPORT_TYPE            ReportType,
+    USHORT                      DataIndex,
+    PHIDP_PREPARSED_DATA        PreparsedData,
+    PHIDP_EXTENDED_ATTRIBUTES   Attributes,
+    PULONG                      LengthAttributes
+    ) ;
+
+FUNCTION: NTSTATUS
+HidP_InitializeReportForID (
+   HIDP_REPORT_TYPE     ReportType,
+   UCHAR                ReportID,
+   PHIDP_PREPARSED_DATA PreparsedData,
+   PCHAR                Report,
+   ULONG                ReportLength
+   ) ;
+
+FUNCTION: NTSTATUS
+HidP_SetData (
+    HIDP_REPORT_TYPE     ReportType,
+    PHIDP_DATA           DataList,
+    PULONG               DataLength,
+    PHIDP_PREPARSED_DATA PreparsedData,
+    PCHAR                Report,
+    ULONG                ReportLength
+    ) ;
+
+FUNCTION: NTSTATUS
+HidP_GetData (
+    HIDP_REPORT_TYPE     ReportType,
+    PHIDP_DATA           DataList,
+    PULONG               DataLength,
+    PHIDP_PREPARSED_DATA PreparsedData,
+    PCHAR                Report,
+    ULONG                ReportLength
+    ) ;
+
+FUNCTION: ULONG
+HidP_MaxDataListLength (
+   HIDP_REPORT_TYPE      ReportType,
+   PHIDP_PREPARSED_DATA  PreparsedData
+   ) ;
+
+FUNCTION: NTSTATUS
+HidP_SetUsages (
+   HIDP_REPORT_TYPE     ReportType,
+   USAGE                UsagePage,
+   USHORT               LinkCollection,
+   PUSAGE               UsageList,
+   PULONG               UsageLength,
+   PHIDP_PREPARSED_DATA PreparsedData,
+   PCHAR                Report,
+   ULONG                ReportLength
+   ) ;
+ALIAS: HidP_SetButtons HidP_SetUsages
+
+FUNCTION: NTSTATUS
+HidP_UnsetUsages (
+   HIDP_REPORT_TYPE     ReportType,
+   USAGE                UsagePage,
+   USHORT               LinkCollection,
+   PUSAGE               UsageList,
+   PULONG               UsageLength,
+   PHIDP_PREPARSED_DATA PreparsedData,
+   PCHAR                Report,
+   ULONG                ReportLength
+   ) ;
+ALIAS: HidP_UnsetButtons HidP_UnsetUsages
+
+FUNCTION: NTSTATUS
+HidP_GetUsages (
+   HIDP_REPORT_TYPE     ReportType,
+   USAGE                UsagePage,
+   USHORT               LinkCollection,
+   PUSAGE               UsageList,
+   PULONG               UsageLength,
+   PHIDP_PREPARSED_DATA PreparsedData,
+   PCHAR                Report,
+   ULONG                ReportLength
+   ) ;
+ALIAS: HidP_GetButtons HidP_GetUsages
+
+FUNCTION: NTSTATUS
+HidP_GetUsagesEx (
+    HIDP_REPORT_TYPE     ReportType,
+    USHORT               LinkCollection,
+    PUSAGE_AND_PAGE      ButtonList,
+    ULONG*               UsageLength,
+    PHIDP_PREPARSED_DATA PreparsedData,
+    PCHAR                Report,
+    ULONG                ReportLength
+   ) ;
+ALIAS: HidP_GetButtonsEx HidP_GetUsagesEx
+
+FUNCTION: ULONG
+HidP_MaxUsageListLength (
+   HIDP_REPORT_TYPE      ReportType,
+   USAGE                 UsagePage,
+   PHIDP_PREPARSED_DATA  PreparsedData
+   ) ;
+
+FUNCTION: NTSTATUS
+HidP_SetUsageValue (
+    HIDP_REPORT_TYPE     ReportType,
+    USAGE                UsagePage,
+    USHORT               LinkCollection,
+    USAGE                Usage,
+    ULONG                UsageValue,
+    PHIDP_PREPARSED_DATA PreparsedData,
+    PCHAR                Report,
+    ULONG                ReportLength
+    ) ;
+
+FUNCTION: NTSTATUS
+HidP_SetScaledUsageValue (
+    HIDP_REPORT_TYPE     ReportType,
+    USAGE                UsagePage,
+    USHORT               LinkCollection,
+    USAGE                Usage,
+    LONG                 UsageValue,
+    PHIDP_PREPARSED_DATA PreparsedData,
+    PCHAR                Report,
+    ULONG                ReportLength
+    ) ;
+
+FUNCTION: NTSTATUS
+HidP_SetUsageValueArray (
+    HIDP_REPORT_TYPE     ReportType,
+    USAGE                UsagePage,
+    USHORT               LinkCollection,
+    USAGE                Usage,
+    PCHAR                UsageValue,
+    USHORT               UsageValueByteLength,
+    PHIDP_PREPARSED_DATA PreparsedData,
+    PCHAR                Report,
+    ULONG                ReportLength
+    ) ;
+
+
+FUNCTION: NTSTATUS
+HidP_GetUsageValue (
+    HIDP_REPORT_TYPE     ReportType,
+    USAGE                UsagePage,
+    USHORT               LinkCollection,
+    USAGE                Usage,
+    PULONG               UsageValue,
+    PHIDP_PREPARSED_DATA PreparsedData,
+    PCHAR                Report,
+    ULONG                ReportLength
+    ) ;
+
+FUNCTION: NTSTATUS
+HidP_GetScaledUsageValue (
+    HIDP_REPORT_TYPE     ReportType,
+    USAGE                UsagePage,
+    USHORT               LinkCollection,
+    USAGE                Usage,
+    PLONG                UsageValue,
+    PHIDP_PREPARSED_DATA PreparsedData,
+    PCHAR                Report,
+    ULONG                ReportLength
+    ) ;
+
+FUNCTION: NTSTATUS
+HidP_GetUsageValueArray (
+    HIDP_REPORT_TYPE     ReportType,
+    USAGE                UsagePage,
+    USHORT               LinkCollection,
+    USAGE                Usage,
+    PCHAR                UsageValue,
+    USHORT               UsageValueByteLength,
+    PHIDP_PREPARSED_DATA PreparsedData,
+    PCHAR                Report,
+    ULONG                ReportLength
+    ) ;
+
+FUNCTION: NTSTATUS
+HidP_UsageListDifference (
+   PUSAGE   PreviousUsageList,
+   PUSAGE   CurrentUsageList,
+   PUSAGE   BreakUsageList,
+   PUSAGE   MakeUsageList,
+   ULONG    UsageListLength
+    ) ;
+
+FUNCTION: NTSTATUS
+HidP_UsageAndPageListDifference (
+   PUSAGE_AND_PAGE PreviousUsageList,
+   PUSAGE_AND_PAGE CurrentUsageList,
+   PUSAGE_AND_PAGE BreakUsageList,
+   PUSAGE_AND_PAGE MakeUsageList,
+   ULONG           UsageListLength
+   ) ;
+
+C-ENUM:
+    HidP_Keyboard_Break
+    HidP_Keyboard_Make ;
+TYPEDEF: int HIDP_KEYBOARD_DIRECTION
+
+STRUCT: HIDP_KEYBOARD_MODIFIER_STATE
+    { ul ULONG } ;
+TYPEDEF: HIDP_KEYBOARD_MODIFIER_STATE* PHIDP_KEYBOARD_MODIFIER_STATE
+
+CALLBACK: BOOLEAN PHIDP_INSERT_SCANCODES (
+    PVOID Context,
+    PCHAR NewScanCodes,
+    ULONG Length ) ;
+
+FUNCTION: NTSTATUS
+HidP_TranslateUsageAndPagesToI8042ScanCodes (
+    PUSAGE_AND_PAGE               ChangedUsageList,
+    ULONG                         UsageListLength,
+    HIDP_KEYBOARD_DIRECTION       KeyAction,
+    PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
+    PHIDP_INSERT_SCANCODES        InsertCodesProcedure,
+    PVOID                         InsertCodesContext
+    ) ;
+
+
+FUNCTION: NTSTATUS
+HidP_TranslateUsagesToI8042ScanCodes (
+    PUSAGE                        ChangedUsageList,
+    ULONG                         UsageListLength,
+    HIDP_KEYBOARD_DIRECTION       KeyAction,
+    PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
+    PHIDP_INSERT_SCANCODES        InsertCodesProcedure,
+    PVOID                         InsertCodesContext
+    ) ;
+
+CONSTANT: FACILITY_HID_ERROR_CODE HEX: 11
+: HIDP_ERROR_CODES ( SEV CODE -- HRESULT )
+    [ 28 shift ] dip bitor FACILITY_HID_ERROR_CODE 16 shift bitor ; inline
+: HIDP_STATUS_SUCCESS                  ( -- HRESULT ) HEX: 0 HEX: 0 HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_NULL                     ( -- HRESULT ) HEX: 8 HEX: 1 HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_INVALID_PREPARSED_DATA   ( -- HRESULT ) HEX: C HEX: 1 HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_INVALID_REPORT_TYPE      ( -- HRESULT ) HEX: C HEX: 2 HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_INVALID_REPORT_LENGTH    ( -- HRESULT ) HEX: C HEX: 3 HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_USAGE_NOT_FOUND          ( -- HRESULT ) HEX: C HEX: 4 HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_VALUE_OUT_OF_RANGE       ( -- HRESULT ) HEX: C HEX: 5 HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_BAD_LOG_PHY_VALUES       ( -- HRESULT ) HEX: C HEX: 6 HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_BUFFER_TOO_SMALL         ( -- HRESULT ) HEX: C HEX: 7 HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_INTERNAL_ERROR           ( -- HRESULT ) HEX: C HEX: 8 HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_I8042_TRANS_UNKNOWN      ( -- HRESULT ) HEX: C HEX: 9 HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_INCOMPATIBLE_REPORT_ID   ( -- HRESULT ) HEX: C HEX: A HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_NOT_VALUE_ARRAY          ( -- HRESULT ) HEX: C HEX: B HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_IS_VALUE_ARRAY           ( -- HRESULT ) HEX: C HEX: C HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_DATA_INDEX_NOT_FOUND     ( -- HRESULT ) HEX: C HEX: D HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_DATA_INDEX_OUT_OF_RANGE  ( -- HRESULT ) HEX: C HEX: E HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_BUTTON_NOT_PRESSED       ( -- HRESULT ) HEX: C HEX: F HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_REPORT_DOES_NOT_EXIST    ( -- HRESULT ) HEX: C HEX: 10 HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_NOT_IMPLEMENTED          ( -- HRESULT ) HEX: C HEX: 20 HIDP_ERROR_CODES ; inline
+: HIDP_STATUS_I8242_TRANS_UNKNOWN      ( -- HRESULT ) HIDP_STATUS_I8042_TRANS_UNKNOWN ; inline
+
+STRUCT: HIDD_CONFIGURATION
+    { cookie            PVOID }
+    { size              ULONG }
+    { RingBufferSize    ULONG } ;
+TYPEDEF: HIDD_CONFIGURATION* PHIDD_CONFIGURATION
+
+STRUCT: HIDD_ATTRIBUTES
+    { Size           ULONG  }
+    { VendorID       USHORT }
+    { ProductID      USHORT }
+    { VersionNumber  USHORT } ;
+TYPEDEF: HIDD_ATTRIBUTES* PHIDD_ATTRIBUTES
+
+FUNCTION: BOOLEAN
+HidD_GetAttributes (
+    HANDLE              HidDeviceObject,
+    PHIDD_ATTRIBUTES    Attributes
+    ) ;
+
+FUNCTION: void
+HidD_GetHidGuid (
+   LPGUID   HidGuid
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_GetPreparsedData (
+   HANDLE                HidDeviceObject,
+   PHIDP_PREPARSED_DATA* PreparsedData
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_FreePreparsedData (
+   PHIDP_PREPARSED_DATA PreparsedData
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_FlushQueue (
+   HANDLE                HidDeviceObject
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_GetConfiguration (
+   HANDLE               HidDeviceObject,
+   PHIDD_CONFIGURATION  Configuration,
+   ULONG                ConfigurationLength
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_SetConfiguration (
+   HANDLE               HidDeviceObject,
+   PHIDD_CONFIGURATION  Configuration,
+   ULONG                ConfigurationLength
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_GetFeature (
+   HANDLE   HidDeviceObject,
+   PVOID    ReportBuffer,
+   ULONG    ReportBufferLength
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_SetFeature (
+   HANDLE   HidDeviceObject,
+   PVOID    ReportBuffer,
+   ULONG    ReportBufferLength
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_GetInputReport (
+   HANDLE   HidDeviceObject,
+   PVOID    ReportBuffer,
+   ULONG    ReportBufferLength
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_SetOutputReport (
+   HANDLE   HidDeviceObject,
+   PVOID    ReportBuffer,
+   ULONG    ReportBufferLength
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_GetNumInputBuffers (
+    HANDLE  HidDeviceObject,
+    PULONG  NumberBuffers
+    ) ;
+
+FUNCTION: BOOLEAN
+HidD_SetNumInputBuffers (
+    HANDLE HidDeviceObject,
+    ULONG  NumberBuffers
+    ) ;
+
+FUNCTION: BOOLEAN
+HidD_GetPhysicalDescriptor (
+   HANDLE   HidDeviceObject,
+   PVOID    Buffer,
+   ULONG    BufferLength
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_GetManufacturerString (
+   HANDLE   HidDeviceObject,
+   PVOID    Buffer,
+   ULONG    BufferLength
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_GetProductString (
+   HANDLE   HidDeviceObject,
+   PVOID    Buffer,
+   ULONG    BufferLength
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_GetIndexedString (
+   HANDLE   HidDeviceObject,
+   ULONG    StringIndex,
+   PVOID    Buffer,
+   ULONG    BufferLength
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_GetSerialNumberString (
+   HANDLE   HidDeviceObject,
+   PVOID    Buffer,
+   ULONG    BufferLength
+   ) ;
+
+FUNCTION: BOOLEAN
+HidD_GetMsGenreDescriptor (
+   HANDLE   HidDeviceObject,
+   PVOID    Buffer,
+   ULONG    BufferLength
+   ) ;

From ed18b911c83e6b3f697731affb0744b2a56182a1 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 16:49:44 -0800
Subject: [PATCH 150/250] io.sockets.windows.nt: update string c-types in
 alien-indirect

---
 basis/io/sockets/windows/nt/nt.factor | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/basis/io/sockets/windows/nt/nt.factor b/basis/io/sockets/windows/nt/nt.factor
index 0dd85954ac..8eb2df5b46 100644
--- a/basis/io/sockets/windows/nt/nt.factor
+++ b/basis/io/sockets/windows/nt/nt.factor
@@ -55,8 +55,8 @@ TUPLE: ConnectEx-args port
         [ lpOverlapped>> ]
         [ ptr>> ]
     } cleave
-    "int"
-    { "SOCKET" "sockaddr_in*" "int" "PVOID" "DWORD" "LPDWORD" "void*" }
+    int
+    { SOCKET void* int PVOID DWORD LPDWORD void* }
     "stdcall" alien-indirect drop
     winsock-error-string [ throw ] when* ; inline
 

From 92e1ca8b612977f8090a1e8ac7fdb1f95a2b467c Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 16:49:58 -0800
Subject: [PATCH 151/250] math.blas: update string c-types

---
 basis/math/blas/matrices/matrices.factor | 8 ++++----
 basis/math/blas/vectors/vectors.factor   | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/basis/math/blas/matrices/matrices.factor b/basis/math/blas/matrices/matrices.factor
index 0a6fc147ad..22c649c544 100644
--- a/basis/math/blas/matrices/matrices.factor
+++ b/basis/math/blas/matrices/matrices.factor
@@ -305,10 +305,10 @@ M: MATRIX pprint-delims
 : define-complex-blas-matrix ( TYPE T -- )
     "U" "C" (define-blas-matrix) ;
 
-"float"          "S" define-real-blas-matrix
-"double"         "D" define-real-blas-matrix
-"complex-float"  "C" define-complex-blas-matrix
-"complex-double" "Z" define-complex-blas-matrix
+float          "S" define-real-blas-matrix
+double         "D" define-real-blas-matrix
+complex-float  "C" define-complex-blas-matrix
+complex-double "Z" define-complex-blas-matrix
 
 >>
 
diff --git a/basis/math/blas/vectors/vectors.factor b/basis/math/blas/vectors/vectors.factor
index 083400224e..caf0984aa4 100644
--- a/basis/math/blas/vectors/vectors.factor
+++ b/basis/math/blas/vectors/vectors.factor
@@ -238,10 +238,10 @@ M: VECTOR Vasum
     [ drop (define-blas-vector) ]
     [ (define-complex-blas-vector) ] 3bi ;
 
-"float"  "S" define-real-blas-vector
-"double" "D" define-real-blas-vector
-"complex-float"  "C" "S" define-complex-blas-vector
-"complex-double" "Z" "D" define-complex-blas-vector
+float  "S" define-real-blas-vector
+double "D" define-real-blas-vector
+complex-float  "C" "S" define-complex-blas-vector
+complex-double "Z" "D" define-complex-blas-vector
 
 >>
 

From d5bf6e55cd5ab4a0d544bd541bd7c1229592337f Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 19:23:47 -0800
Subject: [PATCH 152/250] more implementation of pointer c-types. make it so
 that { char* binary } acts like a real pointer to char instead of
 stringifying, and add byte* typedef for { char* binary }

---
 basis/alien/arrays/arrays.factor              | 15 ++-
 basis/alien/c-types/c-types-tests.factor      | 45 +++++----
 basis/alien/c-types/c-types.factor            | 96 +++++++++++--------
 basis/alien/parser/parser.factor              |  8 +-
 basis/alien/prettyprint/prettyprint.factor    |  2 +-
 basis/compiler/codegen/codegen.factor         |  2 +-
 .../specialized-arrays.factor                 |  5 +
 extra/alien/data/map/map.factor               |  4 +-
 8 files changed, 105 insertions(+), 72 deletions(-)

diff --git a/basis/alien/arrays/arrays.factor b/basis/alien/arrays/arrays.factor
index cf6e8640f0..c62800df36 100644
--- a/basis/alien/arrays/arrays.factor
+++ b/basis/alien/arrays/arrays.factor
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.strings alien.c-types alien.data alien.accessors
 arrays words sequences math kernel namespaces fry cpu.architecture
-io.encodings.utf8 accessors ;
+io.encodings.binary io.encodings.utf8 accessors ;
 IN: alien.arrays
 
 INSTANCE: array value-type
@@ -88,10 +88,14 @@ M: string-type c-type-unboxer
     drop void* c-type-unboxer ;
 
 M: string-type c-type-boxer-quot
-    second '[ _ alien>string ] ;
+    second dup binary =
+    [ drop void* c-type-boxer-quot ]
+    [ '[ _ alien>string ] ] if ;
 
 M: string-type c-type-unboxer-quot
-    second '[ _ string>alien ] ;
+    second dup binary =
+    [ drop void* c-type-unboxer-quot ]
+    [ '[ _ string>alien ] ] if ;
 
 M: string-type c-type-getter
     drop [ alien-cell ] ;
@@ -99,5 +103,8 @@ M: string-type c-type-getter
 M: string-type c-type-setter
     drop [ set-alien-cell ] ;
 
-TYPEDEF: { char* utf8 } char*
+{ char* utf8 } char <pointer> typedef
+{ char* utf8 } uchar <pointer> typedef
+{ char* binary } byte <pointer> typedef
+{ char* binary } ubyte <pointer> typedef
 
diff --git a/basis/alien/c-types/c-types-tests.factor b/basis/alien/c-types/c-types-tests.factor
index 5f903c9a34..13bdfa742a 100644
--- a/basis/alien/c-types/c-types-tests.factor
+++ b/basis/alien/c-types/c-types-tests.factor
@@ -1,6 +1,6 @@
 USING: alien alien.syntax alien.c-types alien.parser
 eval kernel tools.test sequences system libc alien.strings
-io.encodings.utf8 math.constants classes.struct classes
+io.encodings.ascii io.encodings.utf8 math.constants classes.struct classes
 accessors compiler.units ;
 IN: alien.c-types.tests
 
@@ -16,13 +16,13 @@ UNION-STRUCT: foo
     { a int }
     { b int } ;
 
-[ t ] [ pointer: void c-type void* c-type eq? ] unit-test
-[ t ] [ pointer: int  c-type void* c-type eq? ] unit-test
-[ t ] [ pointer: int* c-type void* c-type eq? ] unit-test
-[ f ] [ pointer: foo  c-type void* c-type eq? ] unit-test
-[ t ] [ pointer: foo* c-type void* c-type eq? ] unit-test
+[ t ] [ pointer: void c-type void* c-type = ] unit-test
+[ t ] [ pointer: int  c-type void* c-type = ] unit-test
+[ t ] [ pointer: int* c-type void* c-type = ] unit-test
+[ f ] [ pointer: foo  c-type void* c-type = ] unit-test
+[ t ] [ pointer: foo* c-type void* c-type = ] unit-test
 
-[ t ] [ pointer: char c-type c-string c-type eq? ] unit-test
+[ t ] [ pointer: char c-type char* c-type = ] unit-test
 
 [ t ] [ pointer: foo c-type-boxer-quot foo c-type-boxer-quot = ] unit-test
 
@@ -30,32 +30,39 @@ UNION-STRUCT: foo
 
 TYPEDEF: int MyInt
 
-[ t ] [ int   c-type          MyInt c-type eq? ] unit-test
-[ t ] [ void* c-type pointer: MyInt c-type eq? ] unit-test
+[ t ] [ int   c-type          MyInt c-type = ] unit-test
+[ t ] [ void* c-type pointer: MyInt c-type = ] unit-test
 
 [ 32 ] [ { int 8 } heap-size ] unit-test
 
+TYPEDEF: char MyChar
+
+[ t ] [ pointer: char c-type pointer: MyChar c-type = ] unit-test
+[ t ] [ char*         c-type pointer: MyChar c-type = ] unit-test
+
+TYPEDEF: char MyFunkyChar
+{ char* ascii } pointer: MyFunkyChar typedef
+
+[ f ] [ pointer: char c-type pointer: MyFunkyChar c-type = ] unit-test
+[ { char* ascii } ] [ pointer: MyFunkyChar c-type ] unit-test
+
 TYPEDEF: char* MyString
 
-[ t ] [ c-string c-type MyString          c-type eq? ] unit-test
-[ t ] [ void*    c-type pointer: MyString c-type eq? ] unit-test
+[ t ] [ char* c-type MyString          c-type = ] unit-test
+[ t ] [ void* c-type pointer: MyString c-type = ] unit-test
 
 TYPEDEF: int* MyIntArray
 
-[ t ] [ void* c-type MyIntArray c-type eq? ] unit-test
+[ t ] [ void* c-type MyIntArray c-type = ] unit-test
 
-TYPEDEF: c-string MyLPBYTE
+TYPEDEF: char* MyLPBYTE
 
-[ t ] [ { c-string utf8 } c-type MyLPBYTE c-type = ] unit-test
+[ t ] [ { char* utf8 } c-type MyLPBYTE c-type = ] unit-test
 
 [
     0 B{ 1 2 3 4 } <displaced-alien> <void*>
 ] must-fail
 
-C-TYPE: MyOpaqueType
-
-[ f ] [ pointer: MyOpaqueType c-type void* c-type eq? ] unit-test
-
 os windows? cpu x86.64? and [
     [ -2147467259 ] [ 2147500037 <long> *long ] unit-test
 ] when
@@ -68,7 +75,7 @@ os windows? cpu x86.64? and [
 
 C-TYPE: opaque
 
-[ t ] [ void* c-type opaque resolve-pointer-type c-type eq? ] unit-test
+[ t ] [ void* c-type pointer: opaque c-type = ] unit-test
 [ opaque c-type ] [ no-c-type? ] must-fail-with
 
 [ """
diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor
index 4a7fd840ef..b038244cdd 100644
--- a/basis/alien/c-types/c-types.factor
+++ b/basis/alien/c-types/c-types.factor
@@ -45,21 +45,24 @@ stack-align? ;
 
 ERROR: no-c-type name ;
 
-PREDICATE: c-type-word < word
-    "c-type" word-prop ;
-
 ! C type protocol
 GENERIC: c-type ( name -- c-type ) foldable
 
 : void? ( c-type -- ? )
     void = ; inline
 
+PREDICATE: c-type-word < word
+    "c-type" word-prop ;
+
 TUPLE: pointer { to initial: void read-only } ;
 C: <pointer> pointer
 
+UNION: c-type-name
+    c-type-word pointer ;
+
 : resolve-typedef ( name -- c-type )
     dup void? [ no-c-type ] when
-    dup c-type-word? [ c-type ] when ;
+    dup c-type-name? [ c-type ] when ;
 
 <PRIVATE
 
@@ -77,7 +80,7 @@ GENERIC: c-struct? ( c-type -- ? )
 
 M: object c-struct? drop f ;
 
-M: c-type-word c-struct? dup void? [ drop f ] [ c-type c-struct? ] if ;
+M: c-type-name c-struct? dup void? [ drop f ] [ c-type c-struct? ] if ;
 
 ! These words being foldable means that words need to be
 ! recompiled if a C type is redefined. Even so, folding the
@@ -86,65 +89,65 @@ GENERIC: c-type-class ( name -- class )
 
 M: abstract-c-type c-type-class class>> ;
 
-M: c-type-word c-type-class c-type c-type-class ;
+M: c-type-name c-type-class c-type c-type-class ;
 
 GENERIC: c-type-boxed-class ( name -- class )
 
 M: abstract-c-type c-type-boxed-class boxed-class>> ;
 
-M: c-type-word c-type-boxed-class c-type c-type-boxed-class ;
+M: c-type-name c-type-boxed-class c-type c-type-boxed-class ;
 
 GENERIC: c-type-boxer ( name -- boxer )
 
 M: c-type c-type-boxer boxer>> ;
 
-M: c-type-word c-type-boxer c-type c-type-boxer ;
+M: c-type-name c-type-boxer c-type c-type-boxer ;
 
 GENERIC: c-type-boxer-quot ( name -- quot )
 
 M: abstract-c-type c-type-boxer-quot boxer-quot>> ;
 
-M: c-type-word c-type-boxer-quot c-type c-type-boxer-quot ;
+M: c-type-name c-type-boxer-quot c-type c-type-boxer-quot ;
 
 GENERIC: c-type-unboxer ( name -- boxer )
 
 M: c-type c-type-unboxer unboxer>> ;
 
-M: c-type-word c-type-unboxer c-type c-type-unboxer ;
+M: c-type-name c-type-unboxer c-type c-type-unboxer ;
 
 GENERIC: c-type-unboxer-quot ( name -- quot )
 
 M: abstract-c-type c-type-unboxer-quot unboxer-quot>> ;
 
-M: c-type-word c-type-unboxer-quot c-type c-type-unboxer-quot ;
+M: c-type-name c-type-unboxer-quot c-type c-type-unboxer-quot ;
 
 GENERIC: c-type-rep ( name -- rep )
 
 M: c-type c-type-rep rep>> ;
 
-M: c-type-word c-type-rep c-type c-type-rep ;
+M: c-type-name c-type-rep c-type c-type-rep ;
 
 GENERIC: c-type-getter ( name -- quot )
 
 M: c-type c-type-getter getter>> ;
 
-M: c-type-word c-type-getter c-type c-type-getter ;
+M: c-type-name c-type-getter c-type c-type-getter ;
 
 GENERIC: c-type-setter ( name -- quot )
 
 M: c-type c-type-setter setter>> ;
 
-M: c-type-word c-type-setter c-type c-type-setter ;
+M: c-type-name c-type-setter c-type c-type-setter ;
 
 GENERIC: c-type-align ( name -- n )
 
 M: abstract-c-type c-type-align align>> ;
 
-M: c-type-word c-type-align c-type c-type-align ;
+M: c-type-name c-type-align c-type c-type-align ;
 
 GENERIC: c-type-align-first ( name -- n )
 
-M: c-type-word c-type-align-first c-type c-type-align-first ;
+M: c-type-name c-type-align-first c-type c-type-align-first ;
 
 M: abstract-c-type c-type-align-first align-first>> ;
 
@@ -152,7 +155,7 @@ GENERIC: c-type-stack-align? ( name -- ? )
 
 M: c-type c-type-stack-align? stack-align?>> ;
 
-M: c-type-word c-type-stack-align? c-type c-type-stack-align? ;
+M: c-type-name c-type-stack-align? c-type c-type-stack-align? ;
 
 : c-type-box ( n c-type -- )
     [ c-type-rep ] [ c-type-boxer [ "No boxer" throw ] unless* ] bi
@@ -166,37 +169,37 @@ GENERIC: box-parameter ( n c-type -- )
 
 M: c-type box-parameter c-type-box ;
 
-M: c-type-word box-parameter c-type box-parameter ;
+M: c-type-name box-parameter c-type box-parameter ;
 
 GENERIC: box-return ( c-type -- )
 
 M: c-type box-return f swap c-type-box ;
 
-M: c-type-word box-return c-type box-return ;
+M: c-type-name box-return c-type box-return ;
 
 GENERIC: unbox-parameter ( n c-type -- )
 
 M: c-type unbox-parameter c-type-unbox ;
 
-M: c-type-word unbox-parameter c-type unbox-parameter ;
+M: c-type-name unbox-parameter c-type unbox-parameter ;
 
 GENERIC: unbox-return ( c-type -- )
 
 M: c-type unbox-return f swap c-type-unbox ;
 
-M: c-type-word unbox-return c-type unbox-return ;
+M: c-type-name unbox-return c-type unbox-return ;
 
 : little-endian? ( -- ? ) 1 <int> *char 1 = ; foldable
 
 GENERIC: heap-size ( name -- size )
 
-M: c-type-word heap-size c-type heap-size ;
+M: c-type-name heap-size c-type heap-size ;
 
 M: abstract-c-type heap-size size>> ;
 
 GENERIC: stack-size ( name -- size )
 
-M: c-type-word stack-size c-type stack-size ;
+M: c-type-name stack-size c-type stack-size ;
 
 M: c-type stack-size size>> cell align ;
 
@@ -233,7 +236,7 @@ MIXIN: value-type
 GENERIC: typedef ( old new -- )
 
 PREDICATE: typedef-word < c-type-word
-    "c-type" word-prop c-type-word? ;
+    "c-type" word-prop c-type-name? ;
 
 M: word typedef ( old new -- )
     {
@@ -243,7 +246,7 @@ M: word typedef ( old new -- )
 
 M: pointer typedef ( old new -- )
     to>> dup c-type-word?
-    [ ]
+    [ swap "pointer-c-type" set-word-prop ]
     [ 2drop ] if ;
 
 TUPLE: long-long-type < c-type ;
@@ -278,6 +281,10 @@ M: long-long-type box-return ( c-type -- )
 : if-void ( c-type true false -- )
     pick void? [ drop nip call ] [ nip call ] if ; inline
 
+SYMBOLS:
+    ptrdiff_t intptr_t uintptr_t size_t
+    byte ubyte char* ;
+
 CONSTANT: primitive-types
     {
         char uchar
@@ -287,35 +294,37 @@ CONSTANT: primitive-types
         longlong ulonglong
         float double
         void* bool
+        char*
     }
 
-SYMBOLS:
-    ptrdiff_t intptr_t uintptr_t size_t
-    char* ;
-
-<PRIVATE
-
 : (pointer-c-type) ( void* type -- void*' )
     [ clone ] dip c-type-boxer-quot >>boxer-quot ;
 
-: string-pointer-type? ( type -- ? )
-    dup pointer? [ drop f ]
-    [ resolve-typedef { char uchar } member? ] if ;
+<PRIVATE
+
+: resolve-pointer-typedef ( type -- base-type )
+    dup "c-type" word-prop dup word?
+    [ nip resolve-pointer-typedef ] [ drop ] if ;
+
+: special-pointer-type ( type -- special-type )
+    dup c-type-word? [
+        dup "pointer-c-type" word-prop
+        [ ] [ resolve-pointer-typedef "pointer-c-type" word-prop ] ?if
+    ] [ drop f ] if ;
 
 : primitive-pointer-type? ( type -- ? )
-    dup pointer? [ drop t ] [
-        resolve-typedef [ void? ] [ primitive-types member? ] bi or
-    ] if ;
+    dup c-type-word? [
+        resolve-pointer-typedef [ void? ] [ primitive-types member? ] bi or
+    ] [ drop t ] if ;
 
 PRIVATE>
 
 M: pointer c-type
     [ \ void* c-type ] dip
-    to>> {
-        { [ dup string-pointer-type? ] [ drop \ char* c-type ] }
-        { [ dup primitive-pointer-type? ] [ drop ] }
-        [ (pointer-c-type) ]
-    } cond ;
+    to>> dup special-pointer-type
+    [ nip ] [
+        dup primitive-pointer-type? [ drop ] [ (pointer-c-type) ] if
+    ] ?if ;
 
 : 8-byte-alignment ( c-type -- c-type )
     {
@@ -528,6 +537,9 @@ M: pointer c-type
         \ uint c-type \ uintptr_t typedef
         \ uint c-type \ size_t typedef
     ] if
+
+    \ char \ byte typedef
+    \ uchar \ ubyte typedef
 ] with-compilation-unit
 
 M: char-16-rep rep-component-type drop char ;
diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor
index 09ee88c173..50d1bfd320 100644
--- a/basis/alien/parser/parser.factor
+++ b/basis/alien/parser/parser.factor
@@ -30,9 +30,11 @@ IN: alien.parser
     (parse-c-type) dup valid-c-type? [ no-c-type ] unless ;
 
 : scan-c-type ( -- c-type )
-    scan dup "{" =
-    [ drop \ } parse-until >array ]
-    [ parse-c-type ] if ; 
+    scan {
+        { [ dup "{" = ] [ drop \ } parse-until >array ] }
+        { [ dup "pointer:" = ] [ drop scan-c-type <pointer> ] }
+        [ parse-c-type ]
+    } cond ; 
 
 : reset-c-type ( word -- )
     dup "struct-size" word-prop
diff --git a/basis/alien/prettyprint/prettyprint.factor b/basis/alien/prettyprint/prettyprint.factor
index 6bfbf313a1..489ea0b10a 100644
--- a/basis/alien/prettyprint/prettyprint.factor
+++ b/basis/alien/prettyprint/prettyprint.factor
@@ -21,7 +21,7 @@ M: c-type-word declarations. drop ;
 
 GENERIC: pprint-c-type ( c-type -- )
 M: word pprint-c-type pprint-word ;
-M: pointer pprint-c-type to>> pprint-c-type "*" text ;
+M: pointer pprint-c-type pprint* ;
 M: wrapper pprint-c-type wrapped>> pprint-word ;
 M: string pprint-c-type text ;
 M: array pprint-c-type pprint* ;
diff --git a/basis/compiler/codegen/codegen.factor b/basis/compiler/codegen/codegen.factor
index d6e58f7ac1..963ed0ab28 100755
--- a/basis/compiler/codegen/codegen.factor
+++ b/basis/compiler/codegen/codegen.factor
@@ -325,7 +325,7 @@ GENERIC: flatten-value-type ( type -- types )
 M: object flatten-value-type 1array ;
 M: struct-c-type flatten-value-type (flatten-int-type) ;
 M: long-long-type flatten-value-type (flatten-int-type) ;
-M: c-type-word flatten-value-type c-type flatten-value-type ;
+M: c-type-name flatten-value-type c-type flatten-value-type ;
 
 : flatten-value-types ( params -- params )
     #! Convert value type structs to consecutive void*s.
diff --git a/basis/specialized-arrays/specialized-arrays.factor b/basis/specialized-arrays/specialized-arrays.factor
index 67689998ab..992dbac6d6 100644
--- a/basis/specialized-arrays/specialized-arrays.factor
+++ b/basis/specialized-arrays/specialized-arrays.factor
@@ -119,6 +119,7 @@ M: A v*high [ * \ T heap-size neg shift ] 2map ; inline
 : underlying-type ( c-type -- c-type' )
     dup "c-type" word-prop {
         { [ dup not ] [ drop no-c-type ] }
+        { [ dup pointer? ] [ 2drop void* ] }
         { [ dup c-type-word? ] [ nip underlying-type ] }
         [ drop ]
     } cond ;
@@ -139,6 +140,7 @@ PRIVATE>
     generate-vocab ;
 
 M: c-type-word require-c-array define-array-vocab drop ;
+M: pointer require-c-array drop void* require-c-array ;
 
 ERROR: specialized-array-vocab-not-loaded c-type ;
 
@@ -146,16 +148,19 @@ M: c-type-word c-array-constructor
     underlying-type
     dup [ name>> "<" "-array>" surround ] [ specialized-array-vocab ] bi lookup
     [ ] [ specialized-array-vocab-not-loaded ] ?if ; foldable
+M: pointer c-array-constructor drop void* c-array-constructor ;
 
 M: c-type-word c-(array)-constructor
     underlying-type
     dup [ name>> "(" "-array)" surround ] [ specialized-array-vocab ] bi lookup
     [ ] [ specialized-array-vocab-not-loaded ] ?if ; foldable
+M: pointer c-(array)-constructor drop void* c-(array)-constructor ;
 
 M: c-type-word c-direct-array-constructor
     underlying-type
     dup [ name>> "<direct-" "-array>" surround ] [ specialized-array-vocab ] bi lookup
     [ ] [ specialized-array-vocab-not-loaded ] ?if ; foldable
+M: pointer c-direct-array-constructor drop void* c-direct-array-constructor ;
 
 SYNTAX: SPECIALIZED-ARRAYS:
     ";" parse-tokens [ parse-c-type define-array-vocab use-vocab ] each ;
diff --git a/extra/alien/data/map/map.factor b/extra/alien/data/map/map.factor
index 06997bce56..6c93e8f4b6 100644
--- a/extra/alien/data/map/map.factor
+++ b/extra/alien/data/map/map.factor
@@ -54,7 +54,7 @@ INSTANCE: data-map-param immutable-sequence
     nip '[ _ <sliced-groups> ] ;
 
 : [>param] ( type -- quot )
-    c-type-count over c-type-word?
+    c-type-count over c-type-name?
     [ [>c-type-param] ] [ [>object-param] ] if ; 
 
 MACRO: >param ( in -- quot: ( array -- param ) )
@@ -74,7 +74,7 @@ MACRO: >param ( in -- quot: ( array -- param ) )
     "Factor sequences as data-map outputs not supported" throw ;
 
 : [alloc-param] ( type -- quot )
-    c-type-count over c-type-word?
+    c-type-count over c-type-name?
     [ [alloc-c-type-param] ] [ [alloc-object-param] ] if ; 
 
 MACRO: alloc-param ( out -- quot: ( len -- param ) )

From 5faa97e42c5cd5f838ad9b26fd340b6b946930e2 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 21:06:00 -0800
Subject: [PATCH 153/250] alien.parser: favor parsing "foo*" as pointer-to-foo
 now

---
 basis/alien/c-types/c-types.factor | 4 +++-
 basis/alien/parser/parser.factor   | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor
index b038244cdd..9db6ac7f4a 100644
--- a/basis/alien/c-types/c-types.factor
+++ b/basis/alien/c-types/c-types.factor
@@ -304,7 +304,9 @@ CONSTANT: primitive-types
 
 : resolve-pointer-typedef ( type -- base-type )
     dup "c-type" word-prop dup word?
-    [ nip resolve-pointer-typedef ] [ drop ] if ;
+    [ nip resolve-pointer-typedef ] [
+        pointer? [ drop void* ] when
+    ] if ;
 
 : special-pointer-type ( type -- special-type )
     dup c-type-word? [
diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor
index 50d1bfd320..dee5c6e1dd 100644
--- a/basis/alien/parser/parser.factor
+++ b/basis/alien/parser/parser.factor
@@ -18,8 +18,8 @@ IN: alien.parser
     {
         { [ dup "void" =         ] [ drop void ] }
         { [ CHAR: ] over member? ] [ parse-array-type parse-c-type-name prefix ] }
-        { [ dup search           ] [ parse-c-type-name ] }
         { [ "*" ?tail            ] [ (parse-c-type) <pointer> ] }
+        { [ dup search           ] [ parse-c-type-name ] }
         [ dup search [ ] [ no-word ] ?if ]
     } cond ;
 

From 04cc3052b67f3bc7a1d6a93aedca319610e68c84 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 21:32:34 -0800
Subject: [PATCH 154/250] alien.prettyprint: pprint pointer objects as "type*"
 in c-type contexts

---
 basis/alien/prettyprint/prettyprint.factor | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/basis/alien/prettyprint/prettyprint.factor b/basis/alien/prettyprint/prettyprint.factor
index 489ea0b10a..52e9978a5f 100644
--- a/basis/alien/prettyprint/prettyprint.factor
+++ b/basis/alien/prettyprint/prettyprint.factor
@@ -19,9 +19,19 @@ M: c-type-word definer drop \ C-TYPE: f ;
 M: c-type-word definition drop f ;
 M: c-type-word declarations. drop ;
 
+<PRIVATE
+GENERIC: pointer-string ( pointer -- string/f )
+M: object pointer-string drop f ;
+M: word pointer-string name>> ;
+M: pointer pointer-string to>> pointer-string [ CHAR: * suffix ] [ f ] if* ;
+PRIVATE>
+
 GENERIC: pprint-c-type ( c-type -- )
 M: word pprint-c-type pprint-word ;
-M: pointer pprint-c-type pprint* ;
+M: pointer pprint-c-type
+    dup pointer-string
+    [ swap present-text ]
+    [ pprint* ] if* ;
 M: wrapper pprint-c-type wrapped>> pprint-word ;
 M: string pprint-c-type text ;
 M: array pprint-c-type pprint* ;

From 957f2d9ff61234ec90cf8c5a8a2aa9ac51ff7e04 Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Sun, 21 Feb 2010 23:37:33 -0600
Subject: [PATCH 155/250] Check if we're using ttys before starting curses,
 since initscr exits on error for some dumb reason

---
 basis/unix/ffi/ffi.factor        | 1 +
 extra/curses/curses-tests.factor | 5 +++--
 extra/curses/curses.factor       | 7 ++++++-
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/basis/unix/ffi/ffi.factor b/basis/unix/ffi/ffi.factor
index 3882f6fc80..10346cff2c 100644
--- a/basis/unix/ffi/ffi.factor
+++ b/basis/unix/ffi/ffi.factor
@@ -101,6 +101,7 @@ FUNCTION: uid_t getuid ;
 FUNCTION: uint htonl ( uint n ) ;
 FUNCTION: ushort htons ( ushort n ) ;
 ! FUNCTION: int issetugid ;
+FUNCTION: int isatty ( int fildes ) ;
 FUNCTION: int ioctl ( int fd, ulong request, char* argp ) ;
 FUNCTION: int lchown ( char* path, uid_t owner, gid_t group ) ;
 FUNCTION: int listen ( int s, int backlog ) ;
diff --git a/extra/curses/curses-tests.factor b/extra/curses/curses-tests.factor
index 21463b207b..bd98a7aff1 100644
--- a/extra/curses/curses-tests.factor
+++ b/extra/curses/curses-tests.factor
@@ -14,5 +14,6 @@ IN: curses.tests
         2000000 sleep
     ] with-curses ;
 
-[
-] [ hello-curses ] unit-test
+curses-ok? [
+    [ ] [ hello-curses ] unit-test
+] when
diff --git a/extra/curses/curses.factor b/extra/curses/curses.factor
index 69c6503aa2..dfb1b8672a 100644
--- a/extra/curses/curses.factor
+++ b/extra/curses/curses.factor
@@ -4,7 +4,7 @@ USING: accessors alien.c-types alien.strings assocs byte-arrays
 combinators continuations destructors fry io.encodings.8-bit
 io io.encodings.string io.encodings.utf8 kernel locals math
 namespaces prettyprint sequences classes.struct
-strings threads curses.ffi ;
+strings threads curses.ffi unix.ffi ;
 IN: curses
 
 SYMBOL: curses-windows
@@ -19,6 +19,7 @@ ERROR: duplicate-window window ;
 ERROR: unnamed-window window ;
 ERROR: window-not-found window ;
 ERROR: curses-failed ;
+ERROR: unsupported-curses-terminal ;
 
 : get-window ( string -- window )
     dup curses-windows get at*
@@ -28,7 +29,11 @@ ERROR: curses-failed ;
 
 : curses-error ( n -- ) ERR = [ curses-failed ] when ;
 
+: curses-ok? ( -- ? )
+    { 0 1 2 } [ isatty 0 = not ] all? ;
+
 : with-curses ( quot -- )
+    curses-ok? [ unsupported-curses-terminal ] unless
     H{ } clone curses-windows [
         initscr curses-error
         [

From 5b726f0af9fef70236fe856dc455237f087d08cc Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 22:04:23 -0800
Subject: [PATCH 156/250] add missing using to classes.struct tests

---
 basis/classes/struct/struct-tests.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/classes/struct/struct-tests.factor b/basis/classes/struct/struct-tests.factor
index 0316b1fae0..82530614bf 100644
--- a/basis/classes/struct/struct-tests.factor
+++ b/basis/classes/struct/struct-tests.factor
@@ -1,5 +1,5 @@
 ! (c)Joe Groff bsd license
-USING: accessors alien alien.c-types alien.data ascii
+USING: accessors alien alien.c-types alien.data alien.syntax ascii
 assocs byte-arrays classes.struct classes.tuple.private classes.tuple
 combinators compiler.tree.debugger compiler.units destructors
 io.encodings.utf8 io.pathnames io.streams.string kernel libc

From dcd76d2abe08c343d1efccaf94593f28ff21c700 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 22:07:32 -0800
Subject: [PATCH 157/250] windows.com.syntax: don't put c-type words inside
 stack effect of Interface::Method words

---
 basis/windows/com/syntax/syntax.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/windows/com/syntax/syntax.factor b/basis/windows/com/syntax/syntax.factor
index 5e08454d5a..7e93a6e9f8 100644
--- a/basis/windows/com/syntax/syntax.factor
+++ b/basis/windows/com/syntax/syntax.factor
@@ -71,7 +71,7 @@ ERROR: no-com-interface interface ;
 : (stack-effect-from-return-and-parameters) ( return parameters -- stack-effect )
     swap
     [ [ second ] map ]
-    [ dup void? [ drop { } ] [ 1array ] if ] bi*
+    [ dup void? [ drop { } ] [ name>> 1array ] if ] bi*
     <effect> ;
 
 : (define-word-for-function) ( function interface n -- )

From 525a57fa3d84ff7a614f84d933d83558972d9719 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 22:07:53 -0800
Subject: [PATCH 158/250] windows.com: add missing USING: windows.types

---
 basis/windows/com/com-tests.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/windows/com/com-tests.factor b/basis/windows/com/com-tests.factor
index 329a84ef13..f0b4eadb9f 100644
--- a/basis/windows/com/com-tests.factor
+++ b/basis/windows/com/com-tests.factor
@@ -1,5 +1,5 @@
 USING: kernel windows.com windows.com.syntax windows.ole32
-alien alien.syntax tools.test libc alien.c-types
+windows.types alien alien.syntax tools.test libc alien.c-types
 namespaces arrays continuations accessors math windows.com.wrapper
 windows.com.wrapper.private destructors effects compiler.units ;
 IN: windows.com.tests

From a0b3a370b8d19f51e8471c543e0ce447bf548431 Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Wed, 17 Feb 2010 16:42:53 -0600
Subject: [PATCH 159/250] Fix quirk in open-in-explorer -- msft explorer
 wouldn't go to previous directory correctly if / was a path separator

---
 basis/tools/deploy/windows/windows.factor | 7 ++++++-
 basis/windows/shell32/shell32.factor      | 3 ---
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/basis/tools/deploy/windows/windows.factor b/basis/tools/deploy/windows/windows.factor
index 1dd60583fa..f52154ccd0 100755
--- a/basis/tools/deploy/windows/windows.factor
+++ b/basis/tools/deploy/windows/windows.factor
@@ -5,7 +5,8 @@ io.encodings.ascii kernel namespaces
 sequences locals system splitting tools.deploy.backend
 tools.deploy.config tools.deploy.config.editor assocs hashtables
 prettyprint combinators windows.kernel32 windows.shell32 windows.user32
-alien.c-types vocabs.metadata vocabs.loader tools.deploy.windows.ico ;
+alien.c-types vocabs.metadata vocabs.loader tools.deploy.windows.ico
+io.files.windows.nt ;
 IN: tools.deploy.windows
 
 CONSTANT: app-icon-resource-id "APPICON"
@@ -22,6 +23,10 @@ CONSTANT: app-icon-resource-id "APPICON"
     dup copy-dll
     deploy-ui? get ".exe" ".com" ? copy-vm ;
 
+: open-in-explorer ( dir -- )
+    [ f "open" ] dip absolute-path normalize-separators
+    f f SW_SHOWNORMAL ShellExecute drop ;
+
 : embed-ico ( vm vocab -- )
     dup vocab-windows-icon-path vocab-append-path dup exists?
     [ binary file-contents app-icon-resource-id embed-icon-resource ]
diff --git a/basis/windows/shell32/shell32.factor b/basis/windows/shell32/shell32.factor
index 08474d4bdd..30104e7723 100644
--- a/basis/windows/shell32/shell32.factor
+++ b/basis/windows/shell32/shell32.factor
@@ -87,9 +87,6 @@ ALIAS: SHGetFolderPath SHGetFolderPathW
 FUNCTION: HINSTANCE ShellExecuteW ( HWND hwnd, LPCTSTR lpOperation, LPCTSTR lpFile, LPCTSTR lpParameters, LPCTSTR lpDirectory, INT nShowCmd ) ;
 ALIAS: ShellExecute ShellExecuteW
 
-: open-in-explorer ( dir -- )
-    [ f "open" ] dip absolute-path f f SW_SHOWNORMAL ShellExecute drop ;
-
 : shell32-directory ( n -- str )
     f swap f SHGFP_TYPE_DEFAULT
     MAX_UNICODE_PATH <ushort-array>

From 82e773f8ba97411758b42351afe453962aa3f5dd Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Wed, 17 Feb 2010 16:43:53 -0600
Subject: [PATCH 160/250] Add some more win32 symbols

---
 basis/windows/advapi32/advapi32.factor |  12 +-
 basis/windows/user32/user32.factor     | 149 ++++++++++++++++++++++++-
 2 files changed, 158 insertions(+), 3 deletions(-)

diff --git a/basis/windows/advapi32/advapi32.factor b/basis/windows/advapi32/advapi32.factor
index fa478b03ed..d5fe33b745 100644
--- a/basis/windows/advapi32/advapi32.factor
+++ b/basis/windows/advapi32/advapi32.factor
@@ -405,7 +405,7 @@ CONSTANT: KEY_READ                HEX: 20019
 CONSTANT: KEY_WOW64_32KEY         HEX: 0200
 CONSTANT: KEY_WOW64_64KEY         HEX: 0100
 CONSTANT: KEY_WRITE               HEX: 20006
-CONSTANT: KEY_EXECUTE             KEY_READ
+ALIAS: KEY_EXECUTE             KEY_READ
 CONSTANT: KEY_ALL_ACCESS          HEX: F003F
 
 CONSTANT: REG_NONE                         0
@@ -423,6 +423,9 @@ CONSTANT: REG_RESOURCE_REQUIREMENTS_LIST  10
 CONSTANT: REG_QWORD                       11
 CONSTANT: REG_QWORD_LITTLE_ENDIAN         11
 
+CONSTANT: REG_CREATED_NEW_KEY     1
+CONSTANT: REG_OPENED_EXISTING_KEY 2
+
 TYPEDEF: DWORD REGSAM
 
 ! : I_ScGetCurrentGroupStateW ;
@@ -926,6 +929,7 @@ FUNCTION: LONG RegCloseKey ( HKEY hKey ) ;
 ! : RegCreateKeyA ;
 ! : RegCreateKeyExA ;
 FUNCTION: LONG RegCreateKeyExW ( HKEY hKey, LPCTSTR lpSubKey, DWORD Reserved, LPTSTR lpClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition ) ;
+ALIAS: RegCreateKeyEx RegCreateKeyExW
 ! : RegCreateKeyW
 ! : RegDeleteKeyA ;
 ! : RegDeleteKeyW ;
@@ -949,6 +953,7 @@ ALIAS: RegDeleteKeyEx RegDeleteKeyExW
 ! : RegDisablePredefinedCache ;
 ! : RegEnumKeyA ;
 ! : RegEnumKeyExA ;
+
 FUNCTION: LONG RegEnumKeyExW (
         HKEY hKey,
         DWORD dwIndex,
@@ -959,6 +964,8 @@ FUNCTION: LONG RegEnumKeyExW (
         LPDWORD lpcClass,
         PFILETIME lpftLastWriteTime
     ) ;
+ALIAS: RegEnumKeyEx RegEnumKeyExW
+
 ! : RegEnumKeyW ;
 ! : RegEnumValueA ;
 
@@ -1023,7 +1030,8 @@ ALIAS: RegQueryValueEx RegQueryValueExW
 ! : RegSetValueA ;
 ! : RegSetValueExA ;
 ! : RegSetValueExW ;
-! : RegSetValueW ;
+FUNCTION: LONG RegSetValueExW ( HKEY hKey, LPCTSTR lpValueName, DWORD Reserved, DWORD dwType, BYTE* lpData, DWORD cbData ) ;
+ALIAS: RegSetValueEx RegSetValueExW
 ! : RegUnLoadKeyA ;
 ! : RegUnLoadKeyW ;
 ! : RegisterEventSourceA ;
diff --git a/basis/windows/user32/user32.factor b/basis/windows/user32/user32.factor
index 15eb9ba2f5..27636271cb 100644
--- a/basis/windows/user32/user32.factor
+++ b/basis/windows/user32/user32.factor
@@ -608,6 +608,150 @@ CONSTANT: MF_HELP            HEX: 4000
 CONSTANT: MF_RIGHTJUSTIFY    HEX: 4000
 CONSTANT: MF_MOUSESELECT     HEX: 8000
 
+CONSTANT: SPI_GETBEEP               1
+CONSTANT: SPI_SETBEEP               2
+CONSTANT: SPI_GETMOUSE              3
+CONSTANT: SPI_SETMOUSE              4
+CONSTANT: SPI_GETBORDER             5
+CONSTANT: SPI_SETBORDER             6
+CONSTANT: SPI_GETKEYBOARDSPEED      10
+CONSTANT: SPI_SETKEYBOARDSPEED      11
+CONSTANT: SPI_LANGDRIVER            12
+CONSTANT: SPI_ICONHORIZONTALSPACING 13
+CONSTANT: SPI_GETSCREENSAVETIMEOUT  14
+CONSTANT: SPI_SETSCREENSAVETIMEOUT  15
+CONSTANT: SPI_GETSCREENSAVEACTIVE   16
+CONSTANT: SPI_SETSCREENSAVEACTIVE   17
+CONSTANT: SPI_GETGRIDGRANULARITY    18
+CONSTANT: SPI_SETGRIDGRANULARITY    19
+CONSTANT: SPI_SETDESKWALLPAPER      20
+CONSTANT: SPI_SETDESKPATTERN        21
+CONSTANT: SPI_GETKEYBOARDDELAY      22
+CONSTANT: SPI_SETKEYBOARDDELAY      23
+CONSTANT: SPI_ICONVERTICALSPACING   24
+CONSTANT: SPI_GETICONTITLEWRAP      25
+CONSTANT: SPI_SETICONTITLEWRAP      26
+CONSTANT: SPI_GETMENUDROPALIGNMENT  27
+CONSTANT: SPI_SETMENUDROPALIGNMENT  28
+CONSTANT: SPI_SETDOUBLECLKWIDTH     29
+CONSTANT: SPI_SETDOUBLECLKHEIGHT    30
+CONSTANT: SPI_GETICONTITLELOGFONT   31
+CONSTANT: SPI_SETDOUBLECLICKTIME    32
+CONSTANT: SPI_SETMOUSEBUTTONSWAP    33
+CONSTANT: SPI_SETICONTITLELOGFONT   34
+CONSTANT: SPI_GETFASTTASKSWITCH     35
+CONSTANT: SPI_SETFASTTASKSWITCH     36
+CONSTANT: SPI_SETDRAGFULLWINDOWS    37
+CONSTANT: SPI_GETDRAGFULLWINDOWS    38
+
+CONSTANT: SPI_GETFILTERKEYS         50
+CONSTANT: SPI_SETFILTERKEYS         51
+CONSTANT: SPI_GETTOGGLEKEYS         52
+CONSTANT: SPI_SETTOGGLEKEYS         53
+CONSTANT: SPI_GETMOUSEKEYS          54
+CONSTANT: SPI_SETMOUSEKEYS          55
+CONSTANT: SPI_GETSHOWSOUNDS         56
+CONSTANT: SPI_SETSHOWSOUNDS         57
+CONSTANT: SPI_GETSTICKYKEYS         58
+CONSTANT: SPI_SETSTICKYKEYS         59
+CONSTANT: SPI_GETACCESSTIMEOUT      60
+CONSTANT: SPI_SETACCESSTIMEOUT      61
+
+CONSTANT: SPI_GETSOUNDSENTRY        64
+CONSTANT: SPI_SETSOUNDSENTRY        65
+
+! WINVER >= 0x0400
+CONSTANT: SPI_GETNONCLIENTMETRICS   41
+CONSTANT: SPI_SETNONCLIENTMETRICS   42
+CONSTANT: SPI_GETMINIMIZEDMETRICS   43
+CONSTANT: SPI_SETMINIMIZEDMETRICS   44
+CONSTANT: SPI_GETICONMETRICS        45
+CONSTANT: SPI_SETICONMETRICS        46
+CONSTANT: SPI_SETWORKAREA           47
+CONSTANT: SPI_GETWORKAREA           48
+CONSTANT: SPI_SETPENWINDOWS         49
+
+CONSTANT: SPI_GETSERIALKEYS         62
+CONSTANT: SPI_SETSERIALKEYS         63
+CONSTANT: SPI_GETHIGHCONTRAST       66
+CONSTANT: SPI_SETHIGHCONTRAST       67
+CONSTANT: SPI_GETKEYBOARDPREF       68
+CONSTANT: SPI_SETKEYBOARDPREF       69
+CONSTANT: SPI_GETSCREENREADER       70
+CONSTANT: SPI_SETSCREENREADER       71
+CONSTANT: SPI_GETANIMATION          72
+CONSTANT: SPI_SETANIMATION          73
+CONSTANT: SPI_GETFONTSMOOTHING      74
+CONSTANT: SPI_SETFONTSMOOTHING      75
+CONSTANT: SPI_SETDRAGWIDTH          76
+CONSTANT: SPI_SETDRAGHEIGHT         77
+CONSTANT: SPI_SETHANDHELD           78
+CONSTANT: SPI_GETLOWPOWERTIMEOUT    79
+CONSTANT: SPI_GETPOWEROFFTIMEOUT    80
+CONSTANT: SPI_SETLOWPOWERTIMEOUT    81
+CONSTANT: SPI_SETPOWEROFFTIMEOUT    82
+CONSTANT: SPI_GETLOWPOWERACTIVE     83
+CONSTANT: SPI_GETPOWEROFFACTIVE     84
+CONSTANT: SPI_SETLOWPOWERACTIVE     85
+CONSTANT: SPI_SETPOWEROFFACTIVE     86
+CONSTANT: SPI_SETCURSORS            87
+CONSTANT: SPI_SETICONS              88
+CONSTANT: SPI_GETDEFAULTINPUTLANG   89
+CONSTANT: SPI_SETDEFAULTINPUTLANG   90
+CONSTANT: SPI_SETLANGTOGGLE         91
+CONSTANT: SPI_GETWINDOWSEXTENSION   92
+CONSTANT: SPI_SETMOUSETRAILS        93
+CONSTANT: SPI_GETMOUSETRAILS        94
+CONSTANT: SPI_SETSCREENSAVERRUNNING 97
+ALIAS: SPI_SCREENSAVERRUNNING    SPI_SETSCREENSAVERRUNNING
+
+! WIN32_WINNT >= 0x0400 || WIN32_WINDOWS > 0x0400
+CONSTANT: SPI_GETMOUSEHOVERWIDTH    98
+CONSTANT: SPI_SETMOUSEHOVERWIDTH    99
+CONSTANT: SPI_GETMOUSEHOVERHEIGHT   100
+CONSTANT: SPI_SETMOUSEHOVERHEIGHT   101
+CONSTANT: SPI_GETMOUSEHOVERTIME     102
+CONSTANT: SPI_SETMOUSEHOVERTIME     103
+CONSTANT: SPI_GETWHEELSCROLLLINES   104
+CONSTANT: SPI_SETWHEELSCROLLLINES   105
+
+CONSTANT: SPI_GETSHOWIMEUI          110
+CONSTANT: SPI_SETSHOWIMEUI          111
+
+! WINVER >= 0x0500
+CONSTANT: SPI_GETMOUSESPEED         112
+CONSTANT: SPI_SETMOUSESPEED         113
+CONSTANT: SPI_GETSCREENSAVERRUNNING 114
+
+CONSTANT: SPI_GETACTIVEWINDOWTRACKING    HEX: 1000
+CONSTANT: SPI_SETACTIVEWINDOWTRACKING    HEX: 1001
+CONSTANT: SPI_GETMENUANIMATION           HEX: 1002
+CONSTANT: SPI_SETMENUANIMATION           HEX: 1003
+CONSTANT: SPI_GETCOMBOBOXANIMATION       HEX: 1004
+CONSTANT: SPI_SETCOMBOBOXANIMATION       HEX: 1005
+CONSTANT: SPI_GETLISTBOXSMOOTHSCROLLING  HEX: 1006
+CONSTANT: SPI_SETLISTBOXSMOOTHSCROLLING  HEX: 1007
+CONSTANT: SPI_GETGRADIENTCAPTIONS        HEX: 1008
+CONSTANT: SPI_SETGRADIENTCAPTIONS        HEX: 1009
+CONSTANT: SPI_GETMENUUNDERLINES          HEX: 100A
+CONSTANT: SPI_SETMENUUNDERLINES          HEX: 100B
+CONSTANT: SPI_GETACTIVEWNDTRKZORDER      HEX: 100C
+CONSTANT: SPI_SETACTIVEWNDTRKZORDER      HEX: 100D
+CONSTANT: SPI_GETHOTTRACKING             HEX: 100E
+CONSTANT: SPI_SETHOTTRACKING             HEX: 100F
+CONSTANT: SPI_GETFOREGROUNDLOCKTIMEOUT   HEX: 2000
+CONSTANT: SPI_SETFOREGROUNDLOCKTIMEOUT   HEX: 2001
+CONSTANT: SPI_GETACTIVEWNDTRKTIMEOUT     HEX: 2002
+CONSTANT: SPI_SETACTIVEWNDTRKTIMEOUT     HEX: 2003
+CONSTANT: SPI_GETFOREGROUNDFLASHCOUNT    HEX: 2004
+CONSTANT: SPI_SETFOREGROUNDFLASHCOUNT    HEX: 2005
+
+! SystemParamInfo Flags
+CONSTANT: SPIF_UPDATEINIFILE              1
+CONSTANT: SPIF_SENDWININICHANGE           2
+ALIAS: SPIF_SENDCHANGE                 SPIF_SENDWININICHANGE
+
+
 TYPEDEF: HANDLE HRAWINPUT
 : GET_RAWINPUT_CODE_WPARAM ( wParam -- n ) HEX: ff bitand ; inline
 
@@ -1578,7 +1722,10 @@ FUNCTION: BOOL ShowWindow ( HWND hWnd, int nCmdShow ) ;
 ! FUNCTION: SwitchDesktop
 ! FUNCTION: SwitchToThisWindow
 ! FUNCTION: SystemParametersInfoA
-! FUNCTION: SystemParametersInfoW
+
+FUNCTION: BOOL SystemParametersInfoW ( UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni ) ;
+ALIAS: SystemParametersInfo SystemParametersInfoW
+
 ! FUNCTION: TabbedTextOutA
 ! FUNCTION: TabbedTextOutW
 ! FUNCTION: TileChildWindows

From bb06e4671a49b1fa926097617e7121ac280e8e63 Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Mon, 22 Feb 2010 00:20:00 -0600
Subject: [PATCH 161/250] Require that g++ or cl be present to use factor.sh

---
 build-support/factor.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/build-support/factor.sh b/build-support/factor.sh
index a02a2fad7e..3a5fb4e253 100755
--- a/build-support/factor.sh
+++ b/build-support/factor.sh
@@ -107,6 +107,7 @@ check_installed_programs() {
     ensure_program_installed git
     ensure_program_installed wget curl
     ensure_program_installed gcc
+    ensure_program_installed g++ cl
     ensure_program_installed make gmake
     ensure_program_installed md5sum md5
     ensure_program_installed cut

From db3a23ffe05184f54c798972e2d3f7345ac2f33a Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Mon, 22 Feb 2010 19:15:53 +1300
Subject: [PATCH 162/250] parser: auto-use prefers non-private words to private
 words

---
 core/parser/parser.factor | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/core/parser/parser.factor b/core/parser/parser.factor
index e23673a479..544d75b244 100644
--- a/core/parser/parser.factor
+++ b/core/parser/parser.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2005, 2009 Slava Pestov.
+! Copyright (C) 2005, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays definitions generic assocs kernel math namespaces
 sequences strings vectors words words.symbol quotations io
@@ -33,11 +33,19 @@ SYMBOL: auto-use?
         [ "Added \"" "\" vocabulary to search path" surround note. ] bi
     ] [ create-in ] if ;
 
+: ignore-forwards ( seq -- seq' )
+    [ forward-reference? not ] filter ;
+
+: private? ( word -- ? ) vocabulary>> ".private" tail? ;
+
+: ignore-privates ( seq -- seq' )
+    dup [ private? ] all? [ [ private? not ] filter ] unless ;
+
 : no-word ( name -- newword )
-    dup words-named [ forward-reference? not ] filter
-    dup length 1 = auto-use? get and
-    [ nip first no-word-restarted ]
-    [ <no-word-error> throw-restarts no-word-restarted ]
+    dup words-named ignore-forwards
+    dup ignore-privates dup length 1 = auto-use? get and
+    [ 2nip first no-word-restarted ]
+    [ drop <no-word-error> throw-restarts no-word-restarted ]
     if ;
 
 : parse-word ( string -- word/number )

From 2c34ecbdb54a5f5900c27184be1bac45b84c4329 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Mon, 22 Feb 2010 19:21:56 +1300
Subject: [PATCH 163/250] stack-checker.dependencies: add depends-on-c-type

---
 .../stack-checker/dependencies/dependencies.factor  | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/basis/stack-checker/dependencies/dependencies.factor b/basis/stack-checker/dependencies/dependencies.factor
index ece943acac..1bd7cdcd31 100644
--- a/basis/stack-checker/dependencies/dependencies.factor
+++ b/basis/stack-checker/dependencies/dependencies.factor
@@ -1,8 +1,8 @@
 ! Copyright (C) 2009, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: assocs accessors classes classes.algebra fry generic
-kernel math namespaces sequences words sets
-combinators.short-circuit classes.tuple ;
+USING: arrays assocs accessors classes classes.algebra fry
+generic kernel math namespaces sequences words sets
+combinators.short-circuit classes.tuple alien.c-types ;
 FROM: classes.tuple.private => tuple-layout ;
 FROM: assocs => change-at ;
 IN: stack-checker.dependencies
@@ -38,6 +38,13 @@ SYMBOLS: effect-dependency conditional-dependency definition-dependency ;
 : depends-on-definition ( word -- )
     definition-dependency depends-on ;
 
+GENERIC: depends-on-c-type ( c-type -- )
+
+M: c-type-word depends-on-c-type depends-on-definition ;
+
+M: array depends-on-c-type
+    [ word? ] filter [ depends-on-definition ] each ;
+
 ! Generic words that the current quotation depends on
 SYMBOL: generic-dependencies
 

From 310b3df2ec5b32929093dbd6922e9fb5f9465806 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 22:31:32 -0800
Subject: [PATCH 164/250] stack-checker.dependencies: add method for pointers
 to depends-on-c-type

---
 basis/stack-checker/dependencies/dependencies.factor | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/basis/stack-checker/dependencies/dependencies.factor b/basis/stack-checker/dependencies/dependencies.factor
index 1bd7cdcd31..4c5529d424 100644
--- a/basis/stack-checker/dependencies/dependencies.factor
+++ b/basis/stack-checker/dependencies/dependencies.factor
@@ -45,6 +45,9 @@ M: c-type-word depends-on-c-type depends-on-definition ;
 M: array depends-on-c-type
     [ word? ] filter [ depends-on-definition ] each ;
 
+M: pointer depends-on-c-type
+    to>> depends-on-c-type ;
+
 ! Generic words that the current quotation depends on
 SYMBOL: generic-dependencies
 

From c7acbda342115e0a8fb5aa287126b9595c934920 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 22:46:52 -0800
Subject: [PATCH 165/250] classes.struct: set dependency on slot types in slot
 accessors, so that accessors update when types change. enables pointers to
 make circular references between struct types

---
 basis/classes/struct/struct.factor | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/basis/classes/struct/struct.factor b/basis/classes/struct/struct.factor
index 4e7a565a5a..af73be3aa4 100644
--- a/basis/classes/struct/struct.factor
+++ b/basis/classes/struct/struct.factor
@@ -8,7 +8,8 @@ generalizations generic.parser kernel kernel.private lexer libc
 locals macros make math math.order parser quotations sequences
 slots slots.private specialized-arrays vectors words summary
 namespaces assocs vocabs.parser math.functions
-classes.struct.bit-accessors bit-arrays ;
+classes.struct.bit-accessors bit-arrays
+stack-checker.dependencies ;
 QUALIFIED: math
 IN: classes.struct
 
@@ -124,6 +125,14 @@ M: struct-bit-slot-spec (writer-quot)
 
 : (unboxer-quot) ( class -- quot )
     drop [ >c-ptr ] ;
+
+MACRO: read-struct-slot ( slot -- )
+    dup type>> depends-on-c-type
+    (reader-quot) ;
+
+MACRO: write-struct-slot ( slot -- )
+    dup type>> depends-on-c-type
+    (writer-quot) ;
 PRIVATE>
 
 M: struct-class boa>object
@@ -138,10 +147,10 @@ M: struct-class initial-value* <struct> ; inline
 GENERIC: struct-slot-values ( struct -- sequence )
 
 M: struct-class reader-quot
-    nip (reader-quot) ;
+    nip '[ _ read-struct-slot ] ;
 
 M: struct-class writer-quot
-    nip (writer-quot) ;
+    nip '[ _ write-struct-slot ] ;
 
 : offset-of ( field struct -- offset )
     struct-slots slot-named offset>> ; inline

From 0bc8e8f40844179cee3e7df116915f5d7dd2a97c Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 23:11:59 -0800
Subject: [PATCH 166/250] alien.arrays: typedef special char* symbol so it
 still works as expected

---
 basis/alien/arrays/arrays.factor | 1 +
 1 file changed, 1 insertion(+)

diff --git a/basis/alien/arrays/arrays.factor b/basis/alien/arrays/arrays.factor
index c62800df36..4fddba1de6 100644
--- a/basis/alien/arrays/arrays.factor
+++ b/basis/alien/arrays/arrays.factor
@@ -104,6 +104,7 @@ M: string-type c-type-setter
     drop [ set-alien-cell ] ;
 
 { char* utf8 } char <pointer> typedef
+{ char* utf8 } char* typedef
 { char* utf8 } uchar <pointer> typedef
 { char* binary } byte <pointer> typedef
 { char* binary } ubyte <pointer> typedef

From d8432db49557fd20a5edee219ddc1211e442a7f8 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 23:12:28 -0800
Subject: [PATCH 167/250] openssl: replace some TYPEDEF: void* foo* (which
 won't work anymore) with C-TYPE: foo

---
 basis/openssl/libcrypto/libcrypto.factor | 2 +-
 basis/openssl/libssl/libssl.factor       | 7 +++----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/basis/openssl/libcrypto/libcrypto.factor b/basis/openssl/libcrypto/libcrypto.factor
index dbc5b9e43c..fd5c757bc4 100644
--- a/basis/openssl/libcrypto/libcrypto.factor
+++ b/basis/openssl/libcrypto/libcrypto.factor
@@ -103,7 +103,7 @@ FUNCTION: void* BIO_f_buffer (  ) ;
 
 CONSTANT: EVP_MAX_MD_SIZE 64
 
-TYPEDEF: void* EVP_MD*
+C-TYPE: EVP_MD
 C-TYPE: ENGINE
 
 STRUCT: EVP_MD_CTX
diff --git a/basis/openssl/libssl/libssl.factor b/basis/openssl/libssl/libssl.factor
index 225d4b3da1..1c6fbec011 100644
--- a/basis/openssl/libssl/libssl.factor
+++ b/basis/openssl/libssl/libssl.factor
@@ -89,8 +89,8 @@ CONSTANT: SSL_ERROR_WANT_ACCEPT      8
     } ;
 
 TYPEDEF: void* ssl-method
-TYPEDEF: void* SSL_CTX*
-TYPEDEF: void* SSL_SESSION*
+C-TYPE: SSL_CTX
+C-TYPE: SSL_SESSION
 C-TYPE: SSL
 
 LIBRARY: libssl
@@ -99,8 +99,7 @@ LIBRARY: libssl
 ! x509.h
 ! ===============================================
 
-TYPEDEF: void* X509_NAME*
-
+C-TYPE: X509_NAME
 C-TYPE: X509
 
 FUNCTION: int X509_NAME_get_text_by_NID ( X509_NAME* name, int nid, void* buf, int len ) ;

From c4cc70b92c041a3723c8c9b9e303f7701fc3384b Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 23:13:12 -0800
Subject: [PATCH 168/250] stack-checker.dependencies: extend c-type-word method
 for depends-on-c-type to all words (so it works for non-c-types like void)

---
 basis/stack-checker/dependencies/dependencies.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/stack-checker/dependencies/dependencies.factor b/basis/stack-checker/dependencies/dependencies.factor
index 4c5529d424..ffa021c9f6 100644
--- a/basis/stack-checker/dependencies/dependencies.factor
+++ b/basis/stack-checker/dependencies/dependencies.factor
@@ -40,7 +40,7 @@ SYMBOLS: effect-dependency conditional-dependency definition-dependency ;
 
 GENERIC: depends-on-c-type ( c-type -- )
 
-M: c-type-word depends-on-c-type depends-on-definition ;
+M: word depends-on-c-type depends-on-definition ;
 
 M: array depends-on-c-type
     [ word? ] filter [ depends-on-definition ] each ;

From d64653ee9a86adc373e86cc2e4f84909de0823b5 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 23:13:31 -0800
Subject: [PATCH 169/250] specialized-arrays: fix underlying-type so it always
 returns void* for pointer types

---
 basis/specialized-arrays/specialized-arrays.factor | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/basis/specialized-arrays/specialized-arrays.factor b/basis/specialized-arrays/specialized-arrays.factor
index 992dbac6d6..97ce2ed1ff 100644
--- a/basis/specialized-arrays/specialized-arrays.factor
+++ b/basis/specialized-arrays/specialized-arrays.factor
@@ -116,7 +116,8 @@ M: A v*high [ * \ T heap-size neg shift ] 2map ; inline
 
 ;FUNCTOR
 
-: underlying-type ( c-type -- c-type' )
+GENERIC: underlying-type ( c-type -- c-type' )
+M: c-type-word underlying-type
     dup "c-type" word-prop {
         { [ dup not ] [ drop no-c-type ] }
         { [ dup pointer? ] [ 2drop void* ] }
@@ -124,6 +125,9 @@ M: A v*high [ * \ T heap-size neg shift ] 2map ; inline
         [ drop ]
     } cond ;
 
+M: pointer underlying-type
+    drop void* ;
+
 : specialized-array-vocab ( c-type -- vocab )
     [
         "specialized-arrays.instances." %

From cdde1aa92a4aa0b65201bdd6737ee11143bf117f Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 21 Feb 2010 23:13:56 -0800
Subject: [PATCH 170/250] opengl.gl: TYPEDEF: void* GLvoid* => C-TYPE: GLvoid

---
 basis/opengl/gl/gl.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/opengl/gl/gl.factor b/basis/opengl/gl/gl.factor
index d89cee57d4..27d24718c2 100644
--- a/basis/opengl/gl/gl.factor
+++ b/basis/opengl/gl/gl.factor
@@ -22,7 +22,7 @@ TYPEDEF: float   GLfloat
 TYPEDEF: float   GLclampf
 TYPEDEF: double  GLdouble
 TYPEDEF: double  GLclampd
-TYPEDEF: void*   GLvoid*
+C-TYPE: GLvoid
 
 ! Constants
 

From 757842969255009581ff81d00ca4e12806fbad99 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Mon, 22 Feb 2010 21:31:41 +1300
Subject: [PATCH 171/250] alien.c-types: remove void? word

---
 basis/alien/c-types/c-types.factor | 8 +++-----
 basis/alien/parser/parser.factor   | 4 ++--
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor
index a929cba954..c25f465600 100644
--- a/basis/alien/c-types/c-types.factor
+++ b/basis/alien/c-types/c-types.factor
@@ -17,8 +17,9 @@ SYMBOLS:
     long ulong
     longlong ulonglong
     float double
-    void* bool
-    void ;
+    void* bool ;
+
+SINGLETON: void
 
 DEFER: <int>
 DEFER: *char
@@ -57,9 +58,6 @@ GENERIC: resolve-pointer-type ( name -- c-type )
 
 << \ void \ void* "pointer-c-type" set-word-prop >>
 
-: void? ( c-type -- ? )
-    { void "void" } member? ;
-
 M: word resolve-pointer-type
     dup "pointer-c-type" word-prop
     [ ] [ drop void* ] ?if ;
diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor
index d706446799..dc0a1701f2 100644
--- a/basis/alien/parser/parser.factor
+++ b/basis/alien/parser/parser.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2008, 2009 Slava Pestov, Doug Coleman.
+! Copyright (C) 2008, 2010 Slava Pestov, Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors alien alien.c-types alien.parser
 alien.libraries arrays assocs classes combinators
@@ -66,7 +66,7 @@ IN: alien.parser
         2 group [ first2 normalize-c-arg 2array ] map
         unzip [ "," ?tail drop ] map
     ]
-    [ [ { } ] [ 1array ] if-void ]
+    [ dup "void" = [ drop { } ] [ 1array ] if ]
     bi* <effect> ;
 
 : function-quot ( return library function types -- quot )

From eb3f8632dd347cc1a1364b4a5388257335884c8b Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Mon, 22 Feb 2010 21:32:41 +1300
Subject: [PATCH 172/250] stack-checker.alien: now that C types are words, the
 compiler can add dependencies on them when compiling alien words. This
 triggers the necessary recompilation when C types are redefined

---
 basis/compiler/tests/redefine24.factor        | 39 ++++++++++
 basis/stack-checker/alien/alien.factor        | 76 +++++++++++++------
 .../dependencies/dependencies.factor          |  2 +
 3 files changed, 92 insertions(+), 25 deletions(-)
 create mode 100644 basis/compiler/tests/redefine24.factor

diff --git a/basis/compiler/tests/redefine24.factor b/basis/compiler/tests/redefine24.factor
new file mode 100644
index 0000000000..391102102e
--- /dev/null
+++ b/basis/compiler/tests/redefine24.factor
@@ -0,0 +1,39 @@
+USING: alien alien.syntax eval math tools.test ;
+QUALIFIED: alien.c-types
+IN: compiler.tests.redefine24
+
+TYPEDEF: alien.c-types:int type-1
+
+TYPEDEF: alien.c-types:int type-3
+
+: callback ( -- ptr )
+    type-3 { type-1 type-1 } "cdecl" [ + >integer ] alien-callback ;
+
+TYPEDEF: alien.c-types:float type-2
+
+: indirect ( x y ptr -- z  )
+    type-3 { type-2 type-2 } "cdecl" alien-indirect ;
+
+[ ] [
+    "USING: alien.c-types alien.syntax ;
+    IN: compiler.tests.redefine24 TYPEDEF: int type-2" eval( -- )
+] unit-test
+
+[ 3 ] [ 1 2 callback indirect ] unit-test
+
+[ ] [
+    "USING: alien.c-types alien.syntax ;
+    IN: compiler.tests.redefine24
+    TYPEDEF: float type-1
+    TYPEDEF: float type-2" eval( -- )
+] unit-test
+
+[ 3 ] [ 1.0 2.0 callback indirect ] unit-test
+
+[ ] [
+    "USING: alien.c-types alien.syntax ;
+    IN: compiler.tests.redefine24
+    TYPEDEF: float type-3" eval( -- )
+] unit-test
+
+[ 3.0 ] [ 1.0 2.0 callback indirect ] unit-test
diff --git a/basis/stack-checker/alien/alien.factor b/basis/stack-checker/alien/alien.factor
index fdfda6dd9e..09121488ef 100644
--- a/basis/stack-checker/alien/alien.factor
+++ b/basis/stack-checker/alien/alien.factor
@@ -3,7 +3,7 @@
 USING: kernel sequences accessors combinators math namespaces
 init sets words assocs alien.libraries alien alien.c-types
 cpu.architecture fry stack-checker.backend stack-checker.errors
-stack-checker.visitor ;
+stack-checker.visitor stack-checker.dependencies ;
 IN: stack-checker.alien
 
 TUPLE: alien-node-params return parameters abi in-d out-d ;
@@ -16,65 +16,91 @@ TUPLE: alien-assembly-params < alien-node-params quot ;
 
 TUPLE: alien-callback-params < alien-node-params quot xt ;
 
-: param-prep-quot ( node -- quot )
+: param-prep-quot ( params -- quot )
     parameters>> [ c-type c-type-unboxer-quot ] map spread>quot ;
 
+: infer-params ( params -- )
+    param-prep-quot infer-quot-here ;
+
 : alien-stack ( params extra -- )
     over parameters>> length + consume-d >>in-d
     dup return>> void? 0 1 ? produce-d >>out-d
     drop ;
 
-: return-prep-quot ( node -- quot )
+: return-prep-quot ( params -- quot )
     return>> [ [ ] ] [ c-type c-type-boxer-quot ] if-void ;
 
+: infer-return ( params -- )
+    return-prep-quot infer-quot-here ;
+
+: pop-return ( params -- params )
+    pop-literal [ depends-on-c-type ] [ nip >>return ] bi ;
+
+: pop-library ( params -- params )
+    pop-literal nip >>library ;
+
+: pop-function ( params -- params )
+    pop-literal nip >>function ;
+
+: pop-params ( params -- params )
+    pop-literal [ [ depends-on-c-type ] each ] [ nip >>parameters ] bi ;
+
+: pop-abi ( params -- params )
+    pop-literal nip >>abi ;
+
+: pop-quot ( params -- params )
+    pop-literal nip >>quot ;
+
 : infer-alien-invoke ( -- )
     alien-invoke-params new
     ! Compile-time parameters
-    pop-literal nip >>parameters
-    pop-literal nip >>function
-    pop-literal nip >>library
-    pop-literal nip >>return
-    ! Quotation which coerces parameters to required types
-    dup param-prep-quot infer-quot-here
+    pop-params
+    pop-function
+    pop-library
+    pop-return
     ! Set ABI
     dup library>> library [ abi>> ] [ "cdecl" ] if* >>abi
+    ! Quotation which coerces parameters to required types
+    dup infer-params
     ! Magic #: consume exactly the number of inputs
     dup 0 alien-stack
     ! Add node to IR
     dup #alien-invoke,
     ! Quotation which coerces return value to required type
-    return-prep-quot infer-quot-here ;
+    infer-return ;
 
 : infer-alien-indirect ( -- )
     alien-indirect-params new
     ! Compile-time parameters
-    pop-literal nip >>abi
-    pop-literal nip >>parameters
-    pop-literal nip >>return
+    pop-abi
+    pop-params
+    pop-return
     ! Quotation which coerces parameters to required types
-    dup param-prep-quot '[ _ dip ] infer-quot-here
+    1 infer->r
+    dup infer-params
+    1 infer-r>
     ! Magic #: consume the function pointer, too
     dup 1 alien-stack
     ! Add node to IR
     dup #alien-indirect,
     ! Quotation which coerces return value to required type
-    return-prep-quot infer-quot-here ;
+    infer-return ;
 
 : infer-alien-assembly ( -- )
     alien-assembly-params new
     ! Compile-time parameters
-    pop-literal nip >>quot
-    pop-literal nip >>abi
-    pop-literal nip >>parameters
-    pop-literal nip >>return
+    pop-quot
+    pop-abi
+    pop-params
+    pop-return
     ! Quotation which coerces parameters to required types
-    dup param-prep-quot infer-quot-here
+    dup infer-params
     ! Magic #: consume exactly the number of inputs
     dup 0 alien-stack
     ! Add node to IR
     dup #alien-assembly,
     ! Quotation which coerces return value to required type
-    return-prep-quot infer-quot-here ;
+    infer-return ;
 
 : callback-xt ( word return-rewind -- alien )
     [ callbacks get ] dip '[ _ <callback> ] cache ;
@@ -85,10 +111,10 @@ TUPLE: alien-callback-params < alien-node-params quot xt ;
 
 : infer-alien-callback ( -- )
     alien-callback-params new
-    pop-literal nip >>quot
-    pop-literal nip >>abi
-    pop-literal nip >>parameters
-    pop-literal nip >>return
+    pop-quot
+    pop-abi
+    pop-params
+    pop-return
     "( callback )" <uninterned-word> >>xt
     dup callback-bottom
     #alien-callback, ;
diff --git a/basis/stack-checker/dependencies/dependencies.factor b/basis/stack-checker/dependencies/dependencies.factor
index 1bd7cdcd31..25fe12cbc5 100644
--- a/basis/stack-checker/dependencies/dependencies.factor
+++ b/basis/stack-checker/dependencies/dependencies.factor
@@ -40,6 +40,8 @@ SYMBOLS: effect-dependency conditional-dependency definition-dependency ;
 
 GENERIC: depends-on-c-type ( c-type -- )
 
+M: void depends-on-c-type drop ;
+
 M: c-type-word depends-on-c-type depends-on-definition ;
 
 M: array depends-on-c-type

From 58485af60b8aaa3bdb57791f18cc7975fda11e6a Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Mon, 22 Feb 2010 00:45:54 -0800
Subject: [PATCH 173/250] Fix CALLBACK: effect return type also not a string.
 Added accompanying unit test.

---
 basis/alien/parser/parser-tests.factor | 9 +++++++--
 basis/alien/parser/parser.factor       | 6 +++---
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/basis/alien/parser/parser-tests.factor b/basis/alien/parser/parser-tests.factor
index 2fec2d9a4c..84eefe9df6 100644
--- a/basis/alien/parser/parser-tests.factor
+++ b/basis/alien/parser/parser-tests.factor
@@ -34,9 +34,14 @@ CONSTANT: eleven 11
 
 ] with-file-vocabs
 
-FUNCTION: void* alien-parser-effect-test ( int *arg1 float arg2 ) ;
+FUNCTION: void* alien-parser-function-effect-test ( int *arg1 float arg2 ) ;
 [ (( arg1 arg2 -- void* )) ] [
-    \ alien-parser-effect-test "declared-effect" word-prop
+    \ alien-parser-function-effect-test "declared-effect" word-prop
+] unit-test
+
+CALLBACK: void* alien-parser-callback-effect-test ( int *arg1 float arg2 ) ;
+[ (( arg1 arg2 -- void* )) ] [
+    \ alien-parser-callback-effect-test "callback-effect" word-prop
 ] unit-test
 
 ! Reported by mnestic
diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor
index dc0a1701f2..d073a4caac 100644
--- a/basis/alien/parser/parser.factor
+++ b/basis/alien/parser/parser.factor
@@ -93,15 +93,15 @@ IN: alien.parser
 : library-abi ( lib -- abi )
     library [ abi>> ] [ "cdecl" ] if* ;
 
-:: make-callback-type ( lib return! type-name! parameters -- word quot effect )
-    return type-name normalize-c-arg type-name! return!
+:: make-callback-type ( lib return type-name parameters -- word quot effect )
+    return type-name normalize-c-arg :> ( return-c-type type-name )
     type-name current-vocab create :> type-word 
     type-word [ reset-generic ] [ reset-c-type ] bi
     void* type-word typedef
     parameters return parse-arglist :> ( types callback-effect )
     type-word callback-effect "callback-effect" set-word-prop
     type-word lib "callback-library" set-word-prop
-    type-word return types lib library-abi callback-quot (( quot -- alien )) ;
+    type-word return-c-type types lib library-abi callback-quot (( quot -- alien )) ;
 
 : (CALLBACK:) ( -- word quot effect )
     "c-library" get

From 869e95717c44ff2042769218cd1c1d83bf95d3c3 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Tue, 23 Feb 2010 00:23:30 +1300
Subject: [PATCH 174/250] windows.ddk.hid: add platforms.txt

---
 basis/windows/ddk/hid/platforms.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 basis/windows/ddk/hid/platforms.txt

diff --git a/basis/windows/ddk/hid/platforms.txt b/basis/windows/ddk/hid/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/ddk/hid/platforms.txt
@@ -0,0 +1 @@
+winnt

From 23a1f0ed8c11f8e7ddc0d4a71ca76c30744c1c10 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Tue, 23 Feb 2010 01:28:56 +1300
Subject: [PATCH 175/250] alien: some code cleanups and fixes

---
 basis/alien/c-types/c-types.factor     |  8 --------
 basis/alien/libraries/authors.txt      |  1 +
 basis/alien/libraries/libraries.factor | 15 ++++++++++++---
 basis/alien/parser/parser.factor       | 16 ++++++----------
 basis/stack-checker/alien/alien.factor |  2 +-
 5 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor
index c25f465600..fff49a4480 100644
--- a/basis/alien/c-types/c-types.factor
+++ b/basis/alien/c-types/c-types.factor
@@ -69,14 +69,6 @@ M: array resolve-pointer-type
     dup void? [ no-c-type ] when
     dup c-type-name? [ c-type ] when ;
 
-<PRIVATE
-
-: parse-array-type ( name -- dims c-type )
-    "[" split unclip
-    [ [ "]" ?tail drop string>number ] map ] dip ;
-
-PRIVATE>
-
 M: word c-type
     dup "c-type" word-prop resolve-typedef
     [ ] [ no-c-type ] ?if ;
diff --git a/basis/alien/libraries/authors.txt b/basis/alien/libraries/authors.txt
index 1901f27a24..580f882c8d 100644
--- a/basis/alien/libraries/authors.txt
+++ b/basis/alien/libraries/authors.txt
@@ -1 +1,2 @@
 Slava Pestov
+Joe Groff
diff --git a/basis/alien/libraries/libraries.factor b/basis/alien/libraries/libraries.factor
index 6f80900da0..47e34fe5ff 100644
--- a/basis/alien/libraries/libraries.factor
+++ b/basis/alien/libraries/libraries.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2009 Slava Pestov.
+! Copyright (C) 2009, 2010 Slava Pestov, Joe Groff.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors alien alien.strings assocs io.backend
 kernel namespaces destructors sequences system io.pathnames ;
@@ -9,10 +9,8 @@ IN: alien.libraries
 : dlsym ( name dll -- alien ) [ string>symbol ] dip (dlsym) ;
 
 SYMBOL: libraries
-SYMBOL: deploy-libraries
 
 libraries [ H{ } clone ] initialize
-deploy-libraries [ V{ } clone ] initialize
 
 TUPLE: library path abi dll ;
 
@@ -37,18 +35,29 @@ M: library dispose dll>> [ dispose ] when* ;
     [ 2drop remove-library ]
     [ <library> swap libraries get set-at ] 3bi ;
 
+: library-abi ( library -- abi )
+    library [ abi>> ] [ "cdecl" ] if* ;
+
+SYMBOL: deploy-libraries
+
+deploy-libraries [ V{ } clone ] initialize
+
 : deploy-library ( name -- )
     dup libraries get key?
     [ deploy-libraries get 2dup member? [ 2drop ] [ push ] if ]
     [ no-library ] if ;
 
 <PRIVATE
+
 HOOK: >deployed-library-path os ( path -- path' )
 
 M: windows >deployed-library-path
     file-name ;
+
 M: unix >deployed-library-path
     file-name "$ORIGIN" prepend-path ;
+
 M: macosx >deployed-library-path
     file-name "@executable_path/../Frameworks" prepend-path ;
+
 PRIVATE>
diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor
index dc0a1701f2..8385bfb97f 100644
--- a/basis/alien/parser/parser.factor
+++ b/basis/alien/parser/parser.factor
@@ -66,16 +66,16 @@ IN: alien.parser
         2 group [ first2 normalize-c-arg 2array ] map
         unzip [ "," ?tail drop ] map
     ]
-    [ dup "void" = [ drop { } ] [ 1array ] if ]
+    [ [ { } ] [ name>> 1array ] if-void ]
     bi* <effect> ;
 
 : function-quot ( return library function types -- quot )
     '[ _ _ _ _ alien-invoke ] ;
 
 :: make-function ( return library function parameters -- word quot effect )
-    return function normalize-c-arg :> ( return-c-type function )
+    return function normalize-c-arg :> ( return function )
     function create-in dup reset-generic
-    return-c-type library function
+    return library function
     parameters return parse-arglist [ function-quot ] dip ;
 
 : parse-arg-tokens ( -- tokens )
@@ -88,13 +88,10 @@ IN: alien.parser
     make-function define-declared ;
 
 : callback-quot ( return types abi -- quot )
-    [ [ ] 3curry dip alien-callback ] 3curry ;
+    '[ [ _ _ _ ] dip alien-callback ] ;
 
-: library-abi ( lib -- abi )
-    library [ abi>> ] [ "cdecl" ] if* ;
-
-:: make-callback-type ( lib return! type-name! parameters -- word quot effect )
-    return type-name normalize-c-arg type-name! return!
+:: make-callback-type ( lib return type-name parameters -- word quot effect )
+    return type-name normalize-c-arg :> ( return type-name )
     type-name current-vocab create :> type-word 
     type-word [ reset-generic ] [ reset-c-type ] bi
     void* type-word typedef
@@ -115,4 +112,3 @@ PREDICATE: alien-function-word < word
 
 PREDICATE: alien-callback-type-word < typedef-word
     "callback-effect" word-prop ;
-
diff --git a/basis/stack-checker/alien/alien.factor b/basis/stack-checker/alien/alien.factor
index 09121488ef..81d8a93240 100644
--- a/basis/stack-checker/alien/alien.factor
+++ b/basis/stack-checker/alien/alien.factor
@@ -59,7 +59,7 @@ TUPLE: alien-callback-params < alien-node-params quot xt ;
     pop-library
     pop-return
     ! Set ABI
-    dup library>> library [ abi>> ] [ "cdecl" ] if* >>abi
+    dup library>> library-abi >>abi
     ! Quotation which coerces parameters to required types
     dup infer-params
     ! Magic #: consume exactly the number of inputs

From a15c09b3968a5620bc59652a8cb535baa63534c7 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Mon, 22 Feb 2010 10:39:50 -0800
Subject: [PATCH 176/250] Add some additional error masks and codes

---
 basis/windows/errors/errors.factor | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/basis/windows/errors/errors.factor b/basis/windows/errors/errors.factor
index a7a41433f7..c5dedb090a 100644
--- a/basis/windows/errors/errors.factor
+++ b/basis/windows/errors/errors.factor
@@ -5,6 +5,12 @@ arrays literals windows.types specialized-arrays ;
 SPECIALIZED-ARRAY: TCHAR
 IN: windows.errors
 
+CONSTANT: APPLICATION_ERROR_MASK       HEX: 20000000
+CONSTANT: ERROR_SEVERITY_SUCCESS       HEX: 00000000
+CONSTANT: ERROR_SEVERITY_INFORMATIONAL HEX: 40000000
+CONSTANT: ERROR_SEVERITY_WARNING       HEX: 80000000
+CONSTANT: ERROR_SEVERITY_ERROR         HEX: C0000000
+
 CONSTANT: ERROR_SUCCESS                               0
 CONSTANT: ERROR_INVALID_FUNCTION                      1
 CONSTANT: ERROR_FILE_NOT_FOUND                        2

From 124982ce23478e1723ec40bb72f9e4213e0c414e Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Mon, 22 Feb 2010 00:45:54 -0800
Subject: [PATCH 177/250] Fix CALLBACK: effect return type also not a string.
 Added accompanying unit test.

---
 basis/alien/parser/parser-tests.factor | 9 +++++++--
 basis/alien/parser/parser.factor       | 6 +++---
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/basis/alien/parser/parser-tests.factor b/basis/alien/parser/parser-tests.factor
index 2fec2d9a4c..84eefe9df6 100644
--- a/basis/alien/parser/parser-tests.factor
+++ b/basis/alien/parser/parser-tests.factor
@@ -34,9 +34,14 @@ CONSTANT: eleven 11
 
 ] with-file-vocabs
 
-FUNCTION: void* alien-parser-effect-test ( int *arg1 float arg2 ) ;
+FUNCTION: void* alien-parser-function-effect-test ( int *arg1 float arg2 ) ;
 [ (( arg1 arg2 -- void* )) ] [
-    \ alien-parser-effect-test "declared-effect" word-prop
+    \ alien-parser-function-effect-test "declared-effect" word-prop
+] unit-test
+
+CALLBACK: void* alien-parser-callback-effect-test ( int *arg1 float arg2 ) ;
+[ (( arg1 arg2 -- void* )) ] [
+    \ alien-parser-callback-effect-test "callback-effect" word-prop
 ] unit-test
 
 ! Reported by mnestic
diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor
index dc0a1701f2..d073a4caac 100644
--- a/basis/alien/parser/parser.factor
+++ b/basis/alien/parser/parser.factor
@@ -93,15 +93,15 @@ IN: alien.parser
 : library-abi ( lib -- abi )
     library [ abi>> ] [ "cdecl" ] if* ;
 
-:: make-callback-type ( lib return! type-name! parameters -- word quot effect )
-    return type-name normalize-c-arg type-name! return!
+:: make-callback-type ( lib return type-name parameters -- word quot effect )
+    return type-name normalize-c-arg :> ( return-c-type type-name )
     type-name current-vocab create :> type-word 
     type-word [ reset-generic ] [ reset-c-type ] bi
     void* type-word typedef
     parameters return parse-arglist :> ( types callback-effect )
     type-word callback-effect "callback-effect" set-word-prop
     type-word lib "callback-library" set-word-prop
-    type-word return types lib library-abi callback-quot (( quot -- alien )) ;
+    type-word return-c-type types lib library-abi callback-quot (( quot -- alien )) ;
 
 : (CALLBACK:) ( -- word quot effect )
     "c-library" get

From b2fe49704e26f7dd4ea41ce6cc2a09e23bd74e3b Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Mon, 22 Feb 2010 10:39:50 -0800
Subject: [PATCH 178/250] Add some additional error masks and codes

---
 basis/windows/errors/errors.factor | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/basis/windows/errors/errors.factor b/basis/windows/errors/errors.factor
index a7a41433f7..c5dedb090a 100644
--- a/basis/windows/errors/errors.factor
+++ b/basis/windows/errors/errors.factor
@@ -5,6 +5,12 @@ arrays literals windows.types specialized-arrays ;
 SPECIALIZED-ARRAY: TCHAR
 IN: windows.errors
 
+CONSTANT: APPLICATION_ERROR_MASK       HEX: 20000000
+CONSTANT: ERROR_SEVERITY_SUCCESS       HEX: 00000000
+CONSTANT: ERROR_SEVERITY_INFORMATIONAL HEX: 40000000
+CONSTANT: ERROR_SEVERITY_WARNING       HEX: 80000000
+CONSTANT: ERROR_SEVERITY_ERROR         HEX: C0000000
+
 CONSTANT: ERROR_SUCCESS                               0
 CONSTANT: ERROR_INVALID_FUNCTION                      1
 CONSTANT: ERROR_FILE_NOT_FOUND                        2

From 4d2ded634b081afc7e6f2d9a7f506f36678ec967 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 22 Feb 2010 11:25:01 -0800
Subject: [PATCH 179/250] alien.parser: properly generate return type name for
 FUNCTION: stack effects

---
 basis/alien/parser/parser.factor | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor
index 474bb77dc6..14078f3137 100644
--- a/basis/alien/parser/parser.factor
+++ b/basis/alien/parser/parser.factor
@@ -62,12 +62,20 @@ IN: alien.parser
     ] bi
     [ parse-c-type ] dip ;
 
+<PRIVATE
+GENERIC: return-type-name ( type -- name )
+
+M: object return-type-name drop "void" ;
+M: word return-type-name name>> ;
+M: pointer return-type-name to>> return-type-name CHAR: * suffix ;
+PRIVATE>
+
 : parse-arglist ( parameters return -- types effect )
     [
         2 group [ first2 normalize-c-arg 2array ] map
         unzip [ "," ?tail drop ] map
     ]
-    [ [ { } ] [ name>> 1array ] if-void ]
+    [ [ { } ] [ return-type-name 1array ] if-void ]
     bi* <effect> ;
 
 : function-quot ( return library function types -- quot )

From 1bf37f01e57d531fe37076a6a666933535dc8468 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 22 Feb 2010 12:21:29 -0800
Subject: [PATCH 180/250] alien.arrays/classes.struct: ensure specialized array
 types for struct array slots get instantiated at parse time

---
 basis/alien/arrays/arrays.factor   | 5 +----
 basis/classes/struct/struct.factor | 1 +
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/basis/alien/arrays/arrays.factor b/basis/alien/arrays/arrays.factor
index 4fddba1de6..f9a47f256c 100644
--- a/basis/alien/arrays/arrays.factor
+++ b/basis/alien/arrays/arrays.factor
@@ -35,10 +35,7 @@ M: array box-return drop void* box-return ;
 M: array stack-size drop void* stack-size ;
 
 M: array c-type-boxer-quot
-    unclip
-    [ array-length ]
-    [ [ require-c-array ] keep ] bi*
-    [ <c-direct-array> ] 2curry ;
+    unclip [ array-length ] dip [ <c-direct-array> ] 2curry ;
 
 M: array c-type-unboxer-quot drop [ >c-ptr ] ;
 
diff --git a/basis/classes/struct/struct.factor b/basis/classes/struct/struct.factor
index af73be3aa4..3b2fc875c4 100644
--- a/basis/classes/struct/struct.factor
+++ b/basis/classes/struct/struct.factor
@@ -147,6 +147,7 @@ M: struct-class initial-value* <struct> ; inline
 GENERIC: struct-slot-values ( struct -- sequence )
 
 M: struct-class reader-quot
+    dup array? [ dup first define-array-vocab drop ] when
     nip '[ _ read-struct-slot ] ;
 
 M: struct-class writer-quot

From 6d4724a095fc81b30fdb3661d9fd24b07058df01 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 22 Feb 2010 12:22:29 -0800
Subject: [PATCH 181/250] scrub memory>struct calls made redundant

---
 basis/calendar/unix/unix.factor                    | 2 +-
 basis/game/input/dinput/dinput.factor              | 3 +--
 basis/specialized-arrays/specialized-arrays.factor | 3 ---
 basis/ui/backend/x11/x11.factor                    | 3 +--
 basis/unix/groups/groups.factor                    | 2 +-
 basis/unix/users/users.factor                      | 6 +++---
 basis/unix/utmpx/utmpx.factor                      | 2 +-
 basis/windows/com/wrapper/wrapper.factor           | 3 +--
 basis/windows/uniscribe/uniscribe.factor           | 1 -
 9 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/basis/calendar/unix/unix.factor b/basis/calendar/unix/unix.factor
index ac72385d8c..fdc85c943a 100644
--- a/basis/calendar/unix/unix.factor
+++ b/basis/calendar/unix/unix.factor
@@ -21,7 +21,7 @@ IN: calendar.unix
     timespec>seconds since-1970 ;
 
 : get-time ( -- alien )
-    f time <time_t> localtime tm memory>struct ;
+    f time <time_t> localtime ;
 
 : timezone-name ( -- string )
     get-time zone>> ;
diff --git a/basis/game/input/dinput/dinput.factor b/basis/game/input/dinput/dinput.factor
index e2c1fda759..a95dbd06c3 100755
--- a/basis/game/input/dinput/dinput.factor
+++ b/basis/game/input/dinput/dinput.factor
@@ -94,7 +94,6 @@ SYMBOLS: +dinput+ +keyboard-device+ +keyboard-state+
 
 : find-device-axes-callback ( -- alien )
     [ ! ( lpddoi pvRef -- BOOL )
-        [ DIDEVICEOBJECTINSTANCEW memory>struct ] dip
         +controller-devices+ get at
         swap guidType>> {
             { [ dup GUID_XAxis = ] [ drop 0.0 >>x ] }
@@ -142,7 +141,7 @@ SYMBOLS: +dinput+ +keyboard-device+ +keyboard-state+
 
 : find-controller-callback ( -- alien )
     [ ! ( lpddi pvRef -- BOOL )
-        drop DIDEVICEINSTANCEW memory>struct guidInstance>> add-controller
+        drop guidInstance>> add-controller
         DIENUM_CONTINUE
     ] LPDIENUMDEVICESCALLBACKW ; inline
 
diff --git a/basis/specialized-arrays/specialized-arrays.factor b/basis/specialized-arrays/specialized-arrays.factor
index 97ce2ed1ff..2aca62cc77 100644
--- a/basis/specialized-arrays/specialized-arrays.factor
+++ b/basis/specialized-arrays/specialized-arrays.factor
@@ -143,9 +143,6 @@ PRIVATE>
     [ specialized-array-vocab ] [ '[ _ define-array ] ] bi
     generate-vocab ;
 
-M: c-type-word require-c-array define-array-vocab drop ;
-M: pointer require-c-array drop void* require-c-array ;
-
 ERROR: specialized-array-vocab-not-loaded c-type ;
 
 M: c-type-word c-array-constructor
diff --git a/basis/ui/backend/x11/x11.factor b/basis/ui/backend/x11/x11.factor
index 673dd8e9c3..74d911ef90 100644
--- a/basis/ui/backend/x11/x11.factor
+++ b/basis/ui/backend/x11/x11.factor
@@ -49,8 +49,7 @@ PIXEL-FORMAT-ATTRIBUTE-TABLE: glx-visual { $ GLX_USE_GL $ GLX_RGBA } H{
 
 M: x11-ui-backend (make-pixel-format)
     [ drop dpy get scr get ] dip
-    >glx-visual-int-array glXChooseVisual
-    XVisualInfo memory>struct ;
+    >glx-visual-int-array glXChooseVisual ;
 
 M: x11-ui-backend (free-pixel-format)
     handle>> XFree ;
diff --git a/basis/unix/groups/groups.factor b/basis/unix/groups/groups.factor
index b009fe529f..7be124ced4 100644
--- a/basis/unix/groups/groups.factor
+++ b/basis/unix/groups/groups.factor
@@ -83,7 +83,7 @@ M: integer user-groups ( id -- seq )
     user-name (user-groups) ;
     
 : all-groups ( -- seq )
-    [ unix.ffi:getgrent dup ] [ \ unix.ffi:group memory>struct group-struct>group ] produce nip ;
+    [ unix.ffi:getgrent dup ] [ group-struct>group ] produce nip ;
 
 : <group-cache> ( -- assoc )
     all-groups [ [ id>> ] keep ] H{ } map>assoc ;
diff --git a/basis/unix/users/users.factor b/basis/unix/users/users.factor
index 5de176e242..0575538b87 100644
--- a/basis/unix/users/users.factor
+++ b/basis/unix/users/users.factor
@@ -37,7 +37,7 @@ PRIVATE>
 
 : all-users ( -- seq )
     [
-        [ unix.ffi:getpwent dup ] [ unix.ffi:passwd memory>struct passwd>new-passwd ] produce nip
+        [ unix.ffi:getpwent dup ] [ passwd>new-passwd ] produce nip
     ] with-pwent ;
 
 SYMBOL: user-cache
@@ -52,10 +52,10 @@ GENERIC: user-passwd ( obj -- passwd/f )
 
 M: integer user-passwd ( id -- passwd/f )
     user-cache get
-    [ at ] [ unix.ffi:getpwuid [ unix.ffi:passwd memory>struct passwd>new-passwd ] [ f ] if* ] if* ;
+    [ at ] [ unix.ffi:getpwuid [ passwd>new-passwd ] [ f ] if* ] if* ;
 
 M: string user-passwd ( string -- passwd/f )
-    unix.ffi:getpwnam dup [ unix.ffi:passwd memory>struct passwd>new-passwd ] when ;
+    unix.ffi:getpwnam dup [ passwd>new-passwd ] when ;
 
 : user-name ( id -- string )
     dup user-passwd
diff --git a/basis/unix/utmpx/utmpx.factor b/basis/unix/utmpx/utmpx.factor
index 78556ab225..1d6dfdedec 100644
--- a/basis/unix/utmpx/utmpx.factor
+++ b/basis/unix/utmpx/utmpx.factor
@@ -41,7 +41,7 @@ M: unix new-utmpx-record
     utmpx-record new ;
     
 M: unix utmpx>utmpx-record ( utmpx -- utmpx-record )
-    [ new-utmpx-record ] dip \ utmpx memory>struct
+    [ new-utmpx-record ] dip
     {
         [ ut_user>> _UTX_USERSIZE memory>string >>user ]
         [ ut_id>>   _UTX_IDSIZE memory>string >>id ]
diff --git a/basis/windows/com/wrapper/wrapper.factor b/basis/windows/com/wrapper/wrapper.factor
index 696902439c..623a9c8db3 100644
--- a/basis/windows/com/wrapper/wrapper.factor
+++ b/basis/windows/com/wrapper/wrapper.factor
@@ -49,8 +49,7 @@ unless
 : (make-query-interface) ( interfaces -- quot )
     (query-interface-cases) 
     '[
-        swap GUID memory>struct
-        _ case
+        swap _ case
         [
             void* heap-size * rot <displaced-alien> com-add-ref
             swap 0 set-alien-cell S_OK
diff --git a/basis/windows/uniscribe/uniscribe.factor b/basis/windows/uniscribe/uniscribe.factor
index 87540dc24f..2783840df0 100644
--- a/basis/windows/uniscribe/uniscribe.factor
+++ b/basis/windows/uniscribe/uniscribe.factor
@@ -82,7 +82,6 @@ TUPLE: script-string < disposable font string metrics ssa size image ;
 : script-string-size ( script-string -- dim )
     ssa>> ScriptString_pSize
     dup win32-error=0/f
-    SIZE memory>struct
     [ cx>> ] [ cy>> ] bi 2array ;
 
 : dc-metrics ( dc -- metrics )

From 8628b6032738dd5612805db6c26f1e8273a47d26 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 22 Feb 2010 12:34:38 -0800
Subject: [PATCH 182/250] remove unnecessary memory>structs from extra/ too

---
 extra/chipmunk/chipmunk.factor  |  4 ++--
 extra/chipmunk/demo/demo.factor | 14 +++++++-------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/extra/chipmunk/chipmunk.factor b/extra/chipmunk/chipmunk.factor
index c56e15e12e..a7cd5e0fd2 100644
--- a/extra/chipmunk/chipmunk.factor
+++ b/extra/chipmunk/chipmunk.factor
@@ -512,9 +512,9 @@ FUNCTION: void cpArbiterIgnore ( cpArbiter* arb ) ;
 
 TYPED: cpArbiterGetShapes ( arb: cpArbiter -- a: cpShape b: cpShape )
     dup swappedColl>> 0 = [
-        [ a>> cpShape memory>struct ] [ b>> cpShape memory>struct ] bi
+        [ a>> ] [ b>> ] bi
     ] [
-        [ b>> cpShape memory>struct ] [ a>> cpShape memory>struct ] bi
+        [ b>> ] [ a>> ] bi
     ] if ; inline
 
 TYPED: cpArbiterIsFirstContact ( arb: cpArbiter -- ? )
diff --git a/extra/chipmunk/demo/demo.factor b/extra/chipmunk/demo/demo.factor
index 06f3c32dbe..38a8689bec 100644
--- a/extra/chipmunk/demo/demo.factor
+++ b/extra/chipmunk/demo/demo.factor
@@ -50,9 +50,9 @@ CONSTANT: image-bitmap B{
     x bitnot 7 bitand neg shift 1 bitand 1 = ;
 
 :: make-ball ( x y -- shape )
-    cpBodyAlloc 1.0 NAN: 0 cpBodyInit cpBody memory>struct
+    cpBodyAlloc 1.0 NAN: 0 cpBodyInit
     x y cpv >>p :> body
-    cpCircleShapeAlloc body 0.95 0 0 cpv cpCircleShapeInit cpCircleShape memory>struct
+    cpCircleShapeAlloc body 0.95 0 0 cpv cpCircleShapeInit
     [ shape>> 0 >>e ] [ shape>> 0 >>u ] bi drop ;
 
 TUPLE: chipmunk-world < game-world
@@ -76,7 +76,7 @@ M:: chipmunk-world draw-world* ( world -- )
     3 glPointSize
     0 0 0 glColor3f
     GL_POINTS glBegin
-    space bodies>> cpArray memory>struct
+    space bodies>>
     [ num>> ] [ arr>> swap <direct-void*-array> ] bi [
         cpBody memory>struct p>> [ x>> ] [ y>> ] bi glVertex2f
     ] each
@@ -85,7 +85,7 @@ M:: chipmunk-world draw-world* ( world -- )
     2 glPointSize
     1 0 0 glColor3f
     GL_POINTS glBegin
-    space arbiters>> cpArray memory>struct
+    space arbiters>>
     [ num>> ] [ arr>> swap <direct-void*-array> ] bi [
         cpArbiter memory>struct
         [ numContacts>> ] [ contacts>> swap <direct-cpContact-array> ] bi [
@@ -97,7 +97,7 @@ M:: chipmunk-world draw-world* ( world -- )
 M:: chipmunk-world begin-game-world ( world -- )
     cpInitChipmunk
 
-    cpSpaceAlloc cpSpaceInit cpSpace memory>struct :> space
+    cpSpaceAlloc cpSpaceInit :> space
 
     world space >>space drop
     space 2.0 10000 cpSpaceResizeActiveHash
@@ -115,11 +115,11 @@ M:: chipmunk-world begin-game-world ( world -- )
         ] each
     ] each
     
-    space cpBodyAlloc NAN: 0 dup cpBodyInit cpSpaceAddBody cpBody memory>struct :> body
+    space cpBodyAlloc NAN: 0 dup cpBodyInit cpSpaceAddBody :> body
     body -1000 -10 cpv >>p drop
     body 400 0 cpv >>v drop
 
-    space cpCircleShapeAlloc body 8 0 0 cpv cpCircleShapeInit cpSpaceAddShape cpCircleShape memory>struct :> shape
+    space cpCircleShapeAlloc body 8 0 0 cpv cpCircleShapeInit cpSpaceAddShape :> shape
     shape
     [ shape>> 0 >>e drop ]
     [ shape>> 0 >>u drop ] bi ;

From 949f658928c724e00df8634d5ecf776591abcb77 Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Mon, 22 Feb 2010 17:39:30 -0600
Subject: [PATCH 183/250] Fix a couple of typos in complex number docs

---
 core/math/math-docs.factor | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/core/math/math-docs.factor b/core/math/math-docs.factor
index 6357c8bd98..50a31434f4 100644
--- a/core/math/math-docs.factor
+++ b/core/math/math-docs.factor
@@ -385,14 +385,14 @@ HELP: prev-float
 HELP: real-part
 { $values { "z" number } { "x" real } }
 { $description "Outputs the real part of a complex number. This acts as the identity on real numbers." }
-{ $examples { $example "USING: math prettyprint ; C{ 1 2 } real-part ." "1" } } ;
+{ $examples { $example "USING: math prettyprint ;" "C{ 1 2 } real-part ." "1" } } ;
 
 HELP: imaginary-part
 { $values { "z" number } { "y" real } }
 { $description "Outputs the imaginary part of a complex number. This outputs zero for real numbers." }
 { $examples
-    { $example "USING: math prettyprint ; C{ 1 2 } imaginary-part ." "2" }
-    { $example "USING: math prettyprint ; 3 imaginary-part ." "0" }
+    { $example "USING: math prettyprint ;" "C{ 1 2 } imaginary-part ." "2" }
+    { $example "USING: math prettyprint ;" "3 imaginary-part ." "0" }
 } ;
 
 HELP: real

From 829351f2f28f61ec1d5ec10ba93025401b38a8ca Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 22 Feb 2010 19:08:43 -0800
Subject: [PATCH 184/250] don't box struct pointer values when they're null

---
 basis/alien/c-types/c-types-tests.factor | 2 --
 basis/alien/c-types/c-types.factor       | 2 +-
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/basis/alien/c-types/c-types-tests.factor b/basis/alien/c-types/c-types-tests.factor
index 13bdfa742a..ad53dc487b 100644
--- a/basis/alien/c-types/c-types-tests.factor
+++ b/basis/alien/c-types/c-types-tests.factor
@@ -24,8 +24,6 @@ UNION-STRUCT: foo
 
 [ t ] [ pointer: char c-type char* c-type = ] unit-test
 
-[ t ] [ pointer: foo c-type-boxer-quot foo c-type-boxer-quot = ] unit-test
-
 [ t ] [ foo heap-size int heap-size = ] unit-test
 
 TYPEDEF: int MyInt
diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor
index a9392b03d7..316377dc27 100644
--- a/basis/alien/c-types/c-types.factor
+++ b/basis/alien/c-types/c-types.factor
@@ -288,7 +288,7 @@ CONSTANT: primitive-types
     }
 
 : (pointer-c-type) ( void* type -- void*' )
-    [ clone ] dip c-type-boxer-quot >>boxer-quot ;
+    [ clone ] dip c-type-boxer-quot '[ _ [ f ] if* ] >>boxer-quot ;
 
 <PRIVATE
 

From 7844cbafab5d432543ddf02a74f1a531a5374a9b Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 22 Feb 2010 19:09:03 -0800
Subject: [PATCH 185/250] missed a dead memory>struct in io.sockets

---
 basis/io/sockets/sockets.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/io/sockets/sockets.factor b/basis/io/sockets/sockets.factor
index 59d12f95bc..a1260e80be 100644
--- a/basis/io/sockets/sockets.factor
+++ b/basis/io/sockets/sockets.factor
@@ -241,7 +241,7 @@ HOOK: (send) io-backend ( packet addrspec datagram -- )
     parse-sockaddr ;
 
 : parse-addrinfo-list ( addrinfo -- seq )
-    [ next>> dup [ addrinfo memory>struct ] when ] follow
+    [ next>> ] follow
     [ addrinfo>addrspec ] map
     sift ;
 

From aead6e7dd879b2458e84f282fba61d6b70727ca1 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Mon, 22 Feb 2010 19:34:34 -0800
Subject: [PATCH 186/250] Revert change to make-callback-type cause Slava
 already fixed it in parse-arglist

---
 basis/alien/parser/parser.factor | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor
index 8d850c47ee..8385bfb97f 100644
--- a/basis/alien/parser/parser.factor
+++ b/basis/alien/parser/parser.factor
@@ -91,14 +91,14 @@ IN: alien.parser
     '[ [ _ _ _ ] dip alien-callback ] ;
 
 :: make-callback-type ( lib return type-name parameters -- word quot effect )
-    return type-name normalize-c-arg :> ( return-c-type type-name )
+    return type-name normalize-c-arg :> ( return type-name )
     type-name current-vocab create :> type-word 
     type-word [ reset-generic ] [ reset-c-type ] bi
     void* type-word typedef
     parameters return parse-arglist :> ( types callback-effect )
     type-word callback-effect "callback-effect" set-word-prop
     type-word lib "callback-library" set-word-prop
-    type-word return-c-type types lib library-abi callback-quot (( quot -- alien )) ;
+    type-word return types lib library-abi callback-quot (( quot -- alien )) ;
 
 : (CALLBACK:) ( -- word quot effect )
     "c-library" get

From 4f8a6a032ca1f9fa551f970d4e30056506a49cce Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Mon, 22 Feb 2010 19:34:54 -0800
Subject: [PATCH 187/250] Syntax highlighting for COM-INTERFACE:

---
 misc/fuel/fuel-syntax.el | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/misc/fuel/fuel-syntax.el b/misc/fuel/fuel-syntax.el
index 7de627f8f5..67a8ee89e0 100644
--- a/misc/fuel/fuel-syntax.el
+++ b/misc/fuel/fuel-syntax.el
@@ -46,7 +46,7 @@
   '(":" "::" ";" "&:" "<<" "<PRIVATE" ">>"
     "ABOUT:" "ALIAS:" "ALIEN:" "ARTICLE:"
     "B" "BIN:"
-    "C:" "CALLBACK:" "C-ENUM:" "C-STRUCT:" "C-TYPE:" "C-UNION:" "CHAR:" "CONSTANT:" "call-next-method"
+    "C:" "CALLBACK:" "C-ENUM:" "C-STRUCT:" "C-TYPE:" "C-UNION:" "CHAR:" "COM-INTERFACE:" "CONSTANT:" "call-next-method"
     "DEFER:"
     "EBNF:" ";EBNF" "ERROR:" "EXCLUDE:"
     "f" "FORGET:" "FROM:" "FUNCTION:"
@@ -125,7 +125,7 @@
 
 (defconst fuel-syntax--type-definition-regex
   (fuel-syntax--second-word-regex
-   '("C-STRUCT:" "C-UNION:" "MIXIN:" "TUPLE:" "SINGLETON:" "SPECIALIZED-ARRAY:" "STRUCT:" "UNION:" "UNION-STRUCT:")))
+   '("C-STRUCT:" "C-UNION:" "COM-INTERFACE:" "MIXIN:" "TUPLE:" "SINGLETON:" "SPECIALIZED-ARRAY:" "STRUCT:" "UNION:" "UNION-STRUCT:")))
 
 (defconst fuel-syntax--tuple-decl-regex
   "^TUPLE: +\\([^ \n]+\\) +< +\\([^ \n]+\\)\\_>")
@@ -156,7 +156,7 @@
   "\\_<CALLBACK: \\(\\w+\\) \\(\\w+\\)")
 
 (defconst fuel-syntax--indent-def-starts '("" ":"
-                                           "C-ENUM" "C-STRUCT" "C-UNION"
+                                           "C-ENUM" "C-STRUCT" "C-UNION" "COM-INTERFACE"
                                            "FROM" "FUNCTION:"
                                            "INTERSECTION:"
                                            "M" "M:" "MACRO" "MACRO:"

From 21ab2ef6e789c7602ec15e2b1b92bc82b983b1eb Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 22 Feb 2010 19:35:52 -0800
Subject: [PATCH 188/250] repeated runs of classes.tuple test would fail
 because partially defined classes.tuple.tests:bad-superclass type would
 shadow classes.tuple:bad-superclass

---
 core/classes/tuple/tuple-tests.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/classes/tuple/tuple-tests.factor b/core/classes/tuple/tuple-tests.factor
index 276c6b407c..1609c1eeca 100644
--- a/core/classes/tuple/tuple-tests.factor
+++ b/core/classes/tuple/tuple-tests.factor
@@ -267,7 +267,7 @@ test-server-slot-values
 ] unit-test
 
 [
-    "IN: classes.tuple.tests TUPLE: bad-superclass < word ;" eval( -- )
+    "IN: classes.tuple.tests TUPLE: invalid-superclass < word ;" eval( -- )
 ] must-fail
 
 ! Dynamically changing inheritance hierarchy

From 33f1a7b03b674993b0c81d55a8e3bfdbfcfdcb16 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 22 Feb 2010 19:36:14 -0800
Subject: [PATCH 189/250] db.sqlite.ffi: replace some TYPEDEF: void* foo* with
 C-TYPE: foo

---
 basis/db/sqlite/ffi/ffi.factor | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/basis/db/sqlite/ffi/ffi.factor b/basis/db/sqlite/ffi/ffi.factor
index c180df9bf5..53562fd87e 100644
--- a/basis/db/sqlite/ffi/ffi.factor
+++ b/basis/db/sqlite/ffi/ffi.factor
@@ -99,8 +99,8 @@ CONSTANT: SQLITE_OPEN_TEMP_JOURNAL     HEX: 00001000
 CONSTANT: SQLITE_OPEN_SUBJOURNAL       HEX: 00002000
 CONSTANT: SQLITE_OPEN_MASTER_JOURNAL   HEX: 00004000
 
-TYPEDEF: void* sqlite3*
-TYPEDEF: void* sqlite3_stmt*
+C-TYPE: sqlite3
+C-TYPE: sqlite3_stmt
 TYPEDEF: longlong sqlite3_int64
 TYPEDEF: ulonglong sqlite3_uint64
 
@@ -121,7 +121,7 @@ FUNCTION: int sqlite3_bind_int64 ( sqlite3_stmt* pStmt, int index, sqlite3_int64
 ! Bind the same function as above, but for unsigned 64bit integers
 : sqlite3-bind-uint64 ( pStmt index in64 -- int )
     int "sqlite" "sqlite3_bind_int64"
-    { sqlite3_stmt* int sqlite3_uint64 } alien-invoke ;
+    { pointer: sqlite3_stmt int sqlite3_uint64 } alien-invoke ;
 FUNCTION: int sqlite3_bind_null ( sqlite3_stmt* pStmt, int n ) ;
 FUNCTION: int sqlite3_bind_text ( sqlite3_stmt* pStmt, int index, char* text, int len, int destructor ) ;
 FUNCTION: int sqlite3_bind_parameter_index ( sqlite3_stmt* pStmt, char* name ) ;
@@ -135,7 +135,7 @@ FUNCTION: sqlite3_int64 sqlite3_column_int64 ( sqlite3_stmt* pStmt, int col ) ;
 ! Bind the same function as above, but for unsigned 64bit integers
 : sqlite3-column-uint64 ( pStmt col -- uint64 )
     sqlite3_uint64 "sqlite" "sqlite3_column_int64"
-    { sqlite3_stmt* int } alien-invoke ;
+    { pointer: sqlite3_stmt int } alien-invoke ;
 FUNCTION: double sqlite3_column_double ( 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 ) ;

From 0142d46688d7846b702aeae6a8d82ee045d60b2f Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Mon, 22 Feb 2010 20:17:49 -0800
Subject: [PATCH 190/250] Add scaffolding for platforms.txt, add option to
 fuel-scaffold-vocab

---
 basis/tools/scaffold/scaffold.factor |  3 +++
 extra/fuel/fuel.factor               |  4 ++++
 misc/fuel/fuel-scaffold.el           | 19 +++++++++++++++++++
 3 files changed, 26 insertions(+)

diff --git a/basis/tools/scaffold/scaffold.factor b/basis/tools/scaffold/scaffold.factor
index fee37496c8..9e1d08e352 100644
--- a/basis/tools/scaffold/scaffold.factor
+++ b/basis/tools/scaffold/scaffold.factor
@@ -267,6 +267,9 @@ PRIVATE>
 : scaffold-summary ( vocab summary -- )
     [ "summary.txt" ] dip scaffold-metadata ;
 
+: scaffold-platforms ( vocab platforms -- )
+    [ "platforms.txt" ] dip scaffold-metadata ;
+
 : scaffold-vocab ( vocab-root string -- )
     {
         [ scaffold-directory ]
diff --git a/extra/fuel/fuel.factor b/extra/fuel/fuel.factor
index 2934d5d43c..9d47bf8cc4 100644
--- a/extra/fuel/fuel.factor
+++ b/extra/fuel/fuel.factor
@@ -162,6 +162,10 @@ PRIVATE>
     [ scaffold-summary ]
     [ drop [ vocab-summary-path ] keep swap vocab-append-path absolute-path fuel-eval-set-result ] 2bi ;
 
+: fuel-scaffold-platforms ( name platforms -- )
+    [ scaffold-platforms ]
+    [ drop [ vocab-platforms-path ] keep swap vocab-append-path absolute-path fuel-eval-set-result ] 2bi ;
+
 : fuel-scaffold-get-root ( name -- ) find-vocab-root fuel-eval-set-result ;
 
 ! Remote connection
diff --git a/misc/fuel/fuel-scaffold.el b/misc/fuel/fuel-scaffold.el
index dc2a09713d..0078300fd1 100644
--- a/misc/fuel/fuel-scaffold.el
+++ b/misc/fuel/fuel-scaffold.el
@@ -96,6 +96,10 @@ IN: %s
   (let ((cmd `(:fuel* (,vocab ,summary fuel-scaffold-summary) "fuel")))
     (fuel-eval--send/wait cmd)))
 
+(defsubst fuel-scaffold--create-platforms (vocab platforms)
+  (let ((cmd `(:fuel* (,vocab ,platforms fuel-scaffold-platforms) "fuel")))
+    (fuel-eval--send/wait cmd)))
+
 (defun fuel-scaffold--help (parent)
   (when (and parent (fuel-scaffold--check-auto fuel-scaffold-help-autoinsert-p))
     (let* ((ret (fuel-scaffold--create-docs (fuel-scaffold--vocab parent)))
@@ -131,6 +135,7 @@ You can configure `fuel-scaffold-developer-name' (set by default to
                                 nil t (or root-hint "resource:")))
          (summary (read-string "Vocab summary (empty for none): "))
          (tags (read-string "Vocab tags (empty for none): "))
+         (platforms (read-string "Vocab platforms (empty for all): "))
          (help (y-or-n-p "Scaffold help? "))
          (tests (y-or-n-p "Scaffold tests? "))
          (cmd `(:fuel* ((,root ,name ,fuel-scaffold-developer-name)
@@ -143,6 +148,8 @@ You can configure `fuel-scaffold-developer-name' (set by default to
       (fuel-scaffold--create-summary name summary))
     (when (not (equal "" tags))
       (fuel-scaffold--create-tags name tags))
+    (when (not (equal "" platforms))
+      (fuel-scaffold--create-platforms name platforms))
     (when help
          (fuel-scaffold--create-docs name))
     (when tests
@@ -221,6 +228,18 @@ You can configure `fuel-scaffold-developer-name' (set by default to
           (error "Error creating summary file" (car (fuel-eval--retort-error ret))))
         (find-file file)))
 
+(defun fuel-scaffold-platforms (&optional arg)
+  "Creates, if it does not already exist, a platforms file for the current vocabulary."
+  (interactive "P")
+  (let* ((vocab (or (and (not arg ) (fuel-syntax--current-vocab))
+                    (fuel-completion--read-vocab nil)))
+         (platforms (read-string "Platforms: "))
+         (ret (fuel-scaffold--create-platforms vocab platforms))
+         (file (fuel-eval--retort-result ret)))
+        (unless file
+          (error "Error creating platforms file" (car (fuel-eval--retort-error ret))))
+        (find-file file)))
+
 
 (provide 'fuel-scaffold)
 ;;; fuel-scaffold.el ends here

From ea2fcd2aedac8b26a7a5587aa082054db118fbd2 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Mon, 22 Feb 2010 20:18:15 -0800
Subject: [PATCH 191/250] Fix new compile errors in d3d bindings

---
 .../windows/directx/d3d10effect/d3d10effect.factor | 14 ++++++++++++++
 .../windows/directx/d3d11shader/d3d11shader.factor |  3 +++
 2 files changed, 17 insertions(+)

diff --git a/basis/windows/directx/d3d10effect/d3d10effect.factor b/basis/windows/directx/d3d10effect/d3d10effect.factor
index 5b4fbb4ca5..1d809b3862 100644
--- a/basis/windows/directx/d3d10effect/d3d10effect.factor
+++ b/basis/windows/directx/d3d10effect/d3d10effect.factor
@@ -113,6 +113,20 @@ STRUCT: D3D10_EFFECT_VARIABLE_DESC
     { BufferOffset         UINT   }
     { ExplicitBindPoint    UINT   } ;
 
+C-TYPE: ID3D10EffectConstantBuffer
+C-TYPE: ID3D10EffectScalarVariable
+C-TYPE: ID3D10EffectVectorVariable
+C-TYPE: ID3D10EffectMatrixVariable
+C-TYPE: ID3D10EffectStringVariable
+C-TYPE: ID3D10EffectShaderResourceVariable
+C-TYPE: ID3D10EffectRenderTargetViewVariable
+C-TYPE: ID3D10EffectDepthStencilViewVariable
+C-TYPE: ID3D10EffectShaderVariable
+C-TYPE: ID3D10EffectBlendVariable
+C-TYPE: ID3D10EffectDepthStencilVariable
+C-TYPE: ID3D10EffectRasterizerVariable
+C-TYPE: ID3D10EffectSamplerVariable
+
 COM-INTERFACE: ID3D10EffectVariable f {AE897105-00E6-45bf-BB8E-281DD6DB8E1B}
     BOOL IsValid ( )
     ID3D10EffectType* GetType ( )
diff --git a/basis/windows/directx/d3d11shader/d3d11shader.factor b/basis/windows/directx/d3d11shader/d3d11shader.factor
index a0437e3e65..02ab9bb177 100644
--- a/basis/windows/directx/d3d11shader/d3d11shader.factor
+++ b/basis/windows/directx/d3d11shader/d3d11shader.factor
@@ -152,6 +152,9 @@ COM-INTERFACE: ID3D11ShaderReflectionType f {6E6FFA6A-9BAE-4613-A51E-91652D508C2
     HRESULT IsOfType ( ID3D11ShaderReflectionType* pType )
     HRESULT ImplementsInterface ( ID3D11ShaderReflectionType* pBase ) ;
 
+C-TYPE: ID3D11ShaderReflectionType
+C-TYPE: ID3D11ShaderReflectionConstantBuffer
+
 COM-INTERFACE: ID3D11ShaderReflectionVariable f {51F23923-F3E5-4BD1-91CB-606177D8DB4C}
     HRESULT GetDesc ( D3D11_SHADER_VARIABLE_DESC* pDesc )
     ID3D11ShaderReflectionType* GetType ( )

From e513151e1d93f1c90132146ecfb4916b20b27a73 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Mon, 22 Feb 2010 20:19:04 -0800
Subject: [PATCH 192/250] Summary and tags file for windows.ddk.hid

---
 basis/windows/ddk/hid/summary.txt | 1 +
 basis/windows/ddk/hid/tags.txt    | 1 +
 2 files changed, 2 insertions(+)
 create mode 100644 basis/windows/ddk/hid/summary.txt
 create mode 100644 basis/windows/ddk/hid/tags.txt

diff --git a/basis/windows/ddk/hid/summary.txt b/basis/windows/ddk/hid/summary.txt
new file mode 100644
index 0000000000..71ad299177
--- /dev/null
+++ b/basis/windows/ddk/hid/summary.txt
@@ -0,0 +1 @@
+Bindings to the HID section of the Windows DDK
\ No newline at end of file
diff --git a/basis/windows/ddk/hid/tags.txt b/basis/windows/ddk/hid/tags.txt
new file mode 100644
index 0000000000..fdce1614de
--- /dev/null
+++ b/basis/windows/ddk/hid/tags.txt
@@ -0,0 +1 @@
+unportable bindings
\ No newline at end of file

From 234fa6e20d0471b955a49e6262c0052cb7b325eb Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Mon, 22 Feb 2010 20:37:06 -0800
Subject: [PATCH 193/250] Windows DDK SetupAPI bindings -- used for hardware
 device discovery

---
 basis/windows/ddk/setupapi/authors.txt     |    1 +
 basis/windows/ddk/setupapi/platforms.txt   |    1 +
 basis/windows/ddk/setupapi/setupapi.factor | 2033 ++++++++++++++++++++
 basis/windows/ddk/setupapi/summary.txt     |    1 +
 basis/windows/ddk/setupapi/tags.txt        |    1 +
 5 files changed, 2037 insertions(+)
 create mode 100644 basis/windows/ddk/setupapi/authors.txt
 create mode 100644 basis/windows/ddk/setupapi/platforms.txt
 create mode 100644 basis/windows/ddk/setupapi/setupapi.factor
 create mode 100644 basis/windows/ddk/setupapi/summary.txt
 create mode 100644 basis/windows/ddk/setupapi/tags.txt

diff --git a/basis/windows/ddk/setupapi/authors.txt b/basis/windows/ddk/setupapi/authors.txt
new file mode 100644
index 0000000000..f596342efa
--- /dev/null
+++ b/basis/windows/ddk/setupapi/authors.txt
@@ -0,0 +1 @@
+Erik Charlebois
diff --git a/basis/windows/ddk/setupapi/platforms.txt b/basis/windows/ddk/setupapi/platforms.txt
new file mode 100644
index 0000000000..d2e9c5bf45
--- /dev/null
+++ b/basis/windows/ddk/setupapi/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/ddk/setupapi/setupapi.factor b/basis/windows/ddk/setupapi/setupapi.factor
new file mode 100644
index 0000000000..06d32725f7
--- /dev/null
+++ b/basis/windows/ddk/setupapi/setupapi.factor
@@ -0,0 +1,2033 @@
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: literals windows.kernel32 math alien.syntax windows.types classes.struct
+alien.c-types windows.errors windows.ole32 windows.advapi32 alien.libraries ;
+IN: windows.ddk.setupapi
+
+<< "setupapi" "setupapi.dll" "stdcall" add-library >>
+LIBRARY: setupapi
+
+TYPEDEF: DWORDLONG SP_LOG_TOKEN
+TYPEDEF: DWORDLONG* PSP_LOG_TOKEN
+
+CONSTANT: LOGTOKEN_TYPE_MASK              3
+CONSTANT: LOGTOKEN_UNSPECIFIED            0
+CONSTANT: LOGTOKEN_NO_LOG                 1
+CONSTANT: LOGTOKEN_SETUPAPI_APPLOG        2
+CONSTANT: LOGTOKEN_SETUPAPI_DEVLOG        3
+
+CONSTANT: TXTLOG_SETUPAPI_DEVLOG      HEX: 00000001
+CONSTANT: TXTLOG_SETUPAPI_CMDLINE     HEX: 00000002
+CONSTANT: TXTLOG_SETUPAPI_BITS        HEX: 00000003
+
+CONSTANT: TXTLOG_ERROR                    HEX: 1
+CONSTANT: TXTLOG_WARNING                  HEX: 2
+CONSTANT: TXTLOG_SYSTEM_STATE_CHANGE      HEX: 3
+CONSTANT: TXTLOG_SUMMARY                  HEX: 4
+CONSTANT: TXTLOG_DETAILS                  HEX: 5
+CONSTANT: TXTLOG_VERBOSE                  HEX: 6
+CONSTANT: TXTLOG_VERY_VERBOSE             HEX: 7
+
+CONSTANT: TXTLOG_RESERVED_FLAGS   HEX: 0000FFF0
+
+CONSTANT: TXTLOG_TIMESTAMP        HEX: 00010000
+CONSTANT: TXTLOG_DEPTH_INCR       HEX: 00020000
+CONSTANT: TXTLOG_DEPTH_DECR       HEX: 00040000
+CONSTANT: TXTLOG_TAB_1            HEX: 00080000
+CONSTANT: TXTLOG_FLUSH_FILE       HEX: 00100000
+
+: TXTLOG_LEVEL ( flags -- n ) HEX: f bitand ; inline
+
+CONSTANT: TXTLOG_DEVINST          HEX: 00000001
+CONSTANT: TXTLOG_INF              HEX: 00000002
+CONSTANT: TXTLOG_FILEQ            HEX: 00000004
+CONSTANT: TXTLOG_COPYFILES        HEX: 00000008
+CONSTANT: TXTLOG_SIGVERIF         HEX: 00000020
+CONSTANT: TXTLOG_BACKUP           HEX: 00000080
+CONSTANT: TXTLOG_UI               HEX: 00000100
+CONSTANT: TXTLOG_UTIL             HEX: 00000200
+CONSTANT: TXTLOG_INFDB            HEX: 00000400
+CONSTANT: TXTLOG_POLICY           HEX: 00800000
+CONSTANT: TXTLOG_NEWDEV           HEX: 01000000
+CONSTANT: TXTLOG_UMPNPMGR         HEX: 02000000
+CONSTANT: TXTLOG_DRIVER_STORE     HEX: 04000000
+CONSTANT: TXTLOG_SETUP            HEX: 08000000
+CONSTANT: TXTLOG_CMI              HEX: 10000000
+CONSTANT: TXTLOG_DEVMGR           HEX: 20000000
+CONSTANT: TXTLOG_INSTALLER        HEX: 40000000
+CONSTANT: TXTLOG_VENDOR           HEX: 80000000
+
+TYPEDEF: void* HPROPSHEETPAGE
+TYPEDEF: void* HIMAGELIST
+C-TYPE: DEVPROPKEY
+TYPEDEF: ULONG DEVPROPTYPE
+TYPEDEF: DEVPROPTYPE* PDEVPROPTYPE
+TYPEDEF: void* LPPROPSHEETHEADERA
+TYPEDEF: void* LPPROPSHEETHEADERW
+
+CONSTANT: LINE_LEN                     256
+CONSTANT: LINE_LEN*2                   512
+CONSTANT: MAX_INF_STRING_LENGTH        4096
+CONSTANT: MAX_INF_SECTION_NAME_LENGTH  255
+CONSTANT: MAX_TITLE_LEN                60
+CONSTANT: MAX_INSTRUCTION_LEN          256
+CONSTANT: MAX_LABEL_LEN                30
+CONSTANT: MAX_SERVICE_NAME_LEN         256
+CONSTANT: MAX_SUBTITLE_LEN             256
+CONSTANT: SP_MAX_MACHINENAME_LENGTH    $[ MAX_PATH 3 + ]
+
+TYPEDEF: PVOID HINF
+
+STRUCT: INFCONTEXT
+    { Inf        PVOID }
+    { CurrentInf PVOID }
+    { Section    UINT  }
+    { Line       UINT  } ;
+TYPEDEF: INFCONTEXT* PINFCONTEXT
+
+STRUCT: SP_INF_INFORMATION
+    { InfStyle   DWORD               }
+    { InfCount   DWORD               }
+    { VersionDat BYTE[ANYSIZE_ARRAY] } ;
+TYPEDEF: SP_INF_INFORMATION* PSP_INF_INFORMATION
+
+STRUCT: SP_ALTPLATFORM_INFO_V2
+    { cbSize                     DWORD }
+    { Platform                   DWORD }
+    { MajorVersion               DWORD }
+    { MinorVersion               DWORD }
+    { ProcessorArchitecture      WORD  }
+    { Flags                      WORD  }
+    { FirstValidatedMajorVersion DWORD }
+    { FirstValidatedMinorVersion DWORD } ;
+TYPEDEF: SP_ALTPLATFORM_INFO_V2* PSP_ALTPLATFORM_INFO_V2
+
+STRUCT: SP_ALTPLATFORM_INFO_V1
+    { cbSize                 DWORD }
+    { Platform               DWORD }
+    { MajorVersion           DWORD }
+    { MinorVersion           DWORD }
+    { ProcessorArchitecture  WORD  }
+    { Reserved               WORD  } ;
+TYPEDEF: SP_ALTPLATFORM_INFO_V1* PSP_ALTPLATFORM_INFO_V1
+TYPEDEF: SP_ALTPLATFORM_INFO_V2 SP_ALTPLATFORM_INFO
+TYPEDEF: PSP_ALTPLATFORM_INFO_V2 PSP_ALTPLATFORM_INFO
+
+CONSTANT: SP_ALTPLATFORM_FLAGS_VERSION_RANGE 1
+
+STRUCT: SP_ORIGINAL_FILE_INFO_A
+    { cbSize              DWORD          }
+    { OriginalInfName     CHAR[MAX_PATH] }
+    { OriginalCatalogName CHAR[MAX_PATH] } ;
+TYPEDEF: SP_ORIGINAL_FILE_INFO_A* PSP_ORIGINAL_FILE_INFO_A
+STRUCT: SP_ORIGINAL_FILE_INFO_W
+    { cbSize              DWORD           }
+    { OriginalInfName     WCHAR[MAX_PATH] }
+    { OriginalCatalogName WCHAR[MAX_PATH] } ;
+TYPEDEF: SP_ORIGINAL_FILE_INFO_W* PSP_ORIGINAL_FILE_INFO_W
+TYPEDEF: SP_ORIGINAL_FILE_INFO_W SP_ORIGINAL_FILE_INFO
+TYPEDEF: PSP_ORIGINAL_FILE_INFO_W PSP_ORIGINAL_FILE_INFO
+
+CONSTANT: INF_STYLE_NONE           HEX: 00000000
+CONSTANT: INF_STYLE_OLDNT          HEX: 00000001
+CONSTANT: INF_STYLE_WIN4           HEX: 00000002
+CONSTANT: INF_STYLE_CACHE_ENABLE   HEX: 00000010
+CONSTANT: INF_STYLE_CACHE_DISABLE  HEX: 00000020
+CONSTANT: INF_STYLE_CACHE_IGNORE   HEX: 00000040
+CONSTANT: DIRID_ABSOLUTE          -1
+CONSTANT: DIRID_ABSOLUTE_16BIT     HEX: ffff
+CONSTANT: DIRID_NULL               0
+CONSTANT: DIRID_SRCPATH            1
+CONSTANT: DIRID_WINDOWS           10
+CONSTANT: DIRID_SYSTEM            11
+CONSTANT: DIRID_DRIVERS           12
+CONSTANT: DIRID_IOSUBSYS          $ DIRID_DRIVERS
+CONSTANT: DIRID_INF               17
+CONSTANT: DIRID_HELP              18
+CONSTANT: DIRID_FONTS             20
+CONSTANT: DIRID_VIEWERS           21
+CONSTANT: DIRID_COLOR             23
+CONSTANT: DIRID_APPS              24
+CONSTANT: DIRID_SHARED            25
+CONSTANT: DIRID_BOOT              30
+CONSTANT: DIRID_SYSTEM16          50
+CONSTANT: DIRID_SPOOL             51
+CONSTANT: DIRID_SPOOLDRIVERS      52
+CONSTANT: DIRID_USERPROFILE       53
+CONSTANT: DIRID_LOADER            54
+CONSTANT: DIRID_PRINTPROCESSOR    55
+CONSTANT: DIRID_DEFAULT           $ DIRID_SYSTEM
+CONSTANT: DIRID_COMMON_STARTMENU        16406
+CONSTANT: DIRID_COMMON_PROGRAMS         16407
+CONSTANT: DIRID_COMMON_STARTUP          16408
+CONSTANT: DIRID_COMMON_DESKTOPDIRECTORY 16409
+CONSTANT: DIRID_COMMON_FAVORITES        16415
+CONSTANT: DIRID_COMMON_APPDATA          16419
+CONSTANT: DIRID_PROGRAM_FILES           16422
+CONSTANT: DIRID_SYSTEM_X86              16425
+CONSTANT: DIRID_PROGRAM_FILES_X86       16426
+CONSTANT: DIRID_PROGRAM_FILES_COMMON    16427
+CONSTANT: DIRID_PROGRAM_FILES_COMMONX86 16428
+CONSTANT: DIRID_COMMON_TEMPLATES        16429
+CONSTANT: DIRID_COMMON_DOCUMENTS        16430
+CONSTANT: DIRID_USER              HEX: 8000
+CALLBACK: UINT PSP_FILE_CALLBACK_A ( PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2 ) ;
+CALLBACK: UINT PSP_FILE_CALLBACK_W ( PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2 ) ;
+TYPEDEF: PSP_FILE_CALLBACK_W PSP_FILE_CALLBACK
+CONSTANT: SPFILENOTIFY_STARTQUEUE         HEX: 00000001
+CONSTANT: SPFILENOTIFY_ENDQUEUE           HEX: 00000002
+CONSTANT: SPFILENOTIFY_STARTSUBQUEUE      HEX: 00000003
+CONSTANT: SPFILENOTIFY_ENDSUBQUEUE        HEX: 00000004
+CONSTANT: SPFILENOTIFY_STARTDELETE        HEX: 00000005
+CONSTANT: SPFILENOTIFY_ENDDELETE          HEX: 00000006
+CONSTANT: SPFILENOTIFY_DELETEERROR        HEX: 00000007
+CONSTANT: SPFILENOTIFY_STARTRENAME        HEX: 00000008
+CONSTANT: SPFILENOTIFY_ENDRENAME          HEX: 00000009
+CONSTANT: SPFILENOTIFY_RENAMEERROR        HEX: 0000000a
+CONSTANT: SPFILENOTIFY_STARTCOPY          HEX: 0000000b
+CONSTANT: SPFILENOTIFY_ENDCOPY            HEX: 0000000c
+CONSTANT: SPFILENOTIFY_COPYERROR          HEX: 0000000d
+CONSTANT: SPFILENOTIFY_NEEDMEDIA          HEX: 0000000e
+CONSTANT: SPFILENOTIFY_QUEUESCAN          HEX: 0000000f
+CONSTANT: SPFILENOTIFY_CABINETINFO        HEX: 00000010
+CONSTANT: SPFILENOTIFY_FILEINCABINET      HEX: 00000011
+CONSTANT: SPFILENOTIFY_NEEDNEWCABINET     HEX: 00000012
+CONSTANT: SPFILENOTIFY_FILEEXTRACTED      HEX: 00000013
+CONSTANT: SPFILENOTIFY_FILEOPDELAYED      HEX: 00000014
+CONSTANT: SPFILENOTIFY_STARTBACKUP        HEX: 00000015
+CONSTANT: SPFILENOTIFY_BACKUPERROR        HEX: 00000016
+CONSTANT: SPFILENOTIFY_ENDBACKUP          HEX: 00000017
+CONSTANT: SPFILENOTIFY_QUEUESCAN_EX       HEX: 00000018
+CONSTANT: SPFILENOTIFY_STARTREGISTRATION  HEX: 00000019
+CONSTANT: SPFILENOTIFY_ENDREGISTRATION    HEX: 00000020
+CONSTANT: SPFILENOTIFY_QUEUESCAN_SIGNERINFO HEX: 00000040
+CONSTANT: SPFILENOTIFY_LANGMISMATCH       HEX: 00010000
+CONSTANT: SPFILENOTIFY_TARGETEXISTS       HEX: 00020000
+CONSTANT: SPFILENOTIFY_TARGETNEWER        HEX: 00040000
+CONSTANT: FILEOP_COPY                     0
+CONSTANT: FILEOP_RENAME                   1
+CONSTANT: FILEOP_DELETE                   2
+CONSTANT: FILEOP_BACKUP                   3
+CONSTANT: FILEOP_ABORT                    0
+CONSTANT: FILEOP_DOIT                     1
+CONSTANT: FILEOP_SKIP                     2
+CONSTANT: FILEOP_RETRY                    $ FILEOP_DOIT
+CONSTANT: FILEOP_NEWPATH                  4
+CONSTANT: COPYFLG_WARN_IF_SKIP            HEX: 00000001
+CONSTANT: COPYFLG_NOSKIP                  HEX: 00000002
+CONSTANT: COPYFLG_NOVERSIONCHECK          HEX: 00000004
+CONSTANT: COPYFLG_FORCE_FILE_IN_USE       HEX: 00000008
+CONSTANT: COPYFLG_NO_OVERWRITE            HEX: 00000010
+CONSTANT: COPYFLG_NO_VERSION_DIALOG       HEX: 00000020
+CONSTANT: COPYFLG_OVERWRITE_OLDER_ONLY    HEX: 00000040
+CONSTANT: COPYFLG_PROTECTED_WINDOWS_DRIVER_FILE HEX: 00000100
+CONSTANT: COPYFLG_REPLACEONLY             HEX: 00000400
+CONSTANT: COPYFLG_NODECOMP                HEX: 00000800
+CONSTANT: COPYFLG_REPLACE_BOOT_FILE       HEX: 00001000
+CONSTANT: COPYFLG_NOPRUNE                 HEX: 00002000
+CONSTANT: COPYFLG_IN_USE_TRY_RENAME       HEX: 00004000
+CONSTANT: DELFLG_IN_USE                   HEX: 00000001
+CONSTANT: DELFLG_IN_USE1                  HEX: 00010000
+STRUCT: FILEPATHS_A
+    { Target       PCSTR }
+    { Source       PCSTR }
+    { Win32Error   UINT  }
+    { Flags        DWORD } ;
+TYPEDEF: FILEPATHS_A* PFILEPATHS_A
+STRUCT: FILEPATHS_W
+    { Target       PCWSTR }
+    { Source       PCWSTR }
+    { Win32Error   UINT   }
+    { Flags        DWORD  } ;
+TYPEDEF: FILEPATHS_W* PFILEPATHS_W
+TYPEDEF: FILEPATHS_W FILEPATHS
+TYPEDEF: PFILEPATHS_W PFILEPATHS
+STRUCT: FILEPATHS_SIGNERINFO_A
+    { Target         PCSTR }
+    { Source         PCSTR }
+    { Win32Error     UINT  }
+    { Flags          DWORD }
+    { DigitalSigner  PCSTR }
+    { Version        PCSTR }
+    { CatalogFile    PCSTR } ;
+TYPEDEF: FILEPATHS_SIGNERINFO_A* PFILEPATHS_SIGNERINFO_A
+STRUCT: FILEPATHS_SIGNERINFO_W
+    { Target        PCWSTR }
+    { Source        PCWSTR }
+    { Win32Error    UINT   }
+    { Flags         DWORD  }
+    { DigitalSigner PCWSTR }
+    { Version       PCWSTR }
+    { CatalogFile   PCWSTR } ;
+TYPEDEF: FILEPATHS_SIGNERINFO_W* PFILEPATHS_SIGNERINFO_W
+TYPEDEF: FILEPATHS_SIGNERINFO_W FILEPATHS_SIGNERINFO
+TYPEDEF: PFILEPATHS_SIGNERINFO_W PFILEPATHS_SIGNERINFO
+
+STRUCT: SOURCE_MEDIA_A
+    { Reserved    PCSTR }
+    { Tagfile     PCSTR }
+    { Description PCSTR }
+    { SourcePath  PCSTR }
+    { SourceFile  PCSTR }
+    { Flags       DWORD } ;
+TYPEDEF: SOURCE_MEDIA_A* PSOURCE_MEDIA_A
+STRUCT: SOURCE_MEDIA_W
+    { Reserved    PCWSTR }
+    { Tagfile     PCWSTR }
+    { Description PCWSTR }
+    { SourcePath  PCWSTR }
+    { SourceFile  PCWSTR }
+    { Flags       DWORD  } ;
+TYPEDEF: SOURCE_MEDIA_W* PSOURCE_MEDIA_W
+TYPEDEF: SOURCE_MEDIA_W SOURCE_MEDIA
+TYPEDEF: PSOURCE_MEDIA_W PSOURCE_MEDIA
+
+STRUCT: CABINET_INFO_A
+    { CabinetPath   PCSTR  }
+    { CabinetFile   PCSTR  }
+    { DiskName      PCSTR  }
+    { SetId         USHORT }
+    { CabinetNumber USHORT } ;
+TYPEDEF: CABINET_INFO_A* PCABINET_INFO_A
+STRUCT: CABINET_INFO_W
+    { CabinetPath   PCWSTR }
+    { CabinetFile   PCWSTR }
+    { DiskName      PCWSTR }
+    { SetId         USHORT }
+    { CabinetNumber USHORT } ;
+TYPEDEF: CABINET_INFO_W* PCABINET_INFO_W
+TYPEDEF: CABINET_INFO_W CABINET_INFO
+TYPEDEF: PCABINET_INFO_W PCABINET_INFO
+
+STRUCT: FILE_IN_CABINET_INFO_A
+    { NameInCabinet   PCSTR          }
+    { FileSize        DWORD          }
+    { Win32Error      DWORD          }
+    { DosDate         WORD           }
+    { DosTime         WORD           }
+    { DosAttribs      WORD           }
+    { FullTargetName  CHAR[MAX_PATH] } ;
+TYPEDEF: FILE_IN_CABINET_INFO_A* PFILE_IN_CABINET_INFO_A
+STRUCT: FILE_IN_CABINET_INFO_W
+    { NameInCabinet   PCWSTR          }
+    { FileSize        DWORD           }
+    { Win32Error      DWORD           }
+    { DosDate         WORD            }
+    { DosTime         WORD            }
+    { DosAttribs      WORD            }
+    { FullTargetName  WCHAR[MAX_PATH] } ;
+TYPEDEF: FILE_IN_CABINET_INFO_W* PFILE_IN_CABINET_INFO_W
+TYPEDEF: FILE_IN_CABINET_INFO_W FILE_IN_CABINET_INFO
+TYPEDEF: PFILE_IN_CABINET_INFO_W PFILE_IN_CABINET_INFO
+
+STRUCT: SP_REGISTER_CONTROL_STATUSA
+    { cbSize         DWORD }
+    { FileName       PCSTR }
+    { Win32Error     DWORD }
+    { FailureCode    DWORD } ;
+TYPEDEF: SP_REGISTER_CONTROL_STATUSA* PSP_REGISTER_CONTROL_STATUSA
+STRUCT: SP_REGISTER_CONTROL_STATUSW
+    { cbSize         DWORD  }
+    { FileName       PCWSTR }
+    { Win32Error     DWORD  }
+    { FailureCode    DWORD  } ;
+TYPEDEF: SP_REGISTER_CONTROL_STATUSW* PSP_REGISTER_CONTROL_STATUSW
+
+TYPEDEF: SP_REGISTER_CONTROL_STATUSW SP_REGISTER_CONTROL_STATUS
+TYPEDEF: PSP_REGISTER_CONTROL_STATUSW PSP_REGISTER_CONTROL_STATUS
+
+CONSTANT: SPREG_SUCCESS       HEX: 00000000
+CONSTANT: SPREG_LOADLIBRARY   HEX: 00000001
+CONSTANT: SPREG_GETPROCADDR   HEX: 00000002
+CONSTANT: SPREG_REGSVR        HEX: 00000003
+CONSTANT: SPREG_DLLINSTALL    HEX: 00000004
+CONSTANT: SPREG_TIMEOUT       HEX: 00000005
+CONSTANT: SPREG_UNKNOWN       HEX: FFFFFFFF
+
+TYPEDEF: PVOID HSPFILEQ
+
+STRUCT: SP_FILE_COPY_PARAMS_A
+    { cbSize                DWORD    }
+    { QueueHandle           HSPFILEQ }
+    { SourceRootPath        PCSTR    }
+    { SourcePath            PCSTR    }
+    { SourceFilename        PCSTR    }
+    { SourceDescription     PCSTR    }
+    { SourceTagfile         PCSTR    }
+    { TargetDirectory       PCSTR    }
+    { TargetFilename        PCSTR    }
+    { CopyStyle             DWORD    }
+    { LayoutInf             HINF     }
+    { SecurityDescriptor    PCSTR    } ;
+TYPEDEF: SP_FILE_COPY_PARAMS_A* PSP_FILE_COPY_PARAMS_A
+STRUCT: SP_FILE_COPY_PARAMS_W
+    { cbSize               DWORD    }
+    { QueueHandle          HSPFILEQ }
+    { SourceRootPath       PCWSTR   }
+    { SourcePath           PCWSTR   }
+    { SourceFilename       PCWSTR   }
+    { SourceDescription    PCWSTR   }
+    { SourceTagfile        PCWSTR   }
+    { TargetDirectory      PCWSTR   }
+    { TargetFilename       PCWSTR   }
+    { CopyStyle            DWORD    }
+    { LayoutInf            HINF     }
+    { SecurityDescriptor   PCWSTR   } ;
+TYPEDEF: SP_FILE_COPY_PARAMS_W* PSP_FILE_COPY_PARAMS_W
+
+TYPEDEF: SP_FILE_COPY_PARAMS_W SP_FILE_COPY_PARAMS
+TYPEDEF: PSP_FILE_COPY_PARAMS_W PSP_FILE_COPY_PARAMS
+
+TYPEDEF: PVOID HDSKSPC
+TYPEDEF: PVOID HDEVINFO
+
+STRUCT: SP_DEVINFO_DATA
+    { cbSize     DWORD     }
+    { ClassGuid  GUID      }
+    { DevInst    DWORD     }
+    { Reserved   ULONG_PTR } ;
+TYPEDEF: SP_DEVINFO_DATA* PSP_DEVINFO_DATA
+STRUCT: SP_DEVICE_INTERFACE_DATA
+    { cbSize              DWORD     }
+    { InterfaceClassGuid  GUID      }
+    { Flags               DWORD     }
+    { Reserved            ULONG_PTR } ;
+TYPEDEF: SP_DEVICE_INTERFACE_DATA* PSP_DEVICE_INTERFACE_DATA
+
+CONSTANT: SPINT_ACTIVE  HEX: 00000001
+CONSTANT: SPINT_DEFAULT HEX: 00000002
+CONSTANT: SPINT_REMOVED HEX: 00000004
+TYPEDEF: SP_DEVICE_INTERFACE_DATA  SP_INTERFACE_DEVICE_DATA
+TYPEDEF: PSP_DEVICE_INTERFACE_DATA PSP_INTERFACE_DEVICE_DAT
+CONSTANT: SPID_ACTIVE               $ SPINT_ACTIVE
+CONSTANT: SPID_DEFAULT              $ SPINT_DEFAULT
+CONSTANT: SPID_REMOVED              $ SPINT_REMOVED
+
+STRUCT: SP_DEVICE_INTERFACE_DETAIL_DATA_A
+    { cbSize     DWORD               }
+    { DevicePath CHAR[ANYSIZE_ARRAY] } ;
+TYPEDEF: SP_DEVICE_INTERFACE_DETAIL_DATA_A* PSP_DEVICE_INTERFACE_DETAIL_DATA_A
+STRUCT: SP_DEVICE_INTERFACE_DETAIL_DATA_W
+    { cbSize      DWORD                }
+    { DevicePath  WCHAR[ANYSIZE_ARRAY] } ;
+TYPEDEF: SP_DEVICE_INTERFACE_DETAIL_DATA_W* PSP_DEVICE_INTERFACE_DETAIL_DATA_W
+TYPEDEF: SP_DEVICE_INTERFACE_DETAIL_DATA_W SP_DEVICE_INTERFACE_DETAIL_DATA
+TYPEDEF: PSP_DEVICE_INTERFACE_DETAIL_DATA_W PSP_DEVICE_INTERFACE_DETAIL_DATA
+TYPEDEF: SP_DEVICE_INTERFACE_DETAIL_DATA_W SP_INTERFACE_DEVICE_DETAIL_DATA_W
+TYPEDEF: PSP_DEVICE_INTERFACE_DETAIL_DATA_W PSP_INTERFACE_DEVICE_DETAIL_DATA_W
+TYPEDEF: SP_DEVICE_INTERFACE_DETAIL_DATA_A SP_INTERFACE_DEVICE_DETAIL_DATA_A
+TYPEDEF: PSP_DEVICE_INTERFACE_DETAIL_DATA_A PSP_INTERFACE_DEVICE_DETAIL_DATA_A
+
+TYPEDEF: SP_INTERFACE_DEVICE_DETAIL_DATA_W SP_INTERFACE_DEVICE_DETAIL_DATA
+TYPEDEF: PSP_INTERFACE_DEVICE_DETAIL_DATA_W PSP_INTERFACE_DEVICE_DETAIL_DATA
+
+STRUCT: SP_DEVINFO_LIST_DETAIL_DATA_A
+    { cbSize              DWORD                           }
+    { ClassGuid           GUID                            }
+    { RemoteMachineHandle HANDLE                          }
+    { RemoteMachineName   CHAR[SP_MAX_MACHINENAME_LENGTH] } ;
+TYPEDEF: SP_DEVINFO_LIST_DETAIL_DATA_A* PSP_DEVINFO_LIST_DETAIL_DATA_A
+STRUCT: SP_DEVINFO_LIST_DETAIL_DATA_W
+    { cbSize              DWORD                            }
+    { ClassGuid           GUID                             }
+    { RemoteMachineHandle HANDLE                           }
+    { RemoteMachineName   WCHAR[SP_MAX_MACHINENAME_LENGTH] } ;
+TYPEDEF: SP_DEVINFO_LIST_DETAIL_DATA_W* PSP_DEVINFO_LIST_DETAIL_DATA_W
+
+TYPEDEF: SP_DEVINFO_LIST_DETAIL_DATA_W SP_DEVINFO_LIST_DETAIL_DATA
+TYPEDEF: PSP_DEVINFO_LIST_DETAIL_DATA_W PSP_DEVINFO_LIST_DETAIL_DATA
+
+CONSTANT: DIF_SELECTDEVICE                    HEX: 00000001
+CONSTANT: DIF_INSTALLDEVICE                   HEX: 00000002
+CONSTANT: DIF_ASSIGNRESOURCES                 HEX: 00000003
+CONSTANT: DIF_PROPERTIES                      HEX: 00000004
+CONSTANT: DIF_REMOVE                          HEX: 00000005
+CONSTANT: DIF_FIRSTTIMESETUP                  HEX: 00000006
+CONSTANT: DIF_FOUNDDEVICE                     HEX: 00000007
+CONSTANT: DIF_SELECTCLASSDRIVERS              HEX: 00000008
+CONSTANT: DIF_VALIDATECLASSDRIVERS            HEX: 00000009
+CONSTANT: DIF_INSTALLCLASSDRIVERS             HEX: 0000000A
+CONSTANT: DIF_CALCDISKSPACE                   HEX: 0000000B
+CONSTANT: DIF_DESTROYPRIVATEDATA              HEX: 0000000C
+CONSTANT: DIF_VALIDATEDRIVER                  HEX: 0000000D
+CONSTANT: DIF_DETECT                          HEX: 0000000F
+CONSTANT: DIF_INSTALLWIZARD                   HEX: 00000010
+CONSTANT: DIF_DESTROYWIZARDDATA               HEX: 00000011
+CONSTANT: DIF_PROPERTYCHANGE                  HEX: 00000012
+CONSTANT: DIF_ENABLECLASS                     HEX: 00000013
+CONSTANT: DIF_DETECTVERIFY                    HEX: 00000014
+CONSTANT: DIF_INSTALLDEVICEFILES              HEX: 00000015
+CONSTANT: DIF_UNREMOVE                        HEX: 00000016
+CONSTANT: DIF_SELECTBESTCOMPATDRV             HEX: 00000017
+CONSTANT: DIF_ALLOW_INSTALL                   HEX: 00000018
+CONSTANT: DIF_REGISTERDEVICE                  HEX: 00000019
+CONSTANT: DIF_NEWDEVICEWIZARD_PRESELECT       HEX: 0000001A
+CONSTANT: DIF_NEWDEVICEWIZARD_SELECT          HEX: 0000001B
+CONSTANT: DIF_NEWDEVICEWIZARD_PREANALYZE      HEX: 0000001C
+CONSTANT: DIF_NEWDEVICEWIZARD_POSTANALYZE     HEX: 0000001D
+CONSTANT: DIF_NEWDEVICEWIZARD_FINISHINSTALL   HEX: 0000001E
+CONSTANT: DIF_UNUSED1                         HEX: 0000001F
+CONSTANT: DIF_INSTALLINTERFACES               HEX: 00000020
+CONSTANT: DIF_DETECTCANCEL                    HEX: 00000021
+CONSTANT: DIF_REGISTER_COINSTALLERS           HEX: 00000022
+CONSTANT: DIF_ADDPROPERTYPAGE_ADVANCED        HEX: 00000023
+CONSTANT: DIF_ADDPROPERTYPAGE_BASIC           HEX: 00000024
+CONSTANT: DIF_RESERVED1                       HEX: 00000025
+CONSTANT: DIF_TROUBLESHOOTER                  HEX: 00000026
+CONSTANT: DIF_POWERMESSAGEWAKE                HEX: 00000027
+CONSTANT: DIF_ADDREMOTEPROPERTYPAGE_ADVANCED  HEX: 00000028
+CONSTANT: DIF_UPDATEDRIVER_UI                 HEX: 00000029
+CONSTANT: DIF_FINISHINSTALL_ACTION            HEX: 0000002A
+CONSTANT: DIF_RESERVED2                       HEX: 00000030
+CONSTANT: DIF_MOVEDEVICE                      HEX: 0000000E
+TYPEDEF: UINT DI_FUNCTION
+
+STRUCT: SP_DEVINSTALL_PARAMS_A
+    { cbSize                               DWORD             }
+    { Flags                                DWORD             }
+    { FlagsEx                              DWORD             }
+    { hwndParent                           HWND              }
+    { InstallMsgHandler                    PSP_FILE_CALLBACK }
+    { InstallMsgHandlerContext             PVOID             }
+    { FileQueue                            HSPFILEQ          }
+    { ClassInstallReserved                 ULONG_PTR         }
+    { Reserved                             DWORD             }
+    { DriverPath                           CHAR[MAX_PATH]    } ;
+TYPEDEF: SP_DEVINSTALL_PARAMS_A* PSP_DEVINSTALL_PARAMS_A
+STRUCT: SP_DEVINSTALL_PARAMS_W
+    { cbSize                               DWORD             }
+    { Flags                                DWORD             }
+    { FlagsEx                              DWORD             }
+    { hwndParent                           HWND              }
+    { InstallMsgHandler                    PSP_FILE_CALLBACK }
+    { InstallMsgHandlerContext             PVOID             }
+    { FileQueue                            HSPFILEQ          }
+    { ClassInstallReserved                 ULONG_PTR         }
+    { Reserved                             DWORD             }
+    { DriverPath                           WCHAR[MAX_PATH]   } ;
+TYPEDEF: SP_DEVINSTALL_PARAMS_W* PSP_DEVINSTALL_PARAMS_W
+TYPEDEF: SP_DEVINSTALL_PARAMS_W SP_DEVINSTALL_PARAMS
+TYPEDEF: PSP_DEVINSTALL_PARAMS_W PSP_DEVINSTALL_PARAMS
+
+CONSTANT: DI_SHOWOEM                  HEX: 00000001
+CONSTANT: DI_SHOWCOMPAT               HEX: 00000002
+CONSTANT: DI_SHOWCLASS                HEX: 00000004
+CONSTANT: DI_SHOWALL                  HEX: 00000007
+CONSTANT: DI_NOVCP                    HEX: 00000008
+CONSTANT: DI_DIDCOMPAT                HEX: 00000010
+CONSTANT: DI_DIDCLASS                 HEX: 00000020
+CONSTANT: DI_AUTOASSIGNRES            HEX: 00000040
+CONSTANT: DI_NEEDRESTART              HEX: 00000080
+CONSTANT: DI_NEEDREBOOT               HEX: 00000100
+CONSTANT: DI_NOBROWSE                 HEX: 00000200
+CONSTANT: DI_MULTMFGS                 HEX: 00000400
+CONSTANT: DI_DISABLED                 HEX: 00000800
+CONSTANT: DI_GENERALPAGE_ADDED        HEX: 00001000
+CONSTANT: DI_RESOURCEPAGE_ADDED       HEX: 00002000
+CONSTANT: DI_PROPERTIES_CHANGE        HEX: 00004000
+CONSTANT: DI_INF_IS_SORTED            HEX: 00008000
+CONSTANT: DI_ENUMSINGLEINF            HEX: 00010000
+CONSTANT: DI_DONOTCALLCONFIGMG        HEX: 00020000
+CONSTANT: DI_INSTALLDISABLED          HEX: 00040000
+CONSTANT: DI_COMPAT_FROM_CLASS        HEX: 00080000
+CONSTANT: DI_CLASSINSTALLPARAMS       HEX: 00100000
+CONSTANT: DI_NODI_DEFAULTACTION       HEX: 00200000
+CONSTANT: DI_QUIETINSTALL             HEX: 00800000
+CONSTANT: DI_NOFILECOPY               HEX: 01000000
+CONSTANT: DI_FORCECOPY                HEX: 02000000
+CONSTANT: DI_DRIVERPAGE_ADDED         HEX: 04000000
+CONSTANT: DI_USECI_SELECTSTRINGS      HEX: 08000000
+CONSTANT: DI_OVERRIDE_INFFLAGS        HEX: 10000000
+CONSTANT: DI_PROPS_NOCHANGEUSAGE      HEX: 20000000
+CONSTANT: DI_NOSELECTICONS            HEX: 40000000
+CONSTANT: DI_NOWRITE_IDS              HEX: 80000000
+CONSTANT: DI_FLAGSEX_RESERVED2                HEX: 00000001
+CONSTANT: DI_FLAGSEX_RESERVED3                HEX: 00000002
+CONSTANT: DI_FLAGSEX_CI_FAILED                HEX: 00000004
+CONSTANT: DI_FLAGSEX_FINISHINSTALL_ACTION     HEX: 00000008
+CONSTANT: DI_FLAGSEX_DIDINFOLIST              HEX: 00000010
+CONSTANT: DI_FLAGSEX_DIDCOMPATINFO            HEX: 00000020
+CONSTANT: DI_FLAGSEX_FILTERCLASSES            HEX: 00000040
+CONSTANT: DI_FLAGSEX_SETFAILEDINSTALL         HEX: 00000080
+CONSTANT: DI_FLAGSEX_DEVICECHANGE             HEX: 00000100
+CONSTANT: DI_FLAGSEX_ALWAYSWRITEIDS           HEX: 00000200
+CONSTANT: DI_FLAGSEX_PROPCHANGE_PENDING       HEX: 00000400
+CONSTANT: DI_FLAGSEX_ALLOWEXCLUDEDDRVS        HEX: 00000800
+CONSTANT: DI_FLAGSEX_NOUIONQUERYREMOVE        HEX: 00001000
+CONSTANT: DI_FLAGSEX_USECLASSFORCOMPAT        HEX: 00002000
+CONSTANT: DI_FLAGSEX_RESERVED4                HEX: 00004000
+CONSTANT: DI_FLAGSEX_NO_DRVREG_MODIFY         HEX: 00008000
+CONSTANT: DI_FLAGSEX_IN_SYSTEM_SETUP          HEX: 00010000
+CONSTANT: DI_FLAGSEX_INET_DRIVER              HEX: 00020000
+CONSTANT: DI_FLAGSEX_APPENDDRIVERLIST         HEX: 00040000
+CONSTANT: DI_FLAGSEX_PREINSTALLBACKUP         HEX: 00080000
+CONSTANT: DI_FLAGSEX_BACKUPONREPLACE          HEX: 00100000
+CONSTANT: DI_FLAGSEX_DRIVERLIST_FROM_URL      HEX: 00200000
+CONSTANT: DI_FLAGSEX_RESERVED1                HEX: 00400000
+CONSTANT: DI_FLAGSEX_EXCLUDE_OLD_INET_DRIVERS HEX: 00800000
+CONSTANT: DI_FLAGSEX_POWERPAGE_ADDED          HEX: 01000000
+CONSTANT: DI_FLAGSEX_FILTERSIMILARDRIVERS     HEX: 02000000
+CONSTANT: DI_FLAGSEX_INSTALLEDDRIVER          HEX: 04000000
+CONSTANT: DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE  HEX: 08000000
+CONSTANT: DI_FLAGSEX_ALTPLATFORM_DRVSEARCH    HEX: 10000000
+CONSTANT: DI_FLAGSEX_RESTART_DEVICE_ONLY      HEX: 20000000
+CONSTANT: DI_FLAGSEX_RECURSIVESEARCH          HEX: 40000000
+CONSTANT: DI_FLAGSEX_SEARCH_PUBLISHED_INFS    HEX: 80000000
+
+STRUCT: SP_CLASSINSTALL_HEADER
+    { cbSize          DWORD       }
+    { InstallFunction DI_FUNCTION } ;
+TYPEDEF: SP_CLASSINSTALL_HEADER* PSP_CLASSINSTALL_HEADER
+
+STRUCT: SP_ENABLECLASS_PARAMS
+    { ClassInstallHeader             SP_CLASSINSTALL_HEADER }
+    { ClassGuid                      GUID                   }
+    { EnableMessage                  DWORD                  } ;
+TYPEDEF: SP_ENABLECLASS_PARAMS* PSP_ENABLECLASS_PARAMS
+
+CONSTANT: ENABLECLASS_QUERY   0
+CONSTANT: ENABLECLASS_SUCCESS 1
+CONSTANT: ENABLECLASS_FAILURE 2
+CONSTANT: DICS_ENABLE      HEX: 00000001
+CONSTANT: DICS_DISABLE     HEX: 00000002
+CONSTANT: DICS_PROPCHANGE  HEX: 00000003
+CONSTANT: DICS_START       HEX: 00000004
+CONSTANT: DICS_STOP        HEX: 00000005
+CONSTANT: DICS_FLAG_GLOBAL         HEX: 00000001
+CONSTANT: DICS_FLAG_CONFIGSPECIFIC HEX: 00000002
+CONSTANT: DICS_FLAG_CONFIGGENERAL  HEX: 00000004
+
+STRUCT: SP_PROPCHANGE_PARAMS
+    { ClassInstallHeader           SP_CLASSINSTALL_HEADER }
+    { StateChange                  DWORD                  }
+    { Scope                        DWORD                  }
+    { HwProfile                    DWORD                  } ;
+TYPEDEF: SP_PROPCHANGE_PARAMS* PSP_PROPCHANGE_PARAMS
+
+STRUCT: SP_REMOVEDEVICE_PARAMS
+    { ClassInstallHeader SP_CLASSINSTALL_HEADER }
+    { Scope              DWORD                  }
+    { HwProfile          DWORD                  } ;
+TYPEDEF: SP_REMOVEDEVICE_PARAMS* PSP_REMOVEDEVICE_PARAMS
+
+CONSTANT: DI_REMOVEDEVICE_GLOBAL                  HEX: 00000001
+CONSTANT: DI_REMOVEDEVICE_CONFIGSPECIFIC          HEX: 00000002
+
+STRUCT: SP_UNREMOVEDEVICE_PARAMS
+    { ClassInstallHeader SP_CLASSINSTALL_HEADER }
+    { Scope              DWORD                  }
+    { HwProfile          DWORD                  } ;
+TYPEDEF: SP_UNREMOVEDEVICE_PARAMS* PSP_UNREMOVEDEVICE_PARAMS
+
+CONSTANT: DI_UNREMOVEDEVICE_CONFIGSPECIFIC        HEX: 00000002
+
+STRUCT: SP_SELECTDEVICE_PARAMS_A
+    { ClassInstallHeader             SP_CLASSINSTALL_HEADER    }
+    { Title                          CHAR[MAX_TITLE_LEN]       }
+    { Instructions                   CHAR[MAX_INSTRUCTION_LEN] }
+    { ListLabel                      CHAR[MAX_LABEL_LEN]       }
+    { SubTitle                       CHAR[MAX_SUBTITLE_LEN]    }
+    { Reserved                       BYTE[2]                   } ;
+TYPEDEF: SP_SELECTDEVICE_PARAMS_A* PSP_SELECTDEVICE_PARAMS_A
+STRUCT: SP_SELECTDEVICE_PARAMS_W
+    { ClassInstallHeader            SP_CLASSINSTALL_HEADER     }
+    { Title                         WCHAR[MAX_TITLE_LEN]       }
+    { Instructions                  WCHAR[MAX_INSTRUCTION_LEN] }
+    { ListLabel                     WCHAR[MAX_LABEL_LEN]       }
+    { SubTitle                      WCHAR[MAX_SUBTITLE_LEN]    } ;
+TYPEDEF: SP_SELECTDEVICE_PARAMS_W* PSP_SELECTDEVICE_PARAMS_W
+TYPEDEF: SP_SELECTDEVICE_PARAMS_W SP_SELECTDEVICE_PARAMS
+TYPEDEF: PSP_SELECTDEVICE_PARAMS_W PSP_SELECTDEVICE_PARAMS
+
+CALLBACK: BOOL PDETECT_PROGRESS_NOTIFY ( PVOID ProgressNotifyParam, DWORD DetectComplete ) ;
+
+STRUCT: SP_DETECTDEVICE_PARAMS
+    { ClassInstallHeader                    SP_CLASSINSTALL_HEADER  }
+    { DetectProgressNotify                  PDETECT_PROGRESS_NOTIFY }
+    { ProgressNotifyParam                   PVOID                   } ;
+TYPEDEF: SP_DETECTDEVICE_PARAMS* PSP_DETECTDEVICE_PARAMS
+
+CONSTANT: MAX_INSTALLWIZARD_DYNAPAGES 20
+
+STRUCT: SP_INSTALLWIZARD_DATA
+    { ClassInstallHeader                SP_CLASSINSTALL_HEADER                      }
+    { Flags                             DWORD                                       }
+    { DynamicPages                      HPROPSHEETPAGE[MAX_INSTALLWIZARD_DYNAPAGES] }
+    { NumDynamicPages                   DWORD                                       }
+    { DynamicPageFlags                  DWORD                                       }
+    { PrivateFlags                      DWORD                                       }
+    { PrivateData                       LPARAM                                      }
+    { hwndWizardDlg                     HWND                                        } ;
+TYPEDEF: SP_INSTALLWIZARD_DATA* PSP_INSTALLWIZARD_DATA
+
+CONSTANT: NDW_INSTALLFLAG_DIDFACTDEFS         HEX: 00000001
+CONSTANT: NDW_INSTALLFLAG_HARDWAREALLREADYIN  HEX: 00000002
+CONSTANT: NDW_INSTALLFLAG_NEEDRESTART         $ DI_NEEDRESTART
+CONSTANT: NDW_INSTALLFLAG_NEEDREBOOT          $ DI_NEEDREBOOT
+CONSTANT: NDW_INSTALLFLAG_NEEDSHUTDOWN        HEX: 00000200
+CONSTANT: NDW_INSTALLFLAG_EXPRESSINTRO        HEX: 00000400
+CONSTANT: NDW_INSTALLFLAG_SKIPISDEVINSTALLED  HEX: 00000800
+CONSTANT: NDW_INSTALLFLAG_NODETECTEDDEVS      HEX: 00001000
+CONSTANT: NDW_INSTALLFLAG_INSTALLSPECIFIC     HEX: 00002000
+CONSTANT: NDW_INSTALLFLAG_SKIPCLASSLIST       HEX: 00004000
+CONSTANT: NDW_INSTALLFLAG_CI_PICKED_OEM       HEX: 00008000
+CONSTANT: NDW_INSTALLFLAG_PCMCIAMODE          HEX: 00010000
+CONSTANT: NDW_INSTALLFLAG_PCMCIADEVICE        HEX: 00020000
+CONSTANT: NDW_INSTALLFLAG_USERCANCEL          HEX: 00040000
+CONSTANT: NDW_INSTALLFLAG_KNOWNCLASS          HEX: 00080000
+CONSTANT: DYNAWIZ_FLAG_PAGESADDED             HEX: 00000001
+CONSTANT: DYNAWIZ_FLAG_ANALYZE_HANDLECONFLICT HEX: 00000008
+CONSTANT: DYNAWIZ_FLAG_INSTALLDET_NEXT        HEX: 00000002
+CONSTANT: DYNAWIZ_FLAG_INSTALLDET_PREV        HEX: 00000004
+CONSTANT: MIN_IDD_DYNAWIZ_RESOURCE_ID             10000
+CONSTANT: MAX_IDD_DYNAWIZ_RESOURCE_ID             11000
+CONSTANT: IDD_DYNAWIZ_FIRSTPAGE                   10000
+CONSTANT: IDD_DYNAWIZ_SELECT_PREVPAGE             10001
+CONSTANT: IDD_DYNAWIZ_SELECT_NEXTPAGE             10002
+CONSTANT: IDD_DYNAWIZ_ANALYZE_PREVPAGE            10003
+CONSTANT: IDD_DYNAWIZ_ANALYZE_NEXTPAGE            10004
+CONSTANT: IDD_DYNAWIZ_SELECTDEV_PAGE              10009
+CONSTANT: IDD_DYNAWIZ_ANALYZEDEV_PAGE             10010
+CONSTANT: IDD_DYNAWIZ_INSTALLDETECTEDDEVS_PAGE    10011
+CONSTANT: IDD_DYNAWIZ_SELECTCLASS_PAGE            10012
+CONSTANT: IDD_DYNAWIZ_INSTALLDETECTED_PREVPAGE    10006
+CONSTANT: IDD_DYNAWIZ_INSTALLDETECTED_NEXTPAGE    10007
+CONSTANT: IDD_DYNAWIZ_INSTALLDETECTED_NODEVS      10008
+
+STRUCT: SP_NEWDEVICEWIZARD_DATA
+    { ClassInstallHeader SP_CLASSINSTALL_HEADER                      }
+    { Flags              DWORD                                       }
+    { DynamicPages       HPROPSHEETPAGE[MAX_INSTALLWIZARD_DYNAPAGES] }
+    { NumDynamicPages    DWORD                                       }
+    { hwndWizardDlg      HWND                                        } ;
+TYPEDEF: SP_NEWDEVICEWIZARD_DATA* PSP_NEWDEVICEWIZARD_DATA
+TYPEDEF: SP_NEWDEVICEWIZARD_DATA SP_ADDPROPERTYPAGE_DATA
+TYPEDEF: PSP_NEWDEVICEWIZARD_DATA PSP_ADDPROPERTYPAGE_DATA
+
+STRUCT: SP_TROUBLESHOOTER_PARAMS_A
+    { ClassInstallHeader SP_CLASSINSTALL_HEADER }
+    { ChmFile            CHAR[MAX_PATH]         }
+    { HtmlTroubleShooter CHAR[MAX_PATH]         } ;
+TYPEDEF: SP_TROUBLESHOOTER_PARAMS_A* PSP_TROUBLESHOOTER_PARAMS_A
+STRUCT: SP_TROUBLESHOOTER_PARAMS_W
+    { ClassInstallHeader SP_CLASSINSTALL_HEADER }
+    { ChmFile            WCHAR[MAX_PATH]        }
+    { HtmlTroubleShooter WCHAR[MAX_PATH]        } ;
+TYPEDEF: SP_TROUBLESHOOTER_PARAMS_W* PSP_TROUBLESHOOTER_PARAMS_W
+TYPEDEF: SP_TROUBLESHOOTER_PARAMS_W SP_TROUBLESHOOTER_PARAMS
+TYPEDEF: PSP_TROUBLESHOOTER_PARAMS_W PSP_TROUBLESHOOTER_PARAMS
+
+STRUCT: SP_POWERMESSAGEWAKE_PARAMS_A
+    { ClassInstallHeader     SP_CLASSINSTALL_HEADER }
+    { PowerMessageWake       CHAR[LINE_LEN*2]       } ;
+TYPEDEF: SP_POWERMESSAGEWAKE_PARAMS_A* PSP_POWERMESSAGEWAKE_PARAMS_A
+STRUCT: SP_POWERMESSAGEWAKE_PARAMS_W
+    { ClassInstallHeader    SP_CLASSINSTALL_HEADER }
+    { PowerMessageWake      WCHAR[LINE_LEN*2]      } ;
+TYPEDEF: SP_POWERMESSAGEWAKE_PARAMS_W* PSP_POWERMESSAGEWAKE_PARAMS_W
+TYPEDEF: SP_POWERMESSAGEWAKE_PARAMS_W SP_POWERMESSAGEWAKE_PARAMS
+TYPEDEF: PSP_POWERMESSAGEWAKE_PARAMS_W PSP_POWERMESSAGEWAKE_PARAMS
+
+STRUCT: SP_DRVINFO_DATA_V2_A
+    { cbSize         DWORD          }
+    { DriverType     DWORD          }
+    { Reserved       ULONG_PTR      }
+    { Description    CHAR[LINE_LEN] }
+    { MfgName        CHAR[LINE_LEN] }
+    { ProviderName   CHAR[LINE_LEN] }
+    { DriverDate     FILETIME       }
+    { DriverVersion  DWORDLONG      } ;
+TYPEDEF: SP_DRVINFO_DATA_V2_A* PSP_DRVINFO_DATA_V2_A
+STRUCT: SP_DRVINFO_DATA_V2_W
+    { cbSize         DWORD           }
+    { DriverType     DWORD           }
+    { Reserved       ULONG_PTR       }
+    { Description    WCHAR[LINE_LEN] }
+    { MfgName        WCHAR[LINE_LEN] }
+    { ProviderName   WCHAR[LINE_LEN] }
+    { DriverDate     FILETIME        }
+    { DriverVersion  DWORDLONG       } ;
+TYPEDEF: SP_DRVINFO_DATA_V2_W* PSP_DRVINFO_DATA_V2_W
+STRUCT: SP_DRVINFO_DATA_V1_A
+    { cbSize         DWORD          }
+    { DriverType     DWORD          }
+    { Reserved       ULONG_PTR      }
+    { Description    CHAR[LINE_LEN] }
+    { MfgName        CHAR[LINE_LEN] }
+    { ProviderName   CHAR[LINE_LEN] } ;
+TYPEDEF: SP_DRVINFO_DATA_V1_A* PSP_DRVINFO_DATA_V1_A
+STRUCT: SP_DRVINFO_DATA_V1_W
+    { cbSize         DWORD           }
+    { DriverType     DWORD           }
+    { Reserved       ULONG_PTR       }
+    { Description    WCHAR[LINE_LEN] }
+    { MfgName        WCHAR[LINE_LEN] }
+    { ProviderName   WCHAR[LINE_LEN] } ;
+TYPEDEF: SP_DRVINFO_DATA_V1_W* PSP_DRVINFO_DATA_V1_W
+TYPEDEF: SP_DRVINFO_DATA_V1_W SP_DRVINFO_DATA_V1
+TYPEDEF: PSP_DRVINFO_DATA_V1_W PSP_DRVINFO_DATA_V1
+TYPEDEF: SP_DRVINFO_DATA_V2_W SP_DRVINFO_DATA_V2
+TYPEDEF: PSP_DRVINFO_DATA_V2_W PSP_DRVINFO_DATA_V2
+TYPEDEF: SP_DRVINFO_DATA_V2_A SP_DRVINFO_DATA_A
+TYPEDEF: PSP_DRVINFO_DATA_V2_A PSP_DRVINFO_DATA_A
+TYPEDEF: SP_DRVINFO_DATA_V2_W SP_DRVINFO_DATA_W
+TYPEDEF: PSP_DRVINFO_DATA_V2_W PSP_DRVINFO_DATA_W
+TYPEDEF: SP_DRVINFO_DATA_V2 SP_DRVINFO_DATA
+TYPEDEF: PSP_DRVINFO_DATA_V2 PSP_DRVINFO_DATA
+
+STRUCT: SP_DRVINFO_DETAIL_DATA_A
+    { cbSize             DWORD               }
+    { InfDate            FILETIME            }
+    { CompatIDsOffset    DWORD               }
+    { CompatIDsLength    DWORD               }
+    { Reserved           ULONG_PTR           }
+    { SectionName        CHAR[LINE_LEN]      }
+    { InfFileName        CHAR[MAX_PATH]      }
+    { DrvDescription     CHAR[LINE_LEN]      }
+    { HardwareID         CHAR[ANYSIZE_ARRAY] } ;
+TYPEDEF: SP_DRVINFO_DETAIL_DATA_A* PSP_DRVINFO_DETAIL_DATA_A
+STRUCT: SP_DRVINFO_DETAIL_DATA_W
+    { cbSize             DWORD                }
+    { InfDate            FILETIME             }
+    { CompatIDsOffset    DWORD                }
+    { CompatIDsLength    DWORD                }
+    { Reserved           ULONG_PTR            }
+    { SectionName        WCHAR[LINE_LEN]      }
+    { InfFileName        WCHAR[MAX_PATH]      }
+    { DrvDescription     WCHAR[LINE_LEN]      }
+    { HardwareID         WCHAR[ANYSIZE_ARRAY] } ;
+TYPEDEF: SP_DRVINFO_DETAIL_DATA_W* PSP_DRVINFO_DETAIL_DATA_W
+
+TYPEDEF: SP_DRVINFO_DETAIL_DATA_W SP_DRVINFO_DETAIL_DATA
+TYPEDEF: PSP_DRVINFO_DETAIL_DATA_W PSP_DRVINFO_DETAIL_DATA
+
+STRUCT: SP_DRVINSTALL_PARAMS
+    { cbSize      DWORD     }
+    { Rank        DWORD     }
+    { Flags       DWORD     }
+    { PrivateData DWORD_PTR }
+    { Reserved    DWORD     } ;
+TYPEDEF: SP_DRVINSTALL_PARAMS* PSP_DRVINSTALL_PARAMS
+
+CONSTANT: DNF_DUPDESC             HEX: 00000001
+CONSTANT: DNF_OLDDRIVER           HEX: 00000002
+CONSTANT: DNF_EXCLUDEFROMLIST     HEX: 00000004
+CONSTANT: DNF_NODRIVER            HEX: 00000008
+CONSTANT: DNF_LEGACYINF           HEX: 00000010
+CONSTANT: DNF_CLASS_DRIVER        HEX: 00000020
+CONSTANT: DNF_COMPATIBLE_DRIVER   HEX: 00000040
+CONSTANT: DNF_INET_DRIVER         HEX: 00000080
+CONSTANT: DNF_UNUSED1             HEX: 00000100
+CONSTANT: DNF_UNUSED2             HEX: 00000200
+CONSTANT: DNF_OLD_INET_DRIVER     HEX: 00000400
+CONSTANT: DNF_BAD_DRIVER          HEX: 00000800
+CONSTANT: DNF_DUPPROVIDER         HEX: 00001000
+CONSTANT: DNF_INF_IS_SIGNED         HEX: 00002000
+CONSTANT: DNF_OEM_F6_INF            HEX: 00004000
+CONSTANT: DNF_DUPDRIVERVER          HEX: 00008000
+CONSTANT: DNF_BASIC_DRIVER          HEX: 00010000
+CONSTANT: DNF_AUTHENTICODE_SIGNED   HEX: 00020000
+CONSTANT: DNF_INSTALLEDDRIVER       HEX: 00040000
+CONSTANT: DNF_ALWAYSEXCLUDEFROMLIST HEX: 00080000
+CONSTANT: DNF_INBOX_DRIVER          HEX: 00100000
+CONSTANT: DNF_REQUESTADDITIONALSOFTWARE   HEX: 00200000
+CONSTANT: DNF_UNUSED_22             HEX: 00400000
+CONSTANT: DNF_UNUSED_23             HEX: 00800000
+CONSTANT: DNF_UNUSED_24             HEX: 01000000
+CONSTANT: DNF_UNUSED_25             HEX: 02000000
+CONSTANT: DNF_UNUSED_26             HEX: 04000000
+CONSTANT: DNF_UNUSED_27             HEX: 08000000
+CONSTANT: DNF_UNUSED_28             HEX: 10000000
+CONSTANT: DNF_UNUSED_29             HEX: 20000000
+CONSTANT: DNF_UNUSED_30             HEX: 40000000
+CONSTANT: DNF_UNUSED_31             HEX: 80000000
+CONSTANT: DRIVER_HARDWAREID_RANK  HEX: 00000FFF
+CONSTANT: DRIVER_HARDWAREID_MASK  HEX: 80000FFF
+CONSTANT: DRIVER_UNTRUSTED_RANK   HEX: 80000000
+CONSTANT: DRIVER_W9X_SUSPECT_RANK HEX: C0000000
+
+CALLBACK: DWORD PSP_DETSIG_CMPPROC ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA NewDeviceData, PSP_DEVINFO_DATA ExistingDeviceData, PVOID CompareContext ) ;
+
+STRUCT: COINSTALLER_CONTEXT_DATA
+    { PostProcessing  BOOL  }
+    { InstallResult   DWORD }
+    { PrivateData     PVOID } ;
+TYPEDEF: COINSTALLER_CONTEXT_DATA* PCOINSTALLER_CONTEXT_DATA
+
+STRUCT: SP_CLASSIMAGELIST_DATA
+    { cbSize      DWORD      }
+    { ImageList   HIMAGELIST }
+    { Reserved    ULONG_PTR  } ;
+TYPEDEF: SP_CLASSIMAGELIST_DATA* PSP_CLASSIMAGELIST_DATA
+
+STRUCT: SP_PROPSHEETPAGE_REQUEST
+    { cbSize                   DWORD            }
+    { PageRequested            DWORD            }
+    { DeviceInfoSet            HDEVINFO         }
+    { DeviceInfoData           PSP_DEVINFO_DATA } ;
+TYPEDEF: SP_PROPSHEETPAGE_REQUEST* PSP_PROPSHEETPAGE_REQUEST
+
+CONSTANT: SPPSR_SELECT_DEVICE_RESOURCES      1
+CONSTANT: SPPSR_ENUM_BASIC_DEVICE_PROPERTIES 2
+CONSTANT: SPPSR_ENUM_ADV_DEVICE_PROPERTIES   3
+
+STRUCT: SP_BACKUP_QUEUE_PARAMS_V2_A
+    { cbSize              DWORD          }
+    { FullInfPath         CHAR[MAX_PATH] }
+    { FilenameOffset      INT            }
+    { ReinstallInstance   CHAR[MAX_PATH] } ;
+TYPEDEF: SP_BACKUP_QUEUE_PARAMS_V2_A* PSP_BACKUP_QUEUE_PARAMS_V2_A
+
+STRUCT: SP_BACKUP_QUEUE_PARAMS_V2_W
+    { cbSize              DWORD           }
+    { FullInfPath         WCHAR[MAX_PATH] }
+    { FilenameOffset      INT             }
+    { ReinstallInstance   WCHAR[MAX_PATH] } ;
+TYPEDEF: SP_BACKUP_QUEUE_PARAMS_V2_W* PSP_BACKUP_QUEUE_PARAMS_V2_W
+
+STRUCT: SP_BACKUP_QUEUE_PARAMS_V1_A
+    { cbSize              DWORD          }
+    { FullInfPath         CHAR[MAX_PATH] }
+    { FilenameOffset      INT            } ;
+TYPEDEF: SP_BACKUP_QUEUE_PARAMS_V1_A* PSP_BACKUP_QUEUE_PARAMS_V1_A
+
+STRUCT: SP_BACKUP_QUEUE_PARAMS_V1_W
+    { cbSize              DWORD           }
+    { FullInfPath         WCHAR[MAX_PATH] }
+    { FilenameOffset      INT             } ;
+TYPEDEF: SP_BACKUP_QUEUE_PARAMS_V1_W* PSP_BACKUP_QUEUE_PARAMS_V1_W
+
+TYPEDEF: SP_BACKUP_QUEUE_PARAMS_V1_W SP_BACKUP_QUEUE_PARAMS_V1
+TYPEDEF: PSP_BACKUP_QUEUE_PARAMS_V1_W PSP_BACKUP_QUEUE_PARAMS_V1
+TYPEDEF: SP_BACKUP_QUEUE_PARAMS_V2_W SP_BACKUP_QUEUE_PARAMS_V2
+TYPEDEF: PSP_BACKUP_QUEUE_PARAMS_V2_W PSP_BACKUP_QUEUE_PARAMS_V2
+TYPEDEF: SP_BACKUP_QUEUE_PARAMS_V2_A SP_BACKUP_QUEUE_PARAMS_A
+TYPEDEF: PSP_BACKUP_QUEUE_PARAMS_V2_A PSP_BACKUP_QUEUE_PARAMS_A
+TYPEDEF: SP_BACKUP_QUEUE_PARAMS_V2_W SP_BACKUP_QUEUE_PARAMS_W
+TYPEDEF: PSP_BACKUP_QUEUE_PARAMS_V2_W PSP_BACKUP_QUEUE_PARAMS_W
+TYPEDEF: SP_BACKUP_QUEUE_PARAMS_V2 SP_BACKUP_QUEUE_PARAMS
+TYPEDEF: PSP_BACKUP_QUEUE_PARAMS_V2 PSP_BACKUP_QUEUE_PARAMS
+
+CONSTANT: ERROR_EXPECTED_SECTION_NAME  $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR 0 bitor bitor ]
+CONSTANT: ERROR_BAD_SECTION_NAME_LINE  $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR 1 bitor bitor ]
+CONSTANT: ERROR_SECTION_NAME_TOO_LONG  $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR 2 bitor bitor ]
+CONSTANT: ERROR_GENERAL_SYNTAX         $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR 3 bitor bitor ]
+CONSTANT: ERROR_WRONG_INF_STYLE        $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 100 bitor bitor ]
+CONSTANT: ERROR_SECTION_NOT_FOUND      $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 101 bitor bitor ]
+CONSTANT: ERROR_LINE_NOT_FOUND         $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 102 bitor bitor ]
+CONSTANT: ERROR_NO_BACKUP              $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 103 bitor bitor ]
+CONSTANT: ERROR_NO_ASSOCIATED_CLASS                $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 200 bitor bitor ]
+CONSTANT: ERROR_CLASS_MISMATCH                     $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 201 bitor bitor ]
+CONSTANT: ERROR_DUPLICATE_FOUND                    $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 202 bitor bitor ]
+CONSTANT: ERROR_NO_DRIVER_SELECTED                 $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 203 bitor bitor ]
+CONSTANT: ERROR_KEY_DOES_NOT_EXIST                 $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 204 bitor bitor ]
+CONSTANT: ERROR_INVALID_DEVINST_NAME               $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 205 bitor bitor ]
+CONSTANT: ERROR_INVALID_CLASS                      $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 206 bitor bitor ]
+CONSTANT: ERROR_DEVINST_ALREADY_EXISTS             $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 207 bitor bitor ]
+CONSTANT: ERROR_DEVINFO_NOT_REGISTERED             $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 208 bitor bitor ]
+CONSTANT: ERROR_INVALID_REG_PROPERTY               $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 209 bitor bitor ]
+CONSTANT: ERROR_NO_INF                             $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 20A bitor bitor ]
+CONSTANT: ERROR_NO_SUCH_DEVINST                    $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 20B bitor bitor ]
+CONSTANT: ERROR_CANT_LOAD_CLASS_ICON               $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 20C bitor bitor ]
+CONSTANT: ERROR_INVALID_CLASS_INSTALLER            $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 20D bitor bitor ]
+CONSTANT: ERROR_DI_DO_DEFAULT                      $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 20E bitor bitor ]
+CONSTANT: ERROR_DI_NOFILECOPY                      $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 20F bitor bitor ]
+CONSTANT: ERROR_INVALID_HWPROFILE                  $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 210 bitor bitor ]
+CONSTANT: ERROR_NO_DEVICE_SELECTED                 $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 211 bitor bitor ]
+CONSTANT: ERROR_DEVINFO_LIST_LOCKED                $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 212 bitor bitor ]
+CONSTANT: ERROR_DEVINFO_DATA_LOCKED                $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 213 bitor bitor ]
+CONSTANT: ERROR_DI_BAD_PATH                        $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 214 bitor bitor ]
+CONSTANT: ERROR_NO_CLASSINSTALL_PARAMS             $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 215 bitor bitor ]
+CONSTANT: ERROR_FILEQUEUE_LOCKED                   $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 216 bitor bitor ]
+CONSTANT: ERROR_BAD_SERVICE_INSTALLSECT            $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 217 bitor bitor ]
+CONSTANT: ERROR_NO_CLASS_DRIVER_LIST               $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 218 bitor bitor ]
+CONSTANT: ERROR_NO_ASSOCIATED_SERVICE              $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 219 bitor bitor ]
+CONSTANT: ERROR_NO_DEFAULT_DEVICE_INTERFACE        $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 21A bitor bitor ]
+CONSTANT: ERROR_DEVICE_INTERFACE_ACTIVE            $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 21B bitor bitor ]
+CONSTANT: ERROR_DEVICE_INTERFACE_REMOVED           $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 21C bitor bitor ]
+CONSTANT: ERROR_BAD_INTERFACE_INSTALLSECT          $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 21D bitor bitor ]
+CONSTANT: ERROR_NO_SUCH_INTERFACE_CLASS            $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 21E bitor bitor ]
+CONSTANT: ERROR_INVALID_REFERENCE_STRING           $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 21F bitor bitor ]
+CONSTANT: ERROR_INVALID_MACHINENAME                $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 220 bitor bitor ]
+CONSTANT: ERROR_REMOTE_COMM_FAILURE                $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 221 bitor bitor ]
+CONSTANT: ERROR_MACHINE_UNAVAILABLE                $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 222 bitor bitor ]
+CONSTANT: ERROR_NO_CONFIGMGR_SERVICES              $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 223 bitor bitor ]
+CONSTANT: ERROR_INVALID_PROPPAGE_PROVIDER          $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 224 bitor bitor ]
+CONSTANT: ERROR_NO_SUCH_DEVICE_INTERFACE           $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 225 bitor bitor ]
+CONSTANT: ERROR_DI_POSTPROCESSING_REQUIRED         $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 226 bitor bitor ]
+CONSTANT: ERROR_INVALID_COINSTALLER                $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 227 bitor bitor ]
+CONSTANT: ERROR_NO_COMPAT_DRIVERS                  $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 228 bitor bitor ]
+CONSTANT: ERROR_NO_DEVICE_ICON                     $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 229 bitor bitor ]
+CONSTANT: ERROR_INVALID_INF_LOGCONFIG              $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 22A bitor bitor ]
+CONSTANT: ERROR_DI_DONT_INSTALL                    $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 22B bitor bitor ]
+CONSTANT: ERROR_INVALID_FILTER_DRIVER              $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 22C bitor bitor ]
+CONSTANT: ERROR_NON_WINDOWS_NT_DRIVER              $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 22D bitor bitor ]
+CONSTANT: ERROR_NON_WINDOWS_DRIVER                 $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 22E bitor bitor ]
+CONSTANT: ERROR_NO_CATALOG_FOR_OEM_INF             $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 22F bitor bitor ]
+CONSTANT: ERROR_DEVINSTALL_QUEUE_NONNATIVE         $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 230 bitor bitor ]
+CONSTANT: ERROR_NOT_DISABLEABLE                    $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 231 bitor bitor ]
+CONSTANT: ERROR_CANT_REMOVE_DEVINST                $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 232 bitor bitor ]
+CONSTANT: ERROR_INVALID_TARGET                     $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 233 bitor bitor ]
+CONSTANT: ERROR_DRIVER_NONNATIVE                   $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 234 bitor bitor ]
+CONSTANT: ERROR_IN_WOW64                           $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 235 bitor bitor ]
+CONSTANT: ERROR_SET_SYSTEM_RESTORE_POINT           $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 236 bitor bitor ]
+CONSTANT: ERROR_SCE_DISABLED                       $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 238 bitor bitor ]
+CONSTANT: ERROR_UNKNOWN_EXCEPTION                  $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 239 bitor bitor ]
+CONSTANT: ERROR_PNP_REGISTRY_ERROR                 $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 23A bitor bitor ]
+CONSTANT: ERROR_REMOTE_REQUEST_UNSUPPORTED         $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 23B bitor bitor ]
+CONSTANT: ERROR_NOT_AN_INSTALLED_OEM_INF           $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 23C bitor bitor ]
+CONSTANT: ERROR_INF_IN_USE_BY_DEVICES              $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 23D bitor bitor ]
+CONSTANT: ERROR_DI_FUNCTION_OBSOLETE               $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 23E bitor bitor ]
+CONSTANT: ERROR_NO_AUTHENTICODE_CATALOG            $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 23F bitor bitor ]
+CONSTANT: ERROR_AUTHENTICODE_DISALLOWED            $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 240 bitor bitor ]
+CONSTANT: ERROR_AUTHENTICODE_TRUSTED_PUBLISHER     $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 241 bitor bitor ]
+CONSTANT: ERROR_AUTHENTICODE_TRUST_NOT_ESTABLISHED $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 242 bitor bitor ]
+CONSTANT: ERROR_AUTHENTICODE_PUBLISHER_NOT_TRUSTED $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 243 bitor bitor ]
+CONSTANT: ERROR_SIGNATURE_OSATTRIBUTE_MISMATCH     $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 244 bitor bitor ]
+CONSTANT: ERROR_ONLY_VALIDATE_VIA_AUTHENTICODE     $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 245 bitor bitor ]
+CONSTANT: ERROR_DEVICE_INSTALLER_NOT_READY         $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 246 bitor bitor ]
+CONSTANT: ERROR_DRIVER_STORE_ADD_FAILED            $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 247 bitor bitor ]
+CONSTANT: ERROR_DEVICE_INSTALL_BLOCKED             $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 248 bitor bitor ]
+CONSTANT: ERROR_DRIVER_INSTALL_BLOCKED             $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 249 bitor bitor ]
+CONSTANT: ERROR_WRONG_INF_TYPE                     $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 24A bitor bitor ]
+CONSTANT: ERROR_FILE_HASH_NOT_IN_CATALOG           $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 24B bitor bitor ]
+CONSTANT: ERROR_DRIVER_STORE_DELETE_FAILED         $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 24C bitor bitor ]
+CONSTANT: ERROR_UNRECOVERABLE_STACK_OVERFLOW $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 300 bitor bitor ]
+CONSTANT: EXCEPTION_SPAPI_UNRECOVERABLE_STACK_OVERFLOW $ ERROR_UNRECOVERABLE_STACK_OVERFLOW
+CONSTANT: ERROR_NO_DEFAULT_INTERFACE_DEVICE $ ERROR_NO_DEFAULT_DEVICE_INTERFACE
+CONSTANT: ERROR_INTERFACE_DEVICE_ACTIVE     $ ERROR_DEVICE_INTERFACE_ACTIVE
+CONSTANT: ERROR_INTERFACE_DEVICE_REMOVED    $ ERROR_DEVICE_INTERFACE_REMOVED
+CONSTANT: ERROR_NO_SUCH_INTERFACE_DEVICE    $ ERROR_NO_SUCH_DEVICE_INTERFACE
+CONSTANT: ERROR_NOT_INSTALLED $[ APPLICATION_ERROR_MASK ERROR_SEVERITY_ERROR HEX: 1000 bitor bitor ]
+
+FUNCTION: BOOL SetupGetInfInformationA ( LPCVOID InfSpec, DWORD SearchControl, PSP_INF_INFORMATION ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupGetInfInformationW ( LPCVOID InfSpec, DWORD SearchControl, PSP_INF_INFORMATION ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+CONSTANT: INFINFO_INF_SPEC_IS_HINF        1
+CONSTANT: INFINFO_INF_NAME_IS_ABSOLUTE    2
+CONSTANT: INFINFO_DEFAULT_SEARCH          3
+CONSTANT: INFINFO_REVERSE_DEFAULT_SEARCH  4
+CONSTANT: INFINFO_INF_PATH_LIST_SEARCH    5
+ALIAS: SetupGetInfInformation SetupGetInfInformationW
+
+FUNCTION: BOOL SetupQueryInfFileInformationA ( PSP_INF_INFORMATION InfInformation, UINT InfIndex, PSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupQueryInfFileInformationW ( PSP_INF_INFORMATION InfInformation, UINT InfIndex, PWSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+ALIAS: SetupQueryInfFileInformation SetupQueryInfFileInformationW
+
+FUNCTION: BOOL SetupQueryInfOriginalFileInformationA ( PSP_INF_INFORMATION InfInformation, UINT InfIndex, PSP_ALTPLATFORM_INFO AlternatePlatformInfo, PSP_ORIGINAL_FILE_INFO_A OriginalFileInfo ) ;
+FUNCTION: BOOL SetupQueryInfOriginalFileInformationW ( PSP_INF_INFORMATION InfInformation, UINT InfIndex, PSP_ALTPLATFORM_INFO AlternatePlatformInfo, PSP_ORIGINAL_FILE_INFO_W OriginalFileInfo ) ;
+ALIAS: SetupQueryInfOriginalFileInformation SetupQueryInfOriginalFileInformationW
+
+FUNCTION: BOOL SetupQueryInfVersionInformationA ( PSP_INF_INFORMATION InfInformation, UINT InfIndex, PCSTR Key, PSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupQueryInfVersionInformationW ( PSP_INF_INFORMATION InfInformation, UINT InfIndex, PCWSTR Key, PWSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+ALIAS: SetupQueryInfVersionInformation SetupQueryInfVersionInformationW
+
+FUNCTION: BOOL SetupGetInfDriverStoreLocationA ( PCSTR FileName, PSP_ALTPLATFORM_INFO AlternatePlatformInfo, PCSTR LocaleName, PSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupGetInfDriverStoreLocationW ( PCWSTR FileName, PSP_ALTPLATFORM_INFO AlternatePlatformInfo, PCWSTR LocaleName, PWSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+ALIAS: SetupGetInfDriverStoreLocation SetupGetInfDriverStoreLocationW
+
+FUNCTION: BOOL SetupGetInfPublishedNameA ( PCSTR DriverStoreLocation, PSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupGetInfPublishedNameW ( PCWSTR DriverStoreLocation, PWSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+ALIAS: SetupGetInfPublishedName SetupGetInfPublishedNameW
+
+FUNCTION: BOOL SetupGetInfFileListA ( PCSTR DirectoryPath, DWORD InfStyle, PSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupGetInfFileListW ( PCWSTR DirectoryPath, DWORD InfStyle, PWSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+ALIAS: SetupGetInfFileList SetupGetInfFileListW
+
+FUNCTION: HINF SetupOpenInfFileW ( PCWSTR FileName, PCWSTR InfClass, DWORD InfStyle, PUINT ErrorLine ) ;
+FUNCTION: HINF SetupOpenInfFileA ( PCSTR FileName, PCSTR InfClass, DWORD InfStyle, PUINT ErrorLine ) ;
+ALIAS: SetupOpenInfFile SetupOpenInfFileW
+
+FUNCTION: HINF SetupOpenMasterInf ( ) ;
+
+FUNCTION: BOOL SetupOpenAppendInfFileW ( PCWSTR FileName, HINF InfHandle, PUINT ErrorLine ) ;
+FUNCTION: BOOL SetupOpenAppendInfFileA ( PCSTR FileName, HINF InfHandle, PUINT ErrorLine ) ;
+ALIAS: SetupOpenAppendInfFile SetupOpenAppendInfFileW
+
+FUNCTION: void SetupCloseInfFile ( HINF InfHandle ) ;
+FUNCTION: BOOL SetupFindFirstLineA ( HINF InfHandle, PCSTR Section, PCSTR Key, PINFCONTEXT Context ) ;
+FUNCTION: BOOL SetupFindFirstLineW ( HINF InfHandle, PCWSTR Section, PCWSTR Key, PINFCONTEXT Context ) ;
+ALIAS: SetupFindFirstLine SetupFindFirstLineW
+
+FUNCTION: BOOL SetupFindNextLine ( PINFCONTEXT ContextIn, PINFCONTEXT ContextOut ) ;
+FUNCTION: BOOL SetupFindNextMatchLineA ( PINFCONTEXT ContextIn, PCSTR Key, PINFCONTEXT ContextOut ) ;
+FUNCTION: BOOL SetupFindNextMatchLineW ( PINFCONTEXT ContextIn, PCWSTR Key, PINFCONTEXT ContextOut ) ;
+ALIAS: SetupFindNextMatchLine SetupFindNextMatchLineW
+
+FUNCTION: BOOL SetupGetLineByIndexA ( HINF InfHandle, PCSTR Section, DWORD Index, PINFCONTEXT Context ) ;
+FUNCTION: BOOL SetupGetLineByIndexW ( HINF InfHandle, PCWSTR Section, DWORD Index, PINFCONTEXT Context ) ;
+ALIAS: SetupGetLineByIndex SetupGetLineByIndexW
+
+FUNCTION: LONG SetupGetLineCountA ( HINF InfHandle, PCSTR Section ) ;
+FUNCTION: LONG SetupGetLineCountW ( HINF InfHandle, PCWSTR Section ) ;
+ALIAS: SetupGetLineCount SetupGetLineCountW
+
+FUNCTION: BOOL SetupGetLineTextA ( PINFCONTEXT Context, HINF InfHandle, PCSTR Section, PCSTR Key, PSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupGetLineTextW ( PINFCONTEXT Context, HINF InfHandle, PCWSTR Section, PCWSTR Key, PWSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+ALIAS: SetupGetLineText SetupGetLineTextW
+
+FUNCTION: DWORD SetupGetFieldCount ( PINFCONTEXT Context ) ;
+FUNCTION: BOOL SetupGetStringFieldA ( PINFCONTEXT Context, DWORD FieldIndex, PSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupGetStringFieldW ( PINFCONTEXT Context, DWORD FieldIndex, PWSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+ALIAS: SetupGetStringField SetupGetStringFieldW
+
+FUNCTION: BOOL SetupGetIntField ( PINFCONTEXT Context, DWORD FieldIndex, PINT IntegerValue ) ;
+FUNCTION: BOOL SetupGetMultiSzFieldA ( PINFCONTEXT Context, DWORD FieldIndex, PSTR ReturnBuffer, DWORD ReturnBufferSize, LPDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupGetMultiSzFieldW ( PINFCONTEXT Context, DWORD FieldIndex, PWSTR ReturnBuffer, DWORD ReturnBufferSize, LPDWORD RequiredSize ) ;
+ALIAS: SetupGetMultiSzField SetupGetMultiSzFieldW
+
+FUNCTION: BOOL SetupGetBinaryField ( PINFCONTEXT Context, DWORD FieldIndex, PBYTE ReturnBuffer, DWORD ReturnBufferSize, LPDWORD RequiredSize ) ;
+FUNCTION: DWORD SetupGetFileCompressionInfoA ( PCSTR SourceFileName, PSTR* ActualSourceFileName, PDWORD SourceFileSize, PDWORD TargetFileSize, PUINT CompressionType ) ;
+FUNCTION: DWORD SetupGetFileCompressionInfoW ( PCWSTR SourceFileName, PWSTR* ActualSourceFileName, PDWORD SourceFileSize, PDWORD TargetFileSize, PUINT CompressionType ) ;
+ALIAS: SetupGetFileCompressionInfo SetupGetFileCompressionInfoW
+
+FUNCTION: BOOL SetupGetFileCompressionInfoExA ( PCSTR SourceFileName, PSTR ActualSourceFileNameBuffer, DWORD ActualSourceFileNameBufferLen, PDWORD RequiredBufferLen, PDWORD SourceFileSize, PDWORD TargetFileSize, PUINT CompressionType ) ;
+FUNCTION: BOOL SetupGetFileCompressionInfoExW ( PCWSTR SourceFileName, PWSTR ActualSourceFileNameBuffer, DWORD ActualSourceFileNameBufferLen, PDWORD RequiredBufferLen, PDWORD SourceFileSize, PDWORD TargetFileSize, PUINT CompressionType ) ;
+ALIAS: SetupGetFileCompressionInfoEx SetupGetFileCompressionInfoExW
+
+CONSTANT: FILE_COMPRESSION_NONE       0
+CONSTANT: FILE_COMPRESSION_WINLZA     1
+CONSTANT: FILE_COMPRESSION_MSZIP      2
+CONSTANT: FILE_COMPRESSION_NTCAB      3
+
+FUNCTION: DWORD SetupDecompressOrCopyFileA ( PCSTR SourceFileName, PCSTR TargetFileName, PUINT CompressionType ) ;
+FUNCTION: DWORD SetupDecompressOrCopyFileW ( PCWSTR SourceFileName, PCWSTR TargetFileName, PUINT CompressionType ) ;
+ALIAS: SetupDecompressOrCopyFile SetupDecompressOrCopyFileW
+
+FUNCTION: BOOL SetupGetSourceFileLocationA ( HINF InfHandle, PINFCONTEXT InfContext, PCSTR FileName, PUINT SourceId, PSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupGetSourceFileLocationW ( HINF InfHandle, PINFCONTEXT InfContext, PCWSTR FileName, PUINT SourceId, PWSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+ALIAS: SetupGetSourceFileLocation SetupGetSourceFileLocationW
+
+FUNCTION: BOOL SetupGetSourceFileSizeA ( HINF InfHandle, PINFCONTEXT InfContext, PCSTR FileName, PCSTR Section, PDWORD FileSize, UINT RoundingFactor ) ;
+FUNCTION: BOOL SetupGetSourceFileSizeW ( HINF InfHandle, PINFCONTEXT InfContext, PCWSTR FileName, PCWSTR Section, PDWORD FileSize, UINT RoundingFactor ) ;
+ALIAS: SetupGetSourceFileSize SetupGetSourceFileSizeW
+
+FUNCTION: BOOL SetupGetTargetPathA ( HINF InfHandle, PINFCONTEXT InfContext, PCSTR Section, PSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupGetTargetPathW ( HINF InfHandle, PINFCONTEXT InfContext, PCWSTR Section, PWSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+ALIAS: SetupGetTargetPath SetupGetTargetPathW
+
+CONSTANT: SRCLIST_TEMPORARY       HEX: 00000001
+CONSTANT: SRCLIST_NOBROWSE        HEX: 00000002
+CONSTANT: SRCLIST_SYSTEM          HEX: 00000010
+CONSTANT: SRCLIST_USER            HEX: 00000020
+CONSTANT: SRCLIST_SYSIFADMIN      HEX: 00000040
+CONSTANT: SRCLIST_SUBDIRS         HEX: 00000100
+CONSTANT: SRCLIST_APPEND          HEX: 00000200
+CONSTANT: SRCLIST_NOSTRIPPLATFORM HEX: 00000400
+
+FUNCTION: BOOL SetupSetSourceListA ( DWORD Flags, PCSTR* SourceList, UINT SourceCount ) ;
+FUNCTION: BOOL SetupSetSourceListW ( DWORD Flags, PCWSTR* SourceList, UINT SourceCount ) ;
+ALIAS: SetupSetSourceList SetupSetSourceListW
+
+FUNCTION: BOOL SetupCancelTemporarySourceList( ) ;
+FUNCTION: BOOL SetupAddToSourceListA ( DWORD Flags, PCSTR Source ) ;
+FUNCTION: BOOL SetupAddToSourceListW ( DWORD Flags, PCWSTR Source ) ;
+ALIAS: SetupAddToSourceList SetupAddToSourceListW
+
+FUNCTION: BOOL SetupRemoveFromSourceListA ( DWORD Flags, PCSTR Source ) ;
+FUNCTION: BOOL SetupRemoveFromSourceListW ( DWORD Flags, PCWSTR Source ) ;
+ALIAS: SetupRemoveFromSourceList SetupRemoveFromSourceListW
+
+FUNCTION: BOOL SetupQuerySourceListA ( DWORD Flags, PCSTR** List, PUINT Count ) ;
+FUNCTION: BOOL SetupQuerySourceListW ( DWORD Flags, PCWSTR** List, PUINT Count ) ;
+ALIAS: SetupQuerySourceList SetupQuerySourceListW
+
+FUNCTION: BOOL SetupFreeSourceListA ( PCSTR** List, UINT Count ) ;
+FUNCTION: BOOL SetupFreeSourceListW ( PCWSTR** List, UINT Count ) ;
+ALIAS: SetupFreeSourceList SetupFreeSourceListW
+
+FUNCTION: UINT SetupPromptForDiskA ( HWND hwndParent, PCSTR DialogTitle, PCSTR DiskName, PCSTR PathToSource, PCSTR FileSought, PCSTR TagFile, DWORD DiskPromptStyle, PSTR PathBuffer, DWORD PathBufferSize, PDWORD PathRequiredSize ) ;
+FUNCTION: UINT SetupPromptForDiskW ( HWND hwndParent, PCWSTR DialogTitle, PCWSTR DiskName, PCWSTR PathToSource, PCWSTR FileSought, PCWSTR TagFile, DWORD DiskPromptStyle, PWSTR PathBuffer, DWORD PathBufferSize, PDWORD PathRequiredSize ) ;
+ALIAS: SetupPromptForDisk SetupPromptForDiskW
+
+FUNCTION: UINT SetupCopyErrorA ( HWND hwndParent, PCSTR DialogTitle, PCSTR DiskName, PCSTR PathToSource, PCSTR SourceFile, PCSTR TargetPathFile, UINT Win32ErrorCode, DWORD Style, PSTR PathBuffer, DWORD PathBufferSize, PDWORD PathRequiredSize ) ;
+FUNCTION: UINT SetupCopyErrorW ( HWND hwndParent, PCWSTR DialogTitle, PCWSTR DiskName, PCWSTR PathToSource, PCWSTR SourceFile, PCWSTR TargetPathFile, UINT Win32ErrorCode, DWORD Style, PWSTR PathBuffer, DWORD PathBufferSize, PDWORD PathRequiredSize ) ;
+ALIAS: SetupCopyError SetupCopyErrorW
+
+FUNCTION: UINT SetupRenameErrorA ( HWND hwndParent, PCSTR DialogTitle, PCSTR SourceFile, PCSTR TargetFile, UINT Win32ErrorCode, DWORD Style ) ;
+FUNCTION: UINT SetupRenameErrorW ( HWND hwndParent, PCWSTR DialogTitle, PCWSTR SourceFile, PCWSTR TargetFile, UINT Win32ErrorCode, DWORD Style ) ;
+ALIAS: SetupRenameError SetupRenameErrorW
+
+FUNCTION: UINT SetupDeleteErrorA ( HWND hwndParent, PCSTR DialogTitle, PCSTR File, UINT Win32ErrorCode, DWORD Style ) ;
+FUNCTION: UINT SetupDeleteErrorW ( HWND hwndParent, PCWSTR DialogTitle, PCWSTR File, UINT Win32ErrorCode, DWORD Style ) ;
+ALIAS: SetupDeleteError SetupDeleteErrorW
+
+FUNCTION: UINT SetupBackupErrorA ( HWND hwndParent, PCSTR DialogTitle, PCSTR SourceFile, PCSTR TargetFile, UINT Win32ErrorCode, DWORD Style ) ;
+FUNCTION: UINT SetupBackupErrorW ( HWND hwndParent, PCWSTR DialogTitle, PCWSTR SourceFile, PCWSTR TargetFile, UINT Win32ErrorCode, DWORD Style ) ;
+ALIAS: SetupBackupError SetupBackupErrorW
+
+CONSTANT: IDF_NOBROWSE                    HEX: 00000001
+CONSTANT: IDF_NOSKIP                      HEX: 00000002
+CONSTANT: IDF_NODETAILS                   HEX: 00000004
+CONSTANT: IDF_NOCOMPRESSED                HEX: 00000008
+CONSTANT: IDF_CHECKFIRST                  HEX: 00000100
+CONSTANT: IDF_NOBEEP                      HEX: 00000200
+CONSTANT: IDF_NOFOREGROUND                HEX: 00000400
+CONSTANT: IDF_WARNIFSKIP                  HEX: 00000800
+CONSTANT: IDF_NOREMOVABLEMEDIAPROMPT      HEX: 00001000
+CONSTANT: IDF_USEDISKNAMEASPROMPT         HEX: 00002000
+CONSTANT: IDF_OEMDISK                     HEX: 80000000
+
+CONSTANT: DPROMPT_SUCCESS         0
+CONSTANT: DPROMPT_CANCEL          1
+CONSTANT: DPROMPT_SKIPFILE        2
+CONSTANT: DPROMPT_BUFFERTOOSMALL  3
+CONSTANT: DPROMPT_OUTOFMEMORY     4
+
+FUNCTION: BOOL SetupSetDirectoryIdA ( HINF InfHandle, DWORD Id, PCSTR Directory ) ;
+FUNCTION: BOOL SetupSetDirectoryIdW ( HINF InfHandle, DWORD Id, PCWSTR Directory ) ;
+ALIAS: SetupSetDirectoryId SetupSetDirectoryIdW
+
+FUNCTION: BOOL SetupSetDirectoryIdExA ( HINF InfHandle, DWORD Id, PCSTR Directory, DWORD Flags, DWORD Reserved1, PVOID Reserved2 ) ;
+FUNCTION: BOOL SetupSetDirectoryIdExW ( HINF InfHandle, DWORD Id, PCWSTR Directory, DWORD Flags, DWORD Reserved1, PVOID Reserved2 ) ;
+ALIAS: SetupSetDirectoryIdEx SetupSetDirectoryIdExW
+
+CONSTANT: SETDIRID_NOT_FULL_PATH      HEX: 00000001
+
+FUNCTION: BOOL SetupGetSourceInfoA ( HINF InfHandle, UINT SourceId, UINT InfoDesired, PSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupGetSourceInfoW ( HINF InfHandle, UINT SourceId, UINT InfoDesired, PWSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+ALIAS: SetupGetSourceInfo SetupGetSourceInfoW
+
+CONSTANT: SRCINFO_PATH            1
+CONSTANT: SRCINFO_TAGFILE         2
+CONSTANT: SRCINFO_DESCRIPTION     3
+CONSTANT: SRCINFO_FLAGS           4
+CONSTANT: SRCINFO_TAGFILE2        5
+CONSTANT: SRC_FLAGS_CABFILE       HEX: 0010
+
+FUNCTION: BOOL SetupInstallFileA ( HINF InfHandle, PINFCONTEXT InfContext, PCSTR SourceFile, PCSTR SourcePathRoot, PCSTR DestinationName, DWORD CopyStyle, PSP_FILE_CALLBACK_A CopyMsgHandler, PVOID Context ) ;
+FUNCTION: BOOL SetupInstallFileW ( HINF InfHandle, PINFCONTEXT InfContext, PCWSTR SourceFile, PCWSTR SourcePathRoot, PCWSTR DestinationName, DWORD CopyStyle, PSP_FILE_CALLBACK_W CopyMsgHandler, PVOID Context ) ;
+ALIAS: SetupInstallFile SetupInstallFileW
+
+FUNCTION: BOOL SetupInstallFileExA ( HINF InfHandle, PINFCONTEXT InfContext, PCSTR SourceFile, PCSTR SourcePathRoot, PCSTR DestinationName, DWORD CopyStyle, PSP_FILE_CALLBACK_A CopyMsgHandler, PVOID Context, PBOOL FileWasInUse ) ;
+FUNCTION: BOOL SetupInstallFileExW ( HINF InfHandle, PINFCONTEXT InfContext, PCWSTR SourceFile, PCWSTR SourcePathRoot, PCWSTR DestinationName, DWORD CopyStyle, PSP_FILE_CALLBACK_W CopyMsgHandler, PVOID Context, PBOOL FileWasInUse ) ;
+ALIAS: SetupInstallFileEx SetupInstallFileExW
+
+CONSTANT: SP_COPY_DELETESOURCE        HEX: 0000001
+CONSTANT: SP_COPY_REPLACEONLY         HEX: 0000002
+CONSTANT: SP_COPY_NEWER               HEX: 0000004
+CONSTANT: SP_COPY_NEWER_OR_SAME       $ SP_COPY_NEWER
+CONSTANT: SP_COPY_NOOVERWRITE         HEX: 0000008
+CONSTANT: SP_COPY_NODECOMP            HEX: 0000010
+CONSTANT: SP_COPY_LANGUAGEAWARE       HEX: 0000020
+CONSTANT: SP_COPY_SOURCE_ABSOLUTE     HEX: 0000040
+CONSTANT: SP_COPY_SOURCEPATH_ABSOLUTE HEX: 0000080
+CONSTANT: SP_COPY_IN_USE_NEEDS_REBOOT HEX: 0000100
+CONSTANT: SP_COPY_FORCE_IN_USE        HEX: 0000200
+CONSTANT: SP_COPY_NOSKIP              HEX: 0000400
+CONSTANT: SP_FLAG_CABINETCONTINUATION HEX: 0000800
+CONSTANT: SP_COPY_FORCE_NOOVERWRITE   HEX: 0001000
+CONSTANT: SP_COPY_FORCE_NEWER         HEX: 0002000
+CONSTANT: SP_COPY_WARNIFSKIP          HEX: 0004000
+CONSTANT: SP_COPY_NOBROWSE            HEX: 0008000
+CONSTANT: SP_COPY_NEWER_ONLY          HEX: 0010000
+CONSTANT: SP_COPY_RESERVED            HEX: 0020000
+CONSTANT: SP_COPY_OEMINF_CATALOG_ONLY HEX: 0040000
+CONSTANT: SP_COPY_REPLACE_BOOT_FILE   HEX: 0080000
+CONSTANT: SP_COPY_NOPRUNE             HEX: 0100000
+CONSTANT: SP_COPY_OEM_F6_INF          HEX: 0200000
+CONSTANT: SP_COPY_ALREADYDECOMP       HEX: 0400000
+CONSTANT: SP_COPY_WINDOWS_SIGNED      HEX: 1000000
+CONSTANT: SP_COPY_PNPLOCKED           HEX: 2000000
+CONSTANT: SP_COPY_IN_USE_TRY_RENAME   HEX: 4000000
+CONSTANT: SP_COPY_INBOX_INF           HEX: 8000000
+CONSTANT: SP_COPY_HARDLINK            HEX: 10000000
+
+CONSTANT: SP_BACKUP_BACKUPPASS        HEX: 00000001
+CONSTANT: SP_BACKUP_DEMANDPASS        HEX: 00000002
+CONSTANT: SP_BACKUP_SPECIAL           HEX: 00000004
+CONSTANT: SP_BACKUP_BOOTFILE          HEX: 00000008
+
+FUNCTION: HSPFILEQ SetupOpenFileQueue ( ) ;
+FUNCTION: BOOL SetupCloseFileQueue ( HSPFILEQ QueueHandle ) ;
+FUNCTION: BOOL SetupSetFileQueueAlternatePlatformA ( HSPFILEQ QueueHandle, PSP_ALTPLATFORM_INFO AlternatePlatformInfo, PCSTR AlternateDefaultCatalogFile ) ;
+FUNCTION: BOOL SetupSetFileQueueAlternatePlatformW ( HSPFILEQ QueueHandle, PSP_ALTPLATFORM_INFO AlternatePlatformInfo, PCWSTR AlternateDefaultCatalogFile ) ;
+ALIAS: SetupSetFileQueueAlternatePlatform SetupSetFileQueueAlternatePlatformW
+
+FUNCTION: BOOL SetupSetPlatformPathOverrideA ( PCSTR Override ) ;
+FUNCTION: BOOL SetupSetPlatformPathOverrideW ( PCWSTR Override ) ;
+ALIAS: SetupSetPlatformPathOverride SetupSetPlatformPathOverrideW
+
+FUNCTION: BOOL SetupQueueCopyA ( HSPFILEQ QueueHandle, PCSTR SourceRootPath, PCSTR SourcePath, PCSTR SourceFilename, PCSTR SourceDescription, PCSTR SourceTagfile, PCSTR TargetDirectory, PCSTR TargetFilename, DWORD CopyStyle ) ;
+FUNCTION: BOOL SetupQueueCopyW ( HSPFILEQ QueueHandle, PCWSTR SourceRootPath, PCWSTR SourcePath, PCWSTR SourceFilename, PCWSTR SourceDescription, PCWSTR SourceTagfile, PCWSTR TargetDirectory, PCWSTR TargetFilename, DWORD CopyStyle ) ;
+ALIAS: SetupQueueCopy SetupQueueCopyW
+
+FUNCTION: BOOL SetupQueueCopyIndirectA ( PSP_FILE_COPY_PARAMS_A CopyParams ) ;
+FUNCTION: BOOL SetupQueueCopyIndirectW ( PSP_FILE_COPY_PARAMS_W CopyParams ) ;
+ALIAS: SetupQueueCopyIndirect SetupQueueCopyIndirectW
+
+FUNCTION: BOOL SetupQueueDefaultCopyA ( HSPFILEQ QueueHandle, HINF InfHandle, PCSTR SourceRootPath, PCSTR SourceFilename, PCSTR TargetFilename, DWORD CopyStyle ) ;
+FUNCTION: BOOL SetupQueueDefaultCopyW ( HSPFILEQ QueueHandle, HINF InfHandle, PCWSTR SourceRootPath, PCWSTR SourceFilename, PCWSTR TargetFilename, DWORD CopyStyle ) ;
+ALIAS: SetupQueueDefaultCopy SetupQueueDefaultCopyW
+
+FUNCTION: BOOL SetupQueueCopySectionA ( HSPFILEQ QueueHandle, PCSTR SourceRootPath, HINF InfHandle, HINF ListInfHandle, PCSTR Section, DWORD CopyStyle ) ;
+FUNCTION: BOOL SetupQueueCopySectionW ( HSPFILEQ QueueHandle, PCWSTR SourceRootPath, HINF InfHandle, HINF ListInfHandle, PCWSTR Section, DWORD CopyStyle ) ;
+ALIAS: SetupQueueCopySection SetupQueueCopySectionW
+
+FUNCTION: BOOL SetupQueueDeleteA ( HSPFILEQ QueueHandle, PCSTR PathPart1, PCSTR PathPart2 ) ;
+FUNCTION: BOOL SetupQueueDeleteW ( HSPFILEQ QueueHandle, PCWSTR PathPart1, PCWSTR PathPart2 ) ;
+ALIAS: SetupQueueDelete SetupQueueDeleteW
+
+FUNCTION: BOOL SetupQueueDeleteSectionA ( HSPFILEQ QueueHandle, HINF InfHandle, HINF ListInfHandle, PCSTR Section ) ;
+FUNCTION: BOOL SetupQueueDeleteSectionW ( HSPFILEQ QueueHandle, HINF InfHandle, HINF ListInfHandle, PCWSTR Section ) ;
+ALIAS: SetupQueueDeleteSection SetupQueueDeleteSectionW
+
+FUNCTION: BOOL SetupQueueRenameA ( HSPFILEQ QueueHandle, PCSTR SourcePath, PCSTR SourceFilename, PCSTR TargetPath, PCSTR TargetFilename ) ;
+FUNCTION: BOOL SetupQueueRenameW ( HSPFILEQ QueueHandle, PCWSTR SourcePath, PCWSTR SourceFilename, PCWSTR TargetPath, PCWSTR TargetFilename ) ;
+ALIAS: SetupQueueRename SetupQueueRenameW
+
+FUNCTION: BOOL SetupQueueRenameSectionA ( HSPFILEQ QueueHandle, HINF InfHandle, HINF ListInfHandle, PCSTR Section ) ;
+FUNCTION: BOOL SetupQueueRenameSectionW ( HSPFILEQ QueueHandle, HINF InfHandle, HINF ListInfHandle, PCWSTR Section ) ;
+ALIAS: SetupQueueRenameSection SetupQueueRenameSectionW
+
+FUNCTION: BOOL SetupCommitFileQueueA ( HWND Owner, HSPFILEQ QueueHandle, PSP_FILE_CALLBACK_A MsgHandler, PVOID Context ) ;
+FUNCTION: BOOL SetupCommitFileQueueW ( HWND Owner, HSPFILEQ QueueHandle, PSP_FILE_CALLBACK_W MsgHandler, PVOID Context ) ;
+ALIAS: SetupCommitFileQueue SetupCommitFileQueueW
+
+FUNCTION: BOOL SetupScanFileQueueA ( HSPFILEQ FileQueue, DWORD Flags, HWND Window, PSP_FILE_CALLBACK_A CallbackRoutine, PVOID CallbackContext, PDWORD Result ) ;
+FUNCTION: BOOL SetupScanFileQueueW ( HSPFILEQ FileQueue, DWORD Flags, HWND Window, PSP_FILE_CALLBACK_W CallbackRoutine, PVOID CallbackContext, PDWORD Result ) ;
+ALIAS: SetupScanFileQueue SetupScanFileQueueW
+
+CONSTANT: SPQ_SCAN_FILE_PRESENCE                  HEX: 00000001
+CONSTANT: SPQ_SCAN_FILE_VALIDITY                  HEX: 00000002
+CONSTANT: SPQ_SCAN_USE_CALLBACK                   HEX: 00000004
+CONSTANT: SPQ_SCAN_USE_CALLBACKEX                 HEX: 00000008
+CONSTANT: SPQ_SCAN_INFORM_USER                    HEX: 00000010
+CONSTANT: SPQ_SCAN_PRUNE_COPY_QUEUE               HEX: 00000020
+CONSTANT: SPQ_SCAN_USE_CALLBACK_SIGNERINFO        HEX: 00000040
+CONSTANT: SPQ_SCAN_PRUNE_DELREN                   HEX: 00000080
+CONSTANT: SPQ_SCAN_FILE_PRESENCE_WITHOUT_SOURCE   HEX: 00000100
+CONSTANT: SPQ_SCAN_FILE_COMPARISON                HEX: 00000200
+CONSTANT: SPQ_SCAN_ACTIVATE_DRP                   HEX: 00000400
+CONSTANT: SPQ_DELAYED_COPY                        HEX: 00000001
+
+FUNCTION: BOOL SetupGetFileQueueCount ( HSPFILEQ FileQueue, UINT SubQueueFileOp, PUINT NumOperations ) ;
+FUNCTION: BOOL SetupGetFileQueueFlags ( HSPFILEQ FileQueue, PDWORD Flags ) ;
+FUNCTION: BOOL SetupSetFileQueueFlags ( HSPFILEQ FileQueue, DWORD FlagMask, DWORD Flags ) ;
+
+CONSTANT: SPQ_FLAG_BACKUP_AWARE      HEX: 00000001
+CONSTANT: SPQ_FLAG_ABORT_IF_UNSIGNED HEX: 00000002
+CONSTANT: SPQ_FLAG_FILES_MODIFIED    HEX: 00000004
+CONSTANT: SPQ_FLAG_DO_SHUFFLEMOVE    HEX: 00000008
+CONSTANT: SPQ_FLAG_VALID             HEX: 0000000F
+
+CONSTANT: SPOST_NONE  0
+CONSTANT: SPOST_PATH  1
+CONSTANT: SPOST_URL   2
+CONSTANT: SPOST_MAX   3
+
+FUNCTION: BOOL SetupCopyOEMInfA ( PCSTR SourceInfFileName, PCSTR OEMSourceMediaLocation, DWORD OEMSourceMediaType, DWORD CopyStyle, PSTR DestinationInfFileName, DWORD DestinationInfFileNameSize, PDWORD RequiredSize, PSTR* DestinationInfFileNameComponent ) ;
+FUNCTION: BOOL SetupCopyOEMInfW ( PCWSTR SourceInfFileName, PCWSTR OEMSourceMediaLocation, DWORD OEMSourceMediaType, DWORD CopyStyle, PWSTR DestinationInfFileName, DWORD DestinationInfFileNameSize, PDWORD RequiredSize, PWSTR* DestinationInfFileNameComponent ) ;
+ALIAS: SetupCopyOEMInf SetupCopyOEMInfW
+
+CONSTANT: SUOI_FORCEDELETE   HEX: 00000001
+CONSTANT: SUOI_INTERNAL1     HEX: 00000002
+
+FUNCTION: BOOL SetupUninstallOEMInfA ( PCSTR InfFileName, DWORD Flags, PVOID Reserved ) ;
+FUNCTION: BOOL SetupUninstallOEMInfW ( PCWSTR InfFileName, DWORD Flags, PVOID Reserved ) ;
+ALIAS: SetupUninstallOEMInf SetupUninstallOEMInfW
+
+FUNCTION: BOOL SetupUninstallNewlyCopiedInfs( HSPFILEQ FileQueue, DWORD Flags, PVOID Reserved ) ;
+
+FUNCTION: HDSKSPC SetupCreateDiskSpaceListA ( PVOID Reserved1, DWORD Reserved2, UINT Flags ) ;
+FUNCTION: HDSKSPC SetupCreateDiskSpaceListW ( PVOID Reserved1, DWORD Reserved2, UINT Flags ) ;
+ALIAS: SetupCreateDiskSpaceList SetupCreateDiskSpaceListW
+
+CONSTANT: SPDSL_IGNORE_DISK              HEX: 00000001
+CONSTANT: SPDSL_DISALLOW_NEGATIVE_ADJUST HEX: 00000002
+
+FUNCTION: HDSKSPC SetupDuplicateDiskSpaceListA ( HDSKSPC DiskSpace, PVOID Reserved1, DWORD Reserved2, UINT Flags ) ;
+FUNCTION: HDSKSPC SetupDuplicateDiskSpaceListW ( HDSKSPC DiskSpace, PVOID Reserved1, DWORD Reserved2, UINT Flags ) ;
+ALIAS: SetupDuplicateDiskSpaceList SetupDuplicateDiskSpaceListW
+
+FUNCTION: BOOL SetupDestroyDiskSpaceList( HDSKSPC DiskSpace ) ;
+FUNCTION: BOOL SetupQueryDrivesInDiskSpaceListA ( HDSKSPC DiskSpace, PSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupQueryDrivesInDiskSpaceListW ( HDSKSPC DiskSpace, PWSTR ReturnBuffer, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+ALIAS: SetupQueryDrivesInDiskSpaceList SetupQueryDrivesInDiskSpaceListW
+
+FUNCTION: BOOL SetupQuerySpaceRequiredOnDriveA ( HDSKSPC DiskSpace, PCSTR DriveSpec, LONGLONG* SpaceRequired, PVOID Reserved1, UINT Reserved2 ) ;
+FUNCTION: BOOL SetupQuerySpaceRequiredOnDriveW ( HDSKSPC DiskSpace, PCWSTR DriveSpec, LONGLONG* SpaceRequired, PVOID Reserved1, UINT Reserved2 ) ;
+ALIAS: SetupQuerySpaceRequiredOnDrive SetupQuerySpaceRequiredOnDriveW
+
+FUNCTION: BOOL SetupAdjustDiskSpaceListA ( HDSKSPC DiskSpace, LPCSTR DriveRoot, LONGLONG Amount, PVOID Reserved1, UINT Reserved2 ) ;
+FUNCTION: BOOL SetupAdjustDiskSpaceListW ( HDSKSPC DiskSpace, LPCWSTR DriveRoot, LONGLONG Amount, PVOID Reserved1, UINT Reserved2 ) ;
+ALIAS: SetupAdjustDiskSpaceList SetupAdjustDiskSpaceListW
+
+FUNCTION: BOOL SetupAddToDiskSpaceListA ( HDSKSPC DiskSpace, PCSTR TargetFilespec, LONGLONG FileSize, UINT Operation, PVOID Reserved1, UINT Reserved2 ) ;
+FUNCTION: BOOL SetupAddToDiskSpaceListW ( HDSKSPC DiskSpace, PCWSTR TargetFilespec, LONGLONG FileSize, UINT Operation, PVOID Reserved1, UINT Reserved2 ) ;
+ALIAS: SetupAddToDiskSpaceList SetupAddToDiskSpaceListW
+
+FUNCTION: BOOL SetupAddSectionToDiskSpaceListA ( HDSKSPC DiskSpace, HINF InfHandle, HINF ListInfHandle, PCSTR SectionName, UINT Operation, PVOID Reserved1, UINT Reserved2 ) ;
+FUNCTION: BOOL SetupAddSectionToDiskSpaceListW ( HDSKSPC DiskSpace, HINF InfHandle, HINF ListInfHandle, PCWSTR SectionName, UINT Operation, PVOID Reserved1, UINT Reserved2 ) ;
+ALIAS: SetupAddSectionToDiskSpaceList SetupAddSectionToDiskSpaceListW
+
+FUNCTION: BOOL SetupAddInstallSectionToDiskSpaceListA ( HDSKSPC DiskSpace, HINF InfHandle, HINF LayoutInfHandle, PCSTR SectionName, PVOID Reserved1, UINT Reserved2 ) ;
+FUNCTION: BOOL SetupAddInstallSectionToDiskSpaceListW ( HDSKSPC DiskSpace, HINF InfHandle, HINF LayoutInfHandle, PCWSTR SectionName, PVOID Reserved1, UINT Reserved2 ) ;
+ALIAS: SetupAddInstallSectionToDiskSpaceList SetupAddInstallSectionToDiskSpaceListW
+
+FUNCTION: BOOL SetupRemoveFromDiskSpaceListA ( HDSKSPC DiskSpace, PCSTR TargetFilespec, UINT Operation, PVOID Reserved1, UINT Reserved2 ) ;
+FUNCTION: BOOL SetupRemoveFromDiskSpaceListW ( HDSKSPC DiskSpace, PCWSTR TargetFilespec, UINT Operation, PVOID Reserved1, UINT Reserved2 ) ;
+ALIAS: SetupRemoveFromDiskSpaceList SetupRemoveFromDiskSpaceListW
+
+FUNCTION: BOOL SetupRemoveSectionFromDiskSpaceListA ( HDSKSPC DiskSpace, HINF InfHandle, HINF ListInfHandle, PCSTR SectionName, UINT Operation, PVOID Reserved1, UINT Reserved2 ) ;
+FUNCTION: BOOL SetupRemoveSectionFromDiskSpaceListW ( HDSKSPC DiskSpace, HINF InfHandle, HINF ListInfHandle, PCWSTR SectionName, UINT Operation, PVOID Reserved1, UINT Reserved2 ) ;
+ALIAS: SetupRemoveSectionFromDiskSpaceList SetupRemoveSectionFromDiskSpaceListW
+
+FUNCTION: BOOL SetupRemoveInstallSectionFromDiskSpaceListA ( HDSKSPC DiskSpace, HINF InfHandle, HINF LayoutInfHandle, PCSTR SectionName, PVOID Reserved1, UINT Reserved2 ) ;
+FUNCTION: BOOL SetupRemoveInstallSectionFromDiskSpaceListW ( HDSKSPC DiskSpace, HINF InfHandle, HINF LayoutInfHandle, PCWSTR SectionName, PVOID Reserved1, UINT Reserved2 ) ;
+ALIAS: SetupRemoveInstallSectionFromDiskSpaceList SetupRemoveInstallSectionFromDiskSpaceListW
+
+FUNCTION: BOOL SetupIterateCabinetA ( PCSTR CabinetFile, DWORD Reserved, PSP_FILE_CALLBACK_A MsgHandler, PVOID Context ) ;
+FUNCTION: BOOL SetupIterateCabinetW ( PCWSTR CabinetFile, DWORD Reserved, PSP_FILE_CALLBACK_W MsgHandler, PVOID Context ) ;
+ALIAS: SetupIterateCabinet SetupIterateCabinetW
+
+FUNCTION: INT SetupPromptReboot ( HSPFILEQ FileQueue, HWND Owner, BOOL ScanOnly ) ;
+
+CONSTANT: SPFILEQ_FILE_IN_USE         HEX: 00000001
+CONSTANT: SPFILEQ_REBOOT_RECOMMENDED  HEX: 00000002
+CONSTANT: SPFILEQ_REBOOT_IN_PROGRESS  HEX: 00000004
+
+FUNCTION: PVOID SetupInitDefaultQueueCallback ( HWND OwnerWindow ) ;
+FUNCTION: PVOID SetupInitDefaultQueueCallbackEx ( HWND OwnerWindow, HWND AlternateProgressWindow, UINT ProgressMessage, DWORD Reserved1, PVOID Reserved2 ) ;
+FUNCTION: void SetupTermDefaultQueueCallback ( PVOID Context ) ;
+
+FUNCTION: UINT SetupDefaultQueueCallbackA ( PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2 ) ;
+FUNCTION: UINT SetupDefaultQueueCallbackW ( PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2 ) ;
+ALIAS: SetupDefaultQueueCallback SetupDefaultQueueCallbackW
+
+CONSTANT: FLG_ADDREG_DELREG_BIT       HEX: 00008000
+CONSTANT: FLG_ADDREG_BINVALUETYPE     HEX: 00000001
+CONSTANT: FLG_ADDREG_NOCLOBBER        HEX: 00000002
+CONSTANT: FLG_ADDREG_DELVAL           HEX: 00000004
+CONSTANT: FLG_ADDREG_APPEND           HEX: 00000008
+CONSTANT: FLG_ADDREG_KEYONLY          HEX: 00000010
+CONSTANT: FLG_ADDREG_OVERWRITEONLY    HEX: 00000020
+CONSTANT: FLG_ADDREG_64BITKEY         HEX: 00001000
+CONSTANT: FLG_ADDREG_KEYONLY_COMMON   HEX: 00002000
+CONSTANT: FLG_ADDREG_32BITKEY         HEX: 00004000
+CONSTANT: FLG_ADDREG_TYPE_MASK        HEX: FFFF0001
+CONSTANT: FLG_ADDREG_TYPE_SZ          HEX: 00000000
+CONSTANT: FLG_ADDREG_TYPE_MULTI_SZ    HEX: 00010000
+CONSTANT: FLG_ADDREG_TYPE_EXPAND_SZ   HEX: 00020000
+CONSTANT: FLG_ADDREG_TYPE_BINARY      HEX: 00000001
+CONSTANT: FLG_ADDREG_TYPE_DWORD       HEX: 00010001
+CONSTANT: FLG_ADDREG_TYPE_NONE        HEX: 00020001
+CONSTANT: FLG_DELREG_VALUE            HEX: 00000000
+CONSTANT: FLG_DELREG_TYPE_MASK        $ FLG_ADDREG_TYPE_MASK
+CONSTANT: FLG_DELREG_TYPE_SZ          $ FLG_ADDREG_TYPE_SZ
+CONSTANT: FLG_DELREG_TYPE_MULTI_SZ    $ FLG_ADDREG_TYPE_MULTI_SZ
+CONSTANT: FLG_DELREG_TYPE_EXPAND_SZ   $ FLG_ADDREG_TYPE_EXPAND_SZ
+CONSTANT: FLG_DELREG_TYPE_BINARY      $ FLG_ADDREG_TYPE_BINARY
+CONSTANT: FLG_DELREG_TYPE_DWORD       $ FLG_ADDREG_TYPE_DWORD
+CONSTANT: FLG_DELREG_TYPE_NONE        $ FLG_ADDREG_TYPE_NONE
+CONSTANT: FLG_DELREG_64BITKEY         $ FLG_ADDREG_64BITKEY
+CONSTANT: FLG_DELREG_KEYONLY_COMMON   $ FLG_ADDREG_KEYONLY_COMMON
+CONSTANT: FLG_DELREG_32BITKEY         $ FLG_ADDREG_32BITKEY
+CONSTANT: FLG_DELREG_OPERATION_MASK   HEX: 000000FE
+CONSTANT: FLG_DELREG_MULTI_SZ_DELSTRING HEX: 00018002
+CONSTANT: FLG_BITREG_CLEARBITS        HEX: 00000000
+CONSTANT: FLG_BITREG_SETBITS          HEX: 00000001
+CONSTANT: FLG_BITREG_64BITKEY         HEX: 00001000
+CONSTANT: FLG_BITREG_32BITKEY         HEX: 00004000
+CONSTANT: FLG_INI2REG_64BITKEY        HEX: 00001000
+CONSTANT: FLG_INI2REG_32BITKEY        HEX: 00004000
+CONSTANT: FLG_REGSVR_DLLREGISTER      HEX: 00000001
+CONSTANT: FLG_REGSVR_DLLINSTALL       HEX: 00000002
+CONSTANT: FLG_PROFITEM_CURRENTUSER    HEX: 00000001
+CONSTANT: FLG_PROFITEM_DELETE         HEX: 00000002
+CONSTANT: FLG_PROFITEM_GROUP          HEX: 00000004
+CONSTANT: FLG_PROFITEM_CSIDL          HEX: 00000008
+CONSTANT: FLG_ADDPROPERTY_NOCLOBBER       HEX: 00000001
+CONSTANT: FLG_ADDPROPERTY_OVERWRITEONLY   HEX: 00000002
+CONSTANT: FLG_ADDPROPERTY_APPEND          HEX: 00000004
+CONSTANT: FLG_ADDPROPERTY_OR              HEX: 00000008
+CONSTANT: FLG_ADDPROPERTY_AND             HEX: 00000010
+CONSTANT: FLG_DELPROPERTY_MULTI_SZ_DELSTRING  HEX: 00000001
+
+FUNCTION: BOOL SetupInstallFromInfSectionA ( HWND Owner, HINF InfHandle, PCSTR SectionName, UINT Flags, HKEY RelativeKeyRoot, PCSTR SourceRootPath, UINT CopyFlags, PSP_FILE_CALLBACK_A MsgHandler, PVOID Context, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupInstallFromInfSectionW ( HWND Owner, HINF InfHandle, PCWSTR SectionName, UINT Flags, HKEY RelativeKeyRoot, PCWSTR SourceRootPath, UINT CopyFlags, PSP_FILE_CALLBACK_W MsgHandler, PVOID Context, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+ALIAS: SetupInstallFromInfSection SetupInstallFromInfSectionW
+
+CONSTANT: SPINST_LOGCONFIG                HEX: 00000001
+CONSTANT: SPINST_INIFILES                 HEX: 00000002
+CONSTANT: SPINST_REGISTRY                 HEX: 00000004
+CONSTANT: SPINST_INI2REG                  HEX: 00000008
+CONSTANT: SPINST_FILES                    HEX: 00000010
+CONSTANT: SPINST_BITREG                   HEX: 00000020
+CONSTANT: SPINST_REGSVR                   HEX: 00000040
+CONSTANT: SPINST_UNREGSVR                 HEX: 00000080
+CONSTANT: SPINST_PROFILEITEMS             HEX: 00000100
+CONSTANT: SPINST_COPYINF                  HEX: 00000200
+CONSTANT: SPINST_PROPERTIES               HEX: 00000400
+CONSTANT: SPINST_ALL                      HEX: 000007ff
+CONSTANT: SPINST_SINGLESECTION            HEX: 00010000
+CONSTANT: SPINST_LOGCONFIG_IS_FORCED      HEX: 00020000
+CONSTANT: SPINST_LOGCONFIGS_ARE_OVERRIDES HEX: 00040000
+CONSTANT: SPINST_REGISTERCALLBACKAWARE    HEX: 00080000
+CONSTANT: SPINST_DEVICEINSTALL            HEX: 00100000
+
+FUNCTION: BOOL SetupInstallFilesFromInfSectionA ( HINF InfHandle, HINF LayoutInfHandle, HSPFILEQ FileQueue, PCSTR SectionName, PCSTR SourceRootPath, UINT CopyFlags ) ;
+FUNCTION: BOOL SetupInstallFilesFromInfSectionW ( HINF InfHandle, HINF LayoutInfHandle, HSPFILEQ FileQueue, PCWSTR SectionName, PCWSTR SourceRootPath, UINT CopyFlags ) ;
+ALIAS: SetupInstallFilesFromInfSection SetupInstallFilesFromInfSectionW
+
+CONSTANT: SPSVCINST_TAGTOFRONT                   HEX: 00000001
+CONSTANT: SPSVCINST_ASSOCSERVICE                 HEX: 00000002
+CONSTANT: SPSVCINST_DELETEEVENTLOGENTRY          HEX: 00000004
+CONSTANT: SPSVCINST_NOCLOBBER_DISPLAYNAME        HEX: 00000008
+CONSTANT: SPSVCINST_NOCLOBBER_STARTTYPE          HEX: 00000010
+CONSTANT: SPSVCINST_NOCLOBBER_ERRORCONTROL       HEX: 00000020
+CONSTANT: SPSVCINST_NOCLOBBER_LOADORDERGROUP     HEX: 00000040
+CONSTANT: SPSVCINST_NOCLOBBER_DEPENDENCIES       HEX: 00000080
+CONSTANT: SPSVCINST_NOCLOBBER_DESCRIPTION        HEX: 00000100
+CONSTANT: SPSVCINST_STOPSERVICE                  HEX: 00000200
+CONSTANT: SPSVCINST_CLOBBER_SECURITY             HEX: 00000400
+CONSTANT: SPSVCINST_STARTSERVICE                 HEX: 00000800
+CONSTANT: SPSVCINST_NOCLOBBER_REQUIREDPRIVILEGES HEX: 00001000
+
+FUNCTION: BOOL SetupInstallServicesFromInfSectionA ( HINF InfHandle, PCSTR SectionName, DWORD Flags ) ;
+FUNCTION: BOOL SetupInstallServicesFromInfSectionW ( HINF InfHandle, PCWSTR SectionName, DWORD Flags ) ;
+ALIAS: SetupInstallServicesFromInfSection SetupInstallServicesFromInfSectionW
+
+FUNCTION: BOOL SetupInstallServicesFromInfSectionExA ( HINF InfHandle, PCSTR SectionName, DWORD Flags, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PVOID Reserved1, PVOID Reserved2 ) ;
+FUNCTION: BOOL SetupInstallServicesFromInfSectionExW ( HINF InfHandle, PCWSTR SectionName, DWORD Flags, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PVOID Reserved1, PVOID Reserved2 ) ;
+ALIAS: SetupInstallServicesFromInfSectionEx SetupInstallServicesFromInfSectionExW
+
+FUNCTION: void InstallHinfSectionA ( HWND Window, HINSTANCE ModuleHandle, PCSTR CommandLine, INT ShowCommand ) ;
+FUNCTION: void InstallHinfSectionW ( HWND Window, HINSTANCE ModuleHandle, PCWSTR CommandLine, INT ShowCommand ) ;
+ALIAS: InstallHinfSection InstallHinfSectionW
+
+TYPEDEF: PVOID HSPFILELOG
+
+FUNCTION: HSPFILELOG SetupInitializeFileLogA ( PCSTR LogFileName, DWORD Flags ) ;
+FUNCTION: HSPFILELOG SetupInitializeFileLogW ( PCWSTR LogFileName, DWORD Flags ) ;
+ALIAS: SetupInitializeFileLog SetupInitializeFileLogW
+
+CONSTANT: SPFILELOG_SYSTEMLOG     HEX: 00000001
+CONSTANT: SPFILELOG_FORCENEW      HEX: 00000002
+CONSTANT: SPFILELOG_QUERYONLY     HEX: 00000004
+
+FUNCTION: BOOL SetupTerminateFileLog ( HSPFILELOG FileLogHandle ) ;
+FUNCTION: BOOL SetupLogFileA ( HSPFILELOG FileLogHandle, PCSTR LogSectionName, PCSTR SourceFilename, PCSTR TargetFilename, DWORD Checksum, PCSTR DiskTagfile, PCSTR DiskDescription, PCSTR OtherInfo, DWORD Flags ) ;
+FUNCTION: BOOL SetupLogFileW ( HSPFILELOG FileLogHandle, PCWSTR LogSectionName, PCWSTR SourceFilename, PCWSTR TargetFilename, DWORD Checksum, PCWSTR DiskTagfile, PCWSTR DiskDescription, PCWSTR OtherInfo, DWORD Flags ) ;
+ALIAS: SetupLogFile SetupLogFileW
+
+CONSTANT: SPFILELOG_OEMFILE   HEX: 00000001
+FUNCTION: BOOL SetupRemoveFileLogEntryA ( HSPFILELOG FileLogHandle, PCSTR LogSectionName, PCSTR TargetFilename ) ;
+FUNCTION: BOOL SetupRemoveFileLogEntryW ( HSPFILELOG FileLogHandle, PCWSTR LogSectionName, PCWSTR TargetFilename ) ;
+ALIAS: SetupRemoveFileLogEntry SetupRemoveFileLogEntryW
+
+C-ENUM:
+    SetupFileLogSourceFilename
+    SetupFileLogChecksum
+    SetupFileLogDiskTagfile
+    SetupFileLogDiskDescription
+    SetupFileLogOtherInfo
+    SetupFileLogMax ;
+TYPEDEF: int SetupFileLogInfo
+
+FUNCTION: BOOL SetupQueryFileLogA ( HSPFILELOG FileLogHandle, PCSTR LogSectionName, PCSTR TargetFilename, SetupFileLogInfo DesiredInfo, PSTR DataOut, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupQueryFileLogW ( HSPFILELOG FileLogHandle, PCWSTR LogSectionName, PCWSTR TargetFilename, SetupFileLogInfo DesiredInfo, PWSTR DataOut, DWORD ReturnBufferSize, PDWORD RequiredSize ) ;
+ALIAS: SetupQueryFileLog SetupQueryFileLogW
+
+TYPEDEF: DWORD LogSeverity
+CONSTANT: LogSevInformation           HEX: 00000000
+CONSTANT: LogSevWarning               HEX: 00000001
+CONSTANT: LogSevError                 HEX: 00000002
+CONSTANT: LogSevFatalError            HEX: 00000003
+CONSTANT: LogSevMaximum               HEX: 00000004
+
+FUNCTION: BOOL SetupOpenLog ( BOOL Erase ) ;
+FUNCTION: BOOL SetupLogErrorA ( LPCSTR MessageString, LogSeverity Severity ) ;
+FUNCTION: BOOL SetupLogErrorW ( LPCWSTR MessageString, LogSeverity Severity ) ;
+ALIAS: SetupLogError SetupLogErrorW
+
+FUNCTION: void SetupCloseLog ( ) ;
+FUNCTION: SP_LOG_TOKEN SetupGetThreadLogToken ( ) ;
+FUNCTION: void SetupSetThreadLogToken ( SP_LOG_TOKEN LogToken ) ;
+! Unavailable until FFI to vargargs is supported.
+! FUNCTION: void SetupWriteTextLog ( SP_LOG_TOKEN LogToken, DWORD Category, DWORD Flags, PCSTR MessageStr, ... ) ;
+! FUNCTION: void SetupWriteTextLogError ( SP_LOG_TOKEN LogToken, DWORD Category, DWORD LogFlags, DWORD Error, PCSTR MessageStr, ... ) ;
+FUNCTION: void SetupWriteTextLogInfLine ( SP_LOG_TOKEN LogToken, DWORD Flags, HINF InfHandle, PINFCONTEXT Context ) ;
+
+FUNCTION: BOOL SetupGetBackupInformationA ( HSPFILEQ QueueHandle, PSP_BACKUP_QUEUE_PARAMS_A BackupParams ) ;
+FUNCTION: BOOL SetupGetBackupInformationW ( HSPFILEQ QueueHandle, PSP_BACKUP_QUEUE_PARAMS_W BackupParams ) ;
+ALIAS: SetupGetBackupInformation SetupGetBackupInformationW
+
+FUNCTION: BOOL SetupPrepareQueueForRestoreA ( HSPFILEQ QueueHandle, PCSTR BackupPath, DWORD RestoreFlags ) ;
+FUNCTION: BOOL SetupPrepareQueueForRestoreW ( HSPFILEQ QueueHandle, PCWSTR BackupPath, DWORD RestoreFlags ) ;
+ALIAS: SetupPrepareQueueForRestore SetupPrepareQueueForRestoreW
+
+FUNCTION: BOOL SetupSetNonInteractiveMode ( BOOL NonInteractiveFlag ) ;
+FUNCTION: BOOL SetupGetNonInteractiveMode ( ) ;
+
+FUNCTION: HDEVINFO SetupDiCreateDeviceInfoList ( GUID* ClassGuid, HWND hwndParent ) ;
+FUNCTION: HDEVINFO SetupDiCreateDeviceInfoListExA ( GUID* ClassGuid, HWND hwndParent, PCSTR MachineName, PVOID Reserved ) ;
+FUNCTION: HDEVINFO SetupDiCreateDeviceInfoListExW ( GUID* ClassGuid, HWND hwndParent, PCWSTR MachineName, PVOID Reserved ) ;
+
+ALIAS: SetupDiCreateDeviceInfoListEx SetupDiCreateDeviceInfoListExW
+
+FUNCTION: BOOL SetupDiGetDeviceInfoListClass( HDEVINFO DeviceInfoSet, LPGUID ClassGuid ) ;
+FUNCTION: BOOL SetupDiGetDeviceInfoListDetailA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_LIST_DETAIL_DATA_A DeviceInfoSetDetailData ) ;
+FUNCTION: BOOL SetupDiGetDeviceInfoListDetailW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_LIST_DETAIL_DATA_W DeviceInfoSetDetailData ) ;
+ALIAS: SetupDiGetDeviceInfoListDetail SetupDiGetDeviceInfoListDetailW
+
+CONSTANT: DICD_GENERATE_ID        HEX: 00000001
+CONSTANT: DICD_INHERIT_CLASSDRVS  HEX: 00000002
+
+FUNCTION: BOOL SetupDiCreateDeviceInfoA ( HDEVINFO DeviceInfoSet, PCSTR DeviceName, GUID* ClassGuid, PCSTR DeviceDescription, HWND hwndParent, DWORD CreationFlags, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiCreateDeviceInfoW ( HDEVINFO DeviceInfoSet, PCWSTR DeviceName, GUID* ClassGuid, PCWSTR DeviceDescription, HWND hwndParent, DWORD CreationFlags, PSP_DEVINFO_DATA DeviceInfoData ) ;
+ALIAS: SetupDiCreateDeviceInfo SetupDiCreateDeviceInfoW
+
+CONSTANT: DIOD_INHERIT_CLASSDRVS  HEX: 00000002
+CONSTANT: DIOD_CANCEL_REMOVE      HEX: 00000004
+
+FUNCTION: BOOL SetupDiOpenDeviceInfoA ( HDEVINFO DeviceInfoSet, PCSTR DeviceInstanceId, HWND hwndParent, DWORD OpenFlags, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiOpenDeviceInfoW ( HDEVINFO DeviceInfoSet, PCWSTR DeviceInstanceId, HWND hwndParent, DWORD OpenFlags, PSP_DEVINFO_DATA DeviceInfoData ) ;
+ALIAS: SetupDiOpenDeviceInfo SetupDiOpenDeviceInfoW
+
+FUNCTION: BOOL SetupDiGetDeviceInstanceIdA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSTR DeviceInstanceId, DWORD DeviceInstanceIdSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupDiGetDeviceInstanceIdW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PWSTR DeviceInstanceId, DWORD DeviceInstanceIdSize, PDWORD RequiredSize ) ;
+ALIAS: SetupDiGetDeviceInstanceId SetupDiGetDeviceInstanceIdW
+
+FUNCTION: BOOL SetupDiDeleteDeviceInfo ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiEnumDeviceInfo ( HDEVINFO DeviceInfoSet, DWORD MemberIndex, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiDestroyDeviceInfoList ( HDEVINFO DeviceInfoSet ) ;
+FUNCTION: BOOL SetupDiEnumDeviceInterfaces ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, GUID* InterfaceClassGuid, DWORD MemberIndex, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData ) ;
+ALIAS: SetupDiEnumInterfaceDevice SetupDiEnumDeviceInterfaces
+
+FUNCTION: BOOL SetupDiCreateDeviceInterfaceA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, GUID* InterfaceClassGuid, PCSTR ReferenceString, DWORD CreationFlags, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData ) ;
+FUNCTION: BOOL SetupDiCreateDeviceInterfaceW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, GUID* InterfaceClassGuid, PCWSTR ReferenceString, DWORD CreationFlags, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData ) ;
+ALIAS: SetupDiCreateDeviceInterface SetupDiCreateDeviceInterfaceW
+
+ALIAS: SetupDiCreateInterfaceDeviceW SetupDiCreateDeviceInterfaceW
+ALIAS: SetupDiCreateInterfaceDeviceA SetupDiCreateDeviceInterfaceA
+
+ALIAS: SetupDiCreateInterfaceDevice SetupDiCreateDeviceInterfaceW
+
+CONSTANT: DIODI_NO_ADD    HEX: 00000001
+
+FUNCTION: BOOL SetupDiOpenDeviceInterfaceA ( HDEVINFO DeviceInfoSet, PCSTR DevicePath, DWORD OpenFlags, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData ) ;
+FUNCTION: BOOL SetupDiOpenDeviceInterfaceW ( HDEVINFO DeviceInfoSet, PCWSTR DevicePath, DWORD OpenFlags, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData ) ;
+ALIAS: SetupDiOpenDeviceInterface SetupDiOpenDeviceInterfaceW
+
+ALIAS: SetupDiOpenInterfaceDeviceW SetupDiOpenDeviceInterfaceW
+ALIAS: SetupDiOpenInterfaceDeviceA SetupDiOpenDeviceInterfaceA
+
+ALIAS: SetupDiOpenInterfaceDevice SetupDiOpenDeviceInterfaceW
+
+FUNCTION: BOOL SetupDiGetDeviceInterfaceAlias ( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, GUID* AliasInterfaceClassGuid, PSP_DEVICE_INTERFACE_DATA AliasDeviceInterfaceData ) ;
+ALIAS: SetupDiGetInterfaceDeviceAlias SetupDiGetDeviceInterfaceAlias
+
+FUNCTION: BOOL SetupDiDeleteDeviceInterfaceData ( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData ) ;
+ALIAS: SetupDiDeleteInterfaceDeviceData SetupDiDeleteDeviceInterfaceData
+
+FUNCTION: BOOL SetupDiRemoveDeviceInterface ( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData ) ;
+ALIAS: SetupDiRemoveInterfaceDevice SetupDiRemoveDeviceInterface
+
+FUNCTION: BOOL SetupDiGetDeviceInterfaceDetailA ( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData, DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiGetDeviceInterfaceDetailW ( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData, DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize, PSP_DEVINFO_DATA DeviceInfoData ) ;
+ALIAS: SetupDiGetDeviceInterfaceDetail SetupDiGetDeviceInterfaceDetailW
+
+ALIAS: SetupDiGetInterfaceDeviceDetailW SetupDiGetDeviceInterfaceDetailW
+ALIAS: SetupDiGetInterfaceDeviceDetailA SetupDiGetDeviceInterfaceDetailA
+
+ALIAS: SetupDiGetInterfaceDeviceDetail SetupDiGetDeviceInterfaceDetailW
+
+FUNCTION: BOOL SetupDiInstallDeviceInterfaces ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+ALIAS: SetupDiInstallInterfaceDevices SetupDiInstallDeviceInterfaces
+
+FUNCTION: BOOL SetupDiSetDeviceInterfaceDefault ( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, DWORD Flags, PVOID Reserved ) ;
+
+CONSTANT: SPRDI_FIND_DUPS        HEX: 00000001
+
+FUNCTION: BOOL SetupDiRegisterDeviceInfo ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Flags, PSP_DETSIG_CMPPROC CompareProc, PVOID CompareContext, PSP_DEVINFO_DATA DupDeviceInfoData ) ;
+
+CONSTANT: SPDIT_NODRIVER           HEX: 00000000
+CONSTANT: SPDIT_CLASSDRIVER        HEX: 00000001
+CONSTANT: SPDIT_COMPATDRIVER       HEX: 00000002
+
+FUNCTION: BOOL SetupDiBuildDriverInfoList ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD DriverType ) ;
+FUNCTION: BOOL SetupDiCancelDriverInfoSearch ( HDEVINFO DeviceInfoSet ) ;
+FUNCTION: BOOL SetupDiEnumDriverInfoA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD DriverType, DWORD MemberIndex, PSP_DRVINFO_DATA_A DriverInfoData ) ;
+FUNCTION: BOOL SetupDiEnumDriverInfoW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD DriverType, DWORD MemberIndex, PSP_DRVINFO_DATA_W DriverInfoData ) ;
+ALIAS: SetupDiEnumDriverInfo SetupDiEnumDriverInfoW
+
+FUNCTION: BOOL SetupDiGetSelectedDriverA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DRVINFO_DATA_A DriverInfoData ) ;
+FUNCTION: BOOL SetupDiGetSelectedDriverW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DRVINFO_DATA_W DriverInfoData ) ;
+ALIAS: SetupDiGetSelectedDriver SetupDiGetSelectedDriverW
+
+FUNCTION: BOOL SetupDiSetSelectedDriverA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DRVINFO_DATA_A DriverInfoData ) ;
+FUNCTION: BOOL SetupDiSetSelectedDriverW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DRVINFO_DATA_W DriverInfoData ) ;
+ALIAS: SetupDiSetSelectedDriver SetupDiSetSelectedDriverW
+
+FUNCTION: BOOL SetupDiGetDriverInfoDetailA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DRVINFO_DATA_A DriverInfoData, PSP_DRVINFO_DETAIL_DATA_A DriverInfoDetailData, DWORD DriverInfoDetailDataSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupDiGetDriverInfoDetailW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DRVINFO_DATA_W DriverInfoData, PSP_DRVINFO_DETAIL_DATA_W DriverInfoDetailData, DWORD DriverInfoDetailDataSize, PDWORD RequiredSize ) ;
+ALIAS: SetupDiGetDriverInfoDetail SetupDiGetDriverInfoDetailW
+
+FUNCTION: BOOL SetupDiDestroyDriverInfoList ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD DriverType ) ;
+
+CONSTANT: DIGCF_DEFAULT           HEX: 00000001
+CONSTANT: DIGCF_PRESENT           HEX: 00000002
+CONSTANT: DIGCF_ALLCLASSES        HEX: 00000004
+CONSTANT: DIGCF_PROFILE           HEX: 00000008
+CONSTANT: DIGCF_DEVICEINTERFACE   HEX: 00000010
+CONSTANT: DIGCF_INTERFACEDEVICE   $ DIGCF_DEVICEINTERFACE
+
+FUNCTION: HDEVINFO SetupDiGetClassDevsA ( GUID* ClassGuid, PCSTR Enumerator, HWND hwndParent, DWORD Flags ) ;
+FUNCTION: HDEVINFO SetupDiGetClassDevsW ( GUID* ClassGuid, PCWSTR Enumerator, HWND hwndParent, DWORD Flags ) ;
+ALIAS: SetupDiGetClassDevs SetupDiGetClassDevsW
+
+FUNCTION: HDEVINFO SetupDiGetClassDevsExA ( GUID* ClassGuid, PCSTR Enumerator, HWND hwndParent, DWORD Flags, HDEVINFO DeviceInfoSet, PCSTR MachineName, PVOID Reserved ) ;
+FUNCTION: HDEVINFO SetupDiGetClassDevsExW ( GUID* ClassGuid, PCWSTR Enumerator, HWND hwndParent, DWORD Flags, HDEVINFO DeviceInfoSet, PCWSTR MachineName, PVOID Reserved ) ;
+ALIAS: SetupDiGetClassDevsEx SetupDiGetClassDevsExW
+
+FUNCTION: BOOL SetupDiGetINFClassA ( PCSTR InfName, LPGUID ClassGuid, PSTR ClassName, DWORD ClassNameSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupDiGetINFClassW ( PCWSTR InfName, LPGUID ClassGuid, PWSTR ClassName, DWORD ClassNameSize, PDWORD RequiredSize ) ;
+ALIAS: SetupDiGetINFClass SetupDiGetINFClassW
+
+CONSTANT: DIBCI_NOINSTALLCLASS   HEX: 00000001
+CONSTANT: DIBCI_NODISPLAYCLASS   HEX: 00000002
+
+FUNCTION: BOOL SetupDiBuildClassInfoList ( DWORD Flags, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupDiBuildClassInfoListExA ( DWORD Flags, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize, PCSTR MachineName, PVOID Reserved ) ;
+FUNCTION: BOOL SetupDiBuildClassInfoListExW ( DWORD Flags, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize, PCWSTR MachineName, PVOID Reserved ) ;
+ALIAS: SetupDiBuildClassInfoListEx SetupDiBuildClassInfoListExW
+
+FUNCTION: BOOL SetupDiGetClassDescriptionA ( GUID* ClassGuid, PSTR ClassDescription, DWORD ClassDescriptionSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupDiGetClassDescriptionW ( GUID* ClassGuid, PWSTR ClassDescription, DWORD ClassDescriptionSize, PDWORD RequiredSize ) ;
+ALIAS: SetupDiGetClassDescription SetupDiGetClassDescriptionW
+
+FUNCTION: BOOL SetupDiGetClassDescriptionExA ( GUID* ClassGuid, PSTR ClassDescription, DWORD ClassDescriptionSize, PDWORD RequiredSize, PCSTR MachineName, PVOID Reserved ) ;
+FUNCTION: BOOL SetupDiGetClassDescriptionExW ( GUID* ClassGuid, PWSTR ClassDescription, DWORD ClassDescriptionSize, PDWORD RequiredSize, PCWSTR MachineName, PVOID Reserved ) ;
+ALIAS: SetupDiGetClassDescriptionEx SetupDiGetClassDescriptionExW
+
+FUNCTION: BOOL SetupDiCallClassInstaller ( DI_FUNCTION InstallFunction, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiSelectDevice ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiSelectBestCompatDrv ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiInstallDevice ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiInstallDriverFiles ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiRegisterCoDeviceInstallers( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiRemoveDevice ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiUnremoveDevice ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiRestartDevices ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiChangeState ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiFinishInstallAction ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+
+FUNCTION: BOOL SetupDiInstallClassA ( HWND hwndParent, PCSTR InfFileName, DWORD Flags, HSPFILEQ FileQueue ) ;
+FUNCTION: BOOL SetupDiInstallClassW ( HWND hwndParent, PCWSTR InfFileName, DWORD Flags, HSPFILEQ FileQueue ) ;
+ALIAS: SetupDiInstallClass SetupDiInstallClassW
+
+FUNCTION: BOOL SetupDiInstallClassExA ( HWND hwndParent, PCSTR InfFileName, DWORD Flags, HSPFILEQ FileQueue, GUID* InterfaceClassGuid, PVOID Reserved1, PVOID Reserved2 ) ;
+FUNCTION: BOOL SetupDiInstallClassExW ( HWND hwndParent, PCWSTR InfFileName, DWORD Flags, HSPFILEQ FileQueue, GUID* InterfaceClassGuid, PVOID Reserved1, PVOID Reserved2 ) ;
+ALIAS: SetupDiInstallClassEx SetupDiInstallClassExW
+
+FUNCTION: HKEY SetupDiOpenClassRegKey ( GUID* ClassGuid, REGSAM samDesired ) ;
+
+CONSTANT: DIOCR_INSTALLER   HEX: 00000001
+CONSTANT: DIOCR_INTERFACE   HEX: 00000002
+
+FUNCTION: HKEY SetupDiOpenClassRegKeyExA ( GUID* ClassGuid, REGSAM samDesired, DWORD Flags, PCSTR MachineName, PVOID Reserved ) ;
+FUNCTION: HKEY SetupDiOpenClassRegKeyExW ( GUID* ClassGuid, REGSAM samDesired, DWORD Flags, PCWSTR MachineName, PVOID Reserved ) ;
+ALIAS: SetupDiOpenClassRegKeyEx SetupDiOpenClassRegKeyExW
+
+FUNCTION: HKEY SetupDiCreateDeviceInterfaceRegKeyA ( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, DWORD Reserved, REGSAM samDesired, HINF InfHandle, PCSTR InfSectionName ) ;
+FUNCTION: HKEY SetupDiCreateDeviceInterfaceRegKeyW ( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, DWORD Reserved, REGSAM samDesired, HINF InfHandle, PCWSTR InfSectionName ) ;
+ALIAS: SetupDiCreateDeviceInterfaceRegKey SetupDiCreateDeviceInterfaceRegKeyW
+ALIAS: SetupDiCreateInterfaceDeviceRegKeyW SetupDiCreateDeviceInterfaceRegKeyW
+ALIAS: SetupDiCreateInterfaceDeviceRegKeyA SetupDiCreateDeviceInterfaceRegKeyA
+ALIAS: SetupDiCreateInterfaceDeviceRegKey SetupDiCreateDeviceInterfaceRegKeyW
+
+FUNCTION: HKEY SetupDiOpenDeviceInterfaceRegKey ( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, DWORD Reserved, REGSAM samDesired ) ;
+ALIAS: SetupDiOpenInterfaceDeviceRegKey SetupDiOpenDeviceInterfaceRegKey
+
+FUNCTION: BOOL SetupDiDeleteDeviceInterfaceRegKey ( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, DWORD Reserved ) ;
+ALIAS: SetupDiDeleteInterfaceDeviceRegKey SetupDiDeleteDeviceInterfaceRegKey
+
+CONSTANT: DIREG_DEV       HEX: 00000001
+CONSTANT: DIREG_DRV       HEX: 00000002
+CONSTANT: DIREG_BOTH      HEX: 00000004
+
+FUNCTION: HKEY SetupDiCreateDevRegKeyA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType, HINF InfHandle, PCSTR InfSectionName ) ;
+FUNCTION: HKEY SetupDiCreateDevRegKeyW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType, HINF InfHandle, PCWSTR InfSectionName ) ;
+ALIAS: SetupDiCreateDevRegKey SetupDiCreateDevRegKeyW
+
+FUNCTION: HKEY SetupDiOpenDevRegKey ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType, REGSAM samDesired ) ;
+FUNCTION: BOOL SetupDiDeleteDevRegKey ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType ) ;
+FUNCTION: BOOL SetupDiGetHwProfileList ( PDWORD HwProfileList, DWORD HwProfileListSize, PDWORD RequiredSize, PDWORD CurrentlyActiveIndex ) ;
+FUNCTION: BOOL SetupDiGetHwProfileListExA ( PDWORD HwProfileList, DWORD HwProfileListSize, PDWORD RequiredSize, PDWORD CurrentlyActiveIndex, PCSTR MachineName, PVOID Reserved ) ;
+FUNCTION: BOOL SetupDiGetHwProfileListExW ( PDWORD HwProfileList, DWORD HwProfileListSize, PDWORD RequiredSize, PDWORD CurrentlyActiveIndex, PCWSTR MachineName, PVOID Reserved ) ;
+ALIAS: SetupDiGetHwProfileListEx SetupDiGetHwProfileListExW
+
+FUNCTION: BOOL SetupDiGetDevicePropertyKeys ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DEVPROPKEY* PropertyKeyArray, DWORD PropertyKeyCount, PDWORD RequiredPropertyKeyCount, DWORD Flags ) ;
+FUNCTION: BOOL SetupDiGetDevicePropertyW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DEVPROPKEY* PropertyKey, DEVPROPTYPE* PropertyType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize, DWORD Flags ) ;
+ALIAS: SetupDiGetDeviceProperty SetupDiGetDevicePropertyW
+
+FUNCTION: BOOL SetupDiSetDevicePropertyW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DEVPROPKEY* PropertyKey, DEVPROPTYPE PropertyType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, DWORD Flags ) ;
+ALIAS: SetupDiSetDeviceProperty SetupDiSetDevicePropertyW
+
+FUNCTION: BOOL SetupDiGetDeviceInterfacePropertyKeys ( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, DEVPROPKEY* PropertyKeyArray, DWORD PropertyKeyCount, PDWORD RequiredPropertyKeyCount, DWORD Flags ) ;
+FUNCTION: BOOL SetupDiGetDeviceInterfacePropertyW ( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, DEVPROPKEY* PropertyKey, DEVPROPTYPE* PropertyType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize, DWORD Flags ) ;
+ALIAS: SetupDiGetDeviceInterfaceProperty SetupDiGetDeviceInterfacePropertyW
+
+FUNCTION: BOOL SetupDiSetDeviceInterfacePropertyW ( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, DEVPROPKEY* PropertyKey, DEVPROPTYPE PropertyType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, DWORD Flags ) ;
+ALIAS: SetupDiSetDeviceInterfaceProperty SetupDiSetDeviceInterfacePropertyW
+
+CONSTANT: DICLASSPROP_INSTALLER   HEX: 00000001
+CONSTANT: DICLASSPROP_INTERFACE   HEX: 00000002
+
+FUNCTION: BOOL SetupDiGetClassPropertyKeys ( GUID* ClassGuid, DEVPROPKEY* PropertyKeyArray, DWORD PropertyKeyCount, PDWORD RequiredPropertyKeyCount, DWORD Flags ) ;
+FUNCTION: BOOL SetupDiGetClassPropertyKeysExW ( GUID* ClassGuid, DEVPROPKEY* PropertyKeyArray, DWORD PropertyKeyCount, PDWORD RequiredPropertyKeyCount, DWORD Flags, PCWSTR MachineName, PVOID Reserved ) ;
+ALIAS: SetupDiGetClassPropertyKeysEx SetupDiGetClassPropertyKeysExW
+
+FUNCTION: BOOL SetupDiGetClassPropertyW ( GUID* ClassGuid, DEVPROPKEY* PropertyKey, DEVPROPTYPE* PropertyType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize, DWORD Flags ) ;
+ALIAS: SetupDiGetClassProperty SetupDiGetClassPropertyW
+
+FUNCTION: BOOL SetupDiGetClassPropertyExW ( GUID* ClassGuid, DEVPROPKEY* PropertyKey, DEVPROPTYPE* PropertyType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize, DWORD Flags, PCWSTR MachineName, PVOID Reserved ) ;
+ALIAS: SetupDiGetClassPropertyEx SetupDiGetClassPropertyExW
+
+FUNCTION: BOOL SetupDiSetClassPropertyW ( GUID* ClassGuid, DEVPROPKEY* PropertyKey, DEVPROPTYPE PropertyType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, DWORD Flags ) ;
+ALIAS: SetupDiSetClassProperty SetupDiSetClassPropertyW
+
+FUNCTION: BOOL SetupDiSetClassPropertyExW ( GUID* ClassGuid, DEVPROPKEY* PropertyKey, DEVPROPTYPE PropertyType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, DWORD Flags, PCWSTR MachineName, PVOID Reserved ) ;
+ALIAS: SetupDiSetClassPropertyEx SetupDiSetClassPropertyExW
+
+CONSTANT: SPDRP_DEVICEDESC                  HEX: 00000000
+CONSTANT: SPDRP_HARDWAREID                  HEX: 00000001
+CONSTANT: SPDRP_COMPATIBLEIDS               HEX: 00000002
+CONSTANT: SPDRP_UNUSED0                     HEX: 00000003
+CONSTANT: SPDRP_SERVICE                     HEX: 00000004
+CONSTANT: SPDRP_UNUSED1                     HEX: 00000005
+CONSTANT: SPDRP_UNUSED2                     HEX: 00000006
+CONSTANT: SPDRP_CLASS                       HEX: 00000007
+CONSTANT: SPDRP_CLASSGUID                   HEX: 00000008
+CONSTANT: SPDRP_DRIVER                      HEX: 00000009
+CONSTANT: SPDRP_CONFIGFLAGS                 HEX: 0000000A
+CONSTANT: SPDRP_MFG                         HEX: 0000000B
+CONSTANT: SPDRP_FRIENDLYNAME                HEX: 0000000C
+CONSTANT: SPDRP_LOCATION_INFORMATION        HEX: 0000000D
+CONSTANT: SPDRP_PHYSICAL_DEVICE_OBJECT_NAME HEX: 0000000E
+CONSTANT: SPDRP_CAPABILITIES                HEX: 0000000F
+CONSTANT: SPDRP_UI_NUMBER                   HEX: 00000010
+CONSTANT: SPDRP_UPPERFILTERS                HEX: 00000011
+CONSTANT: SPDRP_LOWERFILTERS                HEX: 00000012
+CONSTANT: SPDRP_BUSTYPEGUID                 HEX: 00000013
+CONSTANT: SPDRP_LEGACYBUSTYPE               HEX: 00000014
+CONSTANT: SPDRP_BUSNUMBER                   HEX: 00000015
+CONSTANT: SPDRP_ENUMERATOR_NAME             HEX: 00000016
+CONSTANT: SPDRP_SECURITY                    HEX: 00000017
+CONSTANT: SPDRP_SECURITY_SDS                HEX: 00000018
+CONSTANT: SPDRP_DEVTYPE                     HEX: 00000019
+CONSTANT: SPDRP_EXCLUSIVE                   HEX: 0000001A
+CONSTANT: SPDRP_CHARACTERISTICS             HEX: 0000001B
+CONSTANT: SPDRP_ADDRESS                     HEX: 0000001C
+CONSTANT: SPDRP_UI_NUMBER_DESC_FORMAT       HEX: 0000001D
+CONSTANT: SPDRP_DEVICE_POWER_DATA           HEX: 0000001E
+CONSTANT: SPDRP_REMOVAL_POLICY              HEX: 0000001F
+CONSTANT: SPDRP_REMOVAL_POLICY_HW_DEFAULT   HEX: 00000020
+CONSTANT: SPDRP_REMOVAL_POLICY_OVERRIDE     HEX: 00000021
+CONSTANT: SPDRP_INSTALL_STATE               HEX: 00000022
+CONSTANT: SPDRP_LOCATION_PATHS              HEX: 00000023
+CONSTANT: SPDRP_BASE_CONTAINERID            HEX: 00000024
+CONSTANT: SPDRP_MAXIMUM_PROPERTY            HEX: 00000025
+CONSTANT: SPCRP_UPPERFILTERS                HEX: 00000011
+CONSTANT: SPCRP_LOWERFILTERS                HEX: 00000012
+CONSTANT: SPCRP_SECURITY                    HEX: 00000017
+CONSTANT: SPCRP_SECURITY_SDS                HEX: 00000018
+CONSTANT: SPCRP_DEVTYPE                     HEX: 00000019
+CONSTANT: SPCRP_EXCLUSIVE                   HEX: 0000001A
+CONSTANT: SPCRP_CHARACTERISTICS             HEX: 0000001B
+CONSTANT: SPCRP_MAXIMUM_PROPERTY            HEX: 0000001C
+
+FUNCTION: BOOL SetupDiGetDeviceRegistryPropertyA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupDiGetDeviceRegistryPropertyW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize ) ;
+ALIAS: SetupDiGetDeviceRegistryProperty SetupDiGetDeviceRegistryPropertyW
+
+FUNCTION: BOOL SetupDiGetClassRegistryPropertyA ( GUID* ClassGuid, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize, PCSTR MachineName, PVOID Reserved ) ;
+FUNCTION: BOOL SetupDiGetClassRegistryPropertyW ( GUID* ClassGuid, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize, PCWSTR MachineName, PVOID Reserved ) ;
+ALIAS: SetupDiGetClassRegistryProperty SetupDiGetClassRegistryPropertyW
+
+FUNCTION: BOOL SetupDiSetDeviceRegistryPropertyA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, BYTE* PropertyBuffer, DWORD PropertyBufferSize ) ;
+FUNCTION: BOOL SetupDiSetDeviceRegistryPropertyW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, BYTE* PropertyBuffer, DWORD PropertyBufferSize ) ;
+ALIAS: SetupDiSetDeviceRegistryProperty SetupDiSetDeviceRegistryPropertyW
+
+FUNCTION: BOOL SetupDiSetClassRegistryPropertyA ( GUID* ClassGuid, DWORD Property, BYTE* PropertyBuffer, DWORD PropertyBufferSize, PCSTR MachineName, PVOID Reserved ) ;
+FUNCTION: BOOL SetupDiSetClassRegistryPropertyW ( GUID* ClassGuid, DWORD Property, BYTE* PropertyBuffer, DWORD PropertyBufferSize, PCWSTR MachineName, PVOID Reserved ) ;
+ALIAS: SetupDiSetClassRegistryProperty SetupDiSetClassRegistryPropertyW
+
+FUNCTION: BOOL SetupDiGetDeviceInstallParamsA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DEVINSTALL_PARAMS_A DeviceInstallParams ) ;
+FUNCTION: BOOL SetupDiGetDeviceInstallParamsW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DEVINSTALL_PARAMS_W DeviceInstallParams ) ;
+ALIAS: SetupDiGetDeviceInstallParams SetupDiGetDeviceInstallParamsW
+
+FUNCTION: BOOL SetupDiGetClassInstallParamsA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_CLASSINSTALL_HEADER ClassInstallParams, DWORD ClassInstallParamsSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupDiGetClassInstallParamsW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_CLASSINSTALL_HEADER ClassInstallParams, DWORD ClassInstallParamsSize, PDWORD RequiredSize ) ;
+ALIAS: SetupDiGetClassInstallParams SetupDiGetClassInstallParamsW
+
+FUNCTION: BOOL SetupDiSetDeviceInstallParamsA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DEVINSTALL_PARAMS_A DeviceInstallParams ) ;
+FUNCTION: BOOL SetupDiSetDeviceInstallParamsW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DEVINSTALL_PARAMS_W DeviceInstallParams ) ;
+ALIAS: SetupDiSetDeviceInstallParams SetupDiSetDeviceInstallParamsW
+
+FUNCTION: BOOL SetupDiSetClassInstallParamsA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_CLASSINSTALL_HEADER ClassInstallParams, DWORD ClassInstallParamsSize ) ;
+FUNCTION: BOOL SetupDiSetClassInstallParamsW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_CLASSINSTALL_HEADER ClassInstallParams, DWORD ClassInstallParamsSize ) ;
+ALIAS: SetupDiSetClassInstallParams SetupDiSetClassInstallParamsW
+
+FUNCTION: BOOL SetupDiGetDriverInstallParamsA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DRVINFO_DATA_A DriverInfoData, PSP_DRVINSTALL_PARAMS DriverInstallParams ) ;
+FUNCTION: BOOL SetupDiGetDriverInstallParamsW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DRVINFO_DATA_W DriverInfoData, PSP_DRVINSTALL_PARAMS DriverInstallParams ) ;
+ALIAS: SetupDiGetDriverInstallParams SetupDiGetDriverInstallParamsW
+
+FUNCTION: BOOL SetupDiSetDriverInstallParamsA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DRVINFO_DATA_A DriverInfoData, PSP_DRVINSTALL_PARAMS DriverInstallParams ) ;
+FUNCTION: BOOL SetupDiSetDriverInstallParamsW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DRVINFO_DATA_W DriverInfoData, PSP_DRVINSTALL_PARAMS DriverInstallParams ) ;
+ALIAS: SetupDiSetDriverInstallParams SetupDiSetDriverInstallParamsW
+
+FUNCTION: BOOL SetupDiLoadClassIcon ( GUID* ClassGuid, HICON* LargeIcon, PINT MiniIconIndex ) ;
+FUNCTION: BOOL SetupDiLoadDeviceIcon ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, UINT cxIcon, UINT cyIcon, DWORD Flags, HICON* hIcon ) ;
+
+CONSTANT: DMI_MASK      HEX: 00000001
+CONSTANT: DMI_BKCOLOR   HEX: 00000002
+CONSTANT: DMI_USERECT   HEX: 00000004
+
+FUNCTION: INT SetupDiDrawMiniIcon ( HDC hdc, RECT rc, INT MiniIconIndex, DWORD Flags ) ;
+FUNCTION: BOOL SetupDiGetClassBitmapIndex ( GUID* ClassGuid, PINT MiniIconIndex ) ;
+FUNCTION: BOOL SetupDiGetClassImageList ( PSP_CLASSIMAGELIST_DATA ClassImageListData ) ;
+FUNCTION: BOOL SetupDiGetClassImageListExA ( PSP_CLASSIMAGELIST_DATA ClassImageListData, PCSTR MachineName, PVOID Reserved ) ;
+FUNCTION: BOOL SetupDiGetClassImageListExW ( PSP_CLASSIMAGELIST_DATA ClassImageListData, PCWSTR MachineName, PVOID Reserved ) ;
+ALIAS: SetupDiGetClassImageListEx SetupDiGetClassImageListExW
+
+FUNCTION: BOOL SetupDiGetClassImageIndex ( PSP_CLASSIMAGELIST_DATA ClassImageListData, GUID* ClassGuid, PINT ImageIndex ) ;
+FUNCTION: BOOL SetupDiDestroyClassImageList ( PSP_CLASSIMAGELIST_DATA ClassImageListData ) ;
+
+CONSTANT: DIGCDP_FLAG_BASIC           HEX: 00000001
+CONSTANT: DIGCDP_FLAG_ADVANCED        HEX: 00000002
+CONSTANT: DIGCDP_FLAG_REMOTE_BASIC    HEX: 00000003
+CONSTANT: DIGCDP_FLAG_REMOTE_ADVANCED HEX: 00000004
+
+FUNCTION: BOOL SetupDiGetClassDevPropertySheetsA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, LPPROPSHEETHEADERA PropertySheetHeader, DWORD PropertySheetHeaderPageListSize, PDWORD RequiredSize, DWORD PropertySheetType ) ;
+FUNCTION: BOOL SetupDiGetClassDevPropertySheetsW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, LPPROPSHEETHEADERW PropertySheetHeader, DWORD PropertySheetHeaderPageListSize, PDWORD RequiredSize, DWORD PropertySheetType ) ;
+ALIAS: SetupDiGetClassDevPropertySheets SetupDiGetClassDevPropertySheetsW
+
+CONSTANT: IDI_RESOURCEFIRST           159
+CONSTANT: IDI_RESOURCE                159
+CONSTANT: IDI_RESOURCELAST            161
+CONSTANT: IDI_RESOURCEOVERLAYFIRST    161
+CONSTANT: IDI_RESOURCEOVERLAYLAST     161
+CONSTANT: IDI_CONFLICT                161
+CONSTANT: IDI_CLASSICON_OVERLAYFIRST  500
+CONSTANT: IDI_CLASSICON_OVERLAYLAST   502
+CONSTANT: IDI_PROBLEM_OVL             500
+CONSTANT: IDI_DISABLED_OVL            501
+CONSTANT: IDI_FORCED_OVL              502
+
+FUNCTION: BOOL SetupDiAskForOEMDisk ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiSelectOEMDrv ( HWND hwndParent, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiClassNameFromGuidA ( GUID* ClassGuid, PSTR ClassName, DWORD ClassNameSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupDiClassNameFromGuidW ( GUID* ClassGuid, PWSTR ClassName, DWORD ClassNameSize, PDWORD RequiredSize ) ;
+ALIAS: SetupDiClassNameFromGuid SetupDiClassNameFromGuidW
+
+FUNCTION: BOOL SetupDiClassNameFromGuidExA ( GUID* ClassGuid, PSTR ClassName, DWORD ClassNameSize, PDWORD RequiredSize, PCSTR MachineName, PVOID Reserved ) ;
+FUNCTION: BOOL SetupDiClassNameFromGuidExW ( GUID* ClassGuid, PWSTR ClassName, DWORD ClassNameSize, PDWORD RequiredSize, PCWSTR MachineName, PVOID Reserved ) ;
+ALIAS: SetupDiClassNameFromGuidEx SetupDiClassNameFromGuidExW
+
+FUNCTION: BOOL SetupDiClassGuidsFromNameA ( PCSTR ClassName, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupDiClassGuidsFromNameW ( PCWSTR ClassName, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize ) ;
+ALIAS: SetupDiClassGuidsFromName SetupDiClassGuidsFromNameW
+
+FUNCTION: BOOL SetupDiClassGuidsFromNameExA ( PCSTR ClassName, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize, PCSTR MachineName, PVOID Reserved ) ;
+FUNCTION: BOOL SetupDiClassGuidsFromNameExW ( PCWSTR ClassName, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize, PCWSTR MachineName, PVOID Reserved ) ;
+ALIAS: SetupDiClassGuidsFromNameEx SetupDiClassGuidsFromNameExW
+
+FUNCTION: BOOL SetupDiGetHwProfileFriendlyNameA ( DWORD HwProfile, PSTR FriendlyName, DWORD FriendlyNameSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupDiGetHwProfileFriendlyNameW ( DWORD HwProfile, PWSTR FriendlyName, DWORD FriendlyNameSize, PDWORD RequiredSize ) ;
+ALIAS: SetupDiGetHwProfileFriendlyName SetupDiGetHwProfileFriendlyNameW
+
+FUNCTION: BOOL SetupDiGetHwProfileFriendlyNameExA ( DWORD HwProfile, PSTR FriendlyName, DWORD FriendlyNameSize, PDWORD RequiredSize, PCSTR MachineName, PVOID Reserved ) ;
+FUNCTION: BOOL SetupDiGetHwProfileFriendlyNameExW ( DWORD HwProfile, PWSTR FriendlyName, DWORD FriendlyNameSize, PDWORD RequiredSize, PCWSTR MachineName, PVOID Reserved ) ;
+ALIAS: SetupDiGetHwProfileFriendlyNameEx SetupDiGetHwProfileFriendlyNameExW
+
+CONSTANT: SPWPT_SELECTDEVICE      HEX: 00000001
+CONSTANT: SPWP_USE_DEVINFO_DATA   HEX: 00000001
+
+FUNCTION: HPROPSHEETPAGE SetupDiGetWizardPage ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_INSTALLWIZARD_DATA InstallWizardData, DWORD PageType, DWORD Flags ) ;
+FUNCTION: BOOL SetupDiGetSelectedDevice ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+FUNCTION: BOOL SetupDiSetSelectedDevice ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData ) ;
+
+FUNCTION: BOOL SetupDiGetActualModelsSectionA ( PINFCONTEXT Context, PSP_ALTPLATFORM_INFO AlternatePlatformInfo, PSTR InfSectionWithExt, DWORD InfSectionWithExtSize, PDWORD RequiredSize, PVOID Reserved ) ;
+FUNCTION: BOOL SetupDiGetActualModelsSectionW ( PINFCONTEXT Context, PSP_ALTPLATFORM_INFO AlternatePlatformInfo, PWSTR InfSectionWithExt, DWORD InfSectionWithExtSize, PDWORD RequiredSize, PVOID Reserved ) ;
+
+ALIAS: SetupDiGetActualModelsSection SetupDiGetActualModelsSectionW
+
+FUNCTION: BOOL SetupDiGetActualSectionToInstallA ( HINF InfHandle, PCSTR InfSectionName, PSTR InfSectionWithExt, DWORD InfSectionWithExtSize, PDWORD RequiredSize, PSTR* Extension ) ;
+FUNCTION: BOOL SetupDiGetActualSectionToInstallW ( HINF InfHandle, PCWSTR InfSectionName, PWSTR InfSectionWithExt, DWORD InfSectionWithExtSize, PDWORD RequiredSize, PWSTR* Extension ) ;
+ALIAS: SetupDiGetActualSectionToInstall SetupDiGetActualSectionToInstallW
+
+FUNCTION: BOOL SetupDiGetActualSectionToInstallExA ( HINF InfHandle, PCSTR InfSectionName, PSP_ALTPLATFORM_INFO AlternatePlatformInfo, PSTR InfSectionWithExt, DWORD InfSectionWithExtSize, PDWORD RequiredSize, PSTR* Extension, PVOID Reserved ) ;
+FUNCTION: BOOL SetupDiGetActualSectionToInstallExW ( HINF InfHandle, PCWSTR InfSectionName, PSP_ALTPLATFORM_INFO AlternatePlatformInfo, PWSTR InfSectionWithExt, DWORD InfSectionWithExtSize, PDWORD RequiredSize, PWSTR* Extension, PVOID Reserved ) ;
+ALIAS: SetupDiGetActualSectionToInstallEx SetupDiGetActualSectionToInstallExW
+
+FUNCTION: BOOL SetupEnumInfSectionsA ( HINF InfHandle, UINT Index, PSTR Buffer, UINT Size, UINT* SizeNeeded ) ;
+FUNCTION: BOOL SetupEnumInfSectionsW ( HINF InfHandle, UINT Index, PWSTR Buffer, UINT Size, UINT* SizeNeeded ) ;
+ALIAS: SetupEnumInfSections SetupEnumInfSectionsW
+
+STRUCT: SP_INF_SIGNER_INFO_V1_A
+    { cbSize               DWORD          }
+    { CatalogFile          CHAR[MAX_PATH] }
+    { DigitalSigner        CHAR[MAX_PATH] }
+    { DigitalSignerVersion CHAR[MAX_PATH] } ;
+TYPEDEF: SP_INF_SIGNER_INFO_V1_A* PSP_INF_SIGNER_INFO_V1_A
+STRUCT: SP_INF_SIGNER_INFO_V1_W
+    { cbSize                DWORD           }
+    { CatalogFile           WCHAR[MAX_PATH] }
+    { DigitalSigner         WCHAR[MAX_PATH] }
+    { DigitalSignerVersion  WCHAR[MAX_PATH] } ;
+TYPEDEF: SP_INF_SIGNER_INFO_V1_W* PSP_INF_SIGNER_INFO_V1_W
+TYPEDEF: SP_INF_SIGNER_INFO_V1_W SP_INF_SIGNER_INFO_V1
+TYPEDEF: PSP_INF_SIGNER_INFO_V1_W PSP_INF_SIGNER_INFO_V1
+
+STRUCT: SP_INF_SIGNER_INFO_V2_A
+    { cbSize                 DWORD          }
+    { CatalogFile            CHAR[MAX_PATH] }
+    { DigitalSigner          CHAR[MAX_PATH] }
+    { DigitalSignerVersion   CHAR[MAX_PATH] }
+    { SignerScore            DWORD          } ;
+TYPEDEF: SP_INF_SIGNER_INFO_V2_A* PSP_INF_SIGNER_INFO_V2_A
+STRUCT: SP_INF_SIGNER_INFO_V2_W
+    { cbSize                DWORD           }
+    { CatalogFile           WCHAR[MAX_PATH] }
+    { DigitalSigner         WCHAR[MAX_PATH] }
+    { DigitalSignerVersion  WCHAR[MAX_PATH] }
+    { SignerScore           DWORD           } ;
+TYPEDEF: SP_INF_SIGNER_INFO_V2_W* PSP_INF_SIGNER_INFO_V2_W
+
+TYPEDEF: SP_INF_SIGNER_INFO_V2_W SP_INF_SIGNER_INFO_V2
+TYPEDEF: PSP_INF_SIGNER_INFO_V2_W PSP_INF_SIGNER_INFO_V2
+
+CONSTANT: SIGNERSCORE_UNKNOWN         HEX: FF000000
+CONSTANT: SIGNERSCORE_W9X_SUSPECT     HEX: C0000000
+CONSTANT: SIGNERSCORE_UNSIGNED        HEX: 80000000
+CONSTANT: SIGNERSCORE_AUTHENTICODE    HEX: 0F000000
+CONSTANT: SIGNERSCORE_WHQL            HEX: 0D000005
+CONSTANT: SIGNERSCORE_UNCLASSIFIED    HEX: 0D000004
+CONSTANT: SIGNERSCORE_INBOX           HEX: 0D000003
+CONSTANT: SIGNERSCORE_LOGO_STANDARD   HEX: 0D000002
+CONSTANT: SIGNERSCORE_LOGO_PREMIUM    HEX: 0D000001
+CONSTANT: SIGNERSCORE_MASK            HEX: FF000000
+CONSTANT: SIGNERSCORE_SIGNED_MASK     HEX: F0000000
+
+TYPEDEF: SP_INF_SIGNER_INFO_V2_A  SP_INF_SIGNER_INFO_A
+TYPEDEF: PSP_INF_SIGNER_INFO_V2_A PSP_INF_SIGNER_INFO_A
+TYPEDEF: SP_INF_SIGNER_INFO_V2_W  SP_INF_SIGNER_INFO_W
+TYPEDEF: PSP_INF_SIGNER_INFO_V2_W PSP_INF_SIGNER_INFO_W
+TYPEDEF: SP_INF_SIGNER_INFO_V2    SP_INF_SIGNER_INFO
+TYPEDEF: PSP_INF_SIGNER_INFO_V2   PSP_INF_SIGNER_INFO
+
+FUNCTION: BOOL SetupVerifyInfFileA ( PCSTR InfName, PSP_ALTPLATFORM_INFO AltPlatformInfo, PSP_INF_SIGNER_INFO_A InfSignerInfo ) ;
+FUNCTION: BOOL SetupVerifyInfFileW ( PCWSTR InfName, PSP_ALTPLATFORM_INFO AltPlatformInfo, PSP_INF_SIGNER_INFO_W InfSignerInfo ) ;
+ALIAS: SetupVerifyInfFile SetupVerifyInfFileW
+
+CONSTANT: DICUSTOMDEVPROP_MERGE_MULTISZ    HEX: 00000001
+FUNCTION: BOOL SetupDiGetCustomDevicePropertyA ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PCSTR CustomPropertyName, DWORD Flags, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize ) ;
+FUNCTION: BOOL SetupDiGetCustomDevicePropertyW ( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PCWSTR CustomPropertyName, DWORD Flags, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize ) ;
+ALIAS: SetupDiGetCustomDeviceProperty SetupDiGetCustomDevicePropertyW
+
+CONSTANT: SCWMI_CLOBBER_SECURITY  HEX: 00000001
+FUNCTION: BOOL SetupConfigureWmiFromInfSectionA ( HINF InfHandle, PCSTR SectionName, DWORD Flags ) ;
+FUNCTION: BOOL SetupConfigureWmiFromInfSectionW ( HINF InfHandle, PCWSTR SectionName, DWORD Flags ) ;
+ALIAS: SetupConfigureWmiFromInfSection SetupConfigureWmiFromInfSectionW
+
diff --git a/basis/windows/ddk/setupapi/summary.txt b/basis/windows/ddk/setupapi/summary.txt
new file mode 100644
index 0000000000..3a6ad610e7
--- /dev/null
+++ b/basis/windows/ddk/setupapi/summary.txt
@@ -0,0 +1 @@
+Bindings to the SetupAPI section of the Windows DDK.
diff --git a/basis/windows/ddk/setupapi/tags.txt b/basis/windows/ddk/setupapi/tags.txt
new file mode 100644
index 0000000000..25fe231655
--- /dev/null
+++ b/basis/windows/ddk/setupapi/tags.txt
@@ -0,0 +1 @@
+unportable bindings

From cdb297f6f3e91ff764d88588319f24e07e9f900a Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Mon, 22 Feb 2010 20:39:45 -0800
Subject: [PATCH 194/250] Make scaffolding use set-file-lines so that generated
 text files end with a newline.

---
 basis/tools/scaffold/scaffold.factor | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/basis/tools/scaffold/scaffold.factor b/basis/tools/scaffold/scaffold.factor
index 9e1d08e352..8fd3e53e19 100644
--- a/basis/tools/scaffold/scaffold.factor
+++ b/basis/tools/scaffold/scaffold.factor
@@ -94,7 +94,7 @@ M: bad-developer-name summary
     ] with-string-writer ;
 
 : set-scaffold-main-file ( vocab path -- )
-    [ main-file-string ] dip utf8 set-file-contents ;
+    [ main-file-string 1array ] dip utf8 set-file-lines ;
 
 : scaffold-main ( vocab-root vocab -- )
     [ ".factor" vocab-root/vocab/suffix>path ] keep swap scaffolding? [
@@ -106,8 +106,8 @@ M: bad-developer-name summary
 : scaffold-metadata ( vocab file contents -- )
     [ ensure-vocab-exists ] 2dip
     [
-        [ vocab/file>path ] dip swap scaffolding? [
-            utf8 set-file-contents
+        [ vocab/file>path ] dip 1array swap scaffolding? [
+            utf8 set-file-lines
         ] [
             2drop
         ] if

From ff9fc2713b7f990620df243bc8d884005bbead73 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 22 Feb 2010 21:57:56 -0800
Subject: [PATCH 195/250] cairo.ffi: update references to pointer types in
 alien-callbacks

---
 basis/cairo/ffi/ffi.factor | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/basis/cairo/ffi/ffi.factor b/basis/cairo/ffi/ffi.factor
index 947869e357..49975afc61 100644
--- a/basis/cairo/ffi/ffi.factor
+++ b/basis/cairo/ffi/ffi.factor
@@ -38,7 +38,7 @@ TYPEDEF: void* cairo_pattern_t
 
 TYPEDEF: void* cairo_destroy_func_t
 : cairo-destroy-func ( quot -- callback )
-    [ void { void* } "cdecl" ] dip alien-callback ; inline
+    [ void { pointer: void } "cdecl" ] dip alien-callback ; inline
 
 ! See cairo.h for details
 STRUCT: cairo_user_data_key_t
@@ -79,11 +79,11 @@ CONSTANT: CAIRO_CONTENT_COLOR_ALPHA HEX: 3000
 
 TYPEDEF: void* cairo_write_func_t
 : cairo-write-func ( quot -- callback )
-    [ cairo_status_t { void* uchar* int } "cdecl" ] dip alien-callback ; inline
+    [ cairo_status_t { pointer: void pointer: uchar int } "cdecl" ] dip alien-callback ; inline
                           
 TYPEDEF: void* cairo_read_func_t
 : cairo-read-func ( quot -- callback )
-    [ cairo_status_t { void* uchar* int } "cdecl" ] dip alien-callback ; inline
+    [ cairo_status_t { pointer: void pointer: uchar int } "cdecl" ] dip alien-callback ; inline
 
 ! Functions for manipulating state objects
 FUNCTION: cairo_t*

From aef979b552924bf95ade129676c8452be1124005 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 22 Feb 2010 21:58:18 -0800
Subject: [PATCH 196/250] alien.fortran: update tests to reflect new pointer
 c-type objects

---
 basis/alien/fortran/fortran-tests.factor | 59 ++++++++++++------------
 1 file changed, 30 insertions(+), 29 deletions(-)

diff --git a/basis/alien/fortran/fortran-tests.factor b/basis/alien/fortran/fortran-tests.factor
index 80a5ec8bae..dc0585cab8 100644
--- a/basis/alien/fortran/fortran-tests.factor
+++ b/basis/alien/fortran/fortran-tests.factor
@@ -4,6 +4,7 @@ alien.data alien.fortran alien.fortran.private alien.strings
 classes.struct arrays assocs byte-arrays combinators fry
 generalizations io.encodings.ascii kernel macros
 macros.expander namespaces sequences shuffle tools.test vocabs.parser ;
+FROM: alien.syntax => pointer: ;
 QUALIFIED-WITH: alien.c-types c
 IN: alien.fortran.tests
 
@@ -100,16 +101,16 @@ intel-unix-abi fortran-abi [
 
     ! fortran-arg-type>c-type
 
-    [ c:void* { } ]
+    [ pointer: c:int { } ]
     [ "integer" fortran-arg-type>c-type ] unit-test
 
-    [ c:void* { } ]
+    [ pointer: { c:int 3 } { } ]
     [ "integer(3)" fortran-arg-type>c-type ] unit-test
 
-    [ c:void* { } ]
+    [ pointer: { c:int 0 } { } ]
     [ "integer(*)" fortran-arg-type>c-type ] unit-test
 
-    [ c:void* { } ]
+    [ pointer: fortran_test_record { } ]
     [
         [
             "alien.fortran.tests" use-vocab
@@ -117,13 +118,13 @@ intel-unix-abi fortran-abi [
         ] with-manifest
     ] unit-test
 
-    [ c:char* { } ]
+    [ pointer: c:char { } ]
     [ "character" fortran-arg-type>c-type ] unit-test
 
-    [ c:char* { } ]
+    [ pointer: c:char { } ]
     [ "character(1)" fortran-arg-type>c-type ] unit-test
 
-    [ c:char* { long } ]
+    [ pointer: { c:char 17 } { long } ]
     [ "character(17)" fortran-arg-type>c-type ] unit-test
 
     ! fortran-ret-type>c-type
@@ -131,7 +132,7 @@ intel-unix-abi fortran-abi [
     [ c:char { } ]
     [ "character(1)" fortran-ret-type>c-type ] unit-test
 
-    [ c:void { c:char* long } ]
+    [ c:void { pointer: { c:char 17 } long } ]
     [ "character(17)" fortran-ret-type>c-type ] unit-test
 
     [ c:int { } ]
@@ -143,22 +144,22 @@ intel-unix-abi fortran-abi [
     [ c:float { } ]
     [ "real" fortran-ret-type>c-type ] unit-test
 
-    [ c:void { c:void* } ]
+    [ c:void { pointer: { c:float 0 } } ]
     [ "real(*)" fortran-ret-type>c-type ] unit-test
 
     [ c:double { } ]
     [ "double-precision" fortran-ret-type>c-type ] unit-test
 
-    [ c:void { c:void* } ]
+    [ c:void { pointer: complex-float } ]
     [ "complex" fortran-ret-type>c-type ] unit-test
 
-    [ c:void { c:void* } ]
+    [ c:void { pointer: complex-double } ]
     [ "double-complex" fortran-ret-type>c-type ] unit-test
 
-    [ c:void { c:void* } ]
+    [ c:void { pointer: { c:int 0 } } ]
     [ "integer(*)" fortran-ret-type>c-type ] unit-test
 
-    [ c:void { c:void* } ]
+    [ c:void { pointer: fortran_test_record } ]
     [
         [
             "alien.fortran.tests" use-vocab
@@ -168,19 +169,19 @@ intel-unix-abi fortran-abi [
 
     ! fortran-sig>c-sig
 
-    [ c:float { c:void* c:char* c:void* c:void* c:long } ]
+    [ c:float { pointer: c:int pointer: { c:char 17 } pointer: c:float pointer: c:double c:long } ]
     [ "real" { "integer" "character*17" "real" "real*8" } fortran-sig>c-sig ]
     unit-test
 
-    [ c:char { c:char* c:char* c:void* c:long } ]
+    [ c:char { pointer: { c:char 17 } pointer: c:char pointer: c:int c:long } ]
     [ "character(1)" { "character*17" "character" "integer" } fortran-sig>c-sig ]
     unit-test
 
-    [ c:void { c:char* c:long c:char* c:char* c:void* c:long } ]
+    [ c:void { pointer: { c:char 18 } c:long pointer: { c:char 17 } pointer: c:char pointer: c:int c:long } ]
     [ "character*18" { "character*17" "character" "integer" } fortran-sig>c-sig ]
     unit-test
 
-    [ c:void { c:void* c:char* c:char* c:void* c:long } ]
+    [ c:void { pointer: complex-float pointer: { c:char 17 } pointer: c:char pointer: c:int c:long } ]
     [ "complex" { "character*17" "character" "integer" } fortran-sig>c-sig ]
     unit-test
 
@@ -201,7 +202,7 @@ intel-unix-abi fortran-abi [
         ! [fortran-invoke]
         [ 
             c:void "funpack" "funtimes_"
-            { c:char* c:void* c:void* c:void* c:void* c:long }
+            { pointer: { c:char 12 } pointer: c:longlong pointer: c:float pointer: complex-float pointer: c:short c:long }
             alien-invoke
         ] 6 nkeep
         ! [fortran-results>]
@@ -226,7 +227,7 @@ intel-unix-abi fortran-abi [
             [ { [ drop ] } spread ]
         } 1 ncleave
         ! [fortran-invoke]
-        [ c:float "funpack" "fun_times_" { void* } alien-invoke ]
+        [ c:float "funpack" "fun_times_" { pointer: { c:float 0 } } alien-invoke ]
         1 nkeep
         ! [fortran-results>]
         shuffle( reta aa -- reta aa ) 
@@ -244,7 +245,7 @@ intel-unix-abi fortran-abi [
         ! [fortran-invoke]
         [
             c:void "funpack" "fun_times_"
-            { void* void* } 
+            { pointer: complex-float pointer: { c:float 0 } } 
             alien-invoke
         ] 2 nkeep
         ! [fortran-results>]
@@ -261,7 +262,7 @@ intel-unix-abi fortran-abi [
         ! [fortran-invoke]
         [
             c:void "funpack" "fun_times_"
-            { c:char* long } 
+            { pointer: { c:char 20 } long } 
             alien-invoke
         ] 2 nkeep
         ! [fortran-results>]
@@ -287,7 +288,7 @@ intel-unix-abi fortran-abi [
         ! [fortran-invoke]
         [
             c:void "funpack" "fun_times_"
-            { c:char* long c:char* c:void* c:char* c:long c:long } 
+            { pointer: { c:char 10 } long pointer: { c:char 20 } pointer: c:float pointer: { c:char 30 } c:long c:long } 
             alien-invoke
         ] 7 nkeep
         ! [fortran-results>]
@@ -321,16 +322,16 @@ f2c-abi fortran-abi [
     [ { c:char 1 } ]
     [ "character(1)" fortran-type>c-type ] unit-test
 
-    [ c:char* { c:long } ]
+    [ pointer: c:char { c:long } ]
     [ "character" fortran-arg-type>c-type ] unit-test
 
-    [ c:void { c:char* c:long } ]
+    [ c:void { pointer: c:char c:long } ]
     [ "character" fortran-ret-type>c-type ] unit-test
 
     [ c:double { } ]
     [ "real" fortran-ret-type>c-type ] unit-test
 
-    [ c:void { void* } ]
+    [ c:void { pointer: { c:float 0 } } ]
     [ "real(*)" fortran-ret-type>c-type ] unit-test
 
     [ "fun_" ] [ "FUN" fortran-name>symbol-name ] unit-test
@@ -344,7 +345,7 @@ gfortran-abi fortran-abi [
     [ c:float { } ]
     [ "real" fortran-ret-type>c-type ] unit-test
 
-    [ c:void { void* } ]
+    [ c:void { pointer: { c:float 0 } } ]
     [ "real(*)" fortran-ret-type>c-type ] unit-test
 
     [ complex-float { } ]
@@ -356,10 +357,10 @@ gfortran-abi fortran-abi [
     [ { char 1 } ]
     [ "character(1)" fortran-type>c-type ] unit-test
 
-    [ c:char* { c:long } ]
+    [ pointer: c:char { c:long } ]
     [ "character" fortran-arg-type>c-type ] unit-test
 
-    [ c:void { c:char* c:long } ]
+    [ c:void { pointer: c:char c:long } ]
     [ "character" fortran-ret-type>c-type ] unit-test
 
     [ complex-float { } ]
@@ -368,7 +369,7 @@ gfortran-abi fortran-abi [
     [ complex-double { } ]
     [ "double-complex" fortran-ret-type>c-type ] unit-test
 
-    [ c:void { c:void* } ]
+    [ c:void { pointer: { complex-double 3 } } ]
     [ "double-complex(3)" fortran-ret-type>c-type ] unit-test
 
 ] with-variable

From 53e601c5f08bf096ad413ca47ed8066923b55f3f Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 22 Feb 2010 23:55:52 -0800
Subject: [PATCH 197/250] _DARWIN_MAXNAMELEN+1 should actually be
 _DARWIN_MAXNAMELEN + 1

---
 basis/unix/ffi/bsd/macosx/macosx.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/unix/ffi/bsd/macosx/macosx.factor b/basis/unix/ffi/bsd/macosx/macosx.factor
index a2e75b6ca6..a7c47f0ff8 100644
--- a/basis/unix/ffi/bsd/macosx/macosx.factor
+++ b/basis/unix/ffi/bsd/macosx/macosx.factor
@@ -32,7 +32,7 @@ STRUCT: utmpx
 
 CONSTANT: __DARWIN_MAXPATHLEN 1024
 CONSTANT: __DARWIN_MAXNAMELEN 255
-CONSTANT: __DARWIN_MAXNAMELEN+1 255
+CONSTANT: __DARWIN_MAXNAMELEN+1 256
 
 STRUCT: dirent
     { d_ino ino_t }

From b8bd5fe6301bd48aea30f9f2e485d1536e357e98 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Mon, 22 Feb 2010 23:57:10 -0800
Subject: [PATCH 198/250] classes.struct: reader-quot was checking
 struct-slot-spec for array-ness, not the type! derp

---
 basis/classes/struct/struct.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/classes/struct/struct.factor b/basis/classes/struct/struct.factor
index 3b2fc875c4..204b05517b 100644
--- a/basis/classes/struct/struct.factor
+++ b/basis/classes/struct/struct.factor
@@ -147,7 +147,7 @@ M: struct-class initial-value* <struct> ; inline
 GENERIC: struct-slot-values ( struct -- sequence )
 
 M: struct-class reader-quot
-    dup array? [ dup first define-array-vocab drop ] when
+    dup type>> array? [ dup type>> first define-array-vocab drop ] when
     nip '[ _ read-struct-slot ] ;
 
 M: struct-class writer-quot

From 3d97bd2ae0538a6df3233295012bfc6200b93c69 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 00:03:18 -0800
Subject: [PATCH 199/250] add opaque C-TYPEs for sundry interfaces to
 windows.com

---
 basis/windows/com/com.factor | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/basis/windows/com/com.factor b/basis/windows/com/com.factor
index 33164f52c4..094859009d 100644
--- a/basis/windows/com/com.factor
+++ b/basis/windows/com/com.factor
@@ -11,6 +11,8 @@ COM-INTERFACE: IUnknown f {00000000-0000-0000-C000-000000000046}
     ULONG Release ( ) ;
 
 C-TYPE: IAdviseSink
+C-TYPE: IEnumFORMATETC
+C-TYPE: IEnumSTATDATA
 
 COM-INTERFACE: IDataObject IUnknown {0000010E-0000-0000-C000-000000000046}
     HRESULT GetData ( FORMATETC* pFormatetc, STGMEDIUM* pmedium )

From 050d0424499cbd7696c475a71f2d638eb3cc2a0f Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Tue, 23 Feb 2010 21:19:06 +1300
Subject: [PATCH 200/250] formatting: fix docs

---
 basis/formatting/formatting-docs.factor |  2 +-
 basis/formatting/formatting.factor      | 26 ++++++++++++-------------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/basis/formatting/formatting-docs.factor b/basis/formatting/formatting-docs.factor
index 47720ad671..9625c40577 100644
--- a/basis/formatting/formatting-docs.factor
+++ b/basis/formatting/formatting-docs.factor
@@ -36,7 +36,7 @@ HELP: printf
     "For example:\n"
     { $list
         "\"%5s\" formats a string padding with spaces up to 5 characters wide."
-        "\"%08d\" formats an integer padding with zeros up to 3 characters wide."
+        "\"%03d\" formats an integer padding with zeros up to 3 characters wide."
         "\"%'#5f\" formats a float padding with '#' up to 3 characters wide."
         "\"%-10d\" formats an integer to 10 characters wide and left-aligns." 
     }
diff --git a/basis/formatting/formatting.factor b/basis/formatting/formatting.factor
index 40279749d6..ec3c9f1d8e 100644
--- a/basis/formatting/formatting.factor
+++ b/basis/formatting/formatting.factor
@@ -12,18 +12,18 @@ IN: formatting
     [ ] [ compose ] reduce ;
 
 : fix-sign ( string -- string )
-    dup CHAR: 0 swap index 0 = 
+    dup CHAR: 0 swap index 0 =
       [ dup 0 swap [ [ CHAR: 0 = not ] keep digit? and ] find-from
          [ dup 1 - rot dup [ nth ] dip swap
             {
                { CHAR: - [ [ 1 - ] dip remove-nth "-" prepend ] }
                { CHAR: + [ [ 1 - ] dip remove-nth "+" prepend ] }
-               [ drop swap drop ] 
-            } case 
+               [ drop swap drop ]
+            } case
          ] [ drop ] if
       ] when ;
 
-: >digits ( string -- digits ) 
+: >digits ( string -- digits )
     [ 0 ] [ string>number ] if-empty ;
 
 : pad-digits ( string digits -- string' )
@@ -33,20 +33,20 @@ IN: formatting
     10^ [ * round ] keep / ; inline
 
 : >exp ( x -- exp base )
-    [ 
+    [
         abs 0 swap
         [ dup [ 10.0 >= ] [ 1.0 < ] bi or ]
         [ dup 10.0 >=
           [ 10.0 / [ 1 + ] dip ]
           [ 10.0 * [ 1 - ] dip ] if
-        ] while 
+        ] while
      ] keep 0 < [ neg ] when ;
 
 : exp>string ( exp base digits -- string )
     [ max-digits ] keep -rot
     [
         [ 0 < "-" "+" ? ]
-        [ abs number>string 2 CHAR: 0 pad-head ] bi 
+        [ abs number>string 2 CHAR: 0 pad-head ] bi
         "e" -rot 3append
     ]
     [ number>string ] bi*
@@ -58,19 +58,19 @@ zero      = "0"                  => [[ CHAR: 0 ]]
 char      = "'" (.)              => [[ second ]]
 
 pad-char  = (zero|char)?         => [[ CHAR: \s or ]]
-pad-align = ("-")?               => [[ \ pad-tail \ pad-head ? ]] 
+pad-align = ("-")?               => [[ \ pad-tail \ pad-head ? ]]
 pad-width = ([0-9])*             => [[ >digits ]]
 pad       = pad-align pad-char pad-width => [[ reverse >quotation dup first 0 = [ drop [ ] ] when ]]
 
 sign      = ("+")?               => [[ [ dup CHAR: - swap index [ "+" prepend ] unless ] [ ] ? ]]
 
 width_    = "." ([0-9])*         => [[ second >digits '[ _ short head ] ]]
-width     = (width_)?            => [[ [ ] or ]] 
+width     = (width_)?            => [[ [ ] or ]]
 
 digits_   = "." ([0-9])*         => [[ second >digits ]]
 digits    = (digits_)?           => [[ 6 or ]]
 
-fmt-%     = "%"                  => [[ [ "%" ] ]] 
+fmt-%     = "%"                  => [[ [ "%" ] ]]
 fmt-c     = "c"                  => [[ [ 1string ] ]]
 fmt-C     = "C"                  => [[ [ 1string >upper ] ]]
 fmt-s     = "s"                  => [[ [ dup number? [ number>string ] when ] ]]
@@ -78,7 +78,7 @@ fmt-S     = "S"                  => [[ [ dup number? [ number>string ] when >upp
 fmt-d     = "d"                  => [[ [ >fixnum number>string ] ]]
 fmt-e     = digits "e"           => [[ first '[ >exp _ exp>string ] ]]
 fmt-E     = digits "E"           => [[ first '[ >exp _ exp>string >upper ] ]]
-fmt-f     = digits "f"           => [[ first dup '[ >float _ max-digits number>string _ pad-digits ] ]] 
+fmt-f     = digits "f"           => [[ first dup '[ >float _ max-digits number>string _ pad-digits ] ]]
 fmt-x     = "x"                  => [[ [ >hex ] ]]
 fmt-X     = "X"                  => [[ [ >hex >upper ] ]]
 unknown   = (.)*                 => [[ "Unknown directive" throw ]]
@@ -89,9 +89,9 @@ strings   = pad width strings_   => [[ reverse compose-all ]]
 numbers_  = fmt-d|fmt-e|fmt-E|fmt-f|fmt-x|fmt-X
 numbers   = sign pad numbers_    => [[ unclip-last prefix compose-all [ fix-sign ] append ]]
 
-types     = strings|numbers 
+types     = strings|numbers
 
-lists     = "[%" types ", %]"    => [[ second '[ _ map ", " join "{ " prepend " }" append ] ]] 
+lists     = "[%" types ", %]"    => [[ second '[ _ map ", " join "{ " prepend " }" append ] ]]
 
 assocs    = "[%" types ": %" types " %]" => [[ [ second ] [ fourth ] bi '[ unzip [ _ map ] dip _ map zip [ ":" join ] map ", " join "{ " prepend " }" append ] ]]
 

From f0aa694c7e8f253aa0909585cd6655435798fcef Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Tue, 23 Feb 2010 23:57:13 +1300
Subject: [PATCH 201/250] effects.parser: throw a proper no-word error if
 effect references an unknown class word

---
 basis/macros/macros.factor        |  6 +++---
 basis/memoize/memoize.factor      |  6 +++---
 basis/peg/peg.factor              |  6 +++---
 basis/promises/promises.factor    |  2 +-
 basis/typed/typed.factor          |  2 +-
 core/effects/parser/parser.factor | 12 ++++++++----
 core/parser/parser.factor         |  7 +------
 7 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/basis/macros/macros.factor b/basis/macros/macros.factor
index 91ca2f301c..9137588e6c 100644
--- a/basis/macros/macros.factor
+++ b/basis/macros/macros.factor
@@ -1,8 +1,8 @@
 ! Copyright (C) 2007, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: parser kernel sequences words effects combinators assocs
-definitions quotations namespaces memoize accessors fry
-compiler.units ;
+USING: parser effects.parser kernel sequences words effects
+combinators assocs definitions quotations namespaces memoize
+accessors fry compiler.units ;
 IN: macros
 
 <PRIVATE
diff --git a/basis/memoize/memoize.factor b/basis/memoize/memoize.factor
index c949c34684..71f9fe1942 100644
--- a/basis/memoize/memoize.factor
+++ b/basis/memoize/memoize.factor
@@ -1,8 +1,8 @@
-! Copyright (C) 2007, 2009 Slava Pestov, Daniel Ehrenberg.
+! Copyright (C) 2007, 2010 Slava Pestov, Daniel Ehrenberg.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel hashtables sequences sequences.private arrays
-words namespaces make parser math assocs effects definitions
-quotations summary accessors fry ;
+words namespaces make parser effects.parser math assocs effects
+definitions quotations summary accessors fry ;
 IN: memoize
 
 <PRIVATE
diff --git a/basis/peg/peg.factor b/basis/peg/peg.factor
index d4397627e8..a180713ccf 100644
--- a/basis/peg/peg.factor
+++ b/basis/peg/peg.factor
@@ -1,9 +1,9 @@
 ! Copyright (C) 2007, 2008 Chris Double.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel sequences strings fry namespaces make math assocs
-io vectors arrays math.parser math.order combinators
-classes sets unicode.categories compiler.units parser words
-quotations memoize accessors locals splitting
+io vectors arrays math.parser math.order combinators classes
+sets unicode.categories compiler.units parser effects.parser
+words quotations memoize accessors locals splitting
 combinators.short-circuit generalizations ;
 IN: peg
 
diff --git a/basis/promises/promises.factor b/basis/promises/promises.factor
index cd98827206..10d028e012 100644
--- a/basis/promises/promises.factor
+++ b/basis/promises/promises.factor
@@ -1,7 +1,7 @@
 ! Copyright (C) 2004, 2006 Chris Double, Matthew Willis.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays effects fry generalizations kernel math
-namespaces parser sequences words ;
+namespaces parser effects.parser sequences words ;
 IN: promises
 
 TUPLE: promise quot forced? value ;
diff --git a/basis/typed/typed.factor b/basis/typed/typed.factor
index 8a85ca1afb..e104c69da9 100644
--- a/basis/typed/typed.factor
+++ b/basis/typed/typed.factor
@@ -2,7 +2,7 @@
 USING: accessors arrays classes classes.tuple combinators
 combinators.short-circuit definitions effects fry hints
 math kernel kernel.private namespaces parser quotations
-sequences slots words locals 
+sequences slots words locals effects.parser
 locals.parser macros stack-checker.dependencies ;
 FROM: classes.tuple.private => tuple-layout ;
 IN: typed
diff --git a/core/effects/parser/parser.factor b/core/effects/parser/parser.factor
index a77ea34c30..842d4f6447 100644
--- a/core/effects/parser/parser.factor
+++ b/core/effects/parser/parser.factor
@@ -1,7 +1,7 @@
-! Copyright (C) 2008, 2009 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: lexer sets sequences kernel splitting effects
-combinators arrays vocabs.parser classes ;
+combinators arrays vocabs.parser classes parser ;
 IN: effects.parser
 
 DEFER: parse-effect
@@ -14,9 +14,8 @@ ERROR: bad-effect ;
             ":" ?tail [
                 scan {
                     { [ dup "(" = ] [ drop ")" parse-effect ] }
-                    { [ dup search class? ] [ search ] }
                     { [ dup f = ] [ ")" unexpected-eof ] }
-                    [ bad-effect ]
+                    [ parse-word dup class? [ bad-effect ] unless ]
                 } cond 2array
             ] when
         ] if
@@ -36,3 +35,8 @@ ERROR: stack-effect-omits-dashes tokens ;
 
 : parse-call( ( accum word -- accum )
     [ ")" parse-effect ] dip 2array append! ;
+
+: (:) ( -- word def effect )
+    CREATE-WORD
+    complete-effect
+    parse-definition swap ;
diff --git a/core/parser/parser.factor b/core/parser/parser.factor
index 544d75b244..e3e7d79c40 100644
--- a/core/parser/parser.factor
+++ b/core/parser/parser.factor
@@ -5,7 +5,7 @@ sequences strings vectors words words.symbol quotations io
 combinators sorting splitting math.parser effects continuations
 io.files vocabs io.encodings.utf8 source-files classes
 hashtables compiler.units accessors sets lexer vocabs.parser
-effects.parser slots parser.notes ;
+ slots parser.notes ;
 IN: parser
 
 : location ( -- loc )
@@ -102,11 +102,6 @@ M: f parse-quotation \ ] parse-until >quotation ;
 : parse-definition ( -- quot )
     \ ; parse-until >quotation ;
 
-: (:) ( -- word def effect )
-    CREATE-WORD
-    complete-effect
-    parse-definition swap ;
-
 ERROR: bad-number ;
 
 : scan-base ( base -- n )

From ae25cfe7127ae4fdecebcc6d2fe24c6e8469bb4f Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Wed, 24 Feb 2010 00:16:55 +1300
Subject: [PATCH 202/250] Get foldable and flushable declarations working on
 typed words

---
 .../tree/propagation/simple/simple.factor     |  2 +-
 basis/typed/typed-tests.factor                | 29 +++++++++++++++-
 basis/typed/typed.factor                      | 12 +++----
 core/effects/effects.factor                   |  9 +++--
 core/generic/generic-tests.factor             | 13 ++++++++
 core/generic/generic.factor                   | 12 ++-----
 core/words/words.factor                       | 33 +++++++++++++------
 7 files changed, 80 insertions(+), 30 deletions(-)

diff --git a/basis/compiler/tree/propagation/simple/simple.factor b/basis/compiler/tree/propagation/simple/simple.factor
index ed417ef9d7..ce169233c1 100644
--- a/basis/compiler/tree/propagation/simple/simple.factor
+++ b/basis/compiler/tree/propagation/simple/simple.factor
@@ -72,7 +72,7 @@ M: #declare propagate-before
 
 : foldable-call? ( #call word -- ? )
     {
-        [ nip "foldable" word-prop ]
+        [ nip foldable? ]
         [ drop literal-inputs? ]
         [ input-classes-match? ]
     } 2&& ;
diff --git a/basis/typed/typed-tests.factor b/basis/typed/typed-tests.factor
index 7f984ccaf2..28ec2b6e86 100644
--- a/basis/typed/typed-tests.factor
+++ b/basis/typed/typed-tests.factor
@@ -1,5 +1,6 @@
 USING: accessors effects eval kernel layouts math namespaces
-quotations tools.test typed words ;
+quotations tools.test typed words words.symbol
+compiler.tree.debugger prettyprint ;
 IN: typed.tests
 
 TYPED: f+ ( a: float b: float -- c: float )
@@ -122,3 +123,29 @@ TYPED: recompile-fail ( a: subclass -- ? ) buh get eq? ;
 [ ] [ "IN: typed.tests TUPLE: subclass < superclass { y read-only } ;" eval( -- ) ] unit-test
 
 [ t ] [ subclass new [ buh set ] [ recompile-fail ] bi ] unit-test
+
+! Make sure that foldable and flushable work on typed words
+TYPED: add ( a: integer b: integer -- c: integer ) + ; foldable
+
+[ [ 3 ] ] [ [ 1 2 add ] cleaned-up-tree nodes>quot ] unit-test
+
+TYPED: flush-test ( s: symbol -- ? ) on t ; flushable
+
+: flush-print-1 ( symbol -- ) flush-test drop ;
+: flush-print-2 ( symbol -- ) flush-test . ;
+
+SYMBOL: a-symbol
+
+[ f ] [
+    f a-symbol [
+        a-symbol flush-print-1
+        a-symbol get
+    ] with-variable
+] unit-test
+
+[ t ] [
+    f a-symbol [
+        a-symbol flush-print-2
+        a-symbol get
+    ] with-variable
+] unit-test
diff --git a/basis/typed/typed.factor b/basis/typed/typed.factor
index e104c69da9..6ab4e0334d 100644
--- a/basis/typed/typed.factor
+++ b/basis/typed/typed.factor
@@ -11,8 +11,8 @@ ERROR: type-mismatch-error word expected-types ;
 ERROR: input-mismatch-error < type-mismatch-error ;
 ERROR: output-mismatch-error < type-mismatch-error ;
 
-PREDICATE: typed-gensym < word "typed-gensym" word-prop ;
-PREDICATE: typed-word < word "typed-word" word-prop ;
+PREDICATE: typed-gensym < word "typed-gensym" word-prop >boolean ;
+PREDICATE: typed-word < word "typed-word" word-prop >boolean ;
 
 <PRIVATE
 
@@ -120,10 +120,10 @@ MACRO: (typed) ( word def effect -- quot )
     [ effect-in-types unboxed-types [ "in" swap 2array ] map ]
     [ effect-out-types unboxed-types [ "out" swap 2array ] map ] bi <effect> ;
 
-M: typed-gensym stack-effect
-    call-next-method unboxed-effect ;
-M: typed-gensym crossref? 
-    "typed-gensym" word-prop crossref? ;
+M: typed-gensym stack-effect call-next-method unboxed-effect ;
+M: typed-gensym parent-word "typed-gensym" word-prop ;
+M: typed-gensym crossref? parent-word crossref? ;
+M: typed-gensym where parent-word where ;
 
 : define-typed-gensym ( word def effect -- gensym )
     [ 2drop <typed-gensym> dup ]
diff --git a/core/effects/effects.factor b/core/effects/effects.factor
index 1790399e04..fea50d2981 100644
--- a/core/effects/effects.factor
+++ b/core/effects/effects.factor
@@ -1,7 +1,8 @@
 ! Copyright (C) 2006, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel math math.parser math.order namespaces make sequences strings
-words assocs combinators accessors arrays quotations ;
+USING: kernel math math.parser math.order namespaces make
+sequences strings words assocs combinators accessors arrays
+quotations ;
 IN: effects
 
 TUPLE: effect
@@ -64,7 +65,9 @@ M: pair effect>type second effect>type ;
 
 GENERIC: stack-effect ( word -- effect/f )
 
-M: word stack-effect "declared-effect" word-prop ;
+M: word stack-effect
+    [ "declared-effect" word-prop ]
+    [ parent-word dup [ stack-effect ] when ] bi or ;
 
 M: deferred stack-effect call-next-method (( -- * )) or ;
 
diff --git a/core/generic/generic-tests.factor b/core/generic/generic-tests.factor
index 700448805c..805c3a4be4 100644
--- a/core/generic/generic-tests.factor
+++ b/core/generic/generic-tests.factor
@@ -212,3 +212,16 @@ M: integer forget-test 3 + ;
 ] unit-test
 
 [ 10 forget-test ] [ no-method? ] must-fail-with
+
+! Declarations on methods
+GENERIC: flushable-generic ( a -- b ) flushable
+M: integer flushable-generic ;
+
+[ t ] [ \ flushable-generic flushable? ] unit-test
+[ t ] [ M\ integer flushable-generic flushable? ] unit-test
+
+GENERIC: non-flushable-generic ( a -- b )
+M: integer non-flushable-generic ; flushable
+
+[ f ] [ \ non-flushable-generic flushable? ] unit-test
+[ t ] [ M\ integer non-flushable-generic flushable? ] unit-test
diff --git a/core/generic/generic.factor b/core/generic/generic.factor
index 9fd7a5be85..0c626ac1d6 100644
--- a/core/generic/generic.factor
+++ b/core/generic/generic.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2006, 2009 Slava Pestov.
+! Copyright (C) 2006, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors words kernel sequences namespaces make assocs
 hashtables definitions kernel.private classes classes.private
@@ -104,11 +104,8 @@ GENERIC: update-generic ( class generic -- )
 : method-word-name ( class generic -- string )
     [ name>> ] bi@ "=>" glue ;
 
-M: method flushable?
-    "method-generic" word-prop flushable? ;
-
-M: method stack-effect
-    "method-generic" word-prop stack-effect ;
+M: method parent-word
+    "method-generic" word-prop ;
 
 M: method crossref?
     "forgotten" word-prop not ;
@@ -196,8 +193,5 @@ M: generic subwords
         tri
     ] { } make ;
 
-M: generic forget*
-    [ subwords forget-all ] [ call-next-method ] bi ;
-
 M: class forget-methods
     [ implementors ] [ [ swap method ] curry ] bi map forget-all ;
diff --git a/core/words/words.factor b/core/words/words.factor
index 5b057230fe..2a4c2c4c06 100644
--- a/core/words/words.factor
+++ b/core/words/words.factor
@@ -73,12 +73,14 @@ GENERIC: crossref? ( word -- ? )
 M: word crossref?
     dup "forgotten" word-prop [ drop f ] [ vocabulary>> >boolean ] if ;
 
-: inline? ( word -- ? ) "inline" word-prop ; inline
-
 GENERIC: subwords ( word -- seq )
 
 M: word subwords drop f ;
 
+GENERIC: parent-word ( word -- word/f )
+
+M: word parent-word drop f ;
+
 : define ( word def -- )
     over changed-definition [ ] like >>def drop ;
 
@@ -100,6 +102,8 @@ M: word subwords drop f ;
 : make-deprecated ( word -- )
     t "deprecated" set-word-prop ;
 
+: inline? ( word -- ? ) "inline" word-prop ; inline
+
 ERROR: cannot-be-inline word ;
 
 GENERIC: make-inline ( word -- )
@@ -111,22 +115,30 @@ M: word make-inline
         bi
     ] if ;
 
+: define-inline ( word def effect -- )
+    [ define-declared ] [ 2drop make-inline ] 3bi ;
+
 : make-recursive ( word -- )
     t "recursive" set-word-prop ;
 
+GENERIC: flushable? ( word -- ? )
+
+M: word flushable?
+    [ "flushable" word-prop ]
+    [ parent-word dup [ flushable? ] when ] bi or ;
+
 : make-flushable ( word -- )
     t "flushable" set-word-prop ;
 
+GENERIC: foldable? ( word -- ? )
+
+M: word foldable?
+    [ "foldable" word-prop ]
+    [ parent-word dup [ foldable? ] when ] bi or ;
+
 : make-foldable ( word -- )
     dup make-flushable t "foldable" set-word-prop ;
 
-: define-inline ( word def effect -- )
-    [ define-declared ] [ 2drop make-inline ] 3bi ;
-
-GENERIC: flushable? ( word -- ? )
-
-M: word flushable? "flushable" word-prop ;
-
 GENERIC: reset-word ( word -- )
 
 M: word reset-word
@@ -208,9 +220,10 @@ M: word set-where swap "loc" set-word-prop ;
 
 M: word forget*
     dup "forgotten" word-prop [ drop ] [
+        [ subwords forget-all ]
         [ [ name>> ] [ vocabulary>> vocab-words ] bi delete-at ]
         [ t "forgotten" set-word-prop ]
-        bi
+        tri
     ] if ;
 
 M: word hashcode*

From 282f284515c90cadf4b1e262087ee8469f80b348 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Wed, 24 Feb 2010 00:46:11 +1300
Subject: [PATCH 203/250] freetype: fix load error

---
 extra/freetype/freetype.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/extra/freetype/freetype.factor b/extra/freetype/freetype.factor
index 23dd62b340..955672d03b 100644
--- a/extra/freetype/freetype.factor
+++ b/extra/freetype/freetype.factor
@@ -166,7 +166,7 @@ STRUCT: FT_Bitmap
     { palette_mode char }
     { palette void* } ;
 
-TYPEDEF: void* FT_Face*
+C-TYPE: FT_Face
 
 FUNCTION: FT_Error FT_New_Face ( void* library, FT_Char* font, FT_Long index, face* face ) ;
 

From 75e2a5098ec13b43e8639efd34e0f307585713b5 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 08:09:33 -0800
Subject: [PATCH 204/250] if any typedef in the chain has a pointer-c-type, use
 it

---
 basis/alien/c-types/c-types-tests.factor | 8 ++++++++
 basis/alien/c-types/c-types.factor       | 2 +-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/basis/alien/c-types/c-types-tests.factor b/basis/alien/c-types/c-types-tests.factor
index ad53dc487b..10a7b50ebb 100644
--- a/basis/alien/c-types/c-types-tests.factor
+++ b/basis/alien/c-types/c-types-tests.factor
@@ -44,6 +44,14 @@ TYPEDEF: char MyFunkyChar
 [ f ] [ pointer: char c-type pointer: MyFunkyChar c-type = ] unit-test
 [ { char* ascii } ] [ pointer: MyFunkyChar c-type ] unit-test
 
+TYPEDEF: MyFunkyChar MyFunkyTypedef
+
+[ { char* ascii } ] [ pointer: MyFunkyTypedef c-type ] unit-test
+
+TYPEDEF: MyFunkyChar* MyFunkyString
+
+[ { char* ascii } ] [ MyFunkyString c-type ] unit-test
+
 TYPEDEF: char* MyString
 
 [ t ] [ char* c-type MyString          c-type = ] unit-test
diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor
index 316377dc27..3255d16d80 100644
--- a/basis/alien/c-types/c-types.factor
+++ b/basis/alien/c-types/c-types.factor
@@ -301,7 +301,7 @@ CONSTANT: primitive-types
 : special-pointer-type ( type -- special-type )
     dup c-type-word? [
         dup "pointer-c-type" word-prop
-        [ ] [ resolve-pointer-typedef "pointer-c-type" word-prop ] ?if
+        [ ] [ "c-type" word-prop special-pointer-type ] ?if
     ] [ drop f ] if ;
 
 : primitive-pointer-type? ( type -- ? )

From 8aa10c528312c8e12020c9306ce70136d08e049e Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 08:10:01 -0800
Subject: [PATCH 205/250] windows.types: fix definition of wchar_t* as { char*
 utf16n }

---
 basis/windows/types/types.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/windows/types/types.factor b/basis/windows/types/types.factor
index 4f527513fc..d0dac31ea9 100644
--- a/basis/windows/types/types.factor
+++ b/basis/windows/types/types.factor
@@ -11,7 +11,7 @@ TYPEDEF: uchar               UCHAR
 TYPEDEF: uchar               BYTE
 
 TYPEDEF: ushort              wchar_t
-TYPEDEF: { char* utf16n }    wchar_t*
+<< { char* utf16n } pointer: wchar_t typedef >>
 
 TYPEDEF: wchar_t             WCHAR
 

From 00a7559d55bcdb92872273f3697e91c764434102 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 10:16:18 -0800
Subject: [PATCH 206/250] have TYPEDEF:, STRUCT: etc. throw an error if you try
 to define a c type name ending with asterisk

---
 basis/alien/parser/parser.factor | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor
index 14078f3137..f5fdced048 100644
--- a/basis/alien/parser/parser.factor
+++ b/basis/alien/parser/parser.factor
@@ -46,8 +46,14 @@ IN: alien.parser
         "callback-library"
     } reset-props ;
 
+ERROR: *-in-c-type-name name ;
+
+: validate-c-type-name ( name -- name )
+    dup "*" tail?
+    [ *-in-c-type-name ] when ;
+
 : CREATE-C-TYPE ( -- word )
-    scan current-vocab create {
+    scan validate-c-type-name current-vocab create {
         [ fake-definition ]
         [ set-word ]
         [ reset-c-type ]

From b0bf5f310606545607b74d363b76202bf5674218 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 10:17:48 -0800
Subject: [PATCH 207/250] get rid of the last few pointer typedefs in
 db.postgresql.ffi, windows.usp10, and windows.winsock

---
 basis/db/postgresql/ffi/ffi.factor   | 1 -
 basis/windows/usp10/usp10.factor     | 2 +-
 basis/windows/winsock/winsock.factor | 2 +-
 3 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/basis/db/postgresql/ffi/ffi.factor b/basis/db/postgresql/ffi/ffi.factor
index f4a55e3280..69ac2c5e5e 100644
--- a/basis/db/postgresql/ffi/ffi.factor
+++ b/basis/db/postgresql/ffi/ffi.factor
@@ -63,7 +63,6 @@ C-TYPE: PGconn
 C-TYPE: PGresult
 C-TYPE: PGcancel
 TYPEDEF: uint Oid
-TYPEDEF: uint* Oid*
 TYPEDEF: char pqbool
 C-TYPE: PQconninfoOption
 C-TYPE: PGnotify
diff --git a/basis/windows/usp10/usp10.factor b/basis/windows/usp10/usp10.factor
index 57702d8780..1c33aaf940 100644
--- a/basis/windows/usp10/usp10.factor
+++ b/basis/windows/usp10/usp10.factor
@@ -57,7 +57,7 @@ SCRIPT_JUSTIFFY_RESERVED4 ;
 STRUCT: SCRIPT_VISATTR
     { flags WORD } ;
 
-TYPEDEF: void* SCRIPT_CACHE*
+C-TYPE: SCRIPT_CACHE
 C-TYPE: ABC
 
 FUNCTION: HRESULT ScriptShape (
diff --git a/basis/windows/winsock/winsock.factor b/basis/windows/winsock/winsock.factor
index b8d1f099d2..818737ca5a 100644
--- a/basis/windows/winsock/winsock.factor
+++ b/basis/windows/winsock/winsock.factor
@@ -141,7 +141,7 @@ STRUCT: timeval
     { sec long }
     { usec long } ;
 
-TYPEDEF: void* fd_set*
+C-TYPE: fd_set
 
 LIBRARY: winsock
 

From 818bbb4984e556fbdb7f46a6a5a2d42e704ac904 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 11:03:48 -0800
Subject: [PATCH 208/250] update docs about pointer types

---
 basis/alien/c-types/c-types-docs.factor | 21 +++++++++++++++++----
 basis/alien/syntax/syntax-docs.factor   |  8 ++++----
 core/alien/alien-docs.factor            |  4 ++--
 3 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/basis/alien/c-types/c-types-docs.factor b/basis/alien/c-types/c-types-docs.factor
index 215ca1b0ef..f0a339b1aa 100644
--- a/basis/alien/c-types/c-types-docs.factor
+++ b/basis/alien/c-types/c-types-docs.factor
@@ -103,7 +103,7 @@ HELP: ulonglong
 HELP: void
 { $description "This symbol is not a valid C type, but it can be used as the return type for a " { $link POSTPONE: FUNCTION: } " or " { $link POSTPONE: CALLBACK: } " definition or for an " { $link alien-invoke } " or " { $link alien-callback } " call." } ;
 HELP: void*
-{ $description "This C type represents a pointer to C memory. " { $link byte-array } " and " { $link alien } " values can be passed as " { $snippet "void*" } " function inputs, but see " { $link "byte-arrays-gc" } " for notes about passing byte arrays into C functions. " { $snippet "void*" } " output values are returned as " { $link alien } "s." } ;
+{ $description "This C type represents a generic pointer to C memory. See " { $link pointer } " for information on pointer C types." }
 HELP: char*
 { $description "This C type represents a pointer to a C string. See " { $link "c-strings" } " for details about using strings with the FFI." } ;
 HELP: float
@@ -115,6 +115,19 @@ HELP: complex-float
 HELP: complex-double
 { $description "This C type represents a double-precision IEEE 754 floating-point complex type. Input values will be converted from Factor " { $link math:complex } " objects into a double-precision complex float type; output values will be returned as Factor " { $link math:complex } " objects." } ;
 
+HELP: pointer:
+{ $syntax "pointer: c-type" }
+{ $description "Constructs a " { $link pointer } " C type." } ;
+
+HELP: pointer
+{ $class-description "Represents a pointer C type. The " { $snippet "to" } " slot contains the C type being pointed to." { $link byte-array } " and " { $link alien } " values can be provided as pointer function inputs, but see " { $link "byte-arrays-gc" } " for notes about passing byte arrays into C functions. Objects with methods on " { $link >c-ptr } ", such as structs and specialized arrays, may also be used as pointer inputs."
+$nl
+"Pointer output values are represented in Factor as " { $link alien } "s. If the pointed-to type is a struct, the alien will automatically be wrapped in a struct object if it is not null."
+$nl
+"In " { $link POSTPONE: TYPEDEF: } ", " { $link POSTPONE: FUNCTION: } ", " { $link POSTPONE: CALLBACK: } ", and " { $link POSTPONE: STRUCT: } " definitions, pointer types can be created by suffixing " { $snippet "*" } " to a C type name. Outside of FFI definitions, a pointer C type can be created using the " { $link POSTPONE: pointer: } " syntax word:"
+{ $unchecked-example "FUNCTION: int* foo ( char* bar ) ;" }
+{ $unchecked-example """: foo ( bar -- int* )
+    pointer: int f \"foo\" { pointer: char } alien-invoke ;""" } } ;
 
 ARTICLE: "byte-arrays-gc" "Byte arrays and the garbage collector"
 "The Factor garbage collector can move byte arrays around, and it is only safe to pass byte arrays to C functions if the garbage collector will not run while C code still has a reference to the data."
@@ -191,11 +204,11 @@ ARTICLE: "c-types.primitives" "Primitive C types"
 "When making alien calls, Factor numbers are converted to and from the above types in a canonical way. Converting a Factor number to a C value may result in a loss of precision." ;
 
 ARTICLE: "c-types.pointers" "Pointer and array types"
-"Pointer types are specified by suffixing a C type with " { $snippet "*" } ", for example " { $snippet "float*" } ". One special case is " { $link void* } ", which denotes a generic pointer; " { $link void } " by itself is not a valid C type specifier. With the exception of strings (see " { $link "c-strings" } "), all pointer types are identical to " { $snippet "void*" } " as far as the C library interface is concerned."
+"Pointer types are specified by suffixing a C type with " { $snippet "*" } ", for example " { $snippet "float*" } ". One special case is " { $link void* } ", which denotes a generic pointer; " { $link void } " by itself is not a valid C type specifier. This syntax constructs a " { $link pointer } " object to represent the C type."
 $nl
 "Fixed-size array types are supported; the syntax consists of a C type name followed by dimension sizes in brackets; the following denotes a 3 by 4 array of integers:"
 { $code "int[3][4]" }
-"Fixed-size arrays differ from pointers in that they are allocated inside structures and unions; however when used as function parameters they behave exactly like pointers and thus the dimensions only serve as documentation." ;
+"Fixed-size arrays differ from pointers in that they are allocated inside structures and unions; however, when used as function parameters, they behave exactly like pointers with the dimensions only serving as documentation." ;
 
 ARTICLE: "c-types.ambiguity" "Word name clashes with C types"
 "Note that some of the C type word names clash with commonly-used Factor words:"
@@ -228,7 +241,7 @@ ARTICLE: "c-types.structs" "Struct and union types"
 "Struct and union types are identified by their class word. See " { $link "classes.struct" } "." ;
 
 ARTICLE: "c-types-specs" "C type specifiers"
-"C types are identified by special words, and type names occur as parameters to the " { $link alien-invoke } ", " { $link alien-indirect } " and " { $link alien-callback } " words."
+"C types are identified by special words. Type names occur as parameters to the " { $link alien-invoke } ", " { $link alien-indirect } " and " { $link alien-callback } " words."
 $nl
 "Defining new C types:"
 { $subsections
diff --git a/basis/alien/syntax/syntax-docs.factor b/basis/alien/syntax/syntax-docs.factor
index a8d3048b82..8ec67d2f65 100644
--- a/basis/alien/syntax/syntax-docs.factor
+++ b/basis/alien/syntax/syntax-docs.factor
@@ -54,7 +54,7 @@ $nl
 HELP: TYPEDEF:
 { $syntax "TYPEDEF: old new" }
 { $values { "old" "a C type" } { "new" "a C type" } }
-{ $description "Aliases the C type " { $snippet "old" } " under the name " { $snippet "new" } " if ." }
+{ $description "Aliases the C type " { $snippet "old" } " under the name " { $snippet "new" } "." }
 { $notes "This word differs from " { $link typedef } " in that it runs at parse time, to ensure correct ordering of operations when loading source files. Words defined in source files are compiled before top-level forms are run, so if a source file defines C binding words and uses " { $link typedef } ", the type alias won't be available at compile time." } ;
 
 HELP: C-ENUM:
@@ -72,12 +72,12 @@ HELP: C-ENUM:
 HELP: C-TYPE:
 { $syntax "C-TYPE: type" }
 { $values { "type" "a new C type" } }
-{ $description "Defines a new, opaque C type. Since it is opaque, " { $snippet "type" } " will not be directly usable as a parameter or return type of a " { $link POSTPONE: FUNCTION: } " or as a slot of a " { $link POSTPONE: STRUCT: } ". However, it can be used as the type of a pointer (that is, as " { $snippet "type*" } ")." $nl
-{ $snippet "C-TYPE:" } " can also be used to forward-declare C types to enable circular dependencies. For example:"
+{ $description "Defines a new, opaque C type. Since it is opaque, " { $snippet "type" } " will not be directly usable as a parameter or return type of a " { $link POSTPONE: FUNCTION: } " or as a slot of a " { $link POSTPONE: STRUCT: } ". However, it can be used as the type of a " { $link pointer } "."
+{ $snippet "C-TYPE:" } " can also be used to forward declare C types, allowing circular dependencies to occur between types. For example:"
 { $code """C-TYPE: forward 
 STRUCT: backward { x forward* } ;
 STRUCT: forward { x backward* } ; """ } }
-{ $notes "Primitive C types are also displayed using " { $snippet "C-TYPE:" } " syntax when they are displayed by " { $link see } "." } ;
+{ $notes "Primitive C types are displayed using " { $snippet "C-TYPE:" } " syntax when they are " { $link see } "n." } ;
 
 HELP: CALLBACK:
 { $syntax "CALLBACK: return type ( parameters ) ;" }
diff --git a/core/alien/alien-docs.factor b/core/alien/alien-docs.factor
index 98292b8728..0b4976fcbe 100644
--- a/core/alien/alien-docs.factor
+++ b/core/alien/alien-docs.factor
@@ -42,7 +42,7 @@ HELP: <alien>
 { $notes "Alien objects are invalidated between image saves and loads." } ;
 
 HELP: c-ptr
-{ $class-description "Class of objects consisting of aliens, byte arrays and " { $link f } ". These objects can convert to pointer C types, which are all aliases of " { $snippet "void*" } "." } ;
+{ $class-description "Class of objects consisting of aliens, byte arrays and " { $link f } ". These objects all can be used as values of " { $link pointer } " C types." } ;
 
 HELP: alien-invoke-error
 { $error-description "Thrown if the word calling " { $link alien-invoke } " was not compiled with the optimizing compiler. This may be a result of one of several failure conditions:"
@@ -136,7 +136,7 @@ ARTICLE: "aliens" "Alien addresses"
 }
 "Anywhere that a " { $link alien } " instance is accepted, the " { $link f } " singleton may be passed in to denote a null pointer."
 $nl
-"Usually alien objects do not have to created and dereferenced directly; instead declaring C function parameters and return values as having a pointer type such as " { $snippet "void*" } " takes care of the details."
+"Usually alien objects do not have to created and dereferenced directly; instead declaring C function parameters and return values as having a " pointer type such as " { $snippet "void*" } " takes care of the details."
 { $subsections
     "syntax-aliens"
     "alien-expiry"

From 4cfa1a6c77465f75745da24ce92456bae7258e10 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 11:42:02 -0800
Subject: [PATCH 209/250] rename current string-mangling "char*" to "c-string".
 char* is now just a boring old pointer to char

---
 basis/alien/arrays/arrays.factor              |   8 +-
 basis/alien/c-types/c-types-docs.factor       |   2 +-
 basis/alien/c-types/c-types-tests.factor      |  27 +---
 basis/alien/c-types/c-types.factor            |   6 +-
 basis/alien/data/data-docs.factor             |  10 +-
 basis/alien/parser/parser-tests.factor        |   4 +-
 .../remote-control/remote-control.factor      |   2 +-
 basis/alien/syntax/syntax-docs.factor         |   4 +-
 basis/cairo/ffi/ffi.factor                    |  26 ++--
 basis/classes/struct/struct-docs.factor       |   2 +-
 basis/classes/struct/struct-tests.factor      |   2 +-
 basis/cocoa/messages/messages.factor          |   2 +-
 basis/cocoa/runtime/runtime.factor            |  16 +--
 basis/compiler/tests/alien.factor             |   4 +-
 basis/core-foundation/data/data.factor        |   2 +-
 basis/core-foundation/strings/strings.factor  |   4 +-
 basis/db/postgresql/ffi/ffi.factor            | 124 +++++++++---------
 basis/db/sqlite/ffi/ffi.factor                |  18 +--
 basis/iokit/hid/hid.factor                    |  18 +--
 basis/iokit/iokit.factor                      |   8 +-
 basis/libc/libc.factor                        |   2 +-
 basis/opengl/gl/gl.factor                     |   2 +-
 basis/opengl/gl/windows/windows.factor        |   2 +-
 basis/openssl/libcrypto/libcrypto.factor      |  14 +-
 basis/openssl/libssl/libssl.factor            |  20 +--
 basis/pango/fonts/fonts.factor                |  12 +-
 basis/pango/layouts/layouts.factor            |   4 +-
 basis/system-info/linux/linux.factor          |   2 +-
 basis/tools/disassembler/udis/udis.factor     |  12 +-
 basis/unix/ffi/bsd/bsd.factor                 |  12 +-
 basis/unix/ffi/bsd/freebsd/freebsd.factor     |   2 +-
 basis/unix/ffi/bsd/macosx/macosx.factor       |   2 +-
 basis/unix/ffi/bsd/netbsd/netbsd.factor       |   2 +-
 basis/unix/ffi/bsd/openbsd/openbsd.factor     |   2 +-
 basis/unix/ffi/ffi.factor                     |  70 +++++-----
 basis/unix/ffi/linux/linux.factor             |  14 +-
 basis/unix/ffi/solaris/solaris.factor         |   2 +-
 basis/unix/linux/inotify/inotify.factor       |   2 +-
 basis/unix/process/process.factor             |   6 +-
 basis/unix/stat/freebsd/freebsd.factor        |   4 +-
 basis/unix/stat/linux/32/32.factor            |   4 +-
 basis/unix/stat/linux/64/64.factor            |   4 +-
 basis/unix/stat/macosx/macosx.factor          |   4 +-
 basis/unix/stat/netbsd/32/32.factor           |   4 +-
 basis/unix/stat/netbsd/64/64.factor           |   4 +-
 basis/unix/stat/openbsd/openbsd.factor        |   4 +-
 basis/unix/statfs/freebsd/freebsd.factor      |   2 +-
 basis/unix/statfs/linux/linux.factor          |   2 +-
 basis/unix/statfs/macosx/macosx.factor        |   2 +-
 basis/unix/statfs/openbsd/openbsd.factor      |   2 +-
 basis/unix/statvfs/freebsd/freebsd.factor     |   2 +-
 basis/unix/statvfs/linux/linux.factor         |   2 +-
 basis/unix/statvfs/macosx/macosx.factor       |   2 +-
 basis/unix/statvfs/netbsd/netbsd.factor       |   2 +-
 basis/unix/statvfs/openbsd/openbsd.factor     |   2 +-
 basis/unix/time/time.factor                   |   2 +-
 basis/windows/kernel32/kernel32.factor        |   2 +-
 basis/windows/ole32/ole32.factor              |   4 +-
 basis/windows/opengl32/opengl32.factor        |   2 +-
 basis/windows/types/types.factor              |  23 ++--
 basis/windows/user32/user32.factor            |   6 +-
 basis/windows/winsock/winsock.factor          |  20 +--
 basis/x11/glx/glx.factor                      |  10 +-
 basis/x11/xlib/xlib.factor                    |  42 +++---
 extra/chipmunk/chipmunk.factor                |   2 +-
 extra/curses/ffi/ffi.factor                   |  48 +++----
 extra/freetype/freetype.factor                |   2 +-
 extra/libusb/libusb.factor                    |  16 +--
 extra/llvm/core/core.factor                   | 114 ++++++++--------
 extra/llvm/engine/engine.factor               |   8 +-
 extra/llvm/types/types.factor                 |   2 +-
 extra/llvm/wrappers/wrappers.factor           |   2 +-
 .../native-thread-test.factor                 |   2 +-
 extra/ogg/ogg.factor                          |  22 ++--
 extra/ogg/theora/theora.factor                |  16 +--
 extra/ogg/vorbis/vorbis.factor                |  12 +-
 extra/openal/alut/alut.factor                 |  12 +-
 extra/opengl/glu/glu.factor                   |   4 +-
 extra/tokyo/alien/tcadb/tcadb.factor          |  28 ++--
 extra/tokyo/alien/tcbdb/tcbdb.factor          |  44 +++----
 extra/tokyo/alien/tcfdb/tcfdb.factor          |  30 ++---
 extra/tokyo/alien/tchdb/tchdb.factor          |  34 ++---
 extra/tokyo/alien/tcrdb/tcrdb.factor          |  56 ++++----
 extra/tokyo/alien/tctdb/tctdb.factor          |  44 +++----
 extra/tokyo/alien/tcutil/tcutil.factor        |   4 +-
 85 files changed, 556 insertions(+), 576 deletions(-)

diff --git a/basis/alien/arrays/arrays.factor b/basis/alien/arrays/arrays.factor
index f9a47f256c..ce6eb85245 100644
--- a/basis/alien/arrays/arrays.factor
+++ b/basis/alien/arrays/arrays.factor
@@ -40,7 +40,7 @@ M: array c-type-boxer-quot
 M: array c-type-unboxer-quot drop [ >c-ptr ] ;
 
 PREDICATE: string-type < pair
-    first2 [ char* = ] [ word? ] bi* and ;
+    first2 [ c-string = ] [ word? ] bi* and ;
 
 M: string-type c-type ;
 
@@ -100,9 +100,5 @@ M: string-type c-type-getter
 M: string-type c-type-setter
     drop [ set-alien-cell ] ;
 
-{ char* utf8 } char <pointer> typedef
-{ char* utf8 } char* typedef
-{ char* utf8 } uchar <pointer> typedef
-{ char* binary } byte <pointer> typedef
-{ char* binary } ubyte <pointer> typedef
+{ c-string utf8 } c-string typedef
 
diff --git a/basis/alien/c-types/c-types-docs.factor b/basis/alien/c-types/c-types-docs.factor
index f0a339b1aa..e73ce556b5 100644
--- a/basis/alien/c-types/c-types-docs.factor
+++ b/basis/alien/c-types/c-types-docs.factor
@@ -104,7 +104,7 @@ HELP: void
 { $description "This symbol is not a valid C type, but it can be used as the return type for a " { $link POSTPONE: FUNCTION: } " or " { $link POSTPONE: CALLBACK: } " definition or for an " { $link alien-invoke } " or " { $link alien-callback } " call." } ;
 HELP: void*
 { $description "This C type represents a generic pointer to C memory. See " { $link pointer } " for information on pointer C types." }
-HELP: char*
+HELP: c-string
 { $description "This C type represents a pointer to a C string. See " { $link "c-strings" } " for details about using strings with the FFI." } ;
 HELP: float
 { $description "This C type represents a single-precision IEEE 754 floating-point type. Input values will be converted to Factor " { $link math:float } "s and demoted to single-precision; output values will be returned as Factor " { $link math:float } "s." } ;
diff --git a/basis/alien/c-types/c-types-tests.factor b/basis/alien/c-types/c-types-tests.factor
index 10a7b50ebb..7ad4bbb074 100644
--- a/basis/alien/c-types/c-types-tests.factor
+++ b/basis/alien/c-types/c-types-tests.factor
@@ -22,7 +22,7 @@ UNION-STRUCT: foo
 [ f ] [ pointer: foo  c-type void* c-type = ] unit-test
 [ t ] [ pointer: foo* c-type void* c-type = ] unit-test
 
-[ t ] [ pointer: char c-type char* c-type = ] unit-test
+[ t ] [ c-string c-type c-string c-type = ] unit-test
 
 [ t ] [ foo heap-size int heap-size = ] unit-test
 
@@ -35,36 +35,21 @@ TYPEDEF: int MyInt
 
 TYPEDEF: char MyChar
 
-[ t ] [ pointer: char c-type pointer: MyChar c-type = ] unit-test
-[ t ] [ char*         c-type pointer: MyChar c-type = ] unit-test
+[ t ] [ pointer: void c-type pointer: MyChar c-type = ] unit-test
 
-TYPEDEF: char MyFunkyChar
-{ char* ascii } pointer: MyFunkyChar typedef
+TYPEDEF: { c-string ascii } MyFunkyString
 
-[ f ] [ pointer: char c-type pointer: MyFunkyChar c-type = ] unit-test
-[ { char* ascii } ] [ pointer: MyFunkyChar c-type ] unit-test
+[ { c-string ascii } ] [ MyFunkyString c-type ] unit-test
 
-TYPEDEF: MyFunkyChar MyFunkyTypedef
+TYPEDEF: c-string MyString
 
-[ { char* ascii } ] [ pointer: MyFunkyTypedef c-type ] unit-test
-
-TYPEDEF: MyFunkyChar* MyFunkyString
-
-[ { char* ascii } ] [ MyFunkyString c-type ] unit-test
-
-TYPEDEF: char* MyString
-
-[ t ] [ char* c-type MyString          c-type = ] unit-test
+[ t ] [ c-string c-type MyString          c-type = ] unit-test
 [ t ] [ void* c-type pointer: MyString c-type = ] unit-test
 
 TYPEDEF: int* MyIntArray
 
 [ t ] [ void* c-type MyIntArray c-type = ] unit-test
 
-TYPEDEF: char* MyLPBYTE
-
-[ t ] [ { char* utf8 } c-type MyLPBYTE c-type = ] unit-test
-
 [
     0 B{ 1 2 3 4 } <displaced-alien> <void*>
 ] must-fail
diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor
index 3255d16d80..73da41cc69 100644
--- a/basis/alien/c-types/c-types.factor
+++ b/basis/alien/c-types/c-types.factor
@@ -273,7 +273,7 @@ M: long-long-type box-return ( c-type -- )
 
 SYMBOLS:
     ptrdiff_t intptr_t uintptr_t size_t
-    byte ubyte char* ;
+    c-string ;
 
 CONSTANT: primitive-types
     {
@@ -284,7 +284,7 @@ CONSTANT: primitive-types
         longlong ulonglong
         float double
         void* bool
-        char*
+        c-string
     }
 
 : (pointer-c-type) ( void* type -- void*' )
@@ -530,8 +530,6 @@ M: pointer c-type
         \ uint c-type \ size_t typedef
     ] if
 
-    \ char \ byte typedef
-    \ uchar \ ubyte typedef
 ] with-compilation-unit
 
 M: char-16-rep rep-component-type drop char ;
diff --git a/basis/alien/data/data-docs.factor b/basis/alien/data/data-docs.factor
index 0536d15736..895b8536f7 100644
--- a/basis/alien/data/data-docs.factor
+++ b/basis/alien/data/data-docs.factor
@@ -140,13 +140,13 @@ HELP: <c-direct-array>
 { $notes "The appropriate specialized array vocabulary must be loaded; otherwise, an error will be thrown. The vocabulary can be loaded with the " { $link require-c-array } " word. See the " { $vocab-link "specialized-arrays" } " vocabulary for details on the underlying sequence type constructed." } ;
 
 ARTICLE: "c-strings" "C strings"
-"C string types are arrays with shape " { $snippet "{ char* encoding }" } ", where " { $snippet "encoding" } " is an encoding descriptor. The type " { $link char* } " is an alias for " { $snippet "{ char* utf8 }" } ". See " { $link "encodings-descriptors" } " for information about encoding descriptors."
+"C string types are arrays with shape " { $snippet "{ c-string encoding }" } ", where " { $snippet "encoding" } " is an encoding descriptor. The type " { $link c-string } " is an alias for " { $snippet "{ c-string utf8 }" } ". See " { $link "encodings-descriptors" } " for information about encoding descriptors. In " { $link POSTPONE: TYPEDEF: } ", " { $link POSTPONE: FUNCTION: } ", " { $link POSTPONE: CALLBACK: } ", and " { $link POSTPONE: STRUCT: } " definitions, the shorthand syntax " { $snippet "c-string[encoding]" } " can be used to specify the string encoding."
 $nl
-"Passing a Factor string to a C function expecting a C string allocates a " { $link byte-array } " in the Factor heap; the string is then converted to the requested format and a raw pointer is passed to the function."
+"Passing a Factor string to a C function expecting a " { $link c-string } " allocates a " { $link byte-array } " in the Factor heap; the string is then converted to the requested format and a raw pointer is passed to the function."
 $nl
 "If the conversion fails, for example if the string contains null bytes or characters with values higher than 255, a " { $link c-string-error. } " is thrown."
 $nl
-"Care must be taken if the C function expects a " { $link char* } " with a length in bytes, rather than a null-terminated " { $link char* } "; passing the result of calling " { $link length } " on the string object will not suffice. This is because a Factor string of " { $emphasis "n" } " characters will not necessarily encode to " { $emphasis "n" } " bytes. The correct idiom for C functions which take a string with a length is to first encode the string using " { $link encode } ", and then pass the resulting byte array together with the length of this byte array."
+"Care must be taken if the C function expects a pointer to a string with its length represented by another parameter rather than a null terminator. Passing the result of calling " { $link length } " on the string object will not suffice. This is because a Factor string of " { $emphasis "n" } " characters will not necessarily encode to " { $emphasis "n" } " bytes. The correct idiom for C functions which take a string with a length is to first encode the string using " { $link encode } ", and then pass the resulting byte array together with the length of this byte array."
 $nl
 "Sometimes a C function has a parameter type of " { $link void* } ", and various data types, among them strings, can be passed in. In this case, strings are not automatically converted to aliens, and instead you must call one of these words:"
 { $subsections
@@ -155,7 +155,9 @@ $nl
 }
 "The first allocates " { $link byte-array } "s, and the latter allocates manually-managed memory which is not moved by the garbage collector and has to be explicitly freed by calling " { $link free } ". See " { $link "byte-arrays-gc" } " for a discussion of the two approaches."
 $nl
+"The C type " { $link char } { $snippet "*" } " represents a generic pointer to " { $snippet "char" } "; arguments with this type will expect and return " { $link alien } "s, and won't perform any implicit string conversion."
+$nl
 "A word to read strings from arbitrary addresses:"
 { $subsections alien>string }
-"For example, if a C function returns a " { $link char* } " but stipulates that the caller must deallocate the memory afterward, you must define the function as returning " { $link void* } ", and call one of the above words before passing the pointer to " { $link free } "." ;
+"For example, if a C function returns a " { $link c-string } " but stipulates that the caller must deallocate the memory afterward, you must define the function as returning " { $snippet "char*" } " and call one of the above words before passing the pointer to " { $link free } "." ;
 
diff --git a/basis/alien/parser/parser-tests.factor b/basis/alien/parser/parser-tests.factor
index 37f10722d1..a730e3084f 100644
--- a/basis/alien/parser/parser-tests.factor
+++ b/basis/alien/parser/parser-tests.factor
@@ -23,9 +23,9 @@ CONSTANT: eleven 11
     [ pointer: int* ] [ "int**" parse-c-type ] unit-test
     [ pointer: int** ] [ "int***" parse-c-type ] unit-test
     [ pointer: int*** ] [ "int****" parse-c-type ] unit-test
-    [ pointer: char ] [ "char*" parse-c-type ] unit-test
+    [ c-string ] [ "c-string" parse-c-type ] unit-test
     [ char2 ] [ "char2" parse-c-type ] unit-test
-    [ pointer: char2 ] [ "char2*" parse-c-type ] unit-test
+    [ c-string2 ] [ "char2*" parse-c-type ] unit-test
 
     [ "not-word" parse-c-type ] [ error>> no-word-error? ] must-fail-with
 ] with-file-vocabs
diff --git a/basis/alien/remote-control/remote-control.factor b/basis/alien/remote-control/remote-control.factor
index ae694bed9c..c305d720f0 100644
--- a/basis/alien/remote-control/remote-control.factor
+++ b/basis/alien/remote-control/remote-control.factor
@@ -6,7 +6,7 @@ eval ;
 IN: alien.remote-control
 
 : eval-callback ( -- callback )
-    void* { char* } "cdecl"
+    void* { c-string } "cdecl"
     [ eval>string utf8 malloc-string ] alien-callback ;
 
 : yield-callback ( -- callback )
diff --git a/basis/alien/syntax/syntax-docs.factor b/basis/alien/syntax/syntax-docs.factor
index 8ec67d2f65..3d1c757035 100644
--- a/basis/alien/syntax/syntax-docs.factor
+++ b/basis/alien/syntax/syntax-docs.factor
@@ -40,11 +40,11 @@ $nl
 }
 "You can define a word for invoking it:"
 { $unchecked-example
-    "LIBRARY: foo\nFUNCTION: void the_answer ( char* question, int value ) ;"
-    "USE: compiler"
+    "LIBRARY: foo\nFUNCTION: void the_answer ( c-string question, int value ) ;"
     "\"the question\" 42 the_answer"
     "The answer to the question is 42."
 } }
+"Using the " { $link c-string } " type instead of " { $snippet "char*" } " causes the FFI to automatically convert Factor strings to C strings. See " { $link "c-strings" } " for more information on using strings with the FFI."
 { $notes "Note that the parentheses and commas are only syntax sugar and can be omitted; they serve no purpose other than to make the declaration slightly easier to read:"
 { $code
     "FUNCTION: void glHint ( GLenum target, GLenum mode ) ;"
diff --git a/basis/cairo/ffi/ffi.factor b/basis/cairo/ffi/ffi.factor
index 49975afc61..bca02c1f17 100644
--- a/basis/cairo/ffi/ffi.factor
+++ b/basis/cairo/ffi/ffi.factor
@@ -18,7 +18,7 @@ IN: cairo.ffi
 LIBRARY: cairo
 
 FUNCTION: int cairo_version ( ) ;
-FUNCTION: char* cairo_version_string ( ) ;
+FUNCTION: c-string cairo_version_string ( ) ;
 
 TYPEDEF: int cairo_bool_t
 
@@ -79,11 +79,11 @@ CONSTANT: CAIRO_CONTENT_COLOR_ALPHA HEX: 3000
 
 TYPEDEF: void* cairo_write_func_t
 : cairo-write-func ( quot -- callback )
-    [ cairo_status_t { pointer: void pointer: uchar int } "cdecl" ] dip alien-callback ; inline
+    [ cairo_status_t { pointer: void c-string int } "cdecl" ] dip alien-callback ; inline
                           
 TYPEDEF: void* cairo_read_func_t
 : cairo-read-func ( quot -- callback )
-    [ cairo_status_t { pointer: void pointer: uchar int } "cdecl" ] dip alien-callback ; inline
+    [ cairo_status_t { pointer: void c-string int } "cdecl" ] dip alien-callback ; inline
 
 ! Functions for manipulating state objects
 FUNCTION: cairo_t*
@@ -463,7 +463,7 @@ cairo_font_options_get_hint_metrics ( cairo_font_options_t* options ) ;
 !  font object inside the the cairo_t.
 
 FUNCTION: void
-cairo_select_font_face ( cairo_t* cr, char* family, cairo_font_slant_t slant, cairo_font_weight_t weight ) ;
+cairo_select_font_face ( cairo_t* cr, c-string family, cairo_font_slant_t slant, cairo_font_weight_t weight ) ;
 
 FUNCTION: void
 cairo_set_font_size ( cairo_t* cr, double size ) ;
@@ -493,19 +493,19 @@ FUNCTION: cairo_scaled_font_t*
 cairo_get_scaled_font ( cairo_t* cr ) ;
 
 FUNCTION: void
-cairo_show_text ( cairo_t* cr, char* utf8 ) ;
+cairo_show_text ( cairo_t* cr, c-string utf8 ) ;
 
 FUNCTION: void
 cairo_show_glyphs ( cairo_t* cr, cairo_glyph_t* glyphs, int num_glyphs ) ;
 
 FUNCTION: void
-cairo_text_path  ( cairo_t* cr, char* utf8 ) ;
+cairo_text_path  ( cairo_t* cr, c-string utf8 ) ;
 
 FUNCTION: void
 cairo_glyph_path ( cairo_t* cr, cairo_glyph_t* glyphs, int num_glyphs ) ;
 
 FUNCTION: void
-cairo_text_extents ( cairo_t* cr, char* utf8, cairo_text_extents_t* extents ) ;
+cairo_text_extents ( cairo_t* cr, c-string utf8, cairo_text_extents_t* extents ) ;
 
 FUNCTION: void
 cairo_glyph_extents ( cairo_t* cr, cairo_glyph_t* glyphs, int num_glyphs, cairo_text_extents_t* extents ) ;
@@ -573,7 +573,7 @@ FUNCTION: void
 cairo_scaled_font_extents ( cairo_scaled_font_t* scaled_font, cairo_font_extents_t* extents ) ;
 
 FUNCTION: void
-cairo_scaled_font_text_extents ( cairo_scaled_font_t* scaled_font, char* utf8, cairo_text_extents_t* extents ) ;
+cairo_scaled_font_text_extents ( cairo_scaled_font_t* scaled_font, c-string utf8, cairo_text_extents_t* extents ) ;
 
 FUNCTION: void
 cairo_scaled_font_glyph_extents ( cairo_scaled_font_t* scaled_font, cairo_glyph_t* glyphs, int num_glyphs, cairo_text_extents_t* extents ) ;
@@ -682,7 +682,7 @@ cairo_path_destroy ( cairo_path_t* path ) ;
 FUNCTION: cairo_status_t
 cairo_status ( cairo_t* cr ) ;
 
-FUNCTION: char* 
+FUNCTION: c-string 
 cairo_status_to_string ( cairo_status_t status ) ;
 
 ! Surface manipulation
@@ -731,7 +731,7 @@ FUNCTION: cairo_content_t
 cairo_surface_get_content ( cairo_surface_t* surface ) ;
 
 FUNCTION: cairo_status_t
-cairo_surface_write_to_png ( cairo_surface_t* surface, char* filename ) ;
+cairo_surface_write_to_png ( cairo_surface_t* surface, c-string filename ) ;
 
 FUNCTION: cairo_status_t
 cairo_surface_write_to_png_stream ( cairo_surface_t* surface, cairo_write_func_t write_func, void* closure ) ;
@@ -786,9 +786,9 @@ FUNCTION: int
 cairo_format_stride_for_width ( cairo_format_t format, int width ) ;
 
 FUNCTION: cairo_surface_t*
-cairo_image_surface_create_for_data ( uchar* data, cairo_format_t format, int width, int height, int stride ) ;
+cairo_image_surface_create_for_data ( c-string data, cairo_format_t format, int width, int height, int stride ) ;
 
-FUNCTION: uchar*
+FUNCTION: c-string
 cairo_image_surface_get_data ( cairo_surface_t* surface ) ;
 
 FUNCTION: cairo_format_t
@@ -804,7 +804,7 @@ FUNCTION: int
 cairo_image_surface_get_stride ( cairo_surface_t* surface ) ;
 
 FUNCTION: cairo_surface_t*
-cairo_image_surface_create_from_png ( char* filename ) ;
+cairo_image_surface_create_from_png ( c-string filename ) ;
 
 FUNCTION: cairo_surface_t*
 cairo_image_surface_create_from_png_stream ( cairo_read_func_t read_func, void* closure ) ;
diff --git a/basis/classes/struct/struct-docs.factor b/basis/classes/struct/struct-docs.factor
index 1a5294992e..7dbfda1f4f 100644
--- a/basis/classes/struct/struct-docs.factor
+++ b/basis/classes/struct/struct-docs.factor
@@ -159,7 +159,7 @@ $nl
 "A C function which returns a struct by value:"
 { $code
     "USING: alien.syntax ;"
-    "FUNCTION: Point give_me_a_point ( char* description ) ;"
+    "FUNCTION: Point give_me_a_point ( c-string description ) ;"
 }
 "A C function which takes a struct parameter by reference:"
 { $code
diff --git a/basis/classes/struct/struct-tests.factor b/basis/classes/struct/struct-tests.factor
index 82530614bf..c94ef48f4c 100644
--- a/basis/classes/struct/struct-tests.factor
+++ b/basis/classes/struct/struct-tests.factor
@@ -139,7 +139,7 @@ UNION-STRUCT: struct-test-float-and-bits
 [ 123 ] [ [ struct-test-foo malloc-struct &free y>> ] with-destructors ] unit-test
 
 STRUCT: struct-test-string-ptr
-    { x char* } ;
+    { x c-string } ;
 
 [ "hello world" ] [
     [
diff --git a/basis/cocoa/messages/messages.factor b/basis/cocoa/messages/messages.factor
index 76b77721ff..2569c391d1 100644
--- a/basis/cocoa/messages/messages.factor
+++ b/basis/cocoa/messages/messages.factor
@@ -110,7 +110,7 @@ H{
     { "d" c:double }
     { "B" c:bool }
     { "v" c:void }
-    { "*" c:char* }
+    { "*" c:c-string }
     { "?" unknown_type }
     { "@" id }
     { "#" Class }
diff --git a/basis/cocoa/runtime/runtime.factor b/basis/cocoa/runtime/runtime.factor
index f02f1f6182..9e49835242 100644
--- a/basis/cocoa/runtime/runtime.factor
+++ b/basis/cocoa/runtime/runtime.factor
@@ -7,11 +7,11 @@ TYPEDEF: void* SEL
 
 TYPEDEF: void* id
 
-FUNCTION: char* sel_getName ( SEL aSelector ) ;
+FUNCTION: c-string sel_getName ( SEL aSelector ) ;
 
 FUNCTION: char sel_isMapped ( SEL aSelector ) ;
 
-FUNCTION: SEL sel_registerName ( char* str ) ;
+FUNCTION: SEL sel_registerName ( c-string str ) ;
 
 TYPEDEF: void* Class
 TYPEDEF: void* Method
@@ -33,13 +33,13 @@ CONSTANT: CLS_METHOD_ARRAY HEX: 100
 
 FUNCTION: int objc_getClassList ( void* buffer, int bufferLen ) ;
 
-FUNCTION: Class objc_getClass ( char* class ) ;
+FUNCTION: Class objc_getClass ( c-string class ) ;
 
-FUNCTION: Class objc_getMetaClass ( char* class ) ;
+FUNCTION: Class objc_getMetaClass ( c-string class ) ;
 
-FUNCTION: Protocol objc_getProtocol ( char* class ) ;
+FUNCTION: Protocol objc_getProtocol ( c-string class ) ;
 
-FUNCTION: Class objc_allocateClassPair ( Class superclass, char* name, size_t extraBytes ) ;
+FUNCTION: Class objc_allocateClassPair ( Class superclass, c-string name, size_t extraBytes ) ;
 FUNCTION: void objc_registerClassPair ( Class cls ) ;
 
 FUNCTION: id class_createInstance ( Class class, uint additionalByteCount ) ;
@@ -54,7 +54,7 @@ FUNCTION: Method* class_copyMethodList ( Class class, uint* outCount ) ;
 
 FUNCTION: Class class_getSuperclass ( Class cls ) ;
 
-FUNCTION: char* class_getName ( Class cls ) ;
+FUNCTION: c-string class_getName ( Class cls ) ;
 
 FUNCTION: char class_addMethod ( Class class, SEL name, void* imp, void* types ) ;
 
@@ -64,7 +64,7 @@ FUNCTION: uint method_getNumberOfArguments ( Method method ) ;
 
 FUNCTION: uint method_getSizeOfArguments ( Method method ) ;
 
-FUNCTION: uint method_getArgumentInfo ( Method method, int argIndex, char** type, int* offset ) ;
+FUNCTION: uint method_getArgumentInfo ( Method method, int argIndex, c-string* type, int* offset ) ;
 
 FUNCTION: void* method_copyReturnType ( Method method ) ;
 
diff --git a/basis/compiler/tests/alien.factor b/basis/compiler/tests/alien.factor
index aba73d1a22..acb5555bc3 100755
--- a/basis/compiler/tests/alien.factor
+++ b/basis/compiler/tests/alien.factor
@@ -67,7 +67,7 @@ FUNCTION: FOO ffi_test_14 int x int y ;
 
 [ 11 6 ] [ 11 6 ffi_test_14 [ x>> ] [ y>> ] bi ] unit-test
 
-FUNCTION: char* ffi_test_15 char* x char* y ;
+FUNCTION: c-string ffi_test_15 c-string x c-string y ;
 
 [ "foo" ] [ "xy" "zt" ffi_test_15 ] unit-test
 [ "bar" ] [ "xy" "xy" ffi_test_15 ] unit-test
@@ -576,7 +576,7 @@ FUNCTION: complex-float ffi_test_47 ( complex-float x, complex-double y ) ;
 
 ! Reported by jedahu
 STRUCT: bool-field-test
-    { name char* }
+    { name c-string }
     { on bool }
     { parents short } ;
 
diff --git a/basis/core-foundation/data/data.factor b/basis/core-foundation/data/data.factor
index c4c09d0cc5..65d6d728c1 100644
--- a/basis/core-foundation/data/data.factor
+++ b/basis/core-foundation/data/data.factor
@@ -12,7 +12,7 @@ CONSTANT: kCFPropertyListImmutable 0
 CONSTANT: kCFPropertyListMutableContainers 1
 CONSTANT: kCFPropertyListMutableContainersAndLeaves 2
 
-FUNCTION: CFDataRef CFDataCreate ( CFAllocatorRef allocator, uchar* bytes, CFIndex length ) ;
+FUNCTION: CFDataRef CFDataCreate ( CFAllocatorRef allocator, c-string bytes, CFIndex length ) ;
 
 FUNCTION: CFTypeID CFGetTypeID ( CFTypeRef cf ) ;
 
diff --git a/basis/core-foundation/strings/strings.factor b/basis/core-foundation/strings/strings.factor
index cbabb083aa..9a91335ae2 100644
--- a/basis/core-foundation/strings/strings.factor
+++ b/basis/core-foundation/strings/strings.factor
@@ -37,7 +37,7 @@ FUNCTION: void CFStringGetCharacters ( void* theString, CFIndex start, CFIndex l
 
 FUNCTION: Boolean CFStringGetCString (
     CFStringRef theString,
-    char* buffer,
+    c-string buffer,
     CFIndex bufferSize,
     CFStringEncoding encoding
 ) ;
@@ -55,7 +55,7 @@ FUNCTION: CFIndex CFStringGetBytes (
 
 FUNCTION: CFStringRef CFStringCreateWithCString (
     CFAllocatorRef alloc,
-    char* cStr,
+    c-string cStr,
     CFStringEncoding encoding
 ) ;
 
diff --git a/basis/db/postgresql/ffi/ffi.factor b/basis/db/postgresql/ffi/ffi.factor
index 69ac2c5e5e..812507a20f 100644
--- a/basis/db/postgresql/ffi/ffi.factor
+++ b/basis/db/postgresql/ffi/ffi.factor
@@ -77,15 +77,15 @@ LIBRARY: postgresql
 
 ! make a new client connection to the backend
 ! Asynchronous (non-blocking)
-FUNCTION: PGconn* PQconnectStart ( char* conninfo ) ;
+FUNCTION: PGconn* PQconnectStart ( c-string conninfo ) ;
 FUNCTION: PostgresPollingStatusType PQconnectPoll ( PGconn* conn ) ;
 
 ! Synchronous (blocking)
-FUNCTION: PGconn* PQconnectdb ( char* conninfo ) ;
-FUNCTION: PGconn* PQsetdbLogin ( char* pghost, char* pgport,
-             char* pgoptions, char* pgtty,
-             char* dbName,
-             char* login, char* pwd ) ;
+FUNCTION: PGconn* PQconnectdb ( c-string conninfo ) ;
+FUNCTION: PGconn* PQsetdbLogin ( c-string pghost, c-string pgport,
+             c-string pgoptions, c-string pgtty,
+             c-string dbName,
+             c-string login, c-string pwd ) ;
 
 : PQsetdb ( M_PGHOST M_PGPORT M_PGOPT M_PGTTY M_DBNAME -- PGconn* )
     f f PQsetdbLogin ;
@@ -116,24 +116,24 @@ FUNCTION: void PQfreeCancel ( PGcancel* cancel ) ;
 FUNCTION: int    PQrequestCancel ( PGconn* conn ) ;
 
 ! Accessor functions for PGconn objects
-FUNCTION: char* PQdb ( PGconn* conn ) ;
-FUNCTION: char* PQuser ( PGconn* conn ) ;
-FUNCTION: char* PQpass ( PGconn* conn ) ;
-FUNCTION: char* PQhost ( PGconn* conn ) ;
-FUNCTION: char* PQport ( PGconn* conn ) ;
-FUNCTION: char* PQtty ( PGconn* conn ) ;
-FUNCTION: char* PQoptions ( PGconn* conn ) ;
+FUNCTION: c-string PQdb ( PGconn* conn ) ;
+FUNCTION: c-string PQuser ( PGconn* conn ) ;
+FUNCTION: c-string PQpass ( PGconn* conn ) ;
+FUNCTION: c-string PQhost ( PGconn* conn ) ;
+FUNCTION: c-string PQport ( PGconn* conn ) ;
+FUNCTION: c-string PQtty ( PGconn* conn ) ;
+FUNCTION: c-string PQoptions ( PGconn* conn ) ;
 FUNCTION: ConnStatusType PQstatus ( PGconn* conn ) ;
 FUNCTION: PGTransactionStatusType PQtransactionStatus ( PGconn* conn ) ;
-FUNCTION: char* PQparameterStatus ( PGconn* conn,
-                  char* paramName ) ;
+FUNCTION: c-string PQparameterStatus ( PGconn* conn,
+                  c-string paramName ) ;
 FUNCTION: int PQprotocolVersion ( PGconn* conn ) ;
 ! FUNCTION: int PQServerVersion ( PGconn* conn ) ;
-FUNCTION: char* PQerrorMessage ( PGconn* conn ) ;
+FUNCTION: c-string PQerrorMessage ( PGconn* conn ) ;
 FUNCTION: int PQsocket ( PGconn* conn ) ;
 FUNCTION: int PQbackendPID ( PGconn* conn ) ;
 FUNCTION: int PQclientEncoding ( PGconn* conn ) ;
-FUNCTION: int PQsetClientEncoding ( PGconn* conn, char* encoding ) ;
+FUNCTION: int PQsetClientEncoding ( PGconn* conn, c-string encoding ) ;
 
 ! May not be compiled into libpq
 ! Get the SSL structure associated with a connection
@@ -153,7 +153,7 @@ FUNCTION: void PQuntrace ( PGconn* conn ) ;
 ! BROKEN
 ! Function types for notice-handling callbacks
 ! typedef void (*PQnoticeReceiver) (void *arg, PGresult *res);
-! typedef void (*PQnoticeProcessor) (void *arg, char* message);
+! typedef void (*PQnoticeProcessor) (void *arg, c-string message);
 ! ALIAS: void* PQnoticeReceiver
 ! ALIAS: void* PQnoticeProcessor
 
@@ -169,43 +169,43 @@ FUNCTION: void PQuntrace ( PGconn* conn ) ;
 ! === in fe-exec.c ===
 
 ! Simple synchronous query
-FUNCTION: PGresult* PQexec ( PGconn* conn, char* query ) ;
+FUNCTION: PGresult* PQexec ( PGconn* conn, c-string query ) ;
 FUNCTION: PGresult* PQexecParams ( PGconn* conn,
-             char* command,
+             c-string command,
              int nParams,
              Oid* paramTypes,
-             char** paramValues,
+             c-string* paramValues,
              int* paramLengths,
              int* paramFormats,
              int resultFormat ) ;
-FUNCTION: PGresult* PQprepare ( PGconn* conn, char* stmtName,
-        char* query, int nParams,
+FUNCTION: PGresult* PQprepare ( PGconn* conn, c-string stmtName,
+        c-string query, int nParams,
         Oid* paramTypes ) ;
 FUNCTION: PGresult* PQexecPrepared ( PGconn* conn,
-             char* stmtName,
+             c-string stmtName,
              int nParams,
-             char** paramValues,
+             c-string* paramValues,
              int* paramLengths,
              int* paramFormats,
              int resultFormat ) ;
 
 ! Interface for multiple-result or asynchronous queries
-FUNCTION: int PQsendQuery ( PGconn* conn, char* query ) ;
+FUNCTION: int PQsendQuery ( PGconn* conn, c-string query ) ;
 FUNCTION: int PQsendQueryParams ( PGconn* conn,
-                  char* command,
+                  c-string command,
                   int nParams,
                   Oid* paramTypes,
-                  char** paramValues,
+                  c-string* paramValues,
                   int* paramLengths,
                   int* paramFormats,
                   int resultFormat ) ;
-FUNCTION: PGresult* PQsendPrepare ( PGconn* conn, char* stmtName,
-            char* query, int nParams,
+FUNCTION: PGresult* PQsendPrepare ( PGconn* conn, c-string stmtName,
+            c-string query, int nParams,
             Oid* paramTypes ) ;
 FUNCTION: int PQsendQueryPrepared ( PGconn* conn,
-                  char* stmtName,
+                  c-string stmtName,
                   int nParams,
-                  char** paramValues,
+                  c-string* paramValues,
                   int *paramLengths,
                   int *paramFormats,
                   int resultFormat ) ;
@@ -219,15 +219,15 @@ FUNCTION: int    PQconsumeInput ( PGconn* conn ) ;
 FUNCTION: PGnotify* PQnotifies ( PGconn* conn ) ;
 
 ! Routines for copy in/out
-FUNCTION: int    PQputCopyData ( PGconn* conn, char* buffer, int nbytes ) ;
-FUNCTION: int    PQputCopyEnd ( PGconn* conn, char* errormsg ) ;
-FUNCTION: int    PQgetCopyData ( PGconn* conn, char** buffer, int async ) ;
+FUNCTION: int    PQputCopyData ( PGconn* conn, c-string buffer, int nbytes ) ;
+FUNCTION: int    PQputCopyEnd ( PGconn* conn, c-string errormsg ) ;
+FUNCTION: int    PQgetCopyData ( PGconn* conn, c-string* buffer, int async ) ;
 
 ! Deprecated routines for copy in/out
-FUNCTION: int    PQgetline ( PGconn* conn, char* string, int length ) ;
-FUNCTION: int    PQputline ( PGconn* conn, char* string ) ;
-FUNCTION: int    PQgetlineAsync ( PGconn* conn, char* buffer, int bufsize ) ;
-FUNCTION: int    PQputnbytes ( PGconn* conn, char* buffer, int nbytes ) ;
+FUNCTION: int    PQgetline ( PGconn* conn, c-string string, int length ) ;
+FUNCTION: int    PQputline ( PGconn* conn, c-string string ) ;
+FUNCTION: int    PQgetlineAsync ( PGconn* conn, c-string buffer, int bufsize ) ;
+FUNCTION: int    PQputnbytes ( PGconn* conn, c-string buffer, int nbytes ) ;
 FUNCTION: int    PQendcopy ( PGconn* conn ) ;
 
 ! Set blocking/nonblocking connection to the backend
@@ -251,25 +251,25 @@ FUNCTION: PGresult* PQfn ( PGconn* conn,
 
 ! Accessor functions for PGresult objects
 FUNCTION: ExecStatusType PQresultStatus ( PGresult* res ) ;
-FUNCTION: char* PQresStatus ( ExecStatusType status ) ;
-FUNCTION: char* PQresultErrorMessage ( PGresult* res ) ;
-FUNCTION: char* PQresultErrorField ( PGresult* res, int fieldcode ) ;
+FUNCTION: c-string PQresStatus ( ExecStatusType status ) ;
+FUNCTION: c-string PQresultErrorMessage ( PGresult* res ) ;
+FUNCTION: c-string PQresultErrorField ( PGresult* res, int fieldcode ) ;
 FUNCTION: int   PQntuples ( PGresult* res ) ;
 FUNCTION: int   PQnfields ( PGresult* res ) ;
 FUNCTION: int   PQbinaryTuples ( PGresult* res ) ;
-FUNCTION: char* PQfname ( PGresult* res, int field_num ) ;
-FUNCTION: int   PQfnumber ( PGresult* res, char* field_name ) ;
+FUNCTION: c-string PQfname ( PGresult* res, int field_num ) ;
+FUNCTION: int   PQfnumber ( PGresult* res, c-string field_name ) ;
 FUNCTION: Oid   PQftable ( PGresult* res, int field_num ) ;
 FUNCTION: int   PQftablecol ( PGresult* res, int field_num ) ;
 FUNCTION: int   PQfformat ( PGresult* res, int field_num ) ;
 FUNCTION: Oid   PQftype ( PGresult* res, int field_num ) ;
 FUNCTION: int   PQfsize ( PGresult* res, int field_num ) ;
 FUNCTION: int   PQfmod ( PGresult* res, int field_num ) ;
-FUNCTION: char* PQcmdStatus ( PGresult* res ) ;
-FUNCTION: char* PQoidStatus ( PGresult* res ) ;
+FUNCTION: c-string PQcmdStatus ( PGresult* res ) ;
+FUNCTION: c-string PQoidStatus ( PGresult* res ) ;
 FUNCTION: Oid   PQoidValue ( PGresult* res ) ;
-FUNCTION: char* PQcmdTuples ( PGresult* res ) ;
-! FUNCTION: char* PQgetvalue ( PGresult* res, int tup_num, int field_num ) ;
+FUNCTION: c-string PQcmdTuples ( PGresult* res ) ;
+! FUNCTION: c-string PQgetvalue ( PGresult* res, int tup_num, int field_num ) ;
 FUNCTION: void* PQgetvalue ( PGresult* res, int tup_num, int field_num ) ;
 FUNCTION: int   PQgetlength ( PGresult* res, int tup_num, int field_num ) ;
 FUNCTION: int   PQgetisnull ( PGresult* res, int tup_num, int field_num ) ;
@@ -292,16 +292,16 @@ FUNCTION: PGresult* PQmakeEmptyPGresult ( PGconn* conn, ExecStatusType status )
 
 ! Quoting strings before inclusion in queries.
 FUNCTION: size_t PQescapeStringConn ( PGconn* conn,
-                                    char* to, char* from, size_t length,
+                                    c-string to, c-string from, size_t length,
                                     int* error ) ;
-FUNCTION: uchar* PQescapeByteaConn ( PGconn* conn,
-                                    char* from, size_t length,
+FUNCTION: c-string PQescapeByteaConn ( PGconn* conn,
+                                    c-string from, size_t length,
                                     size_t* to_length ) ;
-FUNCTION: void* PQunescapeBytea ( uchar* strtext, size_t* retbuflen ) ;
-! FUNCTION: uchar* PQunescapeBytea ( uchar* strtext, size_t* retbuflen ) ;
+FUNCTION: void* PQunescapeBytea ( c-string strtext, size_t* retbuflen ) ;
+! FUNCTION: c-string PQunescapeBytea ( c-string strtext, size_t* retbuflen ) ;
 ! These forms are deprecated!
-FUNCTION: size_t PQescapeString ( void* to, char* from, size_t length ) ;
-FUNCTION: uchar* PQescapeBytea ( uchar* bintext, size_t binlen,
+FUNCTION: size_t PQescapeString ( void* to, c-string from, size_t length ) ;
+FUNCTION: c-string PQescapeBytea ( c-string bintext, size_t binlen,
               size_t* bytealen ) ;
 
 ! === in fe-print.c ===
@@ -312,7 +312,7 @@ FUNCTION: void PQprint ( FILE* fout, PGresult* res, PQprintOpt* ps ) ;
 FUNCTION: void PQdisplayTuples ( PGresult* res,
                                 FILE* fp,               
                                 int fillAlign,
-                                char* fieldSep,
+                                c-string fieldSep,
                                 int printHeader,
                                 int quiet ) ;
 
@@ -326,23 +326,23 @@ FUNCTION: void PQprintTuples ( PGresult* res,
 ! Large-object access routines
 FUNCTION: int    lo_open ( PGconn* conn, Oid lobjId, int mode ) ;
 FUNCTION: int    lo_close ( PGconn* conn, int fd ) ;
-FUNCTION: int    lo_read ( PGconn* conn, int fd, char* buf, size_t len ) ;
-FUNCTION: int    lo_write ( PGconn* conn, int fd, char* buf, size_t len ) ;
+FUNCTION: int    lo_read ( PGconn* conn, int fd, c-string buf, size_t len ) ;
+FUNCTION: int    lo_write ( PGconn* conn, int fd, c-string buf, size_t len ) ;
 FUNCTION: int    lo_lseek ( PGconn* conn, int fd, int offset, int whence ) ;
 FUNCTION: Oid    lo_creat ( PGconn* conn, int mode ) ;
 ! FUNCTION: Oid    lo_creat ( PGconn* conn, Oid lobjId ) ;
 FUNCTION: int    lo_tell ( PGconn* conn, int fd ) ;
 FUNCTION: int    lo_unlink ( PGconn* conn, Oid lobjId ) ;
-FUNCTION: Oid    lo_import ( PGconn* conn, char* filename ) ;
-FUNCTION: int    lo_export ( PGconn* conn, Oid lobjId, char* filename ) ;
+FUNCTION: Oid    lo_import ( PGconn* conn, c-string filename ) ;
+FUNCTION: int    lo_export ( PGconn* conn, Oid lobjId, c-string filename ) ;
 
 ! === in fe-misc.c ===
 
 ! Determine length of multibyte encoded char at *s
-FUNCTION: int    PQmblen ( uchar* s, int encoding ) ;
+FUNCTION: int    PQmblen ( c-string s, int encoding ) ;
 
 ! Determine display length of multibyte encoded char at *s
-FUNCTION: int    PQdsplen ( uchar* s, int encoding ) ;
+FUNCTION: int    PQdsplen ( c-string s, int encoding ) ;
 
 ! Get encoding id from environment variable PGCLIENTENCODING
 FUNCTION: int    PQenv2encoding ( ) ;
diff --git a/basis/db/sqlite/ffi/ffi.factor b/basis/db/sqlite/ffi/ffi.factor
index 53562fd87e..f93b961799 100644
--- a/basis/db/sqlite/ffi/ffi.factor
+++ b/basis/db/sqlite/ffi/ffi.factor
@@ -105,11 +105,11 @@ TYPEDEF: longlong sqlite3_int64
 TYPEDEF: ulonglong sqlite3_uint64
 
 LIBRARY: sqlite
-FUNCTION: int sqlite3_open ( char* filename, void* ppDb ) ;
+FUNCTION: int sqlite3_open ( c-string filename, void* ppDb ) ;
 FUNCTION: int sqlite3_close ( sqlite3* pDb ) ;
-FUNCTION: char* sqlite3_errmsg ( sqlite3* pDb ) ;
-FUNCTION: int sqlite3_prepare ( sqlite3* pDb, char* zSql, int nBytes, void* ppStmt, void* pzTail ) ;
-FUNCTION: int sqlite3_prepare_v2 ( sqlite3* pDb, char* zSql, int nBytes, void* ppStmt, void* pzTail ) ;
+FUNCTION: c-string sqlite3_errmsg ( sqlite3* pDb ) ;
+FUNCTION: int sqlite3_prepare ( sqlite3* pDb, c-string zSql, int nBytes, void* ppStmt, void* pzTail ) ;
+FUNCTION: int sqlite3_prepare_v2 ( sqlite3* pDb, c-string zSql, int nBytes, void* ppStmt, void* pzTail ) ;
 FUNCTION: int sqlite3_finalize ( sqlite3_stmt* pStmt ) ;
 FUNCTION: int sqlite3_reset ( sqlite3_stmt* pStmt ) ;
 FUNCTION: int sqlite3_step ( sqlite3_stmt* pStmt ) ;
@@ -123,13 +123,13 @@ FUNCTION: int sqlite3_bind_int64 ( sqlite3_stmt* pStmt, int index, sqlite3_int64
     int "sqlite" "sqlite3_bind_int64"
     { pointer: sqlite3_stmt int sqlite3_uint64 } alien-invoke ;
 FUNCTION: int sqlite3_bind_null ( sqlite3_stmt* pStmt, int n ) ;
-FUNCTION: int sqlite3_bind_text ( sqlite3_stmt* pStmt, int index, char* text, int len, int destructor ) ;
-FUNCTION: int sqlite3_bind_parameter_index ( sqlite3_stmt* pStmt, char* name ) ;
+FUNCTION: int sqlite3_bind_text ( sqlite3_stmt* pStmt, int index, c-string text, int len, int destructor ) ;
+FUNCTION: int sqlite3_bind_parameter_index ( sqlite3_stmt* pStmt, c-string name ) ;
 FUNCTION: int sqlite3_clear_bindings ( sqlite3_stmt* pStmt ) ;
 FUNCTION: int sqlite3_column_count ( sqlite3_stmt* pStmt ) ;
 FUNCTION: void* sqlite3_column_blob ( sqlite3_stmt* pStmt, int col ) ;
 FUNCTION: int sqlite3_column_bytes ( sqlite3_stmt* pStmt, int col ) ;
-FUNCTION: char* sqlite3_column_decltype ( sqlite3_stmt* pStmt, int col ) ;
+FUNCTION: c-string 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 ) ;
 ! Bind the same function as above, but for unsigned 64bit integers
@@ -137,6 +137,6 @@ FUNCTION: sqlite3_int64 sqlite3_column_int64 ( sqlite3_stmt* pStmt, int col ) ;
     sqlite3_uint64 "sqlite" "sqlite3_column_int64"
     { pointer: sqlite3_stmt int } alien-invoke ;
 FUNCTION: double sqlite3_column_double ( 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: c-string sqlite3_column_name ( sqlite3_stmt* pStmt, int col ) ;
+FUNCTION: c-string sqlite3_column_text ( sqlite3_stmt* pStmt, int col ) ;
 FUNCTION: int sqlite3_column_type ( sqlite3_stmt* pStmt, int col ) ;
diff --git a/basis/iokit/hid/hid.factor b/basis/iokit/hid/hid.factor
index ca339a78ef..bd3fc1e968 100644
--- a/basis/iokit/hid/hid.factor
+++ b/basis/iokit/hid/hid.factor
@@ -132,7 +132,7 @@ TYPEDEF: UInt32 IOHIDValueScaleType
 TYPEDEF: UInt32 IOHIDTransactionDirectionType
 
 CALLBACK: void IOHIDCallback ( void* context, IOReturn result, void* sender ) ;
-CALLBACK: void IOHIDReportCallback ( void* context, IOReturn result, void* sender, IOHIDReportType type, UInt32 reportID, uchar* report, CFIndex reportLength ) ;
+CALLBACK: void IOHIDReportCallback ( void* context, IOReturn result, void* sender, IOHIDReportType type, UInt32 reportID, c-string report, CFIndex reportLength ) ;
 CALLBACK: void IOHIDValueCallback ( void* context, IOReturn result, void* sender, IOHIDValueRef value ) ;
 CALLBACK: void IOHIDValueMultipleCallback ( void* context, IOReturn result, void* sender, CFDictionaryRef multiple ) ;
 CALLBACK: void IOHIDDeviceCallback ( void* context, IOReturn result, void* sender, IOHIDDeviceRef device ) ;
@@ -151,7 +151,7 @@ FUNCTION: void IOHIDDeviceScheduleWithRunLoop ( IOHIDDeviceRef device, CFRunLoop
 FUNCTION: void IOHIDDeviceUnscheduleFromRunLoop ( IOHIDDeviceRef device, CFRunLoopRef runLoop, CFStringRef runLoopMode ) ;
 FUNCTION: void IOHIDDeviceRegisterRemovalCallback ( IOHIDDeviceRef device, IOHIDCallback callback, void* context ) ;
 FUNCTION: void IOHIDDeviceRegisterInputValueCallback ( IOHIDDeviceRef device, IOHIDValueCallback callback, void* context ) ;
-FUNCTION: void IOHIDDeviceRegisterInputReportCallback ( IOHIDDeviceRef device, uchar* report, CFIndex reportLength, IOHIDReportCallback callback, void* context ) ;
+FUNCTION: void IOHIDDeviceRegisterInputReportCallback ( IOHIDDeviceRef device, c-string report, CFIndex reportLength, IOHIDReportCallback callback, void* context ) ;
 FUNCTION: void IOHIDDeviceSetInputValueMatching ( IOHIDDeviceRef device, CFDictionaryRef matching ) ;
 FUNCTION: void IOHIDDeviceSetInputValueMatchingMultiple ( IOHIDDeviceRef device, CFArrayRef multiple ) ;
 FUNCTION: IOReturn IOHIDDeviceSetValue ( IOHIDDeviceRef device, IOHIDElementRef element, IOHIDValueRef value ) ;
@@ -162,10 +162,10 @@ FUNCTION: IOReturn IOHIDDeviceGetValue ( IOHIDDeviceRef device, IOHIDElementRef
 FUNCTION: IOReturn IOHIDDeviceCopyValueMultiple ( IOHIDDeviceRef device, CFArrayRef elements, CFDictionaryRef* pMultiple ) ;
 FUNCTION: IOReturn IOHIDDeviceGetValueWithCallback ( IOHIDDeviceRef device, IOHIDElementRef element, IOHIDValueRef* pValue, CFTimeInterval timeout, IOHIDValueCallback callback, void* context ) ;
 FUNCTION: IOReturn IOHIDDeviceCopyValueMultipleWithCallback ( IOHIDDeviceRef device, CFArrayRef elements, CFDictionaryRef* pMultiple, CFTimeInterval timeout, IOHIDValueMultipleCallback callback, void* context ) ;
-FUNCTION: IOReturn IOHIDDeviceSetReport ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, uchar* report, CFIndex reportLength ) ;
-FUNCTION: IOReturn IOHIDDeviceSetReportWithCallback ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, uchar* report, CFIndex reportLength, CFTimeInterval timeout, IOHIDReportCallback callback, void* context ) ;
-FUNCTION: IOReturn IOHIDDeviceGetReport ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, uchar* report, CFIndex* pReportLength ) ;
-FUNCTION: IOReturn IOHIDDeviceGetReportWithCallback ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, uchar* report, CFIndex* pReportLength, CFTimeInterval timeout, IOHIDReportCallback callback, void* context ) ;
+FUNCTION: IOReturn IOHIDDeviceSetReport ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, c-string report, CFIndex reportLength ) ;
+FUNCTION: IOReturn IOHIDDeviceSetReportWithCallback ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, c-string report, CFIndex reportLength, CFTimeInterval timeout, IOHIDReportCallback callback, void* context ) ;
+FUNCTION: IOReturn IOHIDDeviceGetReport ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, c-string report, CFIndex* pReportLength ) ;
+FUNCTION: IOReturn IOHIDDeviceGetReportWithCallback ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, c-string report, CFIndex* pReportLength, CFTimeInterval timeout, IOHIDReportCallback callback, void* context ) ;
 
 ! IOHIDManager
 
@@ -226,12 +226,12 @@ FUNCTION: Boolean IOHIDElementSetProperty ( IOHIDElementRef element, CFStringRef
 
 FUNCTION: CFTypeID IOHIDValueGetTypeID ( ) ;
 FUNCTION: IOHIDValueRef IOHIDValueCreateWithIntegerValue ( CFAllocatorRef allocator, IOHIDElementRef element, ulonglong timeStamp, CFIndex value ) ;
-FUNCTION: IOHIDValueRef IOHIDValueCreateWithBytes ( CFAllocatorRef allocator, IOHIDElementRef element, ulonglong timeStamp, uchar* bytes, CFIndex length ) ;
-FUNCTION: IOHIDValueRef IOHIDValueCreateWithBytesNoCopy ( CFAllocatorRef allocator, IOHIDElementRef element, ulonglong timeStamp, uchar* bytes, CFIndex length ) ;
+FUNCTION: IOHIDValueRef IOHIDValueCreateWithBytes ( CFAllocatorRef allocator, IOHIDElementRef element, ulonglong timeStamp, c-string bytes, CFIndex length ) ;
+FUNCTION: IOHIDValueRef IOHIDValueCreateWithBytesNoCopy ( CFAllocatorRef allocator, IOHIDElementRef element, ulonglong timeStamp, c-string bytes, CFIndex length ) ;
 FUNCTION: IOHIDElementRef IOHIDValueGetElement ( IOHIDValueRef value ) ;
 FUNCTION: ulonglong IOHIDValueGetTimeStamp ( IOHIDValueRef value ) ;
 FUNCTION: CFIndex IOHIDValueGetLength ( IOHIDValueRef value ) ;
-FUNCTION: uchar* IOHIDValueGetBytePtr ( IOHIDValueRef value ) ;
+FUNCTION: c-string IOHIDValueGetBytePtr ( IOHIDValueRef value ) ;
 FUNCTION: CFIndex IOHIDValueGetIntegerValue ( IOHIDValueRef value ) ;
 FUNCTION: double IOHIDValueGetScaledValue ( IOHIDValueRef value, IOHIDValueScaleType type ) ;
 
diff --git a/basis/iokit/iokit.factor b/basis/iokit/iokit.factor
index 2b31e5c8a8..577c9e1273 100644
--- a/basis/iokit/iokit.factor
+++ b/basis/iokit/iokit.factor
@@ -104,9 +104,9 @@ CONSTANT: KERN_SUCCESS 0
 
 FUNCTION: IOReturn IOMasterPort ( mach_port_t bootstrap, mach_port_t* master ) ;
 
-FUNCTION: CFDictionaryRef IOServiceMatching ( char* name ) ;
-FUNCTION: CFDictionaryRef IOServiceNameMatching ( char* name ) ;
-FUNCTION: CFDictionaryRef IOBSDNameMatching ( char* name ) ;
+FUNCTION: CFDictionaryRef IOServiceMatching ( c-string name ) ;
+FUNCTION: CFDictionaryRef IOServiceNameMatching ( c-string name ) ;
+FUNCTION: CFDictionaryRef IOBSDNameMatching ( c-string name ) ;
 
 FUNCTION: IOReturn IOObjectRetain ( io_object_t o ) ;
 FUNCTION: IOReturn IOObjectRelease ( io_object_t o ) ;
@@ -121,7 +121,7 @@ FUNCTION: IOReturn IORegistryEntryGetPath ( io_registry_entry_t entry, io_name_t
 
 FUNCTION: IOReturn IORegistryEntryCreateCFProperties ( io_registry_entry_t entry, CFMutableDictionaryRef properties, CFAllocatorRef allocator, IOOptionBits options ) ;
 
-FUNCTION: char* mach_error_string ( IOReturn error ) ;
+FUNCTION: c-string mach_error_string ( IOReturn error ) ;
 
 TUPLE: mach-error error-code error-string ;
 : <mach-error> ( code -- error )
diff --git a/basis/libc/libc.factor b/basis/libc/libc.factor
index e935d49748..5f6a808b2e 100644
--- a/basis/libc/libc.factor
+++ b/basis/libc/libc.factor
@@ -96,6 +96,6 @@ PRIVATE>
     memcmp 0 = ;
 
 : strlen ( alien -- len )
-    size_t "libc" "strlen" { char* } alien-invoke ;
+    size_t "libc" "strlen" { c-string } alien-invoke ;
 
 DESTRUCTOR: free
diff --git a/basis/opengl/gl/gl.factor b/basis/opengl/gl/gl.factor
index 27d24718c2..7652720f1a 100644
--- a/basis/opengl/gl/gl.factor
+++ b/basis/opengl/gl/gl.factor
@@ -668,7 +668,7 @@ FUNCTION: void glPopClientAttrib ( ) ;
 
 FUNCTION: GLint glRenderMode ( GLenum mode ) ;
 FUNCTION: GLenum glGetError ( ) ;
-FUNCTION: char* glGetString ( GLenum name ) ;
+FUNCTION: c-string glGetString ( GLenum name ) ;
 FUNCTION: void glFinish ( ) ;
 FUNCTION: void glFlush ( ) ;
 FUNCTION: void glHint ( GLenum target, GLenum mode ) ;
diff --git a/basis/opengl/gl/windows/windows.factor b/basis/opengl/gl/windows/windows.factor
index 5821e3f212..8bceb865e2 100644
--- a/basis/opengl/gl/windows/windows.factor
+++ b/basis/opengl/gl/windows/windows.factor
@@ -4,7 +4,7 @@ IN: opengl.gl.windows
 LIBRARY: gl
 
 FUNCTION: HGLRC wglGetCurrentContext ( ) ;
-FUNCTION: void* wglGetProcAddress ( char* name ) ;
+FUNCTION: void* wglGetProcAddress ( c-string name ) ;
 
 : gl-function-context ( -- context ) wglGetCurrentContext ; inline
 : gl-function-address ( name -- address ) wglGetProcAddress ; inline
diff --git a/basis/openssl/libcrypto/libcrypto.factor b/basis/openssl/libcrypto/libcrypto.factor
index fd5c757bc4..f9983d7813 100644
--- a/basis/openssl/libcrypto/libcrypto.factor
+++ b/basis/openssl/libcrypto/libcrypto.factor
@@ -65,9 +65,9 @@ LIBRARY: libcrypto
 ! bio.h
 ! ===============================================
 
-FUNCTION: bio* BIO_new_file ( char* filename, char* mode ) ;
+FUNCTION: bio* BIO_new_file ( c-string filename, c-string mode ) ;
 
-FUNCTION: int BIO_printf ( bio* bio, char* format ) ;
+FUNCTION: int BIO_printf ( bio* bio, c-string format ) ;
 
 FUNCTION: long BIO_ctrl ( void* bio, int cmd, long larg, void* parg ) ;
 
@@ -83,17 +83,17 @@ FUNCTION: void* BIO_push ( void* bio, void* append ) ;
 
 FUNCTION: int BIO_read ( void* b, void* buf, int len ) ;
 
-FUNCTION: int BIO_gets ( void* b, char* buf, int size ) ;
+FUNCTION: int BIO_gets ( void* b, c-string buf, int size ) ;
 
 FUNCTION: int BIO_write ( void* b, void* buf, int len ) ;
 
-FUNCTION: int BIO_puts ( void* bp, char* buf ) ;
+FUNCTION: int BIO_puts ( void* bp, c-string buf ) ;
 
 FUNCTION: ulong ERR_get_error (  ) ;
 
 FUNCTION: void ERR_clear_error ( ) ;
 
-FUNCTION: char* ERR_error_string ( ulong e, void* buf ) ;
+FUNCTION: c-string ERR_error_string ( ulong e, void* buf ) ;
 
 FUNCTION: void* BIO_f_buffer (  ) ;
 
@@ -120,7 +120,7 @@ FUNCTION: void OpenSSL_add_all_digests (  ) ;
 ! Clean them up before exiting
 FUNCTION: void EVP_cleanup (  ) ;
 
-FUNCTION: EVP_MD* EVP_get_digestbyname ( char* name ) ;
+FUNCTION: EVP_MD* EVP_get_digestbyname ( c-string name ) ;
 
 FUNCTION: void EVP_MD_CTX_init ( EVP_MD* ctx ) ;
 
@@ -166,7 +166,7 @@ FUNCTION: int RSA_print_fp ( void* fp, void* x, int offset ) ;
 ! objects.h
 ! ===============================================
 
-FUNCTION: int OBJ_sn2nid ( char* s ) ;
+FUNCTION: int OBJ_sn2nid ( c-string s ) ;
 
 ! ===============================================
 ! bn.h
diff --git a/basis/openssl/libssl/libssl.factor b/basis/openssl/libssl/libssl.factor
index 1c6fbec011..bfd59cde25 100644
--- a/basis/openssl/libssl/libssl.factor
+++ b/basis/openssl/libssl/libssl.factor
@@ -109,7 +109,7 @@ FUNCTION: X509_NAME* X509_get_subject_name ( X509* a ) ;
 ! ssl.h
 ! ===============================================
 
-FUNCTION: char* SSL_get_version ( SSL* ssl ) ;
+FUNCTION: c-string SSL_get_version ( SSL* ssl ) ;
 
 ! Maps OpenSSL errors to strings
 FUNCTION: void SSL_load_error_strings (  ) ;
@@ -143,7 +143,7 @@ FUNCTION: SSL_CTX* SSL_CTX_new ( ssl-method method ) ;
 
 ! Load the certificates and private keys into the SSL_CTX
 FUNCTION: int SSL_CTX_use_certificate_chain_file ( SSL_CTX* ctx,
-                                                   char* file ) ; ! PEM type
+                                                   c-string file ) ; ! PEM type
 
 FUNCTION: SSL* SSL_new ( SSL_CTX* ctx ) ;
 
@@ -174,7 +174,7 @@ CONSTANT: SSL_RECEIVED_SHUTDOWN 2
 
 FUNCTION: int SSL_get_shutdown ( SSL* ssl ) ;
 
-FUNCTION: int SSL_CTX_set_session_id_context ( SSL_CTX* ctx, char* sid_ctx, uint len ) ;
+FUNCTION: int SSL_CTX_set_session_id_context ( SSL_CTX* ctx, c-string sid_ctx, uint len ) ;
 
 FUNCTION: SSL_SESSION* SSL_get1_session ( SSL* ssl ) ;
 
@@ -197,17 +197,17 @@ FUNCTION: void SSL_CTX_free ( SSL_CTX* ctx ) ;
 
 FUNCTION: void RAND_seed ( void* buf, int num ) ;
 
-FUNCTION: int SSL_set_cipher_list ( SSL* ssl, char* str ) ;
+FUNCTION: int SSL_set_cipher_list ( SSL* ssl, c-string str ) ;
 
-FUNCTION: int SSL_use_RSAPrivateKey_file ( SSL* ssl, char* str ) ;
+FUNCTION: int SSL_use_RSAPrivateKey_file ( SSL* ssl, c-string str ) ;
 
 FUNCTION: int SSL_CTX_use_RSAPrivateKey_file ( SSL_CTX* ctx, int type ) ;
 
 FUNCTION: int SSL_use_certificate_file ( SSL* ssl,
-                                         char* str, int type ) ;
+                                         c-string str, int type ) ;
 
-FUNCTION: int SSL_CTX_load_verify_locations ( SSL_CTX* ctx, char* CAfile,
-                                              char* CApath ) ;
+FUNCTION: int SSL_CTX_load_verify_locations ( SSL_CTX* ctx, c-string CAfile,
+                                              c-string CApath ) ;
 
 FUNCTION: int SSL_CTX_set_default_verify_paths ( SSL_CTX* ctx ) ;
 
@@ -220,7 +220,7 @@ FUNCTION: void SSL_CTX_set_verify ( SSL_CTX* ctx, int mode, void* callback ) ;
 
 FUNCTION: void SSL_CTX_set_client_CA_list ( SSL_CTX* ctx, SSL* list ) ;
 
-FUNCTION: SSL* SSL_load_client_CA_file ( char* file ) ;
+FUNCTION: SSL* SSL_load_client_CA_file ( c-string file ) ;
 
 ! Used to manipulate settings of the SSL_CTX and SSL objects.
 ! This function should never be called directly
@@ -231,7 +231,7 @@ FUNCTION: void SSL_CTX_set_default_passwd_cb ( SSL_CTX* ctx, void* cb ) ;
 FUNCTION: void SSL_CTX_set_default_passwd_cb_userdata ( SSL_CTX* ctx,
                                                         void* u ) ;
 
-FUNCTION: int SSL_CTX_use_PrivateKey_file ( SSL_CTX* ctx, char* file,
+FUNCTION: int SSL_CTX_use_PrivateKey_file ( SSL_CTX* ctx, c-string file,
                                             int type ) ;
 
 ! Sets the maximum depth for the allowed ctx certificate chain verification
diff --git a/basis/pango/fonts/fonts.factor b/basis/pango/fonts/fonts.factor
index 31a51e3f12..c2a7ef128d 100644
--- a/basis/pango/fonts/fonts.factor
+++ b/basis/pango/fonts/fonts.factor
@@ -45,16 +45,16 @@ pango_font_description_free ( PangoFontDescription* desc ) ;
 DESTRUCTOR: pango_font_description_free
 
 FUNCTION: PangoFontDescription*
-pango_font_description_from_string ( char* str ) ;
+pango_font_description_from_string ( c-string str ) ;
 
-FUNCTION: char*
+FUNCTION: c-string
 pango_font_description_to_string ( PangoFontDescription* desc ) ;
 
-FUNCTION: char*
+FUNCTION: c-string
 pango_font_description_to_filename ( PangoFontDescription* desc ) ;
 
 FUNCTION: void
-pango_font_description_set_family ( PangoFontDescription* desc, char* family ) ;
+pango_font_description_set_family ( PangoFontDescription* desc, c-string family ) ;
 
 FUNCTION: void
 pango_font_description_set_style ( PangoFontDescription* desc, PangoStyle style ) ;
@@ -68,7 +68,7 @@ pango_font_description_set_size ( PangoFontDescription* desc, gint size ) ;
 FUNCTION: void
 pango_font_map_list_families ( PangoFontMap* fontmap, PangoFontFamily*** families, int* n_families ) ;
 
-FUNCTION: char*
+FUNCTION: c-string
 pango_font_family_get_name ( PangoFontFamily* family ) ;
 
 FUNCTION: int
@@ -77,7 +77,7 @@ pango_font_family_is_monospace ( PangoFontFamily* family ) ;
 FUNCTION: void
 pango_font_family_list_faces ( PangoFontFamily* family, PangoFontFace*** faces, int* n_faces ) ;
 
-FUNCTION: char*
+FUNCTION: c-string
 pango_font_face_get_face_name ( PangoFontFace* face ) ;
 
 FUNCTION: void
diff --git a/basis/pango/layouts/layouts.factor b/basis/pango/layouts/layouts.factor
index 74b6d0b0c3..3f3b02c7c7 100644
--- a/basis/pango/layouts/layouts.factor
+++ b/basis/pango/layouts/layouts.factor
@@ -21,9 +21,9 @@ FUNCTION: PangoContext*
 pango_layout_get_context ( PangoLayout* layout ) ;
 
 FUNCTION: void
-pango_layout_set_text ( PangoLayout* layout, char* text, int length ) ;
+pango_layout_set_text ( PangoLayout* layout, c-string text, int length ) ;
 
-FUNCTION: char*
+FUNCTION: c-string
 pango_layout_get_text ( PangoLayout* layout ) ;
 
 FUNCTION: void
diff --git a/basis/system-info/linux/linux.factor b/basis/system-info/linux/linux.factor
index 0c21597a2f..1a565705fb 100644
--- a/basis/system-info/linux/linux.factor
+++ b/basis/system-info/linux/linux.factor
@@ -7,7 +7,7 @@ SPECIALIZED-ARRAY: char
 IN: system-info.linux
 
 : (uname) ( buf -- int )
-    int f "uname" { char* } alien-invoke ;
+    int f "uname" { c-string } alien-invoke ;
 
 : uname ( -- seq )
     65536 <char-array> [ (uname) io-error ] keep
diff --git a/basis/tools/disassembler/udis/udis.factor b/basis/tools/disassembler/udis/udis.factor
index ee77268e22..ae8827e093 100644
--- a/basis/tools/disassembler/udis/udis.factor
+++ b/basis/tools/disassembler/udis/udis.factor
@@ -32,8 +32,8 @@ STRUCT: ud
     { inp_fill uchar }
     { inp_file void* }
     { inp_ctr uchar }
-    { inp_buff uchar* }
-    { inp_buff_end uchar* }
+    { inp_buff c-string }
+    { inp_buff_end c-string }
     { inp_end uchar }
     { translator void* }
     { insn_offset ulonglong }
@@ -83,19 +83,19 @@ CONSTANT: UD_VENDOR_INTEL 1
 FUNCTION: void ud_init ( ud* u ) ;
 FUNCTION: void ud_set_mode ( ud* u, uchar mode ) ;
 FUNCTION: void ud_set_pc ( ud* u, ulonglong pc ) ;
-FUNCTION: void ud_set_input_buffer ( ud* u, uchar* offset, size_t size ) ;
+FUNCTION: void ud_set_input_buffer ( ud* u, c-string offset, size_t size ) ;
 FUNCTION: void ud_set_vendor ( ud* u, uint vendor ) ;
 FUNCTION: void ud_set_syntax ( ud* u, void* syntax ) ;
 FUNCTION: void ud_input_skip ( ud* u, size_t size ) ;
 FUNCTION: int ud_input_end ( ud* u ) ;
 FUNCTION: uint ud_decode ( ud* u ) ;
 FUNCTION: uint ud_disassemble ( ud* u ) ;
-FUNCTION: char* ud_insn_asm ( ud* u ) ;
+FUNCTION: c-string ud_insn_asm ( ud* u ) ;
 FUNCTION: void* ud_insn_ptr ( ud* u ) ;
 FUNCTION: ulonglong ud_insn_off ( ud* u ) ;
-FUNCTION: char* ud_insn_hex ( ud* u ) ;
+FUNCTION: c-string ud_insn_hex ( ud* u ) ;
 FUNCTION: uint ud_insn_len ( ud* u ) ;
-FUNCTION: char* ud_lookup_mnemonic ( int c ) ;
+FUNCTION: c-string ud_lookup_mnemonic ( int c ) ;
 
 : <ud> ( -- ud )
     ud malloc-struct &free
diff --git a/basis/unix/ffi/bsd/bsd.factor b/basis/unix/ffi/bsd/bsd.factor
index bda99422fc..ad323bf14a 100644
--- a/basis/unix/ffi/bsd/bsd.factor
+++ b/basis/unix/ffi/bsd/bsd.factor
@@ -48,15 +48,15 @@ STRUCT: sockaddr-un
     { path char[104] } ;
 
 STRUCT: passwd
-    { pw_name char* }
-    { pw_passwd char* }
+    { pw_name c-string }
+    { pw_passwd c-string }
     { pw_uid uid_t }
     { pw_gid gid_t }
     { pw_change time_t }
-    { pw_class char* }
-    { pw_gecos char* }
-    { pw_dir char* }
-    { pw_shell char* }
+    { pw_class c-string }
+    { pw_gecos c-string }
+    { pw_dir c-string }
+    { pw_shell c-string }
     { pw_expire time_t }
     { pw_fields int } ;
 
diff --git a/basis/unix/ffi/bsd/freebsd/freebsd.factor b/basis/unix/ffi/bsd/freebsd/freebsd.factor
index 992d1c3ad0..112758a3e8 100644
--- a/basis/unix/ffi/bsd/freebsd/freebsd.factor
+++ b/basis/unix/ffi/bsd/freebsd/freebsd.factor
@@ -9,7 +9,7 @@ STRUCT: addrinfo
     { socktype int }
     { protocol int }
     { addrlen socklen_t }
-    { canonname char* }
+    { canonname c-string }
     { addr void* }
     { next addrinfo* } ;
 
diff --git a/basis/unix/ffi/bsd/macosx/macosx.factor b/basis/unix/ffi/bsd/macosx/macosx.factor
index a7c47f0ff8..2ca1d9315d 100644
--- a/basis/unix/ffi/bsd/macosx/macosx.factor
+++ b/basis/unix/ffi/bsd/macosx/macosx.factor
@@ -11,7 +11,7 @@ STRUCT: addrinfo
     { socktype int }
     { protocol int }
     { addrlen socklen_t }
-    { canonname char* }
+    { canonname c-string }
     { addr void* }
     { next addrinfo* } ;
 
diff --git a/basis/unix/ffi/bsd/netbsd/netbsd.factor b/basis/unix/ffi/bsd/netbsd/netbsd.factor
index d755caf874..e15971b150 100644
--- a/basis/unix/ffi/bsd/netbsd/netbsd.factor
+++ b/basis/unix/ffi/bsd/netbsd/netbsd.factor
@@ -10,7 +10,7 @@ STRUCT: addrinfo
     { socktype int }
     { protocol int }
     { addrlen socklen_t }
-    { canonname char* }
+    { canonname c-string }
     { addr void* }
     { next addrinfo* } ;
 
diff --git a/basis/unix/ffi/bsd/openbsd/openbsd.factor b/basis/unix/ffi/bsd/openbsd/openbsd.factor
index 076dbdfd24..1f4eddef66 100644
--- a/basis/unix/ffi/bsd/openbsd/openbsd.factor
+++ b/basis/unix/ffi/bsd/openbsd/openbsd.factor
@@ -10,7 +10,7 @@ STRUCT: addrinfo
     { protocol int }
     { addrlen socklen_t }
     { addr void* }
-    { canonname char* }
+    { canonname c-string }
     { next addrinfo* } ;
 
 STRUCT: dirent
diff --git a/basis/unix/ffi/ffi.factor b/basis/unix/ffi/ffi.factor
index 10346cff2c..555bab32e4 100644
--- a/basis/unix/ffi/ffi.factor
+++ b/basis/unix/ffi/ffi.factor
@@ -44,21 +44,21 @@ CONSTANT: DT_WHT      14
 
 LIBRARY: libc
 
-FUNCTION: char* strerror ( int errno ) ;
+FUNCTION: c-string strerror ( int errno ) ;
 
 STRUCT: group
-    { gr_name char* }
-    { gr_passwd char* }
+    { gr_name c-string }
+    { gr_passwd c-string }
     { gr_gid int }
-    { gr_mem char** } ;
+    { gr_mem c-string* } ;
 
 FUNCTION: int accept ( int s, void* sockaddr, socklen_t* socklen ) ;
 FUNCTION: int bind ( int s, void* name, socklen_t namelen ) ;
-FUNCTION: int chdir ( char* path ) ;
-FUNCTION: int chmod ( char* path, mode_t mode ) ;
+FUNCTION: int chdir ( c-string path ) ;
+FUNCTION: int chmod ( c-string path, mode_t mode ) ;
 FUNCTION: int fchmod ( int fd, mode_t mode ) ;
-FUNCTION: int chown ( char* path, uid_t owner, gid_t group ) ;
-FUNCTION: int chroot ( char* path ) ;
+FUNCTION: int chown ( c-string path, uid_t owner, gid_t group ) ;
+FUNCTION: int chroot ( c-string path ) ;
 FUNCTION: int close ( int fd ) ;
 FUNCTION: int closedir ( DIR* dirp ) ;
 FUNCTION: int connect ( int s, void* name, socklen_t namelen ) ;
@@ -70,31 +70,31 @@ FUNCTION: int fcntl ( int fd, int cmd, int arg ) ;
 FUNCTION: int flock ( int fd, int operation ) ;
 FUNCTION: void freeaddrinfo ( addrinfo* ai ) ;
 FUNCTION: int futimes ( int id, timeval[2] times ) ;
-FUNCTION: char* gai_strerror ( int ecode ) ;
-FUNCTION: int getaddrinfo ( char* hostname, char* servname, addrinfo* hints, addrinfo** res ) ;
-FUNCTION: char* getcwd ( char* buf, size_t size ) ;
+FUNCTION: c-string gai_strerror ( int ecode ) ;
+FUNCTION: int getaddrinfo ( c-string hostname, c-string servname, addrinfo* hints, addrinfo** res ) ;
+FUNCTION: c-string getcwd ( c-string buf, size_t size ) ;
 FUNCTION: pid_t getpid ;
 FUNCTION: int getdtablesize ;
 FUNCTION: gid_t getegid ;
 FUNCTION: uid_t geteuid ;
 FUNCTION: gid_t getgid ;
-FUNCTION: char* getenv ( char* name ) ;
+FUNCTION: c-string getenv ( c-string name ) ;
 
-FUNCTION: int getgrgid_r ( gid_t gid, group* grp, char* buffer, size_t bufsize, group** result ) ;
-FUNCTION: int getgrnam_r ( char* name, group* grp, char* buffer, size_t bufsize, group** result ) ;
+FUNCTION: int getgrgid_r ( gid_t gid, group* grp, c-string buffer, size_t bufsize, group** result ) ;
+FUNCTION: int getgrnam_r ( c-string name, group* grp, c-string buffer, size_t bufsize, group** result ) ;
 FUNCTION: passwd* getpwent ( ) ;
 FUNCTION: passwd* getpwuid ( uid_t uid ) ;
-FUNCTION: passwd* getpwnam ( char* login ) ;
-FUNCTION: int getpwnam_r ( char* login, passwd* pwd, char* buffer, size_t bufsize, passwd** result ) ;
+FUNCTION: passwd* getpwnam ( c-string login ) ;
+FUNCTION: int getpwnam_r ( c-string login, passwd* pwd, c-string buffer, size_t bufsize, passwd** result ) ;
 FUNCTION: int getgroups ( int gidsetlen, gid_t* gidset ) ;
-FUNCTION: int getgrouplist ( char* name, int basegid, int* groups, int* ngroups ) ;
+FUNCTION: int getgrouplist ( c-string name, int basegid, int* groups, int* ngroups ) ;
 FUNCTION: int getrlimit ( int resource, rlimit* rlp ) ;
 FUNCTION: int setrlimit ( int resource, rlimit* rlp ) ;
 FUNCTION: int getpriority ( int which, id_t who ) ;
 FUNCTION: int setpriority ( int which, id_t who, int prio ) ;
 FUNCTION: int getrusage ( int who, rusage* r_usage ) ;
 FUNCTION: group* getgrent ;
-FUNCTION: int gethostname ( char* name, int len ) ;
+FUNCTION: int gethostname ( c-string name, int len ) ;
 FUNCTION: int getsockname ( int socket, sockaddr* address, socklen_t* address_len ) ;
 FUNCTION: int getpeername ( int socket, sockaddr* address, socklen_t* address_len ) ;
 FUNCTION: uid_t getuid ;
@@ -102,44 +102,44 @@ FUNCTION: uint htonl ( uint n ) ;
 FUNCTION: ushort htons ( ushort n ) ;
 ! FUNCTION: int issetugid ;
 FUNCTION: int isatty ( int fildes ) ;
-FUNCTION: int ioctl ( int fd, ulong request, char* argp ) ;
-FUNCTION: int lchown ( char* path, uid_t owner, gid_t group ) ;
+FUNCTION: int ioctl ( int fd, ulong request, c-string argp ) ;
+FUNCTION: int lchown ( c-string path, uid_t owner, gid_t group ) ;
 FUNCTION: int listen ( int s, int backlog ) ;
 FUNCTION: off_t lseek ( int fildes, off_t offset, int whence ) ;
-FUNCTION: int mkdir ( char* path, mode_t mode ) ;
+FUNCTION: int mkdir ( c-string path, mode_t mode ) ;
 FUNCTION: void* mmap ( void* addr, size_t len, int prot, int flags, int fd, off_t offset ) ;
 FUNCTION: int munmap ( void* addr, size_t len ) ;
 FUNCTION: uint ntohl ( uint n ) ;
 FUNCTION: ushort ntohs ( ushort n ) ;
 FUNCTION: int shutdown ( int fd, int how ) ;
-FUNCTION: int open ( char* path, int flags, int prot ) ;
-FUNCTION: DIR* opendir ( char* path ) ;
+FUNCTION: int open ( c-string path, int flags, int prot ) ;
+FUNCTION: DIR* opendir ( c-string path ) ;
 
 STRUCT: utimbuf
     { actime time_t }
     { modtime time_t } ;
 
-FUNCTION: int utime ( char* path, utimbuf* buf ) ;
+FUNCTION: int utime ( c-string path, utimbuf* buf ) ;
 
 FUNCTION: int pclose ( void* file ) ;
 FUNCTION: int pipe ( int* filedes ) ;
-FUNCTION: void* popen ( char* command, char* type ) ;
+FUNCTION: void* popen ( c-string command, c-string type ) ;
 FUNCTION: ssize_t read ( int fd, void* buf, size_t nbytes ) ;
 
 FUNCTION: dirent* readdir ( DIR* dirp ) ;
 FUNCTION: int readdir_r ( void* dirp, dirent* entry, dirent** result ) ;
-FUNCTION: ssize_t readlink ( char* path, char* buf, size_t bufsize ) ;
+FUNCTION: ssize_t readlink ( c-string path, c-string buf, size_t bufsize ) ;
 
 CONSTANT: PATH_MAX 1024
 
 FUNCTION: ssize_t recv ( int s, void* buf, size_t nbytes, int flags ) ;
 FUNCTION: ssize_t recvfrom ( int s, void* buf, size_t nbytes, int flags, sockaddr-in* from, socklen_t* fromlen ) ;
-FUNCTION: int rename ( char* from, char* to ) ;
-FUNCTION: int rmdir ( char* path ) ;
+FUNCTION: int rename ( c-string from, c-string to ) ;
+FUNCTION: int rmdir ( c-string path ) ;
 FUNCTION: int select ( int nfds, void* readfds, void* writefds, void* exceptfds, timeval* timeout ) ;
 FUNCTION: ssize_t sendto ( int s, void* buf, size_t len, int flags, sockaddr-in* to, socklen_t tolen ) ;
-FUNCTION: int setenv ( char* name, char* value, int overwrite ) ;
-FUNCTION: int unsetenv ( char* name ) ;
+FUNCTION: int setenv ( c-string name, c-string value, int overwrite ) ;
+FUNCTION: int unsetenv ( c-string name ) ;
 FUNCTION: int setegid ( gid_t egid ) ;
 FUNCTION: int seteuid ( uid_t euid ) ;
 FUNCTION: int setgid ( gid_t gid ) ;
@@ -149,11 +149,11 @@ FUNCTION: int setreuid ( uid_t ruid, uid_t euid ) ;
 FUNCTION: int setsockopt ( int s, int level, int optname, void* optval, socklen_t optlen ) ;
 FUNCTION: int setuid ( uid_t uid ) ;
 FUNCTION: int socket ( int domain, int type, int protocol ) ;
-FUNCTION: int symlink ( char* path1, char* path2 ) ;
-FUNCTION: int link ( char* path1, char* path2 ) ;
-FUNCTION: int system ( char* command ) ;
-FUNCTION: int unlink ( char* path ) ;
-FUNCTION: int utimes ( char* path, timeval[2] times ) ;
+FUNCTION: int symlink ( c-string path1, c-string path2 ) ;
+FUNCTION: int link ( c-string path1, c-string path2 ) ;
+FUNCTION: int system ( c-string command ) ;
+FUNCTION: int unlink ( c-string path ) ;
+FUNCTION: int utimes ( c-string path, timeval[2] times ) ;
 FUNCTION: ssize_t write ( int fd, void* buf, size_t nbytes ) ;
 
 "librt" "librt.so" "cdecl" add-library
diff --git a/basis/unix/ffi/linux/linux.factor b/basis/unix/ffi/linux/linux.factor
index 260796b5e4..3f19e18c14 100644
--- a/basis/unix/ffi/linux/linux.factor
+++ b/basis/unix/ffi/linux/linux.factor
@@ -38,7 +38,7 @@ STRUCT: addrinfo
     { protocol int }
     { addrlen socklen_t }
     { addr void* }
-    { canonname char* }
+    { canonname c-string }
     { next addrinfo* } ;
 
 STRUCT: sockaddr-in
@@ -83,13 +83,13 @@ CONSTANT: SEEK_CUR 1
 CONSTANT: SEEK_END 2
 
 STRUCT: passwd
-    { pw_name char* }
-    { pw_passwd char* }
+    { pw_name c-string }
+    { pw_passwd c-string }
     { pw_uid uid_t }
     { pw_gid gid_t }
-    { pw_gecos char* }
-    { pw_dir char* }
-    { pw_shell char* } ;
+    { pw_gecos c-string }
+    { pw_dir c-string }
+    { pw_shell c-string } ;
 
 ! dirent64
 STRUCT: dirent
@@ -99,7 +99,7 @@ STRUCT: dirent
     { d_type uchar }
     { d_name char[256] } ;
 
-FUNCTION: int open64 ( char* path, int flags, int prot ) ;
+FUNCTION: int open64 ( c-string path, int flags, int prot ) ;
 FUNCTION: dirent* readdir64 ( DIR* dirp ) ;
 FUNCTION: int readdir64_r ( void* dirp, dirent* entry, dirent** result ) ;
 
diff --git a/basis/unix/ffi/solaris/solaris.factor b/basis/unix/ffi/solaris/solaris.factor
index d641961a25..a08785823a 100644
--- a/basis/unix/ffi/solaris/solaris.factor
+++ b/basis/unix/ffi/solaris/solaris.factor
@@ -35,7 +35,7 @@ STRUCT: addrinfo
 !         int _ai_pad;            
 ! #endif
     { addrlen int }
-    { canonname char* }
+    { canonname c-string }
     { addr void* }
     { next void* } ;
 
diff --git a/basis/unix/linux/inotify/inotify.factor b/basis/unix/linux/inotify/inotify.factor
index f589c17e28..c296cc8166 100644
--- a/basis/unix/linux/inotify/inotify.factor
+++ b/basis/unix/linux/inotify/inotify.factor
@@ -52,5 +52,5 @@ CONSTANT: IN_ONESHOT HEX: 80000000    ! only send event once
     } flags ; foldable
 
 FUNCTION: int inotify_init ( ) ;
-FUNCTION: int inotify_add_watch ( int fd, char* name, uint mask  ) ;
+FUNCTION: int inotify_add_watch ( int fd, c-string name, uint mask  ) ;
 FUNCTION: int inotify_rm_watch ( int fd, uint wd ) ;
diff --git a/basis/unix/process/process.factor b/basis/unix/process/process.factor
index ab10aef3ea..4b33c37d07 100644
--- a/basis/unix/process/process.factor
+++ b/basis/unix/process/process.factor
@@ -11,9 +11,9 @@ FUNCTION: pid_t fork ( ) ;
 
 : fork-process ( -- pid ) [ fork ] unix-system-call ;
 
-FUNCTION: int execv ( char* path, char** argv ) ;
-FUNCTION: int execvp ( char* path, char** argv ) ;
-FUNCTION: int execve ( char* path, char** argv, char** envp ) ;
+FUNCTION: int execv ( c-string path, c-string* argv ) ;
+FUNCTION: int execvp ( c-string path, c-string* argv ) ;
+FUNCTION: int execve ( c-string path, c-string* argv, c-string* envp ) ;
 
 : exec ( pathname argv -- int )
     [ utf8 malloc-string ] [ utf8 strings>alien ] bi* execv ;
diff --git a/basis/unix/stat/freebsd/freebsd.factor b/basis/unix/stat/freebsd/freebsd.factor
index 04f884e496..93ed1a42db 100644
--- a/basis/unix/stat/freebsd/freebsd.factor
+++ b/basis/unix/stat/freebsd/freebsd.factor
@@ -24,5 +24,5 @@ STRUCT: stat
     { st_birthtimespec timespec }
     { pad0 __int32_t[2] } ;
 
-FUNCTION: int stat  ( char* pathname, stat* buf ) ;
-FUNCTION: int lstat ( char* pathname, stat* buf ) ;
+FUNCTION: int stat  ( c-string pathname, stat* buf ) ;
+FUNCTION: int lstat ( c-string pathname, stat* buf ) ;
diff --git a/basis/unix/stat/linux/32/32.factor b/basis/unix/stat/linux/32/32.factor
index f01140ff4b..b3becff240 100644
--- a/basis/unix/stat/linux/32/32.factor
+++ b/basis/unix/stat/linux/32/32.factor
@@ -21,8 +21,8 @@ STRUCT: stat
     { st_ctimespec timespec }
     { st_ino ulonglong } ;
 
-FUNCTION: int __xstat64  ( int ver, char* pathname, stat* buf ) ;
-FUNCTION: int __lxstat64 ( int ver, char* pathname, stat* buf ) ;
+FUNCTION: int __xstat64  ( int ver, c-string pathname, stat* buf ) ;
+FUNCTION: int __lxstat64 ( int ver, c-string pathname, stat* buf ) ;
 
 :  stat ( pathname buf -- int ) [ 1 ] 2dip __xstat64 ;
 : lstat ( pathname buf -- int ) [ 1 ] 2dip __lxstat64 ;
diff --git a/basis/unix/stat/linux/64/64.factor b/basis/unix/stat/linux/64/64.factor
index bb16133c76..0862bf82a0 100644
--- a/basis/unix/stat/linux/64/64.factor
+++ b/basis/unix/stat/linux/64/64.factor
@@ -21,8 +21,8 @@ STRUCT: stat
     { st_ctimespec timespec }
     { __unused0 long[3] } ;
 
-FUNCTION: int __xstat64  ( int ver, char* pathname, stat* buf ) ;
-FUNCTION: int __lxstat64 ( int ver, char* pathname, stat* buf ) ;
+FUNCTION: int __xstat64  ( int ver, c-string pathname, stat* buf ) ;
+FUNCTION: int __lxstat64 ( int ver, c-string pathname, stat* buf ) ;
 
 :  stat ( pathname buf -- int ) [ 1 ] 2dip __xstat64 ;
 : lstat ( pathname buf -- int ) [ 1 ] 2dip __lxstat64 ;
diff --git a/basis/unix/stat/macosx/macosx.factor b/basis/unix/stat/macosx/macosx.factor
index 4e6b2dfb21..024cd317e8 100644
--- a/basis/unix/stat/macosx/macosx.factor
+++ b/basis/unix/stat/macosx/macosx.factor
@@ -26,8 +26,8 @@ STRUCT: stat
     { st_qspare0 __int64_t }
     { st_qspare1 __int64_t } ;
 
-FUNCTION: int stat64  ( char* pathname, stat* buf ) ;
-FUNCTION: int lstat64 ( char* pathname, stat* buf ) ;
+FUNCTION: int stat64  ( c-string pathname, stat* buf ) ;
+FUNCTION: int lstat64 ( c-string pathname, stat* buf ) ;
 
 : stat ( path buf -- n ) stat64 ;
 : lstat ( path buf -- n ) lstat64 ;
diff --git a/basis/unix/stat/netbsd/32/32.factor b/basis/unix/stat/netbsd/32/32.factor
index fb0d61b7e9..bb0a403751 100644
--- a/basis/unix/stat/netbsd/32/32.factor
+++ b/basis/unix/stat/netbsd/32/32.factor
@@ -23,8 +23,8 @@ STRUCT: stat
     { st_gen uint32_t }
     { st_qspare uint32_t[2] } ;
 
-FUNCTION: int __stat30  ( char* pathname, stat* buf ) ;
-FUNCTION: int __lstat30 ( char* pathname, stat* buf ) ;
+FUNCTION: int __stat30  ( c-string pathname, stat* buf ) ;
+FUNCTION: int __lstat30 ( c-string pathname, stat* buf ) ;
 
 : stat ( pathname buf -- n ) __stat30 ;
 : lstat ( pathname buf -- n ) __lstat30 ;
diff --git a/basis/unix/stat/netbsd/64/64.factor b/basis/unix/stat/netbsd/64/64.factor
index 47c4e0c129..010dcca724 100644
--- a/basis/unix/stat/netbsd/64/64.factor
+++ b/basis/unix/stat/netbsd/64/64.factor
@@ -23,8 +23,8 @@ STRUCT: stat
     { st_spare0 uint32_t }
     { st_birthtimespec timespec } ;
 
-FUNCTION: int __stat13 ( char* pathname, stat* buf ) ;
-FUNCTION: int __lstat13 ( char* pathname, stat* buf ) ;
+FUNCTION: int __stat13 ( c-string pathname, stat* buf ) ;
+FUNCTION: int __lstat13 ( c-string pathname, stat* buf ) ;
 
 : stat ( pathname buf -- n ) __stat13 ;
 : lstat ( pathname buf -- n ) __lstat13 ;
diff --git a/basis/unix/stat/openbsd/openbsd.factor b/basis/unix/stat/openbsd/openbsd.factor
index 2702e60f6c..b562d085b3 100644
--- a/basis/unix/stat/openbsd/openbsd.factor
+++ b/basis/unix/stat/openbsd/openbsd.factor
@@ -25,5 +25,5 @@ STRUCT: stat
     { st_birthtimespec timespec }
     { st_qspare int64_t[2] } ;
 
-FUNCTION: int stat  ( char* pathname, stat* buf ) ;
-FUNCTION: int lstat ( char* pathname, stat* buf ) ;
+FUNCTION: int stat  ( c-string pathname, stat* buf ) ;
+FUNCTION: int lstat ( c-string pathname, stat* buf ) ;
diff --git a/basis/unix/statfs/freebsd/freebsd.factor b/basis/unix/statfs/freebsd/freebsd.factor
index ae418e6eb4..f12473da92 100644
--- a/basis/unix/statfs/freebsd/freebsd.factor
+++ b/basis/unix/statfs/freebsd/freebsd.factor
@@ -31,4 +31,4 @@ STRUCT: statfs
     { f_mntfromname { char MNAMELEN } }
     { f_mntonname { char MNAMELEN } } ;
 
-FUNCTION: int statfs ( char* path, statfs* buf ) ;
+FUNCTION: int statfs ( c-string path, statfs* buf ) ;
diff --git a/basis/unix/statfs/linux/linux.factor b/basis/unix/statfs/linux/linux.factor
index ab37ab9605..2cf2541a10 100644
--- a/basis/unix/statfs/linux/linux.factor
+++ b/basis/unix/statfs/linux/linux.factor
@@ -16,4 +16,4 @@ STRUCT: statfs64
     { f_frsize __SWORD_TYPE }
     { f_spare __SWORD_TYPE[5] } ;
 
-FUNCTION: int statfs64 ( char* path, statfs64* buf ) ;
+FUNCTION: int statfs64 ( c-string path, statfs64* buf ) ;
diff --git a/basis/unix/statfs/macosx/macosx.factor b/basis/unix/statfs/macosx/macosx.factor
index 56c8989895..75b231da96 100644
--- a/basis/unix/statfs/macosx/macosx.factor
+++ b/basis/unix/statfs/macosx/macosx.factor
@@ -116,5 +116,5 @@ STRUCT: statfs64
     { f_mntfromname { char MAXPATHLEN } }
     { f_reserved uint32_t[8] } ;
 
-FUNCTION: int statfs64 ( char* path, statfs64* buf ) ;
+FUNCTION: int statfs64 ( c-string path, statfs64* buf ) ;
 FUNCTION: int getmntinfo64 ( statfs64** mntbufp, int flags ) ;
diff --git a/basis/unix/statfs/openbsd/openbsd.factor b/basis/unix/statfs/openbsd/openbsd.factor
index 4e65e74c2c..9c63bfa96b 100644
--- a/basis/unix/statfs/openbsd/openbsd.factor
+++ b/basis/unix/statfs/openbsd/openbsd.factor
@@ -31,4 +31,4 @@ STRUCT: statfs
     { f_mntfromname { char MNAMELEN } }
     { mount_info char[160] } ;
 
-FUNCTION: int statfs ( char* path, statfs* buf ) ;
+FUNCTION: int statfs ( c-string path, statfs* buf ) ;
diff --git a/basis/unix/statvfs/freebsd/freebsd.factor b/basis/unix/statvfs/freebsd/freebsd.factor
index c2834736b7..5e66a7daf9 100644
--- a/basis/unix/statvfs/freebsd/freebsd.factor
+++ b/basis/unix/statvfs/freebsd/freebsd.factor
@@ -20,4 +20,4 @@ STRUCT: statvfs
 CONSTANT: ST_RDONLY   HEX: 1 ! Read-only file system
 CONSTANT: ST_NOSUID   HEX: 2 ! Does not honor setuid/setgid
 
-FUNCTION: int statvfs ( char* path, statvfs* buf ) ;
+FUNCTION: int statvfs ( c-string path, statvfs* buf ) ;
diff --git a/basis/unix/statvfs/linux/linux.factor b/basis/unix/statvfs/linux/linux.factor
index d7139d84b2..bda1eb9605 100644
--- a/basis/unix/statvfs/linux/linux.factor
+++ b/basis/unix/statvfs/linux/linux.factor
@@ -17,7 +17,7 @@ STRUCT: statvfs64
     { f_namemax ulong }
     { __f_spare int[6] } ;
 
-FUNCTION: int statvfs64 ( char* path, statvfs64* buf ) ;
+FUNCTION: int statvfs64 ( c-string path, statvfs64* buf ) ;
 
 CONSTANT: ST_RDONLY 1        ! Mount read-only.
 CONSTANT: ST_NOSUID 2        ! Ignore suid and sgid bits.
diff --git a/basis/unix/statvfs/macosx/macosx.factor b/basis/unix/statvfs/macosx/macosx.factor
index 3fe44a28d0..18b794acbf 100644
--- a/basis/unix/statvfs/macosx/macosx.factor
+++ b/basis/unix/statvfs/macosx/macosx.factor
@@ -20,4 +20,4 @@ STRUCT: statvfs
 CONSTANT: ST_RDONLY   HEX: 1 ! Read-only file system
 CONSTANT: ST_NOSUID   HEX: 2 ! Does not honor setuid/setgid
 
-FUNCTION: int statvfs ( char* path, statvfs* buf ) ;
+FUNCTION: int statvfs ( c-string path, statvfs* buf ) ;
diff --git a/basis/unix/statvfs/netbsd/netbsd.factor b/basis/unix/statvfs/netbsd/netbsd.factor
index a76774b656..f53d72f02e 100644
--- a/basis/unix/statvfs/netbsd/netbsd.factor
+++ b/basis/unix/statvfs/netbsd/netbsd.factor
@@ -33,4 +33,4 @@ STRUCT: statvfs
     { f_mntonname { char _VFS_MNAMELEN } }
     { f_mntfromname { char _VFS_MNAMELEN } } ;
 
-FUNCTION: int statvfs ( char* path, statvfs* buf ) ;
+FUNCTION: int statvfs ( c-string path, statvfs* buf ) ;
diff --git a/basis/unix/statvfs/openbsd/openbsd.factor b/basis/unix/statvfs/openbsd/openbsd.factor
index d5b2ee30a8..146db770ef 100644
--- a/basis/unix/statvfs/openbsd/openbsd.factor
+++ b/basis/unix/statvfs/openbsd/openbsd.factor
@@ -19,4 +19,4 @@ STRUCT: statvfs
 CONSTANT: ST_RDONLY       1
 CONSTANT: ST_NOSUID       2
 
-FUNCTION: int statvfs ( char* path, statvfs* buf ) ;
+FUNCTION: int statvfs ( c-string path, statvfs* buf ) ;
diff --git a/basis/unix/time/time.factor b/basis/unix/time/time.factor
index 0a63965c20..72132bb132 100644
--- a/basis/unix/time/time.factor
+++ b/basis/unix/time/time.factor
@@ -35,7 +35,7 @@ STRUCT: tm
     { yday int }
     { isdst int }
     { gmtoff long }
-    { zone char* } ;
+    { zone c-string } ;
 
 FUNCTION: time_t time ( time_t* t ) ;
 FUNCTION: tm* localtime ( time_t* clock ) ;
diff --git a/basis/windows/kernel32/kernel32.factor b/basis/windows/kernel32/kernel32.factor
index db0005e219..c2622cbf48 100644
--- a/basis/windows/kernel32/kernel32.factor
+++ b/basis/windows/kernel32/kernel32.factor
@@ -1352,7 +1352,7 @@ FUNCTION: DWORD GetPriorityClass ( HANDLE hProcess ) ;
 ! FUNCTION: GetPrivateProfileStringW
 ! FUNCTION: GetPrivateProfileStructA
 ! FUNCTION: GetPrivateProfileStructW
-FUNCTION: LPVOID GetProcAddress ( HMODULE hModule, char* lpProcName ) ;
+FUNCTION: LPVOID GetProcAddress ( HMODULE hModule, c-string lpProcName ) ;
 ! FUNCTION: GetProcessAffinityMask
 ! FUNCTION: GetProcessHandleCount
 ! FUNCTION: GetProcessHeap
diff --git a/basis/windows/ole32/ole32.factor b/basis/windows/ole32/ole32.factor
index 6e90cae89a..538a142878 100644
--- a/basis/windows/ole32/ole32.factor
+++ b/basis/windows/ole32/ole32.factor
@@ -10,8 +10,8 @@ LIBRARY: ole32
 
 TYPEDEF: GUID* REFGUID
 TYPEDEF: void* LPUNKNOWN
-TYPEDEF: wchar_t* LPOLESTR
-TYPEDEF: wchar_t* LPCOLESTR
+TYPEDEF: LPWSTR LPOLESTR
+TYPEDEF: LPWSTR LPCOLESTR
 
 TYPEDEF: REFGUID LPGUID
 TYPEDEF: REFGUID REFIID
diff --git a/basis/windows/opengl32/opengl32.factor b/basis/windows/opengl32/opengl32.factor
index 63f705263c..32e067a200 100644
--- a/basis/windows/opengl32/opengl32.factor
+++ b/basis/windows/opengl32/opengl32.factor
@@ -57,7 +57,7 @@ FUNCTION: BOOL wglMakeCurrent ( HDC hDC, HGLRC hglrc ) ;
 
 ! WGL_ARB_extensions_string extension
 
-GL-FUNCTION: char* wglGetExtensionsStringARB { } ( HDC hDC ) ;
+GL-FUNCTION: c-string wglGetExtensionsStringARB { } ( HDC hDC ) ;
 
 ! WGL_ARB_pixel_format extension
 
diff --git a/basis/windows/types/types.factor b/basis/windows/types/types.factor
index d0dac31ea9..e2e4b113a4 100644
--- a/basis/windows/types/types.factor
+++ b/basis/windows/types/types.factor
@@ -11,7 +11,6 @@ TYPEDEF: uchar               UCHAR
 TYPEDEF: uchar               BYTE
 
 TYPEDEF: ushort              wchar_t
-<< { char* utf16n } pointer: wchar_t typedef >>
 
 TYPEDEF: wchar_t             WCHAR
 
@@ -70,8 +69,8 @@ TYPEDEF: ULARGE_INTEGER* PULARGE_INTEGER
 TYPEDEF: size_t SIZE_T
 TYPEDEF: ptrdiff_t SSIZE_T
 
-TYPEDEF: wchar_t*  LPCSTR
-TYPEDEF: wchar_t*  LPWSTR
+TYPEDEF: { c-string utf16n } LPCSTR
+TYPEDEF: { c-string utf16n } LPWSTR
 TYPEDEF: WCHAR       TCHAR
 TYPEDEF: LPWSTR      LPTCH
 TYPEDEF: LPWSTR      PTCH
@@ -125,14 +124,14 @@ TYPEDEF: DWORD               LGRPID
 TYPEDEF: LONG_PTR            LPARAM
 TYPEDEF: BOOL*               LPBOOL
 TYPEDEF: BYTE*               LPBYTE
-TYPEDEF: WCHAR*              LPCWSTR
+TYPEDEF: { c-string utf16n } LPCWSTR
 ! TYPEDEF: WCHAR*              LPWSTR
 
-TYPEDEF: WCHAR*               LPSTR
-TYPEDEF: wchar_t* LPCTSTR
-TYPEDEF: wchar_t* LPWTSTR
+TYPEDEF: { c-string utf16n } LPSTR
+TYPEDEF: { c-string utf16n } LPCTSTR
+TYPEDEF: { c-string utf16n } LPWTSTR
 
-TYPEDEF: wchar_t*       LPTSTR
+TYPEDEF: { c-string utf16n } LPTSTR
 TYPEDEF: LPCSTR      PCTSTR
 TYPEDEF: LPSTR       PTSTR
 
@@ -145,7 +144,7 @@ TYPEDEF: BOOLEAN*            PBOOLEAN
 TYPEDEF: BYTE*               PBYTE
 TYPEDEF: CHAR*               PCHAR
 TYPEDEF: CHAR*               PCSTR
-TYPEDEF: WCHAR*              PCWSTR
+TYPEDEF: { c-string utf16n } PCWSTR
 TYPEDEF: DWORD*              PDWORD
 TYPEDEF: DWORDLONG*          PDWORDLONG
 TYPEDEF: DWORD_PTR*          PDWORD_PTR
@@ -182,9 +181,9 @@ TYPEDEF: ULONG_PTR*          PULONG_PTR
 TYPEDEF: ULONG32*            PULONG32
 TYPEDEF: ULONG64*            PULONG64
 TYPEDEF: USHORT*             PUSHORT
-TYPEDEF: WCHAR*              PWCHAR
+TYPEDEF: { c-string utf16n } PWCHAR
 TYPEDEF: WORD*               PWORD
-TYPEDEF: WCHAR*              PWSTR
+TYPEDEF: { c-string utf16n } PWSTR
 TYPEDEF: HANDLE              SC_HANDLE
 TYPEDEF: LPVOID              SC_LOCK
 TYPEDEF: HANDLE              SERVICE_STATUS_HANDLE
@@ -350,7 +349,7 @@ STRUCT: LVITEM
 
 STRUCT: LVFINDINFO
     { flags uint }
-    { psz char* }
+    { psz c-string }
     { lParam long }
     { pt POINT }
     { vkDirection uint } ;
diff --git a/basis/windows/user32/user32.factor b/basis/windows/user32/user32.factor
index 27636271cb..a966b63308 100644
--- a/basis/windows/user32/user32.factor
+++ b/basis/windows/user32/user32.factor
@@ -1186,8 +1186,8 @@ FUNCTION: UINT EnumClipboardFormats ( UINT format ) ;
 ! FUNCTION: ExcludeUpdateRgn
 ! FUNCTION: ExitWindowsEx
 FUNCTION: int FillRect ( HDC hDC, RECT* lprc, HBRUSH hbr ) ;
-FUNCTION: HWND FindWindowA ( char* lpClassName, char* lpWindowName ) ;
-FUNCTION: HWND FindWindowExA ( HWND hwndParent, HWND childAfter, char* lpClassName, char* lpWindowName ) ;
+FUNCTION: HWND FindWindowA ( c-string lpClassName, c-string lpWindowName ) ;
+FUNCTION: HWND FindWindowExA ( HWND hwndParent, HWND childAfter, c-string lpClassName, c-string lpWindowName ) ;
 ! FUNCTION: FindWindowExW
 ! FUNCTION: FindWindowW
 ! FUNCTION: FlashWindow
@@ -1352,7 +1352,7 @@ ALIAS: GetWindowLong GetWindowLongW
 FUNCTION: BOOL GetWindowRect ( HWND hWnd, LPRECT lpRect ) ;
 ! FUNCTION: GetWindowRgn
 ! FUNCTION: GetWindowRgnBox
-FUNCTION: int GetWindowTextA ( HWND hWnd, char* lpString, int nMaxCount ) ;
+FUNCTION: int GetWindowTextA ( HWND hWnd, c-string lpString, int nMaxCount ) ;
 ! FUNCTION: GetWindowTextLengthA
 ! FUNCTION: GetWindowTextLengthW
 ! FUNCTION: GetWindowTextW
diff --git a/basis/windows/winsock/winsock.factor b/basis/windows/winsock/winsock.factor
index 818737ca5a..b58cbcacbd 100644
--- a/basis/windows/winsock/winsock.factor
+++ b/basis/windows/winsock/winsock.factor
@@ -121,7 +121,7 @@ STRUCT: sockaddr-in6
     { scopeid uint } ;
 
 STRUCT: hostent
-    { name char* }
+    { name c-string }
     { aliases void* }
     { addrtype short }
     { length short }
@@ -133,7 +133,7 @@ STRUCT: addrinfo
     { socktype int }
     { protocol int }
     { addrlen size_t }
-    { canonname char* }
+    { canonname c-string }
     { addr sockaddr* }
     { next addrinfo* } ;
 
@@ -145,29 +145,29 @@ C-TYPE: fd_set
 
 LIBRARY: winsock
 
-FUNCTION: int setsockopt ( SOCKET s, int level, int optname, char* optval, int optlen ) ;
+FUNCTION: int setsockopt ( SOCKET s, int level, int optname, c-string optval, int optlen ) ;
 
 FUNCTION: ushort htons ( ushort n ) ;
 FUNCTION: ushort ntohs ( ushort n ) ;
 FUNCTION: int bind ( void* socket, sockaddr-in* sockaddr, int len ) ;
 FUNCTION: int listen ( void* socket, int backlog ) ;
-FUNCTION: char* inet_ntoa ( int in-addr ) ;
-FUNCTION: int getaddrinfo ( char* nodename,
-                            char* servername,
+FUNCTION: c-string inet_ntoa ( int in-addr ) ;
+FUNCTION: int getaddrinfo ( c-string nodename,
+                            c-string servername,
                             addrinfo* hints,
                             addrinfo** res ) ;
 
 FUNCTION: void freeaddrinfo ( addrinfo* ai ) ;
 
 
-FUNCTION: hostent* gethostbyname ( char* name ) ;
-FUNCTION: int gethostname ( char* name, int len ) ;
+FUNCTION: hostent* gethostbyname ( c-string name ) ;
+FUNCTION: int gethostname ( c-string name, int len ) ;
 FUNCTION: int connect ( void* socket, sockaddr-in* sockaddr, int addrlen ) ;
 FUNCTION: int select ( int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, timeval* timeout ) ;
 FUNCTION: int closesocket ( SOCKET s ) ;
 FUNCTION: int shutdown ( SOCKET s, int how ) ;
-FUNCTION: int send ( SOCKET s, char* buf, int len, int flags ) ;
-FUNCTION: int recv ( SOCKET s, char* buf, int len, int flags ) ;
+FUNCTION: int send ( SOCKET s, c-string buf, int len, int flags ) ;
+FUNCTION: int recv ( SOCKET s, c-string buf, int len, int flags ) ;
 
 FUNCTION: int getsockname ( SOCKET s, sockaddr-in* address, int* addrlen ) ;
 FUNCTION: int getpeername ( SOCKET s, sockaddr-in* address, int* addrlen ) ;
diff --git a/basis/x11/glx/glx.factor b/basis/x11/glx/glx.factor
index 5bc58e5f0a..d095853913 100644
--- a/basis/x11/glx/glx.factor
+++ b/basis/x11/glx/glx.factor
@@ -55,9 +55,9 @@ X-FUNCTION: void glXSwapBuffers ( Display* dpy, GLXDrawable drawable ) ;
 X-FUNCTION: void glXUseXFont ( Font font, int first, int count, int listBase ) ;
 X-FUNCTION: void glXWaitGL ( ) ;
 X-FUNCTION: void glXWaitX ( ) ;
-X-FUNCTION: char* glXGetClientString ( Display* dpy, int name ) ;
-X-FUNCTION: char* glXQueryServerString ( Display* dpy, int screen, int name ) ;
-X-FUNCTION: char* glXQueryExtensionsString ( Display* dpy, int screen ) ;
+X-FUNCTION: c-string glXGetClientString ( Display* dpy, int name ) ;
+X-FUNCTION: c-string glXQueryServerString ( Display* dpy, int screen, int name ) ;
+X-FUNCTION: c-string glXQueryExtensionsString ( Display* dpy, int screen ) ;
 
 ! New for GLX 1.3
 X-FUNCTION: GLXFBConfig* glXGetFBConfigs ( Display* dpy, int screen, int* nelements ) ;
@@ -80,10 +80,10 @@ X-FUNCTION: void glXSelectEvent ( Display* dpy, GLXDrawable draw, ulong event_ma
 X-FUNCTION: void glXGetSelectedEvent ( Display* dpy, GLXDrawable draw, ulong* event_mask ) ;
 
 ! GLX 1.4 and later
-X-FUNCTION: void* glXGetProcAddress ( char* procname ) ;
+X-FUNCTION: void* glXGetProcAddress ( c-string procname ) ;
 
 ! GLX_ARB_get_proc_address extension
-X-FUNCTION: void* glXGetProcAddressARB ( char* procname ) ;
+X-FUNCTION: void* glXGetProcAddressARB ( c-string procname ) ;
 
 ! GLX_ARB_multisample
 CONSTANT: GLX_SAMPLE_BUFFERS 100000
diff --git a/basis/x11/xlib/xlib.factor b/basis/x11/xlib/xlib.factor
index 7235aaf679..88b058abea 100644
--- a/basis/x11/xlib/xlib.factor
+++ b/basis/x11/xlib/xlib.factor
@@ -30,7 +30,7 @@ TYPEDEF: XID KeySym
 
 TYPEDEF: ulong Atom
 
-TYPEDEF: char* XPointer
+TYPEDEF: c-string XPointer
 C-TYPE: Screen
 TYPEDEF: void* GC
 C-TYPE: Visual
@@ -256,13 +256,13 @@ X-FUNCTION: Bool XQueryPointer ( Display* display, Window w, Window* root_return
 
 ! 4.3 - Properties and Atoms
 
-X-FUNCTION: Atom XInternAtom ( Display* display, char* atom_name, Bool only_if_exists ) ;
+X-FUNCTION: Atom XInternAtom ( Display* display, c-string atom_name, Bool only_if_exists ) ;
 
-X-FUNCTION: char* XGetAtomName ( Display* display, Atom atom ) ;
+X-FUNCTION: c-string XGetAtomName ( Display* display, Atom atom ) ;
 
 ! 4.4 - Obtaining and Changing Window Properties
 
-X-FUNCTION: int XGetWindowProperty ( Display* display, Window w, Atom property, long long_offset, long long_length, Bool delete, Atom req_type, Atom* actual_type_return, int* actual_format_return, ulong* nitems_return, ulong* bytes_after_return, char** prop_return ) ;
+X-FUNCTION: int XGetWindowProperty ( Display* display, Window w, Atom property, long long_offset, long long_length, Bool delete, Atom req_type, Atom* actual_type_return, int* actual_format_return, ulong* nitems_return, ulong* bytes_after_return, c-string* prop_return ) ;
 
 X-FUNCTION: int XChangeProperty ( Display* display, Window w, Atom property, Atom type, int format, int mode, void* data, int nelements ) ;
 
@@ -302,7 +302,7 @@ STRUCT: XColor
 { flags char }
 { pad char } ;
 
-X-FUNCTION: Status XLookupColor ( Display* display, Colormap colormap, char* color_name, XColor* exact_def_return, XColor* screen_def_return ) ;
+X-FUNCTION: Status XLookupColor ( Display* display, Colormap colormap, c-string color_name, XColor* exact_def_return, XColor* screen_def_return ) ;
 X-FUNCTION: Status XAllocColor ( Display* display, Colormap colormap, XColor* screen_in_out ) ;
 X-FUNCTION: Status XQueryColor ( Display* display, Colormap colormap, XColor* def_in_out ) ;
 
@@ -430,11 +430,11 @@ STRUCT: XFontStruct
 { ascent int }
 { descent int } ;
 
-X-FUNCTION: Font XLoadFont ( Display* display, char* name ) ;
+X-FUNCTION: Font XLoadFont ( Display* display, c-string name ) ;
 X-FUNCTION: XFontStruct* XQueryFont ( Display* display, XID font_ID ) ;
-X-FUNCTION: XFontStruct* XLoadQueryFont ( Display* display, char* name ) ;
+X-FUNCTION: XFontStruct* XLoadQueryFont ( Display* display, c-string name ) ;
 
-X-FUNCTION: int XTextWidth ( XFontStruct* font_struct, char* string, int count ) ;
+X-FUNCTION: int XTextWidth ( XFontStruct* font_struct, c-string string, int count ) ;
 
 ! 8.6 - Drawing Text
 
@@ -444,7 +444,7 @@ X-FUNCTION: Status XDrawString (
         GC gc,
         int x,
         int y,
-        char* string,
+        c-string string,
         int length ) ;
 
 ! 8.7 - Transferring Images between Client and Server
@@ -464,7 +464,7 @@ STRUCT: XImage
 { height int }
 { xoffset int }
 { format int }
-{ data char* }
+{ data c-string }
 { byte_order int }
 { bitmap_unit int }
 { bitmap_bit_order int }
@@ -1116,7 +1116,7 @@ X-FUNCTION: Status XWarpPointer ( Display* display, Window src_w, Window dest_w,
 
 ! 14.1 Client to Window Manager Communication
 
-X-FUNCTION: Status XFetchName ( Display* display, Window w, char** window_name_return ) ;
+X-FUNCTION: Status XFetchName ( Display* display, Window w, c-string* window_name_return ) ;
 X-FUNCTION: Status XGetTransientForHint ( Display* display, Window w, Window* prop_window_return ) ;
 
 ! 14.1.1.  Manipulating Top-Level Windows
@@ -1220,7 +1220,7 @@ STRUCT: XVisualInfo
 X-FUNCTION: Pixmap XCreateBitmapFromData (
     Display* display,
     Drawable d,
-    char* data,
+    c-string data,
     uint width,
     uint height ) ;
 
@@ -1231,10 +1231,10 @@ X-FUNCTION: Pixmap XCreateBitmapFromData (
 X-FUNCTION: Status XSetStandardProperties (
         Display* display,
         Window w,
-        char* window_name,
-        char* icon_name,
+        c-string window_name,
+        c-string icon_name,
         Pixmap icon_pixmap,
-        char** argv,
+        c-string* argv,
         int argc,
         XSizeHints* hints ) ;
 
@@ -1316,7 +1316,7 @@ CONSTANT: XA_LAST_PREDEFINED 68
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 X-FUNCTION: void XFree ( void* data ) ;
-X-FUNCTION: int XStoreName ( Display* display, Window w, char* window_name ) ;
+X-FUNCTION: int XStoreName ( Display* display, Window w, c-string window_name ) ;
 X-FUNCTION: void XSetWMNormalHints ( Display* display, Window w, XSizeHints* hints ) ;
 X-FUNCTION: int XBell ( Display* display, int percent ) ;
 
@@ -1384,11 +1384,11 @@ CONSTANT: XLookupBoth      4
 
 X-FUNCTION: Bool XFilterEvent ( XEvent* event, Window w ) ;
 
-X-FUNCTION: XIM XOpenIM ( Display* dpy, void* rdb, char* res_name, char* res_class ) ;
+X-FUNCTION: XIM XOpenIM ( Display* dpy, void* rdb, c-string res_name, c-string res_class ) ;
 
 X-FUNCTION: Status XCloseIM ( XIM im ) ;
 
-X-FUNCTION: XIC XCreateIC ( XIM im, char* key1, Window value1, char* key2, Window value2, char* key3, int value3, char* key4, char* value4, char* key5, char* value5, int key6 ) ;
+X-FUNCTION: XIC XCreateIC ( XIM im, c-string key1, Window value1, c-string key2, Window value2, c-string key3, int value3, c-string key4, c-string value4, c-string key5, c-string value5, int key6 ) ;
 
 X-FUNCTION: void XDestroyIC ( XIC ic ) ;
 
@@ -1398,7 +1398,7 @@ X-FUNCTION: void XUnsetICFocus ( XIC ic ) ;
 
 X-FUNCTION: int XwcLookupString ( XIC ic, XKeyPressedEvent* event, ulong* buffer_return, int bytes_buffer, KeySym* keysym_return, Status* status_return ) ;
 
-X-FUNCTION: int Xutf8LookupString ( XIC ic, XKeyPressedEvent* event, char* buffer_return, int bytes_buffer, KeySym* keysym_return, Status* status_return ) ;
+X-FUNCTION: int Xutf8LookupString ( XIC ic, XKeyPressedEvent* event, c-string buffer_return, int bytes_buffer, KeySym* keysym_return, Status* status_return ) ;
 
 ! !!! category of setlocale
 CONSTANT: LC_ALL      0
@@ -1408,8 +1408,8 @@ CONSTANT: LC_MONETARY 3
 CONSTANT: LC_NUMERIC  4
 CONSTANT: LC_TIME     5
 
-X-FUNCTION: char* setlocale ( int category, char* name ) ;
+X-FUNCTION: c-string setlocale ( int category, c-string name ) ;
 
 X-FUNCTION: Bool XSupportsLocale ( ) ;
 
-X-FUNCTION: char* XSetLocaleModifiers ( char* modifier_list ) ;
+X-FUNCTION: c-string XSetLocaleModifiers ( c-string modifier_list ) ;
diff --git a/extra/chipmunk/chipmunk.factor b/extra/chipmunk/chipmunk.factor
index a7cd5e0fd2..b24232147c 100644
--- a/extra/chipmunk/chipmunk.factor
+++ b/extra/chipmunk/chipmunk.factor
@@ -41,7 +41,7 @@ FUNCTION: cpVect cpvslerp ( cpVect v1, cpVect v2, cpFloat t ) ;
 FUNCTION: cpVect cpvslerpconst ( cpVect v1, cpVect v2, cpFloat a ) ;
 FUNCTION: cpVect cpvforangle ( cpFloat a ) ;
 FUNCTION: cpFloat cpvtoangle ( cpVect v ) ;
-FUNCTION: char* cpvstr ( cpVect v ) ;
+FUNCTION: c-string cpvstr ( cpVect v ) ;
 
 TYPED: cpvadd ( v1: cpVect v2: cpVect -- v3: cpVect )
     [ [ x>> ] bi@ + ]
diff --git a/extra/curses/ffi/ffi.factor b/extra/curses/ffi/ffi.factor
index a9edc2e92b..222885b72c 100644
--- a/extra/curses/ffi/ffi.factor
+++ b/extra/curses/ffi/ffi.factor
@@ -58,7 +58,7 @@ STRUCT: c-window
     { _use_keypad bool    }
     { _delay int     }
 
-    { _line char* }
+    { _line c-string }
     { _regtop NCURSES_SIZE_T }
     { _regbottom NCURSES_SIZE_T }
 
@@ -79,7 +79,7 @@ C-GLOBAL: void* stdscr
 FUNCTION: WINDOW* initscr ( ) ;
 FUNCTION: int endwin ( ) ;
 FUNCTION: bool isendwin ( ) ;
-FUNCTION: SCREEN* newterm ( char* type, FILE* outfd, FILE* infd ) ;
+FUNCTION: SCREEN* newterm ( c-string type, FILE* outfd, FILE* infd ) ;
 FUNCTION: SCREEN* set_term ( SCREEN* new ) ;
 FUNCTION: void delscreen ( SCREEN* sp ) ;
 
@@ -157,21 +157,21 @@ FUNCTION: int mvwgetch ( WINDOW* win, int y, int x ) ;
 FUNCTION: int ungetch ( int ch ) ;
 FUNCTION: int has_key ( int ch ) ;
 
-FUNCTION: int getstr ( char* str ) ;
-FUNCTION: int getnstr ( char* str, int n ) ;
-FUNCTION: int wgetstr ( WINDOW* win, char* str ) ;
-FUNCTION: int wgetnstr ( WINDOW* win, char* str, int n ) ;
-FUNCTION: int mvgetstr ( int y, int x, char* str ) ;
-FUNCTION: int mvwgetstr ( WINDOW* win, int y, int x, char* str ) ;
-FUNCTION: int mvgetnstr ( int y, int x, char* str, int n ) ;
-FUNCTION: int mvwgetnstr ( WINDOW* win, int y, int x, char* str, int n ) ;
+FUNCTION: int getstr ( c-string str ) ;
+FUNCTION: int getnstr ( c-string str, int n ) ;
+FUNCTION: int wgetstr ( WINDOW* win, c-string str ) ;
+FUNCTION: int wgetnstr ( WINDOW* win, c-string str, int n ) ;
+FUNCTION: int mvgetstr ( int y, int x, c-string str ) ;
+FUNCTION: int mvwgetstr ( WINDOW* win, int y, int x, c-string str ) ;
+FUNCTION: int mvgetnstr ( int y, int x, c-string str, int n ) ;
+FUNCTION: int mvwgetnstr ( WINDOW* win, int y, int x, c-string str, int n ) ;
 
-FUNCTION: int printw ( char* fmt, int lol ) ;
-FUNCTION: int wprintw ( WINDOW* win, char* fmt, int lol ) ;
-FUNCTION: int mvprintw ( int y, int x, char* fmt, int lol ) ;
-FUNCTION: int mvwprintw ( WINDOW* win, int y, int x, char* fmt, int lol ) ;
-FUNCTION: int vwprintw ( WINDOW* win, char* fmt, va_list varglist ) ;
-FUNCTION: int vw_printw ( WINDOW* win, char* fmt, va_list varglist ) ;
+FUNCTION: int printw ( c-string fmt, int lol ) ;
+FUNCTION: int wprintw ( WINDOW* win, c-string fmt, int lol ) ;
+FUNCTION: int mvprintw ( int y, int x, c-string fmt, int lol ) ;
+FUNCTION: int mvwprintw ( WINDOW* win, int y, int x, c-string fmt, int lol ) ;
+FUNCTION: int vwprintw ( WINDOW* win, c-string fmt, va_list varglist ) ;
+FUNCTION: int vw_printw ( WINDOW* win, c-string fmt, va_list varglist ) ;
 
 FUNCTION: int move ( int y, int x ) ;
 FUNCTION: int wmove ( WINDOW* win, int y, int x ) ;
@@ -221,11 +221,11 @@ FUNCTION: int winsdelln ( WINDOW* win, int n ) ;
 FUNCTION: int insertln ( ) ;
 FUNCTION: int winsertln ( WINDOW* win ) ;
 
-FUNCTION: int addstr ( char* str ) ;
-FUNCTION: int addnstr ( char* str, int n ) ;
-FUNCTION: int waddstr ( WINDOW* win, char* str ) ;
-FUNCTION: int waddnstr ( WINDOW* win, char* str, int n ) ;
-FUNCTION: int mvaddstr ( int y, int x, char* str ) ;
-FUNCTION: int mvaddnstr ( int y, int x, char* str, int n ) ;
-FUNCTION: int mvwaddstr ( WINDOW* win, int y, int x, char* str ) ;
-FUNCTION: int mvwaddnstr ( WINDOW* win, int y, int x, char* str, int n ) ;
+FUNCTION: int addstr ( c-string str ) ;
+FUNCTION: int addnstr ( c-string str, int n ) ;
+FUNCTION: int waddstr ( WINDOW* win, c-string str ) ;
+FUNCTION: int waddnstr ( WINDOW* win, c-string str, int n ) ;
+FUNCTION: int mvaddstr ( int y, int x, c-string str ) ;
+FUNCTION: int mvaddnstr ( int y, int x, c-string str, int n ) ;
+FUNCTION: int mvwaddstr ( WINDOW* win, int y, int x, c-string str ) ;
+FUNCTION: int mvwaddnstr ( WINDOW* win, int y, int x, c-string str, int n ) ;
diff --git a/extra/freetype/freetype.factor b/extra/freetype/freetype.factor
index 955672d03b..d131d2eb35 100644
--- a/extra/freetype/freetype.factor
+++ b/extra/freetype/freetype.factor
@@ -83,7 +83,7 @@ STRUCT: glyph
     { n-points short }
 
     { points void* }
-    { tags char* }
+    { tags c-string }
     { contours short* }
 
     { outline-flags int }
diff --git a/extra/libusb/libusb.factor b/extra/libusb/libusb.factor
index d521015d6f..38bf49ed5b 100644
--- a/extra/libusb/libusb.factor
+++ b/extra/libusb/libusb.factor
@@ -128,7 +128,7 @@ STRUCT: libusb_endpoint_descriptor
     { bInterval         uint8_t  }
     { bRefresh          uint8_t  }
     { bSynchAddress     uint8_t  }
-    { extra             uchar*   }
+    { extra             c-string   }
     { extra_length      int      } ;
 
 STRUCT: libusb_interface_descriptor
@@ -142,7 +142,7 @@ STRUCT: libusb_interface_descriptor
     { bInterfaceProtocol  uint8_t                     }
     { iInterface          uint8_t                     }
     { endpoint            libusb_endpoint_descriptor* }
-    { extra               uchar*                      }
+    { extra               c-string                      }
     { extra_length        int                         } ;
 
 STRUCT: libusb_interface
@@ -159,7 +159,7 @@ STRUCT: libusb_config_descriptor
     { bmAttributes         uint8_t           }
     { MaxPower             uint8_t           }
     { interface            libusb_interface* }
-    { extra                uchar*            }
+    { extra                c-string            }
     { extra_length         int               } ;
 
 STRUCT: libusb_control_setup
@@ -227,7 +227,7 @@ STRUCT: libusb_transfer
     { actual_length   int                             }
     { callback        libusb_transfer_cb_fn           }
     { user_data       void*                           }
-    { buffer          uchar*                          }
+    { buffer          c-string                          }
     { num_iso_packets int                             }
     { iso_packet_desc libusb_iso_packet_descriptor[0] } ;
 
@@ -370,14 +370,14 @@ FUNCTION: void libusb_free_transfer ( libusb_transfer* transfer ) ;
 
 FUNCTION: int libusb_control_transfer ( libusb_device_handle* dev_handle,
     uint8_t request_type, uint8_t request, uint16_t value, uint16_t index,
-    uchar* data, uint16_t length, uint timeout ) ;
+    c-string data, uint16_t length, uint timeout ) ;
 
 FUNCTION: int libusb_bulk_transfer ( libusb_device_handle* dev_handle,
-    uchar endpoint, uchar* data, int length,
+    uchar endpoint, c-string data, int length,
     int* actual_length, uint timeout ) ;
 
 FUNCTION: int libusb_interrupt_transfer ( libusb_device_handle* dev_handle,
-    uchar endpoint, uchar* data, int length,
+    uchar endpoint, c-string data, int length,
     int* actual_length, int timeout ) ;
 
 :: libusb_get_descriptor ( dev desc_type desc_index data length -- int )
@@ -392,7 +392,7 @@ FUNCTION: int libusb_interrupt_transfer ( libusb_device_handle* dev_handle,
 
 FUNCTION: int libusb_get_string_descriptor_ascii ( libusb_device_handle* dev,
                                                    uint8_t               index,
-                                                   uchar*                data,
+                                                   c-string                data,
                                                    int                   length ) ;
 
 FUNCTION: int libusb_try_lock_events ( libusb_context* ctx ) ;
diff --git a/extra/llvm/core/core.factor b/extra/llvm/core/core.factor
index 0d1b22e288..f0a3cafe33 100644
--- a/extra/llvm/core/core.factor
+++ b/extra/llvm/core/core.factor
@@ -137,11 +137,11 @@ TYPEDEF: void* LLVMMemoryBufferRef
 
 ! Functions
 
-FUNCTION: void LLVMDisposeMessage ( char* Message ) ;
+FUNCTION: void LLVMDisposeMessage ( c-string Message ) ;
 
-FUNCTION: LLVMModuleRef LLVMModuleCreateWithName ( char* ModuleID ) ;
+FUNCTION: LLVMModuleRef LLVMModuleCreateWithName ( c-string ModuleID ) ;
 
-FUNCTION: int LLVMAddTypeName ( LLVMModuleRef M, char* Name, LLVMTypeRef Ty ) ;
+FUNCTION: int LLVMAddTypeName ( LLVMModuleRef M, c-string Name, LLVMTypeRef Ty ) ;
 
 FUNCTION: void LLVMDisposeModule ( LLVMModuleRef M ) ;
 
@@ -230,7 +230,7 @@ FUNCTION: unsigned LLVMCountParams ( LLVMValueRef Fn ) ;
 FUNCTION: void LLVMGetParams ( LLVMValueRef Fn, LLVMValueRef* Params ) ;
 
 FUNCTION: LLVMValueRef
-LLVMAddFunction ( LLVMModuleRef M, char* Name, LLVMTypeRef FunctionTy ) ;
+LLVMAddFunction ( LLVMModuleRef M, c-string Name, LLVMTypeRef FunctionTy ) ;
 
 FUNCTION: LLVMValueRef LLVMGetFirstFunction ( LLVMModuleRef M ) ;
 
@@ -241,15 +241,15 @@ FUNCTION: unsigned LLVMGetFunctionCallConv ( LLVMValueRef Fn ) ;
 FUNCTION: void LLVMSetFunctionCallConv ( LLVMValueRef Fn, unsigned CC ) ;
 
 FUNCTION: LLVMBasicBlockRef
-LLVMAppendBasicBlock ( LLVMValueRef Fn, char* Name ) ;
+LLVMAppendBasicBlock ( LLVMValueRef Fn, c-string Name ) ;
 
 FUNCTION: LLVMValueRef LLVMGetBasicBlockParent ( LLVMBasicBlockRef BB ) ;
 
 ! Values
 
 FUNCTION: LLVMTypeRef LLVMTypeOf ( LLVMValueRef Val ) ;
-FUNCTION: char* LLVMGetValueName ( LLVMValueRef Val ) ;
-FUNCTION: void LLVMSetValueName ( LLVMValueRef Val, char* Name ) ;
+FUNCTION: c-string LLVMGetValueName ( LLVMValueRef Val ) ;
+FUNCTION: void LLVMSetValueName ( LLVMValueRef Val, c-string Name ) ;
 FUNCTION: void LLVMDumpValue ( LLVMValueRef Val ) ;
 
 ! Instruction Builders
@@ -284,7 +284,7 @@ FUNCTION: LLVMValueRef LLVMBuildSwitch
 ( LLVMBuilderRef Builder, LLVMValueRef V, LLVMBasicBlockRef Else, unsigned NumCases ) ;
 FUNCTION: LLVMValueRef LLVMBuildInvoke
 ( LLVMBuilderRef Builder, LLVMValueRef Fn, LLVMValueRef* Args, unsigned NumArgs,
-  LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, char* Name ) ;
+  LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildUnwind
 ( LLVMBuilderRef Builder ) ;
 FUNCTION: LLVMValueRef LLVMBuildUnreachable
@@ -298,126 +298,126 @@ FUNCTION: void LLVMAddCase
 ! IB Arithmetic
 
 FUNCTION: LLVMValueRef LLVMBuildAdd
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildSub
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildMul
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildUDiv
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildSDiv
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildFDiv
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildURem
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildSRem
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildFRem
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildShl
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildLShr
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildAShr
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildAnd
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildOr
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildXor
-( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildNeg
-( LLVMBuilderRef Builder, LLVMValueRef V, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef V, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildNot
-( LLVMBuilderRef Builder, LLVMValueRef V, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef V, c-string Name ) ;
 
 ! IB Memory
 
 FUNCTION: LLVMValueRef LLVMBuildMalloc
-( LLVMBuilderRef Builder, LLVMTypeRef Ty, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMTypeRef Ty, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildArrayMalloc
-( LLVMBuilderRef Builder, LLVMTypeRef Ty, LLVMValueRef Val, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMTypeRef Ty, LLVMValueRef Val, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildAlloca
-( LLVMBuilderRef Builder, LLVMTypeRef Ty, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMTypeRef Ty, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildArrayAlloca
-( LLVMBuilderRef Builder, LLVMTypeRef Ty, LLVMValueRef Val, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMTypeRef Ty, LLVMValueRef Val, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildFree
 ( LLVMBuilderRef Builder, LLVMValueRef PointerVal ) ;
 FUNCTION: LLVMValueRef LLVMBuildLoad
-( LLVMBuilderRef Builder, LLVMValueRef PointerVal, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef PointerVal, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildStore
 ( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMValueRef Ptr ) ;
 FUNCTION: LLVMValueRef LLVMBuildGEP
 ( LLVMBuilderRef B, LLVMValueRef Pointer, LLVMValueRef* Indices,
-  unsigned NumIndices, char* Name ) ;
+  unsigned NumIndices, c-string Name ) ;
 
 ! IB Casts
 
 FUNCTION: LLVMValueRef LLVMBuildTrunc
-( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildZExt
-( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildSExt
-( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildFPToUI
-( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildFPToSI
-( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildUIToFP
-( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildSIToFP
-( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildFPTrunc
-( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildFPExt
-( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildPtrToInt
-( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildIntToPtr
-( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildBitCast
-( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, c-string Name ) ;
 
 ! IB Comparisons
 
 FUNCTION: LLVMValueRef LLVMBuildICmp
-( LLVMBuilderRef Builder, LLVMIntPredicate Op, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMIntPredicate Op, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildFCmp
-( LLVMBuilderRef Builder, LLVMRealPredicate Op, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMRealPredicate Op, LLVMValueRef LHS, LLVMValueRef RHS, c-string Name ) ;
 
 ! IB Misc Instructions
 
 FUNCTION: LLVMValueRef LLVMBuildPhi
-( LLVMBuilderRef Builder, LLVMTypeRef Ty, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMTypeRef Ty, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildCall
-( LLVMBuilderRef Builder, LLVMValueRef Fn, LLVMValueRef* Args, unsigned NumArgs, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef Fn, LLVMValueRef* Args, unsigned NumArgs, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildSelect
-( LLVMBuilderRef Builder, LLVMValueRef If, LLVMValueRef Then, LLVMValueRef Else, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef If, LLVMValueRef Then, LLVMValueRef Else, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildVAArg
-( LLVMBuilderRef Builder, LLVMValueRef List, LLVMTypeRef Ty, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef List, LLVMTypeRef Ty, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildExtractElement
-( LLVMBuilderRef Builder, LLVMValueRef VecVal, LLVMValueRef Index, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef VecVal, LLVMValueRef Index, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildInsertElement
-( LLVMBuilderRef Builder, LLVMValueRef VecVal, LLVMValueRef EltVal, LLVMValueRef Index, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef VecVal, LLVMValueRef EltVal, LLVMValueRef Index, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildShuffleVector
-( LLVMBuilderRef Builder, LLVMValueRef V1, LLVMValueRef V2, LLVMValueRef Mask, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef V1, LLVMValueRef V2, LLVMValueRef Mask, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildExtractValue
-( LLVMBuilderRef Builder, LLVMValueRef AggVal, unsigned Index, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef AggVal, unsigned Index, c-string Name ) ;
 FUNCTION: LLVMValueRef LLVMBuildInsertValue
-( LLVMBuilderRef Builder, LLVMValueRef AggVal, LLVMValueRef EltVal, unsigned Index, char* Name ) ;
+( LLVMBuilderRef Builder, LLVMValueRef AggVal, LLVMValueRef EltVal, unsigned Index, c-string Name ) ;
 
 ! Memory Buffers/Bit Reader
 
 FUNCTION: int LLVMCreateMemoryBufferWithContentsOfFile
-( char* Path, LLVMMemoryBufferRef* OutMemBuf, char** OutMessage ) ;
+( c-string Path, LLVMMemoryBufferRef* OutMemBuf, c-string* OutMessage ) ;
 
 FUNCTION: void LLVMDisposeMemoryBuffer ( LLVMMemoryBufferRef MemBuf ) ;
 
 LIBRARY: LLVMBitReader
 
 FUNCTION: int LLVMParseBitcode
-( LLVMMemoryBufferRef MemBuf, LLVMModuleRef* OutModule, char** OutMessage ) ;
+( LLVMMemoryBufferRef MemBuf, LLVMModuleRef* OutModule, c-string* OutMessage ) ;
  
 FUNCTION: int LLVMGetBitcodeModuleProvider
-( LLVMMemoryBufferRef MemBuf, LLVMModuleProviderRef* OutMP, char** OutMessage ) ;
+( LLVMMemoryBufferRef MemBuf, LLVMModuleProviderRef* OutMP, c-string* OutMessage ) ;
diff --git a/extra/llvm/engine/engine.factor b/extra/llvm/engine/engine.factor
index d259c740e6..95e425c425 100644
--- a/extra/llvm/engine/engine.factor
+++ b/extra/llvm/engine/engine.factor
@@ -34,10 +34,10 @@ FUNCTION: ulonglong LLVMGenericValueToInt
 ( LLVMGenericValueRef GenVal, int IsSigned ) ;
 
 FUNCTION: int LLVMCreateExecutionEngine
-( LLVMExecutionEngineRef *OutEE, LLVMModuleProviderRef MP, char** OutError ) ;
+( LLVMExecutionEngineRef *OutEE, LLVMModuleProviderRef MP, c-string* OutError ) ;
 
 FUNCTION: int LLVMCreateJITCompiler
-( LLVMExecutionEngineRef* OutJIT, LLVMModuleProviderRef MP, unsigned OptLevel, char** OutError ) ;
+( LLVMExecutionEngineRef* OutJIT, LLVMModuleProviderRef MP, unsigned OptLevel, c-string* OutError ) ;
 
 FUNCTION: void LLVMDisposeExecutionEngine ( LLVMExecutionEngineRef EE ) ;
 
@@ -46,10 +46,10 @@ FUNCTION: void LLVMFreeMachineCodeForFunction ( LLVMExecutionEngineRef EE, LLVMV
 FUNCTION: void LLVMAddModuleProvider ( LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP ) ;
 
 FUNCTION: int LLVMRemoveModuleProvider
-( LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP, LLVMModuleRef* OutMod, char** OutError ) ;
+( LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP, LLVMModuleRef* OutMod, c-string* OutError ) ;
 
 FUNCTION: int LLVMFindFunction
-( LLVMExecutionEngineRef EE, char* Name, LLVMValueRef* OutFn ) ;
+( LLVMExecutionEngineRef EE, c-string Name, LLVMValueRef* OutFn ) ;
 
 FUNCTION: void* LLVMGetPointerToGlobal ( LLVMExecutionEngineRef EE, LLVMValueRef Global ) ;
 
diff --git a/extra/llvm/types/types.factor b/extra/llvm/types/types.factor
index ddb54ecb27..e93cf7a44b 100644
--- a/extra/llvm/types/types.factor
+++ b/extra/llvm/types/types.factor
@@ -99,7 +99,7 @@ TUPLE: pointer < enclosing type ;
 M: pointer (>tref)* type>> (>tref) 0 LLVMPointerType ;
 M: pointer clean* type>> clean ;
 M: pointer (tref>)* swap LLVMGetElementType (tref>) >>type ;
-M: pointer c-type type>> 8 <integer> = "char*" "void*" ? ;
+M: pointer c-type type>> 8 <integer> = "c-string" "void*" ? ;
 
 TUPLE: vector < enclosing size type ;
 : <vector> ( s t -- o )
diff --git a/extra/llvm/wrappers/wrappers.factor b/extra/llvm/wrappers/wrappers.factor
index a1d757e7e9..05aafce973 100644
--- a/extra/llvm/wrappers/wrappers.factor
+++ b/extra/llvm/wrappers/wrappers.factor
@@ -6,7 +6,7 @@ llvm.core llvm.engine ;
 
 IN: llvm.wrappers
 
-: llvm-throw ( char* -- )
+: llvm-throw ( c-string -- )
     [ utf8 alien>string ] [ LLVMDisposeMessage ] bi throw ;
 
 : <dispose> ( alien class -- disposable ) new swap >>value ;
diff --git a/extra/native-thread-test/native-thread-test.factor b/extra/native-thread-test/native-thread-test.factor
index 4d0df1f454..73b86f53a0 100644
--- a/extra/native-thread-test/native-thread-test.factor
+++ b/extra/native-thread-test/native-thread-test.factor
@@ -5,7 +5,7 @@ io.encodings.utf8 io.files kernel sequences system threads
 unix.utilities ;
 IN: native-thread-test
 
-FUNCTION: void* start_standalone_factor_in_new_thread ( int argc, char** argv ) ;
+FUNCTION: void* start_standalone_factor_in_new_thread ( int argc, c-string* argv ) ;
 
 : start-vm-in-os-thread ( args -- threadhandle )
     vm prefix
diff --git a/extra/ogg/ogg.factor b/extra/ogg/ogg.factor
index d7abece8bc..ed25740ff6 100644
--- a/extra/ogg/ogg.factor
+++ b/extra/ogg/ogg.factor
@@ -28,18 +28,18 @@ LIBRARY: ogg
 STRUCT: oggpack-buffer
     { endbyte long }
     { endbit int   }
-    { buffer uchar* }
-    { ptr uchar* }
+    { buffer c-string }
+    { ptr c-string }
     { storage long } ;
 
 STRUCT: ogg-page
-    {  header uchar* }
+    {  header c-string }
     {  header_len long }
-    {  body uchar* }
+    {  body c-string }
     {  body_len long } ;
 
 STRUCT: ogg-stream-state
-    {  body_data uchar* }
+    {  body_data c-string }
     {  body_storage long }
     {  body_fill long }
     {  body_returned long }
@@ -59,7 +59,7 @@ STRUCT: ogg-stream-state
     {  granulepos longlong } ;
 
 STRUCT: ogg-packet
-    {  packet uchar* }
+    {  packet c-string }
     {  bytes long }
     {  b_o_s long }
     {  e_o_s long }
@@ -67,7 +67,7 @@ STRUCT: ogg-packet
     {  packetno longlong } ;
 
 STRUCT: ogg-sync-state
-    { data uchar* }
+    { data c-string }
     { storage int }
     { fill int }  
     { returned int }
@@ -81,7 +81,7 @@ FUNCTION: void  oggpack_writealign ( oggpack-buffer* b) ;
 FUNCTION: void  oggpack_writecopy ( oggpack-buffer* b, void* source, long bits ) ;
 FUNCTION: void  oggpack_reset ( oggpack-buffer* b ) ;
 FUNCTION: void  oggpack_writeclear ( oggpack-buffer* b ) ;
-FUNCTION: void  oggpack_readinit ( oggpack-buffer* b, uchar* buf, int bytes ) ;
+FUNCTION: void  oggpack_readinit ( oggpack-buffer* b, c-string buf, int bytes ) ;
 FUNCTION: void  oggpack_write ( oggpack-buffer* b, ulong value, int bits ) ;
 FUNCTION: long  oggpack_look ( oggpack-buffer* b, int bits ) ;
 FUNCTION: long  oggpack_look1 ( oggpack-buffer* b ) ;
@@ -91,14 +91,14 @@ FUNCTION: long  oggpack_read ( oggpack-buffer* b, int bits ) ;
 FUNCTION: long  oggpack_read1 ( oggpack-buffer* b ) ;
 FUNCTION: long  oggpack_bytes ( oggpack-buffer* b ) ;
 FUNCTION: long  oggpack_bits ( oggpack-buffer* b ) ;
-FUNCTION: uchar* oggpack_get_buffer ( oggpack-buffer* b ) ;
+FUNCTION: c-string oggpack_get_buffer ( oggpack-buffer* b ) ;
 FUNCTION: void  oggpackB_writeinit ( oggpack-buffer* b ) ;
 FUNCTION: void  oggpackB_writetrunc ( oggpack-buffer* b, long bits ) ;
 FUNCTION: void  oggpackB_writealign ( oggpack-buffer* b ) ;
 FUNCTION: void  oggpackB_writecopy ( oggpack-buffer* b, void* source, long bits ) ;
 FUNCTION: void  oggpackB_reset ( oggpack-buffer* b ) ;
 FUNCTION: void  oggpackB_writeclear ( oggpack-buffer* b ) ;
-FUNCTION: void  oggpackB_readinit ( oggpack-buffer* b, uchar* buf, int bytes ) ;
+FUNCTION: void  oggpackB_readinit ( oggpack-buffer* b, c-string buf, int bytes ) ;
 FUNCTION: void  oggpackB_write ( oggpack-buffer* b, ulong value, int bits ) ;
 FUNCTION: long  oggpackB_look ( oggpack-buffer* b, int bits ) ;
 FUNCTION: long  oggpackB_look1 ( oggpack-buffer* b ) ;
@@ -108,7 +108,7 @@ FUNCTION: long  oggpackB_read ( oggpack-buffer* b, int bits ) ;
 FUNCTION: long  oggpackB_read1 ( oggpack-buffer* b ) ;
 FUNCTION: long  oggpackB_bytes ( oggpack-buffer* b ) ;
 FUNCTION: long  oggpackB_bits ( oggpack-buffer* b ) ;
-FUNCTION: uchar* oggpackB_get_buffer ( oggpack-buffer* b ) ;
+FUNCTION: c-string oggpackB_get_buffer ( oggpack-buffer* b ) ;
 FUNCTION: int      ogg_stream_packetin ( ogg-stream-state* os, ogg-packet* op ) ;
 FUNCTION: int      ogg_stream_pageout ( ogg-stream-state* os, ogg-page* og ) ;
 FUNCTION: int      ogg_stream_flush ( ogg-stream-state* os, ogg-page* og ) ;
diff --git a/extra/ogg/theora/theora.factor b/extra/ogg/theora/theora.factor
index c9141fb9e3..3e28129252 100644
--- a/extra/ogg/theora/theora.factor
+++ b/extra/ogg/theora/theora.factor
@@ -53,7 +53,7 @@ STRUCT: th-img-plane
     { width int }
     { height int }
     { stride int }
-    { data uchar* }
+    { data c-string }
 ;
 
 TYPEDEF: th-img-plane[3] th-ycbcr-buffer
@@ -80,10 +80,10 @@ STRUCT: th-info
 ;
 
 STRUCT: th-comment
-    { user-comments char** }
+    { user-comments c-string* }
     { comment-lengths int* }
     { comments int }
-    { vendor char* }
+    { vendor c-string }
 ;
 
 TYPEDEF: uchar[64] th-quant-base
@@ -110,7 +110,7 @@ STRUCT: th-huff-code
 ;
 
 LIBRARY: theoradec
-FUNCTION: char* th_version_string ( ) ;
+FUNCTION: c-string th_version_string ( ) ;
 FUNCTION: uint th_version_number ( ) ;
 FUNCTION: longlong th_granule_frame ( void* encdec, longlong granpos) ;
 FUNCTION: int th_packet_isheader ( ogg-packet* op ) ;
@@ -118,10 +118,10 @@ FUNCTION: int th_packet_iskeyframe ( ogg-packet* op ) ;
 FUNCTION: void th_info_init ( th-info* info ) ;
 FUNCTION: void th_info_clear ( th-info* info ) ;
 FUNCTION: void th_comment_init ( th-comment* tc ) ;
-FUNCTION: void th_comment_add ( th-comment* tc, char* comment ) ;
-FUNCTION: void th_comment_add_tag ( th-comment* tc, char* tag, char* value ) ;
-FUNCTION: char* th_comment_query ( th-comment* tc, char* tag, int count ) ;
-FUNCTION: int   th_comment_query_count ( th-comment* tc, char* tag ) ;
+FUNCTION: void th_comment_add ( th-comment* tc, c-string comment ) ;
+FUNCTION: void th_comment_add_tag ( th-comment* tc, c-string tag, c-string value ) ;
+FUNCTION: c-string th_comment_query ( th-comment* tc, c-string tag, int count ) ;
+FUNCTION: int   th_comment_query_count ( th-comment* tc, c-string tag ) ;
 FUNCTION: void  th_comment_clear ( th-comment* tc ) ;
 
 CONSTANT: TH-ENCCTL-SET-HUFFMAN-CODES 0
diff --git a/extra/ogg/vorbis/vorbis.factor b/extra/ogg/vorbis/vorbis.factor
index d5905dac9e..ad43750e27 100644
--- a/extra/ogg/vorbis/vorbis.factor
+++ b/extra/ogg/vorbis/vorbis.factor
@@ -90,20 +90,20 @@ STRUCT: vorbis-block
     ;
 
 STRUCT: vorbis-comment
-    { usercomments char** }
+    { usercomments c-string* }
     { comment_lengths int* }
     { comments int }
-    { vendor char* }
+    { vendor c-string }
     ;
 
 FUNCTION: void     vorbis_info_init ( vorbis-info* vi ) ;
 FUNCTION: void     vorbis_info_clear ( vorbis-info* vi ) ;
 FUNCTION: int      vorbis_info_blocksize ( vorbis-info* vi, int zo ) ;
 FUNCTION: void     vorbis_comment_init ( vorbis-comment* vc ) ;
-FUNCTION: void     vorbis_comment_add ( vorbis-comment* vc, char* comment ) ;
-FUNCTION: void     vorbis_comment_add_tag ( vorbis-comment* vc, char* tag, char* contents ) ;
-FUNCTION: char*    vorbis_comment_query ( vorbis-comment* vc, char* tag, int count ) ;
-FUNCTION: int      vorbis_comment_query_count ( vorbis-comment* vc, char* tag ) ;
+FUNCTION: void     vorbis_comment_add ( vorbis-comment* vc, c-string comment ) ;
+FUNCTION: void     vorbis_comment_add_tag ( vorbis-comment* vc, c-string tag, c-string contents ) ;
+FUNCTION: c-string    vorbis_comment_query ( vorbis-comment* vc, c-string tag, int count ) ;
+FUNCTION: int      vorbis_comment_query_count ( vorbis-comment* vc, c-string tag ) ;
 FUNCTION: void     vorbis_comment_clear ( vorbis-comment* vc ) ;
 FUNCTION: int      vorbis_block_init ( vorbis-dsp-state* v, vorbis-block* vb ) ;
 FUNCTION: int      vorbis_block_clear ( vorbis-block* vb ) ;
diff --git a/extra/openal/alut/alut.factor b/extra/openal/alut/alut.factor
index 9e37d9886c..0bf8511647 100755
--- a/extra/openal/alut/alut.factor
+++ b/extra/openal/alut/alut.factor
@@ -49,20 +49,20 @@ CONSTANT: ALUT_WAVEFORM_IMPULSE HEX: 104
 CONSTANT: ALUT_LOADER_BUFFER HEX: 300
 CONSTANT: ALUT_LOADER_MEMORY HEX: 301
 
-FUNCTION: ALboolean alutInit ( int* argcp, char** argv ) ;
-FUNCTION: ALboolean alutInitWithoutContext ( int* argcp, char** argv ) ;
+FUNCTION: ALboolean alutInit ( int* argcp, c-string* argv ) ;
+FUNCTION: ALboolean alutInitWithoutContext ( int* argcp, c-string* argv ) ;
 FUNCTION: ALboolean alutExit ( ) ;
 FUNCTION: ALenum alutGetError ( ) ;
-FUNCTION: char* alutGetErrorString ( ALenum error ) ;
-FUNCTION: ALuint alutCreateBufferFromFile ( char* fileName ) ;
+FUNCTION: c-string alutGetErrorString ( ALenum error ) ;
+FUNCTION: ALuint alutCreateBufferFromFile ( c-string fileName ) ;
 FUNCTION: ALuint alutCreateBufferFromFileImage ( void* data, ALsizei length ) ;
 FUNCTION: ALuint alutCreateBufferHelloWorld ( ) ;
 FUNCTION: ALuint alutCreateBufferWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration ) ;
-FUNCTION: void* alutLoadMemoryFromFile ( char* fileName, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
+FUNCTION: void* alutLoadMemoryFromFile ( c-string fileName, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
 FUNCTION: void* alutLoadMemoryFromFileImage ( void* data, ALsizei length, ALenum* format, ALsizei* size, ALfloat* frequency ) ;
 FUNCTION: void* alutLoadMemoryHelloWorld ( ALenum* format, ALsizei* size, ALfloat* frequency ) ;
 FUNCTION: void* alutLoadMemoryWaveform ( ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration, ALenum* format, ALsizei* size, ALfloat* freq ) ;
-FUNCTION: char* alutGetMIMETypes ( ALenum loader ) ;
+FUNCTION: c-string alutGetMIMETypes ( ALenum loader ) ;
 FUNCTION: ALint alutGetMajorVersion ( ) ;
 FUNCTION: ALint alutGetMinorVersion ( ) ;
 FUNCTION: ALboolean alutSleep ( ALfloat duration ) ;
diff --git a/extra/opengl/glu/glu.factor b/extra/opengl/glu/glu.factor
index 6409a3781b..86936fdd65 100644
--- a/extra/opengl/glu/glu.factor
+++ b/extra/opengl/glu/glu.factor
@@ -218,9 +218,9 @@ FUNCTION: void gluEndCurve ( GLUnurbs* nurb ) ;
 FUNCTION: void gluEndPolygon ( GLUtesselator* tess ) ;
 FUNCTION: void gluEndSurface ( GLUnurbs* nurb ) ;
 FUNCTION: void gluEndTrim ( GLUnurbs* nurb ) ;
-FUNCTION: char* gluErrorString ( GLenum error ) ;
+FUNCTION: c-string gluErrorString ( GLenum error ) ;
 FUNCTION: void gluGetNurbsProperty ( GLUnurbs* nurb, GLenum property, GLfloat* data ) ;
-FUNCTION: char* gluGetString ( GLenum name ) ;
+FUNCTION: c-string gluGetString ( GLenum name ) ;
 FUNCTION: void gluGetTessProperty ( GLUtesselator* tess, GLenum which, GLdouble* data ) ;
 FUNCTION: void gluLoadSamplingMatrices ( GLUnurbs* nurb, GLfloat* model, GLfloat* perspective, GLint* view ) ;
 FUNCTION: void gluLookAt ( GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ ) ;
diff --git a/extra/tokyo/alien/tcadb/tcadb.factor b/extra/tokyo/alien/tcadb/tcadb.factor
index efba5f0374..7e3a2d47c2 100644
--- a/extra/tokyo/alien/tcadb/tcadb.factor
+++ b/extra/tokyo/alien/tcadb/tcadb.factor
@@ -21,38 +21,38 @@ C-ENUM:
 
 FUNCTION: TCADB* tcadbnew ( ) ;
 FUNCTION: void tcadbdel ( TCADB* adb ) ;
-FUNCTION: bool tcadbopen ( TCADB* adb, char* name ) ;
+FUNCTION: bool tcadbopen ( TCADB* adb, c-string name ) ;
 FUNCTION: bool tcadbclose ( TCADB* adb ) ;
 FUNCTION: bool tcadbput ( TCADB* adb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcadbput2 ( TCADB* adb, char* kstr, char* vstr ) ;
+FUNCTION: bool tcadbput2 ( TCADB* adb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tcadbputkeep ( TCADB* adb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcadbputkeep2 ( TCADB* adb, char* kstr, char* vstr ) ;
+FUNCTION: bool tcadbputkeep2 ( TCADB* adb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tcadbputcat ( TCADB* adb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcadbputcat2 ( TCADB* adb, char* kstr, char* vstr ) ;
+FUNCTION: bool tcadbputcat2 ( TCADB* adb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tcadbout ( TCADB* adb, void* kbuf, int ksiz ) ;
-FUNCTION: bool tcadbout2 ( TCADB* adb, char* kstr ) ;
+FUNCTION: bool tcadbout2 ( TCADB* adb, c-string kstr ) ;
 FUNCTION: void* tcadbget ( TCADB* adb, void* kbuf, int ksiz, int* sp ) ;
-FUNCTION: char* tcadbget2 ( TCADB* adb, char* kstr ) ;
+FUNCTION: c-string tcadbget2 ( TCADB* adb, c-string kstr ) ;
 FUNCTION: int tcadbvsiz ( TCADB* adb, void* kbuf, int ksiz ) ;
-FUNCTION: int tcadbvsiz2 ( TCADB* adb, char* kstr ) ;
+FUNCTION: int tcadbvsiz2 ( TCADB* adb, c-string kstr ) ;
 FUNCTION: bool tcadbiterinit ( TCADB* adb ) ;
 FUNCTION: void* tcadbiternext ( TCADB* adb, int* sp ) ;
-FUNCTION: char* tcadbiternext2 ( TCADB* adb ) ;
+FUNCTION: c-string tcadbiternext2 ( TCADB* adb ) ;
 FUNCTION: TCLIST* tcadbfwmkeys ( TCADB* adb, void* pbuf, int psiz, int max ) ;
-FUNCTION: TCLIST* tcadbfwmkeys2 ( TCADB* adb, char* pstr, int max ) ;
+FUNCTION: TCLIST* tcadbfwmkeys2 ( TCADB* adb, c-string pstr, int max ) ;
 FUNCTION: int tcadbaddint ( TCADB* adb, void* kbuf, int ksiz, int num ) ;
 FUNCTION: double tcadbadddouble ( TCADB* adb, void* kbuf, int ksiz, double num ) ;
 FUNCTION: bool tcadbsync ( TCADB* adb ) ;
-FUNCTION: bool tcadboptimize ( TCADB* adb, char* params ) ;
+FUNCTION: bool tcadboptimize ( TCADB* adb, c-string params ) ;
 FUNCTION: bool tcadbvanish ( TCADB* adb ) ;
-FUNCTION: bool tcadbcopy ( TCADB* adb, char* path ) ;
+FUNCTION: bool tcadbcopy ( TCADB* adb, c-string path ) ;
 FUNCTION: bool tcadbtranbegin ( TCADB* adb ) ;
 FUNCTION: bool tcadbtrancommit ( TCADB* adb ) ;
 FUNCTION: bool tcadbtranabort ( TCADB* adb ) ;
-FUNCTION: char* tcadbpath ( TCADB* adb ) ;
+FUNCTION: c-string tcadbpath ( TCADB* adb ) ;
 FUNCTION: ulonglong tcadbrnum ( TCADB* adb ) ;
 FUNCTION: ulonglong tcadbsize ( TCADB* adb ) ;
-FUNCTION: TCLIST* tcadbmisc ( TCADB* adb, char* name, TCLIST* args ) ;
+FUNCTION: TCLIST* tcadbmisc ( TCADB* adb, c-string name, TCLIST* args ) ;
 
 ! -----
 
@@ -66,4 +66,4 @@ FUNCTION: void* tcadbreveal ( TCADB* adb ) ;
 FUNCTION: bool tcadbputproc ( TCADB* adb, void* kbuf, int ksiz, void* vbuf, int vsiz, TCPDPROC proc, void* op ) ;
 FUNCTION: bool tcadbforeach ( TCADB* adb, TCITER iter, void* op ) ;
 FUNCTION: bool tcadbmapbdb ( TCADB* adb, TCLIST* keys, TCBDB* bdb, ADBMAPPROC proc, void* op, longlong csiz ) ;
-FUNCTION: bool tcadbmapbdbemit ( void* map, char* kbuf, int ksiz, char* vbuf, int vsiz ) ;
+FUNCTION: bool tcadbmapbdbemit ( void* map, c-string kbuf, int ksiz, c-string vbuf, int vsiz ) ;
diff --git a/extra/tokyo/alien/tcbdb/tcbdb.factor b/extra/tokyo/alien/tcbdb/tcbdb.factor
index 8739e04608..6454e6b2fa 100644
--- a/extra/tokyo/alien/tcbdb/tcbdb.factor
+++ b/extra/tokyo/alien/tcbdb/tcbdb.factor
@@ -32,7 +32,7 @@ C-ENUM:
     BDBCPBEFORE
     BDBCPAFTER ;
 
-FUNCTION: char* tcbdberrmsg ( int ecode ) ;
+FUNCTION: c-string tcbdberrmsg ( int ecode ) ;
 FUNCTION: TCBDB* tcbdbnew ( ) ;
 FUNCTION: void tcbdbdel ( TCBDB* bdb ) ;
 FUNCTION: int tcbdbecode ( TCBDB* bdb ) ;
@@ -41,42 +41,42 @@ FUNCTION: bool tcbdbsetcmpfunc ( TCBDB* bdb, TCCMP cmp, void* cmpop ) ;
 FUNCTION: bool tcbdbtune ( TCBDB* bdb, int lmemb, int nmemb, longlong bnum, char apow, char fpow, uchar opts ) ;
 FUNCTION: bool tcbdbsetcache ( TCBDB* bdb, int lcnum, int ncnum ) ;
 FUNCTION: bool tcbdbsetxmsiz ( TCBDB* bdb, longlong xmsiz ) ;
-FUNCTION: bool tcbdbopen ( TCBDB* bdb, char* path, int omode ) ;
+FUNCTION: bool tcbdbopen ( TCBDB* bdb, c-string path, int omode ) ;
 FUNCTION: bool tcbdbclose ( TCBDB* bdb ) ;
 FUNCTION: bool tcbdbput ( TCBDB* bdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcbdbput2 ( TCBDB* bdb, char* kstr, char* vstr ) ;
+FUNCTION: bool tcbdbput2 ( TCBDB* bdb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tcbdbputkeep ( TCBDB* bdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcbdbputkeep2 ( TCBDB* bdb, char* kstr, char* vstr ) ;
+FUNCTION: bool tcbdbputkeep2 ( TCBDB* bdb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tcbdbputcat ( TCBDB* bdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcbdbputcat2 ( TCBDB* bdb, char* kstr, char* vstr ) ;
+FUNCTION: bool tcbdbputcat2 ( TCBDB* bdb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tcbdbputdup ( TCBDB* bdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcbdbputdup2 ( TCBDB* bdb, char* kstr, char* vstr ) ;
+FUNCTION: bool tcbdbputdup2 ( TCBDB* bdb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tcbdbputdup3 ( TCBDB* bdb, void* kbuf, int ksiz, TCLIST* vals ) ;
 FUNCTION: bool tcbdbout ( TCBDB* bdb, void* kbuf, int ksiz ) ;
-FUNCTION: bool tcbdbout2 ( TCBDB* bdb, char* kstr ) ;
+FUNCTION: bool tcbdbout2 ( TCBDB* bdb, c-string kstr ) ;
 FUNCTION: bool tcbdbout3 ( TCBDB* bdb, void* kbuf, int ksiz ) ;
 FUNCTION: void* tcbdbget ( TCBDB* bdb, void* kbuf, int ksiz, int* sp ) ;
-FUNCTION: char* tcbdbget2 ( TCBDB* bdb, char* kstr ) ;
+FUNCTION: c-string tcbdbget2 ( TCBDB* bdb, c-string kstr ) ;
 FUNCTION: void* tcbdbget3 ( TCBDB* bdb, void* kbuf, int ksiz, int* sp ) ;
 FUNCTION: TCLIST* tcbdbget4 ( TCBDB* bdb, void* kbuf, int ksiz ) ;
 FUNCTION: int tcbdbvnum ( TCBDB* bdb, void* kbuf, int ksiz ) ;
-FUNCTION: int tcbdbvnum2 ( TCBDB* bdb, char* kstr ) ;
+FUNCTION: int tcbdbvnum2 ( TCBDB* bdb, c-string kstr ) ;
 FUNCTION: int tcbdbvsiz ( TCBDB* bdb, void* kbuf, int ksiz ) ;
-FUNCTION: int tcbdbvsiz2 ( TCBDB* bdb, char* kstr ) ;
+FUNCTION: int tcbdbvsiz2 ( TCBDB* bdb, c-string kstr ) ;
 FUNCTION: TCLIST* tcbdbrange ( TCBDB* bdb, void* bkbuf, int bksiz, bool binc, void* ekbuf, int eksiz, bool einc, int max ) ;
-FUNCTION: TCLIST* tcbdbrange2 ( TCBDB* bdb, char* bkstr, bool binc, char* ekstr, bool einc, int max ) ;
+FUNCTION: TCLIST* tcbdbrange2 ( TCBDB* bdb, c-string bkstr, bool binc, c-string ekstr, bool einc, int max ) ;
 FUNCTION: TCLIST* tcbdbfwmkeys ( TCBDB* bdb, void* pbuf, int psiz, int max ) ;
-FUNCTION: TCLIST* tcbdbfwmkeys2 ( TCBDB* bdb, char* pstr, int max ) ;
+FUNCTION: TCLIST* tcbdbfwmkeys2 ( TCBDB* bdb, c-string pstr, int max ) ;
 FUNCTION: int tcbdbaddint ( TCBDB* bdb, void* kbuf, int ksiz, int num ) ;
 FUNCTION: double tcbdbadddouble ( TCBDB* bdb, void* kbuf, int ksiz, double num ) ;
 FUNCTION: bool tcbdbsync ( TCBDB* bdb ) ;
 FUNCTION: bool tcbdboptimize ( TCBDB* bdb, int lmemb, int nmemb, longlong bnum, char apow, char fpow, uchar opts ) ;
 FUNCTION: bool tcbdbvanish ( TCBDB* bdb ) ;
-FUNCTION: bool tcbdbcopy ( TCBDB* bdb, char* path ) ;
+FUNCTION: bool tcbdbcopy ( TCBDB* bdb, c-string path ) ;
 FUNCTION: bool tcbdbtranbegin ( TCBDB* bdb ) ;
 FUNCTION: bool tcbdbtrancommit ( TCBDB* bdb ) ;
 FUNCTION: bool tcbdbtranabort ( TCBDB* bdb ) ;
-FUNCTION: char* tcbdbpath ( TCBDB* bdb ) ;
+FUNCTION: c-string tcbdbpath ( TCBDB* bdb ) ;
 FUNCTION: ulonglong tcbdbrnum ( TCBDB* bdb ) ;
 FUNCTION: ulonglong tcbdbfsiz ( TCBDB* bdb ) ;
 FUNCTION: BDBCUR* tcbdbcurnew ( TCBDB* bdb ) ;
@@ -84,23 +84,23 @@ FUNCTION: void tcbdbcurdel ( BDBCUR* cur ) ;
 FUNCTION: bool tcbdbcurfirst ( BDBCUR* cur ) ;
 FUNCTION: bool tcbdbcurlast ( BDBCUR* cur ) ;
 FUNCTION: bool tcbdbcurjump ( BDBCUR* cur, void* kbuf, int ksiz ) ;
-FUNCTION: bool tcbdbcurjump2 ( BDBCUR* cur, char* kstr ) ;
+FUNCTION: bool tcbdbcurjump2 ( BDBCUR* cur, c-string kstr ) ;
 FUNCTION: bool tcbdbcurprev ( BDBCUR* cur ) ;
 FUNCTION: bool tcbdbcurnext ( BDBCUR* cur ) ;
 FUNCTION: bool tcbdbcurput ( BDBCUR* cur, void* vbuf, int vsiz, int cpmode ) ;
-FUNCTION: bool tcbdbcurput2 ( BDBCUR* cur, char* vstr, int cpmode ) ;
+FUNCTION: bool tcbdbcurput2 ( BDBCUR* cur, c-string vstr, int cpmode ) ;
 FUNCTION: bool tcbdbcurout ( BDBCUR* cur ) ;
 FUNCTION: void* tcbdbcurkey ( BDBCUR* cur, int* sp ) ;
-FUNCTION: char* tcbdbcurkey2 ( BDBCUR* cur ) ;
+FUNCTION: c-string tcbdbcurkey2 ( BDBCUR* cur ) ;
 FUNCTION: void* tcbdbcurkey3 ( BDBCUR* cur, int* sp ) ;
 FUNCTION: void* tcbdbcurval ( BDBCUR* cur, int* sp ) ;
-FUNCTION: char* tcbdbcurval2 ( BDBCUR* cur ) ;
+FUNCTION: c-string tcbdbcurval2 ( BDBCUR* cur ) ;
 FUNCTION: void* tcbdbcurval3 ( BDBCUR* cur, int* sp ) ;
 FUNCTION: bool tcbdbcurrec ( BDBCUR* cur, TCXSTR* kxstr, TCXSTR* vxstr ) ;
 
 ! -----------
 
-FUNCTION: void tcbdbsetecode ( TCBDB* bdb, int ecode, char* filename, int line, char* func ) ;
+FUNCTION: void tcbdbsetecode ( TCBDB* bdb, int ecode, c-string filename, int line, c-string func ) ;
 FUNCTION: void tcbdbsetdbgfd ( TCBDB* bdb, int fd ) ;
 FUNCTION: int tcbdbdbgfd ( TCBDB* bdb ) ;
 FUNCTION: bool tcbdbhasmutex ( TCBDB* bdb ) ;
@@ -119,14 +119,14 @@ FUNCTION: ulonglong tcbdbinode ( TCBDB* bdb ) ;
 FUNCTION: tokyo_time_t tcbdbmtime ( TCBDB* bdb ) ;
 FUNCTION: uchar tcbdbflags ( TCBDB* bdb ) ;
 FUNCTION: uchar tcbdbopts ( TCBDB* bdb ) ;
-FUNCTION: char* tcbdbopaque ( TCBDB* bdb ) ;
+FUNCTION: c-string tcbdbopaque ( TCBDB* bdb ) ;
 FUNCTION: ulonglong tcbdbbnumused ( TCBDB* bdb ) ;
 FUNCTION: bool tcbdbsetlsmax ( TCBDB* bdb, uint lsmax ) ;
 FUNCTION: bool tcbdbsetcapnum ( TCBDB* bdb, ulonglong capnum ) ;
 FUNCTION: bool tcbdbsetcodecfunc ( TCBDB* bdb, TCCODEC enc, void* encop, TCCODEC dec, void* decop ) ;
 FUNCTION: bool tcbdbputdupback ( TCBDB* bdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcbdbputdupback2 ( TCBDB* bdb, char* kstr, char* vstr ) ;
+FUNCTION: bool tcbdbputdupback2 ( TCBDB* bdb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tcbdbputproc ( TCBDB* bdb, void* kbuf, int ksiz, void* vbuf, int vsiz, TCPDPROC proc, void* op ) ;
 FUNCTION: bool tcbdbcurjumpback ( BDBCUR* cur, void* kbuf, int ksiz ) ;
-FUNCTION: bool tcbdbcurjumpback2 ( BDBCUR* cur, char* kstr ) ;
+FUNCTION: bool tcbdbcurjumpback2 ( BDBCUR* cur, c-string kstr ) ;
 FUNCTION: bool tcbdbforeach ( TCBDB* bdb, TCITER iter, void* op ) ;
diff --git a/extra/tokyo/alien/tcfdb/tcfdb.factor b/extra/tokyo/alien/tcfdb/tcfdb.factor
index 91400aaf4e..cde71f27a5 100644
--- a/extra/tokyo/alien/tcfdb/tcfdb.factor
+++ b/extra/tokyo/alien/tcfdb/tcfdb.factor
@@ -22,40 +22,40 @@ CONSTANT: FDBIDPREV -2
 CONSTANT: FDBIDMAX  -3
 CONSTANT: FDBIDNEXT -4
 
-FUNCTION: char* tcfdberrmsg ( int ecode ) ;
+FUNCTION: c-string tcfdberrmsg ( int ecode ) ;
 FUNCTION: TCFDB* tcfdbnew ( ) ;
 FUNCTION: void tcfdbdel ( TCFDB* fdb ) ;
 FUNCTION: int tcfdbecode ( TCFDB* fdb ) ;
 FUNCTION: bool tcfdbsetmutex ( TCFDB* fdb ) ;
 FUNCTION: bool tcfdbtune ( TCFDB* fdb, int width, longlong limsiz ) ;
-FUNCTION: bool tcfdbopen ( TCFDB* fdb, char* path, int omode ) ;
+FUNCTION: bool tcfdbopen ( TCFDB* fdb, c-string path, int omode ) ;
 FUNCTION: bool tcfdbclose ( TCFDB* fdb ) ;
 FUNCTION: bool tcfdbput ( TCFDB* fdb, longlong id, void* vbuf, int vsiz ) ;
 FUNCTION: bool tcfdbput2 ( TCFDB* fdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcfdbput3 ( TCFDB* fdb, char* kstr, void* vstr ) ;
+FUNCTION: bool tcfdbput3 ( TCFDB* fdb, c-string kstr, void* vstr ) ;
 FUNCTION: bool tcfdbputkeep ( TCFDB* fdb, longlong id, void* vbuf, int vsiz ) ;
 FUNCTION: bool tcfdbputkeep2 ( TCFDB* fdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcfdbputkeep3 ( TCFDB* fdb, char* kstr, void* vstr ) ;
+FUNCTION: bool tcfdbputkeep3 ( TCFDB* fdb, c-string kstr, void* vstr ) ;
 FUNCTION: bool tcfdbputcat ( TCFDB* fdb, longlong id, void* vbuf, int vsiz ) ;
 FUNCTION: bool tcfdbputcat2 ( TCFDB* fdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcfdbputcat3 ( TCFDB* fdb, char* kstr, void* vstr ) ;
+FUNCTION: bool tcfdbputcat3 ( TCFDB* fdb, c-string kstr, void* vstr ) ;
 FUNCTION: bool tcfdbout ( TCFDB* fdb, longlong id ) ;
 FUNCTION: bool tcfdbout2 ( TCFDB* fdb, void* kbuf, int ksiz ) ;
-FUNCTION: bool tcfdbout3 ( TCFDB* fdb, char* kstr ) ;
+FUNCTION: bool tcfdbout3 ( TCFDB* fdb, c-string kstr ) ;
 FUNCTION: void* tcfdbget ( TCFDB* fdb, longlong id, int* sp ) ;
 FUNCTION: void* tcfdbget2 ( TCFDB* fdb, void* kbuf, int ksiz, int* sp ) ;
-FUNCTION: char* tcfdbget3 ( TCFDB* fdb, char* kstr ) ;
+FUNCTION: c-string tcfdbget3 ( TCFDB* fdb, c-string kstr ) ;
 FUNCTION: int tcfdbget4 ( TCFDB* fdb, longlong id, void* vbuf, int max ) ;
 FUNCTION: int tcfdbvsiz ( TCFDB* fdb, longlong id ) ;
 FUNCTION: int tcfdbvsiz2 ( TCFDB* fdb, void* kbuf, int ksiz ) ;
-FUNCTION: int tcfdbvsiz3 ( TCFDB* fdb, char* kstr ) ;
+FUNCTION: int tcfdbvsiz3 ( TCFDB* fdb, c-string kstr ) ;
 FUNCTION: bool tcfdbiterinit ( TCFDB* fdb ) ;
 FUNCTION: ulonglong tcfdbiternext ( TCFDB* fdb ) ;
 FUNCTION: void* tcfdbiternext2 ( TCFDB* fdb, int* sp ) ;
-FUNCTION: char* tcfdbiternext3 ( TCFDB* fdb ) ;
+FUNCTION: c-string tcfdbiternext3 ( TCFDB* fdb ) ;
 FUNCTION: ulonglong* tcfdbrange ( TCFDB* fdb, longlong lower, longlong upper, int max, int* np ) ;
 FUNCTION: TCLIST* tcfdbrange2 ( TCFDB* fdb, void* lbuf, int lsiz, void* ubuf, int usiz, int max ) ;
-FUNCTION: TCLIST* tcfdbrange3 ( TCFDB* fdb, char* lstr, char* ustr, int max ) ;
+FUNCTION: TCLIST* tcfdbrange3 ( TCFDB* fdb, c-string lstr, c-string ustr, int max ) ;
 FUNCTION: TCLIST* tcfdbrange4 ( TCFDB* fdb, void* ibuf, int isiz, int max ) ;
 FUNCTION: TCLIST* tcfdbrange5 ( TCFDB* fdb, void* istr, int max ) ;
 FUNCTION: int tcfdbaddint ( TCFDB* fdb, longlong id, int num ) ;
@@ -63,17 +63,17 @@ FUNCTION: double tcfdbadddouble ( TCFDB* fdb, longlong id, double num ) ;
 FUNCTION: bool tcfdbsync ( TCFDB* fdb ) ;
 FUNCTION: bool tcfdboptimize ( TCFDB* fdb, int width, longlong limsiz ) ;
 FUNCTION: bool tcfdbvanish ( TCFDB* fdb ) ;
-FUNCTION: bool tcfdbcopy ( TCFDB* fdb, char* path ) ;
+FUNCTION: bool tcfdbcopy ( TCFDB* fdb, c-string path ) ;
 FUNCTION: bool tcfdbtranbegin ( TCFDB* fdb ) ;
 FUNCTION: bool tcfdbtrancommit ( TCFDB* fdb ) ;
 FUNCTION: bool tcfdbtranabort ( TCFDB* fdb ) ;
-FUNCTION: char* tcfdbpath ( TCFDB* fdb ) ;
+FUNCTION: c-string tcfdbpath ( TCFDB* fdb ) ;
 FUNCTION: ulonglong tcfdbrnum ( TCFDB* fdb ) ;
 FUNCTION: ulonglong tcfdbfsiz ( TCFDB* fdb ) ;
 
 ! --------
 
-FUNCTION: void tcfdbsetecode ( TCFDB* fdb, int ecode, char* filename, int line, char* func ) ;
+FUNCTION: void tcfdbsetecode ( TCFDB* fdb, int ecode, c-string filename, int line, c-string func ) ;
 FUNCTION: void tcfdbsetdbgfd ( TCFDB* fdb, int fd ) ;
 FUNCTION: int tcfdbdbgfd ( TCFDB* fdb ) ;
 FUNCTION: bool tcfdbhasmutex ( TCFDB* fdb ) ;
@@ -88,7 +88,7 @@ FUNCTION: tokyo_time_t tcfdbmtime ( TCFDB* fdb ) ;
 FUNCTION: int tcfdbomode ( TCFDB* fdb ) ;
 FUNCTION: uchar tcfdbtype ( TCFDB* fdb ) ;
 FUNCTION: uchar tcfdbflags ( TCFDB* fdb ) ;
-FUNCTION: char* tcfdbopaque ( TCFDB* fdb ) ;
+FUNCTION: c-string tcfdbopaque ( TCFDB* fdb ) ;
 FUNCTION: bool tcfdbputproc ( TCFDB* fdb, longlong id, void* vbuf, int vsiz, TCPDPROC proc, void* op ) ;
 FUNCTION: bool tcfdbforeach ( TCFDB* fdb, TCITER iter, void* op ) ;
-FUNCTION: longlong tcfdbkeytoid ( char* kbuf, int ksiz ) ;
+FUNCTION: longlong tcfdbkeytoid ( c-string kbuf, int ksiz ) ;
diff --git a/extra/tokyo/alien/tchdb/tchdb.factor b/extra/tokyo/alien/tchdb/tchdb.factor
index fd0464fcec..65d00b2a69 100644
--- a/extra/tokyo/alien/tchdb/tchdb.factor
+++ b/extra/tokyo/alien/tchdb/tchdb.factor
@@ -26,7 +26,7 @@ CONSTANT: HDBONOLCK  16
 CONSTANT: HDBOLCKNB  32
 CONSTANT: HDBOTSYNC  64
 
-FUNCTION: char* tchdberrmsg ( int ecode ) ;
+FUNCTION: c-string tchdberrmsg ( int ecode ) ;
 FUNCTION: TCHDB* tchdbnew ( ) ;
 FUNCTION: void tchdbdel ( TCHDB* hdb ) ;
 FUNCTION: int tchdbecode ( TCHDB* hdb ) ;
@@ -34,45 +34,45 @@ FUNCTION: bool tchdbsetmutex ( TCHDB* hdb ) ;
 FUNCTION: bool tchdbtune ( TCHDB* hdb, longlong bnum, char apow, char fpow, uchar opts ) ;
 FUNCTION: bool tchdbsetcache ( TCHDB* hdb, int rcnum ) ;
 FUNCTION: bool tchdbsetxmsiz ( TCHDB* hdb, longlong xmsiz ) ;
-FUNCTION: bool tchdbopen ( TCHDB* hdb, char* path, int omode ) ;
+FUNCTION: bool tchdbopen ( TCHDB* hdb, c-string path, int omode ) ;
 FUNCTION: bool tchdbclose ( TCHDB* hdb ) ;
 FUNCTION: bool tchdbput ( TCHDB* hdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tchdbput2 ( TCHDB* hdb, char* kstr, char* vstr ) ;
+FUNCTION: bool tchdbput2 ( TCHDB* hdb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tchdbputkeep ( TCHDB* hdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tchdbputkeep2 ( TCHDB* hdb, char* kstr, char* vstr ) ;
+FUNCTION: bool tchdbputkeep2 ( TCHDB* hdb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tchdbputcat ( TCHDB* hdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tchdbputcat2 ( TCHDB* hdb, char* kstr, char* vstr ) ;
+FUNCTION: bool tchdbputcat2 ( TCHDB* hdb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tchdbputasync ( TCHDB* hdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tchdbputasync2 ( TCHDB* hdb, char* kstr, char* vstr ) ;
+FUNCTION: bool tchdbputasync2 ( TCHDB* hdb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tchdbout ( TCHDB* hdb, void* kbuf, int ksiz ) ;
-FUNCTION: bool tchdbout2 ( TCHDB* hdb, char* kstr ) ;
+FUNCTION: bool tchdbout2 ( TCHDB* hdb, c-string kstr ) ;
 FUNCTION: void* tchdbget ( TCHDB* hdb, void* kbuf, int ksiz, int* sp ) ;
-FUNCTION: char* tchdbget2 ( TCHDB* hdb, char* kstr ) ;
+FUNCTION: c-string tchdbget2 ( TCHDB* hdb, c-string kstr ) ;
 FUNCTION: int tchdbget3 ( TCHDB* hdb, void* kbuf, int ksiz, void* vbuf, int max ) ;
 FUNCTION: int tchdbvsiz ( TCHDB* hdb, void* kbuf, int ksiz ) ;
-FUNCTION: int tchdbvsiz2 ( TCHDB* hdb, char* kstr ) ;
+FUNCTION: int tchdbvsiz2 ( TCHDB* hdb, c-string kstr ) ;
 FUNCTION: bool tchdbiterinit ( TCHDB* hdb ) ;
 FUNCTION: void* tchdbiternext ( TCHDB* hdb, int* sp ) ;
-FUNCTION: char* tchdbiternext2 ( TCHDB* hdb ) ;
+FUNCTION: c-string tchdbiternext2 ( TCHDB* hdb ) ;
 FUNCTION: bool tchdbiternext3 ( TCHDB* hdb, TCXSTR* kxstr, TCXSTR* vxstr ) ;
 FUNCTION: TCLIST* tchdbfwmkeys ( TCHDB* hdb, void* pbuf, int psiz, int max ) ;
-FUNCTION: TCLIST* tchdbfwmkeys2 ( TCHDB* hdb, char* pstr, int max ) ;
+FUNCTION: TCLIST* tchdbfwmkeys2 ( TCHDB* hdb, c-string pstr, int max ) ;
 FUNCTION: int tchdbaddint ( TCHDB* hdb, void* kbuf, int ksiz, int num ) ;
 FUNCTION: double tchdbadddouble ( TCHDB* hdb, void* kbuf, int ksiz, double num ) ;
 FUNCTION: bool tchdbsync ( TCHDB* hdb ) ;
 FUNCTION: bool tchdboptimize ( TCHDB* hdb, longlong bnum, char apow, char fpow, uchar opts ) ;
 FUNCTION: bool tchdbvanish ( TCHDB* hdb ) ;
-FUNCTION: bool tchdbcopy ( TCHDB* hdb, char* path ) ;
+FUNCTION: bool tchdbcopy ( TCHDB* hdb, c-string path ) ;
 FUNCTION: bool tchdbtranbegin ( TCHDB* hdb ) ;
 FUNCTION: bool tchdbtrancommit ( TCHDB* hdb ) ;
 FUNCTION: bool tchdbtranabort ( TCHDB* hdb ) ;
-FUNCTION: char* tchdbpath ( TCHDB* hdb ) ;
+FUNCTION: c-string tchdbpath ( TCHDB* hdb ) ;
 FUNCTION: ulonglong tchdbrnum ( TCHDB* hdb ) ;
 FUNCTION: ulonglong tchdbfsiz ( TCHDB* hdb ) ;
 
 ! --------
 
-FUNCTION: void tchdbsetecode ( TCHDB* hdb, int ecode, char* filename, int line, char* func ) ;
+FUNCTION: void tchdbsetecode ( TCHDB* hdb, int ecode, c-string filename, int line, c-string func ) ;
 FUNCTION: void tchdbsettype ( TCHDB* hdb, uchar type ) ;
 FUNCTION: void tchdbsetdbgfd ( TCHDB* hdb, int fd ) ;
 FUNCTION: int tchdbdbgfd ( TCHDB* hdb ) ;
@@ -89,13 +89,13 @@ FUNCTION: int tchdbomode ( TCHDB* hdb ) ;
 FUNCTION: uchar tchdbtype ( TCHDB* hdb ) ;
 FUNCTION: uchar tchdbflags ( TCHDB* hdb ) ;
 FUNCTION: uchar tchdbopts ( TCHDB* hdb ) ;
-FUNCTION: char* tchdbopaque ( TCHDB* hdb ) ;
+FUNCTION: c-string tchdbopaque ( TCHDB* hdb ) ;
 FUNCTION: ulonglong tchdbbnumused ( TCHDB* hdb ) ;
 FUNCTION: bool tchdbsetcodecfunc ( TCHDB* hdb, TCCODEC enc, void* encop, TCCODEC dec, void* decop ) ;
 FUNCTION: void tchdbcodecfunc ( TCHDB* hdb, TCCODEC* ep, void* *eop, TCCODEC* dp, void* *dop ) ;
 FUNCTION: bool tchdbputproc ( TCHDB* hdb, void* kbuf, int ksiz, void* vbuf, int vsiz, TCPDPROC proc, void* op ) ;
 FUNCTION: void* tchdbgetnext ( TCHDB* hdb, void* kbuf, int ksiz, int* sp ) ;
-FUNCTION: char* tchdbgetnext2 ( TCHDB* hdb, char* kstr ) ;
-FUNCTION: char* tchdbgetnext3 ( TCHDB* hdb, char* kbuf, int ksiz, int* sp, char* *vbp, int* vsp ) ;
+FUNCTION: c-string tchdbgetnext2 ( TCHDB* hdb, c-string kstr ) ;
+FUNCTION: c-string tchdbgetnext3 ( TCHDB* hdb, c-string kbuf, int ksiz, int* sp, c-string *vbp, int* vsp ) ;
 FUNCTION: bool tchdbforeach ( TCHDB* hdb, TCITER iter, void* op ) ;
 FUNCTION: bool tchdbtranvoid ( TCHDB* hdb ) ;
diff --git a/extra/tokyo/alien/tcrdb/tcrdb.factor b/extra/tokyo/alien/tcrdb/tcrdb.factor
index a6e59dbe03..da4a750444 100644
--- a/extra/tokyo/alien/tcrdb/tcrdb.factor
+++ b/extra/tokyo/alien/tcrdb/tcrdb.factor
@@ -17,9 +17,9 @@ C-TYPE: TCRDB
 ! STRUCT: TCRDB
 !     { mmtx pthread_mutex_t }
 !     { eckey pthread_key_t }
-!     { host char* }
+!     { host c-string }
 !     { port int }
-!     { expr char* }
+!     { expr c-string }
 !     { fd int }
 !     { sock TTSOCK* }
 !     { timeout double }
@@ -42,52 +42,52 @@ CONSTANT: RDBXOLCKGLB 2
 CONSTANT: RDBROCHKCON 1
 CONSTANT: RDBMONOULOG 1
 
-FUNCTION: char* tcrdberrmsg ( int ecode ) ;
+FUNCTION: c-string tcrdberrmsg ( int ecode ) ;
 FUNCTION: TCRDB* tcrdbnew ( ) ;
 FUNCTION: void tcrdbdel ( TCRDB* rdb ) ;
 FUNCTION: int tcrdbecode ( TCRDB* rdb ) ;
 FUNCTION: bool tcrdbtune ( TCRDB* rdb, double timeout, int opts ) ;
-FUNCTION: bool tcrdbopen ( TCRDB* rdb, char* host, int port ) ;
-FUNCTION: bool tcrdbopen2 ( TCRDB* rdb, char* expr ) ;
+FUNCTION: bool tcrdbopen ( TCRDB* rdb, c-string host, int port ) ;
+FUNCTION: bool tcrdbopen2 ( TCRDB* rdb, c-string expr ) ;
 FUNCTION: bool tcrdbclose ( TCRDB* rdb ) ;
 FUNCTION: bool tcrdbput ( TCRDB* rdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcrdbput2 ( TCRDB* rdb, char* kstr, char* vstr ) ;
+FUNCTION: bool tcrdbput2 ( TCRDB* rdb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tcrdbputkeep ( TCRDB* rdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcrdbputkeep2 ( TCRDB* rdb, char* kstr, char* vstr ) ;
+FUNCTION: bool tcrdbputkeep2 ( TCRDB* rdb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tcrdbputcat ( TCRDB* rdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcrdbputcat2 ( TCRDB* rdb, char* kstr, char* vstr ) ;
+FUNCTION: bool tcrdbputcat2 ( TCRDB* rdb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tcrdbputshl ( TCRDB* rdb, void* kbuf, int ksiz, void* vbuf, int vsiz, int width ) ;
-FUNCTION: bool tcrdbputshl2 ( TCRDB* rdb, char* kstr, char* vstr, int width ) ;
+FUNCTION: bool tcrdbputshl2 ( TCRDB* rdb, c-string kstr, c-string vstr, int width ) ;
 FUNCTION: bool tcrdbputnr ( TCRDB* rdb, void* kbuf, int ksiz, void* vbuf, int vsiz ) ;
-FUNCTION: bool tcrdbputnr2 ( TCRDB* rdb, char* kstr, char* vstr ) ;
+FUNCTION: bool tcrdbputnr2 ( TCRDB* rdb, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tcrdbout ( TCRDB* rdb, void* kbuf, int ksiz ) ;
-FUNCTION: bool tcrdbout2 ( TCRDB* rdb, char* kstr ) ;
+FUNCTION: bool tcrdbout2 ( TCRDB* rdb, c-string kstr ) ;
 FUNCTION: void* tcrdbget ( TCRDB* rdb, void* kbuf, int ksiz, int* sp ) ;
-FUNCTION: char* tcrdbget2 ( TCRDB* rdb, char* kstr ) ;
+FUNCTION: c-string tcrdbget2 ( TCRDB* rdb, c-string kstr ) ;
 FUNCTION: bool tcrdbget3 ( TCRDB* rdb, TCMAP* recs ) ;
 FUNCTION: int tcrdbvsiz ( TCRDB* rdb, void* kbuf, int ksiz ) ;
-FUNCTION: int tcrdbvsiz2 ( TCRDB* rdb, char* kstr ) ;
+FUNCTION: int tcrdbvsiz2 ( TCRDB* rdb, c-string kstr ) ;
 FUNCTION: bool tcrdbiterinit ( TCRDB* rdb ) ;
 FUNCTION: void* tcrdbiternext ( TCRDB* rdb, int* sp ) ;
-FUNCTION: char* tcrdbiternext2 ( TCRDB* rdb ) ;
+FUNCTION: c-string tcrdbiternext2 ( TCRDB* rdb ) ;
 FUNCTION: TCLIST* tcrdbfwmkeys ( TCRDB* rdb, void* pbuf, int psiz, int max ) ;
-FUNCTION: TCLIST* tcrdbfwmkeys2 ( TCRDB* rdb, char* pstr, int max ) ;
+FUNCTION: TCLIST* tcrdbfwmkeys2 ( TCRDB* rdb, c-string pstr, int max ) ;
 FUNCTION: int tcrdbaddint ( TCRDB* rdb, void* kbuf, int ksiz, int num ) ;
 FUNCTION: double tcrdbadddouble ( TCRDB* rdb, void* kbuf, int ksiz, double num ) ;
-FUNCTION: void* tcrdbext ( TCRDB* rdb, char* name, int opts, void* kbuf, int ksiz, void* vbuf, int vsiz, int* sp ) ;
-FUNCTION: char* tcrdbext2 ( TCRDB* rdb, char* name, int opts, char* kstr, char* vstr ) ;
+FUNCTION: void* tcrdbext ( TCRDB* rdb, c-string name, int opts, void* kbuf, int ksiz, void* vbuf, int vsiz, int* sp ) ;
+FUNCTION: c-string tcrdbext2 ( TCRDB* rdb, c-string name, int opts, c-string kstr, c-string vstr ) ;
 FUNCTION: bool tcrdbsync ( TCRDB* rdb ) ;
-FUNCTION: bool tcrdboptimize ( TCRDB* rdb, char* params ) ;
+FUNCTION: bool tcrdboptimize ( TCRDB* rdb, c-string params ) ;
 FUNCTION: bool tcrdbvanish ( TCRDB* rdb ) ;
-FUNCTION: bool tcrdbcopy ( TCRDB* rdb, char* path ) ;
-FUNCTION: bool tcrdbrestore ( TCRDB* rdb, char* path, ulonglong ts, int opts ) ;
-FUNCTION: bool tcrdbsetmst ( TCRDB* rdb, char* host, int port, int opts ) ;
-FUNCTION: bool tcrdbsetmst2 ( TCRDB* rdb, char* expr, int opts ) ;
-FUNCTION: char* tcrdbexpr ( TCRDB* rdb ) ;
+FUNCTION: bool tcrdbcopy ( TCRDB* rdb, c-string path ) ;
+FUNCTION: bool tcrdbrestore ( TCRDB* rdb, c-string path, ulonglong ts, int opts ) ;
+FUNCTION: bool tcrdbsetmst ( TCRDB* rdb, c-string host, int port, int opts ) ;
+FUNCTION: bool tcrdbsetmst2 ( TCRDB* rdb, c-string expr, int opts ) ;
+FUNCTION: c-string tcrdbexpr ( TCRDB* rdb ) ;
 FUNCTION: ulonglong tcrdbrnum ( TCRDB* rdb ) ;
 FUNCTION: ulonglong tcrdbsize ( TCRDB* rdb ) ;
-FUNCTION: char* tcrdbstat ( TCRDB* rdb ) ;
-FUNCTION: TCLIST* tcrdbmisc ( TCRDB* rdb, char* name, int opts, TCLIST* args ) ;
+FUNCTION: c-string tcrdbstat ( TCRDB* rdb ) ;
+FUNCTION: TCLIST* tcrdbmisc ( TCRDB* rdb, c-string name, int opts, TCLIST* args ) ;
 
 CONSTANT: RDBITLEXICAL TDBITLEXICAL
 CONSTANT: RDBITDECIMAL TDBITDECIMAL
@@ -128,12 +128,12 @@ FUNCTION: bool tcrdbtblputkeep ( TCRDB* rdb, void* pkbuf, int pksiz, TCMAP* cols
 FUNCTION: bool tcrdbtblputcat ( TCRDB* rdb, void* pkbuf, int pksiz, TCMAP* cols ) ;
 FUNCTION: bool tcrdbtblout ( TCRDB* rdb, void* pkbuf, int pksiz ) ;
 FUNCTION: TCMAP* tcrdbtblget ( TCRDB* rdb, void* pkbuf, int pksiz ) ;
-FUNCTION: bool tcrdbtblsetindex ( TCRDB* rdb, char* name, int type ) ;
+FUNCTION: bool tcrdbtblsetindex ( TCRDB* rdb, c-string name, int type ) ;
 FUNCTION: longlong tcrdbtblgenuid ( TCRDB* rdb ) ;
 FUNCTION: RDBQRY* tcrdbqrynew ( TCRDB* rdb ) ;
 FUNCTION: void tcrdbqrydel ( RDBQRY* qry ) ;
-FUNCTION: void tcrdbqryaddcond ( RDBQRY* qry, char* name, int op, char* expr ) ;
-FUNCTION: void tcrdbqrysetorder ( RDBQRY* qry, char* name, int type ) ;
+FUNCTION: void tcrdbqryaddcond ( RDBQRY* qry, c-string name, int op, c-string expr ) ;
+FUNCTION: void tcrdbqrysetorder ( RDBQRY* qry, c-string name, int type ) ;
 FUNCTION: void tcrdbqrysetlimit ( RDBQRY* qry, int max, int skip ) ;
 FUNCTION: TCLIST* tcrdbqrysearch ( RDBQRY* qry ) ;
 FUNCTION: bool tcrdbqrysearchout ( RDBQRY* qry ) ;
diff --git a/extra/tokyo/alien/tctdb/tctdb.factor b/extra/tokyo/alien/tctdb/tctdb.factor
index 9e8071d0df..82100e23c8 100644
--- a/extra/tokyo/alien/tctdb/tctdb.factor
+++ b/extra/tokyo/alien/tctdb/tctdb.factor
@@ -71,7 +71,7 @@ CONSTANT: TDBQPSTOP 16777216
 ! int (*)(const void *pkbuf, int pksiz, TCMAP *cols, void *op);
 TYPEDEF: void* TDBQRYPROC
 
-FUNCTION: char* tctdberrmsg ( int ecode ) ;
+FUNCTION: c-string tctdberrmsg ( int ecode ) ;
 FUNCTION: TCTDB* tctdbnew ( ) ;
 FUNCTION: void tctdbdel ( TCTDB* tdb ) ;
 FUNCTION: int tctdbecode ( TCTDB* tdb ) ;
@@ -79,56 +79,56 @@ FUNCTION: bool tctdbsetmutex ( TCTDB* tdb ) ;
 FUNCTION: bool tctdbtune ( TCTDB* tdb, longlong bnum, char apow, char fpow, uchar opts ) ;
 FUNCTION: bool tctdbsetcache ( TCTDB* tdb, int rcnum, int lcnum, int ncnum ) ;
 FUNCTION: bool tctdbsetxmsiz ( TCTDB* tdb, longlong xmsiz ) ;
-FUNCTION: bool tctdbopen ( TCTDB* tdb, char* path, int omode ) ;
+FUNCTION: bool tctdbopen ( TCTDB* tdb, c-string path, int omode ) ;
 FUNCTION: bool tctdbclose ( TCTDB* tdb ) ;
 FUNCTION: bool tctdbput ( TCTDB* tdb, void* pkbuf, int pksiz, TCMAP* cols ) ;
 FUNCTION: bool tctdbput2 ( TCTDB* tdb, void* pkbuf, int pksiz, void* cbuf, int csiz ) ;
-FUNCTION: bool tctdbput3 ( TCTDB* tdb, char* pkstr, char* cstr ) ;
+FUNCTION: bool tctdbput3 ( TCTDB* tdb, c-string pkstr, c-string cstr ) ;
 FUNCTION: bool tctdbputkeep ( TCTDB* tdb, void* pkbuf, int pksiz, TCMAP* cols ) ;
 FUNCTION: bool tctdbputkeep2 ( TCTDB* tdb, void* pkbuf, int pksiz, void* cbuf, int csiz ) ;
-FUNCTION: bool tctdbputkeep3 ( TCTDB* tdb, char* pkstr, char* cstr ) ;
+FUNCTION: bool tctdbputkeep3 ( TCTDB* tdb, c-string pkstr, c-string cstr ) ;
 FUNCTION: bool tctdbputcat ( TCTDB* tdb, void* pkbuf, int pksiz, TCMAP* cols ) ;
 FUNCTION: bool tctdbputcat2 ( TCTDB* tdb, void* pkbuf, int pksiz, void* cbuf, int csiz ) ;
-FUNCTION: bool tctdbputcat3 ( TCTDB* tdb, char* pkstr, char* cstr ) ;
+FUNCTION: bool tctdbputcat3 ( TCTDB* tdb, c-string pkstr, c-string cstr ) ;
 FUNCTION: bool tctdbout ( TCTDB* tdb, void* pkbuf, int pksiz ) ;
-FUNCTION: bool tctdbout2 ( TCTDB* tdb, char* pkstr ) ;
+FUNCTION: bool tctdbout2 ( TCTDB* tdb, c-string pkstr ) ;
 FUNCTION: TCMAP* tctdbget ( TCTDB* tdb, void* pkbuf, int pksiz ) ;
-FUNCTION: char* tctdbget2 ( TCTDB* tdb, void* pkbuf, int pksiz, int* sp ) ;
-FUNCTION: char* tctdbget3 ( TCTDB* tdb, char* pkstr ) ;
+FUNCTION: c-string tctdbget2 ( TCTDB* tdb, void* pkbuf, int pksiz, int* sp ) ;
+FUNCTION: c-string tctdbget3 ( TCTDB* tdb, c-string pkstr ) ;
 FUNCTION: int tctdbvsiz ( TCTDB* tdb, void* pkbuf, int pksiz ) ;
-FUNCTION: int tctdbvsiz2 ( TCTDB* tdb, char* pkstr ) ;
+FUNCTION: int tctdbvsiz2 ( TCTDB* tdb, c-string pkstr ) ;
 FUNCTION: bool tctdbiterinit ( TCTDB* tdb ) ;
 FUNCTION: void* tctdbiternext ( TCTDB* tdb, int* sp ) ;
-FUNCTION: char* tctdbiternext2 ( TCTDB* tdb ) ;
+FUNCTION: c-string tctdbiternext2 ( TCTDB* tdb ) ;
 FUNCTION: TCLIST* tctdbfwmkeys ( TCTDB* tdb, void* pbuf, int psiz, int max ) ;
-FUNCTION: TCLIST* tctdbfwmkeys2 ( TCTDB* tdb, char* pstr, int max ) ;
+FUNCTION: TCLIST* tctdbfwmkeys2 ( TCTDB* tdb, c-string pstr, int max ) ;
 FUNCTION: int tctdbaddint ( TCTDB* tdb, void* pkbuf, int pksiz, int num ) ;
 FUNCTION: double tctdbadddouble ( TCTDB* tdb, void* pkbuf, int pksiz, double num ) ;
 FUNCTION: bool tctdbsync ( TCTDB* tdb ) ;
 FUNCTION: bool tctdboptimize ( TCTDB* tdb, longlong bnum, char apow, char fpow, uchar opts ) ;
 FUNCTION: bool tctdbvanish ( TCTDB* tdb ) ;
-FUNCTION: bool tctdbcopy ( TCTDB* tdb, char* path ) ;
+FUNCTION: bool tctdbcopy ( TCTDB* tdb, c-string path ) ;
 FUNCTION: bool tctdbtranbegin ( TCTDB* tdb ) ;
 FUNCTION: bool tctdbtrancommit ( TCTDB* tdb ) ;
 FUNCTION: bool tctdbtranabort ( TCTDB* tdb ) ;
-FUNCTION: char* tctdbpath ( TCTDB* tdb ) ;
+FUNCTION: c-string tctdbpath ( TCTDB* tdb ) ;
 FUNCTION: ulonglong tctdbrnum ( TCTDB* tdb ) ;
 FUNCTION: ulonglong tctdbfsiz ( TCTDB* tdb ) ;
-FUNCTION: bool tctdbsetindex ( TCTDB* tdb, char* name, int type ) ;
+FUNCTION: bool tctdbsetindex ( TCTDB* tdb, c-string name, int type ) ;
 FUNCTION: longlong tctdbgenuid ( TCTDB* tdb ) ;
 FUNCTION: TDBQRY* tctdbqrynew ( TCTDB* tdb ) ;
 FUNCTION: void tctdbqrydel ( TDBQRY* qry ) ;
-FUNCTION: void tctdbqryaddcond ( TDBQRY* qry, char* name, int op, char* expr ) ;
-FUNCTION: void tctdbqrysetorder ( TDBQRY* qry, char* name, int type ) ;
+FUNCTION: void tctdbqryaddcond ( TDBQRY* qry, c-string name, int op, c-string expr ) ;
+FUNCTION: void tctdbqrysetorder ( TDBQRY* qry, c-string name, int type ) ;
 FUNCTION: void tctdbqrysetlimit ( TDBQRY* qry, int max, int skip ) ;
 FUNCTION: TCLIST* tctdbqrysearch ( TDBQRY* qry ) ;
 FUNCTION: bool tctdbqrysearchout ( TDBQRY* qry ) ;
 FUNCTION: bool tctdbqryproc ( TDBQRY* qry, TDBQRYPROC proc, void* op ) ;
-FUNCTION: char* tctdbqryhint ( TDBQRY* qry ) ;
+FUNCTION: c-string tctdbqryhint ( TDBQRY* qry ) ;
 
 ! =======
 
-FUNCTION: void tctdbsetecode ( TCTDB* tdb, int ecode, char* filename, int line, char* func ) ;
+FUNCTION: void tctdbsetecode ( TCTDB* tdb, int ecode, c-string filename, int line, c-string func ) ;
 FUNCTION: void tctdbsetdbgfd ( TCTDB* tdb, int fd ) ;
 FUNCTION: int tctdbdbgfd ( TCTDB* tdb ) ;
 FUNCTION: bool tctdbhasmutex ( TCTDB* tdb ) ;
@@ -140,7 +140,7 @@ FUNCTION: ulonglong tctdbinode ( TCTDB* tdb ) ;
 FUNCTION: tokyo_time_t tctdbmtime ( TCTDB* tdb ) ;
 FUNCTION: uchar tctdbflags ( TCTDB* tdb ) ;
 FUNCTION: uchar tctdbopts ( TCTDB* tdb ) ;
-FUNCTION: char* tctdbopaque ( TCTDB* tdb ) ;
+FUNCTION: c-string tctdbopaque ( TCTDB* tdb ) ;
 FUNCTION: ulonglong tctdbbnumused ( TCTDB* tdb ) ;
 FUNCTION: int tctdbinum ( TCTDB* tdb ) ;
 FUNCTION: longlong tctdbuidseed ( TCTDB* tdb ) ;
@@ -150,7 +150,7 @@ FUNCTION: bool tctdbputproc ( TCTDB* tdb, void* pkbuf, int pksiz, void* cbuf, in
 FUNCTION: bool tctdbforeach ( TCTDB* tdb, TCITER iter, void* op ) ;
 FUNCTION: bool tctdbqryproc2 ( TDBQRY* qry, TDBQRYPROC proc, void* op ) ;
 FUNCTION: bool tctdbqrysearchout2 ( TDBQRY* qry ) ;
-FUNCTION: int tctdbstrtoindextype ( char* str ) ;
+FUNCTION: int tctdbstrtoindextype ( c-string str ) ;
 FUNCTION: int tctdbqrycount ( TDBQRY* qry ) ;
-FUNCTION: int tctdbqrystrtocondop ( char* str ) ;
-FUNCTION: int tctdbqrystrtoordertype ( char* str ) ;
+FUNCTION: int tctdbqrystrtocondop ( c-string str ) ;
+FUNCTION: int tctdbqrystrtoordertype ( c-string str ) ;
diff --git a/extra/tokyo/alien/tcutil/tcutil.factor b/extra/tokyo/alien/tcutil/tcutil.factor
index 7cb6c5e092..afb78dba22 100644
--- a/extra/tokyo/alien/tcutil/tcutil.factor
+++ b/extra/tokyo/alien/tcutil/tcutil.factor
@@ -28,9 +28,9 @@ FUNCTION: TCLIST* tclistnew2 ( int anum ) ;
 FUNCTION: void tclistdel ( TCLIST* list ) ;
 FUNCTION: int tclistnum ( TCLIST* list ) ;
 FUNCTION: void* tclistval ( TCLIST* list, int index, int* sp ) ;
-FUNCTION: char* tclistval2 ( TCLIST* list, int index ) ;
+FUNCTION: c-string tclistval2 ( TCLIST* list, int index ) ;
 FUNCTION: void tclistpush ( TCLIST* list, void* ptr, int size ) ;
-FUNCTION: void tclistpush2 ( TCLIST* list, char* str ) ;
+FUNCTION: void tclistpush2 ( TCLIST* list, c-string str ) ;
 FUNCTION: void tcfree ( void* ptr ) ;
 
 TYPEDEF: void* TCCMP

From 71d169e42088b940fe025966309d31fe6f4ea976 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 11:56:10 -0800
Subject: [PATCH 210/250] fix typos in alien docs

---
 basis/alien/c-types/c-types-docs.factor | 2 +-
 core/alien/alien-docs.factor            | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/basis/alien/c-types/c-types-docs.factor b/basis/alien/c-types/c-types-docs.factor
index e73ce556b5..0bcb7b9401 100644
--- a/basis/alien/c-types/c-types-docs.factor
+++ b/basis/alien/c-types/c-types-docs.factor
@@ -103,7 +103,7 @@ HELP: ulonglong
 HELP: void
 { $description "This symbol is not a valid C type, but it can be used as the return type for a " { $link POSTPONE: FUNCTION: } " or " { $link POSTPONE: CALLBACK: } " definition or for an " { $link alien-invoke } " or " { $link alien-callback } " call." } ;
 HELP: void*
-{ $description "This C type represents a generic pointer to C memory. See " { $link pointer } " for information on pointer C types." }
+{ $description "This C type represents a generic pointer to C memory. See " { $link pointer } " for information on pointer C types." } ;
 HELP: c-string
 { $description "This C type represents a pointer to a C string. See " { $link "c-strings" } " for details about using strings with the FFI." } ;
 HELP: float
diff --git a/core/alien/alien-docs.factor b/core/alien/alien-docs.factor
index 0b4976fcbe..9389b24227 100644
--- a/core/alien/alien-docs.factor
+++ b/core/alien/alien-docs.factor
@@ -136,7 +136,7 @@ ARTICLE: "aliens" "Alien addresses"
 }
 "Anywhere that a " { $link alien } " instance is accepted, the " { $link f } " singleton may be passed in to denote a null pointer."
 $nl
-"Usually alien objects do not have to created and dereferenced directly; instead declaring C function parameters and return values as having a " pointer type such as " { $snippet "void*" } " takes care of the details."
+"Usually alien objects do not have to created and dereferenced directly; instead declaring C function parameters and return values as having a " { $link pointer } " type such as " { $snippet "void*" } " takes care of the details."
 { $subsections
     "syntax-aliens"
     "alien-expiry"

From db8b6baa2f14b0b9d6a55374664ea612d526fe53 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 11:59:53 -0800
Subject: [PATCH 211/250] typo in alien.parser test

---
 basis/alien/parser/parser-tests.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/alien/parser/parser-tests.factor b/basis/alien/parser/parser-tests.factor
index a730e3084f..26a71e9623 100644
--- a/basis/alien/parser/parser-tests.factor
+++ b/basis/alien/parser/parser-tests.factor
@@ -25,7 +25,7 @@ CONSTANT: eleven 11
     [ pointer: int*** ] [ "int****" parse-c-type ] unit-test
     [ c-string ] [ "c-string" parse-c-type ] unit-test
     [ char2 ] [ "char2" parse-c-type ] unit-test
-    [ c-string2 ] [ "char2*" parse-c-type ] unit-test
+    [ pointer: char2 ] [ "char2*" parse-c-type ] unit-test
 
     [ "not-word" parse-c-type ] [ error>> no-word-error? ] must-fail-with
 ] with-file-vocabs

From 1916b9269ea5d1162f7cb40944c18bca846a1d26 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 12:07:55 -0800
Subject: [PATCH 212/250] "pointer-c-type" word-prop hack is now unnecessary
 since all pointer types behave uniformly now

---
 basis/alien/c-types/c-types.factor | 20 ++------------------
 basis/alien/parser/parser.factor   |  1 -
 2 files changed, 2 insertions(+), 19 deletions(-)

diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor
index 73da41cc69..ef47f4b69c 100644
--- a/basis/alien/c-types/c-types.factor
+++ b/basis/alien/c-types/c-types.factor
@@ -223,22 +223,15 @@ MIXIN: value-type
         \ swap , [ heap-size , [ * >fixnum ] % ] [ % ] bi*
     ] [ ] make ;
 
-GENERIC: typedef ( old new -- )
-
 PREDICATE: typedef-word < c-type-word
     "c-type" word-prop c-type-name? ;
 
-M: word typedef ( old new -- )
+: typedef ( old new -- )
     {
         [ nip define-symbol ]
         [ swap "c-type" set-word-prop ]
     } 2cleave ;
 
-M: pointer typedef ( old new -- )
-    to>> dup c-type-word?
-    [ swap "pointer-c-type" set-word-prop ]
-    [ 2drop ] if ;
-
 TUPLE: long-long-type < c-type ;
 
 : <long-long-type> ( -- c-type )
@@ -298,12 +291,6 @@ CONSTANT: primitive-types
         pointer? [ drop void* ] when
     ] if ;
 
-: special-pointer-type ( type -- special-type )
-    dup c-type-word? [
-        dup "pointer-c-type" word-prop
-        [ ] [ "c-type" word-prop special-pointer-type ] ?if
-    ] [ drop f ] if ;
-
 : primitive-pointer-type? ( type -- ? )
     dup c-type-word? [
         resolve-pointer-typedef [ void? ] [ primitive-types member? ] bi or
@@ -313,10 +300,7 @@ PRIVATE>
 
 M: pointer c-type
     [ \ void* c-type ] dip
-    to>> dup special-pointer-type
-    [ nip ] [
-        dup primitive-pointer-type? [ drop ] [ (pointer-c-type) ] if
-    ] ?if ;
+    to>> dup primitive-pointer-type? [ drop ] [ (pointer-c-type) ] if ;
 
 : 8-byte-alignment ( c-type -- c-type )
     {
diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor
index f5fdced048..cf8c878589 100644
--- a/basis/alien/parser/parser.factor
+++ b/basis/alien/parser/parser.factor
@@ -41,7 +41,6 @@ IN: alien.parser
     [ dup [ forget-class ] [ { "struct-size" } reset-props ] bi ] when
     {
         "c-type"
-        "pointer-c-type"
         "callback-effect"
         "callback-library"
     } reset-props ;

From b45ec6397baf393d341d4be65ac9b07ca5f94181 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 12:20:47 -0800
Subject: [PATCH 213/250] typo in alien.data docs

---
 basis/alien/data/data-docs.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/alien/data/data-docs.factor b/basis/alien/data/data-docs.factor
index 895b8536f7..6ab6d56bc7 100644
--- a/basis/alien/data/data-docs.factor
+++ b/basis/alien/data/data-docs.factor
@@ -111,7 +111,7 @@ $nl
 { $subsections "byte-arrays-gc" }
 "C-style enumerated types are supported:"
 { $subsections POSTPONE: C-ENUM: }
-"C types can be aliased for convenience and consitency with native library documentation:"
+"C types can be aliased for convenience and consistency with native library documentation:"
 { $subsections POSTPONE: TYPEDEF: }
 "A utility for defining " { $link "destructors" } " for deallocating memory:"
 { $subsections "alien.destructors" }

From 125c680e2f1d0ad6f6497f4f4e0a7ab5452a9364 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 12:53:09 -0800
Subject: [PATCH 214/250] cairo.ffi, core-foundation.strings: change some
 functions that don't really expect strings to use char* instead of c-string
 (reported by Blei)

---
 basis/cairo/ffi/ffi.factor                   | 2 +-
 basis/core-foundation/strings/strings.factor | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/basis/cairo/ffi/ffi.factor b/basis/cairo/ffi/ffi.factor
index bca02c1f17..dc68af64dc 100644
--- a/basis/cairo/ffi/ffi.factor
+++ b/basis/cairo/ffi/ffi.factor
@@ -786,7 +786,7 @@ FUNCTION: int
 cairo_format_stride_for_width ( cairo_format_t format, int width ) ;
 
 FUNCTION: cairo_surface_t*
-cairo_image_surface_create_for_data ( c-string data, cairo_format_t format, int width, int height, int stride ) ;
+cairo_image_surface_create_for_data ( char* data, cairo_format_t format, int width, int height, int stride ) ;
 
 FUNCTION: c-string
 cairo_image_surface_get_data ( cairo_surface_t* surface ) ;
diff --git a/basis/core-foundation/strings/strings.factor b/basis/core-foundation/strings/strings.factor
index 9a91335ae2..4c7e9ba261 100644
--- a/basis/core-foundation/strings/strings.factor
+++ b/basis/core-foundation/strings/strings.factor
@@ -37,7 +37,7 @@ FUNCTION: void CFStringGetCharacters ( void* theString, CFIndex start, CFIndex l
 
 FUNCTION: Boolean CFStringGetCString (
     CFStringRef theString,
-    c-string buffer,
+    UInt8* buffer,
     CFIndex bufferSize,
     CFStringEncoding encoding
 ) ;
@@ -55,7 +55,7 @@ FUNCTION: CFIndex CFStringGetBytes (
 
 FUNCTION: CFStringRef CFStringCreateWithCString (
     CFAllocatorRef alloc,
-    c-string cStr,
+    UInt8* cStr,
     CFStringEncoding encoding
 ) ;
 

From db6c083162cd83687a75ace9dd8f451ed54e0b09 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 13:15:16 -0800
Subject: [PATCH 215/250] change back other char/uchar* parameters that don't
 look like actual string types

---
 basis/core-foundation/data/data.factor |  2 +-
 basis/iokit/hid/hid.factor             | 14 +++++++-------
 basis/windows/user32/user32.factor     |  2 +-
 basis/x11/xlib/xlib.factor             |  2 +-
 extra/libusb/libusb.factor             | 16 ++++++++--------
 extra/ogg/ogg.factor                   | 22 +++++++++++-----------
 extra/ogg/theora/theora.factor         |  2 +-
 7 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/basis/core-foundation/data/data.factor b/basis/core-foundation/data/data.factor
index 65d6d728c1..bb04431a0e 100644
--- a/basis/core-foundation/data/data.factor
+++ b/basis/core-foundation/data/data.factor
@@ -12,7 +12,7 @@ CONSTANT: kCFPropertyListImmutable 0
 CONSTANT: kCFPropertyListMutableContainers 1
 CONSTANT: kCFPropertyListMutableContainersAndLeaves 2
 
-FUNCTION: CFDataRef CFDataCreate ( CFAllocatorRef allocator, c-string bytes, CFIndex length ) ;
+FUNCTION: CFDataRef CFDataCreate ( CFAllocatorRef allocator, UInt8* bytes, CFIndex length ) ;
 
 FUNCTION: CFTypeID CFGetTypeID ( CFTypeRef cf ) ;
 
diff --git a/basis/iokit/hid/hid.factor b/basis/iokit/hid/hid.factor
index bd3fc1e968..a2ac0d5e6f 100644
--- a/basis/iokit/hid/hid.factor
+++ b/basis/iokit/hid/hid.factor
@@ -132,7 +132,7 @@ TYPEDEF: UInt32 IOHIDValueScaleType
 TYPEDEF: UInt32 IOHIDTransactionDirectionType
 
 CALLBACK: void IOHIDCallback ( void* context, IOReturn result, void* sender ) ;
-CALLBACK: void IOHIDReportCallback ( void* context, IOReturn result, void* sender, IOHIDReportType type, UInt32 reportID, c-string report, CFIndex reportLength ) ;
+CALLBACK: void IOHIDReportCallback ( void* context, IOReturn result, void* sender, IOHIDReportType type, UInt32 reportID, uchar* report, CFIndex reportLength ) ;
 CALLBACK: void IOHIDValueCallback ( void* context, IOReturn result, void* sender, IOHIDValueRef value ) ;
 CALLBACK: void IOHIDValueMultipleCallback ( void* context, IOReturn result, void* sender, CFDictionaryRef multiple ) ;
 CALLBACK: void IOHIDDeviceCallback ( void* context, IOReturn result, void* sender, IOHIDDeviceRef device ) ;
@@ -151,7 +151,7 @@ FUNCTION: void IOHIDDeviceScheduleWithRunLoop ( IOHIDDeviceRef device, CFRunLoop
 FUNCTION: void IOHIDDeviceUnscheduleFromRunLoop ( IOHIDDeviceRef device, CFRunLoopRef runLoop, CFStringRef runLoopMode ) ;
 FUNCTION: void IOHIDDeviceRegisterRemovalCallback ( IOHIDDeviceRef device, IOHIDCallback callback, void* context ) ;
 FUNCTION: void IOHIDDeviceRegisterInputValueCallback ( IOHIDDeviceRef device, IOHIDValueCallback callback, void* context ) ;
-FUNCTION: void IOHIDDeviceRegisterInputReportCallback ( IOHIDDeviceRef device, c-string report, CFIndex reportLength, IOHIDReportCallback callback, void* context ) ;
+FUNCTION: void IOHIDDeviceRegisterInputReportCallback ( IOHIDDeviceRef device, uchar* report, CFIndex reportLength, IOHIDReportCallback callback, void* context ) ;
 FUNCTION: void IOHIDDeviceSetInputValueMatching ( IOHIDDeviceRef device, CFDictionaryRef matching ) ;
 FUNCTION: void IOHIDDeviceSetInputValueMatchingMultiple ( IOHIDDeviceRef device, CFArrayRef multiple ) ;
 FUNCTION: IOReturn IOHIDDeviceSetValue ( IOHIDDeviceRef device, IOHIDElementRef element, IOHIDValueRef value ) ;
@@ -162,10 +162,10 @@ FUNCTION: IOReturn IOHIDDeviceGetValue ( IOHIDDeviceRef device, IOHIDElementRef
 FUNCTION: IOReturn IOHIDDeviceCopyValueMultiple ( IOHIDDeviceRef device, CFArrayRef elements, CFDictionaryRef* pMultiple ) ;
 FUNCTION: IOReturn IOHIDDeviceGetValueWithCallback ( IOHIDDeviceRef device, IOHIDElementRef element, IOHIDValueRef* pValue, CFTimeInterval timeout, IOHIDValueCallback callback, void* context ) ;
 FUNCTION: IOReturn IOHIDDeviceCopyValueMultipleWithCallback ( IOHIDDeviceRef device, CFArrayRef elements, CFDictionaryRef* pMultiple, CFTimeInterval timeout, IOHIDValueMultipleCallback callback, void* context ) ;
-FUNCTION: IOReturn IOHIDDeviceSetReport ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, c-string report, CFIndex reportLength ) ;
-FUNCTION: IOReturn IOHIDDeviceSetReportWithCallback ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, c-string report, CFIndex reportLength, CFTimeInterval timeout, IOHIDReportCallback callback, void* context ) ;
-FUNCTION: IOReturn IOHIDDeviceGetReport ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, c-string report, CFIndex* pReportLength ) ;
-FUNCTION: IOReturn IOHIDDeviceGetReportWithCallback ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, c-string report, CFIndex* pReportLength, CFTimeInterval timeout, IOHIDReportCallback callback, void* context ) ;
+FUNCTION: IOReturn IOHIDDeviceSetReport ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, char* report, CFIndex reportLength ) ;
+FUNCTION: IOReturn IOHIDDeviceSetReportWithCallback ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, char* report, CFIndex reportLength, CFTimeInterval timeout, IOHIDReportCallback callback, void* context ) ;
+FUNCTION: IOReturn IOHIDDeviceGetReport ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, char* report, CFIndex* pReportLength ) ;
+FUNCTION: IOReturn IOHIDDeviceGetReportWithCallback ( IOHIDDeviceRef device, IOHIDReportType reportType, CFIndex reportID, char* report, CFIndex* pReportLength, CFTimeInterval timeout, IOHIDReportCallback callback, void* context ) ;
 
 ! IOHIDManager
 
@@ -231,7 +231,7 @@ FUNCTION: IOHIDValueRef IOHIDValueCreateWithBytesNoCopy ( CFAllocatorRef allocat
 FUNCTION: IOHIDElementRef IOHIDValueGetElement ( IOHIDValueRef value ) ;
 FUNCTION: ulonglong IOHIDValueGetTimeStamp ( IOHIDValueRef value ) ;
 FUNCTION: CFIndex IOHIDValueGetLength ( IOHIDValueRef value ) ;
-FUNCTION: c-string IOHIDValueGetBytePtr ( IOHIDValueRef value ) ;
+FUNCTION: uchar* IOHIDValueGetBytePtr ( IOHIDValueRef value ) ;
 FUNCTION: CFIndex IOHIDValueGetIntegerValue ( IOHIDValueRef value ) ;
 FUNCTION: double IOHIDValueGetScaledValue ( IOHIDValueRef value, IOHIDValueScaleType type ) ;
 
diff --git a/basis/windows/user32/user32.factor b/basis/windows/user32/user32.factor
index a966b63308..9908bb1f1b 100644
--- a/basis/windows/user32/user32.factor
+++ b/basis/windows/user32/user32.factor
@@ -1352,7 +1352,7 @@ ALIAS: GetWindowLong GetWindowLongW
 FUNCTION: BOOL GetWindowRect ( HWND hWnd, LPRECT lpRect ) ;
 ! FUNCTION: GetWindowRgn
 ! FUNCTION: GetWindowRgnBox
-FUNCTION: int GetWindowTextA ( HWND hWnd, c-string lpString, int nMaxCount ) ;
+FUNCTION: int GetWindowTextA ( HWND hWnd, char* lpString, int nMaxCount ) ;
 ! FUNCTION: GetWindowTextLengthA
 ! FUNCTION: GetWindowTextLengthW
 ! FUNCTION: GetWindowTextW
diff --git a/basis/x11/xlib/xlib.factor b/basis/x11/xlib/xlib.factor
index 88b058abea..de01d509dd 100644
--- a/basis/x11/xlib/xlib.factor
+++ b/basis/x11/xlib/xlib.factor
@@ -464,7 +464,7 @@ STRUCT: XImage
 { height int }
 { xoffset int }
 { format int }
-{ data c-string }
+{ data uchar* }
 { byte_order int }
 { bitmap_unit int }
 { bitmap_bit_order int }
diff --git a/extra/libusb/libusb.factor b/extra/libusb/libusb.factor
index 38bf49ed5b..d521015d6f 100644
--- a/extra/libusb/libusb.factor
+++ b/extra/libusb/libusb.factor
@@ -128,7 +128,7 @@ STRUCT: libusb_endpoint_descriptor
     { bInterval         uint8_t  }
     { bRefresh          uint8_t  }
     { bSynchAddress     uint8_t  }
-    { extra             c-string   }
+    { extra             uchar*   }
     { extra_length      int      } ;
 
 STRUCT: libusb_interface_descriptor
@@ -142,7 +142,7 @@ STRUCT: libusb_interface_descriptor
     { bInterfaceProtocol  uint8_t                     }
     { iInterface          uint8_t                     }
     { endpoint            libusb_endpoint_descriptor* }
-    { extra               c-string                      }
+    { extra               uchar*                      }
     { extra_length        int                         } ;
 
 STRUCT: libusb_interface
@@ -159,7 +159,7 @@ STRUCT: libusb_config_descriptor
     { bmAttributes         uint8_t           }
     { MaxPower             uint8_t           }
     { interface            libusb_interface* }
-    { extra                c-string            }
+    { extra                uchar*            }
     { extra_length         int               } ;
 
 STRUCT: libusb_control_setup
@@ -227,7 +227,7 @@ STRUCT: libusb_transfer
     { actual_length   int                             }
     { callback        libusb_transfer_cb_fn           }
     { user_data       void*                           }
-    { buffer          c-string                          }
+    { buffer          uchar*                          }
     { num_iso_packets int                             }
     { iso_packet_desc libusb_iso_packet_descriptor[0] } ;
 
@@ -370,14 +370,14 @@ FUNCTION: void libusb_free_transfer ( libusb_transfer* transfer ) ;
 
 FUNCTION: int libusb_control_transfer ( libusb_device_handle* dev_handle,
     uint8_t request_type, uint8_t request, uint16_t value, uint16_t index,
-    c-string data, uint16_t length, uint timeout ) ;
+    uchar* data, uint16_t length, uint timeout ) ;
 
 FUNCTION: int libusb_bulk_transfer ( libusb_device_handle* dev_handle,
-    uchar endpoint, c-string data, int length,
+    uchar endpoint, uchar* data, int length,
     int* actual_length, uint timeout ) ;
 
 FUNCTION: int libusb_interrupt_transfer ( libusb_device_handle* dev_handle,
-    uchar endpoint, c-string data, int length,
+    uchar endpoint, uchar* data, int length,
     int* actual_length, int timeout ) ;
 
 :: libusb_get_descriptor ( dev desc_type desc_index data length -- int )
@@ -392,7 +392,7 @@ FUNCTION: int libusb_interrupt_transfer ( libusb_device_handle* dev_handle,
 
 FUNCTION: int libusb_get_string_descriptor_ascii ( libusb_device_handle* dev,
                                                    uint8_t               index,
-                                                   c-string                data,
+                                                   uchar*                data,
                                                    int                   length ) ;
 
 FUNCTION: int libusb_try_lock_events ( libusb_context* ctx ) ;
diff --git a/extra/ogg/ogg.factor b/extra/ogg/ogg.factor
index ed25740ff6..d7abece8bc 100644
--- a/extra/ogg/ogg.factor
+++ b/extra/ogg/ogg.factor
@@ -28,18 +28,18 @@ LIBRARY: ogg
 STRUCT: oggpack-buffer
     { endbyte long }
     { endbit int   }
-    { buffer c-string }
-    { ptr c-string }
+    { buffer uchar* }
+    { ptr uchar* }
     { storage long } ;
 
 STRUCT: ogg-page
-    {  header c-string }
+    {  header uchar* }
     {  header_len long }
-    {  body c-string }
+    {  body uchar* }
     {  body_len long } ;
 
 STRUCT: ogg-stream-state
-    {  body_data c-string }
+    {  body_data uchar* }
     {  body_storage long }
     {  body_fill long }
     {  body_returned long }
@@ -59,7 +59,7 @@ STRUCT: ogg-stream-state
     {  granulepos longlong } ;
 
 STRUCT: ogg-packet
-    {  packet c-string }
+    {  packet uchar* }
     {  bytes long }
     {  b_o_s long }
     {  e_o_s long }
@@ -67,7 +67,7 @@ STRUCT: ogg-packet
     {  packetno longlong } ;
 
 STRUCT: ogg-sync-state
-    { data c-string }
+    { data uchar* }
     { storage int }
     { fill int }  
     { returned int }
@@ -81,7 +81,7 @@ FUNCTION: void  oggpack_writealign ( oggpack-buffer* b) ;
 FUNCTION: void  oggpack_writecopy ( oggpack-buffer* b, void* source, long bits ) ;
 FUNCTION: void  oggpack_reset ( oggpack-buffer* b ) ;
 FUNCTION: void  oggpack_writeclear ( oggpack-buffer* b ) ;
-FUNCTION: void  oggpack_readinit ( oggpack-buffer* b, c-string buf, int bytes ) ;
+FUNCTION: void  oggpack_readinit ( oggpack-buffer* b, uchar* buf, int bytes ) ;
 FUNCTION: void  oggpack_write ( oggpack-buffer* b, ulong value, int bits ) ;
 FUNCTION: long  oggpack_look ( oggpack-buffer* b, int bits ) ;
 FUNCTION: long  oggpack_look1 ( oggpack-buffer* b ) ;
@@ -91,14 +91,14 @@ FUNCTION: long  oggpack_read ( oggpack-buffer* b, int bits ) ;
 FUNCTION: long  oggpack_read1 ( oggpack-buffer* b ) ;
 FUNCTION: long  oggpack_bytes ( oggpack-buffer* b ) ;
 FUNCTION: long  oggpack_bits ( oggpack-buffer* b ) ;
-FUNCTION: c-string oggpack_get_buffer ( oggpack-buffer* b ) ;
+FUNCTION: uchar* oggpack_get_buffer ( oggpack-buffer* b ) ;
 FUNCTION: void  oggpackB_writeinit ( oggpack-buffer* b ) ;
 FUNCTION: void  oggpackB_writetrunc ( oggpack-buffer* b, long bits ) ;
 FUNCTION: void  oggpackB_writealign ( oggpack-buffer* b ) ;
 FUNCTION: void  oggpackB_writecopy ( oggpack-buffer* b, void* source, long bits ) ;
 FUNCTION: void  oggpackB_reset ( oggpack-buffer* b ) ;
 FUNCTION: void  oggpackB_writeclear ( oggpack-buffer* b ) ;
-FUNCTION: void  oggpackB_readinit ( oggpack-buffer* b, c-string buf, int bytes ) ;
+FUNCTION: void  oggpackB_readinit ( oggpack-buffer* b, uchar* buf, int bytes ) ;
 FUNCTION: void  oggpackB_write ( oggpack-buffer* b, ulong value, int bits ) ;
 FUNCTION: long  oggpackB_look ( oggpack-buffer* b, int bits ) ;
 FUNCTION: long  oggpackB_look1 ( oggpack-buffer* b ) ;
@@ -108,7 +108,7 @@ FUNCTION: long  oggpackB_read ( oggpack-buffer* b, int bits ) ;
 FUNCTION: long  oggpackB_read1 ( oggpack-buffer* b ) ;
 FUNCTION: long  oggpackB_bytes ( oggpack-buffer* b ) ;
 FUNCTION: long  oggpackB_bits ( oggpack-buffer* b ) ;
-FUNCTION: c-string oggpackB_get_buffer ( oggpack-buffer* b ) ;
+FUNCTION: uchar* oggpackB_get_buffer ( oggpack-buffer* b ) ;
 FUNCTION: int      ogg_stream_packetin ( ogg-stream-state* os, ogg-packet* op ) ;
 FUNCTION: int      ogg_stream_pageout ( ogg-stream-state* os, ogg-page* og ) ;
 FUNCTION: int      ogg_stream_flush ( ogg-stream-state* os, ogg-page* og ) ;
diff --git a/extra/ogg/theora/theora.factor b/extra/ogg/theora/theora.factor
index 3e28129252..eb79613496 100644
--- a/extra/ogg/theora/theora.factor
+++ b/extra/ogg/theora/theora.factor
@@ -53,7 +53,7 @@ STRUCT: th-img-plane
     { width int }
     { height int }
     { stride int }
-    { data c-string }
+    { data uchar* }
 ;
 
 TYPEDEF: th-img-plane[3] th-ycbcr-buffer

From 211004f7e0a82daa5b2d8cbaf637d68538219afb Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 13:27:18 -0800
Subject: [PATCH 216/250] add missing USING: effects.parser to descriptive,
 set-n

---
 extra/descriptive/descriptive.factor | 2 +-
 extra/set-n/set-n.factor             | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/extra/descriptive/descriptive.factor b/extra/descriptive/descriptive.factor
index 0756c5c975..5c6b5028f8 100644
--- a/extra/descriptive/descriptive.factor
+++ b/extra/descriptive/descriptive.factor
@@ -3,7 +3,7 @@
 USING: words kernel sequences locals locals.parser fry
 locals.definitions accessors parser namespaces continuations
 summary definitions generalizations arrays prettyprint debugger io
-effects tools.annotations ;
+effects tools.annotations effects.parser ;
 IN: descriptive
 
 ERROR: descriptive-error args underlying word ;
diff --git a/extra/set-n/set-n.factor b/extra/set-n/set-n.factor
index 80d8bf2246..0807b76b5c 100644
--- a/extra/set-n/set-n.factor
+++ b/extra/set-n/set-n.factor
@@ -1,5 +1,5 @@
 USING: accessors assocs fry generalizations kernel locals math
-namespaces parser sequences shuffle words ;
+namespaces parser sequences shuffle words effects.parser ;
 IN: set-n
 : get* ( var n -- val ) namestack dup length rot - head assoc-stack ;
 

From 0975b9a268cda8012140f176680e564b95da90ed Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 14:02:55 -0800
Subject: [PATCH 217/250] missed a uchar* in cairo.ffi

---
 basis/cairo/ffi/ffi.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/basis/cairo/ffi/ffi.factor b/basis/cairo/ffi/ffi.factor
index dc68af64dc..c4700d2dad 100644
--- a/basis/cairo/ffi/ffi.factor
+++ b/basis/cairo/ffi/ffi.factor
@@ -788,7 +788,7 @@ cairo_format_stride_for_width ( cairo_format_t format, int width ) ;
 FUNCTION: cairo_surface_t*
 cairo_image_surface_create_for_data ( char* data, cairo_format_t format, int width, int height, int stride ) ;
 
-FUNCTION: c-string
+FUNCTION: uchar*
 cairo_image_surface_get_data ( cairo_surface_t* surface ) ;
 
 FUNCTION: cairo_format_t

From f6183703b29e015710b2d3396d744b02ae036663 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 19:28:57 -0800
Subject: [PATCH 218/250] ui: add a "system-alert" hook that can raise a system
 modal dialog without involving any potentially stripped gadget, io, or
 debugger code

---
 basis/cocoa/cocoa.factor                |  1 +
 basis/ui/backend/cocoa/cocoa.factor     | 10 ++++++++++
 basis/ui/backend/windows/windows.factor |  3 +++
 basis/ui/backend/x11/x11.factor         | 12 ++++++++++++
 basis/ui/ui.factor                      |  2 ++
 5 files changed, 28 insertions(+)

diff --git a/basis/cocoa/cocoa.factor b/basis/cocoa/cocoa.factor
index 34bac0a505..fb21843c0f 100644
--- a/basis/cocoa/cocoa.factor
+++ b/basis/cocoa/cocoa.factor
@@ -39,6 +39,7 @@ SYNTAX: IMPORT: scan [ ] import-objc-class ;
 
 [
     {
+        "NSAlert"
         "NSApplication"
         "NSArray"
         "NSAutoreleasePool"
diff --git a/basis/ui/backend/cocoa/cocoa.factor b/basis/ui/backend/cocoa/cocoa.factor
index 8eeca89c2f..6e64c35e49 100644
--- a/basis/ui/backend/cocoa/cocoa.factor
+++ b/basis/ui/backend/cocoa/cocoa.factor
@@ -213,6 +213,16 @@ M: cocoa-ui-backend offscreen-pixels ( world -- alien w h )
 M: cocoa-ui-backend beep ( -- )
     NSBeep ;
 
+M: cocoa-ui-backend system-alert
+    NSAlert -> alloc -> init -> autorelease [
+        {
+            [ swap <NSString> -> setInformativeText: ]
+            [ swap <NSString> -> setMessageText: ]
+            [ "OK" <NSString> -> addButtonWithTitle: drop ]
+            [ -> runModal drop ]
+        } cleave
+    ] [ 2drop ] if* ;
+
 CLASS: {
     { +superclass+ "NSObject" }
     { +name+ "FactorApplicationDelegate" }
diff --git a/basis/ui/backend/windows/windows.factor b/basis/ui/backend/windows/windows.factor
index 69b09dcba0..5863d3f39d 100644
--- a/basis/ui/backend/windows/windows.factor
+++ b/basis/ui/backend/windows/windows.factor
@@ -783,6 +783,9 @@ M: windows-ui-backend (with-ui)
 M: windows-ui-backend beep ( -- )
     0 MessageBeep drop ;
 
+M: windows-ui-backend system-alert
+    [ f ] 2dip swap MB_OK MessageBox drop ;
+
 : fullscreen-RECT ( hwnd -- RECT )
     MONITOR_DEFAULTTONEAREST MonitorFromWindow
     MONITORINFOEX <struct>
diff --git a/basis/ui/backend/x11/x11.factor b/basis/ui/backend/x11/x11.factor
index 74d911ef90..ee6eb813b0 100644
--- a/basis/ui/backend/x11/x11.factor
+++ b/basis/ui/backend/x11/x11.factor
@@ -8,6 +8,7 @@ strings ui ui.backend ui.clipboards ui.event-loop ui.gadgets
 ui.gadgets.private ui.gadgets.worlds ui.gestures ui.pixel-formats
 ui.pixel-formats.private ui.private x11 x11.clipboard x11.constants
 x11.events x11.glx x11.io x11.windows x11.xim x11.xlib ;
+FROM: unix.ffi => system ;
 IN: ui.backend.x11
 
 SINGLETON: x11-ui-backend
@@ -326,6 +327,17 @@ M: x11-ui-backend (with-ui) ( quot -- )
 M: x11-ui-backend beep ( -- )
     dpy get 100 XBell drop ;
 
+<PRIVATE
+: escape-' ( string -- string' )
+    [ dup CHAR: ' = [ drop "'\''" ] [ 1string ] if ] { } map-as concat ;
+
+: xmessage ( string -- )
+    escape-' "/usr/X11R6/bin/xmessage '" "'" surround system ;
+PRIVATE>
+
+M: x11-ui-backend system-alert
+    "\n\n" glue xmessage ;
+
 : black ( -- xcolor ) 0 0 0 0 0 0 XColor <struct-boa> ; inline
 
 M:: x11-ui-backend (grab-input) ( handle -- )
diff --git a/basis/ui/ui.factor b/basis/ui/ui.factor
index e0fa560935..824ffb8351 100644
--- a/basis/ui/ui.factor
+++ b/basis/ui/ui.factor
@@ -243,6 +243,8 @@ M: object close-window
 
 HOOK: beep ui-backend ( -- )
 
+HOOK: system-alert ui-backend ( caption text -- )
+
 : parse-main-window-attributes ( class -- attributes )
     "{" expect dup all-slots parse-tuple-literal-slots ;
 

From cdc17e38e85cef6046d71114f5162faa6d1137cc Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 20:29:31 -0800
Subject: [PATCH 219/250] opengl.gl: all those GLchar* should be
 c-string[ascii]

---
 basis/opengl/gl/gl.factor | 42 +++++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/basis/opengl/gl/gl.factor b/basis/opengl/gl/gl.factor
index 7652720f1a..58039558d7 100644
--- a/basis/opengl/gl/gl.factor
+++ b/basis/opengl/gl/gl.factor
@@ -4,7 +4,7 @@
 ! This file is based on the gl.h that comes with xorg-x11 6.8.2
 
 USING: alien alien.c-types alien.syntax combinators kernel parser
-sequences system words opengl.gl.extensions ;
+sequences system words opengl.gl.extensions io.encodings.ascii ;
 FROM: alien.c-types => short ;
 IN: opengl.gl
 
@@ -24,6 +24,8 @@ TYPEDEF: double  GLdouble
 TYPEDEF: double  GLclampd
 C-TYPE: GLvoid
 
+TYPEDEF: c-string[ascii] GLstring
+
 ! Constants
 
 ! Boolean values
@@ -668,7 +670,7 @@ FUNCTION: void glPopClientAttrib ( ) ;
 
 FUNCTION: GLint glRenderMode ( GLenum mode ) ;
 FUNCTION: GLenum glGetError ( ) ;
-FUNCTION: c-string glGetString ( GLenum name ) ;
+FUNCTION: GLstring glGetString ( GLenum name ) ;
 FUNCTION: void glFinish ( ) ;
 FUNCTION: void glFlush ( ) ;
 FUNCTION: void glHint ( GLenum target, GLenum mode ) ;
@@ -1587,10 +1589,8 @@ CONSTANT: GL_STENCIL_BACK_VALUE_MASK HEX: 8CA4
 CONSTANT: GL_STENCIL_BACK_WRITEMASK HEX: 8CA5
 ALIAS: GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION
 
-TYPEDEF: char GLchar
-
 GL-FUNCTION: void glAttachShader { glAttachObjectARB } ( GLuint program, GLuint shader ) ;
-GL-FUNCTION: void glBindAttribLocation { glBindAttribLocationARB } ( GLuint program, GLuint index, GLchar* name ) ;
+GL-FUNCTION: void glBindAttribLocation { glBindAttribLocationARB } ( GLuint program, GLuint index, GLstring name ) ;
 GL-FUNCTION: void glBlendEquationSeparate { glBlendEquationSeparateEXT } ( GLenum modeRGB, GLenum modeAlpha ) ;
 GL-FUNCTION: void glCompileShader { glCompileShaderARB } ( GLuint shader ) ;
 GL-FUNCTION: GLuint glCreateProgram { glCreateProgramObjectARB } (  ) ;
@@ -1601,16 +1601,16 @@ GL-FUNCTION: void glDetachShader { glDetachObjectARB } ( GLuint program, GLuint
 GL-FUNCTION: void glDisableVertexAttribArray { glDisableVertexAttribArrayARB } ( GLuint index ) ;
 GL-FUNCTION: void glDrawBuffers { glDrawBuffersARB glDrawBuffersATI } ( GLsizei n, GLenum* bufs ) ;
 GL-FUNCTION: void glEnableVertexAttribArray { glEnableVertexAttribArrayARB } ( GLuint index ) ;
-GL-FUNCTION: void glGetActiveAttrib { glGetActiveAttribARB } ( GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name ) ;
-GL-FUNCTION: void glGetActiveUniform { glGetActiveUniformARB } ( GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name ) ;
+GL-FUNCTION: void glGetActiveAttrib { glGetActiveAttribARB } ( GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLstring name ) ;
+GL-FUNCTION: void glGetActiveUniform { glGetActiveUniformARB } ( GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLstring name ) ;
 GL-FUNCTION: void glGetAttachedShaders { glGetAttachedObjectsARB } ( GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders ) ;
-GL-FUNCTION: GLint glGetAttribLocation { glGetAttribLocationARB } ( GLuint program, GLchar* name ) ;
-GL-FUNCTION: void glGetProgramInfoLog { glGetInfoLogARB } ( GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog ) ;
+GL-FUNCTION: GLint glGetAttribLocation { glGetAttribLocationARB } ( GLuint program, GLstring name ) ;
+GL-FUNCTION: void glGetProgramInfoLog { glGetInfoLogARB } ( GLuint program, GLsizei bufSize, GLsizei* length, GLstring infoLog ) ;
 GL-FUNCTION: void glGetProgramiv { glGetObjectParameterivARB } ( GLuint program, GLenum pname, GLint* param ) ;
-GL-FUNCTION: void glGetShaderInfoLog { glGetInfoLogARB } ( GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog ) ;
-GL-FUNCTION: void glGetShaderSource { glGetShaderSourceARB } ( GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source ) ;
+GL-FUNCTION: void glGetShaderInfoLog { glGetInfoLogARB } ( GLuint shader, GLsizei bufSize, GLsizei* length, GLstring infoLog ) ;
+GL-FUNCTION: void glGetShaderSource { glGetShaderSourceARB } ( GLint obj, GLsizei maxLength, GLsizei* length, GLstring source ) ;
 GL-FUNCTION: void glGetShaderiv { glGetObjectParameterivARB } ( GLuint shader, GLenum pname, GLint* param ) ;
-GL-FUNCTION: GLint glGetUniformLocation { glGetUniformLocationARB } ( GLint programObj, GLchar* name ) ;
+GL-FUNCTION: GLint glGetUniformLocation { glGetUniformLocationARB } ( GLint programObj, GLstring name ) ;
 GL-FUNCTION: void glGetUniformfv { glGetUniformfvARB } ( GLuint program, GLint location, GLfloat* params ) ;
 GL-FUNCTION: void glGetUniformiv { glGetUniformivARB } ( GLuint program, GLint location, GLint* params ) ;
 GL-FUNCTION: void glGetVertexAttribPointerv { glGetVertexAttribPointervARB } ( GLuint index, GLenum pname, GLvoid** pointer ) ;
@@ -1620,7 +1620,7 @@ GL-FUNCTION: void glGetVertexAttribiv { glGetVertexAttribivARB } ( GLuint index,
 GL-FUNCTION: GLboolean glIsProgram { glIsProgramARB } ( GLuint program ) ;
 GL-FUNCTION: GLboolean glIsShader { glIsShaderARB } ( GLuint shader ) ;
 GL-FUNCTION: void glLinkProgram { glLinkProgramARB } ( GLuint program ) ;
-GL-FUNCTION: void glShaderSource { glShaderSourceARB } ( GLuint shader, GLsizei count, GLchar** strings, GLint* lengths ) ;
+GL-FUNCTION: void glShaderSource { glShaderSourceARB } ( GLuint shader, GLsizei count, GLstring* strings, GLint* lengths ) ;
 GL-FUNCTION: void glStencilFuncSeparate { glStencilFuncSeparateATI } ( GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask ) ;
 GL-FUNCTION: void glStencilMaskSeparate { } ( GLenum face, GLuint mask ) ;
 GL-FUNCTION: void glStencilOpSeparate { glStencilOpSeparateATI } ( GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass ) ;
@@ -1991,8 +1991,8 @@ GL-FUNCTION: void glUniform4uiv { glUniform4uivEXT } ( GLint location, GLsizei c
 
 GL-FUNCTION: void glGetUniformuiv { glGetUniformuivEXT } ( GLuint program, GLint location, GLuint* params ) ;
 
-GL-FUNCTION: void glBindFragDataLocation { glBindFragDataLocationEXT } ( GLuint program, GLuint colorNumber, GLchar* name ) ;
-GL-FUNCTION: GLint glGetFragDataLocation { glGetFragDataLocationEXT } ( GLuint program, GLchar* name ) ;
+GL-FUNCTION: void glBindFragDataLocation { glBindFragDataLocationEXT } ( GLuint program, GLuint colorNumber, GLstring name ) ;
+GL-FUNCTION: GLint glGetFragDataLocation { glGetFragDataLocationEXT } ( GLuint program, GLstring name ) ;
 
 GL-FUNCTION: void glBeginConditionalRender { glBeginConditionalRenderNV } ( GLuint id, GLenum mode ) ;
 GL-FUNCTION: void glEndConditionalRender { glEndConditionalRenderNV } ( ) ;
@@ -2061,10 +2061,10 @@ GL-FUNCTION: void glBeginTransformFeedback { glBeginTransformFeedbackEXT } ( GLe
 GL-FUNCTION: void glEndTransformFeedback { glEndTransformFeedbackEXT } ( ) ;
 
 GL-FUNCTION: void glTransformFeedbackVaryings { glTransformFeedbackVaryingsEXT } ( GLuint program, GLsizei count,
-                                      GLchar** varyings, GLenum bufferMode ) ;
+                                      GLstring* varyings, GLenum bufferMode ) ;
 GL-FUNCTION: void glGetTransformFeedbackVarying { glGetTransformFeedbackVaryingEXT } ( GLuint program, GLuint index,
                                         GLsizei bufSize, GLsizei* length, 
-                                        GLsizei* size, GLenum* type, GLchar* name ) ;
+                                        GLsizei* size, GLenum* type, GLstring name ) ;
 
 GL-FUNCTION: void glClearBufferiv  { } ( GLenum buffer, GLint drawbuffer, GLint* value ) ;
 GL-FUNCTION: void glClearBufferuiv { } ( GLenum buffer, GLint drawbuffer, GLuint* value ) ;
@@ -2156,12 +2156,12 @@ GL-FUNCTION: void glDrawElementsInstanced { glDrawElementsInstancedARB } ( GLenu
 GL-FUNCTION: void glTexBuffer { glTexBufferEXT } ( GLenum target, GLenum internalformat, GLuint buffer ) ;
 GL-FUNCTION: void glPrimitiveRestartIndex { } ( GLuint index ) ;
 
-GL-FUNCTION: void glGetUniformIndices { } ( GLuint program, GLsizei uniformCount, GLchar** uniformNames, GLuint* uniformIndices ) ;
+GL-FUNCTION: void glGetUniformIndices { } ( GLuint program, GLsizei uniformCount, GLstring* uniformNames, GLuint* uniformIndices ) ;
 GL-FUNCTION: void glGetActiveUniformsiv { } ( GLuint program, GLsizei uniformCount, GLuint* uniformIndices, GLenum pname, GLint* params ) ;
-GL-FUNCTION: void glGetActiveUniformName { } ( GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformName ) ;
-GL-FUNCTION: GLuint glGetUniformBlockIndex { } ( GLuint program, GLchar* uniformBlockName ) ;
+GL-FUNCTION: void glGetActiveUniformName { } ( GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, GLstring uniformName ) ;
+GL-FUNCTION: GLuint glGetUniformBlockIndex { } ( GLuint program, GLstring uniformBlockName ) ;
 GL-FUNCTION: void glGetActiveUniformBlockiv { } ( GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params ) ;
-GL-FUNCTION: void glGetActiveUniformBlockName { } ( GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformName ) ;
+GL-FUNCTION: void glGetActiveUniformBlockName { } ( GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLstring uniformName ) ;
 GL-FUNCTION: void glUniformBlockBinding { } ( GLuint buffer, GLuint uniformBlockIndex, GLuint uniformBlockBinding ) ;
 
 GL-FUNCTION: void glCopyBufferSubData { glCopyBufferSubDataEXT } ( GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size ) ;

From 0eb6355827574f78391cacae19f2fcc2976c057f Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 20:29:51 -0800
Subject: [PATCH 220/250] document system-alert

---
 basis/ui/ui-docs.factor | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/basis/ui/ui-docs.factor b/basis/ui/ui-docs.factor
index b55ea44c6b..b2f97857f6 100644
--- a/basis/ui/ui-docs.factor
+++ b/basis/ui/ui-docs.factor
@@ -81,6 +81,11 @@ HELP: with-ui
 HELP: beep
 { $description "Plays the system beep sound." } ;
 
+HELP: system-alert
+{ $values { "caption" string } { "text" string } }
+{ $description "Displays an application-modal alert dialog box with the given caption and text." }
+{ $notes "Since the window raised by this word is modal, all processing in all Factor threads will halt until the dialog is dismissed. In an application that makes full use of the UI framework, it would be more appropriate to display a pane gadget in a Factor window. This word is meant primarily to be used to display errors in deployed applications with minimal dependencies on the UI library, such as games." } ;
+
 HELP: topmost-window
 { $values { "world" world } }
 { $description "Returns the " { $link world } " representing the currently focused window." } ;

From 32b42185e6aecc530aa7f960bf1fac8ff6652794 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 20:42:36 -0800
Subject: [PATCH 221/250] tools.deploy.shaker: raise a generic "This
 application died" system-alert instead of quietly crashing and burning in the
 ui-error-hook for deployed apps with the debugger stripped

---
 basis/tools/deploy/shaker/shaker.factor              | 12 ++++++++----
 basis/tools/deploy/shaker/strip-ui-error-hook.factor |  7 +++++++
 2 files changed, 15 insertions(+), 4 deletions(-)
 create mode 100644 basis/tools/deploy/shaker/strip-ui-error-hook.factor

diff --git a/basis/tools/deploy/shaker/shaker.factor b/basis/tools/deploy/shaker/shaker.factor
index 09219a8e5e..9a5f89fae0 100755
--- a/basis/tools/deploy/shaker/shaker.factor
+++ b/basis/tools/deploy/shaker/shaker.factor
@@ -62,6 +62,13 @@ IN: tools.deploy.shaker
         run-file
     ] when ;
 
+: strip-ui-error-hook ( -- )
+    strip-debugger? deploy-ui? get and "ui" vocab and [
+        "Installing generic UI error hook" show
+        "vocab:tools/deploy/shaker/strip-ui-error-hook.factor"
+        run-file
+    ] when ;
+
 : strip-libc ( -- )
     "libc" vocab [
         "Stripping manual memory management debug code" show
@@ -372,10 +379,6 @@ IN: tools.deploy.shaker
                 compiler.errors:compiler-errors
                 continuations:thread-error-hook
             } %
-            
-            deploy-ui? get [
-                "ui-error-hook" "ui.gadgets.worlds" lookup ,
-            ] when
         ] when
 
         "windows-messages" "windows.messages" lookup [ , ] when*
@@ -529,6 +532,7 @@ SYMBOL: deploy-vocab
     strip-call
     strip-cocoa
     strip-debugger
+    strip-ui-error-hook
     strip-specialized-arrays
     compute-next-methods
     strip-startup-hooks
diff --git a/basis/tools/deploy/shaker/strip-ui-error-hook.factor b/basis/tools/deploy/shaker/strip-ui-error-hook.factor
new file mode 100644
index 0000000000..2525145828
--- /dev/null
+++ b/basis/tools/deploy/shaker/strip-ui-error-hook.factor
@@ -0,0 +1,7 @@
+USING: namespaces tools.deploy.config fry sequences system kernel ui ui.gadgets.worlds ;
+
+deploy-name get "Factor" or '[
+    _ " encountered an unhandled error." append
+    "The application will now exit."
+    system-alert die
+] ui-error-hook set-global

From b7727bc69561a07ff3d3282858310ecfb945868c Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 22:55:57 -0800
Subject: [PATCH 222/250] ui.gadgets.worlds: deactivate world before calling
 the ui-error-hook

---
 basis/ui/gadgets/worlds/worlds.factor | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/basis/ui/gadgets/worlds/worlds.factor b/basis/ui/gadgets/worlds/worlds.factor
index eea2933b04..05466f4673 100644
--- a/basis/ui/gadgets/worlds/worlds.factor
+++ b/basis/ui/gadgets/worlds/worlds.factor
@@ -217,8 +217,7 @@ ui-error-hook [ [ rethrow ] ] initialize
                 dup [ draw-world* ] with-gl-context
                 flush-layout-cache-hook get call( -- )
             ] [
-                over <world-error> ui-error
-                f >>active? drop
+                swap f >>active? <world-error> ui-error
             ] recover
         ] with-variable
     ] [ drop ] if ;

From 856674f1106c23e33476f781a017824bdb3f286e Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Tue, 23 Feb 2010 23:00:24 -0800
Subject: [PATCH 223/250] Bindings to the WinUSB part of the Windows DDK

---
 basis/windows/ddk/winusb/authors.txt   |  1 +
 basis/windows/ddk/winusb/platforms.txt |  1 +
 basis/windows/ddk/winusb/summary.txt   |  1 +
 basis/windows/ddk/winusb/tags.txt      |  1 +
 basis/windows/ddk/winusb/winusb.factor | 66 ++++++++++++++++++++++++++
 5 files changed, 70 insertions(+)
 create mode 100644 basis/windows/ddk/winusb/authors.txt
 create mode 100644 basis/windows/ddk/winusb/platforms.txt
 create mode 100644 basis/windows/ddk/winusb/summary.txt
 create mode 100644 basis/windows/ddk/winusb/tags.txt
 create mode 100644 basis/windows/ddk/winusb/winusb.factor

diff --git a/basis/windows/ddk/winusb/authors.txt b/basis/windows/ddk/winusb/authors.txt
new file mode 100644
index 0000000000..6f03a12101
--- /dev/null
+++ b/basis/windows/ddk/winusb/authors.txt
@@ -0,0 +1 @@
+Erik Charlebois
diff --git a/basis/windows/ddk/winusb/platforms.txt b/basis/windows/ddk/winusb/platforms.txt
new file mode 100644
index 0000000000..205e64323d
--- /dev/null
+++ b/basis/windows/ddk/winusb/platforms.txt
@@ -0,0 +1 @@
+winnt
diff --git a/basis/windows/ddk/winusb/summary.txt b/basis/windows/ddk/winusb/summary.txt
new file mode 100644
index 0000000000..0d95f10574
--- /dev/null
+++ b/basis/windows/ddk/winusb/summary.txt
@@ -0,0 +1 @@
+Bindings to the USB section of the Windows DDK.
diff --git a/basis/windows/ddk/winusb/tags.txt b/basis/windows/ddk/winusb/tags.txt
new file mode 100644
index 0000000000..ee46b6bc1f
--- /dev/null
+++ b/basis/windows/ddk/winusb/tags.txt
@@ -0,0 +1 @@
+unportable bindings
diff --git a/basis/windows/ddk/winusb/winusb.factor b/basis/windows/ddk/winusb/winusb.factor
new file mode 100644
index 0000000000..3b98e7e8ca
--- /dev/null
+++ b/basis/windows/ddk/winusb/winusb.factor
@@ -0,0 +1,66 @@
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: alien.c-types alien.syntax classes.struct windows.kernel32
+windows.types alien.libraries ;
+IN: windows.ddk.winusb
+
+<< "winusb" "winusb.dll" "stdcall" add-library >>
+LIBRARY: winusb
+
+TYPEDEF: PVOID WINUSB_INTERFACE_HANDLE
+TYPEDEF: WINUSB_INTERFACE_HANDLE* PWINUSB_INTERFACE_HANDLE
+
+STRUCT: USB_INTERFACE_DESCRIPTOR
+    { bLength            UCHAR }
+    { bDescriptorType    UCHAR }
+    { bInterfaceNumber   UCHAR }
+    { bAlternateSetting  UCHAR }
+    { bNumEndpoints      UCHAR }
+    { bInterfaceClass    UCHAR }
+    { bInterfaceSubClass UCHAR }
+    { bInterfaceProtocol UCHAR }
+    { iInterface         UCHAR } ;
+TYPEDEF: USB_INTERFACE_DESCRIPTOR* PUSB_INTERFACE_DESCRIPTOR
+
+C-ENUM:
+    UsbdPipeTypeControl
+    UsbdPipeTypeIsochronous
+    UsbdPipeTypeBulk
+    UsbdPipeTypeInterrupt ;
+TYPEDEF: int USBD_PIPE_TYPE
+
+STRUCT: WINUSB_PIPE_INFORMATION
+    { PipeType                   USBD_PIPE_TYPE }
+    { PipeId                     UCHAR          }
+    { MaximumPacketSize          USHORT         }
+    { Interval                   UCHAR          } ;
+TYPEDEF: WINUSB_PIPE_INFORMATION* PWINUSB_PIPE_INFORMATION
+
+STRUCT: WINUSB_SETUP_PACKET
+    { RequestType   UCHAR  }
+    { Request       UCHAR  }
+    { Value         USHORT }
+    { Index         USHORT }
+    { Length        USHORT } ;
+TYPEDEF: WINUSB_SETUP_PACKET* PWINUSB_SETUP_PACKET
+
+FUNCTION: BOOL WinUsb_AbortPipe ( WINUSB_INTERFACE_HANDLE InterfaceHandle, UCHAR PipeID ) ;
+FUNCTION: BOOL WinUsb_FlushPipe ( WINUSB_INTERFACE_HANDLE InterfaceHandle, UCHAR PipeID ) ;
+FUNCTION: BOOL WinUsb_ControlTransfer ( WINUSB_INTERFACE_HANDLE InterfaceHandle, WINUSB_SETUP_PACKET SetupPacket, PUCHAR Buffer, ULONG BufferLength, PULONG LengthTransferred, LPOVERLAPPED Overlapped ) ;
+FUNCTION: BOOL WinUsb_Initialize ( HANDLE DeviceHandle, PWINUSB_INTERFACE_HANDLE InterfaceHandle ) ;
+FUNCTION: BOOL WinUsb_Free ( WINUSB_INTERFACE_HANDLE InterfaceHandle ) ;
+FUNCTION: BOOL WinUsb_GetAssociatedInterface ( WINUSB_INTERFACE_HANDLE InterfaceHandle, UCHAR AssociatedInterfaceIndex, PWINUSB_INTERFACE_HANDLE AssociatedInterfaceHandle ) ;
+FUNCTION: BOOL WinUsb_GetCurrentAlternateSetting ( WINUSB_INTERFACE_HANDLE InterfaceHandle, PUCHAR SettingNumber ) ;
+FUNCTION: BOOL WinUsb_GetDescriptor ( WINUSB_INTERFACE_HANDLE InterfaceHandle, UCHAR DescriptorType, UCHAR Index, USHORT LanguageID, PUCHAR Buffer, ULONG BufferLength, PULONG LengthTransferred ) ;
+FUNCTION: BOOL WinUsb_GetPowerPolicy ( WINUSB_INTERFACE_HANDLE InterfaceHandle, ULONG PolicyType, PULONG ValueLength, PVOID Value ) ;
+FUNCTION: BOOL WinUsb_GetOverlappedResult ( WINUSB_INTERFACE_HANDLE InterfaceHandle, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, BOOL bWait ) ;
+FUNCTION: BOOL WinUsb_GetPipePolicy ( WINUSB_INTERFACE_HANDLE InterfaceHandle, UCHAR PipeID, ULONG PolicyType, PULONG ValueLength, PVOID Value ) ;
+FUNCTION: BOOL WinUsb_QueryInterfaceSettings ( WINUSB_INTERFACE_HANDLE InterfaceHandle, UCHAR AlternateInterfaceNumber, PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor ) ;
+FUNCTION: BOOL WinUsb_QueryDeviceInformation ( WINUSB_INTERFACE_HANDLE InterfaceHandle, ULONG InformationType, PULONG BufferLength, PVOID Buffer ) ;
+FUNCTION: BOOL WinUsb_QueryPipe ( WINUSB_INTERFACE_HANDLE InterfaceHandle, UCHAR AlternateInterfaceNumber, UCHAR PipeIndex, PWINUSB_PIPE_INFORMATION PipeInformation ) ;
+FUNCTION: BOOL WinUsb_ReadPipe ( WINUSB_INTERFACE_HANDLE InterfaceHandle, UCHAR PipeID, PUCHAR Buffer, ULONG BufferLength, PULONG LengthTransferred, LPOVERLAPPED Overlapped ) ;
+FUNCTION: BOOL WinUsb_ResetPipe ( WINUSB_INTERFACE_HANDLE InterfaceHandle, UCHAR PipeID ) ;
+FUNCTION: BOOL WinUsb_SetCurrentAlternateSetting ( WINUSB_INTERFACE_HANDLE InterfaceHandle, UCHAR SettingNumber ) ;
+FUNCTION: BOOL WinUsb_SetPowerPolicy ( WINUSB_INTERFACE_HANDLE InterfaceHandle, ULONG PolicyType, ULONG ValueLength, PVOID Value ) ;
+FUNCTION: BOOL WinUsb_SetPipePolicy ( WINUSB_INTERFACE_HANDLE InterfaceHandle, UCHAR PipeID, ULONG PolicyType, ULONG ValueLength, PVOID Value ) ;
+FUNCTION: BOOL WinUsb_WritePipe ( WINUSB_INTERFACE_HANDLE InterfaceHandle, UCHAR PipeID, PUCHAR Buffer, ULONG BufferLength, PULONG LengthTransferred, LPOVERLAPPED Overlapped ) ;

From af0ddd5985f325c5b7c75a84850cdcfa8dbffc09 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Wed, 24 Feb 2010 20:18:41 +1300
Subject: [PATCH 224/250] Specialized arrays, structs and other objects
 responding to the >c-ptr / byte-length protocol can now be written to binary
 streams

---
 basis/alien/c-types/c-types-docs.factor       |  4 ---
 basis/alien/c-types/c-types.factor            |  6 ----
 basis/alien/data/data.factor                  | 11 ++++--
 basis/bit-arrays/bit-arrays.factor            |  2 +-
 basis/classes/struct/struct.factor            | 10 +++---
 basis/io/buffers/buffers.factor               |  2 +-
 basis/io/ports/ports-tests.factor             | 23 +++++++++++++
 basis/io/ports/ports.factor                   | 22 +++++++-----
 basis/math/bitwise/bitwise.factor             |  3 +-
 .../math/vectors/conversion/conversion.factor |  8 ++---
 basis/math/vectors/simd/simd.factor           | 12 +++----
 basis/nibble-arrays/nibble-arrays.factor      |  2 +-
 .../specialized-arrays.factor                 |  4 +++
 .../specialized-vectors.factor                |  6 ++--
 .../known-words/known-words.factor            |  6 ++--
 core/alien/alien-docs.factor                  | 12 ++++++-
 core/alien/alien.factor                       | 11 +++++-
 core/bootstrap/primitives.factor              |  2 +-
 core/io/files/files-tests.factor              | 27 +++++++++++++--
 core/io/io-docs.factor                        | 34 +++++++++++--------
 core/io/io.factor                             |  2 +-
 .../byte-array/byte-array-tests.factor        | 11 +++++-
 core/io/streams/c/c-docs.factor               | 10 +++---
 core/io/streams/c/c-tests.factor              | 25 +++++++++++++-
 core/io/streams/c/c.factor                    | 30 +++++++++-------
 extra/audio/vorbis/vorbis.factor              |  9 ++---
 extra/mongodb/operations/operations.factor    | 13 +++----
 extra/synth/buffers/buffers.factor            |  4 +--
 vm/io.cpp                                     |  9 +++--
 29 files changed, 212 insertions(+), 108 deletions(-)
 create mode 100644 basis/io/ports/ports-tests.factor

diff --git a/basis/alien/c-types/c-types-docs.factor b/basis/alien/c-types/c-types-docs.factor
index 0bcb7b9401..9592fb1812 100644
--- a/basis/alien/c-types/c-types-docs.factor
+++ b/basis/alien/c-types/c-types-docs.factor
@@ -6,10 +6,6 @@ QUALIFIED: math
 QUALIFIED: sequences
 IN: alien.c-types
 
-HELP: byte-length
-{ $values { "seq" "A byte array or float array" } { "n" "a non-negative integer" } }
-{ $contract "Outputs the size of the byte array, struct, or specialized array data in bytes." } ;
-
 HELP: heap-size
 { $values { "name" "a C type name" } { "size" math:integer } }
 { $description "Outputs the number of bytes needed for a heap-allocated value of this C type." }
diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor
index ef47f4b69c..17bf4765b8 100644
--- a/basis/alien/c-types/c-types.factor
+++ b/basis/alien/c-types/c-types.factor
@@ -193,12 +193,6 @@ M: c-type-name stack-size c-type stack-size ;
 
 M: c-type stack-size size>> cell align ;
 
-GENERIC: byte-length ( seq -- n ) flushable
-
-M: byte-array byte-length length ; inline
-
-M: f byte-length drop 0 ; inline
-
 : >c-bool ( ? -- int ) 1 0 ? ; inline
 
 : c-bool> ( int -- ? ) 0 = not ; inline
diff --git a/basis/alien/data/data.factor b/basis/alien/data/data.factor
index 93b1afd436..462bed8b76 100644
--- a/basis/alien/data/data.factor
+++ b/basis/alien/data/data.factor
@@ -1,7 +1,8 @@
-! (c)2009 Slava Pestov, Joe Groff bsd license
+! (c)2009, 2010 Slava Pestov, Joe Groff bsd license
 USING: accessors alien alien.c-types alien.strings arrays
 byte-arrays cpu.architecture fry io io.encodings.binary
-io.files io.streams.memory kernel libc math sequences words ;
+io.files io.streams.memory kernel libc math sequences words
+byte-vectors ;
 IN: alien.data
 
 GENERIC: require-c-array ( c-type -- )
@@ -65,6 +66,12 @@ M: memory-stream stream-read
 : byte-array>memory ( byte-array base -- )
     swap dup byte-length memcpy ; inline
 
+M: byte-vector stream-write
+    [ binary-object ] dip
+    [ [ length + ] keep lengthen drop ]
+    [ '[ _ underlying>> ] 2dip memcpy ]
+    3bi ;
+
 M: value-type c-type-rep drop int-rep ;
 
 M: value-type c-type-getter
diff --git a/basis/bit-arrays/bit-arrays.factor b/basis/bit-arrays/bit-arrays.factor
index 4fafc528fd..798bfb8ae9 100644
--- a/basis/bit-arrays/bit-arrays.factor
+++ b/basis/bit-arrays/bit-arrays.factor
@@ -1,6 +1,6 @@
 ! Copyright (C) 2007, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.c-types alien.data accessors math alien.accessors kernel
+USING: alien alien.data accessors math alien.accessors kernel
 kernel.private sequences sequences.private byte-arrays
 parser prettyprint.custom fry ;
 IN: bit-arrays
diff --git a/basis/classes/struct/struct.factor b/basis/classes/struct/struct.factor
index 204b05517b..a3b198bd94 100644
--- a/basis/classes/struct/struct.factor
+++ b/basis/classes/struct/struct.factor
@@ -46,11 +46,11 @@ M: struct >c-ptr
 M: struct equal?
     {
         [ [ class ] bi@ = ]
-        [ [ >c-ptr ] [ [ >c-ptr ] [ byte-length ] bi ] bi* memory= ]
+        [ [ >c-ptr ] [ binary-object ] bi* memory= ]
     } 2&& ; inline
 
 M: struct hashcode*
-    [ >c-ptr ] [ byte-length ] bi <direct-uchar-array> hashcode* ; inline    
+    binary-object <direct-uchar-array> hashcode* ; inline
 
 : struct-prototype ( class -- prototype ) "prototype" word-prop ; foldable
 
@@ -137,7 +137,7 @@ PRIVATE>
 
 M: struct-class boa>object
     swap pad-struct-slots
-    [ <struct> ] [ struct-slots ] bi 
+    [ <struct> ] [ struct-slots ] bi
     [ [ (writer-quot) call( value struct -- ) ] with 2each ] curry keep ;
 
 M: struct-class initial-value* <struct> ; inline
@@ -203,7 +203,7 @@ M: struct-c-type c-struct? drop t ;
     define-inline-method ;
 
 : clone-underlying ( struct -- byte-array )
-    [ >c-ptr ] [ byte-length ] bi memory>byte-array ; inline
+    binary-object memory>byte-array ; inline
 
 : (define-clone-method) ( class -- )
     [ \ clone ]
@@ -353,7 +353,7 @@ PRIVATE>
 <PRIVATE
 : parse-struct-slot ( -- slot )
     scan scan-c-type \ } parse-until <struct-slot-spec> ;
-    
+
 : parse-struct-slots ( slots -- slots' more? )
     scan {
         { ";" [ f ] }
diff --git a/basis/io/buffers/buffers.factor b/basis/io/buffers/buffers.factor
index 23358d9a0e..ce5ad2c9a0 100644
--- a/basis/io/buffers/buffers.factor
+++ b/basis/io/buffers/buffers.factor
@@ -61,7 +61,7 @@ HINTS: n>buffer fixnum buffer ;
 
 : >buffer ( byte-array buffer -- )
     [ buffer-end byte-array>memory ]
-    [ [ length ] dip n>buffer ]
+    [ [ byte-length ] dip n>buffer ]
     2bi ;
 
 HINTS: >buffer byte-array buffer ;
diff --git a/basis/io/ports/ports-tests.factor b/basis/io/ports/ports-tests.factor
new file mode 100644
index 0000000000..e637999880
--- /dev/null
+++ b/basis/io/ports/ports-tests.factor
@@ -0,0 +1,23 @@
+USING: destructors io io.encodings.binary io.files io.directories
+io.files.temp io.ports kernel sequences math
+specialized-arrays.instances.alien.c-types.int tools.test ;
+IN: io.ports.tests
+
+! Make sure that writing malloced storage to a file works, and
+! also make sure that writes larger than the buffer size work
+
+[ ] [
+    "test.txt" temp-file binary [
+        100,000 iota
+        0
+        100,000 malloc-int-array &dispose [ copy ] keep write
+    ] with-file-writer
+] unit-test
+
+[ t ] [
+    "test.txt" temp-file binary [
+        100,000 4 * read byte-array>int-array 100,000 iota sequence=
+    ] with-file-reader
+] unit-test
+
+[ ] [ "test.txt" temp-file delete-file ] unit-test
diff --git a/basis/io/ports/ports.factor b/basis/io/ports/ports.factor
index 727d69adf8..0927e7e480 100644
--- a/basis/io/ports/ports.factor
+++ b/basis/io/ports/ports.factor
@@ -1,10 +1,11 @@
-! Copyright (C) 2005, 2008 Slava Pestov, Doug Coleman
+! Copyright (C) 2005, 2010 Slava Pestov, Doug Coleman
 ! See http://factorcode.org/license.txt for BSD license.
 USING: math kernel io sequences io.buffers io.timeouts generic
 byte-vectors system io.encodings math.order io.backend
-continuations classes byte-arrays namespaces splitting
-grouping dlists assocs io.encodings.binary summary accessors
-destructors combinators ;
+continuations classes byte-arrays namespaces splitting grouping
+dlists alien alien.c-types assocs io.encodings.binary summary
+accessors destructors combinators fry specialized-arrays ;
+SPECIALIZED-ARRAY: uchar
 IN: io.ports
 
 SYMBOL: default-buffer-size
@@ -111,14 +112,17 @@ M: output-port stream-write1
     1 over wait-to-write
     buffer>> byte>buffer ; inline
 
+: write-in-groups ( byte-array port -- )
+    [ binary-object <direct-uchar-array> ] dip
+    [ buffer>> size>> <groups> ] [ '[ _ stream-write ] ] bi
+    each ;
+
 M: output-port stream-write
     dup check-disposed
-    over length over buffer>> size>> > [
-        [ buffer>> size>> <groups> ]
-        [ [ stream-write ] curry ] bi
-        each
+    2dup [ byte-length ] [ buffer>> size>> ] bi* > [
+        write-in-groups
     ] [
-        [ [ length ] dip wait-to-write ]
+        [ [ byte-length ] dip wait-to-write ]
         [ buffer>> >buffer ] 2bi
     ] if ;
 
diff --git a/basis/math/bitwise/bitwise.factor b/basis/math/bitwise/bitwise.factor
index e508b49a19..15db425137 100644
--- a/basis/math/bitwise/bitwise.factor
+++ b/basis/math/bitwise/bitwise.factor
@@ -117,8 +117,7 @@ M: byte-array bit-count
     byte-array-bit-count ;
 
 M: object bit-count
-    [ >c-ptr ] [ byte-length ] bi <direct-uchar-array>
-    byte-array-bit-count ;
+    binary-object <direct-uchar-array> byte-array-bit-count ;
 
 : even-parity? ( obj -- ? ) bit-count even? ;
 
diff --git a/basis/math/vectors/conversion/conversion.factor b/basis/math/vectors/conversion/conversion.factor
index 6148962ee0..9d60dd03d4 100644
--- a/basis/math/vectors/conversion/conversion.factor
+++ b/basis/math/vectors/conversion/conversion.factor
@@ -1,10 +1,10 @@
 ! (c)Joe Groff bsd license
-USING: accessors alien.c-types arrays assocs classes combinators
-combinators.short-circuit fry kernel locals math
-math.vectors math.vectors.simd math.vectors.simd.intrinsics sequences ;
+USING: accessors alien arrays assocs classes combinators
+combinators.short-circuit fry kernel locals math math.vectors
+math.vectors.simd math.vectors.simd.intrinsics sequences ;
 FROM: alien.c-types =>
     char uchar short ushort int uint longlong ulonglong
-    float double ;
+    float double heap-size ;
 IN: math.vectors.conversion
 
 ERROR: bad-vconvert from-type to-type ;
diff --git a/basis/math/vectors/simd/simd.factor b/basis/math/vectors/simd/simd.factor
index a60026317d..8d804247d3 100644
--- a/basis/math/vectors/simd/simd.factor
+++ b/basis/math/vectors/simd/simd.factor
@@ -1,9 +1,9 @@
-USING: accessors alien.c-types arrays byte-arrays classes combinators
+USING: accessors alien arrays byte-arrays classes combinators
 cpu.architecture effects fry functors generalizations generic
 generic.parser kernel lexer literals macros math math.functions
-math.vectors math.vectors.private math.vectors.simd.intrinsics namespaces parser
-prettyprint.custom quotations sequences sequences.private vocabs
-vocabs.loader words ;
+math.vectors math.vectors.private math.vectors.simd.intrinsics
+namespaces parser prettyprint.custom quotations sequences
+sequences.private vocabs vocabs.loader words ;
 QUALIFIED-WITH: alien.c-types c
 IN: math.vectors.simd
 
@@ -107,7 +107,7 @@ PRIVATE>
 
 M: simd-128 hashcode* underlying>> hashcode* ; inline
 M: simd-128 clone [ clone ] change-underlying ; inline
-M: simd-128 c:byte-length drop 16 ; inline
+M: simd-128 byte-length drop 16 ; inline
 
 M: simd-128 new-sequence
     2dup length =
@@ -243,7 +243,7 @@ A{     DEFINES       ${T}{
 
 ELT     [ A-rep rep-component-type ]
 N       [ A-rep rep-length ]
-COERCER [ ELT c-type-class "coercer" word-prop [ ] or ]
+COERCER [ ELT c:c-type-class "coercer" word-prop [ ] or ]
 
 SET-NTH [ ELT dup c:c-setter c:array-accessor ]
 
diff --git a/basis/nibble-arrays/nibble-arrays.factor b/basis/nibble-arrays/nibble-arrays.factor
index 16bea56862..865491ed21 100644
--- a/basis/nibble-arrays/nibble-arrays.factor
+++ b/basis/nibble-arrays/nibble-arrays.factor
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: math kernel sequences sequences.private byte-arrays
-alien.c-types prettyprint.custom parser accessors ;
+alien prettyprint.custom parser accessors ;
 IN: nibble-arrays
 
 TUPLE: nibble-array
diff --git a/basis/specialized-arrays/specialized-arrays.factor b/basis/specialized-arrays/specialized-arrays.factor
index 2aca62cc77..f7070c68e1 100644
--- a/basis/specialized-arrays/specialized-arrays.factor
+++ b/basis/specialized-arrays/specialized-arrays.factor
@@ -117,6 +117,7 @@ M: A v*high [ * \ T heap-size neg shift ] 2map ; inline
 ;FUNCTOR
 
 GENERIC: underlying-type ( c-type -- c-type' )
+
 M: c-type-word underlying-type
     dup "c-type" word-prop {
         { [ dup not ] [ drop no-c-type ] }
@@ -149,18 +150,21 @@ M: c-type-word c-array-constructor
     underlying-type
     dup [ name>> "<" "-array>" surround ] [ specialized-array-vocab ] bi lookup
     [ ] [ specialized-array-vocab-not-loaded ] ?if ; foldable
+
 M: pointer c-array-constructor drop void* c-array-constructor ;
 
 M: c-type-word c-(array)-constructor
     underlying-type
     dup [ name>> "(" "-array)" surround ] [ specialized-array-vocab ] bi lookup
     [ ] [ specialized-array-vocab-not-loaded ] ?if ; foldable
+
 M: pointer c-(array)-constructor drop void* c-(array)-constructor ;
 
 M: c-type-word c-direct-array-constructor
     underlying-type
     dup [ name>> "<direct-" "-array>" surround ] [ specialized-array-vocab ] bi lookup
     [ ] [ specialized-array-vocab-not-loaded ] ?if ; foldable
+
 M: pointer c-direct-array-constructor drop void* c-direct-array-constructor ;
 
 SYNTAX: SPECIALIZED-ARRAYS:
diff --git a/basis/specialized-vectors/specialized-vectors.factor b/basis/specialized-vectors/specialized-vectors.factor
index 557ca25cd5..c16fe2510d 100644
--- a/basis/specialized-vectors/specialized-vectors.factor
+++ b/basis/specialized-vectors/specialized-vectors.factor
@@ -1,8 +1,8 @@
 ! Copyright (C) 2008, 2009 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien.c-types alien.parser assocs
-compiler.units functors growable kernel lexer math namespaces parser
-prettyprint.custom sequences specialized-arrays
+USING: accessors alien alien.c-types alien.parser assocs
+compiler.units functors growable kernel lexer math namespaces
+parser prettyprint.custom sequences specialized-arrays
 specialized-arrays.private strings vocabs vocabs.parser
 vocabs.generated fry make ;
 QUALIFIED: vectors.functor
diff --git a/basis/stack-checker/known-words/known-words.factor b/basis/stack-checker/known-words/known-words.factor
index 4bf7dfe0fd..e93dca9072 100644
--- a/basis/stack-checker/known-words/known-words.factor
+++ b/basis/stack-checker/known-words/known-words.factor
@@ -652,15 +652,15 @@ M: bad-executable summary
 
 \ fgetc { alien } { object } define-primitive
 
-\ fwrite { string alien } { } define-primitive
+\ fwrite { c-ptr integer alien } { } define-primitive
 
 \ fputc { object alien } { } define-primitive
 
-\ fread { integer string } { object } define-primitive
+\ fread { integer alien } { object } define-primitive
 
 \ fflush { alien } { } define-primitive
 
-\ fseek { alien integer integer } { } define-primitive
+\ fseek { integer integer alien } { } define-primitive
 
 \ ftell { alien } { integer } define-primitive
 
diff --git a/core/alien/alien-docs.factor b/core/alien/alien-docs.factor
index 9389b24227..60c1cdaf69 100644
--- a/core/alien/alien-docs.factor
+++ b/core/alien/alien-docs.factor
@@ -1,9 +1,19 @@
 USING: byte-arrays arrays help.syntax help.markup
 alien.syntax compiler definitions math libc eval
 debugger parser io io.backend system alien.accessors
-alien.libraries alien.c-types quotations ;
+alien.libraries alien.c-types quotations kernel ;
 IN: alien
 
+HELP: >c-ptr
+{ $values { "object" object } { "c-ptr" c-ptr } }
+{ $contract "Outputs a pointer to the binary data of this object." } ;
+
+HELP: byte-length
+{ $values { "object" object } { "n" "a non-negative integer" } }
+{ $contract "Outputs the number of bytes of binary data that will be output by " { $link >c-ptr } "." } ;
+
+{ >c-ptr byte-length } related-words
+
 HELP: alien
 { $class-description "The class of alien pointers. See " { $link "syntax-aliens" } " for syntax and " { $link "c-data" } " for general information." } ;
 
diff --git a/core/alien/alien.factor b/core/alien/alien.factor
index 16c33fc1c3..42f48f97aa 100644
--- a/core/alien/alien.factor
+++ b/core/alien/alien.factor
@@ -8,10 +8,19 @@ PREDICATE: pinned-alien < alien underlying>> not ;
 
 UNION: pinned-c-ptr pinned-alien POSTPONE: f ;
 
-GENERIC: >c-ptr ( obj -- c-ptr )
+GENERIC: >c-ptr ( obj -- c-ptr ) flushable
 
 M: c-ptr >c-ptr ; inline
 
+GENERIC: byte-length ( seq -- n ) flushable
+
+M: byte-array byte-length length ; inline
+
+M: f byte-length drop 0 ; inline
+
+: binary-object ( obj -- c-ptr n )
+    [ >c-ptr ] [ byte-length ] bi ; inline
+
 SLOT: underlying
 
 M: object >c-ptr underlying>> ; inline
diff --git a/core/bootstrap/primitives.factor b/core/bootstrap/primitives.factor
index 367dc4d942..43aeb6bd70 100644
--- a/core/bootstrap/primitives.factor
+++ b/core/bootstrap/primitives.factor
@@ -434,7 +434,7 @@ tuple
     { "fread" "io.streams.c" "primitive_fread" (( n alien -- str/f )) }
     { "fseek" "io.streams.c" "primitive_fseek" (( alien offset whence -- )) }
     { "ftell" "io.streams.c" "primitive_ftell" (( alien -- n )) }
-    { "fwrite" "io.streams.c" "primitive_fwrite" (( string alien -- )) }
+    { "fwrite" "io.streams.c" "primitive_fwrite" (( data length alien -- )) }
     { "(clone)" "kernel" "primitive_clone" (( obj -- newobj )) }
     { "<wrapper>" "kernel" "primitive_wrapper" (( obj -- wrapper )) }
     { "callstack" "kernel" "primitive_callstack" (( -- cs )) }
diff --git a/core/io/files/files-tests.factor b/core/io/files/files-tests.factor
index da5d670659..cf58dbfe05 100644
--- a/core/io/files/files-tests.factor
+++ b/core/io/files/files-tests.factor
@@ -2,7 +2,8 @@ USING: arrays debugger.threads destructors io io.directories
 io.encodings.ascii io.encodings.binary io.encodings.string
 io.encodings.8-bit.latin1 io.files io.files.private
 io.files.temp io.files.unique kernel make math sequences system
-threads tools.test generic.single ;
+threads tools.test generic.single specialized-arrays alien.c-types ;
+SPECIALIZED-ARRAY: int
 IN: io.files.tests
 
 [ ] [ "append-test" temp-file dup exists? [ delete-file ] [ drop ] if ] unit-test
@@ -65,6 +66,27 @@ IN: io.files.tests
     ] with-file-reader
 ] unit-test
 
+! Writing specialized arrays to binary streams should work
+[ ] [
+    "test.txt" temp-file binary [
+        int-array{ 1 2 3 } write
+    ] with-file-writer
+] unit-test
+
+[ int-array{ 1 2 3 } ] [
+    "test.txt" temp-file binary [
+        3 4 * read
+    ] with-file-reader
+    byte-array>int-array
+] unit-test
+
+! Writing strings to binary streams should fail
+[
+    "test.txt" temp-file binary [
+        "OMGFAIL" write
+    ] with-file-writer
+] must-fail
+
 ! Test EOF behavior
 [ 10 ] [
     image binary [
@@ -73,8 +95,7 @@ IN: io.files.tests
     ] with-file-reader
 ] unit-test
 
-USE: debugger.threads
-
+! Make sure that writing to a closed stream from another thread doesn't crash
 [ ] [ "test-quux.txt" temp-file ascii [ [ yield "Hi" write ] "Test" spawn drop ] with-file-writer ] unit-test
 
 [ ] [ "test-quux.txt" temp-file delete-file ] unit-test
diff --git a/core/io/io-docs.factor b/core/io/io-docs.factor
index aa6e087442..11848cfa03 100644
--- a/core/io/io-docs.factor
+++ b/core/io/io-docs.factor
@@ -1,7 +1,21 @@
 USING: help.markup help.syntax quotations hashtables kernel
-classes strings continuations destructors math byte-arrays ;
+classes strings continuations destructors math byte-arrays
+alien ;
 IN: io
 
+ARTICLE: "stream-types" "Binary and text streams"
+"A word which outputs the stream element type:"
+{ $subsections stream-element-type }
+"Stream element types:"
+{ $subsections +byte+ +character+ }
+"The stream element type is the data type read and written by " { $link stream-read1 } " and " { $link stream-write1 } "."
+$nl
+"Binary streams have an element type of " { $link +byte+ } ". Elements are integers in the range " { $snippet "[0,255]" } ", representing bytes. Reading a sequence of elements produces a " { $link byte-array } ". Any object implementing the " { $link >c-ptr } " and " { $link byte-length } " generic words can be written to a binary stream."
+$nl
+"Character streams have an element tye of " { $link +character+ } ". Elements are non-negative integers, representing Unicode code points. Only instances of the " { $link string } " class can be read or written on a character stream."
+$nl
+"Most external streams are binary streams, and can be wrapped in string streams once a suitable encoding has been provided; see " { $link "io.encodings" } "." ;
+
 HELP: +byte+
 { $description "A stream element type. See " { $link stream-element-type } " for explanation." } ;
 
@@ -10,15 +24,7 @@ HELP: +character+
 
 HELP: stream-element-type
 { $values { "stream" "a stream" } { "type" { $link +byte+ } " or " { $link +character+ } } }
-{ $description
-  "Outputs one of the following two values:"
-  { $list
-    { { $link +byte+ } " - indicates that stream elements are integers in the range " { $snippet "[0,255]" } "; they represent bytes. Reading a sequence of elements produces a " { $link byte-array } "." }
-    { { $link +character+ } " - indicates that stream elements are non-negative integers, representing Unicode code points. Reading a sequence of elements produces a " { $link string } "." }
-  }
-  "Most external streams are binary streams, and can be wrapped in string streams once a suitable encoding has been provided; see " { $link "io.encodings" } "."
-  
-} ;
+{ $contract "Outputs one of " { $link +byte+ } " or " { $link +character+ } "." } ;
 
 HELP: stream-readln
 { $values { "stream" "an input stream" } { "str/f" "a string or " { $link f } } }
@@ -57,8 +63,8 @@ HELP: stream-write1
 $io-error ;
 
 HELP: stream-write
-{ $values { "seq" "a byte array or string" } { "stream" "an output stream" } }
-{ $contract "Writes a sequence of elements to the stream. If the stream does buffering, output may not be performed immediately; use " { $link stream-flush } " to force output." }
+{ $values { "data" "binary data or a string" } { "stream" "an output stream" } }
+{ $contract "Writes a piece of data to the stream. If the stream performs buffering, output may not be performed immediately; use " { $link stream-flush } " to force output." }
 { $notes "Most code only works on one stream at a time and should instead use " { $link write } "; see " { $link "stdio" } "." }
 $io-error ;
 
@@ -262,9 +268,7 @@ $nl
 "Stream protocol words are rarely called directly, since code which only works with one stream at a time should be written to use " { $link "stdio" } " instead, wrapping I/O operations such as " { $link read } " and " { $link write } " in " { $link with-input-stream } " and " { $link with-output-stream } "."
 $nl
 "All streams must implement the " { $link dispose } " word in addition to the stream protocol."
-$nl
-"The following word is required for all input and output streams:"
-{ $subsections stream-element-type }
+{ $subsections "stream-types" }
 "These words are required for binary and string input streams:"
 { $subsections
     stream-read1
diff --git a/core/io/io.factor b/core/io/io.factor
index 48d7f413b8..519d6535b9 100644
--- a/core/io/io.factor
+++ b/core/io/io.factor
@@ -15,7 +15,7 @@ GENERIC: stream-read-partial ( n stream -- seq )
 GENERIC: stream-readln ( stream -- str/f )
 
 GENERIC: stream-write1 ( elt stream -- )
-GENERIC: stream-write ( seq stream -- )
+GENERIC: stream-write ( data stream -- )
 GENERIC: stream-flush ( stream -- )
 GENERIC: stream-nl ( stream -- )
 
diff --git a/core/io/streams/byte-array/byte-array-tests.factor b/core/io/streams/byte-array/byte-array-tests.factor
index 96b122549d..dc95d454fa 100644
--- a/core/io/streams/byte-array/byte-array-tests.factor
+++ b/core/io/streams/byte-array/byte-array-tests.factor
@@ -1,5 +1,8 @@
 USING: tools.test io.streams.byte-array io.encodings.binary
-io.encodings.utf8 io kernel arrays strings namespaces math ;
+io.encodings.utf8 io kernel arrays strings namespaces math
+specialized-arrays alien.c-types ;
+SPECIALIZED-ARRAY: int
+IN: io.streams.byte-array.tests
 
 [ B{ } ] [ B{ } binary [ contents ] with-byte-reader ] unit-test
 [ B{ 1 2 3 } ] [ binary [ B{ 1 2 3 } write ] with-byte-writer ] unit-test
@@ -37,3 +40,9 @@ io.encodings.utf8 io kernel arrays strings namespaces math ;
 [ B{ 123 } ] [
     binary [ 123 >bignum write1 ] with-byte-writer
 ] unit-test
+
+! Writing specialized arrays to byte writers
+[ int-array{ 1 2 3 } ] [
+    binary [ int-array{ 1 2 3 } write ] with-byte-writer
+    byte-array>int-array
+] unit-test
diff --git a/core/io/streams/c/c-docs.factor b/core/io/streams/c/c-docs.factor
index 7103e49f4a..246f65de98 100644
--- a/core/io/streams/c/c-docs.factor
+++ b/core/io/streams/c/c-docs.factor
@@ -1,5 +1,5 @@
 USING: help.markup help.syntax io io.files threads
-strings byte-arrays io.streams.plain ;
+strings byte-arrays io.streams.plain alien math ;
 IN: io.streams.c
 
 ARTICLE: "io.streams.c" "ANSI C streams"
@@ -42,9 +42,9 @@ HELP: fopen
 { $errors "Throws an error if the file could not be opened." }
 { $notes "User code should call " { $link <file-reader> } " or " { $link <file-writer> } " to get a high level stream." } ;
 
-HELP: fwrite ( string alien -- )
-{ $values { "string" "a string" } { "alien" "a C FILE* handle" } }
-{ $description "Writes a string of text to a C FILE* handle." }
+HELP: fwrite
+{ $values { "data" c-ptr } { "length" integer } { "alien" "a C FILE* handle" } }
+{ $description "Writes some bytes to a C FILE* handle." }
 { $errors "Throws an error if the output operation failed." } ;
 
 HELP: fflush ( alien -- )
@@ -62,7 +62,7 @@ HELP: fgetc ( alien -- ch/f )
 { $errors "Throws an error if the input operation failed." } ;
 
 HELP: fread ( n alien -- str/f )
-{ $values { "n" "a positive integer" } { "alien" "a C FILE* handle" } { "str/f" "a string or " { $link f } } }
+{ $values { "n" "a positive integer" } { "alien" "a C FILE* handle" } { "str/f" { $maybe string } } }
 { $description "Reads a sequence of characters from a C FILE* handle, and outputs " { $link f } " on end of file." }
 { $errors "Throws an error if the input operation failed." } ;
 
diff --git a/core/io/streams/c/c-tests.factor b/core/io/streams/c/c-tests.factor
index 657c6ccd75..d05daf3662 100644
--- a/core/io/streams/c/c-tests.factor
+++ b/core/io/streams/c/c-tests.factor
@@ -1,5 +1,7 @@
 USING: tools.test io.files io.files.temp io io.streams.c
-io.encodings.ascii strings destructors kernel ;
+io.encodings.ascii strings destructors kernel specialized-arrays
+alien.c-types math ;
+SPECIALIZED-ARRAY: int
 IN: io.streams.c.tests
 
 [ "hello world" ] [
@@ -17,3 +19,24 @@ IN: io.streams.c.tests
     3 over stream-read drop
     [ stream-tell ] [ dispose ] bi
 ] unit-test
+
+! Writing specialized arrays to binary streams
+[ ] [
+    "test.txt" temp-file "wb" fopen <c-writer> [
+        int-array{ 1 2 3 } write
+    ] with-output-stream
+] unit-test
+
+[ int-array{ 1 2 3 } ] [
+    "test.txt" temp-file "rb" fopen <c-reader> [
+        3 4 * read
+    ] with-input-stream
+    byte-array>int-array
+] unit-test
+
+! Writing strings to binary streams should fail
+[
+    "test.txt" temp-file "wb" fopen <c-writer> [
+        "OMGFAIL" write
+    ] with-output-stream
+] must-fail
diff --git a/core/io/streams/c/c.factor b/core/io/streams/c/c.factor
index d26f03aa5e..9ebf7f7018 100644
--- a/core/io/streams/c/c.factor
+++ b/core/io/streams/c/c.factor
@@ -1,9 +1,9 @@
-! Copyright (C) 2004, 2009 Slava Pestov.
+! Copyright (C) 2004, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel kernel.private namespaces make io io.encodings sequences
-math generic threads.private classes io.backend io.files
-io.encodings.utf8 alien.strings continuations destructors byte-arrays
-accessors combinators ;
+USING: alien alien.strings kernel kernel.private namespaces make
+io io.encodings sequences math generic threads.private classes
+io.backend io.files io.encodings.utf8 continuations destructors
+byte-arrays accessors combinators ;
 IN: io.streams.c
 
 TUPLE: c-stream < disposable handle ;
@@ -16,12 +16,14 @@ M: c-stream dispose* handle>> fclose ;
 M: c-stream stream-tell handle>> ftell ;
 
 M: c-stream stream-seek
-    handle>> swap {
-        { seek-absolute [ 0 ] }
-        { seek-relative [ 1 ] }
-        { seek-end [ 2 ] }
-        [ bad-seek-type ]
-    } case fseek ;
+    [
+        {
+            { seek-absolute [ 0 ] }
+            { seek-relative [ 1 ] }
+            { seek-end [ 2 ] }
+            [ bad-seek-type ]
+        } case
+    ] [ handle>> ] bi* fseek ;
 
 TUPLE: c-writer < c-stream ;
 
@@ -31,7 +33,9 @@ M: c-writer stream-element-type drop +byte+ ;
 
 M: c-writer stream-write1 dup check-disposed handle>> fputc ;
 
-M: c-writer stream-write dup check-disposed handle>> fwrite ;
+M: c-writer stream-write
+    dup check-disposed
+    [ [ >c-ptr ] [ byte-length ] bi ] [ handle>> ] bi* fwrite ;
 
 M: c-writer stream-flush dup check-disposed handle>> fflush ;
 
@@ -93,6 +97,6 @@ M: c-io-backend (file-appender)
     #! print stuff from contexts where the I/O system would
     #! otherwise not work (tools.deploy.shaker, the I/O
     #! multiplexer thread).
-    "\n" append >byte-array
+    "\n" append >byte-array dup length
     stdout-handle fwrite
     stdout-handle fflush ;
diff --git a/extra/audio/vorbis/vorbis.factor b/extra/audio/vorbis/vorbis.factor
index 78f637770f..e67c7b7934 100644
--- a/extra/audio/vorbis/vorbis.factor
+++ b/extra/audio/vorbis/vorbis.factor
@@ -1,8 +1,9 @@
 ! (c)2007, 2010 Chris Double, Joe Groff bsd license
-USING: accessors alien.c-types audio.engine byte-arrays classes.struct
-combinators destructors fry io io.files io.encodings.binary
-kernel libc locals make math math.order math.parser ogg ogg.vorbis
-sequences specialized-arrays specialized-vectors ;
+USING: accessors alien alien.c-types audio.engine byte-arrays
+classes.struct combinators destructors fry io io.files
+io.encodings.binary kernel libc locals make math math.order
+math.parser ogg ogg.vorbis sequences specialized-arrays
+specialized-vectors ;
 FROM: alien.c-types => float short void* ;
 SPECIALIZED-ARRAYS: float void* ;
 SPECIALIZED-VECTOR: short
diff --git a/extra/mongodb/operations/operations.factor b/extra/mongodb/operations/operations.factor
index 8ecd5df54c..56e560f07a 100644
--- a/extra/mongodb/operations/operations.factor
+++ b/extra/mongodb/operations/operations.factor
@@ -1,12 +1,9 @@
 USING: accessors assocs bson.reader bson.writer byte-arrays
-byte-vectors combinators formatting fry io io.binary io.encodings.private
-io.encodings.binary io.encodings.string io.encodings.utf8 io.encodings.utf8.private io.files
-kernel locals math mongodb.msg namespaces sequences uuid bson.writer.private ;
-
-IN: alien.c-types
-
-M: byte-vector byte-length length ;
-
+byte-vectors combinators formatting fry io io.binary
+io.encodings.private io.encodings.binary io.encodings.string
+io.encodings.utf8 io.encodings.utf8.private io.files kernel
+locals math mongodb.msg namespaces sequences uuid
+bson.writer.private ;
 IN: mongodb.operations
 
 <PRIVATE
diff --git a/extra/synth/buffers/buffers.factor b/extra/synth/buffers/buffers.factor
index 978fb32d42..e71b136940 100644
--- a/extra/synth/buffers/buffers.factor
+++ b/extra/synth/buffers/buffers.factor
@@ -1,8 +1,8 @@
 ! Copyright (C) 2008 Alex Chapman
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien.c-types combinators kernel locals math
+USING: accessors alien combinators kernel locals math
 math.ranges openal sequences sequences.merged specialized-arrays ;
-FROM: alien.c-types => short ;
+FROM: alien.c-types => short uchar ;
 SPECIALIZED-ARRAY: uchar
 SPECIALIZED-ARRAY: short
 IN: synth.buffers
diff --git a/vm/io.cpp b/vm/io.cpp
index 8eaaa453b5..0682a1d124 100755
--- a/vm/io.cpp
+++ b/vm/io.cpp
@@ -218,14 +218,13 @@ void factor_vm::primitive_fputc()
 void factor_vm::primitive_fwrite()
 {
 	FILE *file = pop_file_handle();
-	byte_array *text = untag_check<byte_array>(ctx->pop());
-	cell length = array_capacity(text);
-	char *string = (char *)(text + 1);
+	cell length = to_cell(ctx->pop());
+	char *text = alien_offset(ctx->pop());
 
 	if(length == 0)
 		return;
 
-	size_t written = safe_fwrite(string,1,length,file);
+	size_t written = safe_fwrite(text,1,length,file);
 	if(written != length)
 		io_error();
 }
@@ -238,8 +237,8 @@ void factor_vm::primitive_ftell()
 
 void factor_vm::primitive_fseek()
 {
-	int whence = to_fixnum(ctx->pop());
 	FILE *file = pop_file_handle();
+	int whence = to_fixnum(ctx->pop());
 	off_t offset = to_signed_8(ctx->pop());
 	safe_fseek(file,offset,whence);
 }

From fa6c8117aad6c7bc7a5b489b258ef50c1a893306 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Wed, 24 Feb 2010 20:18:48 +1300
Subject: [PATCH 225/250] cocoa.messages: cleanup

---
 basis/cocoa/messages/messages.factor | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/basis/cocoa/messages/messages.factor b/basis/cocoa/messages/messages.factor
index 2569c391d1..a744087037 100644
--- a/basis/cocoa/messages/messages.factor
+++ b/basis/cocoa/messages/messages.factor
@@ -237,8 +237,8 @@ ERROR: no-objc-type name ;
 
 : import-objc-class ( name quot -- )
     2dup swap define-objc-class-word
-    over objc_getClass [ drop ] [ call( -- ) ] if
-    dup objc_getClass [
+    over class-exists? [ drop ] [ call( -- ) ] if
+    dup class-exists? [
         [ objc_getClass register-objc-methods ]
         [ objc_getMetaClass register-objc-methods ] bi
     ] [ drop ] if ;

From 187e0f96ca3e03bae45ca56eb958157f6a3f801d Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Wed, 24 Feb 2010 20:24:32 +1300
Subject: [PATCH 226/250] Move closures, fries and set-n to unmaintained

---
 {extra => unmaintained}/closures/closures.factor | 0
 {extra => unmaintained}/fries/authors.txt        | 0
 {extra => unmaintained}/fries/fries.factor       | 0
 {extra => unmaintained}/fries/summary.txt        | 0
 {extra => unmaintained}/set-n/set-n.factor       | 0
 5 files changed, 0 insertions(+), 0 deletions(-)
 rename {extra => unmaintained}/closures/closures.factor (100%)
 rename {extra => unmaintained}/fries/authors.txt (100%)
 rename {extra => unmaintained}/fries/fries.factor (100%)
 rename {extra => unmaintained}/fries/summary.txt (100%)
 rename {extra => unmaintained}/set-n/set-n.factor (100%)

diff --git a/extra/closures/closures.factor b/unmaintained/closures/closures.factor
similarity index 100%
rename from extra/closures/closures.factor
rename to unmaintained/closures/closures.factor
diff --git a/extra/fries/authors.txt b/unmaintained/fries/authors.txt
similarity index 100%
rename from extra/fries/authors.txt
rename to unmaintained/fries/authors.txt
diff --git a/extra/fries/fries.factor b/unmaintained/fries/fries.factor
similarity index 100%
rename from extra/fries/fries.factor
rename to unmaintained/fries/fries.factor
diff --git a/extra/fries/summary.txt b/unmaintained/fries/summary.txt
similarity index 100%
rename from extra/fries/summary.txt
rename to unmaintained/fries/summary.txt
diff --git a/extra/set-n/set-n.factor b/unmaintained/set-n/set-n.factor
similarity index 100%
rename from extra/set-n/set-n.factor
rename to unmaintained/set-n/set-n.factor

From 2aa1a3dbd7f14836c0c19692b9b0ba6562046aca Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Tue, 23 Feb 2010 23:50:34 -0800
Subject: [PATCH 227/250] ui.backend.cocoa: invalidate run loop timers before
 raising an NSAlert and add them back when runModal returns to avoid run loop
 callbacks reentering Factor

---
 basis/core-foundation/run-loop/run-loop.factor | 3 +++
 basis/ui/backend/cocoa/cocoa.factor            | 4 +++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/basis/core-foundation/run-loop/run-loop.factor b/basis/core-foundation/run-loop/run-loop.factor
index 2370dd4562..e2ba06d61f 100644
--- a/basis/core-foundation/run-loop/run-loop.factor
+++ b/basis/core-foundation/run-loop/run-loop.factor
@@ -91,6 +91,9 @@ TUPLE: run-loop fds sources timers ;
         CFRunLoopAddTimer
     ] bi ;
 
+: invalidate-run-loop-timers ( -- )
+    run-loop [ [ [ CFRunLoopTimerInvalidate ] [ CFRelease ] bi ] each V{ } ] change-timers drop ;
+
 <PRIVATE
 
 : ((reset-timer)) ( timer counter timestamp -- )
diff --git a/basis/ui/backend/cocoa/cocoa.factor b/basis/ui/backend/cocoa/cocoa.factor
index 6e64c35e49..d4f9b82cff 100644
--- a/basis/ui/backend/cocoa/cocoa.factor
+++ b/basis/ui/backend/cocoa/cocoa.factor
@@ -214,6 +214,7 @@ M: cocoa-ui-backend beep ( -- )
     NSBeep ;
 
 M: cocoa-ui-backend system-alert
+    invalidate-run-loop-timers
     NSAlert -> alloc -> init -> autorelease [
         {
             [ swap <NSString> -> setInformativeText: ]
@@ -221,7 +222,8 @@ M: cocoa-ui-backend system-alert
             [ "OK" <NSString> -> addButtonWithTitle: drop ]
             [ -> runModal drop ]
         } cleave
-    ] [ 2drop ] if* ;
+    ] [ 2drop ] if*
+    init-thread-timer ;
 
 CLASS: {
     { +superclass+ "NSObject" }

From 570e332f849b34db4fa44612b9d7c65572a38d25 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Wed, 24 Feb 2010 21:18:29 +1300
Subject: [PATCH 228/250] core-foundation.run-loop: cleanup

---
 basis/core-foundation/run-loop/run-loop.factor | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/basis/core-foundation/run-loop/run-loop.factor b/basis/core-foundation/run-loop/run-loop.factor
index e2ba06d61f..56b5a9c798 100644
--- a/basis/core-foundation/run-loop/run-loop.factor
+++ b/basis/core-foundation/run-loop/run-loop.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2008 Slava Pestov
+! Copyright (C) 2008, 2010 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors alien alien.c-types alien.syntax kernel math
 namespaces sequences destructors combinators threads heaps
@@ -92,7 +92,10 @@ TUPLE: run-loop fds sources timers ;
     ] bi ;
 
 : invalidate-run-loop-timers ( -- )
-    run-loop [ [ [ CFRunLoopTimerInvalidate ] [ CFRelease ] bi ] each V{ } ] change-timers drop ;
+    run-loop [
+        [ [ CFRunLoopTimerInvalidate ] [ CFRelease ] bi ] each
+        V{ } clone
+    ] change-timers drop ;
 
 <PRIVATE
 

From ca8be54c96e0e4f0759d49e9327e9b4b7ac63400 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Wed, 24 Feb 2010 21:20:21 +1300
Subject: [PATCH 229/250] io.files.unix: fix load errors arising from
 byte-length being moved

---
 basis/io/files/info/unix/freebsd/freebsd.factor | 2 +-
 basis/io/files/info/unix/netbsd/netbsd.factor   | 2 +-
 basis/io/files/info/unix/openbsd/openbsd.factor | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/basis/io/files/info/unix/freebsd/freebsd.factor b/basis/io/files/info/unix/freebsd/freebsd.factor
index f1d6b4db66..7c13d86a3c 100644
--- a/basis/io/files/info/unix/freebsd/freebsd.factor
+++ b/basis/io/files/info/unix/freebsd/freebsd.factor
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien.c-types alien.syntax combinators
+USING: accessors alien alien.c-types alien.syntax combinators
 io.backend io.files io.files.info io.files.unix kernel math system unix
 unix.statfs.freebsd unix.statvfs.freebsd unix.getfsstat.freebsd
 sequences grouping alien.strings io.encodings.utf8 unix.types
diff --git a/basis/io/files/info/unix/netbsd/netbsd.factor b/basis/io/files/info/unix/netbsd/netbsd.factor
index 9e37ec8aa9..9ea475433b 100644
--- a/basis/io/files/info/unix/netbsd/netbsd.factor
+++ b/basis/io/files/info/unix/netbsd/netbsd.factor
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.syntax kernel unix.stat math unix
+USING: alien alien.syntax kernel unix.stat math unix
 combinators system io.backend accessors alien.c-types
 io.encodings.utf8 alien.strings unix.types io.files.unix
 io.files io.files.info unix.statvfs.netbsd unix.getfsstat.netbsd arrays
diff --git a/basis/io/files/info/unix/openbsd/openbsd.factor b/basis/io/files/info/unix/openbsd/openbsd.factor
index be88929f2e..e80a4fdafd 100644
--- a/basis/io/files/info/unix/openbsd/openbsd.factor
+++ b/basis/io/files/info/unix/openbsd/openbsd.factor
@@ -1,6 +1,6 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien.c-types alien.strings alien.syntax
+USING: accessors alien alien.c-types alien.strings alien.syntax
 combinators io.backend io.files io.files.info io.files.unix kernel math
 sequences system unix unix.getfsstat.openbsd grouping
 unix.statfs.openbsd unix.statvfs.openbsd unix.types

From dad3870abd4d994fb490f5cb6f24c28a372a9abc Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Wed, 24 Feb 2010 02:47:45 -0600
Subject: [PATCH 230/250] Use for(;;) instead of do/while in a few places, fix
 safe_fread's error handling

---
 vm/io.cpp | 66 ++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 41 insertions(+), 25 deletions(-)

diff --git a/vm/io.cpp b/vm/io.cpp
index 0682a1d124..fdd872457e 100755
--- a/vm/io.cpp
+++ b/vm/io.cpp
@@ -34,20 +34,22 @@ void factor_vm::io_error()
 FILE *factor_vm::safe_fopen(char *filename, char *mode)
 {
 	FILE *file;
-	do {
+	for(;;)
+	{
 		file = fopen(filename,mode);
 		if(file == NULL)
 			io_error();
 		else
 			break;
-	} while(errno == EINTR);
+	}
 	return file;
 }
 
 int factor_vm::safe_fgetc(FILE *stream)
 {
 	int c;
-	do {
+	for(;;)
+	{
 		c = fgetc(stream);
 		if(c == EOF)
 		{
@@ -58,38 +60,53 @@ int factor_vm::safe_fgetc(FILE *stream)
 		}
 		else
 			break;
-	} while(errno == EINTR);
+	}
 	return c;
 }
 
 size_t factor_vm::safe_fread(void *ptr, size_t size, size_t nitems, FILE *stream)
 {
 	size_t items_read = 0;
+	size_t ret = 0;
 
-	do {
-		items_read += fread((void*)((int*)ptr+items_read*size),size,nitems-items_read,stream);
-	} while(items_read != nitems && errno == EINTR);
+	do
+	{
+		ret = fread((void*)((int*)ptr+items_read*size),size,nitems-items_read,stream);
+		if(ret == 0)
+		{
+			if(feof(stream))
+				break;
+			else
+				io_error();
+		}
+		items_read += ret;
+	} while(items_read != nitems);
 
 	return items_read;
 }
 
 void factor_vm::safe_fputc(int c, FILE *stream)
 {
-	do {
+	for(;;)
+	{
 		if(fputc(c,stream) == EOF)
 			io_error();
 		else
 			break;
-	} while(errno == EINTR);
+	}
 }
 
 size_t factor_vm::safe_fwrite(void *ptr, size_t size, size_t nitems, FILE *stream)
 {
 	size_t items_written = 0;
+	size_t ret = 0;
 
 	do {
-		items_written += fwrite((void*)((int*)ptr+items_written*size),size,nitems-items_written,stream);
-	} while(items_written != nitems && errno == EINTR);
+		ret = fwrite((void*)((int*)ptr+items_written*size),size,nitems-items_written,stream);
+		if(ret == 0)
+			io_error();
+		items_written += ret;
+	} while(items_written != nitems);
 
 	return items_written;
 }
@@ -97,12 +114,13 @@ size_t factor_vm::safe_fwrite(void *ptr, size_t size, size_t nitems, FILE *strea
 int factor_vm::safe_ftell(FILE *stream)
 {
 	off_t offset;
-	do {
+	for(;;)
+	{
 		if((offset = FTELL(stream)) == -1)
 			io_error();
 		else
 			break;
-	} while(errno == EINTR);
+	}
 	return offset;
 }
 
@@ -117,32 +135,35 @@ void factor_vm::safe_fseek(FILE *stream, off_t offset, int whence)
 		critical_error("Bad value for whence",whence);
 	}
 
-	do {
+	for(;;)
+	{
 		if(FSEEK(stream,offset,whence) == -1)
 			io_error();
 		else
 			break;
-	} while(errno == EINTR);
+	}
 }
 
 void factor_vm::safe_fflush(FILE *stream)
 {
-	do {
+	for(;;)
+	{
 		if(fflush(stream) == EOF)
 			io_error();
 		else
 			break;
-	} while(errno == EINTR);
+	}
 }
 
 void factor_vm::safe_fclose(FILE *stream)
 {
-	do {
+	for(;;)
+	{
 		if(fclose(stream) == EOF)
 			io_error();
 		else
 			break;
-	} while(errno == EINTR);
+	}
 }
 
 void factor_vm::primitive_fopen()
@@ -189,12 +210,7 @@ void factor_vm::primitive_fread()
 
 	int c = safe_fread(buf.untagged() + 1,1,size,file);
 	if(c == 0)
-	{
-		if(feof(file))
-			ctx->push(false_object);
-		else
-			io_error();
-	}
+		ctx->push(false_object);
 	else
 	{
 		if(feof(file))

From 3bf5eeddf93362d332e7a18d3f21d3b7a070efa4 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Wed, 24 Feb 2010 00:51:02 -0800
Subject: [PATCH 231/250] tidy up load errors in ui.backend.x11

---
 basis/ui/backend/x11/x11.factor | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/basis/ui/backend/x11/x11.factor b/basis/ui/backend/x11/x11.factor
index ee6eb813b0..6a7a8d147f 100644
--- a/basis/ui/backend/x11/x11.factor
+++ b/basis/ui/backend/x11/x11.factor
@@ -329,10 +329,10 @@ M: x11-ui-backend beep ( -- )
 
 <PRIVATE
 : escape-' ( string -- string' )
-    [ dup CHAR: ' = [ drop "'\''" ] [ 1string ] if ] { } map-as concat ;
+    [ dup CHAR: ' = [ drop "'\\''" ] [ 1string ] if ] { } map-as concat ;
 
 : xmessage ( string -- )
-    escape-' "/usr/X11R6/bin/xmessage '" "'" surround system ;
+    escape-' "/usr/X11R6/bin/xmessage '" "'" surround system drop ;
 PRIVATE>
 
 M: x11-ui-backend system-alert

From ebd2cce1bed8d3b23e9fcfd05ba6dab650302498 Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Wed, 24 Feb 2010 03:32:02 -0600
Subject: [PATCH 232/250] Add some commented out unit tests to io.ports.tests
 that seem like they should be supported

---
 basis/io/ports/ports-tests.factor | 42 ++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/basis/io/ports/ports-tests.factor b/basis/io/ports/ports-tests.factor
index e637999880..7d8c799017 100644
--- a/basis/io/ports/ports-tests.factor
+++ b/basis/io/ports/ports-tests.factor
@@ -1,6 +1,7 @@
 USING: destructors io io.encodings.binary io.files io.directories
 io.files.temp io.ports kernel sequences math
-specialized-arrays.instances.alien.c-types.int tools.test ;
+specialized-arrays.instances.alien.c-types.int tools.test
+specialized-arrays alien.c-types classes.struct alien ;
 IN: io.ports.tests
 
 ! Make sure that writing malloced storage to a file works, and
@@ -20,4 +21,43 @@ IN: io.ports.tests
     ] with-file-reader
 ] unit-test
 
+USE: multiline
+/*
+[ ] [
+    BV{ 0 1 2 } "test.txt" temp-file binary set-file-contents
+] unit-test
+
+[ t ] [
+    "test.txt" temp-file binary file-contents
+    B{ 0 1 2 } =
+] unit-test
+
+STRUCT: pt { x uint } { y uint } ;
+SPECIALIZED-ARRAY: pt
+
+CONSTANT: pt-array-1
+    pt-array{ S{ pt f 1 1 } S{ pt f 2 2 } S{ pt f 3 3 } }
+
+[ ] [
+    pt-array-1
+    "test.txt" temp-file binary set-file-contents
+] unit-test
+
+[ t ] [
+    "test.txt" temp-file binary file-contents
+    pt-array-1 >c-ptr sequence=
+] unit-test
+
+[ ] [
+    pt-array-1 rest-slice 
+    "test.txt" temp-file binary set-file-contents
+] unit-test
+
+[ t ] [
+    "test.txt" temp-file binary file-contents
+    pt-array-1 rest-slice >c-ptr sequence=
+] unit-test
+
+*/
+
 [ ] [ "test.txt" temp-file delete-file ] unit-test

From 17b095a5243c0ec94acb336d06cec2890159c08c Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 25 Feb 2010 04:50:31 +1300
Subject: [PATCH 233/250] Slices over specialized arrays can now be passed to C
 functions, written to binary output streams, and given to malloc-byte-array

---
 basis/alien/data/data-docs.factor             | 11 +---
 basis/alien/data/data.factor                  | 14 +++--
 basis/base64/base64.factor                    |  4 +-
 basis/io/buffers/buffers-tests.factor         |  5 +-
 basis/io/buffers/buffers.factor               |  2 +-
 basis/io/encodings/utf32/utf32-tests.factor   |  6 +--
 basis/io/ports/ports-tests.factor             | 54 +++----------------
 basis/serialize/serialize-tests.factor        | 14 ++---
 .../specialized-arrays-tests.factor           |  5 +-
 .../specialized-arrays.factor                 |  2 +-
 .../specialized-vectors.factor                |  4 +-
 basis/ui/backend/windows/windows.factor       |  2 +-
 .../directx/dinput/constants/constants.factor |  5 +-
 core/alien/alien-docs.factor                  | 14 +++--
 core/alien/alien.factor                       | 30 +++++++----
 core/io/files/files-tests.factor              | 49 +++++++++++++++--
 .../byte-array/byte-array-tests.factor        |  1 +
 17 files changed, 117 insertions(+), 105 deletions(-)

diff --git a/basis/alien/data/data-docs.factor b/basis/alien/data/data-docs.factor
index 6ab6d56bc7..4600ea6837 100644
--- a/basis/alien/data/data-docs.factor
+++ b/basis/alien/data/data-docs.factor
@@ -21,11 +21,6 @@ HELP: memory>byte-array
 { $values { "alien" c-ptr } { "len" "a non-negative integer" } { "byte-array" byte-array } }
 { $description "Reads " { $snippet "len" } " bytes starting from " { $snippet "base" } " and stores them in a new byte array." } ;
 
-HELP: byte-array>memory
-{ $values { "byte-array" byte-array } { "base" c-ptr } }
-{ $description "Writes a byte array to memory starting from the " { $snippet "base" } " address." }
-{ $warning "This word is unsafe. Improper use can corrupt memory." } ;
-
 HELP: malloc-array
 { $values { "n" "a non-negative integer" } { "type" "a C type" } { "array" "a specialized array" } }
 { $description "Allocates an unmanaged memory block large enough to hold " { $snippet "n" } " values of a C type, then wraps the memory in a sequence object using " { $link <c-direct-array> } "." }
@@ -75,9 +70,7 @@ $nl
 "You can unsafely copy a range of bytes from one memory location to another:"
 { $subsections memcpy }
 "You can copy a range of bytes from memory into a byte array:"
-{ $subsections memory>byte-array }
-"You can copy a byte array to memory unsafely:"
-{ $subsections byte-array>memory } ;
+{ $subsections memory>byte-array } ;
 
 ARTICLE: "c-pointers" "Passing pointers to C functions"
 "The following Factor objects may be passed to C function parameters with pointer types:"
@@ -85,7 +78,7 @@ ARTICLE: "c-pointers" "Passing pointers to C functions"
     { "Instances of " { $link alien } "." }
     { "Instances of " { $link f } "; this is interpreted as a null pointer." }
     { "Instances of " { $link byte-array } "; the C function receives a pointer to the first element of the array." }
-    { "Any data type which defines a method on " { $link >c-ptr } " that returns an instance of one of the above. This includes " { $link "classes.struct" } " and " { $link "specialized-arrays" } "." } 
+    { "Any data type which defines a method on " { $link >c-ptr } ". This includes " { $link "classes.struct" } " and " { $link "specialized-arrays" } "." }
 }
 "The class of primitive C pointer types:"
 { $subsections c-ptr }
diff --git a/basis/alien/data/data.factor b/basis/alien/data/data.factor
index 462bed8b76..2d572e9f13 100644
--- a/basis/alien/data/data.factor
+++ b/basis/alien/data/data.factor
@@ -49,7 +49,7 @@ M: word <c-direct-array>
     heap-size malloc ; inline
 
 : malloc-byte-array ( byte-array -- alien )
-    dup byte-length [ nip malloc dup ] 2keep memcpy ;
+    binary-object [ nip malloc dup ] 2keep memcpy ;
 
 : memory>byte-array ( alien len -- byte-array )
     [ nip (byte-array) dup ] 2keep memcpy ;
@@ -63,14 +63,12 @@ M: memory-stream stream-read
         swap memory>byte-array
     ] [ [ + ] change-index drop ] 2bi ;
 
-: byte-array>memory ( byte-array base -- )
-    swap dup byte-length memcpy ; inline
-
 M: byte-vector stream-write
-    [ binary-object ] dip
-    [ [ length + ] keep lengthen drop ]
-    [ '[ _ underlying>> ] 2dip memcpy ]
-    3bi ;
+    [ dup byte-length tail-slice ]
+    [ [ [ byte-length ] bi@ + ] keep lengthen ]
+    [ drop byte-length ]
+    2tri
+    [ >c-ptr swap >c-ptr ] dip memcpy ;
 
 M: value-type c-type-rep drop int-rep ;
 
diff --git a/basis/base64/base64.factor b/basis/base64/base64.factor
index 1a0648cef8..9a57740936 100644
--- a/basis/base64/base64.factor
+++ b/basis/base64/base64.factor
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: combinators io io.binary io.encodings.binary
 io.streams.byte-array kernel math namespaces
-sequences strings io.crlf ;
+sequences strings ;
 IN: base64
 
 ERROR: malformed-base64 ;
@@ -35,7 +35,7 @@ SYMBOL: column
 : write1-lines ( ch -- )
     write1
     column get [
-        1 + [ 76 = [ crlf ] when ]
+        1 + [ 76 = [ B{ CHAR: \r CHAR: \n } write ] when ]
         [ 76 mod column set ] bi
     ] when* ;
 
diff --git a/basis/io/buffers/buffers-tests.factor b/basis/io/buffers/buffers-tests.factor
index 836b4d0cc8..07e783f267 100644
--- a/basis/io/buffers/buffers-tests.factor
+++ b/basis/io/buffers/buffers-tests.factor
@@ -4,8 +4,9 @@ kernel.private libc sequences tools.test namespaces byte-arrays
 strings accessors destructors ;
 
 : buffer-set ( string buffer -- )
-    over >byte-array over ptr>> byte-array>memory
-    [ length ] dip buffer-reset ;
+    [ ptr>> swap >byte-array binary-object memcpy ]
+    [ [ length ] dip buffer-reset ]
+    2bi ;
 
 : string>buffer ( string -- buffer )
     dup length <buffer> [ buffer-set ] keep ;
diff --git a/basis/io/buffers/buffers.factor b/basis/io/buffers/buffers.factor
index ce5ad2c9a0..562abad082 100644
--- a/basis/io/buffers/buffers.factor
+++ b/basis/io/buffers/buffers.factor
@@ -60,7 +60,7 @@ HINTS: buffer-read fixnum buffer ;
 HINTS: n>buffer fixnum buffer ;
 
 : >buffer ( byte-array buffer -- )
-    [ buffer-end byte-array>memory ]
+    [ buffer-end swap binary-object memcpy ]
     [ [ byte-length ] dip n>buffer ]
     2bi ;
 
diff --git a/basis/io/encodings/utf32/utf32-tests.factor b/basis/io/encodings/utf32/utf32-tests.factor
index 2a80e47c7b..adff0ecf4b 100644
--- a/basis/io/encodings/utf32/utf32-tests.factor
+++ b/basis/io/encodings/utf32/utf32-tests.factor
@@ -12,7 +12,7 @@ IN: io.encodings.utf32.tests
 [ { CHAR: replacement-character } ] [ B{ 0 } utf32be decode >array ] unit-test
 [ { } ] [ { } utf32be decode >array ] unit-test
 
-[ { 0 0 0 CHAR: x 0 1 HEX: D1 HEX: 1E } ] [ { CHAR: x HEX: 1d11e } >string utf32be encode >array ] unit-test
+[ B{ 0 0 0 CHAR: x 0 1 HEX: D1 HEX: 1E } ] [ { CHAR: x HEX: 1d11e } >string utf32be encode ] unit-test
 
 [ { CHAR: x } ] [ B{ CHAR: x 0 0 0 } utf32le decode >array ] unit-test
 [ { HEX: 1d11e } ] [ B{ HEX: 1e HEX: d1 1 0 } utf32le decode >array ] unit-test
@@ -21,10 +21,10 @@ IN: io.encodings.utf32.tests
 [ { CHAR: replacement-character } ] [ B{ HEX: 1e } utf32le decode >array ] unit-test
 [ { } ] [ { } utf32le decode >array ] unit-test
 
-[ { 120 0 0 0 HEX: 1e HEX: d1 1 0 } ] [ { CHAR: x HEX: 1d11e } >string utf32le encode >array ] unit-test
+[ B{ 120 0 0 0 HEX: 1e HEX: d1 1 0 } ] [ { CHAR: x HEX: 1d11e } >string utf32le encode ] unit-test
 
 [ { CHAR: x } ] [ B{ HEX: ff HEX: fe 0 0 CHAR: x 0 0 0 } utf32 decode >array ] unit-test
 [ { CHAR: x } ] [ B{ 0 0 HEX: fe HEX: ff 0 0 0 CHAR: x } utf32 decode >array ] unit-test
 
-[ { HEX: ff HEX: fe 0 0 120 0 0 0 HEX: 1e HEX: d1 1 0 } ] [ { CHAR: x HEX: 1d11e } >string utf32 encode >array ] unit-test
+[ B{ HEX: ff HEX: fe 0 0 120 0 0 0 HEX: 1e HEX: d1 1 0 } ] [ { CHAR: x HEX: 1d11e } >string utf32 encode ] unit-test
 
diff --git a/basis/io/ports/ports-tests.factor b/basis/io/ports/ports-tests.factor
index 7d8c799017..c7af6909e1 100644
--- a/basis/io/ports/ports-tests.factor
+++ b/basis/io/ports/ports-tests.factor
@@ -1,7 +1,6 @@
-USING: destructors io io.encodings.binary io.files io.directories
-io.files.temp io.ports kernel sequences math
-specialized-arrays.instances.alien.c-types.int tools.test
-specialized-arrays alien.c-types classes.struct alien ;
+USING: destructors io io.directories io.encodings.binary
+io.files io.files.temp kernel libc math sequences
+specialized-arrays.instances.alien.c-types.int tools.test ;
 IN: io.ports.tests
 
 ! Make sure that writing malloced storage to a file works, and
@@ -9,9 +8,11 @@ IN: io.ports.tests
 
 [ ] [
     "test.txt" temp-file binary [
-        100,000 iota
-        0
-        100,000 malloc-int-array &dispose [ copy ] keep write
+        [
+            100,000 iota
+            0
+            100,000 malloc-int-array &free [ copy ] keep write
+        ] with-destructors
     ] with-file-writer
 ] unit-test
 
@@ -21,43 +22,4 @@ IN: io.ports.tests
     ] with-file-reader
 ] unit-test
 
-USE: multiline
-/*
-[ ] [
-    BV{ 0 1 2 } "test.txt" temp-file binary set-file-contents
-] unit-test
-
-[ t ] [
-    "test.txt" temp-file binary file-contents
-    B{ 0 1 2 } =
-] unit-test
-
-STRUCT: pt { x uint } { y uint } ;
-SPECIALIZED-ARRAY: pt
-
-CONSTANT: pt-array-1
-    pt-array{ S{ pt f 1 1 } S{ pt f 2 2 } S{ pt f 3 3 } }
-
-[ ] [
-    pt-array-1
-    "test.txt" temp-file binary set-file-contents
-] unit-test
-
-[ t ] [
-    "test.txt" temp-file binary file-contents
-    pt-array-1 >c-ptr sequence=
-] unit-test
-
-[ ] [
-    pt-array-1 rest-slice 
-    "test.txt" temp-file binary set-file-contents
-] unit-test
-
-[ t ] [
-    "test.txt" temp-file binary file-contents
-    pt-array-1 rest-slice >c-ptr sequence=
-] unit-test
-
-*/
-
 [ ] [ "test.txt" temp-file delete-file ] unit-test
diff --git a/basis/serialize/serialize-tests.factor b/basis/serialize/serialize-tests.factor
index 036356e137..9213a54004 100644
--- a/basis/serialize/serialize-tests.factor
+++ b/basis/serialize/serialize-tests.factor
@@ -4,7 +4,8 @@
 USING: tools.test kernel serialize io io.streams.byte-array
 alien arrays byte-arrays bit-arrays specialized-arrays
 sequences math prettyprint parser classes math.constants
-io.encodings.binary random assocs serialize.private alien.c-types ;
+io.encodings.binary random assocs serialize.private alien.c-types
+combinators.short-circuit ;
 SPECIALIZED-ARRAY: double
 IN: serialize.tests
 
@@ -16,11 +17,12 @@ IN: serialize.tests
 [ t ] [
     100 [
         drop
-        40 [        test-serialize-cell ] all-integers?
-         4 [ 40 *   test-serialize-cell ] all-integers?
-         4 [ 400 *  test-serialize-cell ] all-integers?
-         4 [ 4000 * test-serialize-cell ] all-integers?
-        and and and
+        {
+            [ 40 [        test-serialize-cell ] all-integers? ]
+            [  4 [ 40 *   test-serialize-cell ] all-integers? ]
+            [  4 [ 400 *  test-serialize-cell ] all-integers? ]
+            [  4 [ 4000 * test-serialize-cell ] all-integers? ]
+        } 0&&
     ] all-integers?
 ] unit-test
 
diff --git a/basis/specialized-arrays/specialized-arrays-tests.factor b/basis/specialized-arrays/specialized-arrays-tests.factor
index c25f8ae3b1..645606edc5 100644
--- a/basis/specialized-arrays/specialized-arrays-tests.factor
+++ b/basis/specialized-arrays/specialized-arrays-tests.factor
@@ -1,12 +1,13 @@
 IN: specialized-arrays.tests
 USING: tools.test alien.syntax specialized-arrays
-specialized-arrays.private sequences alien.c-types accessors
+specialized-arrays.private sequences alien accessors
 kernel arrays combinators compiler compiler.units classes.struct
 combinators.smart compiler.tree.debugger math libc destructors
 sequences.private multiline eval words vocabs namespaces
 assocs prettyprint alien.data math.vectors definitions
 compiler.test ;
-FROM: alien.c-types => float ;
+FROM: alien.c-types => int float bool char float ulonglong ushort uint
+heap-size little-endian? ;
 
 SPECIALIZED-ARRAY: int
 SPECIALIZED-ARRAYS: bool ushort char uint float ulonglong ;
diff --git a/basis/specialized-arrays/specialized-arrays.factor b/basis/specialized-arrays/specialized-arrays.factor
index f7070c68e1..b052becfed 100644
--- a/basis/specialized-arrays/specialized-arrays.factor
+++ b/basis/specialized-arrays/specialized-arrays.factor
@@ -95,7 +95,7 @@ M: A resize
     ] [ drop ] 2bi
     <direct-A> ; inline
 
-M: A byte-length length \ T heap-size * ; inline
+M: A element-size drop \ T heap-size ; inline
 
 M: A direct-array-syntax drop \ A@ ;
 
diff --git a/basis/specialized-vectors/specialized-vectors.factor b/basis/specialized-vectors/specialized-vectors.factor
index c16fe2510d..0c0569ea9d 100644
--- a/basis/specialized-vectors/specialized-vectors.factor
+++ b/basis/specialized-vectors/specialized-vectors.factor
@@ -1,4 +1,4 @@
-! Copyright (C) 2008, 2009 Slava Pestov.
+! Copyright (C) 2008, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors alien alien.c-types alien.parser assocs
 compiler.units functors growable kernel lexer math namespaces
@@ -26,7 +26,7 @@ V A <A> vectors.functor:define-vector
 
 M: V contract 2drop ; inline
 
-M: V byte-length length \ T heap-size * ; inline
+M: V element-size drop \ T heap-size ; inline
 
 M: V pprint-delims drop \ V{ \ } ;
 
diff --git a/basis/ui/backend/windows/windows.factor b/basis/ui/backend/windows/windows.factor
index 5863d3f39d..0bf2e88468 100644
--- a/basis/ui/backend/windows/windows.factor
+++ b/basis/ui/backend/windows/windows.factor
@@ -212,7 +212,7 @@ PRIVATE>
             dup win32-error=0/f
     
         dup GlobalLock dup win32-error=0/f
-        swapd byte-array>memory
+        rot binary-object memcpy
         dup GlobalUnlock win32-error=0/f
         CF_UNICODETEXT swap SetClipboardData win32-error=0/f
     ] with-clipboard ;
diff --git a/basis/windows/directx/dinput/constants/constants.factor b/basis/windows/directx/dinput/constants/constants.factor
index 26f9da00ec..ba4d750174 100644
--- a/basis/windows/directx/dinput/constants/constants.factor
+++ b/basis/windows/directx/dinput/constants/constants.factor
@@ -72,10 +72,7 @@ M: array array-base-type first ;
     call swap set-global ; inline
 
 : (malloc-guid-symbol) ( symbol guid -- )
-    '[
-        _ execute( -- value )
-        [ byte-length malloc ] [ over byte-array>memory ] bi
-    ] initialize ;
+    '[ _ execute( -- value ) malloc-byte-array ] initialize ;
 
 : define-guid-constants ( -- )
     {
diff --git a/core/alien/alien-docs.factor b/core/alien/alien-docs.factor
index 60c1cdaf69..99f3a2b0f4 100644
--- a/core/alien/alien-docs.factor
+++ b/core/alien/alien-docs.factor
@@ -1,18 +1,24 @@
 USING: byte-arrays arrays help.syntax help.markup
 alien.syntax compiler definitions math libc eval
 debugger parser io io.backend system alien.accessors
-alien.libraries alien.c-types quotations kernel ;
+alien.libraries alien.c-types quotations kernel
+sequences ;
 IN: alien
 
 HELP: >c-ptr
-{ $values { "object" object } { "c-ptr" c-ptr } }
+{ $values { "obj" object } { "c-ptr" c-ptr } }
 { $contract "Outputs a pointer to the binary data of this object." } ;
 
 HELP: byte-length
-{ $values { "object" object } { "n" "a non-negative integer" } }
+{ $values { "obj" object } { "n" "a non-negative integer" } }
 { $contract "Outputs the number of bytes of binary data that will be output by " { $link >c-ptr } "." } ;
 
-{ >c-ptr byte-length } related-words
+HELP: element-size
+{ $values { "seq" sequence } { "n" "a non-negative integer" } }
+{ $contract "Outputs the number of bytes used for each element of the sequence." }
+{ $notes "If a sequence class implements " { $link element-size } " and " { $link >c-ptr } ", then instances of this sequence, as well as slices of this sequence, can be used as binary objects." } ;
+
+{ >c-ptr element-size byte-length } related-words
 
 HELP: alien
 { $class-description "The class of alien pointers. See " { $link "syntax-aliens" } " for syntax and " { $link "c-data" } " for general information." } ;
diff --git a/core/alien/alien.factor b/core/alien/alien.factor
index 42f48f97aa..3802147838 100644
--- a/core/alien/alien.factor
+++ b/core/alien/alien.factor
@@ -1,30 +1,42 @@
 ! Copyright (C) 2004, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs kernel math namespaces sequences system
-kernel.private byte-arrays arrays init ;
+kernel.private byte-arrays byte-vectors arrays init ;
 IN: alien
 
 PREDICATE: pinned-alien < alien underlying>> not ;
 
 UNION: pinned-c-ptr pinned-alien POSTPONE: f ;
 
+GENERIC: element-size ( seq -- n ) flushable
+
+M: byte-array element-size drop 1 ; inline
+
+M: byte-vector element-size drop 1 ; inline
+
+M: slice element-size seq>> element-size ; inline
+
+M: f element-size drop 1 ; inline
+
+GENERIC: byte-length ( obj -- n ) flushable
+
+M: object byte-length [ length ] [ element-size ] bi * ; inline
+
 GENERIC: >c-ptr ( obj -- c-ptr ) flushable
 
 M: c-ptr >c-ptr ; inline
 
-GENERIC: byte-length ( seq -- n ) flushable
-
-M: byte-array byte-length length ; inline
-
-M: f byte-length drop 0 ; inline
-
-: binary-object ( obj -- c-ptr n )
-    [ >c-ptr ] [ byte-length ] bi ; inline
+M: slice >c-ptr
+    [ [ from>> ] [ element-size ] bi * ] [ seq>> >c-ptr ] bi
+    <displaced-alien> ; inline
 
 SLOT: underlying
 
 M: object >c-ptr underlying>> ; inline
 
+: binary-object ( obj -- c-ptr n )
+    [ >c-ptr ] [ byte-length ] bi ; inline
+
 GENERIC: expired? ( c-ptr -- ? ) flushable
 
 M: alien expired? expired>> ;
diff --git a/core/io/files/files-tests.factor b/core/io/files/files-tests.factor
index cf58dbfe05..5db1822d9e 100644
--- a/core/io/files/files-tests.factor
+++ b/core/io/files/files-tests.factor
@@ -1,8 +1,9 @@
-USING: arrays debugger.threads destructors io io.directories
-io.encodings.ascii io.encodings.binary io.encodings.string
-io.encodings.8-bit.latin1 io.files io.files.private
-io.files.temp io.files.unique kernel make math sequences system
-threads tools.test generic.single specialized-arrays alien.c-types ;
+USING: alien alien.c-types arrays classes.struct
+debugger.threads destructors generic.single io io.directories
+io.encodings.8-bit.latin1 io.encodings.ascii
+io.encodings.binary io.encodings.string io.files
+io.files.private io.files.temp io.files.unique kernel make math
+sequences specialized-arrays system threads tools.test ;
 SPECIALIZED-ARRAY: int
 IN: io.files.tests
 
@@ -80,6 +81,44 @@ IN: io.files.tests
     byte-array>int-array
 ] unit-test
 
+[ ] [
+    BV{ 0 1 2 } "test.txt" temp-file binary set-file-contents
+] unit-test
+
+[ t ] [
+    "test.txt" temp-file binary file-contents
+    B{ 0 1 2 } =
+] unit-test
+
+STRUCT: pt { x uint } { y uint } ;
+SPECIALIZED-ARRAY: pt
+
+CONSTANT: pt-array-1
+    pt-array{ S{ pt f 1 1 } S{ pt f 2 2 } S{ pt f 3 3 } }
+
+[ ] [
+    pt-array-1
+    "test.txt" temp-file binary set-file-contents
+] unit-test
+
+[ t ] [
+    "test.txt" temp-file binary file-contents
+    pt-array-1 >c-ptr sequence=
+] unit-test
+
+! Slices should support >c-ptr and byte-length
+
+[ ] [
+    pt-array-1 rest-slice
+    "test.txt" temp-file binary set-file-contents
+] unit-test
+
+[ t ] [
+    "test.txt" temp-file binary file-contents
+    byte-array>pt-array
+    pt-array-1 rest-slice sequence=
+] unit-test
+
 ! Writing strings to binary streams should fail
 [
     "test.txt" temp-file binary [
diff --git a/core/io/streams/byte-array/byte-array-tests.factor b/core/io/streams/byte-array/byte-array-tests.factor
index dc95d454fa..46e015e576 100644
--- a/core/io/streams/byte-array/byte-array-tests.factor
+++ b/core/io/streams/byte-array/byte-array-tests.factor
@@ -6,6 +6,7 @@ IN: io.streams.byte-array.tests
 
 [ B{ } ] [ B{ } binary [ contents ] with-byte-reader ] unit-test
 [ B{ 1 2 3 } ] [ binary [ B{ 1 2 3 } write ] with-byte-writer ] unit-test
+[ B{ 1 2 3 4 5 6 } ] [ binary [ B{ 1 2 3 } write B{ 4 5 6 } write ] with-byte-writer ] unit-test
 [ B{ 1 2 3 } ] [ { 1 2 3 } binary [ 3 read ] with-byte-reader ] unit-test
 
 [ B{ BIN: 11110101 BIN: 10111111 BIN: 10000000 BIN: 10111111 BIN: 11101111 BIN: 10000000 BIN: 10111111 BIN: 11011111 BIN: 10000000 CHAR: x } ]

From d0c21a9182d11c6f3f18e30a925aff681729a605 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 25 Feb 2010 04:54:42 +1300
Subject: [PATCH 234/250] webapps.wiki: fix template

---
 extra/webapps/wiki/wiki-common.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/extra/webapps/wiki/wiki-common.xml b/extra/webapps/wiki/wiki-common.xml
index 6bdc449dc8..bd2b897c0e 100644
--- a/extra/webapps/wiki/wiki-common.xml
+++ b/extra/webapps/wiki/wiki-common.xml
@@ -15,7 +15,7 @@
 					<div class="contents">
 						<t:bind t:name="contents">
 							<h2>
-								<t:a t:href="$wiki/view" t:query="title">
+								<t:a t:href="$wiki/view" t:rest="title">
 									<t:label t:name="title" />
 								</t:a>
 							</h2>

From e5aa02571f87e3f200724d916518fb636944dc63 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 25 Feb 2010 05:57:09 +1300
Subject: [PATCH 235/250] sequences: add suffix! to destructive sequence ops
 article

---
 core/sequences/sequences-docs.factor | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/core/sequences/sequences-docs.factor b/core/sequences/sequences-docs.factor
index dc26933af4..46b4dcd4ec 100644
--- a/core/sequences/sequences-docs.factor
+++ b/core/sequences/sequences-docs.factor
@@ -1617,8 +1617,8 @@ ARTICLE: "sequences-destructive-discussion" "When to use destructive operations"
 }
 "The second reason is much weaker than the first one. In particular, many combinators (see " { $link map } ", " { $link produce } " and " { $link "namespaces-make" } ") as well as more advanced data structures (such as " { $vocab-link "persistent.vectors" } ") alleviate the need for explicit use of side effects." ;
 
-ARTICLE: "sequences-destructive" "Destructive operations"
-"Many operations have constructive and destructive variants:"
+ARTICLE: "sequences-destructive" "Destructive sequence operations"
+"Many operations have destructive variants that side effect an input sequence, instead of creating a new sequence:"
 { $table
     { "Constructive" "Destructive" }
     { { $link suffix } { $link suffix! } }
@@ -1641,10 +1641,14 @@ ARTICLE: "sequences-destructive" "Destructive operations"
     delete-all
     filter!
 }
+"Adding elements:"
+{ $subsections
+    suffix!
+    append!
+}
 "Other destructive words:"
 { $subsections
     reverse!
-    append!
     move
     exchange
     copy

From d853061f8fca8dd0507b96baba39d4d7360f5a7a Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Wed, 24 Feb 2010 17:00:17 -0800
Subject: [PATCH 236/250] move chipmunk to chipmunk.ffi

---
 extra/chipmunk/demo/demo.factor                    | 2 +-
 extra/chipmunk/{chipmunk.factor => ffi/ffi.factor} | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
 rename extra/chipmunk/{chipmunk.factor => ffi/ffi.factor} (99%)

diff --git a/extra/chipmunk/demo/demo.factor b/extra/chipmunk/demo/demo.factor
index 38a8689bec..b0aa7f18b4 100644
--- a/extra/chipmunk/demo/demo.factor
+++ b/extra/chipmunk/demo/demo.factor
@@ -1,6 +1,6 @@
 ! Copyright (C) 2010 Erik Charlebois
 ! See http:// factorcode.org/license.txt for BSD license.
-USING: accessors chipmunk classes.struct game.worlds kernel locals
+USING: accessors chipmunk.ffi classes.struct game.worlds kernel locals
 math method-chains opengl.gl random sequences specialized-arrays
 specialized-arrays.instances.alien.c-types.void* ui ui.gadgets.worlds
 ui.pixel-formats ;
diff --git a/extra/chipmunk/chipmunk.factor b/extra/chipmunk/ffi/ffi.factor
similarity index 99%
rename from extra/chipmunk/chipmunk.factor
rename to extra/chipmunk/ffi/ffi.factor
index b24232147c..e2adf2dff7 100644
--- a/extra/chipmunk/chipmunk.factor
+++ b/extra/chipmunk/ffi/ffi.factor
@@ -4,7 +4,7 @@ USING: accessors alien.c-types alien.syntax classes.struct combinators
 combinators.short-circuit kernel math math.order sequences
 specialized-arrays.instances.alien.c-types.void* typed
 specialized-arrays locals system alien.libraries ;
-IN: chipmunk
+IN: chipmunk.ffi
 
 << "chipmunk" {
         { [ os windows? ] [ "chipmunk.dll" ] }

From 7de21ca8beee1bc757eeaeb279560360d97a373c Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Wed, 24 Feb 2010 18:46:02 -0800
Subject: [PATCH 237/250] fix up chipmunk.demo, add a MAIN:

---
 extra/chipmunk/demo/demo.factor | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/extra/chipmunk/demo/demo.factor b/extra/chipmunk/demo/demo.factor
index b0aa7f18b4..c110349db5 100644
--- a/extra/chipmunk/demo/demo.factor
+++ b/extra/chipmunk/demo/demo.factor
@@ -1,7 +1,7 @@
 ! Copyright (C) 2010 Erik Charlebois
 ! See http:// factorcode.org/license.txt for BSD license.
-USING: accessors chipmunk.ffi classes.struct game.worlds kernel locals
-math method-chains opengl.gl random sequences specialized-arrays
+USING: accessors alien chipmunk.ffi classes.struct game.worlds kernel
+locals math method-chains opengl.gl random sequences specialized-arrays
 specialized-arrays.instances.alien.c-types.void* ui ui.gadgets.worlds
 ui.pixel-formats ;
 IN: chipmunk.demo
@@ -53,7 +53,10 @@ CONSTANT: image-bitmap B{
     cpBodyAlloc 1.0 NAN: 0 cpBodyInit
     x y cpv >>p :> body
     cpCircleShapeAlloc body 0.95 0 0 cpv cpCircleShapeInit
-    [ shape>> 0 >>e ] [ shape>> 0 >>u ] bi drop ;
+    dup shape>>
+        0 >>e
+        0 >>u
+        drop ;
 
 TUPLE: chipmunk-world < game-world
     space ;
@@ -88,7 +91,7 @@ M:: chipmunk-world draw-world* ( world -- )
     space arbiters>>
     [ num>> ] [ arr>> swap <direct-void*-array> ] bi [
         cpArbiter memory>struct
-        [ numContacts>> ] [ contacts>> swap <direct-cpContact-array> ] bi [
+        [ numContacts>> ] [ contacts>> >c-ptr swap <direct-cpContact-array> ] bi [
             p>> [ x>> ] [ y>> ] bi glVertex2f
         ] each
     ] each
@@ -109,7 +112,7 @@ M:: chipmunk-world begin-game-world ( world -- )
                 x image-width 2 / - 0.05 0.0 1.0 uniform-random-float * + 2 *
                 image-height 2 / y - 0.05 0.0 1.0 uniform-random-float * + 2 *
                 make-ball :> shape
-                space shape body>> cpSpaceAddBody drop
+                space shape shape>> body>> cpSpaceAddBody drop
                 space shape cpSpaceAddShape drop
             ] when
         ] each
@@ -119,10 +122,12 @@ M:: chipmunk-world begin-game-world ( world -- )
     body -1000 -10 cpv >>p drop
     body 400 0 cpv >>v drop
 
-    space cpCircleShapeAlloc body 8 0 0 cpv cpCircleShapeInit cpSpaceAddShape :> shape
-    shape
-    [ shape>> 0 >>e drop ]
-    [ shape>> 0 >>u drop ] bi ;
+    space cpCircleShapeAlloc [ body 8 0 0 cpv cpCircleShapeInit cpSpaceAddShape drop ] keep
+        :> shape
+    shape shape>>
+        0 >>e
+        0 >>u
+        drop ;
 
 M: chipmunk-world end-game-world
     space>>
@@ -145,3 +150,4 @@ M: chipmunk-world end-game-world
         open-window
     ] with-ui ;
 
+MAIN: chipmunk-demo

From 433f0d1ea647fdbaa6e4badfe5f399eee2061215 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Wed, 24 Feb 2010 20:07:13 -0800
Subject: [PATCH 238/250] game.worlds: construct game-loop object before
 begin-game-world is called so begin-game-world can change it before the loop
 is started

---
 extra/game/worlds/worlds.factor | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/extra/game/worlds/worlds.factor b/extra/game/worlds/worlds.factor
index dd9b2431c9..bf05eddc71 100644
--- a/extra/game/worlds/worlds.factor
+++ b/extra/game/worlds/worlds.factor
@@ -44,9 +44,8 @@ PRIVATE>
 M: game-world begin-world
     dup use-game-input?>> [ open-game-input ] when
     dup use-audio-engine?>> [ dup open-game-audio-engine >>audio-engine ] when
-    dup begin-game-world
-    dup [ tick-interval-micros>> ] [ ] bi <game-loop> [ >>game-loop ] keep start-loop
-    drop ;
+    dup [ tick-interval-micros>> ] [ ] bi <game-loop>
+    [ >>game-loop begin-game-world ] keep start-loop ;
 
 M: game-world end-world
     [ [ stop-loop ] when* f ] change-game-loop

From 7826543d2e85f9304c00f8c02c4657b2ea9e9825 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 25 Feb 2010 20:54:41 +1300
Subject: [PATCH 239/250] sequences: add cartesian-each, cartesian-map,
 cartesian-product words to eliminate some duplication throughout the codebase

---
 basis/delegate/delegate.factor            |  7 ++---
 basis/images/processing/processing.factor |  2 +-
 basis/math/matrices/matrices-tests.factor |  3 ---
 basis/math/matrices/matrices.factor       |  5 +---
 basis/opengl/textures/textures.factor     |  6 ++---
 basis/ui/gadgets/grids/grids.factor       | 11 ++++----
 core/sequences/sequences-docs.factor      | 33 +++++++++++++++++++++++
 core/sequences/sequences-tests.factor     |  3 +++
 core/sequences/sequences.factor           |  9 +++++++
 extra/project-euler/004/004.factor        |  2 +-
 extra/project-euler/027/027.factor        |  2 +-
 extra/project-euler/029/029.factor        |  2 +-
 extra/project-euler/032/032.factor        | 12 ++++-----
 extra/project-euler/033/033.factor        |  2 +-
 extra/project-euler/043/043.factor        |  3 ++-
 extra/project-euler/056/056.factor        |  2 +-
 extra/project-euler/081/081.factor        |  4 +--
 extra/project-euler/common/common.factor  |  3 ---
 18 files changed, 72 insertions(+), 39 deletions(-)

diff --git a/basis/delegate/delegate.factor b/basis/delegate/delegate.factor
index d033b7115b..662a2840a1 100644
--- a/basis/delegate/delegate.factor
+++ b/basis/delegate/delegate.factor
@@ -99,11 +99,8 @@ M: consultation forget*
 ! Protocols
 <PRIVATE
 
-: cross-2each ( seq1 seq2 quot -- )
-    [ with each ] 2curry each ; inline
-
 : forget-all-methods ( classes words -- )
-    [ first method forget ] cross-2each ;
+    [ first method forget ] cartesian-each ;
 
 : protocol-users ( protocol -- users )
     protocol-consult keys ;
@@ -120,7 +117,7 @@ M: consultation forget*
 
 : add-new-definitions ( protocol wordlist -- )
     [ drop protocol-consult values ] [ added-words ] 2bi
-    [ swap consult-method ] cross-2each ;
+    [ swap consult-method ] cartesian-each ;
 
 : initialize-protocol-props ( protocol wordlist -- )
     [
diff --git a/basis/images/processing/processing.factor b/basis/images/processing/processing.factor
index b21eb50c62..aa6434743f 100644
--- a/basis/images/processing/processing.factor
+++ b/basis/images/processing/processing.factor
@@ -6,7 +6,7 @@ math.ranges math.vectors sequences sequences.deep fry ;
 IN: images.processing
 
 : coord-matrix ( dim -- m )
-    [ iota ] map first2 [ [ 2array ] with map ] curry map ;
+    [ iota ] map first2 cartesian-product ;
 
 : map^2 ( m quot -- m' ) '[ _ map ] map ; inline
 : each^2 ( m quot -- m' ) '[ _ each ] each ; inline
diff --git a/basis/math/matrices/matrices-tests.factor b/basis/math/matrices/matrices-tests.factor
index 3ee1ddbd6d..a22f6cc978 100644
--- a/basis/math/matrices/matrices-tests.factor
+++ b/basis/math/matrices/matrices-tests.factor
@@ -105,8 +105,5 @@ USING: math.matrices math.vectors tools.test math ;
 
 [ { 1 0 0 } ] [ { 1 1 0 } { 1 0 0 } proj ] unit-test
 
-[ { { { 1 "a" } { 1 "b" } } { { 2 "a" } { 2 "b" } } } ]
-[ { 1 2 } { "a" "b" } cross-zip ] unit-test
-
 [ { { 4181 6765 } { 6765 10946 } } ]
 [ { { 0 1 } { 1 1 } } 20 m^n ] unit-test
diff --git a/basis/math/matrices/matrices.factor b/basis/math/matrices/matrices.factor
index bf14d7ba13..2a1a217c2e 100644
--- a/basis/math/matrices/matrices.factor
+++ b/basis/math/matrices/matrices.factor
@@ -11,7 +11,7 @@ IN: math.matrices
 
 : identity-matrix ( n -- matrix )
     #! Make a nxn identity matrix.
-    iota dup [ [ = 1 0 ? ] with map ] curry map ;
+    iota dup [ = 1 0 ? ] cartesian-map ;
 
 :: rotation-matrix3 ( axis theta -- matrix )
     theta cos :> c
@@ -126,9 +126,6 @@ IN: math.matrices
 : norm-gram-schmidt ( seq -- orthonormal )
     gram-schmidt [ normalize ] map ;
 
-: cross-zip ( seq1 seq2 -- seq1xseq2 )
-    [ [ 2array ] with map ] curry map ;
-    
 : m^n ( m n -- n ) 
     make-bits over first length identity-matrix
     [ [ dupd m. ] when [ dup m. ] dip ] reduce nip ;
diff --git a/basis/opengl/textures/textures.factor b/basis/opengl/textures/textures.factor
index e53383c98b..9284a151f5 100644
--- a/basis/opengl/textures/textures.factor
+++ b/basis/opengl/textures/textures.factor
@@ -1,9 +1,9 @@
-! Copyright (C) 2009 Slava Pestov.
+! Copyright (C) 2009, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs cache colors.constants destructors
 kernel opengl opengl.gl opengl.capabilities combinators images
 images.tesselation grouping sequences math math.vectors
-math.matrices generalizations fry arrays namespaces system
+generalizations fry arrays namespaces system
 locals literals specialized-arrays ;
 FROM: alien.c-types => float ;
 SPECIALIZED-ARRAY: float
@@ -354,7 +354,7 @@ TUPLE: multi-texture < disposable grid display-list loc ;
 : image-locs ( image-grid -- loc-grid )
     [ first [ dim>> first ] map ] [ [ first dim>> second ] map ] bi
     [ 0 [ + ] accumulate nip ] bi@
-    cross-zip flip ;
+    cartesian-product flip ;
 
 : <texture-grid> ( image-grid loc -- grid )
     [ dup image-locs ] dip
diff --git a/basis/ui/gadgets/grids/grids.factor b/basis/ui/gadgets/grids/grids.factor
index 2e964b48b6..d103ce401c 100644
--- a/basis/ui/gadgets/grids/grids.factor
+++ b/basis/ui/gadgets/grids/grids.factor
@@ -1,9 +1,8 @@
 ! Copyright (C) 2006, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel math math.order math.matrices namespaces
-make sequences words io math.vectors ui.gadgets
-ui.baseline-alignment columns accessors strings.tables
-math.rectangles fry ;
+USING: arrays kernel math math.order namespaces make sequences
+words io math.vectors ui.gadgets ui.baseline-alignment columns
+accessors strings.tables math.rectangles fry ;
 IN: ui.gadgets.grids
 
 TUPLE: grid < gadget
@@ -90,7 +89,7 @@ M: grid pref-dim* <grid-layout> grid-pref-dim ;
 : (compute-cell-locs) ( grid-layout -- locs )
     [ accumulate-cell-xs nip ]
     [ accumulate-cell-ys nip ]
-    bi cross-zip flip ;
+    bi cartesian-product flip ;
 
 : adjust-for-baseline ( row-locs row-cells -- row-locs' )
     align-baselines [ 0 swap 2array v+ ] 2map ;
@@ -104,7 +103,7 @@ M: grid pref-dim* <grid-layout> grid-pref-dim ;
 
 : cell-dims ( grid-layout -- dims )
     dup fill?>>
-    [ [ column-widths>> ] [ row-heights>> ] bi cross-zip flip ]
+    [ [ column-widths>> ] [ row-heights>> ] bi cartesian-product flip ]
     [ grid>> [ [ pref-dim>> ] map ] map ]
     if ;
 
diff --git a/core/sequences/sequences-docs.factor b/core/sequences/sequences-docs.factor
index 46b4dcd4ec..94e8e97998 100644
--- a/core/sequences/sequences-docs.factor
+++ b/core/sequences/sequences-docs.factor
@@ -1364,6 +1364,25 @@ HELP: assert-sequence=
   }
 } ;
 
+HELP: cartesian-each
+{ $values { "seq1" sequence } { "seq1" sequence } { "quot" { $quotation "( elt1 elt2 -- )" } } }
+{ $description "Applies the quotation to every possible pairing of elements from the two sequences." } ;
+
+HELP: cartesian-map
+{ $values { "seq1" sequence } { "seq1" sequence } { "quot" { $quotation "( elt1 elt2 -- result )" } } { "newseq" "a new sequence of sequences" } }
+{ $description "Applies the quotation to every possible pairing of elements from the two sequences, collecting results into a new sequence of sequences." } ;
+
+HELP: cartesian-product
+{ $values { "seq1" sequence } { "seq1" sequence } { "newseq" "a new sequence of sequences of pairs" } }
+{ $description "Outputs a sequence of all possible pairings of elements from the two sequences." }
+{ $examples
+    { $example
+        "USING: prettyprint sequences ;"
+        "{ 1 2 } { 3 4 } cartesian-product ."
+        "{ { { 1 3 } { 1 4 } } { { 2 3 } { 2 4 } } }"
+    }
+} ;
+
 ARTICLE: "sequences-unsafe" "Unsafe sequence operations"
 "The " { $link nth-unsafe } " and " { $link set-nth-unsafe } " sequence protocol bypasses bounds checks for increased performance."
 $nl
@@ -1691,6 +1710,19 @@ ARTICLE: "sequences-combinator-implementation" "Implementing sequence combinator
     2selector
 } ;
 
+ARTICLE: "sequences-cartesian" "Cartesian product operations"
+"The cartesian product of two sequences is a sequence of all pairs where the first element of each pair is from the first sequence, and the second element of each pair is from the second sequence. The number of elements in the cartesian product is the product of the lengths of the two sequences."
+$nl
+"Combinators which pair every element of the first sequence with every element of the second:"
+{ $subsections
+    cartesian-each
+    cartesian-map
+}
+"Computing the cartesian product of two sequences:"
+{ $subsections
+    cartesian-product
+} ;
+
 ARTICLE: "sequences" "Sequence operations"
 "A " { $emphasis "sequence" } " is a finite, linearly-ordered collection of elements. Words for working with sequences are in the " { $vocab-link "sequences" } " vocabulary."
 $nl
@@ -1718,6 +1750,7 @@ $nl
     "binary-search"
     "sets"
     "sequences-trimming"
+    "sequences-cartesian"
     "sequences.deep"
 }
 "Using sequences for looping:"
diff --git a/core/sequences/sequences-tests.factor b/core/sequences/sequences-tests.factor
index be1111b826..665e7a7ada 100644
--- a/core/sequences/sequences-tests.factor
+++ b/core/sequences/sequences-tests.factor
@@ -309,3 +309,6 @@ USE: make
 [ +gt+ ] [ { 0 0 0 0 } { 0 0 0 } <=> ] unit-test
 [ +eq+ ] [ { } { } <=> ] unit-test
 [ +eq+ ] [ { 1 2 3 } { 1 2 3 } <=> ] unit-test
+
+[ { { { 1 "a" } { 1 "b" } } { { 2 "a" } { 2 "b" } } } ]
+[ { 1 2 } { "a" "b" } cartesian-product ] unit-test
diff --git a/core/sequences/sequences.factor b/core/sequences/sequences.factor
index 2eafe2ceb8..9f59d98468 100644
--- a/core/sequences/sequences.factor
+++ b/core/sequences/sequences.factor
@@ -947,6 +947,15 @@ M: object sum 0 [ + ] binary-reduce ; inline
 
 : count ( seq quot -- n ) [ 1 0 ? ] compose map-sum ; inline
 
+: cartesian-each ( seq1 seq2 quot -- )
+    [ with each ] 2curry each ; inline
+
+: cartesian-map ( seq1 seq2 quot -- newseq )
+    [ with map ] 2curry map ; inline
+
+: cartesian-product ( seq1 seq2 -- newseq )
+    [ { } 2sequence ] cartesian-map ;
+
 ! We hand-optimize flip to such a degree because type hints
 ! cannot express that an array is an array of arrays yet, and
 ! this word happens to be performance-critical since the compiler
diff --git a/extra/project-euler/004/004.factor b/extra/project-euler/004/004.factor
index fe09914d9f..1bb9ebbef5 100644
--- a/extra/project-euler/004/004.factor
+++ b/extra/project-euler/004/004.factor
@@ -29,7 +29,7 @@ IN: project-euler.004
 PRIVATE>
 
 : euler004 ( -- answer )
-    source-004 dup cartesian-product [ product ] map prune max-palindrome ;
+    source-004 dup [ * ] cartesian-map concat prune max-palindrome ;
 
 ! [ euler004 ] 100 ave-time
 ! 1164 ms ave run time - 39.35 SD (100 trials)
diff --git a/extra/project-euler/027/027.factor b/extra/project-euler/027/027.factor
index 0c697236aa..cd2620bc4f 100644
--- a/extra/project-euler/027/027.factor
+++ b/extra/project-euler/027/027.factor
@@ -47,7 +47,7 @@ IN: project-euler.027
 
 : source-027 ( -- seq )
     1000 iota [ prime? ] filter [ dup [ neg ] map append ] keep
-    cartesian-product [ first2 < ] filter ;
+    cartesian-product concat [ first2 < ] filter ;
 
 : quadratic ( b a n -- m )
     dup sq -rot * + + ;
diff --git a/extra/project-euler/029/029.factor b/extra/project-euler/029/029.factor
index 73773e1887..31be1a566b 100644
--- a/extra/project-euler/029/029.factor
+++ b/extra/project-euler/029/029.factor
@@ -29,7 +29,7 @@ IN: project-euler.029
 ! --------
 
 : euler029 ( -- answer )
-    2 100 [a,b] dup cartesian-product [ first2 ^ ] map prune length ;
+    2 100 [a,b] dup [ ^ ] cartesian-map concat prune length ;
 
 ! [ euler029 ] 100 ave-time
 ! 704 ms ave run time - 28.07 SD (100 trials)
diff --git a/extra/project-euler/032/032.factor b/extra/project-euler/032/032.factor
index 8fb7a2bfaa..7def55b659 100644
--- a/extra/project-euler/032/032.factor
+++ b/extra/project-euler/032/032.factor
@@ -62,17 +62,17 @@ PRIVATE>
 
 <PRIVATE
 
-: source-032a ( -- seq )
-    50 [1,b] 2000 [1,b] cartesian-product ;
-
 ! multiplicand/multiplier/product
-: mmp ( pair -- n )
-    first2 2dup * [ number>string ] tri@ 3append string>number ;
+: mmp ( x y -- n )
+    2dup * [ number>string ] tri@ 3append string>number ;
 
 PRIVATE>
 
 : euler032a ( -- answer )
-    source-032a [ mmp ] map [ pandigital? ] filter products prune sum ;
+    50 [1,b] 2000 [1,b]
+    [ mmp ] cartesian-map concat
+    [ pandigital? ] filter
+    products prune sum ;
 
 ! [ euler032a ] 10 ave-time
 ! 2624 ms ave run time - 131.91 SD (10 trials)
diff --git a/extra/project-euler/033/033.factor b/extra/project-euler/033/033.factor
index 780015ab77..77bae6d2f2 100644
--- a/extra/project-euler/033/033.factor
+++ b/extra/project-euler/033/033.factor
@@ -30,7 +30,7 @@ IN: project-euler.033
 <PRIVATE
 
 : source-033 ( -- seq )
-    10 99 [a,b] dup cartesian-product [ first2 < ] filter ;
+    10 99 [a,b] dup cartesian-product concat [ first2 < ] filter ;
 
 : safe? ( ax xb -- ? )
     [ 10 /mod ] bi@ [ = ] dip zero? not and nip ;
diff --git a/extra/project-euler/043/043.factor b/extra/project-euler/043/043.factor
index 4991d65a89..ab59843e21 100644
--- a/extra/project-euler/043/043.factor
+++ b/extra/project-euler/043/043.factor
@@ -86,7 +86,8 @@ PRIVATE>
 
 : interesting-pandigitals ( -- seq )
     17 candidates { 13 11 7 5 3 2 } [
-        candidates swap cartesian-product [ overlap? ] filter clean
+        candidates swap cartesian-product concat
+        [ overlap? ] filter clean
     ] each [ add-missing-digit ] map ;
 
 PRIVATE>
diff --git a/extra/project-euler/056/056.factor b/extra/project-euler/056/056.factor
index 76c275e4dd..98e39ebd36 100644
--- a/extra/project-euler/056/056.factor
+++ b/extra/project-euler/056/056.factor
@@ -23,7 +23,7 @@ IN: project-euler.056
 ! Through analysis, you only need to check when a and b > 90
 
 : euler056 ( -- answer )
-    90 100 [a,b) dup cartesian-product
+    90 100 [a,b) dup cartesian-product concat
     [ first2 ^ number>digits sum ] [ max ] map-reduce ;
 
 ! [ euler056 ] 100 ave-time
diff --git a/extra/project-euler/081/081.factor b/extra/project-euler/081/081.factor
index cc5e93d7a8..73936ba2ed 100644
--- a/extra/project-euler/081/081.factor
+++ b/extra/project-euler/081/081.factor
@@ -60,8 +60,8 @@ IN: project-euler.081
     3dup minimal-path-sum-to '[ _ + ] change-matrix ;
 
 : (euler081) ( matrix -- n )
-    dup first length iota dup cartesian-product
-    [ first2 pick update-minimal-path-sum ] each
+    dup first length iota dup
+    [ pick update-minimal-path-sum ] cartesian-each
     last last ;
 
 PRIVATE>
diff --git a/extra/project-euler/common/common.factor b/extra/project-euler/common/common.factor
index 48520ef565..895eba4deb 100644
--- a/extra/project-euler/common/common.factor
+++ b/extra/project-euler/common/common.factor
@@ -68,9 +68,6 @@ PRIVATE>
 : alpha-value ( str -- n )
     >lower [ CHAR: a - 1 + ] map-sum ;
 
-: cartesian-product ( seq1 seq2 -- seq1xseq2 )
-    [ [ 2array ] with map ] curry map concat ;
-
 : mediant ( a/c b/d -- (a+b)/(c+d) )
     2>fraction [ + ] 2bi@ / ;
 

From 2ee4db39affc9232fbc0c77fd88b57bf216e5f09 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Thu, 25 Feb 2010 21:39:14 +1300
Subject: [PATCH 240/250] syndication: get it working with doublec's wacky atom
 feed

---
 basis/syndication/syndication.factor | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/basis/syndication/syndication.factor b/basis/syndication/syndication.factor
index e30cd6826c..fe31a49265 100644
--- a/basis/syndication/syndication.factor
+++ b/basis/syndication/syndication.factor
@@ -70,7 +70,8 @@ TUPLE: entry title url description date ;
     tri ;
 
 : atom-entry-link ( tag -- url/f )
-    "link" tags-named [ "rel" attr "alternate" = ] find nip
+    "link" tags-named
+    [ "rel" attr { f "alternate" } member? ] find nip
     dup [ "href" attr >url ] when ;
 
 : atom1.0-entry ( tag -- entry )

From 86b7ba95a8b7fee2086ce150ac8989cb12ab907f Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Fri, 26 Feb 2010 00:44:48 +1300
Subject: [PATCH 241/250] sequences: fix help lint

---
 core/sequences/sequences-docs.factor | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/core/sequences/sequences-docs.factor b/core/sequences/sequences-docs.factor
index 94e8e97998..d40796a4f6 100644
--- a/core/sequences/sequences-docs.factor
+++ b/core/sequences/sequences-docs.factor
@@ -1365,15 +1365,15 @@ HELP: assert-sequence=
 } ;
 
 HELP: cartesian-each
-{ $values { "seq1" sequence } { "seq1" sequence } { "quot" { $quotation "( elt1 elt2 -- )" } } }
+{ $values { "seq1" sequence } { "seq2" sequence } { "quot" { $quotation "( elt1 elt2 -- )" } } }
 { $description "Applies the quotation to every possible pairing of elements from the two sequences." } ;
 
 HELP: cartesian-map
-{ $values { "seq1" sequence } { "seq1" sequence } { "quot" { $quotation "( elt1 elt2 -- result )" } } { "newseq" "a new sequence of sequences" } }
+{ $values { "seq1" sequence } { "seq2" sequence } { "quot" { $quotation "( elt1 elt2 -- result )" } } { "newseq" "a new sequence of sequences" } }
 { $description "Applies the quotation to every possible pairing of elements from the two sequences, collecting results into a new sequence of sequences." } ;
 
 HELP: cartesian-product
-{ $values { "seq1" sequence } { "seq1" sequence } { "newseq" "a new sequence of sequences of pairs" } }
+{ $values { "seq1" sequence } { "seq2" sequence } { "newseq" "a new sequence of sequences of pairs" } }
 { $description "Outputs a sequence of all possible pairings of elements from the two sequences." }
 { $examples
     { $example

From 7548e57b5bbccf1d4c5a74ac6b21ff34cf6be347 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Thu, 25 Feb 2010 08:15:53 -0800
Subject: [PATCH 242/250] Add perp and angle-between words for vectors. Fix bug
 in cross product and add unit tests.

---
 basis/math/matrices/matrices-tests.factor |  3 ++-
 basis/math/matrices/matrices.factor       | 10 ++++++++--
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/basis/math/matrices/matrices-tests.factor b/basis/math/matrices/matrices-tests.factor
index a22f6cc978..b827741209 100644
--- a/basis/math/matrices/matrices-tests.factor
+++ b/basis/math/matrices/matrices-tests.factor
@@ -99,9 +99,10 @@ USING: math.matrices math.vectors tools.test math ;
     m.
 ] unit-test
 
-[ { 0 0 -1 } ] [ { 1 0 0 } { 0 1 0 } cross ] unit-test
+[ { 0 0 1 } ] [ { 1 0 0 } { 0 1 0 } cross ] unit-test
 [ { 1 0 0 } ] [ { 0 1 0 } { 0 0 1 } cross ] unit-test
 [ { 0 1 0 } ] [ { 0 0 1 } { 1 0 0 } cross ] unit-test
+[ { 0.0 -0.707 0.707 } ] [ { 1.0 0.0 0.0 } { 0.0 0.707 0.707 } cross ] unit-test
 
 [ { 1 0 0 } ] [ { 1 1 0 } { 1 0 0 } proj ] unit-test
 
diff --git a/basis/math/matrices/matrices.factor b/basis/math/matrices/matrices.factor
index 2a1a217c2e..216d2c31bb 100644
--- a/basis/math/matrices/matrices.factor
+++ b/basis/math/matrices/matrices.factor
@@ -111,12 +111,18 @@ IN: math.matrices
 : mnorm ( m -- n ) dup mmax abs m/n ;
 
 : cross ( vec1 vec2 -- vec3 )
-    [ [ { 1 2 1 } vshuffle ] [ { 2 0 0 } vshuffle ] bi* v* ]
-    [ [ { 2 0 0 } vshuffle ] [ { 1 2 1 } vshuffle ] bi* v* ] 2bi v- ; inline
+    [ [ { 1 2 0 } vshuffle ] [ { 2 0 1 } vshuffle ] bi* v* ]
+    [ [ { 2 0 1 } vshuffle ] [ { 1 2 0 } vshuffle ] bi* v* ] 2bi v- ; inline
 
 : proj ( v u -- w )
     [ [ v. ] [ norm-sq ] bi / ] keep n*v ;
 
+: perp ( v u -- w )
+    dupd proj v- ;
+
+: angle-between ( v u -- a )
+    [ normalize ] bi@ v. acos ;
+
 : (gram-schmidt) ( v seq -- newseq )
     [ dupd proj v- ] each ;
 

From f2999ce778eaeb7735e9bba0e1533cc0e1ab742b Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Thu, 25 Feb 2010 11:52:21 -0800
Subject: [PATCH 243/250] classes.struct: raise an error in STRUCT: if there
 are duplicate slot names

---
 basis/classes/struct/struct-tests.factor | 18 +++++++++++++-----
 basis/classes/struct/struct.factor       |  3 ++-
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/basis/classes/struct/struct-tests.factor b/basis/classes/struct/struct-tests.factor
index c94ef48f4c..dafd31efde 100644
--- a/basis/classes/struct/struct-tests.factor
+++ b/basis/classes/struct/struct-tests.factor
@@ -1,10 +1,10 @@
 ! (c)Joe Groff bsd license
 USING: accessors alien alien.c-types alien.data alien.syntax ascii
-assocs byte-arrays classes.struct classes.tuple.private classes.tuple
-combinators compiler.tree.debugger compiler.units destructors
-io.encodings.utf8 io.pathnames io.streams.string kernel libc
-literals math mirrors namespaces prettyprint
-prettyprint.config see sequences specialized-arrays system
+assocs byte-arrays classes.struct classes.tuple.parser
+classes.tuple.private classes.tuple combinators compiler.tree.debugger
+compiler.units destructors io.encodings.utf8 io.pathnames
+io.streams.string kernel libc literals math mirrors namespaces
+prettyprint prettyprint.config see sequences specialized-arrays system
 tools.test parser lexer eval layouts generic.single classes ;
 FROM: math => float ;
 QUALIFIED-WITH: alien.c-types c
@@ -334,6 +334,14 @@ STRUCT: struct-that's-a-word { x int } ;
     "struct-class-test-1" parse-stream
 ] [ error>> error>> unexpected-eof? ] must-fail-with
 
+[
+    "USING: alien.c-types classes.struct ; IN: classes.struct.tests STRUCT: struct-test-duplicate-slots { x uint } { x uint } ;" eval( -- )
+] [ error>> duplicate-slot-names? ] must-fail-with
+
+[
+    "USING: alien.c-types classes.struct ; IN: classes.struct.tests STRUCT: struct-test-duplicate-slots { x uint } { x float } ;" eval( -- )
+] [ error>> duplicate-slot-names? ] must-fail-with
+
 ! S{ with non-struct type
 [
     "USE: classes.struct IN: classes.struct.tests TUPLE: not-a-struct ; S{ not-a-struct }"
diff --git a/basis/classes/struct/struct.factor b/basis/classes/struct/struct.factor
index a3b198bd94..79dea73d8c 100644
--- a/basis/classes/struct/struct.factor
+++ b/basis/classes/struct/struct.factor
@@ -363,7 +363,8 @@ PRIVATE>
     } case ;
 
 : parse-struct-definition ( -- class slots )
-    CREATE-CLASS 8 <vector> [ parse-struct-slots ] [ ] while >array ;
+    CREATE-CLASS 8 <vector> [ parse-struct-slots ] [ ] while >array
+    dup [ name>> ] map check-duplicate-slots ;
 PRIVATE>
 
 SYNTAX: STRUCT:

From 31b77781aef97d08431a99829f62c6f393acc9b0 Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Thu, 25 Feb 2010 14:36:12 -0600
Subject: [PATCH 244/250] Add more user32 bindings

---
 basis/windows/user32/user32.factor | 98 ++++++++++++++++++++++++++++--
 1 file changed, 92 insertions(+), 6 deletions(-)

diff --git a/basis/windows/user32/user32.factor b/basis/windows/user32/user32.factor
index 9908bb1f1b..b9d5cc95c4 100644
--- a/basis/windows/user32/user32.factor
+++ b/basis/windows/user32/user32.factor
@@ -927,6 +927,87 @@ STRUCT: RAWINPUTDEVICELIST
     { dwType  DWORD  } ;
 TYPEDEF: RAWINPUTDEVICELIST* PRAWINPUTDEVICELIST
 
+CONSTANT: CCHFORMNAME 32
+
+CONSTANT: CDS_UPDATEREGISTRY      HEX: 00000001
+CONSTANT: CDS_TEST                HEX: 00000002
+CONSTANT: CDS_FULLSCREEN          HEX: 00000004
+CONSTANT: CDS_GLOBAL              HEX: 00000008
+CONSTANT: CDS_SET_PRIMARY         HEX: 00000010
+CONSTANT: CDS_RESET               HEX: 40000000
+CONSTANT: CDS_SETRECT             HEX: 20000000
+CONSTANT: CDS_NORESET             HEX: 10000000
+
+CONSTANT: DISP_CHANGE_SUCCESSFUL 0
+CONSTANT: DISP_CHANGE_RESTART 1
+CONSTANT: DISP_CHANGE_FAILED     -1
+CONSTANT: DISP_CHANGE_BADMODE    -2
+CONSTANT: DISP_CHANGE_NOTUPDATED -3
+CONSTANT: DISP_CHANGE_BADFLAGS   -4
+CONSTANT: DISP_CHANGE_BADPARAM   -5
+
+
+
+STRUCT: DEVMODE
+    { dmDeviceName TCHAR[CCHDEVICENAME] }
+    { dmSpecVersion WORD }
+    { dmDriverVersion WORD }
+    { dmSize WORD }
+    { dmDriverExtra WORD }
+    { dmFields DWORD }
+
+    { dmOrientation short }
+    { dmPaperSize short }
+    { dmPaperLength short }
+    { dmPaperWidth short }
+    { dmScale short }
+    { dmCopies short }
+    { dmDefaultSource short }
+    { dmPrintQuality short }
+
+    { dmColor short }
+    { dmDuplex short }
+    { dmYResolution short }
+    { dmTTOption short }
+    { dmCollate short }
+    { dmFormName TCHAR[CCHFORMNAME] }
+    { dmLogPixels WORD }
+    { dmBitsPerPel DWORD }
+    { dmPelsWidth DWORD }
+    { dmPelsHeight DWORD }
+    { dmDisplayFlags DWORD }
+    { dmDisplayFrequency DWORD }
+    { dmiCMMethod DWORD }
+    { dmICMIntent DWORD }
+
+    { dmMediaType DWORD }
+    { dmDitherType DWORD }
+    { dmReserved1 DWORD }
+    { dmReserved2 DWORD }
+    { dmPanningWidth DWORD } ;
+
+! union { DWORD dmDisplayFlags; DWORD dmNup; } ;
+  ! union {
+    ! struct {
+      ! short dmOrientation;
+      ! short dmPaperSize;
+      ! short dmPaperLength;
+      ! short dmPaperWidth;
+      ! short dmScale;
+      ! short dmCopies;
+      ! short dmDefaultSource;
+      ! short dmPrintQuality;
+    ! } ;
+    ! struct {
+      ! POINTL dmPosition;
+      ! DWORD dmDisplayOrientation;
+      ! DWORD dmDisplayFixedOutput;
+    ! } ;
+  ! } ;
+
+TYPEDEF: DEVMODE* PDEVMODE
+TYPEDEF: DEVMODE* LPDEVMODE
+
 LIBRARY: user32
 
 FUNCTION: HKL ActivateKeyboardLayout ( HKL hkl, UINT Flags ) ;
@@ -965,10 +1046,10 @@ FUNCTION: HDC BeginPaint ( HWND hwnd, LPPAINTSTRUCT lpPaint ) ;
 ! FUNCTION: CascadeChildWindows
 ! FUNCTION: CascadeWindows
 ! FUNCTION: ChangeClipboardChain
-! FUNCTION: ChangeDisplaySettingsA
-! FUNCTION: ChangeDisplaySettingsExA
-! FUNCTION: ChangeDisplaySettingsExW
-! FUNCTION: ChangeDisplaySettingsW
+FUNCTION: LONG ChangeDisplaySettingsExW ( LPCTSTR lpszDeviceName, DEVMODE *lpDevMode, HWND hwnd, DWORD dwFlags, LPVOID lParam ) ;
+FUNCTION: LONG ChangeDisplaySettingsW ( DEVMODE *lpDevMode, DWORD dwFlags ) ;
+ALIAS: ChangeDisplaySettingsEx ChangeDisplaySettingsExW
+ALIAS: ChangeDisplaySettings ChangeDisplaySettingsW
 ! FUNCTION: ChangeMenuA
 ! FUNCTION: ChangeMenuW
 ! FUNCTION: CharLowerA
@@ -1173,7 +1254,8 @@ FUNCTION: UINT EnumClipboardFormats ( UINT format ) ;
 ! FUNCTION: EnumDisplaySettingsA
 ! FUNCTION: EnumDisplaySettingsExA
 ! FUNCTION: EnumDisplaySettingsExW
-! FUNCTION: EnumDisplaySettingsW
+FUNCTION: BOOL EnumDisplaySettingsW ( LPCTSTR lpszDeviceName, DWORD iModeNum, DEVMODE *lpDevMode ) ;
+ALIAS: EnumDisplaySettings EnumDisplaySettingsW
 ! FUNCTION: EnumPropsA
 ! FUNCTION: EnumPropsExA
 ! FUNCTION: EnumPropsExW
@@ -1236,7 +1318,7 @@ FUNCTION: DWORD GetClipboardSequenceNumber ( ) ;
 ! FUNCTION: GetCursorPos
 FUNCTION: HDC GetDC ( HWND hWnd ) ;
 FUNCTION: HDC GetDCEx ( HWND hWnd, HRGN hrgnClip, DWORD flags ) ;
-! FUNCTION: GetDesktopWindow
+FUNCTION: HWND GetDesktopWindow ( ) ;
 ! FUNCTION: GetDialogBaseUnits
 ! FUNCTION: GetDlgCtrlID
 ! FUNCTION: GetDlgItem
@@ -1345,6 +1427,8 @@ FUNCTION: HWND GetWindow ( HWND hWnd, UINT uCmd ) ;
 ! FUNCTION: GetWindowLongW
 FUNCTION: LONG_PTR GetWindowLongW ( HANDLE hWnd, int index ) ;
 ALIAS: GetWindowLong GetWindowLongW
+
+FUNCTION: LONG_PTR GetWindowLongPtr ( HWND hWnd, int nIndex ) ;
 ! FUNCTION: GetWindowModuleFileName
 ! FUNCTION: GetWindowModuleFileNameA
 ! FUNCTION: GetWindowModuleFileNameW
@@ -1692,6 +1776,8 @@ ALIAS: SetWindowLong SetWindowLongW
 ! FUNCTION: SetWindowPlacement
 FUNCTION: BOOL SetWindowPos ( HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags ) ;
 
+FUNCTION: LONG_PTR SetWindowLongPtr ( HWND hWnd, int nIndex, LONG_PTR dwNewLong ) ;
+
 : HWND_BOTTOM ( -- alien ) 1 <alien> ;
 : HWND_NOTOPMOST ( -- alien ) -2 <alien> ;
 CONSTANT: HWND_TOP f

From 6655002629fdfcb2bcd610224769198f83c14d7b Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Thu, 25 Feb 2010 12:55:31 -0800
Subject: [PATCH 245/250] remove repeated "pad" slots from x11.xlib structs

---
 basis/x11/xlib/xlib.factor | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/basis/x11/xlib/xlib.factor b/basis/x11/xlib/xlib.factor
index de01d509dd..e86bb5e8c3 100644
--- a/basis/x11/xlib/xlib.factor
+++ b/basis/x11/xlib/xlib.factor
@@ -1010,14 +1010,7 @@ STRUCT: XKeymapEvent
 { send_event Bool }
 { display Display* }
 { window Window }
-{ pad int }
-{ pad int }
-{ pad int }
-{ pad int }
-{ pad int }
-{ pad int }
-{ pad int }
-{ pad int } ;
+{ pad int[8] } ;
 
 UNION-STRUCT: XEvent
 { int int }

From 1bb27b8a21382a5d375e1deb4325fceb63507038 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Thu, 25 Feb 2010 15:13:06 -0800
Subject: [PATCH 246/250] deploy chipmunk lib

---
 extra/chipmunk/ffi/ffi.factor | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/extra/chipmunk/ffi/ffi.factor b/extra/chipmunk/ffi/ffi.factor
index e2adf2dff7..0142b57a77 100644
--- a/extra/chipmunk/ffi/ffi.factor
+++ b/extra/chipmunk/ffi/ffi.factor
@@ -2,15 +2,19 @@
 ! See http:// factorcode.org/license.txt for BSD license.
 USING: accessors alien.c-types alien.syntax classes.struct combinators
 combinators.short-circuit kernel math math.order sequences
-specialized-arrays.instances.alien.c-types.void* typed
-specialized-arrays locals system alien.libraries ;
+typed specialized-arrays locals system alien.libraries ;
+SPECIALIZED-ARRAY: void*
 IN: chipmunk.ffi
 
-<< "chipmunk" {
-        { [ os windows? ] [ "chipmunk.dll" ] }
-        { [ os macosx? ] [ "libchipmunk.dylib"  ] }
-        { [ os unix?  ] [ "libchipmunk.so" ] }
-    } cond "cdecl" add-library >>
+<<
+"chipmunk" {
+    { [ os windows? ] [ "chipmunk.dll" ] }
+    { [ os macosx? ] [ "libchipmunk.dylib"  ] }
+    { [ os unix?  ] [ "libchipmunk.so" ] }
+} cond "cdecl" add-library
+
+"chipmunk" deploy-library
+>>
 LIBRARY: chipmunk
 
 ! chipmunk_types.h

From 4358edcae79d7bbb425da8933a60b436a0a11254 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Thu, 25 Feb 2010 16:39:30 -0800
Subject: [PATCH 247/250] windows.com: typedef interface word to void*
 immediately so that self-referential pointers in the interface definition
 parse properly. fix a bug where pointer return values for interface methods
 couldn't parse

---
 basis/windows/com/com-tests.factor     | 3 +++
 basis/windows/com/syntax/syntax.factor | 8 ++++----
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/basis/windows/com/com-tests.factor b/basis/windows/com/com-tests.factor
index f0b4eadb9f..fdc48adfbe 100644
--- a/basis/windows/com/com-tests.factor
+++ b/basis/windows/com/com-tests.factor
@@ -16,6 +16,9 @@ COM-INTERFACE: IUnrelated IUnknown {b06ac3f4-30e4-406b-a7cd-c29cead4552c}
     int xPlus ( int y )
     int xMulAdd ( int mul, int add ) ;
 
+COM-INTERFACE: ISelfReferential IUnknown {d4f45bf8-f720-4701-a09d-e8e341981121}
+    ISelfReferential* selfReference ( ) ;
+
 { GUID: {216fb341-0eb2-44b1-8edb-60b76e353abc} } [ ISimple-iid ] unit-test
 { GUID: {9620ecec-8438-423b-bb14-86f835aa40dd} } [ IInherited-iid ] unit-test
 { GUID: {00000000-0000-0000-C000-000000000046} } [ IUnknown-iid ] unit-test
diff --git a/basis/windows/com/syntax/syntax.factor b/basis/windows/com/syntax/syntax.factor
index 7e93a6e9f8..5230d9497e 100644
--- a/basis/windows/com/syntax/syntax.factor
+++ b/basis/windows/com/syntax/syntax.factor
@@ -3,6 +3,7 @@ effects kernel windows.ole32 parser lexer splitting grouping
 sequences namespaces assocs quotations generalizations
 accessors words macros alien.syntax fry arrays layouts math
 classes.struct windows.kernel32 ;
+FROM: alien.parser.private => return-type-name ;
 IN: windows.com.syntax
 
 <PRIVATE
@@ -71,7 +72,7 @@ ERROR: no-com-interface interface ;
 : (stack-effect-from-return-and-parameters) ( return parameters -- stack-effect )
     swap
     [ [ second ] map ]
-    [ dup void? [ drop { } ] [ name>> 1array ] if ] bi*
+    [ dup void? [ drop { } ] [ return-type-name 1array ] if ] bi*
     <effect> ;
 
 : (define-word-for-function) ( function interface n -- )
@@ -83,17 +84,16 @@ ERROR: no-com-interface interface ;
 
 : define-words-for-com-interface ( definition -- )
     [ [ (iid-word) ] [ iid>> 1quotation ] bi (( -- iid )) define-declared ]
-    [ word>> void* swap typedef ]
     [
         dup family-tree-functions
         [ (define-word-for-function) ] with each-index
-    ]
-    tri ;
+    ] bi ;
 
 PRIVATE>
 
 SYNTAX: COM-INTERFACE:
     CREATE-C-TYPE
+    void* over typedef
     scan-object find-com-interface-definition
     scan string>guid
     parse-com-functions

From cebabdc32382998595492824753dbfa6555cce9c Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Thu, 25 Feb 2010 08:15:53 -0800
Subject: [PATCH 248/250] Add perp and angle-between words for vectors. Fix bug
 in cross product and add unit tests.

---
 basis/math/matrices/matrices-tests.factor |  3 ++-
 basis/math/matrices/matrices.factor       | 10 ++++++++--
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/basis/math/matrices/matrices-tests.factor b/basis/math/matrices/matrices-tests.factor
index a22f6cc978..b827741209 100644
--- a/basis/math/matrices/matrices-tests.factor
+++ b/basis/math/matrices/matrices-tests.factor
@@ -99,9 +99,10 @@ USING: math.matrices math.vectors tools.test math ;
     m.
 ] unit-test
 
-[ { 0 0 -1 } ] [ { 1 0 0 } { 0 1 0 } cross ] unit-test
+[ { 0 0 1 } ] [ { 1 0 0 } { 0 1 0 } cross ] unit-test
 [ { 1 0 0 } ] [ { 0 1 0 } { 0 0 1 } cross ] unit-test
 [ { 0 1 0 } ] [ { 0 0 1 } { 1 0 0 } cross ] unit-test
+[ { 0.0 -0.707 0.707 } ] [ { 1.0 0.0 0.0 } { 0.0 0.707 0.707 } cross ] unit-test
 
 [ { 1 0 0 } ] [ { 1 1 0 } { 1 0 0 } proj ] unit-test
 
diff --git a/basis/math/matrices/matrices.factor b/basis/math/matrices/matrices.factor
index 2a1a217c2e..216d2c31bb 100644
--- a/basis/math/matrices/matrices.factor
+++ b/basis/math/matrices/matrices.factor
@@ -111,12 +111,18 @@ IN: math.matrices
 : mnorm ( m -- n ) dup mmax abs m/n ;
 
 : cross ( vec1 vec2 -- vec3 )
-    [ [ { 1 2 1 } vshuffle ] [ { 2 0 0 } vshuffle ] bi* v* ]
-    [ [ { 2 0 0 } vshuffle ] [ { 1 2 1 } vshuffle ] bi* v* ] 2bi v- ; inline
+    [ [ { 1 2 0 } vshuffle ] [ { 2 0 1 } vshuffle ] bi* v* ]
+    [ [ { 2 0 1 } vshuffle ] [ { 1 2 0 } vshuffle ] bi* v* ] 2bi v- ; inline
 
 : proj ( v u -- w )
     [ [ v. ] [ norm-sq ] bi / ] keep n*v ;
 
+: perp ( v u -- w )
+    dupd proj v- ;
+
+: angle-between ( v u -- a )
+    [ normalize ] bi@ v. acos ;
+
 : (gram-schmidt) ( v seq -- newseq )
     [ dupd proj v- ] each ;
 

From d898ee86b68ae36a896b65b7b3492f1318cdb25d Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Thu, 25 Feb 2010 17:05:03 -0800
Subject: [PATCH 249/250] grouping: add circular clumps (e.g. { 1 2 3 4 } 3
 circular-clump => { { 1 2 3 } { 2 3 4 } { 3 4 1 } { 4 1 2 } }

---
 basis/grouping/grouping-docs.factor  | 70 ++++++++++++++++++++++++----
 basis/grouping/grouping-tests.factor |  9 ++++
 basis/grouping/grouping.factor       | 43 ++++++++++++++++-
 3 files changed, 111 insertions(+), 11 deletions(-)

diff --git a/basis/grouping/grouping-docs.factor b/basis/grouping/grouping-docs.factor
index 2c2fee1d70..0c9db38f4b 100644
--- a/basis/grouping/grouping-docs.factor
+++ b/basis/grouping/grouping-docs.factor
@@ -8,22 +8,48 @@ ARTICLE: "grouping" "Groups and clumps"
 { $subsections groups <groups> <sliced-groups> }
 "Splitting a sequence into overlapping, fixed-length subsequences:"
 { $subsections clump }
+"Splitting a sequence into overlapping, fixed-length subsequences, wrapping around the end of the sequence:"
+{ $subsections circular-clump }
 "A virtual sequence for splitting a sequence into overlapping, fixed-length subsequences:"
 { $subsections clumps <clumps> <sliced-clumps> }
+"A virtual sequence for splitting a sequence into overlapping, fixed-length subsequences:"
+{ $subsections circular-clumps <circular-clumps> <sliced-circular-clumps> }
 "The difference can be summarized as the following:"
 { $list
     { "With groups, the subsequences form the original sequence when concatenated:"
+        { $unchecked-example
+            "USING: grouping ;"
+            "{ 1 2 3 4 } 2 group ." "{ { 1 2 } { 3 4 } }"
+        }
         { $unchecked-example
             "USING: grouping ;"
             "{ 1 2 3 4 } dup" "2 <groups> concat sequence= ." "t"
         }
     }
     { "With clumps, collecting the first element of each subsequence but the last one, together with the last subseqence, yields the original sequence:"
+        { $unchecked-example
+            "USING: grouping ;"
+            "{ 1 2 3 4 } 2 clump ." "{ { 1 2 } { 2 3 } { 3 4 } }"
+        }
         { $unchecked-example
             "USING: grouping ;"
             "{ 1 2 3 4 } dup" "2 <clumps> unclip-last [ [ first ] map ] dip append sequence= ." "t"
         }
     }
+    { "With circular clumps, collecting the first element of each subsequence yields the original sequence. Collecting the " { $snippet "n" } "th element of each subsequence would rotate the original sequence " { $snippet "n" } " elements rightward:"
+        { $unchecked-example
+            "USING: grouping ;"
+            "{ 1 2 3 4 } 2 circular-clump ." "{ { 1 2 } { 2 3 } { 3 4 } { 4 1 } }"
+        }
+        { $unchecked-example
+            "USING: grouping ;"
+            "{ 1 2 3 4 } dup" "2 <circular-clumps> [ first ] map sequence= ." "t"
+        }
+        { $unchecked-example
+            "USING: grouping ;"
+            "{ 1 2 3 4 } dup" "2 <circular-clumps> [ second ] { } map-as ." "{ 2 3 4 1 }"
+        }
+    }
 }
 $nl
 "A combinator built using clumps:"
@@ -79,18 +105,31 @@ HELP: <sliced-groups>
 } ;
 
 HELP: clumps
-{ $class-description "Instances are virtual sequences whose elements are overlapping fixed-length subsequences o an underlying sequence. Clumps are mutable and resizable if the underlying sequence is mutable and resizable, respectively."
+{ $class-description "Instances are virtual sequences whose elements are overlapping fixed-length subsequences of an underlying sequence. Clumps are mutable and resizable if the underlying sequence is mutable and resizable, respectively."
 $nl
 "New clumps are created by calling " { $link <clumps> } " and " { $link <sliced-clumps> } "." } ;
 
+HELP: circular-clumps
+{ $class-description "Instances are virtual sequences whose elements are overlapping fixed-length subsequences of an underlying sequence, beginning with every element in the original sequence and wrapping around its end. Circular clumps are mutable and resizable if the underlying sequence is mutable and resizable, respectively."
+$nl
+"New clumps are created by calling " { $link <circular-clumps> } " and " { $link <sliced-circular-clumps> } "." } ;
+
 HELP: clump
 { $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "array" "a sequence of sequences" } }
 { $description "Splits the sequence into overlapping clumps of " { $snippet "n" } " elements and collects the clumps into a new array." }
-{ $errors "Throws an error if " { $snippet "n" } " is smaller than the length of the sequence." }
+{ $errors "Throws an error if " { $snippet "n" } " is larger than the length of the sequence." }
 { $examples
     { $example "USING: grouping prettyprint ;" "{ 3 1 3 3 7 } 2 clump ." "{ { 3 1 } { 1 3 } { 3 3 } { 3 7 } }" }
 } ;
 
+HELP: circular-clump
+{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "array" "a sequence of sequences" } }
+{ $description "Splits the sequence into overlapping clumps of " { $snippet "n" } " elements, wrapping around the end of the sequence, and collects the clumps into a new array." }
+{ $errors "Throws an error if " { $snippet "n" } " is larger than the length of the sequence." }
+{ $examples
+    { $example "USING: grouping prettyprint ;" "{ 3 1 3 3 7 } 2 circular-clump ." "{ { 3 1 } { 1 3 } { 3 3 } { 3 7 } { 7 3 } }" }
+} ;
+
 HELP: <clumps>
 { $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "clumps" clumps } }
 { $description "Outputs a virtual sequence whose elements are overlapping subsequences of " { $snippet "n" } " elements from the underlying sequence." }
@@ -111,24 +150,35 @@ HELP: <clumps>
     }
 } ;
 
-HELP: <sliced-clumps>
+HELP: <circular-clumps>
 { $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "clumps" clumps } }
-{ $description "Outputs a virtual sequence whose elements are overlapping slices of " { $snippet "n" } " elements from the underlying sequence." }
+{ $description "Outputs a virtual sequence whose elements are overlapping subsequences of " { $snippet "n" } " elements from the underlying sequence, starting with each of its elements and wrapping around the end of the sequence." }
 { $examples
     { $example
         "USING: kernel sequences grouping prettyprint ;"
-        "{ 1 2 3 4 5 6 } 3 <sliced-clumps> second ."
-        "T{ slice { from 1 } { to 4 } { seq { 1 2 3 4 5 6 } } }"
+        "{ 1 2 3 4 } 3 <circular-clumps> third ."
+        "{ 3 4 1 }"
     }
 } ;
 
-{ clumps groups } related-words
+HELP: <sliced-circular-clumps>
+{ $values { "seq" "a sequence" } { "n" "a non-negative integer" } { "clumps" clumps } }
+{ $description "Outputs a virtual sequence whose elements are overlapping slices of " { $snippet "n" } " elements from the underlying sequence, starting with each of its elements and wrapping around the end of the sequence." }
+{ $examples
+    { $example
+        "USING: arrays kernel sequences grouping prettyprint ;"
+        "{ 1 2 3 4 } 3 <sliced-circular-clumps> third >array ."
+        "{ 3 4 1 }"
+    }
+} ;
 
-{ clump group } related-words
+{ clumps circular-clumps groups } related-words
 
-{ <clumps> <groups> } related-words
+{ clump circular-clump group } related-words
 
-{ <sliced-clumps> <sliced-groups> } related-words
+{ <clumps> <circular-clumps> <groups> } related-words
+
+{ <sliced-clumps> <sliced-circular-clumps> <sliced-groups> } related-words
 
 HELP: monotonic?
 { $values { "seq" sequence } { "quot" { $quotation "( elt elt -- ? )" } } { "?" "a boolean" } }
diff --git a/basis/grouping/grouping-tests.factor b/basis/grouping/grouping-tests.factor
index 60500558a7..9340b322e2 100644
--- a/basis/grouping/grouping-tests.factor
+++ b/basis/grouping/grouping-tests.factor
@@ -17,6 +17,15 @@ IN: grouping.tests
 [ 1 ] [ { 1 2 } 2 <clumps> length ] unit-test
 [ 2 ] [ { 1 2 3 } 2 <clumps> length ] unit-test
 
+[ { } 2 <circular-clumps> length ] must-fail
+[ { 1 } 2 <circular-clumps> length ] must-fail
+
+[ 2 ] [ { 1 2 } 2 <circular-clumps> length ] unit-test
+[ 3 ] [ { 1 2 3 } 2 <circular-clumps> length ] unit-test
+
+[ { { 1 2 } { 2 1 }         } ] [ { 1 2   } 2 circular-clump ] unit-test
+[ { { 1 2 } { 2 3 } { 3 1 } } ] [ { 1 2 3 } 2 circular-clump ] unit-test
+
 [ 1 ] [ V{ } 2 <clumps> 0 over set-length seq>> length ] unit-test
 [ 2 ] [ V{ } 2 <clumps> 1 over set-length seq>> length ] unit-test
 [ 3 ] [ V{ } 2 <clumps> 2 over set-length seq>> length ] unit-test
diff --git a/basis/grouping/grouping.factor b/basis/grouping/grouping.factor
index 4ee0d0c385..0dced6ad9d 100644
--- a/basis/grouping/grouping.factor
+++ b/basis/grouping/grouping.factor
@@ -1,7 +1,7 @@
 ! Copyright (C) 2005, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel math math.order strings arrays vectors sequences
-sequences.private accessors fry ;
+sequences.private accessors fry combinators.short-circuit ;
 IN: grouping
 
 <PRIVATE
@@ -59,6 +59,13 @@ TUPLE: chunking-seq { seq read-only } { n read-only } ;
 : new-groups ( seq n class -- groups )
     [ check-groups ] dip boa ; inline
 
+: slice-mod ( n length -- n' )
+    2dup >= [ - ] [ drop ] if ; inline
+
+: check-circular-clumps ( seq n -- seq n )
+    2dup { [ nip 0 <= ] [ swap length > ] } 2|| 
+    [ "Invalid clump size" throw ] when ; inline
+
 PRIVATE>
 
 TUPLE: groups < chunking-seq ;
@@ -106,3 +113,37 @@ INSTANCE: sliced-clumps abstract-clumps
 : all-equal? ( seq -- ? ) [ = ] monotonic? ;
 
 : all-eq? ( seq -- ? ) [ eq? ] monotonic? ;
+
+TUPLE: circular-slice < slice ;
+M: circular-slice virtual@
+    [ from>> + ] [ seq>> ] bi [ length slice-mod ] keep ; inline
+
+C: <circular-slice> circular-slice
+
+TUPLE: sliced-circular-clumps < chunking-seq ;
+INSTANCE: sliced-circular-clumps sequence
+
+M: sliced-circular-clumps length
+    seq>> length ; inline
+
+M: sliced-circular-clumps nth
+    [ n>> over + ] [ seq>> ] bi <circular-slice> ; inline
+
+: <sliced-circular-clumps> ( seq n -- clumps )
+    check-circular-clumps sliced-circular-clumps boa ; inline
+
+TUPLE: circular-clumps < chunking-seq ;
+INSTANCE: circular-clumps sequence
+
+M: circular-clumps length
+    seq>> length ; inline
+
+M: circular-clumps nth
+    [ n>> over + ] [ seq>> ] bi [ <circular-slice> ] [ like ] bi ; inline
+
+: <circular-clumps> ( seq n -- clumps )
+    check-circular-clumps circular-clumps boa ; inline
+
+: circular-clump ( seq n -- array )
+    <circular-clumps> { } like ; inline
+

From 889fb74b8fb7af2cb57733176e1eb10baa86f4d4 Mon Sep 17 00:00:00 2001
From: Erik Charlebois <erikcharlebois@gmail.com>
Date: Thu, 25 Feb 2010 18:50:05 -0800
Subject: [PATCH 250/250] Fix windows.directx compile errors

---
 basis/windows/directx/d2d1/d2d1.factor              |  3 +++
 basis/windows/directx/d3d10/d3d10.factor            |  1 +
 .../windows/directx/d3d10effect/d3d10effect.factor  |  2 +-
 basis/windows/directx/d3d10misc/d3d10misc.factor    |  2 +-
 .../windows/directx/d3d10shader/d3d10shader.factor  |  5 +++--
 basis/windows/directx/d3d11/d3d11.factor            |  3 +++
 basis/windows/directx/d3d9/d3d9.factor              | 13 +++++++++++++
 .../windows/directx/d3dx10async/d3dx10async.factor  |  5 +++--
 .../windows/directx/d3dx11async/d3dx11async.factor  |  6 +++---
 basis/windows/directx/d3dx11tex/d3dx11tex.factor    |  6 +++---
 basis/windows/directx/dxgi/dxgi.factor              |  7 ++++---
 basis/windows/directx/xapofx/xapofx.factor          |  4 ++--
 basis/windows/directx/xaudio2/xaudio2.factor        |  3 +++
 13 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/basis/windows/directx/d2d1/d2d1.factor b/basis/windows/directx/d2d1/d2d1.factor
index cf9e5a3a98..4a8b44f63d 100644
--- a/basis/windows/directx/d2d1/d2d1.factor
+++ b/basis/windows/directx/d2d1/d2d1.factor
@@ -303,6 +303,9 @@ TYPEDEF: int D2D1_FACTORY_TYPE
 STRUCT: D2D1_FACTORY_OPTIONS
     { debugLevel D2D1_DEBUG_LEVEL } ;
 
+C-TYPE: ID2D1Factory
+C-TYPE: ID2D1BitmapRenderTarget 
+
 COM-INTERFACE: ID2D1Resource IUnknown {2cd90691-12e2-11dc-9fed-001143a055f9}
     void GetFactory ( ID2D1Factory** factory ) ;
 
diff --git a/basis/windows/directx/d3d10/d3d10.factor b/basis/windows/directx/d3d10/d3d10.factor
index 561aa47acd..4f23d41218 100644
--- a/basis/windows/directx/d3d10/d3d10.factor
+++ b/basis/windows/directx/d3d10/d3d10.factor
@@ -382,6 +382,7 @@ STRUCT: D3D10_BOX
     { bottom UINT }
     { back   UINT } ;
 
+C-TYPE: ID3D10Device
 COM-INTERFACE: ID3D10DeviceChild IUnknown {9B7E4C00-342C-4106-A19F-4F2704F689F0}
     void GetDevice ( ID3D10Device** ppDevice )
     HRESULT GetPrivateData ( LPGUID guid, UINT* pDataSize, void* pData )
diff --git a/basis/windows/directx/d3d10effect/d3d10effect.factor b/basis/windows/directx/d3d10effect/d3d10effect.factor
index 1d809b3862..873f8e26e8 100644
--- a/basis/windows/directx/d3d10effect/d3d10effect.factor
+++ b/basis/windows/directx/d3d10effect/d3d10effect.factor
@@ -1,5 +1,5 @@
 USING: alien.c-types alien.syntax classes.struct windows.com
-windows.com.syntax windows.directx.d3d10
+windows.com.syntax windows.directx.d3d10 windows.directx.d3d10misc
 windows.directx.d3d10shader windows.types ;
 IN: windows.directx.d3d10effect
 
diff --git a/basis/windows/directx/d3d10misc/d3d10misc.factor b/basis/windows/directx/d3d10misc/d3d10misc.factor
index b6f5f12bce..a5809009ea 100644
--- a/basis/windows/directx/d3d10misc/d3d10misc.factor
+++ b/basis/windows/directx/d3d10misc/d3d10misc.factor
@@ -1,5 +1,5 @@
 USING: alien.c-types alien.syntax windows.com windows.com.syntax
-windows.directx.dxgi windows.types alien.libraries ;
+windows.directx.d3d10 windows.directx.dxgi windows.types ;
 IN: windows.directx.d3d10misc
 
 LIBRARY: d3d10
diff --git a/basis/windows/directx/d3d10shader/d3d10shader.factor b/basis/windows/directx/d3d10shader/d3d10shader.factor
index 4507441fd0..787698e503 100644
--- a/basis/windows/directx/d3d10shader/d3d10shader.factor
+++ b/basis/windows/directx/d3d10shader/d3d10shader.factor
@@ -1,5 +1,6 @@
-USING: alien.syntax alien.c-types classes.struct windows.types windows.com
-windows.com.syntax windows.directx.d3d10 ;
+USING: alien.c-types alien.syntax classes.struct windows.com
+windows.com.syntax windows.directx.d3d10 windows.directx.d3d10misc
+windows.types ;
 IN: windows.directx.d3d10shader
 
 LIBRARY: d3d10
diff --git a/basis/windows/directx/d3d11/d3d11.factor b/basis/windows/directx/d3d11/d3d11.factor
index 505ac4bc67..8382c11dc2 100644
--- a/basis/windows/directx/d3d11/d3d11.factor
+++ b/basis/windows/directx/d3d11/d3d11.factor
@@ -634,6 +634,9 @@ STRUCT: D3D11_BOX
     { bottom UINT }
     { back   UINT } ;
 
+C-TYPE: ID3D11Device
+C-TYPE: ID3D11ClassLinkage
+
 COM-INTERFACE: ID3D11DeviceChild IUnknown {1841e5c8-16b0-489b-bcc8-44cfb0d5deae}
     void GetDevice ( ID3D11Device** ppDevice )
     HRESULT GetPrivateData ( REFGUID guid, UINT* pDataSize, void* pData )
diff --git a/basis/windows/directx/d3d9/d3d9.factor b/basis/windows/directx/d3d9/d3d9.factor
index cedfefc103..d4e06ae8c9 100644
--- a/basis/windows/directx/d3d9/d3d9.factor
+++ b/basis/windows/directx/d3d9/d3d9.factor
@@ -23,6 +23,8 @@ FUNCTION: BOOL D3DPERF_QueryRepeatFrame ( ) ;
 FUNCTION: void D3DPERF_SetOptions ( DWORD dwOptions ) ;
 FUNCTION: DWORD D3DPERF_GetStatus ( ) ;
 
+C-TYPE: IDirect3DDevice9
+
 COM-INTERFACE: IDirect3D9 IUnknown {81BDCBCA-64D4-426d-AE8D-AD0147F4275C}
     HRESULT RegisterSoftwareDevice ( void* pInitializeFunction )
     UINT GetAdapterCount ( )
@@ -51,6 +53,17 @@ C-TYPE: IDirect3DVertexDeclaration9
 C-TYPE: IDirect3DVertexShader9
 C-TYPE: IDirect3DIndexBuffer9
 C-TYPE: IDirect3DPixelShader9
+C-TYPE: IDirect3DSwapChain9
+C-TYPE: IDirect3DTexture9
+C-TYPE: IDirect3DVolumeTexture9
+C-TYPE: IDirect3DCubeTexture9
+C-TYPE: IDirect3DStateBlock9
+C-TYPE: IDirect3DQuery9
+C-TYPE: IDirect3DVolume9
+C-TYPE: IDirect3D9Ex
+C-TYPE: IDirect3DDevice9Ex
+C-TYPE: IDirect3DAuthenticatedChannel9
+C-TYPE: IDirect3DCryptoSession9
 
 COM-INTERFACE: IDirect3DDevice9 IUnknown {D0223B96-BF7A-43fd-92BD-A43B0D82B9EB}
     HRESULT TestCooperativeLevel ( )
diff --git a/basis/windows/directx/d3dx10async/d3dx10async.factor b/basis/windows/directx/d3dx10async/d3dx10async.factor
index e2165302f4..e7fbcf573e 100644
--- a/basis/windows/directx/d3dx10async/d3dx10async.factor
+++ b/basis/windows/directx/d3dx10async/d3dx10async.factor
@@ -1,5 +1,5 @@
-USING: alien.syntax windows.directx.d3d10 windows.directx.d3d10shader
-windows.types ;
+USING: alien.syntax windows.directx.d3d10 windows.directx.d3d10misc
+windows.directx.d3d10shader windows.directx.d3dx10core windows.types ;
 IN: windows.directx.d3dx10async
 
 LIBRARY: d3dx10
@@ -8,6 +8,7 @@ C-TYPE: ID3DX10ThreadPump
 C-TYPE: ID3D10EffectPool
 C-TYPE: D3DX10_IMAGE_LOAD_INFO
 C-TYPE: D3DX10_IMAGE_INFO
+C-TYPE: ID3D10Effect
 
 FUNCTION: HRESULT D3DX10CompileFromFileA ( LPCSTR pSrcFile, D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude,
         LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX10ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult ) ;
diff --git a/basis/windows/directx/d3dx11async/d3dx11async.factor b/basis/windows/directx/d3dx11async/d3dx11async.factor
index 369ffd6683..bea30ecb1a 100644
--- a/basis/windows/directx/d3dx11async/d3dx11async.factor
+++ b/basis/windows/directx/d3dx11async/d3dx11async.factor
@@ -1,6 +1,6 @@
-USING: alien.syntax alien.c-types classes.struct windows.types
-windows.directx.d3d10shader windows.directx.d3dx11core
-windows.directx.d3d11 windows.directx.d3dx11tex ;
+USING: alien.syntax windows.directx.d3d10misc
+windows.directx.d3d10shader windows.directx.d3d11
+windows.directx.d3dx11core windows.directx.d3dx11tex windows.types ;
 IN: windows.directx.d3dx11async
 
 LIBRARY: d3dx11
diff --git a/basis/windows/directx/d3dx11tex/d3dx11tex.factor b/basis/windows/directx/d3dx11tex/d3dx11tex.factor
index d21fa0c72a..19425535e8 100644
--- a/basis/windows/directx/d3dx11tex/d3dx11tex.factor
+++ b/basis/windows/directx/d3dx11tex/d3dx11tex.factor
@@ -1,6 +1,6 @@
-USING: alien.syntax alien.c-types classes.struct windows.types
-windows.directx.dxgiformat windows.directx.d3d11
-windows.directx.d3dx11core ;
+USING: alien.c-types alien.syntax classes.struct
+windows.directx.d3d10misc windows.directx.d3d11
+windows.directx.d3dx11core windows.directx.dxgiformat windows.types ;
 IN: windows.directx.d3dx11tex
 
 LIBRARY: d3dx11
diff --git a/basis/windows/directx/dxgi/dxgi.factor b/basis/windows/directx/dxgi/dxgi.factor
index 6537de885f..5d2ae5b990 100644
--- a/basis/windows/directx/dxgi/dxgi.factor
+++ b/basis/windows/directx/dxgi/dxgi.factor
@@ -119,6 +119,7 @@ COM-INTERFACE: IDXGISurface1 IDXGISurface {4AE63092-6327-4c1b-80AE-BFE12EA32B86}
 HRESULT GetDC ( BOOL Discard, HDC* phdc )
 HRESULT ReleaseDC ( RECT* pDirtyRect ) ;
 
+C-TYPE: IDXGIOutput 
 COM-INTERFACE: IDXGIAdapter IDXGIObject {2411e7e1-12ac-4ccf-bd14-9798e8534dc0}
 HRESULT EnumOutputs ( UINT Output, IDXGIOutput** ppOutput )
 HRESULT GetDesc ( DXGI_ADAPTER_DESC* pDesc )
@@ -201,13 +202,13 @@ STRUCT: DXGI_DISPLAY_COLOR_SPACE
 { PrimaryCoordinates FLOAT[8][2] }
 { WhitePoints FLOAT[16][2] } ;
 
+COM-INTERFACE: IDXGIAdapter1 IDXGIAdapter {29038f61-3839-4626-91fd-086879011a05}
+HRESULT GetDesc1 ( DXGI_ADAPTER_DESC1* pDesc ) ;
+
 COM-INTERFACE: IDXGIFactory1 IDXGIFactory {770aae78-f26f-4dba-a829-253c83d1b387}
 HRESULT EnumAdapters1 ( UINT Adapter, IDXGIAdapter1** ppAdapter )
 BOOL IsCurrent ( ) ;
 
-COM-INTERFACE: IDXGIAdapter1 IDXGIAdapter {29038f61-3839-4626-91fd-086879011a05}
-HRESULT GetDesc1 ( DXGI_ADAPTER_DESC1* pDesc ) ;
-
 COM-INTERFACE: IDXGIDevice1 IDXGIDevice {77db970f-6276-48ba-ba28-070143b4392c}
 HRESULT SetMaximumFrameLatency ( UINT MaxLatency )
 HRESULT GetMaximumFrameLatency ( UINT* pMaxLatency ) ;
diff --git a/basis/windows/directx/xapofx/xapofx.factor b/basis/windows/directx/xapofx/xapofx.factor
index 1255880c4c..594ad9ecbe 100644
--- a/basis/windows/directx/xapofx/xapofx.factor
+++ b/basis/windows/directx/xapofx/xapofx.factor
@@ -1,5 +1,5 @@
-USING: alien.c-types alien.syntax classes.struct windows.ole32
-windows.types ;
+USING: alien.c-types alien.syntax classes.struct windows.com
+windows.ole32 windows.types ;
 IN: windows.directx.xapofx
 
 LIBRARY: xapofx
diff --git a/basis/windows/directx/xaudio2/xaudio2.factor b/basis/windows/directx/xaudio2/xaudio2.factor
index 67a9234367..303eaf26b1 100644
--- a/basis/windows/directx/xaudio2/xaudio2.factor
+++ b/basis/windows/directx/xaudio2/xaudio2.factor
@@ -203,6 +203,9 @@ CONSTANT: XAUDIO2_LOG_STREAMING  HEX: 1000
 
 C-TYPE: IXAudio2EngineCallback
 C-TYPE: IXAudio2VoiceCallback
+C-TYPE: IXAudio2SourceVoice
+C-TYPE: IXAudio2SubmixVoice
+C-TYPE: IXAudio2MasteringVoice
 
 COM-INTERFACE: IXAudio2 IUnknown {8bcf1f58-9fe7-4583-8ac6-e2adc465c8bb}
     HRESULT GetDeviceCount ( UINT32* pCount )