Tuesday, 24 July 2012

Experimenting with Cgo - Part 4: C Macros

One of the most frustrating parts of working on Goncurses is the fact that ncurses increasingly uses more and more macros. C macros cause a lot of problems for cgo, which isn't all that surprising, because C macros can cause a lot of problems period.

In order to circumvent C macros you have to provide proper C function wrappers around them. Depending on the library you are trying to port, this could be quick and simple or it could be long and tedious. I will demonstrate a very simple example.

1. You will need to create three files: a go wrapper, a C header and a C source file. The two C files must share the same name.

2. Identify the macro you need to create a wrapper for. For the purpose of this example we will be using a macro called MY_MACRO. In your header file, write a function prototype for the wrapper.

int my_macro_wrapper(const int x);

3. In the C source file, write a definition for the function prototyped in your header which calls the macro you are wrapping.

int my_macro_wrapper(const int x)
{
return MY_MACRO(x);
}

4. In your .go file you will need to include your wrapper header and then wrap the C file in a go function.

// #include "macro_wrapper.h"
import "C"
...
C.my_macro_wrapper(2)

That's all there is to it!

In the complete, trivial example below you'll notice I used the macro to call another function. You might think it a good idea to circumvent the macro altogether and simply call my_function() directly in Go. While this would probably work, and certainly would in this example, it defeats the purpose for why the author of the C library used a macro in the first place. There are several reasons why this could be a bad idea and I recommend using the C API as the author intended.

Complete sources follow:

***
macro_wrapper.h:
***

int my_function(const int x);


#define MY_MACRO(x) my_function(x)


int my_macro_wrapper(const int x);


***
macro_wrapper.c
***

#include "macro_wrapper.h"


int my_function(const int x) 
{
return x;
}


int my_macro_wrapper(const int x) 
{
return MY_MACRO(x);
}


***
library_wrapper.c
***

package main


// #include "macro_wrapper.h"
import "C"


import "fmt"


func main() {
// Uncomment the following line to produce error
// fmt.Println(C.MY_MACRO(2))
fmt.Println(C.my_macro_wrapper(2))
}


Sunday, 10 June 2012

Like Python, like Go

Long ago I vowed I would learn Python. Yet, despite a little dabbling in the past I've never actually dove right into it. Well, now I have and I must say I love it. You might think that I'll be talking about specific features and compare them both but I'm not going to. There's enough of that sort of thing already. Instead, this probably will read like a love letter.

Python's similarity to Go borders on the uncanny. I consider it flattering to Python that that this is the case. Both are fantastic to work with. Slices, great built-in abstract data types, well documented standard libraries and a forced coding style are all reasons I like these two languages. They are so similar that I've even forgotten which language I've been programming in and start using braces in Python and colons in control structures in Go. Thankfully, I don't have to choose between the two languages because I don't think I could. Go is best suited to server programs and system daemons. Python is fantastic for user level applications. Of course, there is a great deal of overlap and cross pollination between the two but that's how I define it.

If you are new to programming I would happily recommend learning either language but, due to the youth of Go, I would probably give the nudge to Python. There is a tremendous amount of introductory material, a plethora of third-party libraries, and a ridiculous amount of other online resources for Python. These will likely come with time for Go, and they are, but its far too young to have the support you would get with Python. After learning Python, however, transitioning to Go will be a breeze. Like Python, it is a terse, well formatted, and powerful language.

Outside of each of their respective third-party libraries, Python is almost a write once, run anywhere language just as Go is almost a write once, compile anywhere language. That is one thing about C that drives me crazy. I hate always having to use tons of boiler plate to conditionally do things depending on the operating system or compiler I'm using to build my application. Its wonderful to know that something I commit to one of my projects will work without modification on any architecture and operating system supported by the language.

That's not to say these languages are perfect. There are things I don't like about both. I prefer the static typing of Go. I prefer how I can run Python scripts directly from the shell without needing to install a third party utility. I prefer compile time error checking in Go. I prefer how I can use the Python shell to interactively run programs and use the interpreter as a calculator. I prefer Go's get program for installing libraries from source. I like how minor changes to the source code, simple things like changes in the doc strings, don't require having to be recompile the work to take advantage of them (via godoc).

Anyway, this is a long winded way of saying that I really like Python and I am glad I've added it to my tool-kit as I intend to continue using it for a long time to come! Hopefully, it won't be so long between posts again. I am going to be learning Scheme and following the SICP soon. I am very happy to see the 1980's lectures up on MIT's OCW site and look forward to watching them!


Saturday, 21 January 2012

Build Google Go on Windows

** Important Note: The Go team now provides a Windows port of Go. This is the recommended way of installing Go on that platform but I will leave this here as an exercise to whomever would prefer to install Go this way. **

I've seen countless posts requesting a Windows port of Go. For quite some time there hasn't been one available but, thankfully, there is an experimental port available. However, as it turns out, you can also compile it yourself without waiting for someone else to do it for you. This gives you the advantage of always having an up-to-date version of Go by having immediate access to the latest release without having to wait for a build, or even using the weekly release. In order to do this, we'll need MinGW.

So, without further adieu, here is a step by step installation procedure to start using Go on Windows.

1) Install Msys and MinGW. You will need a POSIX compliant shell in order to build Go. I'm sure Cygwin would also be capable of building Go but I prefer Msys. For anyone new to Msys, or unfamiliar with using the CLI, I would recommend using the GUI installer. As per the golang documentation, you'll need to make sure you install the following tools: gcc,  glibc or some other C standard library, Bison, Make and Awk. All of these tools are available via the apt-like mingw-get tool. If you forget to download one of these tools during installation, don't worry. The mingw-get tool is accessible from within Msys.

2) Install Mercurial. Here you have two choices. One, you can try and build Mercurial from source on MinGW or you can do the sensible thing and download the Windows version. I highly recommend doing the latter. You can also get TortoiseHg if you require a GUI but if your only intention is to use it to download Go then I wouldn't bother. It's much simpler just using the CLI.

3) Open the Msys terminal. Assuming all is right with the world you will be in your home directory. You should now be able to use the following command, as taken from the Golang installation guide:

$ hg clone -u release https://go.googlecode.com/hg/ go

4) Change to the go/src directory and run all.bash.

$ cd go/src
$ ./all.bash

5) If all goes well, Go is now installed and ready to go! That's it! I recommend creating a .bashrc file and add the recommended environmental variables. Something simple like:

$ cat > ~/.bashrc << EOF
# .bashrc
export GOROOT="$HOME/go"
export PATH="$PATH:$GOROOT/bin"
EOF
$ . ~/.bashrc

Msys does not come with any kind of editor installed (not even ed). Vim is available through the repositories via mingw-get or you can just use your normal text editor for Windows to edit the file. There are plenty of other things you might wish put into your .bashrc, too, but that is beyond the scope of this article. If you installed Msys into the default installation directory, you would save it in "C:\MinGW\msys\1.0\<username>\.bashrc" where <username> is replaced with your name. Obviously.

I should mention that on my first attempt on building Go, the build script hung while trying to compile gprof. Sadly, I didn't have the presence of mind at the time to record on which file it got stuck on, so there's not much I can do to see if this is a Go or MinGW/Msys bug. Irregardless, I had to force-quit Msys by closing the window because no other method would unlock the process. Re-running the all.bash script a second time completed successfully and finally reported that, "ALL TESTS PASSED!" Now THAT is what I wanted to hear! Or, in this case, see.

You should now be able to use the Go tools from the 'cmd' shell but in order for the shell to find it you will need to manually adjust your %PATH% environmental variable in Windows, too. A simple way to do this on Windows 7 is to open the start menu, right-click on 'Computer' and select properties. Then, click the 'Advanced Settings' link on the left to open the advanced settings window. A button near the bottom of the window will allow you to alter your PATH variable. A simple search can show you how to do it on other versions of windows or via an alternate method.

And that, as they say is that. A native Windows build of Go. Provided you adjust some environmental variables, as noted in the 'Getting Started' documentation for Go, you are free to relocate the go tree to another location like "C:\Program Files (x86)". You may also want to build the 'hello world' application as an extra sanity test. You can install a Go IDE or add Go syntax highlighting to your favourite editor.

Sunday, 8 January 2012

A Path to Python

I've always liked the saying, "The only truly stupid person is the one who has nothing left to learn." I have no idea who said it, or if I even have the quote right, but it's always stuck with me. So, I am always trying to learn new programming techniques and new languages.

Call it a fault of mine but I always learn the best when I'm enjoying what I'm learning. I know I don't stand alone in that. So, I've discovered that when I'm going to learn a new language I need to know more about it first; and, to really know a language you have to see it in action. Feature's really don't mean a lot unless the language "speaks" to you. So, I always browse the source code of some applications written in the language. I always take a look at a minimal "hello, world" application, too.

Python has been recommended to me in the past on several occasions but I've never really paid it much interest. My first hang up was the need for the Python interpreter. I didn't like the idea that a user of my product would have to install the Python VM just to use my application. I prefer an all-in-one package and bundling Python with the installer would increase an installer's size dramatically. Of course, there are other solutions but at the time that's how I saw it. I was also worried that Python was very slow. Maybe, at the beginning, it was slow but in relation to what? Will the speed difference even matter or be noticeable? And is that still the case? For application level programming it would probably be a complete non-issue but, again, I couldn't see that at the time.

Go also challenged my programming dogmas. For example, take dynamic linking. I had grown to believe that dynamically linking libraries (not to be confused with dynamic loading) was the only way to go. I just couldn't wrap my head around why anyone would ever use static linking (make sure to follow the links at the bottom of the page) and chalked it up as the old, antiquated way of doing things. How wrong was I? Both methods of linking have advantages and disadvantages and I can certainly appreciate why Go does much of it's linking statically.

Go does struggle with a couple issues and one of the big ones is shared with C. Because most third-party libraries utilized by Go are linked to C libraries portability becomes an issue. I've been looking for a "write-once, run-anywhere" solution ever since writing my first non-trivial application. There is only one platform that immediately jumps out at me to fit that bill: Java.

Initially, I thought Java might be a great language. It's C-like, the JVM is installed on most platforms, and has a huge collection of libraries built right in! Unfortunately, despite it's many strengths, I didn't enjoy programming in the language. My feelings about Oracle aside, I felt that it is very, very verbose. Take even a simple "Hello World!" program for example:


class HelloWorld {
  static public void main( String args[] ) {
    System.out.println( "Hello World!" );
  }
}


Now, compare that to Go:


package main
import "fmt"
func main() {
  fmt.Printf("Hello World\n")
}


And, finally, Python:


print "Hello World"


As I began to work with the language I started to feel like it was more of a patched together, band-aid solution, mess. Don't get me wrong, Java is a decent language but it just doesn't work for me. C is painful enough to program in, Java seems to be worse. Thankfully, other avenues to the JVM platform exist.

I considered Clojure, Jython, Groovy and Scala. I want to learn to learn a LISP-ish language at some point so I thought Clojure may work. After looking at some source code and documentation for the other languages, the only one which spoke to me was Jython. Python + the JVM? How can you go wrong?

Documentation for Jython is somewhat lacking if you don't already know Python. Good thing there's an easy solution to that. The Jython documentation is good for learning how it differs from Python and how to utilize the JVM, and Java, from within Jython but not much on learning the language itself. So? Learn Python.

My first observation has been that it is remarkably similar to Go. Go has clearly been heavily influenced by Python and I feel right at home with it. It does differ from Go in several distinct ways but it's turning out to be a completely fantastic language and I can see why so many programmers are using it. It's expressive, concise and an altogether eloquent language.

Time is important to me. I have precious little of it. So getting bogged down with nonsense is something I do my best to avoid. Python, like Go, does away with a lot of the nonsense and let's you get down to producing functional projects. I can see myself working with it a lot in future projects and I look forward to that time. I think, too, it will help me bridge the mental gap with being able to work in a LISP-like language.

After learning the basics of Python I then started to work with Jython. The amount of time it took for the Jython interpreter to load took me aback. I had gotten used to how quickly the Python interpreter loaded. I then discovered that Jython is based on Python 2.5. Not only is it two CPython releases old (as of this writing CPython 2.7 is the current stable 2.x branch) but Python 3 has also been released. While this hasn't proved to be particularly handy-capping thus far I am worried about the future of Jython as it falls further and further behind it's parent project. I am also concerned about it's speed. Is the slowness of it's interpreter indicative of the language itself? I suppose time will tell, literally.

Monday, 28 November 2011

Creating a Treeview in Glade

Preface: This was one of the first articles I wrote for my blog but never published it. I can't say why but I didn't. It's quite old and it's a little embarrassing. I figure I may as well post it though since it might just help another Glade/GTK+ newbie out there!


Disclaimer: This article assumes you have an understanding of how to implement the Model/View/Controller methodology of a GTK+ treeview. It is also intended for GTK+ 2.xx but may still be applicable to GTK+ 3.xx.

It seems like every day I program I am reminded about how much more I have to learn. Some days, like the name of my blog suggests, I feel like I have no idea what I'm doing. Or more appropriately, what I'm doing wrong. Take for example, a few nights several months ago.

I was continuing the process of converting the user interface for Vocab Builder from a C source code implementation to a gtk-builder xml user interface via Glade. Glade makes designing and maintaining a user interface a dream when it's behaving properly. I am using the latest version of Glade (3.8.0 at the time of writing) on Ubuntu 10.10 Maverick Meerkat and I have experienced a few problems. One of them is a real show-stopper. Literally. Somehow the widget tree gets corrupted and isn't displayed properly. Some widgets are just blank lines where the widget should be or are a garbled mess. If that happens, and you click on the place where the widget SHOULD be, Glade crashes. No warnings, just straight back to the desktop. All unsaved work is lost. Good times! The only work-around is to not click on the spot and instead find the widget (if you can) in your UI and click on it, hoping all the while that it's a visible widget because if its a vbox or adjustment widget you might be out of luck. A work around is to restart Glade. Closing the UI file and re-opening it may fix the issue too, I don't know.

Creating more than just the treeview widget seems to be a relatively new feature to Glade which might explain some of its oddities. First of all, how you add columns isn't exactly clear. Unlike other widgets, there's no treeview subcategory in the tools section where you can click on a category and easily add it to the treeview as a child widget. No sirree, you have to right-click on the treeview widget and select Edit. Okay, fine. Not a big deal. An odd design but whatever. How about a cell renderer? There is absolutely no visual clue that tells you how to add one. What you have to do is go into the Hierarchy tab, where you add new columns, and right-click on each column and select Add. Again, it sort of makes sense but with how easy it is to implement other widgets you would think there would be some kind of a clue like a button or tooltip which would indicate how you add a renderer. At least the Hierarchy tab had an Add button that let you know you could add something to it. View and controller done. What about the model?

Well, there's a property for the treeview where you can select the model to attach to it. It pops up a handy window that allows you to either select a tree model you've already created or, if you haven't created one yet, you can click New and Glade will create one for you. By default, Glade gives you a ListStore. This is where my problems began. I didn't clue in that it was a ListStore that was created by default. To be fair, Glade does call the model ListStore1 or something like that. I just never picked up on it. So I edited the model and put in the values I needed to store in the model. Uh-oh, what's this? Another stumbling block? Where's the string type? There MUST be a string type...Nope, can't find one! As it turns out, while a string is TYPE_STRING in GDK in Glade its called a gchararray. Yes, a string is a character array. So...why change what its called? Why not gstring? Oh...maybe that's why? G-string? Naw...must be another reason. Maybe just to piss me off? Either way, off I went and re-ran Vocab Builder to see if my changes were working. Yup, the treeview headers are clickable and the sort indicators look like they work. It does almost everything I want sans a few options I haven't implemented, yet. However, when selecting New in the Editor the ability to sort by columns disappears. What the heck? What's going on? After hours of trying to solve the issue, nothing. Bah! "I'll fix it tomorrow."

Here it is tomorrow the following day and I'm still not sure what's going on with the treeview so I start converting the Builder interface to get my mind off the Editor. Turns out I use a treeview in the preferences window, too. I can't escape these darned treeviews! Well, I decide to take another stab at it. I go through all the steps, forgetting how to do some of them and getting frustrated again, but I muddle through it. In my original code, I simply removed the old model and created a new one whenever I needed to update the treeview because it would always be new data. However, I realized that I could do away with all that if I just cleared the old treeview. Hrm...why isn't it working? It says it's not a TreeStore...I stared blankly at the screen in consternation. Ya, right, it's not. Its a ListStore. Ohhhh....what an idiot I am! I quickly convert my functions to use that of a ListStore and viola! Everything works as intended! Fantastic! Now, what if I want a TreeStore?

Luckily, this fix was relatively easy to figure out. Rather than have Glade create a default model for me I can just create the TreeStore model first and then attach it to the treeview. Easy. Fixed. Wish I'd known that yesterday the day before after spending hours trying to figure it out...

Addendum: If there turns out to be some interest in an actual step-by-step example of the process of creating a treeview in Glade/GTK+ I'd be more than happy to do so.

Wednesday, 16 November 2011

Making the Switch from Ubuntu to Arch

I'd like deviate from Go for a moment. These last few weeks I've been distracted from programming due to switching my main desktop from Ubuntu to Arch Linux and helping my wife with our home-based business Geekling Designs. The Christmas shopping season is busy enough as it is but we're also in the midst of some major upgrades to our business. What with setting up a new small-business ERP software system (an oxymoron, I realize), building a new custom light exposure unit and purchasing a commercial grade screen printing press, we've been a tad busy. And then there's the desktop switch.

As I stated in a previous article, I've been a long-time fan of Ubuntu. Say what you will about it, it allowed me to move from a casual Linux user to a full-time user. It gave me the experience required to build an LFS system for the first time and encouraged me to finally grow as a programmer and invest in Open Source Software.

I've now finished the process of switching over my main system from Ubuntu to Arch Linux. I elected to use LXDE for my desktop environment for something with a little more pep. Neither my wife or myself care too much for the flash of most modern desktops (KDE, Gnome 3) and LXDE can be made quite elegant in its own right without all the cruft that come with the other two environments. I considered using Lubuntu but I felt it was time to cut my ties with the whole Ubuntu ecosystem for a little while. It's nothing personal against Lubuntu, I run it on my venerable laptop and I've installed it on friend's computers, I just need my space. It's not you, it's me.

Of all the things that Arch has going for it, I must say that it's wiki documentation and  forums are absolutely top-notch. It's rare I can't find an answer to my issues in either source. Even my wife has supported the change and has been impressed with the difference in speed between the two systems. I even changed to using the nouveau graphics driver. For regular desktop use, it appears to work superbly, much to my surprise!

Every system has it's quirks. Take, for example, installing the Eclipse IDE. Now, let me first preface this by saying this is less an Arch issue but an eclipse one. The version of Eclipse in the pacman repositories does not come with the Marketplace plugin installed. Nor could I get it installed. Needless to say, it struck me as odd that the version of Eclipse recommended by it's developers was not the one I found in the repositories. I'm sure there is a valid reason for it but it irked me none-the-less. I ended up uninstalling the Arch version and installing it from the Eclipse website. What can I say? I'm lazy and I like the ease of installing plugins from within Eclipse itself.

That said, the move has gone as smoothly as can be expected. No loss of personal data (thank's to keeping my /home directory on a separate HDD) and just the usual issues with installing required software and tweaking settings to work with the new system. Tough things usually "work out of the box" like they tend to do in Ubuntu some packages do need a little extra work.

That's the price you pay for freedom!

Sunday, 23 October 2011

Experimenting with Cgo - Part 3: Errno

In this third installment of introducing cgo to novice Go programmers I want to talk about error handling. More specifically, how to handle C functions that utilize errno. At first glance one would think that this is something no harder to implement than anything else. Not so. There are a couple of "gotchas" with errno in particular you need to be aware of and little to no documentation to help you out. In particular, there was absolutely no documentation describing how to extract errno from os.Error.

  1. errno can't be accessed directly in Go. The cgo documentation clearly states why this is the case. In two words, 'thread safety'.
  2. There is a handy way to trap errno as an os.Error in Go but no obvious way to extract the actual error number.
After a lot of trial and error I finally pieced the puzzle together. First, if the C functions you're implementing set a common system error, as a function like fopen() would, then cgo provides a simple and easy way to get a Go-like error. Again, I refer you to the cgo documentation and you don't really need to look any further. If, however, you're using a library that doesn't you'll need to follow these steps, or at least some of them.

1. Map the error codes to sensible strings describing the error. Documentation on the library you're implementing usually does a good job helping here.

var errText = map[int]string {
    C.EINVAL: "Invalid mode specified",
}

2. Create a helper function to handle printing the error.

func error(e os.Error) os.Error {
    s, ok := errText[int(e.(os.Errno))]
    if ok {
        return os.NewError(s)
    }
    return os.NewError(fmt.Sprintf("Unknown error: %d", int(e.(os.Errno))))
}

This was the hard part. The os package provides Errno, which is Go's equivalent to errno. In order to extract Errno from Error you have to use a type assertion. Errno is typed to int64 which won't work with our C.int error codes so we need to then type cast it to an int.

3. Catch the error value returned by the function utilizing errno to describe errors.

    f, err := C.fopen(cpath, cmode)
    if f == nil {
        return nil, error(err)
    }

It's as simple as that. Complete source code follows:

Makefile:
include $(GOROOT)/src/Make.inc

TARG=cgoexample
CGOFILES=cgofopen.go

include $(GOROOT)/src/Make.pkg

cgofopen.go:
package cgoexample

//#include <stdio.h>
//#include <stdlib.h>
//#include <errno.h>
import "C"

import (
    "fmt"
    "os"
    "unsafe"
)

var errText = map[int]string {
    C.EINVAL: "Invalid mode specified",
}

func error(e os.Error) os.Error {
    s, ok := errText[int(e.(os.Errno))]
    if ok {
        return os.NewError(s)
    }
    return os.NewError(fmt.Sprintf("Unknown error: %d", int(e.(os.Errno))))
}

type File C.FILE

func Open(path, mode string) (*File, os.Error) {
    cpath, cmode := C.CString(path), C.CString(mode)
    defer C.free(unsafe.Pointer(cpath))
    defer C.free(unsafe.Pointer(cmode))
    
    f, err := C.fopen(cpath, cmode)
    if f == nil {
        return nil, error(err)
    }
    return (*File)(f), nil
}

func (f *File) Close() {
    if f != nil {
        C.fclose((*C.FILE)(f))
    }
}

example/Makefile:
include $(GOROOT)/src/Make.inc

TARG=cgoexample
GOFILES=fopen.go

include $(GOROOT)/src/Make.cmd

example/fopen.go
package main

import (
    "cgoexample"
    "fmt"
)

func main() {
    f, e := cgoexample.Open("foobar", "qq")
    defer f.Close()
    
    if e != nil {
        fmt.Println("Error: ", e)
    }
}