Skip to content

Commit d200c6b

Browse files
committed
initial_commit
1 parent 5d9e295 commit d200c6b

File tree

4 files changed

+140
-0
lines changed

4 files changed

+140
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.vscode*

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/comavius/unfoldcpp
2+
3+
go 1.20

hpp_file.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package unfoldcpp
2+
3+
import (
4+
"bufio"
5+
"errors"
6+
"os"
7+
"path/filepath"
8+
"regexp"
9+
"strings"
10+
)
11+
12+
// filepath structure
13+
type HppFile struct {
14+
path string
15+
dependencies []string
16+
}
17+
18+
// constructor
19+
func NewHppFile(path string) *HppFile {
20+
return &HppFile{path: path}
21+
}
22+
23+
// get depe
24+
func (hpp *HppFile) TraceDependencies() ([]string, error) {
25+
// open file
26+
file, err := os.Open(hpp.path)
27+
if err != nil {
28+
return nil, err
29+
}
30+
defer file.Close()
31+
// read file and extract #include "*"
32+
// setup regex
33+
r, err := regexp.Compile(`#include[\s]+\"(.*)\"\s*`)
34+
if err != nil {
35+
return nil, err
36+
}
37+
// read file line by line
38+
relative_paths := make([]string, 0)
39+
scanner := bufio.NewScanner(file)
40+
for scanner.Scan() {
41+
if r.MatchString(scanner.Text()) {
42+
line := scanner.Text()
43+
start_index := strings.Index(line, "\"")
44+
end_index, err := findNextQuote(line, start_index+1)
45+
if err != nil {
46+
return nil, err
47+
}
48+
relative_paths = append(relative_paths, line[start_index+1:end_index])
49+
}
50+
}
51+
// get absolute paths
52+
absolute_paths := make([]string, 0)
53+
for _, relative_path := range relative_paths {
54+
absolute_path, err := filepath.Abs(filepath.Dir(hpp.path) + "/" + relative_path)
55+
if err != nil {
56+
return nil, err
57+
}
58+
absolute_paths = append(absolute_paths, absolute_path)
59+
}
60+
// return
61+
return absolute_paths, nil
62+
}
63+
64+
func findNextQuote(s string, startIndex int) (int, error) {
65+
if startIndex < 0 || startIndex >= len(s) {
66+
return -1, errors.New("startIndex out of range")
67+
}
68+
69+
for i := startIndex; i < len(s); i++ {
70+
if s[i] == '"' {
71+
if i == 0 || s[i-1] != '\\' {
72+
return i, nil
73+
}
74+
}
75+
}
76+
return -1, errors.New("no unescaped quote found")
77+
}

unfold.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package unfoldcpp
2+
3+
import (
4+
"os"
5+
)
6+
7+
func Unfold(path string) (string, error) {
8+
// trace dependencies recursively
9+
founded_queue := make([]string, 0)
10+
founded_list := make([]string, 0)
11+
resolved_queue := make([]string, 0)
12+
founded_queue = append(founded_queue, path)
13+
founded_list = append(founded_list, path)
14+
err := unfold_recursively(&founded_queue, &resolved_queue, &founded_list)
15+
if err != nil {
16+
return "", err
17+
}
18+
// build single-file
19+
single_file := "#define UNFOLDED\n"
20+
for _, path := range resolved_queue {
21+
data, err := os.ReadFile(path)
22+
if err != nil {
23+
return "", err
24+
}
25+
single_file += string(data) + "\n"
26+
}
27+
return single_file, nil
28+
}
29+
30+
func unfold_recursively(founded_queue *[]string, resolved_queue *[]string, founded_list *[]string) error {
31+
// pop
32+
path := (*founded_queue)[0]
33+
*founded_queue = (*founded_queue)[1:]
34+
// construct HppFile
35+
hpp := NewHppFile(path)
36+
// trace dependencies
37+
dependencies, err := hpp.TraceDependencies()
38+
if err != nil {
39+
return err
40+
}
41+
// add dependencies to founded_queue if not already in founded_list
42+
for _, dependency := range dependencies {
43+
founded_formerly := false
44+
for _, founded_path := range *founded_list {
45+
if founded_path == dependency {
46+
founded_formerly = true
47+
break
48+
}
49+
}
50+
if !founded_formerly {
51+
*founded_queue = append(*founded_queue, dependency)
52+
*founded_list = append(*founded_list, dependency)
53+
unfold_recursively(founded_queue, resolved_queue, founded_list)
54+
}
55+
}
56+
// add path to resolved_queue
57+
*resolved_queue = append(*resolved_queue, path)
58+
return nil
59+
}

0 commit comments

Comments
 (0)