cpp: avoid a gazillion calls to memcpy/memmove
[m6w6/ext-psi] / src / cpp_tokiter.c
index 9ebe1915f21ea059ef07feb57a1a400cc31d5a91..f2b468eacee0cae9c7384c57dea7c95388294f09 100644 (file)
 #include "cpp.h"
 #include "parser.h"
 
-#if PSI_CPP_DEBUG > 1
 void psi_cpp_tokiter_dump(int fd, struct psi_cpp *cpp)
 {
        size_t i = cpp->index;
        struct psi_token *T;
 
-       if (i > 20) {
-               i -= 20;
+       if (i > 40) {
+               i -= 40;
        } else {
                i = 0;
        }
-       while (psi_plist_get(cpp->tokens, i, &T)) {
+       while (psi_plist_get(cpp->tokens.iter, i, &T)) {
                dprintf(fd, "PSI: CPP tokens %5zu %c ", i, cpp->index == i ? '*' : ' ');
-               psi_token_dump(fd, T);
-               if (i >= cpp->index + 10) {
+               if (T) {
+                       psi_token_dump(fd, T);
+               } else {
+                       dprintf(fd, "TOKEN deleted\n");
+               }
+               if (i >= cpp->index + 40) {
                        dprintf(fd, "PSI: CPP tokens .....\n");
                        break;
                }
                ++i;
        }
 }
-#endif
 
 void psi_cpp_tokiter_reset(struct psi_cpp *cpp)
 {
 #if PSI_CPP_DEBUG
-       fprintf(stderr, "PSI: CPP reset (%zu tokens)\n", psi_plist_count(cpp->tokens));
+       fprintf(stderr, "PSI: CPP reset -> iter.count=%zu, next.count=%zu\n",
+                       psi_plist_count(cpp->tokens.iter),
+                       psi_plist_count(cpp->tokens.next));
 #      if PSI_CPP_DEBUG > 1
        psi_cpp_tokiter_dump(2, cpp);
 #      endif
 #endif
        cpp->index = 0;
        cpp->expanded = 0;
+
+       if (cpp->tokens.next) {
+               free(cpp->tokens.iter);
+               cpp->tokens.iter = cpp->tokens.next;
+       }
+       cpp->tokens.next = psi_plist_init((psi_plist_dtor) psi_token_free);
 }
 
 bool psi_cpp_tokiter_seek(struct psi_cpp *cpp, size_t index)
 {
-       if (index < psi_plist_count(cpp->tokens)) {
+       if (index < psi_plist_count(cpp->tokens.iter)) {
                cpp->index = index;
                return true;
        }
@@ -75,7 +85,7 @@ bool psi_cpp_tokiter_seek(struct psi_cpp *cpp, size_t index)
 struct psi_token *psi_cpp_tokiter_current(struct psi_cpp *cpp)
 {
        struct psi_token *current = NULL;
-       bool found = psi_plist_get(cpp->tokens, cpp->index, &current);
+       bool found = psi_plist_get(cpp->tokens.iter, cpp->index, &current);
 
        assert(found);
 
@@ -87,118 +97,161 @@ size_t psi_cpp_tokiter_index(struct psi_cpp *cpp)
        return cpp->index;
 }
 
-void psi_cpp_tokiter_next(struct psi_cpp *cpp)
+bool psi_cpp_tokiter_add_cur(struct psi_cpp *cpp)
 {
-#if 0 && PSI_CPP_DEBUG
-       fprintf(stderr, "PSI: CPP next -> index=%zu -> index=%zu\n", cpp->index, cpp->index+1);
+       struct psi_token *cur = NULL;
+
+       if (psi_plist_get(cpp->tokens.iter, cpp->index, &cur)) {
+               struct psi_plist *tokens = psi_plist_add(cpp->tokens.next, &cur);
+
+               if (tokens) {
+                       cpp->tokens.next = tokens;
+
+#if PSI_CPP_DEBUG
+       fprintf(stderr, "PSI: CPP add_cur -> index=%zu, iter.count=%zu, next.count=%zu  ",
+                       cpp->index, psi_plist_count(cpp->tokens.iter), psi_plist_count(cpp->tokens.next));
+       psi_token_dump(2, cur);
 #endif
-       ++cpp->index;
+
+                       return true;
+               }
+       }
+
+       return false;
 }
 
-void psi_cpp_tokiter_prev(struct psi_cpp *cpp)
+bool psi_cpp_tokiter_add(struct psi_cpp *cpp, struct psi_token *tok)
 {
-#if 0 && PSI_CPP_DEBUG
-       fprintf(stderr, "PSI: CPP prev -> index=%zu -> index=%zu\n", cpp->index, cpp->index-1);
+       struct psi_plist *tokens = psi_plist_add(cpp->tokens.next, &tok);
+
+       if (!tokens) {
+               return false;
+       }
+       cpp->tokens.next = tokens;
+
+#if PSI_CPP_DEBUG
+       fprintf(stderr, "PSI: CPP add -> index=%zu, iter.count=%zu, next.count=%zu      ",
+                       cpp->index, psi_plist_count(cpp->tokens.iter), psi_plist_count(cpp->tokens.next));
+       psi_token_dump(2, tok);
 #endif
-       if (cpp->index) {
-               --cpp->index;
+
+       return true;
+}
+
+
+bool psi_cpp_tokiter_add_range(struct psi_cpp *cpp, size_t num_eles, void **eles)
+{
+       struct psi_plist *tokens;
+
+       if (!num_eles) {
+               return true;
+       }
+
+       tokens = psi_plist_add_r(cpp->tokens.next, num_eles, eles);
+       if (!tokens) {
+               return false;
        }
+       cpp->tokens.next = tokens;
+
+#if PSI_CPP_DEBUG
+       fprintf(stderr, "PSI: CPP add_range -> index=%zu, num_eles=%zu, iter.count=%zu, next.count=%zu\n",
+                       cpp->index, num_eles, psi_plist_count(cpp->tokens.iter), psi_plist_count(cpp->tokens.next));
+#endif
+
+       return true;
+}
+
+
+void psi_cpp_tokiter_next(struct psi_cpp *cpp)
+{
+#if 0 && PSI_CPP_DEBUG
+       fprintf(stderr, "PSI: CPP next -> index=%zu -> index=%zu\n",
+                       cpp->index, cpp->index+1);
+#endif
+       ++cpp->index;
 }
 
 bool psi_cpp_tokiter_valid(struct psi_cpp *cpp)
 {
 #if 0 && PSI_CPP_DEBUG
-       fprintf(stderr, "PSI: CPP valid -> index=%zu -> %d\n", cpp->index, cpp->index < psi_plist_count(cpp->tokens));
+       fprintf(stderr, "PSI: CPP valid -> index=%zu -> %d\n",
+                       cpp->index, cpp->index < psi_plist_count(cpp->tokens.iter));
 #endif
-       return cpp->index < psi_plist_count(cpp->tokens);
+       return cpp->index < psi_plist_count(cpp->tokens.iter);
 }
 
-bool psi_cpp_tokiter_del_cur(struct psi_cpp *cpp, bool free_token)
+bool psi_cpp_tokiter_del_prev(struct psi_cpp *cpp, bool free_token)
 {
        struct psi_token *cur = NULL;
-       bool deleted = psi_plist_del(cpp->tokens, cpp->index, &cur);
-       size_t count;
 
 #if PSI_CPP_DEBUG
-       fprintf(stderr, "PSI: CPP del_cur -> index=%zu, del=%d, free=%d, count=%zu ",
-                       cpp->index, (int) deleted, (int) free_token, psi_plist_count(cpp->tokens));
-       if (cur) {
-               psi_token_dump(2, cur);
-       } else {
-               fprintf(stderr, "NULL\n");
-       }
+       fprintf(stderr, "PSI: CPP del_prev -> index=%zu, iter.count=%zu, next.count\n",
+                       cpp->index, psi_plist_count(cpp->tokens.iter));
 #endif
-       if (free_token) {
-               psi_token_free(&cur);
-       }
-       count = psi_plist_count(cpp->tokens);
-       if (deleted && cpp->index >= count) {
-               if (count > 0) {
-                       cpp->index = count - 1;
-               } else {
-                       cpp->index = 0;
+
+       if (psi_plist_pop(cpp->tokens.next, NULL) && psi_plist_get(cpp->tokens.iter, cpp->index - 1, &cur)) {
+               psi_plist_unset(cpp->tokens.iter, cpp->index - 1);
+               if (free_token && cur) {
+                       psi_token_free(&cur);
                }
+               return true;
        }
-       return deleted;
-}
 
-bool psi_cpp_tokiter_del_range(struct psi_cpp *cpp, size_t offset, size_t num_eles, bool free_tokens)
+       return false;
+}
+bool psi_cpp_tokiter_del_cur(struct psi_cpp *cpp, bool free_token)
 {
-       struct psi_token **ptr;
-       bool deleted;
-
-       if (free_tokens) {
-               ptr = calloc(num_eles, sizeof(*ptr));
-       } else {
-               ptr = NULL;
-       }
+       struct psi_token *cur = NULL;
 
 #if PSI_CPP_DEBUG
-       fprintf(stderr, "PSI: CPP del_range -> index=%zu, offset=%zu, num_eles=%zu, count=%zu\n",
-                       cpp->index, offset, num_eles, psi_plist_count(cpp->tokens));
+       fprintf(stderr, "PSI: CPP del_cur -> index=%zu, iter.count=%zu, next.count=%zu  ",
+                       cpp->index, psi_plist_count(cpp->tokens.iter), psi_plist_count(cpp->tokens.next));
 #endif
 
-       deleted = psi_plist_del_r(cpp->tokens, offset, num_eles, (void *) ptr);
-
-       if (deleted) {
-               size_t count = psi_plist_count(cpp->tokens);
-
-               if (cpp->index >= count) {
-                       if (count > 0) {
-                               cpp->index = count - 1;
-                       } else {
-                               cpp->index = 0;
-                       }
-               }
-
-               if (free_tokens) {
-                       while (num_eles--) {
-                               psi_token_free(&ptr[num_eles]);
-                       }
-                       free(ptr);
+       if (psi_plist_get(cpp->tokens.iter, cpp->index, &cur)) {
+#if PSI_CPP_DEBUG
+               psi_token_dump(2, cur);
+#endif
+               psi_plist_unset(cpp->tokens.iter, cpp->index);
+               if (free_token && cur) {
+                       psi_token_free(&cur);
                }
+               ++cpp->index;
+               return true;
        }
-       return deleted;
+
+       return false;
 }
 
-bool psi_cpp_tokiter_ins_cur(struct psi_cpp *cpp, struct psi_token *tok)
+bool psi_cpp_tokiter_del_range(struct psi_cpp *cpp, size_t offset, size_t num_eles, bool free_tokens)
 {
-       struct psi_plist *tokens = psi_plist_ins(cpp->tokens, cpp->index, &tok);
+       struct psi_token *ptr;
+       size_t i;
 
 #if PSI_CPP_DEBUG
-       fprintf(stderr, "PSI: CPP ins_cur -> index=%zu ", cpp->index);
-       psi_token_dump(2, tok);
+       fprintf(stderr, "PSI: CPP del_range -> index=%zu, offset=%zu, num_eles=%zu, iter.count=%zu, next.count=%zu\n",
+                       cpp->index, offset, num_eles, psi_plist_count(cpp->tokens.iter), psi_plist_count(cpp->tokens.next));
 #endif
 
-       if (!tokens) {
-               return false;
+       for (i = offset; i < offset + num_eles; ++i) {
+               if (!psi_plist_get(cpp->tokens.iter, i, &ptr)) {
+                       return false;
+               }
+#if PSI_CPP_DEBUG
+               fprintf(stderr, "PSI: CPP del_range ->  ");
+               psi_token_dump(2, ptr);
+#endif
+               psi_plist_unset(cpp->tokens.iter, i);
+               if (free_tokens && ptr) {
+                       psi_token_free(&ptr);
+               }
        }
-       cpp->tokens = tokens;
+
+       cpp->index = i;
        return true;
 }
 
-bool psi_cpp_tokiter_ins_range(struct psi_cpp *cpp, size_t offset,
-               size_t num_eles, void **eles)
+bool psi_cpp_tokiter_ins_range(struct psi_cpp *cpp, size_t num_eles, void **eles)
 {
        struct psi_plist *tokens;
 
@@ -206,17 +259,17 @@ bool psi_cpp_tokiter_ins_range(struct psi_cpp *cpp, size_t offset,
                return true;
        }
 
-       tokens = psi_plist_ins_r(cpp->tokens, offset, num_eles, eles);
+       tokens = psi_plist_ins_r(cpp->tokens.iter, cpp->index, num_eles, eles);
+       if (!tokens) {
+               return false;
+       }
+       cpp->tokens.iter = tokens;
 
 #if PSI_CPP_DEBUG
-       fprintf(stderr, "PSI: CPP ins_range -> index=%zu, offset=%zu, num_eles=%zu, count=%zu\n",
-                       cpp->index, offset, num_eles, psi_plist_count(tokens));
+       fprintf(stderr, "PSI: CPP ins_range -> index=%zu, num_eles=%zu, iter.count=%zu, next.count=%zu\n",
+                       cpp->index, num_eles, psi_plist_count(cpp->tokens.iter), psi_plist_count(cpp->tokens.next));
 #endif
 
-       if (!tokens) {
-               return false;
-       }
-       cpp->tokens = tokens;
        return true;
 }
 
@@ -259,7 +312,7 @@ static size_t psi_cpp_tokiter_expand_tokens(struct psi_cpp *cpp,
 
                                tmp_tok = psi_token_init(old_tok->type, "", 0,
                                                target->col, target->line,
-                                               target->file ? target->file->val : "");
+                                               target->file ? target->file : zend_empty_string);
 
                                new_tok = psi_token_cat(NULL, 3, tmp_tok, old_tok, tok);
                                psi_token_free(&old_tok);
@@ -268,7 +321,8 @@ static size_t psi_cpp_tokiter_expand_tokens(struct psi_cpp *cpp,
                                exp_tokens[n - 1] = new_tok;
                        } else {
                                new_tok = psi_token_init(stringify ? PSI_T_QUOTED_STRING : tok->type,
-                                               tok->text->val, tok->text->len, target->col, target->line, target->file?:"");
+                                               tok->text->val, tok->text->len, target->col, target->line,
+                                               target->file ?: zend_empty_string);
 
                                exp_tokens[n++] = new_tok;
                        }
@@ -281,7 +335,7 @@ static size_t psi_cpp_tokiter_expand_tokens(struct psi_cpp *cpp,
                        paste = false;
                        stringify = false;
                }
-               psi_cpp_tokiter_ins_range(cpp, psi_cpp_tokiter_index(cpp), n, (void *) exp_tokens);
+               psi_cpp_tokiter_ins_range(cpp, n, (void *) exp_tokens);
                free(exp_tokens);
 
                return n;
@@ -431,15 +485,11 @@ static bool psi_cpp_tokiter_expand_call(struct psi_cpp *cpp,
 
        /* ditch arg tokens */
        psi_cpp_tokiter_del_range(cpp, start, psi_cpp_tokiter_index(cpp) - start + 1, false);
-       psi_cpp_tokiter_seek(cpp, start);
 
        /* insert and expand macro tokens */
        psi_cpp_tokiter_expand_call_tokens(cpp, target, macro, arg_tokens_list);
        psi_cpp_tokiter_free_call_tokens(arg_tokens_list, psi_plist_count(macro->sig), true);
 
-       /* back to where we took off */
-       psi_cpp_tokiter_seek(cpp, start);
-
        psi_token_free(&target);
        ++cpp->expanded;
        return true;
@@ -448,15 +498,8 @@ static bool psi_cpp_tokiter_expand_call(struct psi_cpp *cpp,
 static bool psi_cpp_tokiter_expand_def(struct psi_cpp *cpp,
                struct psi_token *target, struct psi_cpp_macro_decl *macro)
 {
-       size_t index = psi_cpp_tokiter_index(cpp);
-
        /* delete current token from stream */
        psi_cpp_tokiter_del_cur(cpp, false);
-
-       if (index != psi_cpp_tokiter_index(cpp)) {
-               /* might have been last token */
-               psi_cpp_tokiter_next(cpp);
-       }
        /* replace with tokens from macro */
        psi_cpp_tokiter_expand_tokens(cpp, target, macro->tokens);