This function won't work correctly on unsorted array because the second
part of the function (after the tags search) expects the array is sorted
by name. The only user of this is tm_source_file_set_tag_arglist() in which
we can go through the tags manually by ourselves (it needs only a single
value so the original behavior of tm_tags_find() wasn't a problem).
Eliminate the tags_search() function as it isn't needed any more.
Just cleanup, not functional change.
Do the same with struct/class/union... member tags as we do with
typenames - extract them from the edited file and merge them with
the array containing all of them so while editing, there should
be no slowdowns because one file usually doesn't contain so many
tags. This eliminates about 2s freeze when typing "." on a linux
kernel project with 2300000 tags.
Extract typename and member tags also for global tags in case someone
creates a giant tags file - this needs to be done just once when
loading the tag files.
All the remaining tm_tags_extract() in Geany are called on
file tag array only so there shouldn't be any performance problems.
This patch contains a bit too many things which are however related.
It started by the part in editor.c (where we previously used only the
first type we found to perform scoped search) by going through all the
possible variable types until the scoped search returns some result
(this is useful if variable foo is used once as int and once as struct
and if the int is the first type found, we won't get the struct's members).
This didn't work. After an hour of debugging, it turned out that
because tm_workspace_find_scope_members() calls internally
tm_workspace_find() and this function returns static array, this
invalidates the array returned by the tm_workspace_find() used
previously to get all the possible variable types.
Since this is really dangerous and hard to notice, I tried to eliminate
the static returns from both tm_workspace_find() and
tm_workspace_find_scoped_members().
The tm_workspace_find_scoped_members() function is where I got
stuck because as I started to understand what it's doing, I found
many problems there. This patch does the following in this function:
1. Eliminates search_global and no_definitions parameters because
we always search the whole workspace and this simplifies the slightly
strange logic at the end of the function.
2. Returns members from global tags even when something found in
workspace tags - previously global tags were skipped when something
was found from workspace tags but I don't see a reason why.
3. Adds the lang parameter to restrict tags by language (we do this
with normal search and the same should be done here).
4. Previously when searching for types with members the function
returned NULL when more than one such type was found (there should
have been >=1 instead of ==1 at line 906). This patch improves the
logic a bit and if multiple types are found, it tries to use the one
which is other than typedef because it probably has some members (the
typedef can resolve to e.g. int).
5. Previously the function prevented only direct typedef loops like
typedef A B;
typedef B A;
but a loop like A->B->C->A would lead to an infinite cycle. This patch
restricts the number how many times the typedef can be resolved by
using for loop with limited number of repetitions and giving up when
nothing useful is resolved.
6. Finally the patch tries to simplify the function a bit, make it
easier to read and adds some comments to make it clearer what the
function does.
They are basically identical except:
1. _scoped() compares scope in addition
2. _scoped() is missing the C/CPP tag compatibility part
3. _scoped() allows returning just single result (unused)
4. _scoped() allows not searching in global tags (unused)
Since we now always put lang also under tag->lang, the match_langs()
function is not necessary.
Extend the add_filtered_tags() (and rename it to fill_find_tags_array()) to
perform the tm_tags_find(), compare the scope and add scope
as parameter of tm_workspace_find() and eliminate tm_workspace_find_scoped()
completely.
1. Factor-out the part common to tags_array and global_tags
2. Get both C/CPP tags when either of the languages is specified (both
for global_tags and tags_array)
3. Remove unnecessary strcmp()s (tm_tags_find() should return only tags
with the specified name)
4. Various minor cleanups
`final` is not a normal keyword, as it only have a special meaning in
some specific context. So, use a special case instead of a keyword not
to break identifiers of that name.
If there was two hashes (#) in an inline comment, only the content
between the two was considered a comment.
X-Universal-CTags-Commit-ID: ee93f5b9f393e76a850cf8c894cc748a62981156
Most of the time there's no start of a string which means all the 10
strcmp()s are done for every character of the input. This is very expensive:
before this patch this function alone takes 55% of the parser time.
When comparing by character (and avoiding further comparison if the first
character doesn't match), this function takes only 11% of the parser time
so the performance of the parser nearly doubles.
In addition check for the "rb" prefix which is possible in Python 3.
Ported from universal-ctags.
The character following an '@' was dropped if it didn't start a string
literal.
This could lead to unexpected problems if '@' was valid in other
situations.
X-Universal-CTags-Commit-ID: 2e62f475af1db08850447de46f56db14ce99d2eb
See http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf 6.4.6§3.
Note: This is not exactly the upstream Universal CTags commit because
it depends on another change for adding the `enter` label, which was
then included here.
X-Universal-CTags-Commit-ID: 3b3b60c7664a321a31ec87de336fc6bda90c405e
When tested with 200000 LOC python file (created by making many copies
of scripts/create_py_tags.py), the tm_tags_remove_file_tags() function
takes about 50% of the CPU time when only this file is open. After adding
the linear path to tm_tags_remove_file_tags() it takes just about 2%. See
the comment in the patch for more details.
Add API to truncate a vString to a certain length. This doesn't support
growing the string, only shrinking it.
X-Universal-CTags-Commit-ID: 4e3d9edf2e7a8a476ff97bc678e71c3919b960f9
The previous fix, coming from [CTags bug #1988026], was incorrect if
the parent was not a root-level element, as it checked the level name
(unqualified) against the parent name (qualified).
However, there is no need to check the level name, all what counts is
the indentation level itself: if it's smaller than an existing level,
it ends it.
This fixes [CTags bug #356].
[CTags bug #1988026]: https://sourceforge.net/p/ctags/bugs/227/
[CTags bug #356]: https://sourceforge.net/p/ctags/bugs/356/
X-Universal-CTags-Commit-ID: ab91e6e1ae84b80870a1e8712fc7f3133e4b5542
Unfortunately varType is Geany-only so this patch cannot be ported to ctags.
The removal of the extra { read is not the most elegant thing but making
skipType() aware of the argList collection complicates things too much.
The tags_lang variable is set from the first tag in the found array but
the array may actually contain tags from several languages. This may
lead to two things:
1. Goto tag definition goes to a tag from a different filetype
2. Worse, the first tag is from a different language than the current file
and we get a message that no tag was found
Get lang for every tag in the array and rename tags_lang to tag_lang.
gtk_tree_store_set() becomes very slow when the tree gets bigger
because internally it calls gtk_tree_store_get_path() which counts
all the entries in a linked list of elements at the same tree level
to get the tree path.
Avoid the call of this function when not needed.
Fixing this is however only theoretically useful, as:
* no actual code paths can currently lead to it;
* even if the code actually ended up reading the uninitialized value,
it would still have a fully defined behavior as the result of the
check is irrelevant in the only case the uninitialized read can
happen.
Anyway, fix this to avoid any possible bad surprises in the future.
This makes it easier to define it consistently to what the compiler
and platform supports, and avoids having to include a special header
everywhere, which is some kind of a problem for separate libraries
like TagManager and especially Scintilla.
As we only use these macros from the source and not the headers, it
is fine for it to be defined to a configure-time check from the build
system.
Warning: Although Waf and Windows makefiles are updated they are not
tested an will probably required tuning.
The flags in this variables are used to tune the linker behavior on the
final libgeany (currently set the version information), so should only
used on really linked libraries, not Libtool helper libraries.
Checks if the compiler supports -fvisibility and the linker supports
-dynamic-list arguments and use them instead of hardcoding. The new
geany-lib.m4 also accomodates future use of Libtool versioning.
This will allow plugins to link against the core when accessing API
functions, now that the macro/struct/funcptr stuff is gone.
Also convert the helper libraries into Libtool helper libraries as
linking a shared library against static libraries is (apparently) not
portable.
Adds a new header `pluginexport.h` to put the macros in, could be
moved into an existing header (support.h?) by I didn't want to drag
a bunch of existing stuff into the source files for this one macro.
TagManager has relative include, this could be fixed by changing the
include directories for it if it's a problem. Mark the Scintilla
functions exported by re-declaring them in sciwrappers.c with the
attribute to avoid changing upstream Scintilla code.
Regression for the triple start string issue has been introduced in SVN
revision 669 (fishman git a314e11158307db84c0dadb758846b2302fe69cd) on
2008-06-11. In ctags 5.7 it did work, in 5.8 not anymore.
See also http://sourceforge.net/p/ctags/bugs/229/ for the original bug,
which led to the old fix.
The other issue with normal strings in skipEverything() is even older.