{"id":2003,"date":"2015-12-06T17:17:13","date_gmt":"2015-12-06T23:17:13","guid":{"rendered":"http:\/\/dev.iachieved.it\/iachievedit\/?p=2003"},"modified":"2015-12-23T21:17:10","modified_gmt":"2015-12-24T03:17:10","slug":"more-swift-on-linux","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/more-swift-on-linux\/","title":{"rendered":"More Swift on Linux"},"content":{"rendered":"<p><b>Editor&#8217;s Note:<\/b>  This article was written on December 6, 2015, days after Apple open-sourced Swift and made an Ubuntu distribution of the Swift compiler available.  All of the techniques used below should be forward compatible, however, there may be easier ways of doing things in the future as the Foundation classes are implemented.  Apple has posted a <a href=\"https:\/\/github.com\/apple\/swift-corelibs-foundation\/blob\/master\/Docs\/Status.md\">status page<\/a> that outlines what works and what doesn&#8217;t.<\/p>\n<h2>Using Glibc Routines with Swift<\/h2>\n<p>As I mentioned in <a href=\"http:\/\/dev.iachieved.it\/iachievedit\/swift-on-linux\/\">Swift on Linux!<\/a>, the Foundation classes that Objective-C and Swift developers have come to know and love are only partially implemented.  And by partially implemented I really mean hardly implemented.  Okay, <code>NSError<\/code> is there and a few others, but no <code>NSURL<\/code>, <code>NSURLSession<\/code>, etc.<\/p>\n<p>What <i>is<\/i> there is the wealth of routines from the <a href=\"http:\/\/www.gnu.org\/software\/libc\/\">GNU C Library<\/a>, also known as Glibc.  You know, the library of rotuines you&#8217;d look up with a man page.  Functions like <code>popen<\/code> and <code>fgets<\/code>, <code>getcwd<\/code> and <code>qsort<\/code>.  Swift won&#8217;t be displacing Python any time soon if this is all we&#8217;re left to work with, <i>but<\/i> you can do something useful and begin exploring the possibilities of intermixing C with Swift.  In this tutorial we&#8217;ll do exactly that and write up some Swift code that uses <code>popen<\/code> to spawn <code>wget<\/code> to make up for the lack of <code>NSURLSession<\/code>.<\/p>\n<p>So let&#8217;s get stuck in and write some Swift.<\/p>\n<h3>Swift cat<\/h3>\n<p>Create a file named <code>swiftcat.swift<\/code> and add the following code:<\/p>\n<pre class=\"lang:swift\">\r\nimport Glibc\r\n\r\nguard Process.arguments.count == 2 else {\r\n  print(\"Usage:  swiftcat FILENAME\")\r\n  exit(-1)\r\n}\r\n\r\nlet filename = Process.arguments[1]\r\n\r\nlet BUFSIZE = 1024\r\nvar pp      = popen(\"cat \" + filename, \"r\")\r\nvar buf     = [CChar](count:BUFSIZE, repeatedValue:CChar(0))\r\n\r\nwhile fgets(&buf, Int32(BUFSIZE), pp) != nil {\r\n  print(String.fromCString(buf)!, terminator:\"\")\r\n}\r\n\r\nexit(0)\r\n<\/pre>\n<p>To get access to all of the Glibc routines we use <code>import Glibc<\/code>.  Easy enough.  Swift 2 brought us the <code>guard<\/code> construct, so we&#8217;ll use that to ensure that we have an argument to our script.  Our first exposure to using a Glibc function is <code>exit(-1)<\/code>.  That&#8217;s right, nothing special about calling it, it is just the <a href=\"http:\/\/man7.org\/linux\/man-pages\/man3\/exit.3.html\"><code>void exit(int status)<\/code> function<\/a>.<\/p>\n<p>We&#8217;re going to cheat a bit and leverage the <code>\/bin\/cat<\/code> command to read the file and write to standard out.  To call it though we&#8217;ll use <code>popen<\/code> which will pipe us a stream of bytes that we can read with <code>fgets<\/code>.  There is one thing to notice here, and that is that Glibc routines which take <code>const char*<\/code> arguments can be given Swift <code>String<\/code>s directly.  Routines that take <code>char*<\/code>, as in the case of <code>fgets<\/code> require some finesse.<\/p>\n<p><code>fgets<\/code> <i>does<\/i> take a <code>char*<\/code>, so we cannot pass it a <code>String<\/code>, but rather will use a buffer allocated as a <code>[CChar]<\/code> (C char) array.  The array has a fixed size of 1024 and is initialized with zeroes.  Our <code>while<\/code> loop calls <code>fgets<\/code> with the stream pointer, and non-<code>nil<\/code> results contain a buffer from which we can create a Swift <code>String<\/code>.<\/p>\n<p>Go ahead and save this to a file called <code>swiftcat.swift<\/code> and then run it!  <\/p>\n<pre class=\"crayon:false\">\r\n# swift swiftcat.swift \r\nUsage:  swiftcat FILENAME\r\n<\/pre>\n<p>Pass it a file to get the equivalent of <code>cat<\/code> output!<\/p>\n<h3>Mixing in C<\/h3>\n<p>You aren&#8217;t limited to using Glibc routines with your Swift code.  Let&#8217;s say we want to use <code>libcurl<\/code> to escape some strings and get them ready to be included in a URL.  This is easy to do with libcurl.  <\/p>\n<p>In a file called <code>escapetext.c<\/code> put the following:<\/p>\n<pre class=\"lang:c\">\r\n#include <stdio.h>\r\n#include <string.h>\r\n#include <stdlib.h>\r\n#include <curl\/curl.h>\r\n\r\nint escapeText(const char* text, char** output) {\r\n\r\n  int rc = -1;\r\n  CURL* curl = curl_easy_init();\r\n  if (curl) {\r\n    char* escaped = curl_easy_escape(curl, text, strlen(text));\r\n    if (escaped) {\r\n      *output = (char*)malloc(strlen(escaped) + 1);\r\n      strcpy(*output, escaped);\r\n      curl_free(escaped);\r\n      rc = strlen(*output);\r\n    } \r\n  }\r\n  return rc;\r\n}\r\n\r\n#ifdef __TEST__\r\nint main(int argc, char** argv) {\r\n\r\n  if (argc < 2) {\r\n    printf(\"Usage:  escapetext STRING\\n\");\r\n    exit(-1);\r\n  }\r\n\r\n  char* text = argv[1];\r\n  char* escapedText;\r\n\r\n  int rc = 0;\r\n  if (escapeText(text, &#038;escapedText)) {\r\n    printf(\"Escaped text:  %s\\n\", escapedText);\r\n  } else {\r\n    printf(\"Error\\n\");\r\n    rc = -1;\r\n  }\r\n  free(escapedText);\r\n  exit(rc);\r\n\r\n}\r\n#endif\r\n<\/pre>\n<p>Make sure you have <code>libcurl<\/code> installed with <code>apt-get install -y libcurl4-gnutls-dev<\/code>.<\/p>\n<p>Now, compile the file with:<\/p>\n<pre class=\"crayon:false\">\r\nclang -D__TEST__ -o escapetext escapetext.c -lcurl\r\n<\/pre>\n<p>We include the <code>-D__TEST__<\/code> here to pick up the <code>main<\/code> function.  In a minute I'll show you how to take this routine and include it in a Swift application.  Run the C application:<\/p>\n<pre class=\"crayon:false\">\r\n# .\/escapetext \"hey there\\!\"\r\nEscaped text:  hey%20there%21\r\n<\/pre>\n<p>Easy enough.  Now, we want to write a Swift application that uses our C routine <code>escapeText<\/code>.  The first thing to do is compile an <code>escapetext.o<\/code> object file without the <code>-D__TEST__<\/code> flag set.  This will get rid of <code>main()<\/code>.<\/p>\n<pre class=\"crayon:false\">\r\nclang -c escapetext.c\r\n<\/pre>\n<p>Now, create a file called <code>escapetext.h<\/code> and put the function prototype in it.<\/p>\n<pre class=\"lang:c\">\r\nint escapeText(const char* text, char** output);\r\n<\/pre>\n<p>Write a new file called <code>escapeswift.swift<\/code> and add the following:<\/p>\n<pre class=\"lang:swift\">\r\nimport Foundation\r\nimport Glibc\r\n\r\nguard Process.arguments.count == 2 else {\r\n  print(\"Usage:  escapeswift STRING\")\r\n  exit(-1)\r\n}\r\n\r\nlet string = Process.arguments[1]\r\nvar output:UnsafeMutablePointer<Int8> = nil\r\n\r\nlet rc = escapeText(string, &output)\r\n\r\nguard rc > 0 else {\r\n  print(\"Error escaping text\")\r\n  exit(-1)\r\n}\r\n\r\nprint(\"Escaped text:  \\(String.fromCString(output)!)\")\r\nexit(0)\r\n<\/pre>\n<p>Compile this Swift code with:<\/p>\n<pre class=\"crayon:false\">\r\nswiftc -c escapeswift.swift -import-objc-header escapetext.h \r\n<\/pre>\n<p>Notice that we included <code>-import-objc-header escapetext.h<\/code>.  Without this header the Swift compiler won't be able to find the prototype for <code>escapeText<\/code> and will subsequently fail with <code>use of unresolved identifier<\/code>.<\/p>\n<p>Bringing it all together, we link our <code>escapeswift.o<\/code> and <code>escapetext.o<\/code> objects together, and pass in the Curl library.<\/p>\n<pre class=\"crayon:false\">\r\nswiftc escapeswift.o escapetext.o -o escapeswift -lcurl\r\n<\/pre>\n<p>And run it!<\/p>\n<pre class=\"crayon:false\">\r\n# .\/escapeswift \"how now brown cow\"\r\nEscaped text:  how%20now%20brown%20cow\r\n<\/pre>\n<h2>Translator Application<\/h2>\n<p>This is a more complex example, but the principals are the same as those outlined above.  We're going to mix C objects and Swift modules together to write a command line application that translates strings from one language to another.  <\/p>\n<p>The <a href=\"http:\/\/mymemory.translated.net\/doc\/spec.php\">REST API<\/a> we'll be using to do the actual translation returns results in JSON.  Since <code>NSJSONSerialization<\/code> isn't yet available in Foundation on Linux, we'll use the <code>libjson-c-dev<\/code> library, so install it with <code>apt-get install libjson-c-dev<\/code>.<\/p>\n<h3>jsonparse<\/h3>\n<p>Two files make up our JSON-parsing routine, <code>parsejson.c<\/code> and its companion header <code>parsejson.h<\/code>.<\/p>\n<p><code>parsejson.c<\/code>:<\/p>\n<pre class=\"lang:c\">\r\n#include <stdio.h>\r\n#include <json-c\/json.h>\r\n\r\nconst char* translatedText(const char* json) {\r\n\r\n  const char* c = NULL;\r\n  json_object* jobj         = json_tokener_parse(json);\r\n  json_object* responseData = json_object_object_get(jobj,\r\n\t\t\t\t\t\t     \"responseData\");\r\n  if (responseData) {\r\n    json_object* translatedTextObj= json_object_object_get(responseData,\r\n\t\t\t\t\t\t\t   \"translatedText\");\r\n    if (translatedTextObj) {\r\n      c = json_object_get_string(translatedTextObj);\r\n    }\r\n  }\r\n  return c;\r\n}\r\n<\/pre>\n<p><code>parsejson.h<\/code><\/p>\n<pre class=\"lang:c\">\r\nconst char* translatedText(const char* json);\r\n<\/pre>\n<p>We can easily compile this file with <code>clang -c jsonparse.c<\/code>.  <\/p>\n<h3>Translator module<\/h3>\n<p>The workhorse of the translator application will be a Swift module called <code>translator<\/code>.  To create this module and prepare it for inclusion with the rest of our project, start with the class file <code>translator.swift<\/code>:<\/p>\n<pre class=\"lang:swift\">\r\nimport Glibc\r\nimport Foundation\r\n\r\npublic class Translator {\r\n\r\n  let BUFSIZE = 1024\r\n\r\n  public init() {\r\n  }\r\n\r\n  public func translate(text:String, from:String, to:String,\r\n                        completion:(translation:String?, error:NSError?) -> Void) {\r\n\r\n    let curl = curl_easy_init()\r\n\r\n    guard curl != nil else {\r\n      completion(translation:nil,\r\n                 error:NSError(domain:\"translator\", code:1, userInfo:nil))\r\n      return\r\n    }\r\n\r\n    let escapedText = curl_easy_escape(curl, text, Int32(strlen(text)))\r\n\r\n    guard escapedText != nil else {\r\n      completion(translation:nil,\r\n                 error:NSError(domain:\"translator\", code:2, userInfo:nil))\r\n      return\r\n    }\r\n    \r\n    let langPair = from + \"%7c\" + to\r\n    let wgetCommand = \"wget -qO- http:\/\/api.mymemory.translated.net\/get\\\\?q\\\\=\" + String.fromCString(escapedText)! + \"\\\\&langpair\\\\=\" + langPair\r\n    \r\n    let pp      = popen(wgetCommand, \"r\")\r\n    var buf     = [CChar](count:BUFSIZE, repeatedValue:CChar(0))\r\n    \r\n    var response:String = \"\"\r\n    while fgets(&buf, Int32(BUFSIZE), pp) != nil {\r\n      response = response + String.fromCString(buf)!\r\n    }\r\n    \r\n    let translated = translatedText(response)\r\n\r\n    completion(translation:String.fromCString(translated)!,\r\n               error:nil)\r\n  }\r\n\r\n}\r\n<\/pre>\n<p>Take a moment to read through the code.  We're including direct calls to the Curl library here, as well as <code>popen<\/code> and <code>fgets<\/code>, <i>and<\/i> our <code>translatedText<\/code> routine that is compiled into an object file created by <code>clang<\/code>.<\/p>\n<p>In addition, create a <code>bridgingHeader.h<\/code> with the contents:<\/p>\n<pre>\r\n#include <curl\/curl.h>\r\n#include \"jsonparse.h\"\r\n<\/pre>\n<p>There are two steps to getting this ready to use in our application:<\/p>\n<ul>\n<li>Create a shared library with the translator routine\n<li>Create a <code>swiftmodule<\/code> that describes the interface\n<\/ul>\n<p>I will confess, I didn't understand this until I read on Stackoverflow:<\/p>\n<blockquote><p>The <code>.swiftmodule<\/code> describes the Swift module's interface but it does not contain the module's implementation. A library or set of object files is still required to link your application against.<\/p><\/blockquote>\n<p>First, compile the code into a <code>.o<\/code> and create a shared library:<\/p>\n<pre class=\"crayon:false\">\r\nswiftc -emit-library translator.swift -module-name translator -import-objc-header bridgingHeader.h\r\nclang -shared -o libtranslator.so translator.o\r\n<\/pre>\n<p>Now, create the module:<\/p>\n<pre class=\"crayon:false\">\r\nswiftc -emit-module -module-name translator translator.swift -import-objc-header bridgingHeader.h\r\n<\/pre>\n<p>This leaves us with three files:  <code>libtranslator.so<\/code>, <code>translator.swiftmodule<\/code>, and <code>translator.swiftdoc<\/code>.<\/p>\n<h3>Main Routine<\/h3>\n<p>Our main file, <code>main.swift<\/code> looks like this:<\/p>\n<pre class=\"lang:swift\">\r\nimport translator\r\nimport Foundation\r\nimport Glibc\r\n\r\nguard Process.arguments.count == 6 && \r\n      Process.arguments[2]    == \"from\" &&\r\n      Process.arguments[4]    == \"to\" else {\r\n  print(\"Usage:  translate STRING from LANG to LANG\")\r\n  exit(-1)\r\n}\r\n\r\nlet string     = Process.arguments[1]\r\nlet fromLang   = Process.arguments[3]\r\nlet toLang     = Process.arguments[5]\r\nlet translator = Translator()\r\n\r\ntranslator.translate(string, from:fromLang, to:toLang) {\r\n  (translation:String?, error:NSError?) -> Void in\r\n  guard error == nil && translation != nil else {\r\n    print(\"Error:  No translation available\")\r\n    exit(-1)\r\n  }\r\n\r\n  if let translatedText = translation {\r\n    print(\"Translation:  \" + translatedText)\r\n    exit(0)\r\n  }\r\n}\r\n<\/pre>\n<p>Again, we've made use of Foundation and Glibc, but we're also using <code>import translator<\/code>.  You must have a <code>translator.swiftmodule<\/code> in your module search path, which we add with <code>-I.<\/code>:<\/p>\n<pre class=\"crayon:false\">\r\nswiftc -I. -c main.swift -import-objc-header bridgingHeader.h\r\n<\/pre>\n<p>Let's link everything together:<\/p>\n<pre class=\"crayon:false\">\r\nswiftc -o translate.exe jsonparse.o main.o -L. -ltranslator -lcurl -ljson-c -lswiftGlibc -lFoundation\r\n<\/pre>\n<p>The resulting binary is <code>translate.exe<\/code> because we intend to wrap a helper script around it to set the <code>LD_LIBRARY_PATH<\/code> to find the <code>libtranslator.so<\/code> shared library.  Without the helper script (or using <code>ldconfig<\/code> to update the search path), you need to invoke the excecutable like this:<\/p>\n<pre class=\"crayon:false\">\r\nLD_LIBRARY_PATH=.:$LD_LIBRARY_PATH .\/translate.exe \"Hello world\\!\" from en to es\r\nTranslation:  \u00a1Hola, mundo!\r\n<\/pre>\n<p>Let's try Irish:<\/p>\n<pre class=\"crayon:false\">\r\nLD_LIBRARY_PATH=.:$LD_LIBRARY_PATH .\/translate.exe \"Hello world\\!\" from en to ga\r\nTranslation:  Dia duit\r\n<\/pre>\n<h3>Makefile<\/h3>\n<p>It's not clear how \"interpreter\" friendly Swift will become.  Yes, one can create a single monolithic Swift script right now and run it with <code>swift<\/code>.  In fact we did that above.  Using bits of code from other Swift files though, without specifying everything on the command line, remains, well, impossible.  Maybe I'm wrong and just haven't figured out the magic incantation to have Swift greedily open up files searching for code to run.  <\/p>\n<p>At any rate, our translator application above needs a little help to build.  There is a new Swift builder tool, but I found <code>make<\/code> could get the job done with some appropriate rules:<\/p>\n<pre>\r\nAPP=translate.exe\r\n\r\nall:\t$(APP)\r\n\r\n%.o:%.c\r\n\tclang -c $<\r\n\r\n%.o:%.swift\r\n\tswiftc -I. -c $< -import-objc-header bridgingHeader.h\r\n\r\n$(APP):\tlibtranslator.so translator.swiftmodule jsonparse.o main.o\r\n\tswiftc -o $(APP) jsonparse.o main.o -L. -ltranslator -lcurl -ljson-c -lswiftGlibc -lFoundation\r\n\r\nlibtranslator.so:\ttranslator.o\r\n\tswiftc -emit-library translator.swift -module-name translator -import-objc-header bridgingHeader.h\r\n\tclang -shared -o libtranslator.so translator.o\r\n\r\ntranslator.swiftmodule:\tlibtranslator.so\r\n\tswiftc -emit-module -module-name translator translator.swift -import-objc-header bridgingHeader.h\r\n\r\nclean:\r\n\trm -rf *.o *.swiftmodule *.swiftdoc *.so $(APP)\r\n<\/pre>\n<h2>Getting the Code<\/h2>\n<p>You can get all of the code above from Github.  <\/p>\n<pre class=\"crayon:false\">\r\ngit clone https:\/\/github.com\/iachievedit\/moreswift\r\n<\/pre>\n<p>The <code>swiftcat<\/code> code is meant to be run with the <code>swift<\/code> command, where as <code>escapetext<\/code> has a simple <code>build.sh<\/code> script, and <code>translate<\/code> has a full-on <code>Makefile<\/code>.<\/p>\n<p>If you've enjoyed this tutorial please follow us Twitter at @iachievedit!  There will be more to come as Swift on Linux matures.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Editor&#8217;s Note: This article was written on December 6, 2015, days after Apple open-sourced Swift and made an Ubuntu distribution of the Swift compiler available. All of the techniques used below should be forward compatible, however, there may be easier ways of doing things in the future as the Foundation classes are implemented. Apple has [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,19,5],"tags":[],"class_list":["post-2003","post","type-post","status-publish","format-standard","hentry","category-apple","category-linux","category-swift"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/2003"}],"collection":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/comments?post=2003"}],"version-history":[{"count":31,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/2003\/revisions"}],"predecessor-version":[{"id":2269,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/2003\/revisions\/2269"}],"wp:attachment":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media?parent=2003"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=2003"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=2003"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}