summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/phonon/phonon/extractmethodcalls.rb
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit356978ecce23e076e1b622d5d41dd8c04bf7bcf8 (patch)
tree8e1874cc32750e30b84b2561387d48424e076ae3 /src/3rdparty/phonon/phonon/extractmethodcalls.rb
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/3rdparty/phonon/phonon/extractmethodcalls.rb')
-rwxr-xr-xsrc/3rdparty/phonon/phonon/extractmethodcalls.rb527
1 files changed, 527 insertions, 0 deletions
diff --git a/src/3rdparty/phonon/phonon/extractmethodcalls.rb b/src/3rdparty/phonon/phonon/extractmethodcalls.rb
new file mode 100755
index 0000000..9100489
--- /dev/null
+++ b/src/3rdparty/phonon/phonon/extractmethodcalls.rb
@@ -0,0 +1,527 @@
+#!/usr/bin/ruby
+
+class MethodDef
+ def initialize(returnType, signature, optional)
+ @returnType = returnType
+ @signature = signature
+ @optional = optional
+ end
+
+ attr_reader :returnType, :signature, :optional
+ attr_writer :optional
+end
+
+class SignalDef
+ def initialize(signature)
+ @signature = signature
+ end
+
+ attr_reader :signature
+end
+
+class Parser
+ def initialize(filename)
+ @file = File.new filename, "r"
+ @signatures = Hash.new
+ parse
+ end
+
+ attr_reader :signatures
+
+ private
+ def addSignal(signature)
+ unless @signatures.include? signature
+ @signatures[signature] = SignalDef.new(signature)
+ end
+ end
+
+ def addMethod(returnType, signature, optional)
+ if @signatures.include? signature
+ if returnType != ''
+ if @signatures[signature].returnType == ''
+ optional = false if @signatures[signature].optional == false
+ @signatures[signature] = MethodDef.new(returnType, signature, optional)
+ elsif @signatures[signature].returnType != returnType
+ fail "same signature '#{signature}' but differing return types: #{returnType} and #{@signatures[signature].returnType}"
+ end
+ elsif not optional and @signatures[signature].optional
+ @signatures[signature].optional = false
+ end
+ else
+ @signatures[signature] = MethodDef.new(returnType, signature, optional)
+ end
+ end
+
+ PARSER_RETURN_TYPE = 0
+ PARSER_RETURN_VAR = 1
+ PARSER_METHOD_NAME = 2
+ PARSER_ARGUMENT_TYPE = 3
+ PARSER_ARGUMENT_VAR = 4
+
+ PARSER2_CLASSNAME = 0
+ PARSER2_METHODPREFIX = 1
+
+ PARSER3_QMETAOBJECT = 0
+ PARSER3_SCOPEDELIMIT = 1
+ PARSER3_INVOKEMETHOD = 2
+ PARSER3_OPENPARENTH = 3
+ PARSER3_BACKENDOBJ = 4
+ PARSER3_METHODNAME = 5
+ PARSER3_CONNECTION = 6
+ PARSER3_RET_OR_ARG = 7
+ PARSER3_RET_OPEN = 8
+ PARSER3_RET_TYPE = 9
+ PARSER3_RET_NAME = 10
+ PARSER3_RET_CLOSE = 11
+ PARSER3_ARG = 12
+ PARSER3_ARG_OPEN = 13
+ PARSER3_ARG_TYPE = 14
+ PARSER3_ARG_NAME = 15
+ PARSER3_ARG_CLOSE = 16
+ PARSER3_CLOSE = 17
+ PARSER3_DONE = 18
+
+ PARSER4_OPENING_PAREN = 0
+ PARSER4_SENDER = 1
+ PARSER4_PRIVATE_SENDER = 2
+ PARSER4_COMMA_1 = 3
+ PARSER4_SIGNAL_MACRO = 4
+ PARSER4_SIGNAL_OPENING_PAREN = 5
+ PARSER4_SIGNAL_SIGNATURE = 6
+ PARSER4_SIGNAL_SIGNATURE_OPENING_PAREN = 7
+ PARSER4_SIGNAL_SIGNATURE_CONST = 8
+ PARSER4_SIGNAL_SIGNATURE_TYPE1 = 9
+ PARSER4_SIGNAL_SIGNATURE_TYPE2_1 = 10
+ PARSER4_SIGNAL_SIGNATURE_TYPE2_2 = 11
+ PARSER4_SIGNAL_CLOSING_PAREN = 12
+
+ def parse
+ inbackendcall = false
+ innamedescriptioncall = false
+ ininvokemethodcall = false
+ invokemethodcallOnBackendObject = false
+ inconnect = false
+ optionalmethod = false
+ lasttoken = ';'
+ thistoken = ';'
+ returnType = String.new
+ signature = String.new
+ parserstate = PARSER_RETURN_TYPE
+ depth = 0
+ tokenize do |token|
+ #STDERR.puts token
+ lasttoken = thistoken
+ thistoken = token
+ token = token[1..-1] if token[0,9] == "pBACKEND_"
+ if token[0,8] == "BACKEND_"
+ fail if innamedescriptioncall
+ fail if inbackendcall
+ fail if ininvokemethodcall
+ fail if inconnect
+ inbackendcall = true
+ if token[8,3] != "GET" # skip return arg
+ parserstate = PARSER_METHOD_NAME
+ returnType = ''
+ else
+ parserstate = PARSER_RETURN_TYPE
+ end
+ elsif token == 'NAMEDESCRIPTIONFROMINDEX'
+ fail if innamedescriptioncall
+ fail if inbackendcall
+ fail if ininvokemethodcall
+ fail if inconnect
+ innamedescriptioncall = true
+ parserstate = PARSER2_CLASSNAME
+ elsif token == 'QMetaObject'
+ fail if innamedescriptioncall
+ fail if inbackendcall
+ fail if ininvokemethodcall
+ fail if inconnect
+ ininvokemethodcall = true
+ parserstate = PARSER3_SCOPEDELIMIT
+ optionalmethod = (lasttoken[-1,1] == '=' or lasttoken == '(' or lasttoken == '!') ? true : false
+ elsif token == 'connect'
+ fail if innamedescriptioncall
+ fail if inbackendcall
+ fail if ininvokemethodcall
+ fail if inconnect
+ inconnect = true
+ parserstate = PARSER4_OPENING_PAREN
+ elsif inconnect
+ #puts "state = #{parserstate}, token = #{token}"
+ lastparserstate = parserstate
+ case parserstate
+ when PARSER4_OPENING_PAREN
+ parserstate = PARSER4_SENDER if token == '('
+ when PARSER4_SENDER
+ # d->m_backendObject or only m_backendObject
+ parserstate = PARSER4_COMMA_1 if token == 'm_backendObject'
+ parserstate = PARSER4_PRIVATE_SENDER if token == 'd'
+ when PARSER4_PRIVATE_SENDER
+ parserstate = PARSER4_SENDER if token == '->'
+ when PARSER4_COMMA_1
+ parserstate = PARSER4_SIGNAL_MACRO if token == ','
+ when PARSER4_SIGNAL_MACRO
+ parserstate = PARSER4_SIGNAL_OPENING_PAREN if token == 'SIGNAL'
+ when PARSER4_SIGNAL_OPENING_PAREN
+ parserstate = PARSER4_SIGNAL_SIGNATURE if token == '('
+ when PARSER4_SIGNAL_SIGNATURE
+ signature = token
+ parserstate = PARSER4_SIGNAL_SIGNATURE_OPENING_PAREN
+ when PARSER4_SIGNAL_SIGNATURE_OPENING_PAREN
+ case token
+ when '('
+ signature += '('
+ parserstate = PARSER4_SIGNAL_SIGNATURE_CONST
+ when '()'
+ signature += '()'
+ parserstate = PARSER4_SIGNAL_CLOSING_PAREN
+ end
+ when PARSER4_SIGNAL_SIGNATURE_CONST
+ case token
+ when 'const'
+ signature += 'const '
+ parserstate = PARSER4_SIGNAL_SIGNATURE_TYPE1
+ when ')'
+ signature += ')'
+ parserstate = PARSER4_SIGNAL_CLOSING_PAREN
+ else
+ signature += token
+ parserstate = PARSER4_SIGNAL_SIGNATURE_TYPE2_1
+ end
+ when PARSER4_SIGNAL_SIGNATURE_TYPE1
+ case token
+ when 'const'
+ when ')'
+ else
+ signature += token
+ parserstate = PARSER4_SIGNAL_SIGNATURE_TYPE2_1
+ end
+ when PARSER4_SIGNAL_SIGNATURE_TYPE2_1
+ case token
+ when ','
+ signature += ', '
+ parserstate = PARSER4_SIGNAL_SIGNATURE_TYPE1
+ when ')'
+ signature += ')'
+ parserstate = PARSER4_SIGNAL_CLOSING_PAREN
+ else
+ signature += token
+ parserstate = PARSER4_SIGNAL_SIGNATURE_TYPE2_2
+ end
+ when PARSER4_SIGNAL_SIGNATURE_TYPE2_2
+ case token
+ when ','
+ signature += ', '
+ parserstate = PARSER4_SIGNAL_SIGNATURE_TYPE1
+ when ')'
+ signature += ')'
+ parserstate = PARSER4_SIGNAL_CLOSING_PAREN
+ else
+ signature += token
+ parserstate = PARSER4_SIGNAL_SIGNATURE_TYPE2_1
+ end
+ when PARSER4_SIGNAL_CLOSING_PAREN
+ addSignal(signature) if token == ')'
+ end
+ if parserstate == lastparserstate
+ inconnect = false
+ signature = String.new
+ end
+ elsif ininvokemethodcall
+ case parserstate
+ when PARSER3_BACKENDOBJ
+ if token == ','
+ if invokemethodcallOnBackendObject
+ parserstate += 1
+ else
+ ininvokemethodcall = false
+ end
+ elsif token =~ /backendObject/
+ invokemethodcallOnBackendObject = true
+ end
+ when PARSER3_SCOPEDELIMIT
+ if token == '::'
+ parserstate += 1
+ else
+ ininvokemethodcall = false
+ end
+ when PARSER3_INVOKEMETHOD
+ if token == 'invokeMethod'
+ parserstate += 1
+ else
+ ininvokemethodcall = false
+ end
+ when PARSER3_OPENPARENTH
+ fail if token != '('
+ parserstate += 1
+ invokemethodcallOnBackendObject = false
+ when PARSER3_METHODNAME
+ case token
+ when ','
+ signature += '('
+ parserstate = PARSER3_CONNECTION
+ else
+ fail if signature.length > 0
+ signature = token[1..-2]
+ end
+ when PARSER3_CONNECTION
+ case token
+ when ','
+ parserstate = PARSER3_RET_OR_ARG
+ when ')'
+ parserstate = PARSER3_CLOSE
+# the connection is optional
+ when 'Q_RETURN_ARG'
+ parserstate = PARSER3_RET_OPEN
+ when 'Q_ARG'
+ returnType = ''
+ parserstate = PARSER3_ARG_OPEN
+ end
+ when PARSER3_RET_OR_ARG
+ if token == 'Q_RETURN_ARG'
+ parserstate = PARSER3_RET_OPEN
+ elsif token == 'Q_ARG'
+ returnType = ''
+ parserstate = PARSER3_ARG_OPEN
+ else
+ fail "unexpected token '#{token}"
+ end
+ when PARSER3_RET_TYPE
+ if token == ','
+ parserstate += 1
+ else
+ if token == '*' or token == '&' or token == '<' or token == '>' or token == '::' or returnType.empty? or returnType[-1,1] == '<' or returnType[-2,2] == '::'
+ returnType += token
+ else
+ returnType += ' ' + token
+ end
+ end
+ when PARSER3_RET_NAME
+ parserstate = PARSER3_RET_CLOSE if token == ')'
+ when PARSER3_RET_CLOSE
+ case token
+ when ')'
+ parserstate = PARSER3_CLOSE
+ when ','
+ parserstate = PARSER3_ARG
+ end
+ when PARSER3_ARG
+ if token == 'Q_ARG'
+ parserstate = PARSER3_ARG_OPEN
+ else
+ fail "unexpected token '#{token}"
+ end
+ when PARSER3_ARG_TYPE
+ if token == ','
+ parserstate += 1
+ else
+ signature += ' ' if signature[-1,1] =~ /\w/ and token[0,1] =~ /\w/
+ signature += token
+ end
+ when PARSER3_ARG_NAME
+ case token
+ when '('
+ depth += 1
+ when ')'
+ if depth == 0
+ parserstate = PARSER3_ARG_CLOSE
+ else
+ depth -= 1
+ end
+ end
+ when PARSER3_ARG_CLOSE
+ case token
+ when ','
+ signature += ','
+ parserstate = PARSER3_ARG
+ when ')'
+ parserstate = PARSER3_CLOSE
+ else
+ fail
+ end
+ when PARSER3_ARG_OPEN, PARSER3_RET_OPEN
+ fail if token != '('
+ parserstate += 1
+ when PARSER3_CLOSE
+ signature += ')'
+ addMethod returnType, signature, optionalmethod
+ ininvokemethodcall = false
+ returnType = String.new
+ signature = String.new
+ end
+ elsif innamedescriptioncall
+ case parserstate
+ when PARSER2_CLASSNAME
+ parserstate = PARSER2_METHODPREFIX if token == ','
+ when PARSER2_METHODPREFIX
+ addMethod 'QSet<int>', token + 'Indexes()', false
+ addMethod 'int', token + 'Name()', false
+ addMethod 'int', token + 'Description()', false
+ innamedescriptioncall = false
+ end
+ elsif inbackendcall
+ next if token == '(' # skip (
+ if token == ';'
+ if signature.length > 0
+ signature += ')'
+ addMethod returnType, signature, false
+ signature = String.new
+ returnType = String.new
+ end
+ inbackendcall = false
+ else
+ if token == ','
+ if parserstate == PARSER_ARGUMENT_VAR
+ signature += ','
+ parserstate = PARSER_ARGUMENT_TYPE
+ else
+ parserstate += 1
+ end
+ next
+ end
+ case parserstate
+ when PARSER_RETURN_TYPE
+ returnType += token
+ when PARSER_RETURN_VAR
+ when PARSER_METHOD_NAME
+ next if token == ')'
+ fail if token[0,1] != '"' or token[-1,1] != '"'
+ fail if signature.length > 0
+ signature = token[1..-2] + '('
+ when PARSER_ARGUMENT_TYPE
+ signature += token
+ end
+ end
+ end
+ end
+ end
+
+ def tokenize
+ incomment = false
+ instring = false
+ laststring = ''
+ linenum = 0
+ @file.each_line do |line|
+ linenum += 1
+ line.strip!
+ next if line[0..1] == "//"
+ next if line[0,1] == "#" # ignore preprocessor statements
+ line.split(/(\b|\s+)/).each do |token|
+ #STDERR.puts "string: #{instring} comment: #{incomment} token: '#{token}'"
+ if instring
+ indexOfEscapedQuote = token.index '\\"'
+ if indexOfEscapedQuote != nil
+ laststring += token
+ next
+ end
+ indexOfQuote = token.index '"'
+ if indexOfQuote and indexOfQuote > 0
+ fail if token[indexOfQuote-1,1] == '\\'
+ laststring += token[0..indexOfQuote-1]
+ token = token[indexOfQuote..-1]
+ end
+ if token[0,2] == '""'
+ laststring += token[2..-1]
+ next
+ elsif token[0,1] == '"'
+ if laststring[-1,1] == '\\'
+ laststring[-1,1] = '"'
+ laststring += token[1..-1]
+ next
+ end
+ instring = false
+ yield laststring + '"'
+ token = token[1..-1]
+ else
+ laststring += token
+ next
+ end
+ end
+ token.strip!
+ next if token.empty?
+ if incomment
+ incomment = false if token[0..1] == "*/"
+ next
+ else
+ if token[0..1] == "/*"
+ incomment = true
+ next
+ end
+ break if token == "//"
+ end
+ doublequote = token.index '""'
+ if doublequote != nil
+ if doublequote > 0
+ yield token[0,doublequote]
+ end
+ yield '""'
+ if token.length > doublequote+2
+ token = token[doublequote+2..-1]
+ else
+ next
+ end
+ end
+ quote = token.index '"'
+ if quote != nil
+ laststring = token[quote..-1]
+ instring = true
+ if quote > 0
+ token = token[0,quote]
+ else
+ next
+ end
+ end
+ semicolon = token.index ';'
+ if not semicolon
+ tokenize2(token) { |i| yield i }
+ elsif semicolon > 0
+ tokenize2(token[0..semicolon-1]) { |i| yield i }
+ yield ';'
+ if token.length > semicolon + 1
+ tokenize2(token[semicolon+1..-1]) { |i| yield i }
+ end
+ elsif (semicolon == 0 and token.length > 1)
+ yield ';'
+ tokenize2(token[1..-1]) { |i| yield i }
+ else
+ yield token # a single ;
+ end
+ end
+ end
+ end
+
+ def tokenize2(token)
+ if token.length > 1
+ #STDERR.puts "long token: #{token}"
+ while token[0,1] == '(' or token[0,1] == ')' or token[0,1] == "'" or token[0,1] == '&'
+ yield token[0,1]
+ token = token[1..-1]
+ #STDERR.puts "less long token: #{token}"
+ end
+ return if token.empty?
+ if token.length == 1
+ yield token
+ return
+ elsif token[-1,1] == ',' or token[-1,1] == "'"
+ yield token[0..-2]
+ yield token[-1,1]
+ return
+ end
+ end
+ yield token
+ end
+end
+
+p = Parser.new ARGV[0]
+p.signatures.each do |signature,method|
+ if method.class == SignalDef
+ puts "addSignal(\"#{signature}\");"
+ else
+ if method.optional
+ puts "addMethod(\"#{method.returnType}\", \"#{signature}\", true);"
+ else
+ puts "addMethod(\"#{method.returnType}\", \"#{signature}\");"
+ end
+ end
+end