# Directives
Directives control the operation of both the hex file generator and of the parser, and can be specified in three different places.
- Directives can be in the configuration file for **hhh**
- Directives can be specified on the command line with the `-D` switch, and will override those present in the configuration file
- Directives can be in a binary description file, and will override any on the command line or in the configuration file
A complete list of directives, their arguments, and their use can be obtained with the command line switch `--list-directives`.
## Structure
A directive is specified by giving the symbolic name followed by any arguments in parentheses. For instance:
```
bias(0x2000)
```
This sets the current bias (the amount added to offsets when generating a hex dump or the amount subtracted from offsets when parsing a binary description) to 0x2000.
If a directive does not take any arguments, you can omit the parentheses.
```
prefix
```
Arguments may use radix prefixes and may be given as expressions.
```
bias(0x2000 + 40*8)
```
A directive can be given using either hyphens or underscores, so `little_endian` and `little-endian` are treated as the same.
## Configuration File
Configuration files are explained in their own chapter. See [Configuration](configuration.md). Essentially, directives are given, one per line, and are evaluated in the order they are encountered.
```
// Enable prefixes
prefix
```
## Command Line
To specify a directive on the command line, given the directive after a `-D` switch.
The parentheses may be processed by the shell, so to use them on the command line you may need to surround the entire directive with single or double quotation marks.
```bash
0x00000008: 0x6f72 0x6c64 0x210a // orld!.
```
```bash
```
## Binary Description File
Binary description files are discussed in their own chapter. See [W]
Within a binary description file, directive can be given inside a double square bracket pair `[[..]]`. Only one directive can be given at a time.
```hhh -p
[[prefix()]]
0: 0xfffe 0x4f00 0x6c00 0xe100 0x2c00 0x2000 0x6d00 0x7500
0x6e00 0x6400 0x6f00 0x2100
// Result
// 00000000: ff fe 4f 00 6c 00 e1 00 2c 00 20 00 6d 00 75 00
// 00000010: 6e 00 64 00 6f 00 21 00
```
## All Directives
The complete list of directives at time of writing, along with their arguments and their use, is given here. Some directives are only meaningful during parsing of a binary description file, and some are only meaningful when generating a hex dump. This is indicated for each directive.
Directives that are closely associated are listed together.
~~~admonish note title="## `ascii()`<br>`no_ascii()`<br><br><small>GENERATION</small>"
~~~
Generate or suppress an ASCII preview for each line. Any non-graphical ASCII characters are represented by a period, as are any bytes outside the ASCII range.
The command line switch `--no-ascii` is a synonym for `-Dno-ascii`.
The default behavior is `--ascii`.
```bash
```
```bash
```
~~~admonish note title="## `bias(number)`<br><br><small>GENERATION<br>PARSING</small>"
~~~
Set the bias to add to (parsing) or subtract from (generation) the offset.
The command line switch `--bias=number` is a synonym for `-Dbias(number)`.
The default behavior is to use a bias of zero.
**When generating:** The bias is added to the offset.
```bash
```
**When parsing:** The bias is subtracted from the offset.
```bash
```
```hhh -p
[[bias(0x2000)]]
00002000: 48 6f 77 64 79 21 0a
// Result
// 00000000: 48 6f 77 64 79 21 0a
```
~~~admonish note title="## `big-endian()`<br>`little-endian()`<br><br><small>GENERATION<br>PARSING</small>"
~~~
Specify the order of bytes in unprefixed byte blocks.
The command line switch `--little-endian` is a synonym for `-Dlittle-endian`.
The default behavior is `-Dbig-endian`.
**When generating:** Specifying little endian order reverses the order of the bytes in each unprefixed byte block.
```bash
```
It does not reverse the order of bytes written as part of a prefixed number. That is, if radix prefixes are enabled, then this directive has no effect.
```bash
```
**When parsing:** Specifying little endian order reverses the order of bytes in each unprefixed byte block.
```bash
```
It does not reverse the order of bytes written as part of a prefixed number. That is, if radix prefixes are enabled, then this directive has no effect.
```bash
```
~~~admonish note title="## `bytes-per-group([1..255])`<br>`groups-per-line([1..255])`<br>`group-separator(string)`<br><br><small>GENERATION</small>"
~~~
Specify the number of bytes to include in a single group (or in a single prefixed number) in the output (`bytes-per-group`). Specify the number of groups to include on a line (`groups-per-line`). Specify a string to use to separate groups (`group-separator`).
The command line switches `--bytes-per-group=number` and `-b number` are synonyms for `-Dbytes-per-group(number)`.
The command line switches `--group-per-line=number` and `-g number` are synonyms for `-Dgroups-per-line(number)`.
The command line switches `--group-separator=string` and `-s string` are synonyms for `-Dgroup-separator(string)`.
The default behavior is one byte per group.
```bash
00000008: 4f68 696f 0a // Ohio.
```
```bash
```
~~~admonish note title="## `lowercase()`<br>`uppercase()`<br><br><small>GENERATION</small>"
~~~
Use lower case or upper case letters for hexadecimal output.
The command line switch `--uppercase` is a synonym for `-Duppercase`.
The default behavior is to use lower case.
```bash
```
~~~admonish note title="## `metadata()`<br>`no-metadata()`<br>set-metadata(string,string)`<br><br><small>GENERATION</small>"
~~~
Whether to write a commented metadata block at the top of the generated hex dump (`metadata`) or not (`no-metadata`).
Add or remove metadata elements (`set-metadata`) by giving the metadata name and value as strings. If the value is the empty string, then the metadata item is suppressed.
The command line switches `--meta` and `-m` are synonyms for `-Dmetadata`.
The command line switches `--set-meta=name=value` and `-Mname=value` are synonyms for `-Dset-metadata(name, value)`.
The default behavior is to not write metadata. When metadata is written, then default is to include the command line and the current date and time.
```bash
$ hhh --meta test_files/hello -MUTC= | head -4
// Command-Line: "--no-configuration-file" "--meta" "test_files/hello" "-MUTC="
00000000: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 // .ELF............
00000010: 02 00 3e 00 01 00 00 00 00 10 40 00 00 00 00 00 // ..>.......@.....
00000020: 40 00 00 00 00 00 00 00 40 11 00 00 00 00 00 00 // @.......@.......
```
```bash
$ hhh -Dmeta test_files/hello -MProject=1704 -D'set-metadata("Command-Line","")' -MUTC= | head -6
// Project: 1704
00000000: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 // .ELF............
00000010: 02 00 3e 00 01 00 00 00 00 10 40 00 00 00 00 00 // ..>.......@.....
00000020: 40 00 00 00 00 00 00 00 40 11 00 00 00 00 00 00 // @.......@.......
00000030: 00 00 00 00 40 00 38 00 02 00 40 00 05 00 04 00 // ....@.8...@.....
00000040: 01 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 // ................
```
~~~admonish note title="## `offsets()`<br>`no-offsets()`<br>`offset-width([0..255])`<br><br><small>GENERATION</small>"
~~~
Include or suppress the offset value at the start of each line, or specify the minimum number of digits to display for the offset.
The command line switch `--no-offset` is a synonym for `-Dno-offset`.
The command line switch `--offset-width=number` is a synonym for `-Doffset-width(number)`.
The default behavior is to include an offset at the start of each line and to use eight digits.
```bash
```
```bash
04: 6d206970 // m.ip
08: 73756d0a // sum.
```
~~~admonish note title="## `prefix()`<br>`no-prefix`<br><br><small>GENERATION<br>PARSING</small>"
~~~
Specify whether to use radix prefixes.
The command line switches `--radix-prefixes` and `-r` are synonyms for `-Dprefix`.
The default behavior is to not use or expect radix prefixes.
**When generating:** If radix prefixes are enabled then byte order directives are ignored and byte groups are treated as numbers is the specified radix (currently only hexadecimal is used).
```bash
0x00000004: 0x3435 0x360a // 456.
```
**When parsing:** Numbers are assumed to be decimal unless prefixed with a radix specifier (`0x`, `0o`, or `0b`) and byte order directives are ignored.
```hhh -p
0000: 4561737920
[[prefix]]
0x617320 0x3120 0x3220 0x330a
// Result
// 00000000: 45 61 73 79 20 61 73 20 31 20 32 20 33 0a
```
~~~admonish note title="## `relative(number)`<br><br><small>PARSING</small>"
~~~
Set a bias that makes the current offset into the offset given by the number.
The defaul behavior is to use a bias of zero.
```hhh -p
[[relative(0x4000)]]
4000: "This is a test"
[[bias(0)]]
21 0a
// Result
// 00000000: 54 68 69 73 20 69 73 20 61 20 74 65 73 74 21 0a
```
~~~admonish note title="## `set(variable, number)`<br><br><small>PARSING</small>"
~~~
Set a variable.
By default only `$_`, representing the current offset, is specified.
```hhh -p
[[ set( "first", 0x31323334 ) ]]
0: $first/4
// Result
// 00000000: 31 32 33 34
```
~~~admonish note title="## `stoic()`<br>`no-stoic()`<br><br><small>PARSING</small>"
~~~
Disable (`stoic`) or enable (`no-stoic`) all errors and make a best attempt to parse.
The default is to stop on an error.
```hhh -p
[[stoic]]
[[relative(0x4000)]]
/usr/bin/ls: file format elf64-x86-64
Disassembly of section .init:
0000000000004000 <.init>:
4000: f3 0f 1e fa endbr64
4004: 48 83 ec 08 sub rsp,0x8
4008: 48 8b 05 a9 ef 01 00 mov rax,QWORD PTR [rip+0x1efa9]
400f: 48 85 c0 test rax,rax
4012: 74 02 je 4016 <free@plt-0x61a>
4014: ff d0 call rax
4016: 48 83 c4 08 add rsp,0x8
401a: c3 ret
"END"
// Result
// 00000000: f3 0f 1e fa 48 83 ec 08 48 8b 05 a9 ef 01 00 48
// 00000010: 85 c0 74 02 ff d0 48 83 c4 08 c3 45 4e 44
```