<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>porges &#187; Linux</title>
	<atom:link href="http://porg.es/blog/tag/linux/feed" rel="self" type="application/rss+xml" />
	<link>http://porg.es/blog</link>
	<description></description>
	<lastBuildDate>Thu, 12 Jan 2012 23:45:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Rhythmbox Plugin: Stop after current track</title>
		<link>http://porg.es/blog/rhythmbox-plugin-stop-after-current-track</link>
		<comments>http://porg.es/blog/rhythmbox-plugin-stop-after-current-track#comments</comments>
		<pubDate>Tue, 07 Apr 2009 05:18:24 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rhythmbox]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://porg.es/blog/?p=324</guid>
		<description><![CDATA[I have wanted this for a while, and my brother linking me to this post was the last straw. So here is a very quick and simple plugin; it simply puts a button on the toolbar that you can click when you want to stop playback after the current song. I based the toolbar button [...]]]></description>
			<content:encoded><![CDATA[<p>I have wanted this for a while, and my brother linking me to <a href="http://unadorned.org/dandruff/archives/2004/02/24/002324.html">this post</a> was the last straw.</p>
<p>So here is a very quick and simple plugin; it simply puts a button on the toolbar that you can click when you want to stop playback after the current song. I based the toolbar button code on <a href="http://code.google.com/p/airmindprojects/">Alexandre Rosenfeld’s lastfm-queue plugin</a>, since I had no idea where to start with that <img src="http://porg.es/blog/wp-content/plugins/wp-smiley-switcher/noktahhitam/icon_smile.gif" alt="" /></p>
<p>Download it <a href='http://porg.es/blog/wp-content/uploads/2009/04/stop_after_song.zip'>here</a>, and put it into <code>~/.gnome2/rhythmbox/plugins/stop_after_song/</code>. Activate it in Rhythmbox’s plugin dialog.</p>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/rhythmbox-plugin-stop-after-current-track/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Annoyances with Intrepid</title>
		<link>http://porg.es/blog/annoyances-with-intrepid</link>
		<comments>http://porg.es/blog/annoyances-with-intrepid#comments</comments>
		<pubDate>Thu, 26 Feb 2009 22:30:16 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[commentary]]></category>
		<category><![CDATA[annoyance]]></category>
		<category><![CDATA[ati]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[compiz]]></category>
		<category><![CDATA[criticism]]></category>
		<category><![CDATA[dvd]]></category>
		<category><![CDATA[intrepid]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://porg.es/blog/?p=297</guid>
		<description><![CDATA[After having just installed Intrepid on a friend’s PC last night: I ran into this bug (here’s the fix) ATi’s dual monitor setup is still too hard (here’s how to do it) ATi’s drivers can’t do compiz and video at the same time (Install the latest drivers to fix it)]]></description>
			<content:encoded><![CDATA[<p>After having just installed Intrepid on a friend’s PC last night:</p>
<ul>
<li>I ran into <a href="https://bugs.launchpad.net/ubuntu/+source/mplayer/+bug/197068">this bug</a> (<a href="http://ubuntuforums.org/showpost.php?p=5014367&#038;postcount=4">here’s the fix</a>)</li>
<li>ATi’s dual monitor setup is still too hard (<a href="http://ubuntuforums.org/showpost.php?p=4486852&#038;postcount=6">here’s how to do it</a>)</li>
<li>ATi’s drivers can’t do compiz and video at the same time (<a href="http://wiki.cchtml.com/index.php/Ubuntu_Intrepid_Installation_Guide#Installing_the_restricted_drivers_manually">Install the latest drivers to fix it</a>)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/annoyances-with-intrepid/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cleaning up a set of tags with Awk</title>
		<link>http://porg.es/blog/cleaning-up-a-set-of-tags-with-awk</link>
		<comments>http://porg.es/blog/cleaning-up-a-set-of-tags-with-awk#comments</comments>
		<pubDate>Wed, 28 Jan 2009 02:08:05 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[commentary]]></category>
		<category><![CDATA[replies]]></category>
		<category><![CDATA[utility]]></category>
		<category><![CDATA[awk]]></category>
		<category><![CDATA[inflammatory]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[Unix]]></category>

		<guid isPermaLink="false">http://porg.es/blog/?p=266</guid>
		<description><![CDATA[Introduction David R. MacIver has recently written this blog post about cleaning up a set of tags. This blog post, on the other hand, is about a nice old Unix tool called ‘awk’. Awk is one of those programs that is often overlooked. It is really a small domain-specific language for processing text. In some [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p><a href="http://www.drmaciver.com/about/">David R. MacIver</a> has recently written <a href="http://www.drmaciver.com/2009/01/cleaning-up-a-set-of-tags-part-1/">this blog post about cleaning up a set of tags</a>. <i>This</i> blog post, on the other hand, is about a nice old Unix tool called ‘awk’.</p>
<p>Awk is one of those programs that is often overlooked. It is really a small domain-specific language for processing text. In some ways it resembles sed, but it is more powerful, and it especially excels at processing line- and field-structured input.</p>
<h3>Processing cite-u-like&#8217;s data</h3>
<p>First of all, before we begin I want to say this this isn&#8217;t a criticism of David&#8217;s work. Using a general-purpose language like Ruby to process data comes with several benefits. This post is to explain the benefits of awk and what it excels at doing.</p>
<p>Now, cite-u-like&#8217;s tag data comes in a pipe-separated format, so we have input like this:</p>
<pre style="overflow:auto">42|61baaeba8de136d9c1aa9c18ec3860e8|2004-11-04 02:25:05.373798+00|ecoli
42|61baaeba8de136d9c1aa9c18ec3860e8|2004-11-04 02:25:05.373798+00|metabolism
42|61baaeba8de136d9c1aa9c18ec3860e8|2004-11-04 02:25:05.373798+00|barabasi
42|61baaeba8de136d9c1aa9c18ec3860e8|2004-11-04 02:25:05.373798+00|networks
43|61baaeba8de136d9c1aa9c18ec3860e8|2004-11-04 02:25:51.839281+00|control
43|61baaeba8de136d9c1aa9c18ec3860e8|2004-11-04 02:25:51.839281+00|engineering
43|61baaeba8de136d9c1aa9c18ec3860e8|2004-11-04 02:25:51.839281+00|robustness
44|61baaeba8de136d9c1aa9c18ec3860e8|2004-11-04 02:26:33.156319+00|networks
44|61baaeba8de136d9c1aa9c18ec3860e8|2004-11-04 02:26:33.156319+00|strogatz
44|61baaeba8de136d9c1aa9c18ec3860e8|2004-11-04 02:26:33.156319+00|survey</pre>
<p>From now on, whenever you see <i>x</i>-separated data, I want you to scream ‘USE AWK!’ <img src="http://porg.es/blog/wp-content/plugins/wp-smiley-switcher/noktahhitam/icon_razz.gif" alt="" /></p>
<p>Awk scripts look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="awk" style="font-family:monospace;">pattern <span style="color: #7a0874; font-weight: bold;">&#123;</span> expression <span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p><i>pattern</i> is used to match against a record, and if successful, the action in the braces (<i>expression</i>) will be carried out. But what is a record? Awk allows you to define what a line is using the variable <code>RS</code> (short for ‘record separator’). By default it is set to <code>\n</code> (so that each line is a record), which is what we want here.</p>
<p>Within the expression you can refer to <i>fields</i> of the current record, using the syntax <code>$<i>n</i></code>. <code>$0</code> refers to the whole record, while <code>$1</code>,<code>$2</code>&#8230; refer to individual fields.</p>
<p>Awk also allows you to define what the <i>field separator</i> will be via the variable <code>FS</code>.</p>
<p>So how do we set these variables? Awk has two special patterns <code>BEGIN</code> and <code>END</code>, which run before and after everything else. In this case, we want the fields to be separated by <code>|</code>, so we use the pattern:</p>

<div class="wp_syntax"><div class="code"><pre class="awk" style="font-family:monospace;"><span style="color: #C20CB9; font-weight: bold;">BEGIN</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> <span style="color: #4107D5; font-weight: bold;">FS</span> = <span style="color: #ff0000;">&quot;|&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>This is rather long-winded, so mawk (an implementation of awk) also allows you to set <code>FS</code> via a command-line option <code>-F</code>.</p>
<p>For this application, we want the last field of the record (we could hard-code it as <code>$4</code>, but we&#8217;re exploring awk!). Awk provides the number of fields in the record as the variable <code>NF</code> (number of fields), so we want to access this field. We do so using the record syntax <code>$</code> and the variable <code>NF</code>.</p>
<p>So to put all this together, what we want is the command:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #660033;">-F</span> <span style="color: #ff0000;">&quot;|&quot;</span> <span style="color: #ff0000;">'{ print $NF }'</span></pre></div></div>

<p>We set the field separator to &#8220;|&#8221;, and write an awk expression to print the last field of each record. Since we left the <i>pattern</i> empty, this expression is evaluated on every record.</p>
<h3>Awk vs. Ruby</h3>
<p>So what good is learning all this, anyway? There are a couple of reasons:</p>
<ul>
<li>awk is standard on *nix operating systems. In order to use David&#8217;s code I had to install Ruby; with awk you can generally count on it being there.</li>
<li>awk is <em>fast</em> (I should say at least in the interpreter ‘mawk’ which is the standard for Ubuntu). On my machine the awk version completes in under a third of the time that it takes for David&#8217;s Ruby version to complete. An interesting thing was that the awk version didn&#8217;t even max out the CPU, indicating that it is IO-bound and would go faster if I had faster disks (I&#8217;m currently on a laptop).</li>
<li>Awk is ideal for record- and field-based input, as I hope this post will show you <img src="http://porg.es/blog/wp-content/plugins/wp-smiley-switcher/noktahhitam/icon_smile.gif" alt="" /></li>
</ul>
<h3>Filtering data with awk</h3>
<p>After the above we use <code>sort</code> and <code>uniq</code> the same as David does to get the results in the following form:</p>
<pre> 212595 bibtex-import
 157136 no-tag
  27926 elegans
  27887 celegans
  27825 c_elegans
  27795 nematode
  27738 wormbase
  27736 caenorhabditis_elegans
  18933 review
  15280 all-articles</pre>
<p>David uses the following to filter out lines with no alphabetical content:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ruby <span style="color: #660033;">-ne</span> <span style="color: #ff0000;">'puts $_ if !($_ =~ /^[^a-z]+$/)'</span></pre></div></div>

<p>We can use awk&#8217;s patterns to do the same thing:</p>

<div class="wp_syntax"><div class="code"><pre class="awk" style="font-family:monospace;"><span style="color:#000088;">$0</span> <span style="color:#C4C364;">~</span> <span style="color:black;">/</span><span style="color: #7a0874; font-weight: bold;">&#91;</span>a<span style="color:black;">-</span>zA<span style="color:black;">-</span>Z<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color:black;">/</span></pre></div></div>

<p>Here we use the <code>~</code> (match) operator to write a pattern that matches only the records with an alphabetical character in them. (Remember that <code>$0</code> refers to the entire record.) Notice also that we can leave off the expression after the pattern, because it defaults to <code>{ print }</code>, which is exactly what we want.</p>
<p>In this case, awk really shines. On my machine it outperforms the Ruby version by a factor of 8–9.</p>
<h3>Programming with awk</h3>
<p>The third task that David does is to consolidate all tags which are differentiated only by hyphens or underscores. That is, ‘a-tag’, ‘atag’, and ‘a_tag’ should all be considered the same. We choose which one to put into the output by whichever one is used the most times (and then we normalize the tag by replacing ‘-’ with ‘_’ so there are only underscores in the output).</p>
<p>Here is David&#8217;s code to do the job:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">tag_counts = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
STDIN.<span style="color:#9900CC;">lines</span>.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>l<span style="color:#006600; font-weight:bold;">|</span> c, t = l.<span style="color:#CC0066; font-weight:bold;">split</span>; tag_counts<span style="color:#006600; font-weight:bold;">&#91;</span>t.<span style="color:#9900CC;">strip</span><span style="color:#006600; font-weight:bold;">&#93;</span> = c.<span style="color:#9900CC;">to_i</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
duplicates = <span style="color:#CC00FF; font-weight:bold;">Hash</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>h, k<span style="color:#006600; font-weight:bold;">|</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>k<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
tag_counts.<span style="color:#9900CC;">keys</span>.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>k<span style="color:#006600; font-weight:bold;">|</span> duplicates<span style="color:#006600; font-weight:bold;">&#91;</span>k.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/-|</span>_<span style="color:#006600; font-weight:bold;">/</span>, <span style="color:#996600;">&quot;&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> k <span style="color:#006600; font-weight:bold;">&#125;</span>
duplicates.<span style="color:#9900CC;">values</span>.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>vs<span style="color:#006600; font-weight:bold;">|</span> vs.<span style="color:#9900CC;">sort</span>!<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>x, y<span style="color:#006600; font-weight:bold;">|</span> tag_counts<span style="color:#006600; font-weight:bold;">&#91;</span>y<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&lt;=&gt;</span> tag_counts<span style="color:#006600; font-weight:bold;">&#91;</span>x<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
new_tag_counts = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
duplicates.<span style="color:#9900CC;">values</span>.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>vs<span style="color:#006600; font-weight:bold;">|</span> new_tag_counts<span style="color:#006600; font-weight:bold;">&#91;</span>vs<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#40;</span>_<span style="color:#006600; font-weight:bold;">|-</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">+/</span>, <span style="color:#996600;">&quot;_&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span> = vs.<span style="color:#9900CC;">map</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>v<span style="color:#006600; font-weight:bold;">|</span> tag_counts<span style="color:#006600; font-weight:bold;">&#91;</span>v<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">inject</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">0</span>, <span style="color:#006600; font-weight:bold;">&amp;</span>:<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> new_tag_counts.<span style="color:#9900CC;">to_a</span>.<span style="color:#9900CC;">sort</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>x, y<span style="color:#006600; font-weight:bold;">|</span> y<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&lt;=&gt;</span> x<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">map</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>t, c<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#996600;">&quot; #{c} #{t}&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>I&#8217;m not going to explain it here, because that&#8217;s not the point of the post <img src="http://porg.es/blog/wp-content/plugins/wp-smiley-switcher/noktahhitam/icon_smile.gif" alt="" /></p>
<p>Here&#8217;s my awk script:</p>

<div class="wp_syntax"><div class="code"><pre class="awk" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#123;</span> tag_counts<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color:#000088;">$2</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> = <span style="color:#000088;">$1</span> <span style="color: #7a0874; font-weight: bold;">&#125;</span>
<span style="color: #C20CB9; font-weight: bold;">END</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>tag <span style="color: #000000; font-weight: bold;">in</span> tag_counts<span style="color: #7a0874; font-weight: bold;">&#41;</span>
	<span style="color: #7a0874; font-weight: bold;">&#123;</span>
		normtag=tag
		<span style="color: #07D589; font-weight: bold;">gsub</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color:black;">/-</span>|_<span style="color:black;">/</span>,<span style="color: #ff0000;">&quot;&quot;</span>,normtag<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
		count=tag_counts<span style="color: #7a0874; font-weight: bold;">&#91;</span>tag<span style="color: #7a0874; font-weight: bold;">&#93;</span>
		sum<span style="color: #7a0874; font-weight: bold;">&#91;</span>normtag<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color:black;">+</span>=count
&nbsp;
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>count <span style="color:black;">&gt;</span> max<span style="color: #7a0874; font-weight: bold;">&#91;</span>normtag<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
		<span style="color: #7a0874; font-weight: bold;">&#123;</span>
			names<span style="color: #7a0874; font-weight: bold;">&#91;</span>normtag<span style="color: #7a0874; font-weight: bold;">&#93;</span>=tag
			max<span style="color: #7a0874; font-weight: bold;">&#91;</span>normtag<span style="color: #7a0874; font-weight: bold;">&#93;</span>=count
		<span style="color: #7a0874; font-weight: bold;">&#125;</span>
	<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>tag <span style="color: #000000; font-weight: bold;">in</span> names<span style="color: #7a0874; font-weight: bold;">&#41;</span>
	<span style="color: #7a0874; font-weight: bold;">&#123;</span>
		finaltag=names<span style="color: #7a0874; font-weight: bold;">&#91;</span>tag<span style="color: #7a0874; font-weight: bold;">&#93;</span>
		<span style="color: #07D589; font-weight: bold;">gsub</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color:black;">/</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color:black;">-</span>|_<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color:black;">+/</span>,<span style="color: #ff0000;">&quot;_&quot;</span>,finaltag<span style="color: #7a0874; font-weight: bold;">&#41;</span>
		<span style="color: #0BD507; font-weight: bold;">print</span> <span style="color: #ff0000;">&quot; &quot;</span> sum<span style="color: #7a0874; font-weight: bold;">&#91;</span>tag<span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #ff0000;">&quot; &quot;</span> finaltag
	<span style="color: #7a0874; font-weight: bold;">&#125;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>That&#8217;s right, you can use awk to do some ordinary programming tasks! Arrays are used using the usual syntax, and awk even has a foreach-style loop for looping over them. I&#8217;ll walk through the rest of the script slowly.</p>
<p>First we apply an expression to each record, creating an array of tags and their counts:</p>

<div class="wp_syntax"><div class="code"><pre class="awk" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#123;</span> tag_counts<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color:#000088;">$2</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> = <span style="color:#000088;">$1</span> <span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>Then, once everything has finished (the <code>END</code> pattern), we process this array. For each tag, we do the following:</p>
<ol>
<li>
<p>Normalize the tag (the gsub function overwrites the variable, so we have to make a copy):</p>

<div class="wp_syntax"><div class="code"><pre class="awk" style="font-family:monospace;">normtag=tag
<span style="color: #07D589; font-weight: bold;">gsub</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color:black;">/-</span>|_<span style="color:black;">/</span>,<span style="color: #ff0000;">&quot;&quot;</span>,normtag<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>(Notice the similarity between this and Ruby&#8217;s equivalent <code>normtag.gsub!(/-|_/, "")</code>!)</p>
</li>
<li>
<p>Get the count for that tag and add it to the count for the normalized version:</p>

<div class="wp_syntax"><div class="code"><pre class="awk" style="font-family:monospace;">count=tag_counts<span style="color: #7a0874; font-weight: bold;">&#91;</span>tag<span style="color: #7a0874; font-weight: bold;">&#93;</span>
sum<span style="color: #7a0874; font-weight: bold;">&#91;</span>normtag<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color:black;">+</span>=count</pre></div></div>

<p>Like in PHP and Perl, if a value is not present in an array it is automatically added with a default value.</p>
</li>
<li>
<p>Next we check to see if the current tag is the commonest version of the normalized tag, and if so we save its name and count in two other arrays:</p>

<div class="wp_syntax"><div class="code"><pre class="awk" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>count <span style="color:black;">&gt;</span> max<span style="color: #7a0874; font-weight: bold;">&#91;</span>normtag<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#123;</span>
	names<span style="color: #7a0874; font-weight: bold;">&#91;</span>normtag<span style="color: #7a0874; font-weight: bold;">&#93;</span>=tag
	max<span style="color: #7a0874; font-weight: bold;">&#91;</span>normtag<span style="color: #7a0874; font-weight: bold;">&#93;</span>=count
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>Notice again the usefulness of a default value for nonexistent keys: <code>count > max[normtag]</code> will be true if <code>max[normtag]</code> doesn&#8217;t exist.</p>
</li>
</ol>
<p>Now we have all we need to print out the answer. For each tag we normalize it to the final version (remembering to make a copy):</p>

<div class="wp_syntax"><div class="code"><pre class="awk" style="font-family:monospace;">finaltag=names<span style="color: #7a0874; font-weight: bold;">&#91;</span>tag<span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #07D589; font-weight: bold;">gsub</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color:black;">/</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color:black;">-</span>|_<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color:black;">+/</span>,<span style="color: #ff0000;">&quot;_&quot;</span>,finaltag<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Then we print out the line (concatenation is done by simply juxtaposing variables or strings):</p>

<div class="wp_syntax"><div class="code"><pre class="awk" style="font-family:monospace;"><span style="color: #0BD507; font-weight: bold;">print</span> <span style="color: #ff0000;">&quot; &quot;</span> sum<span style="color: #7a0874; font-weight: bold;">&#91;</span>tag<span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #ff0000;">&quot; &quot;</span> finaltag</pre></div></div>

<p>If you&#8217;ve been watching closely you&#8217;ll notice there is a small difference between the awk and the Ruby scripts; Ruby sorts before outputting, while the awk version will come out in a non-defined order. This is fine! We can use the standard *nix tool ‘sort’ to sort the lines;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #660033;">-f</span> consolidate_tags.awk <span style="color: #000000; font-weight: bold;">&lt;</span> tags <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sort</span> <span style="color: #660033;">-nr</span> <span style="color: #000000; font-weight: bold;">&gt;</span> fixed_tags</pre></div></div>

<p>(Note that this fits in with the *nix philosophy of ‘do one thing well’ and reusing small components.)</p>
<p>Again, the awk version outperforms the Ruby by a factor of 3–4.</p>
<h3>Reading external commands and files</h3>
<p>Unfortunately there doesn&#8217;t seem to be a command-line stemming program (a quick Perl script would suffice but it isn&#8217;t what we&#8217;re here for!), so I&#8217;ll skip that stage (here&#8217;s one of the aforementioned weaknesses of a non-general-purpose language). Instead we&#8217;ll go straight to implementing stopwords.</p>
<p>Here&#8217;s David&#8217;s Ruby code again:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;set&quot;</span>
&nbsp;
stopwords = <span style="color:#CC00FF; font-weight:bold;">Set</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">*</span>
  <span style="color:#CC00FF; font-weight:bold;">IO</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;smart.txt&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">lines</span>.<span style="color:#9900CC;">reject</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>x<span style="color:#006600; font-weight:bold;">|</span> x =~ <span style="color:#006600; font-weight:bold;">/</span>^<span style="color:#008000; font-style:italic;">#/}.map(&amp;:strip)</span>
<span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
STDIN.<span style="color:#9900CC;">lines</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>l<span style="color:#006600; font-weight:bold;">|</span>
  c, t = l.<span style="color:#CC0066; font-weight:bold;">split</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> l <span style="color:#9966CC; font-weight:bold;">unless</span> stopwords.<span style="color:#9966CC; font-weight:bold;">include</span>? t.<span style="color:#9900CC;">strip</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And here&#8217;s my equivalent in awk:</p>

<div class="wp_syntax"><div class="code"><pre class="awk" style="font-family:monospace;"><span style="color: #C20CB9; font-weight: bold;">BEGIN</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #0BD507; font-weight: bold;">getline</span> <span style="color:black;">&lt;</span> <span style="color: #ff0000;">&quot;smart.txt&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
    <span style="color: #7a0874; font-weight: bold;">&#123;</span> stopwords<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color:#000088;">$0</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> = <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">&#125;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
<span style="color:black;">!</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color:#000088;">$2</span> <span style="color: #000000; font-weight: bold;">in</span> stopwords<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Here I use the ‘getline’ function which does as its name suggests. We make an array of all the stopwords, with 1 as a placeholder value. The pattern is then short and simple: Print every record where the tag isn&#8217;t in the stopwords (again, we can leave off the expression to print the whole record).</p>
<p><i>Note: There is a discrepancy here: David claims this eliminated 46 tags, while I get a value of 368 for both my awk code and his Ruby code.</i></p>
<p>Again, the Ruby takes about 8 times as long to execute.</p>
<h3>Conclusion</h3>
<p>Here&#8217;s a couple of points:</p>
<ul>
<li>
<p>Record- or field-oriented data? Think awk.</p>
</li>
<li>
<p>Don&#8217;t discount it just because it&#8217;s <em>venerable</em>. It is very well-suited to its task.</p>
</li>
<li>
<p><code>pattern { expression }</code> syntax is extremely flexible.</p>
</li>
<li>
<p>Awk&#8217;s regular expressions are fast.</p>
</li>
</ul>
<blockquote><p><i>Nowadays everybody wanna talk<br />
&nbsp;&nbsp;&nbsp;&nbsp;like they got something to say<br />
But nothing comes out<br />
&nbsp;&nbsp;&nbsp;&nbsp;when they move their lips<br />
Just a bunch of gibberish<br />
And motherf—kers act<br />
&nbsp;&nbsp;&nbsp;&nbsp;like they forgot about Awk</i></p>
</blockquote>
<p><img src="http://porg.es/blog/wp-content/plugins/wp-smiley-switcher/noktahhitam/icon_biggrin.gif" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/cleaning-up-a-set-of-tags-with-awk/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Generating x86 assembly with Haskell</title>
		<link>http://porg.es/blog/generating-x86-assembly-with-haskell</link>
		<comments>http://porg.es/blog/generating-x86-assembly-with-haskell#comments</comments>
		<pubDate>Mon, 03 Nov 2008 12:51:14 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[asm]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[x86]]></category>

		<guid isPermaLink="false">http://porg.es/blog/?p=236</guid>
		<description><![CDATA[A quick and dirty example: data Exp = Lit Int -- literal value &#124; Call String Exp -- calling a function &#124; Bin BinOp Exp Exp -- binary operations &#124; Param -- the parameter deriving &#40;Show,Eq&#41; &#160; data Function = Func String Exp -- a function has a name and expression data BinOp = Add [...]]]></description>
			<content:encoded><![CDATA[<p>A quick and dirty example:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> Exp <span style="color: #339933; font-weight: bold;">=</span> Lit <span style="color: #cccc00; font-weight: bold;">Int</span> <span style="color: #5d478b; font-style: italic;">-- literal value</span>
	<span style="color: #339933; font-weight: bold;">|</span> Call <span style="color: #cccc00; font-weight: bold;">String</span> Exp <span style="color: #5d478b; font-style: italic;">-- calling a function</span>
	<span style="color: #339933; font-weight: bold;">|</span> Bin BinOp Exp Exp <span style="color: #5d478b; font-style: italic;">-- binary operations</span>
	<span style="color: #339933; font-weight: bold;">|</span> Param <span style="color: #5d478b; font-style: italic;">-- the parameter</span>
	<span style="color: #06c; font-weight: bold;">deriving</span> <span style="color: green;">&#40;</span><span style="color: #cccc00; font-weight: bold;">Show</span><span style="color: #339933; font-weight: bold;">,</span><span style="color: #cccc00; font-weight: bold;">Eq</span><span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">data</span> Function <span style="color: #339933; font-weight: bold;">=</span> Func <span style="color: #cccc00; font-weight: bold;">String</span> Exp <span style="color: #5d478b; font-style: italic;">-- a function has a name and expression</span>
<span style="color: #06c; font-weight: bold;">data</span> BinOp <span style="color: #339933; font-weight: bold;">=</span> Add <span style="color: #339933; font-weight: bold;">|</span> Subtract <span style="color: #339933; font-weight: bold;">|</span> Multiply <span style="color: #339933; font-weight: bold;">|</span> Divide <span style="color: #06c; font-weight: bold;">deriving</span><span style="color: green;">&#40;</span><span style="color: #cccc00; font-weight: bold;">Show</span><span style="color: #339933; font-weight: bold;">,</span><span style="color: #cccc00; font-weight: bold;">Eq</span><span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #5d478b; font-style: italic;">-- an instance to allow us to write nicer definitions</span>
<span style="color: #06c; font-weight: bold;">instance</span> <span style="color: #cccc00; font-weight: bold;">Num</span> Exp <span style="color: #06c; font-weight: bold;">where</span>
	x <span style="color: #339933; font-weight: bold;">*</span> y <span style="color: #339933; font-weight: bold;">=</span> Bin Multiply x y
	x <span style="color: #339933; font-weight: bold;">-</span> y <span style="color: #339933; font-weight: bold;">=</span> Bin Subtract x y
	x <span style="color: #339933; font-weight: bold;">+</span> y <span style="color: #339933; font-weight: bold;">=</span> Bin Add x y
	<span style="font-weight: bold;">fromInteger</span> x <span style="color: #339933; font-weight: bold;">=</span> Lit <span style="color: green;">&#40;</span><span style="font-weight: bold;">fromInteger</span> x<span style="color: green;">&#41;</span>
&nbsp;
outFunc <span style="color: green;">&#40;</span>Func name it<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> name <span style="color: #339933; font-weight: bold;">++</span> <span style="color: #5d478b; font-style: italic;">-- output function name</span>
	<span style="background-color: #3cb371;">&quot;:<span style="background-color: #3cb371; font-weight: bold;">\n</span>push ebp<span style="background-color: #3cb371; font-weight: bold;">\n</span>mov ebp,esp<span style="background-color: #3cb371; font-weight: bold;">\n</span>&quot;</span> <span style="color: #339933; font-weight: bold;">++</span> <span style="color: #5d478b; font-style: italic;">-- save old stack frame</span>
	output it <span style="color: #339933; font-weight: bold;">++</span> <span style="color: #5d478b; font-style: italic;">-- output function</span>
	<span style="background-color: #3cb371;">&quot;pop eax<span style="background-color: #3cb371; font-weight: bold;">\n</span>pop ebp<span style="background-color: #3cb371; font-weight: bold;">\n</span>&quot;</span> <span style="color: #339933; font-weight: bold;">++</span> <span style="color: #5d478b; font-style: italic;">-- restore old stack frame</span>
	<span style="background-color: #3cb371;">&quot;ret 4<span style="background-color: #3cb371; font-weight: bold;">\n</span><span style="background-color: #3cb371; font-weight: bold;">\n</span>&quot;</span> <span style="color: #5d478b; font-style: italic;">-- remove argument from stack and return</span>
&nbsp;
output <span style="color: green;">&#40;</span>Bin op l r<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> outBin op l r <span style="color: #5d478b; font-style: italic;">-- binary operations</span>
output <span style="color: green;">&#40;</span>Lit x<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="background-color: #3cb371;">&quot;push dword &quot;</span> <span style="color: #339933; font-weight: bold;">++</span> <span style="font-weight: bold;">show</span> x <span style="color: #339933; font-weight: bold;">++</span> <span style="background-color: #3cb371;">&quot;<span style="background-color: #3cb371; font-weight: bold;">\n</span>&quot;</span> <span style="color: #5d478b; font-style: italic;">-- push literal</span>
output <span style="color: green;">&#40;</span>Param<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="background-color: #3cb371;">&quot;push dword [ebp+8]<span style="background-color: #3cb371; font-weight: bold;">\n</span>&quot;</span> <span style="color: #5d478b; font-style: italic;">-- push parameter</span>
output <span style="color: green;">&#40;</span>Call name with<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> output with <span style="color: #339933; font-weight: bold;">++</span>
	<span style="background-color: #3cb371;">&quot;call &quot;</span> <span style="color: #339933; font-weight: bold;">++</span> name <span style="color: #339933; font-weight: bold;">++</span>
	<span style="background-color: #3cb371;">&quot;<span style="background-color: #3cb371; font-weight: bold;">\n</span>push eax<span style="background-color: #3cb371; font-weight: bold;">\n</span>&quot;</span> <span style="color: #5d478b; font-style: italic;">-- put return value onto stack</span>
&nbsp;
outBin Add <span style="color: #339933; font-weight: bold;">=</span> outBinGen <span style="background-color: #3cb371;">&quot;add&quot;</span>
outBin Subtract <span style="color: #339933; font-weight: bold;">=</span> outBinGen <span style="background-color: #3cb371;">&quot;sub&quot;</span>
outBin Multiply <span style="color: #339933; font-weight: bold;">=</span> outBinGen <span style="background-color: #3cb371;">&quot;imul&quot;</span>
outBin Divide <span style="color: #339933; font-weight: bold;">=</span> outBinGen <span style="background-color: #3cb371;">&quot;idiv&quot;</span>
&nbsp;
outBinGen op l r <span style="color: #339933; font-weight: bold;">=</span> output l <span style="color: #339933; font-weight: bold;">++</span> output r <span style="color: #339933; font-weight: bold;">++</span>
	<span style="background-color: #3cb371;">&quot;pop ebx<span style="background-color: #3cb371; font-weight: bold;">\n</span>pop eax<span style="background-color: #3cb371; font-weight: bold;">\n</span>&quot;</span> <span style="color: #339933; font-weight: bold;">++</span> op <span style="color: #339933; font-weight: bold;">++</span> <span style="background-color: #3cb371;">&quot; eax,ebx<span style="background-color: #3cb371; font-weight: bold;">\n</span>push eax<span style="background-color: #3cb371; font-weight: bold;">\n</span>&quot;</span></pre></div></div>

<p>And an example of using it:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">main <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">putStr</span> <span style="color: #339933; font-weight: bold;">$</span> <span style="font-weight: bold;">concatMap</span> outFunc <span style="color: green;">&#91;</span>double<span style="color: #339933; font-weight: bold;">,</span>quad<span style="color: green;">&#93;</span>
double <span style="color: #339933; font-weight: bold;">=</span> Func <span style="background-color: #3cb371;">&quot;double&quot;</span> <span style="color: green;">&#40;</span>Param <span style="color: #339933; font-weight: bold;">*</span> <span style="color: red;">2</span><span style="color: green;">&#41;</span>
quad <span style="color: #339933; font-weight: bold;">=</span> Func <span style="background-color: #3cb371;">&quot;quad&quot;</span> <span style="color: green;">&#40;</span>Call <span style="background-color: #3cb371;">&quot;double&quot;</span> <span style="color: green;">&#40;</span><span style="color: red;">2</span><span style="color: #339933; font-weight: bold;">*</span>Param<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre></div></div>

<p>This example outputs:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">double<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">ebp</span>
	<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ebp</span><span style="color: #339933;">,</span><span style="color: #00007f;">esp</span>
	<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #000000; font-weight: bold;">dword</span> <span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">ebp</span><span style="color: #339933;">+</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#93;</span>
	<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #000000; font-weight: bold;">dword</span> <span style="color: #0000ff;">2</span>
	<span style="color: #00007f; font-weight: bold;">pop</span> <span style="color: #00007f;">ebx</span>
	<span style="color: #00007f; font-weight: bold;">pop</span> <span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">imul</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span><span style="color: #00007f;">ebx</span>
	<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">pop</span> <span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">pop</span> <span style="color: #00007f;">ebp</span>
	<span style="color: #00007f; font-weight: bold;">ret</span> <span style="color: #0000ff;">4</span>
&nbsp;
quad<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">ebp</span>
	<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ebp</span><span style="color: #339933;">,</span><span style="color: #00007f;">esp</span>
	<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #000000; font-weight: bold;">dword</span> <span style="color: #0000ff;">2</span>
	<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #000000; font-weight: bold;">dword</span> <span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">ebp</span><span style="color: #339933;">+</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#93;</span>
	<span style="color: #00007f; font-weight: bold;">pop</span> <span style="color: #00007f;">ebx</span>
	<span style="color: #00007f; font-weight: bold;">pop</span> <span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">imul</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span><span style="color: #00007f;">ebx</span>
	<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">call</span> double
	<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">pop</span> <span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">pop</span> <span style="color: #00007f;">ebp</span>
	<span style="color: #00007f; font-weight: bold;">ret</span> <span style="color: #0000ff;">4</span></pre></div></div>

<p>Not the most efficient code in the world <img src="http://porg.es/blog/wp-content/plugins/wp-smiley-switcher/noktahhitam/icon_wink.gif" alt="" /> The calling convention is somewhat ad-hoc; the callee must remove its arguments from the stack and returns its value in <code>eax</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/generating-x86-assembly-with-haskell/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A useful gedit macro for LaTeX</title>
		<link>http://porg.es/blog/a-useful-gedit-macro-for-latex</link>
		<comments>http://porg.es/blog/a-useful-gedit-macro-for-latex#comments</comments>
		<pubDate>Wed, 30 Apr 2008 06:28:41 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[tips]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[gedit]]></category>
		<category><![CDATA[latex]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[snippet]]></category>
		<category><![CDATA[useful]]></category>

		<guid isPermaLink="false">http://porg.es/blog/?p=127</guid>
		<description><![CDATA[Builds and displays your current LaTeX document, and removes all the temporary file spam. #!/bin/bash TMPDIR=$&#40;mktemp -td&#41; &#160; rubber -d --into &#34;$TMPDIR&#34; &#34;$GEDIT_CURRENT_DOCUMENT_NAME&#34; &#38;&#38; mv &#34;$TMPDIR/${GEDIT_CURRENT_DOCUMENT_NAME%tex}pdf&#34; &#34;$GEDIT_CURRENT_DOCUMENT_DIR&#34; &#160; if &#91; $? -eq 0 &#93; then evince &#34;${GEDIT_CURRENT_DOCUMENT_NAME%tex}pdf&#34; &#38; fi &#160; rm -rf &#34;$TMPDIR&#34;]]></description>
			<content:encoded><![CDATA[<p>Builds and displays your current LaTeX document, and removes all the temporary file spam.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #007800;">TMPDIR</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">mktemp</span> -td<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
rubber <span style="color: #660033;">-d</span> <span style="color: #660033;">--into</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$TMPDIR</span>&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$GEDIT_CURRENT_DOCUMENT_NAME</span>&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span>
<span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$TMPDIR</span>/<span style="color: #007800;">${GEDIT_CURRENT_DOCUMENT_NAME%tex}</span>pdf&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$GEDIT_CURRENT_DOCUMENT_DIR</span>&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$?</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">then</span> evince <span style="color: #ff0000;">&quot;<span style="color: #007800;">${GEDIT_CURRENT_DOCUMENT_NAME%tex}</span>pdf&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$TMPDIR</span>&quot;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/a-useful-gedit-macro-for-latex/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HowTo: Get a RT2500-based wifi card working in Ubuntu</title>
		<link>http://porg.es/blog/howto-get-a-rt2500-based-wifi-card-working-in-ubuntu</link>
		<comments>http://porg.es/blog/howto-get-a-rt2500-based-wifi-card-working-in-ubuntu#comments</comments>
		<pubDate>Mon, 14 May 2007 20:45:07 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[howto]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://porg.es/blog/howto-get-a-rt2500-based-wifi-card-working-in-ubuntu</guid>
		<description><![CDATA[This was easier than I thought it was going to be. Nice and simple: Download the RT2500 Windows Drivers, and unzip them somewhere. Ensure you have wireless-tools and ndiswrapper installed. Open a terminal and browse to the folder where you unzipped the drivers. sudo ndiswrapper -i rt2500.inf Edit /etc/modules (as root) and add ‘ndiswrapper’. Edit [...]]]></description>
			<content:encoded><![CDATA[<p>This was easier than I thought it was going to be. Nice and simple:</p>
<ol>
<li>Download the <a href='http://porg.es/blog/wp-content/uploads/2007/05/rt2500_drivers.zip' title='RT2500 Windows Drivers'>RT2500 Windows Drivers</a>, and unzip them somewhere.</li>
<li>Ensure you have <code>wireless-tools</code> and <code>ndiswrapper</code> installed.</li>
<li>Open a terminal and browse to the folder where you unzipped the drivers.</li>
<li><code>sudo ndiswrapper -i rt2500.inf</code></li>
<li>Edit <code>/etc/modules</code> (as root) and add ‘ndiswrapper’.</li>
<li>Edit <code>/etc/modprobe.d/blacklist</code> (again as root) and add ‘blacklist rt2500’.</li>
<li>Restart, and you should now have a working card.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/howto-get-a-rt2500-based-wifi-card-working-in-ubuntu/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>About using Rosetta</title>
		<link>http://porg.es/blog/about-using-rosetta</link>
		<comments>http://porg.es/blog/about-using-rosetta#comments</comments>
		<pubDate>Fri, 11 May 2007 05:55:07 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[GNOME]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://porg.es/blog/about-using-rosetta</guid>
		<description><![CDATA[Oh, that reminds me… I should really contact some translators to ask for updates and release Gnome Specimen 0.2. —Wouter Bolsterlee The Gnome Specimen product is not set up for translation in Launchpad. You might want to talk with Wouter Bolsterlee (uws), the project registrant, about using Rosetta. —Launchpad Done!]]></description>
			<content:encoded><![CDATA[<p>
<blockquote>
<p>Oh, that reminds me… I should really contact some translators to ask for updates and release Gnome Specimen 0.2.</p>
</blockquote>
<p>—<cite><a href="http://uwstopia.nl/blog/2007/05/free-your-fonts">Wouter Bolsterlee</a></cite></p>
<p>
<blockquote>
<p>The Gnome Specimen product is not set up for translation in Launchpad.</p>
<p>You might want to talk with Wouter Bolsterlee (uws), the project registrant, about using Rosetta.</p>
</blockquote>
<p>—<cite><a href="https://launchpad.net/gnome-specimen/+translations">Launchpad</a></cite></p>
<p>Done!</p>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/about-using-rosetta/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using OpenDNS servers with bind9 easily</title>
		<link>http://porg.es/blog/using-opendns-servers-with-bind9-easily</link>
		<comments>http://porg.es/blog/using-opendns-servers-with-bind9-easily#comments</comments>
		<pubDate>Mon, 09 Oct 2006 07:25:46 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[bind9]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[OpenDNS]]></category>
		<category><![CDATA[Reference]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://porg.es/blog/using-opendns-servers-with-bind9-easily</guid>
		<description><![CDATA[The OpenDNS FAQ purports to have a solution to this problem, but it does something obscure to a file I don&#8217;t have on my system. So I quickly checked the man page and came up with this: /etc/bind/named.conf.options //Add this somewhere inside the options{}; section... forward only; forwarders { //OpenDNS 208.67.222.222; 208.67.220.220; };]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.opendns.com/faq/">OpenDNS <abbr title="Frequently Asked Questions">FAQ</abbr></a> purports to have a solution to this problem, but it does something obscure to a file I don&#8217;t have on my system. So I quickly checked the man page and came up with this:</p>
<h3>/etc/bind/named.conf.options</h3>
<pre><code>//Add this somewhere inside the options{}; section...
        forward only;
        forwarders {
                //OpenDNS
                208.67.222.222;
                208.67.220.220;
        };
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/using-opendns-servers-with-bind9-easily/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Easier local DNS cache</title>
		<link>http://porg.es/blog/easier-local-dns-cache</link>
		<comments>http://porg.es/blog/easier-local-dns-cache#comments</comments>
		<pubDate>Mon, 09 Oct 2006 06:59:24 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[bind9]]></category>
		<category><![CDATA[Cool]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Reference]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://porg.es/blog/easier-local-dns-cache</guid>
		<description><![CDATA[After a while pdnsd stopped working for me, and try as I might I can&#8217;t fix it. So I purged pdnsd and found an easier method, with no configuration this time!apt-get install bind9 resolvconf]]></description>
			<content:encoded><![CDATA[<p>After a while <a href="http://porg.es/blog/easy-persistent-local-dns-cache-to-reduce-lookup-times-2">pdnsd</a> stopped working for me, and try as I might I can&#8217;t fix it. So I purged <code>pdnsd</code> and found an easier method, with no configuration this time!<code>apt-get install bind9 resolvconf</code></p>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/easier-local-dns-cache/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Easy, persistent, local DNS cache to reduce lookup times</title>
		<link>http://porg.es/blog/easy-persistent-local-dns-cache-to-reduce-lookup-times-2</link>
		<comments>http://porg.es/blog/easy-persistent-local-dns-cache-to-reduce-lookup-times-2#comments</comments>
		<pubDate>Thu, 05 Oct 2006 02:26:15 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[Broken]]></category>
		<category><![CDATA[Cool]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Reference]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://porg.es/blog/easy-persistent-local-dns-cache-to-reduce-lookup-times-2</guid>
		<description><![CDATA[Important Update! Don&#8217;t use this method any more! I have a much easier way to do it in a more recent post. But for posterity&#8230; First install resolvconf and pdnsd: sudo apt-get install pdnsd resolvconf. Resolvconf handles the messy interaction between different programs fighting over the /etc/resolv.conf file, and pdnsd provides a persistent DNS daemon, [...]]]></description>
			<content:encoded><![CDATA[<h3>Important Update!</h3>
<p>Don&#8217;t use this method any more! I have a much easier way to do it in a <a href="http://porg.es/blog/easier-local-dns-cache">more recent post</a>.</p>
<h3>But for posterity&#8230;</h3>
<p>First install resolvconf and pdnsd: <code>sudo apt-get install pdnsd resolvconf</code>. Resolvconf handles the messy interaction between different programs fighting over the <code>/etc/resolv.conf</code> file, and pdnsd provides a <b>p</b>ersistent <b>DNS</b> <b>d</b>aemon, which will cache the DNS lookups on your machine in order to make browsing faster.</p>
<p>Next, you just need to edit pdnsd&#8217;s configuration file, <code>/etc/pdnsd.conf</code> as root. Edit it to look like this:</p>
<pre><code>global {
        perm_cache=512;
        cache_dir="/var/cache/pdnsd";
        max_ttl=604800;
        run_as="pdnsd";
        paranoid=on;
#       next setting allows ppp/ip-up update the name servers -- ABa / 20040213
        status_ctl=on;
        server_port=53;
        server_ip="127.0.0.1";
}

#Edit these to be your own servers if wished:
server {
        label = "OpenDNS";
        ip=208.67.222.222,208.67.220.220;
        proxy_only=on;
        timeout=10;
}

# if you installed resolvconf, and status_ctl=on
server {
    label="resolvconf";
}

source {
        ttl=86400;
        owner="localhost.";
#       serve_aliases=on;
        file="/etc/hosts";
}</pre>
<p></code></p>
<p>And finally, restart pdnsd with <code>sudo /etc/init.d/pdnsd restart</code> to use the new settings. In the example above, I've used OpenDNS's servers, but you can change these to whatever you want. As far as actual results go:</p>
<blockquote><p><code>~$ dig example.com</p>
<p>; <<>> DiG 9.3.2 <<>> example.com<br />
;; global options:  printcmd<br />
;; Got answer:<br />
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17447<br />
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0</p>
<p>;; QUESTION SECTION:<br />
;example.com.                   IN      A</p>
<p>;; ANSWER SECTION:<br />
example.com.            172800  IN      A       192.0.34.166</p>
<p><b>;; Query time: 513 msec</b><br />
;; SERVER: 127.0.0.1#53(127.0.0.1)<br />
;; WHEN: Thu Oct  5 15:24:19 2006<br />
;; MSG SIZE  rcvd: 45</p>
<p>$ dig example.com</p>
<p>; <<>> DiG 9.3.2 <<>> example.com<br />
;; global options:  printcmd<br />
;; Got answer:<br />
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19338<br />
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0</p>
<p>;; QUESTION SECTION:<br />
;example.com.                   IN      A</p>
<p>;; ANSWER SECTION:<br />
example.com.            172799  IN      A       192.0.34.166</p>
<p><b>;; Query time: 0 msec</b><br />
;; SERVER: 127.0.0.1#53(127.0.0.1)<br />
;; WHEN: Thu Oct  5 15:24:20 2006<br />
;; MSG SIZE  rcvd: 45<br />
</code></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/easy-persistent-local-dns-cache-to-reduce-lookup-times-2/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Normalizing your MP3 collection with mp3gain</title>
		<link>http://porg.es/blog/normalizing-your-mp3-collection-with-mp3gain</link>
		<comments>http://porg.es/blog/normalizing-your-mp3-collection-with-mp3gain#comments</comments>
		<pubDate>Wed, 20 Sep 2006 02:36:32 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[Cool]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Reference]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://porg.es/blog/normalizing-your-mp3-collection-with-mp3gain</guid>
		<description><![CDATA[Carthik Sharma from Ubuntu Blog suggests the following method to normalize all the MP3 files in your collection: find . -type f -iname &apos;*.mp3&apos; -print0 &#124; xargs -0 mp3gain -r -k Unfortunately, this seems to have problems with very large collections (I suspect that the command line is being filled up), so here&#8217;s what I [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://ubuntu.wordpress.com/2006/09/11/normalize-the-gain-playback-volume-of-your-mp3s/">Carthik Sharma from Ubuntu Blog suggests the following method to normalize all the MP3 files in your collection</a>:</p>
<pre><code>find . -type f -iname &apos;*.mp3&apos; -print0 | xargs -0 mp3gain -r -k</code></pre>
<p>Unfortunately, this seems to have problems with very large collections (I suspect that the command line is being filled up), so here&#8217;s what I came up with:</p>
<pre><code>find . -iname &apos;*.mp3&apos; -execdir mp3gain -r -k &quot;{}&quot; &#x5C;; &#038;</code></pre>
<p>If you&#8217;d rather use album normalization (and you have your files separated by album such as &#8220;~/Music/David Bowie/Hunky Dory&#8221;/):</p>
<pre><code>find . -iname &apos;*.mp3&apos; -execdir mp3gain -r -k <u>-a</u> &quot;{}&quot; <u>+</u> &#038;</code></pre>
<h3>How to use it</h3>
<p>Simply open a terminal, browse to your music directory (using <code>cd</code>), and type it in.</p>
<h3>Break it down</h3>
<p>What the command does:</p>
<ol>
<li><code>find . -iname &apos;*.mp3&apos;</code> finds all MP3 files in the current directory and all subdirectories.</li>
<li><code>-execdir mp3gain -r -k &quot;{}&quot; \; &#038;</code> executes &#8220;mp3gain -r -k&#8221; on each file (the filename goes where {} is found). The semi-colon indicates to execute the command once per file, but since ; is also a significant character for bash, you need to escape it with a backslash. The final &#8216;&#038;&#8217; tells bash to run the command in the background.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/normalizing-your-mp3-collection-with-mp3gain/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>DBus, Mono, Rhythmbox, and Beagle, Oh My!</title>
		<link>http://porg.es/blog/dbus-mono-rhythmbox-and-beagle-oh-my</link>
		<comments>http://porg.es/blog/dbus-mono-rhythmbox-and-beagle-oh-my#comments</comments>
		<pubDate>Fri, 15 Sep 2006 10:26:38 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mono]]></category>

		<guid isPermaLink="false">http://porg.es/blog/dbus-mono-rhythmbox-and-beagle-oh-my</guid>
		<description><![CDATA[So I had this idea of writing a quick search plugin for Beagle to search Rhythmbox&#8217;s current playlist titles. They would show up in the search GUI and then you&#8217;d double-click on one and it&#8217;d handle this (probably through a pseudo-URL like playlist://rhythmbox/my-playlist-name which seems to be the de facto standard amongst Beagle plugins) by [...]]]></description>
			<content:encoded><![CDATA[<p>So I had this idea of writing a quick search plugin for Beagle to search Rhythmbox&#8217;s current playlist titles. They would show up in the search GUI and then you&#8217;d double-click on one and it&#8217;d handle this (probably through a pseudo-URL like <code>playlist://rhythmbox/my-playlist-name</code> which seems to be the <i>de facto</i> standard amongst Beagle plugins) by sending a DBus event to Rhythmbox to start playing this playlist. Sounds simple enough.</p>
<h3>Promise</h3>
<p>First of all I headed over to the Beagle site. It turns out that if you want to do more than handle a specific file-type (not an option in this case because the playlists are stored as <code>.xml</code>) you create not a &#8220;Filter&#8221; but a &#8220;Queryable&#8221;. Unfortunately the Queryable HowTo is <a href="http://beagle-project.org/index.php?title=Queryable_HOWTO">still being written</a>. Nevermind, I can always ask on the mailing list, and taking a look through the tutorial for Filters shows that the API for that is nice and clean and should be similar for the Queryables.</p>
<p>Next I try to find a reference for the C# DBus bindings. I install the Monodoc documentation for DBus, only to discover everything marked with &#8220;Documentation for this section has not yet been entered&#8221;&mdash;the default message for undocumented functions, classes, and so on. Nevertheless, I find <a href="http://www.electricrelaxation.com/2006/09/08/rhythmbox-toggle-showhide-using-dbus-and-python">a short tutorial on how to use Python with DBus to control Rhythmbox</a>. The class names and functions seem to have similar titles in C#, so I figure this will map fairly directly.</p>
<p>Finding the DBus reference for Rhythmbox takes a fair bit more effort, trawling through mailing list archives on Google. Eventually I find the DBus APIs hiding in a couple of <code>.xml</code> files in the CVS repositories; <a href="http://cvs.gnome.org/viewcvs/*checkout*/rhythmbox/shell/rb-playlist-manager.xml?content-type=text%2Fplain"><code>org.gnome.Rhythmbox.PlaylistManager</code></a> looks promising.</p>
<h3>Misfortune</h3>
<p>Unfortunately, I find a <a href="http://blogs.gnome.org/view/tko/2006/07/27/">post by a last-exit hacker</a> in which he states (my emphasis):</p>
<blockquote><p>As I was told <em>DBus C# bindings are unusable</em> I went on about writing DBus# objects the hard way.</p></blockquote>
<p>What? This can&#8217;t be right, I&#8217;ve already written a little test program:</p>
<pre><code>using System;
using DBus;

namespace RhythmboxQuery
{
   class MainClass
   {
      public static void Main(string[] args)
      {
         Connection bus = Bus.GetSessionBus();
         try {
            Service rhythmbox = Service.Get(bus,"org.gnome.Rhythmbox");
         } catch (ApplicationException ex) {
            Console.WriteLine("Rhythmbox not started: " + ex);
            return;
         }
         Console.WriteLine("Found Rhythmbox.");
         /*

         Okay, so all I need to do now is to call `getPlaylists` on:
         /org/gnome/Rhythmbox/PlaylistManager

         */
         Console.WriteLine("Uhoh.");
      }
   }
}</code></pre>
<p>Despite my valiant attempts to stave off the past through trivial C# programs, the DBus site <a href="http://www.freedesktop.org/wiki/Software_2fDBusBindings">confirms the aforementioned revelation</a>:</p>
<blockquote><p>They are schedualed to be removed from the core but has yet to find a maintainer. [sic]</p></blockquote>
<h3>Epilogue</h3>
<p>As it turns out, what I had been planning to do would have been impossible anyway because the Rhythmbox DBus bindings lack a <code>PlayPlaylist</code> function in any of the three interfaces. Also, it seems that DBus under C# only plays nicely with C# objects that you have access to&mdash;but this could be just because I couldn&#8217;t find a single example of how to call methods on non-C# DBus applications.</p>
<p>Ah well, that Beagle Filter API did seem quite nice anyway, I wonder if there are any filetypes I could parse out there&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/dbus-mono-rhythmbox-and-beagle-oh-my/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Ur-Quan Masters on Ubuntu AMD64</title>
		<link>http://porg.es/blog/the-ur-quan-masters-on-ubuntu-amd64</link>
		<comments>http://porg.es/blog/the-ur-quan-masters-on-ubuntu-amd64#comments</comments>
		<pubDate>Thu, 14 Sep 2006 20:41:31 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[Cool]]></category>
		<category><![CDATA[Game]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Reference]]></category>
		<category><![CDATA[Review]]></category>

		<guid isPermaLink="false">http://porg.es/blog/the-ur-quan-masters-on-ubuntu-amd64</guid>
		<description><![CDATA[At the moment, The Ur-Quan Masters doesn&#8217;t work on AMD64. This is a shame, because I just found it and realised Star Control II was the game that I had played on my friend-down-the-road&#8217;s computer so many years ago. Attempting to fix this by forcing the install of the 32-bit version of uqm doesn&#8217;t work, [...]]]></description>
			<content:encoded><![CDATA[<p>At the moment, <a href="http://sc2.sourceforge.net/">The Ur-Quan Masters</a> doesn&#8217;t work on AMD64. This is a shame, because I just found it and realised Star Control II was the game that I had played on my friend-down-the-road&#8217;s computer so many years ago.</p>
<p>Attempting to fix this by forcing the install of the 32-bit version of <code>uqm</code> doesn&#8217;t work, because for some reason then apt won&#8217;t recognise that it is installed and complain that <code>uqm-content</code> has unmet dependencies. So here&#8217;s the official recommendation from me:</p>
<ol>
<li>Install <code>uqm</code> normally with the package manager.</li>
<li>Download the i386 .debs, extract them and overwrite the binary files from <code>uqm</code> (there are two of them).</li>
<li>Install <code>ia32-libs-sdl</code> for the 32-bit versions of the libraries it depends on.</li>
</ol>
<p>&#8230; and it should work perfectly. If you want voice-overs and music (yes!), head to <a href="http://sc2.sourceforge.net/downloads.php">the UQM download page</a>, and download the second two files listed under &#8220;Content&#8221; (you already have the first). These are in fact just renamed zip files, so unzip them to <code>/usr/share/games/uqm/content/</code> and you&#8217;re good to go.</p>
<p>And the game? Excellent. This is much better than the last game I bought&mdash;Civilization IV.</p>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/the-ur-quan-masters-on-ubuntu-amd64/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Neat little Linux tool</title>
		<link>http://porg.es/blog/neat-little-linux-tool</link>
		<comments>http://porg.es/blog/neat-little-linux-tool#comments</comments>
		<pubDate>Tue, 12 Sep 2006 08:14:45 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[Cool]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Reference]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://porg.es/blog/neat-little-linux-tool</guid>
		<description><![CDATA[Command Not Found is a great little utility for Linux. If you&#8217;ve ever tried to follow a set of instructions only to find that you don&#8217;t have some of the CLI programs needed, this will come to your rescue. Install command-not-found then add this to your ~/.bashrc: function command_not_found_handle { /usr/bin/command-not-found $1 return $? } [...]]]></description>
			<content:encoded><![CDATA[<p>Command Not Found is a great little utility for Linux. If you&#8217;ve ever tried to follow a set of instructions only to find that you don&#8217;t have some of the <abbr title="command line interface">CLI</abbr> programs needed, this will come to your rescue.</p>
<p>Install <code>command-not-found</code> then add this to your <code>~/.bashrc</code>:</p>
<pre><code>function command_not_found_handle {
        /usr/bin/command-not-found $1
        return $?
}</code></pre>
<p>And you&#8217;re all done:</p>
<blockquote><p><code>~$ ssed<br />
The program 'ssed' is currently not installed, you can install it by typing:<br />
sudo apt-get install ssed<br />
</code></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/neat-little-linux-tool/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spotted</title>
		<link>http://porg.es/blog/spotted</link>
		<comments>http://porg.es/blog/spotted#comments</comments>
		<pubDate>Mon, 04 Sep 2006 22:33:14 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[Cool]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[New Zealand]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://porg.es/blog/spotted</guid>
		<description><![CDATA[This seen outside New World supermarket, Wellington, New Zealand. I&#8217;m not sure if the placement is some kind of metaphor.]]></description>
			<content:encoded><![CDATA[<p><a class="imagelink" href="http://porg.es/blog/wp-content/uploads/2006/09/0_0.jpg" title="Ubuntu sticker on rubbish bin"><img id="image76" src="http://porg.es/blog/wp-content/uploads/2006/09/0_0.thumbnail.jpg" alt="Ubuntu sticker on rubbish bin" /></a></p>
<p>This seen outside New World supermarket, Wellington, New Zealand. I&#8217;m not sure if the placement is some kind of metaphor.</p>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/spotted/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DeskBar Calculator</title>
		<link>http://porg.es/blog/deskbar-calculator</link>
		<comments>http://porg.es/blog/deskbar-calculator#comments</comments>
		<pubDate>Mon, 04 Sep 2006 22:05:22 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[Cool]]></category>
		<category><![CDATA[GNOME]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://porg.es/blog/deskbar-calculator</guid>
		<description><![CDATA[As created by Spooky. It really is easy to use (and surprisingly simple to install), and much easier than popping up Qalculate (despite its awesomnity). Follow his lead and you&#8217;ll have calculation support in DeskBar in less than a minute. The thing that&#8217;s nice about these Python applications is their extensibility, and not having to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://spooky-possum.org/cgi-bin/pyblosxom.cgi/db-calculator.html" title="DeskBar Calculator">As created by Spooky</a>. It really is easy to use (and surprisingly simple to install), and much easier than popping up <a href="http://qalculate.sourceforge.net/">Qalculate</a> (despite its awesomnity). <a href="http://www.spooky-possum.org/callum/software/index.html#db-calculator" title="DeskBar calculator install instructions">Follow his lead</a> and you&#8217;ll have calculation support in DeskBar in less than a minute.</p>
<p>The thing that&#8217;s nice about these Python applications is their extensibility, and not having to restart them for new plugins and suchlike. Now if only they&#8217;d automatically check for updates&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/deskbar-calculator/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Excursions into Parrot</title>
		<link>http://porg.es/blog/excursions-into-parrot</link>
		<comments>http://porg.es/blog/excursions-into-parrot#comments</comments>
		<pubDate>Tue, 08 Aug 2006 10:37:39 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Parrot]]></category>

		<guid isPermaLink="false">http://porg.es/blog/excursions-into-parrot</guid>
		<description><![CDATA[Let me warn you from the start: Patrick Michaud&#8217;s slides make it look deceptively easy! First of all, I created &#8220;simple.pg&#8221; according to his recipe: grammar Simple::Grammar ; token variable { [ &#124; _ ] \w* } token number { \d+ } token addop { \+ &#124; - } token mulop { \* &#124; / [...]]]></description>
			<content:encoded><![CDATA[<p>Let me warn you from the start: <a href="http://www.pmichaud.com/2006/pres/yapc-parsers/">Patrick Michaud&#8217;s slides</a> make it look deceptively easy!</p>
<p>First of all, I created &#8220;simple.pg&#8221; according to his recipe:</p>
<pre><code>grammar Simple::Grammar ;

token variable { [ <alpha> | _ ] \w* }
token number { \d+ }

token addop { \+ | - }
token mulop { \* | / }

rule expression { <addterm> [ <addop> <addterm> ] * }
rule addterm { <multerm> [ <mulop> <multerm> ] * }
rule multerm { <variable> | <number> | \( <expression> \) }</code></pre>
<p>This looks all fine and dandy. Next, to compile: <code>$ parrot pgc.pir simple.pg > simple.pir</code>.</p>
<pre><code>Error reading source file pgc.pir.</code></pre>
<p>Huh? Well he didn&#8217;t say anything about that. Maybe I have a path wrong somewhere? A quick &#8220;locate&#8221; reveals it doesn&#8217;t lie anywhere on my computer. Next step is to check the downloaded source code to see if I wasn&#8217;t meant to delete it yet&#8230; ah, yes, it&#8217;s hiding under <code>./compilers/pge/</code>. It looks like it will be easier to work from this directory, so I&#8217;ll move everything into there.</p>
<p>Unfortunately, pgc.pir won&#8217;t run straight away, and you&#8217;ll need to patch it up a bit:</p>
<pre><code>@@ -49,7 +49,7 @@
     .param pmc args
     load_bytecode 'Getopt/Obj.pbc'
     load_bytecode 'dumper.pbc'
-    load_bytecode 'PGE/Dumper.pbc'
+    load_bytecode 'Data/Dumper.pbc'
     '__onload'()

     ##   create an option parser
@@ -153,8 +153,8 @@

 .sub '__onload' :load
     load_bytecode 'PGE.pbc'
-    load_bytecode 'PGE/Text.pbc'
-    load_bytecode 'PGE/Util.pbc'
+    load_bytecode 'PGE/Text.pir'
+    load_bytecode 'PGE/Util.pir'

     .local pmc p6regex
     p6regex = compreg 'PGE:<img src="http://porg.es/blog/wp-content/plugins/wp-smiley-switcher/noktahhitam/icon_razz.gif" alt="" />6Regex'
</code></pre>
<p>Now it runs fine and generates the output file perfectly. Quite a bit of code in there! Next to use the parser on a real string, using the example:</p>
<pre><code>.include 'simple.pir'

.sub 'foo'
  ...
  ##   get the parrot sub for parsing an expression
  parse = find_global 'Simple::Grammar', 'expression'

  ##   the expression to be parsed
  expr = '3 + 4 * (a-2)'

  ##   parse the expression
  match = parse(expr)

  ##   dump the parse tree
  '_dumper'(match)</code></pre>
<p>That little ellipsis is really in there to let you know that you need to read quite a few more Parrot docs before you&#8217;re allowed to progress past this step. <img src="http://porg.es/blog/wp-content/plugins/wp-smiley-switcher/noktahhitam/icon_smile.gif" alt="" /></p>
<p>In fact, you&#8217;ll be able to get up to speed in no time just by copying some of the example files. I found that I could get by with guessing a bit;</p>
<ul>
<li>.sub needed an .end,</li>
<li>the main method needs to be marked :main to run automatically,</li>
<li>the variables need to be declared&#8230; with appropriate types&#8230; you can&#8217;t just use pmc for everything,</li>
<li>and the _dumper code needed to be loaded.</li>
</ul>
<p>Here&#8217;s what it eventually looked like:</p>
<pre><code>.include 'simple.pir'

.sub main :main
        .local pmc parse, match
        .local string expr
        ## get the parrot sub for parsing an expression
        parse = find_global 'Simple::Grammar', 'expression'
        ## the expression to be parsed
        expr = "3 + 4 * (a-2)"
        ## parse the expression
        match = parse(expr)
        ## dump the parse tree
        load_bytecode 'dumper.pbc'
        '_dumper'(match)
.end
</code></pre>
<p>But that&#8217;s not all, you&#8217;ll need to jump through the automagically-generated parser code to put in things that it forgot to. For brevity, here&#8217;s the diff:</p>
<pre><code>@@ -1,6 +1,7 @@
       .sub '__onload' :load
           .local pmc optable
           ## namespace Simple::Grammar
+          load_bytecode 'PGE.pbc'
           $I0 = find_type 'Simple::Grammar'
           if $I0 != 0 goto onload_186
           $P0 = subclass 'PGE::Grammar', 'Simple::Grammar'
@@ -288,6 +289,7 @@
           .local string target    :unique_reg
           .local pmc mfrom, mpos  :unique_reg
           .local int cpos, iscont :unique_reg
+          load_bytecode 'PGE/Match.pir'
           $P0 = getclass 'PGE::Match'
           (mob, cpos, target, mfrom, mpos, iscont) = $P0.'new'(mob, adverbs :flat :named)           .local pmc ustack :unique_reg
@@ -321,6 +323,7 @@
           goto fail_cut
         R: # concat
         R147: # subrule ws
+          load_bytecode 'PGE/Regex.pir'
           captob = captscope
           $P0 = getattribute captob, '$.pos'
           $P0 = pos
</code></pre>
<p>And now, one and a half hours later, for the grand finale&#8230;</p>
<pre><code>$ parrot simpleparse.pir
"VAR1" => PMC 'PGE::Match' { ... }</code></pre>
<p>Voilà! My first excursion into Parrot. A bit fiddly, but I enjoyed myself <img src="http://porg.es/blog/wp-content/plugins/wp-smiley-switcher/noktahhitam/icon_smile.gif" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/excursions-into-parrot/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Logo Fight!</title>
		<link>http://porg.es/blog/logo-fight</link>
		<comments>http://porg.es/blog/logo-fight#comments</comments>
		<pubDate>Sun, 06 Aug 2006 05:29:00 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://porg.es/blog/logo-fight</guid>
		<description><![CDATA[While stumbling around the internet, I came across the site for Human Rights First, whose logo bears an uncanny resemblance to Ubuntu Linux&#8217;s.]]></description>
			<content:encoded><![CDATA[<p>While <a href="http://www.stumbleupon.com">stumbling</a> around the internet, I came across the site for <a href="http://www.humanrightsfirst.org/index.asp">Human Rights First</a>, whose logo bears an uncanny resemblance to Ubuntu Linux&#8217;s.</p>
<p><img src="http://www.humanrightsfirst.org/images/hrf/home_brand.gif" alt="Human Rights First's logo"/><br />
<img src="http://www.edubuntu.org/files/ubuntu.jpg" alt="Ubuntu's logo"/></p>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/logo-fight/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Opera 9 on Ubuntu Dapper with AMD64</title>
		<link>http://porg.es/blog/opera-9-on-ubuntu-dapper-with-amd64</link>
		<comments>http://porg.es/blog/opera-9-on-ubuntu-dapper-with-amd64#comments</comments>
		<pubDate>Tue, 11 Jul 2006 00:36:51 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Reference]]></category>

		<guid isPermaLink="false">http://porg.es/blog/opera-9-on-ubuntu-dapper-with-amd64</guid>
		<description><![CDATA[The process used for this is the same as used for the previous post. Download the version of Opera 9 for i386 Linux from the official site. Go to the Ubuntu package site and download these packages (also for i386): libqt3-mt libaudio2 libxcursor1 libxft2 libxfixes3 Open each package in turn (don&#8217;t install!) and copy the [...]]]></description>
			<content:encoded><![CDATA[<p>The process used for this is the same as used for the <a href="http://porg.es/blog/wine-on-ubuntu-with-amd64">previous post</a>.</p>
<ol>
<li>Download the version of Opera 9 for i386 Linux from the official site.</li>
<li>Go to the Ubuntu package site and download these packages (also for i386):
<ul>
<li>libqt3-mt</li>
<li>libaudio2</li>
<li>libxcursor1</li>
<li>libxft2</li>
<li>libxfixes3</li>
</ul>
</li>
<li>Open each package in turn (don&#8217;t install!) and copy the libraries to the <code>/lib32</code> folder as root. Open the package, then open &#8220;data.tar.gz&#8221;, then find the <code>/lib</code> folder. You don&#8217;t need to worry about copying anything under the <code>/usr/share</code> folder, these are just docs and some unneeded symlinks.</li>
<li>Install Opera by browsing to the folder where you downloaded it to and entering <code>sudo dpkg -i --force-all opera*.deb</code>.</li>
</ol>
<p>All done!</p>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/opera-9-on-ubuntu-dapper-with-amd64/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Wine on Ubuntu with AMD64</title>
		<link>http://porg.es/blog/wine-on-ubuntu-with-amd64</link>
		<comments>http://porg.es/blog/wine-on-ubuntu-with-amd64#comments</comments>
		<pubDate>Mon, 26 Jun 2006 07:01:35 +0000</pubDate>
		<dc:creator>Porges</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Reference]]></category>

		<guid isPermaLink="false">http://porg.es/blog/wine-on-ubuntu-with-amd64</guid>
		<description><![CDATA[First, go get the latest version of Wine (for i386). Ensure that you have the correct version (6.06 is Dapper). Open up a terminal in the folder you saved it to: sudo apt-get install ia32-libs sudo dpkg -i --force-architecture wine*.deb Next, head to the Ubuntu repository and download both libXx86dga1 and libXx86vm1 (for i386). Extract [...]]]></description>
			<content:encoded><![CDATA[<p>First, go get the <a href="http://wine.budgetdedicated.com/apt/pool/main/w/wine/">latest version of Wine</a> (for i386). Ensure that you have the correct version (6.06 is Dapper).</p>
<p>Open up a terminal in the folder you saved it to:</p>
<pre><code>sudo apt-get install ia32-libs
sudo dpkg -i --force-architecture wine*.deb</code></pre>
<p>Next, head to the <a href="http://packages.ubuntulinux.org/dapper/libs/">Ubuntu repository</a> and download both <code>libXx86dga1</code> and <code>libXx86vm1</code> (for i386). Extract them (don&#8217;t install!) and then extract the data.tar.gz files inside of them. Browse to the <code>/usr/lib32</code> subfolder, then copy both the symlink and the shared library to your <code>/lib32</code> folder (you&#8217;ll need to do this as root). Make sure you do this for both these packages.</p>
<p>I&#8217;m currently testing this with the <a href="http://www.tatanka.com.br/ies4linux/index-en.html">IEs for Linux</a> script, and everything seems to be working so far. IE6 runs perfectly (it may not show up correctly the first time you open it but it&#8217;s fine after that).</p>
]]></content:encoded>
			<wfw:commentRss>http://porg.es/blog/wine-on-ubuntu-with-amd64/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

