]> git.corax.cc Git - toolbox/commitdiff
docs: Add module reference
authorMatthias Kruk <m@m10k.eu>
Sun, 9 Oct 2022 04:22:47 +0000 (13:22 +0900)
committerMatthias Kruk <m@m10k.eu>
Sun, 1 Jan 2023 06:18:25 +0000 (15:18 +0900)
None of the modules and functions in toolbox are documented. Thus,
users have to read the source code to understand how functions work,
and to find out what functions are there to begin with.

This commit adds a module reference, documenting modules and the
functions that they implement. The following modules are documented
in the reference:

 - array
 - conf
 - mutex
 - wmutex
 - git
 - inst
 - queue
 - opt
 - is
 - sem
 - json
 - log

14 files changed:
README.md
docs/array.md [new file with mode: 0644]
docs/conf.md [new file with mode: 0644]
docs/git.md [new file with mode: 0644]
docs/inst.md [new file with mode: 0644]
docs/is.md [new file with mode: 0644]
docs/json.md [new file with mode: 0644]
docs/log.md [new file with mode: 0644]
docs/mutex.md [new file with mode: 0644]
docs/opt.md [new file with mode: 0644]
docs/queue.md [new file with mode: 0644]
docs/reference.md [new file with mode: 0644]
docs/sem.md [new file with mode: 0644]
docs/wmutex.md [new file with mode: 0644]

index 880ef03669a785c9675c7a56f7c1df2e23fab65f..733b47f7c37a319d6b38bfadbd7a75b819886ebb 100644 (file)
--- a/README.md
+++ b/README.md
@@ -65,6 +65,8 @@ used for.
 | uipc   | Message-based IPC (unsigned messages) |
 | wmutex | Weak (owner-less) locks |
 
+Modules are described in detail in the [module reference](docs/reference.md)
+
 
 ## Installation
 
diff --git a/docs/array.md b/docs/array.md
new file mode 100644 (file)
index 0000000..c718304
--- /dev/null
@@ -0,0 +1,194 @@
+# The array module
+
+The array module implements functions for sorting, searching,
+printing, and comparing arrays.
+
+### Dependencies
+
+The array module does not depend on other modules.
+
+### Function index
+
+| Function                              | Purpose                                       |
+|---------------------------------------|-----------------------------------------------|
+| [array_contains()](#array_contains)   | Check if an element is in an array            |
+| [array_identical()](#array_identical) | Check if two arrays are identical             |
+| [array_same()](#array_same)           | Check if two arrays contain the same elements |
+| [array_sort()](#array_sort)           | Sort an array                                 |
+| [array_to_lines()](#array_to_lines)   | Print an array, one element per line          |
+
+
+## array_contains()
+
+Check whether an element is contained in an array.
+
+### Synopsis
+
+    array_contains "$element" "${array[@]}"
+
+### Description
+
+The `array_contains()` function checks whether `element` is contained in `array`.
+It does so by iterating over the array, comparing each element in the array with
+`element`.
+
+### Return value
+
+| Return value | Meaning                                |
+|--------------|----------------------------------------|
+| 0            | The element is contained in the array  |
+| 1            | The element was not found in the array |
+
+### Standard input
+
+`array_contains()` does not read from standard input.
+
+### Standard output
+
+`array_contains()` does not write to standard output.
+
+### Standard error
+
+`array_contains()` does not write to standard error.
+
+
+## array_identical()
+
+Checks if two arrays are identical.
+
+### Synopsis
+
+    array_identical left right
+
+### Description
+
+The `array_identical()` function checks whether the elements in the arrays
+referenced by `left` and `right` are identical. That means, it checks if the
+two arrays contain the same elements in the same order.
+The parameters `left` and `right` are name references to the arrays to be
+compared.
+
+### Return value
+
+| Return value | Meaning                      |
+|--------------|------------------------------|
+| 0            | The arrays are identical     |
+| 1            | The arrays are not identical |
+
+### Standard input
+
+`array_identical()` does not read from standard input.
+
+### Standard output
+
+`array_identical()` does not write to standard output.
+
+### Standard error
+
+`array_identical()` does not write to standard error.
+
+
+## array_same()
+
+Check if two arrays contain the same elements.
+
+### Synopsis
+
+    array_same left right
+
+### Description
+
+The `array_same()` function checks whether the arrays referenced by `left`
+and `right` contain the same elements. That means, it checks if the arrays
+are permutations.
+The parameters `left` and `right` are name references to the arrays to be
+compared.
+
+### Return value
+
+| Return value | Meaning                                     |
+|--------------|---------------------------------------------|
+| 0            | The arrays contain the same elements        |
+| 1            | The arrays do not contain the same elements |
+
+### Standard input
+
+`array_same()` does not read from standard input.
+
+### Standard output
+
+`array_same()` does not write to standard output.
+
+### Standard error
+
+`array_same()` does not write to standard error.
+
+
+## array_sort()
+
+Sort an array.
+
+### Synopsis
+
+    array_sort "${array[@]}"
+
+### Description
+
+The `array_sort()` function sorts the elements of `array` and outputs the
+result to standard output. The elements are sorted using a natural number
+sort, similar to the `sort -V` command from GNU Coreutils.
+If the array is empty, nothing will be written to standard output.
+
+### Return value
+
+| Return value | Meaning                   |
+|--------------|---------------------------|
+| 0            | Success (always returned) |
+
+### Standard input
+
+`array_sort()` does not read from standard input.
+
+### Standard output
+
+The sorted array is written to standard output, one element per line.
+
+### Standard error
+
+`array_sort()` does not write to standard error.
+
+
+## array_to_lines()
+
+Print an array, one element per line.
+
+### Synopsis
+
+    array_to_lines "${array[@]}"
+
+### Description
+
+The `array_to_lines()` function outputs `array` to standard output, writing
+each element in the array to a separate line. The elements of the array are
+output as-is, meaning that an empty string in the array will cause an empty
+line to be written. The elements will be written in their order in the array.
+If the array is empty, nothing will be written to standard output.
+
+### Return value
+
+| Return value | Meaning                   |
+|--------------|---------------------------|
+| 0            | Success (always returned) |
+
+### Standard input
+
+`array_to_lines()` does not read from standard input.
+
+### Standard output
+
+`array_to_lines()` writes one line per array element to standard output. If
+the array is empty, nothing will be written.
+
+### Standard error
+
+`array_to_lines()` does not write to standard error.
diff --git a/docs/conf.md b/docs/conf.md
new file mode 100644 (file)
index 0000000..f7fb93f
--- /dev/null
@@ -0,0 +1,201 @@
+# The conf module
+
+The conf module implements primitive configuration handling. This module
+allows the caller to load and store configuration values without having
+to worry about configuration files and other implementation details.
+
+Settings are stored per-script, meaning that one script will not be able
+to load and store settings from another script. Settings are further kept
+in *configuration domains*, which are namespaces, allowing a script to
+have different configuration profiles.
+
+### Dependencies
+
+ * [log](log.md)
+
+### Function index
+
+| Function                                | Purpose                       |
+|-----------------------------------------|-------------------------------|
+| [conf_get()](#conf_get)                 | Get the value of a setting    |
+| [conf_get_domains()](#conf_get_domains) | List all setting domains      |
+| [conf_get_names()](#conf_get_names)     | List all settings in a domain |
+| [conf_set()](#conf_set)                 | Set the value of a setting    |
+| [conf_unset()](#conf_unset)             | Remove a setting              |
+
+
+## conf_get()
+
+Get the value of a setting.
+
+### Synopsis
+
+    conf_get "$name" "$domain"
+
+### Description
+
+The `conf_get()` function retrieves the configuration setting identified by
+the name `$name` from the domain `$domain`. If `$domain` is omitted, the
+value from the domain `default` is retrieved.
+
+### Return value
+
+| Return value | Meaning                                        |
+|--------------|------------------------------------------------|
+| 0            | The value of the setting was successfully read |
+| 1            | The setting was not found                      |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+On success, the value of the setting is written to standard output. No data
+will be written if the setting was not found.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## conf_get_domains()
+
+List all setting domains.
+
+### Synopsis
+
+    conf_get_domains
+
+### Description
+
+The `conf_get_domains()` function returns the names of all configuration
+domains for the script. If the script does not have any settings, no names
+will be returned.
+If configuration domains for the script have been defined, their names will
+be written to standard output, one domain per line.
+
+### Return value
+
+| Return value | Meaning                   |
+|--------------|---------------------------|
+| 0            | Success (always returned) |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+If configuration domains have been defined for the caller, the names of
+the domains will be written to standard output, one domain per line.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## conf_get_names()
+
+List all settings in a domain.
+
+### Synopsis
+
+    conf_get_names "$domain"
+
+### Description
+
+The `conf_get_names()` function writes the names of all settings that
+have been stored in the configuration domain identified by `$domain`
+to standard output. If no settings have been defined in the domain, no
+data will be written. If `$domain` was omitted, this function will
+output the names of the settings in the default domain.
+
+### Return value
+
+| Return value | Meaning                                  |
+|--------------|------------------------------------------|
+| 0            | The domain contains settings             |
+| 1            | The domain does not contain any settings |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+Upon success, this function will write the names of settings to
+standard output, one name per line. Otherwise, no data will be
+written.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## conf_set()
+
+Set the value of a setting.
+
+### Synopsis
+
+    conf_set "$name" "$value" "$domain"
+
+### Description
+
+The `conf_set()` function sets the value of the setting `$name`
+in the domain `$domain` to `$value`. If `$domain` was omitted,
+the setting in the `default` domain will be set.
+
+### Return value
+
+| Return value | Meaning                                     |
+|--------------|---------------------------------------------|
+| 0            | The setting was written successfully        |
+| 1            | The setting could not be written to storage |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## conf_unset()
+
+Remove a setting.
+
+### Synopsis
+
+    conf_unset "$name" "$domain"
+
+### Description
+
+The `conf_unset()` function removes the setting with name `$name` from
+the domain `$domain`. If `$domain` was omitted, the setting will be
+removed from the `default` domain.
+
+### Return value
+
+| Return value | Meaning                        |
+|--------------|--------------------------------|
+| 0            | The setting was removed        |
+| 1            | The setting could not be found |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
diff --git a/docs/git.md b/docs/git.md
new file mode 100644 (file)
index 0000000..1a8834d
--- /dev/null
@@ -0,0 +1,306 @@
+# The git module
+
+The git module implements functions for interacting with git
+repositories in the local file system.
+
+### Dependencies
+
+ * [log](log.md)
+
+### Function index
+
+| Function                                            | Purpose                               |
+|-----------------------------------------------------|---------------------------------------|
+| [git_clone()](#git_clone)                           | Clone a git repository                |
+| [git_commit()](#git_commit)                         | Commit a change to the current branch |
+| [git_branch_new()](#git_branch_new)                 | Create a new branch                   |
+| [git_branch_get_current()](#git_branch_get_current) | Get the name of the current branch    |
+| [git_branch_checkout()](#git_branch_checkout)       | Change the current branch             |
+| [git_merge()](#git_merge)                           | Merge one branch into another one     |
+| [git_push()](#git_push)                             | Push a branch to a remote             |
+| [git_remote_get()](#git_remote_get)                 | Get the URL of a remote               |
+
+
+## git_clone()
+
+Clone a git repository
+
+### Synopsis
+
+    git_clone "$source" "$destination"
+
+### Description
+
+The `git_clone()` function clones the repository specified by `$source` into the path specified
+by `$destination`. The source repository may be reachable via any protocol that is understood by
+git. The path specified in `$destination` must be on a local file system. It is not necessary
+that the destination path exists, however the executing user must have sufficient permissions to
+create the path, if it does not exist.
+
+### Return value
+
+| Return value | Meaning                                |
+|--------------|----------------------------------------|
+| 0            | The repository was successfully cloned |
+| 1            | The repository could not be cloned     |
+
+### Standard input
+
+`git_clone()` does not read from standard input.
+
+### Standard output
+
+`git_clone()` does not write to standard output.
+
+### Standard error
+
+If an error occurs, `git_clone()` will write an error message to standard error. The message
+that is written includes the standard output and standard error from the git command that was
+invoked by `git_clone()`.
+
+
+## git_commit()
+
+Commit a change to the current branch
+
+### Synopsis
+
+    git_commit "$repository" "$message"
+
+### Description
+
+The `git_commit()` function commits the changes that are staged in the repository specified by
+`$repository` to the repository's current branch. The commit message will be set to the value
+passed in `$message`.
+
+### Return value
+
+| Return value |                                                |
+|--------------|------------------------------------------------|
+| 0            | The staged changes were successfully committed |
+| 1            | The changes could not be committed             |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+In case of an error, `git_commit()` will write an error message to standard error. The message
+that is written includes the standard output and standard error from the git command that was
+invoked by `git_commit()`.
+
+## git_branch_new()
+
+Create a new branch
+
+### Synopsis
+
+    git_branch_new "$repository" "$branch"
+
+### Description
+
+The `git_branch_new()` function creates a new branch with name `$branch` in the repository
+specified by `$repository`.
+
+### Return value
+
+| Return value | Meaning                             |
+|--------------|-------------------------------------|
+| 0            | The branch was created successfully |
+| 1            | The branch could not be created     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+In case of an error, `git_branch_new()` will write an error message to standard error. The message
+that is written includes the standard output and standard error from the git command that was
+invoked by `git_branch_new()`.
+
+
+## git_branch_get_current()
+
+Get the name of the current branch
+
+### Synopsis
+
+    git_branch_get_current "$repository"
+
+### Description
+
+The `git_branch_get_current()` function writes the name of the working branch of the repository
+specified by `$repository` to standard output. The repository must be located in the local file
+system and must not be a bare repository.
+
+### Return value
+
+| Return value | Meaning                                        |
+|--------------|------------------------------------------------|
+| 0            | The branch name was written to standard output |
+| 1            | The branch name could not be determined        |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+On success, the name of the repository's working branch is written to standard output. Otherwise,
+no data is written to standard output.
+
+### Standard error
+
+In case of an error, `git_branch_get_current()` will write an error message to standard error.
+
+
+## git_branch_checkout()
+
+Change the current branch
+
+### Synopsis
+
+    git_branch_checkout "$repository" "$branch"
+
+### Description
+
+The `git_branch_checkout()` function changes the working branch of the repository specified by
+`$repository` to the branch specified by `$branch`. The repository must be located in the local
+file system. If `$branch` was omitted, the `master` branch will be checked out.
+
+### Return value
+
+| Return value | Meaning                                     |
+|--------------|---------------------------------------------|
+| 0            | The working branch was successfully changed |
+| 1            | The working branch could not be changed     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+In case of an error, `git_branch_checkout()` will write an error message to standard error. The message
+that is written includes the standard output and standard error from the git command that was invoked
+by `git_branch_checkout()`.
+
+
+## git_merge()
+
+Merge one branch into another one
+
+### Synopsis
+
+    git_merge "$repository" "$source" "$destination"
+
+### Description
+
+The `git_merge()` function merges the branch `$source` of the repository `$repository` into the branch
+`$destination` of the same repository. If `$destination` was omitted, `$source` will be merged into the
+working branch of the repository.
+
+### Return value
+
+| Return value | Meaning                            |
+|--------------|------------------------------------|
+| 0            | The merge operation was successful |
+| 1            | The merge could not be performed   |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+In case of an error, `git_merge()` will write an error message to standard error. The message
+that is written includes the standard output and standard error from the git command that was
+invoked by `git_merge()`.
+
+
+## git_push()
+
+Push a branch to a remote
+
+### Synopsis
+
+    git_push "$repository" "$branch" "$remote"
+
+### Description
+
+The `git_push()` function pushes the branch `$branch` of the repository `$repository` to the
+remote `$remote`. If `$remote` was omitted, the branch will be pushed to the remote `origin`.
+If `$branch` was omitted, the working branch will be pushed.
+
+### Return value
+
+| Return value | Meaning                            |
+|--------------|------------------------------------|
+| 0            | The branch was pushed successfully |
+| 1            | The branch could not be pushed     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+In case of an error, `git_push()` will write an error message to standard error. The message that
+is written will include the standard output and standard error of the git command that was invoked
+by `git_push()`.
+
+
+## git_remote_get()
+
+Get the URL of a remote
+
+### Synopsis
+
+    git_remote_get "$repository" "$remote"
+
+### Description
+
+The `git_remote_get()` function determines the URL of the remote `$remote` of the repository
+`$repository` and writes it to standard output.
+
+### Return value
+
+| Return value | Meaning                                              |
+|--------------|------------------------------------------------------|
+| 0            | The URL of the remote was written to standard output |
+| 1            | The URL of the remote could not be determined        |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+On success, the URL of the remote is written to standard output. Otherwise, no data is written to
+standard output.
+
+### Standard error
+
+In case of an error, `git_remote_get()` will write an error message to standard error.
diff --git a/docs/inst.md b/docs/inst.md
new file mode 100644 (file)
index 0000000..3643b82
--- /dev/null
@@ -0,0 +1,367 @@
+# The inst module
+
+The inst module implements functions for writing daemons.
+
+### Dependencies
+
+ * [log](log.md)
+ * [opt](opt.md)
+ * [sem](sem.md)
+
+### Function index
+
+| Function                                                  | Purpose                                       |
+|-----------------------------------------------------------|-----------------------------------------------|
+| [inst_count()](#inst_count)                               | Count the running instances of a script       |
+| [inst_get_status()](#inst_get_status)                     | Get the status of an instance                 |
+| [inst_get_status_message()](#inst_get_status_message)     | Get the status message of an instance         |
+| [inst_get_status_timestamp()](#inst_get_status_timestamp) | Get the timestamp of an instance's status     |
+| [inst_list()](#inst_list)                                 | List running instances of a script            |
+| [inst_running()](#inst_running)                           | Return the state of the current instance      |
+| [inst_set_status()](#inst_set_status)                     | Set the status of the current instance        |
+| [inst_singleton()](#inst_singleton)                       | Start a unique instance of the current script |
+| [inst_start()](#inst_start)                               | Start an instance of the current script       |
+| [inst_stop()](#inst_stop)                                 | Stop an instance of a script                  |
+
+## inst_count()
+
+Count the running instances of a script
+
+### Synopsis
+
+    inst_count "$instname"
+
+### Description
+
+The `inst_count()` function counts the running instances of the script determined by `$instname` and writes
+the count to standard output.
+
+### Return value
+
+| Return value | Meaning                                          |
+|--------------|--------------------------------------------------|
+| 0            | The number of instances was successfully written |
+| 1            | The number of instances could not be determined  |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+Upon success, an integer value representing the number of running instances is written to standard output.
+Otherwise, no data is written to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## inst_get_status()
+
+Get the status of an instance
+
+### Synopsis
+
+    inst_get_status "$pid" "$instname"
+
+### Description
+
+The `inst_get_status()` function retrieves the status of the instance with pid `$pid` of the script
+`$instname` and writes it to standard output. If `$instname` is omitted, the status for the instance
+of the current script will be retrieved.
+
+### Return value
+
+| Return value | Meaning                                                |
+|--------------|--------------------------------------------------------|
+| 0            | The status was successfully written to standard output |
+| 1            | The status for the instance could not be retrieved     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+Upon success, the instance status is written to standard output. Otherwise, no data is written to standard
+output.
+
+### Standard error
+
+In case of an error, a message will be written to standard error.
+
+
+## inst_get_status_message()
+
+Get the status message of an instance
+
+### Synopsis
+
+    inst_get_status_message "$pid" "$instname"
+
+### Description
+
+The `inst_get_status_message()` function retrieves the status message of the instance with pid `$pid` of the
+script `$instname` and writes it to standard output. If `$instname` was omitted, the status for an instance
+of the executing script will be retrieved.
+
+### Return value
+
+| Return value | Meaning                                                |
+|--------------|--------------------------------------------------------|
+| 0            | The status was successfully written to standard output |
+| 1            | The status for the instance could not be retrieved     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+Upon success, the status message of the instance is written to standard output. Otherwise, no data is written
+to standard output.
+
+### Standard error
+
+In case of an error, a message will be written to standard error.
+
+
+## inst_get_status_timestamp()
+
+Get the timestamp of an instance's status
+
+### Synopsis
+
+    inst_get_status_timestamp "$pid" "$instname"
+
+### Description
+
+The `inst_get_status_timestamp()` retrieves the timestamp of the status of the instance with pid `$pid` of the
+script `$instname` and writes it to standard output. If `$instname` was omitted, the status for an instance of
+the executing script will be retrieved.
+
+### Return value
+
+| Return value | Meaning                                                   |
+|--------------|-----------------------------------------------------------|
+| 0            | The timestamp was successfully written to standard output |
+| 1            | The timestamp could not be retrieved                      |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+Upon success, an integer value representing the timestamp in UNIX-time is written to standard output.
+Otherwise, no data is written to standard output.
+
+### Standard error
+
+In case of an error, a message is written to standard output.
+
+
+## inst_list()
+
+List running instances of a script
+
+### Synopsis
+
+    inst_list "$instname"
+
+### Description
+
+The `inst_list()` function retrieves a list of running instances of the script `$instname` and writes it to
+standard output. If `$instname` was omitted, instances of the executing script will be returned.
+
+### Return value
+
+| Return value | Meaning                   |
+|--------------|---------------------------|
+| 0            | Success (always returned) |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+If running instances of the script were found, details about each of them will be written to standard output,
+one per line. The following is the format of each line.
+
+    OWNER STATE [STATUS_TIMESTAMP:STATUS_TEXT] INSTANCE_NAME ARGV0 ...
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## inst_running()
+
+Return the state of the current instance
+
+### Synopsis
+
+    inst_running
+
+### Description
+
+The `inst_running()` function determines the state of the executing script. Instances should use this function
+to determine whether they should stop execution. If this function returns a non-zero value, the calling
+instance has been requested to stop either by `inst_stop()` or a signal.
+
+### Return value
+
+| Return value | Meaning                                 |
+|--------------|-----------------------------------------|
+| 0            | The instance is running                 |
+| 1            | The instance has been requested to stop |
+
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+In case of an error, this function writes a message to standard error.
+
+
+## inst_set_status()
+
+Set the status of the current instance
+
+### Synopsis
+
+    inst_set_status "$status"
+
+### Description
+
+The `inst_set_status()` function sets the status of the executing instance to `$status`. The
+`inst_get_status_message()` and `inst_get_status_timestamp()` functions may be used to retrieve the status
+and the timestamp of the status, respectively.
+
+### Return value
+
+| Return value | Meaning                         |
+|--------------|---------------------------------|
+| 0            | The status was successfully set |
+| 1            | The status could not be set     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+In case of an error, this function writes a message to standard error.
+
+
+
+## inst_singleton()
+
+Start a unique instance of the current script
+
+### Synopsis
+
+    inst_singleton "${args[@]}"
+
+### Description
+
+The `inst_singleton()` function starts a unique instance of the executing script using the array passed in
+`$args` as the main function of the new instance. If another instance of the executing script is already
+running, no instance will be started.
+
+### Return value
+
+| Return value | Meaning                                                     |
+|--------------|-------------------------------------------------------------|
+| 0            | The instance was started                                    |
+| 1            | Another instance of the executing script is already running |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+In case of an error, this function writes a message to standard error.
+
+
+## inst_start()
+
+Start an instance of the current script
+
+### Synopsis
+
+    inst_start "${args[@]}"
+
+### Description
+
+The `inst_start()` function starts an instance of the executing script using the array passed in
+`$args` as the main function of the new instance.
+
+### Return value
+
+| Return value | Meaning                   |
+|--------------|---------------------------|
+| 0            | Success (always returned) |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## inst_stop()
+
+Stop an instance of a script
+
+### Synopsis
+
+    inst_stop "$pid" "$instname"
+
+### Description
+
+The `inst_stop()` function requests the instance with pid `$pid` of the script `$instname` to stop. If
+`$instname` was omitted, an instance of the executing script will be requested to stop. Note that the
+instance that was requested to stop is highly unlikely to be stopped by the time this function returns.
+
+### Return value
+
+| Return value | Meaning                                         |
+|--------------|-------------------------------------------------|
+| 0            | The instance was successfully requested to stop |
+| 1            | The instance could not be requested to stop     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+A message will be written to standard error if the instance does not exist.
diff --git a/docs/is.md b/docs/is.md
new file mode 100644 (file)
index 0000000..c2893c4
--- /dev/null
@@ -0,0 +1,278 @@
+# The is module
+
+The is module implements functions for checking the contents of strings.
+
+### Dependencies
+
+The is module does not depend on other modules.
+
+| Function                  | Purpose                                                 |
+|---------------------------|---------------------------------------------------------|
+| [is_alnum()](#is_alnum)   | Check if a string contains only alphanumeric characters |
+| [is_alpha()](#is_alpha)   | Check if a string contains only alphabet characters     |
+| [is_base64()](#is_base64) | Check if a string contains a base64-encoded value       |
+| [is_digits()](#is_digits) | Check if a string contains only digits                  |
+| [is_hex()](#is_hex)       | Check if a string contains a hexadecimal value          |
+| [is_int()](#is_int)       | Check if a string contains an integer value             |
+| [is_lower()](#is_lower)   | Check if a string contains only lower-case letters      |
+| [is_upper()](#is_upper)   | Check if a string contains only upper-case letters      |
+
+
+## is_alnum()
+
+Check if a string contains only alphanumeric characters
+
+### Synopsis
+
+    is_alnum "$str"
+
+### Description
+
+The `is_alnum()` function tests whether all characters in the string `$str` are alphanumeric.
+
+### Return value
+
+| Return value | Meaning                       |
+|--------------|-------------------------------|
+| 0            | The input is alphanumeric     |
+| 1            | The input is not alphanumeric |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## is_alpha()
+
+Check if a string contains only alphabet characters
+
+### Synopsis
+
+    is_alpha "$str"
+
+### Description
+
+The `is_alpha()` function tests whether all characters in the string `$str` are alphabet characters.
+
+### Return value
+
+| Return value | Meaning                     |
+|--------------|-----------------------------|
+| 0            | The input is alphabetic     |
+| 1            | The input is not alphabetic |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## is_base64()
+
+Check if a string contains a base64-encoded value
+
+### Synopsis
+
+    is_base64 "$str"
+
+### Description
+
+The `is_base64()` function tests whether the string `$str` contains a base64-encoded value. Aside of upper and
+lower-case alphabet letters and digits, `/` and `+` are considered part of the base64-alphabet. This function
+does not check if the length of the padding is correct.
+
+### Return value
+
+| Return value | Meaning                 |
+|--------------|-------------------------|
+| 0            | The input is base64     |
+| 1            | The input is not base64 |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## is_digits()
+
+Check if a string contains only digits
+
+### Synopsis
+
+    is_digits "$str"
+
+### Description
+
+The `is_digits()` function tests whether all characters in the string `$str` are digits.
+
+### Return value
+
+| Return value | Meaning                                 |
+|--------------|-----------------------------------------|
+| 0            | The input contains only digits          |
+| 1            | The input contains non-digit characters |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## is_hex()
+
+Check if a string contains a hexadecimal value
+
+### Synopsis
+
+    is_hex "$str"
+
+### Description
+
+The `is_hex()` function tests whether the string `$str` contains a hexadecimal value. The value must neither
+be prefixed with `0x` or `0X`, nor suffixed with `h` or `H`.
+
+### Return value
+
+| Return value | Meaning                      |
+|--------------|------------------------------|
+| 0            | The input is hexadecimal     |
+| 1            | The input is not hexadecimal |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## is_int()
+
+Check if a string contains an integer value
+
+### Synopsis
+
+    is_int "$str"
+
+### Description
+
+The `is_int()` function tests whether the string `$str` contains an integer value. This function is similar to
+`is_digits()`, except that it allows the value to be prefixed with a sign (either `+` or `-`).
+
+### Return value
+
+| Return value | Meaning                     |
+|--------------|-----------------------------|
+| 0            | The input is an integer     |
+| 1            | The input is not an integer |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## is_lower()
+
+Check if a string contains only lower-case letters
+
+### Synopsis
+
+    is_lower "$str"
+
+### Description
+
+The `is_lower()` function tests whether all characters in the string `$str` are lower-case alphabet letters.
+
+### Return value
+
+| Return value | Meaning                     |
+|--------------|-----------------------------|
+| 0            | The input is lower-case     |
+| 1            | The input is not lower-case |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## is_upper()
+
+Check if a string contains only upper-case letters
+
+### Synopsis
+
+    is_upper "$str"
+
+### Description
+
+The `is_upper()` function tests whether all characters in the string `$str` are upper-case alphabet letters.
+
+### Return value
+
+| Return value | Meaning                     |
+|--------------|-----------------------------|
+| 0            | The input is upper-case     |
+| 1            | The input is not upper-case |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
diff --git a/docs/json.md b/docs/json.md
new file mode 100644 (file)
index 0000000..83353c4
--- /dev/null
@@ -0,0 +1,234 @@
+# The json module
+
+The json module implements functions for creating and parsing JSON data.
+
+### Dependencies
+
+ * [array](array.md)
+ * [is](is.md)
+ * [log](log.md)
+
+### Function index
+
+| Function                                      | Purpose                                          |
+|-----------------------------------------------|--------------------------------------------------|
+| [json_array()](#json_array)                   | Create a JSON array                              |
+| [json_array_head()](#json_array_head)         | Get the first element from a JSON array          |
+| [json_array_tail()](#json_array_tail)         | Remove the first element from a JSON array       |
+| [json_array_to_lines()](#json_array_to_lines) | Get the elements from a JSON array, one per line |
+| [json_object()](#json_object)                 | Create a JSON object                             |
+| [json_object_get()](#json_object_get)         | Extract a field from a JSON object               |
+
+## json_array()
+
+Create a JSON array
+
+### Synopsis
+
+    json_array "${args[@]}"
+
+### Description
+
+The `json_array()` function creates a JSON array that is equivalent to the Bash array `$args` and writes
+it to standard output. This function attempts to parse values in `$args`, meaning that inputs that look
+like integer, floating-point, or other values will be converted to the corresponding types. If this is
+not desired, the caller must prefix values with type hints.
+
+| Prefix | Type        |
+|--------|-------------|
+| `s:`   | String      |
+| `i:`   | Integer     |
+| `b:`   | Bool        |
+| `f:`   | Float       |
+| `o:`   | JSON Object |
+| `a:`   | JSON Array  |
+
+### Return value
+
+| Return value | Meaning                            |
+|--------------|------------------------------------|
+| 0            | The array was written successfully |
+| 1            | The array could not be created     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+On success, the JSON array is written to standard output. Otherwise, no data will be written to standard
+output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## json_array_head()
+
+Get the first element from a JSON array
+
+### Synopsis
+
+    json_array_head "$array"
+
+### Description
+
+The `json_array_head()` function extracts the first element from the JSON array `$array` and writes it to
+standard output.
+
+### Return value
+
+| Return value | Meaning                                                 |
+|--------------|---------------------------------------------------------|
+| 0            | The element was written successfully to standard output |
+| 1            | The element could not be retrieved from the array       |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+Upon success, the first element of the array is written to standard output. Otherwise no data is written
+to standard output.
+
+### Standard error
+
+In case of an error, messages from an internal call to `jq` may be written to standard error.
+
+
+## json_array_tail()
+
+Remove the first element from a JSON array
+
+### Synopsis
+
+    json_array_tail "$array"
+
+### Description
+
+The `json_array_tail()` function creates a new JSON array with all but the first element of `$array`, and writes
+the new JSON array to standard output. The order of elements in the array is preserved.
+
+### Return value
+
+| Return value | Meaning                                                   |
+|--------------|-----------------------------------------------------------|
+| 0            | The new array was successfully written to standard output |
+| 1            | The new array could not be created                        |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+Upon success, the new JSON array is written to standard output. Otherwise no data is written to standard output.
+
+### Standard error
+
+In case of an error, messages from an internal call to `jq` may be written to standard error.
+
+
+## json_array_to_lines()
+
+Get the elements from a JSON array, one per line
+
+### Synopsis
+
+    json_array_to_lines "$array"
+
+### Description
+
+The `json_array_to_lines()` function retrieves the elements from the JSON array passed in `$array` and writes them
+to standard output, one element per line.
+
+### Return value
+
+| Return value | Meaning                           |
+|--------------|-----------------------------------|
+| 0            | The array was output successfully |
+| 1            | The array could not be parsed     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+Upon success, the elements from the array are written to standard output, one element per line. Otherwise, no data
+is written to standard output.
+
+### Standard error
+
+In case of an error, messages from an internal call to `jq` may be written to standard error.
+
+
+## json_object()
+
+Create a JSON object
+
+### Synopsis
+
+    json_object "$name0" "$value0" ...
+
+### Description
+
+The `json_object()` function creates a new JSON object using pairs of arguments as the names and values of fields in
+the object. If either the name or the value in a pair of arguments is the empty string, the pair will be skipped. The
+same rules as for the [json_array()](#json_array) function apply to this function. In particular, this means that
+values may need to be prefixed with type hints.
+An even number of arguments must be passed to this function.
+
+### Return value
+
+| Return value | Meaning                                                    |
+|--------------|------------------------------------------------------------|
+| 0            | The new object was successfully written to standard output |
+| 1            | The object could not be created                            |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+Upon success, the new JSON object is written to standard output. Otherwise no data is written to standard output.
+
+### Standard error
+
+In case of an error, this function may write a message to standard error.
+
+
+## json_object_get()
+
+Extract a field from a JSON object
+
+### Synopsis
+
+    json_object_get "$object" "$field"
+
+### Description
+
+The `json_object_get()` function extracts the field `$field` from the JSON object passed in `$object` and writes its
+value to standard output.
+
+### Return value
+
+| Return value | Meaning                                       |
+|--------------|-----------------------------------------------|
+| 0            | The value was written successfully            |
+| 1            | The field could not be parsed from the object |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+Upon success, the the value of the field is written to standard output. Otherwise no data is written to standard output.
+
+### Standard error
+
+In case of an error, messages from an internal call to `jq` may be written to standard error.
diff --git a/docs/log.md b/docs/log.md
new file mode 100644 (file)
index 0000000..10106d7
--- /dev/null
@@ -0,0 +1,377 @@
+# The log module
+
+The log module implements functions for logging and debugging with different log levels. A script that includes
+this module has a global log level that defaults to `__log_warning`, meaning that by default only warnings and
+errors will be logged. The log level may be adjusted to increase or decrease the amount of log messages.
+
+| Log level       | Meaning                                          |
+|-----------------|--------------------------------------------------|
+| `__log_debug`   | Log everything                                   |
+| `__log_info`    | Log errors, warnings, and informational messages |
+| `__log_warning` | Log errors and warnings (default)                |
+| `__log_error`   | Log only errors                                  |
+
+### Dependencies
+
+This module does not depend on other modules.
+
+### Function index
+
+| Function                                            | Purpose                                             |
+|-----------------------------------------------------|-----------------------------------------------------|
+| [log_debug()](#log_debug)                           | Log a debug message                                 |
+| [log_decrease_verbosity()](#log_decrease_verbosity) | Decrease the log level                              |
+| [log_error()](#log_error)                           | Log an error                                        |
+| [log_get_verbosity()](#log_get_verbosity)           | Get the current log level                           |
+| [log_highlight()](#log_highlight)                   | Highlight a message and write it to standard output |
+| [log_increase_verbosity()](#log_increase_verbosity) | Increase the log level                              |
+| [log_info()](#log_info)                             | Log an informational message                        |
+| [log_set_verbosity()](#log_set_verbosity)           | Change the current log level                        |
+| [log_stacktrace()](#log_stacktrace)                 | Write the call hierarchy to standard output         |
+| [log_warn()](#log_warn)                             | Log a warning                                       |
+
+
+## log_debug()
+
+Log a debug message
+
+### Synopsis
+
+    log_debug "${messages[@]}"
+    log_debug <<< "$messages"
+
+### Description
+
+The `log_debug()` function writes debug messages to standard error and the script's log file. If debug messages
+were passed as arguments, this function will treat each argument as a debug message. Otherwise, this function
+will read debug messages line-by-line from standard input.
+Each line of output is prefixed with a timestamp, log tag, as well as the name of the source file and the line
+number that the function was called from.
+
+Messages will only be logged if the current log level is `__log_debug` or above.
+
+### Return value
+
+| Return value | Meaning                              |
+|--------------|--------------------------------------|
+| 0            | The message was written successfully |
+| 1            | The message could not be logged      |
+
+### Standard input
+
+If this function is invoked without arguments, messages will be read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function will write one message per line to standard error.
+
+
+## log_decrease_verbosity()
+
+Decrease the log level
+
+### Synopsis
+
+    log_decrease_verbosity
+
+### Description
+
+The `log_decrease_verbosity()` function lowers the log level of the executing script by one step. If the log level
+is at `__log_error`, it will remain unchanged.
+
+### Return value
+
+| Return value | Meaning                   |
+|--------------|---------------------------|
+| 0            | Success (always returned) |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## log_error()
+
+Log an error
+
+### Synopsis
+
+    log_error "${messages[@]}"
+    log_error <<< "$messages"
+
+### Description
+
+The `log_error()` function writes error messages to standard error and the script's log file. If error messages
+were passed as arguments, this function will treat each argument as an error message. Otherwise, this function
+will read error messages line-by-line from standard input. Each line of output is prefixed with a timestamp and
+log tag.
+
+Error messages are always logged, regardless of the log level.
+
+### Return value
+
+| Return value | Meaning                              |
+|--------------|--------------------------------------|
+| 0            | The message was written successfully |
+| 1            | The message could not be logged      |
+
+### Standard input
+
+If this function is invoked without arguments, messages will be read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function will write one message per line to standard error.
+
+
+## log_get_verbosity()
+
+Get the current log level
+
+### Synopsis
+
+    log_get_verbosity
+
+### Description
+
+The `log_get_verbosity()` function writes the current log level to standard output.
+
+### Return value
+
+| Return value | Meaning                         |
+|--------------|---------------------------------|
+| 0            | Success (always returned)       |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+An integer value indicating the current log level is written to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## log_highlight()
+
+Highlight a message and write it to standard output
+
+### Synopsis
+
+    log_highlight "$tag" "${lines[@]}"
+    log_highlight "$tag" <<< "$lines"
+
+### Description
+
+The `log_highlight()` function adds markers with a tag `$tag` around the lines passed in `$lines` and writes them
+to standard output, making the lines easier to find in a large amount of log output.
+If no lines were passed as arguments, this function reads the data to be highlighted from standard input.
+
+### Return value
+
+| Return value | Meaning                   |
+|--------------|---------------------------|
+| 0            | Success (always returned) |
+
+### Standard input
+
+If this function is invoked without arguments, data to be highlighted will be read from standard input.
+
+### Standard output
+
+Highlighted data will be written to standard output.
+
+### Standard error
+
+This function may write a message to standard error if standard input is not readable.
+
+
+## log_increase_verbosity()
+
+Increase the log level
+
+### Synopsis
+
+    log_increase_verbosity
+
+### Description
+
+The `log_increase_verbosity()` function raises the log level of the executing script by one step. If the log level
+is at `__log_debug`, it will remain unchanged.
+
+### Return value
+
+| Return value | Meaning                   |
+|--------------|---------------------------|
+| 0            | Success (always returned) |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## log_info()
+
+Log an informational message
+
+### Synopsis
+
+    log_info "${messages[@]}"
+    log_info <<< "$messages"
+
+### Description
+
+The `log_info()` function writes informational messages to standard error and the script's log file. If messages
+were passed as arguments, this function will treat each argument as a message. Otherwise, this function will read
+messages line-by-line from standard input. Each line of output is prefixed with a timestamp and log tag.
+
+Messages will only be logged if the log level is `__log_info` or above.
+
+### Return value
+
+| Return value | Meaning                              |
+|--------------|--------------------------------------|
+| 0            | The message was written successfully |
+| 1            | The message could not be logged      |
+
+### Standard input
+
+If this function is invoked without arguments, messages will be read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function will write one message per line to standard error.
+
+
+## log_set_verbosity()
+
+Change the current log level
+
+### Synopsis
+
+    log_set_verbosity "$verbosity"
+
+### Description
+
+The `log_set_verbosity()` function sets the log level of the executing script to `$verbosity`. If the value passed in
+`$verbosity` is not a valid log level, the function will set it to the nearest valid log level.
+
+### Return value
+
+| Return value | Meaning                         |
+|--------------|---------------------------------|
+| 0            | Success (always returned)       |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## log_stacktrace()
+
+Write the call hierarchy to standard output
+
+### Synopsis
+
+    log_stacktrace
+
+### Description
+
+The `log_stacktrace()` function writes the call hierarchy of the calling function to standard output, allowing
+the user to determine where a particular function was called from. The output written to standard output includes
+file names, function names, and the line numbers that functions were called from. Indentation is used to visually
+highlight the nesting of function calls.
+
+### Return value
+
+| Return value | Meaning                         |
+|--------------|---------------------------------|
+| 0            | Success (always returned)       |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+The stacktrace of the calling function is written to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## log_warn()
+
+Log a warning
+
+### Synopsis
+
+    log_warn "${messages[@]}"
+    log_warn <<< "$messages"
+
+### Description
+
+The `log_warn()` function writes warning messages to standard error and the script's log file. If messages were
+passed as arguments, this function will treat each argument as a message. Otherwise, this function will read
+messages line-by-line from standard input. Each line of output is prefixed with a timestamp and log tag.
+
+Messages will only be logged if the log level is `__log_warning` or above.
+
+### Return value
+
+| Return value | Meaning                              |
+|--------------|--------------------------------------|
+| 0            | The message was written successfully |
+| 1            | The message could not be logged      |
+
+### Standard input
+
+If this function is invoked without arguments, messages will be read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function will write one message per line to standard error.
diff --git a/docs/mutex.md b/docs/mutex.md
new file mode 100644 (file)
index 0000000..2f3851a
--- /dev/null
@@ -0,0 +1,133 @@
+# The mutex module
+
+The mutex module implements a simple mechanism to enforce serial execution.
+The path from a mutex lock operation to its corresponding unlock operation is
+called a critical section, and is guaranteed to be executed serially.
+
+Critical sections limit the performance of parallel processes and should thus
+be as short as possible. Further, long and nested critical sections are prone
+to cause deadlocks and should be avoided.
+As a best practice, a critical section should not span multiple functions and
+there should be only one codepath that leads out of the critical section.
+
+### Dependencies
+
+The mutex module has no dependencies.
+
+### Function index
+
+| Function                          | Purpose                              |
+|-----------------------------------|--------------------------------------|
+| [mutex_trylock()](#mutex_trylock) | Try to lock a mutex, without waiting |
+| [mutex_lock()](#mutex_lock)       | Lock a mutex, waiting if necessary   |
+| [mutex_unlock()](#mutex_unlock)   | Unlock a mutex                       |
+
+
+## mutex_trylock()
+
+Try to lock a mutex, without waiting.
+
+### Synopsis
+
+    mutex_trylock "$mutex"
+
+### Description
+
+The `mutex_trylock()` function attempts to lock the mutex with the path
+`$mutex`. This function returns immediately, regardless of the outcome of
+the lock operation.
+
+### Return value
+
+| Return value | Meaning                           |
+|--------------|-----------------------------------|
+| 0            | The mutex was successfully locked |
+| 1            | The mutex could not be locked     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## mutex_lock()
+
+Lock a mutex, waiting if necessary.
+
+### Synopsis
+
+    mutex_lock "$mutex" "$timeout"
+
+### Description
+
+The `mutex_lock()` function locks the mutex with the path `$mutex`. If the mutex
+is already locked by another process, this function will wait either until it was
+able to lock the mutex, or until the timeout has expired. If `$timeout` is -1 or
+was omitted, the function will wait indefinitely. Otherwise, it will wait for
+`$timeout` seconds. The actual time that this function waits depends on the
+process scheduler and may be more than `$timeout` seconds.
+If a timeout of 0 is passed, this function is equivalent with `mutex_trylock()`.
+
+### Return value
+
+| Return value | Meaning                           |
+|--------------|-----------------------------------|
+| 0            | The mutex was successfully locked |
+| 1            | The mutex could not be locked     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## mutex_unlock()
+
+Unlock a mutex.
+
+### Synopsis
+
+    mutex_unlock "$mutex"
+
+### Description
+
+The `mutex_unlock()` function unlocks the mutex at the path `$mutex`. If
+`$mutex` is a valid mutex, this function checks whether the running process
+is the owner of the mutex (i.e. if the running process is the process that
+locked the mutex) and, if it is not the owner, refuses to unlock the mutex.
+
+
+### Return value
+
+| Return value | Meaning                                    |
+|--------------|--------------------------------------------|
+| 0            | The mutex was successfully unlocked        |
+| 1            | The mutex could not be read                |
+| 2            | The running process does not own the mutex |
+| 3            | The mutex could not be removed             |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
diff --git a/docs/opt.md b/docs/opt.md
new file mode 100644 (file)
index 0000000..388fb0e
--- /dev/null
@@ -0,0 +1,218 @@
+# The opt module
+
+The opt module implements a versatile command line parser. The parser can be used for
+options without values (flags) and options with one or multiple values. The parser can
+be instructed to validate values using regular expressions, and call user-defined
+functions when an option was parsed and validated.
+
+### Dependencies
+
+ * [array](array.md)
+ * [log](log.md)
+
+### Function index
+
+| Function                            | Purpose                                 |
+|-------------------------------------|-----------------------------------------|
+| [opt_add_arg()](#opt_add_arg)       | Declare an option                       |
+| [opt_get()](#opt_get)               | Get the value of an option              |
+| [opt_get_argv()](#opt_get_argv)     | Get the executing script's command line |
+| [opt_parse()](#opt_parse)           | Parse a command line                    |
+| [opt_print_help()](#opt_print_help) | Print a help text                       |
+
+
+## opt_add_arg()
+
+Declare an option
+
+### Synopsis
+
+    opt_add_arg "$short" "$long" "$flags" "$default" "$desc" "$regex" "$action"
+
+### Description
+
+The `opt_add_arg()` function declares a new option with the short and long names `$short` and `$long`. The
+behavior of the option is determined by the flags passed in `$flags`, which is a string containing one or more
+of the following attributes.
+
+| Attribute | Meaning                              |
+|-----------|--------------------------------------|
+| `a`       | The option is an array (implies `v`) |
+| `r`       | The option is required               |
+| `v`       | The option has a value               |
+
+If the `a` flag was set, the `$default` parameter must contain the name of the array that the parsed values
+will be appended to. The parser will only append to the array; values that it contains before the parser is
+invoked will not be overwritten.
+If the `r` flag was set, the option must be passed on the command line, otherwise the parser will return an
+error.
+If the `v` or `a` flag was set, the option must be followed by a value. The value is validated against the
+regular expression passed in `$regex`.
+The `$action` parameter may be used to determine a callback that is executed when an option was successfully
+parsed, i.e. it has no value or the value matches `$regex`. The callback `$action` will be passed the long
+name of the option in the first, and the value of the option in the second argument.
+
+The value passed in `$desc` will be displayed as the description in the script's help text.
+
+
+### Return value
+
+| Return value | Meaning                              |
+|--------------|--------------------------------------|
+| 0            | The option was successfully declared |
+| 1            | The option could not be declared     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+In case of an error, a message is written to standard error.
+
+
+## opt_get()
+
+Get the value of an option
+
+### Synopsis
+
+    opt_get "$long"
+
+### Description
+
+The `opt_get()` function returns the value of the option with the long name `$long`. If the option does not
+have a value (i.e. it was declared without the `a` or `v` flags), the number of times it was encountered on
+the command line is returned.
+
+### Return value
+
+| Return value | Meaning                                                |
+|--------------|--------------------------------------------------------|
+| 0            | The value of the option was written to standard output |
+| 1            | The option was not set                                 |
+| 2            | The option name is invalid                             |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+Upon success, the value of the option is written to standard output. If the option's value was not passed on
+the command line, its default value will be written. Otherwise, no data will be written to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## opt_get_argv()
+
+Get the executing script's command line
+
+### Synopsis
+
+    opt_get_argv
+
+### Description
+
+The `opt_get_argv()` function returns options that were passed to the executing script, one argument per line.
+
+### Return value
+
+| Return value | Meaning                          |
+|--------------|----------------------------------|
+| 0            | Success                          |
+| 1            | The options could not be written |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+Upon success, the options that were passed to the executing script are written to standard output, each
+argument on a separate line. Otherwise no data will be written to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## opt_parse()
+
+Parse a command line
+
+### Synopsis
+
+    opt_parse "${opts[@]}"
+
+### Description
+
+The `opt_parse()` function parses the command line passed in `$opts` according to the option definitions that
+were declared using `opt_add_arg()`. Options may appear on the command line either with their short name,
+prefixed by one dash, or with their long name, prefixed by two dashes. The parser operates as follows.
+ * If an option does not have a value, the parser will count the number of times the option was found on the command line.
+ * If an option has a value, but the value is missing or could not be validated against the option's regular expression, the parser will return an error.
+ * If the option is an array, and its value could be validated, the value will be added to the array that stores the option's values.
+ * If the option does not have a value, or it has a value that could be validated against the option's regular expression, the parser will call the option's callback. If the option's callback returns a non-zero value, the parser will stop parsing and return the value that the callback returned.
+ * If `-h` or `--help` were encountered in `$opts`, the help text will be written to standard output.
+ * If `-v` or `--verbose` were encountered in `$opts`, the verbosity of the script is increased one level.
+ * If `-q` or `--quiet` were encountered in `$opts`, the verbosity of the script is decreased one level.
+
+### Return value
+
+| Return value | Meaning                                  |
+|--------------|------------------------------------------|
+| 0            | The command line was successfully parsed |
+| 1            | The command line could not be parsed     |
+| *            | A callback failed with this return value |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+If `-h` or `--help` were found in `$opts`, the help text will be written to standard output.
+
+### Standard error
+
+In case of an error, a message will be written to standard error.
+
+
+## opt_print_help()
+
+Print a help text
+
+### Synopsis
+
+    opt_print_help
+
+### Description
+
+The `opt_print_help()` function writes a help text to standard output. The content of the help text depends
+on the options that were declared using `opt_add_arg()`.
+
+### Return value
+
+| Return value | Meaning         |
+|--------------|-----------------|
+| 2            | Always returned |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+The help text of the script is written to standard output.
+
+### Standard error
+
+This function does not write to standard error.
diff --git a/docs/queue.md b/docs/queue.md
new file mode 100644 (file)
index 0000000..24de444
--- /dev/null
@@ -0,0 +1,188 @@
+# The queue module
+
+The queue implements a "thread"-safe mechanism for exchanging messages
+between multiple processes. Messages exchanged via queues will be received
+in the same order that they were sent.
+
+### Dependencies
+
+ * [log](log.md)
+ * [mutex](mutex.md)
+ * [sem](sem.md)
+
+### Function index
+
+| Function                          | Purpose                                        |
+|-----------------------------------|------------------------------------------------|
+| [queue_destroy()](#queue_destroy) | Remove a queue                                 |
+| [queue_foreach()](#queue_foreach) | Execute a callback for each message in a queue |
+| [queue_get()](#queue_get)         | Get a message from a queue                     |
+| [queue_init()](#queue_init)       | Create a new queue                             |
+| [queue_put()](#queue_put)         | Insert a message into a queue                  |
+
+## queue_destroy()
+
+Remove a queue
+
+### Synopsis
+
+    queue_destroy "$queue"
+
+### Description
+
+The `queue_destory()` function removes the queue referenced by `$queue`.
+
+### Return value
+
+| Return value | Meaning                            |
+|--------------|------------------------------------|
+| 0            | The queue was successfully removed |
+| 1            | The queue could not be removed     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## queue_foreach()
+
+Execute a callback for each message in a queue
+
+### Synopsis
+
+    queue_foreach "$queue" "$func" "${args[@]}"
+
+### Description
+
+The `queue_foreach()` function executes the callback `$func` once for each message contained in the queue
+referenced by `$queue`. The callback will be passed the message in the first parameter, followed by the
+elements in `$args`.
+If the callback returns a non-zero value, `queue_foreach()` will not visit the remaining messages in the
+queue.
+
+### Return value
+
+| Return value | Meaning                                               |
+|--------------|-------------------------------------------------------|
+| 0            | The callback successfully processed all messages      |
+| 1            | The queue could not be locked, or the callback failed |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## queue_get()
+
+Get a message from a queue
+
+### Synopsis
+
+    queue_get "$queue" "$timeout"
+
+### Description
+
+The `queue_get()` function will return the message from the head of the queue `$queue`. If the queue is empty,
+the function will wait for at least `$timeout` seconds for the arrival of a message. If `$timeout` was
+omitted, the function will wait indefinitely; if `$timeout` is zero, the function will return immediately.
+
+### Return value
+
+| Return value | Meaning                                             |
+|--------------|-----------------------------------------------------|
+| 0            | A message was successfully retrieved from the queue |
+| 1            | Could not retrieve a message from the queue         |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+Upon success, the message retrieved from the queue is written to standard output. Otherwise, no data is
+written to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## queue_init()
+
+Create a new queue
+
+### Synopsis
+
+    queue_init "$queue"
+
+### Description
+
+The `queue_init()` function initializes a new queue with path `$queue`. If `$queue` is a relative path, the
+queue will be created in the home directory of the executing user.
+
+### Return value
+
+| Return value | Meaning                            |
+|--------------|------------------------------------|
+| 0            | The queue was successfully created |
+| 1            | The queue could not be created     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## queue_put()
+
+Insert a message into a queue
+
+### Synopsis
+
+    queue_put "$queue" "$item"
+
+### Description
+
+The `queue_put()` function places the item `$item` in the queue referenced by `$queue`.
+
+### Return value
+
+| Return value | Meaning                            |
+|--------------|------------------------------------|
+| 0            | The item was successfully inserted |
+| 1            | The item could not be inserted     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
diff --git a/docs/reference.md b/docs/reference.md
new file mode 100644 (file)
index 0000000..7d2250f
--- /dev/null
@@ -0,0 +1,20 @@
+# Toolbox module reference
+
+The following modules are part of toolbox.
+
+| Module              | Purpose                                  |
+|---------------------|------------------------------------------|
+| [array](array.md)   | Comparing, searching, and sorting arrays |
+| [conf](conf.md)     | Configuration handling                   |
+| [git](git.md)       | Interacting with git repositories        |
+| [inst](inst.md)     | Writing daemons                          |
+| ipc                 | Message-based IPC (GPG-signed)           |
+| [is](is.md)         | Checking the value of variables          |
+| [json](json.md)     | Handling JSON data                       |
+| [log](log.md)       | Logging and debugging                    |
+| [mutex](mutex.md)   | Locks for protecting shared resources    |
+| [opt](opt.md)       | Command line parsing                     |
+| [queue](queue.md)   | "Thread"-safe FIFOs                      |
+| [sem](sem.md)       | Process synchronization                  |
+| uipc                | Message-based IPC (unsigned)             |
+| [wmutex](wmutex.md) | Weak (owner-less) locks                  |
diff --git a/docs/sem.md b/docs/sem.md
new file mode 100644 (file)
index 0000000..c69fb12
--- /dev/null
@@ -0,0 +1,229 @@
+# The sem module
+
+The sem module implements a semaphore datatype for synchronizing access
+to shared resources such as queues.
+
+### Dependencies
+
+ * [is](is.md)
+ * [log](log.md)
+ * [mutex](mutex.md)
+ * [wmutex](wmutex.md)
+
+### Function index
+
+| Function                      | Purpose                                             |
+|-------------------------------|-----------------------------------------------------|
+| [sem_destroy()](#sem_destroy) | Clean up a semaphore                                |
+| [sem_init()](#sem_init)       | Initialize a new semaphore                          |
+| [sem_post()](#sem_post)       | Increase a semaphore                                |
+| [sem_peek()](#sem_peek)       | Get the counter of a semaphore without modifying it |
+| [sem_trywait()](#sem_trywait) | Try to decrease a semaphore without waiting         |
+| [sem_wait()](#sem_wait)       | Decrease a semaphore, waiting if necessary          |
+
+## sem_destroy()
+
+Clean up a semaphore
+
+### Synopsis
+
+    sem_destroy "$name"
+
+### Description
+
+The `sem_destroy()` function removes the semaphore referenced by `$name` and frees all resources
+occupied by it. Before removing the semaphore, this function checks if the calling process is the
+owner of the semaphore. If the caller is not the owner of the semaphore, an error will be returned.
+
+### Return value
+
+| Return value | Meaning                                |
+|--------------|----------------------------------------|
+| 0            | The semaphore was removed successfully |
+| 1            | The semaphore could not be removed     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+In case of an error, this function writes a message to standard error.
+
+
+## sem_init()
+
+Initialize a new semaphore
+
+### Synopsis
+
+    sem_init "$name" "$value"
+
+### Description
+
+The `sem_init()` function creates a new semaphore with the name `$name` and initializes its counter
+to the value `$value`. If `$name` is a relative path, the semaphore will be created in the calling
+user's home directory, otherwise `$name` is assumed to be the absolute path of a semaphore.
+
+### Return value
+
+| Return value | Meaning                                                |
+|--------------|--------------------------------------------------------|
+| 0            | The semaphore was created and initialized successfully |
+| 1            | The semaphore could not be created                     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+In case of an error, this function writes a message to standard error.
+
+
+## sem_post()
+
+Increase a semaphore
+
+### Synopsis
+
+    sem_post "$name"
+
+### Description
+
+The `sem_post()` function increases the counter of a semaphore. This is a synchronous operation, and
+may cause the caller to block indefinitely.
+
+### Return value
+
+| Return value | Meaning                                  |
+|--------------|------------------------------------------|
+| 0            | The semaphore was increased successfully |
+| 1            | The semaphore could not be increased     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## sem_peek()
+
+Get the counter of a semaphore without modifying it
+
+### Synopsis
+
+    sem_peek "$name"
+
+### Description
+
+The `sem_peek()` function reads the counter of the semaphore referenced by `$name` and writes it to
+standard output. This is a synchronous operation, and may cause the caller to block indefinitely.
+
+### Return value
+
+| Return value | Meaning                                                 |
+|--------------|---------------------------------------------------------|
+| 0            | The counter was successfully written to standard output |
+| 1            | The counter could not be read                           |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+On success, the counter of the semaphore is written to standard output. Otherwise, no data is written
+to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## sem_trywait()
+
+Try to decrease a semaphore without waiting
+
+### Synopsis
+
+    sem_trywait "$name"
+
+### Description
+
+The `sem_trywait()` function attempts to decrease the counter of the semaphore referenced by `$name`
+and returns immediately. If the counter cannot be decreased without waiting on the semaphore, the
+counter is not decreased, and an error is returned.
+This function is equivalent to `sem_wait()` with a timeout of `0`, and may be implemented as a call
+to `sem_wait()`.
+
+### Return value
+
+| Return value | Meaning                                              |
+|--------------|------------------------------------------------------|
+| 0            | The semaphore was decreased successfully             |
+| 1            | The semaphore could not be decreased without waiting |
+
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## sem_wait()
+
+Decrease a semaphore, waiting if necessary
+
+### Synopsis
+
+    sem_wait "$name" "$timeout"
+
+### Description
+
+The `sem_wait()` function decreases the counter of the semaphore referenced by `$name`, waiting on the
+semaphore if necessary. The function will wait at most `$timeout` seconds, however the exact time waited
+depends on the process scheduler and may exceed `$timeout` seconds. If the timeout is negative or has been
+omitted, the function may wait indefinitely. If the timeout is `0`, the function will attempt to decrease
+the counter without waiting. The latter is equivalent to a call to `sem_trywait()`.
+
+### Return value
+
+| Return value | Meaning                                                           |
+|--------------|-------------------------------------------------------------------|
+| 0            | The semaphore has been decreased successfully                     |
+| 1            | The semaphore could not be decreased within the specified timeout |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
diff --git a/docs/wmutex.md b/docs/wmutex.md
new file mode 100644 (file)
index 0000000..dbb730d
--- /dev/null
@@ -0,0 +1,138 @@
+# The wmutex (weak mutex) module
+
+The wmutex module implements a simple mechanism to enforce serial execution.
+The path from a wmutex lock operation to its corresponding unlock operation is
+called a critical section, and is guaranteed to be executed serially.
+
+Weak mutexes work the same way as regular mutexes, except that weak mutexes do
+not perform ownership checks. Thus, weak mutexes may be used in situations where
+the process that unlocks a mutex is not the same as the one that locked it (for
+example, in semaphores).
+
+Critical sections limit the performance of parallel processes and should thus
+be as short as possible. Further, long and nested critical sections are prone
+to cause deadlocks and should be avoided.
+As a best practice, a critical section should not span multiple functions and
+there should be only one codepath that leads out of the critical section.
+
+### Dependencies
+
+The wmutex module has no dependencies.
+
+### Function index
+
+| Function                            | Purpose                              |
+|-------------------------------------|--------------------------------------|
+| [wmutex_trylock()](#wmutex_trylock) | Try to lock a mutex, without waiting |
+| [wmutex_lock()](#wmutex_lock)       | Lock a mutex, waiting if necessary   |
+| [wmutex_unlock()](#wmutex_unlock)   | Unlock a mutex                       |
+
+
+## wmutex_trylock()
+
+Try to lock a mutex, without waiting.
+
+### Synopsis
+
+    wmutex_trylock "$mutex"
+
+### Description
+
+The `wmutex_trylock()` function attempts to lock the mutex with the path
+`$mutex`. This function returns immediately, regardless of the outcome of
+the lock operation.
+
+### Return value
+
+| Return value | Meaning                           |
+|--------------|-----------------------------------|
+| 0            | The mutex was successfully locked |
+| 1            | The mutex could not be locked     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## wmutex_lock()
+
+Lock a mutex, waiting if necessary.
+
+### Synopsis
+
+    wmutex_lock "$mutex" "$timeout"
+
+### Description
+
+The `wmutex_lock()` function locks the mutex with the path `$mutex`. If the mutex
+is already locked by another process, this function will wait either until it was
+able to lock the mutex, or until the timeout has expired. If `$timeout` is -1 or
+was omitted, the function will wait indefinitely. Otherwise, it will wait for
+`$timeout` seconds. The actual time that this function waits depends on the
+process scheduler and may be more than `$timeout` seconds.
+If a timeout of 0 is passed, this function is equivalent with `wmutex_trylock()`.
+
+### Return value
+
+| Return value | Meaning                           |
+|--------------|-----------------------------------|
+| 0            | The mutex was successfully locked |
+| 1            | The mutex could not be locked     |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.
+
+
+## wmutex_unlock()
+
+Unlock a mutex.
+
+### Synopsis
+
+    wmutex_unlock "$mutex"
+
+### Description
+
+The `wmutex_unlock()` function unlocks the mutex at the path `$mutex`. If
+`$mutex` is a valid mutex, this function checks whether the running process
+is the owner of the mutex (i.e. if the running process is the process that
+locked the mutex) and, if it is not the owner, refuses to unlock the mutex.
+
+
+### Return value
+
+| Return value | Meaning                                    |
+|--------------|--------------------------------------------|
+| 0            | The mutex was successfully unlocked        |
+| 1            | The mutex could not be read                |
+| 2            | The running process does not own the mutex |
+| 3            | The mutex could not be removed             |
+
+### Standard input
+
+This function does not read from standard input.
+
+### Standard output
+
+This function does not write to standard output.
+
+### Standard error
+
+This function does not write to standard error.