diff --git a/main.go b/main.go index 6bb84457..2847b994 100644 --- a/main.go +++ b/main.go @@ -11,7 +11,7 @@ import ( var log = golog.New("main") const ( - Version = "3.0.0" + Version = "3.0.1" ) var enableProfile = false diff --git a/v3/checker/checker_data.go b/v3/checker/checker_data.go index 8b0d6648..5d43db59 100644 --- a/v3/checker/checker_data.go +++ b/v3/checker/checker_data.go @@ -4,7 +4,6 @@ import ( "github.com/davyxu/tabtoy/v3/model" "github.com/davyxu/tabtoy/v3/report" "strconv" - "strings" ) // 检查数据与定义类型是否匹配 @@ -35,12 +34,9 @@ func checkDataType(globals *model.Globals) { crrCell = inputCell currHeader = header - if inputCell.Value == "" { - continue - } - if header.TypeInfo.IsArray() { - for _, value := range strings.Split(inputCell.Value, header.TypeInfo.ArraySplitter) { + for _, value := range inputCell.ValueList { + err := checkSingleValue(header, value) if err != nil { report.ReportError("DataMissMatchTypeDefine", currHeader.TypeInfo.FieldType, crrCell.String()) @@ -61,31 +57,49 @@ func checkDataType(globals *model.Globals) { func checkSingleValue(header *model.HeaderField, value string) error { switch model.LanguagePrimitive(header.TypeInfo.FieldType, "go") { case "int16": + if value == "" { + return nil + } _, err := strconv.ParseInt(value, 10, 16) if err != nil { return err } case "int32": + if value == "" { + return nil + } _, err := strconv.ParseInt(value, 10, 32) if err != nil { return err } case "int64": + if value == "" { + return nil + } _, err := strconv.ParseInt(value, 10, 64) if err != nil { return err } case "uint16": + if value == "" { + return nil + } _, err := strconv.ParseUint(value, 10, 16) if err != nil { return err } case "uint32": + if value == "" { + return nil + } _, err := strconv.ParseUint(value, 10, 32) if err != nil { return err } case "uint64": + if value == "" { + return nil + } _, err := strconv.ParseUint(value, 10, 64) if err != nil { return err @@ -96,6 +110,9 @@ func checkSingleValue(header *model.HeaderField, value string) error { return err } case "float64": + if value == "" { + return nil + } _, err := strconv.ParseFloat(value, 64) if err != nil { return err diff --git a/v3/checker/checker_enumvalue.go b/v3/checker/checker_enumvalue.go index e588a0b2..3707a73e 100644 --- a/v3/checker/checker_enumvalue.go +++ b/v3/checker/checker_enumvalue.go @@ -3,7 +3,6 @@ package checker import ( "github.com/davyxu/tabtoy/v3/model" "github.com/davyxu/tabtoy/v3/report" - "strings" ) // 枚举值的解析是放在输出端处理的, 例如json中, 所以在这里提前检查 @@ -32,17 +31,14 @@ func checkEnumValue(globals *model.Globals) { continue } - if inputCell.Value != "" { + if header.TypeInfo.IsArray() { - if header.TypeInfo.IsArray() { - - for _, v := range strings.Split(inputCell.Value, header.TypeInfo.ArraySplitter) { - checkEnumFieldValue(globals, header, v, inputCell) - } - - } else { - checkEnumFieldValue(globals, header, inputCell.Value, inputCell) + for _, v := range inputCell.ValueList { + checkEnumFieldValue(globals, header, v, inputCell) } + + } else { + checkEnumFieldValue(globals, header, inputCell.Value, inputCell) } } @@ -52,6 +48,11 @@ func checkEnumValue(globals *model.Globals) { // 检查枚举值是否存在有效 func checkEnumFieldValue(globals *model.Globals, header *model.HeaderField, value string, inputCell *model.Cell) { + + if inputCell.Value == "" { + return + } + enumValue := globals.Types.GetEnumValue(header.TypeInfo.FieldType, value) if enumValue == nil { report.ReportError("UnknownEnumValue", header.TypeInfo.FieldType, inputCell.String()) diff --git a/v3/checker/entry.go b/v3/checker/entry.go index 9388cbec..f9392ed5 100644 --- a/v3/checker/entry.go +++ b/v3/checker/entry.go @@ -1,8 +1,53 @@ package checker -import "github.com/davyxu/tabtoy/v3/model" +import ( + "github.com/davyxu/tabtoy/v3/model" + "github.com/davyxu/tabtoy/v3/report" +) -func CheckData(globals *model.Globals) { +func PreCheck(dataList *model.DataTableList) { + + type ArrayFieldDefine struct { + FieldName string + ObjectName string + } + + fieldCountByField := map[ArrayFieldDefine]int{} + + // 合并前的数据表 + for _, tab := range dataList.AllTables() { + + // 遍历输入数据的每一列 + for _, header := range tab.Headers { + + // 输入的列头,为空表示改列被注释 + if header.TypeInfo == nil { + continue + } + + fieldKey := ArrayFieldDefine{ + FieldName: header.TypeInfo.FieldName, + ObjectName: header.TypeInfo.Name, + } + + if header.TypeInfo.IsArray() { + arrayFieldCount := tab.ArrayFieldCount(header) + if preFieldCount, ok := fieldCountByField[fieldKey]; ok { + + if preFieldCount != arrayFieldCount { + report.ReportError("ArrayMultiColumnDefineNotMatch") + } + } else { + fieldCountByField[fieldKey] = arrayFieldCount + } + } + + } + } +} + +// merge后检查 +func PostCheck(globals *model.Globals) { checkEnumValue(globals) checkRepeat(globals) diff --git a/v3/compiler/flow.go b/v3/compiler/flow.go index 87a1e63e..812d77c6 100644 --- a/v3/compiler/flow.go +++ b/v3/compiler/flow.go @@ -57,6 +57,7 @@ func Compile(globals *model.Globals) (ret error) { report.Log.Debugln("Checking types...") checker.CheckType(globals.Types) + checker.PreCheck(&dataList) if kvList.Count() > 0 { report.Log.Debugln("Merge key-value tables...") @@ -77,7 +78,7 @@ func Compile(globals *model.Globals) (ret error) { // 合并所有的数据表 MergeData(&dataList, &globals.Datas, globals.Types) - checker.CheckData(globals) + checker.PostCheck(globals) return nil } diff --git a/v3/compiler/merge.go b/v3/compiler/merge.go index a0fd9ecb..fff9ee64 100644 --- a/v3/compiler/merge.go +++ b/v3/compiler/merge.go @@ -3,6 +3,7 @@ package compiler import ( "github.com/davyxu/tabtoy/v3/model" "github.com/davyxu/tabtoy/v3/report" + "strings" ) func createOutputTable(symbols *model.TypeTable, inputTab *model.DataTable) *model.DataTable { @@ -114,23 +115,20 @@ func MergeData(inputList, outputList *model.DataTableList, symbols *model.TypeTa func combineRepeatedCell(outputCell, inputCell *model.Cell, inputHeader *model.HeaderField, inputTab *model.DataTable) { - spliter := inputHeader.TypeInfo.ArraySplitter + // 数组列, 单列情况 + if inputTab.ArrayFieldCount(inputHeader) == 1 { - if inputTab.RepeatedFieldIndex(inputHeader) > 0 { - - if outputCell.Value != "" || model.LanguagePrimitive(inputHeader.TypeInfo.FieldType, "go") == "string" { - outputCell.Value += spliter + // 不为空时, 切割值为数组 + if inputCell.Value != "" { + for _, element := range strings.Split(inputCell.Value, inputHeader.TypeInfo.ArraySplitter) { + outputCell.ValueList = append(outputCell.ValueList, element) + } } - } - var inputValue string - if inputCell.Value == "" { - inputValue = model.FetchDefaultValue(inputHeader.TypeInfo.FieldType) } else { - inputValue = inputCell.Value - } - // 将多个列中的数值合并到最终单元格的值中, Spliter分割, 分割过程在每种数据gen中处理 - outputCell.Value += inputValue + // 数组列, 多列情况, 每列添加到单元格 + outputCell.ValueList = append(outputCell.ValueList, inputCell.Value) + } } diff --git a/v3/example/csharp/TabtoyExample/table_gen.cs b/v3/example/csharp/TabtoyExample/table_gen.cs index c7a3f8f7..65dda9a4 100644 --- a/v3/example/csharp/TabtoyExample/table_gen.cs +++ b/v3/example/csharp/TabtoyExample/table_gen.cs @@ -1,6 +1,6 @@ // Generated by github.com/davyxu/tabtoy // DO NOT EDIT!! -// Version: 3.0.1 +// Version: 3.0.0 using System; using System.Collections.Generic; @@ -22,6 +22,8 @@ public partial class ExampleData : tabtoy.ITableSerializable public float Rate = 0; public ActorType Type = ActorType.None; public List Skill = new List(); + public Int32 Buff = 0; + public List TagList = new List(); public List Multi = new List(); #region Deserialize Code @@ -57,7 +59,17 @@ public void Deserialize( tabtoy.TableReader reader ) reader.ReadInt32( ref Skill ); } break; - case 0x660005: + case 0x20005: + { + reader.ReadInt32( ref Buff ); + } + break; + case 0x6c0006: + { + reader.ReadString( ref TagList ); + } + break; + case 0x660007: { reader.ReadInt32( ref Multi ); } @@ -73,6 +85,34 @@ public void Deserialize( tabtoy.TableReader reader ) #endregion } + public partial class ExtendData : tabtoy.ITableSerializable + { + public float Additive = 0; + + #region Deserialize Code + public void Deserialize( tabtoy.TableReader reader ) + { + UInt32 mamaSaidTagNameShouldBeLong = 0; + while ( reader.ReadTag(ref mamaSaidTagNameShouldBeLong) ) + { + switch (mamaSaidTagNameShouldBeLong) + { + case 0x70000: + { + reader.ReadFloat( ref Additive ); + } + break; + default: + { + reader.SkipFiled(mamaSaidTagNameShouldBeLong); + } + break; + } + } + } + #endregion + } + public partial class ExampleKV : tabtoy.ITableSerializable { public string ServerIP = string.Empty; @@ -119,6 +159,8 @@ public partial class Table { // table: ExampleData public List ExampleData = new List(); + // table: ExtendData + public List ExtendData = new List(); // table: ExampleKV public List ExampleKV = new List(); @@ -135,6 +177,7 @@ public ExampleKV GetKeyValue_ExampleKV() public void ResetData( ) { ExampleData.Clear(); + ExtendData.Clear(); ExampleKV.Clear(); ExampleDataByID.Clear(); } @@ -157,6 +200,11 @@ public void Deserialize( tabtoy.TableReader reader ) reader.ReadStruct(ref ExampleData); } break; + case "ExtendData": + { + reader.ReadStruct(ref ExtendData); + } + break; case "ExampleKV": { reader.ReadStruct(ref ExampleKV); diff --git a/v3/example/csv/Data.csv b/v3/example/csv/Data.csv index 385fdeea..47727ff9 100644 --- a/v3/example/csv/Data.csv +++ b/v3/example/csv/Data.csv @@ -1,3 +1,14 @@ -ID,,,б,,б,б,, -100,,3.14,3,,1,2,1|2,3 -200,Ŭ˹,1.2,100,Genji,,90,4, +ID,,,б,,б,б,,,, +100,,3.14,3,,1,2,100,a|b,1,3 +200,Ŭ˹,1.2,100,,,90,1,c,4, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, diff --git a/v3/example/csv/Data2.csv b/v3/example/csv/Data2.csv index 84025595..be7bbb75 100644 --- a/v3/example/csv/Data2.csv +++ b/v3/example/csv/Data2.csv @@ -1,14 +1,14 @@ -ID,,,,б -300,,79.4,Դ, -400,߶,0.63,ʹ, -,,,, -,,,, -,,,, -,,,, -,,,, -,,,, -,,,, -,,,, -,,,, -,,,, -,,,, +ID,,, +300,,79.4,Դ +400,߶,0.63,ʹ +,,, +,,, +,,, +,,, +,,, +,,, +,,, +,,, +,,, +,,, +,,, diff --git a/v3/example/csv/Extend.csv b/v3/example/csv/Extend.csv new file mode 100644 index 00000000..2a472f95 --- /dev/null +++ b/v3/example/csv/Extend.csv @@ -0,0 +1,14 @@ + +1.1 +1.2 + + + + + + + + + + + diff --git a/v3/example/csv/Index.csv b/v3/example/csv/Index.csv index a8fa5aa4..efdfda5c 100644 --- a/v3/example/csv/Index.csv +++ b/v3/example/csv/Index.csv @@ -4,3 +4,4 @@ ֵ,ExampleKV,KV2.csv,n ݱ,ExampleData,Data.csv, ݱ,ExampleData,Data2.csv, +ݱ,ExtendData,Extend.csv, diff --git a/v3/example/csv/Run.sh b/v3/example/csv/Run.sh index 444afd0c..42e3c414 100644 --- a/v3/example/csv/Run.sh +++ b/v3/example/csv/Run.sh @@ -16,6 +16,12 @@ go build -v -o ./tabtoy github.com/davyxu/tabtoy -java_out=../java/src/main/java/main/Table.java \ -package=main + +if [[ $? -ne 0 ]] ; then + read -rsp $'Errors occurred...\n' ; + exit 1 +fi + cp ../json/table_gen.json ../java/cfg rm -f tabtoy \ No newline at end of file diff --git a/v3/example/csv/Type.csv b/v3/example/csv/Type.csv index ed5afb2f..1c4d9b0c 100644 --- a/v3/example/csv/Type.csv +++ b/v3/example/csv/Type.csv @@ -1,12 +1,17 @@ -,,ʶ,ֶ,ֶ,и,ֵ,, -ͷ,ExampleData,ID,ID,int,,,, -ͷ,ExampleData,,Name,string,,,,a|b -ͷ,ExampleData,,Rate,float,,,,c -ͷ,ExampleData,,Type,ActorType,,,, -ͷ,ExampleData,б,Skill,int,|,,, -ͷ,ExampleData,,Multi,int,|,,, -ö,ActorType,,None,int,,0,, -ö,ActorType,,Pharah,int,,1,,k|n -ö,ActorType,,Junkrat,int,,2,,e -ö,ActorType,Դ,Genji,int,,3,, -ö,ActorType,ʹ,Mercy,int,,4,, +,,ʶ,ֶ,ֶ,и,ֵ,,,, +ͷ,ExampleData,ID,ID,int,,,,,, +ͷ,ExampleData,,Name,string,,,,,, +ͷ,ExampleData,,Rate,float,,,,,, +ͷ,ExampleData,,Type,ActorType,,,,,, +ͷ,ExampleData,б,Skill,int,|,,,,, +ͷ,ExampleData,,Buff,int,,,,ֶڲԶ,, +ͷ,ExampleData,,TagList,string,|,,,,, +ͷ,ExampleData,,Multi,int,|,,,,, +ö,ActorType,,None,int,,0,,,, +ö,ActorType,,Pharah,int,,1,,,, +ö,ActorType,,Junkrat,int,,2,,,, +ö,ActorType,Դ,Genji,int,,3,,,, +ö,ActorType,ʹ,Mercy,int,,4,,,, +ͷ,ExtendData,,Additive,float,,,,ֶڲԶ,, +,,,,,,,,,, +,,,,,,,,,, diff --git a/v3/example/golang/table_gen.go b/v3/example/golang/table_gen.go index 4e8edd54..2d77b95b 100644 --- a/v3/example/golang/table_gen.go +++ b/v3/example/golang/table_gen.go @@ -1,6 +1,6 @@ // Generated by github.com/davyxu/tabtoy // DO NOT EDIT!! -// Version: 3.0.1 +// Version: 3.0.0 package main type TableEnumValue struct { @@ -36,12 +36,18 @@ func (self ActorType) String() string { } type ExampleData struct { - ID int32 `tb_name:"任务ID"` - Name string `tb_name:"名称"` - Rate float32 `tb_name:"比例"` - Type ActorType `tb_name:"类型"` - Skill []int32 `tb_name:"技能列表"` - Multi []int32 `tb_name:"多列"` + ID int32 `tb_name:"任务ID"` + Name string `tb_name:"名称"` + Rate float32 `tb_name:"比例"` + Type ActorType `tb_name:"类型"` + Skill []int32 `tb_name:"技能列表"` + Buff int32 `tb_name:"增益"` + TagList []string `tb_name:"标记"` + Multi []int32 `tb_name:"多列"` +} + +type ExtendData struct { + Additive float32 `tb_name:"附加"` } type ExampleKV struct { @@ -53,6 +59,7 @@ type ExampleKV struct { // Combine struct type Table struct { ExampleData []*ExampleData // table: ExampleData + ExtendData []*ExtendData // table: ExtendData ExampleKV []*ExampleKV // table: ExampleKV // Indices @@ -98,6 +105,7 @@ func (self *Table) ResetData() error { } self.ExampleData = self.ExampleData[0:0] + self.ExtendData = self.ExtendData[0:0] self.ExampleKV = self.ExampleKV[0:0] self.ExampleDataByID = map[int32]*ExampleData{} diff --git a/v3/example/java/cfg/table_gen.json b/v3/example/java/cfg/table_gen.json index 55d244bf..438d14e9 100644 --- a/v3/example/java/cfg/table_gen.json +++ b/v3/example/java/cfg/table_gen.json @@ -1,11 +1,15 @@ { "@Tool": "github.com/davyxu/tabtoy", - "@Version": "3.0.1", + "@Version": "3.0.0", "ExampleData":[ - { "ID": 100, "Name": "扎克镇", "Rate": 3.14, "Type": 2, "Skill": [3,1,2], "Multi": [1,2,3] }, - { "ID": 200, "Name": "阿努比斯神庙", "Rate": 1.2, "Type": 3, "Skill": [100,0,90], "Multi": [4,0] }, - { "ID": 300, "Name": "花村", "Rate": 79.4, "Type": 3, "Skill": [0], "Multi": [] }, - { "ID": 400, "Name": "艾兴瓦尔德", "Rate": 0.63, "Type": 4, "Skill": [0], "Multi": [] } + { "ID": 100, "Name": "扎克镇", "Rate": 3.14, "Type": 2, "Skill": [3,1,2], "Buff": 100, "TagList": ["a","b"], "Multi": [1,3] }, + { "ID": 200, "Name": "阿努比斯神庙", "Rate": 1.2, "Type": 1, "Skill": [100,0,90], "Buff": 1, "TagList": ["c"], "Multi": [4,0] }, + { "ID": 300, "Name": "花村", "Rate": 79.4, "Type": 3, "Skill": [], "Buff": 0, "TagList": [], "Multi": [] }, + { "ID": 400, "Name": "艾兴瓦尔德", "Rate": 0.63, "Type": 4, "Skill": [], "Buff": 0, "TagList": [], "Multi": [] } + ], + "ExtendData":[ + { "Additive": 1.1 }, + { "Additive": 1.2 } ], "ExampleKV":[ { "ServerIP": "8.8.8.8", "ServerPort": 1024, "GroupID": [10,20] } diff --git a/v3/example/java/src/main/java/main/Table.java b/v3/example/java/src/main/java/main/Table.java index 172b5a79..8971a138 100644 --- a/v3/example/java/src/main/java/main/Table.java +++ b/v3/example/java/src/main/java/main/Table.java @@ -1,6 +1,6 @@ // Generated by github.com/davyxu/tabtoy // DO NOT EDIT!! -// Version: 3.0.1 +// Version: 3.0.0 package main; import java.util.ArrayList; import java.util.HashMap; @@ -50,9 +50,15 @@ public class ExampleData { public float Rate = 0; // 比例; public ActorType Type = ActorType.None; // 类型; public int[] Skill = new int[]{}; // 技能列表; + public int Buff = 0; // 增益; + public String[] TagList = new String[]{}; // 标记; public int[] Multi = new int[]{}; // 多列; } + public class ExtendData { + public float Additive = 0; // 附加; + } + public class ExampleKV { public String ServerIP = ""; // 服务器IP; public int ServerPort = 0; // 服务器端口; @@ -61,6 +67,7 @@ public class ExampleKV { public List ExampleData = new ArrayList<>(); // table: ExampleData + public List ExtendData = new ArrayList<>(); // table: ExtendData public List ExampleKV = new ArrayList<>(); // table: ExampleKV // Indices @@ -91,6 +98,7 @@ public void ResetData() { } ExampleData.clear(); + ExtendData.clear(); ExampleKV.clear(); ExampleDataByID.clear(); diff --git a/v3/example/json/table_gen.json b/v3/example/json/table_gen.json index 55d244bf..438d14e9 100644 --- a/v3/example/json/table_gen.json +++ b/v3/example/json/table_gen.json @@ -1,11 +1,15 @@ { "@Tool": "github.com/davyxu/tabtoy", - "@Version": "3.0.1", + "@Version": "3.0.0", "ExampleData":[ - { "ID": 100, "Name": "扎克镇", "Rate": 3.14, "Type": 2, "Skill": [3,1,2], "Multi": [1,2,3] }, - { "ID": 200, "Name": "阿努比斯神庙", "Rate": 1.2, "Type": 3, "Skill": [100,0,90], "Multi": [4,0] }, - { "ID": 300, "Name": "花村", "Rate": 79.4, "Type": 3, "Skill": [0], "Multi": [] }, - { "ID": 400, "Name": "艾兴瓦尔德", "Rate": 0.63, "Type": 4, "Skill": [0], "Multi": [] } + { "ID": 100, "Name": "扎克镇", "Rate": 3.14, "Type": 2, "Skill": [3,1,2], "Buff": 100, "TagList": ["a","b"], "Multi": [1,3] }, + { "ID": 200, "Name": "阿努比斯神庙", "Rate": 1.2, "Type": 1, "Skill": [100,0,90], "Buff": 1, "TagList": ["c"], "Multi": [4,0] }, + { "ID": 300, "Name": "花村", "Rate": 79.4, "Type": 3, "Skill": [], "Buff": 0, "TagList": [], "Multi": [] }, + { "ID": 400, "Name": "艾兴瓦尔德", "Rate": 0.63, "Type": 4, "Skill": [], "Buff": 0, "TagList": [], "Multi": [] } + ], + "ExtendData":[ + { "Additive": 1.1 }, + { "Additive": 1.2 } ], "ExampleKV":[ { "ServerIP": "8.8.8.8", "ServerPort": 1024, "GroupID": [10,20] } diff --git a/v3/example/jsontype/type_gen.json b/v3/example/jsontype/type_gen.json index e2933ca8..57e243d1 100644 --- a/v3/example/jsontype/type_gen.json +++ b/v3/example/jsontype/type_gen.json @@ -1,6 +1,6 @@ { "@Tool": "github.com/davyxu/tabtoy", - "@Version": "3.0.1", + "@Version": "3.0.0", "Objects": [ { "Name": "ActorType", @@ -16,20 +16,13 @@ "Name": "Pharah", "Type": "int", "Comment": "法鸡", - "Value": "1", - "Tags": [ - "k", - "n" - ] + "Value": "1" }, { "Name": "Junkrat", "Type": "int", "Comment": "狂鼠", - "Value": "2", - "Tags": [ - "e" - ] + "Value": "2" }, { "Name": "Genji", @@ -58,19 +51,12 @@ { "Name": "Name", "Type": "string", - "Comment": "名称", - "Tags": [ - "a", - "b" - ] + "Comment": "名称" }, { "Name": "Rate", "Type": "float", - "Comment": "比例", - "Tags": [ - "c" - ] + "Comment": "比例" }, { "Name": "Type", @@ -83,6 +69,17 @@ "Comment": "技能列表", "ArraySplitter": "|" }, + { + "Name": "Buff", + "Type": "int", + "Comment": "增益" + }, + { + "Name": "TagList", + "Type": "string", + "Comment": "标记", + "ArraySplitter": "|" + }, { "Name": "Multi", "Type": "int", @@ -103,19 +100,12 @@ { "Name": "ServerIP", "Type": "string", - "Comment": "服务器IP", - "Tags": [ - "e", - "f" - ] + "Comment": "服务器IP" }, { "Name": "ServerPort", "Type": "uint16", - "Comment": "服务器端口", - "Tags": [ - "g" - ] + "Comment": "服务器端口" }, { "Name": "GroupID", @@ -124,6 +114,17 @@ "ArraySplitter": ";" } ] + }, + { + "Name": "ExtendData", + "Type": "Struct", + "Fields": [ + { + "Name": "Additive", + "Type": "float", + "Comment": "附加" + } + ] } ] } \ No newline at end of file diff --git a/v3/example/lua/table_gen.lua b/v3/example/lua/table_gen.lua index 7000adbb..5b39a265 100644 --- a/v3/example/lua/table_gen.lua +++ b/v3/example/lua/table_gen.lua @@ -1,14 +1,18 @@ -- Generated by github.com/davyxu/tabtoy --- Version: 3.0.1 +-- Version: 3.0.0 local tab = { ExampleData = { - { ID = 100, Name = "扎克镇", Rate = 3.14, Type = 2, Skill = {3,1,2}, Multi = {1,2,3}, }, - { ID = 200, Name = "阿努比斯神庙", Rate = 1.2, Type = 3, Skill = {100,0,90}, Multi = {4,0}, }, - { ID = 300, Name = "花村", Rate = 79.4, Type = 3, Skill = {0}, Multi = {}, }, - { ID = 400, Name = "艾兴瓦尔德", Rate = 0.63, Type = 4, Skill = {0}, Multi = {}, }, + { ID = 100, Name = "扎克镇", Rate = 3.14, Type = 2, Skill = [3,1,2], Buff = 100, TagList = ["a","b"], Multi = [1,3], }, + { ID = 200, Name = "阿努比斯神庙", Rate = 1.2, Type = 1, Skill = [100,0,90], Buff = 1, TagList = ["c"], Multi = [4,0], }, + { ID = 300, Name = "花村", Rate = 79.4, Type = 3, Skill = [], Buff = 0, TagList = [], Multi = [], }, + { ID = 400, Name = "艾兴瓦尔德", Rate = 0.63, Type = 4, Skill = [], Buff = 0, TagList = [], Multi = [], }, + }, + ExtendData = { + { Additive = 1.1, }, + { Additive = 1.2, }, }, ExampleKV = { - { ServerIP = "8.8.8.8", ServerPort = 1024, GroupID = {10,20}, }, + { ServerIP = "8.8.8.8", ServerPort = 1024, GroupID = [10,20], }, }, } diff --git a/v3/example/xlsx/Data.xlsx b/v3/example/xlsx/Data.xlsx index a3cd8aac..1ff64299 100644 Binary files a/v3/example/xlsx/Data.xlsx and b/v3/example/xlsx/Data.xlsx differ diff --git a/v3/example/xlsx/Data2.xlsx b/v3/example/xlsx/Data2.xlsx index 064f4c2f..f20febca 100644 Binary files a/v3/example/xlsx/Data2.xlsx and b/v3/example/xlsx/Data2.xlsx differ diff --git a/v3/example/xlsx/Index.xlsx b/v3/example/xlsx/Index.xlsx index 8a2c6894..c9977c25 100644 Binary files a/v3/example/xlsx/Index.xlsx and b/v3/example/xlsx/Index.xlsx differ diff --git a/v3/example/xlsx/KV.xlsx b/v3/example/xlsx/KV.xlsx index 4117a35e..02971e47 100644 Binary files a/v3/example/xlsx/KV.xlsx and b/v3/example/xlsx/KV.xlsx differ diff --git a/v3/example/xlsx/Run.sh b/v3/example/xlsx/Run.sh index 1679feb5..7e4b7ee5 100755 --- a/v3/example/xlsx/Run.sh +++ b/v3/example/xlsx/Run.sh @@ -15,6 +15,11 @@ go build -v -o ./tabtoy github.com/davyxu/tabtoy -java_out=../java/src/main/java/main/Table.java \ -package=main +if [ $? -ne 0 ] ; then + read -rsp $'Errors occurred...\n' ; + exit 1 +fi + cp ../json/table_gen.json ../java/cfg rm -f tabtoy \ No newline at end of file diff --git a/v3/example/xlsx/Type.xlsx b/v3/example/xlsx/Type.xlsx index 866ed986..cc9be9d7 100644 Binary files a/v3/example/xlsx/Type.xlsx and b/v3/example/xlsx/Type.xlsx differ diff --git a/v3/gen/bindata/struct.go b/v3/gen/bindata/struct.go index 2df5f05c..008fb807 100644 --- a/v3/gen/bindata/struct.go +++ b/v3/gen/bindata/struct.go @@ -2,7 +2,6 @@ package bindata import ( "github.com/davyxu/tabtoy/v3/model" - "strings" ) // 写入表的一行 @@ -28,7 +27,7 @@ func writeStruct(globals *model.Globals, tab *model.DataTable, row int) (*Binary // 写入字段 if header.TypeInfo.IsArray() { - for _, elementValue := range strings.Split(cell.Value, header.TypeInfo.ArraySplitter) { + for _, elementValue := range cell.ValueList { if err := writePair(globals, structWriter, header.TypeInfo, goType, elementValue, header.Cell.Col); err != nil { return nil, err diff --git a/v3/gen/jsondata/func.go b/v3/gen/jsondata/func.go index ca55fdcf..04035100 100644 --- a/v3/gen/jsondata/func.go +++ b/v3/gen/jsondata/func.go @@ -9,15 +9,14 @@ import ( var UsefulFunc = template.FuncMap{} -func WrapValue(globals *model.Globals, value string, valueType *model.TypeDefine) string { +func WrapValue(globals *model.Globals, cell *model.Cell, valueType *model.TypeDefine) string { if valueType.IsArray() { var sb strings.Builder sb.WriteString("[") - // 空的单元格,导出空数组,除非强制指定填充默认值 - if value != "" { - for index, elementValue := range strings.Split(value, valueType.ArraySplitter) { + if cell != nil { + for index, elementValue := range cell.ValueList { if index > 0 { sb.WriteString(",") } @@ -30,6 +29,12 @@ func WrapValue(globals *model.Globals, value string, valueType *model.TypeDefine return sb.String() } else { + + var value string + if cell != nil { + value = cell.Value + } + return gen.WrapSingleValue(globals, valueType, value) } } @@ -49,10 +54,10 @@ func init() { if valueCell != nil { - return WrapValue(globals, valueCell.Value, header) + return WrapValue(globals, valueCell, header) } else { // 这个表中没有这列数据 - return WrapValue(globals, "", header) + return WrapValue(globals, nil, header) } } diff --git a/v3/gen/jsondata2/gen.go b/v3/gen/jsondata2/gen.go index 872882f5..44160c03 100644 --- a/v3/gen/jsondata2/gen.go +++ b/v3/gen/jsondata2/gen.go @@ -5,16 +5,16 @@ import ( "github.com/davyxu/tabtoy/util" "github.com/davyxu/tabtoy/v3/model" "strconv" - "strings" ) -func wrapValue(globals *model.Globals, value string, valueType *model.TypeDefine) interface{} { +func wrapValue(globals *model.Globals, valueCell *model.Cell, valueType *model.TypeDefine) interface{} { if valueType.IsArray() { var vlist = make([]interface{}, 0) // 空的单元格,导出空数组,除非强制指定填充默认值 - if value != "" { - for _, elementValue := range strings.Split(value, valueType.ArraySplitter) { + if valueCell != nil { + + for _, elementValue := range valueCell.ValueList { vlist = append(vlist, wrapSingleValue(globals, valueType, elementValue)) } @@ -23,6 +23,12 @@ func wrapValue(globals *model.Globals, value string, valueType *model.TypeDefine return vlist } else { + + var value string + if valueCell != nil { + value = valueCell.Value + } + return wrapSingleValue(globals, valueType, value) } } @@ -110,14 +116,7 @@ func Generate(globals *model.Globals) (data []byte, err error) { // 在单元格找到值 valueCell := tab.GetCell(row, col) - var value interface{} - if valueCell != nil { - - value = wrapValue(globals, valueCell.Value, header) - } else { - // 这个表中没有这列数据 - value = wrapValue(globals, "", header) - } + var value = wrapValue(globals, valueCell, header) rowData[header.FieldName] = value } diff --git a/v3/gen/luasrc/func.go b/v3/gen/luasrc/func.go index dde48024..3c532bc9 100644 --- a/v3/gen/luasrc/func.go +++ b/v3/gen/luasrc/func.go @@ -9,15 +9,14 @@ import ( var UsefulFunc = template.FuncMap{} -func WrapValue(globals *model.Globals, value string, valueType *model.TypeDefine) string { +func WrapValue(globals *model.Globals, cell *model.Cell, valueType *model.TypeDefine) string { if valueType.IsArray() { var sb strings.Builder - sb.WriteString("{") + sb.WriteString("[") - // 空的单元格,导出空数组,除非强制指定填充默认值 - if value != "" { - for index, elementValue := range strings.Split(value, valueType.ArraySplitter) { + if cell != nil { + for index, elementValue := range cell.ValueList { if index > 0 { sb.WriteString(",") } @@ -25,15 +24,19 @@ func WrapValue(globals *model.Globals, value string, valueType *model.TypeDefine } } - sb.WriteString("}") + sb.WriteString("]") return sb.String() } else { + + var value string + if cell != nil { + value = cell.Value + } + return gen.WrapSingleValue(globals, valueType, value) } - - return value } func init() { @@ -51,10 +54,10 @@ func init() { if valueCell != nil { - return WrapValue(globals, valueCell.Value, header) + return WrapValue(globals, valueCell, header) } else { // 这个表中没有这列数据 - return WrapValue(globals, "", header) + return WrapValue(globals, nil, header) } } diff --git a/v3/model/cell.go b/v3/model/cell.go index 2d465359..dccf46ca 100644 --- a/v3/model/cell.go +++ b/v3/model/cell.go @@ -6,10 +6,11 @@ import ( ) type Cell struct { - Value string - Row int // base 0 - Col int // base 0 - Table *DataTable + Value string + ValueList []string // merge之后, 数组值保存在这里 + Row int // base 0 + Col int // base 0 + Table *DataTable } // 全拷贝 @@ -28,5 +29,12 @@ func (self *Cell) String() string { sheet = self.Table.SheetName } - return fmt.Sprintf("'%s' @%s|%s(%s)", self.Value, file, sheet, util.R1C1ToA1(self.Row+1, self.Col+1)) + var value string + if len(self.ValueList) > 0 { + value = fmt.Sprintf("%+v", self.ValueList) + } else { + value = self.Value + } + + return fmt.Sprintf("'%s' @%s|%s(%s)", value, file, sheet, util.R1C1ToA1(self.Row+1, self.Col+1)) } diff --git a/v3/model/datatab.go b/v3/model/datatab.go index 3cb21b91..8db332fd 100644 --- a/v3/model/datatab.go +++ b/v3/model/datatab.go @@ -20,27 +20,11 @@ type DataTable struct { Headers []*HeaderField } -// 重复列在表中数量, 重复列可以将数组拆在多个列中填写 -func (self *DataTable) RepeatedFieldCount(field *HeaderField) (ret int) { - - for _, hf := range self.Headers { - if hf.TypeInfo == field.TypeInfo { - ret++ - } - } - - return -} - // 重复列在表中的索引, 相对于重复列的数量 -func (self *DataTable) RepeatedFieldIndex(field *HeaderField) (ret int) { +func (self *DataTable) ArrayFieldCount(field *HeaderField) (ret int) { for _, hf := range self.Headers { - if hf.TypeInfo == field.TypeInfo { - - if hf == field { - break - } + if hf.TypeInfo != nil && hf.TypeInfo.FieldName == field.TypeInfo.FieldName { ret++ } diff --git a/v3/report/errid.go b/v3/report/errid.go index e645f893..0cbb1841 100644 --- a/v3/report/errid.go +++ b/v3/report/errid.go @@ -6,19 +6,20 @@ type ErrorLanguage struct { var ( ErrorByID = map[string]*ErrorLanguage{ - "HeaderNotMatchFieldName": {CHS: "表头与字段不匹配"}, - "HeaderFieldNotDefined": {CHS: "表头字段未定义"}, - "DuplicateHeaderField": {CHS: "表头字段重复"}, - "DuplicateKVField": {CHS: "键值表字段重复"}, - "UnknownFieldType": {CHS: "未知字段类型"}, - "DuplicateTypeFieldName": {CHS: "类型表字段重复"}, - "EnumValueEmpty": {CHS: "枚举值空"}, - "DuplicateEnumValue": {CHS: "枚举值重复"}, - "UnknownEnumValue": {CHS: "未知的枚举值"}, - "InvalidTypeTable": {CHS: "非法的类型表"}, - "HeaderTypeNotFound": {CHS: "表头类型找不到"}, - "DuplicateValueInMakingIndex": {CHS: "创建索引时发现重复值"}, - "UnknownInputFileExtension": {CHS: "未知的输入文件扩展名"}, - "DataMissMatchTypeDefine": {CHS: "数据与定义类型不匹配"}, + "HeaderNotMatchFieldName": {CHS: "表头与字段不匹配"}, + "HeaderFieldNotDefined": {CHS: "表头字段未定义"}, + "DuplicateHeaderField": {CHS: "表头字段重复"}, + "DuplicateKVField": {CHS: "键值表字段重复"}, + "UnknownFieldType": {CHS: "未知字段类型"}, + "DuplicateTypeFieldName": {CHS: "类型表字段重复"}, + "EnumValueEmpty": {CHS: "枚举值空"}, + "DuplicateEnumValue": {CHS: "枚举值重复"}, + "UnknownEnumValue": {CHS: "未知的枚举值"}, + "InvalidTypeTable": {CHS: "非法的类型表"}, + "HeaderTypeNotFound": {CHS: "表头类型找不到"}, + "DuplicateValueInMakingIndex": {CHS: "创建索引时发现重复值"}, + "UnknownInputFileExtension": {CHS: "未知的输入文件扩展名"}, + "DataMissMatchTypeDefine": {CHS: "数据与定义类型不匹配"}, + "ArrayMultiColumnDefineNotMatch": {CHS: "数组类型多列跨表定义不一致"}, } ) diff --git a/v3/tests/data_test.go b/v3/tests/data_test.go index 84d8f053..409158d7 100644 --- a/v3/tests/data_test.go +++ b/v3/tests/data_test.go @@ -71,35 +71,72 @@ func TestArrayList(t *testing.T) { helper.WriteIndexTableHeader(indexSheet) helper.WriteRowValues(indexSheet, "类型表", "", "Type") - helper.WriteRowValues(indexSheet, "数据表", "", "TestData") + helper.WriteRowValues(indexSheet, "数据表", "TestData", "TestData") + helper.WriteRowValues(indexSheet, "数据表", "TestData", "TestData2") typeSheet := emu.CreateCSVFile("Type") helper.WriteTypeTableHeader(typeSheet) helper.WriteRowValues(typeSheet, "表头", "TestData", "ID", "ID", "int", "", "") helper.WriteRowValues(typeSheet, "表头", "TestData", "技能列表", "SkillList", "int", "|", "") helper.WriteRowValues(typeSheet, "表头", "TestData", "名字列表", "NameList", "string", "|", "") + helper.WriteRowValues(typeSheet, "表头", "TestData", "ID列表", "IDList", "int32", "|", "") // 单列 dataSheet := emu.CreateCSVFile("TestData") - helper.WriteRowValues(dataSheet, "ID", "技能列表", "技能列表", "技能列表", "名字列表", "名字列表") - helper.WriteRowValues(dataSheet, "1", "100", "200", "300", "", "") - helper.WriteRowValues(dataSheet, "2", "1", "", "3", "", "") // 多列数组补0 - helper.WriteRowValues(dataSheet, "3", "", "20", "30", "", "") // 多列数组补0 - helper.WriteRowValues(dataSheet, "4", "", "", "", "", "") // 多列数组补0 + helper.WriteRowValues(dataSheet, "ID", "技能列表", "技能列表", "技能列表", "名字列表", "名字列表", "ID列表") + helper.WriteRowValues(dataSheet, "1", "100", "200", "300", "", "", "") + helper.WriteRowValues(dataSheet, "2", "1", "", "3", "", "", "") // 多列数组补0 + helper.WriteRowValues(dataSheet, "3", "", "20", "30", "", "", "") // 多列数组补0 + helper.WriteRowValues(dataSheet, "4", "", "", "", "", "", "") // 多列数组补0 + + // 数组列多列情况, 又在不同的表中可能存在不同数量列的情况 + dataSheet2 := emu.CreateCSVFile("TestData2") + helper.WriteRowValues(dataSheet2, "ID", "技能列表", "技能列表", "技能列表") + helper.WriteRowValues(dataSheet2, "5", "1", "1") + helper.WriteRowValues(dataSheet2, "6", "2", "1") emu.VerifyData(` { - "@Tool": "github.com/davyxu/tabtoy", - "@Version": "testver", - "TestData":[ - { "ID": 1, "SkillList": [100,200,300], "NameList":["", ""] }, - { "ID": 2, "SkillList": [1,0,3], "NameList":["", ""] }, - { "ID": 3, "SkillList": [0,20,30], "NameList":["", ""] }, - { "ID": 4, "SkillList": [0,0,0], "NameList":["", ""] } - ] - } + "@Tool": "github.com/davyxu/tabtoy", + "@Version": "testver", + "TestData":[ + { "ID": 1, "SkillList": [100,200,300], "NameList": ["",""], "IDList": [] }, + { "ID": 2, "SkillList": [1,0,3], "NameList": ["",""], "IDList": [] }, + { "ID": 3, "SkillList": [0,20,30], "NameList": ["",""], "IDList": [] }, + { "ID": 4, "SkillList": [0,0,0], "NameList": ["",""], "IDList": [] }, + { "ID": 5, "SkillList": [1,1,0], "NameList": [], "IDList": [] }, + { "ID": 6, "SkillList": [2,1,0], "NameList": [], "IDList": [] } + ] + } `) } +func TestArrayMultiColumnDefineNotMatch(t *testing.T) { + emu := NewTableEmulator(t) + indexSheet := emu.CreateCSVFile("Index") + + helper.WriteIndexTableHeader(indexSheet) + helper.WriteRowValues(indexSheet, "类型表", "", "Type") + helper.WriteRowValues(indexSheet, "数据表", "TestData", "TestData") + helper.WriteRowValues(indexSheet, "数据表", "TestData", "TestData2") + + typeSheet := emu.CreateCSVFile("Type") + helper.WriteTypeTableHeader(typeSheet) + helper.WriteRowValues(typeSheet, "表头", "TestData", "ID", "ID", "int", "", "") + helper.WriteRowValues(typeSheet, "表头", "TestData", "技能列表", "SkillList", "int", "|", "") + + dataSheet := emu.CreateCSVFile("TestData") + helper.WriteRowValues(dataSheet, "ID", "技能列表", "技能列表") + helper.WriteRowValues(dataSheet, "1", "100", "200") + + // 数组列多列情况, 又在不同的表中可能存在不同数量列的情况 + dataSheet2 := emu.CreateCSVFile("TestData2") + helper.WriteRowValues(dataSheet2, "ID", "技能列表") + helper.WriteRowValues(dataSheet2, "5", "") + helper.WriteRowValues(dataSheet2, "6", "") + + emu.MustGotError("TableError.ArrayMultiColumnDefineNotMatch 数组类型多列跨表定义不一致 | ") +} + // 重复性检查 func TestRepeatCheck(t *testing.T) { diff --git a/v3/tests/emulator.go b/v3/tests/emulator.go index 4545444f..013798fa 100644 --- a/v3/tests/emulator.go +++ b/v3/tests/emulator.go @@ -5,7 +5,7 @@ import ( "github.com/davyxu/tabtoy/v3/compiler" "github.com/davyxu/tabtoy/v3/gen" "github.com/davyxu/tabtoy/v3/gen/gosrc" - "github.com/davyxu/tabtoy/v3/gen/jsontext" + "github.com/davyxu/tabtoy/v3/gen/jsondata" "github.com/davyxu/tabtoy/v3/helper" "github.com/davyxu/tabtoy/v3/model" "io/ioutil" diff --git a/v3/tests/type_test.go b/v3/tests/type_test.go index 98919902..86358996 100644 --- a/v3/tests/type_test.go +++ b/v3/tests/type_test.go @@ -137,6 +137,39 @@ func TestInvalidEnumValue(t *testing.T) { emu.MustGotError("TableError.UnknownEnumValue 未知的枚举值 | ActorType 'Arch2' @TestData|(A2)") } +// 枚举值为空 +func TestEmptyEnumValue(t *testing.T) { + + emu := NewTableEmulator(t) + indexSheet := emu.CreateCSVFile("Index") + + helper.WriteIndexTableHeader(indexSheet) + helper.WriteRowValues(indexSheet, "类型表", "", "Type") + helper.WriteRowValues(indexSheet, "数据表", "", "TestData") + + typeSheet := emu.CreateCSVFile("Type") + helper.WriteTypeTableHeader(typeSheet) + helper.WriteRowValues(typeSheet, "枚举", "ActorType", "", "None", "int", "", "1") + helper.WriteRowValues(typeSheet, "枚举", "ActorType", "", "Arch", "int", "", "2") + + helper.WriteRowValues(typeSheet, "表头", "TestData", "ID", "ID", "int", "", "") + helper.WriteRowValues(typeSheet, "表头", "TestData", "角色类型", "Type", "ActorType", "", "") + + dataSheet := emu.CreateCSVFile("TestData") + helper.WriteRowValues(dataSheet, "ID", "角色类型") + helper.WriteRowValues(dataSheet, "1", "") + + emu.VerifyData(` +{ + "@Tool": "github.com/davyxu/tabtoy", + "@Version": "testver", + "TestData":[ + { "ID": 1, "Type": 1 } + ] +} +`) +} + func TestBasicType(t *testing.T) { emu := NewTableEmulator(t)