+static void mme_free(MaskMap_Entry *mme) {
+ TFREE(mme->prefix); mme->prefix=0;
+ if (mme->data) { Tcl_DecrRefCount(mme->data); mme->data=0; }
+}
+
+static int mme_parsekey(Tcl_Interp *ip, MaskMap_Entry *mme,
+ Tcl_Obj *prefixo, Tcl_Obj *prefixleno,
+ int inmap) {
+ /* *mme should be blank entry; after exit (even error exit) it will be valid
+ * - on errors, it will be blank. inmap is 1 if we're parsing an existing
+ * map or 0 if it's an entry to be added or modified. */
+ HBytes_Value prefix;
+ int suppliedprefixbytes, prefixlen, wantprefixbytes;
+ int rc;
+
+ hbytes_empty(&prefix);
+
+ rc= pat_hb(ip,prefixo,&prefix); if (rc) goto x_rc;
+ rc= pat_int(ip,prefixleno,&prefixlen); if (rc) goto x_rc;
+
+ wantprefixbytes= prefix_bytes(prefixlen);
+ suppliedprefixbytes= hbytes_len(&prefix);
+
+ if (suppliedprefixbytes < wantprefixbytes) {
+ rc= staticerr(ip, "mask-map entry PREFIX too short for PREFIX-LEN",
+ "HBYTES MASKMAP SYNTAX UNDERRUN");
+ goto x_rc;
+ }
+ if (inmap && suppliedprefixbytes > wantprefixbytes) {
+ rc= staticerr(ip, "mask-map existing entry PREFIX too long for PREFIX-LEN",
+ "HBYTES MASKMAP SYNTAX OVERRUN");
+ goto x_rc;
+ }
+ mme->prefixlen= prefixlen;
+ mme->prefix= TALLOC(wantprefixbytes); assert(mme->prefix);
+ memcpy(mme->prefix, hbytes_data(&prefix), wantprefixbytes);
+ return TCL_OK;
+
+ x_rc:
+ mme_free(mme);
+ return rc;
+}
+
+static int mme_ordercompare(MaskMap_Entry *a, MaskMap_Entry *b) {
+ if (a->prefixlen != b->prefixlen)
+ return a->prefixlen - b->prefixlen;
+ else
+ return memcmp(b->prefix, a->prefix, prefix_bytes(a->prefixlen));
+}
+
+/*---------- useful operations on MaskMap_Value etc. ----------*/
+