adding zend project folders into old campcaster.

This commit is contained in:
naomiaro 2010-12-07 14:19:27 -05:00
parent 56abfaf28e
commit 7ef0c18b26
4045 changed files with 1054952 additions and 0 deletions

View file

@ -0,0 +1,151 @@
<?php
/*
* $Id: DataStore.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
require_once 'phing/system/io/PhingFile.php';
require_once 'phing/system/io/FileWriter.php';
/**
* An abstract representation of file and directory pathnames.
*
* @package phing.util
* @author Michiel Rook <mrook@php.net>
* @version $Revision: 905 $
*/
class DataStore
{
private $data = array();
private $file = null;
/**
* Constructs a new data store
*
* @param PhingFile $file object pointing to the data store on disk
*/
function __construct(PhingFile $file)
{
$this->file = $file;
if ($this->file->exists())
{
$this->read();
}
}
/**
* Destructor
*/
function __destruct()
{
$this->commit();
}
/**
* Retrieves a value from the data store
*
* @param string $key the key
*
* @return mixed the value
*/
public function get($key)
{
if (!isset($this->data[$key]))
{
return null;
}
else
{
return $this->data[$key];
}
}
/**
* Adds a value to the data store
*
* @param string $key the key
* @param mixed $value the value
* @param boolean $autocommit whether to auto-commit (write)
* the data store to disk
*
* @return none
*/
public function put($key, $value, $autocommit = false)
{
$this->data[$key] = $value;
if ($autocommit)
{
$this->commit();
}
}
/**
* Commits data store to disk
*
* @return none
*/
public function commit()
{
$this->write();
}
/**
* Internal function to read data store from file
*
* @return none
*/
private function read()
{
if (!$this->file->canRead())
{
throw new BuildException("Can't read data store from '" .
$file->getPath() . "'");
}
else
{
$serializedData = $this->file->contents();
$this->data = unserialize($serializedData);
}
}
/**
* Internal function to write data store to file
*
* @return none
*/
private function write()
{
if (!$this->file->canWrite())
{
throw new BuildException("Can't write data store to '" .
$file->getPath() . "'");
}
else
{
$serializedData = serialize($this->data);
$writer = new FileWriter($this->file);
$writer->write($serializedData);
$writer->close();
}
}
};

View file

@ -0,0 +1,748 @@
<?php
/*
* $Id: DirectoryScanner.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
require_once 'phing/types/selectors/SelectorScanner.php';
include_once 'phing/util/StringHelper.php';
include_once 'phing/types/selectors/SelectorUtils.php';
/**
* Class for scanning a directory for files/directories that match a certain
* criteria.
*
* These criteria consist of a set of include and exclude patterns. With these
* patterns, you can select which files you want to have included, and which
* files you want to have excluded.
*
* The idea is simple. A given directory is recursively scanned for all files
* and directories. Each file/directory is matched against a set of include
* and exclude patterns. Only files/directories that match at least one
* pattern of the include pattern list, and don't match a pattern of the
* exclude pattern list will be placed in the list of files/directories found.
*
* When no list of include patterns is supplied, "**" will be used, which
* means that everything will be matched. When no list of exclude patterns is
* supplied, an empty list is used, such that nothing will be excluded.
*
* The pattern matching is done as follows:
* The name to be matched is split up in path segments. A path segment is the
* name of a directory or file, which is bounded by DIRECTORY_SEPARATOR
* ('/' under UNIX, '\' under Windows).
* E.g. "abc/def/ghi/xyz.php" is split up in the segments "abc", "def", "ghi"
* and "xyz.php".
* The same is done for the pattern against which should be matched.
*
* Then the segments of the name and the pattern will be matched against each
* other. When '**' is used for a path segment in the pattern, then it matches
* zero or more path segments of the name.
*
* There are special case regarding the use of DIRECTORY_SEPARATOR at
* the beginning of the pattern and the string to match:
* When a pattern starts with a DIRECTORY_SEPARATOR, the string
* to match must also start with a DIRECTORY_SEPARATOR.
* When a pattern does not start with a DIRECTORY_SEPARATOR, the
* string to match may not start with a DIRECTORY_SEPARATOR.
* When one of these rules is not obeyed, the string will not
* match.
*
* When a name path segment is matched against a pattern path segment, the
* following special characters can be used:
* '*' matches zero or more characters,
* '?' matches one character.
*
* Examples:
*
* "**\*.php" matches all .php files/dirs in a directory tree.
*
* "test\a??.php" matches all files/dirs which start with an 'a', then two
* more characters and then ".php", in a directory called test.
*
* "**" matches everything in a directory tree.
*
* "**\test\**\XYZ*" matches all files/dirs that start with "XYZ" and where
* there is a parent directory called test (e.g. "abc\test\def\ghi\XYZ123").
*
* Case sensitivity may be turned off if necessary. By default, it is
* turned on.
*
* Example of usage:
* $ds = new DirectroyScanner();
* $includes = array("**\*.php");
* $excludes = array("modules\*\**");
* $ds->SetIncludes($includes);
* $ds->SetExcludes($excludes);
* $ds->SetBasedir("test");
* $ds->SetCaseSensitive(true);
* $ds->Scan();
*
* print("FILES:");
* $files = ds->GetIncludedFiles();
* for ($i = 0; $i < count($files);$i++) {
* println("$files[$i]\n");
* }
*
* This will scan a directory called test for .php files, but excludes all
* .php files in all directories under a directory called "modules"
*
* This class is complete preg/ereg free port of the Java class
* org.apache.tools.ant.DirectoryScanner. Even functions that use preg/ereg
* internally (like split()) are not used. Only the _fast_ string functions
* and comparison operators (=== !=== etc) are used for matching and tokenizing.
*
* @author Arnout J. Kuiper, ajkuiper@wxs.nl
* @author Magesh Umasankar, umagesh@rediffmail.com
* @author Andreas Aderhold, andi@binarycloud.com
*
* @version $Revision: 905 $
* @package phing.util
*/
class DirectoryScanner implements SelectorScanner {
/** default set of excludes */
protected $DEFAULTEXCLUDES = array(
"**/*~",
"**/#*#",
"**/.#*",
"**/%*%",
"**/CVS",
"**/CVS/**",
"**/.cvsignore",
"**/SCCS",
"**/SCCS/**",
"**/vssver.scc",
"**/.svn",
"**/.svn/**",
"**/._*",
"**/.DS_Store",
);
/** The base directory which should be scanned. */
protected $basedir;
/** The patterns for the files that should be included. */
protected $includes = null;
/** The patterns for the files that should be excluded. */
protected $excludes = null;
/** Whether to expand/dereference symbolic links, default is false */
protected $expandSymbolicLinks = false;
/**
* The files that where found and matched at least one includes, and matched
* no excludes.
*/
protected $filesIncluded;
/** The files that where found and did not match any includes. Trie */
protected $filesNotIncluded;
/**
* The files that where found and matched at least one includes, and also
* matched at least one excludes. Trie object.
*/
protected $filesExcluded;
/**
* The directories that where found and matched at least one includes, and
* matched no excludes.
*/
protected $dirsIncluded;
/** The directories that where found and did not match any includes. */
protected $dirsNotIncluded;
/**
* The files that where found and matched at least one includes, and also
* matched at least one excludes.
*/
protected $dirsExcluded;
/** Have the vars holding our results been built by a slow scan? */
protected $haveSlowResults = false;
/** Should the file system be treated as a case sensitive one? */
protected $isCaseSensitive = true;
/** Selectors */
protected $selectors = null;
protected $filesDeselected;
protected $dirsDeselected;
/** if there are no deselected files */
protected $everythingIncluded = true;
/**
* Does the path match the start of this pattern up to the first "**".
* This is a static mehtod and should always be called static
*
* This is not a general purpose test and should only be used if you
* can live with false positives.
*
* pattern=**\a and str=b will yield true.
*
* @param pattern the (non-null) pattern to match against
* @param str the (non-null) string (path) to match
* @param isCaseSensitive must matches be case sensitive?
* @return boolean true if matches, otherwise false
*/
function matchPatternStart($pattern, $str, $isCaseSensitive = true) {
return SelectorUtils::matchPatternStart($pattern, $str, $isCaseSensitive);
}
/**
* Matches a path against a pattern. Static
*
* @param pattern the (non-null) pattern to match against
* @param str the (non-null) string (path) to match
* @param isCaseSensitive must a case sensitive match be done?
*
* @return true when the pattern matches against the string.
* false otherwise.
*/
function matchPath($pattern, $str, $isCaseSensitive = true) {
return SelectorUtils::matchPath($pattern, $str, $isCaseSensitive);
}
/**
* Matches a string against a pattern. The pattern contains two special
* characters:
* '*' which means zero or more characters,
* '?' which means one and only one character.
*
* @param pattern the (non-null) pattern to match against
* @param str the (non-null) string that must be matched against the
* pattern
*
* @return boolean true when the string matches against the pattern,
* false otherwise.
* @access public
*/
function match($pattern, $str, $isCaseSensitive = true) {
return SelectorUtils::match($pattern, $str, $isCaseSensitive);
}
/**
* Sets the basedir for scanning. This is the directory that is scanned
* recursively. All '/' and '\' characters are replaced by
* DIRECTORY_SEPARATOR
*
* @param basedir the (non-null) basedir for scanning
*/
function setBasedir($_basedir) {
$_basedir = str_replace('\\', DIRECTORY_SEPARATOR, $_basedir);
$_basedir = str_replace('/', DIRECTORY_SEPARATOR, $_basedir);
$this->basedir = $_basedir;
}
/**
* Gets the basedir that is used for scanning. This is the directory that
* is scanned recursively.
*
* @return the basedir that is used for scanning
*/
function getBasedir() {
return $this->basedir;
}
/**
* Sets the case sensitivity of the file system
*
* @param specifies if the filesystem is case sensitive
*/
function setCaseSensitive($_isCaseSensitive) {
$this->isCaseSensitive = ($_isCaseSensitive) ? true : false;
}
/**
* Sets the set of include patterns to use. All '/' and '\' characters are
* replaced by DIRECTORY_SEPARATOR. So the separator used need
* not match DIRECTORY_SEPARATOR.
*
* When a pattern ends with a '/' or '\', "**" is appended.
*
* @param includes list of include patterns
*/
function setIncludes($_includes = array()) {
if (empty($_includes) || is_null($_includes)) {
$this->includes = null;
} else {
for ($i = 0; $i < count($_includes); $i++) {
$pattern = null;
$pattern = str_replace('\\', DIRECTORY_SEPARATOR, $_includes[$i]);
$pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern);
if (StringHelper::endsWith(DIRECTORY_SEPARATOR, $pattern)) {
$pattern .= "**";
}
$this->includes[] = $pattern;
}
}
}
/**
* Sets the set of exclude patterns to use. All '/' and '\' characters are
* replaced by <code>File.separatorChar</code>. So the separator used need
* not match <code>File.separatorChar</code>.
*
* When a pattern ends with a '/' or '\', "**" is appended.
*
* @param excludes list of exclude patterns
*/
function setExcludes($_excludes = array()) {
if (empty($_excludes) || is_null($_excludes)) {
$this->excludes = null;
} else {
for ($i = 0; $i < count($_excludes); $i++) {
$pattern = null;
$pattern = str_replace('\\', DIRECTORY_SEPARATOR, $_excludes[$i]);
$pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern);
if (StringHelper::endsWith(DIRECTORY_SEPARATOR, $pattern)) {
$pattern .= "**";
}
$this->excludes[] = $pattern;
}
}
}
/**
* Sets whether to expand/dereference symbolic links
*
* @param expandSymbolicLinks boolean value
*/
function setExpandSymbolicLinks($expandSymbolicLinks)
{
$this->expandSymbolicLinks = $expandSymbolicLinks;
}
/**
* Scans the base directory for files that match at least one include
* pattern, and don't match any exclude patterns.
*
*/
function scan() {
if ((empty($this->basedir)) || (!@is_dir($this->basedir))) {
return false;
}
if ($this->includes === null) {
// No includes supplied, so set it to 'matches all'
$this->includes = array("**");
}
if (is_null($this->excludes)) {
$this->excludes = array();
}
$this->filesIncluded = array();
$this->filesNotIncluded = array();
$this->filesExcluded = array();
$this->dirsIncluded = array();
$this->dirsNotIncluded = array();
$this->dirsExcluded = array();
$this->dirsDeselected = array();
$this->filesDeselected = array();
if ($this->isIncluded("")) {
if (!$this->isExcluded("")) {
if ($this->isSelected("", $this->basedir)) {
$this->dirsIncluded[] = "";
} else {
$this->dirsDeselected[] = "";
}
} else {
$this->dirsExcluded[] = "";
}
} else {
$this->dirsNotIncluded[] = "";
}
$this->scandir($this->basedir, "", true);
return true;
}
/**
* Toplevel invocation for the scan.
*
* Returns immediately if a slow scan has already been requested.
*/
protected function slowScan() {
if ($this->haveSlowResults) {
return;
}
// copy trie object add CopyInto() method
$excl = $this->dirsExcluded;
$notIncl = $this->dirsNotIncluded;
for ($i=0, $_i=count($excl); $i < $_i; $i++) {
if (!$this->couldHoldIncluded($excl[$i])) {
$this->scandir($this->basedir.$excl[$i], $excl[$i].DIRECTORY_SEPARATOR, false);
}
}
for ($i=0, $_i=count($notIncl); $i < $_i; $i++) {
if (!$this->couldHoldIncluded($notIncl[$i])) {
$this->scandir($this->basedir.$notIncl[$i], $notIncl[$i].DIRECTORY_SEPARATOR, false);
}
}
$this->haveSlowResults = true;
}
/**
* Lists contens of a given directory and returns array with entries
*
* @param src String. Source path and name file to copy.
*
* @access public
* @return array directory entries
* @author Albert Lash, alash@plateauinnovation.com
*/
function listDir($_dir) {
$d = dir($_dir);
$list = array();
while(($entry = $d->read()) !== false) {
if ($entry != "." && $entry != "..") {
$list[] = $entry;
}
}
$d->close();
return $list;
}
/**
* Scans the passed dir for files and directories. Found files and
* directories are placed in their respective collections, based on the
* matching of includes and excludes. When a directory is found, it is
* scanned recursively.
*
* @param dir the directory to scan
* @param vpath the path relative to the basedir (needed to prevent
* problems with an absolute path when using dir)
*
* @access private
* @see #filesIncluded
* @see #filesNotIncluded
* @see #filesExcluded
* @see #dirsIncluded
* @see #dirsNotIncluded
* @see #dirsExcluded
*/
private function scandir($_rootdir, $_vpath, $_fast) {
if (!is_readable($_rootdir)) {
return;
}
$newfiles = self::listDir($_rootdir);
for ($i=0,$_i=count($newfiles); $i < $_i; $i++) {
$file = $_rootdir . DIRECTORY_SEPARATOR . $newfiles[$i];
$name = $_vpath . $newfiles[$i];
if (@is_link($file) && !$this->expandSymbolicLinks)
{
if ($this->isIncluded($name)) {
if (!$this->isExcluded($name)) {
if ($this->isSelected($name, $file)) {
$this->filesIncluded[] = $name;
} else {
$this->everythingIncluded = false;
$this->filesDeselected[] = $name;
}
} else {
$this->everythingIncluded = false;
$this->filesExcluded[] = $name;
}
} else {
$this->everythingIncluded = false;
$this->filesNotIncluded[] = $name;
}
}
else
if (@is_dir($file)) {
if ($this->isIncluded($name)) {
if (!$this->isExcluded($name)) {
if ($this->isSelected($name, $file)) {
$this->dirsIncluded[] = $name;
if ($_fast) {
$this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
}
} else {
$this->everythingIncluded = false;
$this->dirsDeselected[] = $name;
if ($_fast && $this->couldHoldIncluded($name)) {
$this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
}
}
} else {
$this->everythingIncluded = false;
$this->dirsExcluded[] = $name;
if ($_fast && $this->couldHoldIncluded($name)) {
$this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
}
}
} else {
$this->everythingIncluded = false;
$this->dirsNotIncluded[] = $name;
if ($_fast && $this->couldHoldIncluded($name)) {
$this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
}
}
if (!$_fast) {
$this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
}
} elseif (@is_file($file)) {
if ($this->isIncluded($name)) {
if (!$this->isExcluded($name)) {
if ($this->isSelected($name, $file)) {
$this->filesIncluded[] = $name;
} else {
$this->everythingIncluded = false;
$this->filesDeselected[] = $name;
}
} else {
$this->everythingIncluded = false;
$this->filesExcluded[] = $name;
}
} else {
$this->everythingIncluded = false;
$this->filesNotIncluded[] = $name;
}
}
}
}
/**
* Tests whether a name matches against at least one include pattern.
*
* @param name the name to match
* @return <code>true</code> when the name matches against at least one
* include pattern, <code>false</code> otherwise.
*/
protected function isIncluded($_name) {
for ($i=0, $_i=count($this->includes); $i < $_i; $i++) {
if (DirectoryScanner::matchPath($this->includes[$i], $_name, $this->isCaseSensitive)) {
return true;
}
}
return false;
}
/**
* Tests whether a name matches the start of at least one include pattern.
*
* @param name the name to match
* @return <code>true</code> when the name matches against at least one
* include pattern, <code>false</code> otherwise.
*/
protected function couldHoldIncluded($_name) {
for ($i = 0; $i < count($this->includes); $i++) {
if (DirectoryScanner::matchPatternStart($this->includes[$i], $_name, $this->isCaseSensitive)) {
return true;
}
}
return false;
}
/**
* Tests whether a name matches against at least one exclude pattern.
*
* @param name the name to match
* @return <code>true</code> when the name matches against at least one
* exclude pattern, <code>false</code> otherwise.
*/
protected function isExcluded($_name) {
for ($i = 0; $i < count($this->excludes); $i++) {
if (DirectoryScanner::matchPath($this->excludes[$i], $_name, $this->isCaseSensitive)) {
return true;
}
}
return false;
}
/**
* Get the names of the files that matched at least one of the include
* patterns, and matched none of the exclude patterns.
* The names are relative to the basedir.
*
* @return the names of the files
*/
function getIncludedFiles() {
return $this->filesIncluded;
}
/**
* Get the names of the files that matched at none of the include patterns.
* The names are relative to the basedir.
*
* @return the names of the files
*/
function getNotIncludedFiles() {
$this->slowScan();
return $this->filesNotIncluded;
}
/**
* Get the names of the files that matched at least one of the include
* patterns, an matched also at least one of the exclude patterns.
* The names are relative to the basedir.
*
* @return the names of the files
*/
function getExcludedFiles() {
$this->slowScan();
return $this->filesExcluded;
}
/**
* <p>Returns the names of the files which were selected out and
* therefore not ultimately included.</p>
*
* <p>The names are relative to the base directory. This involves
* performing a slow scan if one has not already been completed.</p>
*
* @return the names of the files which were deselected.
*
* @see #slowScan
*/
public function getDeselectedFiles() {
$this->slowScan();
return $this->filesDeselected;
}
/**
* Get the names of the directories that matched at least one of the include
* patterns, an matched none of the exclude patterns.
* The names are relative to the basedir.
*
* @return the names of the directories
*/
function getIncludedDirectories() {
return $this->dirsIncluded;
}
/**
* Get the names of the directories that matched at none of the include
* patterns.
* The names are relative to the basedir.
*
* @return the names of the directories
*/
function getNotIncludedDirectories() {
$this->slowScan();
return $this->dirsNotIncluded;
}
/**
* <p>Returns the names of the directories which were selected out and
* therefore not ultimately included.</p>
*
* <p>The names are relative to the base directory. This involves
* performing a slow scan if one has not already been completed.</p>
*
* @return the names of the directories which were deselected.
*
* @see #slowScan
*/
public function getDeselectedDirectories() {
$this->slowScan();
return $this->dirsDeselected;
}
/**
* Get the names of the directories that matched at least one of the include
* patterns, an matched also at least one of the exclude patterns.
* The names are relative to the basedir.
*
* @return the names of the directories
*/
function getExcludedDirectories() {
$this->slowScan();
return $this->dirsExcluded;
}
/**
* Adds the array with default exclusions to the current exclusions set.
*
*/
function addDefaultExcludes() {
//$excludesLength = ($this->excludes == null) ? 0 : count($this->excludes);
foreach($this->DEFAULTEXCLUDES as $pattern) {
$pattern = str_replace('\\', DIRECTORY_SEPARATOR, $pattern);
$pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern);
$this->excludes[] = $pattern;
}
}
/**
* Sets the selectors that will select the filelist.
*
* @param selectors specifies the selectors to be invoked on a scan
*/
public function setSelectors($selectors) {
$this->selectors = $selectors;
}
/**
* Returns whether or not the scanner has included all the files or
* directories it has come across so far.
*
* @return <code>true</code> if all files and directories which have
* been found so far have been included.
*/
public function isEverythingIncluded() {
return $this->everythingIncluded;
}
/**
* Tests whether a name should be selected.
*
* @param string $name The filename to check for selecting.
* @param string $file The full file path.
* @return boolean False when the selectors says that the file
* should not be selected, True otherwise.
*/
protected function isSelected($name, $file) {
if ($this->selectors !== null) {
$basedir = new PhingFile($this->basedir);
$file = new PhingFile($file);
if (!$file->canRead())
return false;
foreach($this->selectors as $selector) {
if (!$selector->isSelected($basedir, $name, $file)) {
return false;
}
}
}
return true;
}
}

View file

@ -0,0 +1,137 @@
<?php
include_once 'phing/system/io/PhingFile.php';
/**
* $Id: ExtendedFileStream.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* Extended file stream wrapper class which auto-creates directories
*
* @author Michiel Rook <michiel.rook@gmail.com>
* @version $Id: ExtendedFileStream.php 905 2010-10-05 16:28:03Z mrook $
* @package phing.util
*/
class ExtendedFileStream
{
private $fp = NULL;
static function registerStream()
{
if (!in_array("efile", stream_get_wrappers()))
{
stream_wrapper_register("efile", "ExtendedFileStream");
}
}
static function unregisterStream()
{
stream_wrapper_unregister("efile");
}
private function createDirectories($path)
{
$f = new PhingFile($path);
if (!$f->exists()) {
$f->mkdirs();
}
}
function stream_open($path, $mode, $options, &$opened_path)
{
/** Small fix for Windows */
if ($path[8] == DIRECTORY_SEPARATOR)
{
$filepath = substr($path, 7);
}
else
{
$filepath = substr($path, 8);
}
$this->createDirectories(dirname($filepath));
$this->fp = fopen($filepath, $mode);
return true;
}
function stream_close()
{
fclose($this->fp);
$this->fp = NULL;
}
function stream_read($count)
{
return fread($this->fp, $count);
}
function stream_write($data)
{
return fwrite($this->fp, $data);
}
function stream_eof()
{
return feof($this->fp);
}
function stream_tell()
{
return ftell($this->fp);
}
function stream_seek($offset, $whence)
{
return fseek($this->fp, $offset, $whence);
}
function stream_flush()
{
return fflush($this->fp);
}
function stream_stat()
{
return fstat($this->fp);
}
function unlink($path)
{
return FALSE;
}
function rename($path_from, $path_to)
{
return FALSE;
}
function mkdir($path, $mode, $options)
{
return FALSE;
}
function rmdir($path, $options)
{
return FALSE;
}
};

View file

@ -0,0 +1,298 @@
<?php
/*
* $Id: FileUtils.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
include_once 'phing/system/lang/Character.php';
include_once 'phing/util/StringHelper.php';
include_once 'phing/system/io/BufferedReader.php';
include_once 'phing/system/io/BufferedWriter.php';
include_once 'phing/filters/util/ChainReaderHelper.php';
include_once 'phing/system/io/PhingFile.php';
/**
* File utility class.
* - handles os independent stuff etc
* - mapper stuff
* - filter stuff
*
* @package phing.util
* @version $Revision: 905 $
*/
class FileUtils {
/**
* Returns a new Reader with filterchains applied. If filterchains are empty,
* simply returns passed reader.
*
* @param Reader $in Reader to modify (if appropriate).
* @param array &$filterChains filter chains to apply.
* @param Project $project
* @return Reader Assembled Reader (w/ filter chains).
*/
public static function getChainedReader(Reader $in, &$filterChains, Project $project) {
if (!empty($filterChains)) {
$crh = new ChainReaderHelper();
$crh->setBufferSize(65536); // 64k buffer, but isn't being used (yet?)
$crh->setPrimaryReader($in);
$crh->setFilterChains($filterChains);
$crh->setProject($project);
$rdr = $crh->getAssembledReader();
return $rdr;
} else {
return $in;
}
}
/**
* Copies a file using filter chains.
*
* @param PhingFile $sourceFile
* @param PhingFile $destFile
* @param boolean $overwrite
* @param boolean $preserveLastModified
* @param array $filterChains
* @param Project $project
* @param integer $mode
* @return void
*/
function copyFile(PhingFile $sourceFile, PhingFile $destFile, $overwrite = false, $preserveLastModified = true, &$filterChains = null, Project $project, $mode = 0755) {
if ($overwrite || !$destFile->exists() || $destFile->lastModified() < $sourceFile->lastModified()) {
if ($destFile->exists() && $destFile->isFile()) {
$destFile->delete();
}
// ensure that parent dir of dest file exists!
$parent = $destFile->getParentFile();
if ($parent !== null && !$parent->exists()) {
$parent->mkdirs($mode);
}
if ((is_array($filterChains)) && (!empty($filterChains))) {
$in = self::getChainedReader(new BufferedReader(new FileReader($sourceFile)), $filterChains, $project);
$out = new BufferedWriter(new FileWriter($destFile));
// New read() methods returns a big buffer.
while(-1 !== ($buffer = $in->read())) { // -1 indicates EOF
$out->write($buffer);
}
if ( $in !== null )
$in->close();
if ( $out !== null )
$out->close();
$destFile->setMode($sourceFile->getMode());
} else {
// simple copy (no filtering)
$sourceFile->copyTo($destFile);
}
if ($preserveLastModified) {
$destFile->setLastModified($sourceFile->lastModified());
}
}
}
/**
* Interpret the filename as a file relative to the given file -
* unless the filename already represents an absolute filename.
*
* @param $file the "reference" file for relative paths. This
* instance must be an absolute file and must not contain
* ./ or ../ sequences (same for \ instead of /).
* @param $filename a file name
*
* @return PhingFile A PhingFile object pointing to an absolute file that doesn't contain ./ or ../ sequences
* and uses the correct separator for the current platform.
*/
function resolveFile($file, $filename) {
// remove this and use the static class constant File::seperator
// as soon as ZE2 is ready
$fs = FileSystem::getFileSystem();
$filename = str_replace('/', $fs->getSeparator(), str_replace('\\', $fs->getSeparator(), $filename));
// deal with absolute files
if (StringHelper::startsWith($fs->getSeparator(), $filename) ||
(strlen($filename) >= 2 && Character::isLetter($filename{0}) && $filename{1} === ':')) {
return new PhingFile($this->normalize($filename));
}
if (strlen($filename) >= 2 && Character::isLetter($filename{0}) && $filename{1} === ':') {
return new PhingFile($this->normalize($filename));
}
$helpFile = new PhingFile($file->getAbsolutePath());
$tok = strtok($filename, $fs->getSeparator());
while ($tok !== false) {
$part = $tok;
if ($part === '..') {
$parentFile = $helpFile->getParent();
if ($parentFile === null) {
$msg = "The file or path you specified ($filename) is invalid relative to ".$file->getPath();
throw new IOException($msg);
}
$helpFile = new PhingFile($parentFile);
} else if ($part === '.') {
// Do nothing here
} else {
$helpFile = new PhingFile($helpFile, $part);
}
$tok = strtok($fs->getSeparator());
}
return new PhingFile($helpFile->getAbsolutePath());
}
/**
* Normalize the given absolute path.
*
* This includes:
* - Uppercase the drive letter if there is one.
* - Remove redundant slashes after the drive spec.
* - resolve all ./, .\, ../ and ..\ sequences.
* - DOS style paths that start with a drive letter will have
* \ as the separator.
* @param string $path Path to normalize.
* @return string
*/
function normalize($path) {
$path = (string) $path;
$orig = $path;
$path = str_replace('/', DIRECTORY_SEPARATOR, str_replace('\\', DIRECTORY_SEPARATOR, $path));
// make sure we are dealing with an absolute path
if (!StringHelper::startsWith(DIRECTORY_SEPARATOR, $path)
&& !(strlen($path) >= 2 && Character::isLetter($path{0}) && $path{1} === ':')) {
throw new IOException("$path is not an absolute path");
}
$dosWithDrive = false;
$root = null;
// Eliminate consecutive slashes after the drive spec
if (strlen($path) >= 2 && Character::isLetter($path{0}) && $path{1} === ':') {
$dosWithDrive = true;
$ca = str_replace('/', '\\', $path);
$ca = StringHelper::toCharArray($ca);
$path = strtoupper($ca[0]).':';
for ($i=2, $_i=count($ca); $i < $_i; $i++) {
if (($ca[$i] !== '\\') ||
($ca[$i] === '\\' && $ca[$i - 1] !== '\\')
) {
$path .= $ca[$i];
}
}
$path = str_replace('\\', DIRECTORY_SEPARATOR, $path);
if (strlen($path) == 2) {
$root = $path;
$path = "";
} else {
$root = substr($path, 0, 3);
$path = substr($path, 3);
}
} else {
if (strlen($path) == 1) {
$root = DIRECTORY_SEPARATOR;
$path = "";
} else if ($path{1} == DIRECTORY_SEPARATOR) {
// UNC drive
$root = DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR;
$path = substr($path, 2);
}
else {
$root = DIRECTORY_SEPARATOR;
$path = substr($path, 1);
}
}
$s = array();
array_push($s, $root);
$tok = strtok($path, DIRECTORY_SEPARATOR);
while ($tok !== false) {
$thisToken = $tok;
if ("." === $thisToken) {
$tok = strtok(DIRECTORY_SEPARATOR);
continue;
} elseif (".." === $thisToken) {
if (count($s) < 2) {
// using '..' in path that is too short
throw new IOException("Cannot resolve path: $orig");
} else {
array_pop($s);
}
} else { // plain component
array_push($s, $thisToken);
}
$tok = strtok(DIRECTORY_SEPARATOR);
}
$sb = "";
for ($i=0,$_i=count($s); $i < $_i; $i++) {
if ($i > 1) {
// not before the filesystem root and not after it, since root
// already contains one
$sb .= DIRECTORY_SEPARATOR;
}
$sb .= (string) $s[$i];
}
$path = (string) $sb;
if ($dosWithDrive === true) {
$path = str_replace('/', '\\', $path);
}
return $path;
}
/**
* @return boolean Whether contents of two files is the same.
*/
public function contentEquals(PhingFile $file1, PhingFile $file2) {
if (!($file1->exists() || $file2->exists())) {
return false;
}
if (!($file1->canRead() || $file2->canRead())) {
return false;
}
$c1 = file_get_contents($file1->getAbsolutePath());
$c2 = file_get_contents($file2->getAbsolutePath());
return trim($c1) == trim($c2);
}
}

View file

@ -0,0 +1,95 @@
<?php
/**
* $Id: LogWriter.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
require_once 'phing/system/io/Writer.php';
require_once 'phing/Task.php';
/**
* Extends the Writer class to output messages to Phing's log
*
* @author Michiel Rook <michiel.rook@gmail.com>
* @version $Id: LogWriter.php 905 2010-10-05 16:28:03Z mrook $
* @package phing.util
*/
class LogWriter extends Writer
{
private $task = NULL;
private $level = NULL;
/**
* Constructs a new LogWriter object
*/
function __construct(Task $task, $level = Project::MSG_INFO)
{
$this->task = $task;
$this->level = $level;
}
/**
* @see Writer::write()
*/
function write($buf, $off = null, $len = null)
{
$lines = explode("\n", $buf);
foreach ($lines as $line)
{
if ($line == "")
{
continue;
}
$this->task->log($line, $this->level);
}
}
/**
* @see Writer::reset()
*/
function reset()
{
}
/**
* @see Writer::close()
*/
function close()
{
}
/**
* @see Writer::open()
*/
function open()
{
}
/**
* @see Writer::getResource()
*/
function getResource()
{
return $this->task;
}
}

View file

@ -0,0 +1,245 @@
<?php
/*
* $Id: PathTokenizer.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
include_once 'phing/util/StringHelper.php';
/**
* A Path tokenizer takes a path and returns the components that make up
* that path.
*
* The path can use path separators of either ':' or ';' and file separators
* of either '/' or '\'.
*
* @author Hans Lellelid <hans@xmpl.org> (Phing)
* @author Conor MacNeill (Ant)
* @author Jeff Tulley <jtulley@novell.com> (Ant)
* @package phing.util
*/
class PathTokenizer {
/**
* A array of tokens, created by preg_split().
*/
private $tokens = array();
/**
* A string which stores any path components which have been read ahead
* due to DOS filesystem compensation.
* @var string
*/
private $lookahead;
/**
* Flag to indicate whether or not we are running on a platform with a
* DOS style filesystem
* @var boolean
*/
private $dosStyleFilesystem;
/**
* Constructs a path tokenizer for the specified path.
*
* @param path The path to tokenize. Must not be <code>null</code>.
*/
public function __construct($path) {
// on Windows and Unix, we can ignore delimiters and still have
// enough information to tokenize correctly.
$this->tokens = preg_split("/[;:]/", $path, -1, PREG_SPLIT_NO_EMPTY);
$this->dosStyleFilesystem = ( PATH_SEPARATOR == ';');
}
/**
* Tests if there are more path elements available from this tokenizer's
* path. If this method returns <code>true</code>, then a subsequent call
* to nextToken will successfully return a token.
*
* @return <code>true</code> if and only if there is at least one token
* in the string after the current position; <code>false</code> otherwise.
*/
public function hasMoreTokens() {
if ($this->lookahead !== null) {
return true;
}
return !empty($this->tokens);
}
/**
* Returns the next path element from this tokenizer.
*
* @return the next path element from this tokenizer.
*
* @throws Exception if there are no more elements in this tokenizer's path.
*/
public function nextToken() {
if ($this->lookahead !== null) {
$token = $this->lookahead;
$this->lookahead = null;
} else {
$token = trim(array_shift($this->tokens));
}
if (strlen($token) === 1 && Character::isLetter($token{0})
&& $this->dosStyleFilesystem
&& !empty($this->tokens)) {
// we are on a dos style system so this path could be a drive
// spec. We look at the next token
$nextToken = trim(array_shift($this->tokens));
if (StringHelper::startsWith('\\', $nextToken) || StringHelper::startsWith('/', $nextToken)) {
// we know we are on a DOS style platform and the next path
// starts with a slash or backslash, so we know this is a
// drive spec
$token .= ':' . $nextToken;
} else {
// store the token just read for next time
$this->lookahead = $nextToken;
}
}
return $token;
}
/**
* Non StringTokenizer function, that indicates whether the specified path is contained in loaded tokens.
* We can do this easily because in PHP implimentation we're using arrays.
* @param string $path path to search for.
* @return boolean
*/
public function contains($path) {
return in_array($path, $this->tokens, true);
}
}

View file

@ -0,0 +1,159 @@
<?php
/*
* $Id: SourceFileScanner.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* Utility class that collects the functionality of the various
* scanDir methods that have been scattered in several tasks before.
*
* The only method returns an array of source files. The array is a
* subset of the files given as a parameter and holds only those that
* are newer than their corresponding target files.
* @package phing.util
*/
class SourceFileScanner {
/** Instance of FileUtils */
private $fileUtils;
/** Task this class is working for -- for logging purposes. */
private $task;
/**
* @param task The task we should log messages through
*/
function __construct($task) {
$this->task = $task;
$this->fileUtils = new FileUtils();
}
/**
* Restrict the given set of files to those that are newer than
* their corresponding target files.
*
* @param files the original set of files
* @param srcDir all files are relative to this directory
* @param destDir target files live here. if null file names
* returned by the mapper are assumed to be absolute.
* @param FilenameMapper knows how to construct a target file names from
* source file names.
* @param force Boolean that determines if the files should be
* forced to be copied.
*/
function restrict(&$files, $srcDir, $destDir, $mapper, $force = false) {
$now = time();
$targetList = "";
/*
If we're on Windows, we have to munge the time up to 2 secs to
be able to check file modification times.
(Windows has a max resolution of two secs for modification times)
*/
$osname = strtolower(Phing::getProperty('os.name'));
// indexOf()
$index = ((($res = strpos($osname, 'win')) === false) ? -1 : $res);
if ($index >= 0 ) {
$now += 2000;
}
$v = array();
for ($i=0, $size=count($files); $i < $size; $i++) {
$targets = $mapper->main($files[$i]);
if (empty($targets)) {
$this->task->log($files[$i]." skipped - don't know how to handle it", Project::MSG_VERBOSE);
continue;
}
$src = null;
try {
if ($srcDir === null) {
$src = new PhingFile($files[$i]);
} else {
$src = $this->fileUtils->resolveFile($srcDir, $files[$i]);
}
if ($src->lastModified() > $now) {
$this->task->log("Warning: ".$files[$i]." modified in the future (".$src->lastModified()." > ".$now.")", Project::MSG_WARN);
}
} catch (IOException $ioe) {
$this->task->log("Unable to read file ".$files[$i]." (skipping): " . $ioe->getMessage());
continue;
}
$added = false;
$targetList = "";
for ($j=0,$_j=count($targets); (!$added && $j < $_j); $j++) {
$dest = null;
if ($destDir === null) {
$dest = new PhingFile($targets[$j]);
} else {
$dest = $this->fileUtils->resolveFile($destDir, $targets[$j]);
}
if (!$dest->exists()) {
$this->task->log($files[$i]." added as " . $dest->__toString() . " doesn't exist.", Project::MSG_VERBOSE);
$v[] =$files[$i];
$added = true;
} elseif ($src->lastModified() > $dest->lastModified()) {
$this->task->log($files[$i]." added as " . $dest->__toString() . " is outdated.", Project::MSG_VERBOSE );
$v[]=$files[$i];
$added = true;
} elseif ($force === true) {
$this->task->log($files[$i]." added as " . $dest->__toString() . " is forced to be overwritten.", Project::MSG_VERBOSE );
$v[]=$files[$i];
$added = true;
} else {
if (strlen($targetList) > 0) {
$targetList .= ", ";
}
$targetList .= $dest->getAbsolutePath();
}
}
if (!$added) {
$this->task->log($files[$i]." omitted as ".$targetList." ".(count($targets) === 1 ? " is " : " are ")."up to date.", Project::MSG_VERBOSE);
}
}
$result = array();
$result = $v;
return $result;
}
/**
* Convenience layer on top of restrict that returns the source
* files as PhingFile objects (containing absolute paths if srcDir is
* absolute).
*/
function restrictAsFiles(&$files, &$srcDir, &$destDir, &$mapper) {
$res = $this->restrict($files, $srcDir, $destDir, $mapper);
$result = array();
for ($i=0; $i<count($res); $i++) {
$result[$i] = new PhingFile($srcDir, $res[$i]);
}
return $result;
}
}

View file

@ -0,0 +1,208 @@
<?php
/**
* String helper utility class.
*
* This class includes some Java-like functions for parsing strings,
* as well as some functions for getting qualifiers / unqualifying phing-style
* classpaths. (e.g. "phing.util.StringHelper").
*
* @author Hans Lellelid <hans@xmpl.org>
* @package phing.system.util
*/
class StringHelper {
private static $TRUE_VALUES = array("on", "true", "t", "yes");
private static $FALSE_VALUES = array("off", "false", "f", "no");
/**
* Replaces identifier tokens with corresponding text values in passed string.
*
* @params array $strings Array of strings to multiply. (If string is passed, will convert to array)
* @params array $tokens The tokens to search for.
* @params array $replacements The values with which to replace found tokens.
* @return string
*/
public static function multiply($strings, $tokens, $replacements) {
$strings = (array) $strings;
$results = array();
foreach ($strings as $string) {
$results[] = str_replace($tokens, $replacements, $string);
}
return $results;
}
/**
* Remove qualification to name.
* E.g. eg.Cat -> Cat
* @param string $qualifiedName
* @param string $separator Character used to separate.
*/
public static function unqualify($qualifiedName, $separator = '.') {
// if false, then will be 0
$pos = strrpos($qualifiedName, $separator);
if ($pos === false) {
return $qualifiedName; // there is no '.' in the qualifed name
} else {
return substr($qualifiedName, $pos + 1); // start just after '.'
}
}
/**
* Converts a string to an indexed array of chars
* There's really no reason for this to be used in PHP, since strings
* are all accessible using the $string{0} notation.
* @param string $string
* @return array
* @deprecated
*/
public static function toCharArray($str) {
$ret=array();
$len=strlen($str);
for ($i=0; $i < $len; $i++) {
$ret[] = $str{$i};
}
return $ret;
}
/**
* Get the qualifier part of a qualified name.
* E.g. eg.Cat -> eg
* @return string
*/
public static function qualifier($qualifiedName, $seperator = '.') {
$pos = strrchr($qualifiedName, $seperator);
if ($pos === false) {
return '';
} else {
return substr($qualifiedName, 0, $pos);
}
}
/**
* @param array $columns String[]
* @param string $prefix
* @return array String[]
*/
public static function prefix( $columns, $prefix) {
if ($prefix == null) return $columns;
$qualified = array();
foreach($columns as $key => $column) {
$qualified[$key] = $prefix . $column;
}
return $qualified;
}
/**
*
* @return string
*/
public static function root($qualifiedName, $separator = '.') {
$loc = strpos($qualifiedName, $separator);
return ($loc === false) ? $qualifiedName : substr($qualifiedName, 0, $loc);
}
/**
* @return int
*/
public static function hashCode($string) {
return crc32($string);
}
/**
* @return boolean
*/
public static function booleanValue($s) {
if (is_bool($s)) {
return $s; // it's already boolean (not a string)
}
// otherwise assume it's something like "true" or "t"
$trimmed = strtolower(trim($s));
return (boolean) in_array($trimmed, self::$TRUE_VALUES);
}
/** tests if a string is a representative of a boolean */
public static function isBoolean($s) {
if (is_bool($s)) {
return true; // it already is boolean
}
if ($s === "" || $s === null || !is_string($s)) {
return false; // not a valid string for testing
}
$test = trim(strtolower($s));
return (boolean) in_array($test, array_merge(self::$FALSE_VALUES, self::$TRUE_VALUES));
}
/**
* Creates a key based on any number of passed params.
* @return string
*/
public static function key() {
$args = func_get_args();
return serialize($args);
}
/** tests if a string starts with a given string */
public static function startsWith($check, $string) {
if ($check === "" || $check === $string) {
return true;
} else {
return (strpos($string, $check) === 0) ? true : false;
}
}
/** tests if a string ends with a given string */
public static function endsWith($check, $string) {
if ($check === "" || $check === $string) {
return true;
} else {
return (strpos(strrev($string), strrev($check)) === 0) ? true : false;
}
}
/**
* a natural way of getting a subtring, php's circular string buffer and strange
* return values suck if you want to program strict as of C or friends
*/
public static function substring($string, $startpos, $endpos = -1) {
$len = strlen($string);
$endpos = (int) (($endpos === -1) ? $len-1 : $endpos);
if ($startpos > $len-1 || $startpos < 0) {
trigger_error("substring(), Startindex out of bounds must be 0<n<$len", E_USER_ERROR);
}
if ($endpos > $len-1 || $endpos < $startpos) {
trigger_error("substring(), Endindex out of bounds must be $startpos<n<".($len-1), E_USER_ERROR);
}
if ($startpos === $endpos) {
return (string) $string{$startpos};
} else {
$len = $endpos-$startpos;
}
return substr($string, $startpos, $len+1);
}
/**
* Does the value correspond to a slot variable?
* @param string $value
*/
public static function isSlotVar($value) {
$value = trim($value);
if ($value === "") return false;
return preg_match('/^%\{([\w\.\-]+)\}$/', $value);
}
/**
* Extracts the variable name for a slot var in the format %{task.current_file}
* @param string $var The var from build file.
* @return string Extracted name part.
*/
public static function slotVar($var) {
return trim($var, '%{} ');
}
}

View file

@ -0,0 +1,167 @@
<?php
/*
* $Id: PregEngine.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
require_once 'phing/util/regexp/RegexpEngine.php';
/**
* PREG Regexp Engine.
* Implements a regexp engine using PHP's preg_match(), preg_match_all(), and preg_replace() functions.
*
* @author hans lellelid, hans@velum.net
* @package phing.util.regex
*/
class PregEngine implements RegexpEngine {
/**
* Set to null by default to distinguish between false and not set
* @var boolean
*/
private $ignoreCase = null;
/**
* Set to null by default to distinguish between false and not set
* @var boolean
*/
private $multiline = null;
/**
* Pattern modifiers
* @link http://php.net/manual/en/reference.pcre.pattern.modifiers.php
* @var string
*/
private $modifiers = null;
/**
* Sets pattern modifiers for regex engine
*
* @param string $mods Modifiers to be applied to a given regex
* @return void
*/
public function setModifiers($mods) {
$this->modifiers = (string)$mods;
}
/**
* Gets pattern modifiers.
* @return string
*/
public function getModifiers() {
$mods = $this->modifiers;
if($this->getIgnoreCase()) {
$mods .= 'i';
} elseif($this->getIgnoreCase() === false) {
$mods = str_replace('i', '', $mods);
}
if($this->getMultiline()) {
$mods .= 's';
} elseif($this->getMultiline() === false) {
$mods = str_replace('s', '', $mods);
}
// filter out duplicates
$mods = preg_split('//', $mods, -1, PREG_SPLIT_NO_EMPTY);
$mods = implode('', array_unique($mods));
return $mods;
}
/**
* Sets whether or not regex operation is case sensitive.
* @param boolean $bit
* @return void
*/
function setIgnoreCase($bit) {
$this->ignoreCase = (boolean) $bit;
}
/**
* Gets whether or not regex operation is case sensitive.
* @return boolean
*/
function getIgnoreCase() {
return $this->ignoreCase;
}
/**
* Sets whether regexp should be applied in multiline mode.
* @param boolean $bit
*/
function setMultiline($bit) {
$this->multiline = $bit;
}
/**
* Gets whether regexp is to be applied in multiline mode.
* @return boolean
*/
function getMultiline() {
return $this->multiline;
}
/**
* The pattern needs to be converted into PREG style -- which includes adding expression delims & any flags, etc.
* @param string $pattern
* @return string prepared pattern.
*/
private function preparePattern($pattern)
{
// Use backquotes since hardly ever found in a regexp pattern, avoids using preg_quote
return '`'.$pattern.'`' . $this->getModifiers();
}
/**
* Matches pattern against source string and sets the matches array.
* @param string $pattern The regex pattern to match.
* @param string $source The source string.
* @param array $matches The array in which to store matches.
* @return boolean Success of matching operation.
*/
function match($pattern, $source, &$matches) {
return preg_match($this->preparePattern($pattern), $source, $matches);
}
/**
* Matches all patterns in source string and sets the matches array.
* @param string $pattern The regex pattern to match.
* @param string $source The source string.
* @param array $matches The array in which to store matches.
* @return boolean Success of matching operation.
*/
function matchAll($pattern, $source, &$matches) {
return preg_match_all($this->preparePattern($pattern), $source, $matches);
}
/**
* Replaces $pattern with $replace in $source string.
* References to \1 group matches will be replaced with more preg-friendly
* $1.
* @param string $pattern The regex pattern to match.
* @param string $replace The string with which to replace matches.
* @param string $source The source string.
* @return string The replaced source string.
*/
function replace($pattern, $replace, $source) {
// convert \1 -> $1, because we want to use the more generic \1 in the XML
// but PREG prefers $1 syntax.
$replace = preg_replace('/\\\(\d+)/', '\$$1', $replace);
return preg_replace($this->preparePattern($pattern), $replace, $source);
}
}

View file

@ -0,0 +1,204 @@
<?php
/*
* $Id: Regexp.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* A factory class for regex functions.
* @author Hans Lellelid <hans@xmpl.org>
* @package phing.util.regexp
* @version $Revision: 905 $
*/
class Regexp {
/**
* Matching groups found.
* @var array
*/
private $groups = array();
/**
* Pattern to match.
* @var string
*/
private $pattern;
/**
* Replacement pattern.
* @var string
*/
private $replace;
/**
* The regex engine -- e.g. 'preg' or 'ereg';
* @var RegexpEngine
*/
private $engine;
/**
* Constructor sets the regex engine to use (preg by default).
* @param string $_engineType The regex engine to use.
*/
function __construct($engineType='preg') {
if ($engineType == 'preg') {
include_once 'phing/util/regexp/PregEngine.php';
$this->engine = new PregEngine();
} elseif ($engineType == 'ereg') {
include_once 'phing/util/regexp/EregEngine.php';
$this->engine = new EregEngine();
} else {
throw new BuildException("Invalid engine type for Regexp: " . $engineType);
}
}
/**
* Sets pattern to use for matching.
* @param string $pat The pattern to match on.
* @return void
*/
public function setPattern($pat) {
$this->pattern = (string) $pat;
}
/**
* Gets pattern to use for matching.
* @return string The pattern to match on.
*/
public function getPattern() {
return $this->pattern;
}
/**
* Sets replacement string.
* @param string $rep The pattern to replace matches with.
* @return void
*/
public function setReplace($rep) {
$this->replace = (string) $rep;
}
/**
* Gets replacement string.
* @return string The pattern to replace matches with.
* @return void
*/
public function getReplace() {
return $this->replace;
}
/**
* Performs match of specified pattern against $subject.
* @param string $subject The subject, on which to perform matches.
* @return boolean Whether or not pattern matches subject string passed.
*/
public function matches($subject) {
if($this->pattern === null) {
throw new Exception("No pattern specified for regexp match().");
}
return $this->engine->match($this->pattern, $subject, $this->groups);
}
/**
* Performs replacement of specified pattern and replacement strings.
* @param string $subject Text on which to perform replacement.
* @return string subject after replacement has been performed.
*/
public function replace($subject) {
if ($this->pattern === null || $this->replace === null) {
throw new Exception("Missing pattern or replacement string regexp replace().");
}
return $this->engine->replace($this->pattern, $this->replace, $subject);
}
/**
* Get array of matched groups.
* @return array Matched groups
*/
function getGroups() {
return $this->groups;
}
/**
* Get specific matched group.
* @param integer $idx
* @return string specified group or NULL if group is not set.
*/
function getGroup($idx) {
if (!isset($this->groups[$idx])) {
return null;
}
return $this->groups[$idx];
}
/**
* Sets pattern modifiers for regex engine
*
* @param string $mods Modifiers to be applied to a given regex
* @return void
*/
public function setModifiers($mods) {
$this->engine->setModifiers($mods);
}
/**
* Gets pattern modifiers.
* Subsequent call to engines getModifiers() filters out duplicates
* i.e. if i is provided in $mods, and setIgnoreCase(true), "i"
* modifier would be included only once
* @return string
*/
public function getModifiers() {
return $this->engine->getModifiers();
}
/**
* Sets whether the regexp matching is case insensitive.
* (default is false -- i.e. case sensisitive)
* @param boolean $bit
*/
function setIgnoreCase($bit) {
$this->engine->setIgnoreCase($bit);
}
/**
* Gets whether the regexp matching is case insensitive.
* @return boolean
*/
function getIgnoreCase() {
return $this->engine->getIgnoreCase();
}
/**
* Sets whether regexp should be applied in multiline mode.
* @param boolean $bit
*/
function setMultiline($bit) {
$this->engine->setMultiline($bit);
}
/**
* Gets whether regexp is to be applied in multiline mode.
* @return boolean
*/
function getMultiline() {
return $this->engine->getMultiline();
}
}

View file

@ -0,0 +1,73 @@
<?php
/*
* $Id: RegexpEngine.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* Contains some shared attributes and methods -- and some abstract methods with
* engine-specific implementations that sub-classes must override.
*
* @author Hans Lellelid <hans@velum.net>
* @package phing.util.regex
* @version $Revision: 905 $
*/
interface RegexpEngine {
/**
* Sets whether or not regex operation should ingore case.
* @param boolean $bit
* @return void
*/
public function setIgnoreCase($bit);
/**
* Returns status of ignore case flag.
* @return boolean
*/
public function getIgnoreCase();
/**
* Matches pattern against source string and sets the matches array.
* @param string $pattern The regex pattern to match.
* @param string $source The source string.
* @param array $matches The array in which to store matches.
* @return boolean Success of matching operation.
*/
function match($pattern, $source, &$matches);
/**
* Matches all patterns in source string and sets the matches array.
* @param string $pattern The regex pattern to match.
* @param string $source The source string.
* @param array $matches The array in which to store matches.
* @return boolean Success of matching operation.
*/
function matchAll($pattern, $source, &$matches);
/**
* Replaces $pattern with $replace in $source string.
* @param string $pattern The regex pattern to match.
* @param string $replace The string with which to replace matches.
* @param string $source The source string.
* @return string The replaced source string.
*/
function replace($pattern, $replace, $source);
}