Location: PHPKode > projects > Pieforms > pieforms-php5-0.2.2/doc/geshi/geshi/functions.geshi.php
<?php
/**
 * GeSHi - Generic Syntax Highlighter
 * <pre>
 *   File:   geshi/functions.geshi.php
 *   Author: Nigel McNie
 *   E-mail: hide@address.com
 * </pre>
 *
 * For information on how to use GeSHi, please consult the documentation
 * found in the docs/ directory, or online at http://geshi.org/docs/
 *
 * This program is part of GeSHi.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 *
 * @package    geshi
 * @subpackage core
 * @author     Nigel McNie <hide@address.com>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL
 * @copyright  (C) 2004 - 2006 Nigel McNie
 * @version    $Id: functions.geshi.php 910 2007-02-22 00:30:59Z benbe $
 *
 */

//Ensure debugging is set to of if not explicitly told to be enabled before!
if(!defined('GESHI_DBG_ENABLE')) {
	define('GESHI_DBG_ENABLE', false);
}

if(true === GESHI_DBG_ENABLE) {
    /**
     * Handles debugging by printing a message according to current debug level,
     * mask of context and other things.
     *
     * @param string The message to print out
     * @param int The context in which this message is to be printed out in - see
     *            the GESHI_DBG_* constants
     * @param boolean Whether to add a newline to the message
     * @param boolean Whether to return the count of errors or not
     * @access private
     */
    function geshi_dbg ($message, $add_nl = true)
    {
        //
        // Message can have the following symbols at start
        //
        // @b: bold
        // @i: italic
        // @o: ok (green colour)
        // @w: warn (yellow colour)
        // @e: err (red colour)
        $test  = substr($message, 0, 2);
        $start = '';
        $end   = '</span>';
        switch ($test) {
            case '@b':
                $start = '<span style="font-weight:bold;">';
                break;

            case '@i':
                $start = '<span style="font-style:italic;">';
                break;

            case '@o':
                $start = '<span style="color:green;background-color:#efe;border:1px solid #393;">';
                break;

            case '@w':
                $start = '<span style="color:#660;background-color:#ffe;border:1px solid #993;">';
                break;

            case '@e':
                $start = '<span style="color:red;background-color:#fee;border:1px solid #933;">';
                break;

            default:
                $end = '';
        }

        if (preg_match('#(.*?)::(.*?)\((.*?)\)#si', $message)) {
            $start = '<span style="font-weight:bold;">';
            $end   = '</span>';
        }

        if (preg_match('#^@[a-z]#', $message)) {
            $message = substr($message, 2);
        }
        echo $start . GeSHi::hsc(str_replace("\n", '', $message)) . $end;
        if ($add_nl) echo "\n";
    }
} else {
    function geshi_dbg ($message, $add_nl = true)
    {
    }
}

/**
 * Checks whether a file name is able to be read by GeSHi
 *
 * The file must be within the GESHI_ROOT directory
 *
 * @param  string  The absolute pathname of the file to check
 * @return boolean Whether the file is readable by GeSHi
 * @access private
 */
function geshi_can_include ($file_name)
{
    // Check the file is in the root path
    if (GESHI_ROOT != substr($file_name, 0, strlen(GESHI_ROOT))) {
        return false;
    }

    // Check if the given file exists, is a file and is readable
    if (!(file_exists($file_name) && is_file($file_name) && is_readable($file_name))) {
        return false;
    }

    // Check if the user tries to use .. inside the path
    if (false !== strpos($file_name, '..')) {
        return false;
    }

    // Check if we need to check for symlinks and if all required functions are available
    // The availability check is due to compatibility to M$ Windows as PHP doesn't implement
    // some symlink functions there.
    $can_include = true;
    if (!GESHI_ALLOW_SYMLINK_PATHS && function_exists('is_link')) {
        do {
            // Check for filename being a file OR a directory
            $file_type = filetype($file_name);
            $can_include &= (('file' == $file_type || 'dir' == $file_type) && !is_link($file_name));

            // Change to the parent directory for next test
            $file_name = dirname($file_name);
        } while (GESHI_ROOT == substr($file_name, 0, strlen(GESHI_ROOT) && $can_include));
    }

    return (bool) $can_include;
}

/**
 * A replacement for strpos and stripos that can also handle regular expression
 * string positions.
 *
 * @param string The string in which to search for the $needle
 * @param string The string to search for. If this string starts with "REGEX"
 *               then a regular expression search is performed.
 * @param int    The offset in the string in which to start searching.  Look-
 *               behind assertions in a regex that refer to characters prior to
 *               this point will not match.
 * @param boolean Whether the search is case sensitive or not
 * @param boolean Whether the match table is needed (almost never, and it makes
 *                things slower, but probably not noticeably).
 * @return array An array of data:
 * <pre> 'pos' => position in string of needle,
 * 'len' => length of match
 * 'tab' => a tabular array containing the parenthesised sub-matches of a
 *   regular expression.  [0] is the complete match, [1] the first parenthesized
 *   sub-match, and so on.
 * </pre>
 * @access private
 */
function geshi_get_position ($haystack, $needle, $offset = 0,
  $case_sensitive = false, $need_table = false)
{
    if ('REGEX' != substr($needle, 0, 5)) {
        if (!$case_sensitive) {
            // @todo [blocking 1.1.4] This line is marked by BenBE as
            // one of the slowest. If you don't have PHP5 then this is
            // done manually, the function for it should probably be
            // cleaned up a bit.
            return array('pos' => stripos($haystack, $needle, $offset),
              'len' => strlen($needle));
        } else {
            return array('pos' => strpos($haystack, $needle, $offset),
              'len' => strlen($needle));
        }
    }

    $regex = substr($needle, 5);
    $haystack_offset = substr($haystack, $offset);
    $table = array();
    $length = 0;
    $flags = PREG_SPLIT_OFFSET_CAPTURE;
    if ($need_table) $flags |= PREG_SPLIT_DELIM_CAPTURE;
    // @todo [blocking 1.1.4]  This line is marked by BenBE as one of the
    // slowest. There's not too much that can be done to speed up the line
    // per se, but possibly something similar to the "here's a character
    // you can check to see if this is ever going to pass" might be useful.
    $splits = preg_split($regex, $haystack_offset, 2, $flags);
    if (count($splits) > 1) {
        $first = array_shift($splits);
        $last = array_pop($splits);
        $pos = strlen($first[0]);
        $length = $last[1] - $pos;
        $pos += $offset;
        if ($need_table) {
            $table[] = substr($haystack_offset, $pos, $length);
            foreach ($splits as $match) $table[] = $match[0];
        }
    } else $pos = false;
    return array('pos' => $pos, 'len' => $length, 'tab' => $table);
}

/**
 * Which, if any, of the strings in the array $substrs occurs at offset $offset
 * in the string $str?
 * If $flags contains GESHI_WHICHSS_MAXIMAL, then the largest of multiple
 * matches will be returned, otherwise and by default: the first encountered.
 * If $flags contains GESHI_WHICHSS_CASEINSENSITIVE then the comparison will be
 * case-insensitive; otherwise and by default it will be case-sensitive.
 * If $flags contains GESHI_WHICHSS_TRYREGEX then the remaining portion of any
 * string in $substrs that starts with 'REGEX' will be treated as a (Perl-
 * compatible) regular expression to match, anchored to the start of the string
 * at $offset.  Look-behind assertions that refer to parts of the string prior
 * to $offset will not work.  If $flags contains GESHI_WHICHSS_SKIPANCHORINSERT
 * then the anchor insertion on each regex in $substr will not be performed -
 * it will be assumed to have already been performed but in any case only
 * matches at the start of the string will ever be returned.
 * @return Null if no match is found, otherwise the matching substring, with
 * case as in the $substrs element rather than the matching portion of $str.
 */
define('GESHI_WHICHSS_MAXIMAL', 1);
define('GESHI_WHICHSS_CASEINSENSITIVE', 2);
define('GESHI_WHICHSS_TRYREGEX', 4);
define('GESHI_WHICHSS_SKIPANCHORINSERT', 8);
function geshi_whichsubstr($str, $substrs, $offset = 0, $flags = 0) {
    /* Constants */
    static $re_starter_c = 'REGEX';
    static $re_starter_len_c = 5/*strlen($re_starter_c)*/;

    $ret = null;
    $max_len = -1;
    foreach ($substrs as $substr) {
        if (($flags & GESHI_WHICHSS_TRYREGEX) &&
          strncmp($substr,$re_starter_c,$re_starter_len_c)==0) {
            $re = substr($substr, $re_starter_len_c);
            if (!($flags & GESHI_WHICHSS_SKIPANCHORINSERT)) {
                $re = geshi_anchor_re($re);
            }
            $haystack = $offset > 0 ? substr($str, $offset) : $str;
            $match = preg_match($re, $haystack, $matches, PREG_OFFSET_CAPTURE) ?
              $matches[0][0] : null;
            $len = strlen($match);
            /* This code is reached only if GESHI_WHICHSS_SKIPANCHORINSERT was
             * specified without a pre-existing anchor and with a match that
             * started beyond $offset.
             */
            if ($match !== null && $matches[0][1]) $len = $match = null;
        } else {
            $len = strlen($substr);
            if (!($flags & GESHI_WHICHSS_CASEINSENSITIVE)) {
                $match = substr($str,$offset,$len) == $substr ? $substr : null;
            } else if (strcasecmp(substr($str, $offset, $len), $substr) == 0) {
                $match = $substr;
            } else $match = null;
        }
        if ($match !== null) {
            if (!($flags & GESHI_WHICHSS_MAXIMAL)) {
                $ret = $match;
                break;
            } else if ($len > $max_len) {
                $ret = $match;
                $max_len = $len;
            }
        }
    }
    return $ret;
}

/**
 * Safely inserts an anchor into the regex $regex so that it only matches at the
 * start of the searched string.
 * @return string The regex with anchor inserted.
 */
function geshi_anchor_re($regex) {
    $delim = $regex{0};
    $endPos = strrpos($regex, $delim);
    $endChars = substr($regex, $endPos);
    return "$delim^(".substr($regex, 1, $endPos - 1).')'.$endChars;
}

/**
 * @todo [blocking 1.1.5] Octal/hexadecimal numbers are common, so should have functions
 *       for those, and make sure that integers/doubles do not collide
 * @access private
 */

function geshi_is_whitespace ($token)
{
    return !preg_match('/[^\s]/', $token);
}

/**
 * Replacement for stripos for php4 users
 */
if (!function_exists('stripos')) {
    function stripos ($haystack, $needle, $offset=null) {
        return strpos(strtolower($haystack), strtolower($needle), $offset);
    }
}

/**
 * Returns the GeSHi_Styler object used to help with parsing
 *
 * @param boolean $force_new If true, forces the creation of
 *                           a new GeSHi_Parser object
 * @return GeSHi_Styler
 * @access private
 */
function &geshi_styler ($force_new = false)
{
    static $styler = null;
    if (!$styler || $force_new) {
        $styler = new GeSHiStyler;
    }
    return $styler;
}

?>
Return current item: Pieforms