: check-header-string ( str -- str )
#! http://en.wikipedia.org/wiki/HTTP_Header_Injection
- dup "\r\n\"" intersect empty?
- [ "Header injection attack" throw ] unless ;
+ dup "\r\n\"" intersects?
+ [ "Header injection attack" throw ] when ;
: write-header ( assoc -- )
>alist sort-keys [
] { } make ;
: check-cookie-string ( string -- string' )
- dup "=;'\"\r\n" intersect empty?
- [ "Bad cookie name or value" throw ] unless ;
+ dup "=;'\"\r\n" intersects?
+ [ "Bad cookie name or value" throw ] when ;
: unparse-cookie-value ( key value -- )
{
dup
[ nfa-table>> final-states>> keys ]
[ dfa-table>> transitions>> states ] bi
- [ intersect empty? not ] with filter
+ [ intersects? ] with filter
swap dfa-table>> final-states>>
[ conjoin ] curry each ;
: validate-address ( string -- string' )
#! Make sure we send funky stuff to the server by accident.
- dup "\r\n>" intersect empty?
- [ bad-email-address ] unless ;
+ dup "\r\n>" intersects?
+ [ bad-email-address ] when ;
: mail-from ( fromaddr -- )
validate-address
ERROR: invalid-header-string string ;
: validate-header ( string -- string' )
- dup "\r\n" intersect empty?
- [ invalid-header-string ] unless ;
+ dup "\r\n" intersects?
+ [ invalid-header-string ] when ;
: write-header ( key value -- )
[ validate-header write ]
: v-one-line ( str -- str )
v-required
- dup "\r\n" intersect empty?
- [ "must be a single line" throw ] unless ;
+ dup "\r\n" intersects?
+ [ "must be a single line" throw ] when ;
: v-one-word ( str -- str )
v-required
{ $subsection diff }
{ $subsection intersect }
{ $subsection union }
+"Set-theoretic predicates:"
+{ $subsection intersects? }
{ $subsection subset? }
{ $subsection set= }
"A word used to implement the above:"
{ diff intersect union } related-words
+HELP: intersects?
+{ $values { "seq1" sequence } { "seq2" sequence } { "?" "a boolean" } }
+{ $description "Tests if " { $snippet "seq1" } " and " { $snippet "seq2" } " have any elements in common." }
+{ $notes "If one of the sequences is empty, the result is always " { $link f } "." } ;
+
HELP: subset?
{ $values { "seq1" sequence } { "seq2" sequence } { "?" "a boolean" } }
-{ $description "Tests if every element of " { $snippet "seq1" } " is contained in " { $snippet "seq2" } "." } ;
+{ $description "Tests if every element of " { $snippet "seq1" } " is contained in " { $snippet "seq2" } "." }
+{ $notes "If " { $snippet "seq1" } " is empty, the result is always " { $link t } "." } ;
HELP: set=
{ $values { "seq1" sequence } { "seq2" sequence } { "?" "a boolean" } }
[ V{ 1 2 3 } ]
[ 3 V{ 1 3 2 } clone [ adjoin ] keep ] unit-test
+
+[ t ] [ { 1 2 } { 1 3 } intersects? ] unit-test
+
+[ f ] [ { 4 2 } { 1 3 } intersects? ] unit-test
+
+[ f ] [ { } { 1 } intersects? ] unit-test
+
+[ f ] [ { 1 } { } intersects? ] unit-test
-! Copyright (C) 2008 Slava Pestov, Doug Coleman.
+! Copyright (C) 2008, 2009 Slava Pestov, Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: assocs hashtables kernel sequences vectors ;
IN: sets
: all-unique? ( seq -- ? )
dup length <hashtable> [ (all-unique?) ] curry all? ;
+<PRIVATE
+
+: tester ( seq -- quot ) unique [ key? ] curry ; inline
+
+PRIVATE>
+
: intersect ( seq1 seq2 -- newseq )
- unique [ key? ] curry filter ;
+ tester filter ;
+
+: intersects? ( seq1 seq2 -- newseq )
+ tester contains? ;
: diff ( seq1 seq2 -- newseq )
- unique [ key? not ] curry filter ;
+ tester [ not ] compose filter ;
: union ( seq1 seq2 -- newseq )
append prune ;
: subset? ( seq1 seq2 -- ? )
- unique [ key? ] curry all? ;
+ tester all? ;
: set= ( seq1 seq2 -- ? )
[ unique ] bi@ = ;
: split ( seq separators -- pieces ) [ split, ] { } make ;
: string-lines ( str -- seq )
- dup "\r\n" intersect empty? [
- 1array
- ] [
+ dup "\r\n" intersects? [
"\n" split [
but-last-slice [
"\r" ?tail drop "\r" split
] map
] keep peek "\r" split suffix concat
+ ] [
+ 1array
] if ;