Archive for May, 2010

Keyword substitution with Subversion

May 28, 2010

It’s a cumbersome task to keep the revision number, last-changed date and last-modified-by information of a source file up-to-date. That’s what subversion keyword substitution is for.

How it works:
You add special fields to your file comment, like $Author$. This is my default C++ header comment:

/**
*
* \brief Short description of the purpose of this file
*
* @copyright Copyright (c) 2010 me
* @author Original Author: me
* @author Last changed: $Author$
* @date Creation date: 2010-05-28
* @date Last changed: $Date$
* @version $Revision$
*
*/

When you add and commit this file, nothing will happen to the special fields enclosed in dollar signs. First, you have to add them to the subversion property “keywords”. To do so with ToroiseSVN, right click and open the file’s propertys and go to the subversion tab. Select svn:keywords from the drop-down list and enter something like “Date Author Revision” on the edit line. You can also select multiple files and change the property for all of them at once. Your next commit will show the auto-updated fields.

For a description of all possible keywords, look here.

Advertisements

Visual Studio: Collapse Solution Explorer

May 27, 2010

Now this comes in handy if you are driven mad by VS 2005’s behavior to expand all project files in the solution explorer after you build a project:

Visual Studio Macro: Collapse Solution Explorer.

Setting Makefile variables on command line

May 27, 2010

Usually you write something like VARNAME=value within a Makefile to define a make variable. You can also set this when you call make. For example the ADTF Makefiles set ENABLE_DEBUG to true by default. When I want to build an ADTF example filter for release, I call make with:


make ENABLE_DEBUG=false

Controlling issue trackers from your version control system

May 27, 2010

I’ve been looking around for issue trackers and this is a short summary on how to control issues from commit comments.

Trac:
see #Nr – reference an issue (comment shows up in history of the ticket with that number)
fixes #Nr – automatically closes a “bug” ticket with that number
closes #Nr – automatically closes a “feature request” ticket with that number

Redmine:
for referencing issues: refs, references, IssueID
for fixing issues: fixes, closes
example: This commit refs #1, #2 and fixes #3

Mantis:
Has to be configured by a regular expression.
Could be issue, bug #id for referencing and fixes, closes #id etc. for fixing issues.

Some more notes on these systems:
Trac (current version 0.12) requires python with setuptools and Genshi, one DBMS (SQLite, PostgreSQL or MySQL) and the svn repository (one per Trac installation) has to exist on the same server as the Trac.
Redmine (current version 0.95, 1.0 coming soon) is based on Ruby on Rails, and works at least with mysql/pgsql/sqlite as DBMS. SVN binaries have to be installed on the machine running the redmine, but the SVN server can exist somewhere else.
Mantis (current version 1.3) is based on PHP and is proven to work with MySQL/PGsql/MS SQL or DB2, but not SQLite. The SVN server can reside on a different machine.
While Mantis and Trac SVN integration seems to work via a post-commit hook only, Redmine also allows to update SVN information periodically (e.g. cron-job) or on demand.

Indentation of XML documents

May 19, 2010

A nice way to auto-indent your XML documents is via the free editor Notepad++.

Load your XML document, then navigate the menu
TextFX -> TextFX HTML Tidy -> Tidy: Reindent XML

The preconfigured HTML tidy also does some other fixes on your XML code, e.g. converting special characters to ampersand notation and word wrapping at 69 characters. To disable those, you have to alter the TIDYCFG.INI file in folder “plugins\Config\tidy” in your Notpad++ program directory. Add a new configuration like this:

[Tidy: Reindent XML]
input-xml:yes
indent:yes
wrap:0
wrap-sections:no

Look at the Tidy project page for a list of all HTML tidy attributes.

Libxml2 and Python on Windows

May 19, 2010

For the purpose of using XPath and XQuery out of my python scripts for test statistics generation, I decided to try libxml2. I mostly decided against ElementTree because their website told me the XPath subset does not support queries like:


count(//event[evalresult/text()="FALSE"][warnlevel/text()="1"])

Also, I hope to be faster with the C-based implementation of libxml2. For installation, I only had to download this pre-bundled lxml windows binary from the python package repository; it comes with libxml2 included.

The following code is enough to get the above count:

from lxml import etree
doc = etree.parse(filePath)
result = doc.xpath('//event[evalresult/text()="FALSE"][warnlevel/text()="1"]')
count = len(result)
count2 = doc.xpath(count('//event[evalresult/text()="FALSE"][warnlevel/text()="1"]')) # alternative

About XQuery: lxml serves as frontend for libxml2 and libxslt, neither of which support XQuery.

Further information:
lxml homepage
SketchPath, a good XPath expression evaluation software

Python Pitfalls: References to the same dictionary

May 18, 2010

Today, I tried to build a dictionary which contains the contents of a list as keys and empty dictionarys as values. First, I went with the method dict.fromkeys(seq, [value]), then I filled the sub-dictionaries in a for loop, like this:

mydict = dict.fromkeys(lstLabels, {})
for strLabel in dict.keys():
    mydict[strLabel][strLabel] = "x"

What I ended up with was that the sub-dictionaries referenced by the keys from lstLabels all referenced to the same dictionary instance. What this means is, that whenever you add something to dict[lstLabels[0]], it appears in dict[lstLabels[1]], too, and so on.

The correct way to accomplish what I wanted – different instances of subdirectories – was this:

    for strLabel in lstLabels:
        mydict[strLabel] = {}
        mydict[strLabel][strLabel] = "x"

Apparently, the dict.fromkeys() method does something like lstFail = [[] * 3]

Are there more elegant ways to create a dictionary with subdictionarys based on a list of strings than the one presented?

Installing Python packages with easy_install

May 17, 2010

Python comes with a nice tool called easy_install that enables you to install additional packages as easy as:

easy_install <package_name>

If you are behind a HTTP proxy server, this might fail unless you specify the proxy URL in the environment variable HTTP_PROXY like this:

set http_proxy=”http://www.myproxy.org&#8221;

However, when you are sitting behind a firewall (like we at my company are), you might still not be able to download any packages from the python package repository. Here’s a quick guide how to circumvent the issue:

  1. Create a folder on your local machine that will contain all packages you have to download.
  2. Go to http://pypi.python.org/simple/ and download the package you want to install into your local folder.
  3. In the scripts directory of your python installation, call:
    easy_install -H none -f d:\Backup\Programs\python-packages <package_name>
  4. When you disallow all foreign hosts with “-H none”, easy_install will not be able to fetch any packages your package depends on, so you have to resolve all dependency errors by repeating step 1 – 3 for the missing package if easy_install gives you a message like this:
    “No local packages or download links found for logilab-common>=0.49.0”

Another solution I found on the internet would be to install and use ASProxy, but I’m not going to try that for now.

See also: easy_install guide

Hello world!

May 17, 2010

This blog shall serve as my personal cue card collection for solutions I came up with in my daily work as a programmer. Since information is there to be shared, I decided to make this collection public by creating this blog.

So long,

Arwed