Control: tags -1 + patch
memcpy(0x7ffeae63e888, ".", 1)
= 0x7ffeae63e888
inotify_add_watch(3, ".",
IN_MOVED_TO|IN_CREATE|IN_DELETE_SELF|IN_MOVE_SELF|IN_ONLYDIR|IN_EXCL_UNLINK)
= 1
reallocarray(nil, 2, 8)
= 0x55fb0d39a2e0
From 6e26699817640d09fd0c493f5722dd9057212400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= <[email protected]> Date: Thu, 31 Jul 2025 21:27:08 +0200 Subject: [PATCH] Add typedef = bitenum() (Closes: #1110138) X-Mutt-PGP: OS
---
Makefile.am | 2 +-
lens_bitenum.c | 145 +++++++++++++++++++++++++++++++++++++++++++++
lens_bitenum.h | 47 +++++++++++++++
read_config_file.c | 118 ++++++++++++++++++++++++++++++++++++
4 files changed, 311 insertions(+), 1 deletion(-)
create mode 100644 lens_bitenum.c
create mode 100644 lens_bitenum.h
diff --git a/Makefile.am b/Makefile.am
index 394d91c..df408bb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -33,7 +33,7 @@ libltrace_la_SOURCES = bits.c breakpoints.c debug.c demangle.c dict.c \
options.c output.c proc.c read_config_file.c summary.c \
library.c filter.c glob.c type.c value.c value_dict.c expr.c \
fetch.c vect.c param.c printf.c zero.c lens.c lens_default.c \
- lens_enum.c memstream.c prototype.c
+ lens_enum.c lens_bitenum.c memstream.c prototype.c
if HAVE_LIBDW
libltrace_la_SOURCES += dwarf_prototypes.c
endif
diff --git a/lens_bitenum.c b/lens_bitenum.c
new file mode 100644
index 0000000..42a7581
--- /dev/null
+++ b/lens_bitenum.c
@@ -0,0 +1,145 @@
+/*
+ * This file is part of ltrace.
+ * Copyright (C) 2011, 2012 Petr Machata, Red Hat Inc.
+ *
+ * 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.
+ *
+ * This program 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
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include "lens_bitenum.h"
+#include "lens_default.h"
+#include "value.h"
+#include "type.h"
+
+struct bitenum_entry {
+ char *key;
+ uint64_t value;
+ bool own_key : 1;
+};
+static_assert(sizeof(uint64_t) == sizeof(long long), "");
+
+static void
+bitenum_entry_dtor(struct bitenum_entry *entry, void *data)
+{
+ if (entry->own_key)
+ free(entry->key);
+}
+
+static void
+bitenum_lens_destroy_cb(struct lens *lens)
+{
+ struct bitenum_lens *self = (void *)lens;
+
+ VECT_DESTROY(&self->entries, struct bitenum_entry,
+ bitenum_entry_dtor, NULL);
+}
+
+struct consumestate {
+ uint64_t bits;
+ FILE *stream;
+ int wrote;
+};
+
+static enum callback_status
+bitenum_consume(const struct bitenum_entry *entry, void *data)
+{
+ struct consumestate *consumestate = data;
+
+ if ((consumestate->bits & entry->value) != entry->value)
+ return CBS_CONT;
+
+ if (consumestate->wrote) {
+ fputc('|', consumestate->stream);
+ ++consumestate->wrote;
+ }
+
+ fputs(entry->key, consumestate->stream);
+ consumestate->wrote += strlen(entry->key);
+ consumestate->bits &= ~entry->value;
+
+ return CBS_CONT_IF(consumestate->bits);
+}
+
+static int
+bitenum_lens_format_cb(struct lens *lens, FILE *stream,
+ struct value *value, struct value_dict *arguments)
+{
+ struct bitenum_lens *self = (void *)lens;
+
+ struct consumestate consumestate = { .stream = stream };
+ if (value_extract_word(value, (long long *)&consumestate.bits, NULL))
+ none:
+ return lens_format(&default_lens, stream, value, arguments);
+
+ VECT_EACH_CST(&self->entries, struct bitenum_entry, NULL, bitenum_consume, &consumestate);
+
+ if (!consumestate.wrote)
+ goto none;
+ if (!consumestate.bits)
+ return consumestate.wrote;
+
+ fputc('|', stream);
+ ++consumestate.wrote;
+
+ struct value remainder;
+ value_init_detached(&remainder, NULL, value->type, false);
+ value_set_word(&remainder, consumestate.bits);
+ return consumestate.wrote + lens_format(&default_lens, stream, &remainder, arguments);
+}
+
+// Most-populated values first
+static int
+bitenum_lens_sort(const struct bitenum_entry *lhs,
+ const struct bitenum_entry *rhs)
+{
+ return __builtin_popcount(rhs->value) - __builtin_popcount(lhs->value);
+}
+
+
+void
+lens_init_bitenum(struct bitenum_lens *lens)
+{
+ *lens = (struct bitenum_lens){
+ {
+ .format_cb = bitenum_lens_format_cb,
+ .destroy_cb = bitenum_lens_destroy_cb,
+ },
+ };
+ VECT_INIT(&lens->entries, struct bitenum_entry);
+}
+
+int
+lens_bitenum_add(struct bitenum_lens *lens,
+ const char *key, int own_key,
+ uint64_t value)
+{
+ struct bitenum_entry entry = { (char *)key, value, own_key };
+ if (VECT_PUSHBACK(&lens->entries, &entry))
+ return -1;
+ // TODO: this would be better-served as an insert-at-lower_bound(), but vect doesn't have this
+ VECT_QSORT(&lens->entries, struct bitenum_entry, bitenum_lens_sort);
+ return 0;
+}
+
+size_t
+lens_bitenum_size(struct bitenum_lens *lens)
+{
+ return vect_size(&lens->entries);
+}
diff --git a/lens_bitenum.h b/lens_bitenum.h
new file mode 100644
index 0000000..70eb92a
--- /dev/null
+++ b/lens_bitenum.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of ltrace.
+ * Copyright (C) 2011, 2012 Petr Machata, Red Hat Inc.
+ *
+ * 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.
+ *
+ * This program 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
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef LENS_BITENUM_H
+#define LENS_BITENUM_H
+
+#include <stdint.h>
+#include "lens.h"
+#include "vect.h"
+
+struct bitenum_lens {
+ struct lens super;
+ struct vect entries;
+};
+
+/* Init enumeration LENS. */
+void lens_init_bitenum(struct bitenum_lens *lens);
+
+/* Push another member of the enumeration, named KEY, with given
+ * VALUE. If OWN_KEY, KEY is owned and released after the type is
+ * destroyed. KEY is typed as const char *, but note that if OWN_KEY,
+ * this value will be freed. */
+int lens_bitenum_add(struct bitenum_lens *lens,
+ const char *key, int own_key,
+ uint64_t value);
+
+/* Return number of enum elements of type INFO. */
+size_t lens_bitenum_size(struct bitenum_lens *lens);
+
+#endif /* LENS_BITENUM_H */
diff --git a/read_config_file.c b/read_config_file.c
index 9e1f65c..3f35ae4 100644
--- a/read_config_file.c
+++ b/read_config_file.c
@@ -42,6 +42,7 @@
#include "lens.h"
#include "lens_default.h"
#include "lens_enum.h"
+#include "lens_bitenum.h"
/* Lifted from GCC: The ctype functions are often implemented as
* macros which do lookups in arrays using the parameter as the
@@ -80,6 +81,8 @@ static struct arg_type_info *parse_lens(struct protolib *plib,
bool *forwardp);
static int parse_enum(struct protolib *plib, struct locus *loc,
char **str, struct arg_type_info **retp, bool *ownp);
+static int parse_bitenum(struct protolib *plib, struct locus *loc,
+ char **str, struct arg_type_info **retp, bool *ownp);
static int try_parse_kwd(char **str, const char *kwd);
@@ -168,6 +171,22 @@ parse_int(struct locus *loc, char **str, long *ret)
return 0;
}
+static int
+parse_u64(struct locus *loc, char **str, uint64_t *ret)
+{
+ char *end;
+ unsigned long long n = strtoull(*str, &end, 0);
+ if (end == *str) {
+ report_error(loc->filename, loc->line_no, "bad number");
+ return -1;
+ }
+
+ *str = end;
+ if (ret != NULL)
+ *ret = n;
+ return 0;
+}
+
static int
check_nonnegative(struct locus *loc, long l)
{
@@ -717,6 +736,10 @@ parse_alias(struct protolib *plib, struct locus *loc,
return parse_enum(plib, loc, str, retp, ownp);
+ } else if (try_parse_kwd(str, "bitenum") >= 0) {
+
+ return parse_bitenum(plib, loc, str, retp, ownp);
+
} else {
*retp = NULL;
return 0;
@@ -862,6 +885,101 @@ parse_enum(struct protolib *plib, struct locus *loc, char **str,
return 0;
}
+/* Syntax:
+ * bitenum (keyname=value,keyname=value,... )
+ * bitenum<type> (keyname=value,keyname=value,... )
+ */
+static int
+parse_bitenum(struct protolib *plib, struct locus *loc, char **str,
+ struct arg_type_info **retp, bool *ownp)
+{
+ /* Optional type argument. */
+ skip_whitespace(str);
+ if (**str == '[') {
+ parse_char(loc, str, '[');
+ skip_whitespace(str);
+ *retp = parse_nonpointer_type(plib, loc, str, NULL, 0, ownp, NULL);
+ if (*retp == NULL)
+ return -1;
+
+ if (!type_is_integral((*retp)->type)) {
+ report_error(loc->filename, loc->line_no,
+ "integral type required as bitenum argument");
+ fail:
+ if (*ownp) {
+ /* This also releases associated lens
+ * if any was set so far. */
+ type_destroy(*retp);
+ free(*retp);
+ }
+ return -1;
+ }
+
+ skip_whitespace(str);
+ if (parse_char(loc, str, ']') < 0)
+ goto fail;
+
+ } else {
+ *retp = type_get_simple(ARGTYPE_INT);
+ *ownp = false;
+ }
+
+ /* We'll need to set the lens, so unshare. */
+ if (unshare_type_info(loc, retp, ownp) < 0)
+ goto fail;
+
+ skip_whitespace(str);
+ if (parse_char(loc, str, '(') < 0)
+ goto fail;
+
+ struct bitenum_lens *lens = malloc(sizeof(*lens));
+ if (lens == NULL) {
+ report_error(loc->filename, loc->line_no,
+ "malloc enum lens: %s", strerror(errno));
+ return -1;
+ }
+
+ lens_init_bitenum(lens);
+ (*retp)->lens = &lens->super;
+ (*retp)->own_lens = 1;
+
+ while (1) {
+ skip_whitespace(str);
+ if (**str == 0 || **str == ')') {
+ parse_char(loc, str, ')');
+ return 0;
+ }
+
+ /* Field delimiter. XXX should we support the C
+ * syntax, where the enumeration can end in pending
+ * comma? */
+ if (lens_bitenum_size(lens) > 0)
+ parse_char(loc, str, ',');
+
+ skip_whitespace(str);
+ char *key = parse_ident(loc, str);
+ if (key == NULL) {
+ err:
+ free(key);
+ goto fail;
+ }
+
+ if (**str != '=')
+ goto err;
+ ++*str;
+ skip_whitespace(str);
+
+ uint64_t val;
+ if (parse_u64(loc, str, &val) < 0)
+ goto err;
+
+ if (lens_bitenum_add(lens, key, 1, val) < 0)
+ goto err;
+ }
+
+ return 0;
+}
+
static struct arg_type_info *
parse_nonpointer_type(struct protolib *plib, struct locus *loc,
char **str, struct param **extra_param, size_t param_num,
--
2.39.5
signature.asc
Description: PGP signature

