Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libxmlb for openSUSE:Factory checked 
in at 2023-04-29 17:27:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libxmlb (Old)
 and      /work/SRC/openSUSE:Factory/.libxmlb.new.1533 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libxmlb"

Sat Apr 29 17:27:42 2023 rev:11 rq:1083359 version:0.3.11

Changes:
--------
--- /work/SRC/openSUSE:Factory/libxmlb/libxmlb.changes  2023-01-21 
19:10:07.492806483 +0100
+++ /work/SRC/openSUSE:Factory/.libxmlb.new.1533/libxmlb.changes        
2023-04-29 17:27:50.650467709 +0200
@@ -1,0 +2,9 @@
+Thu Apr 27 22:24:36 UTC 2023 - Dirk Müller <dmuel...@suse.com>
+
+- update to 0.3.11:
+  * Add limited support for XPath 1.0 'in' (Richard Hughes)
+  * Add support for zstd (Richard Hughes)
+  * Do not assert() when decompressing invalid LZMA (Richard
+    Hughes)
+
+-------------------------------------------------------------------

Old:
----
  libxmlb-0.3.10.tar.gz

New:
----
  libxmlb-0.3.11.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libxmlb.spec ++++++
--- /var/tmp/diff_new_pack.m1qkf4/_old  2023-04-29 17:27:51.094469569 +0200
+++ /var/tmp/diff_new_pack.m1qkf4/_new  2023-04-29 17:27:51.106469619 +0200
@@ -19,7 +19,7 @@
 
 %define sover 2
 Name:           libxmlb
-Version:        0.3.10
+Version:        0.3.11
 Release:        0
 Summary:        Library for querying compressed XML metadata
 License:        LGPL-2.1-or-later
@@ -36,6 +36,7 @@
 BuildRequires:  pkgconfig(gobject-introspection-1.0)
 BuildRequires:  pkgconfig(gtk-doc)
 BuildRequires:  pkgconfig(liblzma)
+BuildRequires:  pkgconfig(libzstd)
 # Needed for the self tests
 BuildRequires:  pkgconfig(shared-mime-info)
 %{?suse_build_hwcaps_libs}

++++++ libxmlb-0.3.10.tar.gz -> libxmlb-0.3.11.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/.clang-tidy 
new/libxmlb-0.3.11/.clang-tidy
--- old/libxmlb-0.3.10/.clang-tidy      1970-01-01 01:00:00.000000000 +0100
+++ new/libxmlb-0.3.11/.clang-tidy      2023-02-20 10:48:39.000000000 +0100
@@ -0,0 +1,42 @@
+---
+Checks: "-*,\
+bugprone-*,\
+-bugprone-assignment-in-if-condition,\
+-bugprone-easily-swappable-parameters,\
+-bugprone-implicit-widening-of-multiplication-result,\
+-bugprone-macro-parentheses,\
+-bugprone-misplaced-widening-cast,\
+-bugprone-narrowing-conversions,\
+-bugprone-reserved-identifier,\
+-bugprone-too-small-loop-variable,\
+-bugprone-unchecked-optional-access,\
+misc-*,\
+-misc-confusable-identifiers,\
+-misc-const-correctness,\
+-misc-non-private-member-variables-in-classes,\
+-misc-no-recursion,\
+-misc-static-assert,\
+-misc-unused-parameters,\
+modernize-*,\
+-modernize-macro-to-enum,\
+-modernize-use-trailing-return-type,\
+-modernize-use-transparent-functors,\
+performance-*,\
+-performance-inefficient-vector-operation,\
+-performance-no-int-to-ptr,\
+readability-*,\
+-readability-avoid-const-params-in-decls,\
+-readability-braces-around-statements,\
+-readability-function-cognitive-complexity,\
+-readability-identifier-length,\
+-readability-identifier-naming,\
+-readability-implicit-bool-conversion,\
+-readability-isolate-declaration,\
+-readability-magic-numbers,\
+-readability-non-const-parameter,\
+-readability-qualified-auto,\
+-readability-redundant-declaration,\
+-readability-suspicious-call-argument,\
+-readability-uppercase-literal-suffix,\
+"
+...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/NEWS new/libxmlb-0.3.11/NEWS
--- old/libxmlb-0.3.10/NEWS     2022-09-11 12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/NEWS     2023-02-20 10:48:39.000000000 +0100
@@ -1,3 +1,14 @@
+Version 0.3.11
+~~~~~~~~~~~~~~
+Released: 2023-02-20
+
+New Features:
+ - Add limited support for XPath 1.0 'in' (Richard Hughes)
+ - Add support for zstd (Richard Hughes)
+
+Bugfixes:
+ - Do not assert() when decompressing invalid LZMA (Richard Hughes)
+
 Version 0.3.10
 ~~~~~~~~~~~~~~
 Released: 2022-09-11
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/RELEASE new/libxmlb-0.3.11/RELEASE
--- old/libxmlb-0.3.10/RELEASE  2022-09-11 12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/RELEASE  2023-02-20 10:48:39.000000000 +0100
@@ -2,11 +2,11 @@
 
 1. Write NEWS entries for libxmlb in the same format as usual.
 
-git shortlog 0.3.9.. | grep -i -v trivial | grep -v Merge > NEWS.new
+git shortlog 0.3.10.. | grep -i -v trivial | grep -v Merge > NEWS.new
 
-Version 0.3.10
+Version 0.3.11
 ~~~~~~~~~~~~~~
-Released: 2022-xx-xx
+Released: 2023-xx-xx
 
 New Features:
 Bugfixes:
@@ -15,7 +15,7 @@
 Commit changes to git:
 
 # MAKE SURE THESE ARE CORRECT
-export release_ver="0.3.10"
+export release_ver="0.3.11"
 
 git commit -a -m "Release libxmlb ${release_ver}" --no-verify
 git tag -s -f -m "Release libxmlb ${release_ver}" "${release_ver}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/contrib/ci/Dockerfile-debian 
new/libxmlb-0.3.11/contrib/ci/Dockerfile-debian
--- old/libxmlb-0.3.10/contrib/ci/Dockerfile-debian     2022-09-11 
12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/contrib/ci/Dockerfile-debian     2023-02-20 
10:48:39.000000000 +0100
@@ -15,10 +15,11 @@
        python3-wheel \
        shared-mime-info \
        liblzma-dev \
+       libzstd-dev \
        uuid-dev \
        pkg-config
 
 # Meson is too old in unstable, and that won't change until Buster is released
-RUN pip3 install meson
+RUN pip3 install meson --break-system-packages
 
 WORKDIR /build
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/contrib/ci/Dockerfile-fedora 
new/libxmlb-0.3.11/contrib/ci/Dockerfile-fedora
--- old/libxmlb-0.3.10/contrib/ci/Dockerfile-fedora     2022-09-11 
12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/contrib/ci/Dockerfile-fedora     2023-02-20 
10:48:39.000000000 +0100
@@ -5,6 +5,7 @@
        diffutils \
        gcovr \
        xz-devel \
+       libzstd-devel \
        git-core \
        glib2-devel \
        gobject-introspection-devel \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/contrib/ci/Dockerfile-fedora-w64 
new/libxmlb-0.3.11/contrib/ci/Dockerfile-fedora-w64
--- old/libxmlb-0.3.10/contrib/ci/Dockerfile-fedora-w64 2022-09-11 
12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/contrib/ci/Dockerfile-fedora-w64 2023-02-20 
10:48:39.000000000 +0100
@@ -7,6 +7,7 @@
        git-core \
        meson \
        mingw64-xz-libs \
+       mingw64-zstd \
        mingw64-gcc \
        mingw64-glib2 \
        mingw64-pkg-config \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/contrib/libxmlb.spec.in 
new/libxmlb-0.3.11/contrib/libxmlb.spec.in
--- old/libxmlb-0.3.10/contrib/libxmlb.spec.in  2022-09-11 12:09:18.000000000 
+0200
+++ new/libxmlb-0.3.11/contrib/libxmlb.spec.in  2023-02-20 10:48:39.000000000 
+0100
@@ -16,6 +16,7 @@
 BuildRequires: meson
 BuildRequires: gobject-introspection-devel
 BuildRequires: xz-devel
+BuildRequires: libzstd-devel
 %if 0%{?rhel} == 7
 BuildRequires: python36-setuptools
 %else
Binary files old/libxmlb-0.3.10/data/test.xml.zstd and 
new/libxmlb-0.3.11/data/test.xml.zstd differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/meson.build 
new/libxmlb-0.3.11/meson.build
--- old/libxmlb-0.3.10/meson.build      2022-09-11 12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/meson.build      2023-02-20 10:48:39.000000000 +0100
@@ -1,5 +1,5 @@
 project('libxmlb', 'c',
-  version : '0.3.10',
+  version : '0.3.11',
   license : 'LGPL-2.1+',
   meson_version : '>=0.47.0',
   default_options : ['warning_level=2', 'c_std=c99'],
@@ -119,6 +119,7 @@
 gio = dependency('gio-2.0', version : '>= 2.45.8')
 giounix = dependency('gio-unix-2.0', version : '>= 2.45.8', required: false)
 lzma = dependency('liblzma')
+zstd = dependency('libzstd')
 if giounix.found()
   conf.set('HAVE_GIO_UNIX', '1')
 endif
@@ -132,6 +133,7 @@
 libxmlb_deps = [
   gio,
   lzma,
+  zstd,
 ]
 
 # support stemming of search tokens
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/meson.build 
new/libxmlb-0.3.11/src/meson.build
--- old/libxmlb-0.3.10/src/meson.build  2022-09-11 12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/src/meson.build  2023-02-20 10:48:39.000000000 +0100
@@ -49,6 +49,7 @@
     'xb-builder-source-ctx.c',
     'xb-common.c',
     'xb-lzma-decompressor.c',
+    'xb-zstd-decompressor.c',
     'xb-machine.c',
     'xb-opcode.c',
     'xb-node.c',
@@ -220,6 +221,7 @@
       'xb-builder-source-ctx.c',
       'xb-common.c',
       'xb-lzma-decompressor.c',
+      'xb-zstd-decompressor.c',
       'xb-machine.c',
       'xb-node.c',
       'xb-node-query.c',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-builder-source-ctx-private.h 
new/libxmlb-0.3.11/src/xb-builder-source-ctx-private.h
--- old/libxmlb-0.3.10/src/xb-builder-source-ctx-private.h      2022-09-11 
12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/src/xb-builder-source-ctx-private.h      2023-02-20 
10:48:39.000000000 +0100
@@ -6,8 +6,6 @@
 
 #pragma once
 
-#include <glib-object.h>
-
 #include "xb-builder-source-ctx.h"
 
 G_BEGIN_DECLS
@@ -15,7 +13,7 @@
 XbBuilderSourceCtx *
 xb_builder_source_ctx_new(GFile *file, GInputStream *istream);
 void
-xb_builder_source_ctx_set_filename(XbBuilderSourceCtx *self, const gchar 
*filename);
+xb_builder_source_ctx_set_filename(XbBuilderSourceCtx *self, const gchar 
*basename);
 gchar *
 xb_builder_source_ctx_get_content_type(XbBuilderSourceCtx *self,
                                       GCancellable *cancellable,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-builder-source-ctx.h 
new/libxmlb-0.3.11/src/xb-builder-source-ctx.h
--- old/libxmlb-0.3.10/src/xb-builder-source-ctx.h      2022-09-11 
12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/src/xb-builder-source-ctx.h      2023-02-20 
10:48:39.000000000 +0100
@@ -6,7 +6,7 @@
 
 #pragma once
 
-#include <glib-object.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-builder-source.c 
new/libxmlb-0.3.11/src/xb-builder-source.c
--- old/libxmlb-0.3.10/src/xb-builder-source.c  2022-09-11 12:09:18.000000000 
+0200
+++ new/libxmlb-0.3.11/src/xb-builder-source.c  2023-02-20 10:48:39.000000000 
+0100
@@ -15,6 +15,7 @@
 #include "xb-builder-source-ctx-private.h"
 #include "xb-builder-source-private.h"
 #include "xb-lzma-decompressor.h"
+#include "xb-zstd-decompressor.h"
 
 typedef struct {
        GInputStream *istream;
@@ -527,6 +528,18 @@
        return g_converter_input_stream_new(istream, conv);
 }
 
+static GInputStream *
+xb_builder_source_load_zstd_cb(XbBuilderSource *self,
+                              XbBuilderSourceCtx *ctx,
+                              gpointer user_data,
+                              GCancellable *cancellable,
+                              GError **error)
+{
+       GInputStream *istream = xb_builder_source_ctx_get_stream(ctx);
+       g_autoptr(GConverter) conv = G_CONVERTER(xb_zstd_decompressor_new());
+       return g_converter_input_stream_new(istream, conv);
+}
+
 static void
 xb_builder_source_adapter_free(XbBuilderSourceAdapter *item)
 {
@@ -581,6 +594,11 @@
                                      xb_builder_source_load_lzma_cb,
                                      NULL,
                                      NULL);
+       xb_builder_source_add_adapter(self,
+                                     "application/zstd",
+                                     xb_builder_source_load_zstd_cb,
+                                     NULL,
+                                     NULL);
 }
 
 /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-common-private.h 
new/libxmlb-0.3.11/src/xb-common-private.h
--- old/libxmlb-0.3.10/src/xb-common-private.h  2022-09-11 12:09:18.000000000 
+0200
+++ new/libxmlb-0.3.11/src/xb-common-private.h  2023-02-20 10:48:39.000000000 
+0100
@@ -6,7 +6,7 @@
 
 #pragma once
 
-#include <glib.h>
+#include <gio/gio.h>
 
 gchar *
 xb_content_type_guess(const gchar *filename, const guchar *buf, gsize bufsz);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-common.c 
new/libxmlb-0.3.11/src/xb-common.c
--- old/libxmlb-0.3.10/src/xb-common.c  2022-09-11 12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/src/xb-common.c  2023-02-20 10:48:39.000000000 +0100
@@ -8,7 +8,6 @@
 
 #include "config.h"
 
-#include <gio/gio.h>
 #include <string.h>
 
 #include "xb-common-private.h"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-lzma-decompressor.c 
new/libxmlb-0.3.11/src/xb-lzma-decompressor.c
--- old/libxmlb-0.3.10/src/xb-lzma-decompressor.c       2022-09-11 
12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/src/xb-lzma-decompressor.c       2023-02-20 
10:48:39.000000000 +0100
@@ -117,10 +117,45 @@
                                    "Invalid compressed data");
                return G_CONVERTER_ERROR;
        }
+       if (res == LZMA_UNSUPPORTED_CHECK) {
+               g_set_error_literal(error,
+                                   G_IO_ERROR,
+                                   G_IO_ERROR_NOT_SUPPORTED,
+                                   "Cannot calculate the integrity check");
+               return G_CONVERTER_ERROR;
+       }
        if (res == LZMA_MEM_ERROR) {
                g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not 
enough memory");
                return G_CONVERTER_ERROR;
        }
+       if (res == LZMA_FORMAT_ERROR) {
+               g_set_error_literal(error,
+                                   G_IO_ERROR,
+                                   G_IO_ERROR_NOT_SUPPORTED,
+                                   "File format not recognized");
+               return G_CONVERTER_ERROR;
+       }
+       if (res == LZMA_OPTIONS_ERROR) {
+               g_set_error_literal(error,
+                                   G_IO_ERROR,
+                                   G_IO_ERROR_NOT_SUPPORTED,
+                                   "Invalid or unsupported options");
+               return G_CONVERTER_ERROR;
+       }
+       if (res == LZMA_BUF_ERROR) {
+               g_set_error_literal(error,
+                                   G_IO_ERROR,
+                                   G_IO_ERROR_INVALID_DATA,
+                                   "No progress is possible");
+               return G_CONVERTER_ERROR;
+       }
+       if (res == LZMA_PROG_ERROR) {
+               g_set_error_literal(error,
+                                   G_IO_ERROR,
+                                   G_IO_ERROR_INVALID_ARGUMENT,
+                                   "Programming error");
+               return G_CONVERTER_ERROR;
+       }
        if (res == LZMA_OK || res == LZMA_STREAM_END) {
                *bytes_read = inbuf_size - self->lzmastream.avail_in;
                *bytes_written = outbuf_size - self->lzmastream.avail_out;
@@ -129,7 +164,9 @@
                return G_CONVERTER_CONVERTED;
        }
 
-       g_assert_not_reached();
+       /* fallback */
+       g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unhandled error code 
%u", res);
+       return G_CONVERTER_ERROR;
 }
 
 static void
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-machine.c 
new/libxmlb-0.3.11/src/xb-machine.c
--- old/libxmlb-0.3.10/src/xb-machine.c 2022-09-11 12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/src/xb-machine.c 2023-02-20 10:48:39.000000000 +0100
@@ -61,6 +61,8 @@
        GDestroyNotify user_data_free;
 } XbMachineMethodItem;
 
+#define XB_MACHINE_STACK_LEVELS_MAX 20
+
 /**
  * xb_machine_set_debug_flags:
  * @self: a #XbMachine
@@ -248,7 +250,11 @@
 }
 
 static gboolean
-xb_machine_parse_add_func(XbMachine *self, XbStack *opcodes, const gchar 
*func_name, GError **error)
+xb_machine_parse_add_func(XbMachine *self,
+                         XbStack *opcodes,
+                         const gchar *func_name,
+                         guint8 level,
+                         GError **error)
 {
        XbOpcode *opcode;
 
@@ -265,6 +271,7 @@
                xb_stack_pop(opcodes, NULL, NULL);
                return FALSE;
        }
+       xb_opcode_set_level(opcode, level);
 
        return TRUE;
 }
@@ -344,6 +351,7 @@
                          XbStack *opcodes,
                          const gchar *text,
                          gssize text_len,
+                         guint8 level,
                          GError **error)
 {
        XbMachinePrivate *priv = GET_PRIVATE(self);
@@ -370,10 +378,18 @@
        for (guint i = 0; i < priv->text_handlers->len; i++) {
                XbMachineTextHandlerItem *item = 
g_ptr_array_index(priv->text_handlers, i);
                gboolean handled = FALSE;
+               guint opcodes_sz = xb_stack_get_size(opcodes);
                if (!item->handler_cb(self, opcodes, str, &handled, 
item->user_data, error))
                        return FALSE;
-               if (handled)
+               if (handled) {
+                       /* ideally the XbMachineTextHandlerFunc would contain a 
`guint8 level` but
+                        * that is now public ABI. Just fixup the level for any 
added opcodes */
+                       for (guint j = xb_stack_get_size(opcodes); j > 
opcodes_sz; j--) {
+                               XbOpcode *op_tmp = xb_stack_peek(opcodes, j - 
1);
+                               xb_opcode_set_level(op_tmp, level);
+                       }
                        return TRUE;
+               }
        }
 
        /* quoted text */
@@ -384,6 +400,7 @@
                        if (!xb_stack_push(opcodes, &opcode, error))
                                return FALSE;
                        xb_opcode_text_init_steal(opcode, 
g_steal_pointer(&tmp));
+                       xb_opcode_set_level(opcode, level);
                        return TRUE;
                }
        }
@@ -400,6 +417,7 @@
                                       g_steal_pointer(&tmp),
                                       XB_SILO_UNSET,
                                       g_free);
+                       xb_opcode_set_level(opcode, level);
                        return TRUE;
                }
        }
@@ -410,6 +428,7 @@
                if (!xb_stack_push(opcodes, &opcode, error))
                        return FALSE;
                xb_opcode_bind_init(opcode);
+               xb_opcode_set_level(opcode, level);
                return TRUE;
        }
 
@@ -419,6 +438,7 @@
                if (!xb_stack_push(opcodes, &opcode, error))
                        return FALSE;
                xb_opcode_integer_init(opcode, val);
+               xb_opcode_set_level(opcode, level);
                return TRUE;
        }
 
@@ -437,6 +457,7 @@
                         const gchar *text,
                         gssize text_len,
                         gboolean is_method,
+                        guint8 level,
                         GError **error)
 {
        XbMachinePrivate *priv = GET_PRIVATE(self);
@@ -450,63 +471,90 @@
        for (gssize i = 0; i < text_len; i++) {
                for (guint j = 0; j < priv->operators->len; j++) {
                        XbMachineOperator *op = 
g_ptr_array_index(priv->operators, j);
-                       if (strncmp(text + i, op->str, op->strsz) == 0) {
-                               if (is_method) {
-                                       /* after then before */
+                       if (strncmp(text + i, op->str, op->strsz) != 0)
+                               continue;
+                       if (is_method) {
+                               XbOpcode *op_tail;
+                               const gchar *op_name = op->name;
+
+                               /* after then before */
+                               if (!xb_machine_parse_section(self,
+                                                             opcodes,
+                                                             text + i + 
op->strsz,
+                                                             -1,
+                                                             is_method,
+                                                             level,
+                                                             error))
+                                       return FALSE;
+                               if (i > 0) {
                                        if (!xb_machine_parse_section(self,
                                                                      opcodes,
-                                                                     text + i 
+ op->strsz,
-                                                                     -1,
-                                                                     is_method,
+                                                                     text,
+                                                                     i,
+                                                                     FALSE,
+                                                                     level,
                                                                      error))
                                                return FALSE;
-                                       if (i > 0) {
-                                               if 
(!xb_machine_parse_section(self,
-                                                                             
opcodes,
-                                                                             
text,
-                                                                             i,
-                                                                             
FALSE,
-                                                                             
error))
-                                                       return FALSE;
-                                       }
-                                       if (!xb_machine_parse_add_func(self,
-                                                                      opcodes,
-                                                                      op->name,
-                                                                      error))
-                                               return FALSE;
-                               } else {
-                                       /* before then after */
-                                       if (i > 0) {
-                                               if 
(!xb_machine_parse_section(self,
-                                                                             
opcodes,
-                                                                             
text,
-                                                                             i,
-                                                                             
FALSE,
-                                                                             
error))
-                                                       return FALSE;
-                                       }
+                               }
+
+                               /* multiple "eq" sections are converted to "in" 
*/
+                               op_tail = xb_stack_peek_tail(opcodes);
+                               if (op_tail != NULL && 
xb_opcode_get_level(op_tail) != level &&
+                                   g_strcmp0(op_name, "eq") == 0)
+                                       op_name = "in";
+                               if (!xb_machine_parse_add_func(self,
+                                                              opcodes,
+                                                              op_name,
+                                                              level,
+                                                              error))
+                                       return FALSE;
+                       } else {
+                               /* before then after */
+                               if (i > 0) {
                                        if (!xb_machine_parse_section(self,
                                                                      opcodes,
-                                                                     text + i 
+ op->strsz,
-                                                                     -1,
-                                                                     is_method,
+                                                                     text,
+                                                                     i,
+                                                                     FALSE,
+                                                                     level,
                                                                      error))
                                                return FALSE;
-                                       if (!xb_machine_parse_add_func(self,
-                                                                      opcodes,
-                                                                      op->name,
-                                                                      error))
-                                               return FALSE;
                                }
-                               return TRUE;
+                               if (!xb_machine_parse_section(self,
+                                                             opcodes,
+                                                             text + i + 
op->strsz,
+                                                             -1,
+                                                             is_method,
+                                                             level,
+                                                             error))
+                                       return FALSE;
+                               if (!xb_machine_parse_add_func(self,
+                                                              opcodes,
+                                                              op->name,
+                                                              level,
+                                                              error))
+                                       return FALSE;
                        }
+                       return TRUE;
                }
        }
 
        /* nothing matched */
-       if (is_method)
-               return xb_machine_parse_add_func(self, opcodes, text, error);
-       return xb_machine_parse_add_text(self, opcodes, text, text_len, error);
+       if (is_method) {
+               g_autoptr(GError) error_local = NULL;
+               if (!xb_machine_parse_add_text(self,
+                                              opcodes,
+                                              text,
+                                              text_len,
+                                              level,
+                                              &error_local)) {
+                       if (priv->debug_flags & 
XB_MACHINE_DEBUG_FLAG_SHOW_PARSING)
+                               g_debug("Failed to add text %s, trying 
function", text);
+                       return xb_machine_parse_add_func(self, opcodes, text, 
level, error);
+               }
+               return TRUE;
+       }
+       return xb_machine_parse_add_text(self, opcodes, text, text_len, level, 
error);
 }
 
 static gboolean
@@ -515,6 +563,7 @@
                          const gchar *text,
                          gsize text_len,
                          gboolean is_method,
+                         guint8 level,
                          GError **error)
 {
        g_autofree gchar *tmp = NULL;
@@ -531,7 +580,11 @@
                if (tmp[i] == ',') {
                        tmp[i] = '\0';
                        if (is_method) {
-                               if (!xb_machine_parse_add_func(self, opcodes, 
tmp + i + 1, error))
+                               if (!xb_machine_parse_add_func(self,
+                                                              opcodes,
+                                                              tmp + i + 1,
+                                                              level,
+                                                              error))
                                        return FALSE;
                                is_method = FALSE;
                        } else {
@@ -540,13 +593,14 @@
                                                              tmp + i + 1,
                                                              -1,
                                                              TRUE,
+                                                             level,
                                                              error))
                                        return FALSE;
                        }
                }
        }
        if (tmp[0] != '\0') {
-               if (!xb_machine_parse_section(self, opcodes, tmp, -1, 
is_method, error))
+               if (!xb_machine_parse_section(self, opcodes, tmp, -1, 
is_method, level, error))
                        return FALSE;
        }
        return TRUE;
@@ -582,7 +636,7 @@
        g_auto(XbOpcode) op_result = XB_OPCODE_INIT();
        g_auto(XbOpcode) op_owned = op;
 
-       /* a function! lets check the arg length */
+       /* not a function */
        if (xb_opcode_get_kind(&op) != XB_OPCODE_KIND_FUNCTION) {
                XbOpcode *op_out;
                if (!xb_stack_push(results, &op_out, error))
@@ -632,6 +686,7 @@
                }
                if (!xb_stack_push(results, &op_out, error))
                        return FALSE;
+               xb_opcode_set_level(&op_result, xb_opcode_get_level(&op));
                *op_out = xb_opcode_steal(&op_result);
 
                return TRUE;
@@ -691,14 +746,14 @@
                      XbStack *opcodes,
                      const gchar *text,
                      gsize text_len,
-                     guint level,
+                     guint8 level,
                      GError **error)
 {
        XbMachinePrivate *priv = GET_PRIVATE(self);
        guint tail = 0;
 
        /* sanity check */
-       if (level > 20) {
+       if (level > XB_MACHINE_STACK_LEVELS_MAX) {
                g_autofree gchar *tmp = g_strndup(text, text_len);
                g_set_error(error,
                            G_IO_ERROR,
@@ -725,6 +780,7 @@
                                                       text + tail,
                                                       i - tail,
                                                       TRUE,
+                                                      level,
                                                       error))
                                return G_MAXSIZE;
                        i += j;
@@ -737,6 +793,7 @@
                                                       text + tail,
                                                       i - tail,
                                                       FALSE,
+                                                      level,
                                                       error))
                                return G_MAXSIZE;
                        return i + 1;
@@ -751,7 +808,13 @@
                            tmp);
                return G_MAXSIZE;
        }
-       if (!xb_machine_parse_sections(self, opcodes, text + tail, text_len - 
tail, FALSE, error))
+       if (!xb_machine_parse_sections(self,
+                                      opcodes,
+                                      text + tail,
+                                      text_len - tail,
+                                      FALSE,
+                                      level,
+                                      error))
                return G_MAXSIZE;
        return 0;
 }
@@ -781,7 +844,7 @@
 {
        XbMachineOpcodeFixupItem *item;
        XbMachinePrivate *priv = GET_PRIVATE(self);
-       guint level = 0;
+       guint8 level = 0;
        g_autoptr(XbStack) opcodes = NULL;
        g_autofree gchar *opcodes_sig = NULL;
 
@@ -996,7 +1059,8 @@
                                return FALSE;
                        }
                        continue;
-               } else if (kind == XB_OPCODE_KIND_BOUND_UNSET) {
+               }
+               if (kind == XB_OPCODE_KIND_BOUND_UNSET) {
                        g_autofree gchar *tmp1 = xb_stack_to_string(stack);
                        g_autofree gchar *tmp2 = xb_stack_to_string(opcodes);
                        g_set_error(error,
@@ -2137,6 +2201,69 @@
        return xb_machine_stack_push_text_steal(self, stack, tmp, error);
 }
 
+static gboolean
+xb_machine_func_in_cb(XbMachine *self,
+                     XbStack *stack,
+                     gboolean *result,
+                     gpointer user_data,
+                     gpointer exec_data,
+                     GError **error)
+{
+       XbOpcode *op_needle;
+       const gchar *haystack[XB_MACHINE_STACK_LEVELS_MAX + 1] = {NULL};
+       g_auto(XbOpcode) op = XB_OPCODE_INIT();
+       guint8 level = G_MAXUINT8;
+       guint nr_args = 0;
+
+       /* get the size of the haystack, ensuring we only have strings */
+       for (guint i = xb_stack_get_size(stack) - 1; i > 0; i--) {
+               XbOpcode *op_tmp = xb_stack_peek(stack, i);
+
+               /* this is a hack as we do not get the current @level */
+               if (level != G_MAXUINT8) {
+                       if (xb_opcode_get_level(op_tmp) != level)
+                               break;
+               } else {
+                       level = xb_opcode_get_level(op_tmp);
+               }
+               if (!xb_opcode_cmp_str(op_tmp)) {
+                       g_set_error(error,
+                                   G_IO_ERROR,
+                                   G_IO_ERROR_NOT_SUPPORTED,
+                                   "%s type not supported",
+                                   
xb_opcode_kind_to_string(xb_opcode_get_kind(op_tmp)));
+                       return FALSE;
+               }
+               nr_args++;
+       }
+
+       /* ensure the needle is also a string */
+       op_needle = xb_stack_peek(stack, xb_stack_get_size(stack) - (nr_args + 
1));
+       if (!xb_opcode_cmp_str(op_needle)) {
+               g_set_error(error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_NOT_SUPPORTED,
+                           "%s type not supported",
+                           
xb_opcode_kind_to_string(xb_opcode_get_kind(op_needle)));
+               return FALSE;
+       }
+
+       /* build the haystack */
+       for (guint i = 0; i < nr_args; i++) {
+               g_auto(XbOpcode) op_tmp = XB_OPCODE_INIT();
+               if (!xb_machine_stack_pop(self, stack, &op_tmp, error))
+                       return FALSE;
+               haystack[i] = xb_opcode_get_str(&op_tmp);
+       }
+
+       /* get the needle */
+       if (!xb_machine_stack_pop(self, stack, &op, error))
+               return FALSE;
+
+       /* found */
+       return xb_stack_push_bool(stack, g_strv_contains(haystack, 
xb_opcode_get_str(&op)), error);
+}
+
 static void
 xb_machine_opcode_fixup_free(XbMachineOpcodeFixupItem *item)
 {
@@ -2203,6 +2330,7 @@
        xb_machine_add_method(self, "string", 1, xb_machine_func_string_cb, 
NULL, NULL);
        xb_machine_add_method(self, "number", 1, xb_machine_func_number_cb, 
NULL, NULL);
        xb_machine_add_method(self, "string-length", 1, 
xb_machine_func_strlen_cb, NULL, NULL);
+       xb_machine_add_method(self, "in", 0, xb_machine_func_in_cb, NULL, NULL);
 
        /* built-in operators */
        xb_machine_add_operator(self, " and ", "and");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-machine.h 
new/libxmlb-0.3.11/src/xb-machine.h
--- old/libxmlb-0.3.10/src/xb-machine.h 2022-09-11 12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/src/xb-machine.h 2023-02-20 10:48:39.000000000 +0100
@@ -65,12 +65,14 @@
                                             XbStack *opcodes,
                                             gpointer user_data,
                                             GError **error);
+/* when next breaking API add @level here */
 typedef gboolean (*XbMachineTextHandlerFunc)(XbMachine *self,
                                             XbStack *opcodes,
                                             const gchar *text,
                                             gboolean *handled,
                                             gpointer user_data,
                                             GError **error);
+/* when next breaking API add @level here */
 typedef gboolean (*XbMachineMethodFunc)(XbMachine *self,
                                        XbStack *stack,
                                        gboolean *result_unused,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-opcode-private.h 
new/libxmlb-0.3.11/src/xb-opcode-private.h
--- old/libxmlb-0.3.10/src/xb-opcode-private.h  2022-09-11 12:09:18.000000000 
+0200
+++ new/libxmlb-0.3.11/src/xb-opcode-private.h  2023-02-20 10:48:39.000000000 
+0100
@@ -23,11 +23,12 @@
        guint8 tokens_len;
        const gchar *tokens[XB_OPCODE_TOKEN_MAX + 1];
        GDestroyNotify destroy_func;
+       guint8 level;
 };
 
 #define XB_OPCODE_INIT()                                                       
                    \
        {                                                                       
                   \
-               0, 0, NULL, 0, {NULL}, NULL                                     
                   \
+               0, 0, NULL, 0, {NULL}, NULL, 0                                  
                   \
        }
 
 /**
@@ -49,15 +50,15 @@
 }
 
 void
-xb_opcode_init(XbOpcode *opcode,
+xb_opcode_init(XbOpcode *self,
               XbOpcodeKind kind,
               const gchar *str,
               guint32 val,
               GDestroyNotify destroy_func);
 void
-xb_opcode_clear(XbOpcode *opcode);
+xb_opcode_clear(XbOpcode *self);
 void
-xb_opcode_bind_init(XbOpcode *opcode);
+xb_opcode_bind_init(XbOpcode *self);
 gboolean
 xb_opcode_is_binding(XbOpcode *self);
 G_DEPRECATED_FOR(xb_value_bindings_bind_str)
@@ -77,12 +78,17 @@
 gchar *
 xb_opcode_get_sig(XbOpcode *self);
 void
-xb_opcode_bool_init(XbOpcode *opcode, gboolean val);
+xb_opcode_bool_init(XbOpcode *self, gboolean val);
 gboolean
 xb_opcode_has_flag(XbOpcode *self, XbOpcodeFlags flag);
 void
 xb_opcode_add_flag(XbOpcode *self, XbOpcodeFlags flag);
 
+void
+xb_opcode_set_level(XbOpcode *self, guint8 level);
+guint8
+xb_opcode_get_level(XbOpcode *self);
+
 G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(XbOpcode, xb_opcode_clear)
 
 G_END_DECLS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-opcode.c 
new/libxmlb-0.3.11/src/xb-opcode.c
--- old/libxmlb-0.3.10/src/xb-opcode.c  2022-09-11 12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/src/xb-opcode.c  2023-02-20 10:48:39.000000000 +0100
@@ -98,28 +98,45 @@
        return self->ptr;
 }
 
+void
+xb_opcode_set_level(XbOpcode *self, guint8 level)
+{
+       self->level = level;
+}
+
+guint8
+xb_opcode_get_level(XbOpcode *self)
+{
+       return self->level;
+}
+
 static gchar *
 xb_opcode_to_string_internal(XbOpcode *self)
 {
-       /* special cases */
+       g_autoptr(GString) str = g_string_new(NULL);
+
+       /* special cases then bitwise fallbacks */
        if (self->kind == XB_OPCODE_KIND_INDEXED_TEXT)
-               return g_strdup_printf("$'%s'", 
xb_opcode_get_str_for_display(self));
-       if (self->kind == XB_OPCODE_KIND_INTEGER)
-               return g_strdup_printf("%u", xb_opcode_get_val(self));
-       if (self->kind == XB_OPCODE_KIND_BOUND_TEXT)
-               return g_strdup_printf("?'%s'", 
xb_opcode_get_str_for_display(self));
-       if (self->kind == XB_OPCODE_KIND_BOUND_INTEGER)
-               return g_strdup_printf("?%u", xb_opcode_get_val(self));
-       if (self->kind == XB_OPCODE_KIND_BOOLEAN)
+               g_string_append_printf(str, "$'%s'", 
xb_opcode_get_str_for_display(self));
+       else if (self->kind == XB_OPCODE_KIND_INTEGER)
+               g_string_append_printf(str, "%u", xb_opcode_get_val(self));
+       else if (self->kind == XB_OPCODE_KIND_BOUND_TEXT)
+               g_string_append_printf(str, "?'%s'", 
xb_opcode_get_str_for_display(self));
+       else if (self->kind == XB_OPCODE_KIND_BOUND_INTEGER)
+               g_string_append_printf(str, "?%u", xb_opcode_get_val(self));
+       else if (self->kind == XB_OPCODE_KIND_BOOLEAN)
                return g_strdup(xb_opcode_get_val(self) ? "True" : "False");
-
-       /* bitwise fallbacks */
-       if (self->kind & XB_OPCODE_FLAG_FUNCTION)
-               return g_strdup_printf("%s()", 
xb_opcode_get_str_for_display(self));
-       if (self->kind & XB_OPCODE_FLAG_TEXT)
-               return g_strdup_printf("'%s'", 
xb_opcode_get_str_for_display(self));
-       g_critical("no to_string for kind 0x%x", self->kind);
-       return NULL;
+       else if (self->kind & XB_OPCODE_FLAG_FUNCTION)
+               g_string_append_printf(str, "%s()", 
xb_opcode_get_str_for_display(self));
+       else if (self->kind & XB_OPCODE_FLAG_TEXT)
+               g_string_append_printf(str, "'%s'", 
xb_opcode_get_str_for_display(self));
+       else
+               g_string_append_printf(str, "kind:0x%x", self->kind);
+
+       /* add level */
+       if (self->level > 0)
+               g_string_append_printf(str, "^%u", self->level);
+       return g_string_free(g_steal_pointer(&str), FALSE);
 }
 
 /**
@@ -302,7 +319,7 @@
 
 /**
  * xb_opcode_text_init:
- * @opcode: a stack allocated #XbOpcode to initialise
+ * @self: a stack allocated #XbOpcode to initialise
  * @str: a string
  *
  * Initialises a stack allocated #XbOpcode to contain a text literal.
@@ -312,14 +329,14 @@
  * Since: 0.2.0
  **/
 void
-xb_opcode_text_init(XbOpcode *opcode, const gchar *str)
+xb_opcode_text_init(XbOpcode *self, const gchar *str)
 {
-       xb_opcode_init(opcode, XB_OPCODE_KIND_TEXT, g_strdup(str), 0, g_free);
+       xb_opcode_init(self, XB_OPCODE_KIND_TEXT, g_strdup(str), 0, g_free);
 }
 
 /**
  * xb_opcode_init:
- * @opcode: allocated opcode to fill
+ * @self: allocated opcode to fill
  * @kind: a #XbOpcodeKind, e.g. %XB_OPCODE_KIND_INTEGER
  * @str: a string
  * @val: a integer value
@@ -330,22 +347,23 @@
  * Since: 0.2.0
  **/
 void
-xb_opcode_init(XbOpcode *opcode,
+xb_opcode_init(XbOpcode *self,
               XbOpcodeKind kind,
               const gchar *str,
               guint32 val,
               GDestroyNotify destroy_func)
 {
-       opcode->kind = kind;
-       opcode->ptr = (gpointer)str;
-       opcode->val = val;
-       opcode->tokens_len = 0;
-       opcode->destroy_func = destroy_func;
+       self->level = G_MAXUINT8;
+       self->kind = kind;
+       self->ptr = (gpointer)str;
+       self->val = val;
+       self->tokens_len = 0;
+       self->destroy_func = destroy_func;
 }
 
 /**
  * xb_opcode_text_init_static:
- * @opcode: a stack allocated #XbOpcode to initialise
+ * @self: a stack allocated #XbOpcode to initialise
  * @str: a string
  *
  * Initialises a stack allocated #XbOpcode to contain a text literal, where
@@ -354,14 +372,14 @@
  * Since: 0.2.0
  **/
 void
-xb_opcode_text_init_static(XbOpcode *opcode, const gchar *str)
+xb_opcode_text_init_static(XbOpcode *self, const gchar *str)
 {
-       xb_opcode_init(opcode, XB_OPCODE_KIND_TEXT, str, 0, NULL);
+       xb_opcode_init(self, XB_OPCODE_KIND_TEXT, str, 0, NULL);
 }
 
 /**
  * xb_opcode_text_init_steal:
- * @opcode: a stack allocated #XbOpcode to initialise
+ * @self: a stack allocated #XbOpcode to initialise
  * @str: a string
  *
  * Initialises a stack allocated #XbOpcode to contain a text literal, stealing
@@ -370,14 +388,14 @@
  * Since: 0.2.0
  **/
 void
-xb_opcode_text_init_steal(XbOpcode *opcode, gchar *str)
+xb_opcode_text_init_steal(XbOpcode *self, gchar *str)
 {
-       xb_opcode_init(opcode, XB_OPCODE_KIND_TEXT, g_steal_pointer(&str), 0, 
g_free);
+       xb_opcode_init(self, XB_OPCODE_KIND_TEXT, g_steal_pointer(&str), 0, 
g_free);
 }
 
 /**
  * xb_opcode_func_init:
- * @opcode: a stack allocated #XbOpcode to initialise
+ * @self: a stack allocated #XbOpcode to initialise
  * @func: a function index
  *
  * Initialises a stack allocated #XbOpcode to contain a specific function.
@@ -387,14 +405,14 @@
  * Since: 0.2.0
  **/
 void
-xb_opcode_func_init(XbOpcode *opcode, guint32 func)
+xb_opcode_func_init(XbOpcode *self, guint32 func)
 {
-       xb_opcode_init(opcode, XB_OPCODE_KIND_FUNCTION, NULL, func, NULL);
+       xb_opcode_init(self, XB_OPCODE_KIND_FUNCTION, NULL, func, NULL);
 }
 
 /**
  * xb_opcode_bind_init:
- * @opcode: a stack allocated #XbOpcode to initialise
+ * @self: a stack allocated #XbOpcode to initialise
  *
  * Initialises a stack allocated #XbOpcode to contain a bind variable. A value
  * needs to be assigned to this opcode at runtime using
@@ -403,9 +421,9 @@
  * Since: 0.2.0
  **/
 void
-xb_opcode_bind_init(XbOpcode *opcode)
+xb_opcode_bind_init(XbOpcode *self)
 {
-       xb_opcode_init(opcode, XB_OPCODE_KIND_BOUND_INTEGER, NULL, 0, NULL);
+       xb_opcode_init(self, XB_OPCODE_KIND_BOUND_INTEGER, NULL, 0, NULL);
 }
 
 /* private */
@@ -462,7 +480,7 @@
 
 /**
  * xb_opcode_integer_init:
- * @opcode: a stack allocated #XbOpcode to initialise
+ * @self: a stack allocated #XbOpcode to initialise
  * @val: a integer value
  *
  * Initialises a stack allocated #XbOpcode to contain an integer literal.
@@ -470,14 +488,14 @@
  * Since: 0.2.0
  **/
 void
-xb_opcode_integer_init(XbOpcode *opcode, guint32 val)
+xb_opcode_integer_init(XbOpcode *self, guint32 val)
 {
-       xb_opcode_init(opcode, XB_OPCODE_KIND_INTEGER, NULL, val, NULL);
+       xb_opcode_init(self, XB_OPCODE_KIND_INTEGER, NULL, val, NULL);
 }
 
 /* private */
 void
-xb_opcode_bool_init(XbOpcode *opcode, gboolean val)
+xb_opcode_bool_init(XbOpcode *self, gboolean val)
 {
-       xb_opcode_init(opcode, XB_OPCODE_KIND_BOOLEAN, NULL, !!val, NULL);
+       xb_opcode_init(self, XB_OPCODE_KIND_BOOLEAN, NULL, !!val, NULL);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-opcode.h 
new/libxmlb-0.3.11/src/xb-opcode.h
--- old/libxmlb-0.3.10/src/xb-opcode.h  2022-09-11 12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/src/xb-opcode.h  2023-02-20 10:48:39.000000000 +0100
@@ -90,14 +90,14 @@
 xb_opcode_get_val(XbOpcode *self);
 
 void
-xb_opcode_func_init(XbOpcode *opcode, guint32 func);
+xb_opcode_func_init(XbOpcode *self, guint32 func);
 void
-xb_opcode_integer_init(XbOpcode *opcode, guint32 val);
+xb_opcode_integer_init(XbOpcode *self, guint32 val);
 void
-xb_opcode_text_init(XbOpcode *opcode, const gchar *str);
+xb_opcode_text_init(XbOpcode *self, const gchar *str);
 void
-xb_opcode_text_init_static(XbOpcode *opcode, const gchar *str);
+xb_opcode_text_init_static(XbOpcode *self, const gchar *str);
 void
-xb_opcode_text_init_steal(XbOpcode *opcode, gchar *str);
+xb_opcode_text_init_steal(XbOpcode *self, gchar *str);
 
 G_END_DECLS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-self-test.c 
new/libxmlb-0.3.11/src/xb-self-test.c
--- old/libxmlb-0.3.10/src/xb-self-test.c       2022-09-11 12:09:18.000000000 
+0200
+++ new/libxmlb-0.3.11/src/xb-self-test.c       2023-02-20 10:48:39.000000000 
+0100
@@ -224,9 +224,9 @@
                     {"@a=='b'", "'a',attr(),'b',eq()"},
                     {"'a'<'b'", "'a','b',lt()"},
                     {"999>=123", "999,123,ge()"},
-                    {"not(0)", "0,not()"},
+                    {"not(0)", "0^1,not()"},
                     {"@a", "'a',attr(),'(null)',ne()"},
-                    {"not(@a)", "'a',attr(),not()"},
+                    {"not(@a)", "'a'^1,attr()^1,not()"},
                     {"'a'=", "'a',eq()"},
                     {"='b'", "'b',eq()"},
                     {"999=\'b\'", "999,'b',eq()"},
@@ -235,9 +235,10 @@
                     {"text()~='beef'", "text(),'beef'[beef],search()"},
                     {"@type~='dead'", "'type',attr(),'dead',search()"},
                     {"2", "2,position(),eq()"},
-                    {"text()=lower-case('firefox')", 
"text(),'firefox',lower-case(),eq()"},
+                    {"text()=lower-case('firefox')", 
"text(),'firefox'^1,lower-case(),eq()"},
                     {"$'a'=$'b'", "$'a',$'b',eq()"},
-                    {"('a'='b')&&('c'='d')", 
"'a','b',eq(),'c','d',eq(),and()"},
+                    {"('a'='b')&&('c'='d')", 
"'a'^1,'b'^1,eq()^1,'c'^1,'d'^1,eq()^1,and()"},
+                    {"text()==('a','b','c')", "text(),'c'^1,'b'^1,'a'^1,in()"},
                     /* sentinel */
                     {NULL, NULL}};
        const gchar *invalid[] = {"text(",
@@ -291,6 +292,7 @@
                     {"lower-case('Fire')", "'fire'"},
                     {"upper-case('Τάχιστη')", "'ΤΆΧΙΣΤΗ'"},
                     {"upper-case(lower-case('Fire'))", "'FIRE'"}, /* 2nd pass 
*/
+                    {"text()==('a','b','c')", "text(),'c'^1,'b'^1,'a'^1,in()"},
                     /* sentinel */
                     {NULL, NULL}};
        const gchar *invalid[] = {"'a'='b'", "123>=999", "not(1)", NULL};
@@ -488,6 +490,40 @@
 }
 
 static void
+xb_builder_source_zstd_func(void)
+{
+       gboolean ret;
+       g_autofree gchar *path = NULL;
+       g_autofree gchar *tmp_xmlb = g_build_filename(g_get_tmp_dir(), 
"temp.xmlb", NULL);
+       g_autoptr(GError) error = NULL;
+       g_autoptr(GFile) file = NULL;
+       g_autoptr(GFile) file_src = NULL;
+       g_autoptr(XbBuilder) builder = xb_builder_new();
+       g_autoptr(XbBuilderSource) source = xb_builder_source_new();
+       g_autoptr(XbSilo) silo = NULL;
+
+       /* import a source file */
+       path = g_test_build_filename(G_TEST_DIST, "test.xml.zstd", NULL);
+       file_src = g_file_new_for_path(path);
+       if (!g_file_query_exists(file_src, NULL)) {
+               g_test_skip("does not work in subproject test");
+               return;
+       }
+       ret = xb_builder_source_load_file(source,
+                                         file_src,
+                                         XB_BUILDER_SOURCE_FLAG_NONE,
+                                         NULL,
+                                         &error);
+       g_assert_no_error(error);
+       g_assert_true(ret);
+       xb_builder_import_source(builder, source);
+       file = g_file_new_for_path(tmp_xmlb);
+       silo = xb_builder_ensure(builder, file, XB_BUILDER_COMPILE_FLAG_NONE, 
NULL, &error);
+       g_assert_no_error(error);
+       g_assert_nonnull(silo);
+}
+
+static void
 xb_builder_chained_adapters_func(void)
 {
        gboolean ret;
@@ -1364,6 +1400,25 @@
        g_assert_nonnull(str);
        g_debug("\n%s", str);
 
+       /* query with predicate 'in' */
+       xb_silo_set_profile_flags(silo, XB_SILO_PROFILE_FLAG_OPTIMIZER);
+       n = xb_silo_query_first(
+           silo,
+           
"components/component/id[text()=('gimp.desktop','another.desktop','dave.desktop')]",
+           &error);
+       g_assert_no_error(error);
+       g_assert_nonnull(n);
+       g_assert_cmpstr(xb_node_get_text(n), ==, "gimp.desktop");
+       g_clear_object(&n);
+
+       /* query with predicate 'in' -- single-entry tuple */
+       xb_silo_set_profile_flags(silo, XB_SILO_PROFILE_FLAG_OPTIMIZER);
+       n = xb_silo_query_first(silo, 
"components/component/id[text()=('gimp.desktop')]", &error);
+       g_assert_no_error(error);
+       g_assert_nonnull(n);
+       g_assert_cmpstr(xb_node_get_text(n), ==, "gimp.desktop");
+       g_clear_object(&n);
+
        /* query with predicate logical and */
        n = xb_silo_query_first(
            silo,
@@ -2744,6 +2799,7 @@
        g_test_add_func("/libxmlb/builder{custom-mime}", 
xb_builder_custom_mime_func);
        g_test_add_func("/libxmlb/builder{chained-adapters}", 
xb_builder_chained_adapters_func);
        g_test_add_func("/libxmlb/builder{source-lzma}", 
xb_builder_source_lzma_func);
+       g_test_add_func("/libxmlb/builder{source-zstd}", 
xb_builder_source_zstd_func);
        g_test_add_func("/libxmlb/builder-node", xb_builder_node_func);
        g_test_add_func("/libxmlb/builder-node{token-max}", 
xb_builder_node_token_max_func);
        g_test_add_func("/libxmlb/builder-node{info}", 
xb_builder_node_info_func);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-silo-query.c 
new/libxmlb-0.3.11/src/xb-silo-query.c
--- old/libxmlb-0.3.10/src/xb-silo-query.c      2022-09-11 12:09:18.000000000 
+0200
+++ new/libxmlb-0.3.11/src/xb-silo-query.c      2023-02-20 10:48:39.000000000 
+0100
@@ -200,7 +200,7 @@
        /* continue matching children ".." */
        do {
                gboolean result = TRUE;
-               guint bindings_offset_end;
+               guint bindings_offset_end = 0;
                query_data->sn = sn;
                if (!xb_silo_query_node_matches(self,
                                                machine,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-silo.c 
new/libxmlb-0.3.11/src/xb-silo.c
--- old/libxmlb-0.3.10/src/xb-silo.c    2022-09-11 12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/src/xb-silo.c    2023-02-20 10:48:39.000000000 +0100
@@ -1177,6 +1177,7 @@
 {
        XbOpcode *op1;
        XbOpcode *op2;
+       XbOpcode *tail = xb_stack_peek_tail(opcodes);
 
        if (!_xb_stack_push_two(opcodes, &op1, &op2, error))
                return FALSE;
@@ -1184,6 +1185,12 @@
        xb_machine_opcode_func_init(self, op1, "position");
        xb_machine_opcode_func_init(self, op2, "eq");
 
+       /* always exists, but maybe a @level would be cleaner */
+       if (tail != NULL) {
+               xb_opcode_set_level(op1, xb_opcode_get_level(tail));
+               xb_opcode_set_level(op2, xb_opcode_get_level(tail));
+       }
+
        return TRUE;
 }
 
@@ -1196,6 +1203,7 @@
 {
        XbOpcode *op1;
        XbOpcode *op2;
+       XbOpcode *tail = xb_stack_peek_tail(opcodes);
 
        if (!_xb_stack_push_two(opcodes, &op1, &op2, error))
                return FALSE;
@@ -1203,6 +1211,12 @@
        xb_opcode_text_init_static(op1, NULL);
        xb_machine_opcode_func_init(self, op2, "ne");
 
+       /* always exists, but maybe a @level would be cleaner */
+       if (tail != NULL) {
+               xb_opcode_set_level(op1, xb_opcode_get_level(tail));
+               xb_opcode_set_level(op2, xb_opcode_get_level(tail));
+       }
+
        return TRUE;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-value-bindings-private.h 
new/libxmlb-0.3.11/src/xb-value-bindings-private.h
--- old/libxmlb-0.3.10/src/xb-value-bindings-private.h  2022-09-11 
12:09:18.000000000 +0200
+++ new/libxmlb-0.3.11/src/xb-value-bindings-private.h  2023-02-20 
10:48:39.000000000 +0100
@@ -6,7 +6,7 @@
 
 #pragma once
 
-#include <glib.h>
+#include "xb-value-bindings.h"
 
 gchar *
 xb_value_bindings_to_string(XbValueBindings *self);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-value-bindings.c 
new/libxmlb-0.3.11/src/xb-value-bindings.c
--- old/libxmlb-0.3.10/src/xb-value-bindings.c  2022-09-11 12:09:18.000000000 
+0200
+++ new/libxmlb-0.3.11/src/xb-value-bindings.c  2023-02-20 10:48:39.000000000 
+0100
@@ -10,8 +10,6 @@
 
 #define G_LOG_DOMAIN "XbValueBindings"
 
-#include "xb-value-bindings.h"
-
 #include "config.h"
 
 #include <glib.h>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-zstd-decompressor.c 
new/libxmlb-0.3.11/src/xb-zstd-decompressor.c
--- old/libxmlb-0.3.10/src/xb-zstd-decompressor.c       1970-01-01 
01:00:00.000000000 +0100
+++ new/libxmlb-0.3.11/src/xb-zstd-decompressor.c       2023-02-20 
10:48:39.000000000 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2022 Richard Hughes <rich...@hughsie.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#include "xb-zstd-decompressor.h"
+
+#include "config.h"
+
+#include <gio/gio.h>
+#include <zstd.h>
+
+static void
+xb_zstd_decompressor_iface_init(GConverterIface *iface);
+
+struct _XbZstdDecompressor {
+       GObject parent_instance;
+       ZSTD_DStream *zstdstream;
+};
+
+G_DEFINE_TYPE_WITH_CODE(XbZstdDecompressor,
+                       xb_zstd_decompressor,
+                       G_TYPE_OBJECT,
+                       G_IMPLEMENT_INTERFACE(G_TYPE_CONVERTER, 
xb_zstd_decompressor_iface_init))
+
+static void
+xb_zstd_decompressor_finalize(GObject *object)
+{
+       XbZstdDecompressor *self = XB_ZSTD_DECOMPRESSOR(object);
+       ZSTD_freeDStream(self->zstdstream);
+       G_OBJECT_CLASS(xb_zstd_decompressor_parent_class)->finalize(object);
+}
+
+static void
+xb_zstd_decompressor_init(XbZstdDecompressor *self)
+{
+}
+
+static void
+xb_zstd_decompressor_constructed(GObject *object)
+{
+       XbZstdDecompressor *self = XB_ZSTD_DECOMPRESSOR(object);
+       self->zstdstream = ZSTD_createDStream();
+}
+
+static void
+xb_zstd_decompressor_class_init(XbZstdDecompressorClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS(klass);
+       object_class->finalize = xb_zstd_decompressor_finalize;
+       object_class->constructed = xb_zstd_decompressor_constructed;
+}
+
+XbZstdDecompressor *
+xb_zstd_decompressor_new(void)
+{
+       return g_object_new(XB_TYPE_ZSTD_DECOMPRESSOR, NULL);
+}
+
+static void
+xb_zstd_decompressor_reset(GConverter *converter)
+{
+       XbZstdDecompressor *self = XB_ZSTD_DECOMPRESSOR(converter);
+       ZSTD_initDStream(self->zstdstream);
+}
+
+static GConverterResult
+xb_zstd_decompressor_convert(GConverter *converter,
+                            const void *inbuf,
+                            gsize inbuf_size,
+                            void *outbuf,
+                            gsize outbuf_size,
+                            GConverterFlags flags,
+                            gsize *bytes_read,
+                            gsize *bytes_written,
+                            GError **error)
+{
+       XbZstdDecompressor *self = XB_ZSTD_DECOMPRESSOR(converter);
+       ZSTD_outBuffer output = {
+           .dst = outbuf,
+           .size = outbuf_size,
+           .pos = 0,
+       };
+       ZSTD_inBuffer input = {
+           .src = inbuf,
+           .size = inbuf_size,
+           .pos = 0,
+       };
+       size_t res;
+
+       res = ZSTD_decompressStream(self->zstdstream, &output, &input);
+       if (res == 0)
+               return G_CONVERTER_FINISHED;
+       if (ZSTD_isError(res)) {
+               g_set_error(error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_INVALID_DATA,
+                           "cannot decompress data: %s",
+                           ZSTD_getErrorName(res));
+               return G_CONVERTER_ERROR;
+       }
+       *bytes_read = input.pos;
+       *bytes_written = output.pos;
+       return G_CONVERTER_CONVERTED;
+}
+
+static void
+xb_zstd_decompressor_iface_init(GConverterIface *iface)
+{
+       iface->convert = xb_zstd_decompressor_convert;
+       iface->reset = xb_zstd_decompressor_reset;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.10/src/xb-zstd-decompressor.h 
new/libxmlb-0.3.11/src/xb-zstd-decompressor.h
--- old/libxmlb-0.3.10/src/xb-zstd-decompressor.h       1970-01-01 
01:00:00.000000000 +0100
+++ new/libxmlb-0.3.11/src/xb-zstd-decompressor.h       2023-02-20 
10:48:39.000000000 +0100
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2022 Richard Hughes <rich...@hughsie.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define XB_TYPE_ZSTD_DECOMPRESSOR (xb_zstd_decompressor_get_type())
+G_DECLARE_FINAL_TYPE(XbZstdDecompressor, xb_zstd_decompressor, XB, 
ZSTD_DECOMPRESSOR, GObject)
+
+XbZstdDecompressor *
+xb_zstd_decompressor_new(void);
+
+G_END_DECLS

Reply via email to