Parse proc annotations and store in Proc struct
This commit is contained in:
parent
5d8cdfc854
commit
3613b30fe2
@ -159,13 +159,41 @@ type Case struct {
|
||||
|
||||
// Proc holds information about a libvirt procedure the parser has found.
|
||||
type Proc struct {
|
||||
Num int64 // The libvirt procedure number.
|
||||
Name string // The name of the go func.
|
||||
LVName string // The name of the libvirt proc this wraps.
|
||||
Args []Decl // The contents of the args struct for this procedure.
|
||||
Ret []Decl // The contents of the ret struct for this procedure.
|
||||
ArgsStruct string // The name of the args struct for this procedure.
|
||||
RetStruct string // The name of the ret struct for this procedure.
|
||||
Num int64 // The libvirt procedure number.
|
||||
Name string // The name of the go func.
|
||||
LVName string // The name of the libvirt proc this wraps.
|
||||
Args []Decl // The contents of the args struct for this procedure.
|
||||
Ret []Decl // The contents of the ret struct for this procedure.
|
||||
ArgsStruct string // The name of the args struct for this procedure.
|
||||
RetStruct string // The name of the ret struct for this procedure.
|
||||
ReadStreamIdx int // The index of read stream in function argument list
|
||||
WriteStreamIdx int // The index of read stream in function argument list
|
||||
}
|
||||
|
||||
type ProcMetaGenerate int
|
||||
|
||||
const (
|
||||
ProcMetaGenerateNone ProcMetaGenerate = iota
|
||||
ProcMetaGenerateClient
|
||||
ProcMetaGenerateServer
|
||||
ProcMetaGenerateBoth
|
||||
)
|
||||
|
||||
type ProcMetaPriority int
|
||||
|
||||
const (
|
||||
ProcMetaPriorityLow ProcMetaPriority = iota
|
||||
ProcMetaPriorityHigh
|
||||
)
|
||||
|
||||
// ProcMeta holds information from annotations attached to a libvirt procedure
|
||||
type ProcMeta struct {
|
||||
Generate ProcMetaGenerate
|
||||
ReadStream int
|
||||
WriteStream int
|
||||
Priority ProcMetaPriority
|
||||
Acls []string
|
||||
Aclfilter string
|
||||
}
|
||||
|
||||
type structStack []*Structure
|
||||
@ -552,7 +580,20 @@ func AddEnumVal(name, val string) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid enum value %v = %v", name, val)
|
||||
}
|
||||
return addEnumVal(name, ev)
|
||||
return addEnumVal(name, ev, nil)
|
||||
}
|
||||
|
||||
// AddEnumValMeta will add a new enum value with attached metadata to the list.
|
||||
func AddEnumValMeta(name, val, meta string) error {
|
||||
ev, err := parseNumber(val)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid enum value %v = %v", name, val)
|
||||
}
|
||||
metaObj, err := parseMeta(meta)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid metadata for enum value %v: %v", name, err)
|
||||
}
|
||||
return addEnumVal(name, ev, metaObj)
|
||||
}
|
||||
|
||||
// AddEnumAutoVal adds an enum to the list, using the automatically-incremented
|
||||
@ -560,14 +601,14 @@ func AddEnumVal(name, val string) error {
|
||||
// explicit value.
|
||||
func AddEnumAutoVal(name string) error {
|
||||
CurrentEnumVal++
|
||||
return addEnumVal(name, CurrentEnumVal)
|
||||
return addEnumVal(name, CurrentEnumVal, nil)
|
||||
}
|
||||
|
||||
func addEnumVal(name string, val int64) error {
|
||||
func addEnumVal(name string, val int64, meta *ProcMeta) error {
|
||||
goname := constNameTransform(name)
|
||||
Gen.EnumVals = append(Gen.EnumVals, ConstItem{goname, name, fmt.Sprintf("%d", val)})
|
||||
CurrentEnumVal = val
|
||||
addProc(goname, name, val)
|
||||
addProc(goname, name, val, meta)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -584,12 +625,16 @@ func AddConst(name, val string) error {
|
||||
|
||||
// addProc checks an enum value to see if it's a procedure number. If so, we
|
||||
// add the procedure to our list for later generation.
|
||||
func addProc(goname, lvname string, val int64) {
|
||||
func addProc(goname, lvname string, val int64, meta *ProcMeta) {
|
||||
if !strings.HasPrefix(goname, "Proc") {
|
||||
return
|
||||
}
|
||||
goname = goname[4:]
|
||||
proc := &Proc{Num: val, Name: goname, LVName: lvname}
|
||||
proc := &Proc{Num: val, Name: goname, LVName: lvname, ReadStreamIdx: -1, WriteStreamIdx: -1}
|
||||
if meta != nil {
|
||||
proc.ReadStreamIdx = meta.ReadStream
|
||||
proc.WriteStreamIdx = meta.WriteStream
|
||||
}
|
||||
Gen.Procs = append(Gen.Procs, *proc)
|
||||
}
|
||||
|
||||
@ -605,6 +650,64 @@ func parseNumber(val string) (int64, error) {
|
||||
return n, err
|
||||
}
|
||||
|
||||
// parseMeta parses procedure metadata to simple string mapping
|
||||
func parseMeta(meta string) (*ProcMeta, error) {
|
||||
res := &ProcMeta{
|
||||
ReadStream: -1,
|
||||
WriteStream: -1,
|
||||
}
|
||||
for _, line := range strings.Split(meta, "\n") {
|
||||
atInd := strings.Index(line, "@")
|
||||
if atInd == -1 {
|
||||
// Should be only first and last line of comment
|
||||
continue
|
||||
}
|
||||
spl := strings.SplitN(line[atInd+1:], ":", 2)
|
||||
if len(spl) != 2 {
|
||||
return nil, fmt.Errorf("invalid annotation: %s", meta)
|
||||
}
|
||||
spl[1] = strings.Trim(spl[1], " ")
|
||||
if spl[0] == "generate" {
|
||||
if spl[1] == "none" {
|
||||
res.Generate = ProcMetaGenerateNone
|
||||
} else if spl[1] == "client" {
|
||||
res.Generate = ProcMetaGenerateClient
|
||||
} else if spl[1] == "server" {
|
||||
res.Generate = ProcMetaGenerateServer
|
||||
} else if spl[1] == "both" {
|
||||
res.Generate = ProcMetaGenerateBoth
|
||||
} else {
|
||||
return nil, fmt.Errorf("invalid value for generate: %s", spl[1])
|
||||
}
|
||||
} else if spl[0] == "readstream" {
|
||||
var err error
|
||||
res.ReadStream, err = strconv.Atoi(spl[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid value for readstread: %s", spl[1])
|
||||
}
|
||||
} else if spl[0] == "writestream" {
|
||||
var err error
|
||||
res.WriteStream, err = strconv.Atoi(spl[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid value for readstread: %s", spl[1])
|
||||
}
|
||||
} else if spl[0] == "priority" {
|
||||
if spl[1] == "low" {
|
||||
res.Priority = ProcMetaPriorityLow
|
||||
} else if spl[1] == "high" {
|
||||
res.Priority = ProcMetaPriorityHigh
|
||||
} else {
|
||||
return nil, fmt.Errorf("invalid value for priority: %s", spl[1])
|
||||
}
|
||||
} else if spl[0] == "acl" {
|
||||
res.Acls = append(res.Acls, spl[1])
|
||||
} else if spl[0] == "aclfilter" {
|
||||
res.Aclfilter = spl[1]
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// StartStruct is called from the parser when a struct definition is found, but
|
||||
// before the member declarations are processed.
|
||||
func StartStruct(name string) {
|
||||
|
@ -101,7 +101,7 @@ enum_value
|
||||
}
|
||||
}
|
||||
| METADATACOMMENT enum_value_ident '=' value {
|
||||
err := AddEnumVal($2.val, $4.val)
|
||||
err := AddEnumValMeta($2.val, $4.val, $1.val)
|
||||
if err != nil {
|
||||
yylex.Error(err.Error())
|
||||
return 1
|
||||
|
@ -606,7 +606,7 @@ yydefault:
|
||||
yyDollar = yyS[yypt-4 : yypt+1]
|
||||
//line sunrpc.y:103
|
||||
{
|
||||
err := AddEnumVal(yyDollar[2].val, yyDollar[4].val)
|
||||
err := AddEnumValMeta(yyDollar[2].val, yyDollar[4].val, yyDollar[1].val)
|
||||
if err != nil {
|
||||
yylex.Error(err.Error())
|
||||
return 1
|
||||
|
Loading…
Reference in New Issue
Block a user