diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 index 769aeacb8c..aa520063e3 --- a/Makefile +++ b/Makefile @@ -149,14 +149,11 @@ macosx.app: factor ln -s Factor.app/Contents/MacOS/factor ./factor cp $(ENGINE) $(BUNDLE)/Contents/Frameworks - install_name_tool \ - -id @executable_path/../Frameworks/libfreetype.6.dylib \ - Factor.app/Contents/Frameworks/libfreetype.6.dylib install_name_tool \ -change libfactor.dylib \ @executable_path/../Frameworks/libfactor.dylib \ Factor.app/Contents/MacOS/factor - + factor: $(DLL_OBJS) $(EXE_OBJS) $(LINKER) $(ENGINE) $(DLL_OBJS) $(CC) $(LIBS) $(LIBPATH) -L. $(LINK_WITH_ENGINE) \ diff --git a/basis/alarms/alarms-docs.factor b/basis/alarms/alarms-docs.factor old mode 100755 new mode 100644 diff --git a/basis/alarms/alarms-tests.factor b/basis/alarms/alarms-tests.factor old mode 100755 new mode 100644 diff --git a/basis/alarms/alarms.factor b/basis/alarms/alarms.factor old mode 100755 new mode 100644 diff --git a/basis/alias/alias.factor b/basis/alias/alias.factor old mode 100755 new mode 100644 diff --git a/basis/alien/arrays/arrays-docs.factor b/basis/alien/arrays/arrays-docs.factor old mode 100755 new mode 100644 diff --git a/basis/alien/c-types/c-types-docs.factor b/basis/alien/c-types/c-types-docs.factor old mode 100755 new mode 100644 diff --git a/basis/alien/c-types/c-types-tests.factor b/basis/alien/c-types/c-types-tests.factor old mode 100755 new mode 100644 diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor old mode 100755 new mode 100644 diff --git a/basis/alien/remote-control/remote-control.factor b/basis/alien/remote-control/remote-control.factor old mode 100755 new mode 100644 diff --git a/basis/alien/strings/strings.factor b/basis/alien/strings/strings.factor old mode 100755 new mode 100644 diff --git a/basis/alien/structs/structs-docs.factor b/basis/alien/structs/structs-docs.factor old mode 100755 new mode 100644 diff --git a/basis/alien/structs/structs.factor b/basis/alien/structs/structs.factor old mode 100755 new mode 100644 diff --git a/basis/alien/syntax/syntax-docs.factor b/basis/alien/syntax/syntax-docs.factor old mode 100755 new mode 100644 diff --git a/basis/alien/syntax/syntax.factor b/basis/alien/syntax/syntax.factor old mode 100755 new mode 100644 diff --git a/basis/ascii/ascii-docs.factor b/basis/ascii/ascii-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ascii/ascii.factor b/basis/ascii/ascii.factor old mode 100755 new mode 100644 diff --git a/basis/bit-arrays/bit-arrays-tests.factor b/basis/bit-arrays/bit-arrays-tests.factor old mode 100755 new mode 100644 diff --git a/basis/bit-arrays/bit-arrays.factor b/basis/bit-arrays/bit-arrays.factor old mode 100755 new mode 100644 diff --git a/basis/bit-vectors/bit-vectors-docs.factor b/basis/bit-vectors/bit-vectors-docs.factor old mode 100755 new mode 100644 diff --git a/basis/bit-vectors/bit-vectors-tests.factor b/basis/bit-vectors/bit-vectors-tests.factor old mode 100755 new mode 100644 diff --git a/basis/bit-vectors/bit-vectors.factor b/basis/bit-vectors/bit-vectors.factor old mode 100755 new mode 100644 diff --git a/basis/bootstrap/compiler/compiler.factor b/basis/bootstrap/compiler/compiler.factor old mode 100755 new mode 100644 diff --git a/basis/bootstrap/handbook/handbook.factor b/basis/bootstrap/handbook/handbook.factor old mode 100755 new mode 100644 diff --git a/basis/bootstrap/help/help.factor b/basis/bootstrap/help/help.factor old mode 100755 new mode 100644 diff --git a/basis/bootstrap/image/image-tests.factor b/basis/bootstrap/image/image-tests.factor old mode 100755 new mode 100644 diff --git a/basis/bootstrap/image/image.factor b/basis/bootstrap/image/image.factor old mode 100755 new mode 100644 index f3f570b462..db8e8c8ec0 --- a/basis/bootstrap/image/image.factor +++ b/basis/bootstrap/image/image.factor @@ -417,7 +417,7 @@ M: quotation ' } [ [ bootstrap-word ] [ get ] bi ] H{ } map>assoc { class<=-cache class-not-cache classes-intersect-cache - class-and-cache class-or-cache + class-and-cache class-or-cache next-method-quot-cache } [ H{ } clone ] H{ } map>assoc assoc-union bootstrap-global set bootstrap-global emit-userenv ; diff --git a/basis/bootstrap/image/upload/upload.factor b/basis/bootstrap/image/upload/upload.factor old mode 100755 new mode 100644 diff --git a/basis/bootstrap/io/io.factor b/basis/bootstrap/io/io.factor old mode 100755 new mode 100644 diff --git a/basis/bootstrap/random/random.factor b/basis/bootstrap/random/random.factor old mode 100755 new mode 100644 diff --git a/basis/bootstrap/stage2.factor b/basis/bootstrap/stage2.factor old mode 100755 new mode 100644 diff --git a/basis/bootstrap/tools/tools.factor b/basis/bootstrap/tools/tools.factor old mode 100755 new mode 100644 diff --git a/basis/bootstrap/ui/tools/tools.factor b/basis/bootstrap/ui/tools/tools.factor old mode 100755 new mode 100644 diff --git a/basis/bootstrap/unicode/unicode.factor b/basis/bootstrap/unicode/unicode.factor old mode 100755 new mode 100644 diff --git a/basis/boxes/boxes-docs.factor b/basis/boxes/boxes-docs.factor old mode 100755 new mode 100644 diff --git a/basis/boxes/boxes-tests.factor b/basis/boxes/boxes-tests.factor old mode 100755 new mode 100644 diff --git a/basis/boxes/boxes.factor b/basis/boxes/boxes.factor old mode 100755 new mode 100644 diff --git a/basis/calendar/calendar-docs.factor b/basis/calendar/calendar-docs.factor index c3d84fc783..64c74a494a 100644 --- a/basis/calendar/calendar-docs.factor +++ b/basis/calendar/calendar-docs.factor @@ -165,7 +165,15 @@ HELP: milliseconds { $values { "x" number } { "duration" duration } } { $description "Creates a duration object with the specified number of milliseconds." } ; -{ years months days hours minutes seconds milliseconds } related-words +HELP: microseconds +{ $values { "x" number } { "duration" duration } } +{ $description "Creates a duration object with the specified number of microseconds." } ; + +HELP: nanoseconds +{ $values { "x" number } { "duration" duration } } +{ $description "Creates a duration object with the specified number of nanoseconds." } ; + +{ years months days hours minutes seconds milliseconds microseconds nanoseconds } related-words HELP: leap-year? { $values { "obj" object } { "?" "a boolean" } } @@ -263,7 +271,27 @@ HELP: duration>milliseconds } } ; -{ duration>years duration>months duration>days duration>hours duration>minutes duration>seconds duration>milliseconds } related-words +HELP: duration>microseconds +{ $values { "duration" duration } { "x" number } } +{ $description "Calculates the length of a duration in microseconds." } +{ $examples + { $example "USING: calendar prettyprint ;" + "6 seconds duration>microseconds ." + "6000000" + } +} ; + +HELP: duration>nanoseconds +{ $values { "duration" duration } { "x" number } } +{ $description "Calculates the length of a duration in nanoseconds." } +{ $examples + { $example "USING: calendar prettyprint ;" + "6 seconds duration>nanoseconds ." + "6000000000" + } +} ; + +{ duration>years duration>months duration>days duration>hours duration>minutes duration>seconds duration>milliseconds duration>microseconds duration>nanoseconds } related-words HELP: time- @@ -484,6 +512,12 @@ HELP: time-since-midnight { $values { "timestamp" timestamp } { "duration" duration } } { $description "Calculates a " { $snippet "duration" } " that represents the elapsed time since midnight of the input " { $snippet "timestamp" } "." } ; +HELP: since-1970 +{ $values + { "duration" duration } + { "timestamp" timestamp } } +{ $description "Adds the duration to the beginning of Unix time and returns the result as a timestamp." } ; + ARTICLE: "calendar" "Calendar" "The two data types used throughout the calendar library:" { $subsection timestamp } @@ -528,6 +562,8 @@ ARTICLE: "using-durations" "Using durations" { $subsection minutes } { $subsection seconds } { $subsection milliseconds } +{ $subsection microseconds } +{ $subsection nanoseconds } { $subsection instant } "Converting a duration to a number:" { $subsection duration>years } @@ -536,7 +572,9 @@ ARTICLE: "using-durations" "Using durations" { $subsection duration>hours } { $subsection duration>minutes } { $subsection duration>seconds } -{ $subsection duration>milliseconds } ; +{ $subsection duration>milliseconds } +{ $subsection duration>microseconds } +{ $subsection duration>nanoseconds } ; ARTICLE: "relative-timestamps" "Relative timestamps" "In the future:" diff --git a/basis/calendar/calendar-tests.factor b/basis/calendar/calendar-tests.factor old mode 100755 new mode 100644 diff --git a/basis/calendar/calendar.factor b/basis/calendar/calendar.factor old mode 100755 new mode 100644 index c2c386a790..c002760748 --- a/basis/calendar/calendar.factor +++ b/basis/calendar/calendar.factor @@ -2,8 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: arrays kernel math math.functions namespaces sequences strings system vocabs.loader threads accessors combinators -locals classes.tuple math.order summary -combinators.short-circuit ; +locals classes.tuple math.order summary combinators.short-circuit ; IN: calendar HOOK: gmt-offset os ( -- hours minutes seconds ) @@ -129,6 +128,8 @@ PRIVATE> : minutes ( x -- duration ) instant clone swap >>minute ; : seconds ( x -- duration ) instant clone swap >>second ; : milliseconds ( x -- duration ) 1000 / seconds ; +: microseconds ( x -- duration ) 1000000 / seconds ; +: nanoseconds ( x -- duration ) 1000000000 / seconds ; GENERIC: leap-year? ( obj -- ? ) @@ -261,6 +262,8 @@ M: duration <=> [ duration>years ] compare ; : duration>minutes ( duration -- x ) duration>years minutes-per-year * ; : duration>seconds ( duration -- x ) duration>years seconds-per-year * ; : duration>milliseconds ( duration -- x ) duration>seconds 1000 * ; +: duration>microseconds ( duration -- x ) duration>seconds 1000000 * ; +: duration>nanoseconds ( duration -- x ) duration>seconds 1000000000 * ; GENERIC: time- ( time1 time2 -- time3 ) @@ -398,6 +401,9 @@ PRIVATE> : time-since-midnight ( timestamp -- duration ) dup midnight time- ; +: since-1970 ( duration -- timestamp ) + unix-1970 time+ >local-time ; + M: timestamp sleep-until timestamp>millis sleep-until ; M: duration sleep hence sleep-until ; diff --git a/basis/calendar/format/format-tests.factor b/basis/calendar/format/format-tests.factor old mode 100755 new mode 100644 diff --git a/basis/calendar/format/format.factor b/basis/calendar/format/format.factor old mode 100755 new mode 100644 diff --git a/basis/calendar/model/model.factor b/basis/calendar/model/model.factor old mode 100755 new mode 100644 diff --git a/basis/calendar/unix/unix.factor b/basis/calendar/unix/unix.factor index 1da554e0f1..d5b66ffc1a 100644 --- a/basis/calendar/unix/unix.factor +++ b/basis/calendar/unix/unix.factor @@ -1,7 +1,17 @@ -USING: alien alien.c-types arrays calendar kernel structs -math unix.time namespaces system ; +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: alien alien.c-types alien.syntax arrays calendar +kernel math unix unix.time namespaces system ; IN: calendar.unix +: timeval>unix-time ( timeval -- timestamp ) + [ timeval-sec seconds ] [ timeval-usec microseconds ] bi + time+ since-1970 ; + +: timespec>unix-time ( timeval -- timestamp ) + [ timespec-sec seconds ] [ timespec-nsec nanoseconds ] bi + time+ since-1970 ; + : get-time ( -- alien ) f time localtime ; diff --git a/basis/calendar/windows/windows.factor b/basis/calendar/windows/windows.factor old mode 100755 new mode 100644 diff --git a/basis/channels/channels-tests.factor b/basis/channels/channels-tests.factor old mode 100755 new mode 100644 diff --git a/basis/channels/channels.factor b/basis/channels/channels.factor old mode 100755 new mode 100644 diff --git a/basis/channels/examples/examples.factor b/basis/channels/examples/examples.factor old mode 100755 new mode 100644 diff --git a/basis/channels/remote/remote.factor b/basis/channels/remote/remote.factor old mode 100755 new mode 100644 diff --git a/basis/checksums/adler-32/adler-32-docs.factor b/basis/checksums/adler-32/adler-32-docs.factor old mode 100755 new mode 100644 diff --git a/basis/checksums/md5/md5-docs.factor b/basis/checksums/md5/md5-docs.factor old mode 100755 new mode 100644 diff --git a/basis/checksums/md5/md5-tests.factor b/basis/checksums/md5/md5-tests.factor old mode 100755 new mode 100644 diff --git a/basis/checksums/md5/md5.factor b/basis/checksums/md5/md5.factor old mode 100755 new mode 100644 diff --git a/basis/checksums/sha1/sha1-tests.factor b/basis/checksums/sha1/sha1-tests.factor old mode 100755 new mode 100644 diff --git a/basis/checksums/sha1/sha1.factor b/basis/checksums/sha1/sha1.factor old mode 100755 new mode 100644 diff --git a/basis/checksums/sha2/sha2-tests.factor b/basis/checksums/sha2/sha2-tests.factor old mode 100755 new mode 100644 diff --git a/basis/checksums/sha2/sha2.factor b/basis/checksums/sha2/sha2.factor old mode 100755 new mode 100644 diff --git a/basis/circular/circular-tests.factor b/basis/circular/circular-tests.factor old mode 100755 new mode 100644 diff --git a/basis/circular/circular.factor b/basis/circular/circular.factor old mode 100755 new mode 100644 diff --git a/basis/cocoa/application/application-docs.factor b/basis/cocoa/application/application-docs.factor index 55fa5e10b8..791613e876 100644 --- a/basis/cocoa/application/application-docs.factor +++ b/basis/cocoa/application/application-docs.factor @@ -26,6 +26,10 @@ HELP: with-cocoa { $values { "quot" quotation } } { $description "Sets up an autorelease pool, initializes the " { $snippet "NSApplication" } " singleton, and calls the quotation." } ; +HELP: cocoa-app +{ $values { "quot" quotation } } +{ $description "Initializes Cocoa, calls the quotation, and starts the Cocoa event loop." } ; + HELP: do-event { $values { "app" "an " { $snippet "NSApplication" } } { "?" "a boolean" } } { $description "Processes a pending event in the queue, if any, returning a boolean indicating if there was one. Does not block." } ; @@ -46,13 +50,16 @@ HELP: objc-error { $error-description "Thrown by the Objective C runtime when an error occurs, for example, sending a message to an object with an unrecognized selector." } ; ARTICLE: "cocoa-application-utils" "Cocoa application utilities" +"Utilities:" { $subsection NSApp } -{ $subsection with-autorelease-pool } -{ $subsection with-cocoa } { $subsection do-event } { $subsection add-observer } { $subsection remove-observer } -{ $subsection install-delegate } ; +{ $subsection install-delegate } +"Combinators:" +{ $subsection cocoa-app } +{ $subsection with-autorelease-pool } +{ $subsection with-cocoa } ; IN: cocoa.application ABOUT: "cocoa-application-utils" diff --git a/basis/cocoa/application/application.factor b/basis/cocoa/application/application.factor old mode 100755 new mode 100644 index a28952ea33..8f32782d76 --- a/basis/cocoa/application/application.factor +++ b/basis/cocoa/application/application.factor @@ -30,7 +30,7 @@ IN: cocoa.application FUNCTION: void NSBeep ( ) ; : with-cocoa ( quot -- ) - [ NSApp drop call ] with-autorelease-pool ; + [ NSApp drop call ] with-autorelease-pool ; inline : next-event ( app -- event ) 0 f CFRunLoopDefaultMode 1 @@ -50,6 +50,13 @@ FUNCTION: void NSBeep ( ) ; : finish-launching ( -- ) NSApp -> finishLaunching ; +: cocoa-app ( quot -- ) + [ + call + finish-launching + NSApp -> run + ] with-cocoa ; inline + : install-delegate ( receiver delegate -- ) -> alloc -> init -> setDelegate: ; diff --git a/basis/cocoa/cocoa-docs.factor b/basis/cocoa/cocoa-docs.factor index a971288251..dd8d331b35 100644 --- a/basis/cocoa/cocoa-docs.factor +++ b/basis/cocoa/cocoa-docs.factor @@ -16,9 +16,16 @@ HELP: SUPER-> { send super-send POSTPONE: -> POSTPONE: SUPER-> } related-words +HELP: IMPORT: +{ $syntax "IMPORT: name" } +{ $description "Makes an Objective C class available for use." } +{ $examples + { $code "IMPORT: QTMovie" "QTMovie \"My Movie.mov\" f -> movieWithFile:error:" } +} ; + ARTICLE: "objc-calling" "Calling Objective C code" "Before an Objective C class can be used, it must be imported; by default, a small set of common classes are imported automatically, but additional classes can be imported as needed." -{ $subsection import-objc-class } +{ $subsection POSTPONE: IMPORT: } "Every imported Objective C class has as corresponding class word in the " { $vocab-link "cocoa.classes" } " vocabulary. Class words push the class object in the stack, allowing class methods to be invoked." $nl "Messages can be sent to classes and instances using a pair of parsing words:" diff --git a/basis/cocoa/cocoa.factor b/basis/cocoa/cocoa.factor old mode 100755 new mode 100644 index 744d577c0d..ab86796236 --- a/basis/cocoa/cocoa.factor +++ b/basis/cocoa/cocoa.factor @@ -3,7 +3,7 @@ USING: compiler io kernel cocoa.runtime cocoa.subclassing cocoa.messages cocoa.types sequences words vocabs parser core-foundation namespaces assocs hashtables compiler.units -lexer ; +lexer init ; IN: cocoa : (remember-send) ( selector variable -- ) @@ -27,6 +27,16 @@ SYMBOL: super-sent-messages scan dup remember-super-send parsed \ super-send parsed ; parsing +SYMBOL: frameworks + +frameworks global [ V{ } clone or ] change-at + +[ frameworks get [ load-framework ] each ] "cocoa.messages" add-init-hook + +: FRAMEWORK: scan [ load-framework ] [ frameworks get push ] bi ; parsing + +: IMPORT: scan [ ] import-objc-class ; parsing + "Compiling Objective C bridge..." print "cocoa.classes" create-vocab drop diff --git a/basis/cocoa/messages/messages-docs.factor b/basis/cocoa/messages/messages-docs.factor index f78981c923..9b5e3fdfd9 100644 --- a/basis/cocoa/messages/messages-docs.factor +++ b/basis/cocoa/messages/messages-docs.factor @@ -32,11 +32,7 @@ HELP: alien>objc-types HELP: import-objc-class { $values { "name" string } { "quot" "a quotation with stack effect " { $snippet "( -- )" } } } -{ $description "If a class named " { $snippet "name" } " is already known to the Objective C interface, does nothing. Otherwise, first calls the quotation. The quotation should make the class available to the Objective C runtime if necessary, either by loading a framework or defining it directly. After the quotation returns, this word makes the class available to Factor programs by importing methods and creating a class word the class object in the " { $vocab-link "cocoa.classes" } " vocabulary." } -{ $notes "In most cases, the quotation should be " { $link f } "." } -{ $examples - { $code "\"QTMovie\" f import-objc-class" "QTMovie \"My Movie.mov\" f -> movieWithFile:error:" } -} ; +{ $description "If a class named " { $snippet "name" } " is already known to the Objective C interface, does nothing. Otherwise, first calls the quotation. The quotation should make the class available to the Objective C runtime if necessary, either by loading a framework or defining it directly. After the quotation returns, this word makes the class available to Factor programs by importing methods and creating a class word the class object in the " { $vocab-link "cocoa.classes" } " vocabulary." } ; HELP: root-class { $values { "class" alien } { "root" alien } } diff --git a/basis/cocoa/messages/messages.factor b/basis/cocoa/messages/messages.factor old mode 100755 new mode 100644 index 7977485b02..09601ef8cc --- a/basis/cocoa/messages/messages.factor +++ b/basis/cocoa/messages/messages.factor @@ -4,7 +4,8 @@ USING: accessors alien alien.c-types alien.strings arrays assocs combinators compiler kernel math namespaces make parser prettyprint prettyprint.sections quotations sequences strings words cocoa.runtime io macros memoize debugger -io.encodings.ascii effects compiler.generator libc libc.private ; +io.encodings.ascii effects compiler.generator libc libc.private +parser lexer init core-foundation ; IN: cocoa.messages : make-sender ( method function -- quot ) diff --git a/basis/cocoa/pasteboard/pasteboard.factor b/basis/cocoa/pasteboard/pasteboard.factor old mode 100755 new mode 100644 diff --git a/basis/cocoa/subclassing/subclassing.factor b/basis/cocoa/subclassing/subclassing.factor old mode 100755 new mode 100644 diff --git a/basis/cocoa/windows/windows.factor b/basis/cocoa/windows/windows.factor old mode 100755 new mode 100644 diff --git a/basis/colors/colors.factor b/basis/colors/colors.factor index 77a1f46c87..1183c2e46c 100644 --- a/basis/colors/colors.factor +++ b/basis/colors/colors.factor @@ -1,48 +1,33 @@ -! Copyright (C) 2003, 2007, 2008 Slava Pestov. +! Copyright (C) 2003, 2008 Slava Pestov. +! Copyright (C) 2008 Eduardo Cavazos. ! See http://factorcode.org/license.txt for BSD license. - -USING: kernel combinators sequences arrays classes.tuple accessors colors.hsv ; - +USING: kernel accessors ; IN: colors -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - TUPLE: color ; TUPLE: rgba < color red green blue alpha ; -TUPLE: hsva < color hue saturation value alpha ; - -TUPLE: gray < color gray alpha ; - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +C: rgba GENERIC: >rgba ( object -- rgba ) M: rgba >rgba ( rgba -- rgba ) ; -M: hsva >rgba ( hsva -- rgba ) - { [ hue>> ] [ saturation>> ] [ value>> ] [ alpha>> ] } cleave 4array - [ hsv>rgb ] [ peek ] bi suffix first4 rgba boa ; - -M: gray >rgba ( gray -- rgba ) [ gray>> dup dup ] [ alpha>> ] bi rgba boa ; - M: color red>> ( color -- red ) >rgba red>> ; M: color green>> ( color -- green ) >rgba green>> ; M: color blue>> ( color -- blue ) >rgba blue>> ; -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -: black T{ rgba f 0.0 0.0 0.0 1.0 } ; -: blue T{ rgba f 0.0 0.0 1.0 1.0 } ; -: cyan T{ rgba f 0 0.941 0.941 1 } ; -: gray T{ rgba f 0.6 0.6 0.6 1.0 } ; -: green T{ rgba f 0.0 1.0 0.0 1.0 } ; -: light-gray T{ rgba f 0.95 0.95 0.95 0.95 } ; -: light-purple T{ rgba f 0.8 0.8 1.0 1.0 } ; -: magenta T{ rgba f 0.941 0 0.941 1 } ; -: orange T{ rgba f 0.941 0.627 0 1 } ; -: purple T{ rgba f 0.627 0 0.941 1 } ; -: red T{ rgba f 1.0 0.0 0.0 1.0 } ; -: white T{ rgba f 1.0 1.0 1.0 1.0 } ; -: yellow T{ rgba f 1.0 1.0 0.0 1.0 } ; +: black T{ rgba f 0.0 0.0 0.0 1.0 } ; inline +: blue T{ rgba f 0.0 0.0 1.0 1.0 } ; inline +: cyan T{ rgba f 0 0.941 0.941 1 } ; inline +: gray T{ rgba f 0.6 0.6 0.6 1.0 } ; inline +: green T{ rgba f 0.0 1.0 0.0 1.0 } ; inline +: light-gray T{ rgba f 0.95 0.95 0.95 0.95 } ; inline +: light-purple T{ rgba f 0.8 0.8 1.0 1.0 } ; inline +: magenta T{ rgba f 0.941 0 0.941 1 } ; inline +: orange T{ rgba f 0.941 0.627 0 1 } ; inline +: purple T{ rgba f 0.627 0 0.941 1 } ; inline +: red T{ rgba f 1.0 0.0 0.0 1.0 } ; inline +: white T{ rgba f 1.0 1.0 1.0 1.0 } ; inline +: yellow T{ rgba f 1.0 1.0 0.0 1.0 } ; inline diff --git a/basis/colors/gray/gray.factor b/basis/colors/gray/gray.factor new file mode 100644 index 0000000000..26ec1177b6 --- /dev/null +++ b/basis/colors/gray/gray.factor @@ -0,0 +1,11 @@ +! Copyright (C) 2008 Eduardo Cavazos. +! See http://factorcode.org/license.txt for BSD license. +USING: colors kernel accessors ; +IN: colors.gray + +TUPLE: gray < color gray alpha ; + +C: gray + +M: gray >rgba ( gray -- rgba ) + [ gray>> dup dup ] [ alpha>> ] bi ; diff --git a/basis/colors/hsv/hsv-tests.factor b/basis/colors/hsv/hsv-tests.factor new file mode 100644 index 0000000000..8a736553bb --- /dev/null +++ b/basis/colors/hsv/hsv-tests.factor @@ -0,0 +1,26 @@ +IN: colors.hsv.tests +USING: accessors kernel colors colors.hsv tools.test math ; + +: hsv>rgb ( h s v -- r g b ) + [ 360 * ] 2dip + 1 >rgba [ red>> ] [ green>> ] [ blue>> ] tri ; + +[ 1/2 1/2 1/2 ] [ 0 0 1/2 hsv>rgb ] unit-test + +[ 1/2 1/4 1/4 ] [ 0 1/2 1/2 hsv>rgb ] unit-test +[ 1/3 2/9 2/9 ] [ 0 1/3 1/3 hsv>rgb ] unit-test + +[ 24/125 1/5 4/25 ] [ 1/5 1/5 1/5 hsv>rgb ] unit-test +[ 29/180 1/6 5/36 ] [ 1/5 1/6 1/6 hsv>rgb ] unit-test + +[ 6/25 2/5 38/125 ] [ 2/5 2/5 2/5 hsv>rgb ] unit-test +[ 8/25 4/5 64/125 ] [ 2/5 3/5 4/5 hsv>rgb ] unit-test + +[ 6/25 48/125 3/5 ] [ 3/5 3/5 3/5 hsv>rgb ] unit-test +[ 0 0 0 ] [ 3/5 1/5 0 hsv>rgb ] unit-test + +[ 84/125 4/25 4/5 ] [ 4/5 4/5 4/5 hsv>rgb ] unit-test +[ 7/15 1/3 1/2 ] [ 4/5 1/3 1/2 hsv>rgb ] unit-test + +[ 5/6 5/36 5/6 ] [ 5/6 5/6 5/6 hsv>rgb ] unit-test +[ 1/6 0 1/6 ] [ 5/6 1 1/6 hsv>rgb ] unit-test diff --git a/basis/colors/hsv/hsv.factor b/basis/colors/hsv/hsv.factor index dd2811822b..6f658818a1 100644 --- a/basis/colors/hsv/hsv.factor +++ b/basis/colors/hsv/hsv.factor @@ -1,41 +1,38 @@ -! Copyright (C) 2007 Eduardo Cavazos +! Copyright (C) 2008 Eduardo Cavazos. ! See http://factorcode.org/license.txt for BSD license. - -USING: kernel combinators arrays sequences math math.functions ; - +USING: colors kernel combinators math math.functions accessors ; IN: colors.hsv - - ! h [0,360) ! s [0,1] ! v [0,1] +TUPLE: hsva < color hue saturation value alpha ; -: hsv>rgb ( hsv -- rgb ) -dup Hi -{ { 0 [ [ V ] [ t ] [ p ] tri ] } - { 1 [ [ q ] [ V ] [ p ] tri ] } - { 2 [ [ p ] [ V ] [ t ] tri ] } - { 3 [ [ p ] [ q ] [ V ] tri ] } - { 4 [ [ t ] [ p ] [ V ] tri ] } - { 5 [ [ V ] [ p ] [ q ] tri ] } } case 3array ; +C: hsva + +> 60 / floor 6 mod ; inline + +: f ( hsv -- f ) [ hue>> 60 / ] [ Hi ] bi - ; inline + +: p ( hsv -- p ) [ saturation>> 1 swap - ] [ value>> ] bi * ; inline + +: q ( hsv -- q ) [ [ f ] [ saturation>> ] bi * 1 swap - ] [ value>> ] bi * ; inline + +: t ( hsv -- t ) [ [ f 1 swap - ] [ saturation>> ] bi * 1 swap - ] [ value>> ] bi * ; inline + +PRIVATE> + +M: hsva >rgba ( hsva -- rgba ) + [ + dup Hi + { + { 0 [ [ value>> ] [ t ] [ p ] tri ] } + { 1 [ [ q ] [ value>> ] [ p ] tri ] } + { 2 [ [ p ] [ value>> ] [ t ] tri ] } + { 3 [ [ p ] [ q ] [ value>> ] tri ] } + { 4 [ [ t ] [ p ] [ value>> ] tri ] } + { 5 [ [ value>> ] [ p ] [ q ] tri ] } + } case + ] [ alpha>> ] bi ; diff --git a/basis/combinators/short-circuit/short-circuit.factor b/basis/combinators/short-circuit/short-circuit.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/compiler-docs.factor b/basis/compiler/compiler-docs.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/compiler.factor b/basis/compiler/compiler.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/constants/constants.factor b/basis/compiler/constants/constants.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/generator/fixup/fixup.factor b/basis/compiler/generator/fixup/fixup.factor old mode 100755 new mode 100644 index ecc88a7a5e..e8bdc561b7 --- a/basis/compiler/generator/fixup/fixup.factor +++ b/basis/compiler/generator/fixup/fixup.factor @@ -13,7 +13,7 @@ TUPLE: frame-required n ; : frame-required ( n -- ) \ frame-required boa , ; -: stack-frame-size ( code -- n ) +: compute-stack-frame-size ( code -- n ) no-stack-frame [ dup frame-required? [ n>> max ] [ drop ] if ] reduce ; @@ -37,7 +37,7 @@ M: label fixup* : if-stack-frame ( frame-size quot -- ) swap dup no-stack-frame = - [ 2drop ] [ stack-frame swap call ] if ; inline + [ 2drop ] [ stack-frame-size swap call ] if ; inline M: word fixup* { @@ -146,7 +146,7 @@ SYMBOL: literal-table : fixup ( code -- literals relocation labels code ) [ init-fixup - dup stack-frame-size swap [ fixup* ] each drop + dup compute-stack-frame-size swap [ fixup* ] each drop literal-table get >array relocation-table get >byte-array diff --git a/basis/compiler/generator/generator-docs.factor b/basis/compiler/generator/generator-docs.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/generator/generator.factor b/basis/compiler/generator/generator.factor old mode 100755 new mode 100644 index 0a9885357e..22de9d3587 --- a/basis/compiler/generator/generator.factor +++ b/basis/compiler/generator/generator.factor @@ -296,24 +296,20 @@ M: #return-recursive generate-node : return-size ( ctype -- n ) #! Amount of space we reserve for a return value. - dup large-struct? [ heap-size ] [ drop 0 ] if ; + dup large-struct? [ heap-size ] [ drop 2 cells ] if ; : alien-stack-frame ( params -- n ) - alien-parameters parameter-sizes drop ; + stack-frame new + swap + [ return>> return-size >>return ] + [ alien-parameters parameter-sizes drop >>params ] bi + dup [ params>> ] [ return>> ] bi + >>size + dup size>> stack-frame-size >>total-size ; -: alien-invoke-frame ( params -- n ) - #! Two cells for temporary storage, temp@ and on x86.64, - #! small struct return value unpacking - [ return>> return-size ] [ alien-stack-frame ] bi - + 2 cells + ; - -: set-stack-frame ( n -- ) - dup [ frame-required ] when* \ stack-frame set ; - -: with-stack-frame ( n quot -- ) - swap set-stack-frame +: with-stack-frame ( params quot -- ) + swap alien-stack-frame [ size>> frame-required ] [ stack-frame set ] bi call - f set-stack-frame ; inline + stack-frame off ; inline GENERIC: reg-size ( register-class -- n ) @@ -416,8 +412,8 @@ M: long-long-type flatten-value-type ( type -- types ) #! parameters. If the C function is returning a structure, #! the first parameter is an implicit target area pointer, #! so we need to use a different offset. - return>> dup large-struct? - [ heap-size %prepare-box-struct cell ] [ drop 0 ] if ; + return>> large-struct? + [ %prepare-box-struct cell ] [ 0 ] if ; : objects>registers ( params -- ) #! Generate code for unboxing a list of C types, then @@ -476,7 +472,7 @@ M: no-such-symbol compiler-error-type M: #alien-invoke generate-node params>> - dup alien-invoke-frame [ + dup [ end-basic-block %prepare-alien-invoke dup objects>registers @@ -490,7 +486,7 @@ M: #alien-invoke generate-node ! #alien-indirect M: #alien-indirect generate-node params>> - dup alien-invoke-frame [ + dup [ ! Flush registers end-basic-block ! Save registers for GC @@ -556,7 +552,7 @@ TUPLE: callback-context ; : callback-unwind ( params -- n ) { - { [ dup abi>> "stdcall" = ] [ alien-stack-frame ] } + { [ dup abi>> "stdcall" = ] [ drop stack-frame get params>> ] } { [ dup return>> large-struct? ] [ drop 4 ] } [ drop 0 ] } cond ; @@ -572,7 +568,7 @@ TUPLE: callback-context ; dup xt>> dup [ init-templates %prologue-later - dup alien-stack-frame [ + dup [ [ registers>objects ] [ wrap-callback-quot %alien-callback ] [ %callback-return ] diff --git a/basis/compiler/generator/registers/registers.factor b/basis/compiler/generator/registers/registers.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/tests/alien.factor b/basis/compiler/tests/alien.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/tests/curry.factor b/basis/compiler/tests/curry.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/tests/float.factor b/basis/compiler/tests/float.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/tests/intrinsics.factor b/basis/compiler/tests/intrinsics.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/tests/optimizer.factor b/basis/compiler/tests/optimizer.factor old mode 100755 new mode 100644 index 4c39da0479..f1b3e32eed --- a/basis/compiler/tests/optimizer.factor +++ b/basis/compiler/tests/optimizer.factor @@ -362,3 +362,18 @@ TUPLE: some-tuple x ; [ B{ 0 1 2 3 4 5 6 7 } ] [ [ 8 [ ] B{ } map-as ] compile-call ] unit-test [ 0 ] [ 1234 [ { fixnum } declare -64 shift ] compile-call ] unit-test + +! Loop detection problem found by doublec +SYMBOL: counter + +DEFER: loop-bbb + +: loop-aaa ( -- ) + counter inc counter get 2 < [ loop-bbb ] when ; inline recursive + +: loop-bbb ( -- ) + [ loop-aaa ] with-scope ; inline recursive + +: loop-ccc ( -- ) loop-bbb ; + +[ 0 ] [ 0 counter set loop-ccc counter get ] unit-test diff --git a/basis/compiler/tests/simple.factor b/basis/compiler/tests/simple.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/tests/stack-trace.factor b/basis/compiler/tests/stack-trace.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/tests/templates-early.factor b/basis/compiler/tests/templates-early.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/tests/templates.factor b/basis/compiler/tests/templates.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/tests/tuples.factor b/basis/compiler/tests/tuples.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/tree/dead-code/simple/simple.factor b/basis/compiler/tree/dead-code/simple/simple.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/tree/def-use/def-use-tests.factor b/basis/compiler/tree/def-use/def-use-tests.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/tree/def-use/def-use.factor b/basis/compiler/tree/def-use/def-use.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/tree/propagation/propagation-tests.factor b/basis/compiler/tree/propagation/propagation-tests.factor index d73e8b7db1..19ee051ac6 100644 --- a/basis/compiler/tree/propagation/propagation-tests.factor +++ b/basis/compiler/tree/propagation/propagation-tests.factor @@ -8,7 +8,7 @@ math.functions math.private strings layouts compiler.tree.propagation.info compiler.tree.def-use compiler.tree.debugger compiler.tree.checker slots.private words hashtables classes assocs locals -float-arrays ; +float-arrays system ; IN: compiler.tree.propagation.tests \ propagate must-infer @@ -590,6 +590,8 @@ MIXIN: empty-mixin [ V{ float-array } ] [ [| | F{ } ] final-classes ] unit-test +[ V{ t } ] [ [ netbsd unix? ] final-literals ] unit-test + ! [ V{ string } ] [ ! [ dup string? t xor [ "A" throw ] [ ] if ] final-classes ! ] unit-test diff --git a/basis/compiler/tree/propagation/propagation.factor b/basis/compiler/tree/propagation/propagation.factor old mode 100755 new mode 100644 diff --git a/basis/compiler/tree/propagation/simple/simple.factor b/basis/compiler/tree/propagation/simple/simple.factor index 7fc38239f1..d586ff398f 100644 --- a/basis/compiler/tree/propagation/simple/simple.factor +++ b/basis/compiler/tree/propagation/simple/simple.factor @@ -76,13 +76,25 @@ M: #declare propagate-before : fold-call ( #call word -- ) [ (fold-call) ] [ drop out-d>> ] 2bi set-value-infos ; -: predicate-output-infos ( info class -- info ) +: predicate-output-infos/literal ( info class -- info ) + [ literal>> ] dip + '[ _ _ instance? ] + [ drop object-info ] + recover ; + +: predicate-output-infos/class ( info class -- info ) [ class>> ] dip { { [ 2dup class<= ] [ t ] } { [ 2dup classes-intersect? not ] [ f ] } [ object-info ] } cond 2nip ; +: predicate-output-infos ( info class -- info ) + over literal?>> + [ predicate-output-infos/literal ] + [ predicate-output-infos/class ] + if ; + : propagate-predicate ( #call word -- infos ) #! We need to force the caller word to recompile when the class #! is redefined, since now we're making assumptions but the diff --git a/basis/compiler/tree/recursive/recursive-tests.factor b/basis/compiler/tree/recursive/recursive-tests.factor index c66c182869..b1f9406092 100644 --- a/basis/compiler/tree/recursive/recursive-tests.factor +++ b/basis/compiler/tree/recursive/recursive-tests.factor @@ -148,3 +148,27 @@ DEFER: a' [ a' ] build-tree analyze-recursive \ b' label-is-loop? ] unit-test + +DEFER: a'' + +: b'' ( -- ) + a'' ; inline recursive + +: a'' ( -- ) + b'' a'' ; inline recursive + +[ t ] [ + [ a'' ] build-tree analyze-recursive + \ a'' label-is-not-loop? +] unit-test + +: loop-in-non-loop ( x quot: ( i -- ) -- ) + over 0 > [ + [ [ 1 - ] dip loop-in-non-loop ] [ call ] 2bi + ] [ 2drop ] if ; inline recursive + +[ t ] [ + [ 10 [ [ drop ] each-integer ] loop-in-non-loop ] + build-tree analyze-recursive + \ (each-integer) label-is-loop? +] unit-test diff --git a/basis/compiler/tree/recursive/recursive.factor b/basis/compiler/tree/recursive/recursive.factor index d1e4c7c70e..d257cd6600 100644 --- a/basis/compiler/tree/recursive/recursive.factor +++ b/basis/compiler/tree/recursive/recursive.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel assocs namespaces accessors sequences deques +USING: kernel assocs arrays namespaces accessors sequences deques search-deques compiler.tree compiler.tree.combinators ; IN: compiler.tree.recursive @@ -50,11 +50,10 @@ GENERIC: collect-loop-info* ( tail? node -- ) loop-stack get length swap loop-heights get set-at ; M: #recursive collect-loop-info* - nip [ [ label>> - [ loop-stack [ swap suffix ] change ] + [ swap 2array loop-stack [ swap suffix ] change ] [ remember-loop-info ] [ t >>loop? drop ] tri @@ -62,7 +61,7 @@ M: #recursive collect-loop-info* [ t swap child>> (collect-loop-info) ] bi ] with-scope ; -: current-loop-nesting ( label -- labels ) +: current-loop-nesting ( label -- alist ) loop-stack get swap loop-heights get at tail ; : disqualify-loop ( label -- ) @@ -71,7 +70,10 @@ M: #recursive collect-loop-info* M: #call-recursive collect-loop-info* label>> swap [ dup disqualify-loop ] unless - dup current-loop-nesting [ loop-calls get push-at ] with each ; + dup current-loop-nesting + [ keys [ loop-calls get push-at ] with each ] + [ [ nip not ] assoc-filter keys [ disqualify-loop ] each ] + bi ; M: #if collect-loop-info* children>> [ (collect-loop-info) ] with each ; diff --git a/basis/compiler/tree/tree.factor b/basis/compiler/tree/tree.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/combinators/combinators-docs.factor b/basis/concurrency/combinators/combinators-docs.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/combinators/combinators-tests.factor b/basis/concurrency/combinators/combinators-tests.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/combinators/combinators.factor b/basis/concurrency/combinators/combinators.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/conditions/conditions.factor b/basis/concurrency/conditions/conditions.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/count-downs/count-downs-docs.factor b/basis/concurrency/count-downs/count-downs-docs.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/count-downs/count-downs-tests.factor b/basis/concurrency/count-downs/count-downs-tests.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/count-downs/count-downs.factor b/basis/concurrency/count-downs/count-downs.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/distributed/distributed-docs.factor b/basis/concurrency/distributed/distributed-docs.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/distributed/distributed-tests.factor b/basis/concurrency/distributed/distributed-tests.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/distributed/distributed.factor b/basis/concurrency/distributed/distributed.factor old mode 100755 new mode 100644 index 5e2f1bb6d1..99ad239011 --- a/basis/concurrency/distributed/distributed.factor +++ b/basis/concurrency/distributed/distributed.factor @@ -10,7 +10,7 @@ SYMBOL: local-node : handle-node-client ( -- ) deserialize - [ first2 get-process send ] [ stop-server ] if* ; + [ first2 get-process send ] [ stop-this-server ] if* ; : ( addrspec -- threaded-server ) diff --git a/basis/concurrency/exchangers/exchangers-docs.factor b/basis/concurrency/exchangers/exchangers-docs.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/exchangers/exchangers-tests.factor b/basis/concurrency/exchangers/exchangers-tests.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/exchangers/exchangers.factor b/basis/concurrency/exchangers/exchangers.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/flags/flags-tests.factor b/basis/concurrency/flags/flags-tests.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/flags/flags.factor b/basis/concurrency/flags/flags.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/futures/futures-docs.factor b/basis/concurrency/futures/futures-docs.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/futures/futures-tests.factor b/basis/concurrency/futures/futures-tests.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/futures/futures.factor b/basis/concurrency/futures/futures.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/locks/locks-docs.factor b/basis/concurrency/locks/locks-docs.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/locks/locks-tests.factor b/basis/concurrency/locks/locks-tests.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/locks/locks.factor b/basis/concurrency/locks/locks.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/mailboxes/mailboxes-docs.factor b/basis/concurrency/mailboxes/mailboxes-docs.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/mailboxes/mailboxes-tests.factor b/basis/concurrency/mailboxes/mailboxes-tests.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/mailboxes/mailboxes.factor b/basis/concurrency/mailboxes/mailboxes.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/messaging/messaging-docs.factor b/basis/concurrency/messaging/messaging-docs.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/messaging/messaging-tests.factor b/basis/concurrency/messaging/messaging-tests.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/messaging/messaging.factor b/basis/concurrency/messaging/messaging.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/promises/promises-docs.factor b/basis/concurrency/promises/promises-docs.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/promises/promises-tests.factor b/basis/concurrency/promises/promises-tests.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/promises/promises.factor b/basis/concurrency/promises/promises.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/semaphores/semaphores-docs.factor b/basis/concurrency/semaphores/semaphores-docs.factor old mode 100755 new mode 100644 diff --git a/basis/concurrency/semaphores/semaphores.factor b/basis/concurrency/semaphores/semaphores.factor old mode 100755 new mode 100644 diff --git a/unmaintained/webapps/help/authors.txt b/basis/core-foundation/run-loop/authors.txt old mode 100755 new mode 100644 similarity index 100% rename from unmaintained/webapps/help/authors.txt rename to basis/core-foundation/run-loop/authors.txt diff --git a/basis/core-foundation/run-loop/summary.txt b/basis/core-foundation/run-loop/summary.txt new file mode 100644 index 0000000000..ae92138528 --- /dev/null +++ b/basis/core-foundation/run-loop/summary.txt @@ -0,0 +1 @@ +CoreFoundation run loop integration diff --git a/unmaintained/webapps/pastebin/authors.txt b/basis/core-foundation/run-loop/thread/authors.txt old mode 100755 new mode 100644 similarity index 100% rename from unmaintained/webapps/pastebin/authors.txt rename to basis/core-foundation/run-loop/thread/authors.txt diff --git a/basis/core-foundation/run-loop/thread/summary.txt b/basis/core-foundation/run-loop/thread/summary.txt new file mode 100644 index 0000000000..e5818b3d78 --- /dev/null +++ b/basis/core-foundation/run-loop/thread/summary.txt @@ -0,0 +1 @@ +Vocabulary with init hook for running CoreFoundation event loop diff --git a/basis/core-foundation/run-loop/thread/tags.txt b/basis/core-foundation/run-loop/thread/tags.txt new file mode 100644 index 0000000000..6bf68304bb --- /dev/null +++ b/basis/core-foundation/run-loop/thread/tags.txt @@ -0,0 +1 @@ +unportable diff --git a/basis/cpu/architecture/architecture.factor b/basis/cpu/architecture/architecture.factor old mode 100755 new mode 100644 index 63c52d1025..f22d4a2a90 --- a/basis/cpu/architecture/architecture.factor +++ b/basis/cpu/architecture/architecture.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2006, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays generic kernel kernel.private math memory -namespaces make sequences layouts system hashtables classes -alien byte-arrays combinators words sets ; +USING: accessors arrays generic kernel kernel.private math +memory namespaces make sequences layouts system hashtables +classes alien byte-arrays combinators words sets ; IN: cpu.architecture ! Register classes @@ -33,10 +33,9 @@ GENERIC# load-literal 1 ( obj vreg -- ) HOOK: load-indirect cpu ( obj reg -- ) -HOOK: stack-frame cpu ( frame-size -- n ) +HOOK: stack-frame-size cpu ( frame-size -- n ) -: stack-frame* ( -- n ) - \ stack-frame get stack-frame ; +TUPLE: stack-frame total-size size params return ; ! Set up caller stack frame HOOK: %prologue cpu ( n -- ) @@ -117,7 +116,7 @@ HOOK: %box cpu ( n reg-class func -- ) HOOK: %box-long-long cpu ( n func -- ) -HOOK: %prepare-box-struct cpu ( size -- ) +HOOK: %prepare-box-struct cpu ( -- ) HOOK: %box-small-struct cpu ( c-type -- ) diff --git a/basis/cpu/ppc/allot/allot.factor b/basis/cpu/ppc/allot/allot.factor old mode 100755 new mode 100644 diff --git a/basis/cpu/ppc/architecture/architecture.factor b/basis/cpu/ppc/architecture/architecture.factor old mode 100755 new mode 100644 index 80ee1802e1..117ab51fe2 --- a/basis/cpu/ppc/architecture/architecture.factor +++ b/basis/cpu/ppc/architecture/architecture.factor @@ -43,7 +43,7 @@ IN: cpu.ppc.architecture : xt-save ( n -- i ) 2 cells - ; -M: ppc stack-frame ( n -- i ) +M: ppc stack-frame-size ( n -- i ) local@ factor-area-size + 4 cells align ; M: temp-reg v>operand drop 11 ; @@ -96,9 +96,9 @@ M: ppc %epilogue ( n -- ) 1 1 rot ADDI 0 MTLR ; -: (%call) ( -- ) 11 MTLR BLRL ; +: (%call) ( reg -- ) MTLR BLRL ; -: (%jump) ( -- ) 11 MTCTR BCTR ; +: (%jump) ( reg -- ) MTCTR BCTR ; : %load-dlsym ( symbol dll register -- ) 0 swap LOAD32 rc-absolute-ppc-2/2 rel-dlsym ; @@ -117,7 +117,7 @@ M: ppc %dispatch ( -- ) "offset" operand "n" operand 1 SRAWI 11 11 "offset" operand ADD 11 dup 6 cells LWZ - (%jump) + 11 (%jump) ] H{ { +input+ { { f "n" } } } { +scratch+ { { f "offset" } } } @@ -166,11 +166,13 @@ M: float-regs %load-param-reg >r 1 rot local@ r> LF ; M: stack-params %load-param-reg ( stack reg reg-class -- ) drop >r 0 1 rot local@ LWZ 0 1 r> param@ STW ; +: next-param@ ( n -- x ) param@ stack-frame get total-size>> + ; + M: stack-params %save-param-reg ( stack reg reg-class -- ) #! Funky. Read the parameter from the caller's stack frame. #! This word is used in callbacks drop - 0 1 rot param@ stack-frame* + LWZ + 0 1 rot next-param@ LWZ 0 1 rot local@ STW ; M: ppc %prepare-unbox ( -- ) @@ -197,10 +199,8 @@ M: ppc %unbox-long-long ( n func -- ) M: ppc %unbox-large-struct ( n c-type -- ) ! Value must be in r3 - ! Compute destination address - 4 1 roll local@ ADDI - ! Load struct size - heap-size 5 LI + ! Compute destination address and load struct size + [ 4 1 rot local@ ADDI ] [ heap-size 5 LI ] bi* ! Call the function "to_value_struct" f %alien-invoke ; @@ -218,23 +218,18 @@ M: ppc %box-long-long ( n func -- ) 4 1 rot cell + local@ LWZ ] when* r> f %alien-invoke ; -: temp@ ( m -- n ) stack-frame* factor-area-size - swap - ; +: struct-return@ ( n -- n ) + [ stack-frame get params>> ] unless* local@ ; -: struct-return@ ( size n -- n ) [ local@ ] [ temp@ ] ?if ; - -M: ppc %prepare-box-struct ( size -- ) +M: ppc %prepare-box-struct ( -- ) #! Compute target address for value struct return - 3 1 rot f struct-return@ ADDI + 3 1 f struct-return@ ADDI 3 1 0 local@ STW ; M: ppc %box-large-struct ( n c-type -- ) - #! If n = f, then we're boxing a returned struct - heap-size - [ swap struct-return@ ] keep - ! Compute destination address - 3 1 roll ADDI - ! Load struct size - 4 LI + ! If n = f, then we're boxing a returned struct + ! Compute destination address and load struct size + [ 3 1 rot struct-return@ ADDI ] [ heap-size 4 LI ] bi* ! Call the function "box_value_struct" f %alien-invoke ; @@ -249,17 +244,17 @@ M: ppc %prepare-alien-invoke rs-reg 11 12 STW ; M: ppc %alien-invoke ( symbol dll -- ) - 11 %load-dlsym (%call) ; + 11 %load-dlsym 11 (%call) ; M: ppc %alien-callback ( quot -- ) 3 load-indirect "c_to_factor" f %alien-invoke ; M: ppc %prepare-alien-indirect ( -- ) "unbox_alien" f %alien-invoke - 3 1 cell temp@ STW ; + 13 3 MR ; M: ppc %alien-indirect ( -- ) - 11 1 cell temp@ LWZ (%call) ; + 13 (%call) ; M: ppc %callback-value ( ctype -- ) ! Save top of data stack diff --git a/basis/cpu/ppc/assembler/assembler.factor b/basis/cpu/ppc/assembler/assembler.factor old mode 100755 new mode 100644 diff --git a/basis/cpu/ppc/bootstrap.factor b/basis/cpu/ppc/bootstrap.factor old mode 100755 new mode 100644 diff --git a/basis/cpu/ppc/intrinsics/intrinsics.factor b/basis/cpu/ppc/intrinsics/intrinsics.factor old mode 100755 new mode 100644 diff --git a/basis/cpu/ppc/linux/bootstrap.factor b/basis/cpu/ppc/linux/bootstrap.factor old mode 100755 new mode 100644 diff --git a/basis/cpu/ppc/macosx/bootstrap.factor b/basis/cpu/ppc/macosx/bootstrap.factor old mode 100755 new mode 100644 diff --git a/basis/cpu/ppc/ppc.factor b/basis/cpu/ppc/ppc.factor old mode 100755 new mode 100644 diff --git a/basis/cpu/x86/32/32.factor b/basis/cpu/x86/32/32.factor old mode 100755 new mode 100644 index 50d8025b38..dc891a8178 --- a/basis/cpu/x86/32/32.factor +++ b/basis/cpu/x86/32/32.factor @@ -1,13 +1,12 @@ ! Copyright (C) 2005, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: alien.c-types arrays cpu.x86.assembler +USING: locals alien.c-types arrays cpu.x86.assembler cpu.x86.architecture cpu.x86.intrinsics cpu.x86.allot cpu.architecture kernel kernel.private math namespaces sequences -stack-checker.known-words -compiler.generator.registers compiler.generator.fixup -compiler.generator system layouts combinators -command-line compiler compiler.units io vocabs.loader accessors -init ; +stack-checker.known-words compiler.generator.registers +compiler.generator.fixup compiler.generator system layouts +combinators command-line compiler compiler.units io +vocabs.loader accessors init ; IN: cpu.x86.32 ! We implement the FFI for Linux, OS X and Windows all at once. @@ -18,7 +17,6 @@ IN: cpu.x86.32 M: x86.32 ds-reg ESI ; M: x86.32 rs-reg EDI ; M: x86.32 stack-reg ESP ; -M: x86.32 stack-save-reg EDX ; M: x86.32 temp-reg-1 EAX ; M: x86.32 temp-reg-2 ECX ; @@ -32,15 +30,20 @@ M: x86.32 struct-small-enough? ( size -- ? ) heap-size { 1 2 4 8 } member? os { linux netbsd solaris } member? not and ; +: struct-return@ ( n -- operand ) + [ next-stack@ ] [ stack-frame get params>> stack@ ] if* ; + ! On x86, parameters are never passed in registers. M: int-regs return-reg drop EAX ; M: int-regs param-regs drop { } ; M: int-regs vregs drop { EAX ECX EDX EBP } ; M: int-regs push-return-reg return-reg PUSH ; -: load/store-int-return ( n reg-class -- src dst ) - return-reg stack-reg rot [+] ; -M: int-regs load-return-reg load/store-int-return MOV ; -M: int-regs store-return-reg load/store-int-return swap MOV ; + +M: int-regs load-return-reg + return-reg swap next-stack@ MOV ; + +M: int-regs store-return-reg + [ stack@ ] [ return-reg ] bi* MOV ; M: float-regs param-regs drop { } ; M: float-regs vregs drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ; @@ -48,23 +51,26 @@ M: float-regs vregs drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ; : FSTP ( operand size -- ) 4 = [ FSTPS ] [ FSTPL ] if ; M: float-regs push-return-reg - stack-reg swap reg-size [ SUB stack-reg [] ] keep FSTP ; + stack-reg swap reg-size + [ SUB ] [ [ [] ] dip FSTP ] 2bi ; : FLD ( operand size -- ) 4 = [ FLDS ] [ FLDL ] if ; -: load/store-float-return ( n reg-class -- op size ) - [ stack@ ] [ reg-size ] bi* ; -M: float-regs load-return-reg load/store-float-return FLD ; -M: float-regs store-return-reg load/store-float-return FSTP ; +M: float-regs load-return-reg + [ next-stack@ ] [ reg-size ] bi* FLD ; + +M: float-regs store-return-reg + [ stack@ ] [ reg-size ] bi* FSTP ; : align-sub ( n -- ) - dup 16 align swap - ESP swap SUB ; + [ align-stack ] keep - decr-stack-reg ; : align-add ( n -- ) - 16 align ESP swap ADD ; + align-stack incr-stack-reg ; : with-aligned-stack ( n quot -- ) - swap dup align-sub slip align-add ; inline + [ [ align-sub ] [ call ] bi* ] + [ [ align-add ] [ drop ] bi* ] 2bi ; inline M: x86.32 fixnum>slot@ 1 SHR ; @@ -77,68 +83,51 @@ M: object %load-param-reg 3drop ; M: object %save-param-reg 3drop ; -: box@ ( n reg-class -- stack@ ) - #! Used for callbacks; we want to box the values given to - #! us by the C function caller. Computes stack location of - #! nth parameter; note that we must go back one more stack - #! frame, since %box sets one up to call the one-arg boxer - #! function. The size of this stack frame so far depends on - #! the reg-class of the boxer's arg. - reg-size neg + stack-frame* + 20 + ; - : (%box) ( n reg-class -- ) #! If n is f, push the return register onto the stack; we #! are boxing a return value of a C function. If n is an #! integer, push [ESP+n] on the stack; we are boxing a #! parameter being passed to a callback from C. - over [ [ box@ ] keep [ load-return-reg ] keep ] [ nip ] if - push-return-reg ; + over [ load-return-reg ] [ 2drop ] if ; -M: x86.32 %box ( n reg-class func -- ) - over reg-size [ - >r (%box) r> f %alien-invoke +M:: x86.32 %box ( n reg-class func -- ) + n reg-class (%box) + reg-class reg-size [ + reg-class push-return-reg + func f %alien-invoke ] with-aligned-stack ; : (%box-long-long) ( n -- ) - #! If n is f, push the return registers onto the stack; we - #! are boxing a return value of a C function. If n is an - #! integer, push [ESP+n]:[ESP+n+4] on the stack; we are - #! boxing a parameter being passed to a callback from C. [ - int-regs box@ - EDX over stack@ MOV - EAX swap cell - stack@ MOV - ] when* - EDX PUSH - EAX PUSH ; + EDX over next-stack@ MOV + EAX swap cell - next-stack@ MOV + ] when* ; M: x86.32 %box-long-long ( n func -- ) + [ (%box-long-long) ] dip 8 [ - [ (%box-long-long) ] [ f %alien-invoke ] bi* + EDX PUSH + EAX PUSH + f %alien-invoke ] with-aligned-stack ; -: struct-return@ ( size n -- n ) - [ stack-frame* cell + + ] [ \ stack-frame get swap - ] ?if ; - -M: x86.32 %box-large-struct ( n c-type -- ) +M:: x86.32 %box-large-struct ( n c-type -- ) ! Compute destination address - heap-size - [ swap struct-return@ ] keep - ECX ESP roll [+] LEA + ECX n struct-return@ LEA 8 [ ! Push struct size - PUSH + c-type heap-size PUSH ! Push destination address ECX PUSH ! Copy the struct from the C stack "box_value_struct" f %alien-invoke ] with-aligned-stack ; -M: x86.32 %prepare-box-struct ( size -- ) +M: x86.32 %prepare-box-struct ( -- ) ! Compute target address for value struct return - EAX ESP rot f struct-return@ [+] LEA + EAX f struct-return@ LEA ! Store it as the first parameter - ESP [] EAX MOV ; + 0 stack@ EAX MOV ; M: x86.32 %box-small-struct ( c-type -- ) #! Box a <= 8-byte struct returned in EAX:EDX. OS X only. @@ -207,13 +196,12 @@ M: x86 %unbox-small-struct ( size -- ) } case ; M: x86.32 %unbox-large-struct ( n c-type -- ) - #! Alien must be in EAX. - heap-size + ! Alien must be in EAX. ! Compute destination address - ECX ESP roll [+] LEA + ECX rot stack@ LEA 12 [ ! Push struct size - PUSH + heap-size PUSH ! Push destination address ECX PUSH ! Push source address @@ -224,10 +212,10 @@ M: x86.32 %unbox-large-struct ( n c-type -- ) M: x86.32 %prepare-alien-indirect ( -- ) "unbox_alien" f %alien-invoke - cell temp@ EAX MOV ; + EBP EAX MOV ; M: x86.32 %alien-indirect ( -- ) - cell temp@ CALL ; + EBP CALL ; M: x86.32 %alien-callback ( quot -- ) 4 [ @@ -239,7 +227,7 @@ M: x86.32 %alien-callback ( quot -- ) M: x86.32 %callback-value ( ctype -- ) ! Align C stack ESP 12 SUB - ! Save top of data stack + ! Save top of data stack in non-volatile register %prepare-unbox EAX PUSH ! Restore data/call/retain stacks @@ -260,7 +248,7 @@ M: x86.32 %cleanup ( alien-node -- ) { { [ dup abi>> "stdcall" = ] - [ alien-stack-frame ESP swap SUB ] + [ drop ESP stack-frame get params>> SUB ] } { [ dup return>> large-struct? ] [ drop EAX PUSH ] diff --git a/basis/cpu/x86/32/bootstrap.factor b/basis/cpu/x86/32/bootstrap.factor old mode 100755 new mode 100644 diff --git a/basis/cpu/x86/64/64.factor b/basis/cpu/x86/64/64.factor old mode 100755 new mode 100644 index 01b8935e39..5bcd733eaa --- a/basis/cpu/x86/64/64.factor +++ b/basis/cpu/x86/64/64.factor @@ -12,7 +12,6 @@ IN: cpu.x86.64 M: x86.64 ds-reg R14 ; M: x86.64 rs-reg R15 ; M: x86.64 stack-reg RSP ; -M: x86.64 stack-save-reg RSI ; M: x86.64 temp-reg-1 RAX ; M: x86.64 temp-reg-2 RCX ; @@ -46,7 +45,9 @@ M: stack-params %load-param-reg r> stack@ R11 MOV ; M: stack-params %save-param-reg - >r stack-frame* + cell + swap r> %load-param-reg ; + drop + R11 swap next-stack@ MOV + stack@ R11 MOV ; : with-return-regs ( quot -- ) [ @@ -121,7 +122,7 @@ M: x86.64 %unbox-large-struct ( n c-type -- ) ! Source is in RDI heap-size ! Load destination address - RSI RSP roll [+] LEA + RSI rot stack@ LEA ! Load structure size RDX swap MOV ! Copy the struct to the C stack @@ -145,7 +146,7 @@ M: x86.64 %box-long-long ( n func -- ) M: x86.64 struct-small-enough? ( size -- ? ) heap-size 2 cells <= ; -: box-struct-field@ ( i -- operand ) RSP swap 1+ cells [+] ; +: box-struct-field@ ( i -- operand ) 1+ cells stack@ ; : %box-struct-field ( c-type i -- ) box-struct-field@ swap reg-class>> { @@ -163,22 +164,22 @@ M: x86.64 %box-small-struct ( c-type -- ) "box_small_struct" f %alien-invoke ] with-return-regs ; -: struct-return@ ( size n -- n ) - [ ] [ \ stack-frame get swap - ] ?if ; +: struct-return@ ( n -- operand ) + [ stack-frame get params>> ] unless* stack@ ; M: x86.64 %box-large-struct ( n c-type -- ) ! Struct size is parameter 2 - heap-size - RSI over MOV + RSI swap heap-size MOV ! Compute destination address - swap struct-return@ RDI RSP rot [+] LEA + RDI swap struct-return@ LEA ! Copy the struct from the C stack "box_value_struct" f %alien-invoke ; -M: x86.64 %prepare-box-struct ( size -- ) +M: x86.64 %prepare-box-struct ( -- ) ! Compute target address for value struct return - RAX RSP rot f struct-return@ [+] LEA - RSP 0 [+] RAX MOV ; + RAX f struct-return@ LEA + ! Store it as the first parameter + 0 stack@ RAX MOV ; M: x86.64 %prepare-var-args RAX RAX XOR ; @@ -192,10 +193,10 @@ M: x86.64 %alien-invoke M: x86.64 %prepare-alien-indirect ( -- ) "unbox_alien" f %alien-invoke - cell temp@ RAX MOV ; + RBP RAX MOV ; M: x86.64 %alien-indirect ( -- ) - cell temp@ CALL ; + RBP CALL ; M: x86.64 %alien-callback ( quot -- ) RDI load-indirect "c_to_factor" f %alien-invoke ; @@ -203,12 +204,14 @@ M: x86.64 %alien-callback ( quot -- ) M: x86.64 %callback-value ( ctype -- ) ! Save top of data stack %prepare-unbox - ! Put former top of data stack in RDI - cell temp@ RDI MOV + ! Save top of data stack + RSP 8 SUB + RDI PUSH ! Restore data/call/retain stacks "unnest_stacks" f %alien-invoke ! Put former top of data stack in RDI - RDI cell temp@ MOV + RDI POP + RSP 8 ADD ! Unbox former top of data stack to return registers unbox-return ; diff --git a/basis/cpu/x86/64/bootstrap.factor b/basis/cpu/x86/64/bootstrap.factor old mode 100755 new mode 100644 diff --git a/basis/cpu/x86/allot/allot.factor b/basis/cpu/x86/allot/allot.factor old mode 100755 new mode 100644 diff --git a/basis/cpu/x86/architecture/architecture.factor b/basis/cpu/x86/architecture/architecture.factor old mode 100755 new mode 100644 index c97552a649..01256fb4c5 --- a/basis/cpu/x86/architecture/architecture.factor +++ b/basis/cpu/x86/architecture/architecture.factor @@ -10,10 +10,16 @@ IN: cpu.x86.architecture HOOK: ds-reg cpu ( -- reg ) HOOK: rs-reg cpu ( -- reg ) HOOK: stack-reg cpu ( -- reg ) -HOOK: stack-save-reg cpu ( -- reg ) : stack@ ( n -- op ) stack-reg swap [+] ; +: next-stack@ ( n -- operand ) + #! nth parameter from the next stack frame. Used to box + #! input values to callbacks; the callback has its own + #! stack frame set up, and we want to read the frame + #! set up by the caller. + stack-frame get total-size>> + stack@ ; + : reg-stack ( n reg -- op ) swap cells neg [+] ; M: ds-loc v>operand n>> ds-reg reg-stack ; @@ -32,8 +38,8 @@ M: float-regs %save-param-reg >r >r stack@ r> r> MOVSS/D ; M: float-regs %load-param-reg >r swap stack@ r> MOVSS/D ; GENERIC: push-return-reg ( reg-class -- ) -GENERIC: load-return-reg ( stack@ reg-class -- ) -GENERIC: store-return-reg ( stack@ reg-class -- ) +GENERIC: load-return-reg ( n reg-class -- ) +GENERIC: store-return-reg ( n reg-class -- ) ! Only used by inline allocation HOOK: temp-reg-1 cpu ( -- reg ) @@ -45,21 +51,27 @@ HOOK: prepare-division cpu ( -- ) M: immediate load-literal v>operand swap v>operand MOV ; -M: x86 stack-frame ( n -- i ) - 3 cells + 16 align cell - ; +: align-stack ( n -- n' ) + os macosx? cpu x86.64? or [ 16 align ] when ; + +M: x86 stack-frame-size ( n -- i ) + 3 cells + align-stack ; M: x86 %save-word-xt ( -- ) temp-reg v>operand 0 MOV rc-absolute-cell rel-this ; -: factor-area-size ( -- n ) 4 cells ; +: decr-stack-reg ( n -- ) + dup 0 = [ drop ] [ stack-reg swap SUB ] if ; M: x86 %prologue ( n -- ) - dup cell + PUSH + dup PUSH temp-reg v>operand PUSH - stack-reg swap 2 cells - SUB ; + 3 cells - decr-stack-reg ; -M: x86 %epilogue ( n -- ) - stack-reg swap ADD ; +: incr-stack-reg ( n -- ) + dup 0 = [ drop ] [ stack-reg swap ADD ] if ; + +M: x86 %epilogue ( n -- ) cell - incr-stack-reg ; HOOK: %alien-global cpu ( symbol dll register -- ) @@ -137,8 +149,6 @@ M: x86 small-enough? ( n -- ? ) : %tag-fixnum ( reg -- ) tag-bits get SHL ; -: temp@ ( n -- op ) stack-reg \ stack-frame get rot - [+] ; - M: x86 %return ( -- ) 0 %unwind ; ! Alien intrinsics diff --git a/basis/cpu/x86/assembler/assembler.factor b/basis/cpu/x86/assembler/assembler.factor old mode 100755 new mode 100644 diff --git a/basis/cpu/x86/bootstrap.factor b/basis/cpu/x86/bootstrap.factor old mode 100755 new mode 100644 diff --git a/basis/cpu/x86/intrinsics/intrinsics.factor b/basis/cpu/x86/intrinsics/intrinsics.factor old mode 100755 new mode 100644 diff --git a/basis/cpu/x86/sse2/sse2.factor b/basis/cpu/x86/sse2/sse2.factor old mode 100755 new mode 100644 diff --git a/basis/db/db-docs.factor b/basis/db/db-docs.factor index 74b72b8789..52dc389fe6 100644 --- a/basis/db/db-docs.factor +++ b/basis/db/db-docs.factor @@ -5,98 +5,81 @@ alien assocs strings math multiline quotations ; IN: db HELP: db -{ $description "The " { $snippet "db" } " class is the superclass of all other database classes. It stores a " { $snippet "handle" } " to the database as well as insert, update, and delete queries." } ; +{ $description "The " { $snippet "db" } " class is the superclass of all other database classes. It stores a " { $snippet "handle" } " to the database as well as insert, update, and delete queries." } ; HELP: new-db { $values { "class" class } { "obj" object } } -{ $description "Creates a new database object from a given class." } ; - -HELP: make-db* -{ $values { "object" object } { "db" object } { "db" object } } -{ $description "Takes a sequence of parameters specific to each database and a class name of the database, and constructs a new database object." } ; - -HELP: make-db -{ $values { "object" object } { "class" class } { "db" db } } -{ $description "Takes a sequence of parameters specific to each database and a class name of the database, and constructs a new database object." } ; +{ $description "Creates a new database object from a given class with caches for prepared statements. Does not actually connect to the database until " { $link db-open } " or " { $link with-db } " is called." } +{ $notes "User-defined databases must call this constructor word instead of " { $link new } "." } ; HELP: db-open { $values { "db" db } { "db" db } } -{ $description "Opens a database using the configuration data stored in a " { $link db } " tuple." } ; +{ $description "Opens a database using the configuration data stored in a " { $link db } " tuple. The database object now references a database handle that must be cleaned up. Therefore, it is better to use the " { $link with-db } " combinator than calling this word directly." } ; HELP: db-close { $values { "handle" alien } } -{ $description "Closes a database using the handle provided." } ; +{ $description "Closes a database using the handle provided. Use of the " { $link with-db } " combinator is preferred over manually opening and closing databases so that resources are not leaked." } ; + +{ db-open db-close with-db } related-words HELP: dispose-statements { $values { "assoc" assoc } } { $description "Disposes an associative list of statements." } ; -HELP: db-dispose -{ $values { "db" db } } -{ $description "Disposes of all the statements stored in the " { $link db } " object." } ; - HELP: statement { $description "A " { $snippet "statement" } " stores the information about a statemen, such as the SQL statement text, the in/out parameters, and type information." } ; -HELP: simple-statement -{ $description } ; - -HELP: prepared-statement -{ $description } ; - HELP: result-set { $description "An object encapsulating a raw SQL result object. There are two ways in which a result set can be accessed, but they are specific to the database backend in use." { $subsection "db-random-access-result-set" } { $subsection "db-sequential-result-set" } } ; -HELP: init-result-set -{ $values - { "result-set" result-set } } -{ $description "" } ; - HELP: new-result-set { $values { "query" "a query" } { "handle" alien } { "class" class } { "result-set" result-set } } { $description "Creates a new " { $link result-set } " object of type " { $snippet "class" } "." } ; - HELP: new-statement { $values { "sql" string } { "in" sequence } { "out" sequence } { "class" class } { "statement" statement } } { $description "Makes a new statement object from the given parameters." } ; +HELP: bind-statement +{ $values + { "obj" object } { "statement" statement } } +{ $description "Sets the statement's " { $slot "bind-params" } " and calls " { $link bind-statement* } " to do the database-specific bind. Sets " { $slot "bound?" } " to true if binding succeeds." } ; + +HELP: bind-statement* +{ $values + { "statement" statement } } +{ $description "Does a low-level bind of the SQL statement's tuple parameters if the database requires. Some databases should treat this as a no-op and bind instead when the actual statement is run." } ; + HELP: { $values { "string" string } { "in" sequence } { "out" sequence } { "statement" statement } } -{ $description "Makes a new simple statement object from the given parameters." } ; +{ $description "Makes a new simple statement object from the given parameters.." } +{ $warning "Using a simple statement can lead to SQL injection attacks in PostgreSQL. The Factor database implementation for SQLite only uses " { $link } " as the sole kind of statement; simple statements alias to prepared ones." } ; HELP: { $values { "string" string } { "in" sequence } { "out" sequence } { "statement" statement } } -{ $description "Makes a new prepared statement object from the given parameters." } ; +{ $description "Makes a new prepared statement object from the given parameters. A prepared statement's parameters will be escaped by the database backend to avoid SQL injection attacks. Prepared statements should be preferred over simple statements." } ; HELP: prepare-statement { $values { "statement" statement } } { $description "For databases which implement a method on this generic, it does some internal processing to ready the statement for execution." } ; -HELP: bind-statement* -{ $values { "statement" statement } } -{ $description "" } ; - HELP: low-level-bind -{ $values { "statement" statement } } -{ $description "" } ; - -HELP: bind-tuple -{ $values { "tuple" tuple } { "statement" statement } } -{ $description "" } ; +{ $values + { "statement" statement } } +{ $description "For use with prepared statements, methods on this word should bind the datatype in the SQL spec to its identifier in the SQL string. To name bound variables, SQLite uses identifiers in the form of " { $snippet ":name" } ", while PostgreSQL uses increasing numbers beginning with a dollar sign, e.g. " { $snippet "$1" } "." } ; HELP: query-results { $values { "query" object } { "result-set" result-set } } -{ $description "Returns a " { $link result-set } " object representing the reults of a SQL query." } ; +{ $description "Returns a " { $link result-set } " object representing the results of a SQL query. See " { $link "db-result-sets" } "." } ; HELP: #rows { $values { "result-set" result-set } { "n" integer } } @@ -125,41 +108,14 @@ HELP: more-rows? { $values { "result-set" result-set } { "?" "a boolean" } } { $description "Returns true if the " { $link result-set } " has more rows to traverse." } ; -HELP: execute-statement* -{ $values { "statement" statement } { "type" object } } -{ $description } ; - -HELP: execute-one-statement -{ $values - { "statement" null } } -{ $description "" } ; - -HELP: execute-statement -{ $values { "statement" statement } } -{ $description "" } ; - - - - HELP: begin-transaction { $description "Begins a new transaction. User code should make use of the " { $link with-transaction } " combinator." } ; -HELP: bind-statement -{ $values - { "obj" object } { "statement" null } } -{ $description "" } ; - HELP: commit-transaction { $description "Commits a transaction. User code should make use of the " { $link with-transaction } " combinator." } ; -HELP: default-query -{ $values - { "query" null } - { "result-set" null } } -{ $description "" } ; - HELP: in-transaction { $description "A variable that is set true when a transaction is in progress." } ; @@ -170,14 +126,14 @@ HELP: in-transaction? HELP: query-each { $values - { "statement" null } { "quot" quotation } } -{ $description "" } ; + { "statement" statement } { "quot" quotation } } +{ $description "A combinator that calls a quotation on a sequence of SQL statements to their results query results." } ; HELP: query-map { $values - { "statement" null } { "quot" quotation } + { "statement" statement } { "quot" quotation } { "seq" sequence } } -{ $description "" } ; +{ $description "A combinator that maps a sequence of SQL statements to their results query results." } ; HELP: rollback-transaction { $description "Rolls back a transaction; no data is committed to the database. User code should make use of the " { $link with-transaction } " combinator." } ; @@ -211,8 +167,8 @@ HELP: sql-row-typed HELP: with-db { $values - { "seq" sequence } { "class" class } { "quot" quotation } } -{ $description "Calls the quotation with a database bound to the " { $link db } " symbol. The database called is based on the " { $snippet "class" } " with the " } ; + { "db" db } { "quot" quotation } } +{ $description "Calls the quotation with a database bound to the " { $link db } " symbol. See " { $link "db-custom-database-combinators" } " for help setting up database access." } ; HELP: with-transaction { $values @@ -220,22 +176,18 @@ HELP: with-transaction { $description "" } ; ARTICLE: "db" "Database library" +"Accessing a database:" { $subsection "db-custom-database-combinators" } +"Higher-level database help:" +{ $vocab-subsection "Database types" "db.types" } +{ $vocab-subsection "High-level tuple/database integration" "db.tuples" } +"Low-level database help:" { $subsection "db-protocol" } { $subsection "db-result-sets" } { $subsection "db-lowlevel-tutorial" } -"Higher-level database:" -{ $vocab-subsection "Database types" "db.types" } -{ $vocab-subsection "High-level tuple/database integration" "db.tuples" } -! { $subsection "db-tuples" } -! { $subsection "db-tuples-protocol" } -! { $subsection "db-tuples-tutorial" } "Supported database backends:" { $vocab-subsection "SQLite" "db.sqlite" } -{ $vocab-subsection "PostgreSQL" "db.postgresql" } -"To add support for another database to Factor:" -{ $subsection "db-porting-the-library" } -; +{ $vocab-subsection "PostgreSQL" "db.postgresql" } ; ARTICLE: "db-random-access-result-set" "Random access result sets" "Random-access result sets do not have to be traversed in order. For instance, PostgreSQL's result set object can be accessed as a matrix with i,j coordinates." @@ -247,7 +199,7 @@ $nl { $subsection row-column-typed } ; ARTICLE: "db-sequential-result-set" "Sequential result sets" -"Sequential result sets can be iterated one element after the next. SQLite's result sets offer this method of traversal." +"Sequential result sets can be iterated one element after the next. SQLite's result sets offer this method of traversal." $nl "Databases which work in this way must provide methods for the following traversal words:" { $subsection more-rows? } @@ -272,27 +224,75 @@ $nl { $subsection row-column-typed } ; ARTICLE: "db-protocol" "Low-level database protocol" -"The high-level protocol (see " { $vocab-link "db.tuples" } ") uses this low-level protocol for executing statements and queries." +"The high-level protocol (see " { $vocab-link "db.tuples" } ") uses this low-level protocol for executing statements and queries." $nl +"Opening a database:" +{ $subsection db-open } +"Closing a database:" +{ $subsection db-close } +"Creating tatements:" +{ $subsection } +{ $subsection } +"Using statements with the database:" +{ $subsection prepare-statement } +{ $subsection bind-statement* } +{ $subsection low-level-bind } +"Performing a query:" +{ $subsection query-results } +"Handling query results:" +{ $subsection "db-result-sets" } ; +! { $subsection bind-tuple } ARTICLE: "db-lowlevel-tutorial" "Low-level database tutorial" "Although Factor makes integrating a database with its object system easy (see " { $vocab-link "db.tuples" } "), sometimes you may want to write SQL directly and get the results back as arrays of strings, for instance, when interfacing with a legacy database that doesn't easily map to " { $snippet "tuples" } "." -; - -ARTICLE: "db-porting-the-library" "Porting the database library" -"This section is not yet written." -; - -ARTICLE: "db-custom-database-combinators" "Custom database combinators" -"Every database library requires some effort on the programmer's part to initialize and open a database. SQLite uses files on your harddisk, so a simple pathname is all the setup required. With PostgreSQL, you log in to a networked server as a user on a specfic port." $nl - -"Make a " { $snippet "with-" } " word to open, close, and use your database." +"Executing a SQL command:" +{ $subsection sql-command } +"Executing a query directly:" +{ $subsection sql-query } +"Here's an example usage where we'll make a book table, insert some objects, and query them." $nl +"First, let's set up a custom combinator for using our database. See " { $link "db-custom-database-combinators" } " for more details." { $code <" USING: db.sqlite db io.files ; -: with-my-database ( quot -- ) - { "my-database.db" temp-file } sqlite-db rot with-db ; -"> } +: with-book-db ( quot -- ) + "book.db" temp-file swap with-db ;"> } +"Now let's create the table manually:" +{ $code <" "create table books + (id integer primary key, title text, author text, date_published timestamp, + edition integer, cover_price double, condition text)" + [ sql-command ] with-book-db" "> } +"Time to insert some books:" +{ $code <" +"insert into books + (title, author, date_published, edition, cover_price, condition) + values('Factor for Sheeple', 'Mister Stacky Pants', date('now'), 1, 13.37, 'mint')" +[ sql-command ] with-book-db"> } +"Now let's select the book:" +{ $code <" +"select id, title, cover_price from books;" [ sql-query ] with-book-db "> } +"Notice that the result of this query is a Factor array containing the database rows as arrays of strings. We would have to convert the " { $snippet "cover_price" } " from a string to a number in order to use it in a calculation." $nl +"In conclusion, this method of accessing a database is supported, but it is fairly low-level and generally specific to a single database. The " { $vocab-link "db.tuples" } " vocabulary is a good alternative to writing SQL by hand." ; -; +ARTICLE: "db-custom-database-combinators" "Custom database combinators" +"Every database library requires some effort on the programmer's part to initialize and open a database. SQLite uses files on your harddisk, so a simple pathname is all the setup required. With PostgreSQL, you log in to a networked server as a user on a specfic port." $nl + +"Make a " { $snippet "with-" } " combinator to open and close a database so that resources are not leaked." $nl + +"SQLite example combinator:" +{ $code <" +USING: db.sqlite db io.files ; +: with-sqlite-db ( quot -- ) + "my-database.db" temp-file swap with-db ; inline"> } + +"PostgreSQL example combinator:" +{ $code <" USING: db.postgresql db ; +: with-postgresql-db ( quot -- ) + + "localhost" >>host + 5432 >>port + "erg" >>username + "secrets?" >>password + "factor-test" >>database + swap with-db ; inline"> +} ; ABOUT: "db" diff --git a/basis/db/db-tests.factor b/basis/db/db-tests.factor old mode 100755 new mode 100644 index 3f1dab2c37..56b6c25a19 --- a/basis/db/db-tests.factor +++ b/basis/db/db-tests.factor @@ -3,4 +3,4 @@ IN: db.tests { 1 0 } [ [ drop ] query-each ] must-infer-as { 1 1 } [ [ ] query-map ] must-infer-as -{ 2 0 } [ [ ] with-db ] must-infer-as +{ 1 0 } [ [ ] with-db ] must-infer-as diff --git a/basis/db/db.factor b/basis/db/db.factor old mode 100755 new mode 100644 index 87bf21d261..3ee0fe3d09 --- a/basis/db/db.factor +++ b/basis/db/db.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: arrays assocs classes continuations destructors kernel math namespaces sequences classes.tuple words strings -tools.walker accessors combinators ; +tools.walker accessors combinators fry ; IN: db TUPLE: db @@ -17,23 +17,18 @@ TUPLE: db H{ } clone >>update-statements H{ } clone >>delete-statements ; inline -GENERIC: make-db* ( object db -- db ) - -: make-db ( object class -- db ) new-db make-db* ; - GENERIC: db-open ( db -- db ) HOOK: db-close db ( handle -- ) : dispose-statements ( assoc -- ) values dispose-each ; -: db-dispose ( db -- ) +M: db dispose ( db -- ) dup db [ - { - [ insert-statements>> dispose-statements ] - [ update-statements>> dispose-statements ] - [ delete-statements>> dispose-statements ] - [ handle>> db-close ] - } cleave + [ dispose-statements H{ } clone ] change-insert-statements + [ dispose-statements H{ } clone ] change-update-statements + [ dispose-statements H{ } clone ] change-delete-statements + [ db-close f ] change-handle + drop ] with-variable ; TUPLE: result-set sql in-params out-params handle n max ; @@ -111,27 +106,26 @@ M: object execute-statement* ( statement type -- ) : query-map ( statement quot -- seq ) accumulator [ query-each ] dip { } like ; inline -: with-db ( seq class quot -- ) - [ make-db db-open db ] dip - [ db get swap [ drop ] prepose with-disposal ] curry with-variable ; - inline +: with-db ( db quot -- ) + [ db-open db ] dip + '[ db get [ drop @ ] with-disposal ] with-variable ; inline +! Words for working with raw SQL statements : default-query ( query -- result-set ) query-results [ [ sql-row ] query-map ] with-disposal ; : sql-query ( sql -- rows ) f f [ default-query ] with-disposal ; -: sql-command ( sql -- ) - dup string? [ - f f [ execute-statement ] with-disposal - ] [ - ! [ - [ sql-command ] each - ! ] with-transaction - ] if ; +: (sql-command) ( string -- ) + f f [ execute-statement ] with-disposal ; +: sql-command ( sql -- ) + dup string? [ (sql-command) ] [ [ (sql-command) ] each ] if ; + +! Transactions SYMBOL: in-transaction + HOOK: begin-transaction db ( -- ) HOOK: commit-transaction db ( -- ) HOOK: rollback-transaction db ( -- ) diff --git a/basis/db/pools/pools-tests.factor b/basis/db/pools/pools-tests.factor index f07d1e8468..0a68db501b 100644 --- a/basis/db/pools/pools-tests.factor +++ b/basis/db/pools/pools-tests.factor @@ -4,7 +4,7 @@ accessors kernel math destructors ; \ must-infer -{ 2 0 } [ [ ] with-db-pool ] must-infer-as +{ 1 0 } [ [ ] with-db-pool ] must-infer-as { 1 0 } [ [ ] with-pooled-db ] must-infer-as @@ -13,7 +13,7 @@ USE: db.sqlite [ "pool-test.db" temp-file delete-file ] ignore-errors -[ ] [ "pool-test.db" temp-file sqlite-db "pool" set ] unit-test +[ ] [ "pool-test.db" temp-file "pool" set ] unit-test [ ] [ "pool" get expired>> t >>expired drop ] unit-test diff --git a/basis/db/pools/pools.factor b/basis/db/pools/pools.factor index 63153c451e..8bc5e87f0e 100644 --- a/basis/db/pools/pools.factor +++ b/basis/db/pools/pools.factor @@ -1,21 +1,20 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel arrays namespaces sequences continuations -io.pools db ; +io.pools db fry ; IN: db.pools -TUPLE: db-pool < pool db params ; +TUPLE: db-pool < pool db ; -: ( params db -- pool ) +: ( db -- pool ) db-pool - swap >>db - swap >>params ; + swap >>db ; -: with-db-pool ( db params quot -- ) - >r r> with-pool ; inline +: with-db-pool ( db quot -- ) + [ ] dip with-pool ; inline M: db-pool make-connection ( pool -- ) - [ params>> ] [ db>> ] bi make-db db-open ; + db>> db-open ; : with-pooled-db ( pool quot -- ) - [ db swap with-variable ] curry with-pooled-connection ; inline + '[ db _ with-variable ] with-pooled-connection ; inline diff --git a/basis/db/postgresql/ffi/ffi.factor b/basis/db/postgresql/ffi/ffi.factor old mode 100755 new mode 100644 diff --git a/basis/db/postgresql/lib/lib.factor b/basis/db/postgresql/lib/lib.factor old mode 100755 new mode 100644 diff --git a/basis/db/postgresql/postgresql-tests.factor b/basis/db/postgresql/postgresql-tests.factor old mode 100755 new mode 100644 index 65b75a63dc..fe53e2416e --- a/basis/db/postgresql/postgresql-tests.factor +++ b/basis/db/postgresql/postgresql-tests.factor @@ -1,13 +1,14 @@ -! You will need to run 'createdb factor-test' to create the database. -! Set username and password in the 'connect' word. - USING: kernel db.postgresql alien continuations io classes prettyprint sequences namespaces tools.test db -db.tuples db.types unicode.case ; +db.tuples db.types unicode.case accessors ; IN: db.postgresql.tests : test-db ( -- postgresql-db ) - { "localhost" "postgres" "foob" "factor-test" } postgresql-db ; + + "localhost" >>host + "postgres" >>username + "thepasswordistrust" >>password + "factor-test" >>database ; [ ] [ test-db [ ] with-db ] unit-test @@ -92,4 +93,4 @@ IN: db.postgresql.tests : with-dummy-db ( quot -- ) - >r T{ postgresql-db } db r> with-variable ; + [ T{ postgresql-db } db ] dip with-variable ; diff --git a/basis/db/postgresql/postgresql.factor b/basis/db/postgresql/postgresql.factor old mode 100755 new mode 100644 index 28548d1260..2b4cadf489 --- a/basis/db/postgresql/postgresql.factor +++ b/basis/db/postgresql/postgresql.factor @@ -10,32 +10,28 @@ USE: tools.walker IN: db.postgresql TUPLE: postgresql-db < db - host port pgopts pgtty db user pass ; + host port pgopts pgtty database username password ; + +: ( -- postgresql-db ) + postgresql-db new-db ; TUPLE: postgresql-statement < statement ; TUPLE: postgresql-result-set < result-set ; -M: postgresql-db make-db* ( seq db -- db ) - >r first4 r> - swap >>db - swap >>pass - swap >>user - swap >>host ; - M: postgresql-db db-open ( db -- db ) dup { [ host>> ] [ port>> ] [ pgopts>> ] [ pgtty>> ] - [ db>> ] - [ user>> ] - [ pass>> ] + [ database>> ] + [ username>> ] + [ password>> ] } cleave connect-postgres >>handle ; -M: postgresql-db dispose ( db -- ) - handle>> PQfinish ; +M: postgresql-db db-close ( handle -- ) + PQfinish ; M: postgresql-statement bind-statement* ( statement -- ) drop ; @@ -102,7 +98,7 @@ M: postgresql-result-set dispose ( result-set -- ) M: postgresql-statement prepare-statement ( statement -- ) dup - >r db get handle>> f r> + [ db get handle>> f ] dip [ sql>> ] [ in-params>> ] bi length f PQprepare postgresql-error >>handle drop ; @@ -121,7 +117,8 @@ M: postgresql-db bind% ( spec -- ) bind-name% 1, ; M: postgresql-db bind# ( spec object -- ) - >r bind-name% f swap type>> r> 1, ; + [ bind-name% f swap type>> ] dip + 1, ; : create-table-sql ( class -- statement ) [ @@ -143,7 +140,7 @@ M: postgresql-db bind# ( spec object -- ) : create-function-sql ( class -- statement ) [ - >r remove-id r> + [ remove-id ] dip "create function add_" 0% dup 0% "(" 0% over [ "," 0% ] @@ -233,6 +230,7 @@ M: postgresql-db persistent-table ( -- hashtable ) { +foreign-id+ { f f "references" } } + { +on-update+ { f f "on update" } } { +on-delete+ { f f "on delete" } } { +restrict+ { f f "restrict" } } { +cascade+ { f f "cascade" } } diff --git a/basis/db/queries/queries.factor b/basis/db/queries/queries.factor index f7809de578..3cf4d98215 100644 --- a/basis/db/queries/queries.factor +++ b/basis/db/queries/queries.factor @@ -2,8 +2,8 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel math namespaces make sequences random strings math.parser math.intervals combinators math.bitwise -nmake db db.tuples db.types db.sql classes words shuffle arrays -destructors continuations db.tuples.private ; +nmake db db.tuples db.types classes words shuffle arrays +destructors continuations db.tuples.private prettyprint ; IN: db.queries GENERIC: where ( specs obj -- ) @@ -45,11 +45,14 @@ M: retryable execute-statement* ( statement type -- ) : sql-props ( class -- columns table ) [ db-columns ] [ db-table ] bi ; -: query-make ( class quot -- ) +: query-make ( class quot -- statements ) + #! query, input, outputs, secondary queries + over unparse "table" set [ sql-props ] dip [ 0 sql-counter rot with-variable ] curry - { "" { } { } } nmake - maybe-make-retryable ; inline + { "" { } { } { } } nmake + [ maybe-make-retryable ] dip + [ [ 1array ] dip append ] unless-empty ; inline : where-primary-key% ( specs -- ) " where " 0% @@ -111,6 +114,9 @@ M: sequence where ( spec obj -- ) [ " or " 0% ] [ dupd where ] interleave drop ] in-parens ; +M: NULL where ( spec obj -- ) + drop column-name>> 0% " is NULL" 0% ; + : object-where ( spec obj -- ) over column-name>> 0% " = " 0% bind# ; @@ -142,35 +148,34 @@ M: db ( tuple table -- sql ) where-clause ] query-make ; +ERROR: all-slots-ignored class ; + M: db ( tuple class -- statement ) [ "select " 0% - over [ ", " 0% ] + [ dupd filter-ignores ] dip + over empty? [ all-slots-ignored ] when + over + [ ", " 0% ] [ dup column-name>> 0% 2, ] interleave - " from " 0% 0% where-clause ] query-make ; +: splice ( string1 string2 string3 -- string ) + swap 3append ; + : do-group ( tuple groups -- ) - [ - ", " join " group by " swap 3append - ] curry change-sql drop ; + [ ", " join " group by " splice ] curry change-sql drop ; : do-order ( tuple order -- ) - [ - ", " join " order by " swap 3append - ] curry change-sql drop ; + [ ", " join " order by " splice ] curry change-sql drop ; : do-offset ( tuple n -- ) - [ - number>string " offset " swap 3append - ] curry change-sql drop ; + [ number>string " offset " splice ] curry change-sql drop ; : do-limit ( tuple n -- ) - [ - number>string " limit " swap 3append - ] curry change-sql drop ; + [ number>string " limit " splice ] curry change-sql drop ; : make-query* ( tuple query -- tuple' ) dupd @@ -187,18 +192,6 @@ M: db query>statement ( query -- tuple ) ! select ID, NAME, SCORE from EXAM limit 1 offset 3 -: select-tuples* ( tuple -- statement ) - dup - [ - select 0, - dup class db-columns [ ", " 0, ] - [ dup column-name>> 0, 2, ] interleave - from 0, - class name>> 0, - ] { { } { } { } } nmake - >r >r parse-sql 4drop r> r> - maybe-make-retryable do-select ; - M: db ( query -- statement ) [ tuple>> dup class ] keep [ [ "select count(*) from " 0% 0% where-clause ] query-make ] diff --git a/basis/db/sqlite/ffi/ffi.factor b/basis/db/sqlite/ffi/ffi.factor old mode 100755 new mode 100644 diff --git a/basis/db/sqlite/lib/lib.factor b/basis/db/sqlite/lib/lib.factor old mode 100755 new mode 100644 diff --git a/basis/db/sqlite/sqlite-tests.factor b/basis/db/sqlite/sqlite-tests.factor old mode 100755 new mode 100644 index 67eac2702b..fe95980bcf --- a/basis/db/sqlite/sqlite-tests.factor +++ b/basis/db/sqlite/sqlite-tests.factor @@ -4,7 +4,7 @@ continuations db.types db.tuples unicode.case ; IN: db.sqlite.tests : db-path "test.db" temp-file ; -: test.db db-path sqlite-db ; +: test.db db-path ; [ ] [ [ db-path delete-file ] ignore-errors ] unit-test diff --git a/basis/db/sqlite/sqlite.factor b/basis/db/sqlite/sqlite.factor old mode 100755 new mode 100644 index aab1e5f40f..93135a23e3 --- a/basis/db/sqlite/sqlite.factor +++ b/basis/db/sqlite/sqlite.factor @@ -5,19 +5,20 @@ io.files kernel math math.parser namespaces prettyprint sequences strings classes.tuple alien.c-types continuations db.sqlite.lib db.sqlite.ffi db.tuples words db.types combinators math.intervals io nmake accessors vectors math.ranges random -math.bitwise db.queries destructors db.tuples.private ; +math.bitwise db.queries destructors db.tuples.private interpolate +io.streams.string multiline make ; IN: db.sqlite TUPLE: sqlite-db < db path ; -M: sqlite-db make-db* ( path db -- db ) - swap >>path ; +: ( path -- sqlite-db ) + sqlite-db new-db + swap >>path ; M: sqlite-db db-open ( db -- db ) dup path>> sqlite-open >>handle ; M: sqlite-db db-close ( handle -- ) sqlite-close ; -M: sqlite-db dispose ( db -- ) db-dispose ; TUPLE: sqlite-statement < statement ; @@ -47,8 +48,8 @@ M: sqlite-result-set dispose ( result-set -- ) handle>> [ sqlite3_reset drop ] [ sqlite3_clear_bindings drop ] bi ; M: sqlite-statement low-level-bind ( statement -- ) - [ bind-params>> ] [ handle>> ] bi - [ swap [ key>> ] [ value>> ] [ type>> ] tri sqlite-bind-type ] curry each ; + [ handle>> ] [ bind-params>> ] bi + [ [ key>> ] [ value>> ] [ type>> ] tri sqlite-bind-type ] with each ; M: sqlite-statement bind-statement* ( statement -- ) sqlite-maybe-prepare @@ -77,16 +78,19 @@ M: generator-bind sqlite-bind-conversion ( tuple generate-bind -- array ) tuck [ generator-singleton>> eval-generator tuck ] [ slot-name>> ] bi rot set-slot-named - >r [ key>> ] [ type>> ] bi r> swap ; + [ [ key>> ] [ type>> ] bi ] dip + swap ; M: sqlite-statement bind-tuple ( tuple statement -- ) [ in-params>> [ sqlite-bind-conversion ] with map ] keep bind-statement ; +ERROR: sqlite-last-id-fail ; + : last-insert-id ( -- id ) db get handle>> sqlite3_last_insert_rowid - dup zero? [ "last-id failed" throw ] when ; + dup zero? [ sqlite-last-id-fail ] when ; M: sqlite-db insert-tuple-set-key ( tuple statement -- ) execute-statement last-insert-id swap set-primary-key ; @@ -99,7 +103,7 @@ M: sqlite-result-set row-column ( result-set n -- obj ) M: sqlite-result-set row-column-typed ( result-set n -- obj ) dup pick out-params>> nth type>> - >r >r handle>> r> r> sqlite-column-typed ; + [ handle>> ] 2dip sqlite-column-typed ; M: sqlite-result-set advance-row ( result-set -- ) dup handle>> sqlite-next >>has-more? drop ; @@ -117,7 +121,8 @@ M: sqlite-db create-sql-statement ( class -- statement ) dupd "create table " 0% 0% "(" 0% [ ", " 0% ] [ - dup column-name>> 0% + dup "sql-spec" set + dup column-name>> [ "table-id" set ] [ 0% ] bi " " 0% dup type>> lookup-create-type 0% modifiers 0% @@ -158,10 +163,10 @@ M: sqlite-db ( tuple -- statement ) ; M: sqlite-db bind# ( spec obj -- ) - >r - [ column-name>> ":" swap next-sql-counter 3append dup 0% ] - [ type>> ] bi - r> 1, ; + [ + [ column-name>> ":" swap next-sql-counter 3append dup 0% ] + [ type>> ] bi + ] dip 1, ; M: sqlite-db bind% ( spec -- ) dup 1, column-name>> ":" prepend 0% ; @@ -173,6 +178,7 @@ M: sqlite-db persistent-table ( -- assoc ) { +random-id+ { "integer" "integer" f } } { +foreign-id+ { "integer" "integer" "references" } } + { +on-update+ { f f "on update" } } { +on-delete+ { f f "on delete" } } { +restrict+ { f f "restrict" } } { +cascade+ { f f "cascade" } } @@ -203,9 +209,110 @@ M: sqlite-db persistent-table ( -- assoc ) { random-generator { f f f } } } ; +: insert-trigger ( -- string ) + [ + <" + CREATE TRIGGER fki_${table}_${foreign-table}_id + BEFORE INSERT ON ${table} + FOR EACH ROW BEGIN + SELECT RAISE(ROLLBACK, 'insert on table "${table}" violates foreign key constraint "fk_${foreign-table}_id"') + WHERE (SELECT ${foreign-table-id} FROM ${foreign-table} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL; + END; + "> interpolate + ] with-string-writer ; + +: insert-trigger-not-null ( -- string ) + [ + <" + CREATE TRIGGER fki_${table}_${foreign-table}_id + BEFORE INSERT ON ${table} + FOR EACH ROW BEGIN + SELECT RAISE(ROLLBACK, 'insert on table "${table}" violates foreign key constraint "fk_${foreign-table}_id"') + WHERE NEW.${foreign-table-id} IS NOT NULL + AND (SELECT ${foreign-table-id} FROM ${foreign-table} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL; + END; + "> interpolate + ] with-string-writer ; + +: update-trigger ( -- string ) + [ + <" + CREATE TRIGGER fku_${table}_${foreign-table}_id + BEFORE UPDATE ON ${table} + FOR EACH ROW BEGIN + SELECT RAISE(ROLLBACK, 'update on table "${table}" violates foreign key constraint "fk_${foreign-table}_id"') + WHERE (SELECT ${foreign-table-id} FROM ${foreign-table} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL; + END; + "> interpolate + ] with-string-writer ; + +: update-trigger-not-null ( -- string ) + [ + <" + CREATE TRIGGER fku_${table}_${foreign-table}_id + BEFORE UPDATE ON ${table} + FOR EACH ROW BEGIN + SELECT RAISE(ROLLBACK, 'update on table "${table}" violates foreign key constraint "fk_${foreign-table}_id"') + WHERE NEW.${foreign-table-id} IS NOT NULL + AND (SELECT ${foreign-table-id} FROM ${foreign-table} WHERE ${foreign-table-id} = NEW.${table-id}) IS NULL; + END; + "> interpolate + ] with-string-writer ; + +: delete-trigger-restrict ( -- string ) + [ + <" + CREATE TRIGGER fkd_${table}_${foreign-table}_id + BEFORE DELETE ON ${foreign-table} + FOR EACH ROW BEGIN + SELECT RAISE(ROLLBACK, 'delete on table "${foreign-table}" violates foreign key constraint "fk_${foreign-table}_id"') + WHERE (SELECT ${foreign-table-id} FROM ${foreign-table} WHERE ${foreign-table-id} = OLD.${foreign-table-id}) IS NOT NULL; + END; + "> interpolate + ] with-string-writer ; + +: delete-trigger-cascade ( -- string ) + [ + <" + CREATE TRIGGER fkd_${table}_${foreign-table}_id + BEFORE DELETE ON ${foreign-table} + FOR EACH ROW BEGIN + DELETE from ${table} WHERE ${table-id} = OLD.${foreign-table-id}; + END; + "> interpolate + ] with-string-writer ; + +: can-be-null? ( -- ? ) + "sql-spec" get modifiers>> [ +not-null+ = ] contains? not ; + +: delete-cascade? ( -- ? ) + "sql-spec" get modifiers>> { +on-delete+ +cascade+ } swap subseq? ; + +: sqlite-trigger, ( string -- ) + { } { } 3, ; + +: create-sqlite-triggers ( -- ) + can-be-null? [ + insert-trigger sqlite-trigger, + update-trigger sqlite-trigger, + ] [ + insert-trigger-not-null sqlite-trigger, + update-trigger-not-null sqlite-trigger, + ] if + delete-cascade? [ + delete-trigger-cascade sqlite-trigger, + ] [ + delete-trigger-restrict sqlite-trigger, + ] if ; + M: sqlite-db compound ( string seq -- new-string ) over { { "default" [ first number>string join-space ] } - { "references" [ >reference-string ] } + { "references" [ + [ >reference-string ] keep + first2 [ "foreign-table" set ] + [ "foreign-table-id" set ] bi* + create-sqlite-triggers + ] } [ 2drop ] } case ; diff --git a/basis/db/tuples/tuples-docs.factor b/basis/db/tuples/tuples-docs.factor index d7ee3a5ad2..51830ee610 100644 --- a/basis/db/tuples/tuples-docs.factor +++ b/basis/db/tuples/tuples-docs.factor @@ -1,9 +1,63 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: classes help.markup help.syntax io.streams.string kernel -quotations sequences strings multiline math db.types ; +quotations sequences strings multiline math db.types db ; IN: db.tuples +HELP: create-sql-statement +{ $values + { "class" class } + { "object" object } } +{ $description "Generates the SQL code for creating a table for a given class." } ; + +HELP: drop-sql-statement +{ $values + { "class" class } + { "object" object } } +{ $description "Generates the SQL code for dropping a table for a given class." } ; + +HELP: insert-tuple-set-key +{ $values + { "tuple" tuple } { "statement" statement } } +{ $description "Inserts a tuple and sets its primary key in one word. This is necessary for some databases." } ; + +HELP: +{ $values + { "query" query } + { "statement" statement } } +{ $description "A database-specific hook for generating the SQL for a count statement." } ; + +HELP: +{ $values + { "tuple" tuple } { "class" class } + { "object" object } } +{ $description "A database-specific hook for generating the SQL for an delete statement." } ; + +HELP: +{ $values + { "class" class } + { "object" object } } +{ $description "A database-specific hook for generating the SQL for an insert statement with a database-assigned primary key." } ; + +HELP: +{ $values + { "class" class } + { "object" object } } +{ $description "A database-specific hook for generating the SQL for an insert statement with a user-assigned primary key." } ; + +HELP: +{ $values + { "tuple" tuple } { "class" class } + { "tuple" tuple } } +{ $description "A database-specific hook for generating the SQL for a select statement." } ; + +HELP: +{ $values + { "class" class } + { "object" object } } +{ $description "A database-specific hook for generating the SQL for an update statement." } ; + + HELP: define-persistent { $values { "class" class } { "table" string } { "columns" "an array of slot specifiers" } } @@ -128,7 +182,21 @@ ARTICLE: "db-tuples-words" "High-level tuple/database words" { $subsection count-tuples } ; ARTICLE: "db-tuples-protocol" "Tuple database protocol" -; +"Creating a table:" +{ $subsection create-sql-statement } +"Dropping a table:" +{ $subsection drop-sql-statement } +"Inserting a tuple:" +{ $subsection } +{ $subsection } +"Updating a tuple:" +{ $subsection } +"Deleting tuples:" +{ $subsection } +"Selecting tuples:" +{ $subsection } +"Counting tuples:" +{ $subsection } ; ARTICLE: "db-tuples-tutorial" "Tuple database tutorial" "Let's make a tuple and store it in a database. To follow along, click on each code example and run it in the listener. If you forget to run an example, just start at the top and run them all again in order." $nl @@ -161,7 +229,7 @@ T{ book "Now we've created a book. Let's save it to the database." { $code <" USING: db db.sqlite fry io.files ; : with-book-tutorial ( quot -- ) - '[ "book-tutorial.db" temp-file sqlite-db _ with-db ] call ; + '[ "book-tutorial.db" temp-file _ with-db ] call ; [ book recreate-table @@ -190,7 +258,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 " { $link "db-custom-database-combinators" } " to open your database and run a " { $snippet "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/basis/db/tuples/tuples-tests.factor b/basis/db/tuples/tuples-tests.factor old mode 100755 new mode 100644 index 6a5e78aa4b..192986484e --- a/basis/db/tuples/tuples-tests.factor +++ b/basis/db/tuples/tuples-tests.factor @@ -7,16 +7,34 @@ db.postgresql accessors random math.bitwise math.ranges strings urls fry db.tuples.private ; IN: db.tuples.tests +: sqlite-db ( -- sqlite-db ) + "tuples-test.db" temp-file ; + : test-sqlite ( quot -- ) - [ ] swap '[ - "tuples-test.db" temp-file sqlite-db _ with-db - ] unit-test ; + '[ + [ ] [ + "tuples-test.db" temp-file _ with-db + ] unit-test + ] call ; inline + +: postgresql-db ( -- postgresql-db ) + + "localhost" >>host + "postgres" >>username + "thepasswordistrust" >>password + "factor-test" >>database ; : test-postgresql ( quot -- ) - [ ] swap '[ - { "localhost" "postgres" "foob" "factor-test" } - postgresql-db _ with-db - ] unit-test ; + '[ + [ ] [ postgresql-db _ with-db ] unit-test + ] call ; inline + +! These words leak resources, but are useful for interactivel testing +: sqlite-test-db ( -- ) + sqlite-db db-open db set ; + +: postgresql-test-db ( -- ) + postgresql-db db-open db set ; TUPLE: person the-id the-name the-number the-real ts date time blob factor-blob url ; @@ -176,26 +194,49 @@ SYMBOL: person4 T{ timestamp f 0 0 0 12 34 56 T{ duration f 0 0 0 0 0 0 } } f H{ { 1 2 } { 3 4 } { 5 "lol" } } URL" http://www.google.com/search?hl=en&q=trailer+park+boys&btnG=Google+Search" person4 set ; + TUPLE: paste n summary author channel mode contents timestamp annotations ; TUPLE: annotation n paste-id summary author mode contents ; -: db-assigned-paste-schema ( -- ) - paste "PASTE" - { - { "n" "ID" +db-assigned-id+ } - { "summary" "SUMMARY" TEXT } - { "author" "AUTHOR" TEXT } - { "channel" "CHANNEL" TEXT } - { "mode" "MODE" TEXT } - { "contents" "CONTENTS" TEXT } - { "timestamp" "DATE" TIMESTAMP } - { "annotations" { +has-many+ annotation } } - } define-persistent +paste "PASTE" +{ + { "n" "ID" +db-assigned-id+ } + { "summary" "SUMMARY" TEXT } + { "author" "AUTHOR" TEXT } + { "channel" "CHANNEL" TEXT } + { "mode" "MODE" TEXT } + { "contents" "CONTENTS" TEXT } + { "timestamp" "DATE" TIMESTAMP } + { "annotations" { +has-many+ annotation } } +} define-persistent +: annotation-schema-foreign-key ( -- ) annotation "ANNOTATION" { { "n" "ID" +db-assigned-id+ } - { "paste-id" "PASTE_ID" INTEGER { +foreign-id+ paste "n" } + { "paste-id" "PASTE_ID" INTEGER { +foreign-id+ paste "ID" } } + { "summary" "SUMMARY" TEXT } + { "author" "AUTHOR" TEXT } + { "mode" "MODE" TEXT } + { "contents" "CONTENTS" TEXT } + } define-persistent ; + +: annotation-schema-foreign-key-not-null ( -- ) + annotation "ANNOTATION" + { + { "n" "ID" +db-assigned-id+ } + { "paste-id" "PASTE_ID" INTEGER { +foreign-id+ paste "ID" } +not-null+ } + { "summary" "SUMMARY" TEXT } + { "author" "AUTHOR" TEXT } + { "mode" "MODE" TEXT } + { "contents" "CONTENTS" TEXT } + } define-persistent ; + +: annotation-schema-cascade ( -- ) + annotation "ANNOTATION" + { + { "n" "ID" +db-assigned-id+ } + { "paste-id" "PASTE_ID" INTEGER { +foreign-id+ paste "ID" } +on-delete+ +cascade+ } { "summary" "SUMMARY" TEXT } { "author" "AUTHOR" TEXT } @@ -203,8 +244,18 @@ TUPLE: annotation n paste-id summary author mode contents ; { "contents" "CONTENTS" TEXT } } define-persistent ; +: annotation-schema-restrict ( -- ) + annotation "ANNOTATION" + { + { "n" "ID" +db-assigned-id+ } + { "paste-id" "PASTE_ID" INTEGER { +foreign-id+ paste "ID" } } + { "summary" "SUMMARY" TEXT } + { "author" "AUTHOR" TEXT } + { "mode" "MODE" TEXT } + { "contents" "CONTENTS" TEXT } + } define-persistent ; + : test-paste-schema ( -- ) - [ ] [ db-assigned-paste-schema ] unit-test [ ] [ paste ensure-table ] unit-test [ ] [ annotation ensure-table ] unit-test [ ] [ annotation drop-table ] unit-test @@ -229,14 +280,38 @@ TUPLE: annotation n paste-id summary author mode contents ; "erg" >>author "annotation contents" >>contents insert-tuple - ] unit-test + ] unit-test ; - [ ] [ - ] unit-test - ; +: test-foreign-key ( -- ) + [ ] [ annotation-schema-foreign-key ] unit-test + test-paste-schema + [ paste new 1 >>n delete-tuples ] must-fail ; -[ test-paste-schema ] test-sqlite -[ test-paste-schema ] test-postgresql +: test-foreign-key-not-null ( -- ) + [ ] [ annotation-schema-foreign-key-not-null ] unit-test + test-paste-schema + [ paste new 1 >>n delete-tuples ] must-fail ; + +: test-cascade ( -- ) + [ ] [ annotation-schema-cascade ] unit-test + test-paste-schema + [ ] [ paste new 1 >>n delete-tuples ] unit-test + [ 0 ] [ paste new select-tuples length ] unit-test ; + +: test-restrict ( -- ) + [ ] [ annotation-schema-restrict ] unit-test + test-paste-schema + [ paste new 1 >>n delete-tuples ] must-fail ; + +[ test-foreign-key ] test-sqlite +[ test-foreign-key-not-null ] test-sqlite +[ test-cascade ] test-sqlite +[ test-restrict ] test-sqlite + +[ test-foreign-key ] test-postgresql +[ test-foreign-key-not-null ] test-postgresql +[ test-cascade ] test-postgresql +[ test-restrict ] test-postgresql : test-repeated-insert [ ] [ person ensure-table ] unit-test @@ -293,6 +368,14 @@ TUPLE: exam id name score ; [ ] [ T{ exam f f "Kenny" 60 } insert-tuple ] unit-test [ ] [ T{ exam f f "Cartman" 41 } insert-tuple ] unit-test + [ 4 ] + [ T{ exam { name IGNORE } { score IGNORE } } select-tuples length ] unit-test + + [ f ] + [ T{ exam { name IGNORE } { score IGNORE } } select-tuples first score>> ] unit-test + + [ T{ exam { name IGNORE } { score IGNORE } { id IGNORE } } select-tuples first score>> ] [ class>> "EXAM" = ] must-fail-with + [ { T{ exam f 3 "Kenny" 60 } @@ -389,7 +472,12 @@ TUPLE: exam id name score ; T{ exam } select-tuples ] unit-test - [ 4 ] [ T{ exam } count-tuples ] unit-test ; + [ 4 ] [ T{ exam } count-tuples ] unit-test + + [ ] [ T{ exam { score 10 } } insert-tuple ] unit-test + + [ 10 ] + [ T{ exam { name NULL } } select-tuples first score>> ] unit-test ; TUPLE: bignum-test id m n o ; : ( m n o -- obj ) @@ -574,10 +662,3 @@ compound-foo "COMPOUND_FOO" [ test-compound-primary-key ] test-sqlite [ test-compound-primary-key ] test-postgresql - -: sqlite-test-db ( -- ) - "tuples-test.db" temp-file sqlite-db make-db db-open db set ; - -: postgresql-test-db ( -- ) - { "localhost" "postgres" "foob" "factor-test" } postgresql-db - make-db db-open db set ; diff --git a/basis/db/tuples/tuples.factor b/basis/db/tuples/tuples.factor old mode 100755 new mode 100644 index 7f567697d2..7a5c9e41e6 --- a/basis/db/tuples/tuples.factor +++ b/basis/db/tuples/tuples.factor @@ -6,8 +6,6 @@ math.parser io prettyprint db.types continuations destructors mirrors sets db.types ; IN: db.tuples - db ( tuple class -- object ) HOOK: db ( tuple class -- tuple ) HOOK: db ( query -- statement ) HOOK: query>statement db ( query -- statement ) - HOOK: insert-tuple-set-key db ( tuple statement -- ) +string ; @@ -65,8 +65,8 @@ GENERIC: eval-generator ( singleton -- object ) : do-count ( exemplar-tuple statement -- tuples ) [ [ bind-tuple ] [ nip default-query ] 2bi ] with-disposal ; -PRIVATE> +PRIVATE> ! High level ERROR: no-slots-named class seq ; diff --git a/basis/db/types/types-docs.factor b/basis/db/types/types-docs.factor index 401bbbc4d7..f1a6ba6c6c 100644 --- a/basis/db/types/types-docs.factor +++ b/basis/db/types/types-docs.factor @@ -8,7 +8,7 @@ HELP: +autoincrement+ { $description "" } ; HELP: +db-assigned-id+ -{ $description "The database assigns a primary key to the object. The primary key is most likely a big integer, but is database-dependent." } ; +{ $description "The database assigns a primary key to the object. The primary key is most likely a big integer, but is database-dependent." } ; HELP: +default+ { $description "" } ; @@ -29,7 +29,7 @@ HELP: +primary-key+ { $description "" } ; HELP: +random-id+ -{ $description "Factor chooses a random number and tries to insert the tuple into the database with this number as its primary key. The default number of retries to find a unique random number is 10, though in practice it will almost certainly succeed on the first try." } ; +{ $description "Factor chooses a random number and tries to insert the tuple into the database with this number as its primary key. The default number of retries to find a unique random number is 10, though in practice it will almost certainly succeed on the first try." } ; HELP: +serial+ { $description "" } ; @@ -38,7 +38,7 @@ HELP: +unique+ { $description "" } ; HELP: +user-assigned-id+ -{ $description "The user is responsible for choosing a primary key for tuples inserted with this database type. Keys must be unique or else the database will throw an error. Usually it is better to use a " { $link +db-assigned-id+ } "." } ; +{ $description "The user is responsible for choosing a primary key for tuples inserted with this database type. Keys must be unique or else the database will throw an error. Usually it is better to use a " { $link +db-assigned-id+ } "." } ; HELP: { $description "" } ; @@ -53,7 +53,7 @@ HELP: BIG-INTEGER { $description "A 64-bit integer. Whether this number is signed or unsigned depends on the database backend." } ; HELP: BLOB -{ $description "A serialized Factor object. The database library automatically serializes the object for a SQL insert or update and deserializes it on a tuple query." } ; +{ $description "A byte array." } ; HELP: BOOLEAN { $description "Either true or false." } ; @@ -65,7 +65,7 @@ HELP: DATETIME { $description "A date and a time." } ; HELP: DOUBLE -{ $description "Corresponds to Factor's 64bit floating-point numbers." } ; +{ $description "Corresponds to Factor's 64-bit floating-point numbers." } ; HELP: FACTOR-BLOB { $description "A serialized Factor object." } ; @@ -77,30 +77,31 @@ HELP: NULL { $description "The SQL null type." } ; HELP: REAL -{ $description "" } ; +{ $description "A real number of unlimited precision. May not be supported on all databases." } ; HELP: SIGNED-BIG-INTEGER -{ $description "For portability, if a number is known to be 64bit and signed, then this datatype may be used. Some databases, like SQLite, cannot store arbitrary bignums as BIGINT types. If storing arbitrary bignums, use " { $link FACTOR-BLOB } "." } ; +{ $description "For portability, if a number is known to be 64bit and signed, then this datatype may be used. Some databases, like SQLite, cannot store arbitrary bignums as BIGINT types. If storing arbitrary bignums, use " { $link FACTOR-BLOB } "." } ; HELP: TEXT -{ $description "" } ; +{ $description "Stores a string that is longer than a " { $link VARCHAR } ". SQLite uses this type for strings; it does not handle " { $link VARCHAR } " strings." } ; HELP: TIME -{ $description "" } ; +{ $description "A timestamp without a date component." } ; HELP: TIMESTAMP { $description "A Factor timestamp." } ; HELP: UNSIGNED-BIG-INTEGER -{ $description "For portability, if a number is known to be 64bit, then this datatype may be used. Some databases, like SQLite, cannot store arbitrary bignums as BIGINT types. If storing arbitrary bignums, use " { $link FACTOR-BLOB } "." } ; +{ $description "For portability, if a number is known to be 64bit, then this datatype may be used. Some databases, like SQLite, cannot store arbitrary bignums as BIGINT types. If storing arbitrary bignums, use " { $link FACTOR-BLOB } "." } ; { INTEGER SIGNED-BIG-INTEGER UNSIGNED-BIG-INTEGER } related-words HELP: URL -{ $description "A Factor " { $link "urls" } " object." } ; +{ $description "A Factor " { $link "urls" } " object." } ; HELP: VARCHAR -{ $description "The SQL varchar type. This type can take an integer as an argument." } ; +{ $description "The SQL varchar type. This type can take an integer as an argument." } +{ $examples { $unchecked-example "{ VARCHAR 256 }" "" } } ; HELP: user-assigned-id-spec? { $values @@ -279,8 +280,9 @@ ARTICLE: "db.types" "Database types" { $subsection DATETIME } { $subsection TIME } { $subsection TIMESTAMP } -"Arbitrary Factor objects:" +"Factor byte-arrays:" { $subsection BLOB } +"Arbitrary Factor objects:" { $subsection FACTOR-BLOB } "Factor URLs:" { $subsection URL } ; diff --git a/basis/db/types/types.factor b/basis/db/types/types.factor old mode 100755 new mode 100644 index bc33792e52..6a889689ce --- a/basis/db/types/types.factor +++ b/basis/db/types/types.factor @@ -26,12 +26,20 @@ SINGLETONS: +db-assigned-id+ +user-assigned-id+ +random-id+ ; UNION: +primary-key+ +db-assigned-id+ +user-assigned-id+ +random-id+ ; SYMBOLS: +autoincrement+ +serial+ +unique+ +default+ +null+ +not-null+ -+foreign-id+ +has-many+ +on-delete+ +restrict+ +cascade+ +set-null+ -+set-default+ ; ++foreign-id+ +has-many+ +on-update+ +on-delete+ +restrict+ +cascade+ ++set-null+ +set-default+ ; + +SYMBOL: IGNORE + +: filter-ignores ( tuple specs -- specs' ) + [ [ nip IGNORE = ] assoc-filter keys ] dip + [ slot-name>> swap member? not ] with filter ; + +ERROR: no-slot ; : offset-of-slot ( string tuple -- n ) class superclasses [ "slots" word-prop ] map concat - slot-named offset>> ; + slot-named dup [ no-slot ] unless offset>> ; : get-slot-named ( name tuple -- value ) tuck offset-of-slot slot ; @@ -83,20 +91,21 @@ ERROR: not-persistent class ; : relation? ( spec -- ? ) [ +has-many+ = ] deep-find ; -SYMBOLS: INTEGER BIG-INTEGER SIGNED-BIG-INTEGER UNSIGNED-BIG-INTEGER +SINGLETONS: INTEGER BIG-INTEGER SIGNED-BIG-INTEGER UNSIGNED-BIG-INTEGER DOUBLE REAL BOOLEAN TEXT VARCHAR DATE TIME DATETIME TIMESTAMP BLOB FACTOR-BLOB NULL URL ; -: spec>tuple ( class spec -- tuple ) - 3 f pad-right - [ first3 ] keep 3 tail +: ( class slot-name column-name type modifiers -- sql-spec ) sql-spec new swap >>modifiers swap >>type swap >>column-name swap >>slot-name swap >>class - dup normalize-spec ; + dup normalize-spec ; + +: spec>tuple ( class spec -- tuple ) + 3 f pad-right [ first3 ] keep 3 tail ; : number>string* ( n/string -- string ) dup number? [ number>string ] when ; @@ -115,7 +124,6 @@ FACTOR-BLOB NULL URL ; ! PostgreSQL Types: ! http://developer.postgresql.org/pgdocs/postgres/datatype.html - : ?at ( obj assoc -- value/obj ? ) dupd at* [ [ nip ] [ drop ] if ] keep ; @@ -159,8 +167,11 @@ ERROR: no-sql-type type ; HOOK: bind% db ( spec -- ) HOOK: bind# db ( spec obj -- ) +ERROR: no-column column ; + : >reference-string ( string pair -- string ) first2 [ [ unparse join-space ] [ db-columns ] bi ] dip - swap [ slot-name>> = ] with find nip + swap [ column-name>> = ] with find nip + [ no-column ] unless* column-name>> paren append ; diff --git a/basis/debugger/debugger-docs.factor b/basis/debugger/debugger-docs.factor old mode 100755 new mode 100644 diff --git a/basis/debugger/debugger-tests.factor b/basis/debugger/debugger-tests.factor old mode 100755 new mode 100644 diff --git a/basis/debugger/debugger.factor b/basis/debugger/debugger.factor old mode 100755 new mode 100644 index 20e0703ce0..ec93a01c19 --- a/basis/debugger/debugger.factor +++ b/basis/debugger/debugger.factor @@ -22,6 +22,9 @@ M: tuple error-help class ; M: string error. print ; +: :error ( -- ) + error get error. ; + : :s ( -- ) error-continuation get data>> stack. ; diff --git a/basis/delegate/delegate-tests.factor b/basis/delegate/delegate-tests.factor old mode 100755 new mode 100644 diff --git a/basis/delegate/delegate.factor b/basis/delegate/delegate.factor old mode 100755 new mode 100644 diff --git a/basis/delegate/protocols/protocols.factor b/basis/delegate/protocols/protocols.factor old mode 100755 new mode 100644 diff --git a/basis/dlists/dlists-docs.factor b/basis/dlists/dlists-docs.factor old mode 100755 new mode 100644 diff --git a/basis/dlists/dlists-tests.factor b/basis/dlists/dlists-tests.factor old mode 100755 new mode 100644 diff --git a/basis/dlists/dlists.factor b/basis/dlists/dlists.factor old mode 100755 new mode 100644 diff --git a/basis/documents/documents.factor b/basis/documents/documents.factor old mode 100755 new mode 100644 diff --git a/basis/editors/editors.factor b/basis/editors/editors.factor old mode 100755 new mode 100644 diff --git a/basis/editors/editpadpro/editpadpro.factor b/basis/editors/editpadpro/editpadpro.factor old mode 100755 new mode 100644 diff --git a/basis/editors/editplus/editplus.factor b/basis/editors/editplus/editplus.factor old mode 100755 new mode 100644 diff --git a/basis/editors/emacs/emacs.factor b/basis/editors/emacs/emacs.factor old mode 100755 new mode 100644 diff --git a/basis/editors/emeditor/emeditor.factor b/basis/editors/emeditor/emeditor.factor old mode 100755 new mode 100644 diff --git a/basis/editors/gvim/gvim.factor b/basis/editors/gvim/gvim.factor old mode 100755 new mode 100644 diff --git a/basis/editors/gvim/windows/windows.factor b/basis/editors/gvim/windows/windows.factor old mode 100755 new mode 100644 diff --git a/basis/editors/jedit/jedit.factor b/basis/editors/jedit/jedit.factor old mode 100755 new mode 100644 diff --git a/basis/editors/macvim/macvim.factor b/basis/editors/macvim/macvim.factor old mode 100755 new mode 100644 diff --git a/basis/editors/notepadpp/notepadpp.factor b/basis/editors/notepadpp/notepadpp.factor old mode 100755 new mode 100644 diff --git a/basis/editors/scite/scite.factor b/basis/editors/scite/scite.factor old mode 100755 new mode 100644 diff --git a/basis/editors/ted-notepad/ted-notepad.factor b/basis/editors/ted-notepad/ted-notepad.factor old mode 100755 new mode 100644 diff --git a/basis/editors/textedit/textedit.factor b/basis/editors/textedit/textedit.factor old mode 100755 new mode 100644 diff --git a/basis/editors/textmate/textmate.factor b/basis/editors/textmate/textmate.factor old mode 100755 new mode 100644 diff --git a/basis/editors/ultraedit/ultraedit.factor b/basis/editors/ultraedit/ultraedit.factor old mode 100755 new mode 100644 diff --git a/basis/editors/vim/vim.factor b/basis/editors/vim/vim.factor old mode 100755 new mode 100644 diff --git a/basis/editors/wordpad/wordpad.factor b/basis/editors/wordpad/wordpad.factor old mode 100755 new mode 100644 diff --git a/basis/farkup/farkup.factor b/basis/farkup/farkup.factor index 959d53c904..21e3c05d04 100644 --- a/basis/farkup/farkup.factor +++ b/basis/farkup/farkup.factor @@ -1,14 +1,15 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays combinators html.elements io -io.streams.string kernel math memoize namespaces peg peg.ebnf +io.streams.string kernel math namespaces peg peg.ebnf sequences sequences.deep strings xml.entities -vectors splitting xmode.code2html urls ; +vectors splitting xmode.code2html urls.encoding ; IN: farkup SYMBOL: relative-link-prefix SYMBOL: disable-images? SYMBOL: link-no-follow? +SYMBOL: line-breaks? TUPLE: heading1 child ; TUPLE: heading2 child ; @@ -29,6 +30,7 @@ TUPLE: link href text ; TUPLE: image href text ; TUPLE: code mode string ; TUPLE: line ; +TUPLE: line-break ; : absolute-url? ( string -- ? ) { "http://" "https://" "ftp://" } [ head? ] with contains? ; @@ -109,7 +111,9 @@ table = ((table-row nl => [[ first ]] )+ table-row? | table-row) text = (!(nl | code | heading | inline-delimiter | table ).)+ => [[ >string ]] -paragraph-nl-item = nl (list | line)? +paragraph-nl-item = nl list + | nl line + | nl => [[ line-breaks? get [ drop line-break new ] when ]] paragraph-item = (table | code | text | inline-tag | inline-delimiter)+ paragraph = ((paragraph-item paragraph-nl-item)+ nl+ => [[ first ]] | (paragraph-item paragraph-nl-item)+ paragraph-item? @@ -209,6 +213,7 @@ M: link (write-farkup) [ href>> ] [ text>> ] bi write-link ; M: image (write-farkup) [ href>> ] [ text>> ] bi write-image-link ; M: code (write-farkup) [ string>> ] [ mode>> ] bi render-code ; M: line (write-farkup) drop
; +M: line-break (write-farkup) drop
nl ; M: table-row (write-farkup) ( obj -- ) child>> [ [ [ (write-farkup) ] "td" in-tag. ] each ] "tr" in-tag. ; M: table (write-farkup) [ child>> (write-farkup) ] "table" in-tag. ; diff --git a/basis/float-arrays/float-arrays-tests.factor b/basis/float-arrays/float-arrays-tests.factor old mode 100755 new mode 100644 diff --git a/basis/float-arrays/float-arrays.factor b/basis/float-arrays/float-arrays.factor old mode 100755 new mode 100644 diff --git a/basis/float-vectors/float-vectors-docs.factor b/basis/float-vectors/float-vectors-docs.factor old mode 100755 new mode 100644 diff --git a/basis/float-vectors/float-vectors-tests.factor b/basis/float-vectors/float-vectors-tests.factor old mode 100755 new mode 100644 diff --git a/basis/float-vectors/float-vectors.factor b/basis/float-vectors/float-vectors.factor old mode 100755 new mode 100644 diff --git a/basis/freetype/freetype.factor b/basis/freetype/freetype.factor old mode 100755 new mode 100644 diff --git a/basis/fry/fry-docs.factor b/basis/fry/fry-docs.factor old mode 100755 new mode 100644 diff --git a/basis/fry/fry-tests.factor b/basis/fry/fry-tests.factor old mode 100755 new mode 100644 diff --git a/basis/fry/fry.factor b/basis/fry/fry.factor old mode 100755 new mode 100644 diff --git a/basis/furnace/actions/actions-tests.factor b/basis/furnace/actions/actions-tests.factor old mode 100755 new mode 100644 diff --git a/basis/furnace/actions/actions.factor b/basis/furnace/actions/actions.factor old mode 100755 new mode 100644 index 2a63489299..7505b3c612 --- a/basis/furnace/actions/actions.factor +++ b/basis/furnace/actions/actions.factor @@ -79,7 +79,7 @@ TUPLE: action rest authorize init display validate submit ; : revalidate-url ( -- url/f ) revalidate-url-key param - dup [ >url [ same-host? ] keep and ] when ; + dup [ >url ensure-port [ same-host? ] keep and ] when ; : validation-failed ( -- * ) post-request? revalidate-url and [ diff --git a/basis/furnace/alloy/alloy.factor b/basis/furnace/alloy/alloy.factor index decee690a3..128ec448b7 100644 --- a/basis/furnace/alloy/alloy.factor +++ b/basis/furnace/alloy/alloy.factor @@ -17,19 +17,17 @@ IN: furnace.alloy state-classes ensure-tables user ensure-table ; -: ( responder db params -- responder' ) - [ [ init-furnace-tables ] with-db ] +: ( responder db -- responder' ) + [ [ init-furnace-tables ] with-db ] keep [ - [ - - - - ] 2dip - - - ] 2bi ; + + + + ] dip + + ; -: start-expiring ( db params -- ) +: start-expiring ( db -- ) '[ - _ _ [ state-classes [ expire-state ] each ] with-db + _ [ state-classes [ expire-state ] each ] with-db ] 5 minutes every drop ; diff --git a/basis/furnace/auth/auth.factor b/basis/furnace/auth/auth.factor old mode 100755 new mode 100644 diff --git a/basis/furnace/auth/basic/basic.factor b/basis/furnace/auth/basic/basic.factor old mode 100755 new mode 100644 diff --git a/basis/furnace/auth/login/login-tests.factor b/basis/furnace/auth/login/login-tests.factor old mode 100755 new mode 100644 diff --git a/basis/furnace/auth/login/login.factor b/basis/furnace/auth/login/login.factor old mode 100755 new mode 100644 diff --git a/basis/furnace/auth/providers/assoc/assoc-tests.factor b/basis/furnace/auth/providers/assoc/assoc-tests.factor old mode 100755 new mode 100644 diff --git a/basis/furnace/auth/providers/assoc/assoc.factor b/basis/furnace/auth/providers/assoc/assoc.factor old mode 100755 new mode 100644 diff --git a/basis/furnace/auth/providers/db/db-tests.factor b/basis/furnace/auth/providers/db/db-tests.factor old mode 100755 new mode 100644 index fac5c23e4a..3bcd82a15d --- a/basis/furnace/auth/providers/db/db-tests.factor +++ b/basis/furnace/auth/providers/db/db-tests.factor @@ -11,7 +11,7 @@ io.files accessors kernel ; [ "auth-test.db" temp-file delete-file ] ignore-errors -"auth-test.db" temp-file sqlite-db [ +"auth-test.db" temp-file [ user ensure-table diff --git a/basis/furnace/auth/providers/db/db.factor b/basis/furnace/auth/providers/db/db.factor old mode 100755 new mode 100644 diff --git a/basis/furnace/auth/providers/null/null.factor b/basis/furnace/auth/providers/null/null.factor old mode 100755 new mode 100644 diff --git a/basis/furnace/auth/providers/providers.factor b/basis/furnace/auth/providers/providers.factor old mode 100755 new mode 100644 diff --git a/basis/furnace/boilerplate/boilerplate.factor b/basis/furnace/boilerplate/boilerplate.factor index 59f71b1524..946372e1f8 100644 --- a/basis/furnace/boilerplate/boilerplate.factor +++ b/basis/furnace/boilerplate/boilerplate.factor @@ -17,16 +17,13 @@ TUPLE: boilerplate < filter-responder template init ; [ ] >>init ; : wrap-boilerplate? ( response -- ? ) - { - [ code>> { [ 200 = ] [ 400 499 between? ] } 1|| ] - [ content-type>> "text/html" = ] - } 1&& ; + { [ code>> 200 = ] [ content-type>> "text/html" = ] } 1&& ; M:: boilerplate call-responder* ( path responder -- ) begin-form path responder call-next-method responder init>> call - dup content-type>> "text/html" = [ + dup wrap-boilerplate? [ clone [| body | [ body diff --git a/basis/furnace/chloe-tags/chloe-tags.factor b/basis/furnace/chloe-tags/chloe-tags.factor index 0cd1d6bd38..697c885a01 100644 --- a/basis/furnace/chloe-tags/chloe-tags.factor +++ b/basis/furnace/chloe-tags/chloe-tags.factor @@ -59,8 +59,12 @@ CHLOE: write-atom drop [ write-atom-feeds ] [code] ; attrs>> '[ [ [ _ ] dip link-attr ] each-responder ] [code] ; : a-start-tag ( tag -- ) - [ compile-link-attrs ] [ compile-a-url ] bi - [ ] [code] ; + [ ] [code] ; : a-end-tag ( tag -- ) drop [ ] [code] ; @@ -70,6 +74,9 @@ CHLOE: a [ a-start-tag ] [ compile-children ] [ a-end-tag ] tri ] compile-with-scope ; +CHLOE: base + compile-a-url [ ] [code] ; + : compile-hidden-form-fields ( for -- ) '[
diff --git a/basis/furnace/db/db.factor b/basis/furnace/db/db.factor old mode 100755 new mode 100644 index b4a4386015..ed18e42a4f --- a/basis/furnace/db/db.factor +++ b/basis/furnace/db/db.factor @@ -6,7 +6,7 @@ IN: furnace.db TUPLE: db-persistence < filter-responder pool ; -: ( responder params db -- responder' ) +: ( responder db -- responder' ) db-persistence boa ; M: db-persistence call-responder* diff --git a/basis/furnace/sessions/sessions-tests.factor b/basis/furnace/sessions/sessions-tests.factor old mode 100755 new mode 100644 index ff089a92b2..6bb3c1cd69 --- a/basis/furnace/sessions/sessions-tests.factor +++ b/basis/furnace/sessions/sessions-tests.factor @@ -48,9 +48,9 @@ M: foo call-responder* [ [ ] "text/plain" exit-with ] >>display ; -[ "auth-test.db" temp-file sqlite-db delete-file ] ignore-errors +[ "auth-test.db" temp-file delete-file ] ignore-errors -"auth-test.db" temp-file sqlite-db [ +"auth-test.db" temp-file [ init-request session ensure-table diff --git a/basis/furnace/sessions/sessions.factor b/basis/furnace/sessions/sessions.factor old mode 100755 new mode 100644 diff --git a/basis/generalizations/generalizations-docs.factor b/basis/generalizations/generalizations-docs.factor old mode 100755 new mode 100644 diff --git a/basis/generalizations/generalizations-tests.factor b/basis/generalizations/generalizations-tests.factor old mode 100755 new mode 100644 diff --git a/basis/generalizations/generalizations.factor b/basis/generalizations/generalizations.factor old mode 100755 new mode 100644 diff --git a/basis/globs/globs.factor b/basis/globs/globs.factor old mode 100755 new mode 100644 diff --git a/basis/hash2/hash2-tests.factor b/basis/hash2/hash2-tests.factor old mode 100755 new mode 100644 diff --git a/basis/heaps/authors.txt b/basis/heaps/authors.txt index 1229a590fa..d0c12d9aa4 100755 --- a/basis/heaps/authors.txt +++ b/basis/heaps/authors.txt @@ -1,2 +1,3 @@ Doug Coleman Ryan Murphy +Slava Pestov diff --git a/basis/heaps/heaps-docs.factor b/basis/heaps/heaps-docs.factor old mode 100755 new mode 100644 index d1003ac2f8..3c1c61faec --- a/basis/heaps/heaps-docs.factor +++ b/basis/heaps/heaps-docs.factor @@ -1,5 +1,5 @@ USING: heaps.private help.markup help.syntax kernel math assocs -math.order ; +math.order quotations ; IN: heaps ARTICLE: "heaps" "Heaps" @@ -28,7 +28,9 @@ $nl "Removal:" { $subsection heap-pop* } { $subsection heap-pop } -{ $subsection heap-delete } ; +{ $subsection heap-delete } +"Processing heaps:" +{ $subsection slurp-heap } ; ABOUT: "heaps" @@ -82,3 +84,8 @@ HELP: heap-delete { $description "Remove the specified entry from the heap." } { $errors "Throws an error if the entry is from another heap or if it has already been deleted." } { $side-effects "heap" } ; + +HELP: slurp-heap +{ $values + { "heap" "a heap" } { "quot" quotation } } +{ $description "Removes values from a heap and processes them with the quotation until the heap is empty." } ; diff --git a/basis/heaps/heaps-tests.factor b/basis/heaps/heaps-tests.factor old mode 100755 new mode 100644 index 13b6a97654..e28eb3007a --- a/basis/heaps/heaps-tests.factor +++ b/basis/heaps/heaps-tests.factor @@ -1,6 +1,5 @@ ! Copyright 2007, 2008 Ryan Murphy, Slava Pestov ! See http://factorcode.org/license.txt for BSD license. - USING: arrays kernel math namespaces tools.test heaps heaps.private math.parser random assocs sequences sorting accessors math.order ; @@ -54,9 +53,6 @@ IN: heaps.tests [ t ] swap [ 2^ test-entry-indices ] curry unit-test ] each -: delete-random ( seq -- elt ) - dup length random dup pick nth >r swap delete-nth r> ; - : sort-entries ( entries -- entries' ) [ [ key>> ] compare ] sort ; diff --git a/basis/heaps/heaps.factor b/basis/heaps/heaps.factor old mode 100755 new mode 100644 diff --git a/basis/help/cookbook/cookbook.factor b/basis/help/cookbook/cookbook.factor old mode 100755 new mode 100644 diff --git a/basis/help/crossref/crossref-tests.factor b/basis/help/crossref/crossref-tests.factor old mode 100755 new mode 100644 diff --git a/basis/help/definitions/definitions-tests.factor b/basis/help/definitions/definitions-tests.factor old mode 100755 new mode 100644 diff --git a/basis/help/definitions/definitions.factor b/basis/help/definitions/definitions.factor old mode 100755 new mode 100644 diff --git a/basis/help/handbook/handbook.factor b/basis/help/handbook/handbook.factor old mode 100755 new mode 100644 index 51750d772f..c1505705da --- a/basis/help/handbook/handbook.factor +++ b/basis/help/handbook/handbook.factor @@ -90,7 +90,7 @@ ARTICLE: "numbers" "Numbers" { $subsection "math-constants" } { $subsection "math-functions" } { $subsection "number-strings" } -{ $subsection "random-numbers" } +{ $subsection "random" } "Number implementations:" { $subsection "integers" } { $subsection "rationals" } diff --git a/basis/help/help-docs.factor b/basis/help/help-docs.factor old mode 100755 new mode 100644 diff --git a/basis/help/help.factor b/basis/help/help.factor old mode 100755 new mode 100644 diff --git a/basis/help/html/html-tests.factor b/basis/help/html/html-tests.factor new file mode 100644 index 0000000000..475b2114b3 --- /dev/null +++ b/basis/help/html/html-tests.factor @@ -0,0 +1,5 @@ +IN: help.html.tests +USING: html.streams classes.predicate help.topics help.markup +io.streams.string accessors prettyprint kernel tools.test ; + +[ ] [ [ [ \ predicate-instance? def>> . ] with-html-writer ] with-string-writer drop ] unit-test diff --git a/basis/help/html/html.factor b/basis/help/html/html.factor index b1bf8958a8..386dca9576 100644 --- a/basis/help/html/html.factor +++ b/basis/help/html/html.factor @@ -1,5 +1,127 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. +USING: io.encodings.utf8 io.encodings.ascii io.encodings.binary +io.files html.streams html.elements html.components help kernel +assocs sequences make words accessors arrays help.topics vocabs +tools.vocabs tools.vocabs.browser namespaces prettyprint io +vocabs.loader serialize fry memoize unicode.case math.order +sorting ; IN: help.html +: escape-char ( ch -- ) + dup H{ + { CHAR: " "__quote__" } + { CHAR: * "__star__" } + { CHAR: : "__colon__" } + { CHAR: < "__lt__" } + { CHAR: > "__gt__" } + { CHAR: ? "__question__" } + { CHAR: \\ "__backslash__" } + { CHAR: | "__pipe__" } + { CHAR: _ "__underscore__" } + { CHAR: / "__slash__" } + { CHAR: \\ "__backslash__" } + { CHAR: , "__comma__" } + } at [ % ] [ , ] ?if ; +: escape-filename ( string -- filename ) + [ [ escape-char ] each ] "" make ; + +GENERIC: topic>filename* ( topic -- name prefix ) + +M: word topic>filename* + dup vocabulary>> [ + [ name>> ] [ vocabulary>> ] bi 2array "word" + ] [ drop f f ] if ; + +M: link topic>filename* name>> dup [ "article" ] [ topic>filename* ] if ; +M: word-link topic>filename* name>> topic>filename* ; +M: vocab-spec topic>filename* vocab-name "vocab" ; +M: vocab-tag topic>filename* name>> "tag" ; +M: vocab-author topic>filename* name>> "author" ; +M: f topic>filename* drop \ f topic>filename* ; + +: topic>filename ( topic -- filename ) + topic>filename* dup [ + [ + % "-" % + dup array? + [ [ escape-filename ] map "," join ] + [ escape-filename ] + if % ".html" % + ] "" make + ] [ 2drop f ] if ; + +M: topic browser-link-href topic>filename ; + +: help-stylesheet ( -- ) + "resource:basis/help/html/stylesheet.css" ascii file-contents write ; + +: help>html ( topic -- ) + dup topic>filename utf8 [ + dup article-title + [ ] + [ [ help ] with-html-writer ] simple-page + ] with-file-writer ; + +: all-vocabs-really ( -- seq ) + #! Hack. + all-vocabs values concat + vocabs [ find-vocab-root not ] filter [ vocab ] map append ; + +: all-topics ( -- topics ) + [ + articles get keys [ >link ] map % + all-words [ >link ] map % + all-authors [ ] map % + all-tags [ ] map % + all-vocabs-really % + ] { } make ; + +: serialize-index ( index file -- ) + [ [ [ topic>filename ] dip ] { } assoc-map-as object>bytes ] dip + binary set-file-contents ; + +: generate-indices ( -- ) + articles get keys [ [ >link ] [ article-title ] bi ] { } map>assoc "articles.idx" serialize-index + all-words [ dup name>> ] { } map>assoc "words.idx" serialize-index + all-vocabs-really [ dup vocab-name ] { } map>assoc "vocabs.idx" serialize-index ; + +: generate-help-files ( -- ) + all-topics [ help>html ] each ; + +: generate-help ( -- ) + { "resource:core" "resource:basis" "resource:extra" } vocab-roots [ + load-everything + + "/tmp/docs/" make-directory + + "/tmp/docs/" [ + generate-indices + generate-help-files + ] with-directory + ] with-variable ; + +MEMO: load-index ( name -- index ) + binary file-contents bytes>object ; + +TUPLE: result title href ; + +M: result link-title title>> ; + +M: result link-href href>> ; + +: offline-apropos ( string index -- results ) + load-index swap >lower + '[ [ drop _ ] dip >lower subseq? ] assoc-filter + [ swap result boa ] { } assoc>map + [ [ title>> ] compare ] sort ; + +: article-apropos ( string -- results ) + "articles.idx" offline-apropos ; + +: word-apropos ( string -- results ) + "words.idx" offline-apropos ; + +: vocab-apropos ( string -- results ) + "vocabs.idx" offline-apropos ; diff --git a/basis/help/html/stylesheet.css b/basis/help/html/stylesheet.css new file mode 100644 index 0000000000..ff657d634e --- /dev/null +++ b/basis/help/html/stylesheet.css @@ -0,0 +1,4 @@ +a:link { text-decoration: none; color: #00004c; } +a:visited { text-decoration: none; color: #00004c; } +a:active { text-decoration: none; color: #00004c; } +a:hover { text-decoration: underline; color: #00004c; } diff --git a/basis/help/lint/lint.factor b/basis/help/lint/lint.factor old mode 100755 new mode 100644 diff --git a/basis/help/markup/markup.factor b/basis/help/markup/markup.factor old mode 100755 new mode 100644 index b5e074b598..1eae56cfcc --- a/basis/help/markup/markup.factor +++ b/basis/help/markup/markup.factor @@ -71,7 +71,10 @@ ALIAS: $slot $snippet [ strong-style get print-element* ] ($span) ; : $url ( children -- ) - [ url-style get print-element* ] ($span) ; + [ + dup first href associate url-style get assoc-union + print-element* + ] ($span) ; : $nl ( children -- ) nl nl drop ; diff --git a/basis/help/stylesheet/stylesheet.factor b/basis/help/stylesheet/stylesheet.factor old mode 100755 new mode 100644 diff --git a/basis/help/syntax/syntax-tests.factor b/basis/help/syntax/syntax-tests.factor old mode 100755 new mode 100644 diff --git a/basis/help/syntax/syntax.factor b/basis/help/syntax/syntax.factor old mode 100755 new mode 100644 diff --git a/basis/help/topics/topics.factor b/basis/help/topics/topics.factor old mode 100755 new mode 100644 diff --git a/basis/help/tutorial/tutorial.factor b/basis/help/tutorial/tutorial.factor old mode 100755 new mode 100644 diff --git a/basis/html/components/components-docs.factor b/basis/html/components/components-docs.factor index d7690b30e2..d131cc3e03 100644 --- a/basis/html/components/components-docs.factor +++ b/basis/html/components/components-docs.factor @@ -29,7 +29,7 @@ HELP: textarea { $class-description "Text area components display a multi-line editor for a string value. The " { $slot "rows" } " and " { $slot "cols" } " properties determine the size of the text area." } ; HELP: link -{ $description "Link components render a link to an object stored at a value, with the link title and URL determined by the " { $link link-title } " and " { $link link-href } " generic words." } ; +{ $description "Link components render a link to an object stored at a value, with the link title and URL determined by the " { $link link-title } " and " { $link link-href } " generic words. The optional " { $slot "target" } " slot is a target frame to open the link in." } ; HELP: link-title { $values { "obj" object } { "string" string } } diff --git a/basis/html/components/components-tests.factor b/basis/html/components/components-tests.factor index 56c7118ab9..b4247e6e30 100644 --- a/basis/html/components/components-tests.factor +++ b/basis/html/components/components-tests.factor @@ -134,7 +134,7 @@ M: link-test link-href drop "http://www.apple.com/foo&bar" ; [ ] [ link-test "link" set-value ] unit-test [ "<Link Title>" ] [ - [ "link" link render ] with-string-writer + [ "link" link new render ] with-string-writer ] unit-test [ ] [ @@ -163,7 +163,7 @@ M: link-test link-href drop "http://www.apple.com/foo&bar" ; [ t ] [ [ "object" inspector render ] with-string-writer - [ "object" value [ describe ] with-html-stream ] with-string-writer + [ "object" value [ describe ] with-html-writer ] with-string-writer = ] unit-test diff --git a/basis/html/components/components.factor b/basis/html/components/components.factor index 18e1aad9eb..6f35ba5d97 100644 --- a/basis/html/components/components.factor +++ b/basis/html/components/components.factor @@ -83,7 +83,7 @@ TUPLE: choice size multiple choices ; choice new ; : render-option ( text selected? -- ) - ; @@ -126,11 +126,11 @@ M: string link-href ; M: url link-title ; M: url link-href ; -SINGLETON: link +TUPLE: link target ; M: link render* - 2drop - + nip + > [ =target ] when* dup link-href =href a> link-title present escape-string write ; @@ -169,7 +169,7 @@ M: farkup render* SINGLETON: inspector M: inspector render* - 2drop [ describe ] with-html-stream ; + 2drop [ describe ] with-html-writer ; ! Diff component SINGLETON: comparison diff --git a/basis/html/elements/elements.factor b/basis/html/elements/elements.factor index c7281df54d..0ee6955e29 100644 --- a/basis/html/elements/elements.factor +++ b/basis/html/elements/elements.factor @@ -113,6 +113,7 @@ SYMBOL: html "hr" "link" "img" + "base" ] [ define-open-html-word ] each ! Define some attributes @@ -124,7 +125,7 @@ SYMBOL: html "width" "selected" "onsubmit" "xmlns" "lang" "xml:lang" "media" "title" "multiple" "checked" "summary" "cellspacing" "align" "scope" "abbr" - "nofollow" "alt" + "nofollow" "alt" "target" ] [ define-attribute-word ] each >> @@ -133,12 +134,16 @@ SYMBOL: html "" write-html "" write-html ; -: simple-page ( title quot -- ) +: simple-page ( title head-quot body-quot -- ) #! Call the quotation, with all output going to the #! body of an html page with the given title. + spin xhtml-preamble - swap write + + write + call + call ; inline diff --git a/basis/html/streams/streams-docs.factor b/basis/html/streams/streams-docs.factor index d7638a2817..f05eeb30fc 100644 --- a/basis/html/streams/streams-docs.factor +++ b/basis/html/streams/streams-docs.factor @@ -13,13 +13,13 @@ HELP: { $values { "stream" "an output stream" } { "html-stream" html-stream } } { $description "Creates a new formatted output stream which emits HTML markup on " { $snippet "stream" } "." } ; -HELP: with-html-stream +HELP: with-html-writer { $values { "quot" quotation } } { $description "Calls the quotation in a new dynamic scope with " { $link output-stream } " rebound to an " { $link html-stream } " wrapping the current " { $link output-stream } "." } { $examples { $example "USING: io io.styles html.streams ;" - "[ \"Hello\" { { font-style bold } } format nl ] with-html-stream" + "[ \"Hello\" { { font-style bold } } format nl ] with-html-writer" "Hello
" } } ; @@ -28,6 +28,6 @@ ARTICLE: "html.streams" "HTML streams" "The " { $vocab-link "html.streams" } " vocabulary provides a stream which implements " { $link "styles" } " by writing HTML markup to the wrapped stream." { $subsection html-stream } { $subsection } -{ $subsection with-html-stream } ; +{ $subsection with-html-writer } ; ABOUT: "html.streams" diff --git a/basis/html/streams/streams-tests.factor b/basis/html/streams/streams-tests.factor index b5707c158f..94229b3aea 100644 --- a/basis/html/streams/streams-tests.factor +++ b/basis/html/streams/streams-tests.factor @@ -4,7 +4,7 @@ xml.writer sbufs sequences inspector colors ; IN: html.streams.tests : make-html-string - [ with-html-stream ] with-string-writer ; inline + [ with-html-writer ] with-string-writer ; inline [ [ ] make-html-string ] must-infer @@ -71,4 +71,4 @@ M: funky browser-link-href [ H{ } [ ] with-nesting nl ] make-html-string ] unit-test -[ ] [ [ { 1 2 3 } describe ] with-html-stream ] unit-test +[ ] [ [ { 1 2 3 } describe ] with-html-writer ] unit-test diff --git a/basis/html/streams/streams.factor b/basis/html/streams/streams.factor old mode 100755 new mode 100644 index 7d0fe9b17c..fa81a69bb4 --- a/basis/html/streams/streams.factor +++ b/basis/html/streams/streams.factor @@ -4,7 +4,7 @@ USING: combinators generic assocs help http io io.styles io.files continuations io.streams.string kernel math math.order math.parser namespaces make quotations assocs sequences strings words html.elements xml.entities sbufs continuations destructors -accessors arrays ; +accessors arrays urls.encoding ; IN: html.streams GENERIC: browser-link-href ( presented -- href ) @@ -22,7 +22,7 @@ TUPLE: html-stream stream last-div ; : not-a-div ( stream -- stream ) f >>last-div ; inline -: a-div ( stream -- straem ) +: a-div ( stream -- stream ) t >>last-div ; inline : ( stream -- html-stream ) @@ -44,10 +44,15 @@ TUPLE: html-sub-stream < html-stream style parent ; : object-link-tag ( style quot -- ) presented pick at [ browser-link-href [ - call + call ] [ call ] if* ] [ call ] if* ; inline +: href-link-tag ( style quot -- ) + href pick at [ + call + ] [ call ] if* ; inline + : hex-color, ( color -- ) [ red>> ] [ green>> ] [ blue>> ] tri [ 255 * >fixnum >hex 2 CHAR: 0 pad-left % ] tri@ ; @@ -95,7 +100,7 @@ TUPLE: html-sub-stream < html-stream style parent ; : format-html-span ( string style stream -- ) stream>> [ - [ [ drop write ] span-tag ] object-link-tag + [ [ [ drop write ] span-tag ] href-link-tag ] object-link-tag ] with-output-stream* ; TUPLE: html-span-stream < html-sub-stream ; @@ -192,5 +197,5 @@ M: html-stream stream-write-table M: html-stream dispose stream>> dispose ; -: with-html-stream ( quot -- ) +: with-html-writer ( quot -- ) output-stream get swap with-output-stream* ; inline diff --git a/basis/html/templates/chloe/chloe-docs.factor b/basis/html/templates/chloe/chloe-docs.factor index b97a4c5c35..f390aad238 100644 --- a/basis/html/templates/chloe/chloe-docs.factor +++ b/basis/html/templates/chloe/chloe-docs.factor @@ -27,13 +27,9 @@ HELP: CHLOE: { $values { "name" "the tag name" } { "definition" "a quotation with stack effect " { $snippet "( tag -- )" } } } { $description "Defines compilation semantics for the Chloe tag named " { $snippet "tag" } ". The definition body receives a " { $link tag } " on the stack." } ; -HELP: CHLOE-SINGLETON: -{ $syntax "CHLOE-SINGLETON: name" } -{ $description "Defines a Chloe tag named " { $snippet "name" } " rendering an HTML component with singleton class word " { $snippet "name" } ". See " { $link "html.components" } "." } ; - -HELP: CHLOE-TUPLE: -{ $syntax "CHLOE-TUPLE: name" } -{ $description "Defines a Chloe tag named " { $snippet "name" } " rendering an HTML component with tuple class word " { $snippet "name" } ". See " { $link "html.components" } "." } ; +HELP: COMPONENT: +{ $syntax "COMPONENT: name" } +{ $description "Defines a Chloe tag named " { $snippet "name" } " rendering the HTML component with class word " { $snippet "name" } ". See " { $link "html.components" } "." } ; HELP: reset-cache { $description "Resets the compiled template cache. Chloe automatically recompiles templates when their file changes on disk, however other when redefining Chloe tags or words which they call, the cache may have to be reset manually for the changes to take effect." } ; @@ -135,6 +131,7 @@ ARTICLE: "html.templates.chloe.tags.form" "Chloe link and form tags" "s" } } } + { { $snippet "t:base" } { "Outputs an HTML " { $snippet "" } " tag. The attributes are interpreted in the same manner as the attributes of " { $snippet "t:a" } "." } } { { $snippet "t:form" } { "Renders a form; extends the standard XHTML " { $snippet "form" } " tag by providing some integration with other web framework features, for example by adding hidden fields for authentication credentials and session management allowing those features to work with form submission transparently. The following attributes are supported:" { $list @@ -264,14 +261,13 @@ ARTICLE: "html.templates.chloe.extend.components.example" "An example of a custo "Now we define a method on the " { $link render* } " generic word which renders the image using " { $vocab-link "html.elements" } ":" { $code "M: image render* 2drop ;" } "Finally, we can define a Chloe component:" -{ $code "CHLOE-SINGLETON: image" } +{ $code "COMPONENT: image" } "We can use it as follows, assuming the current form has a value named " { $snippet "image" } ":" { $code "" } ; ARTICLE: "html.templates.chloe.extend.components" "Extending Chloe with custom components" "Custom HTML components implementing the " { $link render* } " word can be wired up with Chloe using the following syntax from " { $vocab-link "html.templates.chloe.components" } ":" -{ $subsection POSTPONE: CHLOE-SINGLETON: } -{ $subsection POSTPONE: CHLOE-TUPLE: } +{ $subsection POSTPONE: COMPONENT: } { $subsection "html.templates.chloe.extend.components.example" } ; ARTICLE: "html.templates.chloe" "Chloe templates" diff --git a/basis/html/templates/chloe/chloe.factor b/basis/html/templates/chloe/chloe.factor index e83040b00d..1bc4684d5c 100644 --- a/basis/html/templates/chloe/chloe.factor +++ b/basis/html/templates/chloe/chloe.factor @@ -78,20 +78,19 @@ CHLOE: call-next-template CHLOE: if dup if>quot [ swap when ] append process-children ; -CHLOE-SINGLETON: label -CHLOE-SINGLETON: link -CHLOE-SINGLETON: inspector -CHLOE-SINGLETON: comparison -CHLOE-SINGLETON: html -CHLOE-SINGLETON: hidden - -CHLOE-TUPLE: farkup -CHLOE-TUPLE: field -CHLOE-TUPLE: textarea -CHLOE-TUPLE: password -CHLOE-TUPLE: choice -CHLOE-TUPLE: checkbox -CHLOE-TUPLE: code +COMPONENT: label +COMPONENT: link +COMPONENT: inspector +COMPONENT: comparison +COMPONENT: html +COMPONENT: hidden +COMPONENT: farkup +COMPONENT: field +COMPONENT: textarea +COMPONENT: password +COMPONENT: choice +COMPONENT: checkbox +COMPONENT: code SYMBOL: template-cache diff --git a/basis/html/templates/chloe/components/components.factor b/basis/html/templates/chloe/components/components.factor index 77d7c937be..3041120d43 100644 --- a/basis/html/templates/chloe/components/components.factor +++ b/basis/html/templates/chloe/components/components.factor @@ -1,35 +1,31 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors assocs sequences kernel parser fry quotations -classes.tuple +classes.tuple classes.singleton html.components html.templates.chloe.compiler html.templates.chloe.syntax ; IN: html.templates.chloe.components + +GENERIC: component-tag ( tag class -- ) -: singleton-component-tag ( tag class -- ) +M: singleton-class component-tag ( tag class -- ) [ "name" required-attr compile-attr ] [ literalize [ render ] [code-with] ] bi* ; -: CHLOE-SINGLETON: - scan-word - [ name>> ] [ '[ _ singleton-component-tag ] ] bi - define-chloe-tag ; - parsing - : compile-component-attrs ( tag class -- ) [ attrs>> [ drop main>> "name" = not ] assoc-filter ] dip [ all-slots swap '[ name>> _ at compile-attr ] each ] [ [ boa ] [code-with] ] bi ; -: tuple-component-tag ( tag class -- ) +M: tuple-class component-tag ( tag class -- ) [ drop "name" required-attr compile-attr ] [ compile-component-attrs ] 2bi [ render ] [code] ; -: CHLOE-TUPLE: +: COMPONENT: scan-word - [ name>> ] [ '[ _ tuple-component-tag ] ] bi + [ name>> ] [ '[ _ component-tag ] ] bi define-chloe-tag ; parsing diff --git a/basis/html/templates/fhtml/fhtml-tests.factor b/basis/html/templates/fhtml/fhtml-tests.factor old mode 100755 new mode 100644 diff --git a/basis/html/templates/fhtml/fhtml.factor b/basis/html/templates/fhtml/fhtml.factor old mode 100755 new mode 100644 diff --git a/basis/http/client/client-docs.factor b/basis/http/client/client-docs.factor index adab7caa44..d4f277a7c3 100644 --- a/basis/http/client/client-docs.factor +++ b/basis/http/client/client-docs.factor @@ -1,6 +1,6 @@ USING: http help.markup help.syntax io.files io.streams.string io.encodings.8-bit io.encodings.binary kernel strings urls -byte-arrays strings assocs sequences ; +urls.encoding byte-arrays strings assocs sequences ; IN: http.client HELP: download-failed @@ -39,11 +39,21 @@ HELP: http-post { $description "Submits a form at a URL." } { $errors "Throws an error if the HTTP request fails." } ; +HELP: with-http-get +{ $values { "url" "a " { $link url } " or " { $link string } } { "quot" "a quotation with stack effect " { $snippet "( chunk -- )" } } { "response" response } } +{ $description "Downloads the contents of a URL. Chunks of data are passed to the quotation as they are read." } +{ $errors "Throws an error if the HTTP request fails." } ; + HELP: http-request { $values { "request" request } { "response" response } { "data" sequence } } { $description "Sends an HTTP request to an HTTP server, and reads the response." } { $errors "Throws an error if the HTTP request fails." } ; +HELP: with-http-request +{ $values { "request" request } { "quot" "a quotation with stack effect " { $snippet "( chunk -- )" } } { "response" response } } +{ $description "Sends an HTTP request to an HTTP server, and reads the response incrementally. Chunks of data are passed to the quotation as they are read." } +{ $errors "Throws an error if the HTTP request fails." } ; + ARTICLE: "http.client.get" "GET requests with the HTTP client" "Basic usage involves passing a " { $link url } " and getting a " { $link response } " and data back:" { $subsection http-get } @@ -52,7 +62,10 @@ ARTICLE: "http.client.get" "GET requests with the HTTP client" { $subsection download-to } "Advanced usage involves constructing a " { $link request } ", which allows " { $link "http.cookies" } " and " { $link "http.headers" } " to be set:" { $subsection } -{ $subsection http-request } ; +{ $subsection http-request } +"The " { $link http-get } " and " { $link http-request } " words output sequences. This is undesirable if the response data may be large. Another pair of words take a quotation instead, and pass the quotation chunks of data incrementally:" +{ $subsection with-http-get } +{ $subsection with-http-request } ; ARTICLE: "http.client.post" "POST requests with the HTTP client" "As with GET requests, there is a high-level word which takes a " { $link url } " and a lower-level word which constructs an HTTP request object which can be passed to " { $link http-request } ":" @@ -82,6 +95,8 @@ ARTICLE: "http.client.errors" "HTTP client errors" ARTICLE: "http.client" "HTTP client" "The " { $vocab-link "http.client" } " vocabulary implements an HTTP and HTTPS client on top of " { $link "http" } "." $nl +"For HTTPS support, you must load the " { $vocab-link "urls.secure" } " vocab first. If you don't load it, HTTPS will not load and images generated by " { $vocab-link "tools.deploy" } " will be smaller as a result." +$nl "There are two primary usage patterns, data retrieval with GET requests and form submission with POST requests:" { $subsection "http.client.get" } { $subsection "http.client.post" } diff --git a/basis/http/client/client-tests.factor b/basis/http/client/client-tests.factor old mode 100755 new mode 100644 index 1219ae0b97..4dcc6b8813 --- a/basis/http/client/client-tests.factor +++ b/basis/http/client/client-tests.factor @@ -1,5 +1,8 @@ USING: http.client http.client.private http tools.test namespaces urls ; + +\ download must-infer + [ "localhost" f ] [ "localhost" parse-host ] unit-test [ "localhost" 8888 ] [ "localhost:8888" parse-host ] unit-test diff --git a/basis/http/client/client.factor b/basis/http/client/client.factor old mode 100755 new mode 100644 index e473ef4e26..9260f15a7b --- a/basis/http/client/client.factor +++ b/basis/http/client/client.factor @@ -3,14 +3,14 @@ USING: accessors assocs kernel math math.parser namespaces make sequences io io.sockets io.streams.string io.files io.timeouts strings splitting calendar continuations accessors vectors -math.order hashtables byte-arrays prettyprint +math.order hashtables byte-arrays prettyprint destructors io.encodings io.encodings.string io.encodings.ascii io.encodings.8-bit io.encodings.binary io.streams.duplex -fry debugger summary ascii urls present +fry debugger summary ascii urls urls.encoding present http http.parsers ; IN: http.client @@ -88,72 +88,92 @@ M: too-many-redirects summary drop [ "Redirection limit of " % max-redirects # " exceeded" % ] "" make ; -DEFER: (http-request) - url derive-url ensure-port ] change-url ; -: do-redirect ( response data -- response data ) - over code>> 300 399 between? [ - drop - redirects inc - redirects get max-redirects < [ - request get - swap "location" header redirect-url - "GET" >>method (http-request) - ] [ - too-many-redirects - ] if - ] when ; +: redirect? ( response -- ? ) + code>> 300 399 between? ; -PRIVATE> +: do-redirect ( quot: ( chunk -- ) response -- response ) + redirects inc + redirects get max-redirects < [ + request get clone + swap "location" header redirect-url + "GET" >>method swap (with-http-request) + ] [ too-many-redirects ] if ; inline recursive : read-chunk-size ( -- n ) read-crlf ";" split1 drop [ blank? ] trim-right hex> [ "Bad chunk size" throw ] unless* ; -: read-chunks ( -- ) +: read-chunked ( quot: ( chunk -- ) -- ) read-chunk-size dup zero? - [ drop ] [ read % read-crlf B{ } assert= read-chunks ] if ; + [ 2drop ] [ + read [ swap call ] [ drop ] 2bi + read-crlf B{ } assert= read-chunked + ] if ; inline recursive -: read-response-body ( response -- response data ) - dup "transfer-encoding" header "chunked" = [ - binary decode-input - [ read-chunks ] B{ } make - over content-charset>> decode - ] [ - dup content-charset>> decode-input - input-stream get contents - ] if ; +: read-unchunked ( quot: ( chunk -- ) -- ) + 8192 read-partial dup [ + [ swap call ] [ drop read-unchunked ] 2bi + ] [ 2drop ] if ; inline recursive -: (http-request) ( request -- response data ) - dup request [ - dup url>> url-addr ascii [ - 1 minutes timeouts - write-request - read-response - read-response-body - ] with-client - do-redirect - ] with-variable ; +: read-response-body ( quot response -- ) + binary decode-input + "transfer-encoding" header "chunked" = + [ read-chunked ] [ read-unchunked ] if ; inline + +: ( -- stream ) + request get url>> url-addr ascii drop + 1 minutes over set-timeout ; + +: (with-http-request) ( request quot: ( chunk -- ) -- response ) + swap + request [ + [ + [ + out>> + [ request get write-request ] + with-output-stream* + ] [ + in>> [ + read-response dup redirect? [ t ] [ + [ nip response set ] + [ read-response-body ] + [ ] + 2tri f + ] if + ] with-input-stream* + ] bi + ] with-disposal + [ do-redirect ] [ nip ] if + ] with-variable ; inline recursive + +PRIVATE> : success? ( code -- ? ) 200 = ; -ERROR: download-failed response body ; +ERROR: download-failed response ; M: download-failed error. - "HTTP download failed:" print nl - [ response>> . nl ] [ body>> write ] bi ; + "HTTP request failed:" print nl + response>> . ; -: check-response ( response data -- response data ) - over code>> success? [ download-failed ] unless ; +: check-response ( response -- response ) + dup code>> success? [ download-failed ] unless ; + +: with-http-request ( request quot -- response ) + (with-http-request) check-response ; inline : http-request ( request -- response data ) - (http-request) check-response ; + [ [ % ] with-http-request ] B{ } make + over content-charset>> decode ; : ( url -- request ) @@ -163,14 +183,14 @@ M: download-failed error. : http-get ( url -- response data ) http-request ; +: with-http-get ( url quot -- response ) + [ ] dip with-http-request ; inline + : download-name ( url -- name ) present file-name "?" split1 drop "/" ?tail drop ; : download-to ( url file -- ) - #! Downloads the contents of a URL to a file. - swap http-get - [ content-charset>> ] [ '[ _ write ] ] bi* - with-file-writer ; + binary [ [ write ] with-http-get drop ] with-file-writer ; : download ( url -- ) dup download-name download-to ; diff --git a/basis/http/http-tests.factor b/basis/http/http-tests.factor old mode 100755 new mode 100644 index 9a1421a3ad..b3930878ff --- a/basis/http/http-tests.factor +++ b/basis/http/http-tests.factor @@ -179,12 +179,14 @@ http.server.dispatchers db.tuples ; : add-quit-action - [ stop-server "Goodbye" "text/html" ] >>display + [ stop-this-server "Goodbye" "text/html" ] >>display "quit" add-responder ; -: test-db "test.db" temp-file sqlite-db ; +: test-db-file "test.db" temp-file ; -[ test-db drop delete-file ] ignore-errors +: test-db test-db-file ; + +[ test-db-file delete-file ] ignore-errors test-db [ init-furnace-tables diff --git a/basis/http/http.factor b/basis/http/http.factor old mode 100755 new mode 100644 index cfc205dbb5..c90a1872ce --- a/basis/http/http.factor +++ b/basis/http/http.factor @@ -3,7 +3,7 @@ USING: accessors kernel combinators math namespaces make assocs sequences splitting sorting sets debugger strings vectors hashtables quotations arrays byte-arrays -math.parser calendar calendar.format present urls logging +math.parser calendar calendar.format present urls io io.encodings io.encodings.iana io.encodings.binary io.encodings.8-bit @@ -96,8 +96,6 @@ TUPLE: cookie name value version comment path domain expires max-age http-only s drop ] { } make ; -\ parse-cookie DEBUG add-input-logging - : check-cookie-string ( string -- string' ) dup "=;'\"\r\n" intersect empty? [ "Bad cookie name or value" throw ] unless ; diff --git a/basis/http/parsers/parsers.factor b/basis/http/parsers/parsers.factor index ce8257dec5..8e8e7358d1 100644 --- a/basis/http/parsers/parsers.factor +++ b/basis/http/parsers/parsers.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: combinators.short-circuit math math.order math.parser kernel sequences sequences.deep peg peg.parsers assocs arrays -hashtables strings unicode.case namespaces make ascii logging ; +hashtables strings unicode.case namespaces make ascii ; IN: http.parsers : except ( quot -- parser ) @@ -61,8 +61,6 @@ PEG: parse-request-line ( string -- triple ) 'space' , ] seq* just ; -\ parse-request-line DEBUG add-input-logging - : 'text' ( -- parser ) [ ctl? ] except ; diff --git a/basis/http/server/cgi/cgi.factor b/basis/http/server/cgi/cgi.factor old mode 100755 new mode 100644 index 0a3cb5cff3..e618249ff4 --- a/basis/http/server/cgi/cgi.factor +++ b/basis/http/server/cgi/cgi.factor @@ -1,8 +1,9 @@ ! Copyright (C) 2007, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: namespaces kernel assocs io.files io.streams.duplex -combinators arrays io.launcher io http.server.static http.server -http accessors sequences strings math.parser fry urls ; +combinators arrays io.launcher io.encodings.binary io +http.server.static http.server http accessors sequences strings +math.parser fry urls urls.encoding calendar ; IN: http.server.cgi : cgi-variables ( script-path -- assoc ) @@ -43,14 +44,15 @@ IN: http.server.cgi : ( name -- desc ) over 1array >>command - swap cgi-variables >>environment ; + swap cgi-variables >>environment + 1 minutes >>timeout ; : serve-cgi ( name -- response ) 200 >>code "CGI output follows" >>message swap '[ - _ output-stream get swap [ + _ output-stream get swap binary [ post-request? [ request get post-data>> raw>> write flush ] when input-stream get swap (stream-copy) ] with-stream diff --git a/basis/http/server/server.factor b/basis/http/server/server.factor old mode 100755 new mode 100644 index 64c85a24d2..697dec24ce --- a/basis/http/server/server.factor +++ b/basis/http/server/server.factor @@ -14,7 +14,7 @@ io.encodings.binary io.streams.limited io.servers.connection io.timeouts -fry logging logging.insomniac calendar urls +fry logging logging.insomniac calendar urls urls.encoding http http.parsers http.server.responses @@ -24,6 +24,8 @@ html.elements html.streams ; IN: http.server +\ parse-cookie DEBUG add-input-logging + : check-absolute ( url -- url ) dup path>> "/" head? [ "Bad request: URL" throw ] unless ; inline @@ -153,8 +155,8 @@ main-responder global [ <404> or ] change-at [ add-responder-nesting ] [ call-responder* ] 2bi ; : http-error. ( error -- ) - "Internal server error" [ - [ print-error nl :c ] with-html-stream + "Internal server error" [ ] [ + [ print-error nl :c ] with-html-writer ] simple-page ; : <500> ( error -- response ) diff --git a/basis/http/server/static/static-docs.factor b/basis/http/server/static/static-docs.factor index 866d2a3409..bca72a6126 100644 --- a/basis/http/server/static/static-docs.factor +++ b/basis/http/server/static/static-docs.factor @@ -19,11 +19,7 @@ HELP: enable-fhtml { $notes "See " { $link "html.templates.fhtml" } "." } { $side-effects "responder" } ; -ARTICLE: "http.server.static" "Serving static content" -"The " { $vocab-link "http.server.static" } " vocabulary implements a responder for serving static files." -{ $subsection } -"The static responder does not serve directory listings by default, as a security measure. Directory listings can be enabled by storing a true value in the " { $slot "allow-listings" } " slot." -$nl +ARTICLE: "http.server.static.extend" "Hooks for dynamic content" "The static responder can be extended for dynamic content by associating quotations with MIME types in the hashtable stored in the " { $slot "special" } " slot. The quotations have stack effect " { $snippet "( path -- )" } "." $nl "A utility word uses the above feature to enable server-side " { $snippet ".fhtml" } " scripts, allowing a development style much like PHP:" @@ -34,4 +30,17 @@ $nl { $subsection } "The default just sends the file's contents with the request; " { $vocab-link "xmode.code2html.responder" } " provides an alternate hook which sends a syntax-highlighted version of the file." ; +ARTICLE: "http.server.static" "Serving static content" +"The " { $vocab-link "http.server.static" } " vocabulary implements a responder for serving static files." +{ $subsection } +"The static responder does not serve directory listings by default, as a security measure. Directory listings can be enabled by storing a true value in the " { $slot "allow-listings" } " slot." +$nl +"If all you want to do is serve files from a directory, the following phrase does the trick:" +{ $code + "USING: namespaces http.server http.server.static ;" + "/var/www/mysite.com/ main-responder set" + "8080 httpd" +} +{ $subsection "http.server.static.extend" } ; + ABOUT: "http.server.static" diff --git a/basis/http/server/static/static.factor b/basis/http/server/static/static.factor old mode 100755 new mode 100644 index abb504ed94..3e3307033a --- a/basis/http/server/static/static.factor +++ b/basis/http/server/static/static.factor @@ -3,7 +3,7 @@ USING: calendar io io.files kernel math math.order math.parser namespaces parser sequences strings assocs hashtables debugger mime-types sorting logging -calendar.format accessors +calendar.format accessors splitting io.encodings.binary fry xml.entities destructors urls html.elements html.templates.fhtml http @@ -14,9 +14,13 @@ IN: http.server.static TUPLE: file-responder root hook special allow-listings ; +: modified-since ( request -- date ) + "if-modified-since" header ";" split1 drop + dup [ rfc822>timestamp ] when ; + : modified-since? ( filename -- ? ) - request get "if-modified-since" header dup [ - [ file-info modified>> ] [ rfc822>timestamp ] bi* after? + request get modified-since dup [ + [ file-info modified>> ] dip after? ] [ 2drop t ] if ; @@ -60,7 +64,7 @@ TUPLE: file-responder root hook special allow-listings ; dup escape-string write ; : directory. ( path -- ) - dup file-name [ + dup file-name [ ] [ [

file-name escape-string write

] [
    diff --git a/basis/inspector/inspector.factor b/basis/inspector/inspector.factor old mode 100755 new mode 100644 diff --git a/basis/interpolate/authors.txt b/basis/interpolate/authors.txt new file mode 100644 index 0000000000..b4bd0e7b35 --- /dev/null +++ b/basis/interpolate/authors.txt @@ -0,0 +1 @@ +Doug Coleman \ No newline at end of file diff --git a/basis/interpolate/interpolate-tests.factor b/basis/interpolate/interpolate-tests.factor new file mode 100644 index 0000000000..005ae87746 --- /dev/null +++ b/basis/interpolate/interpolate-tests.factor @@ -0,0 +1,4 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: tools.test interpolate ; +IN: interpolate.tests diff --git a/basis/interpolate/interpolate.factor b/basis/interpolate/interpolate.factor new file mode 100644 index 0000000000..27f0756f1f --- /dev/null +++ b/basis/interpolate/interpolate.factor @@ -0,0 +1,21 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: io kernel macros make multiline namespaces parser +peg.ebnf present sequences strings ; +IN: interpolate + +MACRO: interpolate ( string -- ) +[EBNF +var = "${" [^}]+ "}" => [[ second >string [ get present write ] curry ]] +text = [^$]+ => [[ >string [ write ] curry ]] +interpolate = (var|text)* => [[ [ ] join ]] +EBNF] ; + +EBNF: interpolate-locals +var = "${" [^}]+ "}" => [[ [ second >string search , [ present write ] % ] [ ] make ]] +text = [^$]+ => [[ [ >string , [ write ] % ] [ ] make ]] +interpolate = (var|text)* => [[ [ ] join ]] +;EBNF + +: I[ "]I" parse-multiline-string + interpolate-locals parsed \ call parsed ; parsing diff --git a/basis/interval-maps/interval-maps-docs.factor b/basis/interval-maps/interval-maps-docs.factor old mode 100755 new mode 100644 diff --git a/basis/interval-maps/interval-maps-tests.factor b/basis/interval-maps/interval-maps-tests.factor old mode 100755 new mode 100644 diff --git a/basis/interval-maps/interval-maps.factor b/basis/interval-maps/interval-maps.factor old mode 100755 new mode 100644 diff --git a/basis/io/buffers/buffers-docs.factor b/basis/io/buffers/buffers-docs.factor old mode 100755 new mode 100644 diff --git a/basis/io/buffers/buffers-tests.factor b/basis/io/buffers/buffers-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/buffers/buffers.factor b/basis/io/buffers/buffers.factor old mode 100755 new mode 100644 diff --git a/basis/io/encodings/8-bit/8-bit.factor b/basis/io/encodings/8-bit/8-bit.factor old mode 100755 new mode 100644 diff --git a/basis/io/encodings/ascii/ascii-docs.factor b/basis/io/encodings/ascii/ascii-docs.factor index fa496a3526..e0ab11f1a4 100644 --- a/basis/io/encodings/ascii/ascii-docs.factor +++ b/basis/io/encodings/ascii/ascii-docs.factor @@ -4,8 +4,8 @@ IN: io.encodings.ascii HELP: ascii { $class-description "ASCII encoding descriptor." } ; -ARTICLE: "ascii" "ASCII encoding" +ARTICLE: "io.encodings.ascii" "ASCII encoding" "By default, if there's a non-ASCII character in an input stream, it will be replaced with a replacement character (U+FFFD), and if a non-ASCII character is used in output, an exception is thrown." { $subsection ascii } ; -ABOUT: "ascii" +ABOUT: "io.encodings.ascii" diff --git a/basis/io/encodings/ascii/ascii.factor b/basis/io/encodings/ascii/ascii.factor old mode 100755 new mode 100644 diff --git a/basis/io/encodings/iana/iana.factor b/basis/io/encodings/iana/iana.factor old mode 100755 new mode 100644 diff --git a/basis/io/encodings/utf16/utf16-tests.factor b/basis/io/encodings/utf16/utf16-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/encodings/utf16/utf16.factor b/basis/io/encodings/utf16/utf16.factor old mode 100755 new mode 100644 diff --git a/basis/io/launcher/launcher-docs.factor b/basis/io/launcher/launcher-docs.factor old mode 100755 new mode 100644 diff --git a/basis/io/launcher/launcher-tests.factor b/basis/io/launcher/launcher-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/launcher/launcher.factor b/basis/io/launcher/launcher.factor old mode 100755 new mode 100644 diff --git a/basis/io/mmap/mmap-docs.factor b/basis/io/mmap/mmap-docs.factor old mode 100755 new mode 100644 diff --git a/basis/io/mmap/mmap-tests.factor b/basis/io/mmap/mmap-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/mmap/mmap.factor b/basis/io/mmap/mmap.factor old mode 100755 new mode 100644 diff --git a/basis/io/monitors/monitors-docs.factor b/basis/io/monitors/monitors-docs.factor old mode 100755 new mode 100644 diff --git a/basis/io/monitors/monitors-tests.factor b/basis/io/monitors/monitors-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/monitors/monitors.factor b/basis/io/monitors/monitors.factor old mode 100755 new mode 100644 diff --git a/basis/io/pipes/pipes-tests.factor b/basis/io/pipes/pipes-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/ports/ports-docs.factor b/basis/io/ports/ports-docs.factor old mode 100755 new mode 100644 diff --git a/basis/io/ports/ports.factor b/basis/io/ports/ports.factor old mode 100755 new mode 100644 diff --git a/basis/io/servers/connection/connection-docs.factor b/basis/io/servers/connection/connection-docs.factor old mode 100755 new mode 100644 index 839f3d8414..00711ce226 --- a/basis/io/servers/connection/connection-docs.factor +++ b/basis/io/servers/connection/connection-docs.factor @@ -58,9 +58,11 @@ ARTICLE: "io.servers.connection" "Threaded servers" { $subsection start-server } { $subsection start-server* } { $subsection wait-for-server } +"Stopping the server:" +{ $subsection stop-server } "From within the dynamic scope of a client handler, several words can be used to interact with the threaded server:" { $subsection remote-address } -{ $subsection stop-server } +{ $subsection stop-this-server } { $subsection secure-port } { $subsection insecure-port } "Additionally, the " { $link local-address } " variable is set, as in " { $link with-client } "." ; @@ -88,7 +90,8 @@ HELP: handle-client* HELP: start-server { $values { "threaded-server" threaded-server } } -{ $description "Starts a threaded server, returning when a client handler calls " { $link stop-server } "." } ; +{ $description "Starts a threaded server." } +{ $notes "Use " { $link stop-server } " or " { $link stop-this-server } " to stop the server." } ; HELP: wait-for-server { $values { "threaded-server" threaded-server } } @@ -96,9 +99,13 @@ HELP: wait-for-server HELP: start-server* { $values { "threaded-server" threaded-server } } -{ $description "Starts a threaded server, returning as soon as it is accepting connections." } ; +{ $description "Starts a threaded server, returning as soon as it is ready to begin accepting connections." } ; HELP: stop-server +{ $values { "threaded-server" threaded-server } } +{ $description "Stops a threaded server, preventing it from accepting any more connections and returning to the caller of " { $link start-server } ". All client connections which have already been opened continue to be serviced." } ; + +HELP: stop-this-server { $description "Stops the current threaded server, preventing it from accepting any more connections and returning to the caller of " { $link start-server } ". All client connections which have already been opened continue to be serviced." } ; HELP: secure-port diff --git a/basis/io/servers/connection/connection-tests.factor b/basis/io/servers/connection/connection-tests.factor old mode 100755 new mode 100644 index aa8df0b16c..a3223ed2aa --- a/basis/io/servers/connection/connection-tests.factor +++ b/basis/io/servers/connection/connection-tests.factor @@ -33,7 +33,7 @@ concurrency.promises io.encodings.ascii io threads calendar ; 5 >>max-connections 1237 >>insecure - [ "Hello world." write stop-server ] >>handler + [ "Hello world." write stop-this-server ] >>handler "server" set ] unit-test diff --git a/basis/io/servers/connection/connection.factor b/basis/io/servers/connection/connection.factor old mode 100755 new mode 100644 index bde4e518ac..674ed8803c --- a/basis/io/servers/connection/connection.factor +++ b/basis/io/servers/connection/connection.factor @@ -105,7 +105,7 @@ M: threaded-server handle-client* handler>> call ; threaded-server get encoding>> [ started-accept-loop ] [ [ accept-loop ] with-disposal ] bi ; -\ start-accept-loop ERROR add-error-logging +\ start-accept-loop NOTICE add-error-logging : init-server ( threaded-server -- threaded-server ) dup semaphore>> [ @@ -136,8 +136,11 @@ PRIVATE> [ wait-for-server ] bi ; -: stop-server ( -- ) - threaded-server get [ f ] change-sockets drop dispose-each ; +: stop-server ( threaded-server -- ) + [ f ] change-sockets drop dispose-each ; + +: stop-this-server ( -- ) + threaded-server get stop-server ; GENERIC: port ( addrspec -- n ) diff --git a/basis/io/sockets/secure/secure-tests.factor b/basis/io/sockets/secure/secure-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/sockets/secure/secure.factor b/basis/io/sockets/secure/secure.factor old mode 100755 new mode 100644 diff --git a/basis/io/sockets/sockets-docs.factor b/basis/io/sockets/sockets-docs.factor old mode 100755 new mode 100644 index 3c77be254c..3454f3384e --- a/basis/io/sockets/sockets-docs.factor +++ b/basis/io/sockets/sockets-docs.factor @@ -104,7 +104,7 @@ HELP: } ; HELP: with-client -{ $values { "remote" "an address specifier" } { "encoding" "an encding descriptor" } { "quot" quotation } } +{ $values { "remote" "an address specifier" } { "encoding" "an encoding descriptor" } { "quot" quotation } } { $description "Opens a network connection and calls the quotation in a new dynamic scope with " { $link input-stream } " and " { $link output-stream } " rebound to the network streams. The local address the socket is bound to is stored in the " { $link local-address } " variable." } { $errors "Throws an error if the connection cannot be established." } ; diff --git a/basis/io/sockets/sockets-tests.factor b/basis/io/sockets/sockets-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/sockets/sockets.factor b/basis/io/sockets/sockets.factor old mode 100755 new mode 100644 index 9bfcc7e310..c704382dd4 --- a/basis/io/sockets/sockets.factor +++ b/basis/io/sockets/sockets.factor @@ -17,10 +17,12 @@ IN: io.sockets ! Addressing GENERIC: protocol-family ( addrspec -- af ) -GENERIC: sockaddr-type ( addrspec -- type ) +GENERIC: sockaddr-size ( addrspec -- n ) GENERIC: make-sockaddr ( addrspec -- sockaddr ) +GENERIC: empty-sockaddr ( addrspec -- sockaddr ) + GENERIC: address-size ( addrspec -- n ) GENERIC: inet-ntop ( data addrspec -- str ) @@ -28,10 +30,10 @@ GENERIC: inet-ntop ( data addrspec -- str ) GENERIC: inet-pton ( str addrspec -- data ) : make-sockaddr/size ( addrspec -- sockaddr size ) - [ make-sockaddr ] [ sockaddr-type heap-size ] bi ; + [ make-sockaddr ] [ sockaddr-size ] bi ; : empty-sockaddr/size ( addrspec -- sockaddr size ) - sockaddr-type [ ] [ heap-size ] bi ; + [ empty-sockaddr ] [ sockaddr-size ] bi ; GENERIC: parse-sockaddr ( sockaddr addrspec -- newaddrspec ) @@ -74,7 +76,9 @@ M: inet4 address-size drop 4 ; M: inet4 protocol-family drop PF_INET ; -M: inet4 sockaddr-type drop "sockaddr-in" c-type ; +M: inet4 sockaddr-size drop "sockaddr-in" heap-size ; + +M: inet4 empty-sockaddr drop "sockaddr-in" ; M: inet4 make-sockaddr ( inet -- sockaddr ) "sockaddr-in" @@ -128,7 +132,9 @@ M: inet6 address-size drop 16 ; M: inet6 protocol-family drop PF_INET6 ; -M: inet6 sockaddr-type drop "sockaddr-in6" c-type ; +M: inet6 sockaddr-size drop "sockaddr-in6" heap-size ; + +M: inet6 empty-sockaddr drop "sockaddr-in6" ; M: inet6 make-sockaddr ( inet -- sockaddr ) "sockaddr-in6" diff --git a/basis/io/streams/duplex/duplex-docs.factor b/basis/io/streams/duplex/duplex-docs.factor old mode 100755 new mode 100644 diff --git a/basis/io/streams/duplex/duplex-tests.factor b/basis/io/streams/duplex/duplex-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/streams/duplex/duplex.factor b/basis/io/streams/duplex/duplex.factor old mode 100755 new mode 100644 diff --git a/basis/io/streams/null/null.factor b/basis/io/streams/null/null.factor old mode 100755 new mode 100644 diff --git a/basis/io/styles/styles.factor b/basis/io/styles/styles.factor index b0eb327927..c9ba8f66df 100644 --- a/basis/io/styles/styles.factor +++ b/basis/io/styles/styles.factor @@ -20,6 +20,8 @@ SYMBOL: presented SYMBOL: presented-path SYMBOL: presented-printer +SYMBOL: href + ! Paragraph styles SYMBOL: page-color SYMBOL: border-color diff --git a/basis/io/thread/thread.factor b/basis/io/thread/thread.factor old mode 100755 new mode 100644 diff --git a/basis/io/timeouts/timeouts-docs.factor b/basis/io/timeouts/timeouts-docs.factor old mode 100755 new mode 100644 diff --git a/basis/io/timeouts/timeouts.factor b/basis/io/timeouts/timeouts.factor old mode 100755 new mode 100644 diff --git a/basis/io/unix/backend/backend.factor b/basis/io/unix/backend/backend.factor old mode 100755 new mode 100644 index 0e9139f431..5bb0b82555 --- a/basis/io/unix/backend/backend.factor +++ b/basis/io/unix/backend/backend.factor @@ -1,11 +1,11 @@ ! Copyright (C) 2004, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: alien alien.c-types generic assocs kernel kernel.private -math io.ports sequences strings structs sbufs threads unix +math io.ports sequences strings sbufs threads unix vectors io.buffers io.backend io.encodings math.parser continuations system libc qualified namespaces make io.timeouts io.encodings.utf8 destructors accessors summary combinators -locals ; +locals unix.time ; QUALIFIED: io IN: io.unix.backend diff --git a/basis/io/unix/bsd/bsd.factor b/basis/io/unix/bsd/bsd.factor old mode 100755 new mode 100644 diff --git a/basis/io/unix/epoll/epoll.factor b/basis/io/unix/epoll/epoll.factor index 406a7fcb50..05a9bcfa8d 100644 --- a/basis/io/unix/epoll/epoll.factor +++ b/basis/io/unix/epoll/epoll.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: alien.c-types kernel io.ports io.unix.backend bit-arrays sequences assocs unix unix.linux.epoll math -namespaces structs ; +namespaces unix.time ; IN: io.unix.epoll TUPLE: epoll-mx < mx events ; diff --git a/basis/io/unix/files/bsd/bsd.factor b/basis/io/unix/files/bsd/bsd.factor new file mode 100644 index 0000000000..18e713af2f --- /dev/null +++ b/basis/io/unix/files/bsd/bsd.factor @@ -0,0 +1,17 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel alien.syntax math io.unix.files system +unix.stat accessors combinators calendar.unix ; +IN: io.unix.files.bsd + +TUPLE: bsd-file-info < unix-file-info birth-time flags gen ; + +M: bsd new-file-info ( -- class ) bsd-file-info new ; + +M: bsd stat>file-info ( stat -- file-info ) + [ call-next-method ] keep + { + [ stat-st_flags >>flags ] + [ stat-st_gen >>gen ] + [ stat-st_birthtimespec timespec>unix-time >>birth-time ] + } cleave ; diff --git a/basis/io/unix/files/bsd/tags.txt b/basis/io/unix/files/bsd/tags.txt new file mode 100644 index 0000000000..6bf68304bb --- /dev/null +++ b/basis/io/unix/files/bsd/tags.txt @@ -0,0 +1 @@ +unportable diff --git a/basis/io/unix/files/files-docs.factor b/basis/io/unix/files/files-docs.factor new file mode 100644 index 0000000000..5b5e257c5e --- /dev/null +++ b/basis/io/unix/files/files-docs.factor @@ -0,0 +1,277 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: classes help.markup help.syntax io.streams.string +strings math calendar io.files ; +IN: io.unix.files + +HELP: file-group-id +{ $values + { "path" "a pathname string" } + { "gid" integer } } +{ $description "Returns the group id for a given file." } ; + +HELP: file-group-name +{ $values + { "path" "a pathname string" } + { "string" string } } +{ $description "Returns the group name for a given file." } ; + +HELP: file-permissions +{ $values + { "path" "a pathname string" } + { "n" integer } } +{ $description "Returns the Unix file permissions for a given file." } ; + +HELP: file-username +{ $values + { "path" "a pathname string" } + { "string" string } } +{ $description "Returns the username for a given file." } ; + +HELP: file-user-id +{ $values + { "path" "a pathname string" } + { "uid" integer } } +{ $description "Returns the user id for a given file." } ; + +HELP: group-execute? +{ $values + { "path" "a pathname string" } + { "?" "a boolean" } } +{ $description "Tests whether the " { $snippet "group execute" } " bit is set on a file." } ; + +HELP: group-read? +{ $values + { "path" "a pathname string" } + { "?" "a boolean" } } +{ $description "Tests whether the " { $snippet "group read" } " bit is set on a file." } ; + +HELP: group-write? +{ $values + { "path" "a pathname string" } + { "?" "a boolean" } } +{ $description "Tests whether the " { $snippet "group write" } " bit is set on a file." } ; + +HELP: other-execute? +{ $values + { "path" "a pathname string" } + { "?" "a boolean" } } +{ $description "Tests whether the " { $snippet "other execute" } " bit is set on a file." } ; + +HELP: other-read? +{ $values + { "path" "a pathname string" } + { "?" "a boolean" } } +{ $description "Tests whether the " { $snippet "other read" } " bit is set on a file." } ; + +HELP: other-write? +{ $values + { "path" "a pathname string" } + { "?" "a boolean" } } +{ $description "Tests whether the " { $snippet "other write" } " bit is set on a file." } ; + +HELP: set-file-access-time +{ $values + { "path" "a pathname string" } { "timestamp" timestamp } } +{ $description "Sets a file's last access timestamp." } ; + +HELP: set-file-group +{ $values + { "path" "a pathname string" } { "string/id" "a string or a group id" } } +{ $description "Sets a file's group id from the given group id or group name." } ; + +HELP: set-file-ids +{ $values + { "path" "a pathname string" } { "uid" integer } { "gid" integer } } +{ $description "Sets the user id and group id of a file with a single library call." } ; + +HELP: set-file-permissions +{ $values + { "path" "a pathname string" } { "n" "an integer, interepreted as a string of bits" } } +{ $description "Sets the file permissions for a given file with the supplied Unix permissions integer. Supplying an octal number with " { $link POSTPONE: OCT: } " is recommended." } +{ $examples "Using the tradidional octal value:" + { $unchecked-example "USING: io.unix.files kernel ;" + "\"resource:license.txt\" OCT: 755 set-file-permissions" + "" + } + "Higher-level, setting named bits:" + { $unchecked-example "USING: io.unix.files kernel math.bitwise ;" + "\"resource:license.txt\"" + "{ USER-ALL GROUP-READ GROUP-EXECUTE OTHER-READ OTHER-EXECUTE }" + "flags set-file-permissions" + "" } +} ; + +HELP: set-file-times +{ $values + { "path" "a pathname string" } { "timestamps" "an array of two timestamps" } } +{ $description "Sets the access and write timestamps for a file as provided in the input array. A value of " { $link f } " provided for either of the timestamps will not change that timestamp." } ; + +HELP: set-file-user +{ $values + { "path" "a pathname string" } { "string/id" "a string or a user id" } } +{ $description "Sets a file's user id from the given user id or username." } ; + +HELP: set-file-modified-time +{ $values + { "path" "a pathname string" } { "timestamp" timestamp } } +{ $description "Sets a file's last modified timestamp, or write timestamp." } ; + +HELP: set-gid +{ $values + { "path" "a pathname string" } { "?" "a boolean" } } +{ $description "Sets the " { $snippet "gid" } " bit of a file to true or false." } ; + +HELP: gid? +{ $values + { "path" "a pathname string" } + { "?" "a boolean" } } +{ $description "Tests whether the " { $snippet "gid" } " bit is set on a file." } ; + +HELP: set-group-execute +{ $values + { "path" "a pathname string" } { "?" "a boolean" } } +{ $description "Sets the " { $snippet "group execute" } " bit of a file to true or false." } ; + +HELP: set-group-read +{ $values + { "path" "a pathname string" } { "?" "a boolean" } } +{ $description "Sets the " { $snippet "group read" } " bit of a file to true or false." } ; + +HELP: set-group-write +{ $values + { "path" "a pathname string" } { "?" "a boolean" } } +{ $description "Sets the " { $snippet "group write" } " bit of a file to true or false." } ; + +HELP: set-other-execute +{ $values + { "path" "a pathname string" } { "?" "a boolean" } } +{ $description "Sets the " { $snippet "other execute" } " bit of a file to true or false." } ; + +HELP: set-other-read +{ $values + { "path" "a pathname string" } { "?" "a boolean" } } +{ $description "Sets the " { $snippet "other read" } " bit of a file to true or false." } ; + +HELP: set-other-write +{ $values + { "path" "a pathname string" } { "?" "a boolean" } } +{ $description "Sets the " { $snippet "other execute" } " bit of a file to true or false." } ; + +HELP: set-sticky +{ $values + { "path" "a pathname string" } { "?" "a boolean" } } +{ $description "Sets the " { $snippet "sticky" } " bit of a file to true or false." } ; + +HELP: sticky? +{ $values + { "path" "a pathname string" } + { "?" "a boolean" } } +{ $description "Tests whether the " { $snippet "sticky" } " bit of a file is set." } ; + +HELP: set-uid +{ $values + { "path" "a pathname string" } { "?" "a boolean" } } +{ $description "Sets the " { $snippet "uid" } " bit of a file to true or false." } ; + +HELP: uid? +{ $values + { "path" "a pathname string" } + { "?" "a boolean" } } +{ $description "Tests whether the " { $snippet "uid" } " bit of a file is set." } ; + +HELP: set-user-execute +{ $values + { "path" "a pathname string" } { "?" "a boolean" } } +{ $description "Sets the " { $snippet "user execute" } " bit of a file to true or false." } ; + +HELP: set-user-read +{ $values + { "path" "a pathname string" } { "?" "a boolean" } } +{ $description "Sets the " { $snippet "user read" } " bit of a file to true or false." } ; + +HELP: set-user-write +{ $values + { "path" "a pathname string" } { "?" "a boolean" } } +{ $description "Sets the " { $snippet "user write" } " bit of a file to true or false." } ; + +HELP: user-execute? +{ $values + { "path" "a pathname string" } + { "?" "a boolean" } } +{ $description "Tests whether the " { $snippet "user execute" } " bit is set on a file." } ; + +HELP: user-read? +{ $values + { "path" "a pathname string" } + { "?" "a boolean" } } +{ $description "Tests whether the " { $snippet "user read" } " bit is set on a file." } ; + +HELP: user-write? +{ $values + { "path" "a pathname string" } + { "?" "a boolean" } } +{ $description "Tests whether the " { $snippet "user write" } " bit is set on a file." } ; + +ARTICLE: "unix-file-permissions" "Unix file permissions" +"Reading all file permissions:" +{ $subsection file-permissions } +"Reading individual file permissions:" +{ $subsection uid? } +{ $subsection gid? } +{ $subsection sticky? } +{ $subsection user-read? } +{ $subsection user-write? } +{ $subsection user-execute? } +{ $subsection group-read? } +{ $subsection group-write? } +{ $subsection group-execute? } +{ $subsection other-read? } +{ $subsection other-write? } +{ $subsection other-execute? } +"Writing all file permissions:" +{ $subsection set-file-permissions } +"Writing individual file permissions:" +{ $subsection set-uid } +{ $subsection set-gid } +{ $subsection set-sticky } +{ $subsection set-user-read } +{ $subsection set-user-write } +{ $subsection set-user-execute } +{ $subsection set-group-read } +{ $subsection set-group-write } +{ $subsection set-group-execute } +{ $subsection set-other-read } +{ $subsection set-other-write } +{ $subsection set-other-execute } ; + +ARTICLE: "unix-file-timestamps" "Unix file timestamps" +"To read file times, use the accessors on the object returned by the " { $link file-info } " word." $nl +"Setting multiple file times:" +{ $subsection set-file-times } +"Setting just the last access time:" +{ $subsection set-file-access-time } +"Setting just the last modified time:" +{ $subsection set-file-modified-time } ; + + +ARTICLE: "unix-file-ids" "Unix file user and group ids" +"Reading file user data:" +{ $subsection file-user-id } +{ $subsection file-username } +"Setting file user data:" +{ $subsection set-file-user } +"Reading file group data:" +{ $subsection file-group-id } +{ $subsection file-group-name } +"Setting file group data:" +{ $subsection set-file-group } ; + + +ARTICLE: "io.unix.files" "Unix file attributes" +"The " { $vocab-link "io.unix.files" } " vocabulary implements the Unix backend for opening files and provides a high-level way to set permissions, timestamps, and user and group ids for files." +{ $subsection "unix-file-permissions" } +{ $subsection "unix-file-timestamps" } +{ $subsection "unix-file-ids" } ; + +ABOUT: "io.unix.files" diff --git a/basis/io/unix/files/files-tests.factor b/basis/io/unix/files/files-tests.factor old mode 100755 new mode 100644 index 040b191d27..5a24c1314a --- a/basis/io/unix/files/files-tests.factor +++ b/basis/io/unix/files/files-tests.factor @@ -1,4 +1,6 @@ -USING: tools.test io.files ; +USING: tools.test io.files continuations kernel io.unix.files +math.bitwise calendar accessors math.functions math unix.users +unix.groups arrays sequences ; IN: io.unix.files.tests [ "/usr/libexec/" ] [ "/usr/libexec/awk/" parent-directory ] unit-test @@ -27,3 +29,109 @@ IN: io.unix.files.tests [ "/lib/bux" ] [ "/usr" "/lib/bux" append-path ] unit-test [ "/lib/bux/" ] [ "/usr" "/lib/bux/" append-path ] unit-test [ t ] [ "/foo" absolute-path? ] unit-test + +: test-file ( -- path ) + "permissions" temp-file ; + +: prepare-test-file ( -- ) + [ test-file delete-file ] ignore-errors + test-file touch-file ; + +: perms ( -- n ) + test-file file-permissions OCT: 7777 mask ; + +prepare-test-file + +[ t ] +[ test-file { USER-ALL GROUP-ALL OTHER-ALL } flags set-file-permissions perms OCT: 777 = ] unit-test + +[ t ] [ test-file user-read? ] unit-test +[ t ] [ test-file user-write? ] unit-test +[ t ] [ test-file user-execute? ] unit-test +[ t ] [ test-file group-read? ] unit-test +[ t ] [ test-file group-write? ] unit-test +[ t ] [ test-file group-execute? ] unit-test +[ t ] [ test-file other-read? ] unit-test +[ t ] [ test-file other-write? ] unit-test +[ t ] [ test-file other-execute? ] unit-test + +[ t ] +[ test-file f set-other-execute perms OCT: 776 = ] unit-test + +[ t ] +[ test-file f set-other-write perms OCT: 774 = ] unit-test + +[ t ] +[ test-file f set-other-read perms OCT: 770 = ] unit-test + +[ t ] +[ test-file f set-group-execute perms OCT: 760 = ] unit-test + +[ t ] +[ test-file f set-group-write perms OCT: 740 = ] unit-test + +[ t ] +[ test-file f set-group-read perms OCT: 700 = ] unit-test + +[ t ] +[ test-file f set-user-execute perms OCT: 600 = ] unit-test + +[ t ] +[ test-file f set-user-write perms OCT: 400 = ] unit-test + +[ t ] +[ test-file f set-user-read perms OCT: 000 = ] unit-test + +[ t ] +[ test-file { USER-ALL GROUP-ALL OTHER-EXECUTE } flags set-file-permissions perms OCT: 771 = ] unit-test + +prepare-test-file + +[ t ] +[ + test-file now + [ set-file-access-time ] 2keep + [ file-info accessed>> ] + [ [ [ truncate >integer ] change-second ] bi@ ] bi* = +] unit-test + +[ t ] +[ + test-file now + [ set-file-modified-time ] 2keep + [ file-info modified>> ] + [ [ [ truncate >integer ] change-second ] bi@ ] bi* = +] unit-test + +[ t ] +[ + test-file now [ dup 2array set-file-times ] 2keep + [ file-info [ modified>> ] [ accessed>> ] bi ] dip + 3array + [ [ truncate >integer ] change-second ] map all-equal? +] unit-test + +[ ] [ test-file f now 2array set-file-times ] unit-test +[ ] [ test-file now f 2array set-file-times ] unit-test +[ ] [ test-file f f 2array set-file-times ] unit-test + + +[ ] [ test-file real-username set-file-user ] unit-test +[ ] [ test-file real-user-id set-file-user ] unit-test +[ ] [ test-file real-group-name set-file-group ] unit-test +[ ] [ test-file real-group-id set-file-group ] unit-test + +[ t ] [ test-file file-username real-username = ] unit-test +[ t ] [ test-file file-group-name real-group-name = ] unit-test + +[ ] +[ test-file real-user-id real-group-id set-file-ids ] unit-test + +[ ] +[ test-file f real-group-id set-file-ids ] unit-test + +[ ] +[ test-file real-user-id f set-file-ids ] unit-test + +[ ] +[ test-file f f set-file-ids ] unit-test diff --git a/basis/io/unix/files/files.factor b/basis/io/unix/files/files.factor old mode 100755 new mode 100644 index c6eda50855..40ef9ad859 --- a/basis/io/unix/files/files.factor +++ b/basis/io/unix/files/files.factor @@ -1,11 +1,11 @@ -! Copyright (C) 2005, 2008 Slava Pestov. +! Copyright (C) 2005, 2008 Slava Pestov, Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: io.backend io.ports io.unix.backend io.files io unix unix.stat unix.time kernel math continuations math.bitwise byte-arrays alien combinators calendar io.encodings.binary accessors sequences strings system -io.files.private destructors ; - +io.files.private destructors vocabs.loader calendar.unix +unix.stat alien.c-types arrays unix.users unix.groups ; IN: io.unix.files M: unix cwd ( -- path ) @@ -74,26 +74,14 @@ M: unix copy-file ( from to -- ) [ swap file-info permissions>> chmod io-error ] 2bi ; -: stat>type ( stat -- type ) - stat-st_mode S_IFMT bitand { - { S_IFREG [ +regular-file+ ] } - { S_IFDIR [ +directory+ ] } - { S_IFCHR [ +character-device+ ] } - { S_IFBLK [ +block-device+ ] } - { S_IFIFO [ +fifo+ ] } - { S_IFLNK [ +symbolic-link+ ] } - { S_IFSOCK [ +socket+ ] } - [ drop +unknown+ ] - } case ; +HOOK: stat>file-info os ( stat -- file-info ) -: stat>file-info ( stat -- info ) - { - [ stat>type ] - [ stat-st_size ] - [ stat-st_mode ] - [ stat-st_mtim timespec-sec seconds unix-1970 time+ ] - } cleave - \ file-info boa ; +HOOK: stat>type os ( stat -- file-info ) + +HOOK: new-file-info os ( -- class ) + +TUPLE: unix-file-info < file-info uid gid dev ino +nlink rdev blocks blocksize ; M: unix file-info ( path -- info ) normalize-path file-status stat>file-info ; @@ -105,4 +93,165 @@ M: unix make-link ( path1 path2 -- ) normalize-path symlink io-error ; M: unix read-link ( path -- path' ) - normalize-path read-symbolic-link ; \ No newline at end of file + normalize-path read-symbolic-link ; + +M: unix new-file-info ( -- class ) unix-file-info new ; + +M: unix stat>file-info ( stat -- file-info ) + [ new-file-info ] dip + { + [ stat>type >>type ] + [ stat-st_size >>size ] + [ stat-st_mode >>permissions ] + [ stat-st_ctimespec timespec>unix-time >>created ] + [ stat-st_mtimespec timespec>unix-time >>modified ] + [ stat-st_atimespec timespec>unix-time >>accessed ] + [ stat-st_uid >>uid ] + [ stat-st_gid >>gid ] + [ stat-st_dev >>dev ] + [ stat-st_ino >>ino ] + [ stat-st_nlink >>nlink ] + [ stat-st_rdev >>rdev ] + [ stat-st_blocks >>blocks ] + [ stat-st_blksize >>blocksize ] + } cleave ; + +M: unix stat>type ( stat -- type ) + stat-st_mode S_IFMT bitand { + { S_IFREG [ +regular-file+ ] } + { S_IFDIR [ +directory+ ] } + { S_IFCHR [ +character-device+ ] } + { S_IFBLK [ +block-device+ ] } + { S_IFIFO [ +fifo+ ] } + { S_IFLNK [ +symbolic-link+ ] } + { S_IFSOCK [ +socket+ ] } + [ drop +unknown+ ] + } case ; + +! Linux has no extra fields in its stat struct +os { + { macosx [ "io.unix.files.bsd" require ] } + { netbsd [ "io.unix.files.bsd" require ] } + { openbsd [ "io.unix.files.bsd" require ] } + { freebsd [ "io.unix.files.bsd" require ] } + { linux [ ] } +} case + + + +: UID OCT: 0004000 ; inline +: GID OCT: 0002000 ; inline +: STICKY OCT: 0001000 ; inline +: USER-ALL OCT: 0000700 ; inline +: USER-READ OCT: 0000400 ; inline +: USER-WRITE OCT: 0000200 ; inline +: USER-EXECUTE OCT: 0000100 ; inline +: GROUP-ALL OCT: 0000070 ; inline +: GROUP-READ OCT: 0000040 ; inline +: GROUP-WRITE OCT: 0000020 ; inline +: GROUP-EXECUTE OCT: 0000010 ; inline +: OTHER-ALL OCT: 0000007 ; inline +: OTHER-READ OCT: 0000004 ; inline +: OTHER-WRITE OCT: 0000002 ; inline +: OTHER-EXECUTE OCT: 0000001 ; inline + +: uid? ( path -- ? ) UID file-mode? ; +: gid? ( path -- ? ) GID file-mode? ; +: sticky? ( path -- ? ) STICKY file-mode? ; +: user-read? ( path -- ? ) USER-READ file-mode? ; +: user-write? ( path -- ? ) USER-WRITE file-mode? ; +: user-execute? ( path -- ? ) USER-EXECUTE file-mode? ; +: group-read? ( path -- ? ) GROUP-READ file-mode? ; +: group-write? ( path -- ? ) GROUP-WRITE file-mode? ; +: group-execute? ( path -- ? ) GROUP-EXECUTE file-mode? ; +: other-read? ( path -- ? ) OTHER-READ file-mode? ; +: other-write? ( path -- ? ) OTHER-WRITE file-mode? ; +: other-execute? ( path -- ? ) OTHER-EXECUTE file-mode? ; + +: set-uid ( path ? -- ) UID swap chmod-set-bit ; +: set-gid ( path ? -- ) GID swap chmod-set-bit ; +: set-sticky ( path ? -- ) STICKY swap chmod-set-bit ; +: set-user-read ( path ? -- ) USER-READ swap chmod-set-bit ; +: set-user-write ( path ? -- ) USER-WRITE swap chmod-set-bit ; +: set-user-execute ( path ? -- ) USER-EXECUTE swap chmod-set-bit ; +: set-group-read ( path ? -- ) GROUP-READ swap chmod-set-bit ; +: set-group-write ( path ? -- ) GROUP-WRITE swap chmod-set-bit ; +: set-group-execute ( path ? -- ) GROUP-EXECUTE swap chmod-set-bit ; +: set-other-read ( path ? -- ) OTHER-READ swap chmod-set-bit ; +: set-other-write ( path ? -- ) OTHER-WRITE swap chmod-set-bit ; +: set-other-execute ( path ? -- ) OTHER-EXECUTE swap chmod-set-bit ; + +: set-file-permissions ( path n -- ) + [ normalize-path ] dip chmod io-error ; + +: file-permissions ( path -- n ) + normalize-path file-info permissions>> ; + + ] keep + dup length [ over [ pick set-timeval-nth ] [ 2drop ] if ] 2each ; + +: timestamp>timeval ( timestamp -- timeval ) + unix-1970 time- duration>milliseconds make-timeval ; + +: timestamps>byte-array ( timestamps -- byte-array ) + [ dup [ timestamp>timeval ] when ] map make-timeval-array ; + +PRIVATE> + +: set-file-times ( path timestamps -- ) + #! set access, write + [ normalize-path ] dip + timestamps>byte-array utimes io-error ; + +: set-file-access-time ( path timestamp -- ) + f 2array set-file-times ; + +: set-file-modified-time ( path timestamp -- ) + f swap 2array set-file-times ; + +: set-file-ids ( path uid gid -- ) + [ normalize-path ] 2dip + [ [ -1 ] unless* ] bi@ chown io-error ; + +GENERIC: set-file-user ( path string/id -- ) + +GENERIC: set-file-group ( path string/id -- ) + +M: integer set-file-user ( path uid -- ) + f set-file-ids ; + +M: string set-file-user ( path string -- ) + user-id f set-file-ids ; + +M: integer set-file-group ( path gid -- ) + f swap set-file-ids ; + +M: string set-file-group ( path string -- ) + group-id + f swap set-file-ids ; + +: file-user-id ( path -- uid ) + normalize-path file-info uid>> ; + +: file-username ( path -- string ) + file-user-id username ; + +: file-group-id ( path -- gid ) + normalize-path file-info gid>> ; + +: file-group-name ( path -- string ) + file-group-id group-name ; diff --git a/basis/io/unix/files/unique/unique.factor b/basis/io/unix/files/unique/unique.factor index 95e321fd93..e47ac6a2e3 100644 --- a/basis/io/unix/files/unique/unique.factor +++ b/basis/io/unix/files/unique/unique.factor @@ -1,3 +1,5 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. USING: kernel io.ports io.unix.backend math.bitwise unix io.files.unique.backend system ; IN: io.unix.files.unique diff --git a/basis/io/unix/kqueue/kqueue.factor b/basis/io/unix/kqueue/kqueue.factor old mode 100755 new mode 100644 diff --git a/basis/io/unix/launcher/launcher-tests.factor b/basis/io/unix/launcher/launcher-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/unix/launcher/launcher.factor b/basis/io/unix/launcher/launcher.factor old mode 100755 new mode 100644 diff --git a/basis/io/unix/launcher/parser/parser-tests.factor b/basis/io/unix/launcher/parser/parser-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/unix/launcher/parser/parser.factor b/basis/io/unix/launcher/parser/parser.factor old mode 100755 new mode 100644 diff --git a/basis/io/unix/linux/linux.factor b/basis/io/unix/linux/linux.factor old mode 100755 new mode 100644 diff --git a/basis/io/unix/mmap/mmap.factor b/basis/io/unix/mmap/mmap.factor old mode 100755 new mode 100644 diff --git a/basis/io/unix/select/select.factor b/basis/io/unix/select/select.factor old mode 100755 new mode 100644 index f0547da10e..f2a802a859 --- a/basis/io/unix/select/select.factor +++ b/basis/io/unix/select/select.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2004, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: alien.c-types kernel io.ports io.unix.backend -bit-arrays sequences assocs unix math namespaces structs -accessors math.order locals ; +bit-arrays sequences assocs unix math namespaces +accessors math.order locals unix.time ; IN: io.unix.select TUPLE: select-mx < mx read-fdset write-fdset ; diff --git a/basis/io/unix/sockets/secure/secure.factor b/basis/io/unix/sockets/secure/secure.factor old mode 100755 new mode 100644 diff --git a/basis/io/unix/sockets/sockets.factor b/basis/io/unix/sockets/sockets.factor old mode 100755 new mode 100644 index 50952dd217..8f9ff4f066 --- a/basis/io/unix/sockets/sockets.factor +++ b/basis/io/unix/sockets/sockets.factor @@ -139,7 +139,9 @@ M: unix (send) ( packet addrspec datagram -- ) ! Unix domain sockets M: local protocol-family drop PF_UNIX ; -M: local sockaddr-type drop "sockaddr-un" c-type ; +M: local sockaddr-size drop "sockaddr-un" heap-size ; + +M: local empty-sockaddr drop "sockaddr-un" ; M: local make-sockaddr path>> (normalize-path) diff --git a/basis/io/unix/unix-tests.factor b/basis/io/unix/unix-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/unix/unix.factor b/basis/io/unix/unix.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/files/files.factor b/basis/io/windows/files/files.factor old mode 100755 new mode 100644 index 40e7e17402..dbe16f0a6e --- a/basis/io/windows/files/files.factor +++ b/basis/io/windows/files/files.factor @@ -147,18 +147,18 @@ SYMBOLS: +read-only+ +hidden+ +system+ FILE_ATTRIBUTE_DIRECTORY mask? +directory+ +regular-file+ ? ; : WIN32_FIND_DATA>file-info ( WIN32_FIND_DATA -- file-info ) + [ \ file-info new ] dip { - [ WIN32_FIND_DATA-dwFileAttributes win32-file-type ] + [ WIN32_FIND_DATA-dwFileAttributes win32-file-type >>type ] [ [ WIN32_FIND_DATA-nFileSizeLow ] - [ WIN32_FIND_DATA-nFileSizeHigh ] bi >64bit + [ WIN32_FIND_DATA-nFileSizeHigh ] bi >64bit >>size ] - [ WIN32_FIND_DATA-dwFileAttributes ] - ! [ WIN32_FIND_DATA-ftCreationTime FILETIME>timestamp ] - [ WIN32_FIND_DATA-ftLastWriteTime FILETIME>timestamp ] - ! [ WIN32_FIND_DATA-ftLastAccessTime FILETIME>timestamp ] - } cleave - \ file-info boa ; + [ WIN32_FIND_DATA-dwFileAttributes >>permissions ] + [ WIN32_FIND_DATA-ftCreationTime FILETIME>timestamp >>created ] + [ WIN32_FIND_DATA-ftLastWriteTime FILETIME>timestamp >>modified ] + [ WIN32_FIND_DATA-ftLastAccessTime FILETIME>timestamp >>accessed ] + } cleave ; : find-first-file-stat ( path -- WIN32_FIND_DATA ) "WIN32_FIND_DATA" [ @@ -168,23 +168,32 @@ SYMBOLS: +read-only+ +hidden+ +system+ ] keep ; : BY_HANDLE_FILE_INFORMATION>file-info ( HANDLE_FILE_INFORMATION -- file-info ) + [ \ file-info new ] dip { - [ BY_HANDLE_FILE_INFORMATION-dwFileAttributes win32-file-type ] + [ BY_HANDLE_FILE_INFORMATION-dwFileAttributes win32-file-type >>type ] [ [ BY_HANDLE_FILE_INFORMATION-nFileSizeLow ] - [ BY_HANDLE_FILE_INFORMATION-nFileSizeHigh ] bi >64bit + [ BY_HANDLE_FILE_INFORMATION-nFileSizeHigh ] bi >64bit >>size + ] + [ BY_HANDLE_FILE_INFORMATION-dwFileAttributes >>permissions ] + [ + BY_HANDLE_FILE_INFORMATION-ftCreationTime + FILETIME>timestamp >>created + ] + [ + BY_HANDLE_FILE_INFORMATION-ftLastWriteTime + FILETIME>timestamp >>modified + ] + [ + BY_HANDLE_FILE_INFORMATION-ftLastAccessTime + FILETIME>timestamp >>accessed ] - [ BY_HANDLE_FILE_INFORMATION-dwFileAttributes ] - ! [ BY_HANDLE_FILE_INFORMATION-ftCreationTime FILETIME>timestamp ] - [ BY_HANDLE_FILE_INFORMATION-ftLastWriteTime FILETIME>timestamp ] - ! [ BY_HANDLE_FILE_INFORMATION-ftLastAccessTime FILETIME>timestamp ] ! [ BY_HANDLE_FILE_INFORMATION-nNumberOfLinks ] ! [ ! [ BY_HANDLE_FILE_INFORMATION-nFileIndexLow ] ! [ BY_HANDLE_FILE_INFORMATION-nFileIndexHigh ] bi >64bit ! ] - } cleave - \ file-info boa ; + } cleave ; : get-file-information ( handle -- BY_HANDLE_FILE_INFORMATION ) [ diff --git a/basis/io/windows/files/unique/unique.factor b/basis/io/windows/files/unique/unique.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/launcher/launcher-tests.factor b/basis/io/windows/launcher/launcher-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/launcher/launcher.factor b/basis/io/windows/launcher/launcher.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/mmap/mmap.factor b/basis/io/windows/mmap/mmap.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/nt/backend/backend.factor b/basis/io/windows/nt/backend/backend.factor old mode 100755 new mode 100644 index 7fbc1dbcf9..73b77508b7 --- a/basis/io/windows/nt/backend/backend.factor +++ b/basis/io/windows/nt/backend/backend.factor @@ -1,9 +1,9 @@ USING: alien alien.c-types arrays assocs combinators continuations destructors io io.backend io.ports io.timeouts -io.windows io.windows.files libc kernel math namespaces -sequences threads windows windows.errors windows.kernel32 -strings splitting io.files io.buffers qualified ascii system -accessors locals ; +io.windows io.windows.files io.files io.buffers io.streams.c +libc kernel math namespaces sequences threads windows +windows.errors windows.kernel32 strings splitting qualified +ascii system accessors locals ; QUALIFIED: windows.winsock IN: io.windows.nt.backend @@ -120,3 +120,5 @@ M: winnt (wait-to-read) ( port -- ) [ finish-read ] tri ] with-destructors ; + +M: winnt (init-stdio) init-c-stdio ; diff --git a/basis/io/windows/nt/files/files-tests.factor b/basis/io/windows/nt/files/files-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/nt/files/files.factor b/basis/io/windows/nt/files/files.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/nt/launcher/launcher-tests.factor b/basis/io/windows/nt/launcher/launcher-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/nt/launcher/launcher.factor b/basis/io/windows/nt/launcher/launcher.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/nt/launcher/test/append.factor b/basis/io/windows/nt/launcher/test/append.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/nt/launcher/test/env.factor b/basis/io/windows/nt/launcher/test/env.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/nt/launcher/test/stderr.factor b/basis/io/windows/nt/launcher/test/stderr.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/nt/monitors/monitors-tests.factor b/basis/io/windows/nt/monitors/monitors-tests.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/nt/monitors/monitors.factor b/basis/io/windows/nt/monitors/monitors.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/nt/nt.factor b/basis/io/windows/nt/nt.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/nt/pipes/pipes.factor b/basis/io/windows/nt/pipes/pipes.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/nt/privileges/privileges.factor b/basis/io/windows/nt/privileges/privileges.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/nt/sockets/sockets.factor b/basis/io/windows/nt/sockets/sockets.factor old mode 100755 new mode 100644 index 41c5e88f5f..5d94cf2d4a --- a/basis/io/windows/nt/sockets/sockets.factor +++ b/basis/io/windows/nt/sockets/sockets.factor @@ -71,7 +71,7 @@ TUPLE: AcceptEx-args port dwLocalAddressLength dwRemoteAddressLength lpdwBytesReceived lpOverlapped ; : init-accept-buffer ( addr AcceptEx -- ) - swap sockaddr-type heap-size 16 + + swap sockaddr-size 16 + [ >>dwLocalAddressLength ] [ >>dwRemoteAddressLength ] bi dup dwLocalAddressLength>> 2 * malloc &free >>lpOutputBuffer drop ; inline @@ -135,7 +135,7 @@ TUPLE: WSARecvFrom-args port WSARecvFrom-args new swap >>port dup port>> handle>> handle>> >>s - dup port>> addr>> sockaddr-type heap-size + dup port>> addr>> sockaddr-size [ malloc &free >>lpFrom ] [ malloc-int &free >>lpFromLen ] bi make-receive-buffer >>lpBuffers diff --git a/basis/io/windows/privileges/privileges.factor b/basis/io/windows/privileges/privileges.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/sockets/sockets.factor b/basis/io/windows/sockets/sockets.factor old mode 100755 new mode 100644 diff --git a/basis/io/windows/windows.factor b/basis/io/windows/windows.factor old mode 100755 new mode 100644 diff --git a/basis/json/reader/reader.factor b/basis/json/reader/reader.factor old mode 100755 new mode 100644 diff --git a/basis/lcs/lcs-docs.factor b/basis/lcs/lcs-docs.factor old mode 100755 new mode 100644 diff --git a/basis/lcs/lcs-tests.factor b/basis/lcs/lcs-tests.factor old mode 100755 new mode 100644 diff --git a/basis/lcs/lcs.factor b/basis/lcs/lcs.factor old mode 100755 new mode 100644 diff --git a/basis/libc/libc-tests.factor b/basis/libc/libc-tests.factor old mode 100755 new mode 100644 diff --git a/basis/libc/libc.factor b/basis/libc/libc.factor old mode 100755 new mode 100644 diff --git a/basis/listener/listener-docs.factor b/basis/listener/listener-docs.factor old mode 100755 new mode 100644 diff --git a/basis/listener/listener-tests.factor b/basis/listener/listener-tests.factor old mode 100755 new mode 100644 diff --git a/basis/listener/listener.factor b/basis/listener/listener.factor old mode 100755 new mode 100644 diff --git a/basis/locals/locals-docs.factor b/basis/locals/locals-docs.factor index 748c206cc0..eb368936d4 100644 --- a/basis/locals/locals-docs.factor +++ b/basis/locals/locals-docs.factor @@ -65,7 +65,7 @@ HELP: [wlet HELP: :: { $syntax ":: word ( bindings... -- outputs... ) body... ;" } -{ $description "Defines a word with named inputs; it reads stack values into bindings from left to right, then executes the body with those bindings in lexical scope. Any " { $link POSTPONE: [| } ", " { $link POSTPONE: [let } " or " { $link POSTPONE: [wlet } " forms used in the body of the word definition are automatically closure-converted." } +{ $description "Defines a word with named inputs; it reads stack values into bindings from left to right, then executes the body with those bindings in lexical scope." } { $notes "The output names do not affect the word's behavior, however the compiler attempts to check the stack effect as with other definitions." } { $examples "See " { $link POSTPONE: [| } ", " { $link POSTPONE: [let } " and " { $link POSTPONE: [wlet } "." } ; @@ -85,7 +85,7 @@ HELP: MEMO:: { POSTPONE: MEMO: POSTPONE: MEMO:: } related-words ARTICLE: "locals-mutable" "Mutable locals" -"In the list of bindings supplied to " { $link POSTPONE: :: } ", " { $link POSTPONE: [let } ", " { $link POSTPONE: [let* } " or " { $link POSTPONE: [| } ", a mutable binding may be introduced by suffixing its named with " { $snippet "!" } ". Mutable bindings are read by giving their name as usual; the suffix is not part of the binding's name. To write to a mutable binding, use the binding's with the " { $snippet "!" } " suffix." +"In the list of bindings supplied to " { $link POSTPONE: :: } ", " { $link POSTPONE: [let } ", " { $link POSTPONE: [let* } " or " { $link POSTPONE: [| } ", a mutable binding may be introduced by suffixing its named with " { $snippet "!" } ". Mutable bindings are read by giving their name as usual; the suffix is not part of the binding's name. To write to a mutable binding, use the binding's name with the " { $snippet "!" } " suffix." $nl "Here is a example word which outputs a pair of quotations which increment and decrement an internal counter, and then return the new value. The quotations are closed over the counter and each invocation of the word yields new quotations with their unique internal counter:" { $code diff --git a/basis/locals/locals-tests.factor b/basis/locals/locals-tests.factor old mode 100755 new mode 100644 diff --git a/basis/locals/locals.factor b/basis/locals/locals.factor old mode 100755 new mode 100644 index 05ea3cb524..bbcc8a6745 --- a/basis/locals/locals.factor +++ b/basis/locals/locals.factor @@ -421,7 +421,7 @@ M: lambda-macro definition "lambda" word-prop body>> ; M: lambda-macro reset-word - [ f "lambda" set-word-prop ] [ call-next-method ] bi ; + [ call-next-method ] [ f "lambda" set-word-prop ] bi ; INTERSECTION: lambda-method method-body lambda-word ; diff --git a/basis/logging/analysis/analysis.factor b/basis/logging/analysis/analysis.factor old mode 100755 new mode 100644 diff --git a/basis/logging/insomniac/insomniac-docs.factor b/basis/logging/insomniac/insomniac-docs.factor old mode 100755 new mode 100644 diff --git a/basis/logging/insomniac/insomniac.factor b/basis/logging/insomniac/insomniac.factor old mode 100755 new mode 100644 diff --git a/basis/logging/logging-docs.factor b/basis/logging/logging-docs.factor old mode 100755 new mode 100644 diff --git a/basis/logging/logging.factor b/basis/logging/logging.factor old mode 100755 new mode 100644 diff --git a/basis/logging/parser/parser.factor b/basis/logging/parser/parser.factor old mode 100755 new mode 100644 diff --git a/basis/logging/server/server.factor b/basis/logging/server/server.factor old mode 100755 new mode 100644 diff --git a/basis/macros/macros.factor b/basis/macros/macros.factor old mode 100755 new mode 100644 diff --git a/basis/match/match-tests.factor b/basis/match/match-tests.factor old mode 100755 new mode 100644 diff --git a/basis/match/match.factor b/basis/match/match.factor old mode 100755 new mode 100644 diff --git a/basis/math/bitwise/bitwise-tests.factor b/basis/math/bitwise/bitwise-tests.factor old mode 100755 new mode 100644 diff --git a/basis/math/complex/complex-docs.factor b/basis/math/complex/complex-docs.factor old mode 100755 new mode 100644 diff --git a/basis/math/complex/complex-tests.factor b/basis/math/complex/complex-tests.factor old mode 100755 new mode 100644 diff --git a/basis/math/complex/complex.factor b/basis/math/complex/complex.factor old mode 100755 new mode 100644 diff --git a/basis/math/constants/constants-docs.factor b/basis/math/constants/constants-docs.factor old mode 100755 new mode 100644 diff --git a/basis/math/constants/constants.factor b/basis/math/constants/constants.factor old mode 100755 new mode 100644 diff --git a/basis/math/functions/functions-docs.factor b/basis/math/functions/functions-docs.factor old mode 100755 new mode 100644 diff --git a/basis/math/functions/functions-tests.factor b/basis/math/functions/functions-tests.factor old mode 100755 new mode 100644 diff --git a/basis/math/functions/functions.factor b/basis/math/functions/functions.factor old mode 100755 new mode 100644 diff --git a/basis/math/intervals/intervals-tests.factor b/basis/math/intervals/intervals-tests.factor old mode 100755 new mode 100644 index 7d8d496737..ad2fb53dc4 --- a/basis/math/intervals/intervals-tests.factor +++ b/basis/math/intervals/intervals-tests.factor @@ -1,6 +1,6 @@ USING: math.intervals kernel sequences words math math.order arrays prettyprint tools.test random vocabs combinators -accessors ; +accessors math.constants ; IN: math.intervals.tests [ empty-interval ] [ 2 2 (a,b) ] unit-test diff --git a/basis/math/intervals/intervals.factor b/basis/math/intervals/intervals.factor old mode 100755 new mode 100644 index 7c3bf27e9d..213bfce354 --- a/basis/math/intervals/intervals.factor +++ b/basis/math/intervals/intervals.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2007, 2008 Slava Pestov. +! Copyright (C) 2007, 2008 Slava Pestov, Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. ! Based on Slate's src/unfinished/interval.slate by Brian Rice. USING: accessors kernel sequences arrays math math.order diff --git a/basis/math/libm/libm.factor b/basis/math/libm/libm.factor old mode 100755 new mode 100644 diff --git a/basis/math/ranges/ranges.factor b/basis/math/ranges/ranges.factor old mode 100755 new mode 100644 diff --git a/basis/math/ratios/ratios-docs.factor b/basis/math/ratios/ratios-docs.factor old mode 100755 new mode 100644 diff --git a/basis/math/ratios/ratios-tests.factor b/basis/math/ratios/ratios-tests.factor old mode 100755 new mode 100644 diff --git a/basis/math/ratios/ratios.factor b/basis/math/ratios/ratios.factor old mode 100755 new mode 100644 diff --git a/basis/math/vectors/vectors-docs.factor b/basis/math/vectors/vectors-docs.factor old mode 100755 new mode 100644 diff --git a/basis/math/vectors/vectors.factor b/basis/math/vectors/vectors.factor old mode 100755 new mode 100644 diff --git a/basis/memoize/memoize-docs.factor b/basis/memoize/memoize-docs.factor old mode 100755 new mode 100644 diff --git a/basis/memoize/memoize.factor b/basis/memoize/memoize.factor old mode 100755 new mode 100644 diff --git a/basis/mime-types/mime-types.factor b/basis/mime-types/mime-types.factor old mode 100755 new mode 100644 diff --git a/basis/mirrors/mirrors-docs.factor b/basis/mirrors/mirrors-docs.factor old mode 100755 new mode 100644 diff --git a/basis/mirrors/mirrors-tests.factor b/basis/mirrors/mirrors-tests.factor old mode 100755 new mode 100644 diff --git a/basis/mirrors/mirrors.factor b/basis/mirrors/mirrors.factor old mode 100755 new mode 100644 diff --git a/basis/models/compose/compose-docs.factor b/basis/models/compose/compose-docs.factor old mode 100755 new mode 100644 diff --git a/basis/models/compose/compose-tests.factor b/basis/models/compose/compose-tests.factor old mode 100755 new mode 100644 diff --git a/basis/models/compose/compose.factor b/basis/models/compose/compose.factor old mode 100755 new mode 100644 diff --git a/basis/models/delay/delay-docs.factor b/basis/models/delay/delay-docs.factor old mode 100755 new mode 100644 diff --git a/basis/models/delay/delay.factor b/basis/models/delay/delay.factor old mode 100755 new mode 100644 diff --git a/basis/models/filter/filter-docs.factor b/basis/models/filter/filter-docs.factor old mode 100755 new mode 100644 diff --git a/basis/models/filter/filter-tests.factor b/basis/models/filter/filter-tests.factor old mode 100755 new mode 100644 diff --git a/basis/models/filter/filter.factor b/basis/models/filter/filter.factor old mode 100755 new mode 100644 diff --git a/basis/models/history/history-docs.factor b/basis/models/history/history-docs.factor old mode 100755 new mode 100644 diff --git a/basis/models/history/history-tests.factor b/basis/models/history/history-tests.factor old mode 100755 new mode 100644 diff --git a/basis/models/history/history.factor b/basis/models/history/history.factor old mode 100755 new mode 100644 diff --git a/basis/models/mapping/mapping-tests.factor b/basis/models/mapping/mapping-tests.factor old mode 100755 new mode 100644 diff --git a/basis/models/mapping/mapping.factor b/basis/models/mapping/mapping.factor old mode 100755 new mode 100644 diff --git a/basis/models/models-docs.factor b/basis/models/models-docs.factor old mode 100755 new mode 100644 diff --git a/basis/models/models-tests.factor b/basis/models/models-tests.factor old mode 100755 new mode 100644 diff --git a/basis/models/models.factor b/basis/models/models.factor old mode 100755 new mode 100644 diff --git a/basis/models/range/range-docs.factor b/basis/models/range/range-docs.factor old mode 100755 new mode 100644 diff --git a/basis/models/range/range-tests.factor b/basis/models/range/range-tests.factor old mode 100755 new mode 100644 diff --git a/basis/models/range/range.factor b/basis/models/range/range.factor old mode 100755 new mode 100644 diff --git a/basis/multiline/multiline-tests.factor b/basis/multiline/multiline-tests.factor old mode 100755 new mode 100644 diff --git a/basis/multiline/multiline.factor b/basis/multiline/multiline.factor old mode 100755 new mode 100644 diff --git a/basis/opengl/gl/windows/windows.factor b/basis/opengl/gl/windows/windows.factor old mode 100755 new mode 100644 diff --git a/basis/opengl/opengl.factor b/basis/opengl/opengl.factor old mode 100755 new mode 100644 diff --git a/basis/openssl/libcrypto/libcrypto.factor b/basis/openssl/libcrypto/libcrypto.factor old mode 100755 new mode 100644 diff --git a/basis/openssl/libssl/libssl.factor b/basis/openssl/libssl/libssl.factor old mode 100755 new mode 100644 diff --git a/basis/openssl/openssl-tests.factor b/basis/openssl/openssl-tests.factor old mode 100755 new mode 100644 diff --git a/basis/openssl/openssl.factor b/basis/openssl/openssl.factor old mode 100755 new mode 100644 diff --git a/basis/peg/parsers/parsers-docs.factor b/basis/peg/parsers/parsers-docs.factor old mode 100755 new mode 100644 diff --git a/basis/peg/parsers/parsers.factor b/basis/peg/parsers/parsers.factor old mode 100755 new mode 100644 diff --git a/basis/peg/peg.factor b/basis/peg/peg.factor old mode 100755 new mode 100644 diff --git a/basis/peg/search/search-docs.factor b/basis/peg/search/search-docs.factor old mode 100755 new mode 100644 diff --git a/basis/peg/search/search-tests.factor b/basis/peg/search/search-tests.factor old mode 100755 new mode 100644 diff --git a/basis/peg/search/search.factor b/basis/peg/search/search.factor old mode 100755 new mode 100644 diff --git a/basis/present/present-docs.factor b/basis/present/present-docs.factor index f148d96b32..bda7723173 100644 --- a/basis/present/present-docs.factor +++ b/basis/present/present-docs.factor @@ -8,6 +8,6 @@ ARTICLE: "present" "Converting objects to human-readable strings" HELP: present { $values { "object" object } { "string" string } } { $contract "Outputs a human-readable string from an object." } -{ $notes "New methods can be defined by user code. Most often, this is done so that the object can be used with various words in the " { $link "html.components" } " or " { $link "urls" } " vocabularies." } ; +{ $notes "New methods can be defined by user code. Most often, this is done so that the object can be used with various words in the " { $vocab-link "html.components" } " or " { $link "urls" } " vocabularies." } ; ABOUT: "present" diff --git a/basis/prettyprint/backend/backend-docs.factor b/basis/prettyprint/backend/backend-docs.factor old mode 100755 new mode 100644 diff --git a/basis/prettyprint/backend/backend.factor b/basis/prettyprint/backend/backend.factor old mode 100755 new mode 100644 diff --git a/basis/prettyprint/prettyprint-docs.factor b/basis/prettyprint/prettyprint-docs.factor old mode 100755 new mode 100644 diff --git a/basis/prettyprint/prettyprint-tests.factor b/basis/prettyprint/prettyprint-tests.factor old mode 100755 new mode 100644 diff --git a/basis/prettyprint/prettyprint.factor b/basis/prettyprint/prettyprint.factor old mode 100755 new mode 100644 index d41a68f0c4..f63ce44c71 --- a/basis/prettyprint/prettyprint.factor +++ b/basis/prettyprint/prettyprint.factor @@ -229,14 +229,15 @@ M: word declarations. : pprint-; ( -- ) \ ; pprint-word ; -: (see) ( spec -- ) - - dup definer nip [ pprint-word ] when* declarations. - block> ; - M: object see - [ (see) ] with-use nl ; + [ + 12 nesting-limit set + 100 length-limit set + + dup definer nip [ pprint-word ] when* declarations. + block> + ] with-use nl ; GENERIC: see-class* ( word -- ) @@ -324,10 +325,8 @@ M: word see dup class? over symbol? not and [ nl ] when - dup class? over symbol? and not [ - [ dup (see) ] with-use nl - ] when - drop ; + dup [ class? ] [ symbol? ] bi and + [ drop ] [ call-next-method ] if ; : see-all ( seq -- ) natural-sort [ nl ] [ see ] interleave ; diff --git a/basis/prettyprint/sections/sections-docs.factor b/basis/prettyprint/sections/sections-docs.factor old mode 100755 new mode 100644 diff --git a/basis/qualified/qualified-docs.factor b/basis/qualified/qualified-docs.factor old mode 100755 new mode 100644 diff --git a/basis/random/dummy/dummy.factor b/basis/random/dummy/dummy.factor old mode 100755 new mode 100644 diff --git a/basis/random/mersenne-twister/mersenne-twister-tests.factor b/basis/random/mersenne-twister/mersenne-twister-tests.factor old mode 100755 new mode 100644 index 3f0ebf692a..8a2a5031fa --- a/basis/random/mersenne-twister/mersenne-twister-tests.factor +++ b/basis/random/mersenne-twister/mersenne-twister-tests.factor @@ -3,17 +3,17 @@ random.mersenne-twister sequences tools.test math.order ; IN: random.mersenne-twister.tests : check-random ( max -- ? ) - dup >r random 0 r> between? ; + [ random 0 ] keep between? ; [ t ] [ 100 [ drop 674 check-random ] all? ] unit-test -: make-100-randoms - [ 100 [ 100 random , ] times ] { } make ; +: randoms ( -- seq ) + 100 [ 100 random ] replicate ; : test-rng ( seed quot -- ) >r r> with-random ; -[ f ] [ 1234 [ make-100-randoms make-100-randoms = ] test-rng ] unit-test +[ f ] [ 1234 [ randoms randoms = ] test-rng ] unit-test [ 1333075495 ] [ 0 [ 1000 [ drop random-generator get random-32* drop ] each random-generator get random-32* ] test-rng diff --git a/basis/random/mersenne-twister/mersenne-twister.factor b/basis/random/mersenne-twister/mersenne-twister.factor old mode 100755 new mode 100644 diff --git a/basis/random/random-docs.factor b/basis/random/random-docs.factor old mode 100644 new mode 100755 index 74751328d5..18c9ca781c --- a/basis/random/random-docs.factor +++ b/basis/random/random-docs.factor @@ -1,12 +1,6 @@ -USING: help.markup help.syntax math ; +USING: help.markup help.syntax math kernel sequences ; IN: random -ARTICLE: "random-numbers" "Generating random integers" -"The " { $vocab-link "random" } " vocabulary implements the ``Mersenne Twister'' pseudo-random number generator algorithm." -{ $subsection random } ; - -ABOUT: "random-numbers" - HELP: seed-random { $values { "tuple" "a random number generator" } { "seed" "an integer between 0 and 2^32-1" } } { $description "Seed the random number generator." } @@ -21,9 +15,19 @@ HELP: random-bytes* { $description "Generates a byte-array of random bytes." } ; HELP: random -{ $values { "seq" "a sequence" } { "elt" "a random element" } } -{ $description "Outputs a random element of the sequence. If the sequence is empty, always outputs " { $link f } "." } -{ $notes "Since integers are sequences, passing an integer " { $snippet "n" } " yields a random integer in the interval " { $snippet "[0,n)" } "." } ; +{ $values { "seq" sequence } { "elt" "a random element" } } +{ $description "Outputs a random element of the input sequence. Outputs " { $link f } " if the sequence is empty." } +{ $notes "Since integers are sequences, passing an integer " { $snippet "n" } " outputs an integer in the interval " { $snippet "[0,n)" } "." } +{ $examples + { $unchecked-example "USING: random prettyprint ;" + "10 random ." + "3" } + { $unchecked-example "USING: random prettyprint ;" + "SYMBOL: heads" + "SYMBOL: tails" + "{ heads tails } random ." + "heads" } +} ; HELP: random-bytes { $values { "n" "an integer" } { "byte-array" "a random integer" } } @@ -47,4 +51,39 @@ HELP: with-secure-random { $values { "quot" "a quotation" } } { $description "Calls the quotation with the secure random generator in a dynamic variable. All random numbers will be generated using this random generator." } ; -{ with-random with-secure-random } related-words +HELP: with-system-random +{ $values { "quot" "a quotation" } } +{ $description "Calls the quotation with the system's random generator in a dynamic variable. All random numbers will be generated using this random generator." } ; + +{ with-random with-secure-random with-system-random } related-words + +HELP: delete-random +{ $values + { "seq" sequence } + { "elt" object } } +{ $description "Deletes a random number from a sequence using " { $link delete-nth } " and returns the deleted object." } ; + +ARTICLE: "random-protocol" "Random protocol" +"A random number generator must implement one of these two words:" +{ $subsection random-32* } +{ $subsection random-bytes* } +"Optional, to seed a random number generator:" +{ $subsection seed-random } ; + +ARTICLE: "random" "Generating random integers" +"The " { $vocab-link "random" } " vocabulary contains a protocol for generating random or pseudorandom numbers." +$nl +"The ``Mersenne Twister'' pseudorandom number generator algorithm is the default generator stored in " { $link random-generator } "." +$nl +"Generate a random object:" +{ $subsection random } +"Combinators to change the random number generator:" +{ $subsection with-random } +{ $subsection with-system-random } +{ $subsection with-secure-random } +"Implementation:" +{ $subsection "random-protocol" } +"Deleting a random element from a sequence:" +{ $subsection delete-random } ; + +ABOUT: "random" diff --git a/basis/random/random-tests.factor b/basis/random/random-tests.factor index 89c0c02c4a..e686dd7301 100644 --- a/basis/random/random-tests.factor +++ b/basis/random/random-tests.factor @@ -15,3 +15,5 @@ IN: random.tests [ t ] [ 10000 [ 0 [ drop 400 random + ] reduce ] keep / 2 * 400 10 ~ ] unit-test [ t ] [ 1000 [ 400 random ] replicate prune length 256 > ] unit-test + +[ f ] [ 0 random ] unit-test diff --git a/basis/random/random.factor b/basis/random/random.factor index 5ee45e6729..845f8e004f 100755 --- a/basis/random/random.factor +++ b/basis/random/random.factor @@ -33,19 +33,24 @@ M: f random-32* ( obj -- * ) no-random-number-generator ; random-generator get random-bytes* ] keep head ; +bignum ] + [ 3 shift 2^ ] bi / * >integer ; + +PRIVATE> + +: random-bits ( n -- r ) 2^ random-integer ; + : random ( seq -- elt ) [ f ] [ - [ - length dup log2 7 + 8 /i 1+ - [ random-bytes byte-array>bignum ] - [ 3 shift 2^ ] bi / * >integer - ] keep nth + [ length random-integer ] keep nth ] if-empty ; : delete-random ( seq -- elt ) - [ length random ] keep [ nth ] 2keep delete-nth ; - -: random-bits ( n -- r ) 2^ random ; + [ length random-integer ] keep [ nth ] 2keep delete-nth ; : with-random ( tuple quot -- ) random-generator swap with-variable ; inline diff --git a/basis/sequences/deep/deep-tests.factor b/basis/sequences/deep/deep-tests.factor old mode 100755 new mode 100644 diff --git a/basis/sequences/next/next.factor b/basis/sequences/next/next.factor old mode 100755 new mode 100644 diff --git a/basis/serialize/serialize-docs.factor b/basis/serialize/serialize-docs.factor old mode 100755 new mode 100644 diff --git a/basis/serialize/serialize-tests.factor b/basis/serialize/serialize-tests.factor old mode 100755 new mode 100644 diff --git a/basis/serialize/serialize.factor b/basis/serialize/serialize.factor old mode 100755 new mode 100644 diff --git a/basis/shuffle/shuffle-tests.factor b/basis/shuffle/shuffle-tests.factor old mode 100755 new mode 100644 diff --git a/basis/smtp/server/server.factor b/basis/smtp/server/server.factor old mode 100755 new mode 100644 diff --git a/basis/smtp/smtp-tests.factor b/basis/smtp/smtp-tests.factor old mode 100755 new mode 100644 diff --git a/basis/smtp/smtp.factor b/basis/smtp/smtp.factor old mode 100755 new mode 100644 diff --git a/basis/stack-checker/backend/backend.factor b/basis/stack-checker/backend/backend.factor old mode 100755 new mode 100644 diff --git a/basis/stack-checker/known-words/known-words.factor b/basis/stack-checker/known-words/known-words.factor old mode 100755 new mode 100644 diff --git a/basis/stack-checker/stack-checker-docs.factor b/basis/stack-checker/stack-checker-docs.factor old mode 100755 new mode 100644 diff --git a/basis/stack-checker/stack-checker-tests.factor b/basis/stack-checker/stack-checker-tests.factor old mode 100755 new mode 100644 diff --git a/basis/stack-checker/stack-checker.factor b/basis/stack-checker/stack-checker.factor old mode 100755 new mode 100644 diff --git a/basis/stack-checker/state/state.factor b/basis/stack-checker/state/state.factor old mode 100755 new mode 100644 diff --git a/basis/stack-checker/transforms/transforms-docs.factor b/basis/stack-checker/transforms/transforms-docs.factor old mode 100755 new mode 100644 diff --git a/basis/stack-checker/transforms/transforms-tests.factor b/basis/stack-checker/transforms/transforms-tests.factor old mode 100755 new mode 100644 diff --git a/basis/stack-checker/transforms/transforms.factor b/basis/stack-checker/transforms/transforms.factor old mode 100755 new mode 100644 diff --git a/basis/state-parser/state-parser-tests.factor b/basis/state-parser/state-parser-tests.factor old mode 100755 new mode 100644 diff --git a/basis/structs/structs.factor b/basis/structs/structs.factor deleted file mode 100644 index f54917dc47..0000000000 --- a/basis/structs/structs.factor +++ /dev/null @@ -1,12 +0,0 @@ -USING: alien.c-types alien.syntax kernel math ; -IN: structs - -C-STRUCT: timeval - { "long" "sec" } - { "long" "usec" } ; - -: make-timeval ( ms -- timeval ) - 1000 /mod 1000 * - "timeval" - [ set-timeval-usec ] keep - [ set-timeval-sec ] keep ; diff --git a/basis/structs/summary.txt b/basis/structs/summary.txt deleted file mode 100644 index 86d6ad349e..0000000000 --- a/basis/structs/summary.txt +++ /dev/null @@ -1 +0,0 @@ -Cross-platform C structs diff --git a/basis/symbols/symbols-tests.factor b/basis/symbols/symbols-tests.factor old mode 100755 new mode 100644 diff --git a/basis/symbols/symbols.factor b/basis/symbols/symbols.factor old mode 100755 new mode 100644 diff --git a/basis/syndication/syndication-tests.factor b/basis/syndication/syndication-tests.factor old mode 100755 new mode 100644 diff --git a/basis/syndication/syndication.factor b/basis/syndication/syndication.factor index ca7511f1af..aca09b939c 100644 --- a/basis/syndication/syndication.factor +++ b/basis/syndication/syndication.factor @@ -69,11 +69,15 @@ TUPLE: entry title url description date ; [ "item" tags-named [ rss2.0-entry ] map set-entries ] tri ; +: atom-entry-link ( tag -- url/f ) + "link" tags-named [ "rel" swap at "alternate" = ] find nip + dup [ "href" swap at >url ] when ; + : atom1.0-entry ( tag -- entry ) entry new swap { [ "title" tag-named children>string >>title ] - [ "link" tag-named "href" swap at >url >>url ] + [ atom-entry-link >>url ] [ { "content" "summary" } any-tag-named dup children>> [ string? not ] contains? diff --git a/basis/threads/threads-docs.factor b/basis/threads/threads-docs.factor old mode 100755 new mode 100644 diff --git a/basis/threads/threads-tests.factor b/basis/threads/threads-tests.factor old mode 100755 new mode 100644 diff --git a/basis/threads/threads.factor b/basis/threads/threads.factor old mode 100755 new mode 100644 diff --git a/basis/tools/annotations/annotations-docs.factor b/basis/tools/annotations/annotations-docs.factor old mode 100755 new mode 100644 diff --git a/basis/tools/annotations/annotations-tests.factor b/basis/tools/annotations/annotations-tests.factor old mode 100755 new mode 100644 diff --git a/basis/tools/annotations/annotations.factor b/basis/tools/annotations/annotations.factor old mode 100755 new mode 100644 diff --git a/basis/tools/completion/completion.factor b/basis/tools/completion/completion.factor old mode 100755 new mode 100644 diff --git a/basis/tools/crossref/crossref-tests.factor b/basis/tools/crossref/crossref-tests.factor old mode 100755 new mode 100644 diff --git a/basis/tools/crossref/crossref.factor b/basis/tools/crossref/crossref.factor old mode 100755 new mode 100644 diff --git a/basis/tools/crossref/test/foo.factor b/basis/tools/crossref/test/foo.factor old mode 100755 new mode 100644 diff --git a/basis/tools/deploy/backend/backend.factor b/basis/tools/deploy/backend/backend.factor old mode 100755 new mode 100644 index cb899f4b87..a0565c6bab --- a/basis/tools/deploy/backend/backend.factor +++ b/basis/tools/deploy/backend/backend.factor @@ -10,13 +10,15 @@ io.encodings.utf8 destructors accessors ; IN: tools.deploy.backend : copy-vm ( executable bundle-name extension -- vm ) - [ prepend-path ] dip append vm over copy-file ; + [ prepend-path ] dip append vm over copy-file ; : copy-fonts ( name dir -- ) - append-path "resource:fonts/" swap copy-tree-into ; + deploy-ui? get [ + append-path "resource:fonts/" swap copy-tree-into + ] [ 2drop ] if ; : image-name ( vocab bundle-name -- str ) - prepend-path ".image" append ; + prepend-path ".image" append ; : copy-lines ( -- ) readln [ print flush copy-lines ] when* ; diff --git a/basis/tools/deploy/config/config-docs.factor b/basis/tools/deploy/config/config-docs.factor old mode 100755 new mode 100644 diff --git a/basis/tools/deploy/config/config.factor b/basis/tools/deploy/config/config.factor old mode 100755 new mode 100644 diff --git a/basis/tools/deploy/deploy-docs.factor b/basis/tools/deploy/deploy-docs.factor old mode 100755 new mode 100644 diff --git a/basis/tools/deploy/deploy-tests.factor b/basis/tools/deploy/deploy-tests.factor old mode 100755 new mode 100644 index 1d5b59bf0c..db4255cdb1 --- a/basis/tools/deploy/deploy-tests.factor +++ b/basis/tools/deploy/deploy-tests.factor @@ -66,7 +66,7 @@ http.server.responses http.server.static io.servers.connection ; SINGLETON: quit-responder M: quit-responder call-responder* - 2drop stop-server "Goodbye" "text/html" ; + 2drop stop-this-server "Goodbye" "text/html" ; : add-quot-responder ( responder -- responder ) quit-responder "quit" add-responder ; diff --git a/basis/tools/deploy/deploy.factor b/basis/tools/deploy/deploy.factor old mode 100755 new mode 100644 diff --git a/basis/tools/deploy/macosx/macosx.factor b/basis/tools/deploy/macosx/macosx.factor old mode 100755 new mode 100644 index ee60ce3982..d3464993e1 --- a/basis/tools/deploy/macosx/macosx.factor +++ b/basis/tools/deploy/macosx/macosx.factor @@ -4,7 +4,7 @@ USING: io io.files kernel namespaces make sequences system tools.deploy.backend tools.deploy.config assocs hashtables prettyprint io.unix.backend cocoa io.encodings.utf8 io.backend cocoa.application cocoa.classes cocoa.plists -qualified ; +qualified combinators ; IN: tools.deploy.macosx : bundle-dir ( -- dir ) @@ -30,12 +30,26 @@ IN: tools.deploy.macosx "Contents/Info.plist" append-path write-plist ; +: copy-dll ( bundle-name -- ) + "Frameworks/libfactor.dylib" copy-bundle-dir ; + +: copy-freetype ( bundle-name -- ) + deploy-ui? get [ "Frameworks" copy-bundle-dir ] [ drop ] if ; + +: copy-nib ( bundle-name -- ) + deploy-ui? get [ + "Resources/English.lproj/MiniFactor.nib" copy-bundle-dir + ] [ drop ] if ; + : create-app-dir ( vocab bundle-name -- vm ) [ - nip - [ "Frameworks" copy-bundle-dir ] - [ "Resources/English.lproj/MiniFactor.nib" copy-bundle-dir ] - [ "Contents/Resources/" copy-fonts ] tri + nip { + [ copy-dll ] + [ copy-freetype ] + [ copy-nib ] + [ "Contents/Resources/" copy-fonts ] + [ "Contents/Resources" append-path make-directories ] + } cleave ] [ create-app-plist ] [ "Contents/MacOS/" append-path "" copy-vm ] 2tri ; diff --git a/basis/tools/deploy/shaker/shaker.factor b/basis/tools/deploy/shaker/shaker.factor index f8b0862c9d..d9348bedd5 100755 --- a/basis/tools/deploy/shaker/shaker.factor +++ b/basis/tools/deploy/shaker/shaker.factor @@ -1,20 +1,18 @@ ! Copyright (C) 2007, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors qualified io.streams.c init fry namespaces make -assocs kernel parser lexer strings.parser tools.deploy.config -vocabs sequences words words.private memory kernel.private -continuations io prettyprint vocabs.loader debugger system -strings sets vectors quotations byte-arrays sorting ; +USING: accessors qualified io.backend io.streams.c init fry +namespaces make assocs kernel parser lexer strings.parser +tools.deploy.config vocabs sequences words words.private memory +kernel.private continuations io prettyprint vocabs.loader +debugger system strings sets vectors quotations byte-arrays +sorting compiler.units definitions ; QUALIFIED: bootstrap.stage2 QUALIFIED: classes QUALIFIED: command-line QUALIFIED: compiler.errors.private -QUALIFIED: compiler.units QUALIFIED: continuations QUALIFIED: definitions QUALIFIED: init -QUALIFIED: io.backend -QUALIFIED: io.thread QUALIFIED: layouts QUALIFIED: listener QUALIFIED: prettyprint.config @@ -87,8 +85,8 @@ IN: tools.deploy.shaker ] change-props drop ] each ] [ - "Remaining word properties:" print - [ props>> keys ] gather . + "Remaining word properties:\n" show + [ props>> keys ] gather unparse show ] [ H{ } clone '[ [ [ _ [ ] cache ] map ] change-props drop @@ -198,11 +196,6 @@ IN: tools.deploy.shaker strip-word-names? [ dup strip-word-names ] when 2drop ; -: strip-recompile-hook ( -- ) - [ [ f ] { } map>assoc ] - compiler.units:recompile-hook - set-global ; - : strip-vocab-globals ( except names -- words ) [ child-vocabs [ words ] map concat ] map concat swap diff ; @@ -220,20 +213,21 @@ IN: tools.deploy.shaker continuations:restarts listener:error-hook init:init-hooks - io.thread:io-thread source-files:source-files input-stream output-stream error-stream } % + "io-thread" "io.thread" lookup , + "mallocs" "libc.private" lookup , deploy-threads? [ "initial-thread" "threads" lookup , ] unless - strip-io? [ io.backend:io-backend , ] when + strip-io? [ io-backend , ] when { } { "alarms" @@ -260,9 +254,9 @@ IN: tools.deploy.shaker command-line:main-vocab-hook compiled-crossref compiled-generic-crossref - compiler.units:recompile-hook - compiler.units:update-tuples-hook - compiler.units:definition-observers + recompile-hook + update-tuples-hook + definition-observers definitions:crossref interactive-vocabs layouts:num-tags @@ -326,6 +320,14 @@ IN: tools.deploy.shaker 21 setenv ] [ drop ] if ; +: strip-c-io ( -- ) + deploy-io get 2 = os windows? or [ + [ + c-io-backend forget + "io.streams.c" forget-vocab + ] with-compilation-unit + ] unless ; + : compress ( pred string -- ) "Compressing " prepend show instances @@ -358,22 +360,29 @@ SYMBOL: deploy-vocab init-hooks get values concat % , strip-io? [ \ flush , ] unless - ] [ ] make "Boot quotation: " write dup . flush + ] [ ] make "Boot quotation: " show dup unparse show set-boot-quot ; +: init-stripper ( -- ) + t "quiet" set-global + f output-stream set-global ; + : strip ( -- ) + init-stripper strip-libc strip-cocoa strip-debugger - strip-recompile-hook strip-init-hooks + strip-c-io + f 5 setenv ! we can't use the Factor debugger or Factor I/O anymore deploy-vocab get vocab-main set-boot-quot* stripped-word-props >r stripped-globals strip-globals r> strip-words compress-byte-arrays compress-quotations - compress-strings ; + compress-strings + H{ } clone classes:next-method-quot-cache set-global ; : (deploy) ( final-image vocab config -- ) #! Does the actual work of a deployment in the slave diff --git a/basis/tools/deploy/shaker/strip-cocoa.factor b/basis/tools/deploy/shaker/strip-cocoa.factor old mode 100755 new mode 100644 index 2cf803e270..d5249dc20c --- a/basis/tools/deploy/shaker/strip-cocoa.factor +++ b/basis/tools/deploy/shaker/strip-cocoa.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: cocoa cocoa.messages cocoa.application cocoa.nibs assocs namespaces kernel kernel.private words compiler.units sequences -ui ui.cocoa init ; +init vocabs ; IN: tools.deploy.shaker.cocoa : pool ( obj -- obj' ) \ pool get [ ] cache ; @@ -23,9 +23,12 @@ IN: cocoa.application H{ } clone \ pool [ global [ - stop-after-last-window? set + "stop-after-last-window?" "ui" lookup set - [ "MiniFactor.nib" load-nib ] cocoa-init-hook set-global + "ui.cocoa" vocab [ + [ "MiniFactor.nib" load-nib ] + "cocoa-init-hook" "ui.cocoa" lookup set-global + ] when ! Only keeps those methods that we actually call sent-messages get super-sent-messages get assoc-union diff --git a/basis/tools/deploy/shaker/strip-debugger.factor b/basis/tools/deploy/shaker/strip-debugger.factor old mode 100755 new mode 100644 index 2302b61715..bdcc6c237e --- a/basis/tools/deploy/shaker/strip-debugger.factor +++ b/basis/tools/deploy/shaker/strip-debugger.factor @@ -1,8 +1,14 @@ -USING: kernel threads threads.private ; +USING: compiler.units words vocabs kernel threads.private ; IN: debugger : print-error ( error -- ) die drop ; : error. ( error -- ) die drop ; -M: thread error-in-thread ( error thread -- ) die 2drop ; +"threads" vocab [ + [ + "error-in-thread" "threads" lookup + [ die 2drop ] + define + ] with-compilation-unit +] when diff --git a/basis/tools/deploy/shaker/strip-libc.factor b/basis/tools/deploy/shaker/strip-libc.factor old mode 100755 new mode 100644 diff --git a/basis/tools/deploy/test/1/1.factor b/basis/tools/deploy/test/1/1.factor old mode 100755 new mode 100644 diff --git a/basis/tools/deploy/test/1/deploy.factor b/basis/tools/deploy/test/1/deploy.factor old mode 100755 new mode 100644 diff --git a/basis/tools/deploy/test/2/2.factor b/basis/tools/deploy/test/2/2.factor old mode 100755 new mode 100644 diff --git a/basis/tools/deploy/test/2/deploy.factor b/basis/tools/deploy/test/2/deploy.factor old mode 100755 new mode 100644 diff --git a/basis/tools/deploy/test/3/3.factor b/basis/tools/deploy/test/3/3.factor old mode 100755 new mode 100644 diff --git a/basis/tools/deploy/test/3/deploy.factor b/basis/tools/deploy/test/3/deploy.factor old mode 100755 new mode 100644 diff --git a/basis/tools/deploy/test/6/deploy.factor b/basis/tools/deploy/test/6/deploy.factor index 410bb770be..e7d3764d39 100644 --- a/basis/tools/deploy/test/6/deploy.factor +++ b/basis/tools/deploy/test/6/deploy.factor @@ -1,15 +1,15 @@ USING: tools.deploy.config ; H{ - { deploy-threads? f } - { deploy-ui? f } - { deploy-io 1 } - { deploy-c-types? f } - { deploy-name "tools.deploy.test.6" } - { deploy-compiler? t } { deploy-reflection 1 } { deploy-word-props? f } + { deploy-io 1 } + { deploy-name "tools.deploy.test.6" } + { deploy-math? t } + { deploy-random? f } + { deploy-compiler? t } + { deploy-ui? f } + { deploy-c-types? f } { deploy-word-defs? f } { "stop-after-last-window?" t } - { deploy-random? f } - { deploy-math? f } + { deploy-threads? f } } diff --git a/basis/tools/deploy/windows/windows-tests.factor b/basis/tools/deploy/windows/windows-tests.factor old mode 100755 new mode 100644 diff --git a/basis/tools/deploy/windows/windows.factor b/basis/tools/deploy/windows/windows.factor index e0ce2c268a..ad1b3cbd84 100755 --- a/basis/tools/deploy/windows/windows.factor +++ b/basis/tools/deploy/windows/windows.factor @@ -5,16 +5,23 @@ tools.deploy.backend tools.deploy.config assocs hashtables prettyprint combinators windows.shell32 windows.user32 ; IN: tools.deploy.windows -: copy-dlls ( bundle-name -- ) - { - "resource:freetype6.dll" - "resource:zlib1.dll" - "resource:factor.dll" - } swap copy-files-into ; +: copy-dll ( bundle-name -- ) + "resource:factor.dll" swap copy-file-into ; + +: copy-freetype ( bundle-name -- ) + deploy-ui? get [ + { + "resource:freetype6.dll" + "resource:zlib1.dll" + } swap copy-files-into + ] [ drop ] if ; : create-exe-dir ( vocab bundle-name -- vm ) - dup copy-dlls - dup "" copy-fonts + deploy-ui? get [ + dup copy-dll + dup copy-freetype + dup "" copy-fonts + ] when ".exe" copy-vm ; M: winnt deploy* diff --git a/basis/tools/disassembler/disassembler-docs.factor b/basis/tools/disassembler/disassembler-docs.factor old mode 100755 new mode 100644 diff --git a/basis/tools/disassembler/disassembler-tests.factor b/basis/tools/disassembler/disassembler-tests.factor old mode 100755 new mode 100644 diff --git a/basis/tools/disassembler/disassembler.factor b/basis/tools/disassembler/disassembler.factor old mode 100755 new mode 100644 diff --git a/basis/tools/memory/memory-docs.factor b/basis/tools/memory/memory-docs.factor old mode 100755 new mode 100644 diff --git a/basis/tools/memory/memory.factor b/basis/tools/memory/memory.factor old mode 100755 new mode 100644 diff --git a/basis/tools/profiler/profiler-docs.factor b/basis/tools/profiler/profiler-docs.factor old mode 100755 new mode 100644 diff --git a/basis/tools/profiler/profiler-tests.factor b/basis/tools/profiler/profiler-tests.factor old mode 100755 new mode 100644 diff --git a/basis/tools/profiler/profiler.factor b/basis/tools/profiler/profiler.factor old mode 100755 new mode 100644 diff --git a/basis/tools/scaffold/scaffold-docs.factor b/basis/tools/scaffold/scaffold-docs.factor index e22e10f8c9..d2989d3cac 100644 --- a/basis/tools/scaffold/scaffold-docs.factor +++ b/basis/tools/scaffold/scaffold-docs.factor @@ -5,7 +5,7 @@ IN: tools.scaffold HELP: developer-name { $description "Set this symbol to hold your name so that the scaffold tools can generate the correct file header for copyright. Setting this variable in your .factor-boot-rc file is recommended." } -{ $unchecked-example "USING: namespaces tools.scaffold ;\n\"Stacky Guy\" developer-name set-global" } ; +{ $code "USING: namespaces tools.scaffold ;\n\"Stacky Guy\" developer-name set-global" } ; HELP: help. { $values @@ -13,8 +13,7 @@ HELP: help. { $description "Prints out scaffold help markup for a given word." } ; HELP: scaffold-help -{ $values - { "vocab-root" "a vocabulary root string" } { "string" string } } +{ $values { "string" string } } { $description "Takes an existing vocabulary and creates a help file with scaffolded help for each word. This word only works if no help file yet exists." } ; HELP: scaffold-undocumented diff --git a/basis/tools/scaffold/scaffold.factor b/basis/tools/scaffold/scaffold.factor index d8d35ebf31..17eafa91c6 100644 --- a/basis/tools/scaffold/scaffold.factor +++ b/basis/tools/scaffold/scaffold.factor @@ -217,9 +217,9 @@ PRIVATE> : help. ( word -- ) [ (help.) ] [ nl vocabulary>> link-vocab ] bi ; -: scaffold-help ( vocab-root string -- ) +: scaffold-help ( string -- ) [ - check-vocab + [ find-vocab-root ] [ check-vocab ] bi prepare-scaffold [ "-docs.factor" scaffold-path ] dip swap [ set-scaffold-help-file ] [ 2drop ] if diff --git a/basis/tools/test/test-docs.factor b/basis/tools/test/test-docs.factor old mode 100755 new mode 100644 diff --git a/basis/tools/test/test.factor b/basis/tools/test/test.factor old mode 100755 new mode 100644 diff --git a/basis/tools/test/ui/ui.factor b/basis/tools/test/ui/ui.factor old mode 100755 new mode 100644 diff --git a/basis/tools/threads/threads.factor b/basis/tools/threads/threads.factor old mode 100755 new mode 100644 diff --git a/basis/tools/time/time-docs.factor b/basis/tools/time/time-docs.factor old mode 100755 new mode 100644 diff --git a/basis/tools/vocabs/browser/browser-docs.factor b/basis/tools/vocabs/browser/browser-docs.factor old mode 100755 new mode 100644 diff --git a/basis/tools/vocabs/browser/browser-tests.factor b/basis/tools/vocabs/browser/browser-tests.factor old mode 100755 new mode 100644 diff --git a/basis/tools/vocabs/browser/browser.factor b/basis/tools/vocabs/browser/browser.factor old mode 100755 new mode 100644 diff --git a/basis/tools/vocabs/monitor/monitor.factor b/basis/tools/vocabs/monitor/monitor.factor old mode 100755 new mode 100644 diff --git a/basis/tools/vocabs/vocabs-docs.factor b/basis/tools/vocabs/vocabs-docs.factor old mode 100755 new mode 100644 diff --git a/basis/tools/vocabs/vocabs.factor b/basis/tools/vocabs/vocabs.factor old mode 100755 new mode 100644 diff --git a/basis/tools/walker/debug/debug.factor b/basis/tools/walker/debug/debug.factor old mode 100755 new mode 100644 diff --git a/basis/tools/walker/walker-tests.factor b/basis/tools/walker/walker-tests.factor old mode 100755 new mode 100644 diff --git a/basis/tools/walker/walker.factor b/basis/tools/walker/walker.factor old mode 100755 new mode 100644 diff --git a/basis/tuple-arrays/tuple-arrays-tests.factor b/basis/tuple-arrays/tuple-arrays-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/backend/backend.factor b/basis/ui/backend/backend.factor old mode 100755 new mode 100644 diff --git a/basis/ui/cocoa/cocoa.factor b/basis/ui/cocoa/cocoa.factor old mode 100755 new mode 100644 diff --git a/basis/ui/cocoa/tools/tools.factor b/basis/ui/cocoa/tools/tools.factor old mode 100755 new mode 100644 diff --git a/basis/ui/cocoa/views/views.factor b/basis/ui/cocoa/views/views.factor old mode 100755 new mode 100644 diff --git a/basis/ui/commands/commands.factor b/basis/ui/commands/commands.factor old mode 100755 new mode 100644 diff --git a/basis/ui/freetype/freetype-docs.factor b/basis/ui/freetype/freetype-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/freetype/freetype.factor b/basis/ui/freetype/freetype.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/books/books-docs.factor b/basis/ui/gadgets/books/books-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/books/books-tests.factor b/basis/ui/gadgets/books/books-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/books/books.factor b/basis/ui/gadgets/books/books.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/buttons/buttons-docs.factor b/basis/ui/gadgets/buttons/buttons-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/buttons/buttons-tests.factor b/basis/ui/gadgets/buttons/buttons-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/buttons/buttons.factor b/basis/ui/gadgets/buttons/buttons.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/canvas/canvas-tests.factor b/basis/ui/gadgets/canvas/canvas-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/canvas/canvas.factor b/basis/ui/gadgets/canvas/canvas.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/editors/editors-docs.factor b/basis/ui/gadgets/editors/editors-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/editors/editors-tests.factor b/basis/ui/gadgets/editors/editors-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/editors/editors.factor b/basis/ui/gadgets/editors/editors.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/frames/frames-docs.factor b/basis/ui/gadgets/frames/frames-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/gadgets-docs.factor b/basis/ui/gadgets/gadgets-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/gadgets-tests.factor b/basis/ui/gadgets/gadgets-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/gadgets.factor b/basis/ui/gadgets/gadgets.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/grid-lines/grid-lines-docs.factor b/basis/ui/gadgets/grid-lines/grid-lines-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/grid-lines/grid-lines.factor b/basis/ui/gadgets/grid-lines/grid-lines.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/grids/grids-docs.factor b/basis/ui/gadgets/grids/grids-docs.factor old mode 100755 new mode 100644 index 64e14c4961..1c00bedea8 --- a/basis/ui/gadgets/grids/grids-docs.factor +++ b/basis/ui/gadgets/grids/grids-docs.factor @@ -6,7 +6,7 @@ ARTICLE: "ui-grid-layout" "Grid layouts" { $subsection grid } "Creating grids from a fixed set of gadgets:" { $subsection } -"Managing chidren:" +"Managing children:" { $subsection grid-add } { $subsection grid-remove } { $subsection grid-child } ; diff --git a/basis/ui/gadgets/incremental/incremental-docs.factor b/basis/ui/gadgets/incremental/incremental-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/incremental/incremental.factor b/basis/ui/gadgets/incremental/incremental.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/labelled/labelled-docs.factor b/basis/ui/gadgets/labelled/labelled-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/labelled/labelled.factor b/basis/ui/gadgets/labelled/labelled.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/labels/labels-docs.factor b/basis/ui/gadgets/labels/labels-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/labels/labels.factor b/basis/ui/gadgets/labels/labels.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/lists/lists-docs.factor b/basis/ui/gadgets/lists/lists-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/lists/lists.factor b/basis/ui/gadgets/lists/lists.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/menus/menus-docs.factor b/basis/ui/gadgets/menus/menus-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/packs/packs-docs.factor b/basis/ui/gadgets/packs/packs-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/packs/packs.factor b/basis/ui/gadgets/packs/packs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/panes/panes-docs.factor b/basis/ui/gadgets/panes/panes-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/panes/panes-tests.factor b/basis/ui/gadgets/panes/panes-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/panes/panes.factor b/basis/ui/gadgets/panes/panes.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/presentations/presentations-docs.factor b/basis/ui/gadgets/presentations/presentations-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/scrollers/scrollers-docs.factor b/basis/ui/gadgets/scrollers/scrollers-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/scrollers/scrollers-tests.factor b/basis/ui/gadgets/scrollers/scrollers-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/scrollers/scrollers.factor b/basis/ui/gadgets/scrollers/scrollers.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/sliders/sliders-docs.factor b/basis/ui/gadgets/sliders/sliders-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/sliders/sliders.factor b/basis/ui/gadgets/sliders/sliders.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/slots/slots.factor b/basis/ui/gadgets/slots/slots.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/status-bar/status-bar-docs.factor b/basis/ui/gadgets/status-bar/status-bar-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/status-bar/status-bar.factor b/basis/ui/gadgets/status-bar/status-bar.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/theme/theme.factor b/basis/ui/gadgets/theme/theme.factor index 46fa0105a3..5e4a2fbf4c 100644 --- a/basis/ui/gadgets/theme/theme.factor +++ b/basis/ui/gadgets/theme/theme.factor @@ -2,7 +2,8 @@ ! Copyright (C) 2006, 2007 Alex Chapman. ! See http://factorcode.org/license.txt for BSD license. USING: arrays kernel sequences io.styles ui.gadgets ui.render -colors accessors ; +colors colors.gray qualified accessors ; +QUALIFIED: colors IN: ui.gadgets.theme : solid-interior ( gadget color -- gadget ) @@ -12,7 +13,7 @@ IN: ui.gadgets.theme >>boundary ; inline : faint-boundary ( gadget -- gadget ) - gray solid-boundary ; inline + colors:gray solid-boundary ; inline : selection-color ( -- color ) light-purple ; diff --git a/basis/ui/gadgets/tracks/tracks-docs.factor b/basis/ui/gadgets/tracks/tracks-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/viewports/viewports-docs.factor b/basis/ui/gadgets/viewports/viewports-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/viewports/viewports.factor b/basis/ui/gadgets/viewports/viewports.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/worlds/worlds-docs.factor b/basis/ui/gadgets/worlds/worlds-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/gadgets/worlds/worlds.factor b/basis/ui/gadgets/worlds/worlds.factor old mode 100755 new mode 100644 index 1bdc63ed0e..6f901c37ee --- a/basis/ui/gadgets/worlds/worlds.factor +++ b/basis/ui/gadgets/worlds/worlds.factor @@ -101,10 +101,10 @@ world H{ { T{ key-down f { C+ } "c" } [ T{ copy-action } send-action ] } { T{ key-down f { C+ } "v" } [ T{ paste-action } send-action ] } { T{ key-down f { C+ } "a" } [ T{ select-all-action } send-action ] } - { T{ button-down f { C+ } 1 } [ T{ button-down f f 3 } swap resend-button-down ] } - { T{ button-down f { A+ } 1 } [ T{ button-down f f 2 } swap resend-button-down ] } - { T{ button-up f { C+ } 1 } [ T{ button-up f f 3 } swap resend-button-up ] } - { T{ button-up f { A+ } 1 } [ T{ button-up f f 2 } swap resend-button-up ] } + { 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-up f { C+ } 1 } [ drop T{ button-up f f 3 } button-gesture ] } + { T{ button-up f { A+ } 1 } [ drop T{ button-up f f 2 } button-gesture ] } } set-gestures : close-global ( world global -- ) diff --git a/basis/ui/gestures/gestures.factor b/basis/ui/gestures/gestures.factor old mode 100755 new mode 100644 index a1c6adac6e..2a29d32055 --- a/basis/ui/gestures/gestures.factor +++ b/basis/ui/gestures/gestures.factor @@ -249,12 +249,6 @@ SYMBOL: drag-timer : send-action ( world gesture -- ) swap world-focus send-gesture drop ; -: resend-button-down ( gesture world -- ) - hand-loc get-global swap send-button-down ; - -: resend-button-up ( gesture world -- ) - hand-loc get-global swap send-button-up ; - GENERIC: gesture>string ( gesture -- string/f ) : modifiers>string ( modifiers -- string ) diff --git a/basis/ui/operations/operations-tests.factor b/basis/ui/operations/operations-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/operations/operations.factor b/basis/ui/operations/operations.factor old mode 100755 new mode 100644 diff --git a/basis/ui/render/render-docs.factor b/basis/ui/render/render-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/browser/browser-tests.factor b/basis/ui/tools/browser/browser-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/browser/browser.factor b/basis/ui/tools/browser/browser.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/debugger/debugger-docs.factor b/basis/ui/tools/debugger/debugger-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/deploy/deploy-docs.factor b/basis/ui/tools/deploy/deploy-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/deploy/deploy.factor b/basis/ui/tools/deploy/deploy.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/interactor/interactor-docs.factor b/basis/ui/tools/interactor/interactor-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/interactor/interactor-tests.factor b/basis/ui/tools/interactor/interactor-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/interactor/interactor.factor b/basis/ui/tools/interactor/interactor.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/listener/listener-tests.factor b/basis/ui/tools/listener/listener-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/listener/listener.factor b/basis/ui/tools/listener/listener.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/operations/operations.factor b/basis/ui/tools/operations/operations.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/profiler/profiler.factor b/basis/ui/tools/profiler/profiler.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/search/search-tests.factor b/basis/ui/tools/search/search-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/search/search.factor b/basis/ui/tools/search/search.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/tools-docs.factor b/basis/ui/tools/tools-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/tools-tests.factor b/basis/ui/tools/tools-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/tools.factor b/basis/ui/tools/tools.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/traceback/traceback.factor b/basis/ui/tools/traceback/traceback.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/walker/walker-docs.factor b/basis/ui/tools/walker/walker-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/walker/walker-tests.factor b/basis/ui/tools/walker/walker-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/walker/walker.factor b/basis/ui/tools/walker/walker.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/workspace/workspace-tests.factor b/basis/ui/tools/workspace/workspace-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/tools/workspace/workspace.factor b/basis/ui/tools/workspace/workspace.factor old mode 100755 new mode 100644 diff --git a/basis/ui/traverse/traverse-tests.factor b/basis/ui/traverse/traverse-tests.factor old mode 100755 new mode 100644 diff --git a/basis/ui/ui-docs.factor b/basis/ui/ui-docs.factor old mode 100755 new mode 100644 diff --git a/basis/ui/ui.factor b/basis/ui/ui.factor old mode 100755 new mode 100644 diff --git a/basis/ui/windows/windows.factor b/basis/ui/windows/windows.factor old mode 100755 new mode 100644 index 345c73bcb9..3e600d2e3c --- a/basis/ui/windows/windows.factor +++ b/basis/ui/windows/windows.factor @@ -420,15 +420,25 @@ M: windows-ui-backend do-events style 0 ex-style AdjustWindowRectEx win32-error=0/f ; : make-RECT ( world -- RECT ) - dup window-loc>> { 40 40 } vmax dup rot rect-dim v+ + dup window-loc>> dup rot rect-dim v+ "RECT" over first over set-RECT-right swap second over set-RECT-bottom over first over set-RECT-left swap second over set-RECT-top ; +: default-position-RECT ( RECT -- ) + dup get-RECT-dimensions [ 2drop ] 2dip + CW_USEDEFAULT + pick set-RECT-bottom + CW_USEDEFAULT + over set-RECT-right + CW_USEDEFAULT over set-RECT-left + CW_USEDEFAULT swap set-RECT-top ; + : make-adjusted-RECT ( rect -- RECT ) - make-RECT dup adjust-RECT ; + make-RECT + dup get-RECT-top-left [ zero? ] both? swap + dup adjust-RECT + swap [ dup default-position-RECT ] when ; : create-window ( rect -- hwnd ) make-adjusted-RECT diff --git a/basis/ui/x11/x11.factor b/basis/ui/x11/x11.factor old mode 100755 new mode 100644 diff --git a/basis/unicode/breaks/breaks-tests.factor b/basis/unicode/breaks/breaks-tests.factor old mode 100755 new mode 100644 diff --git a/basis/unicode/breaks/breaks.factor b/basis/unicode/breaks/breaks.factor old mode 100755 new mode 100644 index 6aa3e60647..0f2e12119d --- a/basis/unicode/breaks/breaks.factor +++ b/basis/unicode/breaks/breaks.factor @@ -1,3 +1,5 @@ +! Copyright (C) 2008 Daniel Ehrenberg. +! See http://factorcode.org/license.txt for BSD license. USING: combinators.short-circuit unicode.categories kernel math combinators splitting sequences math.parser io.files io assocs arrays namespaces make math.ranges unicode.normalize values diff --git a/basis/unicode/case/case-tests.factor b/basis/unicode/case/case-tests.factor old mode 100755 new mode 100644 diff --git a/basis/unicode/case/case.factor b/basis/unicode/case/case.factor old mode 100755 new mode 100644 index 5e961e2d67..3def7b5f48 --- a/basis/unicode/case/case.factor +++ b/basis/unicode/case/case.factor @@ -1,3 +1,5 @@ +! Copyright (C) 2008 Daniel Ehrenberg. +! See http://factorcode.org/license.txt for BSD license. USING: unicode.data sequences sequences.next namespaces make unicode.normalize math unicode.categories combinators assocs strings splitting kernel accessors ; @@ -70,17 +72,6 @@ SYMBOL: locale ! Just casing locale, or overall? : final-sigma ( string -- string ) HEX: 3A3 over member? [ sigma-map ] when ; -! : map-case ( string string-quot char-quot -- case ) -! [ -! rot [ -! -rot [ -! rot dup special-casing at -! [ -rot drop call % ] -! [ -rot nip call , ] ?if -! ] 2keep -! ] each 2drop -! ] "" make ; inline - : map-case ( string string-quot char-quot -- case ) [ [ diff --git a/basis/unicode/categories/categories.factor b/basis/unicode/categories/categories.factor index 4ba96fb9c4..0464e31b12 100644 --- a/basis/unicode/categories/categories.factor +++ b/basis/unicode/categories/categories.factor @@ -1,3 +1,5 @@ +! Copyright (C) 2008 Daniel Ehrenberg. +! See http://factorcode.org/license.txt for BSD license. USING: unicode.syntax ; IN: unicode.categories diff --git a/basis/unicode/collation/collation-tests.factor b/basis/unicode/collation/collation-tests.factor old mode 100755 new mode 100644 index bf87c6b7da..be6af2d920 --- a/basis/unicode/collation/collation-tests.factor +++ b/basis/unicode/collation/collation-tests.factor @@ -11,11 +11,7 @@ IN: unicode.collation.tests : test-two ( str1 str2 -- ) [ +lt+ ] -rot [ string<=> ] 2curry unit-test ; -: failures - parse-test dup 2 - [ string<=> +lt+ = not ] assoc-filter dup assoc-size ; - -: test-equality +: test-equality ( str1 str2 -- ) { primary= secondary= tertiary= quaternary= } [ execute ] with with each ; diff --git a/basis/unicode/collation/collation.factor b/basis/unicode/collation/collation.factor old mode 100755 new mode 100644 index 8e9e2963a8..7f445b8513 --- a/basis/unicode/collation/collation.factor +++ b/basis/unicode/collation/collation.factor @@ -1,3 +1,5 @@ +! Copyright (C) 2008 Daniel Ehrenberg. +! See http://factorcode.org/license.txt for BSD license. USING: combinators.short-circuit sequences io.files io.encodings.ascii kernel values splitting accessors math.parser ascii io assocs strings math namespaces make sorting combinators @@ -100,8 +102,8 @@ ducet insert-helpers ] { } map-as concat ; : append-weights ( weights quot -- ) - swap [ ignorable?>> not ] filter - swap map [ zero? not ] filter % 0 , ; + [ [ ignorable?>> not ] filter ] dip + map [ zero? not ] filter % 0 , ; inline : variable-weight ( weight -- ) dup ignorable?>> [ primary>> ] [ drop HEX: FFFF ] if , ; @@ -135,7 +137,7 @@ PRIVATE> @@ -158,8 +160,7 @@ PRIVATE> PRIVATE> : sort-strings ( strings -- sorted ) - [ w/collation-key ] map - natural-sort values ; + [ w/collation-key ] map natural-sort values ; : string<=> ( str1 str2 -- <=> ) [ w/collation-key ] compare ; diff --git a/basis/unicode/data/data.factor b/basis/unicode/data/data.factor old mode 100755 new mode 100644 index cd54b93f2a..31d0be799f --- a/basis/unicode/data/data.factor +++ b/basis/unicode/data/data.factor @@ -1,3 +1,5 @@ +! Copyright (C) 2008 Daniel Ehrenberg. +! See http://factorcode.org/license.txt for BSD license. USING: combinators.short-circuit assocs math kernel sequences io.files hashtables quotations splitting grouping arrays math.parser hash2 math.order byte-arrays words namespaces words diff --git a/basis/unicode/normalize/normalize-tests.factor b/basis/unicode/normalize/normalize-tests.factor old mode 100755 new mode 100644 diff --git a/basis/unicode/normalize/normalize.factor b/basis/unicode/normalize/normalize.factor old mode 100755 new mode 100644 index 53a38faed4..8d6f6e888a --- a/basis/unicode/normalize/normalize.factor +++ b/basis/unicode/normalize/normalize.factor @@ -1,3 +1,5 @@ +! Copyright (C) 2008 Daniel Ehrenberg. +! See http://factorcode.org/license.txt for BSD license. USING: sequences namespaces make unicode.data kernel math arrays locals sorting.insertion accessors ; IN: unicode.normalize diff --git a/basis/unicode/script/script-docs.factor b/basis/unicode/script/script-docs.factor old mode 100755 new mode 100644 diff --git a/basis/unicode/script/script-tests.factor b/basis/unicode/script/script-tests.factor old mode 100755 new mode 100644 diff --git a/basis/unicode/script/script.factor b/basis/unicode/script/script.factor old mode 100755 new mode 100644 index 103beb4d2a..9691797128 --- a/basis/unicode/script/script.factor +++ b/basis/unicode/script/script.factor @@ -1,3 +1,5 @@ +! Copyright (C) 2008 Daniel Ehrenberg. +! See http://factorcode.org/license.txt for BSD license. USING: accessors values kernel sequences assocs io.files io.encodings ascii math.ranges io splitting math.parser namespaces make byte-arrays locals math sets io.encodings.ascii diff --git a/basis/unicode/syntax/syntax.factor b/basis/unicode/syntax/syntax.factor old mode 100755 new mode 100644 index 1ba76fd380..bf4610ab0d --- a/basis/unicode/syntax/syntax.factor +++ b/basis/unicode/syntax/syntax.factor @@ -1,3 +1,5 @@ +! Copyright (C) 2008 Daniel Ehrenberg. +! See http://factorcode.org/license.txt for BSD license. USING: unicode.data kernel math sequences parser lexer bit-arrays namespaces make sequences.private arrays quotations assocs classes.predicate math.order eval ; diff --git a/basis/unix/bsd/bsd.factor b/basis/unix/bsd/bsd.factor old mode 100755 new mode 100644 index 6934d5b8dc..7bbf2b4fdf --- a/basis/unix/bsd/bsd.factor +++ b/basis/unix/bsd/bsd.factor @@ -48,6 +48,19 @@ C-STRUCT: sockaddr-un { "uchar" "family" } { { "char" 104 } "path" } ; +C-STRUCT: passwd + { "char*" "pw_name" } + { "char*" "pw_passwd" } + { "uid_t" "pw_uid" } + { "gid_t" "pw_gid" } + { "time_t" "pw_change" } + { "char*" "pw_class" } + { "char*" "pw_gecos" } + { "char*" "pw_dir" } + { "char*" "pw_shell" } + { "time_t" "pw_expire" } + { "int" "pw_fields" } ; + : max-un-path 104 ; inline : SOCK_STREAM 1 ; inline diff --git a/basis/unix/bsd/macosx/macosx.factor b/basis/unix/bsd/macosx/macosx.factor index 6582d29687..c41ae6df7d 100644 --- a/basis/unix/bsd/macosx/macosx.factor +++ b/basis/unix/bsd/macosx/macosx.factor @@ -1,4 +1,4 @@ -USING: alien.syntax ; +USING: alien.syntax unix.time ; IN: unix : FD_SETSIZE 1024 ; inline @@ -13,19 +13,6 @@ C-STRUCT: addrinfo { "void*" "addr" } { "addrinfo*" "next" } ; -C-STRUCT: passwd - { "char*" "pw_name" } - { "char*" "pw_passwd" } - { "uid_t" "pw_uid" } - { "gid_t" "pw_gid" } - { "time_t" "pw_change" } - { "char*" "pw_class" } - { "char*" "pw_gecos" } - { "char*" "pw_dir" } - { "char*" "pw_shell" } - { "time_t" "pw_expire" } - { "int" "pw_fields" } ; - : EPERM 1 ; inline : ENOENT 2 ; inline : ESRCH 3 ; inline @@ -130,3 +117,18 @@ C-STRUCT: passwd : ETIME 101 ; inline : EOPNOTSUPP 102 ; inline : ENOPOLICY 103 ; inline + +: _UTX_USERSIZE 256 ; inline +: _UTX_LINESIZE 32 ; inline +: _UTX_IDSIZE 4 ; inline +: _UTX_HOSTSIZE 256 ; inline + +C-STRUCT: utmpx + { { "char" _UTX_USERSIZE } "ut_user" } + { { "char" _UTX_IDSIZE } "ut_id" } + { { "char" _UTX_LINESIZE } "ut_line" } + { "pid_t" "ut_pid" } + { "short" "ut_type" } + { "timeval" "ut_tv" } + { { "char" _UTX_HOSTSIZE } "ut_host" } + { { "uint" 16 } "ut_pad" } ; diff --git a/basis/unix/bsd/netbsd/netbsd.factor b/basis/unix/bsd/netbsd/netbsd.factor index e646f87116..ca42b7840c 100644 --- a/basis/unix/bsd/netbsd/netbsd.factor +++ b/basis/unix/bsd/netbsd/netbsd.factor @@ -1,4 +1,4 @@ -USING: alien.syntax ; +USING: alien.syntax alien.c-types math vocabs.loader ; IN: unix : FD_SETSIZE 256 ; inline @@ -111,3 +111,24 @@ C-STRUCT: addrinfo : ENOLINK 95 ; inline : EPROTO 96 ; inline : ELAST 96 ; inline + +TYPEDEF: __uint8_t sa_family_t + +: _UTX_USERSIZE 32 ; inline +: _UTX_LINESIZE 32 ; inline +: _UTX_IDSIZE 4 ; inline +: _UTX_HOSTSIZE 256 ; inline + +: _SS_MAXSIZE ( -- n ) + 128 ; inline + +: _SS_ALIGNSIZE ( -- n ) + "__int64_t" heap-size ; inline + +: _SS_PAD1SIZE ( -- n ) + _SS_ALIGNSIZE 2 - ; inline + +: _SS_PAD2SIZE ( -- n ) + _SS_MAXSIZE 2 - _SS_PAD1SIZE - _SS_ALIGNSIZE - ; inline + +"unix.bsd.netbsd.structs" require diff --git a/basis/unix/bsd/netbsd/structs/structs.factor b/basis/unix/bsd/netbsd/structs/structs.factor new file mode 100644 index 0000000000..dba7590a93 --- /dev/null +++ b/basis/unix/bsd/netbsd/structs/structs.factor @@ -0,0 +1,29 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.syntax unix.time ; +IN: unix + +C-STRUCT: sockaddr_storage + { "__uint8_t" "ss_len" } + { "sa_family_t" "ss_family" } + { { "char" _SS_PAD1SIZE } "__ss_pad1" } + { "__int64_t" "__ss_align" } + { { "char" _SS_PAD2SIZE } "__ss_pad2" } ; + +C-STRUCT: exit_struct + { "uint16_t" "e_termination" } + { "uint16_t" "e_exit" } ; + +C-STRUCT: utmpx + { { "char" _UTX_USERSIZE } "ut_user" } + { { "char" _UTX_IDSIZE } "ut_id" } + { { "char" _UTX_LINESIZE } "ut_line" } + { { "char" _UTX_HOSTSIZE } "ut_host" } + { "uint16_t" "ut_session" } + { "uint16_t" "ut_type" } + { "pid_t" "ut_pid" } + { "exit_struct" "ut_exit" } + { "sockaddr_storage" "ut_ss" } + { "timeval" "ut_tv" } + { { "uint32_t" 10 } "ut_pad" } ; + diff --git a/basis/unix/bsd/netbsd/structs/tags.txt b/basis/unix/bsd/netbsd/structs/tags.txt new file mode 100644 index 0000000000..6bf68304bb --- /dev/null +++ b/basis/unix/bsd/netbsd/structs/tags.txt @@ -0,0 +1 @@ +unportable diff --git a/basis/structs/authors.txt b/basis/unix/groups/authors.txt old mode 100755 new mode 100644 similarity index 100% rename from basis/structs/authors.txt rename to basis/unix/groups/authors.txt diff --git a/basis/unix/groups/groups-docs.factor b/basis/unix/groups/groups-docs.factor new file mode 100644 index 0000000000..ef2631ae3f --- /dev/null +++ b/basis/unix/groups/groups-docs.factor @@ -0,0 +1,108 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: help.markup help.syntax io.streams.string kernel quotations sequences strings math ; +IN: unix.groups + +HELP: all-groups +{ $values + + { "seq" sequence } } +{ $description "Returns a sequence of " { $link group } " tuples that are platform-dependent and field for field complete with the Unix " { $link group } " structure." } ; + +HELP: effective-group-id +{ $values + + { "string" string } } +{ $description "Returns the effective group id for the current user." } ; + +HELP: effective-group-name +{ $values + + { "string" string } } +{ $description "Returns the effective group name for the current user." } ; + +HELP: group +{ $description "A platform-specific tuple corresponding to every field from the Unix group struct including the group name, the group id, the group passwd, and a list of users in each group." } ; + +HELP: group-cache +{ $description "A symbol containing a cache of groups returned from " { $link all-groups } " and indexed by group id. Can be more efficient than using the system call words for many group lookups." } ; + +HELP: group-id +{ $values + { "string" string } + { "id" integer } } +{ $description "Returns the group id given a group name." } ; + +HELP: group-name +{ $values + { "id" integer } + { "string" string } } +{ $description "Returns the group name given a group id." } ; + +HELP: group-struct +{ $values + { "obj" object } + { "group" "a group struct" } } +{ $description "Returns an alien group struct to be turned into a group tuple by calling subsequent words." } ; + +HELP: real-group-id +{ $values + + { "id" integer } } +{ $description "Returns the real group id for the current user." } ; + +HELP: real-group-name +{ $values + + { "string" string } } +{ $description "Returns the real group name for the current user." } ; + +HELP: set-effective-group +{ $values + { "obj" object } } +{ $description "Sets the effective group id for the current user." } ; + +HELP: set-real-group +{ $values + { "obj" object } } +{ $description "Sets the real group id for the current user." } ; + +HELP: user-groups +{ $values + { "string/id" "a string or a group id" } + { "seq" sequence } } +{ $description "Returns the sequence of groups to which the user belongs." } ; + +HELP: with-effective-group +{ $values + { "string/id" "a string or a group id" } { "quot" quotation } } +{ $description "Sets the effective group name and calls the quotation. Restors the effective group name on success or on error after the call." } ; + +HELP: with-group-cache +{ $values + { "quot" quotation } } +{ $description "Iterates over the group file using library calls and creates a cache in the " { $link group-cache } " symbol. The cache is a hashtable indexed by group id. When looking up many groups, this approach is much faster than calling system calls." } ; + +HELP: with-real-group +{ $values + { "string/id" "a string or a group id" } { "quot" quotation } } +{ $description "Sets the real group name and calls the quotation. Restores the current group name on success or on error after the call." } ; + +ARTICLE: "unix.groups" "unix.groups" +"The " { $vocab-link "unix.groups" } " vocabulary contains words that return information about Unix groups." +"Listing all groups:" +{ $subsection all-groups } +"Returning a passwd tuple:" +"Real groups:" +{ $subsection real-group-name } +{ $subsection real-group-id } +{ $subsection set-real-group } +"Effective groups:" +{ $subsection effective-group-name } +{ $subsection effective-group-id } +{ $subsection set-effective-group } +"Combinators to change groups:" +{ $subsection with-real-group } +{ $subsection with-effective-group } ; + +ABOUT: "unix.groups" diff --git a/basis/unix/groups/groups-tests.factor b/basis/unix/groups/groups-tests.factor new file mode 100644 index 0000000000..9e7122fc34 --- /dev/null +++ b/basis/unix/groups/groups-tests.factor @@ -0,0 +1,24 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: tools.test unix.groups kernel strings math ; +IN: unix.groups.tests + + +[ ] [ all-groups drop ] unit-test + +\ all-groups must-infer + +[ t ] [ real-group-name string? ] unit-test +[ t ] [ effective-group-name string? ] unit-test + +[ t ] [ real-group-id integer? ] unit-test +[ t ] [ effective-group-id integer? ] unit-test + +[ ] [ real-group-id set-real-group ] unit-test +[ ] [ effective-group-id set-effective-group ] unit-test + +[ ] [ real-group-name [ ] with-real-group ] unit-test +[ ] [ real-group-id [ ] with-real-group ] unit-test + +[ ] [ effective-group-name [ ] with-effective-group ] unit-test +[ ] [ effective-group-id [ ] with-effective-group ] unit-test diff --git a/basis/unix/groups/groups.factor b/basis/unix/groups/groups.factor new file mode 100644 index 0000000000..c3af9cc83d --- /dev/null +++ b/basis/unix/groups/groups.factor @@ -0,0 +1,132 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: alien alien.c-types alien.strings io.encodings.utf8 +io.unix.backend kernel math sequences splitting unix strings +combinators.short-circuit byte-arrays combinators qualified +accessors math.parser fry assocs namespaces continuations +unix.users ; +IN: unix.groups + +QUALIFIED: grouping + +TUPLE: group id name passwd members ; + +SYMBOL: group-cache + +GENERIC: group-struct ( obj -- group ) + +string + [ alien-address "char**" heap-size + ] dip + ] [ ] produce nip ; + +: (group-struct) ( id -- group-struct id group-struct byte-array length void* ) + "group" tuck 4096 + [ ] keep f ; + +M: integer group-struct ( id -- group ) + (group-struct) getgrgid_r io-error ; + +M: string group-struct ( string -- group ) + (group-struct) getgrnam_r 0 = [ (io-error) ] unless ; + +: group-struct>group ( group-struct -- group ) + [ \ group new ] dip + { + [ group-gr_name >>name ] + [ group-gr_passwd >>passwd ] + [ group-gr_gid >>id ] + [ group-members >>members ] + } cleave ; + +PRIVATE> + +: group-name ( id -- string ) + dup group-cache get [ + at + ] [ + group-struct group-gr_name + ] if* + [ nip ] [ number>string ] if* ; + +: group-id ( string -- id ) + group-struct group-gr_gid ; + +groups ( byte-array n -- groups ) + [ 4 grouping:group ] dip head-slice [ *uint group-name ] map ; + +: (user-groups) ( string -- seq ) + #! first group is -1337, legacy unix code + -1337 NGROUPS_MAX [ 4 * ] keep + [ getgrouplist io-error ] 2keep + [ 4 tail-slice ] [ *int 1- ] bi* >groups ; + +PRIVATE> + +GENERIC: user-groups ( string/id -- seq ) + +M: string user-groups ( string -- seq ) + (user-groups) ; + +M: integer user-groups ( id -- seq ) + username (user-groups) ; + +: all-groups ( -- seq ) + [ getgrent dup ] [ group-struct>group ] [ drop ] produce ; + +: with-group-cache ( quot -- ) + all-groups [ [ id>> ] keep ] H{ } map>assoc + group-cache rot with-variable ; inline + +: real-group-id ( -- id ) + getgid ; inline + +: real-group-name ( -- string ) + real-group-id group-name ; inline + +: effective-group-id ( -- string ) + getegid ; inline + +: effective-group-name ( -- string ) + effective-group-id group-name ; inline + +GENERIC: set-real-group ( obj -- ) + +GENERIC: set-effective-group ( obj -- ) + +: with-real-group ( string/id quot -- ) + '[ _ set-real-group @ ] + real-group-id '[ _ set-real-group ] [ ] cleanup ; inline + +: with-effective-group ( string/id quot -- ) + '[ _ set-effective-group @ ] + effective-group-id '[ _ set-effective-group ] [ ] cleanup ; inline + + + +M: string set-real-group ( string -- ) + group-id (set-real-group) ; + +M: integer set-real-group ( id -- ) + (set-real-group) ; + +M: integer set-effective-group ( id -- ) + (set-effective-group) ; + +M: string set-effective-group ( string -- ) + group-id (set-effective-group) ; diff --git a/basis/unix/groups/tags.txt b/basis/unix/groups/tags.txt new file mode 100644 index 0000000000..6bf68304bb --- /dev/null +++ b/basis/unix/groups/tags.txt @@ -0,0 +1 @@ +unportable diff --git a/basis/unix/linux/ifreq/ifreq.factor b/basis/unix/linux/ifreq/ifreq.factor old mode 100755 new mode 100644 diff --git a/basis/unix/linux/linux.factor b/basis/unix/linux/linux.factor old mode 100755 new mode 100644 index 0c08cf0f2b..457d96c7d8 --- a/basis/unix/linux/linux.factor +++ b/basis/unix/linux/linux.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2005, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -IN: unix USING: alien.syntax ; +IN: unix ! Linux. diff --git a/basis/unix/process/process.factor b/basis/unix/process/process.factor old mode 100755 new mode 100644 diff --git a/basis/unix/stat/freebsd/32/32.factor b/basis/unix/stat/freebsd/32/32.factor index a81fc4f02e..3692dea0c0 100644 --- a/basis/unix/stat/freebsd/32/32.factor +++ b/basis/unix/stat/freebsd/32/32.factor @@ -12,9 +12,9 @@ C-STRUCT: stat { "uid_t" "st_uid" } { "gid_t" "st_gid" } { "__dev_t" "st_rdev" } - { "timespec" "st_atim" } - { "timespec" "st_mtim" } - { "timespec" "st_ctim" } + { "timespec" "st_atimespec" } + { "timespec" "st_mtimespec" } + { "timespec" "st_ctimespec" } { "off_t" "st_size" } { "blkcnt_t" "st_blocks" } { "blksize_t" "st_blksize" } @@ -27,4 +27,4 @@ C-STRUCT: stat { "__uint32_t" "pad1" } ; FUNCTION: int stat ( char* pathname, stat* buf ) ; -FUNCTION: int lstat ( char* pathname, stat* buf ) ; \ No newline at end of file +FUNCTION: int lstat ( char* pathname, stat* buf ) ; diff --git a/basis/unix/stat/freebsd/64/64.factor b/basis/unix/stat/freebsd/64/64.factor index 75d51cd6ae..73ba676701 100644 --- a/basis/unix/stat/freebsd/64/64.factor +++ b/basis/unix/stat/freebsd/64/64.factor @@ -12,9 +12,9 @@ C-STRUCT: stat { "uid_t" "st_uid" } { "gid_t" "st_gid" } { "__dev_t" "st_rdev" } - { "timespec" "st_atim" } - { "timespec" "st_mtim" } - { "timespec" "st_ctim" } + { "timespec" "st_atimespec" } + { "timespec" "st_mtimespec" } + { "timespec" "st_ctimespec" } { "off_t" "st_size" } { "blkcnt_t" "st_blocks" } { "blksize_t" "st_blksize" } diff --git a/basis/unix/stat/linux/32/32.factor b/basis/unix/stat/linux/32/32.factor index ed53fab86b..3f6c6ba0e0 100644 --- a/basis/unix/stat/linux/32/32.factor +++ b/basis/unix/stat/linux/32/32.factor @@ -18,9 +18,9 @@ C-STRUCT: stat { "off_t" "st_size" } { "blksize_t" "st_blksize" } { "blkcnt_t" "st_blocks" } - { "timespec" "st_atim" } - { "timespec" "st_mtim" } - { "timespec" "st_ctim" } + { "timespec" "st_atimespec" } + { "timespec" "st_mtimespec" } + { "timespec" "st_ctimespec" } { "ulong" "unused4" } { "ulong" "unused5" } ; @@ -30,4 +30,4 @@ FUNCTION: int __xstat ( int ver, char* pathname, stat* buf ) ; FUNCTION: int __lxstat ( int ver, char* pathname, stat* buf ) ; : stat ( pathname buf -- int ) 3 -rot __xstat ; -: lstat ( pathname buf -- int ) 3 -rot __lxstat ; \ No newline at end of file +: lstat ( pathname buf -- int ) 3 -rot __lxstat ; diff --git a/basis/unix/stat/linux/64/64.factor b/basis/unix/stat/linux/64/64.factor index a374551385..088ab8d339 100644 --- a/basis/unix/stat/linux/64/64.factor +++ b/basis/unix/stat/linux/64/64.factor @@ -17,9 +17,9 @@ C-STRUCT: stat { "off_t" "st_size" } { "blksize_t" "st_blksize" } { "blkcnt_t" "st_blocks" } - { "timespec" "st_atim" } - { "timespec" "st_mtim" } - { "timespec" "st_ctim" } + { "timespec" "st_atimespec" } + { "timespec" "st_mtimespec" } + { "timespec" "st_ctimespec" } { "long" "__unused0" } { "long" "__unused1" } { "long" "__unused2" } ; diff --git a/basis/unix/stat/macosx/macosx.factor b/basis/unix/stat/macosx/macosx.factor index 4d84e38399..b2574b474d 100644 --- a/basis/unix/stat/macosx/macosx.factor +++ b/basis/unix/stat/macosx/macosx.factor @@ -1,21 +1,21 @@ - USING: kernel alien.syntax math ; - IN: unix.stat ! Mac OS X ppc +! stat64 structure C-STRUCT: stat { "dev_t" "st_dev" } - { "ino_t" "st_ino" } { "mode_t" "st_mode" } { "nlink_t" "st_nlink" } + { "ino64_t" "st_ino" } { "uid_t" "st_uid" } { "gid_t" "st_gid" } { "dev_t" "st_rdev" } { "timespec" "st_atimespec" } { "timespec" "st_mtimespec" } { "timespec" "st_ctimespec" } + { "timespec" "st_birthtimespec" } { "off_t" "st_size" } { "blkcnt_t" "st_blocks" } { "blksize_t" "st_blksize" } @@ -25,9 +25,8 @@ C-STRUCT: stat { "__int64_t" "st_qspare0" } { "__int64_t" "st_qspare1" } ; -FUNCTION: int stat ( char* pathname, stat* buf ) ; -FUNCTION: int lstat ( char* pathname, stat* buf ) ; +FUNCTION: int stat64 ( char* pathname, stat* buf ) ; +FUNCTION: int lstat64 ( char* pathname, stat* buf ) ; -: stat-st_atim ( stat -- timespec ) stat-st_atimespec ; -: stat-st_mtim ( stat -- timespec ) stat-st_mtimespec ; -: stat-st_ctim ( stat -- timespec ) stat-st_ctimespec ; +: 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 55f5108c70..d6a60ba5c8 100644 --- a/basis/unix/stat/netbsd/32/32.factor +++ b/basis/unix/stat/netbsd/32/32.factor @@ -11,10 +11,10 @@ C-STRUCT: stat { "uid_t" "st_uid" } { "gid_t" "st_gid" } { "dev_t" "st_rdev" } - { "timespec" "st_atim" } - { "timespec" "st_mtim" } - { "timespec" "st_ctim" } - { "timespec" "st_birthtim" } + { "timespec" "st_atimespec" } + { "timespec" "st_mtimespec" } + { "timespec" "st_ctimespec" } + { "timespec" "st_birthtimespec" } { "off_t" "st_size" } { "blkcnt_t" "st_blocks" } { "blksize_t" "st_blksize" } diff --git a/basis/unix/stat/netbsd/64/64.factor b/basis/unix/stat/netbsd/64/64.factor index 163695b524..1a1f97507c 100644 --- a/basis/unix/stat/netbsd/64/64.factor +++ b/basis/unix/stat/netbsd/64/64.factor @@ -11,16 +11,16 @@ C-STRUCT: stat { "uid_t" "st_uid" } { "gid_t" "st_gid" } { "dev_t" "st_rdev" } - { "timespec" "st_atim" } - { "timespec" "st_mtim" } - { "timespec" "st_ctim" } + { "timespec" "st_atimespec" } + { "timespec" "st_mtimespec" } + { "timespec" "st_ctimespec" } { "off_t" "st_size" } { "blkcnt_t" "st_blocks" } { "blksize_t" "st_blksize" } { "uint32_t" "st_flags" } { "uint32_t" "st_gen" } { "uint32_t" "st_spare0" } - { "timespec" "st_birthtim" } ; + { "timespec" "st_birthtimespec" } ; FUNCTION: int __stat13 ( char* pathname, stat* buf ) ; FUNCTION: int __lstat13 ( char* pathname, stat* buf ) ; diff --git a/basis/unix/stat/openbsd/openbsd.factor b/basis/unix/stat/openbsd/openbsd.factor index decfb0dbb1..f76d4c6e18 100644 --- a/basis/unix/stat/openbsd/openbsd.factor +++ b/basis/unix/stat/openbsd/openbsd.factor @@ -12,16 +12,16 @@ C-STRUCT: stat { "gid_t" "st_gid" } { "dev_t" "st_rdev" } { "int32_t" "st_lspare0" } - { "timespec" "st_atim" } - { "timespec" "st_mtim" } - { "timespec" "st_ctim" } + { "timespec" "st_atimespec" } + { "timespec" "st_mtimespec" } + { "timespec" "st_ctimespec" } { "off_t" "st_size" } { "int64_t" "st_blocks" } { "u_int32_t" "st_blksize" } { "u_int32_t" "st_flags" } { "u_int32_t" "st_gen" } { "int32_t" "st_lspare1" } - { "timespec" "st_birthtim" } + { "timespec" "st_birthtimespec" } { { "int64_t" 2 } "st_qspare" } ; FUNCTION: int stat ( char* pathname, stat* buf ) ; diff --git a/basis/unix/stat/stat.factor b/basis/unix/stat/stat.factor index 2bc60105b4..46fe7d98f9 100644 --- a/basis/unix/stat/stat.factor +++ b/basis/unix/stat/stat.factor @@ -1,12 +1,8 @@ - USING: kernel system combinators alien.syntax alien.c-types - math io.unix.backend vocabs.loader unix ; - +math io.unix.backend vocabs.loader unix ; IN: unix.stat -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! File Types -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! : S_IFMT OCT: 170000 ; ! These bits determine file type. @@ -18,54 +14,24 @@ IN: unix.stat : S_IFLNK OCT: 120000 ; inline ! Symbolic link. : S_IFSOCK OCT: 140000 ; inline ! Socket. -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! File Access Permissions -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -! Read, write, execute/search by owner -: S_IRWXU OCT: 0000700 ; inline ! rwx mask owner -: S_IRUSR OCT: 0000400 ; inline ! r owner -: S_IWUSR OCT: 0000200 ; inline ! w owner -: S_IXUSR OCT: 0000100 ; inline ! x owner -! Read, write, execute/search by group -: S_IRWXG OCT: 0000070 ; inline ! rwx mask group -: S_IRGRP OCT: 0000040 ; inline ! r group -: S_IWGRP OCT: 0000020 ; inline ! w group -: S_IXGRP OCT: 0000010 ; inline ! x group -! Read, write, execute/search by others -: S_IRWXO OCT: 0000007 ; inline ! rwx mask other -: S_IROTH OCT: 0000004 ; inline ! r other -: S_IWOTH OCT: 0000002 ; inline ! w other -: S_IXOTH OCT: 0000001 ; inline ! x other - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - FUNCTION: int chmod ( char* path, mode_t mode ) ; - FUNCTION: int fchmod ( int fd, mode_t mode ) ; - FUNCTION: int mkdir ( char* path, mode_t mode ) ; -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -<< - os - { +<< os { { linux [ "unix.stat.linux" require ] } { macosx [ "unix.stat.macosx" require ] } { freebsd [ "unix.stat.freebsd" require ] } { netbsd [ "unix.stat.netbsd" require ] } { openbsd [ "unix.stat.openbsd" require ] } - } - case ->> -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +} case >> : file-status ( pathname -- stat ) - "stat" dup >r - [ stat ] unix-system-call drop - r> ; + "stat" [ + [ stat ] unix-system-call drop + ] keep ; : link-status ( pathname -- stat ) - "stat" dup >r - [ lstat ] unix-system-call drop - r> ; + "stat" [ + [ lstat ] unix-system-call drop + ] keep ; diff --git a/basis/unix/time/time.factor b/basis/unix/time/time.factor index 4fbb20dca0..c664aa3bfb 100644 --- a/basis/unix/time/time.factor +++ b/basis/unix/time/time.factor @@ -1,9 +1,27 @@ - -USING: kernel alien.syntax alien.c-types math ; - +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel alien.syntax alien.c-types math unix.types ; IN: unix.time -TYPEDEF: uint time_t +C-STRUCT: timeval + { "long" "sec" } + { "long" "usec" } ; + +C-STRUCT: timespec + { "time_t" "sec" } + { "long" "nsec" } ; + +: make-timeval ( ms -- timeval ) + 1000 /mod 1000 * + "timeval" + [ set-timeval-usec ] keep + [ set-timeval-sec ] keep ; + +: make-timespec ( ms -- timespec ) + 1000 /mod 1000000 * + "timespec" + [ set-timespec-nsec ] keep + [ set-timespec-sec ] keep ; C-STRUCT: tm { "int" "sec" } ! Seconds: 0-59 (K&R says 0-61?) @@ -18,16 +36,6 @@ C-STRUCT: tm { "long" "gmtoff" } ! Seconds: 0-59 (K&R says 0-61?) { "char*" "zone" } ; -C-STRUCT: timespec - { "time_t" "sec" } - { "long" "nsec" } ; - -: make-timespec ( ms -- timespec ) - 1000 /mod 1000000 * - "timespec" - [ set-timespec-nsec ] keep - [ set-timespec-sec ] keep ; - FUNCTION: time_t time ( time_t* t ) ; FUNCTION: tm* localtime ( time_t* clock ) ; FUNCTION: int gettimeofday ( timespec* TP, void* TZP ) ; diff --git a/basis/unix/types/freebsd/freebsd.factor b/basis/unix/types/freebsd/freebsd.factor old mode 100755 new mode 100644 diff --git a/basis/unix/types/macosx/macosx.factor b/basis/unix/types/macosx/macosx.factor index 8f9c5082df..156e756641 100644 --- a/basis/unix/types/macosx/macosx.factor +++ b/basis/unix/types/macosx/macosx.factor @@ -22,6 +22,7 @@ TYPEDEF: __uint32_t uid_t TYPEDEF: __uint32_t gid_t TYPEDEF: __int64_t off_t TYPEDEF: __int64_t blkcnt_t +TYPEDEF: __int64_t ino64_t TYPEDEF: __int32_t blksize_t TYPEDEF: long ssize_t TYPEDEF: __int32_t pid_t diff --git a/basis/unix/types/netbsd/32/32.factor b/basis/unix/types/netbsd/32/32.factor old mode 100755 new mode 100644 diff --git a/basis/unix/types/netbsd/64/64.factor b/basis/unix/types/netbsd/64/64.factor old mode 100755 new mode 100644 diff --git a/basis/unix/types/netbsd/netbsd.factor b/basis/unix/types/netbsd/netbsd.factor old mode 100755 new mode 100644 diff --git a/basis/unix/types/openbsd/openbsd.factor b/basis/unix/types/openbsd/openbsd.factor old mode 100755 new mode 100644 diff --git a/basis/unix/types/types.factor b/basis/unix/types/types.factor index 0ac2fa608e..69d07a07f1 100644 --- a/basis/unix/types/types.factor +++ b/basis/unix/types/types.factor @@ -3,6 +3,29 @@ system ; IN: unix.types TYPEDEF: void* caddr_t +TYPEDEF: uint in_addr_t +TYPEDEF: uint socklen_t + +TYPEDEF: char int8_t +TYPEDEF: short int16_t +TYPEDEF: int int32_t +TYPEDEF: longlong int64_t + +TYPEDEF: uchar uint8_t +TYPEDEF: ushort uint16_t +TYPEDEF: uint uint32_t +TYPEDEF: ulonglong uint64_t + +TYPEDEF: char __int8_t +TYPEDEF: short __int16_t +TYPEDEF: int __int32_t +TYPEDEF: longlong __int64_t + +TYPEDEF: uchar __uint8_t +TYPEDEF: ushort __uint16_t +TYPEDEF: uint __uint32_t +TYPEDEF: ulonglong __uint64_t + os { { linux [ "unix.types.linux" require ] } diff --git a/basis/unix/unix.factor b/basis/unix/unix.factor old mode 100755 new mode 100644 index 2011fa0dcb..960115d1a6 --- a/basis/unix/unix.factor +++ b/basis/unix/unix.factor @@ -1,17 +1,12 @@ ! Copyright (C) 2005, 2007 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. - -USING: alien alien.c-types alien.syntax kernel libc structs sequences - continuations byte-arrays strings - math namespaces system combinators vocabs.loader qualified - accessors stack-checker macros locals generalizations - unix.types debugger io prettyprint ; - +USING: alien alien.c-types alien.syntax kernel libc +sequences continuations byte-arrays strings math namespaces +system combinators vocabs.loader qualified accessors +stack-checker macros locals generalizations unix.types +debugger io prettyprint ; IN: unix -TYPEDEF: uint in_addr_t -TYPEDEF: uint socklen_t - : PROT_NONE 0 ; inline : PROT_READ 1 ; inline : PROT_WRITE 2 ; inline @@ -80,6 +75,8 @@ MACRO:: unix-system-call ( quot -- ) 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 fchmod ( int fd, mode_t mode ) ; FUNCTION: int chown ( char* path, uid_t owner, gid_t group ) ; FUNCTION: int chroot ( char* path ) ; @@ -93,6 +90,7 @@ FUNCTION: int dup2 ( int oldd, int newd ) ; : _exit ( status -- * ) #! We throw to give this a terminating stack effect. "int" f "_exit" { "int" } alien-invoke "Exit failed" throw ; +FUNCTION: void endpwent ( ) ; FUNCTION: int fchdir ( int fd ) ; FUNCTION: int fchown ( int fd, uid_t owner, gid_t group ) ; FUNCTION: int fcntl ( int fd, int cmd, int arg ) ; @@ -109,8 +107,14 @@ FUNCTION: uid_t geteuid ; FUNCTION: gid_t getgid ; 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: 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: int getgroups ( int gidsetlen, gid_t* gidset ) ; +FUNCTION: int getgrouplist ( char* name, int basegid, int* groups, int* ngroups ) ; + +FUNCTION: group* getgrent ; FUNCTION: int gethostname ( char* 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 ) ; diff --git a/extra/crypto/common/authors.txt b/basis/unix/users/authors.txt old mode 100755 new mode 100644 similarity index 100% rename from extra/crypto/common/authors.txt rename to basis/unix/users/authors.txt diff --git a/unmaintained/assoc-heaps/authors.txt b/basis/unix/users/bsd/authors.txt old mode 100755 new mode 100644 similarity index 100% rename from unmaintained/assoc-heaps/authors.txt rename to basis/unix/users/bsd/authors.txt diff --git a/basis/unix/users/bsd/bsd.factor b/basis/unix/users/bsd/bsd.factor new file mode 100644 index 0000000000..b3778ced70 --- /dev/null +++ b/basis/unix/users/bsd/bsd.factor @@ -0,0 +1,19 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: combinators accessors kernel unix unix.users +system ; +IN: unix.users.bsd + +TUPLE: bsd-passwd < passwd change class expire fields ; + +M: bsd new-passwd ( -- bsd-passwd ) bsd-passwd new ; + +M: bsd passwd>new-passwd ( passwd -- bsd-passwd ) + [ call-next-method ] keep + { + [ passwd-pw_change >>change ] + [ passwd-pw_class >>class ] + [ passwd-pw_shell >>shell ] + [ passwd-pw_expire >>expire ] + [ passwd-pw_fields >>fields ] + } cleave ; diff --git a/basis/unix/users/bsd/tags.txt b/basis/unix/users/bsd/tags.txt new file mode 100644 index 0000000000..6bf68304bb --- /dev/null +++ b/basis/unix/users/bsd/tags.txt @@ -0,0 +1 @@ +unportable diff --git a/basis/unix/users/tags.txt b/basis/unix/users/tags.txt new file mode 100644 index 0000000000..6bf68304bb --- /dev/null +++ b/basis/unix/users/tags.txt @@ -0,0 +1 @@ +unportable diff --git a/basis/unix/users/users-docs.factor b/basis/unix/users/users-docs.factor new file mode 100644 index 0000000000..f8586ffc35 --- /dev/null +++ b/basis/unix/users/users-docs.factor @@ -0,0 +1,120 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: help.markup help.syntax io.streams.string kernel quotations sequences strings math ; +IN: unix.users + +HELP: all-users +{ $values + + { "seq" sequence } } +{ $description "Returns a sequence of high-level " { $link passwd } " tuples that are platform-dependent and field for field complete with the Unix " { $link passwd } " structure." } ; + +HELP: effective-username +{ $values + + { "string" string } } +{ $description "Returns the effective username for the current user." } ; + +HELP: effective-user-id +{ $values + + { "id" integer } } +{ $description "Returns the effective username id for the current user." } ; + +HELP: new-passwd +{ $values + + { "passwd" passwd } } +{ $description "Creates a new passwd tuple dependent on the operating system." } ; + +HELP: passwd +{ $description "A platform-specific tuple correspding to every field from the Unix passwd struct. BSD passwd structures have four extra slots: " { $slot "change" } ", " { $slot "class" } "," { $slot "expire" } ", " { $slot "fields" } "." } ; + +HELP: passwd-cache +{ $description "A symbol storing passwd structures indexed by user-ids when within a " { $link with-passwd-cache } "." } ; + +HELP: passwd>new-passwd +{ $values + { "passwd" "a passwd struct" } + { "new-passwd" "a passwd tuple" } } +{ $description "A platform-specific conversion routine from a passwd structure to a passwd tuple." } ; + +HELP: real-username +{ $values + + { "string" string } } +{ $description "The real username of the current user." } ; + +HELP: real-user-id +{ $values + + { "id" integer } } +{ $description "The real user id of the current user." } ; + +HELP: set-effective-user +{ $values + { "string/id" "a string or a user id" } } +{ $description "Sets the current effective user given a username or a user id." } ; + +HELP: set-real-user +{ $values + { "string/id" "a string or a user id" } } +{ $description "Sets the current real user given a username or a user id." } ; + +HELP: user-passwd +{ $values + { "obj" object } + { "passwd" passwd } } +{ $description "Returns the passwd tuple given a username string or user id." } ; + +HELP: username +{ $values + { "id" integer } + { "string" string } } +{ $description "Returns the username associated with the user id." } ; + +HELP: user-id +{ $values + { "string" string } + { "id" integer } } +{ $description "Returns the user id associated with the username." } ; + +HELP: with-effective-user +{ $values + { "string/id" "a string or a uid" } { "quot" quotation } } +{ $description "Sets the effective username and calls the quotation. Restores the current username on success or on error after the call." } ; + +HELP: with-passwd-cache +{ $values + { "quot" quotation } } +{ $description "Iterates over the password file using library calls and creates a cache in the " { $link passwd-cache } " symbol. The cache is a hashtable indexed by user id. When looking up many users, this approach is much faster than calling system calls." } ; + +HELP: with-real-user +{ $values + { "string/id" "a string or a uid" } { "quot" quotation } } +{ $description "Sets the real username and calls the quotation. Restores the current username on success or on error after the call." } ; + +{ + real-username real-user-id set-real-user + effective-username effective-user-id + set-effective-user +} related-words + +ARTICLE: "unix.users" "unix.users" +"The " { $vocab-link "unix.users" } " vocabulary contains words that return information about Unix users." +"Listing all users:" +{ $subsection all-users } +"Returning a passwd tuple:" +"Real user:" +{ $subsection real-username } +{ $subsection real-user-id } +{ $subsection set-real-user } +"Effective user:" +{ $subsection effective-username } +{ $subsection effective-user-id } +{ $subsection set-effective-user } +"Combinators to change users:" +{ $subsection with-real-user } +{ $subsection with-effective-user } ; + +ABOUT: "unix.users" diff --git a/basis/unix/users/users-tests.factor b/basis/unix/users/users-tests.factor new file mode 100644 index 0000000000..a85c322aca --- /dev/null +++ b/basis/unix/users/users-tests.factor @@ -0,0 +1,24 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: tools.test unix.users kernel strings math ; +IN: unix.users.tests + + +[ ] [ all-users drop ] unit-test + +\ all-users must-infer + +[ t ] [ real-username string? ] unit-test +[ t ] [ effective-username string? ] unit-test + +[ t ] [ real-user-id integer? ] unit-test +[ t ] [ effective-user-id integer? ] unit-test + +[ ] [ real-user-id set-real-user ] unit-test +[ ] [ effective-user-id set-effective-user ] unit-test + +[ ] [ real-username [ ] with-real-user ] unit-test +[ ] [ real-user-id [ ] with-real-user ] unit-test + +[ ] [ effective-username [ ] with-effective-user ] unit-test +[ ] [ effective-user-id [ ] with-effective-user ] unit-test diff --git a/basis/unix/users/users.factor b/basis/unix/users/users.factor new file mode 100644 index 0000000000..eac771160b --- /dev/null +++ b/basis/unix/users/users.factor @@ -0,0 +1,114 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: alien alien.c-types alien.strings io.encodings.utf8 +io.unix.backend kernel math sequences splitting unix strings +combinators.short-circuit grouping byte-arrays combinators +accessors math.parser fry assocs namespaces continuations +vocabs.loader system ; +IN: unix.users + +TUPLE: passwd username password uid gid gecos dir shell ; + +HOOK: new-passwd os ( -- passwd ) +HOOK: passwd>new-passwd os ( passwd -- new-passwd ) + +new-passwd ( passwd -- seq ) + [ new-passwd ] dip + { + [ passwd-pw_name >>username ] + [ passwd-pw_passwd >>password ] + [ passwd-pw_uid >>uid ] + [ passwd-pw_gid >>gid ] + [ passwd-pw_gecos >>gecos ] + [ passwd-pw_dir >>dir ] + [ passwd-pw_shell >>shell ] + } cleave ; + +: with-pwent ( quot -- ) + [ endpwent ] [ ] cleanup ; inline + +PRIVATE> + +: all-users ( -- seq ) + [ + [ getpwent dup ] [ passwd>new-passwd ] [ drop ] produce + ] with-pwent ; + +SYMBOL: passwd-cache + +: with-passwd-cache ( quot -- ) + all-users [ [ uid>> ] keep ] H{ } map>assoc + passwd-cache swap with-variable ; inline + +GENERIC: user-passwd ( obj -- passwd ) + +M: integer user-passwd ( id -- passwd/f ) + passwd-cache get + [ at ] [ getpwuid passwd>new-passwd ] if* ; + +M: string user-passwd ( string -- passwd/f ) + getpwnam dup [ passwd>new-passwd ] when ; + +: username ( id -- string ) + user-passwd username>> ; + +: user-id ( string -- id ) + user-passwd uid>> ; + +: real-user-id ( -- id ) + getuid ; inline + +: real-username ( -- string ) + real-user-id username ; inline + +: effective-user-id ( -- id ) + geteuid ; inline + +: effective-username ( -- string ) + effective-user-id username ; inline + +GENERIC: set-real-user ( string/id -- ) + +GENERIC: set-effective-user ( string/id -- ) + +: with-real-user ( string/id quot -- ) + '[ _ set-real-user @ ] + real-user-id '[ _ set-real-user ] + [ ] cleanup ; inline + +: with-effective-user ( string/id quot -- ) + '[ _ set-effective-user @ ] + effective-user-id '[ _ set-effective-user ] + [ ] cleanup ; inline + + + +M: string set-real-user ( string -- ) + user-id (set-real-user) ; + +M: integer set-real-user ( id -- ) + (set-real-user) ; + +M: integer set-effective-user ( id -- ) + (set-effective-user) ; + +M: string set-effective-user ( string -- ) + user-id (set-effective-user) ; + +os { + { [ dup bsd? ] [ drop "unix.users.bsd" require ] } + { [ dup linux? ] [ drop ] } +} cond diff --git a/unmaintained/taxes/authors.txt b/basis/unix/utmpx/authors.txt similarity index 100% rename from unmaintained/taxes/authors.txt rename to basis/unix/utmpx/authors.txt diff --git a/basis/unix/utmpx/macosx/authors.txt b/basis/unix/utmpx/macosx/authors.txt new file mode 100644 index 0000000000..b4bd0e7b35 --- /dev/null +++ b/basis/unix/utmpx/macosx/authors.txt @@ -0,0 +1 @@ +Doug Coleman \ No newline at end of file diff --git a/basis/unix/utmpx/macosx/macosx-tests.factor b/basis/unix/utmpx/macosx/macosx-tests.factor new file mode 100644 index 0000000000..b0aa97dbca --- /dev/null +++ b/basis/unix/utmpx/macosx/macosx-tests.factor @@ -0,0 +1,4 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: tools.test unix.utmpx.macosx ; +IN: unix.utmpx.macosx.tests diff --git a/basis/unix/utmpx/macosx/macosx.factor b/basis/unix/utmpx/macosx/macosx.factor new file mode 100644 index 0000000000..92a0d9e3a4 --- /dev/null +++ b/basis/unix/utmpx/macosx/macosx.factor @@ -0,0 +1,6 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.syntax unix.bsd.macosx ; +IN: unix.utmpx.macosx + +! empty diff --git a/basis/unix/utmpx/macosx/tags.txt b/basis/unix/utmpx/macosx/tags.txt new file mode 100644 index 0000000000..6bf68304bb --- /dev/null +++ b/basis/unix/utmpx/macosx/tags.txt @@ -0,0 +1 @@ +unportable diff --git a/basis/unix/utmpx/netbsd/authors.txt b/basis/unix/utmpx/netbsd/authors.txt new file mode 100644 index 0000000000..b4bd0e7b35 --- /dev/null +++ b/basis/unix/utmpx/netbsd/authors.txt @@ -0,0 +1 @@ +Doug Coleman \ No newline at end of file diff --git a/basis/unix/utmpx/netbsd/netbsd-tests.factor b/basis/unix/utmpx/netbsd/netbsd-tests.factor new file mode 100644 index 0000000000..5bd0e4622f --- /dev/null +++ b/basis/unix/utmpx/netbsd/netbsd-tests.factor @@ -0,0 +1,4 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: tools.test unix.utmpx.netbsd ; +IN: unix.utmpx.netbsd.tests diff --git a/basis/unix/utmpx/netbsd/netbsd.factor b/basis/unix/utmpx/netbsd/netbsd.factor new file mode 100644 index 0000000000..40fce746b1 --- /dev/null +++ b/basis/unix/utmpx/netbsd/netbsd.factor @@ -0,0 +1,22 @@ +! 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 ; +IN: unix.utmpx.netbsd + +TUPLE: netbsd-utmpx-record < utmpx-record termination exit +sockaddr ; + +M: netbsd new-utmpx-record ( -- utmpx-record ) + 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 ; diff --git a/basis/unix/utmpx/netbsd/tags.txt b/basis/unix/utmpx/netbsd/tags.txt new file mode 100644 index 0000000000..6bf68304bb --- /dev/null +++ b/basis/unix/utmpx/netbsd/tags.txt @@ -0,0 +1 @@ +unportable diff --git a/basis/unix/utmpx/tags.txt b/basis/unix/utmpx/tags.txt new file mode 100644 index 0000000000..6bf68304bb --- /dev/null +++ b/basis/unix/utmpx/tags.txt @@ -0,0 +1 @@ +unportable diff --git a/basis/unix/utmpx/utmpx.factor b/basis/unix/utmpx/utmpx.factor new file mode 100644 index 0000000000..e1756daa00 --- /dev/null +++ b/basis/unix/utmpx/utmpx.factor @@ -0,0 +1,66 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.c-types alien.syntax combinators continuations +io.encodings.string io.encodings.utf8 kernel sequences strings +unix calendar system accessors unix.time calendar.unix +vocabs.loader ; +IN: unix.utmpx + +: EMPTY 0 ; inline +: RUN_LVL 1 ; inline +: BOOT_TIME 2 ; inline +: OLD_TIME 3 ; inline +: NEW_TIME 4 ; inline +: INIT_PROCESS 5 ; inline +: LOGIN_PROCESS 6 ; inline +: USER_PROCESS 7 ; inline +: DEAD_PROCESS 8 ; inline +: ACCOUNTING 9 ; inline +: SIGNATURE 10 ; inline +: SHUTDOWN_TIME 11 ; inline + +FUNCTION: void setutxent ( ) ; +FUNCTION: void endutxent ( ) ; +FUNCTION: utmpx* getutxent ( ) ; +FUNCTION: utmpx* getutxid ( utmpx* id ) ; +FUNCTION: utmpx* getutxline ( utmpx* line ) ; +FUNCTION: utmpx* pututxline ( utmpx* utx ) ; + +TUPLE: utmpx-record user id line pid type timestamp host ; + +HOOK: new-utmpx-record os ( -- utmpx-record ) + +HOOK: utmpx>utmpx-record os ( utmpx -- utmpx-record ) + +: memory>string ( alien n -- string ) + memory>byte-array utf8 decode [ 0 = ] trim-right ; + +M: unix new-utmpx-record + utmpx-record new ; + +M: unix utmpx>utmpx-record ( utmpx -- utmpx-record ) + [ new-utmpx-record ] dip + { + [ utmpx-ut_user _UTX_USERSIZE memory>string >>user ] + [ utmpx-ut_id _UTX_IDSIZE memory>string >>id ] + [ utmpx-ut_line _UTX_LINESIZE memory>string >>line ] + [ utmpx-ut_pid >>pid ] + [ utmpx-ut_type >>type ] + [ utmpx-ut_tv timeval>unix-time >>timestamp ] + [ utmpx-ut_host _UTX_HOSTSIZE memory>string >>host ] + } cleave ; + +: with-utmpx ( quot -- ) + setutxent [ endutxent ] [ ] cleanup ; inline + +: all-utmpx ( -- seq ) + [ + [ getutxent dup ] + [ utmpx>utmpx-record ] + [ drop ] produce + ] with-utmpx ; + +os { + { macosx [ "unix.utmpx.macosx" require ] } + { netbsd [ "unix.utmpx.netbsd" require ] } +} case diff --git a/unmaintained/webapps/planet/authors.txt b/basis/urls/encoding/authors.txt old mode 100755 new mode 100644 similarity index 100% rename from unmaintained/webapps/planet/authors.txt rename to basis/urls/encoding/authors.txt diff --git a/basis/urls/encoding/encoding-docs.factor b/basis/urls/encoding/encoding-docs.factor new file mode 100644 index 0000000000..f8b435441f --- /dev/null +++ b/basis/urls/encoding/encoding-docs.factor @@ -0,0 +1,57 @@ +IN: urls.encoding +USING: strings help.markup help.syntax assocs multiline ; + +HELP: url-decode +{ $values { "str" string } { "decoded" string } } +{ $description "Decodes a URL-encoded string." } ; + +HELP: url-encode +{ $values { "str" string } { "encoded" string } } +{ $description "URL-encodes a string." } ; + +HELP: url-quotable? +{ $values { "ch" "a character" } { "?" "a boolean" } } +{ $description "Tests if a character be used without URL-encoding in a URL." } ; + +HELP: assoc>query +{ $values { "assoc" assoc } { "str" string } } +{ $description "Converts an assoc of query parameters into a query string, performing URL encoding." } +{ $notes "This word is used by the implementation of " { $link "urls" } ". It is also used by the HTTP client to encode POST requests." } +{ $examples + { $example + "USING: io urls.encoding ;" + "{ { \"from\" \"Lead\" } { \"to\" \"Gold, please\" } }" + "assoc>query print" + "from=Lead&to=Gold%2c%20please" + } +} ; + +HELP: query>assoc +{ $values { "query" string } { "assoc" assoc } } +{ $description "Parses a URL query string and URL-decodes each component." } +{ $notes "This word is used by the implementation of " { $link "urls" } ". It is also used by the HTTP server to parse POST requests." } +{ $examples + { $unchecked-example + "USING: prettyprint urls.encoding ;" + "\"gender=female&agefrom=22&ageto=28&location=Omaha+NE\"" + "query>assoc ." + <" H{ + { "gender" "female" } + { "agefrom" "22" } + { "ageto" "28" } + { "location" "Omaha NE" } +}"> + } +} ; + +ARTICLE: "url-encoding" "URL encoding and decoding" +"URL encoding and decoding strings:" +{ $subsection url-encode } +{ $subsection url-decode } +{ $subsection url-quotable? } +"Encoding and decoding queries:" +{ $subsection assoc>query } +{ $subsection query>assoc } +"See " { $url "http://en.wikipedia.org/wiki/Percent-encoding" } " for a description of URL encoding." ; + +ABOUT: "url-encoding" diff --git a/basis/urls/encoding/encoding-tests.factor b/basis/urls/encoding/encoding-tests.factor new file mode 100644 index 0000000000..87b1812ef8 --- /dev/null +++ b/basis/urls/encoding/encoding-tests.factor @@ -0,0 +1,28 @@ +IN: urls.encoding.tests +USING: urls.encoding tools.test arrays kernel assocs present accessors ; + +[ "~hello world" ] [ "%7ehello world" url-decode ] unit-test +[ f ] [ "%XX%XX%XX" url-decode ] unit-test +[ f ] [ "%XX%XX%X" url-decode ] unit-test + +[ "hello world" ] [ "hello%20world" url-decode ] unit-test +[ " ! " ] [ "%20%21%20" url-decode ] unit-test +[ "hello world" ] [ "hello world%" url-decode ] unit-test +[ "hello world" ] [ "hello world%x" url-decode ] unit-test +[ "hello%20world" ] [ "hello world" url-encode ] unit-test + +[ "hello world" ] [ "hello+world" query-decode ] unit-test + +[ "\u001234hi\u002045" ] [ "\u001234hi\u002045" url-encode url-decode ] unit-test + +[ "a=b&a=c" ] [ { { "a" { "b" "c" } } } assoc>query ] unit-test + +[ H{ { "a" "b" } } ] [ "a=b" query>assoc ] unit-test + +[ H{ { "a" { "b" "c" } } } ] [ "a=b&a=c" query>assoc ] unit-test + +[ H{ { "a" { "b" "c" } } } ] [ "a=b;a=c" query>assoc ] unit-test + +[ H{ { "text" "hello world" } } ] [ "text=hello+world" query>assoc ] unit-test + +[ "a=3" ] [ { { "a" 3 } } assoc>query ] unit-test diff --git a/basis/urls/encoding/encoding.factor b/basis/urls/encoding/encoding.factor new file mode 100644 index 0000000000..fa882609a5 --- /dev/null +++ b/basis/urls/encoding/encoding.factor @@ -0,0 +1,96 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel ascii combinators combinators.short-circuit +sequences splitting fry namespaces make assocs arrays strings +io.encodings.string io.encodings.utf8 math math.parser accessors +hashtables present ; +IN: urls.encoding + +: url-quotable? ( ch -- ? ) + { + [ letter? ] + [ LETTER? ] + [ digit? ] + [ "/_-.:" member? ] + } 1|| ; foldable + +hex 2 CHAR: 0 pad-left % ] each ; + +PRIVATE> + +: url-encode ( str -- encoded ) + [ + [ dup url-quotable? [ , ] [ push-utf8 ] if ] each + ] "" make ; + += [ + 2drop + ] [ + [ 1+ dup 2 + ] dip subseq hex> [ , ] when* + ] if ; + +: url-decode-% ( index str -- index str ) + 2dup url-decode-hex ; + +: url-decode-iter ( index str -- ) + 2dup length >= [ + 2drop + ] [ + 2dup nth dup CHAR: % = [ + drop url-decode-% [ 3 + ] dip + ] [ + , [ 1+ ] dip + ] if url-decode-iter + ] if ; + +PRIVATE> + +: url-decode ( str -- decoded ) + [ 0 swap url-decode-iter ] "" make utf8 decode ; + +: query-decode ( str -- decoded ) + [ dup CHAR: + = [ drop "%20" ] [ 1string ] if ] { } map-as + concat url-decode ; + + + +: query>assoc ( query -- assoc ) + dup [ + "&;" split H{ } clone [ + [ + [ "=" split1 [ dup [ query-decode ] when ] bi@ swap ] dip + add-query-param + ] curry each + ] keep + ] when ; + +: assoc>query ( assoc -- str ) + [ + dup array? [ [ present ] map ] [ present 1array ] if + ] assoc-map + [ + [ + [ url-encode ] dip + [ url-encode "=" swap 3append , ] with each + ] assoc-each + ] { } make "&" join ; diff --git a/basis/urls/encoding/summary.txt b/basis/urls/encoding/summary.txt new file mode 100644 index 0000000000..d156e44c56 --- /dev/null +++ b/basis/urls/encoding/summary.txt @@ -0,0 +1 @@ +URL and form encoding/decoding diff --git a/basis/urls/encoding/tags.txt b/basis/urls/encoding/tags.txt new file mode 100644 index 0000000000..c0772185a0 --- /dev/null +++ b/basis/urls/encoding/tags.txt @@ -0,0 +1 @@ +web diff --git a/basis/urls/secure/secure.factor b/basis/urls/secure/secure.factor new file mode 100644 index 0000000000..d2fa55f7f3 --- /dev/null +++ b/basis/urls/secure/secure.factor @@ -0,0 +1,6 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: urls urls.private io.sockets io.sockets.secure ; +IN: urls.secure + +M: abstract-inet >secure-addr ; diff --git a/basis/urls/urls-docs.factor b/basis/urls/urls-docs.factor index 166ad9d586..b423e6b751 100644 --- a/basis/urls/urls-docs.factor +++ b/basis/urls/urls-docs.factor @@ -46,37 +46,6 @@ HELP: URL" } } ; -HELP: assoc>query -{ $values { "assoc" assoc } { "str" string } } -{ $description "Converts an assoc of query parameters into a query string, performing URL encoding." } -{ $notes "This word is used to implement the " { $link present } " method on URLs; it is also used by the HTTP client to encode POST requests." } -{ $examples - { $example - "USING: io urls ;" - "{ { \"from\" \"Lead\" } { \"to\" \"Gold, please\" } }" - "assoc>query print" - "from=Lead&to=Gold%2c+please" - } -} ; - -HELP: query>assoc -{ $values { "query" string } { "assoc" assoc } } -{ $description "Parses a URL query string and URL-decodes each component." } -{ $notes "This word is used to implement " { $link >url } ". It is also used by the HTTP server to parse POST requests." } -{ $examples - { $unchecked-example - "USING: prettyprint urls ;" - "\"gender=female&agefrom=22&ageto=28&location=Omaha+NE\"" - "query>assoc ." - <" H{ - { "gender" "female" } - { "agefrom" "22" } - { "ageto" "28" } - { "location" "Omaha NE" } -}"> - } -} ; - HELP: derive-url { $values { "base" url } { "url" url } { "url'" url } } { $description "Builds a URL by filling in missing components of " { $snippet "url" } " from " { $snippet "base" } "." } @@ -166,6 +135,12 @@ HELP: relative-url } } ; +HELP: relative-url? +{ $values + { "url" url } + { "?" "a boolean" } } +{ $description "Tests whether a URL is relative." } ; + HELP: secure-protocol? { $values { "protocol" string } { "?" "a boolean" } } { $description "Tests if protocol connections must be made with secure sockets (SSL/TLS)." } @@ -192,28 +167,7 @@ HELP: url-append-path { $values { "path1" string } { "path2" string } { "path" string } } { $description "Like " { $link append-path } ", but intended for use with URL paths and not filesystem paths." } ; -HELP: url-decode -{ $values { "str" string } { "decoded" string } } -{ $description "Decodes a URL-encoded string." } ; - -HELP: url-encode -{ $values { "str" string } { "encoded" string } } -{ $description "URL-encodes a string." } ; - -HELP: url-quotable? -{ $values { "ch" "a character" } { "?" "a boolean" } } -{ $description "Tests if a character be used without URL-encoding in a URL." } ; - -ARTICLE: "url-encoding" "URL encoding and decoding" -"URL encoding and decoding strings:" -{ $subsection url-encode } -{ $subsection url-decode } -{ $subsection url-quotable? } -"The URL implemention encodes and decodes components of " { $link url } " instances automatically, but sometimes it is required for non-URL strings. See " { $url "http://en.wikipedia.org/wiki/Percent-encoding" } " for a description of URL encoding." ; - ARTICLE: "url-utilities" "URL implementation utilities" -{ $subsection assoc>query } -{ $subsection query>assoc } { $subsection parse-host } { $subsection secure-protocol? } { $subsection url-append-path } ; @@ -240,8 +194,9 @@ $nl { $subsection set-query-param } "Creating " { $link "network-addressing" } " from URLs:" { $subsection url-addr } -"Additional topics:" -{ $subsection "url-utilities" } -{ $subsection "url-encoding" } ; +"The URL implemention encodes and decodes components of " { $link url } " instances automatically, but sometimes this functionality is needed for non-URL strings." +{ $subsection "url-encoding" } +"Utility words used by the URL implementation:" +{ $subsection "url-utilities" } ; ABOUT: "urls" diff --git a/basis/urls/urls-tests.factor b/basis/urls/urls-tests.factor index b0bf950178..cac206bf3c 100644 --- a/basis/urls/urls-tests.factor +++ b/basis/urls/urls-tests.factor @@ -2,30 +2,6 @@ IN: urls.tests USING: urls urls.private tools.test arrays kernel assocs present accessors ; -[ "hello+world" ] [ "hello world" url-encode ] unit-test -[ "hello world" ] [ "hello%20world" url-decode ] unit-test -[ "~hello world" ] [ "%7ehello+world" url-decode ] unit-test -[ f ] [ "%XX%XX%XX" url-decode ] unit-test -[ f ] [ "%XX%XX%X" url-decode ] unit-test - -[ "hello world" ] [ "hello+world" url-decode ] unit-test -[ "hello world" ] [ "hello%20world" url-decode ] unit-test -[ " ! " ] [ "%20%21%20" url-decode ] unit-test -[ "hello world" ] [ "hello world%" url-decode ] unit-test -[ "hello world" ] [ "hello world%x" url-decode ] unit-test -[ "hello+world" ] [ "hello world" url-encode ] unit-test -[ "+%21+" ] [ " ! " url-encode ] unit-test - -[ "\u001234hi\u002045" ] [ "\u001234hi\u002045" url-encode url-decode ] unit-test - -[ "a=b&a=c" ] [ { { "a" { "b" "c" } } } assoc>query ] unit-test - -[ H{ { "a" "b" } } ] [ "a=b" query>assoc ] unit-test - -[ H{ { "a" { "b" "c" } } } ] [ "a=b&a=c" query>assoc ] unit-test - -[ "a=3" ] [ { { "a" 3 } } assoc>query ] unit-test - : urls { { diff --git a/basis/urls/urls.factor b/basis/urls/urls.factor index 5fe9bbb5a0..597cdfdb7f 100644 --- a/basis/urls/urls.factor +++ b/basis/urls/urls.factor @@ -2,102 +2,12 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel ascii combinators combinators.short-circuit sequences splitting fry namespaces make assocs arrays strings -io.sockets io.sockets.secure io.encodings.string +io.sockets io.encodings.string io.encodings.utf8 math math.parser accessors parser strings.parser lexer prettyprint.backend hashtables present -peg.ebnf ; +peg.ebnf urls.encoding ; IN: urls -: url-quotable? ( ch -- ? ) - { - [ letter? ] - [ LETTER? ] - [ digit? ] - [ "/_-.:" member? ] - } 1|| ; foldable - -hex 2 CHAR: 0 pad-left % ] each - ] if ; - -PRIVATE> - -: url-encode ( str -- encoded ) - [ - [ dup url-quotable? [ , ] [ push-utf8 ] if ] each - ] "" make ; - -= [ - 2drop - ] [ - [ 1+ dup 2 + ] dip subseq hex> [ , ] when* - ] if ; - -: url-decode-% ( index str -- index str ) - 2dup url-decode-hex [ 3 + ] dip ; - -: url-decode-+-or-other ( index str ch -- index str ) - dup CHAR: + = [ drop CHAR: \s ] when , [ 1+ ] dip ; - -: url-decode-iter ( index str -- ) - 2dup length >= [ - 2drop - ] [ - 2dup nth dup CHAR: % = [ - drop url-decode-% - ] [ - url-decode-+-or-other - ] if url-decode-iter - ] if ; - -PRIVATE> - -: url-decode ( str -- decoded ) - [ 0 swap url-decode-iter ] "" make utf8 decode ; - - - -: query>assoc ( query -- assoc ) - dup [ - "&" split H{ } clone [ - [ - [ "=" split1 [ dup [ url-decode ] when ] bi@ swap ] dip - add-query-param - ] curry each - ] keep - ] when ; - -: assoc>query ( assoc -- str ) - [ - dup array? [ [ present ] map ] [ present 1array ] if - ] assoc-map - [ - [ - [ url-encode ] dip - [ url-encode "=" swap 3append , ] with each - ] assoc-each - ] { } make "&" join ; - TUPLE: url protocol username password host port path query anchor ; : ( -- url ) url new ; @@ -229,14 +139,14 @@ PRIVATE> : derive-url ( base url -- url' ) [ clone ] dip over { - [ [ protocol>> ] either? >>protocol ] - [ [ username>> ] either? >>username ] - [ [ password>> ] either? >>password ] - [ [ host>> ] either? >>host ] - [ [ port>> ] either? >>port ] - [ [ path>> ] bi@ swap url-append-path >>path ] - [ [ query>> ] either? >>query ] - [ [ anchor>> ] either? >>anchor ] + [ [ protocol>> ] either? >>protocol ] + [ [ username>> ] either? >>username ] + [ [ password>> ] either? >>password ] + [ [ host>> ] either? >>host ] + [ [ port>> ] either? >>port ] + [ [ path>> ] bi@ swap url-append-path >>path ] + [ [ query>> ] either? >>query ] + [ [ anchor>> ] either? >>anchor ] } 2cleave ; : relative-url ( url -- url' ) @@ -245,10 +155,18 @@ PRIVATE> f >>host f >>port ; +: relative-url? ( url -- ? ) protocol>> not ; + ! Half-baked stuff follows : secure-protocol? ( protocol -- ? ) "https" = ; +secure-addr ( addrspec -- addrspec' ) + +PRIVATE> + : url-addr ( url -- addr ) [ [ host>> ] @@ -256,7 +174,7 @@ PRIVATE> [ protocol>> protocol-port ] tri or ] [ protocol>> ] bi - secure-protocol? [ ] when ; + secure-protocol? [ >secure-addr ] when ; : ensure-port ( url -- url ) dup protocol>> '[ _ protocol-port or ] change-port ; diff --git a/basis/values/values-docs.factor b/basis/values/values-docs.factor old mode 100755 new mode 100644 diff --git a/basis/values/values-tests.factor b/basis/values/values-tests.factor old mode 100755 new mode 100644 diff --git a/basis/values/values.factor b/basis/values/values.factor old mode 100755 new mode 100644 diff --git a/basis/windows/advapi32/advapi32.factor b/basis/windows/advapi32/advapi32.factor old mode 100755 new mode 100644 diff --git a/basis/windows/com/com-tests.factor b/basis/windows/com/com-tests.factor old mode 100755 new mode 100644 diff --git a/basis/windows/com/com.factor b/basis/windows/com/com.factor old mode 100755 new mode 100644 diff --git a/basis/windows/com/syntax/syntax-docs.factor b/basis/windows/com/syntax/syntax-docs.factor old mode 100755 new mode 100644 diff --git a/basis/windows/com/syntax/syntax.factor b/basis/windows/com/syntax/syntax.factor old mode 100755 new mode 100644 diff --git a/basis/windows/com/wrapper/wrapper-docs.factor b/basis/windows/com/wrapper/wrapper-docs.factor old mode 100755 new mode 100644 diff --git a/basis/windows/com/wrapper/wrapper.factor b/basis/windows/com/wrapper/wrapper.factor old mode 100755 new mode 100644 diff --git a/basis/windows/dinput/constants/constants.factor b/basis/windows/dinput/constants/constants.factor old mode 100755 new mode 100644 diff --git a/basis/windows/dinput/dinput.factor b/basis/windows/dinput/dinput.factor old mode 100755 new mode 100644 diff --git a/basis/windows/gdi32/gdi32.factor b/basis/windows/gdi32/gdi32.factor old mode 100755 new mode 100644 diff --git a/basis/windows/kernel32/kernel32.factor b/basis/windows/kernel32/kernel32.factor old mode 100755 new mode 100644 diff --git a/basis/windows/messages/messages.factor b/basis/windows/messages/messages.factor old mode 100755 new mode 100644 diff --git a/basis/windows/ole32/ole32.factor b/basis/windows/ole32/ole32.factor old mode 100755 new mode 100644 diff --git a/basis/windows/opengl32/opengl32.factor b/basis/windows/opengl32/opengl32.factor old mode 100755 new mode 100644 diff --git a/basis/windows/user32/user32.factor b/basis/windows/user32/user32.factor old mode 100755 new mode 100644 diff --git a/basis/windows/winsock/winsock.factor b/basis/windows/winsock/winsock.factor old mode 100755 new mode 100644 index 3c4230e21e..4ca07ce850 --- a/basis/windows/winsock/winsock.factor +++ b/basis/windows/winsock/winsock.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2006 Mackenzie Straight, Doug Coleman. - +! See http://factorcode.org/license.txt for BSD license. USING: alien alien.c-types alien.strings alien.syntax arrays byte-arrays kernel math sequences windows.types windows.kernel32 -windows.errors structs windows math.bitwise alias ; +windows.errors windows math.bitwise alias ; IN: windows.winsock USE: libc @@ -138,6 +138,10 @@ C-STRUCT: addrinfo { "sockaddr*" "addr" } { "addrinfo*" "next" } ; +C-STRUCT: timeval + { "long" "sec" } + { "long" "usec" } ; + : hostent-addr ( hostent -- addr ) hostent-addr-list *void* ; ! *uint ; LIBRARY: winsock @@ -440,4 +444,3 @@ FUNCTION: void GetAcceptExSockaddrs ( void* a, int b, int c, int d, void* e, voi : init-winsock ( -- ) HEX: 0202 WSAStartup winsock-return-check ; - diff --git a/basis/x11/clipboard/clipboard.factor b/basis/x11/clipboard/clipboard.factor old mode 100755 new mode 100644 diff --git a/basis/x11/windows/windows.factor b/basis/x11/windows/windows.factor old mode 100755 new mode 100644 diff --git a/basis/x11/xim/xim.factor b/basis/x11/xim/xim.factor old mode 100755 new mode 100644 diff --git a/basis/x11/xlib/xlib.factor b/basis/x11/xlib/xlib.factor old mode 100755 new mode 100644 diff --git a/basis/xml-rpc/xml-rpc.factor b/basis/xml-rpc/xml-rpc.factor old mode 100755 new mode 100644 diff --git a/basis/xml/char-classes/char-classes.factor b/basis/xml/char-classes/char-classes.factor old mode 100755 new mode 100644 diff --git a/basis/xml/data/data.factor b/basis/xml/data/data.factor old mode 100755 new mode 100644 diff --git a/basis/xml/errors/errors-tests.factor b/basis/xml/errors/errors-tests.factor old mode 100755 new mode 100644 diff --git a/basis/xml/tests/soap.factor b/basis/xml/tests/soap.factor old mode 100755 new mode 100644 diff --git a/basis/xml/utilities/utilities.factor b/basis/xml/utilities/utilities.factor old mode 100755 new mode 100644 diff --git a/basis/xmode/catalog/catalog.factor b/basis/xmode/catalog/catalog.factor old mode 100755 new mode 100644 diff --git a/basis/xmode/code2html/code2html.factor b/basis/xmode/code2html/code2html.factor old mode 100755 new mode 100644 diff --git a/basis/xmode/code2html/responder/responder.factor b/basis/xmode/code2html/responder/responder.factor old mode 100755 new mode 100644 diff --git a/basis/xmode/loader/loader.factor b/basis/xmode/loader/loader.factor old mode 100755 new mode 100644 diff --git a/basis/xmode/marker/marker-tests.factor b/basis/xmode/marker/marker-tests.factor old mode 100755 new mode 100644 diff --git a/basis/xmode/marker/marker.factor b/basis/xmode/marker/marker.factor old mode 100755 new mode 100644 diff --git a/basis/xmode/marker/state/state.factor b/basis/xmode/marker/state/state.factor old mode 100755 new mode 100644 diff --git a/basis/xmode/rules/rules.factor b/basis/xmode/rules/rules.factor old mode 100755 new mode 100644 diff --git a/basis/xmode/tokens/tokens.factor b/basis/xmode/tokens/tokens.factor old mode 100755 new mode 100644 diff --git a/basis/xmode/utilities/utilities-tests.factor b/basis/xmode/utilities/utilities-tests.factor old mode 100755 new mode 100644 diff --git a/core/alien/alien-docs.factor b/core/alien/alien-docs.factor old mode 100755 new mode 100644 index 814ca8613e..ce3497439a --- a/core/alien/alien-docs.factor +++ b/core/alien/alien-docs.factor @@ -302,8 +302,8 @@ ARTICLE: "embedding" "Embedding Factor into C applications" "The Factor " { $snippet "Makefile" } " builds the Factor VM both as an executable and a library. The library can be used by other applications. File names for the library on various operating systems:" { $table { "OS" "Library name" "Shared?" } - { "Windows XP/Vista" { $snippet "factor-nt.dll" } "Yes" } - { "Windows CE" { $snippet "factor-ce.dll" } "Yes" } + { "Windows XP/Vista" { $snippet "factor.dll" } "Yes" } + ! { "Windows CE" { $snippet "factor-ce.dll" } "Yes" } { "Mac OS X" { $snippet "libfactor.dylib" } "Yes" } { "Other Unix" { $snippet "libfactor.a" } "No" } } diff --git a/core/alien/alien-tests.factor b/core/alien/alien-tests.factor old mode 100755 new mode 100644 diff --git a/core/alien/alien.factor b/core/alien/alien.factor old mode 100755 new mode 100644 diff --git a/core/arrays/arrays-docs.factor b/core/arrays/arrays-docs.factor old mode 100755 new mode 100644 diff --git a/core/arrays/arrays-tests.factor b/core/arrays/arrays-tests.factor old mode 100755 new mode 100644 diff --git a/core/arrays/arrays.factor b/core/arrays/arrays.factor old mode 100755 new mode 100644 diff --git a/core/assocs/assocs-docs.factor b/core/assocs/assocs-docs.factor old mode 100755 new mode 100644 diff --git a/core/assocs/assocs-tests.factor b/core/assocs/assocs-tests.factor old mode 100755 new mode 100644 diff --git a/core/assocs/assocs.factor b/core/assocs/assocs.factor old mode 100755 new mode 100644 diff --git a/core/bootstrap/layouts/layouts.factor b/core/bootstrap/layouts/layouts.factor old mode 100755 new mode 100644 diff --git a/core/bootstrap/primitives.factor b/core/bootstrap/primitives.factor old mode 100755 new mode 100644 diff --git a/core/bootstrap/stage1.factor b/core/bootstrap/stage1.factor old mode 100755 new mode 100644 diff --git a/core/bootstrap/syntax.factor b/core/bootstrap/syntax.factor old mode 100755 new mode 100644 diff --git a/core/byte-arrays/byte-arrays-docs.factor b/core/byte-arrays/byte-arrays-docs.factor old mode 100755 new mode 100644 diff --git a/core/byte-arrays/byte-arrays-tests.factor b/core/byte-arrays/byte-arrays-tests.factor old mode 100755 new mode 100644 diff --git a/core/byte-arrays/byte-arrays.factor b/core/byte-arrays/byte-arrays.factor old mode 100755 new mode 100644 diff --git a/core/byte-vectors/byte-vectors-docs.factor b/core/byte-vectors/byte-vectors-docs.factor old mode 100755 new mode 100644 diff --git a/core/byte-vectors/byte-vectors-tests.factor b/core/byte-vectors/byte-vectors-tests.factor old mode 100755 new mode 100644 diff --git a/core/byte-vectors/byte-vectors.factor b/core/byte-vectors/byte-vectors.factor old mode 100755 new mode 100644 diff --git a/core/checksums/crc32/crc32.factor b/core/checksums/crc32/crc32.factor old mode 100755 new mode 100644 diff --git a/core/classes/algebra/algebra-docs.factor b/core/classes/algebra/algebra-docs.factor old mode 100755 new mode 100644 diff --git a/core/classes/algebra/algebra-tests.factor b/core/classes/algebra/algebra-tests.factor old mode 100755 new mode 100644 diff --git a/core/classes/algebra/algebra.factor b/core/classes/algebra/algebra.factor old mode 100755 new mode 100644 diff --git a/core/classes/classes-docs.factor b/core/classes/classes-docs.factor old mode 100755 new mode 100644 index ff7aac36d3..f8a2ff415c --- a/core/classes/classes-docs.factor +++ b/core/classes/classes-docs.factor @@ -28,12 +28,13 @@ $nl $nl "Classes themselves form a class:" { $subsection class? } -"You can ask an object for its class or superclass:" +"You can ask an object for its class:" { $subsection class } -{ $subsection superclass } -{ $subsection superclasses } "Testing if an object is an instance of a class:" { $subsection instance? } +"You can ask a class for its superclass:" +{ $subsection superclass } +{ $subsection superclasses } "Class predicates can be used to test instances directly:" { $subsection "class-predicates" } "There is a universal class which all objects are an instance of, and an empty class with no instances:" diff --git a/core/classes/classes-tests.factor b/core/classes/classes-tests.factor old mode 100755 new mode 100644 diff --git a/core/classes/classes.factor b/core/classes/classes.factor old mode 100755 new mode 100644 index 67a789a1dc..dcb69c9149 --- a/core/classes/classes.factor +++ b/core/classes/classes.factor @@ -10,20 +10,23 @@ SYMBOL: class-not-cache SYMBOL: classes-intersect-cache SYMBOL: class-and-cache SYMBOL: class-or-cache +SYMBOL: next-method-quot-cache : init-caches ( -- ) H{ } clone class<=-cache set H{ } clone class-not-cache set H{ } clone classes-intersect-cache set H{ } clone class-and-cache set - H{ } clone class-or-cache set ; + H{ } clone class-or-cache set + H{ } clone next-method-quot-cache set ; : reset-caches ( -- ) class<=-cache get clear-assoc class-not-cache get clear-assoc classes-intersect-cache get clear-assoc class-and-cache get clear-assoc - class-or-cache get clear-assoc ; + class-or-cache get clear-assoc + next-method-quot-cache get clear-assoc ; SYMBOL: update-map diff --git a/core/classes/mixin/mixin-docs.factor b/core/classes/mixin/mixin-docs.factor old mode 100755 new mode 100644 diff --git a/core/classes/mixin/mixin.factor b/core/classes/mixin/mixin.factor old mode 100755 new mode 100644 diff --git a/core/classes/predicate/predicate-docs.factor b/core/classes/predicate/predicate-docs.factor old mode 100755 new mode 100644 diff --git a/core/classes/predicate/predicate.factor b/core/classes/predicate/predicate.factor old mode 100755 new mode 100644 diff --git a/core/classes/singleton/singleton.factor b/core/classes/singleton/singleton.factor old mode 100755 new mode 100644 diff --git a/core/classes/tuple/parser/parser-tests.factor b/core/classes/tuple/parser/parser-tests.factor index 17376a594f..6b9a953ab9 100644 --- a/core/classes/tuple/parser/parser-tests.factor +++ b/core/classes/tuple/parser/parser-tests.factor @@ -96,3 +96,16 @@ TUPLE: syntax-test bar baz ; [ T{ syntax-test } ] [ T{ syntax-test } ] unit-test [ T{ syntax-test f { 2 3 } { 4 { 5 } } } ] [ T{ syntax-test { bar { 2 3 } } { baz { 4 { 5 } } } } ] unit-test + +! Corner case +TUPLE: parsing-corner-case x ; + +[ T{ parsing-corner-case f 3 } ] [ + { + "USE: classes.tuple.parser.tests" + "T{ parsing-corner-case" + " f" + " 3" + "}" + } "\n" join eval +] unit-test diff --git a/core/classes/tuple/parser/parser.factor b/core/classes/tuple/parser/parser.factor index dd78b4ba3e..7888635641 100644 --- a/core/classes/tuple/parser/parser.factor +++ b/core/classes/tuple/parser/parser.factor @@ -86,6 +86,7 @@ ERROR: bad-literal-tuple ; : parse-tuple-literal ( -- tuple ) scan-word scan { + { f [ unexpected-eof ] } { "f" [ \ } parse-until boa>tuple ] } { "{" [ parse-slot-values assoc>tuple ] } { "}" [ new ] } diff --git a/core/classes/tuple/tuple-docs.factor b/core/classes/tuple/tuple-docs.factor old mode 100755 new mode 100644 diff --git a/core/classes/tuple/tuple-tests.factor b/core/classes/tuple/tuple-tests.factor old mode 100755 new mode 100644 diff --git a/core/classes/tuple/tuple.factor b/core/classes/tuple/tuple.factor old mode 100755 new mode 100644 diff --git a/core/classes/union/union-docs.factor b/core/classes/union/union-docs.factor old mode 100755 new mode 100644 diff --git a/core/classes/union/union.factor b/core/classes/union/union.factor old mode 100755 new mode 100644 diff --git a/core/combinators/combinators-docs.factor b/core/combinators/combinators-docs.factor old mode 100755 new mode 100644 diff --git a/core/combinators/combinators-tests.factor b/core/combinators/combinators-tests.factor old mode 100755 new mode 100644 diff --git a/core/combinators/combinators.factor b/core/combinators/combinators.factor old mode 100755 new mode 100644 diff --git a/core/compiler/errors/errors-docs.factor b/core/compiler/errors/errors-docs.factor old mode 100755 new mode 100644 diff --git a/core/compiler/errors/errors.factor b/core/compiler/errors/errors.factor old mode 100755 new mode 100644 diff --git a/core/compiler/units/units-docs.factor b/core/compiler/units/units-docs.factor old mode 100755 new mode 100644 diff --git a/core/compiler/units/units.factor b/core/compiler/units/units.factor old mode 100755 new mode 100644 diff --git a/core/continuations/continuations-docs.factor b/core/continuations/continuations-docs.factor old mode 100755 new mode 100644 diff --git a/core/continuations/continuations-tests.factor b/core/continuations/continuations-tests.factor old mode 100755 new mode 100644 diff --git a/core/continuations/continuations.factor b/core/continuations/continuations.factor old mode 100755 new mode 100644 diff --git a/core/definitions/definitions-docs.factor b/core/definitions/definitions-docs.factor old mode 100755 new mode 100644 diff --git a/core/definitions/definitions-tests.factor b/core/definitions/definitions-tests.factor old mode 100755 new mode 100644 diff --git a/core/definitions/definitions.factor b/core/definitions/definitions.factor old mode 100755 new mode 100644 diff --git a/core/destructors/destructors-docs.factor b/core/destructors/destructors-docs.factor old mode 100755 new mode 100644 diff --git a/core/destructors/destructors-tests.factor b/core/destructors/destructors-tests.factor old mode 100755 new mode 100644 diff --git a/core/destructors/destructors.factor b/core/destructors/destructors.factor old mode 100755 new mode 100644 diff --git a/core/effects/effects.factor b/core/effects/effects.factor old mode 100755 new mode 100644 diff --git a/core/generic/generic-docs.factor b/core/generic/generic-docs.factor old mode 100755 new mode 100644 diff --git a/core/generic/generic-tests.factor b/core/generic/generic-tests.factor old mode 100755 new mode 100644 index 22c690ffaf..aae76184ff --- a/core/generic/generic-tests.factor +++ b/core/generic/generic-tests.factor @@ -222,3 +222,17 @@ M: integer a-generic a-word ; M: boii jeah ; "> eval ] unit-test + +! call-next-method cache test +GENERIC: c-n-m-cache ( a -- b ) + +! Force it to be unoptimized +M: fixnum c-n-m-cache { } [ ] like call call-next-method ; +M: integer c-n-m-cache 1 + ; +M: number c-n-m-cache ; + +[ 3 ] [ 2 c-n-m-cache ] unit-test + +[ ] [ [ { integer c-n-m-cache } forget ] with-compilation-unit ] unit-test + +[ 2 ] [ 2 c-n-m-cache ] unit-test diff --git a/core/generic/generic.factor b/core/generic/generic.factor old mode 100755 new mode 100644 index 026e372912..095a8d5dcc --- a/core/generic/generic.factor +++ b/core/generic/generic.factor @@ -45,7 +45,9 @@ GENERIC: effective-method ( generic -- method ) GENERIC: next-method-quot* ( class generic combination -- quot ) : next-method-quot ( class generic -- quot ) - dup "combination" word-prop next-method-quot* ; + next-method-quot-cache get [ + dup "combination" word-prop next-method-quot* + ] 2cache ; : (call-next-method) ( class generic -- ) next-method-quot call ; @@ -99,10 +101,11 @@ M: method-body crossref? 2bi ; : create-method ( class generic -- method ) - 2dup method dup [ - 2nip - ] [ - drop [ dup ] 2keep reveal-method + 2dup method dup [ 2nip ] [ + drop + [ dup ] 2keep + reveal-method + reset-caches ] if ; PREDICATE: default-method < word "default" word-prop ; @@ -149,8 +152,8 @@ M: method-body forget* ] keep eq? [ [ [ delete-at ] with-methods ] - [ [ delete-at ] with-implementors ] - 2bi + [ [ delete-at ] with-implementors ] 2bi + reset-caches ] [ 2drop ] if ] if ] diff --git a/core/generic/math/math-docs.factor b/core/generic/math/math-docs.factor old mode 100755 new mode 100644 diff --git a/core/generic/math/math.factor b/core/generic/math/math.factor old mode 100755 new mode 100644 diff --git a/core/growable/growable-docs.factor b/core/growable/growable-docs.factor old mode 100755 new mode 100644 diff --git a/core/growable/growable-tests.factor b/core/growable/growable-tests.factor old mode 100755 new mode 100644 diff --git a/core/hashtables/hashtables-docs.factor b/core/hashtables/hashtables-docs.factor old mode 100755 new mode 100644 diff --git a/core/hashtables/hashtables-tests.factor b/core/hashtables/hashtables-tests.factor old mode 100755 new mode 100644 diff --git a/core/hashtables/hashtables.factor b/core/hashtables/hashtables.factor old mode 100755 new mode 100644 diff --git a/core/init/init.factor b/core/init/init.factor old mode 100755 new mode 100644 diff --git a/core/io/backend/backend-tests.factor b/core/io/backend/backend-tests.factor old mode 100755 new mode 100644 diff --git a/core/io/backend/backend.factor b/core/io/backend/backend.factor old mode 100755 new mode 100644 index 0760063f0d..0c13277106 --- a/core/io/backend/backend.factor +++ b/core/io/backend/backend.factor @@ -6,6 +6,10 @@ IN: io.backend SYMBOL: io-backend +SINGLETON: c-io-backend + +c-io-backend io-backend set-global + HOOK: init-io io-backend ( -- ) HOOK: (init-stdio) io-backend ( -- stdin stdout stderr ) diff --git a/core/io/binary/binary-tests.factor b/core/io/binary/binary-tests.factor old mode 100755 new mode 100644 diff --git a/core/io/binary/binary.factor b/core/io/binary/binary.factor old mode 100755 new mode 100644 diff --git a/core/io/encodings/binary/binary.factor b/core/io/encodings/binary/binary.factor old mode 100755 new mode 100644 diff --git a/core/io/encodings/encodings-tests.factor b/core/io/encodings/encodings-tests.factor old mode 100755 new mode 100644 diff --git a/core/io/encodings/encodings.factor b/core/io/encodings/encodings.factor old mode 100755 new mode 100644 diff --git a/core/io/encodings/utf8/utf8-docs.factor b/core/io/encodings/utf8/utf8-docs.factor old mode 100755 new mode 100644 diff --git a/core/io/encodings/utf8/utf8-tests.factor b/core/io/encodings/utf8/utf8-tests.factor old mode 100755 new mode 100644 diff --git a/core/io/encodings/utf8/utf8.factor b/core/io/encodings/utf8/utf8.factor old mode 100755 new mode 100644 diff --git a/core/io/files/files-docs.factor b/core/io/files/files-docs.factor old mode 100755 new mode 100644 diff --git a/core/io/files/files-tests.factor b/core/io/files/files-tests.factor old mode 100755 new mode 100644 diff --git a/core/io/files/files.factor b/core/io/files/files.factor old mode 100755 new mode 100644 index 1634b7a3f1..bc84aa5d21 --- a/core/io/files/files.factor +++ b/core/io/files/files.factor @@ -153,7 +153,7 @@ PRIVATE> "." last-split1 nip ; ! File info -TUPLE: file-info type size permissions modified ; +TUPLE: file-info type size permissions created modified accessed ; HOOK: file-info io-backend ( path -- info ) diff --git a/core/io/io-docs.factor b/core/io/io-docs.factor old mode 100755 new mode 100644 diff --git a/core/io/io-tests.factor b/core/io/io-tests.factor old mode 100755 new mode 100644 diff --git a/core/io/io.factor b/core/io/io.factor old mode 100755 new mode 100644 diff --git a/core/io/streams/c/c-docs.factor b/core/io/streams/c/c-docs.factor old mode 100755 new mode 100644 diff --git a/core/io/streams/c/c-tests.factor b/core/io/streams/c/c-tests.factor old mode 100755 new mode 100644 diff --git a/core/io/streams/c/c.factor b/core/io/streams/c/c.factor old mode 100755 new mode 100644 index 780d892d2e..1e12d7e956 --- a/core/io/streams/c/c.factor +++ b/core/io/streams/c/c.factor @@ -54,26 +54,28 @@ M: c-reader stream-read-until M: c-reader dispose* handle>> fclose ; -M: object init-io ; +M: c-io-backend init-io ; : stdin-handle 11 getenv ; : stdout-handle 12 getenv ; : stderr-handle 61 getenv ; -M: object (init-stdio) +: init-c-stdio ( -- stdin stdout stderr ) stdin-handle stdout-handle stderr-handle ; -M: object io-multiplex 60 60 * 1000 * or (sleep) ; +M: c-io-backend (init-stdio) init-c-stdio ; -M: object (file-reader) +M: c-io-backend io-multiplex 60 60 * 1000 * or (sleep) ; + +M: c-io-backend (file-reader) "rb" fopen ; -M: object (file-writer) +M: c-io-backend (file-writer) "wb" fopen ; -M: object (file-appender) +M: c-io-backend (file-appender) "ab" fopen ; : show ( msg -- ) diff --git a/core/io/streams/nested/nested.factor b/core/io/streams/nested/nested.factor old mode 100755 new mode 100644 diff --git a/core/io/streams/string/string.factor b/core/io/streams/string/string.factor old mode 100755 new mode 100644 diff --git a/core/kernel/kernel-docs.factor b/core/kernel/kernel-docs.factor old mode 100755 new mode 100644 diff --git a/core/kernel/kernel-tests.factor b/core/kernel/kernel-tests.factor old mode 100755 new mode 100644 diff --git a/core/kernel/kernel.factor b/core/kernel/kernel.factor old mode 100755 new mode 100644 diff --git a/core/layouts/layouts-docs.factor b/core/layouts/layouts-docs.factor old mode 100755 new mode 100644 diff --git a/core/layouts/layouts-tests.factor b/core/layouts/layouts-tests.factor old mode 100755 new mode 100644 diff --git a/core/layouts/layouts.factor b/core/layouts/layouts.factor old mode 100755 new mode 100644 diff --git a/core/math/floats/floats-tests.factor b/core/math/floats/floats-tests.factor old mode 100755 new mode 100644 diff --git a/core/math/floats/floats.factor b/core/math/floats/floats.factor old mode 100755 new mode 100644 diff --git a/core/math/integers/integers-docs.factor b/core/math/integers/integers-docs.factor old mode 100755 new mode 100644 diff --git a/core/math/integers/integers-tests.factor b/core/math/integers/integers-tests.factor old mode 100755 new mode 100644 diff --git a/core/math/integers/integers.factor b/core/math/integers/integers.factor old mode 100755 new mode 100644 diff --git a/core/math/math-docs.factor b/core/math/math-docs.factor old mode 100755 new mode 100644 diff --git a/core/math/math.factor b/core/math/math.factor old mode 100755 new mode 100644 diff --git a/core/math/parser/parser-tests.factor b/core/math/parser/parser-tests.factor old mode 100755 new mode 100644 index aad87ca995..0fb2559854 --- a/core/math/parser/parser-tests.factor +++ b/core/math/parser/parser-tests.factor @@ -108,3 +108,6 @@ unit-test [ -1.0/0.0 ] [ "-1/0." string>number ] unit-test [ "-0.0" ] [ -0.0 number>string ] unit-test + +[ "-3/4" ] [ -3/4 number>string ] unit-test +[ "-1-1/4" ] [ -5/4 number>string ] unit-test diff --git a/core/math/parser/parser.factor b/core/math/parser/parser.factor old mode 100755 new mode 100644 index a126bbea8e..0134693761 --- a/core/math/parser/parser.factor +++ b/core/math/parser/parser.factor @@ -105,7 +105,7 @@ GENERIC# >base 1 ( n radix -- str ) base) ( n -- str ) radix get >base ; +: (>base) ( n -- str ) radix get positive>base ; PRIVATE> @@ -123,7 +123,7 @@ M: integer >base M: ratio >base [ dup 0 < negative? set - 1 /mod + abs 1 /mod [ dup zero? [ drop "" ] [ (>base) sign append ] if ] [ [ numerator (>base) ] diff --git a/core/memory/memory-docs.factor b/core/memory/memory-docs.factor old mode 100755 new mode 100644 diff --git a/core/memory/memory-tests.factor b/core/memory/memory-tests.factor old mode 100755 new mode 100644 diff --git a/core/namespaces/namespaces-docs.factor b/core/namespaces/namespaces-docs.factor old mode 100755 new mode 100644 diff --git a/core/parser/parser-docs.factor b/core/parser/parser-docs.factor old mode 100755 new mode 100644 diff --git a/core/parser/parser-tests.factor b/core/parser/parser-tests.factor old mode 100755 new mode 100644 diff --git a/core/parser/parser.factor b/core/parser/parser.factor old mode 100755 new mode 100644 diff --git a/core/parser/test/assert-depth.factor b/core/parser/test/assert-depth.factor old mode 100755 new mode 100644 diff --git a/core/quotations/quotations-docs.factor b/core/quotations/quotations-docs.factor old mode 100755 new mode 100644 diff --git a/core/quotations/quotations-tests.factor b/core/quotations/quotations-tests.factor old mode 100755 new mode 100644 diff --git a/core/quotations/quotations.factor b/core/quotations/quotations.factor old mode 100755 new mode 100644 diff --git a/core/sbufs/sbufs.factor b/core/sbufs/sbufs.factor old mode 100755 new mode 100644 diff --git a/core/sequences/sequences-docs.factor b/core/sequences/sequences-docs.factor old mode 100755 new mode 100644 diff --git a/core/sequences/sequences-tests.factor b/core/sequences/sequences-tests.factor old mode 100755 new mode 100644 diff --git a/core/sequences/sequences.factor b/core/sequences/sequences.factor old mode 100755 new mode 100644 index 267238a502..63cc14d1d7 --- a/core/sequences/sequences.factor +++ b/core/sequences/sequences.factor @@ -27,7 +27,7 @@ M: sequence lengthen 2dup length > [ set-length ] [ 2drop ] if ; M: sequence shorten 2dup length < [ set-length ] [ 2drop ] if ; -: empty? ( seq -- ? ) length zero? ; inline +: empty? ( seq -- ? ) length 0 = ; inline : if-empty ( seq quot1 quot2 -- ) [ dup empty? ] [ [ drop ] prepose ] [ ] tri* if ; inline @@ -362,7 +362,7 @@ PRIVATE> prepose curry ; inline : (interleave) ( n elt between quot -- ) - roll zero? [ nip ] [ swapd 2slip ] if call ; inline + roll 0 = [ nip ] [ swapd 2slip ] if call ; inline PRIVATE> @@ -530,7 +530,7 @@ M: sequence <=> [ -rot 2nth-unsafe <=> ] [ [ length ] compare ] if* ; : sequence= ( seq1 seq2 -- ? ) - 2dup [ length ] bi@ number= + 2dup [ length ] bi@ = [ mismatch not ] [ 2drop f ] if ; inline : sequence-hashcode-step ( oldhash newpart -- newhash ) @@ -547,7 +547,7 @@ M: reversed equal? over reversed? [ sequence= ] [ 2drop f ] if ; M: slice equal? over slice? [ sequence= ] [ 2drop f ] if ; : move ( to from seq -- ) - 2over number= + 2over = [ 3drop ] [ [ nth swap ] [ set-nth ] bi ] if ; inline r 2over + pick r> move >r 1+ r> ] keep @@ -590,7 +590,7 @@ PRIVATE> ] if ; : move-forward ( shift from to seq -- ) - 2over number= [ + 2over = [ 2drop 2drop ] [ [ >r pick >r dup dup r> + swap r> move 1- ] keep @@ -607,7 +607,7 @@ PRIVATE> PRIVATE> : open-slice ( shift from seq -- ) - pick zero? [ + pick 0 = [ 3drop ] [ pick over length + over >r >r @@ -680,7 +680,7 @@ PRIVATE> : padding ( seq n elt quot -- newseq ) [ - [ over length [-] dup zero? [ drop ] ] dip + [ over length [-] dup 0 = [ drop ] ] dip [ ] curry ] dip compose if ; inline diff --git a/core/slots/slots-docs.factor b/core/slots/slots-docs.factor old mode 100755 new mode 100644 diff --git a/core/slots/slots.factor b/core/slots/slots.factor old mode 100755 new mode 100644 diff --git a/core/sorting/sorting-tests.factor b/core/sorting/sorting-tests.factor old mode 100755 new mode 100644 diff --git a/core/sorting/sorting.factor b/core/sorting/sorting.factor old mode 100755 new mode 100644 diff --git a/core/source-files/source-files-docs.factor b/core/source-files/source-files-docs.factor old mode 100755 new mode 100644 diff --git a/core/source-files/source-files.factor b/core/source-files/source-files.factor old mode 100755 new mode 100644 diff --git a/core/splitting/splitting.factor b/core/splitting/splitting.factor old mode 100755 new mode 100644 diff --git a/core/strings/strings-docs.factor b/core/strings/strings-docs.factor old mode 100755 new mode 100644 diff --git a/core/strings/strings-tests.factor b/core/strings/strings-tests.factor old mode 100755 new mode 100644 diff --git a/core/strings/strings.factor b/core/strings/strings.factor old mode 100755 new mode 100644 diff --git a/core/syntax/syntax-docs.factor b/core/syntax/syntax-docs.factor old mode 100755 new mode 100644 index 905cd87903..2b7de36d56 --- a/core/syntax/syntax-docs.factor +++ b/core/syntax/syntax-docs.factor @@ -573,12 +573,12 @@ $nl } ; HELP: initial: -{ $syntax "TUPLE: ... { \"slot\" initial: value } ... ;" } +{ $syntax "TUPLE: ... { slot initial: value } ... ;" } { $values { "slot" "a slot name" } { "value" "any literal" } } { $description "Specifies an initial value for a tuple slot." } ; HELP: read-only -{ $syntax "TUPLE: ... { \"slot\" read-only } ... ;" } +{ $syntax "TUPLE: ... { slot read-only } ... ;" } { $values { "slot" "a slot name" } } { $description "Defines a tuple slot to be read-only. If a tuple has read-only slots, instances of the tuple should only be created by calling " { $link boa } ", instead of " { $link new } ". Using " { $link boa } " is the only way to set the value of a read-only slot." } ; diff --git a/core/syntax/syntax.factor b/core/syntax/syntax.factor old mode 100755 new mode 100644 diff --git a/core/system/system-docs.factor b/core/system/system-docs.factor old mode 100755 new mode 100644 diff --git a/core/system/system-tests.factor b/core/system/system-tests.factor old mode 100755 new mode 100644 diff --git a/core/system/system.factor b/core/system/system.factor old mode 100755 new mode 100644 index 3c207c4ab5..6c9d838fa4 --- a/core/system/system.factor +++ b/core/system/system.factor @@ -11,7 +11,7 @@ SINGLETON: ppc UNION: x86 x86.32 x86.64 ; -: cpu ( -- class ) \ cpu get ; +: cpu ( -- class ) \ cpu get-global ; foldable SINGLETON: winnt SINGLETON: wince @@ -29,7 +29,7 @@ UNION: bsd freebsd netbsd openbsd macosx ; UNION: unix bsd solaris linux ; -: os ( -- class ) \ os get ; +: os ( -- class ) \ os get-global ; foldable r >alist r> seq-uses ; + M: callable (quot-uses) seq-uses ; M: wrapper (quot-uses) >r wrapped>> r> (quot-uses) ; diff --git a/extra/assoc-heaps/assoc-heaps-docs.factor b/extra/assoc-heaps/assoc-heaps-docs.factor new file mode 100644 index 0000000000..8beaf9c4b1 --- /dev/null +++ b/extra/assoc-heaps/assoc-heaps-docs.factor @@ -0,0 +1,33 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: help.markup help.syntax io.streams.string ; +IN: assoc-heaps + +HELP: +{ $description "Constructs a new " { $link assoc-heap } " from two existing data structures." } ; + +HELP: +{ $values + + { "unique-heap" assoc-heap } } +{ $description "Creates a new " { $link assoc-heap } " where the assoc is a hashtable and the heap is a max-heap. Popping an element from the heap leaves this element in the hashtable to ensure that the element will not be processed again." } ; + +HELP: +{ $values + { "unique-heap" assoc-heap } } +{ $description "Creates a new " { $link assoc-heap } " where the assoc is a hashtable and the heap is a min-heap. Popping an element from the heap leaves this element in the hashtable to ensure that the element will not be processed again." } ; + +{ } related-words + +HELP: assoc-heap +{ $description "A data structure containing an assoc and a heap to get certain properties with better time constraints at the expense of more space and complexity. For instance, a hashtable and a heap can be combined into one assoc-heap to get a sorted data structure with O(1) lookup. Operations on assoc-heap may update both the assoc and the heap or leave them out of sync if it's advantageous." } ; + +ARTICLE: "assoc-heaps" "Associative heaps" +"The " { $vocab-link "assoc-heaps" } " vocabulary combines exists to synthesize data structures with better time properties than either of the two component data structures alone." $nl +"Associative heap constructor:" +{ $subsection } +"Unique heaps:" +{ $subsection } +{ $subsection } ; + +ABOUT: "assoc-heaps" diff --git a/extra/assoc-heaps/assoc-heaps-tests.factor b/extra/assoc-heaps/assoc-heaps-tests.factor new file mode 100644 index 0000000000..6ea3fe14a4 --- /dev/null +++ b/extra/assoc-heaps/assoc-heaps-tests.factor @@ -0,0 +1,4 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: tools.test assoc-heaps ; +IN: assoc-heaps.tests diff --git a/extra/assoc-heaps/assoc-heaps.factor b/extra/assoc-heaps/assoc-heaps.factor new file mode 100644 index 0000000000..a495aed626 --- /dev/null +++ b/extra/assoc-heaps/assoc-heaps.factor @@ -0,0 +1,30 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors assocs hashtables heaps kernel ; +IN: assoc-heaps + +TUPLE: assoc-heap assoc heap ; + +C: assoc-heap + +: ( -- unique-heap ) + H{ } clone ; + +: ( -- unique-heap ) + H{ } clone ; + +M: assoc-heap heap-push* ( value key assoc-heap -- entry ) + pick over assoc>> key? [ + 3drop f + ] [ + [ assoc>> swapd set-at ] [ heap>> heap-push* ] 3bi + ] if ; + +M: assoc-heap heap-pop ( assoc-heap -- value key ) + heap>> heap-pop ; + +M: assoc-heap heap-peek ( assoc-heap -- value key ) + heap>> heap-peek ; + +M: assoc-heap heap-empty? ( assoc-heap -- value key ) + heap>> heap-empty? ; diff --git a/extra/assoc-heaps/authors.txt b/extra/assoc-heaps/authors.txt new file mode 100644 index 0000000000..b4bd0e7b35 --- /dev/null +++ b/extra/assoc-heaps/authors.txt @@ -0,0 +1 @@ +Doug Coleman \ No newline at end of file diff --git a/extra/benchmark/mandel/colors/colors.factor b/extra/benchmark/mandel/colors/colors.factor index 7bbb25a47d..218f566eda 100644 --- a/extra/benchmark/mandel/colors/colors.factor +++ b/extra/benchmark/mandel/colors/colors.factor @@ -1,10 +1,11 @@ USING: math math.order kernel arrays byte-arrays sequences -colors.hsv benchmark.mandel.params ; +colors.hsv benchmark.mandel.params accessors colors ; IN: benchmark.mandel.colors : scale 255 * >fixnum ; inline -: scale-rgb ( r g b -- n ) [ scale ] tri@ 3byte-array ; +: scale-rgb ( rgba -- n ) + [ red>> scale ] [ green>> scale ] [ blue>> scale ] tri 3byte-array ; : sat 0.85 ; inline : val 0.85 ; inline @@ -12,7 +13,7 @@ IN: benchmark.mandel.colors : ( nb-cols -- map ) dup [ 360 * swap 1+ / sat val - 3array hsv>rgb first3 scale-rgb + 1 >rgba scale-rgb ] with map ; : color-map ( -- map ) diff --git a/extra/bubble-chamber/bubble-chamber-docs.factor b/extra/bubble-chamber/bubble-chamber-docs.factor index 47331efd7e..72ffb63848 100644 --- a/extra/bubble-chamber/bubble-chamber-docs.factor +++ b/extra/bubble-chamber/bubble-chamber-docs.factor @@ -55,48 +55,30 @@ HELP: axion ARTICLE: "bubble-chamber" "Bubble Chamber" - { $subsection "bubble-chamber-introduction" } - { $subsection "bubble-chamber-particles" } - { $subsection "bubble-chamber-author" } - { $subsection "bubble-chamber-running" } ; - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -ARTICLE: "bubble-chamber-introduction" "Introduction" - -"The Bubble Chamber is a generative painting system of imaginary " +"The " { $vocab-link "bubble-chamber" } +" is a generative painting system of imaginary " "colliding particles. A single super-massive collision produces a " "discrete universe of four particle types. Particles draw their " -"positions over time as pixel exposures. " ; - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -ARTICLE: "bubble-chamber-particles" "Particles" - +"positions over time as pixel exposures.\n" +"\n" "Four types of particles exist. The behavior and graphic appearance of " -"each particle type is unique." - +"each particle type is unique.\n" { $subsection muon } { $subsection quark } { $subsection hadron } - { $subsection axion } ; + { $subsection axion } +"\n" +"After you run the vocabulary, a window will appear. Click the " +"mouse in a random area to fire 11 particles of each type. " +"Another way to fire particles is to press the " +"spacebar. This fires all the particles.\n" +"\n" +"Bubble Chamber was created by Jared Tarbell. " +"It was originally implemented in Processing. " +"It was ported to Factor by Eduardo Cavazos. " +"The original work is on display here: " +{ $url +"http://www.complexification.net/gallery/machines/bubblechamber/" } ; -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +ABOUT: "bubble-chamber" -ARTICLE: "bubble-chamber-author" "Author" - - "Bubble Chamber was created by Jared Tarbell. " - "It was originally implemented in Processing. " - "It was ported to Factor by Eduardo Cavazos. " - "The original work is on display here: " - { $url - "http://www.complexification.net/gallery/machines/bubblechamber/" } ; - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -ARTICLE: "bubble-chamber-running" "How to use" - - "After you run the vocabulary, a window will appear. Click the " - "mouse in a random area to fire 11 particles of each type. " - "Another way to fire particles is to press the " - "spacebar. This fires all the particles." ; \ No newline at end of file diff --git a/extra/color-picker/color-picker.factor b/extra/color-picker/color-picker.factor index 4a0c148145..6ed8c1220c 100755 --- a/extra/color-picker/color-picker.factor +++ b/extra/color-picker/color-picker.factor @@ -23,7 +23,7 @@ M: color-preview model-changed swap value>> >>interior relayout-1 ; : ( model -- model ) - [ [ 256 /f ] map 1 suffix first4 rgba boa ] ; + [ first3 [ 256 /f ] tri@ 1 ] ; : ( -- model gadget ) 3 [ 0 0 0 255 ] replicate diff --git a/extra/crypto/barrett/barrett-tests.factor b/extra/crypto/barrett/barrett-tests.factor index be52240372..01163f730f 100644 --- a/extra/crypto/barrett/barrett-tests.factor +++ b/extra/crypto/barrett/barrett-tests.factor @@ -1,4 +1,7 @@ +! Copyright (C) 2008 DoDoug Coleman. +! See http://factorcode.org/license.txt for BSD license. USING: crypto.barrett kernel math namespaces tools.test ; +IN: crypto.barrett.tests [ HEX: 1f63edfb7e838622c7412eafaf0439cf0cdf3aae8bdd09e2de69b509a53883a83560d5ce50ea039e4 ] [ HEX: 827c67f31b2b46afa49ed95d7f7a3011e5875f7052d4c55437ce726d3c6ce0dc9c445fda63b6dc4e 16 barrett-mu ] unit-test diff --git a/extra/crypto/barrett/barrett.factor b/extra/crypto/barrett/barrett.factor index 4a070190e3..25e67d01ce 100644 --- a/extra/crypto/barrett/barrett.factor +++ b/extra/crypto/barrett/barrett.factor @@ -1,14 +1,12 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. USING: kernel math math.functions ; IN: crypto.barrett : barrett-mu ( n size -- mu ) #! Calculates Barrett's reduction parameter mu #! size = word size in bits (8, 16, 32, 64, ...) - ! over log2 1+ over / 2 * >r 2 swap ^ r> ^ swap / floor ; - [ - [ log2 1+ ] [ / 2 * ] bi* - ] [ - 2^ rot ^ swap /i - ] 2bi ; + [ [ log2 1+ ] [ / 2 * ] bi* ] + [ 2^ rot ^ swap /i ] 2bi ; diff --git a/extra/crypto/common/common.factor b/extra/crypto/common/common.factor deleted file mode 100644 index 61cc11f959..0000000000 --- a/extra/crypto/common/common.factor +++ /dev/null @@ -1,17 +0,0 @@ -USING: arrays kernel io io.binary sbufs splitting grouping -strings sequences namespaces math math.parser parser -hints math.bitwise assocs ; -IN: crypto.common - -: (nth-int) ( string n -- int ) - 2 shift dup 4 + rot ; inline - -: nth-int ( string n -- int ) (nth-int) le> ; inline - -: update ( num var -- ) [ w+ ] change ; inline - -SYMBOL: big-endian? - -: mod-nth ( n seq -- elt ) - #! 5 "abcd" -> b - [ length mod ] [ nth ] bi ; diff --git a/extra/crypto/hmac/hmac.factor b/extra/crypto/hmac/hmac.factor index 6e30f19775..d98e8a9798 100755 --- a/extra/crypto/hmac/hmac.factor +++ b/extra/crypto/hmac/hmac.factor @@ -1,4 +1,4 @@ -USING: arrays combinators crypto.common checksums checksums.md5 +USING: arrays combinators checksums checksums.md5 checksums.sha1 checksums.md5.private io io.binary io.files io.streams.byte-array kernel math math.vectors memoize sequences io.encodings.binary ; diff --git a/extra/crypto/random.factor b/extra/crypto/random.factor deleted file mode 100755 index f2d3b0555a..0000000000 --- a/extra/crypto/random.factor +++ /dev/null @@ -1,40 +0,0 @@ -USING: kernel math math-contrib sequences namespaces errors -hashtables words arrays parser compiler syntax io ; -IN: crypto -: make-bits ( quot numbits -- n | quot: -- 0/1 ) - 0 -rot [ drop dup call rot 1 shift bitor swap ] each drop ; - -: random-bytes ( m -- n ) - >r [ 2 random ] r> 8 * make-bits ; - -! DEFER: random-bits -: add-bit ( bit integer -- integer ) 1 shift bitor ; -: append-bits ( inta intb nbits -- int ) swapd shift bitor ; -: large-random-bits ( n -- int ) - #! random number with high bit and low bit enabled (odd) - 2 swap ^ [ random ] keep -1 shift 1 bitor bitor ; -! : next-double ( -- f ) 53 random-bits 9007199254740992 /f ; - -: 0count ( integer -- n ) 0 swap [ 0 = [ 1+ ] when ] each-bit ; -: 1count ( integer -- n ) 0 swap [ 1 = [ 1+ ] when ] each-bit ; - -: bit-reverse-table -{ - HEX: 00 HEX: 80 HEX: 40 HEX: C0 HEX: 20 HEX: A0 HEX: 60 HEX: E0 HEX: 10 HEX: 90 HEX: 50 HEX: D0 HEX: 30 HEX: B0 HEX: 70 HEX: F0 - HEX: 08 HEX: 88 HEX: 48 HEX: C8 HEX: 28 HEX: A8 HEX: 68 HEX: E8 HEX: 18 HEX: 98 HEX: 58 HEX: D8 HEX: 38 HEX: B8 HEX: 78 HEX: F8 - HEX: 04 HEX: 84 HEX: 44 HEX: C4 HEX: 24 HEX: A4 HEX: 64 HEX: E4 HEX: 14 HEX: 94 HEX: 54 HEX: D4 HEX: 34 HEX: B4 HEX: 74 HEX: F4 - HEX: 0C HEX: 8C HEX: 4C HEX: CC HEX: 2C HEX: AC HEX: 6C HEX: EC HEX: 1C HEX: 9C HEX: 5C HEX: DC HEX: 3C HEX: BC HEX: 7C HEX: FC - HEX: 02 HEX: 82 HEX: 42 HEX: C2 HEX: 22 HEX: A2 HEX: 62 HEX: E2 HEX: 12 HEX: 92 HEX: 52 HEX: D2 HEX: 32 HEX: B2 HEX: 72 HEX: F2 - HEX: 0A HEX: 8A HEX: 4A HEX: CA HEX: 2A HEX: AA HEX: 6A HEX: EA HEX: 1A HEX: 9A HEX: 5A HEX: DA HEX: 3A HEX: BA HEX: 7A HEX: FA - HEX: 06 HEX: 86 HEX: 46 HEX: C6 HEX: 26 HEX: A6 HEX: 66 HEX: E6 HEX: 16 HEX: 96 HEX: 56 HEX: D6 HEX: 36 HEX: B6 HEX: 76 HEX: F6 - HEX: 0E HEX: 8E HEX: 4E HEX: CE HEX: 2E HEX: AE HEX: 6E HEX: EE HEX: 1E HEX: 9E HEX: 5E HEX: DE HEX: 3E HEX: BE HEX: 7E HEX: FE - HEX: 01 HEX: 81 HEX: 41 HEX: C1 HEX: 21 HEX: A1 HEX: 61 HEX: E1 HEX: 11 HEX: 91 HEX: 51 HEX: D1 HEX: 31 HEX: B1 HEX: 71 HEX: F1 - HEX: 09 HEX: 89 HEX: 49 HEX: C9 HEX: 29 HEX: A9 HEX: 69 HEX: E9 HEX: 19 HEX: 99 HEX: 59 HEX: D9 HEX: 39 HEX: B9 HEX: 79 HEX: F9 - HEX: 05 HEX: 85 HEX: 45 HEX: C5 HEX: 25 HEX: A5 HEX: 65 HEX: E5 HEX: 15 HEX: 95 HEX: 55 HEX: D5 HEX: 35 HEX: B5 HEX: 75 HEX: F5 - HEX: 0D HEX: 8D HEX: 4D HEX: CD HEX: 2D HEX: AD HEX: 6D HEX: ED HEX: 1D HEX: 9D HEX: 5D HEX: DD HEX: 3D HEX: BD HEX: 7D HEX: FD - HEX: 03 HEX: 83 HEX: 43 HEX: C3 HEX: 23 HEX: A3 HEX: 63 HEX: E3 HEX: 13 HEX: 93 HEX: 53 HEX: D3 HEX: 33 HEX: B3 HEX: 73 HEX: F3 - HEX: 0B HEX: 8B HEX: 4B HEX: CB HEX: 2B HEX: AB HEX: 6B HEX: EB HEX: 1B HEX: 9B HEX: 5B HEX: DB HEX: 3B HEX: BB HEX: 7B HEX: FB - HEX: 07 HEX: 87 HEX: 47 HEX: C7 HEX: 27 HEX: A7 HEX: 67 HEX: E7 HEX: 17 HEX: 97 HEX: 57 HEX: D7 HEX: 37 HEX: B7 HEX: 77 HEX: F7 - HEX: 0F HEX: 8F HEX: 4F HEX: CF HEX: 2F HEX: AF HEX: 6F HEX: EF HEX: 1F HEX: 9F HEX: 5F HEX: DF HEX: 3F HEX: BF HEX: 7F HEX: FF -} ; inline - diff --git a/extra/crypto/rsa/rsa-tests.factor b/extra/crypto/rsa/rsa-tests.factor index 7de6bed76f..03aca0578b 100644 --- a/extra/crypto/rsa/rsa-tests.factor +++ b/extra/crypto/rsa/rsa-tests.factor @@ -1,4 +1,5 @@ USING: kernel math namespaces crypto.rsa tools.test ; +IN: crypto.rsa.tests [ 123456789 ] [ 128 generate-rsa-keypair 123456789 over rsa-encrypt swap rsa-decrypt ] unit-test [ 123456789 ] [ 129 generate-rsa-keypair 123456789 over rsa-encrypt swap rsa-decrypt ] unit-test diff --git a/extra/crypto/rsa/rsa.factor b/extra/crypto/rsa/rsa.factor index 5d3228db10..b1eb907547 100644 --- a/extra/crypto/rsa/rsa.factor +++ b/extra/crypto/rsa/rsa.factor @@ -1,3 +1,5 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. USING: math.miller-rabin kernel math math.functions namespaces sequences accessors ; IN: crypto.rsa diff --git a/extra/crypto/summary.txt b/extra/crypto/summary.txt index edd7c44333..0421c07ca0 100644 --- a/extra/crypto/summary.txt +++ b/extra/crypto/summary.txt @@ -1 +1 @@ -Cryptographic algorithms implemented in Factor, such as MD5 and SHA1 +HMAC, XOR, Barrett, RSA, Timing diff --git a/extra/crypto/xor/xor-tests.factor b/extra/crypto/xor/xor-tests.factor index ef781b9f25..f3a13e086f 100644 --- a/extra/crypto/xor/xor-tests.factor +++ b/extra/crypto/xor/xor-tests.factor @@ -2,23 +2,24 @@ USING: continuations crypto.xor kernel strings tools.test ; IN: crypto.xor.tests ! No key -[ "" dup xor-crypt ] [ T{ no-xor-key f } = ] must-fail-with -[ { } dup xor-crypt ] [ T{ no-xor-key f } = ] must-fail-with -[ V{ } dup xor-crypt ] [ T{ no-xor-key f } = ] must-fail-with -[ "" "asdf" dupd xor-crypt xor-crypt ] [ T{ no-xor-key f } = ] must-fail-with +[ "" dup xor-crypt ] [ T{ empty-xor-key } = ] must-fail-with +[ { } dup xor-crypt ] [ T{ empty-xor-key } = ] must-fail-with +[ V{ } dup xor-crypt ] [ T{ empty-xor-key } = ] must-fail-with +[ "" "asdf" dupd xor-crypt xor-crypt ] [ T{ empty-xor-key } = ] must-fail-with ! a xor a = 0 [ "\0\0\0\0\0\0\0" ] [ "abcdefg" dup xor-crypt ] unit-test [ { 15 15 15 15 } ] [ { 10 10 10 10 } { 5 5 5 5 } xor-crypt ] unit-test -[ "asdf" ] [ "key" "asdf" dupd xor-crypt xor-crypt >string ] unit-test -[ "" ] [ "key" "" xor-crypt >string ] unit-test +[ "asdf" ] [ "asdf" "key" [ xor-crypt ] [ xor-crypt ] bi >string ] unit-test +[ "" ] [ "" "key" xor-crypt >string ] unit-test [ "a longer message...!" ] [ - "." - "a longer message...!" dupd xor-crypt xor-crypt >string + "a longer message...!" + "." [ xor-crypt ] [ xor-crypt ] bi >string ] unit-test [ "a longer message...!" ] [ + "a longer message...!" "a very long key, longer than the message even." - "a longer message...!" dupd xor-crypt xor-crypt >string + [ xor-crypt ] [ xor-crypt ] bi >string ] unit-test diff --git a/extra/crypto/xor/xor.factor b/extra/crypto/xor/xor.factor index 247387ebdf..6e3a605f5c 100644 --- a/extra/crypto/xor/xor.factor +++ b/extra/crypto/xor/xor.factor @@ -1,8 +1,12 @@ -USING: crypto.common kernel math sequences ; +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel math sequences fry ; IN: crypto.xor -ERROR: no-xor-key ; +: mod-nth ( n seq -- elt ) [ length mod ] [ nth ] bi ; -: xor-crypt ( key seq -- seq' ) - over empty? [ no-xor-key ] when - dup length rot [ mod-nth bitxor ] curry 2map ; +ERROR: empty-xor-key ; + +: xor-crypt ( seq key -- seq' ) + dup empty? [ empty-xor-key ] when + [ dup length ] dip '[ _ mod-nth bitxor ] 2map ; diff --git a/extra/descriptive/descriptive.factor b/extra/descriptive/descriptive.factor index 4b40747e9f..d02983d7fd 100755 --- a/extra/descriptive/descriptive.factor +++ b/extra/descriptive/descriptive.factor @@ -1,4 +1,4 @@ -USING: words kernel sequences combinators.lib locals +USING: words kernel sequences locals locals.private accessors parser namespaces continuations summary definitions generalizations arrays ; IN: descriptive diff --git a/unmaintained/digraphs/authors.txt b/extra/digraphs/authors.txt similarity index 100% rename from unmaintained/digraphs/authors.txt rename to extra/digraphs/authors.txt diff --git a/unmaintained/digraphs/digraphs-tests.factor b/extra/digraphs/digraphs-tests.factor similarity index 72% rename from unmaintained/digraphs/digraphs-tests.factor rename to extra/digraphs/digraphs-tests.factor index b113c18ca7..64589c1a99 100644 --- a/unmaintained/digraphs/digraphs-tests.factor +++ b/extra/digraphs/digraphs-tests.factor @@ -3,7 +3,9 @@ IN: digraphs.tests : test-digraph ( -- digraph ) - { { "one" 1 } { "two" 2 } { "three" 3 } { "four" 4 } { "five" 5 } } [ first2 pick add-vertex ] each - { { "one" "three" } { "one" "four" } { "two" "three" } { "two" "one" } { "three" "four" } } [ first2 pick add-edge ] each ; + { { "one" 1 } { "two" 2 } { "three" 3 } { "four" 4 } { "five" 5 } } + [ first2 pick add-vertex ] each + { { "one" "three" } { "one" "four" } { "two" "three" } { "two" "one" } { "three" "four" } } + [ first2 pick add-edge ] each ; [ 5 ] [ test-digraph topological-sort length ] unit-test diff --git a/unmaintained/digraphs/digraphs.factor b/extra/digraphs/digraphs.factor similarity index 87% rename from unmaintained/digraphs/digraphs.factor rename to extra/digraphs/digraphs.factor index 7d56c96034..5ccc0d5a60 100755 --- a/unmaintained/digraphs/digraphs.factor +++ b/extra/digraphs/digraphs.factor @@ -1,19 +1,20 @@ ! Copyright (C) 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: accessors assocs kernel sequences vectors ; +USING: accessors assocs hashtables hashtables.private kernel sequences vectors ; IN: digraphs -TUPLE: digraph ; -TUPLE: vertex value edges ; +TUPLE: digraph < hashtable ; : ( -- digraph ) - digraph new H{ } clone over set-delegate ; + 0 digraph new [ reset-hash ] keep ; + +TUPLE: vertex value edges ; : ( value -- vertex ) V{ } clone vertex boa ; : add-vertex ( key value digraph -- ) - >r swap r> set-at ; + [ swap ] dip set-at ; : children ( key digraph -- seq ) at edges>> ; diff --git a/unmaintained/digraphs/summary.txt b/extra/digraphs/summary.txt similarity index 100% rename from unmaintained/digraphs/summary.txt rename to extra/digraphs/summary.txt diff --git a/unmaintained/digraphs/tags.txt b/extra/digraphs/tags.txt similarity index 100% rename from unmaintained/digraphs/tags.txt rename to extra/digraphs/tags.txt diff --git a/extra/faq/faq.factor b/extra/faq/faq.factor index 1ab348e434..c0636c5fd7 100644 --- a/extra/faq/faq.factor +++ b/extra/faq/faq.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2007 Daniel Ehrenberg ! See http://factorcode.org/license.txt for BSD license. -USING: xml kernel sequences xml.utilities combinators.lib -math xml.data arrays assocs xml.generator xml.writer namespaces +USING: xml kernel sequences xml.utilities math xml.data +arrays assocs xml.generator xml.writer namespaces make math.parser io accessors ; IN: faq diff --git a/extra/hexdump/hexdump-docs.factor b/extra/hexdump/hexdump-docs.factor index adf31d3787..a83f64e8db 100644 --- a/extra/hexdump/hexdump-docs.factor +++ b/extra/hexdump/hexdump-docs.factor @@ -1,12 +1,22 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. USING: help.markup help.syntax kernel ; IN: hexdump HELP: hexdump. -{ $values { "seq" "a sequence" } } +{ $values { "sequence" "a sequence" } } { $description "Converts a sequence to its hexadecimal and ASCII representation sixteen characters at a time and writes it to standard out." } ; HELP: hexdump -{ $values { "seq" "a sequence" } { "str" "a string" } } +{ $values { "sequence" "a sequence" } { "string" "a string" } } { $description "Converts a sequence to its hexadecimal and ASCII representation sixteen characters at a time. Lines are separated by a newline character." } { $see-also hexdump. } ; +ARTICLE: "hexdump" "Hexdump" +"The " { $vocab-link "hexdump" } " vocabulary provides a traditional hexdump view of a sequence." $nl +"Write hexdump to string:" +{ $subsection hexdump } +"Write the hexdump to the output stream:" +{ $subsection hexdump. } ; + +ABOUT: "hexdump" diff --git a/extra/hexdump/hexdump.factor b/extra/hexdump/hexdump.factor index f444f5a4f2..618ed00802 100644 --- a/extra/hexdump/hexdump.factor +++ b/extra/hexdump/hexdump.factor @@ -1,5 +1,8 @@ -USING: arrays io io.streams.string kernel math math.parser namespaces -prettyprint sequences sequences.lib splitting grouping strings ascii ; +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: arrays io io.streams.string kernel math math.parser +namespaces prettyprint sequences splitting grouping strings +ascii ; IN: hexdump -: hexdump ( seq -- str ) + +: hexdump ( sequence -- string ) [ dup length header. 16 [ line. ] each-index ] with-string-writer ; -: hexdump. ( seq -- ) +: hexdump. ( sequence -- ) hexdump write ; diff --git a/extra/html/parser/analyzer/analyzer.factor b/extra/html/parser/analyzer/analyzer.factor index 47cd4dbbc6..095e3c3246 100755 --- a/extra/html/parser/analyzer/analyzer.factor +++ b/extra/html/parser/analyzer/analyzer.factor @@ -3,13 +3,13 @@ USING: assocs html.parser kernel math sequences strings ascii arrays generalizations shuffle unicode.case namespaces make splitting http accessors io combinators http.client urls -fry sequences.lib ; +urls.encoding fry ; IN: html.parser.analyzer TUPLE: link attributes clickable ; -: scrape-html ( url -- vector ) - http-get nip parse-html ; +: scrape-html ( url -- headers vector ) + http-get parse-html ; : find-all ( seq quot -- alist ) [ >alist ] [ '[ second @ ] ] bi* filter ; inline diff --git a/extra/io/paths/paths.factor b/extra/io/paths/paths.factor index fb4f6d3a6d..58b3518edd 100755 --- a/extra/io/paths/paths.factor +++ b/extra/io/paths/paths.factor @@ -1,14 +1,16 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. USING: io.files kernel sequences accessors -dlists deques arrays sequences.lib ; +dlists deques arrays ; IN: io.paths TUPLE: directory-iterator path bfs queue ; : qualified-directory ( path -- seq ) - dup directory [ first2 >r append-path r> 2array ] with map ; + dup directory [ first2 [ append-path ] dip 2array ] with map ; : push-directory ( path iter -- ) - >r qualified-directory r> [ + [ qualified-directory ] dip [ dup queue>> swap bfs>> [ push-front ] [ push-back ] if ] curry each ; @@ -24,27 +26,24 @@ TUPLE: directory-iterator path bfs queue ; ] if ; : iterate-directory ( iter quot -- obj ) - 2dup >r >r >r next-file dup [ - r> call dup [ - r> r> 2drop - ] [ - drop r> r> iterate-directory - ] if + over next-file [ + over call + [ 2drop ] [ iterate-directory ] if ] [ - drop r> r> r> 3drop f - ] if ; inline + 2drop f + ] if* ; inline recursive : find-file ( path bfs? quot -- path/f ) - >r r> + [ ] dip [ keep and ] curry iterate-directory ; inline : each-file ( path bfs? quot -- ) - >r r> + [ ] dip [ f ] compose iterate-directory drop ; inline : find-all-files ( path bfs? quot -- paths ) - >r r> - pusher >r [ f ] compose iterate-directory drop r> ; inline + [ ] dip + pusher [ [ f ] compose iterate-directory drop ] dip ; inline : recursive-directory ( path bfs? -- paths ) - [ ] accumulator >r each-file r> ; + [ ] accumulator [ each-file ] dip ; diff --git a/extra/irc/client/client-docs.factor b/extra/irc/client/client-docs.factor index 6bb6a6328e..6d4fae9b83 100644 --- a/extra/irc/client/client-docs.factor +++ b/extra/irc/client/client-docs.factor @@ -1,62 +1,57 @@ USING: help.markup help.syntax quotations kernel irc.messages ; IN: irc.client -HELP: irc-client "IRC Client object" -"blah" ; +HELP: irc-client "IRC Client object" ; -HELP: irc-server-listener "Listener for server messages unmanaged by other listeners" -"blah" ; +HELP: irc-server-chat "Chat for server messages unmanaged by other chats" ; -HELP: irc-channel-listener "Listener for irc channels" -"blah" ; +HELP: irc-channel-chat "Chat for irc channels" ; -HELP: irc-nick-listener "Listener for irc users" -"blah" ; +HELP: irc-nick-chat "Chat for irc users" ; -HELP: irc-profile "IRC Client profile object" -"blah" ; +HELP: irc-profile "IRC Client profile object" ; HELP: connect-irc "Connecting to an irc server" { $values { "irc-client" "an irc client object" } } { $description "Connects and logins " { $link irc-client } " using the settings specified on its " { $link irc-profile } "." } ; -HELP: add-listener "Listening to irc channels/users/etc" -{ $values { "irc-listener" "an irc listener object" } { "irc-client" "an irc client object" } } -{ $description "Registers " { $snippet "irc-listener" } " with " { $snippet "irc-client" } " and starts listening." } ; +HELP: attach-chat "Chatting with irc channels/users/etc" +{ $values { "irc-chat" "an irc chat object" } { "irc-client" "an irc client object" } } +{ $description "Registers " { $snippet "irc-chat" } " with " { $snippet "irc-client" } " and starts listening." } ; -HELP: remove-listener "Stop an unregister listener" -{ $values { "irc-listener" "an irc listener object" } { "irc-client" "an irc client object" } } -{ $description "Unregisters " { $snippet "irc-listener" } " from " { $snippet "irc-client" } " and stops listening. This is how you part from a channel." } ; +HELP: detach-chat "Stop an unregister chat" +{ $values { "irc-chat" "an irc chat object" } } +{ $description "Unregisters " { $snippet "irc-chat" } " from " { $snippet "irc-client" } " and stops listening. This is how you part from a channel." } ; HELP: terminate-irc "Terminates an irc client" { $values { "irc-client" "an irc client object" } } -{ $description "Terminates all activity by " { $link irc-client } " cleaning up resources and notifying listeners." } ; +{ $description "Terminates all activity by " { $link irc-client } " cleaning up resources and notifying chats." } ; -HELP: write-message "Sends a message through a listener" -{ $values { "message" "a string or irc message object" } { "irc-listener" "an irc listener object" } } -{ $description "Sends " { $snippet "message" } " through " { $snippet "irc-listener" } ". Strings are automatically promoted to privmsg objects." } ; +HELP: speak "Sends a message through a chat" +{ $values { "message" "a string or irc message object" } { "irc-chat" "an irc chat object" } } +{ $description "Sends " { $snippet "message" } " through " { $snippet "irc-chat" } ". Strings are automatically promoted to privmsg objects." } ; -HELP: read-message "Reads a message from a listener" -{ $values { "irc-listener" "an irc listener object" } { "message" "an irc message object" } } -{ $description "Reads " { $snippet "message" } " from " { $snippet "irc-listener" } "." } ; +HELP: hear "Reads a message from a chat" +{ $values { "irc-chat" "an irc chat object" } { "message" "an irc message object" } } +{ $description "Reads " { $snippet "message" } " from " { $snippet "irc-chat" } "." } ; ARTICLE: "irc.client" "IRC Client" "An IRC Client library" { $heading "IRC objects:" } { $subsection irc-client } -{ $heading "Listener objects:" } -{ $subsection irc-server-listener } -{ $subsection irc-channel-listener } -{ $subsection irc-nick-listener } +{ $heading "Chat objects:" } +{ $subsection irc-server-chat } +{ $subsection irc-channel-chat } +{ $subsection irc-nick-chat } { $heading "Setup objects:" } { $subsection irc-profile } { $heading "Words:" } { $subsection connect-irc } { $subsection terminate-irc } -{ $subsection add-listener } -{ $subsection remove-listener } -{ $subsection read-message } -{ $subsection write-message } +{ $subsection attach-chat } +{ $subsection detach-chat } +{ $subsection hear } +{ $subsection speak } { $heading "IRC messages" } "Some of the RFC defined irc messages as objects:" { $table @@ -77,28 +72,29 @@ ARTICLE: "irc.client" "IRC Client" { $heading "Special messages" } "Some special messages that are created by the library and not by the irc server." { $table - { { $link irc-end } " sent when the client isn't running anymore, listeners should stop after this." } - { { $link irc-disconnected } " sent to notify listeners that connection was lost." } - { { $link irc-connected } " sent to notify listeners that a connection with the irc server was established." } } + { { $link irc-chat-end } "sent to a chat when it has been detached from the client, the chat should stop after it receives this message. " } + { { $link irc-end } " sent when the client isn't running anymore, chats should stop after it receives this message." } + { { $link irc-disconnected } " sent to notify chats that connection was lost." } + { { $link irc-connected } " sent to notify chats that a connection with the irc server was established." } } { $heading "Example:" } { $code - "USING: irc.client concurrency.mailboxes ;" + "USING: irc.client ;" "SYMBOL: bot" "SYMBOL: mychannel" "! Create the profile and client objects" "\"irc.freenode.org\" irc-port \"mybot123\" f bot set" "! Connect to the server" "bot get connect-irc" - "! Create a channel listener" - "\"#mychannel123\" mychannel set" - "! Register and start listener (this joins the channel)" - "mychannel get bot get add-listener" + "! Create a channel chat" + "\"#mychannel123\" mychannel set" + "! Register and start chat (this joins the channel)" + "mychannel get bot get attach-chat" "! Send a message to the channel" - "\"what's up?\" mychannel get write-message" + "\"what's up?\" mychannel get speak" "! Read a message from the channel" - "mychannel get read-message" + "mychannel get hear" } ; -ABOUT: "irc.client" \ No newline at end of file +ABOUT: "irc.client" diff --git a/extra/irc/client/client-tests.factor b/extra/irc/client/client-tests.factor index c768c1a82e..fe85d6c375 100644 --- a/extra/irc/client/client-tests.factor +++ b/extra/irc/client/client-tests.factor @@ -1,5 +1,5 @@ USING: kernel tools.test accessors arrays sequences qualified - io io.streams.duplex namespaces threads + io io.streams.duplex namespaces threads destructors calendar irc.client.private irc.client irc.messages.private concurrency.mailboxes classes assocs combinators ; EXCLUDE: irc.messages => join ; @@ -19,20 +19,23 @@ M: mb-reader stream-readln ( mb-reader -- str/f ) lines>> mailbox-get ; M: mb-writer stream-nl ( mb-writer -- ) [ [ last-line>> concat ] [ lines>> ] bi push ] keep V{ } clone >>last-line drop ; +M: mb-reader dispose drop ; +M: mb-writer dispose drop ; : spawn-client ( -- irc-client ) "someserver" irc-port "factorbot" f + t >>is-ready t >>is-running >>stream dup [ spawn-irc yield ] with-irc-client ; ! to be used inside with-irc-client quotations -: %add-named-listener ( listener -- ) [ name>> ] keep set+run-listener ; -: %join ( channel -- ) irc> add-listener ; +: %add-named-chat ( chat -- ) irc> attach-chat ; : %push-line ( line -- ) irc> stream>> in>> push-line yield ; +: %join ( channel -- ) irc> attach-chat ; -: read-matching-message ( listener quot: ( msg -- ? ) -- irc-message ) +: read-matching-message ( chat quot: ( msg -- ? ) -- irc-message ) [ in-messages>> 0.1 seconds ] dip mailbox-get-timeout? ; : with-irc ( quot: ( -- ) -- ) @@ -42,9 +45,9 @@ M: mb-writer stream-nl ( mb-writer -- ) ! TESTS ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -[ { t } [ irc> profile>> nickname>> me? ] unit-test +[ { t } [ irc> nick>> me? ] unit-test - { "factorbot" } [ irc> profile>> nickname>> ] unit-test + { "factorbot" } [ irc> nick>> ] unit-test { "someuser" } [ "someuser!n=user@some.where" parse-name ] unit-test @@ -58,30 +61,46 @@ M: mb-writer stream-nl ( mb-writer -- ) ! Test login and nickname set [ { "factorbot2" } [ ":some.where 001 factorbot2 :Welcome factorbot2" %push-line - irc> profile>> nickname>> + irc> nick>> + ] unit-test +] with-irc + +! Test connect +{ V{ "NICK factorbot" "USER factorbot hostname servername :irc.factor" } } [ + "someserver" irc-port "factorbot" f + [ 2drop t ] >>connect + [ connect-irc ] keep + stream>> [ in>> [ f ] dip push-line ] [ out>> lines>> ] bi +] unit-test + +! Test join +[ { "JOIN #factortest" } [ + "#factortest" %join + irc> stream>> out>> lines>> pop ] unit-test ] with-irc [ { join_ "#factortest" } [ + "#factortest" [ %add-named-chat ] keep { ":factorbot!n=factorbo@some.where JOIN :#factortest" ":ircserver.net 353 factorbot @ #factortest :@factorbot " ":ircserver.net 366 factorbot #factortest :End of /NAMES list." ":ircserver.net 477 factorbot #factortest :[ircserver-info] blah blah" } [ %push-line ] each - irc> join-messages>> 0.1 seconds mailbox-get-timeout + in-messages>> 0.1 seconds mailbox-get-timeout [ class ] [ trailing>> ] bi ] unit-test ] with-irc [ { T{ participant-changed f "somebody" +join+ } } [ - "#factortest" [ %add-named-listener ] keep + "#factortest" [ %add-named-chat ] keep ":somebody!n=somebody@some.where JOIN :#factortest" %push-line [ participant-changed? ] read-matching-message ] unit-test ] with-irc [ { privmsg "#factortest" "hello" } [ - "#factortest" [ %add-named-listener ] keep + "#factortest" [ %add-named-chat ] keep ":somebody!n=somebody@some.where PRIVMSG #factortest :hello" %push-line [ privmsg? ] read-matching-message [ class ] [ name>> ] [ trailing>> ] tri @@ -89,90 +108,90 @@ M: mb-writer stream-nl ( mb-writer -- ) ] with-irc [ { privmsg "factorbot" "hello" } [ - "somedude" [ %add-named-listener ] keep - ":somedude!n=user@isp.net PRIVMSG factorbot :hello" %push-line + "ircuser" [ %add-named-chat ] keep + ":ircuser!n=user@isp.net PRIVMSG factorbot :hello" %push-line [ privmsg? ] read-matching-message [ class ] [ name>> ] [ trailing>> ] tri ] unit-test ] with-irc [ { mode } [ - "#factortest" [ %add-named-listener ] keep + "#factortest" [ %add-named-chat ] keep ":ircserver.net MODE #factortest +ns" %push-line [ mode? ] read-matching-message class ] unit-test ] with-irc ! Participant lists tests -[ { H{ { "somedude" +normal+ } } } [ - "#factortest" [ %add-named-listener ] keep - ":somedude!n=user@isp.net JOIN :#factortest" %push-line +[ { H{ { "ircuser" +normal+ } } } [ + "#factortest" [ %add-named-chat ] keep + ":ircuser!n=user@isp.net JOIN :#factortest" %push-line participants>> ] unit-test ] with-irc -[ { H{ { "somedude2" +normal+ } } } [ - "#factortest" - H{ { "somedude2" +normal+ } - { "somedude" +normal+ } } clone >>participants - [ %add-named-listener ] keep - ":somedude!n=user@isp.net PART #factortest" %push-line +[ { H{ { "ircuser2" +normal+ } } } [ + "#factortest" + H{ { "ircuser2" +normal+ } + { "ircuser" +normal+ } } clone >>participants + [ %add-named-chat ] keep + ":ircuser!n=user@isp.net PART #factortest" %push-line participants>> ] unit-test ] with-irc -[ { H{ { "somedude2" +normal+ } } } [ - "#factortest" - H{ { "somedude2" +normal+ } - { "somedude" +normal+ } } clone >>participants - [ %add-named-listener ] keep - ":somedude!n=user@isp.net QUIT" %push-line +[ { H{ { "ircuser2" +normal+ } } } [ + "#factortest" + H{ { "ircuser2" +normal+ } + { "ircuser" +normal+ } } clone >>participants + [ %add-named-chat ] keep + ":ircuser!n=user@isp.net QUIT" %push-line participants>> ] unit-test ] with-irc -[ { H{ { "somedude2" +normal+ } } } [ - "#factortest" - H{ { "somedude2" +normal+ } - { "somedude" +normal+ } } clone >>participants - [ %add-named-listener ] keep - ":somedude2!n=user2@isp.net KICK #factortest somedude" %push-line +[ { H{ { "ircuser2" +normal+ } } } [ + "#factortest" + H{ { "ircuser2" +normal+ } + { "ircuser" +normal+ } } clone >>participants + [ %add-named-chat ] keep + ":ircuser2!n=user2@isp.net KICK #factortest ircuser" %push-line participants>> ] unit-test ] with-irc -[ { H{ { "somedude2" +normal+ } } } [ - "#factortest" - H{ { "somedude" +normal+ } } clone >>participants - [ %add-named-listener ] keep - ":somedude!n=user2@isp.net NICK :somedude2" %push-line +[ { H{ { "ircuser2" +normal+ } } } [ + "#factortest" + H{ { "ircuser" +normal+ } } clone >>participants + [ %add-named-chat ] keep + ":ircuser!n=user2@isp.net NICK :ircuser2" %push-line participants>> ] unit-test ] with-irc ! Namelist change notification [ { T{ participant-changed f f f f } } [ - "#factortest" [ %add-named-listener ] keep + "#factortest" [ %add-named-chat ] keep ":ircserver.net 353 factorbot @ #factortest :@factorbot " %push-line ":ircserver.net 366 factorbot #factortest :End of /NAMES list." %push-line [ participant-changed? ] read-matching-message ] unit-test ] with-irc -[ { T{ participant-changed f "somedude" +part+ f } } [ - "#factortest" - H{ { "somedude" +normal+ } } clone >>participants - [ %add-named-listener ] keep - ":somedude!n=user@isp.net QUIT" %push-line +[ { T{ participant-changed f "ircuser" +part+ f } } [ + "#factortest" + H{ { "ircuser" +normal+ } } clone >>participants + [ %add-named-chat ] keep + ":ircuser!n=user@isp.net QUIT" %push-line [ participant-changed? ] read-matching-message ] unit-test ] with-irc -[ { T{ participant-changed f "somedude" +nick+ "somedude2" } } [ - "#factortest" - H{ { "somedude" +normal+ } } clone >>participants - [ %add-named-listener ] keep - ":somedude!n=user2@isp.net NICK :somedude2" %push-line +[ { T{ participant-changed f "ircuser" +nick+ "ircuser2" } } [ + "#factortest" + H{ { "ircuser" +normal+ } } clone >>participants + [ %add-named-chat ] keep + ":ircuser!n=user2@isp.net NICK :ircuser2" %push-line [ participant-changed? ] read-matching-message ] unit-test ] with-irc diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index 569f6c4bf7..ce7a6e5373 100755 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -17,17 +17,24 @@ IN: irc.client TUPLE: irc-profile server port nickname password ; C: irc-profile -TUPLE: irc-client profile stream in-messages out-messages join-messages - listeners is-running connect reconnect-time ; -: ( profile -- irc-client ) - f H{ } clone f - [ latin1 ] 15 seconds irc-client boa ; +TUPLE: irc-client profile stream in-messages out-messages + chats is-running nick connect reconnect-time is-ready ; -TUPLE: irc-listener in-messages out-messages ; -TUPLE: irc-server-listener < irc-listener ; -TUPLE: irc-channel-listener < irc-listener name password timeout participants ; -TUPLE: irc-nick-listener < irc-listener name ; -SYMBOL: +server-listener+ +: ( profile -- irc-client ) + irc-client new + swap >>profile + >>in-messages + >>out-messages + H{ } clone >>chats + dup profile>> nickname>> >>nick + [ latin1 ] >>connect + 15 seconds >>reconnect-time ; + +TUPLE: irc-chat in-messages client ; +TUPLE: irc-server-chat < irc-chat ; +TUPLE: irc-channel-chat < irc-chat name password timeout participants ; +TUPLE: irc-nick-chat < irc-chat name ; +SYMBOL: +server-chat+ ! participant modes SYMBOL: +operator+ @@ -43,18 +50,16 @@ SYMBOL: +part+ SYMBOL: +mode+ SYMBOL: +nick+ -! listener objects -: ( -- irc-listener ) irc-listener boa ; +! chat objects +: ( -- irc-server-chat ) + f irc-server-chat boa ; -: ( -- irc-server-listener ) - irc-server-listener boa ; +: ( name -- irc-channel-chat ) + [ f ] dip f 60 seconds H{ } clone + irc-channel-chat boa ; -: ( name -- irc-channel-listener ) - [ ] dip f 60 seconds H{ } clone - irc-channel-listener boa ; - -: ( name -- irc-nick-listener ) - [ ] dip irc-nick-listener boa ; +: ( name -- irc-nick-chat ) + [ f ] dip irc-nick-chat boa ; ! ====================================== ! Message objects @@ -63,22 +68,17 @@ SYMBOL: +nick+ TUPLE: participant-changed nick action parameter ; C: participant-changed -SINGLETON: irc-listener-end ! send to a listener to stop its execution +SINGLETON: irc-chat-end ! sent to a chat to stop its execution SINGLETON: irc-end ! sent when the client isn't running anymore SINGLETON: irc-disconnected ! sent when connection is lost SINGLETON: irc-connected ! sent when connection is established -> values [ out-messages>> ] map ] - [ in-messages>> ] - [ out-messages>> ] tri 2array prepend - [ irc-end swap mailbox-put ] each ; -PRIVATE> - : terminate-irc ( irc-client -- ) [ is-running>> ] keep and [ - [ end-loops ] [ [ f ] dip (>>is-running) ] bi + f >>is-running + [ stream>> dispose ] keep + [ in-messages>> ] [ out-messages>> ] bi 2array + [ irc-end swap mailbox-put ] each ] when* ; ( -- irc-client ) current-irc-client get ; -: irc-stream> ( -- stream ) irc> stream>> ; -: irc-write ( s -- ) irc-stream> stream-write ; -: irc-print ( s -- ) irc-stream> [ stream-print ] keep stream-flush ; +: irc-write ( s -- ) irc> stream>> stream-write ; +: irc-print ( s -- ) irc> stream>> [ stream-print ] keep stream-flush ; : irc-send ( irc-message -- ) irc> out-messages>> mailbox-put ; -: listener> ( name -- listener/f ) irc> listeners>> at ; +: chat> ( name -- chat/f ) irc> chats>> at ; : channel-mode? ( mode -- ? ) name>> first "#&" member? ; -: me? ( string -- ? ) irc> profile>> nickname>> = ; +: me? ( string -- ? ) irc> nick>> = ; -GENERIC: to-listener ( message obj -- ) +GENERIC: to-chat ( message obj -- ) -M: string to-listener ( message string -- ) - listener> [ +server-listener+ listener> ] unless* - [ to-listener ] [ drop ] if* ; +M: string to-chat + chat> [ +server-chat+ chat> ] unless* + [ to-chat ] [ drop ] if* ; -M: irc-listener to-listener ( message irc-listener -- ) - in-messages>> mailbox-put ; +M: irc-chat to-chat in-messages>> mailbox-put ; -: unregister-listener ( name -- ) - irc> listeners>> - [ at [ irc-listener-end ] dip to-listener ] +: unregister-chat ( name -- ) + irc> chats>> + [ at [ irc-chat-end ] dip to-chat ] [ delete-at ] 2bi ; -: (remove-participant) ( nick listener -- ) +: (remove-participant) ( nick chat -- ) [ participants>> delete-at ] - [ [ +part+ f ] dip to-listener ] 2bi ; + [ [ +part+ f ] dip to-chat ] 2bi ; : remove-participant ( nick channel -- ) - listener> [ (remove-participant) ] [ drop ] if* ; + chat> [ (remove-participant) ] [ drop ] if* ; -: listeners-with-participant ( nick -- seq ) - irc> listeners>> values - [ dup irc-channel-listener? [ participants>> key? ] [ 2drop f ] if ] +: chats-with-participant ( nick -- seq ) + irc> chats>> values + [ [ irc-channel-chat? ] keep and [ participants>> key? ] [ drop f ] if* ] with filter ; -: to-listeners-with-participant ( message nickname -- ) - listeners-with-participant [ to-listener ] with each ; +: to-chats-with-participant ( message nickname -- ) + chats-with-participant [ to-chat ] with each ; : remove-participant-from-all ( nick -- ) - dup listeners-with-participant [ (remove-participant) ] with each ; + dup chats-with-participant [ (remove-participant) ] with each ; -: notify-rename ( newnick oldnick listener -- ) +: notify-rename ( newnick oldnick chat -- ) [ participant-changed new +nick+ >>action - [ (>>nick) ] [ (>>parameter) ] [ ] tri ] dip to-listener ; + [ (>>nick) ] [ (>>parameter) ] [ ] tri ] dip to-chat ; -: rename-participant ( newnick oldnick listener -- ) - [ participants>> [ delete-at* drop ] [ [ swap ] dip set-at ] bi ] +: rename-participant ( newnick oldnick chat -- ) + [ participants>> [ delete-at* drop ] [ swapd set-at ] bi ] [ notify-rename ] 3bi ; : rename-participant-in-all ( oldnick newnick -- ) - swap dup listeners-with-participant [ rename-participant ] with with each ; + swap dup chats-with-participant [ rename-participant ] with with each ; : add-participant ( mode nick channel -- ) - listener> + chat> [ participants>> set-at ] - [ [ +join+ f ] dip to-listener ] 2bi ; + [ [ +join+ f ] dip to-chat ] 2bi ; : change-participant-mode ( channel mode nick -- ) - rot listener> + rot chat> [ participants>> set-at ] - [ [ [ +mode+ ] dip ] dip to-listener ] 3bi ; ! FIXME + [ [ [ +mode+ ] dip ] dip to-chat ] 3bi ; ! FIXME DEFER: me? -: maybe-forward-join ( join -- ) - [ irc-message-sender me? ] keep and - [ irc> join-messages>> mailbox-put ] when* ; - ! ====================================== ! IRC client messages ! ====================================== @@ -184,64 +178,57 @@ DEFER: me? ! Server message handling ! ====================================== +GENERIC: initialize-chat ( chat -- ) +M: irc-chat initialize-chat drop ; +M: irc-channel-chat initialize-chat [ name>> ] [ password>> ] bi /JOIN ; + GENERIC: forward-name ( irc-message -- name ) -M: join forward-name ( join -- name ) trailing>> ; -M: part forward-name ( part -- name ) channel>> ; -M: kick forward-name ( kick -- name ) channel>> ; -M: mode forward-name ( mode -- name ) name>> ; -M: privmsg forward-name ( privmsg -- name ) - dup name>> me? [ irc-message-sender ] [ name>> ] if ; +M: join forward-name trailing>> ; +M: part forward-name channel>> ; +M: kick forward-name channel>> ; +M: mode forward-name name>> ; +M: privmsg forward-name dup name>> me? [ irc-message-sender ] [ name>> ] if ; UNION: single-forward join part kick mode privmsg ; UNION: multiple-forward nick quit ; UNION: broadcast-forward irc-end irc-disconnected irc-connected ; GENERIC: forward-message ( irc-message -- ) -M: irc-message forward-message ( irc-message -- ) - +server-listener+ listener> [ to-listener ] [ drop ] if* ; +M: irc-message forward-message + +server-chat+ chat> [ to-chat ] [ drop ] if* ; -M: single-forward forward-message ( forward-single -- ) - dup forward-name to-listener ; +M: single-forward forward-message dup forward-name to-chat ; -M: multiple-forward forward-message ( multiple-forward -- ) - dup irc-message-sender to-listeners-with-participant ; - -M: join forward-message ( join -- ) - [ maybe-forward-join ] [ call-next-method ] bi ; - -M: broadcast-forward forward-message ( irc-broadcasted-message -- ) - irc> listeners>> values [ to-listener ] with each ; +M: multiple-forward forward-message + dup irc-message-sender to-chats-with-participant ; + +M: broadcast-forward forward-message + irc> chats>> values [ to-chat ] with each ; GENERIC: process-message ( irc-message -- ) +M: object process-message drop ; +M: logged-in process-message + name>> f irc> [ (>>is-ready) ] [ (>>nick) ] [ chats>> ] tri + values [ initialize-chat ] each ; +M: ping process-message trailing>> /PONG ; +M: nick-in-use process-message name>> "_" append /NICK ; -M: object process-message ( object -- ) - drop ; - -M: logged-in process-message ( logged-in -- ) - name>> irc> profile>> (>>nickname) ; - -M: ping process-message ( ping -- ) - trailing>> /PONG ; - -M: nick-in-use process-message ( nick-in-use -- ) - name>> "_" append /NICK ; - -M: join process-message ( join -- ) +M: join process-message [ drop +normal+ ] [ irc-message-sender ] [ trailing>> ] tri - dup listener> [ add-participant ] [ 3drop ] if ; + dup chat> [ add-participant ] [ 3drop ] if ; -M: part process-message ( part -- ) +M: part process-message [ irc-message-sender ] [ channel>> ] bi remove-participant ; -M: kick process-message ( kick -- ) +M: kick process-message [ [ who>> ] [ channel>> ] bi remove-participant ] - [ dup who>> me? [ unregister-listener ] [ drop ] if ] + [ dup who>> me? [ unregister-chat ] [ drop ] if ] bi ; -M: quit process-message ( quit -- ) +M: quit process-message irc-message-sender remove-participant-from-all ; -M: nick process-message ( nick -- ) +M: nick process-message [ irc-message-sender ] [ trailing>> ] bi rename-participant-in-all ; ! M: mode process-message ( mode -- ) @@ -257,10 +244,10 @@ M: nick process-message ( nick -- ) trailing>> [ blank? ] trim " " split [ >nick/mode 2array ] map >hashtable ; -M: names-reply process-message ( names-reply -- ) - [ names-reply>participants ] [ channel>> listener> ] bi [ +M: names-reply process-message + [ names-reply>participants ] [ channel>> chat> ] bi [ [ (>>participants) ] - [ [ f f f ] dip name>> to-listener ] bi + [ [ f f f ] dip name>> to-chat ] bi ] [ drop ] if* ; ! ====================================== @@ -268,9 +255,8 @@ M: names-reply process-message ( names-reply -- ) ! ====================================== GENERIC: handle-outgoing-irc ( irc-message -- ? ) -M: irc-end handle-outgoing-irc ( irc-end -- ? ) drop f ; -M: irc-message handle-outgoing-irc ( irc-message -- ? ) - irc-message>client-line irc-print t ; +M: irc-end handle-outgoing-irc drop f ; +M: irc-message handle-outgoing-irc irc-message>client-line irc-print t ; ! ====================================== ! Reader/Writer @@ -285,12 +271,12 @@ DEFER: (connect-irc) irc> [ [ irc-disconnected ] dip in-messages>> mailbox-put ] [ dup reconnect-time>> sleep (connect-irc) ] - [ profile>> nickname>> /LOGIN ] + [ nick>> /LOGIN ] tri ; ! FIXME: do something with the exception, store somewhere to help debugging -: handle-disconnect ( error -- ) - drop irc> is-running>> [ (handle-disconnect) ] when ; +: handle-disconnect ( error -- ? ) + drop irc> is-running>> [ (handle-disconnect) t ] [ f ] if ; : (reader-loop) ( -- ? ) irc> stream>> [ @@ -302,7 +288,7 @@ DEFER: (connect-irc) ] with-destructors ; : reader-loop ( -- ? ) - [ (reader-loop) ] [ handle-disconnect t ] recover ; + [ (reader-loop) ] [ handle-disconnect ] recover ; : writer-loop ( -- ? ) irc> out-messages>> mailbox-get handle-outgoing-irc ; @@ -324,16 +310,11 @@ DEFER: (connect-irc) [ nip ] } cond ; -GENERIC: handle-listener-out ( irc-message -- ? ) -M: irc-end handle-listener-out ( irc-end -- ? ) drop f ; -M: irc-message handle-listener-out ( irc-message -- ? ) - irc> out-messages>> mailbox-put t ; - -: listener-loop ( name -- ? ) - dup listener> [ - out-messages>> mailbox-get - maybe-annotate-with-name handle-listener-out - ] [ drop f ] if* ; +GENERIC: annotate-message ( chat object -- object ) +M: object annotate-message nip ; +M: part annotate-message swap name>> >>channel ; +M: privmsg annotate-message swap name>> >>name ; +M: string annotate-message [ name>> ] dip strings>privmsg ; : spawn-irc ( -- ) [ reader-loop ] "irc-reader-loop" spawn-server @@ -341,48 +322,35 @@ M: irc-message handle-listener-out ( irc-message -- ? ) [ in-multiplexer-loop ] "in-multiplexer-loop" spawn-server 3drop ; -! ====================================== -! Listener join request handling -! ====================================== +GENERIC: (attach-chat) ( irc-chat -- ) +USE: prettyprint +M: irc-chat (attach-chat) + [ [ irc> >>client ] [ name>> ] bi irc> chats>> set-at ] + [ [ irc> is-ready>> ] dip and [ initialize-chat ] when* ] + bi ; -: set+run-listener ( name irc-listener -- ) - over irc> listeners>> set-at - '[ _ listener-loop ] "irc-listener-loop" spawn-server drop ; +M: irc-server-chat (attach-chat) + irc> >>client +server-chat+ irc> chats>> set-at ; -GENERIC: (add-listener) ( irc-listener -- ) +GENERIC: (remove-chat) ( irc-chat -- ) -M: irc-channel-listener (add-listener) ( irc-channel-listener -- ) - [ [ name>> ] [ password>> ] bi /JOIN ] - [ [ [ drop irc> join-messages>> ] - [ timeout>> ] - [ name>> '[ trailing>> _ = ] ] - tri mailbox-get-timeout? trailing>> ] keep set+run-listener - ] bi ; +M: irc-nick-chat (remove-chat) + name>> unregister-chat ; -M: irc-nick-listener (add-listener) ( irc-nick-listener -- ) - [ name>> ] keep set+run-listener ; +M: irc-channel-chat (remove-chat) + [ part new annotate-message irc> out-messages>> mailbox-put ] keep + name>> unregister-chat ; -M: irc-server-listener (add-listener) ( irc-server-listener -- ) - [ +server-listener+ ] dip set+run-listener ; - -GENERIC: (remove-listener) ( irc-listener -- ) - -M: irc-nick-listener (remove-listener) ( irc-nick-listener -- ) - name>> unregister-listener ; - -M: irc-channel-listener (remove-listener) ( irc-channel-listener -- ) - [ [ name>> ] [ out-messages>> ] bi - [ [ part new ] dip >>channel ] dip mailbox-put ] keep - name>> unregister-listener ; - -M: irc-server-listener (remove-listener) ( irc-server-listener -- ) - drop +server-listener+ unregister-listener ; +M: irc-server-chat (remove-chat) + drop +server-chat+ unregister-chat ; : (connect-irc) ( irc-client -- ) - [ profile>> [ server>> ] [ port>> ] bi /CONNECT ] keep - swap >>stream - t >>is-running - in-messages>> [ irc-connected ] dip mailbox-put ; + { + [ profile>> [ server>> ] [ port>> ] bi /CONNECT ] + [ (>>stream) ] + [ t swap (>>is-running) ] + [ in-messages>> [ irc-connected ] dip mailbox-put ] + } cleave ; : with-irc-client ( irc-client quot: ( -- ) -- ) [ \ current-irc-client ] dip with-variable ; inline @@ -390,15 +358,14 @@ M: irc-server-listener (remove-listener) ( irc-server-listener -- ) PRIVATE> : connect-irc ( irc-client -- ) - [ irc> - [ (connect-irc) ] [ profile>> nickname>> /LOGIN ] bi - spawn-irc ] with-irc-client ; + dup [ [ (connect-irc) ] [ nick>> /LOGIN ] bi spawn-irc ] with-irc-client ; -: add-listener ( irc-listener irc-client -- ) - swap '[ _ (add-listener) ] with-irc-client ; +: attach-chat ( irc-chat irc-client -- ) [ (attach-chat) ] with-irc-client ; -: remove-listener ( irc-listener irc-client -- ) - swap '[ _ (remove-listener) ] with-irc-client ; +: detach-chat ( irc-chat -- ) + [ client>> ] keep '[ _ (remove-chat) ] with-irc-client ; -: write-message ( message irc-listener -- ) out-messages>> mailbox-put ; -: read-message ( irc-listener -- message ) in-messages>> mailbox-get ; +: speak ( message irc-chat -- ) + [ swap annotate-message ] [ client>> out-messages>> mailbox-put ] bi ; + +: hear ( irc-chat -- message ) in-messages>> mailbox-get ; diff --git a/extra/irc/messages/messages-tests.factor b/extra/irc/messages/messages-tests.factor index b61dd16448..41272a43f2 100644 --- a/extra/irc/messages/messages-tests.factor +++ b/extra/irc/messages/messages-tests.factor @@ -62,4 +62,14 @@ IN: irc.messages.tests { parameters { } } { trailing "someuser2" } } } [ ":someuser!n=user@some.where NICK :someuser2" + parse-irc-line f >>timestamp ] unit-test + +{ T{ nick-in-use + { line ":ircserver.net 433 * nickname :Nickname is already in use" } + { prefix "ircserver.net" } + { command "433" } + { parameters { "*" "nickname" } } + { name "nickname" } + { trailing "Nickname is already in use" } } } +[ ":ircserver.net 433 * nickname :Nickname is already in use" parse-irc-line f >>timestamp ] unit-test \ No newline at end of file diff --git a/extra/irc/messages/messages.factor b/extra/irc/messages/messages.factor index 9201f822da..32533c102a 100755 --- a/extra/irc/messages/messages.factor +++ b/extra/irc/messages/messages.factor @@ -4,7 +4,6 @@ USING: kernel fry splitting ascii calendar accessors combinators qualified arrays classes.tuple math.order ; RENAME: join sequences => sjoin EXCLUDE: sequences => join ; -EXCLUDE: inverse => _ ; IN: irc.messages TUPLE: irc-message line prefix command parameters trailing timestamp ; @@ -17,15 +16,18 @@ TUPLE: nick < irc-message ; TUPLE: privmsg < irc-message name ; TUPLE: kick < irc-message channel who ; TUPLE: roomlist < irc-message channel names ; -TUPLE: nick-in-use < irc-message asterisk name ; +TUPLE: nick-in-use < irc-message name ; TUPLE: notice < irc-message type ; TUPLE: mode < irc-message name mode parameter ; TUPLE: names-reply < irc-message who channel ; TUPLE: unhandled < irc-message ; : ( command parameters trailing -- irc-message ) - irc-message new now >>timestamp - [ [ (>>trailing) ] [ (>>parameters) ] [ (>>command) ] tri ] keep ; + irc-message new + now >>timestamp + swap >>trailing + swap >>parameters + swap >>command ; > ( kick -- seq ) M: mode command-parameters>> ( mode -- seq ) [ name>> ] [ channel>> ] [ mode>> ] tri 3array ; -GENERIC: (>>command-parameters) ( params irc-message -- ) +GENERIC# >>command-parameters 1 ( irc-message params -- irc-message ) -M: irc-message (>>command-parameters) ( params irc-message -- ) 2drop ; -M: logged-in (>>command-parameters) ( params part -- ) [ first ] dip (>>name) ; -M: privmsg (>>command-parameters) ( params privmsg -- ) [ first ] dip (>>name) ; -M: notice (>>command-parameters) ( params notice -- ) [ first ] dip (>>type) ; -M: part (>>command-parameters) ( params part -- ) - [ first ] dip (>>channel) ; -M: kick (>>command-parameters) ( params kick -- ) - [ first2 ] dip [ (>>who) ] [ (>>channel) ] bi ; -M: names-reply (>>command-parameters) ( params names-reply -- ) - [ [ first ] dip (>>who) ] [ [ third ] dip (>>channel) ] 2bi ; -M: mode (>>command-parameters) ( params mode -- ) - { { [ >r 2array r> ] [ [ (>>mode) ] [ (>>name) ] bi ] } - { [ >r 3array r> ] [ [ (>>parameter) ] [ (>>mode) ] [ (>>name) ] tri ] } - } switch ; +M: irc-message >>command-parameters ( irc-message params -- irc-message ) + drop ; + +M: logged-in >>command-parameters ( part params -- part ) + first >>name ; + +M: privmsg >>command-parameters ( privmsg params -- privmsg ) + first >>name ; + +M: notice >>command-parameters ( notice params -- notice ) + first >>type ; + +M: part >>command-parameters ( part params -- part ) + first >>channel ; + +M: kick >>command-parameters ( kick params -- kick ) + first2 [ >>channel ] [ >>who ] bi* ; + +M: nick-in-use >>command-parameters ( nick-in-use params -- nick-in-use ) + second >>name ; + +M: names-reply >>command-parameters ( names-reply params -- names-reply ) + first3 nip [ >>who ] [ >>channel ] bi* ; + +M: mode >>command-parameters ( mode params -- mode ) + dup length 3 = [ + first3 [ >>name ] [ >>mode ] [ >>parameter ] tri* + ] [ + first2 [ >>name ] [ >>mode ] bi* + ] if ; PRIVATE> @@ -90,6 +108,7 @@ M: irc-message irc-message>server-line ( irc-message -- string ) drop "not implemented yet" ; server-line ( irc-message -- string ) : split-at-first ( seq separators -- before after ) dupd '[ _ member? ] find [ cut 1 tail ] [ swap ] if ; -: remove-heading-: ( seq -- seq ) dup ":" head? [ 1 tail ] when ; +: remove-heading-: ( seq -- seq ) + ":" ?head drop ; : parse-name ( string -- string ) remove-heading-: "!" split-at-first drop ; : split-prefix ( string -- string/f string ) dup ":" head? - [ remove-heading-: " " split1 ] - [ f swap ] - if ; + [ remove-heading-: " " split1 ] [ f swap ] if ; : split-trailing ( string -- string string/f ) ":" split1 ; -: copy-message-in ( origin dest -- ) - { [ [ parameters>> ] dip [ (>>command-parameters) ] [ (>>parameters) ] 2bi ] - [ [ line>> ] dip (>>line) ] - [ [ prefix>> ] dip (>>prefix) ] - [ [ command>> ] dip (>>command) ] - [ [ trailing>> ] dip (>>trailing) ] - [ [ timestamp>> ] dip (>>timestamp) ] - } 2cleave ; +: copy-message-in ( command irc-message -- command ) + { + [ parameters>> [ >>parameters ] [ >>command-parameters ] bi ] + [ line>> >>line ] + [ prefix>> >>prefix ] + [ command>> >>command ] + [ trailing>> >>trailing ] + [ timestamp>> >>timestamp ] + } cleave ; PRIVATE> @@ -132,20 +151,24 @@ M: sender-in-prefix irc-message-sender ( sender-in-prefix -- sender ) [ [ blank? ] trim " " split unclip swap ] dip now irc-message boa ; +: irc-message>command ( irc-message -- command ) + [ + command>> { + { "PING" [ ping ] } + { "NOTICE" [ notice ] } + { "001" [ logged-in ] } + { "433" [ nick-in-use ] } + { "353" [ names-reply ] } + { "JOIN" [ join ] } + { "PART" [ part ] } + { "NICK" [ nick ] } + { "PRIVMSG" [ privmsg ] } + { "QUIT" [ quit ] } + { "MODE" [ mode ] } + { "KICK" [ kick ] } + [ drop unhandled ] + } case new + ] keep copy-message-in ; + : parse-irc-line ( string -- message ) - string>irc-message - dup command>> { - { "PING" [ ping ] } - { "NOTICE" [ notice ] } - { "001" [ logged-in ] } - { "433" [ nick-in-use ] } - { "353" [ names-reply ] } - { "JOIN" [ join ] } - { "PART" [ part ] } - { "NICK" [ nick ] } - { "PRIVMSG" [ privmsg ] } - { "QUIT" [ quit ] } - { "MODE" [ mode ] } - { "KICK" [ kick ] } - [ drop unhandled ] - } case new [ copy-message-in ] keep ; + string>irc-message irc-message>command ; diff --git a/extra/irc/ui/commands/commands.factor b/extra/irc/ui/commands/commands.factor index 184a2b4de8..4bb77e7490 100755 --- a/extra/irc/ui/commands/commands.factor +++ b/extra/irc/ui/commands/commands.factor @@ -8,7 +8,7 @@ IN: irc.ui.commands : say ( string -- ) irc-tab get [ window>> client>> profile>> nickname>> print-irc ] - [ listener>> write-message ] 2bi ; + [ chat>> speak ] 2bi ; : join ( string -- ) irc-tab get window>> join-channel ; @@ -18,7 +18,7 @@ IN: irc.ui.commands : whois ( string -- ) "WHOIS" swap { } clone swap - irc-tab get listener>> write-message ; + irc-tab get listener>> speak ; : quote ( string -- ) drop ; ! THIS WILL CHANGE diff --git a/extra/irc/ui/ui.factor b/extra/irc/ui/ui.factor index 1e4bcf35f8..e854d285b7 100755 --- a/extra/irc/ui/ui.factor +++ b/extra/irc/ui/ui.factor @@ -15,7 +15,7 @@ RENAME: join sequences => sjoin IN: irc.ui -SYMBOL: listener +SYMBOL: chat SYMBOL: client @@ -24,7 +24,7 @@ TUPLE: ui-window < tabbed client ; M: ui-window ungraft* client>> terminate-irc ; -TUPLE: irc-tab < frame listener client window ; +TUPLE: irc-tab < frame chat client window ; : write-color ( str color -- ) foreground associate format ; @@ -117,7 +117,7 @@ M: irc-disconnected write-irc M: irc-connected write-irc drop "* Connected" dark-green write-color ; -M: irc-listener-end write-irc +M: irc-chat-end write-irc drop ; M: irc-message write-irc @@ -135,7 +135,7 @@ M: object time-happened drop now ; : send-message ( message -- ) [ print-irc ] - [ listener get write-message ] bi ; + [ chat get speak ] bi ; GENERIC: handle-inbox ( tab message -- ) @@ -150,7 +150,7 @@ M: object handle-inbox : display ( stream tab -- ) '[ _ [ [ t ] - [ _ dup listener>> read-message handle-inbox ] + [ _ dup chat>> hear handle-inbox ] [ ] while ] with-output-stream ] "ircv" spawn drop ; : ( tab -- tab pane ) @@ -175,28 +175,28 @@ irc-editor "general" f { { T{ key-down f f "ENTER" } editor-send } } define-command-map -: new-irc-tab ( listener ui-window class -- irc-tab ) +: new-irc-tab ( chat ui-window class -- irc-tab ) new-frame swap >>window - swap >>listener + swap >>chat [ @center grid-add ] keep @bottom grid-add ; M: irc-tab graft* - [ listener>> ] [ window>> client>> ] bi add-listener ; + [ chat>> ] [ window>> client>> ] bi attach-chat ; M: irc-tab ungraft* - [ listener>> ] [ window>> client>> ] bi remove-listener ; + chat>> detach-chat ; TUPLE: irc-channel-tab < irc-tab userlist ; -: ( listener ui-window -- irc-tab ) +: ( chat ui-window -- irc-tab ) irc-channel-tab new-irc-tab [ @right grid-add ] keep >>userlist ; : update-participants ( tab -- ) [ userlist>> [ clear-gadget ] keep ] - [ listener>> participants>> ] bi + [ chat>> participants>> ] bi [ +operator+ value-labels dark-green add-gadget-color ] [ +voice+ value-labels blue add-gadget-color ] [ +normal+ value-labels black add-gadget-color ] tri drop ; @@ -206,22 +206,22 @@ M: participant-changed handle-inbox TUPLE: irc-server-tab < irc-tab ; -: ( listener -- irc-tab ) +: ( chat -- irc-tab ) f irc-server-tab new-irc-tab ; -: ( listener ui-window -- irc-tab ) +: ( chat ui-window -- irc-tab ) irc-tab new-irc-tab ; M: irc-tab pref-dim* drop { 480 480 } ; : join-channel ( name ui-window -- ) - [ dup ] dip + [ dup ] dip [ swap ] keep add-page ; : query-nick ( nick ui-window -- ) - [ dup ] dip + [ dup ] dip [ swap ] keep add-page ; @@ -232,8 +232,8 @@ M: irc-tab pref-dim* : ui-connect ( profile -- ui-window ) - { [ [ ] dip add-listener ] - [ listeners>> +server-listener+ swap at dup + { [ [ ] dip attach-chat ] + [ chats>> +server-chat+ swap at dup "Server" associate ui-window new-tabbed [ swap (>>window) ] keep ] [ >>client ] [ connect-irc ] } cleave ; diff --git a/unmaintained/jamshred/authors.txt b/extra/jamshred/authors.txt similarity index 100% rename from unmaintained/jamshred/authors.txt rename to extra/jamshred/authors.txt diff --git a/unmaintained/jamshred/deploy.factor b/extra/jamshred/deploy.factor similarity index 100% rename from unmaintained/jamshred/deploy.factor rename to extra/jamshred/deploy.factor diff --git a/unmaintained/jamshred/game/authors.txt b/extra/jamshred/game/authors.txt similarity index 100% rename from unmaintained/jamshred/game/authors.txt rename to extra/jamshred/game/authors.txt diff --git a/unmaintained/jamshred/game/game.factor b/extra/jamshred/game/game.factor similarity index 96% rename from unmaintained/jamshred/game/game.factor rename to extra/jamshred/game/game.factor index 938605ce9f..9cb5bc7c3a 100644 --- a/unmaintained/jamshred/game/game.factor +++ b/extra/jamshred/game/game.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2007 Alex Chapman +! Copyright (C) 2007, 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel opengl arrays sequences jamshred.log jamshred.player jamshred.sound jamshred.tunnel math math.constants math.vectors ; IN: jamshred.game diff --git a/unmaintained/jamshred/gl/authors.txt b/extra/jamshred/gl/authors.txt similarity index 100% rename from unmaintained/jamshred/gl/authors.txt rename to extra/jamshred/gl/authors.txt diff --git a/unmaintained/jamshred/gl/gl.factor b/extra/jamshred/gl/gl.factor similarity index 86% rename from unmaintained/jamshred/gl/gl.factor rename to extra/jamshred/gl/gl.factor index 52caaa10c9..6c553147a1 100644 --- a/unmaintained/jamshred/gl/gl.factor +++ b/extra/jamshred/gl/gl.factor @@ -1,9 +1,6 @@ -! Copyright (C) 2007 Alex Chapman +! Copyright (C) 2007, 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: accessors alien.c-types colors jamshred.game -jamshred.oint jamshred.player jamshred.tunnel kernel math -math.constants math.functions math.vectors opengl opengl.gl -opengl.glu sequences float-arrays ; +USING: accessors alien.c-types jamshred.game jamshred.oint jamshred.player jamshred.tunnel kernel math math.constants math.functions math.vectors opengl opengl.gl opengl.glu sequences float-arrays ; IN: jamshred.gl : min-vertices 6 ; inline @@ -44,8 +41,9 @@ IN: jamshred.gl : equally-spaced-radians ( n -- seq ) #! return a sequence of n numbers between 0 and 2pi dup [ / pi 2 * * ] curry map ; + : draw-segment-vertex ( segment theta -- ) - over segment-color gl-color segment-vertex-and-normal + over color>> set-color segment-vertex-and-normal gl-normal gl-vertex ; : draw-vertex-pair ( theta next-segment segment -- ) @@ -61,8 +59,8 @@ IN: jamshred.gl 1 over length pick subseq swap [ draw-segment ] 2each ; : segments-to-render ( player -- segments ) - dup player-nearest-segment segment-number dup n-segments-behind - - swap n-segments-ahead + rot player-tunnel sub-tunnel ; + dup nearest-segment>> number>> dup n-segments-behind - + swap n-segments-ahead + rot tunnel>> sub-tunnel ; : draw-tunnel ( player -- ) segments-to-render draw-segments ; diff --git a/unmaintained/jamshred/jamshred.factor b/extra/jamshred/jamshred.factor similarity index 82% rename from unmaintained/jamshred/jamshred.factor rename to extra/jamshred/jamshred.factor index d9a0f84b53..2357742fde 100755 --- a/unmaintained/jamshred/jamshred.factor +++ b/extra/jamshred/jamshred.factor @@ -1,15 +1,12 @@ ! Copyright (C) 2007, 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: accessors alarms arrays calendar jamshred.game jamshred.gl -jamshred.player jamshred.log kernel math math.constants namespaces -sequences threads ui ui.backend ui.gadgets ui.gadgets.worlds -ui.gestures ui.render math.vectors math.geometry.rect ; +USING: accessors arrays calendar jamshred.game jamshred.gl jamshred.player jamshred.log kernel math math.constants math.geometry.rect math.vectors namespaces sequences threads ui ui.backend ui.gadgets ui.gadgets.worlds ui.gestures ui.render ; IN: jamshred -TUPLE: jamshred-gadget jamshred last-hand-loc alarm ; +TUPLE: jamshred-gadget < gadget { jamshred jamshred } last-hand-loc ; : ( jamshred -- gadget ) - jamshred-gadget construct-gadget swap >>jamshred ; + jamshred-gadget new-gadget swap >>jamshred ; : default-width ( -- x ) 800 ; : default-height ( -- y ) 600 ; @@ -26,7 +23,7 @@ M: jamshred-gadget draw-gadget* ( gadget -- ) ] [ [ jamshred>> jamshred-update ] [ relayout-1 ] - [ yield jamshred-loop ] tri + [ 10 sleep yield jamshred-loop ] tri ] if ; : fullscreen ( gadget -- ) @@ -39,7 +36,7 @@ M: jamshred-gadget draw-gadget* ( gadget -- ) [ fullscreen? not ] keep set-fullscreen* ; M: jamshred-gadget graft* ( gadget -- ) - [ jamshred-loop ] in-thread drop ; + [ jamshred-loop ] curry in-thread ; M: jamshred-gadget ungraft* ( gadget -- ) jamshred>> t swap (>>quit) ; @@ -91,7 +88,7 @@ jamshred-gadget H{ { T{ mouse-scroll } [ handle-mouse-scroll ] } } set-gestures -: jamshred-window ( -- jamshred ) - [ dup "Jamshred" open-window ] with-ui ; +: jamshred-window ( -- gadget ) + [ dup "Jamshred" open-window ] with-ui ; MAIN: jamshred-window diff --git a/unmaintained/jamshred/log/log.factor b/extra/jamshred/log/log.factor similarity index 100% rename from unmaintained/jamshred/log/log.factor rename to extra/jamshred/log/log.factor diff --git a/unmaintained/jamshred/oint/authors.txt b/extra/jamshred/oint/authors.txt similarity index 100% rename from unmaintained/jamshred/oint/authors.txt rename to extra/jamshred/oint/authors.txt diff --git a/unmaintained/jamshred/oint/oint-tests.factor b/extra/jamshred/oint/oint-tests.factor similarity index 100% rename from unmaintained/jamshred/oint/oint-tests.factor rename to extra/jamshred/oint/oint-tests.factor diff --git a/unmaintained/jamshred/oint/oint.factor b/extra/jamshred/oint/oint.factor similarity index 98% rename from unmaintained/jamshred/oint/oint.factor rename to extra/jamshred/oint/oint.factor index 7a37646a6d..808e92a1f9 100644 --- a/unmaintained/jamshred/oint/oint.factor +++ b/extra/jamshred/oint/oint.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2007 Alex Chapman +! Copyright (C) 2007, 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays float-arrays kernel locals math math.constants math.functions math.matrices math.vectors math.quaternions random sequences ; IN: jamshred.oint diff --git a/unmaintained/jamshred/player/authors.txt b/extra/jamshred/player/authors.txt similarity index 100% rename from unmaintained/jamshred/player/authors.txt rename to extra/jamshred/player/authors.txt diff --git a/unmaintained/jamshred/player/player.factor b/extra/jamshred/player/player.factor similarity index 78% rename from unmaintained/jamshred/player/player.factor rename to extra/jamshred/player/player.factor index 48ea847db1..72f26a2c79 100644 --- a/unmaintained/jamshred/player/player.factor +++ b/extra/jamshred/player/player.factor @@ -1,12 +1,15 @@ ! Copyright (C) 2007, 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: accessors colors combinators jamshred.log jamshred.oint -jamshred.sound jamshred.tunnel kernel locals math math.constants -math.order math.ranges math.vectors math.matrices shuffle -sequences system float-arrays ; +USING: accessors colors combinators float-arrays jamshred.log jamshred.oint jamshred.sound jamshred.tunnel kernel locals math math.constants math.order math.ranges math.vectors math.matrices sequences shuffle strings system ; IN: jamshred.player -TUPLE: player < oint name sounds tunnel nearest-segment last-move speed ; +TUPLE: player < oint + { name string } + { sounds sounds } + tunnel + nearest-segment + { last-move integer } + { speed float } ; ! speeds are in GL units / second : default-speed ( -- speed ) 1.0 ; @@ -14,7 +17,7 @@ TUPLE: player < oint name sounds tunnel nearest-segment last-move speed ; : ( name sounds -- player ) [ F{ 0 0 5 } F{ 0 0 -1 } F{ 0 1 0 } F{ -1 0 0 } ] 2dip - f f f default-speed player boa ; + f f 0 default-speed player boa ; : turn-player ( player x-radians y-radians -- ) >r over r> left-pivot up-pivot ; @@ -72,6 +75,9 @@ TUPLE: player < oint name sounds tunnel nearest-segment last-move speed ; : distance-to-collision ( player -- distance ) dup nearest-segment>> (distance-to-collision) ; +: almost-to-collision ( player -- distance ) + distance-to-collision 0.1 - dup 0 < [ drop 0 ] when ; + : from ( player -- radius distance-from-centre ) [ nearest-segment>> dup radius>> swap ] [ location>> ] bi distance-from-centre ; @@ -96,14 +102,17 @@ TUPLE: player < oint name sounds tunnel nearest-segment last-move speed ; heading player update-nearest-segment2 d-left d-to-move - player ] ; -: move-toward-wall ( d-left player d-to-wall -- d-left' player ) - over [ forward>> ] keep distance-to-heading-segment-area min - over forward>> move-player-on-heading ; +: distance-to-move-freely ( player -- distance ) + [ almost-to-collision ] + [ [ forward>> ] keep distance-to-heading-segment-area ] bi min ; : ?move-player-freely ( d-left player -- d-left' player ) over 0 > [ - dup distance-to-collision dup 0.2 > [ ! bug! should be 0, not 0.2 - move-toward-wall ?move-player-freely + ! must make sure we are moving a significant distance, otherwise + ! we can recurse endlessly due to floating-point imprecision. + ! (at least I /think/ that's what causes it...) + dup distance-to-move-freely dup 0.1 > [ + over forward>> move-player-on-heading ?move-player-freely ] [ drop ] if ] when ; diff --git a/unmaintained/jamshred/sound/bang.wav b/extra/jamshred/sound/bang.wav similarity index 100% rename from unmaintained/jamshred/sound/bang.wav rename to extra/jamshred/sound/bang.wav diff --git a/unmaintained/jamshred/sound/sound.factor b/extra/jamshred/sound/sound.factor similarity index 81% rename from unmaintained/jamshred/sound/sound.factor rename to extra/jamshred/sound/sound.factor index fd1b1127bd..c19c67671f 100644 --- a/unmaintained/jamshred/sound/sound.factor +++ b/extra/jamshred/sound/sound.factor @@ -1,3 +1,5 @@ +! Copyright (C) 2008 Alex Chapman +! See http://factorcode.org/license.txt for BSD license. USING: accessors io.files kernel openal sequences ; IN: jamshred.sound diff --git a/unmaintained/jamshred/summary.txt b/extra/jamshred/summary.txt similarity index 100% rename from unmaintained/jamshred/summary.txt rename to extra/jamshred/summary.txt diff --git a/unmaintained/jamshred/tags.txt b/extra/jamshred/tags.txt similarity index 100% rename from unmaintained/jamshred/tags.txt rename to extra/jamshred/tags.txt diff --git a/unmaintained/jamshred/tunnel/authors.txt b/extra/jamshred/tunnel/authors.txt similarity index 100% rename from unmaintained/jamshred/tunnel/authors.txt rename to extra/jamshred/tunnel/authors.txt diff --git a/unmaintained/jamshred/tunnel/tunnel-tests.factor b/extra/jamshred/tunnel/tunnel-tests.factor similarity index 69% rename from unmaintained/jamshred/tunnel/tunnel-tests.factor rename to extra/jamshred/tunnel/tunnel-tests.factor index 97077bdd67..9486713f55 100644 --- a/unmaintained/jamshred/tunnel/tunnel-tests.factor +++ b/extra/jamshred/tunnel/tunnel-tests.factor @@ -1,20 +1,20 @@ -! Copyright (C) 2007 Alex Chapman +! Copyright (C) 2007, 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: arrays jamshred.oint jamshred.tunnel kernel math.vectors sequences tools.test float-arrays ; +USING: accessors arrays float-arrays jamshred.oint jamshred.tunnel kernel math.vectors sequences tools.test ; IN: jamshred.tunnel.tests [ 0 ] [ T{ segment f { 0 0 0 } f f f 0 } T{ segment f { 1 1 1 } f f f 1 } T{ oint f { 0 0 0.25 } } - nearer-segment segment-number ] unit-test + nearer-segment number>> ] unit-test -[ 0 ] [ T{ oint f { 0 0 0 } } find-nearest-segment segment-number ] unit-test -[ 1 ] [ T{ oint f { 0 0 -1 } } find-nearest-segment segment-number ] unit-test -[ 2 ] [ T{ oint f { 0 0.1 -2.1 } } find-nearest-segment segment-number ] unit-test +[ 0 ] [ T{ oint f { 0 0 0 } } find-nearest-segment number>> ] unit-test +[ 1 ] [ T{ oint f { 0 0 -1 } } find-nearest-segment number>> ] unit-test +[ 2 ] [ T{ oint f { 0 0.1 -2.1 } } find-nearest-segment number>> ] unit-test -[ 3 ] [ T{ oint f { 0 0 -3.25 } } 0 nearest-segment-forward segment-number ] unit-test +[ 3 ] [ T{ oint f { 0 0 -3.25 } } 0 nearest-segment-forward number>> ] unit-test -[ F{ 0 0 0 } ] [ T{ oint f { 0 0 -0.25 } } over first nearest-segment oint-location ] unit-test +[ F{ 0 0 0 } ] [ T{ oint f { 0 0 -0.25 } } over first nearest-segment location>> ] unit-test : test-segment-oint ( -- oint ) { 0 0 0 } { 0 0 -1 } { 0 1 0 } { -1 0 0 } ; @@ -32,14 +32,14 @@ IN: jamshred.tunnel.tests { 0 0 0 } { 0 0 -1 } { 0 1 0 } { -1 0 0 } initial-segment ; -[ { 0 0 0 } ] [ simplest-straight-ahead sideways-heading ] unit-test -[ { 0 0 0 } ] [ simplest-straight-ahead sideways-relative-location ] unit-test +[ { 0.0 0.0 0.0 } ] [ simplest-straight-ahead sideways-heading ] unit-test +[ { 0.0 0.0 0.0 } ] [ simplest-straight-ahead sideways-relative-location ] unit-test : simple-collision-up ( -- oint segment ) { 0 0 0 } { 0 1 0 } { 0 0 1 } { -1 0 0 } initial-segment ; -[ { 0 1 0 } ] [ simple-collision-up sideways-heading ] unit-test -[ { 0 0 0 } ] [ simple-collision-up sideways-relative-location ] unit-test -[ { 0 1 0 } ] +[ { 0.0 1.0 0.0 } ] [ simple-collision-up sideways-heading ] unit-test +[ { 0.0 0.0 0.0 } ] [ simple-collision-up sideways-relative-location ] unit-test +[ { 0.0 1.0 0.0 } ] [ simple-collision-up collision-vector 0 0 0 3array v+ ] unit-test diff --git a/unmaintained/jamshred/tunnel/tunnel.factor b/extra/jamshred/tunnel/tunnel.factor similarity index 93% rename from unmaintained/jamshred/tunnel/tunnel.factor rename to extra/jamshred/tunnel/tunnel.factor index 99c396bebd..7082acec47 100755 --- a/unmaintained/jamshred/tunnel/tunnel.factor +++ b/extra/jamshred/tunnel/tunnel.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2007, 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: accessors arrays combinators float-arrays kernel jamshred.oint locals math math.constants math.matrices math.order math.ranges math.vectors math.quadratic random sequences vectors ; +USING: accessors arrays colors combinators float-arrays kernel jamshred.oint locals math math.constants math.matrices math.order math.ranges math.vectors math.quadratic random sequences vectors ; USE: tools.walker IN: jamshred.tunnel @@ -13,7 +13,7 @@ C: segment [ number>> 1+ ] keep (>>number) ; : random-color ( -- color ) - { 100 100 100 } [ random 100 / >float ] map { 1.0 } append ; + { 100 100 100 } [ random 100 / >float ] map first3 1.0 ; : tunnel-segment-distance ( -- n ) 0.4 ; : random-rotation-angle ( -- theta ) pi 20 / ; @@ -21,7 +21,7 @@ C: segment : random-segment ( previous-segment -- segment ) clone dup random-rotation-angle random-turn tunnel-segment-distance over go-forward - random-color over set-segment-color dup segment-number++ ; + random-color >>color dup segment-number++ ; : (random-segments) ( segments n -- segments ) dup 0 > [ @@ -77,7 +77,7 @@ C: segment : nearest-segment ( segments oint start-segment -- segment ) #! find the segment nearest to 'oint', and return it. #! start looking at segment 'start-segment' - segment-number over >r + number>> over >r [ nearest-segment-forward ] 3keep nearest-segment-backward r> nearer-segment ; diff --git a/extra/lisp/lisp.factor b/extra/lisp/lisp.factor index 2866e63c69..e60529caab 100644 --- a/extra/lisp/lisp.factor +++ b/extra/lisp/lisp.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2008 James Cash ! See http://factorcode.org/license.txt for BSD license. -USING: kernel peg sequences arrays strings combinators.lib +USING: kernel peg sequences arrays strings namespaces combinators math locals locals.private locals.backend accessors -vectors syntax lisp.parser assocs parser sequences.lib words +vectors syntax lisp.parser assocs parser words quotations fry lists summary combinators.short-circuit continuations multiline ; IN: lisp @@ -180,4 +180,4 @@ M: no-such-var summary drop "No such variable" ; : " parse-multiline-string define-lisp-builtins - lisp-string>factor parsed \ call parsed ; parsing \ No newline at end of file + lisp-string>factor parsed \ call parsed ; parsing diff --git a/extra/lisp/parser/parser.factor b/extra/lisp/parser/parser.factor index 1b14f5bb34..72344fd0dc 100644 --- a/extra/lisp/parser/parser.factor +++ b/extra/lisp/parser/parser.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 James Cash ! See http://factorcode.org/license.txt for BSD license. USING: kernel peg peg.ebnf math.parser sequences arrays strings -combinators.lib math fry accessors lists combinators.short-circuit ; +math fry accessors lists combinators.short-circuit ; IN: lisp.parser @@ -36,4 +36,4 @@ atom = number | string s-expression = LPAREN (list-item)* RPAREN => [[ second seq>cons ]] list-item = _ ( atom | s-expression ) _ => [[ second ]] -;EBNF \ No newline at end of file +;EBNF diff --git a/extra/math/algebra/algebra.factor b/extra/math/algebra/algebra.factor index 8bb8420d1a..8cccded26a 100644 --- a/extra/math/algebra/algebra.factor +++ b/extra/math/algebra/algebra.factor @@ -1,8 +1,10 @@ ! Copyright (c) 2007 Samuel Tardieu ! See http://factorcode.org/license.txt for BSD license. -USING: kernel math math.functions sequences ; +USING: kernel math math.functions sequences fry ; IN: math.algebra : chinese-remainder ( aseq nseq -- x ) dup product - [ [ over / [ swap gcd drop ] keep * * ] curry 2map sum ] keep rem ; foldable + [ + '[ _ over / [ swap gcd drop ] keep * * ] 2map sum + ] keep rem ; foldable diff --git a/extra/math/analysis/analysis.factor b/extra/math/analysis/analysis.factor index a41281d779..7da1c96b61 100755 --- a/extra/math/analysis/analysis.factor +++ b/extra/math/analysis/analysis.factor @@ -1,5 +1,7 @@ +! Copyright (C) 2008 Doug Coleman, Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. USING: kernel math math.constants math.functions math.intervals -math.vectors namespaces sequences ; +math.vectors namespaces sequences combinators.short-circuit ; IN: math.analysis r log * r> - - swap 6 gamma-z gamma-p6 v. log + ; + [ 0.5 + dup gamma-g6 + dup [ log * ] dip - ] + [ 6 gamma-z gamma-p6 v. log ] bi + ; : gamma-lanczos6 ( x -- gamma[x] ) #! gamma(x) = gamma(x+1) / x @@ -39,7 +41,7 @@ PRIVATE> : gamma ( x -- y ) #! gamma(x) = integral 0..inf [ t^(x-1) exp(-t) ] dt #! gamma(n+1) = n! for n > 0 - dup 0.0 <= over 1.0 mod zero? and [ + dup { [ 0.0 <= ] [ 1.0 mod zero? ] } 1&& [ drop 1./0. ] [ dup abs gamma-lanczos6 swap dup 0 > [ drop ] [ gamma-neg ] if @@ -55,7 +57,7 @@ PRIVATE> ] if ; : nth-root ( n x -- y ) - over 0 = [ "0th root is undefined" throw ] when >r recip r> swap ^ ; + [ recip ] dip swap ^ ; ! Forth Scientific Library Algorithm #1 ! diff --git a/extra/math/combinatorics/combinatorics.factor b/extra/math/combinatorics/combinatorics.factor index a0c6df083b..b1c49b8ab5 100644 --- a/extra/math/combinatorics/combinatorics.factor +++ b/extra/math/combinatorics/combinatorics.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2007, 2008 Slava Pestov, Doug Coleman, Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: assocs kernel math math.order math.ranges mirrors -namespaces make sequences sequences.lib sorting ; +namespaces sequences sorting fry ; IN: math.combinatorics [ dupd - ] when ; inline ! See this article for explanation of the factoradic-based permutation methodology: -! http://msdn2.microsoft.com/en-us/library/aa302371.aspx +! http://msdn2.microsoft.com/en-us/library/aa302371.aspx : factoradic ( n -- factoradic ) 0 [ over 0 > ] [ 1+ [ /mod ] keep swap ] [ ] produce reverse 2nip ; @@ -39,13 +39,10 @@ PRIVATE> twiddle [ nPk ] keep factorial / ; : permutation ( n seq -- seq ) - tuck permutation-indices swap nths ; + [ permutation-indices ] keep nths ; : all-permutations ( seq -- seq ) - [ - [ length factorial ] keep [ permutation , ] curry each - ] { } make ; + [ length factorial ] keep '[ _ permutation ] map ; : inverse-permutation ( seq -- permutation ) >alist sort-values keys ; - diff --git a/extra/math/compare/compare.factor b/extra/math/compare/compare.factor index 28a8eadc81..d19dac3d2b 100644 --- a/extra/math/compare/compare.factor +++ b/extra/math/compare/compare.factor @@ -19,4 +19,3 @@ IN: math.compare : clamp ( a value b -- x ) min max ; - diff --git a/extra/math/derivatives/derivatives.factor b/extra/math/derivatives/derivatives.factor index ad8d944bfe..b7612e112b 100644 --- a/extra/math/derivatives/derivatives.factor +++ b/extra/math/derivatives/derivatives.factor @@ -1,4 +1,3 @@ - USING: kernel continuations combinators sequences math math.order math.ranges accessors float-arrays ; @@ -7,11 +6,11 @@ IN: math.derivatives TUPLE: state x func h err i j errt fac hh ans a done ; : largest-float ( -- x ) HEX: 7fefffffffffffff bits>double ; foldable -: ntab ( -- val ) 8 ; -: con ( -- val ) 1.6 ; -: con2 ( -- val ) con con * ; -: big ( -- val ) largest-float ; -: safe ( -- val ) 2.0 ; +: ntab ( -- val ) 8 ; inline +: con ( -- val ) 1.6 ; inline +: con2 ( -- val ) con con * ; inline +: big ( -- val ) largest-float ; inline +: safe ( -- val ) 2.0 ; inline ! Yes, this was ported from C code. : a[i][i] ( state -- elt ) [ i>> ] [ i>> ] [ a>> ] tri nth nth ; @@ -120,4 +119,4 @@ TUPLE: state x func h err i j errt fac hh ans a done ; bi ; : derivative ( x func -- m ) 0.01 2.0 (derivative) drop ; -: derivative-func ( func -- der ) [ derivative ] curry ; \ No newline at end of file +: derivative-func ( func -- der ) [ derivative ] curry ; diff --git a/extra/math/erato/erato.factor b/extra/math/erato/erato.factor index f836d71a99..4c6675e8f1 100644 --- a/extra/math/erato/erato.factor +++ b/extra/math/erato/erato.factor @@ -11,8 +11,8 @@ TUPLE: erato limit bits latest ; : ind ( n -- i ) 2/ 1- ; inline -: is-prime ( n erato -- bool ) - >r ind r> bits>> nth ; inline +: is-prime ( n limit -- bool ) + [ ind ] [ bits>> ] bi* nth ; inline : indices ( n erato -- range ) limit>> ind over 3 * ind swap rot ; diff --git a/extra/math/fft/fft.factor b/extra/math/fft/fft.factor index 682d2a49db..b82ecb6b2c 100644 --- a/extra/math/fft/fft.factor +++ b/extra/math/fft/fft.factor @@ -9,7 +9,7 @@ IN: math.fft : odd ( seq -- seq ) 2 group 1 ; DEFER: fft : two ( seq -- seq ) fft 2 v/n dup append ; -: omega ( n -- n ) recip -2 pi i* * * exp ; +: omega ( n -- n' ) recip -2 pi i* * * exp ; : twiddle ( seq -- seq ) dup length dup omega swap n^v v* ; : (fft) ( seq -- seq ) dup odd two twiddle swap even two v+ ; : fft ( seq -- seq ) dup length 1 = [ (fft) ] unless ; diff --git a/extra/math/miller-rabin/miller-rabin.factor b/extra/math/miller-rabin/miller-rabin.factor index f1953340db..45665c701d 100755 --- a/extra/math/miller-rabin/miller-rabin.factor +++ b/extra/math/miller-rabin/miller-rabin.factor @@ -1,3 +1,5 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. USING: combinators combinators.lib io locals kernel math math.functions math.ranges namespaces random sequences hashtables sets ; diff --git a/extra/math/newtons-method/newtons-method.factor b/extra/math/newtons-method/newtons-method.factor index 5bf71deac8..269eae2538 100644 --- a/extra/math/newtons-method/newtons-method.factor +++ b/extra/math/newtons-method/newtons-method.factor @@ -1,11 +1,17 @@ ! Copyright © 2008 Reginald Keith Ford II +! See http://factorcode.org/license.txt for BSD license. ! Newton's Method of approximating roots - USING: kernel math math.derivatives ; IN: math.newtons-method -: newtons-method ( guess function -- x ) newton-precision [ [ newton-step ] keep ] times drop ; + +: newtons-method ( guess function -- x ) + newton-precision [ [ newton-step ] keep ] times drop ; diff --git a/extra/math/numerical-integration/numerical-integration.factor b/extra/math/numerical-integration/numerical-integration.factor index 798d3a5e71..dfaa618b53 100644 --- a/extra/math/numerical-integration/numerical-integration.factor +++ b/extra/math/numerical-integration/numerical-integration.factor @@ -1,18 +1,20 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. USING: arrays kernel sequences namespaces make math math.ranges math.vectors vectors ; IN: math.numerical-integration SYMBOL: num-steps 180 num-steps set-global + : setup-simpson-range ( from to -- frange ) 2dup swap - num-steps get / ; : generate-simpson-weights ( seq -- seq ) - [ - { 1 4 } % length 2 / 2 - { 2 4 } concat % 1 , - ] { } make ; + { 1 4 } + swap length 2 / 2 - { 2 4 } concat + { 1 } 3append ; : integrate-simpson ( from to f -- x ) - >r setup-simpson-range r> - dupd map dup generate-simpson-weights + [ setup-simpson-range dup ] dip + map dup generate-simpson-weights v. swap [ third ] keep first - 6 / * ; - diff --git a/extra/math/polynomials/polynomials.factor b/extra/math/polynomials/polynomials.factor index 8662bbb089..51512ca2e3 100644 --- a/extra/math/polynomials/polynomials.factor +++ b/extra/math/polynomials/polynomials.factor @@ -1,3 +1,5 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. USING: arrays kernel sequences vectors math math.vectors namespaces make shuffle splitting sequences.lib math.order ; IN: math.polynomials @@ -82,5 +84,5 @@ PRIVATE> : polyval ( p x -- p[x] ) #! Evaluate a polynomial. - >r dup length r> powers v. ; + [ dup length ] dip powers v. ; diff --git a/extra/math/primes/primes.factor b/extra/math/primes/primes.factor index f3a515e72b..feb60c555d 100644 --- a/extra/math/primes/primes.factor +++ b/extra/math/primes/primes.factor @@ -8,44 +8,45 @@ IN: math.primes : next-prime ( n -- p ) - dup 999983 < [ - primes-under-million [ natural-search drop 1+ ] keep nth - ] [ - next-odd find-prime-miller-rabin - ] if ; foldable + dup 999983 < [ + primes-under-million [ natural-search drop 1+ ] keep nth + ] [ + next-odd find-prime-miller-rabin + ] if ; foldable : prime? ( n -- ? ) - dup 1000000 < [ - dup primes-under-million natural-search nip = - ] [ - miller-rabin - ] if ; foldable + dup 1000000 < [ + dup primes-under-million natural-search nip = + ] [ + miller-rabin + ] if ; foldable : lprimes ( -- list ) - 0 primes-under-million seq>list - 1000003 [ 2 + find-prime-miller-rabin ] lfrom-by - lappend ; + 0 primes-under-million seq>list + 1000003 [ 2 + find-prime-miller-rabin ] lfrom-by + lappend ; : lprimes-from ( n -- list ) - dup 3 < [ drop lprimes ] [ 1- next-prime [ next-prime ] lfrom-by ] if ; + dup 3 < [ drop lprimes ] [ 1- next-prime [ next-prime ] lfrom-by ] if ; : primes-upto ( n -- seq ) - { - { [ dup 2 < ] [ drop { } ] } - { [ dup 1000003 < ] - [ primes-under-million [ natural-search drop 1+ 0 swap ] keep ] } - [ primes-under-million 1000003 lprimes-from - rot [ <= ] curry lwhile list>array append ] - } cond ; foldable + { + { [ dup 2 < ] [ drop { } ] } + { [ dup 1000003 < ] [ + primes-under-million [ natural-search drop 1+ 0 swap ] keep + ] } + [ primes-under-million 1000003 lprimes-from + rot [ <= ] curry lwhile list>array append ] + } cond ; foldable : primes-between ( low high -- seq ) - primes-upto - [ 1- next-prime ] dip - [ natural-search drop ] keep [ length ] keep ; foldable + primes-upto + [ 1- next-prime ] dip + [ natural-search drop ] keep [ length ] keep ; foldable : coprime? ( a b -- ? ) gcd nip 1 = ; foldable diff --git a/extra/math/quaternions/quaternions.factor b/extra/math/quaternions/quaternions.factor index 3c450f1c05..65f18d3568 100755 --- a/extra/math/quaternions/quaternions.factor +++ b/extra/math/quaternions/quaternions.factor @@ -28,7 +28,7 @@ PRIVATE> : qconjugate ( u -- u' ) #! Quaternion conjugate. - first2 neg >r conjugate r> 2array ; + first2 [ conjugate ] [ neg ] bi* 2array ; : qrecip ( u -- 1/u ) #! Quaternion inverse. diff --git a/extra/math/secant-method/secant-method.factor b/extra/math/secant-method/secant-method.factor index e039b42bbd..ad52c0cd4a 100644 --- a/extra/math/secant-method/secant-method.factor +++ b/extra/math/secant-method/secant-method.factor @@ -1,14 +1,26 @@ ! Copyright © 2008 Reginald Keith Ford II +! See http://factorcode.org/license.txt for BSD license. ! Secant Method of approximating roots - USING: kernel math math.function-tools math.points math.vectors ; IN: math.secant-method -: secant-method ( left right function -- x ) secant-precision [ secant-step ] times drop + 2 / ; + +: secant-method ( left right function -- x ) + secant-precision [ secant-step ] times drop + 2 / ; + ! : close-enough? ( a b -- t/f ) - abs tiny-amount < ; -! : secant-method2 ( left right function -- x ) 2over close-enough? [ drop average ] [ secant-step secant-method ] if ; \ No newline at end of file + +! : secant-method2 ( left right function -- x ) + ! 2over close-enough? + ! [ drop average ] [ secant-step secant-method ] if ; diff --git a/extra/math/statistics/statistics.factor b/extra/math/statistics/statistics.factor index 28cc05151b..8cd6d26c1c 100644 --- a/extra/math/statistics/statistics.factor +++ b/extra/math/statistics/statistics.factor @@ -1,5 +1,7 @@ +! Copyright (C) 2008 Doug Coleman, Michael Judge. +! See http://factorcode.org/license.txt for BSD license. USING: kernel math math.analysis math.functions math.vectors sequences - sequences.lib sorting ; +sequences.lib sorting ; IN: math.statistics : mean ( seq -- n ) @@ -18,7 +20,7 @@ IN: math.statistics : median ( seq -- n ) #! middle number if odd, avg of two middle numbers if even natural-sort dup length dup even? [ - 1- 2 / swap [ nth ] [ >r 1+ r> nth ] 2bi + 2 / + 1- 2 / swap [ nth ] [ [ 1+ ] dip nth ] 2bi + 2 / ] [ 2 / swap nth ] if ; diff --git a/extra/math/text/english/english.factor b/extra/math/text/english/english.factor index 387be4d791..439d0a75fe 100755 --- a/extra/math/text/english/english.factor +++ b/extra/math/text/english/english.factor @@ -1,8 +1,7 @@ ! Copyright (c) 2007 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: combinators.lib kernel math math.functions math.parser namespaces - sequences splitting grouping sequences.lib - combinators.short-circuit ; +sequences splitting grouping combinators.short-circuit ; IN: math.text.english text) ( n -- str ) - dup negative-text swap abs 3digit-groups recombine append ; + [ negative-text ] [ abs 3digit-groups recombine ] bi append ; PRIVATE> : number>text ( n -- str ) - dup zero? [ - small-numbers - ] [ - [ (number>text) ] with-scope - ] if ; + dup zero? [ small-numbers ] [ [ (number>text) ] with-scope ] if ; diff --git a/extra/math/trig/trig.factor b/extra/math/trig/trig.factor index be9ec6a56c..3d9428adda 100644 --- a/extra/math/trig/trig.factor +++ b/extra/math/trig/trig.factor @@ -1,6 +1,6 @@ - +! Copyright (C) 2008 Eduardo Cavazos. +! See http://factorcode.org/license.txt for BSD license. USING: math math.constants ; - IN: math.trig : deg>rad pi * 180 / ; inline diff --git a/extra/money/money.factor b/extra/money/money.factor index 76bc2bae18..5fa76d5f53 100644 --- a/extra/money/money.factor +++ b/extra/money/money.factor @@ -1,6 +1,6 @@ USING: io kernel math math.functions math.parser parser lexer namespaces make sequences splitting grouping combinators -continuations sequences.lib ; +continuations ; IN: money : dollars/cents ( dollars -- dollars cents ) diff --git a/extra/parser-combinators/regexp/regexp.factor b/extra/parser-combinators/regexp/regexp.factor index 40d4603fb6..b13321d991 100755 --- a/extra/parser-combinators/regexp/regexp.factor +++ b/extra/parser-combinators/regexp/regexp.factor @@ -1,6 +1,6 @@ USING: arrays combinators kernel lists math math.parser namespaces parser lexer parser-combinators parser-combinators.simple -promises quotations sequences combinators.lib strings math.order +promises quotations sequences strings math.order assocs prettyprint.backend memoize unicode.case unicode.categories combinators.short-circuit accessors make io ; IN: parser-combinators.regexp diff --git a/extra/printf/printf-docs.factor b/extra/printf/printf-docs.factor index b28b5e1c86..3ca9c07c36 100644 --- a/extra/printf/printf-docs.factor +++ b/extra/printf/printf-docs.factor @@ -18,11 +18,11 @@ HELP: printf { $example "USING: printf ;" "1.23456789 \"%.3f\" printf" - "1.234" } + "1.235" } { $example "USING: printf ;" "1234567890 \"%.5e\" printf" - "1.23456e+09" } + "1.23457e+09" } { $example "USING: printf ;" "12 \"%'#4d\" printf" diff --git a/extra/printf/printf-tests.factor b/extra/printf/printf-tests.factor index 5302048dfe..2123784ea1 100644 --- a/extra/printf/printf-tests.factor +++ b/extra/printf/printf-tests.factor @@ -23,25 +23,27 @@ USING: kernel printf tools.test ; [ t ] [ "+0010" 10 "%+05d" sprintf = ] unit-test -[ t ] [ "123.456" 123.456 "%f" sprintf = ] unit-test +[ t ] [ "123.456000" 123.456 "%f" sprintf = ] unit-test + +[ t ] [ "2.44" 2.436 "%.2f" sprintf = ] unit-test [ t ] [ "123.10" 123.1 "%01.2f" sprintf = ] unit-test -[ t ] [ "1.2345" 1.23456789 "%.4f" sprintf = ] unit-test +[ t ] [ "1.2346" 1.23456789 "%.4f" sprintf = ] unit-test [ t ] [ " 1.23" 1.23456789 "%6.2f" sprintf = ] unit-test -[ t ] [ "1.234e+08" 123400000 "%e" sprintf = ] unit-test +[ t ] [ "1.234000e+08" 123400000 "%e" sprintf = ] unit-test -[ t ] [ "-1.234e+08" -123400000 "%e" sprintf = ] unit-test +[ t ] [ "-1.234000e+08" -123400000 "%e" sprintf = ] unit-test [ t ] [ "1.234567e+08" 123456700 "%e" sprintf = ] unit-test [ t ] [ "3.625e+08" 362525200 "%.3e" sprintf = ] unit-test -[ t ] [ "2.5e-03" 0.0025 "%e" sprintf = ] unit-test +[ t ] [ "2.500000e-03" 0.0025 "%e" sprintf = ] unit-test -[ t ] [ "2.5E-03" 0.0025 "%E" sprintf = ] unit-test +[ t ] [ "2.500000E-03" 0.0025 "%E" sprintf = ] unit-test [ t ] [ " 1.0E+01" 10 "%10.1E" sprintf = ] unit-test diff --git a/extra/printf/printf.factor b/extra/printf/printf.factor index c7a7153d6a..0120891e12 100644 --- a/extra/printf/printf.factor +++ b/extra/printf/printf.factor @@ -2,8 +2,8 @@ ! See http://factorcode.org/license.txt for BSD license USING: io io.encodings.ascii io.files io.streams.string combinators -kernel sequences splitting strings math math.parser macros -fry peg.ebnf ascii unicode.case arrays quotations vectors ; +kernel sequences splitting strings math math.functions math.parser +macros fry peg.ebnf ascii unicode.case arrays quotations vectors ; IN: printf @@ -27,42 +27,52 @@ IN: printf : >digits ( string -- digits ) [ 0 ] [ string>number ] if-empty ; -: max-digits ( string digits -- string ) +: pad-digits ( string digits -- string' ) [ "." split1 ] dip [ CHAR: 0 pad-right ] [ head-slice ] bi "." swap 3append ; -: max-width ( string length -- string ) +: max-digits ( n digits -- n' ) + 10 swap ^ [ * round ] keep / ; + +: max-width ( string length -- string' ) short head ; -: >exponential ( n -- base exp ) - [ 0 < ] keep abs 0 - [ swap dup [ 10.0 >= ] keep 1.0 < or ] - [ dup 10.0 >= - [ 10.0 / [ 1+ ] dip swap ] - [ 10.0 * [ 1- ] dip swap ] if - ] [ swap ] while - [ number>string ] dip - dup abs number>string 2 CHAR: 0 pad-left - [ 0 < "-" "+" ? ] dip append - "e" prepend - rot [ [ "-" prepend ] dip ] when ; +: >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 + ] keep 0 < [ neg ] when ; + +: exp>string ( exp base digits -- string ) + [ max-digits ] keep -rot + [ + [ 0 < "-" "+" ? ] + [ abs number>string 2 CHAR: 0 pad-left ] bi + "e" -rot 3append + ] + [ number>string ] bi* + rot pad-digits prepend ; EBNF: parse-format-string zero = "0" => [[ CHAR: 0 ]] char = "'" (.) => [[ second ]] -pad-char = (zero|char)? => [[ CHAR: \s or 1quotation ]] -pad-align = ("-")? => [[ [ pad-right ] [ pad-left ] ? ]] -pad-width = ([0-9])* => [[ >digits 1quotation ]] -pad = pad-align pad-char pad-width => [[ reverse compose-all [ first ] keep swap 0 = [ drop [ ] ] when ]] +pad-char = (zero|char)? => [[ CHAR: \s or ]] +pad-align = ("-")? => [[ \ pad-right \ pad-left ? ]] +pad-width = ([0-9])* => [[ >digits ]] +pad = pad-align pad-char pad-width => [[ reverse >quotation dup first 0 = [ drop [ ] ] when ]] -sign = ("+")? => [[ [ dup CHAR: - swap index not [ "+" prepend ] when ] [ ] ? ]] +sign = ("+")? => [[ [ dup CHAR: - swap index [ "+" prepend ] unless ] [ ] ? ]] width_ = "." ([0-9])* => [[ second >digits '[ _ max-width ] ]] width = (width_)? => [[ [ ] or ]] -digits_ = "." ([0-9])* => [[ second >digits '[ _ max-digits ] ]] -digits = (digits_)? => [[ [ ] or ]] +digits_ = "." ([0-9])* => [[ second >digits ]] +digits = (digits_)? => [[ 6 or ]] fmt-% = "%" => [[ [ "%" ] ]] fmt-c = "c" => [[ [ 1string ] ]] @@ -70,26 +80,24 @@ fmt-C = "C" => [[ [ 1string >upper ] ]] fmt-s = "s" => [[ [ ] ]] fmt-S = "S" => [[ [ >upper ] ]] fmt-d = "d" => [[ [ >fixnum number>string ] ]] -fmt-e = "e" => [[ [ >exponential ] ]] -fmt-E = "E" => [[ [ >exponential >upper ] ]] -fmt-f = "f" => [[ [ >float 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-x = "x" => [[ [ >hex ] ]] fmt-X = "X" => [[ [ >hex >upper ] ]] unknown = (.)* => [[ "Unknown directive" throw ]] -chars = fmt-c | fmt-C -strings = pad width (fmt-s|fmt-S) => [[ reverse compose-all ]] -decimals = fmt-d -exps = digits (fmt-e|fmt-E) => [[ reverse [ swap ] join [ swap append ] append ]] -floats = digits fmt-f => [[ reverse compose-all ]] -hex = fmt-x | fmt-X -numbers = sign pad (decimals|floats|hex|exps) => [[ reverse first3 swap 3append [ fix-sign ] append ]] +strings_ = fmt-c|fmt-C|fmt-s|fmt-S +strings = pad width strings_ => [[ reverse compose-all ]] -formats = "%" (chars|strings|numbers|fmt-%|unknown) => [[ second '[ _ dip ] ]] +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 ]] -plain-text = (!("%").)+ => [[ >string '[ _ swap ] ]] +formats = "%" (strings|numbers|fmt-%|unknown) => [[ second '[ _ dip ] ]] -text = (formats|plain-text)* => [[ reverse [ [ dup [ push ] dip ] append ] map ]] +plain-text = (!("%").)+ => [[ >string '[ _ swap ] ]] + +text = (formats|plain-text)* => [[ reverse [ [ [ push ] keep ] append ] map ]] ;EBNF diff --git a/extra/project-euler/014/014.factor b/extra/project-euler/014/014.factor index fcbc956de8..dc0c060b22 100644 --- a/extra/project-euler/014/014.factor +++ b/extra/project-euler/014/014.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2007 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays combinators.lib combinators.short-circuit kernel +USING: arrays combinators.short-circuit kernel math math.ranges namespaces make sequences sorting ; IN: project-euler.014 diff --git a/extra/project-euler/017/017.factor b/extra/project-euler/017/017.factor index cf58e88ffe..5f6541873a 100644 --- a/extra/project-euler/017/017.factor +++ b/extra/project-euler/017/017.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2007 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel math.ranges math.text.english sequences sequences.lib strings +USING: kernel math.ranges math.text.english sequences strings ascii combinators.short-circuit ; IN: project-euler.017 diff --git a/extra/project-euler/019/019.factor b/extra/project-euler/019/019.factor index b29495f913..9482b337bb 100644 --- a/extra/project-euler/019/019.factor +++ b/extra/project-euler/019/019.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2007 Samuel Tardieu, Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: calendar combinators kernel math math.ranges namespaces sequences - sequences.lib math.order ; + math.order ; IN: project-euler.019 ! http://projecteuler.net/index.php?section=problems&id=19 @@ -32,7 +32,7 @@ IN: project-euler.019 : euler019 ( -- answer ) 1901 2000 [a,b] [ - 12 [1,b] [ 1 zeller-congruence ] map-with + 12 [1,b] [ 1 zeller-congruence ] with map ] map concat [ zero? ] count ; ! [ euler019 ] 100 ave-time diff --git a/extra/project-euler/021/021.factor b/extra/project-euler/021/021.factor index 9ae5f6af10..af6bb3270b 100644 --- a/extra/project-euler/021/021.factor +++ b/extra/project-euler/021/021.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2007 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: combinators.lib combinators.short-circuit kernel math math.functions - math.ranges namespaces project-euler.common sequences sequences.lib ; +USING: combinators.short-circuit kernel math math.functions + math.ranges namespaces project-euler.common sequences ; IN: project-euler.021 ! http://projecteuler.net/index.php?section=problems&id=21 diff --git a/extra/project-euler/022/022.factor b/extra/project-euler/022/022.factor index 82054ce014..a508ddea6c 100644 --- a/extra/project-euler/022/022.factor +++ b/extra/project-euler/022/022.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2007 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: ascii io.encodings.ascii io.files kernel math project-euler.common - sequences sequences.lib sorting splitting ; + sequences sorting splitting ; IN: project-euler.022 ! http://projecteuler.net/index.php?section=problems&id=22 diff --git a/extra/project-euler/030/030.factor b/extra/project-euler/030/030.factor index 53d6b199fb..250494c0dc 100644 --- a/extra/project-euler/030/030.factor +++ b/extra/project-euler/030/030.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel math math.functions project-euler.common sequences sequences.lib ; +USING: kernel math math.functions project-euler.common sequences ; IN: project-euler.030 ! http://projecteuler.net/index.php?section=problems&id=30 diff --git a/extra/project-euler/032/032.factor b/extra/project-euler/032/032.factor index 8a54c595a9..f9667c75fe 100755 --- a/extra/project-euler/032/032.factor +++ b/extra/project-euler/032/032.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: combinators.lib hashtables kernel math math.combinatorics math.functions +USING: hashtables kernel math math.combinatorics math.functions math.parser math.ranges project-euler.common sequences sets ; IN: project-euler.032 diff --git a/extra/project-euler/034/034.factor b/extra/project-euler/034/034.factor index cf73ee828b..28c4fa5dc7 100644 --- a/extra/project-euler/034/034.factor +++ b/extra/project-euler/034/034.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel math.ranges project-euler.common sequences sequences.lib ; +USING: kernel math.ranges project-euler.common sequences ; IN: project-euler.034 ! http://projecteuler.net/index.php?section=problems&id=34 diff --git a/extra/project-euler/035/035.factor b/extra/project-euler/035/035.factor index cec9bc6957..8e8b654d28 100755 --- a/extra/project-euler/035/035.factor +++ b/extra/project-euler/035/035.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: kernel math math.combinatorics math.parser math.primes - project-euler.common sequences sequences.lib sets ; + project-euler.common sequences sets ; IN: project-euler.035 ! http://projecteuler.net/index.php?section=problems&id=35 diff --git a/extra/project-euler/036/036.factor b/extra/project-euler/036/036.factor index f3a9f738bf..fc9df9a8fe 100644 --- a/extra/project-euler/036/036.factor +++ b/extra/project-euler/036/036.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: combinators.lib combinators.short-circuit kernel math.parser math.ranges +USING: combinators.short-circuit kernel math.parser math.ranges project-euler.common sequences ; IN: project-euler.036 diff --git a/extra/project-euler/039/039.factor b/extra/project-euler/039/039.factor index 7a9f51f1d3..d0caa6d0e4 100755 --- a/extra/project-euler/039/039.factor +++ b/extra/project-euler/039/039.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays combinators.lib kernel math math.ranges +USING: arrays kernel math math.ranges namespaces project-euler.common sequences ; IN: project-euler.039 diff --git a/extra/project-euler/042/042.factor b/extra/project-euler/042/042.factor index da26e34927..8ae95d6db7 100644 --- a/extra/project-euler/042/042.factor +++ b/extra/project-euler/042/042.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: ascii io.files kernel math math.functions namespaces make - project-euler.common sequences sequences.lib splitting io.encodings.ascii ; + project-euler.common sequences splitting io.encodings.ascii ; IN: project-euler.042 ! http://projecteuler.net/index.php?section=problems&id=42 diff --git a/extra/project-euler/043/043.factor b/extra/project-euler/043/043.factor index a2f4ad5c61..84ed7a830f 100644 --- a/extra/project-euler/043/043.factor +++ b/extra/project-euler/043/043.factor @@ -1,8 +1,8 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: combinators.lib combinators.short-circuit hashtables kernel math +USING: combinators.short-circuit hashtables kernel math math.combinatorics math.parser math.ranges project-euler.common sequences - sequences.lib sorting sets ; + sorting sets ; IN: project-euler.043 ! http://projecteuler.net/index.php?section=problems&id=43 diff --git a/extra/project-euler/047/047.factor b/extra/project-euler/047/047.factor index e59ca56f39..87a1387887 100644 --- a/extra/project-euler/047/047.factor +++ b/extra/project-euler/047/047.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays combinators.lib kernel math math.primes math.primes.factors +USING: arrays kernel math math.primes math.primes.factors math.ranges namespaces sequences ; IN: project-euler.047 diff --git a/extra/project-euler/052/052.factor b/extra/project-euler/052/052.factor index aec8015f94..3f562baa85 100644 --- a/extra/project-euler/052/052.factor +++ b/extra/project-euler/052/052.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: combinators.lib combinators.short-circuit kernel math +USING: combinators.short-circuit kernel math project-euler.common sequences sorting ; IN: project-euler.052 diff --git a/extra/project-euler/055/055.factor b/extra/project-euler/055/055.factor index 289f3a002a..bf1dd43b97 100644 --- a/extra/project-euler/055/055.factor +++ b/extra/project-euler/055/055.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel math math.parser project-euler.common sequences sequences.lib ; +USING: kernel math math.parser project-euler.common sequences ; IN: project-euler.055 ! http://projecteuler.net/index.php?section=problems&id=55 @@ -49,8 +49,8 @@ IN: project-euler.055 : (lychrel?) ( n iteration -- ? ) dup 50 < [ - >r add-reverse dup palindrome? - [ r> 2drop f ] [ r> 1+ (lychrel?) ] if + [ add-reverse ] dip over palindrome? + [ 2drop f ] [ 1+ (lychrel?) ] if ] [ 2drop t ] if ; diff --git a/extra/project-euler/059/059.factor b/extra/project-euler/059/059.factor index f209b50a46..e3ab9762d8 100644 --- a/extra/project-euler/059/059.factor +++ b/extra/project-euler/059/059.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2008 Aaron Schaefer, Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: arrays ascii assocs hashtables io.encodings.ascii io.files kernel math - math.parser namespaces make sequences sequences.lib sequences.private sorting + math.parser namespaces make sequences sequences.private sorting splitting grouping strings sets accessors ; IN: project-euler.059 diff --git a/extra/project-euler/075/075.factor b/extra/project-euler/075/075.factor index 8e5b849de5..76f2a2a26e 100755 --- a/extra/project-euler/075/075.factor +++ b/extra/project-euler/075/075.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays combinators.lib kernel math math.ranges - namespaces project-euler.common sequences sequences.lib ; +USING: arrays kernel math math.ranges + namespaces project-euler.common sequences ; IN: project-euler.075 ! http://projecteuler.net/index.php?section=problems&id=75 diff --git a/extra/project-euler/116/116.factor b/extra/project-euler/116/116.factor index 5e2059ad9a..0e3633dc9a 100644 --- a/extra/project-euler/116/116.factor +++ b/extra/project-euler/116/116.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2008 Eric Mertens. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel math math.ranges sequences sequences.lib ; +USING: kernel math math.ranges sequences ; IN: project-euler.116 ! http://projecteuler.net/index.php?section=problems&id=116 diff --git a/extra/project-euler/148/148.factor b/extra/project-euler/148/148.factor index 49fd9a4895..0509936e52 100644 --- a/extra/project-euler/148/148.factor +++ b/extra/project-euler/148/148.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2008 Eric Mertens. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel math math.functions sequences sequences.lib ; +USING: kernel math math.functions sequences ; IN: project-euler.148 ! http://projecteuler.net/index.php?section=problems&id=148 diff --git a/extra/project-euler/151/151.factor b/extra/project-euler/151/151.factor index b64ae3d49f..7913cf9540 100644 --- a/extra/project-euler/151/151.factor +++ b/extra/project-euler/151/151.factor @@ -1,7 +1,6 @@ ! Copyright (c) 2008 Eric Mertens. ! See http://factorcode.org/license.txt for BSD license. -USING: assocs combinators kernel math math.order namespaces sequences - sequences.lib ; +USING: assocs combinators kernel math math.order namespaces sequences ; IN: project-euler.151 ! http://projecteuler.net/index.php?section=problems&id=151 diff --git a/extra/project-euler/186/186.factor b/extra/project-euler/186/186.factor index 5308662daf..7504e09a81 100644 --- a/extra/project-euler/186/186.factor +++ b/extra/project-euler/186/186.factor @@ -1,5 +1,5 @@ USING: circular disjoint-sets kernel math math.ranges - sequences sequences.lib ; +sequences ; IN: project-euler.186 : (generator) ( k -- n ) diff --git a/extra/project-euler/190/190.factor b/extra/project-euler/190/190.factor index 35b9344362..c0b7cb577f 100644 --- a/extra/project-euler/190/190.factor +++ b/extra/project-euler/190/190.factor @@ -1,6 +1,6 @@ ! Copyright (c) 2008 Eric Mertens. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel sequences sequences.lib math math.functions math.ranges locals ; +USING: kernel sequences math math.functions math.ranges locals ; IN: project-euler.190 ! http://projecteuler.net/index.php?section=problems&id=190 diff --git a/extra/sequences/lib/lib-tests.factor b/extra/sequences/lib/lib-tests.factor index a44d41d98a..509d9b1432 100755 --- a/extra/sequences/lib/lib-tests.factor +++ b/extra/sequences/lib/lib-tests.factor @@ -47,13 +47,6 @@ IN: sequences.lib.tests [ t ] [ "ab" 4 strings [ >string ] map "abab" swap member? ] unit-test [ { { } { 1 } { 2 } { 1 2 } } ] [ { 1 2 } power-set ] unit-test -[ f ] [ { } ?first ] unit-test -[ f ] [ { } ?fourth ] unit-test -[ 1 ] [ { 1 2 3 } ?first ] unit-test -[ 2 ] [ { 1 2 3 } ?second ] unit-test -[ 3 ] [ { 1 2 3 } ?third ] unit-test -[ f ] [ { 1 2 3 } ?fourth ] unit-test - [ 1 2 { 3 4 } [ + + ] 2 map-withn ] must-infer { { 6 7 } } [ 1 2 { 3 4 } [ + + ] 2 map-withn ] unit-test { { 16 17 18 19 20 } } [ 1 2 3 4 { 6 7 8 9 10 } [ + + + + ] 4 map-withn ] unit-test diff --git a/extra/sequences/lib/lib.factor b/extra/sequences/lib/lib.factor index fe9d9bb587..ed7f40598c 100755 --- a/extra/sequences/lib/lib.factor +++ b/extra/sequences/lib/lib.factor @@ -131,15 +131,6 @@ PRIVATE> : power-set ( seq -- subsets ) 2 over length exact-number-strings swap [ switches ] curry map ; -: ?first ( seq -- first/f ) 0 swap ?nth ; inline -: ?second ( seq -- second/f ) 1 swap ?nth ; inline -: ?third ( seq -- third/f ) 2 swap ?nth ; inline -: ?fourth ( seq -- fourth/f ) 3 swap ?nth ; inline - -: ?first2 ( seq -- 1st/f 2nd/f ) dup ?first swap ?second ; inline -: ?first3 ( seq -- 1st/f 2nd/f 3rd/f ) dup ?first2 rot ?third ; inline -: ?first4 ( seq -- 1st/f 2nd/f 3rd/f 4th/f ) dup ?first3 roll ?fourth ; inline - USE: continuations : ?subseq ( from to seq -- subseq ) >r >r 0 max r> r> diff --git a/extra/spider/authors.txt b/extra/spider/authors.txt new file mode 100644 index 0000000000..7c1b2f2279 --- /dev/null +++ b/extra/spider/authors.txt @@ -0,0 +1 @@ +Doug Coleman diff --git a/extra/spider/spider-docs.factor b/extra/spider/spider-docs.factor new file mode 100644 index 0000000000..41dd13e918 --- /dev/null +++ b/extra/spider/spider-docs.factor @@ -0,0 +1,56 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: help.markup help.syntax io.streams.string urls +multiline spider.private quotations ; +IN: spider + +HELP: +{ $values + { "base" "a string or url" } + { "spider" spider } } +{ $description "Creates a new web spider with a given base url." } ; + +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." } ; + +HELP: slurp-heap-while +{ $values + { "heap" "a heap" } { "quot1" quotation } { "quot2" quotation } } +{ $description "Removes values from a heap that match the predicate quotation " { $snippet "quot1" } " and processes them with " { $snippet "quot2" } " until the predicate quotation no longer matches." } ; + +ARTICLE: "spider-tutorial" "Spider tutorial" +"To create a new spider, call the " { $link } " word with a link to the site you wish to spider." +{ $code <" "http://concatentative.org" "> } +"The max-depth is initialized to 0, which retrieves just the initial page. Let's initialize it to something more fun:" +{ $code <" 1 >>max-depth "> } +"Now the spider will retrieve the first page and all the pages it links to in the same domain." $nl +"But suppose the front page contains thousands of links. To avoid grabbing them all, we can set " { $slot "max-count" } " to a reasonable limit." +{ $code <" 10 >>max-count "> } +"A timeout might keep the spider from hitting the server too hard:" +{ $code <" USE: calendar 1.5 seconds >>sleep "> } +"Since we happen to know that not all pages of a wiki are suitable for spidering, we will spider only the wiki view pages, not the edit or revisions pages. To do this, we add a filter through which new links are tested; links that pass the filter are added to the todo queue, while links that do not are discarded. You can add several filters to the filter array, but we'll just add a single one for now." +{ $code <" { [ path>> "/wiki/view" head? ] } >>filters "> } +"Finally, to start the spider, call the " { $link run-spider } " word." +{ $code "run-spider" } +"The full code from the tutorial." +{ $code <" USING: spider calendar sequences accessors ; +: spider-concatenative ( -- spider ) + "http://concatenative.org" + 1 >>max-depth + 10 >>max-count + 1.5 seconds >>sleep + { [ path>> "/wiki/view" head? ] } >>filters + run-spider ;"> } ; + +ARTICLE: "spider" "Spider" +"The " { $vocab-link "spider" } " vocabulary implements a simple web spider for retrieving sets of webpages." +{ $subsection "spider-tutorial" } +"Creating a new spider:" +{ $subsection } +"Running the spider:" +{ $subsection run-spider } ; + +ABOUT: "spider" diff --git a/extra/spider/spider.factor b/extra/spider/spider.factor new file mode 100644 index 0000000000..bd5b2668be --- /dev/null +++ b/extra/spider/spider.factor @@ -0,0 +1,101 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors fry html.parser html.parser.analyzer +http.client kernel tools.time sets assocs sequences +concurrency.combinators io threads namespaces math multiline +heaps math.parser inspector urls assoc-heaps logging +combinators.short-circuit continuations calendar prettyprint ; +IN: spider + +TUPLE: spider base count max-count sleep max-depth initial-links +filters spidered todo nonmatching quiet ; + +TUPLE: spider-result url depth headers fetch-time parsed-html +links processing-time timestamp ; + +: ( base -- spider ) + >url + spider new + over >>base + swap 0 [ heap-push ] keep >>todo + >>nonmatching + 0 >>max-depth + 0 >>count + 1/0. >>max-count + H{ } clone >>spidered ; + +> [ '[ _ 1&& ] filter ] when* ; + +: push-links ( links level assoc-heap -- ) + '[ _ _ heap-push ] each ; + +: add-todo ( links level spider -- ) + todo>> push-links ; + +: add-nonmatching ( links level spider -- ) + nonmatching>> push-links ; + +: filter-base ( spider spider-result -- base-links nonmatching-links ) + [ base>> host>> ] [ links>> prune ] bi* + [ host>> = ] with partition ; + +: add-spidered ( spider spider-result -- ) + [ [ 1+ ] change-count ] dip + 2dup [ spidered>> ] [ dup url>> ] bi* rot set-at + [ filter-base ] 2keep + depth>> 1+ swap + [ add-nonmatching ] + [ tuck [ apply-filters ] 2dip add-todo ] 2bi ; + +: normalize-hrefs ( links -- links' ) + [ >url ] map + spider get base>> swap [ derive-url ] with map ; + +: print-spidering ( url depth -- ) + "depth: " write number>string write + ", spidering: " write . yield ; + +: (spider-page) ( url depth -- spider-result ) + f pick spider get spidered>> set-at + over '[ _ http-get ] benchmark swap + [ parse-html dup find-hrefs normalize-hrefs ] benchmark + now spider-result boa ; + +: spider-page ( url depth -- ) + spider get quiet>> [ 2dup print-spidering ] unless + (spider-page) + spider get [ quiet>> [ dup describe ] unless ] + [ swap add-spidered ] bi ; + +\ spider-page ERROR add-error-logging + +: spider-sleep ( -- ) + spider get sleep>> [ sleep ] when* ; + +: queue-initial-links ( spider -- spider ) + [ initial-links>> normalize-hrefs 0 ] keep + [ add-todo ] keep ; + +: slurp-heap-while ( heap quot1 quot2: ( value key -- ) -- ) + pick heap-empty? [ 3drop ] [ + [ [ heap-pop dup ] 2dip slip [ t ] compose [ 2drop f ] if ] + [ roll [ slurp-heap-while ] [ 3drop ] if ] 3bi + ] if ; inline recursive + +PRIVATE> + +: run-spider ( spider -- spider ) + "spider" [ + dup spider [ + queue-initial-links + [ todo>> ] [ max-depth>> ] bi + '[ + _ <= spider get + [ count>> ] [ max-count>> ] bi < and + ] [ spider-page spider-sleep ] slurp-heap-while + spider get + ] with-variable + ] with-logging ; diff --git a/extra/suffix-arrays/authors.txt b/extra/suffix-arrays/authors.txt new file mode 100755 index 0000000000..e4a36df7ef --- /dev/null +++ b/extra/suffix-arrays/authors.txt @@ -0,0 +1 @@ +Marc Fauconneau \ No newline at end of file diff --git a/extra/suffix-arrays/suffix-arrays-docs.factor b/extra/suffix-arrays/suffix-arrays-docs.factor new file mode 100755 index 0000000000..87df27281e --- /dev/null +++ b/extra/suffix-arrays/suffix-arrays-docs.factor @@ -0,0 +1,45 @@ +! Copyright (C) 2008 Marc Fauconneau. +! See http://factorcode.org/license.txt for BSD license. +USING: arrays help.markup help.syntax io.streams.string +sequences strings math suffix-arrays.private ; +IN: suffix-arrays + +HELP: >suffix-array +{ $values + { "seq" sequence } + { "array" array } } +{ $description "Creates a suffix array from the input sequence. Suffix arrays are arrays of slices." } ; + +HELP: SA{ +{ $description "Creates a new literal suffix array at parse-time." } ; + +HELP: suffixes +{ $values + { "string" string } + { "suffixes-seq" "a sequence of slices" } } +{ $description "Returns a sequence of tail slices of the input string." } ; + +HELP: from-to +{ $values + { "index" integer } { "begin" sequence } { "suffix-array" "a suffix-array" } + { "from/f" "an integer or f" } { "to/f" "an integer or f" } } +{ $description "Finds the bounds of the suffix array that match the input sequence. A return value of " { $link f } " means that the endpoint is included." } +{ $notes "Slices are [m,n) and we want (m,n) so we increment." } ; + +HELP: query +{ $values + { "begin" sequence } { "suffix-array" "a suffix-array" } + { "matches" array } } +{ $description "Returns a sequence of sequences from the suffix-array that contain the input sequence. An empty array is returned when there are no matches." } ; + +ARTICLE: "suffix-arrays" "Suffix arrays" +"The " { $vocab-link "suffix-arrays" } " vocabulary implements the suffix array data structure for efficient lookup of subsequences. This suffix array implementation is a sorted array of suffixes. Querying it for matches uses binary search for efficiency." $nl + +"Creating new suffix arrays:" +{ $subsection >suffix-array } +"Literal suffix arrays:" +{ $subsection POSTPONE: SA{ } +"Querying suffix arrays:" +{ $subsection query } ; + +ABOUT: "suffix-arrays" diff --git a/extra/suffix-arrays/suffix-arrays-tests.factor b/extra/suffix-arrays/suffix-arrays-tests.factor new file mode 100755 index 0000000000..5149804ce6 --- /dev/null +++ b/extra/suffix-arrays/suffix-arrays-tests.factor @@ -0,0 +1,38 @@ +! Copyright (C) 2008 Marc Fauconneau. +! See http://factorcode.org/license.txt for BSD license. +USING: tools.test suffix-arrays kernel namespaces sequences ; +IN: suffix-arrays.tests + +! built from [ all-words 10 head [ name>> ] map ] +[ ] [ + { + "run-tests" + "must-fail-with" + "test-all" + "short-effect" + "failure" + "test" + "" + "this-test" + "(unit-test)" + "unit-test" + } >suffix-array "suffix-array" set +] unit-test + +[ t ] +[ "suffix-array" get "" swap query empty? not ] unit-test + +[ { } ] +[ SA{ } "something" swap query ] unit-test + +[ V{ "unit-test" "(unit-test)" } ] +[ "suffix-array" get "unit-test" swap query ] unit-test + +[ t ] +[ "suffix-array" get "something else" swap query empty? ] unit-test + +[ V{ "rofl" } ] [ SA{ "rofl" } "r" swap query ] unit-test +[ V{ "rofl" } ] [ SA{ "rofl" } "o" swap query ] unit-test +[ V{ "rofl" } ] [ SA{ "rofl" } "f" swap query ] unit-test +[ V{ "rofl" } ] [ SA{ "rofl" } "l" swap query ] unit-test +[ V{ } ] [ SA{ "rofl" } "t" swap query ] unit-test diff --git a/extra/suffix-arrays/suffix-arrays.factor b/extra/suffix-arrays/suffix-arrays.factor new file mode 100755 index 0000000000..b181ba9d60 --- /dev/null +++ b/extra/suffix-arrays/suffix-arrays.factor @@ -0,0 +1,39 @@ +! Copyright (C) 2008 Marc Fauconneau. +! See http://factorcode.org/license.txt for BSD license. +USING: parser kernel arrays math accessors sequences +math.vectors math.order sorting binary-search sets assocs fry ; +IN: suffix-arrays + + ( begin seq -- <=> ) + [ <=> ] [ swap head? ] 2bi [ drop +eq+ ] when ; + +: find-index ( begin suffix-array -- index/f ) + [ prefix<=> ] with search drop ; + +: from-to ( index begin suffix-array -- from/f to/f ) + swap '[ _ head? not ] + [ find-last-from drop dup [ 1+ ] when ] + [ find-from drop ] 3bi ; + +: ( from/f to/f seq -- slice ) + [ + tuck + [ drop 0 or ] [ length or ] 2bi* + [ min ] keep + ] keep ; inline + +PRIVATE> + +: >suffix-array ( seq -- array ) + [ suffixes ] map concat natural-sort ; + +: SA{ \ } [ >suffix-array ] parse-literal ; parsing + +: query ( begin suffix-array -- matches ) + 2dup find-index dup + [ -rot [ from-to ] keep [ seq>> ] map prune ] + [ 3drop { } ] if ; diff --git a/extra/suffix-arrays/summary.txt b/extra/suffix-arrays/summary.txt new file mode 100755 index 0000000000..71eda476bc --- /dev/null +++ b/extra/suffix-arrays/summary.txt @@ -0,0 +1 @@ +Suffix arrays diff --git a/extra/suffix-arrays/tags.txt b/extra/suffix-arrays/tags.txt new file mode 100755 index 0000000000..42d711b32b --- /dev/null +++ b/extra/suffix-arrays/tags.txt @@ -0,0 +1 @@ +collections diff --git a/extra/suffix-arrays/words/words.factor b/extra/suffix-arrays/words/words.factor new file mode 100755 index 0000000000..74e2fc2f97 --- /dev/null +++ b/extra/suffix-arrays/words/words.factor @@ -0,0 +1,19 @@ +! Copyright (C) 2008 Marc Fauconneau. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel arrays math accessors sequences math.vectors +math.order sorting binary-search sets assocs fry suffix-arrays ; +IN: suffix-arrays.words + +! to search on word names + +: new-word-sa ( words -- sa ) + [ name>> ] map >suffix-array ; + +: name>word-map ( words -- map ) + dup [ name>> V{ } clone ] H{ } map>assoc + [ '[ dup name>> _ at push ] each ] keep ; + +: query-word-sa ( map begin sa -- matches ) query '[ _ at ] map concat ; + +! usage example : +! clear all-words 100 head dup name>word-map "test" rot new-word-sa query . diff --git a/extra/taxes/usa/federal/federal.factor b/extra/taxes/usa/federal/federal.factor new file mode 100644 index 0000000000..b71b831ca6 --- /dev/null +++ b/extra/taxes/usa/federal/federal.factor @@ -0,0 +1,59 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors arrays assocs kernel math math.intervals +namespaces sequences money math.order taxes.usa.fica +taxes.usa.medicare taxes.usa taxes.usa.w4 ; +IN: taxes.usa.federal + +! http://www.irs.gov/pub/irs-pdf/p15.pdf +! Table 7 ANNUAL Payroll Period + +: federal-single ( -- triples ) + { + { 0 2650 DECIMAL: 0 } + { 2650 10300 DECIMAL: .10 } + { 10300 33960 DECIMAL: .15 } + { 33960 79725 DECIMAL: .25 } + { 79725 166500 DECIMAL: .28 } + { 166500 359650 DECIMAL: .33 } + { 359650 1/0. DECIMAL: .35 } + } ; + +: federal-married ( -- triples ) + { + { 0 8000 DECIMAL: 0 } + { 8000 23550 DECIMAL: .10 } + { 23550 72150 DECIMAL: .15 } + { 72150 137850 DECIMAL: .25 } + { 137850 207700 DECIMAL: .28 } + { 207700 365100 DECIMAL: .33 } + { 365100 1/0. DECIMAL: .35 } + } ; + +SINGLETON: federal +: ( -- obj ) + federal federal-single federal-married ; + +: federal-tax ( salary w4 tax-table -- n ) + [ adjust-allowances ] 2keep marriage-table tax ; + +M: federal adjust-allowances* ( salary w4 collector entity -- newsalary ) + 2drop calculate-w4-allowances - ; + +M: federal withholding* ( salary w4 tax-table entity -- x ) + drop + [ federal-tax ] 3keep drop + [ fica-tax ] 2keep + medicare-tax + + ; + +: total-withholding ( salary w4 tax-table -- x ) + dup entity>> dup federal = [ + withholding* + ] [ + drop + [ drop federal withholding* ] + [ dup entity>> withholding* ] 3bi + + ] if ; + +: net ( salary w4 collector -- x ) + >r dupd r> total-withholding - ; diff --git a/extra/taxes/usa/fica/fica.factor b/extra/taxes/usa/fica/fica.factor new file mode 100644 index 0000000000..c1e85b75b4 --- /dev/null +++ b/extra/taxes/usa/fica/fica.factor @@ -0,0 +1,17 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors assocs.lib math math.order money ; +IN: taxes.usa.fica + +: fica-tax-rate ( -- x ) DECIMAL: .062 ; inline + +ERROR: fica-base-unknown year ; + +: fica-base-rate ( year -- x ) + H{ + { 2008 102000 } + { 2007 97500 } + } [ fica-base-unknown ] unless-at ; + +: fica-tax ( salary w4 -- x ) + year>> fica-base-rate min fica-tax-rate * ; diff --git a/extra/taxes/usa/futa/futa.factor b/extra/taxes/usa/futa/futa.factor new file mode 100644 index 0000000000..7368aef825 --- /dev/null +++ b/extra/taxes/usa/futa/futa.factor @@ -0,0 +1,15 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors arrays assocs kernel math math.intervals +namespaces sequences money math.order ; +IN: taxes.usa.futa + +! Employer tax only, not withheld +: futa-tax-rate ( -- x ) DECIMAL: .062 ; inline +: futa-base-rate ( -- x ) 7000 ; inline +: futa-tax-offset-credit ( -- x ) DECIMAL: .054 ; inline + +: futa-tax ( salary w4 -- x ) + drop futa-base-rate min + futa-tax-rate futa-tax-offset-credit - + * ; diff --git a/extra/taxes/usa/medicare/medicare.factor b/extra/taxes/usa/medicare/medicare.factor new file mode 100644 index 0000000000..ea95224456 --- /dev/null +++ b/extra/taxes/usa/medicare/medicare.factor @@ -0,0 +1,8 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel math money ; +IN: taxes.usa.medicare + +! No base rate for medicare; all wages subject +: medicare-tax-rate ( -- x ) DECIMAL: .0145 ; inline +: medicare-tax ( salary w4 -- x ) drop medicare-tax-rate * ; diff --git a/extra/taxes/usa/mn/mn.factor b/extra/taxes/usa/mn/mn.factor new file mode 100644 index 0000000000..8bb629efcd --- /dev/null +++ b/extra/taxes/usa/mn/mn.factor @@ -0,0 +1,33 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors arrays assocs kernel math math.intervals +namespaces sequences money math.order usa-cities +taxes.usa taxes.usa.w4 ; +IN: taxes.usa.mn + +! Minnesota +: mn-single ( -- triples ) + { + { 0 1950 DECIMAL: 0 } + { 1950 23750 DECIMAL: .0535 } + { 23750 73540 DECIMAL: .0705 } + { 73540 1/0. DECIMAL: .0785 } + } ; + +: mn-married ( -- triples ) + { + { 0 7400 DECIMAL: 0 } + { 7400 39260 DECIMAL: .0535 } + { 39260 133980 DECIMAL: .0705 } + { 133980 1/0. DECIMAL: .0785 } + } ; + +: ( -- obj ) + MN mn-single mn-married ; + +M: MN adjust-allowances* ( salary w4 collector entity -- newsalary ) + 2drop calculate-w4-allowances - ; + +M: MN withholding* ( salary w4 collector entity -- x ) + drop + [ adjust-allowances ] 2keep marriage-table tax ; diff --git a/unmaintained/taxes/taxes-tests.factor b/extra/taxes/usa/usa-tests.factor similarity index 56% rename from unmaintained/taxes/taxes-tests.factor rename to extra/taxes/usa/usa-tests.factor index 17d1998f67..a529762c81 100644 --- a/unmaintained/taxes/taxes-tests.factor +++ b/extra/taxes/usa/usa-tests.factor @@ -1,5 +1,7 @@ -USING: kernel money taxes tools.test ; -IN: taxes.tests +USING: kernel money tools.test +taxes.usa taxes.usa.federal taxes.usa.mn +taxes.utils taxes.usa.w4 usa-cities ; +IN: taxes.usa.tests [ 426 23 @@ -42,14 +44,14 @@ IN: taxes.tests [ 780 81 ] [ - 24000 2008 3 f net biweekly + 24000 2008 3 f net biweekly dollars/cents ] unit-test [ 818 76 ] [ - 24000 2008 3 t net biweekly + 24000 2008 3 t net biweekly dollars/cents ] unit-test @@ -57,14 +59,14 @@ IN: taxes.tests [ 2124 39 ] [ - 78250 2008 3 f net biweekly + 78250 2008 3 f net biweekly dollars/cents ] unit-test [ 2321 76 ] [ - 78250 2008 3 t net biweekly + 78250 2008 3 t net biweekly dollars/cents ] unit-test @@ -72,45 +74,45 @@ IN: taxes.tests [ 2612 63 ] [ - 100000 2008 3 f net biweekly + 100000 2008 3 f net biweekly dollars/cents ] unit-test [ 22244 52 ] [ - 1000000 2008 3 f net biweekly + 1000000 2008 3 f net biweekly dollars/cents ] unit-test [ 578357 40 ] [ - 1000000 2008 3 f net + 1000000 2008 3 f net dollars/cents ] unit-test [ 588325 41 ] [ - 1000000 2008 3 t net + 1000000 2008 3 t net dollars/cents ] unit-test [ 30 97 ] [ - 24000 2008 2 f withholding biweekly dollars/cents + 24000 2008 2 f MN withholding* biweekly dollars/cents ] unit-test [ 173 66 ] [ - 78250 2008 2 f withholding biweekly dollars/cents + 78250 2008 2 f MN withholding* biweekly dollars/cents ] unit-test [ 138 69 ] [ - 24000 2008 2 f withholding biweekly dollars/cents + 24000 2008 2 f total-withholding biweekly dollars/cents ] unit-test [ 754 72 ] [ - 78250 2008 2 f withholding biweekly dollars/cents + 78250 2008 2 f total-withholding biweekly dollars/cents ] unit-test diff --git a/extra/taxes/usa/usa.factor b/extra/taxes/usa/usa.factor new file mode 100644 index 0000000000..27ff4aef98 --- /dev/null +++ b/extra/taxes/usa/usa.factor @@ -0,0 +1,32 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors arrays assocs kernel math math.intervals +namespaces sequences money math.order taxes.usa.w4 ; +IN: taxes.usa + +! Withhold: FICA, Medicare, Federal (FICA is social security) + +TUPLE: tax-table entity single married ; +C: tax-table + +GENERIC: adjust-allowances* ( salary w4 tax-table entity -- newsalary ) +GENERIC: withholding* ( salary w4 tax-table entity -- x ) + +: adjust-allowances ( salary w4 tax-table -- newsalary ) + dup entity>> adjust-allowances* ; + +: withholding ( salary w4 tax-table -- x ) + dup entity>> withholding* ; + +: tax-bracket-range ( pair -- n ) first2 swap - ; + +: tax-bracket ( tax salary triples -- tax salary ) + [ [ tax-bracket-range min ] keep third * + ] 2keep + tax-bracket-range [-] ; + +: tax ( salary triples -- x ) + 0 -rot [ tax-bracket ] each drop ; + +: marriage-table ( w4 tax-table -- triples ) + swap married?>> + [ married>> ] [ single>> ] if ; diff --git a/extra/taxes/usa/w4/w4.factor b/extra/taxes/usa/w4/w4.factor new file mode 100644 index 0000000000..aad3773220 --- /dev/null +++ b/extra/taxes/usa/w4/w4.factor @@ -0,0 +1,13 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors kernel math ; +IN: taxes.usa.w4 + +! Each employee fills out a w4 +TUPLE: w4 year allowances married? ; +C: w4 + +: allowance ( -- x ) 3500 ; inline + +: calculate-w4-allowances ( w4 -- x ) allowances>> allowance * ; + diff --git a/extra/taxes/utils/utils.factor b/extra/taxes/utils/utils.factor new file mode 100644 index 0000000000..a5c2240625 --- /dev/null +++ b/extra/taxes/utils/utils.factor @@ -0,0 +1,10 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: math ; +IN: taxes.utils + +: monthly ( x -- y ) 12 / ; +: semimonthly ( x -- y ) 24 / ; +: biweekly ( x -- y ) 26 / ; +: weekly ( x -- y ) 52 / ; +: daily ( x -- y ) 360 / ; diff --git a/unmaintained/tetris/README.txt b/extra/tetris/README.txt similarity index 91% rename from unmaintained/tetris/README.txt rename to extra/tetris/README.txt index bd34dc3c16..e8f81fc831 100644 --- a/unmaintained/tetris/README.txt +++ b/extra/tetris/README.txt @@ -14,3 +14,4 @@ n: start a new game TODO: - rotation of pieces when they're on the far right of the board - make blocks prettier +- possibly make piece inherit from tetromino diff --git a/unmaintained/tetris/authors.txt b/extra/tetris/authors.txt similarity index 100% rename from unmaintained/tetris/authors.txt rename to extra/tetris/authors.txt diff --git a/unmaintained/tetris/board/authors.txt b/extra/tetris/board/authors.txt similarity index 100% rename from unmaintained/tetris/board/authors.txt rename to extra/tetris/board/authors.txt diff --git a/extra/tetris/board/board-tests.factor b/extra/tetris/board/board-tests.factor new file mode 100644 index 0000000000..518b5544e9 --- /dev/null +++ b/extra/tetris/board/board-tests.factor @@ -0,0 +1,23 @@ +USING: accessors arrays colors kernel tetris.board tetris.piece tools.test ; + +[ { { f f } { f f } { f f } } ] [ 2 3 make-rows ] unit-test +[ { { f f } { f f } { f f } } ] [ 2 3 rows>> ] unit-test +[ 1 { f f } ] [ 2 3 { 1 1 } board@block ] unit-test +[ f ] [ 2 3 { 1 1 } block ] unit-test +[ 2 3 { 2 3 } block ] must-fail +red 1array [ 2 3 dup { 1 1 } red set-block { 1 1 } block ] unit-test +[ t ] [ 2 3 { 1 1 } block-free? ] unit-test +[ f ] [ 2 3 dup { 1 1 } red set-block { 1 1 } block-free? ] unit-test +[ t ] [ 2 3 dup { 1 1 } red set-block { 1 2 } block-free? ] unit-test +[ t ] [ 2 3 dup { 1 1 } red set-block { 0 1 } block-free? ] unit-test +[ t ] [ 2 3 { 0 0 } block-in-bounds? ] unit-test +[ f ] [ 2 3 { -1 0 } block-in-bounds? ] unit-test +[ t ] [ 2 3 { 1 2 } block-in-bounds? ] unit-test +[ f ] [ 2 3 { 2 2 } block-in-bounds? ] unit-test +[ t ] [ 2 3 { 1 1 } location-valid? ] unit-test +[ f ] [ 2 3 dup { 1 1 } red set-block { 1 1 } location-valid? ] unit-test +[ t ] [ 10 10 10 piece-valid? ] unit-test +[ f ] [ 2 3 10 { 1 2 } >>location piece-valid? ] unit-test +[ { { f } { f } } ] [ 1 1 add-row rows>> ] unit-test +[ { { f } } ] [ 1 2 dup { 0 1 } red set-block remove-full-rows rows>> ] unit-test +[ { { f } { f } } ] [ 1 2 dup { 0 1 } red set-block dup check-rows drop rows>> ] unit-test diff --git a/unmaintained/tetris/board/board.factor b/extra/tetris/board/board.factor similarity index 51% rename from unmaintained/tetris/board/board.factor rename to extra/tetris/board/board.factor index 3e4548078c..1f12dcabe6 100644 --- a/unmaintained/tetris/board/board.factor +++ b/extra/tetris/board/board.factor @@ -1,9 +1,9 @@ -! Copyright (C) 2006, 2007 Alex Chapman +! Copyright (C) 2006, 2007, 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: kernel sequences arrays tetris.piece math ; +USING: accessors arrays kernel math sequences tetris.piece ; IN: tetris.board -TUPLE: board width height rows ; +TUPLE: board { width integer } { height integer } rows ; : make-rows ( width height -- rows ) [ drop f ] with map ; @@ -15,17 +15,17 @@ TUPLE: board width height rows ; #! the tetris board, and { 9 19 } is the bottom right on a 10x20 board. : board@block ( board block -- n row ) - [ second swap board-rows nth ] keep first swap ; + [ second swap rows>> nth ] keep first swap ; -: board-set-block ( board block colour -- ) -rot board@block set-nth ; +: set-block ( board block colour -- ) -rot board@block set-nth ; -: board-block ( board block -- colour ) board@block nth ; +: block ( board block -- colour ) board@block nth ; -: block-free? ( board block -- ? ) board-block not ; +: block-free? ( board block -- ? ) block not ; : block-in-bounds? ( board block -- ? ) - [ first swap board-width bounds-check? ] 2keep - second swap board-height bounds-check? and ; + [ first swap width>> bounds-check? ] 2keep + second swap height>> bounds-check? and ; : location-valid? ( board block -- ? ) 2dup block-in-bounds? [ block-free? ] [ 2drop f ] if ; @@ -35,22 +35,21 @@ TUPLE: board width height rows ; : row-not-full? ( row -- ? ) f swap member? ; -: add-row ( board -- ) - dup board-rows over board-width f - prefix swap set-board-rows ; +: add-row ( board -- board ) + dup rows>> over width>> f prefix >>rows ; : top-up-rows ( board -- ) - dup board-height over board-rows length = [ + dup height>> over rows>> length = [ drop ] [ - dup add-row top-up-rows + add-row top-up-rows ] if ; -: remove-full-rows ( board -- ) - dup board-rows [ row-not-full? ] filter swap set-board-rows ; +: remove-full-rows ( board -- board ) + [ [ row-not-full? ] filter ] change-rows ; : check-rows ( board -- n ) #! remove full rows, then add blank ones at the top, returning the number #! of rows removed (and added) - dup remove-full-rows dup board-height over board-rows length - >r top-up-rows r> ; + remove-full-rows dup height>> over rows>> length - swap top-up-rows ; diff --git a/unmaintained/tetris/deploy.factor b/extra/tetris/deploy.factor similarity index 100% rename from unmaintained/tetris/deploy.factor rename to extra/tetris/deploy.factor diff --git a/unmaintained/tetris/game/authors.txt b/extra/tetris/game/authors.txt similarity index 100% rename from unmaintained/tetris/game/authors.txt rename to extra/tetris/game/authors.txt diff --git a/extra/tetris/game/game-tests.factor b/extra/tetris/game/game-tests.factor new file mode 100644 index 0000000000..047c20d053 --- /dev/null +++ b/extra/tetris/game/game-tests.factor @@ -0,0 +1,16 @@ +USING: accessors kernel tetris.game tetris.board tetris.piece tools.test +sequences ; + +[ t ] [ [ current-piece ] [ next-piece ] bi and t f ? ] unit-test +[ t ] [ { 1 1 } can-move? ] unit-test +[ t ] [ { 1 1 } tetris-move ] unit-test +[ 1 ] [ dup { 1 1 } tetris-move drop current-piece location>> second ] unit-test +[ 1 ] [ level>> ] unit-test +[ 1 ] [ 9 >>rows level>> ] unit-test +[ 2 ] [ 10 >>rows level>> ] unit-test +[ 0 ] [ 3 0 rows-score ] unit-test +[ 80 ] [ 1 1 rows-score ] unit-test +[ 4800 ] [ 3 4 rows-score ] unit-test +[ 1 ] [ dup 3 score-rows dup 3 score-rows dup 3 score-rows level>> ] unit-test +[ 2 ] [ dup 4 score-rows dup 4 score-rows dup 2 score-rows level>> ] unit-test + diff --git a/extra/tetris/game/game.factor b/extra/tetris/game/game.factor new file mode 100644 index 0000000000..30622c9e38 --- /dev/null +++ b/extra/tetris/game/game.factor @@ -0,0 +1,114 @@ +! Copyright (C) 2006, 2007, 2008 Alex Chapman +! See http://factorcode.org/license.txt for BSD license. +USING: accessors combinators kernel lists math math.functions sequences system tetris.board tetris.piece tetris.tetromino ; +IN: tetris.game + +TUPLE: tetris + { board board } + { pieces } + { last-update integer initial: 0 } + { rows integer initial: 0 } + { score integer initial: 0 } + { paused? initial: f } + { running? initial: t } ; + +: default-width 10 ; inline +: default-height 20 ; inline + +: ( width height -- tetris ) + dupd swap + tetris new swap >>pieces swap >>board ; + +: ( -- tetris ) default-width default-height ; + +: ( old -- new ) + board>> [ width>> ] [ height>> ] bi ; + +: current-piece ( tetris -- piece ) pieces>> car ; + +: next-piece ( tetris -- piece ) pieces>> cdr car ; + +: toggle-pause ( tetris -- ) + [ not ] change-paused? drop ; + +: level>> ( tetris -- level ) + rows>> 1+ 10 / ceiling ; + +: update-interval ( tetris -- interval ) + level>> 1- 60 * 1000 swap - ; + +: add-block ( tetris block -- ) + over board>> spin current-piece tetromino>> colour>> set-block ; + +: game-over? ( tetris -- ? ) + [ board>> ] [ next-piece ] bi piece-valid? not ; + +: new-current-piece ( tetris -- tetris ) + dup game-over? [ + f >>running? + ] [ + [ cdr ] change-pieces + ] if ; + +: rows-score ( level n -- score ) + { + { 0 [ 0 ] } + { 1 [ 40 ] } + { 2 [ 100 ] } + { 3 [ 300 ] } + { 4 [ 1200 ] } + } case swap 1+ * ; + +: add-score ( tetris n-rows -- tetris ) + over level>> swap rows-score swap [ + ] change-score ; + +: add-rows ( tetris rows -- tetris ) + swap [ + ] change-rows ; + +: score-rows ( tetris n -- ) + [ add-score ] keep add-rows drop ; + +: lock-piece ( tetris -- ) + [ dup current-piece piece-blocks [ add-block ] with each ] keep + new-current-piece dup board>> check-rows score-rows ; + +: can-rotate? ( tetris -- ? ) + [ board>> ] [ current-piece clone 1 rotate-piece ] bi piece-valid? ; + +: (rotate) ( inc tetris -- ) + dup can-rotate? [ current-piece swap rotate-piece drop ] [ 2drop ] if ; + +: rotate-left ( tetris -- ) -1 swap (rotate) ; + +: rotate-right ( tetris -- ) 1 swap (rotate) ; + +: can-move? ( tetris move -- ? ) + [ drop board>> ] [ [ current-piece clone ] dip move-piece ] 2bi piece-valid? ; + +: tetris-move ( tetris move -- ? ) + #! moves the piece if possible, returns whether the piece was moved + 2dup can-move? [ + >r current-piece r> move-piece drop t + ] [ + 2drop f + ] if ; + +: move-left ( tetris -- ) { -1 0 } tetris-move drop ; + +: move-right ( tetris -- ) { 1 0 } tetris-move drop ; + +: move-down ( tetris -- ) + dup { 0 1 } tetris-move [ drop ] [ lock-piece ] if ; + +: move-drop ( tetris -- ) + dup { 0 1 } tetris-move [ move-drop ] [ lock-piece ] if ; + +: update ( tetris -- ) + millis over last-update>> - + over update-interval > [ + dup move-down + millis >>last-update + ] when drop ; + +: ?update ( tetris -- ) + dup [ paused?>> ] [ running?>> not ] bi or [ drop ] [ update ] if ; diff --git a/unmaintained/tetris/gl/authors.txt b/extra/tetris/gl/authors.txt similarity index 100% rename from unmaintained/tetris/gl/authors.txt rename to extra/tetris/gl/authors.txt diff --git a/unmaintained/tetris/gl/gl.factor b/extra/tetris/gl/gl.factor similarity index 51% rename from unmaintained/tetris/gl/gl.factor rename to extra/tetris/gl/gl.factor index e425c4766f..d47f027293 100644 --- a/unmaintained/tetris/gl/gl.factor +++ b/extra/tetris/gl/gl.factor @@ -1,8 +1,6 @@ -! Copyright (C) 2006, 2007 Alex Chapman +! Copyright (C) 2006, 2007, 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. -USING: kernel sequences arrays math math.vectors namespaces -opengl opengl.gl ui.render ui.gadgets tetris.game tetris.board -tetris.piece tetris.tetromino ; +USING: accessors arrays combinators kernel math math.vectors namespaces opengl opengl.gl sequences tetris.board tetris.game tetris.piece ui.render tetris.tetromino ui.gadgets ; IN: tetris.gl #! OpenGL rendering for tetris @@ -14,33 +12,36 @@ IN: tetris.gl piece-blocks [ draw-block ] each ; : draw-piece ( piece -- ) - dup tetromino-colour gl-color draw-piece-blocks ; + dup tetromino>> colour>> set-color draw-piece-blocks ; : draw-next-piece ( piece -- ) - dup tetromino-colour clone 0.2 3 pick set-nth gl-color draw-piece-blocks ; + dup tetromino>> colour>> + clone 0.2 >>alpha set-color draw-piece-blocks ; ! TODO: move implementation specific stuff into tetris-board : (draw-row) ( x y row -- ) >r over r> nth dup - [ gl-color 2array draw-block ] [ 3drop ] if ; + [ set-color 2array draw-block ] [ 3drop ] if ; : draw-row ( y row -- ) dup length -rot [ (draw-row) ] 2curry each ; : draw-board ( board -- ) - board-rows dup length swap + rows>> dup length swap [ dupd nth draw-row ] curry each ; -: scale-tetris ( width height tetris -- ) - [ board-width swap ] keep board-height / -rot / swap 1 glScalef ; +: scale-board ( width height board -- ) + [ width>> ] [ height>> ] bi swapd [ / ] dup 2bi* 1 glScalef ; : (draw-tetris) ( width height tetris -- ) #! width and height are in pixels GL_MODELVIEW [ - [ scale-tetris ] keep - dup tetris-board draw-board - dup tetris-next-piece draw-next-piece - tetris-current-piece draw-piece + { + [ board>> scale-board ] + [ board>> draw-board ] + [ next-piece draw-next-piece ] + [ current-piece draw-piece ] + } cleave ] do-matrix ; : draw-tetris ( width height tetris -- ) diff --git a/unmaintained/tetris/piece/authors.txt b/extra/tetris/piece/authors.txt similarity index 100% rename from unmaintained/tetris/piece/authors.txt rename to extra/tetris/piece/authors.txt diff --git a/extra/tetris/piece/piece-tests.factor b/extra/tetris/piece/piece-tests.factor new file mode 100644 index 0000000000..05e4faa68f --- /dev/null +++ b/extra/tetris/piece/piece-tests.factor @@ -0,0 +1,23 @@ +USING: accessors kernel tetris.tetromino tetris.piece tools.test sequences arrays namespaces ; + +! Tests for tetris.tetromino and tetris.piece, since there's not much to test in tetris.tetromino + +! these two tests rely on the first rotation of the first tetromino being the +! 'I' tetromino in its vertical orientation. +[ 4 ] [ tetrominoes get first states>> first blocks-width ] unit-test +[ 1 ] [ tetrominoes get first states>> first blocks-height ] unit-test + +[ { 0 0 } ] [ random-tetromino location>> ] unit-test +[ 0 ] [ 10 rotation>> ] unit-test + +[ { { 0 0 } { 1 0 } { 2 0 } { 3 0 } } ] +[ tetrominoes get first piece-blocks ] unit-test + +[ { { 0 0 } { 0 1 } { 0 2 } { 0 3 } } ] +[ tetrominoes get first 1 rotate-piece piece-blocks ] unit-test + +[ { { 1 1 } { 2 1 } { 3 1 } { 4 1 } } ] +[ tetrominoes get first { 1 1 } move-piece piece-blocks ] unit-test + +[ 3 ] [ tetrominoes get second piece-width ] unit-test +[ 2 ] [ tetrominoes get second 1 rotate-piece piece-width ] unit-test diff --git a/extra/tetris/piece/piece.factor b/extra/tetris/piece/piece.factor new file mode 100644 index 0000000000..2ebbfc07d6 --- /dev/null +++ b/extra/tetris/piece/piece.factor @@ -0,0 +1,50 @@ +! Copyright (C) 2006, 2007, 2008 Alex Chapman +! See http://factorcode.org/license.txt for BSD license. +USING: accessors arrays kernel math math.vectors sequences tetris.tetromino lists.lazy ; +IN: tetris.piece + +#! The rotation is an index into the tetromino's states array, and the +#! position is added to the tetromino's blocks to give them their location on the +#! tetris board. If the location is f then the piece is not yet on the board. + +TUPLE: piece + { tetromino tetromino } + { rotation integer initial: 0 } + { location array initial: { 0 0 } } ; + +: ( tetromino -- piece ) + piece new swap >>tetromino ; + +: (piece-blocks) ( piece -- blocks ) + #! rotates the piece + [ rotation>> ] [ tetromino>> states>> ] bi nth ; + +: piece-blocks ( piece -- blocks ) + #! rotates and positions the piece + [ (piece-blocks) ] [ location>> ] bi [ v+ ] curry map ; + +: piece-width ( piece -- width ) + piece-blocks blocks-width ; + +: set-start-location ( piece board-width -- piece ) + over piece-width [ 2 /i ] bi@ - 0 2array >>location ; + +: ( board-width -- piece ) + random-tetromino swap set-start-location ; + +: ( board-width -- llist ) + [ [ ] curry ] keep [ ] curry lazy-cons ; + +: modulo ( n m -- n ) + #! -2 7 mod => -2, -2 7 modulo => 5 + tuck mod over + swap mod ; + +: (rotate-piece) ( rotation inc n-states -- rotation' ) + [ + ] dip modulo ; + +: rotate-piece ( piece inc -- piece ) + over tetromino>> states>> length + [ (rotate-piece) ] 2curry change-rotation ; + +: move-piece ( piece move -- piece ) + [ v+ ] curry change-location ; diff --git a/unmaintained/tetris/summary.txt b/extra/tetris/summary.txt similarity index 100% rename from unmaintained/tetris/summary.txt rename to extra/tetris/summary.txt diff --git a/unmaintained/tetris/tags.txt b/extra/tetris/tags.txt similarity index 100% rename from unmaintained/tetris/tags.txt rename to extra/tetris/tags.txt diff --git a/extra/tetris/tetris.factor b/extra/tetris/tetris.factor new file mode 100644 index 0000000000..b200c4d735 --- /dev/null +++ b/extra/tetris/tetris.factor @@ -0,0 +1,56 @@ +! Copyright (C) 2006, 2007, 2008 Alex Chapman +! See http://factorcode.org/license.txt for BSD license. +USING: accessors alarms arrays calendar kernel make math math.geometry.rect math.parser namespaces sequences system tetris.game tetris.gl ui.gadgets ui.gadgets.labels ui.gadgets.worlds ui.gadgets.status-bar ui.gestures ui.render ui ; +IN: tetris + +TUPLE: tetris-gadget < gadget { tetris tetris } { alarm } ; + +: ( tetris -- gadget ) + tetris-gadget new-gadget swap >>tetris ; + +M: tetris-gadget pref-dim* drop { 200 400 } ; + +: update-status ( gadget -- ) + dup tetris>> [ + "Level: " % dup level>> # + " Score: " % score>> # + ] "" make swap show-status ; + +M: tetris-gadget draw-gadget* ( gadget -- ) + [ + dup rect-dim [ first ] [ second ] bi rot tetris>> draw-tetris + ] keep update-status ; + +: new-tetris ( gadget -- gadget ) + [ ] change-tetris ; + +tetris-gadget H{ + { T{ key-down f f "UP" } [ tetris>> rotate-right ] } + { T{ key-down f f "d" } [ tetris>> rotate-left ] } + { T{ key-down f f "f" } [ tetris>> rotate-right ] } + { T{ key-down f f "e" } [ tetris>> rotate-left ] } ! dvorak d + { T{ key-down f f "u" } [ tetris>> rotate-right ] } ! dvorak f + { T{ key-down f f "LEFT" } [ tetris>> move-left ] } + { T{ key-down f f "RIGHT" } [ tetris>> move-right ] } + { T{ key-down f f "DOWN" } [ tetris>> move-down ] } + { T{ key-down f f " " } [ tetris>> move-drop ] } + { T{ key-down f f "p" } [ tetris>> toggle-pause ] } + { T{ key-down f f "n" } [ new-tetris drop ] } +} set-gestures + +: tick ( gadget -- ) + [ tetris>> ?update ] [ relayout-1 ] bi ; + +M: tetris-gadget graft* ( gadget -- ) + [ [ tick ] curry 100 milliseconds every ] keep (>>alarm) ; + +M: tetris-gadget ungraft* ( gadget -- ) + [ cancel-alarm f ] change-alarm drop ; + +: tetris-window ( -- ) + [ + + "Tetris" open-status-window + ] with-ui ; + +MAIN: tetris-window diff --git a/unmaintained/tetris/tetromino/authors.txt b/extra/tetris/tetromino/authors.txt similarity index 100% rename from unmaintained/tetris/tetromino/authors.txt rename to extra/tetris/tetromino/authors.txt diff --git a/unmaintained/tetris/tetromino/tetromino.factor b/extra/tetris/tetromino/tetromino.factor similarity index 97% rename from unmaintained/tetris/tetromino/tetromino.factor rename to extra/tetris/tetromino/tetromino.factor index 957f808aae..7e6b2ecf34 100644 --- a/unmaintained/tetris/tetromino/tetromino.factor +++ b/extra/tetris/tetromino/tetromino.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2006, 2007 Alex Chapman +! Copyright (C) 2006, 2007, 2008 Alex Chapman ! See http://factorcode.org/license.txt for BSD license. USING: kernel arrays namespaces sequences math math.vectors colors random ; diff --git a/extra/webapps/calculator/calculator.factor b/extra/webapps/calculator/calculator.factor index f1416fb02d..d19946d39b 100644 --- a/extra/webapps/calculator/calculator.factor +++ b/extra/webapps/calculator/calculator.factor @@ -33,7 +33,7 @@ TUPLE: calculator < dispatcher ; ! Deployment example USING: db.sqlite furnace.alloy namespaces http.server ; -: calculator-db ( -- params db ) "calculator.db" sqlite-db ; +: calculator-db ( -- db ) "calculator.db" ; : run-calculator ( -- ) diff --git a/extra/webapps/counter/counter.factor b/extra/webapps/counter/counter.factor index f49d8f008e..d62096fffc 100644 --- a/extra/webapps/counter/counter.factor +++ b/extra/webapps/counter/counter.factor @@ -27,13 +27,12 @@ M: counter-app init-session* drop 0 count sset ; counter-app new-dispatcher [ 1+ ] "inc" add-responder [ 1- ] "dec" add-responder - "" add-responder - ; + "" add-responder ; ! Deployment example USING: db.sqlite furnace.alloy namespaces ; -: counter-db ( -- params db ) "counter.db" sqlite-db ; +: counter-db ( -- db ) "counter.db" ; : run-counter ( -- ) diff --git a/extra/webapps/help/help.factor b/extra/webapps/help/help.factor new file mode 100644 index 0000000000..c209fe222e --- /dev/null +++ b/extra/webapps/help/help.factor @@ -0,0 +1,38 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel accessors http.server.dispatchers +http.server.static furnace.actions furnace.redirection urls +validators locals io.files html.forms help.html ; +IN: webapps.help + +TUPLE: help-webapp < dispatcher ; + +:: ( help-dir -- action ) + + { help-webapp "search" } >>template + + [ + { + { "search" [ 1 v-min-length 50 v-max-length v-one-line ] } + } validate-params + + help-dir set-current-directory + + "search" value article-apropos "articles" set-value + "search" value word-apropos "words" set-value + "search" value vocab-apropos "vocabs" set-value + + { help-webapp "search" } + ] >>submit ; + +: ( -- action ) + + { help-webapp "help" } >>template ; + +: ( help-dir -- webapp ) + help-webapp new-dispatcher + "" add-responder + over "search" add-responder + swap "content" add-responder ; + + diff --git a/extra/webapps/help/help.xml b/extra/webapps/help/help.xml new file mode 100644 index 0000000000..7718b10a22 --- /dev/null +++ b/extra/webapps/help/help.xml @@ -0,0 +1,20 @@ + + + + + + + + Factor Documentation + + + + + + + + + + diff --git a/extra/webapps/help/search.xml b/extra/webapps/help/search.xml new file mode 100644 index 0000000000..e5fa5d3901 --- /dev/null +++ b/extra/webapps/help/search.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + +

    Factor documentation

    + +

    This is the Factor + documentation, generated offline from a + load-everything image. If you want, you can also browse the + documentation from within the Factor UI.

    + +

    You may search article titles below; for example, try searching for "HTTP".

    + + + + + + + +
    + +

    Articles

    + +
      + +
    • +
      +
    +
    + + +
    + +

    Vocabularies

    + +
      + +
    • +
      +
    +
    + + +
    + +

    Words

    + +
      + +
    • +
      +
    +
    + + + + +
    diff --git a/extra/webapps/irc-log/authors.txt b/extra/webapps/irc-log/authors.txt new file mode 100644 index 0000000000..b4bd0e7b35 --- /dev/null +++ b/extra/webapps/irc-log/authors.txt @@ -0,0 +1 @@ +Doug Coleman \ No newline at end of file diff --git a/extra/webapps/irc-log/irc-log.factor b/extra/webapps/irc-log/irc-log.factor new file mode 100644 index 0000000000..c193550719 --- /dev/null +++ b/extra/webapps/irc-log/irc-log.factor @@ -0,0 +1,22 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: calendar kernel http.server.dispatchers prettyprint +sequences printf furnace.actions html.forms accessors +furnace.redirection ; +IN: webapps.irc-log + +TUPLE: irclog-app < dispatcher ; + +: irc-link ( -- string ) + gmt -7 hours convert-timezone >date< + [ unparse 2 tail ] 2dip + "http://bespin.org/~nef/logs/concatenative/%02s.%02d.%02d" + sprintf ; + +: ( -- action ) + + [ irc-link ] >>display ; + +: ( -- dispatcher ) + irclog-app new-dispatcher + "" add-responder ; diff --git a/extra/webapps/pastebin/new-paste.xml b/extra/webapps/pastebin/new-paste.xml index 6abae4895b..96339b6cf8 100644 --- a/extra/webapps/pastebin/new-paste.xml +++ b/extra/webapps/pastebin/new-paste.xml @@ -18,6 +18,6 @@ - +

    diff --git a/extra/webapps/pastebin/paste.xml b/extra/webapps/pastebin/paste.xml index 1c138fc8c0..8fe672049f 100644 --- a/extra/webapps/pastebin/paste.xml +++ b/extra/webapps/pastebin/paste.xml @@ -20,7 +20,7 @@ -

    Annotation:

    +

    Annotation:

    @@ -52,7 +52,7 @@
    Author:
    - +

    diff --git a/extra/webapps/pastebin/pastebin-common.xml b/extra/webapps/pastebin/pastebin-common.xml index b95f3f7b64..6d524ad86f 100644 --- a/extra/webapps/pastebin/pastebin-common.xml +++ b/extra/webapps/pastebin/pastebin-common.xml @@ -8,7 +8,7 @@