interned strings
[m6w6/ext-psi] / src / parser.re
index b0d390dd00cc4898d235d5bc0aea011ec520e9d8..72587f0917755df8aed11c5a805a7dc822d5811f 100644 (file)
 #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*/
@@ -66,7 +69,7 @@ struct psi_parser_input *psi_parser_open_file(struct psi_parser *P, const char *
                return NULL;
        }
 
-       if (!(fb = malloc(sizeof(*fb) + strlen(filename) + 1 + sb.st_size + YYMAXFILL))) {
+       if (!(fb = malloc(sizeof(*fb) + sb.st_size + YYMAXFILL))) {
                if (report_errors) {
                        P->error(PSI_DATA(P), NULL, PSI_WARNING,
                                        "Could not allocate %zu bytes for reading '%s': %s",
@@ -96,10 +99,8 @@ struct psi_parser_input *psi_parser_open_file(struct psi_parser *P, const char *
                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;
 }
@@ -108,7 +109,7 @@ struct psi_parser_input *psi_parser_open_string(struct psi_parser *P, const char
 {
        struct psi_parser_input *sb;
 
-       if (!(sb = malloc(sizeof(*sb) + sizeof("<stdin>") + length + YYMAXFILL))) {
+       if (!(sb = malloc(sizeof(*sb) + length + YYMAXFILL))) {
                P->error(PSI_DATA(P), NULL, PSI_WARNING,
                                "Could not allocate %zu bytes: %s",
                                length + YYMAXFILL, strerror(errno));
@@ -119,68 +120,11 @@ struct psi_parser_input *psi_parser_open_string(struct psi_parser *P, const char
        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)) {
@@ -219,15 +163,21 @@ void psi_parser_postprocess(struct psi_parser *P)
                                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) {
@@ -238,14 +188,20 @@ void psi_parser_postprocess(struct psi_parser *P)
                                                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);
                                        }
                                }
                        }
@@ -305,17 +261,17 @@ void psi_parser_free(struct psi_parser **P)
        ++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)
 {
@@ -326,7 +282,7 @@ struct psi_plist *psi_parser_scan(struct psi_parser *P, struct psi_parser_input
        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;
@@ -585,7 +541,7 @@ struct psi_plist *psi_parser_scan(struct psi_parser *P, struct psi_parser_input
 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;