changeset 56:161ad9354cbd

Merge pull request #21 from ericjperry/master Update install.sh to support using a different tag and repo committer: GitHub <noreply@github.com>
author Brendan Rius <brendan.rius@gmail.com>
date Fri, 09 Jun 2017 16:32:31 +0200
parents 4a03cede4763 (diff) 94feb0290715 (current diff)
children 308a0eaa4e49
files
diffstat 2 files changed, 35 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/jupyter_c_kernel/kernel.py	Wed Jan 18 11:27:00 2017 -0500
+++ b/jupyter_c_kernel/kernel.py	Fri Jun 09 16:32:31 2017 +0200
@@ -2,6 +2,7 @@
 from threading import Thread
 
 from ipykernel.kernelbase import Kernel
+import re
 import subprocess
 import tempfile
 import os
@@ -72,7 +73,7 @@
     language_version = 'C11'
     language_info = {'name': 'c',
                      'mimetype': 'text/plain',
-                     'file_extension': 'c'}
+                     'file_extension': '.c'}
     banner = "C kernel.\n" \
              "Uses gcc, compiles in C11, and creates source code files and executables in temporary folder.\n"
 
@@ -111,17 +112,42 @@
                                   lambda contents: self._write_to_stdout(contents.decode()),
                                   lambda contents: self._write_to_stderr(contents.decode()))
 
-    def compile_with_gcc(self, source_filename, binary_filename):
-        args = ['gcc', source_filename, '-std=c11', '-fPIC', '-shared', '-rdynamic', '-o', binary_filename]
+    def compile_with_gcc(self, source_filename, binary_filename, cflags=None, ldflags=None):
+        cflags = ['-std=c11', '-fPIC', '-shared', '-rdynamic'] + cflags
+        args = ['gcc', source_filename] + cflags + ['-o', binary_filename] + ldflags
         return self.create_jupyter_subprocess(args)
 
+    def _filter_magics(self, code):
+
+        magics = {'cflags': [],
+                  'ldflags': [],
+                  'args': []}
+
+        for line in code.splitlines():
+            if line.startswith('//%'):
+                key, value = line[3:].split(":", 2)
+                key = key.strip().lower()
+
+                if key in ['ldflags', 'cflags']:
+                    for flag in value.split():
+                        magics[key] += [flag]
+                elif key == "args":
+                    # Split arguments respecting quotes
+                    for argument in re.findall(r'(?:[^\s,"]|"(?:\\.|[^"])*")+', value):
+                        magics['args'] += [argument.strip('"')]
+
+        return magics
+
     def do_execute(self, code, silent, store_history=True,
                    user_expressions=None, allow_stdin=False):
+
+        magics = self._filter_magics(code)
+
         with self.new_temp_file(suffix='.c') as source_file:
             source_file.write(code)
             source_file.flush()
             with self.new_temp_file(suffix='.out') as binary_file:
-                p = self.compile_with_gcc(source_file.name, binary_file.name)
+                p = self.compile_with_gcc(source_file.name, binary_file.name, magics['cflags'], magics['ldflags'])
                 while p.poll() is None:
                     p.write_contents()
                 p.write_contents()
@@ -132,7 +158,7 @@
                     return {'status': 'ok', 'execution_count': self.execution_count, 'payload': [],
                             'user_expressions': {}}
 
-        p = self.create_jupyter_subprocess([self.master_path, binary_file.name])
+        p = self.create_jupyter_subprocess([self.master_path, binary_file.name] + magics['args'])
         while p.poll() is None:
             p.write_contents()
         p.write_contents()
--- a/resources/master.c	Wed Jan 18 11:27:00 2017 -0500
+++ b/resources/master.c	Fri Jun 09 16:32:31 2017 +0200
@@ -25,5 +25,7 @@
         fprintf(stderr, "%s: %s\n", argv[0], error);
         return EXIT_FAILURE;
     }
-    return usermain(argc, argv, envp);
-}
\ No newline at end of file
+
+    /* Call Users main, but make master.c invisible by removing first argument */
+    return usermain(argc-1, argv+1, envp);
+}