<?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"
	>

<channel>
	<title>blog.s11n.net &#187; General</title>
	<atom:link href="http://blog.s11n.net/?feed=rss2&#038;cat=1" rel="self" type="application/rss+xml" />
	<link>http://blog.s11n.net</link>
	<description>blog for s11n.net</description>
	<pubDate>Fri, 30 Apr 2010 00:38:36 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Achtung Ubuntu 10.4 users: data loss</title>
		<link>http://blog.s11n.net/?p=86</link>
		<comments>http://blog.s11n.net/?p=86#comments</comments>
		<pubDate>Fri, 30 Apr 2010 00:38:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.s11n.net/?p=86</guid>
		<description><![CDATA[i&#8217;m just so frigging sick to my stomach at the moment because Ubuntu 10.4 ate my home directory, and i wanted to take a moment to warn other Ubuntu upgraders about a data-loss scenario.
Full details are in the bug report:
https://bugs.launchpad.net/ubuntu/+bug/571958
If you&#8217;re going to use Ubuntu 10.4, make damned sure your shell scripts do not depend [...]]]></description>
			<content:encoded><![CDATA[<p>i&#8217;m just so frigging sick to my stomach at the moment because Ubuntu 10.4 ate my home directory, and i wanted to take a moment to warn other Ubuntu upgraders about a data-loss scenario.</p>
<p>Full details are in the bug report:</p>
<p><a href="https://bugs.launchpad.net/ubuntu/+bug/571958">https://bugs.launchpad.net/ubuntu/+bug/571958</a></p>
<p>If you&#8217;re going to use Ubuntu 10.4, make damned sure your shell scripts do not depend on case-sensitive shell expansion!</p>
<p>(Yes, i have backups, but i&#8217;ve got to pull them from 20 different source repos and a 15GB Dropbox, and the whole point of the exercise which revealed the bug was to avoid having to pull down 30GB of data from the net.)</p>
<p>&gt;:-(</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.s11n.net/?feed=rss2&amp;p=86</wfw:commentRss>
		</item>
		<item>
		<title>A live previewer/editor for Google Code Wiki</title>
		<link>http://blog.s11n.net/?p=85</link>
		<comments>http://blog.s11n.net/?p=85#comments</comments>
		<pubDate>Thu, 22 Apr 2010 12:54:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.s11n.net/?p=85</guid>
		<description><![CDATA[Hi, all!
And how for something very different&#8230;
A couple of days ago i was looking for JavaScript code which can parse the Google Code wiki syntax reasonably well. i stumbled upon (via a link in a bug report) some code by Fabien Ménager which did most of the work. After coming across a few too many [...]]]></description>
			<content:encoded><![CDATA[<div>Hi, all!</p>
<p>And how for something very different&#8230;</p>
<p>A couple of days ago i was looking for JavaScript code which can parse the Google Code wiki syntax reasonably well. i stumbled upon (via a link in a bug report) some code by Fabien Ménager which did most of the work. After coming across a few too many corner cases, i sat down to re-implement the parser using a char-by-char scan, rather than regexes, for most of the work.</p>
<p>It&#8217;s now about 20 hours after that work started, i haven&#8217;t slept in 26 hours, and Fabien and i now have:</p>
<ul>
<li>A reasonable parser (only missing a few markup features): <a title="http://code.google.com/p/wikiwym/" href="http://code.google.com/p/wikiwym/" target="_blank">http://code.google.com/p/wikiwym/</a></li>
<li>An application to demo it: <a title="http://wikiwym.googlecode.com/svn/trunk/index.html" href="http://wikiwym.googlecode.com/svn/trunk/index.html" target="_blank">http://wikiwym.googlecode.com/svn/trunk/index.html</a></li>
<li>And another application which allows the user to load arbitrary wiki pages from arbitrary Google Code-hosted projects and preview them in raw and HTML modes. That code can then be pasted back into the Google Code wiki editor when editing is finished: <a title="http://fossil.wanderinghorse.net/demos/wikiwym/" href="http://fossil.wanderinghorse.net/demos/wikiwym/" target="_blank">http://fossil.wanderinghorse.net/demos/wikiwym/</a></li>
</ul>
<p>Basically, that last app provides an editor environment for people who edit wiki pages of arbitrary Google Code projects. The app cannot save the data back to Google Code for you, but it provides a relatively effective interface for editing wiki markup. If you make a mistake while typing in the editor, for example forgetting to close an inlined markup tag (bold, italics, etc.), the preview mode will prominently mark the error so you know where to fix it (and what to fix).</p>
<p>If you&#8217;re looking for a wiki parser implementation in JavaScript, this one might just suit you. If you&#8217;re a parser guru and would like to help us improve the parser, then please get in touch!</p>
<p><strong><em>Happy hacking!</em></strong></p>
<p>&#8212;&#8211; stephan beal</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.s11n.net/?feed=rss2&amp;p=85</wfw:commentRss>
		</item>
		<item>
		<title>CLI-like Web Apps with JavaScript</title>
		<link>http://blog.s11n.net/?p=83</link>
		<comments>http://blog.s11n.net/?p=83#comments</comments>
		<pubDate>Fri, 02 Apr 2010 19:53:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.s11n.net/?p=83</guid>
		<description><![CDATA[On April 1st xkcd.com added a new web interface which allows one to view the xkcd comics using a Unix-style command-line interface: http://uni.xkcd.com/
Interested in how it was being done, i followed the source code links, downloaded it, and set it up locally. After spending the whole day hacking on it, and sharing several mails with the [...]]]></description>
			<content:encoded><![CDATA[<p>On April 1st <a title="xkcd.com" href="http://xkcd.com">xkcd.com</a> added a new web interface which allows one to view the xkcd comics using a Unix-style command-line interface: <a title="http://uni.xkcd.com/" href="http://uni.xkcd.com/">http://uni.xkcd.com/</a></p>
<p>Interested in how it was being done, i followed the source code links, downloaded it, and set it up locally. After spending the whole day hacking on it, and sharing several mails with the author (who goes by the moniker Chromakode), i&#8217;m really interested in exploring this idea for web GUIs a bit more&#8230;</p>
<p>For those interested in truly geeky things, the source code is here:</p>
<p><a title="xkcdfools source code" href="http://github.com/chromakode/xkcdfools">http://github.com/chromakode/xkcdfools</a></p>
<p>i&#8217;ve tied that into an experimental JavaScript app framework i&#8217;ve been tinkering on the past year:</p>
<p><a title="jqApp Console Demo/Experiment" href="http://wanderinghorse.net/computing/javascript/jquery/jqapp/console.php">http://wanderinghorse.net/computing/javascript/jquery/jqapp/console.php</a></p>
<p>That page demonstrates tying in the CLI interface with JSON-centric RPC. e.g. the &#8220;ping&#8221; command sends of a JSON-structured RPC request to the server, the server dispatches it to the appropriate event handler, the handler answers and sends us back another JSON object describing the result. Such an interface could be used to write some exceedingly geeky web applications.</p>
<p>In any case&#8230; not something of general interest, but in case there are a few other hackers who find the Web/CLI mixture interesting&#8230; see the above links.</p>
<p><em><strong>Happy Hacking!</strong></em></p>
<p>&#8212;&#8211; stephan</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.s11n.net/?feed=rss2&amp;p=83</wfw:commentRss>
		</item>
		<item>
		<title>Stupid C Tricks: Portably Passing Function Pointers via (void*)</title>
		<link>http://blog.s11n.net/?p=82</link>
		<comments>http://blog.s11n.net/?p=82#comments</comments>
		<pubDate>Tue, 02 Mar 2010 16:15:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[c]]></category>

		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.s11n.net/?p=82</guid>
		<description><![CDATA[Hello, fellow C programmers!
(If you don&#8217;t program in C (or even know what that means) then the following won&#8217;t interest you in the slightest. If you are a C programmer, it might interest you in the slightest.)
It is common for C code to use the venerable void pointer, and (despite what our OO teachings might [...]]]></description>
			<content:encoded><![CDATA[<p>Hello, fellow C programmers!</p>
<p>(If you don&#8217;t program in C (or even know what that means) then the following won&#8217;t interest you <em>in the slightest</em>. If you are a C programmer, it <em>might</em> interest you in the slightest.)</p>
<p>It is common for C code to use the venerable void pointer, and (despite what our OO teachings might tell us), the void pointer isn&#8217;t the bad guy. Mis-use of void pointers is the bad guy. Because there are <em style="font-style: italic;">lots</em> of ways to abuse a void pointer, void pointers are, at least in higher-level APIs, generally to be avoided. Lower-level APIs often cannot get by without them.</p>
<p>Today&#8217;s talk is not about void pointers in general (there&#8217;s an awful lot to say about void!), but specifically about using a void pointer to hold a function pointer.</p>
<p>Did you know that passing a function pointer via a void pointer, casting that void pointer to the original function pointer, and dereferencing (i.e. calling) the casted function results in undefined behaviour? That&#8217;s what the C standard says.</p>
<p>What does that mean? It means the following code is invokes undefined behavhiour in any country or providence which respects the C Standard:</p>
<pre>typedef int (*my_callback)( void * state );
my_callback cb = some_callback_function;
void * ptr = cb;
((my_callback)ptr)( ... ); // &lt;--- undefined behaviour!</pre>
<p>The above code is rather contrived, but it demonstrates a feature which is seen from time to time in ancient C code. It is also used in some OS-level functions which open DLLs (e.g. based on dlopen() on POSIX systems). DLL-loading systems often look for a symbol with a specific name within the DLL right after they open it. If they find it, they treat it like a function and call it. Some DLL-loading systems provide a similar feature for closing a DLL. Higher-level &#8220;plugin&#8221; systems, common in today&#8217;s applications, often use this approach to fetch a factory function from the DLL, which is then used to create an instance of the plugin.</p>
<p>If such systems expect their magic symbol(s) to be a function (and in my experience they do!), then they are relying on undefined behaviour. And we abhor undefined behaviour, don&#8217;t we?</p>
<p>There is a portable, and only slightly inconvenient, workaround. In short, we add a level of indirection between the function we want to fetch from the DLL and the symbol name the DLL-opener expects to find. That level of indirection is a tiny struct:</p>
<pre>typedef int (*my_callback)( void * state );
typedef struct my_callback_struct {
    my_callback callback;
} my_callback_struct;</pre>
<p>And in our DLLs we use that indirection like so:</p>
<pre>/* implements the my_callback() interface. */
static int private_callback( void * state );
/* The symbol our DLL/plugin system will look for: */
const my_callback_struct TheExpectedSymbolName =  {private_callback};</pre>
<p>In the DLL opening code, we look for &#8220;TheExpectedSymbolName&#8221;, but instead of casting it to a function pointer, we cast it to a my_callback_struct pointer. From that object, we can invoke its member function without invoking undefined behaviour. Obviously, if the DLL contains a non-my_callback_struct with the expected symbol name, behaviour <em style="font-style: italic;">is</em> undefined, but the function-pointer approach has the same problem.</p>
<p>This approach can easily be expanded to provide open() and close() routines for plugins, or any other application-specific plugin functionality. It can be combined with macros to allow clients to easily implement a plugin by calling the macro and passing pointers to their callback implementations. Since the DLL lookup symbols must unique, however, it means we have a limitation of one logical plugin per DLL file. (That is the norm in most plugin systems, but this limitation makes it an explicitproperty of such systems.)</p>
<p>In C++ (as opposed to C), the ability to to construct objects and call functions during the DLL&#8217;s static initialization phase (i.e. while it&#8217;s being opened, before the DLL opener gets it back) allows for an elegant solution to all of the above-mentioned problems and limitations. We won&#8217;t go into that here, but for interested readers there is a detailed article about it, called <em>Classloading in C++</em>, over at <a href="http://wanderinghorse.net/computing/papers/#classloading_cpp">http://wanderinghorse.net/computing/papers/</a>.</p>
<p><strong style="font-weight: bold;"><em>Happing hacking!</em></strong></p>
<p>&#8212;&#8211; stephan beal, 2 March 2010</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.s11n.net/?feed=rss2&amp;p=82</wfw:commentRss>
		</item>
		<item>
		<title>Implementing not-quite-namespaces in C</title>
		<link>http://blog.s11n.net/?p=81</link>
		<comments>http://blog.s11n.net/?p=81#comments</comments>
		<pubDate>Sun, 28 Feb 2010 10:24:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[c]]></category>

		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.s11n.net/?p=81</guid>
		<description><![CDATA[Hi, all!
A few days ago i came across a trick in C. It isn&#8217;t new, but i hadn&#8217;t seen it used quite this way before and i wanted to share it&#8230;
Background: i have several mini-libraries which i tend to copy directly in to other projects. It has happened that i then use two other libraries [...]]]></description>
			<content:encoded><![CDATA[<p>Hi, all!</p>
<p>A few days ago i came across a trick in C. It isn&#8217;t new, but i hadn&#8217;t seen it used quite this way before and i wanted to share it&#8230;</p>
<p>Background: i have several mini-libraries which i tend to copy directly in to other projects. It has happened that i then use two other libraries together, and both of them internally use the same underlying mini-library. In some cases i want each to continue to use their own copy (maybe a different/incompatible version), but not collide with the other copy. Here&#8217;s one way to do it&#8230;</p>
<p>In the lib&#8217;s main header, before we declare any of its API:</p>
<pre>#if !defined(MY_NS)
#  define MY_NS(X) my_namespace_prefix_ ## X
#endif</pre>
<p>We then declare our types and functions using that macro:</p>
<pre>int MY_NS(func1)( ... );
struct MY_NS(type1) { ... };</pre>
<p>And throughout the implementation and client code we use:</p>
<pre>int x = MY_NS(func1)( ... );</pre>
<p>Each library which wants to import and rename the API then simply has to redefine MY_NS while building the included mini-library.</p>
<p>The major down-side is that this construct makes reading the docs through tools like <a title="Doxygen Home Page" href="http://www.doxygen.org">doxygen</a> more difficult.</p>
<p><em><strong>Happy hacking!</strong></em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.s11n.net/?feed=rss2&amp;p=81</wfw:commentRss>
		</item>
		<item>
		<title>Allocating memory in C without dynamic memory</title>
		<link>http://blog.s11n.net/?p=80</link>
		<comments>http://blog.s11n.net/?p=80#comments</comments>
		<pubDate>Tue, 01 Dec 2009 01:47:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[c]]></category>

		<guid isPermaLink="false">http://blog.s11n.net/?p=80</guid>
		<description><![CDATA[Hi, all!
The past year or two i&#8217;ve been working on various C-based projects. Through that work i&#8217;ve taken a strong interest in conserving memory and reducing the number of calls made to make new memory available (e.g. via malloc()). For example, i&#8217;ve spent many hours optimizing the whefs embedded filesystem library to run with fewer [...]]]></description>
			<content:encoded><![CDATA[<p>Hi, all!</p>
<p>The past year or two i&#8217;ve been working on various C-based projects. Through that work i&#8217;ve taken a strong interest in conserving memory and reducing the number of calls made to make new memory available (e.g. via malloc()). For example, i&#8217;ve spent many hours optimizing the <a title="whefs home page" href="http://code.google.com/p/whefs/">whefs embedded filesystem library</a> to run with fewer than 2kb of dynamic memory for the average use case (and as little as 96 bytes(!!!) for a highly-optimized case).</p>
<p>The past few days, that latent fascination with saving calls to malloc() has culminated into a new library:</p>
<p><a title="whalloc home page" href="http://fossil.wanderinghorse.net/repos/whalloc">whalloc (the WanderingHorse.net Allocator)</a> is a small C library which provides an alternative memory management approach. It is initialized with a block of client-supplied memory, typically a stack-allocated char buffer, and then it can slice up that memory and use it for allocations and deallocations. The whole process looks a bit like:</p>
<blockquote>
<pre class="verbatim">whalloc_bt pool = whalloc_bt_empty;
enum { BufLen = 1024 * 8 };
unsigned char buffer[BufLen];
whalloc_size_t blockSize = sizeof(my_type);
int rc = whalloc_bt_init(&amp;pool, buffer, BufLen, blockSize );
if( whalloc_rc.OK != rc ) { &#8230; error &#8230; }
my_type * m = whalloc_bt_alloc(&amp;pool, sizeof(my_type));
// ^^^ m now lives somewhere inside of buffer
&#8230;
whalloc_bt_free(&amp;pool, m); // makes the memory available for re-use
whalloc_bt_drain(&amp;pool); // &#8220;deallocates&#8221; all allocated objects at once</pre>
</blockquote>
<p>The most interesting part is how it stores its memory management information: by taking up a small slice of the memory it is managing. It needs only <em>two bits</em> of storage for each block of memory it manages (there are (memBufferSize/blockSize) blocks in the buffer). The allocator takes up, worst-case (block size of 1 byte), 18-19% of that memory, dropping to 11% for 2-byte blocks, 6% for 4-byte-blocks, and halving for each additional doubling of block size. With a block size of 64 bytes it uses less than 0.5% of the memory for its own purposes. If its storing only a small number of blocks (default setting=128) then it can use its own few-byte-long internal cache and must reserve <em>none</em> of the client&#8217;s memory for its own purposes.</p>
<p>For the average use case, where objects are destroyed in reverse of their allocation order, it can perform O(1) if the allocations are equal to or smaller than the defined block size. Its worst-case performance is O(N), with N being a function of the number of blocks being allocated, the total number of blocks managed, and current memory pool fill status. Deallocation is always O(N), with N being the number of blocks being deallocated. For deallocation, finding the underlying management data is always O(1) - a simple hashing operation which uniquely maps any given pointer to its memory block index.</p>
<p>There&#8217;s also a variant of the allocator which requires 2 bytes (instead of 2 bits) per managed block. The primary difference is that it stores the requested size of each allocation, whereas the optimized variation simply knows whether a block as a whole has been allocated or not.</p>
<p>The allocators optionally support a client-provided mutex, to lock the allocator, and fallback allocation/deallocation functions, which they can use if their own pool runs out of space (e.g. falling back to malloc() and free()).</p>
<p>For those of you interested in C, in particular in shaving off a few bytes of dynamic memory in your C apps, the code is available (it&#8217;s in the Public Domain) over on the whalloc web page:</p>
<p style="text-align: center;"><a title="whalloc home page" href="http://fossil.wanderinghorse.net/repos/whalloc">http://fossil.wanderinghorse.net/repos/whalloc</a></p>
<p><strong><em>Happy hacking!</em></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.s11n.net/?feed=rss2&amp;p=80</wfw:commentRss>
		</item>
		<item>
		<title>The Chicken/Egg Scenario</title>
		<link>http://blog.s11n.net/?p=78</link>
		<comments>http://blog.s11n.net/?p=78#comments</comments>
		<pubDate>Mon, 10 Aug 2009 19:29:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[StrangerThanFiction]]></category>

		<guid isPermaLink="false">http://blog.s11n.net/?p=78</guid>
		<description><![CDATA[The age-old question goes:
Which came first: the chicken or the egg?
And i think the point of it is that nobody really knows. Kind of like the ancient Egyptian saying, &#8220;if a tree falls in the dunes of the Sahara desert and no one hears it, did it really emit audible vibrations?&#8221; (Though the original hieroglyph [...]]]></description>
			<content:encoded><![CDATA[<p>The age-old question goes:</p>
<blockquote><p>Which came first: the chicken or the egg?</p></blockquote>
<p>And i think the point of it is that nobody really knows. Kind of like the ancient Egyptian saying, &#8220;if a tree falls in the dunes of the Sahara desert and no one hears it, did it really emit audible vibrations?&#8221; (Though the original hieroglyph looks something like a man with an axe in one hand and the other hand cupped to his ear.)</p>
<p>But i think there might be a solution:</p>
<p>A chicken, by definition, comes from an egg. Not just <em>any</em> egg, mind you, but a <em><span style="text-decoration: underline;">chicken</span> egg</em>. Thus it is impossible that the chicken came before the egg. Ergo, what laid the first chicken egg was not a chicken. That creature might indeed have been hatched from <em>an</em> egg, but because it cannot have been a <em>chicken egg</em> (as we just established), the first chicken egg still came before the first chicken.</p>
<p>Elementary, dear Watson!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.s11n.net/?feed=rss2&amp;p=78</wfw:commentRss>
		</item>
		<item>
		<title>whefs: an embedded filesystem library for C</title>
		<link>http://blog.s11n.net/?p=77</link>
		<comments>http://blog.s11n.net/?p=77#comments</comments>
		<pubDate>Thu, 18 Jun 2009 12:15:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[c]]></category>

		<category><![CDATA[library]]></category>

		<category><![CDATA[whefs]]></category>

		<guid isPermaLink="false">http://blog.s11n.net/?p=77</guid>
		<description><![CDATA[Hi, all!
Late last year i started working on an embedded filesystem library for C. The library uses &#8220;container files&#8221; (called embedded filesystems, or EFSes), in which the client can store &#8220;files&#8221; (i call them &#8220;pseudofiles&#8221;). The API allows random read/write access to them using a flexible i/o device interface. If you&#8217;ve ever programmed with sqlite [...]]]></description>
			<content:encoded><![CDATA[<p>Hi, all!</p>
<p>Late last year i started working on an embedded filesystem library for C. The library uses &#8220;container files&#8221; (called embedded filesystems, or EFSes), in which the client can store &#8220;files&#8221; (i call them &#8220;pseudofiles&#8221;). The API allows random read/write access to them using a flexible i/o device interface. If you&#8217;ve ever programmed with <a title="sqlite home page" href="http://www.sqlite.org">sqlite</a> - whefs is similar in concept but creates an embedded/virtual filesystem instead an embedded/virtual SQL server.</p>
<p>While whefs is still beta and open for lots of experimentation, it seems to be in a usable state.</p>
<p>To give whefs a more public home, a couple days ago i moved whefs over from its original source repository to Google Code:</p>
<p><a title="whefs home page" href="http://code.google.com/p/whefs/">http://code.google.com/p/whefs/</a></p>
<p>The project is of course open to collaboration, and i invite any interested C hackers out there to get in touch.</p>
<p>Happy hacking!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.s11n.net/?feed=rss2&amp;p=77</wfw:commentRss>
		</item>
		<item>
		<title>Four reasons to take a closer look at the Fossil SCM</title>
		<link>http://blog.s11n.net/?p=72</link>
		<comments>http://blog.s11n.net/?p=72#comments</comments>
		<pubDate>Mon, 12 Jan 2009 15:30:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[software-dev]]></category>

		<category><![CDATA[fossil]]></category>

		<guid isPermaLink="false">http://blog.s11n.net/?p=72</guid>
		<description><![CDATA[This post was originally made to the mailing list of the Fossil source control system on January 11th, 2009, with the subject line &#8220;A letter to the new or unconverted fossil user&#8221;. After reading it over again, i figured i could recycle it as a blog post to evangelize Fossil a bit. It might also [...]]]></description>
			<content:encoded><![CDATA[<p>This post was originally made to the mailing list of the <a title="Fossil home page" href="http://www.fossil-scm.org">Fossil source control system</a> on January 11th, 2009, with the subject line &#8220;A letter to the new or unconverted fossil user&#8221;. After reading it over again, i figured i could recycle it as a blog post to evangelize Fossil a bit. It might also make good food for the 200+ spambot suscribers to this blog from @mail.ru.</p>
<p>&#8230;</p>
<p>This is addressed those of you who are new to fossil and those who have used it for a while but just aren&#8217;t quite sure whether they like it or not&#8230;</p>
<p>Sometime in late 2007 i came across a link to fossil on <a href="http://sqlite.org/" target="_blank">sqlite.org</a>. It was a good thing i bookmarked it, because i was never able to find the link again (it might have been in a bug report or something). The reasons i first took a close look at it were (A) it stemmed from the sqlite project, which i&#8217;ve held in high regards for years (e.g. i wrote JavaScript bindings for it: <a href="http://spiderape.sourceforge.net/plugins/sqlite/" target="_blank">http://spiderape.sourceforge.net/plugins/sqlite/</a>), and (B) it could run as a CGI. That second point might seem a bit archaic, but in practice CGI is the only way most hosted sites can set up a shared source repository with multiple user IDs. (i&#8217;m not about to give out my only account password or SSH key for my hosted sites, no matter how much i trust the other developers, and none of my hosters allow me to run standalone servers or add Apache modules.)</p>
<p>So i tried it out. The thing which bugged me most about it was having to type &#8220;commit&#8221; or &#8220;com&#8221; instead of &#8220;ci&#8221; for checking in (as is custom in all other systems i&#8217;ve used), despite the fact that fossil uses &#8220;ci&#8221; as a filter in things like the timeline view. Looking back now, i have used fossil for about about 95% of my work in the past year (<a href="../?p=71" target="_blank">http://blog.s11n.net/?p=71</a>), in over 15 source trees, and i now get tripped up when i have to use svn or cvs.</p>
<p>So, having got over typing &#8220;fossil com -m &#8230;&#8221;, here&#8217;s why i love fossil so much&#8230;</p>
<p><strong> Point #1: CGI</strong></p>
<p>Again, this sounds archaic, but fossil has allowed me to share source trees which i cannot justifiably host in other projects i work on (they don&#8217;t belong to those projects), which i cannot host in <a title="Google Code" href="http://code.google.com">Google Code</a> (because google code doesn&#8217;t allow/recognize Public Domain as a license, and i refuse to relicense just to accommodate them), and for which <a title="SourceForge" href="http://www.sourceforge.net">SourceForge</a> is overkill (and way too slow). With fossil i can create a new repo, have it installed on my hoster (<a href="http://fossil.wanderinghorse.net/" target="_blank">http://fossil.wanderinghorse.net</a>), and be commiting code to it within 5 minutes.</p>
<p><strong> Point #2: Wiki</strong></p>
<p>i hate wikis. i really do. Always have. They all have a different syntax and the content tends to get really disorganized really quickly. Their nature makes it difficult to reorganize them without replacing old pages with lots of &#8220;has been moved to [TheNewPage]&#8221; links. i&#8217;m one of those &#8220;code for tomorrow&#8221; coders (i.e., code such that it&#8217;ll be easy to reorganize/refactor later). i like to document the same way, and wikis make that problematic. Then again, no documentation system is really good in that regard.</p>
<p>That said, fossil has made me love having a centralized, common documentation platform. Whereas i used to document everything in the API docs (header files) and often include an ODT file for a library manual, fossil has become my preferred platform for non-API documentation because it&#8217;s just so easy to do. No matter where i am, i can log in and write (i write a lot). The added ability to export my wiki pages, edit them in xemacs, and re-import them just makes it nicer, as i can tweak as much as i want without ending up with 10 &#8220;updated wiki page SoAndSo&#8221; messages in the commit log.</p>
<p><strong>Point #3: running a server locally</strong></p>
<p>Fossil runs not only as a CGI, but as a server. i don&#8217;t WANT to host my own server (and don&#8217;t have the rights to on my hosters). i hate server-side maintenance (a hate born from years of administering systems). But the server has other uses. When working on the wiki, bug reports, etc., the local server is <em>the</em> way to do it. It&#8217;s blazingly fast and much more productive. When you&#8217;re done, just run &#8220;fossil push&#8221; and everything&#8217;s synced.</p>
<p><strong>Point #4: the single-file repository</strong></p>
<p>Having all controlled content inside a single container file has been a godsend when it comes to backups and copying/moving a repository. There are no access or file ownership issues, which are often problematic with other server-side systems (at least on the initial install). For about 5 years i administered a CVS repo for a company for, and every time someone added a directory to the (huge and dynamic) source tree i had to log in and &#8220;chmod 4775&#8243; the directory before others could commit to it. Fossil&#8217;s model inherently eliminates that type of problem, and i&#8217;m a *huge* fan of solutions which inherently (that is, due to their very nature) avoid certain foreseeable problems. The single-file repository model&#8217;s flexibility would seem to become more problematic for massive repositories (a few hundred MB+) with many users with differing levels of access (e.g. OpenOffice, Firefox, or the Linux Kernel), but 99.9% of projects never reach anywhere near that size or complexity. (For that level of project, it would seem the world is quickly migrating to <a title="git home page" href="http://git-scm.com/">git</a>.)</p>
<p><strong>In summary:</strong></p>
<p>i remember my first reaction to fossil being, &#8220;this will be an excellent solution for small projects [like the dozens we've all got sitting on our hard drives but which don't justify the hassle of version control].&#8221; A year of daily use in over 15 source trees has confirmed that, and i continue to heartily recommend fossil to other developers i know who also have their own collection of &#8220;unhosted&#8221; pet projects.</p>
<p>Even if fossil stagnates today, never adds another feature, and never gets another bug fix (what bugs?), this is a tool i see myself using for many years to come. (No, honestly, i don&#8217;t know what bugs you&#8217;re talking about.)</p>
<p><em><strong> Happy hacking!</strong></em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.s11n.net/?feed=rss2&amp;p=72</wfw:commentRss>
		</item>
		<item>
		<title>Happy New Year! A hacker is born!</title>
		<link>http://blog.s11n.net/?p=71</link>
		<comments>http://blog.s11n.net/?p=71#comments</comments>
		<pubDate>Wed, 31 Dec 2008 18:32:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[hacking]]></category>

		<guid isPermaLink="false">http://blog.s11n.net/?p=71</guid>
		<description><![CDATA[Hello, all!
On this day in 2004, i made a post with the subject line &#8220;3&#8230; 2&#8230; 1.0!&#8221; to announce the release of libs11n, which had been in heavy development for almost 18 months at that time. A year later, 1.2.0 was released. Since then, libs11n&#8217;s 1.2.x branch has been fairly stable and has undergone only [...]]]></description>
			<content:encoded><![CDATA[<p>Hello, all!</p>
<p>On this day in 2004, i made a post with the subject line &#8220;3&#8230; 2&#8230; 1.0!&#8221; to announce the release of <a title="s11n home page" href="http://s11n.net">libs11n</a>, which had been in heavy development for almost 18 months at that time. A year later, 1.2.0 was released. Since then, libs11n&#8217;s 1.2.x branch has been fairly stable and has undergone only relatively minor updates and a few bug fixes.</p>
<p>This year i don&#8217;t have a new libs11n release to make :`(. That library is stable and useful, and the improvements i&#8217;d like to make <a title="s11n 1.4" href="http://s11n.net/s11n/1.4/">would require some significant rearchitecting</a> in areas where (A) i&#8217;m simply not the right man for the job (e.g. i118n/wide character support) and (B) i have little interest and therefore correspondingly little drive to work on them.</p>
<p>But that doesn&#8217;t mean i haven&#8217;t been coding. In hindsight, 2008 has been a record year for me in terms of number of lines of code produced, on par with 2004 (when i would sometimes spend 60+ hours per week hacking on s11n - one particular week saw about 100 hours of hacking and less than 20 hours of sleep). Quite unlike 2004, where i expended 100% of my energy on libs11n (and its supporting code/subprojects), 2008 saw the birth of several new pet projects.</p>
<p>So, though i don&#8217;t have another 1.0 (or 1.1, or 1.5) release to present at the end of this year, i thought i&#8217;d post a bit about what software i&#8217;ve been working on this year. This post is not to brag, but does serve a few purposes:</p>
<ul>
<li>i won&#8217;t deny it: publicity for new personal projects which might be of interest to some other hackers out there.</li>
<li>i&#8217;m trying to justify to myself why i spent so little time with my family (Simone and <a title="pictures of Baako" href="http://picasaweb.google.com/sgbeal/TheDog">Baako</a>) this year. Likewise, my parents and friends probably wonder why i&#8217;m so uncommunicative.</li>
<li>Help me internally sum up what&#8217;s just passed, to help me sort out what comes next.</li>
<li>We all started coding somewhere, and we all draw inspiration from different places. It is my hope that some young hacker out there may be inspired to explore his love of computing. With some effort on his part he may someday surpass us all in ability.</li>
<li>And lastly, to set up the scene for my &#8220;coming out&#8221; at the end of this post.</li>
</ul>
<p>So, here it goes&#8230;</p>
<p>(In case you&#8217;re more interested in a quick summary, just read the text <strong>marked in bold</strong>.)</p>
<p>The first half of the year was quite slow, in terms of coding. i had just moved back to Munich and was settling in. On this very night one year ago we didn&#8217;t yet have a flat in Munich, and were stuck in a hotel room so small you could practically step into the bed from the doorway.</p>
<p>The code i do remember working on includes <strong>what i now call <a title="whprintf home page" href="http://fossil.wanderinghorse.net/repos/whprintf/">whprintf</a></strong>, a custom printf() implementation which i took from the sqlite3 source tree and refactored so that it can send its output to an arbitrary destination (e.g. a GUI widget, stdout, a socket, or a memory buffer) via a callback mechanism. Aside from that, i mainly experimented with utility classes for C, such as managed memory buffers and hashtables (i couldn&#8217;t code my own hashtable from scratch, but i hacked quite a lot <a title="Christopher Clark's hashtable home page" href="http://www.cl.cam.ac.uk/~cwc22/hashtable">on one written by Christopher Clark</a>).</p>
<p>In April or May of 2008 i came across <a href="http://code.google.com/p/pegtl">PEGTL</a>, a C++0x library for creating <a href="http://en.wikipedia.org/wiki/Parsing_expression_grammar">PEG</a> parsers using C++ templates. PEGTL inspired me tremendously, and PEGTL&#8217;s author (Dr. Colin Hirsch) and myself exchanged over 100 emails on the topic inside of a month or so. Unsatisfied with some of his design decisions, i of course took it upon myself to take a crack at the problem. <strong>My first attempt, named <a title="parsepp home page" href="http://fossil.wanderinghorse.net/repos/parse0x/">parse0x</a></strong>, was also a C++0x library. It did almost everything pegtl did and i was happy with it. i was, however, unhappy that i couldn&#8217;t use parse0x in real projects because it requires C++0x support, which is still far from leaving beta status in the next generation of C++ compilers.</p>
<p>So i sat down to approach the problem from C++9x, and <strong>hacked out <a title="parsepp home page" href="http://fossil.wanderinghorse.net/repos/parsepp/">parsepp</a></strong>, which is similar to both pegtl and parse0x, but nowhere near as powerful as libraries like <a title="Spirit Parser home page" href="http://spirit.sourceforge.net">Boost.Spirit</a>.</p>
<p>And all was good. Two projects behind me and the year not quite half over, i got a sudden urge (for reasons i don&#8217;t remember), to rewrite an old program of mine for playing boardgames on the PC (tactical/strategy games are a hobby of mine, though i haven&#8217;t actually played any in some years). So i spent much of June getting back into <a href="http://trolltech.com/products/">Qt</a> <strong>by writing <a title="QBoard home page" href="http://code.google.com/p/qboard">QBoard</a></strong>. As is usual with Qt apps, QBoard grew way beyond the minimalistic app i wanted to write (Qt just makes it easy to keep adding features), and within a month or two it was doing 90% of everything i would probably ever want it do, and QBoard now sits quietly, awaiting the next urge to hack on it. If you use (or are aware of) libs11n, it might interest you to know that libs11n was originally written to support the rewrite which would become QBoard. That is, QBoard is largely the reason libs11n ever came into existance.</p>
<p>The last time i did any significant work on QBoard was September, after which i was again enchanted by the idea of PEG parser generators&#8230;</p>
<p>In the end of 2007 i got involved on the fringes of the <a title="Fossil home page" href="http://fossil-scm.org/">Fossil</a> project, where i contribute patches now and then. Fossil re-awakened my interest in C (which i used heavily in 1992-1995, but not since discovering higher-level languages), and since early 2008 i have spent a significant amount of time banging out little C libraries, both to get back into practice and to build up components for other planned projects. That re-emergence of interest in C, combined with my fascination of the concept of PEG parsers, led me to try tackling the PEG problem again, but from a much different direction than before.</p>
<p><strong>And thus <a title="pegc home page" href="http://fossil.wanderinghorse.net/repos/pegc">pegc</a> was born</strong>. pegc was to be my third PEG parsing library in 2008, but this time it was implemented in C (and in fact has turned out to be somewhat more interesting than the C++ variants). As far as i have been able to determine, pegc is the only <em>C library</em> of its kind (there are some C code generators for PEGs, but no C <em>libraries</em>). After getting pegc to a &#8220;90% there&#8221; point, i put it down for a while to put some more thought into a few of the internals, and didn&#8217;t hack on it for a couple months. Unaware that anyone else knew about pegc (other than google, of course, but i thought he could keep a secret), another coder surprised me by sending me an email in which he explained that he had <a title="s11n.net blog post #70" href="http://blog.s11n.net/?p=70">implemented a LISP-based PEG generator using pegc as the back-end</a>. That has (yet again) re-awakened my interest in PEGs, and there is certainly more work to be done in this area in 2009.</p>
<p>The year was a couple months short of ending and i had accomplished much coding and solved some problems which interested me. But, as i would later find out, the year was far from over. My two greatest challenges were to be found hiding in the bushes up ahead&#8230;</p>
<p>Encouraged by pegc&#8217;s development, i decided to expend some effort on a problem which i had original discounted as &#8220;too much trouble to be worth the effort&#8221; - the generic serialization of objects in the C programming language. (<em>Ouch!</em>) So in late October i sat down to hack. <strong>Within a few days <a title="c11n home page" href="http://s11n.net/c11n/">c11n</a> was born</strong>. While c11n cannot reach the ease of use levels of C++ serialization libraries (because C is not &#8220;dynamically expressive&#8221; enough to do so), it does work and wasn&#8217;t nearly as difficult to implement as i had initially anticipated (it was simply a matter of finding (err&#8230; stumbling across) a useful model).</p>
<p>It was sometime in early December, the year almost over, when i got the itch to work on yet more C code.</p>
<p>There&#8217;s a problem i&#8217;ve contemplated for years but never really knew where to start - a virtual/embedded filesystem. Google reveals little non-commercial activity in this area, so there aren&#8217;t many decent starting points to study. This type of problem is C&#8217;s bread and butter, and having lost much of my previous distaste for C, i took what i&#8217;d learned over the previous year and tried to apply it to what was (in my mind) my most challenging C program yet. Truth be told, i was largely anticipating a crash-and-burn coding session, at the end of which i would be so frustrated as to leave C forever.</p>
<p>After a day or two of hacking i had the basic filesystem generator in place, but wasn&#8217;t happy with the i/o model (based on the C-standard (FILE*) API). So i scraped out the i/o layer API from c11n (which i had grown quite happy with), extended it to support random-access devices, and <strong>forked that to create the <a title="whio home page" href="http://fossil.wanderinghorse.net/repos/whio/">whio i/o library</a></strong>. The primary reason for this step was so that the VFS could use arbitrary back-end storage (provided it&#8217;s capable of random-access), and to that end i added implementations for treating standard file handles and in-memory buffers as i/o devices.</p>
<p>With whio in place i <strong>reimplemented the embedded filesystem (now called <a title="whefs home page" href="http://fossil.wanderinghorse.net/repos/whefs/">whefs</a>)</strong> around it, and within a week or ten days i had gotten the rest of the significant bits in place. As of a few days ago i&#8217;ve got a working embedded filesystem library, which is like my little Christmas present to myself (just a few days late). Now i&#8217;ve just got to find a use case for it. (That said, googling has revealed very little open source code in this area, so there is potential for whefs to become a useful niche market product.)</p>
<p><em><strong>Whew!</strong></em></p>
<p>And now i&#8217;m tired and <strong>have sworn not to program a single line of code for the rest of 2008</strong>. All 4 hours and 39 minutes of it. I might write some documentation, but i&#8217;ll (somehow) avoid the temptation to code. i think i can do it. Wish me luck.</p>
<p>It wasn&#8217;t my intention to turn 2008 into a running hackathon, nor to set a personal record, but that&#8217;s essentially how it turned out. Truth be told, little of this is code which i will use on a regular basis. Nonetheless, i immensely enjoyed hacking on these projects, and some of them will certainly see continued development for some time (namely c11n, pegc, and whefs).</p>
<p>According to <a title="SLOCCount home page" href="http://www.dwheeler.com/sloccount/">David Wheeler&#8217;s SLOCCount</a>, it would have cost a company around half a million dollars to get it all written and out the door, whereas a garden variety hacker can do it all from the comfort of his living room using nothing more than freely-available tools like <a title="XEmacs home page" href="http://www.xemacs.org">XEmacs</a>, <a title="GNU Make home page" href="http://www.gnu.org/software/make/">GNU Make</a>, <a title="gcc home page" href="http://www.gnu.org/software/gcc/">gcc</a>, and <a title="google home page" href="http://www.google.com">google</a>. Though he also isn&#8217;t likely to get paid for it.</p>
<p><strong>And speaking of hackers&#8230;</strong></p>
<p>(Now for the &#8220;coming out&#8221; announcement&#8230;)</p>
<p>Per long-standing traditions, programmers are never to call themselves hackers <a title="Hacker HOWTO" href="http://www.catb.org/~esr/faqs/hacker-howto.html">until another hacker calls them a hacker</a>. This is fair and respectful, and in deference to this ideal i have always been careful about who i publically dub to be a &#8220;hacker.&#8221; i have in fact been called a hacker by other hackers, but i don&#8217;t normally proclaim myself to be a hacker. Part of the reason is the misinformed public opinion that a hacker is one who breaks into computer systems (something i&#8217;ve never had an interest in and certainly never done), where as we (that is, anyone who would read so far into this blog post!) all know that a hacker is someone who not only loves working on software, but is also particularly good at it. Another reason i&#8217;ve avoided using the word in reference to myself has been because i have not always felt that i am quite qualified to wear the title. i won&#8217;t claim to be a guru in any given area of computer science (and i&#8217;m certainly a zero in many areas!), but i can confidently say that i am a fairly good general-purpose programmer.</p>
<p>But i&#8217;m also now convinced that i am indeed a hacker. The past year i somehow managed to implement three programs in particular (<a title="c11n home page" href="http://s11n.net/c11n/">c11n</a>, <a title="pegc home page" href="http://fossil.wanderinghorse.net/repos/pegc/">pegc</a>, and <a title="whefs home page" href="http://fossil.wanderinghorse.net/repos/whefs/">whefs</a>) which i would have thought impossible (for me) half a decade ago. That might be reason enough to be dubbed a hacker. The more compelling reason, however, has nothing to do with lines of code or architecture or the number of functions in one&#8217;s API. Simone has sometimes asked me, &#8220;how can you be so tired from your six hours at work, and then sit here for 12 hours programming?&#8221; The answer took me some time to find (as i had never given it any thought before), but is in principal simple. Everything we do requires an expenditure of energy. Working as a Unix system administrator (my current job) takes a lot of energy. It sucks me dry at times. Programming, on the other hand, not only takes relatively little energy (per unit of time), but often literally gives more energy than it takes. That has convinced me that i may unashamedly use the title Hacker (though i&#8217;ll use a small &#8220;h&#8221;, to keep it in proportion ;).</p>
<p>So, there you have it. i&#8217;ve just written the world&#8217;s longest &#8220;i&#8217;m a hacker&#8221; post.</p>
<p>Happy hacking!</p>
<p>PS: i&#8217;ve still got 3 hours and 14 minutes before i may hack again.</p>
<p>Update: 1 hour and 47 minutes</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.s11n.net/?feed=rss2&amp;p=71</wfw:commentRss>
		</item>
	</channel>
</rss>
