changeset 0:50ea00cf5896

Initial commit
author Brendan Rius <brendan@omixy.com>
date Fri, 25 Mar 2016 11:50:40 +0000
parents
children 5618ac3a53f5
files .gitignore README.md c_kernel/__init__.py c_kernel/kernel.json c_kernel/kernel.py
diffstat 5 files changed, 86 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.gitignore	Fri Mar 25 11:50:40 2016 +0000
@@ -0,0 +1,5 @@
+__pycache__
+*.pyc
+build/
+dist/
+MANIFEST
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Fri Mar 25 11:50:40 2016 +0000
@@ -0,0 +1,18 @@
+# Minimal C kernel for Jupyter
+
+## Requirements
+
+* gcc
+* jupyter
+
+## Installation
+
+ * `git clone git@github.com:brendan-rius/jupyter-c-kernel.git`
+ * `cd jupyter-c-kernel`
+ * `jupyter-kernelspec install c_kernel`
+
+## Usage
+
+ * Create a new Jupyter notebook: `jupyter-notebook`
+ * Change the kernel to `C`
+ * Enjoy!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/c_kernel/__init__.py	Fri Mar 25 11:50:40 2016 +0000
@@ -0,0 +1,3 @@
+from ipykernel.kernelapp import IPKernelApp
+from .kernel import CKernel
+IPKernelApp.launch_instance(kernel_class=CKernel)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/c_kernel/kernel.json	Fri Mar 25 11:50:40 2016 +0000
@@ -0,0 +1,11 @@
+{
+  "argv": [
+    "python",
+    "-m",
+    "c_kernel",
+    "-f",
+    "{connection_file}"
+  ],
+  "display_name": "C",
+  "language":"c"
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/c_kernel/kernel.py	Fri Mar 25 11:50:40 2016 +0000
@@ -0,0 +1,49 @@
+from ipykernel.kernelbase import Kernel
+import subprocess
+import tempfile
+
+
+class CKernel(Kernel):
+    implementation = 'c_kernel'
+    implementation_version = '1.0'
+    language = 'c'
+    language_version = 'C11'
+    language_info = {'name': 'c', 'mimetype': 'text/plain', 'file_extension': 'c'}
+    _banner = None
+
+    @property
+    def banner(self):
+        if self._banner is None:
+            self._banner = subprocess.check_output(['gcc', '-v']).decode('utf-8')
+        return self._banner
+
+    def do_execute(self, code, silent, store_history=True,
+                   user_expressions=None, allow_stdin=False):
+        code = code.strip()
+        if not code:
+            return {'status': 'ok',
+                    'execution_count': self.execution_count,
+                    'payload': [],
+                    'user_expressions': {}}
+
+        output = '### COMPILATION ###\n'
+        try:
+            sourcefile = tempfile.NamedTemporaryFile(suffix='.c', delete=False)
+            sourcefile.write(code)
+            sourcefile.close()
+            binaryfile = tempfile.NamedTemporaryFile(suffix='.out', delete=False)
+            binaryfile.close()
+            output += subprocess.check_output(['gcc', '-std=c11', sourcefile.name, '-o', binaryfile.name],
+                                              stderr=subprocess.STDOUT).decode('utf-8')
+        except subprocess.CalledProcessError as e:
+            print(e)
+            return {'status': 'error', 'ename': 'Compilation error', 'evalue': e.output}
+
+        output += '\n### EXECUTION ###\n'
+        try:
+            output += subprocess.check_output([binaryfile.name], stderr=subprocess.STDOUT).decode('utf-8')
+        except subprocess.CalledProcessError as e:
+            output += e.output
+        if not silent:
+            stream_content = {'name': 'stdout', 'text': output}
+            self.send_response(self.iopub_socket, 'stream', stream_content)