bugfix [#25230] Quick extrude Ctrl-LMB : wrong behaviour of 'RotateSource' option.
[blender-staging.git] / build_files / cmake / cmake_consistency_check.py
1 # $Id$
2 # ***** BEGIN GPL LICENSE BLOCK *****
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 #
18 # Contributor(s): Campbell Barton
19 #
20 # ***** END GPL LICENSE BLOCK *****
21
22 IGNORE = \
23     "/test/",\
24     "/decimate_glut_test/",\
25     "/BSP_GhostTest/",\
26     "/release/",\
27     "/xembed/",\
28     "/decimation/intern/future/",\
29     "/TerraplayNetwork/",\
30     "/ik_glut_test/"
31
32 import os
33 from os.path import join, dirname, normpath, abspath
34
35 base = join(os.path.dirname(__file__), "..", "..")
36 base = normpath(base)
37 base = abspath(base)
38
39 print("Scanning:", base)
40
41 global_h = set()
42 global_c = set()
43
44 import os
45 from os.path import  splitext
46 def source_list(path, filename_check=None):
47     for dirpath, dirnames, filenames in os.walk(path):
48
49         # skip '.svn'
50         if dirpath.startswith("."):
51             continue
52
53         for filename in filenames:
54             if filename_check is None or filename_check(filename):
55                 yield os.path.join(dirpath, filename)
56
57 # extension checking
58 def is_c_header(filename):
59     ext = splitext(filename)[1]
60     return (ext in (".h", ".hpp", ".hxx"))
61
62 def is_cmake(filename):
63     ext = splitext(filename)[1]
64     return (ext == ".cmake") or (filename == "CMakeLists.txt")
65
66 def is_c_header(filename):
67     ext = splitext(filename)[1]
68     return (ext in (".h", ".hpp", ".hxx"))
69
70 def is_c(filename):
71     ext = splitext(filename)[1]
72     return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc"))
73
74 def is_c_any(filename):
75     return is_c(filename) or is_c_header(filename)
76
77 def cmake_get_src(f):
78     
79     sources_h = []
80     sources_c = []
81     
82     filen = open(f, "r", encoding="utf8")
83     it = iter(filen)
84     found = False
85     i = 0
86     # print(f)
87     while it is not None:
88         while it is not None:
89             i += 1
90             try:
91                 l = next(it)
92             except StopIteration:
93                 it = None
94                 break
95             l = l.strip()
96             if not l.startswith("#"):
97                 if 'set(SRC' in l or ('set(' in l and l.endswith("SRC")):
98                     if len(l.split()) > 1:
99                         raise Exception("strict formatting not kept 'set(SRC*' %s:%d" % (f, i))
100                     found = True
101                     break
102                 
103                 if "list(APPEND SRC" in l:
104                     if l.endswith(")"):
105                         raise Exception("strict formatting not kept 'list(APPEND SRC...)' on 1 line %s:%d" % (f, i))
106                     found = True
107                     break
108
109         if found:
110             cmake_base = dirname(f)
111
112             while it is not None:
113                 i += 1
114                 try:
115                     l = next(it)
116                 except StopIteration:
117                     it = None
118                     break
119                     
120                 l = l.strip()
121
122                 if not l.startswith("#"):
123                         
124                     if ")" in l:
125                         if l.strip() != ")":
126                             raise Exception("strict formatting not kept '*)' %s:%d" % (f, i))
127                         break
128
129                     if not l:
130                         pass
131                     elif l.startswith("$"):
132                         print("Cant use var '%s' %s:%d" % (l, f, i))
133                     elif len(l.split()) > 1:
134                         raise Exception("Multi-line define '%s' %s:%d" % (l, f, i))
135                     else:
136                         new_file = normpath(join(cmake_base, l))
137                         
138                         if is_c_header(new_file):
139                             sources_h.append(new_file)
140                         elif is_c(new_file):
141                             sources_c.append(new_file)
142                         else:
143                             raise Exception("unknown file type - not c or h %s -> %s" % (f, new_file))
144
145                         # print(new_file)
146
147             global_h.update(set(sources_h))
148             global_c.update(set(sources_c))
149             '''
150             if not sources_h and not sources_c:
151                 raise Exception("No sources %s" % f)
152
153             sources_h_fs = list(source_list(cmake_base, is_c_header))
154             sources_c_fs = list(source_list(cmake_base, is_c))
155             '''
156             # find missing C files:
157             '''
158             for ff in sources_c_fs:
159                 if ff not in sources_c:
160                     print("  missing: " + ff)
161             '''
162     
163     filen.close()
164
165
166 for cmake in source_list(base, is_cmake):
167     cmake_get_src(cmake)
168
169 def is_ignore(f):
170     for ig in IGNORE:
171         if ig in f:
172             return True
173     return False
174     
175 # First do stupid check, do these files exist?
176 for f in (global_h | global_c):
177     if f.endswith("dna.c"):
178         continue
179
180     if not os.path.exists(f):
181         raise Exception("CMake referenced file missing: " + f)
182
183     
184 # now check on files not accounted for.
185 print("\nC/C++ Files CMake doesnt know about...")
186 for cf in sorted(source_list(base, is_c)):
187     if not is_ignore(cf):
188         if cf not in global_c:
189             print("missing_c: ", cf)
190 print("\nC/C++ Headers CMake doesnt know about...")
191 for hf in sorted(source_list(base, is_c_header)):
192     if not is_ignore(hf):
193         if hf not in global_h:
194             print("missing_h: ", hf)
195
196 # test encoding
197 import traceback
198 for files in (global_c, global_h):
199     for f in sorted(files):
200         i = 1
201         try:
202             for l in open(f, "r", encoding="utf8"):
203                 i += 1
204         except:
205             print("Non utf8: %s:%d" % (f, i))
206             if i > 1:
207                 traceback.print_exc()