Skip to content

Instantly share code, notes, and snippets.

@1ace
Created October 4, 2018 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 1ace/95f4cb32b0172ce10cc531fb40b94cc7 to your computer and use it in GitHub Desktop.
Save 1ace/95f4cb32b0172ce10cc531fb40b94cc7 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
set -eu -o pipefail
declare -r drm_fourcc_h=/usr/include/libdrm/drm_fourcc.h
declare -r prog="${BASH_SOURCE[0]}".out
update() {
fourcc_h=$(perl -pe 's/\\\n//' < "$drm_fourcc_h")
fourcc_code=($(echo "$fourcc_h" | grep -E '#define\s+\w+\s+fourcc_code' | awk '{print $2}'))
fourcc_mod_code=($(echo "$fourcc_h" | grep -E '#define\s+\w+\s+fourcc_mod_code' | awk '{print $2}'))
c=$(mktemp --suffix=.c)
cat >> "$c" <<'EOF'
#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <drm_fourcc.h>
EOF
cat >> "$c" <<'EOF'
static void
drm_print(const char* const name, const uint64_t value)
{
printf("%s = %lu (%#lx)\n", name, value, value);
}
EOF
cat >> "$c" <<'EOF'
static bool
number_from_name(const char * const name)
{
#define CASE(x) \
if (strcmp(#x, name) == 0) \
{ \
drm_print(name, x); \
return true; \
}
EOF
printf ' CASE(%s);\n' >> "$c" "${fourcc_code[@]}"
printf ' CASE(%s);\n' >> "$c" "${fourcc_mod_code[@]}"
cat >> "$c" <<'EOF'
#undef CASE
return false;
}
EOF
cat >> "$c" <<'EOF'
static bool
format_name_from_number(const uint32_t number)
{
bool found = false;
#define CASE(x) do { \
if (number == x) { \
drm_print(#x, x); \
found = true; \
} \
} while(0)
EOF
printf ' CASE(%s);\n' >> "$c" "${fourcc_code[@]}"
cat >> "$c" <<'EOF'
#undef CASE
return found;
}
EOF
cat >> "$c" <<'EOF'
static bool
modifier_name_from_number(const uint64_t number)
{
bool found = false;
#define CASE(x) do { \
if (number == x) { \
drm_print(#x, x); \
found = true; \
} \
} while(0)
EOF
printf ' CASE(%s);\n' >> "$c" "${fourcc_mod_code[@]}"
cat >> "$c" <<'EOF'
#undef CASE
return found;
}
EOF
cat >> "$c" <<'EOF'
static void
list_all_names()
{
#define CASE(x) do { \
printf("- "); \
drm_print(#x, x); \
} while(0)
EOF
printf ' printf("Known DRM formats:\\n");\n' >> "$c"
printf ' CASE(%s);\n' >> "$c" "${fourcc_code[@]}"
printf ' printf("\\n");\n' >> "$c"
printf ' printf("Known DRM modifiers:\\n");\n' >> "$c"
printf ' CASE(%s);\n' >> "$c" "${fourcc_mod_code[@]}"
cat >> "$c" <<'EOF'
#undef CASE
}
EOF
cat >> "$c" <<'EOF'
int main(int argc, char* argv[])
{
if (argc < 2) {
list_all_names();
return 0;
}
for (int i = 1; i < argc; i++)
{
if (isdigit(argv[i][0]))
{
errno = 0;
char *end;
uint64_t number = strtoull(argv[i], &end, 0);
if (errno != 0 || end == argv[i] || *end != '\0') {
printf("unreadable number: %s\n", argv[i]);
continue;
}
if (!format_name_from_number(number) &&
!modifier_name_from_number(number))
printf("unknown number: %s\n", argv[i]);
}
else
{
if (!number_from_name(argv[i]))
printf("unknown name: %s\n", argv[i]);
}
}
return 0;
}
EOF
cc $(pkg-config --cflags --libs libdrm) -o "$prog" "$c" -Wall -Wextra || {
cat "$c"
rm "$c"
exit 1
}
rm "$c"
}
if [ ! -f "$prog" ] ||
[ $(stat -c %Y "$prog") -lt $(stat -c %Y "$drm_fourcc_h") ] ||
[ $(stat -c %Y "$prog") -lt $(stat -c %Y "${BASH_SOURCE[0]}") ]
then
update
fi
exec "$prog" "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment