#include "php_psi_stdinc.h"
#include <sys/mman.h>
#include <assert.h>
+#include <errno.h>
#include <stdarg.h>
+#include <Zend/zend_smart_str.h>
+
#include "parser.h"
/*!max:re2c*/
struct psi_parser *psi_parser_init(struct psi_parser *P, psi_error_cb error, unsigned flags)
{
if (!P) {
- P = malloc(sizeof(*P));
+ P = pemalloc(sizeof(*P), 1);
}
memset(P, 0, sizeof(*P));
P->preproc = psi_cpp_init(P);
- psi_cpp_load_defaults(P->preproc);
-
return P;
}
return NULL;
}
- if (!(fb = malloc(sizeof(*fb) + strlen(filename) + 1 + sb.st_size + YYMAXFILL))) {
+ if (!(fb = pemalloc(sizeof(*fb) + sb.st_size + YYMAXFILL, 1))) {
if (report_errors) {
P->error(PSI_DATA(P), NULL, PSI_WARNING,
"Could not allocate %zu bytes for reading '%s': %s",
return NULL;
}
- memset(fb->buffer + sb.st_size, 0, YYMAXFILL);
fb->length = sb.st_size;
- fb->file = &fb->buffer[sb.st_size + YYMAXFILL];
- memcpy(fb->file, filename, strlen(filename) + 1);
+ fb->file = zend_string_init_interned(filename, strlen(filename), 1);
return fb;
}
{
struct psi_parser_input *sb;
- if (!(sb = malloc(sizeof(*sb) + sizeof("<stdin>") + length + YYMAXFILL))) {
+ if (!(sb = pemalloc(sizeof(*sb) + length + YYMAXFILL, 1))) {
P->error(PSI_DATA(P), NULL, PSI_WARNING,
"Could not allocate %zu bytes: %s",
length + YYMAXFILL, strerror(errno));
memset(sb->buffer + length, 0, YYMAXFILL);
sb->length = length;
- sb->file = &sb->buffer[length + YYMAXFILL];
- memcpy(sb->file, "<stdin>", sizeof("<stdin>"));
+ sb->file = zend_string_init_interned("<stdin>", strlen("<stdin>"), 1);
return sb;
}
-#if 0
-static void psi_parser_register_constants(struct psi_parser *P)
-{
- zend_string *key;
- zval *val;
-
- ZEND_HASH_FOREACH_STR_KEY_VAL(&P->cpp.defs, key, val)
- {
- struct psi_impl_def_val *iv;
- struct psi_const_type *ct;
- struct psi_const *c;
- const char *ctn;
- token_t ctt;
- impl_val tmp;
- zend_string *str;
-
- ZVAL_DEREF(val);
- switch (Z_TYPE_P(val)) {
- case IS_TRUE:
- case IS_FALSE:
- ctt = PSI_T_BOOL;
- ctn = "bool";
- tmp.zend.bval = Z_TYPE_P(val) == IS_TRUE;
- break;
- case IS_LONG:
- ctt = PSI_T_INT;
- ctn = "int";
- tmp.zend.lval = Z_LVAL_P(val);
- break;
- case IS_DOUBLE:
- ctt = PSI_T_FLOAT;
- ctn = "float";
- tmp.dval = Z_DVAL_P(val);
- break;
- default:
- ctt = PSI_T_STRING;
- ctn = "string";
- str = zval_get_string(val);
- tmp.zend.str = zend_string_dup(str, 1);
- zend_string_release(str);
- break;
- }
-
- iv = psi_impl_def_val_init(ctt, NULL);
- iv->ival = tmp;
- ct = psi_const_type_init(ctt, ctn);
- c = psi_const_init(ct, key->val, iv);
- if (!P->consts) {
- P->consts = psi_plist_init((psi_plist_dtor) psi_const_free);
- }
- P->consts = psi_plist_add(P->consts, &c);
- }
- ZEND_HASH_FOREACH_END();
-}
-#endif
-
struct psi_plist *psi_parser_preprocess(struct psi_parser *P, struct psi_plist **tokens)
{
if (psi_cpp_process(P->preproc, tokens)) {
struct psi_impl_def_val *def;
struct psi_const *cnst;
struct psi_num_exp *num;
- char *name_str = malloc(name->len + sizeof("psi\\"));
+ smart_str ns_name = {0};
+ zend_string *name_str, *type_str;
+
+ smart_str_appendl_ex(&ns_name, ZEND_STRL("psi\\"), 1);
+ smart_str_append_ex(&ns_name, name, 1);
+ name_str = smart_str_extract(&ns_name);
+ type_str = zend_string_init_interned(ZEND_STRL("<eval number>"), 1);
- strcat(strcpy(name_str, "psi\\"), name->val);
num = psi_num_exp_copy(scope.macro->exp);
def = psi_impl_def_val_init(PSI_T_NUMBER, num);
- type = psi_impl_type_init(PSI_T_NUMBER, "<eval number>");
+ type = psi_impl_type_init(PSI_T_NUMBER, type_str);
cnst = psi_const_init(type, name_str, def);
P->consts = psi_plist_add(P->consts, &cnst);
- free(name_str);
+ zend_string_release(name_str);
+ zend_string_release(type_str);
}
} else {
if (psi_plist_count(scope.macro->tokens) == 1) {
struct psi_impl_type *type;
struct psi_impl_def_val *def;
struct psi_const *cnst;
- char *name_str = malloc(name->len + sizeof("psi\\"));
+ smart_str ns_name = {0};
+ zend_string *name_str, *type_str;
+
+ smart_str_appendl_ex(&ns_name, ZEND_STRL("psi\\"), 1);
+ smart_str_append_ex(&ns_name, name, 1);
+ name_str = smart_str_extract(&ns_name);
+ type_str = zend_string_init_interned(ZEND_STRL("string"), 1);
- strcat(strcpy(name_str, "psi\\"), name->val);
- type = psi_impl_type_init(PSI_T_STRING, "string");
+ type = psi_impl_type_init(PSI_T_STRING, type_str);
def = psi_impl_def_val_init(PSI_T_QUOTED_STRING, t->text);
cnst = psi_const_init(type, name_str, def);
P->consts = psi_plist_add(P->consts, &cnst);
- free(name_str);
+ zend_string_release(name_str);
+ zend_string_release(type_str);
}
}
}
++I->lines
#define NEWTOKEN(t) \
- token = psi_token_init(t, tok, cur - tok, tok - eol + 1, I->lines, I->file); \
+ if (t == PSI_T_COMMENT || t == PSI_T_WHITESPACE) { \
+ token = psi_token_init(t, "", 0, tok - eol + 1, I->lines, I->file); \
+ } else { \
+ token = psi_token_init(t, tok, cur - tok, tok - eol + 1, I->lines, I->file); \
+ } \
tokens = psi_plist_add(tokens, &token); \
if (P->flags & PSI_DEBUG) { \
fprintf(stderr, "PSI< "); \
psi_token_dump(2, token); \
}
-union int_suffix {
- char s[4];
- uint32_t i;
-};
+
+
struct psi_plist *psi_parser_scan(struct psi_parser *P, struct psi_parser_input *I)
{
bool escaped;
token_t char_width;
- PSI_DEBUG_PRINT(P, "PSI: scanning %s\n", I->file);
+ PSI_DEBUG_PRINT(P, "PSI: scanning %s\n", I->file->val);
tok = mrk = eol = cur = I->buffer;
lim = I->buffer + I->length;
error: ;
P->error(PSI_DATA(P), token, PSI_WARNING, "PSI syntax error: unexpected input (%d) '%.*s' at col %tu",
- token->type, token->size, token->text, tok - eol + 1);
+ token->type, token->text->len, token->text->val, tok - eol + 1);
psi_plist_free(tokens);
return NULL;