code:
Getting started
###############

Genode can be approached from two different angles: as an operating-system
architecture or as a practical tool kit. This chapter assists you with
exploring Genode as the latter. After introducing the recommended
development environment,
it guides you through the steps needed to obtain the source code
(Section [Obtaining the source code]), to use the tool chain
(Section [Using the build system]), to test-drive system scenarios
(Section [A simple system scenario]), and to create your first custom
component from scratch (Section [Hello world]).

Recommended development environment
-----------------------------------

Genode is regularly used and developed on GNU/Linux. It is recommended to
use the latest long-term support (LTS) version of Ubuntu. Make sure that your
installation satisfies the following requirements:

* GNU Make version 3.81 (or newer) needed by the build system,
* _libSDL-dev_ needed to run system scenarios directly on Linux,
* _tclsh_ and _expect_ needed by test-automation and work-flow tools,
* _xmllint_ for validating configurations,
* _qemu_, _xorriso_, _sgdisk_, and _e2tools_ needed for running
  system scenarios on non-Linux platforms via the Qemu emulator.

For using the entire collection of ported 3rd-party software, the following
packages should be installed additionally:
_byacc_, _autoconf2.64_, _autogen_, _bison_, _flex_, _g++_, _git_, _gperf_,
_libxml2-utils_, _subversion_, and _xsltproc_.

Seeking help
------------

The best way to get assistance while exploring Genode is to consult the
mailing list, which is the primary communication medium of regular
users and developers alike. Please feel welcome to join in!

:Mailing Lists:

  [https://genode.org/community/mailing-lists]

If you encounter a new bug, ambiguous documentation, or a missing feature,
please consider opening a corresponding issue at the issue tracker:

:Issue tracker:

  [https://github.com/genodelabs/genode/issues]

Obtaining the source code
=========================

The centerpiece of Genode is the source code found within the official Git
repository:

:Source code at GitHub:

  [https://github.com/genodelabs/genode]

To obtain the source code, clone the Git repository:

! git clone https://github.com/genodelabs/genode.git

After cloning, you can find the source code within
the _genode/_ directory. In the following, we refer to this directory
as _<genode-dir>_.

Source-tree structure
=====================

Top-level directory
-------------------

At the root of the directory tree, there is the following content:

:_doc/_: Documentation in plain text format, including the
  release notes
  of all versions. _Practical hint:_ The comprehensive release notes
  conserve most of the hands-on documentation aggregated over the lifetime
  of the project. When curious about a certain topic, it is often worthwhile to
  "grep" for the topic within the release notes to get a starting point
  for investigation.

:_tool/_: Tools and scripts to support the build system, various boot loaders,
  the tool chain, and the management of 3rd-party source code. Please find
  more information in the _README_ file contained in the subdirectory.

:_repos/_: The so-called source-code repositories, which contain the actual
  source code of the framework components. The source code is not organized
  within a single source tree but multiple trees. Each tree is called a
  _source-code repository_ and has the same principle structure.
  At build time, a set of source-code repositories can be selected to be
  incorporated into the build process. Thereby, the source-code repositories
  provide a coarse-grained modularization of the framework.

Repositories overview
---------------------

The _<genode-dir>/repos/_ directory contains the following source-code
repositories.

:_base/_:

  The fundamental framework interfaces as well as the platform-agnostic parts
  of the core component (Section [Core - the root of the component tree]).

:_base-<platform>/_:
  Platform-specific supplements of the _base/_ repository where _<platform>_
  corresponds to one of the following:

  :_linux_:

    Linux kernel (both x86_32 and x86_64).

  :_nova_:

    NOVA microhypervisor.
    More information about the NOVA platform is provided by Section
    [Execution on the NOVA microhypervisor (base-nova)].

  :_hw_:

    The hw platform allows the execution of Genode on bare hardware
    without the need for a separate kernel. The kernel functionality is
    included in the core component. It supports the 32-bit ARM, 64-bit ARM,
    64-bit x86, and 64-bit RISC-V CPU architectures.
    More information about the hw platform can be
    found in Section [Execution on bare hardware (base-hw)].

  :_sel4_:

    The seL4 microkernel combines the L4-kernel philosophy with formal
    verification. The support for this kernel is experimental.

  :_foc_:

    Fiasco.OC is a modernized version of the L4/Fiasco microkernel with a
    completely revised kernel interface fostering capability-based
    security.

  :_okl4_:

    OKL4 kernel originally developed at Open-Kernel-Labs.

  :_pistachio_:

    L4ka::Pistachio kernel developed at University of Karlsruhe.

  :_fiasco_:

    L4/Fiasco kernel originally developed at Technische Universität Dresden.

:_os/_:

  OS components such as the init component, device drivers, and basic system
  services.

:_demo/_:

  Various services and applications used for demonstration purposes, for
  example the graphical application launcher and the tutorial browser
  described in Section [A simple system scenario] can be found here.

:_hello_tutorial/_:

  Tutorial for creating a simple client-server scenario. This
  repository includes documentation and the complete source code.

:_libports/_:

  Ports of popular open-source libraries, most importantly the C library.
  Among the 3rd-party libraries are the standard C++ library, Qt5, FreeType,
  ncurses, libUSB, curl, lwip, and Mesa.

:_dde_linux/_:

  Device-driver environment for executing Linux kernel subsystems as
  user-level components. Besides hosting ports of generic Linux kernel
  subsystems such as the TCP/IP stack, it is the basis for many board-specific
  drivers hosted in other repositories.

:_dde_ipxe/_:

  Device-driver environment for executing network drivers of the iPXE project.

:_dde_bsd/_:

  Device-driver environment for audio drivers ported from OpenBSD.

:_dde_rump/_:

  Port of rump kernels, which are used to execute subsystems of the NetBSD
  kernel as user-level components.
  The repository contains a server that uses a rump kernel to provide
  various NetBSD file systems.

:_pc/_:

  Device drivers for x86 PC hardware. The _pc_ repository depends on the
  _dde_linux repository because drivers such as the USB stack, the
  Intel wireless stack, or the Intel graphics driver are based on the
  framework infrastructure of _dde_linux/_.

:_ports/_:

  Ports of 3rd-party applications.

:_gems/_:

  Components that use
  both native Genode interfaces as well as features of other high-level
  repositories, in particular shared libraries provided by _libports/_.

In addition to the repositories hosted in Genode's main source tree, there
exist a number of external repositories that extend the framework with
optional features such as additional components and board support for various
hardware platforms.

:Additional repositories maintained by Genode Labs:

  [https://github.com/orgs/genodelabs/repositories]

Using the build system
======================

Genode relies on a custom tool chain, which can be downloaded at the following
website:

:Tool chain:

  [https://genode.org/download/tool-chain]

Build directory
---------------

The build system never touches the source tree but generates object
files, libraries, and programs in a dedicated build directory. We do not have a
build directory yet. For a quick start, let us create one using the following
command:

! cd <genode-dir>
! ./tool/create_builddir x86_64

_To follow the subsequent steps of test driving the Linux version of Genode,_
_the specified platform argument should match your host OS installation. If_
_you are using a 32-bit installation, specify 'x86_32' instead of 'x86_64'._

The command creates a new build directory at 'build/x86_64'.

Build configuration
-------------------

Before using the build directory, it is recommended to revisit and
possibly adjust the build configuration, which is located in the
_etc/_ subdirectory of the build directory, e.g., _build/x86_64/etc/_.
The _build.conf_ file contains global build parameters, in particular
the selection of source-code repositories to be incorporated, the kernel
to use ('KERNEL'), and the targeted board ('BOARD'). It is also
a suitable place for adding global build options. For example, for
enabling GNU make to use 4 CPU cores, use the following line in the
_build.conf_ file:

! MAKE += -j4

You may also consider speeding up your workflow by enabling the use of the
compiler cache ('ccache') using the following line:

! CCACHE := yes

Building components
-------------------

The recipe for building a component has the form of a _target.mk_ file
within the _src/_ directory of one of the source-code repositories.
For example, the _target.mk_ file of the init component is located
at _<genode-dir>/repos/os/src/init/target.mk_. To build the component, execute
the following command from within the build directory:

! make init

The argument "init" refers to the path relative to the _src/_ subdirectory.
The build system determines and builds all targets found under this path in
all source-code repositories.
When the build the is finished, the resulting executable binary can be found
in a subdirectory that matches the target's path. Additionally, the build
system installs a symbolic link in the _bin/_ subdirectory that points to the
executable binary.

If the specified path contains multiple _target.mk_ files in different
subdirectories, the build system builds all of them. For example, the
following command builds all targets found within one of the
_<repo>/src/drivers/_ subdirectories:

! make drivers

Furthermore, it is possible to specify multiple targets at once. The following
command builds both the init component and the nitpicker GUI server component:

! make init server/nitpicker

A simple system scenario
========================

The build directory offers much more than an environment for building
components. It supports the automation of system-integration work flows,
which typically include the following steps:

# Building a set of components,
# Configuring the static part of a system scenario,
# Assembling a boot directory with all ingredients needed by the scenario,
# Creating a boot image that can be loaded onto the target platform,
# Booting the target platform with the boot image,
# Validating the behavior of the scenario.

The recipe for such a sequence of steps can be expressed in the form of
a so-called run script. Each run script represents a system scenario and
entails all information required to reproduce the scenario. Run scripts can
reside within the _run/_ subdirectory of any source-code repository.

Genode comes with a ready-to-use run script showcasing a simple graphical demo
scenario. The run script is located at _<genode-dir>/repos/os/run/demo.run_.
It leverages Genode's package-management tools for assembling a static system
image.
The package management is explained in detail in Section [Package management].
For now, we can skip the details by instructing the build system to
automatically create packages and update their version numbers for us.
Uncomment the following line in the _build/x86_64/build.conf_ file:

! RUN_OPT += --depot-auto-update

In contrast to the building of individual components as described in the
previous section, the integration of a complete system scenario requires us to
select a particular OS kernel to use. The following command instructs the
build system to build, integrate, and start the "run/demo" scenario on the
Linux kernel:

! make run/demo KERNEL=linux BOARD=linux

The command prompts the build system to lookup a run script called _demo.run_
in all repositories listed in _etc/build.conf_.
It will eventually find the run script within the _os/_ repository. After
completing the build of all components needed, the command will then
automatically start the scenario.
Because the build directory was created for the _x86_64_ platform and we
specified "linux" as 'KERNEL', the scenario will be executed directly on the
host system where each Genode component resides in a distinct Linux process.
To explore the scenario, follow the instructions given by the graphical
tutorial browser.

The terminal where the 'make run/demo' command was issued displays the log
output of the Genode system. To cancel the execution,
hit _control-c_ in the terminal.

Targeting a microkernel
-----------------------

Whereas the ability to run system scenarios on top of Linux allows for the
convenient and rapid development of components and protocols, Genode is
primarily designed for the use of microkernels. The choice of the microkernel
to use is up to the user of the framework and may depend on various factors
like the feature set, the supported hardware architectures, the license, or
the development community. To execute the demo scenario directly on the NOVA
microhypervisor, the following preparatory steps are needed:

# Download the 3rd-party source code of the NOVA microhypervisor
  ! <genode-dir>/tool/ports/prepare_port nova

  The _prepare_port_ tool downloads the source code of NOVA to a
  subdirectory at _<genode-dir>/contrib/nova-<hash>/_ where _<hash>_
  uniquely refers to the prepared version of NOVA.

# On real hardware, the scenario needs a framebuffer driver. The VESA
  driver relies on a 3rd-party x86-emulation library in order to execute
  the VESA BIOS code. Download the 3rd-party source code of the _x86emu_
  library:
  ! <genode-dir>/tool/ports/prepare_port x86emu

  The source code will be downloaded to _<genode-dir>/contrib/x86emu-<hash>/_.

# To handle USB devices, a device-driver environment for executing a Linux
  kernel subsystem as a user-level component is used. Download the 3rd-party
  source code of the _dde_linux_ repository:
  ! <genode-dir>/tool/ports/prepare_port dde_linux linux

  The source code will be downloaded to
  _<genode-dir>/contrib/dde_linux-<hash>/_ and
  _<genode-dir>/contrib/linux-<hash>/_ respectively.

# To boot the scenario as an operating system on a PC, a boot loader is
  needed. The build process produces a bootable disk or ISO image
  that includes the GRUB2 boot loader as well as a working boot-loader
  configuration. Download the boot loader as ingredient for the image-creation
  step.

  ! <genode-dir>/tool/ports/prepare_port grub2

# Since NOVA supports the x86_64 architecture of our build directory, we
  can keep using the existing build directory that we just used for Linux.
  However, apart from enabling the parallelization of the build process as
  mentioned in Section [Using the build system], we need to incorporate the
  _libports_, _dde_linux_, and _pc_ source-code repositories into the build
  process by uncommenting the corresponding lines in the configuration.
  Otherwise the build system would fail to build the VESA and USB HID drivers,
  which reside within _libports/_, _dde_linux/_, and _pc/_ respectively.

With those preparations in place, issue the execution of the demo run
script from within the build directory:

! make run/demo KERNEL=nova BOARD=pc

This time, an instance of Qemu will be started to execute the demo scenario.
The Qemu command-line arguments appear in the log output. As suggested
by the arguments, the scenario is supplied to Qemu as an ISO image residing
at _var/run/demo.iso_. This ISO image can not only be used with Qemu but
also with a real machine. For example, creating a bootable USB stick with
the system scenario is as simple as writing the ISO image onto an USB stick:
! sudo dd if=var/run/demo.iso of=/dev/<usb-device> bs=8M conv=fsync

Note that _<usb-device>_ refers to the device node of an USB stick. It can be
determined using the 'dmesg' command after plugging-in the USB stick.
For booting from the USB stick, you may need to adjust the BIOS
settings of the test machine accordingly.

Hello world
===========

This section introduces the steps needed to create and execute a simple
custom component that prints a hello-world message.

Using a custom source-code repository
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In principle, it would be possible to add a new component to one of the
existing source-code repositories found at _<genode-dir>/repos/_. However,
unless the component is meant to be incorporated into upstream development
of the Genode project, it is generally recommended to keep custom code
separate from Genode's code base. This eases future updates to new versions
of Genode and allows you to pick a revision-control system of your choice.

The new repository must appear within the _<genode-dir>/repos/_ directory.
This can be achieved by either hosting it as a subdirectory or by creating
a symbolic link that points to an arbitrary location of your choice. For
now, let us host a new source-code repository called "lab" directly within
the _repos/_ directory.

! cd <genode-dir>
! mkdir repos/lab

The lab repository will contain the source code and build rules for a
single component as well as a run script for executing the component within
Genode. Component source code reside in a _src/_ subdirectory. By convention,
the _src/_ directory contains further subdirectories for hosting different
types of components, in particular _server_ (services and protocol stacks),
_drivers_ (hardware-device drivers), and _app_ (applications). For the
hello-world component, an appropriate location would be _src/app/hello/_:

! mkdir -p repos/lab/src/app/hello

Source code and build description
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The _hello/_ directory contains both the source code and the build description
of the component. The main part of each component typically resides in a
file called _main.cc_. Hence, for a hello-world program, we have to create
the _repos/lab/src/app/hello/main.cc_ file with the following content:

! #include <base/component.h>
! #include <base/log.h>
!
! void Component::construct(Genode::Env &)
! {
!   Genode::log("Hello world");
! }

The _base/component.h_ header contains the interface each component must
implement.
The 'construct' function is called by the component's execution environment
to initialize the component. The interface to the execution environment is
passed as argument. This interface allows the application code to interact
with the outside world. The simple example above merely produces a log
message. The 'log' function is defined in the _base/log.h_ header.

The component does not exit after the 'construct' function returns. Instead,
it becomes ready to respond to requests or signals originating from other
components. The example above does not interact with other components though.
Hence, it will just keep waiting infinitely.

Please note that there exists a recommended coding style for genuine Genode
components. If you consider submitting your work to the upstream development
of the project, please pay attention to these common guidelines.

:Coding-style guidelines:

  https://genode.org/documentation/developer-resources/coding_style

The source file _main.cc_ is accompanied by a build-description file called
_target.mk_. It contains the declarations for the source files, the libraries
used by the component, and the name of the component. Create the file
_repos/lab/src/app/hello/target.mk_ with the following content:

! TARGET = hello
! SRC_CC = main.cc
! LIBS  += base

Building the component
~~~~~~~~~~~~~~~~~~~~~~

With the build-description file in place, it is time to build the new
component, for example from within the _x86_64_ build directory as
created in Section [A simple system scenario]. To aid the build system
to find the component, we have to extend the build
configuration _<build-dir>/etc/build.conf_ by appending the following line:

! REPOSITORIES += $(GENODE_DIR)/repos/lab

By adding this line, the build system will consider our custom source-code
repository. To build the component, issue the following command:

! make app/hello

This step compiles the _main.cc_
file and links the executable ELF binary called "hello". The result can be
found in the _<build-dir>/app/hello/_ subdirectory.

Defining a system scenario
~~~~~~~~~~~~~~~~~~~~~~~~~~

For testing the component, we need to define a system scenario that
incorporates the component. As mentioned in
Section [A simple system scenario], such a description has the form of
a run script. To equip the _lab_ repository with a run script, we first
need to create a _lab/run/_ subdirectory:

! mkdir <genode-dir>/repos/lab/run

Within this directory, we create the file
_<genode-dir>/repos/lab/run/hello.run_ with the following content:

!build "core init app/hello"
!create_boot_directory
!install_config {
! <config>
!   <parent-provides>
!     <service name="LOG"/>
!     <service name="PD"/>
!     <service name="CPU"/>
!     <service name="ROM"/>
!   </parent-provides>
!   <default-route>
!     <any-service> <parent/> </any-service>
!   </default-route>
!   <default caps="100"/>
!   <start name="hello">
!     <resource name="RAM" quantum="10M"/>
!   </start>
! </config>
!}
!build_boot_image "core ld.lib.so init hello"
!append qemu_args "-nographic -m 64"
!run_genode_until {Hello world.*\n} 10

This run script performs the following steps:

# It builds the components core, init, and app/hello.
; XXX references to the Sections about core and init

# It creates a fresh boot directory at _<build-dir>/var/run/hello_.
  This directory contains all files that will end up in the final
  boot image.

# It creates a configuration for the init component. The configuration
  starts the hello component as the only child of init. Session
  requests originating from the hello component will always be directed
  towards the parent of init, which is core. The '<default>' node declares
  that each component may consume up to 100 capabilities.

# It assembles a boot image with the executable ELF binaries core,
  ld.lib.so (the dynamic linker), init, and hello. The binaries are picked up
  from the _<build-dir>/bin/_ subdirectory.

# It instructs Qemu (if used) to disable the graphical output.

# It triggers the execution of the system scenario and watches the log
  output for the given regular expression. The execution ends when
  the log output appears or after a timeout of 10 seconds.

The run script can be executed from within the build directory via the
command:

! make run/hello KERNEL=linux BOARD=linux

After the boot output of the used kernel, the scenario will produce the
following output:

! [init -> hello] Hello world
!
! Run script execution successful.

The label within the brackets at the start of each line identifies the
component where the message originated from. The final line is printed by the
run tool after it successfully matched the log output against the regular
expression specified to the 'run_genode_until' command.

[raw spec/clearpage]

Responding to external events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Most non-trivial components respond to external events such as user input,
timer events, device interrupts, the arrival of new data, or RPC requests
issued by other components.

The following example presents the typical skeleton of such a component.
The 'construct' function merely creates an object representing the application
as a 'static' local variable. The actual component code lives inside the
'Main' class.

! #include <base/component.h>
! #include <base/log.h>
! #include <timer_session/connection.h>
!
! namespace Hello { struct Main; }
!
! struct Hello::Main
! {
!   Genode::Env &_env;
!
!   Timer::Connection _timer { _env };
!
!   void _handle_timeout()
!   {
!     Genode::log("woke up at ", _timer.elapsed_ms(), " ms");
!   }
!
!   Genode::Signal_handler<Main> _timeout_handler {
!     _env.ep(), *this, &Main::_handle_timeout };
!
!   Main(Genode::Env &env) : _env(env)
!   {
!     _timer.sigh(_timeout_handler);
!     _timer.trigger_periodic(1000*1000);
!     Genode::log("component constructed");
!   }
! };
!
! void Component::construct(Genode::Env &env)
! {
!   static Hello::Main main(env);
! }

First, note the 'Hello' namespace. As a good practice, component code
typically lives in a namespace. The component-specific namespace may
incorporate other namespaces - in particular the 'Genode' namespace - without
polluting the global scope.

The constructor of the 'Main' object takes the Genode environment as argument
and stores it as the reference member variable '_env'. The member variable is
prefixed with an underscore to highlight the fact that it is
private to the 'Main' class. In principle, 'Main' could be a 'class' with '_env'
being part of the 'private' section, but as 'Main' is the top-level class of
the component that is not accessed by any other parts of the program, we use a
'struct' for brevity while still maintaining the convention to prefix private
members with an underscore character. When spotting the use of such a prefixed
variable in the code, we immediately see that it is part of the code's object
context, not being an argument or a local variable.

By aggregating a 'Timer::Connection' as a member variable, the 'Main' object
requests a session to a timer service at construction time. As this session
request requires an interaction with the outside world, the '_env' needs to
be passed to the '_timer' constructor.

In order to respond to events from the timer, the 'Main' class hosts a
'_timeout_handler' object. Its constructor arguments refer to the object and
a method to be executed whenever an event occurs. The timeout handler object is
registered at the '_timer' as the recipient of timeout events via the 'sigh'
method. Finally, the timer is instructed to trigger timeout events at a rate
of 1 second.

The following remarks are worth noting:

* The programming style expresses what the component _is_ rather than what
  the component _does_.

* The component does not perform any dynamic memory allocation.

* When called, the '_handle_timeout' method has its context (the 'Main' object)
  readily available, which makes the application of internal state changes as
  response to external events very natural.

* Neither the 'construct' function nor the 'Main::_handle_timeout' method
  blocks for external events.

* The component does not receive any indication about the number of occurred
  events, just the fact that at least one event occurred. The
  '_handle_timeout' code explicitly requests the current time from the
  timer driver via the synchronous RPC call 'elapsed_ms'.

To execute the new version of the component, we need to slightly modify the
run script.

!build "core init timer app/hello"
!create_boot_directory
!install_config {
! <config>
!   <parent-provides>
!     <service name="LOG"/>
!     <service name="PD"/>
!     <service name="CPU"/>
!     <service name="ROM"/>
!   </parent-provides>
!   <default-route>
!     <any-service> <parent/> <any-child/> </any-service>
!   </default-route>
!   <default caps="100"/>
!   <start name="timer">
!     <resource name="RAM" quantum="1M"/>
!     <provides> <service name="Timer"/> </provides>
!   </start>
!   <start name="hello">
!     <resource name="RAM" quantum="10M"/>
!   </start>
! </config>
!}
!build_boot_image "core ld.lib.so init timer hello"
!append qemu_args "-nographic -m 64"
!run_genode_until forever

The modifications are as follows:

* Since the hello component now relies on a timer service, we need to
  build and integrate a timer driver into the scenario by extending
  the 'build' and 'build_boot_image' steps accordingly.

* We instruct init to spawn the timer driver as an additional component
  by adding a '<start>' node to init's configuration. Within this node,
  we declare that the component provides a service of type "Timer".

* To enable the hello component to open a "Timer" session at the timer
  driver, the default route is modified to consider any children as
  servers whenever the requested service is not provided by the parent.

* This time, we let the scenario run forever so that we can watch the
  messages printed at periodic intervals.

When starting the run script, we can observe the periodic activation
of the component in the log output:

![init] child "timer" announces service "Timer"
![init -> hello] component constructed
![init -> hello] woke up at 12 ms
![init -> hello] woke up at 1008 ms
![init -> hello] woke up at 2005 ms
!...

Next steps
==========

There are several possible ways to continue your exploration.

# To form a *mental model* of how Genode works, give Chapter [Architecture]
  a read. In particular, Sections [Capability-based security],
  [Recursive system structure], [Resource trading], and
  [Inter-component communication] deserve your attention.
  Section [Component composition] nicely complements this theoretic material
  with a number of illustrative examples.

# If you are eager to see Genode's *potential* *unfolded*, try out
  the Genode-based operating system called Sculpt OS, which is available
  as a downloadable system image along with thorough documentation.

  :Sculpt OS:

    [https://genode.org/download/sculpt]

# Genode comprises a *feature set* of hundreds of ready-to-use components,
  which are fun to discover and to combine. Most components are not only
  accompanied with documentation in the form of README files local to the
  respective source code, but come with at least one ready-to-use run script
  or test package, which illustrates the integration of the component in
  executable form. After familiarizing yourself with the concept of run
  scripts by reading Section [System integration and automated testing],
  review the _run/_ and _recipes/pkg/_ subdirectories of the various
  source-code repositories, for example those at _repos/os/run/_ or
  _repos/gems/run/_.

# To follow the work of the Genode *community*, learn about current lines of
  work, plans, and experiences, head to the Genodians.org community blog.

  :Genodians.org:

    [https://genodians.org]


code:
Introduction
############

We are surrounded by operating systems.
Each device where multiple software functions are consolidated on a single
CPU employs some sort of operating system that multiplexes the physical
CPU for the different functions.
In our age when even mundane household items get connected to the internet,
it becomes increasingly hard to find devices where this is not the case.

; maybe we could replace CPU by "platform", "hardware", or "device"?
; that would include any hardware resource esp. RAM beside the CPU too.

Our lives and our society depend on an increasing number of such devices.
We have to trust them to fulfill their advertised functionality and
to not perform actions that are against our interests. But are those devices
trustworthy? In most cases, nobody knows that for sure. Even the device
vendors are unable to guarantee the absence of vulnerabilities or hidden
functions. This is not by malice. The employed commodity software stacks are
simply too complex to reason about them.
Software is universally known to be not perfect.
So we have seemingly come to accept the common practice where vendors
provide a stream of software and firmware updates that fix
vulnerabilities once they become publicly known.
Building moderately complex systems that are free from such issues appears to be
unrealistic.
Why is that?

Universal truths
----------------

The past decades have provided us with enough empirical evidence about
the need to be pragmatic about operating-system software.
For example,
high-assurance systems are known to be expensive and struggle to scale.
Consequently, under cost pressure, we can live without high assurance.
Security is considered as important. But at the point where the user gets
bothered by it, we have to be willing to compromise. Most users would agree that
guaranteed quality of service is desirable. But to attain good utilization
of cheap hardware, we have to sacrifice such guarantees.
Those universal truths have formed our expectations of commodity
operating system software.

[tikz img/assurance_vs_scalability]

In markets where vendors are held liable for the correctness of their
products, physical separation provides the highest assurance for the
independence and protection of different functions from each other.
For example, cars contain dozens of electronic control units (ECU) that
can be individually evaluated and certified. However, cost considerations
call for the consolidation of multiple functions on a single ECU.
At this point, separation kernels are considered to partition the
hardware resources into isolated compartments. Because the isolation is
only as strong as the correctness of the isolation kernel, such kernels
must undergo a thorough evaluation. In the face of being liable,
an oversight during the evaluation may have disastrous consequences for the
vendor. Each line of code to be evaluated is an expense. Hence, separation
kernels are minimized to the lowest possible complexity - up to only a
few thousand lines of code.

The low complexity of separation kernels comes at the cost of being
inflexible. Because the hardware resources are partitioned at
system-integration time,
dynamic workloads are hard to accommodate. The rigidity of the approach
stands in the way whenever the number of partitions, the assignment of
resources to partitions, and the software running in the partitions have to be
changed at runtime.

Even though the high level of assurance as provided by separation kernels is
generally desirable, flexibility and the support for dynamic workloads is even
more so. For this reason, commodity general-purpose OSes find their way into
all kinds of devices except into those where vendors are held liable for the
correctness of their products.
The former include not only household appliances, network gear, consumer
electronics, mobile devices, and certain comfort functions in vehicles but
also the IT equipment of governments, smart-city appliances, and surveillance
systems.
To innovate quickly, vendors accept to make their products reliant
on highly complex OS foundations. The trusted computing base (TCB) of all
commodity general-purpose operating systems is measured in millions of
lines of code. It comprises all the software components that must be trusted
to not violate the interests of the user. This includes the kernel, the
software executed at the system start, all background services with system
privileges, and the actual application software.
In contrast to separation kernels, any attempt to assess the correct functioning
of the involved code is shallow at best. The trustworthiness of such a
system remains uncertain to vendors and users alike.
The uncertainty that comes with the staggering TCB complexity becomes a
problem when such systems get connected to the internet:
Is my internet router under control of a bot net? Is my mobile phone remotely
manipulated to wiretap me? Is my TV spying on me when switched off? Are
my sensitive documents stored on my computer prone to leakage?
Faithfully, we hope the answers to those question to be no. But because
it is impossible to reason about the trusted computing base of the employed
operating systems, there are no answers.

Apparently, the lack of assurance must be the price to pay for the
accommodation of feature-rich dynamic workloads.

[tikz img/security_vs_ease_of_use]

The ease of use of software systems is often perceived as diametrical to
security. There are countless mundane examples: Remembering passwords
of sufficient strength is annoying. Even more so is picking a dedicated
password for each different purpose. Hence, users tend to become lax about
choosing and updating passwords. Another example is OpenPGP. Because setting
it up for secure email communication is perceived as complicated,
business-sensitive information is routinely exchanged unencrypted. Yet another
example is the lack of adoption of the security frameworks such as SELinux.
Even though they are readily available on commodity OS distributions,
comprehending and defining security policies is considered as a black art,
which is better left to experts.

How should an operating system strike the balance between being unusably
secure and user-friendly insecure?

[tikz img/utilization_vs_accountability]

Current-generation general-purpose OSes are designed to utilize physical
resources like memory, network bandwidth, computation time, and power in the
best way possible. The common approach to maximize utilization is the
over-provisioning of resources to processes. The OS kernel
pretends the availability of an unlimited amount of resources
to each process in the hope that processes will attempt to allocate and
utilize as much resources as possible. Its holistic view on all processes
and physical resources
puts the kernel in the ideal position to balance resources between processes.
For example, if physical memory becomes scarce, the kernel is able to uphold
the illusion of unlimited memory by temporarily swapping the memory content of
inactive processes to disk.

However, the optimization for high utilization comes at the price of
indeterminism and effectively makes modern commodity OSes defenseless
against denial-of-service attacks driven by applications.
For example, because the network load is not accounted to individual
network-using applications, a misbehaving network-heavy application is able
to degrade the performance of other network applications. As another
example, any GUI application is able to indirectly cause a huge memory
consumption at the GUI server by creating an infinite amount of windows. If
the system eventually runs out of memory, the kernel will identify the GUI
server as the offender.

With the help of complex heuristics like process-behaviour-aware schedulers,
the kernel tries hard to uphold the illusion of unlimited resources when
under pressure. But since the physical resources are ultimately limited, this
abstraction is destined to break sooner or later. If it breaks, the
consequences may be fatal: In an out-of-memory situation, the last resort
of the kernel is to rampage and kill arbitrary processes.

Can an operating system achieve high resource utilization while still being
dependable?

Clean-slate approach
--------------------

Surprisingly, by disregarding the practical considerations of existing
commodity operating systems, the contradictions outlined above can be
resolved by a combination of the following key techniques:

:Microkernels: as a middle ground between separation kernels and
  monolithic kernels are able to accommodate dynamic workloads without
  unreasonably inflating the trusting computing base.

:Capability-based security: supposedly makes security easy to use by
  providing an intuitive way to manage authority without the need for
  an all-encompassing and complex global system policy.

:Kernelization: of software components aids the deconstruction of
  complex software into low-complexity security-sensitive parts and
  high-complexity parts. The latter no longer need to be considered
  as part of the trusted computing base.

:Virtualization: can bridge the gap between applications that expect
  current-generation OSes and a new operating-system design.

:The management of budgets: within hierarchical organizations shows how
  limited resources can be utilized and still be properly accounted for.

None of those techniques is new by any means. However, they have never
been used as a composition of a general-purpose operating system. This
is where Genode comes into the picture.

[tikz img/app_specific_tcb]
  Application-specific trusted computing base

Application-specific trusted computing base
-------------------------------------------

A Genode system is structured as a tree of components where each component
(except for the root of the tree) is owned by its parent. The notion of
ownership means both responsibility and control. Being responsible for
its children, the parent has to explicitly provide the resources needed by
its children out of its own resources. It is also responsible to acquaint
children with one another and the outside world. In
return, the parent retains ultimate control over each of its children. As the
owner of a child, it has ultimate power over the child's environment, the
child's view of the system, and the lifetime of the child.
Each child can, in turn, have children, which yields a recursive system
structure. Figure [img/app_specific_tcb] illustrates the idea.

At the root of the tree, there is a low-complexity microkernel that is
always part of the TCB. The kernel is solely responsible to provide
protection domains, threads of execution, and the controlled communication
between protection domains. All other system functions such as device drivers,
network stacks, file systems, runtime environments, virtual machines,
security functions, and resource multiplexers are realized as components
within the tree.

The rigid organizational structure enables the system designer to
tailor the trusted computing base for each component individually. For
example, by hosting a cryptographic function nearby the root of the tree,
the function is exposed only to the microkernel but not to complex drivers
and protocol stacks that may exist in other branches of the tree. Figure
[img/app_specific_tcb] illustrates the TCB of one leaf node. The TCB of the
yellow component comprises the chain of parents and grandparents because it is
directly or indirectly owned by them. Furthermore, the TCB comprises a
service used by the component. But the right branch of tree is
unrelated to the component and can thereby disregarded from the yellow
component's TCB.

Trading and tracking of physical resources
------------------------------------------

Unlike traditional operating systems, Genode does not abstract from physical
resources. Instead, each component has a budget of physical resources
assigned by its parent. The budget allows the component to use the
resources within the budget or to assign parts of its budget to its children.
The usage and assignment of budgets is a deliberative decision by each
component rather than a global policy of the OS kernel.
Components are able to trade resource budgets along the branches
of the tree. This way, components can offer services to other components
without consuming their own resources. The dynamic trading of resource
budgets between components allows for a high resource utilization without
the over-provisioning of resources. Consequently, the system behavior
remains deterministic at all times.

Operating-system framework
==========================

The Genode OS framework is the implementation of the Genode architecture.
It is a tool kit for building highly secure
special-purpose operating systems. It scales from embedded systems with as
little as 4 MB of memory to highly dynamic general-purpose workloads.

The system is based on a recursive structure. Each program is executed in a
dedicated sandbox and gets granted only those access rights and resources that
are required to fulfill its specific purpose. Programs can create and manage
sub-sandboxes out of their own resources, thereby forming hierarchies where
policies can be applied at each level. The framework provides mechanisms to
let programs communicate with each other and trade their resources, but only
in strictly-defined manners. Thanks to this rigid regime, the attack surface
of security-critical functions can be reduced by orders of magnitude compared
to contemporary operating systems.

The framework aligns the construction principles of microkernels with Unix
philosophy.
In line with Unix philosophy, Genode is a collection of small building blocks,
out of which sophisticated systems can be composed. But unlike Unix, those
building blocks include not only applications but also all classical OS
functionalities including kernels, device drivers, file systems, and protocol
stacks.

:CPU architectures:

  Genode supports the x86 (32 and 64 bit), ARM (32 and 64 bit),
  and RISC-V (64 bit) CPU architectures.
  On x86, modern architectural features such as IOMMUs and
  hardware virtualization can be utilized.
  On ARM, Genode is able to take advantage of TrustZone and virtualization
  technology.

:Kernels:

  Genode can be deployed on a variety of different kernels including
  most members of the L4 family (NOVA, seL4, Fiasco.OC, OKL4 v2.1,
  L4ka::Pistachio, L4/Fiasco).
  Furthermore, it can be used on top of the Linux kernel to attain
  rapid development-test cycles during development.
  Additionally, the framework is accompanied with a custom microkernel that has
  been specifically developed for Genode and thereby further reduces the
  complexity of the trusted computing base compared to other kernels.

:Virtualization:

  Genode supports virtualization at different levels:
  * On NOVA, faithful virtualization via VirtualBox allows the execution of
    unmodified guest operating systems as Genode subsystems. Alternatively,
    the Seoul virtual machine monitor can be used to run unmodified
    Linux-based guest OSes.
  * On ARM, Genode can be used as TrustZone monitor, or as a virtual machine
    monitor that facilitates ARM's virtualization extensions.

:Building blocks:

  There exist hundreds of ready-to-use components such as
  * Device drivers for most common PC peripherals including networking,
    storage, display, USB, PS/2, Intel wireless, and audio output.
  * Device drivers for a variety of ARM-based SoCs, in particular the NXP i.MX
    family.
  * A GUI stack including a low-complexity GUI server, window management,
    and widget toolkits such as Qt5.
  * Networking components such as TCP/IP stacks and packet-level network
    services.
  * Applications based on the POSIX interface, including GNU coreutils, bash,
    GCC, binutils, and findutils.

Licensing and commercial support
================================

Genode is commercially supported by the German company Genode Labs GmbH, which
offers trainings, development work under contract, developer support, and
commercial licensing:

:Genode Labs website:

  [https://www.genode-labs.com]

The framework is available under two flavours of licences: an open-source
license and commercial licensing.
The primary license used for the distribution of the Genode OS framework is
the GNU Affero General Public License Version 3 (AGPLv3). In short, the AGPLv3
grants everybody the rights to

* Use the Genode OS framework without paying any license fee,
* Freely distribute the software,
* Modify the source code and distribute modified versions of the software.

In return, the AGPLv3 requires any modifications and derived work to be
published under the same or a compatible license. For the full license
text, refer to

:GNU Affero General Public License Version 3:

  [https://genode.org/about/LICENSE]

Note that the official license text accompanies the AGPLv3 with an additional
clause that clarifies our consent to link Genode with all commonly established
Open-Source licenses.

For applications that require more permissive licensing conditions than
granted by the AGPLv3, Genode Labs offers the option to commercially
license the technology upon request. Please write to _licensing@genode-labs.com_.

About this document
===================

This document is split into two parts. Whereas the first part contains the
textual description of the architectural and practical foundations, the second
part serves as a reference of the framework's programming interface. This
allows the first part to stay largely clear from implementation details.
Cross-references between both parts are used to connect the conceptual level
with the implementation level.

Chapter [Getting started] provides engineering-minded readers with
a practical jump start to explore the code and experiment with it.
These practical steps are good to get a first impression and will hopefully
provide the motivation to engage with the core part of the book, which are
the Chapters [Architecture] and [Components].

Chapter [Architecture]
introduces Genode's high-level architecture by presenting the concept of
capability-based security, the resource-trading mechanism, the root of the
component tree, and the ways how components can collaborate without mutually
trusting each other. Chapter [Components] narrows the view on different types
of components, namely device drivers, protocol stacks, resource multiplexers,
runtime environments, and applications. The remaining part of the chapter
focuses on the composition of components.

Chapter [Development] substantiates Chapter [Getting started] with all
information needed to develop meaningful components. It covers the
integration of 3rd-party software, the build system, the tool kit for
automated testing, and the Git work flow of the regular Genode developers.

Chapter [System configuration] addresses the system integration. After
presenting Genode's holistic configuration concept, it details the usage of
the init component, which bootstraps the static part of each Genode system.

Chapter [Under the hood] closes the first part with a look behind the scenes.
It provides the details and the rationales behind technical decisions,
explains the startup procedure of components, shows how Genode's concepts are
mapped to kernel mechanisms, and documents known limitations.

The second part of the document gives an overview of the framework's
C++ programming interface. The content is partially derived from the actual
source code and supplemented with additional background information.

Acknowledgements and feedback
-----------------------------

This document greatly benefited from the feedback of the community at the
Genode mailing list, the wonderful team at Genode Labs, the thorough review
by Adrian-Ken Rueegsegger and Reto Buerki, and several anonymous reviewers.
Thanks to everyone who contributed to the effort, be it in the form of reviews,
comments, moral support, or through projects commissioned to Genode Labs.

That said, feedback from you as the reader of the document is always
welcome. If you identify points you would like to see improved or
if you spot grammatical errors, please do not hesitate to contact the
author by writing to _norman.feske@genode-labs.com_ or to post your feedback
to the mailing list [https://genode.org/community/mailing-lists].

repo_name: Fhiss/genode


code:
proc title_tikz {} { return {\input{img/title.tikz}} }

### WRITE HEADER OF TEX FILE ###
proc produce_head_latex {} {
	global title authors

#	printline {\documentclass[11pt,a4paper,normalheadings,twoside,DIV12]{scrartcl}}
	printline {\documentclass[a4paper,normalheadings]{scrartcl}}
	printline {\usepackage[T1]{fontenc}}
	printline {\linespread{1.05} % avoid foot-note markers to mess up the line spacing}
	printline {\usepackage[norule,perpage]{footmisc}}
	printline {\usepackage{lmodern}}
	printline {\usepackage{ucs}}
	printline {\usepackage[utf8x]{inputenc}}
	printline {\usepackage[english]{babel}}
	printline {\usepackage[small,bf,hang]{caption}}
	printline {\usepackage{epsfig}}
	printline {\emergencystretch = 10pt}
	printline {\clubpenalty = 10000}
	printline {\widowpenalty = 300}
	printline {\displaywidowpenalty = 10000}
	printline {\usepackage{fancyhdr}}
	printline {\usepackage{palatino}}
	printline {\usepackage{helvet}}
	printline {\usepackage{courier}}
	printline {\usepackage{amsmath}}
	printline {\usepackage{amssymb}}
	printline {\usepackage{graphicx}}
	printline {\usepackage{color}}
	printline {\usepackage[scaled]{beramono}}
	printline "\\usepackage\[pdftex,pdfauthor={$authors},pdftitle={$title},pagebackref=true,colorlinks=true,linkcolor=darkblue,citecolor=darkblue,urlcolor=darkblue\]{hyperref}"
	printline {\usepackage{enumitem} % for colored items as used in spec }
	printline {\usepackage{tabularx} % for tables with paragraphs as used in spec }
	printline {\input{img/tikz-preamble.tex}}
	printline {\urlstyle{same}}

	printline {\begin{document}}

	printline {\input{img/tikz-common.tex}}

	printline {\definecolor{lightgray}{gray}{0.5}}
	printline {\definecolor{darkblue}{rgb}{0.1,0,0.55}}

	printline {\begin{titlepage}}
	printline {\thispagestyle{empty}}
	printline [title_tikz]
	printline {\end{titlepage}}

	printline "\\title{[out_latex $title]}"
	printline "\\author{[out_latex $authors]}"

	printline {\pagestyle{fancy}}
	printline {\fancyhf{}}
	printline {\fancyhead[RE]{\slshape \uppercase{\leftmark}}}
	printline {\fancyhead[LO]{\slshape \uppercase{\rightmark}}}
	printline {\fancyfoot[C]{\thepage \\ \vspace{1cm} \epsfig{file=img/genode_labs,angle=0,height=0.5cm}}}
	printline {\renewcommand{\footrulewidth}{0pt}}
	printline {\tableofcontents}
}

### WRITE TAIL OF TEX FILE ###
proc produce_tail_latex {} {
	printline "\\end{document}"
}

### CHAPTER ###
proc process_chapter_latex {txtblock} {
	global curr_chapter references
	global chapter_tag
	set title [linetxt [lindex $txtblock 0]]
	set curr_chapter $references($title,index)
	printline ""
	printline "%     -+*|\[ [string toupper $title] \]|*+-\n"
	printline "\\clearpage"
	printline "\\$chapter_tag[section_env_latex $title]"
	handle_txtblock chapter [lrange $txtblock 2 end]
}

### SECTION ###
proc process_section_latex {txtblock} {
	set title [linetxt [lindex $txtblock 0]]
	global section_tag
	printline ""
	printline "%     -+*|\[ [string toupper $title] \]|*+-\n"
	printline "\\clearpage"
	printline "\\$section_tag[section_env_latex $title]"
	handle_txtblock section [lrange $txtblock 2 end]
}

### ANNOTATION ###
proc process_annotation_latex {txtblock} {
	set new_txtblock {}
	foreach txtline $txtblock {
		set txtline [lineregsub {^\| ?} $txtline ""]
		lappend new_txtblock $txtline
	}
	printline "\\vspace{0.2cm}{\\setlength{\\parindent}{0cm} \\colorbox\[gray\]{0.9}{\\parbox{10cm}{ \\color{lightgray} \\footnotesize \\it"
	handle_txtblock annotation $new_txtblock
	printline "}}}\\vspace{0.2cm}"
}

### VERBATIM  ###
proc process_verbatim_latex {txtblock} {
	while {[lindex $txtblock end] == ""} {
		set txtblock [lrange $txtblock 0 [expr [llength $txtblock]-2]]
	}

	#
	# For the output of verbatim text, we use 'puts' rather than
	# 'printline' because 'printline' would indent the text, which
	# is not desired within a verbatim environment.
	#
	printline "\\begin{flushleft}"
	printline "\\begin{tikzpicture}"
	printline "\\node\[font=\\small] (verbatim) {"
	printline "\\begin{lstlisting}"
	foreach txtline $txtblock {
		set txt [linetxt $txtline]
		regsub     {^\!} $txt ""   txt
		regsub -all {\t} $txt "  " txt
		puts "$txt"
	}
	printline "\\end{lstlisting}"
	printline "};"
	printline "\\path\[very thick, draw=black!5\] (verbatim.north west) -- (verbatim.south west);"
	printline "\\end{tikzpicture}"
	printline "\\end{flushleft}"
}


code: : \clearpage \part{Foundations}


code: : \clearpage \part{Reference}


code:
usage:
	@echo "--- available targets ---"
	@echo "class_index.mk     - generate class index"
	@echo "class_descriptions - generate class descriptions"
	@echo "file_overviews     - generate file overviews"
	@echo "genode.git         - download Genode source code"
	@echo "all                - generate everything"
	@echo "clean              - clean downloaded and generated files"

VERBOSE ?= @

#
# Obtaining the Genode source code, from which to extract specification
#
# Unless GENODE_DIR is set manually (e.g., via the make command line), the
# source code is downloaded from the official Genode Git repository. The
# download is triggered via the class_index.mk dependency.
#

GENODE_GIT_URL := /home/no/src/genode
GENODE_GIT_REV := HEAD

ifeq ($(GENODE_DIR),)
GENODE_DIR := genode.git
class_index.mk: genode.git/checked_out.tag
clean: clean_local_genode_git
endif

genode.git:
	git clone $(GENODE_GIT_URL) $@

genode.git/checked_out.tag: genode.git
	cd genode.git; git reset --hard $(GENODE_GIT_REV)
	touch $@

clean_local_genode_git:
	rm -rf genode.git

#
# Definition of the parts of the source code that contains the functional
# specification. All header files in those directories are parsed using the
# genode/tool/parse_cxx tool. For each header, a file with the suffix .token
# is created, which contains the abstract syntax tree of the corresponding
# header file.
#

#define BASE_INCLUDE_DIRS
#  util
#  base
#endef

#define OS_INCLUDE_DIRS
#  os
#  util
#endef

define BASE_INCLUDE_DIRS
  base
  cpu
  cpu_session
  cpu_thread
  dataspace
  io_mem_session
  io_port_session
  irq_session
  log_session
  parent
  pd_session
  region_map
  rm_session
  rom_session
  root
  session
  trace_session
  util
  spec/32bit
  spec/64bit
  timer_session
endef

define OS_INCLUDE_DIRS
  audio_out_session
  block_session
  block
  file_system_session
  framebuffer_session
  capture_session
  gpio_session
  init
  input_session
  event_session
  nic_session
  uplink_session
  gui_session
  os
  packet_stream_rx
  packet_stream_tx
  platform_session
  report_session
  rtc_session
  sandbox
  terminal_session
  uart_session
  usb_session
  util
endef

GENODE_ABS_DIR := $(realpath $(shell echo $(GENODE_DIR)))

API_DIRS := $(addprefix repos/base/include/,$(BASE_INCLUDE_DIRS)) \
            $(addprefix repos/os/include/,$(OS_INCLUDE_DIRS))

SRC_H := $(shell test -d $(GENODE_DIR) && (cd $(GENODE_DIR); \
             for i in $(API_DIRS); do \
                 find $$i -name "*.h"; done))

# list of token files to generate
TOKEN_FILES := $(SRC_H:.h=.h.tokens)

$(SRC_H):
	$(VERBOSE)mkdir -p $(dir $@)
	$(VERBOSE)ln -sf $(GENODE_ABS_DIR)/$@ $@

%.h.tokens: %.h
	@echo "extract tokens from $^"
	$(VERBOSE)$(GENODE_ABS_DIR)/tool/parse_cxx -format tokens $^ > $@

#
# Generate class index
#

# include class index prior generated via the rule below
ifeq ($(filter clean,$(MAKECMDGOALS)),)
-include class_index.mk
endif

class_index.mk: $(TOKEN_FILES) Makefile gen_class_index util.tcl
	$(VERBOSE)echo "# generated by ./gen_class_index" > $@
	@for i in $(TOKEN_FILES); do \
		echo "generate class index of $$i"; \
		./gen_class_index $$i >> $@ ;done

#
# All rules as invoked by the top-level Makefile of the manual
#
# We process the generating steps in a separate make instance, which will
# include the class_index.mk file as producted by the initial instance.
#

all: class_index.mk
	make class_descriptions file_overviews

#
# Generate class descriptions
#
# Each class-description snippet contains a class overview and a box for each
# method with further details.
#

CLASS_DESCRIPTIONS := $(addprefix classes/,$(addsuffix /description.tex,$(CLASSES)))

$(CLASS_DESCRIPTIONS) : Makefile gen_class_description util.tcl latex.tcl

class_descriptions: $(CLASS_DESCRIPTIONS)

classes/%/diagram.tikz:
	$(VERBOSE)mkdir -p $(dir $@)
	@echo "generate class diagram for ${CLASS_NAME($*)}"
	$(VERBOSE)./gen_class_diagram --class "${CLASS_NAME($*)}" ${CLASS_HEADER($*)}.tokens > $@

classes/%/description.tex:
	$(VERBOSE)mkdir -p $(dir $@)
	@echo "generate class description for ${CLASS_NAME($*)}"
	$(VERBOSE)./gen_class_description --class "${CLASS_NAME($*)}" ${CLASS_HEADER($*)}.tokens > $@

#
# Generate file overviews
#
# The following headers contain types and free-standing functions that are not
# covered by the class descripton above.
#

FILE_OVERVIEW_HEADERS := repos/base/include/util/string.h \
                         repos/base/include/util/construct_at.h \
                         repos/base/include/base/blocking.h \
                         repos/base/include/base/cache.h \
                         repos/base/include/base/component.h \
                         repos/base/include/base/env.h \
                         repos/base/include/base/log.h \
                         repos/base/include/base/output.h \
                         repos/base/include/base/snprintf.h \
                         repos/base/include/base/stdint.h \
                         repos/base/include/spec/64bit/base/fixed_stdint.h \
                         repos/base/include/spec/32bit/base/fixed_stdint.h \
                         repos/base/include/rom_session/rom_session.h \
                         repos/base/include/io_mem_session/io_mem_session.h \
                         repos/os/include/file_system_session/file_system_session.h

FILE_OVERVIEWS := $(addsuffix .overview.tex,$(FILE_OVERVIEW_HEADERS))

$(FILE_OVERVIEWS) : $(FILE_OVERVIEW_HEADERS)

file_overviews: $(FILE_OVERVIEWS)

%.h.overview.tex: %.h.tokens
	@echo "generate file overview for $*"
	$(VERBOSE)./gen_file_overview $< > $@

#
# Clean rules
#

clean:
	rm -rf classes
	rm -rf repos
	rm -f class_index.mk

ALL_CLASS_NAMES = $(foreach C,$(CLASSES),${CLASS_NAME($C)})

check_spec_complete: class_index.mk
	@$(foreach C,$(ALL_CLASS_NAMES),\
	    (grep "$C" ../functional_specification.txt > /dev/null || \
	     echo "missing class description for '$C'");)

path: foundations/spec/Makefile


code:
#!/usr/bin/tclsh

#
# \brief  Generate class diagram
# \author Norman Feske
# \date   2015-03-17
#
# Usage ./gen_class_diagram --class <name> <tokens-file> > output.tikz
#

source util.tcl
source latex.tcl

#
# User interface interface
#
import_tokens [token_file]

set class_name [get_cmd_arg --class ""]

##
# Convert identifier to a sanitized string that can be used as tikz node name
#
proc tikz_node { identifier } {
	regsub -all {_} $identifier "" identifier
	regsub -all {::} $identifier "" identifier
	regsub -all {<} $identifier "" identifier
	regsub -all {>} $identifier "" identifier
	regsub -all { } $identifier "" identifier
	regsub -all {,} $identifier "" identifier
	return $identifier
}

##
# Return class name with template arguments stripped off
#
proc class_name_identifier { } {

	global class_name

	regexp {^[^<]+} $class_name class_name_identifier
	return $class_name_identifier
}

proc out_class_name { class_name } {

	set template_args ""
	regexp {<.*>} $class_name template_args

	regsub {^Genode::} [class_name_identifier] {} short_class_name

	return "[out_latex $short_class_name][out_latex $template_args]"
}

proc in_genode_namespace { class_name } {

	if {[regexp {^Genode::} $class_name]} { return 1 }
	return 0
}

proc out_linked_class_name { class_name } {

	set template_args ""
	regexp {<.*>} $class_name template_args

	regexp {^[^<]+} $class_name link_identifier

	#
	# If classes within the Genode namespace refer to other classes within
	# Genode, they usually omit the Genode:: namespace prefix. For the
	# huperlink, however, we need to fully quality the class name.
	# For a generic solution, we needed a cross-referencing database that
	# knows the C++ name-resolution rules.
	#
	if {[in_genode_namespace [class_name_identifier]] &&
	    ![in_genode_namespace $link_identifier]} {
		set link_identifier "Genode::$link_identifier"
	}

	regsub {^Genode::} $link_identifier {} short_class_name

	return "\\hyperlink{$link_identifier}{[out_latex $short_class_name]}\
	        [out_latex $template_args]"
}

proc generate_diagram { class_token } {

	puts {\begin{tikzpicture}}

	# base classes
	set base_classes [public_base_classes $class_token]
	set right_of_node ""

	foreach base_class $base_classes {

		puts "  \\node\[umlclass, draw opacity=0.4, text opacity=0.7, $right_of_node, node distance=10ex, inner sep=0.7ex\]"
		puts "    ([tikz_node $base_class]) {\\texttt{\\textbf{[out_linked_class_name $base_class]}}};"

		set right_of_node "right=3ex of [tikz_node $base_class]"
	}

	# positioning of the class node (depends on the presence of base classes)
	set class_below_of ""

	# compound node covering all base classes
	if {[llength $base_classes]} {
		puts -nonewline "  \\node\[fit="
		foreach base_class $base_classes {
			puts -nonewline "([tikz_node $base_class])" }
		puts "\] (baseclasses) {};"
		set class_below_of " below=3ex of baseclasses,"
	}

	# actual class below the base classes
	set has_members [class_has_members $class_token]

	set nodestyle "umlclass, inner sep=0.7ex,"
	if {$has_members} { set nodestyle "umlclass3, inner sep=0.7ex" }

	set template_args [class_template_arguments $class_token]

	puts "  \\node\[$nodestyle,$class_below_of\] (class) {"

	set class_name [class_name $class_token]
	puts "    \\texttt{\\textbf{[out_class_name $class_name]}}"

	if {$has_members} {
		puts "    \\nodepart{two}"

		# XXX no public attributes

		puts "    \\nodepart{three}"

		set members_sequence [public_and_protected_class_members $class_token]
		set first 1
		puts {    \begin{tabular}{ll}}
		foreach_sub_token $members_sequence plain { } token {
			if {[is_function $token]} {
				if {!$first} { puts "\\\\" }

				set params ""
				if {[llength [function_arguments $token]] > 0} {
					set params {$\ldots$} }

				set method_name [function_name $token]
				set method_link "$class_name\::$method_name"
				regsub -all {~} $method_link {Destructor} method_link
				set method_name_out [out_latex $method_name]
				if {[function_is_static $token]} {
					set method_name_out "\\underline{$method_name_out}" }
				set method_name_out "$method_name_out\($params)"
				if {[function_is_virtual $token]} {
					set method_name_out "\\textit{$method_name_out}" }
				set method_name_out "\\texttt{$method_name_out}"

				if {[method_is_interesting $token]} {
					puts "      \\hyperlink{$method_link}{$method_name_out}"
				} else {
					puts "       $method_name_out"
				}
				puts "     \\texttt{[out_latex [return_type_uml_style $token]]}"

				set first 0
			}
		}
		puts {    \end{tabular}}
	}
	puts "  };"

	# attach template arguments
	if {[llength $template_args] > 0} {

		set first 1
		set args ""
		foreach arg $template_args {

			if {!$first} { append args ", " }
			set arg_name [lindex $arg 0]
			if {$arg_name == ""} { set arg_name [lindex $arg 1] }
			append args "\\texttt{[out_latex $arg_name]}"
			set first 0
		}
		if {[string length $args] > 30} {
			regsub -all {,\s*} $args {,\\\\} args }

		puts "  \\path (class.north east) node\[align=left,anchor=south west, inner xsep=0.8ex, minimum size=3ex, xshift=-1.5ex, yshift=-1.5ex, umlclass, dashed\] {$args};"
	}

	# inheritance relationships
	if {[llength $base_classes]} {
		set index 0
		foreach base_class $base_classes {
			set angle [expr 90 - $index*10]
			puts "  \\path (class.$angle) -- coordinate (mid) ([tikz_node $base_class]);"
			puts "  \\path\[umlinherit\] (class.$angle) |- (mid) -| ([tikz_node $base_class]);"
			incr index
		}
	}

	# class infos
	set info_items {}
	if {[class_is_rpc_interface $class_token]} {
		lappend info_items "RPC interface"
	}

	if {[llength $info_items]} {
		set info [join $info_items "\\\\"]
		puts "  \\node\[umlinfo,right=5ex of class\] (info) {[out_latex $info]};"
		puts "  \\node\[left=5ex of class\] {}; % balance horizontal whitespace"
		puts "  \\path\[umlinfoline\] (class) -- (info);"
	}

	puts {\end{tikzpicture}}
}

proc method_prefix { method_token } {

	if {[is_function_template $method_token]} {
		set impl_token [sub_token $method_token funcimpl]
		if {$impl_token == ""} {
			set impl_token [sub_token $method_token constimpl] }

		if {$impl_token != ""} {
			set prefix [method_prefix $impl_token]
			return "$prefix template"
		}
		set prefix "method template"
	}

	set method_types {{funcdecl  method}
	                  {funcimpl  method}
	                  {constdecl constructor}
	                  {constimpl constructor}
	                  {destdecl  destructor}
	                  {destimpl  destructor}}

	foreach method_type $method_types {
		if {[tok_type $method_token] == [lindex $method_type 0]} {
			set prefix [lindex $method_type 1]

			if {[function_is_const $method_token]} {
				set prefix "const $prefix"
			}

			if {[function_is_static $method_token]} {
				set prefix "class function"
			}

			if {[function_is_virtual $method_token]} {
				set prefix "virtual $prefix"
			}

			if {[function_is_pure_virtual $method_token]} {
				set prefix "pure $prefix"
			}
		}
	}

	return $prefix
}

proc generate_method_description { namespace_name class_name method_token } {

	set method_name [function_name $method_token]
	set class_link  "$namespace_name\::$class_name"
	set method_link "$class_link\::$method_name"
	regsub -all {~} $method_link {Destructor} method_link

	puts "{ \\noindent \\raggedleft"
	puts -nonewline "\\hypertarget{$method_link}{\\hspace{0cm}}"
	puts {\begin{tikzpicture}[inner sep=0]}
	puts { \tikzstyle{every node} = [font=\small] }
	puts { \begin{apibox}{0.8,0.9,0.7}}

	# title
	set method_name_out [out_latex $method_name]
	if {[function_is_virtual $method_token]} {
		set method_name_out "\\textit{$method_name_out}" }
	if {[function_is_static $method_token]} {
		set method_name_out "\\underline{$method_name_out}" }
	puts "\\apimethodboxtitle{\\texttt{\\small \\strut [out_latex $namespace_name]}}"
	puts "  {\\texttt{\\small \\strut \\hyperlink{$class_link}{[out_latex $class_name]}}}"
	puts "  {\\texttt{\\textbf{\\small \\strut  $method_name_out}}}"
	puts "  {\\normalsize [out_latex [method_prefix $method_token]]}"

	generate_function_info_sections $method_token

	puts { \end{apibox}}
	puts "\\end{tikzpicture}"
	puts "}"

	generate_function_detail_section $method_token
}

proc generate_methods { class_token } {

	set namespace_name ""
	set class_name     ""
	regexp {(.*)::([^:]+)} [class_name $class_token] dummy namespace_name class_name

	set members_sequence [public_and_protected_class_members $class_token]
	foreach_sub_token $members_sequence plain { } token {

		if {[is_function $token] && [method_is_interesting $token]} {
			generate_method_description $namespace_name $class_name $token
		}
	}
}

set class_token [find_class_by_name content0 $class_name]

#puts {\noindent\rule{\textwidth}{0.1pt}}

puts "{ \\noindent \\raggedleft"
puts -nonewline "\\hypertarget{[class_name_identifier]}{"
puts {\begin{tikzpicture}[inner sep=0]}
puts { \tikzstyle{every node} = [font=\small] }
puts { \begin{apibox}{0.8,0.85,0.9}}

# title
# XXX distinguish template from regular classes (class_type)
set namespace_name ""
set only_class_name     ""
regexp {(.*)::([^:]+)} $class_name dummy namespace_name only_class_name
set annotation "class"
if {[is_class_template $class_token]} {
	set annotation "class template" }
puts "\\apiclassboxtitle{\\texttt{\\normalsize \\strut [out_latex $namespace_name]}}"
puts "  {\\texttt{\\textbf{\\normalsize \\strut [out_latex $only_class_name]}}}"
puts "  {\\normalsize [out_latex $annotation]}"

# brief description and diagram
set brief_description [brief_class_description $class_token]
if {$brief_description != ""} {
	puts "\\apiboxcontent{[out_latex [brief_class_description $class_token]]}" }
puts "\\apiboxcenteredcontent{"
puts { \tikzstyle{every node}+=[minimum size=0, inner sep=0.5ex, font=\footnotesize \sffamily]}
puts { \tikzstyle{dropshadow}+=[fill opacity=0.9, left color=white, right color=black!5]}
generate_diagram $class_token
puts "}"

# template arguments
if {[is_class_template $class_token]} {
	set arguments [class_template_arguments $class_token]
	generate_list_of_arguments $arguments "Template argument" "Template arguments"
}

set accessor_tokens [accessor_functions $class_token]
if {[llength $accessor_tokens] > 0} {
	set accessors_label "Accessor"
	if {[llength $accessor_tokens] > 1} { append accessors_label s }
	puts "\\apisection{$accessors_label}{0.95,0.95,0.95}"
	puts "\\apiboxcontent{"
	puts "  \\begin{minipage}{0.97\\textwidth}"
	puts "    \\begin{tabular}{ll}"
	set first 1
	foreach func_token $accessor_tokens {
		set acc_name    [function_name              $func_token]
		set acc_type    [function_return_type       $func_token]
		set acc_desc    [function_brief_description $func_token]
		if {!$first} { puts {\noalign{\smallskip}} }
		set first 0
		puts "      \\texttt{[out_latex $acc_name]} & \\texttt{\\textbf{[out_latex "$acc_type"]}}"
		puts "      \\\\"
		if {$acc_desc != ""} {
			puts "      & \\begin{minipage}{0.8\\textwidth}[out_latex $acc_desc]\\end{minipage}\\\\"
		}
	}
	puts "    \\end{tabular}"
	puts "  \\end{minipage}"
	puts "}"
}

generate_link_to_header

puts { \end{apibox}}
puts "\\end{tikzpicture} }}"
puts " "

# detailed description
set detailed_description [class_detailed_description $class_token]
if {[llength $detailed_description] > 0} {
	puts -nonewline "[out_latex [join $detailed_description {\\}]]"
	puts "\n"
}

generate_methods $class_token

puts ""


code:
#!/usr/bin/tclsh

#
# \brief  Generate class diagram
# \author Norman Feske
# \date   2015-03-17
#
# Usage ./gen_class_diagram --class <name> <tokens-file> > output.tikz
#

source util.tcl
source latex.tcl

#
# User interface interface
#
import_tokens [token_file]

set class_name [get_cmd_arg --class ""]

##
# Convert identifier to a sanitized string that can be used as tikz node name
#
proc tikz_node { identifier } {
	regsub -all {_} $identifier "" identifier
	regsub -all {::} $identifier "" identifier
	return $identifier
}

proc out_class_name { class_name } {

	regexp {^[^<]+} $class_name class_name_identifier

	# XXX separate template arguments

	regsub {^Genode::} $class_name_identifier {} short_class_name

	return "\\hyperlink{$class_name}{[out_latex $short_class_name]}"
}

proc generate_diagram {class_name} {

	set class_token [find_class_by_name content0 $class_name]

	puts {\begin{tikzpicture}}

	# base classes
	set base_classes [public_base_classes $class_token]
	set right_of_node ""
	foreach base_class $base_classes {

		puts "  \\node\[umlclass, draw opacity=0.4, text opacity=0.7, $right_of_node, node distance=10ex, inner sep=1ex\]"
		puts "    ([tikz_node $base_class]) {\\bf \\tiny \\sffamily [out_class_name $base_class]};"

		set right_of_node "right=3ex of [tikz_node $base_class]"
	}

	# positioning of the class node (depends on the presence of base classes)
	set class_below_of ""

	# compound node covering all base classes
	if {[llength $base_classes]} {
		puts -nonewline "  \\node\[fit="
		foreach base_class $base_classes {
			puts -nonewline "([tikz_node $base_class])" }
		puts "\] (baseclasses) {};"
		set class_below_of " below of=baseclasses,"
	}

	# actual class below the base classes
	puts "  \\node\[umlclass3,$class_below_of node distance=10ex\] (class) {"

	puts "    \\bf \\sffamily [out_class_name [class_name $class_token]]"
	puts "    \\nodepart{two}"

	# no public attributes

	puts "    \\nodepart{three}"

	# no public members

	puts "  };"

	# inheritance relationships
	if {[llength $base_classes]} {
		set index 0
		foreach base_class $base_classes {
			set angle [expr 90 - $index*10]
			puts "  \\path (class.$angle) -- coordinate (mid) ([tikz_node $base_class]);"
			puts "  \\path\[umlinherit\] (class.$angle) |- (mid) -| ([tikz_node $base_class]);"
			incr index
		}
	}

	puts {\end{tikzpicture}}
}

generate_diagram $class_name


code:
#!/usr/bin/tclsh

source util.tcl

import_tokens [token_file]

proc output_class_info { class_token } {

	set name_token [sub_token $class_token identifier]
	set name [unfold_token $name_token]

	#
	# Strip template arguments from class names so that they won't appear as
	# part of 'class_path' (needed for e.g., 'Rpc_object::Capability_guard').
	#
	regsub -all {<[^>]*>} $name "" name

	regsub -all {::} "[string tolower $name]" {/} class_path
	regsub -all {.} $class_path " " pad

	puts ""
	puts "CLASSES$pad        += $class_path"
	puts "CLASS_HEADER($class_path) := [header_file]"
	puts "CLASS_NAME($class_path)   := $name"
}

foreach_sub_token [tok_text content0] plain { } token {

	if {[tok_type $token] == "struct" || [tok_type $token] == "class"} {
		output_class_info $token
	}

	if {[tok_type $token] == "tplclass"} {
		set class_token [sub_token $token class]
		if {[llength $class_token]} {
			output_class_info $class_token }
	}

	if {[tok_type $token] == "tplstruct"} {
		set struct_token [sub_token $token struct]
		if {[llength $struct_token]} {
			output_class_info $struct_token }
	}
}


code:
#!/usr/bin/tclsh

#
# \brief  Generate header-file overview
# \author Norman Feske
# \date   2015-03-26
#
# Usage ./gen_file_overview <tokens-file> > output.tikz
#

source util.tcl
source latex.tcl

#
# User interface interface
#
import_tokens [token_file]

proc function_annotation { func_token } {

	if {[is_function_template $func_token]} {
		return "function template";
	}
	return "global function"
}

##
# Generate description of a global function
#
proc generate_function_description { namespace_name func_token } {

	set function_name [function_name $func_token]

	set link "$namespace_name\::$function_name"

	puts "{ \\noindent \\raggedleft"
	puts -nonewline "\\hypertarget{$link}{\\hspace{0cm}}"
	puts {\begin{tikzpicture}[inner sep=0]}
	puts { \tikzstyle{every node} = [font=\small] }
	puts { \begin{apibox}{1.0,0.85,0.6}}

	# title
	set function_name_out [out_latex $function_name]
	puts "\\apifunctionboxtitle{\\texttt{\\small \\strut [out_latex $namespace_name]}}"
	puts "  {\\texttt{\\textbf{\\small \\strut $function_name_out}}}"
	puts "  {\\normalsize [out_latex [function_annotation $func_token]]}"

	generate_function_info_sections $func_token

	puts { \end{apibox}}
	puts "\\end{tikzpicture} \\linebreak"
	puts "}"

	generate_function_detail_section $func_token
}

##
# Generate description boxes for specified namespace
#
proc generate_namespace_functions { namespace_name } {

	foreach func_token [namespace_functions $namespace_name] {
		generate_function_description $namespace_name $func_token
	}
}

proc generate_type_definitions { typedefs } {

	if {[llength $typedefs] > 0} {
		set section_label "Type"
		if {[llength $typedefs] > 1} { append section_label "s" }
		puts "\\apisection{$section_label}{0.95,0.95,0.95}"
		puts "\\apiboxcontent{"
		puts "  \\begin{tabularx}{0.96\\textwidth}{lX}"

		set first 0
		foreach typedef $typedefs {

			if {!$first} { puts {\noalign{\medskip}} }
			set first 0

			set typedef_type [lindex $typedef 0]
			set typedef_name [lindex $typedef 1]
			set typedef_def  [lindex $typedef 2]
			set typedef_desc [lindex $typedef 3]

			if {$typedef_type == "subtype"} {
				puts -nonewline "    \\texttt{\\textbf{[out_latex $typedef_name]}}"
				puts " & is a subtype of \\texttt{[out_latex "$typedef_def"]}\\\\"
			}

			if {$typedef_type == "typedef"} {
				puts -nonewline "    \\texttt{\\textbf{[out_latex $typedef_name]}}"
				puts " & is defined as \\texttt{[out_latex "$typedef_def"]}\\\\"
			}

			if {$typedef_type == "enum"} {
				puts -nonewline "    \\texttt{\\textbf{[out_latex $typedef_name]}}"
				puts " & is an enumeration type\\\\"
			}

			if {[llength $typedef_desc] > 0} {
				puts {\noalign{\medskip}}
				puts "   & [out_latex [lindex $typedef_desc 0]]\\\\"

				if {[llength $typedef_desc] > 1} {

					foreach part [lrange $typedef_desc 1 end] {
					puts {\noalign{\medskip}}
						puts "   & [out_latex $part]"
					}
				}
				puts "    \\\\"
			}
		}
		puts "  \\end{tabularx}"
		puts "}"
	}
}

# global scope
set global_typedefs [global_types]

if {[llength $global_typedefs] > 0} {

	puts -nonewline "{ \\noindent \\raggedleft"
	puts {\begin{tikzpicture}[inner sep=0]}
	puts { \tikzstyle{every node} = [font=\small] }
	puts { \begin{apibox}{1.0,0.95,0.78}}

	# title
	puts "\\apiglobalnamespaceboxtitle{\\normalsize root namespace}"

	# brief description
	set brief_description [header_brief_comment]
	if {$brief_description != ""} {
		puts "\\apiboxcontent{[out_latex $brief_description]}" }

	# type definitions
	generate_type_definitions $global_typedefs

	generate_link_to_header

	puts { \end{apibox}}
	puts "\\end{tikzpicture}"
	puts "}"
	puts ""
}

foreach namespace_name [namespaces_in_header] {

	puts -nonewline "{ \\noindent \\raggedleft"
	puts {\begin{tikzpicture}[inner sep=0]}
	puts { \tikzstyle{every node} = [font=\small] }
	puts { \begin{apibox}{1.0,0.95,0.78}}

	# title
	puts "\\apinamespaceboxtitle{\\texttt{\\textbf{\\normalsize \\strut [out_latex $namespace_name]}}}"
	puts "  {\\normalsize namespace}"

	# brief description
	set brief_description [header_brief_comment]
	if {$brief_description != ""} {
		puts "\\apiboxcontent{[out_latex $brief_description]}" }

	# types
	set typedefs [namespace_types $namespace_name]
	generate_type_definitions $typedefs

	# functions
	set function_tokens [namespace_functions $namespace_name]
	if {[llength $function_tokens] > 0} {
		set section_label "Function"
		if {[llength $function_tokens] > 1} { append section_label "s" }
		puts "\\apisection{$section_label}{0.95,0.95,0.95}"
		puts "\\apiboxcontent{ \\begin{minipage}{15cm}"
		puts "  \\begin{itemize}\[label={\\color{apifunction}\\textbullet}\] \\itemsep1pt \\parskip0pt"
		foreach func_token $function_tokens {
			set params ""
			if {[llength [function_arguments $func_token]] > 0} {
				set params {$\ldots$} }

			set name [function_name $func_token]
			set link "$namespace_name\::$name"
			set name_out [out_latex $name]
			set name_out "$name_out\($params)"

			puts "     \\item"
			puts -nonewline "       \\texttt{\\hyperlink{$link}{$name_out}"
			puts "\\ [out_latex [return_type_uml_style $func_token]]}"
		}
		puts "  \\end{itemize}"
		puts "\\end{minipage} }"
	}

	generate_link_to_header

	puts { \end{apibox}}
	puts "\\end{tikzpicture}"
	puts "}"

	generate_namespace_functions $namespace_name

	puts ""
}


code:
#
# \brief  Utilities for producing LaTeX output
# \author Norman Feske
# \date   2015-03-18
#
# Based on the code of GOSH
#

proc seal_repl {replace_string} {
	regsub -all {&} $replace_string {\\&} replace_string
	return $replace_string
}

proc out_latex {string} {
	global references

	set string " $string "

	# italic style
	while {[regexp {([ \"\(])_(.+?)_([ \)\.\",:!?\-])} $string dummy head_char emph_text tail_char]} {
		regsub {^_} $emph_text " " emph_text
		regsub {_$} $emph_text " " emph_text
		regsub {([ \"\(])_(.+?)_([ \)\.\",:!?\-])} $string [seal_repl "$head_char\\emph{$emph_text}$tail_char"] string
	}

	# bold style
	while {[regexp {([ \"\(])\*([^*]+?[^ ])\*([ \)\.\",:!?])} $string dummy head_char bf_text tail_char]} {
		regsub -all {\*} $bf_text " " bf_text
		regsub {([ \"\(])\*([^*]+?[^ ])\*([ \)\.\",:!?])} $string [seal_repl "$head_char\\textbf{$bf_text}$tail_char"] string
	}

	# monospace style
	while {[regexp {([ \"\(])\'(.+?)\'([ \-\)\.\"\',:!?])} $string dummy head_char code_text tail_char]} {
		regsub {([ \"\(])\'(.+?)\'([ \-\)\.\"\',:!?])} $string [seal_repl "$head_char\\texttt{$code_text}$tail_char"] string
	}

	regsub -all {_citation_gap_} $string "\[\\ldots\{\}\]" string
	regsub -all {"([\w\\])} $string "``\\1" string
	regsub -all {([\.\?\!\w\}])"} $string "\\1''" string
	regsub -all {\^} $string "\\^{ }" string
	regsub -all {_} $string "\\_" string
	regsub -all {#} $string "\\#" string
	regsub -all {%} $string "\\%" string
	regsub -all {\$} $string "\\$" string
	regsub -all {&} $string {\\&} string
	regsub -all {^ *} $string "" string
	regsub -all { *$} $string "" string
	regsub -all {~} $string {\\textasciitilde{}} string
	regsub -all {µ} $string "\$\\mu\$" string

	regsub -all {<->} $string "\$\\leftrightarrow\$" string
	regsub -all -- {->} $string "\$\\rightarrow\$" string
	regsub -all {<-} $string "\$\\leftarrow\$" string
	regsub -all {<=>} $string "\$\\Leftrightarrow\$" string
	regsub -all {=>} $string "\$\\Rightarrow\$" string
	regsub -all {<=} $string "\$\\Leftarrow\$" string

	regsub -all {<} $string "\\mbox{\$<\$}" string
	regsub -all {>} $string "\\mbox{\$>\$}" string

	regsub -all {e\.g\.} $string "e.\\,g." string
	regsub -all {i\.e\.} $string "i.\\,e." string

	set string [string map {{³} {\&}} $string]

	return $string
}

##
# Return string of the return type description as used in UML class diagrams
#
proc return_type_uml_style { func_token } {

	set return_type [function_return_type $func_token]
	if {$return_type == "void"} { set return_type "" }
	if {$return_type != ""} {
	set return_type ":\\ $return_type" }

	return $return_type
}

proc generate_list_of_arguments { arguments label_one label_multi } {

	if {[llength $arguments] != 0} {
		set arguments_label $label_one
		if {[llength $arguments] > 1} { set arguments_label $label_multi }
		puts "\\apisection{$arguments_label}{0.95,0.95,0.95}"

		puts "\\apiboxcontent{"
		puts "  \\begin{tabularx}{0.96\\textwidth}{lX}"
		set first 1
		foreach argument $arguments {
			set arg_name    [lindex $argument 0]
			set arg_type    [lindex $argument 1]
			set arg_default [lindex $argument 2]
			set arg_desc    [lindex $argument 3]
			if {!$first} { puts {\noalign{\medskip}} }
			set first 0
			puts "    \\texttt{[out_latex $arg_name]} & \\texttt{\\textbf{[out_latex "$arg_type"]}}"
			puts "    \\\\"
			if {$arg_desc != ""} {
				puts "    & [out_latex $arg_desc]\\\\"
			}
			if {$arg_default != ""} {
				puts "    & \\textit{Default is \\texttt{[out_latex $arg_default]}}\\\\"
			}
		}
		puts "  \\end{tabularx}"
		puts "} % apiboxcontent"
	}
}

proc generate_function_info_sections { func_token } {

	# brief description
	set brief_description [function_brief_description $func_token]
	if {$brief_description != ""} {
		puts "\\apiboxcontent{"
		puts "  \\begin{minipage}{10cm}"
		puts "    [out_latex $brief_description]"
		puts "  \\end{minipage}"
		puts "}"
	} else {
		puts "\\apiboxvspace{0.9ex}"
	}

	if {[is_function_template $func_token]} {
		set tplargs [function_template_arguments $func_token]
		generate_list_of_arguments $tplargs "Template argument" "Template arguments"
	}

	# arguments description
	set arguments [function_arguments $func_token]
	generate_list_of_arguments $arguments "Argument" "Arguments"

	# exceptions
	set exceptions [function_exceptions $func_token]
	if {[llength $exceptions] != 0} {
		set exceptions_label "Exception"
		if {[llength $exceptions] > 1} { append exceptions_label s }
		puts "\\apisection{$exceptions_label}{0.95,0.95,0.95}"
		puts "\\apiboxcontent{"
		puts "  \\begin{tabularx}{0.96\\textwidth}{lX}"
		foreach exception $exceptions {
			set exc_type [lindex $exception 0]
			set exc_desc [to_title [lindex $exception 1]]
			puts "    \\texttt{\\textbf{[out_latex $exc_type]}} & [out_latex "$exc_desc"]\\\\"
		}
		puts "  \\end{tabularx}"
		puts "}"
	}

	# return value
	set return_type [function_return_type $func_token]
	if {$return_type != "void" && $return_type != ""} {
		puts "\\apisection{Return value}{0.95,0.95,0.95}"
		puts "\\apiboxcontent{"
		puts "  \\begin{tabularx}{0.96\\textwidth}{lX}"
		set return_desc [function_return_description $func_token]
		puts "   \\texttt{\\textbf{[out_latex $return_type]}} & [out_latex "$return_desc"]\\\\"
		puts "  \\end{tabularx}"
		puts "}"
	}
}

proc generate_function_detail_section { func_token } {

	set detailed_description [function_detailed_description $func_token]
	if {[llength $detailed_description] > 0} {
		puts -nonewline "[out_latex [join $detailed_description {\\}]]"
		puts "\n"
	}
}

proc generate_link_to_header { } {
	puts "\\apisection{Header}{0.95,0.95,0.95}"
	puts "\\apiboxcontent{"
	puts " \\href{[code_url][header_file]}{\\textit{[out_latex [header_file]]}}"
	puts "}"
}