# FreeRIDE Ruby Integrated Development Environment
#
# Author: Rich Kilmer
# Copyright (c) 2001, Richard Kilmer, rich@infoether.com
# Licensed under the Ruby License
#
# Updated 2003 for Scintilla 1.52
class ScintillaGenerator
VALUE = /val\s+([A-Z_]\w+)=/
FUNCTION = /fun\s([a-z]\w+)\s(\w+)=([0-9]\w+)\((\w+)?\s?(\w+)?,\s?(\w+)?\s?(\w+)?\)/
SET = /set\s([a-z]\w+)\s(\w+)=([0-9]\w+)\((\w+)?\s?(\w+)?,\s?(\w+)?\s?(\w+)?\)/
GET = /get\s([a-z]\w+)\s(\w+)=([0-9]\w+)\((\w+)?\s?(\w+)?,\s?(\w+)?\s?(\w+)?\)/
EVENT = /evt\s([a-z]\w+)\s(\w+)=([0-9]\w+)\((.*)\)/
COMMENT = /##/
LINE_COMMENT = /#\s/
INT = "int"
VOID = "void"
BOOL = "bool"
POSITION = "position"
COLOUR = "colour"
STRING_RESULT = "stringresult"
STRING = "string"
if ARGV.size ==1
DEBUG = eval(ARGV[0])
else
DEBUG=false
end
## void
## int
## bool -> integer, 1=true, 0=false
## position -> integer position in a document
## colour -> colour integer containing red, green and blue bytes.
## string -> pointer to const character
## stringresult -> pointer to character
## cells -> pointer to array of cells, each cell containing a style byte and character byte
## textrange -> charrange + output string
## findtext -> searchrange, text -> foundposition
## keymod -> integer containing key in low half and modifiers in high half
## formatrange
def initialize(input, output)
@input = input
@output = output
@event_stubs = []
@event_cases = []
end
def generate
o = File.new(@output, "w")
o.puts "## ***** WARNING...THIS FILE IS GENERATED BY FROM SCINTILLA.IFACE"
o.puts "## ***** DO NOT MODIFY...MODIFY SCINTILLA.RB INSTEAD\n\n"
o.puts "module Scintilla"
i = File.new(@input)
i.each_line do |line|
parse_line(line) { |text| o.puts text }
end
i.close
o.puts " module ScintillaEvents"
o.puts " def handle_notification(from, id, scn)"
o.puts " case id"
@event_cases.each {|ecase| o.puts ecase}
o.puts " end"
o.puts " end"
@event_stubs.each {|event| o.puts event}
o.puts " end"
o.puts "end"
o.close
end
def parse_line(line)
if line.length==1
yield ""
return
end
case line
when VALUE
@in_line_comment = false
yield " #{$1} = #{$'}"
when LINE_COMMENT
unless @in_line_comment
yield " ##\n"
@in_line_comment = true
end
yield " #{line}"
when EVENT
@in_line_comment = false
returnType = $1
function = $2
function = "on_"+un_camelcase(function)
id = $3
params = $4.split(",").collect {|p| p.strip}
params = nil if params == ['void']
event = " def #{function}"
if params
event << "("
event << (params.collect {|param| un_camelcase(param.split(' ')[1])}).join(", ")
event << ")\n"
else
event << "\n"
end
event << " end\n"
@event_stubs << event
event_case = " when #{id}\n"
event_case += " #{function}"
if params
event_case << "("
event_case << (params.collect {|param| "scn."+param.split(' ')[1]}).join(", ")
event_case << ")\n"
else
event_case << "\n"
end
@event_cases << event_case
when GET, SET, FUNCTION
@in_line_comment = false
returnType = $1
function = $2
function = (line[1,2]=='et' ? line[0,3] : '') + function unless function[0,3].downcase==line[0,3]
function = un_camelcase(function)
id = $3
param1Type = $4
param1 = $5
param2Type = $6
param2 = $7
param1 = "finish" if param1=="end"
param2 = "finish" if param2=="end"
if param1Type==INT && param1=="length" && param2Type==STRING && param2=="text"
str = " def #{function}( text )\n"
str << " send_message(#{id}, text.length, text)\n"
str << " end\n\n"
elsif param2Type==STRING_RESULT
str = " def #{function}"
str << "( " if param1
str << param1 if param1
str << " )" if param1
str << "\n"
if param1 && param1=="length"
str << " buffer = ' '*#{param1}\n"
str << " send_message(#{id}, #{param1}, buffer)\n"
else
if param1
str << " len = send_message(#{id}, #{param1}, '')\n"
str << " buffer = ' '*len\n"
str << " send_message(#{id}, #{param1}, buffer)\n"
else
str << " len = send_message(#{id}, 0, '')\n"
str << " buffer = ' '*len\n"
str << " send_message(#{id}, len, buffer)\n"
end
end
str << " return buffer\n"
str << " end\n"
if line[0,3]=='get'
str << " alias :#{function[4..-1]} :#{function}\n"
elsif line[0,3]=='set'
str << " alias :#{function[4..-1]}= :#{function}\n"
end
else
str = " def #{function}"
#str << "?" if returnType==BOOL
str << "( " if param1 || param2
str << param1 if param1
str << " , " if param1 && param2
str << param2 if param2
str << " )" if param1 || param2
str << "\n"
if DEBUG
str << (" puts "+'"'+"called #{function} ")
str << "( " if param1 || param2
str << ('#{'+param1+'}') if param1
str << " , " if param1 && param2
str << ('#{'+param2+'}') if param2
str << " )" if param1 || param2
str << ('"'+"\n")
end
str << " return (send_message(#{id}, #{caste_param(param1, param1Type)}, #{caste_param(param2, param2Type)})"
str << (returnType==BOOL ? "==1 ? true : false)\n" : ")\n")
str << " end\n"
if line[0,3]=='get'
str << " alias :#{function[4..-1] + (returnType==BOOL ? '?' : '')} :#{function}\n"
elsif line[0,3]=='set' && !param2 && param1
str << " alias :#{function[4..-1]}= :#{function}\n"
end
end
yield str
when COMMENT
@in_line_comment = false
else
end # case line
end # def parseLine(line)
def caste_param(param, type)
return "0" unless param
case type
when COLOUR
result = "#{param}.to_i"
when BOOL
result = "( #{param} ? 1 : 0 )"
else
result = param
end
return result
end
def un_camelcase(func)
result = ""
scratch = ""
func.each_byte do |byte|
if (?A..?Z).include? byte
scratch << byte.chr
else
if scratch.size==1
result += "_"+scratch
scratch = ""
elsif scratch.size>1
result += "_"+scratch[0..-2]+"_"+scratch[-1,1]
scratch = ""
end
result += byte.chr
end
end
result += "_"+scratch if scratch!=""
result = result[1..-1] if result[0,1]=='_'
result.downcase
end
end # class ScintillaParser
if __FILE__ == $0
ScintillaGenerator.new("Scintilla.iface", "scintilla_wrapper.rb").generate
end
syntax highlighted by Code2HTML, v. 0.9.1