12 #include "ext/standard/info.h"
13 #include "php_scandir.h"
18 #include "validator.h"
21 ZEND_DECLARE_MODULE_GLOBALS(psi
);
24 STD_PHP_INI_ENTRY("psi.directory", "psis", PHP_INI_ALL
, OnUpdateString
, directory
, zend_psi_globals
, psi_globals
)
27 static void psi_error(int type
, const char *msg
, ...)
33 vslprintf(buf
, 0x1000, msg
, argv
);
39 static int psi_select_dirent(const struct dirent
*entry
)
42 #define FNM_CASEFOLD 0
44 return 0 == fnmatch("*.psi", entry
->d_name
, FNM_CASEFOLD
);
47 PHP_MINIT_FUNCTION(psi
)
51 struct dirent
**entries
= NULL
;
53 REGISTER_INI_ENTRIES();
57 if (!(ctx
= jit_context_create())) {
58 zend_error(E_WARNING
, "Could not initialize libjit!");
64 n
= php_scandir(PSI_G(directory
), &entries
, psi_select_dirent
, alphasort
);
66 php_error(E_WARNING
, "Failed to scan PSI directory '%s'", PSI_G(directory
));
67 } else for (i
= 0; i
< n
; ++i
) {
72 if (MAXPATHLEN
<= slprintf(psi
, MAXPATHLEN
, "%s/%s", PSI_G(directory
), entries
[i
]->d_name
)) {
73 php_error(E_WARNING
, "Path to PSI file too long: %s/%s",
74 PSI_G(directory
), entries
[i
]->d_name
);
76 if (!PSI_ParserInit(&P
, psi
, psi_error
, 0)) {
77 php_error(E_WARNING
, "Failed to init PSI parser (%s): %s",
78 psi
, strerror(errno
));
82 while (-1 != PSI_ParserScan(&P
)) {
83 PSI_ParserParse(&P
, PSI_TokenAlloc(&P
));
85 PSI_ParserParse(&P
, NULL
);
87 if (!PSI_ValidatorInit(&V
, &P
)) {
88 php_error(E_WARNING
, "Failed to init PSI validator");
93 if (PSI_ValidatorValidate(&V
)) {
96 jit_context_build_start(ctx
);
97 if (PSI_CompilerInit(&C
, &V
, ctx
)) {
98 zend_function_entry
*closures
= PSI_CompilerCompile(&C
);
100 if (closures
&& SUCCESS
!= zend_register_functions(NULL
, closures
, NULL
, MODULE_PERSISTENT
)) {
101 psi_error(E_WARNING
, "Failed to register functions!");
103 //PSI_CompilerDtor(&C);
105 jit_context_build_end(ctx
);
107 PSI_ValidatorDtor(&V
);
110 for (i
= 0; i
< n
; ++i
) {
117 PHP_MSHUTDOWN_FUNCTION(psi
)
119 jit_context_t ctx
= PSI_G(context
);
120 jit_context_destroy(ctx
);
122 UNREGISTER_INI_ENTRIES();
127 /* Remove if there's nothing to do at request start */
128 /* {{{ PHP_RINIT_FUNCTION
130 PHP_RINIT_FUNCTION(psi
)
132 #if defined(COMPILE_DL_PSI) && defined(ZTS)
133 ZEND_TSRMLS_CACHE_UPDATE();
139 /* Remove if there's nothing to do at request end */
140 /* {{{ PHP_RSHUTDOWN_FUNCTION
142 PHP_RSHUTDOWN_FUNCTION(psi
)
148 PHP_MINFO_FUNCTION(psi
)
150 php_info_print_table_start();
151 php_info_print_table_header(2, "psi support", "enabled");
152 php_info_print_table_end();
154 DISPLAY_INI_ENTRIES();
156 const zend_function_entry psi_functions
[] = {
160 zend_module_entry psi_module_entry
= {
161 STANDARD_MODULE_HEADER
,
166 PHP_RINIT(psi
), /* Replace with NULL if there's nothing to do at request start */
167 PHP_RSHUTDOWN(psi
), /* Replace with NULL if there's nothing to do at request end */
170 STANDARD_MODULE_PROPERTIES
173 #ifdef COMPILE_DL_PSI
175 ZEND_TSRMLS_CACHE_DEFINE();
185 * vim600: noet sw=4 ts=4 fdm=marker
186 * vim<600: noet sw=4 ts=4