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

<channel>
	<title>tlrobinson.net / blog &#187; Mac</title>
	<atom:link href="http://tlrobinson.net/blog/category/mac/feed/" rel="self" type="application/rss+xml" />
	<link>http://tlrobinson.net/blog</link>
	<description></description>
	<lastBuildDate>Mon, 06 Apr 2009 08:37:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='tlrobinson.net' port='80' path='/blog/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>ropen: Remote &#8220;open&#8221; command for opening remote files locally on OS X</title>
		<link>http://tlrobinson.net/blog/2009/04/04/ropen-remote-open-command/</link>
		<comments>http://tlrobinson.net/blog/2009/04/04/ropen-remote-open-command/#comments</comments>
		<pubDate>Sun, 05 Apr 2009 04:40:15 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Command line]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://tlrobinson.net/blog/?p=94</guid>
		<description><![CDATA[The Problem

Most Mac OS X power users know about the &#8220;open&#8221; command line tool which opens the files specified as arguments in their default (or a specified) OS X application. Additionally, many OS X text editors, such as TextMate (&#8221;mate&#8221;) and SubEthaEdit (&#8221;see&#8221;), come with command line tools which can be used to open files.

These [...]]]></description>
			<content:encoded><![CDATA[<h2>The Problem</h2>

<p>Most Mac OS X power users know about the <a href="http://tuvix.apple.com/documentation/Darwin/Reference/ManPages/man1/open.1.html">&#8220;open&#8221;</a> command line tool which opens the files specified as arguments in their default (or a specified) OS X application. Additionally, many OS X text editors, such as TextMate (&#8221;mate&#8221;) and SubEthaEdit (&#8221;see&#8221;), come with command line tools which can be used to open files.</p>

<p>These are great when working locally, but obviously do no work remotely. Often when working on remote servers you end up using command line editors which you may not be as familiar with.</p>

<h2>ropen&#8217;s Solution</h2>

<p>The <a href="http://github.com/tlrobinson/ropen">ropen</a> tool solves this problem using two simple shell scripts, which make use of MacFuse&#8217;s sshfs. You run the &#8220;ropen&#8221; program on your remote machine(s) when you want to open a remote file locally (this is equivalent to the OS X &#8220;open&#8221; command). The &#8220;ropend&#8221; daemon runs on your local OS X machine waiting for open requests, and the &#8220;ropen.php&#8221; PHP script proxies requests from ropen to ropend.</p>

<h2>How it works</h2>

<ol>
<li>When ropen is executed it makes an HTTP request to ropen.php with the paths to be opened and application to open them with, if any, as well as the SSH user, host, and port of the remote machine.</li>
<li>ropen.php stores this open request in a queue that is tied to ROPEN_SECRET via PHP&#8217;s sessions.</li>
<li>ropend polls ropen.php every 1 second waiting for open requests. When it receives one it mounts the remote filesystem using sshfs (if it&#8217;s not already mounted) and opens the files or directories specified.</li>
</ol>

<h2>More information</h2>

<p>See more information about ropen on the <a href="http://github.com/tlrobinson/ropen">ropen project page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tlrobinson.net/blog/2009/04/04/ropen-remote-open-command/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Determining the absolute absolute path of a shell script</title>
		<link>http://tlrobinson.net/blog/2009/03/30/determining-the-absolute-absolute-path-of-a-shell-script/</link>
		<comments>http://tlrobinson.net/blog/2009/03/30/determining-the-absolute-absolute-path-of-a-shell-script/#comments</comments>
		<pubDate>Mon, 30 Mar 2009 15:04:24 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Command line]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://tlrobinson.net/blog/?p=91</guid>
		<description><![CDATA[In the course of working on projects like server-side Objective-J, jack, and now narwhal, I&#8217;ve often had to write shell scripts that needed to know their location in the filesystem. Rather than hardcoding it, I prefer to infer it automatically at runtime. Unfortunately this isn&#8217;t as easy as you would expect.

If the script is invoked [...]]]></description>
			<content:encoded><![CDATA[<p>In the course of working on projects like server-side <a href="http://cappuccino.org">Objective-J</a>, <a href="http://jackjs.org">jack</a>, and now <a href="http://github.com/tlrobinson/narwhal">narwhal</a>, I&#8217;ve often had to write shell scripts that needed to know their location in the filesystem. Rather than hardcoding it, I prefer to infer it automatically at runtime. Unfortunately this isn&#8217;t as easy as you would expect.</p>

<p>If the script is invoked with an absolute path (&#8221;/foo/bar/baz&#8221;) or from your PATH (&#8221;baz&#8221;), then &#8220;$0&#8243; in the script will contain the absolute of the script (&#8221;/foo/bar/baz&#8221;). However, if it is invoked using a relative path (&#8221;./bar/baz&#8221; from &#8220;/foo&#8221;) then $0 will contain the relative path (&#8221;./bar/baz&#8221;). Furthermore, if the path to the script is actually a symbolic link, you&#8217;ll get the symlink&#8217;s path instead of the original.</p>

<p>Surprisingly, I couldn&#8217;t find a definitive solution that handles all these cases, so I took the various ones I did find and created one which I think handles all the cases I&#8217;m aware of:</p>

<script src="http://gist.github.com/87785.js"></script>

<p>If you don&#8217;t want to resolve the symlinks remove the second half.</p>
]]></content:encoded>
			<wfw:commentRss>http://tlrobinson.net/blog/2009/03/30/determining-the-absolute-absolute-path-of-a-shell-script/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>&#8220;Mark Old As Read&#8221; for NetNewsWire</title>
		<link>http://tlrobinson.net/blog/2008/11/13/mark-old-as-read-for-netnewswire/</link>
		<comments>http://tlrobinson.net/blog/2008/11/13/mark-old-as-read-for-netnewswire/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 01:58:28 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[AppleScript]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://tlrobinson.net/blog/?p=73</guid>
		<description><![CDATA[I recently heard about an RSS reader (can&#8217;t remember which) that had a feature to mark all messages older than a certain threshold as &#8220;read&#8221;. I thought this was an incredibly useful feature, since I often forget to check my feeds for days at a time, and end up with hundreds of unread items that [...]]]></description>
			<content:encoded><![CDATA[<p>I recently heard about an RSS reader (can&#8217;t remember which) that had a feature to mark all messages older than a certain threshold as &#8220;read&#8221;. I thought this was an incredibly useful feature, since I often forget to check my feeds for days at a time, and end up with hundreds of unread items that I don&#8217;t have time to read.</p>

<p>Luckily my current RSS reader, <a href="http://www.newsgator.com/INDIVIDUALS/NETNEWSWIRE/">NetNewsWire</a>, has AppleScript built in, so I whipped up this script that prompts for the number of days you want to keep as unread, and marks the rest as read.</p>

<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#0b0bff;">tell</span> <span style="color:#0b0bff;">application</span> &quot;NetNewsWire&quot;<br />
&nbsp;&nbsp;&nbsp;&nbsp;display dialog &quot;How many days old to mark read?&quot; default answer &quot;7&quot;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#0b0bff;">set</span> numDays <span style="color:#0b0bff;">to</span> text returned <span style="color:#0b0bff;">of</span> <span style="color:#0b0bff;">result</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#0b0bff;">set</span> threshold <span style="color:#0b0bff;">to</span> (current date) &#8211; (numDays * <span style="color:#0b0bff;">days</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#0b0bff;">set</span> isRead <span style="color:#0b0bff;">of</span> (headlines <span style="color:#0b0bff;">of</span> subscriptions <span style="color:#0b0bff;">where</span> (isRead <span style="color:#0b0bff;">is</span> <span style="color:#0b0bff;">equal</span> <span style="color:#0b0bff;">to</span> <span style="color:#0b0bff;">false</span> <span style="color:#0b0bff;">and</span> date published &lt; threshold)) <span style="color:#0b0bff;">to</span> <span style="color:#0b0bff;">true</span><br />
<span style="color:#0b0bff;">end</span> <span style="color:#0b0bff;">tell</span></div>
]]></content:encoded>
			<wfw:commentRss>http://tlrobinson.net/blog/2008/11/13/mark-old-as-read-for-netnewswire/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Open new Terminal tab in current directory (updated!)</title>
		<link>http://tlrobinson.net/blog/2008/10/23/open-new-terminal-tab/</link>
		<comments>http://tlrobinson.net/blog/2008/10/23/open-new-terminal-tab/#comments</comments>
		<pubDate>Thu, 23 Oct 2008 08:47:16 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Command line]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://tlrobinson.net/blog/?p=68</guid>
		<description><![CDATA[This is an updated shell script / AppleScript for opening a new tab in your current directory (or the specified directory). The last version was for the pre-tabbed version of Terminal.

#!/bin/sh -

if [ $# -ne 1 ]; then
&#160;&#160;&#160;&#160;PATHDIR=`pwd`
else
&#160;&#160;&#160;&#160;PATHDIR=$1
fi

/usr/bin/osascript &#60;&#60;-EOF
activate application &#34;Terminal&#34;
tell application &#34;System Events&#34;
&#160;&#160;&#160;&#160;keystroke &#34;t&#34; using {command down}
end tell
tell application &#34;Terminal&#34;
&#160;&#160;&#160;&#160;repeat with win in windows
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;try
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if [...]]]></description>
			<content:encoded><![CDATA[<p>This is an updated shell script / AppleScript for opening a new <em>tab</em> in your current directory (or the specified directory). The <a href="http://tlrobinson.net/blog/2007/09/07/open-new-terminal-window-in-current-or-other-specified-directory/">last version</a> was for the pre-tabbed version of Terminal.</p>

<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#236e25;">#!/bin/sh -<br />
</span><br />
<span style="color:#881350;">if</span> [ <span style="color:#c4620a;">$#</span> -ne <span style="color:#0000ff;">1</span> ]; <span style="color:#881350;">then</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;PATHDIR=<span style="color:#660088;">`pwd`</span><br />
<span style="color:#881350;">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;PATHDIR=<span style="color:#c4620a;">$1</span><br />
<span style="color:#881350;">fi</span><br />
<br />
/usr/bin/osascript &lt;&lt;-EOF<br />
activate application <span style="color:#760f15;">&quot;Terminal&quot;</span><br />
tell application <span style="color:#760f15;">&quot;System Events&quot;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;keystroke <span style="color:#760f15;">&quot;t&quot;</span> using {<span style="color:#440088;">command</span> down}<br />
end tell<br />
tell application <span style="color:#760f15;">&quot;Terminal&quot;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;repeat with win <span style="color:#881350;">in</span> windows<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span> get frontmost of win is <span style="color:#880088;">true</span> <span style="color:#881350;">then</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">do</span> script <span style="color:#760f15;">&quot;cd </span><span style="color:#c4620a;">$PATHDIR</span><span style="color:#760f15;">; clear&quot;</span> <span style="color:#881350;">in</span><span style="color:#003369;"> </span>(selected tab of win)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end <span style="color:#881350;">if</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end try<br />
&nbsp;&nbsp;&nbsp;&nbsp;end repeat<br />
end tell<br />
EOF<br />
</div>
]]></content:encoded>
			<wfw:commentRss>http://tlrobinson.net/blog/2008/10/23/open-new-terminal-tab/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Command line interpreter and REPL for JSCocoa</title>
		<link>http://tlrobinson.net/blog/2008/10/10/command-line-interpreter-and-repl-for-jscocoa/</link>
		<comments>http://tlrobinson.net/blog/2008/10/10/command-line-interpreter-and-repl-for-jscocoa/#comments</comments>
		<pubDate>Fri, 10 Oct 2008 10:08:07 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Command line]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://tlrobinson.net/blog/?p=55</guid>
		<description><![CDATA[A few months ago I started working on a JavaScript to Objective-C bridge. We had already implemented Objective-C in JavaScript, so I figured &#8220;why not?&#8221;

Well, I never got very far, but thankfully Patrick Geiller apparently had the same idea and actually executed it: He announced JSCocoa today. It looks like it&#8217;s a solid bridge, about [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago I started working on a JavaScript to Objective-C bridge. We had already <a href="http://cappuccino.org">implemented Objective-C in JavaScript</a>, so I figured &#8220;why not?&#8221;</p>

<p>Well, I never got very far, but thankfully <a href="http://parmanoir.com/">Patrick Geiller</a> apparently had the same idea and actually executed it: He <a href="http://parmanoir.com/JSCocoa%2C_a_bridge_from_Javascript_to_Cocoa">announced</a> <a href="http://inexdo.com/JSCocoa">JSCocoa</a> today. It looks like it&#8217;s a solid bridge, about up to par with <a href="http://pyobjc.sourceforge.net/">PyObjC</a> and <a href="http://rubycocoa.sourceforge.net/">RubyCocoa</a>.</p>

<p>While the included GUI interface for trying out JSCocoa is nice, I prefer command line interfaces for my languages, so I ripped out the few lines of code from my original bridge and plugged in JSCocoa.</p>

<p><a href="http://github.com/tlrobinson/tlrobinson/tree/master/jscocoa">Code and build instructions on GitHub</a>.</p>

<p>It&#8217;s very bare bones at the moment: it will either read one or more file names from the command line arguments, or if no arguments are supplied it will present a no-frills REPL. Obviously line-editing, etc would be one of the next steps, but for now it works nicely with <a href="http://http://tlrobinson.net/blog/?p=32">rlwrap</a>.</p>

<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#683821;">#import &lt;Foundation/Foundation.h&gt;<br />
#import &quot;JSCocoaController.h&quot;<br />
</span><br />
<span style="color:#881350;">void</span> <span style="color:#003369;">JSValuePrint</span>(JSContextRef, JSValueRef, JSValueRef *);<br />
<br />
<span style="color:#881350;">int</span> <span style="color:#003369;">main </span>(<span style="color:#881350;">int</span> argc, <span style="color:#881350;">const</span> <span style="color:#881350;">char</span> * argv[])<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;[[<span style="color:#400080;">NSAutoreleasePool</span> <span style="color:#ff0000;">alloc</span>] <span style="color:#6c0540;">init</span>];<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">id</span> c = [JSCocoaController <span style="color:#6c0540;">sharedController</span>];<br />
&nbsp;&nbsp;&nbsp;&nbsp;JSGlobalContextRef ctx = [c <span style="color:#6c0540;">ctx</span>];<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(argc &gt; <span style="color:#0000ff;">1</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">for</span><span style="color:#003369;"> </span>(<span style="color:#881350;">int</span> i = <span style="color:#0000ff;">1</span>; i &lt; argc; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[c <span style="color:#6c0540;">evalJSFile:</span>[<span style="color:#400080;">NSString</span> <span style="color:#6c0540;">stringWithFormat:</span><span style="color:#760f15;">@&quot;%s&quot;</span>, argv[i]]];<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">while</span><span style="color:#003369;"> </span>(<span style="color:#0000ff;">1</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">char</span> buffer[<span style="color:#0000ff;">1024</span>];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">printf</span>(<span style="color:#760f15;">&quot;js&gt; &quot;</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(<span style="color:#003369;">fgets</span>(buffer, <span style="color:#0000ff;">1024</span>, stdin) == <span style="color:#881350;">NULL</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">exit</span>(<span style="color:#0000ff;">0</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JSStringRef script = <span style="color:#003369;">JSStringCreateWithUTF8CString</span>(buffer);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JSValueRef exception = <span style="color:#881350;">NULL</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(<span style="color:#003369;">JSCheckScriptSyntax</span>(ctx, script, <span style="color:#0000ff;">0</span>, <span style="color:#0000ff;">0</span>, &amp;exception) &amp;&amp; !exception)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JSValueRef value = <span style="color:#003369;">JSEvaluateScript</span>(ctx, script, <span style="color:#0000ff;">0</span>, <span style="color:#0000ff;">0</span>, <span style="color:#0000ff;">0</span>, &amp;exception);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(exception)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">JSValuePrint</span>(ctx, exception, <span style="color:#881350;">NULL</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(value &amp;&amp; !<span style="color:#003369;">JSValueIsUndefined</span>(ctx, value))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">JSValuePrint</span>(ctx, value, &amp;exception);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">printf</span>(<span style="color:#760f15;">&quot;Syntax error\n&quot;</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">JSStringRelease</span>(script);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
<br />
<span style="color:#881350;">void</span> <span style="color:#003369;">JSValuePrint</span>(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JSContextRef ctx,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JSValueRef value,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JSValueRef *exception)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;JSStringRef string = <span style="color:#003369;">JSValueToStringCopy</span>(ctx, value, exception);<br />
&nbsp;&nbsp;&nbsp;&nbsp;size_t length = <span style="color:#003369;">JSStringGetLength</span>(string);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">char</span> *buffer = <span style="color:#003369;">malloc</span>(length+<span style="color:#0000ff;">1</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">JSStringGetUTF8CString</span>(string, buffer, length+<span style="color:#0000ff;">1</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">JSStringRelease</span>(string);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">puts</span>(buffer);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">free</span>(buffer);<br />
}</div>
]]></content:encoded>
			<wfw:commentRss>http://tlrobinson.net/blog/2008/10/10/command-line-interpreter-and-repl-for-jscocoa/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Useful Mac OS X-specific command line utilities</title>
		<link>http://tlrobinson.net/blog/2008/07/25/useful-mac-os-x-specific-command-line-utilities/</link>
		<comments>http://tlrobinson.net/blog/2008/07/25/useful-mac-os-x-specific-command-line-utilities/#comments</comments>
		<pubDate>Sat, 26 Jul 2008 01:31:16 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Command line]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://tlrobinson.net/blog/?p=45</guid>
		<description><![CDATA[One of the greatest strengths of Mac OS X, for developers in particular, is that it has a very elegant and consistent graphical user interface as well as an excellent command line interface. I&#8217;m not going to cover the basics like &#8220;ls&#8221; and &#8220;cd&#8221;, but rather point out some Mac OS X specific tools that [...]]]></description>
			<content:encoded><![CDATA[<p>One of the greatest strengths of Mac OS X, for developers in particular, is that it has a very elegant and consistent graphical user interface as well as an excellent command line interface. I&#8217;m not going to cover the basics like &#8220;ls&#8221; and &#8220;cd&#8221;, but rather point out some Mac OS X specific tools that are less well known than they should be.</p>

<p>Many of these are the command line equivalents for the GUI versions available in OS X. Combining them with other command line tools can be very powerful and huge time savers. See the &#8220;man&#8221; pages for more details of each.</p>

<p><strong>open</strong> &#8211; Opens a file, application, or directory in GUI-land. Very useful.</p>

<p><strong>screencapture</strong> &#8211; Take a screenshot. Exactly the same as <command><shift> 3 or <command><shift> 4 (or even <command><shift> 4 then <space>) plus more.</p>

<p><strong>say</strong> &#8211; Text to speech. Give it a file name, string of text, or pipe the output of another program to it. Options for difference voices, 
saving the result to a file, etc. Fun hobby: ssh into a computer being used by someone else and start speaking to them using &#8220;say&#8221;.</p>

<p><strong>pbcopy</strong> and <strong>pbpaste</strong> &#8211; Copy and paste to/from the OS X pasteboard.</p>

<p><strong>srm</strong> &#8211; Secure &#8220;rm&#8221;. Like &#8220;rm&#8221; but overwrites deleted data. &#8220;-m&#8221; gives you DoD compliant erasing!</p>

<p><strong>osascript</strong> &#8211; Run AppleScripts (or other OSA languages) from the command line. (I use this in the &#8220;<a href="http://tlrobinson.net/blog/?p=26">term</a>&#8221; script)</p>

<p><strong>hdiutil</strong> &#8211; create and open disk images (.dmg)</p>

<p><strong>defaults</strong> &#8211; view and set various hidden settings. Check out <a href="http://www.macosxhints.com/">macosxhints.com</a> for some of these.</p>

<p>These are just a few Mac OS X specific commands I found most useful. Amit Singh has a <a href="http://www.kernelthread.com/mac/osx/tools.html">fairly comprehensive list</a> over at his excellent <a href="http://www.kernelthread.com/">kernelthread.com</a> website.</p>
]]></content:encoded>
			<wfw:commentRss>http://tlrobinson.net/blog/2008/07/25/useful-mac-os-x-specific-command-line-utilities/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Mac OS X, Web Sharing / Apache, and Symlinks</title>
		<link>http://tlrobinson.net/blog/2008/06/25/mac-os-x-web-sharing-apache-and-symlinks/</link>
		<comments>http://tlrobinson.net/blog/2008/06/25/mac-os-x-web-sharing-apache-and-symlinks/#comments</comments>
		<pubDate>Wed, 25 Jun 2008 23:29:04 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://tlrobinson.net/blog/?p=40</guid>
		<description><![CDATA[Mac OS X comes with an Apache installation which is very handy, but by default it&#8217;s configured not to follow symlinks. A lot of times I have projects in other directories which I want to share via the web server, but end up getting errors such as the following:

Forbidden

You don't have permission to access /~tlrobinson/Editor/ [...]]]></description>
			<content:encoded><![CDATA[<p>Mac OS X comes with an Apache installation which is very handy, but by default it&#8217;s configured not to follow symlinks. A lot of times I have projects in other directories which I want to share via the web server, but end up getting errors such as the following:</p>

<pre><code>Forbidden

You don't have permission to access /~tlrobinson/Editor/ on this server.
</code></pre>

<p>And in the error log file:</p>

<pre><code>[Wed Jun 25 16:17:14 2008] [error] [client ::1] Symbolic link not allowed or link target not accessible: /Users/tlrobinson/Sites/Editor
</code></pre>

<p>To enable following of symlinks, edit your account&#8217;s configure file located at /private/etc/apache2/users/<i>username</i>.conf</p>

<p>Here&#8217;s the default:</p>

<pre><code>&lt;Directory "/Users/tlrobinson/Sites/"&gt;
    Options Indexes MultiViews
    AllowOverride None
    Order allow,deny
    Allow from all
&lt;/Directory&gt;
</code></pre>

<p>You can either add &#8220;FollowSymLinks&#8221; to the Options directive (&#8221;Options Indexes MultiViews FollowSymLinks&#8221;), or change the AllowOverride directive to &#8220;All&#8221; (&#8221;AllowOverride None&#8221;) <b>and</b> place a .htaccess with it&#8217;s own Options directive (&#8221;Options FollowSymLinks&#8221;) in your Sites directory.</p>

<p>Then just restart Apache (&#8221;sudo apachectl graceful&#8221;) and symlinks should work.</p>
]]></content:encoded>
			<wfw:commentRss>http://tlrobinson.net/blog/2008/06/25/mac-os-x-web-sharing-apache-and-symlinks/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Overriding library functions in Mac OS X, the easy way: DYLD_INSERT_LIBRARIES</title>
		<link>http://tlrobinson.net/blog/2007/12/21/overriding-library-functions-in-mac-os-x-the-easy-way-dyld_insert_libraries/</link>
		<comments>http://tlrobinson.net/blog/2007/12/21/overriding-library-functions-in-mac-os-x-the-easy-way-dyld_insert_libraries/#comments</comments>
		<pubDate>Fri, 21 Dec 2007 09:31:19 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[GCC]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://tlrobinson.net/blog/?p=30</guid>
		<description><![CDATA[Back at MacHack 2003 Jonathan Rentzsch talked about how to override functions and inject code in Mac OS X using several neat tricks. He also released a framework called mach_star which has two components: mach_override and mach_inject. These are great, but overkill for some simple cases.

A much easier way of doing library function overrides is [...]]]></description>
			<content:encoded><![CDATA[<p>Back at MacHack 2003 Jonathan Rentzsch talked about how to override functions and inject code in Mac OS X using <a href="http://rentzsch.com/papers/overridingMacOSX">several neat tricks</a>. He also released a framework called <a href="http://rentzsch.com/mach_star/">mach_star</a> which has two components: mach_override and mach_inject. These are great, but overkill for some simple cases.</p>

<p>A much easier way of doing library function overrides is using the DYLD_INSERT_LIBRARIES environment variable (analogous to LD_PRELOAD on Linux). The concept is simple: at load time the dynamic linker (dyld) will load any dynamic libraries specified in DYLD_INSERT_LIBRARIES before any libraries the executable wants loaded. By naming a function the same as one in a library function it will override any calls to the original.</p>

<p>The original function is also loaded, and can be retrieved using the dlsym(RTLD_NEXT, &#8220;function_name&#8221;); function. This allows a simple method of wrapping existing library functions.</p>

<p>Here&#8217;s a simple example which prints out the path of every file opened using the &#8220;fopen&#8221; function (lib_overrides.c):</p>

<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#683821;">#include &lt;stdio.h&gt;<br />
#include &lt;unistd.h&gt;<br />
#include &lt;dlfcn.h&gt;<br />
</span><br />
<span style="color:#236e25;">// for caching the original fopen implementation<br />
</span>FILE * (*original_fopen) (<span style="color:#881350;">const</span> <span style="color:#881350;">char</span> *, <span style="color:#881350;">const</span> <span style="color:#881350;">char</span> *) = <span style="color:#881350;">NULL</span>;<br />
<br />
<span style="color:#236e25;">// our fopen override implmentation<br />
</span>FILE * <span style="color:#003369;">fopen</span>(<span style="color:#881350;">const</span> <span style="color:#881350;">char</span> * filename, <span style="color:#881350;">const</span> <span style="color:#881350;">char</span> * mode)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// if we haven&#8217;t already, retrieve the original fopen implementation<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(!original_fopen)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;original_fopen = <span style="color:#003369;">dlsym</span>(RTLD_NEXT, <span style="color:#760f15;">&quot;fopen&quot;</span>);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// do our own processing; in this case just print the parameters<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">printf</span>(<span style="color:#760f15;">&quot;== fopen: {%s,%s} ==\n&quot;</span>, filename, mode);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// call the original fopen with the same arugments<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;FILE* f = <span style="color:#003369;">original_fopen</span>(filename, mode);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// return the result<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">return</span> f;<br />
}</div>

<p>And a simple test program (overrides_test.c):</p>

<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#683821;">#include &lt;stdio.h&gt;<br />
#include &lt;string.h&gt;<br />
</span><br />
<span style="color:#881350;">int</span> <span style="color:#003369;">main</span>(<span style="color:#881350;">int</span> argc, <span style="color:#881350;">char</span> <span style="color:#881350;">const</span> *argv[])<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">char</span> hello[] = <span style="color:#760f15;">&quot;hello world&quot;</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;FILE *fp = <span style="color:#003369;">fopen</span>(<span style="color:#760f15;">&quot;hello.txt&quot;</span>, <span style="color:#760f15;">&quot;w&quot;</span>);<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(fp) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">fwrite</span>(hello, <span style="color:#0000ff;">1</span>, <span style="color:#003369;">strlen</span>(hello), fp);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">fclose</span>(fp);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">return</span> <span style="color:#0000ff;">0</span>;<br />
}</div>

<p>Compiled and tested:</p>

<pre><code>tlrobinson$ gcc -Wall -o lib_overrides.dylib -dynamiclib lib_overrides.c
tlrobinson$ gcc -Wall -o overrides_test overrides_test.c
tlrobinson$ DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=lib_overrides.dylib overrides_test
== fopen: {hello.txt,w} ==
tlrobinson$
</code></pre>

<p>There are certainly scenarios far more interesting than this, though!</p>
]]></content:encoded>
			<wfw:commentRss>http://tlrobinson.net/blog/2007/12/21/overriding-library-functions-in-mac-os-x-the-easy-way-dyld_insert_libraries/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Presenting GCCalc: a horrible abuse of GCC</title>
		<link>http://tlrobinson.net/blog/2007/12/14/presenting-gccalc-a-horribly-awesome-abuse-of-gcc/</link>
		<comments>http://tlrobinson.net/blog/2007/12/14/presenting-gccalc-a-horribly-awesome-abuse-of-gcc/#comments</comments>
		<pubDate>Fri, 14 Dec 2007 09:02:29 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Command line]]></category>
		<category><![CDATA[GCC]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://tlrobinson.net/blog/?p=31</guid>
		<description><![CDATA[Following an interesting discussion on Reddit about first class functions in C, I was inspired to see what I could do with this new-found knowledge. The result is what I affectionately call &#8220;GCCalc&#8221;, for reasons that will become clear below.

GCCalc is a simple command line calculator, much like the common bc calculator on many Unix [...]]]></description>
			<content:encoded><![CDATA[<p>Following an <a href="http://programming.reddit.com/info/62v70/comments">interesting discussion on Reddit</a> about <a href="http://en.wikipedia.org/wiki/First-class_function">first class functions</a> in C, I was inspired to see what I could do with this new-found knowledge. The result is what I affectionately call &#8220;GCCalc&#8221;, for reasons that will become clear below.</p>

<p>GCCalc is a simple command line calculator, much like the common <a href="http://en.wikipedia.org/wiki/Bc_programming_language">bc</a> calculator on many Unix systems. It&#8217;s implementation, however, is <em>very</em> different than most calculators. While bc is said to have &#8220;C-like syntax&#8221;, GCCalc&#8217;s syntax <em>is</em> C. Whatever you enter on the command line automatically gets compiled, loaded, and executed, and the result is returned (as a double) and printed to the screen.</p>

<p>You can either enter expressions like:</p>

<pre><code>round(46.95886*sqrt(1+2/9.99*sin((21%5)*pow(2,8))))
</code></pre>

<p>or you can enter whole C statements (as long as they&#8217;re on one line, for now) like:</p>

<pre><code> int i; for (i=0;i&lt;10;i++) { printf("hello world!\n"); } printf("goodbye\n");
</code></pre>

<p>Unfortunately variables are scoped to the function that wraps them, so they don&#8217;t persist across multiple entries. However, you can access the last result using the &#8220;last&#8221; variable (a double).</p>

<p><a href="http://tlrobinson.net/projects/gccalc/gccalc.c">Here&#8217;s the source file</a>, and here&#8217;s a syntax highlighted version:</p>

<p>It&#8217;s been tested on Mac OS X (Leopard) and Linux (Ubuntu Gutsy), with GCC 4. Compile with &#8220;gcc -o gccalc gccalc.c&#8221; on OS X, or &#8220;gcc -o gccalc gccalc.c -ldl&#8221; on Linux.</p>

<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; ">
<span style="color:#683821;">#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;string.h&gt;<br />
#include &lt;dlfcn.h&gt;<br />
#include &lt;unistd.h&gt;<br />
</span><br />
<span style="color:#683821;">#ifdef __ELF__<br />
#define GCC_FLAGS &quot;-fPIC -shared&quot;<br />
#define EXTENSION &quot;so&quot;<br />
#else<br />
#define GCC_FLAGS &quot;-dynamiclib&quot;<br />
#define EXTENSION &quot;dylib&quot;<br />
#endif<br />
</span><br />
<span style="color:#683821;">#define HEADERS &quot;#include &lt;stdio.h&gt;\n#include&lt;math.h&gt;&quot;<br />
</span><br />
<span style="color:#881350;">typedef</span> <span style="color:#881350;">double</span>(func_return_double)(<span style="color:#881350;">double</span>);<br />
<br />
<span style="color:#881350;">unsigned</span> count = <span style="color:#0000ff;">0</span>;<br />
<span style="color:#881350;">char</span> *cwd;<br />
<span style="color:#881350;">char</span> tmp_path[<span style="color:#0000ff;">1024</span>] = {<span style="color:#0000ff;">&#8216;\0&#8242;</span>};<br />
<br />
<span style="color:#881350;">void</span> *lib = <span style="color:#881350;">NULL</span>;<br />
<br />
<span style="color:#881350;">int</span> <span style="color:#003369;">main</span>(<span style="color:#881350;">int</span> argc, <span style="color:#881350;">char</span> **argv)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">double</span> result = <span style="color:#0000ff;">0.0</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">char</span> input_buffer[<span style="color:#0000ff;">1024</span>], code_buffer[<span style="color:#0000ff;">2048</span>], function_name[<span style="color:#0000ff;">32</span>], command_buffer[<span style="color:#0000ff;">1024</span>];<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// get out current directory, which we&#8217;ll use for tmp files (dlopen seems to need absolute paths)<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;cwd = <span style="color:#003369;">getcwd</span>(<span style="color:#881350;">NULL</span>, <span style="color:#0000ff;">0</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">while</span><span style="color:#003369;"> </span>(<span style="color:#0000ff;">1</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// for unique function and file names (needed for dlopen/dlsym to work correctly)<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// read in the next line<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">printf</span>(<span style="color:#760f15;">&quot;&gt;&gt; &quot;</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">fgets</span>(input_buffer, <span style="color:#881350;">sizeof</span>(input_buffer), stdin);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// format the function name<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">sprintf</span>(function_name, <span style="color:#760f15;">&quot;f%d&quot;</span>, count);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// format the code string: if it doesn&#8217;t contain a semicolon, assume it is just an expression<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(<span style="color:#003369;">strchr</span>(input_buffer, <span style="color:#0000ff;">&#8216;;&#8217;</span>))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">sprintf</span>(code_buffer, <span style="color:#760f15;">&quot;%s\ndouble %s(double last) { %s\nreturn 0; }&quot;</span>, HEADERS, function_name, input_buffer);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">sprintf</span>(code_buffer, <span style="color:#760f15;">&quot;%s\ndouble %s(double last) { return (%s); }&quot;</span>, HEADERS, function_name, input_buffer);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// format the filename string, delete the file if it exists<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">sprintf</span>(tmp_path, <span style="color:#760f15;">&quot;%s/libtmp%d.%s&quot;</span>, cwd, count, EXTENSION);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">unlink</span>(tmp_path);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// format the gcc command string<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">sprintf</span>(command_buffer, <span style="color:#760f15;">&quot;gcc -Wall %s -x c &#8211; -o %s&quot;</span>, GCC_FLAGS, tmp_path);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// execute gcc command, write out the code<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FILE *fp = <span style="color:#003369;">popen</span>(command_buffer, <span style="color:#760f15;">&quot;w&quot;</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">fwrite</span>(code_buffer, <span style="color:#0000ff;">1</span>, <span style="color:#003369;">strlen</span>(code_buffer), fp);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">fprintf</span>(fp, <span style="color:#760f15;">&quot;\n&quot;</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// pclose waits for gcc to terminate (fclose/close do NOT thus compilation will sometimes not finish prior to the dlopen)<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">pclose</span>(fp);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">void</span> *ptr = <span style="color:#881350;">NULL</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// open the just-compiled dynamic library<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>((lib = <span style="color:#003369;">dlopen</span>(tmp_path, RTLD_NOW|RTLD_LOCAL)) == <span style="color:#881350;">NULL</span>) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">puts</span>(<span style="color:#003369;">dlerror</span>());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// get the function pointer<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">else</span> <span style="color:#881350;">if</span><span style="color:#003369;"> </span>((ptr = <span style="color:#003369;">dlsym</span>(lib, function_name)) == <span style="color:#881350;">NULL</span>) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">puts</span>(<span style="color:#003369;">dlerror</span>());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// execute it<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(ptr != <span style="color:#881350;">NULL</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func_return_double *func = (func_return_double*)ptr;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = (*func)(result);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// print the result<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">printf</span>(<span style="color:#760f15;">&quot;=&gt; %.*lf\n&quot;</span>, (result/((<span style="color:#881350;">int</span>)result)&gt;<span style="color:#0000ff;">1.0</span>)?<span style="color:#0000ff;">5</span>:<span style="color:#0000ff;">0</span>, result);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// clean up: close the library, delete the temp file<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">dlclose</span>(lib);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">unlink</span>(tmp_path);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">return</span> <span style="color:#0000ff;">0</span>;<br />
}<br />
</div>

<p>Thanks to jbert on Reddit for the initial code and inspiration.</p>

<p>If only I had known about this back when The Daily WTF has having their <a href="http://omg.thedailywtf.com/">OMG WTF</a> crazy calculator programming contest&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://tlrobinson.net/blog/2007/12/14/presenting-gccalc-a-horribly-awesome-abuse-of-gcc/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Open new Terminal window in current (or other specified) directory</title>
		<link>http://tlrobinson.net/blog/2007/09/07/open-new-terminal-window-in-current-or-other-specified-directory/</link>
		<comments>http://tlrobinson.net/blog/2007/09/07/open-new-terminal-window-in-current-or-other-specified-directory/#comments</comments>
		<pubDate>Fri, 07 Sep 2007 21:38:18 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Command line]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://tlrobinson.net/blog/?p=26</guid>
		<description><![CDATA[A lot of times I find myself wanting to open another (Mac OS X) Terminal window in the same directory as my current one. This little shell script, which executes a little AppleScript, makes that trivial:

#!/bin/sh

if [ $# -ne 1 ]; then
&#160;&#160;&#160;&#160;PATHDIR=`pwd`
else
&#160;&#160;&#160;&#160;PATHDIR=$1
fi

osascript -e &#34;tell application \&#34;Terminal\&#34;&#34; -e &#34;do script \&#34;cd $PATHDIR\&#34;&#34; -e &#34;end tell&#34;


Save this [...]]]></description>
			<content:encoded><![CDATA[<p>A lot of times I find myself wanting to open another (Mac OS X) Terminal window in the same directory as my current one. This little shell script, which executes a little AppleScript, makes that trivial:</p>

<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#236e25;">#!/bin/sh<br />
</span><br />
<span style="color:#881350;">if</span> [ <span style="color:#c4620a;">$#</span> -ne <span style="color:#0000ff;">1</span> ]; <span style="color:#881350;">then</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;PATHDIR=<span style="color:#660088;">`pwd`</span><br />
<span style="color:#881350;">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;PATHDIR=<span style="color:#c4620a;">$</span><span style="color:#0000ff;">1</span><br />
<span style="color:#881350;">fi</span><br />
<br />
osascript -e <span style="color:#760f15;">&quot;tell application \&quot;Terminal\&quot;&quot;</span> -e <span style="color:#760f15;">&quot;do script \&quot;cd </span><span style="color:#c4620a;">$PATHDIR</span><span style="color:#760f15;">\&quot;&quot;</span> -e <span style="color:#760f15;">&quot;end tell&quot;</span><br />
</div>

<p>Save this script somewhere in your $PATH with executable permissions. Now instead of hitting Command-N then typing &#8220;cd really/long/path/to/your/current/directory&#8221;, you can simply type the name of the script (I used &#8220;term&#8221;):</p>

<pre><code>term
</code></pre>

<p>Chain them together to open multiple windows. The following would open three new windows with the same current directory:</p>

<pre><code>term; term; term
</code></pre>

<p>It can also take an optional directory path argument to override the current directory:</p>

<pre><code>term /System/Library/
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://tlrobinson.net/blog/2007/09/07/open-new-terminal-window-in-current-or-other-specified-directory/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
