-*- text -*-

Stuff that should still be done on the ASN.1 encoder conversion:

* Add support for opaque objects (pre-encoded fields, or ANY), and fix
  up those remaining encoders (e.g., asn1_encode_sam_challenge_2) that
  need them.

* Convert PKINIT encoders, after we have test cases.

* Make offsetof uses conforming.  Currently we may use foo.bar or
  foo[0] as fields.

* Script to generate the tables.  Then each type or field entry can
  generate multiple bits of code, instead of forcing us to bury the
  type consistency checking into the structure initializer
  expression.  For example, we might generate these bits of code from
  one field descriptor:

  * Field table entry.

  * Type-checking code: Create a pointer of the expected type and a
    pointer of the actual type (address of field of automatic struct),
    and verify consistency with comparison, assignment, or conditional
    expr.  Plenty of comments to indicate what's being compared and
    what a compiler complain means.

  * Range-checking code for bitfields: Create an automatic field info
    struct, fill in the computed offset or whatever, read it back,
    make sure it matches.  Also with comments.

  * Possibly header declarations describing the types that could be
    imported, with correct handles *and* C types.

  * Static declarations for non-exported types to keep symbol table
    sizes down.

  Then similar bits of code (e.g., all the field table entries) can be
  pulled together into the appropriate places.

* Some kind of "module" system for exporting and importing encoders,
  better than relying on the "type_*" variable names.  Probably use
  meaningful strings that indicate both the ASN.1 type and the
  associated C type.  Find a way to fit "imported type" into this
  scheme so that we can cleanly move the PKINIT types into the PKINIT
  plugin, the LDAP types into the LDAP plugin, etc., and still let
  them use the encoders in the code.  Only a subset of types would be
  exported probably.

* More compact encoding: For tags and optional-field bit positions,
  encode N+1, and use 0 for "none", then make the field unsigned.
  Currently the fields are signed, non-negative values hold useful
  data, -1 means "none", and MIN..-2 are unused.  Changing this will
  either let us reduce the field size one bit, or extend the maximum
  tag/bitpos value from 2**(N-1)-1 to 2**N-2.

* More compact encoding: Use a union with designated initializers, or
  some ugly casting, to make the structures smaller by not having all
  fields present when we never use all of them at once.  The union
  approach is certainly more appealing, aside from the little detail
  that it won't work on Windows unless we do all the initialization at
  run time.

* Pie in the sky: A verbose mode that can tell you "missing field
  KDC-REP.cname.name-string[1].data" or some such.  This would require
  tracking the stack of pending encodes and adding strings with type
  and field names.

* For ALL_POINTERS_ARE_THE_SAME mode (which is not strictly conforming
  with the C standard, and thus not default currently, but makes
  things a little smaller and faster), eliminate the loadptr structure
  entry.

* Maybe: Reorganize the data of a "module" so everything needing
  relocation is put in some tables, referenced by index from other
  structures without relocations.  E.g., for krb5_data, here's the
  offset for the data pointer, here's the offset for the length value,
  here's the index into the pointer reader function table, here's the
  index into the length reader function table, here's an index into
  the string-type encoder table.

  Using an index into a set of pointer types, with a single function
  taking an integer parameter used to switch between various
  ptr-to-ptr-to-type code paths, will be a lot smaller -- with a good
  compiler the function will probably collapse to a simple
  fetch-a-pointer function ignoring the integer argument, while at the
  C level it's strictly conforming by using the correct types for
  access.

* Table-driven decoders?
