--- /dev/null
+# This file is part of NIT (http://www.nitlanguage.org).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Filters preprocessed C-like header files to remove static code and keep their signatures.
+#
+# This tool is used in the process of parsing header files to extract
+# information on the declared services (the functions and structures).
+# This information is then used to generate bindings for Nit code
+# to access these services.
+#
+# The C header sometimes contains static code. It deletes static code of
+# headers, but keep their signatures. This tool is an extension of
+# header_keeper. It searches the keyword static to identify
+# the static code, and ignores the code into their brackets. The result is
+# printed to sdtout.
+#
+# ~~~sh
+# cat Pre-Processed/CGGeometry.h | header_static > Pre-Processed/static_header.h
+# ~~~
+#
+# This module can also be used as a library.
+# The main service is the method `header_static`
+module header_static
+
+redef class Char
+ private fun is_endline: Bool do return "\};".has(self)
+end
+
+# Filters the preprocessed `input` to keep signatures for static code and write to the `output`
+fun header_static(input: Reader, output: Writer) do
+ var static_target = false
+ var static_attribute_target = false
+ var bracket_counter = 0
+ var previous_letter = ""
+ var instruction = ""
+ var double_underscore = 0
+ var position = 0
+
+ while not input.eof do
+ var line = input.read_line
+ if line.to_s.has("static") then static_target = true
+
+ if static_target then
+ if line.to_s.has("__attribute__") then static_attribute_target = true
+ for letter in line do
+ if letter == '{' then bracket_counter += 1
+ if letter == '}' then bracket_counter -= 1
+
+ if letter == '_' and previous_letter == "_" and bracket_counter == 0 then
+ double_underscore += 1
+ end
+
+ # Sometimes we lost space between return type and signature name,
+ # because he has a return line between both.
+ # We add a space before signature name for safety.
+ if bracket_counter == 0 and letter == '_' and double_underscore >= 1 and not static_attribute_target then
+ instruction = instruction.insert_at(" ", position - 2)
+ end
+ if bracket_counter == 0 and not letter.is_endline then instruction += letter.to_s
+ if bracket_counter == 0 and letter.is_endline then
+ instruction += ";"
+ static_target = false
+ static_attribute_target = false
+ end
+
+ if bracket_counter == 0 and (letter == '}' and double_underscore >= 1 or letter == ';') then
+ output.write instruction + "\n"
+ end
+
+ if letter.is_endline and bracket_counter == 0 then
+ double_underscore = 0
+ position = 0
+ instruction = ""
+ end
+
+ previous_letter = letter.to_s
+ position += 1
+ end
+ else
+ output.write line + "\n"
+ end
+ end
+end
+
+header_static(sys.stdin, sys.stdout)