Add C# bindings for Actor's POSITION_USES_ANCHOR_POINT property
[platform/core/uifw/dali-toolkit.git] / plugins / dali-swig / constructor-generator.rb
1 #!/usr/bin/env ruby
2 # encoding: utf-8
3 require 'pathname'
4 require 'scanf'
5 require 'fileutils'
6 #
7 # DALi traditonally use a static New function to create an object.
8 # E.g. Actor myActor = Actor::New();
9 #
10 # However it has been request that for the CSharp DALi API we this coding convention
11 #
12 #  Actor myActor = new Actor();
13 #
14 # Script does the follow:
15 #
16 # - greps dali csharp wrapper files for the class constructor (new Actor()) and the static New() e.g. functions ( TextLabel::New(), TextLabel::New( string label) )
17 #
18 # regexp for searching swig generated constructors grep  -oP -n  'public [A-Z]([A-Z]*[a-z])*\(\)'  *
19 # regexp for searching for swig genereated New functions  grep -oP -n -i 'static [a-zA-Z]\+ New'
20
21
22 $fileHeader = "/*"\
23  "* Copyright (c) #{Time.now.year} Samsung Electronics Co., Ltd.\n"\
24  "*\n"\
25  "* Licensed under the Apache License, Version 2.0 (the \"License\");\n"\
26  "* you may not use this file except in compliance with the License.\n"\
27  "* You may obtain a copy of the License at\n"\
28  "*\n"\
29  "* http://www.apache.org/licenses/LICENSE-2.0\n"\
30  "*\n"\
31  "* Unless required by applicable law or agreed to in writing, software\n"\
32  "* distributed under the License is distributed on an \"AS IS\" BASIS,\n"\
33  "* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"\
34  "* See the License for the specific language governing permissions and\n"\
35  "* limitations under the License.\n"\
36  "*\n"\
37  "*/\n"\
38  "// This File has been auto-generated by SWIG and then modified using DALi Ruby Scripts\n"
39
40 # global paths
41 $rootPath = ""
42 $daliCSharpPath = ""
43 $totalDaliClasses = 0
44 $totalConstructorsGenerated = 0
45
46
47 $swigConstructorNumLines = 3
48 $swigNewFuncNumLines = 4
49
50
51 # daliClass struct stores information about where the constructor / static New functions are in the file
52 $daliClassStruct = Struct.new("DaliClass", :name, :file, :hasNewFunction, :hasConstructor, :constructorLine, :staticNewLines, :generatedConstructors)
53
54 # Array
55 $daliClassArray = Array.new
56
57 def init
58
59     pn = Pathname.new(Dir.pwd)
60     fullPath = pn.to_s
61
62     $rootPath = fullPath.slice(0..( fullPath.index('/dali-toolkit')))
63     $daliCSharpPath = $rootPath + "dali-toolkit/plugins/dali-swig/automatic/csharp"
64     puts("--------------------------------------------")
65     puts("Modifying constructors for DALi C# files ")
66     puts("E.g. modify TextLabel::New() ==>  new TextLabel() ")
67     puts("")
68
69
70 end
71
72 def getDaliClassItem( className )
73
74    # puts( "getDaliClassItem  "+ className )
75     index = $daliClassArray.index{ |a| a.name == className }
76
77     if( index == nil)
78         # create a new item along with a array for it's properites
79         classItem = $daliClassStruct.new( className );
80
81         classItem.name = className
82         classItem.hasNewFunction = false
83         classItem.hasConstructor = false
84         classItem.generatedConstructors = Array.new
85         classItem.staticNewLines =  Array.new
86
87         $daliClassArray.push( classItem )
88
89     else
90
91         classItem = $daliClassArray[ index ]
92     end
93
94     return classItem;
95
96 end
97
98 def grepConstructorInfo
99
100     # grep for strings like    public Actor(), have to use double black slash on the parenthesis for some reason
101    result =`grep -oP -n "public [A-Z]([A-Z]*[0-9]*[a-z])*\\(\\)"   #{$daliCSharpPath}/*`
102
103    # result is an array of lines that look like this:
104    #  /homepath/dali-toolkit/plugins/dali-swig/csharp/Window.cs:66:public Window()
105
106    lines = result.split(/\n+/);
107    for line in lines
108
109       # Split the line into file name, line number
110       data  = line.split(":",3)
111       fileName = data[0];
112       lineNum = data[1]
113
114
115       # Get the class name from the filename
116       className =  File.basename(fileName,".cs")
117
118        # get or create a new DALi class item which stores the new / constructor information
119       classItem  = getDaliClassItem( className )
120
121       classItem.file = fileName
122       classItem.constructorLine = lineNum.to_i
123       classItem.hasConstructor = true
124     #  puts classItem.name
125
126     end
127
128 end
129
130
131
132 def grepStaticNewInfo
133
134     # grep for strings like    static Actor::New()
135    result =`grep -oP -n -i "static [a-zA-Z0-9]\+ New"   #{$daliCSharpPath}/*`
136
137    lines = result.split(/\n+/);
138    for line in lines
139
140       #puts line
141       # Split the line into file name and property macro, split 2 means just create two strings
142       data  = line.split(":",3)
143       fileName = data[0];
144       lineNum = data[1]
145
146         #  # Get the class name from the filename  ( e.g. image-actor-impl.cpp => image-actor)
147       className = File.basename(fileName,".cs")
148
149        # get or create a new DALi class item which stores the property information
150       classItem  = getDaliClassItem( className )
151
152       classItem.file = fileName
153       classItem.hasNewFunction = true
154       classItem.staticNewLines.push( lineNum.to_i )
155      # puts "added line number #{lineNum} for #{classItem.name}"
156
157     end
158
159 end
160
161
162
163
164 def generateNewConstructors
165     todo = 2
166
167     for daliClass in  $daliClassArray
168
169         # if the class doesn't have a New function and a constructor then skip it
170         if ! (daliClass.hasNewFunction && daliClass.hasConstructor)
171             #puts( "Doesn't have a New function #{daliClass.file}" )
172             next
173         end
174
175         File.open(daliClass.file, 'r+') do |file|
176
177           currentLine = 0
178           for newEntryLine in daliClass.staticNewLines
179               linesToRead = newEntryLine - currentLine -1
180             #  puts("lineToRead = #{linesToRead} #{newEntryLine}")
181               linesToRead.times{  file.gets }
182
183               currentLine += linesToRead +$swigConstructorNumLines # +3 for 3 lines of the New function that we read in below
184               line =  file.readline
185               #puts("line = #{line} _________")
186               parameterString = /\((.*)\)/.match(line) # pulls out the New parameter e.g. (float duration)
187
188               #read the next line
189               #file.gets
190               line =  file.readline
191               constructorCall = /\((.*)\)/.match(line) # pulls out the constructor call e.g. ((NDalicPINVOKE.TextLabel_New__SWIG_1(text), true))
192
193               exceptionLine =  file.readline
194
195               #res = file.line.line.grep(/asd/i)
196               constructorCode = "  public #{daliClass.name} #{parameterString} : this #{constructorCall} {\n"\
197                                 "  #{exceptionLine}\n"\
198                                 "  }\n"
199
200
201               daliClass.generatedConstructors.push( constructorCode )
202               #puts constructorCode
203           end # for
204       end  # file open
205     end # for
206 end
207
208 def InjectConstructors( daliClass, file )
209
210   for code in daliClass.generatedConstructors
211       file.puts( code )
212       #puts code
213       $totalConstructorsGenerated+=1
214   end
215 end
216
217 def lineShouldBeSkipped(daliClass, line)
218
219   if line.between?(daliClass.constructorLine-1, daliClass.constructorLine+$swigConstructorNumLines -1)
220     return true
221   end
222
223
224   for n in daliClass.staticNewLines
225     if line.between?(n-1, n+$swigNewFuncNumLines )
226       return true
227     end
228   end
229
230   return false
231 end
232
233
234 # helper class to color the background
235 class String
236 def blueBackground;   "\e[45m#{self}\e[0m" end
237 end
238
239 def updateCSharpFiles
240
241   # we now have a populated array of daliClassStructs.
242   # With each class we open it's SWIG generated csharp file
243   # create a new temp file, and copy the SWIG generated code over to the temporary one
244   # except for the existing constructors and New() functions. e.g. Actor() and Actor::New()
245   # We also inject our new constructor functions e.g. Actor()
246
247   for daliClass in  $daliClassArray
248      #  puts "writing file #{daliClass.name}..."
249
250       # check the class has some constructors to write
251       if (daliClass.generatedConstructors.length == 0 )
252         #   puts "no constructors for  #{daliClass.name}..."
253         next
254       end
255
256       if daliClass.name == "Application"
257         next
258       end
259
260       $totalDaliClasses+=1  # for stats
261
262       # create a file to store the modified output
263       tempFileName = "#{daliClass.file}.tmp"
264       tempFile = File.new(tempFileName, 'w')
265
266       tempFile.puts $fileHeader
267       currentLine = 0
268       # open the the file
269       constructorsWritten = false
270
271       File.open(daliClass.file, 'r') do |file|
272
273         file.each do |line|
274
275           if lineShouldBeSkipped( daliClass, currentLine ) # lineShouldBeSkipped ( daliClass, currentLine )
276             currentLine +=1
277             if( !constructorsWritten )
278                 # inject our newly generated constructors
279               InjectConstructors( daliClass, tempFile );
280               puts("Converting static Class::New(xxx) ---> new Class(xxx) into #{daliClass.name}".blueBackground)
281
282               constructorsWritten = true  # only write our new constructors to the file once
283             end
284             next
285           end # line should be skipped
286
287           currentLine +=1
288           tempFile.puts( line )
289
290         end # file each
291       end # file open
292
293       tempFile.close
294
295       # copy the temp file over the top of the exiting file
296       FileUtils.mv tempFileName, daliClass.file
297
298   end
299   puts"\n"
300   puts("Done. Generated #{$totalConstructorsGenerated} Constructors for #{$totalDaliClasses} DALi C# classes".blueBackground)
301
302
303
304 end
305
306 init
307 grepConstructorInfo
308 grepStaticNewInfo
309 generateNewConstructors
310 updateCSharpFiles
311
312