@@ -32,7 +32,8 @@ SYNOPSIS
                           const char *key);

  int flux_kvs_txn_symlink (flux_kvs_txn_t *txn, int flags,
-                           const char *key, const char *target);
+                           const char *key, const char *ns,
+                           const char *target);

  int flux_kvs_txn_put_raw (flux_kvs_txn_t *txn, int flags,
                            const char *key, const void *data, int len);

flux_kvs_txn_create(3)
======================
:doctype: manpage

NAME
----
flux_kvs_txn_create, flux_kvs_txn_destroy, flux_kvs_txn_put, flux_kvs_txn_pack, flux_kvs_txn_vpack, flux_kvs_txn_mkdir, flux_kvs_txn_unlink, flux_kvs_txn_symlink, flux_kvs_txn_put_raw, flux_kvs_txn_put_treeobj - operate on a KVS transaction object

SYNOPSIS
--------
 #include <flux/core.h>

 flux_kvs_txn_t *flux_kvs_txn_create (void);

 void flux_kvs_txn_destroy (flux_kvs_txn_t *txn);

 int flux_kvs_txn_put (flux_kvs_txn_t *txn, int flags,
                       const char *key, const char *value);

 int flux_kvs_txn_pack (flux_kvs_txn_t *txn, int flags,
                        const char *key, const char *fmt, ...);

 int flux_kvs_txn_vpack (flux_kvs_txn_t *txn, int flags,
                         const char *key, const char *fmt, va_list ap);

 int flux_kvs_txn_mkdir (flux_kvs_txn_t *txn, int flags,
                         const char *key);

 int flux_kvs_txn_unlink (flux_kvs_txn_t *txn, int flags,
                          const char *key);

 int flux_kvs_txn_symlink (flux_kvs_txn_t *txn, int flags,
                           const char *key, const char *target);

 int flux_kvs_txn_put_raw (flux_kvs_txn_t *txn, int flags,
                           const char *key, const void *data, int len);

 int flux_kvs_txn_put_treeobj (flux_kvs_txn_t *txn, int flags,
                               const char *key, const char *treeobj);

DESCRIPTION
-----------

The Flux Key Value Store is a general purpose distributed storage
service used by Flux services.

`flux_kvs_txn_create()` creates a KVS transaction object that may be
passed to `flux_kvs_commit(3)` or `flux_kvs_fence(3)`.  The transaction
consists of a list of operations that are applied to the KVS together,
in order.  The entire transaction either succeeds or fails.  After commit
or fence, the object must be destroyed with `flux_kvs_txn_destroy()`.

Each function below adds a single operation to _txn_.  _key_ is a
hierarchical path name with period (".") used as path separator.
When the transaction is committed, any existing keys or path components
that are in conflict with the requested operation are overwritten.
_flags_ can modify the request as described below.

`flux_kvs_txn_put()` sets _key_ to a NULL terminated string _value_.
_value_ may be NULL indicating that an empty value should be stored.

`flux_kvs_txn_pack()` sets _key_ to a NULL terminated string encoded
from a JSON object built with `json_pack()` style arguments (see below).
`flux_kvs_txn_vpack()` is a variant that accepts a _va_list_ argument.

`flux_kvs_txn_mkdir()` sets _key_ to an empty directory.

`flux_kvs_txn_unlink()` removes _key_.  If _key_ is a directory,
all its contents are removed as well.

`flux_kvs_txn_symlink()` sets _key_ to a symbolic link pointing to _target_,
another key.  _target_ need not exist.

`flux_kvs_txn_put_raw()` sets _key_ to a value containing raw data
referred to by _data_ of length _len_.

`flux_kvs_txn_put_treeobj()` sets _key_ to an RFC 11 object, encoded
as a JSON string.

FLAGS
-----

The following are valid bits in a _flags_ mask passed as an argument
to `flux_kvs_txn_put()` or `flux_kvs_txn_put_raw()`.

FLUX_KVS_APPEND::
Append value instead of overwriting it.  If the key does not exist,
it will be created with the value as the initial value.

include::JSON_PACK.adoc[]

RETURN VALUE
------------

`flux_kvs_txn_create()` returns a `flux_kvs_txn_t` object on success,
or NULL on failure with errno set appropriately.

`flux_kvs_txn_put()`, `flux_kvs_txn_pack()`, `flux_kvs_txn_mkdir()`,
`flux_kvs_txn_unlink()`, `flux_kvs_txn_symlink()`, and `flux_kvs_txn_put_raw()`
returns 0 on success, or -1 on failure with errno set appropriately.

ERRORS
------

EINVAL::
One of the arguments was invalid.

ENOMEM::
Out of memory.

AUTHOR
------
This page is maintained by the Flux community.

RESOURCES
---------
Github: <http://github.com/flux-framework>

COPYRIGHT
---------
include::COPYRIGHT.adoc[]

SEE ALSO
---------
flux_kvs_commit(3)

https://github.com/flux-framework/rfc/blob/master/spec_11.adoc[RFC 11: Key Value Store Tree Object Format v1]

Not critical but "common" is not that helpful in the commit title. Maybe go with "libkvs/txn:" for this one?


@@ -93,6 +93,26 @@ bool wlr_drm_format_set_add(struct wlr_drm_format_set *set, uint32_t format,
 	return true;
 }

+bool wlr_drm_format_set_copy(struct wlr_drm_format_set *dst,
+		const struct wlr_drm_format_set *src) {
+	dst->len = src->len;
+	dst->cap = src->cap;
+	dst->formats = calloc(dst->cap, sizeof(struct wlr_drm_format *));
+	if (dst->formats == NULL) {
+		return false;
+	}
+	for (size_t i = 0; i < src->len; i++) {
+		const struct wlr_drm_format *fmt = src->formats[i];
+		size_t fmt_size = sizeof(*fmt) + sizeof(fmt->modifiers[0]) * fmt->cap;
+		dst->formats[i] = malloc(fmt_size);
+		if (dst->formats[i] == NULL) {
+			return false;
+		}
+		memcpy(dst->formats[i], fmt, fmt_size);
+	}
+	return true;
+}
+
 struct wlr_drm_format *wlr_drm_format_create(uint32_t format) {
 	size_t cap = 4;
 	struct wlr_drm_format *fmt =

#include <assert.h>
#include <drm_fourcc.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wlr/render/drm_format_set.h>
#include <wlr/util/log.h>
#include "render/drm_format_set.h"

void wlr_drm_format_set_finish(struct wlr_drm_format_set *set) {
	for (size_t i = 0; i < set->len; ++i) {
		free(set->formats[i]);
	}
	free(set->formats);

	set->len = 0;
	set->cap = 0;
	set->formats = NULL;
}

static struct wlr_drm_format **format_set_get_ref(struct wlr_drm_format_set *set,
		uint32_t format) {
	for (size_t i = 0; i < set->len; ++i) {
		if (set->formats[i]->format == format) {
			return &set->formats[i];
		}
	}

	return NULL;
}

const struct wlr_drm_format *wlr_drm_format_set_get(
		const struct wlr_drm_format_set *set, uint32_t format) {
	struct wlr_drm_format **ptr =
		format_set_get_ref((struct wlr_drm_format_set *)set, format);
	return ptr ? *ptr : NULL;
}

bool wlr_drm_format_set_has(const struct wlr_drm_format_set *set,
		uint32_t format, uint64_t modifier) {
	const struct wlr_drm_format *fmt = wlr_drm_format_set_get(set, format);
	if (!fmt) {
		return false;
	}

	if (modifier == DRM_FORMAT_MOD_INVALID) {
		return true;
	}

	for (size_t i = 0; i < fmt->len; ++i) {
		if (fmt->modifiers[i] == modifier) {
			return true;
		}
	}

	return false;
}

bool wlr_drm_format_set_add(struct wlr_drm_format_set *set, uint32_t format,
		uint64_t modifier) {
	assert(format != DRM_FORMAT_INVALID);

	struct wlr_drm_format **ptr = format_set_get_ref(set, format);
	if (ptr) {
		return wlr_drm_format_add(ptr, modifier);
	}

	struct wlr_drm_format *fmt = wlr_drm_format_create(format);
	if (!fmt) {
		return false;
	}
	if (!wlr_drm_format_add(&fmt, modifier)) {
		return false;
	}

	if (set->len == set->cap) {
		size_t new = set->cap ? set->cap * 2 : 4;

		struct wlr_drm_format **tmp = realloc(set->formats,
			sizeof(*fmt) + sizeof(fmt->modifiers[0]) * new);
		if (!tmp) {
			wlr_log_errno(WLR_ERROR, "Allocation failed");
			free(fmt);
			return false;
		}

		set->cap = new;
		set->formats = tmp;
	}

	set->formats[set->len++] = fmt;
	return true;
}

struct wlr_drm_format *wlr_drm_format_create(uint32_t format) {
	size_t cap = 4;
	struct wlr_drm_format *fmt =
		calloc(1, sizeof(*fmt) + sizeof(fmt->modifiers[0]) * cap);
	if (!fmt) {
		wlr_log_errno(WLR_ERROR, "Allocation failed");
		return NULL;
	}
	fmt->format = format;
	fmt->cap = cap;
	return fmt;
}

bool wlr_drm_format_add(struct wlr_drm_format **fmt_ptr, uint64_t modifier) {
	struct wlr_drm_format *fmt = *fmt_ptr;

	if (modifier == DRM_FORMAT_MOD_INVALID) {
		return true;
	}

	for (size_t i = 0; i < fmt->len; ++i) {
		if (fmt->modifiers[i] == modifier) {
			return true;
		}
	}

	if (fmt->len == fmt->cap) {
		size_t cap = fmt->cap ? fmt->cap * 2 : 4;

		fmt = realloc(fmt, sizeof(*fmt) + sizeof(fmt->modifiers[0]) * cap);
		if (!fmt) {
			wlr_log_errno(WLR_ERROR, "Allocation failed");
			return false;
		}

		fmt->cap = cap;
		*fmt_ptr = fmt;
	}

	fmt->modifiers[fmt->len++] = modifier;
	return true;
}

struct wlr_drm_format *wlr_drm_format_dup(const struct wlr_drm_format *format) {
	assert(format->len <= format->cap);
	size_t format_size = sizeof(struct wlr_drm_format) +
		format->cap * sizeof(format->modifiers[0]);
	struct wlr_drm_format *duped_format = malloc(format_size);
	if (duped_format == NULL) {
		return NULL;
	}
	memcpy(duped_format, format, format_size);
	return duped_format;
}

struct wlr_drm_format *wlr_drm_format_intersect(
		const struct wlr_drm_format *a, const struct wlr_drm_format *b) {
	assert(a->format == b->format);

	// Special case: if a format only supports LINEAR and the other doesn't
	// support any modifier, force LINEAR. This will force the allocator to
	// create a buffer with a LINEAR layout instead of an implicit modifier.
	if (a->len == 0 && b->len == 1 && b->modifiers[0] == DRM_FORMAT_MOD_LINEAR) {
		return wlr_drm_format_dup(b);
	}
	if (b->len == 0 && a->len == 1 && a->modifiers[0] == DRM_FORMAT_MOD_LINEAR) {
		return wlr_drm_format_dup(a);
	}

	size_t format_cap = a->len < b->len ? a->len : b->len;
	size_t format_size = sizeof(struct wlr_drm_format) +
		format_cap * sizeof(a->modifiers[0]);
	struct wlr_drm_format *format = calloc(1, format_size);
	if (format == NULL) {
		wlr_log_errno(WLR_ERROR, "Allocation failed");
		return NULL;
	}
	format->format = a->format;
	format->cap = format_cap;

	for (size_t i = 0; i < a->len; i++) {
		for (size_t j = 0; j < b->len; j++) {
			if (a->modifiers[i] == b->modifiers[j]) {
				assert(format->len < format->cap);
				format->modifiers[format->len] = a->modifiers[i];
				format->len++;
				break;
			}
		}
	}

	// If both formats support modifiers, but the intersection is empty, then
	// the formats aren't compatible with each other
	if (format->len == 0 && a->len > 0 && b->len > 0) {
		free(format);
		return NULL;
	}

	return format;
}

Forgot to free the `dst->formats[i]` that were allocated until this failure and also `dst->formats`.


@@ -76,22 +76,22 @@ thrift_server_set_property (GObject *object, guint property_id,
   switch (property_id)
   {
     case PROP_THRIFT_SERVER_PROCESSOR:
-      server->processor = g_value_get_object (value);
+      server->processor = g_value_dup_object (value);
       break;
     case PROP_THRIFT_SERVER_SERVER_TRANSPORT:
-      server->server_transport = g_value_get_object (value);
+      server->server_transport = g_value_dup_object (value);
       break;
     case PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY:
-      server->input_transport_factory = g_value_get_object (value);
+      server->input_transport_factory = g_value_dup_object (value);
       break;
     case PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY:
-      server->output_transport_factory = g_value_get_object (value);
+      server->output_transport_factory = g_value_dup_object (value);
       break;
     case PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY:
-      server->input_protocol_factory = g_value_get_object (value);
+      server->input_protocol_factory = g_value_dup_object (value);
       break;
     case PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY:
-      server->output_protocol_factory = g_value_get_object (value);
+      server->output_protocol_factory = g_value_dup_object (value);
       break;
   }
 }

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <thrift/c_glib/thrift.h>
#include "thrift_server.h"

/* object properties */
enum _ThriftServerProperties
{
  PROP_0,
  PROP_THRIFT_SERVER_PROCESSOR,
  PROP_THRIFT_SERVER_SERVER_TRANSPORT,
  PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY,
  PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY,
  PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY,
  PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY
};

G_DEFINE_ABSTRACT_TYPE(ThriftServer, thrift_server, G_TYPE_OBJECT)

void
thrift_server_get_property (GObject *object, guint property_id,
                            GValue *value, GParamSpec *pspec)
{
  ThriftServer *server = THRIFT_SERVER (object);

  THRIFT_UNUSED_VAR (pspec);

  switch (property_id)
  {
    case PROP_THRIFT_SERVER_PROCESSOR:
      g_value_set_object (value, server->processor);
      break;
    case PROP_THRIFT_SERVER_SERVER_TRANSPORT:
      g_value_set_object (value, server->server_transport);
      break;
    case PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY:
      g_value_set_object (value, server->input_transport_factory);
      break;
    case PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY:
      g_value_set_object (value, server->output_transport_factory);
      break;
    case PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY:
      g_value_set_object (value, server->input_protocol_factory);
      break;
    case PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY:
      g_value_set_object (value, server->output_protocol_factory);
      break;
  }
}

void
thrift_server_set_property (GObject *object, guint property_id,
                            const GValue *value, GParamSpec *pspec)
{
  ThriftServer *server = THRIFT_SERVER (object);

  THRIFT_UNUSED_VAR (pspec);

  switch (property_id)
  {
    case PROP_THRIFT_SERVER_PROCESSOR:
      server->processor = g_value_get_object (value);
      break;
    case PROP_THRIFT_SERVER_SERVER_TRANSPORT:
      server->server_transport = g_value_get_object (value);
      break;
    case PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY:
      server->input_transport_factory = g_value_get_object (value);
      break;
    case PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY:
      server->output_transport_factory = g_value_get_object (value);
      break;
    case PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY:
      server->input_protocol_factory = g_value_get_object (value);
      break;
    case PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY:
      server->output_protocol_factory = g_value_get_object (value);
      break;
  }
}

gboolean
thrift_server_serve (ThriftServer *server, GError **error)
{
  return THRIFT_SERVER_GET_CLASS (server)->serve (server, error);
}

void
thrift_server_stop (ThriftServer *server)
{
  THRIFT_SERVER_GET_CLASS (server)->stop (server);
}

/* instance initializer for Thrift Server */
static void
thrift_server_init (ThriftServer *server)
{
  server->processor = NULL;
  server->server_transport = NULL;
  server->input_transport_factory = NULL;
  server->output_transport_factory = NULL;
  server->input_protocol_factory = NULL;
  server->output_protocol_factory = NULL;
}

/* class initializer for ThriftServer
 * TODO: implement ServerEventHandler as a GClosure
 */
static void
thrift_server_class_init (ThriftServerClass *cls)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (cls);

  gobject_class->get_property = thrift_server_get_property;
  gobject_class->set_property = thrift_server_set_property;

  g_object_class_install_property (gobject_class,
      PROP_THRIFT_SERVER_PROCESSOR,
      g_param_spec_object ("processor", "Processor", "Thrift Processor",
                           THRIFT_TYPE_PROCESSOR,
                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property (gobject_class,
      PROP_THRIFT_SERVER_SERVER_TRANSPORT,
      g_param_spec_object ("server_transport", "Server Transport",
                           "Thrift Server Transport",
                           THRIFT_TYPE_SERVER_TRANSPORT,
                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property (gobject_class,
      PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY,
      g_param_spec_object ("input_transport_factory", "Input Transport Factory",
                           "Thrift Server Input Transport Factory",
                           THRIFT_TYPE_TRANSPORT_FACTORY,
                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property (gobject_class,
      PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY,
      g_param_spec_object ("output_transport_factory",
                           "Output Transport Factory",
                           "Thrift Server Output Transport Factory",
                           THRIFT_TYPE_TRANSPORT_FACTORY,
                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property (gobject_class,
      PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY,
      g_param_spec_object ("input_protocol_factory", "Input Protocol Factory",
                           "Thrift Server Input Protocol Factory",
                           THRIFT_TYPE_PROTOCOL_FACTORY,
                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_class_install_property (gobject_class,
      PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY,
      g_param_spec_object ("output_protocol_factory", "Output Protocol Factory",
                           "Thrift Server Output Protocol Factory",
                           THRIFT_TYPE_PROTOCOL_FACTORY,
                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));

  /* set these as virtual methods to be implemented by a subclass */
  cls->serve = thrift_server_serve;
  cls->stop = thrift_server_stop;
}

Same here. Are you sure you must duplicate them?


@@ -33,6 +33,8 @@ class SkipListHandler:
         Process the lines of the skip file.
         """
         self.__skip = []
+        if not skip_file_content:
+            skip_file_content = ""

         self.__skip_file_lines = [line.strip() for line
                                   in skip_file_content.splitlines()

# -------------------------------------------------------------------------
#
#  Part of the CodeChecker project, under the Apache License v2.0 with
#  LLVM Exceptions. See LICENSE for license information.
#  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------
"""
"""

import fnmatch
import re
import os

from codechecker_common.logger import get_logger

LOG = get_logger('system')

class SkipListHandler:
    """
    Skiplist file format:

    -/skip/all/source/in/directory*
    -/do/not/check/this.file
    +/dir/check.this.file
    -/dir/*
    """

    def __init__(self, skip_file_content=""):
        """
        Process the lines of the skip file.
        """
        self.__skip = []

        self.__skip_file_lines = [line.strip() for line
                                  in skip_file_content.splitlines()
                                  if line.strip()]

        valid_lines = self.__check_line_format(self.__skip_file_lines)
        self.__gen_regex(valid_lines)

    def __gen_regex(self, skip_lines):
        """
        Generate a regular expression from the given skip lines
        and collect them for later match.

        The lines should be checked for validity before generating
        the regular expressions.
        """
        for skip_line in skip_lines:
            norm_skip_path = os.path.normpath(skip_line[1:].strip())
            rexpr = re.compile(
                fnmatch.translate(norm_skip_path + '*'))
            self.__skip.append((skip_line, rexpr))

    def __check_line_format(self, skip_lines):
        """
        Check if the skip line is given in a valid format.
        Returns the list of valid lines.
        """
        valid_lines = []
        for line in skip_lines:
            if len(line) < 2 or line[0] not in ['-', '+']:
                LOG.warning("Skipping malformed skipfile pattern: %s", line)
                continue

            valid_lines.append(line)

        return valid_lines

    @property
    def skip_file_lines(self):
        """
        List of the lines from the skip file without changes.
        """
        return self.__skip_file_lines

    def overwrite_skip_content(self, skip_lines):
        """
        Cleans out the already collected skip regular expressions
        and rebuilds the list from the given skip_lines.
        """
        self.__skip = []
        valid_lines = self.__check_line_format(skip_lines)
        self.__gen_regex(valid_lines)

    def should_skip(self, source):
        """
        Check if the given source should be skipped.
        Should the analyzer skip the given source file?
        """
        if not self.__skip:
            return False

        for line, rexpr in self.__skip:
            if rexpr.match(source):
                sign = line[0]
                return sign == '-'
        return False

Do we need this? By default it is an empty string and also a string should be given if this parameter is specified.


@@ -31,15 +31,19 @@
 typedef struct {
   const char *name;
   gboolean (*fn) (int argc, char **argv, GCancellable *cancellable, GError **error);
+  const char *description;
 } OstreeAdminInstUtilCommand;

 static OstreeAdminInstUtilCommand admin_instutil_subcommands[] = {
 #ifdef HAVE_SELINUX
-  { "selinux-ensure-labeled", ot_admin_instutil_builtin_selinux_ensure_labeled },
+  { "selinux-ensure-labeled", ot_admin_instutil_builtin_selinux_ensure_labeled,
+    "relabel all or part of a deployment" },
 #endif
-  { "set-kargs", ot_admin_instutil_builtin_set_kargs },
-  { "grub2-generate", ot_admin_instutil_builtin_grub2_generate },
-  { NULL, NULL }
+  { "set-kargs", ot_admin_instutil_builtin_set_kargs,
+    "set new kernel command line arguments(Not stable) "  },
+  { "grub2-generate", ot_admin_instutil_builtin_grub2_generate,
+    "generate GRUB2 configuration from given BLS entries" },
+  { NULL, NULL, NULL }
 };

 static GOptionContext *

/*
 * Copyright (C) 2011,2014 Colin Walters <walters@verbum.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "config.h"

#include "ot-main.h"
#include "ot-builtins.h"
#include "ot-admin-instutil-builtins.h"
#include "ot-admin-builtins.h"
#include "ot-admin-functions.h"
#include "ostree.h"

#include <glib/gi18n.h>

typedef struct {
  const char *name;
  gboolean (*fn) (int argc, char **argv, GCancellable *cancellable, GError **error);
} OstreeAdminInstUtilCommand;

static OstreeAdminInstUtilCommand admin_instutil_subcommands[] = {
#ifdef HAVE_SELINUX
  { "selinux-ensure-labeled", ot_admin_instutil_builtin_selinux_ensure_labeled },
#endif
  { "set-kargs", ot_admin_instutil_builtin_set_kargs },
  { "grub2-generate", ot_admin_instutil_builtin_grub2_generate },
  { NULL, NULL }
};

static GOptionContext *
ostree_admin_instutil_option_context_new_with_commands (void)
{
  OstreeAdminInstUtilCommand *command = admin_instutil_subcommands;
  GOptionContext *context = g_option_context_new ("COMMAND");

  g_autoptr(GString) summary = g_string_new ("Builtin \"admin instutil\" Commands:");

  while (command->name != NULL)
    {
      g_string_append_printf (summary, "\n  %s", command->name);
      command++;
    }

  g_option_context_set_summary (context, summary->str);

  return context;
}

gboolean
ot_admin_builtin_instutil (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  const char *subcommand_name = NULL;
  int in, out;

  for (in = 1, out = 1; in < argc; in++, out++)
    {
      /* The non-option is the command, take it out of the arguments */
      if (argv[in][0] != '-')
        {
          if (subcommand_name == NULL)
            {
              subcommand_name = argv[in];
              out--;
              continue;
            }
        }

      else if (g_str_equal (argv[in], "--"))
        {
          break;
        }

      argv[out] = argv[in];
    }

  argc = out;

  OstreeAdminInstUtilCommand *subcommand = admin_instutil_subcommands;
  while (subcommand->name)
    {
      if (g_strcmp0 (subcommand_name, subcommand->name) == 0)
        break;
      subcommand++;
    }

  if (!subcommand->name)
    {
      g_autoptr(GOptionContext) context =
        ostree_admin_instutil_option_context_new_with_commands ();

      /* This will not return for some options (e.g. --version). */
      if (ostree_admin_option_context_parse (context, NULL, &argc, &argv,
                                             OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT,
                                             NULL, cancellable, error))
        {
          if (subcommand_name == NULL)
            {
              g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                   "No \"admin instutil\" subcommand specified");
            }
          else
            {
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                           "Unknown \"admin instutil\" subcommand '%s'", subcommand_name);
            }
        }

      g_autofree char *help = g_option_context_get_help (context, FALSE, NULL);
      g_printerr ("%s", help);
      return FALSE;
    }

  g_autofree char *prgname = g_strdup_printf ("%s %s", g_get_prgname (), subcommand_name);
  g_set_prgname (prgname);

  if (!subcommand->fn (argc, argv, cancellable, error))
    return FALSE;

  return TRUE;
}

Let's capitalize these too to be consistent.


@@ -78,6 +78,7 @@ int syslog_prot_process(struct syslog_conn *conn)

         /* Incomplete message */
         if (eof == end || (*eof != '\n' && *eof != '\0')) {
+            flb_debug("[syslog-prot] incomplete message! (Enable trace log to see the message.)");
             return 0;
         }

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*  Fluent Bit
 *  ==========
 *  Copyright (C) 2019      The Fluent Bit Authors
 *  Copyright (C) 2015-2018 Treasure Data Inc.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include <string.h>

#include <fluent-bit/flb_info.h>
#include <fluent-bit/flb_parser.h>
#include <fluent-bit/flb_time.h>

#include "syslog.h"
#include "syslog_conn.h"

static inline void consume_bytes(char *buf, int bytes, int length)
{
    memmove(buf, buf + bytes, length - bytes);
}

static inline int pack_line(struct flb_syslog *ctx,
                            struct flb_time *time, char *data, size_t data_size)
{
    msgpack_packer mp_pck;
    msgpack_sbuffer mp_sbuf;

    /* Initialize local msgpack buffer */
    msgpack_sbuffer_init(&mp_sbuf);
    msgpack_packer_init(&mp_pck, &mp_sbuf, msgpack_sbuffer_write);

    msgpack_pack_array(&mp_pck, 2);
    flb_time_append_to_msgpack(time, &mp_pck, 0);
    msgpack_sbuffer_write(&mp_sbuf, data, data_size);

    flb_input_chunk_append_raw(ctx->i_ins, NULL, 0, mp_sbuf.data, mp_sbuf.size);
    msgpack_sbuffer_destroy(&mp_sbuf);

    return 0;
}

int syslog_prot_process(struct syslog_conn *conn)
{
    int len;
    int ret;
    char *p;
    char *eof;
    char *end;
    void *out_buf;
    size_t out_size;
    struct flb_time out_time;
    struct flb_syslog *ctx = conn->ctx;

    eof = p = conn->buf_data;
    end = conn->buf_data + conn->buf_len;

    /* Always parse while some remaining bytes exists */
    while (eof < end) {

        /* Lookup the ending byte */
        eof = conn->buf_data + conn->buf_parsed;
        while (*eof != '\n' && *eof != '\0' && eof < end) {
            eof++;
        }

        /* Incomplete message */
        if (eof == end || (*eof != '\n' && *eof != '\0')) {
            return 0;
        }

        /* No data ? */
        len = (eof - p);
        if (len == 0) {
            consume_bytes(conn->buf_data, 1, conn->buf_len);
            conn->buf_len--;
            conn->buf_parsed = 0;
            conn->buf_data[conn->buf_len] = '\0';
            end = conn->buf_data + conn->buf_len;

            if (conn->buf_len == 0) {
                return 0;
            }

            continue;
        }

        /* Process the string */
        ret = flb_parser_do(ctx->parser, p, len,
                            &out_buf, &out_size, &out_time);
        if (ret >= 0) {
            pack_line(ctx, &out_time, out_buf, out_size);
            flb_free(out_buf);
        }
        else {
            flb_warn("[in_syslog] error parsing log message");
        }

        conn->buf_parsed += len + 1;
        end = conn->buf_data + conn->buf_len;
        eof = p = conn->buf_data + conn->buf_parsed;
    }

    consume_bytes(conn->buf_data, conn->buf_parsed, conn->buf_len);
    conn->buf_len -= conn->buf_parsed;
    conn->buf_parsed = 0;
    conn->buf_data[conn->buf_len] = '\0';

    return 0;
}

int syslog_prot_process_udp(char *buf, size_t size, struct flb_syslog *ctx)
{
    int ret;
    void *out_buf;
    size_t out_size;
    struct flb_time out_time = {0};

    ret = flb_parser_do(ctx->parser, buf, size,
                        &out_buf, &out_size, &out_time);
    if (ret >= 0) {
        if (flb_time_to_double(&out_time) == 0) {
            flb_time_get(&out_time);
        }
        pack_line(ctx, &out_time, out_buf, out_size);
        flb_free(out_buf);
    }
    else {
        flb_warn("[in_syslog] error parsing log message");
        return -1;
    }

    return 0;
}

would you please rename the message prefix to: [in_syslog] ..."


@@ -28,47 +28,27 @@ namespace Thrift.Transport.Server
     public class TServerSocketTransport : TServerTransport
     {
         private readonly int _clientTimeout;
-        private readonly int _port;
         private readonly bool _useBufferedSockets;
         private readonly bool _useFramedTransport;
         private TcpListener _server;

-        public TServerSocketTransport(TcpListener listener)
-            : this(listener, 0)
-        {
-        }
-
-        public TServerSocketTransport(TcpListener listener, int clientTimeout)
+        public TServerSocketTransport(TcpListener listener, int clientTimeout = 0, bool useBufferedSockets = false, bool useFramedTransport = false)
         {
             _server = listener;
             _clientTimeout = clientTimeout;
+            _useBufferedSockets = useBufferedSockets;
+            _useFramedTransport = useFramedTransport;
         }

-        public TServerSocketTransport(int port)
-            : this(port, 0)
-        {
-        }
-
-        public TServerSocketTransport(int port, int clientTimeout)
-            : this(port, clientTimeout, false)
-        {
-        }
-
-        public TServerSocketTransport(int port, int clientTimeout, bool useBufferedSockets):
-            this(port, clientTimeout, useBufferedSockets, false)
-        {
-        }
-
-        public TServerSocketTransport(int port, int clientTimeout, bool useBufferedSockets, bool useFramedTransport)
+        public TServerSocketTransport(int port, int clientTimeout = 0, bool useBufferedSockets = false, bool useFramedTransport = false)
         {
-            _port = port;
             _clientTimeout = clientTimeout;
             _useBufferedSockets = useBufferedSockets;
             _useFramedTransport = useFramedTransport;
             try
             {
                 // Make server socket
-                _server = new TcpListener(IPAddress.Any, _port);
+                _server = new TcpListener(IPAddress.Any, port);
                 _server.Server.NoDelay = true;
             }
             catch (Exception)

// Licensed to the Apache Software Foundation(ASF) under one
// or more contributor license agreements.See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using Thrift.Transport.Client;

namespace Thrift.Transport.Server
{
    // ReSharper disable once InconsistentNaming
    public class TServerSocketTransport : TServerTransport
    {
        private readonly int _clientTimeout;
        private readonly int _port;
        private readonly bool _useBufferedSockets;
        private readonly bool _useFramedTransport;
        private TcpListener _server;

        public TServerSocketTransport(TcpListener listener)
            : this(listener, 0)
        {
        }

        public TServerSocketTransport(TcpListener listener, int clientTimeout)
        {
            _server = listener;
            _clientTimeout = clientTimeout;
        }

        public TServerSocketTransport(int port)
            : this(port, 0)
        {
        }

        public TServerSocketTransport(int port, int clientTimeout)
            : this(port, clientTimeout, false)
        {
        }

        public TServerSocketTransport(int port, int clientTimeout, bool useBufferedSockets):
            this(port, clientTimeout, useBufferedSockets, false)
        {
        }

        public TServerSocketTransport(int port, int clientTimeout, bool useBufferedSockets, bool useFramedTransport)
        {
            _port = port;
            _clientTimeout = clientTimeout;
            _useBufferedSockets = useBufferedSockets;
            _useFramedTransport = useFramedTransport;
            try
            {
                // Make server socket
                _server = new TcpListener(IPAddress.Any, _port);
                _server.Server.NoDelay = true;
            }
            catch (Exception)
            {
                _server = null;
                throw new TTransportException("Could not create ServerSocket on port " + port + ".");
            }
        }

        public override void Listen()
        {
            // Make sure not to block on accept
            if (_server != null)
            {
                try
                {
                    _server.Start();
                }
                catch (SocketException sx)
                {
                    throw new TTransportException("Could not accept on listening socket: " + sx.Message);
                }
            }
        }

        public override bool IsClientPending()
        {
            return _server.Pending();
        }

        protected override async Task<TTransport> AcceptImplementationAsync(CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return await Task.FromCanceled<TTransport>(cancellationToken);
            }

            if (_server == null)
            {
                throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket.");
            }

            try
            {
                TTransport tSocketTransport = null;
                var tcpClient = await _server.AcceptTcpClientAsync();

                try
                {
                    tSocketTransport = new TSocketTransport(tcpClient)
                    {
                        Timeout = _clientTimeout
                    };

                    if (_useBufferedSockets)
                    {
                        tSocketTransport = new TBufferedTransport(tSocketTransport);
                    }

                    if (_useFramedTransport)
                    {
                        tSocketTransport = new TFramedTransport(tSocketTransport);
                    }

                    return tSocketTransport;
                }
                catch (Exception)
                {
                    if (tSocketTransport != null)
                    {
                        tSocketTransport.Dispose();
                    }
                    else //  Otherwise, clean it up ourselves.
                    {
                        ((IDisposable) tcpClient).Dispose();
                    }

                    throw;
                }
            }
            catch (Exception ex)
            {
                throw new TTransportException(ex.ToString());
            }
        }

        public override void Close()
        {
            if (_server != null)
            {
                try
                {
                    _server.Stop();
                }
                catch (Exception ex)
                {
                    throw new TTransportException("WARNING: Could not close server socket: " + ex);
                }
                _server = null;
            }
        }
    }
}

It would have been cleaner to make a TcpListener here and then call the TcpListener constructor so there is one code path to initialization, not two.


@@ -27,7 +27,8 @@ class ClangTidyConfigHandler(config_handler.AnalyzerConfigHandler):
         """
         Enable checker, keep description if already set.
         """
-        if checker_name.startswith("Wno-") or checker_name.startswith("W"):
+        if checker_name.startswith('W') or \
+           checker_name.startswith('clang-diagnostic-'):
             self.add_checker(checker_name)

         super(ClangTidyConfigHandler, self).set_checker_enabled(checker_name,

# -------------------------------------------------------------------------
#                     The CodeChecker Infrastructure
#   This file is distributed under the University of Illinois Open Source
#   License. See LICENSE.TXT for details.
# -------------------------------------------------------------------------
"""
Config handler for Clang Tidy analyzer.
"""

from codechecker_common.logger import get_logger

from .. import config_handler

LOG = get_logger('analyzer.tidy')

class ClangTidyConfigHandler(config_handler.AnalyzerConfigHandler):
    """
    Configuration handler for Clang-tidy analyzer.
    """

    def __init__(self):
        super(ClangTidyConfigHandler, self).__init__()

    def set_checker_enabled(self, checker_name, enabled=True):
        """
        Enable checker, keep description if already set.
        """
        if checker_name.startswith("Wno-") or checker_name.startswith("W"):
            self.add_checker(checker_name)

        super(ClangTidyConfigHandler, self).set_checker_enabled(checker_name,
                                                                enabled)

You removed `Wno-` from this condition. Isn't it change the behaviour of the analyze command? For example if I give `-e Wno-unused-value` or `-d Wno-unused-value` to this command?


@@ -54,6 +54,7 @@ void handle_keyboard_key(struct libinput_event *event,
 	struct libinput_event_keyboard *kbevent =
 		libinput_event_get_keyboard_event(event);
 	struct wlr_event_keyboard_key wlr_event = { 0 };
+	wlr_event.device = wlr_dev;
 	wlr_event.time_msec =
 		usec_to_msec(libinput_event_keyboard_get_time_usec(kbevent));
 	wlr_event.keycode = libinput_event_keyboard_get_key(kbevent);

#include <stdlib.h>
#include <assert.h>
#include <libinput.h>
#include <wlr/backend/session.h>
#include <wlr/types/wlr_input_device.h>
#include <wlr/interfaces/wlr_keyboard.h>
#include <wlr/util/log.h>
#include "backend/libinput.h"

struct wlr_libinput_keyboard {
	struct wlr_keyboard wlr_keyboard;
	struct libinput_device *libinput_dev;
};

static void wlr_libinput_keyboard_set_leds(struct wlr_keyboard *wlr_kb, uint32_t leds) {
	struct wlr_libinput_keyboard *wlr_libinput_kb = (struct wlr_libinput_keyboard *)wlr_kb;
	libinput_device_led_update(wlr_libinput_kb->libinput_dev, leds);
}

static void wlr_libinput_keyboard_destroy(struct wlr_keyboard *wlr_kb) {
	struct wlr_libinput_keyboard *wlr_libinput_kb =
		(struct wlr_libinput_keyboard *)wlr_kb;
	libinput_device_unref(wlr_libinput_kb->libinput_dev);
}

struct wlr_keyboard_impl impl = {
	.destroy = wlr_libinput_keyboard_destroy,
	.led_update = wlr_libinput_keyboard_set_leds
};

struct wlr_keyboard *wlr_libinput_keyboard_create(
		struct libinput_device *libinput_dev) {
	assert(libinput_dev);
	struct wlr_libinput_keyboard *wlr_libinput_kb;
	if (!(wlr_libinput_kb= calloc(1, sizeof(struct wlr_libinput_keyboard)))) {
		return NULL;
	}
	wlr_libinput_kb->libinput_dev = libinput_dev;
	libinput_device_ref(libinput_dev);
	libinput_device_led_update(libinput_dev, 0);
	struct wlr_keyboard *wlr_kb = &wlr_libinput_kb->wlr_keyboard;
	wlr_keyboard_init(wlr_kb, &impl);
	return wlr_kb;
}

void handle_keyboard_key(struct libinput_event *event,
		struct libinput_device *libinput_dev) {
	struct wlr_input_device *wlr_dev =
		get_appropriate_device(WLR_INPUT_DEVICE_KEYBOARD, libinput_dev);
	if (!wlr_dev) {
		wlr_log(L_DEBUG, "Got a keyboard event for a device with no keyboards?");
		return;
	}
	struct libinput_event_keyboard *kbevent =
		libinput_event_get_keyboard_event(event);
	struct wlr_event_keyboard_key wlr_event = { 0 };
	wlr_event.time_msec =
		usec_to_msec(libinput_event_keyboard_get_time_usec(kbevent));
	wlr_event.keycode = libinput_event_keyboard_get_key(kbevent);
	enum libinput_key_state state =
		libinput_event_keyboard_get_key_state(kbevent);
	switch (state) {
	case LIBINPUT_KEY_STATE_RELEASED:
		wlr_event.state = WLR_KEY_RELEASED;
		break;
	case LIBINPUT_KEY_STATE_PRESSED:
		wlr_event.state = WLR_KEY_PRESSED;
		break;
	}
	wlr_event.update_state = true;
	wlr_keyboard_notify_key(wlr_dev->keyboard, &wlr_event);
}


@@ -105,21 +105,14 @@ func createNetworkPolicy(clientset *kubernetes.Clientset, namespace string) {
 			Name:      "test-syncer-basic-net-policy",
 		},
 		Spec: networkingv1.NetworkPolicySpec{
-			PodSelector: metav1.LabelSelector{
-				MatchLabels: map[string]string{"calico/k8s_ns": namespace},
-			},
+			// An empty PodSelector selects all pods in this Namespace.
+			PodSelector: metav1.LabelSelector{},
 			Ingress: []networkingv1.NetworkPolicyIngressRule{
 				networkingv1.NetworkPolicyIngressRule{
-					Ports: []networkingv1.NetworkPolicyPort{
-						networkingv1.NetworkPolicyPort{},
-					},
 					From: []networkingv1.NetworkPolicyPeer{
 						networkingv1.NetworkPolicyPeer{
-							PodSelector: &metav1.LabelSelector{
-								MatchLabels: map[string]string{
-									"calico/k8s_ns": namespace,
-								},
-							},
+							// An empty PodSelector selects all pods in this Namespace.
+							PodSelector: &metav1.LabelSelector{},
 						},
 					},
 				},

// Copyright (c) 2017 Tigera, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"encoding/json"
	"fmt"
	"strings"

	log "github.com/sirupsen/logrus"
	"k8s.io/api/core/v1"
	networkingv1 "k8s.io/api/networking/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
)

var nsPrefixNum = 0

func getNamespacePrefix() (nsPrefix string) {
	nsPrefixNum++
	nsPrefix = fmt.Sprintf("ns%d-", nsPrefixNum)
	return
}

type namespacePolicy struct {
	Ingress struct {
		Isolation string `json:"isolation"`
	} `json:"ingress"`
}

func createNamespace(clientset *kubernetes.Clientset, name string, labels map[string]string) {
	createNamespaceInt(clientset, name, labels, "")
}

func createIsolatedNamespace(clientset *kubernetes.Clientset, name string, labels map[string]string) {
	createNamespaceInt(clientset, name, labels, "DefaultDeny")
}

func createNamespaceInt(
	clientset *kubernetes.Clientset,
	name string,
	labels map[string]string,
	isolation string,
) {
	ns_in := &v1.Namespace{
		ObjectMeta: metav1.ObjectMeta{
			Name:   name,
			Labels: labels,
		},
	}
	if isolation != "" {
		np := namespacePolicy{}
		np.Ingress.Isolation = isolation
		annotation, _ := json.Marshal(np)
		ns_in.ObjectMeta.Annotations = map[string]string{
			"net.beta.kubernetes.io/network-policy": string(annotation),
		}
	}
	log.WithField("ns_in", ns_in).Debug("Namespace defined")
	ns_out, err := clientset.CoreV1().Namespaces().Create(ns_in)
	if err != nil {
		panic(err)
	}
	log.WithField("ns_out", ns_out).Debug("Created namespace")
}

func cleanupAllNamespaces(clientset *kubernetes.Clientset, nsPrefix string) {
	log.Info("Cleaning up all namespaces...")
	nsList, err := clientset.CoreV1().Namespaces().List(metav1.ListOptions{})
	if err != nil {
		panic(err)
	}
	log.WithField("count", len(nsList.Items)).Info("Namespaces present")
	for _, ns := range nsList.Items {
		if strings.HasPrefix(ns.ObjectMeta.Name, nsPrefix) {
			err = clientset.CoreV1().Namespaces().Delete(ns.ObjectMeta.Name, deleteImmediately)
			if err != nil {
				panic(err)
			}
		} else {
			log.WithField("name", ns.ObjectMeta.Name).Debug("Namespace skipped")
		}
	}
	log.Info("Cleaned up all namespaces")
}

// Create a NetworkPolicy, for pods in the specified namespace, that allows ingress from other pods
// in the same namespace.
func createNetworkPolicy(clientset *kubernetes.Clientset, namespace string) {
	np := networkingv1.NetworkPolicy{
		ObjectMeta: metav1.ObjectMeta{
			Namespace: namespace,
			Name:      "test-syncer-basic-net-policy",
		},
		Spec: networkingv1.NetworkPolicySpec{
			PodSelector: metav1.LabelSelector{
				MatchLabels: map[string]string{"calico/k8s_ns": namespace},
			},
			Ingress: []networkingv1.NetworkPolicyIngressRule{
				networkingv1.NetworkPolicyIngressRule{
					Ports: []networkingv1.NetworkPolicyPort{
						networkingv1.NetworkPolicyPort{},
					},
					From: []networkingv1.NetworkPolicyPeer{
						networkingv1.NetworkPolicyPeer{
							PodSelector: &metav1.LabelSelector{
								MatchLabels: map[string]string{
									"calico/k8s_ns": namespace,
								},
							},
						},
					},
				},
			},
		},
	}
	clientset.NetworkingV1().NetworkPolicies("").Create(&np)
}

Does not specifying Ports at all here, have the same meaning as specifying a single empty Port struct?


@@ -32,8 +32,10 @@ bool wlr_backend_start(struct wlr_backend *backend) {
 }

 void wlr_backend_destroy(struct wlr_backend *backend) {
-	if (backend->impl->destroy) {
+	if (backend->impl && backend->impl->destroy) {
 		backend->impl->destroy(backend);
+	} else {
+		free(backend);
 	}
 }

#include <wayland-server.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <libinput.h>
#include <wlr/backend/session.h>
#include <wlr/backend/interface.h>
#include <wlr/backend/drm.h>
#include <wlr/backend/libinput.h>
#include <wlr/backend/wayland.h>
#include <wlr/backend/multi.h>
#include <wlr/util/log.h>
#include "backend/udev.h"

void wlr_backend_init(struct wlr_backend *backend,
		const struct wlr_backend_impl *impl) {
	assert(backend);
	backend->impl = impl;
	wl_signal_init(&backend->events.input_add);
	wl_signal_init(&backend->events.input_remove);
	wl_signal_init(&backend->events.output_add);
	wl_signal_init(&backend->events.output_remove);
}

bool wlr_backend_start(struct wlr_backend *backend) {
	if (backend->impl->start) {
		return backend->impl->start(backend);
	}
	return true;
}

void wlr_backend_destroy(struct wlr_backend *backend) {
	if (backend->impl->destroy) {
		backend->impl->destroy(backend);
	}
}

struct wlr_egl *wlr_backend_get_egl(struct wlr_backend *backend) {
	if (backend->impl->get_egl) {
		return backend->impl->get_egl(backend);
	}
	return NULL;
}

static struct wlr_backend *attempt_wl_backend(struct wl_display *display) {
	struct wlr_backend *backend = wlr_wl_backend_create(display);
	if (backend) {
		int outputs = 1;
		const char *_outputs = getenv("WLR_WL_OUTPUTS");
		if (_outputs) {
			char *end;
			outputs = (int)strtol(_outputs, &end, 10);
			if (*end) {
				wlr_log(L_ERROR, "WLR_WL_OUTPUTS specified with invalid integer, ignoring");
				outputs = 1;
			} else if (outputs < 0) {
				wlr_log(L_ERROR, "WLR_WL_OUTPUTS specified with negative outputs, ignoring");
				outputs = 1;
			}
		}
		while (outputs--) {
			wlr_wl_output_create(backend);
		}
	}
	return backend;
}

struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) {
	struct wlr_backend *backend;
	if (getenv("WAYLAND_DISPLAY") || getenv("_WAYLAND_DISPLAY")) {
		backend = attempt_wl_backend(display);
		if (backend) {
			return backend;
		}
	}

	if (getenv("DISPLAY")) {
		wlr_log(L_ERROR, "X11 backend is not implemented"); // TODO
		return NULL;
	}

	// Attempt DRM+libinput

	struct wlr_session *session = wlr_session_start(display);
	if (!session) {
		wlr_log(L_ERROR, "Failed to start a DRM session");
		return NULL;
	}

	struct wlr_udev *udev = wlr_udev_create(display);
	if (!udev) {
		wlr_log(L_ERROR, "Failed to start udev");
		goto error_session;
	}

	int gpu = wlr_udev_find_gpu(udev, session);
	if (gpu == -1) {
		wlr_log(L_ERROR, "Failed to open DRM device");
		goto error_udev;
	}

	backend = wlr_multi_backend_create(session, udev);
	if (!backend) {
		goto error_gpu;
	}

	struct wlr_backend *libinput = wlr_libinput_backend_create(display, session, udev);
	if (!libinput) {
		goto error_multi;
	}

	struct wlr_backend *drm = wlr_drm_backend_create(display, session, udev, gpu);
	if (!drm) {
		goto error_libinput;
	}

	wlr_multi_backend_add(backend, libinput);
	wlr_multi_backend_add(backend, drm);
	return backend;

error_libinput:
	wlr_backend_destroy(libinput);
error_multi:
	wlr_backend_destroy(backend);
error_gpu:
	wlr_session_close_file(session, gpu);
error_udev:
	wlr_udev_destroy(udev);
error_session:
	wlr_session_finish(session);
	return NULL;
}

If you're going to start testing that impl itself is not NULL you should probably be doing it everywhere.


@@ -50,6 +50,24 @@
 -- @see rule
 -- @see except

+--- A table which content will be compared to the target object current properties.
+--
+-- The comparison will be made using the lesser (`<`) operator.
+--
+-- @rulecomponent rule_lesser
+-- @param table
+-- @see rule
+-- @see except
+
+--- A table which content will be compared to the target object current properties.
+--
+-- The comparison will be made using the greater (`>`) operator.
+--
+-- @rulecomponent rule_greater
+-- @param table
+-- @see rule
+-- @see except
+
 --- An identifier for this rule.
 --
 -- It can be anything. It will be compared with the `==` operator. Strings are

---

--- A table which content will be used to set the target object properties.
--
-- @rulecomponent properties
-- @param table
-- @see callbacks

--TODO add ^
-- @DOC_text_gears_matcher_properties_EXAMPLE@

--- A list of callback function to call *after* the properties have been apploed.
-- @rulecomponent callbacks
-- @param table
-- @see properties

--- A table which content will be compared to the target object current properties.
--
-- @rulecomponent rule
-- @param table
-- @see rule_any
-- @see except

--- Similar to `rule`, but each entry is a table with multiple values.
--
--
-- @rulecomponent rule_any
-- @param table
-- @see rule
-- @see except_any

--- The negative equivalent of `rule`.
--
-- @rulecomponent except
-- @param table
-- @see rule
-- @see except_any

--- The negative equivalent of `rule_any`.
--
-- @rulecomponent except_any
-- @param table
-- @see rule
-- @see except

--- Matches when one of every "category" of components match.
--
-- @rulecomponent rule_every
-- @param table
-- @see rule
-- @see except

--- An identifier for this rule.
--
-- It can be anything. It will be compared with the `==` operator. Strings are
-- highly recommended.
--
-- Setting an `id` is useful to be able to remove the rule by using its id
-- instead of a table reference. Modules can also listen to `rule::appended` and
-- modify or disable a rule.
--
-- @rulecomponent id
-- @param table|string|number|function

I do not understand what "comparing the content of tables via `<`" is supposed to mean.


@@ -74,6 +74,12 @@ proc_num_simd_saved(void)
     return num_simd_saved;
 }

+void
+proc_set_num_simd_saved(int num)
+{
+    num_simd_saved = num;
+}
+
 DR_API
 int
 proc_num_simd_registers(void)

/* **********************************************************
 * Copyright (c) 2016 ARM Limited. All rights reserved.
 * **********************************************************/

/*
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of ARM Limited nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without
 *   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL ARM LIMITED OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

#include "../globals.h"
#include "proc.h"
#include "instr.h"

static int num_simd_saved;
static int num_simd_registers;

void
proc_init_arch(void)
{
    num_simd_saved = MCXT_NUM_SIMD_SLOTS;
    num_simd_registers = MCXT_NUM_SIMD_SLOTS;

    /* FIXME i#1569: NYI */
}

bool
proc_has_feature(feature_bit_t f)
{
    ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */
    return false;
}

void
machine_cache_sync(void *pc_start, void *pc_end, bool flush_icache)
{
    clear_icache(pc_start, pc_end);
}

DR_API
size_t
proc_fpstate_save_size(void)
{
    ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */
    return 0;
}

DR_API
int
proc_num_simd_saved(void)
{
    return num_simd_saved;
}

DR_API
int
proc_num_simd_registers(void)
{
    return num_simd_registers;
}

int
proc_num_simd_sse_avx_registers(void)
{
    CLIENT_ASSERT(false, "Incorrect usage for ARM/AArch64.");
    return 0;
}

int
proc_num_simd_sse_avx_saved(void)
{
    CLIENT_ASSERT(false, "Incorrect usage for ARM/AArch64.");
    return 0;
}

DR_API
size_t
proc_save_fpstate(byte *buf)
{
    /* All registers are saved by insert_push_all_registers so nothing extra
     * needs to be saved here.
     */
    return DR_FPSTATE_BUF_SIZE;
}

DR_API
void
proc_restore_fpstate(byte *buf)
{
    /* Nothing to restore. */
}

void
dr_insert_save_fpstate(void *drcontext, instrlist_t *ilist, instr_t *where, opnd_t buf)
{
    ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */
}

void
dr_insert_restore_fpstate(void *drcontext, instrlist_t *ilist, instr_t *where, opnd_t buf)
{
    ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */
}

uint64
proc_get_timestamp(void)
{
    ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */
    return 0;
}

> i#1312 AVX-512 support: Add code cache to/from context switching. s|to/from|| (redundant and mildly confusing (called "enter" and "return" in code)).


@@ -41,6 +41,7 @@ def add_verbose_arguments(parser):

 # ------------------------------------------------------------------------------
 logging.DEBUG_ANALYZER = 15
+DEBUG_ANALYZER = logging.DEBUG_ANALYZER
 logging.addLevelName(logging.DEBUG_ANALYZER, 'DEBUG_ANALYZER')

# -------------------------------------------------------------------------
#                     The CodeChecker Infrastructure
#   This file is distributed under the University of Illinois Open Source
#   License. See LICENSE.TXT for details.
# -------------------------------------------------------------------------
"""
"""

import logging
import os
import sys
import time

# The logging leaves can be accesses without
# importing the logging module in other modules.
DEBUG = logging.DEBUG
INFO = logging.INFO
WARNING = logging.WARNING
ERROR = logging.ERROR
CRITICAL = logging.CRITICAL
NOTSET = logging.NOTSET

class BColors(object):
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'

def add_verbose_arguments(parser):
    """
    Verbosity level arguments.
    """
    parser.add_argument('--verbose', type=str, dest='verbose',
                        choices=['info', 'debug', 'debug_analyzer'],
                        default='info',
                        help='Set verbosity level.')

# ------------------------------------------------------------------------------
logging.DEBUG_ANALYZER = 15
logging.addLevelName(logging.DEBUG_ANALYZER, 'DEBUG_ANALYZER')

class CCLogger(logging.Logger):
    def __init__(self, name, level=NOTSET):
        super(CCLogger, self).__init__(name, level)

    def debug_analyzer(self, msg, *args, **kwargs):
        if self.isEnabledFor(logging.DEBUG_ANALYZER):
            self._log(logging.DEBUG_ANALYZER, msg, args, **kwargs)

logging.setLoggerClass(CCLogger)

class CustomFormatter(logging.Formatter):
    """
    Custom formatter to print log level in case of ERROR, WARNING
    or CRITICAL.
    """

    info_fmt = '[%(asctime)s] - %(message)s'
    error_fmt = '[%(levelname)s] [%(asctime)s] - %(message)s'
    debug_fmt = '[%(asctime)s] [%(process)d] <%(thread)d> - ' \
        '%(filename)s:%(lineno)d %(funcName)s() - %(message)s'

    def formatTime(self, record, datefmt=None):
        if LoggerFactory.log_level == logging.DEBUG or \
                LoggerFactory.log_level == logging.DEBUG_ANALYZER:
            return time.strftime('%H:%M:%S')
        else:
            return time.strftime('%H:%M')

    def format(self, record):

        # Save the original format
        format_orig = self._fmt

        # Replace the original format
        if record.levelno == logging.DEBUG:
            self._fmt = CustomFormatter.debug_fmt
        if record.levelno == logging.DEBUG_ANALYZER:
            self._fmt = CustomFormatter.debug_fmt
        elif record.levelno == logging.INFO:
            self._fmt = CustomFormatter.info_fmt
        elif record.levelno == logging.ERROR:
            self._fmt = CustomFormatter.error_fmt
        elif record.levelno == logging.WARNING:
            self._fmt = CustomFormatter.error_fmt
        elif record.levelno == logging.CRITICAL:
            self._fmt = CustomFormatter.error_fmt

        result = logging.Formatter.format(self, record)

        self._fmt = format_orig

        return result

class LoggerFactory(object):
    log_level = logging.INFO
    loggers = []

    short_format_handler = logging.StreamHandler(stream=sys.stdout)
    long_format_handler = logging.StreamHandler(stream=sys.stdout)

    short_format_handler.setFormatter(CustomFormatter())
    long_format_handler.setFormatter(CustomFormatter())

    handlers = {
        logging.INFO: short_format_handler,
        logging.DEBUG: long_format_handler,
        logging.DEBUG_ANALYZER: short_format_handler}

    @classmethod
    def get_log_level(cls):
        return cls.log_level

    @classmethod
    def set_log_level(cls, level):
        for logger in cls.loggers:
            logger.removeHandler(cls.handlers[LoggerFactory.log_level])

        if level == 'debug':
            cls.log_level = logging.DEBUG
        elif level == 'info':
            cls.log_level = logging.INFO
        elif level == 'debug_analyzer':
            cls.log_level = logging.DEBUG_ANALYZER
        else:
            cls.log_level = logging.INFO

        cls.short_format_handler.setLevel(cls.log_level)
        cls.long_format_handler.setLevel(cls.log_level)

        for logger in cls.loggers:
            logger.setLevel(cls.log_level)
            logger.addHandler(cls.handlers[cls.log_level])

    @classmethod
    def get_new_logger(cls, logger_name):
        logger = logging.getLogger('[' + logger_name + ']')

        logger.setLevel(cls.log_level)
        logger.addHandler(cls.handlers[cls.log_level])

        cls.loggers.append(logger)

        return logger

I think we could use the `DEBUG_ANALYZER` instead of `logging.DEBUG_ANALYZER` when we add the new level name.


@@ -34,6 +34,7 @@
  */

 #include "globals.h"
+#include "arch.h"

 void
 unit_test_io(void);

/* **********************************************************
 * Copyright (c) 2012-2013 Google, Inc.  All rights reserved.
 * **********************************************************/

/*
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of Google, Inc. nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without
 *   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE, INC. OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

/* Simple main that just calls each unit test in turn.
 */

#include "globals.h"

void
unit_test_io(void);
#ifdef UNIX
void
unit_test_string(void);
void
unit_test_os(void);
#endif
void
unit_test_options(void);
void
unit_test_vmareas(void);
void
unit_test_utils(void);
#ifdef WINDOWS
void
unit_test_drwinapi(void);
#endif
void
unit_test_asm(dcontext_t *dc);
void
unit_test_atomic_ops(void);
void
unit_test_jit_fragment_tree(void);

int
main(int argc, char **argv, char **envp)
{
    dcontext_t *dc = standalone_init();

    /* Each test will abort if it fails, so we just call each in turn and return
     * 0 for success.  If we want to be able to call each test independently, it
     * might be worth looking into gtest, which already does this.
     */
    unit_test_io();
#ifdef UNIX
    unit_test_string();
    unit_test_os();
#endif
    unit_test_utils();
    unit_test_options();
    unit_test_vmareas();
#ifdef WINDOWS
    unit_test_drwinapi();
#endif
    unit_test_asm(dc);
    unit_test_atomic_ops();
    unit_test_jit_fragment_tree();
    print_file(STDERR, "all done\n");
    return 0;
}

Put the unit tests in an arch/ location, not in this top-level driver file. IIRC I suggested arch.c in my original request for a unit test, but arch/x86 may be better.


@@ -73,13 +73,15 @@ void handle_x11_input_event(struct wlr_x11_backend *x11,

 		if (ev->detail == XCB_BUTTON_INDEX_4 ||
 				ev->detail == XCB_BUTTON_INDEX_5) {
-			double delta = (ev->detail == XCB_BUTTON_INDEX_4 ? -15 : 15);
+			int32_t delta_discrete = ev->detail == XCB_BUTTON_INDEX_4 ? -1 : 1;
 			struct wlr_event_pointer_axis axis = {
 				.device = &output->pointer_dev,
 				.time_msec = ev->time,
 				.source = WLR_AXIS_SOURCE_WHEEL,
 				.orientation = WLR_AXIS_ORIENTATION_VERTICAL,
-				.delta = delta,
+				// 15 is a typical value libinput sends for one scroll
+				.delta = delta_discrete * 15,
+				.delta_discrete = delta_discrete,
 			};
 			wlr_signal_emit_safe(&output->pointer.events.axis, &axis);
 			x11->time = ev->time;

#include <stdlib.h>
#include <wlr/config.h>
#include <wlr/interfaces/wlr_input_device.h>
#include <wlr/interfaces/wlr_keyboard.h>
#include <wlr/interfaces/wlr_pointer.h>
#include <wlr/util/log.h>
#include <xcb/xcb.h>
#ifdef __linux__
#include <linux/input-event-codes.h>
#elif __FreeBSD__
#include <dev/evdev/input-event-codes.h>
#endif
#ifdef WLR_HAS_XCB_XKB
#include <xcb/xkb.h>
#endif
#include "backend/x11.h"
#include "util/signal.h"

static uint32_t xcb_button_to_wl(uint32_t button) {
	switch (button) {
	case XCB_BUTTON_INDEX_1: return BTN_LEFT;
	case XCB_BUTTON_INDEX_2: return BTN_MIDDLE;
	case XCB_BUTTON_INDEX_3: return BTN_RIGHT;
	// XXX: I'm not sure the scroll-wheel direction is right
	case XCB_BUTTON_INDEX_4: return BTN_GEAR_UP;
	case XCB_BUTTON_INDEX_5: return BTN_GEAR_DOWN;
	default: return 0;
	}
}

static void x11_handle_pointer_position(struct wlr_x11_output *output,
		int16_t x, int16_t y, xcb_timestamp_t time) {
	struct wlr_x11_backend *x11 = output->x11;
	struct wlr_output *wlr_output = &output->wlr_output;
	struct wlr_event_pointer_motion_absolute event = {
		.device = &output->pointer_dev,
		.time_msec = time,
		.x = (double)x / wlr_output->width,
		.y = (double)y / wlr_output->height,
	};
	wlr_signal_emit_safe(&output->pointer.events.motion_absolute, &event);

	x11->time = time;
}

void handle_x11_input_event(struct wlr_x11_backend *x11,
		xcb_generic_event_t *event) {
	switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) {
	case XCB_KEY_PRESS:
	case XCB_KEY_RELEASE: {
		xcb_key_press_event_t *ev = (xcb_key_press_event_t *)event;
		struct wlr_event_keyboard_key key = {
			.time_msec = ev->time,
			.keycode = ev->detail - 8,
			.state = event->response_type == XCB_KEY_PRESS ?
				WLR_KEY_PRESSED : WLR_KEY_RELEASED,
			.update_state = true,
		};

		// TODO use xcb-xkb for more precise modifiers state?
		wlr_keyboard_notify_key(&x11->keyboard, &key);
		x11->time = ev->time;
		return;
	}
	case XCB_BUTTON_PRESS: {
		xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event;

		struct wlr_x11_output *output =
			get_x11_output_from_window_id(x11, ev->event);
		if (output == NULL) {
			break;
		}

		if (ev->detail == XCB_BUTTON_INDEX_4 ||
				ev->detail == XCB_BUTTON_INDEX_5) {
			double delta = (ev->detail == XCB_BUTTON_INDEX_4 ? -15 : 15);
			struct wlr_event_pointer_axis axis = {
				.device = &output->pointer_dev,
				.time_msec = ev->time,
				.source = WLR_AXIS_SOURCE_WHEEL,
				.orientation = WLR_AXIS_ORIENTATION_VERTICAL,
				.delta = delta,
			};
			wlr_signal_emit_safe(&output->pointer.events.axis, &axis);
			x11->time = ev->time;
			break;
		}
	}
	/* fallthrough */
	case XCB_BUTTON_RELEASE: {
		xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event;

		struct wlr_x11_output *output =
			get_x11_output_from_window_id(x11, ev->event);
		if (output == NULL) {
			break;
		}

		if (ev->detail != XCB_BUTTON_INDEX_4 &&
				ev->detail != XCB_BUTTON_INDEX_5) {
			struct wlr_event_pointer_button button = {
				.device = &output->pointer_dev,
				.time_msec = ev->time,
				.button = xcb_button_to_wl(ev->detail),
				.state = event->response_type == XCB_BUTTON_PRESS ?
					WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED,
			};

			wlr_signal_emit_safe(&output->pointer.events.button, &button);
		}
		x11->time = ev->time;
		return;
	}
	case XCB_MOTION_NOTIFY: {
		xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)event;

		struct wlr_x11_output *output =
			get_x11_output_from_window_id(x11, ev->event);
		if (output != NULL) {
			x11_handle_pointer_position(output, ev->event_x, ev->event_y, ev->time);
		}
		return;
	}
	default:
#ifdef WLR_HAS_XCB_XKB
		if (x11->xkb_supported && event->response_type == x11->xkb_base_event) {
			xcb_xkb_state_notify_event_t *ev =
				(xcb_xkb_state_notify_event_t *)event;
			wlr_keyboard_notify_modifiers(&x11->keyboard, ev->baseMods,
				ev->latchedMods, ev->lockedMods, ev->lockedGroup);
			return;
		}
#endif
		break;
	}
}

static void input_device_destroy(struct wlr_input_device *wlr_device) {
	// Don't free the input device, it's on the stack
}

const struct wlr_input_device_impl input_device_impl = {
	.destroy = input_device_destroy,
};

static void keyboard_destroy(struct wlr_keyboard *wlr_keyboard) {
	// Don't free the keyboard, it's on the stack
}

const struct wlr_keyboard_impl keyboard_impl = {
	.destroy = keyboard_destroy,
};

static void pointer_destroy(struct wlr_pointer *wlr_pointer) {
	// Don't free the pointer, it's on the stack
}

const struct wlr_pointer_impl pointer_impl = {
	.destroy = pointer_destroy,
};

void update_x11_pointer_position(struct wlr_x11_output *output,
		xcb_timestamp_t time) {
	struct wlr_x11_backend *x11 = output->x11;

	xcb_query_pointer_cookie_t cookie =
		xcb_query_pointer(x11->xcb_conn, output->win);
	xcb_query_pointer_reply_t *reply =
		xcb_query_pointer_reply(x11->xcb_conn, cookie, NULL);
	if (!reply) {
		return;
	}

	x11_handle_pointer_position(output, reply->win_x, reply->win_y, time);

	free(reply);
}

bool wlr_input_device_is_x11(struct wlr_input_device *wlr_dev) {
	return wlr_dev->impl == &input_device_impl;
}

I'm not a fan of putting 15 here like that. It seems just like the Xwayland problem of 10, but now with a different value.


@@ -19,6 +19,23 @@ from libcodechecker.logger import LoggerFactory
 LOG = LoggerFactory.get_new_logger('PROFILER')

+class Timer(object):
+    """
+    Simple timer context manager
+    to measure code block execution time.
+    """
+    def __init__(self, block_name=''):
+        self.block_name = block_name
+
+    def __enter__(self):
+        self.before = datetime.datetime.now()
+
+    def __exit__(self, type, value, traceback):
+        after = datetime.datetime.now()
+        time_diff = after - self.before
+        LOG.debug(self.block_name + " " + str(time_diff.total_seconds())+'s')
+
+
 def timeit(function):
     """
     Decorator to measure function call time.

# -------------------------------------------------------------------------
#                     The CodeChecker Infrastructure
#   This file is distributed under the University of Illinois Open Source
#   License. See LICENSE.TXT for details.
# -------------------------------------------------------------------------

from datetime import datetime
import cProfile
import pstats

try:
    from StringIO import StringIO
except ImportError:
    from io import BytesIO as StringIO

from libcodechecker import logger
from libcodechecker.logger import LoggerFactory

LOG = LoggerFactory.get_new_logger('PROFILER')

def timeit(function):
    """
    Decorator to measure function call time.
    """

    func_name = function.__name__

    def debug_wrapper(*args, **kwargs):
        """
        Log measured time.
        """
        before = datetime.now()
        res = function(*args, **kwargs)
        after = datetime.now()
        timediff = after - before
        diff = timediff.microseconds/1000
        LOG.debug('['+str(diff)+'ms] ' + func_name)
        return res

    def release_wrapper(*args, **kwargs):
        """
        No logging and measuring.
        """
        res = function(*args, **kwargs)
        return res

    if LoggerFactory.get_log_level() == logger.DEBUG:
        return debug_wrapper
    else:
        return release_wrapper

def profileit(function):
    """
    Decorator to pofile function calls.
    """

    function_name = function.__name__

    def wrapper(*args, **kwargs):

        prof = cProfile.Profile()
        LOG.debug('Profiling: ' + function_name)
        prof.enable()
        res = function(*args, **kwargs)
        prof.disable()
        sortby = 'cumulative'

        prof_data = StringIO.StringIO()
        ps = pstats.Stats(prof, stream=prof_data).sort_stats(sortby)
        ps.print_stats()
        LOG.debug(prof_data.getvalue())
        prof_data.close()
        return res

    return wrapper

I think either this should be `self.after` or `self.after` should not be initialized.


@@ -13,7 +13,10 @@ void wlr_tablet_pad_init(struct wlr_tablet_pad *pad,
 }

 void wlr_tablet_pad_destroy(struct wlr_tablet_pad *pad) {
-	if (!pad) return;
+	if (!pad) {
+		return;
+	}
+
 	if (pad->impl && pad->impl->destroy) {
 		pad->impl->destroy(pad);
 	} else {

#include <stdlib.h>
#include <string.h>
#include <wayland-server.h>
#include <wlr/types/wlr_tablet_pad.h>
#include <wlr/interfaces/wlr_tablet_pad.h>

void wlr_tablet_pad_init(struct wlr_tablet_pad *pad,
		struct wlr_tablet_pad_impl *impl) {
	pad->impl = impl;
	wl_signal_init(&pad->events.button);
	wl_signal_init(&pad->events.ring);
	wl_signal_init(&pad->events.strip);
}

void wlr_tablet_pad_destroy(struct wlr_tablet_pad *pad) {
	if (!pad) return;
	if (pad->impl && pad->impl->destroy) {
		pad->impl->destroy(pad);
	} else {
		free(pad);
	}
}


@@ -1,18 +1,23 @@
 #define BOOST_TEST_MODULE TQTcpServerTest
 #include <QTest>
-#include <boost/smart_ptr.hpp>
+
+#ifndef Q_MOC_RUN
+  #include <boost/smart_ptr.hpp>
+#endif
 #include <iostream>

 #include <QTcpServer>
 #include <QTcpSocket>
 #include <QHostAddress>

-#include "thrift/protocol/TBinaryProtocol.h"
-#include "thrift/async/TAsyncProcessor.h"
-#include "thrift/qt/TQTcpServer.h"
-#include "thrift/qt/TQIODeviceTransport.h"
-
-#include "gen-cpp/ParentService.h"
+#ifndef Q_MOC_RUN
+  #include "thrift/protocol/TBinaryProtocol.h"
+  #include "thrift/async/TAsyncProcessor.h"
+  #include "thrift/qt/TQTcpServer.h"
+  #include "thrift/qt/TQIODeviceTransport.h"
+
+  #include "gen-cpp/ParentService.h"
+#endif

 using namespace apache::thrift;

#define BOOST_TEST_MODULE TQTcpServerTest
#include <QTest>
#include <boost/smart_ptr.hpp>
#include <iostream>

#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>

#include "thrift/protocol/TBinaryProtocol.h"
#include "thrift/async/TAsyncProcessor.h"
#include "thrift/qt/TQTcpServer.h"
#include "thrift/qt/TQIODeviceTransport.h"

#include "gen-cpp/ParentService.h"

using namespace apache::thrift;

struct AsyncHandler : public test::ParentServiceCobSvIf {
  std::vector<std::string> strings;
  virtual void addString(tcxx::function<void()> cob, const std::string& s) {
    strings.push_back(s);
    cob();
  }
  virtual void getStrings(tcxx::function<void(std::vector<std::string> const& _return)> cob) {
    cob(strings);
  }

  // Overrides not used in this test
  virtual void incrementGeneration(tcxx::function<void(int32_t const& _return)> cob) {}
  virtual void getGeneration(tcxx::function<void(int32_t const& _return)> cob) {}
  virtual void getDataWait(tcxx::function<void(std::string const& _return)> cob,
                           const int32_t length) {}
  virtual void onewayWait(tcxx::function<void()> cob) {}
  virtual void exceptionWait(
      tcxx::function<void()> cob,
      tcxx::function<void(::apache::thrift::TDelayedException* _throw)> /* exn_cob */,
      const std::string& message) {}
  virtual void unexpectedExceptionWait(tcxx::function<void()> cob, const std::string& message) {}
};

class TQTcpServerTest : public QObject {
  void init() {
    // setup server
    serverSocket.reset(new QTcpServer);
    server.reset(new async::TQTcpServer(serverSocket,
                                        boost::make_shared<test::ParentServiceAsyncProcessor>(
                                            boost::make_shared<AsyncHandler>()),
                                        boost::make_shared<protocol::TBinaryProtocolFactory>()));
    QVERIFY(serverSocket->listen(QHostAddress::LocalHost));
    int port = serverSocket->serverPort();
    QVERIFY(port > 0);

    // setup client
    socket.reset(new QTcpSocket);
    client.reset(new test::ParentServiceClient(boost::make_shared<protocol::TBinaryProtocol>(
        boost::make_shared<transport::TQIODeviceTransport>(socket))));
    socket->connectToHost(QHostAddress::LocalHost, port);
    QVERIFY(socket->waitForConnected());
  }

  void cleanup() {
    socket->close();
    serverSocket->close();
  }

  void test_communicate() {
    client->addString("foo");
    client->addString("bar");

    std::vector<std::string> reply;
    client->getStrings(reply);
    QCOMPARE(reply[0], "foo");
    QCOMPARE(reply[1], "foo");
  }

  boost::shared_ptr<QTcpServer> serverSocket;
  boost::shared_ptr<async::TQTcpServer> server;
  boost::shared_ptr<QTcpSocket> socket;
  boost::shared_ptr<test::ParentServiceClient> client;
};

#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
QTEST_GUILESS_MAIN(TQTcpServerTest);
#else
#undef QT_GUI_LIB
QTEST_MAIN(TQTcpServerTest);
#endif
#include "TQTcpServerTest.moc"

Please put it to #ifdef below as reordering seems OK here.


@@ -4,11 +4,13 @@
 #   This file is distributed under the University of Illinois Open Source
 #   License. See LICENSE.TXT for details.
 # -----------------------------------------------------------------------------
+from time import sleep

 """Setup for the test package comment."""

 from subprocess import CalledProcessError

+import json
 import multiprocessing
 import os
 import shutil

# coding=utf-8
# -----------------------------------------------------------------------------
#                     The CodeChecker Infrastructure
#   This file is distributed under the University of Illinois Open Source
#   License. See LICENSE.TXT for details.
# -----------------------------------------------------------------------------

"""Setup for the test package comment."""

from subprocess import CalledProcessError

import multiprocessing
import os
import shutil
import subprocess
import sys
import time
import uuid

from libtest import codechecker
from libtest import env
from libtest import project

# Stopping event for CodeChecker server.
__STOP_SERVER = multiprocessing.Event()

# Test workspace should be initialized in this module.
TEST_WORKSPACE = None

def setup_package():
    """Setup the environment for the tests. """

    global TEST_WORKSPACE
    TEST_WORKSPACE = env.get_workspace('comment')

    os.environ['TEST_WORKSPACE'] = TEST_WORKSPACE

    test_project = 'cpp'

    test_project_path = project.path(test_project)

    pg_db_config = env.get_postgresql_cfg()

    test_config = {}

    project_info = project.get_info(test_project)

    test_config['test_project'] = project_info

    suppress_file = None

    skip_list_file = None

    # Setup environment variabled for test cases.
    host_port_cfg = env.get_host_port_cfg()

    test_env = env.test_env()

    codechecker_cfg = {
        'suppress_file': suppress_file,
        'skip_list_file': skip_list_file,
        'check_env': test_env,
        'workspace': TEST_WORKSPACE,
        'reportdir': os.path.join(TEST_WORKSPACE, 'reports'),
        'pg_db_config': pg_db_config,
        'checkers': ['-d', 'core.CallAndMessage',
                     '-e', 'core.StackAddressEscape']
    }

    codechecker_cfg.update(host_port_cfg)

    test_config['codechecker_cfg'] = codechecker_cfg

    ret = project.clean(test_project, test_env)
    if ret:
        sys.exit(ret)

    # Start the CodeChecker server.
    print("Starting server to get results")
    _start_server(codechecker_cfg, test_config, False)

    # Check the test project for the first time.
    test_project_name = project_info['name'] + '_' + uuid.uuid4().hex

    ret = codechecker.check(codechecker_cfg,
                            test_project_name,
                            test_project_path)
    if ret:
        sys.exit(1)
    print("Analyzing test project was succcessful.")

    # Check the test project again.
    test_project_name = project_info['name'] + '_' + uuid.uuid4().hex

    ret = codechecker.check(codechecker_cfg,
                            test_project_name,
                            test_project_path)
    if ret:
        sys.exit(1)
    print("Analyzing test project was succcessful.")

    if pg_db_config:
        print("Waiting for PotgreSQL to stop.")
        codechecker.wait_for_postgres_shutdown(TEST_WORKSPACE)

    codechecker_cfg['run_names'] = [test_project_name]

    test_config['codechecker_cfg'] = codechecker_cfg

    env.export_test_cfg(TEST_WORKSPACE, test_config)

def teardown_package():
    """Stop the CodeChecker server."""
    __STOP_SERVER.set()

    # TODO: If environment variable is set keep the workspace
    # and print out the path.
    global TEST_WORKSPACE

    print("Removing: " + TEST_WORKSPACE)
    shutil.rmtree(TEST_WORKSPACE)

def _start_server(codechecker_cfg, test_config, auth=False):
    """Start the CodeChecker server."""

    def start_server_proc(event, server_cmd, checking_env):
        """Target function for starting the CodeChecker server."""

        proc = subprocess.Popen(server_cmd, env=checking_env)

        # Blocking termination until event is set.
        event.wait()

        # If proc is still running, stop it.
        if proc.poll() is None:
            proc.terminate()

    server_cmd = codechecker.serv_cmd(codechecker_cfg, test_config)

    server_proc = multiprocessing.Process(
        name='server',
        target=start_server_proc,
        args=(__STOP_SERVER, server_cmd, codechecker_cfg['check_env']))

    server_proc.start()

    # Wait for server to start and connect to database.
    time.sleep(20)


@@ -38,6 +38,8 @@
 #include <flux/core.h>
 #include "heaptrace.h"

+static flux_msg_handler_t **handlers = NULL;
+
 static void start_cb (flux_t *h, flux_msg_handler_t *mh,
                       const flux_msg_t *msg, void *arg)
 {

/*****************************************************************************\
 *  Copyright (c) 2014 Lawrence Livermore National Security, LLC.  Produced at
 *  the Lawrence Livermore National Laboratory (cf, AUTHORS, DISCLAIMER.LLNS).
 *  LLNL-CODE-658032 All rights reserved.
 *
 *  This file is part of the Flux resource manager framework.
 *  For details, see https://github.com/flux-framework.
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the license, or (at your option)
 *  any later version.
 *
 *  Flux is distributed in the hope that it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the terms and conditions of the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *  See also:  http://www.gnu.org/licenses/
\*****************************************************************************/

#if HAVE_CONFIG_H
#include "config.h"
#endif
#if WITH_TCMALLOC
#if HAVE_GPERFTOOLS_HEAP_PROFILER_H
  #include <gperftools/heap-profiler.h>
#elif HAVE_GOOGLE_HEAP_PROFILER_H
  #include <google/heap-profiler.h>
#else
  #error gperftools headers not configured
#endif
#endif /* WITH_TCMALLOC */

#include <flux/core.h>
#include "heaptrace.h"

static void start_cb (flux_t *h, flux_msg_handler_t *mh,
                      const flux_msg_t *msg, void *arg)
{
    const char *filename;

    if (flux_request_unpack (msg, NULL, "{s:s}", "filename", &filename) < 0)
        goto error;
#if WITH_TCMALLOC
    if (IsHeapProfilerRunning ()) {
        errno = EINVAL;
        goto error;
    }
    HeapProfilerStart (filename);
#else
    errno = ENOSYS;
    goto error;
#endif
    if (flux_respond (h, msg, 0, NULL) < 0)
        FLUX_LOG_ERROR (h);
    return;
error:
    if (flux_respond (h, msg, errno, NULL) < 0)
        FLUX_LOG_ERROR (h);
}

static void dump_cb (flux_t *h, flux_msg_handler_t *mh,
                     const flux_msg_t *msg, void *arg)
{
    const char *reason;

    if (flux_request_unpack (msg, NULL, "{s:s}", "reason", &reason) < 0)
        goto error;
#if WITH_TCMALLOC
    if (!IsHeapProfilerRunning ()) {
        errno = EINVAL;
        goto error;
    }
    HeapProfilerDump (reason);
#else
    errno = ENOSYS;
    goto error;
#endif
    if (flux_respond (h, msg, 0, NULL) < 0)
        FLUX_LOG_ERROR (h);
    return;
error:
    if (flux_respond (h, msg, errno, NULL) < 0)
        FLUX_LOG_ERROR (h);
}

static void stop_cb (flux_t *h, flux_msg_handler_t *mh,
                     const flux_msg_t *msg, void *arg)
{
    if (flux_request_decode (msg, NULL, NULL) < 0)
        goto error;
#if WITH_TCMALLOC
    if (!IsHeapProfilerRunning ()) {
        errno = EINVAL;
        goto error;
    }
    HeapProfilerStop();
#else
    errno = ENOSYS;
    goto error;
#endif /* WITH_TCMALLOC */
    if (flux_respond (h, msg, 0, NULL) < 0)
        FLUX_LOG_ERROR (h);
    return;
error:
    if (flux_respond (h, msg, errno, NULL) < 0)
        FLUX_LOG_ERROR (h);
}

static struct flux_msg_handler_spec handlers[] = {
    { FLUX_MSGTYPE_REQUEST, "heaptrace.start",  start_cb, 0, NULL },
    { FLUX_MSGTYPE_REQUEST, "heaptrace.dump",   dump_cb, 0, NULL },
    { FLUX_MSGTYPE_REQUEST, "heaptrace.stop",   stop_cb, 0, NULL },
    FLUX_MSGHANDLER_TABLE_END,
};

static void heaptrace_finalize (void *arg)
{
    flux_msg_handler_delvec (handlers);
}

int heaptrace_initialize (flux_t *h)
{
    char *dummy = "hello";
    if (flux_msg_handler_addvec (h, handlers, NULL) < 0)
        return -1;
    flux_aux_set (h, "flux::heaptrace", dummy, heaptrace_finalize);
    return 0;
}

/*
 * vi:tabstop=4 shiftwidth=4 expandtab
 */

In C, file scope variables are already initialized to 0 so the "= NULL" is redundant. Not a big deal.


@@ -47,7 +47,7 @@ bool legacy_crtc_set_cursor(struct wlr_drm_backend *drm,

 	if (drmModeSetCursor(drm->fd, crtc->id, gbm_bo_get_handle(bo).u32,
 			plane->surf.width, plane->surf.height)) {
-		wlr_log_errno(L_ERROR, "Failed to set hardware cursor");
+		wlr_log_errno(L_DEBUG, "Failed to set hardware cursor");
 		return false;
 	}

#include <gbm.h>
#include <wlr/util/log.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include "backend/drm/drm.h"
#include "backend/drm/iface.h"
#include "backend/drm/util.h"

static bool legacy_crtc_pageflip(struct wlr_drm_backend *drm,
		struct wlr_drm_connector *conn, struct wlr_drm_crtc *crtc,
		uint32_t fb_id, drmModeModeInfo *mode) {
	if (mode) {
		if (drmModeSetCrtc(drm->fd, crtc->id, fb_id, 0, 0,
				&conn->id, 1, mode)) {
			wlr_log_errno(L_ERROR, "%s: Failed to set CRTC", conn->output.name);
			return false;
		}
	}

	if (drmModePageFlip(drm->fd, crtc->id, fb_id, DRM_MODE_PAGE_FLIP_EVENT, conn)) {
		wlr_log_errno(L_ERROR, "%s: Failed to page flip", conn->output.name);
		return false;
	}

	return true;
}

static bool legacy_conn_enable(struct wlr_drm_backend *drm,
		struct wlr_drm_connector *conn, bool enable) {
	int ret = drmModeConnectorSetProperty(drm->fd, conn->id, conn->props.dpms,
		enable ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF);
	return ret >= 0;
}

bool legacy_crtc_set_cursor(struct wlr_drm_backend *drm,
		struct wlr_drm_crtc *crtc, struct gbm_bo *bo) {
	if (!crtc || !crtc->cursor) {
		return true;
	}

	if (!bo) {
		drmModeSetCursor(drm->fd, crtc->id, 0, 0, 0);
		return true;
	}

	struct wlr_drm_plane *plane = crtc->cursor;

	if (drmModeSetCursor(drm->fd, crtc->id, gbm_bo_get_handle(bo).u32,
			plane->surf.width, plane->surf.height)) {
		wlr_log_errno(L_ERROR, "Failed to set hardware cursor");
		return false;
	}

	return true;
}

bool legacy_crtc_move_cursor(struct wlr_drm_backend *drm,
		struct wlr_drm_crtc *crtc, int x, int y) {
	return !drmModeMoveCursor(drm->fd, crtc->id, x, y);
}

bool legacy_crtc_set_gamma(struct wlr_drm_backend *drm,
		struct wlr_drm_crtc *crtc, uint16_t *r, uint16_t *g, uint16_t *b,
		uint32_t size) {
	return !drmModeCrtcSetGamma(drm->fd, crtc->id, size, r, g, b);
}

uint32_t legacy_crtc_get_gamma_size(struct wlr_drm_backend *drm,
		struct wlr_drm_crtc *crtc) {
	return crtc->legacy_crtc->gamma_size;
}

const struct wlr_drm_interface legacy_iface = {
	.conn_enable = legacy_conn_enable,
	.crtc_pageflip = legacy_crtc_pageflip,
	.crtc_set_cursor = legacy_crtc_set_cursor,
	.crtc_move_cursor = legacy_crtc_move_cursor,
	.crtc_set_gamma = legacy_crtc_set_gamma,
	.crtc_get_gamma_size = legacy_crtc_get_gamma_size,
};


@@ -54,6 +54,26 @@ var _ = Describe("NAT", func() {
 			},
 		}))
 	})
+	It("should render rules when active with explicit port range", func() {
+
+		//copy struct
+		localConfig := rrConfigNormal
+		localConfig.IptablesNATOutgoingInterfaceFilter = "cali-123"
+		renderer = NewRenderer(localConfig)
+
+		Expect(renderer.NATOutgoingChain(true, 4)).To(Equal(&Chain{
+			Name: "cali-nat-outgoing",
+			Rules: []Rule{
+				{
+					Action: MasqAction{},
+					Match: Match().
+						SourceIPSet("cali4-masq-ipam-pools").
+						NotDestIPSet("cali4-all-ipam-pools").
+						OutInterface("cali-123"),
+				},
+			},
+		}))
+	})
 	It("should render nothing when inactive", func() {
 		Expect(renderer.NATOutgoingChain(false, 4)).To(Equal(&Chain{
 			Name:  "cali-nat-outgoing",

// Copyright (c) 2017 Tigera, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package rules_test

import (
	. "github.com/projectcalico/felix/rules"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/projectcalico/felix/ipsets"
	. "github.com/projectcalico/felix/iptables"
)

var _ = Describe("NAT", func() {
	var rrConfigNormal = Config{
		IPIPEnabled:          true,
		IPIPTunnelAddress:    nil,
		IPSetConfigV4:        ipsets.NewIPVersionConfig(ipsets.IPFamilyV4, "cali", nil, nil),
		IPSetConfigV6:        ipsets.NewIPVersionConfig(ipsets.IPFamilyV6, "cali", nil, nil),
		IptablesMarkAccept:   0x8,
		IptablesMarkPass:     0x10,
		IptablesMarkScratch0: 0x20,
		IptablesMarkScratch1: 0x40,
	}

	var renderer RuleRenderer
	BeforeEach(func() {
		renderer = NewRenderer(rrConfigNormal)
	})

	It("should render rules when active", func() {
		Expect(renderer.NATOutgoingChain(true, 4)).To(Equal(&Chain{
			Name: "cali-nat-outgoing",
			Rules: []Rule{
				{
					Action: MasqAction{},
					Match: Match().
						SourceIPSet("cali4-masq-ipam-pools").
						NotDestIPSet("cali4-all-ipam-pools"),
				},
			},
		}))
	})
	It("should render nothing when inactive", func() {
		Expect(renderer.NATOutgoingChain(false, 4)).To(Equal(&Chain{
			Name:  "cali-nat-outgoing",
			Rules: nil,
		}))
	})
})

Name of test case is incorrect after backport (we don't have port ranges in v3.0)