From 25ca454b64791de0b9c2754894bec408bd2f2f9b Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Wed, 4 Oct 2023 21:30:36 -0400 Subject: [PATCH] Add "fill until" support MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This patch adds an item to add bytes until some offset is reached: 89 89 aa ff cc dd +0x3c {ICITTE:8} Result: 89 89 aa ff cc dd 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• 00 00 00 00 00 00 00 00 00 00 00 00 3c ┆ ••••••••••••< The item forms are: +EXPR +EXPR~PAD where EXPR is a positive constant integer, a name, or an expression between `{` and `}`, and PAD is a positive constant integer padding byte value (0 by default). The item `+EXPR~PAD` is functionally equivalent to `PAD * {(EXPR) - ICITTE}`: it's just an alias for what I think is a common operation. For example, you might only want to write the first few fields of some header: {le} "FRMT" # Magic {0x7855:32} # Total pixel count {data_beg:32} # Data beginning pointer +0x80 "the pixels" # Here they are Result: 46 52 4d 54 55 78 00 00 80 00 00 00 00 00 00 00 ┆ FRMTUx•••••••••• 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• 74 68 65 20 70 69 78 65 6c 73 ┆ the pixels Change-Id: Ibd3a2bd243c15e1d4f9a9d5b5aa0076e19f9f9f7 Signed-off-by: Philippe Proulx --- README.adoc | 148 +++++++++++++++++++++++- normand/normand.py | 129 +++++++++++++++++---- pyproject.toml | 2 +- tests/fail-align-inval-pad-val-neg.nt | 2 +- tests/fail-align-inval-pad-val-str.nt | 2 +- tests/fail-fill-before.nt | 3 + tests/fail-fill-inval-pad-val-neg.nt | 4 + tests/fail-fill-inval-pad-val-str.nt | 4 + tests/fail-fill-inval-val-neg.nt | 4 + tests/fail-fill-inval-val-str.nt | 4 + tests/fail-fill-pad-val-out-of-range.nt | 4 + tests/fail-fill-unknown-name-1.nt | 4 + tests/fail-fill-unknown-name-2.nt | 5 + tests/pass-comment-sym-bin-const.nt | 4 +- tests/pass-comment-sym-group.nt | 2 +- tests/pass-comment-sym-hex-const.nt | 6 +- tests/pass-comment-sym-rep-post.nt | 2 +- tests/pass-fill-cur-offset.nt | 3 + tests/pass-fill-name.nt | 5 + tests/pass-fill-pad-val.nt | 7 ++ tests/pass-fill.nt | 5 + tests/pass-readme-intro-fill.nt | 23 ++++ tests/pass-readme-learn-fill-1.nt | 9 ++ tests/pass-readme-learn-fill-2.nt | 25 ++++ 24 files changed, 372 insertions(+), 34 deletions(-) create mode 100644 tests/fail-fill-before.nt create mode 100644 tests/fail-fill-inval-pad-val-neg.nt create mode 100644 tests/fail-fill-inval-pad-val-str.nt create mode 100644 tests/fail-fill-inval-val-neg.nt create mode 100644 tests/fail-fill-inval-val-str.nt create mode 100644 tests/fail-fill-pad-val-out-of-range.nt create mode 100644 tests/fail-fill-unknown-name-1.nt create mode 100644 tests/fail-fill-unknown-name-2.nt create mode 100644 tests/pass-fill-cur-offset.nt create mode 100644 tests/pass-fill-name.nt create mode 100644 tests/pass-fill-pad-val.nt create mode 100644 tests/pass-fill.nt create mode 100644 tests/pass-readme-intro-fill.nt create mode 100644 tests/pass-readme-learn-fill-1.nt create mode 100644 tests/pass-readme-learn-fill-2.nt diff --git a/README.adoc b/README.adoc index e98e637..ce86733 100644 --- a/README.adoc +++ b/README.adoc @@ -29,7 +29,7 @@ _**Normand**_ is a text-to-binary processor with its own language. This package offers both a portable {py3} module and a command-line tool. -WARNING: This version of Normand is 0.11, meaning both the Normand +WARNING: This version of Normand is 0.12, meaning both the Normand language and the module/CLI interface aren't stable. ifdef::env-github[] @@ -241,6 +241,40 @@ Output: ff 85 ff ff 00 00 15 d0 ---- +Filling:: ++ +Input: ++ +---- +{le} +{0xdeadbeef:32} +{-1993:16} +{9:16} ++0x40 +{ICITTE:8} +"meow mix" ++200~0xff +{ICITTE:8} +---- ++ +Output: ++ +---- +ef be ad de 37 f8 09 00 00 00 00 00 00 00 00 00 ┆ ••••7••••••••••• +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• +40 6d 65 6f 77 20 6d 69 78 ff ff ff ff ff ff ff ┆ @meow mix••••••• +ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ┆ •••••••••••••••• +ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ┆ •••••••••••••••• +ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ┆ •••••••••••••••• +ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ┆ •••••••••••••••• +ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ┆ •••••••••••••••• +ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ┆ •••••••••••••••• +ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ┆ •••••••••••••••• +ff ff ff ff ff ff ff ff c8 ┆ ••••••••• +---- + Multilevel grouping:: + Input: @@ -417,6 +451,8 @@ The available items are: * A <>. +* A <>. + * A <>, that is, a named constant holding the current offset. + @@ -458,7 +494,7 @@ the following symbol characters are also considered comments where a comment may exist: ---- -/ \ ? & : ; . , + [ ] _ = | - +/ \ ? & : ; . , [ ] _ = | - ---- The latter serve to improve readability so that you may write, for @@ -962,6 +998,114 @@ aa bb cc ff ff ff 7a 6f 6f 6d ┆ ••••••zoom ---- ==== +=== Filling + +A _filling_ represents zero or more padding bytes to make the +<> reach a given value. + +A filling is: + +. The ``pass:[+]`` prefix. + +. One of: + +** A positive integer (hexadecimal starting with `0x` or `0X` accepted) + which is the current offset target. + +** The ``pass:[{]`` prefix, a valid {py3} expression of which the + evaluation result type is `int` or `bool` (automatically converted to + `int`), and the ``pass:[}]`` suffix. ++ +For a filling at some source location{nbsp}__**L**__, this expression +may contain: ++ +-- +* The name of any <> defined before{nbsp}__**L**__ + which isn't within a nested group. +* The name of any <> known + at{nbsp}__**L**__. +-- ++ +The value of the special name `ICITTE` (`int` type) in this expression +is the <> (before handling the items to +repeat). + +** A valid {py3} name. ++ +For the name `__NAME__`, this is equivalent to the +`pass:[{]__NAME__pass:[}]` form above. + ++ +This value must be greater than or equal to the current offset where +it's used. + +. **Optional**: ++ +-- +. The ``pass:[~]`` prefix. +. A positive integer (hexadecimal starting with `0x` or `0X` accepted) + which is the value of the byte to use as padding to reach the + current offset target. +-- ++ +Without this section, the padding byte value is zero. + +==== +Input: + +---- +aa bb cc dd ++0x40 +"hello world" +---- + +Output: + +---- +aa bb cc dd 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ┆ •••••••••••••••• +68 65 6c 6c 6f 20 77 6f 72 6c 64 ┆ hello world +---- +==== + +==== +Input: + +---- +!macro part(iter, fill) + <0> "particular security " {ord('0') + iter : 8} +fill~0x80 +!end + +{iter = 1} + +!repeat 5 + m:part(iter, {32 + 4 * iter}) + {iter = iter + 1} +!end +---- + +Output: + +---- +70 61 72 74 69 63 75 6c 61 72 20 73 65 63 75 72 ┆ particular secur +69 74 79 20 31 80 80 80 80 80 80 80 80 80 80 80 ┆ ity 1••••••••••• +80 80 80 80 70 61 72 74 69 63 75 6c 61 72 20 73 ┆ ••••particular s +65 63 75 72 69 74 79 20 32 80 80 80 80 80 80 80 ┆ ecurity 2••••••• +80 80 80 80 80 80 80 80 80 80 80 80 70 61 72 74 ┆ ••••••••••••part +69 63 75 6c 61 72 20 73 65 63 75 72 69 74 79 20 ┆ icular security +33 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ┆ 3••••••••••••••• +80 80 80 80 80 80 80 80 70 61 72 74 69 63 75 6c ┆ ••••••••particul +61 72 20 73 65 63 75 72 69 74 79 20 34 80 80 80 ┆ ar security 4••• +80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ┆ •••••••••••••••• +80 80 80 80 80 80 80 80 70 61 72 74 69 63 75 6c ┆ ••••••••particul +61 72 20 73 65 63 75 72 69 74 79 20 35 80 80 80 ┆ ar security 5••• +80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 ┆ •••••••••••••••• +80 80 80 80 80 80 80 80 80 80 80 80 ┆ •••••••••••• +---- +==== + === Label A _label_ associates a name to the <>. diff --git a/normand/normand.py b/normand/normand.py index 935e845..c44373d 100644 --- a/normand/normand.py +++ b/normand/normand.py @@ -30,7 +30,7 @@ # Upstream repository: . __author__ = "Philippe Proulx" -__version__ = "0.11.0" +__version__ = "0.12.0" __all__ = [ "__author__", "__version__", @@ -241,6 +241,29 @@ class _ExprMixin: return self._expr +# Fill until some offset. +class _FillUntil(_Item, _ExprMixin): + def __init__( + self, expr_str: str, expr: ast.Expression, pad_val: int, text_loc: TextLocation + ): + super().__init__(text_loc) + _ExprMixin.__init__(self, expr_str, expr) + self._pad_val = pad_val + + # Padding byte value. + @property + def pad_val(self): + return self._pad_val + + def __repr__(self): + return "_FillUntil({}, {}, {}, {})".format( + repr(self._expr_str), + repr(self._expr), + repr(self._pad_val), + repr(self._text_loc), + ) + + # Variable assignment. class _VarAssign(_Item, _ExprMixin): def __init__( @@ -603,7 +626,7 @@ class _Parser: # Pattern for _skip_ws_and_comments() _ws_or_syms_or_comments_pat = re.compile( - r"(?:[\s/\\?&:;.,+[\]_=|-]|#[^#]*?(?:\n|#))*" + r"(?:[\s/\\?&:;.,[\]_=|-]|#[^#]*?(?:\n|#))*" ) # Skips as many whitespaces, insignificant symbol characters, and @@ -1050,10 +1073,38 @@ class _Parser: self._expect_pat(self._label_set_offset_suffix_pat, "Expecting `>`") return item + # Pattern for _parse_pad_val() + _pad_val_prefix_pat = re.compile(r"~") + + # Tries to parse a padding value, returning the padding value, or 0 + # if none. + def _parse_pad_val(self): + # Padding value? + self._skip_ws() + pad_val = 0 + + if self._try_parse_pat(self._pad_val_prefix_pat) is not None: + self._skip_ws() + pad_val_text_loc = self._text_loc + m = self._expect_pat( + self._pos_const_int_pat, + "Expecting a positive constant integer (byte value)", + ) + + # Validate + pad_val = int(m.group(0), 0) + + if pad_val > 255: + _raise_error( + "Invalid padding byte value {}".format(pad_val), + pad_val_text_loc, + ) + + return pad_val + # Patterns for _try_parse_align_offset() _align_offset_prefix_pat = re.compile(r"@") _align_offset_val_pat = re.compile(r"\d+") - _align_offset_pad_val_prefix_pat = re.compile(r"~") # Tries to parse an offset alignment, returning an offset alignment # item on success. @@ -1065,9 +1116,8 @@ class _Parser: # No match return - self._skip_ws() - # Expect an alignment + self._skip_ws() align_text_loc = self._text_loc m = self._expect_pat( self._align_offset_val_pat, @@ -1085,26 +1135,34 @@ class _Parser: align_text_loc, ) - # Padding value? - self._skip_ws() - pad_val = 0 + # Padding value + pad_val = self._parse_pad_val() - if self._try_parse_pat(self._align_offset_pad_val_prefix_pat) is not None: - self._skip_ws() - pad_val_text_loc = self._text_loc - m = self._expect_pat(self._pos_const_int_pat, "Expecting a byte value") + # Return item + return _AlignOffset(val, pad_val, begin_text_loc) - # Validate - pad_val = int(m.group(0), 0) + # Patterns for _try_parse_fill_until() + _fill_until_prefix_pat = re.compile(r"\+") + _fill_until_pad_val_prefix_pat = re.compile(r"~") - if pad_val > 255: - _raise_error( - "Invalid padding byte value {}".format(pad_val), - pad_val_text_loc, - ) + # Tries to parse a filling, returning a filling item on success. + def _try_parse_fill_until(self): + begin_text_loc = self._text_loc + + # Match prefix + if self._try_parse_pat(self._fill_until_prefix_pat) is None: + # No match + return + + # Expect expression + self._skip_ws() + expr_str, expr = self._expect_const_int_name_expr(True) + + # Padding value + pad_val = self._parse_pad_val() # Return item - return _AlignOffset(val, pad_val, begin_text_loc) + return _FillUntil(expr_str, expr, pad_val, begin_text_loc) # Patterns for _expect_rep_mul_expr() _inner_expr_prefix_pat = re.compile(r"\{") @@ -1424,6 +1482,12 @@ class _Parser: # Offset alignment item? item = self._try_parse_align_offset() + if item is not None: + return item + + # Filling item? + item = self._try_parse_fill_until() + if item is not None: return item @@ -1835,7 +1899,7 @@ class _Gen: # `float` too. @staticmethod def _eval_item_expr( - item: Union[_FlNum, _Leb128Int, _VarAssign, _Rep, _Cond], + item: Union[_FlNum, _Leb128Int, _FillUntil, _VarAssign, _Rep, _Cond], state: _GenState, allow_float: bool = False, ): @@ -2018,13 +2082,33 @@ class _Gen: def _handle_set_offset_item(self, item: _SetOffset, state: _GenState): state.offset = item.val - # Handles offset alignment item `item` (adds padding). + # Handles the offset alignment item `item` (adds padding). def _handle_align_offset_item(self, item: _AlignOffset, state: _GenState): init_offset = state.offset align_bytes = item.val // 8 state.offset = (state.offset + align_bytes - 1) // align_bytes * align_bytes self._data += bytes([item.pad_val] * (state.offset - init_offset)) + # Handles the filling item `item` (adds padding). + def _handle_fill_until_item(self, item: _FillUntil, state: _GenState): + # Compute the new offset + new_offset = _Gen._eval_item_expr(item, state) + + # Validate the new offset + if new_offset < state.offset: + _raise_error_for_item( + "Invalid expression `{}`: new offset {:,} is less than current offset {:,}".format( + item.expr_str, new_offset, state.offset + ), + item, + ) + + # Fill + self._data += bytes([item.pad_val] * (new_offset - state.offset)) + + # Update offset + state.offset = new_offset + # Handles the label item `item`. def _handle_label_item(self, item: _Label, state: _GenState): state.labels[item.name] = state.offset @@ -2125,6 +2209,7 @@ class _Gen: _AlignOffset: self._handle_align_offset_item, _Byte: self._handle_byte_item, _Cond: self._handle_cond_item, + _FillUntil: self._handle_fill_until_item, _FlNum: self._handle_fl_num_item, _Group: self._handle_group_item, _Label: self._handle_label_item, diff --git a/pyproject.toml b/pyproject.toml index 556430f..bcf5751 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ [tool.poetry] name = 'normand' -version = '0.11.0' +version = '0.12.0' description = 'Text-to-binary processor with its own language' license = 'MIT' authors = ['Philippe Proulx '] diff --git a/tests/fail-align-inval-pad-val-neg.nt b/tests/fail-align-inval-pad-val-neg.nt index d31aa48..3a87a9a 100644 --- a/tests/fail-align-inval-pad-val-neg.nt +++ b/tests/fail-align-inval-pad-val-neg.nt @@ -1,4 +1,4 @@ 88 44 @16~-45 "meow" @ 56 ~ 127 $132 --- -1:11 - Expecting a byte value +1:11 - Expecting a positive constant integer (byte value) diff --git a/tests/fail-align-inval-pad-val-str.nt b/tests/fail-align-inval-pad-val-str.nt index fa9458e..911e1a2 100644 --- a/tests/fail-align-inval-pad-val-str.nt +++ b/tests/fail-align-inval-pad-val-str.nt @@ -1,4 +1,4 @@ 88 44 @16~yo "meow" @ 56 ~ 127 $132 --- -1:11 - Expecting a byte value +1:11 - Expecting a positive constant integer (byte value) diff --git a/tests/fail-fill-before.nt b/tests/fail-fill-before.nt new file mode 100644 index 0000000..3788b2d --- /dev/null +++ b/tests/fail-fill-before.nt @@ -0,0 +1,3 @@ +aa bb cc +2 "zoom" +--- +1:10 - Invalid expression `2`: new offset 2 is less than current offset 3 diff --git a/tests/fail-fill-inval-pad-val-neg.nt b/tests/fail-fill-inval-pad-val-neg.nt new file mode 100644 index 0000000..a064bc8 --- /dev/null +++ b/tests/fail-fill-inval-pad-val-neg.nt @@ -0,0 +1,4 @@ +88 44 +16~-45 "meow" ++ 100 ~ 127 $132 +--- +1:11 - Expecting a positive constant integer (byte value) diff --git a/tests/fail-fill-inval-pad-val-str.nt b/tests/fail-fill-inval-pad-val-str.nt new file mode 100644 index 0000000..e21acf5 --- /dev/null +++ b/tests/fail-fill-inval-pad-val-str.nt @@ -0,0 +1,4 @@ +88 44 +16~yo "meow" ++ 56 ~ 127 $132 +--- +1:11 - Expecting a positive constant integer (byte value) diff --git a/tests/fail-fill-inval-val-neg.nt b/tests/fail-fill-inval-val-neg.nt new file mode 100644 index 0000000..ac01c79 --- /dev/null +++ b/tests/fail-fill-inval-val-neg.nt @@ -0,0 +1,4 @@ +88 44 +-16 "meow" ++ 56 ~ 127 $132 +--- +1:8 - Expecting a positive constant integer diff --git a/tests/fail-fill-inval-val-str.nt b/tests/fail-fill-inval-val-str.nt new file mode 100644 index 0000000..b7432f3 --- /dev/null +++ b/tests/fail-fill-inval-val-str.nt @@ -0,0 +1,4 @@ +88 44 +"yo" "meow" ++ 56 ~ 127 $132 +--- +1:8 - Expecting a positive constant integer, a name, or `{` diff --git a/tests/fail-fill-pad-val-out-of-range.nt b/tests/fail-fill-pad-val-out-of-range.nt new file mode 100644 index 0000000..e7dd14d --- /dev/null +++ b/tests/fail-fill-pad-val-out-of-range.nt @@ -0,0 +1,4 @@ +88 44 +16~256 "meow" ++ 56 ~ 127 $132 +--- +1:11 - Invalid padding byte value 256 diff --git a/tests/fail-fill-unknown-name-1.nt b/tests/fail-fill-unknown-name-1.nt new file mode 100644 index 0000000..3fe6b2a --- /dev/null +++ b/tests/fail-fill-unknown-name-1.nt @@ -0,0 +1,4 @@ +{zoom = 32} +aa bb cc +yo "zoom" +--- +2:10 - Illegal (unknown or unreachable) variable/label name `yo` in expression `yo`; the legal names are {`ICITTE`, `zoom`} diff --git a/tests/fail-fill-unknown-name-2.nt b/tests/fail-fill-unknown-name-2.nt new file mode 100644 index 0000000..e691272 --- /dev/null +++ b/tests/fail-fill-unknown-name-2.nt @@ -0,0 +1,5 @@ +{zoom = 32} +aa bb cc +yo "zoom" +{yo = 0x99} +--- +2:10 - Illegal (unknown or unreachable) variable/label name `yo` in expression `yo`; the legal names are {`ICITTE`, `zoom`} diff --git a/tests/pass-comment-sym-bin-const.nt b/tests/pass-comment-sym-bin-const.nt index 2e39488..ff49023 100644 --- a/tests/pass-comment-sym-bin-const.nt +++ b/tests/pass-comment-sym-bin-const.nt @@ -1,6 +1,6 @@ -%1/01\0?1&0:1;0 %.0,1+0[1]0_1=0|1 %1111-0000 +%1/01\0?1&0:1;0 %.0,10[1]0_1=0|1 %1111-0000 % 1 0 / 1 \ 0 ? 1 & 0 : 1 ; 0 -% . 0 , 1 + 0 [ 1 ] 0 _ 1 = 0 | 1 +% . 0 , 1 0 [ 1 ] 0 _ 1 = 0 | 1 % 1111 - 0000 --- aa 55 f0 diff --git a/tests/pass-comment-sym-group.nt b/tests/pass-comment-sym-group.nt index 0b33c27..bcc7db9 100644 --- a/tests/pass-comment-sym-group.nt +++ b/tests/pass-comment-sym-group.nt @@ -1,3 +1,3 @@ -(012/3\4?5&6:7;8.9,a+b[c]d_e=f|0-1(/\?&:;.,+[]_=|-)) +(012/3\4?5&6:7;8.9,ab[c]d_e=f|0-1(/\?&:;.,[]_=|-)) --- 01 23 45 67 89 ab cd ef 01 diff --git a/tests/pass-comment-sym-hex-const.nt b/tests/pass-comment-sym-hex-const.nt index 4c3b990..c770691 100644 --- a/tests/pass-comment-sym-hex-const.nt +++ b/tests/pass-comment-sym-hex-const.nt @@ -1,6 +1,6 @@ -/ \ ? & : ; . , + [ ] _ = | - -012/3\4?5&6:7;8.9,a+b[c]d_e=f|0-1 -0 1 2 / 3 \ 4 ? 5 & 6 : 7 ; 8 . 9 , a + b [ c ] d_e = f | 0 - 1 +/ \ ? & : ; . , [ ] _ = | - +012/3\4?5&6:7;8.9,ab[c]d_e=f|0-1 +0 1 2 / 3 \ 4 ? 5 & 6 : 7 ; 8 . 9 , a b [ c ] d_e = f | 0 - 1 --- 01 23 45 67 89 ab cd ef 01 01 23 45 67 89 ab cd ef 01 diff --git a/tests/pass-comment-sym-rep-post.nt b/tests/pass-comment-sym-rep-post.nt index 08dc0c3..98c94bc 100644 --- a/tests/pass-comment-sym-rep-post.nt +++ b/tests/pass-comment-sym-rep-post.nt @@ -1,4 +1,4 @@ # repetition -ff/\?&:;.,+[]_=|-*/\?&:;.,+[]_=|-5 +ff/\?&:;.,[]_=|-*/\?&:;.,[]_=|-5 --- ff ff ff ff ff diff --git a/tests/pass-fill-cur-offset.nt b/tests/pass-fill-cur-offset.nt new file mode 100644 index 0000000..c0f9a96 --- /dev/null +++ b/tests/pass-fill-cur-offset.nt @@ -0,0 +1,3 @@ +aa bb cc +{ICITTE} {ICITTE:8} +--- +aa bb cc 03 diff --git a/tests/pass-fill-name.nt b/tests/pass-fill-name.nt new file mode 100644 index 0000000..aeecbd5 --- /dev/null +++ b/tests/pass-fill-name.nt @@ -0,0 +1,5 @@ +aa {zoom = 10} bb cc +zoom {ICITTE:8} +--- +aa bb cc 00 00 +00 00 00 00 00 +0a diff --git a/tests/pass-fill-pad-val.nt b/tests/pass-fill-pad-val.nt new file mode 100644 index 0000000..ba43a7f --- /dev/null +++ b/tests/pass-fill-pad-val.nt @@ -0,0 +1,7 @@ +aa {zoom = 10} bb cc +zoom~0xcc {ICITTE:8} ++ 15 ~ 255 {ICITTE:8} +--- +aa bb cc cc cc +cc cc cc cc cc +0a ff ff ff ff +0f diff --git a/tests/pass-fill.nt b/tests/pass-fill.nt new file mode 100644 index 0000000..15e7a94 --- /dev/null +++ b/tests/pass-fill.nt @@ -0,0 +1,5 @@ +aa bb cc +10 {ICITTE:8} +--- +aa bb cc 00 00 +00 00 00 00 00 +0a diff --git a/tests/pass-readme-intro-fill.nt b/tests/pass-readme-intro-fill.nt new file mode 100644 index 0000000..1ef55a2 --- /dev/null +++ b/tests/pass-readme-intro-fill.nt @@ -0,0 +1,23 @@ +{le} +{0xdeadbeef:32} +{-1993:16} +{9:16} ++0x40 +{ICITTE:8} +"meow mix" ++200~0xff +{ICITTE:8} +--- +ef be ad de 37 f8 09 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +40 6d 65 6f 77 20 6d 69 78 ff ff ff ff ff ff ff +ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +ff ff ff ff ff ff ff ff c8 diff --git a/tests/pass-readme-learn-fill-1.nt b/tests/pass-readme-learn-fill-1.nt new file mode 100644 index 0000000..6fb6b3f --- /dev/null +++ b/tests/pass-readme-learn-fill-1.nt @@ -0,0 +1,9 @@ +aa bb cc dd ++0x40 +"hello world" +--- +aa bb cc dd 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +68 65 6c 6c 6f 20 77 6f 72 6c 64 diff --git a/tests/pass-readme-learn-fill-2.nt b/tests/pass-readme-learn-fill-2.nt new file mode 100644 index 0000000..fed70e9 --- /dev/null +++ b/tests/pass-readme-learn-fill-2.nt @@ -0,0 +1,25 @@ +!macro part(iter, fill) + <0> "particular security " {ord('0') + iter : 8} +fill~0x80 +!end + +{iter = 1} + +!repeat 5 + m:part(iter, {32 + 4 * iter}) + {iter = iter + 1} +!end +--- +70 61 72 74 69 63 75 6c 61 72 20 73 65 63 75 72 +69 74 79 20 31 80 80 80 80 80 80 80 80 80 80 80 +80 80 80 80 70 61 72 74 69 63 75 6c 61 72 20 73 +65 63 75 72 69 74 79 20 32 80 80 80 80 80 80 80 +80 80 80 80 80 80 80 80 80 80 80 80 70 61 72 74 +69 63 75 6c 61 72 20 73 65 63 75 72 69 74 79 20 +33 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 +80 80 80 80 80 80 80 80 70 61 72 74 69 63 75 6c +61 72 20 73 65 63 75 72 69 74 79 20 34 80 80 80 +80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 +80 80 80 80 80 80 80 80 70 61 72 74 69 63 75 6c +61 72 20 73 65 63 75 72 69 74 79 20 35 80 80 80 +80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 +80 80 80 80 80 80 80 80 80 80 80 80 -- 2.34.1