<?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-31740253</id><updated>2012-01-25T21:07:16.748+02:00</updated><category term='gestalt'/><category term='interposing'/><category term='core data'/><category term='postgres'/><category term='Bâlea'/><category term='Piatra Craiului'/><category term='web'/><category term='later'/><category term='memento'/><category term='openstreetmap'/><category term='ip'/><category term='GMP'/><category term='cocoa'/><category term='objective-c'/><category term='ppp'/><category term='cisco'/><category term='divert sockets'/><category term='procfs'/><category term='hiking'/><category term='privateframeworks'/><category term='valgrind'/><category term='spell checker'/><category term='__ sprintf_chk'/><category term='smartmontools'/><category term='reliability'/><category term='Piatra Mare'/><category term='email'/><category term='interfacebuilder'/><category term='ocr'/><category term='raid'/><category term='cdr'/><category term='xml'/><category term='gsoap'/><category term='nasm'/><category term='loudhush'/><category term='digg news'/><category term='sysctl'/><category term='heap'/><category term='x11'/><category term='text to speech'/><category term='security'/><category term='foodbrowser'/><category term='Făgăraș'/><category term='sw_vers'/><category term='battery'/><category term='htc legend'/><category term='postgis'/><category term='bucharest'/><category term='cltq'/><category term='geographical location'/><category term='shp'/><category term='flex'/><category term='tnef'/><category term='myown'/><category term='c'/><category term='geometry'/><category term='segfault'/><category term='asterisk'/><category term='socket'/><category term='case folding'/><category term='photo'/><category term='android'/><category term='carbon'/><category term='dns'/><category term='iphoto'/><category term='intel'/><category term='html'/><category term='mac'/><category term='romanian'/><category term='sampler'/><category term='libproj4'/><category term='vmutils'/><category term='framework'/><category term='notetoself'/><category term='noise'/><category term='sprintf'/><category term='google'/><category term='screencast'/><category term='sandbox'/><category term='mail'/><category term='c-client'/><category term='proxy'/><category term='bucharestapp'/><category term='ipfw'/><category term='kb'/><category term='romania'/><category term='arp'/><category term='frameaway 3.0'/><category term='debugger'/><category term='f-script'/><category term='core image'/><category term='srtm'/><category term='64bit'/><category term='eval'/><category term='shapelib'/><category term='hardware address'/><category term='infix'/><category term='x86'/><category term='vodafone mobile connect'/><category term='bad block'/><category term='demo'/><category term='assembly'/><category term='renault'/><category term='3g'/><category term='untested code'/><category term='clang'/><category term='pgrouting'/><category term='python'/><category term='leopard'/><category term='tee'/><category term='projections'/><category term='10.6'/><category term='llvm'/><category term='macbook'/><category term='x86_64'/><category term='qrcode'/><category term='firewall'/><category term='osm2pgsql'/><category term='frameaway'/><category term='tesseract'/><category term='old news'/><category term='diacritics'/><category term='ethernet'/><category term='plpgsql'/><category term='boot'/><category term='vi'/><category term='gdb'/><category term='programming'/><category term='sqlite'/><category term='gis'/><category term='mac os x'/><category term='web services'/><category term='dylib'/><category term='time'/><category term='lldb'/><category term='grass'/><category term='outlook'/><category term='spamassassin'/><category term='stack'/><category term='imq'/><category term='openstretmap'/><category term='sql'/><category term='telephony'/><category term='unix'/><category term='Qgis'/><category term='poetry'/><category term='composition'/><category term='routing'/><category term='gcc'/><category term='vpn'/><category term='lex'/><category term='maps'/><category term='x-alps'/><category term='iax'/><category term='megane'/><category term='ipv6'/><category term='rpn'/><title type='text'>LoudHush Blog</title><subtitle type='html'>please tell her to roll back the universe</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default?start-index=101&amp;max-results=100'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>137</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-31740253.post-356836988428952876</id><published>2012-01-25T21:06:00.000+02:00</published><updated>2012-01-25T21:07:16.751+02:00</updated><title type='text'>OrbView-3 imagery freely available from USGS</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;a href="http://geo-spatial.org"&gt;geo-spatial.org&lt;/a&gt;'s mailing list had a link to this little gem: &lt;a href="http://www.usgs.gov/newsroom/article_pf.asp?ID=3070"&gt;High Resolution OrbView - 3 Images Now Available from USGS&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;The resolution itself is not spectacular when compared to the Bing imagery displayed in OSM's Potlatch and the coverage of Romania's territory is rather sparse, but the license lets you do whatever you want with the imagery (public domain).&lt;br/&gt;&lt;br/&gt;A preview of the OSM street network on top of OrbView-3 imagery for Bucharest, Aviatiei: &lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-JoxqVBExnZk/TyBOlt3XQrI/AAAAAAAAEvc/KFsBNPMt81k/s1600/Bucharest_orbview3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="244" src="http://4.bp.blogspot.com/-JoxqVBExnZk/TyBOlt3XQrI/AAAAAAAAEvc/KFsBNPMt81k/s400/Bucharest_orbview3.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;geo-spatial.org &lt;a href="http://earth.unibuc.ro/articole/documentare-orbview3"&gt;are working on a project&lt;/a&gt; to make the processed data available through their WMS service.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-356836988428952876?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/356836988428952876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=356836988428952876' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/356836988428952876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/356836988428952876'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2012/01/orbview-3-imagery-freely-available-from.html' title='OrbView-3 imagery freely available from USGS'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-JoxqVBExnZk/TyBOlt3XQrI/AAAAAAAAEvc/KFsBNPMt81k/s72-c/Bucharest_orbview3.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5287978411289497026</id><published>2011-11-08T13:27:00.000+02:00</published><updated>2011-11-08T14:12:19.151+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='srtm'/><category scheme='http://www.blogger.com/atom/ns#' term='grass'/><category scheme='http://www.blogger.com/atom/ns#' term='hiking'/><title type='text'>Line of sight analysis using Grass GIS and SRTM elevation data</title><content type='html'>Grass GIS has built-in support for line of sight analysis (the command is called &lt;a href="http://grass.fbk.eu/gdp/html_grass62/r.los.html"&gt;r.los&lt;/a&gt;).&lt;br/&gt;&lt;br/&gt;I'm revisiting an older post (&lt;a href="http://blog.loudhush.ro/2010/09/mountain-hiking-tracks-in-fagaras.html"&gt;Mountain Hiking Tracks in Făgăraș&lt;/a&gt;) that I've ended with a line of sight diagram I've built by hand based on the description given by a fellow hiker who described to us what we were seeing (peak names).This time I've used Grass GIS to build the line of sight raster from Vânătoarea lui Buteanu peak with a 20 Km radius.The background is based on the freely available Landsat 7 image data.&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-kKjNsIMddkQ/Trjp3tqedVI/AAAAAAAAElM/pO8mNAAQxtQ/s1600/los_westward_detail.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="282" width="400" src="http://3.bp.blogspot.com/-kKjNsIMddkQ/Trjp3tqedVI/AAAAAAAAElM/pO8mNAAQxtQ/s400/los_westward_detail.png" /&gt;&lt;/a&gt;&lt;/div&gt;Note there are NULL values (failures to read altitudes in certain raster cells) in the SRTM data (represented in black in the picture below) so the line of sight analysis above was carried on an interpolated version of the data.&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-cr9KE5Hyt14/Trjp36isVsI/AAAAAAAAElY/z-3vouRhsxo/s1600/los_westward_nulls.png" title="Line of sight diagram from Vânătoarea Lui Buteanu" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="282" width="400" src="http://2.bp.blogspot.com/-cr9KE5Hyt14/Trjp36isVsI/AAAAAAAAElY/z-3vouRhsxo/s400/los_westward_nulls.png" /&gt;&lt;/a&gt;&lt;/div&gt;As far as I can tell, the diagram is fairly accurate. I'm not sure about "Turnul Paltinului" and the small ridge following it, but the rest of the features fall into place pretty nicely.This is a photo taken from Vânătoarea lui Buteanu towards Negoiu Peak:&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-QpYOy2sptDo/TrjtqqTFlKI/AAAAAAAAElk/GndLqCsDDBw/s1600/DSC_0212.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="266" width="400" src="http://2.bp.blogspot.com/-QpYOy2sptDo/TrjtqqTFlKI/AAAAAAAAElk/GndLqCsDDBw/s400/DSC_0212.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;And this is a mash-up of the line of sight diagram over-imposed on the photograph:&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Gvk1QZEDpXk/Trj3NhNivoI/AAAAAAAAElw/CZrOccyvCrs/s1600/diag.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="211" width="400" src="http://3.bp.blogspot.com/-Gvk1QZEDpXk/Trj3NhNivoI/AAAAAAAAElw/CZrOccyvCrs/s400/diag.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-5287978411289497026?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5287978411289497026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5287978411289497026' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5287978411289497026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5287978411289497026'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/11/line-of-sight-analysis-using-grass-gis.html' title='Line of sight analysis using Grass GIS and SRTM elevation data'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-kKjNsIMddkQ/Trjp3tqedVI/AAAAAAAAElM/pO8mNAAQxtQ/s72-c/los_westward_detail.png' height='72' width='72'/><thr:total>0</thr:total><georss:featurename>DN7C, Romania</georss:featurename><georss:point>45.60839359673345 24.610748291015625</georss:point><georss:box>45.58617959673345 24.571266291015625 45.63060759673345 24.650230291015625</georss:box></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-2174167820092062272</id><published>2011-11-07T14:39:00.000+02:00</published><updated>2011-11-08T14:14:19.364+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grass'/><category scheme='http://www.blogger.com/atom/ns#' term='gis'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='osm2pgsql'/><title type='text'>Using OpenStreetMap osm2pgsql data in Grass GIS</title><content type='html'>These are my notes on using the OSM data as imported by &lt;i&gt;osm2pgsql&lt;/i&gt; in a PostgreSQL database with Grass GIS.&lt;br/&gt;&lt;br/&gt;While Grass is a very powerful tool, it's Unixy feel is a little disconcerting.If you're a programmer like me, it helps to realize the Grass command line shell is in fact a preconfigured &lt;i&gt;bash&lt;/i&gt; session:&lt;pre class="prettyprint"&gt;&lt;br /&gt;GRASS 6.4.1 (OSM_900913):~ &gt; ps ax | grep "$$" | grep -v grep&lt;br /&gt;98804 s000  S      0:00.06 /bin/bash&lt;br /&gt;&lt;/pre&gt;The things you get from Grass are a set of binaries that interact with the data you have (organized in &lt;i&gt;locations&lt;/i&gt; that are part of a &lt;i&gt;mapset&lt;/i&gt; stored inside your filesystem).The other thing that is somewhat unexpected for a PostGIS user is that, within a Grass &lt;i&gt;location&lt;/i&gt;, all the data has to share a single projection.&lt;h2&gt;Creating a location for your OSM data&lt;/h2&gt;The first step required when using OSM data is to create a Grass location for the OSM data.I've used the same projection &lt;i&gt;osm2pgsql&lt;/i&gt; uses when importing, the "fake" projection with SRID 900913. Grass doesn't know it, so you can define it as a custom PROJ4 string based on the definition you get from PostGIS:&lt;pre class="prettyprint"&gt;&lt;br /&gt;osm=# select proj4text from spatial_ref_sys where srid = 900913;&lt;br /&gt;                                                    proj4text                                                     &lt;br /&gt;------------------------------------------------------------------------------------------------------------------&lt;br /&gt; +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +units=m +k=1.0 +nadgrids=@null +no_defs&lt;br /&gt;(1 row)&lt;br /&gt;&lt;/pre&gt;Here are the relevant screen shots when defining the location using Grass Python WXGUI:&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-eaRxX3pZ2yU/TrfFTPaCs9I/AAAAAAAAEj4/2k5x27bDDkU/s1600/Screen%2BShot%2B2011-11-07%2Bat%2B1.35.58%2BPM.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="257" width="400" src="http://4.bp.blogspot.com/-eaRxX3pZ2yU/TrfFTPaCs9I/AAAAAAAAEj4/2k5x27bDDkU/s400/Screen%2BShot%2B2011-11-07%2Bat%2B1.35.58%2BPM.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-b5mMFTiObIw/TrfFTdveM8I/AAAAAAAAEkI/t8XiHaB2Vm4/s1600/Screen%2BShot%2B2011-11-07%2Bat%2B1.37.18%2BPM.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="264" width="400" src="http://1.bp.blogspot.com/-b5mMFTiObIw/TrfFTdveM8I/AAAAAAAAEkI/t8XiHaB2Vm4/s400/Screen%2BShot%2B2011-11-07%2Bat%2B1.37.18%2BPM.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-avLsiytv4UU/TrfFUF99jMI/AAAAAAAAEkQ/kfhEHE0YrEA/s1600/Screen%2BShot%2B2011-11-07%2Bat%2B1.37.32%2BPM.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="260" width="400" src="http://3.bp.blogspot.com/-avLsiytv4UU/TrfFUF99jMI/AAAAAAAAEkQ/kfhEHE0YrEA/s400/Screen%2BShot%2B2011-11-07%2Bat%2B1.37.32%2BPM.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;h2&gt;Creating temporary tables in OSM&lt;/h2&gt;To reduce the size of the data set, I've created a couple of tables in PostGIS by selecting only those features I planned to use for my map by spatially selecting those features within a certain administrative boundary:&lt;pre class="prettyprint"&gt;&lt;br /&gt;create table bucharest_s1_streets as&lt;br /&gt;select * from planet_osm_line where st_contains((select way from planet_osm_polygon where boundary = 'administrative' and name ='Sector 1' limit 1), way)&lt;br /&gt;and highway is not null;&lt;br /&gt;&lt;br /&gt;create table bucharest_s1_pois as&lt;br /&gt;select * from planet_osm_point where st_contains((select way from planet_osm_polygon where boundary = 'administrative' and name ='Sector 1' limit 1), way);&lt;br /&gt;&lt;/pre&gt;I then defined these tables in PostGIS' geometry_tables (otherwise Grass will refuse to import them):&lt;pre class="prettyprint"&gt;&lt;br /&gt;insert into geometry_columns(f_table_catalog, f_table_schema, f_table_name, f_geometry_column, coord_dimension, srid, type) values('','public','bucharest_s1_pois','way',2,900913,'POINT');&lt;br /&gt;insert into geometry_columns(f_table_catalog, f_table_schema, f_table_name, f_geometry_column, coord_dimension, srid, type) values('','public','bucharest_s1_streets','way',2,900913,'LINESTRING');&lt;br /&gt;&lt;/pre&gt;&lt;h2&gt;Importing the data in Grass&lt;/h2&gt;For some reason, my Grass setup fails to set the environment variables below, so I have to re-export them:&lt;pre&gt;&lt;br /&gt;GRASS 6.4.1 (OSM_900913):~ &gt; export GISDBASE=/Users/diciu/grassdata&lt;br /&gt;GRASS 6.4.1 (OSM_900913):~ &gt; export LOCATION_NAME=OSM_900913&lt;br /&gt;GRASS 6.4.1 (OSM_900913):~ &gt; export MAPSET=PERMANENT&lt;br /&gt;&lt;/pre&gt;The PostGIS database parameters have to be defined next:&lt;pre&gt;&lt;br /&gt;export HOST=localhost&lt;br /&gt;export DB=osm&lt;br /&gt;export USER=gisuser&lt;br /&gt;export PASS=somepassword&lt;br /&gt;export DSN="PG:host=${HOST} dbname=${DB} user=${USER} password=${PASS}"&lt;br /&gt;&lt;/pre&gt;You can now run the &lt;i&gt;v.ogr.in&lt;/i&gt; commands to import your data (I'm importing roads and pharmacies):&lt;pre&gt;&lt;br /&gt;v.in.ogr dsn="${DSN}" layer=bucharest_s1_streets out=streets&lt;br /&gt;v.in.ogr dsn="${DSN}" layer=bucharest_s1_pois out=pharmacy where="amenity='pharmacy'"&lt;br /&gt;&lt;/pre&gt;If everything went well, not you have two vector layers in your &lt;i&gt;location&lt;/i&gt;:&lt;pre class="prettyprint"&gt;&lt;br /&gt;GRASS 6.4.1 (OSM_900913):~ &gt; g.list type=vect&lt;br /&gt;----------------------------------------------&lt;br /&gt;vector files available in mapset &lt;PERMANENT&gt;:&lt;br /&gt;pharmacy                  streets&lt;br /&gt;----------------------------------------------&lt;br /&gt;&lt;/pre&gt;&lt;h2&gt;Computing distance to pharmacies&lt;/h2&gt;The &lt;a href="http://grass.osgeo.org/grass57/tutorial/network.html"&gt;Vector networking tutorial&lt;/a&gt; describes a number of very nice examples of processing tools available in Grass.I am using &lt;i&gt;v.net.iso&lt;/i&gt; below to compute the distance from pharmacies:&lt;pre&gt;&lt;br /&gt;v.distance -p from=pharmacy to=streets output=pharmacy_conn_streets upload=dist column=dist&lt;br /&gt;v.patch in=pharmacy,streets,pharmacy_conn_streets out=pharmacy_net&lt;br /&gt;v.clean in=pharmacy_net out=pharmacy_net_clean tool=snap,break thresh=1&lt;br /&gt;v.net.iso input=pharmacy_net_clean output=pharmacy_iso ccats=1-100 costs=200,500,1000 nlayer=1&lt;br /&gt;&lt;/pre&gt;The command's output are a number of vector layers, &lt;i&gt;pharmacy_iso&lt;/i&gt; being the one that stores our road network categorized by distance to pharmacies (less than 200 meters, between 200 and 500 meters and so on).&lt;h2&gt;Rendering a map using the data&lt;/h2&gt;It's much easier and the results are probably better if you use QGIS instead of Grass' UI.There's a plugin for QGIS that asks you to specify the Grass mapset, location and loads a given layer. As an added bonus, QGIS is able to re-project on the fly so you can mix layers in different projections.&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-VVW5ATtw724/TrfOCIBHvsI/AAAAAAAAEko/JT-TE7WHr2I/s1600/Screen%2BShot%2B2011-11-07%2Bat%2B2.23.48%2BPM.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="312" width="400" src="http://1.bp.blogspot.com/-VVW5ATtw724/TrfOCIBHvsI/AAAAAAAAEko/JT-TE7WHr2I/s400/Screen%2BShot%2B2011-11-07%2Bat%2B2.23.48%2BPM.png" /&gt;&lt;/a&gt;&lt;/div&gt;Here's a map of pharmacies in my neighborhood as rendered by QGIS' export to PNG feature:&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-K_7mjY5B5Js/TrfM3V3yXcI/AAAAAAAAEkc/c7NLKHHcfZU/s1600/pharma.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="282" src="http://1.bp.blogspot.com/-K_7mjY5B5Js/TrfM3V3yXcI/AAAAAAAAEkc/c7NLKHHcfZU/s400/pharma.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-2174167820092062272?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/2174167820092062272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=2174167820092062272' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/2174167820092062272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/2174167820092062272'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/11/using-openstreetmap-osm2pgsql-data-in.html' title='Using OpenStreetMap osm2pgsql data in Grass GIS'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-eaRxX3pZ2yU/TrfFTPaCs9I/AAAAAAAAEj4/2k5x27bDDkU/s72-c/Screen%2BShot%2B2011-11-07%2Bat%2B1.35.58%2BPM.png' height='72' width='72'/><thr:total>0</thr:total><georss:featurename>Strada Borşa, Bucharest, Romania</georss:featurename><georss:point>44.48089151743199 26.095361709594727</georss:point><georss:box>44.47522701743199 26.085491209594725 44.486556017431994 26.10523220959473</georss:box></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-3582064969345841497</id><published>2011-10-12T12:57:00.000+03:00</published><updated>2011-10-12T12:57:06.520+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='postgis'/><category scheme='http://www.blogger.com/atom/ns#' term='routing'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='pgrouting'/><title type='text'>Using pgRouting on an OSM database imported by osm2pgsql</title><content type='html'>If you've tried to use pgRouting on an OSM database imported by osm2pgsql you've probably noticed it doesn't work.&lt;br /&gt;&lt;br /&gt;It doesn't work because one of the requirements for pgRouting is that streets are split at intersections, meaning it expects each osm_id from &lt;i&gt;planet_osm_line&lt;/i&gt; to only contain street segments. &lt;br /&gt;However, in &lt;i&gt;planet_osm_line&lt;/i&gt;, a street is represented by a LINESTRING, most of the times the intersection with other streets being just another POINT in the street's LINESTRING.&lt;br /&gt;&lt;br /&gt;A visual representation of the long explanation above:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-ZL2CL4iuYdc/Tl-ykqEUKQI/AAAAAAAAEL8/0H84xmKMvLI/s1600/expected.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 361px;" src="http://4.bp.blogspot.com/-ZL2CL4iuYdc/Tl-ykqEUKQI/AAAAAAAAEL8/0H84xmKMvLI/s400/expected.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5647428800583313666" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-fC19dvMepOU/Tl4SColS4SI/AAAAAAAAELc/Zm3aJd8ngtY/s1600/reality.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 361px;" src="http://1.bp.blogspot.com/-fC19dvMepOU/Tl4SColS4SI/AAAAAAAAELc/Zm3aJd8ngtY/s400/reality.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5646970819232063778" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The good news is that it's fairly easy to split the OSM streets into constituent segments using PLPGSQL.&lt;br /&gt;One way to achieve that is the one listed below (note the filtering on "Sector 1" - I am restricting table entries within the administrative boundary of the first sector of Bucharest because things get really slow on the entire OSM road network):&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&lt;br /&gt;drop table if exists network;&lt;br /&gt;create table network(gid serial, osm_id integer, name varchar, the_geom geometry, source integer, target integer, length float);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;CREATE OR REPLACE FUNCTION compute_network() RETURNS text as $$&lt;br /&gt;DECLARE&lt;br /&gt;streetRecord record;&lt;br /&gt;wayRecord record;&lt;br /&gt;pointCount integer;&lt;br /&gt;pointIndex integer;&lt;br /&gt;geomFragment record;&lt;br /&gt;BEGIN&lt;br /&gt;-- for each street&lt;br /&gt;FOR streetRecord in select way, osm_id, name from planet_osm_line where highway is not null and st_contains((select way from planet_osm_polygon where boundary = 'administrative' and name like 'Sector 1' limit 1), way) LOOP&lt;br /&gt; -- for each street in the region of interest&lt;br /&gt; SELECT * from planet_osm_ways where id = streetRecord.osm_id into wayRecord; &lt;br /&gt; FOR pointIndex in array_lower(wayRecord.nodes, 1)..array_upper(wayRecord.nodes,1)-1 LOOP&lt;br /&gt;  RAISE NOTICE 'Inserting name % source %, target %', streetRecord.name, wayRecord.nodes[pointIndex], wayRecord.nodes[pointIndex+1];&lt;br /&gt;  select st_makeline(st_pointn(streetRecord.way, pointIndex), st_pointn(streetRecord.way, pointIndex+1)) as way into geomFragment;&lt;br /&gt;  insert into network(osm_id, name, the_geom, source, target, length) values(streetRecord.osm_id, streetRecord.name, geomFragment.way, wayRecord.nodes[pointIndex], wayRecord.nodes[pointIndex+1], st_length(geomFragment.way));&lt;br /&gt; END LOOP;&lt;br /&gt;END LOOP;&lt;br /&gt;return 'Done';&lt;br /&gt;END;&lt;br /&gt;$$ LANGUAGE 'plpgsql';&lt;br /&gt;&lt;br /&gt;select * from compute_network();&lt;br /&gt;select assign_vertex_id('network', 1, 'the_geom', 'gid');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The PLPGSQL procedure works by creating a street segment for each pair of nodes from &lt;i&gt;planet_osm_ways&lt;/i&gt;; the geometry is created by simply creating a new line from the points corresponding to the nodes (see the &lt;i&gt;st_makeline&lt;/i&gt; call).&lt;br /&gt;&lt;br /&gt;Once &lt;i&gt;assign_vertex_id&lt;/i&gt; has been run, you can start using &lt;i&gt;shortest_path&lt;/i&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;osm=# select n.name, p.edge_id, o.highway from network n, (select edge_id from shortest_path('&lt;br /&gt;osm'# SELECT gid as id,&lt;br /&gt;osm'# source,&lt;br /&gt;osm'# target,&lt;br /&gt;osm'# length as cost&lt;br /&gt;osm'# FROM network',&lt;br /&gt;osm(# (select source from network where name='Intrarea Jugului' limit 1),(select source from network where name='Strada Sofia' limit 1),false,false)) p,&lt;br /&gt;osm-# planet_osm_line o&lt;br /&gt;osm-# where p.edge_id = n.gid and n.osm_id = o.osm_id;&lt;br /&gt;             name             | edge_id |   highway   &lt;br /&gt;------------------------------+---------+-------------&lt;br /&gt; Intrarea Jugului             |    2330 | residential&lt;br /&gt; Strada Elena Caragiani       |     808 | residential&lt;br /&gt; Strada Borșa                 |    2016 | residential&lt;br /&gt; Strada Borșa                 |    2015 | residential&lt;br /&gt; Strada Borșa                 |    2014 | residential&lt;br /&gt; Strada Borșa                 |    2013 | residential&lt;br /&gt;                              |    1992 | residential&lt;br /&gt; Șoseaua Pipera               |    8098 | secondary&lt;br /&gt; Strada Nicolae Caramfil      |    1828 | secondary&lt;br /&gt; Strada Nicolae Caramfil      |    1827 | secondary&lt;br /&gt; Strada Nicolae Caramfil      |    1826 | secondary&lt;br /&gt; Strada Nicolae Caramfil      |    1825 | secondary&lt;br /&gt; Strada Nicolae Caramfil      |    1824 | secondary&lt;br /&gt; Strada Nicolae Caramfil      |    1823 | secondary&lt;br /&gt; Strada Nicolae Caramfil      |    1822 | secondary&lt;br /&gt; Strada Nicolae Caramfil      |    1821 | secondary&lt;br /&gt; Bulevardul Beijing           |    1035 | secondary&lt;br /&gt; Bulevardul Beijing           |    1036 | secondary&lt;br /&gt; Bulevardul Beijing           |    7883 | secondary&lt;br /&gt; Bulevardul Beijing           |    7766 | secondary&lt;br /&gt; Bulevardul Beijing           |    1474 | residential&lt;br /&gt; Bulevardul Beijing           |    1473 | residential&lt;br /&gt; Bulevardul Beijing           |    1472 | residential&lt;br /&gt; Bulevardul Beijing           |    1471 | residential&lt;br /&gt; Bulevardul Beijing           |    1470 | residential&lt;br /&gt; Bulevardul Beijing           |    1469 | residential&lt;br /&gt; Bulevardul Beijing           |    1468 | residential&lt;br /&gt; Bulevardul Beijing           |    1467 | residential&lt;br /&gt; Piața Charles de Gaulle      |     859 | residential&lt;br /&gt; Piața Charles de Gaulle      |     858 | residential&lt;br /&gt; Piața Charles de Gaulle      |    8918 | residential&lt;br /&gt; Piața Charles de Gaulle      |    8917 | residential&lt;br /&gt; Piața Charles de Gaulle      |    8916 | residential&lt;br /&gt; Piața Charles de Gaulle      |    8915 | residential&lt;br /&gt; Piața Charles de Gaulle      |    8914 | residential&lt;br /&gt; Piața Charles de Gaulle      |    8913 | residential&lt;br /&gt; Piața Charles de Gaulle      |    8912 | residential&lt;br /&gt; Calea Dorobanților           |     264 | primary&lt;br /&gt;                              |    9999 | footway&lt;br /&gt; Calea Dorobanților           |    8116 | primary&lt;br /&gt; Calea Dorobanților           |    8117 | primary&lt;br /&gt; Calea Dorobanților           |    8118 | primary&lt;br /&gt; Calea Dorobanților           |    8119 | primary&lt;br /&gt; Strada Emil Pangrati         |    3489 | residential&lt;br /&gt; Strada Emil Pangrati         |    3412 | residential&lt;br /&gt; Strada Emil Pangrati         |    3413 | residential&lt;br /&gt; Strada Emil Pangrati         |    3414 | residential&lt;br /&gt; Cpt. Av. Demetriade Gheorghe |    3446 | residential&lt;br /&gt; Strada Andrei Muresanu       |    8086 | residential&lt;br /&gt;(49 rows)&lt;br /&gt;&lt;br /&gt;Time: 77.807 ms&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you render the above (I used QGIS), the (start of) the route looks like this:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-oMoHEVKgUCw/Tl4MzvNICXI/AAAAAAAAEK0/yUT0O-swGvU/s1600/route_with_edges.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 340px;" src="http://3.bp.blogspot.com/-oMoHEVKgUCw/Tl4MzvNICXI/AAAAAAAAEK0/yUT0O-swGvU/s400/route_with_edges.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5646965065753561458" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Note how pgRouting has found multiple edges (2016, 2015, 2014, 2013) alongside "Strada Borșa"; that's because we split the street using the PLPGSQL procedure described at the beginning of the post:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;osm=# select osm_id, name from network where gid in (2016, 2015, 2014, 2013);&lt;br /&gt;  osm_id  |     name     &lt;br /&gt;----------+--------------&lt;br /&gt; 23730998 | Strada Borșa&lt;br /&gt; 23730998 | Strada Borșa&lt;br /&gt; 23730998 | Strada Borșa&lt;br /&gt; 23730998 | Strada Borșa&lt;br /&gt;(4 rows)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-3582064969345841497?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/3582064969345841497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=3582064969345841497' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3582064969345841497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3582064969345841497'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/10/using-pgrouting-on-osm-database.html' title='Using pgRouting on an OSM database imported by osm2pgsql'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-ZL2CL4iuYdc/Tl-ykqEUKQI/AAAAAAAAEL8/0H84xmKMvLI/s72-c/expected.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-1947625480477133434</id><published>2011-10-04T10:02:00.004+03:00</published><updated>2011-10-04T10:51:47.602+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='postgis'/><category scheme='http://www.blogger.com/atom/ns#' term='Qgis'/><title type='text'>Installing the Fast SQL Layer plugin on Mac OS X 10.7</title><content type='html'>If you're running QGis version 1.7 (trunk) from the &lt;a href="http://www.kyngchaos.com/software/qgis"&gt;KyngChaos site&lt;/a&gt; and you want to install the &lt;a href="http://underdark.wordpress.com/2011/05/25/fast-sql-layer-for-qgis/"&gt;Fast SQL Layer&lt;/a&gt; plugin, you need to solve some dependencies first.&lt;br /&gt;&lt;br /&gt;The paths below may not be the same on your machine if you've not installed GEOS and PROJ4 from the KyngChaos packages.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;sudo easy_install-2.6 Pygments&lt;br /&gt;sudo C_INCLUDE_PATH=/usr/local/pgsql/include/ easy_install-2.6  psycopg2&lt;br /&gt;sudo LIBRARY_PATH=/Library/Frameworks/GEOS.framework/Versions/3/unix/lib/:/Library/Frameworks/PROJ.framework/Versions/4/unix/lib/ C_INCLUDE_PATH=/Library/Frameworks/GEOS.framework/Versions/3/unix/include/:/Library/Frameworks/PROJ.framework/Versions/4/Headers/ easy_install-2.6  pyspatialite&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If the installation has been successful, you should not get an error when importing the modules, i.e.:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;cristi:~ diciu$ python2.6&lt;br /&gt;Python 2.6.6 (r266:84292, Jun 16 2011, 16:59:16) &lt;br /&gt;[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin&lt;br /&gt;Type "help", "copyright", "credits" or "license" for more information.&lt;br /&gt;&gt;&gt;&gt; import pygments, psycopg2, pyspatialite&lt;br /&gt;&gt;&gt;&gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Once you've installed the dependencies, you can go on installing the plugin using the QGIS GUI.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-1947625480477133434?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/1947625480477133434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=1947625480477133434' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1947625480477133434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1947625480477133434'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/10/installing-fast-sql-layer-plugin-on-mac.html' title='Installing the Fast SQL Layer plugin on Mac OS X 10.7'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-4186830597132870336</id><published>2011-09-01T14:14:00.012+03:00</published><updated>2011-09-05T11:04:31.400+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='routing'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='hiking'/><title type='text'>Using pgRouting to compute routes on OSM hiking trails</title><content type='html'>I've experimented with using pgRouting's &lt;i&gt;shortest_path&lt;/i&gt; function to compute routes using the hiking trails defined in the OpenStreetMap data set.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Building the topology&lt;/h3&gt;&lt;br /&gt;In the OSM model as created by osm2pgsql, the relations table models a hiking trail based on a set of members (each member a LINESTRING geometry from the planet_osm_line table). &lt;br /&gt;&lt;br /&gt;The problem is you cannot build a topology based solely on the start and end points of each trail segment, because more often then not, trail segment intersect mid-way:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-upS8UlODpV4/Tl-XskP623I/AAAAAAAAELk/ZDiMEPEpZJk/s1600/nonterminal.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 302px;" src="http://2.bp.blogspot.com/-upS8UlODpV4/Tl-XskP623I/AAAAAAAAELk/ZDiMEPEpZJk/s400/nonterminal.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5647399249646377842" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So I used the relations table to build the topology where each trail segment is split based on the POINTS that are part of its LINESTRING geometry. This means that every point from the trail segment becomes a node in our topology (this is &lt;b&gt;very&lt;/b&gt; inefficient, but I could not find a faster way of not missing mid-trail intersections). &lt;br /&gt;&lt;br /&gt;I've built the topology using the following SQL code:&lt;br /&gt;&lt;br /&gt;&lt;pre code="prettyprint"&gt;&lt;br /&gt;drop table if exists trail_network;&lt;br /&gt;create table trail_network(gid serial, osm_id integer, name varchar, symbol varchar, the_geom geometry, source integer, target integer, length float);&lt;br /&gt;&lt;br /&gt;CREATE OR REPLACE FUNCTION compute_trail_network() RETURNS text as $$&lt;br /&gt;DECLARE&lt;br /&gt;relationRecord record;&lt;br /&gt;partIndex integer;&lt;br /&gt;lineRecord record;&lt;br /&gt;wayRecord record;&lt;br /&gt;geomFragment record;&lt;br /&gt;BEGIN&lt;br /&gt;	FOR relationRecord in select id, parts, tags from planet_osm_rels where tags @&gt; '{osmc:symbol}' and tags @&gt; '{hiking}' LOOP&lt;br /&gt;		FOR partIndex in array_lower(relationRecord.parts, 1)..array_upper(relationRecord.parts, 1) LOOP&lt;br /&gt;			SELECT name, highway, way from planet_osm_line where osm_id = relationRecord.parts[partIndex] into lineRecord;&lt;br /&gt;			SELECT * from planet_osm_ways where id = relationRecord.parts[partIndex] into wayRecord;&lt;br /&gt;			FOR pointIndex in 1..ST_NPoints(lineRecord.way)-1 LOOP&lt;br /&gt;				select st_makeline(st_pointn(lineRecord.way, pointIndex), st_pointn(lineRecord.way, pointIndex+1)) as way into geomFragment;&lt;br /&gt;				INSERT into trail_network(osm_id, name, symbol, the_geom, length) values(relationRecord.parts[partIndex], substring(array_to_string(relationRecord.tags, '#'), '#name#([^#]*)#?$'), substring(array_to_string(relationRecord.tags, '#'), '(red_cross|blue_cross|red_triangle|blue_triangle|red_dot|blue_dot|red_stripe|blue_stripe|yellow_stripe|yellow_triangle|yellow_cross)'), geomFragment.way, st_length(geomFragment.way));&lt;br /&gt;			END LOOP;&lt;br /&gt;		END LOOP;&lt;br /&gt;	END LOOP;&lt;br /&gt;return 'Done';&lt;br /&gt;END;&lt;br /&gt;$$ LANGUAGE 'plpgsql';&lt;br /&gt;&lt;br /&gt;select * from compute_trail_network();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Once the topology has been created, I called assign_vertex_id() to compute source and target values (for some reason, &lt;i&gt;probe_geometry_columns&lt;/i&gt; does not work on my machine so I had to fill in my topology table's geometry column data by hand):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;insert into geometry_columns(f_table_catalog, f_table_schema, f_table_name, f_geometry_column, coord_dimension, srid, type) values('', 'public', 'trail_network', 'the_geom', 2, 900913, 'LINESTRING');&lt;br /&gt;&lt;br /&gt;SELECT assign_vertex_id('trail_network', 2, 'the_geom', 'gid');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Computing a route&lt;/h3&gt;&lt;br /&gt;The first thing required is finding topology nodes close to the POI's that represent departure and arrival points.&lt;br /&gt;In this example, we will compute a route between &lt;i&gt;Cabana Piscul Negru&lt;/i&gt; and &lt;i&gt;Negoiu&lt;/i&gt;:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;osm=# select t.gid, t.source, t.target, t.osm_id, t.name, st_distance(p.way, t.the_geom) from trail_network t, planet_osm_point p where st_buffer(p.way, 100) &amp;&amp; t.the_geom and p.name='Cabana Piscul Negru' order by st_distance(p.way, t.the_geom) asc limit 5;&lt;br /&gt;  gid  | source | target |  osm_id  |              name              |   st_distance    &lt;br /&gt;-------+--------+--------+----------+--------------------------------+------------------&lt;br /&gt; 41354 |  17684 |  17685 | 73964460 | Piscu Negru - Refugiul Călțun  | 94.9336094118476&lt;br /&gt; 41532 |  17684 |  17685 | 73964460 | Piscul Negru - Șaua Paltinului | 94.9336094118476&lt;br /&gt;(2 rows)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;there are two edges in close proximity to Piscul Negru (94 meters away). They share source and target nodes because they are in fact over a segment shared between the two different trails.&lt;br /&gt;&lt;br /&gt;We repeat the query to find out the node for Negoiu:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;osm=# select t.gid, t.source, t.target, t.osm_id, t.name, st_distance(p.way, t.the_geom) from trail_network t, planet_osm_point p where st_buffer(p.way, 100) &amp;&amp; t.the_geom and p.name='Negoiu' order by st_distance(p.way, t.the_geom) asc limit 5;&lt;br /&gt;  gid  | source | target |  osm_id  |      name      |   st_distance    &lt;br /&gt;-------+--------+--------+----------+----------------+------------------&lt;br /&gt; 42688 |  18832 |  18833 | 27182093 | Traseu creasta | 2.03276684697733&lt;br /&gt; 42687 |  18831 |  18832 | 27182093 | Traseu creasta | 2.18879960182101&lt;br /&gt; 42686 |  18830 |  18831 | 27182093 | Traseu creasta | 13.9052808592012&lt;br /&gt; 42685 |  18829 |  18830 | 27182093 | Traseu creasta | 35.2142772300472&lt;br /&gt; 42684 |  18828 |  18829 | 27182093 | Traseu creasta |  63.933925517158&lt;br /&gt;(5 rows)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now that we've got the start (17684) and end (18832) nodes, we can ask pgRouting to compute the route:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;osm=# select tn.name, p.edge_id, tn.symbol from trail_network tn, (select edge_id from shortest_path('&lt;br /&gt;osm'# SELECT gid as id,&lt;br /&gt;osm'# source,&lt;br /&gt;osm'# target,&lt;br /&gt;osm'# length as cost&lt;br /&gt;osm'# FROM trail_network',&lt;br /&gt;osm(# 17684, 18832,false,false)) p&lt;br /&gt;osm-# where p.edge_id = tn.gid;&lt;br /&gt;                name                 | edge_id |    symbol     &lt;br /&gt;-------------------------------------+---------+---------------&lt;br /&gt; Piscu Negru - Refugiul Călțun       |   41343 | blue_triangle&lt;br /&gt; Piscu Negru - Refugiul Călțun       |   41341 | blue_triangle&lt;br /&gt; Piscu Negru - Refugiul Călțun       |   41338 | blue_triangle&lt;br /&gt; Piscu Negru - Refugiul Călțun       |   41335 | blue_triangle&lt;br /&gt;[..]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If we retrieve a summary of the involved trails, we get:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;osm=# select max(tn.name), max(tn.symbol) from trail_network tn, (select edge_id from shortest_path('&lt;br /&gt;osm'# SELECT gid as id,&lt;br /&gt;osm'# source,&lt;br /&gt;osm'# target,&lt;br /&gt;osm'# length as cost&lt;br /&gt;osm'# FROM trail_network',&lt;br /&gt;osm(# 17684, 18832,false,false)) p&lt;br /&gt;osm-# where p.edge_id = tn.gid group by tn.name;&lt;br /&gt;                 max                 |      max      &lt;br /&gt;-------------------------------------+---------------&lt;br /&gt; Piscu Negru - Refugiul Călțun       | blue_triangle&lt;br /&gt; Lacul Călțun - Tunel Transfăgărășan | blue_cross&lt;br /&gt; Traseu creasta                      | red_stripe&lt;br /&gt;(3 rows)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-afy9-puTthc/Tl-vssbLAEI/AAAAAAAAEL0/MLjSs93rRyQ/s1600/negoiu_route.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 382px;" src="http://3.bp.blogspot.com/-afy9-puTthc/Tl-vssbLAEI/AAAAAAAAEL0/MLjSs93rRyQ/s400/negoiu_route.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5647425640120123458" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;While the choice of the blue cross trail might look weird, it happens because in this particular section, the blue cross trail shares the same path as the blue triangle trail. From the routing engine's point of view, they are perfectly equivalent but a human might argue that the correct trail sequencing would be "Piscu Negru - Refugiul Caltun" following the blue triangle and then the ridge trail following the red stripe up to Negoiu.&lt;br /&gt;&lt;br /&gt;You can also use the driving distance functions from pgRouting.&lt;br /&gt;This is a colormap showing a classification of reachable places starting from Cabana Piscul Negru:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-rmZAxolAHO0/TmC0lT-qGsI/AAAAAAAAEME/147FfSzV8Uc/s1600/colormap.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 283px;" src="http://2.bp.blogspot.com/-rmZAxolAHO0/TmC0lT-qGsI/AAAAAAAAEME/147FfSzV8Uc/s400/colormap.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5647712485833841346" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-4186830597132870336?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/4186830597132870336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=4186830597132870336' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4186830597132870336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4186830597132870336'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/09/using-pgrouting-to-compute-routes-on.html' title='Using pgRouting to compute routes on OSM hiking trails'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-upS8UlODpV4/Tl-XskP623I/AAAAAAAAELk/ZDiMEPEpZJk/s72-c/nonterminal.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-1375052167905579537</id><published>2011-08-19T19:08:00.006+03:00</published><updated>2011-08-19T19:35:53.087+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Piatra Craiului'/><category scheme='http://www.blogger.com/atom/ns#' term='gis'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><title type='text'>Piatra Craiului mashup</title><content type='html'>A mashup of the OpenStreetMap hiking trails displayed in Google Earth:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/--seBgnkNRlM/Tk6KrvICVbI/AAAAAAAAEHg/J8_wE_NgcWo/s1600/Screen%2Bshot%2B2011-08-19%2Bat%2B7.05.20%2BPM.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 193px;" src="http://1.bp.blogspot.com/--seBgnkNRlM/Tk6KrvICVbI/AAAAAAAAEHg/J8_wE_NgcWo/s400/Screen%2Bshot%2B2011-08-19%2Bat%2B7.05.20%2BPM.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5642599867130992050" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I've initially experimented with displaying the actual OSM tiles over Google Earth (that automatically maps them using the terrain's altitude profile) but I obtained mixed results - for one, the tiles overlapped the satellite imagery displayed by GE and, most annoyingly, I didn't manage to find a way to correctly match GE's bounding box request to OSM's discrete zoom levels.&lt;br /&gt;If you're interested in displaying the OSM tiles over GE, check out &lt;a href="http://www.markus-bader.de/?p=14"&gt;Markus Bader's OpenStreetMapLayer.kmz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I've instead displayed the vector version of the trails (linestrings and icons) using a Python script that extracts data from my local OSM Postgresql database. The script runs as a CGI and exports a bounding box worth of data to Google Earth using the &lt;a href="http://code.google.com/apis/kml/documentation/kmlreference.html#networklink"&gt;KML NetworkLink&lt;/a&gt; feature.&lt;br /&gt;&lt;br /&gt;Hacky code sample follows (builds the KML Placemarks for the OSM tourism points of interest):&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;def poisFromBBOX(east,west,south,north):&lt;br /&gt;        result = ""&lt;br /&gt;        conn = psycopg2.connect("dbname=...")&lt;br /&gt;        cur = conn.cursor()&lt;br /&gt;        stmt = cur.mogrify('select name,tourism, st_astext(transform(way, 4326)) from planet_osm_point where tourism is not null and st_contains(st_transform(ST_SetSRID(ST_MakeBox2D(ST_Point(%s, %s), ST_Point(%s, %s)), 4326), 900913), way)', (east, south, west, north))&lt;br /&gt;        cur.execute(stmt)&lt;br /&gt;        tl = cur.fetchall()&lt;br /&gt;        for item in tl:&lt;br /&gt;                name = item[0]               &lt;br /&gt;                if name == None:                        &lt;br /&gt;                    continue&lt;br /&gt;                tourism = item[1]                &lt;br /&gt;                point = item[2]                &lt;br /&gt;                m = re.search('(?&amp;lt;=POINT\()([0-9.]+) ([0-9.]+)', str(point))&lt;br /&gt;                result = result + '&amp;lt;Placemark&gt;&amp;lt;styleUrl&gt;#myStyleMap&amp;lt;/styleUrl&gt;&amp;lt;name&gt;' + escape(str(name))  + '&lt;/name&gt;&amp;lt;description&gt;OSM tourism: ' + escape(str(tourism)) + '&amp;lt;/description&gt;&amp;lt;Point&gt;&amp;lt;coordinates&gt;' + str(m.group(1)) + ',' + str(m.group(2)) + ',0&amp;lt;/coordinates&gt;&amp;lt;/Point&gt;&amp;lt;/Placemark&gt;'&lt;br /&gt;        cur.close()&lt;br /&gt;        conn.close()&lt;br /&gt;        return result&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-1375052167905579537?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/1375052167905579537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=1375052167905579537' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1375052167905579537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1375052167905579537'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/08/piatra-craiului-mashup.html' title='Piatra Craiului mashup'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/--seBgnkNRlM/Tk6KrvICVbI/AAAAAAAAEHg/J8_wE_NgcWo/s72-c/Screen%2Bshot%2B2011-08-19%2Bat%2B7.05.20%2BPM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-4731912624620045618</id><published>2011-08-16T15:52:00.007+03:00</published><updated>2011-08-16T21:54:20.415+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Piatra Craiului'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='hiking'/><title type='text'>Symbol reference in Piatra Craiului</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-jRxMVeZMVXE/TkpxALI55II/AAAAAAAAEHY/NI_xhMuoJW4/s1600/test3_fused.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 150px;" src="http://2.bp.blogspot.com/-jRxMVeZMVXE/TkpxALI55II/AAAAAAAAEHY/NI_xhMuoJW4/s400/test3_fused.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5641445731039044738" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Around Refugiul Diana&lt;/h3&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1708809&amp;zone=Piatra%20Craiului&amp;traseu=Valea%20Urșilor%20-%20Refugiul%20Diana"&gt;Valea Urșilor - Refugiul Diana (2h from the road, 2.5 h from Plaiul Foii)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-w8lAcW9CKM4/Tkpoi8JZR8I/AAAAAAAAEHA/ggo6b7OmkSE/s1600/IMAG0203.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://1.bp.blogspot.com/-w8lAcW9CKM4/Tkpoi8JZR8I/AAAAAAAAEHA/ggo6b7OmkSE/s400/IMAG0203.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5641436432705341378" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1668044&amp;zone=Piatra%20Craiului&amp;traseu=Padina%20Popii"&gt;Padina Popii (1.5-2h)&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-cj01razCAqk/TkpojABbfvI/AAAAAAAAEHQ/pZcvy0jrIB8/s1600/IMAG0205.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://4.bp.blogspot.com/-cj01razCAqk/TkpojABbfvI/AAAAAAAAEHQ/pZcvy0jrIB8/s400/IMAG0205.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5641436433745673970" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1668041&amp;zone=Piatra%20Craiului&amp;traseu=Brâna%20Caprelor"&gt;Brâna Caprelor (2h to Șaua Padinei Închise)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-xBcT5vq-MWo/Tkpoi-qecvI/AAAAAAAAEHI/fSsvd3p1RAg/s1600/IMAG0204.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://2.bp.blogspot.com/-xBcT5vq-MWo/Tkpoi-qecvI/AAAAAAAAEHI/fSsvd3p1RAg/s400/IMAG0204.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5641436433380963058" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;La Zaplaz, on the trail leading to La Om&lt;/h3&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1708830&amp;zone=Piatra%20Craiului&amp;traseu=Plaiul%20Foii%20-%20Refugiul%20Șpirla%20-%20La%20Zaplaz%20-%20La%20Lanțuri%20-%20Vârful%20La%20Om"&gt;Plaiul Foii - Refugiul Șpirla - La Zaplaz - La Lanțuri - Vârful La Om (5-6 h)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-ptD9DevHPZM/TkpoX3odtBI/AAAAAAAAEGo/3i4v99gX2JU/s1600/IMAG0199.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 267px; height: 400px;" src="http://1.bp.blogspot.com/-ptD9DevHPZM/TkpoX3odtBI/AAAAAAAAEGo/3i4v99gX2JU/s400/IMAG0199.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5641436242514916370" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;La Om peak&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-lRpdlzOmlls/TkpoYPM6jfI/AAAAAAAAEG4/WuGdZMfjBcQ/s1600/IMAG0201.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 267px; height: 400px;" src="http://3.bp.blogspot.com/-lRpdlzOmlls/TkpoYPM6jfI/AAAAAAAAEG4/WuGdZMfjBcQ/s400/IMAG0201.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5641436248841817586" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Around Plaiul Foii&lt;/h3&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1708831&amp;zone=Piatra%20Craiului&amp;traseu=Plaiul%20Foii%20-%20Vârful%20Tămașul%20Mare"&gt;Plaiul Foii - Vârful Tămașul Mare&lt;/a&gt; Note: this trail is not marked all the way to Tămașul Mare - in my survey August 2011 the yellow stripe marking disappears in a big heath.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-IR2Dqtwtddk/TkpoYPUUyfI/AAAAAAAAEGw/CtFOdE_tOBA/s1600/IMAG0200.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 267px; height: 400px;" src="http://1.bp.blogspot.com/-IR2Dqtwtddk/TkpoYPUUyfI/AAAAAAAAEGw/CtFOdE_tOBA/s400/IMAG0200.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5641436248872897010" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-xwglhD2PGmo/TkpoXxaBvnI/AAAAAAAAEGg/aUpUaSq3S_A/s1600/IMAG0195.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://1.bp.blogspot.com/-xwglhD2PGmo/TkpoXxaBvnI/AAAAAAAAEGg/aUpUaSq3S_A/s400/IMAG0195.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5641436240843751026" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Trail leading to Făgăraș (leaves Plaiul Foii by following the road on the bank of Bârsa Groșetului)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-GE-DiCdI7XE/TkpoXswAFDI/AAAAAAAAEGY/87g3QOjZ-c8/s1600/IMAG0194.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://3.bp.blogspot.com/-GE-DiCdI7XE/TkpoXswAFDI/AAAAAAAAEGY/87g3QOjZ-c8/s400/IMAG0194.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5641436239593739314" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-4731912624620045618?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/4731912624620045618/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=4731912624620045618' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4731912624620045618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4731912624620045618'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/08/symbol-reference-in-piatra-craiului.html' title='Symbol reference in Piatra Craiului'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-jRxMVeZMVXE/TkpxALI55II/AAAAAAAAEHY/NI_xhMuoJW4/s72-c/test3_fused.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-7428901797330744133</id><published>2011-07-28T20:21:00.004+03:00</published><updated>2011-07-28T20:31:47.351+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='postgis'/><category scheme='http://www.blogger.com/atom/ns#' term='geometry'/><title type='text'>Java Topology Suite</title><content type='html'>If you're looking for a way to visually check geometries, their validity, intersections and so on, the &lt;a href="http://sourceforge.net/projects/jts-topo-suite/"&gt;Java Topology Suite&lt;/a&gt; might be a very good idea.&lt;br /&gt;&lt;br /&gt;It runs out of the box on Mac OS X (checked on 10.6.8) but you do have to run &lt;i&gt;testbuilder.sh&lt;/i&gt; yourself (from the &lt;i&gt;bin&lt;/i&gt; directory of the JTS distribution).&lt;br /&gt;&lt;br /&gt;You can paste geometries out of &lt;i&gt;postgis&lt;/i&gt; directly (by using &lt;i&gt;st_asekwt&lt;/i&gt; and stripping out the SRID definition).&lt;br /&gt;Just as &lt;i&gt;postgis&lt;/i&gt;, it conforms to the Simple Features Specification for SQL published by the Open GIS Consortium so overlapping, crossing, and so on have the same meanings.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-3q3JVB2ME9k/TjGbwICZ0JI/AAAAAAAAEA8/7RtmykZXYsg/s1600/jts.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 331px;" src="http://1.bp.blogspot.com/-3q3JVB2ME9k/TjGbwICZ0JI/AAAAAAAAEA8/7RtmykZXYsg/s400/jts.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5634455859910791314" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-7428901797330744133?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/7428901797330744133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=7428901797330744133' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7428901797330744133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7428901797330744133'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/07/java-topology-suite.html' title='Java Topology Suite'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-3q3JVB2ME9k/TjGbwICZ0JI/AAAAAAAAEA8/7RtmykZXYsg/s72-c/jts.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-9134854006023858983</id><published>2011-07-28T10:37:00.004+03:00</published><updated>2011-07-28T10:44:46.261+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clang'/><category scheme='http://www.blogger.com/atom/ns#' term='llvm'/><title type='text'>Cling, the interactive C++ interpreter</title><content type='html'>Some folks from CERN and Fermilab are working on &lt;a href="http://cern.ch/cling"&gt;cling&lt;/a&gt;, a C++ interpreter based on llvm and clang.&lt;br /&gt;&lt;br /&gt;It works as advertised (you have to build it as part of the llvm tree, near clang) and it's amazingly cool:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;llvm diciu$ ./Release+Asserts/bin/cling &lt;br /&gt;&lt;br /&gt;**** Welcome to the cling prototype! ****&lt;br /&gt;* Type C code and press enter to run it *&lt;br /&gt;* Type .q, exit or ctrl+D to quit       *&lt;br /&gt;*****************************************&lt;br /&gt;[cling]$ FILE * f = fopen("/dev/random", "r");&lt;br /&gt;[cling]$ unsigned char rnd;&lt;br /&gt;[cling]$ int i=0;&lt;br /&gt;[cling]$ while(++i&lt;10) { fread(&amp;rnd, sizeof(rnd), 1, f); printf("%03d\n", rnd); }&lt;br /&gt;201&lt;br /&gt;161&lt;br /&gt;186&lt;br /&gt;086&lt;br /&gt;056&lt;br /&gt;092&lt;br /&gt;125&lt;br /&gt;063&lt;br /&gt;203&lt;br /&gt;[cling]$ .q&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/31740253-9134854006023858983?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/9134854006023858983/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=9134854006023858983' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/9134854006023858983'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/9134854006023858983'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/07/cling-interactive-c-interpreter.html' title='Cling, the interactive C++ interpreter'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-709022404862480610</id><published>2011-07-22T21:07:00.002+03:00</published><updated>2011-07-22T21:19:39.275+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x-alps'/><title type='text'>Red Bull X-Alps 2011</title><content type='html'>Unbelievable effort by everyone involved in the X-Alps competition.&lt;br /&gt;In a single day today Christian Maurer flew some 350 Km leaving Romanian Toma Coconea 150 Km behind.&lt;br /&gt;&lt;br /&gt;&lt;iframe width="620" height="352" scrolling="no" frameborder="0" name="redbullxalps-livetracking-preview" src="http://www.redbullxalps.com/redbullxalps-iframe.html" &gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-709022404862480610?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/709022404862480610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=709022404862480610' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/709022404862480610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/709022404862480610'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/07/red-bull-x-alps-2011.html' title='Red Bull X-Alps 2011'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-1697801804459207681</id><published>2011-07-16T22:50:00.009+03:00</published><updated>2011-07-28T14:46:28.650+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Piatra Craiului'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='hiking'/><title type='text'>OSMC symbol reference for Piatra Craiului around Șaua Padinei Închise (surveyed July 2011)</title><content type='html'>Updates on final section of the southern blue stripe trail: &lt;br /&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1556151&amp;zone=Piatra%20Craiului&amp;traseu=Zărnești%20-%20Prăpăstiile%20Zărneștiului%20-%20Curmătura%20-%20Șaua%20Padinei%20Închise"&gt;Curmătura-Șaua Padinei Închise&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I've added relations for a couple of trails (both linking &lt;i&gt;Refugiul Diana&lt;/i&gt; to &lt;i&gt;Vârful Turnu&lt;/i&gt;) on the northern side based on existing OSM ways:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1668041&amp;zone=Piatra%20Craiului&amp;traseu=Brâna%20Caprelor"&gt;Brâna Caprelor&lt;/a&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1668044&amp;zone=Piatra%20Craiului&amp;traseu=Padina%20Popii"&gt;Padina Popii&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Șaua Padinei Închise:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-5ilyEAo76LE/TiHsR8vvADI/AAAAAAAAD-4/zYGgNfvEGPs/s1600/IMAG0180.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 267px;" src="http://2.bp.blogspot.com/-5ilyEAo76LE/TiHsR8vvADI/AAAAAAAAD-4/zYGgNfvEGPs/s400/IMAG0180.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5630040802298101810" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-iLSNVzjFGhA/TiHsSEcoEEI/AAAAAAAAD_A/ZJgSFws23vc/s1600/IMAG0181.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 267px;" src="http://4.bp.blogspot.com/-iLSNVzjFGhA/TiHsSEcoEEI/AAAAAAAAD_A/ZJgSFws23vc/s400/IMAG0181.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5630040804365439042" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Vârful Turnu:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-y-DhYKagD8w/TiHsSbBx3sI/AAAAAAAAD_Q/UVNd_Xi7nYo/s1600/IMAG0183.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 267px;" src="http://2.bp.blogspot.com/-y-DhYKagD8w/TiHsSbBx3sI/AAAAAAAAD_Q/UVNd_Xi7nYo/s400/IMAG0183.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5630040810426851010" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-TV9dkxu7Rbw/TiHsSYnLWeI/AAAAAAAAD_I/qqWAoFDKskc/s1600/IMAG0182.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 267px;" src="http://4.bp.blogspot.com/-TV9dkxu7Rbw/TiHsSYnLWeI/AAAAAAAAD_I/qqWAoFDKskc/s400/IMAG0182.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5630040809778403810" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-xwcZtWwA3pk/TiHsS31tc0I/AAAAAAAAD_Y/fViDO5DuFIc/s1600/IMAG0186.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 267px; height: 400px;" src="http://4.bp.blogspot.com/-xwcZtWwA3pk/TiHsS31tc0I/AAAAAAAAD_Y/fViDO5DuFIc/s400/IMAG0186.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5630040818160857922" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Descent through Padina Șindrilăriei:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-5OnsPo7wlGE/TiMKcXkjDfI/AAAAAAAAD_g/nx9ZEEYspu8/s1600/IMAG0184.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 267px;" src="http://2.bp.blogspot.com/-5OnsPo7wlGE/TiMKcXkjDfI/AAAAAAAAD_g/nx9ZEEYspu8/s400/IMAG0184.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5630355441623174642" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-1697801804459207681?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/1697801804459207681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=1697801804459207681' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1697801804459207681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1697801804459207681'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/07/osmc-symbol-reference-for-piatra.html' title='OSMC symbol reference for Piatra Craiului around Șaua Padinei Închise (surveyed July 2011)'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-5ilyEAo76LE/TiHsR8vvADI/AAAAAAAAD-4/zYGgNfvEGPs/s72-c/IMAG0180.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-7553310622669217388</id><published>2011-06-18T21:48:00.004+03:00</published><updated>2011-06-27T11:17:25.057+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='hiking'/><title type='text'>OSMC symbol reference for Piatra Craiului around Cabana Curmătura (surveyed June 2011)</title><content type='html'>Signs towards the east:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-fyfW24MPqOM/TfzzixaFQ0I/AAAAAAAAD-A/epSZb6fUDt0/s1600/IMAG0165.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 267px; height: 400px;" src="http://3.bp.blogspot.com/-fyfW24MPqOM/TfzzixaFQ0I/AAAAAAAAD-A/epSZb6fUDt0/s400/IMAG0165.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5619634213755372354" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-lKkwG9j1ras/Tfzzl2djEOI/AAAAAAAAD-I/nbnrmddKBDs/s1600/IMAG0167.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 267px; height: 400px;" src="http://1.bp.blogspot.com/-lKkwG9j1ras/Tfzzl2djEOI/AAAAAAAAD-I/nbnrmddKBDs/s400/IMAG0167.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5619634266651693282" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Signs towards the west:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-lOiGJJdjngw/Tfzzma6hq5I/AAAAAAAAD-Q/orEidnhFHIk/s1600/IMAG0170.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 267px; height: 400px;" src="http://1.bp.blogspot.com/-lOiGJJdjngw/Tfzzma6hq5I/AAAAAAAAD-Q/orEidnhFHIk/s400/IMAG0170.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5619634276436913042" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Intersection where the red cross trail leaves the track going through Prăpăstiile Zărneștilor:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-uMsV8UW_OtE/Tfzzm_MEjxI/AAAAAAAAD-Y/lkFXAMEyV2Q/s1600/IMAG0174.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 267px; height: 400px;" src="http://2.bp.blogspot.com/-uMsV8UW_OtE/Tfzzm_MEjxI/AAAAAAAAD-Y/lkFXAMEyV2Q/s400/IMAG0174.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5619634286174179090" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Part of the blue dot trail leading from Șaua Crăpăturii towards Piatra Craiului Mică peak:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-373njd2zYAg/Tgg7uVDfeiI/AAAAAAAAD-w/3wa36ZrA-j4/s1600/DSC_0027.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://3.bp.blogspot.com/-373njd2zYAg/Tgg7uVDfeiI/AAAAAAAAD-w/3wa36ZrA-j4/s400/DSC_0027.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5622809801883875874" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-7553310622669217388?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/7553310622669217388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=7553310622669217388' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7553310622669217388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7553310622669217388'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/06/osmc-symbol-reference-for-piatra.html' title='OSMC symbol reference for Piatra Craiului around Cabana Curmătura (surveyed June 2011)'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-fyfW24MPqOM/TfzzixaFQ0I/AAAAAAAAD-A/epSZb6fUDt0/s72-c/IMAG0165.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-4990260725179191438</id><published>2011-05-30T07:48:00.002+03:00</published><updated>2011-05-30T11:06:01.139+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='hiking'/><title type='text'>Hiking trails in Iezer</title><content type='html'>Signpost where the blue dot trail leaves the blue cross trail:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-1JB6ZlNLFcE/TeMh62HucEI/AAAAAAAAD8o/NmRC5W0LWw0/s1600/IMAG0145.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 312px; height: 400px;" src="http://3.bp.blogspot.com/-1JB6ZlNLFcE/TeMh62HucEI/AAAAAAAAD8o/NmRC5W0LWw0/s400/IMAG0145.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5612366855477817410" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Signpost at convergence of blue dot and blue cross trails, very close to Iezer shelter:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-xTLJ6GfDaps/TeMh_ExdZCI/AAAAAAAAD8w/37BlaLBZUDU/s1600/IMAG0151.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 266px; height: 400px;" src="http://3.bp.blogspot.com/-xTLJ6GfDaps/TeMh_ExdZCI/AAAAAAAAD8w/37BlaLBZUDU/s400/IMAG0151.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5612366928130434082" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Sign at the Iezer shelter, indicating distance to Crucea Ateneului (located by the ridge trail):&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-o3bRK0RVVYU/TeMiDgeyeLI/AAAAAAAAD84/1C7SDVOoxGg/s1600/IMAG0152.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 266px; height: 400px;" src="http://2.bp.blogspot.com/-o3bRK0RVVYU/TeMiDgeyeLI/AAAAAAAAD84/1C7SDVOoxGg/s400/IMAG0152.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5612367004287793330" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Sign on the main ridge trail (marked with a red stripe -&gt; left(south east) towards Cabana Voina by Văcarea, right (north west) towards Iezer and Roșu peaks):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-8dijK52662U/TeMigt5ld9I/AAAAAAAAD9A/b1wp72-l70s/s1600/IMAG0153.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 267px;" src="http://1.bp.blogspot.com/-8dijK52662U/TeMigt5ld9I/AAAAAAAAD9A/b1wp72-l70s/s400/IMAG0153.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5612367506106054610" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;View of Iezer Lake and shelter from Crucea Ateneului:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-wQsx1W53NQc/TeMj3pNKp1I/AAAAAAAAD9Q/CPj9dQ1ID78/s1600/DSC_0125.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://2.bp.blogspot.com/-wQsx1W53NQc/TeMj3pNKp1I/AAAAAAAAD9Q/CPj9dQ1ID78/s400/DSC_0125.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5612368999494625106" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-41Pm-SKu1Lg/TeMj3QCMUaI/AAAAAAAAD9I/TD9SlmWlxN8/s1600/DSC_0124.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://3.bp.blogspot.com/-41Pm-SKu1Lg/TeMj3QCMUaI/AAAAAAAAD9I/TD9SlmWlxN8/s400/DSC_0124.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5612368992737710498" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Views from the shelter:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-DlRJGfLHnEE/TeMj34l4NkI/AAAAAAAAD9g/llkU7iwFyCI/s1600/DSC_0138.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://1.bp.blogspot.com/-DlRJGfLHnEE/TeMj34l4NkI/AAAAAAAAD9g/llkU7iwFyCI/s400/DSC_0138.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5612369003624805954" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-YegEUxSlVHY/TeMj3pkfI6I/AAAAAAAAD9Y/LiUw5D5jevE/s1600/DSC_0135.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://3.bp.blogspot.com/-YegEUxSlVHY/TeMj3pkfI6I/AAAAAAAAD9Y/LiUw5D5jevE/s400/DSC_0135.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5612368999592436642" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Updated trails:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1476076&amp;zone=Iezer&amp;traseu=Cabana%20Voina%20-%20Lacul%20și%20Refugiul%20Iezer%20%28prin%20jepi%29"&gt;Cabana Voina - Lacul și Refugiul Iezer (prin jepi)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1604612&amp;zone=Iezer&amp;traseu=Voina%20-%20Cabana%20Cuca%20-%20Vârful%20Păpușa"&gt;Voina - Cabana Cuca - Vârful Păpușa&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1604620&amp;zone=Iezer&amp;traseu=Voina%20-%20Culmea%20Văcarea%20-%20Crucea%20Ateneului%20-%20Vârful%20Iezer"&gt;Voina - Culmea Văcarea - Crucea Ateneului - Vârful Iezer&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1604356&amp;zone=Iezer&amp;traseu=Cabana%20Voina%20-%20Lacul%20și%20Refugiul%20Iezer%20prin%20stâna%20din%20Iezer"&gt;Cabana Voina - Lacul și Refugiul Iezer prin stâna din Iezer&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-4990260725179191438?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/4990260725179191438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=4990260725179191438' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4990260725179191438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4990260725179191438'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/05/hiking-trails-in-iezer.html' title='Hiking trails in Iezer'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-1JB6ZlNLFcE/TeMh62HucEI/AAAAAAAAD8o/NmRC5W0LWw0/s72-c/IMAG0145.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5197923031887452575</id><published>2011-05-15T07:50:00.006+03:00</published><updated>2011-05-27T07:50:34.604+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='hiking'/><title type='text'>Updates on hiking trails in Cozia</title><content type='html'>&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1586103&amp;zone=Cozia&amp;traseu=Căciulata%20-%20Valea%20Păușa%20-%20Mănăstirea%20Stânișoara"&gt;Căciulata - Valea Păușa - Mănăstirea Stânișoara&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1586104&amp;zone=Cozia&amp;traseu=Căciulata%20-%20Satul%20Păușa%20-%20Șaua%20%22La%20Troiță%22%20-%20Mănăstirea%20Stânișoara%20-%20Muchia%20Vlădesei%20-%20Muntele%20Durduc%20-%20Cabana%20Cozia"&gt;Căciulata - Satul Păușa - Șaua "La Troiță" - Mănăstirea Stânișoara - Muchia Vlădesei - Muntele Durduc - Cabana Cozia (incomplete)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1586102&amp;zone=Cozia&amp;traseu=Poiana%20Stânișoara%20-%20Cascada%20Gardului"&gt;Poiana Stânișoara - Cascada Gardului&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Trail signs at Mănăstirea Stânișoara:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-qg1WdzqlGIE/Tc9cNwKiJbI/AAAAAAAAD8Q/Ldzpf79Y84E/s1600/IMAG0136.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 297px;" src="http://3.bp.blogspot.com/-qg1WdzqlGIE/Tc9cNwKiJbI/AAAAAAAAD8Q/Ldzpf79Y84E/s400/IMAG0136.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5606801452436694450" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-qnTK6A698qM/Tc9c9tT8mFI/AAAAAAAAD8Y/3oOFzEXqzLQ/s1600/IMAG0137.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 245px;" src="http://4.bp.blogspot.com/-qnTK6A698qM/Tc9c9tT8mFI/AAAAAAAAD8Y/3oOFzEXqzLQ/s400/IMAG0137.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5606802276304590930" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Cascada Gardului&lt;/h3&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-oGegvl_LGR0/Td8tXAL_IzI/AAAAAAAAD8g/_sj4j9MA9Gk/s1600/DSC_0056.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 266px; height: 400px;" src="http://1.bp.blogspot.com/-oGegvl_LGR0/Td8tXAL_IzI/AAAAAAAAD8g/_sj4j9MA9Gk/s400/DSC_0056.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5611253533937443634" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-5197923031887452575?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5197923031887452575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5197923031887452575' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5197923031887452575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5197923031887452575'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/05/updates-on-hiking-trails-in-cozia.html' title='Updates on hiking trails in Cozia'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-qg1WdzqlGIE/Tc9cNwKiJbI/AAAAAAAAD8Q/Ldzpf79Y84E/s72-c/IMAG0136.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-3990934859636747247</id><published>2011-05-10T07:59:00.009+03:00</published><updated>2011-05-11T12:41:59.009+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='hiking'/><title type='text'>Mălaia - Vârful Zmeureț</title><content type='html'>A 4 hour trail in Munții Căpătânii, demanding because of the altitude gain (you climb from 500 m to 1900 m).&lt;br /&gt;&lt;br /&gt;The trail is fairly well marked, but has not been maintained recently (surveyed May 2011) so there are some areas that have been covered by fallen trees where the trail is easily lost.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-_u9tlEhetac/TcjIlsV6Z8I/AAAAAAAAD8A/1OB3JQcWy3k/s1600/DSC_0183.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://3.bp.blogspot.com/-_u9tlEhetac/TcjIlsV6Z8I/AAAAAAAAD8A/1OB3JQcWy3k/s400/DSC_0183.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5604950286146365378" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-1r2sRIGpEbI/TcjIfOBB6ZI/AAAAAAAAD74/8YJWVETNwyQ/s1600/DSC_0124.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://4.bp.blogspot.com/-1r2sRIGpEbI/TcjIfOBB6ZI/AAAAAAAAD74/8YJWVETNwyQ/s400/DSC_0124.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5604950174926498194" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-ZX7PZzuDymA/TcjIY57X4mI/AAAAAAAAD7w/2-x3TQuz5Pc/s1600/DSC_0118.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://1.bp.blogspot.com/-ZX7PZzuDymA/TcjIY57X4mI/AAAAAAAAD7w/2-x3TQuz5Pc/s400/DSC_0118.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5604950066454848098" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-yXDoaC7xBc0/TcjNK2eUVzI/AAAAAAAAD8I/lI6sVtu0HN0/s1600/panorama.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 126px;" src="http://2.bp.blogspot.com/-yXDoaC7xBc0/TcjNK2eUVzI/AAAAAAAAD8I/lI6sVtu0HN0/s400/panorama.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5604955322567644978" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've added the trail relation in openstreetmap, see here: &lt;a href="http://gis.modulo.ro:8080/hiking/hiking.html?rel=1577445&amp;zone=Munții%20Căpătânii&amp;traseu=Mălaia%20-%20Vârful%20Zmeureț"&gt;Mălaia - Vârful Zmeureț&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-3990934859636747247?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/3990934859636747247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=3990934859636747247' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3990934859636747247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3990934859636747247'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/05/malaia-varful-zmeuret.html' title='Mălaia - Vârful Zmeureț'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-_u9tlEhetac/TcjIlsV6Z8I/AAAAAAAAD8A/1OB3JQcWy3k/s72-c/DSC_0183.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-1581871361756067466</id><published>2011-05-05T15:53:00.004+03:00</published><updated>2011-05-06T07:31:52.481+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tesseract'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='ocr'/><title type='text'>Using TesseractGUI with other languages (non English)</title><content type='html'>It is possible to use &lt;a href="http://blog.loudhush.ro/2009/02/tesseract-gui.html"&gt;TesseractGUI 0.3&lt;/a&gt; to do OCR on other languages but you have to download the language pack for the required language and install it as part of the TesseractGUI application bundle.&lt;br /&gt;&lt;br /&gt;E.g. for German:&lt;br /&gt;&lt;br /&gt;1/ Download the German training data (e.g. http://code.google.com/p/tesseract-ocr/downloads/detail?name=deu.traineddata.gz&amp;can=2&amp;q=)&lt;br /&gt;&lt;br /&gt;2/ The archive will expand into a file called &lt;i&gt;deu.traineddata&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;3/ Copy the &lt;i&gt;deu.traineddata&lt;/i&gt; inside the TesseractGUI application bundle, under &lt;i&gt;Contents/Resources/tessdata/&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;4/ Configure TesseractGUI to use the language pack (Set &lt;i&gt;Preferences-&gt;Custom language spec&lt;/i&gt; to read &lt;i&gt;deu&lt;/i&gt;)&lt;br /&gt;&lt;br /&gt;5/ Load a TIFF file containing a scan of something written in German.&lt;br /&gt;&lt;br /&gt;That should be it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-1581871361756067466?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/1581871361756067466/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=1581871361756067466' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1581871361756067466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1581871361756067466'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/05/using-tesseractgui-with-other-languages.html' title='Using TesseractGUI with other languages (non English)'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-7252074272460102379</id><published>2011-04-26T07:29:00.011+03:00</published><updated>2011-04-26T08:02:18.991+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Piatra Craiului'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='hiking'/><title type='text'>Updates on hiking trails in Piatra Craiului (surveyed Apr 2011)</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-BCARVQeOSh0/TbZKYVGZ6oI/AAAAAAAAD64/eoRHeyxehek/s1600/IMAG0115.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 214px; height: 320px;" src="http://3.bp.blogspot.com/-BCARVQeOSh0/TbZKYVGZ6oI/AAAAAAAAD64/eoRHeyxehek/s320/IMAG0115.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5599744968523115138" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hiking relations for:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1556151&amp;zone=Piatra%20Craiului&amp;traseu=Zărnești%20-%20Prăpăstiile%20Zărneștiului%20-%20Curmătura"&gt;Zărnești - Prăpăstiile Zărneștiului - Curmătura (incomplete)&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1556150&amp;zone=Piatra%20Craiului&amp;traseu=Zărnești%20-%20Prăpăstiile%20Zărneștiului%20-%20Cheile%20Pisicii%20-%20La%20Table%20-%20Moeciu"&gt;Zărnești - Prăpăstiile Zărneștiului - Cheile Pisicii - La Table - Moeciu (incomplete)&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1555489&amp;zone=Piatra%20Craiului&amp;traseu=Zărnești%20-%20Botorog%20-%20Zănoaga%20-%20Curmătura"&gt;Zărnești - Botorog - Zănoaga - Curmătura&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Intersection near Fântâna lui Botorog where Curmătura trail leaves the road:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-2bnVj_kD2OM/TbZMRhgwzSI/AAAAAAAAD7I/QgNwgf9VLYM/s1600/IMAG0117.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 214px; height: 320px;" src="http://3.bp.blogspot.com/-2bnVj_kD2OM/TbZMRhgwzSI/AAAAAAAAD7I/QgNwgf9VLYM/s320/IMAG0117.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5599747050619063586" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;From the trail towards cabana Curmătura a trail marked with a blue dot opens up towards Piatra Mică peak:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1555488&amp;zone=Piatra%20Craiului&amp;traseu=Poiana%20Zănoaga%20-%20Vârful%20Piatra%20Mică%20-%20Șaua%20Crăpăturii"&gt;Poiana Zănoaga - Vârful Piatra Mică - Șaua Crăpăturii&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-YiX-fjhpcV4/TbZMzTy6FYI/AAAAAAAAD7Q/-uvsBILzGXM/s1600/IMAG0119.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 214px; height: 320px;" src="http://4.bp.blogspot.com/-YiX-fjhpcV4/TbZMzTy6FYI/AAAAAAAAD7Q/-uvsBILzGXM/s320/IMAG0119.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5599747631052625282" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;On the trail to Piatra Mică there's a beautiful vantage point (called "Crucea din Carpați and marked by a couple of crosses) offering spectacular views of the surroundings:&lt;br /&gt;&lt;br /&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-3r5JWnl64tc/TbZQAvrN-VI/AAAAAAAAD7Y/hYTOPowltB8/s1600/DSC_0128.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 133px;" src="http://4.bp.blogspot.com/-3r5JWnl64tc/TbZQAvrN-VI/AAAAAAAAD7Y/hYTOPowltB8/s200/DSC_0128.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5599751160409749842" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-yFThq3xZyGw/TbZQGmHOHvI/AAAAAAAAD7g/GBFTt6LG9iQ/s1600/DSC_0130.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 133px;" src="http://1.bp.blogspot.com/-yFThq3xZyGw/TbZQGmHOHvI/AAAAAAAAD7g/GBFTt6LG9iQ/s200/DSC_0130.jpg" border="0" alt="Piatra Craiului ridge" id="BLOGGER_PHOTO_ID_5599751260922060530" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-CtLo2NwODQY/TbZQL9qrLbI/AAAAAAAAD7o/XtI01buXxDw/s1600/DSC_0142.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 133px;" src="http://3.bp.blogspot.com/-CtLo2NwODQY/TbZQL9qrLbI/AAAAAAAAD7o/XtI01buXxDw/s200/DSC_0142.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5599751353144126898" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Trail reference:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-bZdP8G1yGiQ/TbZMKZypY-I/AAAAAAAAD7A/WgBsmsbl7kI/s1600/IMAG0116.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 122px; height: 320px;" src="http://3.bp.blogspot.com/-bZdP8G1yGiQ/TbZMKZypY-I/AAAAAAAAD7A/WgBsmsbl7kI/s320/IMAG0116.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5599746928287507426" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-7252074272460102379?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/7252074272460102379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=7252074272460102379' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7252074272460102379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7252074272460102379'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/04/updates-on-hiking-trails-in-piatra.html' title='Updates on hiking trails in Piatra Craiului (surveyed Apr 2011)'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-BCARVQeOSh0/TbZKYVGZ6oI/AAAAAAAAD64/eoRHeyxehek/s72-c/IMAG0115.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-829207891325249941</id><published>2011-03-28T11:53:00.005+03:00</published><updated>2011-03-29T09:31:49.429+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gis'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='hiking'/><title type='text'>Update on hiking trails in Predeal area</title><content type='html'>Updates on:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1120723&amp;zone=Piatra%20Mare"&gt;Cabana Cioplea - Cabana Susai&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1112796&amp;zone=Piatra%20Mare"&gt;Cabana Cioplea - Stâna Pietricica (prin valea Timișului Sec)&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1112807&amp;zone=Piatra%20Mare"&gt;Cabana Cioplea - Cabana Susai - Cabana Piatra Mare&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-kO64ZC_FnGo/TZBMx0369vI/AAAAAAAAD6U/ku07cSdIYJ4/s1600/IMAG0099.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 213px;" src="http://4.bp.blogspot.com/-kO64ZC_FnGo/TZBMx0369vI/AAAAAAAAD6U/ku07cSdIYJ4/s320/IMAG0099.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5589051556457281266" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hiking relation for &lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1120722&amp;zone=Piatra%20Mare"&gt;Clăbucet Plecare - Cabana Susai&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-fYIz1aDYBPk/TZBNCTwuiGI/AAAAAAAAD6c/T_VloP-JYXM/s1600/IMAG0100.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 213px; height: 320px;" src="http://2.bp.blogspot.com/-fYIz1aDYBPk/TZBNCTwuiGI/AAAAAAAAD6c/T_VloP-JYXM/s320/IMAG0100.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5589051839626512482" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Updates on: &lt;a href="http://gis.modulo.ro/hiking/hiking.html?rel=1507328&amp;zone=Piatra%20Mare"&gt;Clăbucet Sosire - Cabana Gârbova - Azuga&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-b_HdLs2zMcw/TZBNIAw4uTI/AAAAAAAAD6k/omeGS2YCVtg/s1600/IMAG0101.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 212px; height: 320px;" src="http://3.bp.blogspot.com/-b_HdLs2zMcw/TZBNIAw4uTI/AAAAAAAAD6k/omeGS2YCVtg/s320/IMAG0101.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5589051937606121778" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-829207891325249941?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/829207891325249941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=829207891325249941' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/829207891325249941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/829207891325249941'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/03/update-on-hiking-trails-in-predeal-area.html' title='Update on hiking trails in Predeal area'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-kO64ZC_FnGo/TZBMx0369vI/AAAAAAAAD6U/ku07cSdIYJ4/s72-c/IMAG0099.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-6625206302684185336</id><published>2011-03-10T12:04:00.004+02:00</published><updated>2011-03-14T13:20:21.785+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='hiking'/><title type='text'>Work in progress</title><content type='html'>Proiect in lucru: web site cu OpenLayers/ExtJS pentru &lt;a href="http://gis.modulo.ro"&gt;afisare trasee montane din OpenStreetMap&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/Z4X93oLxeR8?hd=1" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-6625206302684185336?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/6625206302684185336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=6625206302684185336' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6625206302684185336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6625206302684185336'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/03/work-in-progress.html' title='Work in progress'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/Z4X93oLxeR8/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5304880350063625826</id><published>2011-02-12T08:00:00.008+02:00</published><updated>2011-02-12T08:09:43.334+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><title type='text'>OSMC symbol reference for Diham/Bușteni</title><content type='html'>This is a set of photographs of hiking symbols in Busteni - surveyed in February 2011.&lt;br /&gt;&lt;br /&gt;Description of red stripe trail on a tree on the Gura Diham - Cabana Diham trail:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-kfGtootyt6M/TVYiNXO95hI/AAAAAAAAD4U/LSkKmTwd6Uo/s1600/IMAG0081.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://3.bp.blogspot.com/-kfGtootyt6M/TVYiNXO95hI/AAAAAAAAD4U/LSkKmTwd6Uo/s320/IMAG0081.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5572679201888003602" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Trail intersection in Șaua Baiului:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-sI9dK2jVg6k/TVYikoTk24I/AAAAAAAAD4c/3S_FM1EEX80/s1600/IMAG0082.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://3.bp.blogspot.com/-sI9dK2jVg6k/TVYikoTk24I/AAAAAAAAD4c/3S_FM1EEX80/s320/IMAG0082.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5572679601607728002" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-f3iqXoywLqo/TVYiqZIndBI/AAAAAAAAD4k/Ajo-tZJmk-M/s1600/IMAG0083.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://1.bp.blogspot.com/-f3iqXoywLqo/TVYiqZIndBI/AAAAAAAAD4k/Ajo-tZJmk-M/s320/IMAG0083.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5572679700614444050" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-0X0C2GGJ5Xs/TVYi9tPrU-I/AAAAAAAAD4s/xEyyTftWqn4/s1600/IMAG0084.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://2.bp.blogspot.com/-0X0C2GGJ5Xs/TVYi9tPrU-I/AAAAAAAAD4s/xEyyTftWqn4/s320/IMAG0084.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5572680032430281698" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-CSvQ4T9PZjY/TVYjKQBlq_I/AAAAAAAAD40/-gzzkAETaE8/s1600/IMAG0085.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://3.bp.blogspot.com/-CSvQ4T9PZjY/TVYjKQBlq_I/AAAAAAAAD40/-gzzkAETaE8/s320/IMAG0085.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5572680247924861938" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Trail intersection at Cabana Diham:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-cFRzcJiB46M/TVYjRxT4L4I/AAAAAAAAD48/Bq70Ee4a3rw/s1600/IMAG0086.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://4.bp.blogspot.com/-cFRzcJiB46M/TVYjRxT4L4I/AAAAAAAAD48/Bq70Ee4a3rw/s320/IMAG0086.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5572680377119027074" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-oOqknSNat80/TVYjcVXyXKI/AAAAAAAAD5E/5I76M13AUPo/s1600/IMAG0087.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://4.bp.blogspot.com/-oOqknSNat80/TVYjcVXyXKI/AAAAAAAAD5E/5I76M13AUPo/s320/IMAG0087.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5572680558597790882" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Trail intersection at Cabana Poiana Izvoarelor:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-_0byqsMfjgk/TVYjn3bVgQI/AAAAAAAAD5M/Gy3zM62NYRQ/s1600/IMAG0088.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://1.bp.blogspot.com/-_0byqsMfjgk/TVYjn3bVgQI/AAAAAAAAD5M/Gy3zM62NYRQ/s320/IMAG0088.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5572680756718043394" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-5304880350063625826?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5304880350063625826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5304880350063625826' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5304880350063625826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5304880350063625826'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/02/osmc-symbol-reference-for-dihambusteni.html' title='OSMC symbol reference for Diham/Bușteni'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-kfGtootyt6M/TVYiNXO95hI/AAAAAAAAD4U/LSkKmTwd6Uo/s72-c/IMAG0081.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-4349217777655505965</id><published>2011-01-12T11:43:00.013+02:00</published><updated>2011-01-17T09:51:59.980+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Piatra Mare'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='hiking'/><title type='text'>Mountain Hiking tracks in Piatra Mare. Timișu de Sus - Piatra Mare</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/TS2gPKemsgI/AAAAAAAAD3s/CO5GXUtO318/s1600/piatramare.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 219px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/TS2gPKemsgI/AAAAAAAAD3s/CO5GXUtO318/s400/piatramare.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5561277297243632130" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The fastest way to reach Piatra Mare Peak (1844 m) is to start from Timișu de Sus and continue upwards by Cascada Tamina (Tamina waterfall). It's a 3.5 - 4 hour hike up to the peak and 2.5 - 3 hours back.&lt;br /&gt;&lt;br /&gt;If you're driving on DN1 from Predeal to Brașov, you can leave your car in the parking lot on the right of the road, just after you've exited Timișu de Sus. The trail opens on the right hand side with a small bridge leading to a forestry road marked with a blue stripe.&lt;br /&gt;&lt;br /&gt;The blue stripe trail leads to Cascada Tamina. The waterfall is one hour away, and you can hike through it (there are steel stairs installed inside the canyon formed by the river).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rXrjDFwt37w/TTAxYcYrJkI/AAAAAAAAD4E/VjfuwgsmEso/s1600/DSC_0106.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 266px; height: 400px;" src="http://3.bp.blogspot.com/_rXrjDFwt37w/TTAxYcYrJkI/AAAAAAAAD4E/VjfuwgsmEso/s400/DSC_0106.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5561999835808867906" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To hike through the waterfall leave the trail when you see the waterfall sign, descend on the right side until you reach the bottom of the waterfall and then climb your way up using the steel stairs. Once you've exited the waterfall, climb back to where you've started from and re-enter the trail towards Piatra Mare.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rXrjDFwt37w/TS2G-ule52I/AAAAAAAAD3c/XjZ-32ARFM8/s1600/DSC_0121.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://4.bp.blogspot.com/_rXrjDFwt37w/TS2G-ule52I/AAAAAAAAD3c/XjZ-32ARFM8/s400/DSC_0121.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5561249527087687522" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The trail continues through the forest, intersecting the forestry road you've started from, until you hit the alpine region at Stâna Pietricica.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rXrjDFwt37w/TS2FASuCkiI/AAAAAAAAD3U/BV3bpVKe1EM/s1600/StanaP.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 162px;" src="http://3.bp.blogspot.com/_rXrjDFwt37w/TS2FASuCkiI/AAAAAAAAD3U/BV3bpVKe1EM/s400/StanaP.jpg" border="0" alt="View from alpine region - central and slightly to the right is Postăvaru Peak from Brașov" id="BLOGGER_PHOTO_ID_5561247354943869474" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The trail then follows the red cross mark (&lt;img src="http://4.bp.blogspot.com/_rXrjDFwt37w/TSxd-63GRkI/AAAAAAAAD2Q/yxBH6RRxO_U/s1600/red_cross.png" /&gt;) and then the red stripe (&lt;img src="http://1.bp.blogspot.com/_rXrjDFwt37w/TSxePnzc9WI/AAAAAAAAD2Y/3eCfxOfpr4o/s1600/red_stripe.png" /&gt;) towards the peak.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/TTAwD07sG1I/AAAAAAAAD38/prbEBtlzKOU/s1600/panopm2.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 70px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/TTAwD07sG1I/AAAAAAAAD38/prbEBtlzKOU/s400/panopm2.jpg" border="0" alt="Piatra Mare Peak Panorama" id="BLOGGER_PHOTO_ID_5561998382109301586" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rXrjDFwt37w/TS2HL-bBgeI/AAAAAAAAD3k/2tmZf2u38fM/s1600/DSC_0172.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 266px; height: 400px;" src="http://4.bp.blogspot.com/_rXrjDFwt37w/TS2HL-bBgeI/AAAAAAAAD3k/2tmZf2u38fM/s400/DSC_0172.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5561249754677084642" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Google Maps version of the trail above: &lt;a href="http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=en&amp;amp;msa=0&amp;amp;msid=204824797392223100078.000499cc15f71493e6944&amp;amp;ll=45.541225,25.616169&amp;amp;spn=0.068171,0.150547&amp;amp;t=h&amp;amp;z=13"&gt;Timișu de Sus - Piatra Mare Map&lt;/a&gt;&lt;br /&gt;The KML is loadable in Google Earth and the visualization is pretty spectacular:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/TTAqwJ_T9SI/AAAAAAAAD30/0w9q1Mw69qM/s1600/Screen%2Bshot%2B2011-01-14%2Bat%2B12.50.09%2BPM.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 315px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/TTAqwJ_T9SI/AAAAAAAAD30/0w9q1Mw69qM/s400/Screen%2Bshot%2B2011-01-14%2Bat%2B12.50.09%2BPM.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5561992546606118178" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-4349217777655505965?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/4349217777655505965/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=4349217777655505965' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4349217777655505965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4349217777655505965'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2011/01/mountain-hiking-tracks-in-piatra-mare.html' title='Mountain Hiking tracks in Piatra Mare. Timișu de Sus - Piatra Mare'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rXrjDFwt37w/TS2gPKemsgI/AAAAAAAAD3s/CO5GXUtO318/s72-c/piatramare.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-3580781183505633988</id><published>2010-12-16T14:48:00.004+02:00</published><updated>2010-12-16T15:19:16.351+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='sprintf'/><category scheme='http://www.blogger.com/atom/ns#' term='__ sprintf_chk'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>sprintf_chk in Mac OS X</title><content type='html'>Under Snow Leopard, &lt;i&gt;sprintf&lt;/i&gt; calls are automatically replaced by calls to &lt;i&gt;sprintf_chk&lt;/i&gt;, a functionally equivalent function that performs bounds checking on the &lt;i&gt;sprintf&lt;/i&gt; argument.&lt;br /&gt;&lt;br /&gt;This means the following program (that deliberately overwrites the end of &lt;i&gt;t&lt;/i&gt;):&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;#include &amp;lt;stdio.h&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; char t[1] = {0x41};&lt;br /&gt; char v[1] = {0x42};&lt;br /&gt;&lt;br /&gt; sprintf(t, "%d%d", 0x43, 0x44);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;produces assembler code where the &lt;i&gt;sprintf&lt;/i&gt; call is replaced to a &lt;i&gt;sprintf_chk&lt;/i&gt; call:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;(gdb) disass&lt;br /&gt;Dump of assembler code for function main:&lt;br /&gt;0x0000000100000eec &amp;lt;main+0&amp;gt;: push   %rbp&lt;br /&gt;0x0000000100000eed &amp;lt;main+1&amp;gt;: mov    %rsp,%rbp&lt;br /&gt;0x0000000100000ef0 &amp;lt;main+4&amp;gt;: sub    $0x10,%rsp&lt;br /&gt;0x0000000100000ef4 &amp;lt;main+8&amp;gt;: movb   $0x41,-0x1(%rbp)&lt;br /&gt;0x0000000100000ef8 &amp;lt;main+12&amp;gt;: movb   $0x42,-0x2(%rbp)&lt;br /&gt;0x0000000100000efc &amp;lt;main+16&amp;gt;: lea    -0x1(%rbp),%rdi        # buffer argument&lt;br /&gt;0x0000000100000f00 &amp;lt;main+20&amp;gt;: mov    $0x44,%r9d             # second va_arg argument&lt;br /&gt;0x0000000100000f06 &amp;lt;main+26&amp;gt;: mov    $0x43,%r8d             # first va_arg argument &lt;br /&gt;0x0000000100000f0c &amp;lt;main+32&amp;gt;: lea    0x47(%rip),%rcx        # format string ("%d%d")&lt;br /&gt;0x0000000100000f13 &amp;lt;main+39&amp;gt;: mov    $0x1,%edx              # storage size as detected by the compiler       &lt;br /&gt;0x0000000100000f18 &amp;lt;main+44&amp;gt;: mov    $0x0,%esi              # flags argument (0)&lt;br /&gt;0x0000000100000f1d &amp;lt;main+49&amp;gt;: mov    $0x0,%eax              # MMS registers are not used to pass va_args&lt;br /&gt;0x0000000100000f22 &amp;lt;main+54&amp;gt;: callq  0x100000f2a &amp;lt;dyld_stub___sprintf_chk&amp;gt;&lt;br /&gt;0x0000000100000f27 &amp;lt;main+59&amp;gt;: leaveq &lt;br /&gt;0x0000000100000f28 &amp;lt;main+60&amp;gt;: retq   &lt;br /&gt;End of assembler dump.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;sprintf_chk&lt;/i&gt; has the following prototype:&lt;br /&gt;&lt;pre&gt;int __sprintf_chk (char *s, int flags, &lt;font color=red&gt;size_t len&lt;/font&gt;, const char *format, ...)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;that implies that the compiler is aware of the storage size of the destination buffer used by &lt;i&gt;sprintf&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;If the compiler knows the storage size of the destination buffer it uses it in the &lt;i&gt;sprintf_chk&lt;/i&gt; call, which in turn calls &lt;i&gt;vsnprintf&lt;/i&gt; and checks that the number of characters written in the buffer is less or equal to the size of the buffer (if this is not the case, it aborts).&lt;br /&gt;&lt;br /&gt;&lt;i&gt;sprintf_chk&lt;/i&gt; will not work with buffers that have been allocated on the heap (it will be called with length set to -1).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-3580781183505633988?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/3580781183505633988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=3580781183505633988' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3580781183505633988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3580781183505633988'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/12/sprintfchk-in-mac-os-x.html' title='sprintf_chk in Mac OS X'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5414737504935316352</id><published>2010-12-03T09:41:00.004+02:00</published><updated>2010-12-03T10:30:51.247+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><title type='text'>Compressing Mac OS X executables using UPX</title><content type='html'>&lt;i&gt;&lt;a href="upx.sourceforge.net"&gt;UPX&lt;/a&gt; stands for Ultimate Packer for eXecutables and you can use it to compress many executable formats including Mac OS X fat binaries. UPX will create a new version of your executable that will self extract itself at runtime.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Things to remember when considering production code&lt;/h3&gt;&lt;br /&gt;UPX changes your executable. otool no longer produces the output you would expect and running the executable under GDB is completely un-symbolized (although you can get around this by attaching to the binary after it's been uncompressed in memory).&lt;br /&gt;&lt;br /&gt;The crash reports created by Mac OS X on executables produced by UPX are almost empty - they only contain the registry dump because Mac OS X is unable to resolve the backtraces on the application threads.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Compiling UCL&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;UPX depends on UCL (portable lossless data compression library). Download the latest UCL version (ucl-1.03.tar.gz) from &lt;a href="http://www.oberhumer.com/opensource/ucl/download/"&gt;http://www.oberhumer.com/opensource/ucl/download/&lt;/a&gt; and untar it.&lt;br /&gt;&lt;br /&gt;Compile UCL using the usual &lt;i&gt;./configure&lt;/i&gt;, &lt;i&gt;make&lt;/i&gt; sequence.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Compiling UPX&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Download the source package from &lt;a href="http://upx.sourceforge.net/#downloadupx"&gt;upx.sourceforge.net&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To compile upx, you need to tell it where the UCL library is stored (unless you're installed it).&lt;br /&gt;&lt;pre class="prettyprint"&gt;cristi:upx-3.07-src diciu$ cd src/&lt;br /&gt;export UPX_UCLDIR=/Users/diciu/Downloads/ucl-1.03&lt;br /&gt;make&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Once its compiled you can use it to compress any executable:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;cristi:src diciu$ ./upx.out  /tmp/LoudHush &lt;br /&gt;                       Ultimate Packer for eXecutables&lt;br /&gt;                          Copyright (C) 1996 - 2010&lt;br /&gt;UPX 3.07        Markus Oberhumer, Laszlo Molnar &amp; John Reiser   Sep 08th 2010&lt;br /&gt;&lt;br /&gt;        File size         Ratio      Format      Name&lt;br /&gt;   --------------------   ------   -----------   -----------&lt;br /&gt;    584560 -&gt;    216576   37.05%    Mach/fat     LoudHush                      &lt;br /&gt;&lt;br /&gt;Packed 1 file.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;PS. If you get a &lt;i&gt;NotCompressibleException&lt;/i&gt; it may be that your executable is too small and cannot be compressed (the size of the compressed binary exceeds the size of the original binary).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-5414737504935316352?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5414737504935316352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5414737504935316352' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5414737504935316352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5414737504935316352'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/12/compressing-mac-os-x-executables-using.html' title='Compressing Mac OS X executables using UPX'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-1292544376228271179</id><published>2010-11-28T15:17:00.005+02:00</published><updated>2010-11-29T08:19:35.053+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><category scheme='http://www.blogger.com/atom/ns#' term='x86_64'/><title type='text'>Looking at memset's implementation</title><content type='html'>&lt;i&gt;Not all LibC functions are written in C. Some are written in assembler because they are optimized to take in consideration the data size and alignment of LibC call arguments. This post describes memset based on GDB's disassembly.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;void * memset(void *b, int c, size_t len);&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Following the 64 bit ABI, the parameters to the function are set as follows:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;b&lt;/b&gt; is the destination ($rdi)&lt;br /&gt;&lt;b&gt;c&lt;/b&gt; is the character to fill the destination with ($rsi) (my example uses 0x38 - character '8')&lt;br /&gt;&lt;b&gt;len&lt;/b&gt; is the length ($rdx)&lt;br /&gt;&lt;br /&gt;The first thing &lt;i&gt;memset&lt;/i&gt; does is to check if the character argument is 0 (logical AND with 0xFF)&lt;br /&gt;If it is, the &lt;i&gt;memset&lt;/i&gt; call is equivalent to a bzero call and the code jumps to the bzero implementation (0x7fffffe00600).&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f414 &amp;lt;memset+0&amp;gt;: and    $0xff,%esi&lt;br /&gt;0x00007fff8749f41a &amp;lt;memset+6&amp;gt;: jne    0x7fff8749f42b &amp;lt;memset+23&gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;RSI is zero - this memset call is equivalent to a bzero call (0x7fffffe00600).&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f41c &amp;lt;memset+8&amp;gt;: mov    $0x7fffffe00600,%rax&lt;br /&gt;0x00007fff8749f426 &amp;lt;memset+18&amp;gt;: mov    %rdx,%rsi&lt;br /&gt;0x00007fff8749f429 &amp;lt;memset+21&amp;gt;: jmpq   *%rax&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;RSI is non-zero.&lt;br /&gt;Save the destination address to R8 (it will be used later on as return value of memset.&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f42b &amp;lt;memset+23&amp;gt;: mov    %rdi,%r8&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The following section fills each byte of EAX with the character argument (0x38383838)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rXrjDFwt37w/TPJZmPf8ONI/AAAAAAAAD1Y/apK9yq09ozw/s1600/diag2eax.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 214px; height: 400px;" src="http://1.bp.blogspot.com/_rXrjDFwt37w/TPJZmPf8ONI/AAAAAAAAD1Y/apK9yq09ozw/s400/diag2eax.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5544592604776904914" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f42e &amp;lt;memset+26&amp;gt;: mov    %esi,%eax&lt;br /&gt;0x00007fff8749f430 &amp;lt;memset+28&amp;gt;: shl    $0x8,%esi&lt;br /&gt;0x00007fff8749f433 &amp;lt;memset+31&amp;gt;: or     %esi,%eax&lt;br /&gt;0x00007fff8749f435 &amp;lt;memset+33&amp;gt;: mov    %eax,%esi&lt;br /&gt;0x00007fff8749f437 &amp;lt;memset+35&amp;gt;: shl    $0x10,%esi&lt;br /&gt;0x00007fff8749f43a &amp;lt;memset+38&amp;gt;: or     %esi,%eax&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Check if the size of the fill is bigger then 256 bytes.&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f43c &amp;lt;memset+40&amp;gt;: cmp    $0xff,%rdx&lt;br /&gt;0x00007fff8749f443 &amp;lt;memset+47&amp;gt;: ja     0x7fff8749f490 &lt;a href="#124"&gt;&amp;lt;memset+124&amp;gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Check if the size of the fill is bigger then 16 bytes.&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f445 &amp;lt;memset+49&amp;gt;: cmp    $0x10,%edx&lt;br /&gt;0x00007fff8749f448 &amp;lt;memset+52&amp;gt;: jge    0x7fff8749f464 &lt;a href="#80"&gt;&amp;lt;memset+80&amp;gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Check if the size of the fill is zero.&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f44a &amp;lt;memset+54&amp;gt;: test   %edx,%edx&lt;br /&gt;0x00007fff8749f44c &amp;lt;memset+56&amp;gt;: je     0x7fff8749f48c &lt;a href="#120"&gt;&amp;lt;memset+120&amp;gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Size of fill is less then 16 bytes but not zero.&lt;br /&gt;Fill is the destination buffer (RDI is pointing to it) one byte at a time, decrementing RDX at each step.&lt;br /&gt;Continue until RDX is zero, and jump at function end.&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f44e &amp;lt;memset+58&amp;gt;: mov    %al,(%rdi)&lt;br /&gt;0x00007fff8749f450 &amp;lt;memset+60&amp;gt;: add    $0x1,%rdi&lt;br /&gt;0x00007fff8749f454 &amp;lt;memset+64&amp;gt;: sub    $0x1,%edx&lt;br /&gt;0x00007fff8749f457 &amp;lt;memset+67&amp;gt;: jne    0x7fff8749f44e &amp;lt;memset+58&gt;&lt;br /&gt;0x00007fff8749f459 &amp;lt;memset+69&amp;gt;: jmp    0x7fff8749f48c &amp;lt;memset+120&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f45b &amp;lt;memset+71&amp;gt;: mov    %al,(%rdi)&lt;br /&gt;0x00007fff8749f45d &amp;lt;memset+73&amp;gt;: add    $0x1,%rdi&lt;br /&gt;0x00007fff8749f461 &amp;lt;memset+77&amp;gt;: sub    $0x1,%edx&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name="80"&gt; &lt;/a&gt;Size of fill is more then 16 bytes.&lt;br /&gt;If the destination is not 4 byte aligned, fill in the first bytes until the destination is aligned.&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f464 &amp;lt;memset+80&amp;gt;: test   $0x3,%edi&lt;br /&gt;0x00007fff8749f46a &amp;lt;memset+86&amp;gt;: jne    0x7fff8749f45b &amp;lt;memset+71&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The destination is now aligned, so it can be filled in 4 bytes at a time.&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f46c &amp;lt;memset+88&amp;gt;: mov    %edx,%ecx&lt;br /&gt;0x00007fff8749f46e &amp;lt;memset+90&amp;gt;: shr    $0x2,%edx&lt;br /&gt;0x00007fff8749f471 &amp;lt;memset+93&amp;gt;: mov    %eax,(%rdi)&lt;br /&gt;0x00007fff8749f473 &amp;lt;memset+95&amp;gt;: add    $0x4,%rdi&lt;br /&gt;0x00007fff8749f477 &amp;lt;memset+99&amp;gt;: sub    $0x1,%edx&lt;br /&gt;0x00007fff8749f47a &amp;lt;memset+102&amp;gt;: jne    0x7fff8749f471 &amp;lt;memset+93&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If the size was also a multiple of 4, we're done.&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f47c &amp;lt;memset+104&amp;gt;: and    $0x3,%ecx&lt;br /&gt;0x00007fff8749f47f &amp;lt;memset+107&amp;gt;: je     0x7fff8749f48c &amp;lt;memset+120&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If the size was not a multiple of 4, there are some leftovers to copy.&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f481 &amp;lt;memset+109&amp;gt;: mov    %al,(%rdi)&lt;br /&gt;0x00007fff8749f483 &amp;lt;memset+111&amp;gt;: add    $0x1,%rdi&lt;br /&gt;0x00007fff8749f487 &amp;lt;memset+115&amp;gt;: sub    $0x1,%ecx&lt;br /&gt;0x00007fff8749f48a &amp;lt;memset+118&amp;gt;: jne    0x7fff8749f481 &amp;lt;memset+109&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name="120"&gt; &lt;/a&gt;Load RAX with the value of R8 (pointer to fill buffer saved at beginning) and return.&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f48c &amp;lt;memset+120&amp;gt;: mov    %r8,%rax&lt;br /&gt;0x00007fff8749f48f &amp;lt;memset+123&amp;gt;: retq   &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name="124"&gt; &lt;/a&gt;A fill operation with more then 256 bytes.&lt;br /&gt;This is done using MMS instructions. xmm0 is set to 16 bytes of 0x38 (our character)&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f490 &amp;lt;memset+124&amp;gt;: movd   %eax,%xmm0&lt;br /&gt;0x00007fff8749f494 &amp;lt;memset+128&amp;gt;: pshufd $0x0,%xmm0,%xmm0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Check for alignment of destination.&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f499 &amp;lt;memset+133&amp;gt;: mov    %rdi,%rcx&lt;br /&gt;0x00007fff8749f49c &amp;lt;memset+136&amp;gt;: neg    %ecx&lt;br /&gt;0x00007fff8749f49e &amp;lt;memset+138&amp;gt;: and    $0xf,%ecx&lt;br /&gt;0x00007fff8749f4a1 &amp;lt;memset+141&amp;gt;: je     0x7fff8749f4b1 &amp;lt;memset+157&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The destination is not 16 byte aligned, copy some bytes until rest of destination will be aligned.&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f4a3 &amp;lt;memset+143&amp;gt;: sub    %rcx,%rdx&lt;br /&gt;0x00007fff8749f4a6 &amp;lt;memset+146&amp;gt;: mov    %al,(%rdi)&lt;br /&gt;0x00007fff8749f4a8 &amp;lt;memset+148&amp;gt;: add    $0x1,%rdi&lt;br /&gt;0x00007fff8749f4ac &amp;lt;memset+152&amp;gt;: sub    $0x1,%ecx&lt;br /&gt;0x00007fff8749f4af &amp;lt;memset+155&amp;gt;: jne    0x7fff8749f4a6 &amp;lt;memset+146&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Call _memset_pattern.&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f4b1 &amp;lt;memset+157&amp;gt;: mov    $0x7fffffe01000,%rax&lt;br /&gt;0x00007fff8749f4bb &amp;lt;memset+167&amp;gt;: callq  *%rax&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Load RAX with the value of R8 (pointer to fill buffer saved at beginning).&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x00007fff8749f4bd &amp;lt;memset+169&amp;gt;: mov    %r8,%rax&lt;br /&gt;0x00007fff8749f4c0 &amp;lt;memset+172&amp;gt;: retq   &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/31740253-1292544376228271179?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/1292544376228271179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=1292544376228271179' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1292544376228271179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1292544376228271179'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/11/looking-at-memsets-implementation.html' title='Looking at memset&apos;s implementation'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_rXrjDFwt37w/TPJZmPf8ONI/AAAAAAAAD1Y/apK9yq09ozw/s72-c/diag2eax.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-7919891489951239999</id><published>2010-11-23T11:16:00.003+02:00</published><updated>2010-11-23T11:37:10.838+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><category scheme='http://www.blogger.com/atom/ns#' term='x86_64'/><title type='text'>Calling _printf from 64bit code under Mac OS X</title><content type='html'>If you're trying to figure out why your &lt;i&gt;printf&lt;/i&gt; call &lt;i&gt;sometimes&lt;/i&gt; crashes, check that you're zeroing out %rax before the &lt;i&gt;printf&lt;/i&gt; call (unless you're actually printf-ing floating point numbers).&lt;br /&gt;&lt;br /&gt;Under the 64bit ABI %rax is described as: &lt;i&gt;temporary register; &lt;b&gt;with variable arguments passes information about the number of vector registers used&lt;/b&gt;; 1st return register&lt;/i&gt;. The vector registers are xmm0-xmm7 and they are used when passing floating point arguments.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;#============== asm.s  ==============#&lt;br /&gt;.data&lt;br /&gt;msg: .ascii "Hello World\0"&lt;br /&gt;fmt1: .ascii "%s\n\0"&lt;br /&gt;fmt2: .ascii "This is pi:%.10f\n\0"&lt;br /&gt;pi: .quad 0x400921FB53C8D4F1&lt;br /&gt;&lt;br /&gt;.text&lt;br /&gt;.globl _dis&lt;br /&gt;_dis:&lt;br /&gt; sub $8, %rsp&lt;br /&gt;&lt;br /&gt; movq $0, %rax&lt;br /&gt; movq fmt1@GOTPCREL(%rip), %rdi&lt;br /&gt; movq msg@GOTPCREL(%rip), %rsi&lt;br /&gt; call _printf&lt;br /&gt;&lt;br /&gt; movsd pi(%rip), %xmm0&lt;br /&gt; movq $1, %rax&lt;br /&gt; movq fmt2@GOTPCREL(%rip), %rdi&lt;br /&gt; call _printf&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; add $8, %rsp&lt;br /&gt; ret&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;#============ mainasm.c  ============#&lt;br /&gt;extern void dis();&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; dis();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;cristi:tmp diciu$ as -arch x86_64 asm.s -o asm.o&lt;br /&gt;cristi:tmp diciu$ gcc mainasm.c asm.o&lt;br /&gt;cristi:tmp diciu$ ./a.out&lt;br /&gt;Hello World&lt;br /&gt;This is pi:3.1415926500&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you're looking for a way to get the hex representation of PI (0x400921FB53C8D4F1), this is what I used: &lt;a href="http://babbage.cs.qc.edu/IEEE-754/Decimal.html"&gt;IEEE-754 Floating-Point Conversion&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-7919891489951239999?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/7919891489951239999/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=7919891489951239999' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7919891489951239999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7919891489951239999'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/11/calling-printf-from-64bit-code-under.html' title='Calling _printf from 64bit code under Mac OS X'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-200092988007071662</id><published>2010-11-22T12:31:00.003+02:00</published><updated>2010-11-22T12:40:34.855+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='64bit'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>Debugging session summary</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rXrjDFwt37w/TOpHo8PB2uI/AAAAAAAAD1Q/i00k5CoXlCg/s1600/diag.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 221px;" src="http://1.bp.blogspot.com/_rXrjDFwt37w/TOpHo8PB2uI/AAAAAAAAD1Q/i00k5CoXlCg/s400/diag.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5542321060122319586" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-200092988007071662?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/200092988007071662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=200092988007071662' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/200092988007071662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/200092988007071662'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/11/debugging-session-summary.html' title='Debugging session summary'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_rXrjDFwt37w/TOpHo8PB2uI/AAAAAAAAD1Q/i00k5CoXlCg/s72-c/diag.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-3683638234641382998</id><published>2010-11-18T10:10:00.005+02:00</published><updated>2010-11-18T10:56:23.798+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><category scheme='http://www.blogger.com/atom/ns#' term='x86_64'/><title type='text'>Hello world in 64bit, Mac OS X</title><content type='html'>System call numbers in 64 bit are different when compared to the 32 bit versions. They are obtained by adding the 32 bit system call number to 0x2000000 (see SYSCALL_CONSTRUCT_UNIX in &lt;a href="http://www.opensource.apple.com/source/xnu/xnu-1504.7.4/osfmk/mach/i386/syscall_sw.h"&gt;syscall_hw.h&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Other 64 bit particularities are instruction pointer (%rip) relative data references.&lt;br /&gt;&lt;br /&gt;If you try to assemble:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;.data    &lt;br /&gt;msg:&lt;br /&gt; .ascii "Hello, world!\n"&lt;br /&gt;len:&lt;br /&gt; .long . - msg&lt;br /&gt;&lt;br /&gt;.text  # text section&lt;br /&gt;.globl _start # declare _start as global symbol for the linker to find&lt;br /&gt;&lt;br /&gt;_start:&lt;br /&gt; movq len, %rdx  # length of string&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;you get:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cristi:64bit diciu$ as -arch x86_64 rdf.s -o rdf.o&lt;br /&gt;rdf.s:14:32-bit absolute addressing is not supported for x86-64&lt;br /&gt;rdf.s:14:cannot do signed 4 byte relocation&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is explained in the &lt;a href="http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/MachOTopics/1-Articles/x86_64_code.html"&gt;x86-64 Code Model&lt;/a&gt;:&lt;br /&gt;&lt;quote&gt;&lt;i&gt;&lt;br /&gt;All local and small data is accessed directly using addressing that’s relative to the instruction pointer (RIP-relative addressing). All large or possibly nonlocal data is accessed indirectly through a global offset table (GOT) entry. The GOT entry is accessed directly using RIP-relative addressing.&lt;/i&gt;&lt;/quote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Our hello world assembler program becomes:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;============= hello64bit.s ===================&lt;br /&gt;#as -arch x86_64 hello64bit.s -o hello64bit.o&lt;br /&gt;#ld -e _start -arch x86_64 hello64bit.o -o hello64bit&lt;br /&gt;&lt;br /&gt;.data  # data section&lt;br /&gt;msg:&lt;br /&gt; .ascii "Hello, world!\n" # ascii string to be printed&lt;br /&gt;len:&lt;br /&gt; .long . - msg  # string length&lt;br /&gt;&lt;br /&gt;.text  # text section&lt;br /&gt;.globl _start # declare _start as global symbol for the linker to find&lt;br /&gt;&lt;br /&gt;_start:&lt;br /&gt; movq $0x2000004, %rax   # write call (see SYSCALL_CONSTRUCT_UNIX)&lt;br /&gt; movq $1, %rdi   # file descriptior (stdout)&lt;br /&gt; movq msg@GOTPCREL(%rip), %rsi # string to print&lt;br /&gt; movq len(%rip), %rdx  # length of string&lt;br /&gt; syscall    # call write&lt;br /&gt;&lt;br /&gt; movq $0x2000001, %rax  # exit call&lt;br /&gt; movq $0, %rdi   # return code&lt;br /&gt; syscall    # call exit&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/31740253-3683638234641382998?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/3683638234641382998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=3683638234641382998' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3683638234641382998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3683638234641382998'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/11/hello-world-in-64bit-mac-os-x.html' title='Hello world in 64bit, Mac OS X'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-1154430658033310141</id><published>2010-11-15T08:58:00.004+02:00</published><updated>2010-11-15T09:47:17.277+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photo'/><title type='text'>Panorama Stâna Pietricica (Piatra Mare)</title><content type='html'>&lt;a href="#"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 800px; height: 324px;" src="http://4.bp.blogspot.com/_rXrjDFwt37w/TODaXY_8hDI/AAAAAAAADyg/4-0YgTImSE0/s1600/pano_stana_pietricica.jpg" onmouseover="this.src='http://2.bp.blogspot.com/_rXrjDFwt37w/TODknI33yEI/AAAAAAAADyo/NQU8VkOMDBc/s1600/pano_stana_pietricica_hover.jpg'" onmouseout="this.src='http://4.bp.blogspot.com/_rXrjDFwt37w/TODaXY_8hDI/AAAAAAAADyg/4-0YgTImSE0/s1600/pano_stana_pietricica.jpg'"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-1154430658033310141?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/1154430658033310141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=1154430658033310141' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1154430658033310141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1154430658033310141'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/11/panorama-stana-pietricica-piatra-mare.html' title='Panorama Stâna Pietricica (Piatra Mare)'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_rXrjDFwt37w/TODaXY_8hDI/AAAAAAAADyg/4-0YgTImSE0/s72-c/pano_stana_pietricica.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-7467903287469982151</id><published>2010-10-29T10:55:00.005+03:00</published><updated>2010-10-31T17:17:03.667+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='diacritics'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><title type='text'>Charpy - a helper application for diacritical marks</title><content type='html'>I've built a small (around 70 lines of code thanks to &lt;a href="http://pyobjc.sourceforge.net/"&gt;PyObjC&lt;/a&gt;) helper application that shows UTF-8 encodings and the Unicode description for a character.&lt;br /&gt;&lt;br /&gt;You can download it here: &lt;a href="http://loudhush.ro/files/charpy.zip"&gt;charpy.zip&lt;/a&gt;&lt;br /&gt;MD5 sum: a4f7d56ac7342b4ab0ec403c0b4c4b43.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rXrjDFwt37w/TMp-MTePIuI/AAAAAAAADyE/2gHrNFxCsiA/s1600/charpyscr.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 340px;" src="http://1.bp.blogspot.com/_rXrjDFwt37w/TMp-MTePIuI/AAAAAAAADyE/2gHrNFxCsiA/s400/charpyscr.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5533373842028700386" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rXrjDFwt37w/TMp_oHRHLNI/AAAAAAAADyM/V3nSKD-x_Lk/s1600/charpy_shiftjis.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 342px;" src="http://4.bp.blogspot.com/_rXrjDFwt37w/TMp_oHRHLNI/AAAAAAAADyM/V3nSKD-x_Lk/s400/charpy_shiftjis.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5533375419300392146" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-7467903287469982151?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/7467903287469982151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=7467903287469982151' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7467903287469982151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7467903287469982151'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/10/charpy-helper-application-for.html' title='Charpy - a helper application for diacritical marks'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_rXrjDFwt37w/TMp-MTePIuI/AAAAAAAADyE/2gHrNFxCsiA/s72-c/charpyscr.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-2133574788155317461</id><published>2010-10-28T10:05:00.002+03:00</published><updated>2010-10-28T10:21:43.779+03:00</updated><title type='text'>psql with diacritical marks on Mac OS X 10.6.4</title><content type='html'>If you're typing diacritical marks (ăâșt) into the &lt;i&gt;psql&lt;/i&gt; command line on Mac OS X 10.6.4 and getting question marks in place of the expected marks, you're facing a problem in the &lt;i&gt;libedit&lt;/i&gt; library used by &lt;i&gt;psql&lt;/i&gt; for enhanced command line editing.&lt;br /&gt;&lt;br /&gt;You can tell &lt;i&gt;psql&lt;/i&gt; to stop using the &lt;i&gt;libedit&lt;/i&gt; library, using a command line option:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Input and output options:&lt;br /&gt;[..]&lt;br /&gt;  -n, --no-readline        disable enhanced command line editing (readline)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The disadvantage is that &lt;i&gt;psql&lt;/i&gt; will loose all enhanced editing features (such as going to the begging of the line by typing Ctrl+A). To get around this problem, I usually run two &lt;i&gt;psql&lt;/i&gt; sessions, one without read line capabilities (the "Romanian session") and one with enhanced editing features (the "normal session").&lt;br /&gt;&lt;br /&gt;The 10.6.4 &lt;i&gt;libedit&lt;/i&gt; library also causes crashes when using TAB completion on some object names. Reference here: &lt;a href="http://archives.postgresql.org/pgsql-bugs/2010-04/msg00127.php"&gt;archives.postgresql.org&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-2133574788155317461?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/2133574788155317461/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=2133574788155317461' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/2133574788155317461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/2133574788155317461'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/10/psql-with-diacritical-marks-on-mac-os-x.html' title='psql with diacritical marks on Mac OS X 10.6.4'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-8222148884845894906</id><published>2010-09-28T09:03:00.007+03:00</published><updated>2010-09-28T09:23:08.881+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='postgis'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><title type='text'>Point that is part of way does not intersect way</title><content type='html'>If you're wondering why a point that is obviously part of a way does not intersect the way, it's because coordinates are stored differently in &lt;i&gt;planet_osm_point&lt;/i&gt; vs. &lt;i&gt;planet_osm_line&lt;/i&gt;. &lt;br /&gt;&lt;br /&gt;Case in point, a subway station drawn as a node on a subway railway is reported by &lt;i&gt;postgis&lt;/i&gt; as not intersecting the railway.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rXrjDFwt37w/TKGI4OfpcuI/AAAAAAAADxg/pUq6kzGDHN4/s1600/Screen+shot+2010-09-28+at+9.18.25+AM.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 185px;" src="http://1.bp.blogspot.com/_rXrjDFwt37w/TKGI4OfpcuI/AAAAAAAADxg/pUq6kzGDHN4/s400/Screen+shot+2010-09-28+at+9.18.25+AM.png" border="0" alt="Screenshot of JOSM showing a subway station on a subway railway" id="BLOGGER_PHOTO_ID_5521845117677826786" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The apparent cause is that, when saving coordinates in planet_osm_line, &lt;b&gt;osm2pgsql&lt;/b&gt; rounds them to two decimal places (I've only checked for SRID 900913):&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;openmapdb=# select st_asewkt(way) from planet_osm_point where osm_id = 293317918;&lt;br /&gt; SRID=900913;POINT(2905477.18172046 5539892.28016006)&lt;br /&gt;(1 row)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;openmapdb=# select st_asewkt(way) from planet_osm_line where osm_id = 45736605;&lt;br /&gt;SRID=900913;LINESTRING([..]2905477.18 5539892.28&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The side effect of this rounding is that &lt;i&gt;st_intersects&lt;/i&gt; applied to the point and the line will return false because the distance difference caused by the rounding is larger then the margin used by the intersection function.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-8222148884845894906?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/8222148884845894906/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=8222148884845894906' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8222148884845894906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8222148884845894906'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/09/point-that-is-part-of-way-does-not.html' title='Point that is part of way does not intersect way'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_rXrjDFwt37w/TKGI4OfpcuI/AAAAAAAADxg/pUq6kzGDHN4/s72-c/Screen+shot+2010-09-28+at+9.18.25+AM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-6445354274926524088</id><published>2010-09-15T12:14:00.016+03:00</published><updated>2010-09-16T08:00:47.957+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Bâlea'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='Făgăraș'/><category scheme='http://www.blogger.com/atom/ns#' term='hiking'/><title type='text'>Mountain hiking tracks in Făgăraș. Cabana Bâlea - Vânătoarea lui Buteanu (part I)</title><content type='html'>&lt;i&gt;With few exceptions (Ceahlău's excellent national park office comes to mind) I am always frustrated with the quality of signage in Romania's mountain trekking areas. &lt;br /&gt;&lt;br /&gt;I usually document my trips by searching on the Internet but sometimes it's hard to find trail descriptions at the level of detail I require. It may be that the writer assumes I carry a tent and camp out for the night, or he proposes start points that are un-drivable.&lt;br /&gt;&lt;br /&gt;This post, and future follow-ups will describe trails that can be walked within a summer's daylight span (9 hours at most).&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Disclaimer&lt;/b&gt;&lt;br /&gt;While I've worked on collecting some of the data used in these maps and I've performed the rendering myself, I cannot guarantee for their correctness or accuracy. When going up for a hike, make sure to take decent maps and appropriate gear. Around Bâlea, most of the alpine huts sell good paper maps.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Cabana Bâlea - Vânătoarea lui Buteanu&lt;/h3&gt;&lt;br /&gt;Cabana Bâlea - Vânătoarea lui Buteanu is probably the easiest, but still very rewarding trail when starting from Bâlea. The trail is not very long but it is somewhat steep (500m altitude gain).&lt;br /&gt;&lt;br /&gt;Map of the trails to the west of Bâlea Lake (&lt;a href="http://www.openstreetmap.org/?lat=45.6023&amp;lon=24.6207&amp;zoom=13&amp;layers=M"&gt;click here for the standard OSM map&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/TJCSMvhh8nI/AAAAAAAADwA/dGimd5-wH9A/s1600/Screen+shot+2010-09-15+at+12.13.57+PM.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 308px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/TJCSMvhh8nI/AAAAAAAADwA/dGimd5-wH9A/s400/Screen+shot+2010-09-15+at+12.13.57+PM.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5517070291142046322" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Symbol&lt;/td&gt;&lt;td&gt;Trail name&lt;/td&gt;&lt;td&gt;Duration estimate&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rXrjDFwt37w/TJCTA1dyPRI/AAAAAAAADwI/T9zhOXPfMTs/s1600/blue_triangle.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 16px; height: 16px;" src="http://4.bp.blogspot.com/_rXrjDFwt37w/TJCTA1dyPRI/AAAAAAAADwI/T9zhOXPfMTs/s400/blue_triangle.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5517071186090147090" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Cabana Bâlea - Șaua Caprei&lt;/td&gt;&lt;td&gt;45 min - 1 h&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/TJCTl66ILiI/AAAAAAAADwQ/8e66frFpfio/s1600/blue_cross.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 16px; height: 16px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/TJCTl66ILiI/AAAAAAAADwQ/8e66frFpfio/s400/blue_cross.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5517071823206362658" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Șaua Caprei - Vânătoarea lui Buteanu (2507m)&lt;/td&gt;&lt;td&gt;45 min&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Take the blue triangle trail to Șaua Caprei. Once you reach Șaua Caprei, you can walk around Capra Lake (~2200m), a beautiful glacial lake:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rXrjDFwt37w/TJCicWGp73I/AAAAAAAADwg/MltBENTnjA4/s1600/DSC_0157.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://1.bp.blogspot.com/_rXrjDFwt37w/TJCicWGp73I/AAAAAAAADwg/MltBENTnjA4/s400/DSC_0157.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5517088151382388594" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;From Șaua Caprei, you can continue on the blue cross trail to Vânătoarea lui Buteanu (2507 m), the easiest big peak to reach in Făgăraș when starting from Bâlea, offering spectacular views of the surrounding mountains (photo shows Negoiu peak as seen from Vânătoarea lui Buteanu):&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rXrjDFwt37w/TJCWVY8JC4I/AAAAAAAADwY/4eIb8QD99rE/s1600/DSC_0208.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://1.bp.blogspot.com/_rXrjDFwt37w/TJCWVY8JC4I/AAAAAAAADwY/4eIb8QD99rE/s400/DSC_0208.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5517074837744978818" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;View towards Capra Lake (colleague's photo)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rXrjDFwt37w/TJDDReuBbHI/AAAAAAAADwo/Mse6sVePPIM/s1600/P1060359.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 225px;" src="http://1.bp.blogspot.com/_rXrjDFwt37w/TJDDReuBbHI/AAAAAAAADwo/Mse6sVePPIM/s400/P1060359.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5517124248600145010" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In the background (trapezoid shape) Viștea Mare on the left, Moldoveanu on the right (roughly 23 Km away in a straight line).&lt;br /&gt;To the left of Viștea Mare and closer to the viewer, Podragu peak.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rXrjDFwt37w/TJDIlktimaI/AAAAAAAADww/zcLGXBqEGHQ/s1600/DSC_0209.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://3.bp.blogspot.com/_rXrjDFwt37w/TJDIlktimaI/AAAAAAAADww/zcLGXBqEGHQ/s400/DSC_0209.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5517130091364260258" title="Podragu, Viștea Mare, Moldoveanu"/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This map schematic shows the visible peaks present in the photograph above:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/TJGkbgskTFI/AAAAAAAADxI/poID2ihJMgQ/s1600/fagaras_b_m.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 103px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/TJGkbgskTFI/AAAAAAAADxI/poID2ihJMgQ/s400/fagaras_b_m.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5517371811045854290" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-6445354274926524088?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/6445354274926524088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=6445354274926524088' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6445354274926524088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6445354274926524088'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/09/mountain-hiking-tracks-in-fagaras.html' title='Mountain hiking tracks in Făgăraș. Cabana Bâlea - Vânătoarea lui Buteanu (part I)'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rXrjDFwt37w/TJCSMvhh8nI/AAAAAAAADwA/dGimd5-wH9A/s72-c/Screen+shot+2010-09-15+at+12.13.57+PM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-356337662302203287</id><published>2010-08-16T15:23:00.006+03:00</published><updated>2010-08-16T16:28:17.400+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cltq'/><category scheme='http://www.blogger.com/atom/ns#' term='gcc'/><category scheme='http://www.blogger.com/atom/ns#' term='64bit'/><title type='text'>In 64bit sizeof(int) != sizeof(char *) and an unexpected side effect</title><content type='html'>While trying to figure out how the &lt;i&gt;PATH&lt;/i&gt; environment variable can be set under Mac OS X, I wrote a little C program to test what &lt;i&gt;getenv&lt;/i&gt; returns.&lt;br /&gt;&lt;br /&gt;This is how I usually write them, not really taking care to include headers, as I leave it to &lt;i&gt;gcc&lt;/i&gt; to do the right thing:&lt;br /&gt;&lt;pre class="prettyprint"&gt;int main()&lt;br /&gt;{&lt;br /&gt;        char * t = getenv("PATH");&lt;br /&gt;        printf("&gt;%s&lt;\n", t);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In this case however, the binary crashed with a segmentation fault in the &lt;i&gt;printf&lt;/i&gt; call.&lt;br /&gt;Compiling on 32 bit makes the problem go away, so what is the problem?&lt;br /&gt;&lt;br /&gt;Well, if we look at the assembler code, &lt;i&gt;gcc&lt;/i&gt; has added an extra call (&lt;b&gt;cltq&lt;/b&gt;) to convert the 4 byte integer result of &lt;i&gt;getenv&lt;/i&gt; to 8 bytes (the size of &lt;i&gt;char *&lt;/i&gt; on 64 bit):&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;0x0000000100000ee4 &amp;lt;main+8&amp;gt;: lea    0x67(%rip),%rdi        # 0x100000f52&lt;br /&gt;0x0000000100000eeb &amp;lt;main+15&amp;gt;: mov    $0x0,%eax&lt;br /&gt;0x0000000100000ef0 &amp;lt;main+20&amp;gt;: callq  0x100000f18 &amp;lt;dyld_stub_getenv&amp;gt;&lt;br /&gt;0x0000000100000ef5 &amp;lt;main+25&amp;gt;: cltq   &lt;br /&gt;0x0000000100000ef7 &amp;lt;main+27&amp;gt;: mov    %rax,-0x8(%rbp)&lt;br /&gt;0x0000000100000efb &amp;lt;main+31&amp;gt;: mov    -0x8(%rbp),%rsi&lt;br /&gt;0x0000000100000eff &amp;lt;main+35&amp;gt;: lea    0x51(%rip),%rdi        # 0x100000f57&lt;br /&gt;0x0000000100000f06 &amp;lt;main+42&amp;gt;: mov    $0x0,%eax&lt;br /&gt;0x0000000100000f0b &amp;lt;main+47&amp;gt;: callq  0x100000f1e &amp;lt;dyld_stub_printf&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This conversion clobbers the &lt;b&gt;rax&lt;/b&gt; register, clearing the top 4 bytes - this makes the &lt;b&gt;t&lt;/b&gt; pointer to point outside the segment, causing the segmentation fault at &lt;i&gt;printf&lt;/i&gt; time.&lt;br /&gt;&lt;br /&gt;Under 32bit it works as the pointer size is the same as the integer's size.&lt;br /&gt;&lt;br /&gt;Vaguely related, I like &lt;b&gt;clang's&lt;/b&gt; output better:&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;clang output&lt;/h3&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;cristi:tmp diciu$ clang test.c&lt;br /&gt;test.c:3:13: warning: implicit declaration of function 'getenv' is invalid in C99 [-Wimplicit-function-declaration]&lt;br /&gt;        char * t = getenv("PATH");&lt;br /&gt;                   ^&lt;br /&gt;test.c:3:9: warning: incompatible integer to pointer conversion initializing 'char *' with an expression of type 'int'&lt;br /&gt;        char * t = getenv("PATH");&lt;br /&gt;               ^   ~~~~~~~~~~~~~~&lt;br /&gt;test.c:4:2: warning: implicitly declaring C library function 'printf' with type 'int (char const *, ...)'&lt;br /&gt;        printf("&gt;%s&lt;\n", t);&lt;br /&gt;        ^&lt;br /&gt;test.c:4:2: note: please include the header &lt;stdio.h&gt; or explicitly provide a declaration for 'printf'&lt;br /&gt;3 warnings generated.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;gcc output&lt;/h3&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;cristi:tmp diciu$ gcc test.c&lt;br /&gt;test.c: In function ‘main’:&lt;br /&gt;test.c:3: warning: initialization makes pointer from integer without a cast&lt;br /&gt;test.c:4: warning: incompatible implicit declaration of built-in function ‘printf’&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/31740253-356337662302203287?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/356337662302203287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=356337662302203287' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/356337662302203287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/356337662302203287'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/08/in-64bit-sizeofint-sizeofchar-and.html' title='In 64bit sizeof(int) != sizeof(char *) and an unexpected side effect'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-581651829761274757</id><published>2010-08-04T21:49:00.003+03:00</published><updated>2010-08-04T22:02:01.668+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bucharest'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><title type='text'>Parks in Bucharest</title><content type='html'>Parks in Bucharest, based on data from OpenStreetMap:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rXrjDFwt37w/TFm4rmLK24I/AAAAAAAADfE/Ulo3kg4plO0/s1600/parcuri.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_rXrjDFwt37w/TFm4rmLK24I/AAAAAAAADfE/Ulo3kg4plO0/s320/parcuri.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5501631478931053442" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In numbers: 9.3 sq km out of Bucharest's 236.5 sq km.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-581651829761274757?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/581651829761274757/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=581651829761274757' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/581651829761274757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/581651829761274757'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/08/parks-in-bucharest.html' title='Parks in Bucharest'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_rXrjDFwt37w/TFm4rmLK24I/AAAAAAAADfE/Ulo3kg4plO0/s72-c/parcuri.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-9142889700728580196</id><published>2010-07-28T07:42:00.003+03:00</published><updated>2010-07-28T07:48:52.208+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='plpgsql'/><category scheme='http://www.blogger.com/atom/ns#' term='postgres'/><title type='text'>usleep in plpgsql</title><content type='html'>There is no sleep function in plpgsql under postgres 8.1, but you can create your own usleep function by using the one provided by glibc:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;openmapdb=# CREATE OR REPLACE FUNCTION usleep(int) RETURNS int AS&lt;br /&gt;openmapdb-# '/lib/libc.so.6', 'usleep' LANGUAGE 'C' STRICT;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In your plpgsql program, you can then call:&lt;br /&gt;&lt;pre&gt;PERFORM usleep(100000);&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/31740253-9142889700728580196?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/9142889700728580196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=9142889700728580196' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/9142889700728580196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/9142889700728580196'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/07/usleep-in-plpgsql.html' title='usleep in plpgsql'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-2449827067289759908</id><published>2010-06-10T14:40:00.004+03:00</published><updated>2010-06-10T15:12:49.804+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lldb'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='llvm'/><title type='text'>Running LLDB with a self-signed certificate</title><content type='html'>In a &lt;a href="http://blog.loudhush.ro/2010/06/lldb-new-debugger-on-mac-os-x.html"&gt;previous post&lt;/a&gt; I was describing running lldb using sudo to get around the need for elevated privileges as required by &lt;i&gt;task_for_pid&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;The obvious solution is to codesign the &lt;b&gt;debugserver&lt;/b&gt; binary. You can use a self-signed certificate, providing that the self signed certificate is trusted for code signing in your keychain.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Using &lt;b&gt;Keychain Access&lt;/b&gt;, run &lt;b&gt;Certificate Assistant&lt;/b&gt; -&gt; &lt;b&gt;Create a Certificate Authority...&lt;/b&gt;&lt;br /&gt;&lt;li&gt;From the &lt;b&gt;Keys&lt;/b&gt; category, select the newly created key and the contained certificate.&lt;br /&gt;&lt;li&gt;Right click the certificate and choose &lt;b&gt;Get Info&lt;/b&gt;.&lt;br /&gt;&lt;li&gt;Disclose the &lt;b&gt;Trust&lt;/b&gt; triangle and configure the &lt;b&gt;Code Signing&lt;/b&gt; option to &lt;b&gt;Always trust&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rXrjDFwt37w/TBDRTbu0dVI/AAAAAAAADPc/GsKsqUfPT48/s1600/Screen+shot+2010-06-10+at+2.46.38+PM.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 286px;" src="http://4.bp.blogspot.com/_rXrjDFwt37w/TBDRTbu0dVI/AAAAAAAADPc/GsKsqUfPT48/s320/Screen+shot+2010-06-10+at+2.46.38+PM.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5481110878301746514" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Codesign the &lt;b&gt;debugserver&lt;/b&gt; binary:&lt;br /&gt;&lt;pre&gt;cd ./build/BuildAndIntegration/LLDB.framework/Versions/A/Resources/&lt;br /&gt;codesign -s 'Cristian Draghici' ./debugserver&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Once you codesign the debug server, you should be able to run lldb as your current user.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-2449827067289759908?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/2449827067289759908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=2449827067289759908' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/2449827067289759908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/2449827067289759908'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/06/running-lldb-with-self-signed.html' title='Running LLDB with a self-signed certificate'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_rXrjDFwt37w/TBDRTbu0dVI/AAAAAAAADPc/GsKsqUfPT48/s72-c/Screen+shot+2010-06-10+at+2.46.38+PM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-9209279724730903388</id><published>2010-06-09T10:34:00.004+03:00</published><updated>2010-06-09T12:54:00.531+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lldb'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='llvm'/><title type='text'>LLDB, a new debugger on Mac OS X</title><content type='html'>The LLVM team is working on a &lt;a href="http://blog.llvm.org/2010/06/new-lldb-debugger.html"&gt;new debugger called lldb&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It compiles cleanly so you can give it a try if you have the devtools (including SVN client) installed on your machine. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Running it&lt;/h3&gt;&lt;br /&gt;You need to run the lldb-tool with the firewall disabled and as the superuser because it uses &lt;i&gt;task_for_pid&lt;/i&gt; and in 10.6 this requires superuser privileges or code signing on the binary. Since the binary is not signed, you need to run it with superuser privileges, otherwise you will get an error like: &lt;i&gt;"failed to send the qLaunchSuccess packet"&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;I run it this way:&lt;br /&gt;&lt;pre&gt;sudo DYLD_FRAMEWORK_PATH=/Users/diciu/Programming/external/lldb/build/BuildAndIntegration/ ./build/BuildAndIntegration/lldb /tmp/a.out&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;LLDB vs GDB&lt;/h3&gt;&lt;br /&gt;&lt;table style="font-family:Courier: font-size: 7px;"&gt;&lt;tr&gt;&lt;td width="50%"&gt;LLDB&lt;/td&gt;&lt;td&gt;GDB&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="vertical-align:top"&gt;&lt;i&gt;&lt;br /&gt;(lldb) breakpoint set -n main&lt;br /&gt;Breakpoint created: 1 Breakpoint by name: 'main' with 1 location;&lt;br /&gt;(lldb) r&lt;br /&gt;Launching '/private/tmp/a.out'  (x86_64)&lt;br /&gt;(lldb) Process 50271 Stopped&lt;br /&gt;* thread #1: tid = 0x2c03, pc = 0x0000000100000edb, where = a.out`main + 11 at /private/tmp/test.c:14, stop reason = breakpoint 1.1, queue = com.apple.main-thread&lt;br /&gt;  11    &lt;br /&gt;  12    int main()&lt;br /&gt;  13    {&lt;br /&gt;  14 -&gt;  struct i10 v = fun();&lt;br /&gt;  15    }&lt;br /&gt;&lt;/i&gt;&lt;/td&gt;&lt;td style="vertical-align:top"&gt;&lt;i&gt;&lt;br /&gt;(gdb) b main&lt;br /&gt;Breakpoint 1 at 0x100000edb: file test.c, line 14.&lt;br /&gt;(gdb) r&lt;br /&gt;Starting program: /private/tmp/a.out &lt;br /&gt;Reading symbols for shared libraries +. done&lt;br /&gt;&lt;br /&gt;Breakpoint 1, main () at test.c:14&lt;br /&gt;14  struct i10 v = fun();&lt;br /&gt;&lt;/i&gt;&lt;/td&gt;&lt;tr&gt;&lt;td style="vertical-align:top"&gt;&lt;i&gt;(lldb) disass&lt;br /&gt;0x100000ed0:  pushq  %rbp&lt;br /&gt;0x100000ed1:  movq   %rsp, %rbp&lt;br /&gt;0x100000ed4:  subq   $131072, %rsp&lt;br /&gt;0x100000edb:  leaq   -131072(%rbp), %rdi&lt;br /&gt;0x100000ee2:  movl   $0, %eax&lt;br /&gt;0x100000ee7:  callq  0x100000ea0              ; fun at /private/tmp/test.c:7&lt;br /&gt;0x100000eec:  leave&lt;br /&gt;0x100000eed:  ret&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;td style="vertical-align:top"&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;(gdb) disass main&lt;br /&gt;Dump of assembler code for function main:&lt;br /&gt;0x0000000100000ed0 &lt;main+0&gt;: push   %rbp&lt;br /&gt;0x0000000100000ed1 &lt;main+1&gt;: mov    %rsp,%rbp&lt;br /&gt;0x0000000100000ed4 &lt;main+4&gt;: sub    $0x20000,%rsp&lt;br /&gt;0x0000000100000edb &lt;main+11&gt;: lea    -0x20000(%rbp),%rdi&lt;br /&gt;0x0000000100000ee2 &lt;main+18&gt;: mov    $0x0,%eax&lt;br /&gt;0x0000000100000ee7 &lt;main+23&gt;: callq  0x100000ea0 &lt;fun&gt;&lt;br /&gt;0x0000000100000eec &lt;main+28&gt;: leaveq &lt;br /&gt;0x0000000100000eed &lt;main+29&gt;: retq   &lt;br /&gt;End of assembler dump.&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-9209279724730903388?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/9209279724730903388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=9209279724730903388' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/9209279724730903388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/9209279724730903388'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/06/lldb-new-debugger-on-mac-os-x.html' title='LLDB, a new debugger on Mac OS X'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-7940811734596178611</id><published>2010-05-19T13:03:00.005+03:00</published><updated>2010-06-11T12:16:32.046+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='htc legend'/><title type='text'>The Missing Sync for Android 2.1 only half compatible with HTC Legend</title><content type='html'>&lt;h3&gt;&lt;i&gt;Update June 11th&lt;/i&gt;&lt;/h3&gt;&lt;i&gt;I've upgraded both the Missing Sync Android client and the Mac OS X version to 1.4+ and the problem has been fixed - contacts appear correctly on the phone.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="gray"&gt;&lt;br /&gt;If you're looking into using The Missing Sync for Android as a sync solution for your HTC Legend, you may want to know that it only works half way:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Contacts from the Mac Address Book cannot be edited on the phone&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Contacts from the Mac Address Book do not appear in the People app, under Applications&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Details here: &lt;a href="https://support.markspace.com/index.php?_m=knowledgebase&amp;_a=viewarticle&amp;kbarticleid=482&amp;nav=0,115"&gt;The Missing Sync for Android 2.1: HTC Sense UI (HTC Desire, Legend, Droid Eris, and Droid Incredible) Contact Sync Issues&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I have to say I am disappointed considering the price point they chose for their software (50 USD).&lt;br /&gt;&lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-7940811734596178611?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/7940811734596178611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=7940811734596178611' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7940811734596178611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7940811734596178611'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/05/missing-sync-for-android-21-only-half.html' title='The Missing Sync for Android 2.1 &lt;s&gt;only half&lt;/s&gt; compatible with HTC Legend'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-8889238271596202785</id><published>2010-03-31T14:06:00.006+03:00</published><updated>2010-03-31T14:26:37.807+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tesseract'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='ocr'/><title type='text'>Processing tiff images for TessertactGUI</title><content type='html'>When processing images, &lt;i&gt;tesseract&lt;/i&gt; is very restrictive about the images it processes.&lt;br /&gt;It only touches TIFF files, with the extension "tif" and uncompressed.&lt;br /&gt;&lt;br /&gt;Unfortunately, TesseractGUI is not very straightforward about the reason it rejects files from processing (it would just say "Error reading tesseract output").&lt;br /&gt;&lt;br /&gt;Here's how you can identify the error and fix it:&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Run tesseract from the command line to find out more about the rejection cause&lt;/h3&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;cristi:~ diciu$ export TESSDATA_PREFIX=/Applications/TesseractGUI.app/Contents/Resources/&lt;br /&gt;cristi:~ diciu$ /Applications/TesseractGUI.app/Contents/Resources/tesseract ~/Desktop/tiffs/page1.tif /tmp/ocrtest.txt&lt;br /&gt;Tesseract Open Source OCR Engine&lt;br /&gt;read_tif_image:Error:Illegal image format:Compression&lt;br /&gt;/Applications/TesseractGUI.app/Contents/Resources/tesseract:Error:Read of file failed:/Users/diciu/Desktop/tiffs/page1.tif&lt;br /&gt;Signal_exit 31 ABORT. LocCode: 3  AbortCode: 3&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;the problem with this particular TIFF file is the compression.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Fixing the problem&lt;/h3&gt;&lt;br /&gt;Step 1/ Download &lt;a href="http://www.imagemagick.org/script/binary-releases.php#macosx"&gt;ImageMagick&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Step 2/ Identify the TIFF file we want to use:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;cd /Users/diciu/Downloads/ImageMagick-6.5.8/bin&lt;br /&gt;export DYLD_FALLBACK_LIBRARY_PATH=/Users/diciu/Downloads/ImageMagick-6.5.8/lib&lt;br /&gt;export MAGICK_HOME=/Users/diciu/Downloads/ImageMagick-6.5.8/&lt;br /&gt;cristi:bin diciu$ tiffutil -info ~/Desktop/tiffs/page1.tif &lt;br /&gt;Directory at 0x837f8&lt;br /&gt;  Subfile Type: (0 = 0x0)&lt;br /&gt;  Image Width: 1200 Image Length: 2088&lt;br /&gt;  Resolution: 200, 200&lt;br /&gt;  Resolution Unit: pixels/inch&lt;br /&gt;  Bits/Sample: 8&lt;br /&gt;  Compression Scheme: Lempel-Ziv &amp; Welch encoding&lt;br /&gt;  Photometric Interpretation: palette color (RGB from colormap)&lt;br /&gt;  Predictor: none&lt;br /&gt;  Samples/Pixel: 1&lt;br /&gt;  Rows/Strip: 10&lt;br /&gt;  Number of Strips: 209&lt;br /&gt;  Planar Configuration: Not planar&lt;br /&gt;  Color Map: (present)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note the compression scheme (LZW).&lt;br /&gt;&lt;br /&gt;Step 3/ Uncompress the TIFF file&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;tiffutil -none ~/Desktop/tiffs/page1.tif -out ~/Desktop/tiffs/page1_uncompressed.tif&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now use page1_uncompressed.tif with tesseract.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Related:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://blog.loudhush.ro/2009/02/tesseract-gui.html"&gt;TesseractGUI&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://blog.loudhush.ro/2008/12/open-source-ocr-on-mac-os-x-tesseract.html"&gt;tesseract&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-8889238271596202785?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/8889238271596202785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=8889238271596202785' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8889238271596202785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8889238271596202785'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/03/processing-tif-images-for-tessertactgui.html' title='Processing tiff images for TessertactGUI'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-4934884820202289937</id><published>2010-03-02T15:50:00.004+02:00</published><updated>2010-03-03T09:37:00.140+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='email'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>Send HTML email from Cocoa. Take 2.</title><content type='html'>This is an alternate solution to &lt;a href="http://blog.loudhush.ro/2009/12/sending-html-email-from-cocoa.html"&gt;sending HTML email from Cocoa&lt;/a&gt;, that takes advantage of python's email capabilities.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/SzUN0MQW-rI/AAAAAAAADH0/2tVgw7PJ1Jo/s1600-h/multipart.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 306px; height: 320px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/SzUN0MQW-rI/AAAAAAAADH0/2tVgw7PJ1Jo/s320/multipart.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5419252916904458930" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The python email package allows a much cleaner source when writing the code for sending the HTML email:&lt;br /&gt;&lt;br /&gt;==================== htmlemail.py ==================&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;from email.mime import Multipart, Text, Image&lt;br /&gt;import smtplib&lt;br /&gt;&lt;br /&gt;email_from = "sender@domain.com"&lt;br /&gt;email_to = "recipient@domain.com"&lt;br /&gt;msg = Multipart.MIMEMultipart('alternative')&lt;br /&gt;msg['Subject'] = "HTML email"&lt;br /&gt;msg['From'] = email_from&lt;br /&gt;msg['To'] = email_to&lt;br /&gt;&lt;br /&gt;text = "Plain text version"&lt;br /&gt;html = "&amp;lt;html&amp;gt;&amp;lt;p&amp;gt;A little bit in &amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt; and some &amp;lt;i&amp;gt;italic&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;img src="cid:55665566" /&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;The end&amp;lt;/p&amp;gt;&amp;lt;/html&amp;gt;"&lt;br /&gt;&lt;br /&gt;part1 = Text.MIMEText(text, 'plain')&lt;br /&gt;&lt;br /&gt;# the embedded image&lt;br /&gt;fp = open("/Users/diciu/Desktop/test.png")&lt;br /&gt;&lt;br /&gt;# assemble the message based on the diagram&lt;br /&gt;part2 = Multipart.MIMEMultipart('related')&lt;br /&gt;part21 = Text.MIMEText(html, 'html')&lt;br /&gt;part22 = Image.MIMEImage(fp.read(), _subtype='PNG')&lt;br /&gt;part22.add_header('Content-ID', '55665566')&lt;br /&gt;&lt;br /&gt;msg.attach(part1)&lt;br /&gt;part2.attach(part21)&lt;br /&gt;part2.attach(part22)&lt;br /&gt;msg.attach(part2)&lt;br /&gt;&lt;br /&gt;s = smtplib.SMTP('some.smtp.server')&lt;br /&gt;s.sendmail(email_from, email_to, msg.as_string())&lt;br /&gt;&lt;br /&gt;s.quit()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To use the Python code from Cocoa, we use the Python framework:&lt;br /&gt;&lt;br /&gt;==================== htmlemail.m ==================&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// build with:&lt;br /&gt;//      gcc htmlemail.m -framework Cocoa -framework Python&lt;br /&gt;//&lt;br /&gt;#import &amp;lt;Cocoa/Cocoa.h&amp;gt;&lt;br /&gt;#import &amp;lt;Python/Python.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; NSAutoreleasePool * m = [NSAutoreleasePool new];&lt;br /&gt; NSError * err = nil;&lt;br /&gt; NSString * pycode = [NSString stringWithContentsOfFile:@"./htmlemail.py" &lt;br /&gt;    encoding:NSASCIIStringEncoding error:&amp;amp;err];&lt;br /&gt;&lt;br /&gt; Py_Initialize(); &lt;br /&gt; PyRun_SimpleString([pycode cStringUsingEncoding:NSASCIIStringEncoding]);&lt;br /&gt; Py_Finalize();&lt;br /&gt; &lt;br /&gt; [m release];&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&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/31740253-4934884820202289937?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/4934884820202289937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=4934884820202289937' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4934884820202289937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4934884820202289937'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/03/send-html-email-from-cocoa-take-2.html' title='Send HTML email from Cocoa. Take 2.'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rXrjDFwt37w/SzUN0MQW-rI/AAAAAAAADH0/2tVgw7PJ1Jo/s72-c/multipart.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-414904716806495715</id><published>2010-02-28T10:26:00.004+02:00</published><updated>2010-03-01T09:11:30.966+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='romania'/><title type='text'>BizBazar canceled</title><content type='html'>I've never written an opinion piece on this here blog, partly because this blog is more of a technical knowledge base I keep for myself and also because I don't like blurting out my thoughts in the forever archived searchable medium that is the internet.&lt;br /&gt;&lt;br /&gt;I will make an exception because one of the things I care deeply about is gone. I find it surprising that I'm writing I care about a TV show, but this show I'm talking about was a special show, an example of a great team working hard for what I can only describe as true journalism.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Television in Romania&lt;/h3&gt;&lt;br /&gt;I don't really know how TV is elsewhere these days, but in Romania it's in a state of suffering. News shows are based on violence, be it physical or psychological violence. The viewer is fed 30 minutes of car accidents, rapes, killings, stories on raising taxes, raising prices, corruption in politics, repeated ad nauseam.&lt;br /&gt;&lt;br /&gt;News are written to stir up feelings, with passion rather then detachment, thus it's a common occurrence for the news anchor to pass judgment when presenting the news. A suspect is more often than not shown as guilty, stories are written in such a manner that the viewer is gratified with a speedy one minute trial of the scene unraveled before him. &lt;br /&gt;&lt;br /&gt;If it's a car accident, the reporter will interview a couple of eye witnesses that will describe how the driver involved in the accident was doing at least 100 KPH just before the accident. It's common knowledge that a human can estimate car speeds by just looking, right? The reporter will never fail to mention that the driver's license is less then 5 years old, not-so-subtly implying that lack of experience is a major contributing factor to the crash.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;BizBazar&lt;/h3&gt;&lt;br /&gt;The show that's gone is called &lt;a href="http://biziday.ro/2010/02/26/bizbazar-over-and-out/"&gt;BizBazar&lt;/a&gt; and what made it special was that it always tried to present both sides of the story. It was refreshing to see a conversation between a host and his guest where the host &lt;i&gt;is&lt;/i&gt; presenting the guest with an opportunity to speak his mind, although it's obvious their views on the matter diverge greatly.&lt;br /&gt;&lt;br /&gt;BizBazar was one of the rare shows whose team did not claim expertise in every conceivable subject, and this was a very welcome change compared to the rest of the shows out there, whose hosts will prefer talking nonsense to admitting the subject at hand is a big unknown.&lt;br /&gt;&lt;br /&gt;BizBazar has been a fresh take on the news, light years away from the paranoia that characterizes so much of our media these days.&lt;br /&gt;&lt;br /&gt;My hat's off to the team, good luck in whatever you will try next, and thanks for all the fish.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-414904716806495715?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/414904716806495715/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=414904716806495715' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/414904716806495715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/414904716806495715'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/02/bizbazar-canceled.html' title='BizBazar canceled'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5031287113880829556</id><published>2010-02-25T16:38:00.006+02:00</published><updated>2010-02-25T16:53:28.004+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vi'/><category scheme='http://www.blogger.com/atom/ns#' term='notetoself'/><title type='text'>vim - replace command conditioned by preceding and following atoms</title><content type='html'>Going from:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;John has one hundred apples&lt;br /&gt;Jane has twelve hundred and fifty seven apples&lt;br /&gt;Mary has thirty seven apples&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;to&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;John has one_hundred apples&lt;br /&gt;Jane has twelve_hundred_and_fifty_seven apples&lt;br /&gt;Mary has thirty_seven apples&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;in &lt;a href="http://vimdoc.sourceforge.net/htmldoc/pattern.html#/\@%3C="&gt;vim&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;.,$s/\(has .*\)\@&lt;= \(.* apples\)\@=/_/g&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/31740253-5031287113880829556?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5031287113880829556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5031287113880829556' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5031287113880829556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5031287113880829556'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/02/vim-replace-command-conditioned-by.html' title='vim - replace command conditioned by preceding and following atoms'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-3151603499215776119</id><published>2010-02-24T10:14:00.004+02:00</published><updated>2010-02-24T13:45:43.690+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='valgrind'/><category scheme='http://www.blogger.com/atom/ns#' term='10.6'/><title type='text'>Compiling Valgrind on Snow Leopard</title><content type='html'>Checkout the valgrind sources:&lt;br /&gt;&lt;br /&gt;&lt;pre class='prettyprint'&gt;svn co svn://svn.valgrind.org/valgrind/tags/VALGRIND_3_5_0 valgrind&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Download Greg Parker's 10.6 patch&lt;br /&gt;&lt;pre class='prettyprint'&gt;curl http://bugsfiles.kde.org/attachment.cgi?id=36999 &gt; 10.6.patch&lt;br /&gt;mv 10.6.patch ./valgrind&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Apply the patch&lt;br /&gt;&lt;br /&gt;&lt;pre class='prettyprint'&gt;cd valgrind&lt;br /&gt;patch -p0 &lt; 10.6.patch&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Compile valgrind (if you want to run it on 64 bit binaries, use "./configure --build=amd64-darwin", otherwise you'll build it for 32 bits)&lt;br /&gt;&lt;pre class='prettyprint'&gt;./autogen.sh&lt;br /&gt;./configure&lt;br /&gt;make&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Install it&lt;br /&gt;&lt;pre class='prettyprint'&gt;sudo make install&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Run it&lt;br /&gt;&lt;pre class='prettyprint'&gt;cristi:tmp diciu$ cat /tmp/test.c&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; char * t = malloc(1024);&lt;br /&gt; char * w = "Ana";&lt;br /&gt; &lt;br /&gt; t = w;&lt;br /&gt;}&lt;br /&gt;cristi:tmp diciu$ gcc -arch i386 /tmp/test.c&lt;br /&gt;cristi:tmp diciu$ valgrind --leak-check=full /tmp/a.out&lt;br /&gt;[..]&lt;br /&gt;==938== HEAP SUMMARY:&lt;br /&gt;==938==     in use at exit: 1,344 bytes in 8 blocks&lt;br /&gt;==938==   total heap usage: 8 allocs, 0 frees, 1,344 bytes allocated&lt;br /&gt;==938== &lt;br /&gt;==938== 1,024 bytes in 1 blocks are definitely lost in loss record 4 of 4&lt;br /&gt;==938==    at 0xF666: malloc (vg_replace_malloc.c:195)&lt;br /&gt;==938==    by 0x1F66: main (in /tmp/a.out)&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/31740253-3151603499215776119?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/3151603499215776119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=3151603499215776119' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3151603499215776119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3151603499215776119'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/02/compiling-valgrind-on-snow-leopard.html' title='Compiling Valgrind on Snow Leopard'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-4613758056029776280</id><published>2010-01-06T14:08:00.004+02:00</published><updated>2010-01-06T14:34:11.568+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sandbox'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>Using the Snow Leopard sandbox</title><content type='html'>First and foremost, a warning that's prominently displayed in all sandbox definition files:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt; WARNING: The sandbox rules [..] currently constitute Apple System Private Interface and are subject to change at any time and&lt;br /&gt; without notice. The contents of this file are also auto-generated and not user editable; it may be overwritten at any time.&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;The sandbox being a private interface is probably the reason why the sandbox policy files are un-documented. However, in the standard Snow Leopard install there are a bunch of files that define sandboxing policies ( under /System/Library/Sandbox/Profiles/ and /usr/share/sandbox/) that can be used to derive new policy files.&lt;br /&gt;&lt;br /&gt;When creating a policy file for HTTP, the most verbose section out of our sandbox definition turns out to be the section for allowing DNS queries. &lt;br /&gt;&lt;br /&gt;&lt;H3&gt;http.sb&lt;/H3&gt;&lt;br /&gt;&lt;PRE class='prettyprint'&gt;&lt;br /&gt;(version 1)&lt;br /&gt;(debug deny)&lt;br /&gt;&lt;br /&gt;;; DNS&lt;br /&gt;(allow file-read-metadata&lt;br /&gt;        (literal &amp;quot;/var&amp;quot;)&lt;br /&gt;        (literal &amp;quot;/etc&amp;quot;))&lt;br /&gt;&lt;br /&gt;(allow ipc-posix-shm)&lt;br /&gt;&lt;br /&gt;(allow mach-lookup&lt;br /&gt;  (global-name &amp;quot;com.apple.SystemConfiguration.configd&amp;quot;)&lt;br /&gt;  (global-name &amp;quot;com.apple.system.notification_center&amp;quot;))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(allow network-outbound&lt;br /&gt;       (remote unix-socket (path-literal &amp;quot;/private/var/run/mDNSResponder&amp;quot;)))&lt;br /&gt;&lt;br /&gt;;; HTTP traffic&lt;br /&gt;(allow network-outbound (remote ip4 &amp;quot;*:80&amp;quot;))&lt;br /&gt;&lt;br /&gt;(deny default)&lt;br /&gt;&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;&lt;br /&gt;Our test program runs a couple of functions - a curl based HTTP client and a file read operation.&lt;br /&gt;&lt;br /&gt;&lt;H3&gt;test.c&lt;/H3&gt;&lt;br /&gt;&lt;PRE CLASS='prettyprint'&gt;&lt;br /&gt;#include &amp;lt;sandbox.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;curl/curl.h&amp;gt;&lt;br /&gt;&lt;br /&gt;size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)&lt;br /&gt;{&lt;br /&gt; int i=0;&lt;br /&gt; //exit after 80 chars&lt;br /&gt; for(;i&amp;lt;size * nmemb &amp;amp;&amp;amp; i &amp;lt; 80;i++)&lt;br /&gt;  fprintf(stderr, &amp;quot;%c&amp;quot;, (unsigned char)((char *)buffer)[i]);&lt;br /&gt; fprintf(stderr, &amp;quot;[..]\n&amp;quot;);&lt;br /&gt;}&lt;br /&gt;int httpRequest()&lt;br /&gt;{&lt;br /&gt; CURL * easyhandle = curl_easy_init();&lt;br /&gt; curl_easy_setopt(easyhandle, CURLOPT_URL, &amp;quot;http://loudhush.ro/changelog.txt&amp;quot;);&lt;br /&gt; curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data);&lt;br /&gt; curl_easy_perform(easyhandle);&lt;br /&gt;}&lt;br /&gt;int readFile()&lt;br /&gt;{&lt;br /&gt; FILE * f = fopen(&amp;quot;/etc/passwd&amp;quot;, &amp;quot;r&amp;quot;);&lt;br /&gt; if(f == NULL)&lt;br /&gt; {&lt;br /&gt;  perror(&amp;quot;Error opening file&amp;quot;);&lt;br /&gt;  return 1;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; char line[1024];&lt;br /&gt; while(fgets(line, 1023, f) != NULL)&lt;br /&gt;  fprintf(stdout, &amp;quot;Line: %s&amp;quot;, line);&lt;br /&gt;&lt;br /&gt; fclose(f);&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; char * errbuf;&lt;br /&gt; int retval = sandbox_init(&amp;quot;/Users/diciu/Programming/sandbox/http.sb&amp;quot;, SANDBOX_NAMED, &amp;amp;errbuf);&lt;br /&gt; if(retval)&lt;br /&gt; {&lt;br /&gt;  fprintf(stderr, &amp;quot;Sandbox init error: %s\n&amp;quot;, errbuf);&lt;br /&gt;  return 1;&lt;br /&gt; }&lt;br /&gt; fprintf(stderr, &amp;quot;--- HTTP request ---\n&amp;quot;);&lt;br /&gt; httpRequest();&lt;br /&gt; fprintf(stderr, &amp;quot;\n--- File read request ---\n&amp;quot;);&lt;br /&gt; readFile();&lt;br /&gt;}&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As expected, once the sandbox is initialized, HTTP requests go through but the file access operation is denied:&lt;br /&gt;&lt;br /&gt;&lt;PRE class='prettyprint'&gt;&lt;br /&gt;cristi:sandbox diciu$ ./a.out &lt;br /&gt;--- HTTP request ---&lt;br /&gt;LoudHush 1.3.21&lt;br /&gt;&lt;br /&gt;- Fixed a couple of leaks in AccountController/Management&lt;br /&gt;- Fix[..]&lt;br /&gt;&lt;br /&gt;--- File read request ---&lt;br /&gt;Error opening file: Operation not permitted&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;&lt;br /&gt;Attempts to go out of the sandbox are logged in syslog:&lt;br /&gt;&lt;PRE class="prettyprint"&gt;&lt;br /&gt;Jan  6 14:13:37 cristi sandboxd[59224]: a.out(59222) deny file-read-data /private/etc/passwd&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/31740253-4613758056029776280?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/4613758056029776280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=4613758056029776280' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4613758056029776280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4613758056029776280'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/01/using-snow-leopard-sandbox.html' title='Using the Snow Leopard sandbox'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-4478465603757351176</id><published>2010-01-04T10:51:00.005+02:00</published><updated>2010-01-04T17:14:02.323+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='loudhush'/><category scheme='http://www.blogger.com/atom/ns#' term='asterisk'/><title type='text'>LoudHush compatibility with Asterisk 1.4.26.2+ requires configuration on server</title><content type='html'>With recent versions of Asterisk, a security triggered upgrade broke the IAX protocol as LoudHush knows it, by adding a new IAX IE called CALLTOKEN (see &lt;a href="http://svn.digium.com/svn/asterisk/branches/1.4/doc/IAX2-security.pdf"&gt;IAX2 Security&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;When trying to register with an IAX account with CALLTOKEN enabled, LoudHush will display "Registration rejected" and the Asterisk server will log:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;chan_iax2.c: Call rejected, CallToken Support required.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To disable the CALLTOKEN functionality from the server, allowing LoudHush to register, the following lines need to be added in the iax configuration:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;calltokenoptional = 0.0.0.0/0.0.0.0&lt;br /&gt;maxcallnumbers = 16382&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/31740253-4478465603757351176?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/4478465603757351176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=4478465603757351176' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4478465603757351176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4478465603757351176'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2010/01/loudhush-compatibility-with-asterisk.html' title='LoudHush compatibility with Asterisk 1.4.26.2+ requires configuration on server'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-1261741119937037460</id><published>2009-12-25T21:08:00.009+02:00</published><updated>2009-12-28T16:28:27.434+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c-client'/><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>Sending HTML email from Cocoa</title><content type='html'>In a &lt;a href="http://blog.loudhush.ro/2009/10/sending-mail-on-snow-leopard-using-c.html"&gt;previous post&lt;/a&gt; I described sending email using c-client. This post takes things a little bit further and describes sending an email containing HTML content using the same c-client API.&lt;br /&gt;&lt;br /&gt;First things first - people usually call HTML email an HTML fragment that refers inline images. These images are part of the email too and they are referred in the HTML source by their content id (using a special construct on the source reference, i.e. &lt;i&gt;img src="cid:image_content_id"&lt;/i&gt;). &lt;br /&gt;&lt;br /&gt;Mail clients (at least Snow Leopard's Mail.app) expect the HTML fragment and the images they refer to be part of the same container. This container is a MIME multipart/related container.&lt;br /&gt;&lt;br /&gt;The simplest HTML message that we can send is based on the following MIME multipart structure:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/SzUN0MQW-rI/AAAAAAAADH0/2tVgw7PJ1Jo/s1600-h/multipart.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 306px; height: 320px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/SzUN0MQW-rI/AAAAAAAADH0/2tVgw7PJ1Jo/s320/multipart.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5419252916904458930" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;#include &amp;lt;c-client.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include &amp;quot;c-client-interface.c&amp;quot;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;        #include &amp;quot;linkage.c&amp;quot;&lt;br /&gt;&lt;br /&gt;        char * hostlist[] = { &amp;quot;smtp.gmail.com/ssl/user=user@gmail.com/smtp&amp;quot;, NULL };&lt;br /&gt;&lt;br /&gt;        SENDSTREAM * sndstream = smtp_open(hostlist, 0);&lt;br /&gt;        if(sndstream == NULL)&lt;br /&gt;        {&lt;br /&gt;                fprintf(stderr, &amp;quot;Can't open SMTP connection\n&amp;quot;);&lt;br /&gt;                return 1;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        BODY * body = mail_newbody();&lt;br /&gt;&lt;br /&gt;        ENVELOPE * env = mail_newenvelope();&lt;br /&gt;        ADDRESS * to = mail_newaddr();&lt;br /&gt;&lt;br /&gt;        env-&amp;gt;from = mail_newaddr();&lt;br /&gt;        env-&amp;gt;from-&amp;gt;personal = strdup(&amp;quot;User Name&amp;quot;);&lt;br /&gt;        env-&amp;gt;from-&amp;gt;mailbox = strdup(&amp;quot;username&amp;quot;);&lt;br /&gt;        env-&amp;gt;from-&amp;gt;host = strdup(&amp;quot;gmail.com&amp;quot;);&lt;br /&gt;        env-&amp;gt;subject = strdup(&amp;quot;subject&amp;quot;);&lt;br /&gt;&lt;br /&gt;        rfc822_parse_adrlist(&amp;amp;env-&amp;gt;to, strdup(&amp;quot;username&amp;quot;), strdup(&amp;quot;destination.dom&amp;quot;));&lt;br /&gt;&lt;br /&gt;        char *text = (char *) fs_get (8*MAILTMPLEN);&lt;br /&gt;        strcpy(text, &amp;quot;test message \015\012\0&amp;quot;);&lt;br /&gt;&lt;br /&gt;        #define HTMLfragment &amp;quot;&amp;lt;HTML&amp;gt;&amp;lt;p&amp;gt;A little bit in &amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt; and some &amp;lt;i&amp;gt;italic&amp;lt;/i&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt; &amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;img src=\&amp;quot;cid:55665566\&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;The end&amp;lt;/p&amp;gt;&amp;lt;/HTML&amp;gt;&amp;quot;&lt;br /&gt;&lt;br /&gt;/* We need three parts, a part for HTML, a part for the image and &lt;br /&gt;a part that groups them (called &lt;i&gt;related&lt;/i&gt;). */&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        PART * htmlpart, *imagepart, *related;&lt;br /&gt;        related = mail_newbody_part();&lt;br /&gt;        related-&amp;gt;body.type = TYPEMULTIPART;&lt;br /&gt;        related-&amp;gt;body.subtype =  cpystr(&amp;quot;related&amp;quot;);&lt;br /&gt;&lt;br /&gt;        htmlpart = mail_newbody_part();&lt;br /&gt;        htmlpart-&amp;gt;body.encoding = ENCBASE64;&lt;br /&gt;        htmlpart-&amp;gt;body.contents.text.data = (char *) rfc822_binary (HTMLfragment, strlen(HTMLfragment), &amp;amp;htmlpart-&amp;gt;body.contents.text.size);&lt;br /&gt;&lt;br /&gt;        htmlpart-&amp;gt;body.parameter = mail_newbody_parameter ();&lt;br /&gt;        htmlpart-&amp;gt;body.parameter-&amp;gt;attribute = cpystr (&amp;quot;CHARSET&amp;quot;);        &lt;br /&gt;        htmlpart-&amp;gt;body.parameter-&amp;gt;value = cpystr (&amp;quot;US-ASCII&amp;quot;);        &lt;br /&gt;        htmlpart-&amp;gt;body.type = TYPETEXT;        &lt;br /&gt;        htmlpart-&amp;gt;body.subtype = cpystr (&amp;quot;HTML&amp;quot;);&lt;br /&gt;        htmlpart-&amp;gt;body.description = cpystr (&amp;quot;html version&amp;quot;);&lt;br /&gt;&lt;br /&gt;        //for brevity, we define a GIF file inline. in real code, you would probably load this from a file&lt;br /&gt;        unsigned char buf[] = {0x47, 0x49, 0x46,0x38,0x37,0x61,0x0c,0x00,0x0c,0x00,0xc2,0x04,0x00,0x00,0x24,0xff,0xff,0x00,0x00,0x00,0xa0,0x0b,0xf6,0x7a&lt;br /&gt;,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x0c,0x00,0x0c,0x00,0x00,0x03,0x23,0x18,0xba,0xd3,0xbe,0xcc,0&lt;br /&gt;x35,0xa8,0xe4,0xa4,0x76,0x50,0x42,0x2c,0xe4,0x9c,0x24,0x8c,0x02,0x48,0x00,0x28,0x40,0x8e,0x5c,0x8a,0xae,0xa3,0xfb,0xc2,0xb2,0x4a,0xcb,0xb0,0x50,0x27,0x0&lt;br /&gt;0,0x3b};&lt;br /&gt;&lt;br /&gt;        /* allocate a MIME part for the image content at the end of the HTML part */&lt;br /&gt;        imagepart = (htmlpart-&amp;gt;next = mail_newbody_part());&lt;br /&gt;        /* the image is binary so we encode in base64 */&lt;br /&gt;        imagepart-&amp;gt;body.encoding = ENCBASE64;&lt;br /&gt;        imagepart-&amp;gt;body.contents.text.data = (char *) rfc822_binary(buf, 86, &amp;amp;imagepart-&amp;gt;body.contents.text.size);&lt;br /&gt;        imagepart-&amp;gt;body.type = TYPEIMAGE;&lt;br /&gt;        imagepart-&amp;gt;body.subtype = cpystr (&amp;quot;GIF&amp;quot;);&lt;br /&gt;        imagepart-&amp;gt;body.id = cpystr(&amp;quot;&amp;lt;55665566&amp;gt;&amp;quot;);&lt;br /&gt;&lt;br /&gt;/* Our body's content is of type multipart and it contains a nested part &lt;br /&gt;that is in fact the related part that we have created above */&lt;br /&gt;&lt;br /&gt;        body-&amp;gt;type = TYPEMULTIPART;&lt;br /&gt;        body-&amp;gt;subtype = cpystr(&amp;quot;alternative&amp;quot;);&lt;br /&gt;        body-&amp;gt;nested.part = mail_newbody_part ();&lt;br /&gt;        body-&amp;gt;nested.part-&amp;gt;body.contents.text.data = text;&lt;br /&gt;        body-&amp;gt;nested.part-&amp;gt;body.contents.text.size = strlen (text);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        related-&amp;gt;body.nested.part = htmlpart;&lt;br /&gt;        body-&amp;gt;nested.part-&amp;gt;next = related;&lt;br /&gt;&lt;br /&gt;        long result = smtp_mail(sndstream, &amp;quot;MAIL&amp;quot;, env, body);&lt;br /&gt;&lt;br /&gt;        if(sndstream)&lt;br /&gt;                smtp_close(sndstream);&lt;br /&gt;&lt;br /&gt;        mail_free_envelope(&amp;amp;env);&lt;br /&gt;        mail_free_body(&amp;amp;body);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Our message in Mail.app:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/SzUUfn-8iWI/AAAAAAAADIE/Hw5pTJxmapo/s1600-h/messagecap.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 97px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/SzUUfn-8iWI/AAAAAAAADIE/Hw5pTJxmapo/s400/messagecap.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5419260260151757154" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-1261741119937037460?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/1261741119937037460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=1261741119937037460' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1261741119937037460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1261741119937037460'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/12/sending-html-email-from-cocoa.html' title='Sending HTML email from Cocoa'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rXrjDFwt37w/SzUN0MQW-rI/AAAAAAAADH0/2tVgw7PJ1Jo/s72-c/multipart.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-3081454087139968251</id><published>2009-12-11T09:13:00.009+02:00</published><updated>2011-02-09T08:12:43.191+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qrcode'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><title type='text'>Creating QR codes on Mac OS X Snow Leopard</title><content type='html'>This post describes a step by step procedure to compile and run &lt;i&gt;qrencode&lt;/i&gt;, a command line tool for encoding text into png files of QRcodes written by FUKUCHI Kentaro as part of libqrencode (licensed under LGPL).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1/ Create a directory for our project&lt;br /&gt;&lt;pre class="prettyprint"&gt;cristi:~ diciu$ mkdir qr&lt;br /&gt;cristi:~ diciu$ cd qr/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;2/ Download the &lt;a href="http://megaui.net/fukuchi/works/qrencode/index.en.html"&gt;libqrencode&lt;/a&gt; source, and untar it.&lt;br /&gt;&lt;pre class="prettyprint"&gt;cristi:qr diciu$ tar zxvf qrencode-3.1.0.tar.gz&lt;br /&gt;cristi:qr diciu$ cd qrencode-3.1.0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;3/ We need to set a couple of environment variables to tell &lt;i&gt;configure&lt;/i&gt; where the &lt;i&gt;libpng&lt;/i&gt; libraries and headers are:&lt;br /&gt;&lt;pre class="prettyprint"&gt;cristi:qrencode-3.1.0 diciu$export png_CFLAGS="-I /usr/X11/include/"&lt;br /&gt;cristi:qrencode-3.1.0 diciu$export png_LIBS="-lpng -L/usr/X11/lib/"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;4/ Even though we don't need pkg-config (that's why we exported vars in step 3), &lt;i&gt;configure&lt;/i&gt; requires a pkg-config script, so we'll create an empty one and add it to the path.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;cristi:qrencode-3.1.0 diciu$ touch pkg-config&lt;br /&gt;cristi:qrencode-3.1.0 diciu$ chmod +x pkg-config &lt;br /&gt;cristi:qrencode-3.1.0 diciu$ export PATH=$PATH:.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;5/ Now we have everything we need, so we can run &lt;i&gt;./configure&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;./configure&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;6/ Once configure runs, we can run make to build it&lt;br /&gt;&lt;pre class="prettyprint"&gt;make&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;7/ And finally we get to encode a qr code:&lt;br /&gt;&lt;pre&gt;./qrencode -o ~/Desktop/modulo.png "http://www.modulo.ro"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The end result:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/SyH0lu0EdWI/AAAAAAAADHs/yftkgJ4-9cY/s1600-h/modulo.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 99px; height: 99px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/SyH0lu0EdWI/AAAAAAAADHs/yftkgJ4-9cY/s400/modulo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5413877156134810978" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-3081454087139968251?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/3081454087139968251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=3081454087139968251' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3081454087139968251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3081454087139968251'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/12/creating-qr-codes-on-mac-os-x-snow.html' title='Creating QR codes on Mac OS X Snow Leopard'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rXrjDFwt37w/SyH0lu0EdWI/AAAAAAAADHs/yftkgJ4-9cY/s72-c/modulo.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-6464263953451203389</id><published>2009-12-04T20:08:00.004+02:00</published><updated>2009-12-04T21:11:45.508+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Query strings received from Google</title><content type='html'>Some of the unexpected queries that get here and some hopefully useful answers:&lt;br /&gt;&lt;br /&gt;1/ Some &lt;i&gt;netstat&lt;/i&gt; based commands, e.g.:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;netstat -anp | grep "tcp\|udp" | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As far as I can tell, it prints a summary of network connections. This includes established connections and connections that are about to close, and also connections that are locally awaiting for a client.&lt;br /&gt;&lt;br /&gt;In the Mac OS X version of netstat, the "-p" option is not supported; &lt;i&gt;sort&lt;/i&gt; is also capable of uniquing its results so you can rewrite the line as:&lt;br /&gt;&lt;pre class="prettyPrint"&gt;&lt;br /&gt;netstat -an | grep "tcp\|udp" | awk '{print $5}' | cut -d: -f1 | sort -nu&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2/ &lt;i&gt;check a word how many times in nsstring &lt;/i&gt;&lt;br /&gt;&lt;br /&gt;I'd do something like:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;int count = 0;&lt;br /&gt;NSString * s = [NSString stringWithString:@"foobar contains foobar and some more foobar"];&lt;br /&gt;while([s rangeOfString:@"foobar"].location != NSNotFound)&lt;br /&gt;{&lt;br /&gt;    count++;&lt;br /&gt;    s = [s substringFromIndex:([s rangeOfString:@"foobar"].location + [s rangeOfString:@"foobar"].length)];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;3/ &lt;i&gt;/tmp/msgsends&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;It's the prefix of files created by setting the variable &lt;i&gt;NSObjCMessageLoggingEnabled&lt;/i&gt; to &lt;i&gt;YES&lt;/i&gt; in the environment of a Cocoa application. The ObjC runtime will write an entry for each ObjC message received in the application.&lt;br /&gt;&lt;br /&gt;4/ &lt;i&gt;average life expectancy of macbook&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;I don't really know - we've had two in the office, one ran for about 18 months before dying (mine), the other is still running (after more then 2 years).&lt;br /&gt;&lt;br /&gt;5/ &lt;i&gt;core image histogram&lt;/i&gt;&lt;br /&gt;Look for &lt;i&gt;vImageHistogramCalculation_ARGB8888&lt;/i&gt;, part of &lt;i&gt;Accelarate.framework&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;6/ &lt;i&gt;raising x to power of y "objective c"&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;NSLog(@"2 to the power of 3: %f", pow(2.0, 3.0));&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-6464263953451203389?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/6464263953451203389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=6464263953451203389' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6464263953451203389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6464263953451203389'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/12/query-strings-received-from-google.html' title='Query strings received from Google'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5102217203312722551</id><published>2009-11-08T18:17:00.003+02:00</published><updated>2009-11-08T18:31:01.805+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='diacritics'/><category scheme='http://www.blogger.com/atom/ns#' term='sqlite'/><title type='text'>Diacritical folding in SQLite</title><content type='html'>Diacritical folding can be directly achieved in SQLite by implementing a custom function call. The following code demonstrates a possible implementation of such a function, taking in a string and returning a copy of the string with its diacritical marks folded.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;sqlite3.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;CoreFoundation/CoreFoundation.h&amp;gt;&lt;br /&gt;&lt;br /&gt;// this will be called by sqlite to dispose of the memory we malloced in diactrics_folding&lt;br /&gt;void destruct_result(void * ptr)&lt;br /&gt;{&lt;br /&gt;    free(ptr);&lt;br /&gt;}&lt;br /&gt;void diactrics_folding(sqlite3_context* ctx,int cnt,sqlite3_value** val)&lt;br /&gt;{&lt;br /&gt;    char * in = (char *)sqlite3_value_text(*val);&lt;br /&gt;    if(in == NULL)&lt;br /&gt;        return;&lt;br /&gt;&lt;br /&gt;    CFStringRef cstr = CFStringCreateWithCString(NULL, in, kCFStringEncodingUTF8);&lt;br /&gt;    CFMutableStringRef str = CFStringCreateMutableCopy(NULL, 0, cstr);&lt;br /&gt;    CFStringFold(str, kCFCompareDiacriticInsensitive, NULL);&lt;br /&gt;&lt;br /&gt;    char * resultAsCString = malloc(strlen(in));&lt;br /&gt;    if(!CFStringGetCString(str, resultAsCString, strlen(in), kCFStringEncodingUTF8))&lt;br /&gt;    {&lt;br /&gt;        free(resultAsCString);&lt;br /&gt;        sqlite3_result_text(ctx, in, strlen(in), NULL);&lt;br /&gt;        return;&lt;br /&gt;    }&lt;br /&gt;    sqlite3_result_text(ctx, resultAsCString, strlen(resultAsCString), &amp;destruct_result);&lt;br /&gt;&lt;br /&gt;    CFRelease(cstr);&lt;br /&gt;    CFRelease(str);&lt;br /&gt;}&lt;br /&gt;int cback (void* udata,int ncol,char** value,char** colname)&lt;br /&gt;{&lt;br /&gt;    int i=0;&lt;br /&gt;    for(;i&amp;lt;ncol;i++)&lt;br /&gt;        printf("Result column: %s value: %s   \n", colname[i], value[i]);&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    sqlite3 * handle;&lt;br /&gt;    int res = sqlite3_open("./test.sql", &amp;handle);&lt;br /&gt;&lt;br /&gt;    res = sqlite3_create_function(handle, "diactrics_folding", 1, SQLITE_UTF8, NULL, &amp;diactrics_folding, NULL, NULL);&lt;br /&gt; &lt;br /&gt;    char * errmsg = NULL;   &lt;br /&gt;    res = sqlite3_exec(handle, "select w, diactrics_folding(w) from t", &amp;cback, NULL, &amp;errmsg);&lt;br /&gt;    printf("sqlite3_exec result: %d %s\n", res, errmsg != NULL ? errmsg : "No error");&lt;br /&gt;&lt;br /&gt;    sqlite3_close(handle);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class='prettyprint'&gt;&lt;br /&gt;diciu$ gcc sqlite_diacritics.c -framework CoreFoundation -lsqlite3&lt;br /&gt;diciu$ ./a.out&lt;br /&gt;Result column: w value: &lt;i&gt;mămăliguță cu brânză și smântână   &lt;/i&gt;&lt;br /&gt;Result column: diactrics_folding(w) value: &lt;i&gt;mamaliguta cu branza si smantana   &lt;/i&gt;&lt;br /&gt;sqlite3_exec result: 0 No error&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/31740253-5102217203312722551?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5102217203312722551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5102217203312722551' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5102217203312722551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5102217203312722551'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/11/diacritical-folding-in-sqlite.html' title='Diacritical folding in SQLite'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-9209523208410656069</id><published>2009-10-29T12:57:00.005+02:00</published><updated>2009-10-29T14:05:37.553+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gsoap'/><category scheme='http://www.blogger.com/atom/ns#' term='web services'/><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>Web Services from Cocoa/Objective-C (Take 2)</title><content type='html'>One solution to the web services from Cocoa problem is using &lt;a href="http://www.cs.fsu.edu/~engelen/soap.html"&gt;gSoap&lt;/a&gt;. It's not 100% to my liking, in that solves web services by reducing them to SOAP and I find that mildly annoying - in my opinion web services tools should do their best to abstract away the transport.&lt;br /&gt;&lt;br /&gt;However, gSoap does a nice job of creating pure C code that can be used as a web services client so I'll ignore my reluctance to think of SOAP when talking about web services. I am using complete paths (&lt;i&gt;/Users/diciu/Downloads&lt;/i&gt;) because I've not installed gSoap - it makes compiling a bit more verbose but I hate writing in my /usr/ folder. YMMV.&lt;br /&gt;&lt;br /&gt;Here's how you build a C web services client to the EchoHeaders sample web service that's part of &lt;a href="http://ws.apache.org/axis/"&gt;Apache Axis&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Step 1. WSDL to SOAP&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;/Users/diciu/Downloads/gsoap-2.7/gsoap/wsdl/wsdl2h  -c -o test.h EchoHeaders.wsdl&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Step 2. SOAP stub and skeleton creation&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;/Users/diciu/Downloads/gsoap-2.7/gsoap/bin/macosx/soapcpp2 test.h&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This step will create a flurry of XML files and a namespace map file (&lt;i&gt;EchoHeadersSoapBinding.nsmap&lt;/i&gt;).&lt;br /&gt;&lt;br /&gt;Step 3. Creating a client (&lt;i&gt;test.c&lt;/i&gt;)&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include "soapH.h"&lt;br /&gt;#include "EchoHeadersSoapBinding.nsmap"&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    struct soap *soap = soap_new(); &lt;br /&gt;    char * t;&lt;br /&gt; &lt;br /&gt;    if(soap_call_ns2__echo(soap, NULL, NULL, "test echo", &amp;t) == SOAP_OK)&lt;br /&gt;    {&lt;br /&gt;        printf("echo result: &gt;%s&lt;\n", t);&lt;br /&gt;    }&lt;br /&gt;    else&lt;br /&gt;    {&lt;br /&gt;        soap_print_fault(soap, stderr); &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Step 4. Compiling the client&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;gcc test.c  soapC.c soapClient.c  -I/Users/diciu/Downloads/gsoap-2.7/gsoap/ /Users/diciu/Downloads/gsoap-2.7/gsoap/libgsoap.a&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Step 5. Running the client&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;cristi:webservices diciu$ ./a.out &lt;br /&gt;echo result: &amp;gt;test echo&amp;lt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Of course, this last step assumes that Apache Axis is running on localhost port 8080, otherwise you will get a SOAP fault:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;cristi:webservices diciu$ ./a.out &lt;br /&gt;SOAP 1.1 fault: SOAP-ENV:Client [no subcode]&lt;br /&gt;"Connection refused"&lt;br /&gt;Detail: connect failed in tcp_connect()&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/31740253-9209523208410656069?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/9209523208410656069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=9209523208410656069' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/9209523208410656069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/9209523208410656069'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/10/web-services-from-cocoaobjective-c-take.html' title='Web Services from Cocoa/Objective-C (Take 2)'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5983041223353389234</id><published>2009-10-19T08:50:00.008+03:00</published><updated>2009-10-21T09:24:51.982+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flex'/><category scheme='http://www.blogger.com/atom/ns#' term='infix'/><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='lex'/><category scheme='http://www.blogger.com/atom/ns#' term='rpn'/><category scheme='http://www.blogger.com/atom/ns#' term='eval'/><title type='text'>Evaluating arithmetic expressions</title><content type='html'>&lt;i&gt;Or computing the result of &lt;b&gt;1+2*3-(7*7*9)+1-(2*(2+5-1))&lt;/b&gt; to &lt;b&gt;-445&lt;/b&gt;, without using "eval".&lt;br /&gt;&lt;br /&gt;In languages missing evaluation capabilities, evaluating arbitrary expressions is not necessarily straight forward, because expressions written in infix form can't be intuitively parsed or evaluated. The quickest solution is probably embedding a scripting engine at runtime and using the scripting engine to evaluate the expression but this is not always feasible. &lt;br /&gt;&lt;br /&gt;This post describes an alternate solution, that is parsing the expression into Reverse Polish Notation and evaluating the RPN form, one operator at a time.&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Our infix expression parser requires three steps:&lt;br /&gt; - parsing the expression into tokens.&lt;br /&gt; - infix to RPN (reverse polish notation) (we'll do this using the &lt;a href="http://en.wikipedia.org/wiki/Shunting-yard%5Falgorithm"&gt;Shunting-yard algorithm&lt;/a&gt;).&lt;br /&gt; - evaluate the RPN expression.&lt;br /&gt;&lt;br /&gt;We first define the token types our expression will be parsed into.&lt;br /&gt;There's a limited set of operators used in our example: addition, subtraction, multiplication and division. We'll also support parenthesis for defining groups.&lt;br /&gt;&lt;br /&gt;&lt;pre class='prettyprint'&gt;&lt;br /&gt;------------------------- defs.h ------------------------&lt;br /&gt;typedef enum {&lt;br /&gt;    ENDFILE, ERROR,&lt;br /&gt;    LPAREN, RPAREN,&lt;br /&gt;    OPPLUS, OPMINUS,&lt;br /&gt;    OPMUL, OPDIV,&lt;br /&gt;    CONSTNUMBER} TokenType;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We'll parse the expression using (f)lex so we need to define our tokens for lex to parse:&lt;br /&gt;&lt;pre class='prettyprint'&gt;&lt;br /&gt;-------------------------- infix.lex ----------------------&lt;br /&gt;%{&lt;br /&gt;#import &amp;lt;Cocoa/Cocoa.h&amp;gt;&lt;br /&gt;#import "defs.h"&lt;br /&gt;#import "Token.h"&lt;br /&gt;&lt;br /&gt;%}&lt;br /&gt;&lt;br /&gt;digit [0-9]&lt;br /&gt;number {digit}+&lt;br /&gt;&lt;br /&gt;whitespace [ \t]+&lt;br /&gt;newline \n&lt;br /&gt;%%&lt;br /&gt;{number}        {return CONSTNUMBER;}&lt;br /&gt;"+"             {return OPPLUS;}&lt;br /&gt;"-"             {return OPMINUS;}&lt;br /&gt;"*"  {return OPMUL;}&lt;br /&gt;"/"  {return OPDIV;}&lt;br /&gt;"("             {return LPAREN;}&lt;br /&gt;")"             {return RPAREN;}&lt;br /&gt;{whitespace}    {/* skip whitespace */}&lt;br /&gt;{newline}       {return ENDFILE;}&lt;br /&gt;.               {return ERROR;}&lt;br /&gt;%%&lt;br /&gt;Token * getToken()&lt;br /&gt;{&lt;br /&gt;    Token * t = [[[Token alloc] init] autorelease];&lt;br /&gt;    [t setType:yylex()];&lt;br /&gt;    [t setValue:[NSString stringWithCString:yytext encoding:NSASCIIStringEncoding]];&lt;br /&gt;&lt;br /&gt;    return t;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the lex definition file, we define the token types based on the regular expressions they match. The &lt;i&gt;getToken&lt;/i&gt; function will be repeatedly called to create and consume tokens. The token itself has two attributes, the token type (as returned by &lt;i&gt;yylex()&lt;/i&gt;) and the corresponding token value (&lt;i&gt;yytext&lt;/i&gt;).&lt;br /&gt;&lt;br /&gt;We'll use a very simple ObjC class to store and manipulate our tokens.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class='prettyprint'&gt;&lt;br /&gt;------------------------- Token.h ------------------------&lt;br /&gt;#import &amp;lt;Cocoa/Cocoa.h&amp;gt;&lt;br /&gt;#import "defs.h"&lt;br /&gt;&lt;br /&gt;@interface Token: NSObject&lt;br /&gt;{&lt;br /&gt;    TokenType type;&lt;br /&gt;    NSString * value;&lt;br /&gt;}&lt;br /&gt;@property TokenType type;&lt;br /&gt;@property (retain) NSString * value;&lt;br /&gt;- (BOOL) isOperator;&lt;br /&gt;- (int) precendence;&lt;br /&gt;&lt;br /&gt;+ (Token *) eval:(Token *)larg :(Token *)op :(Token *)rarg;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class='prettyprint'&gt;&lt;br /&gt;------------------------- Token.m ------------------------&lt;br /&gt;#import "Token.h"&lt;br /&gt;&lt;br /&gt;@implementation Token&lt;br /&gt;&lt;br /&gt;@synthesize type;&lt;br /&gt;@synthesize value;&lt;br /&gt;&lt;br /&gt;- (BOOL) isOperator&lt;br /&gt;{&lt;br /&gt;    if(type == OPPLUS || type == OPMUL || type == OPDIV || type == OPMINUS)&lt;br /&gt;        return YES;&lt;br /&gt;    return NO;&lt;br /&gt;}&lt;br /&gt;- (int) precendence&lt;br /&gt;{&lt;br /&gt;    if(type == OPPLUS || type == OPMINUS)&lt;br /&gt;        return 10;&lt;br /&gt;    if(type == OPMUL || type == OPDIV)&lt;br /&gt;        return 100;&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (NSString *) description&lt;br /&gt;{&lt;br /&gt;    return value;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;+ (Token *) eval:(Token *)larg :(Token *)op :(Token *)rarg&lt;br /&gt;{&lt;br /&gt;        NSInteger lval = [[larg value] integerValue];&lt;br /&gt;        NSInteger rval = [[rarg value] integerValue];&lt;br /&gt;&lt;br /&gt;        Token * r = [[[Token alloc] init] autorelease];&lt;br /&gt;        [r setType:CONSTNUMBER];&lt;br /&gt;&lt;br /&gt;        int res;&lt;br /&gt;&lt;br /&gt;        if([op type] == OPMUL)&lt;br /&gt;                res = lval * rval;&lt;br /&gt;        else if([op type] == OPDIV)&lt;br /&gt;                res = lval / rval;&lt;br /&gt;        else if([op type] == OPPLUS)&lt;br /&gt;                res = lval + rval;&lt;br /&gt;        else if([op type] == OPMINUS)&lt;br /&gt;                res = lval - rval;&lt;br /&gt;&lt;br /&gt;    NSString * s = [NSString stringWithFormat:@"%d", res];&lt;br /&gt;    [r setValue:s];&lt;br /&gt;    return r;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The Evaluate class defines most of the logic. It consumes tokens following the Shunting-yard algorithm.&lt;br /&gt;&lt;br /&gt;&lt;pre class='prettyprint'&gt;&lt;br /&gt;------------------------- Evaluate.m ------------------------&lt;br /&gt;#import "Evaluate.h"&lt;br /&gt;#import "defs.h"&lt;br /&gt;#import "Token.h"&lt;br /&gt;@implementation Evaluate&lt;br /&gt;&lt;br /&gt;extern Token * getToken();&lt;br /&gt;&lt;br /&gt;-(void) run&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    NSMutableArray * outputQueue = [NSMutableArray arrayWithCapacity:10];&lt;br /&gt;    NSMutableArray * operatorStack = [NSMutableArray arrayWithCapacity:10];&lt;br /&gt; &lt;br /&gt;    Token * t = getToken();&lt;br /&gt;    while([t type] != ENDFILE)&lt;br /&gt;    {&lt;br /&gt;        if([t type] == ERROR)&lt;br /&gt;        {&lt;br /&gt;            NSLog(@"Error parsing token: %@, halting", [t value]);&lt;br /&gt;            break;&lt;br /&gt;        }&lt;br /&gt;        else if([t type] == CONSTNUMBER)&lt;br /&gt;        {&lt;br /&gt;            NSLog(@"Adding constant: %@", [t value]);&lt;br /&gt;            [outputQueue addObject:t];&lt;br /&gt;        }&lt;br /&gt;        else if([t isOperator])&lt;br /&gt;        {&lt;br /&gt;            NSLog(@"Adding operator: %@", [t value]);&lt;br /&gt;            while([operatorStack count]  &amp;&amp; [[operatorStack objectAtIndex:0] isOperator])&lt;br /&gt;            {&lt;br /&gt;                Token * topOfStack = [operatorStack objectAtIndex:0];&lt;br /&gt;                if([t precendence] &lt;= [topOfStack precendence])&lt;br /&gt;                {&lt;br /&gt;                    NSLog(@"Popping operator %@ off the stack", topOfStack);&lt;br /&gt;                    [outputQueue addObject:topOfStack];&lt;br /&gt;                    [operatorStack removeObjectAtIndex:0];&lt;br /&gt;                }&lt;br /&gt;                else&lt;br /&gt;                {&lt;br /&gt;                    NSLog(@"Not popping off the stack, top is %@, current op is %@", topOfStack, t);&lt;br /&gt;                    break;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            [operatorStack insertObject:t  atIndex:0];&lt;br /&gt;        }&lt;br /&gt;        else if([t type] == LPAREN)&lt;br /&gt;        {&lt;br /&gt;            NSLog(@"Adding operator: %@", t);&lt;br /&gt;            [operatorStack insertObject:t atIndex:0];&lt;br /&gt;        }&lt;br /&gt;        else if([t type] == RPAREN)&lt;br /&gt;        {&lt;br /&gt;            NSLog(@"Adding operator: %@", [t value]);&lt;br /&gt;            while([operatorStack count]  &amp;&amp; [(Token *)[operatorStack objectAtIndex:0] type] != LPAREN)&lt;br /&gt;            {&lt;br /&gt;                NSLog(@"Popping LPAREN off the stack");&lt;br /&gt;                Token * topOfStack = [operatorStack objectAtIndex:0];&lt;br /&gt;                [outputQueue addObject:topOfStack];&lt;br /&gt;                [operatorStack removeObjectAtIndex:0];&lt;br /&gt;            }&lt;br /&gt;            if([operatorStack count]  &amp;&amp; [(Token *)[operatorStack objectAtIndex:0] type] == LPAREN)&lt;br /&gt;                [operatorStack removeObjectAtIndex:0];&lt;br /&gt;            else&lt;br /&gt;                NSLog(@"Missing LPAREN");&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        t = getToken();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    if([operatorStack count]  &amp;&amp; ([(Token *)[operatorStack objectAtIndex:0] type] == LPAREN  || &lt;br /&gt;        [(Token *)[operatorStack objectAtIndex:0] type] == RPAREN))&lt;br /&gt;            NSLog(@"Mismatched paren");&lt;br /&gt;&lt;br /&gt;    int i=0;&lt;br /&gt;    for(i=0;i&lt;[operatorStack count];i++)&lt;br /&gt;    {&lt;br /&gt;        if([(Token *)[operatorStack objectAtIndex:i] type] == LPAREN || &lt;br /&gt;            [(Token *)[operatorStack objectAtIndex:i] type] == RPAREN)&lt;br /&gt;        {&lt;br /&gt;            NSLog(@"ERROR: Non operator on stack");&lt;br /&gt;            return;&lt;br /&gt;        }&lt;br /&gt;        [outputQueue addObject:[operatorStack objectAtIndex:i]];&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    NSLog(@"Output queue: %@", outputQueue);&lt;br /&gt;&lt;br /&gt;    NSLog(@"Trying to eval expression from queue");&lt;br /&gt;    NSMutableArray * rpStack = [NSMutableArray arrayWithCapacity:10];&lt;br /&gt;    for(i=0;i&lt;[outputQueue count];i++)&lt;br /&gt;    {&lt;br /&gt;        Token * ct = (Token *)[outputQueue objectAtIndex:i];&lt;br /&gt;        if([ct type] == CONSTNUMBER)&lt;br /&gt;        {&lt;br /&gt;            NSLog(@"Consuming numeric token: %@", ct);&lt;br /&gt;            [rpStack addObject:ct];&lt;br /&gt;        }&lt;br /&gt;        if([ct isOperator])&lt;br /&gt;        {&lt;br /&gt;                NSLog(@"Consuming operator token: %@", ct);&lt;br /&gt;                /* pop two args off of the stack*/&lt;br /&gt;                if([rpStack count] &lt; 2)&lt;br /&gt;                {&lt;br /&gt;                    NSLog(@"Error: Operator %@ is missing arguments", t);&lt;br /&gt;                    return;&lt;br /&gt;                }&lt;br /&gt;                Token * t1 = [rpStack objectAtIndex:[rpStack count]-1];&lt;br /&gt;                [rpStack removeLastObject];&lt;br /&gt;                Token * t2 = [rpStack objectAtIndex:[rpStack count]-1];&lt;br /&gt;                [rpStack removeLastObject];&lt;br /&gt;&lt;br /&gt;                Token * eval = [Token eval:t2 :ct :t1];&lt;br /&gt;                NSLog(@"Eval: %@ %@ %@ result: %@", t2, ct, t1, eval);&lt;br /&gt;                [rpStack addObject:eval];&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    if([rpStack count] != 1)&lt;br /&gt;    {&lt;br /&gt;        NSLog(@"ERROR: too many values");&lt;br /&gt;        return;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    NSLog(@"RP stack: %@", rpStack);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;@end&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/31740253-5983041223353389234?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5983041223353389234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5983041223353389234' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5983041223353389234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5983041223353389234'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/10/evaluating-arithmetic-expressions.html' title='Evaluating arithmetic expressions'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-205833600444888278</id><published>2009-10-16T15:18:00.007+03:00</published><updated>2009-10-20T09:36:53.602+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='c-client'/><title type='text'>Sending mail on Snow Leopard using the c-client API</title><content type='html'>c-client is an API that you can use to build email clients and servers.&lt;br /&gt;It's been around for more then 10 years and it implements virtually anything you would want to do with SMTP, IMAP or POP, albeit in ANSI C which makes things a bit more challenging, especially when you go through the sources and try to follow the pointer arithmetic being used. &lt;br /&gt;&lt;br /&gt;I haven't touched c-client since 2001 (that's 8 years ago) and I've run into a pleasant surprise finding c-client alive and well in 2009, and compiling "out of the box" on Snow Leopard on 64 bit. Many thanks, &lt;a href="http://panda.com/mrc/"&gt;Mark Crispin&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here's how you write a small application that acts as a SMTP client.&lt;br /&gt;&lt;br /&gt;1/ Download the distribution (ftp://ftp.cac.washington.edu/imap/imap.tar.Z)&lt;br /&gt;&lt;br /&gt;2/ Un-archive the distribution&lt;br /&gt;&lt;br /&gt;3/ Build the distribution&lt;br /&gt;&lt;pre class="prettyprint"&gt;cd imap-2007e/&lt;br /&gt;make osx&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;4/ Build a small application that sends an SMTP message&lt;br /&gt;&lt;br /&gt;c-client requires an application linking against it to implement a set of functions.&lt;br /&gt;These are grouped in our example under the file called c-client-interface.c:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// --------------------- c-client-interface.c --------------------------------&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;void mm_searched (MAILSTREAM *stream,unsigned long number) {}&lt;br /&gt;void mm_exists (MAILSTREAM *stream,unsigned long number) {}&lt;br /&gt;void mm_expunged (MAILSTREAM *stream,unsigned long number){}&lt;br /&gt;void mm_flags (MAILSTREAM *stream,unsigned long number) {}&lt;br /&gt;void mm_notify (MAILSTREAM *stream,char *string,long errflg) {}&lt;br /&gt;void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes) {}&lt;br /&gt;void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes) {}&lt;br /&gt;void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status) {}&lt;br /&gt;&lt;br /&gt;void mm_log (char *string,long errflg)&lt;br /&gt;{&lt;br /&gt;    fprintf(stdout, "mm_log: %s\n", string);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void mm_dlog (char *string)&lt;br /&gt;{&lt;br /&gt;    fprintf(stdout, "mm_dlog: %s\n", string);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void mm_login (NETMBX *mb,char *user,char *pwd,long trial)&lt;br /&gt;{&lt;br /&gt;    fprintf(stdout, "mm_login for mb-&gt;user: %s\n", mb-&gt;user);&lt;br /&gt;    strcpy(user, mb-&gt;user);&lt;br /&gt;    strcpy(pwd, "passwordGoesHere");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void mm_critical (MAILSTREAM *stream) {}&lt;br /&gt;void mm_nocritical (MAILSTREAM *stream) {}&lt;br /&gt;long mm_diskerror (MAILSTREAM *stream,long errcode,long serious) {}&lt;br /&gt;void mm_fatal (char *string) {}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We implement only three functions from the interface, namely &lt;i&gt;mm_log&lt;/i&gt; and &lt;i&gt;mm_dlog&lt;/i&gt; for logging purposes and &lt;i&gt;mm_login&lt;/i&gt;, required to provide the password for our SMTP authentication when the server requires it.&lt;br /&gt;&lt;br /&gt;The application itself is as basic as it gets. Note the host specification (it contains "novalidate-cert" because the certificate on our mail server is invalid).&lt;br /&gt;The host specification is used by the &lt;i&gt;smtp_open&lt;/i&gt; call that takes care of all the hard work that goes behind the scenes, that is the negotiation in between c-client and the SMTP server.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// --------------------- test.c ------------------------------------&lt;br /&gt;#include &amp;lt;c-client.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include "c-client-interface.c"&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    #include "linkage.c"&lt;br /&gt;&lt;br /&gt;    char * hostlist[] = { "mail.somedomain.com/ssl/novalidate-cert/user=senderUserName", NULL };&lt;br /&gt;&lt;br /&gt;    SENDSTREAM * sndstream = smtp_open(hostlist, 0);&lt;br /&gt;    if(sndstream == NULL)&lt;br /&gt;    {&lt;br /&gt;        fprintf(stderr, "Can't open SMTP connection\n");&lt;br /&gt;        return 1;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    BODY * body = mail_newbody();&lt;br /&gt;&lt;br /&gt;    ENVELOPE * env = mail_newenvelope();&lt;br /&gt;    ADDRESS * to = mail_newaddr();&lt;br /&gt;&lt;br /&gt;        // data about the sender&lt;br /&gt;    env-&gt;from = mail_newaddr();&lt;br /&gt;    env-&gt;from-&gt;personal = strdup("Sender Full Name");&lt;br /&gt;    env-&gt;from-&gt;mailbox = strdup("senderUserName");&lt;br /&gt;    env-&gt;from-&gt;host = strdup("somedomain.com");&lt;br /&gt;&lt;br /&gt;        // subject for our message&lt;br /&gt;    env-&gt;subject = strdup("subject");&lt;br /&gt;&lt;br /&gt;        // destination for our message (the recipient)&lt;br /&gt;    rfc822_parse_adrlist(&amp;env-&gt;to, strdup("recipientUserName"), strdup("destinationdomain.com"));&lt;br /&gt;&lt;br /&gt;        // the content of our message&lt;br /&gt;    body-&gt;type = TYPETEXT;&lt;br /&gt;    char *text = (char *) fs_get (8*MAILTMPLEN);&lt;br /&gt;    strcpy(text, "test message \015\012\0");&lt;br /&gt;    body-&gt;contents.text.data = text;&lt;br /&gt;    body-&gt;contents.text.size = strlen(text);&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;    long result = smtp_mail(sndstream, "MAIL", env, body);&lt;br /&gt;&lt;br /&gt;    if(sndstream)&lt;br /&gt;        smtp_close(sndstream);&lt;br /&gt;&lt;br /&gt;    mail_free_envelope(&amp;env);&lt;br /&gt;    mail_free_body(&amp;body);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To build the application, once you saved the c-client-interface.c and the test.c files, you need to run (assuming you've unarchived the imap archive on your Desktop):&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;gcc test.c -L ~/Desktop/imap-2007e/c-client/c-client.a -I ~/Desktop/imap-2007e/c-client -lcrypto -lssl -lkrb4&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Oh, and if you compile on Snow Leopard you will get a 64 bit application:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;cristi:c-client diciu$ file ./a.out &lt;br /&gt;./a.out: Mach-O 64-bit executable x86_64&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/31740253-205833600444888278?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/205833600444888278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=205833600444888278' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/205833600444888278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/205833600444888278'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/10/sending-mail-on-snow-leopard-using-c.html' title='Sending mail on Snow Leopard using the c-client API'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-4547029471961852676</id><published>2009-09-01T11:28:00.004+03:00</published><updated>2009-09-01T11:35:38.771+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='10.6'/><category scheme='http://www.blogger.com/atom/ns#' term='loudhush'/><title type='text'>About LoudHush 1.3.21</title><content type='html'>LoudHush 1.3.21 is out, the change log follows:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Fixed a couple of leaks in AccountController/Management&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Fixed bug that caused LoudHush to hang in Snow Leopard (due to updating UI from two different threads)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Address book browser ordering&lt;/li&gt;&lt;br /&gt;&lt;li&gt;When hovering over missed calls, click opens the call history window&lt;/li&gt;&lt;br /&gt;&lt;li&gt;When call history is brought up, reset missed calls counter&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Please note 1.3.21 has received limited testing; it is being released early because 1.3.20 is hanging on Snow Leopard/10.6.&lt;br /&gt;If you encounter problems using 1.3.21, write us (email address available over at loudhush.ro site) and we'll try to help.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-4547029471961852676?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/4547029471961852676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=4547029471961852676' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4547029471961852676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/4547029471961852676'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/09/about-loudhush-1321.html' title='About LoudHush 1.3.21'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5423197371912907580</id><published>2009-07-10T09:02:00.012+03:00</published><updated>2009-07-10T13:18:20.616+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gis'/><category scheme='http://www.blogger.com/atom/ns#' term='romanian'/><category scheme='http://www.blogger.com/atom/ns#' term='openstretmap'/><title type='text'>On Romanian GIS data, Stereo 1970 and WGS84</title><content type='html'>GIS data for Romania is sparse. The government have it, but they are slow to share it and even when they do, they fail to release under clear licensing terms.&lt;br /&gt;&lt;br /&gt;Once GIS data is obtained, another problem arises - the data is most likely in the Stereo 1970 projection (&lt;a href="http://spatialreference.org/ref/epsg/31700/"&gt;EPSG 31700&lt;/a&gt;). Modern GIS systems, including openstreetmap, have no capability of interpreting data in anything other then WGS 84 (&lt;a href="http://spatialreference.org/ref/epsg/4326/"&gt;EPSG 4326&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;A translation is needed from Stereo 1970 to WGS84.&lt;br /&gt;&lt;br /&gt;One can attempt to translate coordinates using the excellent &lt;a href="http://trac.osgeo.org/proj/"&gt;libproj&lt;/a&gt;.&lt;br /&gt;Given the coordinates for &lt;i&gt;Cabana Fantanele&lt;/i&gt;, a hut in the Ceahlau mountains, in Stereo 1970, we can use the tools provided by libproj to translate to WGS84:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cristi:proj diciu$ ./src/cs2cs  +proj=stere +lat_0=46 +lon_0=25 +k=0.999750 \&lt;br /&gt;&gt; +x_0=500000 +y_0=500000 +ellps=krass +units=m +no_defs  +to  \&lt;br /&gt;&gt;+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs -f "%.6f"&lt;br /&gt;572176.849  611484.777&lt;br /&gt;25.949088 46.999202 0.000000&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;However, if you plot this WGS84 coordinate set on Google Earth (pin name is "Fantanele proj"), you will see the coordinates are approximately 100 meters away from the hut.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/SlbgJ6eSPHI/AAAAAAAACjY/dM5m-oA2d-w/s1600-h/FantaneleGE.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 197px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/SlbgJ6eSPHI/AAAAAAAACjY/dM5m-oA2d-w/s320/FantaneleGE.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5356715267723508850" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rXrjDFwt37w/SlbhpgvcDqI/AAAAAAAACjo/WiQeB028L4k/s1600-h/FantaneleGE_ruler.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 167px;" src="http://3.bp.blogspot.com/_rXrjDFwt37w/SlbhpgvcDqI/AAAAAAAACjo/WiQeB028L4k/s320/FantaneleGE_ruler.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5356716910083575458" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thanks to the work of a government agency called ANCPI (&lt;a href="http://ancpi.ro/"&gt;Agentia Nationala de Cadastru si Publicitate Imobiliara&lt;/a&gt;) we have a tool that allows accurate translations between Stereo 1970 and WGS84: &lt;a href="http://ancpi.ro/pages/download.php?lang=ro"&gt;TransDatRO&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Unfortunately accurate translation between Stereo 1970 and ETRS89 requires a set of common points and the tool only includes enough points for the following counties: Caras Severin, Gorj, Valcea, Dambovita, Teleorman, Braila, Botosani, Suceava.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rXrjDFwt37w/SlbqNMo6lkI/AAAAAAAACjw/XgbgLmoVfac/s1600-h/TransDatRO.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 188px;" src="http://3.bp.blogspot.com/_rXrjDFwt37w/SlbqNMo6lkI/AAAAAAAACjw/XgbgLmoVfac/s320/TransDatRO.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5356726319255819842" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Degrees, minutes, seconds can be converted to decimal degrees (as required by openstreetmap) using libproj's cs2cs:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cristi:proj diciu$ ./src/cs2cs -f “%.6f” +proj=latlong +datum=WGS84 +to +proj=latlong +datum=WGS84&lt;br /&gt;46d59'56.28495N 25d56'51.25243E&lt;br /&gt;“46.998968” “25.947570” “0.000000”&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;When we plot the coordinates as returned by TransDat, even though Neamt county is not part of the accurate county list, we observe that coordinates returned by TransDat are much closer to what's revealed by the satellite imagery (see how "Fantanele Topo" is in close proximity to the hut's roof):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rXrjDFwt37w/SlbrCeEDv7I/AAAAAAAACj4/TfUkUe34Jbc/s1600-h/FantaneleGE_Transdat.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 176px;" src="http://1.bp.blogspot.com/_rXrjDFwt37w/SlbrCeEDv7I/AAAAAAAACj4/TfUkUe34Jbc/s320/FantaneleGE_Transdat.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5356727234466135986" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;Note: I am not a geographer. All of this explained above is derived from personal, rather empiric research.&lt;br /&gt;I have lots of questions that I couldn't find an answer to such as why there is no apparent difference when converting from &lt;a href="http://spatialreference.org/ref/epsg/4258/"&gt;ETRS89&lt;/a&gt; to WGS84 - you might notice that I use ETRS89 and WGS84 interchangeably.&lt;/b&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-5423197371912907580?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5423197371912907580/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5423197371912907580' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5423197371912907580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5423197371912907580'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/07/on-romanian-gis-data-stereo-1970-and.html' title='On Romanian GIS data, Stereo 1970 and WGS84'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rXrjDFwt37w/SlbgJ6eSPHI/AAAAAAAACjY/dM5m-oA2d-w/s72-c/FantaneleGE.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-3955116000108632904</id><published>2009-06-18T16:36:00.001+03:00</published><updated>2009-06-18T16:38:55.330+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='diacritics'/><category scheme='http://www.blogger.com/atom/ns#' term='romanian'/><title type='text'>postgresql drop Romanian diacritics</title><content type='html'>&lt;pre&gt;&lt;br /&gt;create or replace function strip_diacritics(varchar) returns varchar as $$&lt;br /&gt;DECLARE &lt;br /&gt;  src ALIAS FOR $1;  &lt;br /&gt;  result VARCHAR;&lt;br /&gt;&lt;br /&gt;BEGIN  result := TRANSLATE(src, E'\xc3\x82\xc3\x83\xc3\xa2\xc3\xa3\xc4\x82\xc3\x8e\xc3\xae\xc5\x9e\xc5\x9f\xc5\xa2\xc3\xa3\xc7\x8d\xc7\x8e\xc8\x98\xc8\x99\xc8\x9a\xc8\x9B\xc3\x83', 'AaaaAIiSsTtAaSsTtA');&lt;br /&gt;return result;&lt;br /&gt;END;&lt;br /&gt;$$ LANGUAGE 'plpgsql' IMMUTABLE;&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/31740253-3955116000108632904?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/3955116000108632904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=3955116000108632904' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3955116000108632904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3955116000108632904'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/06/postgresql-drop-romanian-diacritics.html' title='postgresql drop Romanian diacritics'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-6140017951948293673</id><published>2009-06-10T16:27:00.005+03:00</published><updated>2009-06-10T16:59:02.313+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bucharestapp'/><title type='text'>Note to self</title><content type='html'>OpenStreetMap places less then 2000 meters apart with names of the same length:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;select p1.name, p2.name, p1.osm_id, p2.osm_id, p1.place, p2.place, distance(p1.way, p2.way) from planet_osm_point p1, planet_osm_point p2  where p1.place !='' and p2.place!='' and p1.osm_id != p2.osm_id and distance(p1.way, p2.way) &lt; 2000 and octet_length(p1.name) = octet_length(p2.name) order by p1.name;&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/31740253-6140017951948293673?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/6140017951948293673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=6140017951948293673' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6140017951948293673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6140017951948293673'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/06/note-to-self.html' title='Note to self'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-3139637126653188605</id><published>2009-04-28T15:58:00.007+03:00</published><updated>2009-10-16T11:10:54.080+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='spell checker'/><category scheme='http://www.blogger.com/atom/ns#' term='objective-c'/><title type='text'>Spell checking in Objective-C</title><content type='html'>&lt;script language="javascript"&gt;prettyPrint();&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;I've finally beat python at running the very simple spell checker described &lt;a href="http://blog.dv8.ro/2009/04/on-my-objective-c-code-thats-slower.html "&gt;in an earlier post&lt;/a&gt;. The code is not "pure" Objective-C, some parts are just too slow so I've had to mix in some C.&lt;br /&gt;&lt;br /&gt;The major difference compared to the versions described in the earlier post is this addition in the loop of &lt;i&gt; - (NSSet *) knownEdits2:(NSString *) word&lt;/i&gt; of an additional condition:&lt;br /&gt;&lt;pre class="prettyprint"&gt;if([ts intersectsSet:knownWords])&lt;br /&gt;   [edits2 unionSet:[self edits1:w]];&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;i&gt;intersectsSet&lt;/i&gt; condition avoids growing the set of edit distance 2 very effectively - in fact I suspect the python reference code does exactly that - I'm not sure how to read the python construct into distinct loops: &lt;i&gt;return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)&lt;/i&gt; so I can't tell for sure.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;CSSpell .h&lt;/i&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;#import &amp;lt;Cocoa/Cocoa.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@interface CSSpell : NSObject &lt;br /&gt;{&lt;br /&gt;    NSMutableDictionary * model;&lt;br /&gt;    NSDictionary * NWORDS;&lt;br /&gt;    NSMutableSet * knownWords; &lt;br /&gt;}&lt;br /&gt;@end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;CSSpell.m&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;#import "CSSpell.h"&lt;br /&gt;&lt;br /&gt;@interface CSMutableNumber:NSObject&lt;br /&gt;{&lt;br /&gt;    NSUInteger mNumber;&lt;br /&gt;}&lt;br /&gt;@end&lt;br /&gt;&lt;br /&gt;@implementation CSMutableNumber&lt;br /&gt;- (id)initWithInt:(int)value &lt;br /&gt;{&lt;br /&gt;    self = [super init];&lt;br /&gt;    if(!self) return nil;&lt;br /&gt;    mNumber = value;&lt;br /&gt;         return self;&lt;br /&gt;}&lt;br /&gt;+ (CSMutableNumber *)numberWithInt:(int)value &lt;br /&gt;{&lt;br /&gt;     return [[[CSMutableNumber alloc] initWithInt:value] autorelease];&lt;br /&gt;}&lt;br /&gt;- (void)setIntValue:(int)value &lt;br /&gt;{&lt;br /&gt;     mNumber = value;&lt;br /&gt;}&lt;br /&gt;- (void) increment&lt;br /&gt;{&lt;br /&gt;     if(mNumber &lt; NSUIntegerMax) mNumber++;&lt;br /&gt;}&lt;br /&gt;- (int) intValue&lt;br /&gt;{&lt;br /&gt;     return mNumber;&lt;br /&gt;}&lt;br /&gt;@end&lt;br /&gt;&lt;br /&gt;@implementation CSSpell&lt;br /&gt;&lt;br /&gt;- (NSDictionary *) trainv2:(NSString *)text&lt;br /&gt;{&lt;br /&gt;     if(model == nil)&lt;br /&gt;     {&lt;br /&gt;          model = [NSMutableDictionary dictionaryWithCapacity:40000];&lt;br /&gt;          [model retain];&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     NSString * t = [text lowercaseString];&lt;br /&gt;     char * buf = (char *)[t cStringUsingEncoding:NSASCIIStringEncoding];&lt;br /&gt; &lt;br /&gt;     char **bp = &amp;buf;&lt;br /&gt;     char *tok;&lt;br /&gt;     while (tok = strsep(bp, " \r\t,.*()[]#\n\"-!?&amp;/'~;:"))&lt;br /&gt;     if(strlen(tok)&gt;2)&lt;br /&gt;     {&lt;br /&gt;           NSString * w = [NSString stringWithCString:tok];&lt;br /&gt;   &lt;br /&gt;           CSMutableNumber * wordVal = [model objectForKey:w];&lt;br /&gt;           if(wordVal)&lt;br /&gt;                [wordVal increment];&lt;br /&gt;           else&lt;br /&gt;                 [model setObject:[CSMutableNumber numberWithInt:1] forKey:w];&lt;br /&gt;   &lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;     NSLog(@"Caching set of known words");&lt;br /&gt; &lt;br /&gt;     knownWords = [NSSet setWithArray:[model allKeys]];&lt;br /&gt;     return model;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/* returns a set of words at edit distance 1 away */&lt;br /&gt;- (NSSet *) edits1:(NSString *) word&lt;br /&gt;{&lt;br /&gt;     NSMutableSet * s = [NSMutableSet setWithCapacity:2000];&lt;br /&gt; &lt;br /&gt;     int i=0, len;&lt;br /&gt;     char c;&lt;br /&gt;     #define MAX_LEN_C 500&lt;br /&gt;     char str[MAX_LEN_C];&lt;br /&gt;     char temp[MAX_LEN_C];&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;     strcpy(str, [word cStringUsingEncoding:NSASCIIStringEncoding]);&lt;br /&gt;     for(i=0;i&lt;[word length];i++)&lt;br /&gt;     {&lt;br /&gt;          strcpy(temp, str); temp[i] = str[i+1]; temp[i+1] = str[i];&lt;br /&gt;          len = strlen(temp);&lt;br /&gt;  &lt;br /&gt;          if(i&lt;[word length]-1)&lt;br /&gt;          {&lt;br /&gt;               NSString * transposed = [NSString stringWithCString:temp length:len];&lt;br /&gt;               [s addObject:transposed];&lt;br /&gt;          }&lt;br /&gt;  &lt;br /&gt;          strcpy(temp + i, str+i+1);&lt;br /&gt;          NSString * deletion = [NSString stringWithCString:temp length:strlen(temp)];&lt;br /&gt;          [s addObject:deletion];&lt;br /&gt;  &lt;br /&gt;          for(c='a';c&lt;='z';c++)&lt;br /&gt;          {&lt;br /&gt;               temp[i] = c; strcpy(temp + i + 1, str+i+1);&lt;br /&gt;               NSString * replaced = [NSString stringWithCString:temp length:len];&lt;br /&gt;               [s addObject:replaced];&lt;br /&gt;   &lt;br /&gt;               strcpy(temp + i + 1, str+i);&lt;br /&gt;               NSString * inserted = [NSString stringWithCString:temp length:len+1];&lt;br /&gt;               [s addObject:inserted];&lt;br /&gt;          }&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     return s;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/* returns a set of known words based at edit distance 2 away */&lt;br /&gt;- (NSSet *) knownEdits2:(NSString *) word&lt;br /&gt;{&lt;br /&gt;     NSMutableSet * edits2 = [NSMutableSet setWithCapacity:5000];&lt;br /&gt;     NSSet * edits1 = [self edits1:word];&lt;br /&gt; &lt;br /&gt;     NSEnumerator * en1 = [edits1 objectEnumerator];&lt;br /&gt;     NSString * w;&lt;br /&gt;     while(w=[en1 nextObject])&lt;br /&gt;     {&lt;br /&gt;          NSSet * ts = [self edits1:w];&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;          if([ts intersectsSet:knownWords])&lt;br /&gt;          [edits2 unionSet:[self edits1:w]];&lt;br /&gt;      }&lt;br /&gt; &lt;br /&gt;      //NSLog(@"Edits2 has %d", [edits2 count]);&lt;br /&gt; &lt;br /&gt;     [edits2 intersectSet:knownWords];&lt;br /&gt;     NSLog(@"KW for %@: %@", word, edits2);&lt;br /&gt; &lt;br /&gt;     return edits2;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/* returns a set of known words from a given set of words */&lt;br /&gt;- (NSSet *) known:(NSSet *) words&lt;br /&gt;{&lt;br /&gt;     NSMutableSet * s = [NSMutableSet setWithCapacity:100];&lt;br /&gt;     [s unionSet:words];&lt;br /&gt;     [s intersectSet:knownWords]; &lt;br /&gt;     return s;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (NSString *) correct:(NSString *) word&lt;br /&gt;{&lt;br /&gt;     if([word length] &gt; 300)&lt;br /&gt;          return nil;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;     NSMutableSet * candidates = [NSMutableSet setWithCapacity:10];&lt;br /&gt;  &lt;br /&gt;     if([candidates count] &lt; 1)&lt;br /&gt;     {&lt;br /&gt;          [candidates unionSet:[self known:[NSSet setWithObject:word]]];&lt;br /&gt;          //NSLog(@"Adding known words set: %@", candidates);&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     if([candidates count] &lt; 1)&lt;br /&gt;     {&lt;br /&gt;          [candidates unionSet:[self known:[self edits1:word]]];&lt;br /&gt;          //NSLog(@"Adding edit distance 1 set: %@", candidates);&lt;br /&gt;      }&lt;br /&gt; &lt;br /&gt;     if([candidates count] &lt; 1)&lt;br /&gt;     {&lt;br /&gt;           [candidates unionSet:[self knownEdits2:word]];&lt;br /&gt;     }&lt;br /&gt;     if([candidates count] &lt; 1)&lt;br /&gt;     {&lt;br /&gt;          //NSLog(@"Adding the word itself");&lt;br /&gt;          [candidates addObject:word]; &lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     int max=0;&lt;br /&gt;     NSString * chosen = @"Unknown#";&lt;br /&gt;     NSEnumerator * e = [candidates objectEnumerator];&lt;br /&gt;     NSString * w;&lt;br /&gt;     while(w=[e nextObject])&lt;br /&gt;     {&lt;br /&gt;          CSMutableNumber * wordVal = [NWORDS objectForKey:w];&lt;br /&gt;          if(wordVal)&lt;br /&gt;          {&lt;br /&gt;               if([wordVal intValue] &gt; max)&lt;br /&gt;               {&lt;br /&gt;                    chosen = w;&lt;br /&gt;                    max = [wordVal intValue];&lt;br /&gt;               }&lt;br /&gt;          }&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;     return chosen;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (void) awakeFromNib&lt;br /&gt;{&lt;br /&gt; &lt;br /&gt;     NSString * cnt = [NSString stringWithContentsOfFile:@"/Users/diciu/Desktop/big.txt" encoding:NSASCIIStringEncoding error:nil];&lt;br /&gt;     NSLog(@"Dictionary has been loaded");&lt;br /&gt; &lt;br /&gt;     NWORDS = [self trainv2:cnt];&lt;br /&gt;     NSLog(@"Training done, %d words", [NWORDS count]);&lt;br /&gt; &lt;br /&gt;     NSDate * startDate = [NSDate date];&lt;br /&gt; &lt;br /&gt;     NSArray * tests = [NSArray arrayWithObjects:@"generataed", @"acount", @"guidlines", &lt;br /&gt;        @"wheere", @"myne", @"graet", @"silenc", @"aggresive", &lt;br /&gt;                                           @"appreceiated", @"aquantance", @"beggining",  nil];&lt;br /&gt;     NSEnumerator * en = [tests objectEnumerator];&lt;br /&gt;     NSString * c;&lt;br /&gt;     while(c=[en nextObject])&lt;br /&gt;     {&lt;br /&gt;          NSDate * sd = [NSDate date];&lt;br /&gt;          NSString * correct = [self correct:c];&lt;br /&gt;          NSLog(@"%@ / %@ \t\t\t in %f seconds", c, correct, [sd timeIntervalSinceNow]);&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;     NSLog(@"Total runtime: %f", [startDate timeIntervalSinceNow]);&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;@end&lt;br /&gt;&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/31740253-3139637126653188605?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/3139637126653188605/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=3139637126653188605' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3139637126653188605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3139637126653188605'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/04/spell-checking-in-objective-c.html' title='Spell checking in Objective-C'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-477651295749702474</id><published>2009-04-19T21:28:00.014+03:00</published><updated>2009-10-26T08:22:21.041+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='spell checker'/><category scheme='http://www.blogger.com/atom/ns#' term='objective-c'/><title type='text'>On (my) Objective-C code that's slower then expected</title><content type='html'>I was looking into building a spell checker for the geographical names in &lt;a href="dv8.ro/Bucharest/"&gt;BucharestApp&lt;/a&gt; based on a &lt;a href="http://norvig.com/spell-correct.html"&gt;Peter Norvig's article on building a spell checker&lt;/a&gt; so I've started writing a translation of Peter's python script in Objective-C.&lt;br /&gt;&lt;br /&gt;The unpleasant surprise came when I timed my Objective-C code against the python script.&lt;br /&gt;Running the spell checker on one of my word lists in python took 1.11 seconds; the Objective-C code was 4.69 times slower.&lt;br /&gt;&lt;br /&gt;After factoring out training time because this can be very easily optimized by something as simple as serializing the training dictionary instead of computing it at runtime, I watched how my Objective-C code takes a whopping 5.3 seconds for spellchecking 11 words.&lt;br /&gt;&lt;br /&gt;&lt;table style="font-size: smaller; text-align: right"&gt;&lt;tr&gt;&lt;td&gt;generataed      &lt;/td&gt;&lt;td&gt; generate               &lt;/td&gt;&lt;td style="background-color:#444"&gt;-1.459070 s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;acount          &lt;/td&gt;&lt;td&gt; count                          &lt;/td&gt;&lt;td&gt;-0.003310 s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;guidlines               &lt;/td&gt;&lt;td&gt; guideline              &lt;/td&gt;&lt;td style="background-color:#444"&gt;-1.173020 s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;wheere          &lt;/td&gt;&lt;td&gt; where                          &lt;/td&gt;&lt;td&gt;-0.002277 s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;myne                    &lt;/td&gt;&lt;td&gt; mine                   &lt;/td&gt;&lt;td&gt;-0.001197 s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;graet                   &lt;/td&gt;&lt;td&gt; great                          &lt;/td&gt;&lt;td&gt;-0.002184 s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;silenc                  &lt;/td&gt;&lt;td&gt; silent                         &lt;/td&gt;&lt;td&gt;-0.001916 s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;aggresive               &lt;/td&gt;&lt;td&gt; aggressive             &lt;/td&gt;&lt;td&gt;-0.003051 s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;appreceiated  &lt;/td&gt;&lt;td&gt; appreciated      &lt;/td&gt;&lt;td&gt;-0.004764 s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;aquantance      &lt;/td&gt;&lt;td&gt; acquaintance   &lt;/td&gt;&lt;td style="background-color:#444"&gt;-1.483899 s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;beggining               &lt;/td&gt;&lt;td&gt; beginning              &lt;/td&gt;&lt;td style="background-color:#444"&gt;-1.185744 s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=2&gt;&lt;b&gt;Total runtime&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt; -5.329394&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The data set shows a cluster of words performing at .003 seconds and another cluster performing at 1.4 seconds.&lt;br /&gt;What the miss-spellings "generataed", "guidlines", "aquantance", "beggining" have in common is edit distance. Unlike the other miss-spellings that are all at edit distance 1, they are all at edit distance 2. The problem with edit distance 2 is that it produces many variations of the miss-spelled word (around 200000) - Peter explains all this in his article.&lt;br /&gt;&lt;br /&gt;My first instinct was to blame NSSet operations. After all, I was intersecting a 200000 set (the words at edit distance 2) with a 40000 set (the dictionary). &lt;br /&gt;This must be slow, right? Wrong. After messing with the initial capacity of my NSSets and poking around Google for some explanation of what I was seeing, I started looking at the data Shark shows.&lt;br /&gt;&lt;br /&gt;As expected, Shark shows the bottleneck in knownEdits2, the method which computes variations at edit distance 2.&lt;br /&gt;But it's not NSSet operations that take the most CPU, but rather unexpectedly it's [NSString stringWithFormat].&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rXrjDFwt37w/SetxLoxozFI/AAAAAAAACco/LlCq2yGNaOk/s1600-h/CocoaSpellUnoptimized.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 242px;" src="http://4.bp.blogspot.com/_rXrjDFwt37w/SetxLoxozFI/AAAAAAAACco/LlCq2yGNaOk/s320/CocoaSpellUnoptimized.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5326475429033856082" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;-[CSSpell knownEdits2]&lt;/i&gt; does most of its work in &lt;i&gt;-[CSSpell edits1StringsInObjCUnoptimized]&lt;/i&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;- (NSSet *) edits1StringsInObjCUnoptimized:(NSString *) word&lt;br /&gt;{&lt;br /&gt; NSMutableSet * s = [NSMutableSet setWithCapacity:2000];&lt;br /&gt; &lt;br /&gt; int i=0;&lt;br /&gt; char c;&lt;br /&gt; //deletions&lt;br /&gt; for(i=0;i&lt;[word length];i++)&lt;br /&gt;  [s addObject:[NSString stringWithFormat:@"%@%@",&lt;br /&gt;       [word substringToIndex:i],&lt;br /&gt;       [word substringFromIndex:i+1]]];&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;  //replaces&lt;br /&gt;  for(i=0;i&lt;[word length];i++)&lt;br /&gt;   for(c='a';c&lt;='z';c++)&lt;br /&gt;    [s addObject:[NSString stringWithFormat:@"%@%c%@",&lt;br /&gt;         [word substringToIndex:i],&lt;br /&gt;         c,&lt;br /&gt;         [word substringFromIndex:i+1]]];&lt;br /&gt;  &lt;br /&gt;  // inserts&lt;br /&gt;  for(i=0;i&lt;[word length];i++)&lt;br /&gt;   for(c='a';c&lt;='z';c++)&lt;br /&gt;    [s addObject:[NSString stringWithFormat:@"%@%c%@", &lt;br /&gt;         [word substringToIndex:i],&lt;br /&gt;         c,&lt;br /&gt;         [word substringFromIndex:i]]];&lt;br /&gt;  &lt;br /&gt;  //transposes&lt;br /&gt;  for(i=0;i&lt;[word length]-1;i++)&lt;br /&gt;   [s addObject:[NSString stringWithFormat:@"%@%@%@%@",&lt;br /&gt;        [word substringToIndex:i],&lt;br /&gt;        [word substringWithRange:NSMakeRange(i+1, 1)],&lt;br /&gt;        [word substringWithRange:NSMakeRange(i, 1)],&lt;br /&gt;        [word substringFromIndex:i+2]]];&lt;br /&gt; &lt;br /&gt; return s;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;-[CSSpell edits1StringsInObjCUnoptimized]&lt;/i&gt; is shown by Shark to call &lt;i&gt;-[NSString stringWithFormat]&lt;/i&gt; lots of times.&lt;br /&gt;Which makes sense, since edits are formed using loops. But when I looked at how &lt;a href="http://otx.osxninja.com/"&gt;otx&lt;/a&gt; shows the assembler code generated from this method, I had another surprise (many parts cut for brevity):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-(id)[CSSpell edits1StringsInObjCUnoptimized:]&lt;br /&gt;[..]&lt;br /&gt;   +36 0000281b  e8ef270000     calll  0x0000500f   +[NSMutableSet setWithCapacity:]&lt;br /&gt;[..]&lt;br /&gt;  +101 0000285c  e8ae270000     calll   0x0000500f  -[(%esp,1) substringToIndex:] ///--&lt;br /&gt;[..]&lt;br /&gt;  +134 0000287d  e88d270000     calll   0x0000500f  +[NSString stringWithFormat:]&lt;br /&gt;[..]&lt;br /&gt;  +158 00002895  e875270000     calll   0x0000500f  -[(%esp,1) addObject:]&lt;br /&gt;[..]&lt;br /&gt;  +268 00002903  e807270000     calll   0x0000500f  -[(%esp,1) substringToIndex:] ///--&lt;br /&gt;[..]&lt;br /&gt;  +306 00002929  e8e1260000     calll 0x0000500f    +[NSString stringWithFormat:]&lt;br /&gt;[..]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The surprise is that substringToIndex is called twice.&lt;br /&gt;Since it's called on an immutable string and thus it yields the same result within the method's scope, I would have expected GCC to optimize the call.&lt;br /&gt;&lt;br /&gt;So I rewrote the method, optimizing calls to substring methods:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;- (NSSet *) edits1StringsInObjC:(NSString *) word&lt;br /&gt;{&lt;br /&gt; NSMutableSet * s = [NSMutableSet setWithCapacity:2000];&lt;br /&gt;&lt;br /&gt; int i=0;&lt;br /&gt; char c;&lt;br /&gt; &lt;br /&gt; for(i=0;i&lt;[word length];i++)&lt;br /&gt; {&lt;br /&gt;  NSString * toIndex = [word substringToIndex:i];&lt;br /&gt;  NSString * fromIndex = [word substringFromIndex:i+1];&lt;br /&gt;  NSString * fromIndex2 = [word substringFromIndex:i];&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;  if(i&lt;[word length]-1)&lt;br /&gt;   [s addObject:[NSString stringWithFormat:@"%@%c%c%@",&lt;br /&gt;        toIndex,&lt;br /&gt;        [word characterAtIndex:i+1],&lt;br /&gt;        [word characterAtIndex:i],&lt;br /&gt;        [word substringFromIndex:i+2]]]; // transposes&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;  [s addObject:[NSString stringWithFormat:@"%@%@", toIndex, fromIndex]]; //deletion&lt;br /&gt;  &lt;br /&gt;  for(c='a';c&lt;='z';c++)&lt;br /&gt;  {&lt;br /&gt;   [s addObject:[NSString stringWithFormat:@"%@%c%@",&lt;br /&gt;        toIndex,&lt;br /&gt;        c,&lt;br /&gt;        fromIndex]]; //replace&lt;br /&gt;   [s addObject:[NSString stringWithFormat:@"%@%c%@", &lt;br /&gt;        toIndex,&lt;br /&gt;        c,&lt;br /&gt;        fromIndex2]]; //insert   &lt;br /&gt;  }  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; return s;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Timing the code after the optimization shows:&lt;br /&gt;&lt;br /&gt;&lt;table style="font-size: smaller; text-align: right"&gt;&lt;tr&gt;&lt;td&gt;generataed              &lt;/td&gt;&lt;td&gt; generate                      &lt;/td&gt;&lt;td&gt;-1.142463 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;acount                  &lt;/td&gt;&lt;td&gt; count                                 &lt;/td&gt;&lt;td&gt;-0.001646 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;guidlines               &lt;/td&gt;&lt;td&gt; guideline                     &lt;/td&gt;&lt;td&gt;-0.931142 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;wheere          &lt;/td&gt;&lt;td&gt; where                                 &lt;/td&gt;&lt;td&gt;-0.002310 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;myne                    &lt;/td&gt;&lt;td&gt; mine                          &lt;/td&gt;&lt;td&gt;-0.001241 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;graet                   &lt;/td&gt;&lt;td&gt; great                                 &lt;/td&gt;&lt;td&gt;-0.001417 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;silenc                  &lt;/td&gt;&lt;td&gt; silent                                &lt;/td&gt;&lt;td&gt;-0.001597 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;aggresive               &lt;/td&gt;&lt;td&gt; aggressive                    &lt;/td&gt;&lt;td&gt;-0.002322 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;appreceiated    &lt;/td&gt;&lt;td&gt; appreciated                   &lt;/td&gt;&lt;td&gt;-0.003206 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;aquantance              &lt;/td&gt;&lt;td&gt; acquaintance          &lt;/td&gt;&lt;td&gt;-1.157321 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;beggining               &lt;/td&gt;&lt;td&gt; beginning                     &lt;/td&gt;&lt;td&gt;-0.938545 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=2&gt;&lt;b&gt;Total runtime&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt; -4.192067&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This optimization has shaved off ~0.35 seconds when checking miss-spells at edit distance 2.&lt;br /&gt;In the total runtime, we've decreased to 78% out of the initial runtime.&lt;br /&gt;&lt;br /&gt;If we check this new version using Shark, the bottleneck is still shown in &lt;i&gt;-[NSString stringWithFormat]&lt;/i&gt;, in fact the stringWithFormat calls have increased their presence in CPU time to 34% out of the total run-time. Considering the Shark data takes into account training time too, stringWithFormat is in fact burning probably around 50% of our CPU time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rXrjDFwt37w/Setyb8oKPPI/AAAAAAAACcw/CkXMOEoUOHw/s1600-h/CocoaSpellO1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 258px;" src="http://3.bp.blogspot.com/_rXrjDFwt37w/Setyb8oKPPI/AAAAAAAACcw/CkXMOEoUOHw/s320/CocoaSpellO1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5326476808752348402" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Googling around yet again, I've arrived to the conclusion that NSString might be indeed slow because of the complete UTF-8 support it offers. For the purpose of the spell checker, UTF-8 is not needed, but unfortunately you just can't tell NSString to not care about UTF-8.&lt;br /&gt;How about replacing stringWithFormat and forming a NSString out of pure C strings?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;- (NSSet *) edits1StringsInC:(NSString *) word&lt;br /&gt;{&lt;br /&gt; NSMutableSet * s = [NSMutableSet setWithCapacity:2000];&lt;br /&gt; &lt;br /&gt; int i=0;&lt;br /&gt; char c;&lt;br /&gt; &lt;br /&gt; #define MAX_LEN_C 500&lt;br /&gt; char toIndex[MAX_LEN_C];&lt;br /&gt; char fromIndex[MAX_LEN_C];&lt;br /&gt; char fromIndex2[MAX_LEN_C];&lt;br /&gt; char str[MAX_LEN_C];&lt;br /&gt; char temp[MAX_LEN_C];&lt;br /&gt; &lt;br /&gt; if([word length] &gt; MAX_LEN_C)&lt;br /&gt;  return [self edits1StringsInObjC:word];&lt;br /&gt; &lt;br /&gt; strcpy(str, [word cStringUsingEncoding:NSASCIIStringEncoding]);&lt;br /&gt; &lt;br /&gt; for(i=0;i&lt;[word length];i++)&lt;br /&gt; {&lt;br /&gt;  strncpy(toIndex, str, i);&lt;br /&gt;  toIndex[i] = '\0';&lt;br /&gt;  strcpy(fromIndex, str+i+1);&lt;br /&gt;  strcpy(fromIndex2, str+i);&lt;br /&gt;  &lt;br /&gt;  sprintf(temp, "%s%c%c%s", toIndex, str[i+1], str[i], str+i+2);&lt;br /&gt;  NSString * transposed = [NSString stringWithCString:temp length:strlen(temp)];&lt;br /&gt;  if(i&lt;[word length]-1)&lt;br /&gt;   [s addObject:transposed];&lt;br /&gt;  &lt;br /&gt;  sprintf(temp, "%s%s", toIndex, fromIndex);&lt;br /&gt;  NSString * deletion = [NSString stringWithCString:temp length:strlen(temp)];&lt;br /&gt;  [s addObject:deletion];&lt;br /&gt;  &lt;br /&gt;  for(c='a';c&lt;='z';c++)&lt;br /&gt;  {&lt;br /&gt;   sprintf(temp, "%s%c%s", toIndex, c, fromIndex);&lt;br /&gt;   NSString * replaced = [NSString stringWithCString:temp length:strlen(temp)];&lt;br /&gt;   [s addObject:replaced];&lt;br /&gt;   sprintf(temp, "%s%c%s", toIndex, c, fromIndex2);&lt;br /&gt;   NSString * inserted = [NSString stringWithCString:temp length:strlen(temp)];&lt;br /&gt;   [s addObject:inserted];&lt;br /&gt;  }  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; return s;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Timing the code after changing string forming to C shows a total runtime of 2.04 seconds.&lt;br /&gt;Our optimization has shaved off 1 second when checking miss-spells at edit distance 2 compared to the original implementation.&lt;br /&gt;In the total runtime, we're down to 38% from the initial implementation runtime. Mind you, it's still twice as slow when compared to the python equivalent.&lt;br /&gt;&lt;br /&gt;In this latest version, the CPU time is split between edits1StringsInC (3X), intersectSet (2X) and unionSet (1X).&lt;br /&gt;edits1StringsInC still takes most of the CPU time, with the most intensive operations being sprintf at 41% and stringWithCString at 30%.&lt;br /&gt;&lt;br /&gt;The next thing I tried is replacing sprintf with strcpy.&lt;br /&gt;Yet another half a second in speed gain, but the code becomes less and less readable:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;- (NSSet *) edits1StringsInCv2:(NSString *) word&lt;br /&gt;{&lt;br /&gt; NSMutableSet * s = [NSMutableSet setWithCapacity:2000];&lt;br /&gt; &lt;br /&gt; int i=0, len;&lt;br /&gt; char c;&lt;br /&gt; &lt;br /&gt; #define MAX_LEN_C 500&lt;br /&gt; char str[MAX_LEN_C];&lt;br /&gt; char temp[MAX_LEN_C];&lt;br /&gt; &lt;br /&gt; if([word length] &gt; MAX_LEN_C-1)&lt;br /&gt;  return [self edits1StringsInObjC:word];&lt;br /&gt; &lt;br /&gt; strcpy(str, [word cStringUsingEncoding:NSASCIIStringEncoding]);&lt;br /&gt; for(i=0;i&lt;[word length];i++)&lt;br /&gt; {&lt;br /&gt;  strcpy(temp, str); temp[i] = str[i+1]; temp[i+1] = str[i];&lt;br /&gt;  len = strlen(temp);&lt;br /&gt;  &lt;br /&gt;  if(i&lt;[word length]-1)&lt;br /&gt;  {&lt;br /&gt;   NSString * transposed = [NSString stringWithCString:temp length:len];&lt;br /&gt;   [s addObject:transposed];&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  strcpy(temp + i, str+i+1);&lt;br /&gt;  NSString * deletion = [NSString stringWithCString:temp length:strlen(temp)];&lt;br /&gt;  [s addObject:deletion];&lt;br /&gt;  &lt;br /&gt;  for(c='a';c&lt;='z';c++)&lt;br /&gt;  {&lt;br /&gt;   temp[i] = c; strcpy(temp + i + 1, str+i+1);&lt;br /&gt;   NSString * replaced = [NSString stringWithCString:temp length:len];&lt;br /&gt;   [s addObject:replaced];&lt;br /&gt;&lt;br /&gt;   strcpy(temp + i + 1, str+i);&lt;br /&gt;   NSString * inserted = [NSString stringWithCString:temp length:len+1];&lt;br /&gt;   [s addObject:inserted];&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return s;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Using strcpy and hard to follow pointer arithmetic instead of sprintf, we get at 1.5 seconds:&lt;br /&gt;&lt;br /&gt;&lt;table style="font-size: smaller; text-align: right"&gt;&lt;tr&gt;&lt;td&gt;generataed              &lt;/td&gt;&lt;td&gt; generate                      &lt;/td&gt;&lt;td&gt;-0.402929 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;acount                  &lt;/td&gt;&lt;td&gt; count                                 &lt;/td&gt;&lt;td&gt;-0.001699 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;guidlines               &lt;/td&gt;&lt;td&gt; guideline                     &lt;/td&gt;&lt;td&gt;-0.329685 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;wheere          &lt;/td&gt;&lt;td&gt; where                                 &lt;/td&gt;&lt;td&gt;-0.000743 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;myne                    &lt;/td&gt;&lt;td&gt; mine                          &lt;/td&gt;&lt;td&gt;-0.000473 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;graet                   &lt;/td&gt;&lt;td&gt; great                                 &lt;/td&gt;&lt;td&gt;-0.001423 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;silenc                  &lt;/td&gt;&lt;td&gt; silent                                &lt;/td&gt;&lt;td&gt;-0.000769 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;aggresive               &lt;/td&gt;&lt;td&gt; aggressive                    &lt;/td&gt;&lt;td&gt;-0.001243 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;appreceiated    &lt;/td&gt;&lt;td&gt; appreciated                   &lt;/td&gt;&lt;td&gt;-0.001449 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;aquantance              &lt;/td&gt;&lt;td&gt; acquaintance          &lt;/td&gt;&lt;td&gt;-0.421072 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;beggining               &lt;/td&gt;&lt;td&gt; beginning                     &lt;/td&gt;&lt;td&gt;-0.340965 s &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=2&gt;&lt;b&gt;Total runtime&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt; -1.509337&lt;/b&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In knownEdits2 Shark shows a tie between edit1StringsInCv2 and -[NSMutableSet intersectSet].&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/SetzjgFOmPI/AAAAAAAACc4/YpK3sMHG02g/s1600-h/CocoaSpellUglyC.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 238px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/SetzjgFOmPI/AAAAAAAACc4/YpK3sMHG02g/s320/CocoaSpellUglyC.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5326478038040221938" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;At this point, further optimizations in knownEdits probably don't make sense unless NSMutableSet is replaced too. And working with sets in plain C is not fun, so for now I'll settle with a 1.50 seconds, 35% slower run-time when compared to the python equivalent.&lt;br /&gt;&lt;br /&gt;Conclusions:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Python string handling is fast&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Python set operations are fast&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Objective-C string operations are slow&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-477651295749702474?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/477651295749702474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=477651295749702474' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/477651295749702474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/477651295749702474'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/04/on-my-objective-c-code-thats-slower.html' title='On (my) Objective-C code that&apos;s slower then expected'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_rXrjDFwt37w/SetxLoxozFI/AAAAAAAACco/LlCq2yGNaOk/s72-c/CocoaSpellUnoptimized.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5318421505179480744</id><published>2009-04-17T14:28:00.004+03:00</published><updated>2009-04-17T14:56:57.502+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ip'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='geographical location'/><title type='text'>Network connections by geographic location</title><content type='html'>A couple of days ago, a colleague made me aware that iplocationtools.com exposes a cool web service that allows you to get the geographical location based on an IP address.&lt;br /&gt;&lt;br /&gt;Here's a script that parses the IP addresses the workstation is connected to, and then resolves each one to its geographical location:&lt;br /&gt; &lt;br /&gt;&lt;table style="width:200px"&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;clear; netstat -an | grep ESTABLISHED | awk {'print $5'} | sort -u | sed "s/\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*/\1/g" | while read sw; do url="http://iplocationtools.com/ip_query.php?ip=$sw"; curl $url -s | ~/tools/xmlstarlet sel -t -m "/Response/CountryName"  -v . -o "," -m "/Response/City" -v .  -; done&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Note the dependancy on &lt;a href="xmlstar.sourceforge.net/"&gt;xmlstarlet&lt;/a&gt; that allows easy extraction of values from XML content. Unlike xsltproc which demands a XSL file, xmlstarlet allows you to run an Xpath query, building the needed XSL file by itself.&lt;br /&gt;&lt;br /&gt;And here's a rundown of the script:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;clear&lt;/i&gt; just clears the shell screen.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;clear; netstat -an&lt;/i&gt; -&gt; get a list of connections, without attempting to solve names&lt;br /&gt;&lt;br /&gt;&lt;i&gt;clear; netstat -an | grep ESTABLISHED&lt;/i&gt; -&gt; keep only lines containing ESTABLISHED, that is active connections&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;clear; netstat -an | grep ESTABLISHED | awk {'print $5'}&lt;/i&gt; -&gt; keep only the 5th field from each line, containing the IP address we are connected to&lt;br /&gt;&lt;br /&gt;&lt;i&gt;clear; netstat -an | grep ESTABLISHED | awk {'print $5'} | sed "s/\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*/\1/g"&lt;/i&gt; -&gt; strip out the port number from the IP address.&lt;br /&gt;&lt;br /&gt;Without sed, netstat outputs stuff like &lt;i&gt;74.125.43.83.443&lt;/i&gt; where 443 is the TCP port we are connected to.&lt;br /&gt;To strip out the port, we can use sed, matching IP addresses to 4 groups of digits separated by a dot, i.e. \([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\). This is later matched by the "\1" reference.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;clear; netstat -an | grep ESTABLISHED | awk {'print $5'} | sort -u | sed "s/\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*/\1/g" | while read sw; do &lt;b&gt;command&lt;/b&gt; done&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;What follows is a while loop, where we read each ip address, one at a time and execute the localization command.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;command&lt;/b&gt; is:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;url="http://iplocationtools.com/ip_query.php?ip=$sw"; curl $url -s | ~/tools/xmlstarlet sel -t -m "/Response/CountryName"  -v . -o "," -m "/Response/City" -v .  -&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;We use &lt;i&gt;curl&lt;/i&gt; to get an XML document that lists the geolocation of the IP we and then process the XML document using xmlstarlet, by extracting the country and city name.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-5318421505179480744?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5318421505179480744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5318421505179480744' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5318421505179480744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5318421505179480744'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/04/network-connections-by-geographic.html' title='Network connections by geographic location'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5648025562755846419</id><published>2009-03-10T14:04:00.006+02:00</published><updated>2009-04-28T14:45:51.247+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sysctl'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>Network statistics on OS X using the sysctl interface</title><content type='html'>sysctl offers read access to a couple of kernel structures that contain network statistics.&lt;br /&gt;&lt;br /&gt;I am yet to figure out the difference in between the IP statistics as read from the "net.inet.ip.stats" sysctl value when compared to the values as read by netstat (as seen below, IP stats prints 114243 packets and netstat reports 116840).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cristi:tmp diciu$ ./a.out&lt;br /&gt;IP packets received:        114243&lt;br /&gt;IP packets generated here:  85251&lt;br /&gt;TCP connection attempts:    3337&lt;br /&gt;TCP total packets sent:     81779&lt;br /&gt;TCP total packets received: 105700&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cristi:tmp diciu$ netstat -bi&lt;br /&gt;Name  Mtu   Network       Address            Ipkts Ierrs     Ibytes    Opkts Oerrs     Obytes  Coll&lt;br /&gt;[..]&lt;br /&gt;en0   1500  Link#4    xx:xx:xx:xx:xx:xx   116840     0  113745333    85202     0   13307330     0&lt;br /&gt;[..]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's the C source for the sysctl reader:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;#include &amp;lt;sys/sysctl.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;sys/socketvar.h&amp;gt;&lt;br /&gt;#include &amp;lt;netinet/ip.h&amp;gt;&lt;br /&gt;#include &amp;lt;netinet/ip_var.h&amp;gt;&lt;br /&gt;#include &amp;lt;netinet/tcp.h&amp;gt;&lt;br /&gt;#include &amp;lt;netinet/tcp_var.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; void * oldp = malloc(1024);&lt;br /&gt; size_t oldlen = sizeof(struct ipstat), newlen;&lt;br /&gt; void * newp = NULL;&lt;br /&gt;&lt;br /&gt; int retval = sysctlbyname("net.inet.ip.stats", oldp, &amp;oldlen, newp, newlen);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; struct ipstat * g = (struct ipstat *) oldp;&lt;br /&gt; printf("IP packets received:        %d\n", g-&gt;ips_total);&lt;br /&gt; printf("IP packets generated here:  %d\n", g-&gt;ips_localout);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; struct tcpstat * t = (struct tcpstat *) oldp;&lt;br /&gt; oldlen = sizeof(struct  tcpstat);&lt;br /&gt; retval = sysctlbyname("net.inet.tcp.stats", oldp, &amp;oldlen, newp, newlen);&lt;br /&gt; printf("TCP connection attempts:    %d\n", t-&gt;tcps_connattempt);&lt;br /&gt; printf("TCP total packets sent:     %d\n", t-&gt;tcps_sndtotal);&lt;br /&gt; printf("TCP total packets received: %d\n", t-&gt;tcps_rcvtotal);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-5648025562755846419?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5648025562755846419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5648025562755846419' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5648025562755846419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5648025562755846419'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/03/network-statistics-on-os-x-using-sysctl.html' title='Network statistics on OS X using the sysctl interface'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-9140578350023069031</id><published>2009-02-02T14:58:00.009+02:00</published><updated>2011-05-03T13:52:48.022+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tesseract'/><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>Tesseract GUI for Mac OS X</title><content type='html'>&lt;i&gt;Update 3 May 2011:&lt;br /&gt;&lt;br /&gt;I've released new version for TesseractGUI (0.3) - the new version is using tesseract version 3 and it is linked against libtiff so it is able to open compressed TIFF files (packbits, lwz).&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've created a very simple user interface on top of tesseract.&lt;br /&gt;&lt;br /&gt;It's available, along with sources under the MIT license, at: &lt;a href="http://download.dv8.ro/files/TesseractGUI/"&gt;http://download.dv8.ro/files/TesseractGUI/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To use Tesseract GUI, open a TIF image.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rXrjDFwt37w/SYbwnNAG4KI/AAAAAAAACMg/Ck93y82Jxwk/s1600-h/Picture+2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 257px;" src="http://3.bp.blogspot.com/_rXrjDFwt37w/SYbwnNAG4KI/AAAAAAAACMg/Ck93y82Jxwk/s320/Picture+2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5298186567943643298" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;After a couple of seconds, Tessertact GUI will switch to the text tab where it displays whatever it was able to recognize:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/SYbw7cNkkWI/AAAAAAAACMo/npUfGQH4hjQ/s1600-h/Picture+3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 256px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/SYbw7cNkkWI/AAAAAAAACMo/npUfGQH4hjQ/s320/Picture+3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5298186915624030562" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Nothing is saved, so if the recognition was successful you probably want to copy and paste it in some document.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-9140578350023069031?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/9140578350023069031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=9140578350023069031' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/9140578350023069031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/9140578350023069031'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/02/tesseract-gui.html' title='Tesseract GUI for Mac OS X'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_rXrjDFwt37w/SYbwnNAG4KI/AAAAAAAACMg/Ck93y82Jxwk/s72-c/Picture+2.png' height='72' width='72'/><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-7028902312207832306</id><published>2009-01-19T21:42:00.007+02:00</published><updated>2009-01-20T06:18:45.377+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='diacritics'/><category scheme='http://www.blogger.com/atom/ns#' term='case folding'/><category scheme='http://www.blogger.com/atom/ns#' term='romanian'/><title type='text'>Bătăi de cîmpi: De ce scriu cu î și nu cu â?</title><content type='html'>A new take on the diacritical marks in Romanian (written in Romanian) : &lt;a href="http://fieldbeatings.blogspot.com/2009/01/de-ce-scriu-cu-i-nu-cu.html#links"&gt;Bătăi de cîmpi: De ce scriu cu î și nu cu â?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Linguistics, history and common sense aside, the programming solution of string diacritic insensitive folding when &lt;a href="http://blog.dv8.ro/2008/11/diacritical-insensitive-comparison.html"&gt;performing searches&lt;/a&gt; no longer works as "â" is folded to "a" and "î" is folded to "i"; "a" is not equal to "i".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I for one do not agree with not using â simply because it's already been (widely) adopted - as Google puts it:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Results 1 - 10 of about 9,910,000 for brânză&lt;br /&gt;Results 1 - 10 of about 163,000 for brînză&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The damage is done, the two versions are hard to support side by side (see diacritical folding reason), politics sucks, be a man and admit it - â has won.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PS Diacritical folding failure test case below:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include &amp;lt;Cocoa/Cocoa.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; NSAutoreleasePool * pool = [NSAutoreleasePool new];&lt;br /&gt; NSString * str1 = [NSString stringWithString:@"brinza"];&lt;br /&gt; NSString * str2 = [NSString stringWithString:@"brînză"];&lt;br /&gt;&lt;br /&gt; int res = [str1 compare:str2 options:NSDiacriticInsensitiveSearch];&lt;br /&gt; NSLog(@"The strings %@, %@ are %@equal", str1, str2, res == NSOrderedSame ? @"" : @"not ");&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; NSString * str3 = [NSString stringWithString:@"brânză"];&lt;br /&gt; res = [str1 compare:str3 options:NSDiacriticInsensitiveSearch];&lt;br /&gt; NSLog(@"The strings %@, %@ are %@equal", str1, str3, res == NSOrderedSame ? @"" : @"not ");&lt;br /&gt;&lt;br /&gt; [pool release];&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cristi:tmp diciu$ ./a.out &lt;br /&gt;2009-01-19 21:40:45.935 a.out[6734:10b] The strings brinza, brînză are equal&lt;br /&gt;2009-01-19 21:40:45.965 a.out[6734:10b] The strings brinza, brânză are not equal&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/31740253-7028902312207832306?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/7028902312207832306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=7028902312207832306' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7028902312207832306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7028902312207832306'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/01/bti-de-cmpi-de-ce-scriu-cu-i-nu-cu.html' title='Bătăi de cîmpi: De ce scriu cu î și nu cu â?'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-8810631645467265281</id><published>2009-01-09T13:06:00.008+02:00</published><updated>2009-01-09T13:38:42.312+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='bucharest'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><title type='text'>BucharestApp 1.8 is out</title><content type='html'>&lt;a href="http://dv8.ro/Bucharest/Bucharest.html"&gt;BucharestApp 1.8&lt;/a&gt; is out with some work in the place finding area (Point Of Interest finding and finding places around a given geographical location picked by clicking on the map).&lt;br /&gt;&lt;br /&gt;There's a new menu item in the Control-Click contextual menu titled "Coordinates" that allows you to start the POI finder panel centered around the click location or to copy the click coordinates to the clipboard:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rXrjDFwt37w/SWcwpvQ1-dI/AAAAAAAAB_E/tPE1QeB8eTA/s1600-h/CopyCoords.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 170px;" src="http://1.bp.blogspot.com/_rXrjDFwt37w/SWcwpvQ1-dI/AAAAAAAAB_E/tPE1QeB8eTA/s320/CopyCoords.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5289249780989819346" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The POI finder offers a number of built-in POI queries (for ATMs, banks, bus stops, malls, etc) but it does not expose all the capabilities of the namefinder (you are not able to search for pubs, hospitals, airports, etc using the POI finder).&lt;br /&gt;&lt;br /&gt;However, you can copy the coordinates to clipboard and locate pubs through a custom search in the place finder panel:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rXrjDFwt37w/SWcxWo_gbkI/AAAAAAAAB_M/76TXGiAuV6A/s1600-h/pubsearch.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 116px;" src="http://4.bp.blogspot.com/_rXrjDFwt37w/SWcxWo_gbkI/AAAAAAAAB_M/76TXGiAuV6A/s320/pubsearch.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5289250552400604738" /&gt;&lt;/a&gt;&lt;br /&gt;The results are displayed based on distance from the coordinates used in the query, from the nearest to the furthest:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rXrjDFwt37w/SWcxq7gm1pI/AAAAAAAAB_U/O5plhpVNycA/s1600-h/pubsearchresult.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 249px; height: 320px;" src="http://3.bp.blogspot.com/_rXrjDFwt37w/SWcxq7gm1pI/AAAAAAAAB_U/O5plhpVNycA/s320/pubsearchresult.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5289250900968658578" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As with everything else, the chance of actually finding something you're looking for depends on the work of the folks contributing on OpenStreetMap so if you can't find you favorite pub or cafe you might want to log in the OpenStreetMap site and add it yourself.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-8810631645467265281?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/8810631645467265281/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=8810631645467265281' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8810631645467265281'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8810631645467265281'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2009/01/bucharestapp-18-is-out.html' title='BucharestApp 1.8 is out'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_rXrjDFwt37w/SWcwpvQ1-dI/AAAAAAAAB_E/tPE1QeB8eTA/s72-c/CopyCoords.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-6262837749832313018</id><published>2008-12-22T18:53:00.006+02:00</published><updated>2008-12-30T12:43:06.898+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tesseract'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='ocr'/><title type='text'>Open source OCR on Mac OS X: tesseract</title><content type='html'>I am looking for a optical character recognition solution and I've checked out OCRopus, but the early alpha stages it's in make it very hard to compile. OCRopus lists &lt;a href="http://code.google.com/p/tesseract-ocr/wiki/ReadMe"&gt;tesseract&lt;/a&gt; as a dependancy so I've compiled and ran tesseract on a couple of scanned pages.&lt;br /&gt;&lt;br /&gt;The results are impressive (see below the results of running it on a page from a Cisco manual).&lt;br /&gt;&lt;table&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/SVn2728v1nI/AAAAAAAAB-8/9UHyMTHWAYQ/s1600-h/input.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 168px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/SVn2728v1nI/AAAAAAAAB-8/9UHyMTHWAYQ/s320/input.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5285527145919010418" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;tr&gt;&lt;br /&gt;&lt;td style='font-size:smaller'&gt;&lt;br /&gt;Chapter 24 • Mixed-Media Bridging&lt;br /&gt; &lt;br /&gt;ending delimiter, which follows the data field) are treated differently depende&lt;br /&gt;ing on the bridge manufacturer Some bridge manufacturers simply ignore the&lt;br /&gt;bits. Others have the bridge set the C bit (to indicate that the frame has been&lt;br /&gt;copied) but not the A bit (which indicates that the destination station recog-&lt;br /&gt;nizes die address). Ln the former case, a Token Ring source node determines&lt;br /&gt;whether the frame it sent has become lost. Proponents of this approach sug~&lt;br /&gt;gest that reliability mechanisms, such as the tracking of lost frames [..]&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-6262837749832313018?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/6262837749832313018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=6262837749832313018' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6262837749832313018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6262837749832313018'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/12/open-source-ocr-on-mac-os-x-tesseract.html' title='Open source OCR on Mac OS X: tesseract'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rXrjDFwt37w/SVn2728v1nI/AAAAAAAAB-8/9UHyMTHWAYQ/s72-c/input.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-8434906272316008038</id><published>2008-12-18T20:02:00.004+02:00</published><updated>2008-12-18T20:14:36.136+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web services'/><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='objective-c'/><title type='text'>Web Services from Cocoa/Objective-C</title><content type='html'>If you're looking into using web services from Cocoa don't bother with WSMakeStubs. &lt;br /&gt;&lt;br /&gt;It's so bad it's not even funny.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/SUqS327C2mI/AAAAAAAAB-U/1cUucLuStuM/s1600-h/DSC_0130.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 133px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/SUqS327C2mI/AAAAAAAAB-U/1cUucLuStuM/s200/DSC_0130.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5281195001378953826" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-8434906272316008038?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/8434906272316008038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=8434906272316008038' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8434906272316008038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8434906272316008038'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/12/web-services-from-cocoaobjective-c.html' title='Web Services from Cocoa/Objective-C'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rXrjDFwt37w/SUqS327C2mI/AAAAAAAAB-U/1cUucLuStuM/s72-c/DSC_0130.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-2304131609925935127</id><published>2008-12-17T20:05:00.006+02:00</published><updated>2008-12-17T20:42:44.165+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gcc'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='framework'/><title type='text'>Trying out an OS X framework without installing it</title><content type='html'>One of the things I dread is installing stuff on my box. And by installing I refer to those things using the OS X installer that copy themselves deep within the system. I am aware of &lt;i&gt;lsbom&lt;/i&gt; and &lt;i&gt;/Library/Receipts&lt;/i&gt; but whenever I can avoid it I choose not to install.&lt;br /&gt;&lt;br /&gt;I especially don't like installing frameworks because they make my system incompatible with "vanilla" systems. I may at some point ship an application that depends on a framework that works fine on my system but instantly fails on a "vanilla" system, the dynamic linker complaining "image not found" as it tries to load the missing framework.&lt;br /&gt;&lt;br /&gt;The solution is using a framework without actually installing it in /System/Library.&lt;br /&gt;&lt;br /&gt;This can be done in XCode but I prefer the console - I find using gcc and the linker from the command line a good habit as it acts as a constant reminder of the process XCode hides away behind the build button.&lt;br /&gt;Here's how to use gcc to compile a simple binary against a framework, without the framework being installed on the system:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#import &amp;lt;Cocoa/Cocoa.h&amp;gt;&lt;br /&gt;#import &amp;lt;RegexKit/NSString.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; NSAutoreleasePool * pool = [NSAutoreleasePool new];&lt;br /&gt;&lt;br /&gt; NSString * t = @"This is a string with 12 or more characters on line 1";&lt;br /&gt; NSLog(@"t is %@", t);&lt;br /&gt;&lt;br /&gt; NSString * nodigits = [t stringByMatching:@"(\\d)" &lt;br /&gt;                                                   replace:RKReplaceAll &lt;br /&gt;                                                   withReferenceString:@"5"];&lt;br /&gt; NSLog(@"\nInput: &gt;&gt;&gt; %@\nOutput: &gt;&gt;&gt;  %@", t, nodigits);&lt;br /&gt;&lt;br /&gt; [pool release];&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Our example above replaces any digit with an NSString with the digit "5".&lt;br /&gt;It uses the &lt;a href="http://regexkit.sourceforge.net/"&gt;RegexKit framework&lt;/a&gt; which I've previously unarchived on the Desktop (click right on RegexKit_Framework.pkg -&gt; choose "Show Package Contents" -&gt; unzip Archive.pax)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;diciu$ gcc regexp.m -framework Cocoa   -framework RegexKit  -F/Users/diciu/Desktop/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;When running the binary you have to remember to set the DYLD_FRAMEWORK_PATH environment variable:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;diciu$ DYLD_FRAMEWORK_PATH=/Users/diciu/Desktop/ ./a.out&lt;br /&gt;2008-12-17 20:12:49.979 a.out[3925:10b] &lt;br /&gt;Input: &gt;&gt;&gt; This is a string with 12 or more characters on line 1&lt;br /&gt;Output: &gt;&gt;&gt;  This is a string with 55 or more characters on line 5&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/31740253-2304131609925935127?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/2304131609925935127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=2304131609925935127' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/2304131609925935127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/2304131609925935127'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/12/trying-out-os-x-framework-without.html' title='Trying out an OS X framework without installing it'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-6636785556938187070</id><published>2008-12-12T11:03:00.007+02:00</published><updated>2008-12-21T13:02:18.171+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='untested code'/><category scheme='http://www.blogger.com/atom/ns#' term='clang'/><category scheme='http://www.blogger.com/atom/ns#' term='llvm'/><title type='text'>Don't trust clang blindly</title><content type='html'>&lt;i&gt;Update: Thanks to a comment by Ted Kremenek I discovered that the official clang tool does not emit the warning discussed below. It turns out that the AnalysisTool.app frontend application that I've used ships with its own modified clang.&lt;br /&gt;&lt;br /&gt;Reading his comment I've also realized that my post might be interpreted as a criticism on clang and this is not the case - I think clang is a great addition to the existing tools on Mac OS X. It's just that, unlike &lt;b&gt;leaks&lt;/b&gt;, static checkers should be used before the testing stage.&lt;br /&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://clang.llvm.org/"&gt;clang&lt;/a&gt; and the &lt;a href="http://clang.llvm.org/StaticAnalysis.html"&gt;static analyzer&lt;/a&gt; that's built on top of it work by analyzing your sources while being compiled and making suggestions. Sort of like the warnings in GCC but on a deeper level, e.g.:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;NSString *string;&lt;br /&gt;string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;font color="yellow"&gt;&lt;br /&gt;'autorelease' should be called right after alloc &amp; init. Do not leave the responsibility of calling 'release' until later stages.&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;But clang goes wrong as the code that follows the lines above is:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if(string != nil)&lt;br /&gt;  [textBuffer appendString:string];&lt;br /&gt;  &lt;br /&gt;[string autorelease];&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Trusting clang's warning without realizing that two lines later the &lt;i&gt;string&lt;/i&gt; variable was already being auto-released results in a crasher due to over-releasing.&lt;br /&gt;&lt;br /&gt;Sure, clang is right and it doesn't really make sense to not auto-release the string immediately on but from a functional point of view not acting on clang's warning produces leak-free workable code, while following it blindly (i.e. without re-reading the entire context) makes clang happy but yields a crasher.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Which is exactly what happened with releases 1.5 and 1.6 of BucharestApp. &lt;br /&gt;The moral of the story? &lt;font style='+1'&gt;never ship untested code. &lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-6636785556938187070?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/6636785556938187070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=6636785556938187070' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6636785556938187070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6636785556938187070'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/12/dont-trust-clang-blindly.html' title='Don&apos;t trust clang blindly'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-8105643080148599328</id><published>2008-12-11T09:30:00.008+02:00</published><updated>2008-12-12T11:03:33.522+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='bucharest'/><title type='text'>BucharestApp 1.5 is out</title><content type='html'>Download link: &lt;a href="http://download.dv8.ro/files/BucharestApp.zip"&gt;BucharestApp.zip [50Mb]&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Yet another later edit: make that 1.7&lt;br /&gt;&lt;p&gt;Changes in version 1.7&lt;br /&gt;&lt;ul style='font-size:smaller'&gt;&lt;br /&gt;&lt;li&gt;Fixed a crasher when computing a route caused by an over-released NSString.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;Later edit: make that 1.6.&lt;br /&gt;&lt;p&gt;Changes in version 1.6&lt;br /&gt;&lt;ul style='font-size:smaller'&gt;&lt;br /&gt;&lt;li&gt;Fixed a crasher when installing the map caused by an over-released NSString.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Changes in version 1.5&lt;br /&gt;&lt;ul style='font-size:smaller'&gt;&lt;br /&gt;&lt;li&gt;Place finder filters search results by geographical coordinates&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Rendering based on data from December 2008&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A bit more sane window and panel placement when Desktop spans multiple monitors&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A map versioner so that new application versions can override cached data if necessary&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Control-click for contextual menu for setting route from,to&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Route and segment length computed in Km&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Highlight segments table&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;New stuff includes entire Romania rendering at zoom level 10 (thus the small increase in app size), a bit of work on route finding and displaying the segments that are part of a route. The place finder is now based on interaction with a server side component that is hosted in Romania (we're hosting our own gazetteer).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-8105643080148599328?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/8105643080148599328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=8105643080148599328' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8105643080148599328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8105643080148599328'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/12/bucharestapp-15-is-out.html' title='BucharestApp 1.5 is out'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-6724213977623263347</id><published>2008-12-04T14:12:00.005+02:00</published><updated>2008-12-04T14:23:26.270+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cisco'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='ipv6'/><title type='text'>Cisco VPN client used over 3G modem incompatible with Parallels</title><content type='html'>If your Cisco VPN Client is disconnecting your VPN connection a couple of seconds after it's established when you're using a 3G USB modem, the culprit might be Parallels.&lt;br /&gt;&lt;br /&gt;In my case, disabling IPv6 and IPv4 on both Parallels interfaces made the problem disappear.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rXrjDFwt37w/STfKG_9e0tI/AAAAAAAAB8M/6PwmiQYTQaQ/s1600-h/Picture+1.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 150px;" src="http://3.bp.blogspot.com/_rXrjDFwt37w/STfKG_9e0tI/AAAAAAAAB8M/6PwmiQYTQaQ/s200/Picture+1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5275907710085157586" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rXrjDFwt37w/STfKOXKN-WI/AAAAAAAAB8U/eQlTnXcVCWk/s1600-h/Picture+2.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px; height: 152px;" src="http://4.bp.blogspot.com/_rXrjDFwt37w/STfKOXKN-WI/AAAAAAAAB8U/eQlTnXcVCWk/s200/Picture+2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5275907836571679074" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-6724213977623263347?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/6724213977623263347/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=6724213977623263347' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6724213977623263347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6724213977623263347'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/12/cisco-vpn-client-used-over-3g-modem.html' title='Cisco VPN client used over 3G modem incompatible with Parallels'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_rXrjDFwt37w/STfKG_9e0tI/AAAAAAAAB8M/6PwmiQYTQaQ/s72-c/Picture+1.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-8439590385874718532</id><published>2008-11-27T13:43:00.004+02:00</published><updated>2008-11-27T13:50:44.625+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='old news'/><category scheme='http://www.blogger.com/atom/ns#' term='gcc'/><title type='text'>gcc poison pragma</title><content type='html'>Useful when you want to get rid of C calls that should not be used because they are unsafe, like strcpy or sprintf: GCC's pre-processor allows you to mark a function as poisonous, causing calls to it to become a compile time error:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include &amp;lt;string.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#pragma GCC poison strcpy&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    char t[5];&lt;br /&gt;    strcpy(t, "A");&lt;br /&gt;    printf("Hello World\n");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cristi:~ diciu$ gcc strcpy.c &lt;br /&gt;strcpy.c:10:2: error: attempt to use poisoned "strcpy"&lt;br /&gt;cristi:~ diciu$ &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/31740253-8439590385874718532?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/8439590385874718532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=8439590385874718532' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8439590385874718532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8439590385874718532'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/11/gcc-poison-pragma.html' title='gcc poison pragma'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-717642172676367135</id><published>2008-11-17T11:05:00.003+02:00</published><updated>2008-11-17T11:09:05.763+02:00</updated><title type='text'>BucharestApp 1.4</title><content type='html'>I've released &lt;a href="http://dv8.ro/Bucharest/Bucharest.html"&gt;Version 1.4 of BucharestApp&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Changelog:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;version 1.4&lt;br /&gt;&lt;li&gt;Help book&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Rendering based on data from November 2008&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;version 1.3&lt;br /&gt;&lt;li&gt;OpenLayer library off-line copy (complete off-line map)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Route from, to picking from map (shift-click sets from, alt-click sets to)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Proper resize on window resize (old version was reloading the entire document)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Keyboard navigation (arrow keys for navigation, plus key to zoom in, minus key to zoom out)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-717642172676367135?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/717642172676367135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=717642172676367135' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/717642172676367135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/717642172676367135'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/11/bucharestapp-14.html' title='BucharestApp 1.4'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5581885043322939424</id><published>2008-11-07T15:31:00.004+02:00</published><updated>2008-11-07T16:13:20.133+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='diacritics'/><category scheme='http://www.blogger.com/atom/ns#' term='case folding'/><category scheme='http://www.blogger.com/atom/ns#' term='romanian'/><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><title type='text'>Diacritical insensitive comparison, string folding</title><content type='html'>One of the common problems when dealing with language containing &lt;a href="http://en.wikipedia.org/wiki/Diacritic"&gt;diacritical marks&lt;/a&gt; is matching an improper writing of a word missing the diacritical marks.&lt;br /&gt;&lt;br /&gt;This is especially true for Romanian, as most Romanians (myself included) don't use diacritical marks when writing in Romanian.&lt;br /&gt;&lt;br /&gt;I'm not here to pass judgment on writing with or without diacritics. There are &lt;a href="http://kitblog.com/2008/10/romanian_diacritic_marks.html"&gt;others&lt;/a&gt; much better informed on the subject.&lt;br /&gt;&lt;br /&gt;The reality is improper use of diacritics will not disappear in the near future and the good news is that Cocoa has built-in support for dealing with this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;NSString * stringDia = [NSString stringWithString:@"Mămăligă"];&lt;br /&gt;NSString * string = [NSString stringWithString:@"Mamaliga"];&lt;br /&gt;&lt;br /&gt;int res = [stringDia compare:string options:NSDiacriticInsensitiveSearch];&lt;br /&gt;NSLog(@"The strings are %@equal", res == NSOrderedSame ? @"" : @"not ");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There's even an implementation for string folding which may be worthwhile if you're building an index of place names:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;b&gt;CFStringFold&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Discussion&lt;/i&gt;&lt;br /&gt;Character foldings are operations that convert any of a set of characters sharing similar semantics into a single representative from that set.&lt;br /&gt;&lt;br /&gt;You can use this function to preprocess strings that are to be compared, searched, or indexed.[..]&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;PS In care you were wondering: &lt;a href="http://en.wikipedia.org/wiki/Mămăligă"&gt;Mămăligă&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-5581885043322939424?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5581885043322939424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5581885043322939424' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5581885043322939424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5581885043322939424'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/11/diacritical-insensitive-comparison.html' title='Diacritical insensitive comparison, string folding'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-184627776339202968</id><published>2008-10-27T07:50:00.005+02:00</published><updated>2008-10-27T08:41:48.129+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vodafone mobile connect'/><category scheme='http://www.blogger.com/atom/ns#' term='3g'/><title type='text'>When Vodafone Mobile Connect refuses to start</title><content type='html'>The problem: at some point Vodafone Mobile Connect refuses to start. The application icon bounces in the dock for a couple of minutes and the application window never gets displayed. The only way to quit the application at this point is using "Force Quit".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Quick solution&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1/ Force quit VMC&lt;br /&gt;&lt;br /&gt;2/ Delete "/Library/Application Support/nova media/VMC/ppp_session.log"&lt;br /&gt;&lt;br /&gt;3/ Start VMC&lt;br /&gt;&lt;br /&gt;Please note that deleting the ppp_session.log file wipes your PPP session history so VMC will re-start the traffic statistics from zero.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Why it hangs&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;VMC maintains a log of all the PPP traffic that flows through the 3G PPP interface. This log is saved under the ppp_session.log file mentioned above.&lt;br /&gt;&lt;br /&gt;In certain conditions (e.g. traffic exceeding 90 MB in the previous session), VMC enters a function that never finishes execution  namely:&lt;br /&gt;&lt;br /&gt;001a428e t _ClassConnectionAbstract.TrafficFormat%s%o&amp;lt;ClassConnectionAbstract&amp;gt;i4&lt;br /&gt;&lt;br /&gt;Here's an Instruments screenshot demonstrating the endless loop:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/SQVXO7w_GBI/AAAAAAAAB7s/KiQu-WzVfpc/s1600-h/Picture+2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 118px;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/SQVXO7w_GBI/AAAAAAAAB7s/KiQu-WzVfpc/s320/Picture+2.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5261707653725231122" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This is the ppp_session line that causes the infinite loop on my Mac:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;diciu$ diff ~/Desktop/ppp_session.log.crasher ~/Desktop/ppp_session.log.works&lt;br /&gt;200d199&lt;br /&gt;&lt; [2008/10/25 13:7:14] out:8736305 in:99719384 time:14036 &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The problem with that line is the "in" value which is too big - I'm &lt;i&gt;guessing&lt;/i&gt; it's causing "pow" (the C function for computing the raising of X to the power of Y) to return a range error and the calling function doesn't process this error correctly (i.e. it calls pow$fenv_access_off again instead of exiting).&lt;br /&gt;&lt;br /&gt;On Leopard, the effect is you cannot download more then 90 MB in one session - if you do, Vodafone Mobile Connect will refuse to start the next time you run it.&lt;br /&gt;&lt;br /&gt;To fix the problem you either edit the ppp_session.log file and remove the last line, or, you delete the file altogether.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-184627776339202968?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/184627776339202968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=184627776339202968' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/184627776339202968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/184627776339202968'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/10/when-vodafone-mobile-connect-refuses-to.html' title='When Vodafone Mobile Connect refuses to start'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rXrjDFwt37w/SQVXO7w_GBI/AAAAAAAAB7s/KiQu-WzVfpc/s72-c/Picture+2.png' height='72' width='72'/><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-7890500348769242714</id><published>2008-10-13T16:33:00.004+03:00</published><updated>2008-10-13T16:37:42.659+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='myown'/><title type='text'>OpenStreetMap map of Bucharest as .app</title><content type='html'>&lt;a href="http://dv8.ro/Bucharest/Bucharest.html"&gt;BucharestApp&lt;/a&gt; is a map rendering of Bucharest based on OpenStreetMap data, with a place finder panel and routing based on Gosmore.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rXrjDFwt37w/SPNOhDti2KI/AAAAAAAAB7k/vI4LcYAYRBE/s1600-h/BucharestApp%2BSearch.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_rXrjDFwt37w/SPNOhDti2KI/AAAAAAAAB7k/vI4LcYAYRBE/s400/BucharestApp%2BSearch.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5256631519910484130" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-7890500348769242714?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/7890500348769242714/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=7890500348769242714' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7890500348769242714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7890500348769242714'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/10/openstreetmap-map-of-bucharest-as-app.html' title='OpenStreetMap map of Bucharest as .app'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_rXrjDFwt37w/SPNOhDti2KI/AAAAAAAAB7k/vI4LcYAYRBE/s72-c/BucharestApp%2BSearch.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5670261551400521418</id><published>2008-10-01T18:04:00.009+03:00</published><updated>2008-10-02T11:07:20.759+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='core data'/><category scheme='http://www.blogger.com/atom/ns#' term='f-script'/><title type='text'>F-Script and Core Data</title><content type='html'>F-Script has very powerful support for array and set operations. This makes it particularly interesting when analyzing core data as it allows very easy querying of the data sets.&lt;br /&gt;&lt;br /&gt;The first part is setting up the core data entities array in F-Script - this is pretty lengthy as you have to load both the object model and the managed object context tied to the persistent store holding the actual data.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;If you want to paste the data below in the F-Script interpreter window, press F7. F-Script will say &amp;quot;When pasting command, newline is now interpreted as subcommands separator&amp;quot;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mompath := NSString stringWithString:'/Users/diciu/FoodBrowser/build/Release/FoodBrowser.app/Contents/Resources/FoodHistory.mom'&lt;br /&gt;momurl := NSURL URLWithString:mompath &lt;br /&gt;mom := NSManagedObjectModel alloc initWithContentsOfURL:momurl&lt;br /&gt;&lt;br /&gt;pstore := NSPersistentStoreCoordinator alloc initWithManagedObjectModel:mom&lt;br /&gt;&lt;br /&gt;sqfile := NSString stringWithString:'/Users/diciu/Library/Application Support/FoodBrowser/FoodHistory.sql'&lt;br /&gt;sqfileurl := NSURL fileURLWithPath:sqfile&lt;br /&gt;pstore addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:sqfileurl options:nil error:nil&lt;br /&gt;&lt;br /&gt;mocontext:= NSManagedObjectContext alloc init&lt;br /&gt;mocontext setPersistentStoreCoordinator:pstore&lt;br /&gt;&lt;br /&gt;edes := NSEntityDescription entityForName:'FoodItem' inManagedObjectContext:mocontext&lt;br /&gt;fetchreq := NSFetchRequest alloc init&lt;br /&gt;fetchreq setEntity:edes  &lt;br /&gt;&lt;br /&gt;dataitems := mocontext executeFetchRequest:fetchreq error:nil&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Once you've fetched your data, you can use the power of F-Script to analyze it:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; dataitems&lt;br /&gt;_PFArray {&lt;NSManagedObject: 0x4e42c0&gt; (entity: FoodItem; id: 0x4da020 &lt;x-coredata://BB042234-54BD-4984-A0C3-78A5A6133901/FoodItem/p1&gt; ; data: {&lt;br /&gt;    energy = 380;&lt;br /&gt;    name = "Snacks, pretzels, hard, plain, salted";&lt;br /&gt;    quantity = 100;&lt;br /&gt;    time = 2008-06-27 09:30:00 +0300;&lt;br /&gt;    value = 380;&lt;br /&gt;}), &lt;br /&gt;&lt;NSManagedObject: 0x4e4510&gt; (entity: FoodItem; id: 0xda192c0 &lt;x-coredata://BB042234-54BD-4984-A0C3-78A5A6133901/FoodItem/p2&gt; ; data: {&lt;br /&gt;    energy = 0;&lt;br /&gt;    name = "Water, bottled, generic";&lt;br /&gt;    quantity = 100;&lt;br /&gt;    time = 2008-06-27 10:02:00 +0300;&lt;br /&gt;    value = 0;&lt;br /&gt;}), &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Running sum through reduction:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; (dataitems energy) \#+&lt;br /&gt;19777.38003540039&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Average:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; (dataitems energy) \#+ / (dataitems count)&lt;br /&gt;229.9695352953534&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Maximum:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; (dataitems energy) \#max:&lt;br /&gt;1080&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Minimum&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; (dataitems energy) \#min:&lt;br /&gt;0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Is minimum value sane? (retrieve the index)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; (dataitems energy) ! ((dataitems energy) \#min:)&lt;br /&gt;1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Print the object at index one:&lt;br /&gt;&lt;br /&gt;&gt; dataitems at:1&lt;br /&gt;&lt;NSManagedObject: 0x4e4510&gt; (entity: FoodItem; id: 0xda192c0 &lt;x-coredata://BB042234-54BD-4984-A0C3-78A5A6133901/FoodItem/p2&gt; ; data: {&lt;br /&gt;    energy = 0;&lt;br /&gt;    name = "Water, bottled, generic";&lt;br /&gt;    quantity = 100;&lt;br /&gt;    time = 2008-06-27 10:02:00 +0300;&lt;br /&gt;    value = 0;&lt;br /&gt;})&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To run the graphical browser on the set of managed items, use:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt; sys browse:dataitems&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_rXrjDFwt37w/SOOgkaA7-NI/AAAAAAAAB7E/SjDzbGtlJfI/s1600-h/F-Script_core_data.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_rXrjDFwt37w/SOOgkaA7-NI/AAAAAAAAB7E/SjDzbGtlJfI/s400/F-Script_core_data.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5252218137763117266" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Reference: &lt;a href="http://www.fscript.org/documentation/ExploringCocoaWithFScript/#ExploringCoreData"&gt; ExploringCocoaWithFScript&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-5670261551400521418?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5670261551400521418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5670261551400521418' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5670261551400521418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5670261551400521418'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/10/f-script-and-core-data.html' title='F-Script and Core Data'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_rXrjDFwt37w/SOOgkaA7-NI/AAAAAAAAB7E/SjDzbGtlJfI/s72-c/F-Script_core_data.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-7329761289304510332</id><published>2008-09-30T14:37:00.002+03:00</published><updated>2008-09-30T14:39:21.960+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='foodbrowser'/><title type='text'>FoodBrowser 1.3 beta released</title><content type='html'>Change log:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Monthly graph - work in progress &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Calorie estimation box based on Mifflin and St Jeor&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Copying foods in the history (copy, paste, drag and drop)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Editing time in the history&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Fixed bug that caused some missing dates in the Energy Calculator window&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Fixed bug in drag and drop of some foods&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-7329761289304510332?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/7329761289304510332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=7329761289304510332' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7329761289304510332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7329761289304510332'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/09/foodbrowser-13-beta-released.html' title='FoodBrowser 1.3 beta released'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-1208310450273517692</id><published>2008-09-25T17:08:00.004+03:00</published><updated>2008-09-25T17:27:29.772+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bad block'/><category scheme='http://www.blogger.com/atom/ns#' term='raid'/><category scheme='http://www.blogger.com/atom/ns#' term='smartmontools'/><title type='text'>A failing disk and the first time I see S.M.A.R.T. actually working</title><content type='html'>One of the disks that are part of the software RAID powering loudhush.ro has developed a bad sector.&lt;br /&gt;The bad news arrived via email, thanks to smartmontools:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;The following warning/error was logged by the smartd daemon:&lt;br /&gt;Device: /dev/hdc, 1 Currently unreadable (pending) sectors&lt;br /&gt;For details see host's SYSLOG (default: /var/log/messages).&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The good news is you can tell the disk to re-allocate the bad sector somewhere else.&lt;br /&gt;I've followed the instructions here:  &lt;a href="http://smartmontools.sourceforge.net/BadBlockHowTo.txt"&gt; BadBlockHowTo.txt&lt;/a&gt;, almost to the letter (I did some additional work removing the disk from RAID), and now the disk looks better.&lt;br /&gt;&lt;br /&gt;I still have to replace it, since a bad block is likely to be followed by others but it's somewhat reassuring to know that smartmontools &lt;i&gt;is&lt;/i&gt; smart enough to help.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-1208310450273517692?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/1208310450273517692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=1208310450273517692' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1208310450273517692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1208310450273517692'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/09/failing-disk-and-first-time-i-see-smart.html' title='A failing disk and the first time I see S.M.A.R.T. actually working'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-9161581437845100379</id><published>2008-09-15T17:27:00.002+03:00</published><updated>2008-09-15T17:31:32.281+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='loudhush'/><category scheme='http://www.blogger.com/atom/ns#' term='demo'/><category scheme='http://www.blogger.com/atom/ns#' term='screencast'/><title type='text'>Demo screencast: configuring an IAX account with LoudHush</title><content type='html'>&lt;object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="437" height="315" id="viddler_94cb3597"&gt;&lt;param name="movie" value="http://www.viddler.com/player/94cb3597/" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;embed src="http://www.viddler.com/player/94cb3597/" width="437" height="315" type="application/x-shockwave-flash" allowScriptAccess="always" allowFullScreen="true" name="viddler_94cb3597" &gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-9161581437845100379?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/9161581437845100379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=9161581437845100379' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/9161581437845100379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/9161581437845100379'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/09/demo-screencast-configuring-iax-account.html' title='Demo screencast: configuring an IAX account with LoudHush'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-2520903406053757061</id><published>2008-09-15T16:25:00.004+03:00</published><updated>2008-09-16T15:22:37.526+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='loudhush'/><category scheme='http://www.blogger.com/atom/ns#' term='text to speech'/><title type='text'>Text to speech in LoudHush</title><content type='html'>I've included a text to speech translator with the current development version of LoudHush. The feature will requires Leopard, otherwise the menu item leading to the text to speech window will remain disabled.&lt;br /&gt;&lt;br /&gt;It's using the default voice as selected in the system preferences - i.e. the Alex voice on Leopard.&lt;br /&gt;&lt;br /&gt;At this point I'm not sure about real use cases behind this feature so if you're willing to try a beta version please leave a comment or contact us at &lt;i&gt;info at loudhush dot ro&lt;/i&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-2520903406053757061?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/2520903406053757061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=2520903406053757061' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/2520903406053757061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/2520903406053757061'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/09/text-to-speech-in-loudhush.html' title='Text to speech in LoudHush'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-7486148444767899809</id><published>2008-09-08T17:48:00.002+03:00</published><updated>2008-09-08T18:04:55.097+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='foodbrowser'/><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><title type='text'>FoodBrowser released as beta</title><content type='html'>I didn't find the time to work on &lt;a href="http://foodbrowser.dv8.ro/"&gt;FoodBrowser&lt;/a&gt; lately so I've decided to go ahead and release it as beta.&lt;br /&gt;&lt;br /&gt;I've started writing it out of sheer frustration over the lack of a native OS X application that counts calories in various foods. Found a bunch, hated them. I've hated them because they record data in proprietary formats, locking data analysis into their own GUIs. Core Data is nice because you can always get to the data using sqlite.&lt;br /&gt;&lt;br /&gt;So did my attempt fare any better?&lt;br /&gt;Well, no. FoodBrowser is the point where most of my Cocoa projects get - usable but screaming "the devil is in the details". The devil &lt;i&gt;is&lt;/i&gt; in the details and details take time and patience, none of which are cheap.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-7486148444767899809?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/7486148444767899809/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=7486148444767899809' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7486148444767899809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7486148444767899809'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/09/foodbrowser-released-as-beta.html' title='FoodBrowser released as beta'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-6917782734464746503</id><published>2008-08-29T13:29:00.003+03:00</published><updated>2008-08-29T13:39:53.915+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='bucharest'/><category scheme='http://www.blogger.com/atom/ns#' term='gis'/><title type='text'>OpenStreetMap</title><content type='html'>&lt;a href="http://www.openstreetmap.org/"&gt;www.openstreetmap.org&lt;/a&gt; provides one of the first decent maps of Bucharest. It's based on community work, just like Wikipedia and their progress is unbelievable. Two years ago Bucharest had just one street on the map and now it looks almost completely mapped.&lt;br /&gt;&lt;br /&gt;If you're thinking of participating, Merkaartor is probably the best way to edit maps on Leopard. It's based on QT and a bit quirky but it's fast and very much usable. &lt;br /&gt;&lt;br /&gt;&lt;iframe width="425" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://www.openstreetmap.org/export/embed.html?bbox=26.1052,44.4296,26.1572,44.469&amp;layer=osmarender" style="border: 1px solid black"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;small&gt;&lt;a href="http://www.openstreetmap.org/?lat=44.4493&amp;lon=26.1312&amp;zoom=13&amp;layers=0B0FTFT"&gt;View Larger Map&lt;/a&gt;&lt;/small&gt;&lt;br /&gt;&lt;br /&gt;See also &lt;a href="http://www.informationfreeway.org/"&gt;www.informationfreeway.org&lt;/a&gt;, an online result of openstreemap's effort.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-6917782734464746503?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/6917782734464746503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=6917782734464746503' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6917782734464746503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6917782734464746503'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/08/openstreetmap.html' title='OpenStreetMap'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-6562814945901729849</id><published>2008-08-29T13:25:00.003+03:00</published><updated>2009-04-28T14:47:47.308+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GMP'/><category scheme='http://www.blogger.com/atom/ns#' term='kb'/><title type='text'>libGMP</title><content type='html'>&lt;blockquote&gt;&lt;a href="http://gmplib.org/"&gt;GMP&lt;/a&gt; is a free library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating point numbers. There is no practical limit to the precision except the ones implied by the available memory in the machine GMP runs on. GMP has a rich set of functions, and the functions have a regular interface.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Another definition:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cristi:demos diciu$ date; ./primes 100000000 | tail ;date&lt;br /&gt;Fri Aug 29 13:24:&lt;b&gt;22&lt;/b&gt; EEST 2008&lt;br /&gt;99999787&lt;br /&gt;99999821&lt;br /&gt;99999827&lt;br /&gt;99999839&lt;br /&gt;99999847&lt;br /&gt;99999931&lt;br /&gt;99999941&lt;br /&gt;99999959&lt;br /&gt;99999971&lt;br /&gt;99999989&lt;br /&gt;Fri Aug 29 13:24:&lt;b&gt;23&lt;/b&gt; EEST 2008&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/31740253-6562814945901729849?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/6562814945901729849/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=6562814945901729849' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6562814945901729849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6562814945901729849'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/08/libgmp.html' title='libGMP'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-7660532812002571048</id><published>2008-07-04T14:46:00.001+03:00</published><updated>2008-07-04T14:48:34.281+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='proxy'/><title type='text'>Ratproxy</title><content type='html'>Google's open source &lt;a href="http://code.google.com/p/ratproxy/wiki/RatproxyDoc"&gt;ratproxy&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A semi-automated, largely passive web application security audit tool, optimized for an accurate and sensitive detection, and automatic annotation, of potential problems and security-relevant design patterns based on the observation of existing, user-initiated traffic in complex web 2.0 environments.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-7660532812002571048?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/7660532812002571048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=7660532812002571048' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7660532812002571048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/7660532812002571048'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/07/ratproxy.html' title='Ratproxy'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-2468970605598361361</id><published>2008-07-01T12:46:00.004+03:00</published><updated>2008-07-01T12:47:51.550+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='kb'/><category scheme='http://www.blogger.com/atom/ns#' term='sqlite'/><title type='text'>timestamp to human readable string in sqlite3</title><content type='html'>&lt;blockquote&gt;&lt;br /&gt;sqlite&amp;gt; SELECT datetime(ZTIME, 'unixepoch',  '+31 years') from zfooditem;&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-2468970605598361361?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/2468970605598361361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=2468970605598361361' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/2468970605598361361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/2468970605598361361'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/07/timestamp-to-human-readable-string-in.html' title='timestamp to human readable string in sqlite3'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-3397603460980008628</id><published>2008-06-13T10:35:00.004+03:00</published><updated>2008-06-16T12:20:49.363+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='divert sockets'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='tee'/><title type='text'>Using divert sockets to log HTTP requests</title><content type='html'>One of the cool things about divert sockets is they allow you to spy on local traffic with virtually zero overhead. You don't have to worry about re-forwarding the traffic to the intended recipient port, re-setting headers inside the TCP packet, etc.&lt;br /&gt;Using divert tees you can just get a copy of the traffic matching a given rule, free for you to use in any way without interfering with the regular traffic.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cristi:~ diciu$ sudo ipfw add tee 8080 tcp from 193.231.199.80 to any 80 &lt;br /&gt;00100 tee 8080 tcp from 193.231.199.80 to any dst-port 80&lt;br /&gt;cristi:~ diciu$ sudo ipfw list&lt;br /&gt;00100 tee 8080 tcp from 193.231.199.80 to any dst-port 80&lt;br /&gt;65535 allow ip from any to any&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The ipfw rule we are using is "tee" - the concept is similar to the Unix tee in that we get a copy of the traffic matched by the rule. Once we've set up a divert tee, we need a divert socket reader.&lt;br /&gt;The protocol type for the divert socket is defined in netinet/in.h:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/usr/include/netinet/in.h:&lt;br /&gt;#define IPPROTO_DIVERT  254  /* divert pseudo-protocol */&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The code below binds a divert sockets and looks for HTTP GET and POST requests inside the content received from the socket:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import socket&lt;br /&gt;import select&lt;br /&gt;import re&lt;br /&gt;&lt;br /&gt;IPPROTO_DIVERT = 254&lt;br /&gt;&lt;br /&gt;sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, IPPROTO_DIVERT)&lt;br /&gt;fd = sock.bind(('127.0.0.1', 8080))&lt;br /&gt;sock.setblocking(True)&lt;br /&gt;&lt;br /&gt;MSGLEN = 32768&lt;br /&gt;&lt;br /&gt;while(1):&lt;br /&gt; msg = ''&lt;br /&gt; while len(msg) &lt; MSGLEN:&lt;br /&gt;  chunk = sock.recv(MSGLEN-len(msg))&lt;br /&gt;  if chunk == '':&lt;br /&gt;   raise RuntimeError, "Socket gone"&lt;br /&gt;  msg = msg + chunk&lt;br /&gt;&lt;br /&gt;  t = re.compile(r"(?P&lt;int&gt;(.*)(GET|POST)(.*)(HTTP/\d+\.\d+)(.*)(Host: )([a-zA-Z\.0-9-]*)(.*))", re.DOTALL)&lt;br /&gt;  m = t.match(msg)&lt;br /&gt;  if m:&lt;br /&gt;   print m.group(3) + " " + m.group(4) + " " + m.group(5) + " " + m.group(8)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;to run the code, you need to run python as root, because otherwise you'll get a permission denied when trying to create a RAW socket:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo python divert.py&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Once you're done, you need to delete the &lt;i&gt;divert tee&lt;/i&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo ipfw delete 100&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/31740253-3397603460980008628?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/3397603460980008628/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=3397603460980008628' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3397603460980008628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3397603460980008628'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/06/using-divert-sockets-to-log-http.html' title='Using divert sockets to log HTTP requests'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-875087242374770489</id><published>2008-06-02T15:33:00.005+03:00</published><updated>2008-06-02T16:30:06.766+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cisco'/><category scheme='http://www.blogger.com/atom/ns#' term='dns'/><category scheme='http://www.blogger.com/atom/ns#' term='leopard'/><category scheme='http://www.blogger.com/atom/ns#' term='vpn'/><title type='text'>Configuring Cisco VPN for local DNS connections on Leopard</title><content type='html'>1/ Connect CISCO VPN client - it will overwrite DNS settings in /etc/resolv.conf with whatever is read from the network the VPN is connecting to.&lt;br /&gt;&lt;br /&gt;If you're unlucky at this point normal DNS queries will no longer work.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2/ Use scutil to add a local DNS server:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;diciu$ sudo scutil&lt;br /&gt;&gt; get State:/Network/Service/com.cisco.VPN/DNS&lt;br /&gt;&lt;br /&gt;&gt; d.show&lt;br /&gt;&lt;dictionary&gt; {&lt;br /&gt;  ServerAddresses : &lt;array&gt; {&lt;br /&gt;    0 : 10.10.10.1&lt;br /&gt;    1 : 10.10.10.2&lt;br /&gt;  }&lt;br /&gt;  DomainName : somedomain.com&lt;br /&gt;  SearchDomains : &lt;array&gt; {&lt;br /&gt;    0 : somedomain.com&lt;br /&gt;    1 : modulo.ro&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&gt; d.add ServerAddresses * 193.231.199.1&lt;br /&gt;&gt; set State:/Network/Service/com.cisco.VPN/DNS&lt;br /&gt;&gt; d.show&lt;br /&gt;&lt;dictionary&gt; {&lt;br /&gt;  ServerAddresses : &lt;array&gt; {&lt;br /&gt;    0 : 193.231.199.1&lt;br /&gt;  }&lt;br /&gt;  DomainName : somedomain.com&lt;br /&gt;  SearchDomains : &lt;array&gt; {&lt;br /&gt;    0 : somedomain.com&lt;br /&gt;    1 : modulo.ro&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Single line command:&lt;br /&gt;&lt;br /&gt;&lt;quote&gt;&lt;br /&gt;printf "get State:/Network/Service/com.cisco.VPN/DNS\nd.add ServerAddresses * 193.231.199.1\nset State:/Network/Service/com.cisco.VPN/DNS" | sudo scutil&lt;br /&gt;&lt;/quote&gt;&lt;br /&gt;&lt;br /&gt;References: &lt;a href="http://www.afp548.com/article.php?story=20050703052052393"&gt;Using scutil to set DNS server&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-875087242374770489?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/875087242374770489/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=875087242374770489' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/875087242374770489'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/875087242374770489'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/06/configuring-cisco-vpn-for-local-dns.html' title='Configuring Cisco VPN for local DNS connections on Leopard'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-8204806630280387563</id><published>2008-05-26T13:39:00.006+03:00</published><updated>2009-04-28T14:38:42.993+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><title type='text'>How to tell how many documents are being opened in a multi document application</title><content type='html'>If you've subclassed NSDocumentController, when the user opens multiple documents, the method&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;- (id)openDocumentWithContentsOfURL:(NSURL *)absoluteURL display:(BOOL)displayDocument error:(NSError **)outError&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;will be called once per each document.&lt;br /&gt;&lt;br /&gt;If you need to figure out how many documents are being opened (you might to do something after the last document that is part of a batch has been opened), you need to do a couple of things.&lt;br /&gt;&lt;br /&gt;For documents opened via the open panel, things are easy:&lt;br /&gt;In your NSDocumentController subclass, override the implementation for URLsFromRunningOpenPanel:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;- (NSArray *)URLsFromRunningOpenPanel&lt;br /&gt;{&lt;br /&gt;    NSArray * a = [super URLsFromRunningOpenPanel];&lt;br /&gt;    documentsPendingOpen = [a count];&lt;br /&gt; &lt;br /&gt;    return a;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For documents being opened through Applescript events (such as documents dropped over the application icon), this is my not very elegant but efficient solution:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;- (id)openDocumentWithContentsOfURL:(NSURL *)absoluteURL display:(BOOL)displayDocument error:(NSError **)outError&lt;br /&gt;{&lt;br /&gt; NSAppleEventDescriptor * aed = [[[NSAppleEventManager sharedAppleEventManager]&lt;br /&gt;        currentAppleEvent]&lt;br /&gt;        paramDescriptorForKeyword:keyDirectObject];&lt;br /&gt; if(aed != nil &amp;&amp; cachedAppleEventDescriptor != nil &amp;&amp; ![[aed data] isEqualToData:[cachedAppleEventDescriptor data]])&lt;br /&gt; {&lt;br /&gt;    cachedAppleEventDescriptor = aed;&lt;br /&gt;    documentsPendingOpen = [aed numberOfItems];&lt;br /&gt; }&lt;br /&gt;[..]&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/31740253-8204806630280387563?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/8204806630280387563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=8204806630280387563' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8204806630280387563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8204806630280387563'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/05/how-to-tell-how-many-documents-are.html' title='How to tell how many documents are being opened in a multi document application'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-3818064802461388640</id><published>2008-05-25T09:28:00.004+03:00</published><updated>2008-06-04T16:35:30.866+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><title type='text'>XML command line tools in Mac OS X (1)</title><content type='html'>&lt;strong&gt;xmllint&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;xmllint is a parser for XML files that allows you to check for the well-formed state of the input.&lt;br /&gt;&lt;br /&gt;xmllint can re-format the output, taking one long line of unreadable input and indenting it in a more readable form:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;diciu$ cat test.xml &lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;a&amp;gt; &amp;lt;m&amp;gt; &amp;lt;p&amp;gt;one, two, three&amp;lt;/p&amp;gt; &amp;lt;/m&amp;gt; &amp;lt;m&amp;gt; &amp;lt;p&amp;gt;three, four&amp;lt;/p&amp;gt; &amp;lt;/m&amp;gt; &amp;lt;m&amp;gt; &amp;lt;p&amp;gt;five&amp;lt;/p&amp;gt; &amp;lt;/m&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;&lt;br /&gt;cristi:~ diciu$ xmllint --format test.xml &lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;a&amp;gt;&lt;br /&gt;  &amp;lt;m&amp;gt;&lt;br /&gt;    &amp;lt;p&amp;gt;one, two, three&amp;lt;/p&amp;gt;&lt;br /&gt;  &amp;lt;/m&amp;gt;&lt;br /&gt;  &amp;lt;m&amp;gt;&lt;br /&gt;    &amp;lt;p&amp;gt;three, four&amp;lt;/p&amp;gt;&lt;br /&gt;  &amp;lt;/m&amp;gt;&lt;br /&gt;  &amp;lt;m&amp;gt;&lt;br /&gt;    &amp;lt;p&amp;gt;five&amp;lt;/p&amp;gt;&lt;br /&gt;  &amp;lt;/m&amp;gt;&lt;br /&gt;&amp;lt;/a&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In the Leopard versions, xmlllint and most of the other XML tools have a built in &lt;a href="http://www.w3.org/TR/xpath"&gt;XPath&lt;/a&gt; browser implemented through a shell, allowing you to browse an XML's file hierarchy of nodes just like you would browse a filesystem:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;diciu$ cat test.xml &lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;a&amp;gt;&lt;br /&gt;&amp;lt;m&amp;gt;&lt;br /&gt; &amp;lt;p&amp;gt;one, two, three&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/m&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;m&amp;gt;&lt;br /&gt; &amp;lt;p&amp;gt;three, four&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/m&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;m&amp;gt;&lt;br /&gt; &amp;lt;p&amp;gt;five&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/m&amp;gt;&lt;br /&gt;&amp;lt;/a&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;The built in commands (viewable with the &lt;i&gt;help&lt;/i&gt; command), include &lt;i&gt;cat, cd, ls, pwd&lt;/i&gt; that work in similar ways to their Unix cousins:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;diciu$ xmllint --shell test.xml &lt;br /&gt;/ &gt; cat a&lt;br /&gt; -------&lt;br /&gt;&amp;lt;a&amp;gt;&lt;br /&gt;&amp;lt;m&amp;gt;&lt;br /&gt; &amp;lt;p&amp;gt;one, two, three&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/m&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;m&amp;gt;&lt;br /&gt; &amp;lt;p&amp;gt;three, four&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/m&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;m&amp;gt;&lt;br /&gt; &amp;lt;p&amp;gt;five&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/m&amp;gt;&lt;br /&gt;&amp;lt;/a&amp;gt;&lt;br /&gt;/ &amp;gt; cd a&lt;br /&gt;a &amp;gt; pwd&lt;br /&gt;/a&lt;br /&gt;a &amp;gt; cd m[position()=1]&lt;br /&gt;m &amp;gt; pwd&lt;br /&gt;/a/m[1]&lt;br /&gt;m &amp;gt; ls&lt;br /&gt;t--        2   &lt;br /&gt;---        1 p&lt;br /&gt;t--        1  &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/31740253-3818064802461388640?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/3818064802461388640/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=3818064802461388640' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3818064802461388640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3818064802461388640'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/05/xml-command-line-tools-in-mac-os-x-1.html' title='XML command line tools in Mac OS X (1)'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-6469729793449221823</id><published>2008-05-19T18:03:00.007+03:00</published><updated>2008-07-01T12:48:27.736+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kb'/><category scheme='http://www.blogger.com/atom/ns#' term='firewall'/><category scheme='http://www.blogger.com/atom/ns#' term='ipfw'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Testing your product's resilience to network errors</title><content type='html'>&lt;i&gt;Sometimes it's useful to test your product in adverse network conditions. Networking is a very complex layer and it's fortunate that the popularity of TCP throughout the last decade shields us from the implementation that has been moved within the kernel code.&lt;br /&gt;Many bugs in applications using networking are obscured by the developer's use of a fast network - he may use the product on a daily basis and still not hit certain conditions that are only met in conjunction with using the product on a slow network.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;If your product has auto-update functionality, there's some code that will try to query the home server for a new version. This usually occurs over HTTP (that's how &lt;a href="http://sparkle.andymatuschak.org/"&gt;Sparkle&lt;/a&gt; does it).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Have you ever wondered how your product's auto-update code behaves when there's a 10 second delay on the network?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The IP firewall running on your Leopard box makes it very easy to find out.&lt;br /&gt;Here's how you create a 10 second delay for your HTTP traffic towards a given host:&lt;br /&gt;&lt;br /&gt;First we configure a pipe that delays packets by 10000 milliseconds:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo ipfw pipe 1 config noerror delay 10000&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then we redirect the traffic we want to delay through that given pipe:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo ipfw add prob 1 pipe 1 tcp from any to www.home.com http&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Listing the rules from the IP firewalls shows the new rule we've just added:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cristi:~ diciu$ sudo ipfw list&lt;br /&gt;Password:&lt;br /&gt;00100 pipe 1 tcp from any to 192.168.1.1 dst-port 80&lt;br /&gt;65535 allow ip from any to any&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Testing with network delays&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Once you've configured the firewall, you can test your product. As a side note, the auto-update from Sparkle behaves admirably - it will run the query in the background so the 10 second delay is not experienced within the application.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Resetting the delay rule&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;To clear the ipfw rules once you're done testing:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cristi:~ diciu$ sudo ipfw flush&lt;br /&gt;Are you sure? [yn] y&lt;br /&gt;&lt;br /&gt;Flushed all rules.&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/31740253-6469729793449221823?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/6469729793449221823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=6469729793449221823' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6469729793449221823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/6469729793449221823'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/05/testing-your-products-resilience-to.html' title='Testing your product&apos;s resilience to network errors'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-8450786837477443860</id><published>2008-04-30T09:20:00.005+03:00</published><updated>2009-04-28T14:46:41.017+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='frameaway 3.0'/><title type='text'>FrameAway 3.0</title><content type='html'>A preview on how FrameAway version 3.0 looks at this point:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_rXrjDFwt37w/SBgUTpAk8CI/AAAAAAAAA9g/nZ-wSjvSyys/s1600-h/Picture+2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_rXrjDFwt37w/SBgUTpAk8CI/AAAAAAAAA9g/nZ-wSjvSyys/s320/Picture+2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5194924497830211618" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-8450786837477443860?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/8450786837477443860/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=8450786837477443860' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8450786837477443860'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8450786837477443860'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/04/frameaway-30.html' title='FrameAway 3.0'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_rXrjDFwt37w/SBgUTpAk8CI/AAAAAAAAA9g/nZ-wSjvSyys/s72-c/Picture+2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-8750639779857658065</id><published>2008-04-23T09:11:00.003+03:00</published><updated>2008-05-08T18:05:50.266+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='loudhush'/><title type='text'>LoudHush weird message when auto updating?</title><content type='html'>If you're seeing a message such as the one below when auto-updating LoudHush, the most likely cause is that you have renamed the LoudHush application.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;The update archive didn't contain an application with the name I was expecting (/var/tmp/tmp.0.xz9xho/LoudHush 2.app). Remember, the updated app's file name must be identical to the running app's filename!&lt;br /&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-8750639779857658065?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/8750639779857658065/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=8750639779857658065' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8750639779857658065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8750639779857658065'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/04/loudhush-weird-message-when-auto.html' title='LoudHush weird message when auto updating?'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-1195884758087751387</id><published>2008-04-16T15:03:00.004+03:00</published><updated>2009-04-28T14:44:40.244+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ppp'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='leopard'/><title type='text'>UDP traffic over 3G modem cut after 2 minutes?</title><content type='html'>On Leopard 10.5.2, UDP traffic over the Vodafone 3G Modem is cut after 2-3 minutes.&lt;br /&gt;I'm not sure what's to blame, symptoms are &lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;ping showing a message I've never seen before &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;some-macbook-pro:~ u$ ping 192.168.1.1&lt;br /&gt;PING 192.168.1.1 (192.168.1.1): 56 data bytes&lt;br /&gt;ping: sendto: No buffer space available&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;and a message in the system.log&lt;/li&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;dlil_output: output error retval = 37&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;The solution that works in my case is to stop the Cisco VPN client:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo SystemStarter stop CiscoVPN&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And this is &lt;a href="http://discussions.apple.com/thread.jspa?messageID=6936393"&gt;the thread over at Apple Discussions &lt;/a&gt; that discusses the problem and possible solutions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-1195884758087751387?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/1195884758087751387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=1195884758087751387' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1195884758087751387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1195884758087751387'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/04/udp-traffic-over-3g-modem-cut-after-2.html' title='UDP traffic over 3G modem cut after 2 minutes?'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5029400479985640177</id><published>2008-04-10T10:22:00.002+03:00</published><updated>2008-04-10T10:47:38.276+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='macbook'/><title type='text'>MacBook's life expectancy decreasing steadily</title><content type='html'>Google shows 91 results when searching for "disk0s2: 0xe0030005 (UNDEFINED)"&lt;br /&gt;&lt;br /&gt;Make this the 92nd:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Apr 10 09:05:15 cristi kernel[0]: disk0s2: 0xe0030005 (UNDEFINED).&lt;br /&gt;Apr 10 09:05:15 cristi kernel[0]:&lt;br /&gt;Apr 10 09:05:24: --- last message repeated 1 time ---&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/31740253-5029400479985640177?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5029400479985640177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5029400479985640177' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5029400479985640177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5029400479985640177'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/04/macbooks-life-expectancy-decreasing.html' title='MacBook&apos;s life expectancy decreasing steadily'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-8895265664646016959</id><published>2008-04-01T18:31:00.006+03:00</published><updated>2008-07-01T12:48:46.633+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kb'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>cgdisplayfade</title><content type='html'>The code snippet below fades the display to a solid blue color and back&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cd:~ diciu$ cat testfade.c &lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;ApplicationServices/ApplicationServices.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; fprintf(stdout, "Fading to blue...\n");&lt;br /&gt;&lt;br /&gt; CGDisplayFadeReservationToken token;&lt;br /&gt; CGError err = CGAcquireDisplayFadeReservation(10, &amp;token);&lt;br /&gt; CGDisplayFade(token, 2.0, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, .1, .3, 1.0, true);&lt;br /&gt; CGDisplayFade(token, 2.0, kCGDisplayBlendSolidColor,kCGDisplayBlendNormal, .1, .3, 1.0, true);&lt;br /&gt; err = CGReleaseDisplayFadeReservation(token);&lt;br /&gt;}&lt;br /&gt;cd:~ diciu$gcc  -framework ApplicationServices testfade.c&lt;br /&gt;cd:~ diciu$ ./a.out &lt;br /&gt;Fading to blue...&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/31740253-8895265664646016959?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/8895265664646016959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=8895265664646016959' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8895265664646016959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/8895265664646016959'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/04/cgdisplayfade.html' title='cgdisplayfade'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-3394099577712542397</id><published>2008-03-31T13:02:00.012+03:00</published><updated>2008-12-09T14:25:23.056+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='core image'/><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='frameaway 3.0'/><title type='text'>Core Image filter for overexposed areas</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rXrjDFwt37w/R_C8_7UGLmI/AAAAAAAAA8Q/6TcZYOH2k6A/s1600-h/tulip_overexposed.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_rXrjDFwt37w/R_C8_7UGLmI/AAAAAAAAA8Q/6TcZYOH2k6A/s320/tulip_overexposed.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5183850977543204450" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Because cameras are not as smart as they should be when it comes to dynamic range, neither from a hardware nor software standpoint, and mostly because I'm not very good at using my camera, I sometimes get overexposed areas in my photos. An overexposed area is an area where pixels are all-white (i.e. lit up all the way). If the overexposed area is large enough, the photo gets an unpleasant "burned" look.&lt;br /&gt;&lt;br /&gt;In our sample photo on the left side, the overexposed area is caused by the camera facing the light source - a common reason for overexposures as the camera's software computed the exposure based on the tulip's shaded side.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can detect overexposed areas in a number of ways - on my Nikon D70 there's a &lt;i&gt;highlights&lt;/i&gt; mode that blinks overexposed areas and there's a histogram on the green channel - the histogram less reliable because it does not show the red and blue channels as well so a relatively big value in the right hand side of the histogram might not necessarily mean an area has been overexposed.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rXrjDFwt37w/R_C777UGLlI/AAAAAAAAA8I/IRW59hNmQao/s1600-h/histogram.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_rXrjDFwt37w/R_C777UGLlI/AAAAAAAAA8I/IRW59hNmQao/s320/histogram.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5183849809312099922" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Overexposed ares show up in the photo's histogram (see below for a RGB histogram - the white bar on the right side represents overexposed pixels - nearly 10% of all the photo's pixels have been overexposed).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Using Core Image filters, overexposed areas are very easy to identify.&lt;br /&gt;With Core Image, using a histogram doesn't make sense - building a histogram is a computationally intensive task because it requires going through large amounts of data (a 6MB photo has, yes, 6MB of data) - it's better to write a filter that highlights the areas that have been overexposed.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here's my (possibly naive) solution:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;kernel vec4 replaceOverExposed(sampler image, __color color)&lt;br /&gt;{&lt;br /&gt; vec4 p = sample(image, samplerCoord(image));&lt;br /&gt; float multiplier = 1;&lt;br /&gt; &lt;br /&gt; float level = (p.r + p.g + p.b) / 3.0;&lt;br /&gt; &lt;br /&gt; vec4 res;&lt;br /&gt; res.r = level &gt; .99 ? 1.0 : p.r;&lt;br /&gt; res.g = level &gt; .99 ? 0.0 : p.g;&lt;br /&gt; res.b = level &gt; .99 ? 0.0 : p.b;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; return vec4(res.r, res.g, res.b, p.a);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Here's a rendering of the overexposed filter above applied on the tulip photo.&lt;br /&gt;The filter has replaced all the overexposed pixels with a red pixel (p.r 1.0, p.g 0.0 and p.b 0.0).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_rXrjDFwt37w/R_DDXrUGLnI/AAAAAAAAA8Y/Iu_SeCXgmVg/s1600-h/Picture+1.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_rXrjDFwt37w/R_DDXrUGLnI/AAAAAAAAA8Y/Iu_SeCXgmVg/s320/Picture+1.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5183857982634864242" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-3394099577712542397?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/3394099577712542397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=3394099577712542397' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3394099577712542397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/3394099577712542397'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/03/core-image-filter-for-overexposed-areas.html' title='Core Image filter for overexposed areas'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_rXrjDFwt37w/R_C8_7UGLmI/AAAAAAAAA8Q/6TcZYOH2k6A/s72-c/tulip_overexposed.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5788465214988403731</id><published>2008-03-28T08:31:00.004+02:00</published><updated>2008-03-28T08:39:59.557+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='loudhush'/><title type='text'>About LoudHush 1.3.15</title><content type='html'>We're run into an incompatibility issue with version 1.3.15 that caused it not to run on non-Leopard systems (10.4, 10.3).&lt;br /&gt;We have fixed this issue and are right now working to test the fixed version.&lt;br /&gt;&lt;br /&gt;In the meantime, we've pulled 1.3.15 from the site and from the auto-updater application cast.&lt;br /&gt;&lt;br /&gt;We will publish 1.3.16 with a correction for the problem as soon as possible.&lt;br /&gt;&lt;br /&gt;If you've end up with a non-functioning 1.3.15, please re-download the old version from the &lt;a href="http://www.loudhush.ro"&gt;http://www.loudhush.ro&lt;/a&gt; site.&lt;br /&gt;&lt;br /&gt;Sorry for the trouble.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-5788465214988403731?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5788465214988403731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5788465214988403731' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5788465214988403731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5788465214988403731'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/03/about-loudhush-1315.html' title='About LoudHush 1.3.15'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-2038972378137618765</id><published>2008-03-27T17:29:00.003+02:00</published><updated>2008-12-09T14:25:23.270+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='loudhush'/><title type='text'>New icon for LoudHush (1.3.15)</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_rXrjDFwt37w/R-u-PLUGLjI/AAAAAAAAA74/o2xc6lSh2CM/s1600-h/loudhush_new_icon.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_rXrjDFwt37w/R-u-PLUGLjI/AAAAAAAAA74/o2xc6lSh2CM/s320/loudhush_new_icon.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5182444964164283954" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The LoudHush icon has finally been updated to Leopard requirements (512x512).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-2038972378137618765?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/2038972378137618765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=2038972378137618765' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/2038972378137618765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/2038972378137618765'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/03/new-icon-for-loudhush-1315.html' title='New icon for LoudHush (1.3.15)'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_rXrjDFwt37w/R-u-PLUGLjI/AAAAAAAAA74/o2xc6lSh2CM/s72-c/loudhush_new_icon.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-5813455946457344335</id><published>2008-03-17T08:53:00.001+02:00</published><updated>2008-03-17T08:55:18.628+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='memento'/><title type='text'>Exif Orientation</title><content type='html'>&lt;b&gt;Orientation &lt;/b&gt;&lt;br /&gt;The image orientation viewed in terms of rows and columns.  &lt;br /&gt;Tag = 274 (112.H) &lt;br /&gt;Type = SHORT &lt;br /&gt;Count = 1 &lt;br /&gt;Default = 1 &lt;br /&gt;&lt;div style="margin-left: 30px"&gt;&lt;br /&gt;1 = The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side. &lt;br /&gt;2 = The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side. &lt;br /&gt;3 = The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side. &lt;br /&gt;4 = The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side. &lt;br /&gt;5 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual top. &lt;br /&gt;6 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual top. &lt;br /&gt;7 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual bottom. &lt;br /&gt;8 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual bottom. &lt;br /&gt;Other = reserved &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.exif.org/Exif2-2.PDF"&gt;Exif2.2 Spec&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-5813455946457344335?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/5813455946457344335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=5813455946457344335' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5813455946457344335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/5813455946457344335'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/03/exif-orientation.html' title='Exif Orientation'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-31740253.post-1037903636672984018</id><published>2008-03-03T12:11:00.003+02:00</published><updated>2008-07-01T12:49:15.451+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kb'/><category scheme='http://www.blogger.com/atom/ns#' term='mac os x'/><category scheme='http://www.blogger.com/atom/ns#' term='gdb'/><category scheme='http://www.blogger.com/atom/ns#' term='stack'/><title type='text'>Backtrace call in 10.5</title><content type='html'>&lt;b&gt;backtrace()&lt;/b&gt; writes the function return addresses of the current call stack to the array of pointers referenced by array.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/backtrace.3.html"&gt;man backtrace&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/31740253-1037903636672984018?l=blog.loudhush.ro' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.loudhush.ro/feeds/1037903636672984018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=31740253&amp;postID=1037903636672984018' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1037903636672984018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/31740253/posts/default/1037903636672984018'/><link rel='alternate' type='text/html' href='http://blog.loudhush.ro/2008/03/backtrace-call-in-105.html' title='Backtrace call in 10.5'/><author><name>diciu</name><uri>http://www.blogger.com/profile/05684542103324988243</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_rXrjDFwt37w/SpY398J2CdI/AAAAAAAACuA/8IZLQySB21Y/S220/me.jpg'/></author><thr:total>0</thr:total></entry></feed>
