]> Cypherpunks repositories - keks.git/commitdiff
Ability to compare strings in schemas
authorSergey Matveev <stargrave@stargrave.org>
Fri, 4 Apr 2025 18:55:56 +0000 (21:55 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Fri, 4 Apr 2025 18:55:56 +0000 (21:55 +0300)
c/lib/schema.c
go/schema/check.go
spec/schema/cmds.texi
spec/schema/tcl.texi
tcl/schema2bin
tcl/schemas/encrypted.tcl
tcl/schemas/pub.tcl

index 2d8c1eb456a1e8b9607932105c8b3d250e847ffdc0ec2ccd94b4a694bc7b07e4..7251dd3a4641d5cfc24cbd161bf13f8e3e1b83538eea32451145dbe2737a68c1 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <stdbool.h>
 #include <stdint.h>
+#include <string.h>
 
 #include "atom.h"
 #include "frombe.h"
@@ -22,6 +23,7 @@
 #include "schema.h"
 
 static const char CmdEach[] = "*";
+static const char CmdEq[] = "=";
 static const char CmdExists[] = "E";
 static const char CmdGT[] = ">";
 static const char CmdLT[] = "<";
@@ -243,6 +245,32 @@ Eached:
         }
         err.msg = "TAKE";
         err.code = KEKSSchemaErrNo;
+    } else if (KEKSStrEqual(&(schema->list[idxSchema].atom), CmdEq)) {
+        err.msg = "EQ";
+        if ((*taken) == SIZE_MAX) {
+            err.code = KEKSSchemaErrNo;
+        } else {
+            idxSchema = schema->list[idxSchema].next;
+            if (idxSchema == 0) {
+                err.code = KEKSSchemaErrInvalidSchema;
+                err.msg = "wrong number of args";
+                return err;
+            }
+            err.offSchema = schema->offsets[idxSchema];
+            if (schema->list[idxSchema].atom.typ != KEKSItemStr) {
+                err.code = KEKSSchemaErrInvalidSchema;
+                err.msg = "non-str EQ";
+                return err;
+            }
+            err.code = ((schema->list[idxSchema].atom.v.str.len ==
+                         data->list[*taken].atom.v.str.len) &&
+                        (memcmp(
+                             schema->list[idxSchema].atom.v.str.ptr,
+                             data->list[*taken].atom.v.str.ptr,
+                             schema->list[idxSchema].atom.v.str.len) == 0)) ?
+                           KEKSSchemaErrNo :
+                           KEKSSchemaErrInvalidData;
+        }
     } else if (KEKSStrEqual(&(schema->list[idxSchema].atom), CmdEach)) {
         err.msg = "EACH";
         (*eachInList) = false;
index df779be5205d37255441fecc76236693c152577580cd66d7369a1477cff78f76..9e0f2e6e3340ea1764f0bcdd801528161fb35c36c11d6464970eee3025a18925 100644 (file)
@@ -30,6 +30,7 @@ import (
 
 const (
        CmdEach        = "*"
+       CmdEq          = "="
        CmdExists      = "E"
        CmdGT          = ">"
        CmdLT          = "<"
@@ -107,6 +108,26 @@ func Check(schemaName string, schemas map[string][][]any, data any) error {
                        default:
                                return fmt.Errorf("%s: %d: %s: non-iterable", schemaName, i, cmd)
                        }
+               case CmdEq:
+                       if vs == nil {
+                               continue
+                       }
+                       if len(act) != 2 {
+                               return fmt.Errorf("%s: %d: %s: wrong number of args", schemaName, i, cmd)
+                       }
+                       expect, ok := act[1].(string)
+                       if !ok {
+                               return fmt.Errorf("%s: %d: %s: bad str: %+v", schemaName, i, cmd, act[1])
+                       }
+                       for _, v := range vs {
+                               got, ok := v.(string)
+                               if !ok {
+                                       return fmt.Errorf("%s: %d: %s: not str: %T", schemaName, i, cmd, v)
+                               }
+                               if got != expect {
+                                       return fmt.Errorf("%s: %d: %s: !=", schemaName, i, cmd)
+                               }
+                       }
                case CmdType:
                        if vs == nil {
                                continue
@@ -193,10 +214,10 @@ func Check(schemaName string, schemas map[string][][]any, data any) error {
                        if vs == nil {
                                continue
                        }
-                       var expect int64
                        if len(act) != 2 {
                                return fmt.Errorf("%s: %d: %s: wrong number of args", schemaName, i, cmd)
                        }
+                       var expect int64
                        switch v := act[1].(type) {
                        case uint64:
                                expect = int64(v)
index 4d1d90e29da5446f8abc6a6a263e0148e2d7af212acdf2068f0b9bb915993da6..f37f324c6c045b466836cf076932cf8385ca87b2340e224b59fe97ec367e97bc 100644 (file)
@@ -59,6 +59,9 @@ maximal time precision. "p" is integer with following possible values:
     @item 18 -- up to attoseconds;
     @end itemize
 
+@item = v
+Check that chosen (if it exists) string element's value equals to "v".
+
 @end table
 
 For example let's check "our" structure, described in CDDL as:
index c5293144ffde29b69f48ad8dad480f490d288fe96e1634f8ded45b0559f8cfd2..05d58626d851998dc512b6d0b004ec63ca7411b63e7eee5de3fe4ce02585ab3b 100644 (file)
@@ -64,4 +64,7 @@ Check that "k" element's length is greater than zero.
 @item IS-SET k
 Check that "k" is non-empty set (map with NIL values).
 
+@item STR= k v
+Check that "k" is a string with value "v".
+
 @end table
index 6df461e7f87fefa7df1ce7ccd0fb39d502132ba41ea86763fe09a71a04ddb9c2..159054d28cf809c1df960f8257379c83f874d38ed0551aca22eb9a6b6895aaa1 100755 (executable)
@@ -28,6 +28,7 @@ proc TAKE {v} {
 proc EXISTS {} {return {{LIST {{STR E}}}}}
 proc !EXISTS {} {return {{LIST {{STR !E}}}}}
 proc EACH {} {return {{LIST {{STR *}}}}}
+proc EQ {v} {subst {{LIST {{STR =} {STR $v}}}}}
 proc TYPE {vs} {
     set l {{STR T}}
     foreach v $vs {
@@ -70,6 +71,15 @@ proc !HAS {k} {
     }]
 }
 
+proc STR= {k v} {
+    evals [subst {
+        {TAKE $k}
+        {TYPE {STR}}
+        {TAKE $k}
+        {EQ $v}
+    }]
+}
+
 proc LEN= {k l} {
     evals [subst {
         {TAKE $k}
index c864fea642fbbe656be7e447cce24f739723bc6dc6c65a23c68fc46ac4769337..4c218c3d42870633348c907f439fb283a28836b402b02eb378374da5413f9869 100644 (file)
@@ -37,8 +37,7 @@ balloon-cost {
 
 kem-balloon-blake2b-hkdf {
     {HAS a}
-    {TYPE= a {STR}}
-    {!EMPTY a}
+    {STR= a balloon-blake2b-hkdf}
     {HAS cek}
     {TYPE= cek {BIN}}
     {HAS salt}
index 376d65b348744b62bc337d20977af4e030bea9fb7b66ce9011e612025215229b..4ca815ae06a792a811568014b66f6cd924761f7c408fd3dc3955f5abdb5d0465 100644 (file)
@@ -21,8 +21,7 @@ pub {
 
 load {
     {HAS t}
-    {TYPE= t {STR}}
-    {!EMPTY t}
+    {STR= t pub}
     {HAS v}
     {SCHEMA= v pub-load}
 }