summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-08-10 15:07:54 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-08-10 15:07:54 +0200
commit17987da884f8ff1147f4804ce42622a001eb7210 (patch)
treea107af2740fd64bc9c4cd791a39f9cbde9829034 /scripts
parentd9e2d185057b66e2adc9f25ce4ee60d482e086a9 (diff)
downloadphp-git-17987da884f8ff1147f4804ce42622a001eb7210.tar.gz
Expand preprocessor support in gen_stubs
Support #ifdef, #ifndef, #else and nested #if's.
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/dev/gen_stub.php68
1 files changed, 46 insertions, 22 deletions
diff --git a/scripts/dev/gen_stub.php b/scripts/dev/gen_stub.php
index 59b7d448f6..993be075d7 100755
--- a/scripts/dev/gen_stub.php
+++ b/scripts/dev/gen_stub.php
@@ -224,20 +224,34 @@ function parseStubFile(string $fileName) {
$nodeTraverser->traverse($stmts);
$funcInfos = [];
- $cond = null;
+ $conds = [];
foreach ($stmts as $stmt) {
foreach ($stmt->getComments() as $comment) {
$text = trim($comment->getText());
- if (preg_match('/^#if\s+(.+)$/', $text, $matches)) {
- if ($cond !== null) {
- throw new Exception("Not implemented preprocessor directive");
+ if (preg_match('/^#\s*if\s+(.+)$/', $text, $matches)) {
+ $conds[] = $matches[1];
+ } else if (preg_match('/^#\s*ifdef\s+(.+)$/', $text, $matches)) {
+ $conds[] = "defined($matches[1])";
+ } else if (preg_match('/^#\s*ifndef\s+(.+)$/', $text, $matches)) {
+ $conds[] = "!defined($matches[1])";
+ } else if (preg_match('/^#\s*else$/', $text)) {
+ if (empty($conds)) {
+ throw new Exception("Encountered else without corresponding #if");
}
- $cond = $matches[1];
- } else if ($text === '#endif') {
- $cond = null;
+ $cond = array_pop($conds);
+ $conds[] = "!($cond)";
+ } else if (preg_match('/^#\s*endif$/', $text)) {
+ if (empty($conds)) {
+ throw new Exception("Encountered #endif without corresponding #if");
+ }
+ array_pop($conds);
+ } else if ($text[0] === '#') {
+ throw new Exception("Unrecognized preprocessor directive \"$text\"");
}
}
+ $cond = empty($conds) ? null : implode(' && ', $conds);
+
if ($stmt instanceof Stmt\Nop) {
continue;
}
@@ -272,9 +286,6 @@ function parseStubFile(string $fileName) {
function funcInfoToCode(FuncInfo $funcInfo): string {
$code = '';
- if ($funcInfo->cond) {
- $code .= "#if {$funcInfo->cond}\n";
- }
if ($funcInfo->return->type) {
$returnType = $funcInfo->return->type;
if ($returnType->isBuiltin) {
@@ -326,29 +337,42 @@ function funcInfoToCode(FuncInfo $funcInfo): string {
}
$code .= "ZEND_END_ARG_INFO()";
- if ($funcInfo->cond) {
- $code .= "\n#endif";
- }
return $code;
}
+function findEquivalentFuncInfo(array $generatedFuncInfos, $funcInfo): ?FuncInfo {
+ foreach ($generatedFuncInfos as $generatedFuncInfo) {
+ if ($generatedFuncInfo->equalsApartFromName($funcInfo)) {
+ return $generatedFuncInfo;
+ }
+ }
+ return null;
+}
+
/** @param FuncInfo[] $funcInfos */
function generateArginfoCode(array $funcInfos): string {
$code = "/* This is a generated file, edit the .stub.php file instead. */";
$generatedFuncInfos = [];
foreach ($funcInfos as $funcInfo) {
+ $code .= "\n\n";
+ if ($funcInfo->cond) {
+ $code .= "#if {$funcInfo->cond}\n";
+ }
+
/* If there already is an equivalent arginfo structure, only emit a #define */
- foreach ($generatedFuncInfos as $generatedFuncInfo) {
- if ($generatedFuncInfo->equalsApartFromName($funcInfo)) {
- $code .= sprintf(
- "\n\n#define arginfo_%s arginfo_%s",
- $funcInfo->name, $generatedFuncInfo->name
- );
- continue 2;
- }
+ if ($generatedFuncInfo = findEquivalentFuncInfo($generatedFuncInfos, $funcInfo)) {
+ $code .= sprintf(
+ "#define arginfo_%s arginfo_%s",
+ $funcInfo->name, $generatedFuncInfo->name
+ );
+ } else {
+ $code .= funcInfoToCode($funcInfo);
+ }
+
+ if ($funcInfo->cond) {
+ $code .= "\n#endif";
}
- $code .= "\n\n" . funcInfoToCode($funcInfo);
$generatedFuncInfos[] = $funcInfo;
}
return $code . "\n";