c43fe2ac81f94d0b09d17211a127dee6e03a7f2a
[nit.git] / contrib / objcwrapper / src / header_static.nit
1 # This file is part of NIT (http://www.nitlanguage.org).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Filters preprocessed C-like header files to remove static code and keep their signatures.
16 #
17 # This tool is used in the process of parsing header files to extract
18 # information on the declared services (the functions and structures).
19 # This information is then used to generate bindings for Nit code
20 # to access these services.
21 #
22 # The C header sometimes contains static code. It deletes static code of
23 # headers, but keep their signatures. This tool is an extension of
24 # header_keeper. It searches the keyword static to identify
25 # the static code, and ignores the code into their brackets. The result is
26 # printed to sdtout.
27 #
28 # ~~~sh
29 # cat Pre-Processed/CGGeometry.h | header_static > Pre-Processed/static_header.h
30 # ~~~
31 #
32 # This module can also be used as a library.
33 # The main service is the method `header_static`
34 module header_static
35
36 redef class Char
37 private fun is_endline: Bool do return "\};".has(self)
38 end
39
40 # Filters the preprocessed `input` to keep signatures for static code and write to the `output`
41 fun header_static(input: Reader, output: Writer) do
42 var static_target = false
43 var static_attribute_target = false
44 var bracket_counter = 0
45 var previous_letter = ""
46 var instruction = ""
47 var double_underscore = 0
48 var position = 0
49
50 while not input.eof do
51 var line = input.read_line
52 if line.to_s.has("static") then static_target = true
53
54 if static_target then
55 if line.to_s.has("__attribute__") then static_attribute_target = true
56 for letter in line do
57 if letter == '{' then bracket_counter += 1
58 if letter == '}' then bracket_counter -= 1
59
60 if letter == '_' and previous_letter == "_" and bracket_counter == 0 then
61 double_underscore += 1
62 end
63
64 # Sometimes we lost space between return type and signature name,
65 # because he has a return line between both.
66 # We add a space before signature name for safety.
67 if bracket_counter == 0 and letter == '_' and double_underscore >= 1 and not static_attribute_target then
68 instruction = instruction.insert_at(" ", position - 2)
69 end
70 if bracket_counter == 0 and not letter.is_endline then instruction += letter.to_s
71 if bracket_counter == 0 and letter.is_endline then
72 instruction += ";"
73 static_target = false
74 static_attribute_target = false
75 end
76
77 if bracket_counter == 0 and (letter == '}' and double_underscore >= 1 or letter == ';') then
78 output.write instruction + "\n"
79 end
80
81 if letter.is_endline and bracket_counter == 0 then
82 double_underscore = 0
83 position = 0
84 instruction = ""
85 end
86
87 previous_letter = letter.to_s
88 position += 1
89 end
90 else
91 output.write line + "\n"
92 end
93 end
94 end
95
96 header_static(sys.stdin, sys.stdout)