PHP_CompatInfo
[ class tree: PHP_CompatInfo ] [ index: PHP_CompatInfo ] [ all elements ]

Source for file Cli.php

Documentation is available at Cli.php

  1. <?php
  2. /**
  3.  * Copyright (c) 2004-2008, Davey Shafik <davey@php.net>
  4.  *                          Laurent Laville <pear@laurent-laville.org>
  5.  *
  6.  * All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  *
  12.  *     * Redistributions of source code must retain the above copyright
  13.  *       notice, this list of conditions and the following disclaimer.
  14.  *     * Redistributions in binary form must reproduce the above copyright
  15.  *       notice, this list of conditions and the following disclaimer in the
  16.  *       documentation and/or other materials provided with the distribution.
  17.  *     * Neither the name of the authors nor the names of its contributors
  18.  *       may be used to endorse or promote products derived from this software
  19.  *       without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  22.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
  25.  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  26.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  27.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  28.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  29.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  30.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  31.  * POSSIBILITY OF SUCH DAMAGE.
  32.  *
  33.  * PHP versions 4 and 5
  34.  *
  35.  * @category PHP
  36.  * @package  PHP_CompatInfo
  37.  * @author   Davey Shafik <davey@php.net>
  38.  * @author   Laurent Laville <pear@laurent-laville.org>
  39.  * @license  http://www.opensource.org/licenses/bsd-license.php  BSD
  40.  * @version  CVS: $Id: Cli.php,v 1.74 2008/07/22 20:26:19 farell Exp $
  41.  * @link     http://pear.php.net/package/PHP_CompatInfo
  42.  * @since    File available since Release 0.8.0
  43.  */
  44.  
  45. require_once 'PHP/CompatInfo.php';
  46. require_once 'Console/Getargs.php';
  47.  
  48. /**
  49.  * CLI Script to Check Compatibility of chunk of PHP code
  50.  *
  51.  * <code>
  52.  * <?php
  53.  *     require_once 'PHP/CompatInfo/Cli.php';
  54.  *     $cli = new PHP_CompatInfo_Cli();
  55.  *     $cli->run();
  56.  * ?>
  57.  * </code>
  58.  *
  59.  * @category  PHP
  60.  * @package   PHP_CompatInfo
  61.  * @author    Davey Shafik <davey@php.net>
  62.  * @author    Laurent Laville <pear@laurent-laville.org>
  63.  * @copyright 2003 Davey Shafik and Synaptic Media. All Rights Reserved.
  64.  * @license   http://www.opensource.org/licenses/bsd-license.php  BSD
  65.  * @version   Release: 1.9.0b1
  66.  * @link      http://pear.php.net/package/PHP_CompatInfo
  67.  * @since     Class available since Release 0.8.0
  68.  */
  69.  
  70. {
  71.     /**
  72.      * @var    array    Current CLI Flags
  73.      * @since  0.8.0
  74.      */
  75.     var $opts = array();
  76.  
  77.     /**
  78.      * Unified data source reference
  79.      *
  80.      * @var    string   Directory, File or String to be processed
  81.      * @since  1.8.0b3
  82.      */
  83.     var $dataSource;
  84.  
  85.     /**
  86.      * @var    array    Current parser options
  87.      * @since  1.4.0
  88.      */
  89.     var $options = array();
  90.  
  91.  
  92.     /**
  93.      * Command-Line Class constructor
  94.      *
  95.      * Command-Line Class constructor (ZE2) for PHP5+
  96.      *
  97.      * @since  version 0.8.0 (2004-04-22)
  98.      */
  99.     function __construct()
  100.     {
  101.         $this->opts = array(
  102.             'dir' =>
  103.                 array('short' => 'd',
  104.                       'desc'  => 'Parse DIR to get its compatibility info',
  105.                       'default' => '',
  106.                       'min'   => 0 'max' => 1),
  107.             'file' =>
  108.                 array('short' => 'f',
  109.                       'desc' => 'Parse FILE to get its compatibility info',
  110.                       'default' => '',
  111.                       'min'   => 0 'max' => 1),
  112.             'string' =>
  113.                 array('short' => 's',
  114.                       'desc' => 'Parse STRING to get its compatibility info',
  115.                       'default' => '',
  116.                       'min'   => 0 'max' => 1),
  117.             'verbose' =>
  118.                 array('short'   => 'v',
  119.                       'desc'    => 'Set the verbose level',
  120.                       'default' => 1,
  121.                       'min'     => 0 'max' => 1),
  122.             'no-recurse' =>
  123.                 array('short' => 'n',
  124.                       'desc'  => 'Do not recursively parse files when using --dir',
  125.                       'max'   => 0),
  126.             'ignore-files' =>
  127.                 array('short'   => 'if',
  128.                       'desc'    => 'Data file name which contains a list of '
  129.                                  . 'file to ignore',
  130.                       'default' => 'files.txt',
  131.                       'min'     => 0 'max' => 1),
  132.             'ignore-dirs' =>
  133.                 array('short'   => 'id',
  134.                       'desc'    => 'Data file name which contains a list of '
  135.                                  . 'directory to ignore',
  136.                       'default' => 'dirs.txt',
  137.                       'min'     => 0 'max' => 1),
  138.             'ignore-functions' =>
  139.                 array('short'   => 'in',
  140.                       'desc'    => 'Data file name which contains a list of '
  141.                                  . 'php function to ignore',
  142.                       'default' => 'functions.txt',
  143.                       'min'     => 0 'max' => 1),
  144.             'ignore-constants' =>
  145.                 array('short'   => 'ic',
  146.                       'desc'    => 'Data file name which contains a list of '
  147.                                  . 'php constant to ignore',
  148.                       'default' => 'constants.txt',
  149.                       'min'     => 0 'max' => 1),
  150.             'ignore-extensions' =>
  151.                 array('short'   => 'ie',
  152.                       'desc'    => 'Data file name which contains a list of '
  153.                                  . 'php extension to ignore',
  154.                       'default' => 'extensions.txt',
  155.                       'min'     => 0 'max' => 1),
  156.             'ignore-versions' =>
  157.                 array('short'   => 'iv',
  158.                       'desc'    => 'PHP versions - functions to exclude '
  159.                                  . 'when parsing source code',
  160.                       'default' => '5.0.0',
  161.                       'min'     => 0 'max' => 2),
  162.             'ignore-functions-match' =>
  163.                 array('short'   => 'inm',
  164.                       'desc'    => 'Data file name which contains a list of '
  165.                                  . 'php function pattern to ignore',
  166.                       'default' => 'functions-match.txt',
  167.                       'min'     => 0 'max' => 1),
  168.             'ignore-extensions-match' =>
  169.                 array('short'   => 'iem',
  170.                       'desc'    => 'Data file name which contains a list of '
  171.                                  . 'php extension pattern to ignore',
  172.                       'default' => 'extensions-match.txt',
  173.                       'min'     => 0 'max' => 1),
  174.             'ignore-constants-match' =>
  175.                 array('short'   => 'icm',
  176.                       'desc'    => 'Data file name which contains a list of '
  177.                                  . 'php constant pattern to ignore',
  178.                       'default' => 'constants-match.txt',
  179.                       'min'     => 0 'max' => 1),
  180.             'file-ext' =>
  181.                 array('short'   => 'fe',
  182.                       'desc'    => 'A comma separated list of file extensions '
  183.                                  . 'to parse (only valid if parsing a directory)',
  184.                       'default' => 'php, php4, inc, phtml',
  185.                       'min'     => 0 'max' => 1),
  186.             'report' =>
  187.                 array('short' => 'r',
  188.                       'desc' => 'Print either "xml" or "csv" report',
  189.                       'default' => 'text',
  190.                       'min'   => 0 'max' => 1),
  191.             'output-level' =>
  192.                 array('short' => 'o',
  193.                       'desc' => 'Print Path/File + Version with additional data',
  194.                       'default' => 31,
  195.                       'min'   => 0 'max' => 1),
  196.             'tab' =>
  197.                 array('short' => 't',
  198.                       'desc'  => 'Columns width',
  199.                       'default' => '29,12,20',
  200.                       'min'   => 0 'max' => 1),
  201.             'progress' =>
  202.                 array('short' => 'p',
  203.                       'desc' => 'Show a wait message [text] or a progress bar [bar]',
  204.                       'default' => 'bar',
  205.                       'min'   => 0 'max' => 1),
  206.             'summarize' =>
  207.                 array('short' => 'S',
  208.                       'desc' => 'Print only summary when parsing directory',
  209.                       'max'   => 0),
  210.             'version' =>
  211.                 array('short' => 'V',
  212.                       'desc'  => 'Print version information',
  213.                       'max'   => 0),
  214.             'help' =>
  215.                 array('short' => 'h',
  216.                       'desc'  => 'Show this help',
  217.                       'max'   => 0),
  218.         );
  219.     }
  220.  
  221.     /**
  222.      * Command-Line Class constructor
  223.      *
  224.      * Command-Line Class constructor (ZE1) for PHP4
  225.      *
  226.      * @since  version 0.8.0 (2004-04-22)
  227.      */
  228.     function PHP_CompatInfo_Cli()
  229.     {
  230.         $this->__construct();
  231.     }
  232.  
  233.     /**
  234.      * Run the CLI version
  235.      *
  236.      * Run the CLI version of PHP_CompatInfo
  237.      *
  238.      * @return void 
  239.      * @access public
  240.      * @since  version 0.8.0 (2004-04-22)
  241.      */
  242.     function run()
  243.     {
  244.         $args Console_Getargs::factory($this->opts);
  245.         if (PEAR::isError($args)) {
  246.             if ($args->getCode(=== CONSOLE_GETARGS_HELP{
  247.                 $error '';
  248.             else {
  249.                 $error $args->getMessage();
  250.             }
  251.             $this->_printUsage($error);
  252.             return;
  253.         }
  254.  
  255.         // default parser options
  256.         $this->options = array(
  257.             'file_ext' => array('php''php4''inc''phtml'),
  258.             'recurse_dir' => true,
  259.             'debug' => false,
  260.             'is_string' => false,
  261.             'ignore_files' => array(),
  262.             'ignore_dirs' => array()
  263.             );
  264.  
  265.         // version
  266.         $V $args->getValue('V');
  267.         if (isset($V)) {
  268.             $error 'PHP_CompatInfo (cli) version 1.9.0b1'
  269.                    . ' (http://pear.php.net/package/PHP_CompatInfo)';
  270.             echo $error;
  271.             return;
  272.         }
  273.  
  274.         // debug
  275.         if ($args->isDefined('v')) {
  276.             $v $args->getValue('v');
  277.             if ($v > 3{
  278.                 $this->options['debug'= true;
  279.             }
  280.         }
  281.  
  282.         // no-recurse
  283.         if ($args->isDefined('n')) {
  284.             $this->options['recurse_dir'= false;
  285.         }
  286.  
  287.         // dir
  288.         if ($args->isDefined('d')) {
  289.             $d $args->getValue('d');
  290.             if (file_exists($d)) {
  291.                 if ($d{strlen($d)-1== '/' || $d{strlen($d)-1== '\\'{
  292.                     $d substr($d0-1);
  293.                 }
  294.                 $this->dataSource = realpath($d);
  295.             else {
  296.                 $error 'Failed opening directory "' $d
  297.                        . '". Please check your spelling and try again.';
  298.                 $this->_printUsage($error);
  299.                 return;
  300.             }
  301.         }
  302.  
  303.         // file
  304.         if ($args->isDefined('f')) {
  305.             $f $args->getValue('f');
  306.             if (file_exists($f)) {
  307.                 $this->dataSource = $f;
  308.             else {
  309.                 $error 'Failed opening file "' $f
  310.                        . '". Please check your spelling and try again.';
  311.                 $this->_printUsage($error);
  312.                 return;
  313.             }
  314.         }
  315.  
  316.         // string
  317.         if ($args->isDefined('s')) {
  318.             $s $args->getValue('s');
  319.             if (!empty($s)) {
  320.                 $this->dataSource           = sprintf("<?php %s ?>"$s);
  321.                 $this->options['is_string'= true;
  322.             else {
  323.                 $error 'Failed opening string "' $s
  324.                        . '". Please check your spelling and try again.';
  325.                 $this->_printUsage($error);
  326.                 return;
  327.             }
  328.         }
  329.  
  330.         // ignore-files
  331.         $if $args->getValue('if');
  332.         if (isset($if)) {
  333.             if (file_exists($if)) {
  334.                 $options                       $this->_parseParamFile($if);
  335.                 $this->options['ignore_files'$options['std'];
  336.             else {
  337.                 $error 'Failed opening file "' $if
  338.                        . '" (ignore-files option). '
  339.                        . 'Please check your spelling and try again.';
  340.                 $this->_printUsage($error);
  341.                 return;
  342.             }
  343.         }
  344.  
  345.         // ignore-dirs
  346.         $id $args->getValue('id');
  347.         if (isset($id)) {
  348.             if (file_exists($id)) {
  349.                 $options                      $this->_parseParamFile($id);
  350.                 $this->options['ignore_dirs'$options['std'];
  351.             else {
  352.                 $error 'Failed opening file "' $id
  353.                        . '" (ignore-dirs option). '
  354.                        . 'Please check your spelling and try again.';
  355.                 $this->_printUsage($error);
  356.                 return;
  357.             }
  358.         }
  359.  
  360.         // ignore-functions
  361.         $in $args->getValue('in');
  362.         if (isset($in)) {
  363.             if (file_exists($in)) {
  364.                 $options                           $this->_parseParamFile($in);
  365.                 $this->options['ignore_functions'$options['std'];
  366.             else {
  367.                 $error 'Failed opening file "' $in
  368.                        . '" (ignore-functions option). '
  369.                        . 'Please check your spelling and try again.';
  370.                 $this->_printUsage($error);
  371.                 return;
  372.             }
  373.         }
  374.  
  375.         // ignore-constants
  376.         $ic $args->getValue('ic');
  377.         if (isset($ic)) {
  378.             if (file_exists($ic)) {
  379.                 $options                           $this->_parseParamFile($ic);
  380.                 $this->options['ignore_constants'$options['std'];
  381.             else {
  382.                 $error 'Failed opening file "' $ic
  383.                        . '" (ignore-constants option). '
  384.                        . 'Please check your spelling and try again.';
  385.                 $this->_printUsage($error);
  386.                 return;
  387.             }
  388.         }
  389.  
  390.         // ignore-extensions
  391.         $ie $args->getValue('ie');
  392.         if (isset($ie)) {
  393.             if (file_exists($ie)) {
  394.                 $options                            $this->_parseParamFile($ie);
  395.                 $this->options['ignore_extensions'$options['std'];
  396.             else {
  397.                 $error 'Failed opening file "' $ie
  398.                        . '" (ignore-extensions option). '
  399.                        . 'Please check your spelling and try again.';
  400.                 $this->_printUsage($error);
  401.                 return;
  402.             }
  403.         }
  404.  
  405.         // ignore-versions
  406.         $iv $args->getValue('iv');
  407.         if (isset($iv)) {
  408.             if (!is_array($iv)) {
  409.                 $iv = array($iv);
  410.             }
  411.             $this->options['ignore_versions'$iv;
  412.         }
  413.  
  414.         // ignore-functions-match
  415.         $inm $args->getValue('inm');
  416.         if (isset($inm)) {
  417.             if (file_exists($inm)) {
  418.                 $patterns $this->_parseParamFile($inmtrue);
  419.                 if (count($patterns['std']> 0
  420.                     && count($patterns['reg']> 0{
  421.                     $error 'Mixed "function_exists" and '
  422.                            . '"preg_match" conditions are not allowed. '
  423.                            . 'Please check your spelling and try again.';
  424.                     $this->_printUsage($error);
  425.                     return;
  426.  
  427.                 elseif (count($patterns['std']> 0{
  428.                     $this->options['ignore_functions_match']
  429.                         = array('function_exists'$patterns['std']);
  430.                 elseif (count($patterns['reg']> 0{
  431.                     $this->options['ignore_functions_match']
  432.                         = array('preg_match'$patterns['reg']);
  433.                 }
  434.             else {
  435.                 $error 'Failed opening file "' $inm
  436.                        . '" (ignore-functions-match option). '
  437.                        . 'Please check your spelling and try again.';
  438.                 $this->_printUsage($error);
  439.                 return;
  440.             }
  441.         }
  442.  
  443.         // ignore-extensions-match
  444.         $iem $args->getValue('iem');
  445.         if (isset($iem)) {
  446.             if (file_exists($iem)) {
  447.                 $patterns $this->_parseParamFile($iemtrue);
  448.                 if (count($patterns['std']> 0
  449.                     && count($patterns['reg']> 0{
  450.                     $error 'Mixed "extension_loaded" and '
  451.                            . '"preg_match" conditions are not allowed. '
  452.                            . 'Please check your spelling and try again.';
  453.                     $this->_printUsage($error);
  454.                     return;
  455.  
  456.                 elseif (count($patterns['std']> 0{
  457.                     $this->options['ignore_extensions_match']
  458.                         = array('extension_loaded'$patterns['std']);
  459.                 elseif (count($patterns['reg']> 0{
  460.                     $this->options['ignore_extensions_match']
  461.                         = array('preg_match'$patterns['reg']);
  462.                 }
  463.             else {
  464.                 $error 'Failed opening file "' $iem
  465.                        . '" (ignore-extensions-match option). '
  466.                        . 'Please check your spelling and try again.';
  467.                 $this->_printUsage($error);
  468.                 return;
  469.             }
  470.         }
  471.  
  472.         // ignore-constants-match
  473.         $icm $args->getValue('icm');
  474.         if (isset($icm)) {
  475.             if (file_exists($icm)) {
  476.                 $patterns $this->_parseParamFile($icmtrue);
  477.                 if (count($patterns['std']> 0
  478.                     && count($patterns['reg']> 0{
  479.                     $error 'Mixed "defined" and '
  480.                            . '"preg_match" conditions are not allowed. '
  481.                            . 'Please check your spelling and try again.';
  482.                     $this->_printUsage($error);
  483.                     return;
  484.  
  485.                 elseif (count($patterns['std']> 0{
  486.                     $this->options['ignore_constants_match']
  487.                         = array('defined'$patterns['std']);
  488.                 elseif (count($patterns['reg']> 0{
  489.                     $this->options['ignore_constants_match']
  490.                         = array('preg_match'$patterns['reg']);
  491.                 }
  492.             else {
  493.                 $error 'Failed opening file "' $icm
  494.                        . '" (ignore-constants-match option). '
  495.                        . 'Please check your spelling and try again.';
  496.                 $this->_printUsage($error);
  497.                 return;
  498.             }
  499.         }
  500.  
  501.         // file-ext
  502.         if ($args->isDefined('d'&& $args->isDefined('fe')) {
  503.             $fe $args->getValue('fe');
  504.             if (is_string($fe)) {
  505.                 $this->options['file_ext'explode(','$fe);
  506.             else {
  507.                 $error 'No valid file extensions provided "'
  508.                        . '". Please check your spelling and try again.';
  509.                 $this->_printUsage($error);
  510.                 return;
  511.             }
  512.         }
  513.  
  514.         // file or directory options are minimum required to work
  515.         if (!$args->isDefined('f')
  516.             && !$args->isDefined('d')
  517.             && !$args->isDefined('s')) {
  518.             $error 'ERROR: You must supply at least '
  519.                    . 'one string, file or directory to process';
  520.             $this->_printUsage($error);
  521.             return;
  522.         }
  523.  
  524.         if ($args->isDefined('r')) {
  525.             $report $args->getValue('r');
  526.         else {
  527.             $report 'text';
  528.         }
  529.  
  530.         if ($args->isDefined('t')) {
  531.             $defs = array('f' => 29'e' => 12'c' => 20);
  532.             $tabs $args->getValue('t');
  533.             $tabs explode(','$tabs);
  534.             for ($t = 0; $t < 3; $t++{
  535.                 if (isset($tabs[$t])) {
  536.                     if ($t == 0{
  537.                         $defs['f'= (int)$tabs[$t];
  538.                     elseif ($t == 1{
  539.                         $defs['e'= (int)$tabs[$t];
  540.                     else {
  541.                         $defs['c'= (int)$tabs[$t];
  542.                     }
  543.                 }
  544.             }
  545.             $conf = array('colwidth' => $defs);
  546.         else {
  547.             $conf = array();
  548.         }
  549.         $conf array_merge($confarray('args' => $args->getValues()));
  550.  
  551.         $compatInfo = new PHP_CompatInfo($report$conf);
  552.  
  553.         // dir
  554.         if ($args->isDefined('d')) {
  555.             $d     $args->getValue('d');
  556.             $files $compatInfo->parser->getFilelist($d$this->options);
  557.             if (count($files== 0{
  558.                 $error 'No valid files into directory "'$d
  559.                        . '". Please check your spelling and try again.';
  560.                 $this->_printUsage($error);
  561.                 return;
  562.             }
  563.         }
  564.         $compatInfo->parseData($this->dataSource$this->options);
  565.     }
  566.  
  567.     /**
  568.      * Parse content of parameter files
  569.      *
  570.      * Parse content of parameter files used by switches
  571.      * <ul>
  572.      * <li>ignore-files
  573.      * <li>ignore-dirs
  574.      * <li>ignore-functions
  575.      * <li>ignore-constants
  576.      * <li>ignore-extensions
  577.      * <li>ignore-functions-match
  578.      * <li>ignore-extensions-match
  579.      * <li>ignore-constants-match
  580.      * </ul>
  581.      *
  582.      * @param string $fn          Parameter file name
  583.      * @param bool   $withPattern TRUE if the file may contain regular expression
  584.      *
  585.      * @return array 
  586.      * @access private
  587.      * @since  version 1.7.0b4 (2008-04-03)
  588.      */
  589.     function _parseParamFile($fn$withPattern = false)
  590.     {
  591.         $lines    file($fn);
  592.         $patterns = array('std' => array()'reg' => array());
  593.         foreach ($lines as $line{
  594.             $line rtrim($line);  // remove line ending
  595.             if (strlen($line== 0{
  596.                 continue;  // skip empty lines
  597.             }
  598.             if ($line{0== ';'{
  599.                 continue;  // skip this pattern: consider as comment line
  600.             }
  601.             if ($line{0== '='{
  602.                 list($p$s)       explode('='$line);
  603.                 $patterns['reg']['/'.$s.'/';
  604.             else {
  605.                 if ($withPattern === true{
  606.                     $patterns['std']['/'.$line.'/';
  607.                 else {
  608.                     $patterns['std'][$line;
  609.                 }
  610.             }
  611.         }
  612.         return $patterns;
  613.     }
  614.  
  615.     /**
  616.      * Show full help information
  617.      *
  618.      * @param string $footer (optional) page footer content
  619.      *
  620.      * @return void 
  621.      * @access private
  622.      * @since  version 0.8.0 (2004-04-22)
  623.      */
  624.     function _printUsage($footer '')
  625.     {
  626.         $header 'Usage: '
  627.             . basename($_SERVER['SCRIPT_NAME']" [options]\n\n";
  628.         echo Console_Getargs::getHelp($this->opts$header,
  629.             "\n$footer\n"782)."\n";
  630.     }
  631. }
  632. ?>

Documentation generated on Sun, 30 Nov 2008 16:30:24 -0500 by phpDocumentor 1.4.0. PEAR Logo Copyright © PHP Group 2004.