Nigel Tao | 79a9455 | 2017-11-30 16:37:20 +1100 | [diff] [blame] | 1 | // Copyright 2017 The Wuffs Authors. |
Nigel Tao | e57c8d7 | 2017-11-03 15:05:19 +1100 | [diff] [blame] | 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 | // https://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 | |
Nigel Tao | 788479d | 2021-08-22 10:52:51 +1000 | [diff] [blame] | 15 | //go:build ignore |
Nigel Tao | e57c8d7 | 2017-11-03 15:05:19 +1100 | [diff] [blame] | 16 | // +build ignore |
| 17 | |
| 18 | package main |
| 19 | |
| 20 | // inline-c-relative-includes.go echoes the given C file to stdout, expanding |
| 21 | // #include lines that uses "quoted files" (but not <bracketed files>). |
| 22 | // |
| 23 | // The output should be a stand-alone C file that other people can easily |
Nigel Tao | d1399fa | 2018-03-16 10:48:33 +1100 | [diff] [blame] | 24 | // compile and run with no further dependencies, other than test/data files. |
Nigel Tao | e57c8d7 | 2017-11-03 15:05:19 +1100 | [diff] [blame] | 25 | // |
| 26 | // Usage: go run inline-c-relative-includes.go path/to/foo.c |
| 27 | |
| 28 | import ( |
| 29 | "bufio" |
| 30 | "bytes" |
| 31 | "fmt" |
| 32 | "os" |
| 33 | "path/filepath" |
| 34 | ) |
| 35 | |
| 36 | func main() { |
| 37 | if err := main1(); err != nil { |
| 38 | os.Stderr.WriteString(err.Error() + "\n") |
| 39 | os.Exit(1) |
| 40 | } |
| 41 | } |
| 42 | |
| 43 | func main1() error { |
| 44 | if len(os.Args) != 2 { |
| 45 | return fmt.Errorf("inline-c-relative-includes takes exactly 1 argument") |
| 46 | } |
| 47 | w := bufio.NewWriter(os.Stdout) |
| 48 | defer w.Flush() |
| 49 | return do(w, ".", os.Args[1], 0) |
| 50 | } |
| 51 | |
| 52 | var ( |
| 53 | prefix = []byte(`#include "`) |
| 54 | suffix = []byte(`"`) |
| 55 | |
| 56 | seen = map[string]bool{} |
| 57 | ) |
| 58 | |
| 59 | func do(w *bufio.Writer, dir string, filename string, depth int) error { |
| 60 | if depth == 100 { |
| 61 | return fmt.Errorf("recursion too deep") |
| 62 | } |
| 63 | if depth != 0 { |
| 64 | fmt.Fprintf(w, "// BEGIN INLINE #include %q\n", filename) |
| 65 | defer fmt.Fprintf(w, "// END INLINE #include %q\n", filename) |
| 66 | } |
| 67 | depth++ |
| 68 | |
| 69 | filename = filepath.Join(dir, filename) |
| 70 | if seen[filename] { |
| 71 | return fmt.Errorf("duplicate filename %q", filename) |
| 72 | } |
| 73 | seen[filename] = true |
| 74 | |
| 75 | dir, _ = filepath.Split(filename) |
| 76 | f, err := os.Open(filename) |
| 77 | if err != nil { |
| 78 | return err |
| 79 | } |
| 80 | defer f.Close() |
| 81 | |
| 82 | r := bufio.NewScanner(f) |
| 83 | for r.Scan() { |
Nigel Tao | e364357 | 2017-11-03 15:33:23 +1100 | [diff] [blame] | 84 | line := r.Bytes() |
Nigel Tao | e57c8d7 | 2017-11-03 15:05:19 +1100 | [diff] [blame] | 85 | |
Nigel Tao | e364357 | 2017-11-03 15:33:23 +1100 | [diff] [blame] | 86 | if s := line; bytes.HasPrefix(s, prefix) { |
Nigel Tao | e57c8d7 | 2017-11-03 15:05:19 +1100 | [diff] [blame] | 87 | s = s[len(prefix):] |
| 88 | if bytes.HasSuffix(s, suffix) { |
| 89 | s = s[:len(s)-len(suffix)] |
| 90 | if err := do(w, dir, string(s), depth); err == nil { |
| 91 | continue |
| 92 | } else if os.IsNotExist(err) { |
| 93 | // This is probably an #include of a system header, like |
Nigel Tao | 024dc7f | 2017-11-30 18:18:40 +1100 | [diff] [blame] | 94 | // `#include "zlib.h"`, and not of Wuffs code. Fall through |
Nigel Tao | e57c8d7 | 2017-11-03 15:05:19 +1100 | [diff] [blame] | 95 | // and print the #include line as normal. |
| 96 | } else { |
| 97 | return err |
| 98 | } |
| 99 | } |
| 100 | } |
| 101 | |
Nigel Tao | e364357 | 2017-11-03 15:33:23 +1100 | [diff] [blame] | 102 | w.Write(line) |
Nigel Tao | e57c8d7 | 2017-11-03 15:05:19 +1100 | [diff] [blame] | 103 | w.WriteByte('\n') |
| 104 | } |
| 105 | return r.Err() |
| 106 | } |