Saturday, December 1, 2012

Returning Command Line Errors

When the starting of the single shot time to force the application to quit upon entering the event loop was replaced by a simple return (of 0), I realized that it should really be returning an error code if there is an error in the command line options.

To accomplish this, the processed flag in the CommandLine class was replaced with return code variable, which has three values: 0 for successfully processed command line only option, 1 for error occurred with the command line options, and -1 for no command line only options (in other words, start the GUI).  An access function was added for the return code.

The processed access function remains (so callers don't need to be modified), but now returns true if the return code variable is not negative.  A return code variable was also added to the MainWindow class along with an access function.  In the constructor, the return code is obtained from the command line instance when the GUI active flag is set to false (when the command line was processed).  The main function was modified to return this code.

By convention, a command returns a code of 0 to indicate success and any other value to indicate an error.  Some commands return a specific error code value, but here just a general error occurred code (1) is returned.  To test if this new functionality was working correctly, this command was used:
ibcp -v && echo no error
This command will output the version number followed by the "no error" message.  If the -v is replaced with an invalid option, the "no error" message will not be output.

[commit 164fb19fe8]

Friday, November 30, 2012

Qt GUI Files and CMake

Previously, new header or source files were added to the list of header and source files in the CMake build file CMakeLists.txt.  Qt form files (with the .ui extension) and header files containing the Q_OBJECT macro are handled differently.

The Q_OBJECT macro is added to any class definition that contains Qt's C++ extensions for defining signals and slots, which are class sections in additional to the normal private, public and protected sections.  These are handled by Qt's Meta-Object Compiler (moc), which produces a special MOC source file from the header file.  For mainwindow.h, the special source file produced is moc_mainwindow.cxx, which then gets compiled and linked into the program.

In the CMake build file, this is handled by the qt4_wrap_cpp command that is added as part of the Qt4 CMake module.  It is given a list of MOC source files and produces a list of MOC output source files.  This output list is then specified as a dependency to the output executable.  When a header file is included in the MOC sources list, it does not also need to be specified in the list of [normal] header files.

Qt form files are generated as an XML like language.  This file needs to be converted into a class definition (within a header file) so that it can be used by the C++ code.  These conversions are handled by Qt's User Interface Compiler (uic), which produces a special header file from the form file.  For mainwindow.ui, the special header file produced is ui_mainwindow.h, which contains the Ui_MainWindow class.  This source file is then included by the mainwinow.h header file.

In the CMake build file, this is handled by the qt4_wrap_ui command.  It is given a list of form UI files and produces a list of user interface header files.  This output list is then specified as a dependency to the output executive.

All of the generated files are placed in the CMake build directory, the same directory where the auto-generated header files (from the awk scripts) are placed.  This directory (the project binary directory) is specified in the include_directories command, so that the C++ compiler can find all of these generated files.  It is also no longer necessary to specifically check for an in-source build to not add this directory because the conflict no long exists between the system string.h header file (not used) and project string.h header file (removed).

[commit f4a35bbab6] [commit 266022803b]

Initial Main Window Implementation

The instance and running of the CommandLine class was moved from the main function to the constructor of MainWindow.  A flag was added to the MainWindow class to indicate when the GUI is active (along with an access function).  If the command line instance reports that the arguments have been processed, this flag is set to false.  Otherwise (later), the GUI is setup and this flag is set to true.

In the main function, after the MainWindow is instanced (as a local variable), if the GUI is not active, a value of 0 (indicating no error) is returned.  It is not necessary to have a single shot timer to force the event processing loop to exist immediately - simply returning before starting the event loop is sufficient.

The MainWindow class definition starts with the Q_OBJECT macro.  Essentially this allows the use of signals and slots, which is a mechanism used by Qt to allow classes to communicate with each other.  More on this later when these get implemented, but for now, the MainWindow class does not contain any of these, but will as the GUI is developed.  Details about how these Qt GUI files are built with CMake in the next post.

Thursday, November 29, 2012

Qt Application – Main Window Class

The main window of a Qt Application contains the menu bar, any tool bars, optional dock widgets, a status line and a central widget (for example, contains the main document, which for this project will contain the BASIC program).

To create the new MainWindow class, the new file wizard in QtCreator was again used.  This time the Qt type was selected under Files and Classes, and Qt Designer Form Class was selected on the right upper box, which will create both a C++ header and a source file for the new class along with Qt Designer form file.  After clicking Choose..., the wizard asks for the form template type, where Main Window was selected.  The defaults were selected for the remaining dialogs of the wizard.

The wizard sets up a simple form for main window containing a central widget, menu bar, main tool bar and a status bar.  These can be seen in the Designer window in QtCreator (edit the mainwindow.ui file, by double clicking on it in QtCreator's project file list).  For the moment, nothing will be down with this as it will remain inactive (temporarily).  More about the initial implementation of this class in the next post.

Monday, November 26, 2012

Command Line Class

To create the new CommandLine class, the new file wizard in QtCreator was used.  The wizard is started by selecting New File or Project... on the File menu.  The C++ type was selected under Files and Classes, and C++ Class was selected on the right upper box, which will create both a C++ header and a source file for the new class.

On the next dialog, the class name is entered and the wizard automatically creates the header and source file names along with the path, any of which can be changed.  A Qt base class can also be selected, but wasn't for this class.  The final dialog allow the new source files to be added to version control.  If QMake was being used, the file would be added to the QMake build file, but for CMake, this has to be done manually.

This new class now handles the version option along with using the Tester class for the test options and running the tests if specified on the command line.  The command line arguments are processed in the constructor, which sets a processed flag if the arguments result in using the command line only, or if an error occurs.  There are only command lines at the moment, so this flag is always set.  The intention is that the caller then checks this flag (via a constant access function) and if not set, the GUI will be started.

Besides the constructor, this class contains a private function for handling the version option and a function to get an output stream to the standard output device (which the output stream on the first call).  The destructor deletes this output device if it was created.  The class contains members for the program base name (no access function since it is currently only used internally), the processed flag, the output stream and a list of strings for the GPL statement.

Previously there was a function to output the GPL statement.  As part of the constructor, a list of strings is created for this statement.  The QT_TR_NOOP() macro is used (verses the tr() function) so that the strings will be found by the translation utilities.  Only if the tr() function is used later on the strings will translations be used.  This list is passed to the Tester class for output, but the tr() function is not used on the strings so they will not be translated in the test output (to make sure test results match the expected results).

The main function now creates a CommandLine instance passing the command line arguments to the constructor.  If the processed flag is set (for now it will be), a single slot timer is connected to the application quit function to force the program to quit upon entered the event processing loop.  The Tester class run function was modified to accept the GPL statement string list, which is output when appropriate.

[commit ea8e56dd68]

Sunday, November 25, 2012

String Comparisons

I realized that the various string comparisons in the code could be performed with the equality and inequality operators, which the QString class supports, instead of using the specific compare function, at least when case insensitive compares are not needed.  With C character arrays, the string compare function was needed, but that is not the case with the higher level QString class.

[commit 11ae68634b]

Saturday, November 24, 2012

Tester Class – Single Option

As the design of the command line class was being developed, I realized that the Tester class should not be looping through all of the command line arguments.  This lead to the problem mentioned at the end of the last post when other options are specified.  The current version and test options are mutually exclusive - only one should be specified.

The version option was already checking to be make it is the only option specified.  The Tester class was modified to also make sure only one of the test options are specified - there is no reason to loop through the command line arguments since the number of arguments must match the form used (either one of two arguments).  This greatly simplified the Tester code.

All the access read only Tester functions were made constant (previously missed).  A new access function was also added to return a list of valid test options, which is used by the caller to construct the usage message.

[commit 710414e4ba]

Wednesday, November 21, 2012

Tester Class

A Tester class was created to contain all the test routines - all the functions in the test_ibcp.cpp source file were put into this new class.  The class definition was put into the new test_ibcp.h header file.  The main test function was split into two functions: the constructor for the Tester class, which will be given the list of command line arguments and will be parsed for test options, and a run function that will run the testing.

Once a Tester instance is created, the caller can check the status.  There will be a function for checking if errors occurred with any command line test arguments, a function to get an error message if an error occurred, and a function to check if there were any test arguments specified.  If there are test options, the run function can then be called.

The code to initialize the static Token data, create a table instance and output any errors, and create a translator instance was moved from the main function to the tester run function along with the output of the GPL header (which is now only output if no error occurs during startup).

The main() function now only handles the command line arguments - outputting the version information if the version option was specified (if this was the only option specified), otherwise creating a tester instance, checking for test argument errors, checking if there are any tests arguments, outputting the usage message if not or running the tester if there are (outputting a message if an error occurs during the test).  If the run function returns false, an error occurred during testing (like it could not open the test file specified) and the error message access function is used to get the message to output.

The tester argument parser in the constructor loops over all arguments looking for valid test options.  It verifies that only one test argument is specified, but ignores non-test arguments.  Right now, if valid test arguments are specified, the test will be run and the program will exit.  If other options are also specified (say version or an invalid option), they are currently ignored.  This will be taken care of next with a new command line class.

[commit f70cf1fc73]

Sunday, November 18, 2012

CMake Issues

The patch release number has not been updated for recent development tags.  There needed to be way to automatically keep the release numbers in the CMake build file up to date with to release number in the git repository (which is determined from the most recent tag).

To prevent this from happening in the future, the CMake file was modified to check the release numbers to the current tag in the Git repository.  Previously, if the Git program was found, the release string was obtained from Git using the git describe command, otherwise the release string was set to the release numbers specified in the CMake file.

The CMake file was modified to instead first set the release string to the release numbers.  If the Git program is found, then its release number is obtained and put into a temporary variable.  If the Git release number was obtained (it wouldn't be if no repository is present), then a check is made to made sure the release string matches the first part of the Git release number (using the string command with the REGEX MATCH operation).  If it doesn't match, then a fatal error is produced.  This will catch a mismatch after a new tag is added if the release numbers are not also  updated before changes are pushed to GitHub.

One other minor change was made to the CMake file.  If the build type contains an empty string, it is now set to "Release" so that it is not empty.  Though technically this is the same as an empty string, at least now when CMake is run, the "Build type:" message does not show nothing.

[commit c0c027c07b]

Qt Application – Main Function

Another convention of Qt applications is that the main() function goes in the main.cpp source file, so the ibcp.cpp source file was renamed (and the CMake build file was updated).

While reviewing the CMake documentation, I discovered that there is a specific FindGit module, so it is not necessary to use the more generic find_program command.  The CMake build file was updated to use the find_package with the FindGit module (by using the Git argument).  There is no specific module for finding the Awk program, so this will remain using the generic find_program command.

Note: For now on instead of saying the changes have been pushed to GitHub, the specific commit ID (short form) will be put at the bottom of the post with a direct link to the commit on GitHub that is associated with the post (instead of a generic link to the Git repository, which is on the right under Downloads).  The post will also be given the GitHub label.  Recent posts are being updated to this convention.

I also noticed that the patch version number in the CMake file hasn't been updated for recent development tags.  This is not an issue when building from a source directory with the Git repository, but is when building from downloaded archives from GitHub.  So to set things straight going forward, tag v0.2-5 was added with the correct patch number in the CMake file.

[commit 381d30da1a]

Saturday, November 17, 2012

Qt Application – Memory Errors

A simply program was created that containing a single main() function with a QApplication instance, a single shot timer to force the program to quit and a call to the Qt event processing executive.  This simply program also had the same memory issues, so this is some sort of issue with Qt, and probably explains why the External Errors are disabled by default in the Analyzer.

The valgrind utility has an option to disable (suppress) errors from being reported.  The ‑‑gen‑suppressions=all option can be used to generate a list of errors to suppress.  These error suppressions (extracted from the output - between the sets of braces) were put into the ibcp.supp file in the test sub-directory.  The memory test script was modified with the ‑‑suppression=$dir/ibcp.supp option where $dir is set to the test sub-directory in the source directory within the script.

This error suppression file can also be added to the Analyzer in QtCreator by going to Options... in the Tools menu and going to the Analyzer options page.  In the Memory Analysis Options section, the Add... button is used to select the ibcp.supp file.  (Note: this is only for running on Linux.)

The commented static linking commands in the CMake file were removed.  Since the executable is now going to require two Qt library files, there is no longer any reason to link the MinGW libraries required by the executable statically.  All the required dynamic link libraries will be included in future releases of the binary zip file for Windows.  If I read the licensing correctly, this is permitted if the libraries were not built from custom source.

[commit  af6faac469]

Qt Application – Building

Now that the program is using the QApplication class, the QtGui component needed to be added to the find package for Qt4 command in addition to the QtCore component in the CMake file. 

Upon testing these changes, there were no differences, however, the memory test reported a number of lost memory blocks.  It was not obvious where the problem was and was just reported on the line with the QApplication app instance.  After much experimentation, the problem was caused by statically linking libgcc and libstdc++.  Without the static linking, there were no more errors - at least when using Analyzer in QtCreator.

When running the memory test script, many more memory errors were reported, again against the QApplication app instance.  These were actually being reported in Analyzer, but were not listed because they were disabled (External Errors on the funnel looking icon on the Analyzer tool bar).

A commit was made with the changes for the QApplication instance and how the command line arguments are handled.  The static linking part of the CMake build file was temporarily commented (this will be dealt with next).

[commit  01a79dda20]

Qt Application – Event Loop

The Qt event loop is started with a call to the exec() member function of QApplication.  Normally when the users requests the program to exit from the GUI, the exec() function returns.  This occurs when the quit() function is called from one of the GUI elements (for example, the close on the application windows of Exit from the File menu).

Since no GUI elements have been implemented yet including any window, somehow the quit() function needs to be called.  This is accomplished with a single shot timer initiated with the call:
QTimer::singleShot(0, &app, SLOT(quit()));
This timer times out immediately and calls the quit() slot of the QApplication instance, but fortunately this does not occur until the exec() function is called.  Once exec() is called, it immediately returns, exiting the application.

Qt Application – Command Line Arguments

Up to now, the source code has been modified to use Qt support classes, but the program is not yet a Qt application.  A Qt application has a GUI (usually though it is possible to have a command line Qt application).  A GUI application has an event processing loop, which basically means that instead of processing sequentially from start to end, it processes events when they occur such as a keyboard press or a mouse click and calling the appropriate function to carry out the selected action.

A Qt application starts by creating an instance of a QApplication (or a QCoreApplication for a command line application).  Since this project will have a GUI, a QApplication instance will be created, but no GUI will be started if either the version or a test mode options are selected on the command line.

The command line arguments, via the argc and argv arguments of main(), are passed to the QApplication constructor because there are some Qt options that can be specified on the command line.  The arguments() member function of QApplication is used to obtain a QStringList of the remaining options (with the Qt options removed).  The first string in this list is still the name of the program.  The argc and argv arguments to the various functions were changed to QStringList &args, which is set to the arguments.

Wednesday, November 14, 2012

Internationalization (Qt)

Applications developed with Qt can support internationalization meaning support for multiple languages.  While I have no intention in implementing any language other than English, the door can be left open to add additional language translations later.

This is accomplished by adding the QObject::tr() function around all constant strings that would need to be translated.  The Qt linguist utilities use this as one way to identify strings that need a translation.  The Qt widget classes inherit this function from QObject and therefore just tr() is used without the scope.  This function can also be added to classes that don't inherit from QObject by adding a macro to the beginning of the class definition:
class MyClass
{
    Q_DECLARE_TR_FUNCTIONS(MyClass)
    ...
};
So, this was added to the Token class (so tr() could be used on the token status messages) and the Parser class (so tr() could be used on the parser error messages).

The scoped form QObject::tr() was added for the version, usage, error and test strings.  However, the GPL and test output strings were not changed so that the output of the regression tests would not change (otherwise the results will not match the expected result files).  The table initialization error messages were also not changed since these are development errors and will never occur in an official release.  There are alternatives to using scoped QObject::tr() form, but these need to wait until the program is turned into a full fledge Qt application (next up).

One other minor change was made to all class, struct and enum definitions where the opening brace was moved to a separate line instead of the end of the line, which is the same format used for if, for, while, etc. statements.  The opening brace on array initializers remain at the end of the line (for now).  And two unnamed enumerations were given names.

[commit  58b55f0b51]

Monday, November 12, 2012

Constant Access Getter Functions

Class member functions that do not modify the class instance should be defined to indicate this, which is coded as a trailing const on the function inside the class definition:
class MyClass {
    int value;
    ...
public:
    int value(void) const
    {
        return m_value;
    }
    int valueSquared(void) const;
}
If the function body is defined in class source file instead in the class definition in the header file, the trailing const is also necessary:
int MyClass::valueSquared(void) const
{
    return m_value * m_value;
}
The functions in the Table, Token and Translator classes that don't modify the instances were made constant functions.  The Parser class doesn't have any non-modifying access functions.  The getToken() function was also renamed to the more consistent token().  This is a good place to create another development tag: v0.2-4.

[commit  af69957e69]