diff --git a/example-notebook.ipynb b/example-notebook.ipynb index dcd2844..95b78b5 100644 --- a/example-notebook.ipynb +++ b/example-notebook.ipynb @@ -10,9 +10,7 @@ { "cell_type": "code", "execution_count": 1, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stderr", @@ -32,6 +30,7 @@ "\n", "int main() {\n", " printf(\"Hello world\\n\");\n", + " return 0;\n", "}" ] }, @@ -52,9 +51,7 @@ { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stderr", @@ -98,9 +95,7 @@ { "cell_type": "code", "execution_count": 3, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stderr", @@ -142,14 +137,14 @@ "kernelspec": { "display_name": "C", "language": "c", - "name": "c_kernel" + "name": "c" }, "language_info": { - "file_extension": "c", + "file_extension": ".c", "mimetype": "text/plain", - "name": "c" + "name": "text/x-c++src" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } diff --git a/jupyter_c_kernel/kernel.py b/jupyter_c_kernel/kernel.py index 99243fc..6194234 100644 --- a/jupyter_c_kernel/kernel.py +++ b/jupyter_c_kernel/kernel.py @@ -71,7 +71,9 @@ class RealTimeSubprocess(subprocess.Popen): contents = contents.replace(self.__class__.inputRequest, '') if(len(contents) > 0): self._write_to_stdout(contents) - readLine = self._read_from_stdin() + readLine = "" + while(len(readLine) == 0): + readLine = self._read_from_stdin() # need to add newline since it is not captured by frontend readLine += "\n" self.stdin.write(readLine.encode()) @@ -104,6 +106,7 @@ class CKernel(Kernel): super(CKernel, self).__init__(*args, **kwargs) self._allow_stdin = True self.readOnlyFileSystem = False + self.linkMaths = True # always link math library self.wAll = True # show all warnings by default self.wError = False # but keep comipiling for warnings self.files = [] @@ -148,7 +151,12 @@ class CKernel(Kernel): self._read_from_stdin) def compile_with_gcc(self, source_filename, binary_filename, cflags=None, ldflags=None): - cflags = ['-std=c11', '-fPIC', '-shared', '-rdynamic'] + cflags + # cflags = ['-std=c89', '-pedantic', '-fPIC', '-shared', '-rdynamic'] + cflags + # cflags = ['-std=iso9899:199409', '-pedantic', '-fPIC', '-shared', '-rdynamic'] + cflags + # cflags = ['-std=c99', '-pedantic', '-fPIC', '-shared', '-rdynamic'] + cflags + cflags = ['-std=c11', '-pedantic', '-fPIC', '-shared', '-rdynamic'] + cflags + if self.linkMaths: + cflags = cflags + ['-lm'] if self.wError: cflags = cflags + ['-Werror'] if self.wAll: diff --git a/jupyter_c_kernel/resources/stdio_wrap.h b/jupyter_c_kernel/resources/stdio_wrap.h index 8a365d8..e079947 100644 --- a/jupyter_c_kernel/resources/stdio_wrap.h +++ b/jupyter_c_kernel/resources/stdio_wrap.h @@ -5,8 +5,20 @@ #include #include +/* Figure out used C standard. + __STDC_VERSION__ is not always defined until C99. + If it is not defined, set standard to C89. + It is safest to set it by hand, to make sure */ +#ifdef __STDC_VERSION__ +#if __STDC_VERSION__ <= 199409L +#define C89_SUPPORT +#endif /* __STDC_VERSION__ <= 199409L */ +#else /* __STDC_VERSION__ */ +#define C89_SUPPORT +#endif /* __STDC_VERSION__ */ + /* Need input buffer to know whether we need another input request */ -char inputBuff[1<<10] = ""; +static char inputBuff[1<<10] = ""; /* read remaining input into buffer so it can be used in next call */ void readIntoBuffer() { @@ -19,8 +31,8 @@ void readIntoBuffer() { inputBuff[length] = '\0'; } -/* Define the functions to overload the old ones */ -int scanf_wrap(const char *format, ...) { +/* check whether input request is needed */ +char checkInputRequest() { /* unget chars in buffer */ char doRequest = 1; char leadingNewline = 1; @@ -38,21 +50,49 @@ int scanf_wrap(const char *format, ...) { } } + return doRequest; +} + +/* Define the functions to overload the old ones */ + +/* Wrapping of scanf depends on standard */ +#ifdef C89_SUPPORT +/* Need to define vscanf for c89. + TODO: This is a bit risky, since the underlying glibc does not + have to include this if it is old. If it does not, linking will fail. + The only safe way is reimplementing the whole function. */ + +/* Read formatted input from stdin into argument list ARG. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int vscanf (const char *__restrict __format, _G_va_list __arg) + __attribute__ ((__format__ (__scanf__, 1, 0))) __wur; +#endif /* C89_SUPPORT */ + +int scanf_wrap(const char *format, ...) { + char doRequest = checkInputRequest(); + if(doRequest) { printf(""); fflush(stdout); } - va_list arglist; - va_start( arglist, format ); - int result = vscanf( format, arglist ); - va_end( arglist ); - /* Put the remaining input into the input buffer */ - readIntoBuffer(); + { + va_list arglist; + int result; + va_start( arglist, format ); + result = vscanf( format, arglist ); + va_end( arglist ); - return result; + /* Put the remaining input into the input buffer */ + readIntoBuffer(); + + return result; + } } + int getchar_wrap(){ /* check if there is still something in the input buffer*/ char input = 0; @@ -64,9 +104,10 @@ int getchar_wrap(){ input = getchar(); readIntoBuffer(); } else { + int i = 1; + input = inputBuff[0]; /* shift all chars one to the left */ - int i = 1; for(; i < 100; ++i){ inputBuff[i-1] = inputBuff[i]; if(inputBuff[i] == '\0') { @@ -79,8 +120,15 @@ int getchar_wrap(){ } /* Replace all the necessary input functions - Need double hashes in case there are no __VA_ARGS__*/ + depending on the language version used */ +#ifndef C89_SUPPORT +/* Need double hashes in case there are no __VA_ARGS__*/ #define scanf(format, ...) scanf_wrap(format, ##__VA_ARGS__) +#else /* C89_SUPPORT */ +/* Since there are no variadic macros in C89, this is the only way + although it is horrible */ +#define scanf scanf_wrap +#endif /* C89_SUPPORT */ #define getchar() getchar_wrap()