Saturday, October 20, 2012

Add URL to Pinboard with Alfred

Just wrote a tiny little ruby script to add URLs to Pinboard using Alfred.

Get it on github.

Chaptrs Photo Browser

Still waiting for my app to enter the Mac App Store review process.

Come on Apple, the app automatically arranges people's photos. People will love it! Review it already :)

http://chaptrs.com

Quicksilver vs Alfred

So if you're like me, you're a long-time Quicksilver user who think that its noun-verb-noun model rules the world. In some cases, the first noun can be an action/script, so practically, the model expands into a verb or verb-noun model. And with the ability to assign keyboard shortcuts to any manifestation of the model and the ability to assign gestures to any key combination, the possibilities become endless.


Alfred is a relatively new player in this arena of "launcher apps". Its been in my radar for awhile, but really, how can I possibly move away from the awesomeness of the Quicksilver model. One day however, I find myself purchasing its Powerpack features (I really have no idea why), so now I'm forced to give it a good spin (money has been invested!).


Having used Alfred for a good two weeks, I must say, it feels faster than Quicksilver and I'm liking its different approach. Using Alfred is a little like using Mozilla's Ubiquity, albeit not as elaborate or powerful. The idea is however similar: you get one text box to enter your query and Alfred acts on that query depending on the syntax. So you could make Alfred work like the Safari Omnibar and type "g [query]" to search Google with [query]. And you can add query shortcuts for all your frequently-used sites: Wikipedia, Google Images, imdb, Rotten Tomatoes, etc. I've even added a shortcut to Google's I'm Feeling Lucky so typing "lq [site]" will take me directly to the site.


More than that these Omnibar-like shortcuts, Alfred is extensible just like Quicksilver. You can hook-up any old Apple Script, Shell Script, etc to Alfred and have it run the script [keyword] with [query] whenever you type like so "[keyword] [query]". There's already a tonne of extensions written for Alfred, all ready for your free shopping. You can also use scripts as Alfred actions so you can run them on selected files / folders, instead of a query string.

So in summary, I think that whatever you want / can do in Quicksilver can be done just as simply in Alfred. The difference is subtle and subjective. Alfred may look aesthetically better for some people, but that could just be the new leather smell thats clouding your judgement. We can't know for sure without a proper A/B testing on an unbiased population sample. The real difference is in their execution models. In most cases, while Quicksilver  makes you think of a noun first, Alfred makes you think of a verb first. Which model is better really depends on the user, preference / comfort, and a fair comparison after prolonged use. For me, I'm sticking with Alfred or at least until the new leather smell wears off.

Friday, October 19, 2012

Using the ANTLR C++ Grammar for C Target

From the ANTLR site:
ANTLR is a language tool that provides a framework constructing recognisers, interpreters, compilers, and translators from grammatical descriptions containing actions in a variety of target languages.
Unfortunately, the grammars publicly listed at the site don't normally come with an easy to follow set of instructions. This post will hopefully provide such help for the C++ grammar for C Target.

First, you will need to install the ANTLR C runtime library, only then can you use the ANTLR C++ grammar files.

The ANTLR C Runtime Library

An alternate set of instructions can be found at the ANTLR site.
  1. Download the library  (v3.4 at the time of this post)
    wget http://www.antlr.org/download/C/libantlr3c-3.4.tar.gz
  2. Untar:
    tar -zxvf libantlr3c-3.4.tar.gz
  3. Configure:
    ./configure --enable-64bit
    (Note that you need to use the --enable-64bit flag if your machine is capable, otherwise you'll run into problems later on)
  4. Compile:
    make
  5. Fix any compilation errors. For example, if you encountered the error "/usr/include/gnu/stubs.h:7:27: error: gnu/stubs-32.h: No such file or directory", then a quick Google search would lead to this stack overflow question, which will suggest installing glibc-devel.i386 via yum if your machine is running CentOS 5.8
  6. Repeat steps 3-5 until there are no compilation errors
  7. Install:
    sudo make install
  8. Export the library path:
    export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH
    
    

The ANTLR C++ Grammar

  1. Download the ANTLR java library. You will need this to process the .g grammar file.
    wget http://www.antlr.org/download/antlr-3.4-complete.jar
  2. Download the grammar file
    wget http://www.antlr.org/grammar/1295920686207/antlr3.2_cpp_parser4.1.0.zip
  3. Extract files:
    unzip antlr3.2_cpp_parser4.1.0.zip
  4. Process the .g grammar file:
    • java -jar /path/to/antlr-3.4-complete.jar CPP_grammar_.g
    • Rename the resulting code files to C++
      mv CPP_grammar_Lexer.c CPP_grammar_Lexer.cpp
      mv CPP_grammar_Parser.c CPP_grammar_Parser.cpp
  5. Edit CPP_grammar_Parser.cpp and comment out  line 29639 (there is an extra ');' present) that will prohibit the file from compiling
  6. Edit cpp_full_prog.cpp at line 239 and change
    input = antlr3AsciiFileStreamNew(fName);
    with:
    input = antlr3FileStreamNew(fName, 4);
    The integer 4 refers to the constant ANTLR3_ENC_8BIT found in antlr3defs.h (in the C runtime library installed in the first section)
  7. Compile and link:
    g++ -o cpp_full_prog cpp_full_prog.cpp CPP_grammar_Lexer.cpp CPP_grammar_Parser.cpp Helper/*.cpp -I/usr/local/include/ -I./antlr_include/ -L/usr/local/lib/ -lantlr3c
For more information on how to massage information out of the lexer, tokens, or parser, you can refer to the C runtime library API

Essentially, the ANTLR C runtime library works by defining a series of structs with dynamically assigned function pointers in each struct. This way, each struct can be assigned with the functions that should be used for that struct. This however, makes for a little weird looking function calls like "currToken->getType(currToken)".