| 1 | = Bithenge Library = |
| 2 | |
| 3 | [[PageOutline(2-3)]] |
| 4 | |
| 5 | This page gives an overview of the [[Bithenge]] library API and internals. |
| 6 | Detailed documentation can be found in the source code’s Doxygen comments. |
| 7 | |
| 8 | == Conventions == |
| 9 | |
| 10 | === Names === |
| 11 | |
| 12 | All public functions and types have names starting with `bithenge_`. |
| 13 | |
| 14 | === Error handling === |
| 15 | |
| 16 | Almost all Bithenge functions return an integer error code. It will be EOK on |
| 17 | success or an error code from `errno.h` on failure. Even if an error occurs, |
| 18 | functions will still free or dereference their arguments as documented. |
| 19 | |
| 20 | === Reference counting === |
| 21 | |
| 22 | Nodes, expressions, transforms, and scopes use reference counting. For |
| 23 | instance, functions that produce a node (through a `bithenge_node_t **` |
| 24 | parameter) create a new reference to the node; you are responsible for ensuring |
| 25 | the reference count is eventually decremented. The reference count can be |
| 26 | incremented with `bithenge_xxx_inc_ref` and decremented with |
| 27 | `bithenge_xxx_dec_ref`. |
| 28 | |
| 29 | If a function’s documentation says it “takes [ownership of] a reference” to an |
| 30 | object, the function guarantees the object’s reference count will eventually be |
| 31 | decremented, even if an error occurs. Therefore, if you create an object only |
| 32 | to immediately pass it to such a function, you do not need to change its |
| 33 | reference count. |
| 34 | |
| 35 | === Polymorphism === |
| 36 | |
| 37 | Blob nodes, internal nodes, expressions, and transforms are polymorphic. We |
| 38 | will use transforms as an example, but the others are similar. Each transform |
| 39 | implementation has its own `struct`, including a `bithenge_transform_t` member, |
| 40 | and its own static `bithenge_transform_ops_t` instance. When a transform is |
| 41 | created, it calls `bithenge_transform_init` on the `bithenge_transform_t` and |
| 42 | gives it a pointer to the `bithenge_transform_ops_t` instance. It then returns |
| 43 | a pointer to the `bithenge_transform_t` to the caller. When the caller uses a |
| 44 | function on the `bithenge_transform_t *`, it automatically looks in the |
| 45 | `bithenge_transform_ops_t` for the transform‐specific implementation. |
| 46 | |
| 47 | == Main types == |
| 48 | |
| 49 | === Nodes === |
| 50 | |
| 51 | Integer, boolean, and string nodes are trivial. Blob and internal nodes are |
| 52 | polymorphic; each node has its own functions to access its contents. This means |
| 53 | calculating the node’s contents can be delayed until the contents are needed. |
| 54 | |
| 55 | === Transforms === |
| 56 | |
| 57 | The primary method of transforms is `apply`, which applies a transform to an |
| 58 | input tree and creates an output tree. When a transform takes a blob node as |
| 59 | input, it is sometimes necessary to determine the prefix of a given blob that |
| 60 | can be used as input to the transform; the method `prefix_length` can be used |
| 61 | for this. Alternatively, a `prefix_apply` method can do both at once, |
| 62 | substituting for or supplementing `apply` and `prefix_length`. All three of |
| 63 | these methods take a scope; see below. |
| 64 | |
| 65 | === Expressions === |
| 66 | |
| 67 | The only method of expressions is `evaluate`, which evaluates the expression in |
| 68 | a scope to create an output node. Expressions can be considered similar to |
| 69 | transforms, except that they have no input node. |
| 70 | |
| 71 | === Scopes === |
| 72 | |
| 73 | Scopes keep track of all information needed by transforms and expressions other |
| 74 | than transforms’ input trees. This includes parameters, nodes being created, |
| 75 | input nodes, and error messages. |
| 76 | |
| 77 | == Main functions == |
| 78 | |
| 79 | Aside from functions directly related to the types above, Bithenge has several |
| 80 | other important functions: |
| 81 | - `bithenge_parse_script` parses a Bithenge script file to create a transform. |
| 82 | - `bithenge_node_from_source` creates a node based on a string, such as |
| 83 | `block:bd/initrd`. |
| 84 | - `bithenge_print_node` prints nodes in human‐readable formats. |
| 85 | |
| 86 | The [https://bazaar.launchpad.net/~wtachi/helenos/bithenge/view/head:/uspace/app/bithenge/test.c test.c] |
| 87 | program included with Bithenge is a simple demonstration of all of these functions. |
| 88 | |
| 89 | == Testing == |
| 90 | |
| 91 | In HelenOS, Bithenge can be tested by running `batch test.bdsh` in the |
| 92 | `/src/bithenge` directory. If it runs to the end and prints "Success!", |
| 93 | Bithenge worked correctly on the example files. |
| 94 | |
| 95 | In Linux, more advanced testing is possible. Compile with |
| 96 | `COVERAGE=y FAILURE=y make` and run `test.sh` with Valgrind installed. Bithenge |
| 97 | will use failure injection to test much of the error handling code, in addition |
| 98 | to the main paths. |