home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / CodeGen / Extension.php < prev    next >
Encoding:
PHP Script  |  2006-04-07  |  15.4 KB  |  769 lines

  1. <?php
  2. /**
  3.  * Extension generator class
  4.  *
  5.  * PHP versions 5
  6.  *
  7.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  8.  * that is available through the world-wide-web at the following URI:
  9.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  10.  * the PHP License and are unable to obtain it through the web, please
  11.  * send a note to license@php.net so we can mail you a copy immediately.
  12.  *
  13.  * @category   Tools and Utilities
  14.  * @package    CodeGen
  15.  * @author     Hartmut Holzgraefe <hartmut@php.net>
  16.  * @copyright  2005 Hartmut Holzgraefe
  17.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  18.  * @version    CVS: $Id: Extension.php,v 1.16 2006/02/17 09:47:00 hholzgra Exp $
  19.  * @link       http://pear.php.net/package/CodeGen
  20.  */
  21.  
  22. /**
  23.  * includes
  24.  *
  25.  */
  26. require_once "CodeGen/Maintainer.php";
  27. require_once "CodeGen/License.php";
  28. require_once "CodeGen/Release.php";
  29. require_once "CodeGen/Tools/Platform.php";
  30. require_once "CodeGen/Tools/Indent.php";
  31. require_once "CodeGen/Tools/FileReplacer.php";
  32. require_once "CodeGen/Tools/Outbuf.php";
  33. require_once "CodeGen/Dependency/Lib.php";
  34. require_once "CodeGen/Dependency/Header.php";
  35.  
  36. /**
  37.  * Extension generator class
  38.  *
  39.  * @category   Tools and Utilities
  40.  * @package    CodeGen
  41.  * @author     Hartmut Holzgraefe <hartmut@php.net>
  42.  * @copyright  2005 Hartmut Holzgraefe
  43.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  44.  * @version    Release: @package_version@
  45.  * @link       http://pear.php.net/package/CodeGen
  46.  */
  47. abstract class CodeGen_Extension 
  48. {
  49.     /**
  50.     * Current version number
  51.     * 
  52.     * @return string
  53.     */
  54.     abstract static public function version();
  55.  
  56.     /**
  57.     * Copyright message
  58.     *
  59.     * @return string
  60.     */
  61.     abstract static public function copyright();
  62.  
  63.     /**
  64.      * The extensions basename (C naming rules apply)
  65.      *
  66.      * @var string
  67.      */
  68.     protected $name = "unknown";
  69.     
  70.  
  71.     /**
  72.      * The extensions descriptive name
  73.      *
  74.      * @var string
  75.      */
  76.     protected $summary = "The unknown extension";
  77.     
  78.     /**
  79.      * extension description
  80.      *
  81.      * @var    string
  82.      * @access private
  83.      */
  84.     protected $description;
  85.  
  86.     /** 
  87.      * The license for this extension
  88.      *
  89.      * @var object
  90.      */
  91.     protected $license  = NULL;
  92.     
  93.     /** 
  94.      * The release info for this extension
  95.      *
  96.      * @var object
  97.      */
  98.     protected $release  = NULL;
  99.         
  100.     /** 
  101.      * The implementation language
  102.      *
  103.      * Currently we support "c" and "cpp"
  104.      *
  105.      * @var string
  106.      */
  107.     protected $language  = "c";
  108.     
  109.     /**
  110.      * The target platform for this extension
  111.      *
  112.      * Possible values are "unix", "win" and "all"
  113.      * 
  114.      * @var string
  115.      */
  116.     protected $platform = null;
  117.     
  118.     
  119.     /**
  120.      * The authors contributing to this extension
  121.      *
  122.      * @var array
  123.      */
  124.     protected $authors = array();
  125.     
  126.     
  127.     /**
  128.      * Name prefix for functions etc.
  129.      * 
  130.      * @var string
  131.      */
  132.     protected $prefix = "";
  133.  
  134.  
  135.     /**
  136.      * Release changelog
  137.      *
  138.      * @access private
  139.      * @var     string
  140.      */
  141.     protected $changelog = "";
  142.  
  143.     
  144.     /** 
  145.      * Basedir for all created files
  146.      *
  147.      * @access protected
  148.      * @var    string
  149.      */
  150.     public $dirpath = ".";
  151.  
  152.  
  153.     /**
  154.      * External libraries
  155.      *
  156.      * @var    array
  157.      * @access private
  158.      */
  159.     protected $libs = array();
  160.  
  161.     /**
  162.      * External header files
  163.      *
  164.      * @var    array
  165.      * @access private
  166.      */
  167.     protected $headers = array();
  168.  
  169.     /**
  170.      * Code snippets
  171.      *
  172.      * @var array
  173.      */
  174.     protected $code = array();
  175.  
  176.     /**
  177.      * The package files created by this extension
  178.      *
  179.      * @var array
  180.      */
  181.     protected $packageFiles = array();
  182.  
  183.     /**
  184.      * Version requested by input if any
  185.      *
  186.      * @var string
  187.      */
  188.     protected $version = "";
  189.  
  190.  
  191.     /**
  192.      * Makefile fragments
  193.      *
  194.      * @var    array
  195.      * @access private
  196.      */
  197.     protected $makefragments = array();
  198.  
  199.  
  200.     /**
  201.      * config.m4 fragments
  202.      *
  203.      * @var    array
  204.      * @access private
  205.      */
  206.     protected $configfragments = array("top"=>array(), "bottom"=>array());
  207.  
  208.  
  209.     /**
  210.      * acinclude fragments
  211.      *
  212.      * @var    array
  213.      * @access private
  214.      */
  215.     protected $acfragments = array("top"=>array(), "bottom"=>array());
  216.  
  217.  
  218.  
  219.     // {{{ constructor
  220.  
  221.     /**
  222.      * The constructor
  223.      *
  224.      * @access public
  225.      */
  226.     function __construct() 
  227.     {
  228.         set_locale("C"); // ASCII only
  229.  
  230.         $this->release = new CodeGen_Release;
  231.         
  232.         $this->platform = new CodeGen_Tools_Platform("all");
  233.     }
  234.     
  235.     // }}} 
  236.     /**
  237.      * Set method for changelog
  238.      *
  239.      * @access public
  240.      * @param  string changelog
  241.      * @return bool   true on success
  242.      */
  243.     function setChangelog($changelog)
  244.     {
  245.         $this->changelog = $changelog;
  246.         
  247.         return true;
  248.     }
  249.     
  250.     /**
  251.      * changelog getter
  252.      *
  253.      * @access public
  254.      * @return string
  255.      */
  256.     function getChangelog()
  257.     {
  258.         return $this->changelog;
  259.     }
  260.  
  261.     /**
  262.      * Set extension base name
  263.      *
  264.      * @access public
  265.      * @param  string  name
  266.      */
  267.     function setName($name) 
  268.     {
  269.         if (!preg_match('|^[a-z_]\w*$|i', $name)) {
  270.             return PEAR::raiseError("'$name' is not a valid extension name");
  271.         }
  272.         
  273.         $this->name = $name;
  274.         return true;
  275.     }
  276.  
  277.     /**
  278.      * Get extension base name
  279.      *
  280.      * @return string
  281.      */
  282.     function getName()
  283.     {
  284.         return $this->name;
  285.     }
  286.  
  287.     /**
  288.      * Set extension summary text
  289.      *
  290.      * @access public
  291.      * @param  string  short summary
  292.      */
  293.     function setSummary($text) 
  294.     {
  295.         $this->summary = $text;
  296.         return true;
  297.     }
  298.  
  299.     /** 
  300.      * Set extension documentation text
  301.      *
  302.      * @access public
  303.      * @param  string  long description
  304.      */
  305.     function setDescription($text) 
  306.     {
  307.         $this->description = $text;
  308.         return true;
  309.     }
  310.  
  311.     /**
  312.      * Set the programming language to produce code for
  313.      *
  314.      * @access public
  315.      * @param  string  programming language name
  316.      */
  317.     function setLanguage($lang)
  318.     {
  319.         switch (strtolower($lang)) {
  320.         case "c":
  321.             $this->language = "c";
  322.             return true;
  323.         case "cpp":
  324.         case "cxx":
  325.         case "c++":
  326.             $this->language = "cpp";
  327.             return true;
  328.         default:
  329.             break;
  330.         }
  331.  
  332.         return PEAR::raiseError("'$lang' is not a supported implementation language");
  333.     }
  334.  
  335.     /**
  336.      * Get programming language
  337.      *
  338.      * @return string
  339.      */
  340.     function getLanguage()
  341.     {
  342.         return $this->language;
  343.     }
  344.  
  345.     /**
  346.      * Set target platform for generated code
  347.      *
  348.      * @access public
  349.      * @param  string  platform name
  350.      */
  351.     function setPlatform($type)
  352.     {
  353.         $this->platform = new CodeGen_Tools_Platform($type);
  354.         if (PEAR::isError($this->platform)) {
  355.             return $this->platform;
  356.         }
  357.         
  358.         return true;
  359.     }
  360.  
  361.     /**
  362.      * Add an author or maintainer to the extension
  363.      *
  364.      * @access public
  365.      * @param  object   a maintainer object
  366.      */
  367.     function addAuthor($author)
  368.     {
  369.         if (!is_a($author, "CodeGen_Maintainer")) {
  370.             return PEAR::raiseError("argument is not CodeGen_Maintainer");
  371.         }
  372.         
  373.         $this->authors[$author->getUser()] = $author;
  374.         
  375.         return true;
  376.     }
  377.  
  378.     /** 
  379.      * Set release info
  380.      * 
  381.      * @access public
  382.      * @var    object
  383.      */
  384.     function setRelease($release)
  385.     {
  386.         $this->release = $release;
  387.  
  388.         return true;
  389.     }
  390.  
  391.  
  392.     /** 
  393.      * Set license 
  394.      * 
  395.      * @access public
  396.      * @param  object
  397.      */
  398.     function setLicense($license)
  399.     {
  400.         $this->license = $license;
  401.  
  402.         return true;
  403.     }
  404.  
  405.  
  406.     /**
  407.      * Set extension name prefix (for functions etc.)
  408.      *
  409.      * @access public
  410.      * @param  string  name
  411.      */
  412.     function setPrefix($prefix) 
  413.     {
  414.         if (! CodeGen_Element::isName($prefix)) {
  415.             return PEAR::raiseError("'$name' is not a valid name prefix");
  416.         }
  417.         
  418.         $this->prefix = $prefix;
  419.         return true;
  420.     }
  421.  
  422.     /**
  423.      * Get extension name prefix
  424.      *
  425.      * @return string
  426.      */
  427.     function getPrefix()
  428.     {
  429.         return $this->prefix;
  430.     }
  431.  
  432.     /** 
  433.      * Add verbatim code snippet to extension
  434.      *
  435.      * @access public
  436.      * @param  string  which file to put the code to
  437.      * @param  string  where in the file the code should be put
  438.      * @param  string  the actual code
  439.      */
  440.     function addCode($role, $position, $code)
  441.     {
  442.         if (!in_array($role, array("header", "code"))) {
  443.             return PEAR::raiseError("'$role' is not a valid custom code role");
  444.         }
  445.         if (!in_array($position, array("top", "bottom"))) {
  446.             return PEAR::raiseError("'$position' is not a valid custom code position");
  447.         }
  448.         $this->code[$role][$position][] = $code;
  449.     }
  450.  
  451.  
  452.     /**
  453.      * Add toplevel library dependancy 
  454.      *
  455.      * @var  string  library basename
  456.      */
  457.     function addLib(CodeGen_Dependency_Lib $lib) 
  458.     {
  459.         $name = $lib->getName();
  460.        
  461.         if (isset($this->libs[$name])) {
  462.             return PEAR::raiseError("library '{$name}' added twice");
  463.         }
  464.  
  465.         $this->libs[$name] = $lib;
  466.  
  467.         return true;
  468.     }
  469.  
  470.     /**
  471.      * Add toplevel header file dependancy 
  472.      *
  473.      * @var  string  header filename
  474.      */
  475.     function addHeader(CodeGen_Dependency_Header $header) 
  476.     {
  477.         $name = $header->getName();
  478.        
  479.         if (isset($this->headers[$name])) {
  480.             return PEAR::raiseError("header '{$name}' added twice");
  481.         }
  482.  
  483.         $this->headers[$name] = $header;
  484.  
  485.         return true;
  486.     }
  487.  
  488.     /**
  489.     * Describe next steps after successfull extension creation
  490.     *
  491.     * @access private
  492.     */
  493.     function successMsg()
  494.     {
  495.         $relpath = str_replace(getcwd(), '.', $this->dirpath);
  496.     
  497.         $msg = "\nYour extension has been created in directory $relpath.\n";
  498.         $msg.= "See $relpath/README and $relpath/INSTALL for further instructions.\n";
  499.  
  500.         return $msg;
  501.     }
  502.  
  503.     /**
  504.      * Get requested version
  505.      *
  506.      * @return  string
  507.      */
  508.     function getVersion()
  509.     {
  510.         return $this->version;
  511.     }
  512.  
  513.     /**
  514.      * Set requested version
  515.      *
  516.      * @param  string
  517.      */
  518.     function setVersion($version)
  519.     {
  520.         if (!preg_match('/^\d+\.\d+\.\d+(dev|alpha|beta|gamma|rc|pl)?\d*$/', $version)) {
  521.             return PEAR::raiseError("'$version' is not a valid version number");
  522.         }
  523.         
  524.         if (version_compare($version, $this->version(), ">")) {
  525.             return PEAR::raiseError("This is ".get_class($this)." ".$this->version().", input file requires at least version $version ");
  526.         }
  527.         
  528.         $this->version = $version;
  529.         return true;
  530.     }
  531.  
  532.     /**
  533.      * Check requested version
  534.      *
  535.      * @param  string version
  536.      * @return bool
  537.      */
  538.     function haveVersion($version)
  539.     {
  540.         return version_compare(empty($this->version) ? $this->version() : $this->version, $version) >= 0;
  541.  
  542.         return true; // 
  543.     }
  544.  
  545.     /**
  546.      * Add a package file by type and path
  547.      *
  548.      * @access  public
  549.      * @param   string  type
  550.      * @param   string  path
  551.      * @returns bool    success state
  552.      */
  553.     function addPackageFile($type, $path)
  554.     {
  555.         $basename = basename($path);
  556.  
  557.         if (isset($this->packageFiles[$type][$basename])) {
  558.             return PEAR::raiseError("duplicate distribution file name '$basename'");
  559.         }
  560.  
  561.         $this->packageFiles[$type][$basename] = $path;
  562.         return true;
  563.     }
  564.  
  565.     /**
  566.      * Add a source file to be copied to the extension dir
  567.      *
  568.      * @access public
  569.      * @param  string path
  570.      */
  571.     function addSourceFile($name) 
  572.     {
  573.         // TODO catch errors returned from addPackageFile
  574.  
  575.         $filename = realpath($name);
  576.  
  577.         if (!is_file($filename)) {
  578.           return PEAR::raiseError("'$name' is not a valid file");
  579.         }
  580.         
  581.         if (!is_readable($filename)) {
  582.           return PEAR::raiseError("'$name' is not readable");
  583.         }
  584.         
  585.         $pathinfo = pathinfo($filename);
  586.         $ext = $pathinfo["extension"];
  587.  
  588.         switch ($ext) {
  589.         case 'c':
  590.           $this->addConfigFragment("AC_PROG_CC");
  591.           $this->addPackageFile('code', $filename);
  592.           break;
  593.         case 'cpp':
  594.         case 'cxx':
  595.         case 'c++':
  596.           $this->addConfigFragment("AC_PROG_CXX");
  597.           $this->addConfigFragment("AC_LANG([C++])");
  598.           $this->addPackageFile('code', $filename);
  599.           break;
  600.         case 'l':
  601.         case 'flex':
  602.           $this->addConfigFragment("AM_PROG_LEX");
  603.           $this->addPackageFile('code', $filename);
  604.           break;
  605.         case 'y':
  606.         case 'bison':
  607.           $this->addConfigFragment("AM_PROG_YACC");
  608.           $this->addPackageFile('code', $filename);
  609.           break;
  610.         default:
  611.           break;
  612.         }
  613.         
  614.         return $this->addPackageFile('copy', $filename);
  615.     }
  616.  
  617.     /**
  618.      * Add makefile fragment
  619.      *
  620.      * @access public
  621.      * @param  string
  622.      */
  623.     function addMakeFragment($text)
  624.     {
  625.         $this->makefragments[] = $text;
  626.         return true;
  627.     }
  628.             
  629.  
  630.     /**
  631.      * Add config.m4 fragment
  632.      *
  633.      * @access public
  634.      * @param  string
  635.      */
  636.     function addConfigFragment($text, $position="top")
  637.     {
  638.         if (!in_array($position, array("top", "bottom"))) {
  639.             return PEAR::raiseError("'$position' is not a valid config snippet position");
  640.         }
  641.         $this->configfragments[$position][] = $text;
  642.         return true;
  643.     }
  644.  
  645.  
  646.     /**
  647.      * Add acinclude.m4 fragment
  648.      *
  649.      * @access public
  650.      * @param  string
  651.      */
  652.     function addAcIncludeFragment($text, $position="top")
  653.     {
  654.         if (!in_array($position, array("top", "bottom"))) {
  655.             return PEAR::raiseError("'$position' is not a valid config snippet position");
  656.         }
  657.         $this->acfragments[$position][] = $text;
  658.         return true;
  659.     }
  660.             
  661.  
  662.     /**
  663.     * Write .cvsignore entries
  664.     *
  665.     * @access public
  666.     * @param  string  directory to write to
  667.     */
  668.     function writeDotCvsignore()
  669.     {
  670.         $file = new CodeGen_Tools_Outbuf($this->dirpath."/.cvsignore");
  671.  
  672.         // unix specific entries
  673.         if ($this->platform->test("unix")) {
  674.             echo 
  675. "*.lo
  676. *.la
  677. .deps
  678. .libs
  679. Makefile
  680. Makefile.fragments
  681. Makefile.global
  682. Makefile.objects
  683. acinclude.m4
  684. aclocal.m4
  685. autom4te.cache
  686. build
  687. config.cache
  688. config.guess
  689. config.h
  690. config.h.in
  691. config.log
  692. config.nice
  693. config.status
  694. config.sub
  695. configure
  696. configure.in
  697. conftest
  698. conftest.c
  699. include
  700. install-sh
  701. libtool
  702. ltmain.sh
  703. missing
  704. mkinstalldirs
  705. modules
  706. scan_makefile_in.awk
  707. ";
  708.         }
  709.  
  710.         // windows specific entries
  711.         if ($this->platform->test("windows")) {
  712.             echo 
  713. "*.dsw
  714. *.plg
  715. *.opt
  716. *.ncb
  717. Release
  718. Release_inline
  719. Debug
  720. Release_TS
  721. Release_TSDbg
  722. Release_TS_inline
  723. Debug_TS
  724. ";
  725.         }
  726.  
  727.         // "pear package" creates .tgz
  728.         echo "{$this->name}*.tgz\n";
  729.  
  730.         return $file->write();
  731.     }
  732.  
  733.     /**
  734.      * Generate Editor settings block for C source files
  735.      *
  736.      * @access public
  737.      * @return string Editor settings comment block
  738.     */
  739.     function cCodeEditorSettings() 
  740.     {
  741.             return '
  742. /*
  743.  * Local variables:
  744.  * tab-width: 4
  745.  * c-basic-offset: 4
  746.  * End:
  747.  * vim600: noet sw=4 ts=4 fdm=marker
  748.  * vim<600: noet sw=4 ts=4
  749.  */
  750. ';
  751.      }
  752.  
  753.     /**
  754.      * Generate Editor settings block for documentation files
  755.      *
  756.      * @access public
  757.      * @param  int    Directory nesting depth of target file (default: 3)
  758.      * @return string Editor settings comment block
  759.     */
  760.     static function docEditorSettings($level=3) 
  761.     {
  762.         return "";
  763.     }
  764. }
  765.  
  766.  
  767.  
  768. ?>
  769.