======== Programs ======== .. Modified: 2019-10-20/23:17-0400 btiffin .. Copyright 2016 Brian Tiffin .. GPL 3.0+ :ref:`license` .. This file is part of the Unicon Programming documentation set .. image:: images/unicon.png :align: center .. only:: html :ref:`genindex` :floatright:`Unicon` .. index:: programs .. _programs: Sample programs and integrations ================================ For lack of a better chapter name, this part of the docset is miscellaneous sample programs. .. index:: S-Lang .. _slang: S-Lang ------ An example of embedding an S-Lang interpreter. S-Lang programs, as Unicon strings, are evaluated, and the last S-Lang result is passed back to Unicon. Allowed return types: - :ref:`integer` - :ref:`real` - :ref:`string` - :ref:`list` (from S-Lang array, single dimension, cast to ``double``) S-Lang, by John Davis. http://www.jedsoft.org/slang/ .. note:: The ``mkRlist`` function in ``ipl/cfuncs/icall.h`` had the wrong prototype prior to `Revision 4501 `_ of the Unicon sources. Was ``int x[]``, needs to be ``double x[]``. :: -word mkRlist(int x[], int n); +word mkRlist(double x[], int n); Already fixed, thanks to :ref:`Jafar`. .. note:: Also be aware that some of the memory management in ``slang.c`` may be erroneous. Not for production use if you see this note. Here is the ``slang`` :ref:`loadfunc` C function: .. literalinclude:: programs/slang.c :language: c .. only:: html .. rst-class:: rightalign :download:`programs/slang.c` A Unicon test head: .. literalinclude:: programs/slang.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/slang.icn` And a flying carpet run to see how things go: .. command-output:: gcc -o slang.so -shared -fpic slang.c -lslang :cwd: programs Sample run ends in a purposeful error demonstration: .. command-output:: unicon -s slang.icn -x :cwd: programs :returncode: 1 And Unicon can use S-Lang scripts whenever necessary. -------- .. index:: COBOL .. _unicob: COBOL ----- An example of embedding a COBOL module. First pass is simply seeing if integers make into the COBOL runtime. GnuCOBOL is a free software COBOL compiler; part of the GNU project, copyright Free Software Foundation. https://sourceforge.net/projects/open-cobol/ :ref:`GnuCOBOL` .. blockdiag:: blockdiag { orientation = portrait; unisrc [label="unicob.icn", shape=note]; source [label="unicob.cob", shape=note]; module [label="unicob.so", shape=flowchart.input]; result [label="result :=\n unicob(arg1, ...)"]; unisrc -> unicon -> loadfunc -> result; source -> cobc -> module -> loadfunc; } .. note:: This is first step trial code The loaded COBOL function, ``unicob``: .. literalinclude:: programs/unicob-v1.cob :language: cobol :start-after: *>+<* .. only:: html .. rst-class:: rightalign :download:`programs/unicob-v1.cob` A test head: .. literalinclude:: programs/unicob-v1.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/unicob-v1.icn` And a flying carpet run to see how things go: .. command-output:: cobc -m -w -fimplicit-init unicob-v1.cob :cwd: programs .. command-output:: unicon -s unicob-v1.icn -x :cwd: programs Seems to work ok. *Nerd dancing ensues, with a couple of "Oh, yeah, uh huh"s thrown in*. Step 2 ...... This is still fairly experimental code. A little bit of ``icall.h`` ported in, with support of more datatypes than simple integers. .. index:: unicob.cob .. _unicob.cob: .. literalinclude:: programs/unicob.cob :language: cobol :start-after: *>+<* .. only:: html .. rst-class:: rightalign :download:`programs/unicob.cob` Adding to the test head: .. index:: unicob.icn .. literalinclude:: programs/unicob.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/unicob.icn` And a fly by to check out the new datatype support: .. command-output:: cobc -m -w -fimplicit-init unicob.cob :cwd: programs .. command-output:: unicon -s unicob.icn -x :cwd: programs So, yeah, Unicon and COBOL; might come in handy. There are a lot more details about GnuCOBOL at http://open-cobol.sourceforge.net/faq/index.html -------- .. index:: duktape .. _duktape: Duktape ------- A Javascript engine. Another exploratory trial. Duktape is hosted at http://duktape.org You will need the ``.c`` and ``.h`` files from the ``src/`` directory from the distribution. This test uses version 1.5.1. http://duktape.org/duktape-1.5.1.tar.xz With Duktape, you simply include the ``.c`` files in a build. In this case, ``uniduk.so`` is built with ``uniduk.c`` and ``dukctape.c``. The C sample for ``loadfunc``. ``uniduk-v1.c``. .. index:: uniduk-v1 .. literalinclude:: programs/uniduk-v1.c :language: c .. only:: html .. rst-class:: rightalign :download:`programs/uniduk-v1.c` The sample Unicon file to load and test the engine, ``uniduk-v1.icn``. .. literalinclude:: programs/uniduk-v1.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/uniduk-v1.icn` And a test run .. command-output:: gcc -std=c99 -o uniduk.so -shared -fpic uniduk-v1.c duktape.c :cwd: programs .. command-output:: unicon -s uniduk-v1.icn -x :cwd: programs And Duktape Javascript step 1 has been taken. Second step ........... .. todo:: extend this further to handle more datatypes The extended C sample for ``loadfunc``. ``uniduk.c``. .. index:: uniduk.c .. literalinclude:: programs/uniduk.c :language: c .. only:: html .. rst-class:: rightalign :download:`programs/uniduk.c` The sample Unicon file to load and test the engine, ``uniduk.icn``. .. literalinclude:: programs/uniduk.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/uniduk.icn` .. literalinclude:: programs/uniduk.js :language: js .. only:: html .. rst-class:: rightalign :download:`programs/uniduk.js` And a test run .. command-output:: gcc -std=c99 -o uniduk.so -shared -fpic uniduk.c duktape.c :cwd: programs .. command-output:: unicon -s uniduk.icn -x :cwd: programs And Duktape Javascript step 2 has been taken. *Can you feel the nerd dancing? Running man with a wicked loud*\ [1]_ *"Ice, Ice Baby" playing in the background?* To be a little more confident, here is an initial stress test, calling out the Viking, ``valgrind``. .. command-output:: valgrind ./uniduk :cwd: programs There used to be a warning about invalid fd passed to the ``close`` syscall. Turns out, *by tracking with* ``strace``, it was actually Unicon start up doing that.\ [2]_. *Didn't effect program outcome, but after mentioning it to the principals it was fixed.*\ [3]_. *The rest is all good, 0 leaked RAM*. The still reachable being non-zero is a common thing in most processes; exit was called while the Unicon engine was still in play, so there is valid runtime memory used for statics (like message strings) and a little bit of allocation for buffers. The important numbers for this test pass are :: ... ==nnnnn== LEAK SUMMARY: ==nnnnn== definitely lost: 0 bytes in 0 blocks ==nnnnn== indirectly lost: 0 bytes in 0 blocks ==nnnnn== possibly lost: 0 bytes in 0 blocks ... ==nnnnn== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ... Those are what you want to see from a Viking\ [4]_ report. *Process numbers will vary by machine and run* .. [1] Turned up wayyy past 4 on the dial, maybe even a 6. .. [2] Tried this with a bare bones Unicon program, single write of a string. ``valgrind`` still reported the invalid -1 to the close syscall. .. [3] Mentioned the -1 being passed to ``close`` during :ref:`ucode` invocation. This was caused by a lower level ``sh`` edge case interaction in handling the way ``ucode`` is attached to an invocation script. Harmless, and not to be entirely blamed on Unicon, but it was fixed anyway. Every bug reported to the Unicon team has been fixed while writing this book. .. [4] ``valgrind`` is a Norse name, pronounced to rhyme with ``grinned``, not ``grind``. Go vikings. Duktape license obligation .......................... :: Copyright (c) 2013-2016 by Duktape authors (see AUTHORS.rst) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------- .. index:: mruby .. _mruby: mruby ----- Integrate the `mruby` (Mini Ruby) library with Unicon. First pass, see if things gel: .. index:: uniruby-v1.c .. literalinclude:: programs/uniruby-v1.c :language: c .. only:: html .. rst-class:: rightalign :download:`programs/uniruby-v1.c` The sample Unicon file to load and test the engine, ``uniruby-v1.icn``. .. literalinclude:: programs/uniruby-v1.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/uniruby-v1.icn` And a test run .. command-output:: gcc -o uniruby.so -shared -fpic uniruby-v1.c /usr/lib/libmruby.a -lm :cwd: programs .. command-output:: unicon -s uniruby-v1.icn -x :cwd: programs mruby license obligation ........................ :: Copyright (c) 2016 mruby developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------- .. index:: ficl, Forth .. _ficl: ficl ---- The Forth Inspired Command Language. http://ficl.sourceforge.net/ This sample embeds a Forth interpreter using ficl-4.1.0 as a shared library. The initial trial, ``unificl-v1`` .. index:: unificl-v1.c .. literalinclude:: programs/unificl-v1.c :language: c :start-after: +*/ .. only:: html .. rst-class:: rightalign :download:`programs/unificl-v1.c` A sample Unicon file to load and test the engine, ``unificl-v1.icn``. .. literalinclude:: programs/unificl-v1.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/unificl-v1.icn` And a test run (using an uninstalled copy of ``ficl``, so the Makefile includes C compiler ``-L``, ``-I`` options and ``LD_LIBRARY_PATH`` runtime settings). .. pending command-output:: make -B unificl-v1 :cwd: programs Forth scripting inside Unicon. *If you look closely, that ficl word-list display includes the test definition of unificl-test, along with the ficl core, and default extension words*. Note that ``ficl`` result code ``-257`` is the normal exit status. Defined as .. sourcecode:: c /* hungry - normal exit */ #define FICL_VM_STATUS_OUT_OF_TEXT (-257) That means the text was successfully interpreted and the engine is ready for more. ``-260`` is defined as .. sourcecode:: c /* interpreter found an error */ #define FICL_VM_STATUS_ERROR_EXIT (-260) Second step ........... And now for some real integration. .. index:: unificl.c .. literalinclude:: programs/unificl.c :language: c :start-after: +*/ .. only:: html .. rst-class:: rightalign :download:`programs/unificl.c` A sample Unicon file to load and test the updated engine, ``unificl.icn``. .. literalinclude:: programs/unificl.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/unificl.icn` Sample run ends in a purposeful error, Unicon trapping a Ficl segfault: .. command-output:: make -B unificl :cwd: programs :returncode: 2 The ``unificl`` engine can evaluate Forth source, and Unicon can snag the stack and the floating point stack as needed, as a list. That returned list is ready for Unicon style stack functions, :ref:`pop` will pop what would be the top of the ``ficl`` data stack. *Separate structures, the ficl stack is the ficl stack, and Unicon gets a copy as a list*. As a side bonus, no effort was required to have Unicon catch (and report) the purposeful segfault in the last ``ficl`` test of ``0 ?`` (an attempt to read address 0). FICL License obligation ....................... :: FICL LICENSE Copyright © 1997-2001 John Sadler (john_sadler@alum.mit.edu) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------- .. index:: Lua .. _lua: Lua --- Lua scripts embedded in Unicon. First pass, see if things gel: .. index:: unilua-v1.c .. literalinclude:: programs/unilua-v1.c :language: c :start-after: +*/ .. only:: html .. rst-class:: rightalign :download:`programs/unilua-v1.c` The sample Unicon file to load and test the engine, ``unilua-v1.icn``. .. literalinclude:: programs/unilua-v1.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/unilua-v1.icn` The :ref:`make` recipes: .. sourcecode:: make # Lua in Unicon # alpha test unilua-v1.so: unilua-v1.c > gcc -o unilua-v1.so -shared -fpic unilua-v1.c \ -I/usr/include/lua5.3 -llua5.3 unilua-v1: unilua-v1.so > unicon -s unilua-v1.icn -x # unilua unilua.so: unilua.c > gcc -o unilua.so -shared -fpic unilua.c \ -I/usr/include/lua5.3 -llua5.3 unilua: unilua.so > unicon -s unilua.icn -x And the alpha test run: .. command-output:: make -B --no-print-directory unilua-v1.so :cwd: programs .. command-output:: unicon -s unilua-v1.icn -x :cwd: programs Second step ........... Lua state is held in a persistent variable, remembered across calls. A new ``luaclose`` function is supported. .. index:: unilua.c .. literalinclude:: programs/unilua.c :language: c :start-after: +*/ .. only:: html .. rst-class:: rightalign :download:`programs/unilua.c` Another sample Unicon file to load and test the engine, ``unilua.icn``. .. literalinclude:: programs/unilua.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/unilua.icn` And the second test run: .. command-output:: make -B unilua.so :cwd: programs .. command-output:: unicon -s unilua.icn -x :cwd: programs A final step will be returning all Lua stack items to Unicon during each call, and perhaps exposing a few more Lua internal API features. Lua license obligation ...................... :: Copyright © 1994–2016 Lua.org, PUC-Rio. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------- .. index:: fortran .. _fortran: Fortran ------- Calling FORTRAN programs from Unicon. The first step passes no arguments, but uses various Fortran source forms; FORTRAN-66, FORTRAN-77. A Fortran-90 (free format) program takes an integer and returns a result to Unicon. .. literalinclude:: programs/fortran-66.f :language: fortran :start-after: CC+ .. only:: html .. rst-class:: rightalign :download:`programs/fortran-66.f` .. literalinclude:: programs/fortran-77.f :language: fortran :start-after: *+* .. only:: html .. rst-class:: rightalign :download:`programs/fortran-77.f` This next Fortran-90 source accepts an integer argument and returns the square of the Unicon value (using Fortran ``subroutine`` call frame expectations which has no return value, all parameters passed by reference) plus the cube of the Unicon number (using Fortran ``function`` call frame expectations). The data marshalling to and from Fortran uses a small layer of C, but that could be pure Fortran if the data structures from :file:`icall.h` were ported to Fortran friendly data definitions. .. literalinclude:: programs/fortran.f :language: fortran :start-after: !!+ .. only:: html .. rst-class:: rightalign :download:`programs/fortran.f` A little bit of C as an intermedia data marshalling layer: .. literalinclude:: programs/unifortran.c :language: c :start-after: +*/ .. only:: html .. rst-class:: rightalign :download:`programs/unifortran.c` The make recipes: .. sourcecode:: make # gfortran modules fortran-66.so: fortran-66.f > gfortran -o fortran-66.so -shared -fpic fortran-66.f fortran-77.so: fortran-77.f > gfortran -o fortran-77.so -shared -fpic fortran-77.f fortran.so: fortran.f unifortran.c > gfortran -ffree-form -c -fpic fortran.f > gcc -o fortran.so -shared -fpic unifortran.c fortran.o fortran: fortran.icn fortran-66.so fortran-77.so fortran.so > unicon -s $< -x A Unicon test file: .. literalinclude:: programs/fortran.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/fortran.icn` The alpha trial serves multiple purposes in this case. There is a simple goal of trying various forms of Fortran source; FORTRAN 66, FORTRAN 77, and more modern Fortran syntax. There is also a proof of technology test to see if ``main`` modules can be loaded with :ref:`loadfunc`. A third purpose is ensuring that C interstitial code plays well between Fortran and Unicon, when passing parameters and retrieving results. .. command-output:: make --no-print-directory -B fortran :cwd: programs -------- .. index:: Assembler .. _assembler: Assembler --------- Calling assembly programs from Unicon. Assembler is no different than C when it comes to the binary objects produced for the operating system. Assembler is a step on the way to native binary for many C compilers, `gcc` in particular. A very similar Unicon :ref:`loadfunc` setup, identical actually: .. literalinclude:: programs/uniasm.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/uniasm.icn` A fairly sophisticated looking piece of x86_64 assembler source: .. literalinclude:: programs/uniasm.s :language: gas .. only:: html .. rst-class:: rightalign :download:`programs/uniasm.s` Which is computer generated output from a much simpler looking C source file: .. literalinclude:: programs/uniasm.c :language: C :start-after: +*/ .. only:: html .. rst-class:: rightalign :download:`programs/uniasm.c` .. command-output:: gcc -S -fpic uniasm.c :cwd: programs That assembly can be used just like a C file when it comes to creating the shared objects required by `loadfunc`. The ``-fpic`` option is required along with ``gcc -S`` to generate assembly code that can be relocated, for use in a dynamic shared object file. .. command-output:: gcc -o uniasm.so -shared -fpic uniasm.s :cwd: programs Note the :file:`.s` on that command line, not a :file:`.c` file. And running that from Unicon: .. command-output:: unicon -s uniasm.icn -x :cwd: programs Although this example was generated assembly, the :file:`.s` source code could be used as a basis for hand edited files, all the Unicon `loadfunc` requirements, and associated macros, properly expanded into working assembler. -------- .. index:: vedis, Symisc .. _vedis: vedis ----- ``vedis``, an embedded Redis clone by Symisc Systems. Using a Redis style data store from Unicon. http://vedis.symisc.net/ The Unicon setup uses ``pathload`` from IPL file :file:`io.icn`. .. literalinclude:: programs/univedis-v1.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/univedis-v1.icn` The vedis source is an SQLite style amalgamation bundle. Just include :file:`vedis.c` in a build. .. literalinclude:: programs/Makefile :language: make :start-after: ##+vedis :end-before: ##-vedis The initial trial is a simple vedis example: .. literalinclude:: programs/univedis-v1.c :language: c :start-after: +*/ .. only:: html .. rst-class:: rightalign :download:`programs/univedis-v1.c` And a sample run: .. command-output:: make -B --no-print-directory univedis-v1 :cwd: programs There are some 70 ``Redis`` type commands in the ``vedis`` engine. vedis license obligation ........................ :: /* * Copyright (C) 2013 Symisc Systems, S.U.A.R.L [M.I.A.G Mrad Chems Eddine ]. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Redistributions in any form must be accompanied by information on * how to obtain complete source code for the Vedis engine and any * accompanying software that uses the Vedis engine software. * The source code must either be included in the distribution * or be available for no more than the cost of distribution plus * a nominal fee, and must be freely redistributable under reasonable * conditions. For an executable file, complete source code means * the source code for all modules it contains.It does not include * source code for modules or files that typically accompany the major * components of the operating system on which the executable file runs. * * THIS SOFTWARE IS PROVIDED BY SYMISC SYSTEMS ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL SYMISC SYSTEMS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -------- .. index:: libcox, Symisc .. _libcox: libcox ------ ``libcox`` a cross platform system command evaluation library by Symisc Systems. http://libcox.symisc.net/ Another Unicon :ref:`loadfunc` sample. .. literalinclude:: programs/unicox.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/unicox.icn` The libcox source is an SQLite style amalgamation bundle. Just include :file:`libcox.c` in a build. .. literalinclude:: programs/Makefile :language: make :start-after: ##+libcox :end-before: ##-libcox The loadable: .. literalinclude:: programs/unicox.c :language: c :start-after: +*/ .. only:: html .. rst-class:: rightalign :download:`programs/unicox.c` The initial trial includes the ``libcox`` :command:`CMD_LIST` and a sample file expansion :command:`glob` from a different working directory. .. command-output:: make -B --no-print-directory unicox | par :cwd: programs :shell: With :file:`libcox.c` version 1.7, there are over 145 commands available. Set to work across multiple platforms; GNU/Linux and Windows at a minimum. libcox license obligation ......................... :: /* * Symisc libcox: Cross Platform Utilities & System Calls. * Copyright (C) 2014, 2015 Symisc Systems http://libcox.net/ * Version 1.7 * For additional information on licensing, redistribution of this file, * and for a DISCLAIMER OF ALL WARRANTIES please contact Symisc Systems via: * licensing@symisc.net * contact@symisc.net * or visit: * http://libcox.net/ */ /* * Copyright (C) 2014, 2015 Symisc Systems, S.U.A.R.L [M.I.A.G Mrad Chems Eddine ]. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY SYMISC SYSTEMS ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL SYMISC SYSTEMS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -------- .. index:: PHP, PH7, Symisc .. _PH7: PH7 --- ``PH7`` is an embeddable PHP engine from Symisc Systems. Calling PHP programs from Unicon with PH7. http://ph7.symisc.net/ A very similar Unicon setup: .. literalinclude:: programs/uniph7-v1.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/uniph7-v1.icn` The PH7 source is an SQLite style amalgamation bundle. Just include :file:`ph7.c` in a build. .. literalinclude:: programs/Makefile :language: make :start-after: ##+ph7 :end-before: ##-ph7 The initial trial is a simple change to the PH7 example, :file:`ph7_intro.c`. .. literalinclude:: programs/uniph7-v1.c :diff: programs/ph7_intro.c A complete listing for clarity: .. literalinclude:: programs/uniph7-v1.c :language: c .. only:: html .. rst-class:: rightalign :download:`programs/uniph7-v1.c` And a sample run: .. command-output:: make -B --no-print-directory uniph7-v1 :cwd: programs There are some differences between the reference implementation of PHP and PH7, so large frameworks may not work, but small bits of PHP will, and the PH7 includes a foreign function interface to add features if required. PH7 license obligation ...................... :: /* * Copyright (C) 2011,2012 Symisc Systems. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Redistributions in any form must be accompanied by information on * how to obtain complete source code for the PH7 engine and any * accompanying software that uses the PH7 engine software. * The source code must either be included in the distribution * or be available for no more than the cost of distribution plus * a nominal fee, and must be freely redistributable under reasonable * conditions. For an executable file, complete source code means * the source code for all modules it contains.It does not include * source code for modules or files that typically accompany the major * components of the operating system on which the executable file runs. * * THIS SOFTWARE IS PROVIDED BY SYMISC SYSTEMS ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL SYMISC SYSTEMS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -------- .. index:: unqlite, Symisc .. _unqlite: UnQLite ------- Another amalgam release from Symisc. This is a NoSQL database engine, with Jx9 scripting included (Jx9 is another Symisc software but included in the UnQLite distribution). Similar build environment, include unqlite.c along with other sources to build a shared object file for use with Unicon :ref:`loadfunc`. *Aside:* Being a COBOL programmer, and growing up on Vax/VMS, the term "NoSQL" is a sad state of word smithery. Key-value database would be better. Computers had ISAM and RMS and other indexed record management systems long before SQL became dominant, and the term NoSQL just shows a lack of educational history in the field of computer science. Unstructured Query Language is the new post-modern database paradigm, UnQL (pronounced Uncle) but records and keys is not "NoSQL". Rant over. So here is a NoSQL data engine with UnQLite. A fairly unique blend of key-value store and document store. First step is to see if it'll work. .. literalinclude:: programs/uniunql-v1.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/uniunql-v1.icn` The make rules .. literalinclude:: programs/Makefile :language: make :start-after: ##+unqlite :end-before: ##-unqlite A slightly modified :file:`unqlite_doc_intro.c` for use with a :ref:`loadfunc` trial. .. literalinclude:: programs/uniunql-v1.c :diff: programs/unqlite_doc_intro.c A complete listing, for clarity .. literalinclude:: programs/uniunql-v1.c :language: c And a sample run: .. command-output:: make -B --no-print-directory uniunql-v1 :cwd: programs A :ref:`JSON` document stored and then retrieved, filtered by ``age > 30``, from :file:`:mem:` in-memory storage. A different (valid) filename passed from Unicon in ``uniunql()`` would create a disk persistent document store. Next step will be a more capable Unicon binding. Performance of UnQLite is impressive. https://unqlite.org/ UnQLite license obligation .......................... :: /* * Copyright (C) 2012, 2013 Symisc Systems, S.U.A.R.L [M.I.A.G Mrad Chems Eddine ]. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY SYMISC SYSTEMS ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL SYMISC SYSTEMS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ There is a visible conflict with this license and the Jx9 engine. Separated, Jx9 ships with more capabilities and a 3 clause license, comparable to the :ref:`vedis` and :ref:`PH7` licenses. Symisc has openly stated that the license intent with UnQLite is 2 clause, there is no obligation to produce source for all associated usage or work out a dual licensing contract when using the version of Jx9 that ships with UnQLite in closed source systems. Not that Unicon is against strong copyleft freedoms, but the conflict is visible when inspecting the unqlite.c file when looking at the included jx9.h source file. Although it may be wise to treat UnQLite as a three clause system if you need to satisfy company attorneys, this forum post clarifies the author's intent https://unqlite.org/forum/thread.php?file=can-i-use-the-jx9-with-unqlite-for-closed-source-project :: ... So, even UnQLite uses a portion of the Jx9 core to implement it's document storage engine, everything is covered by the UnQLite BSD license as far you do not embed the entire Jx9 library (I mean here the independent engine available here http://jx9.smisc.net) in your commercial software. Or, just ship all the sources when using UnQLite and avoid any and all potential issues. -------- .. index:: REXX, ooRexx, Cowlishaw; Mike .. _oorexx: REXX ---- Restructured Extended Executor as Open Object Rexx, embedded in Unicon via :ref:`loadfunc`. Rexx was originally designed and implemented from 1979 to 1982 by Mike Cowlishaw. Rexx is a close relative to Icon, age wise. A version of Object Rexx was released by IBM as free software in 2004. That spawned Open Object Rexx, which is used here for the demonstration. Regina Rexx would also work for classic Rexx, and may make more sense for ``loadfunc``, being a solid C build environment, but ooRexx has some pretty nifty features and is keeping the C heritage available while the team builds out the new C++ API. .. literalinclude:: programs/unirexx.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/unirexx.icn` The main ooRexx API is now a C++ implementation, but there is a classic interface based on C. Both are tested here. The classic API. .. literalinclude:: programs/unirexx.c :language: c :start-after: +*/ .. only:: html .. rst-class:: rightalign :download:`programs/unirexx.c` The C++ API, with a slightly simpler Unicon interface. This is also testing whether Unicon :ref:`loadfunc` can manage C++ (which it does seem to, at least for the initial trials). .. literalinclude:: programs/oorexx.cpp :language: cpp :start-after: +*/ .. only:: html .. rst-class:: rightalign :download:`programs/oorexx.cpp` The build rules are not complicated. .. literalinclude:: programs/Makefile :language: make :start-after: ##+rexx :end-before: ##-rexx And the sample run. A single Unicon program tests both API implementation style. .. command-output:: make -B unirexx :cwd: programs Open Object Rexx is available on SourceForge at https://sourceforge.net/projects/oorexx/ This is 4.2, ooRexx has started in on 5.0 beta releases. -------- .. index:: i18n, L10n, Internationalization, Localization, gettext .. _i18n: Internationalization and Localization ------------------------------------- i18n/L10n The GNU project provides very extensive localization tools. ``gettext`` being one of the main C functions provided to allow for runtime human language translations based on :ref:`locale`. .. index:: unicon-i18n.c .. literalinclude:: programs/unicon-i18n.c :language: c :start-after: +*/ .. only:: html .. rst-class:: rightalign :download:`programs/unicon-i18n.c` .. index:: unicon-i18n.icn .. literalinclude:: programs/unicon-i18n.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/unicon-i18n.icn` With a sample run (using messages from GNU coretils and Spanish translations) .. command-output:: gcc -o unicon-i18n.so -shared -fpic unicon-i18n.c :cwd: programs Using local default locale, *English* .. command-output:: unicon -s unicon-i18n.icn -x :cwd: programs Using a Spanish language locale setting .. command-output:: LC_ALL="es_ES.UTF-8" LANG="spanish" LANGUAGE="spanish" ./unicon-i18n :cwd: programs :shell: -------- .. index:: libsoldout, soldout, markdown .. _soldout: libsoldout markdown ------------------- A loadable function to process Markdown into HTML. libsoldout also ships with example renderers for LaTeX and man page outputs. Simple Markdown, and extended Discount and soldout features included. .. literalinclude:: programs/soldout.c :language: c .. only:: html .. rst-class:: rightalign :download:`programs/soldout.icn` .. literalinclude:: programs/soldout.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/soldout.icn` And a sample run: .. command-output:: unicon -s soldout.icn -x :cwd: programs .. image:: images/soldout-firefox.png :align: center -------- .. index:: ie, readline .. _readline: ie modified for readline ------------------------ ``ie``, the Icon Evaluator, part of the :ref:`IPL` and built along with Unicon, is a handy utility for trying out Unicon expressions in an interactive shell. Nicer when the commands can be recalled. This example integrates GNU ``readline`` into ``ie``. .. note:: You could also use ``rlwrap ie`` to get the same effect. .. index:: unireadline.c .. literalinclude:: programs/unireadline.c :language: c .. only:: html .. rst-class:: rightalign :download:`programs/unireadline.c` The changes to ``ie`` are minor. In the sources from ``uni/prog/ie.icn``, change .. sourcecode:: unicon writes(if *line = 0 then "][ " else "... ") inline := (read()|stop()) to .. sourcecode:: unicon inline := (readline(if *line = 0 then "uni> " else "... ")|stop()) and add .. sourcecode:: unicon procedure reader(prompt) writes(prompt) return read() end procedure readline(prompt) &error +:= 1 readline := loadfunc("./unireadline.so", "unirl") | reader &error -:= 1 return readline(prompt) end Then recompile ``ie``. :: prompt$ gcc -o unireadline.so -shared -fpic unireadline -lreadline prompt$ unicon ie.icn prompt$ cp ie unireadline.so [INSTALL-DIR]/bin/ After that, when you run ``ie``, you will have ``readline`` command recall available. *Assuming* ``readline`` *is installed*. If ``readline`` is not installed, you will get the old interface of :ref:`read`. To properly compile ``unireadline.c``, you will need the GNU readline development headers installed on your system. -------- .. index:: snobol .. _snobol4: SNOBOL4 ------- A short program to run SNOBOL4 programs with a pipe, and display any OUTPUT. Some of the test programs that ship with SNOBOL4 are included, to highlight how complete the distribution is: https://sourceforge.net/projects/snobol4/ Run `SNOBOL` files passed as arguments. This is a very lightweight program, results are simply written to `&output`. Much more could be done with the :command:`snobol4` ``OUTPUT =`` data. .. literalinclude:: programs/snobol.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/snobol.icn` And a sample run, with ``spitbol`` based diagnostics and a hello: .. command-output:: unicon -s snobol.icn -x hello.sno diag[12].sno :cwd: programs The SNOBOL sources are from the SNOBOL4 distribution ``test/`` directory downloaded from SourceForge. *Tabs replaced with spaces at tab stop 8*. .. literalinclude:: programs/hello.sno :language: snobol .. only:: html .. rst-class:: rightalign :download:`programs/hello.sno` .. literalinclude:: programs/diag1.sno :language: snobol .. only:: html .. rst-class:: rightalign :download:`programs/diag1.sno` .. literalinclude:: programs/diag2.sno :language: snobol .. only:: html .. rst-class:: rightalign :download:`programs/diag2.sno` Many thanks to the SNOBOL4 in C team, Philip L. Budne, and the other contributors. :ref:`Ralph` sure did some amazing design work. Be sure to check out the SourceForge link given above, and grab a copy of the distribution kit. CSNOBOL4 License obligation ........................... :: Copyright © 1993-2015, Philip L. Budne All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------- .. index:: fizzbuzz .. _fizzbuzz: fizzbuzz -------- FizzBuzz without modulo. Chase the fizz. FizzBuzz is a task on Rosetta Code, :ref:`RosettaCode`. Most entries use some form of modulo test, this one (idea from a COBOL entry by Steve Williams) simply adds to the fizz and the buzz during the loop. .. literalinclude:: programs/fizzbuzz.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/fizzbuzz.icn` And a sample run: .. command-output:: unicon -s fizzbuzz.icn -x :cwd: programs -------- .. index:: eval, uval.icn .. _eval: eval ---- A poor person's *expensive* ``eval`` procedure. Putting the multi-tasker to work with on the fly compilation, :ref:`load` of new code and co-expression reflective properties. .. literalinclude:: programs/uval.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/uval.icn` And a sample run: .. command-output:: unicon -s uval.icn -x :cwd: programs -------- .. index:: unilist .. _unilist: unilist ------- Creating list results with `loadfunc`. This is a pass at coming to grips with building heterogeneous lists from C functions. First the C side: .. literalinclude:: programs/unilist.c :language: c :start-after: +*/ .. only:: html .. rst-class:: rightalign :download:`programs/unilist.c` Then a Unicon test pass: .. literalinclude:: programs/unilist.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/unilist.icn` Build the loadable: .. command-output:: gcc -o unilist.so -shared -fPIC unilist.c :cwd: programs Run the test under ``valgrind`` to watch for leaks, should be 0. .. command-output:: valgrind unicon -s unilist.icn -x :cwd: programs -------- .. index:: tcc, Tiny C .. _tcc: tcc --- Embedding and integrating Tiny C with `loadfunc`. This is a pass at building `loadfunc` dynamic shared object files with Tiny C. As a first trial, the ``unilist.c`` and ``unilist.icn`` listed above is used: Build the loadable: .. command-output:: tcc -o unilist.so -shared unilist.c :cwd: programs Run the test: .. command-output:: unicon -s unilist.icn -x :cwd: programs So, :t:`tcc` can be used to build Unicon loadable shared libraries. :t:`gcc` produced a 12K shared object file, :t:`tcc` produced an 8K file. Embedded tcc ............ And then, to embed a C compiler in a Unicon function: .. literalinclude:: programs/unitcc.c :language: c :start-after: +*/ .. only:: html .. rst-class:: rightalign :download:`programs/unitcc.c` Unicon test file, expects to find a post compile symbol of ``trytcc`` that takes an integer and returns that parameter multiplied by seven. .. literalinclude:: programs/unitcc.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/unitcc.icn` Build the loadable using ``libtcc.so`` from ``/usr/local/lib``. .. command-output:: tcc -o unitcc.so -shared unitcc.c -ltcc -L/usr/local/lib :cwd: programs This test loads the external function, which is an embedded C compiler, and then compiles and links a C function, ``trytcc`` directly into memory. The external function trial expects the ``trytcc`` entry point and invokes the function with an integer that is passed by Unicon along with the code. We expect to see "Hello, world" and a result that returns 6 * 7. Six is passed from Unicon and the C code multiples the input parameter by seven. Note that the `loadfunc` `DSO` was created by :t:`tcc`. .. command-output:: unicon -s unitcc.icn -x :cwd: programs Tiny C is very neat. And not really a toy. It's a full fledged ANSI C compiler, that even includes an inline assembler. Originally by Fabrice Bellard, now famous for designing and developing QEMU. http://bellard.org/tcc/ C code, compiled on the fly from Unicon, then invoked with arguments, and results returned using the features of `loadfunc`. .. only:: html .. -------- :ref:`genindex` | Previous: :doc:`scenarios` | Next: :doc:`multilanguage` |