The ucode language is a tiny general purpose scripting language featuring a syntax closely resembling ECMAScript. It can be used in a stand-alone manner by using the ucode command line interpreter or embedded into host applications by linking libucode and utilizing its C language API. Additionally, ucode can be invoked in template mode where control flow and expression logic statements are embedded in Jinja-like markup blocks.
Besides aiming for small size, the major design goals of ucode are the ability to trivially read and write JSON data, good embeddability into C applications, template capabilities for output formatting, extensiblity through loadable native extension modules and a straightforward set of built-in functions mimicking those found in the Perl 5 language.
In spring 2021 it has been decided to rewrite the OpenWrt firewall framework on top of nftables with the goal to replace the then current C application with a kind of preprocessor generating nftables rulesets using a set of templates instead of relying on built-in hardcoded rules like its predecessor.
That decision spurred the development of ucode, initially meant to be a simple template processor solely for the OpenWrt nftables firewall but quickly evolving into a general purpose scripting language suitable for a wider range of system scripting tasks.
Despite OpenWrt predominantly relying on POSIX shell and Lua as system scripting languages already, a new solution was needed to accomodate the needs of the new firewall implementation; mainly the ability to efficiently deal with JSON data and complex data structures such as arrays and dictionaries and the ability to closely interface with OpenWrt's ubus message bus system.
Throughout the design process of the new firewall and its template processor, the following design goals were defined for the ucode scripting language:
Summarized, ucode can be described as synchronous ECMAScript without the object oriented standard library.
In OpenWrt 22.03 and later, ucode should already be preinstalled. If not,
it can be installed via the package manager, using the opkg install ucode
command.
To build on MacOS, first install cmake and json-c via Homebrew, then clone the ucode repository and execute cmake followed by make:
$ brew install cmake json-c
$ git clone https://github.com/jow-/ucode.git
$ cd ucode/
$ cmake -DUBUS_SUPPORT=OFF -DUCI_SUPPORT=OFF -DULOOP_SUPPORT=OFF .
$ make
$ sudo make install
The ucode repository contains build recipes for Debian packages, to build .deb packages for local installation, first install required development packages, then clone the repository and invoke dpkg-buildpackage to produce the binary package files:
$ sudo apt-get install build-essential devscripts debhelper libjson-c-dev cmake pkg-config
$ git clone https://github.com/jow-/ucode.git
$ cd ucode/
$ dpkg-buildpackage -b -us -uc
$ sudo dpkg -i ../ucode*.deb ../libucode*.deb
To install ucode from source on other systems, ensure that the json-c library and associated development headers are installed, then clone and compile the ucode repository:
$ git clone https://github.com/jow-/ucode.git
$ cd ucode/
$ cmake -DUBUS_SUPPORT=OFF -DUCI_SUPPORT=OFF -DULOOP_SUPPORT=OFF .
$ make
$ sudo make install