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}");
}
}