Merge remote branch 'origin/terencehill/newpanelhud-dom_points' into terencehill...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / autocvarize.pl
1 #!/usr/bin/perl
2 # this tool generates JUST the autocvar declarations for cvars
3 use strict;
4 use warnings;
5
6 my @files = @ARGV;
7
8 my %cvars = ();
9 my %old = ();
10 my %menu = ();
11 my %defaults = ();
12
13 sub found($$$$)
14 {
15         my ($name, $type, $default, $force) = @_;
16         if(length $name >= 55)
17         {
18                 warn "cvar $name is a Dr. honorificabilitudinitatibis causa BRLOGENSHFEGLE";
19                 $type = 'cvar_toolong';
20                 return;
21         }
22 #       $old{$name} = 1
23 #               if $force;
24 #       $menu{$name} = 1
25 #               if $force > 1;
26         if(exists $cvars{$name} and not defined $cvars{name})
27         {
28                 # have already warned
29         }
30         elsif(exists $cvars{$name} and $type ne $cvars{$name})
31         {
32                 warn "cvar $name used with different types";
33                 if($force)
34                 {
35                         $defaults{$name} = $default;
36                         $cvars{$name} = $type;
37                 }
38                 else
39                 {
40                         undef $cvars{$name}
41                                 unless $old{$name};
42                 }
43                 return;
44         }
45         elsif(exists $cvars{$name} and exists $defaults{$name} and $default ne $defaults{$name})
46         {
47                 warn "cvar $name used with different defaults";
48                 if($force)
49                 {
50                         $defaults{$name} = $default;
51                         $cvars{$name} = $type;
52                 }
53                 else
54                 {
55                         undef $cvars{$name}
56                                 unless $old{$name};
57                 }
58         }
59         else
60         {
61                 $defaults{$name} = $default;
62                 $cvars{$name} = $type;
63         }
64 }
65
66 for my $f(@files)
67 {
68         print STDERR "In file $f\n";
69         open my $fh, "<", $f;
70         while(<$fh>)
71         {
72                 chomp;
73                 if(/^\/\/#NO AUTOCVARS START/ .. /^\/\/#NO AUTOCVARS END/)
74                 {
75                         next;
76                 }
77                 s/\/\/.*//;
78                 if(/^(?:var )?float autocvar_(\w+);$/)
79                 {
80                         found $1, 'cvar', 0, 1;
81                         next;
82                 }
83                 if(/^var float autocvar_(\w+) = (.*);$/)
84                 {
85                         found $1, 'cvar', $2, 1;
86                         next;
87                 }
88                 if(/^(?:var )?vector autocvar_(\w+);$/)
89                 {
90                         found $1, 'cvar_vector', "0 0 0", 1;
91                         next;
92                 }
93                 if(/^var vector autocvar_(\w+) = '(.*)';$/)
94                 {
95                         found $1, 'cvar_vector', $2, 1;
96                         next;
97                 }
98                 if(/^(?:var )?string autocvar_(\w+);$/)
99                 {
100                         found $1, 'cvar_string', "", 1;
101                         next;
102                 }
103                 if(/^var string autocvar_(\w+) = "(.*)";$/)
104                 {
105                         found $1, 'cvar_string', $2, 1;
106                         next;
107                 }
108                 if(/^#define autocvar_(\w+) cvar("\1")$/)
109                 {
110                         found $1, 'cvar', 0, 2;
111                         next;
112                 }
113                 if(/^#define autocvar_(\w+) cvar_or("\1", (.*))$/)
114                 {
115                         found $1, 'cvar', $1, 2;
116                         next;
117                 }
118                 if(/^#define autocvar_(\w+) cvar_string("\1")$/)
119                 {
120                         found $1, 'cvar_string', "", 2;
121                         next;
122                 }
123                 while(/\bcvar\s*\(\s*"(\w+)"\s*\)/g)
124                 {
125                         found $1, 'cvar', 0, 0;
126                 }
127                 while(/\bcvar_string\s*\(\s*"(\w+)"\s*\)/g)
128                 {
129                         found $1, 'cvar_string', "", 0;
130                 }
131                 while(/\bcvar_vector\s*\(\s*"(\w+)"\s*\)/g)
132                 {
133                         found $1, 'cvar_vector', "0 0 0", 0;
134                 }
135                 while(/\bcvar_or\s*\(\s*"(\w+)"\s*,\s*([^\s)]+)\s*\)/g)
136                 {
137                         found $1, 'cvar', $2, 0;
138                 }
139         }
140 }
141
142 if($ENV{AUTOCVARING_SVQC})
143 {
144         for my $f(<menu/xonotic/*.c>)
145         {
146                 print STDERR "In file $f\n";
147                 open my $fh, "<", $f;
148                 while(<$fh>)
149                 {
150                         for(/"([^"]*)"/g)
151                         {
152                                 $menu{$1} = 1;
153                         }
154                 }
155         }
156
157         for my $f(<../maps/campaign*.txt>)
158         {
159                 print STDERR "In file $f\n";
160                 open my $fh, "<", $f;
161                 while(<$fh>)
162                 {
163                         for(/\b(.+?)\b/g)
164                         {
165                                 $menu{$1} = 1;
166                         }
167                 }
168         }
169 }
170
171 for my $name(sort keys %cvars)
172 {
173         my $type = $cvars{$name};
174         my $menu = $menu{$name};
175         my $default = $defaults{$name};
176         die "wtf" if $name =~ /\0/;
177         if(not defined $type)
178         {
179                 print "// cannot declare $name, it is used with different types\n";
180         }
181         elsif($type eq 'cvar_toolong')
182         {
183                 print "// cannot declare $name, name is too long\n";
184         }
185         elsif($type eq 'cvar' and not $menu and $default eq "0")
186         {
187                 print "float autocvar_$name;\n";
188         }
189         elsif($type eq 'cvar' and not $menu and $default ne "0")
190         {
191                 print "var float autocvar_$name = $default;\n";
192         }
193         elsif($type eq 'cvar_vector' and not $menu and $default eq "0 0 0")
194         {
195                 print "vector autocvar_$name;\n";
196         }
197         elsif($type eq 'cvar_vector' and not $menu and $default ne "0 0 0")
198         {
199                 print "var vector autocvar_$name = '$default';\n";
200         }
201         elsif($type eq 'cvar_string' and not $menu and $default eq "")
202         {
203                 print "string autocvar_$name;\n";
204         }
205         elsif($type eq 'cvar_string' and not $menu and $default ne "")
206         {
207                 print "var string autocvar_$name = \"$default\";\n";
208         }
209         elsif($type eq 'cvar' and $menu and $default eq "0")
210         {
211                 print "#define autocvar_$name cvar(\"$name\")\n";
212         }
213         elsif($type eq 'cvar' and $menu and $default ne "0")
214         {
215                 print "#define autocvar_$name cvar_or(\"$name\", \"$default\")\n";
216         }
217         elsif($type eq 'cvar_string' and $menu) # sorry, no cvar_or for these
218         {
219                 print "#define autocvar_$name cvar_string(\"$name\")\n";
220         }
221         elsif($type eq 'cvar_vector' and $menu) # sorry, no cvar_or for these
222         {
223                 print "#define autocvar_$name cvar_vector(\"$name\")\n";
224         }
225 }
226
227 for my $f(@files)
228 {
229         print STDERR "In file $f\n";
230         open my $fh, "<", $f;
231         my $out = "";
232         while(<$fh>)
233         {
234                 chomp;
235                 if(/^\/\/#NO AUTOCVARS START/ .. /^\/\/#NO AUTOCVARS END/)
236                 {
237                         $out .= "$_\n";
238                         next;
239                 }
240                 if(/^(?:var )?float autocvar_(.*);$/)
241                 {
242                         $out .= "$_\n";
243                         next;
244                 }
245                 if(/^(?:var )?string autocvar_(.*);$/)
246                 {
247                         $out .= "$_\n";
248                         next;
249                 }
250                 if(/^#define autocvar_(.*) cvar/)
251                 {
252                         $out .= "$_\n";
253                         next;
254                 }
255                 s{\b(cvar|cvar_string|cvar_vector|cvar_or)\s*\(\s*"([^"]+)"\s*(?:,\s*[^\s)]+\s*)?\)}{
256                         my ($type, $name) = ($1, $2);
257                         $type = 'cvar' if $type eq 'cvar_or';
258                         my $realtype = $cvars{$name};
259                         my $r = $&;
260                         if(defined $realtype)
261                         {
262                                 #$r = "$realtype(\"$name\")";
263                                 $r = "autocvar_$name";
264                                 if($type eq 'cvar' && $realtype eq 'cvar_string')
265                                 {
266                                         $r = "stof($r)";
267                                 }
268                                 if($type eq 'cvar_string' && $realtype eq 'cvar')
269                                 {
270                                         $r = "ftos($r)";
271                                 }
272                         }
273                         $r;
274                 }ge;
275                 $out .= "$_\n";
276         }
277         close $fh;
278         open $fh, ">", $f;
279         print $fh $out;
280         close $fh;
281 }