<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4137570364011598202</id><updated>2011-07-29T00:41:43.597-04:00</updated><category term='Life'/><category term='Design'/><category term='Games'/><category term='Management'/><category term='Linux'/><category term='Version Control'/><category term='Editors'/><category term='Programming'/><category term='Configuration'/><category term='Review'/><title type='text'>Lazy Malloc()</title><subtitle type='html'>Topics on programming, software design, version control, and Linux-based systems.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://lazymalloc.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>25</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-1321338421193901850</id><published>2010-10-09T21:38:00.008-04:00</published><updated>2010-10-16T16:51:23.599-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><title type='text'>Maintaining a Patch Series with Mercurial Queues</title><content type='html'>This topic has been written about quite a bit (there are links to some additional resources at the end of the article), but I'm going to describe how I handle patches using Mercurial Queues. Some existing articles are either out of date or describe a different workflow.&lt;br /&gt;&lt;br /&gt;I normally use Mercurial Queues to maintain patches on top of source trees for applications that I need to modify before compiling for use for whatever reason (compiler fixes, system tweaks, non-mainstream features, etc). Although Mercurial Queues can be used to manage thousands of patches, the number of patches I work with is usually less than ten in this situation, so this work flow is optimized for a smaller number of patches. It also requires the &lt;a href="http://mercurial.selenic.com/wiki/RebaseExtension"&gt;rebase extension&lt;/a&gt; (bundled with "modern" versions of Mercurial) to be enabled, as well as &lt;a href="http://mercurial.selenic.com/wiki/MqExtension"&gt;Mercurial Queues&lt;/a&gt; itself.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Initial Setup&lt;/span&gt;&lt;br /&gt;We're going to assume that the official application source is not contained in a Mercurial repository. If it is, you can just clone that and skip the steps in this section. The commands below are based on the workflow I use, just to convey the general idea of what to do.&lt;br /&gt;First, grab the latest version of the application you need to modify, and extract it into a directory. In this case I'll be modifying &lt;span style="font-weight: bold;"&gt;some_application&lt;/span&gt;, because I have no imagination. Since this will be the repository in which you'll be making your changes, you may want to remove the version from the folder name, if present.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cd custom_builds&lt;br /&gt;tar xvf some_application-version.tar.bz2&lt;br /&gt;mv some_application-version some_application&lt;br /&gt;cd some_application&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Create a Mercurial repository here.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg init&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Custom Changes&lt;/span&gt;&lt;br /&gt;Now you can make your changes, adding as many patches as necessary. Please see the &lt;a href="http://mercurial.selenic.com/wiki/MqExtension"&gt;MQ official documentation&lt;/a&gt; for more information on these commands,&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg qnew [patch name] # create a new patch&lt;br /&gt;hg qrefresh          # refresh the current patch&lt;br /&gt;hg qrecord           # refresh the current patch (at the patch hunk level)&lt;br /&gt;hg qdelete           # remove the current patch&lt;br /&gt;hg qpush             # push the next patch onto the stack&lt;br /&gt;hg qpop              # pop the current patch off of the stack&lt;br /&gt;hg qseries           # list all of the patches in the series&lt;br /&gt;hg qapplied          # list all of the patches that are currently applied&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;After your changes are set up to your liking, you can compile and enjoy the application.&lt;br /&gt;Please note that there are many more Mercurial Queues commands; to get a full listing you can type &lt;span style="color: rgb(153, 0, 0);"&gt;hg help mq&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Handling Updates to the Core Source Code&lt;/span&gt;&lt;br /&gt;Say it's been a few months and there have been a few significant changes to some_application, and a new version is out. The kind of changes you would like to be able to use.&lt;br /&gt;&lt;br /&gt;Clone your existing repository (without the patches) to create an area in which to apply the core updates.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg clone some_application some_application-new_version&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Extract the source code for the new version over the files in your cloned repository, and update it.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;tar xvf some_application-new_version&lt;br /&gt;cd some_application-new_version&lt;br /&gt;hg addremove # tell Mercurial to add new files and remove ones that were deleted&lt;br /&gt;hg commit -m 'Updated to new version.'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now you can go back to your main repository, and pull in the updated changes from the clone. Thanks to the rebase extension, the &lt;span style="font-weight:bold;"&gt;pull&lt;/span&gt; command can be used to update the changes to the core code, then merge in your managed patches on top using the regular merge tools.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg qpush -a # apply all of your patches&lt;br /&gt;hg pull --rebase ../some_application-new_version&lt;br /&gt;...do any manual merging necessary...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;After this process is complete your patches will apply cleanly onto the updated source tree. You can delete the &lt;span style="font-weight:bold;"&gt;some_application-new_version&lt;/span&gt; folder if you wish, or keep it around for archival purposes.&lt;br /&gt;&lt;br /&gt;This process makes maintaining a series of patches relatively painless in terms of merging and keeping the code up to date. Based on the experiences of others, similar processes scale well, so I assume this one does as well.&lt;br /&gt;&lt;br /&gt;For more information and additional work flows, check out the links below:&lt;br /&gt;&lt;a href="http://hgbook.red-bean.com/read/managing-change-with-mercurial-queues.html"&gt;Mercurial Definitive Guide - Managing Change with Mercurial Queues&lt;/a&gt; (a little outdated, but useful).&lt;br /&gt;&lt;a href="https://developer.mozilla.org/en/Mercurial_queues"&gt;Mozilla's MQ Notes&lt;/a&gt;&lt;br /&gt;&lt;a href="http://davidherron.com/node/972"&gt;David Herron's Introduction to MQ&lt;/a&gt;&lt;br /&gt;&lt;a href="http://stevelosh.com/blog/2010/08/a-git-users-guide-to-mercurial-queues/"&gt;Git User's Guide to Mercurial Queues&lt;/a&gt;&lt;br /&gt;&lt;a href="http://tarekziade.wordpress.com/2010/06/30/random-notes-on-mercurial-queues/"&gt;Random Notes on Mercurial Queues&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-1321338421193901850?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/1321338421193901850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/1321338421193901850'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2010/10/maintaining-patch-series-with-mercurial.html' title='Maintaining a Patch Series with Mercurial Queues'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-9174688319299134735</id><published>2010-10-01T20:23:00.004-04:00</published><updated>2010-10-01T20:46:24.361-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Editors'/><title type='text'>Emacs - Clear Current Buffer</title><content type='html'>There are a few cases where clearing the current buffer is useful. For example,when using the *scratch* buffer a lot, or running a shell inside Emacs, being able to clear the screen can help the user stay organized. Since I'm often stuck in a Windows environment without Cygwin, running a shell inside Emacs is a great boost to productivity.&lt;br /&gt;&lt;br /&gt;I recently found a method that works great. I'm sure there other, (possibly more elegant) solutions, but this gets the job done.&lt;br /&gt;&lt;br /&gt;There are two functions to define for this solution; the best place for them is probably your &lt;span style="font-weight: bold;"&gt;.emacs&lt;/span&gt; file.&lt;br /&gt;&lt;br /&gt;The first function, &lt;span style="font-weight: bold;"&gt;beginning-of-buffer()&lt;/span&gt;, from &lt;a href="http://www.rattlesnake.com/intro/simplified_002dbeginning_002dof_002dbuffer.html"&gt;rattlesnake.com&lt;/a&gt; simply moves the point to the beginning of the buffer, leaving the mark wherever it happens to currently be.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(defun beginning-of-buffer()&lt;br /&gt; "Move point to the beginning of the buffer."&lt;br /&gt; (interactive)&lt;br /&gt; (push-mark)&lt;br /&gt; (goto-char (point-min))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The second function, &lt;span style="font-weight: bold;"&gt;clear-buffer()&lt;/span&gt;, from &lt;a href="http://audacity-forum.de/download/edgar/nyquist/nyquist-doc/examples/emacs/how-to/init-nyquist.html"&gt;Audacity Init-Nyquist&lt;/a&gt;, deletes everything in the buffer and moves the point to the beginning of the buffer.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(defun clear-buffer()&lt;br /&gt; "Kill all of the text in the current buffer."&lt;br /&gt; (interactive)&lt;br /&gt; (clipboard-kill-region 1 (point-max))&lt;br /&gt; (beginning-of-buffer)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It is of course possible to combine these two functions together if there is no reason to re-use beginning-of-buffer(). Once this is in your .emacs file, or has been run in Emacs, you can type &lt;span style="font-weight: bold;"&gt;M-x clear-buffer&lt;/span&gt; to clear the current buffer. It can also be mapped to a key combination like any other function.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-9174688319299134735?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/9174688319299134735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/9174688319299134735'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2010/10/emacs-clear-current-buffer.html' title='Emacs - Clear Current Buffer'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-6594841003579195219</id><published>2009-12-12T11:04:00.012-05:00</published><updated>2009-12-13T11:36:47.570-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><title type='text'>Mercurial Relink Extension and hg-relink.py</title><content type='html'>In newer versions of &lt;a href="http://mercurial.selenic.com/"&gt;Mercurial&lt;/a&gt; (greater than 1.3.1), a great extension called &lt;a href="http://mercurial.selenic.com/wiki/RelinkExtension"&gt;relink&lt;/a&gt; comes bundled with the system. For larger projects, this can significantly reduce the amount of disk space consumed when you have a large number of cloned repositories.&lt;br /&gt;&lt;br /&gt;When a repository is locally cloned, Mercurial will create hardlinks to the original repository's files in order to save space, if the operating system and file system support hardlinking. However, when a &lt;span style="font-weight: bold;"&gt;pull&lt;/span&gt; is done into either repository (the original or the cloned), those hardlinks are broken, regardless of whether the files are still identical. The &lt;span style="font-weight: bold;"&gt;relink extension&lt;/span&gt; allows Mercurial to re-create those hardlinks. &lt;span style="font-weight: bold;"&gt;For those of you stuck with 1.3.1 or a prior version, see the last section of this post for the solution used before this extension.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Since the relink extension is bundled with Mercurial, to activate it, just add the standard lines to your &lt;span style="font-weight: bold;"&gt;.hgrc&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;[extensions]&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;relink =&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Using the extension is very straightforward. Execute one of the following commands from somewhere within the cloned repository's directory structure.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;# Re-link with the stored origin (the original repository this was cloned from.)&lt;br /&gt;hg relink&lt;br /&gt;&lt;br /&gt;# Relink with a specific ORIGIN repository.&lt;br /&gt;hg relink /path/to/origin&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Mercurial will print out which repositories were relinked and how many files were pruned. See the &lt;a href="http://mercurial.selenic.com/wiki/RelinkExtension"&gt;official extension page&lt;/a&gt;, or type &lt;span style="font-style: italic;"&gt;hg help relink&lt;/span&gt; in a terminal for more information on usage and output.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;For users of version 1.3.1 and prior:&lt;/span&gt;&lt;br /&gt;There is a python script (contrib/hg-relink.py, or sometimes contrib/relink.py) in the source tree that provides this same functionality, and can be used with versions 1.3.1 and prior. I used it myself until I found out about the relink extension.&lt;br /&gt;&lt;br /&gt;The usage is just as easy as the extension, but requires some extra setup. First, copy the &lt;span style="font-weight: bold;"&gt;hg-relink.py (or relink.py)&lt;/span&gt; file to a directory in your PATH. You can then call it as shown below:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;python hg-relink.py /path/to/source /path/to/destination&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The script will then hardlink the appropriate files from the source repository to the destination repository. There used to be a page on the Mercurial wiki describing this script in more detail, but it seems to have disappeared.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-6594841003579195219?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/6594841003579195219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/6594841003579195219'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2009/12/mercurial-relink-extension-and-hg.html' title='Mercurial Relink Extension and hg-relink.py'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-1291415853088395347</id><published>2009-12-07T19:26:00.017-05:00</published><updated>2009-12-10T21:20:54.675-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Changing the Terminal Titlebar Text for Each Application</title><content type='html'>I have been using the &lt;a href="http://awesome.naquadah.org/"&gt;awesome&lt;/a&gt; window manager, and it has been, well, awesome. I have also tried &lt;a href="http://www.nongnu.org/ratpoison/"&gt;ratpoison&lt;/a&gt;, &lt;a href="http://xmonad.org/"&gt;xmonad&lt;/a&gt;, and &lt;a href="http://www.modeemi.cs.tut.fi/~tuomov/ion/"&gt;ion&lt;/a&gt; but awesome is my current favorite. Anyway, as you may have gathered from the title, window managers are not the topic of this post.&lt;br /&gt;&lt;br /&gt;I have found myself using more terminal applications because it is easy to manage them with a tiling window manager, and I am a fan of minimizing mouse use when doing text-related tasks. However, when there are several terminal windows open, it would be nice to see what is currently running in each one, instead of having to cycle through all of the windows. I imagine that this is the case with all window managers, and it has just become more obvious with my current setup.&lt;br /&gt;&lt;br /&gt;This technique is based on a tip found &lt;a href="http://tldp.org/LDP/LGNET/issue10/lg_tips10.html#xterm"&gt;here&lt;/a&gt;, which is for displaying the hostname in the titlebar of an xterm window. I use &lt;a href="http://software.schmorp.de/pkg/rxvt-unicode.html"&gt;rxvt-unicode&lt;/a&gt; as my terminal, but this technique should work with any xterm compatible terminal emulator running a bash terminal. The following is an example of the section in my .bashrc.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;if [ "$TERM" = "rxvt-unicode" ] &amp;&amp; [ "$0" = "-bash" ]&lt;br /&gt;then&lt;br /&gt;   # Escape sequence for setting xterm title&lt;br /&gt;   label () { echo -ne "\e]0;$*\a"; }&lt;br /&gt;&lt;br /&gt;   # Titles for each application&lt;br /&gt;   alias s1='label urxvt - ${PWD#$HOME/}'&lt;br /&gt;   alias s2='label urxvt - vim $*'&lt;br /&gt;   alias s3='label urxvt - top $*'&lt;br /&gt;&lt;br /&gt;   # Commands for each application&lt;br /&gt;   cd_t () { "cd" $*; eval s1; }&lt;br /&gt;   vims_t () { eval s2; "vim" $*; eval s1;}&lt;br /&gt;   top_t () { eval s3; "top" $*; eval s1;} &lt;br /&gt;&lt;br /&gt;   # Assign the aliases&lt;br /&gt;   alias cd=cd_t&lt;br /&gt;   alias vim=vim_t&lt;br /&gt;   alias top=top_t&lt;br /&gt;&lt;br /&gt;   # Set title to home directory&lt;br /&gt;   eval s1&lt;br /&gt;fi&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Let's take a look and (hopefully) shed some light on what is going on here.&lt;br /&gt;&lt;br /&gt;The first line is checking for the name of the terminal. Replace this with whatever terminal you are using (e.g. xterm, aterm, rxvt, etc) so that the configuration will take effect.&lt;br /&gt;&lt;br /&gt;The next section defines a function named &lt;span style="font-weight:bold;"&gt;label&lt;/span&gt; that will change the title of the terminal window.&lt;br /&gt;&lt;pre&gt;label () { echo -ne "\e]0;$*\a"; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Next, we set up some aliases to rename the window depending on the application. The &lt;span style="font-weight:bold;"&gt;$*&lt;/span&gt; after each application represents the list of arguments it was called with. For example, the command &lt;span style="font-weight:bold;"&gt;vim bob.txt&lt;/span&gt; would name the window &lt;span style="font-weight:bold;"&gt;vim bob.txt&lt;/span&gt;. Shocking, no? Here we define three aliases; the first sets the window title to the name of the home directory, the second to "vim", and the third to "top", all with the accompanying arguments.&lt;br /&gt;&lt;pre&gt;alias s1='label urxvt - ${PWD#$HOME/}'&lt;br /&gt;alias s2='label urxvt - vim $*'&lt;br /&gt;alias s3='label urxvt - man $*'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now we need some functions to actually change the titles. These are defined in the next section, one for each application. One downside of this technique is that your .bashrc will become long and messy if you need to do this for many applications. The applications have been named with the scheme &lt;span style="font-weight:bold;"&gt;[application name]_t&lt;/span&gt;. Each function does the following:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Changes the title for the current application&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Runs the application&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Resets the title to the current directory after the application closes&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;cd_t () { "cd" $*; eval s1; }&lt;br /&gt;vim_t () { eval s2; "vim" $*; eval s1;}&lt;br /&gt;top_t () { eval s3; "top" $*; eval s1;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The final section assigns aliases for the commands actually used to the functions defined in the previous section. This allows the title window text to be changed transparently in the background. For example, when "vim" is typed, the "vim_t" function will be called.&lt;br /&gt;&lt;pre&gt;alias cd=cd_t&lt;br /&gt;alias vim=vim_t&lt;br /&gt;alias top=top_t&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The last line of the configuration section simply sets the title to the home directory after the terminal window is opened.&lt;br /&gt;&lt;br /&gt;This setup has made identifying windows more convenient for me, and I imagine it would with any window manager, not just the tiling variety. Remember that this should work for any terminal application. Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-1291415853088395347?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/1291415853088395347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/1291415853088395347'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2009/12/changing-terminal-titlebar-text-for.html' title='Changing the Terminal Titlebar Text for Each Application'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-4796976695402778161</id><published>2009-03-21T17:47:00.011-04:00</published><updated>2009-12-13T11:38:43.977-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Review'/><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><title type='text'>Creating Unrelated Branches in Mercurial</title><content type='html'>Earlier I watched Scott Chacon's excellent &lt;a href="http://gitcasts.com/posts/empty-branches"&gt;GitCast about using "Empty Branches"&lt;/a&gt;, or branches that are not derivations of your main development flow. In other words, they are not descendants of your first revision. Obviously his tutorial was about how this is done in &lt;a href="http://www.git-scm.com"&gt;Git&lt;/a&gt;, but it is possible in &lt;a href="http://www.selenic.com/mercurial"&gt;Mercurial&lt;/a&gt; as well.&lt;br /&gt;&lt;br /&gt;It's important to remember that while Git ignores commits that it cannot reach via a branch head or tag, Mercurial follows all commits. Therefore some of the steps described below are not necessary if you wish to refer to a branch head anonymously. Another caveat is that when I refer to a branch, I mean a fork in the revision history graph (you can automatically track these with &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/BookmarksExtension"&gt;bookmarks&lt;/a&gt;, similar to Git's &lt;a href="http://book.git-scm.com/3_basic_branching_and_merging.html"&gt;branches&lt;/a&gt;), not what Mercurial sees as a &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/NamedBranches"&gt;named branch&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Starting an Unrelated Empty Branch&lt;/span&gt;&lt;br&gt;&lt;br /&gt;&lt;br /&gt;First let's bookmark the tip revision for easier reference later:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ hg bookmark -r tip MainBranch&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Make sure your working directory is clean, with no changes. If there are changes, either revert or commit them.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ hg status&lt;br /&gt;M test.txt&lt;br /&gt;$ hg revert --all&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now set the parents of the current directory to &lt;span style="font-weight:bold;"&gt;null&lt;/span&gt; to start the root of a new tree.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ debugsetparents null&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Update: Some readers have pointed out that there is a much cleaner (and potentially safer) way to set the parents to null.&lt;br /&gt;&lt;pre&gt;$ hg update -C null&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Go ahead and add some files and make your first commit.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ echo "test file" &gt;&gt; f1.txt&lt;br /&gt;$ echo "test file" &gt;&gt; f2.txt&lt;br /&gt;$ hg addremove&lt;br /&gt;adding f1.txt&lt;br /&gt;adding f2.txt&lt;br /&gt;$ hg ci -m "A new separate branch."&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Let's bookmark this head so it's easier to review separately from the main development tree.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ hg bookmark NewBranch&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That's it! You can now switch between these unrelated branches using &lt;span style="font-style:italic;"&gt;hg update -C&lt;/span&gt;. Remember that the bookmarks are simply for convenience, you can always refer to the heads anonymously if you would like. These separate branches have several uses. Scott Chacon mentions creating one for documentation, or for the website for the project. While these branches are part of the project, they are unrelated to the main code base. You could also use these branches to store an alternate version of the project that doesn't share much of the same code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Using Unrelated Branches&lt;/span&gt;&lt;br&gt;&lt;br /&gt;Here are a few usage examples.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# Check out the main project tree&lt;br /&gt;$ hg update -C MainBranch&lt;br /&gt;# Check out the alternate tree&lt;br /&gt;$ hg update -C NewBranch&lt;br /&gt;# View only the history for the main tree&lt;br /&gt;$ hg view MainBranch&lt;br /&gt;# View only the history for the alternative tree&lt;br /&gt;$ hg view NewBranch&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-4796976695402778161?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/4796976695402778161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/4796976695402778161'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2009/03/creating-unrelated-branches-in.html' title='Creating Unrelated Branches in Mercurial'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-4192971918855670215</id><published>2009-03-18T22:42:00.021-04:00</published><updated>2009-03-21T02:50:51.587-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><title type='text'>Mercurial vs Git: Tags</title><content type='html'>The implementation of tags is one design idea that is fundamentally different between &lt;a href="http://www.selenic.com/mercurial"&gt;Mercurial&lt;/a&gt; and &lt;a href="http://www.git-scm.com/"&gt;Git&lt;/a&gt;. In this post I aim to summarize how each system handles tagging revisions, and hopefully enlighten the reader.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Mercurial&lt;/span&gt;&lt;br /&gt;Both systems have two types of tags, &lt;span style="font-style: italic;"&gt;long-lived&lt;/span&gt; tags that are meant to mark significant points in project history, and &lt;span style="font-style: italic;"&gt;local or lightweight&lt;/span&gt; tags for temporarily marking revisions.&lt;br /&gt;&lt;br /&gt;Mercurial brands the two types as &lt;span style="font-style: italic;"&gt;public tags&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;local tags&lt;/span&gt;. Public tags are stored in a text file called &lt;span style="font-weight: bold;"&gt;.hgtags&lt;/span&gt; that lives in the root directory of the repository and is versioned along with the rest of the files.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;However, the latest committed version is always used, regardless of the changeset currently checked out.&lt;/span&gt; This means that any tag can be referenced at any time, even between named branches.&lt;br /&gt;&lt;br /&gt;The idea is that changes to tags should be tracked over time, so that we can look back and see when a tag changed, and who made the change. A custom commit message can be added to the changeset adding the tag, allowing for annotated tags. Mercurial also allows GPG signing of changesets with the &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/GpgExtension"&gt;GPG Extension&lt;/a&gt;.&lt;br /&gt;The disadvantage of this is that all of the tags must be shared among clones of the repository. There are some workarounds, as described below. In addition, there are a few caveats with the .hgtags file:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; Each named branch in Mercurial has a separate set of tags.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Occasionally the .hgtags file introduces merge conflicts.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Example Usage&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg tag -r 78hfvea v1.08&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The other type of tagging Mercurial supports involves local tags. These are stored in a plain text file called &lt;span style="font-weight: bold;"&gt;.hg/localtags&lt;/span&gt;. These tags are, as the name implies, local to the repository in which they were created and are not propagated during a push, pull or a clone. These types of tags are ideal for temporary markers for finding bugs, or simply tags that you do not wish to share.&lt;br /&gt;&lt;br /&gt;Example Usage&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg tag -l -r 78hfvea "Bug51 sighted"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;However, if you wish to propogate these tags to certain repositories, you can always add a hook for a push event (or just do it manually) to trigger &lt;span style="font-style:italic;"&gt;scp&lt;/span&gt; or &lt;span style="font-style:italic;"&gt;rsync&lt;/span&gt; to copy the &lt;span style="font-weight:bold;"&gt;.hg/localtags&lt;/span&gt; file.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Git&lt;/span&gt;&lt;br /&gt;Git brands its two types of tags as &lt;span style="font-style:italic;"&gt;normal&lt;/span&gt; tags and &lt;span style="font-style:italic;"&gt;lightweight&lt;/span&gt; tags. Normal tags are actual objects in Git (like commits, trees, and blobs), and can be annotated and GPG signed. Unlike Mercurial, Git treats all tags completely independent of history and manages them outside of the file tree.&lt;br /&gt;&lt;br /&gt;Example Usage&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# create an unsigned annotated tag&lt;br /&gt;git tag -a v1.01 78h2gv&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Git's lightweight tags are similar to Mercurial's local tags. They exist as text files in &lt;span style="font-weight:bold;"&gt;.git/refs/tags&lt;/span&gt; and are not annotated. However, unlike Mercurial's local tags, these are separate objects and can be shared between repositories.&lt;br /&gt;&lt;br /&gt;Example Usage&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;git tag PossibleBug 78h2gv&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Summary&lt;/span&gt;&lt;br /&gt;Both systems have capable tagging capabilities that work well with most workflows. Mercurial's global tags are version controlled, which can be advantageous if your project workflow involves lots of tag changes. The local tags provide an alternative for throw-away tags that are not part of project history, at the expense of not being able to directly share them between repositories.&lt;br /&gt;&lt;br /&gt;Git's tag objects have the advantage that they can be annotated directly in the tag, which is advantageous if you often need to store longer comments about particular revisions. In addition, both normal and lightweight tags can be selectively shared between repositories (via push/pull/etc). This feature adds some flexibility, allowing someone to publish only the tags that make sense for a public repository. &lt;br /&gt;&lt;br /&gt;For more information concerning how each system handles tags, check the manual for the respective system: &lt;a href="http://www.selenic.com/mercurial/hg.1.html/tag"&gt;Mercurial&lt;/a&gt;, &lt;a href="http://www.kernel.org/pub/software/scm/git/docs/git-tag.html"&gt;Git&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-4192971918855670215?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/4192971918855670215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/4192971918855670215'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2009/03/mercurial-vs-git-tags.html' title='Mercurial vs Git: Tags'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-2536302004557063426</id><published>2009-03-02T20:35:00.009-05:00</published><updated>2009-03-02T22:02:05.203-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Review'/><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><title type='text'>Uses of Mercurial's "bookmarks" Extension</title><content type='html'>The &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/BookmarksExtension"&gt;bookmarks&lt;/a&gt; extension that is now bundled with &lt;a href="http://www.selenic.com/mercurial"&gt;Mercurial&lt;/a&gt; makes it easy to keep track of multiple heads in a repository, similar to &lt;a href="http://www.git-scm.com"&gt;Git's&lt;/a&gt; "lightweight" branches.&lt;br /&gt;&lt;br /&gt;While Mercurial has always supported lightweight branches via multiple repository heads, they are somewhat difficult to keep track of because they are unnamed. Moving tags manually (or via a script) to keep track of each head becomes unwieldy, as does tracking by the last commit message. In Git, unnamed repository heads simply become inaccessible if they are not tagged. A branch in Git is basically a pointer to the head of a fork in the tree.&lt;br /&gt;&lt;br /&gt;Similar to Git's branches, &lt;span style="font-weight:bold;"&gt;bookmarks&lt;/span&gt; are markers that move forward with each commit automatically, allowing you to track different lines of work in one repository. This feature is perfect for small experimental features or bugfixes that will either later be thrown away or merged into the main line of development.&lt;br /&gt;&lt;br /&gt;NOTE: To take advantage of having a "current" bookmark, make sure you have the latest version of the extension, available &lt;a href="http://bitbucket.org/segv/bookmarks/overview/"&gt;here&lt;/a&gt;.&lt;br /&gt;You will also need to add the following section to your &lt;span style="font-weight:bold;"&gt;.hgrc&lt;/span&gt; or &lt;span style="font-weight:bold;"&gt;Mercurial.ini&lt;/span&gt;.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt;[extensions]&lt;br /&gt;hgext.bookmarks =&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;[bookmarks]&lt;br /&gt;track.current = True&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here are a few example uses of bookmarks to consider:&lt;br /&gt;&lt;br /&gt;Let's say you're working on a relatively small project and only have two clones, one for main development and a "stable" clone. You decide to start work on a new feature based off of version 1.0 of your project. Fortunately, thanks to your crazy awesome software development skills, you tagged v1.0 after it's release.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...create a bookmark for your new feature&lt;br /&gt;hg bookmark -r v1.0 awesome_feature&lt;br /&gt;...check out the code and set as the current bookmark&lt;br /&gt;hg update -C awesome_feature&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Those who are familiar with Git's branches will see the similarity. The current bookmark is set in &lt;span style="font-weight:bold;"&gt;.hg/bookmarks.current&lt;/span&gt;. Now you start on your feature.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...some good work going on&lt;br /&gt;hg commit -m "A good feature."&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You will notice that the bookmark moves along with your commit. With the extension set to track the "current" bookmark, only the one currently set will move forward. This means that you can set two bookmarks to the same revision, and as long as you update appropriately only one will move forward. This is different from how the bookmarks extension operates by default, which entails all bookmarks moving forward when a commit is done on their parent. &lt;br /&gt;&lt;br /&gt;Now you start another feature from the v1.0 revision and make some commits.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg bookmark -r v1.0 even_cooler_feature&lt;br /&gt;...set as current bookmark&lt;br /&gt;hg update -C even_cooler_feature&lt;br /&gt;...work&lt;br /&gt;hg commit -m "some work."&lt;br /&gt;...work&lt;br /&gt;hg commit -m "some more work."&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;*** soda break ***&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...work&lt;br /&gt;hg commit -m "almost done."&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Someone wants to help with one of your new features and clones the repository. Since they also want the bookmarks, they have to copy the &lt;span style="font-weight:bold;"&gt;.hg/bookmarks&lt;/span&gt; file over manually. &lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;This is important:&lt;/span&gt;&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;bookmarks are not part of the repository&lt;/span&gt; (yet). They are not pushed/pulled or cloned. However, since they refer to the hash of the changeset ID, they can be used in any clone of the repository.&lt;br /&gt;&lt;br /&gt;The anonymous helpful person does some work on the "awesome_feature", making a few commits and asks you to pull and review them. However, he has also made some commits to "even_cooler_feature" that are not ready yet, so you need to pull only the changes from the awesome_feature branch. This is a two step process, although it can be easily automated.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# update and set the current bookmark to awesome_feature so it is fowarded&lt;br /&gt;hg update -C awesome_feature&lt;br /&gt;# find the tip of the awesome_feature branch &lt;br /&gt;# (the location of the remote bookmark)&lt;br /&gt;hg id -r awesome_feature http://some.remote.repo&lt;br /&gt;74b4cb5hs4b2&lt;br /&gt;# pull all of the ancestor changesets of that tip&lt;br /&gt;hg pull -r 74b4cb5hs4b2 http://some.remote.repo&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;br /&gt;pulling from http://some.remote.repo&lt;br /&gt;searching for changes&lt;br /&gt;adding changesets&lt;br /&gt;adding manifests&lt;br /&gt;adding file changes&lt;br /&gt;added 2 changesets with 6 changes to 2 files&lt;br /&gt;(run 'hg update' to get a working copy)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The awesome_feature bookmark will have moved to the tip of your now updated branch, and you can review to your heart's content. No unrelated changesets were pulled. You can also push bookmarks just as you can with any other revision identifier.&lt;br /&gt;&lt;br /&gt;Now say you want to add an experimental feature that you may not keep.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg bookmark -r v1.0 experiment&lt;br /&gt;# locally tag the base of the branch so it can be deleted later if necessary&lt;br /&gt;hg tag -l experiment_base&lt;br /&gt;...some work&lt;br /&gt;hg commit -m "here goes nothing."&lt;br /&gt;...some more work.&lt;br /&gt;hg commit -m "work."&lt;br /&gt;...realization that this is a horrible idea&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can delete the bookmark and leave the head and changesets intact (which is what Git does), or remove the changesets with the strip command from Mercurial Queues.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# delete the reference to the tip&lt;br /&gt;hg bookmark -d experiment&lt;br /&gt;# now no one will ever know, muwahaha&lt;br /&gt;hg strip experiment_base&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There are many more things you can do with bookmarks, but this should get you started. This is a great extension and people who use both Git and Mercurial will enjoy having more flexibility with lightweight branches in Mercurial. I'm sure as the extension evolves we'll have more features to play with. I...err...of course mean "optimize our productivity". Have fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-2536302004557063426?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/2536302004557063426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/2536302004557063426'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2009/03/uses-of-mercurials-bookmarks-extension.html' title='Uses of Mercurial&apos;s &quot;bookmarks&quot; Extension'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-6666079574380573251</id><published>2009-02-28T23:31:00.030-05:00</published><updated>2009-03-02T20:35:01.951-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><title type='text'>Organizing Commits with Mercurial Queues and Attic</title><content type='html'>I've been using distributed version control for a few years. Although I've only collaborated with smaller groups of people, these tools have helped out immensely. However, I've only recently started using Mercurial to organize changes into logical commits. I use the &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/MqExtension"&gt;Mercurial Queues&lt;/a&gt; and &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/AtticExtension"&gt;attic&lt;/a&gt; (or &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/ShelveExtension"&gt;shelve&lt;/a&gt;) extensions. &lt;span style="font-weight:bold;"&gt;Note: &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;EDIT: A few people have mentioned that the workflow outline below is possible using only the attic extension. For the example outlined below, the attic extension would be adequate. However, using Mercurial Queues allows you to work on patches that depend on each other, which gives you quite a bit of flexibility, almost like a "queue" of patches ;).&lt;br /&gt; &lt;br /&gt;If you're using &lt;a href="http://git-scm.com"&gt;Git&lt;/a&gt;, check out &lt;a href="http://www.procode.org/stgit/"&gt;StGit&lt;/a&gt; and the &lt;a href="http://www.kernel.org/pub/software/scm/git/docs/git-stash.html"&gt;stash&lt;/a&gt; command, or with &lt;a href="http://bazaar-vcs.org"&gt;Bazaar&lt;/a&gt;, the &lt;a href="https://launchpad.net/bzr-loom"&gt;Loom&lt;/a&gt; and &lt;a href="http://doc.bazaar-vcs.org/bzr.dev/en/user-guide/index.html#a-brief-tour-of-some-popular-plugins"&gt;shelve&lt;/a&gt; commands for similar functionality. Similar workflows are also possible with the help of the &lt;a href="http://book.git-scm.com/1_the_git_index.html"&gt;Git Index&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;My workflow has traditionally gone something like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...work on some parts of features...&lt;br /&gt;hg commit -m "Added feature1, part of feature2..."&lt;br /&gt;...some more random work...&lt;br /&gt;hg commit&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;While my commits contain generally related items, the implementation of features is often spread out among commits. Below is an example of an alternative workflow resulting in more organized commits.&lt;br /&gt;&lt;br /&gt;Say we're working on a multithreaded application, and have written the skeleton code for the worker thread function. Without committing, we began working on the code for the main thread.&lt;br /&gt;We could always commit with the &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/RecordExtension"&gt;record&lt;/a&gt; extension or something similar, but there is a more natural way.&lt;br /&gt;&lt;br /&gt;Store away the changes related to the main function interactively (similar to record) in a patch called &lt;span style="font-weight:bold;"&gt;main.p&lt;/span&gt;. It will be stored in &lt;span style="font-weight:bold;"&gt;.hg/attic&lt;/span&gt;.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg shelve -i main.p&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Initialize a Mercurial Queues repository:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg qinit -c&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Create a new patch to track the changes to the worker thread (use the &lt;span style="font-weight:bold;"&gt;-f&lt;/span&gt; flag to include local changes.) The patch will be stored as &lt;span style="font-weight:bold;"&gt;.hg/patches/workerthread.p&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg qnew -f workerthread.p&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Refresh the patch, and create a new patch for the main thread.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg qrefresh&lt;br /&gt;hg qnew mainthread.p&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;Restore the changes we saved earlier, and delete the temporary patch from the attic directory.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg unshelve --delete main.p&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The working directory is now updated with those changes. Refresh the  mainthread.p patch.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg qrefresh&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We can use the &lt;span style="font-weight:bold;"&gt;qapplied&lt;/span&gt; command at any time to look at the applied patches that Mercurial Queues is managing:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hg qapplied&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;br /&gt;mainthread.p&lt;br /&gt;workerthread.p&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We are now free to work on the patches separately, using &lt;span style="font-weight:bold;"&gt;qpush&lt;/span&gt; and &lt;span style="font-weight:bold;"&gt;qpop&lt;/span&gt; to switch to the patch we want to edit, then running &lt;span style="font-weight:bold;"&gt;qrefresh&lt;/span&gt; to save our changes. Mercurial will warn you when you try to switch patches without saving local changes. It's also possible to change the order that the patches are applied by editing the &lt;span style="font-weight:bold;"&gt;.hg/patches/series&lt;/span&gt; file. Just make sure that none of them are applied! When we feel that one of our patches is ready, we can turn it into a "real" commit using &lt;span style="font-weight:bold;"&gt;qfinish&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I highly recommend reviewing the Mercurial Queues documentation if you use Mercurial. It opens the door to workflows of which you may not have been aware. Organized commits are especially important when collaborating on projects that depend on patches. When each commit makes one logical change or a group of logically related changes, the process of tracking down the source of a bug is greatly simplified.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-6666079574380573251?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/6666079574380573251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/6666079574380573251'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2009/02/organizing-commits-with-mercurial.html' title='Organizing Commits with Mercurial Queues and Attic'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-5229643279410503931</id><published>2009-01-02T23:50:00.007-05:00</published><updated>2009-01-03T00:22:14.522-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Audio with Flash Applications in Firefox (Linux)</title><content type='html'>The title of this post may not be the best, but this issue does not apply to a particular distribution, or to all distributions. As far as I can tell, it just depends on your distribution and sound hardware. I had the issue with Slackware 12.2, but I had not encountered it in previous versions with the same hardware.&lt;br /&gt;&lt;br /&gt;The problem is as follows: You have configured ALSA properly, adjusted using your favorite mixer, and sound works normally (tested by playing a sound file in amp/xmms/etc). However, sound from Flash based websites (using the Adobe Flash plugin) does not play in Firefox. This includes websites such as Youtube and Pandora. The most common fix I encountered was to install &lt;span style="font-weight:bold;"&gt;libflashsupport&lt;/span&gt;, which adds support for non-ALSA sound systems to the Adobe Flash Player. If you use Slackware, there is a Slackbuild file over at &lt;a href="http://slackbuilds.org/repository/12.2/libraries/libflashsupport/"&gt;slackbuilds.org&lt;/a&gt;. Most other distributions should have an appropriate package.&lt;br /&gt;&lt;br /&gt;I had some trouble finding the solution to this issue, so I hope this helps. Best of luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-5229643279410503931?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/5229643279410503931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/5229643279410503931'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2009/01/audio-with-flash-applications-in.html' title='Audio with Flash Applications in Firefox (Linux)'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-3208447771937886720</id><published>2008-11-26T23:49:00.012-05:00</published><updated>2008-11-27T01:03:28.759-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Working with Sets in Common LISP</title><content type='html'>For a long time I was unaware that Common LISP has built in facilities for working with sets. I may have been looking in the wrong places (actually, I'm *sure* that was the case), but other people must have come across the same issue. I'll outline the most common LISP functions for dealing with sets below. &lt;a href="http://www.gigamonkeys.com/book/beyond-lists-other-uses-for-cons-cells.html"&gt;Chapter 13&lt;/a&gt; of &lt;a href="http://www.gigamonkeys.com/book/"&gt;Practical Common LISP&lt;/a&gt; has some more information for anyone who is interested.&lt;br /&gt;&lt;br /&gt;The easiest way to represent a set in Common LISP is as a list. Shocking, I know. To add an item, use &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_adjoin.htm"&gt;adjoin&lt;/a&gt; or &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_pshnew.htm"&gt;pushnew&lt;/a&gt;. They both check to see if an item is already in the list before adding it to avoid duplicates. The difference between the two is that &lt;span style="font-weight:bold;"&gt;pushnew&lt;/span&gt; modifies the original list and &lt;span style="font-weight:bold;"&gt;adjoin&lt;/span&gt; does not. In addition, since the lists are treated as sets the order of the elements does not matter.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;; Create a list of numbers&lt;br /&gt;&gt; (setq li '(1 2 3 4 5))&lt;br /&gt;; Try to add another 2&lt;br /&gt;&gt; (adjoin 2 li)&lt;br /&gt;(1 2 3 4 5)&lt;br /&gt;; Try to add a 0&lt;br /&gt;&gt; (adjoin 0 li)&lt;br /&gt;(0 1 2 3 4 5)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can check whether an item is in a set with the &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_mem_m.htm"&gt;member&lt;/a&gt; function, or it's companions &lt;span style="font-weight:bold;"&gt;member-if&lt;/span&gt; and &lt;span style="font-weight:bold;"&gt;member-if-not&lt;/span&gt;. Instead of returning just the item (what the &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_find_.htm"&gt;find&lt;/a&gt; family of functions do), &lt;span style="font-weight:bold;"&gt;member&lt;/span&gt; returns a sublist containing the item and all subsequent items in the original list.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;; Using our list from the previous example&lt;br /&gt;&gt; (member 2 li)&lt;br /&gt;(2 3 4 5)&lt;br /&gt;&gt; (member 8 li)&lt;br /&gt;nil&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Common LISP also includes the basic set functions &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_isec_.htm"&gt;intersection&lt;/a&gt;, &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_unionc.htm"&gt;union&lt;/a&gt;, and &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_set_di.htm"&gt;set-difference&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;; Create some sets&lt;br /&gt;&gt; (setq s1 '(1 2 3 4))&lt;br /&gt;&gt; (setq s2 '(3 4 5 6))&lt;br /&gt;; Find the intersection&lt;br /&gt;&gt; (intersection s1 s2)&lt;br /&gt;(3 4)&lt;br /&gt;; Find the Union&lt;br /&gt;&gt; (union s1 s2)&lt;br /&gt;(1 2 3 4 5 6)&lt;br /&gt;; Find the Set Difference between s1 and s2&lt;br /&gt;&gt; (set-difference s1 s2)&lt;br /&gt;(1 2)&lt;br /&gt;; Find the Set Difference between s2 and s1&lt;br /&gt;&gt; (set-difference s2 s1)&lt;br /&gt;(5 6)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Remember that all of these functions accept the optional &lt;span style="font-weight:bold;"&gt;:test&lt;/span&gt; parameter, and therefore can be used with any data type. There are more set related functions, however these are those that I found most useful and others may as well. Check out the full function documentation in the &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Front/index.htm"&gt;Common LISP Hyperspec&lt;/a&gt; or the chapter in &lt;span style="font-style:italic;"&gt;Practical Common LISP&lt;/span&gt; mentioned above for more information. LISP time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-3208447771937886720?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/3208447771937886720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/3208447771937886720'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/11/working-with-sets-in-common-lisp.html' title='Working with Sets in Common LISP'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-4500100536476358870</id><published>2008-10-30T23:08:00.006-04:00</published><updated>2008-10-30T23:32:10.684-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Always Initialize Your Pointers!</title><content type='html'>I've recently been debugging quite a bit of C code that was written a while back. The original developers rarely initialized their pointers, maybe 30% of the time. I linked most of the memory leaks and crashes back to those pointers. Moral of the story: &lt;span style="font-weight:bold;"&gt;Always Initialize Your Pointers&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;If you are not familiar with the difference between an &lt;span style="font-style:italic;"&gt;uninitialized&lt;/span&gt; or bad pointer, and a &lt;span style="font-style:italic;"&gt;null&lt;/span&gt; pointer, keep reading. &lt;br /&gt;&lt;br /&gt;When a pointer is declared and not initialized, there is no telling where it points to. This is also sometimes referred to as a "bad pointer". When you try and deference it, the program will try and jump to the address of whatever random value happens to be in that spot in memory. Also, it is sometimes outside the range of memory locations allocated to your program, resulting in the classic &lt;span style="font-weight:bold;"&gt;segfault&lt;/span&gt; on UNIX's, or an &lt;span style="font-weight:bold;"&gt;illegal operation&lt;/span&gt; for the Windows folks. Keep in mind that this doesn't always happen, if the address is within your program memory, sometimes your program will just quietly self destruct internally and the error will show up later. Good times, good times.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;int* somePointer; //This is an unitialized pointer.&lt;br /&gt;&lt;br /&gt;//There is no telling what this will do.&lt;br /&gt;printf("%d", somePointer)&lt;br /&gt;&lt;br /&gt;//Uh-oh. This will definitely throw an error.&lt;br /&gt;free(somePointer);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;However, if you initialize a pointer when you declare it, this eliminates most of those problems, as it is now a "null" pointer. In C and C++, null pointers are easy to test for. Setting a pointer to null directly after freeing it is also considered good practice. &lt;br /&gt;&lt;br /&gt;You may think that since you're assigning a value to the pointer three lines down in the function, it's not worth initializing when you declare it. What happens when you remove that line during refactoring or debugging and forget about it? Exactly.&lt;br /&gt;Do yourself and your colleagues a favor. Initialize your pointers (either with null or a value) when they are declared, and set them to null after you free them.&lt;br /&gt;&lt;br /&gt;A properly allocated and freed pointer:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;int* somePointer = NULL; //Can also be 0&lt;br /&gt;somePointer = (int*)(malloc(sizeof(int)));&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;some code...&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;free(somePointer);&lt;br /&gt;somePointer = NULL;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-4500100536476358870?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/4500100536476358870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/4500100536476358870'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/10/always-initialize-your-pointers.html' title='Always Initialize Your Pointers!'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-8035686459267468841</id><published>2008-10-19T11:50:00.003-04:00</published><updated>2008-10-19T13:39:21.945-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Configuring OpenCV v1.1pre1 in Visual Studio 2005</title><content type='html'>I'm currently using &lt;span style="font-weight: bold;"&gt;OpenCV&lt;/span&gt; for a project, and since a new version was released October 15th, I decided to update the libraries. It turns out a few tricks are needed to get the auxiliary libraries and sample applications to compile in debug mode (in Visual Studio 2005), as the source for JasPer (for reading JPG images) was not included, and there is no debug version of the library present. Below I've outlined the steps I took to make everything compile correctly. If you're using Visual Studio 2008, I imagine the steps below will still work with some minor tweaking.&lt;br /&gt;&lt;br /&gt;1) &lt;a href="http://sourceforge.net/projects/opencvlibrary/"&gt;Download OpenCV v1.1pre1&lt;/a&gt;.&lt;br /&gt;2) Run the executable and install OpenCV. Go to the start menu item for&lt;br /&gt;"OpenCV .NET Workspace 2005,2008" and open it. Building some of the&lt;br /&gt;items requires libjasper, so we'll build that next.&lt;br /&gt;&lt;br /&gt;3) &lt;a href="http://www.ece.uvic.ca/%7Emdadams/jasper/"&gt;Download JasPer (1.900.1)&lt;/a&gt;&lt;br /&gt;4) Extract the files, and navigate to the &lt;span style="font-style: italic;"&gt;...\src\msvc&lt;/span&gt; directory. Open the&lt;br /&gt;project and let Visual Studio convert it to the new format. Build the&lt;br /&gt;debug version, it should compile with no issues.&lt;br /&gt;5) Go to the debug output folder and rename libjasper.lib to libjasperd.lib&lt;br /&gt;6) Copy libjasperd.lib to &lt;span style="font-style: italic;"&gt;...\OpenCV\otherlibs\_graphics\lib&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;7) Back in the main OpenCV solution, right click on the "highgui" project&lt;br /&gt;and open the properties window. Under the "Linker" section, and the&lt;br /&gt;"Ignore Specific Library" field, add "libcmtd.lib" to the list.&lt;br /&gt;8) Build the "highgui" project.&lt;br /&gt;9) The rest of the projects should now build with no problem.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;NOTE:&lt;/span&gt; Some of the libraries are not compiled, so you may need to compile everything in the solution before any of the sample programs will work.&lt;br /&gt;&lt;br /&gt;Good Luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-8035686459267468841?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/8035686459267468841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/8035686459267468841'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/10/configuring-opencv-v11pre1-in-visual.html' title='Configuring OpenCV v1.1pre1 in Visual Studio 2005'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-8825316342363850124</id><published>2008-10-12T15:46:00.012-04:00</published><updated>2008-10-13T01:26:27.874-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Looping in Common Lisp</title><content type='html'>I'm currently taking an Artificial Intelligence class, and had my first assignment to be done in Common Lisp. There have been many variations of Lisp over the years, and currently the two major dialects are &lt;a href="http://en.wikipedia.org/wiki/Common_Lisp"&gt;Common Lisp&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Scheme_%28programming_language%29"&gt;Scheme&lt;/a&gt;, both of which are commonly used for Artificial Intelligence related applications.&lt;br /&gt;Since I was learning Common Lisp over the course of doing the project, I had a somewhat difficult time getting the syntax for loops correct. For those of you who support the "pure" functional programming paradigm (where side effects and loops are &lt;span style="font-weight:bold;"&gt;evil&lt;/span&gt;): I took the lazy approach of using a loop and some variables rather than figuring out how to do the recursion. Faster? Maybe. Overall better? Varies by opinion. Feel free to disagree.&lt;br /&gt;&lt;br /&gt;Anyway, these are the most useful and "safe" ways I found to do loops without causing massive debugging headaches that cause you to want to switch to a lucrative career in ice cream sales.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;loop: The simplest loop structure&lt;br /&gt;&lt;/span&gt;The "loop" structure is as simple as you can get. It provides no built-in termination, you must provide that yourself with a conditional statement, and the "return" command. Here is a simple example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(let ((n 5))&lt;br /&gt;  (loop&lt;br /&gt;   (print "Looping!")&lt;br /&gt;   (- n 1)&lt;br /&gt;  (if (&lt; n 0) (return "Finished"))&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;do: General Counting Loop&lt;/span&gt;&lt;br /&gt;The "do" loop is analogous to the "for" loop structure in many languages. You can specify several variables, rules for how they are to be updated each iteration, and a stopping condition. For me, it took a little while to get used to the syntax, but once you understand the structure, you have a great deal of flexibility at your fingertips. The general syntax is as follows:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(do (([var1] [var1 initial value] [var1 step])&lt;br /&gt;     ([var2] [var2 initial value] [var2 step])&lt;br /&gt;     .&lt;br /&gt;     .&lt;br /&gt;    )&lt;br /&gt;    ([stopping-condition-test] [return value])&lt;br /&gt;    ...commands....&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A simple example that will loop 10 times, each time printing "Looping..." and&lt;br /&gt;then will print "Finished":&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(do ((i 0 (+1 i))&lt;br /&gt;  ((= i 10) "Finished")&lt;br /&gt;  (print "Looping...")&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;dotimes:&lt;/span&gt;&lt;br /&gt;"dotimes" is a specialized form of the "do" loop, suited for situations where you know exactly how many times you need to iterate. It basically saves you from having to enter a stopping condition, by counting from 0 until the number you specify. Here is the syntax:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(dotimes ([variable] [final-value])&lt;br /&gt; ...commands...&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;An example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(dotimes (i 10)&lt;br /&gt; (print i)&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;dolist:&lt;/span&gt;&lt;br /&gt;"dolist" is another specialized form of "do", perfect for iterating through a list. You need to specify an iteration variable (holds the value of the current item in the list) and a list to iterate through. The basic form is as follows:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(dolist ([variable] [list])&lt;br /&gt;  ...commands...&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;An example that squares each value of a list of numbers:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(dolist (item '(1 2 3 4 5))&lt;br /&gt;  (print (* item item))&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Note:&lt;/span&gt; In this situation you could also use the one of the "map" functions (mapcar or maplist) to apply a function to each successive item in a list (mapcar), or to successive cdr's of a list (maplist). These functions both return another list.&lt;br /&gt;&lt;br /&gt;Now, go forth and Lisp.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-8825316342363850124?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/8825316342363850124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/8825316342363850124'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/10/looping-in-common-lisp.html' title='Looping in Common Lisp'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-7713924776849605582</id><published>2008-10-02T23:29:00.007-04:00</published><updated>2008-10-03T00:56:38.899-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Review'/><category scheme='http://www.blogger.com/atom/ns#' term='Games'/><title type='text'>A Review of Spore</title><content type='html'>So...Spore. The game many of us have been anticipating for years. Many are disappointed at how it turned out, throwing out a lot of criticism; some of it deserved, some of it not. This will by no means be a full rebuttal to everything I've read, but I have addressed a few issues. I didn't even  limit it to worthless pricks! It turns out that's only about 80% of the internet. I'm sure everyone can guess what groups make up the rest. Anyway, before I get started:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;DISCLAIMER: Yes, the DRM included by EA is a horrible idea and probably reduced their sales to a fraction of what they could have been. However, I am not going to address that. &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;If you want to see people complain about the DRM, r&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;ead the comments of any article featured on Digg that even mentions Spore. Even some that don't. Seriously.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;1) The game is watered down so much it is boring.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;This is a pretty broad claim, and&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;encompasses a lot of the other criticisms that I address below. In short, I will say that the game is watered down from it's original design and is not quite what everyone was expecting. However, this does not automatically make it a bad game, for reasons I discuss.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;2) The game has very little depth, and is basically a simplified combination of five games.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;If you have not played Spore yet, &lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;the game is divided into five&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;"stages"; cell stage, creature stage, tribal stage, civilization stage, and the space stage.&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;/span&gt;Your creature starts in the cell stage and "evolves" up through the space stage.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;"&gt;cell stage&lt;/span&gt; is a lot of fun, simply because you just swim around, eat stuff, and kill other cells. It's a good, solid, two dimensional life. This is the shortest stage, after which at some point you seem to discover that there are three dimensions and grow some type of legs. Or not, it's your choice. Once on land, you are in the &lt;span style="font-weight: bold;"&gt;creature stage&lt;/span&gt;, during which you eat, make friends or hunt other creatures, and find random creature parts from skeletons that just happen to be lying around and sparkle at you. This stage is pretty underrated. You can have a lot of fun trying to locate all the creature parts to build awesome creatures.&lt;br /&gt;&lt;br /&gt;I actually agree with the criticism of the &lt;span style="font-weight: bold;"&gt;tribal stage&lt;/span&gt;. It is very simplistic compared to what it could be. When dealing with another tribe, you can destroy them, or give them food until they like you enough to let you perform a musical selection for them. After you've conquered or befriended all the tribes, you move to the &lt;span style="font-weight: bold;"&gt;civilization stage&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I've read a lot of criticism that this stage is an extremely watered down version of the classic Civilization games. There are quite a few similarities, but I think this stage is just to segway your creatures' expansion into space, since it is almost a direct subset of the space stage. While it is pretty easy, I still enjoy it.&lt;br /&gt;I've seen a few complaints that this stage should be more like an RTS (real time stragety game). Remember that Spore is not supposed to be five games. It's supposed to contain five stages of development. Making this stage an RTS would take away from the other stages.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;"&gt;space stage&lt;/span&gt; is what Spore is all about. As you advance through the space stage, you obtain tools to accomplish quite a bit, including the manipulation of lesser species, and planet destruction. With the exception of the cell stage (which is just cool), my guess is that the other stages act as tutorials to help you hit the ground running when you obtain these tools. They are fun in themselves, but the space stage is where the real depth of the game lies. You ally, declare war, and trade with other empires, expand your empire and terraform planets.&lt;br /&gt;&lt;br /&gt;The creature stage lets you experience modifying a species, and how various species interact. The tribal stage introduces diplomacy in the game, and the civilization stage ultimately teaches you how to manage your home planet and colonies.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;3) The DRM is horrible. Why would EA do this?&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;Seriously, did you even read the introduction? &lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;Exactly, now keep reading.&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;4) It's difficult to accomplish anything in the space stage because you keep getting called back to your home planet or a colony every few minutes to solve an ecodisaster or an invasion.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt; Also, there is only one spaceship in the whole empire!&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;This does happen when you reach a certain point in the space stage (although the first official patch reduces the amount of disasters and attacks in easy and normal mode), however once you obtain the funding to properly outfit your colonies with defense turrets, it is no longer a problem. They may still call you back, but they survive fine with no help. With a sufficient number of colonies, you make more money every few minutes than you could possibly need.&lt;br /&gt;&lt;br /&gt;The one spaceship issue is kind of annoying, but keeps the game from being too close to an RTS at this level and allows more of a sense of immersion. I know quite a few people disagree, but my guess is that was the intent. Also, you can travel to the center of the galaxy.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;5) There is no actual evolution!&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;This is true, and I do not know if this was ever planned to be included. It would have been nice to have some simple evolution like that which occurs in the old &lt;a href="http://en.wikipedia.org/wiki/SimLife"&gt;SimLife&lt;/a&gt; game, but nothing is perfect. Spore already includes some amazing technological achievements, most notably the procedural generation of the planet environments and the galaxy, the various creators, and the texturing system used.&lt;br /&gt;&lt;br /&gt;Creating creatures, buildings, and vehicles is awesome, and probably one of the best characteristics of the game. By the time you get to the space stage, your creature has various accessories from all the previous stages. Also, if they are anything like all the other races, they have an annoying voice and often jump around excitedly for no apparent reason.&lt;br /&gt;Regardless, it is a lot of fun to see how other people interact with your race (see the Sporepedia) and to see a less evolved version of one of your creatures in another game.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;6) The Grox are the biggest jerks ever.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;All part of the game, my friend.&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;/span&gt;I'm sure you know people with the same attitude.&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;7) I disagree, and you sir, are an idiot.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;That could be. At least that sentence makes sense and everything is spelled right. Oh yeah, I worded it for you.&lt;br /&gt;&lt;br /&gt;This is just my opinion, you do not have to agree with it. I play Spore a great deal and have a lot of fun with it. Games do not always have to be about constantly using strategy and tactics to destroy an enemy. That is always awesome, but Spore is a different type of game. Maybe not what everyone expected, but still great.&lt;br /&gt;&lt;br /&gt;Now, if you live in the US, take a break from games, do something useful, and go watch the Vice Presidential debate (CNN, Youtube, etc).&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-7713924776849605582?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/7713924776849605582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/7713924776849605582'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/10/review-of-spore.html' title='A Review of Spore'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-5964686609690506968</id><published>2008-09-26T18:20:00.003-04:00</published><updated>2008-09-26T18:25:51.024-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Life'/><title type='text'>The Return</title><content type='html'>So I have not posted for a while. A long while. However, it's all good.&lt;br /&gt;I'm back into the swing of school, and I'm planning on writing at least one post a week here. To start out, I will post a rebuttal to a lot of criticism written recently by some worthless pricks concerning &lt;a href="http://www.spore.com/"&gt;Spore&lt;/a&gt; , and my experiences with common LISP. Stay Tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-5964686609690506968?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/5964686609690506968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/5964686609690506968'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/09/return.html' title='The Return'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-4610351058373083164</id><published>2008-07-21T22:19:00.004-04:00</published><updated>2008-07-22T21:52:12.247-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Review'/><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Embedding Mozilla in Java SWING Applications:JDIC and Mozswing</title><content type='html'>Sorry for the delay, I have been doing some overtime at work and have been pretty lethargic outside of it. Anyway, on with the article!&lt;br /&gt;&lt;br /&gt;If you need to embed a web browser into a Java Swing application on Windows, you have many options, of which I have found the most useful is &lt;a href="https://jdic.dev.java.net/documentation/incubator/JDICplus/index.html"&gt;JDICplus&lt;/a&gt;,  or &lt;a href="https://jdic.dev.java.net/"&gt;JDIC&lt;/a&gt; itself. Both of these approaches are very well documented with excellent sample code.&lt;br /&gt;&lt;br /&gt;However, doing this in a Linux environment is a little more complicated. I succeeded using no commercial software. There may be much better methods, but this is what worked for me.&lt;br /&gt;I was initially able to get the package up and running using &lt;a href="http://sourceforge.net/projects/mozswing"&gt;Mozswing&lt;/a&gt;. There is currently next to no documentation, but looking at the provided sample code helps a great deal. It uses the &lt;a href="http://developer.mozilla.org/en/docs/XULRunner"&gt;Xulrunner&lt;/a&gt;   application from Mozilla to embed the browser. I did experience some instability (probably due to their Java/GTK libraries) under certain conditions, but they were easy to spot. The issues seem to be present if the Java application uses a large number of JNI calls. If you experience instability, I recommend using JDIC as discussed below.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Pros: &lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Embeds a browser as a JPanel, fully compatible with the rest of the Swing application&lt;/li&gt;&lt;li&gt;Tri-Licensed (GPL, LPGL, Mozilla), so it can be used in all the same situations as Mozilla.&lt;/li&gt;&lt;li&gt;Uses an up-to-date version of Xulrunner&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Cons:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;Early in development, currently at Beta 1 release&lt;/li&gt;&lt;li&gt;Some instability issues with Java applications that make heavy use of JNI&lt;/li&gt;&lt;li&gt;Many JAR and SO libraries&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Because of the stability issues I tried out &lt;a href="https://jdic.dev.java.net/"&gt;JDIC&lt;/a&gt;. Although at the time of this writing, the front page says it has not been updated since 2006, looking at the download page shows some active development. JDIC proved to be very stable, no matter the situation, and had few JAR and SO library files to carry around. It does embed the browser as an AWT component, so in some situation that may be an issue. However, I used it in an application with a very rich Swing GUI, and had no problems with the browser window drawing/resizing as necessary. I was also only able to use JDIC with &lt;a href="http://www.mozilla.org/developer/"&gt;Mozilla 1.7.13&lt;/a&gt;, which is kind of old. OK, fine. Really old. JDIC does not work with Firefox, and for some reason on Linux, embedding Seamonkey causes the scrollbars to disappear.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Pros:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;Very stable&lt;/li&gt;&lt;li&gt;Licensed as LGPL, not GPL&lt;/li&gt;&lt;li&gt;Very little JAR and SO baggage to distribute&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Cons:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;Only works correctly with old version of Mozilla.&lt;/li&gt;&lt;li&gt;Embeds as an AWT component, which could cause problems in some Swing applications.&lt;/li&gt;&lt;/ul&gt;During this process I was able to find very little information on this subject. If you are faced with this problem and are unable to use a commercial library to solve the problem, I hope this information can help you piece together a solution.&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-4610351058373083164?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/4610351058373083164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/4610351058373083164'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/07/embedding-mozilla-in-java-swing.html' title='Embedding Mozilla in Java SWING Applications:JDIC and Mozswing'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-229426811284254271</id><published>2008-06-28T10:41:00.010-04:00</published><updated>2008-06-28T12:21:48.177-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Interfacing C/C++ with Java Through JNI</title><content type='html'>There are quite a few applications that for one reason or another are written partially in C++, and partially in Java. In most cases it seems the GUI is the Java portion. While several methods exist to interface C++ and Java, the one that is a core part of Java is the &lt;span style="font-weight: bold;"&gt;JNI&lt;/span&gt;, or &lt;span style="font-weight: bold;"&gt;Java Native Interface&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;It is much easier to use the JNI than one might think, although it does produce some nasty looking C code so it is sometime difficult to debug. The process for creating methods with the JNI is simple. This example uses the tools included with the standard JDK (Java Development Kit).&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Create a class and include declarations for the method you would like to implement in C/C+&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class TestJNIClass {&lt;br /&gt;   //Method declaration.&lt;br /&gt;  private static native void testJNI();&lt;br /&gt;&lt;br /&gt;  //Loads the library. Use System.loadLibrary() &lt;br /&gt;  //if the library will be registered with the system.&lt;br /&gt;  static {&lt;br /&gt;      System.load("./TestJNIClass.o"); //For UNIX&lt;br /&gt;      //System..load(./TestJNiClass.dll); //For Windows&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  //Test call to the method&lt;br /&gt;  public static void main(String[] args) {&lt;br /&gt;  TestJNIClass.testJNI();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Compile the class: &lt;span style="font-family:courier new;"&gt;javac TestJNIClass.java&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:georgia;"&gt;Generate the C header file with the javah tool: &lt;span style="font-family:courier new;"&gt;javah -jni TestJNIClass &lt;span style="font-family:georgia;"&gt;(There are many options you can pass to this command, check out the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/solaris/javah.html"&gt;man page&lt;/a&gt;).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:georgia;"&gt;Implement the C or C++ functions you would like to include, then compile using your compiler of choice. &lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;Note:&lt;/span&gt;&lt;/span&gt; &lt;span style="font-style: italic;"&gt;If you get errors about a missing jni.h file, be sure to include the JDK Home/include directory, and if you're on Windows, the JDK Home/include/win32 directory as well. Make sure you are compiling a library native to your system (for example, DLL on Wndows)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include "TestJNIClass.h"&lt;br /&gt;&lt;br /&gt;JNIEXPORT void JNICALL Java_TestJNIClass_testJNI&lt;br /&gt;  (JNIEnv *, jclass)&lt;br /&gt;  {&lt;br /&gt;    printf("Output!\n");&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Run the java class you compiled earlier, and it will call the native method you wrote in C/C++!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;If you you need your methods to return simple datatypes, simply add the return type to the declaration in the java file. This article barely scratches the surface of what you can do with JNI, be sure to check out the official Sun documentation or if you're really interested, there are several books written about JNI.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-229426811284254271?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/229426811284254271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/229426811284254271'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/06/interfacing-cc-with-java-through-jni.html' title='Interfacing C/C++ with Java Through JNI'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-6669087384309175639</id><published>2008-06-22T18:23:00.008-04:00</published><updated>2008-12-10T23:45:38.768-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Management'/><category scheme='http://www.blogger.com/atom/ns#' term='Design'/><title type='text'>Managing Solo Software Development with Spreadsheets</title><content type='html'>This is more of a quick tip than a full-fledged how-to.&lt;br /&gt;&lt;br /&gt;For software projects involving only one person, or even just a few people, there is no reason to deploy a full-fledged item tracking system to manage the various components of the project and to who each item is assigned. The method I use involves a simple spreadsheet. Almost any spreadsheet software (Excel, GNumeric, etc) will work, as only the base features are needed.&lt;br /&gt;&lt;br /&gt;First, decide which characteristics each&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;span style="color: rgb(102, 102, 102); font-weight: bold;"&gt;item&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);"&gt; &lt;/span&gt;or &lt;span style="color: rgb(102, 102, 102); font-weight: bold;"&gt;task&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;of the project will have. I recommend assigning each task the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Name&lt;/li&gt;&lt;li&gt;Description&lt;/li&gt;&lt;li&gt;Assignee (if more than one person is involved)&lt;/li&gt;&lt;li&gt;Estimated Time&lt;/li&gt;&lt;li&gt;Actual Time&lt;/li&gt;&lt;li&gt;Status (Defined, In progress, Finished, etc)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;For projects that are not simple enough to be divided into tasks, you can divide each task into components, with each having the above characteristsics as well as the task they are assigned to. For example:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_LBWNVs7jpgg/SF7YCrTk75I/AAAAAAAAAAU/5ytw1Muj5ag/s1600-h/temp.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_LBWNVs7jpgg/SF7YCrTk75I/AAAAAAAAAAU/5ytw1Muj5ag/s400/temp.jpg" alt="" id="BLOGGER_PHOTO_ID_5214842959037788050" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;This method of managing projects works well for me. Hopefully you will be able to adapt it to your needs. Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-6669087384309175639?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/6669087384309175639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/6669087384309175639'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/06/managing-solo-software-development-with.html' title='Managing Solo Software Development with Spreadsheets'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_LBWNVs7jpgg/SF7YCrTk75I/AAAAAAAAAAU/5ytw1Muj5ag/s72-c/temp.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-3412150414367950711</id><published>2008-06-15T11:42:00.003-04:00</published><updated>2008-06-15T12:04:35.501-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Games'/><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><title type='text'>Alternative Uses for Version Control: Games</title><content type='html'>I am an avid player of &lt;a href="http://simcity.ea.com/index.php"&gt;Simcity 4&lt;/a&gt;. However when trying out a new strategy for developing a city, I find it much easier to plan out the development in stages, and save the cities between stages. Making backup copies of a city is a pain because each city file is stored in a region folder. You need to manually copy the file to a different location and rename it. Obviously, if you plan on backup up a city more than a few times during its development, this becomes a pain.&lt;br /&gt;&lt;br /&gt;One solution I have been using recently is to place the region folder under version control using &lt;a href="http://www.selenic.com/mercurial"&gt;Mercurial&lt;/a&gt;. In fact, almost any version control tool would work in this situation. Simply add the cities you want to track, and make commits whenever you reach a point you want to preserve. If a few saves later you notice that your decision to build a prison in the middle of a high wealth residential zone is not quite working out, instead of destroying it and trying to improve the land value again, you can simply revert to an earlier revision. Here is an example using Mercurial:&lt;br /&gt;&lt;br /&gt;[Create a new city within the game]&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;hg commit "City - TheCity.sc4" -m "Initial Commit."&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;[Play the city for a while, make a few saves]&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;hg commit "City - TheCity.sc4" -m "Basic residential, adding more industrial."&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;[Play the city for while]&lt;br /&gt;[Massive air and water pollution...overall reduction in health...uh oh]&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;hg revert "City - TheCity.sc4"&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;This is an oversimplified example, but you get the idea. While this obviously does not promote realism in the development of a city, when trying out new techniques it can save you a lot of time and frustration. This idea is also applicable to other games that do not have some type of "save as" feature to back up progress.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-3412150414367950711?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/3412150414367950711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/3412150414367950711'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/06/alternative-uses-for-version-control.html' title='Alternative Uses for Version Control: Games'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-6458887162157750114</id><published>2008-05-30T10:38:00.011-04:00</published><updated>2008-05-30T11:35:53.519-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Review'/><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><title type='text'>Managing Multiple Repositories with Mercurial</title><content type='html'>Unfortunately my interest has shifted to other projects, so I will not be continuing my series on different distributed revision control systems at the moment. I may pick it up again at some point in the future. However, since I currently use &lt;a href="http://www.selenic.com/mercurial"&gt;Mercurial,&lt;/a&gt; I will be posting information on how I use it. For now I'll give an overview of different ways to use Mercurial to manage multiple projects.&lt;br /&gt;&lt;br /&gt;From my personal experience as well as sources that I have read, it seems that there are three main ways to use Mercurial to manage multiple projects:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold; color: rgb(204, 204, 204);"&gt;Single Repository&lt;/span&gt;&lt;span style="color: rgb(255, 255, 255);"&gt; &lt;/span&gt;- There is a root directory called something like "projects", which is the Mercurial repository. Each project has a subfolder, but all of the tracked files are in the main repository.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold; color: rgb(204, 204, 204);"&gt;Multiple Repositories&lt;/span&gt;&lt;span style="color: rgb(204, 204, 204);"&gt; &lt;/span&gt;- Each project has its own repository. They are most likely all grouped under the same root folder, but all have different histories and are managed independently.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold; color: rgb(204, 204, 204);"&gt;Multiple Repositories with the ForestExtension&lt;/span&gt; - Each project has it's own repository, however they are all "nested" repositories in one large Mercurial repository. The &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/ForestExtension"&gt;ForestExtension&lt;/a&gt; provides commands to manage all the repositories in a loose group.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold; color: rgb(255, 204, 51);"&gt;Single Repository&lt;/span&gt;&lt;br /&gt;This is the setup I currently use. I have a main "Projects" directory, containing folders for various categories of projects. Each of those in turn has a folder for each project in that category. The advantage is that to back up the repository I can deal with everything at one time. In addition, there are a few tricks to deal with the projects independently.&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:georgia;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For example, to view the history only affecting files associated with a certain project, list that project's subdirectory after the "log" command:&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;hg log /projects/school/project1&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:georgia;"&gt;It is also possible to clone only part of the repository (eg, a particular project), and merge it back in using the &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/ConvertExtension"&gt;ConvertExtension&lt;/a&gt;. You must create a temporary file that includes the path of the files you would like to extract. For example, you would create a file &lt;span style="color: rgb(153, 153, 153);"&gt;testconvertmap.txt &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(153, 153, 153);"&gt;that contains the text:&lt;/span&gt;&lt;span style="color: rgb(153, 153, 153);"&gt; &lt;/span&gt;&lt;span style="color: rgb(153, 153, 153);"&gt;include "school/project1".  &lt;span style="color: rgb(0, 0, 0);"&gt;Then run the command:&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;hg convert --filemap testconvertmap.txt /projects /subproject&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The new folder "subproject" will contain the subset of the repository with all the files in the directory that you specified, with full history concerning those files. This is useful for testing a feature in a particular project, or providing someone with only the part of the repository they need. You can merge your changes back into the main repository, however depending on the nature of the repository and the changes you may need to employ the method outlined in &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/MergingUnrelatedRepositories"&gt;Merging Unrelated Repositories&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 204, 51);"&gt;Multiple Repositories&lt;/span&gt;&lt;br /&gt;The advantage to this method is that each project is actually independent. No special methods are needed to clone a project to test a new feature or only extract the information for a particular project. However if you later want to combine two projects (eg, they are closely related), you will need to employ the method in the Merging Unrelated Repositories document mentioned in the previous section.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 204, 51);"&gt;Multiple Repositories with the ForestExtension&lt;/span&gt;&lt;br /&gt;I have not used this extensively, I have a small group of test repositories in a "forest". However, at least conceptually, this seems to be the most convenient method for handling multiple projects. Each project is in its own repository, so cloning individual projects is just as easy as with the &lt;span style="color: rgb(204, 204, 204);"&gt;Multiple Repositories&lt;/span&gt; method. However, all of these repositories are in one larger repository. The &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/ForestExtension"&gt;ForestExtension&lt;/a&gt; provides commands to operate on all of the repositories at once, such as &lt;span style="font-family:courier new;"&gt;fpull, fpush, fupdate, fstatus, &lt;span style="font-family:georgia;"&gt;etc. This makes backups and bundling of all the repositories similar to the &lt;span style="color: rgb(204, 204, 204);"&gt;Single Repository&lt;/span&gt; method. There is also a recommendation to include the functionality of this extension into the core of Mercurial with &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/NestedRepositories"&gt;NestedRepositories&lt;/a&gt;. I will be working with this method more in the future and will expand on it when I know more.&lt;br /&gt;&lt;br /&gt;Each of these methods has advantages and disadvantages, just like anything else. I would recommend trying each with a small number of projects to see which you prefer, then employ that for all of your projects. Since it is possible to convert between them, whichever you choose is not set in stone.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-6458887162157750114?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/6458887162157750114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/6458887162157750114'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/05/managing-multiple-repositories-with.html' title='Managing Multiple Repositories with Mercurial'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-4353444731296074431</id><published>2008-05-08T21:01:00.007-04:00</published><updated>2008-05-08T21:12:01.595-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><title type='text'>Reviews of Distributed Revision Control: Mercurial</title><content type='html'>First up on the reviews of distributed revision control systems (DRCS) is &lt;a href="http://www.selenic.com/mercurial"&gt;Mercurial&lt;/a&gt;. This, along with &lt;a href="http://git.or.cz/"&gt;Git&lt;/a&gt;, is one of the revision control systems that came out of the big &lt;a href="http://en.wikipedia.org/wiki/Bitkeeper"&gt;Bitkeeper Debacle of 2005&lt;/a&gt; (believe it or not, I did not come up with that name, and I’m sure it’s trademarked). Long story short, &lt;a href="http://www.bitkeeper.com/"&gt;Bitkeeper&lt;/a&gt; was the versioning system used by the Linux Kernel developers until Larry McVoy (the CEO of Bitmover) decided to take away the free license. Of course there is much more to the story, but you can read up on that on your own if you care.&lt;br /&gt;&lt;br /&gt;Anyway, Mercurial is written in Python with the exception of a few core routines written in C. The command line user interface is very well designed. The commands are intuitive and relatively easy to get used to, especially if you are familiar with &lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt; or &lt;a href="http://www.nongnu.org/cvs/"&gt;CVS &lt;/a&gt;(If you are still using CVS, you should probably upgrade. Seriously.) Mercurial's output is customizable, making it perfect for scripting. However if you prefer a GUI, &lt;a href="http://www.selenic.com/mercurial/wiki/index.cgi/OtherTools"&gt;there are some available&lt;/a&gt;. The classic repository features (such as hooks and permissions) are all there, and it scales well for large projects. Mercurial is used by projects such as &lt;a href="http://www.netbeans.org/"&gt;NetBeans&lt;/a&gt;, &lt;a href="http://www.mozilla.org/"&gt;Mozilla&lt;/a&gt;, and &lt;a href="http://opensolaris.org/index.html"&gt;OpenSolaris&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;My personal experiences with Mercurial have all been pleasant. It has worked well for small/medium projects, both with me being the only developer and with a few more people contributing to the repository. I have also used Mercurial to manage some patches on top of the Linux Kernel with a great deal of success. Having patch management built on top of the revision control system is incredibly convenient. Just try it.&lt;br /&gt;&lt;br /&gt;Stay tuned for the next review, Git.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-4353444731296074431?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/4353444731296074431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/4353444731296074431'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/05/reviews-of-distributed-revision-control_08.html' title='Reviews of Distributed Revision Control: Mercurial'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-1985249919140555624</id><published>2008-05-06T22:31:00.008-04:00</published><updated>2008-06-15T11:09:53.620-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Version Control'/><title type='text'>Reviews of Distributed Revision Control Systems</title><content type='html'>&lt;p class="MsoNormal"&gt;I know many people involved with software development have at least heard of &lt;span style="font-weight: bold;"&gt;distributed revision control (DRC),&lt;/span&gt; but there are still many that have not. In this series of articles I attempt to summarize the differences between distributed revision control and &lt;span style="font-weight: bold;"&gt;traditional centralized revision control &lt;/span&gt;while comparing different distributed revision control systems; namely  the open source applications &lt;a href="http://www.selenic.com/mercurial/wiki/"&gt;Mercurial&lt;/a&gt;, &lt;a href="http://git.or.cz/"&gt;Git&lt;/a&gt;, &lt;a href="http://bazaar-vcs.org/"&gt;Bazaar&lt;/a&gt;, and &lt;a href="http://darcs.net/"&gt;darcs&lt;/a&gt;.&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Alright, alright, CALM DOWN. I apologize if your favorite application is not on the list, but I am going for quality over quantity, and these are the four systems I have used extensively. There are many others as well. &lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt; and &lt;a href="http://www.perforce.com/"&gt;Perforce&lt;/a&gt; will be the centralized revision control systems that I use for reference.&lt;/p&gt;      &lt;p class="MsoNormal"&gt;For a more in-depth description of distributed revision control in general, &lt;a href="http://betterexplained.com/articles/intro-to-distributed-version-control-illustrated/"&gt;check out this introduction&lt;/a&gt;, or &lt;a href="http://video.google.com/videoplay?docid=-2199332044603874737&amp;amp;ei=1hUhSNz0GI6IrQKog7m2Ag&amp;amp;hl=en"&gt;this talk by Linus Torvalds&lt;/a&gt; (Warning: His views are &lt;span style="font-weight: bold;"&gt;very&lt;/span&gt; one-sided, so do not take it personally if he bashes your favorite revision control system).&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Stay tuned for the first review: &lt;span style="font-weight: bold; font-style: italic;"&gt;Mercurial&lt;/span&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-1985249919140555624?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/1985249919140555624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/1985249919140555624'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/05/reviews-of-distributed-revision-control.html' title='Reviews of Distributed Revision Control Systems'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-5542443203877397847</id><published>2008-04-27T00:58:00.006-04:00</published><updated>2008-04-27T01:14:23.550-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Design'/><title type='text'>Software Design Patterns: Observer Pattern</title><content type='html'>&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;I learned about the &lt;span style="font-weight: bold;"&gt;Observer&lt;/span&gt; (also known as Subscriber) pattern near the beginning of this semester in my Software Design Methods class, and had the same thoughts that I’m sure most people have when they first learn about it; “Oh, that could be useful”. Then I went right back to pretending I was out fishing somewhere, and not in class.&lt;/p&gt;    &lt;p class="MsoNormal"&gt;Recently I’ve actually begin to use the Observer pattern in a project, and it has been very helpful. Some of you may be thinking that I am making stuff up, “fabricating” as it were, that there never was such a thing as the Observer pattern. HA!&lt;span style=""&gt;  &lt;/span&gt;Got You!&lt;/p&gt;    &lt;p class="MsoNormal"&gt;Just kidding, it is an extremely useful pattern, most notably for interaction between the core functionality layer of an application and the UI layer (be it a GUI &lt;span style="font-style: italic;"&gt;Graphical User Interface&lt;/span&gt; or CLI &lt;span style="font-style: italic;"&gt;Command Line Interface&lt;/span&gt;). For those of you who do not know what the Observer pattern is, I’ll explain it briefly. Various objects “subscribe” to other objects that broadcast some type of information.&lt;/p&gt;    &lt;p class="MsoNormal"&gt;For example, let’s say that you are object A, and object B is a website that offers a weekly e-mail newsletter. You subscribe to object B, aka the website, because the newsletter sounded interesting at the time (We've all done it). After subscribing, you, along with everyone else who is subscribed, receive a weekly copy of the newsletter. After a few weeks you decide that the newsletter is an abomination and a waste of time and unsubscribe. The next week you do not receive an e-mail, but everyone who is still subscribed does. This pattern allows information to be sent to whichever objects declare that they would like to receive it, thus allowing a great amount of flexibility for future changes.&lt;/p&gt;    &lt;p class="MsoNormal"&gt;While the project I’m referring to only has a rudimentary GUI, I’m using the observer pattern to facilitate showing updated information. I am only familiar with the implementation of this pattern with Java using interfaces, but I imagine it is trivial to use an inherited class as well. Here is a more detailed example using interfaces: &lt;/p&gt;      &lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;A&lt;/span&gt; is an integer counting the number of words in the text file&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;B&lt;/span&gt; is a GUI widget in the status bar that displays the number of words in the text file&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;B&lt;/span&gt; implements the “Observer” interface, implementing a method such “getUpdate()”, allowing objects it is subscribed to send it new information.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;A&lt;/span&gt; implements the “Observed” interface, implemented methods such as register(), and unRegister() for subscribing and unsubscribing objects. These methods both take in references to Observer objects as arguments. There should also be a method for sending the update to all the observers.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;A&lt;/span&gt; has an internal list of references to Observer objects that are its subscribers. &lt;/li&gt;&lt;/ul&gt;        &lt;p class="MsoNormal"&gt;To allow the status bar (B) to receive the word count updates, implement a simple &lt;span style="font-weight: bold;"&gt;Observer&lt;/span&gt; interface with a function that knows how to handle update information. In the current example, it may be &lt;span style="color: rgb(51, 51, 255);"&gt;getUpdate(int wordCount)&lt;/span&gt;. Implement a simple &lt;span style="font-weight: bold;"&gt;Observed&lt;/span&gt; interface in A with functions to register/subscribe and unregister/unsubscribe Observers. For example, &lt;span style="color: rgb(51, 51, 255);"&gt;register(Observer newObserver)&lt;/span&gt;, &lt;span style="color: rgb(51, 51, 255);"&gt;unRegister(Observer newObserver)&lt;/span&gt;. You will also need a function to send the update to all the observers. It should basically just iterate through the list of observers, calling the getUpdate() function of each with the proper arguments. It could be called something like &lt;span style="color: rgb(51, 51, 255);"&gt;sendUpdates()&lt;/span&gt;.&lt;br /&gt;&lt;/p&gt;      &lt;p class="MsoNormal"&gt;The main program may look something like this:&lt;br /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;        &lt;p style="color: rgb(255, 255, 255);" class="MsoNormal"&gt;Observed A;&lt;br /&gt;Observer B;&lt;br /&gt;A.register(B); //Register the observer&lt;br /&gt;A.sendUpdates(); //Update all the observers&lt;br /&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;I realize that this is a very generic example, but I hope it conveys the general idea. The beauty of this pattern is that if at a later time you need another widget to monitor the word count, you just need to implement the Observer interface and call the appropriate functions. There is minimal modification to code that you have already written and tested.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;I encourage you to try this out, you’ll thank yourself later.&lt;/p&gt;    &lt;p style="font-family: arial;" class="MsoNormal"&gt;Two excellent books about design patterns in general:&lt;br /&gt;&lt;a style="font-family: arial;" href="http://www.amazon.com/Applying-UML-Patterns-Introduction-Object-Oriented/dp/0131489062/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1209272285&amp;amp;sr=8-1"&gt;Applying UML and Patterns&lt;/a&gt;&lt;a href="http://www.amazon.com/Head-First-Design-Patterns/dp/0596007124/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1209272160&amp;amp;sr=8-1"&gt;&lt;br /&gt;Design Patterns (Head First)&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-5542443203877397847?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/5542443203877397847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/5542443203877397847'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/04/software-design-patterns-observer.html' title='Software Design Patterns: Observer Pattern'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-6261785114078307064</id><published>2008-04-19T01:56:00.005-04:00</published><updated>2008-04-19T02:26:02.727-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Ext2 Gotchas (Directory Entry Size)</title><content type='html'>&lt;p class="MsoNormal" style="text-indent: 0.5in;"&gt;Recently in my Operating Systems Concepts class, one of our projects involved reading in an &lt;a href="http://en.wikipedia.org/wiki/Ext2"&gt;ext2 filesystem&lt;/a&gt; and listing the contents of the root directory. For anyone who is familiar with filesystem programming, yes, you can go ahead and laugh at the simplicity of this project.&lt;br /&gt;Seriously, go ahead, I'll wait.&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;            &lt;/span&gt;However, there is one aspect of the ext2 filesystem that was extremely difficult to track down: &lt;b style=""&gt;the size of a directory entry must be a multiple of four (4)&lt;/b&gt;. This makes sense for efficiency reasons, however people familiar with this filesystem seems to take this for granted when writing descriptions and make no mention of it. The directory entry structure is defined as a struct in C with the following items:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;!--[if !supportLists]--&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;Inode Number &lt;i style=""&gt;(4 bytes)&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;!--[if !supportLists]--&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;Length of this entry &lt;i style=""&gt;(2 bytes)&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;!--[if !supportLists]--&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;Length of file name &lt;i style=""&gt;(1 byte)&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;!--[if !supportLists]--&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;File Type (1 =&gt; File, 2=&gt; Directory) &lt;i style=""&gt;(1 byte)&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;!--[if !supportLists]--&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;The file name &lt;i style=""&gt;(? Bytes)&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;          &lt;p class="MsoNormal" style="text-indent: 0.4in;"&gt;The reason the size is variable in practice is due to the variable lengths of file names. If the length of the name is not a multiple of four, extra bytes are tacked on the end to even it out. For example, take the link present in every directory pointing to its parent. The name of this link is &lt;span style="font-style: italic;"&gt;“..”&lt;/span&gt;, causing the size of the directory entry structure to be 10 (4 + 2 + 1 + 1 + 2). Two null bytes are added to the end of the name giving the structure an appropriate size of 12.&lt;/p&gt;  &lt;p class="MsoNormal" style="text-indent: 0.4in;"&gt;I finally figured out the answer after looking at different systems with a hex editor, and then got a hold of the book &lt;a href="http://www.oreilly.com/catalog/linuxkernel/"&gt;&lt;i style=""&gt;Understanding the Linux Kernel&lt;/i&gt; &lt;/a&gt;by Bovet and Cesati, which was invaluable. (It is also available online at &lt;a href="http://books.google.com/books?id=cbbMrRNiC4cC&amp;amp;dq=understanding+the+linux+kernel&amp;amp;pg=PP1&amp;amp;ots=TvSgbZmf1d&amp;amp;sig=e5kq0dGVeWQ6oD5dslf92b99KGM&amp;amp;hl=en&amp;amp;prev=http://www.google.com/search?hl=en&amp;amp;q=Understanding+the+linux+kernel&amp;amp;btnG=Google+Search&amp;amp;sa=X&amp;amp;oi=print&amp;amp;ct=title&amp;amp;cad=one-book-with-thumbnail"&gt;Google books&lt;/a&gt;.) So if you ever find yourself writing a tool for dealing with ext2 or ext3 filesystems and cannot use the existing functions for whatever reason, keep this is mind.&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: 0.4in;"&gt;On another note, &lt;a href="http://homepage.smc.edu/morgan_david/cs40/analyze-ext2.htm"&gt;here is another resource&lt;/a&gt; that was very helpful when doing this project. It is a great in-depth introduction to the ext2 filesystem for those who are not familiar with filesystems in general.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-6261785114078307064?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/6261785114078307064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/6261785114078307064'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/04/ext2-gothas-directory-entry-size.html' title='Ext2 Gotchas (Directory Entry Size)'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4137570364011598202.post-2228595722644427879</id><published>2008-04-18T23:46:00.000-04:00</published><updated>2008-04-19T00:11:12.614-04:00</updated><title type='text'>The Beginning (Always has to be somewhere)</title><content type='html'>I'm starting this for the same reasons that many other people start blogs. Or so I imagine.&lt;br /&gt;I have quite a few projects I would like to get started on and with the semester ending in a few weeks I will finally have the time to actually do them. Writing about them here will hopefully help motivate me to keep with them until completion.&lt;br /&gt;&lt;br /&gt;I will probably write about other programming, software design, and general technology topics as well as time goes on. I'll just have to see how it goes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4137570364011598202-2228595722644427879?l=lazymalloc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/2228595722644427879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4137570364011598202/posts/default/2228595722644427879'/><link rel='alternate' type='text/html' href='http://lazymalloc.blogspot.com/2008/04/beginning-always-has-to-be-somewhere.html' title='The Beginning (Always has to be somewhere)'/><author><name>cheeseofsteel</name><uri>http://www.blogger.com/profile/16330370944920010120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry></feed>
