Move ifndef extractor to module
diff --git a/gen/src/ifndef.rs b/gen/src/ifndef.rs
new file mode 100644
index 0000000..b436266
--- /dev/null
+++ b/gen/src/ifndef.rs
@@ -0,0 +1,46 @@
+use crate::gen::include::HEADER;
+use crate::gen::out::Content;
+
+pub(super) fn write(out: &mut Content, needed: bool, guard: &str) {
+    let ifndef = format!("#ifndef {}", guard);
+    let define = format!("#define {}", guard);
+    let endif = format!("#endif // {}", guard);
+
+    let mut offset = 0;
+    loop {
+        let begin = find_line(offset, &ifndef);
+        let end = find_line(offset, &endif);
+        if let (Some(begin), Some(end)) = (begin, end) {
+            if !needed {
+                return;
+            }
+            out.next_section();
+            if offset == 0 {
+                writeln!(out, "{}", ifndef);
+                writeln!(out, "{}", define);
+            }
+            for line in HEADER[begin + ifndef.len()..end].trim().lines() {
+                if line != define && !line.trim_start().starts_with("//") {
+                    writeln!(out, "{}", line);
+                }
+            }
+            offset = end + endif.len();
+        } else if offset == 0 {
+            panic!("not found in cxx.h header: {}", guard)
+        } else {
+            writeln!(out, "{}", endif);
+            return;
+        }
+    }
+}
+
+fn find_line(mut offset: usize, line: &str) -> Option<usize> {
+    loop {
+        offset += HEADER[offset..].find(line)?;
+        let rest = &HEADER[offset + line.len()..];
+        if rest.starts_with('\n') || rest.starts_with('\r') {
+            return Some(offset);
+        }
+        offset += line.len();
+    }
+}
diff --git a/gen/src/include.rs b/gen/src/include.rs
index 0ccb4d0..091f6c8 100644
--- a/gen/src/include.rs
+++ b/gen/src/include.rs
@@ -5,50 +5,6 @@
 /// The complete contents of the "rust/cxx.h" header.
 pub static HEADER: &str = include_str!("include/cxx.h");
 
-pub(super) fn write(out: &mut Content, needed: bool, guard: &str) {
-    let ifndef = format!("#ifndef {}", guard);
-    let define = format!("#define {}", guard);
-    let endif = format!("#endif // {}", guard);
-
-    let mut offset = 0;
-    loop {
-        let begin = find_line(offset, &ifndef);
-        let end = find_line(offset, &endif);
-        if let (Some(begin), Some(end)) = (begin, end) {
-            if !needed {
-                return;
-            }
-            out.next_section();
-            if offset == 0 {
-                writeln!(out, "{}", ifndef);
-                writeln!(out, "{}", define);
-            }
-            for line in HEADER[begin + ifndef.len()..end].trim().lines() {
-                if line != define && !line.trim_start().starts_with("//") {
-                    writeln!(out, "{}", line);
-                }
-            }
-            offset = end + endif.len();
-        } else if offset == 0 {
-            panic!("not found in cxx.h header: {}", guard)
-        } else {
-            writeln!(out, "{}", endif);
-            return;
-        }
-    }
-}
-
-fn find_line(mut offset: usize, line: &str) -> Option<usize> {
-    loop {
-        offset += HEADER[offset..].find(line)?;
-        let rest = &HEADER[offset + line.len()..];
-        if rest.starts_with('\n') || rest.starts_with('\r') {
-            return Some(offset);
-        }
-        offset += line.len();
-    }
-}
-
 /// A header to #include.
 ///
 /// The cxxbridge tool does not parse or even require the given paths to exist;
diff --git a/gen/src/mod.rs b/gen/src/mod.rs
index e969dec..d79a465 100644
--- a/gen/src/mod.rs
+++ b/gen/src/mod.rs
@@ -6,6 +6,7 @@
 pub(super) mod error;
 mod file;
 pub(super) mod fs;
+mod ifndef;
 pub(super) mod include;
 mod namespace_organizer;
 pub(super) mod out;
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 095b2c2..2af11c6 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -1,6 +1,6 @@
 use crate::gen::namespace_organizer::NamespaceEntries;
 use crate::gen::out::OutFile;
-use crate::gen::{include, Opt};
+use crate::gen::{ifndef, Opt};
 use crate::syntax::atom::Atom::{self, *};
 use crate::syntax::symbol::Symbol;
 use crate::syntax::{
@@ -308,7 +308,7 @@
     out.begin_block("inline namespace cxxbridge05");
     writeln!(out, "// #include \"rust/cxx.h\"");
 
-    include::write(out, builtin.panic, "CXXBRIDGE05_PANIC");
+    ifndef::write(out, builtin.panic, "CXXBRIDGE05_PANIC");
 
     if builtin.rust_string {
         out.next_section();
@@ -322,15 +322,15 @@
         out.end_block("namespace");
     }
 
-    include::write(out, builtin.rust_string, "CXXBRIDGE05_RUST_STRING");
-    include::write(out, builtin.rust_str, "CXXBRIDGE05_RUST_STR");
-    include::write(out, builtin.rust_slice, "CXXBRIDGE05_RUST_SLICE");
-    include::write(out, builtin.rust_box, "CXXBRIDGE05_RUST_BOX");
-    include::write(out, builtin.unsafe_bitcopy, "CXXBRIDGE05_RUST_BITCOPY");
-    include::write(out, builtin.rust_vec, "CXXBRIDGE05_RUST_VEC");
-    include::write(out, builtin.rust_fn, "CXXBRIDGE05_RUST_FN");
-    include::write(out, builtin.rust_error, "CXXBRIDGE05_RUST_ERROR");
-    include::write(out, builtin.rust_isize, "CXXBRIDGE05_RUST_ISIZE");
+    ifndef::write(out, builtin.rust_string, "CXXBRIDGE05_RUST_STRING");
+    ifndef::write(out, builtin.rust_str, "CXXBRIDGE05_RUST_STR");
+    ifndef::write(out, builtin.rust_slice, "CXXBRIDGE05_RUST_SLICE");
+    ifndef::write(out, builtin.rust_box, "CXXBRIDGE05_RUST_BOX");
+    ifndef::write(out, builtin.unsafe_bitcopy, "CXXBRIDGE05_RUST_BITCOPY");
+    ifndef::write(out, builtin.rust_vec, "CXXBRIDGE05_RUST_VEC");
+    ifndef::write(out, builtin.rust_fn, "CXXBRIDGE05_RUST_FN");
+    ifndef::write(out, builtin.rust_error, "CXXBRIDGE05_RUST_ERROR");
+    ifndef::write(out, builtin.rust_isize, "CXXBRIDGE05_RUST_ISIZE");
 
     if builtin.manually_drop {
         out.next_section();