mesa/src/intel/mda/slice.c
Mauro Rossi 7b50b8966b intel/mda: Fix gnu-empty-initializer warning
This also causes build errors on older Android prebuilt clang.

Fixes: bccc0fa9 ("intel/mda: Add code to produce mesa debug archives")
Reviewed-by: Caio Oliveira <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37586>
2025-09-26 08:30:16 +00:00

211 lines
4.1 KiB
C

/*
* Copyright 2025 Intel Corporation
* SPDX-License-Identifier: MIT
*/
#include <stdio.h>
#include <string.h>
#include "util/ralloc.h"
#include "util/hash_table.h"
#include "slice.h"
slice
slice_from_cstr(const char *str)
{
return (slice){ str, str ? strlen(str) : 0 };
}
bool
slice_is_empty(slice s)
{
return s.len == 0;
}
bool
slice_equal(slice a, slice b)
{
return a.len == b.len && (a.len == 0 || memcmp(a.data, b.data, a.len) == 0);
}
bool
slice_equal_cstr(slice s, const char *cstr)
{
slice cstr_slice = slice_from_cstr(cstr);
return slice_equal(s, cstr_slice);
}
char *
slice_to_cstr(void *mem_ctx, slice s)
{
char *str = ralloc_size(mem_ctx, s.len + 1);
memcpy(str, s.data, s.len);
str[s.len] = '\0';
return str;
}
slice
slice_find_char(slice s, char c)
{
for (int i = 0; i < s.len; i++) {
if (s.data[i] == c) {
return slice_substr_from(s, i);
}
}
return (slice){0};
}
slice
slice_find_str(slice s, slice needle)
{
if (needle.len == 0)
return s;
if (needle.len > s.len)
return (slice){0};
for (int i = 0; i <= s.len - needle.len; i++) {
if (memcmp(s.data + i, needle.data, needle.len) == 0) {
return slice_substr_from(s, i);
}
}
return (slice){0};
}
bool
slice_contains_str(slice s, slice needle)
{
return !slice_is_empty(slice_find_str(s, needle));
}
bool
slice_starts_with(slice s, slice prefix)
{
if (prefix.len > s.len)
return false;
return memcmp(s.data, prefix.data, prefix.len) == 0;
}
bool
slice_ends_with(slice s, slice suffix)
{
if (suffix.len > s.len)
return false;
return memcmp(s.data + s.len - suffix.len, suffix.data, suffix.len) == 0;
}
slice
slice_strip_prefix(slice s, slice prefix)
{
if (slice_starts_with(s, prefix))
return slice_substr_from(s, prefix.len);
return s;
}
slice
slice_substr_from(slice s, int start)
{
if (start < 0)
start = 0;
if (start >= s.len)
return (slice){0};
return (slice){.data = s.data + start, .len = s.len - start};
}
slice
slice_substr_to(slice s, int end)
{
if (end < 0)
end = 0;
if (end > s.len)
end = s.len;
return (slice){.data = s.data, .len = end};
}
slice
slice_substr(slice s, int start, int end)
{
if (start < 0)
start = 0;
if (end > s.len)
end = s.len;
if (start >= end)
return (slice){0};
return (slice){.data = s.data + start, .len = end - start};
}
slice_cut_result
slice_cut(slice s, char c)
{
return slice_cut_n(s, c, 1);
}
slice_cut_result
slice_cut_n(slice s, char c, int n)
{
if (n <= 0) {
slice_cut_result result = { .before = s, .after = {0}, .found = false };
return result;
}
slice current = s;
int count = 0;
while (!slice_is_empty(current)) {
slice found = slice_find_char(current, c);
if (slice_is_empty(found))
break;
count++;
if (count == n) {
int pos = found.data - s.data;
slice_cut_result result = {
.before = slice_substr_to(s, pos),
.after = slice_substr_from(s, pos + 1),
.found = true
};
return result;
}
/* Move past this occurrence. */
current = slice_substr_from(found, 1);
}
/* Not enough occurrences found. */
slice_cut_result result = { .before = s, .after = {0}, .found = false };
return result;
}
static uint32_t
slice_ptr_hash(const void *key)
{
const slice *s = (const slice *)key;
return _mesa_hash_string_with_length(s->data, s->len);
}
static bool
slice_ptr_equal(const void *a, const void *b)
{
const slice *sa = (const slice *)a;
const slice *sb = (const slice *)b;
return slice_equal(*sa, *sb);
}
struct hash_table *
slice_hash_table_create(void *mem_ctx)
{
return _mesa_hash_table_create(mem_ctx, slice_ptr_hash, slice_ptr_equal);
}
struct hash_entry *
slice_hash_table_insert(struct hash_table *ht, slice key, void *data)
{
/* Create a new slice that will be stable in memory, so its pointer can
* be used as key.
*/
slice *key_copy = rzalloc(ht, slice);
*key_copy = key;
return _mesa_hash_table_insert(ht, key_copy, data);
}