Saturday, June 23, 2012

A Macro Interlude

Or... Traversing Macro Pasting Hell

Full disclaimer: This article used to be very different but was also complete tosh. The code I wrote based on its assumptions and misinformation was working fine for days and then broke around 5 minutes after posting the article when I discovered a new use case. This new article addresses that use case and the subsequent solution

Macro pasting

The C preprocessor has a handy (if not essential) operator for pasting 2 tokens together, ##. I use it all over the place in my OOOCode project to generate class and function names, etc using macros. It can be used like this...

Now consider the following...

In this second example I have passed a macro in as an argument to the PASTE macro and as a result it does not get expanded. In order to fix this it is necessary to add a level of indirection...

As an aside, this same problem (and solution) occurs with the quoting operator, #, too.

Variadic macros and swallowing extra commas

Now it gets interesting as the pasting operator can also be used in variadic macros to swallow commas when no arguments are provided...

Handy, yeah? Well sort of. The problem is that this still exhibits the same problems as above when macros are used as arguments...

Macro pasting variadic hell

The above code does not compile as the second macro call does not get expanded. So I tried this...

I'm not sure if this would work in other environments but the C Preprocessor that comes with the OpenTV IDE doesn't swallow the comma in this case.

This gave me a big problem. I can either support macros as arguments or zero length argument lists... but not both :(

Believe me I tried a great many more constructions involving the ## operator and various indirections but to no avail. It just wasn't happening. Eventually (it was quite long time that may even have involved praying as I was a long way into my OOOCode stuff and this was pretty key) I came across a different solution involving detecting empty argument lists. Doing this is not simple and definitely not something I want to get into here, but just know that in the following example the ISEMPTY macro expands to 1 if the argument list supplied is empty or 0 if not...

For the ISEMPTY macro stuff, special thanks have to go to Jens Gustedt and this article:

http://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/

Sunday, June 17, 2012

OOOCode - Part 1

This is a continuation of the following post on Object Oriented C

Object Oriented C - Part 2

First thing is to get the existing pattern example into an OCode project and stick that up on GitHub. I don't like the default OpenTV IDE project templates as they actually require multiple Eclipse projects and due to the nature of the OpenTV hacked Eclipse cannot be built and run from a command line. This creates obvious problems when trying to set up a continuous integration environment. However for these purposes a standard OCode template will suffice.

To do this:


I created an OOOCode directory and checked out the OOOCode git repository to it.

I opened the OpenTV IDE and selected  the new OOOCode directory as the workspace location


I created a new OpenTV Project called OOOCode in the default location (pressing Finish immediately as I did not want the hello world example code)


This resulted in the following projects being created in my OOOCode directory.
  • OOOCode
  • OOOCodeDir
  • OOOCodeFlow
  • OOOCodeRes
As pictured:


To build and run the project in the OpenTV Virtual STB. 

Choose "Build All" from the "Project" menu.

Select the OOOCodeFlow project and press the Run button.

In the next dialog choose "Local OpenTV Application".


That's as much as I'm going to say about the OpenTV IDE for now but next I copied in my existing OO pattern example code and committed it to GitHub. This starting state can be found here:


Full disclosure... I did fix a couple of issues in the code i originally posted in the gists:
  • I missed a parameter in the MyClass constructor
  • I forgot that the VSTB exits when the main method exits and as such it can be difficult to check the debug output unless you put a real message loop in and wait for the quit message



Object Oriented C - Part 2

Now that I have detailed my existing pattern it's time to start working on an easier to implement/maintain replacement. To do this I need to start thinking about how to test it. After all I am fully embracing test driven development these days.

One thing I forgot of course when detailing the existing pattern is how to use it in an application. I think that part at least is pretty straight forward but just to complete the square, here's an example main.c:

So here are the tests although I haven't used the unit test framework I might use ordinarily (I didn't want to cloud the details and introduce more dependencies). Again I haven't run this code (currently working in OSx and the OpenTV IDE only runs on Windows) but as soon as I do I'll correct any mistakes found and likely add it to my previously created project in GitHub (currently lying empty)

One last thing for this post though, I thought of a better name for my project. From Object Oriented OCode we get OOOCode. That's right... Oooooo, code ;) (or Oh! Oh! Oh! Code - haven't decided)

Previous link is now almost certainly broken so here's a new one.

https://github.com/pghalliday/OOOCode

Saturday, June 16, 2012

Object Oriented C Reboot

As is normally the case I started something and then put it down and did lots of other things instead. In a rare bout of refocusing though I'm picking up the object oriented C (OCode) stuff again.

Previously I got very side tracked into setting up a perfect development environment as I would like to use at work. Something that would be compatible with automated build systems. Furthermore, I started trying to port the subversion externals pattern that I like to use for shared code to Git on GitHub - I quickly discovered that I'm still very much a Git newbie. This was not very lean of me...

So i'm rebooting. This time around I will focus on the task at hand which is to create a simple templating and/or preprocessing system for generating class and interface boiler plate for use in OpenTV applications which are exclusively written in C.

Let's start with a description of the pattern I currently use to implement classes. This part is simple and the boiler plate is not so bad.

The header:
The implementation:
Excuse any obvious errors, I just typed that out without trying to run or compile it, but i think you can get the idea - nicely encapsulated, right?

So that's all good. A little boiler plate in exposing opaque types and constructors/destructors but not so bad. The problems/challenges(/opportunities ;)) start when I try to extend this pattern with interfaces. Let's extend the example with that pattern.

The interface:
Now we can see some really obvious complexity. Just look at the length of it and it doesn't even do anything really. Immediately apparent is how much work it would be to add a new method to the interface.

  1. Add a new typedef for the method prototype
  2. Add a field to the interface structure
  3. Add an argument to the interface constructor
  4. Add a redirector method to allow the implementation to be called

It's fiddly work and potentially error prone (and this stuff can be hard to debug). The good news is that interfaces tend to be fairly stable once done as they don't contain business logic (although they may represent it I guess).

We're not finished though. The interface has to be implemented by our class for it to be useful.

Here's the new header for our class:

Notice the addition of a method to get an instance as an instance of MyInterface this is our casting convention.

Here's the new implementation of our class:

That wasn't so bad, we:

  1. Added a field to the class structure to store the interface instance
  2. Implemented the interface method
  3. Constructed an interface instance in the class constructor
  4. Destroyed the interface instance in the class destructor
  5. Added the method to implement our casting convention
Again it was fiddly though and remembering that we have to do these things in every class that implements the interface we are now exposed to following types of errors:
  • Memory leaks due to forgetting to destroy the interface
  • Strange affects from casting incorrectly in method implementations (doesn't seem likely until you remember that casts are a nightmare for hiding copy paste errors)

So let's review. We now have 3 quite complicated files that are quite hard to maintain. Particularly, changes in interfaces result in a large quantity of refactoring radiating out all over the place. Plus we have to be careful whenever we implement a new instance of an interface. And remember that this example only implements 1 interface method!

This is a barrier to using the pattern which I would like to overcome. Just writing it up took longer than I expected and I have to go out now so I guess there will be a part 2 where I actually get started on how I would like it to look and work :)

...
...
...

As an aside the work I have been doing to make OpenTV application generating and testing makefiles using make function implementations will likely be the subject of a future post. As will figuring out how to share code and resources across Git repositories/projects.

Friday, June 15, 2012

Required watching!


http://jamesshore.com/Blog/Lets-Play/

Well it might be if it weren't 197 episodes and counting but this series of videos illustrating test driven development (TDD) in Java and Eclipse are really excellent. I'm currently up to episode 25 (since yesterday... addicted!) and already I have learnt so much about:

  • writing tests up front
  • emergent design
  • AND just how magical eclipse is when it comes to generating code and refactoring in Java

I really recommend watching some of these. It starts with a completely blank application so I would go from there.

I really want some of these IDE features in the OCode development we do too. And I can see that there may be some mileage in that.

Now i can't wait for James' new series that I gladly helped fund on Kickstarter.

http://www.letscodejavascript.com/

2 things that have got me excited recently in one package - TDD and server side Javascript... Yay, Node.js!

Thursday, June 7, 2012

Error handling in C


An interesting and somewhat familiar set of macros for error handling in C:

http://c.learncodethehardway.org/book/learn-c-the-hard-waych21.html

A possible coding standard. Not with the debug flags (I hate debug builds!) but interesting all the same. I can see this approach getting rid of some of the over indentation caused by checking return values. As a coding standard though, I am resistant to always using the return value of a function as an error code... maybe I shouldn't be.

The most interesting part is that it looks and behaves like exception handling to an extent. A problem which is altogether too difficult to mess around with in C. However by stopping short of trying to automatically pass you back up the stack perhaps this does capture some of the essence (read value). A good, lean application of the 80/20 rule.

Still, to retrofit this stuff would likely fall short of being lean. Maybe I can mix it into the the Object Oriented C stuff I started working on.

Saturday, June 2, 2012

Object Oriented C

I'm waiting for virus updates to complete and the new windows GitHub client to install - why is my computer so slow today!?

Anyway a chance to write a blog post then.

I'm becoming increasingly agile :) ... no not like a cat :s

Recently I completed my certified Scrum Master and Product Owner training and we're making great progress at work putting it all into practice. It really has reinvigorated my interest in software development and once again I am reading voraciously on subjects that actually excite me (you'll maybe shake your head when you realise what those subjects are ;)). Can't remember having this feeling since I first started coding back in University.

So what's on my mind today?

Well, I've been reading Michael Feather's "Working Effectively With Legacy Code" and once again I have found an author who really does reflect, distill and reinforce what I only really knew at the back of my mind. This is great as it gives me more confidence that I'm on the right path but also provides a glimpse of where that path leads.

One place that it leads is to greater use of object oriented principles in our code.

Some background... We write software for the OpenTV middleware in C to run on digital TV set top boxes. This is not object oriented. It isn't even really C, we can't use standard libraries and have to write pretty much everything from scratch. This has included basic libraries and a lot of tools and frameworks. Our main focuses at the moment are


  • Reduce build times and complexity
  • Use more off the shelf and advanced development/debugging tools
    • There is a freely available OpenTV IDE based on Eclipse which is very useful as it also includes a set top box emulator allowing us to step through code (http://community.opentv.com)
  • Automate builds / implement continuous integration (Jenkins)
    • This conflicts with the eclipse IDE which is not good with headless builds, we've worked around this though, it just means we can't take advantage of standard OpenTV project templates. No biggy, we know what we're doing :)
  • Add a unit testing framework and increase test coverage of legacy code
  • Test driven development
    • We have the framework so we have to do this to really reap the benefits in my opinion
  • Automate tests
    • Very much a TODO - the set top box emulator does not like to run on our continuous integration server unless it is not running as a service and some one is logged on. It uses DirectX :s
  • Move away from specification documents to specification by tests.
    • We are looking at integrating Fit and FitNesse to capture business rules and automate acceptance testing

So why more OO?

Simple really. We need units to test. We need those units to be independent so that we can develop and verify them quickly. The approaches of TDD and the means of dealing with legacy code to make it more maintainable/manageable require great discipline and effort. We need to make the task less onerous. A major part of doing that is to use interfaces to break dependencies between libraries. There are other options in C (preprocessor for example) and we have to be careful about performance on our platform. But with careful application I am convinced that we will get the best mileage out of a consistent application of OO interfaces.

So today I am going to figure out a good standard pattern for implementing classes and interfaces in C. Probably using the preprocessor to do some of the hard work. Previous attempts have always resulted in a lot of unwieldy repetition that I sometimes think only I understand (making it instant legacy code!).

Ok, installs completed :) New git repository created. I wonder if I'll just end up reinventing Objective C.