aboutsummaryrefslogtreecommitdiff
path: root/glgen.sh
blob: 75d93c3b4341468e3e8cd7bfb119d060eaf55327 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/bin/sh

# Generates a simple GL/EGL extension function loader.
#
# The input is a .txt file, with each function to load on its own line.
# If a line starts with a -, it is optional, and will not cause the loader
# to fail if it can't load the function. You'll need to check if that function
# is NULL before using it.

if [ $# -ne 2 ]; then
	exit 1
fi

SPEC=$1
OUT=$2

BASE=$(basename "$SPEC" .txt)
INCLUDE_GUARD=$(printf %s "$SPEC" | tr -c [:alnum:] _ | tr [:lower:] [:upper:])

DECL=""
DEFN=""
LOADER=""

DECL_FMT='extern %s %s;'
DEFN_FMT='%s %s;'
LOADER_FMT='%s = (%s)eglGetProcAddress("%s");'
CHECK_FMT='if (!%s) {
	wlr_log(L_ERROR, "Unable to load %s");
	return false;
}'

while read -r COMMAND; do
	OPTIONAL=0
	FUNC_PTR_FMT='PFN%sPROC'

	case $COMMAND in
	-*)
		OPTIONAL=1
		;;
	esac

	case $COMMAND in
	*WL)
		FUNC_PTR_FMT='PFN%s'
		;;
	esac

	COMMAND=${COMMAND#-}
	FUNC_PTR=$(printf "$FUNC_PTR_FMT" "$COMMAND" | tr [:lower:] [:upper:])

	DECL="$DECL$(printf "\n$DECL_FMT" "$FUNC_PTR" "$COMMAND")"
	DEFN="$DEFN$(printf "\n$DEFN_FMT" "$FUNC_PTR" "$COMMAND")"
	LOADER="$LOADER$(printf "\n$LOADER_FMT" "$COMMAND" "$FUNC_PTR" "$COMMAND")"

	if [ $OPTIONAL -eq 0 ]; then
		LOADER="$LOADER$(printf "\n$CHECK_FMT" "$COMMAND" "$COMMAND")"
	fi
done < $SPEC


case $OUT in
*.h)
	cat > $OUT << EOF
	#ifndef $INCLUDE_GUARD
	#define $INCLUDE_GUARD

	#include <stdbool.h>

	#include <EGL/egl.h>
	#include <EGL/eglext.h>
	#include <EGL/eglmesaext.h>
	#include <GLES2/gl2.h>
	#include <GLES2/gl2ext.h>

	bool load_$BASE(void);
	$DECL

	#endif
EOF
	;;
*.c)
	cat > $OUT << EOF
	#include <wlr/util/log.h>
	#include "$BASE.h"
	$DEFN

	bool load_$BASE(void) {
		static bool done = false;
		if (done) {
			return true;
		}
	$LOADER

		done = true;
		return true;
	}
EOF
	;;
*)
	exit 1
	;;
esac