写了个GO可以把c++的结构批量转成go的结构,超爽

我看你有戏 2017-01-15 09:52:57

package main

import (
"bufio"
"fmt"
"strconv"
// "io"
"log"
"os"
"strings"

"github.com/axgle/mahonia"
)

const (
READ_KNOW uint32 = 0
READ_ENUM uint32 = 1
READ_STRUCT uint32 = 2
)

type struct_node struct {
node_type string //字段类型
node_name string //字段名
node_des string //注释
node_len int //字段长度
str_ary_cout string //是数组的话表示数组长度 宏定义,默认""
n_ary_cout int //是数组的话表示数组长度 数值,默认1
}
type struc_info struct {
struct_name string
ary_node []struct_node
}

func (st *struc_info) clear() {
st.struct_name = ""
st.ary_node = nil
}
func (st *struc_info) print() {
fmt.Println("type " + st.struct_name + " struct {")
for i := 0; i < len(st.ary_node); i++ {
if st.ary_node[i].n_ary_cout == 1 {
fmt.Println("\t", st.ary_node[i].node_name, "\t", st.ary_node[i].node_type, st.ary_node[i].node_des)
} else if st.ary_node[i].n_ary_cout > 1 {
//fmt.Println("维数:st.ary_node[i].n_ary_cout", st.ary_node[i].n_ary_cout)
if st.ary_node[i].str_ary_cout != "" {
fmt.Println("\t", st.ary_node[i].node_name, "\t", "["+st.ary_node[i].str_ary_cout+"]"+st.ary_node[i].node_type, st.ary_node[i].node_des)
} else {
fmt.Println("\t", st.ary_node[i].node_name, "\t", "["+fmt.Sprintf("%d", st.ary_node[i].n_ary_cout)+"]"+st.ary_node[i].node_type, st.ary_node[i].node_des)
}
}
}
fmt.Println("}")
}

var mp_macro map[string]string

func main() {
var read_type uint32
read_type = READ_KNOW

//fileName := "E:/学习/DouDou/系统模块/消息定义/CMD_GameChat.h"

var fileName string
arg_num := len(os.Args)
if arg_num == 2 {
fileName = os.Args[1]
} else {
log.Fatal("请输入c++ .h文件的路径")
return
}

dec := mahonia.NewDecoder("gbk")
f, err := os.Open(fileName)
if err != nil {
log.Fatal(err.Error())
}
buf := bufio.NewReader(f)

var dec_str string
var stinfo struc_info

mp_macro = make(map[string]string)
for {
line, err := buf.ReadString('\n')
if err != nil {
log.Println("文件尾部")
break
}
line = strings.TrimSpace(line)
dec_str = ""
nIdx := strings.Index(line, "//")
if read_type == READ_KNOW {
if nIdx >= 0 {
//fmt.Println(line[0:nIdx])
dec_str = find_define(line[0:nIdx])
dec_str += dec.ConvertString(line[nIdx:])
} else {
//fmt.Println(line)
dec_str = find_define(line)
}

if dec_str != "" {
fmt.Println(dec_str)
continue
}

if nIdx >= 0 {
dec_str = find_enum(line[0:nIdx], &read_type)
dec_str += dec.ConvertString(line[nIdx:])
} else {
dec_str = find_enum(line, &read_type)
}

if dec_str != "" {
fmt.Println(dec_str)
continue
}

if nIdx >= 0 {
dec_str = find_struct(line[0:nIdx], &read_type, &stinfo)
dec_str += dec.ConvertString(line[nIdx:])
} else {
dec_str = find_struct(line, &read_type, &stinfo)
}

if dec_str != "" {
//fmt.Println(dec_str)
continue
}

} else if read_type == READ_ENUM {
if nIdx >= 0 {
dec_str = find_enum(line[0:nIdx], &read_type)
dec_str += dec.ConvertString(line[nIdx:])
} else {
dec_str = find_enum(line, &read_type)
}

if dec_str != "" {
fmt.Println(dec_str)
continue
}
} else if read_type == READ_STRUCT {
if nIdx >= 0 {
dec_str = find_struct(line[0:nIdx], &read_type, &stinfo)
zs := dec.ConvertString(line[nIdx:])
stinfo.ary_node[len(stinfo.ary_node)-1].node_des = zs
dec_str += zs
} else {
dec_str = find_struct(line, &read_type, &stinfo)
}

if dec_str != "" {
//fmt.Println(dec_str)

if read_type == READ_KNOW {
stinfo.print()
}

continue
}

}

fmt.Printf("\r\n")

}
}

func tran_type(str string) string {
if str == "BYTE" || str == "byte" || str == "char" || str == "TCHAR" {
return "byte"
} else if str == "DWORD" {
return "uint32"
} else if str == "__int64" || str == "LONGLONG" {
return "int64"
} else if str == "ULONG64" {
return "uint64"
} else if str == "WORD" {
return "uint16"
}

return str
}
func find_enum(str string, read_type *uint32) string {
idx := strings.Index(str, "enum")
if idx == 0 {
*read_type = READ_ENUM
return "//" + str + "\r\n" + "const ("
} else if *read_type == READ_ENUM {
if str == "{" {
return ""
} else if str == "};" {
*read_type = READ_KNOW
return ")"
} else {
str = strings.Replace(str, "=", "uint32 = ", -1)
str = strings.Replace(str, ",", "", -1)
return "\t" + str
}
}
return ""
}
func find_struct(str string, read_type *uint32, stinfo *struc_info) string {
idx := strings.Index(str, "struct")
if idx == 0 {
ary := []byte(str)
var start, end int
var ok bool
start = 0
end = 0
ok = false

//return "//" + str + "\r\n" + "const ("
var aryString []string
for i := 0; i < len(ary); i++ {
if ok == false {
if ary[i] == 0x20 {
end = i
ok = true
} else if ary[i] == 0x09 {
end = i
ok = true
}
} else {
if (ary[i] == 0x20 || ary[i] == 0x09) == false {
//fmt.Print("\n")
aryString = append(aryString, string(ary[start:end]))
start = i
ok = false
}
}
//fmt.Printf("0x%.2x ", ary[i])
}
aryString = append(aryString, string(ary[start:len(ary)]))

if len(aryString) == 2 {
*read_type = READ_STRUCT
stinfo.clear()
stinfo.struct_name = aryString[1]
return "type " + aryString[1] + " struct {"
}
} else if *read_type == READ_STRUCT {
if str == "{" {
return ""
} else if str == "};" {
*read_type = READ_KNOW
return "}"
} else {
str = strings.Replace(str, ";", "", -1)
abc := find_strucinfo(str)
/*if stinfo.ary_node == nil {
stinfo.ary_node = make([]struct_node, 1)
stinfo.ary_node[0] = abc

} else {
stinfo.ary_node = append(stinfo.ary_node, abc)
}*/
//fmt.Println("维数:", abc.n_ary_cout)

stinfo.ary_node = append(stinfo.ary_node, abc)
return "\t" + str
}
}

return ""
}

func find_strucinfo(str string) struct_node {
ary := []byte(str)
var start, end int
var ok bool
start = 0
end = 0
ok = false
var aryString []string
for i := 0; i < len(ary); i++ {
if ok == false {
if ary[i] == 0x20 {
end = i
ok = true
} else if ary[i] == 0x09 {
end = i
ok = true
}
} else {
if (ary[i] == 0x20 || ary[i] == 0x09) == false {
//fmt.Print("\n")
aryString = append(aryString, string(ary[start:end]))
start = i
ok = false
}
}
}
aryString = append(aryString, string(ary[start:len(ary)]))

var st struct_node
if len(aryString) >= 2 {
a, b, c := find_ary(aryString[1])
st.node_name = a
st.str_ary_cout = b
st.n_ary_cout = c

st.node_type = tran_type(aryString[0])
}
//fmt.Println("解析数据:", st.node_type, st.node_name)
return st
}

func IsNum(str string) bool {
ary := []byte(str)
for i := 0; i < len(ary); i++ {
if !(ary[i] >= '0' && ary[i] <= '9') {
return false
}
}
return true
}

func find_ary(str string) (string, string, int) {
nPos1 := strings.Index(str, "[")
nPos2 := strings.Index(str, "]")
if nPos1 > 0 && nPos2 > nPos1 {
var n int
tmp := str[nPos1+1 : nPos2]
if IsNum(tmp) {
n, _ := strconv.Atoi(tmp)

return str[0:nPos1], "", n
} else {
//fmt.Println(mp_macro)
v, ok := mp_macro[tmp]
if !ok {
log.Fatal("宏定义", tmp, "找不到定义")
}
n, _ = strconv.Atoi(v)
return str[0:nPos1], tmp, n
}

}
return str, "", 1
}
func find_define(str string) string {
ary := []byte(str)
var start, end int
var ok bool
start = 0
end = 0
ok = false
var aryString []string
for i := 0; i < len(ary); i++ {
if ok == false {
if ary[i] == 0x20 {
end = i
ok = true
} else if ary[i] == 0x09 {
end = i
ok = true
}
} else {
if (ary[i] == 0x20 || ary[i] == 0x09) == false {
//fmt.Print("\n")
aryString = append(aryString, string(ary[start:end]))
start = i
ok = false
}
}
//fmt.Printf("0x%.2x ", ary[i])
}
//fmt.Print("\n")
//fmt.Println(string(ary[start:len(ary)]))

//fmt.Println("")
//fmt.Println(str)
aryString = append(aryString, string(ary[start:len(ary)]))
//for i := 0; i < len(aryString); i++ {
// fmt.Println(aryString[i])
//}
if aryString[0] == "#define" && len(aryString) == 3 {
mp_macro[aryString[1]] = aryString[2]
return "const " + aryString[1] + "=" + aryString[2]
}

return ""
}



保存为tran.go
编译

cmd
tran.exe c:\\123.h
看下屏幕有惊喜
...全文
456 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

2,190

社区成员

发帖
与我相关
我的任务
社区描述
go语言学习与交流版
社区管理员
  • go语言社区
  • Freeman Z
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧