detected unmatched #if/#else/#endif
[xonotic/xonotic-maps.pk3dir.git] / scripts / shader-cpp.sh
1 #!/bin/sh
2
3 case "$0" in
4         */*)
5                 cd "${0%/*}"
6                 ;;
7 esac
8
9 . ./shader-parser.subr
10 set -e
11
12 err()
13 {
14         echo >&2 "(EE) $*"
15         exit 1
16 }
17
18 LF="
19 "
20 TAB="   "
21
22 parse_shader_pre()
23 {
24         shadertext=
25         shaderconds=
26 }
27 parse_conditional()
28 {
29         shaderconds="$shaderconds$LF$*"
30 }
31 parse_shader_line()
32 {
33         case "$1" in
34                 '#if')
35                         parse_conditional $2 $3
36                         ;;
37         esac
38         shadertext="$shadertext$LF$TAB$*"
39 }
40 parse_shaderstage_pre()
41 {
42         shadertext="$shadertext$LF$TAB{"
43 }
44 parse_shaderstage_line()
45 {
46         case "$1" in
47                 '#if')
48                         parse_conditional $2 $3
49                         ;;
50         esac
51         shadertext="$shadertext$LF$TAB$TAB$*"
52 }
53 parse_shaderstage_post()
54 {
55         shadertext="$shadertext$LF$TAB}"
56 }
57 # note: the conds are what is FALSE, not TRUE
58 shaderkill()
59 {
60         parseALLtheconds=$conds
61         while :; do
62                 case "$parseALLtheconds" in
63                         '')
64                                 break
65                                 ;;
66                         *$LF*)
67                                 thiscond=${parseALLtheconds%%$LF*}
68                                 parseALLtheconds=${parseALLtheconds#*$LF}
69                                 ;;
70                         *)
71                                 thiscond=$parseALLtheconds
72                                 parseALLtheconds=
73                                 ;;
74                 esac
75                 [ -n "$thiscond" ] || continue
76                 echo "$TAB""dpshaderkillifcvar $thiscond"
77         done
78 }
79 preprocess()
80 {
81         echo "$shadertext" | {
82                 condstack=
83                 while IFS= read -r L; do
84                         [ -n "$L" ] || continue
85                         set -- $L
86                         k=$1
87                         shift
88                         case "$k" in
89                                 '#if')
90                                         case "$LF$conds$LF" in
91                                                 *"$LF$*$LF"*)
92                                                         condstack=0$condstack
93                                                         ;;
94                                                 *)
95                                                         condstack=1$condstack
96                                                         ;;
97                                         esac
98                                         ;;
99                                 '#else')
100                                         if [ -z "$condstack" ]; then
101                                                 err "unmatched #else"
102                                         fi
103                                         case "$condstack" in
104                                                 0*)
105                                                         condstack=1${condstack#0}
106                                                         ;;
107                                                 1*)
108                                                         condstack=0${condstack#1}
109                                                         ;;
110                                         esac
111                                         ;;
112                                 '#endif')
113                                         if [ -z "$condstack" ]; then
114                                                 err "unmatched #endif"
115                                         fi
116                                         condstack=${condstack#?}
117                                         ;;
118                                 *)
119                                         case "$condstack" in
120                                                 *0*)
121                                                         ;;
122                                                 *)
123                                                         echo "${L% }"
124                                                         ;;
125                                         esac
126                                         ;;
127                         esac
128                 done
129                 if [ -n "$condstack" ]; then
130                         err "unmatched #if"
131                 fi
132         }
133 }
134 conditionalize()
135 {
136         case "$1" in
137                 '')
138                         # no conditions
139                         echo "$parsing_shader"
140                         echo "{"
141                         shaderkill
142                         preprocess
143                         echo "}"
144                         return
145                         ;;
146                 *$LF*)
147                         # many conditions
148                         firstcond="${1%%$LF*}"
149                         restcond="${1#*$LF}"
150                         ;;
151                 *)
152                         firstcond=$1
153                         restcond=
154                         ;;
155         esac
156         (
157                 conds="$conds$LF$firstcond"
158                 conditionalize "$restcond"
159         )
160         (
161                 set -- $firstcond
162                 case "$2" in
163                         '==') op='!=' ;;
164                         '!=') op='==' ;;
165                         '>') op='<=' ;;
166                         '<') op='>=' ;;
167                         '>=') op='<' ;;
168                         '<=') op='>' ;;
169                 esac
170                 set -- "$1" "$op" "$3"
171                 conds="$conds$LF$*"
172                 conditionalize "$restcond"
173         )
174 }
175 parse_shader_post()
176 {
177         allconds=`echo "$shaderconds" | sort -u | grep .`
178         conds=
179         conditionalize "$allconds"
180 }
181
182 parse_shaders "$@"