Monday, December 31, 2012

GUI – Icons and Tool Bar

Now that the resource mechanism has been added to the project, actions can now be added to the tool bar with appropriate icons.  Contrary to what was said at the beginning of the last post, tool bar items can be text and are text if no icon has been assigned to them.  In any case, icons will be used here for the tool bar.  Also, when an action has an assigned icon, the icon also appears on the menu item in the menus.

First icons need to be assigned to the actions.  The easiest way to do this is with Designer inside QtCreator.  The icons can be assigned the same as with the MainWindow object, but it is easier to add the icons from the Action Editor tab at the bottom of Designer.  Double-clicking on the action brings up the Edit Action dialog.  The icon is added by clicking the ... button on the Icon: field line.  Appropriate icons were added to all of the actions.  To add the actions to the tool bar, the actions are simply dragged from the Action Editor to the tool bar.

Note: The icons will not be available on the
Select Resource dialog until the program has been built after the icons have been added to the resource file.

The icons were obtained from the KDE Oxygen icon set (found in the /usr/share/icons/oxygen/32x32/actions/ directory on Linux) except for the Qt icon, which was obtained from the Qt SDK.  All of the icon file names were renamed to match the menu and menu item the icon was assigned to.  The Oxygen icons can be distributed with the source code and embedded within the program as long as the program is under the LGPL (Lesser GNU Pulbic License) version 3, which this program is being developed under.

[commit a2d2675627]

GUI – Icons and Resources

The next item for the GUI is to add items to the tool bar, which has already been created, but is currently only blank.  Unlike the menu items which are text, the tool bar items are icons.  It is convenient if the icons are part of the application file and not separate files that must be included to run and must be loaded by the application.

This is accomplished by converting the icon files into C++ source files that are then compiled and linked into the application.  The Qt Resource Compiler (RCC) is used to convert the icon files to source files.  All the resources for the program are listed in an XML resource (.qrc) file.  QtCreator makes it easy to create and maintain these resource files.

To create the resource file, the new file wizard was again utilized.  Under Files and Classes the Qt item (lower-left) and Qt Resource file (upper-right) was selected.  On the next Choose the Location dialog, the Name: field was set to ibcp.qrc.  On the next Project Management dialog, the defaults were selected (which was set to git).  Once finished, QtCreator opened up a specific resources editing window.

To start simple, an application icon was given to the program, which will appear in the upper corner of the application window and on the task bar of the OS.  Up to now, a generic icon was being used (an X icon on Linux/KDE and a generic program icon on Windows).  An icon file was created by the name ibcp.png and placed in the new images sub-directory.  The image chosen and created consists of two lightning bolts, which represents the letter I, two to represent Interactive and Incremental, for the type of BASIC compiler being created.  The lightning bolt itself represents speed, since the goal of this project is to make a fast interactive BASIC compiler.

To add this new icon to the resource file, the Add button at the bottom resource editing window was clicked and Add Prefix was selected.  The Prefix: field, which defaulted to /new/prefix1 was cleared (which set it to a single slash).  The Add/Add Files was then selected, which opened a file selection dialog.  The images/ibcp.png file was selected, which added the file to the resource list.

To assign this icon file to the application, in Designer, the MainWindow object was selected (upper-right panel) and under properties (lower-right panel), the ... button was clicked for the windowIcon property, which displayed a Select Resource dialog.  The images item (left-side) was selected, which displayed the ibcp.png icon (right-side), which was selected.

To finish, the building of the resources needed to be added to the CMake build file.  Resources are handled by the qt4_add_resources command that is added as part of the Qt4 CMake module.  This command is given a list of resource files (in this case ibcp.qrc) and produces a list of resource source files that are generated by RCC.  This list of generated source files was then added to the add_executable command.

[commit ba9ee1be2a]

Sunday, December 30, 2012

GUI – Status Bar

The status bar on the bottom of the window was already automatically created when the MainWindow class was created from the new file wizard and is already being used for the menu item status tips.  Eventually program information like current line and column will be displayed on the status line along with error messages.  But for now there are a few places where messages are needed for the file operation functions, specifically when the program has been loaded or saved successfully.

[commit ea1b7585bb]

GUI – File Operations - Functions

A couple of helper functions were implemented to support the file operation functions.  The first is a function check if it is okay to continue, which checks if the file has been modified and if it has, ask if the file should be saved or the operation canceled.  This check is needed on the new, open and close program functions.

The second helper function sets a new member variable that holds the current program file path and sets the window title to the base file name of the current program file path.  The window title is set to the string "<file name>[*] ‑ IBCP" where the [*] is a placeholder for whether the file has been modified.  Qt handles this in a platform specific way.  Qt handles this in a platform specific way.  Generally on Windows and Linux, it  simple puts an asterisk after the file name, but on MAC, a dot is put in the close bubble.  If the program file path is blank, the program name is set to the "Untitled" string.

In the main window constructor, a connection was added to the edit box document's modification changed signal to the main windows set window modified slot.  Whenever the document is modified, this signal causes the file modified indicator to appear.

Two support functions were also implemented that load and save the program into or from memory, though right now they simply read and write a text file to or from the edit box document as plain text.  Eventually when a program is loaded, it will need to be parsed, translated, encoded and stored in memory.  Details of the main file operation functions can be found by clicking Continue...

[commit ea1b7585bb]

Actions/Menus – Using Designer

I discovered a much better and easier way to create actions and menus for the application without having to write all the lines of code by using Designer within QtCreator.  The UI form for the main window is opened in Designer by double-clicking on mainwindow.ui from the project files area.

Main menus are added by double-clicking on the "Type Here" text at the top of the edit area and entering the text.  Hot keys are entered by preceding the desired character with an '&' ampersand character.  The menus can be repositioned by dragging them as desired.

Menu items are added is a similar way, by selecting the main menu and again double-clicking the "Type Here" text.  Separators are added by double-clicking the "Add Separator" text.  Status tips are entered in the statusTip field on the lower-right side properties after selecting the desired action from the upper-right side object tree list.  Shortcut keys can be entered in the shortcut field in the properties area or can be entered using the Action Editor tab at the bottom of Designer.

Designer automatically names the actions with the name "actionXxx" where Xxx is the text entered for the menu item.  The under-bar character is used for spaces, so these were removed to follow the camel casing naming convention.  Qt will make connections between actions and functions automatically if the functions are named correctly.  For the menu item actions, the functions are named on_actionXxx_triggered() where actionXxx is the name of the action and triggered is the name of the signal to connect.  All of the dummy program functions were renamed to this form so that the needed connections are made automatically.

However, this does not work for connecting the actionExit triggered signal to the MainWindow::close() function, since this does not follow the automatic naming convention.  This was accomplished by using Signal & Slots Editor tab at the bottom of Designer.  A new signal/slot is added by clicking the large plus icon.  For this new entry, the Sender was set to actionExit, the Signal was set to triggered(), the Receiver was set to MainWindow, and the Slot was set to close().

The actionAboutQt action could not be setup in Designer since there is no way to connect to the application's aboutQt() function using the Signal & Slots Editor because the application object is not an available Receiver.  This was instead accomplished by adding a new on_actionAboutQt_triggered() function to MainWindow, which simply calls qApp‑>aboutQt().

Now that all the actions and menus are in the UI form for MainWindow, the action enumeration, action pointers and menu pointers were removed from the class definition.  The pointers are now contained in the Ui::MainWindow class that is automatically generated from the mainwindow.ui form file by the UIC (Qt User-Interface Compiler), which MainWindow contains a member pointer to.  Since the setupUi() function, called in the constructor, now creates the actions and sets up the menus, the createActions() and createMenus() functions are no longer needed and were removed.

[commit 46737de13d]

GUI – File Operations - Actions

To start, the EditBox will be made to handle simple text files.  Once the base GUI functionality is implemented, the process of implementing a full program editor will commence .  The first file operations to implement are new, open, save, and save as.

To create an action, several lines of code are needed, plus there needs to be a QAction pointer added to the class definition for each.  The program is going to end up with a lot of actions, so a more streamlined way of handling actions was needed.

In the MainWindow class definition, an enumeration for all actions was added.  Values will be added to this enumeration for each new action implemented.  The enumeration ends with a size of value, which is used to declare an array of QAction pointers.

In the createActions() function, a simple action information structure was added containing the action enumeration value, the name, the shortcut key sequence and the status tip string of the action.  An array of these action information structures is declared and initialized.  The size of enumeration value in the action value is used to indicate the end of the array.

A loop was added to process each element in this array, creating the QAction instance, setting its shortcut key sequence and status tip.  Not all actions will have a shortcut key sequence, so for these, the key sequence is initialized to an unknown value and no key sequence will not be set for these.

Finally all the actions are connected to their associated functions.  Unfortunately, the connection call could not be included in the loop because of the Qt SIGNAL and SLOT macros and the inability to declare a function pointer that could be added to the information array.  Plus, not all connection calls are identical (the close function returns a boolean instead of nothing and the About Qt action is connected to an application function, not a MainWindow function).  For now only dummy file operation functions were added - these will be implemented next.

[commit 8958bacc2e]

Saturday, December 29, 2012

GUI – Edit Box (Begin)

To create the new EditBox class source and header file, the new file wizard of QtCreator was again used (New File or Project... under the File menu). Under File and Classes the C++ option was selected and then C++ Class was selected to create both files and Choose... was clicked.

On the next C++ Class Wizard dialog, the Class name: was set to EditBox, Base class: was set to QTextEdit and for Type information: the Inherits QWidget option was selected.  The rest were left to the filled in defaults.  On the final Project Management dialog, git was selected to add to version control and the wizard was finished.

For now, nothing was changed in the created editbox.h and editbox.cpp files except the customary comment headers were added and the formatting was corrected to match the style of the rest of the project files.  Functionality for the EditBox class will be implemented in the commits that follow.  The sources files were also added to the CMake build file, and because the EditBox class contains QOBJECT, the editbox.h file was added to the MOC sources instead of the header files variable.

A new EditBox member pointer was added to the MainWindow class.  In the MainWindow constructor, an EditBox instance was created.  There is no need to give it a parent here because the next call to setCentralWidget() does this automatically, and makes the edit box widget the main widget of the main window.  This also means that for new there is no need to delete the EditBox instance because Qt will do this when the MainWindow instance is deleted upon the program closing.

Eventually this basic mechanism of how the single EditBox instance is maintained will change since there will be a need to have multiple edit boxes open (the plan is that subroutines and functions will be contained in their own edit boxes).  The exact interface hasn't been designed or decided yet (split windows, tabs, multiple windows, etc. are all possibilities).

[commit de0ec4eb2b]

C++ Explicit Constructors

The new EditBox class was created using QtCreator's new class wizard and I noticed that it put the explicit keyword in front of the constructor definition (it also did this with the MainWindow class).  (More about the new EditBox class in the post.)  Curious what this keyword does (which was added since I learned C++ in the early 90's), I did some research.  The explicit keyword tells the compiler not to allow implicit type conversions on constructors that take a single argument.  Consider this partial example:
class MyFloat {
    float m_value;
public:
    MyFloat(int value): m_value(value) {}
    float value(void) { return m_value; }
};

float square(MyFloat myFloat) {
    return myFloat.value() * myFloat.value();
}

MyFloat something = 47;
std::cout << square(12) << std::endl;
On the last two lines, implicit conversions occur from int to MyFloat, which are perfectly acceptable  for this simple class.  However, if the implicit conversion was not desired, the explicit keyword can be added in front of the constructor to prevent it.  The compiler will now generate errors for the last two lines above.  These lines can be rewritten to work:
MyFloat something = MyFloat(47);
std::cout << square(MyFloat(12)) << std::endl;
This is a contrived example and would probably make sense to allow the implicit conversion in this class, however, this is not the case with the classes used in this project.  Therefore, the explicit keyword was added to all the constructors that take a single argument, which included the CommandLine, Parser, Tester, Token and Translator classes.

The most glaring constructor requiring explicit was the Token constructor Token(int column = -1) that would have allowed a statement like Token token = 47;, which does not make sense (a token should not be assigned an integer).

[commit 5979939788]

Sunday, December 16, 2012

GUI – Settings and Window Title

All programs should save all of their settings upon exit and restore them so that when restarted the program starts up in exactly the way it was when it exited, because otherwise it is time consuming to set all the settings again.  Very few programs do however, but this approach will be used for this project.

Fortunately, Qt has the QSettings class to perform the saving and restoring mostly automatically.  The vendor (programmer) name and program name is provided to the constructor of the QSettings instance.  For saving, the setValue() method function is used with the name of the property to save and the value to save.  When the instance goes out of scope, the settings are saved.  For restoring, the settings are automatically read when the instance is created.  The properties are accessed with the value() method function.

The settings are stored to a platform specific location.  On Windows, this is to the registry.  On Linux, this is to a text file located in the .config directory on the user's home directory within a sub-directory for the vendor name under another sub-directory for the program name.  The file name is the program name with the .conf extension.

The settings are restored in the MainWindow constructor.  For saving, the closeEvent() function was implemented.  This function is called when a close event occurs (for example, the File/Exit menu item, the close icon, etc.) and can decide whether to accept or reject the request.  For now, the settings are saved and the event is accepted.

For now, only the position and the size of the main window is saved and restored.  These are obtained from the geometry of the MainWindow instance.  The program will now remember where it was and how big the last time the program was closed.  Additional settings will be added as the are implemented in the program.

[commit 54a5b24f69]

Saturday, December 15, 2012

GUI – Initial Actions and Menu Items

The first thing to add to the GUI are some top level File and Help menus with menu entries under them.  Menu entries are added to each top level menu using actions.  Actions can also be added to the tool bar.  For now the File menu will contain an Exit entry and the Help menu will contain the About and About Qt entries.  A separator is added before the Help menu so that Qt knows to put this menu on the right side of the menu for those styles that support this (Windows does not do this and KDE only does this for certain application appearance styles).

Actions contain information including the name of the action (an ampersand '&' is put in front of the character that is the hot key for the entry), along with an optional shortcut key, icon, and a status tip.  No icons were added to any of the entries at this time.  A connection is made from the triggered signal of each action to the function that will perform the action.

All the actions are created in the createActions() function and the menus are created in the createMenus() function, both called from the MainWindow constructor.  The about() function was moved from the private section to the private slots section of the class definition so that the connection can be made from the about action.  The temporary show() function was removed since it is no longer needed.  The size of the header for program name in the About box was reduced to match the header size in the About Qt box.

Now the GUI will start, but doesn't do much beyond the menus (see image below).  The window still has the default name given when the MainWindow class was created and there is just a generic program icon.  There is also a blank tool bar under the menu bar.  The dot or two on the left side of the tool bar allows the bar to be dragged to any side of the window and even detached from window.  Icons (via actions) will be added to the tool bar later.


[commit 16e6755c0d]

Tuesday, December 11, 2012

Initial GUI Design Plan

A plan is needed for what form the GUI will take for the program initially, especially considering that only the translator and parser are implemented (and only for a limited number of BASIC commands).  The basic GUI will consist of a menu bar, tool bar, status bar and the main editing window.

This menu bar will probably only consist of the File, Edit and Help menus to start.  The File menu will start with New, Open, Save, Save As, and Quit entries.  The Edit menu will start with Copy, Cut, and Paste entries.  The Help menu will have About and About Qt entries (the about Qt is customary for Qt applications and shows information about the version of Qt used to build the program).  The initial tool bar will have buttons for items in the File and Edit menus.

Most of the effort for this initial GUI will be in the main editing window and getting it to work for the requirements needed for the interactive nature of the interactive compiler.  Namely, the code will need to catch when the enter key is hit so that the current line can be read from the editing box, compiled (translated and encoded) and stored in internal memory.  Eventually the line will need to be recreated from the internal representation back to the original text (or close to it).

Since only the translator is currently implemented, each line entered into the editing window will be translated to the RPN (reverse polish notation) list.  The tokens of the  RPN list will be converted to text (as now by the test code) and displayed in a special area in the GUI known as a dock widget.  A dock widget can be moved and docked to any side of the main editing window, and can also be undocked from the application window.  This dock widget will use to validate correct operation of the program.

Sunday, December 9, 2012

Qt Transition – Release

The Qt transition is now complete and the implementation of the GUI can begin.  But first this is a good point to make a development release.  Release 0.2.0 was made (branch0.2 was merged to the master branch and tagged v0.2.0).

There is one issue when running the program on Windows when starting the program from Explorer.  A console window is opened underneath the GUI (About box), which is closed upon exit.  This can be removed by adding the WIN32 option to the add_executable command in the CMake build file.  However, this causes the command line options to no longer work.  This issue will be resolved later.

Archive files containing the source files and binary files (with test files) have been uploaded to SourceForge.  For Windows, there is also the ibcp‑libs.zip file that contains all the dynamic linked libraries required to run the program if the MinGW and QtSDK packages have not been installed (extract in the ibcp directory).  Linux should already have the required libraries installed.

This concludes the 0.2 development series.  Implementation of the GUI elements will now begin with the 0.3 development series.

[commit 85d28cd9e5]

GUI Preparation – About Box

Qt contains a static library function for displaying an about box, QMessageBox::about().  All that is needed is the title for the dialog and a string with the contents for the dialog window.  This string supports a limited set of HTML tags for formatting the text.  There is an OK button to close the dialog.  The creation of the about string and call to the Qt about function was put into the about() function in the MainWindow class.

The about string contains the full name of the program using the HTML header tag for emphasis.  As done in the Tester run function, the lines of GPL statement are added next.  Instead of putting the program name as the first part of the copyright line, the version string will be used instead with the string "Version" in front of it.  For the about box, the tr() function is used to translate the strings.  Since this is a preliminary about box, a placeholder for the full GUI, an italicized message stating such is added next.  This is followed by the command line usage string (modified to show all the options are optional).  An image of the about box running on Windows 7 is shown below.

So that the new about function has access to the GPL statement, version string, copyright year and usage string, the CommandLine instance was made a member variable as a pointer to the MainWindow class instead of being temporary in the constructor.  The instance is created in the constructor and deleted in the destructor.

The show() function for the QMainWindow class was temporarily reimplemented in the MainWindow class to prevent the full GUI from appearing (which is currently empty).  The reimplemented function calls the about() function and then does a single shot timer connected to the application quit function to end the program once the event process loop is entered.  Finally, a check for no command line options was added towards the beginning of the constructor to exit the constructor (which will start the GUI in the main function).

[commit 6eab34398c]

GUI Preparation – Usage String

Since for now the GUI is only going to pop up the About box and then exit, it would be nice if it included some information about how to use the program from the command line, specifically displaying the usage string that was previously output when no arguments were given (which will start the GUI).  The CommandLine class was modified to generate the usage string at the beginning of the constructor and save it in a new member variable, with a new function to access it.

Previously, the test options were obtained from the Tester instance, but this isn't created until later in the constructor and won't be created if there are no command line options (the constructor will return).  The Tester options access function didn't actually use any instance variables, so this function was made a static member function so that now an instance isn't necessary to access the test options.

[commit 3b93360cff]

GUI Preparation – Version String

One of the items needed in the About box is the version string.  Two minor changes were made to the CommandLine class so that it can provide the version string.  The previous version() function was renamed to isVersionOption() to mirror the name of the isHelpOption() function.

A new version() function was added to access the version string.  The version string is accessed from the ibcp_RELEASE_STRING definition contained in the CMake generated ibcp_config.h header file (from ibcp_config.h.in).  CMake gets the release string from either git (if the repository is present) or from variables set in the CMakeLists.txt file.  The actual version string starts at the seventh character of release string, which skips over the "release" part of the string.

An include statement could be added to whichever source file needs the release string, but keeping the include in a single source file and providing access functions to its values allows this to be updated in the future without having to change a bunch of other source files.  This also applies to the copyright year value.  The CommandLine class also provides access to the program name.

[commit 5431b8f9b4]

GUI Preparation – GPL Statement

The lines of the GPL statement was implemented as a QStringList in the CommandLine class.  The intention was to use this string untranslated for the test output (so the output matches the expected output files).  The QT_TR_NOOP() macro was used on the strings, so that the strings could be found by the Qt translation utilities.  The tr() function would be used later (by the GUI's About box), to translate strings (given the program was set up to do translations and the appropriate translation file was available).

However, this is not how the tr() function works.  The tr() function takes a constant char pointer and translates the string.  It does not accept a QString, so the scheme described above will not work.  Therefore, the GPL statement was changed from a QStringList to a const char * array, and also changed from a regular member to a static member.  The initialization of which was moved outside of the CommandLine constructor.  The variable was also appropriately prefixed with a 's_' to represent a static member.

The first line of the GPL statement requires special handling:
"%1  Copyright (c) 2010-%2  Thunder422"
Where the %1 and %2 are place holders for the program name and the current copyright year.  These were previously filled in by the CommandLine constructor when the QStringList was created.  This can only be done after the string is in a QString, in other words, after it has been translated (if it is going to be translated).

The Tester run function previously received the GPL statement (as a QStringList argument), which it simply output.  However, since the statement is now raw character strings, it will need to fill in the first line with the program name and copyright, neither of which it had access to.  These could have been added as additional arguments, but instead, the argument was changed to a CommandLine instance pointer, which has new access functions for these values.  After converting the GPL line to a QString, if at the first line, the program name and copyright year are filled in.

One other minor problem in the Tester run function was discovered and corrected with the interactive testing mode.  The "Testing Xxx..." string was being output before the GPL statement and it should have been after the statement and the "Table initialization successful" message.

[commit c25848a1829] [commit e27358a938]

Saturday, December 8, 2012

GUI Preparation

The 0.2 development series is going to conclude with the program displaying its about box and then exiting.  The GUI elements will be added in the 0.3 development series.  Before adding the about box, some modifications to existing classes are needed, which will occur over the next set of commits.  But first, this is probably a good time to create the v0.2-6 tag as there have been 11 commits since the last development tag.

The base GUI is already present in the program, which was added by default when the main window class was created by new class wizard in QtCreator.  This GUI only contains a blank menu bar, tool bar and status bar.  If it was activated, the only thing present beside the window title (with the normal minimize, maximum, close, etc. icons) would a blank window with an empty tool bar that can be docked (more on this later) on any of the four sides of the window.

However, the program is not currently activating this window because it exits with a usage message if no options were present on the command line.  The command line and tester classes need some minor modifications before the about box can be implemented, which will contain information that will be obtained from the command line class (version, GPL statement, etc.).

[commit 6f55c2ffae]

Table Initialization – Revisited

The Table class was modified to be singleton class (see November 14).  This implementation was modified.  To be consistent with the Token class, which is initialized with a static initialize() function, the Table class create() function was renamed to initialize() and changed to return nothing instead of a list of errors.

The old initialize() function, a normal private member function, was renamed to setupAndCheck() and still returns a list of errors.  Two new static functions were added to access the error list: hasErrors() to report if there were any errors detected and errorList() to return the list of errors.  Both fatally abort the program if the initialize function was not called.  The initialize function stores the error list returned by setupAndCheck() into a new static error list member variable.

The two static members, one for the pointer to the single instance and the other for the error list are now prefixed with 's_' instead of 'm_' to denote a static member as opposed to a regular member variable.  The static member variables to the Token class were also renamed with the 's_' prefix.

The new initialize function also checks if either the instance pointer is not null or if the error list is not empty to determine if the table instance was previously created or at least attempted.  When an error is found, the instance is deleted, so the instance pointer alone can't be used to determine if the instance creation was attempted.  Similarly, the new error list access functions also check if both the instance pointer is null and error list is empty to determine if there was a creation attempt.  The check for a non-empty error list was also added to the instance() access function.

The Token and Table initialize function calls were moved from the Tester run function to the main function.  This keeps the initialization in a single location.  The Tester run function still contains the check for table errors.  The error check was not moved to main because when the GUI is started, any table errors need to be reported in an error dialog box, not to the console output.  When the program is started from say an OS start menu or file browser, there is no console for these errors and the program will inexplicably fail to start.  Now work on the GUI can begin...

[commit 5c5da1f069]  [commit e0474f5144]

Standard Error Output - Oops

My job took me away from this project the past week.  In making the next set of changes, I discovered that the last commit did not compile.  During the development of the standard error output changes, the coutClose() function (which closes the current channel if open) was originally named cclose().  At the last moment, this was renamed to the more appropriate coutClose(), but in the haste to get the code committed, the code was not compiled and retested.

It has been recent policy recently make sure every commit pushed to the repository compile and test successfully, at least on the development platform (Linux).  Any problems with testing would be noted in the commit message.  The last commit failed this policy and I apologize (and worst, it went for a week in this state).

When a development tag is added, it is validated to compile and test successfully on both the Linux and Windows platform (specifically XP, though it should work on 7 also).  Again any problems are noted in the commit message.  For an actual release however, it will also be tested on the Windows 7 platform (and there should be no test issues).

[commit 4ffed94ea2]

Saturday, December 1, 2012

Standard Error Output

Command line error messages should be sent to the standard error channel; the Qt qWarning() function should not be used because these messages can be disabled.  The cout() function was modified to accept a FILE stream (channel) pointer, either stdout or stderr, with stdout the default.  The qWarning() calls were changed to cout(stderr), which made these lines cleaner because the qPrintable() function is not longer needed to output QString values.

There was also a qWarning() call in the Tester run function when table errors are detected.  These only occur when there are problems in the table entries and are followed by a qFatal() call (which terminates the program).  This qWarning() call was changed to a qCritical() call, whose messages can not be disabled.

Previously, to get the usage message, invalid arguments had to be specified.  To get the usage message without returning an error, new help options were added (either '-?' or '-h').  The usage message will be output to standard output channel when using these options, but to the standard error channel for invalid arguments.

When an error occurs in the Tester run function, like when the test file can't be opened, the standard output channel needs to be closed and the standard error channel opened to output the error message.  The new function coutClose() was added to the CommandLine class, which closes the current channel (if open), which is called before outputting the error message from the Tester instance.  The code for this function was pulled from the destructor, which was replaced with a call to the new function.

[commit e64eadee4a]

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]

Sunday, November 11, 2012

Parser Errors – Resolved

It turned that many more places needed to be tested for parser errors.  The number of tests ballooned from 112 to 301 (43 places times seven parser errors).  A commit was made with all these tests.  While working on correcting the errors, there were only really two types of parser errors, an unrecognizable character and a numerical error.  So the tests were reduced to 86 with the six possible numerical errors spread across the 43 places.

The numerical parser errors were rephrased to the "expected such-and-such" format except for the "floating point constant is out of range" error ("expected valid floating point constant" didn't seem quite appropriate).  To determine which type of parser error occurs, the data type of the token is set to Double for numeric errors (previously the data type was set to None for all errors).

Numerical parser errors should only be used only when a numeric expression is expected.  In other words, when a number constant is expected, but there is something wrong with the number, then the appropriate numeric parser error should be reported.  In this case, the error should point where in the error is detected on the constant.  However, when a non-numeric expression is expected, the error should point to the beginning of the constant.  Consider the following two numerical parser errors (missing sign or digits in the exponent):
A = B + 1.2e
A$ = B$ + 1.2.e
In the first statement, the error should point to the character following the "e" indicating that a sign or digit(s) were expected in the exponent.  However, in the second statement, the same error does not make sense (pointing to the character after the "e").  The correct error should point to the "1" saying that a string expression was expected.

The remaining parser error (unrecognizable character) was treated as a normal bad token with the proper translator error being reported so the "unrecognizable character" error should never occur.  All the parser error reporting has been corrected.  More work is expected once more commands are implemented.

[commit 885389f640] [commit 6de8df90b] [commit  82ebc0beab]

Saturday, November 10, 2012

Parser Errors – New Test

There are seven parser errors that can occur, but only two major types - an unrecognizable character error and some type of error in a numerical constant.  To test each of these seven errors, a new translator test (#14) was created for all the possible places during translation each of these errors can occur.  If no instances were missed, this is 16 places for each of the seven errors for a total of 112 test inputs.

The translator was temporarily modified to output the string "PARSER:" in front of the parser errors so they can easily be seen.  This does affect any of the current expected test results since none of the current translator tests have parser errors (an obvious oversight).

For now, the expected results for this new test contains the current output, but will be updated as these are corrected to the desired "expected such-and-such" error messages.  The numeric errors are appropriate if the translator was expecting a numerical constant (in other words, an operand), so the existing parser errors will be changed to the "expected such-and-such" format with the possible exception of the "constant is out of range" error.

Note that because of the recent changes to the regression test scripts (which now automatically detect tests), no modifications were needed to add this new test.

[commit  aa9271b8c9]