mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-26 18:58:13 +02:00
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>
211 lines
4.1 KiB
C
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);
|
|
}
|