free hit counter

Friday, July 22, 2011

awk out the git hash

I'm using the first 5 of the git hash as a build number so we can get some automated traceability of developer builds around here.

git log | head | awk '/commit/ {print substr($2,0,5)}' | head -1

ain't unix great?

The first to head at the beginning saves a few milliseconds of your CPU's time by not processing the entire history, and the last call to head -1 makes sure you just get one hash back.

To coerce CMake into stuffing that into a versionInfo.h file you'll need to put the command into a two line script file as CMake execute_process doesn't support a fully piped call like this.

Labels: ,

Thursday, July 21, 2011

cmake and reswrap


profile for Rian Sanderson at Stack Overflow, Q&A for professional and enthusiast programmers

I was trying to package up some test data files into an object file so my unit tests wouldn't depend on anything external. StackOverflow was a bit of help, but I eventually pried the answer from the cryptic CMake documentation.

I solved it with reswrap and CMake, using add_custom_command and some additional dependency magic with set_property.


add_custom_command(
OUTPUT testData.cpp
COMMAND reswrap
ARGS testData.src > testData.cpp
DEPENDS testData.src
)
set_property(SOURCE unit-tests.cpp APPEND PROPERTY OBJECT_DEPENDS testData.cpp)

add_executable(app main.cpp)
add_executable(tests unit-tests.cpp)


So now testData.cpp will generated before unit-tests.cpp is compiled, and any time testData.src changes. If the command you're calling is really slow you get the added bonus that when you build just the app target you won't have to wait around for that command (which only the tests executable needs) to finish.

It's not shown above, but careful application of ${PROJECT_BINARY_DIR}, ${PROJECT_SOURCE_DIR} and include_directories() will keep your source tree clean of generated files.

Labels: ,

Tuesday, July 12, 2011

memory leak check in unit tests



I'd like to easily check for memory leaks inside my unit tests, and it seems that lots of other people want to as well, but it's not natively supported under Linux:

http://stackoverflow.com/questions/3559938/memory-leak-unit-test-c
http://stackoverflow.com/questions/169058/memory-leak-detection-while-running-unit-tests
http://stackoverflow.com/questions/2980917/c-is-it-possible-to-implement-memory-leak-testing-in-a-unit-test
http://stackoverflow.com/questions/3652028/unit-testing-memory-leaks

Score one point for Redmond, apparently this is supported in MSVC under Windows; it's even implemented in Boost::Test.

However, under Linux it looks like people who want to do this are running their unit test suite under valgrind, or compiling each unit test into its own executable and running valgrind on that.

Labels: ,

Monday, June 06, 2011

Test Driven Development




After flirting with Test Driven Development for years, I'm going whole hog into it as I begin a new project.

Right now crusing through Kent Beck's classic Test Driven Development: By Example

Labels:

Wednesday, December 08, 2010

precision timers

Trying to timestamp when USB data is received and a standard QTimer was terrible. It turns out under Windows you can get something more accurate:
QueryPerformanceCounter() solves the issue.

Sample code below for getting out the timer tick in milliseconds. I should really put this into a nice little object, but no time right now!


...
QueryPerformanceFrequency(&_TICKS_TO_MSEC);
qDebug() << _TICKS_TO_MSEC.QuadPart;
_TICKS_TO_MSEC.QuadPart= _TICKS_TO_MSEC.QuadPart / 1000;
qDebug() << _TICKS_TO_MSEC.QuadPart;
QueryPerformanceCounter(&_resetTime);
getTimeMs(); //!!!
getTimeMs(); //!!!
QTimer::singleShot(1000, this, SLOT(getTimeMs()));
...
double getTimeMs()
{
double result;

LARGE_INTEGER ticks;
QueryPerformanceCounter(&ticks);

ticks.QuadPart= ticks.QuadPart - _resetTime.QuadPart;
result= ((double)ticks.QuadPart) / ((double)_TICKS_TO_MSEC.QuadPart) ;

qDebug() << "tstamp: " << result;

return result;
}


Returns these results, showing that QTimer is accurate within 10ms.

2337968
2337
tstamp: 0.0012837
tstamp: 0.132221
tstamp: 1010.78

Labels:

Wednesday, July 29, 2009

BLD_NUM via awk or perl

Trying to grab the build number out of my autogenerated file:

#define BLD_MAJOR 1
#define BLD_MINOR 5
#define BLD_STAMP 0
#define BLD_NUM 4541
#define BLD_STR "1.05.00.4541"
#define BLD_VAL 105004541L

awk is easy:

awk '/BLD_NUM/ {print $3}'

Perl runs outside of cygwin, so I went for this instead:

perl -lane 'if ($F[1]=~/BLD_NUM/){ print $F[2];}'

Labels: ,

Friday, March 28, 2008

C99 - almost a decade later

So I know it takes a few years for standards to get into implementation, but there sure isn't much buzz about C99 these days.

The stdint.h and stdbool.h headers are great. why aren't they more prevalent?

C99 Overview

Labels:

Monday, March 24, 2008

C Style (cont)

I found the modular C style reference I was looking for:
Chapter 6 of McConnel's Code Complete

Here's a great page cataloging many other C Styles, and an interesting paper: "#ifdef considered harmful"

C and C Style Guides

Labels:

Monday, March 17, 2008

C style

I've been looking for a standard reference for C++ style C, but all I can find are old C style manuals like the venerable Indian Hill guide with its famous (and outdated) admonishment against headers including other headers.

This embedded C++ style guide makes some good points (like no #ifdefs)

Labels:

Tuesday, February 26, 2008

Type punning

After seeing the warning:
"dereferencing type-punned pointer will break strict-aliasing rules"
I got curious: What the hell is type punning?

Type Punning (from wikipedia)
In computer science, type punning is a common term for any programming technique that subverts or circumvents the type system of a programming language in order to achieve an effect that would be difficult or impossible to achieve within the bounds of the formal language.


Turns out I've been doing these kinds of hacks for ages, but didn't know there was a formal name for them! With default flags GCC does some optimizations that rely on strict aliasing of variables that type punning may break.

Labels:

Friday, February 22, 2008

decent code style guide

This is about the closest code formating document that matches with my sensibilities. I agree with 90% of it, and the 10% I don't agree with is the totally arbitrary stuff.

Framewave Development Guide

Labels:

Monday, February 04, 2008

MapReduce != RDBMS

The guys who wrote this critique on mapReduce just don't seem to understand that it's a distributed computing framework, not a relational database framework.
MapReduce: A major step backwards - The Database Column

The best rebuttle I've seen:
http://typicalprogrammer.com/programming/mapreduce/

Labels:

Saturday, January 05, 2008

bash script-fu guide

Monday, December 10, 2007

smart pointer haters?

Quite a thread on Smart pointers from 2005:
"Smart" Pointers - comp.lang.c .moderated | Google Groups

This guy, a self described Smart Pointer Hater, thinks "...they make resource tracking more difficult and obscure" In some instances, like his factory example, maybe. In most of my instances, the RIIA paradigm frees me from having to worry about leaked memory. I think there's a substantial shift to declaring more objects on the stack rather than the heap that's difficult to get used to if you come from a C background and really like your pointers.

Labels:

Saturday, September 29, 2007

allocConsole and FreeConsole

I was looking for these function names about 6 months ago, trying to make an application that, depending on command line flags, would run in GUI or CLI mode.

http://dslweb.nwnexus.com/~ast/dload/guicon.htm

Labels:

Tuesday, September 11, 2007

Object Pascal Resurected?

I have a deep fondness for Oject Pascal from my early years where I learned to write real software using Borland Delphi. Borland's infamous management disasters have all but sealed Delphi's fate, but this company RemObjects is trying to evolve their own new Object Pascal, in the spirit of Delphi, that runs on the .NET platform.


RemObjects Software: Chrome 'Joyride'

Labels:

Thursday, August 09, 2007

needle in the haystack: DLLs

Microsoft documentation is usually pretty good- if you can find the document you're looking for in amongst the thousands of other products they sell.

This basic documentation on DLLs, that I've read a hundred times in the past, was particularly hard to find this time around.

DLLs

Labels:

Monday, July 30, 2007

Use gperf for command line parsing?

I'll agree with the authors of this article that command line processing is an oft neglected block of software implementation that ends up being thrown together and regretted forever. I don't think their article's solution is completely appropriate to the problem they present, and may be leading many programmers down the path of premature optimization.

In effect they say:

Problem:
1. command line parsers are often implemented as ugly if then else if unmaintainable code
2. typical command line parsers are O(n^2) performance

Part 1 can hardly be argued with. This is just bad (tm).
Part 2 is where I take umbrage. How many programs have so many command line arguments they need to worry about O(n^2) drag on command line parsing? Compilers. EDA tools. Can you think of any others?

Now these guys are EDA tool builders, and if they'd come out and limited their scope by saying this is appropriate for some limited segment of software I'd be happy as a clam with the article. However, by including part 1 of their problem description, they imply that all software should use gperf for command line parsing.

I'd say: all software should use command line parsing library functions such as GNUgetopt(). If after everything is working and you notice performance is being dragged down, then you ought to look into new tools such as gperf.

Use gperf for efficient C/C command line processing

Labels:

Tuesday, March 27, 2007

accessing environment variables in qmake

Funny how the most common things seem to be the hardest to find information about on the information-super-highway.

I forgot how to reference environment variables in qmake, and don't have access to my super complicated build files from two lives ago.

The answer:

$$(AN_ENV_VAR)

e.g.

contains($$(USERDOMAIN), "riansanderson.com")
{
#special processing
}

Labels:

Friday, December 01, 2006

C++ foward structures

The syntax for forward declaring structs in a namespace wasn't immediatly intuitive to me.


// Bar.h
namespace MikesHax
{
class Bar {
public: Bar( int inVal );
private: int mVal; };
}

// Foo.h
// Note we don't include Bar.h
namespace MikesHax
{
class Bar;
}

class Foo { public: Foo( MikesHax::Bar const &inBar ); };


When Full Declarations Are Not Required

Labels: