= Bithenge Library = [[PageOutline(2-3)]] This page gives an overview of the [[Bithenge]] library API and internals. Detailed documentation can be found in the source code’s Doxygen comments. == Conventions == === Names === All public functions and types have names starting with `bithenge_`. === Error handling === Almost all Bithenge functions return an integer error code. It will be EOK on success or an error code from `errno.h` on failure. Even if an error occurs, functions will still free or dereference their arguments as documented. === Reference counting === Nodes, expressions, transforms, and scopes use reference counting. For instance, functions that produce a node (through a `bithenge_node_t **` parameter) create a new reference to the node; you are responsible for ensuring the reference count is eventually decremented. The reference count can be incremented with `bithenge_xxx_inc_ref` and decremented with `bithenge_xxx_dec_ref`. If a function’s documentation says it “takes [ownership of] a reference” to an object, the function guarantees the object’s reference count will eventually be decremented, even if an error occurs. Therefore, if you create an object only to immediately pass it to such a function, you do not need to change its reference count. === Polymorphism === Blob nodes, internal nodes, expressions, and transforms are polymorphic. We will use transforms as an example, but the others are similar. Each transform implementation has its own `struct`, including a `bithenge_transform_t` member, and its own static `bithenge_transform_ops_t` instance. When a transform is created, it calls `bithenge_transform_init` on the `bithenge_transform_t` and gives it a pointer to the `bithenge_transform_ops_t` instance. It then returns a pointer to the `bithenge_transform_t` to the caller. When the caller uses a function on the `bithenge_transform_t *`, it automatically looks in the `bithenge_transform_ops_t` for the transform‐specific implementation. == Main types == === Nodes === Integer, boolean, and string nodes are trivial. Blob and internal nodes are polymorphic; each node has its own functions to access its contents. This means calculating the node’s contents can be delayed until the contents are needed. === Transforms === The primary method of transforms is `apply`, which applies a transform to an input tree and creates an output tree. When a transform takes a blob node as input, it is sometimes necessary to determine the prefix of a given blob that can be used as input to the transform; the method `prefix_length` can be used for this. Alternatively, a `prefix_apply` method can do both at once, substituting for or supplementing `apply` and `prefix_length`. All three of these methods take a scope; see below. === Expressions === The only method of expressions is `evaluate`, which evaluates the expression in a scope to create an output node. Expressions can be considered similar to transforms, except that they have no input node. === Scopes === Scopes keep track of all information needed by transforms and expressions other than transforms’ input trees. This includes parameters, nodes being created, input nodes, and error messages. == Main functions == Aside from functions directly related to the types above, Bithenge has several other important functions: - `bithenge_parse_script` parses a Bithenge script file to create a transform. - `bithenge_node_from_source` creates a node based on a string, such as `block:bd/initrd`. - `bithenge_print_node` prints nodes in human‐readable formats. The [https://bazaar.launchpad.net/~wtachi/helenos/bithenge/view/head:/uspace/app/bithenge/test.c test.c] program included with Bithenge is a simple demonstration of all of these functions. == Testing == In HelenOS, Bithenge can be tested by running `batch test.bdsh` in the `/src/bithenge` directory. If it runs to the end and prints "Success!", Bithenge worked correctly on the example files. In Linux, more advanced testing is possible. Compile with `COVERAGE=y FAILURE=y make` and run `test.sh` with Valgrind installed. Bithenge will use failure injection to test much of the error handling code, in addition to the main paths.