node/lib/metasm/metasm/parse_c.rb
def parse_type_struct(parser, scope)
			@type.parse_attributes(parser)
			if tok = parser.skipspaces and tok.type == :punct and tok.raw == '{'
				# anonymous struct, ok
				@type.backtrace = tok
				if @type.kind_of? Enum
					(scope.anonymous_enums ||= []) << @type
				end
			elsif tok and tok.type == :string
				name = tok.raw
				raise tok, 'bad struct name' if Keyword[name] or (?0..?9).include?(name[0])
				@type.backtrace = tok
				@type.name = name
				@type.parse_attributes(parser)
				raise parser if not ntok = parser.skipspaces
				if ntok.type != :punct or ntok.raw != '{'
					raise tok, "struct/union confusion" if scope.struct[name] and scope.struct[name].class != @type.class
					# variable declaration
					parser.unreadtok ntok
					if ntok.type == :punct and ntok.raw == ';'
						# struct predeclaration
						# allow redefinition
						@type = scope.struct[name] ||= @type
					else
						# check that the structure exists
						struct = scope.struct_ancestors[name]
						# allow incomplete types, usage as var type will raise later
						struct = scope.struct[name] = @type if not struct
						raise tok, 'unknown struct' if struct.class != @type.class
						(struct.attributes ||= []).concat @type.attributes if @type.attributes
						(struct.qualifier  ||= []).concat @type.qualifier  if @type.qualifier	# XXX const struct foo bar => bar is const, not foo...
						@type = struct
					end
					return
				end
				if scope.struct[name] and scope.struct[name].members
					# redefinition of an existing struct, save for later comparison
					oldstruct = scope.struct[name]
					raise tok, "struct/union confusion" if oldstruct.class != @type.class
				elsif struct = scope.struct[name]
					raise tok, "struct/union confusion" if struct.class != @type.class
					(struct.attributes ||= []).concat @type.attributes if @type.attributes
					(struct.qualifier  ||= []).concat @type.qualifier  if @type.qualifier
					struct.backtrace = @type.backtrace
					struct.name = @type.name
					@type = struct
				else
					scope.struct[name] = @type
				end
			else
				raise tok || parser, 'struct name or "{" expected'
			end

			@type.parse_members(parser, scope)

			if oldstruct
				if not @type.compare_deep(oldstruct)
					raise tok, "conflicting struct redefinition (old at #{oldstruct.backtrace.exception(nil).message rescue :unknown})"
				end
				@type = oldstruct
			end
		end
# parses a structure/union/enum declaration
parses a structure/union/enum declaration
parses a structure / union / enum declaration
def parse_type_struct(parser, scope)
			@type.parse_attributes(parser)
			if tok = parser.skipspaces and tok.type == :punct and tok.raw == '{'
				@type.backtrace = tok
				if @type.kind_of? Enum
					(scope.anonymous_enums ||= []) << @type
				end
			elsif tok and tok.type == :string
				name = tok.raw
				raise tok, 'bad struct name' if Keyword[name] or (?0..?9).include?(name[0])
				@type.backtrace = tok
				@type.name = name
				@type.parse_attributes(parser)
				raise parser if not ntok = parser.skipspaces
				if ntok.type != :punct or ntok.raw != '{'
					raise tok, "struct/union confusion" if scope.struct[name] and scope.struct[name].class != @type.class
					parser.unreadtok ntok
					if ntok.type == :punct and ntok.raw == ';'
						@type = scope.struct[name] ||= @type
					else
						struct = scope.struct_ancestors[name]
						struct = scope.struct[name] = @type if not struct
						raise tok, 'unknown struct' if struct.class != @type.class
						(struct.attributes ||= []).concat @type.attributes if @type.attributes
						(struct.qualifier  ||= []).concat @type.qualifier  if @type.qualifier	
						@type = struct
					end
					return
				end
				if scope.struct[name] and scope.struct[name].members
					oldstruct = scope.struct[name]
					raise tok, "struct/union confusion" if oldstruct.class != @type.class
				elsif struct = scope.struct[name]
					raise tok, "struct/union confusion" if struct.class != @type.class
					(struct.attributes ||= []).concat @type.attributes if @type.attributes
					(struct.qualifier  ||= []).concat @type.qualifier  if @type.qualifier
					struct.backtrace = @type.backtrace
					struct.name = @type.name
					@type = struct
				else
					scope.struct[name] = @type
				end
			else
				raise tok || parser, 'struct name or "{" expected'
			end
			@type.parse_members(parser, scope)
			if oldstruct
				if not @type.compare_deep(oldstruct)
					raise tok, "conflicting struct redefinition (old at #{oldstruct.backtrace.exception(nil).message rescue :unknown})"
				end
				@type = oldstruct
			end
		end
def parse_type_struct ( parser , scope ) @type . parse_attributes ( parser ) if tok = parser . skipspaces and tok . type == :punct and tok . raw == '{' @type . backtrace = tok if @type . kind_of? Enum ( scope . anonymous_enums ||= [ ] ) << @type end elsif tok and tok . type == :string name = tok . raw raise tok , 'bad struct name' if Keyword [ name ] or ( ?0 .. ?9 ) . include? ( name [ 0 ] ) @type . backtrace = tok @type . name = name @type . parse_attributes ( parser ) raise parser if not ntok = parser . skipspaces if ntok . type != :punct or ntok . raw != '{' raise tok , "struct/union confusion" if scope . struct [ name ] and scope . struct [ name ] . class != @type . class parser . unreadtok ntok if ntok . type == :punct and ntok . raw == ';' @type = scope . struct [ name ] ||= @type else struct = scope . struct_ancestors [ name ] struct = scope . struct [ name ] = @type if not struct raise tok , 'unknown struct' if struct . class != @type . class ( struct . attributes ||= [ ] ) . concat @type . attributes if @type . attributes ( struct . qualifier ||= [ ] ) . concat @type . qualifier if @type . qualifier @type = struct end return end if scope . struct [ name ] and scope . struct [ name ] . members oldstruct = scope . struct [ name ] raise tok , "struct/union confusion" if oldstruct . class != @type . class elsif struct = scope . struct [ name ] raise tok , "struct/union confusion" if struct . class != @type . class ( struct . attributes ||= [ ] ) . concat @type . attributes if @type . attributes ( struct . qualifier ||= [ ] ) . concat @type . qualifier if @type . qualifier struct . backtrace = @type . backtrace struct . name = @type . name @type = struct else scope . struct [ name ] = @type end else raise tok || parser , 'struct name or "{" expected' end @type . parse_members ( parser , scope ) if oldstruct if not @type . compare_deep ( oldstruct ) raise tok , "conflicting struct redefinition (old at #{oldstruct.backtrace.exception(nil).message rescue :unknown})" end @type = oldstruct end end
parses a structure/union/enum declaration
parses a structure / union / enum declaration
# anonymous struct, ok # variable declaration # struct predeclaration # allow redefinition # check that the structure exists # allow incomplete types, usage as var type will raise later # XXX const struct foo bar => bar is const, not foo... # redefinition of an existing struct, save for later comparison
parser
scope