intermediate check in; integrating new parser and tests thereof yet in progress

git-svn-id: http://cmock.svn.sourceforge.net/svnroot/cmock/trunk@93 bf332499-1b4d-0410-844d-d2d48d5cc64c
This commit is contained in:
mkarlesky
2009-05-14 05:18:45 +00:00
parent 71729e1b65
commit 500c30a5ce
5 changed files with 237 additions and 465 deletions
+7 -1
View File
@@ -1,4 +1,10 @@
$here = File.dirname __FILE__
require 'rubygems'
require 'treetop'
require "#{$here}/cmock_function_prototype_node_classes"
require "#{$here}/cmock_function_prototype_parser"
require "#{$here}/cmock_header_parser"
require "#{$here}/cmock_generator"
require "#{$here}/cmock_file_writer"
@@ -26,7 +32,7 @@ class CMock
path = File.dirname(src)
@cfg.set_path(path)
cm_parser = CMockHeaderParser.new(File.read(src), @cfg)
cm_parser = CMockHeaderParser.new(CMockFunctionPrototypeParser.new, File.read(src), @cfg)
cm_unityhelper = CMockUnityHelperParser.new(@cfg)
cm_writer = CMockFileWriter.new(@cfg)
cm_gen_utils = CMockGeneratorUtils.new(@cfg, {:unity_helper => cm_unityhelper})
+43 -95
View File
@@ -1,23 +1,23 @@
class CMockHeaderParser
attr_accessor :src_lines, :funcs, :c_attributes
attr_accessor :src_lines, :prototypes, :c_attributes
def initialize(source, cfg)
@funcs = []
def initialize(parser, source, cfg)
@src_lines = []
@prototypes = []
@c_attributes = cfg.attributes
@declaration_parse_matcher = /([\d\w\s\*\(\),]+??)\(([\d\w\s\*\(\),\.]*)\)$/m
@prototype_parse_matcher = /([\d\w\s\*\(\),]+??)\(([\d\w\s\*\(\),\.]*)\)$/m
@parser = parser
import_source(source)
end
def parse
mod = {:includes => nil, :functions => []}
parse_functions
if !@funcs.nil? and @funcs.length > 0
@funcs.each do |decl|
mod[:functions] << parse_declaration(decl)
end
end
# build prototype list
extract_prototypes
# parse all prototyes into hashes of components and add to array
@prototypes.each {|prototype| mod[:functions] << parse_prototype(prototype)} if (@prototypes.length > 0)
return mod
end
@@ -27,7 +27,7 @@ class CMockHeaderParser
# look for any edge cases of typedef'd void;
# void must be void for cmock AndReturn calls to process properly.
# to a certain extent, these replacements assume we're chewing on pre-processed header files
void_types = source.scan(/typedef\s+void\s+([\w\d]+)\s*;/)
void_types = source.scan(/typedef\s+(\(\s*)?void(\s*\))?\s+([\w\d]+)\s*;/)
void_types.each {|type| source.gsub!(/#{type}/, 'void')} if void_types.size > 0
source.gsub!(/\s*\\\s*/m, ' ') # smush multiline into single line
@@ -35,7 +35,10 @@ class CMockHeaderParser
source.gsub!(/\/\/.*$/, '') # remove line comments
source.gsub!(/#.*/, '') # remove preprocessor statements
source.gsub!(/typedef.*/, '') # remove typedef statements
source.gsub!(/^\s+/, '') # remove excessive white space
source.gsub!(/\s+$/, '') # remove excessive white space
source.gsub!(/\s+/, ' ') # remove excessive white space
@src_lines = source.split(/\s*;\s*/) # split source at end of statements (removing extra white space)
@src_lines.delete_if {|line| line.strip.length == 0} # remove blank lines
end
@@ -45,96 +48,41 @@ class CMockHeaderParser
@attribute_match = Regexp.compile(%|(#{@c_attributes.join('|')}\s+)*|)
end
def parse_functions
def extract_prototypes
@src_lines.each do |line|
@funcs << line.strip.gsub(/\s+/, ' ') if line =~ @declaration_parse_matcher
end
return @funcs
end
def parse_args(arg_list)
args = []
arg_list.split(',').each do |arg|
arg = arg.strip
return args if ((arg == '...') || (arg == 'void'))
arg_elements = arg.split
args << {:type => arg_elements[0..-2].join(' '), :name => arg_elements[-1]}
end
return args
end
def clean_args(arg_list)
if ((arg_list.strip == 'void') or (arg_list.empty?))
return 'void'
else
c=0
arg_list.gsub!(/\s+\*/,'*') # remove space to place asterisks with type (where they belong)
arg_list.gsub!(/\*(\w)/,'* \1') # pull asterisks away from param to place asterisks with type (where they belong)
arg_list.split(/\s*,\s*/).map{|arg| (arg =~ /^(\w+|.+\*|.+\)|.+const)$/) ? "#{arg} cmock_arg#{c+=1}" : arg}.join(', ')
end
end
def parse_declaration(declaration)
decl = {}
regex_match = @declaration_parse_matcher.match(declaration)
raise "Failed parsing function declaration: '#{declaration}'" if regex_match.nil?
# grab argument list
args = regex_match[2].strip
# process function attributes, return type, and name
descriptors = regex_match[1]
descriptors.gsub!(/\s+\*/,'*') # remove space to place asterisks with return type (where they belong)
descriptors.gsub!(/\*(\w)/,'* \1') # pull asterisks away from function name to place asterisks with return type (where they belong)
descriptors = descriptors.split # array of all descriptor strings
# grab name
decl[:name] = descriptors[-1] # snag name as last array item
# build attribute and return type strings
decl[:modifier] = []
decl[:rettype] = []
descriptors[0..-2].each do |word|
if @c_attributes.include?(word)
decl[:modifier] << word
else
decl[:rettype] << word
# build array of function prototypes
if (line =~ @prototype_parse_matcher)
# (remove any default parameter statements from argument lists while scanning)
line.gsub!(/=\s*[a-zA-Z0-9_\.]+\s*/, '')
@prototypes << line
end
end
decl[:modifier] = decl[:modifier].join(' ')
decl[:rettype] = decl[:rettype].join(' ')
# remove default parameter statements from mock definitions
args.gsub!(/=\s*[a-zA-Z0-9_\.]+\s*\,/, ',')
args.gsub!(/=\s*[a-zA-Z0-9_\.]+\s*/, ' ')
return @prototypes
end
def parse_prototype(prototype)
hash = {}
#check for var args
if (args =~ /\.\.\./)
decl[:var_arg] = args.match( /[\w\s]*\.\.\./ ).to_s.strip
if (args =~ /\,[\w\s]*\.\.\./)
args = args.gsub!(/\,[\w\s]*\.\.\./,'')
else
args = 'void'
modifiers = []
@c_attributes.each do |attribute|
if (prototype =~ /#{attribute}\s+/i)
modifiers << attribute
prototype.gsub!(/#{attribute}\s+/i, '')
end
else
decl[:var_arg] = nil
end
hash[:modifier] = modifiers.join(' ')
args = clean_args(args)
decl[:args_string] = args
decl[:args] = parse_args(args)
if decl[:rettype].nil? or decl[:name].nil? or decl[:args].nil?
raise "Declaration parse failed!\n" +
" declaration: #{declaration}\n" +
" modifier: #{decl[:modifier]}\n" +
" return: #{decl[:rettype]}\n" +
" function: #{decl[:name]}\n" +
" args:#{decl[:args]}\n"
end
parsed = @parser.parse(prototype)
raise "Failed parsing function prototype: '#{prototype}'" if parsed.nil?
return decl
hash[:name] = parsed.get_function_name
hash[:args_string] = parsed.get_argument_list
hash[:args] = parsed.get_arguments
hash[:rettype] = parsed.get_return_type
hash[:var_arg] = parsed.get_var_arg
return hash
end
end
-4
View File
@@ -34,12 +34,9 @@ task :treetop do
treetop_files.each do |file|
compiler.compile(file)
end
#`vendor/gems/treetop-1.2.5/bin/tt lib/cmock_function_prototype_parser.treetop`
end
namespace :test do
desc "Run all unit and system tests"
task :all => ['test:units', 'test:system']
@@ -55,5 +52,4 @@ namespace :test do
tests_failed = run_systests(FileList['test/system/cases/*.yml'])
raise "System tests failed." if (tests_failed > 0)
end
end
@@ -15,6 +15,7 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase
def teardown
end
should "parse simple void function prototypes" do
parsed = @parser.parse("void foo_bar(void)")
@@ -35,6 +36,7 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase
assert_nil(parsed.get_var_arg)
end
should "fail to parse garbage, broken function prototypes, and strings that only appear to be prototypes" do
assert_nil(@parser.parse("** !"))
assert_nil(@parser.parse("ashjfhskdh"))
@@ -51,6 +53,7 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase
assert_nil(@parser.parse("(parenthetical comment)"))
end
should "parse and normalize white space" do
parsed = @parser.parse("void foo_bar ( void )")
assert_equal("void foo_bar(void)", parsed.get_declaration)
@@ -74,6 +77,7 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase
assert_equal("float (*GetPtr( const char opCode ))( float, float )", parsed.get_declaration)
end
should "parse out simple arguments from an argument list into an array of hashes" do
# function pointers & var args tested elsewhere
@@ -115,6 +119,7 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase
assert_nil(parsed.get_var_arg)
end
should "fail to parse arguments that mix multiple custom types or a custom type and a primitive" do
# parser can only recognize strings of primitves followed by optional name or
# a single custom type followed by optional name;
@@ -125,6 +130,7 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase
assert_nil(@parser.parse("void foo_bar(CUSTOM_TYPE1 CUSTOM_TYPE2 abc, CUSTOM_TYPE1 CUSTOM_TYPE2 xyz)"))
end
should "parse out simple return types" do
# function pointers tested elsewhere
@@ -144,13 +150,14 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase
assert_equal('CUSTOM_TYPE', parsed.get_return_type)
end
should "normalize pointer notation" do
parsed = @parser.parse("void * foo(unsigned int * a, char * *b, int* c, int (* func)(void))")
parsed = @parser.parse("void * foo(unsigned int * * * a, char * *b, int* c, int (* func)(void))")
assert_equal('void*', parsed.get_return_type)
assert_equal('unsigned int* a, char** b, int* c, int (*func)(void)', parsed.get_argument_list)
assert_equal('unsigned int*** a, char** b, int* c, int (*func)(void)', parsed.get_argument_list)
assert_equal([
{:type => 'unsigned int*', :name => 'a'},
{:type => 'unsigned int***', :name => 'a'},
{:type => 'char**', :name => 'b'},
{:type => 'int*', :name => 'c'},
{:type => 'int (*)(void)', :name => 'func'}],
@@ -158,6 +165,7 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase
assert_nil(parsed.get_var_arg)
end
should "specially process var args in preparation for mocking" do
parsed = @parser.parse("void foo_bar(...)")
assert_equal('void', parsed.get_argument_list)
@@ -179,8 +187,12 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase
assert_nil(parsed.get_var_arg) # no var args for thing(), just for the function pointer param
end
should "parse prototypes handling function pointers" do
# function pointer prototypes in argument lists (i.e. no typedef)
# handle this? --> "int slinkydog(bool thing, int (* const)(void));\n" +
parsed = @parser.parse("void thing(int (*func_ptr)(int, int))")
assert_equal('int (*func_ptr)( int, int )', parsed.get_argument_list)
assert_equal(
@@ -211,6 +223,7 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase
assert_equal('unsigned int* (*)( unsigned int a )', parsed.get_return_type)
end
should "create unique typedefs for function pointer prototypes in argument lists and return types" do
# function prototype argument list handling
parsed = @parser.parse("void foo_bar(unsigned int a, void (*func)(int *, unsigned long int, ...))")
@@ -246,13 +259,14 @@ class CMockFunctionPrototypeParserTest < Test::Unit::TestCase
parsed.get_typedefs)
end
should "insert unique names for top-level nameless arguments" do
parsed = @parser.parse("void foo_bar(int (*)(int, int), char, unsigned int c, CUSTOM_THING)")
assert_equal('int (*cmock_arg1)( int, int ), char cmock_arg2, unsigned int c, CUSTOM_THING cmock_arg4', parsed.get_argument_list)
should "insert unique names for top-level nameless arguments" do
parsed = @parser.parse("void foo_bar(int (*)(int, int), char* const, unsigned int c, CUSTOM_THING)")
assert_equal('int (*cmock_arg1)( int, int ), char* const cmock_arg2, unsigned int c, CUSTOM_THING cmock_arg4', parsed.get_argument_list)
assert_equal(
[{:type => 'int (*)( int, int )', :name => 'cmock_arg1'},
{:type => 'char', :name => 'cmock_arg2'},
{:type => 'char* const', :name => 'cmock_arg2'},
{:type => 'unsigned int', :name => 'c'},
{:type => 'CUSTOM_THING', :name => 'cmock_arg4'}],
parsed.get_arguments)
+166 -358
View File
@@ -4,7 +4,7 @@ require 'cmock_header_parser'
class CMockHeaderParserTest < Test::Unit::TestCase
def setup
create_mocks :config
create_mocks :config, :prototype_parser, :parsed
@config.expect.attributes.returns(['static', 'inline', '__ramfunc'])
end
@@ -12,8 +12,9 @@ class CMockHeaderParserTest < Test::Unit::TestCase
end
should "create and initialize variables to defaults appropriately" do
@parser = CMockHeaderParser.new("", @config)
assert_equal([], @parser.funcs)
@parser = CMockHeaderParser.new(@prototype_parser, "", @config)
assert_equal([], @parser.prototypes)
assert_equal([], @parser.src_lines)
assert_equal(['static', 'inline', '__ramfunc'], @parser.c_attributes)
end
@@ -22,12 +23,12 @@ class CMockHeaderParserTest < Test::Unit::TestCase
" abcd;\n" +
"// hello;\n" +
"who // is you\n"
@parser = CMockHeaderParser.new(source, @config)
@parser = CMockHeaderParser.new(@prototype_parser, source, @config)
expected =
[
" abcd",
"who \n"
"abcd",
"who"
]
assert_equal(expected, @parser.src_lines)
@@ -39,12 +40,12 @@ class CMockHeaderParserTest < Test::Unit::TestCase
"/* hello;*/\n" +
"who /* is you\n" +
"// embedded line comment */\n"
@parser = CMockHeaderParser.new(source, @config)
@parser = CMockHeaderParser.new(@prototype_parser, source, @config)
expected =
[
" abcd",
"who \n"
"abcd",
"who"
]
assert_equal(expected, @parser.src_lines)
@@ -55,7 +56,7 @@ class CMockHeaderParserTest < Test::Unit::TestCase
"#when stuff_happens\n" +
"#ifdef _TEST\n" +
"#pragma stack_switch"
@parser = CMockHeaderParser.new(source, @config)
@parser = CMockHeaderParser.new(@prototype_parser, source, @config)
expected = []
@@ -66,11 +67,11 @@ class CMockHeaderParserTest < Test::Unit::TestCase
source =
"hoo hah \\\n" +
"when \\ \n"
@parser = CMockHeaderParser.new(source, @config)
@parser = CMockHeaderParser.new(@prototype_parser, source, @config)
expected =
[
"hoo hah when "
"hoo hah when"
]
assert_equal(expected, @parser.src_lines)
@@ -83,11 +84,11 @@ class CMockHeaderParserTest < Test::Unit::TestCase
"typedef who cares what really comes here \\\n" + # exercise multiline typedef
" continuation\n" +
"this should remain!"
@parser = CMockHeaderParser.new(source, @config)
@parser = CMockHeaderParser.new(@prototype_parser, source, @config)
expected =
[
"\nwhack me? \n\nthis should remain!"
"whack me? this should remain!"
]
assert_equal(expected, @parser.src_lines)
@@ -100,12 +101,12 @@ class CMockHeaderParserTest < Test::Unit::TestCase
"#DEFINE I JUST DON'T CARE\n" +
"#deFINE\n" +
"#define get_foo() \\\n ((Thing)foo.bar)" # exercise multiline define
@parser = CMockHeaderParser.new(source, @config)
@parser = CMockHeaderParser.new(@prototype_parser, source, @config)
expected =
[
"\nvoid hello(void)",
"void hello(void)",
]
assert_equal(expected, @parser.src_lines)
@@ -115,360 +116,167 @@ class CMockHeaderParserTest < Test::Unit::TestCase
source =
"typedef void SILLY_VOID_TYPE1;\n" +
"typedef void SILLY_VOID_TYPE2 ;\n" +
"typedef void (*FUNCPTR)(void);\n\n" + # don't get fooled by function pointer typedef with void as return type
"typedef (void) SILLY_VOID_TYPE2 ;\n" +
"typedef ( void ) (*FUNCPTR)(void);\n\n" + # don't get fooled by function pointer typedef with void as return type
"SILLY_VOID_TYPE2 Foo(int a, unsigned int b);\n" +
"void\n shiz(SILLY_VOID_TYPE1 *);\n" +
"void tat(FUNCPTR);\n"
@parser = CMockHeaderParser.new(source, @config)
parsed_stuff = @parser.parse
@parser = CMockHeaderParser.new(@prototype_parser, source, @config)
expected =
[
{
:modifier => "",
:args_string => "int a, unsigned int b",
:rettype => "void",
:var_arg => nil,
:args => [{:type => "int", :name => "a"}, {:type => "unsigned int", :name => "b"}],
:name => "Foo"
},
{
:modifier => "",
:args_string => "void* cmock_arg1",
:rettype => "void",
:var_arg => nil,
:args => [{:type => "void*", :name => "cmock_arg1"}],
:name => "shiz"
},
{
:modifier => "",
:args_string => "FUNCPTR cmock_arg1",
:rettype => "void",
:var_arg => nil,
:args => [{:type => "FUNCPTR", :name => "cmock_arg1"}],
:name => "tat"
}
"void Foo(int a, unsigned int b)",
"void shiz(void *)",
"void tat(FUNCPTR)"
]
assert_equal(expected, parsed_stuff[:functions])
assert_equal(expected, @parser.src_lines)
end
should "extract and return function declarations" do
should "raise upon prototype parsing failure" do
source =
"int Foo(int a, unsigned int b);\n" +
"void bar \n(uint la, int de, bool da) ; \n" +
"void FunkyChicken (\n uint la,\n int de,\n bool da);\n" +
"void\n shiz(void);\n" +
"void tat();\n" +
# following lines should yield no function declarations:
"#define get_foo() \\\n (Thing)foo())\n" +
"ARRAY_TYPE array[((U8)10)];\n" +
"THINGER_MASK = (0x0001 << 5),\n"
@parser = CMockHeaderParser.new(source, @config)
parsed_stuff = @parser.parse
"void bar \n(uint la, int de, bool da) ; \n"
expected =
[
{
:modifier => "",
:args_string => "int a, unsigned int b",
:rettype => "int",
:var_arg => nil,
:args => [{:type => "int", :name => "a"}, {:type => "unsigned int", :name => "b"}],
:name => "Foo"
},
{
:modifier => "",
:args_string => "uint la, int de, bool da",
:rettype => "void",
:var_arg => nil,
:args =>
[
{:type => "uint", :name => "la"},
{:type => "int", :name => "de"},
{:type => "bool", :name => "da"}
],
:name => "bar"
},
{
:modifier => "",
:args_string => "uint la, int de, bool da",
:rettype => "void",
:var_arg => nil,
:args =>
[
{:type => "uint", :name => "la"},
{:type => "int", :name => "de"},
{:type => "bool", :name => "da"}
],
:name => "FunkyChicken"
},
@prototype_parser.expect.parse('int Foo(int a, unsigned int b)').returns(nil)
@parser = CMockHeaderParser.new(@prototype_parser, source, @config)
begin
@parser.parse
assert_fail('should have raised')
rescue
end
end
{
:modifier => "",
:args_string => "void",
:rettype => "void",
:var_arg => nil,
:args => [],
:name => "shiz"
},
{
:modifier => "",
:args_string => "void",
:rettype => "void",
:var_arg => nil,
:args => [],
:name => "tat"
}
]
assert_equal(expected, parsed_stuff[:functions])
end
should "extract and return function declarations with attributes" do
source =
"static \tint \n Foo(int a, unsigned int b);\n" +
"inline\t bool bar \n(uint la, int de, bool da);\n" +
"inline static __ramfunc bool bar ( uint thinger );\n"
@parser = CMockHeaderParser.new(source, @config)
parsed_stuff = @parser.parse
expected =
[
{
:modifier => "static",
:args_string => "int a, unsigned int b",
:rettype => "int",
:var_arg => nil,
:args => [{:type => "int", :name => "a"}, {:type => "unsigned int", :name => "b"}],
:name => "Foo"
},
{
:modifier => "inline",
:args_string => "uint la, int de, bool da",
:rettype => "bool",
:var_arg => nil,
:args =>
[
{:type => "uint", :name => "la"},
{:type => "int", :name => "de"},
{:type => "bool", :name => "da"}
],
:name => "bar"
},
{
:modifier => "inline static __ramfunc",
:args_string => "uint thinger",
:rettype => "bool",
:var_arg => nil,
:args =>
[
{:type => "uint", :name => "thinger"},
],
:name => "bar"
}
]
assert_equal(expected, parsed_stuff[:functions])
end
should "extract and return function declarations with variable argument lists" do
source =
"\tint \n printf(char * const format, ...);\n" +
"bool bar \n(...);\n"
@parser = CMockHeaderParser.new(source, @config)
parsed_stuff = @parser.parse
expected =
[
{
:modifier => "",
:args_string => "char* const format",
:rettype => "int",
:var_arg => "...",
:args => [{:type => "char* const", :name => "format"}],
:name => "printf"
},
{
:modifier => "",
:args_string => "void",
:rettype => "bool",
:var_arg => "...",
:args => [],
:name => "bar"
}
]
assert_equal(expected, parsed_stuff[:functions])
end
should "attach * to type" do
source =
"MY_STRUCT* HooWah(char *** format);\n" +
"bool* HotShot(HIS_STRUCT **p, unsigned int* pint);\n" +
"bool * HotDog(BOW_WOW *p, unsigned int* pint);\n" +
"bool ** HotDog(BOW_WOW* p, unsigned int* pint);\n" +
"static bool *HotToTrot(unsigned int * struttin);\n" +
"static bool ***HotToTrot(unsigned int ** struttin);\n"
@parser = CMockHeaderParser.new(source, @config)
parsed_stuff = @parser.parse
expected =
[
{
:modifier => "",
:args_string => "char*** format",
:rettype => "MY_STRUCT*",
:var_arg => nil,
:args => [{:type => "char***", :name => "format"}],
:name => "HooWah"
},
{
:modifier => "",
:args_string => "HIS_STRUCT** p, unsigned int* pint",
:rettype => "bool*",
:var_arg => nil,
:args =>
[
{:type => "HIS_STRUCT**", :name => "p"},
{:type => "unsigned int*", :name => "pint"}
],
:name => "HotShot"
},
# should "extract and return function declarations" do
#
# source =
# "int Foo(int a, unsigned int b);\n" +
# "void bar \n(uint la, int de, bool da) ; \n" +
# "void FunkyChicken (\n uint la,\n int de,\n bool da);\n" +
# "void\n shiz(void);\n" +
# "void tat();\n" +
# # following lines should yield no function declarations:
# "#define get_foo() \\\n (Thing)foo())\n" +
# "ARRAY_TYPE array[((U8)10)];\n" +
# "THINGER_MASK = (0x0001 << 5),\n"
#
# @parser = CMockHeaderParser.new(@prototype_parser, source, @config)
# parsed_stuff = @parser.parse
#
# expected =
# [
# {
# :modifier => "",
# :args_string => "int a, unsigned int b",
# :rettype => "int",
# :var_arg => nil,
# :args => [{:type => "int", :name => "a"}, {:type => "unsigned int", :name => "b"}],
# :name => "Foo"
# },
#
# {
# :modifier => "",
# :args_string => "uint la, int de, bool da",
# :rettype => "void",
# :var_arg => nil,
# :args =>
# [
# {:type => "uint", :name => "la"},
# {:type => "int", :name => "de"},
# {:type => "bool", :name => "da"}
# ],
# :name => "bar"
# },
#
# {
# :modifier => "",
# :args_string => "uint la, int de, bool da",
# :rettype => "void",
# :var_arg => nil,
# :args =>
# [
# {:type => "uint", :name => "la"},
# {:type => "int", :name => "de"},
# {:type => "bool", :name => "da"}
# ],
# :name => "FunkyChicken"
# },
#
# {
# :modifier => "",
# :args_string => "void",
# :rettype => "void",
# :var_arg => nil,
# :args => [],
# :name => "shiz"
# },
#
# {
# :modifier => "",
# :args_string => "void",
# :rettype => "void",
# :var_arg => nil,
# :args => [],
# :name => "tat"
# }
# ]
#
# assert_equal(expected, parsed_stuff[:functions])
# end
#
# should "extract and return function declarations with attributes" do
#
# source =
# "static \tint \n Foo(int a, unsigned int b);\n" +
# "inline\t bool bar \n(uint la, int de, bool da);\n" +
# "inline static __ramfunc bool bar ( uint thinger );\n"
#
# @parser = CMockHeaderParser.new(@prototype_parser, source, @config)
# parsed_stuff = @parser.parse
#
# expected =
# [
# {
# :modifier => "static",
# :args_string => "int a, unsigned int b",
# :rettype => "int",
# :var_arg => nil,
# :args => [{:type => "int", :name => "a"}, {:type => "unsigned int", :name => "b"}],
# :name => "Foo"
# },
#
# {
# :modifier => "inline",
# :args_string => "uint la, int de, bool da",
# :rettype => "bool",
# :var_arg => nil,
# :args =>
# [
# {:type => "uint", :name => "la"},
# {:type => "int", :name => "de"},
# {:type => "bool", :name => "da"}
# ],
# :name => "bar"
# },
#
# {
# :modifier => "inline static __ramfunc",
# :args_string => "uint thinger",
# :rettype => "bool",
# :var_arg => nil,
# :args =>
# [
# {:type => "uint", :name => "thinger"},
# ],
# :name => "bar"
# }
# ]
#
# assert_equal(expected, parsed_stuff[:functions])
# end
{
:modifier => "",
:args_string => "BOW_WOW* p, unsigned int* pint",
:rettype => "bool*",
:var_arg => nil,
:args =>
[
{:type => "BOW_WOW*", :name => "p"},
{:type => "unsigned int*", :name => "pint"}
],
:name => "HotDog"
},
{
:modifier => "",
:args_string => "BOW_WOW* p, unsigned int* pint",
:rettype => "bool**",
:var_arg => nil,
:args =>
[
{:type => "BOW_WOW*", :name => "p"},
{:type => "unsigned int*", :name => "pint"}
],
:name => "HotDog"
},
{
:modifier => "static",
:args_string => "unsigned int* struttin",
:rettype => "bool*",
:var_arg => nil,
:args =>
[
{:type => "unsigned int*", :name => "struttin"}
],
:name => "HotToTrot"
},
{
:modifier => "static",
:args_string => "unsigned int** struttin",
:rettype => "bool***",
:var_arg => nil,
:args =>
[
{:type => "unsigned int**", :name => "struttin"}
],
:name => "HotToTrot"
}
]
assert_equal(expected, parsed_stuff[:functions])
end
should "extract and return function declarations with just types (no argument names)" do
source =
"int buzzlightyear(char*, bool);\n" +
"bool woody();\n" +
"int slinkydog(bool thing, int (* const)(void));\n" +
"int andy(int* const);\n"
@parser = CMockHeaderParser.new(source, @config)
parsed_stuff = @parser.parse
expected =
[
{
:modifier => "",
:args_string => "char* cmock_arg1, bool cmock_arg2",
:rettype => "int",
:var_arg => nil,
:args =>
[
{:type => "char*", :name => "cmock_arg1"},
{:type => "bool", :name => "cmock_arg2"}
],
:name => "buzzlightyear"
},
{
:modifier => "",
:args_string => "void",
:rettype => "bool",
:var_arg => nil,
:args => [],
:name => "woody"
},
{
:modifier => "",
:args_string => "bool thing, int (* const)(void) cmock_arg1",
:rettype => "int",
:var_arg => nil,
:args =>
[
{:type => "bool", :name => "thing"},
{:type => "int (* const)(void)", :name => "cmock_arg1"}
],
:name => "slinkydog"
},
{
:modifier => "",
:args_string => "int* const cmock_arg1",
:rettype => "int",
:var_arg => nil,
:args =>
[
{:type => "int* const", :name => "cmock_arg1"},
],
:name => "andy"
}
]
assert_equal(expected, parsed_stuff[:functions])
end
end