Generate libvirt structs, unions, typedefs.
This commit is contained in:
		| @@ -412,7 +412,7 @@ const ( | |||||||
| 	ProcDomainManagedSaveGetXMLDesc = 388 | 	ProcDomainManagedSaveGetXMLDesc = 388 | ||||||
| 	ProcDomainManagedSaveDefineXML = 389 | 	ProcDomainManagedSaveDefineXML = 389 | ||||||
| 	ProcDomainSetLifecycleAction = 390 | 	ProcDomainSetLifecycleAction = 390 | ||||||
| 	 |  | ||||||
|  |  | ||||||
| 	// From consts: | 	// From consts: | ||||||
| 	StringMax = 4194304 | 	StringMax = 4194304 | ||||||
| @@ -471,5 +471,4 @@ const ( | |||||||
| 	DomainEventGraphicsIdentityMax = 20 | 	DomainEventGraphicsIdentityMax = 20 | ||||||
| 	Program = 0x20008086 | 	Program = 0x20008086 | ||||||
| 	ProtocolVersion = 1 | 	ProtocolVersion = 1 | ||||||
| 	 |  | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -19,10 +19,10 @@ package constants | |||||||
| //	REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207, | //	REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207, | ||||||
| const ( | const ( | ||||||
| 	// From enums: | 	// From enums: | ||||||
| 	{{range .Enums}}{{.Name}} = {{.Val}} | {{range .EnumVals}}	{{.Name}} = {{.Val}} | ||||||
| 	{{end}} | {{end}} | ||||||
|  |  | ||||||
| 	// From consts: | 	// From consts: | ||||||
| 	{{range .Consts}}{{.Name}} = {{.Val}} | {{range .Consts}}	{{.Name}} = {{.Val}} | ||||||
| 	{{end}} | {{end -}} | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -62,10 +62,19 @@ type ConstItem struct { | |||||||
|  |  | ||||||
| // Generator holds all the information parsed out of the protocol file. | // Generator holds all the information parsed out of the protocol file. | ||||||
| type Generator struct { | type Generator struct { | ||||||
| 	// Enums holds the list of enums found by the parser. | 	// Enums holds the enum declarations. The type of enums is always int32. | ||||||
| 	Enums []ConstItem | 	Enums []Decl | ||||||
|  | 	// EnumVals holds the list of enum values found by the parser. In sunrpc as | ||||||
|  | 	// in go, these are not separately namespaced. | ||||||
|  | 	EnumVals []ConstItem | ||||||
| 	// Consts holds all the const items found by the parser. | 	// Consts holds all the const items found by the parser. | ||||||
| 	Consts []ConstItem | 	Consts []ConstItem | ||||||
|  | 	// Structs holds a list of all the structs found by the parser | ||||||
|  | 	Structs []Structure | ||||||
|  | 	// Typedefs hold all the type definitions from 'typedef ...' lines. | ||||||
|  | 	Typedefs []Typedef | ||||||
|  | 	// Unions hold all the discriminated unions | ||||||
|  | 	Unions []Union | ||||||
| } | } | ||||||
|  |  | ||||||
| // Gen accumulates items as the parser runs, and is then used to produce the | // Gen accumulates items as the parser runs, and is then used to produce the | ||||||
| @@ -81,6 +90,60 @@ var CurrentEnumVal int64 | |||||||
| // runes. | // runes. | ||||||
| var oneRuneTokens = `{}[]<>(),=;:*` | var oneRuneTokens = `{}[]<>(),=;:*` | ||||||
|  |  | ||||||
|  | var reservedIdentifiers = map[string]string{ | ||||||
|  | 	"type":   "lvtype", | ||||||
|  | 	"string": "lvstring", | ||||||
|  | 	"error":  "lverror", | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Decl records a declaration, like 'int x' or 'remote_nonnull_string str' | ||||||
|  | type Decl struct { | ||||||
|  | 	Name, Type string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Structure records the name and members of a struct definition. | ||||||
|  | type Structure struct { | ||||||
|  | 	Name    string | ||||||
|  | 	Members []Decl | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Typedef holds the name and underlying type for a typedef. | ||||||
|  | type Typedef struct { | ||||||
|  | 	Name string | ||||||
|  | 	Type string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Union holds a "discriminated union", which consists of a discriminant, which | ||||||
|  | // tells you what kind of thing you're looking at, and a number of encodings. | ||||||
|  | type Union struct { | ||||||
|  | 	Name             string | ||||||
|  | 	DiscriminantType string | ||||||
|  | 	Cases            []Case | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Case holds a single case of a discriminated union. | ||||||
|  | type Case struct { | ||||||
|  | 	DiscriminantVal string | ||||||
|  | 	Type            Decl | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // CurrentStruct will point to a struct record if we're in a struct declaration. | ||||||
|  | // When the parser adds a declaration, it will be added to the open struct if | ||||||
|  | // there is one. | ||||||
|  | var CurrentStruct *Structure | ||||||
|  |  | ||||||
|  | // CurrentTypedef will point to a typedef record if we're parsing one. Typedefs | ||||||
|  | // can define a struct or union type, but the preferred for is struct xxx{...}, | ||||||
|  | // so we may never see the typedef form in practice. | ||||||
|  | var CurrentTypedef *Typedef | ||||||
|  |  | ||||||
|  | // CurrentUnion holds the current discriminated union record. | ||||||
|  | var CurrentUnion *Union | ||||||
|  |  | ||||||
|  | // CurrentCase holds the current case record while the parser is in a union and | ||||||
|  | // a case statement. | ||||||
|  | var CurrentCase *Case | ||||||
|  |  | ||||||
| // Generate will output go bindings for libvirt. The lvPath parameter should be | // Generate will output go bindings for libvirt. The lvPath parameter should be | ||||||
| // the path to the root of the libvirt source directory to use for the | // the path to the root of the libvirt source directory to use for the | ||||||
| // generation. | // generation. | ||||||
| @@ -100,35 +163,51 @@ func Generate(proto io.Reader) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Generate and write the output. | 	// Generate and write the output. | ||||||
| 	wr, err := os.Create("../constants/constants.gen.go") | 	constFile, err := os.Create("../constants/constants.gen.go") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	defer wr.Close() | 	defer constFile.Close() | ||||||
|  | 	procFile, err := os.Create("../../libvirt.gen.go") | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	defer procFile.Close() | ||||||
|  |  | ||||||
| 	err = genGo(wr) | 	err = genGo(constFile, procFile) | ||||||
|  |  | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| func genGo(wr io.Writer) error { | func genGo(constFile, procFile io.Writer) error { | ||||||
| 	// Enums and consts from the protocol definition both become go consts in |  | ||||||
| 	// the generated code. We'll remove "REMOTE_" and then camel-case the |  | ||||||
| 	// name before making each one a go constant. |  | ||||||
| 	for ix, en := range Gen.Enums { |  | ||||||
| 		Gen.Enums[ix].Name = constNameTransform(en.Name) |  | ||||||
| 	} |  | ||||||
| 	for ix, en := range Gen.Consts { |  | ||||||
| 		Gen.Consts[ix].Name = constNameTransform(en.Name) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	t, err := template.ParseFiles("constants.tmpl") | 	t, err := template.ParseFiles("constants.tmpl") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	if err := t.Execute(wr, Gen); err != nil { | 	if err = t.Execute(constFile, Gen); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	t, err = template.ParseFiles("procedures.tmpl") | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if err := t.Execute(procFile, Gen); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	// Now generate the wrappers for libvirt's various public API functions. | ||||||
|  | 	// for _, c := range Gen.Enums { | ||||||
|  | 	// This appears to be the name of a libvirt procedure, so sort it into | ||||||
|  | 	// the right list based on the next part of its name. | ||||||
|  | 	// segs := camelcase.Split(c.Name) | ||||||
|  | 	// if len(segs) < 3 || segs[0] != "Proc" { | ||||||
|  | 	// 	continue | ||||||
|  | 	// } | ||||||
|  | 	//category := segs[1] | ||||||
|  |  | ||||||
|  | 	//fmt.Println(segs) | ||||||
|  | 	// } | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -137,20 +216,35 @@ func genGo(wr io.Writer) error { | |||||||
| // also tries to upcase abbreviations so a name like DOMAIN_GET_XML becomes | // also tries to upcase abbreviations so a name like DOMAIN_GET_XML becomes | ||||||
| // DomainGetXML, not DomainGetXml. | // DomainGetXML, not DomainGetXml. | ||||||
| func constNameTransform(name string) string { | func constNameTransform(name string) string { | ||||||
| 	nn := fromSnakeToCamel(strings.TrimPrefix(name, "REMOTE_")) | 	nn := fromSnakeToCamel(strings.TrimPrefix(name, "REMOTE_"), true) | ||||||
| 	nn = fixAbbrevs(nn) | 	nn = fixAbbrevs(nn) | ||||||
| 	return nn | 	return nn | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func identifierTransform(name string) string { | ||||||
|  | 	nn := strings.TrimPrefix(name, "remote_") | ||||||
|  | 	nn = fromSnakeToCamel(nn, false) | ||||||
|  | 	nn = fixAbbrevs(nn) | ||||||
|  | 	nn = checkIdentifier(nn) | ||||||
|  | 	return nn | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func typeTransform(name string) string { | ||||||
|  | 	nn := strings.TrimLeft(name, "*") | ||||||
|  | 	diff := len(name) - len(nn) | ||||||
|  | 	nn = identifierTransform(nn) | ||||||
|  | 	return name[0:diff] + nn | ||||||
|  | } | ||||||
|  |  | ||||||
| // fromSnakeToCamel transmutes a snake-cased string to a camel-cased one. All | // fromSnakeToCamel transmutes a snake-cased string to a camel-cased one. All | ||||||
| // runes that follow an underscore are up-cased, and the underscores themselves | // runes that follow an underscore are up-cased, and the underscores themselves | ||||||
| // are omitted. | // are omitted. | ||||||
| // | // | ||||||
| // ex: "PROC_DOMAIN_GET_METADATA" -> "ProcDomainGetMetadata" | // ex: "PROC_DOMAIN_GET_METADATA" -> "ProcDomainGetMetadata" | ||||||
| func fromSnakeToCamel(s string) string { | func fromSnakeToCamel(s string, public bool) string { | ||||||
| 	buf := make([]rune, 0, len(s)) | 	buf := make([]rune, 0, len(s)) | ||||||
| 	// Start with an upper-cased rune | 	// Start rune may be either upper or lower case. | ||||||
| 	hump := true | 	hump := public | ||||||
|  |  | ||||||
| 	for _, r := range s { | 	for _, r := range s { | ||||||
| 		if r == '_' { | 		if r == '_' { | ||||||
| @@ -203,19 +297,22 @@ func fixAbbrevs(s string) string { | |||||||
| //--------------------------------------------------------------------------- | //--------------------------------------------------------------------------- | ||||||
|  |  | ||||||
| // StartEnum is called when the parser has found a valid enum. | // StartEnum is called when the parser has found a valid enum. | ||||||
| func StartEnum() { | func StartEnum(name string) { | ||||||
|  | 	// Enums are always signed 32-bit integers. | ||||||
|  | 	name = identifierTransform(name) | ||||||
|  | 	Gen.Enums = append(Gen.Enums, Decl{name, "int32"}) | ||||||
| 	// Set the automatic value var to -1; it will be incremented before being | 	// Set the automatic value var to -1; it will be incremented before being | ||||||
| 	// assigned to an enum value. | 	// assigned to an enum value. | ||||||
| 	CurrentEnumVal = -1 | 	CurrentEnumVal = -1 | ||||||
| } | } | ||||||
|  |  | ||||||
| // AddEnum will add a new enum value to the list. | // AddEnumVal will add a new enum value to the list. | ||||||
| func AddEnum(name, val string) error { | func AddEnumVal(name, val string) error { | ||||||
| 	ev, err := parseNumber(val) | 	ev, err := parseNumber(val) | ||||||
| 	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 addEnum(name, ev) | 	return addEnumVal(name, ev) | ||||||
| } | } | ||||||
|  |  | ||||||
| // AddEnumAutoVal adds an enum to the list, using the automatically-incremented | // AddEnumAutoVal adds an enum to the list, using the automatically-incremented | ||||||
| @@ -223,11 +320,12 @@ func AddEnum(name, val string) error { | |||||||
| // explicit value. | // explicit value. | ||||||
| func AddEnumAutoVal(name string) error { | func AddEnumAutoVal(name string) error { | ||||||
| 	CurrentEnumVal++ | 	CurrentEnumVal++ | ||||||
| 	return addEnum(name, CurrentEnumVal) | 	return addEnumVal(name, CurrentEnumVal) | ||||||
| } | } | ||||||
|  |  | ||||||
| func addEnum(name string, val int64) error { | func addEnumVal(name string, val int64) error { | ||||||
| 	Gen.Enums = append(Gen.Enums, ConstItem{name, fmt.Sprintf("%d", val)}) | 	name = constNameTransform(name) | ||||||
|  | 	Gen.EnumVals = append(Gen.EnumVals, ConstItem{name, fmt.Sprintf("%d", val)}) | ||||||
| 	CurrentEnumVal = val | 	CurrentEnumVal = val | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -238,6 +336,7 @@ func AddConst(name, val string) error { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("invalid const value %v = %v", name, val) | 		return fmt.Errorf("invalid const value %v = %v", name, val) | ||||||
| 	} | 	} | ||||||
|  | 	name = constNameTransform(name) | ||||||
| 	Gen.Consts = append(Gen.Consts, ConstItem{name, val}) | 	Gen.Consts = append(Gen.Consts, ConstItem{name, val}) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -253,3 +352,80 @@ func parseNumber(val string) (int64, error) { | |||||||
| 	n, err := strconv.ParseInt(val, base, 64) | 	n, err := strconv.ParseInt(val, base, 64) | ||||||
| 	return n, err | 	return n, err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // StartStruct is called from the parser when a struct definition is found, but | ||||||
|  | // before the member declarations are processed. | ||||||
|  | func StartStruct(name string) { | ||||||
|  | 	name = identifierTransform(name) | ||||||
|  | 	CurrentStruct = &Structure{Name: name} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // AddStruct is called when the parser has finished parsing a struct. It adds | ||||||
|  | // the now-complete struct definition to the generator's list. | ||||||
|  | func AddStruct() { | ||||||
|  | 	Gen.Structs = append(Gen.Structs, *CurrentStruct) | ||||||
|  | 	CurrentStruct = nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func StartTypedef() { | ||||||
|  | 	CurrentTypedef = &Typedef{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TODO: remove before flight | ||||||
|  | func Beacon(name string) { | ||||||
|  | 	fmt.Println(name) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // StartUnion is called by the parser when it finds a union declaraion. | ||||||
|  | func StartUnion(name string) { | ||||||
|  | 	name = identifierTransform(name) | ||||||
|  | 	CurrentUnion = &Union{Name: name} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // AddUnion is called by the parser when it has finished processing a union | ||||||
|  | // type. It adds the union to the generator's list and clears the CurrentUnion | ||||||
|  | // pointer. | ||||||
|  | func AddUnion() { | ||||||
|  | 	Gen.Unions = append(Gen.Unions, *CurrentUnion) | ||||||
|  | 	CurrentUnion = nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func StartCase(dvalue string) { | ||||||
|  | 	CurrentCase = &Case{DiscriminantVal: dvalue} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func AddCase() { | ||||||
|  | 	CurrentUnion.Cases = append(CurrentUnion.Cases, *CurrentCase) | ||||||
|  | 	CurrentCase = nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // AddDeclaration is called by the parser when it find a declaration (int x). | ||||||
|  | // The declaration will be added to any open container (such as a struct, if the | ||||||
|  | // parser is working through a struct definition.) | ||||||
|  | func AddDeclaration(identifier, itype string) { | ||||||
|  | 	// TODO: panic if not in a struct/union/typedef? | ||||||
|  | 	// If the name is a reserved word, transform it so it isn't. | ||||||
|  | 	identifier = identifierTransform(identifier) | ||||||
|  | 	itype = typeTransform(itype) | ||||||
|  | 	decl := &Decl{Name: identifier, Type: itype} | ||||||
|  | 	if CurrentStruct != nil { | ||||||
|  | 		CurrentStruct.Members = append(CurrentStruct.Members, *decl) | ||||||
|  | 	} else if CurrentTypedef != nil { | ||||||
|  | 		CurrentTypedef.Name = identifier | ||||||
|  | 		CurrentTypedef.Type = itype | ||||||
|  | 		Gen.Typedefs = append(Gen.Typedefs, *CurrentTypedef) | ||||||
|  | 		CurrentTypedef = nil | ||||||
|  | 	} else if CurrentCase != nil { | ||||||
|  | 		CurrentCase.Type = *decl | ||||||
|  | 	} else if CurrentUnion != nil { | ||||||
|  | 		CurrentUnion.DiscriminantType = itype | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func checkIdentifier(i string) string { | ||||||
|  | 	nn, reserved := reservedIdentifiers[i] | ||||||
|  | 	if reserved { | ||||||
|  | 		return nn | ||||||
|  | 	} | ||||||
|  | 	return i | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										25
									
								
								internal/lvgen/procedures.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								internal/lvgen/procedures.tmpl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | /* | ||||||
|  |  * This file generated by internal/lvgen/generate.go. DO NOT EDIT BY HAND! | ||||||
|  |  * | ||||||
|  |  * To regenerate, run 'go generate' in internal/lvgen. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | package libvirt | ||||||
|  |  | ||||||
|  | // Typedefs: | ||||||
|  | {{range .Typedefs}}type {{.Name}} {{.Type}} | ||||||
|  | {{end}} | ||||||
|  | // Enums: | ||||||
|  | {{range .Enums}}	type {{.Name}} {{.Type}} | ||||||
|  | {{end}} | ||||||
|  | // Structs: | ||||||
|  | {{range .Structs}}type {{.Name}} struct { | ||||||
|  | {{range .Members}}	{{.Name}} {{.Type}} | ||||||
|  | {{end -}} | ||||||
|  | } | ||||||
|  | {{end}} | ||||||
|  | // Unions: | ||||||
|  | {{range .Unions}}type {{.Name}} struct { | ||||||
|  | 	discriminant {{.DiscriminantType}} | ||||||
|  | {{end -}} | ||||||
|  | } | ||||||
| @@ -46,7 +46,7 @@ definition | |||||||
|     ; |     ; | ||||||
|  |  | ||||||
| enum_definition | enum_definition | ||||||
|     : ENUM enum_ident '{' enum_value_list '}' { StartEnum() } |     : ENUM enum_ident '{' enum_value_list '}' { StartEnum($2.val) } | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
| enum_value_list | enum_value_list | ||||||
| @@ -63,7 +63,7 @@ enum_value | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     | enum_value_ident '=' value { |     | enum_value_ident '=' value { | ||||||
|         err := AddEnum($1.val, $3.val) |         err := AddEnumVal($1.val, $3.val) | ||||||
|         if err != nil { |         if err != nil { | ||||||
|             yylex.Error(err.Error()) |             yylex.Error(err.Error()) | ||||||
|             return 1 |             return 1 | ||||||
| @@ -98,7 +98,7 @@ const_ident | |||||||
|     ; |     ; | ||||||
|  |  | ||||||
| typedef_definition | typedef_definition | ||||||
|     : TYPEDEF declaration |     : TYPEDEF {StartTypedef()} declaration | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
| declaration | declaration | ||||||
| @@ -109,17 +109,17 @@ declaration | |||||||
|     ; |     ; | ||||||
|  |  | ||||||
| simple_declaration | simple_declaration | ||||||
|     : type_specifier variable_ident |     : type_specifier variable_ident {AddDeclaration($2.val, $1.val)} | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
| type_specifier | type_specifier | ||||||
|     : int_spec |     : int_spec | ||||||
|     | UNSIGNED int_spec |     | UNSIGNED int_spec {$$.val = "u"+$2.val} | ||||||
|     | FLOAT |     | FLOAT             {$$.val = "float32"} | ||||||
|     | DOUBLE |     | DOUBLE            {$$.val = "float64"} | ||||||
|     | BOOL |     | BOOL              {$$.val = "bool"} | ||||||
|     | STRING |     | STRING            {$$.val = "string"} | ||||||
|     | OPAQUE |     | OPAQUE            {$$.val = "[]byte"} | ||||||
|     | enum_definition |     | enum_definition | ||||||
|     | struct_definition |     | struct_definition | ||||||
|     | union_definition |     | union_definition | ||||||
| @@ -127,10 +127,10 @@ type_specifier | |||||||
|     ; |     ; | ||||||
|  |  | ||||||
| int_spec | int_spec | ||||||
|     : HYPER |     : HYPER {$$.val = "int64"} | ||||||
|     | INT |     | INT   {$$.val = "int32"} | ||||||
|     | SHORT |     | SHORT {$$.val = "int16"} | ||||||
|     | CHAR |     | CHAR  {$$.val = "int8"} | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
| variable_ident | variable_ident | ||||||
| @@ -138,20 +138,20 @@ variable_ident | |||||||
|     ; |     ; | ||||||
|  |  | ||||||
| fixed_array_declaration | fixed_array_declaration | ||||||
|     : type_specifier variable_ident '[' value ']' |     : type_specifier variable_ident '[' value ']'   { AddDeclaration($2.val, $1.val) } // FIXME: Handle the max size (value)? | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
| variable_array_declaration | variable_array_declaration | ||||||
|     : type_specifier variable_ident '<' value '>' |     : type_specifier variable_ident '<' value '>'   { AddDeclaration($2.val, $1.val) }  // FIXME: Handle the max size (value)? | ||||||
|     | type_specifier variable_ident '<' '>' |     | type_specifier variable_ident '<' '>'         { AddDeclaration($2.val, $1.val) } | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
| pointer_declaration | pointer_declaration | ||||||
|     : type_specifier '*' variable_ident |     : type_specifier '*' variable_ident             { AddDeclaration($3.val, "*"+$1.val) } | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
| struct_definition | struct_definition | ||||||
|     : STRUCT struct_ident '{' declaration_list '}' |     : STRUCT struct_ident '{' {StartStruct($2.val)} declaration_list '}' {AddStruct()} | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
| struct_ident | struct_ident | ||||||
| @@ -164,7 +164,7 @@ declaration_list | |||||||
|     ; |     ; | ||||||
|  |  | ||||||
| union_definition | union_definition | ||||||
|     : UNION union_ident SWITCH '(' simple_declaration ')' '{' case_list '}' |     : UNION union_ident {StartUnion($2.val)} SWITCH '(' simple_declaration ')' '{' case_list '}' {AddUnion()} | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
| union_ident | union_ident | ||||||
| @@ -177,8 +177,8 @@ case_list | |||||||
|     ; |     ; | ||||||
|  |  | ||||||
| case | case | ||||||
|     : CASE value ':' declaration |     : CASE value {StartCase($2.val)} ':' declaration {AddCase()} | ||||||
|     | DEFAULT ':' declaration |     | DEFAULT {StartCase("default")} ':' declaration {AddCase()} | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
| program_definition | program_definition | ||||||
|   | |||||||
							
								
								
									
										2492
									
								
								libvirt.gen.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2492
									
								
								libvirt.gen.go
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user