adding quickfix
This commit is contained in:
194
quickfix/cmd/generate-fix/generate-fix.go
Normal file
194
quickfix/cmd/generate-fix/generate-fix.go
Normal file
@ -0,0 +1,194 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"text/template"
|
||||
|
||||
"quantex.com/qfixdpl/quickfix/cmd/generate-fix/internal"
|
||||
"quantex.com/qfixdpl/quickfix/datadictionary"
|
||||
)
|
||||
|
||||
var (
|
||||
waitGroup sync.WaitGroup
|
||||
errors = make(chan error)
|
||||
)
|
||||
|
||||
func usage() {
|
||||
fmt.Fprintf(os.Stderr, "usage: %v [flags] <path to data dictionary> ... \n", os.Args[0])
|
||||
flag.PrintDefaults()
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
func getPackageName(fixSpec *datadictionary.DataDictionary) string {
|
||||
pkg := strings.ToLower(fixSpec.FIXType) + strconv.Itoa(fixSpec.Major) + strconv.Itoa(fixSpec.Minor)
|
||||
|
||||
if fixSpec.ServicePack != 0 {
|
||||
pkg += "sp" + strconv.Itoa(fixSpec.ServicePack)
|
||||
}
|
||||
|
||||
return pkg
|
||||
}
|
||||
|
||||
func getTransportPackageName(fixSpec *datadictionary.DataDictionary) string {
|
||||
if fixSpec.Major >= 5 {
|
||||
return "fixt11"
|
||||
}
|
||||
return getPackageName(fixSpec)
|
||||
}
|
||||
|
||||
type component struct {
|
||||
Package string
|
||||
FIXPackage string
|
||||
TransportPackage string
|
||||
FIXSpec *datadictionary.DataDictionary
|
||||
Name string
|
||||
*datadictionary.MessageDef
|
||||
}
|
||||
|
||||
func genHeader(pkg string, spec *datadictionary.DataDictionary) {
|
||||
c := component{
|
||||
Package: pkg,
|
||||
Name: "Header",
|
||||
MessageDef: spec.Header,
|
||||
FIXSpec: spec,
|
||||
}
|
||||
gen(internal.HeaderTemplate, path.Join(pkg, "header.generated.go"), c)
|
||||
}
|
||||
|
||||
func genTrailer(pkg string, spec *datadictionary.DataDictionary) {
|
||||
c := component{
|
||||
Package: pkg,
|
||||
Name: "Trailer",
|
||||
MessageDef: spec.Trailer,
|
||||
}
|
||||
gen(internal.TrailerTemplate, path.Join(pkg, "trailer.generated.go"), c)
|
||||
}
|
||||
|
||||
func genMessage(fixPkg string, spec *datadictionary.DataDictionary, msg *datadictionary.MessageDef) {
|
||||
pkgName := strings.ToLower(msg.Name)
|
||||
transportPkg := getTransportPackageName(spec)
|
||||
|
||||
c := component{
|
||||
Package: pkgName,
|
||||
FIXPackage: fixPkg,
|
||||
TransportPackage: transportPkg,
|
||||
FIXSpec: spec,
|
||||
Name: msg.Name,
|
||||
MessageDef: msg,
|
||||
}
|
||||
|
||||
gen(internal.MessageTemplate, path.Join(fixPkg, pkgName, msg.Name+".generated.go"), c)
|
||||
}
|
||||
|
||||
func genTags() {
|
||||
gen(internal.TagTemplate, "tag/tag_numbers.generated.go", internal.GlobalFieldTypes)
|
||||
}
|
||||
|
||||
func genFields() {
|
||||
gen(internal.FieldTemplate, "field/fields.generated.go", internal.GlobalFieldTypes)
|
||||
}
|
||||
|
||||
func genEnums() {
|
||||
gen(internal.EnumTemplate, "enum/enums.generated.go", internal.GlobalFieldTypes)
|
||||
}
|
||||
|
||||
func gen(t *template.Template, fileOut string, data interface{}) {
|
||||
defer waitGroup.Done()
|
||||
writer := new(bytes.Buffer)
|
||||
|
||||
if err := t.Execute(writer, data); err != nil {
|
||||
errors <- err
|
||||
return
|
||||
}
|
||||
|
||||
if err := internal.WriteFile(fileOut, writer.String()); err != nil {
|
||||
errors <- err
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
if flag.NArg() < 1 {
|
||||
usage()
|
||||
}
|
||||
|
||||
args := flag.Args()
|
||||
if len(args) == 1 {
|
||||
dictpath := args[0]
|
||||
if strings.Contains(dictpath, "FIX50SP1") {
|
||||
args = append(args, strings.Replace(dictpath, "FIX50SP1", "FIXT11", -1))
|
||||
} else if strings.Contains(dictpath, "FIX50SP2") {
|
||||
args = append(args, strings.Replace(dictpath, "FIX50SP2", "FIXT11", -1))
|
||||
} else if strings.Contains(dictpath, "FIX50") {
|
||||
args = append(args, strings.Replace(dictpath, "FIX50", "FIXT11", -1))
|
||||
}
|
||||
}
|
||||
specs := []*datadictionary.DataDictionary{}
|
||||
|
||||
for _, dataDictPath := range args {
|
||||
spec, err := datadictionary.Parse(dataDictPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Error Parsing %v: %v", dataDictPath, err)
|
||||
}
|
||||
specs = append(specs, spec)
|
||||
}
|
||||
|
||||
internal.BuildGlobalFieldTypes(specs)
|
||||
|
||||
waitGroup.Add(1)
|
||||
go genTags()
|
||||
waitGroup.Add(1)
|
||||
go genFields()
|
||||
waitGroup.Add(1)
|
||||
go genEnums()
|
||||
|
||||
for _, spec := range specs {
|
||||
pkg := getPackageName(spec)
|
||||
|
||||
if fi, err := os.Stat(pkg); os.IsNotExist(err) {
|
||||
if err := os.Mkdir(pkg, os.ModePerm); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else if !fi.IsDir() {
|
||||
log.Fatalf("%v/ is not a directory", pkg)
|
||||
}
|
||||
|
||||
switch pkg {
|
||||
// Uses fixt11 header/trailer.
|
||||
case "fix50", "fix50sp1", "fix50sp2":
|
||||
default:
|
||||
waitGroup.Add(1)
|
||||
go genHeader(pkg, spec)
|
||||
|
||||
waitGroup.Add(1)
|
||||
go genTrailer(pkg, spec)
|
||||
}
|
||||
|
||||
for _, m := range spec.Messages {
|
||||
waitGroup.Add(1)
|
||||
go genMessage(pkg, spec, m)
|
||||
}
|
||||
}
|
||||
|
||||
go func() {
|
||||
waitGroup.Wait()
|
||||
close(errors)
|
||||
}()
|
||||
|
||||
var h internal.ErrorHandler
|
||||
for err := range errors {
|
||||
h.Handle(err)
|
||||
}
|
||||
|
||||
os.Exit(h.ReturnCode)
|
||||
}
|
||||
Reference in New Issue
Block a user