Parse proc annotations and store in Proc struct
This commit is contained in:
parent
5d8cdfc854
commit
3613b30fe2
@ -166,6 +166,34 @@ type Proc struct {
|
|||||||
Ret []Decl // The contents of the ret 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.
|
ArgsStruct string // The name of the args struct for this procedure.
|
||||||
RetStruct string // The name of the ret 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
|
type structStack []*Structure
|
||||||
@ -552,7 +580,20 @@ func AddEnumVal(name, val string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid enum value %v = %v", name, val)
|
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
|
// AddEnumAutoVal adds an enum to the list, using the automatically-incremented
|
||||||
@ -560,14 +601,14 @@ func AddEnumVal(name, val string) error {
|
|||||||
// explicit value.
|
// explicit value.
|
||||||
func AddEnumAutoVal(name string) error {
|
func AddEnumAutoVal(name string) error {
|
||||||
CurrentEnumVal++
|
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)
|
goname := constNameTransform(name)
|
||||||
Gen.EnumVals = append(Gen.EnumVals, ConstItem{goname, name, fmt.Sprintf("%d", val)})
|
Gen.EnumVals = append(Gen.EnumVals, ConstItem{goname, name, fmt.Sprintf("%d", val)})
|
||||||
CurrentEnumVal = val
|
CurrentEnumVal = val
|
||||||
addProc(goname, name, val)
|
addProc(goname, name, val, meta)
|
||||||
return nil
|
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
|
// 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.
|
// 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") {
|
if !strings.HasPrefix(goname, "Proc") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
goname = goname[4:]
|
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)
|
Gen.Procs = append(Gen.Procs, *proc)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,6 +650,64 @@ func parseNumber(val string) (int64, error) {
|
|||||||
return n, err
|
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
|
// StartStruct is called from the parser when a struct definition is found, but
|
||||||
// before the member declarations are processed.
|
// before the member declarations are processed.
|
||||||
func StartStruct(name string) {
|
func StartStruct(name string) {
|
||||||
|
@ -101,7 +101,7 @@ enum_value
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
| METADATACOMMENT enum_value_ident '=' value {
|
| METADATACOMMENT enum_value_ident '=' value {
|
||||||
err := AddEnumVal($2.val, $4.val)
|
err := AddEnumValMeta($2.val, $4.val, $1.val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
yylex.Error(err.Error())
|
yylex.Error(err.Error())
|
||||||
return 1
|
return 1
|
||||||
|
@ -606,7 +606,7 @@ yydefault:
|
|||||||
yyDollar = yyS[yypt-4 : yypt+1]
|
yyDollar = yyS[yypt-4 : yypt+1]
|
||||||
//line sunrpc.y:103
|
//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 {
|
if err != nil {
|
||||||
yylex.Error(err.Error())
|
yylex.Error(err.Error())
|
||||||
return 1
|
return 1
|
||||||
|
Loading…
Reference in New Issue
Block a user