Parsing issues -- C++ project with UEStudio 6.20

Parsing issues -- C++ project with UEStudio 6.20

61
Advanced UserAdvanced User
61

    Jun 09, 2007#1

    Before I file a bug report with IDM, I'm just checking here for feedback to make sure I'm not doing something stupid (or stupidly neglecting to do something necessary :) )...

    It seems that there are problems finding symbols which require searching in paths other than the one where the current CPP file resides. For example, I am developing Windows apps using the Qt libraries. So I have all of my sources and headers in one single directory divided up into two group folders: "include" and "src". This works fine ... UEStudio can find anything in any header in that directory.

    But I would also like to look up symbols in the Qt source files. So I install the sources and add the main Qt "include" directory to the main environment variables (PATH and INCLUDE), in "Compiler Options" I set "Additional Include Directories" to the Qt include directory, and I also add it to the project. I have tried adding it both as a group (i.e. virtual folder) and as a real folder.

    In one of my header files, which extends a built-in Qt class, I have an #include statement and a class definition as follows:

    Code: Select all

    #include <QtGui/QSpinBox>
    
    class AlphaSpinBox : public QSpinBox
    {
        Q_OBJECT
    
    public:
        AlphaSpinBox(QWidget *parent = 0);
    
        int valueFromText(const QString &text) const;
        QString textFromValue(int value) const;
    };
    
    This code works fine when I compile it from the command line (I'm not even talking about compilation here, just finding symbols ... so it should also work from within UEStudio).

    When I try to find the definition for "QSpinBox", it can't find it. However, now I get status messages "Parsing xxx of 2500 files..." whenever I open the program...

    I tried the following (after waiting for the parsing orgy to stop):

    1. changing the forward slash to a backslash;
    2. inserting the full path and file name of QSpinBox (which is a dummy include for other header files);
    3. inserting the full path and file name of the "real" include file inside quotes;
    4. reparsing the active CPP file after every step.

    Still, I always get the "symbol QSpinBox was not found!" status message. I'm sorry, but every compiler in the world can resolve include paths better than UEStudio! This can't be rocket science, can it??

    6,603548
    Grand MasterGrand Master
    6,603548

      Jun 10, 2007#2

      Have you verified that QSpinBox is recognized with that code as symbol at all?

      Copy that code temporarily into one of your CPP source files, save it, parse this document only and then check if QSpinBox is recognized as symbol.

      I can't give you further help, because I don't have such a header file management.
      Best regards from an UC/UE/UES for Windows user from Austria

      61
      Advanced UserAdvanced User
      61

        Jun 10, 2007#3

        Thanks, Mofi!

        I added the Qt header file to my project and it found the symbol declarations OK. But it would be nice if I could just add the Qt "include" directory in order to find them ... why should I need to add the file itself to the project? The name of the header file is available in the #include statement...and if I right-click on the #include line, it opens the right file.

        I will suggest this to IDM to be added as a new feature.

          Jun 13, 2007#4

          Well ... since nobody has said I am doing something wrong, or neglecting to do something right, I assume this is just "the way it works"... :( (or doesn't...)

          The Qt libraries have what I call "convenience" headers ... if you install only the binaries with headers, then you get one level of "convenience" headers which is designed somewhat like the STL C++ headers: there is a main include directory, and you have a file which is named without an extension which one includes in a C++ file like this:

          Code: Select all

          #include <cstring>
          
          All this header does is #include "string.h" and wrap it in the namespace "stl" (more or less). All the real symbols are contained in the file "string.h". Most likely they are in the same directory.

          Now if I add just the file "cstring" (without ".h") UEStudio still cannot find the symbols. I have to add BOTH "cstring" and "string.h". So I create a new group and just dump everything from the STL include directory into that, and everything works like it should (if they are in the same directory).

          Unfortunately, after installing the Qt from source files, this doesn't work as expected. Any header without ".h", for example "QtCore/QString", includes a file named "qstring.h" in the same directory. HOWEVER, that file has just one line which looks like this:

          Code: Select all

          #include "../../src/corelib/tools/qstring.h"
          
          So I have to hunt for THAT file and add it to the project if I want to see function parameters and IntelliSense for the QString class. This gets VERY ANNOYING if the library has about 2300 files organized in about 50 different folders.

          If anyone else has issues in this direction, PLEASE send a note to IDM with "Feature request" in the subject line requesting the following improvements to the parsing engine:

          (1) It should be sufficient to add just ONE FOLDER (either as a real folder added to the project or as a real folder added to a group) to gain access to all symbols defined in any subdirectories of that folder;

          (2) If the headers located in such a folder include other headers located in folders which are NOT subdirectories of the main folder, those should be parsed recursively;

          (3) Automatic parsing at program startup should be user configurable;

          (4) It would be nice to have auto-parsing enabled or disabled on a per-folder basis.

          Thanks.

            Jun 15, 2007#5

            In the meantime, I have discovered a few helpful things. I added the top folder containing all the source header files to a group with a filter "*.h". This seems to pull everything in; however, I don't really NEED all of the symbols, and unfortunately the Qt libraries are not wrapped in their own namespace. Wrapping all of my own non-GUI objects in appropriate namespaces helps keep the tag treeview somewhat less cluttered.

            The big disadvantage to using folders seems to be that there is no option to remove a folder from the project, but only to "Delete from Disk" (???). If I create a group folder first, then add the real folder to the group, I can remove the group without deleting anything from the disk drive. However, I can't seem to be able to remove individual subfolders from the folder without deleting them. :?:

            I'm now working on a way to create group folders for just the headers I need. I still think that if the parser would automatically recurse through the #include directives, it would make life much easier on the user/programmer.

            6,603548
            Grand MasterGrand Master
            6,603548

              Jun 15, 2007#6

              To automatically recognize the include files by the smybol parser is not so easy as it maybe looks for you because UEStudio is a general EDE not designed for only 1 specific language. The include directive is different for every language. C/C++ has a different include directive than HTML or Assembler or JavaScript or PHP. IDM would have to make the parser very intelligent to recognize also the included files in all languages and additionally know where and how to find it (get full path).

              A suggestion:

              Write a macro which runs a FindInFiles with parameter ProjFiles which searches for your include directives with results to an edit window.

              Then reformat the result to get only the names of the include files, complete the names with the full path and sort it.

              Next toggle to column mode, number the lines at start of every line and insert also the necessary equal sign between the number and the full file name of every QT header file with a regular expression search and replace.

              What you now should have is a perfect project file list for a project group. Copy this list to a user clipboard and close the results file which is not needed anymore.

              Next open your project file into an edit window. The project file should already contain a group entry named for example "QT headers". Search with the macro for this group, select it's content (= files), if there are already such files and replace it with the new list in the user clipboard.

              Clear the user clipboard, switch back to Windows clipboard, save and close the updated project file.

              Now you can run this macro whenever you think it is necessary to update the symbol list from the QT header files because you have added a new include not used before in any other source file. After macro execution run symbol reparse.

              Specify the QT header files directory to be ignored for Find In Files to avoid finding include directives in the QT header lines. Or you delete them from the find result in the edit window.


              Another idea: What about using CTags to create a list of all symbols from all QT header files and convert the CTags taglist into an auto-complete file which you specify to be used also? You need to do this only once and that would not slow down the symbol parser because then the parser would still need only to parse your project files.

              The auto-complete files are rarely used by most users. But it could be and is very helpful for progamers. Put the function headers of all standard libraries including with their parameters into an auto-complete file and you have easy access to all standard functions. If your compiler comes additionally also with an help file which contains the explanation for all functions and lists all function names in the help index, then add this help file also to UltraEdit/UEStudio and you can very easily get the help for the function you currently want to use by simply pressing the help key when the cusor is within the function name or the function name is selected.
              Best regards from an UC/UE/UES for Windows user from Austria

              61
              Advanced UserAdvanced User
              61

                Jun 15, 2007#7

                Thank you, Mofi -- your suggestion is quite beautiful, and I appreciate the time and thought you have put into it. :D

                I was also thinking about something along these lines ... after examining the project file, everything is in text format, so it should be possible to generate some kind of list of files and just copy them into the project file as text.

                After finding out how the filter works, I discovered that it doesn't take UEStudio so long to open as I thought. Unfortunately, I haven't seen an option to filter a group folder yet, and since the Qt headers are very well organized into subfolders and sub-subfolders, I will just have to deal with this by adding each needed folder separately.

                I would like to somehow set it up so that I can re-use the existing structure in the next project -- as you suggest, probably it would be easy to do with a macro to copy things from the old project file into a new one (or even from a template set up for this purpose).

                As you pointed out, some compilers can also generate a list of header dependencies -- Borland, for example, can do this. MSVC probably can, too, but I will have to find the appropriate option.

                Nochmals herzlichen Dank, und viele Grüße aus Zürich ! :D

                  Jun 16, 2007#8

                  I finally got this to work -- somewhat, anyway:

                  (1) Created a group (blue folder) called "Qt" in my project and added a few files to it so that there would be something in the project file I could recognize regarding the format of how the files are listed;

                  (2) Copied the .PRJ file to another file and changed the ending to TXT -- this is so that I can now open and edit it normally in UltraEdit without UE thinking it is a real project. Also, it might be a good idea to create a second copy as a backup;

                  (3) In a DOS console window, I navigated to the main source directory which contains the headers I need. I typed this command:

                  Code: Select all

                  dir /s/o/b *.h > headers.txt
                  This lists the files of all subdirectories and shows only the file and path wthout the other stuff which normally appears when typing just "dir". The resulting list is redirected to a new text file called "headers.txt";

                  (4) Open the copy of the project file (with TXT extension) in UltraEdit and look for the entry showing the group "Qt" and all the files. The PRJ files are somewhat the same format as Windows INI files (key/value pairs grouped under headers between "[...]":

                  Code: Select all

                  [Files - Qt]
                  0=E:\qt-msvc\qt-win-opensource-src-4.2.3\src\corelib\arch\qatomic_alpha.h
                  1=E:\qt-msvc\qt-win-opensource-src-4.2.3\src\corelib\arch\qatomic_arch.h
                  2=E:\qt-msvc\qt-win-opensource-src-4.2.3\src\corelib\arch\qatomic_arm.h
                  3=E:\qt-msvc\qt-win-opensource-src-4.2.3\src\corelib\arch\qatomic_boundschecker.h
                  4=E:\qt-msvc\qt-win-opensource-src-4.2.3\src\corelib\arch\qatomic_generic.h
                  5=E:\qt-msvc\qt-win-opensource-src-4.2.3\src\corelib\arch\qatomic_i386.h
                  ... etc. ...
                  (5) Open the file generated from the DOS "dir" command (the one I called "headers.txt"). Make sure that typing is in INSERT mode, switch to column mode, do "select all" or CTRL-A (in column mode, this should show as a thin vertical line at the left) and then type a single "=" character. This will prepend that character to every single line.

                  (6) Do "Select all" (CTRL-A) again, go to the Column menu and choose "Insert Number" with "First Number" = 0 and "Leading Zeros" = off. This will give you extra spaces for any numbers with less than three digits.

                  (7) Next, to get rid of the extra spaces, do a Find/Replace with the appropriate regular expression (Unix-style would be "^\d+ +" or "^\d+\s+" which would also find tab characters after a digit at the beginning of a line). Now you can select the entire list and copy/paste it into the copy of the project file, replacing the existing files.

                  (8 ) Rename the copy of the project file to the original .PRJ file. When UEStudio opens, it will load the project using the edited PRJ file and should take a couple of minutes to create parsing data for the additional files. The next time UEStudio opens, this will go a lot quicker because it reads in the cache which was stored in the hidden %APPDATA% folder.

                  Now all I have to do is figure out why auto-complete sometimes shows the wrong class members... :cry:

                  6,603548
                  Grand MasterGrand Master
                  6,603548

                    Jun 17, 2007#9

                    Glad to read that you have found a solution for you. Just one tip: To create a list of files you can also use the Find In Files function of UltraEdit or UEStudio. The macro line below will also create in a new edit window a list of all header files in the specified directory and all sub directories.

                    FindInFiles Recursive "Root path of the header files\" "*.h" ""

                    An empty find string in Find In Files to get a list of files is supported since UltraEdit v9.10 which means also since first version of UEStudio.
                    Best regards from an UC/UE/UES for Windows user from Austria