Created
October 4, 2018 14:15
-
-
Save 1ace/95f4cb32b0172ce10cc531fb40b94cc7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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