OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
-#include "php_psi_stdinc.h"
-
-#include "php_psi.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#else
+# include "php_config.h"
+#endif
-#include <dlfcn.h>
#include <fnmatch.h>
+#include <Zend/zend_smart_str.h>
+#include "php_psi.h"
#include "data.h"
+#include "dl.h"
struct psi_decl_extvar *psi_decl_extvar_init(struct psi_decl_arg *arg)
{
- struct psi_decl_extvar *evar = calloc(1, sizeof(*evar));
+ struct psi_decl_extvar *evar = pecalloc(1, sizeof(*evar), 1);
evar->arg = arg;
return evar;
struct psi_decl_extvar *evar = *evar_ptr;
*evar_ptr = NULL;
- if (evar->token) {
- free(evar->token);
- }
+ psi_token_free(&evar->token);
psi_decl_arg_free(&evar->arg);
psi_decl_free(&evar->getter);
psi_decl_free(&evar->setter);
}
bool psi_decl_extvar_validate(struct psi_data *data,
- struct psi_decl_extvar *evar, void *dl,
- struct psi_validate_stack *type_stack)
+ struct psi_decl_extvar *evar, struct psi_validate_scope *scope)
{
- if (!psi_decl_arg_validate(data, evar->arg, type_stack)) {
+ if (!psi_decl_arg_validate(data, evar->arg, scope)) {
return false;
}
evar->size = psi_decl_arg_get_size(evar->arg);
if (!evar->size) {
data->error(data, evar->arg->var->token, PSI_WARNING,
- "Failed to calculate size of symbol '%s'", evar->arg->var->name);
+ "Failed to calculate size of symbol '%s'", evar->arg->var->name->val);
return false;
}
if (!evar->sym) {
-#ifndef RTLD_NEXT
-# define RTLD_NEXT ((void *) -1l)
-#endif
-#ifndef RTLD_DEFAULT
-# define RTLD_DEFAULT ((void *) 0)
-#endif
- evar->sym = dlsym(dl ?: RTLD_DEFAULT, evar->arg->var->name);
- if (!evar->sym) {
- data->error(data, evar->arg->var->token, PSI_WARNING,
- "Failed to locate symbol '%s': %s", evar->arg->var->name,
- dlerror() ?: "not found");
- return false;
- }
+ evar->sym = psi_dlsym(data->file.dlopened, evar->arg->var->name->val,
+ evar->redir ? evar->redir->val : NULL);
+ }
+ if (!evar->sym) {
+ data->error(data, evar->arg->var->token, PSI_WARNING,
+ "Failed to locate symbol '%s': %s", evar->arg->var->name->val,
+ dlerror() ?: "not found");
+ return false;
}
evar->getter = psi_decl_extvar_getter(evar);
- if (!psi_decl_validate_nodl(data, evar->getter, type_stack)) {
+ if (!psi_decl_validate_nodl(data, evar->getter, scope)) {
return false;
}
evar->setter = psi_decl_extvar_setter(evar);
- if (!psi_decl_validate_nodl(data, evar->setter, type_stack)) {
+ if (!psi_decl_validate_nodl(data, evar->setter, scope)) {
return false;
}
return true;
}
-void psi_decl_extvar_dump(int fd, struct psi_decl_extvar *evar)
+void psi_decl_extvar_dump(struct psi_dump *dump, struct psi_decl_extvar *evar)
{
- dprintf(fd, "extern ");
- psi_decl_arg_dump(fd, evar->arg, 0);
- dprintf(fd, ";\n");
+ PSI_DUMP(dump, "extern ");
+ psi_decl_arg_dump(dump, evar->arg, 0);
+ PSI_DUMP(dump, ";\n");
}
struct psi_decl *psi_decl_extvar_setter(struct psi_decl_extvar *evar)
{
- struct psi_decl_type *func_type = psi_decl_type_init(PSI_T_VOID, "void");
+ zend_string *type_str = psi_string_init_interned(ZEND_STRS("void"), 1);
+ struct psi_decl_type *func_type = psi_decl_type_init(PSI_T_VOID, type_str);
struct psi_decl_var *func_var = psi_decl_var_copy(evar->arg->var);
struct psi_decl_arg *func = psi_decl_arg_init(func_type, func_var);
struct psi_decl_type *arg_type = psi_decl_type_copy(evar->arg->type);
struct psi_decl_arg *arg = psi_decl_arg_init(arg_type, arg_var);
struct psi_plist *args = psi_plist_init((psi_plist_dtor) psi_decl_arg_free);
struct psi_decl *decl = psi_decl_init(func, psi_plist_add(args, &arg));
+ smart_str name = {0};
+
+ zend_string_release(type_str);
+
+ func_var->pointer_level = 0;
+ func_var->array_size = 0;
- func_var->name = realloc(func_var->name, strlen(evar->arg->var->name) + sizeof("_set"));
- strcat(func_var->name, "_set");
+ smart_str_append_ex(&name, func_var->name, 1);
+ smart_str_appendl_ex(&name, ZEND_STRL("_set"), 1);
+ zend_string_release(func_var->name);
+ func_var->name = psi_new_interned_string(smart_str_extract(&name));
+
+ decl->extvar = 1;
return decl;
}
struct psi_decl_var *func_var = psi_decl_var_copy(evar->arg->var);
struct psi_decl_arg *func = psi_decl_arg_init(func_type, func_var);
struct psi_decl *decl = psi_decl_init(func, NULL);
+ smart_str name = {0};
+
+ smart_str_append_ex(&name, func_var->name, 1);
+ smart_str_appendl_ex(&name, ZEND_STRL("_get"), 1);
+ zend_string_release(func_var->name);
+ func_var->name = psi_new_interned_string(smart_str_extract(&name));
- func_var->name = realloc(func_var->name, strlen(evar->arg->var->name) + sizeof("_get"));
- strcat(func_var->name, "_get");
+ decl->extvar = 1;
return decl;
}
void psi_decl_extvar_get(struct psi_decl_extvar *evar, void *ptr)
{
- memcpy(ptr, evar->sym, evar->size);
+ if (evar->arg->var->array_size) {
+ /* arrays are passed as pointer */
+ *(void **) ptr = evar->sym;
+ } else {
+ memcpy(ptr, evar->sym, evar->size);
+ }
}
}
return false;
}
-