<?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; C</title>
	<atom:link href="http://tlrobinson.net/blog/category/c/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>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>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>
	</channel>
</rss>
