public static function createM4Extension($packageName, $m4Path) { if (!file_exists($m4Path)) { return NULL; } $m4 = file_get_contents($m4Path); // PHP_NEW_EXTENSION(extname, sources [, shared [, sapi_class [, extra-cflags [, cxx [, zend_ext]]]]]) if (preg_match('/PHP_NEW_EXTENSION \\( \\s* \\[? (\\w+) # The extension name \\]? \\s*,\\s* \\[? ([^,]*) # Source files \\]? (?: \\s*,\\s* ([^,\\)]*) # Ext Shared (?: \\s*,\\s* ([^,\\)]*) # SAPI class (?: \\s*,\\s* ([^,\\)]*) # Extra cflags (?: \\s*,\\s* ([^,\\)]*) # CXX \\s*,\\s* ([^,\\)]*) # zend extension )? )? )? )? /x', $m4, $matches)) { $fullmatched = array_shift($matches); $ext = new M4Extension($packageName); $ext->setExtensionName($matches[0]); $ext->setSharedLibraryName($matches[0] . '.so'); if (isset($matches[6]) && strpos($matches[6], 'yes') !== false) { $ext->setZend(true); } $ext->setSourceDirectory(dirname($m4Path)); /* PHP_ARG_ENABLE(calendar,whether to enable calendar conversion support, [ --enable-calendar Enable support for calendar conversion]) */ if (preg_match_all('/ PHP_ARG_ENABLE\\( \\s*([^,]*) (?: \\s*,\\s* ( [^,\\)]* ) (?: \\s*,\\s* \\[ \\s* ([^\\s]+) \\s+ ([^,\\)]*) \\s* \\] )? )?/x', $m4, $allMatches)) { for ($i = 0; $i < count($allMatches[0]); $i++) { $name = $allMatches[1][$i]; $desc = $allMatches[2][$i]; $option = $allMatches[3][$i]; $optionDesc = $allMatches[4][$i]; $ext->addConfigureOption(new ConfigureOption($option ?: '--enable-' . $name, $desc ?: $optionDesc)); } } /* PHP_ARG_WITH(gd, for GD support, [ --with-gd[=DIR] Include GD support. DIR is the GD library base install directory [BUNDLED]]) Possible option formats: --with-libxml-dir=DIR --with-recode[=DIR] --with-yaml[[=DIR]] --with-mysql-sock[=SOCKPATH] */ if (preg_match_all('/ PHP_ARG_WITH\\( \\s* ([^,]*) (?: \\s*,\\s* \\[? ([^,\\)]*) \\]? (?: \\s*,\\s* \\[ \\s* # simple match (\\S+) ([a-zA-Z0-9-]+) # option (?: =? \\[? =?([^\\s\\]]*?) \\]? )? # option value hint \\s+ ([^,\\)]*) # option description \\s* \\] (?: \\s*,\\s* ([^,\\)]*) (?: \\s*,\\s* ([^,\\)]*) )? )? )? )?/x', $m4, $allMatches)) { // Parsing the M4 statement: // // dnl PHP_ARG_WITH(arg-name, check message, help text[, default-val[, extension-or-not]]) // for ($i = 0; $i < count($allMatches[0]); $i++) { $name = $allMatches[1][$i]; $desc = $allMatches[2][$i]; $option = $allMatches[3][$i]; $optionValueHint = $allMatches[4][$i]; $optionDesc = $allMatches[5][$i]; $defaultValue = $allMatches[6][$i]; $opt = new ConfigureOption($option ?: '--with-' . $name, $desc ?: $optionDesc, $optionValueHint); if ($defaultValue) { $opt->setDefaultValue($opt); } $ext->addConfigureOption($opt); } } return $ext; } else { throw new Exception("Can not parse config.m4: {$m4Path}"); } }