This NEWS file records noteworthy changes, very tersely.
See the manual for detailed information.

  Copyright 2019, 2020, 2021, 2022, 2023 The poke authors.

  Copying and distribution of this file, with or without modification,
  are permitted in any medium without royalty provided the copyright
  notice and this notice are preserved.

 Version 3.3 (20 August 2023)
* Bug fixes

  - Mapping in non-strict mode now assures that constraint expressions
    are executed, even if their result is discarded.  This is
    important because very often constraint expressions have side
    effects (such as setting the current endianness) on which further
    mapping relies.

  - Bug in array promotion has been fixed.

  - A bug impacting array bounders in struct constructors has been
    fixed.

  - The return type of the builtin `iolist' has been fixed.

  - A bug impacting the re-definition of struct types at the top-level
    has been fixed.

  - Error locations were not very xprecise in a couple of circumstances
    due to a bison limitation.  This should be fixed now.

  - Setting values of mapped structs in strict mode now really check
    for integrity, erroing whenever necessary.

  - A bug flushing stream IO devices has been fixed.

  - The .sub dot-command now does the right thing when no name is
    specified, instead of crashing poke.

* Pickles

  - The BTF pickle has been updated to support BTF_KIND_ENUM64.

 Version 3.2 (13 May 2023)
* Bug fixes

   - Fix value returned by the libpoke function pk_load.

   - Fix a very annoying regression that resulted in a segfault when
     doing l-value maps of struct values having anonymous fields.

 Version 3.1 (17 April 2023)
* Bug fixes

   - Fix recognition of token 0[bB] in the lexer.

   - Do not validate and check _print* functions within struct types
     as if they were methods.  As functions, they can have any
     signature as they are no special in any way.

   - Do not emit an empty table for computed fiels in the output of
     .info type if the type has no computed fields.

   - Use tar-ustar in AM_INIT_AUTOMAKE.  The usage older algorithms in
     tar was causing problems when creating poke tarballs with long
     path names.

   - std.pk now provides utility functions to parse and compare poke
     versions.  This is for example to be used by poke pickles in
     order to require a particular minimum version of the program.

   - poked now recognizes the short option -S.

   - poked now creates its socket with umask 0077, and it uses a more
     suitable default socket path that includes the PID of the process
     running the daemon.

   - The Poke compiler now emits proper parse errors when problems are
     found in asm templates.

   - poke will no longer abort execution in case it finds a fatal
     error in the lexer, such as memory exhaustion.

   - Casts from arrays to arrays now use the right bounder.

   - Constant folding of offset multiplication by an offset with zero
     unit is now fixed.

 Version 3.0 (26 January 2023)
* User interface updates

  - A screen pager has been added to the poke application.  If enabled
    with the =.set pager yes= option, output will be paged one
    screenful at a time.

  - A tracer has been added to libpoke and the poke application.  If
    enabled with the =.set tracer yes= option, subsequent loaded Poke
    types will be instrumentalized so calls to user-defined handlers
    are executed when certain events happen:

    + Every time a field gets mapped.
    + Every time a struct/union gets mapped.
    + Every time a field gets constructed.
    + Every time a struct/union gets constructed.
    + Every time an optional field is omitted when mapping or
      constructing.

    This is very useful when debugging and writing pickles.

  - A new command sdiff (for "structured diff") has been added to the
    poke application, that provides a way to generate patchable diffs
    of mapped structured Poke values.  This command is an interface to
    the structured diffs provided by the new diff.pk pickle.

  - When no name is passed to the .mem command, an unique name for the
    memory IOS with the form *N* will be used automatically, where N
    is a positive integer.

  - auto-completion of 'attributes is now available in the poke
    application.

  - Constraint errors now contain details on the location (which
    field) where the constraint error happens, along with the
    particular expression that failed.

  - Inline assembler expressions and statements are now supported:

    : asm (TEMPLATE [: OUTPUTS [: INPUTS]])
    : asm TYPE: (TEMPLATE [: INPUTS])

    where PVM assembly code can be executed as part of normal Poke
    programs.

  - Both =printf= and =format= now support printing values of type
    =any=.

  - Both =printf= and =format= now support printing integral values
    interpreted as floating-point values encoded in IEEE 754.  Format
    tags %f, %g and %e are supported.  This feature, along with the
    new ieee754.pk pickle, eases dealing with floating-point data in
    binary data.

  - Pre-conditional optional fields are added to complement the
    currently supported post-conditional optional fields.  A
    pre-conditional optional field like:

    : if (CONDITION)
    :   TYPE FNAME;

    makes FNAME optional based on the evaluation of CONDITION.  But
    the field itself is not mapped if the condition evaluates to
    false.

  - A new option =.set autoremap no= can be used in order to tell poke
    to not remap mapped values automatically.  This greatly speeds up
    things, but assumes that the contents of the IO space are not
    updated out of the control of the user.  See the manual for
    details.

  - The :to argument to the =extract= command is now optional, and
    defaults to the empty string.

  - ${XDG_CONFIG_HOME:-$HOME/.config} is now preferred to
    XDG_CONFIG_DIRS.

* Poke Language updates

  - Array and struct constructors are now primaries in the Poke
    syntax.  This means that it is no longer necessary to enclose them
    between parenthesis in constructions like:

    : (Packet {}).field

    and this is now accepted:

    : Packet {}.field

  - Bit-concatenation is now supported in l-values.  After executing
    this code:

    : var a = 0 as int<4>;
    : var b = 0 as uint<28>;
    :
    : a:::b = 0x12345678;

    the value of =a= is 0x1N and the value of =b= is (uint<28>)
    0x2345678.

  - Arrays can now be indented by size, by specifying an offset as an
    index.  This is particularly useful for accessing structures such
    as string tables without having to explicitly iterate on the
    array's elements.

  - Union types can now be declared as "integral".  The same features
    of integral structs are now available for unions: integration,
    deintegration, the ability of being used in contexts where an
    integer is expected, etc.

  - Support for "computed fields" has been added to struct and union
    types.  Computed fields are accessed just like regular fields, but
    the semantics of referring to them and of assigning to them are
    specified by the user by the way of defining getter and setter
    methods.

  - This version introduces three new Poke attributes that work on
    values of type =any=:

    : VAL'elem (N)
    :    evaluates to the Nth element in VAL, as a value of type `any'.
    :
    : VAL'eoffset (N)
    :    evaluates to the offset of the Nth element in VAL.
    :
    : VAL'esize (N)
    :    evaluates to the size of the Nth element in VAL.
    :
    : VAL'ename (N)
    :    attribute evaluates to the name of the Nth element in VAL.

  - Two new operators have been introduced to facilitate operating
    Poke array as stacks in an efficient way: apush and apop.  Since
    these operators change the size of the involved arrays, they are
    only allowed in unbounded arrays.

  - Poke programs can now hook in the IO subsystem by installing
    functions that will be invoked when certain operations on IO
    spaces are being performed:

    : ios_open_hook
    :   Functions in this hook are invoked once a new IO space has been
    :   opened.
    :
    : ios_set_hook
    :   Functions in this hook are invoked once the current IO space
    :   changes.
    :
    : ios_close_pre_hook
    : ios_close_hook
    :   Functions in these hooks are invoked before and after an IO space is
    :   closed, respectively.

  - The 'length attribute is now valid in values of type =any=.

  - Poke declarations can now be annotated as =immutable=.  It is not
    allowed to re-define immutable definitions.

  - A new compiler built-in =iolist= has been introduced, that returns
    an array with the IO space identifiers of currently open IOS.

  - We have changed the logic of the EXCOND operator ?!.  It now
    evaluates to 1 (true) if the execution of the first operand raises
    the specified exception, and to 0 (false) otherwise.  We
    profusedly apologize for the backwards incompatibility, but this
    is way better than the previous (reversed) logic.

  - The containing struct or union value can now be refered as SELF in
    the body of methods.  SELF is of type =any=.

  - Integer literal suffixes (B, H, U, etc) are case-insensitive.  But
    until now little-case =b= wasn't being recognized as such.  Now
    =1B= is the same than =1b=.

  - Casting to union types now raise a compile-time error.

  - If no explicit message is specified in calls to =assert=, a
    default one showing the source code of the failing condition is
    constructed and used instead.

  - An operator =remap= has been used in order to force a re-map of
    some mapped Poke value.

  - Signed integral types of one bit are not allowed.  How could they
    be, in two's complement?

  - The built-in function get_time has been renamed to gettime, to
    follow the usual naming of the corresponding standard C function.

* Standard Poke Library updates

  - New standard functions:

    : eoffset (V, N)
    :   Given a value of type `any' and a name, returns the offset of
    :   the element having that name.
    :
    : openset (HANDLER, [FLAGS])
    :   Open an IO space and make it the current IO space.
    :
    : with_temp_ios ([HANDLER], [FLAGS], [DO], [ENDIAN])
    :   Execute some code with a temporary IO space.
    :
    : with_cur_ios (IOS, [DO], [ENDIAN])
    :   Execute some code on some given IO space.

* libpoke updates

  - New API function pk_struct_ref_set_field_value.

  - New API function pk_type_name.

* Pickles updates

  - New pickles provided in the poke distribution:

    : diff.pk
    :   Useful binary diffing utilities.  In particular, it implements
    :   the "structured diff" format as described in
    :   https://binary-tools.net/bindiff.pdf.
    :
    : io.pk
    :   Facilities to dump data to the terminal.
    :
    : pk-table.pk
    :   Convenient facilities to Poke programs to print tabulated data.
    :
    : openpgp.pk
    :   Pickle to poke at OpenPGP RFC 4880 data.
    :
    : sframe.pk
    : sframe-dump.pk
    :   Pickles for the SFrame unwinding format, and related dump
    :   utilities.
    :
    : search.pk
    :   Utility for searching data in IO spaces that conform to some
    :   given Poke type.
    :
    : riscv.pk
    :   Pickle to poke at instructions encoded in the RISC-V instruction
    :   set (RV32I).  It also provides methods to generate assembly
    :   language.
    :
    : coff.pk
    : coff-aarch64.pk
    : coff-i386.pk
    :   COFF object files.
    :
    : pe.pk
    : pe-amd64.pk
    : pe-arm.pk
    : pe-arm64.pk
    : pe-debug.pk
    : pe-i386.pk
    : pe-ia64.pk
    : pe-m32r.pk
    : pe-mips.pk
    : pe-ppc.pk
    : pe-riscv.pk
    : pe-sh3.pk
    :   PE/COFF object files.
    :
    : pcap.pk
    :   Capture file format.
    :
    : uuid.pk
    :   Universally Unique Identifier (UUID) as defined by RFC4122.
    :
    : redoxfs.pk
    :   RedoxFS files ystem of Redox OS.
    :
    : ieee754.pk
    :   IEEE Standard for Floating-Point Arithmetic.

  - The ELF pickle now provides functions implementing ELF hashing.

* Build system updates

  - It is now supported to configure the poke sources with
    --disable-hserver.

* Documentation updates

  - Documentation for the =format= language construction has been
    added to the poke manual.

* Other updates

  - A new program poked, for "poke daemon", has been contributed to
    the poke distribution by Mohammad-Reza Nabipoor.  poked links with
    libpoke and uses Unix sockets to act as a broker to communicate
    with an instance of a Poke incremental compiler.  This is already
    used by several user interfaces to poke.

  - The machine-interface subsystem has been removed from poke, in
    favor of the poked approach.

  - The example GUI that was intended to be a test tool for the
    machine interface has been removed from the poke distribution.

  - Many bugs have been fixed.

 Version 2.4 (25 July 2022)
* Improvements

   - poke now accompanies the E_constraint exceptions raised when it
     fails to map an union value with an explicative message, such as
     "no valid alternative found for union Foo".

   - poke now doesn't remap arrays when indexing them if the elements
     are themselves mapped, and of a type whose size is known at
     compile-time.  This speeds things up.

   - Struct constructors and array constructors were not considered as
     syntactic "primaries", for no reason.  This made it necessary to
     surround them with parentheses before indexing or dot-notating
     them, like in:

       (Foo {}).foo
       (int[3]())[2]

     Now it is possible to write this instead:

       Foo {}.foo
       int[3]()[2]

* Bug fixes

   - Rejecting tokens in the lexer was causing the location
     information in the compiler to be trashed.  This is now fixed.

   - The CTF pickle was raising an E_inval exception in ctf_get_dict
     when there wasn't exactly one section named .ctf in the object
     file.  It now asserts instead.

   - Add missing #include for ctype.h in pk-repl.c.

   - Improve E_no_return diagnostics.

* Documentation updates

   - An example of a comparator function for `qsort' has been added to
     the poke manual.

 Version 2.3 (31 March 2022)
* Bug fixes

   - Fix diagnostics in 32-bit.

 Version 2.2 (29 March 2022)
* Bug fixes

   - Fix the ASCII part of `dump' when the offset is not zero.
   - printf format fixes.
   - The 'length attribute is valid in `any' values.
   - Handle --version and --help before loading subsystems.
   - Create uniquely named memory IO subsystems when no name
     is specified in the .mem dot-command.
   - Some methods in the ELF64 pickle were doing mappings using
     the wrong IO space.  This is now fixed.
   - The precedence of the EXCOND operator has been lowered.
   - A bug was causing arrays of `void' elements to be created.
   - Exceptions raised from the application of value attributes are
     now accompanied by informative messages.
   - The LEB128 and ULEB128 pickles now calculate the right value for
     leb128 values.
   - The tag %% is now properly handled in format strings.
   - The pk_map_decl callback in libpoke now gets PK_NULL as the
     declaration value.
   - A bug in the stream IOS has been fixed.

 Version 2.1 (8 February 2022)
* Bug fixes

   - A needed file (pk-hserver.pk) was not distributed if poke was
     built without hserver support.  Now it is.
   - poke can now be cross-built.
   - Auto-completion now works in subcommands.
   - Don't panic when an attribute is not known at compile-time.
   - Fix ICE related to completeness of trimmed arrays.
   - Restore proper behavior with -l and unhandled exceptions.
   - Make --disable-gui the default.
   - Fix size calculation of complete union types.
   - Do not change the compiler environment when unhandled exceptions.
   - Jitter has been updated to not use minimum-threading, since
     there is a bug in that dispatch mode.
   - The argument :ios of `dump' is now documented.

 Version 2.0 (28 January 2022)
* User interface updates

  - Types can now be redefined at the prompt.  This allowed us to
    change `load' to always load the requested file/module.

  - The poke command now accepts two additional command-line options
    in order to select which default style to use: --style-dark and
    --style-bright.  The first, which is the default, works good with
    dark backgrounds.  The second works good with bright backgrounds.

  - Invoking the .set command with no arguments now lists all the
    global settings along with their values.  It also emits buttons
    (terminal hyperlinks) to easily toggle boolean settings.

  - The .file dot-command now supports a =/c= flag, that tells poke it
    must create an empty file with the specified name if it doesn't
    already exist.

  - The :size argument of the =dump= command is now rounded up to the
    next byte, not truncated down to the previous byte.

  - A new "sub" IO space has been implemented in poke.  It allows to
    create IO spaces that are like narrowed versions of some other IO
    space.  These "sub" IO spaces are created using the new
    dot-command =.sub=:

    : (poke) .mem scratch
    : (poke) .info ios
    :   Id   Type     Mode   Bias           Size           Name
    : * #0   MEMORY   rw     0x00000000#B   0x00001000#B   *scratch*
    : (poke) .sub #0, 2, 16, lala
    : (poke) .info ios
    :   Id   Type     Mode   Bias           Size           Name
    : * #1   SUB      rw     0x00000002#B   0x00000010#B   sub://0/0x0/0x10/lala
    :   #0   MEMORY   rw     0x00000000#B   0x00001000#B   *scratch*

    At this point accessing the IO space #1 at offset 0#B will modify
    the data in the *scratch* IO space at offset 2#B.

  - GNU poke can now poke at the memory of a running process using the
    new process IOS.  This can be done using the new dot-command
    =.proc=:

    : (poke) .proc 30244
    : (poke) .info ios
    :   Id   Type   Mode   Bias           Size                   Name
    : * #0   PROC   rw     0x00000000#B   0xffffffffffffffff#B   pid://30244

    The command above has opened a new IO space (with id #0) to poke
    at the memory of the running process with PID 30244.

    A flag =/m= can be passed to =.proc= to indicate we want poke to
    create additional sub-spaces providing access to the mapped VM
    ranges of the process:

    : (poke) .proc/m 30244
    : (poke) .info ios
    :   Id   Type   Mode   Bias           Size          Name
    :   #9   SUB    r      0x00000000#B   0x00001000#B  sub://0/0xffffffffff600000/0x1000/[vsyscall]
    :   #8   SUB    r      0x00000000#B   0x00002000#B  sub://0/0x7ffe82db2000/0x2000/[vdso]
    :   #7   SUB    r      0x00000000#B   0x00002000#B  sub://0/0x7ffe82db0000/0x2000/[vvar]
    :   #6   SUB    rw     0x00000000#B   0x00021000#B  sub://0/0x7ffe82c2f000/0x21000/[stack]
    :   [...]
    : * #0   PROC   rw     0x00000000#B   0xffffffffffffffff#B pid://30244

    See below for the new handler syntax in =open= to open process IO
    spaces from Poke programs.  Note that the support for process IO
    space is only implemented in GNU/Linux systems.

  - The =dump= command now shows ?? marks to denote bytes that are not
    readable, for whatever reason.  This happens for example when we
    try to access some non-mapped area of the VM space of a process:

    : (poke) .proc/m 30244
    : (poke) dump :from 0#B :size 16#B
    : 76543210  0011 2233 4455 6677 8899 aabb ccdd eeff  0123456789ABCDEF
    : 00000000: ???? ???? ???? ???? ???? ???? ???? ????  ................

  - The =dump= command now emits hyperlinks for the shown bytes, if
    requested.  Clicking on them will insert the offset where the byte
    resides in the poke prompt.

  - The =dump= command now remembers the last used offset per IO
    space.  In poke 1.x it just remembered the last globally used
    offset, which was very confusing.

  - The =.info ios= dot-command now emits [close] buttons if
    hyperlinks are enabled.  Clicking on them closes the referred IO
    space.

  - The =.info ios= dot-command now shows the value of the "bias" for
    each open IO space.  See below for more information on this bias.

  - E_constraint exceptions raised when mapping now include some
    useful location information:

    : (poke) Elf64_Ehdr @ 1#B
    : unhandled constraint violation exception
    : constraint expression failed for field Elf_Ident.ei_mag

  - The =.info types=, =.info variables= and =.info functions=
    dot-commands now accept an optional regular expression.  Example:

    : (poke) load elf
    : (poke) .info types Elf64_
    : Name                 Declared at
    : Elf64_Ehdr           elf-64.pk:184
    : Elf64_Off            elf-64.pk:26
    : Elf64_SectionFlags   elf-64.pk:130
    : Elf64_Shdr           elf-64.pk:152
    : Elf64_RelInfo        elf-64.pk:36
    : [...]

    When listing types, the names in the first column are emitted with
    a nice terminal hyperlink.  Clicking on them will result in
    executing =.info type NAME=.

  - New dot-command =.info type NAME=, that prints out a nice and
    informative description of the type with the given name.  Example:

    : (poke) .info type Elf64_File
    : Class:      struct
    : Name:       "Elf64_File"
    : Complete:   no
    : Fields:
    :   ehdr
    :   shdr
    :   phdr
    : Methods:
    :  get_section_name
    :  get_symbol_name
    :  get_sections_by_name
    :  get_sections_by_type
    :  section_name_p
    :  get_string
    :  get_group_signature
    :  get_group_signatures
    :  get_section_group

* Poke Language updates

  - Integral structs are struct values that are stored like integers.
    This is a simple real-life example:

    : type Elf_Sym_Info =
    :   struct uint<8>
    :   {
    :     uint<4> st_bind;
    :     uint<4> st_type;
    :   };

    These structs can be used pretty much like regular structs,
    accessing their fields normally.  In poke 1.x it was already
    possible to "integrate" them, i.e. operating with their "integer"
    value by using either an explicit cast:

    : (poke) Elf_Sym_Info { st_bind = 1 } as uint<8>
    : 0x10UB

    or automatically, using them in a context where an integral value
    is expected:

    : (poke) Elf_Sym_Info { st_bind = 1} + 1
    : 0x11UB

    We are now introducing support for the inverse operation: to
    "deintegrate" an integer into an integral struct value.  This is
    performed by a cast:

    : (poke) 0x10 as Elf_Sym_Info
    : Elf_Sym_Info { st_bind=0x1UB, st_type=0x0UB }

  - Arrays whose elements are integral (integers, other integral
    arrays, or integral structs) can now be also "integrated"
    using casts:

    : (poke) [1UB, 0UB] as int
    : 0x10
    : (poke) 0x10 as uint<8>[2]
    : [1UB,0UB]
    : (poke) [[1UB,2UB],[3UB,4UB]] as int
    : 0x1234

    This nice feature has been contributed by Mohammad-Reza Nabipoor.

  - Poke programs can now sleep for a number of seconds and
    nanoseconds using the new built-in function =sleep=.  It has the
    following signature:

    : fun sleep = (int<64> sec, int<64> nsec = 0) void:

    The sleep is not active, i.e. poke will not consume CPU while it
    is sleeping.

  - The only way in poke 1.x to print styled text to the terminal was
    to use the very ugly and clumsy %<..> tags in =printf= statements.
    This was annoying to use, especially because you were required to
    end every styling class you open in the same statement.  So we
    added a couple of new built-in functions =term_begin_class= and
    =term_end_class=.  They are used like this:

    : term_begin_class ("error");
    : print "error: the quux is foobared";
    : term_end_class ("error");

    The functions will raise an exception in case you nest your
    classes the wrong way.

  - It is now possible to emit terminal hyperlinks from Poke programs.
    See "Terminal hyperlinks updates" below for more information on
    this.

  - The equality `==' and inequality `!=' operators now work on
    function values.  Two given function values are equal if they are
    the same function value. i.e. given these definitions:

    : fun foo = void: {}
    : fun bar = void: {}

    In this example =foo= is equal to =foo=, but =foo= is not equal to
    =bar= even if both functions happen to have identical type
    signature and bodies.

  - Now it is a compile-time error to cast =any= values to function
    types.  We plan to support this at some point, since it is needed
    for things like having =any= fields in structs, but at the moment
    closure values are not tagged with their type at run-time and it
    is better for the user to get compile-time errors.

  - In this release we have changed both the semantics and syntax of
    struct type field initializers.  This change has been motivated by
    our own practical usage of poke.  In poke 1.x a struct field
    initializer had the form:

    : type Foo =
    :   struct
    :   {
    :     int i = 10;
    :     long l;
    :   };

    The initialization of =i= had two effects: newly constructed =Foo=
    struct values would have =i= initialized to 10, and a constraint
    that =i= must equal =10= was also implied when mapping structs of
    type =Foo=.  This worked well, but we realized it is good to
    decouple the implicit constraint from the initialization value:
    sometimes you need one of these, but not both.  It was also not
    possible to add additional constraints.  So we changed the
    semantics of the construction above to denote "initialize to 10,
    but no implicit constraint", with maybe an additional constraint
    like in:

    : type Foo =
    :   struct
    :   {
    :     int i = 10 : i < 100;
    :     long l;
    :   };

    And then we added the new syntax:

    : type Foo =
    :   struct
    :   {
    :     int i == 10;
    :     long l;
    :   };

    to denote "initialize to 10, plus implicit constraint i == 10."

  - The Poke language is quite exception-oriented.  A good example of
    this is the way to detect whether a given alternative in an union
    is the currently selected one: refer to it and see if an =E_elem=
    exception gets raised.  This in practice leads to code like this:

    : try { length.indefinite; return 1; }
    : catch if E_elem { return 0; }

    This is so common that we have introduced a new "exception
    conditional" operator =?!=.  The above code can now be rewritten
    as:

    : return length.indefinite ?! E_elem;

    The new operator also has a ={ ... } ?! EXCEPTION= form where the
    code to execute is a compound statement.

  - Constraints in struct type fields are very often related to the
    values of other fields in the same struct.  The relationship is
    often in the form "if field X has value N, then I should have a
    value M".  We have added a new "logical implication" operator ==>=
    (inspired from the recutils operator with the same name) that
    implements this logic:

    : A => B :=: !A || (A && B)

    For example:

    : uint<1> encoding;
    : uint<5> tag_number : tag_number == BER_TAG_REAL => encoding == 1;

    Meaning that if =tag_number= denotes a "real" then =encoding= must
    be 1.  If =tag_number= does not denote a "real" then the value of
    =encoding= is irrelevant.

  - Mohammad-Reza Nabipoor has contributed support for a new built-in
    function =format=, that is able to format a string out of a format
    string and a list of values.  For example:

    : var s = format ("%s - %s (%i32d)", name, sex, age);

    Will format a string in =s= like:

    : "Francisco Maganto - male (63)"

    The format string is identical to the one used by =printf=, and
    therefore it also accepts =%v= tags to format nested complex
    values like arrays and structs.

  - Exception structs have been expanded to include two additional
    fields: =location= and =msg=.  Both new fields are strings, and
    are used to convey location information (like the field whose
    constraint expression failed resulting in an E_constraint) and an
    explanation of why the exception was raised, respectively.  There
    is no more need to abuse the field =name= for these purposes.

  - Much like in C, the Poke printf format strings use =%= to
    introduce formatting tags, like =%i32d=.  In poke 1.x it was
    embarrassingly not possible to denote the character =%= itself.
    Now =%%= can be used in printf format strings in order to denote a
    single =%= character.

  - If a struct type has labels and all of them are constant, it is
    now considered a complete type. i.e. a type whose size is known at
    compile-time.  This makes it possible to use it in =sizeof= or as
    the unit of an offset.

  - The Poke Virtual Machine settings that configure output are now
    accessible programmatically from Poke using a set of new
    built-ins:

    : vm_{obase,opprint,oacutoff,odepth,oindent,omaps,omode}
    : vm_set_{obase,opprint,oacutoff,odepth,oindent,omaps,omode}

  - We added introspection capabilities: typeof.

* Standard Poke Library updates

  - The =atoi= standard function has been improved in order to parse
    integers with signs.

  - The =ltos= standard function now works for any numeration base
    from 1 to 16, included.

  - New standard functions =opensub= and =openproc= have been
    introduced to help with the creation of "sub" and process IO
    spaces, respectively.  See below under "IO subsystem updates" for
    more information.

  - A new standard function =exit= has been added to the standard
    library, that provides a familiar way to exit a Poke program with
    an optional exit code:

    : fun exit = (int<32> exit_code 0)

    This is just a wrapper to the more "pokeish" and less conventional
    way of exiting, which is to raise an exception of type =EC_exit=:

    : raise Exception { code = EC_exit, exit_status = exit_code };

  - In poke 1.x we forgot to emit an error at compile-time when the
    user defined an union type as pinned.  This obviously doesn't make
    any sense (all the alternatives of an union are "pinned") so now a
    compile-time error is raised.

  - We have realized that it doesn't make much sense for pinned struct
    types (whose fields all have an implicit offset of zero bytes) to
    have field labels.  To avoid confusing the user, the compiler now
    emits a compile-time error if such a type is defined.

  - Unions can no longer have alternatives with labels.  This worked
    in poke 1.x, but had complicated semantics with little real
    practical benefit.  So now a compile-time error is raised if such
    a type is defined.

* IO subsystem updates

  - Each open IO space now maintains a "bias", which is a bit-offset.
    This bias is added to the offset specified in every read or write
    access to the IO space.  This bias is programmable, and can be
    read and set by Poke programs using two new built-in calls:

    : fun iobias = (int<32> ios = get_ios)
    : fun iosetbias = (offset<uint<64,b> bias = 0#b, int<32> ios = get_ios)

    Note how the positioning and default values of these functions
    makes it comfortable to use them at the (poke) prompt.

  - Poke programs can now poke at the standard input, standard output
    and standard error output of the running poke process using the
    new stream IO spaces.

    The new available handlers (to be used with =open=) are =<stdin>=,
    =<stdout>= and =<stderr>=.  A good application of these IO spaces
    is to write filter utilities in Poke.

    This support has been contributed by Egeyar Bagcioglu.

  - The =IOS_F_*= flags used in the =open= builtin has been
    rationalized.  As a consequence the IOS_F_TRUNCATE flag has been
    removed.

  - There is a new built-in =ioflags= that returns the flags used to
    open some particular IO space.

  - =open= now raises an E_perm exception if the user doesn't have
    enough credentials when opening an IO space.  This can happen for
    example with insufficient permissions when opening a file in some
    specified mode.

  - Opening an IO space using a handler =<zero>= now provides an IO
    space of size 2^64 bytes whose contents are all zero bytes, and
    that ignores any writes to it.  Example:

    : var zeroes = open ("<zero>");

  - New IO device =sub= for sub-spaces.  Sub IO spaces that act like a
    (maybe) narrower version of some other given IO space can be
    opened using a =sub://= handler.  Example:

    : var sub = open ("sub://2/0x10/0x1000/somename", IOS_M_RDONLY);

    This will create a sub-space that provides read-only access to the
    =[0x10#B,0x1010#B]= range of bytes of some other IO space with id
    #2.

    Since it can be annoying to format the handler string, a
    convenient utility function called =opensub= has been added to the
    standard library:

    : var sub = opensub (ios, 0x10#B, 0x1000#B, "somename", IOS_M_RDONLY);

  - New IO device =proc= for poking at the memory of live processes.
    The handler to pass to =open= in order to poke at the memory of a
    process with a given PID has the form =pid://PID=.  Example:

    : var fd = open ("pid://1234");

    Since it can be annoying to format the handler string, a
    convenient utility function called =openproc= has been added to
    the standard library:

    : var fd = openproc (1234);

* Terminal hyperlinks updates

  - The payload used in the terminal hyperlinks URL is now reduced to
    a token number.  This makes it more opaque and compact than the
    previous version where we would encode full Poke expressions in
    the URL.

  - The "hyperserver", poke utility subsystem that provides and
    handles the support for "terminal hyperlinks", has been partially
    rewritten.  The new implementation is mostly written in Poke.
    This makes it possible for Poke programs (like pickles) to emit
    and handle terminal hyperlinks.  For example:

    : var url = hserver_make_hyperlink ('e', "2 + 2");
    :
    : term_begin_hyperlink (url, "");
    : print ("[clickme]");
    : term_end_hyperlink;

    Will print a clickable button "[clickme]" in the terminal, which
    once clicked on will execute the Poke code "2 + 2".

  - poke 1.x supported two variants of terminal hyperlinks: "execute"
    and "insert".  Clicking on an "execute" hyperlink triggers the
    execution of some given textual Poke expression or statement.
    Clicking on an "insert" hyperlink triggers the inclusion of some
    given string at the current input position at the prompt.  We now
    introduced a third kind of hyperlinks: the "closure" hyperlinks.
    Once clicked, some given Poke closure/function gets executed.
    This is particularly useful when generating hyperlinks from a Poke
    program.  For example:

    : fun toggle_setting = void: { ... };
    :
    : term_begin_hyperlink (hserver_make_hyperlink ('c', "", (toggle_setting)), "");
    : print "[toggle]";
    : term_end_hyperlinks;

    will print a clickable button "[toggle]" in the terminal, which
    once clicked on will execute the =toggle_setting= function.

* libpoke updates

  - poke now installs a pkg-config file poke.pc to ease using libpoke.

  - libpoke now provides an interface to register foreign IO spaces.
    This allows adding pokeish capabilities to third-party programs.
    As an example, poke integration in GDB has been written (not
    upstreamed yet) that makes it possible to poke the memory of an
    inferior process being debugged.  This is achieved by registering
    callbacks in the foreign IO interface.

  - libpoke now provides an interface to register "alien tokens".
    This is also useful when integrating libpoke in third-party
    applications.  For example, in the GDB integration this interface
    has been used to allow users to refer to the value of GDB symbols
    in Poke programs using this syntax:

    : $main

    and to the address of a given symbol using this syntax:

    : $addr::main

  - It is now possible to create an incremental compiler without
    standard types.  This is useful in cases where the program
    integrating with libpoke provides its own concept of types like
    =int= or =long=.  This is the case of GDB.

  - We added more services in libpoke to operate on PK values.  Many
    more still need to be added.

  - libpoke.h is now C++ compatible.

* Pickles updates

  - New pickle =asn1-ber.pk= provides definitions to poke ASN-1 data
    encoded in BER (Basic Encoding Rules.)

  - New pickles =ustar.pk= provides definitions to poke USTAR file
    systems, standardized by POSIX.1-1988 and POSIX.1-2001.

  - New pickles =ctf-dump.pk= provides functions that dump the data of
    CTF sections in a human-readable form.  Contributed by Indu Bhagat
    on behalf of Oracle Inc.

  - New pickles =jffs2.pk= provides definitions to poke JFFS2 file
    systems.

  - The =elf.pk= pickle has been splitted in 32-bit and 64-bit
    variants, and ELF-32 definitions have been added.

  - The output messages emitted by =argp.pk= have been improved.

  - New tests for the =btf.pk= pickle.  Contributed by David Faust on
    behalf of Oracle Inc.

* Utilities updates

  - New filter =pk-strings.pk=.
  - New filter =pk-bin2poke.pk=.

* Development tools updates

  - RAS (the retarded poke assembler) now allows to split long logical
    lines into several physical lines by finishing them with the
    backslash character.  This is an example:

    : .macro struct_field_extractor @struct_type @field @struct_itype \
    :                               @field_type #ivalw #fieldw

  - RAS now understands the endianness specifiers =IOS_ENDIAN_LSB= and
    =IOS_ENDIAN_MSB=.  Better than hardcoded magic numbers.

  - RAS now emits an error if it finds a .function in which there is
    not exactly one =prolog= instruction and at least one =return=
    instruction.  This problem has bitten me very often, resulting in
    very puzzling and subtle bugs, glglgl.

* Notable bug fixes

  - The infamous, annoying, hated and despised "PVM_VAL_CLS_ENV
    (closure) != NULL" bug has (most probably... crossing fingers,
    toes and whatnot) been finally fixed in this release.  I have
    tried no less than eight times to fix this bug, but not until very
    recently I finally understood what was going on; I thought I did
    and the test case would work, but no I didn't and the bug would
    soon return with renovated hatred.  On my defense, the involved
    area is the hairiest part of the code generator and every time I
    look at it I basically have to re-learn how it works.  Good news
    is: if the same problem manifests again, now we know how to fix
    it.  But hopefully it is fixed now and I will stop receiving hate
    email about this.

  - =--disable-hserver= now actually disables the hyperserver.  Yes,
    really.

* Documentation updates

  - We have added a new online help system to the poke utility, which
    is accessible using the =.help= dot-command.  There are help
    entries for all the commands, dot-commands and global settings.
    This new online help system is written in Poke, making it possible
    to other Poke programs (like pickles) to add their own help topics
    to the system.

  - We have expanded the user manual to cover the new functionality
    and clarify obscure concepts that weren't explained with enough
    clarity.  Despite of this work, the user manual is not yet
    complete, unfortunately, but getting there.

  - The user manual now contains a section that explains how to set up
    your system and terminal emulators to support poke terminal
    hyperlinks.

  - There is a new website called Pokology, https://pokology.net,
    which is maintained by the poke developers and users.  It is a
    live repository of knowledge relative to GNU poke, including
    practical articles, multimedia stuff, hints and tricks, a
    frequently asked question, etc.

* Editor support updates

  - The Emacs modes =poke-mode=, =poke-ras-mode= and =poke-map-mode=
    have been update with more features and bug fixes.

  - We now distribute a module for Poke syntax highlighting for vim.
    Contributed by Matthew T. Ihlenfield.

* Other updates

  - We have rewritten the way global settings (like endianness,
    numeration base used for output, etc) are handled in both libpoke
    and the poke application.  The new implementation introduces a
    "settings registry" which is written itself in Poke.  As such,
    other Poke code (like pickles and the like) have full access to
    the settings registry, and even add their own settings to the
    application.

  - Many improvements in compiler error messages.  This includes
    emitting more meaningful messages, for example "got int<32>
    expected string" instead of "invalid operands in expression".  And
    also better locations, like pointing at the particular operand
    whose type is wrong instead of the entire expression.

 Version 1.4 (3 December 2021)
* User visible changes
  - Operating with arrays must be now much faster.
  - Some of the compiler diagnostics have been made more readable and
    helpful.
  - Limitations in the values of the odepth, oindent and oacutoff have
    been removed.
* Bug fixes
  - Several typos and errors have been fixed in the User Manual.
  - Fix some segfaults in printf "%v".
  - The map operator wasn't using the right IO space in some
    circumstances.  Now it does the right thing.

 Version 1.3 (5 June 2021)
* User visible changes
  - The `dump' command now remembers and re-uses the last used offset
    per IO space.  Before it was a global offset used for all IO
    spaces, which was very confusing.
  - The text accompanying constraint violation exceptions now indicate
    the type and the field whose constraint failed.
  - libpoke.h is now compatible with C++.
  - printf "%v" now gives valid literals for strings in all cases,
    even if they contain non-printable characters.  It uses
    hexadecimal escape sequences \xNN in that case.
* Bug fixes
  - We were overflowing the Boehm GC roots capacity under certain
    circumstances.  This has been fixed in this release.
  - Avoid leaking slots in the exceptions stack.
  - Fix struct printers to skip absent fields.
  - Other bug fixes.

 Version 1.2 (18 April 2021)
* User visible changes
  - The .file dot-command now supports a /c flag for creating new,
    empty files.
  - A new compiler built-in `ioflags' is available, that returns
    the flags of some given IO space.
  - Certain operations now raise a E_perm exception, instead of the
    more generic E_io.
  - A new kind of IO device is now supported: the `zero' IOD.
    Opening "<zero>" will result in an IO space covering the full
    64-bit byte range, that always returns zero on reads and that
    ignores writes.
  - Function values (closures) can now be compared at language-level.
    They are compared by pointer.
  - The compiler now rejects casts from `any' to function types
    instead of ICEing.
  - The `dump' command now doesn't try to print anything if the
    current IOS is not readable.
  - The `dump' command now prints ?? for "unknown" bytes, i.e. for bytes
    in addresses that are not readable in the underlying IO space.
  - The standard function `ltos' now gets an additional optional
    argument `base', that defaults to 10.
  - The `big' and `little' annotations can now be used in any struct
    type field, regardless of its type.
* Bug fixes
  - A very nasty performance bottleneck in pvm_array_insert has been
    fixed.
  - Fix the opening mode of write-only files when the user doesn't
    specify explicit flags in `open'.
  - Avoid spurious EOF exceptions when writing weird integers past
    the end of an IOS.
  - Fix method `value' in leb128.pk
  - Fix ICE while compiling for-statements with several declarations.
  - Properly print > 2^32 addresses in `dump'
  - Other minor fixes.
* Other changes
  - The JSON MI machinery has been rewritten and much improved.
  - More tests in several areas.

 Version 1.1 (21 March 2021)
* User visible changes
  - The IOS_F_TRUNCATE `open' flag has been removed.
  - Constraint expressions and initializers can be now
    used together in struct fields.
* Bug fixes
  - The infamous bug preventing poke work on 32-bit systems is now
    fixed.
  - Better handling of open modes in the file IOD.
  - Improve some translatable strings.
  - poke won't raise an exception when starting if HOME
    is not defined in the environment.
  - The compiler now emits an error if it sees un-map-able
    fields in a struct type.
  - Properly handle the absence of current IOS in the map command.
  - Install Emacs modes.
  - Portability fixes for:
    + Mac OS X 10.5.
    + GNU/Hurd.
    + Solaris 11 OpenIndiana.
    + AIX.
    + mingw.
* Manual
  - Relicensed to GPLv3+.
  - Expand section on struct methods.
  - New section on data padding and alignment.
  - Document the Emacs modes provided by poke.
  - Provide a recommended pokerc configuration for beginners.
  - Other minor fixes based on user feedback.

 Version 1.0 (26 February 2021)
* Initial release!
