Rebol [
	Name: 'Patches
	Title: "Patches"
	File: %patches.r
	Author: "A J Martin"
	Owner: "Aztecnology"
	Rights: "Copyright © 2003 A J Martin, Aztecnology."
	eMail: Rebol@orcon.net.nz
	Web: http://www.rebol.it/Valley/
	Tabs: 4
	Purpose: "Various patches to Rebol."
	Language: 'English
	Date: 11/August/2003
	Version: 1.4.0
    library: [level: 'intermediate
                platform: 'all
               type: [ tool]
               domain: [patch]
               tested-under: none
               support: none
               license: none
              see-also: none
            ]
	]

; Replacement 'Extract to work with series!, and better initial length.
Extract: function [
	"Extracts every n-th value from a series."
	Series [series!]
	Width [integer!] "Size of each entry (the skip)."
	/Index "Position to extract from." N [number! logic!]
	] [New] [
	if not Index [N: 1]
	New: make Series (length? Series) / Width
	forskip Series Width [
		insert/only tail New pick Series N
		]
	New
	]

; Replacement 'Alter.
Alter: function [
	{If a value is not found in a series, append it; otherwise, remove it.}
	Series [series! port!]
	Value [any-type!]
	] [Temp] [
	either Temp: find/only :Series :Value [
		remove Temp
		] [
		insert/only tail :Series :Value
		]
	:Series
	]

; Replacement 'Append.
Append: func [
    {Appends a value to the tail of a series and returns the series.}
    Series [series! port!]
    Value [any-type!]
    /Only "Appends a block value as a block."
    ][
    head either only [
        insert/only tail :Series :Value
        ] [
        insert tail :Series :Value
        ]
    :Series
    ]

; Replacement 'Repend.
Repend: func [
	{Appends a reduced value to a series and returns the series.}
	Series [series! port!]
	Value [any-type!]
	/Only "Appends a block value as a block."
	][
	either only [
		insert/only tail :Series reduce :Value
		] [
		insert tail :Series reduce :Value
		]
	:Series
	]

; Replacement 'function that adds 'throw-on-error.
Function: func [
	"Defines a user function with local words."
	[catch]
	Spec [block!] {Optional help info followed by arg words (and optional type and string)}
	Vars [block!] "List of words that are local to the function"
    Body [block!] "The body block of the function"
    ] [
	throw-on-error [make function! head insert insert tail copy spec /local vars body]
	]

; Enhanced 'Charset function to allow 'char! values.
Charset: func [
	"Makes a bitset of chars for the parse function."
	Chars [string! block! char!]
	][
	make bitset! Chars
	]

; Needed until very latest versions of Rebol are released.
if not value? 'as-pair [
	as-pair: func [
		"Combine X and Y values into a pair."
		x [number!] y [number!]
		][
		to-pair reduce [to-integer x to-integer y]
		]
	]

; Needed until very latest versions of Rebol are released.
decode-cgi: func [
	{Converts CGI argument string to a block of set-words and value strings.}
	args [any-string!] "Starts at first argument word."
	/local block name value here tmp
	][
	block: make block! 7
	parse/all args [
		any [
			copy name [to #"=" | to #"&" | to end] skip here: (
				if tmp: find name #"&" [
					here: skip here (offset? tmp name) - 2
					clear tmp
					]
				append block to-set-word name
				) :here [
				[copy value to #"&" skip | copy value to end]
				(
					append block either none? value [copy ""] [
						replace/all dehex replace/all value #"+" #" " crlf newline
						]
					)
				]
			]
		end
		]
	block
	]

; Needed until very latest versions of Rebol are released.
array: func [
	"Makes and initializes a series of a given size."
	size [integer! block!] "Size or block of sizes for each dimension"
	/initial "Specify an initial value for all elements"
	value "Initial value"
	/local block rest
	][
	if not initial [value: none]
	if block? size [
		rest: next size
		if tail? rest [rest: none]
		size: first size
		if not integer? size [make error! "Integer size required"]
		]
	block: make block! size
	either not rest [
		either series? value [
			loop size [insert/only block copy/deep value]
			] [
			insert/dup block value size
			]
		] [
		loop size [
			if series? value [value: copy/deep value]
			block: insert/only block array/initial rest value
			]
		]
	head block
	]

; Needed until very latest versions of Rebol are released.
if not value? 'sign? [
	sign?: func [
		{Returns sign of number as 1, 0, or -1 (to use as multiplier).}
		number [number! money! time!]
		][
		either positive? number [1] [either negative? number [-1] [0]]
		]
	]

; Needed until very latest versions of Rebol are released.
if not value? 'attempt [
	attempt: func [
		{Tries to evaluate and returns result or NONE on error.}
		value [block!]
		][
		if not error? set/any 'value try value [get/any 'value]
		]
	]

; Needed until very latest versions of Rebol are released.
if not value? 'build-markup [
	build-markup: func [
		{Return markup text replacing <%tags%> with their evaluated results.}
		content [string! file! url!]
		/quiet "Do not show errors in the output."
		/local out eval value
		][
		content: either string? content [copy content] [read content]
		out: make string! 126
		eval: func [val /local tmp] [
			either error? set/any 'tmp try [do val] [
				if not quiet [
					tmp: disarm :tmp
					append out reform ["***ERROR" tmp/id "in:" val]
					]
				] [
				if not unset? get/any 'tmp [append out :tmp]
				]
			]
		parse/all content [
			any [
				end break
				| "<%" [copy value to "%>" 2 skip | copy value to end] (eval value)
				| copy value [to "<%" | to end] (append out value)
				]
			]
		out
		]
	]

; Needed until very latest versions of Rebol are released.
if not value? 'component? [
	component?: func [
		"Returns specific REBOL component info if enabled."
		name [word!]
		][
		find system/components name
		]

]