From 62f6fcf41eef72b1d0e1d7bc7f414d5914f77db9 Mon Sep 17 00:00:00 2001 From: sekelsenmat Date: Wed, 15 Jun 2011 10:16:23 +0000 Subject: [PATCH] Starts adding the android java sdk bindings generator git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1677 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../android_bindings_generator.lpi | 295 ++++++++++++++++++ .../android_bindings_generator.pas | 21 ++ .../android-sdk/android_sdk_bindings_gen.pas | 205 ++++++++++++ bindings/android-sdk/mainform.lfm | 47 +++ bindings/android-sdk/mainform.pas | 42 +++ .../android-sdk/sdk_level_7/android_view.txt | 6 + 6 files changed, 616 insertions(+) create mode 100644 bindings/android-sdk/android_bindings_generator.lpi create mode 100644 bindings/android-sdk/android_bindings_generator.pas create mode 100644 bindings/android-sdk/android_sdk_bindings_gen.pas create mode 100644 bindings/android-sdk/mainform.lfm create mode 100644 bindings/android-sdk/mainform.pas create mode 100644 bindings/android-sdk/sdk_level_7/android_view.txt diff --git a/bindings/android-sdk/android_bindings_generator.lpi b/bindings/android-sdk/android_bindings_generator.lpi new file mode 100644 index 000000000..cf1a03c43 --- /dev/null +++ b/bindings/android-sdk/android_bindings_generator.lpi @@ -0,0 +1,295 @@ + + + + + + + + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <Icon Value="0"/> + <ActiveWindowIndexAtStart Value="0"/> + </General> + <i18n> + <EnableI18N LFM="False"/> + </i18n> + <VersionInfo> + <StringTable ProductVersion=""/> + </VersionInfo> + <BuildModes Count="1" Active="Default"> + <Item1 Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> + <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + <LaunchingApplication PathPlusParams="/usr/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/> + </local> + </RunParams> + <RequiredPackages Count="2"> + <Item1> + <PackageName Value="LCLBase"/> + <MinVersion Valid="True"/> + </Item1> + <Item2> + <PackageName Value="LCL"/> + </Item2> + </RequiredPackages> + <Units Count="9"> + <Unit0> + <Filename Value="android_bindings_generator.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="android_bindings_generator"/> + <IsVisibleTab Value="True"/> + <EditorIndex Value="1"/> + <WindowIndex Value="0"/> + <TopLine Value="1"/> + <CursorPos X="15" Y="14"/> + <UsageCount Value="20"/> + <Loaded Value="True"/> + </Unit0> + <Unit1> + <Filename Value="mainform.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="Form1"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="mainform"/> + <EditorIndex Value="0"/> + <WindowIndex Value="0"/> + <TopLine Value="1"/> + <CursorPos X="22" Y="32"/> + <UsageCount Value="20"/> + <Loaded Value="True"/> + <LoadedDesigner Value="True"/> + </Unit1> + <Unit2> + <Filename Value="../../../p-tools/turbochessclock4android/androidmenu.pas"/> + <UnitName Value="androidmenu"/> + <EditorIndex Value="4"/> + <WindowIndex Value="0"/> + <TopLine Value="14"/> + <CursorPos X="25" Y="24"/> + <UsageCount Value="10"/> + <Loaded Value="True"/> + </Unit2> + <Unit3> + <Filename Value="../../../p-tools/turbochessclock4android/androidutil.pas"/> + <UnitName Value="androidutil"/> + <EditorIndex Value="3"/> + <WindowIndex Value="0"/> + <TopLine Value="1"/> + <CursorPos X="1" Y="1"/> + <UsageCount Value="10"/> + <Loaded Value="True"/> + </Unit3> + <Unit4> + <Filename Value="../../../p-tools/turbochessclock4android/androidview.pas"/> + <UnitName Value="androidview"/> + <EditorIndex Value="6"/> + <WindowIndex Value="0"/> + <TopLine Value="53"/> + <CursorPos X="1" Y="1"/> + <UsageCount Value="10"/> + <Loaded Value="True"/> + </Unit4> + <Unit5> + <Filename Value="../../../p-tools/turbochessclock4android/androiddialog.pas"/> + <UnitName Value="androiddialog"/> + <EditorIndex Value="7"/> + <WindowIndex Value="0"/> + <TopLine Value="1"/> + <CursorPos X="1" Y="1"/> + <UsageCount Value="10"/> + <Loaded Value="True"/> + </Unit5> + <Unit6> + <Filename Value="../../../p-tools/turbochessclock4android/androidinputevent.pas"/> + <UnitName Value="androidinputevent"/> + <WindowIndex Value="0"/> + <TopLine Value="1"/> + <CursorPos X="1" Y="1"/> + <UsageCount Value="10"/> + </Unit6> + <Unit7> + <Filename Value="../../../p-tools/turbochessclock4android/android/src/com/pascal/turbochessclock/AndroidMenu.java"/> + <EditorIndex Value="5"/> + <WindowIndex Value="0"/> + <TopLine Value="81"/> + <CursorPos X="56" Y="104"/> + <UsageCount Value="10"/> + <Loaded Value="True"/> + <DefaultSyntaxHighlighter Value="Java"/> + </Unit7> + <Unit8> + <Filename Value="android_sdk_bindings_gen.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="android_sdk_bindings_gen"/> + <EditorIndex Value="2"/> + <WindowIndex Value="0"/> + <TopLine Value="72"/> + <CursorPos X="19" Y="99"/> + <UsageCount Value="20"/> + <Loaded Value="True"/> + </Unit8> + </Units> + <JumpHistory Count="30" HistoryIndex="29"> + <Position1> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="13" Column="3" TopLine="9"/> + </Position1> + <Position2> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="62" Column="16" TopLine="47"/> + </Position2> + <Position3> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="14" Column="50" TopLine="1"/> + </Position3> + <Position4> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="18" Column="17" TopLine="1"/> + </Position4> + <Position5> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="67" Column="1" TopLine="54"/> + </Position5> + <Position6> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="55" Column="70" TopLine="34"/> + </Position6> + <Position7> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="16" Column="39" TopLine="1"/> + </Position7> + <Position8> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="1" Column="30" TopLine="1"/> + </Position8> + <Position9> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="17" Column="74" TopLine="1"/> + </Position9> + <Position10> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="43" Column="20" TopLine="15"/> + </Position10> + <Position11> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="45" Column="9" TopLine="20"/> + </Position11> + <Position12> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="72" Column="6" TopLine="43"/> + </Position12> + <Position13> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="73" Column="39" TopLine="50"/> + </Position13> + <Position14> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="74" Column="6" TopLine="51"/> + </Position14> + <Position15> + <Filename Value="mainform.pas"/> + <Caret Line="38" Column="83" TopLine="1"/> + </Position15> + <Position16> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="28" Column="1" TopLine="1"/> + </Position16> + <Position17> + <Filename Value="mainform.pas"/> + <Caret Line="38" Column="13" TopLine="1"/> + </Position17> + <Position18> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="35" Column="78" TopLine="33"/> + </Position18> + <Position19> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="144" Column="17" TopLine="110"/> + </Position19> + <Position20> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="142" Column="34" TopLine="110"/> + </Position20> + <Position21> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="144" Column="33" TopLine="110"/> + </Position21> + <Position22> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="90" Column="143" TopLine="78"/> + </Position22> + <Position23> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="22" Column="24" TopLine="1"/> + </Position23> + <Position24> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="116" Column="21" TopLine="96"/> + </Position24> + <Position25> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="175" Column="35" TopLine="150"/> + </Position25> + <Position26> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="21" Column="31" TopLine="40"/> + </Position26> + <Position27> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="98" Column="42" TopLine="75"/> + </Position27> + <Position28> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="84" Column="3" TopLine="77"/> + </Position28> + <Position29> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="89" Column="1" TopLine="77"/> + </Position29> + <Position30> + <Filename Value="android_sdk_bindings_gen.pas"/> + <Caret Line="114" Column="29" TopLine="91"/> + </Position30> + </JumpHistory> + </ProjectOptions> + <CompilerOptions> + <Version Value="10"/> + <Target> + <Filename Value="android_bindings_generator"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Linking> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + <Other> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/bindings/android-sdk/android_bindings_generator.pas b/bindings/android-sdk/android_bindings_generator.pas new file mode 100644 index 000000000..94f59a6c5 --- /dev/null +++ b/bindings/android-sdk/android_bindings_generator.pas @@ -0,0 +1,21 @@ +program android_bindings_generator; + +{$mode objfpc}{$H+} + +uses + {$IFDEF UNIX}{$IFDEF UseCThreads} + cthreads, + {$ENDIF}{$ENDIF} + Interfaces, // this includes the LCL widgetset + Forms, mainform, android_sdk_bindings_gen + { you can add units after this }; + +{$R *.res} + +begin + RequireDerivedFormResource := True; + Application.Initialize; + Application.CreateForm(TForm1, Form1); + Application.Run; +end. + diff --git a/bindings/android-sdk/android_sdk_bindings_gen.pas b/bindings/android-sdk/android_sdk_bindings_gen.pas new file mode 100644 index 000000000..0d318bd48 --- /dev/null +++ b/bindings/android-sdk/android_sdk_bindings_gen.pas @@ -0,0 +1,205 @@ +unit android_sdk_bindings_gen; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils; + +type + + { TAndroidSDKBindingsGen } + + TAndroidSDKBindingsGen = class + private + FSourceFile, FPasOutputClasses, FPasOutputImpl: TStringList; + FClassName: string; // Class name of the class currently being parsed + procedure ProcessModelFile(ASourceFile, APasOutputFile, AJavaOutputDir: string); + procedure ProcessModelLine(ASourceLine: string); + function GetNextWord(ALine: string; var AStartPos: Integer): string; + function GetPascalTypeName(ABaseName: string): string; + public + procedure GenerateAllBindings(AInputDir, APasOutputDir, AJavaOutputDir: string); + end; + +var + AndroidSDKBindingsGen: TAndroidSDKBindingsGen; + +implementation + +{ TAndroidSDKBindingsGen } + +procedure TAndroidSDKBindingsGen.ProcessModelFile(ASourceFile, APasOutputFile, + AJavaOutputDir: string); +var + i: Integer; + lPasOutputFile: TStringList; +begin + FSourceFile := TStringList.Create; + FPasOutputClasses := TStringList.Create; + FPasOutputImpl := TStringList.Create; + lPasOutputFile := TStringList.Create; + try + FSourceFile.LoadFromFile(ASourceFile); + + // Preparations + FClassName := ''; + + for i := 0 to FSourceFile.Count - 1 do + begin + ProcessModelLine(FSourceFile.Strings[i]); + end; + + // Now save the output + lPasOutputFile.Add('unit ;'); + lPasOutputFile.Add(''); + lPasOutputFile.Add('interface'); + lPasOutputFile.Add(''); + lPasOutputFile.Add('type'); + lPasOutputFile.AddStrings(FPasOutputClasses); + lPasOutputFile.Add(' end;'); + lPasOutputFile.Add(''); + lPasOutputFile.Add(''); + lPasOutputFile.Add('implementation'); + lPasOutputFile.Add(''); + lPasOutputFile.AddStrings(FPasOutputImpl); + lPasOutputFile.Add(''); + lPasOutputFile.Add('end.'); + + lPasOutputFile.SaveToFile(APasOutputFile); + finally + FSourceFile.Free; + FPasOutputClasses.Free; + FPasOutputImpl.Free; + lPasOutputFile.Free; + end; +end; + +procedure TAndroidSDKBindingsGen.ProcessModelLine(ASourceLine: string); +var + lReaderPos: Integer = 1; + lCurWord, lParentClassName: string; + lMethodReturn, lMethodName, lParamType, lParamName: string; + TmpStr: string; +begin + if ASourceLine = '' then Exit; + + lCurWord := GetNextWord(ASourceLine, lReaderPos); + + // Starting a new class + if ASourceLine[1] = '[' then + begin + if FClassName <> '' then + begin + FPasOutputClasses.Add(' end;'); + FPasOutputClasses.Add(''); + end; + + FClassName := GetPascalTypeName(lCurWord); + lParentClassName := GetNextWord(ASourceLine, lReaderPos); + lParentClassName := GetPascalTypeName(lParentClassName); + FPasOutputClasses.Add(Format(' %s = class(%s)', [FClassName, lParentClassName])); + FPasOutputClasses.Add(' public'); + end; + + // Adding methods to a class + if lCurWord = 'method' then + begin + lMethodReturn := GetNextWord(ASourceLine, lReaderPos); + lMethodReturn := GetPascalTypeName(lMethodReturn); + lMethodName := GetNextWord(ASourceLine, lReaderPos); + + if lMethodReturn = 'void' then TmpStr := ' procedure ' + else TmpStr := ' function '; + + // Add all parameters + TmpStr := TmpStr + lMethodName + '('; + + repeat + lParamType := GetNextWord(ASourceLine, lReaderPos); + lParamType := GetPascalTypeName(lParamType); + lParamName := GetNextWord(ASourceLine, lReaderPos); + + if lParamName = '' then Break; + + TmpStr := TmpStr + lParamName + ': ' + lParamType + '; '; + until lParamName = ''; + + // Remove the last ; for the parameters, if necessary + if TmpStr[Length(TmpStr)-1] = ';' then TmpStr := System.Copy(TmpStr, 0, Length(TmpStr)-2); + + // Add the return + if lMethodReturn = 'void' then TmpStr := TmpStr + ');' + else TmpStr := TmpStr + '): ' + lMethodReturn + ';'; + + FPasOutputClasses.Add(TmpStr); + end; +end; + +{ Reads one word in a string, starting at AStartPos (1-based index) + and going up to a space or comma or ( or ) or another separator } +function TAndroidSDKBindingsGen.GetNextWord(ALine: string; + var AStartPos: Integer): string; +const + WordSeparators = [' ','(',')','[',']',',']; +var + lState: Integer = 0; +begin + Result := ''; + + while AStartPos <= Length(ALine) do + begin + // Searching the word start + if lState = 0 then + begin + if ALine[AStartPos] in WordSeparators then Inc(AStartPos) + else + begin + Result := ALine[AStartPos]; + Inc(AStartPos); + lState := 1; + end; + end + // Reading until the word finishes + else + begin + if ALine[AStartPos] in WordSeparators then Exit + else + begin + Result := Result + ALine[AStartPos]; + Inc(AStartPos); + end; + end; + end; +end; + +function TAndroidSDKBindingsGen.GetPascalTypeName(ABaseName: string): string; +begin + if ABaseName = '' then Exit(''); + + if ABaseName = 'int' then Result := 'Integer' + else if ABaseName = 'void' then Result := ABaseName + else if ABaseName = 'CharSequence' then Result := 'string' + else if ABaseName = 'TJavaObject' then Result := ABaseName + else Result := 'T' + ABaseName; +end; + +procedure TAndroidSDKBindingsGen.GenerateAllBindings(AInputDir, APasOutputDir, + AJavaOutputDir: string); +begin + ProcessModelFile(IncludeTrailingPathDelimiter(AInputDir) + 'android_view.txt', + IncludeTrailingPathDelimiter(APasOutputDir) + 'android_view.pas', + IncludeTrailingPathDelimiter(AJavaOutputDir)); +end; + +initialization + + AndroidSDKBindingsGen := TAndroidSDKBindingsGen.Create; + +finalization + + AndroidSDKBindingsGen.Free; + +end. + diff --git a/bindings/android-sdk/mainform.lfm b/bindings/android-sdk/mainform.lfm new file mode 100644 index 000000000..a24be5e8d --- /dev/null +++ b/bindings/android-sdk/mainform.lfm @@ -0,0 +1,47 @@ +object Form1: TForm1 + Left = 479 + Height = 414 + Top = 137 + Width = 434 + Caption = 'Android Bindings Generator' + ClientHeight = 414 + ClientWidth = 434 + LCLVersion = '0.9.31' + object Label1: TLabel + Left = 8 + Height = 18 + Top = 8 + Width = 43 + Caption = 'Label1' + ParentColor = False + end + object editInputPath: TDirectoryEdit + Left = 64 + Height = 25 + Top = 72 + Width = 312 + Directory = '/home/felipe/Programas/lazarus-ccr/bindings/android-sdk/sdk_level_7' + ShowHidden = False + ButtonWidth = 23 + NumGlyphs = 0 + MaxLength = 0 + TabOrder = 0 + end + object Label2: TLabel + Left = 7 + Height = 18 + Top = 73 + Width = 43 + Caption = 'Label2' + ParentColor = False + end + object Button1: TButton + Left = 17 + Height = 25 + Top = 120 + Width = 155 + Caption = 'Build the Bindings' + OnClick = Button1Click + TabOrder = 1 + end +end diff --git a/bindings/android-sdk/mainform.pas b/bindings/android-sdk/mainform.pas new file mode 100644 index 000000000..0e608440f --- /dev/null +++ b/bindings/android-sdk/mainform.pas @@ -0,0 +1,42 @@ +unit mainform; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, + EditBtn, android_sdk_bindings_gen; + +type + + { TForm1 } + + TForm1 = class(TForm) + Button1: TButton; + editInputPath: TDirectoryEdit; + Label1: TLabel; + Label2: TLabel; + procedure Button1Click(Sender: TObject); + private + { private declarations } + public + { public declarations } + end; + +var + Form1: TForm1; + +implementation + +{$R *.lfm} + +{ TForm1 } + +procedure TForm1.Button1Click(Sender: TObject); +begin + AndroidSDKBindingsGen.GenerateAllBindings(editInputPath.Text, editInputPath.Text, editInputPath.Text); +end; + +end. + diff --git a/bindings/android-sdk/sdk_level_7/android_view.txt b/bindings/android-sdk/sdk_level_7/android_view.txt new file mode 100644 index 000000000..d9ccd63a6 --- /dev/null +++ b/bindings/android-sdk/sdk_level_7/android_view.txt @@ -0,0 +1,6 @@ +[MenuItem] TJavaObject +classcallback MenuItem.OnMenuItemClickListener boolean onMenuItemClick (MenuItem item) +method MenuItem setOnMenuItemClickListener (MenuItem.OnMenuItemClickListener menuItemClickListener) + +[Menu] TJavaObject +method MenuItem add(int groupId, int itemId, int order, CharSequence title)