Wednesday, January 30, 2013

Retirement == Freedom

I have been retired for 7 or 8 months now and I think I am starting to get used to the new life.  Recently I have started feeling more energetic about programming.  It is different now.  In the past I was either working on a project with a specific goal in mind or generally too busy to focus on new programming projects.

Now don't get me wrong I have done some interesting, fun things as parts of several projects during the last 5 years at USM.  The difference is one of degree.  Over the years I would explore interesting things for fun, but the unpaid projects were usually somewhat small.  Now whatever I decide to do is my choice and I can generally decide when to work on it.

"Toy Box" for ebe

Since about November 19, 2012 I have been working steadily rewriting the ebe integrated development environment in C++ using the Qt toolkit for the GUI controls.  The new ebe is better in many ways than the older one which was written in Python.

One feature I have been considering was to allow beginners to enter simple expressions and evaluate them the same way that the compiler would do.  I searched for C and C++ interpreters thinking that an interpreter might make a good choice for speedy computations.  During my search I came across a Python program which does live calls to g++ to "interpret" the C++ as it is entered.  I had to wonder about the speed of the compilations.

I started by compiling hello.c and hello.cpp to see how long it took.  On my Core i7 desktop it took about 0.1 seconds for compiling hello.cpp which hello.c took about 0.06 seconds.   I copied hello.c to hello.cpp and it still required 0.06 seconds compiled with g++.  That meant that using printf would be superior for my needs over cout.  Compilations could be done in 0.6 seconds and executing the small program took about 0.002 seconds.  So perhaps I could get 16 compilations per second.

I knew enough about the C++ typeid to figure out the type of an expression, but in order to capture the data precisely I wanted to dump the data for the expression as hexadecimal.  That would allow me to capture floats and doubles exactly as they were computed in the expression.  It seemed a shame to write one program to determine the type of an expression and a second program to dump the value of the expression in hex.  So I kept searching.

Eventually I ran across the g++ typeof operator.  This would allow me to declare a variable of the exact type as an expression.   Consider the declaration below
     typeof((a+b+c)/3.0) x;
This declaration determines that the type of the expression is double and declares x as a double.  With this interesting feature it was easy to write code to declare a variable of the right type to assign the value of an expression and then, using sizeof, I could dump each byte of the variable.



Here you can see the "Toy Box" after defining 3 int variablees and evaluating some expressions.  Line 1 of the lower table shows the original type, format and result for the expression in column 1.  In the others I have used the Format combobox to select an alternative format.  This seems like a useful tool to use when learning a language.  I feel sure that a lot of teachers would enjoy illustrating how C/C++ evaluates expressions using the toybox.  This is far superior to using an interpreter which would probably approximate the syntax and the behavior,  This tool uses the compiler so what you see is what you get.

Tuesday, January 08, 2013

A simple solution to unbuffering for a debugger

A problem which I have run into recently is the fact that pipes in Windows are not recognized as interactive and thus the C standard library routines does full buffering.  I am using two pipes to implement the stdin, stdout and stderr for C/C++ programs being debugged.  My luck was great with Linux and OSX - not so good with Windows.  On Windows I had to do fflush(stdout) to see the test printed by printf.  (and also cout using \n rather than endl)  The problem exists in the library code which inspects the attached file descriptors (or handles) and decides that this is a batch type operation and buffering perhaps 4096 bytes is perfect.

The solution I came up with is to mix C and C++.  It works just fine with gcc compiling a C program and g++ compiling a C class file and finally linking the 2 object files with g++.  The trick is to take advantage of the fact that C++ constructors for static objects are called before main is called.  Fortunately they are called after the library has prepared all the I/O routines for normal use.

Here is my C++ code:


#include <cstdio>

class __UnBuffer
{
public:
    __UnBuffer();
    int x;
};

__UnBuffer::__UnBuffer()
{
    printf("Here we go\n");
    setbuf(stdout,NULL);
}

__UnBuffer _unBuffer;

The constructor is called for the one __UnBuffer object which sets the buffering to unbuffered for stdout and also prints a message.  This message was printed first in  my test and the data made it through the pipe immediately.  Surprisingly I got some 1 byte messages which I will have to accommodate in the Qt ebe, but at least I have a simple solution which works well.

I ran into other folks who were writing GUI debuggers and they seemed to have difficulties.  I am not sure how they coped, but I didn't read a solution from any of those people.  Hopefully they will run into my solution and get past this stupid issue.

Friday, January 04, 2013

Ebe with toolbars

To make ebe more colorful I have added 3 toolbars.  After adding them I think they may actually be useful, though I was only trying to make it look better.


Thursday, January 03, 2013

New and improved ebe

Recently I decided to bite the bullet and rewrite the ebe integrated development environment using Qt.  I was getting quite tired of coping with the large number of windows used in the original ebe.  I also needed to update ebe so that class and structs could be properly displayed while debugging.  It was a fairly interesting adventure.


You can see how it looks using Qt.  The various windows are now implemented using a main widget for the editing and a collection of dock widgets.  The dock widgets can be moved around and resized.  They can even be moved out of the main window if desired.  Perhaps more useful is the ability to drop dock widgets on top of each other forming a collection of tabs.  In the image above the terminal, project and back trace dock widgets are stacked making it simple to select one of the 3 to display.

The data window is now a dock widget containing a "tree" widget which has little "arrows" to the left of items which can be expanded.  You can expand class objects and arrays to drill down into the data of a program.  The tree widget turned out to be exactly what was needed to display the data.  This simplified the effort involved in revising the data display.

The terminal was previously an xterm window under Linux and a cmd.exe window under Windows.  These separate windows complicated the management of fonts.  Now you can increase or decrease the fonts in all the widgets using Control+ or Control-.

Qt had some extra capabilities which I had not expected.  There is a QCompleter class designed to aid in implementing word completion for a variety of widgets.  I used this to make editing easier.  There is a QSyntaxHighlighter class designed for implementing syntax.  I also used Qt's QTabWidget to manage editing a collection of files as tabs in the source frame.  It allows you to open all the files in a project when you start ebe.

Overall I found it easier to implement this version of ebe compared to the previous version based on Python.  It requires more effort to get started coding with Qt, but the rather large class collection ends up saving time.  It was also nice for me to use C++ which I have more experience with.

I think the program would look better with a collection of toolbars with colorful icons.  I can't think of appropriate icons for use in debugging, but I will probably add a toolbar of file/edit operations so it doesn't look so boring.