[Cbor] building "enum" from CDDL map keys

Michael Richardson <mcr+ietf@sandelman.ca> Sun, 14 March 2021 21:08 UTC

Return-Path: <mcr+ietf@sandelman.ca>
X-Original-To: cbor@ietfa.amsl.com
Delivered-To: cbor@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id B38173A158F for <cbor@ietfa.amsl.com>; Sun, 14 Mar 2021 14:08:56 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.899
X-Spam-Level:
X-Spam-Status: No, score=-1.899 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id mNRKeVjR4HhC for <cbor@ietfa.amsl.com>; Sun, 14 Mar 2021 14:08:54 -0700 (PDT)
Received: from tuna.sandelman.ca (tuna.sandelman.ca [209.87.249.19]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 9EB213A158E for <cbor@ietf.org>; Sun, 14 Mar 2021 14:08:54 -0700 (PDT)
Received: from localhost (localhost [127.0.0.1]) by tuna.sandelman.ca (Postfix) with ESMTP id C5F0C389CC for <cbor@ietf.org>; Sun, 14 Mar 2021 17:14:13 -0400 (EDT)
Received: from tuna.sandelman.ca ([127.0.0.1]) by localhost (localhost [127.0.0.1]) (amavisd-new, port 10024) with LMTP id W03KB5l9ACtd for <cbor@ietf.org>; Sun, 14 Mar 2021 17:14:13 -0400 (EDT)
Received: from sandelman.ca (obiwan.sandelman.ca [IPv6:2607:f0b0:f:2::247]) by tuna.sandelman.ca (Postfix) with ESMTP id 3E315389CA for <cbor@ietf.org>; Sun, 14 Mar 2021 17:14:13 -0400 (EDT)
Received: from localhost (localhost [IPv6:::1]) by sandelman.ca (Postfix) with ESMTP id 359A71C0 for <cbor@ietf.org>; Sun, 14 Mar 2021 17:08:53 -0400 (EDT)
From: Michael Richardson <mcr+ietf@sandelman.ca>
To: cbor@ietf.org
X-Attribution: mcr
X-Mailer: MH-E 8.6+git; nmh 1.7+dev; GNU Emacs 26.1
X-Face: $\n1pF)h^`}$H>Hk{L"x@)JS7<%Az}5RyS@k9X%29-lHB$Ti.V>2bi.~ehC0; <'$9xN5Ub# z!G,p`nR&p7Fz@^UXIn156S8.~^@MJ*mMsD7=QFeq%AL4m<nPbLgmtKK-5dC@#:k
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="=-=-="; micalg="pgp-sha512"; protocol="application/pgp-signature"
Date: Sun, 14 Mar 2021 17:08:53 -0400
Message-ID: <1301.1615756133@localhost>
Archived-At: <https://mailarchive.ietf.org/arch/msg/cbor/xyMC1qjkp1DHBtyXVYcUzW2IkQg>
Subject: [Cbor] building "enum" from CDDL map keys
X-BeenThere: cbor@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "Concise Binary Object Representation \(CBOR\)" <cbor.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/cbor>, <mailto:cbor-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/cbor/>
List-Post: <mailto:cbor@ietf.org>
List-Help: <mailto:cbor-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/cbor>, <mailto:cbor-request@ietf.org?subject=subscribe>
X-List-Received-Date: Sun, 14 Mar 2021 21:08:57 -0000

This seems to be primarily about a specific parser for CDDL, (software), and
the IETF is not entirely concerned about how specific software works (or
fails to), except in as-much that it is implementator feedback.

I have figured out how to use Carsten's "cddl" program to process my CDDL
file for the internal protocol that led me to file-magic and network-address.
Yes, I've actually already implemented in C first (validated with hundreds of
unit tests), and then wrote it down in CDDL before I implement in Rust.
(It was also really a process of discoverying what data was part of which
commands, which has so far remained an internal-only issue)

So I have a series of maps (I'm unclear if I should, in CDDL refer to them as
tables).  So I have, for example:

whack-message = {
  WHACK_STATUS     => { },
  WHACK_SHUTDOWN   => { },
  WHACK_OPTIONS    => OptionsCommand,
  WHACK_CONNECTION => Connection,
  ...
}
...
WHACK_STATUS =  1
WHACK_SHUTDOWN =2
WHACK_OPTIONS  =3
WHACK_CONNECTION=4
...

So to be clear, a single command message is a map, and each map key implies a
command.  This is a kind of very-wide-instruction-set, and is copied from the C-code.
In practice, we rarely do more than one command at the same time.

(I initially used : rather than => and then learnt that was wrong. That cddl
program helped me a lot here.  It also helped me find a typo, "unit" rather
than "uint", although the error handling there could be improved)

With the undocumented "e" option, I can create output like:

#define CDDL_WHACK_STATUS 1
#define CDDL_WHACK_SHUTDOWN 2
#define CDDL_WHACK_OPTIONS 3
#define CDDL_WHACK_CONNECTION 4

(or any other single-line format) which is useful, but not ideal.  What I really want is:

  enum whack_message_keys {
     WHACK_STATUS = 1,
     WHACK_SHUTDOWN=2,
     WHACK_OPTIONS =3,
     WHACK_CONNECTION=4
     ...
  };

A reason I want to do this is so that my compiler can help me identify:
  1) duplicate values
  2) missing handling of case statements

<CORE POINT>
I looked through the cddl code, and I am not at all certain that CDDL has
enough meta information about where the keys are used to be able to do this.
I think that it's also possible to use the same key values in many places,
and I even do this myself.

I think that what I'm doing is not unique: maybe I should be describing this
in CDDL in a different way.
</CORE POINT>

So at this point, I'm generating to another file:
	printf "/* generated from whack.cddl */\n" >include/whack_values.h
	printf "#ifndef WHACKVALUES_H\n#define WHACKVALUES_H\n" >>include/whack_values.h
	cddl docs/whack.cddl ep                  >>include/whack_values.h
	printf "#endif /* WHACKVALUES_H */\n"    >>include/whack_values.h

and then I would have:

enum whack_CBOR_actions {
    WHACK_STATUS =  CDDL_WHACK_STATUS,
    WHACK_SHUTDOWN =CDDL_WHACK_SHUTDOWN,
    WHACK_OPTIONS  =CDDL_WHACK_OPTIONS,
    WHACK_CONNECTION=CDDL_WHACK_CONNECTION,
...

but that requires more work that I'd like, and I won't get the switch(enum)
benefit from the compiler, telling me that I forgot to implement something.

(There are, however, some conflicting requirements here, because I probably
do want a default: clause that skips CBOR that I don't know, in order to
allow for forward and backwards compatibility.  This does not apply at all
levels of the decode though)



--
]               Never tell me the odds!                 | ipv6 mesh networks [
]   Michael Richardson, Sandelman Software Works        |    IoT architect   [
]     mcr@sandelman.ca  http://www.sandelman.ca/        |   ruby on rails    [







--
Michael Richardson <mcr+IETF@sandelman.ca>   . o O ( IPv6 IøT consulting )
           Sandelman Software Works Inc, Ottawa and Worldwide