mirror of
https://github.com/dunglas/frankenphp.git
synced 2025-12-24 13:38:11 +08:00
* feat: add helpers to create PHP extensions (#1644) * feat: add helpers to create PHP extensions * cs * feat: GoString * test * add test for RegisterExtension * cs * optimize includes * fix * feat(extensions): add the PHP extension generator (#1649) * feat(extensions): add the PHP extension generator * unexport many types * unexport more symbols * cleanup some tests * unexport more symbols * fix * revert types files * revert * add better validation and fix templates * remove GoStringCopy * small fixes --------- Co-authored-by: Kévin Dunglas <kevin@dunglas.fr> * try to fix tests * fix CS * try some workarounds * try some workarounds * ingore TestRegisterExtension * exclude cgo tests in Docker images * fix * workaround... * race detector * simplify tests and code * make linter happy * feat(gofile): use templates to generate the Go file (#1666) --------- Co-authored-by: Alexandre Daubois <2144837+alexandre-daubois@users.noreply.github.com>
83 lines
1.8 KiB
Go
83 lines
1.8 KiB
Go
package extgen
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type PHPFuncGenerator struct {
|
|
paramParser *ParameterParser
|
|
}
|
|
|
|
func (pfg *PHPFuncGenerator) generate(fn phpFunction) string {
|
|
var builder strings.Builder
|
|
|
|
paramInfo := pfg.paramParser.analyzeParameters(fn.Params)
|
|
|
|
builder.WriteString(fmt.Sprintf("PHP_FUNCTION(%s)\n{\n", fn.Name))
|
|
|
|
if decl := pfg.paramParser.generateParamDeclarations(fn.Params); decl != "" {
|
|
builder.WriteString(decl + "\n")
|
|
}
|
|
|
|
builder.WriteString(pfg.paramParser.generateParamParsing(fn.Params, paramInfo.RequiredCount) + "\n")
|
|
|
|
builder.WriteString(pfg.generateGoCall(fn) + "\n")
|
|
|
|
if returnCode := pfg.generateReturnCode(fn.ReturnType); returnCode != "" {
|
|
builder.WriteString(returnCode + "\n")
|
|
}
|
|
|
|
builder.WriteString("}\n\n")
|
|
|
|
return builder.String()
|
|
}
|
|
|
|
func (pfg *PHPFuncGenerator) generateGoCall(fn phpFunction) string {
|
|
callParams := pfg.paramParser.generateGoCallParams(fn.Params)
|
|
|
|
if fn.ReturnType == "void" {
|
|
return fmt.Sprintf(" %s(%s);", fn.Name, callParams)
|
|
}
|
|
|
|
if fn.ReturnType == "string" {
|
|
return fmt.Sprintf(" zend_string *result = %s(%s);", fn.Name, callParams)
|
|
}
|
|
|
|
return fmt.Sprintf(" %s result = %s(%s);", pfg.getCReturnType(fn.ReturnType), fn.Name, callParams)
|
|
}
|
|
|
|
func (pfg *PHPFuncGenerator) getCReturnType(returnType string) string {
|
|
switch returnType {
|
|
case "string":
|
|
return "zend_string*"
|
|
case "int":
|
|
return "long"
|
|
case "float":
|
|
return "double"
|
|
case "bool":
|
|
return "int"
|
|
default:
|
|
return "void"
|
|
}
|
|
}
|
|
|
|
func (pfg *PHPFuncGenerator) generateReturnCode(returnType string) string {
|
|
switch returnType {
|
|
case "string":
|
|
return ` if (result) {
|
|
RETURN_STR(result);
|
|
} else {
|
|
RETURN_EMPTY_STRING();
|
|
}`
|
|
case "int":
|
|
return ` RETURN_LONG(result);`
|
|
case "float":
|
|
return ` RETURN_DOUBLE(result);`
|
|
case "bool":
|
|
return ` RETURN_BOOL(result);`
|
|
default:
|
|
return ""
|
|
}
|
|
}
|